pixel.c revision 6340d6bf22ad0bfedf8565500336237a8da887f5
1/*
2 * Mesa 3-D graphics library
3 * Version:  6.5.2
4 *
5 * Copyright (C) 1999-2006  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] = (GLushort) CLAMP(ctx->Pixel.MapItoI[i], 0.0, 65535.0);
799	 }
800	 break;
801      case GL_PIXEL_MAP_S_TO_S:
802	 for (i = 0; i < mapsize; i++) {
803            values[i] = (GLushort) CLAMP(ctx->Pixel.MapStoS[i], 0.0, 65535.0);
804	 }
805	 break;
806      case GL_PIXEL_MAP_I_TO_R:
807	 for (i = 0; i < mapsize; i++) {
808	    CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapItoR[i] );
809	 }
810	 break;
811      case GL_PIXEL_MAP_I_TO_G:
812	 for (i = 0; i < mapsize; i++) {
813	    CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapItoG[i] );
814	 }
815	 break;
816      case GL_PIXEL_MAP_I_TO_B:
817	 for (i = 0; i < mapsize; i++) {
818	    CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapItoB[i] );
819	 }
820	 break;
821      case GL_PIXEL_MAP_I_TO_A:
822	 for (i = 0; i < mapsize; i++) {
823	    CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapItoA[i] );
824	 }
825	 break;
826      case GL_PIXEL_MAP_R_TO_R:
827	 for (i = 0; i < mapsize; i++) {
828	    CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapRtoR[i] );
829	 }
830	 break;
831      case GL_PIXEL_MAP_G_TO_G:
832	 for (i = 0; i < mapsize; i++) {
833	    CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapGtoG[i] );
834	 }
835	 break;
836      case GL_PIXEL_MAP_B_TO_B:
837	 for (i = 0; i < mapsize; i++) {
838	    CLAMPED_FLOAT_TO_USHORT(values[i] , ctx->Pixel.MapBtoB[i] );
839	 }
840	 break;
841      case GL_PIXEL_MAP_A_TO_A:
842	 for (i = 0; i < mapsize; i++) {
843	    CLAMPED_FLOAT_TO_USHORT(values[i] , 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   const GLint max = table->Size - 1;
1175   const GLfloat scale = (GLfloat) max;
1176   const GLfloat *lut = table->TableF;
1177   GLuint i;
1178
1179   if (!table->TableF || table->Size == 0)
1180      return;
1181
1182   switch (table->_BaseFormat) {
1183      case GL_INTENSITY:
1184         /* replace RGBA with 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] =
1189            rgba[i][GCOMP] =
1190            rgba[i][BCOMP] =
1191            rgba[i][ACOMP] = c;
1192         }
1193         break;
1194      case GL_LUMINANCE:
1195         /* replace RGB with L */
1196         for (i = 0; i < n; i++) {
1197            GLint j = IROUND(rgba[i][RCOMP] * scale);
1198            GLfloat c = lut[CLAMP(j, 0, max)];
1199            rgba[i][RCOMP] =
1200            rgba[i][GCOMP] =
1201            rgba[i][BCOMP] = c;
1202         }
1203         break;
1204      case GL_ALPHA:
1205         /* replace A with A */
1206         for (i = 0; i < n; i++) {
1207            GLint j = IROUND(rgba[i][ACOMP] * scale);
1208            rgba[i][ACOMP] = lut[CLAMP(j, 0, max)];
1209         }
1210         break;
1211      case GL_LUMINANCE_ALPHA:
1212         /* replace RGBA with LLLA */
1213         for (i = 0; i < n; i++) {
1214            GLint jL = IROUND(rgba[i][RCOMP] * scale);
1215            GLint jA = IROUND(rgba[i][ACOMP] * scale);
1216            GLfloat luminance, alpha;
1217            jL = CLAMP(jL, 0, max);
1218            jA = CLAMP(jA, 0, max);
1219            luminance = lut[jL * 2 + 0];
1220            alpha     = lut[jA * 2 + 1];
1221            rgba[i][RCOMP] =
1222            rgba[i][GCOMP] =
1223            rgba[i][BCOMP] = luminance;
1224            rgba[i][ACOMP] = alpha;;
1225         }
1226         break;
1227      case GL_RGB:
1228         /* replace RGB with RGB */
1229         for (i = 0; i < n; i++) {
1230            GLint jR = IROUND(rgba[i][RCOMP] * scale);
1231            GLint jG = IROUND(rgba[i][GCOMP] * scale);
1232            GLint jB = IROUND(rgba[i][BCOMP] * scale);
1233            jR = CLAMP(jR, 0, max);
1234            jG = CLAMP(jG, 0, max);
1235            jB = CLAMP(jB, 0, max);
1236            rgba[i][RCOMP] = lut[jR * 3 + 0];
1237            rgba[i][GCOMP] = lut[jG * 3 + 1];
1238            rgba[i][BCOMP] = lut[jB * 3 + 2];
1239         }
1240         break;
1241      case GL_RGBA:
1242         /* replace RGBA with RGBA */
1243         for (i = 0; i < n; i++) {
1244            GLint jR = IROUND(rgba[i][RCOMP] * scale);
1245            GLint jG = IROUND(rgba[i][GCOMP] * scale);
1246            GLint jB = IROUND(rgba[i][BCOMP] * scale);
1247            GLint jA = IROUND(rgba[i][ACOMP] * scale);
1248            jR = CLAMP(jR, 0, max);
1249            jG = CLAMP(jG, 0, max);
1250            jB = CLAMP(jB, 0, max);
1251            jA = CLAMP(jA, 0, max);
1252            rgba[i][RCOMP] = lut[jR * 4 + 0];
1253            rgba[i][GCOMP] = lut[jG * 4 + 1];
1254            rgba[i][BCOMP] = lut[jB * 4 + 2];
1255            rgba[i][ACOMP] = lut[jA * 4 + 3];
1256         }
1257         break;
1258      default:
1259         _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_float");
1260         return;
1261   }
1262}
1263
1264
1265
1266/**
1267 * Apply a color table lookup to an array of ubyte/RGBA colors.
1268 */
1269void
1270_mesa_lookup_rgba_ubyte(const struct gl_color_table *table,
1271                        GLuint n, GLubyte rgba[][4])
1272{
1273   const GLubyte *lut = table->TableUB;
1274   const GLfloat scale = (GLfloat) (table->Size - 1) / 255.0;
1275   GLuint i;
1276
1277   if (!table->TableUB || table->Size == 0)
1278      return;
1279
1280   switch (table->_BaseFormat) {
1281   case GL_INTENSITY:
1282      /* replace RGBA with I */
1283      if (table->Size == 256) {
1284         for (i = 0; i < n; i++) {
1285            const GLubyte c = lut[rgba[i][RCOMP]];
1286            rgba[i][RCOMP] =
1287            rgba[i][GCOMP] =
1288            rgba[i][BCOMP] =
1289            rgba[i][ACOMP] = c;
1290         }
1291      }
1292      else {
1293         for (i = 0; i < n; i++) {
1294            GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1295            rgba[i][RCOMP] =
1296            rgba[i][GCOMP] =
1297            rgba[i][BCOMP] =
1298            rgba[i][ACOMP] = lut[j];
1299         }
1300      }
1301      break;
1302   case GL_LUMINANCE:
1303      /* replace RGB with L */
1304      if (table->Size == 256) {
1305         for (i = 0; i < n; i++) {
1306            const GLubyte c = lut[rgba[i][RCOMP]];
1307            rgba[i][RCOMP] =
1308            rgba[i][GCOMP] =
1309            rgba[i][BCOMP] = c;
1310         }
1311      }
1312      else {
1313         for (i = 0; i < n; i++) {
1314            GLint j = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1315            rgba[i][RCOMP] =
1316            rgba[i][GCOMP] =
1317            rgba[i][BCOMP] = lut[j];
1318         }
1319      }
1320      break;
1321   case GL_ALPHA:
1322      /* replace A with A */
1323      if (table->Size == 256) {
1324         for (i = 0; i < n; i++) {
1325            rgba[i][ACOMP] = lut[rgba[i][ACOMP]];
1326         }
1327      }
1328      else {
1329         for (i = 0; i < n; i++) {
1330            GLint j = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1331            rgba[i][ACOMP] = lut[j];
1332         }
1333      }
1334      break;
1335   case GL_LUMINANCE_ALPHA:
1336      /* replace RGBA with LLLA */
1337      if (table->Size == 256) {
1338         for (i = 0; i < n; i++) {
1339            GLubyte l = lut[rgba[i][RCOMP] * 2 + 0];
1340            GLubyte a = lut[rgba[i][ACOMP] * 2 + 1];;
1341            rgba[i][RCOMP] =
1342            rgba[i][GCOMP] =
1343            rgba[i][BCOMP] = l;
1344            rgba[i][ACOMP] = a;
1345         }
1346      }
1347      else {
1348         for (i = 0; i < n; i++) {
1349            GLint jL = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1350            GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1351            GLubyte luminance = lut[jL * 2 + 0];
1352            GLubyte alpha     = lut[jA * 2 + 1];
1353            rgba[i][RCOMP] =
1354            rgba[i][GCOMP] =
1355            rgba[i][BCOMP] = luminance;
1356            rgba[i][ACOMP] = alpha;
1357         }
1358      }
1359      break;
1360   case GL_RGB:
1361      if (table->Size == 256) {
1362         for (i = 0; i < n; i++) {
1363            rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 3 + 0];
1364            rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 3 + 1];
1365            rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 3 + 2];
1366         }
1367      }
1368      else {
1369         for (i = 0; i < n; i++) {
1370            GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1371            GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1372            GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1373            rgba[i][RCOMP] = lut[jR * 3 + 0];
1374            rgba[i][GCOMP] = lut[jG * 3 + 1];
1375            rgba[i][BCOMP] = lut[jB * 3 + 2];
1376         }
1377      }
1378      break;
1379   case GL_RGBA:
1380      if (table->Size == 256) {
1381         for (i = 0; i < n; i++) {
1382            rgba[i][RCOMP] = lut[rgba[i][RCOMP] * 4 + 0];
1383            rgba[i][GCOMP] = lut[rgba[i][GCOMP] * 4 + 1];
1384            rgba[i][BCOMP] = lut[rgba[i][BCOMP] * 4 + 2];
1385            rgba[i][ACOMP] = lut[rgba[i][ACOMP] * 4 + 3];
1386         }
1387      }
1388      else {
1389         for (i = 0; i < n; i++) {
1390            GLint jR = IROUND((GLfloat) rgba[i][RCOMP] * scale);
1391            GLint jG = IROUND((GLfloat) rgba[i][GCOMP] * scale);
1392            GLint jB = IROUND((GLfloat) rgba[i][BCOMP] * scale);
1393            GLint jA = IROUND((GLfloat) rgba[i][ACOMP] * scale);
1394            CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], lut[jR * 4 + 0]);
1395            CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], lut[jG * 4 + 1]);
1396            CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], lut[jB * 4 + 2]);
1397            CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], lut[jA * 4 + 3]);
1398         }
1399      }
1400      break;
1401   default:
1402      _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba_chan");
1403      return;
1404   }
1405}
1406
1407
1408
1409/*
1410 * Map color indexes to float rgba values.
1411 */
1412void
1413_mesa_map_ci_to_rgba( const GLcontext *ctx, GLuint n,
1414                      const GLuint index[], GLfloat rgba[][4] )
1415{
1416   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1417   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1418   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1419   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1420   const GLfloat *rMap = ctx->Pixel.MapItoR;
1421   const GLfloat *gMap = ctx->Pixel.MapItoG;
1422   const GLfloat *bMap = ctx->Pixel.MapItoB;
1423   const GLfloat *aMap = ctx->Pixel.MapItoA;
1424   GLuint i;
1425   for (i=0;i<n;i++) {
1426      rgba[i][RCOMP] = rMap[index[i] & rmask];
1427      rgba[i][GCOMP] = gMap[index[i] & gmask];
1428      rgba[i][BCOMP] = bMap[index[i] & bmask];
1429      rgba[i][ACOMP] = aMap[index[i] & amask];
1430   }
1431}
1432
1433
1434/**
1435 * Map ubyte color indexes to ubyte/RGBA values.
1436 */
1437void
1438_mesa_map_ci8_to_rgba8(const GLcontext *ctx, GLuint n, const GLubyte index[],
1439                       GLubyte rgba[][4])
1440{
1441   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1442   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1443   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1444   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1445   const GLubyte *rMap = ctx->Pixel.MapItoR8;
1446   const GLubyte *gMap = ctx->Pixel.MapItoG8;
1447   const GLubyte *bMap = ctx->Pixel.MapItoB8;
1448   const GLubyte *aMap = ctx->Pixel.MapItoA8;
1449   GLuint i;
1450   for (i=0;i<n;i++) {
1451      rgba[i][RCOMP] = rMap[index[i] & rmask];
1452      rgba[i][GCOMP] = gMap[index[i] & gmask];
1453      rgba[i][BCOMP] = bMap[index[i] & bmask];
1454      rgba[i][ACOMP] = aMap[index[i] & amask];
1455   }
1456}
1457
1458
1459void
1460_mesa_scale_and_bias_depth(const GLcontext *ctx, GLuint n,
1461                           GLfloat depthValues[])
1462{
1463   const GLfloat scale = ctx->Pixel.DepthScale;
1464   const GLfloat bias = ctx->Pixel.DepthBias;
1465   GLuint i;
1466   for (i = 0; i < n; i++) {
1467      GLfloat d = depthValues[i] * scale + bias;
1468      depthValues[i] = CLAMP(d, 0.0F, 1.0F);
1469   }
1470}
1471
1472
1473
1474/**********************************************************************/
1475/*****                    State Management                        *****/
1476/**********************************************************************/
1477
1478/*
1479 * Return a bitmask of IMAGE_*_BIT flags which to indicate which
1480 * pixel transfer operations are enabled.
1481 */
1482static void
1483update_image_transfer_state(GLcontext *ctx)
1484{
1485   GLuint mask = 0;
1486
1487   if (ctx->Pixel.RedScale   != 1.0F || ctx->Pixel.RedBias   != 0.0F ||
1488       ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F ||
1489       ctx->Pixel.BlueScale  != 1.0F || ctx->Pixel.BlueBias  != 0.0F ||
1490       ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F)
1491      mask |= IMAGE_SCALE_BIAS_BIT;
1492
1493   if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset)
1494      mask |= IMAGE_SHIFT_OFFSET_BIT;
1495
1496   if (ctx->Pixel.MapColorFlag)
1497      mask |= IMAGE_MAP_COLOR_BIT;
1498
1499   if (ctx->Pixel.ColorTableEnabled)
1500      mask |= IMAGE_COLOR_TABLE_BIT;
1501
1502   if (ctx->Pixel.Convolution1DEnabled ||
1503       ctx->Pixel.Convolution2DEnabled ||
1504       ctx->Pixel.Separable2DEnabled) {
1505      mask |= IMAGE_CONVOLUTION_BIT;
1506      if (ctx->Pixel.PostConvolutionScale[0] != 1.0F ||
1507          ctx->Pixel.PostConvolutionScale[1] != 1.0F ||
1508          ctx->Pixel.PostConvolutionScale[2] != 1.0F ||
1509          ctx->Pixel.PostConvolutionScale[3] != 1.0F ||
1510          ctx->Pixel.PostConvolutionBias[0] != 0.0F ||
1511          ctx->Pixel.PostConvolutionBias[1] != 0.0F ||
1512          ctx->Pixel.PostConvolutionBias[2] != 0.0F ||
1513          ctx->Pixel.PostConvolutionBias[3] != 0.0F) {
1514         mask |= IMAGE_POST_CONVOLUTION_SCALE_BIAS;
1515      }
1516   }
1517
1518   if (ctx->Pixel.PostConvolutionColorTableEnabled)
1519      mask |= IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT;
1520
1521   if (ctx->ColorMatrixStack.Top->type != MATRIX_IDENTITY ||
1522       ctx->Pixel.PostColorMatrixScale[0] != 1.0F ||
1523       ctx->Pixel.PostColorMatrixBias[0]  != 0.0F ||
1524       ctx->Pixel.PostColorMatrixScale[1] != 1.0F ||
1525       ctx->Pixel.PostColorMatrixBias[1]  != 0.0F ||
1526       ctx->Pixel.PostColorMatrixScale[2] != 1.0F ||
1527       ctx->Pixel.PostColorMatrixBias[2]  != 0.0F ||
1528       ctx->Pixel.PostColorMatrixScale[3] != 1.0F ||
1529       ctx->Pixel.PostColorMatrixBias[3]  != 0.0F)
1530      mask |= IMAGE_COLOR_MATRIX_BIT;
1531
1532   if (ctx->Pixel.PostColorMatrixColorTableEnabled)
1533      mask |= IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT;
1534
1535   if (ctx->Pixel.HistogramEnabled)
1536      mask |= IMAGE_HISTOGRAM_BIT;
1537
1538   if (ctx->Pixel.MinMaxEnabled)
1539      mask |= IMAGE_MIN_MAX_BIT;
1540
1541   ctx->_ImageTransferState = mask;
1542}
1543
1544
1545void _mesa_update_pixel( GLcontext *ctx, GLuint new_state )
1546{
1547   if (new_state & _NEW_COLOR_MATRIX)
1548      _math_matrix_analyse( ctx->ColorMatrixStack.Top );
1549
1550   /* References ColorMatrix.type (derived above).
1551    */
1552   if (new_state & _IMAGE_NEW_TRANSFER_STATE)
1553      update_image_transfer_state(ctx);
1554}
1555
1556
1557/**********************************************************************/
1558/*****                      Initialization                        *****/
1559/**********************************************************************/
1560
1561
1562/**
1563 * Initialize the context's PIXEL attribute group.
1564 */
1565void
1566_mesa_init_pixel( GLcontext *ctx )
1567{
1568   int i;
1569
1570   /* Pixel group */
1571   ctx->Pixel.RedBias = 0.0;
1572   ctx->Pixel.RedScale = 1.0;
1573   ctx->Pixel.GreenBias = 0.0;
1574   ctx->Pixel.GreenScale = 1.0;
1575   ctx->Pixel.BlueBias = 0.0;
1576   ctx->Pixel.BlueScale = 1.0;
1577   ctx->Pixel.AlphaBias = 0.0;
1578   ctx->Pixel.AlphaScale = 1.0;
1579   ctx->Pixel.DepthBias = 0.0;
1580   ctx->Pixel.DepthScale = 1.0;
1581   ctx->Pixel.IndexOffset = 0;
1582   ctx->Pixel.IndexShift = 0;
1583   ctx->Pixel.ZoomX = 1.0;
1584   ctx->Pixel.ZoomY = 1.0;
1585   ctx->Pixel.MapColorFlag = GL_FALSE;
1586   ctx->Pixel.MapStencilFlag = GL_FALSE;
1587   ctx->Pixel.MapStoSsize = 1;
1588   ctx->Pixel.MapItoIsize = 1;
1589   ctx->Pixel.MapItoRsize = 1;
1590   ctx->Pixel.MapItoGsize = 1;
1591   ctx->Pixel.MapItoBsize = 1;
1592   ctx->Pixel.MapItoAsize = 1;
1593   ctx->Pixel.MapRtoRsize = 1;
1594   ctx->Pixel.MapGtoGsize = 1;
1595   ctx->Pixel.MapBtoBsize = 1;
1596   ctx->Pixel.MapAtoAsize = 1;
1597   ctx->Pixel.MapStoS[0] = 0;
1598   ctx->Pixel.MapItoI[0] = 0.0;
1599   ctx->Pixel.MapItoR[0] = 0.0;
1600   ctx->Pixel.MapItoG[0] = 0.0;
1601   ctx->Pixel.MapItoB[0] = 0.0;
1602   ctx->Pixel.MapItoA[0] = 0.0;
1603   ctx->Pixel.MapItoR8[0] = 0;
1604   ctx->Pixel.MapItoG8[0] = 0;
1605   ctx->Pixel.MapItoB8[0] = 0;
1606   ctx->Pixel.MapItoA8[0] = 0;
1607   ctx->Pixel.MapRtoR[0] = 0.0;
1608   ctx->Pixel.MapGtoG[0] = 0.0;
1609   ctx->Pixel.MapBtoB[0] = 0.0;
1610   ctx->Pixel.MapAtoA[0] = 0.0;
1611   ctx->Pixel.HistogramEnabled = GL_FALSE;
1612   ctx->Pixel.MinMaxEnabled = GL_FALSE;
1613   ASSIGN_4V(ctx->Pixel.PostColorMatrixScale, 1.0, 1.0, 1.0, 1.0);
1614   ASSIGN_4V(ctx->Pixel.PostColorMatrixBias, 0.0, 0.0, 0.0, 0.0);
1615   ASSIGN_4V(ctx->Pixel.ColorTableScale, 1.0, 1.0, 1.0, 1.0);
1616   ASSIGN_4V(ctx->Pixel.ColorTableBias, 0.0, 0.0, 0.0, 0.0);
1617   ASSIGN_4V(ctx->Pixel.PCCTscale, 1.0, 1.0, 1.0, 1.0);
1618   ASSIGN_4V(ctx->Pixel.PCCTbias, 0.0, 0.0, 0.0, 0.0);
1619   ASSIGN_4V(ctx->Pixel.PCMCTscale, 1.0, 1.0, 1.0, 1.0);
1620   ASSIGN_4V(ctx->Pixel.PCMCTbias, 0.0, 0.0, 0.0, 0.0);
1621   ctx->Pixel.ColorTableEnabled = GL_FALSE;
1622   ctx->Pixel.PostConvolutionColorTableEnabled = GL_FALSE;
1623   ctx->Pixel.PostColorMatrixColorTableEnabled = GL_FALSE;
1624   ctx->Pixel.Convolution1DEnabled = GL_FALSE;
1625   ctx->Pixel.Convolution2DEnabled = GL_FALSE;
1626   ctx->Pixel.Separable2DEnabled = GL_FALSE;
1627   for (i = 0; i < 3; i++) {
1628      ASSIGN_4V(ctx->Pixel.ConvolutionBorderColor[i], 0.0, 0.0, 0.0, 0.0);
1629      ctx->Pixel.ConvolutionBorderMode[i] = GL_REDUCE;
1630      ASSIGN_4V(ctx->Pixel.ConvolutionFilterScale[i], 1.0, 1.0, 1.0, 1.0);
1631      ASSIGN_4V(ctx->Pixel.ConvolutionFilterBias[i], 0.0, 0.0, 0.0, 0.0);
1632   }
1633   for (i = 0; i < MAX_CONVOLUTION_WIDTH * MAX_CONVOLUTION_WIDTH * 4; i++) {
1634      ctx->Convolution1D.Filter[i] = 0.0;
1635      ctx->Convolution2D.Filter[i] = 0.0;
1636      ctx->Separable2D.Filter[i] = 0.0;
1637   }
1638   ASSIGN_4V(ctx->Pixel.PostConvolutionScale, 1.0, 1.0, 1.0, 1.0);
1639   ASSIGN_4V(ctx->Pixel.PostConvolutionBias, 0.0, 0.0, 0.0, 0.0);
1640   /* GL_SGI_texture_color_table */
1641   ASSIGN_4V(ctx->Pixel.TextureColorTableScale, 1.0, 1.0, 1.0, 1.0);
1642   ASSIGN_4V(ctx->Pixel.TextureColorTableBias, 0.0, 0.0, 0.0, 0.0);
1643
1644   /* Pixel transfer */
1645   ctx->Pack.Alignment = 4;
1646   ctx->Pack.RowLength = 0;
1647   ctx->Pack.ImageHeight = 0;
1648   ctx->Pack.SkipPixels = 0;
1649   ctx->Pack.SkipRows = 0;
1650   ctx->Pack.SkipImages = 0;
1651   ctx->Pack.SwapBytes = GL_FALSE;
1652   ctx->Pack.LsbFirst = GL_FALSE;
1653   ctx->Pack.ClientStorage = GL_FALSE;
1654   ctx->Pack.Invert = GL_FALSE;
1655#if FEATURE_EXT_pixel_buffer_object
1656   ctx->Pack.BufferObj = ctx->Array.NullBufferObj;
1657#endif
1658   ctx->Unpack.Alignment = 4;
1659   ctx->Unpack.RowLength = 0;
1660   ctx->Unpack.ImageHeight = 0;
1661   ctx->Unpack.SkipPixels = 0;
1662   ctx->Unpack.SkipRows = 0;
1663   ctx->Unpack.SkipImages = 0;
1664   ctx->Unpack.SwapBytes = GL_FALSE;
1665   ctx->Unpack.LsbFirst = GL_FALSE;
1666   ctx->Unpack.ClientStorage = GL_FALSE;
1667   ctx->Unpack.Invert = GL_FALSE;
1668#if FEATURE_EXT_pixel_buffer_object
1669   ctx->Unpack.BufferObj = ctx->Array.NullBufferObj;
1670#endif
1671
1672   /*
1673    * _mesa_unpack_image() returns image data in this format.  When we
1674    * execute image commands (glDrawPixels(), glTexImage(), etc) from
1675    * within display lists we have to be sure to set the current
1676    * unpacking parameters to these values!
1677    */
1678   ctx->DefaultPacking.Alignment = 1;
1679   ctx->DefaultPacking.RowLength = 0;
1680   ctx->DefaultPacking.SkipPixels = 0;
1681   ctx->DefaultPacking.SkipRows = 0;
1682   ctx->DefaultPacking.ImageHeight = 0;
1683   ctx->DefaultPacking.SkipImages = 0;
1684   ctx->DefaultPacking.SwapBytes = GL_FALSE;
1685   ctx->DefaultPacking.LsbFirst = GL_FALSE;
1686   ctx->DefaultPacking.ClientStorage = GL_FALSE;
1687   ctx->DefaultPacking.Invert = GL_FALSE;
1688#if FEATURE_EXT_pixel_buffer_object
1689   ctx->DefaultPacking.BufferObj = ctx->Array.NullBufferObj;
1690#endif
1691
1692   if (ctx->Visual.doubleBufferMode) {
1693      ctx->Pixel.ReadBuffer = GL_BACK;
1694   }
1695   else {
1696      ctx->Pixel.ReadBuffer = GL_FRONT;
1697   }
1698
1699   /* Miscellaneous */
1700   ctx->_ImageTransferState = 0;
1701}
1702