pixel.c revision ba643a2094a1e844b6ce60f468057057557859ce
1/* $Id: pixel.c,v 1.14 2000/10/28 18:34:48 brianp Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version:  3.5
6 *
7 * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28#ifdef PC_HEADER
29#include "all.h"
30#else
31#include "glheader.h"
32#include "context.h"
33#include "macros.h"
34#include "mem.h"
35#include "pixel.h"
36#include "types.h"
37#endif
38
39
40
41/**********************************************************************/
42/*****                    glPixelZoom                             *****/
43/**********************************************************************/
44
45
46
47void
48_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor )
49{
50   GET_CURRENT_CONTEXT(ctx);
51   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPixelZoom");
52
53   ctx->Pixel.ZoomX = xfactor;
54   ctx->Pixel.ZoomY = yfactor;
55}
56
57
58
59/**********************************************************************/
60/*****                    glPixelStore                            *****/
61/**********************************************************************/
62
63
64void
65_mesa_PixelStorei( GLenum pname, GLint param )
66{
67   /* NOTE: this call can't be compiled into the display list */
68   GET_CURRENT_CONTEXT(ctx);
69   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPixelStore");
70
71   switch (pname) {
72      case GL_PACK_SWAP_BYTES:
73         ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
74	 break;
75      case GL_PACK_LSB_FIRST:
76         ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
77	 break;
78      case GL_PACK_ROW_LENGTH:
79	 if (param<0) {
80	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
81	 }
82	 else {
83	    ctx->Pack.RowLength = param;
84	 }
85	 break;
86      case GL_PACK_IMAGE_HEIGHT:
87         if (param<0)
88            gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
89         else
90            ctx->Pack.ImageHeight = param;
91         break;
92      case GL_PACK_SKIP_PIXELS:
93	 if (param<0) {
94	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
95	 }
96	 else {
97	    ctx->Pack.SkipPixels = param;
98	 }
99	 break;
100      case GL_PACK_SKIP_ROWS:
101	 if (param<0) {
102	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
103	 }
104	 else {
105	    ctx->Pack.SkipRows = param;
106	 }
107	 break;
108      case GL_PACK_SKIP_IMAGES:
109	 if (param<0) {
110	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
111	 }
112	 else {
113	    ctx->Pack.SkipImages = param;
114	 }
115	 break;
116      case GL_PACK_ALIGNMENT:
117         if (param==1 || param==2 || param==4 || param==8) {
118	    ctx->Pack.Alignment = param;
119	 }
120	 else {
121	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
122	 }
123	 break;
124      case GL_UNPACK_SWAP_BYTES:
125	 ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
126         break;
127      case GL_UNPACK_LSB_FIRST:
128	 ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
129	 break;
130      case GL_UNPACK_ROW_LENGTH:
131	 if (param<0) {
132	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
133	 }
134	 else {
135	    ctx->Unpack.RowLength = param;
136	 }
137	 break;
138      case GL_UNPACK_IMAGE_HEIGHT:
139         if (param<0)
140            gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
141         else
142            ctx->Unpack.ImageHeight = param;
143         break;
144      case GL_UNPACK_SKIP_PIXELS:
145	 if (param<0) {
146	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
147	 }
148	 else {
149	    ctx->Unpack.SkipPixels = param;
150	 }
151	 break;
152      case GL_UNPACK_SKIP_ROWS:
153	 if (param<0) {
154	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
155	 }
156	 else {
157	    ctx->Unpack.SkipRows = param;
158	 }
159	 break;
160      case GL_UNPACK_SKIP_IMAGES:
161	 if (param < 0) {
162	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
163	 }
164	 else {
165	    ctx->Unpack.SkipImages = param;
166	 }
167	 break;
168      case GL_UNPACK_ALIGNMENT:
169         if (param==1 || param==2 || param==4 || param==8) {
170	    ctx->Unpack.Alignment = param;
171	 }
172	 else {
173	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore" );
174	 }
175	 break;
176      default:
177	 gl_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
178   }
179}
180
181
182void
183_mesa_PixelStoref( GLenum pname, GLfloat param )
184{
185   _mesa_PixelStorei( pname, (GLint) param );
186}
187
188
189
190/**********************************************************************/
191/*****                         glPixelMap                         *****/
192/**********************************************************************/
193
194
195
196void
197_mesa_PixelMapfv( GLenum map, GLint mapsize, const GLfloat *values )
198{
199   GLint i;
200   GET_CURRENT_CONTEXT(ctx);
201   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPixelMapfv");
202
203
204   if (mapsize<0 || mapsize>MAX_PIXEL_MAP_TABLE) {
205      gl_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
206      return;
207   }
208
209   if (map>=GL_PIXEL_MAP_S_TO_S && map<=GL_PIXEL_MAP_I_TO_A) {
210      /* test that mapsize is a power of two */
211      GLuint p;
212      GLboolean ok = GL_FALSE;
213      for (p=1; p<=MAX_PIXEL_MAP_TABLE; p=p<<1) {
214	 if ( (p&mapsize) == p ) {
215	    ok = GL_TRUE;
216	    break;
217	 }
218      }
219      if (!ok) {
220	 gl_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
221         return;
222      }
223   }
224
225   switch (map) {
226      case GL_PIXEL_MAP_S_TO_S:
227         ctx->Pixel.MapStoSsize = mapsize;
228         for (i=0;i<mapsize;i++) {
229	    ctx->Pixel.MapStoS[i] = (GLint) values[i];
230	 }
231	 break;
232      case GL_PIXEL_MAP_I_TO_I:
233         ctx->Pixel.MapItoIsize = mapsize;
234         for (i=0;i<mapsize;i++) {
235	    ctx->Pixel.MapItoI[i] = (GLint) values[i];
236	 }
237	 break;
238      case GL_PIXEL_MAP_I_TO_R:
239         ctx->Pixel.MapItoRsize = mapsize;
240         for (i=0;i<mapsize;i++) {
241            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
242	    ctx->Pixel.MapItoR[i] = val;
243	    ctx->Pixel.MapItoR8[i] = (GLint) (val * 255.0F);
244	 }
245	 break;
246      case GL_PIXEL_MAP_I_TO_G:
247         ctx->Pixel.MapItoGsize = mapsize;
248         for (i=0;i<mapsize;i++) {
249            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
250	    ctx->Pixel.MapItoG[i] = val;
251	    ctx->Pixel.MapItoG8[i] = (GLint) (val * 255.0F);
252	 }
253	 break;
254      case GL_PIXEL_MAP_I_TO_B:
255         ctx->Pixel.MapItoBsize = mapsize;
256         for (i=0;i<mapsize;i++) {
257            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
258	    ctx->Pixel.MapItoB[i] = val;
259	    ctx->Pixel.MapItoB8[i] = (GLint) (val * 255.0F);
260	 }
261	 break;
262      case GL_PIXEL_MAP_I_TO_A:
263         ctx->Pixel.MapItoAsize = mapsize;
264         for (i=0;i<mapsize;i++) {
265            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
266	    ctx->Pixel.MapItoA[i] = val;
267	    ctx->Pixel.MapItoA8[i] = (GLint) (val * 255.0F);
268	 }
269	 break;
270      case GL_PIXEL_MAP_R_TO_R:
271         ctx->Pixel.MapRtoRsize = mapsize;
272         for (i=0;i<mapsize;i++) {
273	    ctx->Pixel.MapRtoR[i] = CLAMP( values[i], 0.0, 1.0 );
274	 }
275	 break;
276      case GL_PIXEL_MAP_G_TO_G:
277         ctx->Pixel.MapGtoGsize = mapsize;
278         for (i=0;i<mapsize;i++) {
279	    ctx->Pixel.MapGtoG[i] = CLAMP( values[i], 0.0, 1.0 );
280	 }
281	 break;
282      case GL_PIXEL_MAP_B_TO_B:
283         ctx->Pixel.MapBtoBsize = mapsize;
284         for (i=0;i<mapsize;i++) {
285	    ctx->Pixel.MapBtoB[i] = CLAMP( values[i], 0.0, 1.0 );
286	 }
287	 break;
288      case GL_PIXEL_MAP_A_TO_A:
289         ctx->Pixel.MapAtoAsize = mapsize;
290         for (i=0;i<mapsize;i++) {
291	    ctx->Pixel.MapAtoA[i] = CLAMP( values[i], 0.0, 1.0 );
292	 }
293	 break;
294      default:
295         gl_error( ctx, GL_INVALID_ENUM, "glPixelMapfv(map)" );
296   }
297}
298
299
300
301void
302_mesa_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values )
303{
304   GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
305   GLint i;
306   if (map==GL_PIXEL_MAP_I_TO_I || map==GL_PIXEL_MAP_S_TO_S) {
307      for (i=0;i<mapsize;i++) {
308         fvalues[i] = (GLfloat) values[i];
309      }
310   }
311   else {
312      for (i=0;i<mapsize;i++) {
313         fvalues[i] = UINT_TO_FLOAT( values[i] );
314      }
315   }
316   _mesa_PixelMapfv(map, mapsize, fvalues);
317}
318
319
320
321void
322_mesa_PixelMapusv(GLenum map, GLint mapsize, const GLushort *values )
323{
324   GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
325   GLint i;
326   if (map==GL_PIXEL_MAP_I_TO_I || map==GL_PIXEL_MAP_S_TO_S) {
327      for (i=0;i<mapsize;i++) {
328         fvalues[i] = (GLfloat) values[i];
329      }
330   }
331   else {
332      for (i=0;i<mapsize;i++) {
333         fvalues[i] = USHORT_TO_FLOAT( values[i] );
334      }
335   }
336   _mesa_PixelMapfv(map, mapsize, fvalues);
337}
338
339
340
341void
342_mesa_GetPixelMapfv( GLenum map, GLfloat *values )
343{
344   GET_CURRENT_CONTEXT(ctx);
345   GLint i;
346
347   ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetPixelMapfv");
348
349   switch (map) {
350      case GL_PIXEL_MAP_I_TO_I:
351         for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
352	    values[i] = (GLfloat) ctx->Pixel.MapItoI[i];
353	 }
354	 break;
355      case GL_PIXEL_MAP_S_TO_S:
356         for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
357	    values[i] = (GLfloat) ctx->Pixel.MapStoS[i];
358	 }
359	 break;
360      case GL_PIXEL_MAP_I_TO_R:
361         MEMCPY(values,ctx->Pixel.MapItoR,ctx->Pixel.MapItoRsize*sizeof(GLfloat));
362	 break;
363      case GL_PIXEL_MAP_I_TO_G:
364         MEMCPY(values,ctx->Pixel.MapItoG,ctx->Pixel.MapItoGsize*sizeof(GLfloat));
365	 break;
366      case GL_PIXEL_MAP_I_TO_B:
367         MEMCPY(values,ctx->Pixel.MapItoB,ctx->Pixel.MapItoBsize*sizeof(GLfloat));
368	 break;
369      case GL_PIXEL_MAP_I_TO_A:
370         MEMCPY(values,ctx->Pixel.MapItoA,ctx->Pixel.MapItoAsize*sizeof(GLfloat));
371	 break;
372      case GL_PIXEL_MAP_R_TO_R:
373         MEMCPY(values,ctx->Pixel.MapRtoR,ctx->Pixel.MapRtoRsize*sizeof(GLfloat));
374	 break;
375      case GL_PIXEL_MAP_G_TO_G:
376         MEMCPY(values,ctx->Pixel.MapGtoG,ctx->Pixel.MapGtoGsize*sizeof(GLfloat));
377	 break;
378      case GL_PIXEL_MAP_B_TO_B:
379         MEMCPY(values,ctx->Pixel.MapBtoB,ctx->Pixel.MapBtoBsize*sizeof(GLfloat));
380	 break;
381      case GL_PIXEL_MAP_A_TO_A:
382         MEMCPY(values,ctx->Pixel.MapAtoA,ctx->Pixel.MapAtoAsize*sizeof(GLfloat));
383	 break;
384      default:
385         gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
386   }
387}
388
389
390void
391_mesa_GetPixelMapuiv( GLenum map, GLuint *values )
392{
393   GET_CURRENT_CONTEXT(ctx);
394   GLint i;
395
396   ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetPixelMapfv");
397
398   switch (map) {
399      case GL_PIXEL_MAP_I_TO_I:
400         MEMCPY(values, ctx->Pixel.MapItoI, ctx->Pixel.MapItoIsize*sizeof(GLint));
401	 break;
402      case GL_PIXEL_MAP_S_TO_S:
403         MEMCPY(values, ctx->Pixel.MapStoS, ctx->Pixel.MapStoSsize*sizeof(GLint));
404	 break;
405      case GL_PIXEL_MAP_I_TO_R:
406	 for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
407	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoR[i] );
408	 }
409	 break;
410      case GL_PIXEL_MAP_I_TO_G:
411	 for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
412	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoG[i] );
413	 }
414	 break;
415      case GL_PIXEL_MAP_I_TO_B:
416	 for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
417	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoB[i] );
418	 }
419	 break;
420      case GL_PIXEL_MAP_I_TO_A:
421	 for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
422	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoA[i] );
423	 }
424	 break;
425      case GL_PIXEL_MAP_R_TO_R:
426	 for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
427	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapRtoR[i] );
428	 }
429	 break;
430      case GL_PIXEL_MAP_G_TO_G:
431	 for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
432	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapGtoG[i] );
433	 }
434	 break;
435      case GL_PIXEL_MAP_B_TO_B:
436	 for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
437	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapBtoB[i] );
438	 }
439	 break;
440      case GL_PIXEL_MAP_A_TO_A:
441	 for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
442	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapAtoA[i] );
443	 }
444	 break;
445      default:
446         gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
447   }
448}
449
450
451void
452_mesa_GetPixelMapusv( GLenum map, GLushort *values )
453{
454   GET_CURRENT_CONTEXT(ctx);
455   GLint i;
456
457   ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetPixelMapfv");
458
459   switch (map) {
460      case GL_PIXEL_MAP_I_TO_I:
461	 for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
462	    values[i] = (GLushort) ctx->Pixel.MapItoI[i];
463	 }
464	 break;
465      case GL_PIXEL_MAP_S_TO_S:
466	 for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
467	    values[i] = (GLushort) ctx->Pixel.MapStoS[i];
468	 }
469	 break;
470      case GL_PIXEL_MAP_I_TO_R:
471	 for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
472	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoR[i] );
473	 }
474	 break;
475      case GL_PIXEL_MAP_I_TO_G:
476	 for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
477	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoG[i] );
478	 }
479	 break;
480      case GL_PIXEL_MAP_I_TO_B:
481	 for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
482	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoB[i] );
483	 }
484	 break;
485      case GL_PIXEL_MAP_I_TO_A:
486	 for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
487	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoA[i] );
488	 }
489	 break;
490      case GL_PIXEL_MAP_R_TO_R:
491	 for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
492	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapRtoR[i] );
493	 }
494	 break;
495      case GL_PIXEL_MAP_G_TO_G:
496	 for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
497	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapGtoG[i] );
498	 }
499	 break;
500      case GL_PIXEL_MAP_B_TO_B:
501	 for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
502	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapBtoB[i] );
503	 }
504	 break;
505      case GL_PIXEL_MAP_A_TO_A:
506	 for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
507	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapAtoA[i] );
508	 }
509	 break;
510      default:
511         gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
512   }
513}
514
515
516
517/**********************************************************************/
518/*****                       glPixelTransfer                      *****/
519/**********************************************************************/
520
521
522/*
523 * Implements glPixelTransfer[fi] whether called immediately or from a
524 * display list.
525 */
526void
527_mesa_PixelTransferf( GLenum pname, GLfloat param )
528{
529   GET_CURRENT_CONTEXT(ctx);
530   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPixelTransfer");
531
532
533   switch (pname) {
534      case GL_MAP_COLOR:
535         ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
536	 break;
537      case GL_MAP_STENCIL:
538         ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
539	 break;
540      case GL_INDEX_SHIFT:
541         ctx->Pixel.IndexShift = (GLint) param;
542	 break;
543      case GL_INDEX_OFFSET:
544         ctx->Pixel.IndexOffset = (GLint) param;
545	 break;
546      case GL_RED_SCALE:
547         ctx->Pixel.RedScale = param;
548	 break;
549      case GL_RED_BIAS:
550         ctx->Pixel.RedBias = param;
551	 break;
552      case GL_GREEN_SCALE:
553         ctx->Pixel.GreenScale = param;
554	 break;
555      case GL_GREEN_BIAS:
556         ctx->Pixel.GreenBias = param;
557	 break;
558      case GL_BLUE_SCALE:
559         ctx->Pixel.BlueScale = param;
560	 break;
561      case GL_BLUE_BIAS:
562         ctx->Pixel.BlueBias = param;
563	 break;
564      case GL_ALPHA_SCALE:
565         ctx->Pixel.AlphaScale = param;
566	 break;
567      case GL_ALPHA_BIAS:
568         ctx->Pixel.AlphaBias = param;
569	 break;
570      case GL_DEPTH_SCALE:
571         ctx->Pixel.DepthScale = param;
572	 break;
573      case GL_DEPTH_BIAS:
574         ctx->Pixel.DepthBias = param;
575	 break;
576      case GL_POST_COLOR_MATRIX_RED_SCALE:
577         ctx->Pixel.PostColorMatrixScale[0] = param;
578	 break;
579      case GL_POST_COLOR_MATRIX_RED_BIAS:
580         ctx->Pixel.PostColorMatrixBias[0] = param;
581	 break;
582      case GL_POST_COLOR_MATRIX_GREEN_SCALE:
583         ctx->Pixel.PostColorMatrixScale[1] = param;
584	 break;
585      case GL_POST_COLOR_MATRIX_GREEN_BIAS:
586         ctx->Pixel.PostColorMatrixBias[1] = param;
587	 break;
588      case GL_POST_COLOR_MATRIX_BLUE_SCALE:
589         ctx->Pixel.PostColorMatrixScale[2] = param;
590	 break;
591      case GL_POST_COLOR_MATRIX_BLUE_BIAS:
592         ctx->Pixel.PostColorMatrixBias[2] = param;
593	 break;
594      case GL_POST_COLOR_MATRIX_ALPHA_SCALE:
595         ctx->Pixel.PostColorMatrixScale[3] = param;
596	 break;
597      case GL_POST_COLOR_MATRIX_ALPHA_BIAS:
598         ctx->Pixel.PostColorMatrixBias[3] = param;
599	 break;
600      case GL_POST_CONVOLUTION_RED_SCALE:
601         ctx->Pixel.PostConvolutionScale[0] = param;
602	 break;
603      case GL_POST_CONVOLUTION_RED_BIAS:
604         ctx->Pixel.PostConvolutionBias[0] = param;
605	 break;
606      case GL_POST_CONVOLUTION_GREEN_SCALE:
607         ctx->Pixel.PostConvolutionScale[1] = param;
608	 break;
609      case GL_POST_CONVOLUTION_GREEN_BIAS:
610         ctx->Pixel.PostConvolutionBias[1] = param;
611	 break;
612      case GL_POST_CONVOLUTION_BLUE_SCALE:
613         ctx->Pixel.PostConvolutionScale[2] = param;
614	 break;
615      case GL_POST_CONVOLUTION_BLUE_BIAS:
616         ctx->Pixel.PostConvolutionBias[2] = param;
617	 break;
618      case GL_POST_CONVOLUTION_ALPHA_SCALE:
619         ctx->Pixel.PostConvolutionScale[2] = param;
620	 break;
621      case GL_POST_CONVOLUTION_ALPHA_BIAS:
622         ctx->Pixel.PostConvolutionBias[2] = param;
623	 break;
624      default:
625         gl_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
626         return;
627   }
628
629   /* signal to recompute the bitmask */
630   ctx->ImageTransferState = UPDATE_IMAGE_TRANSFER_STATE;
631}
632
633
634void
635_mesa_PixelTransferi( GLenum pname, GLint param )
636{
637   _mesa_PixelTransferf( pname, (GLfloat) param );
638}
639
640
641
642/**********************************************************************/
643/*****                  Pixel processing functions               ******/
644/**********************************************************************/
645
646
647/*
648 * Apply scale and bias factors to an array of RGBA pixels.
649 */
650void
651_mesa_scale_and_bias_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4])
652{
653   if (ctx->Pixel.RedScale != 1.0 || ctx->Pixel.RedBias != 0.0) {
654      const GLfloat scale = ctx->Pixel.RedScale;
655      const GLfloat bias = ctx->Pixel.RedBias;
656      GLuint i;
657      for (i = 0; i < n; i++) {
658         rgba[i][RCOMP] = rgba[i][RCOMP] * scale + bias;
659      }
660   }
661   if (ctx->Pixel.GreenScale != 1.0 || ctx->Pixel.GreenBias != 0.0) {
662      const GLfloat scale = ctx->Pixel.GreenScale;
663      const GLfloat bias = ctx->Pixel.GreenBias;
664      GLuint i;
665      for (i = 0; i < n; i++) {
666         rgba[i][GCOMP] = rgba[i][GCOMP] * scale + bias;
667      }
668   }
669   if (ctx->Pixel.BlueScale != 1.0 || ctx->Pixel.BlueBias != 0.0) {
670      const GLfloat scale = ctx->Pixel.BlueScale;
671      const GLfloat bias = ctx->Pixel.BlueBias;
672      GLuint i;
673      for (i = 0; i < n; i++) {
674         rgba[i][BCOMP] = rgba[i][BCOMP] * scale + bias;
675      }
676   }
677   if (ctx->Pixel.AlphaScale != 1.0 || ctx->Pixel.AlphaBias != 0.0) {
678      const GLfloat scale = ctx->Pixel.AlphaScale;
679      const GLfloat bias = ctx->Pixel.AlphaBias;
680      GLuint i;
681      for (i = 0; i < n; i++) {
682         rgba[i][ACOMP] = rgba[i][ACOMP] * scale + bias;
683      }
684   }
685}
686
687
688/*
689 * Apply pixel mapping to an array of floating point RGBA pixels.
690 */
691void
692_mesa_map_rgba( const GLcontext *ctx, GLuint n, GLfloat rgba[][4] )
693{
694   const GLfloat rscale = ctx->Pixel.MapRtoRsize - 1;
695   const GLfloat gscale = ctx->Pixel.MapGtoGsize - 1;
696   const GLfloat bscale = ctx->Pixel.MapBtoBsize - 1;
697   const GLfloat ascale = ctx->Pixel.MapAtoAsize - 1;
698   const GLfloat *rMap = ctx->Pixel.MapRtoR;
699   const GLfloat *gMap = ctx->Pixel.MapGtoG;
700   const GLfloat *bMap = ctx->Pixel.MapBtoB;
701   const GLfloat *aMap = ctx->Pixel.MapAtoA;
702   GLuint i;
703   for (i=0;i<n;i++) {
704      rgba[i][RCOMP] = rMap[(GLint) (rgba[i][RCOMP] * rscale + 0.5F)];
705      rgba[i][GCOMP] = gMap[(GLint) (rgba[i][GCOMP] * gscale + 0.5F)];
706      rgba[i][BCOMP] = bMap[(GLint) (rgba[i][BCOMP] * bscale + 0.5F)];
707      rgba[i][ACOMP] = aMap[(GLint) (rgba[i][ACOMP] * ascale + 0.5F)];
708   }
709}
710
711
712/*
713 * Apply the color matrix and post color matrix scaling and biasing.
714 */
715void
716_mesa_transform_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4])
717{
718   const GLfloat rs = ctx->Pixel.PostColorMatrixScale[0];
719   const GLfloat rb = ctx->Pixel.PostColorMatrixBias[0];
720   const GLfloat gs = ctx->Pixel.PostColorMatrixScale[1];
721   const GLfloat gb = ctx->Pixel.PostColorMatrixBias[1];
722   const GLfloat bs = ctx->Pixel.PostColorMatrixScale[2];
723   const GLfloat bb = ctx->Pixel.PostColorMatrixBias[2];
724   const GLfloat as = ctx->Pixel.PostColorMatrixScale[3];
725   const GLfloat ab = ctx->Pixel.PostColorMatrixBias[3];
726   const GLfloat *m = ctx->ColorMatrix.m;
727   GLuint i;
728   for (i = 0; i < n; i++) {
729      const GLfloat r = rgba[i][RCOMP];
730      const GLfloat g = rgba[i][GCOMP];
731      const GLfloat b = rgba[i][BCOMP];
732      const GLfloat a = rgba[i][ACOMP];
733      rgba[i][RCOMP] = (m[0] * r + m[4] * g + m[ 8] * b + m[12] * a) * rs + rb;
734      rgba[i][GCOMP] = (m[1] * r + m[5] * g + m[ 9] * b + m[13] * a) * gs + gb;
735      rgba[i][BCOMP] = (m[2] * r + m[6] * g + m[10] * b + m[14] * a) * bs + bb;
736      rgba[i][ACOMP] = (m[3] * r + m[7] * g + m[11] * b + m[15] * a) * as + ab;
737   }
738}
739
740
741/*
742 * Apply a color table lookup to an array of colors.
743 */
744void
745_mesa_lookup_rgba(const struct gl_color_table *table,
746                  GLuint n, GLfloat rgba[][4])
747{
748   ASSERT(table->FloatTable);
749   if (!table->Table)
750      return;
751
752   switch (table->Format) {
753      case GL_INTENSITY:
754         /* replace RGBA with I */
755         if (!table->FloatTable) {
756            const GLfloat scale = (GLfloat) (table->Size - 1);
757            const GLubyte *lut = (const GLubyte *) table->Table;
758            GLuint i;
759            for (i = 0; i < n; i++) {
760               GLint j = (GLint) (rgba[i][RCOMP] * scale + 0.5F);
761               GLfloat c = lut[j] * (1.0F / 255.0F);
762               rgba[i][RCOMP] = rgba[i][GCOMP] =
763                  rgba[i][BCOMP] = rgba[i][ACOMP] = c;
764            }
765
766         }
767         else {
768            const GLfloat scale = (GLfloat) (table->Size - 1);
769            const GLfloat *lut = (const GLfloat *) table->Table;
770            GLuint i;
771            for (i = 0; i < n; i++) {
772               GLint j = (GLint) (rgba[i][RCOMP] * scale + 0.5F);
773               GLfloat c = lut[j];
774               rgba[i][RCOMP] = rgba[i][GCOMP] =
775                  rgba[i][BCOMP] = rgba[i][ACOMP] = c;
776            }
777         }
778         break;
779      case GL_LUMINANCE:
780         /* replace RGB with L */
781         if (!table->FloatTable) {
782            const GLfloat scale = (GLfloat) (table->Size - 1);
783            const GLubyte *lut = (const GLubyte *) table->Table;
784            GLuint i;
785            for (i = 0; i < n; i++) {
786               GLint j = (GLint) (rgba[i][RCOMP] * scale + 0.5F);
787               GLfloat c = lut[j] * (1.0F / 255.0F);
788               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
789            }
790         }
791         else {
792            const GLfloat scale = (GLfloat) (table->Size - 1);
793            const GLfloat *lut = (const GLfloat *) table->Table;
794            GLuint i;
795            for (i = 0; i < n; i++) {
796               GLint j = (GLint) (rgba[i][RCOMP] * scale + 0.5F);
797               GLfloat c = lut[j];
798               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
799            }
800         }
801         break;
802      case GL_ALPHA:
803         /* replace A with A */
804         if (!table->FloatTable) {
805            const GLfloat scale = (GLfloat) (table->Size - 1);
806            const GLubyte *lut = (const GLubyte *) table->Table;
807            GLuint i;
808            for (i = 0; i < n; i++) {
809               GLint j = (GLint) (rgba[i][ACOMP] * scale + 0.5F);
810               rgba[i][ACOMP] = lut[j] * (1.0F / 255.0F);
811            }
812         }
813         else  {
814            const GLfloat scale = (GLfloat) (table->Size - 1);
815            const GLfloat *lut = (const GLfloat *) table->Table;
816            GLuint i;
817            for (i = 0; i < n; i++) {
818               GLint j = (GLint) (rgba[i][ACOMP] * scale + 0.5F);
819               rgba[i][ACOMP] = lut[j];
820            }
821         }
822         break;
823      case GL_LUMINANCE_ALPHA:
824         /* replace RGBA with LLLA */
825         if (!table->FloatTable) {
826            const GLfloat scale = (GLfloat) (table->Size - 1);
827            const GLubyte *lut = (const GLubyte *) table->Table;
828            GLuint i;
829            for (i = 0; i < n; i++) {
830               GLint jL = (GLint) (rgba[i][RCOMP] * scale + 0.5F);
831               GLint jA = (GLint) (rgba[i][ACOMP] * scale + 0.5F);
832               GLfloat luminance = lut[jL * 2 + 0] * (1.0F / 255.0F);
833               GLfloat alpha     = lut[jA * 2 + 1] * (1.0F / 255.0F);
834               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
835               rgba[i][ACOMP] = alpha;;
836            }
837         }
838         else {
839            const GLfloat scale = (GLfloat) (table->Size - 1);
840            const GLfloat *lut = (const GLfloat *) table->Table;
841            GLuint i;
842            for (i = 0; i < n; i++) {
843               GLint jL = (GLint) (rgba[i][RCOMP] * scale + 0.5F);
844               GLint jA = (GLint) (rgba[i][ACOMP] * scale + 0.5F);
845               GLfloat luminance = lut[jL * 2 + 0];
846               GLfloat alpha     = lut[jA * 2 + 1];
847               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
848               rgba[i][ACOMP] = alpha;;
849            }
850         }
851         break;
852      case GL_RGB:
853         /* replace RGB with RGB */
854         if (!table->FloatTable) {
855            const GLfloat scale = (GLfloat) (table->Size - 1);
856            const GLubyte *lut = (const GLubyte *) table->Table;
857            GLuint i;
858            for (i = 0; i < n; i++) {
859               GLint jR = (GLint) (rgba[i][RCOMP] * scale + 0.5F);
860               GLint jG = (GLint) (rgba[i][GCOMP] * scale + 0.5F);
861               GLint jB = (GLint) (rgba[i][BCOMP] * scale + 0.5F);
862               rgba[i][RCOMP] = lut[jR * 3 + 0] * (1.0F / 255.0F);
863               rgba[i][GCOMP] = lut[jG * 3 + 1] * (1.0F / 255.0F);
864               rgba[i][BCOMP] = lut[jB * 3 + 2] * (1.0F / 255.0F);
865            }
866         }
867         else {
868            const GLfloat scale = (GLfloat) (table->Size - 1);
869            const GLfloat *lut = (const GLfloat *) table->Table;
870            GLuint i;
871            for (i = 0; i < n; i++) {
872               GLint jR = (GLint) (rgba[i][RCOMP] * scale + 0.5F);
873               GLint jG = (GLint) (rgba[i][GCOMP] * scale + 0.5F);
874               GLint jB = (GLint) (rgba[i][BCOMP] * scale + 0.5F);
875               rgba[i][RCOMP] = lut[jR * 3 + 0];
876               rgba[i][GCOMP] = lut[jG * 3 + 1];
877               rgba[i][BCOMP] = lut[jB * 3 + 2];
878            }
879         }
880         break;
881      case GL_RGBA:
882         /* replace RGBA with RGBA */
883         if (!table->FloatTable) {
884            const GLfloat scale = (GLfloat) (table->Size - 1);
885            const GLubyte *lut = (const GLubyte *) table->Table;
886            GLuint i;
887            for (i = 0; i < n; i++) {
888               GLint jR = (GLint) (rgba[i][RCOMP] * scale + 0.5F);
889               GLint jG = (GLint) (rgba[i][GCOMP] * scale + 0.5F);
890               GLint jB = (GLint) (rgba[i][BCOMP] * scale + 0.5F);
891               GLint jA = (GLint) (rgba[i][ACOMP] * scale + 0.5F);
892               rgba[i][RCOMP] = lut[jR * 4 + 0] * (1.0F / 255.0F);
893               rgba[i][GCOMP] = lut[jG * 4 + 1] * (1.0F / 255.0F);
894               rgba[i][BCOMP] = lut[jB * 4 + 2] * (1.0F / 255.0F);
895               rgba[i][ACOMP] = lut[jA * 4 + 3] * (1.0F / 255.0F);
896            }
897         }
898         else {
899            const GLfloat scale = (GLfloat) (table->Size - 1);
900            const GLfloat *lut = (const GLfloat *) table->Table;
901            GLuint i;
902            for (i = 0; i < n; i++) {
903               GLint jR = (GLint) (rgba[i][RCOMP] * scale + 0.5F);
904               GLint jG = (GLint) (rgba[i][GCOMP] * scale + 0.5F);
905               GLint jB = (GLint) (rgba[i][BCOMP] * scale + 0.5F);
906               GLint jA = (GLint) (rgba[i][ACOMP] * scale + 0.5F);
907               rgba[i][RCOMP] = lut[jR * 4 + 0];
908               rgba[i][GCOMP] = lut[jG * 4 + 1];
909               rgba[i][BCOMP] = lut[jB * 4 + 2];
910               rgba[i][ACOMP] = lut[jA * 4 + 3];
911            }
912         }
913         break;
914      default:
915         gl_problem(NULL, "Bad format in _mesa_lookup_rgba");
916         return;
917   }
918}
919
920
921
922/*
923 * Apply color index shift and offset to an array of pixels.
924 */
925void
926_mesa_shift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] )
927{
928   GLint shift = ctx->Pixel.IndexShift;
929   GLint offset = ctx->Pixel.IndexOffset;
930   GLuint i;
931   if (shift > 0) {
932      for (i=0;i<n;i++) {
933         indexes[i] = (indexes[i] << shift) + offset;
934      }
935   }
936   else if (shift < 0) {
937      shift = -shift;
938      for (i=0;i<n;i++) {
939         indexes[i] = (indexes[i] >> shift) + offset;
940      }
941   }
942   else {
943      for (i=0;i<n;i++) {
944         indexes[i] = indexes[i] + offset;
945      }
946   }
947}
948
949
950/*
951 * Apply color index mapping to color indexes.
952 */
953void
954_mesa_map_ci( const GLcontext *ctx, GLuint n, GLuint index[] )
955{
956   GLuint mask = ctx->Pixel.MapItoIsize - 1;
957   GLuint i;
958   for (i=0;i<n;i++) {
959      index[i] = ctx->Pixel.MapItoI[ index[i] & mask ];
960   }
961}
962
963
964/*
965 * Map color indexes to rgba values.
966 */
967void
968_mesa_map_ci_to_rgba_ubyte( const GLcontext *ctx, GLuint n,
969                            const GLuint index[], GLubyte rgba[][4] )
970{
971   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
972   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
973   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
974   GLuint amask = ctx->Pixel.MapItoAsize - 1;
975   const GLubyte *rMap = ctx->Pixel.MapItoR8;
976   const GLubyte *gMap = ctx->Pixel.MapItoG8;
977   const GLubyte *bMap = ctx->Pixel.MapItoB8;
978   const GLubyte *aMap = ctx->Pixel.MapItoA8;
979   GLuint i;
980   for (i=0;i<n;i++) {
981      rgba[i][RCOMP] = rMap[index[i] & rmask];
982      rgba[i][GCOMP] = gMap[index[i] & gmask];
983      rgba[i][BCOMP] = bMap[index[i] & bmask];
984      rgba[i][ACOMP] = aMap[index[i] & amask];
985   }
986}
987
988
989/*
990 * Map color indexes to float rgba values.
991 */
992void
993_mesa_map_ci_to_rgba( const GLcontext *ctx, GLuint n,
994                      const GLuint index[], GLfloat rgba[][4] )
995{
996   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
997   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
998   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
999   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1000   const GLfloat *rMap = ctx->Pixel.MapItoR;
1001   const GLfloat *gMap = ctx->Pixel.MapItoG;
1002   const GLfloat *bMap = ctx->Pixel.MapItoB;
1003   const GLfloat *aMap = ctx->Pixel.MapItoA;
1004   GLuint i;
1005   for (i=0;i<n;i++) {
1006      rgba[i][RCOMP] = rMap[index[i] & rmask];
1007      rgba[i][GCOMP] = gMap[index[i] & gmask];
1008      rgba[i][BCOMP] = bMap[index[i] & bmask];
1009      rgba[i][ACOMP] = aMap[index[i] & amask];
1010   }
1011}
1012
1013
1014/*
1015 * Map 8-bit color indexes to rgb values.
1016 */
1017void
1018_mesa_map_ci8_to_rgba( const GLcontext *ctx, GLuint n, const GLubyte index[],
1019                       GLubyte rgba[][4] )
1020{
1021   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1022   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1023   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1024   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1025   const GLubyte *rMap = ctx->Pixel.MapItoR8;
1026   const GLubyte *gMap = ctx->Pixel.MapItoG8;
1027   const GLubyte *bMap = ctx->Pixel.MapItoB8;
1028   const GLubyte *aMap = ctx->Pixel.MapItoA8;
1029   GLuint i;
1030   for (i=0;i<n;i++) {
1031      rgba[i][RCOMP] = rMap[index[i] & rmask];
1032      rgba[i][GCOMP] = gMap[index[i] & gmask];
1033      rgba[i][BCOMP] = bMap[index[i] & bmask];
1034      rgba[i][ACOMP] = aMap[index[i] & amask];
1035   }
1036}
1037
1038
1039void
1040_mesa_shift_and_offset_stencil( const GLcontext *ctx, GLuint n,
1041                                GLstencil stencil[] )
1042{
1043   GLuint i;
1044   GLint shift = ctx->Pixel.IndexShift;
1045   GLint offset = ctx->Pixel.IndexOffset;
1046   if (shift > 0) {
1047      for (i=0;i<n;i++) {
1048         stencil[i] = (stencil[i] << shift) + offset;
1049      }
1050   }
1051   else if (shift < 0) {
1052      shift = -shift;
1053      for (i=0;i<n;i++) {
1054         stencil[i] = (stencil[i] >> shift) + offset;
1055      }
1056   }
1057   else {
1058      for (i=0;i<n;i++) {
1059         stencil[i] = stencil[i] + offset;
1060      }
1061   }
1062
1063}
1064
1065
1066void
1067_mesa_map_stencil( const GLcontext *ctx, GLuint n, GLstencil stencil[] )
1068{
1069   GLuint mask = ctx->Pixel.MapStoSsize - 1;
1070   GLuint i;
1071   for (i=0;i<n;i++) {
1072      stencil[i] = ctx->Pixel.MapStoS[ stencil[i] & mask ];
1073   }
1074}
1075