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