3d36c66e5be3b194be893e13ba64091ed397c857
[mesa.git] / src / mesa / main / pixel.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.3
4 *
5 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #include "glheader.h"
26 #include "bufferobj.h"
27 #include "colormac.h"
28 #include "context.h"
29 #include "image.h"
30 #include "macros.h"
31 #include "pixel.h"
32 #include "mtypes.h"
33
34
35 /**********************************************************************/
36 /***** glPixelZoom *****/
37 /**********************************************************************/
38
39
40
41 void GLAPIENTRY
42 _mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor )
43 {
44 GET_CURRENT_CONTEXT(ctx);
45
46 if (ctx->Pixel.ZoomX == xfactor &&
47 ctx->Pixel.ZoomY == yfactor)
48 return;
49
50 FLUSH_VERTICES(ctx, _NEW_PIXEL);
51 ctx->Pixel.ZoomX = xfactor;
52 ctx->Pixel.ZoomY = yfactor;
53 }
54
55
56
57 /**********************************************************************/
58 /***** glPixelStore *****/
59 /**********************************************************************/
60
61
62 void GLAPIENTRY
63 _mesa_PixelStorei( GLenum pname, GLint param )
64 {
65 /* NOTE: this call can't be compiled into the display list */
66 GET_CURRENT_CONTEXT(ctx);
67 ASSERT_OUTSIDE_BEGIN_END(ctx);
68
69 switch (pname) {
70 case GL_PACK_SWAP_BYTES:
71 if (param == (GLint)ctx->Pack.SwapBytes)
72 return;
73 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
74 ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
75 break;
76 case GL_PACK_LSB_FIRST:
77 if (param == (GLint)ctx->Pack.LsbFirst)
78 return;
79 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
80 ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
81 break;
82 case GL_PACK_ROW_LENGTH:
83 if (param<0) {
84 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
85 return;
86 }
87 if (ctx->Pack.RowLength == param)
88 return;
89 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
90 ctx->Pack.RowLength = param;
91 break;
92 case GL_PACK_IMAGE_HEIGHT:
93 if (param<0) {
94 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
95 return;
96 }
97 if (ctx->Pack.ImageHeight == param)
98 return;
99 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
100 ctx->Pack.ImageHeight = param;
101 break;
102 case GL_PACK_SKIP_PIXELS:
103 if (param<0) {
104 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
105 return;
106 }
107 if (ctx->Pack.SkipPixels == param)
108 return;
109 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
110 ctx->Pack.SkipPixels = param;
111 break;
112 case GL_PACK_SKIP_ROWS:
113 if (param<0) {
114 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
115 return;
116 }
117 if (ctx->Pack.SkipRows == param)
118 return;
119 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
120 ctx->Pack.SkipRows = param;
121 break;
122 case GL_PACK_SKIP_IMAGES:
123 if (param<0) {
124 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
125 return;
126 }
127 if (ctx->Pack.SkipImages == param)
128 return;
129 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
130 ctx->Pack.SkipImages = param;
131 break;
132 case GL_PACK_ALIGNMENT:
133 if (param!=1 && param!=2 && param!=4 && param!=8) {
134 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
135 return;
136 }
137 if (ctx->Pack.Alignment == param)
138 return;
139 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
140 ctx->Pack.Alignment = param;
141 break;
142 case GL_PACK_INVERT_MESA:
143 if (!ctx->Extensions.MESA_pack_invert) {
144 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelstore(pname)" );
145 return;
146 }
147 if (ctx->Pack.Invert == param)
148 return;
149 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
150 ctx->Pack.Invert = param;
151 break;
152
153 case GL_UNPACK_SWAP_BYTES:
154 if (param == (GLint)ctx->Unpack.SwapBytes)
155 return;
156 if ((GLint)ctx->Unpack.SwapBytes == param)
157 return;
158 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
159 ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
160 break;
161 case GL_UNPACK_LSB_FIRST:
162 if (param == (GLint)ctx->Unpack.LsbFirst)
163 return;
164 if ((GLint)ctx->Unpack.LsbFirst == param)
165 return;
166 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
167 ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
168 break;
169 case GL_UNPACK_ROW_LENGTH:
170 if (param<0) {
171 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
172 return;
173 }
174 if (ctx->Unpack.RowLength == param)
175 return;
176 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
177 ctx->Unpack.RowLength = param;
178 break;
179 case GL_UNPACK_IMAGE_HEIGHT:
180 if (param<0) {
181 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
182 return;
183 }
184 if (ctx->Unpack.ImageHeight == param)
185 return;
186
187 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
188 ctx->Unpack.ImageHeight = param;
189 break;
190 case GL_UNPACK_SKIP_PIXELS:
191 if (param<0) {
192 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
193 return;
194 }
195 if (ctx->Unpack.SkipPixels == param)
196 return;
197 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
198 ctx->Unpack.SkipPixels = param;
199 break;
200 case GL_UNPACK_SKIP_ROWS:
201 if (param<0) {
202 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
203 return;
204 }
205 if (ctx->Unpack.SkipRows == param)
206 return;
207 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
208 ctx->Unpack.SkipRows = param;
209 break;
210 case GL_UNPACK_SKIP_IMAGES:
211 if (param < 0) {
212 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
213 return;
214 }
215 if (ctx->Unpack.SkipImages == param)
216 return;
217 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
218 ctx->Unpack.SkipImages = param;
219 break;
220 case GL_UNPACK_ALIGNMENT:
221 if (param!=1 && param!=2 && param!=4 && param!=8) {
222 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore" );
223 return;
224 }
225 if (ctx->Unpack.Alignment == param)
226 return;
227 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
228 ctx->Unpack.Alignment = param;
229 break;
230 case GL_UNPACK_CLIENT_STORAGE_APPLE:
231 if (param == (GLint)ctx->Unpack.ClientStorage)
232 return;
233 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
234 ctx->Unpack.ClientStorage = param ? GL_TRUE : GL_FALSE;
235 break;
236 default:
237 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
238 return;
239 }
240 }
241
242
243 void GLAPIENTRY
244 _mesa_PixelStoref( GLenum pname, GLfloat param )
245 {
246 _mesa_PixelStorei( pname, (GLint) param );
247 }
248
249
250
251 /**********************************************************************/
252 /***** glPixelMap *****/
253 /**********************************************************************/
254
255
256 /**
257 * Helper routine used by the other _mesa_PixelMap() functions.
258 */
259 static void
260 pixelmap(GLcontext *ctx, GLenum map, GLsizei mapsize, const GLfloat *values)
261 {
262 GLint i;
263 switch (map) {
264 case GL_PIXEL_MAP_S_TO_S:
265 ctx->Pixel.MapStoSsize = mapsize;
266 for (i = 0; i < mapsize; i++) {
267 ctx->Pixel.MapStoS[i] = (GLint) values[i];
268 }
269 break;
270 case GL_PIXEL_MAP_I_TO_I:
271 ctx->Pixel.MapItoIsize = mapsize;
272 for (i = 0; i < mapsize; i++) {
273 ctx->Pixel.MapItoI[i] = (GLint) values[i];
274 }
275 break;
276 case GL_PIXEL_MAP_I_TO_R:
277 ctx->Pixel.MapItoRsize = mapsize;
278 for (i = 0; i < mapsize; i++) {
279 GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
280 ctx->Pixel.MapItoR[i] = val;
281 ctx->Pixel.MapItoR8[i] = (GLint) (val * 255.0F);
282 }
283 break;
284 case GL_PIXEL_MAP_I_TO_G:
285 ctx->Pixel.MapItoGsize = mapsize;
286 for (i = 0; i < mapsize; i++) {
287 GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
288 ctx->Pixel.MapItoG[i] = val;
289 ctx->Pixel.MapItoG8[i] = (GLint) (val * 255.0F);
290 }
291 break;
292 case GL_PIXEL_MAP_I_TO_B:
293 ctx->Pixel.MapItoBsize = mapsize;
294 for (i = 0; i < mapsize; i++) {
295 GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
296 ctx->Pixel.MapItoB[i] = val;
297 ctx->Pixel.MapItoB8[i] = (GLint) (val * 255.0F);
298 }
299 break;
300 case GL_PIXEL_MAP_I_TO_A:
301 ctx->Pixel.MapItoAsize = mapsize;
302 for (i = 0; i < mapsize; i++) {
303 GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
304 ctx->Pixel.MapItoA[i] = val;
305 ctx->Pixel.MapItoA8[i] = (GLint) (val * 255.0F);
306 }
307 break;
308 case GL_PIXEL_MAP_R_TO_R:
309 ctx->Pixel.MapRtoRsize = mapsize;
310 for (i = 0; i < mapsize; i++) {
311 ctx->Pixel.MapRtoR[i] = CLAMP( values[i], 0.0F, 1.0F );
312 }
313 break;
314 case GL_PIXEL_MAP_G_TO_G:
315 ctx->Pixel.MapGtoGsize = mapsize;
316 for (i = 0; i < mapsize; i++) {
317 ctx->Pixel.MapGtoG[i] = CLAMP( values[i], 0.0F, 1.0F );
318 }
319 break;
320 case GL_PIXEL_MAP_B_TO_B:
321 ctx->Pixel.MapBtoBsize = mapsize;
322 for (i = 0; i < mapsize; i++) {
323 ctx->Pixel.MapBtoB[i] = CLAMP( values[i], 0.0F, 1.0F );
324 }
325 break;
326 case GL_PIXEL_MAP_A_TO_A:
327 ctx->Pixel.MapAtoAsize = mapsize;
328 for (i = 0; i < mapsize; i++) {
329 ctx->Pixel.MapAtoA[i] = CLAMP( values[i], 0.0F, 1.0F );
330 }
331 break;
332 default:
333 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelMap(map)" );
334 }
335 }
336
337
338 void GLAPIENTRY
339 _mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
340 {
341 GET_CURRENT_CONTEXT(ctx);
342 ASSERT_OUTSIDE_BEGIN_END(ctx);
343
344 /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */
345 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
346 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
347 return;
348 }
349
350 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
351 /* test that mapsize is a power of two */
352 if (_mesa_bitcount((GLuint) mapsize) != 1) {
353 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
354 return;
355 }
356 }
357
358 FLUSH_VERTICES(ctx, _NEW_PIXEL);
359
360 if (ctx->Unpack.BufferObj->Name) {
361 /* unpack pixelmap from PBO */
362 GLubyte *buf;
363 /* Note, need to use DefaultPacking and Unpack's buffer object */
364 ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
365 if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1,
366 GL_INTENSITY, GL_FLOAT, values)) {
367 _mesa_error(ctx, GL_INVALID_OPERATION,
368 "glPixelMapfv(invalid PBO access)");
369 return;
370 }
371 /* restore */
372 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
373 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
374 GL_READ_ONLY_ARB,
375 ctx->Unpack.BufferObj);
376 if (!buf) {
377 /* buffer is already mapped - that's an error */
378 _mesa_error(ctx, GL_INVALID_OPERATION,
379 "glPixelMapfv(PBO is mapped)");
380 return;
381 }
382 values = (const GLfloat *) ADD_POINTERS(buf, values);
383 }
384 else if (!values) {
385 return;
386 }
387
388 pixelmap(ctx, map, mapsize, values);
389
390 if (ctx->Unpack.BufferObj->Name) {
391 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
392 ctx->Unpack.BufferObj);
393 }
394 }
395
396
397
398 void GLAPIENTRY
399 _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
400 {
401 GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
402 GET_CURRENT_CONTEXT(ctx);
403 ASSERT_OUTSIDE_BEGIN_END(ctx);
404
405 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
406 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
407 return;
408 }
409
410 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
411 /* test that mapsize is a power of two */
412 if (_mesa_bitcount((GLuint) mapsize) != 1) {
413 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
414 return;
415 }
416 }
417
418 FLUSH_VERTICES(ctx, _NEW_PIXEL);
419
420 if (ctx->Unpack.BufferObj->Name) {
421 /* unpack pixelmap from PBO */
422 GLubyte *buf;
423 /* Note, need to use DefaultPacking and Unpack's buffer object */
424 ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
425 if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1,
426 GL_INTENSITY, GL_UNSIGNED_INT, values)) {
427 _mesa_error(ctx, GL_INVALID_OPERATION,
428 "glPixelMapuiv(invalid PBO access)");
429 return;
430 }
431 /* restore */
432 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
433 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
434 GL_READ_ONLY_ARB,
435 ctx->Unpack.BufferObj);
436 if (!buf) {
437 /* buffer is already mapped - that's an error */
438 _mesa_error(ctx, GL_INVALID_OPERATION,
439 "glPixelMapuiv(PBO is mapped)");
440 return;
441 }
442 values = (const GLuint *) ADD_POINTERS(buf, values);
443 }
444 else if (!values) {
445 return;
446 }
447
448 /* convert to floats */
449 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
450 GLint i;
451 for (i = 0; i < mapsize; i++) {
452 fvalues[i] = (GLfloat) values[i];
453 }
454 }
455 else {
456 GLint i;
457 for (i = 0; i < mapsize; i++) {
458 fvalues[i] = UINT_TO_FLOAT( values[i] );
459 }
460 }
461
462 if (ctx->Unpack.BufferObj->Name) {
463 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
464 ctx->Unpack.BufferObj);
465 }
466
467 pixelmap(ctx, map, mapsize, fvalues);
468 }
469
470
471
472 void GLAPIENTRY
473 _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
474 {
475 GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
476 GET_CURRENT_CONTEXT(ctx);
477 ASSERT_OUTSIDE_BEGIN_END(ctx);
478
479 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
480 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" );
481 return;
482 }
483
484 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
485 /* test that mapsize is a power of two */
486 if (_mesa_bitcount((GLuint) mapsize) != 1) {
487 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
488 return;
489 }
490 }
491
492 FLUSH_VERTICES(ctx, _NEW_PIXEL);
493
494 if (ctx->Unpack.BufferObj->Name) {
495 /* unpack pixelmap from PBO */
496 GLubyte *buf;
497 /* Note, need to use DefaultPacking and Unpack's buffer object */
498 ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
499 if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1,
500 GL_INTENSITY, GL_UNSIGNED_SHORT,
501 values)) {
502 _mesa_error(ctx, GL_INVALID_OPERATION,
503 "glPixelMapusv(invalid PBO access)");
504 return;
505 }
506 /* restore */
507 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
508 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
509 GL_READ_ONLY_ARB,
510 ctx->Unpack.BufferObj);
511 if (!buf) {
512 /* buffer is already mapped - that's an error */
513 _mesa_error(ctx, GL_INVALID_OPERATION,
514 "glPixelMapusv(PBO is mapped)");
515 return;
516 }
517 values = (const GLushort *) ADD_POINTERS(buf, values);
518 }
519 else if (!values) {
520 return;
521 }
522
523 /* convert to floats */
524 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
525 GLint i;
526 for (i = 0; i < mapsize; i++) {
527 fvalues[i] = (GLfloat) values[i];
528 }
529 }
530 else {
531 GLint i;
532 for (i = 0; i < mapsize; i++) {
533 fvalues[i] = USHORT_TO_FLOAT( values[i] );
534 }
535 }
536
537 if (ctx->Unpack.BufferObj->Name) {
538 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
539 ctx->Unpack.BufferObj);
540 }
541
542 pixelmap(ctx, map, mapsize, fvalues);
543 }
544
545
546 /**
547 * Return size of the named map.
548 */
549 static GLuint
550 get_map_size(GLcontext *ctx, GLenum map)
551 {
552 switch (map) {
553 case GL_PIXEL_MAP_I_TO_I:
554 return ctx->Pixel.MapItoIsize;
555 case GL_PIXEL_MAP_S_TO_S:
556 return ctx->Pixel.MapStoSsize;
557 case GL_PIXEL_MAP_I_TO_R:
558 return ctx->Pixel.MapItoRsize;
559 case GL_PIXEL_MAP_I_TO_G:
560 return ctx->Pixel.MapItoGsize;
561 case GL_PIXEL_MAP_I_TO_B:
562 return ctx->Pixel.MapItoBsize;
563 case GL_PIXEL_MAP_I_TO_A:
564 return ctx->Pixel.MapItoAsize;
565 case GL_PIXEL_MAP_R_TO_R:
566 return ctx->Pixel.MapRtoRsize;
567 case GL_PIXEL_MAP_G_TO_G:
568 return ctx->Pixel.MapGtoGsize;
569 case GL_PIXEL_MAP_B_TO_B:
570 return ctx->Pixel.MapBtoBsize;
571 case GL_PIXEL_MAP_A_TO_A:
572 return ctx->Pixel.MapAtoAsize;
573 default:
574 return 0;
575 }
576 }
577
578
579 void GLAPIENTRY
580 _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
581 {
582 GET_CURRENT_CONTEXT(ctx);
583 GLuint mapsize, i;
584 ASSERT_OUTSIDE_BEGIN_END(ctx);
585
586 mapsize = get_map_size(ctx, map);
587
588 if (ctx->Pack.BufferObj->Name) {
589 /* pack pixelmap into PBO */
590 GLubyte *buf;
591 /* Note, need to use DefaultPacking and Pack's buffer object */
592 ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
593 if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1,
594 GL_INTENSITY, GL_FLOAT, values)) {
595 _mesa_error(ctx, GL_INVALID_OPERATION,
596 "glGetPixelMapfv(invalid PBO access)");
597 return;
598 }
599 /* restore */
600 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
601 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
602 GL_WRITE_ONLY_ARB,
603 ctx->Pack.BufferObj);
604 if (!buf) {
605 /* buffer is already mapped - that's an error */
606 _mesa_error(ctx, GL_INVALID_OPERATION,
607 "glGetPixelMapfv(PBO is mapped)");
608 return;
609 }
610 values = (GLfloat *) ADD_POINTERS(buf, values);
611 }
612 else if (!values) {
613 return;
614 }
615
616 switch (map) {
617 case GL_PIXEL_MAP_I_TO_I:
618 for (i = 0; i < mapsize; i++) {
619 values[i] = (GLfloat) ctx->Pixel.MapItoI[i];
620 }
621 break;
622 case GL_PIXEL_MAP_S_TO_S:
623 for (i = 0; i < mapsize; i++) {
624 values[i] = (GLfloat) ctx->Pixel.MapStoS[i];
625 }
626 break;
627 case GL_PIXEL_MAP_I_TO_R:
628 MEMCPY(values, ctx->Pixel.MapItoR, mapsize * sizeof(GLfloat));
629 break;
630 case GL_PIXEL_MAP_I_TO_G:
631 MEMCPY(values, ctx->Pixel.MapItoG, mapsize * sizeof(GLfloat));
632 break;
633 case GL_PIXEL_MAP_I_TO_B:
634 MEMCPY(values, ctx->Pixel.MapItoB, mapsize * sizeof(GLfloat));
635 break;
636 case GL_PIXEL_MAP_I_TO_A:
637 MEMCPY(values, ctx->Pixel.MapItoA, mapsize * sizeof(GLfloat));
638 break;
639 case GL_PIXEL_MAP_R_TO_R:
640 MEMCPY(values, ctx->Pixel.MapRtoR, mapsize * sizeof(GLfloat));
641 break;
642 case GL_PIXEL_MAP_G_TO_G:
643 MEMCPY(values, ctx->Pixel.MapGtoG, mapsize * sizeof(GLfloat));
644 break;
645 case GL_PIXEL_MAP_B_TO_B:
646 MEMCPY(values, ctx->Pixel.MapBtoB, mapsize * sizeof(GLfloat));
647 break;
648 case GL_PIXEL_MAP_A_TO_A:
649 MEMCPY(values, ctx->Pixel.MapAtoA, mapsize * sizeof(GLfloat));
650 break;
651 default:
652 _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
653 }
654
655 if (ctx->Pack.BufferObj->Name) {
656 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
657 ctx->Pack.BufferObj);
658 }
659 }
660
661
662 void GLAPIENTRY
663 _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
664 {
665 GET_CURRENT_CONTEXT(ctx);
666 GLint mapsize, i;
667 ASSERT_OUTSIDE_BEGIN_END(ctx);
668
669 mapsize = get_map_size(ctx, map);
670
671 if (ctx->Pack.BufferObj->Name) {
672 /* pack pixelmap into PBO */
673 GLubyte *buf;
674 /* Note, need to use DefaultPacking and Pack's buffer object */
675 ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
676 if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1,
677 GL_INTENSITY, GL_UNSIGNED_INT, values)) {
678 _mesa_error(ctx, GL_INVALID_OPERATION,
679 "glGetPixelMapuiv(invalid PBO access)");
680 return;
681 }
682 /* restore */
683 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
684 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
685 GL_WRITE_ONLY_ARB,
686 ctx->Pack.BufferObj);
687 if (!buf) {
688 /* buffer is already mapped - that's an error */
689 _mesa_error(ctx, GL_INVALID_OPERATION,
690 "glGetPixelMapuiv(PBO is mapped)");
691 return;
692 }
693 values = (GLuint *) ADD_POINTERS(buf, values);
694 }
695 else if (!values) {
696 return;
697 }
698
699 switch (map) {
700 case GL_PIXEL_MAP_I_TO_I:
701 MEMCPY(values, ctx->Pixel.MapItoI, mapsize * sizeof(GLint));
702 break;
703 case GL_PIXEL_MAP_S_TO_S:
704 MEMCPY(values, ctx->Pixel.MapStoS, mapsize * sizeof(GLint));
705 break;
706 case GL_PIXEL_MAP_I_TO_R:
707 for (i = 0; i < mapsize; i++) {
708 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoR[i] );
709 }
710 break;
711 case GL_PIXEL_MAP_I_TO_G:
712 for (i = 0; i < mapsize; i++) {
713 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoG[i] );
714 }
715 break;
716 case GL_PIXEL_MAP_I_TO_B:
717 for (i = 0; i < mapsize; i++) {
718 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoB[i] );
719 }
720 break;
721 case GL_PIXEL_MAP_I_TO_A:
722 for (i = 0; i < mapsize; i++) {
723 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoA[i] );
724 }
725 break;
726 case GL_PIXEL_MAP_R_TO_R:
727 for (i = 0; i < mapsize; i++) {
728 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapRtoR[i] );
729 }
730 break;
731 case GL_PIXEL_MAP_G_TO_G:
732 for (i = 0; i < mapsize; i++) {
733 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapGtoG[i] );
734 }
735 break;
736 case GL_PIXEL_MAP_B_TO_B:
737 for (i = 0; i < mapsize; i++) {
738 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapBtoB[i] );
739 }
740 break;
741 case GL_PIXEL_MAP_A_TO_A:
742 for (i = 0; i < mapsize; i++) {
743 values[i] = FLOAT_TO_UINT( ctx->Pixel.MapAtoA[i] );
744 }
745 break;
746 default:
747 _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
748 }
749
750 if (ctx->Pack.BufferObj->Name) {
751 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
752 ctx->Pack.BufferObj);
753 }
754 }
755
756
757 void GLAPIENTRY
758 _mesa_GetPixelMapusv( GLenum map, GLushort *values )
759 {
760 GET_CURRENT_CONTEXT(ctx);
761 GLint mapsize, i;
762 ASSERT_OUTSIDE_BEGIN_END(ctx);
763
764 mapsize = get_map_size(ctx, map);
765
766 if (ctx->Pack.BufferObj->Name) {
767 /* pack pixelmap into PBO */
768 GLubyte *buf;
769 /* Note, need to use DefaultPacking and Pack's buffer object */
770 ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
771 if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1,
772 GL_INTENSITY, GL_UNSIGNED_SHORT,
773 values)) {
774 _mesa_error(ctx, GL_INVALID_OPERATION,
775 "glGetPixelMapusv(invalid PBO access)");
776 return;
777 }
778 /* restore */
779 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
780 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
781 GL_WRITE_ONLY_ARB,
782 ctx->Pack.BufferObj);
783 if (!buf) {
784 /* buffer is already mapped - that's an error */
785 _mesa_error(ctx, GL_INVALID_OPERATION,
786 "glGetPixelMapusv(PBO is mapped)");
787 return;
788 }
789 values = (GLushort *) ADD_POINTERS(buf, values);
790 }
791 else if (!values) {
792 return;
793 }
794
795 switch (map) {
796 case GL_PIXEL_MAP_I_TO_I:
797 for (i = 0; i < mapsize; i++) {
798 values[i] = (GLushort) ctx->Pixel.MapItoI[i];
799 }
800 break;
801 case GL_PIXEL_MAP_S_TO_S:
802 for (i = 0; i < mapsize; i++) {
803 values[i] = (GLushort) ctx->Pixel.MapStoS[i];
804 }
805 break;
806 case GL_PIXEL_MAP_I_TO_R:
807 for (i = 0; i < mapsize; i++) {
808 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoR[i] );
809 }
810 break;
811 case GL_PIXEL_MAP_I_TO_G:
812 for (i = 0; i < mapsize; i++) {
813 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoG[i] );
814 }
815 break;
816 case GL_PIXEL_MAP_I_TO_B:
817 for (i = 0; i < mapsize; i++) {
818 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoB[i] );
819 }
820 break;
821 case GL_PIXEL_MAP_I_TO_A:
822 for (i = 0; i < mapsize; i++) {
823 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoA[i] );
824 }
825 break;
826 case GL_PIXEL_MAP_R_TO_R:
827 for (i = 0; i < mapsize; i++) {
828 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapRtoR[i] );
829 }
830 break;
831 case GL_PIXEL_MAP_G_TO_G:
832 for (i = 0; i < mapsize; i++) {
833 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapGtoG[i] );
834 }
835 break;
836 case GL_PIXEL_MAP_B_TO_B:
837 for (i = 0; i < mapsize; i++) {
838 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapBtoB[i] );
839 }
840 break;
841 case GL_PIXEL_MAP_A_TO_A:
842 for (i = 0; i < mapsize; i++) {
843 values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapAtoA[i] );
844 }
845 break;
846 default:
847 _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
848 }
849
850 if (ctx->Pack.BufferObj->Name) {
851 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
852 ctx->Pack.BufferObj);
853 }
854 }
855
856
857
858 /**********************************************************************/
859 /***** glPixelTransfer *****/
860 /**********************************************************************/
861
862
863 /*
864 * Implements glPixelTransfer[fi] whether called immediately or from a
865 * display list.
866 */
867 void GLAPIENTRY
868 _mesa_PixelTransferf( GLenum pname, GLfloat param )
869 {
870 GET_CURRENT_CONTEXT(ctx);
871 ASSERT_OUTSIDE_BEGIN_END(ctx);
872
873 switch (pname) {
874 case GL_MAP_COLOR:
875 if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE))
876 return;
877 FLUSH_VERTICES(ctx, _NEW_PIXEL);
878 ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
879 break;
880 case GL_MAP_STENCIL:
881 if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE))
882 return;
883 FLUSH_VERTICES(ctx, _NEW_PIXEL);
884 ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
885 break;
886 case GL_INDEX_SHIFT:
887 if (ctx->Pixel.IndexShift == (GLint) param)
888 return;
889 FLUSH_VERTICES(ctx, _NEW_PIXEL);
890 ctx->Pixel.IndexShift = (GLint) param;
891 break;
892 case GL_INDEX_OFFSET:
893 if (ctx->Pixel.IndexOffset == (GLint) param)
894 return;
895 FLUSH_VERTICES(ctx, _NEW_PIXEL);
896 ctx->Pixel.IndexOffset = (GLint) param;
897 break;
898 case GL_RED_SCALE:
899 if (ctx->Pixel.RedScale == param)
900 return;
901 FLUSH_VERTICES(ctx, _NEW_PIXEL);
902 ctx->Pixel.RedScale = param;
903 break;
904 case GL_RED_BIAS:
905 if (ctx->Pixel.RedBias == param)
906 return;
907 FLUSH_VERTICES(ctx, _NEW_PIXEL);
908 ctx->Pixel.RedBias = param;
909 break;
910 case GL_GREEN_SCALE:
911 if (ctx->Pixel.GreenScale == param)
912 return;
913 FLUSH_VERTICES(ctx, _NEW_PIXEL);
914 ctx->Pixel.GreenScale = param;
915 break;
916 case GL_GREEN_BIAS:
917 if (ctx->Pixel.GreenBias == param)
918 return;
919 FLUSH_VERTICES(ctx, _NEW_PIXEL);
920 ctx->Pixel.GreenBias = param;
921 break;
922 case GL_BLUE_SCALE:
923 if (ctx->Pixel.BlueScale == param)
924 return;
925 FLUSH_VERTICES(ctx, _NEW_PIXEL);
926 ctx->Pixel.BlueScale = param;
927 break;
928 case GL_BLUE_BIAS:
929 if (ctx->Pixel.BlueBias == param)
930 return;
931 FLUSH_VERTICES(ctx, _NEW_PIXEL);
932 ctx->Pixel.BlueBias = param;
933 break;
934 case GL_ALPHA_SCALE:
935 if (ctx->Pixel.AlphaScale == param)
936 return;
937 FLUSH_VERTICES(ctx, _NEW_PIXEL);
938 ctx->Pixel.AlphaScale = param;
939 break;
940 case GL_ALPHA_BIAS:
941 if (ctx->Pixel.AlphaBias == param)
942 return;
943 FLUSH_VERTICES(ctx, _NEW_PIXEL);
944 ctx->Pixel.AlphaBias = param;
945 break;
946 case GL_DEPTH_SCALE:
947 if (ctx->Pixel.DepthScale == param)
948 return;
949 FLUSH_VERTICES(ctx, _NEW_PIXEL);
950 ctx->Pixel.DepthScale = param;
951 break;
952 case GL_DEPTH_BIAS:
953 if (ctx->Pixel.DepthBias == param)
954 return;
955 FLUSH_VERTICES(ctx, _NEW_PIXEL);
956 ctx->Pixel.DepthBias = param;
957 break;
958 case GL_POST_COLOR_MATRIX_RED_SCALE:
959 if (ctx->Pixel.PostColorMatrixScale[0] == param)
960 return;
961 FLUSH_VERTICES(ctx, _NEW_PIXEL);
962 ctx->Pixel.PostColorMatrixScale[0] = param;
963 break;
964 case GL_POST_COLOR_MATRIX_RED_BIAS:
965 if (ctx->Pixel.PostColorMatrixBias[0] == param)
966 return;
967 FLUSH_VERTICES(ctx, _NEW_PIXEL);
968 ctx->Pixel.PostColorMatrixBias[0] = param;
969 break;
970 case GL_POST_COLOR_MATRIX_GREEN_SCALE:
971 if (ctx->Pixel.PostColorMatrixScale[1] == param)
972 return;
973 FLUSH_VERTICES(ctx, _NEW_PIXEL);
974 ctx->Pixel.PostColorMatrixScale[1] = param;
975 break;
976 case GL_POST_COLOR_MATRIX_GREEN_BIAS:
977 if (ctx->Pixel.PostColorMatrixBias[1] == param)
978 return;
979 FLUSH_VERTICES(ctx, _NEW_PIXEL);
980 ctx->Pixel.PostColorMatrixBias[1] = param;
981 break;
982 case GL_POST_COLOR_MATRIX_BLUE_SCALE:
983 if (ctx->Pixel.PostColorMatrixScale[2] == param)
984 return;
985 FLUSH_VERTICES(ctx, _NEW_PIXEL);
986 ctx->Pixel.PostColorMatrixScale[2] = param;
987 break;
988 case GL_POST_COLOR_MATRIX_BLUE_BIAS:
989 if (ctx->Pixel.PostColorMatrixBias[2] == param)
990 return;
991 FLUSH_VERTICES(ctx, _NEW_PIXEL);
992 ctx->Pixel.PostColorMatrixBias[2] = param;
993 break;
994 case GL_POST_COLOR_MATRIX_ALPHA_SCALE:
995 if (ctx->Pixel.PostColorMatrixScale[3] == param)
996 return;
997 FLUSH_VERTICES(ctx, _NEW_PIXEL);
998 ctx->Pixel.PostColorMatrixScale[3] = param;
999 break;
1000 case GL_POST_COLOR_MATRIX_ALPHA_BIAS:
1001 if (ctx->Pixel.PostColorMatrixBias[3] == param)
1002 return;
1003 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1004 ctx->Pixel.PostColorMatrixBias[3] = param;
1005 break;
1006 case GL_POST_CONVOLUTION_RED_SCALE:
1007 if (ctx->Pixel.PostConvolutionScale[0] == param)
1008 return;
1009 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1010 ctx->Pixel.PostConvolutionScale[0] = param;
1011 break;
1012 case GL_POST_CONVOLUTION_RED_BIAS:
1013 if (ctx->Pixel.PostConvolutionBias[0] == param)
1014 return;
1015 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1016 ctx->Pixel.PostConvolutionBias[0] = param;
1017 break;
1018 case GL_POST_CONVOLUTION_GREEN_SCALE:
1019 if (ctx->Pixel.PostConvolutionScale[1] == param)
1020 return;
1021 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1022 ctx->Pixel.PostConvolutionScale[1] = param;
1023 break;
1024 case GL_POST_CONVOLUTION_GREEN_BIAS:
1025 if (ctx->Pixel.PostConvolutionBias[1] == param)
1026 return;
1027 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1028 ctx->Pixel.PostConvolutionBias[1] = param;
1029 break;
1030 case GL_POST_CONVOLUTION_BLUE_SCALE:
1031 if (ctx->Pixel.PostConvolutionScale[2] == param)
1032 return;
1033 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1034 ctx->Pixel.PostConvolutionScale[2] = param;
1035 break;
1036 case GL_POST_CONVOLUTION_BLUE_BIAS:
1037 if (ctx->Pixel.PostConvolutionBias[2] == param)
1038 return;
1039 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1040 ctx->Pixel.PostConvolutionBias[2] = param;
1041 break;
1042 case GL_POST_CONVOLUTION_ALPHA_SCALE:
1043 if (ctx->Pixel.PostConvolutionScale[2] == param)
1044 return;
1045 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1046 ctx->Pixel.PostConvolutionScale[2] = param;
1047 break;
1048 case GL_POST_CONVOLUTION_ALPHA_BIAS:
1049 if (ctx->Pixel.PostConvolutionBias[2] == param)
1050 return;
1051 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1052 ctx->Pixel.PostConvolutionBias[2] = param;
1053 break;
1054 default:
1055 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
1056 return;
1057 }
1058 }
1059
1060
1061 void GLAPIENTRY
1062 _mesa_PixelTransferi( GLenum pname, GLint param )
1063 {
1064 _mesa_PixelTransferf( pname, (GLfloat) param );
1065 }
1066
1067
1068
1069 /**********************************************************************/
1070 /***** Pixel processing functions ******/
1071 /**********************************************************************/
1072
1073 /*
1074 * Apply scale and bias factors to an array of RGBA pixels.
1075 */
1076 void
1077 _mesa_scale_and_bias_rgba(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
1078 GLfloat rScale, GLfloat gScale,
1079 GLfloat bScale, GLfloat aScale,
1080 GLfloat rBias, GLfloat gBias,
1081 GLfloat bBias, GLfloat aBias)
1082 {
1083 (void) ctx;
1084
1085 if (rScale != 1.0 || rBias != 0.0) {
1086 GLuint i;
1087 for (i = 0; i < n; i++) {
1088 rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias;
1089 }
1090 }
1091 if (gScale != 1.0 || gBias != 0.0) {
1092 GLuint i;
1093 for (i = 0; i < n; i++) {
1094 rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias;
1095 }
1096 }
1097 if (bScale != 1.0 || bBias != 0.0) {
1098 GLuint i;
1099 for (i = 0; i < n; i++) {
1100 rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias;
1101 }
1102 }
1103 if (aScale != 1.0 || aBias != 0.0) {
1104 GLuint i;
1105 for (i = 0; i < n; i++) {
1106 rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias;
1107 }
1108 }
1109 }
1110
1111
1112 /*
1113 * Apply pixel mapping to an array of floating point RGBA pixels.
1114 */
1115 void
1116 _mesa_map_rgba( const GLcontext *ctx, GLuint n, GLfloat rgba[][4] )
1117 {
1118 const GLfloat rscale = (GLfloat) (ctx->Pixel.MapRtoRsize - 1);
1119 const GLfloat gscale = (GLfloat) (ctx->Pixel.MapGtoGsize - 1);
1120 const GLfloat bscale = (GLfloat) (ctx->Pixel.MapBtoBsize - 1);
1121 const GLfloat ascale = (GLfloat) (ctx->Pixel.MapAtoAsize - 1);
1122 const GLfloat *rMap = ctx->Pixel.MapRtoR;
1123 const GLfloat *gMap = ctx->Pixel.MapGtoG;
1124 const GLfloat *bMap = ctx->Pixel.MapBtoB;
1125 const GLfloat *aMap = ctx->Pixel.MapAtoA;
1126 GLuint i;
1127 for (i=0;i<n;i++) {
1128 GLfloat r = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
1129 GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
1130 GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
1131 GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
1132 rgba[i][RCOMP] = rMap[IROUND(r * rscale)];
1133 rgba[i][GCOMP] = gMap[IROUND(g * gscale)];
1134 rgba[i][BCOMP] = bMap[IROUND(b * bscale)];
1135 rgba[i][ACOMP] = aMap[IROUND(a * ascale)];
1136 }
1137 }
1138
1139
1140 /*
1141 * Apply the color matrix and post color matrix scaling and biasing.
1142 */
1143 void
1144 _mesa_transform_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4])
1145 {
1146 const GLfloat rs = ctx->Pixel.PostColorMatrixScale[0];
1147 const GLfloat rb = ctx->Pixel.PostColorMatrixBias[0];
1148 const GLfloat gs = ctx->Pixel.PostColorMatrixScale[1];
1149 const GLfloat gb = ctx->Pixel.PostColorMatrixBias[1];
1150 const GLfloat bs = ctx->Pixel.PostColorMatrixScale[2];
1151 const GLfloat bb = ctx->Pixel.PostColorMatrixBias[2];
1152 const GLfloat as = ctx->Pixel.PostColorMatrixScale[3];
1153 const GLfloat ab = ctx->Pixel.PostColorMatrixBias[3];
1154 const GLfloat *m = ctx->ColorMatrixStack.Top->m;
1155 GLuint i;
1156 for (i = 0; i < n; i++) {
1157 const GLfloat r = rgba[i][RCOMP];
1158 const GLfloat g = rgba[i][GCOMP];
1159 const GLfloat b = rgba[i][BCOMP];
1160 const GLfloat a = rgba[i][ACOMP];
1161 rgba[i][RCOMP] = (m[0] * r + m[4] * g + m[ 8] * b + m[12] * a) * rs + rb;
1162 rgba[i][GCOMP] = (m[1] * r + m[5] * g + m[ 9] * b + m[13] * a) * gs + gb;
1163 rgba[i][BCOMP] = (m[2] * r + m[6] * g + m[10] * b + m[14] * a) * bs + bb;
1164 rgba[i][ACOMP] = (m[3] * r + m[7] * g + m[11] * b + m[15] * a) * as + ab;
1165 }
1166 }
1167
1168
1169 /**
1170 * Apply a color table lookup to an array of floating point RGBA colors.
1171 */
1172 void
1173 _mesa_lookup_rgba_float(const struct gl_color_table *table,
1174 GLuint n, GLfloat rgba[][4])
1175 {
1176 if (!table->Table || table->Size == 0)
1177 return;
1178
1179 switch (table->Format) {
1180 case GL_INTENSITY:
1181 /* replace RGBA with I */
1182 if (table->Type == GL_FLOAT) {
1183 const GLint max = table->Size - 1;
1184 const GLfloat scale = (GLfloat) max;
1185 const GLfloat *lut = (const GLfloat *) table->Table;
1186 GLuint i;
1187 for (i = 0; i < n; i++) {
1188 GLint j = IROUND(rgba[i][RCOMP] * scale);
1189 GLfloat c = lut[CLAMP(j, 0, max)];
1190 rgba[i][RCOMP] = rgba[i][GCOMP] =
1191 rgba[i][BCOMP] = rgba[i][ACOMP] = c;
1192 }
1193 }
1194 else {
1195 const GLint max = table->Size - 1;
1196 const GLfloat scale = (GLfloat) max;
1197 const GLchan *lut = (const GLchan *) table->Table;
1198 GLuint i;
1199 for (i = 0; i < n; i++) {
1200 GLint j = IROUND(rgba[i][RCOMP] * scale);
1201 GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
1202 rgba[i][RCOMP] = rgba[i][GCOMP] =
1203 rgba[i][BCOMP] = rgba[i][ACOMP] = c;
1204 }
1205 }
1206 break;
1207 case GL_LUMINANCE:
1208 /* replace RGB with L */
1209 if (table->Type == GL_FLOAT) {
1210 const GLint max = table->Size - 1;
1211 const GLfloat scale = (GLfloat) max;
1212 const GLfloat *lut = (const GLfloat *) table->Table;
1213 GLuint i;
1214 for (i = 0; i < n; i++) {
1215 GLint j = IROUND(rgba[i][RCOMP] * scale);
1216 GLfloat c = lut[CLAMP(j, 0, max)];
1217 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
1218 }
1219 }
1220 else {
1221 const GLint max = table->Size - 1;
1222 const GLfloat scale = (GLfloat) max;
1223 const GLchan *lut = (const GLchan *) table->Table;
1224 GLuint i;
1225 for (i = 0; i < n; i++) {
1226 GLint j = IROUND(rgba[i][RCOMP] * scale);
1227 GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
1228 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
1229 }
1230 }
1231 break;
1232 case GL_ALPHA:
1233 /* replace A with A */
1234 if (table->Type == GL_FLOAT) {
1235 const GLint max = table->Size - 1;
1236 const GLfloat scale = (GLfloat) max;
1237 const GLfloat *lut = (const GLfloat *) table->Table;
1238 GLuint i;
1239 for (i = 0; i < n; i++) {
1240 GLint j = IROUND(rgba[i][ACOMP] * scale);
1241 rgba[i][ACOMP] = lut[CLAMP(j, 0, max)];
1242 }
1243 }
1244 else {
1245 const GLint max = table->Size - 1;
1246 const GLfloat scale = (GLfloat) max;
1247 const GLchan *lut = (const GLchan *) table->Table;
1248 GLuint i;
1249 for (i = 0; i < n; i++) {
1250 GLint j = IROUND(rgba[i][ACOMP] * scale);
1251 rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
1252 }
1253 }
1254 break;
1255 case GL_LUMINANCE_ALPHA:
1256 /* replace RGBA with LLLA */
1257 if (table->Type == GL_FLOAT) {
1258 const GLint max = table->Size - 1;
1259 const GLfloat scale = (GLfloat) max;
1260 const GLfloat *lut = (const GLfloat *) table->Table;
1261 GLuint i;
1262 for (i = 0; i < n; i++) {
1263 GLint jL = IROUND(rgba[i][RCOMP] * scale);
1264 GLint jA = IROUND(rgba[i][ACOMP] * scale);
1265 GLfloat luminance, alpha;
1266 jL = CLAMP(jL, 0, max);
1267 jA = CLAMP(jA, 0, max);
1268 luminance = lut[jL * 2 + 0];
1269 alpha = lut[jA * 2 + 1];
1270 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
1271 rgba[i][ACOMP] = alpha;;
1272 }
1273 }
1274 else {
1275 const GLint max = table->Size - 1;
1276 const GLfloat scale = (GLfloat) max;
1277 const GLchan *lut = (const GLchan *) table->Table;
1278 GLuint i;
1279 for (i = 0; i < n; i++) {
1280 GLint jL = IROUND(rgba[i][RCOMP] * scale);
1281 GLint jA = IROUND(rgba[i][ACOMP] * scale);
1282 GLfloat luminance, alpha;
1283 jL = CLAMP(jL, 0, max);
1284 jA = CLAMP(jA, 0, max);
1285 luminance = CHAN_TO_FLOAT(lut[jL * 2 + 0]);
1286 alpha = CHAN_TO_FLOAT(lut[jA * 2 + 1]);
1287 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
1288 rgba[i][ACOMP] = alpha;;
1289 }
1290 }
1291 break;
1292 case GL_RGB:
1293 /* replace RGB with RGB */
1294 if (table->Type == GL_FLOAT) {
1295 const GLint max = table->Size - 1;
1296 const GLfloat scale = (GLfloat) max;
1297 const GLfloat *lut = (const GLfloat *) table->Table;
1298 GLuint i;
1299 for (i = 0; i < n; i++) {
1300 GLint jR = IROUND(rgba[i][RCOMP] * scale);
1301 GLint jG = IROUND(rgba[i][GCOMP] * scale);
1302 GLint jB = IROUND(rgba[i][BCOMP] * scale);
1303 jR = CLAMP(jR, 0, max);
1304 jG = CLAMP(jG, 0, max);
1305 jB = CLAMP(jB, 0, max);
1306 rgba[i][RCOMP] = lut[jR * 3 + 0];
1307 rgba[i][GCOMP] = lut[jG * 3 + 1];
1308 rgba[i][BCOMP] = lut[jB * 3 + 2];
1309 }
1310 }
1311 else {
1312 const GLint max = table->Size - 1;
1313 const GLfloat scale = (GLfloat) max;
1314 const GLchan *lut = (const GLchan *) table->Table;
1315 GLuint i;
1316 for (i = 0; i < n; i++) {
1317 GLint jR = IROUND(rgba[i][RCOMP] * scale);
1318 GLint jG = IROUND(rgba[i][GCOMP] * scale);
1319 GLint jB = IROUND(rgba[i][BCOMP] * scale);
1320 jR = CLAMP(jR, 0, max);
1321 jG = CLAMP(jG, 0, max);
1322 jB = CLAMP(jB, 0, max);
1323 rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 3 + 0]);
1324 rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 3 + 1]);
1325 rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 3 + 2]);
1326 }
1327 }
1328 break;
1329 case GL_RGBA:
1330 /* replace RGBA with RGBA */
1331 if (table->Type == GL_FLOAT) {
1332 const GLint max = table->Size - 1;
1333 const GLfloat scale = (GLfloat) max;
1334 const GLfloat *lut = (const GLfloat *) table->Table;
1335 GLuint i;
1336 for (i = 0; i < n; i++) {
1337 GLint jR = IROUND(rgba[i][RCOMP] * scale);
1338 GLint jG = IROUND(rgba[i][GCOMP] * scale);
1339 GLint jB = IROUND(rgba[i][BCOMP] * scale);
1340 GLint jA = IROUND(rgba[i][ACOMP] * scale);
1341 jR = CLAMP(jR, 0, max);
1342 jG = CLAMP(jG, 0, max);
1343 jB = CLAMP(jB, 0, max);
1344 jA = CLAMP(jA, 0, max);
1345 rgba[i][RCOMP] = lut[jR * 4 + 0];
1346 rgba[i][GCOMP] = lut[jG * 4 + 1];
1347 rgba[i][BCOMP] = lut[jB * 4 + 2];
1348 rgba[i][ACOMP] = lut[jA * 4 + 3];
1349 }
1350 }
1351 else {
1352 const GLint max = table->Size - 1;
1353 const GLfloat scale = (GLfloat) max;
1354 const GLchan *lut = (const GLchan *) table->Table;
1355 GLuint i;
1356 for (i = 0; i < n; i++) {
1357 GLint jR = IROUND(rgba[i][RCOMP] * scale);
1358 GLint jG = IROUND(rgba[i][GCOMP] * scale);
1359 GLint jB = IROUND(rgba[i][BCOMP] * scale);
1360 GLint jA = IROUND(rgba[i][ACOMP] * scale);
1361 jR = CLAMP(jR, 0, max);
1362 jG = CLAMP(jG, 0, max);
1363 jB = CLAMP(jB, 0, max);
1364 jA = CLAMP(jA, 0, max);
1365 rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 4 + 0]);
1366 rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 4 + 1]);
1367 rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 4 + 2]);
1368 rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[jA * 4 + 3]);
1369 }
1370 }
1371 break;
1372 default:
1373 _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_float");
1374 return;
1375 }
1376 }
1377
1378
1379
1380 /**
1381 * Apply a color table lookup to an array of GLchan RGBA colors.
1382 */
1383 void
1384 _mesa_lookup_rgba_chan(const struct gl_color_table *table,
1385 GLuint n, GLchan rgba[][4])
1386 {
1387 if (!table->Table || table->Size == 0)
1388 return;
1389
1390 switch (table->Format) {
1391 case GL_INTENSITY:
1392 /* replace RGBA with I */
1393 if (table->Type == GL_FLOAT) {
1394 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1395 const GLfloat *lut = (const GLfloat *) table->Table;
1396 GLuint i;
1397 for (i = 0; i < n; i++) {
1398 GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1399 GLchan c;
1400 CLAMPED_FLOAT_TO_CHAN(c, lut[j]);
1401 rgba[i][RCOMP] = rgba[i][GCOMP] =
1402 rgba[i][BCOMP] = rgba[i][ACOMP] = c;
1403 }
1404 }
1405 else {
1406 #if CHAN_TYPE == GL_UNSIGNED_BYTE
1407 if (table->Size == 256) {
1408 /* common case */
1409 const GLchan *lut = (const GLchan *) table->Table;
1410 GLuint i;
1411 for (i = 0; i < n; i++) {
1412 const GLchan c = lut[rgba[i][RCOMP]];
1413 rgba[i][RCOMP] = rgba[i][GCOMP] =
1414 rgba[i][BCOMP] = rgba[i][ACOMP] = c;
1415 }
1416 }
1417 else
1418 #endif
1419 {
1420 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1421 const GLchan *lut = (const GLchan *) table->Table;
1422 GLuint i;
1423 for (i = 0; i < n; i++) {
1424 GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1425 rgba[i][RCOMP] = rgba[i][GCOMP] =
1426 rgba[i][BCOMP] = rgba[i][ACOMP] = lut[j];
1427 }
1428 }
1429 }
1430 break;
1431 case GL_LUMINANCE:
1432 /* replace RGB with L */
1433 if (table->Type == GL_FLOAT) {
1434 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1435 const GLfloat *lut = (const GLfloat *) table->Table;
1436 GLuint i;
1437 for (i = 0; i < n; i++) {
1438 GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1439 GLchan c;
1440 CLAMPED_FLOAT_TO_CHAN(c, lut[j]);
1441 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
1442 }
1443 }
1444 else {
1445 #if CHAN_TYPE == GL_UNSIGNED_BYTE
1446 if (table->Size == 256) {
1447 /* common case */
1448 const GLchan *lut = (const GLchan *) table->Table;
1449 GLuint i;
1450 for (i = 0; i < n; i++) {
1451 const GLchan c = lut[rgba[i][RCOMP]];
1452 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
1453 }
1454 }
1455 else
1456 #endif
1457 {
1458 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1459 const GLchan *lut = (const GLchan *) table->Table;
1460 GLuint i;
1461 for (i = 0; i < n; i++) {
1462 GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1463 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = lut[j];
1464 }
1465 }
1466 }
1467 break;
1468 case GL_ALPHA:
1469 /* replace A with A */
1470 if (table->Type == GL_FLOAT) {
1471 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1472 const GLfloat *lut = (const GLfloat *) table->Table;
1473 GLuint i;
1474 for (i = 0; i < n; i++) {
1475 GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1476 GLchan c;
1477 CLAMPED_FLOAT_TO_CHAN(c, lut[j]);
1478 rgba[i][ACOMP] = c;
1479 }
1480 }
1481 else {
1482 #if CHAN_TYPE == GL_UNSIGNED_BYTE
1483 if (table->Size == 256) {
1484 /* common case */
1485 const GLchan *lut = (const GLchan *) table->Table;
1486 GLuint i;
1487 for (i = 0; i < n; i++) {
1488 rgba[i][ACOMP] = lut[rgba[i][ACOMP]];
1489 }
1490 }
1491 else
1492 #endif
1493 {
1494 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1495 const GLchan *lut = (const GLchan *) table->Table;
1496 GLuint i;
1497 for (i = 0; i < n; i++) {
1498 GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1499 rgba[i][ACOMP] = lut[j];
1500 }
1501 }
1502 }
1503 break;
1504 case GL_LUMINANCE_ALPHA:
1505 /* replace RGBA with LLLA */
1506 if (table->Type == GL_FLOAT) {
1507 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1508 const GLfloat *lut = (const GLfloat *) table->Table;
1509 GLuint i;
1510 for (i = 0; i < n; i++) {
1511 GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1512 GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1513 GLchan luminance, alpha;
1514 CLAMPED_FLOAT_TO_CHAN(luminance, lut[jL * 2 + 0]);
1515 CLAMPED_FLOAT_TO_CHAN(alpha, lut[jA * 2 + 1]);
1516 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
1517 rgba[i][ACOMP] = alpha;;
1518 }
1519 }
1520 else {
1521 #if CHAN_TYPE == GL_UNSIGNED_BYTE
1522 if (table->Size == 256) {
1523 /* common case */
1524 const GLchan *lut = (const GLchan *) table->Table;
1525 GLuint i;
1526 for (i = 0; i < n; i++) {
1527 GLchan l = lut[rgba[i][RCOMP] * 2 + 0];
1528 GLchan a = lut[rgba[i][ACOMP] * 2 + 1];;
1529 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = l;
1530 rgba[i][ACOMP] = a;
1531 }
1532 }
1533 else
1534 #endif
1535 {
1536 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1537 const GLchan *lut = (const GLchan *) table->Table;
1538 GLuint i;
1539 for (i = 0; i < n; i++) {
1540 GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1541 GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1542 GLchan luminance = lut[jL * 2 + 0];
1543 GLchan alpha = lut[jA * 2 + 1];
1544 rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
1545 rgba[i][ACOMP] = alpha;
1546 }
1547 }
1548 }
1549 break;
1550 case GL_RGB:
1551 /* replace RGB with RGB */
1552 if (table->Type == GL_FLOAT) {
1553 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1554 const GLfloat *lut = (const GLfloat *) table->Table;
1555 GLuint i;
1556 for (i = 0; i < n; i++) {
1557 GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1558 GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1559 GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1560 CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 3 + 0]);
1561 CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 3 + 1]);
1562 CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 3 + 2]);
1563 }
1564 }
1565 else {
1566 #if CHAN_TYPE == GL_UNSIGNED_BYTE
1567 if (table->Size == 256) {
1568 /* common case */
1569 const GLchan *lut = (const GLchan *) table->Table;
1570 GLuint i;
1571 for (i = 0; i < n; i++) {
1572 rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 3 + 0];
1573 rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 3 + 1];
1574 rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 3 + 2];
1575 }
1576 }
1577 else
1578 #endif
1579 {
1580 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1581 const GLchan *lut = (const GLchan *) table->Table;
1582 GLuint i;
1583 for (i = 0; i < n; i++) {
1584 GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1585 GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1586 GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1587 rgba[i][RCOMP] = lut[jR * 3 + 0];
1588 rgba[i][GCOMP] = lut[jG * 3 + 1];
1589 rgba[i][BCOMP] = lut[jB * 3 + 2];
1590 }
1591 }
1592 }
1593 break;
1594 case GL_RGBA:
1595 /* replace RGBA with RGBA */
1596 if (table->Type == GL_FLOAT) {
1597 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1598 const GLfloat *lut = (const GLfloat *) table->Table;
1599 GLuint i;
1600 for (i = 0; i < n; i++) {
1601 GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1602 GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1603 GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1604 GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1605 CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]);
1606 CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]);
1607 CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]);
1608 CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]);
1609 }
1610 }
1611 else {
1612 #if CHAN_TYPE == GL_UNSIGNED_BYTE
1613 if (table->Size == 256) {
1614 /* common case */
1615 const GLchan *lut = (const GLchan *) table->Table;
1616 GLuint i;
1617 for (i = 0; i < n; i++) {
1618 rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 4 + 0];
1619 rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 4 + 1];
1620 rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 4 + 2];
1621 rgba[i][ACOMP] = lut[rgba[i][ACOMP] * 4 + 3];
1622 }
1623 }
1624 else
1625 #endif
1626 {
1627 const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1628 const GLfloat *lut = (const GLfloat *) table->Table;
1629 GLuint i;
1630 for (i = 0; i < n; i++) {
1631 GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1632 GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1633 GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1634 GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1635 CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]);
1636 CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]);
1637 CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]);
1638 CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]);
1639 }
1640 }
1641 }
1642 break;
1643 default:
1644 _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_chan");
1645 return;
1646 }
1647 }
1648
1649
1650
1651 /*
1652 * Apply color index shift and offset to an array of pixels.
1653 */
1654 void
1655 _mesa_shift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] )
1656 {
1657 GLint shift = ctx->Pixel.IndexShift;
1658 GLint offset = ctx->Pixel.IndexOffset;
1659 GLuint i;
1660 if (shift > 0) {
1661 for (i=0;i<n;i++) {
1662 indexes[i] = (indexes[i] << shift) + offset;
1663 }
1664 }
1665 else if (shift < 0) {
1666 shift = -shift;
1667 for (i=0;i<n;i++) {
1668 indexes[i] = (indexes[i] >> shift) + offset;
1669 }
1670 }
1671 else {
1672 for (i=0;i<n;i++) {
1673 indexes[i] = indexes[i] + offset;
1674 }
1675 }
1676 }
1677
1678
1679 /*
1680 * Apply color index mapping to color indexes.
1681 */
1682 void
1683 _mesa_map_ci( const GLcontext *ctx, GLuint n, GLuint index[] )
1684 {
1685 GLuint mask = ctx->Pixel.MapItoIsize - 1;
1686 GLuint i;
1687 for (i=0;i<n;i++) {
1688 index[i] = ctx->Pixel.MapItoI[ index[i] & mask ];
1689 }
1690 }
1691
1692
1693 /*
1694 * Map color indexes to rgba values.
1695 */
1696 void
1697 _mesa_map_ci_to_rgba_chan( const GLcontext *ctx, GLuint n,
1698 const GLuint index[], GLchan rgba[][4] )
1699 {
1700 #if CHAN_BITS == 8
1701 GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1702 GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1703 GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1704 GLuint amask = ctx->Pixel.MapItoAsize - 1;
1705 const GLubyte *rMap = ctx->Pixel.MapItoR8;
1706 const GLubyte *gMap = ctx->Pixel.MapItoG8;
1707 const GLubyte *bMap = ctx->Pixel.MapItoB8;
1708 const GLubyte *aMap = ctx->Pixel.MapItoA8;
1709 GLuint i;
1710 for (i=0;i<n;i++) {
1711 rgba[i][RCOMP] = rMap[index[i] & rmask];
1712 rgba[i][GCOMP] = gMap[index[i] & gmask];
1713 rgba[i][BCOMP] = bMap[index[i] & bmask];
1714 rgba[i][ACOMP] = aMap[index[i] & amask];
1715 }
1716 #else
1717 GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1718 GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1719 GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1720 GLuint amask = ctx->Pixel.MapItoAsize - 1;
1721 const GLfloat *rMap = ctx->Pixel.MapItoR;
1722 const GLfloat *gMap = ctx->Pixel.MapItoG;
1723 const GLfloat *bMap = ctx->Pixel.MapItoB;
1724 const GLfloat *aMap = ctx->Pixel.MapItoA;
1725 GLuint i;
1726 for (i=0;i<n;i++) {
1727 CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]);
1728 CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]);
1729 CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]);
1730 CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]);
1731 }
1732 #endif
1733 }
1734
1735
1736 /*
1737 * Map color indexes to float rgba values.
1738 */
1739 void
1740 _mesa_map_ci_to_rgba( const GLcontext *ctx, GLuint n,
1741 const GLuint index[], GLfloat rgba[][4] )
1742 {
1743 GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1744 GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1745 GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1746 GLuint amask = ctx->Pixel.MapItoAsize - 1;
1747 const GLfloat *rMap = ctx->Pixel.MapItoR;
1748 const GLfloat *gMap = ctx->Pixel.MapItoG;
1749 const GLfloat *bMap = ctx->Pixel.MapItoB;
1750 const GLfloat *aMap = ctx->Pixel.MapItoA;
1751 GLuint i;
1752 for (i=0;i<n;i++) {
1753 rgba[i][RCOMP] = rMap[index[i] & rmask];
1754 rgba[i][GCOMP] = gMap[index[i] & gmask];
1755 rgba[i][BCOMP] = bMap[index[i] & bmask];
1756 rgba[i][ACOMP] = aMap[index[i] & amask];
1757 }
1758 }
1759
1760
1761 /*
1762 * Map 8-bit color indexes to rgb values.
1763 */
1764 void
1765 _mesa_map_ci8_to_rgba( const GLcontext *ctx, GLuint n, const GLubyte index[],
1766 GLchan rgba[][4] )
1767 {
1768 #if CHAN_BITS == 8
1769 GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1770 GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1771 GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1772 GLuint amask = ctx->Pixel.MapItoAsize - 1;
1773 const GLubyte *rMap = ctx->Pixel.MapItoR8;
1774 const GLubyte *gMap = ctx->Pixel.MapItoG8;
1775 const GLubyte *bMap = ctx->Pixel.MapItoB8;
1776 const GLubyte *aMap = ctx->Pixel.MapItoA8;
1777 GLuint i;
1778 for (i=0;i<n;i++) {
1779 rgba[i][RCOMP] = rMap[index[i] & rmask];
1780 rgba[i][GCOMP] = gMap[index[i] & gmask];
1781 rgba[i][BCOMP] = bMap[index[i] & bmask];
1782 rgba[i][ACOMP] = aMap[index[i] & amask];
1783 }
1784 #else
1785 GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1786 GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1787 GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1788 GLuint amask = ctx->Pixel.MapItoAsize - 1;
1789 const GLfloat *rMap = ctx->Pixel.MapItoR;
1790 const GLfloat *gMap = ctx->Pixel.MapItoG;
1791 const GLfloat *bMap = ctx->Pixel.MapItoB;
1792 const GLfloat *aMap = ctx->Pixel.MapItoA;
1793 GLuint i;
1794 for (i=0;i<n;i++) {
1795 CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]);
1796 CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]);
1797 CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]);
1798 CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]);
1799 }
1800 #endif
1801 }
1802
1803
1804 void
1805 _mesa_shift_and_offset_stencil( const GLcontext *ctx, GLuint n,
1806 GLstencil stencil[] )
1807 {
1808 GLuint i;
1809 GLint shift = ctx->Pixel.IndexShift;
1810 GLint offset = ctx->Pixel.IndexOffset;
1811 if (shift > 0) {
1812 for (i=0;i<n;i++) {
1813 stencil[i] = (stencil[i] << shift) + offset;
1814 }
1815 }
1816 else if (shift < 0) {
1817 shift = -shift;
1818 for (i=0;i<n;i++) {
1819 stencil[i] = (stencil[i] >> shift) + offset;
1820 }
1821 }
1822 else {
1823 for (i=0;i<n;i++) {
1824 stencil[i] = stencil[i] + offset;
1825 }
1826 }
1827
1828 }
1829
1830
1831 void
1832 _mesa_map_stencil( const GLcontext *ctx, GLuint n, GLstencil stencil[] )
1833 {
1834 GLuint mask = ctx->Pixel.MapStoSsize - 1;
1835 GLuint i;
1836 for (i=0;i<n;i++) {
1837 stencil[i] = ctx->Pixel.MapStoS[ stencil[i] & mask ];
1838 }
1839 }
1840
1841
1842
1843 /*
1844 * This function converts an array of GLchan colors to GLfloat colors.
1845 * Most importantly, it undoes the non-uniform quantization of pixel
1846 * values introduced when we convert shallow (< 8 bit) pixel values
1847 * to GLubytes in the ctx->Driver.ReadRGBASpan() functions.
1848 * This fixes a number of OpenGL conformance failures when running on
1849 * 16bpp displays, for example.
1850 */
1851 void
1852 _mesa_chan_to_float_span(const GLcontext *ctx, GLuint n,
1853 CONST GLchan rgba[][4], GLfloat rgbaf[][4])
1854 {
1855 #if CHAN_TYPE == GL_FLOAT
1856 MEMCPY(rgbaf, rgba, n * 4 * sizeof(GLfloat));
1857 #else
1858 const GLuint rShift = CHAN_BITS - ctx->Visual.redBits;
1859 const GLuint gShift = CHAN_BITS - ctx->Visual.greenBits;
1860 const GLuint bShift = CHAN_BITS - ctx->Visual.blueBits;
1861 GLuint aShift;
1862 const GLfloat rScale = 1.0F / (GLfloat) ((1 << ctx->Visual.redBits ) - 1);
1863 const GLfloat gScale = 1.0F / (GLfloat) ((1 << ctx->Visual.greenBits) - 1);
1864 const GLfloat bScale = 1.0F / (GLfloat) ((1 << ctx->Visual.blueBits ) - 1);
1865 GLfloat aScale;
1866 GLuint i;
1867
1868 if (ctx->Visual.alphaBits > 0) {
1869 aShift = CHAN_BITS - ctx->Visual.alphaBits;
1870 aScale = 1.0F / (GLfloat) ((1 << ctx->Visual.alphaBits) - 1);
1871 }
1872 else {
1873 aShift = 0;
1874 aScale = 1.0F / CHAN_MAXF;
1875 }
1876
1877 for (i = 0; i < n; i++) {
1878 const GLint r = rgba[i][RCOMP] >> rShift;
1879 const GLint g = rgba[i][GCOMP] >> gShift;
1880 const GLint b = rgba[i][BCOMP] >> bShift;
1881 const GLint a = rgba[i][ACOMP] >> aShift;
1882 rgbaf[i][RCOMP] = (GLfloat) r * rScale;
1883 rgbaf[i][GCOMP] = (GLfloat) g * gScale;
1884 rgbaf[i][BCOMP] = (GLfloat) b * bScale;
1885 rgbaf[i][ACOMP] = (GLfloat) a * aScale;
1886 }
1887 #endif
1888 }
1889
1890 /**********************************************************************/
1891 /***** State Management *****/
1892 /**********************************************************************/
1893
1894 /*
1895 * Return a bitmask of IMAGE_*_BIT flags which to indicate which
1896 * pixel transfer operations are enabled.
1897 */
1898 static void
1899 update_image_transfer_state(GLcontext *ctx)
1900 {
1901 GLuint mask = 0;
1902
1903 if (ctx->Pixel.RedScale != 1.0F || ctx->Pixel.RedBias != 0.0F ||
1904 ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F ||
1905 ctx->Pixel.BlueScale != 1.0F || ctx->Pixel.BlueBias != 0.0F ||
1906 ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F)
1907 mask |= IMAGE_SCALE_BIAS_BIT;
1908
1909 if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset)
1910 mask |= IMAGE_SHIFT_OFFSET_BIT;
1911
1912 if (ctx->Pixel.MapColorFlag)
1913 mask |= IMAGE_MAP_COLOR_BIT;
1914
1915 if (ctx->Pixel.ColorTableEnabled)
1916 mask |= IMAGE_COLOR_TABLE_BIT;
1917
1918 if (ctx->Pixel.Convolution1DEnabled ||
1919 ctx->Pixel.Convolution2DEnabled ||
1920 ctx->Pixel.Separable2DEnabled) {
1921 mask |= IMAGE_CONVOLUTION_BIT;
1922 if (ctx->Pixel.PostConvolutionScale[0] != 1.0F ||
1923 ctx->Pixel.PostConvolutionScale[1] != 1.0F ||
1924 ctx->Pixel.PostConvolutionScale[2] != 1.0F ||
1925 ctx->Pixel.PostConvolutionScale[3] != 1.0F ||
1926 ctx->Pixel.PostConvolutionBias[0] != 0.0F ||
1927 ctx->Pixel.PostConvolutionBias[1] != 0.0F ||
1928 ctx->Pixel.PostConvolutionBias[2] != 0.0F ||
1929 ctx->Pixel.PostConvolutionBias[3] != 0.0F) {
1930 mask |= IMAGE_POST_CONVOLUTION_SCALE_BIAS;
1931 }
1932 }
1933
1934 if (ctx->Pixel.PostConvolutionColorTableEnabled)
1935 mask |= IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT;
1936
1937 if (ctx->ColorMatrixStack.Top->type != MATRIX_IDENTITY ||
1938 ctx->Pixel.PostColorMatrixScale[0] != 1.0F ||
1939 ctx->Pixel.PostColorMatrixBias[0] != 0.0F ||
1940 ctx->Pixel.PostColorMatrixScale[1] != 1.0F ||
1941 ctx->Pixel.PostColorMatrixBias[1] != 0.0F ||
1942 ctx->Pixel.PostColorMatrixScale[2] != 1.0F ||
1943 ctx->Pixel.PostColorMatrixBias[2] != 0.0F ||
1944 ctx->Pixel.PostColorMatrixScale[3] != 1.0F ||
1945 ctx->Pixel.PostColorMatrixBias[3] != 0.0F)
1946 mask |= IMAGE_COLOR_MATRIX_BIT;
1947
1948 if (ctx->Pixel.PostColorMatrixColorTableEnabled)
1949 mask |= IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT;
1950
1951 if (ctx->Pixel.HistogramEnabled)
1952 mask |= IMAGE_HISTOGRAM_BIT;
1953
1954 if (ctx->Pixel.MinMaxEnabled)
1955 mask |= IMAGE_MIN_MAX_BIT;
1956
1957 ctx->_ImageTransferState = mask;
1958 }
1959
1960
1961 void _mesa_update_pixel( GLcontext *ctx, GLuint new_state )
1962 {
1963 if (new_state & _NEW_COLOR_MATRIX)
1964 _math_matrix_analyse( ctx->ColorMatrixStack.Top );
1965
1966 /* References ColorMatrix.type (derived above).
1967 */
1968 if (new_state & _IMAGE_NEW_TRANSFER_STATE)
1969 update_image_transfer_state(ctx);
1970 }
1971
1972
1973 /**********************************************************************/
1974 /***** Initialization *****/
1975 /**********************************************************************/
1976
1977
1978 /**
1979 * Initialize the context's PIXEL attribute group.
1980 */
1981 void
1982 _mesa_init_pixel( GLcontext *ctx )
1983 {
1984 int i;
1985
1986 /* Pixel group */
1987 ctx->Pixel.RedBias = 0.0;
1988 ctx->Pixel.RedScale = 1.0;
1989 ctx->Pixel.GreenBias = 0.0;
1990 ctx->Pixel.GreenScale = 1.0;
1991 ctx->Pixel.BlueBias = 0.0;
1992 ctx->Pixel.BlueScale = 1.0;
1993 ctx->Pixel.AlphaBias = 0.0;
1994 ctx->Pixel.AlphaScale = 1.0;
1995 ctx->Pixel.DepthBias = 0.0;
1996 ctx->Pixel.DepthScale = 1.0;
1997 ctx->Pixel.IndexOffset = 0;
1998 ctx->Pixel.IndexShift = 0;
1999 ctx->Pixel.ZoomX = 1.0;
2000 ctx->Pixel.ZoomY = 1.0;
2001 ctx->Pixel.MapColorFlag = GL_FALSE;
2002 ctx->Pixel.MapStencilFlag = GL_FALSE;
2003 ctx->Pixel.MapStoSsize = 1;
2004 ctx->Pixel.MapItoIsize = 1;
2005 ctx->Pixel.MapItoRsize = 1;
2006 ctx->Pixel.MapItoGsize = 1;
2007 ctx->Pixel.MapItoBsize = 1;
2008 ctx->Pixel.MapItoAsize = 1;
2009 ctx->Pixel.MapRtoRsize = 1;
2010 ctx->Pixel.MapGtoGsize = 1;
2011 ctx->Pixel.MapBtoBsize = 1;
2012 ctx->Pixel.MapAtoAsize = 1;
2013 ctx->Pixel.MapStoS[0] = 0;
2014 ctx->Pixel.MapItoI[0] = 0;
2015 ctx->Pixel.MapItoR[0] = 0.0;
2016 ctx->Pixel.MapItoG[0] = 0.0;
2017 ctx->Pixel.MapItoB[0] = 0.0;
2018 ctx->Pixel.MapItoA[0] = 0.0;
2019 ctx->Pixel.MapItoR8[0] = 0;
2020 ctx->Pixel.MapItoG8[0] = 0;
2021 ctx->Pixel.MapItoB8[0] = 0;
2022 ctx->Pixel.MapItoA8[0] = 0;
2023 ctx->Pixel.MapRtoR[0] = 0.0;
2024 ctx->Pixel.MapGtoG[0] = 0.0;
2025 ctx->Pixel.MapBtoB[0] = 0.0;
2026 ctx->Pixel.MapAtoA[0] = 0.0;
2027 ctx->Pixel.HistogramEnabled = GL_FALSE;
2028 ctx->Pixel.MinMaxEnabled = GL_FALSE;
2029 ctx->Pixel.PixelTextureEnabled = GL_FALSE;
2030 ctx->Pixel.FragmentRgbSource = GL_PIXEL_GROUP_COLOR_SGIS;
2031 ctx->Pixel.FragmentAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS;
2032 ASSIGN_4V(ctx->Pixel.PostColorMatrixScale, 1.0, 1.0, 1.0, 1.0);
2033 ASSIGN_4V(ctx->Pixel.PostColorMatrixBias, 0.0, 0.0, 0.0, 0.0);
2034 ASSIGN_4V(ctx->Pixel.ColorTableScale, 1.0, 1.0, 1.0, 1.0);
2035 ASSIGN_4V(ctx->Pixel.ColorTableBias, 0.0, 0.0, 0.0, 0.0);
2036 ASSIGN_4V(ctx->Pixel.PCCTscale, 1.0, 1.0, 1.0, 1.0);
2037 ASSIGN_4V(ctx->Pixel.PCCTbias, 0.0, 0.0, 0.0, 0.0);
2038 ASSIGN_4V(ctx->Pixel.PCMCTscale, 1.0, 1.0, 1.0, 1.0);
2039 ASSIGN_4V(ctx->Pixel.PCMCTbias, 0.0, 0.0, 0.0, 0.0);
2040 ctx->Pixel.ColorTableEnabled = GL_FALSE;
2041 ctx->Pixel.PostConvolutionColorTableEnabled = GL_FALSE;
2042 ctx->Pixel.PostColorMatrixColorTableEnabled = GL_FALSE;
2043 ctx->Pixel.Convolution1DEnabled = GL_FALSE;
2044 ctx->Pixel.Convolution2DEnabled = GL_FALSE;
2045 ctx->Pixel.Separable2DEnabled = GL_FALSE;
2046 for (i = 0; i < 3; i++) {
2047 ASSIGN_4V(ctx->Pixel.ConvolutionBorderColor[i], 0.0, 0.0, 0.0, 0.0);
2048 ctx->Pixel.ConvolutionBorderMode[i] = GL_REDUCE;
2049 ASSIGN_4V(ctx->Pixel.ConvolutionFilterScale[i], 1.0, 1.0, 1.0, 1.0);
2050 ASSIGN_4V(ctx->Pixel.ConvolutionFilterBias[i], 0.0, 0.0, 0.0, 0.0);
2051 }
2052 for (i = 0; i < MAX_CONVOLUTION_WIDTH * MAX_CONVOLUTION_WIDTH * 4; i++) {
2053 ctx->Convolution1D.Filter[i] = 0.0;
2054 ctx->Convolution2D.Filter[i] = 0.0;
2055 ctx->Separable2D.Filter[i] = 0.0;
2056 }
2057 ASSIGN_4V(ctx->Pixel.PostConvolutionScale, 1.0, 1.0, 1.0, 1.0);
2058 ASSIGN_4V(ctx->Pixel.PostConvolutionBias, 0.0, 0.0, 0.0, 0.0);
2059 /* GL_SGI_texture_color_table */
2060 ASSIGN_4V(ctx->Pixel.TextureColorTableScale, 1.0, 1.0, 1.0, 1.0);
2061 ASSIGN_4V(ctx->Pixel.TextureColorTableBias, 0.0, 0.0, 0.0, 0.0);
2062
2063 /* Pixel transfer */
2064 ctx->Pack.Alignment = 4;
2065 ctx->Pack.RowLength = 0;
2066 ctx->Pack.ImageHeight = 0;
2067 ctx->Pack.SkipPixels = 0;
2068 ctx->Pack.SkipRows = 0;
2069 ctx->Pack.SkipImages = 0;
2070 ctx->Pack.SwapBytes = GL_FALSE;
2071 ctx->Pack.LsbFirst = GL_FALSE;
2072 ctx->Pack.ClientStorage = GL_FALSE;
2073 ctx->Pack.Invert = GL_FALSE;
2074 #if FEATURE_EXT_pixel_buffer_object
2075 ctx->Pack.BufferObj = ctx->Array.NullBufferObj;
2076 #endif
2077 ctx->Unpack.Alignment = 4;
2078 ctx->Unpack.RowLength = 0;
2079 ctx->Unpack.ImageHeight = 0;
2080 ctx->Unpack.SkipPixels = 0;
2081 ctx->Unpack.SkipRows = 0;
2082 ctx->Unpack.SkipImages = 0;
2083 ctx->Unpack.SwapBytes = GL_FALSE;
2084 ctx->Unpack.LsbFirst = GL_FALSE;
2085 ctx->Unpack.ClientStorage = GL_FALSE;
2086 ctx->Unpack.Invert = GL_FALSE;
2087 #if FEATURE_EXT_pixel_buffer_object
2088 ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;
2089 #endif
2090
2091 /*
2092 * _mesa_unpack_image() returns image data in this format. When we
2093 * execute image commands (glDrawPixels(), glTexImage(), etc) from
2094 * within display lists we have to be sure to set the current
2095 * unpacking parameters to these values!
2096 */
2097 ctx->DefaultPacking.Alignment = 1;
2098 ctx->DefaultPacking.RowLength = 0;
2099 ctx->DefaultPacking.SkipPixels = 0;
2100 ctx->DefaultPacking.SkipRows = 0;
2101 ctx->DefaultPacking.ImageHeight = 0;
2102 ctx->DefaultPacking.SkipImages = 0;
2103 ctx->DefaultPacking.SwapBytes = GL_FALSE;
2104 ctx->DefaultPacking.LsbFirst = GL_FALSE;
2105 ctx->DefaultPacking.ClientStorage = GL_FALSE;
2106 ctx->DefaultPacking.Invert = GL_FALSE;
2107 #if FEATURE_EXT_pixel_buffer_object
2108 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
2109 #endif
2110
2111 if (ctx->Visual.doubleBufferMode) {
2112 ctx->Pixel.ReadBuffer = GL_BACK;
2113 ctx->Pixel._ReadSrcMask = DD_BACK_LEFT_BIT;
2114 }
2115 else {
2116 ctx->Pixel.ReadBuffer = GL_FRONT;
2117 ctx->Pixel._ReadSrcMask = DD_FRONT_LEFT_BIT;
2118 }
2119
2120 /* Miscellaneous */
2121 ctx->_ImageTransferState = 0;
2122 }