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