source: trunk/src/opengl/mesa/readpix.c

Last change on this file was 3598, checked in by jeroen, 25 years ago

* empty log message *

File size: 22.3 KB
RevLine 
[3598]1/* $Id: readpix.c,v 1.3 2000-05-23 20:40:52 jeroen Exp $ */
[2938]2
3/*
4 * Mesa 3-D graphics library
[3598]5 * Version: 3.3
[2938]6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28#ifdef PC_HEADER
29#include "all.h"
30#else
[3598]31#include "glheader.h"
[2938]32#include "alphabuf.h"
[2962]33#include "types.h"
[2938]34#include "context.h"
35#include "depth.h"
36#include "feedback.h"
37#include "image.h"
38#include "macros.h"
39#include "pixel.h"
40#include "readpix.h"
41#include "span.h"
42#include "stencil.h"
[3598]43#include "mem.h"
[2938]44#endif
45
46
47
48
49/*
50 * Read a block of color index pixels.
51 */
52static void read_index_pixels( GLcontext *ctx,
53 GLint x, GLint y,
[2962]54 GLsizei width, GLsizei height,
[3598]55 GLenum type, GLvoid *pixels,
[2938]56 const struct gl_pixelstore_attrib *packing )
57{
58 GLint i, j, readWidth;
59
60 /* error checking */
61 if (ctx->Visual->RGBAflag) {
62 gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
63 return;
64 }
65
[3598]66 ASSERT(ctx->Driver.SetReadBuffer);
67 (*ctx->Driver.SetReadBuffer)(ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer);
[2938]68
69 readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
70
71 /* process image row by row */
72 for (j=0;j<height;j++,y++) {
73 GLuint index[MAX_WIDTH];
74 GLvoid *dest;
75
76 (*ctx->Driver.ReadCI32Span)( ctx, readWidth, x, y, index );
77
78 if (ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0) {
79 gl_shift_and_offset_ci( ctx, readWidth, index);
80 }
81
82 if (ctx->Pixel.MapColorFlag) {
83 gl_map_ci(ctx, readWidth, index);
84 }
85
[3598]86 dest = _mesa_image_address(packing, pixels,
[2938]87 width, height, GL_COLOR_INDEX, type, 0, j, 0);
88
89 switch (type) {
[3598]90 case GL_UNSIGNED_BYTE:
91 {
[2938]92 GLubyte *dst = (GLubyte *) dest;
[3598]93 for (i=0;i<readWidth;i++) {
94 *dst++ = (GLubyte) index[i];
95 }
96 }
97 break;
98 case GL_BYTE:
99 {
[2938]100 GLbyte *dst = (GLbyte *) dest;
[3598]101 for (i=0;i<readWidth;i++) {
102 dst[i] = (GLbyte) index[i];
103 }
104 }
105 break;
106 case GL_UNSIGNED_SHORT:
107 {
[2938]108 GLushort *dst = (GLushort *) dest;
[3598]109 for (i=0;i<readWidth;i++) {
110 dst[i] = (GLushort) index[i];
111 }
112 if (packing->SwapBytes) {
113 _mesa_swap2( (GLushort *) dst, readWidth );
114 }
115 }
116 break;
117 case GL_SHORT:
118 {
[2938]119 GLshort *dst = (GLshort *) dest;
[3598]120 for (i=0;i<readWidth;i++) {
121 dst[i] = (GLshort) index[i];
122 }
123 if (packing->SwapBytes) {
124 _mesa_swap2( (GLushort *) dst, readWidth );
125 }
126 }
127 break;
128 case GL_UNSIGNED_INT:
129 {
[2938]130 GLuint *dst = (GLuint *) dest;
[3598]131 for (i=0;i<readWidth;i++) {
132 dst[i] = (GLuint) index[i];
133 }
134 if (packing->SwapBytes) {
135 _mesa_swap4( (GLuint *) dst, readWidth );
136 }
137 }
138 break;
139 case GL_INT:
140 {
[2938]141 GLint *dst = (GLint *) dest;
[3598]142 for (i=0;i<readWidth;i++) {
143 dst[i] = (GLint) index[i];
144 }
145 if (packing->SwapBytes) {
146 _mesa_swap4( (GLuint *) dst, readWidth );
147 }
148 }
149 break;
150 case GL_FLOAT:
151 {
[2938]152 GLfloat *dst = (GLfloat *) dest;
[3598]153 for (i=0;i<readWidth;i++) {
154 dst[i] = (GLfloat) index[i];
155 }
156 if (packing->SwapBytes) {
157 _mesa_swap4( (GLuint *) dst, readWidth );
158 }
159 }
160 break;
[2938]161 default:
162 gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
163 j = height + 1; /* exit loop */
164 }
165 }
166
[3598]167 (*ctx->Driver.SetReadBuffer)(ctx, ctx->DrawBuffer, ctx->Color.DriverDrawBuffer);
[2938]168}
169
170
171
172static void read_depth_pixels( GLcontext *ctx,
173 GLint x, GLint y,
[3598]174 GLsizei width, GLsizei height,
175 GLenum type, GLvoid *pixels,
[2938]176 const struct gl_pixelstore_attrib *packing )
177{
178 GLint i, j, readWidth;
179 GLboolean bias_or_scale;
180
181 /* Error checking */
182 if (ctx->Visual->DepthBits <= 0) {
183 /* No depth buffer */
184 gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
185 return;
186 }
187
188 readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
189
190 if (type != GL_BYTE &&
191 type != GL_UNSIGNED_BYTE &&
192 type != GL_SHORT &&
193 type != GL_UNSIGNED_SHORT &&
194 type != GL_INT &&
195 type != GL_UNSIGNED_INT &&
196 type != GL_FLOAT) {
197 gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels(depth type)");
198 return;
199 }
200
201 bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
202
203 if (type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort)
204 && !bias_or_scale && !packing->SwapBytes) {
205 /* Special case: directly read 16-bit unsigned depth values. */
206 for (j=0;j<height;j++,y++) {
[3598]207 GLdepth depth[MAX_WIDTH];
208 GLushort *dst = (GLushort*) _mesa_image_address( packing, pixels,
[2938]209 width, height, GL_DEPTH_COMPONENT, type, 0, j, 0 );
[3598]210 GLint i;
211 (*ctx->Driver.ReadDepthSpan)( ctx, width, x, y, depth);
212 for (i = 0; i < width; i++)
213 dst[i] = depth[i];
[2938]214 }
215 }
[3598]216 else if (type==GL_UNSIGNED_INT && ctx->Visual->DepthBits == 32
[2938]217 && !bias_or_scale && !packing->SwapBytes) {
218 /* Special case: directly read 32-bit unsigned depth values. */
219 for (j=0;j<height;j++,y++) {
[3598]220 GLdepth *dst = (GLdepth *) _mesa_image_address( packing, pixels,
[2938]221 width, height, GL_DEPTH_COMPONENT, type, 0, j, 0 );
[3598]222 (*ctx->Driver.ReadDepthSpan)( ctx, width, x, y, dst);
[2938]223 }
224 }
225 else {
226 /* General case (slow) */
227 for (j=0;j<height;j++,y++) {
228 GLfloat depth[MAX_WIDTH];
229 GLvoid *dest;
230
[3598]231 _mesa_read_depth_span_float(ctx, readWidth, x, y, depth);
[2938]232
233 if (bias_or_scale) {
234 for (i=0;i<readWidth;i++) {
235 GLfloat d;
236 d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
237 depth[i] = CLAMP( d, 0.0F, 1.0F );
238 }
239 }
240
[3598]241 dest = _mesa_image_address(packing, pixels,
[2938]242 width, height, GL_DEPTH_COMPONENT, type, 0, j, 0);
243
244 switch (type) {
245 case GL_UNSIGNED_BYTE:
246 {
247 GLubyte *dst = (GLubyte *) dest;
248 for (i=0;i<readWidth;i++) {
249 dst[i] = FLOAT_TO_UBYTE( depth[i] );
250 }
251 }
252 break;
253 case GL_BYTE:
254 {
255 GLbyte *dst = (GLbyte *) dest;
256 for (i=0;i<readWidth;i++) {
257 dst[i] = FLOAT_TO_BYTE( depth[i] );
258 }
259 }
260 break;
261 case GL_UNSIGNED_SHORT:
262 {
263 GLushort *dst = (GLushort *) dest;
264 for (i=0;i<readWidth;i++) {
265 dst[i] = FLOAT_TO_USHORT( depth[i] );
266 }
267 if (packing->SwapBytes) {
[3598]268 _mesa_swap2( (GLushort *) dst, readWidth );
[2938]269 }
270 }
271 break;
272 case GL_SHORT:
273 {
274 GLshort *dst = (GLshort *) dest;
275 for (i=0;i<readWidth;i++) {
276 dst[i] = FLOAT_TO_SHORT( depth[i] );
277 }
278 if (packing->SwapBytes) {
[3598]279 _mesa_swap2( (GLushort *) dst, readWidth );
[2938]280 }
281 }
282 break;
283 case GL_UNSIGNED_INT:
284 {
285 GLuint *dst = (GLuint *) dest;
286 for (i=0;i<readWidth;i++) {
287 dst[i] = FLOAT_TO_UINT( depth[i] );
288 }
289 if (packing->SwapBytes) {
[3598]290 _mesa_swap4( (GLuint *) dst, readWidth );
[2938]291 }
292 }
293 break;
294 case GL_INT:
295 {
296 GLint *dst = (GLint *) dest;
297 for (i=0;i<readWidth;i++) {
298 dst[i] = FLOAT_TO_INT( depth[i] );
299 }
300 if (packing->SwapBytes) {
[3598]301 _mesa_swap4( (GLuint *) dst, readWidth );
[2938]302 }
303 }
304 break;
305 case GL_FLOAT:
306 {
307 GLfloat *dst = (GLfloat *) dest;
308 for (i=0;i<readWidth;i++) {
309 dst[i] = depth[i];
310 }
311 if (packing->SwapBytes) {
[3598]312 _mesa_swap4( (GLuint *) dst, readWidth );
[2938]313 }
314 }
315 break;
316 default:
317 gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
318 }
319 }
320 }
321}
322
323
324
325
326static void read_stencil_pixels( GLcontext *ctx,
327 GLint x, GLint y,
[3598]328 GLsizei width, GLsizei height,
329 GLenum type, GLvoid *pixels,
[2938]330 const struct gl_pixelstore_attrib *packing )
331{
332 GLboolean shift_or_offset;
333 GLint i, j, readWidth;
334
335 if (type != GL_BYTE &&
336 type != GL_UNSIGNED_BYTE &&
337 type != GL_SHORT &&
338 type != GL_UNSIGNED_SHORT &&
339 type != GL_INT &&
340 type != GL_UNSIGNED_INT &&
341 type != GL_FLOAT &&
342 type != GL_BITMAP) {
343 gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels(stencil type)");
344 return;
345 }
346
347 readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
348
349 if (ctx->Visual->StencilBits<=0) {
350 /* No stencil buffer */
351 gl_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
352 return;
353 }
354
355 shift_or_offset = ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0;
356
357 /* process image row by row */
358 for (j=0;j<height;j++,y++) {
359 GLvoid *dest;
360 GLstencil stencil[MAX_WIDTH];
361
362 gl_read_stencil_span( ctx, readWidth, x, y, stencil );
363
364 if (shift_or_offset) {
365 gl_shift_and_offset_stencil( ctx, readWidth, stencil );
366 }
367
368 if (ctx->Pixel.MapStencilFlag) {
369 gl_map_stencil( ctx, readWidth, stencil );
370 }
371
[3598]372 dest = _mesa_image_address( packing, pixels,
[2938]373 width, height, GL_STENCIL_INDEX, type, 0, j, 0 );
374
375 switch (type) {
[3598]376 case GL_UNSIGNED_BYTE:
[2938]377 if (sizeof(GLstencil) == 8) {
378 MEMCPY( dest, stencil, readWidth );
379 }
380 else {
381 GLubyte *dst = (GLubyte *) dest;
[3598]382 for (i=0;i<readWidth;i++) {
383 dst[i] = (GLubyte) stencil[i];
384 }
[2938]385 }
[3598]386 break;
387 case GL_BYTE:
[2938]388 if (sizeof(GLstencil) == 8) {
389 MEMCPY( dest, stencil, readWidth );
390 }
391 else {
392 GLbyte *dst = (GLbyte *) dest;
[3598]393 for (i=0;i<readWidth;i++) {
394 dst[i] = (GLbyte) stencil[i];
395 }
[2938]396 }
[3598]397 break;
398 case GL_UNSIGNED_SHORT:
399 {
[2938]400 GLushort *dst = (GLushort *) dest;
[3598]401 for (i=0;i<readWidth;i++) {
402 dst[i] = (GLushort) stencil[i];
403 }
404 if (packing->SwapBytes) {
405 _mesa_swap2( (GLushort *) dst, readWidth );
406 }
407 }
408 break;
409 case GL_SHORT:
410 {
[2938]411 GLshort *dst = (GLshort *) dest;
[3598]412 for (i=0;i<readWidth;i++) {
413 dst[i] = (GLshort) stencil[i];
414 }
415 if (packing->SwapBytes) {
416 _mesa_swap2( (GLushort *) dst, readWidth );
417 }
418 }
419 break;
420 case GL_UNSIGNED_INT:
421 {
[2938]422 GLuint *dst = (GLuint *) dest;
[3598]423 for (i=0;i<readWidth;i++) {
424 dst[i] = (GLuint) stencil[i];
425 }
426 if (packing->SwapBytes) {
427 _mesa_swap4( (GLuint *) dst, readWidth );
428 }
429 }
430 break;
431 case GL_INT:
432 {
[2938]433 GLint *dst = (GLint *) dest;
[3598]434 for (i=0;i<readWidth;i++) {
435 *dst++ = (GLint) stencil[i];
436 }
437 if (packing->SwapBytes) {
438 _mesa_swap4( (GLuint *) dst, readWidth );
439 }
440 }
441 break;
442 case GL_FLOAT:
443 {
[2938]444 GLfloat *dst = (GLfloat *) dest;
[3598]445 for (i=0;i<readWidth;i++) {
446 dst[i] = (GLfloat) stencil[i];
447 }
448 if (packing->SwapBytes) {
449 _mesa_swap4( (GLuint *) dst, readWidth );
450 }
451 }
452 break;
[2938]453 case GL_BITMAP:
454 if (packing->LsbFirst) {
455 GLubyte *dst = (GLubyte*) dest;
456 GLint shift = 0;
457 for (i = 0; i < readWidth; i++) {
458 if (shift == 0)
459 *dst = 0;
460 *dst |= ((stencil != 0) << shift);
461 shift++;
462 if (shift == 8) {
463 shift = 0;
464 dst++;
465 }
466 }
467 }
468 else {
469 GLubyte *dst = (GLubyte*) dest;
470 GLint shift = 7;
471 for (i = 0; i < readWidth; i++) {
472 if (shift == 7)
473 *dst = 0;
474 *dst |= ((stencil != 0) << shift);
475 shift--;
476 if (shift < 0) {
477 shift = 7;
478 dst++;
479 }
480 }
481 }
482 break;
483 default:
484 gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
485 }
486 }
487}
488
489
490
491/*
492 * Optimized glReadPixels for particular pixel formats:
493 * GL_UNSIGNED_BYTE, GL_RGBA
494 * when pixel scaling, biasing and mapping are disabled.
495 */
496static GLboolean
497read_fast_rgba_pixels( GLcontext *ctx,
498 GLint x, GLint y,
499 GLsizei width, GLsizei height,
500 GLenum format, GLenum type,
501 GLvoid *pixels,
502 const struct gl_pixelstore_attrib *packing )
503{
504 /* can't do scale, bias or mapping */
505 if (ctx->Pixel.ScaleOrBiasRGBA || ctx->Pixel.MapColorFlag)
506 return GL_FALSE;
507
508 /* can't do fancy pixel packing */
509 if (packing->Alignment != 1 || packing->SwapBytes || packing->LsbFirst)
510 return GL_FALSE;
511
512 {
513 GLint srcX = x;
514 GLint srcY = y;
515 GLint readWidth = width; /* actual width read */
516 GLint readHeight = height; /* actual height read */
517 GLint skipPixels = packing->SkipPixels;
518 GLint skipRows = packing->SkipRows;
519 GLint rowLength;
520
521 if (packing->RowLength > 0)
522 rowLength = packing->RowLength;
523 else
524 rowLength = width;
525
526 /* horizontal clipping */
[3598]527 if (srcX < ctx->ReadBuffer->Xmin) {
528 skipPixels += (ctx->ReadBuffer->Xmin - srcX);
529 readWidth -= (ctx->ReadBuffer->Xmin - srcX);
530 srcX = ctx->ReadBuffer->Xmin;
[2938]531 }
[3598]532 if (srcX + readWidth > ctx->ReadBuffer->Xmax)
533 readWidth -= (srcX + readWidth - ctx->ReadBuffer->Xmax - 1);
[2938]534 if (readWidth <= 0)
535 return GL_TRUE;
536
537 /* vertical clipping */
[3598]538 if (srcY < ctx->ReadBuffer->Ymin) {
539 skipRows += (ctx->ReadBuffer->Ymin - srcY);
540 readHeight -= (ctx->ReadBuffer->Ymin - srcY);
541 srcY = ctx->ReadBuffer->Ymin;
[2938]542 }
[3598]543 if (srcY + readHeight > ctx->ReadBuffer->Ymax)
544 readHeight -= (srcY + readHeight - ctx->ReadBuffer->Ymax - 1);
[2938]545 if (readHeight <= 0)
546 return GL_TRUE;
547
548 /*
549 * Ready to read!
550 * The window region at (destX, destY) of size (readWidth, readHeight)
551 * will be read back.
552 * We'll write pixel data to buffer pointed to by "pixels" but we'll
553 * skip "skipRows" rows and skip "skipPixels" pixels/row.
554 */
555 if (format==GL_RGBA && type==GL_UNSIGNED_BYTE) {
556 GLubyte *dest = (GLubyte *) pixels
557 + (skipRows * rowLength + skipPixels) * 4;
558 GLint row;
559 for (row=0; row<readHeight; row++) {
560 (*ctx->Driver.ReadRGBASpan)(ctx, readWidth, srcX, srcY,
561 (GLubyte (*)[4]) dest);
562 if (ctx->Visual->SoftwareAlpha) {
563 gl_read_alpha_span(ctx, readWidth, srcX, srcY,
564 (GLubyte (*)[4]) dest);
565 }
566 dest += rowLength * 4;
567 srcY++;
568 }
569 return GL_TRUE;
570 }
571 else {
572 /* can't do this format/type combination */
573 return GL_FALSE;
574 }
575 }
576}
577
578
579
580/*
581 * Read R, G, B, A, RGB, L, or LA pixels.
582 */
583static void read_rgba_pixels( GLcontext *ctx,
584 GLint x, GLint y,
585 GLsizei width, GLsizei height,
586 GLenum format, GLenum type, GLvoid *pixels,
587 const struct gl_pixelstore_attrib *packing )
588{
589 GLint readWidth;
590
[3598]591 (*ctx->Driver.SetReadBuffer)(ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer);
[2938]592
593 /* Try optimized path first */
594 if (read_fast_rgba_pixels( ctx, x, y, width, height,
595 format, type, pixels, packing )) {
596
[3598]597 (*ctx->Driver.SetReadBuffer)(ctx, ctx->DrawBuffer, ctx->Color.DriverDrawBuffer);
[2938]598 return; /* done! */
599 }
600
601 readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
602
603 /* do error checking on pixel type, format was already checked by caller */
604 switch (type) {
605 case GL_UNSIGNED_BYTE:
606 case GL_BYTE:
607 case GL_UNSIGNED_SHORT:
608 case GL_SHORT:
609 case GL_UNSIGNED_INT:
610 case GL_INT:
611 case GL_FLOAT:
612 case GL_UNSIGNED_BYTE_3_3_2:
613 case GL_UNSIGNED_BYTE_2_3_3_REV:
614 case GL_UNSIGNED_SHORT_5_6_5:
615 case GL_UNSIGNED_SHORT_5_6_5_REV:
616 case GL_UNSIGNED_SHORT_4_4_4_4:
617 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
618 case GL_UNSIGNED_SHORT_5_5_5_1:
619 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
620 case GL_UNSIGNED_INT_8_8_8_8:
621 case GL_UNSIGNED_INT_8_8_8_8_REV:
622 case GL_UNSIGNED_INT_10_10_10_2:
623 case GL_UNSIGNED_INT_2_10_10_10_REV:
624 /* valid pixel type */
625 break;
626 default:
627 gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
628 return;
629 }
630
[3598]631 if (!_mesa_is_legal_format_and_type(format, type)) {
[2938]632 gl_error(ctx, GL_INVALID_OPERATION, "glReadPixels(format or type)");
633 return;
634 }
635
636 if (ctx->Visual->RGBAflag) {
637 GLint j;
638 for (j=0;j<height;j++,y++) {
639 GLubyte rgba[MAX_WIDTH][4];
640 GLvoid *dest;
641
[3598]642 gl_read_rgba_span( ctx, ctx->ReadBuffer, readWidth, x, y, rgba );
[2938]643
[3598]644 dest = _mesa_image_address( packing, pixels, width, height,
[2938]645 format, type, 0, j, 0);
646
[3598]647 _mesa_pack_rgba_span( ctx, readWidth, (const GLubyte (*)[4]) rgba,
648 format, type, dest, packing, GL_TRUE );
[2938]649 }
650 }
651 else {
652 GLint j;
653 for (j=0;j<height;j++,y++) {
654 GLubyte rgba[MAX_WIDTH][4];
[3598]655 GLuint index[MAX_WIDTH];
[2938]656 GLvoid *dest;
657
[3598]658 (*ctx->Driver.ReadCI32Span)( ctx, readWidth, x, y, index );
[2938]659
[3598]660 if (ctx->Pixel.IndexShift!=0 || ctx->Pixel.IndexOffset!=0) {
[2938]661 gl_map_ci( ctx, readWidth, index );
[3598]662 }
[2938]663
664 gl_map_ci_to_rgba(ctx, readWidth, index, rgba );
665
[3598]666 dest = _mesa_image_address( packing, pixels, width, height,
[2938]667 format, type, 0, j, 0);
668
[3598]669 _mesa_pack_rgba_span( ctx, readWidth, (const GLubyte (*)[4]) rgba,
670 format, type, dest, packing, GL_TRUE );
[2938]671 }
672 }
673
[3598]674 (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, ctx->Color.DriverDrawBuffer );
[2938]675}
676
677
678
[3598]679void
680_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
681 GLenum format, GLenum type, GLvoid *pixels )
[2938]682{
[3598]683 GET_CURRENT_CONTEXT(ctx);
[2938]684 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glReadPixels");
685
686 if (!pixels) {
687 gl_error( ctx, GL_INVALID_VALUE, "glReadPixels(pixels)" );
688 return;
689 }
690
[3598]691 if (ctx->Driver.ReadPixels &&
692 (*ctx->Driver.ReadPixels)(ctx, x, y, width, height,
693 format, type, &ctx->Pack, pixels))
694 return;
695
[2938]696 switch (format) {
697 case GL_COLOR_INDEX:
[3598]698 read_index_pixels(ctx, x, y, width, height, type, pixels, &ctx->Pack );
699 break;
[2938]700 case GL_STENCIL_INDEX:
[3598]701 read_stencil_pixels(ctx, x, y, width, height, type, pixels, &ctx->Pack );
[2938]702 break;
703 case GL_DEPTH_COMPONENT:
[3598]704 read_depth_pixels(ctx, x, y, width, height, type, pixels, &ctx->Pack );
705 break;
[2938]706 case GL_RED:
707 case GL_GREEN:
708 case GL_BLUE:
709 case GL_ALPHA:
710 case GL_RGB:
711 case GL_LUMINANCE:
712 case GL_LUMINANCE_ALPHA:
713 case GL_RGBA:
714 case GL_BGR:
715 case GL_BGRA:
716 case GL_ABGR_EXT:
[3598]717 read_rgba_pixels(ctx, x, y, width, height,
718 format, type, pixels, &ctx->Pack );
719 break;
[2938]720 default:
[3598]721 gl_error( ctx, GL_INVALID_ENUM, "glReadPixels(format)" );
[2938]722 }
723}
Note: See TracBrowser for help on using the repository browser.