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