pixel.c revision ac3ec5096a760daabb1f2be7400bd9723e5058a5
1/*
2 * Mesa 3-D graphics library
3 * Version:  6.3
4 *
5 * Copyright (C) 1999-2005  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] = IROUND(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] = 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(1, &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(1, &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(1, &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(1, &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         MEMCPY(values, ctx->Pixel.MapItoI, mapsize * sizeof(GLfloat));
619	 break;
620      case GL_PIXEL_MAP_S_TO_S:
621         for (i = 0; i < mapsize; i++) {
622	    values[i] = (GLfloat) ctx->Pixel.MapStoS[i];
623	 }
624	 break;
625      case GL_PIXEL_MAP_I_TO_R:
626         MEMCPY(values, ctx->Pixel.MapItoR, mapsize * sizeof(GLfloat));
627	 break;
628      case GL_PIXEL_MAP_I_TO_G:
629         MEMCPY(values, ctx->Pixel.MapItoG, mapsize * sizeof(GLfloat));
630	 break;
631      case GL_PIXEL_MAP_I_TO_B:
632         MEMCPY(values, ctx->Pixel.MapItoB, mapsize * sizeof(GLfloat));
633	 break;
634      case GL_PIXEL_MAP_I_TO_A:
635         MEMCPY(values, ctx->Pixel.MapItoA, mapsize * sizeof(GLfloat));
636	 break;
637      case GL_PIXEL_MAP_R_TO_R:
638         MEMCPY(values, ctx->Pixel.MapRtoR, mapsize * sizeof(GLfloat));
639	 break;
640      case GL_PIXEL_MAP_G_TO_G:
641         MEMCPY(values, ctx->Pixel.MapGtoG, mapsize * sizeof(GLfloat));
642	 break;
643      case GL_PIXEL_MAP_B_TO_B:
644         MEMCPY(values, ctx->Pixel.MapBtoB, mapsize * sizeof(GLfloat));
645	 break;
646      case GL_PIXEL_MAP_A_TO_A:
647         MEMCPY(values, ctx->Pixel.MapAtoA, mapsize * sizeof(GLfloat));
648	 break;
649      default:
650         _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
651   }
652
653   if (ctx->Pack.BufferObj->Name) {
654      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
655                              ctx->Pack.BufferObj);
656   }
657}
658
659
660void GLAPIENTRY
661_mesa_GetPixelMapuiv( GLenum map, GLuint *values )
662{
663   GET_CURRENT_CONTEXT(ctx);
664   GLint mapsize, i;
665   ASSERT_OUTSIDE_BEGIN_END(ctx);
666
667   mapsize = get_map_size(ctx, map);
668
669   if (ctx->Pack.BufferObj->Name) {
670      /* pack pixelmap into PBO */
671      GLubyte *buf;
672      /* Note, need to use DefaultPacking and Pack's buffer object */
673      ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
674      if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
675                                     GL_INTENSITY, GL_UNSIGNED_INT, values)) {
676         _mesa_error(ctx, GL_INVALID_OPERATION,
677                     "glGetPixelMapuiv(invalid PBO access)");
678         return;
679      }
680      /* restore */
681      ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
682      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
683                                              GL_WRITE_ONLY_ARB,
684                                              ctx->Pack.BufferObj);
685      if (!buf) {
686         /* buffer is already mapped - that's an error */
687         _mesa_error(ctx, GL_INVALID_OPERATION,
688                     "glGetPixelMapuiv(PBO is mapped)");
689         return;
690      }
691      values = (GLuint *) ADD_POINTERS(buf, values);
692   }
693   else if (!values) {
694      return;
695   }
696
697   switch (map) {
698      case GL_PIXEL_MAP_I_TO_I:
699	 for (i = 0; i < mapsize; i++) {
700	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoI[i] );
701	 }
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(1, &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] = FLOAT_TO_USHORT(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(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   if (rScale != 1.0 || rBias != 0.0) {
1084      GLuint i;
1085      for (i = 0; i < n; i++) {
1086         rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias;
1087      }
1088   }
1089   if (gScale != 1.0 || gBias != 0.0) {
1090      GLuint i;
1091      for (i = 0; i < n; i++) {
1092         rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias;
1093      }
1094   }
1095   if (bScale != 1.0 || bBias != 0.0) {
1096      GLuint i;
1097      for (i = 0; i < n; i++) {
1098         rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias;
1099      }
1100   }
1101   if (aScale != 1.0 || aBias != 0.0) {
1102      GLuint i;
1103      for (i = 0; i < n; i++) {
1104         rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias;
1105      }
1106   }
1107}
1108
1109
1110/*
1111 * Apply pixel mapping to an array of floating point RGBA pixels.
1112 */
1113void
1114_mesa_map_rgba( const GLcontext *ctx, GLuint n, GLfloat rgba[][4] )
1115{
1116   const GLfloat rscale = (GLfloat) (ctx->Pixel.MapRtoRsize - 1);
1117   const GLfloat gscale = (GLfloat) (ctx->Pixel.MapGtoGsize - 1);
1118   const GLfloat bscale = (GLfloat) (ctx->Pixel.MapBtoBsize - 1);
1119   const GLfloat ascale = (GLfloat) (ctx->Pixel.MapAtoAsize - 1);
1120   const GLfloat *rMap = ctx->Pixel.MapRtoR;
1121   const GLfloat *gMap = ctx->Pixel.MapGtoG;
1122   const GLfloat *bMap = ctx->Pixel.MapBtoB;
1123   const GLfloat *aMap = ctx->Pixel.MapAtoA;
1124   GLuint i;
1125   for (i=0;i<n;i++) {
1126      GLfloat r = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
1127      GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
1128      GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
1129      GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
1130      rgba[i][RCOMP] = rMap[IROUND(r * rscale)];
1131      rgba[i][GCOMP] = gMap[IROUND(g * gscale)];
1132      rgba[i][BCOMP] = bMap[IROUND(b * bscale)];
1133      rgba[i][ACOMP] = aMap[IROUND(a * ascale)];
1134   }
1135}
1136
1137
1138/*
1139 * Apply the color matrix and post color matrix scaling and biasing.
1140 */
1141void
1142_mesa_transform_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4])
1143{
1144   const GLfloat rs = ctx->Pixel.PostColorMatrixScale[0];
1145   const GLfloat rb = ctx->Pixel.PostColorMatrixBias[0];
1146   const GLfloat gs = ctx->Pixel.PostColorMatrixScale[1];
1147   const GLfloat gb = ctx->Pixel.PostColorMatrixBias[1];
1148   const GLfloat bs = ctx->Pixel.PostColorMatrixScale[2];
1149   const GLfloat bb = ctx->Pixel.PostColorMatrixBias[2];
1150   const GLfloat as = ctx->Pixel.PostColorMatrixScale[3];
1151   const GLfloat ab = ctx->Pixel.PostColorMatrixBias[3];
1152   const GLfloat *m = ctx->ColorMatrixStack.Top->m;
1153   GLuint i;
1154   for (i = 0; i < n; i++) {
1155      const GLfloat r = rgba[i][RCOMP];
1156      const GLfloat g = rgba[i][GCOMP];
1157      const GLfloat b = rgba[i][BCOMP];
1158      const GLfloat a = rgba[i][ACOMP];
1159      rgba[i][RCOMP] = (m[0] * r + m[4] * g + m[ 8] * b + m[12] * a) * rs + rb;
1160      rgba[i][GCOMP] = (m[1] * r + m[5] * g + m[ 9] * b + m[13] * a) * gs + gb;
1161      rgba[i][BCOMP] = (m[2] * r + m[6] * g + m[10] * b + m[14] * a) * bs + bb;
1162      rgba[i][ACOMP] = (m[3] * r + m[7] * g + m[11] * b + m[15] * a) * as + ab;
1163   }
1164}
1165
1166
1167/**
1168 * Apply a color table lookup to an array of floating point RGBA colors.
1169 */
1170void
1171_mesa_lookup_rgba_float(const struct gl_color_table *table,
1172                        GLuint n, GLfloat rgba[][4])
1173{
1174   if (!table->Table || table->Size == 0)
1175      return;
1176
1177   switch (table->Format) {
1178      case GL_INTENSITY:
1179         /* replace RGBA with I */
1180         if (table->Type == GL_FLOAT) {
1181            const GLint max = table->Size - 1;
1182            const GLfloat scale = (GLfloat) max;
1183            const GLfloat *lut = (const GLfloat *) table->Table;
1184            GLuint i;
1185            for (i = 0; i < n; i++) {
1186               GLint j = IROUND(rgba[i][RCOMP] * scale);
1187               GLfloat c = lut[CLAMP(j, 0, max)];
1188               rgba[i][RCOMP] = rgba[i][GCOMP] =
1189                  rgba[i][BCOMP] = rgba[i][ACOMP] = c;
1190            }
1191         }
1192         else {
1193            const GLint max = table->Size - 1;
1194            const GLfloat scale = (GLfloat) max;
1195            const GLchan *lut = (const GLchan *) table->Table;
1196            GLuint i;
1197            for (i = 0; i < n; i++) {
1198               GLint j = IROUND(rgba[i][RCOMP] * scale);
1199               GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
1200               rgba[i][RCOMP] = rgba[i][GCOMP] =
1201                  rgba[i][BCOMP] = rgba[i][ACOMP] = c;
1202            }
1203         }
1204         break;
1205      case GL_LUMINANCE:
1206         /* replace RGB with L */
1207         if (table->Type == GL_FLOAT) {
1208            const GLint max = table->Size - 1;
1209            const GLfloat scale = (GLfloat) max;
1210            const GLfloat *lut = (const GLfloat *) table->Table;
1211            GLuint i;
1212            for (i = 0; i < n; i++) {
1213               GLint j = IROUND(rgba[i][RCOMP] * scale);
1214               GLfloat c = lut[CLAMP(j, 0, max)];
1215               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
1216            }
1217         }
1218         else {
1219            const GLint max = table->Size - 1;
1220            const GLfloat scale = (GLfloat) max;
1221            const GLchan *lut = (const GLchan *) table->Table;
1222            GLuint i;
1223            for (i = 0; i < n; i++) {
1224               GLint j = IROUND(rgba[i][RCOMP] * scale);
1225               GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
1226               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
1227            }
1228         }
1229         break;
1230      case GL_ALPHA:
1231         /* replace A with A */
1232         if (table->Type == GL_FLOAT) {
1233            const GLint max = table->Size - 1;
1234            const GLfloat scale = (GLfloat) max;
1235            const GLfloat *lut = (const GLfloat *) table->Table;
1236            GLuint i;
1237            for (i = 0; i < n; i++) {
1238               GLint j = IROUND(rgba[i][ACOMP] * scale);
1239               rgba[i][ACOMP] = lut[CLAMP(j, 0, max)];
1240            }
1241         }
1242         else {
1243            const GLint max = table->Size - 1;
1244            const GLfloat scale = (GLfloat) max;
1245            const GLchan *lut = (const GLchan *) table->Table;
1246            GLuint i;
1247            for (i = 0; i < n; i++) {
1248               GLint j = IROUND(rgba[i][ACOMP] * scale);
1249               rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
1250            }
1251         }
1252         break;
1253      case GL_LUMINANCE_ALPHA:
1254         /* replace RGBA with LLLA */
1255         if (table->Type == GL_FLOAT) {
1256            const GLint max = table->Size - 1;
1257            const GLfloat scale = (GLfloat) max;
1258            const GLfloat *lut = (const GLfloat *) table->Table;
1259            GLuint i;
1260            for (i = 0; i < n; i++) {
1261               GLint jL = IROUND(rgba[i][RCOMP] * scale);
1262               GLint jA = IROUND(rgba[i][ACOMP] * scale);
1263               GLfloat luminance, alpha;
1264               jL = CLAMP(jL, 0, max);
1265               jA = CLAMP(jA, 0, max);
1266               luminance = lut[jL * 2 + 0];
1267               alpha     = lut[jA * 2 + 1];
1268               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
1269               rgba[i][ACOMP] = alpha;;
1270            }
1271         }
1272         else {
1273            const GLint max = table->Size - 1;
1274            const GLfloat scale = (GLfloat) max;
1275            const GLchan *lut = (const GLchan *) table->Table;
1276            GLuint i;
1277            for (i = 0; i < n; i++) {
1278               GLint jL = IROUND(rgba[i][RCOMP] * scale);
1279               GLint jA = IROUND(rgba[i][ACOMP] * scale);
1280               GLfloat luminance, alpha;
1281               jL = CLAMP(jL, 0, max);
1282               jA = CLAMP(jA, 0, max);
1283               luminance = CHAN_TO_FLOAT(lut[jL * 2 + 0]);
1284               alpha     = CHAN_TO_FLOAT(lut[jA * 2 + 1]);
1285               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
1286               rgba[i][ACOMP] = alpha;;
1287            }
1288         }
1289         break;
1290      case GL_RGB:
1291         /* replace RGB with RGB */
1292         if (table->Type == GL_FLOAT) {
1293            const GLint max = table->Size - 1;
1294            const GLfloat scale = (GLfloat) max;
1295            const GLfloat *lut = (const GLfloat *) table->Table;
1296            GLuint i;
1297            for (i = 0; i < n; i++) {
1298               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1299               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1300               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1301               jR = CLAMP(jR, 0, max);
1302               jG = CLAMP(jG, 0, max);
1303               jB = CLAMP(jB, 0, max);
1304               rgba[i][RCOMP] = lut[jR * 3 + 0];
1305               rgba[i][GCOMP] = lut[jG * 3 + 1];
1306               rgba[i][BCOMP] = lut[jB * 3 + 2];
1307            }
1308         }
1309         else {
1310            const GLint max = table->Size - 1;
1311            const GLfloat scale = (GLfloat) max;
1312            const GLchan *lut = (const GLchan *) table->Table;
1313            GLuint i;
1314            for (i = 0; i < n; i++) {
1315               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1316               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1317               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1318               jR = CLAMP(jR, 0, max);
1319               jG = CLAMP(jG, 0, max);
1320               jB = CLAMP(jB, 0, max);
1321               rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 3 + 0]);
1322               rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 3 + 1]);
1323               rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 3 + 2]);
1324            }
1325         }
1326         break;
1327      case GL_RGBA:
1328         /* replace RGBA with RGBA */
1329         if (table->Type == GL_FLOAT) {
1330            const GLint max = table->Size - 1;
1331            const GLfloat scale = (GLfloat) max;
1332            const GLfloat *lut = (const GLfloat *) table->Table;
1333            GLuint i;
1334            for (i = 0; i < n; i++) {
1335               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1336               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1337               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1338               GLint jA = IROUND(rgba[i][ACOMP] * scale);
1339               jR = CLAMP(jR, 0, max);
1340               jG = CLAMP(jG, 0, max);
1341               jB = CLAMP(jB, 0, max);
1342               jA = CLAMP(jA, 0, max);
1343               rgba[i][RCOMP] = lut[jR * 4 + 0];
1344               rgba[i][GCOMP] = lut[jG * 4 + 1];
1345               rgba[i][BCOMP] = lut[jB * 4 + 2];
1346               rgba[i][ACOMP] = lut[jA * 4 + 3];
1347            }
1348         }
1349         else {
1350            const GLint max = table->Size - 1;
1351            const GLfloat scale = (GLfloat) max;
1352            const GLchan *lut = (const GLchan *) table->Table;
1353            GLuint i;
1354            for (i = 0; i < n; i++) {
1355               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1356               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1357               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1358               GLint jA = IROUND(rgba[i][ACOMP] * scale);
1359               jR = CLAMP(jR, 0, max);
1360               jG = CLAMP(jG, 0, max);
1361               jB = CLAMP(jB, 0, max);
1362               jA = CLAMP(jA, 0, max);
1363               rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 4 + 0]);
1364               rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 4 + 1]);
1365               rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 4 + 2]);
1366               rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[jA * 4 + 3]);
1367            }
1368         }
1369         break;
1370      default:
1371         _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_float");
1372         return;
1373   }
1374}
1375
1376
1377
1378/**
1379 * Apply a color table lookup to an array of GLchan RGBA colors.
1380 */
1381void
1382_mesa_lookup_rgba_chan(const struct gl_color_table *table,
1383                       GLuint n, GLchan rgba[][4])
1384{
1385   if (!table->Table || table->Size == 0)
1386      return;
1387
1388   switch (table->Format) {
1389      case GL_INTENSITY:
1390         /* replace RGBA with I */
1391         if (table->Type == GL_FLOAT) {
1392            const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1393            const GLfloat *lut = (const GLfloat *) table->Table;
1394            GLuint i;
1395            for (i = 0; i < n; i++) {
1396               GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1397               GLchan c;
1398               CLAMPED_FLOAT_TO_CHAN(c, lut[j]);
1399               rgba[i][RCOMP] = rgba[i][GCOMP] =
1400                  rgba[i][BCOMP] = rgba[i][ACOMP] = c;
1401            }
1402         }
1403         else {
1404#if CHAN_TYPE == GL_UNSIGNED_BYTE
1405            if (table->Size == 256) {
1406               /* common case */
1407               const GLchan *lut = (const GLchan *) table->Table;
1408               GLuint i;
1409               for (i = 0; i < n; i++) {
1410                  const GLchan c = lut[rgba[i][RCOMP]];
1411                  rgba[i][RCOMP] = rgba[i][GCOMP] =
1412                     rgba[i][BCOMP] = rgba[i][ACOMP] = c;
1413               }
1414            }
1415            else
1416#endif
1417            {
1418               const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1419               const GLchan *lut = (const GLchan *) table->Table;
1420               GLuint i;
1421               for (i = 0; i < n; i++) {
1422                  GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1423                  rgba[i][RCOMP] = rgba[i][GCOMP] =
1424                     rgba[i][BCOMP] = rgba[i][ACOMP] = lut[j];
1425               }
1426            }
1427         }
1428         break;
1429      case GL_LUMINANCE:
1430         /* replace RGB with L */
1431         if (table->Type == GL_FLOAT) {
1432            const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1433            const GLfloat *lut = (const GLfloat *) table->Table;
1434            GLuint i;
1435            for (i = 0; i < n; i++) {
1436               GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1437               GLchan c;
1438               CLAMPED_FLOAT_TO_CHAN(c, lut[j]);
1439               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
1440            }
1441         }
1442         else {
1443#if CHAN_TYPE == GL_UNSIGNED_BYTE
1444            if (table->Size == 256) {
1445               /* common case */
1446               const GLchan *lut = (const GLchan *) table->Table;
1447               GLuint i;
1448               for (i = 0; i < n; i++) {
1449                  const GLchan c = lut[rgba[i][RCOMP]];
1450                  rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
1451               }
1452            }
1453            else
1454#endif
1455            {
1456               const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1457               const GLchan *lut = (const GLchan *) table->Table;
1458               GLuint i;
1459               for (i = 0; i < n; i++) {
1460                  GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1461                  rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = lut[j];
1462               }
1463            }
1464         }
1465         break;
1466      case GL_ALPHA:
1467         /* replace A with A */
1468         if (table->Type == GL_FLOAT) {
1469            const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1470            const GLfloat *lut = (const GLfloat *) table->Table;
1471            GLuint i;
1472            for (i = 0; i < n; i++) {
1473               GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1474               GLchan c;
1475               CLAMPED_FLOAT_TO_CHAN(c, lut[j]);
1476               rgba[i][ACOMP] = c;
1477            }
1478         }
1479         else {
1480#if CHAN_TYPE == GL_UNSIGNED_BYTE
1481            if (table->Size == 256) {
1482               /* common case */
1483               const GLchan *lut = (const GLchan *) table->Table;
1484               GLuint i;
1485               for (i = 0; i < n; i++) {
1486                  rgba[i][ACOMP] = lut[rgba[i][ACOMP]];
1487               }
1488            }
1489            else
1490#endif
1491            {
1492               const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1493               const GLchan *lut = (const GLchan *) table->Table;
1494               GLuint i;
1495               for (i = 0; i < n; i++) {
1496                  GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1497                  rgba[i][ACOMP] = lut[j];
1498               }
1499            }
1500         }
1501         break;
1502      case GL_LUMINANCE_ALPHA:
1503         /* replace RGBA with LLLA */
1504         if (table->Type == GL_FLOAT) {
1505            const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1506            const GLfloat *lut = (const GLfloat *) table->Table;
1507            GLuint i;
1508            for (i = 0; i < n; i++) {
1509               GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1510               GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1511               GLchan luminance, alpha;
1512               CLAMPED_FLOAT_TO_CHAN(luminance, lut[jL * 2 + 0]);
1513               CLAMPED_FLOAT_TO_CHAN(alpha, lut[jA * 2 + 1]);
1514               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
1515               rgba[i][ACOMP] = alpha;;
1516            }
1517         }
1518         else {
1519#if CHAN_TYPE == GL_UNSIGNED_BYTE
1520            if (table->Size == 256) {
1521               /* common case */
1522               const GLchan *lut = (const GLchan *) table->Table;
1523               GLuint i;
1524               for (i = 0; i < n; i++) {
1525                  GLchan l = lut[rgba[i][RCOMP] * 2 + 0];
1526                  GLchan a = lut[rgba[i][ACOMP] * 2 + 1];;
1527                  rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = l;
1528                  rgba[i][ACOMP] = a;
1529               }
1530            }
1531            else
1532#endif
1533            {
1534               const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1535               const GLchan *lut = (const GLchan *) table->Table;
1536               GLuint i;
1537               for (i = 0; i < n; i++) {
1538                  GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1539                  GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1540                  GLchan luminance = lut[jL * 2 + 0];
1541                  GLchan alpha     = lut[jA * 2 + 1];
1542                  rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
1543                  rgba[i][ACOMP] = alpha;
1544               }
1545            }
1546         }
1547         break;
1548      case GL_RGB:
1549         /* replace RGB with RGB */
1550         if (table->Type == GL_FLOAT) {
1551            const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1552            const GLfloat *lut = (const GLfloat *) table->Table;
1553            GLuint i;
1554            for (i = 0; i < n; i++) {
1555               GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1556               GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1557               GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1558               CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 3 + 0]);
1559               CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 3 + 1]);
1560               CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 3 + 2]);
1561            }
1562         }
1563         else {
1564#if CHAN_TYPE == GL_UNSIGNED_BYTE
1565            if (table->Size == 256) {
1566               /* common case */
1567               const GLchan *lut = (const GLchan *) table->Table;
1568               GLuint i;
1569               for (i = 0; i < n; i++) {
1570                  rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 3 + 0];
1571                  rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 3 + 1];
1572                  rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 3 + 2];
1573               }
1574            }
1575            else
1576#endif
1577            {
1578               const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1579               const GLchan *lut = (const GLchan *) table->Table;
1580               GLuint i;
1581               for (i = 0; i < n; i++) {
1582                  GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1583                  GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1584                  GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1585                  rgba[i][RCOMP] = lut[jR * 3 + 0];
1586                  rgba[i][GCOMP] = lut[jG * 3 + 1];
1587                  rgba[i][BCOMP] = lut[jB * 3 + 2];
1588               }
1589            }
1590         }
1591         break;
1592      case GL_RGBA:
1593         /* replace RGBA with RGBA */
1594         if (table->Type == GL_FLOAT) {
1595            const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1596            const GLfloat *lut = (const GLfloat *) table->Table;
1597            GLuint i;
1598            for (i = 0; i < n; i++) {
1599               GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1600               GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1601               GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1602               GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1603               CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]);
1604               CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]);
1605               CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]);
1606               CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]);
1607            }
1608         }
1609         else {
1610#if CHAN_TYPE == GL_UNSIGNED_BYTE
1611            if (table->Size == 256) {
1612               /* common case */
1613               const GLchan *lut = (const GLchan *) table->Table;
1614               GLuint i;
1615               for (i = 0; i < n; i++) {
1616                  rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 4 + 0];
1617                  rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 4 + 1];
1618                  rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 4 + 2];
1619                  rgba[i][ACOMP] = lut[rgba[i][ACOMP] * 4 + 3];
1620               }
1621            }
1622            else
1623#endif
1624            {
1625               const GLfloat scale = (GLfloat) (table->Size - 1) / CHAN_MAXF;
1626               const GLfloat *lut = (const GLfloat *) table->Table;
1627               GLuint i;
1628               for (i = 0; i < n; i++) {
1629                  GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1630                  GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1631                  GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1632                  GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1633                  CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]);
1634                  CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]);
1635                  CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]);
1636                  CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]);
1637               }
1638            }
1639         }
1640         break;
1641      default:
1642         _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_chan");
1643         return;
1644   }
1645}
1646
1647
1648
1649/*
1650 * Apply color index shift and offset to an array of pixels.
1651 */
1652void
1653_mesa_shift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] )
1654{
1655   GLint shift = ctx->Pixel.IndexShift;
1656   GLint offset = ctx->Pixel.IndexOffset;
1657   GLuint i;
1658   if (shift > 0) {
1659      for (i=0;i<n;i++) {
1660         indexes[i] = (indexes[i] << shift) + offset;
1661      }
1662   }
1663   else if (shift < 0) {
1664      shift = -shift;
1665      for (i=0;i<n;i++) {
1666         indexes[i] = (indexes[i] >> shift) + offset;
1667      }
1668   }
1669   else {
1670      for (i=0;i<n;i++) {
1671         indexes[i] = indexes[i] + offset;
1672      }
1673   }
1674}
1675
1676
1677/*
1678 * Apply color index mapping to color indexes.
1679 */
1680void
1681_mesa_map_ci( const GLcontext *ctx, GLuint n, GLuint index[] )
1682{
1683   const GLuint mask = ctx->Pixel.MapItoIsize - 1;
1684   GLuint i;
1685   for (i = 0; i < n; i++) {
1686      const GLuint j = index[i] & mask;
1687      index[i] = IROUND(ctx->Pixel.MapItoI[j]);
1688   }
1689}
1690
1691
1692/*
1693 * Map color indexes to rgba values.
1694 */
1695void
1696_mesa_map_ci_to_rgba_chan( const GLcontext *ctx, GLuint n,
1697                           const GLuint index[], GLchan rgba[][4] )
1698{
1699#if CHAN_BITS == 8
1700   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1701   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1702   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1703   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1704   const GLubyte *rMap = ctx->Pixel.MapItoR8;
1705   const GLubyte *gMap = ctx->Pixel.MapItoG8;
1706   const GLubyte *bMap = ctx->Pixel.MapItoB8;
1707   const GLubyte *aMap = ctx->Pixel.MapItoA8;
1708   GLuint i;
1709   for (i=0;i<n;i++) {
1710      rgba[i][RCOMP] = rMap[index[i] & rmask];
1711      rgba[i][GCOMP] = gMap[index[i] & gmask];
1712      rgba[i][BCOMP] = bMap[index[i] & bmask];
1713      rgba[i][ACOMP] = aMap[index[i] & amask];
1714   }
1715#else
1716   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1717   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1718   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1719   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1720   const GLfloat *rMap = ctx->Pixel.MapItoR;
1721   const GLfloat *gMap = ctx->Pixel.MapItoG;
1722   const GLfloat *bMap = ctx->Pixel.MapItoB;
1723   const GLfloat *aMap = ctx->Pixel.MapItoA;
1724   GLuint i;
1725   for (i=0;i<n;i++) {
1726      CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]);
1727      CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]);
1728      CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]);
1729      CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]);
1730   }
1731#endif
1732}
1733
1734
1735/*
1736 * Map color indexes to float rgba values.
1737 */
1738void
1739_mesa_map_ci_to_rgba( const GLcontext *ctx, GLuint n,
1740                      const GLuint index[], GLfloat rgba[][4] )
1741{
1742   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1743   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1744   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1745   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1746   const GLfloat *rMap = ctx->Pixel.MapItoR;
1747   const GLfloat *gMap = ctx->Pixel.MapItoG;
1748   const GLfloat *bMap = ctx->Pixel.MapItoB;
1749   const GLfloat *aMap = ctx->Pixel.MapItoA;
1750   GLuint i;
1751   for (i=0;i<n;i++) {
1752      rgba[i][RCOMP] = rMap[index[i] & rmask];
1753      rgba[i][GCOMP] = gMap[index[i] & gmask];
1754      rgba[i][BCOMP] = bMap[index[i] & bmask];
1755      rgba[i][ACOMP] = aMap[index[i] & amask];
1756   }
1757}
1758
1759
1760/*
1761 * Map 8-bit color indexes to rgb values.
1762 */
1763void
1764_mesa_map_ci8_to_rgba( const GLcontext *ctx, GLuint n, const GLubyte index[],
1765                       GLchan rgba[][4] )
1766{
1767#if CHAN_BITS == 8
1768   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1769   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1770   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1771   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1772   const GLubyte *rMap = ctx->Pixel.MapItoR8;
1773   const GLubyte *gMap = ctx->Pixel.MapItoG8;
1774   const GLubyte *bMap = ctx->Pixel.MapItoB8;
1775   const GLubyte *aMap = ctx->Pixel.MapItoA8;
1776   GLuint i;
1777   for (i=0;i<n;i++) {
1778      rgba[i][RCOMP] = rMap[index[i] & rmask];
1779      rgba[i][GCOMP] = gMap[index[i] & gmask];
1780      rgba[i][BCOMP] = bMap[index[i] & bmask];
1781      rgba[i][ACOMP] = aMap[index[i] & amask];
1782   }
1783#else
1784   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1785   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1786   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1787   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1788   const GLfloat *rMap = ctx->Pixel.MapItoR;
1789   const GLfloat *gMap = ctx->Pixel.MapItoG;
1790   const GLfloat *bMap = ctx->Pixel.MapItoB;
1791   const GLfloat *aMap = ctx->Pixel.MapItoA;
1792   GLuint i;
1793   for (i=0;i<n;i++) {
1794      CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]);
1795      CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]);
1796      CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]);
1797      CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]);
1798   }
1799#endif
1800}
1801
1802
1803void
1804_mesa_shift_and_offset_stencil( const GLcontext *ctx, GLuint n,
1805                                GLstencil stencil[] )
1806{
1807   GLuint i;
1808   GLint shift = ctx->Pixel.IndexShift;
1809   GLint offset = ctx->Pixel.IndexOffset;
1810   if (shift > 0) {
1811      for (i=0;i<n;i++) {
1812         stencil[i] = (stencil[i] << shift) + offset;
1813      }
1814   }
1815   else if (shift < 0) {
1816      shift = -shift;
1817      for (i=0;i<n;i++) {
1818         stencil[i] = (stencil[i] >> shift) + offset;
1819      }
1820   }
1821   else {
1822      for (i=0;i<n;i++) {
1823         stencil[i] = stencil[i] + offset;
1824      }
1825   }
1826
1827}
1828
1829
1830void
1831_mesa_map_stencil( const GLcontext *ctx, GLuint n, GLstencil stencil[] )
1832{
1833   GLuint mask = ctx->Pixel.MapStoSsize - 1;
1834   GLuint i;
1835   for (i=0;i<n;i++) {
1836      stencil[i] = ctx->Pixel.MapStoS[ stencil[i] & mask ];
1837   }
1838}
1839
1840
1841void
1842_mesa_scale_and_bias_depth(const GLcontext *ctx, GLuint n,
1843                           GLfloat depthValues[])
1844{
1845   const GLfloat scale = ctx->Pixel.DepthScale;
1846   const GLfloat bias = ctx->Pixel.DepthBias;
1847   GLuint i;
1848   for (i = 0; i < n; i++) {
1849      GLfloat d = depthValues[i] * scale + bias;
1850      depthValues[i] = CLAMP(d, 0.0F, 1.0F);
1851   }
1852}
1853
1854
1855/*
1856 * This function converts an array of GLchan colors to GLfloat colors.
1857 * Most importantly, it undoes the non-uniform quantization of pixel
1858 * values introduced when we convert shallow (< 8 bit) pixel values
1859 * to GLubytes in the ctx->Driver.ReadRGBASpan() functions.
1860 * This fixes a number of OpenGL conformance failures when running on
1861 * 16bpp displays, for example.
1862 */
1863void
1864_mesa_chan_to_float_span(const GLcontext *ctx, GLuint n,
1865                         CONST GLchan rgba[][4], GLfloat rgbaf[][4])
1866{
1867#if CHAN_TYPE == GL_FLOAT
1868   MEMCPY(rgbaf, rgba, n * 4 * sizeof(GLfloat));
1869#else
1870   const GLuint rShift = CHAN_BITS - ctx->Visual.redBits;
1871   const GLuint gShift = CHAN_BITS - ctx->Visual.greenBits;
1872   const GLuint bShift = CHAN_BITS - ctx->Visual.blueBits;
1873   GLuint aShift;
1874   const GLfloat rScale = 1.0F / (GLfloat) ((1 << ctx->Visual.redBits  ) - 1);
1875   const GLfloat gScale = 1.0F / (GLfloat) ((1 << ctx->Visual.greenBits) - 1);
1876   const GLfloat bScale = 1.0F / (GLfloat) ((1 << ctx->Visual.blueBits ) - 1);
1877   GLfloat aScale;
1878   GLuint i;
1879
1880   if (ctx->Visual.alphaBits > 0) {
1881      aShift = CHAN_BITS - ctx->Visual.alphaBits;
1882      aScale = 1.0F / (GLfloat) ((1 << ctx->Visual.alphaBits) - 1);
1883   }
1884   else {
1885      aShift = 0;
1886      aScale = 1.0F / CHAN_MAXF;
1887   }
1888
1889   for (i = 0; i < n; i++) {
1890      const GLint r = rgba[i][RCOMP] >> rShift;
1891      const GLint g = rgba[i][GCOMP] >> gShift;
1892      const GLint b = rgba[i][BCOMP] >> bShift;
1893      const GLint a = rgba[i][ACOMP] >> aShift;
1894      rgbaf[i][RCOMP] = (GLfloat) r * rScale;
1895      rgbaf[i][GCOMP] = (GLfloat) g * gScale;
1896      rgbaf[i][BCOMP] = (GLfloat) b * bScale;
1897      rgbaf[i][ACOMP] = (GLfloat) a * aScale;
1898   }
1899#endif
1900}
1901
1902/**********************************************************************/
1903/*****                    State Management                        *****/
1904/**********************************************************************/
1905
1906/*
1907 * Return a bitmask of IMAGE_*_BIT flags which to indicate which
1908 * pixel transfer operations are enabled.
1909 */
1910static void
1911update_image_transfer_state(GLcontext *ctx)
1912{
1913   GLuint mask = 0;
1914
1915   if (ctx->Pixel.RedScale   != 1.0F || ctx->Pixel.RedBias   != 0.0F ||
1916       ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F ||
1917       ctx->Pixel.BlueScale  != 1.0F || ctx->Pixel.BlueBias  != 0.0F ||
1918       ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F)
1919      mask |= IMAGE_SCALE_BIAS_BIT;
1920
1921   if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset)
1922      mask |= IMAGE_SHIFT_OFFSET_BIT;
1923
1924   if (ctx->Pixel.MapColorFlag)
1925      mask |= IMAGE_MAP_COLOR_BIT;
1926
1927   if (ctx->Pixel.ColorTableEnabled)
1928      mask |= IMAGE_COLOR_TABLE_BIT;
1929
1930   if (ctx->Pixel.Convolution1DEnabled ||
1931       ctx->Pixel.Convolution2DEnabled ||
1932       ctx->Pixel.Separable2DEnabled) {
1933      mask |= IMAGE_CONVOLUTION_BIT;
1934      if (ctx->Pixel.PostConvolutionScale[0] != 1.0F ||
1935          ctx->Pixel.PostConvolutionScale[1] != 1.0F ||
1936          ctx->Pixel.PostConvolutionScale[2] != 1.0F ||
1937          ctx->Pixel.PostConvolutionScale[3] != 1.0F ||
1938          ctx->Pixel.PostConvolutionBias[0] != 0.0F ||
1939          ctx->Pixel.PostConvolutionBias[1] != 0.0F ||
1940          ctx->Pixel.PostConvolutionBias[2] != 0.0F ||
1941          ctx->Pixel.PostConvolutionBias[3] != 0.0F) {
1942         mask |= IMAGE_POST_CONVOLUTION_SCALE_BIAS;
1943      }
1944   }
1945
1946   if (ctx->Pixel.PostConvolutionColorTableEnabled)
1947      mask |= IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT;
1948
1949   if (ctx->ColorMatrixStack.Top->type != MATRIX_IDENTITY ||
1950       ctx->Pixel.PostColorMatrixScale[0] != 1.0F ||
1951       ctx->Pixel.PostColorMatrixBias[0]  != 0.0F ||
1952       ctx->Pixel.PostColorMatrixScale[1] != 1.0F ||
1953       ctx->Pixel.PostColorMatrixBias[1]  != 0.0F ||
1954       ctx->Pixel.PostColorMatrixScale[2] != 1.0F ||
1955       ctx->Pixel.PostColorMatrixBias[2]  != 0.0F ||
1956       ctx->Pixel.PostColorMatrixScale[3] != 1.0F ||
1957       ctx->Pixel.PostColorMatrixBias[3]  != 0.0F)
1958      mask |= IMAGE_COLOR_MATRIX_BIT;
1959
1960   if (ctx->Pixel.PostColorMatrixColorTableEnabled)
1961      mask |= IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT;
1962
1963   if (ctx->Pixel.HistogramEnabled)
1964      mask |= IMAGE_HISTOGRAM_BIT;
1965
1966   if (ctx->Pixel.MinMaxEnabled)
1967      mask |= IMAGE_MIN_MAX_BIT;
1968
1969   ctx->_ImageTransferState = mask;
1970}
1971
1972
1973void _mesa_update_pixel( GLcontext *ctx, GLuint new_state )
1974{
1975   if (new_state & _NEW_COLOR_MATRIX)
1976      _math_matrix_analyse( ctx->ColorMatrixStack.Top );
1977
1978   /* References ColorMatrix.type (derived above).
1979    */
1980   if (new_state & _IMAGE_NEW_TRANSFER_STATE)
1981      update_image_transfer_state(ctx);
1982}
1983
1984
1985/**********************************************************************/
1986/*****                      Initialization                        *****/
1987/**********************************************************************/
1988
1989
1990/**
1991 * Initialize the context's PIXEL attribute group.
1992 */
1993void
1994_mesa_init_pixel( GLcontext *ctx )
1995{
1996   int i;
1997
1998   /* Pixel group */
1999   ctx->Pixel.RedBias = 0.0;
2000   ctx->Pixel.RedScale = 1.0;
2001   ctx->Pixel.GreenBias = 0.0;
2002   ctx->Pixel.GreenScale = 1.0;
2003   ctx->Pixel.BlueBias = 0.0;
2004   ctx->Pixel.BlueScale = 1.0;
2005   ctx->Pixel.AlphaBias = 0.0;
2006   ctx->Pixel.AlphaScale = 1.0;
2007   ctx->Pixel.DepthBias = 0.0;
2008   ctx->Pixel.DepthScale = 1.0;
2009   ctx->Pixel.IndexOffset = 0;
2010   ctx->Pixel.IndexShift = 0;
2011   ctx->Pixel.ZoomX = 1.0;
2012   ctx->Pixel.ZoomY = 1.0;
2013   ctx->Pixel.MapColorFlag = GL_FALSE;
2014   ctx->Pixel.MapStencilFlag = GL_FALSE;
2015   ctx->Pixel.MapStoSsize = 1;
2016   ctx->Pixel.MapItoIsize = 1;
2017   ctx->Pixel.MapItoRsize = 1;
2018   ctx->Pixel.MapItoGsize = 1;
2019   ctx->Pixel.MapItoBsize = 1;
2020   ctx->Pixel.MapItoAsize = 1;
2021   ctx->Pixel.MapRtoRsize = 1;
2022   ctx->Pixel.MapGtoGsize = 1;
2023   ctx->Pixel.MapBtoBsize = 1;
2024   ctx->Pixel.MapAtoAsize = 1;
2025   ctx->Pixel.MapStoS[0] = 0;
2026   ctx->Pixel.MapItoI[0] = 0.0;
2027   ctx->Pixel.MapItoR[0] = 0.0;
2028   ctx->Pixel.MapItoG[0] = 0.0;
2029   ctx->Pixel.MapItoB[0] = 0.0;
2030   ctx->Pixel.MapItoA[0] = 0.0;
2031   ctx->Pixel.MapItoR8[0] = 0;
2032   ctx->Pixel.MapItoG8[0] = 0;
2033   ctx->Pixel.MapItoB8[0] = 0;
2034   ctx->Pixel.MapItoA8[0] = 0;
2035   ctx->Pixel.MapRtoR[0] = 0.0;
2036   ctx->Pixel.MapGtoG[0] = 0.0;
2037   ctx->Pixel.MapBtoB[0] = 0.0;
2038   ctx->Pixel.MapAtoA[0] = 0.0;
2039   ctx->Pixel.HistogramEnabled = GL_FALSE;
2040   ctx->Pixel.MinMaxEnabled = GL_FALSE;
2041   ctx->Pixel.PixelTextureEnabled = GL_FALSE;
2042   ctx->Pixel.FragmentRgbSource = GL_PIXEL_GROUP_COLOR_SGIS;
2043   ctx->Pixel.FragmentAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS;
2044   ASSIGN_4V(ctx->Pixel.PostColorMatrixScale, 1.0, 1.0, 1.0, 1.0);
2045   ASSIGN_4V(ctx->Pixel.PostColorMatrixBias, 0.0, 0.0, 0.0, 0.0);
2046   ASSIGN_4V(ctx->Pixel.ColorTableScale, 1.0, 1.0, 1.0, 1.0);
2047   ASSIGN_4V(ctx->Pixel.ColorTableBias, 0.0, 0.0, 0.0, 0.0);
2048   ASSIGN_4V(ctx->Pixel.PCCTscale, 1.0, 1.0, 1.0, 1.0);
2049   ASSIGN_4V(ctx->Pixel.PCCTbias, 0.0, 0.0, 0.0, 0.0);
2050   ASSIGN_4V(ctx->Pixel.PCMCTscale, 1.0, 1.0, 1.0, 1.0);
2051   ASSIGN_4V(ctx->Pixel.PCMCTbias, 0.0, 0.0, 0.0, 0.0);
2052   ctx->Pixel.ColorTableEnabled = GL_FALSE;
2053   ctx->Pixel.PostConvolutionColorTableEnabled = GL_FALSE;
2054   ctx->Pixel.PostColorMatrixColorTableEnabled = GL_FALSE;
2055   ctx->Pixel.Convolution1DEnabled = GL_FALSE;
2056   ctx->Pixel.Convolution2DEnabled = GL_FALSE;
2057   ctx->Pixel.Separable2DEnabled = GL_FALSE;
2058   for (i = 0; i < 3; i++) {
2059      ASSIGN_4V(ctx->Pixel.ConvolutionBorderColor[i], 0.0, 0.0, 0.0, 0.0);
2060      ctx->Pixel.ConvolutionBorderMode[i] = GL_REDUCE;
2061      ASSIGN_4V(ctx->Pixel.ConvolutionFilterScale[i], 1.0, 1.0, 1.0, 1.0);
2062      ASSIGN_4V(ctx->Pixel.ConvolutionFilterBias[i], 0.0, 0.0, 0.0, 0.0);
2063   }
2064   for (i = 0; i < MAX_CONVOLUTION_WIDTH * MAX_CONVOLUTION_WIDTH * 4; i++) {
2065      ctx->Convolution1D.Filter[i] = 0.0;
2066      ctx->Convolution2D.Filter[i] = 0.0;
2067      ctx->Separable2D.Filter[i] = 0.0;
2068   }
2069   ASSIGN_4V(ctx->Pixel.PostConvolutionScale, 1.0, 1.0, 1.0, 1.0);
2070   ASSIGN_4V(ctx->Pixel.PostConvolutionBias, 0.0, 0.0, 0.0, 0.0);
2071   /* GL_SGI_texture_color_table */
2072   ASSIGN_4V(ctx->Pixel.TextureColorTableScale, 1.0, 1.0, 1.0, 1.0);
2073   ASSIGN_4V(ctx->Pixel.TextureColorTableBias, 0.0, 0.0, 0.0, 0.0);
2074
2075   /* Pixel transfer */
2076   ctx->Pack.Alignment = 4;
2077   ctx->Pack.RowLength = 0;
2078   ctx->Pack.ImageHeight = 0;
2079   ctx->Pack.SkipPixels = 0;
2080   ctx->Pack.SkipRows = 0;
2081   ctx->Pack.SkipImages = 0;
2082   ctx->Pack.SwapBytes = GL_FALSE;
2083   ctx->Pack.LsbFirst = GL_FALSE;
2084   ctx->Pack.ClientStorage = GL_FALSE;
2085   ctx->Pack.Invert = GL_FALSE;
2086#if FEATURE_EXT_pixel_buffer_object
2087   ctx->Pack.BufferObj = ctx->Array.NullBufferObj;
2088#endif
2089   ctx->Unpack.Alignment = 4;
2090   ctx->Unpack.RowLength = 0;
2091   ctx->Unpack.ImageHeight = 0;
2092   ctx->Unpack.SkipPixels = 0;
2093   ctx->Unpack.SkipRows = 0;
2094   ctx->Unpack.SkipImages = 0;
2095   ctx->Unpack.SwapBytes = GL_FALSE;
2096   ctx->Unpack.LsbFirst = GL_FALSE;
2097   ctx->Unpack.ClientStorage = GL_FALSE;
2098   ctx->Unpack.Invert = GL_FALSE;
2099#if FEATURE_EXT_pixel_buffer_object
2100   ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;
2101#endif
2102
2103   /*
2104    * _mesa_unpack_image() returns image data in this format.  When we
2105    * execute image commands (glDrawPixels(), glTexImage(), etc) from
2106    * within display lists we have to be sure to set the current
2107    * unpacking parameters to these values!
2108    */
2109   ctx->DefaultPacking.Alignment = 1;
2110   ctx->DefaultPacking.RowLength = 0;
2111   ctx->DefaultPacking.SkipPixels = 0;
2112   ctx->DefaultPacking.SkipRows = 0;
2113   ctx->DefaultPacking.ImageHeight = 0;
2114   ctx->DefaultPacking.SkipImages = 0;
2115   ctx->DefaultPacking.SwapBytes = GL_FALSE;
2116   ctx->DefaultPacking.LsbFirst = GL_FALSE;
2117   ctx->DefaultPacking.ClientStorage = GL_FALSE;
2118   ctx->DefaultPacking.Invert = GL_FALSE;
2119#if FEATURE_EXT_pixel_buffer_object
2120   ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
2121#endif
2122
2123   if (ctx->Visual.doubleBufferMode) {
2124      ctx->Pixel.ReadBuffer = GL_BACK;
2125   }
2126   else {
2127      ctx->Pixel.ReadBuffer = GL_FRONT;
2128   }
2129
2130   /* Miscellaneous */
2131   ctx->_ImageTransferState = 0;
2132}
2133