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