pixel.c revision 331cc1dcba8705116288e487f43f460852c2159f
1/*
2 * Mesa 3-D graphics library
3 * Version:  6.3
4 *
5 * Copyright (C) 1999-2004  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
40
41void GLAPIENTRY
42_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor )
43{
44   GET_CURRENT_CONTEXT(ctx);
45
46   if (ctx->Pixel.ZoomX == xfactor &&
47       ctx->Pixel.ZoomY == yfactor)
48      return;
49
50   FLUSH_VERTICES(ctx, _NEW_PIXEL);
51   ctx->Pixel.ZoomX = xfactor;
52   ctx->Pixel.ZoomY = yfactor;
53}
54
55
56
57/**********************************************************************/
58/*****                    glPixelStore                            *****/
59/**********************************************************************/
60
61
62void GLAPIENTRY
63_mesa_PixelStorei( GLenum pname, GLint param )
64{
65   /* NOTE: this call can't be compiled into the display list */
66   GET_CURRENT_CONTEXT(ctx);
67   ASSERT_OUTSIDE_BEGIN_END(ctx);
68
69   switch (pname) {
70      case GL_PACK_SWAP_BYTES:
71	 if (param == (GLint)ctx->Pack.SwapBytes)
72	    return;
73	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
74         ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
75	 break;
76      case GL_PACK_LSB_FIRST:
77	 if (param == (GLint)ctx->Pack.LsbFirst)
78	    return;
79	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
80         ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
81	 break;
82      case GL_PACK_ROW_LENGTH:
83	 if (param<0) {
84	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
85	    return;
86	 }
87	 if (ctx->Pack.RowLength == param)
88	    return;
89	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
90	 ctx->Pack.RowLength = param;
91	 break;
92      case GL_PACK_IMAGE_HEIGHT:
93         if (param<0) {
94            _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
95	    return;
96	 }
97	 if (ctx->Pack.ImageHeight == param)
98	    return;
99	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
100	 ctx->Pack.ImageHeight = param;
101         break;
102      case GL_PACK_SKIP_PIXELS:
103	 if (param<0) {
104	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
105	    return;
106	 }
107	 if (ctx->Pack.SkipPixels == param)
108	    return;
109	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
110	 ctx->Pack.SkipPixels = param;
111	 break;
112      case GL_PACK_SKIP_ROWS:
113	 if (param<0) {
114	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
115	    return;
116	 }
117	 if (ctx->Pack.SkipRows == param)
118	    return;
119	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
120	 ctx->Pack.SkipRows = param;
121	 break;
122      case GL_PACK_SKIP_IMAGES:
123	 if (param<0) {
124	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
125	    return;
126	 }
127	 if (ctx->Pack.SkipImages == param)
128	    return;
129	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
130	 ctx->Pack.SkipImages = param;
131	 break;
132      case GL_PACK_ALIGNMENT:
133         if (param!=1 && param!=2 && param!=4 && param!=8) {
134	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
135	    return;
136	 }
137	 if (ctx->Pack.Alignment == param)
138	    return;
139	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
140	 ctx->Pack.Alignment = param;
141	 break;
142      case GL_PACK_INVERT_MESA:
143         if (!ctx->Extensions.MESA_pack_invert) {
144            _mesa_error( ctx, GL_INVALID_ENUM, "glPixelstore(pname)" );
145            return;
146         }
147         if (ctx->Pack.Invert == param)
148            return;
149         FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
150         ctx->Pack.Invert = param;
151         break;
152
153      case GL_UNPACK_SWAP_BYTES:
154	 if (param == (GLint)ctx->Unpack.SwapBytes)
155	    return;
156	 if ((GLint)ctx->Unpack.SwapBytes == param)
157	    return;
158	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
159	 ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
160         break;
161      case GL_UNPACK_LSB_FIRST:
162	 if (param == (GLint)ctx->Unpack.LsbFirst)
163	    return;
164	 if ((GLint)ctx->Unpack.LsbFirst == param)
165	    return;
166	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
167	 ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
168	 break;
169      case GL_UNPACK_ROW_LENGTH:
170	 if (param<0) {
171	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
172	    return;
173	 }
174	 if (ctx->Unpack.RowLength == param)
175	    return;
176	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
177	 ctx->Unpack.RowLength = param;
178	 break;
179      case GL_UNPACK_IMAGE_HEIGHT:
180         if (param<0) {
181            _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
182	    return;
183	 }
184	 if (ctx->Unpack.ImageHeight == param)
185	    return;
186
187	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
188	 ctx->Unpack.ImageHeight = param;
189         break;
190      case GL_UNPACK_SKIP_PIXELS:
191	 if (param<0) {
192	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
193	    return;
194	 }
195	 if (ctx->Unpack.SkipPixels == param)
196	    return;
197	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
198	 ctx->Unpack.SkipPixels = param;
199	 break;
200      case GL_UNPACK_SKIP_ROWS:
201	 if (param<0) {
202	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
203	    return;
204	 }
205	 if (ctx->Unpack.SkipRows == param)
206	    return;
207	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
208	 ctx->Unpack.SkipRows = param;
209	 break;
210      case GL_UNPACK_SKIP_IMAGES:
211	 if (param < 0) {
212	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
213	    return;
214	 }
215	 if (ctx->Unpack.SkipImages == param)
216	    return;
217	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
218	 ctx->Unpack.SkipImages = param;
219	 break;
220      case GL_UNPACK_ALIGNMENT:
221         if (param!=1 && param!=2 && param!=4 && param!=8) {
222	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore" );
223	    return;
224	 }
225	 if (ctx->Unpack.Alignment == param)
226	    return;
227	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
228	 ctx->Unpack.Alignment = param;
229	 break;
230      case GL_UNPACK_CLIENT_STORAGE_APPLE:
231         if (param == (GLint)ctx->Unpack.ClientStorage)
232            return;
233         FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
234         ctx->Unpack.ClientStorage = param ? GL_TRUE : GL_FALSE;
235         break;
236      default:
237	 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
238	 return;
239   }
240}
241
242
243void GLAPIENTRY
244_mesa_PixelStoref( GLenum pname, GLfloat param )
245{
246   _mesa_PixelStorei( pname, (GLint) param );
247}
248
249
250
251/**********************************************************************/
252/*****                         glPixelMap                         *****/
253/**********************************************************************/
254
255
256/**
257 * Helper routine used by the other _mesa_PixelMap() functions.
258 */
259static void
260pixelmap(GLcontext *ctx, GLenum map, GLsizei mapsize, const GLfloat *values)
261{
262   GLint i;
263   switch (map) {
264      case GL_PIXEL_MAP_S_TO_S:
265         ctx->Pixel.MapStoSsize = mapsize;
266         for (i = 0; i < mapsize; i++) {
267	    ctx->Pixel.MapStoS[i] = (GLint) values[i];
268	 }
269	 break;
270      case GL_PIXEL_MAP_I_TO_I:
271         ctx->Pixel.MapItoIsize = mapsize;
272         for (i = 0; i < mapsize; i++) {
273	    ctx->Pixel.MapItoI[i] = (GLint) values[i];
274	 }
275	 break;
276      case GL_PIXEL_MAP_I_TO_R:
277         ctx->Pixel.MapItoRsize = mapsize;
278         for (i = 0; i < mapsize; i++) {
279            GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
280	    ctx->Pixel.MapItoR[i] = val;
281	    ctx->Pixel.MapItoR8[i] = (GLint) (val * 255.0F);
282	 }
283	 break;
284      case GL_PIXEL_MAP_I_TO_G:
285         ctx->Pixel.MapItoGsize = mapsize;
286         for (i = 0; i < mapsize; i++) {
287            GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
288	    ctx->Pixel.MapItoG[i] = val;
289	    ctx->Pixel.MapItoG8[i] = (GLint) (val * 255.0F);
290	 }
291	 break;
292      case GL_PIXEL_MAP_I_TO_B:
293         ctx->Pixel.MapItoBsize = mapsize;
294         for (i = 0; i < mapsize; i++) {
295            GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
296	    ctx->Pixel.MapItoB[i] = val;
297	    ctx->Pixel.MapItoB8[i] = (GLint) (val * 255.0F);
298	 }
299	 break;
300      case GL_PIXEL_MAP_I_TO_A:
301         ctx->Pixel.MapItoAsize = mapsize;
302         for (i = 0; i < mapsize; i++) {
303            GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
304	    ctx->Pixel.MapItoA[i] = val;
305	    ctx->Pixel.MapItoA8[i] = (GLint) (val * 255.0F);
306	 }
307	 break;
308      case GL_PIXEL_MAP_R_TO_R:
309         ctx->Pixel.MapRtoRsize = mapsize;
310         for (i = 0; i < mapsize; i++) {
311	    ctx->Pixel.MapRtoR[i] = CLAMP( values[i], 0.0F, 1.0F );
312	 }
313	 break;
314      case GL_PIXEL_MAP_G_TO_G:
315         ctx->Pixel.MapGtoGsize = mapsize;
316         for (i = 0; i < mapsize; i++) {
317	    ctx->Pixel.MapGtoG[i] = CLAMP( values[i], 0.0F, 1.0F );
318	 }
319	 break;
320      case GL_PIXEL_MAP_B_TO_B:
321         ctx->Pixel.MapBtoBsize = mapsize;
322         for (i = 0; i < mapsize; i++) {
323	    ctx->Pixel.MapBtoB[i] = CLAMP( values[i], 0.0F, 1.0F );
324	 }
325	 break;
326      case GL_PIXEL_MAP_A_TO_A:
327         ctx->Pixel.MapAtoAsize = mapsize;
328         for (i = 0; i < mapsize; i++) {
329	    ctx->Pixel.MapAtoA[i] = CLAMP( values[i], 0.0F, 1.0F );
330	 }
331	 break;
332      default:
333         _mesa_error( ctx, GL_INVALID_ENUM, "glPixelMap(map)" );
334   }
335}
336
337
338void GLAPIENTRY
339_mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
340{
341   GET_CURRENT_CONTEXT(ctx);
342   ASSERT_OUTSIDE_BEGIN_END(ctx);
343
344   /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */
345   if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
346      _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
347      return;
348   }
349
350   if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
351      /* test that mapsize is a power of two */
352      if (_mesa_bitcount((GLuint) mapsize) != 1) {
353	 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
354         return;
355      }
356   }
357
358   FLUSH_VERTICES(ctx, _NEW_PIXEL);
359
360   if (ctx->Unpack.BufferObj->Name) {
361      /* unpack pixelmap from PBO */
362      GLubyte *buf;
363      /* Note, need to use DefaultPacking and Unpack's buffer object */
364      ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
365      if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1,
366                                     GL_INTENSITY, GL_FLOAT, values)) {
367         _mesa_error(ctx, GL_INVALID_OPERATION,
368                     "glPixelMapfv(invalid PBO access)");
369         return;
370      }
371      /* restore */
372      ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
373      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
374                                              GL_READ_ONLY_ARB,
375                                              ctx->Unpack.BufferObj);
376      if (!buf) {
377         /* buffer is already mapped - that's an error */
378         _mesa_error(ctx, GL_INVALID_OPERATION,
379                     "glPixelMapfv(PBO is mapped)");
380         return;
381      }
382      values = (const GLfloat *) ADD_POINTERS(buf, values);
383   }
384   else if (!values) {
385      return;
386   }
387
388   pixelmap(ctx, map, mapsize, values);
389
390   if (ctx->Unpack.BufferObj->Name) {
391      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
392                              ctx->Unpack.BufferObj);
393   }
394}
395
396
397
398void GLAPIENTRY
399_mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
400{
401   GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
402   GET_CURRENT_CONTEXT(ctx);
403   ASSERT_OUTSIDE_BEGIN_END(ctx);
404
405   if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
406      _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
407      return;
408   }
409
410   if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
411      /* test that mapsize is a power of two */
412      if (_mesa_bitcount((GLuint) mapsize) != 1) {
413	 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
414         return;
415      }
416   }
417
418   FLUSH_VERTICES(ctx, _NEW_PIXEL);
419
420   if (ctx->Unpack.BufferObj->Name) {
421      /* unpack pixelmap from PBO */
422      GLubyte *buf;
423      /* Note, need to use DefaultPacking and Unpack's buffer object */
424      ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
425      if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1,
426                                     GL_INTENSITY, GL_UNSIGNED_INT, values)) {
427         _mesa_error(ctx, GL_INVALID_OPERATION,
428                     "glPixelMapuiv(invalid PBO access)");
429         return;
430      }
431      /* restore */
432      ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
433      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
434                                              GL_READ_ONLY_ARB,
435                                              ctx->Unpack.BufferObj);
436      if (!buf) {
437         /* buffer is already mapped - that's an error */
438         _mesa_error(ctx, GL_INVALID_OPERATION,
439                     "glPixelMapuiv(PBO is mapped)");
440         return;
441      }
442      values = (const GLuint *) ADD_POINTERS(buf, values);
443   }
444   else if (!values) {
445      return;
446   }
447
448   /* convert to floats */
449   if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
450      GLint i;
451      for (i = 0; i < mapsize; i++) {
452         fvalues[i] = (GLfloat) values[i];
453      }
454   }
455   else {
456      GLint i;
457      for (i = 0; i < mapsize; i++) {
458         fvalues[i] = UINT_TO_FLOAT( values[i] );
459      }
460   }
461
462   if (ctx->Unpack.BufferObj->Name) {
463      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
464                              ctx->Unpack.BufferObj);
465   }
466
467   pixelmap(ctx, map, mapsize, fvalues);
468}
469
470
471
472void GLAPIENTRY
473_mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
474{
475   GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
476   GET_CURRENT_CONTEXT(ctx);
477   ASSERT_OUTSIDE_BEGIN_END(ctx);
478
479   if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
480      _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" );
481      return;
482   }
483
484   if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
485      /* test that mapsize is a power of two */
486      if (_mesa_bitcount((GLuint) mapsize) != 1) {
487	 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
488         return;
489      }
490   }
491
492   FLUSH_VERTICES(ctx, _NEW_PIXEL);
493
494   if (ctx->Unpack.BufferObj->Name) {
495      /* unpack pixelmap from PBO */
496      GLubyte *buf;
497      /* Note, need to use DefaultPacking and Unpack's buffer object */
498      ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
499      if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1,
500                                     GL_INTENSITY, GL_UNSIGNED_SHORT,
501                                     values)) {
502         _mesa_error(ctx, GL_INVALID_OPERATION,
503                     "glPixelMapusv(invalid PBO access)");
504         return;
505      }
506      /* restore */
507      ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
508      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
509                                              GL_READ_ONLY_ARB,
510                                              ctx->Unpack.BufferObj);
511      if (!buf) {
512         /* buffer is already mapped - that's an error */
513         _mesa_error(ctx, GL_INVALID_OPERATION,
514                     "glPixelMapusv(PBO is mapped)");
515         return;
516      }
517      values = (const GLushort *) ADD_POINTERS(buf, values);
518   }
519   else if (!values) {
520      return;
521   }
522
523    /* convert to floats */
524   if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
525      GLint i;
526      for (i = 0; i < mapsize; i++) {
527         fvalues[i] = (GLfloat) values[i];
528      }
529   }
530   else {
531      GLint i;
532      for (i = 0; i < mapsize; i++) {
533         fvalues[i] = USHORT_TO_FLOAT( values[i] );
534      }
535   }
536
537   if (ctx->Unpack.BufferObj->Name) {
538      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
539                              ctx->Unpack.BufferObj);
540   }
541
542   pixelmap(ctx, map, mapsize, fvalues);
543}
544
545
546/**
547 * Return size of the named map.
548 */
549static GLuint
550get_map_size(GLcontext *ctx, GLenum map)
551{
552   switch (map) {
553      case GL_PIXEL_MAP_I_TO_I:
554         return ctx->Pixel.MapItoIsize;
555      case GL_PIXEL_MAP_S_TO_S:
556         return ctx->Pixel.MapStoSsize;
557      case GL_PIXEL_MAP_I_TO_R:
558         return ctx->Pixel.MapItoRsize;
559      case GL_PIXEL_MAP_I_TO_G:
560         return ctx->Pixel.MapItoGsize;
561      case GL_PIXEL_MAP_I_TO_B:
562         return ctx->Pixel.MapItoBsize;
563      case GL_PIXEL_MAP_I_TO_A:
564         return ctx->Pixel.MapItoAsize;
565      case GL_PIXEL_MAP_R_TO_R:
566         return ctx->Pixel.MapRtoRsize;
567      case GL_PIXEL_MAP_G_TO_G:
568         return ctx->Pixel.MapGtoGsize;
569      case GL_PIXEL_MAP_B_TO_B:
570         return ctx->Pixel.MapBtoBsize;
571      case GL_PIXEL_MAP_A_TO_A:
572         return ctx->Pixel.MapAtoAsize;
573      default:
574         return 0;
575   }
576}
577
578
579void GLAPIENTRY
580_mesa_GetPixelMapfv( GLenum map, GLfloat *values )
581{
582   GET_CURRENT_CONTEXT(ctx);
583   GLuint mapsize, i;
584   ASSERT_OUTSIDE_BEGIN_END(ctx);
585
586   mapsize = get_map_size(ctx, map);
587
588   if (ctx->Pack.BufferObj->Name) {
589      /* pack pixelmap into PBO */
590      GLubyte *buf;
591      /* Note, need to use DefaultPacking and Pack's buffer object */
592      ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
593      if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1,
594                                     GL_INTENSITY, GL_FLOAT, values)) {
595         _mesa_error(ctx, GL_INVALID_OPERATION,
596                     "glGetPixelMapfv(invalid PBO access)");
597         return;
598      }
599      /* restore */
600      ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
601      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
602                                              GL_WRITE_ONLY_ARB,
603                                              ctx->Pack.BufferObj);
604      if (!buf) {
605         /* buffer is already mapped - that's an error */
606         _mesa_error(ctx, GL_INVALID_OPERATION,
607                     "glGetPixelMapfv(PBO is mapped)");
608         return;
609      }
610      values = (GLfloat *) ADD_POINTERS(buf, values);
611   }
612   else if (!values) {
613      return;
614   }
615
616   switch (map) {
617      case GL_PIXEL_MAP_I_TO_I:
618         for (i = 0; i < mapsize; i++) {
619	    values[i] = (GLfloat) ctx->Pixel.MapItoI[i];
620	 }
621	 break;
622      case GL_PIXEL_MAP_S_TO_S:
623         for (i = 0; i < mapsize; i++) {
624	    values[i] = (GLfloat) ctx->Pixel.MapStoS[i];
625	 }
626	 break;
627      case GL_PIXEL_MAP_I_TO_R:
628         MEMCPY(values, ctx->Pixel.MapItoR, mapsize * sizeof(GLfloat));
629	 break;
630      case GL_PIXEL_MAP_I_TO_G:
631         MEMCPY(values, ctx->Pixel.MapItoG, mapsize * sizeof(GLfloat));
632	 break;
633      case GL_PIXEL_MAP_I_TO_B:
634         MEMCPY(values, ctx->Pixel.MapItoB, mapsize * sizeof(GLfloat));
635	 break;
636      case GL_PIXEL_MAP_I_TO_A:
637         MEMCPY(values, ctx->Pixel.MapItoA, mapsize * sizeof(GLfloat));
638	 break;
639      case GL_PIXEL_MAP_R_TO_R:
640         MEMCPY(values, ctx->Pixel.MapRtoR, mapsize * sizeof(GLfloat));
641	 break;
642      case GL_PIXEL_MAP_G_TO_G:
643         MEMCPY(values, ctx->Pixel.MapGtoG, mapsize * sizeof(GLfloat));
644	 break;
645      case GL_PIXEL_MAP_B_TO_B:
646         MEMCPY(values, ctx->Pixel.MapBtoB, mapsize * sizeof(GLfloat));
647	 break;
648      case GL_PIXEL_MAP_A_TO_A:
649         MEMCPY(values, ctx->Pixel.MapAtoA, mapsize * sizeof(GLfloat));
650	 break;
651      default:
652         _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
653   }
654
655   if (ctx->Pack.BufferObj->Name) {
656      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
657                              ctx->Pack.BufferObj);
658   }
659}
660
661
662void GLAPIENTRY
663_mesa_GetPixelMapuiv( GLenum map, GLuint *values )
664{
665   GET_CURRENT_CONTEXT(ctx);
666   GLint mapsize, i;
667   ASSERT_OUTSIDE_BEGIN_END(ctx);
668
669   mapsize = get_map_size(ctx, map);
670
671   if (ctx->Pack.BufferObj->Name) {
672      /* pack pixelmap into PBO */
673      GLubyte *buf;
674      /* Note, need to use DefaultPacking and Pack's buffer object */
675      ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
676      if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1,
677                                     GL_INTENSITY, GL_UNSIGNED_INT, values)) {
678         _mesa_error(ctx, GL_INVALID_OPERATION,
679                     "glGetPixelMapuiv(invalid PBO access)");
680         return;
681      }
682      /* restore */
683      ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
684      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
685                                              GL_WRITE_ONLY_ARB,
686                                              ctx->Pack.BufferObj);
687      if (!buf) {
688         /* buffer is already mapped - that's an error */
689         _mesa_error(ctx, GL_INVALID_OPERATION,
690                     "glGetPixelMapuiv(PBO is mapped)");
691         return;
692      }
693      values = (GLuint *) ADD_POINTERS(buf, values);
694   }
695   else if (!values) {
696      return;
697   }
698
699   switch (map) {
700      case GL_PIXEL_MAP_I_TO_I:
701         MEMCPY(values, ctx->Pixel.MapItoI, mapsize * sizeof(GLint));
702	 break;
703      case GL_PIXEL_MAP_S_TO_S:
704         MEMCPY(values, ctx->Pixel.MapStoS, mapsize * sizeof(GLint));
705	 break;
706      case GL_PIXEL_MAP_I_TO_R:
707	 for (i = 0; i < mapsize; i++) {
708	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoR[i] );
709	 }
710	 break;
711      case GL_PIXEL_MAP_I_TO_G:
712	 for (i = 0; i < mapsize; i++) {
713	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoG[i] );
714	 }
715	 break;
716      case GL_PIXEL_MAP_I_TO_B:
717	 for (i = 0; i < mapsize; i++) {
718	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoB[i] );
719	 }
720	 break;
721      case GL_PIXEL_MAP_I_TO_A:
722	 for (i = 0; i < mapsize; i++) {
723	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoA[i] );
724	 }
725	 break;
726      case GL_PIXEL_MAP_R_TO_R:
727	 for (i = 0; i < mapsize; i++) {
728	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapRtoR[i] );
729	 }
730	 break;
731      case GL_PIXEL_MAP_G_TO_G:
732	 for (i = 0; i < mapsize; i++) {
733	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapGtoG[i] );
734	 }
735	 break;
736      case GL_PIXEL_MAP_B_TO_B:
737	 for (i = 0; i < mapsize; i++) {
738	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapBtoB[i] );
739	 }
740	 break;
741      case GL_PIXEL_MAP_A_TO_A:
742	 for (i = 0; i < mapsize; i++) {
743	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapAtoA[i] );
744	 }
745	 break;
746      default:
747         _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
748   }
749
750   if (ctx->Pack.BufferObj->Name) {
751      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
752                              ctx->Pack.BufferObj);
753   }
754}
755
756
757void GLAPIENTRY
758_mesa_GetPixelMapusv( GLenum map, GLushort *values )
759{
760   GET_CURRENT_CONTEXT(ctx);
761   GLint mapsize, i;
762   ASSERT_OUTSIDE_BEGIN_END(ctx);
763
764   mapsize = get_map_size(ctx, map);
765
766   if (ctx->Pack.BufferObj->Name) {
767      /* pack pixelmap into PBO */
768      GLubyte *buf;
769      /* Note, need to use DefaultPacking and Pack's buffer object */
770      ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
771      if (!_mesa_validate_pbo_access(&ctx->DefaultPacking, mapsize, 1, 1,
772                                     GL_INTENSITY, GL_UNSIGNED_SHORT,
773                                     values)) {
774         _mesa_error(ctx, GL_INVALID_OPERATION,
775                     "glGetPixelMapusv(invalid PBO access)");
776         return;
777      }
778      /* restore */
779      ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
780      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
781                                              GL_WRITE_ONLY_ARB,
782                                              ctx->Pack.BufferObj);
783      if (!buf) {
784         /* buffer is already mapped - that's an error */
785         _mesa_error(ctx, GL_INVALID_OPERATION,
786                     "glGetPixelMapusv(PBO is mapped)");
787         return;
788      }
789      values = (GLushort *) ADD_POINTERS(buf, values);
790   }
791   else if (!values) {
792      return;
793   }
794
795   switch (map) {
796      case GL_PIXEL_MAP_I_TO_I:
797	 for (i = 0; i < mapsize; i++) {
798	    values[i] = (GLushort) ctx->Pixel.MapItoI[i];
799	 }
800	 break;
801      case GL_PIXEL_MAP_S_TO_S:
802	 for (i = 0; i < mapsize; i++) {
803	    values[i] = (GLushort) ctx->Pixel.MapStoS[i];
804	 }
805	 break;
806      case GL_PIXEL_MAP_I_TO_R:
807	 for (i = 0; i < mapsize; i++) {
808	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoR[i] );
809	 }
810	 break;
811      case GL_PIXEL_MAP_I_TO_G:
812	 for (i = 0; i < mapsize; i++) {
813	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoG[i] );
814	 }
815	 break;
816      case GL_PIXEL_MAP_I_TO_B:
817	 for (i = 0; i < mapsize; i++) {
818	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoB[i] );
819	 }
820	 break;
821      case GL_PIXEL_MAP_I_TO_A:
822	 for (i = 0; i < mapsize; i++) {
823	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoA[i] );
824	 }
825	 break;
826      case GL_PIXEL_MAP_R_TO_R:
827	 for (i = 0; i < mapsize; i++) {
828	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapRtoR[i] );
829	 }
830	 break;
831      case GL_PIXEL_MAP_G_TO_G:
832	 for (i = 0; i < mapsize; i++) {
833	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapGtoG[i] );
834	 }
835	 break;
836      case GL_PIXEL_MAP_B_TO_B:
837	 for (i = 0; i < mapsize; i++) {
838	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapBtoB[i] );
839	 }
840	 break;
841      case GL_PIXEL_MAP_A_TO_A:
842	 for (i = 0; i < mapsize; i++) {
843	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapAtoA[i] );
844	 }
845	 break;
846      default:
847         _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
848   }
849
850   if (ctx->Pack.BufferObj->Name) {
851      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
852                              ctx->Pack.BufferObj);
853   }
854}
855
856
857
858/**********************************************************************/
859/*****                       glPixelTransfer                      *****/
860/**********************************************************************/
861
862
863/*
864 * Implements glPixelTransfer[fi] whether called immediately or from a
865 * display list.
866 */
867void GLAPIENTRY
868_mesa_PixelTransferf( GLenum pname, GLfloat param )
869{
870   GET_CURRENT_CONTEXT(ctx);
871   ASSERT_OUTSIDE_BEGIN_END(ctx);
872
873   switch (pname) {
874      case GL_MAP_COLOR:
875         if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE))
876	    return;
877	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
878         ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
879	 break;
880      case GL_MAP_STENCIL:
881         if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE))
882	    return;
883	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
884         ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
885	 break;
886      case GL_INDEX_SHIFT:
887         if (ctx->Pixel.IndexShift == (GLint) param)
888	    return;
889	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
890         ctx->Pixel.IndexShift = (GLint) param;
891	 break;
892      case GL_INDEX_OFFSET:
893         if (ctx->Pixel.IndexOffset == (GLint) param)
894	    return;
895	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
896         ctx->Pixel.IndexOffset = (GLint) param;
897	 break;
898      case GL_RED_SCALE:
899         if (ctx->Pixel.RedScale == param)
900	    return;
901	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
902         ctx->Pixel.RedScale = param;
903	 break;
904      case GL_RED_BIAS:
905         if (ctx->Pixel.RedBias == param)
906	    return;
907	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
908         ctx->Pixel.RedBias = param;
909	 break;
910      case GL_GREEN_SCALE:
911         if (ctx->Pixel.GreenScale == param)
912	    return;
913	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
914         ctx->Pixel.GreenScale = param;
915	 break;
916      case GL_GREEN_BIAS:
917         if (ctx->Pixel.GreenBias == param)
918	    return;
919	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
920         ctx->Pixel.GreenBias = param;
921	 break;
922      case GL_BLUE_SCALE:
923         if (ctx->Pixel.BlueScale == param)
924	    return;
925	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
926         ctx->Pixel.BlueScale = param;
927	 break;
928      case GL_BLUE_BIAS:
929         if (ctx->Pixel.BlueBias == param)
930	    return;
931	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
932         ctx->Pixel.BlueBias = param;
933	 break;
934      case GL_ALPHA_SCALE:
935         if (ctx->Pixel.AlphaScale == param)
936	    return;
937	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
938         ctx->Pixel.AlphaScale = param;
939	 break;
940      case GL_ALPHA_BIAS:
941         if (ctx->Pixel.AlphaBias == param)
942	    return;
943	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
944         ctx->Pixel.AlphaBias = param;
945	 break;
946      case GL_DEPTH_SCALE:
947         if (ctx->Pixel.DepthScale == param)
948	    return;
949	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
950         ctx->Pixel.DepthScale = param;
951	 break;
952      case GL_DEPTH_BIAS:
953         if (ctx->Pixel.DepthBias == param)
954	    return;
955	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
956         ctx->Pixel.DepthBias = param;
957	 break;
958      case GL_POST_COLOR_MATRIX_RED_SCALE:
959         if (ctx->Pixel.PostColorMatrixScale[0] == param)
960	    return;
961	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
962         ctx->Pixel.PostColorMatrixScale[0] = param;
963	 break;
964      case GL_POST_COLOR_MATRIX_RED_BIAS:
965         if (ctx->Pixel.PostColorMatrixBias[0] == param)
966	    return;
967	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
968         ctx->Pixel.PostColorMatrixBias[0] = param;
969	 break;
970      case GL_POST_COLOR_MATRIX_GREEN_SCALE:
971         if (ctx->Pixel.PostColorMatrixScale[1] == param)
972	    return;
973	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
974         ctx->Pixel.PostColorMatrixScale[1] = param;
975	 break;
976      case GL_POST_COLOR_MATRIX_GREEN_BIAS:
977         if (ctx->Pixel.PostColorMatrixBias[1] == param)
978	    return;
979	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
980         ctx->Pixel.PostColorMatrixBias[1] = param;
981	 break;
982      case GL_POST_COLOR_MATRIX_BLUE_SCALE:
983         if (ctx->Pixel.PostColorMatrixScale[2] == param)
984	    return;
985	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
986         ctx->Pixel.PostColorMatrixScale[2] = param;
987	 break;
988      case GL_POST_COLOR_MATRIX_BLUE_BIAS:
989         if (ctx->Pixel.PostColorMatrixBias[2] == param)
990	    return;
991	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
992         ctx->Pixel.PostColorMatrixBias[2] = param;
993	 break;
994      case GL_POST_COLOR_MATRIX_ALPHA_SCALE:
995         if (ctx->Pixel.PostColorMatrixScale[3] == param)
996	    return;
997	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
998         ctx->Pixel.PostColorMatrixScale[3] = param;
999	 break;
1000      case GL_POST_COLOR_MATRIX_ALPHA_BIAS:
1001         if (ctx->Pixel.PostColorMatrixBias[3] == param)
1002	    return;
1003	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1004         ctx->Pixel.PostColorMatrixBias[3] = param;
1005	 break;
1006      case GL_POST_CONVOLUTION_RED_SCALE:
1007         if (ctx->Pixel.PostConvolutionScale[0] == param)
1008	    return;
1009	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1010         ctx->Pixel.PostConvolutionScale[0] = param;
1011	 break;
1012      case GL_POST_CONVOLUTION_RED_BIAS:
1013         if (ctx->Pixel.PostConvolutionBias[0] == param)
1014	    return;
1015	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1016         ctx->Pixel.PostConvolutionBias[0] = param;
1017	 break;
1018      case GL_POST_CONVOLUTION_GREEN_SCALE:
1019         if (ctx->Pixel.PostConvolutionScale[1] == param)
1020	    return;
1021	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1022         ctx->Pixel.PostConvolutionScale[1] = param;
1023	 break;
1024      case GL_POST_CONVOLUTION_GREEN_BIAS:
1025         if (ctx->Pixel.PostConvolutionBias[1] == param)
1026	    return;
1027	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1028         ctx->Pixel.PostConvolutionBias[1] = param;
1029	 break;
1030      case GL_POST_CONVOLUTION_BLUE_SCALE:
1031         if (ctx->Pixel.PostConvolutionScale[2] == param)
1032	    return;
1033	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1034         ctx->Pixel.PostConvolutionScale[2] = param;
1035	 break;
1036      case GL_POST_CONVOLUTION_BLUE_BIAS:
1037         if (ctx->Pixel.PostConvolutionBias[2] == param)
1038	    return;
1039	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1040         ctx->Pixel.PostConvolutionBias[2] = param;
1041	 break;
1042      case GL_POST_CONVOLUTION_ALPHA_SCALE:
1043         if (ctx->Pixel.PostConvolutionScale[2] == param)
1044	    return;
1045	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1046         ctx->Pixel.PostConvolutionScale[2] = param;
1047	 break;
1048      case GL_POST_CONVOLUTION_ALPHA_BIAS:
1049         if (ctx->Pixel.PostConvolutionBias[2] == param)
1050	    return;
1051	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
1052         ctx->Pixel.PostConvolutionBias[2] = param;
1053	 break;
1054      default:
1055         _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
1056         return;
1057   }
1058}
1059
1060
1061void GLAPIENTRY
1062_mesa_PixelTransferi( GLenum pname, GLint param )
1063{
1064   _mesa_PixelTransferf( pname, (GLfloat) param );
1065}
1066
1067
1068
1069/**********************************************************************/
1070/*****                  Pixel processing functions               ******/
1071/**********************************************************************/
1072
1073/*
1074 * Apply scale and bias factors to an array of RGBA pixels.
1075 */
1076void
1077_mesa_scale_and_bias_rgba(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
1078                          GLfloat rScale, GLfloat gScale,
1079                          GLfloat bScale, GLfloat aScale,
1080                          GLfloat rBias, GLfloat gBias,
1081                          GLfloat bBias, GLfloat aBias)
1082{
1083   (void) ctx;
1084
1085   if (rScale != 1.0 || rBias != 0.0) {
1086      GLuint i;
1087      for (i = 0; i < n; i++) {
1088         rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias;
1089      }
1090   }
1091   if (gScale != 1.0 || gBias != 0.0) {
1092      GLuint i;
1093      for (i = 0; i < n; i++) {
1094         rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias;
1095      }
1096   }
1097   if (bScale != 1.0 || bBias != 0.0) {
1098      GLuint i;
1099      for (i = 0; i < n; i++) {
1100         rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias;
1101      }
1102   }
1103   if (aScale != 1.0 || aBias != 0.0) {
1104      GLuint i;
1105      for (i = 0; i < n; i++) {
1106         rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias;
1107      }
1108   }
1109}
1110
1111
1112/*
1113 * Apply pixel mapping to an array of floating point RGBA pixels.
1114 */
1115void
1116_mesa_map_rgba( const GLcontext *ctx, GLuint n, GLfloat rgba[][4] )
1117{
1118   const GLfloat rscale = (GLfloat) (ctx->Pixel.MapRtoRsize - 1);
1119   const GLfloat gscale = (GLfloat) (ctx->Pixel.MapGtoGsize - 1);
1120   const GLfloat bscale = (GLfloat) (ctx->Pixel.MapBtoBsize - 1);
1121   const GLfloat ascale = (GLfloat) (ctx->Pixel.MapAtoAsize - 1);
1122   const GLfloat *rMap = ctx->Pixel.MapRtoR;
1123   const GLfloat *gMap = ctx->Pixel.MapGtoG;
1124   const GLfloat *bMap = ctx->Pixel.MapBtoB;
1125   const GLfloat *aMap = ctx->Pixel.MapAtoA;
1126   GLuint i;
1127   for (i=0;i<n;i++) {
1128      GLfloat r = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
1129      GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
1130      GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
1131      GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
1132      rgba[i][RCOMP] = rMap[IROUND(r * rscale)];
1133      rgba[i][GCOMP] = gMap[IROUND(g * gscale)];
1134      rgba[i][BCOMP] = bMap[IROUND(b * bscale)];
1135      rgba[i][ACOMP] = aMap[IROUND(a * ascale)];
1136   }
1137}
1138
1139
1140/*
1141 * Apply the color matrix and post color matrix scaling and biasing.
1142 */
1143void
1144_mesa_transform_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4])
1145{
1146   const GLfloat rs = ctx->Pixel.PostColorMatrixScale[0];
1147   const GLfloat rb = ctx->Pixel.PostColorMatrixBias[0];
1148   const GLfloat gs = ctx->Pixel.PostColorMatrixScale[1];
1149   const GLfloat gb = ctx->Pixel.PostColorMatrixBias[1];
1150   const GLfloat bs = ctx->Pixel.PostColorMatrixScale[2];
1151   const GLfloat bb = ctx->Pixel.PostColorMatrixBias[2];
1152   const GLfloat as = ctx->Pixel.PostColorMatrixScale[3];
1153   const GLfloat ab = ctx->Pixel.PostColorMatrixBias[3];
1154   const GLfloat *m = ctx->ColorMatrixStack.Top->m;
1155   GLuint i;
1156   for (i = 0; i < n; i++) {
1157      const GLfloat r = rgba[i][RCOMP];
1158      const GLfloat g = rgba[i][GCOMP];
1159      const GLfloat b = rgba[i][BCOMP];
1160      const GLfloat a = rgba[i][ACOMP];
1161      rgba[i][RCOMP] = (m[0] * r + m[4] * g + m[ 8] * b + m[12] * a) * rs + rb;
1162      rgba[i][GCOMP] = (m[1] * r + m[5] * g + m[ 9] * b + m[13] * a) * gs + gb;
1163      rgba[i][BCOMP] = (m[2] * r + m[6] * g + m[10] * b + m[14] * a) * bs + bb;
1164      rgba[i][ACOMP] = (m[3] * r + m[7] * g + m[11] * b + m[15] * a) * as + ab;
1165   }
1166}
1167
1168
1169/**
1170 * Apply a color table lookup to an array of floating point RGBA colors.
1171 */
1172void
1173_mesa_lookup_rgba_float(const struct gl_color_table *table,
1174                        GLuint n, GLfloat rgba[][4])
1175{
1176   if (!table->Table || table->Size == 0)
1177      return;
1178
1179   switch (table->Format) {
1180      case GL_INTENSITY:
1181         /* replace RGBA with I */
1182         if (table->Type == GL_FLOAT) {
1183            const GLint max = table->Size - 1;
1184            const GLfloat scale = (GLfloat) max;
1185            const GLfloat *lut = (const GLfloat *) table->Table;
1186            GLuint i;
1187            for (i = 0; i < n; i++) {
1188               GLint j = IROUND(rgba[i][RCOMP] * scale);
1189               GLfloat c = lut[CLAMP(j, 0, max)];
1190               rgba[i][RCOMP] = rgba[i][GCOMP] =
1191                  rgba[i][BCOMP] = rgba[i][ACOMP] = c;
1192            }
1193         }
1194         else {
1195            const GLint max = table->Size - 1;
1196            const GLfloat scale = (GLfloat) max;
1197            const GLchan *lut = (const GLchan *) table->Table;
1198            GLuint i;
1199            for (i = 0; i < n; i++) {
1200               GLint j = IROUND(rgba[i][RCOMP] * scale);
1201               GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
1202               rgba[i][RCOMP] = rgba[i][GCOMP] =
1203                  rgba[i][BCOMP] = rgba[i][ACOMP] = c;
1204            }
1205         }
1206         break;
1207      case GL_LUMINANCE:
1208         /* replace RGB with L */
1209         if (table->Type == GL_FLOAT) {
1210            const GLint max = table->Size - 1;
1211            const GLfloat scale = (GLfloat) max;
1212            const GLfloat *lut = (const GLfloat *) table->Table;
1213            GLuint i;
1214            for (i = 0; i < n; i++) {
1215               GLint j = IROUND(rgba[i][RCOMP] * scale);
1216               GLfloat c = lut[CLAMP(j, 0, max)];
1217               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
1218            }
1219         }
1220         else {
1221            const GLint max = table->Size - 1;
1222            const GLfloat scale = (GLfloat) max;
1223            const GLchan *lut = (const GLchan *) table->Table;
1224            GLuint i;
1225            for (i = 0; i < n; i++) {
1226               GLint j = IROUND(rgba[i][RCOMP] * scale);
1227               GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
1228               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
1229            }
1230         }
1231         break;
1232      case GL_ALPHA:
1233         /* replace A with A */
1234         if (table->Type == GL_FLOAT) {
1235            const GLint max = table->Size - 1;
1236            const GLfloat scale = (GLfloat) max;
1237            const GLfloat *lut = (const GLfloat *) table->Table;
1238            GLuint i;
1239            for (i = 0; i < n; i++) {
1240               GLint j = IROUND(rgba[i][ACOMP] * scale);
1241               rgba[i][ACOMP] = lut[CLAMP(j, 0, max)];
1242            }
1243         }
1244         else {
1245            const GLint max = table->Size - 1;
1246            const GLfloat scale = (GLfloat) max;
1247            const GLchan *lut = (const GLchan *) table->Table;
1248            GLuint i;
1249            for (i = 0; i < n; i++) {
1250               GLint j = IROUND(rgba[i][ACOMP] * scale);
1251               rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
1252            }
1253         }
1254         break;
1255      case GL_LUMINANCE_ALPHA:
1256         /* replace RGBA with LLLA */
1257         if (table->Type == GL_FLOAT) {
1258            const GLint max = table->Size - 1;
1259            const GLfloat scale = (GLfloat) max;
1260            const GLfloat *lut = (const GLfloat *) table->Table;
1261            GLuint i;
1262            for (i = 0; i < n; i++) {
1263               GLint jL = IROUND(rgba[i][RCOMP] * scale);
1264               GLint jA = IROUND(rgba[i][ACOMP] * scale);
1265               GLfloat luminance, alpha;
1266               jL = CLAMP(jL, 0, max);
1267               jA = CLAMP(jA, 0, max);
1268               luminance = lut[jL * 2 + 0];
1269               alpha     = lut[jA * 2 + 1];
1270               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
1271               rgba[i][ACOMP] = alpha;;
1272            }
1273         }
1274         else {
1275            const GLint max = table->Size - 1;
1276            const GLfloat scale = (GLfloat) max;
1277            const GLchan *lut = (const GLchan *) table->Table;
1278            GLuint i;
1279            for (i = 0; i < n; i++) {
1280               GLint jL = IROUND(rgba[i][RCOMP] * scale);
1281               GLint jA = IROUND(rgba[i][ACOMP] * scale);
1282               GLfloat luminance, alpha;
1283               jL = CLAMP(jL, 0, max);
1284               jA = CLAMP(jA, 0, max);
1285               luminance = CHAN_TO_FLOAT(lut[jL * 2 + 0]);
1286               alpha     = CHAN_TO_FLOAT(lut[jA * 2 + 1]);
1287               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
1288               rgba[i][ACOMP] = alpha;;
1289            }
1290         }
1291         break;
1292      case GL_RGB:
1293         /* replace RGB with RGB */
1294         if (table->Type == GL_FLOAT) {
1295            const GLint max = table->Size - 1;
1296            const GLfloat scale = (GLfloat) max;
1297            const GLfloat *lut = (const GLfloat *) table->Table;
1298            GLuint i;
1299            for (i = 0; i < n; i++) {
1300               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1301               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1302               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1303               jR = CLAMP(jR, 0, max);
1304               jG = CLAMP(jG, 0, max);
1305               jB = CLAMP(jB, 0, max);
1306               rgba[i][RCOMP] = lut[jR * 3 + 0];
1307               rgba[i][GCOMP] = lut[jG * 3 + 1];
1308               rgba[i][BCOMP] = lut[jB * 3 + 2];
1309            }
1310         }
1311         else {
1312            const GLint max = table->Size - 1;
1313            const GLfloat scale = (GLfloat) max;
1314            const GLchan *lut = (const GLchan *) table->Table;
1315            GLuint i;
1316            for (i = 0; i < n; i++) {
1317               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1318               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1319               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1320               jR = CLAMP(jR, 0, max);
1321               jG = CLAMP(jG, 0, max);
1322               jB = CLAMP(jB, 0, max);
1323               rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 3 + 0]);
1324               rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 3 + 1]);
1325               rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 3 + 2]);
1326            }
1327         }
1328         break;
1329      case GL_RGBA:
1330         /* replace RGBA with RGBA */
1331         if (table->Type == GL_FLOAT) {
1332            const GLint max = table->Size - 1;
1333            const GLfloat scale = (GLfloat) max;
1334            const GLfloat *lut = (const GLfloat *) table->Table;
1335            GLuint i;
1336            for (i = 0; i < n; i++) {
1337               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1338               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1339               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1340               GLint jA = IROUND(rgba[i][ACOMP] * scale);
1341               jR = CLAMP(jR, 0, max);
1342               jG = CLAMP(jG, 0, max);
1343               jB = CLAMP(jB, 0, max);
1344               jA = CLAMP(jA, 0, max);
1345               rgba[i][RCOMP] = lut[jR * 4 + 0];
1346               rgba[i][GCOMP] = lut[jG * 4 + 1];
1347               rgba[i][BCOMP] = lut[jB * 4 + 2];
1348               rgba[i][ACOMP] = lut[jA * 4 + 3];
1349            }
1350         }
1351         else {
1352            const GLint max = table->Size - 1;
1353            const GLfloat scale = (GLfloat) max;
1354            const GLchan *lut = (const GLchan *) table->Table;
1355            GLuint i;
1356            for (i = 0; i < n; i++) {
1357               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1358               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1359               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1360               GLint jA = IROUND(rgba[i][ACOMP] * scale);
1361               jR = CLAMP(jR, 0, max);
1362               jG = CLAMP(jG, 0, max);
1363               jB = CLAMP(jB, 0, max);
1364               jA = CLAMP(jA, 0, max);
1365               rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 4 + 0]);
1366               rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 4 + 1]);
1367               rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 4 + 2]);
1368               rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[jA * 4 + 3]);
1369            }
1370         }
1371         break;
1372      default:
1373         _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_float");
1374         return;
1375   }
1376}
1377
1378
1379
1380/**
1381 * Apply a color table lookup to an array of GLchan RGBA colors.
1382 */
1383void
1384_mesa_lookup_rgba_chan(const struct gl_color_table *table,
1385                       GLuint n, GLchan rgba[][4])
1386{
1387   if (!table->Table || table->Size == 0)
1388      return;
1389
1390   switch (table->Format) {
1391      case GL_INTENSITY:
1392         /* replace RGBA with I */
1393         if (table->Type == GL_FLOAT) {
1394            const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1395            const GLfloat *lut = (const GLfloat *) table->Table;
1396            GLuint i;
1397            for (i = 0; i < n; i++) {
1398               GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1399               GLchan c;
1400               CLAMPED_FLOAT_TO_CHAN(c, lut[j]);
1401               rgba[i][RCOMP] = rgba[i][GCOMP] =
1402                  rgba[i][BCOMP] = rgba[i][ACOMP] = c;
1403            }
1404         }
1405         else {
1406#if CHAN_TYPE == GL_UNSIGNED_BYTE
1407            if (table->Size == 256) {
1408               /* common case */
1409               const GLchan *lut = (const GLchan *) table->Table;
1410               GLuint i;
1411               for (i = 0; i < n; i++) {
1412                  const GLchan c = lut[rgba[i][RCOMP]];
1413                  rgba[i][RCOMP] = rgba[i][GCOMP] =
1414                     rgba[i][BCOMP] = rgba[i][ACOMP] = c;
1415               }
1416            }
1417            else
1418#endif
1419            {
1420               const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1421               const GLchan *lut = (const GLchan *) table->Table;
1422               GLuint i;
1423               for (i = 0; i < n; i++) {
1424                  GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1425                  rgba[i][RCOMP] = rgba[i][GCOMP] =
1426                     rgba[i][BCOMP] = rgba[i][ACOMP] = lut[j];
1427               }
1428            }
1429         }
1430         break;
1431      case GL_LUMINANCE:
1432         /* replace RGB with L */
1433         if (table->Type == GL_FLOAT) {
1434            const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1435            const GLfloat *lut = (const GLfloat *) table->Table;
1436            GLuint i;
1437            for (i = 0; i < n; i++) {
1438               GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1439               GLchan c;
1440               CLAMPED_FLOAT_TO_CHAN(c, lut[j]);
1441               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
1442            }
1443         }
1444         else {
1445#if CHAN_TYPE == GL_UNSIGNED_BYTE
1446            if (table->Size == 256) {
1447               /* common case */
1448               const GLchan *lut = (const GLchan *) table->Table;
1449               GLuint i;
1450               for (i = 0; i < n; i++) {
1451                  const GLchan c = lut[rgba[i][RCOMP]];
1452                  rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
1453               }
1454            }
1455            else
1456#endif
1457            {
1458               const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1459               const GLchan *lut = (const GLchan *) table->Table;
1460               GLuint i;
1461               for (i = 0; i < n; i++) {
1462                  GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1463                  rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = lut[j];
1464               }
1465            }
1466         }
1467         break;
1468      case GL_ALPHA:
1469         /* replace A with A */
1470         if (table->Type == GL_FLOAT) {
1471            const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1472            const GLfloat *lut = (const GLfloat *) table->Table;
1473            GLuint i;
1474            for (i = 0; i < n; i++) {
1475               GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1476               GLchan c;
1477               CLAMPED_FLOAT_TO_CHAN(c, lut[j]);
1478               rgba[i][ACOMP] = c;
1479            }
1480         }
1481         else {
1482#if CHAN_TYPE == GL_UNSIGNED_BYTE
1483            if (table->Size == 256) {
1484               /* common case */
1485               const GLchan *lut = (const GLchan *) table->Table;
1486               GLuint i;
1487               for (i = 0; i < n; i++) {
1488                  rgba[i][ACOMP] = lut[rgba[i][ACOMP]];
1489               }
1490            }
1491            else
1492#endif
1493            {
1494               const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1495               const GLchan *lut = (const GLchan *) table->Table;
1496               GLuint i;
1497               for (i = 0; i < n; i++) {
1498                  GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1499                  rgba[i][ACOMP] = lut[j];
1500               }
1501            }
1502         }
1503         break;
1504      case GL_LUMINANCE_ALPHA:
1505         /* replace RGBA with LLLA */
1506         if (table->Type == GL_FLOAT) {
1507            const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1508            const GLfloat *lut = (const GLfloat *) table->Table;
1509            GLuint i;
1510            for (i = 0; i < n; i++) {
1511               GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1512               GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1513               GLchan luminance, alpha;
1514               CLAMPED_FLOAT_TO_CHAN(luminance, lut[jL * 2 + 0]);
1515               CLAMPED_FLOAT_TO_CHAN(alpha, lut[jA * 2 + 1]);
1516               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
1517               rgba[i][ACOMP] = alpha;;
1518            }
1519         }
1520         else {
1521#if CHAN_TYPE == GL_UNSIGNED_BYTE
1522            if (table->Size == 256) {
1523               /* common case */
1524               const GLchan *lut = (const GLchan *) table->Table;
1525               GLuint i;
1526               for (i = 0; i < n; i++) {
1527                  GLchan l = lut[rgba[i][RCOMP] * 2 + 0];
1528                  GLchan a = lut[rgba[i][ACOMP] * 2 + 1];;
1529                  rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = l;
1530                  rgba[i][ACOMP] = a;
1531               }
1532            }
1533            else
1534#endif
1535            {
1536               const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1537               const GLchan *lut = (const GLchan *) table->Table;
1538               GLuint i;
1539               for (i = 0; i < n; i++) {
1540                  GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1541                  GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1542                  GLchan luminance = lut[jL * 2 + 0];
1543                  GLchan alpha     = lut[jA * 2 + 1];
1544                  rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
1545                  rgba[i][ACOMP] = alpha;
1546               }
1547            }
1548         }
1549         break;
1550      case GL_RGB:
1551         /* replace RGB with RGB */
1552         if (table->Type == GL_FLOAT) {
1553            const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1554            const GLfloat *lut = (const GLfloat *) table->Table;
1555            GLuint i;
1556            for (i = 0; i < n; i++) {
1557               GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1558               GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1559               GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1560               CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 3 + 0]);
1561               CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 3 + 1]);
1562               CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 3 + 2]);
1563            }
1564         }
1565         else {
1566#if CHAN_TYPE == GL_UNSIGNED_BYTE
1567            if (table->Size == 256) {
1568               /* common case */
1569               const GLchan *lut = (const GLchan *) table->Table;
1570               GLuint i;
1571               for (i = 0; i < n; i++) {
1572                  rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 3 + 0];
1573                  rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 3 + 1];
1574                  rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 3 + 2];
1575               }
1576            }
1577            else
1578#endif
1579            {
1580               const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1581               const GLchan *lut = (const GLchan *) table->Table;
1582               GLuint i;
1583               for (i = 0; i < n; i++) {
1584                  GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1585                  GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1586                  GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1587                  rgba[i][RCOMP] = lut[jR * 3 + 0];
1588                  rgba[i][GCOMP] = lut[jG * 3 + 1];
1589                  rgba[i][BCOMP] = lut[jB * 3 + 2];
1590               }
1591            }
1592         }
1593         break;
1594      case GL_RGBA:
1595         /* replace RGBA with RGBA */
1596         if (table->Type == GL_FLOAT) {
1597            const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1598            const GLfloat *lut = (const GLfloat *) table->Table;
1599            GLuint i;
1600            for (i = 0; i < n; i++) {
1601               GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1602               GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1603               GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1604               GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1605               CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]);
1606               CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]);
1607               CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]);
1608               CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]);
1609            }
1610         }
1611         else {
1612#if CHAN_TYPE == GL_UNSIGNED_BYTE
1613            if (table->Size == 256) {
1614               /* common case */
1615               const GLchan *lut = (const GLchan *) table->Table;
1616               GLuint i;
1617               for (i = 0; i < n; i++) {
1618                  rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 4 + 0];
1619                  rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 4 + 1];
1620                  rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 4 + 2];
1621                  rgba[i][ACOMP] = lut[rgba[i][ACOMP] * 4 + 3];
1622               }
1623            }
1624            else
1625#endif
1626            {
1627               const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1628               const GLfloat *lut = (const GLfloat *) table->Table;
1629               GLuint i;
1630               for (i = 0; i < n; i++) {
1631                  GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1632                  GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1633                  GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1634                  GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1635                  CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]);
1636                  CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]);
1637                  CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]);
1638                  CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]);
1639               }
1640            }
1641         }
1642         break;
1643      default:
1644         _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_chan");
1645         return;
1646   }
1647}
1648
1649
1650
1651/*
1652 * Apply color index shift and offset to an array of pixels.
1653 */
1654void
1655_mesa_shift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] )
1656{
1657   GLint shift = ctx->Pixel.IndexShift;
1658   GLint offset = ctx->Pixel.IndexOffset;
1659   GLuint i;
1660   if (shift > 0) {
1661      for (i=0;i<n;i++) {
1662         indexes[i] = (indexes[i] << shift) + offset;
1663      }
1664   }
1665   else if (shift < 0) {
1666      shift = -shift;
1667      for (i=0;i<n;i++) {
1668         indexes[i] = (indexes[i] >> shift) + offset;
1669      }
1670   }
1671   else {
1672      for (i=0;i<n;i++) {
1673         indexes[i] = indexes[i] + offset;
1674      }
1675   }
1676}
1677
1678
1679/*
1680 * Apply color index mapping to color indexes.
1681 */
1682void
1683_mesa_map_ci( const GLcontext *ctx, GLuint n, GLuint index[] )
1684{
1685   GLuint mask = ctx->Pixel.MapItoIsize - 1;
1686   GLuint i;
1687   for (i=0;i<n;i++) {
1688      index[i] = ctx->Pixel.MapItoI[ index[i] & mask ];
1689   }
1690}
1691
1692
1693/*
1694 * Map color indexes to rgba values.
1695 */
1696void
1697_mesa_map_ci_to_rgba_chan( const GLcontext *ctx, GLuint n,
1698                           const GLuint index[], GLchan rgba[][4] )
1699{
1700#if CHAN_BITS == 8
1701   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1702   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1703   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1704   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1705   const GLubyte *rMap = ctx->Pixel.MapItoR8;
1706   const GLubyte *gMap = ctx->Pixel.MapItoG8;
1707   const GLubyte *bMap = ctx->Pixel.MapItoB8;
1708   const GLubyte *aMap = ctx->Pixel.MapItoA8;
1709   GLuint i;
1710   for (i=0;i<n;i++) {
1711      rgba[i][RCOMP] = rMap[index[i] & rmask];
1712      rgba[i][GCOMP] = gMap[index[i] & gmask];
1713      rgba[i][BCOMP] = bMap[index[i] & bmask];
1714      rgba[i][ACOMP] = aMap[index[i] & amask];
1715   }
1716#else
1717   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1718   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1719   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1720   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1721   const GLfloat *rMap = ctx->Pixel.MapItoR;
1722   const GLfloat *gMap = ctx->Pixel.MapItoG;
1723   const GLfloat *bMap = ctx->Pixel.MapItoB;
1724   const GLfloat *aMap = ctx->Pixel.MapItoA;
1725   GLuint i;
1726   for (i=0;i<n;i++) {
1727      CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]);
1728      CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]);
1729      CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]);
1730      CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]);
1731   }
1732#endif
1733}
1734
1735
1736/*
1737 * Map color indexes to float rgba values.
1738 */
1739void
1740_mesa_map_ci_to_rgba( const GLcontext *ctx, GLuint n,
1741                      const GLuint index[], GLfloat rgba[][4] )
1742{
1743   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1744   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1745   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1746   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1747   const GLfloat *rMap = ctx->Pixel.MapItoR;
1748   const GLfloat *gMap = ctx->Pixel.MapItoG;
1749   const GLfloat *bMap = ctx->Pixel.MapItoB;
1750   const GLfloat *aMap = ctx->Pixel.MapItoA;
1751   GLuint i;
1752   for (i=0;i<n;i++) {
1753      rgba[i][RCOMP] = rMap[index[i] & rmask];
1754      rgba[i][GCOMP] = gMap[index[i] & gmask];
1755      rgba[i][BCOMP] = bMap[index[i] & bmask];
1756      rgba[i][ACOMP] = aMap[index[i] & amask];
1757   }
1758}
1759
1760
1761/*
1762 * Map 8-bit color indexes to rgb values.
1763 */
1764void
1765_mesa_map_ci8_to_rgba( const GLcontext *ctx, GLuint n, const GLubyte index[],
1766                       GLchan rgba[][4] )
1767{
1768#if CHAN_BITS == 8
1769   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1770   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1771   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1772   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1773   const GLubyte *rMap = ctx->Pixel.MapItoR8;
1774   const GLubyte *gMap = ctx->Pixel.MapItoG8;
1775   const GLubyte *bMap = ctx->Pixel.MapItoB8;
1776   const GLubyte *aMap = ctx->Pixel.MapItoA8;
1777   GLuint i;
1778   for (i=0;i<n;i++) {
1779      rgba[i][RCOMP] = rMap[index[i] & rmask];
1780      rgba[i][GCOMP] = gMap[index[i] & gmask];
1781      rgba[i][BCOMP] = bMap[index[i] & bmask];
1782      rgba[i][ACOMP] = aMap[index[i] & amask];
1783   }
1784#else
1785   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1786   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1787   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1788   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1789   const GLfloat *rMap = ctx->Pixel.MapItoR;
1790   const GLfloat *gMap = ctx->Pixel.MapItoG;
1791   const GLfloat *bMap = ctx->Pixel.MapItoB;
1792   const GLfloat *aMap = ctx->Pixel.MapItoA;
1793   GLuint i;
1794   for (i=0;i<n;i++) {
1795      CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]);
1796      CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]);
1797      CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]);
1798      CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]);
1799   }
1800#endif
1801}
1802
1803
1804void
1805_mesa_shift_and_offset_stencil( const GLcontext *ctx, GLuint n,
1806                                GLstencil stencil[] )
1807{
1808   GLuint i;
1809   GLint shift = ctx->Pixel.IndexShift;
1810   GLint offset = ctx->Pixel.IndexOffset;
1811   if (shift > 0) {
1812      for (i=0;i<n;i++) {
1813         stencil[i] = (stencil[i] << shift) + offset;
1814      }
1815   }
1816   else if (shift < 0) {
1817      shift = -shift;
1818      for (i=0;i<n;i++) {
1819         stencil[i] = (stencil[i] >> shift) + offset;
1820      }
1821   }
1822   else {
1823      for (i=0;i<n;i++) {
1824         stencil[i] = stencil[i] + offset;
1825      }
1826   }
1827
1828}
1829
1830
1831void
1832_mesa_map_stencil( const GLcontext *ctx, GLuint n, GLstencil stencil[] )
1833{
1834   GLuint mask = ctx->Pixel.MapStoSsize - 1;
1835   GLuint i;
1836   for (i=0;i<n;i++) {
1837      stencil[i] = ctx->Pixel.MapStoS[ stencil[i] & mask ];
1838   }
1839}
1840
1841
1842
1843/*
1844 * This function converts an array of GLchan colors to GLfloat colors.
1845 * Most importantly, it undoes the non-uniform quantization of pixel
1846 * values introduced when we convert shallow (< 8 bit) pixel values
1847 * to GLubytes in the ctx->Driver.ReadRGBASpan() functions.
1848 * This fixes a number of OpenGL conformance failures when running on
1849 * 16bpp displays, for example.
1850 */
1851void
1852_mesa_chan_to_float_span(const GLcontext *ctx, GLuint n,
1853                         CONST GLchan rgba[][4], GLfloat rgbaf[][4])
1854{
1855#if CHAN_TYPE == GL_FLOAT
1856   MEMCPY(rgbaf, rgba, n * 4 * sizeof(GLfloat));
1857#else
1858   const GLuint rShift = CHAN_BITS - ctx->Visual.redBits;
1859   const GLuint gShift = CHAN_BITS - ctx->Visual.greenBits;
1860   const GLuint bShift = CHAN_BITS - ctx->Visual.blueBits;
1861   GLuint aShift;
1862   const GLfloat rScale = 1.0F / (GLfloat) ((1 << ctx->Visual.redBits  ) - 1);
1863   const GLfloat gScale = 1.0F / (GLfloat) ((1 << ctx->Visual.greenBits) - 1);
1864   const GLfloat bScale = 1.0F / (GLfloat) ((1 << ctx->Visual.blueBits ) - 1);
1865   GLfloat aScale;
1866   GLuint i;
1867
1868   if (ctx->Visual.alphaBits > 0) {
1869      aShift = CHAN_BITS - ctx->Visual.alphaBits;
1870      aScale = 1.0F / (GLfloat) ((1 << ctx->Visual.alphaBits) - 1);
1871   }
1872   else {
1873      aShift = 0;
1874      aScale = 1.0F / CHAN_MAXF;
1875   }
1876
1877   for (i = 0; i < n; i++) {
1878      const GLint r = rgba[i][RCOMP] >> rShift;
1879      const GLint g = rgba[i][GCOMP] >> gShift;
1880      const GLint b = rgba[i][BCOMP] >> bShift;
1881      const GLint a = rgba[i][ACOMP] >> aShift;
1882      rgbaf[i][RCOMP] = (GLfloat) r * rScale;
1883      rgbaf[i][GCOMP] = (GLfloat) g * gScale;
1884      rgbaf[i][BCOMP] = (GLfloat) b * bScale;
1885      rgbaf[i][ACOMP] = (GLfloat) a * aScale;
1886   }
1887#endif
1888}
1889
1890/**********************************************************************/
1891/*****                    State Management                        *****/
1892/**********************************************************************/
1893
1894/*
1895 * Return a bitmask of IMAGE_*_BIT flags which to indicate which
1896 * pixel transfer operations are enabled.
1897 */
1898static void
1899update_image_transfer_state(GLcontext *ctx)
1900{
1901   GLuint mask = 0;
1902
1903   if (ctx->Pixel.RedScale   != 1.0F || ctx->Pixel.RedBias   != 0.0F ||
1904       ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F ||
1905       ctx->Pixel.BlueScale  != 1.0F || ctx->Pixel.BlueBias  != 0.0F ||
1906       ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F)
1907      mask |= IMAGE_SCALE_BIAS_BIT;
1908
1909   if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset)
1910      mask |= IMAGE_SHIFT_OFFSET_BIT;
1911
1912   if (ctx->Pixel.MapColorFlag)
1913      mask |= IMAGE_MAP_COLOR_BIT;
1914
1915   if (ctx->Pixel.ColorTableEnabled)
1916      mask |= IMAGE_COLOR_TABLE_BIT;
1917
1918   if (ctx->Pixel.Convolution1DEnabled ||
1919       ctx->Pixel.Convolution2DEnabled ||
1920       ctx->Pixel.Separable2DEnabled) {
1921      mask |= IMAGE_CONVOLUTION_BIT;
1922      if (ctx->Pixel.PostConvolutionScale[0] != 1.0F ||
1923          ctx->Pixel.PostConvolutionScale[1] != 1.0F ||
1924          ctx->Pixel.PostConvolutionScale[2] != 1.0F ||
1925          ctx->Pixel.PostConvolutionScale[3] != 1.0F ||
1926          ctx->Pixel.PostConvolutionBias[0] != 0.0F ||
1927          ctx->Pixel.PostConvolutionBias[1] != 0.0F ||
1928          ctx->Pixel.PostConvolutionBias[2] != 0.0F ||
1929          ctx->Pixel.PostConvolutionBias[3] != 0.0F) {
1930         mask |= IMAGE_POST_CONVOLUTION_SCALE_BIAS;
1931      }
1932   }
1933
1934   if (ctx->Pixel.PostConvolutionColorTableEnabled)
1935      mask |= IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT;
1936
1937   if (ctx->ColorMatrixStack.Top->type != MATRIX_IDENTITY ||
1938       ctx->Pixel.PostColorMatrixScale[0] != 1.0F ||
1939       ctx->Pixel.PostColorMatrixBias[0]  != 0.0F ||
1940       ctx->Pixel.PostColorMatrixScale[1] != 1.0F ||
1941       ctx->Pixel.PostColorMatrixBias[1]  != 0.0F ||
1942       ctx->Pixel.PostColorMatrixScale[2] != 1.0F ||
1943       ctx->Pixel.PostColorMatrixBias[2]  != 0.0F ||
1944       ctx->Pixel.PostColorMatrixScale[3] != 1.0F ||
1945       ctx->Pixel.PostColorMatrixBias[3]  != 0.0F)
1946      mask |= IMAGE_COLOR_MATRIX_BIT;
1947
1948   if (ctx->Pixel.PostColorMatrixColorTableEnabled)
1949      mask |= IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT;
1950
1951   if (ctx->Pixel.HistogramEnabled)
1952      mask |= IMAGE_HISTOGRAM_BIT;
1953
1954   if (ctx->Pixel.MinMaxEnabled)
1955      mask |= IMAGE_MIN_MAX_BIT;
1956
1957   ctx->_ImageTransferState = mask;
1958}
1959
1960
1961void _mesa_update_pixel( GLcontext *ctx, GLuint new_state )
1962{
1963   if (new_state & _NEW_COLOR_MATRIX)
1964      _math_matrix_analyse( ctx->ColorMatrixStack.Top );
1965
1966   /* References ColorMatrix.type (derived above).
1967    */
1968   if (new_state & _IMAGE_NEW_TRANSFER_STATE)
1969      update_image_transfer_state(ctx);
1970}
1971
1972
1973/**********************************************************************/
1974/*****                      Initialization                        *****/
1975/**********************************************************************/
1976
1977
1978/**
1979 * Initialize the context's PIXEL attribute group.
1980 */
1981void
1982_mesa_init_pixel( GLcontext *ctx )
1983{
1984   int i;
1985
1986   /* Pixel group */
1987   ctx->Pixel.RedBias = 0.0;
1988   ctx->Pixel.RedScale = 1.0;
1989   ctx->Pixel.GreenBias = 0.0;
1990   ctx->Pixel.GreenScale = 1.0;
1991   ctx->Pixel.BlueBias = 0.0;
1992   ctx->Pixel.BlueScale = 1.0;
1993   ctx->Pixel.AlphaBias = 0.0;
1994   ctx->Pixel.AlphaScale = 1.0;
1995   ctx->Pixel.DepthBias = 0.0;
1996   ctx->Pixel.DepthScale = 1.0;
1997   ctx->Pixel.IndexOffset = 0;
1998   ctx->Pixel.IndexShift = 0;
1999   ctx->Pixel.ZoomX = 1.0;
2000   ctx->Pixel.ZoomY = 1.0;
2001   ctx->Pixel.MapColorFlag = GL_FALSE;
2002   ctx->Pixel.MapStencilFlag = GL_FALSE;
2003   ctx->Pixel.MapStoSsize = 1;
2004   ctx->Pixel.MapItoIsize = 1;
2005   ctx->Pixel.MapItoRsize = 1;
2006   ctx->Pixel.MapItoGsize = 1;
2007   ctx->Pixel.MapItoBsize = 1;
2008   ctx->Pixel.MapItoAsize = 1;
2009   ctx->Pixel.MapRtoRsize = 1;
2010   ctx->Pixel.MapGtoGsize = 1;
2011   ctx->Pixel.MapBtoBsize = 1;
2012   ctx->Pixel.MapAtoAsize = 1;
2013   ctx->Pixel.MapStoS[0] = 0;
2014   ctx->Pixel.MapItoI[0] = 0;
2015   ctx->Pixel.MapItoR[0] = 0.0;
2016   ctx->Pixel.MapItoG[0] = 0.0;
2017   ctx->Pixel.MapItoB[0] = 0.0;
2018   ctx->Pixel.MapItoA[0] = 0.0;
2019   ctx->Pixel.MapItoR8[0] = 0;
2020   ctx->Pixel.MapItoG8[0] = 0;
2021   ctx->Pixel.MapItoB8[0] = 0;
2022   ctx->Pixel.MapItoA8[0] = 0;
2023   ctx->Pixel.MapRtoR[0] = 0.0;
2024   ctx->Pixel.MapGtoG[0] = 0.0;
2025   ctx->Pixel.MapBtoB[0] = 0.0;
2026   ctx->Pixel.MapAtoA[0] = 0.0;
2027   ctx->Pixel.HistogramEnabled = GL_FALSE;
2028   ctx->Pixel.MinMaxEnabled = GL_FALSE;
2029   ctx->Pixel.PixelTextureEnabled = GL_FALSE;
2030   ctx->Pixel.FragmentRgbSource = GL_PIXEL_GROUP_COLOR_SGIS;
2031   ctx->Pixel.FragmentAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS;
2032   ASSIGN_4V(ctx->Pixel.PostColorMatrixScale, 1.0, 1.0, 1.0, 1.0);
2033   ASSIGN_4V(ctx->Pixel.PostColorMatrixBias, 0.0, 0.0, 0.0, 0.0);
2034   ASSIGN_4V(ctx->Pixel.ColorTableScale, 1.0, 1.0, 1.0, 1.0);
2035   ASSIGN_4V(ctx->Pixel.ColorTableBias, 0.0, 0.0, 0.0, 0.0);
2036   ASSIGN_4V(ctx->Pixel.PCCTscale, 1.0, 1.0, 1.0, 1.0);
2037   ASSIGN_4V(ctx->Pixel.PCCTbias, 0.0, 0.0, 0.0, 0.0);
2038   ASSIGN_4V(ctx->Pixel.PCMCTscale, 1.0, 1.0, 1.0, 1.0);
2039   ASSIGN_4V(ctx->Pixel.PCMCTbias, 0.0, 0.0, 0.0, 0.0);
2040   ctx->Pixel.ColorTableEnabled = GL_FALSE;
2041   ctx->Pixel.PostConvolutionColorTableEnabled = GL_FALSE;
2042   ctx->Pixel.PostColorMatrixColorTableEnabled = GL_FALSE;
2043   ctx->Pixel.Convolution1DEnabled = GL_FALSE;
2044   ctx->Pixel.Convolution2DEnabled = GL_FALSE;
2045   ctx->Pixel.Separable2DEnabled = GL_FALSE;
2046   for (i = 0; i < 3; i++) {
2047      ASSIGN_4V(ctx->Pixel.ConvolutionBorderColor[i], 0.0, 0.0, 0.0, 0.0);
2048      ctx->Pixel.ConvolutionBorderMode[i] = GL_REDUCE;
2049      ASSIGN_4V(ctx->Pixel.ConvolutionFilterScale[i], 1.0, 1.0, 1.0, 1.0);
2050      ASSIGN_4V(ctx->Pixel.ConvolutionFilterBias[i], 0.0, 0.0, 0.0, 0.0);
2051   }
2052   for (i = 0; i < MAX_CONVOLUTION_WIDTH * MAX_CONVOLUTION_WIDTH * 4; i++) {
2053      ctx->Convolution1D.Filter[i] = 0.0;
2054      ctx->Convolution2D.Filter[i] = 0.0;
2055      ctx->Separable2D.Filter[i] = 0.0;
2056   }
2057   ASSIGN_4V(ctx->Pixel.PostConvolutionScale, 1.0, 1.0, 1.0, 1.0);
2058   ASSIGN_4V(ctx->Pixel.PostConvolutionBias, 0.0, 0.0, 0.0, 0.0);
2059   /* GL_SGI_texture_color_table */
2060   ASSIGN_4V(ctx->Pixel.TextureColorTableScale, 1.0, 1.0, 1.0, 1.0);
2061   ASSIGN_4V(ctx->Pixel.TextureColorTableBias, 0.0, 0.0, 0.0, 0.0);
2062
2063   /* Pixel transfer */
2064   ctx->Pack.Alignment = 4;
2065   ctx->Pack.RowLength = 0;
2066   ctx->Pack.ImageHeight = 0;
2067   ctx->Pack.SkipPixels = 0;
2068   ctx->Pack.SkipRows = 0;
2069   ctx->Pack.SkipImages = 0;
2070   ctx->Pack.SwapBytes = GL_FALSE;
2071   ctx->Pack.LsbFirst = GL_FALSE;
2072   ctx->Pack.ClientStorage = GL_FALSE;
2073   ctx->Pack.Invert = GL_FALSE;
2074#if FEATURE_EXT_pixel_buffer_object
2075   ctx->Pack.BufferObj = ctx->Array.NullBufferObj;
2076#endif
2077   ctx->Unpack.Alignment = 4;
2078   ctx->Unpack.RowLength = 0;
2079   ctx->Unpack.ImageHeight = 0;
2080   ctx->Unpack.SkipPixels = 0;
2081   ctx->Unpack.SkipRows = 0;
2082   ctx->Unpack.SkipImages = 0;
2083   ctx->Unpack.SwapBytes = GL_FALSE;
2084   ctx->Unpack.LsbFirst = GL_FALSE;
2085   ctx->Unpack.ClientStorage = GL_FALSE;
2086   ctx->Unpack.Invert = GL_FALSE;
2087#if FEATURE_EXT_pixel_buffer_object
2088   ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;
2089#endif
2090
2091   /*
2092    * _mesa_unpack_image() returns image data in this format.  When we
2093    * execute image commands (glDrawPixels(), glTexImage(), etc) from
2094    * within display lists we have to be sure to set the current
2095    * unpacking parameters to these values!
2096    */
2097   ctx->DefaultPacking.Alignment = 1;
2098   ctx->DefaultPacking.RowLength = 0;
2099   ctx->DefaultPacking.SkipPixels = 0;
2100   ctx->DefaultPacking.SkipRows = 0;
2101   ctx->DefaultPacking.ImageHeight = 0;
2102   ctx->DefaultPacking.SkipImages = 0;
2103   ctx->DefaultPacking.SwapBytes = GL_FALSE;
2104   ctx->DefaultPacking.LsbFirst = GL_FALSE;
2105   ctx->DefaultPacking.ClientStorage = GL_FALSE;
2106   ctx->DefaultPacking.Invert = GL_FALSE;
2107#if FEATURE_EXT_pixel_buffer_object
2108   ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
2109#endif
2110
2111   if (ctx->Visual.doubleBufferMode) {
2112      ctx->Pixel.ReadBuffer = GL_BACK;
2113      ctx->Pixel._ReadSrcMask = DD_BACK_LEFT_BIT;
2114   }
2115   else {
2116      ctx->Pixel.ReadBuffer = GL_FRONT;
2117      ctx->Pixel._ReadSrcMask = DD_FRONT_LEFT_BIT;
2118   }
2119
2120   /* Miscellaneous */
2121   ctx->_ImageTransferState = 0;
2122}
2123