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