mesa: refactor: move glPixelStore function into new pixelstore.c file
[mesa.git] / src / mesa / main / pixel.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5.3
4 *
5 * Copyright (C) 1999-2007 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 void GLAPIENTRY
40 _mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor )
41 {
42 GET_CURRENT_CONTEXT(ctx);
43
44 if (ctx->Pixel.ZoomX == xfactor &&
45 ctx->Pixel.ZoomY == yfactor)
46 return;
47
48 FLUSH_VERTICES(ctx, _NEW_PIXEL);
49 ctx->Pixel.ZoomX = xfactor;
50 ctx->Pixel.ZoomY = yfactor;
51 }
52
53
54
55 /**********************************************************************/
56 /***** glPixelMap *****/
57 /**********************************************************************/
58
59 /**
60 * Return pointer to a pixelmap by name.
61 */
62 static struct gl_pixelmap *
63 get_pixelmap(GLcontext *ctx, GLenum map)
64 {
65 switch (map) {
66 case GL_PIXEL_MAP_I_TO_I:
67 return &ctx->PixelMaps.ItoI;
68 case GL_PIXEL_MAP_S_TO_S:
69 return &ctx->PixelMaps.StoS;
70 case GL_PIXEL_MAP_I_TO_R:
71 return &ctx->PixelMaps.ItoR;
72 case GL_PIXEL_MAP_I_TO_G:
73 return &ctx->PixelMaps.ItoG;
74 case GL_PIXEL_MAP_I_TO_B:
75 return &ctx->PixelMaps.ItoB;
76 case GL_PIXEL_MAP_I_TO_A:
77 return &ctx->PixelMaps.ItoA;
78 case GL_PIXEL_MAP_R_TO_R:
79 return &ctx->PixelMaps.RtoR;
80 case GL_PIXEL_MAP_G_TO_G:
81 return &ctx->PixelMaps.GtoG;
82 case GL_PIXEL_MAP_B_TO_B:
83 return &ctx->PixelMaps.BtoB;
84 case GL_PIXEL_MAP_A_TO_A:
85 return &ctx->PixelMaps.AtoA;
86 default:
87 return NULL;
88 }
89 }
90
91
92 /**
93 * Helper routine used by the other _mesa_PixelMap() functions.
94 */
95 static void
96 store_pixelmap(GLcontext *ctx, GLenum map, GLsizei mapsize,
97 const GLfloat *values)
98 {
99 GLint i;
100 struct gl_pixelmap *pm = get_pixelmap(ctx, map);
101 if (!pm) {
102 _mesa_error(ctx, GL_INVALID_ENUM, "glPixelMap(map)");
103 return;
104 }
105
106 switch (map) {
107 case GL_PIXEL_MAP_S_TO_S:
108 /* special case */
109 ctx->PixelMaps.StoS.Size = mapsize;
110 for (i = 0; i < mapsize; i++) {
111 ctx->PixelMaps.StoS.Map[i] = (GLfloat)IROUND(values[i]);
112 }
113 break;
114 case GL_PIXEL_MAP_I_TO_I:
115 /* special case */
116 ctx->PixelMaps.ItoI.Size = mapsize;
117 for (i = 0; i < mapsize; i++) {
118 ctx->PixelMaps.ItoI.Map[i] = values[i];
119 }
120 break;
121 default:
122 /* general case */
123 pm->Size = mapsize;
124 for (i = 0; i < mapsize; i++) {
125 GLfloat val = CLAMP(values[i], 0.0F, 1.0F);
126 pm->Map[i] = val;
127 pm->Map8[i] = (GLint) (val * 255.0F);
128 }
129 }
130 }
131
132
133 void GLAPIENTRY
134 _mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
135 {
136 GET_CURRENT_CONTEXT(ctx);
137 ASSERT_OUTSIDE_BEGIN_END(ctx);
138
139 /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */
140 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
141 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
142 return;
143 }
144
145 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
146 /* test that mapsize is a power of two */
147 if (_mesa_bitcount((GLuint) mapsize) != 1) {
148 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
149 return;
150 }
151 }
152
153 FLUSH_VERTICES(ctx, _NEW_PIXEL);
154
155 if (ctx->Unpack.BufferObj->Name) {
156 /* unpack pixelmap from PBO */
157 GLubyte *buf;
158 /* Note, need to use DefaultPacking and Unpack's buffer object */
159 ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
160 if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
161 GL_INTENSITY, GL_FLOAT, values)) {
162 _mesa_error(ctx, GL_INVALID_OPERATION,
163 "glPixelMapfv(invalid PBO access)");
164 return;
165 }
166 /* restore */
167 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
168 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
169 GL_READ_ONLY_ARB,
170 ctx->Unpack.BufferObj);
171 if (!buf) {
172 /* buffer is already mapped - that's an error */
173 _mesa_error(ctx, GL_INVALID_OPERATION,
174 "glPixelMapfv(PBO is mapped)");
175 return;
176 }
177 values = (const GLfloat *) ADD_POINTERS(buf, values);
178 }
179 else if (!values) {
180 return;
181 }
182
183 store_pixelmap(ctx, map, mapsize, values);
184
185 if (ctx->Unpack.BufferObj->Name) {
186 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
187 ctx->Unpack.BufferObj);
188 }
189 }
190
191
192 void GLAPIENTRY
193 _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
194 {
195 GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
196 GET_CURRENT_CONTEXT(ctx);
197 ASSERT_OUTSIDE_BEGIN_END(ctx);
198
199 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
200 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
201 return;
202 }
203
204 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
205 /* test that mapsize is a power of two */
206 if (_mesa_bitcount((GLuint) mapsize) != 1) {
207 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
208 return;
209 }
210 }
211
212 FLUSH_VERTICES(ctx, _NEW_PIXEL);
213
214 if (ctx->Unpack.BufferObj->Name) {
215 /* unpack pixelmap from PBO */
216 GLubyte *buf;
217 /* Note, need to use DefaultPacking and Unpack's buffer object */
218 ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
219 if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
220 GL_INTENSITY, GL_UNSIGNED_INT, values)) {
221 _mesa_error(ctx, GL_INVALID_OPERATION,
222 "glPixelMapuiv(invalid PBO access)");
223 return;
224 }
225 /* restore */
226 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
227 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
228 GL_READ_ONLY_ARB,
229 ctx->Unpack.BufferObj);
230 if (!buf) {
231 /* buffer is already mapped - that's an error */
232 _mesa_error(ctx, GL_INVALID_OPERATION,
233 "glPixelMapuiv(PBO is mapped)");
234 return;
235 }
236 values = (const GLuint *) ADD_POINTERS(buf, values);
237 }
238 else if (!values) {
239 return;
240 }
241
242 /* convert to floats */
243 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
244 GLint i;
245 for (i = 0; i < mapsize; i++) {
246 fvalues[i] = (GLfloat) values[i];
247 }
248 }
249 else {
250 GLint i;
251 for (i = 0; i < mapsize; i++) {
252 fvalues[i] = UINT_TO_FLOAT( values[i] );
253 }
254 }
255
256 if (ctx->Unpack.BufferObj->Name) {
257 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
258 ctx->Unpack.BufferObj);
259 }
260
261 store_pixelmap(ctx, map, mapsize, fvalues);
262 }
263
264
265 void GLAPIENTRY
266 _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
267 {
268 GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
269 GET_CURRENT_CONTEXT(ctx);
270 ASSERT_OUTSIDE_BEGIN_END(ctx);
271
272 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
273 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" );
274 return;
275 }
276
277 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
278 /* test that mapsize is a power of two */
279 if (_mesa_bitcount((GLuint) mapsize) != 1) {
280 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
281 return;
282 }
283 }
284
285 FLUSH_VERTICES(ctx, _NEW_PIXEL);
286
287 if (ctx->Unpack.BufferObj->Name) {
288 /* unpack pixelmap from PBO */
289 GLubyte *buf;
290 /* Note, need to use DefaultPacking and Unpack's buffer object */
291 ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
292 if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
293 GL_INTENSITY, GL_UNSIGNED_SHORT,
294 values)) {
295 _mesa_error(ctx, GL_INVALID_OPERATION,
296 "glPixelMapusv(invalid PBO access)");
297 return;
298 }
299 /* restore */
300 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
301 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
302 GL_READ_ONLY_ARB,
303 ctx->Unpack.BufferObj);
304 if (!buf) {
305 /* buffer is already mapped - that's an error */
306 _mesa_error(ctx, GL_INVALID_OPERATION,
307 "glPixelMapusv(PBO is mapped)");
308 return;
309 }
310 values = (const GLushort *) ADD_POINTERS(buf, values);
311 }
312 else if (!values) {
313 return;
314 }
315
316 /* convert to floats */
317 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
318 GLint i;
319 for (i = 0; i < mapsize; i++) {
320 fvalues[i] = (GLfloat) values[i];
321 }
322 }
323 else {
324 GLint i;
325 for (i = 0; i < mapsize; i++) {
326 fvalues[i] = USHORT_TO_FLOAT( values[i] );
327 }
328 }
329
330 if (ctx->Unpack.BufferObj->Name) {
331 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
332 ctx->Unpack.BufferObj);
333 }
334
335 store_pixelmap(ctx, map, mapsize, fvalues);
336 }
337
338
339 void GLAPIENTRY
340 _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
341 {
342 GET_CURRENT_CONTEXT(ctx);
343 GLuint mapsize, i;
344 const struct gl_pixelmap *pm;
345
346 ASSERT_OUTSIDE_BEGIN_END(ctx);
347
348 pm = get_pixelmap(ctx, map);
349 if (!pm) {
350 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapfv(map)");
351 return;
352 }
353
354 mapsize = pm->Size;
355
356 if (ctx->Pack.BufferObj->Name) {
357 /* pack pixelmap into PBO */
358 GLubyte *buf;
359 /* Note, need to use DefaultPacking and Pack's buffer object */
360 ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
361 if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
362 GL_INTENSITY, GL_FLOAT, values)) {
363 _mesa_error(ctx, GL_INVALID_OPERATION,
364 "glGetPixelMapfv(invalid PBO access)");
365 return;
366 }
367 /* restore */
368 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
369 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
370 GL_WRITE_ONLY_ARB,
371 ctx->Pack.BufferObj);
372 if (!buf) {
373 /* buffer is already mapped - that's an error */
374 _mesa_error(ctx, GL_INVALID_OPERATION,
375 "glGetPixelMapfv(PBO is mapped)");
376 return;
377 }
378 values = (GLfloat *) ADD_POINTERS(buf, values);
379 }
380 else if (!values) {
381 return;
382 }
383
384 if (map == GL_PIXEL_MAP_S_TO_S) {
385 /* special case */
386 for (i = 0; i < mapsize; i++) {
387 values[i] = (GLfloat) ctx->PixelMaps.StoS.Map[i];
388 }
389 }
390 else {
391 MEMCPY(values, pm->Map, mapsize * sizeof(GLfloat));
392 }
393
394 if (ctx->Pack.BufferObj->Name) {
395 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
396 ctx->Pack.BufferObj);
397 }
398 }
399
400
401 void GLAPIENTRY
402 _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
403 {
404 GET_CURRENT_CONTEXT(ctx);
405 GLint mapsize, i;
406 const struct gl_pixelmap *pm;
407
408 ASSERT_OUTSIDE_BEGIN_END(ctx);
409
410 pm = get_pixelmap(ctx, map);
411 if (!pm) {
412 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapuiv(map)");
413 return;
414 }
415 mapsize = pm->Size;
416
417 if (ctx->Pack.BufferObj->Name) {
418 /* pack pixelmap into PBO */
419 GLubyte *buf;
420 /* Note, need to use DefaultPacking and Pack's buffer object */
421 ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
422 if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
423 GL_INTENSITY, GL_UNSIGNED_INT, values)) {
424 _mesa_error(ctx, GL_INVALID_OPERATION,
425 "glGetPixelMapuiv(invalid PBO access)");
426 return;
427 }
428 /* restore */
429 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
430 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
431 GL_WRITE_ONLY_ARB,
432 ctx->Pack.BufferObj);
433 if (!buf) {
434 /* buffer is already mapped - that's an error */
435 _mesa_error(ctx, GL_INVALID_OPERATION,
436 "glGetPixelMapuiv(PBO is mapped)");
437 return;
438 }
439 values = (GLuint *) ADD_POINTERS(buf, values);
440 }
441 else if (!values) {
442 return;
443 }
444
445 if (map == GL_PIXEL_MAP_S_TO_S) {
446 /* special case */
447 MEMCPY(values, ctx->PixelMaps.StoS.Map, mapsize * sizeof(GLint));
448 }
449 else {
450 for (i = 0; i < mapsize; i++) {
451 values[i] = FLOAT_TO_UINT( pm->Map[i] );
452 }
453 }
454
455 if (ctx->Pack.BufferObj->Name) {
456 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
457 ctx->Pack.BufferObj);
458 }
459 }
460
461
462 void GLAPIENTRY
463 _mesa_GetPixelMapusv( GLenum map, GLushort *values )
464 {
465 GET_CURRENT_CONTEXT(ctx);
466 GLint mapsize, i;
467 const struct gl_pixelmap *pm;
468
469 ASSERT_OUTSIDE_BEGIN_END(ctx);
470
471 pm = get_pixelmap(ctx, map);
472 if (!pm) {
473 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapusv(map)");
474 return;
475 }
476 mapsize = pm ? pm->Size : 0;
477
478 if (ctx->Pack.BufferObj->Name) {
479 /* pack pixelmap into PBO */
480 GLubyte *buf;
481 /* Note, need to use DefaultPacking and Pack's buffer object */
482 ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
483 if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
484 GL_INTENSITY, GL_UNSIGNED_SHORT,
485 values)) {
486 _mesa_error(ctx, GL_INVALID_OPERATION,
487 "glGetPixelMapusv(invalid PBO access)");
488 return;
489 }
490 /* restore */
491 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
492 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
493 GL_WRITE_ONLY_ARB,
494 ctx->Pack.BufferObj);
495 if (!buf) {
496 /* buffer is already mapped - that's an error */
497 _mesa_error(ctx, GL_INVALID_OPERATION,
498 "glGetPixelMapusv(PBO is mapped)");
499 return;
500 }
501 values = (GLushort *) ADD_POINTERS(buf, values);
502 }
503 else if (!values) {
504 return;
505 }
506
507 switch (map) {
508 /* special cases */
509 case GL_PIXEL_MAP_I_TO_I:
510 for (i = 0; i < mapsize; i++) {
511 values[i] = (GLushort) CLAMP(ctx->PixelMaps.ItoI.Map[i], 0.0, 65535.);
512 }
513 break;
514 case GL_PIXEL_MAP_S_TO_S:
515 for (i = 0; i < mapsize; i++) {
516 values[i] = (GLushort) CLAMP(ctx->PixelMaps.StoS.Map[i], 0.0, 65535.);
517 }
518 break;
519 default:
520 for (i = 0; i < mapsize; i++) {
521 CLAMPED_FLOAT_TO_USHORT(values[i], pm->Map[i] );
522 }
523 }
524
525 if (ctx->Pack.BufferObj->Name) {
526 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
527 ctx->Pack.BufferObj);
528 }
529 }
530
531
532
533 /**********************************************************************/
534 /***** glPixelTransfer *****/
535 /**********************************************************************/
536
537
538 /*
539 * Implements glPixelTransfer[fi] whether called immediately or from a
540 * display list.
541 */
542 void GLAPIENTRY
543 _mesa_PixelTransferf( GLenum pname, GLfloat param )
544 {
545 GET_CURRENT_CONTEXT(ctx);
546 ASSERT_OUTSIDE_BEGIN_END(ctx);
547
548 switch (pname) {
549 case GL_MAP_COLOR:
550 if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE))
551 return;
552 FLUSH_VERTICES(ctx, _NEW_PIXEL);
553 ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
554 break;
555 case GL_MAP_STENCIL:
556 if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE))
557 return;
558 FLUSH_VERTICES(ctx, _NEW_PIXEL);
559 ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
560 break;
561 case GL_INDEX_SHIFT:
562 if (ctx->Pixel.IndexShift == (GLint) param)
563 return;
564 FLUSH_VERTICES(ctx, _NEW_PIXEL);
565 ctx->Pixel.IndexShift = (GLint) param;
566 break;
567 case GL_INDEX_OFFSET:
568 if (ctx->Pixel.IndexOffset == (GLint) param)
569 return;
570 FLUSH_VERTICES(ctx, _NEW_PIXEL);
571 ctx->Pixel.IndexOffset = (GLint) param;
572 break;
573 case GL_RED_SCALE:
574 if (ctx->Pixel.RedScale == param)
575 return;
576 FLUSH_VERTICES(ctx, _NEW_PIXEL);
577 ctx->Pixel.RedScale = param;
578 break;
579 case GL_RED_BIAS:
580 if (ctx->Pixel.RedBias == param)
581 return;
582 FLUSH_VERTICES(ctx, _NEW_PIXEL);
583 ctx->Pixel.RedBias = param;
584 break;
585 case GL_GREEN_SCALE:
586 if (ctx->Pixel.GreenScale == param)
587 return;
588 FLUSH_VERTICES(ctx, _NEW_PIXEL);
589 ctx->Pixel.GreenScale = param;
590 break;
591 case GL_GREEN_BIAS:
592 if (ctx->Pixel.GreenBias == param)
593 return;
594 FLUSH_VERTICES(ctx, _NEW_PIXEL);
595 ctx->Pixel.GreenBias = param;
596 break;
597 case GL_BLUE_SCALE:
598 if (ctx->Pixel.BlueScale == param)
599 return;
600 FLUSH_VERTICES(ctx, _NEW_PIXEL);
601 ctx->Pixel.BlueScale = param;
602 break;
603 case GL_BLUE_BIAS:
604 if (ctx->Pixel.BlueBias == param)
605 return;
606 FLUSH_VERTICES(ctx, _NEW_PIXEL);
607 ctx->Pixel.BlueBias = param;
608 break;
609 case GL_ALPHA_SCALE:
610 if (ctx->Pixel.AlphaScale == param)
611 return;
612 FLUSH_VERTICES(ctx, _NEW_PIXEL);
613 ctx->Pixel.AlphaScale = param;
614 break;
615 case GL_ALPHA_BIAS:
616 if (ctx->Pixel.AlphaBias == param)
617 return;
618 FLUSH_VERTICES(ctx, _NEW_PIXEL);
619 ctx->Pixel.AlphaBias = param;
620 break;
621 case GL_DEPTH_SCALE:
622 if (ctx->Pixel.DepthScale == param)
623 return;
624 FLUSH_VERTICES(ctx, _NEW_PIXEL);
625 ctx->Pixel.DepthScale = param;
626 break;
627 case GL_DEPTH_BIAS:
628 if (ctx->Pixel.DepthBias == param)
629 return;
630 FLUSH_VERTICES(ctx, _NEW_PIXEL);
631 ctx->Pixel.DepthBias = param;
632 break;
633 case GL_POST_COLOR_MATRIX_RED_SCALE:
634 if (ctx->Pixel.PostColorMatrixScale[0] == param)
635 return;
636 FLUSH_VERTICES(ctx, _NEW_PIXEL);
637 ctx->Pixel.PostColorMatrixScale[0] = param;
638 break;
639 case GL_POST_COLOR_MATRIX_RED_BIAS:
640 if (ctx->Pixel.PostColorMatrixBias[0] == param)
641 return;
642 FLUSH_VERTICES(ctx, _NEW_PIXEL);
643 ctx->Pixel.PostColorMatrixBias[0] = param;
644 break;
645 case GL_POST_COLOR_MATRIX_GREEN_SCALE:
646 if (ctx->Pixel.PostColorMatrixScale[1] == param)
647 return;
648 FLUSH_VERTICES(ctx, _NEW_PIXEL);
649 ctx->Pixel.PostColorMatrixScale[1] = param;
650 break;
651 case GL_POST_COLOR_MATRIX_GREEN_BIAS:
652 if (ctx->Pixel.PostColorMatrixBias[1] == param)
653 return;
654 FLUSH_VERTICES(ctx, _NEW_PIXEL);
655 ctx->Pixel.PostColorMatrixBias[1] = param;
656 break;
657 case GL_POST_COLOR_MATRIX_BLUE_SCALE:
658 if (ctx->Pixel.PostColorMatrixScale[2] == param)
659 return;
660 FLUSH_VERTICES(ctx, _NEW_PIXEL);
661 ctx->Pixel.PostColorMatrixScale[2] = param;
662 break;
663 case GL_POST_COLOR_MATRIX_BLUE_BIAS:
664 if (ctx->Pixel.PostColorMatrixBias[2] == param)
665 return;
666 FLUSH_VERTICES(ctx, _NEW_PIXEL);
667 ctx->Pixel.PostColorMatrixBias[2] = param;
668 break;
669 case GL_POST_COLOR_MATRIX_ALPHA_SCALE:
670 if (ctx->Pixel.PostColorMatrixScale[3] == param)
671 return;
672 FLUSH_VERTICES(ctx, _NEW_PIXEL);
673 ctx->Pixel.PostColorMatrixScale[3] = param;
674 break;
675 case GL_POST_COLOR_MATRIX_ALPHA_BIAS:
676 if (ctx->Pixel.PostColorMatrixBias[3] == param)
677 return;
678 FLUSH_VERTICES(ctx, _NEW_PIXEL);
679 ctx->Pixel.PostColorMatrixBias[3] = param;
680 break;
681 case GL_POST_CONVOLUTION_RED_SCALE:
682 if (ctx->Pixel.PostConvolutionScale[0] == param)
683 return;
684 FLUSH_VERTICES(ctx, _NEW_PIXEL);
685 ctx->Pixel.PostConvolutionScale[0] = param;
686 break;
687 case GL_POST_CONVOLUTION_RED_BIAS:
688 if (ctx->Pixel.PostConvolutionBias[0] == param)
689 return;
690 FLUSH_VERTICES(ctx, _NEW_PIXEL);
691 ctx->Pixel.PostConvolutionBias[0] = param;
692 break;
693 case GL_POST_CONVOLUTION_GREEN_SCALE:
694 if (ctx->Pixel.PostConvolutionScale[1] == param)
695 return;
696 FLUSH_VERTICES(ctx, _NEW_PIXEL);
697 ctx->Pixel.PostConvolutionScale[1] = param;
698 break;
699 case GL_POST_CONVOLUTION_GREEN_BIAS:
700 if (ctx->Pixel.PostConvolutionBias[1] == param)
701 return;
702 FLUSH_VERTICES(ctx, _NEW_PIXEL);
703 ctx->Pixel.PostConvolutionBias[1] = param;
704 break;
705 case GL_POST_CONVOLUTION_BLUE_SCALE:
706 if (ctx->Pixel.PostConvolutionScale[2] == param)
707 return;
708 FLUSH_VERTICES(ctx, _NEW_PIXEL);
709 ctx->Pixel.PostConvolutionScale[2] = param;
710 break;
711 case GL_POST_CONVOLUTION_BLUE_BIAS:
712 if (ctx->Pixel.PostConvolutionBias[2] == param)
713 return;
714 FLUSH_VERTICES(ctx, _NEW_PIXEL);
715 ctx->Pixel.PostConvolutionBias[2] = param;
716 break;
717 case GL_POST_CONVOLUTION_ALPHA_SCALE:
718 if (ctx->Pixel.PostConvolutionScale[3] == param)
719 return;
720 FLUSH_VERTICES(ctx, _NEW_PIXEL);
721 ctx->Pixel.PostConvolutionScale[3] = param;
722 break;
723 case GL_POST_CONVOLUTION_ALPHA_BIAS:
724 if (ctx->Pixel.PostConvolutionBias[3] == param)
725 return;
726 FLUSH_VERTICES(ctx, _NEW_PIXEL);
727 ctx->Pixel.PostConvolutionBias[3] = param;
728 break;
729 default:
730 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
731 return;
732 }
733 }
734
735
736 void GLAPIENTRY
737 _mesa_PixelTransferi( GLenum pname, GLint param )
738 {
739 _mesa_PixelTransferf( pname, (GLfloat) param );
740 }
741
742
743
744 /**********************************************************************/
745 /***** Pixel processing functions ******/
746 /**********************************************************************/
747
748 /*
749 * Apply scale and bias factors to an array of RGBA pixels.
750 */
751 void
752 _mesa_scale_and_bias_rgba(GLuint n, GLfloat rgba[][4],
753 GLfloat rScale, GLfloat gScale,
754 GLfloat bScale, GLfloat aScale,
755 GLfloat rBias, GLfloat gBias,
756 GLfloat bBias, GLfloat aBias)
757 {
758 if (rScale != 1.0 || rBias != 0.0) {
759 GLuint i;
760 for (i = 0; i < n; i++) {
761 rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias;
762 }
763 }
764 if (gScale != 1.0 || gBias != 0.0) {
765 GLuint i;
766 for (i = 0; i < n; i++) {
767 rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias;
768 }
769 }
770 if (bScale != 1.0 || bBias != 0.0) {
771 GLuint i;
772 for (i = 0; i < n; i++) {
773 rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias;
774 }
775 }
776 if (aScale != 1.0 || aBias != 0.0) {
777 GLuint i;
778 for (i = 0; i < n; i++) {
779 rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias;
780 }
781 }
782 }
783
784
785 /*
786 * Apply pixel mapping to an array of floating point RGBA pixels.
787 */
788 void
789 _mesa_map_rgba( const GLcontext *ctx, GLuint n, GLfloat rgba[][4] )
790 {
791 const GLfloat rscale = (GLfloat) (ctx->PixelMaps.RtoR.Size - 1);
792 const GLfloat gscale = (GLfloat) (ctx->PixelMaps.GtoG.Size - 1);
793 const GLfloat bscale = (GLfloat) (ctx->PixelMaps.BtoB.Size - 1);
794 const GLfloat ascale = (GLfloat) (ctx->PixelMaps.AtoA.Size - 1);
795 const GLfloat *rMap = ctx->PixelMaps.RtoR.Map;
796 const GLfloat *gMap = ctx->PixelMaps.GtoG.Map;
797 const GLfloat *bMap = ctx->PixelMaps.BtoB.Map;
798 const GLfloat *aMap = ctx->PixelMaps.AtoA.Map;
799 GLuint i;
800 for (i=0;i<n;i++) {
801 GLfloat r = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
802 GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
803 GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
804 GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
805 rgba[i][RCOMP] = rMap[IROUND(r * rscale)];
806 rgba[i][GCOMP] = gMap[IROUND(g * gscale)];
807 rgba[i][BCOMP] = bMap[IROUND(b * bscale)];
808 rgba[i][ACOMP] = aMap[IROUND(a * ascale)];
809 }
810 }
811
812
813 /*
814 * Apply the color matrix and post color matrix scaling and biasing.
815 */
816 void
817 _mesa_transform_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4])
818 {
819 const GLfloat rs = ctx->Pixel.PostColorMatrixScale[0];
820 const GLfloat rb = ctx->Pixel.PostColorMatrixBias[0];
821 const GLfloat gs = ctx->Pixel.PostColorMatrixScale[1];
822 const GLfloat gb = ctx->Pixel.PostColorMatrixBias[1];
823 const GLfloat bs = ctx->Pixel.PostColorMatrixScale[2];
824 const GLfloat bb = ctx->Pixel.PostColorMatrixBias[2];
825 const GLfloat as = ctx->Pixel.PostColorMatrixScale[3];
826 const GLfloat ab = ctx->Pixel.PostColorMatrixBias[3];
827 const GLfloat *m = ctx->ColorMatrixStack.Top->m;
828 GLuint i;
829 for (i = 0; i < n; i++) {
830 const GLfloat r = rgba[i][RCOMP];
831 const GLfloat g = rgba[i][GCOMP];
832 const GLfloat b = rgba[i][BCOMP];
833 const GLfloat a = rgba[i][ACOMP];
834 rgba[i][RCOMP] = (m[0] * r + m[4] * g + m[ 8] * b + m[12] * a) * rs + rb;
835 rgba[i][GCOMP] = (m[1] * r + m[5] * g + m[ 9] * b + m[13] * a) * gs + gb;
836 rgba[i][BCOMP] = (m[2] * r + m[6] * g + m[10] * b + m[14] * a) * bs + bb;
837 rgba[i][ACOMP] = (m[3] * r + m[7] * g + m[11] * b + m[15] * a) * as + ab;
838 }
839 }
840
841
842 /**
843 * Apply a color table lookup to an array of floating point RGBA colors.
844 */
845 void
846 _mesa_lookup_rgba_float(const struct gl_color_table *table,
847 GLuint n, GLfloat rgba[][4])
848 {
849 const GLint max = table->Size - 1;
850 const GLfloat scale = (GLfloat) max;
851 const GLfloat *lut = table->TableF;
852 GLuint i;
853
854 if (!table->TableF || table->Size == 0)
855 return;
856
857 switch (table->_BaseFormat) {
858 case GL_INTENSITY:
859 /* replace RGBA with I */
860 for (i = 0; i < n; i++) {
861 GLint j = IROUND(rgba[i][RCOMP] * scale);
862 GLfloat c = lut[CLAMP(j, 0, max)];
863 rgba[i][RCOMP] =
864 rgba[i][GCOMP] =
865 rgba[i][BCOMP] =
866 rgba[i][ACOMP] = c;
867 }
868 break;
869 case GL_LUMINANCE:
870 /* replace RGB with L */
871 for (i = 0; i < n; i++) {
872 GLint j = IROUND(rgba[i][RCOMP] * scale);
873 GLfloat c = lut[CLAMP(j, 0, max)];
874 rgba[i][RCOMP] =
875 rgba[i][GCOMP] =
876 rgba[i][BCOMP] = c;
877 }
878 break;
879 case GL_ALPHA:
880 /* replace A with A */
881 for (i = 0; i < n; i++) {
882 GLint j = IROUND(rgba[i][ACOMP] * scale);
883 rgba[i][ACOMP] = lut[CLAMP(j, 0, max)];
884 }
885 break;
886 case GL_LUMINANCE_ALPHA:
887 /* replace RGBA with LLLA */
888 for (i = 0; i < n; i++) {
889 GLint jL = IROUND(rgba[i][RCOMP] * scale);
890 GLint jA = IROUND(rgba[i][ACOMP] * scale);
891 GLfloat luminance, alpha;
892 jL = CLAMP(jL, 0, max);
893 jA = CLAMP(jA, 0, max);
894 luminance = lut[jL * 2 + 0];
895 alpha = lut[jA * 2 + 1];
896 rgba[i][RCOMP] =
897 rgba[i][GCOMP] =
898 rgba[i][BCOMP] = luminance;
899 rgba[i][ACOMP] = alpha;;
900 }
901 break;
902 case GL_RGB:
903 /* replace RGB with RGB */
904 for (i = 0; i < n; i++) {
905 GLint jR = IROUND(rgba[i][RCOMP] * scale);
906 GLint jG = IROUND(rgba[i][GCOMP] * scale);
907 GLint jB = IROUND(rgba[i][BCOMP] * scale);
908 jR = CLAMP(jR, 0, max);
909 jG = CLAMP(jG, 0, max);
910 jB = CLAMP(jB, 0, max);
911 rgba[i][RCOMP] = lut[jR * 3 + 0];
912 rgba[i][GCOMP] = lut[jG * 3 + 1];
913 rgba[i][BCOMP] = lut[jB * 3 + 2];
914 }
915 break;
916 case GL_RGBA:
917 /* replace RGBA with RGBA */
918 for (i = 0; i < n; i++) {
919 GLint jR = IROUND(rgba[i][RCOMP] * scale);
920 GLint jG = IROUND(rgba[i][GCOMP] * scale);
921 GLint jB = IROUND(rgba[i][BCOMP] * scale);
922 GLint jA = IROUND(rgba[i][ACOMP] * scale);
923 jR = CLAMP(jR, 0, max);
924 jG = CLAMP(jG, 0, max);
925 jB = CLAMP(jB, 0, max);
926 jA = CLAMP(jA, 0, max);
927 rgba[i][RCOMP] = lut[jR * 4 + 0];
928 rgba[i][GCOMP] = lut[jG * 4 + 1];
929 rgba[i][BCOMP] = lut[jB * 4 + 2];
930 rgba[i][ACOMP] = lut[jA * 4 + 3];
931 }
932 break;
933 default:
934 _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_float");
935 return;
936 }
937 }
938
939
940
941 /**
942 * Apply a color table lookup to an array of ubyte/RGBA colors.
943 */
944 void
945 _mesa_lookup_rgba_ubyte(const struct gl_color_table *table,
946 GLuint n, GLubyte rgba[][4])
947 {
948 const GLubyte *lut = table->TableUB;
949 const GLfloat scale = (GLfloat) (table->Size - 1) / (GLfloat)255.0;
950 GLuint i;
951
952 if (!table->TableUB || table->Size == 0)
953 return;
954
955 switch (table->_BaseFormat) {
956 case GL_INTENSITY:
957 /* replace RGBA with I */
958 if (table->Size == 256) {
959 for (i = 0; i < n; i++) {
960 const GLubyte c = lut[rgba[i][RCOMP]];
961 rgba[i][RCOMP] =
962 rgba[i][GCOMP] =
963 rgba[i][BCOMP] =
964 rgba[i][ACOMP] = c;
965 }
966 }
967 else {
968 for (i = 0; i < n; i++) {
969 GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
970 rgba[i][RCOMP] =
971 rgba[i][GCOMP] =
972 rgba[i][BCOMP] =
973 rgba[i][ACOMP] = lut[j];
974 }
975 }
976 break;
977 case GL_LUMINANCE:
978 /* replace RGB with L */
979 if (table->Size == 256) {
980 for (i = 0; i < n; i++) {
981 const GLubyte c = lut[rgba[i][RCOMP]];
982 rgba[i][RCOMP] =
983 rgba[i][GCOMP] =
984 rgba[i][BCOMP] = c;
985 }
986 }
987 else {
988 for (i = 0; i < n; i++) {
989 GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
990 rgba[i][RCOMP] =
991 rgba[i][GCOMP] =
992 rgba[i][BCOMP] = lut[j];
993 }
994 }
995 break;
996 case GL_ALPHA:
997 /* replace A with A */
998 if (table->Size == 256) {
999 for (i = 0; i < n; i++) {
1000 rgba[i][ACOMP] = lut[rgba[i][ACOMP]];
1001 }
1002 }
1003 else {
1004 for (i = 0; i < n; i++) {
1005 GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1006 rgba[i][ACOMP] = lut[j];
1007 }
1008 }
1009 break;
1010 case GL_LUMINANCE_ALPHA:
1011 /* replace RGBA with LLLA */
1012 if (table->Size == 256) {
1013 for (i = 0; i < n; i++) {
1014 GLubyte l = lut[rgba[i][RCOMP] * 2 + 0];
1015 GLubyte a = lut[rgba[i][ACOMP] * 2 + 1];;
1016 rgba[i][RCOMP] =
1017 rgba[i][GCOMP] =
1018 rgba[i][BCOMP] = l;
1019 rgba[i][ACOMP] = a;
1020 }
1021 }
1022 else {
1023 for (i = 0; i < n; i++) {
1024 GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1025 GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1026 GLubyte luminance = lut[jL * 2 + 0];
1027 GLubyte alpha = lut[jA * 2 + 1];
1028 rgba[i][RCOMP] =
1029 rgba[i][GCOMP] =
1030 rgba[i][BCOMP] = luminance;
1031 rgba[i][ACOMP] = alpha;
1032 }
1033 }
1034 break;
1035 case GL_RGB:
1036 if (table->Size == 256) {
1037 for (i = 0; i < n; i++) {
1038 rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 3 + 0];
1039 rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 3 + 1];
1040 rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 3 + 2];
1041 }
1042 }
1043 else {
1044 for (i = 0; i < n; i++) {
1045 GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1046 GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1047 GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1048 rgba[i][RCOMP] = lut[jR * 3 + 0];
1049 rgba[i][GCOMP] = lut[jG * 3 + 1];
1050 rgba[i][BCOMP] = lut[jB * 3 + 2];
1051 }
1052 }
1053 break;
1054 case GL_RGBA:
1055 if (table->Size == 256) {
1056 for (i = 0; i < n; i++) {
1057 rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 4 + 0];
1058 rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 4 + 1];
1059 rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 4 + 2];
1060 rgba[i][ACOMP] = lut[rgba[i][ACOMP] * 4 + 3];
1061 }
1062 }
1063 else {
1064 for (i = 0; i < n; i++) {
1065 GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1066 GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1067 GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1068 GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1069 CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]);
1070 CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]);
1071 CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]);
1072 CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]);
1073 }
1074 }
1075 break;
1076 default:
1077 _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_chan");
1078 return;
1079 }
1080 }
1081
1082
1083
1084 /*
1085 * Map color indexes to float rgba values.
1086 */
1087 void
1088 _mesa_map_ci_to_rgba( const GLcontext *ctx, GLuint n,
1089 const GLuint index[], GLfloat rgba[][4] )
1090 {
1091 GLuint rmask = ctx->PixelMaps.ItoR.Size - 1;
1092 GLuint gmask = ctx->PixelMaps.ItoG.Size - 1;
1093 GLuint bmask = ctx->PixelMaps.ItoB.Size - 1;
1094 GLuint amask = ctx->PixelMaps.ItoA.Size - 1;
1095 const GLfloat *rMap = ctx->PixelMaps.ItoR.Map;
1096 const GLfloat *gMap = ctx->PixelMaps.ItoG.Map;
1097 const GLfloat *bMap = ctx->PixelMaps.ItoB.Map;
1098 const GLfloat *aMap = ctx->PixelMaps.ItoA.Map;
1099 GLuint i;
1100 for (i=0;i<n;i++) {
1101 rgba[i][RCOMP] = rMap[index[i] & rmask];
1102 rgba[i][GCOMP] = gMap[index[i] & gmask];
1103 rgba[i][BCOMP] = bMap[index[i] & bmask];
1104 rgba[i][ACOMP] = aMap[index[i] & amask];
1105 }
1106 }
1107
1108
1109 /**
1110 * Map ubyte color indexes to ubyte/RGBA values.
1111 */
1112 void
1113 _mesa_map_ci8_to_rgba8(const GLcontext *ctx, GLuint n, const GLubyte index[],
1114 GLubyte rgba[][4])
1115 {
1116 GLuint rmask = ctx->PixelMaps.ItoR.Size - 1;
1117 GLuint gmask = ctx->PixelMaps.ItoG.Size - 1;
1118 GLuint bmask = ctx->PixelMaps.ItoB.Size - 1;
1119 GLuint amask = ctx->PixelMaps.ItoA.Size - 1;
1120 const GLubyte *rMap = ctx->PixelMaps.ItoR.Map8;
1121 const GLubyte *gMap = ctx->PixelMaps.ItoG.Map8;
1122 const GLubyte *bMap = ctx->PixelMaps.ItoB.Map8;
1123 const GLubyte *aMap = ctx->PixelMaps.ItoA.Map8;
1124 GLuint i;
1125 for (i=0;i<n;i++) {
1126 rgba[i][RCOMP] = rMap[index[i] & rmask];
1127 rgba[i][GCOMP] = gMap[index[i] & gmask];
1128 rgba[i][BCOMP] = bMap[index[i] & bmask];
1129 rgba[i][ACOMP] = aMap[index[i] & amask];
1130 }
1131 }
1132
1133
1134 void
1135 _mesa_scale_and_bias_depth(const GLcontext *ctx, GLuint n,
1136 GLfloat depthValues[])
1137 {
1138 const GLfloat scale = ctx->Pixel.DepthScale;
1139 const GLfloat bias = ctx->Pixel.DepthBias;
1140 GLuint i;
1141 for (i = 0; i < n; i++) {
1142 GLfloat d = depthValues[i] * scale + bias;
1143 depthValues[i] = CLAMP(d, 0.0F, 1.0F);
1144 }
1145 }
1146
1147
1148 void
1149 _mesa_scale_and_bias_depth_uint(const GLcontext *ctx, GLuint n,
1150 GLuint depthValues[])
1151 {
1152 const GLdouble max = (double) 0xffffffff;
1153 const GLdouble scale = ctx->Pixel.DepthScale;
1154 const GLdouble bias = ctx->Pixel.DepthBias * max;
1155 GLuint i;
1156 for (i = 0; i < n; i++) {
1157 GLdouble d = (GLdouble) depthValues[i] * scale + bias;
1158 d = CLAMP(d, 0.0, max);
1159 depthValues[i] = (GLuint) d;
1160 }
1161 }
1162
1163
1164 /**********************************************************************/
1165 /***** State Management *****/
1166 /**********************************************************************/
1167
1168 /*
1169 * Return a bitmask of IMAGE_*_BIT flags which to indicate which
1170 * pixel transfer operations are enabled.
1171 */
1172 static void
1173 update_image_transfer_state(GLcontext *ctx)
1174 {
1175 GLuint mask = 0;
1176
1177 if (ctx->Pixel.RedScale != 1.0F || ctx->Pixel.RedBias != 0.0F ||
1178 ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F ||
1179 ctx->Pixel.BlueScale != 1.0F || ctx->Pixel.BlueBias != 0.0F ||
1180 ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F)
1181 mask |= IMAGE_SCALE_BIAS_BIT;
1182
1183 if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset)
1184 mask |= IMAGE_SHIFT_OFFSET_BIT;
1185
1186 if (ctx->Pixel.MapColorFlag)
1187 mask |= IMAGE_MAP_COLOR_BIT;
1188
1189 if (ctx->Pixel.ColorTableEnabled[COLORTABLE_PRECONVOLUTION])
1190 mask |= IMAGE_COLOR_TABLE_BIT;
1191
1192 if (ctx->Pixel.Convolution1DEnabled ||
1193 ctx->Pixel.Convolution2DEnabled ||
1194 ctx->Pixel.Separable2DEnabled) {
1195 mask |= IMAGE_CONVOLUTION_BIT;
1196 if (ctx->Pixel.PostConvolutionScale[0] != 1.0F ||
1197 ctx->Pixel.PostConvolutionScale[1] != 1.0F ||
1198 ctx->Pixel.PostConvolutionScale[2] != 1.0F ||
1199 ctx->Pixel.PostConvolutionScale[3] != 1.0F ||
1200 ctx->Pixel.PostConvolutionBias[0] != 0.0F ||
1201 ctx->Pixel.PostConvolutionBias[1] != 0.0F ||
1202 ctx->Pixel.PostConvolutionBias[2] != 0.0F ||
1203 ctx->Pixel.PostConvolutionBias[3] != 0.0F) {
1204 mask |= IMAGE_POST_CONVOLUTION_SCALE_BIAS;
1205 }
1206 }
1207
1208 if (ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCONVOLUTION])
1209 mask |= IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT;
1210
1211 if (ctx->ColorMatrixStack.Top->type != MATRIX_IDENTITY ||
1212 ctx->Pixel.PostColorMatrixScale[0] != 1.0F ||
1213 ctx->Pixel.PostColorMatrixBias[0] != 0.0F ||
1214 ctx->Pixel.PostColorMatrixScale[1] != 1.0F ||
1215 ctx->Pixel.PostColorMatrixBias[1] != 0.0F ||
1216 ctx->Pixel.PostColorMatrixScale[2] != 1.0F ||
1217 ctx->Pixel.PostColorMatrixBias[2] != 0.0F ||
1218 ctx->Pixel.PostColorMatrixScale[3] != 1.0F ||
1219 ctx->Pixel.PostColorMatrixBias[3] != 0.0F)
1220 mask |= IMAGE_COLOR_MATRIX_BIT;
1221
1222 if (ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCOLORMATRIX])
1223 mask |= IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT;
1224
1225 if (ctx->Pixel.HistogramEnabled)
1226 mask |= IMAGE_HISTOGRAM_BIT;
1227
1228 if (ctx->Pixel.MinMaxEnabled)
1229 mask |= IMAGE_MIN_MAX_BIT;
1230
1231 ctx->_ImageTransferState = mask;
1232 }
1233
1234
1235 void _mesa_update_pixel( GLcontext *ctx, GLuint new_state )
1236 {
1237 if (new_state & _NEW_COLOR_MATRIX)
1238 _math_matrix_analyse( ctx->ColorMatrixStack.Top );
1239
1240 /* References ColorMatrix.type (derived above).
1241 */
1242 if (new_state & _IMAGE_NEW_TRANSFER_STATE)
1243 update_image_transfer_state(ctx);
1244 }
1245
1246
1247 /**********************************************************************/
1248 /***** Initialization *****/
1249 /**********************************************************************/
1250
1251 static void
1252 init_pixelmap(struct gl_pixelmap *map)
1253 {
1254 map->Size = 1;
1255 map->Map[0] = 0.0;
1256 map->Map8[0] = 0;
1257 }
1258
1259
1260 /**
1261 * Initialize the context's PIXEL attribute group.
1262 */
1263 void
1264 _mesa_init_pixel( GLcontext *ctx )
1265 {
1266 int i;
1267
1268 /* Pixel group */
1269 ctx->Pixel.RedBias = 0.0;
1270 ctx->Pixel.RedScale = 1.0;
1271 ctx->Pixel.GreenBias = 0.0;
1272 ctx->Pixel.GreenScale = 1.0;
1273 ctx->Pixel.BlueBias = 0.0;
1274 ctx->Pixel.BlueScale = 1.0;
1275 ctx->Pixel.AlphaBias = 0.0;
1276 ctx->Pixel.AlphaScale = 1.0;
1277 ctx->Pixel.DepthBias = 0.0;
1278 ctx->Pixel.DepthScale = 1.0;
1279 ctx->Pixel.IndexOffset = 0;
1280 ctx->Pixel.IndexShift = 0;
1281 ctx->Pixel.ZoomX = 1.0;
1282 ctx->Pixel.ZoomY = 1.0;
1283 ctx->Pixel.MapColorFlag = GL_FALSE;
1284 ctx->Pixel.MapStencilFlag = GL_FALSE;
1285 init_pixelmap(&ctx->PixelMaps.StoS);
1286 init_pixelmap(&ctx->PixelMaps.ItoI);
1287 init_pixelmap(&ctx->PixelMaps.ItoR);
1288 init_pixelmap(&ctx->PixelMaps.ItoG);
1289 init_pixelmap(&ctx->PixelMaps.ItoB);
1290 init_pixelmap(&ctx->PixelMaps.ItoA);
1291 init_pixelmap(&ctx->PixelMaps.RtoR);
1292 init_pixelmap(&ctx->PixelMaps.GtoG);
1293 init_pixelmap(&ctx->PixelMaps.BtoB);
1294 init_pixelmap(&ctx->PixelMaps.AtoA);
1295 ctx->Pixel.HistogramEnabled = GL_FALSE;
1296 ctx->Pixel.MinMaxEnabled = GL_FALSE;
1297 ASSIGN_4V(ctx->Pixel.PostColorMatrixScale, 1.0, 1.0, 1.0, 1.0);
1298 ASSIGN_4V(ctx->Pixel.PostColorMatrixBias, 0.0, 0.0, 0.0, 0.0);
1299 for (i = 0; i < COLORTABLE_MAX; i++) {
1300 ASSIGN_4V(ctx->Pixel.ColorTableScale[i], 1.0, 1.0, 1.0, 1.0);
1301 ASSIGN_4V(ctx->Pixel.ColorTableBias[i], 0.0, 0.0, 0.0, 0.0);
1302 ctx->Pixel.ColorTableEnabled[i] = GL_FALSE;
1303 }
1304 ctx->Pixel.Convolution1DEnabled = GL_FALSE;
1305 ctx->Pixel.Convolution2DEnabled = GL_FALSE;
1306 ctx->Pixel.Separable2DEnabled = GL_FALSE;
1307 for (i = 0; i < 3; i++) {
1308 ASSIGN_4V(ctx->Pixel.ConvolutionBorderColor[i], 0.0, 0.0, 0.0, 0.0);
1309 ctx->Pixel.ConvolutionBorderMode[i] = GL_REDUCE;
1310 ASSIGN_4V(ctx->Pixel.ConvolutionFilterScale[i], 1.0, 1.0, 1.0, 1.0);
1311 ASSIGN_4V(ctx->Pixel.ConvolutionFilterBias[i], 0.0, 0.0, 0.0, 0.0);
1312 }
1313 for (i = 0; i < MAX_CONVOLUTION_WIDTH * MAX_CONVOLUTION_WIDTH * 4; i++) {
1314 ctx->Convolution1D.Filter[i] = 0.0;
1315 ctx->Convolution2D.Filter[i] = 0.0;
1316 ctx->Separable2D.Filter[i] = 0.0;
1317 }
1318 ASSIGN_4V(ctx->Pixel.PostConvolutionScale, 1.0, 1.0, 1.0, 1.0);
1319 ASSIGN_4V(ctx->Pixel.PostConvolutionBias, 0.0, 0.0, 0.0, 0.0);
1320 /* GL_SGI_texture_color_table */
1321 ASSIGN_4V(ctx->Pixel.TextureColorTableScale, 1.0, 1.0, 1.0, 1.0);
1322 ASSIGN_4V(ctx->Pixel.TextureColorTableBias, 0.0, 0.0, 0.0, 0.0);
1323
1324 /* Pixel transfer */
1325 ctx->Pack.Alignment = 4;
1326 ctx->Pack.RowLength = 0;
1327 ctx->Pack.ImageHeight = 0;
1328 ctx->Pack.SkipPixels = 0;
1329 ctx->Pack.SkipRows = 0;
1330 ctx->Pack.SkipImages = 0;
1331 ctx->Pack.SwapBytes = GL_FALSE;
1332 ctx->Pack.LsbFirst = GL_FALSE;
1333 ctx->Pack.ClientStorage = GL_FALSE;
1334 ctx->Pack.Invert = GL_FALSE;
1335 #if FEATURE_EXT_pixel_buffer_object
1336 ctx->Pack.BufferObj = ctx->Array.NullBufferObj;
1337 #endif
1338 ctx->Unpack.Alignment = 4;
1339 ctx->Unpack.RowLength = 0;
1340 ctx->Unpack.ImageHeight = 0;
1341 ctx->Unpack.SkipPixels = 0;
1342 ctx->Unpack.SkipRows = 0;
1343 ctx->Unpack.SkipImages = 0;
1344 ctx->Unpack.SwapBytes = GL_FALSE;
1345 ctx->Unpack.LsbFirst = GL_FALSE;
1346 ctx->Unpack.ClientStorage = GL_FALSE;
1347 ctx->Unpack.Invert = GL_FALSE;
1348 #if FEATURE_EXT_pixel_buffer_object
1349 ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;
1350 #endif
1351
1352 /*
1353 * _mesa_unpack_image() returns image data in this format. When we
1354 * execute image commands (glDrawPixels(), glTexImage(), etc) from
1355 * within display lists we have to be sure to set the current
1356 * unpacking parameters to these values!
1357 */
1358 ctx->DefaultPacking.Alignment = 1;
1359 ctx->DefaultPacking.RowLength = 0;
1360 ctx->DefaultPacking.SkipPixels = 0;
1361 ctx->DefaultPacking.SkipRows = 0;
1362 ctx->DefaultPacking.ImageHeight = 0;
1363 ctx->DefaultPacking.SkipImages = 0;
1364 ctx->DefaultPacking.SwapBytes = GL_FALSE;
1365 ctx->DefaultPacking.LsbFirst = GL_FALSE;
1366 ctx->DefaultPacking.ClientStorage = GL_FALSE;
1367 ctx->DefaultPacking.Invert = GL_FALSE;
1368 #if FEATURE_EXT_pixel_buffer_object
1369 ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
1370 #endif
1371
1372 if (ctx->Visual.doubleBufferMode) {
1373 ctx->Pixel.ReadBuffer = GL_BACK;
1374 }
1375 else {
1376 ctx->Pixel.ReadBuffer = GL_FRONT;
1377 }
1378
1379 /* Miscellaneous */
1380 ctx->_ImageTransferState = 0;
1381 }