1*5f2bebf7SJérôme Gardou /* $Id: readpix.c,v 1.10 1997/07/24 01:25:18 brianp Exp $ */
2*5f2bebf7SJérôme Gardou
3*5f2bebf7SJérôme Gardou /*
4*5f2bebf7SJérôme Gardou * Mesa 3-D graphics library
5*5f2bebf7SJérôme Gardou * Version: 2.4
6*5f2bebf7SJérôme Gardou * Copyright (C) 1995-1997 Brian Paul
7*5f2bebf7SJérôme Gardou *
8*5f2bebf7SJérôme Gardou * This library is free software; you can redistribute it and/or
9*5f2bebf7SJérôme Gardou * modify it under the terms of the GNU Library General Public
10*5f2bebf7SJérôme Gardou * License as published by the Free Software Foundation; either
11*5f2bebf7SJérôme Gardou * version 2 of the License, or (at your option) any later version.
12*5f2bebf7SJérôme Gardou *
13*5f2bebf7SJérôme Gardou * This library is distributed in the hope that it will be useful,
14*5f2bebf7SJérôme Gardou * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*5f2bebf7SJérôme Gardou * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16*5f2bebf7SJérôme Gardou * Library General Public License for more details.
17*5f2bebf7SJérôme Gardou *
18*5f2bebf7SJérôme Gardou * You should have received a copy of the GNU Library General Public
19*5f2bebf7SJérôme Gardou * License along with this library; if not, write to the Free
20*5f2bebf7SJérôme Gardou * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*5f2bebf7SJérôme Gardou */
22*5f2bebf7SJérôme Gardou
23*5f2bebf7SJérôme Gardou
24*5f2bebf7SJérôme Gardou /*
25*5f2bebf7SJérôme Gardou * $Log: readpix.c,v $
26*5f2bebf7SJérôme Gardou * Revision 1.10 1997/07/24 01:25:18 brianp
27*5f2bebf7SJérôme Gardou * changed precompiled header symbol from PCH to PC_HEADER
28*5f2bebf7SJérôme Gardou *
29*5f2bebf7SJérôme Gardou * Revision 1.9 1997/05/28 03:26:18 brianp
30*5f2bebf7SJérôme Gardou * added precompiled header (PCH) support
31*5f2bebf7SJérôme Gardou *
32*5f2bebf7SJérôme Gardou * Revision 1.8 1997/05/08 01:43:50 brianp
33*5f2bebf7SJérôme Gardou * added error check to gl_ReadPixels() for inside glBegin/glEnd
34*5f2bebf7SJérôme Gardou *
35*5f2bebf7SJérôme Gardou * Revision 1.7 1997/02/03 20:31:15 brianp
36*5f2bebf7SJérôme Gardou * added a few DEFARRAY macros for BeOS
37*5f2bebf7SJérôme Gardou *
38*5f2bebf7SJérôme Gardou * Revision 1.6 1997/01/16 19:24:05 brianp
39*5f2bebf7SJérôme Gardou * replaced a few abort()'s with gl_error() calls
40*5f2bebf7SJérôme Gardou *
41*5f2bebf7SJérôme Gardou * Revision 1.5 1996/12/20 20:28:04 brianp
42*5f2bebf7SJérôme Gardou * use DEF/UNDEFARRAY() macros in read_color_pixels() for Mac compilers
43*5f2bebf7SJérôme Gardou *
44*5f2bebf7SJérôme Gardou * Revision 1.4 1996/11/01 03:20:47 brianp
45*5f2bebf7SJérôme Gardou * reading GL_LUMINANCE pixels weren't clamped
46*5f2bebf7SJérôme Gardou *
47*5f2bebf7SJérôme Gardou * Revision 1.3 1996/09/27 01:29:47 brianp
48*5f2bebf7SJérôme Gardou * added missing default cases to switches
49*5f2bebf7SJérôme Gardou *
50*5f2bebf7SJérôme Gardou * Revision 1.2 1996/09/15 14:18:37 brianp
51*5f2bebf7SJérôme Gardou * now use GLframebuffer and GLvisual
52*5f2bebf7SJérôme Gardou *
53*5f2bebf7SJérôme Gardou * Revision 1.1 1996/09/13 01:38:16 brianp
54*5f2bebf7SJérôme Gardou * Initial revision
55*5f2bebf7SJérôme Gardou *
56*5f2bebf7SJérôme Gardou */
57*5f2bebf7SJérôme Gardou
58*5f2bebf7SJérôme Gardou
59*5f2bebf7SJérôme Gardou #ifdef PC_HEADER
60*5f2bebf7SJérôme Gardou #include "all.h"
61*5f2bebf7SJérôme Gardou #else
62*5f2bebf7SJérôme Gardou #include <math.h>
63*5f2bebf7SJérôme Gardou #include <stdlib.h>
64*5f2bebf7SJérôme Gardou #include <string.h>
65*5f2bebf7SJérôme Gardou #include "alphabuf.h"
66*5f2bebf7SJérôme Gardou #include "context.h"
67*5f2bebf7SJérôme Gardou #include "depth.h"
68*5f2bebf7SJérôme Gardou #include "feedback.h"
69*5f2bebf7SJérôme Gardou #include "dlist.h"
70*5f2bebf7SJérôme Gardou #include "macros.h"
71*5f2bebf7SJérôme Gardou #include "image.h"
72*5f2bebf7SJérôme Gardou #include "readpix.h"
73*5f2bebf7SJérôme Gardou #include "span.h"
74*5f2bebf7SJérôme Gardou #include "stencil.h"
75*5f2bebf7SJérôme Gardou #include "types.h"
76*5f2bebf7SJérôme Gardou #endif
77*5f2bebf7SJérôme Gardou
78*5f2bebf7SJérôme Gardou
79*5f2bebf7SJérôme Gardou
80*5f2bebf7SJérôme Gardou
81*5f2bebf7SJérôme Gardou /*
82*5f2bebf7SJérôme Gardou * Read a block of color index pixels.
83*5f2bebf7SJérôme Gardou */
read_index_pixels(GLcontext * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum type,GLvoid * pixels)84*5f2bebf7SJérôme Gardou static void read_index_pixels( GLcontext *ctx,
85*5f2bebf7SJérôme Gardou GLint x, GLint y,
86*5f2bebf7SJérôme Gardou GLsizei width, GLsizei height,
87*5f2bebf7SJérôme Gardou GLenum type, GLvoid *pixels )
88*5f2bebf7SJérôme Gardou {
89*5f2bebf7SJérôme Gardou GLint i, j;
90*5f2bebf7SJérôme Gardou GLuint a, s, k, l, start;
91*5f2bebf7SJérôme Gardou
92*5f2bebf7SJérôme Gardou /* error checking */
93*5f2bebf7SJérôme Gardou if (ctx->Visual->RGBAflag) {
94*5f2bebf7SJérôme Gardou gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
95*5f2bebf7SJérôme Gardou return;
96*5f2bebf7SJérôme Gardou }
97*5f2bebf7SJérôme Gardou
98*5f2bebf7SJérôme Gardou /* Size of each component */
99*5f2bebf7SJérôme Gardou s = gl_sizeof_type( type );
100*5f2bebf7SJérôme Gardou if (s<=0) {
101*5f2bebf7SJérôme Gardou gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
102*5f2bebf7SJérôme Gardou return;
103*5f2bebf7SJérôme Gardou }
104*5f2bebf7SJérôme Gardou
105*5f2bebf7SJérôme Gardou /* Compute packing parameters */
106*5f2bebf7SJérôme Gardou a = ctx->Pack.Alignment;
107*5f2bebf7SJérôme Gardou if (ctx->Pack.RowLength>0) {
108*5f2bebf7SJérôme Gardou l = ctx->Pack.RowLength;
109*5f2bebf7SJérôme Gardou }
110*5f2bebf7SJérôme Gardou else {
111*5f2bebf7SJérôme Gardou l = width;
112*5f2bebf7SJérôme Gardou }
113*5f2bebf7SJérôme Gardou /* k = offset between rows in components */
114*5f2bebf7SJérôme Gardou if (s>=a) {
115*5f2bebf7SJérôme Gardou k = l;
116*5f2bebf7SJérôme Gardou }
117*5f2bebf7SJérôme Gardou else {
118*5f2bebf7SJérôme Gardou k = a/s * CEILING( s*l, a );
119*5f2bebf7SJérôme Gardou }
120*5f2bebf7SJérôme Gardou
121*5f2bebf7SJérôme Gardou /* offset to first component returned */
122*5f2bebf7SJérôme Gardou start = ctx->Pack.SkipRows * k + ctx->Pack.SkipPixels;
123*5f2bebf7SJérôme Gardou
124*5f2bebf7SJérôme Gardou /* process image row by row */
125*5f2bebf7SJérôme Gardou for (j=0;j<height;j++,y++) {
126*5f2bebf7SJérôme Gardou GLuint index[MAX_WIDTH];
127*5f2bebf7SJérôme Gardou (*ctx->Driver.ReadIndexSpan)( ctx, width, x, y, index );
128*5f2bebf7SJérôme Gardou
129*5f2bebf7SJérôme Gardou if (ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0) {
130*5f2bebf7SJérôme Gardou GLuint s;
131*5f2bebf7SJérôme Gardou if (ctx->Pixel.IndexShift<0) {
132*5f2bebf7SJérôme Gardou /* right shift */
133*5f2bebf7SJérôme Gardou s = -ctx->Pixel.IndexShift;
134*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
135*5f2bebf7SJérôme Gardou index[i] = (index[i] >> s) + ctx->Pixel.IndexOffset;
136*5f2bebf7SJérôme Gardou }
137*5f2bebf7SJérôme Gardou }
138*5f2bebf7SJérôme Gardou else {
139*5f2bebf7SJérôme Gardou /* left shift */
140*5f2bebf7SJérôme Gardou s = ctx->Pixel.IndexShift;
141*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
142*5f2bebf7SJérôme Gardou index[i] = (index[i] << s) + ctx->Pixel.IndexOffset;
143*5f2bebf7SJérôme Gardou }
144*5f2bebf7SJérôme Gardou }
145*5f2bebf7SJérôme Gardou }
146*5f2bebf7SJérôme Gardou
147*5f2bebf7SJérôme Gardou if (ctx->Pixel.MapColorFlag) {
148*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
149*5f2bebf7SJérôme Gardou index[i] = ctx->Pixel.MapItoI[ index[i] ];
150*5f2bebf7SJérôme Gardou }
151*5f2bebf7SJérôme Gardou }
152*5f2bebf7SJérôme Gardou
153*5f2bebf7SJérôme Gardou switch (type) {
154*5f2bebf7SJérôme Gardou case GL_UNSIGNED_BYTE:
155*5f2bebf7SJérôme Gardou {
156*5f2bebf7SJérôme Gardou GLubyte *dst = (GLubyte *) pixels + start + j * k;
157*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
158*5f2bebf7SJérôme Gardou *dst++ = (GLubyte) index[i];
159*5f2bebf7SJérôme Gardou }
160*5f2bebf7SJérôme Gardou }
161*5f2bebf7SJérôme Gardou break;
162*5f2bebf7SJérôme Gardou case GL_BYTE:
163*5f2bebf7SJérôme Gardou {
164*5f2bebf7SJérôme Gardou GLbyte *dst = (GLbyte *) pixels + start + j * k;
165*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
166*5f2bebf7SJérôme Gardou *dst++ = (GLbyte) index[i];
167*5f2bebf7SJérôme Gardou }
168*5f2bebf7SJérôme Gardou }
169*5f2bebf7SJérôme Gardou break;
170*5f2bebf7SJérôme Gardou case GL_UNSIGNED_SHORT:
171*5f2bebf7SJérôme Gardou {
172*5f2bebf7SJérôme Gardou GLushort *dst = (GLushort *) pixels + start + j * k;
173*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
174*5f2bebf7SJérôme Gardou *dst++ = (GLushort) index[i];
175*5f2bebf7SJérôme Gardou }
176*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
177*5f2bebf7SJérôme Gardou gl_swap2( (GLushort *) pixels + start + j * k, width );
178*5f2bebf7SJérôme Gardou }
179*5f2bebf7SJérôme Gardou }
180*5f2bebf7SJérôme Gardou break;
181*5f2bebf7SJérôme Gardou case GL_SHORT:
182*5f2bebf7SJérôme Gardou {
183*5f2bebf7SJérôme Gardou GLshort *dst = (GLshort *) pixels + start + j * k;
184*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
185*5f2bebf7SJérôme Gardou *dst++ = (GLshort) index[i];
186*5f2bebf7SJérôme Gardou }
187*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
188*5f2bebf7SJérôme Gardou gl_swap2( (GLushort *) pixels + start + j * k, width );
189*5f2bebf7SJérôme Gardou }
190*5f2bebf7SJérôme Gardou }
191*5f2bebf7SJérôme Gardou break;
192*5f2bebf7SJérôme Gardou case GL_UNSIGNED_INT:
193*5f2bebf7SJérôme Gardou {
194*5f2bebf7SJérôme Gardou GLuint *dst = (GLuint *) pixels + start + j * k;
195*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
196*5f2bebf7SJérôme Gardou *dst++ = (GLuint) index[i];
197*5f2bebf7SJérôme Gardou }
198*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
199*5f2bebf7SJérôme Gardou gl_swap4( (GLuint *) pixels + start + j * k, width );
200*5f2bebf7SJérôme Gardou }
201*5f2bebf7SJérôme Gardou }
202*5f2bebf7SJérôme Gardou break;
203*5f2bebf7SJérôme Gardou case GL_INT:
204*5f2bebf7SJérôme Gardou {
205*5f2bebf7SJérôme Gardou GLint *dst = (GLint *) pixels + start + j * k;
206*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
207*5f2bebf7SJérôme Gardou *dst++ = (GLint) index[i];
208*5f2bebf7SJérôme Gardou }
209*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
210*5f2bebf7SJérôme Gardou gl_swap4( (GLuint *) pixels + start + j * k, width );
211*5f2bebf7SJérôme Gardou }
212*5f2bebf7SJérôme Gardou }
213*5f2bebf7SJérôme Gardou break;
214*5f2bebf7SJérôme Gardou case GL_FLOAT:
215*5f2bebf7SJérôme Gardou {
216*5f2bebf7SJérôme Gardou GLfloat *dst = (GLfloat *) pixels + start + j * k;
217*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
218*5f2bebf7SJérôme Gardou *dst++ = (GLfloat) index[i];
219*5f2bebf7SJérôme Gardou }
220*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
221*5f2bebf7SJérôme Gardou gl_swap4( (GLuint *) pixels + start + j * k, width );
222*5f2bebf7SJérôme Gardou }
223*5f2bebf7SJérôme Gardou }
224*5f2bebf7SJérôme Gardou break;
225*5f2bebf7SJérôme Gardou default:
226*5f2bebf7SJérôme Gardou gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
227*5f2bebf7SJérôme Gardou }
228*5f2bebf7SJérôme Gardou }
229*5f2bebf7SJérôme Gardou }
230*5f2bebf7SJérôme Gardou
231*5f2bebf7SJérôme Gardou
232*5f2bebf7SJérôme Gardou
read_depth_pixels(GLcontext * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum type,GLvoid * pixels)233*5f2bebf7SJérôme Gardou static void read_depth_pixels( GLcontext *ctx,
234*5f2bebf7SJérôme Gardou GLint x, GLint y,
235*5f2bebf7SJérôme Gardou GLsizei width, GLsizei height,
236*5f2bebf7SJérôme Gardou GLenum type, GLvoid *pixels )
237*5f2bebf7SJérôme Gardou {
238*5f2bebf7SJérôme Gardou GLint i, j;
239*5f2bebf7SJérôme Gardou GLuint a, s, k, l, start;
240*5f2bebf7SJérôme Gardou GLboolean bias_or_scale;
241*5f2bebf7SJérôme Gardou
242*5f2bebf7SJérôme Gardou /* Error checking */
243*5f2bebf7SJérôme Gardou if (ctx->Visual->DepthBits<=0) {
244*5f2bebf7SJérôme Gardou /* No depth buffer */
245*5f2bebf7SJérôme Gardou gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
246*5f2bebf7SJérôme Gardou return;
247*5f2bebf7SJérôme Gardou }
248*5f2bebf7SJérôme Gardou
249*5f2bebf7SJérôme Gardou bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
250*5f2bebf7SJérôme Gardou
251*5f2bebf7SJérôme Gardou /* Size of each component */
252*5f2bebf7SJérôme Gardou s = gl_sizeof_type( type );
253*5f2bebf7SJérôme Gardou if (s<=0) {
254*5f2bebf7SJérôme Gardou gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
255*5f2bebf7SJérôme Gardou return;
256*5f2bebf7SJérôme Gardou }
257*5f2bebf7SJérôme Gardou
258*5f2bebf7SJérôme Gardou /* Compute packing parameters */
259*5f2bebf7SJérôme Gardou a = ctx->Pack.Alignment;
260*5f2bebf7SJérôme Gardou if (ctx->Pack.RowLength>0) {
261*5f2bebf7SJérôme Gardou l = ctx->Pack.RowLength;
262*5f2bebf7SJérôme Gardou }
263*5f2bebf7SJérôme Gardou else {
264*5f2bebf7SJérôme Gardou l = width;
265*5f2bebf7SJérôme Gardou }
266*5f2bebf7SJérôme Gardou /* k = offset between rows in components */
267*5f2bebf7SJérôme Gardou if (s>=a) {
268*5f2bebf7SJérôme Gardou k = l;
269*5f2bebf7SJérôme Gardou }
270*5f2bebf7SJérôme Gardou else {
271*5f2bebf7SJérôme Gardou k = a/s * CEILING( s*l, a );
272*5f2bebf7SJérôme Gardou }
273*5f2bebf7SJérôme Gardou
274*5f2bebf7SJérôme Gardou /* offset to first component returned */
275*5f2bebf7SJérôme Gardou start = ctx->Pack.SkipRows * k + ctx->Pack.SkipPixels;
276*5f2bebf7SJérôme Gardou
277*5f2bebf7SJérôme Gardou if (type==GL_UNSIGNED_INT && !bias_or_scale && !ctx->Pack.SwapBytes) {
278*5f2bebf7SJérôme Gardou /* Special case: directly read 32-bit unsigned depth values. */
279*5f2bebf7SJérôme Gardou /* Compute shift value to scale depth values up to 32-bit uints. */
280*5f2bebf7SJérôme Gardou GLuint shift = 0;
281*5f2bebf7SJérôme Gardou GLuint max = MAX_DEPTH;
282*5f2bebf7SJérôme Gardou while ((max&0x80000000)==0) {
283*5f2bebf7SJérôme Gardou max = max << 1;
284*5f2bebf7SJérôme Gardou shift++;
285*5f2bebf7SJérôme Gardou }
286*5f2bebf7SJérôme Gardou for (j=0;j<height;j++,y++) {
287*5f2bebf7SJérôme Gardou GLuint *dst = (GLuint *) pixels + start + j * k;
288*5f2bebf7SJérôme Gardou (*ctx->Driver.ReadDepthSpanInt)( ctx, width, x, y, (GLdepth*) dst);
289*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
290*5f2bebf7SJérôme Gardou dst[i] = dst[i] << shift;
291*5f2bebf7SJérôme Gardou }
292*5f2bebf7SJérôme Gardou }
293*5f2bebf7SJérôme Gardou }
294*5f2bebf7SJérôme Gardou else {
295*5f2bebf7SJérôme Gardou /* General case (slow) */
296*5f2bebf7SJérôme Gardou for (j=0;j<height;j++,y++) {
297*5f2bebf7SJérôme Gardou GLfloat depth[MAX_WIDTH];
298*5f2bebf7SJérôme Gardou
299*5f2bebf7SJérôme Gardou (*ctx->Driver.ReadDepthSpanFloat)( ctx, width, x, y, depth );
300*5f2bebf7SJérôme Gardou
301*5f2bebf7SJérôme Gardou if (bias_or_scale) {
302*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
303*5f2bebf7SJérôme Gardou GLfloat d;
304*5f2bebf7SJérôme Gardou d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
305*5f2bebf7SJérôme Gardou depth[i] = CLAMP( d, 0.0, 1.0 );
306*5f2bebf7SJérôme Gardou }
307*5f2bebf7SJérôme Gardou }
308*5f2bebf7SJérôme Gardou
309*5f2bebf7SJérôme Gardou switch (type) {
310*5f2bebf7SJérôme Gardou case GL_UNSIGNED_BYTE:
311*5f2bebf7SJérôme Gardou {
312*5f2bebf7SJérôme Gardou GLubyte *dst = (GLubyte *) pixels + start + j * k;
313*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
314*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UBYTE( depth[i] );
315*5f2bebf7SJérôme Gardou }
316*5f2bebf7SJérôme Gardou }
317*5f2bebf7SJérôme Gardou break;
318*5f2bebf7SJérôme Gardou case GL_BYTE:
319*5f2bebf7SJérôme Gardou {
320*5f2bebf7SJérôme Gardou GLbyte *dst = (GLbyte *) pixels + start + j * k;
321*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
322*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_BYTE( depth[i] );
323*5f2bebf7SJérôme Gardou }
324*5f2bebf7SJérôme Gardou }
325*5f2bebf7SJérôme Gardou break;
326*5f2bebf7SJérôme Gardou case GL_UNSIGNED_SHORT:
327*5f2bebf7SJérôme Gardou {
328*5f2bebf7SJérôme Gardou GLushort *dst = (GLushort *) pixels + start + j * k;
329*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
330*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_USHORT( depth[i] );
331*5f2bebf7SJérôme Gardou }
332*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
333*5f2bebf7SJérôme Gardou gl_swap2( (GLushort *) pixels + start + j * k, width );
334*5f2bebf7SJérôme Gardou }
335*5f2bebf7SJérôme Gardou }
336*5f2bebf7SJérôme Gardou break;
337*5f2bebf7SJérôme Gardou case GL_SHORT:
338*5f2bebf7SJérôme Gardou {
339*5f2bebf7SJérôme Gardou GLshort *dst = (GLshort *) pixels + start + j * k;
340*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
341*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_SHORT( depth[i] );
342*5f2bebf7SJérôme Gardou }
343*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
344*5f2bebf7SJérôme Gardou gl_swap2( (GLushort *) pixels + start + j * k, width );
345*5f2bebf7SJérôme Gardou }
346*5f2bebf7SJérôme Gardou }
347*5f2bebf7SJérôme Gardou break;
348*5f2bebf7SJérôme Gardou case GL_UNSIGNED_INT:
349*5f2bebf7SJérôme Gardou {
350*5f2bebf7SJérôme Gardou GLuint *dst = (GLuint *) pixels + start + j * k;
351*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
352*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UINT( depth[i] );
353*5f2bebf7SJérôme Gardou }
354*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
355*5f2bebf7SJérôme Gardou gl_swap4( (GLuint *) pixels + start + j * k, width );
356*5f2bebf7SJérôme Gardou }
357*5f2bebf7SJérôme Gardou }
358*5f2bebf7SJérôme Gardou break;
359*5f2bebf7SJérôme Gardou case GL_INT:
360*5f2bebf7SJérôme Gardou {
361*5f2bebf7SJérôme Gardou GLint *dst = (GLint *) pixels + start + j * k;
362*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
363*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_INT( depth[i] );
364*5f2bebf7SJérôme Gardou }
365*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
366*5f2bebf7SJérôme Gardou gl_swap4( (GLuint *) pixels + start + j * k, width );
367*5f2bebf7SJérôme Gardou }
368*5f2bebf7SJérôme Gardou }
369*5f2bebf7SJérôme Gardou break;
370*5f2bebf7SJérôme Gardou case GL_FLOAT:
371*5f2bebf7SJérôme Gardou {
372*5f2bebf7SJérôme Gardou GLfloat *dst = (GLfloat *) pixels + start + j * k;
373*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
374*5f2bebf7SJérôme Gardou *dst++ = depth[i];
375*5f2bebf7SJérôme Gardou }
376*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
377*5f2bebf7SJérôme Gardou gl_swap4( (GLuint *) pixels + start + j * k, width );
378*5f2bebf7SJérôme Gardou }
379*5f2bebf7SJérôme Gardou }
380*5f2bebf7SJérôme Gardou break;
381*5f2bebf7SJérôme Gardou default:
382*5f2bebf7SJérôme Gardou gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
383*5f2bebf7SJérôme Gardou }
384*5f2bebf7SJérôme Gardou }
385*5f2bebf7SJérôme Gardou }
386*5f2bebf7SJérôme Gardou }
387*5f2bebf7SJérôme Gardou
388*5f2bebf7SJérôme Gardou
389*5f2bebf7SJérôme Gardou
390*5f2bebf7SJérôme Gardou
read_stencil_pixels(GLcontext * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum type,GLvoid * pixels)391*5f2bebf7SJérôme Gardou static void read_stencil_pixels( GLcontext *ctx,
392*5f2bebf7SJérôme Gardou GLint x, GLint y,
393*5f2bebf7SJérôme Gardou GLsizei width, GLsizei height,
394*5f2bebf7SJérôme Gardou GLenum type, GLvoid *pixels )
395*5f2bebf7SJérôme Gardou {
396*5f2bebf7SJérôme Gardou GLint i, j;
397*5f2bebf7SJérôme Gardou GLuint a, s, k, l, start;
398*5f2bebf7SJérôme Gardou GLboolean shift_or_offset;
399*5f2bebf7SJérôme Gardou
400*5f2bebf7SJérôme Gardou if (ctx->Visual->StencilBits<=0) {
401*5f2bebf7SJérôme Gardou /* No stencil buffer */
402*5f2bebf7SJérôme Gardou gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
403*5f2bebf7SJérôme Gardou return;
404*5f2bebf7SJérôme Gardou }
405*5f2bebf7SJérôme Gardou
406*5f2bebf7SJérôme Gardou shift_or_offset = ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0;
407*5f2bebf7SJérôme Gardou
408*5f2bebf7SJérôme Gardou /* Size of each component */
409*5f2bebf7SJérôme Gardou s = gl_sizeof_type( type );
410*5f2bebf7SJérôme Gardou if (s<=0) {
411*5f2bebf7SJérôme Gardou gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
412*5f2bebf7SJérôme Gardou return;
413*5f2bebf7SJérôme Gardou }
414*5f2bebf7SJérôme Gardou
415*5f2bebf7SJérôme Gardou /* Compute packing parameters */
416*5f2bebf7SJérôme Gardou a = ctx->Pack.Alignment;
417*5f2bebf7SJérôme Gardou if (ctx->Pack.RowLength>0) {
418*5f2bebf7SJérôme Gardou l = ctx->Pack.RowLength;
419*5f2bebf7SJérôme Gardou }
420*5f2bebf7SJérôme Gardou else {
421*5f2bebf7SJérôme Gardou l = width;
422*5f2bebf7SJérôme Gardou }
423*5f2bebf7SJérôme Gardou /* k = offset between rows in components */
424*5f2bebf7SJérôme Gardou if (s>=a) {
425*5f2bebf7SJérôme Gardou k = l;
426*5f2bebf7SJérôme Gardou }
427*5f2bebf7SJérôme Gardou else {
428*5f2bebf7SJérôme Gardou k = a/s * CEILING( s*l, a );
429*5f2bebf7SJérôme Gardou }
430*5f2bebf7SJérôme Gardou
431*5f2bebf7SJérôme Gardou /* offset to first component returned */
432*5f2bebf7SJérôme Gardou start = ctx->Pack.SkipRows * k + ctx->Pack.SkipPixels;
433*5f2bebf7SJérôme Gardou
434*5f2bebf7SJérôme Gardou /* process image row by row */
435*5f2bebf7SJérôme Gardou for (j=0;j<height;j++,y++) {
436*5f2bebf7SJérôme Gardou GLubyte stencil[MAX_WIDTH];
437*5f2bebf7SJérôme Gardou
438*5f2bebf7SJérôme Gardou gl_read_stencil_span( ctx, width, x, y, stencil );
439*5f2bebf7SJérôme Gardou
440*5f2bebf7SJérôme Gardou if (shift_or_offset) {
441*5f2bebf7SJérôme Gardou GLuint s;
442*5f2bebf7SJérôme Gardou if (ctx->Pixel.IndexShift<0) {
443*5f2bebf7SJérôme Gardou /* right shift */
444*5f2bebf7SJérôme Gardou s = -ctx->Pixel.IndexShift;
445*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
446*5f2bebf7SJérôme Gardou stencil[i] = (stencil[i] >> s) + ctx->Pixel.IndexOffset;
447*5f2bebf7SJérôme Gardou }
448*5f2bebf7SJérôme Gardou }
449*5f2bebf7SJérôme Gardou else {
450*5f2bebf7SJérôme Gardou /* left shift */
451*5f2bebf7SJérôme Gardou s = ctx->Pixel.IndexShift;
452*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
453*5f2bebf7SJérôme Gardou stencil[i] = (stencil[i] << s) + ctx->Pixel.IndexOffset;
454*5f2bebf7SJérôme Gardou }
455*5f2bebf7SJérôme Gardou }
456*5f2bebf7SJérôme Gardou }
457*5f2bebf7SJérôme Gardou
458*5f2bebf7SJérôme Gardou if (ctx->Pixel.MapStencilFlag) {
459*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
460*5f2bebf7SJérôme Gardou stencil[i] = ctx->Pixel.MapStoS[ stencil[i] ];
461*5f2bebf7SJérôme Gardou }
462*5f2bebf7SJérôme Gardou }
463*5f2bebf7SJérôme Gardou
464*5f2bebf7SJérôme Gardou switch (type) {
465*5f2bebf7SJérôme Gardou case GL_UNSIGNED_BYTE:
466*5f2bebf7SJérôme Gardou {
467*5f2bebf7SJérôme Gardou GLubyte *dst = (GLubyte *) pixels + start + j * k;
468*5f2bebf7SJérôme Gardou MEMCPY( dst, stencil, width );
469*5f2bebf7SJérôme Gardou }
470*5f2bebf7SJérôme Gardou break;
471*5f2bebf7SJérôme Gardou case GL_BYTE:
472*5f2bebf7SJérôme Gardou {
473*5f2bebf7SJérôme Gardou GLbyte *dst = (GLbyte *) pixels + start + j * k;
474*5f2bebf7SJérôme Gardou MEMCPY( dst, stencil, width );
475*5f2bebf7SJérôme Gardou }
476*5f2bebf7SJérôme Gardou break;
477*5f2bebf7SJérôme Gardou case GL_UNSIGNED_SHORT:
478*5f2bebf7SJérôme Gardou {
479*5f2bebf7SJérôme Gardou GLushort *dst = (GLushort *) pixels + start + j * k;
480*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
481*5f2bebf7SJérôme Gardou *dst++ = (GLushort) stencil[i];
482*5f2bebf7SJérôme Gardou }
483*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
484*5f2bebf7SJérôme Gardou gl_swap2( (GLushort *) pixels + start +j * k, width );
485*5f2bebf7SJérôme Gardou }
486*5f2bebf7SJérôme Gardou }
487*5f2bebf7SJérôme Gardou break;
488*5f2bebf7SJérôme Gardou case GL_SHORT:
489*5f2bebf7SJérôme Gardou {
490*5f2bebf7SJérôme Gardou GLshort *dst = (GLshort *) pixels + start + j * k;
491*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
492*5f2bebf7SJérôme Gardou *dst++ = (GLshort) stencil[i];
493*5f2bebf7SJérôme Gardou }
494*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
495*5f2bebf7SJérôme Gardou gl_swap2( (GLushort *) pixels + start +j * k, width );
496*5f2bebf7SJérôme Gardou }
497*5f2bebf7SJérôme Gardou }
498*5f2bebf7SJérôme Gardou break;
499*5f2bebf7SJérôme Gardou case GL_UNSIGNED_INT:
500*5f2bebf7SJérôme Gardou {
501*5f2bebf7SJérôme Gardou GLuint *dst = (GLuint *) pixels + start + j * k;
502*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
503*5f2bebf7SJérôme Gardou *dst++ = (GLuint) stencil[i];
504*5f2bebf7SJérôme Gardou }
505*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
506*5f2bebf7SJérôme Gardou gl_swap4( (GLuint *) pixels + start +j * k, width );
507*5f2bebf7SJérôme Gardou }
508*5f2bebf7SJérôme Gardou }
509*5f2bebf7SJérôme Gardou break;
510*5f2bebf7SJérôme Gardou case GL_INT:
511*5f2bebf7SJérôme Gardou {
512*5f2bebf7SJérôme Gardou GLint *dst = (GLint *) pixels + start + j * k;
513*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
514*5f2bebf7SJérôme Gardou *dst++ = (GLint) stencil[i];
515*5f2bebf7SJérôme Gardou }
516*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
517*5f2bebf7SJérôme Gardou gl_swap4( (GLuint *) pixels + start +j * k, width );
518*5f2bebf7SJérôme Gardou }
519*5f2bebf7SJérôme Gardou }
520*5f2bebf7SJérôme Gardou break;
521*5f2bebf7SJérôme Gardou case GL_FLOAT:
522*5f2bebf7SJérôme Gardou {
523*5f2bebf7SJérôme Gardou GLfloat *dst = (GLfloat *) pixels + start + j * k;
524*5f2bebf7SJérôme Gardou for (i=0;i<width;i++) {
525*5f2bebf7SJérôme Gardou *dst++ = (GLfloat) stencil[i];
526*5f2bebf7SJérôme Gardou }
527*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes) {
528*5f2bebf7SJérôme Gardou gl_swap4( (GLuint *) pixels + start +j * k, width );
529*5f2bebf7SJérôme Gardou }
530*5f2bebf7SJérôme Gardou }
531*5f2bebf7SJérôme Gardou break;
532*5f2bebf7SJérôme Gardou default:
533*5f2bebf7SJérôme Gardou gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
534*5f2bebf7SJérôme Gardou }
535*5f2bebf7SJérôme Gardou }
536*5f2bebf7SJérôme Gardou }
537*5f2bebf7SJérôme Gardou
538*5f2bebf7SJérôme Gardou
539*5f2bebf7SJérôme Gardou
540*5f2bebf7SJérôme Gardou /*
541*5f2bebf7SJérôme Gardou * Test if scaling or biasing of colors is needed.
542*5f2bebf7SJérôme Gardou */
scale_or_bias_rgba(GLcontext * ctx)543*5f2bebf7SJérôme Gardou static GLboolean scale_or_bias_rgba( GLcontext *ctx )
544*5f2bebf7SJérôme Gardou {
545*5f2bebf7SJérôme Gardou if (ctx->Pixel.RedScale!=1.0F || ctx->Pixel.RedBias!=0.0F ||
546*5f2bebf7SJérôme Gardou ctx->Pixel.GreenScale!=1.0F || ctx->Pixel.GreenBias!=0.0F ||
547*5f2bebf7SJérôme Gardou ctx->Pixel.BlueScale!=1.0F || ctx->Pixel.BlueBias!=0.0F ||
548*5f2bebf7SJérôme Gardou ctx->Pixel.AlphaScale!=1.0F || ctx->Pixel.AlphaBias!=0.0F) {
549*5f2bebf7SJérôme Gardou return GL_TRUE;
550*5f2bebf7SJérôme Gardou }
551*5f2bebf7SJérôme Gardou else {
552*5f2bebf7SJérôme Gardou return GL_FALSE;
553*5f2bebf7SJérôme Gardou }
554*5f2bebf7SJérôme Gardou }
555*5f2bebf7SJérôme Gardou
556*5f2bebf7SJérôme Gardou
557*5f2bebf7SJérôme Gardou
558*5f2bebf7SJérôme Gardou /*
559*5f2bebf7SJérôme Gardou * Apply scale and bias factors to an array of RGBA pixels.
560*5f2bebf7SJérôme Gardou */
scale_and_bias_rgba(GLcontext * ctx,GLint n,GLfloat red[],GLfloat green[],GLfloat blue[],GLfloat alpha[])561*5f2bebf7SJérôme Gardou static void scale_and_bias_rgba( GLcontext *ctx,
562*5f2bebf7SJérôme Gardou GLint n,
563*5f2bebf7SJérôme Gardou GLfloat red[], GLfloat green[],
564*5f2bebf7SJérôme Gardou GLfloat blue[], GLfloat alpha[] )
565*5f2bebf7SJérôme Gardou {
566*5f2bebf7SJérôme Gardou register GLint i;
567*5f2bebf7SJérôme Gardou register GLfloat r, g, b, a;
568*5f2bebf7SJérôme Gardou
569*5f2bebf7SJérôme Gardou for (i=0;i<n;i++) {
570*5f2bebf7SJérôme Gardou r = red[i] * ctx->Pixel.RedScale + ctx->Pixel.RedBias;
571*5f2bebf7SJérôme Gardou g = green[i] * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
572*5f2bebf7SJérôme Gardou b = blue[i] * ctx->Pixel.BlueScale + ctx->Pixel.BlueBias;
573*5f2bebf7SJérôme Gardou a = alpha[i] * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
574*5f2bebf7SJérôme Gardou red[i] = CLAMP( r, 0.0F, 1.0F );
575*5f2bebf7SJérôme Gardou green[i] = CLAMP( g, 0.0F, 1.0F );
576*5f2bebf7SJérôme Gardou blue[i] = CLAMP( b, 0.0F, 1.0F );
577*5f2bebf7SJérôme Gardou alpha[i] = CLAMP( a, 0.0F, 1.0F );
578*5f2bebf7SJérôme Gardou }
579*5f2bebf7SJérôme Gardou }
580*5f2bebf7SJérôme Gardou
581*5f2bebf7SJérôme Gardou
582*5f2bebf7SJérôme Gardou
583*5f2bebf7SJérôme Gardou /*
584*5f2bebf7SJérôme Gardou * Apply pixel mapping to an array of RGBA pixels.
585*5f2bebf7SJérôme Gardou */
map_rgba(GLcontext * ctx,GLint n,GLfloat red[],GLfloat green[],GLfloat blue[],GLfloat alpha[])586*5f2bebf7SJérôme Gardou static void map_rgba( GLcontext *ctx,
587*5f2bebf7SJérôme Gardou GLint n,
588*5f2bebf7SJérôme Gardou GLfloat red[], GLfloat green[],
589*5f2bebf7SJérôme Gardou GLfloat blue[], GLfloat alpha[] )
590*5f2bebf7SJérôme Gardou {
591*5f2bebf7SJérôme Gardou GLfloat rscale = ctx->Pixel.MapRtoRsize-1;
592*5f2bebf7SJérôme Gardou GLfloat gscale = ctx->Pixel.MapGtoGsize-1;
593*5f2bebf7SJérôme Gardou GLfloat bscale = ctx->Pixel.MapBtoBsize-1;
594*5f2bebf7SJérôme Gardou GLfloat ascale = ctx->Pixel.MapAtoAsize-1;
595*5f2bebf7SJérôme Gardou GLint i;
596*5f2bebf7SJérôme Gardou
597*5f2bebf7SJérôme Gardou for (i=0;i<n;i++) {
598*5f2bebf7SJérôme Gardou red[i] = ctx->Pixel.MapRtoR[ (GLint) (red[i] * rscale) ];
599*5f2bebf7SJérôme Gardou green[i] = ctx->Pixel.MapGtoG[ (GLint) (green[i] * gscale) ];
600*5f2bebf7SJérôme Gardou blue[i] = ctx->Pixel.MapBtoB[ (GLint) (blue[i] * bscale) ];
601*5f2bebf7SJérôme Gardou alpha[i] = ctx->Pixel.MapAtoA[ (GLint) (alpha[i] * ascale) ];
602*5f2bebf7SJérôme Gardou }
603*5f2bebf7SJérôme Gardou }
604*5f2bebf7SJérôme Gardou
605*5f2bebf7SJérôme Gardou
606*5f2bebf7SJérôme Gardou
607*5f2bebf7SJérôme Gardou
608*5f2bebf7SJérôme Gardou /*
609*5f2bebf7SJérôme Gardou * Read R, G, B, A, RGB, L, or LA pixels.
610*5f2bebf7SJérôme Gardou */
read_color_pixels(GLcontext * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)611*5f2bebf7SJérôme Gardou static void read_color_pixels(GLcontext *ctx, GLint x, GLint y, GLsizei width,
612*5f2bebf7SJérôme Gardou GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
613*5f2bebf7SJérôme Gardou {
614*5f2bebf7SJérôme Gardou GLint i, j, n, a, s, l, k;
615*5f2bebf7SJérôme Gardou GLboolean scale_or_bias;
616*5f2bebf7SJérôme Gardou DEFARRAY(GLfloat, red, MAX_WIDTH);
617*5f2bebf7SJérôme Gardou DEFARRAY(GLfloat, green, MAX_WIDTH);
618*5f2bebf7SJérôme Gardou DEFARRAY(GLfloat, blue, MAX_WIDTH);
619*5f2bebf7SJérôme Gardou DEFARRAY(GLfloat, alpha, MAX_WIDTH);
620*5f2bebf7SJérôme Gardou DEFARRAY(GLfloat, luminance, MAX_WIDTH);
621*5f2bebf7SJérôme Gardou GLboolean r_flag, g_flag, b_flag, a_flag, l_flag;
622*5f2bebf7SJérôme Gardou GLboolean is_bgr = GL_FALSE;
623*5f2bebf7SJérôme Gardou GLuint start;
624*5f2bebf7SJérôme Gardou
625*5f2bebf7SJérôme Gardou scale_or_bias = scale_or_bias_rgba(ctx);
626*5f2bebf7SJérôme Gardou
627*5f2bebf7SJérôme Gardou /* Determine how many / which components to return */
628*5f2bebf7SJérôme Gardou r_flag = g_flag = b_flag = a_flag = l_flag = GL_FALSE;
629*5f2bebf7SJérôme Gardou switch (format)
630*5f2bebf7SJérôme Gardou {
631*5f2bebf7SJérôme Gardou case GL_RED:
632*5f2bebf7SJérôme Gardou r_flag = GL_TRUE;
633*5f2bebf7SJérôme Gardou n = 1;
634*5f2bebf7SJérôme Gardou break;
635*5f2bebf7SJérôme Gardou case GL_GREEN:
636*5f2bebf7SJérôme Gardou g_flag = GL_TRUE;
637*5f2bebf7SJérôme Gardou n = 1;
638*5f2bebf7SJérôme Gardou break;
639*5f2bebf7SJérôme Gardou case GL_BLUE:
640*5f2bebf7SJérôme Gardou b_flag = GL_TRUE;
641*5f2bebf7SJérôme Gardou n = 1;
642*5f2bebf7SJérôme Gardou break;
643*5f2bebf7SJérôme Gardou case GL_ALPHA:
644*5f2bebf7SJérôme Gardou a_flag = GL_TRUE;
645*5f2bebf7SJérôme Gardou n = 1;
646*5f2bebf7SJérôme Gardou break;
647*5f2bebf7SJérôme Gardou case GL_LUMINANCE:
648*5f2bebf7SJérôme Gardou l_flag = GL_TRUE;
649*5f2bebf7SJérôme Gardou n = 1;
650*5f2bebf7SJérôme Gardou break;
651*5f2bebf7SJérôme Gardou case GL_LUMINANCE_ALPHA:
652*5f2bebf7SJérôme Gardou l_flag = a_flag = GL_TRUE;
653*5f2bebf7SJérôme Gardou n = 2;
654*5f2bebf7SJérôme Gardou break;
655*5f2bebf7SJérôme Gardou case GL_RGB:
656*5f2bebf7SJérôme Gardou r_flag = g_flag = b_flag = GL_TRUE;
657*5f2bebf7SJérôme Gardou n = 3;
658*5f2bebf7SJérôme Gardou break;
659*5f2bebf7SJérôme Gardou case GL_BGR_EXT:
660*5f2bebf7SJérôme Gardou r_flag = g_flag = b_flag = GL_TRUE;
661*5f2bebf7SJérôme Gardou n = 3;
662*5f2bebf7SJérôme Gardou is_bgr = GL_TRUE;
663*5f2bebf7SJérôme Gardou break;
664*5f2bebf7SJérôme Gardou case GL_RGBA:
665*5f2bebf7SJérôme Gardou r_flag = g_flag = b_flag = a_flag = GL_TRUE;
666*5f2bebf7SJérôme Gardou n = 4;
667*5f2bebf7SJérôme Gardou break;
668*5f2bebf7SJérôme Gardou case GL_BGRA_EXT:
669*5f2bebf7SJérôme Gardou r_flag = g_flag = b_flag = a_flag = GL_TRUE;
670*5f2bebf7SJérôme Gardou n = 4;
671*5f2bebf7SJérôme Gardou is_bgr = GL_TRUE;
672*5f2bebf7SJérôme Gardou break;
673*5f2bebf7SJérôme Gardou default:
674*5f2bebf7SJérôme Gardou gl_error(ctx, GL_INVALID_ENUM, "glReadPixels(format)");
675*5f2bebf7SJérôme Gardou UNDEFARRAY( red );
676*5f2bebf7SJérôme Gardou UNDEFARRAY( green );
677*5f2bebf7SJérôme Gardou UNDEFARRAY( blue );
678*5f2bebf7SJérôme Gardou UNDEFARRAY( alpha );
679*5f2bebf7SJérôme Gardou UNDEFARRAY( luminance );
680*5f2bebf7SJérôme Gardou return;
681*5f2bebf7SJérôme Gardou }
682*5f2bebf7SJérôme Gardou
683*5f2bebf7SJérôme Gardou /* Size of each component */
684*5f2bebf7SJérôme Gardou s = gl_sizeof_type(type);
685*5f2bebf7SJérôme Gardou if (s <= 0)
686*5f2bebf7SJérôme Gardou {
687*5f2bebf7SJérôme Gardou gl_error(ctx, GL_INVALID_ENUM, "glReadPixels(type)");
688*5f2bebf7SJérôme Gardou UNDEFARRAY( red );
689*5f2bebf7SJérôme Gardou UNDEFARRAY( green );
690*5f2bebf7SJérôme Gardou UNDEFARRAY( blue );
691*5f2bebf7SJérôme Gardou UNDEFARRAY( alpha );
692*5f2bebf7SJérôme Gardou UNDEFARRAY( luminance );
693*5f2bebf7SJérôme Gardou return;
694*5f2bebf7SJérôme Gardou }
695*5f2bebf7SJérôme Gardou
696*5f2bebf7SJérôme Gardou /* Compute packing parameters */
697*5f2bebf7SJérôme Gardou a = ctx->Pack.Alignment;
698*5f2bebf7SJérôme Gardou if (ctx->Pack.RowLength > 0)
699*5f2bebf7SJérôme Gardou {
700*5f2bebf7SJérôme Gardou l = ctx->Pack.RowLength;
701*5f2bebf7SJérôme Gardou }
702*5f2bebf7SJérôme Gardou else
703*5f2bebf7SJérôme Gardou {
704*5f2bebf7SJérôme Gardou l = width;
705*5f2bebf7SJérôme Gardou }
706*5f2bebf7SJérôme Gardou /* k = offset between rows in components */
707*5f2bebf7SJérôme Gardou if (s >= a)
708*5f2bebf7SJérôme Gardou {
709*5f2bebf7SJérôme Gardou k = n * l;
710*5f2bebf7SJérôme Gardou }
711*5f2bebf7SJérôme Gardou else
712*5f2bebf7SJérôme Gardou {
713*5f2bebf7SJérôme Gardou k = a / s * CEILING(s * n * l, a);
714*5f2bebf7SJérôme Gardou }
715*5f2bebf7SJérôme Gardou
716*5f2bebf7SJérôme Gardou /* offset to first component returned */
717*5f2bebf7SJérôme Gardou start = ctx->Pack.SkipRows * k + ctx->Pack.SkipPixels * n;
718*5f2bebf7SJérôme Gardou
719*5f2bebf7SJérôme Gardou /* process image row by row */
720*5f2bebf7SJérôme Gardou for (j = 0; j < height; j++, y++)
721*5f2bebf7SJérôme Gardou {
722*5f2bebf7SJérôme Gardou /*
723*5f2bebf7SJérôme Gardou * Read the pixels from frame buffer
724*5f2bebf7SJérôme Gardou */
725*5f2bebf7SJérôme Gardou if (ctx->Visual->RGBAflag)
726*5f2bebf7SJérôme Gardou {
727*5f2bebf7SJérôme Gardou DEFARRAY(GLubyte, r, MAX_WIDTH);
728*5f2bebf7SJérôme Gardou DEFARRAY(GLubyte, g, MAX_WIDTH);
729*5f2bebf7SJérôme Gardou DEFARRAY(GLubyte, b, MAX_WIDTH);
730*5f2bebf7SJérôme Gardou DEFARRAY(GLubyte, a, MAX_WIDTH);
731*5f2bebf7SJérôme Gardou GLfloat rscale = 1.0F * ctx->Visual->InvRedScale;
732*5f2bebf7SJérôme Gardou GLfloat gscale = 1.0F * ctx->Visual->InvGreenScale;
733*5f2bebf7SJérôme Gardou GLfloat bscale = 1.0F * ctx->Visual->InvBlueScale;
734*5f2bebf7SJérôme Gardou GLfloat ascale = 1.0F * ctx->Visual->InvAlphaScale;
735*5f2bebf7SJérôme Gardou
736*5f2bebf7SJérôme Gardou /* read colors and convert to floats */
737*5f2bebf7SJérôme Gardou (*ctx->Driver.ReadColorSpan)(ctx, width, x, y, r, g, b, a);
738*5f2bebf7SJérôme Gardou if (ctx->RasterMask & ALPHABUF_BIT)
739*5f2bebf7SJérôme Gardou {
740*5f2bebf7SJérôme Gardou gl_read_alpha_span(ctx, width, x, y, a);
741*5f2bebf7SJérôme Gardou }
742*5f2bebf7SJérôme Gardou for (i = 0; i < width; i++)
743*5f2bebf7SJérôme Gardou {
744*5f2bebf7SJérôme Gardou red[i] = r[i] * rscale;
745*5f2bebf7SJérôme Gardou green[i] = g[i] * gscale;
746*5f2bebf7SJérôme Gardou blue[i] = b[i] * bscale;
747*5f2bebf7SJérôme Gardou alpha[i] = a[i] * ascale;
748*5f2bebf7SJérôme Gardou }
749*5f2bebf7SJérôme Gardou
750*5f2bebf7SJérôme Gardou if (scale_or_bias)
751*5f2bebf7SJérôme Gardou {
752*5f2bebf7SJérôme Gardou scale_and_bias_rgba(ctx, width, red, green, blue, alpha);
753*5f2bebf7SJérôme Gardou }
754*5f2bebf7SJérôme Gardou if (ctx->Pixel.MapColorFlag)
755*5f2bebf7SJérôme Gardou {
756*5f2bebf7SJérôme Gardou map_rgba(ctx, width, red, green, blue, alpha);
757*5f2bebf7SJérôme Gardou }
758*5f2bebf7SJérôme Gardou UNDEFARRAY(r);
759*5f2bebf7SJérôme Gardou UNDEFARRAY(g);
760*5f2bebf7SJérôme Gardou UNDEFARRAY(b);
761*5f2bebf7SJérôme Gardou UNDEFARRAY(a);
762*5f2bebf7SJérôme Gardou }
763*5f2bebf7SJérôme Gardou else
764*5f2bebf7SJérôme Gardou {
765*5f2bebf7SJérôme Gardou /* convert CI values to RGBA */
766*5f2bebf7SJérôme Gardou GLuint index[MAX_WIDTH];
767*5f2bebf7SJérôme Gardou (*ctx->Driver.ReadIndexSpan)(ctx, width, x, y, index);
768*5f2bebf7SJérôme Gardou
769*5f2bebf7SJérôme Gardou if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset != 0)
770*5f2bebf7SJérôme Gardou {
771*5f2bebf7SJérôme Gardou GLuint s;
772*5f2bebf7SJérôme Gardou if (ctx->Pixel.IndexShift < 0)
773*5f2bebf7SJérôme Gardou {
774*5f2bebf7SJérôme Gardou /* right shift */
775*5f2bebf7SJérôme Gardou s = -ctx->Pixel.IndexShift;
776*5f2bebf7SJérôme Gardou for (i = 0; i < width; i++)
777*5f2bebf7SJérôme Gardou {
778*5f2bebf7SJérôme Gardou index[i] = (index[i] >> s) + ctx->Pixel.IndexOffset;
779*5f2bebf7SJérôme Gardou }
780*5f2bebf7SJérôme Gardou }
781*5f2bebf7SJérôme Gardou else
782*5f2bebf7SJérôme Gardou {
783*5f2bebf7SJérôme Gardou /* left shift */
784*5f2bebf7SJérôme Gardou s = ctx->Pixel.IndexShift;
785*5f2bebf7SJérôme Gardou for (i = 0; i < width; i++)
786*5f2bebf7SJérôme Gardou {
787*5f2bebf7SJérôme Gardou index[i] = (index[i] << s) + ctx->Pixel.IndexOffset;
788*5f2bebf7SJérôme Gardou }
789*5f2bebf7SJérôme Gardou }
790*5f2bebf7SJérôme Gardou }
791*5f2bebf7SJérôme Gardou
792*5f2bebf7SJérôme Gardou for (i = 0; i < width; i++)
793*5f2bebf7SJérôme Gardou {
794*5f2bebf7SJérôme Gardou red[i] = ctx->Pixel.MapItoR[index[i]];
795*5f2bebf7SJérôme Gardou green[i] = ctx->Pixel.MapItoG[index[i]];
796*5f2bebf7SJérôme Gardou blue[i] = ctx->Pixel.MapItoB[index[i]];
797*5f2bebf7SJérôme Gardou alpha[i] = ctx->Pixel.MapItoA[index[i]];
798*5f2bebf7SJérôme Gardou }
799*5f2bebf7SJérôme Gardou }
800*5f2bebf7SJérôme Gardou
801*5f2bebf7SJérôme Gardou if (l_flag)
802*5f2bebf7SJérôme Gardou {
803*5f2bebf7SJérôme Gardou for (i = 0; i < width; i++)
804*5f2bebf7SJérôme Gardou {
805*5f2bebf7SJérôme Gardou GLfloat sum = red[i] + green[i] + blue[i];
806*5f2bebf7SJérôme Gardou luminance[i] = CLAMP(sum, 0.0F, 1.0F);
807*5f2bebf7SJérôme Gardou }
808*5f2bebf7SJérôme Gardou }
809*5f2bebf7SJérôme Gardou
810*5f2bebf7SJérôme Gardou /*
811*5f2bebf7SJérôme Gardou * Pack/transfer/store the pixels
812*5f2bebf7SJérôme Gardou */
813*5f2bebf7SJérôme Gardou
814*5f2bebf7SJérôme Gardou switch (type)
815*5f2bebf7SJérôme Gardou {
816*5f2bebf7SJérôme Gardou case GL_UNSIGNED_BYTE:
817*5f2bebf7SJérôme Gardou {
818*5f2bebf7SJérôme Gardou GLubyte *dst = (GLubyte *) pixels + start + j * k;
819*5f2bebf7SJérôme Gardou for (i = 0; i < width; i++)
820*5f2bebf7SJérôme Gardou {
821*5f2bebf7SJérôme Gardou if (is_bgr)
822*5f2bebf7SJérôme Gardou {
823*5f2bebf7SJérôme Gardou if (b_flag)
824*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UBYTE(blue[i]);
825*5f2bebf7SJérôme Gardou if (g_flag)
826*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UBYTE(green[i]);
827*5f2bebf7SJérôme Gardou if (r_flag)
828*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UBYTE(red[i]);
829*5f2bebf7SJérôme Gardou }
830*5f2bebf7SJérôme Gardou else
831*5f2bebf7SJérôme Gardou {
832*5f2bebf7SJérôme Gardou if (r_flag)
833*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UBYTE(red[i]);
834*5f2bebf7SJérôme Gardou if (g_flag)
835*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UBYTE(green[i]);
836*5f2bebf7SJérôme Gardou if (b_flag)
837*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UBYTE(blue[i]);
838*5f2bebf7SJérôme Gardou }
839*5f2bebf7SJérôme Gardou if (l_flag)
840*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UBYTE(luminance[i]);
841*5f2bebf7SJérôme Gardou if (a_flag)
842*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UBYTE(alpha[i]);
843*5f2bebf7SJérôme Gardou }
844*5f2bebf7SJérôme Gardou break;
845*5f2bebf7SJérôme Gardou }
846*5f2bebf7SJérôme Gardou case GL_BYTE:
847*5f2bebf7SJérôme Gardou {
848*5f2bebf7SJérôme Gardou GLbyte *dst = (GLbyte *) pixels + start + j * k;
849*5f2bebf7SJérôme Gardou for (i = 0; i < width; i++)
850*5f2bebf7SJérôme Gardou {
851*5f2bebf7SJérôme Gardou if (is_bgr)
852*5f2bebf7SJérôme Gardou {
853*5f2bebf7SJérôme Gardou if (b_flag)
854*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_BYTE(blue[i]);
855*5f2bebf7SJérôme Gardou if (g_flag)
856*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_BYTE(green[i]);
857*5f2bebf7SJérôme Gardou if (r_flag)
858*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_BYTE(red[i]);
859*5f2bebf7SJérôme Gardou }
860*5f2bebf7SJérôme Gardou else
861*5f2bebf7SJérôme Gardou {
862*5f2bebf7SJérôme Gardou if (r_flag)
863*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_BYTE(red[i]);
864*5f2bebf7SJérôme Gardou if (g_flag)
865*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_BYTE(green[i]);
866*5f2bebf7SJérôme Gardou if (b_flag)
867*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_BYTE(blue[i]);
868*5f2bebf7SJérôme Gardou }
869*5f2bebf7SJérôme Gardou if (l_flag)
870*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_BYTE(luminance[i]);
871*5f2bebf7SJérôme Gardou if (a_flag)
872*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_BYTE(alpha[i]);
873*5f2bebf7SJérôme Gardou }
874*5f2bebf7SJérôme Gardou break;
875*5f2bebf7SJérôme Gardou }
876*5f2bebf7SJérôme Gardou case GL_UNSIGNED_SHORT:
877*5f2bebf7SJérôme Gardou {
878*5f2bebf7SJérôme Gardou GLushort *dst = (GLushort *) pixels + start + j * k;
879*5f2bebf7SJérôme Gardou for (i = 0; i < width; i++)
880*5f2bebf7SJérôme Gardou {
881*5f2bebf7SJérôme Gardou if (is_bgr)
882*5f2bebf7SJérôme Gardou {
883*5f2bebf7SJérôme Gardou if (b_flag)
884*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_USHORT(blue[i]);
885*5f2bebf7SJérôme Gardou if (g_flag)
886*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_USHORT(green[i]);
887*5f2bebf7SJérôme Gardou if (r_flag)
888*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_USHORT(red[i]);
889*5f2bebf7SJérôme Gardou }
890*5f2bebf7SJérôme Gardou else
891*5f2bebf7SJérôme Gardou {
892*5f2bebf7SJérôme Gardou if (r_flag)
893*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_USHORT(red[i]);
894*5f2bebf7SJérôme Gardou if (g_flag)
895*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_USHORT(green[i]);
896*5f2bebf7SJérôme Gardou if (b_flag)
897*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_USHORT(blue[i]);
898*5f2bebf7SJérôme Gardou }
899*5f2bebf7SJérôme Gardou if (l_flag)
900*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_USHORT(luminance[i]);
901*5f2bebf7SJérôme Gardou if (a_flag)
902*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_USHORT(alpha[i]);
903*5f2bebf7SJérôme Gardou }
904*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes)
905*5f2bebf7SJérôme Gardou {
906*5f2bebf7SJérôme Gardou gl_swap2((GLushort *) pixels + start + j * k, width * n);
907*5f2bebf7SJérôme Gardou }
908*5f2bebf7SJérôme Gardou break;
909*5f2bebf7SJérôme Gardou }
910*5f2bebf7SJérôme Gardou case GL_SHORT:
911*5f2bebf7SJérôme Gardou {
912*5f2bebf7SJérôme Gardou GLshort *dst = (GLshort *) pixels + start + j * k;
913*5f2bebf7SJérôme Gardou for (i = 0; i < width; i++)
914*5f2bebf7SJérôme Gardou {
915*5f2bebf7SJérôme Gardou if (is_bgr)
916*5f2bebf7SJérôme Gardou {
917*5f2bebf7SJérôme Gardou if (b_flag)
918*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_SHORT(blue[i]);
919*5f2bebf7SJérôme Gardou if (g_flag)
920*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_SHORT(green[i]);
921*5f2bebf7SJérôme Gardou if (r_flag)
922*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_SHORT(red[i]);
923*5f2bebf7SJérôme Gardou }
924*5f2bebf7SJérôme Gardou else
925*5f2bebf7SJérôme Gardou {
926*5f2bebf7SJérôme Gardou if (r_flag)
927*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_SHORT(red[i]);
928*5f2bebf7SJérôme Gardou if (g_flag)
929*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_SHORT(green[i]);
930*5f2bebf7SJérôme Gardou if (b_flag)
931*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_SHORT(blue[i]);
932*5f2bebf7SJérôme Gardou }
933*5f2bebf7SJérôme Gardou if (l_flag)
934*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_SHORT(luminance[i]);
935*5f2bebf7SJérôme Gardou if (a_flag)
936*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_SHORT(alpha[i]);
937*5f2bebf7SJérôme Gardou }
938*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes)
939*5f2bebf7SJérôme Gardou {
940*5f2bebf7SJérôme Gardou gl_swap2((GLushort *) pixels + start + j * k, width * n);
941*5f2bebf7SJérôme Gardou }
942*5f2bebf7SJérôme Gardou break;
943*5f2bebf7SJérôme Gardou }
944*5f2bebf7SJérôme Gardou case GL_UNSIGNED_INT:
945*5f2bebf7SJérôme Gardou {
946*5f2bebf7SJérôme Gardou GLuint *dst = (GLuint *) pixels + start + j * k;
947*5f2bebf7SJérôme Gardou for (i = 0; i < width; i++)
948*5f2bebf7SJérôme Gardou {
949*5f2bebf7SJérôme Gardou if (is_bgr)
950*5f2bebf7SJérôme Gardou {
951*5f2bebf7SJérôme Gardou if (b_flag)
952*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UINT(blue[i]);
953*5f2bebf7SJérôme Gardou if (g_flag)
954*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UINT(green[i]);
955*5f2bebf7SJérôme Gardou if (r_flag)
956*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UINT(red[i]);
957*5f2bebf7SJérôme Gardou }
958*5f2bebf7SJérôme Gardou else
959*5f2bebf7SJérôme Gardou {
960*5f2bebf7SJérôme Gardou if (r_flag)
961*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UINT(red[i]);
962*5f2bebf7SJérôme Gardou if (g_flag)
963*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UINT(green[i]);
964*5f2bebf7SJérôme Gardou if (b_flag)
965*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UINT(blue[i]);
966*5f2bebf7SJérôme Gardou }
967*5f2bebf7SJérôme Gardou if (l_flag)
968*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UINT(luminance[i]);
969*5f2bebf7SJérôme Gardou if (a_flag)
970*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_UINT(alpha[i]);
971*5f2bebf7SJérôme Gardou }
972*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes)
973*5f2bebf7SJérôme Gardou {
974*5f2bebf7SJérôme Gardou gl_swap4((GLuint *) pixels + start + j * k, width * n);
975*5f2bebf7SJérôme Gardou }
976*5f2bebf7SJérôme Gardou break;
977*5f2bebf7SJérôme Gardou }
978*5f2bebf7SJérôme Gardou case GL_INT:
979*5f2bebf7SJérôme Gardou {
980*5f2bebf7SJérôme Gardou GLint *dst = (GLint *) pixels + start + j * k;
981*5f2bebf7SJérôme Gardou for (i = 0; i < width; i++)
982*5f2bebf7SJérôme Gardou {
983*5f2bebf7SJérôme Gardou if (is_bgr)
984*5f2bebf7SJérôme Gardou {
985*5f2bebf7SJérôme Gardou if (b_flag)
986*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_INT(blue[i]);
987*5f2bebf7SJérôme Gardou if (g_flag)
988*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_INT(green[i]);
989*5f2bebf7SJérôme Gardou if (r_flag)
990*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_INT(red[i]);
991*5f2bebf7SJérôme Gardou }
992*5f2bebf7SJérôme Gardou else
993*5f2bebf7SJérôme Gardou {
994*5f2bebf7SJérôme Gardou if (r_flag)
995*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_INT(red[i]);
996*5f2bebf7SJérôme Gardou if (g_flag)
997*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_INT(green[i]);
998*5f2bebf7SJérôme Gardou if (b_flag)
999*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_INT(blue[i]);
1000*5f2bebf7SJérôme Gardou }
1001*5f2bebf7SJérôme Gardou if (l_flag)
1002*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_INT(luminance[i]);
1003*5f2bebf7SJérôme Gardou if (a_flag)
1004*5f2bebf7SJérôme Gardou *dst++ = FLOAT_TO_INT(alpha[i]);
1005*5f2bebf7SJérôme Gardou }
1006*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes)
1007*5f2bebf7SJérôme Gardou {
1008*5f2bebf7SJérôme Gardou gl_swap4((GLuint *) pixels + start + j * k, width * n);
1009*5f2bebf7SJérôme Gardou }
1010*5f2bebf7SJérôme Gardou break;
1011*5f2bebf7SJérôme Gardou }
1012*5f2bebf7SJérôme Gardou case GL_FLOAT:
1013*5f2bebf7SJérôme Gardou {
1014*5f2bebf7SJérôme Gardou GLfloat *dst = (GLfloat *) pixels + start + j * k;
1015*5f2bebf7SJérôme Gardou for (i = 0; i < width; i++)
1016*5f2bebf7SJérôme Gardou {
1017*5f2bebf7SJérôme Gardou if (is_bgr)
1018*5f2bebf7SJérôme Gardou {
1019*5f2bebf7SJérôme Gardou if (b_flag)
1020*5f2bebf7SJérôme Gardou *dst++ = blue[i];
1021*5f2bebf7SJérôme Gardou if (g_flag)
1022*5f2bebf7SJérôme Gardou *dst++ = green[i];
1023*5f2bebf7SJérôme Gardou if (r_flag)
1024*5f2bebf7SJérôme Gardou *dst++ = red[i];
1025*5f2bebf7SJérôme Gardou }
1026*5f2bebf7SJérôme Gardou else
1027*5f2bebf7SJérôme Gardou {
1028*5f2bebf7SJérôme Gardou if (r_flag)
1029*5f2bebf7SJérôme Gardou *dst++ = red[i];
1030*5f2bebf7SJérôme Gardou if (g_flag)
1031*5f2bebf7SJérôme Gardou *dst++ = green[i];
1032*5f2bebf7SJérôme Gardou if (b_flag)
1033*5f2bebf7SJérôme Gardou *dst++ = blue[i];
1034*5f2bebf7SJérôme Gardou }
1035*5f2bebf7SJérôme Gardou if (l_flag)
1036*5f2bebf7SJérôme Gardou *dst++ = luminance[i];
1037*5f2bebf7SJérôme Gardou if (a_flag)
1038*5f2bebf7SJérôme Gardou *dst++ = alpha[i];
1039*5f2bebf7SJérôme Gardou }
1040*5f2bebf7SJérôme Gardou if (ctx->Pack.SwapBytes)
1041*5f2bebf7SJérôme Gardou {
1042*5f2bebf7SJérôme Gardou gl_swap4((GLuint *) pixels + start + j * k, width * n);
1043*5f2bebf7SJérôme Gardou }
1044*5f2bebf7SJérôme Gardou break;
1045*5f2bebf7SJérôme Gardou }
1046*5f2bebf7SJérôme Gardou default:
1047*5f2bebf7SJérôme Gardou gl_error(ctx, GL_INVALID_ENUM, "glReadPixels(type)");
1048*5f2bebf7SJérôme Gardou }
1049*5f2bebf7SJérôme Gardou }
1050*5f2bebf7SJérôme Gardou UNDEFARRAY( red );
1051*5f2bebf7SJérôme Gardou UNDEFARRAY( green );
1052*5f2bebf7SJérôme Gardou UNDEFARRAY( blue );
1053*5f2bebf7SJérôme Gardou UNDEFARRAY( alpha );
1054*5f2bebf7SJérôme Gardou UNDEFARRAY( luminance );
1055*5f2bebf7SJérôme Gardou }
1056*5f2bebf7SJérôme Gardou
1057*5f2bebf7SJérôme Gardou
1058*5f2bebf7SJérôme Gardou
gl_ReadPixels(GLcontext * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)1059*5f2bebf7SJérôme Gardou void gl_ReadPixels( GLcontext *ctx,
1060*5f2bebf7SJérôme Gardou GLint x, GLint y, GLsizei width, GLsizei height,
1061*5f2bebf7SJérôme Gardou GLenum format, GLenum type, GLvoid *pixels )
1062*5f2bebf7SJérôme Gardou {
1063*5f2bebf7SJérôme Gardou if (INSIDE_BEGIN_END(ctx))
1064*5f2bebf7SJérôme Gardou {
1065*5f2bebf7SJérôme Gardou gl_error(ctx, GL_INVALID_OPERATION, "glReadPixels");
1066*5f2bebf7SJérôme Gardou return;
1067*5f2bebf7SJérôme Gardou }
1068*5f2bebf7SJérôme Gardou
1069*5f2bebf7SJérôme Gardou (void) (*ctx->Driver.SetBuffer)(ctx, ctx->Pixel.ReadBuffer);
1070*5f2bebf7SJérôme Gardou
1071*5f2bebf7SJérôme Gardou switch (format)
1072*5f2bebf7SJérôme Gardou {
1073*5f2bebf7SJérôme Gardou case GL_COLOR_INDEX:
1074*5f2bebf7SJérôme Gardou read_index_pixels(ctx, x, y, width, height, type, pixels);
1075*5f2bebf7SJérôme Gardou break;
1076*5f2bebf7SJérôme Gardou case GL_STENCIL_INDEX:
1077*5f2bebf7SJérôme Gardou read_stencil_pixels(ctx, x, y, width, height, type, pixels);
1078*5f2bebf7SJérôme Gardou break;
1079*5f2bebf7SJérôme Gardou case GL_DEPTH_COMPONENT:
1080*5f2bebf7SJérôme Gardou read_depth_pixels(ctx, x, y, width, height, type, pixels);
1081*5f2bebf7SJérôme Gardou break;
1082*5f2bebf7SJérôme Gardou case GL_RED:
1083*5f2bebf7SJérôme Gardou case GL_GREEN:
1084*5f2bebf7SJérôme Gardou case GL_BLUE:
1085*5f2bebf7SJérôme Gardou case GL_ALPHA:
1086*5f2bebf7SJérôme Gardou case GL_RGB:
1087*5f2bebf7SJérôme Gardou case GL_BGR_EXT:
1088*5f2bebf7SJérôme Gardou case GL_LUMINANCE:
1089*5f2bebf7SJérôme Gardou case GL_LUMINANCE_ALPHA:
1090*5f2bebf7SJérôme Gardou case GL_RGBA:
1091*5f2bebf7SJérôme Gardou case GL_BGRA_EXT:
1092*5f2bebf7SJérôme Gardou read_color_pixels(ctx, x, y, width, height, format, type, pixels);
1093*5f2bebf7SJérôme Gardou break;
1094*5f2bebf7SJérôme Gardou default:
1095*5f2bebf7SJérôme Gardou gl_error(ctx, GL_INVALID_ENUM, "glReadPixels(format)");
1096*5f2bebf7SJérôme Gardou }
1097*5f2bebf7SJérôme Gardou
1098*5f2bebf7SJérôme Gardou (void) (*ctx->Driver.SetBuffer)(ctx, ctx->Color.DrawBuffer);
1099*5f2bebf7SJérôme Gardou }
1100