1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 
26 /**
27  * \file pixel.c
28  * Pixel transfer functions (glPixelZoom, glPixelMap, glPixelTransfer)
29  */
30 
31 #include "c99_math.h"
32 #include "glheader.h"
33 #include "bufferobj.h"
34 #include "context.h"
35 #include "macros.h"
36 #include "pixel.h"
37 #include "pbo.h"
38 #include "mtypes.h"
39 
40 
41 /**********************************************************************/
42 /*****                    glPixelZoom                             *****/
43 /**********************************************************************/
44 
45 void GLAPIENTRY
_mesa_PixelZoom(GLfloat xfactor,GLfloat yfactor)46 _mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor )
47 {
48    GET_CURRENT_CONTEXT(ctx);
49 
50    if (ctx->Pixel.ZoomX == xfactor &&
51        ctx->Pixel.ZoomY == yfactor)
52       return;
53 
54    FLUSH_VERTICES(ctx, _NEW_PIXEL);
55    ctx->Pixel.ZoomX = xfactor;
56    ctx->Pixel.ZoomY = yfactor;
57 }
58 
59 
60 
61 /**********************************************************************/
62 /*****                         glPixelMap                         *****/
63 /**********************************************************************/
64 
65 /**
66  * Return pointer to a pixelmap by name.
67  */
68 static struct gl_pixelmap *
get_pixelmap(struct gl_context * ctx,GLenum map)69 get_pixelmap(struct gl_context *ctx, GLenum map)
70 {
71    switch (map) {
72    case GL_PIXEL_MAP_I_TO_I:
73       return &ctx->PixelMaps.ItoI;
74    case GL_PIXEL_MAP_S_TO_S:
75       return &ctx->PixelMaps.StoS;
76    case GL_PIXEL_MAP_I_TO_R:
77       return &ctx->PixelMaps.ItoR;
78    case GL_PIXEL_MAP_I_TO_G:
79       return &ctx->PixelMaps.ItoG;
80    case GL_PIXEL_MAP_I_TO_B:
81       return &ctx->PixelMaps.ItoB;
82    case GL_PIXEL_MAP_I_TO_A:
83       return &ctx->PixelMaps.ItoA;
84    case GL_PIXEL_MAP_R_TO_R:
85       return &ctx->PixelMaps.RtoR;
86    case GL_PIXEL_MAP_G_TO_G:
87       return &ctx->PixelMaps.GtoG;
88    case GL_PIXEL_MAP_B_TO_B:
89       return &ctx->PixelMaps.BtoB;
90    case GL_PIXEL_MAP_A_TO_A:
91       return &ctx->PixelMaps.AtoA;
92    default:
93       return NULL;
94    }
95 }
96 
97 
98 /**
99  * Helper routine used by the other _mesa_PixelMap() functions.
100  */
101 static void
store_pixelmap(struct gl_context * ctx,GLenum map,GLsizei mapsize,const GLfloat * values)102 store_pixelmap(struct gl_context *ctx, GLenum map, GLsizei mapsize,
103                const GLfloat *values)
104 {
105    GLint i;
106    struct gl_pixelmap *pm = get_pixelmap(ctx, map);
107    if (!pm) {
108       _mesa_error(ctx, GL_INVALID_ENUM, "glPixelMap(map)");
109       return;
110    }
111 
112    switch (map) {
113    case GL_PIXEL_MAP_S_TO_S:
114       /* special case */
115       ctx->PixelMaps.StoS.Size = mapsize;
116       for (i = 0; i < mapsize; i++) {
117          ctx->PixelMaps.StoS.Map[i] = roundf(values[i]);
118       }
119       break;
120    case GL_PIXEL_MAP_I_TO_I:
121       /* special case */
122       ctx->PixelMaps.ItoI.Size = mapsize;
123       for (i = 0; i < mapsize; i++) {
124          ctx->PixelMaps.ItoI.Map[i] = values[i];
125       }
126       break;
127    default:
128       /* general case */
129       pm->Size = mapsize;
130       for (i = 0; i < mapsize; i++) {
131          GLfloat val = CLAMP(values[i], 0.0F, 1.0F);
132          pm->Map[i] = val;
133       }
134    }
135 }
136 
137 
138 /**
139  * Convenience wrapper for _mesa_validate_pbo_access() for gl[Get]PixelMap().
140  */
141 static GLboolean
validate_pbo_access(struct gl_context * ctx,struct gl_pixelstore_attrib * pack,GLsizei mapsize,GLenum format,GLenum type,GLsizei clientMemSize,const GLvoid * ptr)142 validate_pbo_access(struct gl_context *ctx,
143                     struct gl_pixelstore_attrib *pack, GLsizei mapsize,
144                     GLenum format, GLenum type, GLsizei clientMemSize,
145                     const GLvoid *ptr)
146 {
147    GLboolean ok;
148 
149    /* Note, need to use DefaultPacking and Unpack's buffer object */
150    _mesa_reference_buffer_object(ctx,
151                                  &ctx->DefaultPacking.BufferObj,
152                                  pack->BufferObj);
153 
154    ok = _mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
155                                   format, type, clientMemSize, ptr);
156 
157    /* restore */
158    _mesa_reference_buffer_object(ctx,
159                                  &ctx->DefaultPacking.BufferObj, NULL);
160 
161    if (!ok) {
162       if (pack->BufferObj) {
163          _mesa_error(ctx, GL_INVALID_OPERATION,
164                      "gl[Get]PixelMap*v(out of bounds PBO access)");
165       } else {
166          _mesa_error(ctx, GL_INVALID_OPERATION,
167                      "glGetnPixelMap*vARB(out of bounds access:"
168                      " bufSize (%d) is too small)", clientMemSize);
169       }
170    }
171    return ok;
172 }
173 
174 
175 void GLAPIENTRY
_mesa_PixelMapfv(GLenum map,GLsizei mapsize,const GLfloat * values)176 _mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
177 {
178    GET_CURRENT_CONTEXT(ctx);
179 
180    /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */
181    if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
182       _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
183       return;
184    }
185 
186    if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
187       /* test that mapsize is a power of two */
188       if (!util_is_power_of_two_or_zero(mapsize)) {
189 	 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
190          return;
191       }
192    }
193 
194    FLUSH_VERTICES(ctx, _NEW_PIXEL);
195 
196    if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, GL_INTENSITY,
197                             GL_FLOAT, INT_MAX, values)) {
198       return;
199    }
200 
201    values = (const GLfloat *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values);
202    if (!values) {
203       if (ctx->Unpack.BufferObj) {
204          _mesa_error(ctx, GL_INVALID_OPERATION,
205                      "glPixelMapfv(PBO is mapped)");
206       }
207       return;
208    }
209 
210    store_pixelmap(ctx, map, mapsize, values);
211 
212    _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
213 }
214 
215 
216 void GLAPIENTRY
_mesa_PixelMapuiv(GLenum map,GLsizei mapsize,const GLuint * values)217 _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
218 {
219    GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
220    GET_CURRENT_CONTEXT(ctx);
221 
222    if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
223       _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
224       return;
225    }
226 
227    if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
228       /* test that mapsize is a power of two */
229       if (!util_is_power_of_two_or_zero(mapsize)) {
230 	 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
231          return;
232       }
233    }
234 
235    FLUSH_VERTICES(ctx, _NEW_PIXEL);
236 
237    if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, GL_INTENSITY,
238                             GL_UNSIGNED_INT, INT_MAX, values)) {
239       return;
240    }
241 
242    values = (const GLuint *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values);
243    if (!values) {
244       if (ctx->Unpack.BufferObj) {
245          _mesa_error(ctx, GL_INVALID_OPERATION,
246                      "glPixelMapuiv(PBO is mapped)");
247       }
248       return;
249    }
250 
251    /* convert to floats */
252    if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
253       GLint i;
254       for (i = 0; i < mapsize; i++) {
255          fvalues[i] = (GLfloat) values[i];
256       }
257    }
258    else {
259       GLint i;
260       for (i = 0; i < mapsize; i++) {
261          fvalues[i] = UINT_TO_FLOAT( values[i] );
262       }
263    }
264 
265    _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
266 
267    store_pixelmap(ctx, map, mapsize, fvalues);
268 }
269 
270 
271 void GLAPIENTRY
_mesa_PixelMapusv(GLenum map,GLsizei mapsize,const GLushort * values)272 _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
273 {
274    GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
275    GET_CURRENT_CONTEXT(ctx);
276 
277    if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
278       _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" );
279       return;
280    }
281 
282    if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
283       /* test that mapsize is a power of two */
284       if (!util_is_power_of_two_or_zero(mapsize)) {
285 	 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" );
286          return;
287       }
288    }
289 
290    FLUSH_VERTICES(ctx, _NEW_PIXEL);
291 
292    if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, GL_INTENSITY,
293                             GL_UNSIGNED_SHORT, INT_MAX, values)) {
294       return;
295    }
296 
297    values = (const GLushort *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values);
298    if (!values) {
299       if (ctx->Unpack.BufferObj) {
300          _mesa_error(ctx, GL_INVALID_OPERATION,
301                      "glPixelMapusv(PBO is mapped)");
302       }
303       return;
304    }
305 
306    /* convert to floats */
307    if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
308       GLint i;
309       for (i = 0; i < mapsize; i++) {
310          fvalues[i] = (GLfloat) values[i];
311       }
312    }
313    else {
314       GLint i;
315       for (i = 0; i < mapsize; i++) {
316          fvalues[i] = USHORT_TO_FLOAT( values[i] );
317       }
318    }
319 
320    _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
321 
322    store_pixelmap(ctx, map, mapsize, fvalues);
323 }
324 
325 
326 void GLAPIENTRY
_mesa_GetnPixelMapfvARB(GLenum map,GLsizei bufSize,GLfloat * values)327 _mesa_GetnPixelMapfvARB( GLenum map, GLsizei bufSize, GLfloat *values )
328 {
329    GET_CURRENT_CONTEXT(ctx);
330    GLint mapsize, i;
331    const struct gl_pixelmap *pm;
332 
333    pm = get_pixelmap(ctx, map);
334    if (!pm) {
335       _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapfv(map)");
336       return;
337    }
338 
339    mapsize = pm->Size;
340 
341    if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY,
342                             GL_FLOAT, bufSize, values)) {
343       return;
344    }
345 
346    values = (GLfloat *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
347    if (!values) {
348       if (ctx->Pack.BufferObj) {
349          _mesa_error(ctx, GL_INVALID_OPERATION,
350                      "glGetPixelMapfv(PBO is mapped)");
351       }
352       return;
353    }
354 
355    if (map == GL_PIXEL_MAP_S_TO_S) {
356       /* special case */
357       for (i = 0; i < mapsize; i++) {
358          values[i] = (GLfloat) ctx->PixelMaps.StoS.Map[i];
359       }
360    }
361    else {
362       memcpy(values, pm->Map, mapsize * sizeof(GLfloat));
363    }
364 
365    _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
366 }
367 
368 
369 void GLAPIENTRY
_mesa_GetPixelMapfv(GLenum map,GLfloat * values)370 _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
371 {
372    _mesa_GetnPixelMapfvARB(map, INT_MAX, values);
373 }
374 
375 void GLAPIENTRY
_mesa_GetnPixelMapuivARB(GLenum map,GLsizei bufSize,GLuint * values)376 _mesa_GetnPixelMapuivARB( GLenum map, GLsizei bufSize, GLuint *values )
377 {
378    GET_CURRENT_CONTEXT(ctx);
379    GLint mapsize, i;
380    const struct gl_pixelmap *pm;
381 
382    pm = get_pixelmap(ctx, map);
383    if (!pm) {
384       _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapuiv(map)");
385       return;
386    }
387 
388    mapsize = pm->Size;
389 
390    if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY,
391                             GL_UNSIGNED_INT, bufSize, values)) {
392       return;
393    }
394 
395    values = (GLuint *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
396    if (!values) {
397       if (ctx->Pack.BufferObj) {
398          _mesa_error(ctx, GL_INVALID_OPERATION,
399                      "glGetPixelMapuiv(PBO is mapped)");
400       }
401       return;
402    }
403 
404    if (map == GL_PIXEL_MAP_S_TO_S) {
405       /* special case */
406       memcpy(values, ctx->PixelMaps.StoS.Map, mapsize * sizeof(GLint));
407    }
408    else {
409       for (i = 0; i < mapsize; i++) {
410          values[i] = FLOAT_TO_UINT( pm->Map[i] );
411       }
412    }
413 
414    _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
415 }
416 
417 
418 void GLAPIENTRY
_mesa_GetPixelMapuiv(GLenum map,GLuint * values)419 _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
420 {
421    _mesa_GetnPixelMapuivARB(map, INT_MAX, values);
422 }
423 
424 void GLAPIENTRY
_mesa_GetnPixelMapusvARB(GLenum map,GLsizei bufSize,GLushort * values)425 _mesa_GetnPixelMapusvARB( GLenum map, GLsizei bufSize, GLushort *values )
426 {
427    GET_CURRENT_CONTEXT(ctx);
428    GLint mapsize, i;
429    const struct gl_pixelmap *pm;
430 
431    pm = get_pixelmap(ctx, map);
432    if (!pm) {
433       _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapusv(map)");
434       return;
435    }
436 
437    mapsize = pm->Size;
438 
439    if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY,
440                             GL_UNSIGNED_SHORT, bufSize, values)) {
441       return;
442    }
443 
444    values = (GLushort *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
445    if (!values) {
446       if (ctx->Pack.BufferObj) {
447          _mesa_error(ctx, GL_INVALID_OPERATION,
448                      "glGetPixelMapusv(PBO is mapped)");
449       }
450       return;
451    }
452 
453    switch (map) {
454    /* special cases */
455    case GL_PIXEL_MAP_I_TO_I:
456       for (i = 0; i < mapsize; i++) {
457          values[i] = (GLushort) CLAMP(ctx->PixelMaps.ItoI.Map[i], 0.0F, 65535.0F);
458       }
459       break;
460    case GL_PIXEL_MAP_S_TO_S:
461       for (i = 0; i < mapsize; i++) {
462          values[i] = (GLushort) CLAMP(ctx->PixelMaps.StoS.Map[i], 0.0F, 65535.0F);
463       }
464       break;
465    default:
466       for (i = 0; i < mapsize; i++) {
467          CLAMPED_FLOAT_TO_USHORT(values[i], pm->Map[i] );
468       }
469    }
470 
471    _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
472 }
473 
474 
475 void GLAPIENTRY
_mesa_GetPixelMapusv(GLenum map,GLushort * values)476 _mesa_GetPixelMapusv( GLenum map, GLushort *values )
477 {
478    _mesa_GetnPixelMapusvARB(map, INT_MAX, values);
479 }
480 
481 
482 /**********************************************************************/
483 /*****                       glPixelTransfer                      *****/
484 /**********************************************************************/
485 
486 
487 /*
488  * Implements glPixelTransfer[fi] whether called immediately or from a
489  * display list.
490  */
491 void GLAPIENTRY
_mesa_PixelTransferf(GLenum pname,GLfloat param)492 _mesa_PixelTransferf( GLenum pname, GLfloat param )
493 {
494    GET_CURRENT_CONTEXT(ctx);
495 
496    switch (pname) {
497       case GL_MAP_COLOR:
498          if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE))
499 	    return;
500 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
501          ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
502 	 break;
503       case GL_MAP_STENCIL:
504          if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE))
505 	    return;
506 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
507          ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
508 	 break;
509       case GL_INDEX_SHIFT:
510          if (ctx->Pixel.IndexShift == (GLint) param)
511 	    return;
512 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
513          ctx->Pixel.IndexShift = (GLint) param;
514 	 break;
515       case GL_INDEX_OFFSET:
516          if (ctx->Pixel.IndexOffset == (GLint) param)
517 	    return;
518 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
519          ctx->Pixel.IndexOffset = (GLint) param;
520 	 break;
521       case GL_RED_SCALE:
522          if (ctx->Pixel.RedScale == param)
523 	    return;
524 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
525          ctx->Pixel.RedScale = param;
526 	 break;
527       case GL_RED_BIAS:
528          if (ctx->Pixel.RedBias == param)
529 	    return;
530 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
531          ctx->Pixel.RedBias = param;
532 	 break;
533       case GL_GREEN_SCALE:
534          if (ctx->Pixel.GreenScale == param)
535 	    return;
536 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
537          ctx->Pixel.GreenScale = param;
538 	 break;
539       case GL_GREEN_BIAS:
540          if (ctx->Pixel.GreenBias == param)
541 	    return;
542 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
543          ctx->Pixel.GreenBias = param;
544 	 break;
545       case GL_BLUE_SCALE:
546          if (ctx->Pixel.BlueScale == param)
547 	    return;
548 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
549          ctx->Pixel.BlueScale = param;
550 	 break;
551       case GL_BLUE_BIAS:
552          if (ctx->Pixel.BlueBias == param)
553 	    return;
554 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
555          ctx->Pixel.BlueBias = param;
556 	 break;
557       case GL_ALPHA_SCALE:
558          if (ctx->Pixel.AlphaScale == param)
559 	    return;
560 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
561          ctx->Pixel.AlphaScale = param;
562 	 break;
563       case GL_ALPHA_BIAS:
564          if (ctx->Pixel.AlphaBias == param)
565 	    return;
566 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
567          ctx->Pixel.AlphaBias = param;
568 	 break;
569       case GL_DEPTH_SCALE:
570          if (ctx->Pixel.DepthScale == param)
571 	    return;
572 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
573          ctx->Pixel.DepthScale = param;
574 	 break;
575       case GL_DEPTH_BIAS:
576          if (ctx->Pixel.DepthBias == param)
577 	    return;
578 	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
579          ctx->Pixel.DepthBias = param;
580 	 break;
581       default:
582          _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
583          return;
584    }
585 }
586 
587 
588 void GLAPIENTRY
_mesa_PixelTransferi(GLenum pname,GLint param)589 _mesa_PixelTransferi( GLenum pname, GLint param )
590 {
591    _mesa_PixelTransferf( pname, (GLfloat) param );
592 }
593 
594 
595 
596 /**********************************************************************/
597 /*****                    State Management                        *****/
598 /**********************************************************************/
599 
600 
601 /**
602  * Update mesa pixel transfer derived state to indicate which operations are
603  * enabled.
604  */
605 void
_mesa_update_pixel(struct gl_context * ctx)606 _mesa_update_pixel( struct gl_context *ctx )
607 {
608    GLuint mask = 0;
609 
610    if (ctx->Pixel.RedScale   != 1.0F || ctx->Pixel.RedBias   != 0.0F ||
611        ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F ||
612        ctx->Pixel.BlueScale  != 1.0F || ctx->Pixel.BlueBias  != 0.0F ||
613        ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F)
614       mask |= IMAGE_SCALE_BIAS_BIT;
615 
616    if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset)
617       mask |= IMAGE_SHIFT_OFFSET_BIT;
618 
619    if (ctx->Pixel.MapColorFlag)
620       mask |= IMAGE_MAP_COLOR_BIT;
621 
622    ctx->_ImageTransferState = mask;
623 }
624 
625 
626 /**********************************************************************/
627 /*****                      Initialization                        *****/
628 /**********************************************************************/
629 
630 static void
init_pixelmap(struct gl_pixelmap * map)631 init_pixelmap(struct gl_pixelmap *map)
632 {
633    map->Size = 1;
634    map->Map[0] = 0.0;
635 }
636 
637 
638 /**
639  * Initialize the context's PIXEL attribute group.
640  */
641 void
_mesa_init_pixel(struct gl_context * ctx)642 _mesa_init_pixel( struct gl_context *ctx )
643 {
644    /* Pixel group */
645    ctx->Pixel.RedBias = 0.0;
646    ctx->Pixel.RedScale = 1.0;
647    ctx->Pixel.GreenBias = 0.0;
648    ctx->Pixel.GreenScale = 1.0;
649    ctx->Pixel.BlueBias = 0.0;
650    ctx->Pixel.BlueScale = 1.0;
651    ctx->Pixel.AlphaBias = 0.0;
652    ctx->Pixel.AlphaScale = 1.0;
653    ctx->Pixel.DepthBias = 0.0;
654    ctx->Pixel.DepthScale = 1.0;
655    ctx->Pixel.IndexOffset = 0;
656    ctx->Pixel.IndexShift = 0;
657    ctx->Pixel.ZoomX = 1.0;
658    ctx->Pixel.ZoomY = 1.0;
659    ctx->Pixel.MapColorFlag = GL_FALSE;
660    ctx->Pixel.MapStencilFlag = GL_FALSE;
661    init_pixelmap(&ctx->PixelMaps.StoS);
662    init_pixelmap(&ctx->PixelMaps.ItoI);
663    init_pixelmap(&ctx->PixelMaps.ItoR);
664    init_pixelmap(&ctx->PixelMaps.ItoG);
665    init_pixelmap(&ctx->PixelMaps.ItoB);
666    init_pixelmap(&ctx->PixelMaps.ItoA);
667    init_pixelmap(&ctx->PixelMaps.RtoR);
668    init_pixelmap(&ctx->PixelMaps.GtoG);
669    init_pixelmap(&ctx->PixelMaps.BtoB);
670    init_pixelmap(&ctx->PixelMaps.AtoA);
671 
672    if (ctx->Visual.doubleBufferMode) {
673       ctx->Pixel.ReadBuffer = GL_BACK;
674    }
675    else {
676       ctx->Pixel.ReadBuffer = GL_FRONT;
677    }
678 
679    /* Miscellaneous */
680    ctx->_ImageTransferState = 0;
681 }
682