pixel.c revision 33143303feaf84afbef2e63ac0adab2d70b3c344
1/* $Id: pixel.c,v 1.28 2001/04/10 15:25:45 brianp Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version:  3.5
6 *
7 * Copyright (C) 1999-2001  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 "colormac.h"
33#include "context.h"
34#include "macros.h"
35#include "mem.h"
36#include "pixel.h"
37#include "mtypes.h"
38#endif
39
40
41
42/**********************************************************************/
43/*****                    glPixelZoom                             *****/
44/**********************************************************************/
45
46
47
48void
49_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor )
50{
51   GET_CURRENT_CONTEXT(ctx);
52
53   if (ctx->Pixel.ZoomX == xfactor &&
54       ctx->Pixel.ZoomY == yfactor)
55      return;
56
57   FLUSH_VERTICES(ctx, _NEW_PIXEL);
58   ctx->Pixel.ZoomX = xfactor;
59   ctx->Pixel.ZoomY = yfactor;
60}
61
62
63
64/**********************************************************************/
65/*****                    glPixelStore                            *****/
66/**********************************************************************/
67
68
69void
70_mesa_PixelStorei( GLenum pname, GLint param )
71{
72   /* NOTE: this call can't be compiled into the display list */
73   GET_CURRENT_CONTEXT(ctx);
74   ASSERT_OUTSIDE_BEGIN_END(ctx);
75
76   switch (pname) {
77      case GL_PACK_SWAP_BYTES:
78	 if (param == (GLint)ctx->Pack.SwapBytes)
79	    return;
80	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
81         ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
82	 break;
83      case GL_PACK_LSB_FIRST:
84	 if (param == (GLint)ctx->Pack.LsbFirst)
85	    return;
86	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
87         ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
88	 break;
89      case GL_PACK_ROW_LENGTH:
90	 if (param<0) {
91	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
92	    return;
93	 }
94	 if (ctx->Pack.RowLength == param)
95	    return;
96	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
97	 ctx->Pack.RowLength = param;
98	 break;
99      case GL_PACK_IMAGE_HEIGHT:
100         if (param<0) {
101            _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
102	    return;
103	 }
104	 if (ctx->Pack.ImageHeight == param)
105	    return;
106	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
107	 ctx->Pack.ImageHeight = param;
108         break;
109      case GL_PACK_SKIP_PIXELS:
110	 if (param<0) {
111	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
112	    return;
113	 }
114	 if (ctx->Pack.SkipPixels == param)
115	    return;
116	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
117	 ctx->Pack.SkipPixels = param;
118	 break;
119      case GL_PACK_SKIP_ROWS:
120	 if (param<0) {
121	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
122	    return;
123	 }
124	 if (ctx->Pack.SkipRows == param)
125	    return;
126	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
127	 ctx->Pack.SkipRows = param;
128	 break;
129      case GL_PACK_SKIP_IMAGES:
130	 if (param<0) {
131	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
132	    return;
133	 }
134	 if (ctx->Pack.SkipImages == param)
135	    return;
136	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
137	 ctx->Pack.SkipImages = param;
138	 break;
139      case GL_PACK_ALIGNMENT:
140         if (param!=1 && param!=2 && param!=4 && param!=8) {
141	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
142	    return;
143	 }
144	 if (ctx->Pack.Alignment == param)
145	    return;
146	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
147	 ctx->Pack.Alignment = param;
148	 break;
149      case GL_UNPACK_SWAP_BYTES:
150	 if (param == (GLint)ctx->Unpack.SwapBytes)
151	    return;
152	 if ((GLint)ctx->Unpack.SwapBytes == param)
153	    return;
154	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
155	 ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
156         break;
157      case GL_UNPACK_LSB_FIRST:
158	 if (param == (GLint)ctx->Unpack.LsbFirst)
159	    return;
160	 if ((GLint)ctx->Unpack.LsbFirst == param)
161	    return;
162	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
163	 ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
164	 break;
165      case GL_UNPACK_ROW_LENGTH:
166	 if (param<0) {
167	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
168	    return;
169	 }
170	 if (ctx->Unpack.RowLength == param)
171	    return;
172	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
173	 ctx->Unpack.RowLength = param;
174	 break;
175      case GL_UNPACK_IMAGE_HEIGHT:
176         if (param<0) {
177            _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
178	    return;
179	 }
180	 if (ctx->Unpack.ImageHeight == param)
181	    return;
182
183	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
184	 ctx->Unpack.ImageHeight = param;
185         break;
186      case GL_UNPACK_SKIP_PIXELS:
187	 if (param<0) {
188	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
189	    return;
190	 }
191	 if (ctx->Unpack.SkipPixels == param)
192	    return;
193	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
194	 ctx->Unpack.SkipPixels = param;
195	 break;
196      case GL_UNPACK_SKIP_ROWS:
197	 if (param<0) {
198	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
199	    return;
200	 }
201	 if (ctx->Unpack.SkipRows == param)
202	    return;
203	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
204	 ctx->Unpack.SkipRows = param;
205	 break;
206      case GL_UNPACK_SKIP_IMAGES:
207	 if (param < 0) {
208	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
209	    return;
210	 }
211	 if (ctx->Unpack.SkipImages == param)
212	    return;
213	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
214	 ctx->Unpack.SkipImages = param;
215	 break;
216      case GL_UNPACK_ALIGNMENT:
217         if (param!=1 && param!=2 && param!=4 && param!=8) {
218	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore" );
219	    return;
220	 }
221	 if (ctx->Unpack.Alignment == param)
222	    return;
223	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
224	 ctx->Unpack.Alignment = param;
225	 break;
226      default:
227	 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
228	 return;
229   }
230}
231
232
233void
234_mesa_PixelStoref( GLenum pname, GLfloat param )
235{
236   _mesa_PixelStorei( pname, (GLint) param );
237}
238
239
240
241/**********************************************************************/
242/*****                         glPixelMap                         *****/
243/**********************************************************************/
244
245
246
247void
248_mesa_PixelMapfv( GLenum map, GLint mapsize, const GLfloat *values )
249{
250   GLint i;
251   GET_CURRENT_CONTEXT(ctx);
252   ASSERT_OUTSIDE_BEGIN_END(ctx);
253
254   if (mapsize<0 || mapsize>MAX_PIXEL_MAP_TABLE) {
255      _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
256      return;
257   }
258
259   if (map>=GL_PIXEL_MAP_S_TO_S && map<=GL_PIXEL_MAP_I_TO_A) {
260      /* test that mapsize is a power of two */
261      GLuint p;
262      GLboolean ok = GL_FALSE;
263      for (p=1; p<=MAX_PIXEL_MAP_TABLE; p=p<<1) {
264	 if ( (p&mapsize) == p ) {
265	    ok = GL_TRUE;
266	    break;
267	 }
268      }
269      if (!ok) {
270	 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
271         return;
272      }
273   }
274
275   FLUSH_VERTICES(ctx, _NEW_PIXEL);
276
277   switch (map) {
278      case GL_PIXEL_MAP_S_TO_S:
279         ctx->Pixel.MapStoSsize = mapsize;
280         for (i=0;i<mapsize;i++) {
281	    ctx->Pixel.MapStoS[i] = (GLint) values[i];
282	 }
283	 break;
284      case GL_PIXEL_MAP_I_TO_I:
285         ctx->Pixel.MapItoIsize = mapsize;
286         for (i=0;i<mapsize;i++) {
287	    ctx->Pixel.MapItoI[i] = (GLint) values[i];
288	 }
289	 break;
290      case GL_PIXEL_MAP_I_TO_R:
291         ctx->Pixel.MapItoRsize = mapsize;
292         for (i=0;i<mapsize;i++) {
293            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
294	    ctx->Pixel.MapItoR[i] = val;
295	    ctx->Pixel.MapItoR8[i] = (GLint) (val * 255.0F);
296	 }
297	 break;
298      case GL_PIXEL_MAP_I_TO_G:
299         ctx->Pixel.MapItoGsize = mapsize;
300         for (i=0;i<mapsize;i++) {
301            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
302	    ctx->Pixel.MapItoG[i] = val;
303	    ctx->Pixel.MapItoG8[i] = (GLint) (val * 255.0F);
304	 }
305	 break;
306      case GL_PIXEL_MAP_I_TO_B:
307         ctx->Pixel.MapItoBsize = mapsize;
308         for (i=0;i<mapsize;i++) {
309            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
310	    ctx->Pixel.MapItoB[i] = val;
311	    ctx->Pixel.MapItoB8[i] = (GLint) (val * 255.0F);
312	 }
313	 break;
314      case GL_PIXEL_MAP_I_TO_A:
315         ctx->Pixel.MapItoAsize = mapsize;
316         for (i=0;i<mapsize;i++) {
317            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
318	    ctx->Pixel.MapItoA[i] = val;
319	    ctx->Pixel.MapItoA8[i] = (GLint) (val * 255.0F);
320	 }
321	 break;
322      case GL_PIXEL_MAP_R_TO_R:
323         ctx->Pixel.MapRtoRsize = mapsize;
324         for (i=0;i<mapsize;i++) {
325	    ctx->Pixel.MapRtoR[i] = CLAMP( values[i], 0.0, 1.0 );
326	 }
327	 break;
328      case GL_PIXEL_MAP_G_TO_G:
329         ctx->Pixel.MapGtoGsize = mapsize;
330         for (i=0;i<mapsize;i++) {
331	    ctx->Pixel.MapGtoG[i] = CLAMP( values[i], 0.0, 1.0 );
332	 }
333	 break;
334      case GL_PIXEL_MAP_B_TO_B:
335         ctx->Pixel.MapBtoBsize = mapsize;
336         for (i=0;i<mapsize;i++) {
337	    ctx->Pixel.MapBtoB[i] = CLAMP( values[i], 0.0, 1.0 );
338	 }
339	 break;
340      case GL_PIXEL_MAP_A_TO_A:
341         ctx->Pixel.MapAtoAsize = mapsize;
342         for (i=0;i<mapsize;i++) {
343	    ctx->Pixel.MapAtoA[i] = CLAMP( values[i], 0.0, 1.0 );
344	 }
345	 break;
346      default:
347         _mesa_error( ctx, GL_INVALID_ENUM, "glPixelMapfv(map)" );
348   }
349}
350
351
352
353void
354_mesa_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values )
355{
356   GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
357   GLint i;
358   if (map==GL_PIXEL_MAP_I_TO_I || map==GL_PIXEL_MAP_S_TO_S) {
359      for (i=0;i<mapsize;i++) {
360         fvalues[i] = (GLfloat) values[i];
361      }
362   }
363   else {
364      for (i=0;i<mapsize;i++) {
365         fvalues[i] = UINT_TO_FLOAT( values[i] );
366      }
367   }
368   _mesa_PixelMapfv(map, mapsize, fvalues);
369}
370
371
372
373void
374_mesa_PixelMapusv(GLenum map, GLint mapsize, const GLushort *values )
375{
376   GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
377   GLint i;
378   if (map==GL_PIXEL_MAP_I_TO_I || map==GL_PIXEL_MAP_S_TO_S) {
379      for (i=0;i<mapsize;i++) {
380         fvalues[i] = (GLfloat) values[i];
381      }
382   }
383   else {
384      for (i=0;i<mapsize;i++) {
385         fvalues[i] = USHORT_TO_FLOAT( values[i] );
386      }
387   }
388   _mesa_PixelMapfv(map, mapsize, fvalues);
389}
390
391
392
393void
394_mesa_GetPixelMapfv( GLenum map, GLfloat *values )
395{
396   GET_CURRENT_CONTEXT(ctx);
397   GLint i;
398   ASSERT_OUTSIDE_BEGIN_END(ctx);
399
400   switch (map) {
401      case GL_PIXEL_MAP_I_TO_I:
402         for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
403	    values[i] = (GLfloat) ctx->Pixel.MapItoI[i];
404	 }
405	 break;
406      case GL_PIXEL_MAP_S_TO_S:
407         for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
408	    values[i] = (GLfloat) ctx->Pixel.MapStoS[i];
409	 }
410	 break;
411      case GL_PIXEL_MAP_I_TO_R:
412         MEMCPY(values,ctx->Pixel.MapItoR,ctx->Pixel.MapItoRsize*sizeof(GLfloat));
413	 break;
414      case GL_PIXEL_MAP_I_TO_G:
415         MEMCPY(values,ctx->Pixel.MapItoG,ctx->Pixel.MapItoGsize*sizeof(GLfloat));
416	 break;
417      case GL_PIXEL_MAP_I_TO_B:
418         MEMCPY(values,ctx->Pixel.MapItoB,ctx->Pixel.MapItoBsize*sizeof(GLfloat));
419	 break;
420      case GL_PIXEL_MAP_I_TO_A:
421         MEMCPY(values,ctx->Pixel.MapItoA,ctx->Pixel.MapItoAsize*sizeof(GLfloat));
422	 break;
423      case GL_PIXEL_MAP_R_TO_R:
424         MEMCPY(values,ctx->Pixel.MapRtoR,ctx->Pixel.MapRtoRsize*sizeof(GLfloat));
425	 break;
426      case GL_PIXEL_MAP_G_TO_G:
427         MEMCPY(values,ctx->Pixel.MapGtoG,ctx->Pixel.MapGtoGsize*sizeof(GLfloat));
428	 break;
429      case GL_PIXEL_MAP_B_TO_B:
430         MEMCPY(values,ctx->Pixel.MapBtoB,ctx->Pixel.MapBtoBsize*sizeof(GLfloat));
431	 break;
432      case GL_PIXEL_MAP_A_TO_A:
433         MEMCPY(values,ctx->Pixel.MapAtoA,ctx->Pixel.MapAtoAsize*sizeof(GLfloat));
434	 break;
435      default:
436         _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
437   }
438}
439
440
441void
442_mesa_GetPixelMapuiv( GLenum map, GLuint *values )
443{
444   GET_CURRENT_CONTEXT(ctx);
445   GLint i;
446   ASSERT_OUTSIDE_BEGIN_END(ctx);
447
448   switch (map) {
449      case GL_PIXEL_MAP_I_TO_I:
450         MEMCPY(values, ctx->Pixel.MapItoI, ctx->Pixel.MapItoIsize*sizeof(GLint));
451	 break;
452      case GL_PIXEL_MAP_S_TO_S:
453         MEMCPY(values, ctx->Pixel.MapStoS, ctx->Pixel.MapStoSsize*sizeof(GLint));
454	 break;
455      case GL_PIXEL_MAP_I_TO_R:
456	 for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
457	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoR[i] );
458	 }
459	 break;
460      case GL_PIXEL_MAP_I_TO_G:
461	 for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
462	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoG[i] );
463	 }
464	 break;
465      case GL_PIXEL_MAP_I_TO_B:
466	 for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
467	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoB[i] );
468	 }
469	 break;
470      case GL_PIXEL_MAP_I_TO_A:
471	 for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
472	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoA[i] );
473	 }
474	 break;
475      case GL_PIXEL_MAP_R_TO_R:
476	 for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
477	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapRtoR[i] );
478	 }
479	 break;
480      case GL_PIXEL_MAP_G_TO_G:
481	 for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
482	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapGtoG[i] );
483	 }
484	 break;
485      case GL_PIXEL_MAP_B_TO_B:
486	 for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
487	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapBtoB[i] );
488	 }
489	 break;
490      case GL_PIXEL_MAP_A_TO_A:
491	 for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
492	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapAtoA[i] );
493	 }
494	 break;
495      default:
496         _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
497   }
498}
499
500
501void
502_mesa_GetPixelMapusv( GLenum map, GLushort *values )
503{
504   GET_CURRENT_CONTEXT(ctx);
505   GLint i;
506   ASSERT_OUTSIDE_BEGIN_END(ctx);
507
508   switch (map) {
509      case GL_PIXEL_MAP_I_TO_I:
510	 for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
511	    values[i] = (GLushort) ctx->Pixel.MapItoI[i];
512	 }
513	 break;
514      case GL_PIXEL_MAP_S_TO_S:
515	 for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
516	    values[i] = (GLushort) ctx->Pixel.MapStoS[i];
517	 }
518	 break;
519      case GL_PIXEL_MAP_I_TO_R:
520	 for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
521	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoR[i] );
522	 }
523	 break;
524      case GL_PIXEL_MAP_I_TO_G:
525	 for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
526	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoG[i] );
527	 }
528	 break;
529      case GL_PIXEL_MAP_I_TO_B:
530	 for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
531	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoB[i] );
532	 }
533	 break;
534      case GL_PIXEL_MAP_I_TO_A:
535	 for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
536	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoA[i] );
537	 }
538	 break;
539      case GL_PIXEL_MAP_R_TO_R:
540	 for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
541	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapRtoR[i] );
542	 }
543	 break;
544      case GL_PIXEL_MAP_G_TO_G:
545	 for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
546	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapGtoG[i] );
547	 }
548	 break;
549      case GL_PIXEL_MAP_B_TO_B:
550	 for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
551	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapBtoB[i] );
552	 }
553	 break;
554      case GL_PIXEL_MAP_A_TO_A:
555	 for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
556	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapAtoA[i] );
557	 }
558	 break;
559      default:
560         _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
561   }
562}
563
564
565
566/**********************************************************************/
567/*****                       glPixelTransfer                      *****/
568/**********************************************************************/
569
570
571/*
572 * Implements glPixelTransfer[fi] whether called immediately or from a
573 * display list.
574 */
575void
576_mesa_PixelTransferf( GLenum pname, GLfloat param )
577{
578   GET_CURRENT_CONTEXT(ctx);
579   ASSERT_OUTSIDE_BEGIN_END(ctx);
580
581   switch (pname) {
582      case GL_MAP_COLOR:
583         if (ctx->Pixel.MapColorFlag == param ? GL_TRUE : GL_FALSE)
584	    return;
585	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
586         ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
587	 break;
588      case GL_MAP_STENCIL:
589         if (ctx->Pixel.MapStencilFlag == param ? GL_TRUE : GL_FALSE)
590	    return;
591	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
592         ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
593	 break;
594      case GL_INDEX_SHIFT:
595         if (ctx->Pixel.IndexShift == (GLint) param)
596	    return;
597	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
598         ctx->Pixel.IndexShift = (GLint) param;
599	 break;
600      case GL_INDEX_OFFSET:
601         if (ctx->Pixel.IndexOffset == (GLint) param)
602	    return;
603	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
604         ctx->Pixel.IndexOffset = (GLint) param;
605	 break;
606      case GL_RED_SCALE:
607         if (ctx->Pixel.RedScale == param)
608	    return;
609	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
610         ctx->Pixel.RedScale = param;
611	 break;
612      case GL_RED_BIAS:
613         if (ctx->Pixel.RedBias == param)
614	    return;
615	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
616         ctx->Pixel.RedBias = param;
617	 break;
618      case GL_GREEN_SCALE:
619         if (ctx->Pixel.GreenScale == param)
620	    return;
621	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
622         ctx->Pixel.GreenScale = param;
623	 break;
624      case GL_GREEN_BIAS:
625         if (ctx->Pixel.GreenBias == param)
626	    return;
627	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
628         ctx->Pixel.GreenBias = param;
629	 break;
630      case GL_BLUE_SCALE:
631         if (ctx->Pixel.BlueScale == param)
632	    return;
633	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
634         ctx->Pixel.BlueScale = param;
635	 break;
636      case GL_BLUE_BIAS:
637         if (ctx->Pixel.BlueBias == param)
638	    return;
639	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
640         ctx->Pixel.BlueBias = param;
641	 break;
642      case GL_ALPHA_SCALE:
643         if (ctx->Pixel.AlphaScale == param)
644	    return;
645	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
646         ctx->Pixel.AlphaScale = param;
647	 break;
648      case GL_ALPHA_BIAS:
649         if (ctx->Pixel.AlphaBias == param)
650	    return;
651	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
652         ctx->Pixel.AlphaBias = param;
653	 break;
654      case GL_DEPTH_SCALE:
655         if (ctx->Pixel.DepthScale == param)
656	    return;
657	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
658         ctx->Pixel.DepthScale = param;
659	 break;
660      case GL_DEPTH_BIAS:
661         if (ctx->Pixel.DepthBias == param)
662	    return;
663	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
664         ctx->Pixel.DepthBias = param;
665	 break;
666      case GL_POST_COLOR_MATRIX_RED_SCALE:
667         if (ctx->Pixel.PostColorMatrixScale[0] == param)
668	    return;
669	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
670         ctx->Pixel.PostColorMatrixScale[0] = param;
671	 break;
672      case GL_POST_COLOR_MATRIX_RED_BIAS:
673         if (ctx->Pixel.PostColorMatrixBias[0] == param)
674	    return;
675	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
676         ctx->Pixel.PostColorMatrixBias[0] = param;
677	 break;
678      case GL_POST_COLOR_MATRIX_GREEN_SCALE:
679         if (ctx->Pixel.PostColorMatrixScale[1] == param)
680	    return;
681	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
682         ctx->Pixel.PostColorMatrixScale[1] = param;
683	 break;
684      case GL_POST_COLOR_MATRIX_GREEN_BIAS:
685         if (ctx->Pixel.PostColorMatrixBias[1] == param)
686	    return;
687	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
688         ctx->Pixel.PostColorMatrixBias[1] = param;
689	 break;
690      case GL_POST_COLOR_MATRIX_BLUE_SCALE:
691         if (ctx->Pixel.PostColorMatrixScale[2] == param)
692	    return;
693	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
694         ctx->Pixel.PostColorMatrixScale[2] = param;
695	 break;
696      case GL_POST_COLOR_MATRIX_BLUE_BIAS:
697         if (ctx->Pixel.PostColorMatrixBias[2] == param)
698	    return;
699	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
700         ctx->Pixel.PostColorMatrixBias[2] = param;
701	 break;
702      case GL_POST_COLOR_MATRIX_ALPHA_SCALE:
703         if (ctx->Pixel.PostColorMatrixScale[3] == param)
704	    return;
705	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
706         ctx->Pixel.PostColorMatrixScale[3] = param;
707	 break;
708      case GL_POST_COLOR_MATRIX_ALPHA_BIAS:
709         if (ctx->Pixel.PostColorMatrixBias[3] == param)
710	    return;
711	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
712         ctx->Pixel.PostColorMatrixBias[3] = param;
713	 break;
714      case GL_POST_CONVOLUTION_RED_SCALE:
715         if (ctx->Pixel.PostConvolutionScale[0] == param)
716	    return;
717	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
718         ctx->Pixel.PostConvolutionScale[0] = param;
719	 break;
720      case GL_POST_CONVOLUTION_RED_BIAS:
721         if (ctx->Pixel.PostConvolutionBias[0] == param)
722	    return;
723	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
724         ctx->Pixel.PostConvolutionBias[0] = param;
725	 break;
726      case GL_POST_CONVOLUTION_GREEN_SCALE:
727         if (ctx->Pixel.PostConvolutionScale[1] == param)
728	    return;
729	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
730         ctx->Pixel.PostConvolutionScale[1] = param;
731	 break;
732      case GL_POST_CONVOLUTION_GREEN_BIAS:
733         if (ctx->Pixel.PostConvolutionBias[1] == param)
734	    return;
735	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
736         ctx->Pixel.PostConvolutionBias[1] = param;
737	 break;
738      case GL_POST_CONVOLUTION_BLUE_SCALE:
739         if (ctx->Pixel.PostConvolutionScale[2] == param)
740	    return;
741	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
742         ctx->Pixel.PostConvolutionScale[2] = param;
743	 break;
744      case GL_POST_CONVOLUTION_BLUE_BIAS:
745         if (ctx->Pixel.PostConvolutionBias[2] == param)
746	    return;
747	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
748         ctx->Pixel.PostConvolutionBias[2] = param;
749	 break;
750      case GL_POST_CONVOLUTION_ALPHA_SCALE:
751         if (ctx->Pixel.PostConvolutionScale[2] == param)
752	    return;
753	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
754         ctx->Pixel.PostConvolutionScale[2] = param;
755	 break;
756      case GL_POST_CONVOLUTION_ALPHA_BIAS:
757         if (ctx->Pixel.PostConvolutionBias[2] == param)
758	    return;
759	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
760         ctx->Pixel.PostConvolutionBias[2] = param;
761	 break;
762      default:
763         _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
764         return;
765   }
766}
767
768
769void
770_mesa_PixelTransferi( GLenum pname, GLint param )
771{
772   _mesa_PixelTransferf( pname, (GLfloat) param );
773}
774
775
776
777/**********************************************************************/
778/*****                  Pixel processing functions               ******/
779/**********************************************************************/
780
781
782/*
783 * Apply scale and bias factors to an array of RGBA pixels.
784 */
785void
786_mesa_scale_and_bias_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4],
787                          GLfloat rScale, GLfloat gScale,
788                          GLfloat bScale, GLfloat aScale,
789                          GLfloat rBias, GLfloat gBias,
790                          GLfloat bBias, GLfloat aBias)
791{
792   if (rScale != 1.0 || rBias != 0.0) {
793      GLuint i;
794      for (i = 0; i < n; i++) {
795         rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias;
796      }
797   }
798   if (gScale != 1.0 || gBias != 0.0) {
799      GLuint i;
800      for (i = 0; i < n; i++) {
801         rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias;
802      }
803   }
804   if (bScale != 1.0 || bBias != 0.0) {
805      GLuint i;
806      for (i = 0; i < n; i++) {
807         rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias;
808      }
809   }
810   if (aScale != 1.0 || aBias != 0.0) {
811      GLuint i;
812      for (i = 0; i < n; i++) {
813         rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias;
814      }
815   }
816}
817
818
819/*
820 * Apply pixel mapping to an array of floating point RGBA pixels.
821 */
822void
823_mesa_map_rgba( const GLcontext *ctx, GLuint n, GLfloat rgba[][4] )
824{
825   const GLfloat rscale = ctx->Pixel.MapRtoRsize - 1;
826   const GLfloat gscale = ctx->Pixel.MapGtoGsize - 1;
827   const GLfloat bscale = ctx->Pixel.MapBtoBsize - 1;
828   const GLfloat ascale = ctx->Pixel.MapAtoAsize - 1;
829   const GLfloat *rMap = ctx->Pixel.MapRtoR;
830   const GLfloat *gMap = ctx->Pixel.MapGtoG;
831   const GLfloat *bMap = ctx->Pixel.MapBtoB;
832   const GLfloat *aMap = ctx->Pixel.MapAtoA;
833   GLuint i;
834   for (i=0;i<n;i++) {
835      rgba[i][RCOMP] = rMap[IROUND(rgba[i][RCOMP] * rscale)];
836      rgba[i][GCOMP] = gMap[IROUND(rgba[i][GCOMP] * gscale)];
837      rgba[i][BCOMP] = bMap[IROUND(rgba[i][BCOMP] * bscale)];
838      rgba[i][ACOMP] = aMap[IROUND(rgba[i][ACOMP] * ascale)];
839   }
840}
841
842
843/*
844 * Apply the color matrix and post color matrix scaling and biasing.
845 */
846void
847_mesa_transform_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4])
848{
849   const GLfloat rs = ctx->Pixel.PostColorMatrixScale[0];
850   const GLfloat rb = ctx->Pixel.PostColorMatrixBias[0];
851   const GLfloat gs = ctx->Pixel.PostColorMatrixScale[1];
852   const GLfloat gb = ctx->Pixel.PostColorMatrixBias[1];
853   const GLfloat bs = ctx->Pixel.PostColorMatrixScale[2];
854   const GLfloat bb = ctx->Pixel.PostColorMatrixBias[2];
855   const GLfloat as = ctx->Pixel.PostColorMatrixScale[3];
856   const GLfloat ab = ctx->Pixel.PostColorMatrixBias[3];
857   const GLfloat *m = ctx->ColorMatrix.m;
858   GLuint i;
859   for (i = 0; i < n; i++) {
860      const GLfloat r = rgba[i][RCOMP];
861      const GLfloat g = rgba[i][GCOMP];
862      const GLfloat b = rgba[i][BCOMP];
863      const GLfloat a = rgba[i][ACOMP];
864      rgba[i][RCOMP] = (m[0] * r + m[4] * g + m[ 8] * b + m[12] * a) * rs + rb;
865      rgba[i][GCOMP] = (m[1] * r + m[5] * g + m[ 9] * b + m[13] * a) * gs + gb;
866      rgba[i][BCOMP] = (m[2] * r + m[6] * g + m[10] * b + m[14] * a) * bs + bb;
867      rgba[i][ACOMP] = (m[3] * r + m[7] * g + m[11] * b + m[15] * a) * as + ab;
868   }
869}
870
871
872/*
873 * Apply a color table lookup to an array of colors.
874 */
875void
876_mesa_lookup_rgba(const struct gl_color_table *table,
877                  GLuint n, GLfloat rgba[][4])
878{
879   ASSERT(table->FloatTable);
880   if (!table->Table || table->Size == 0)
881      return;
882
883   switch (table->Format) {
884      case GL_INTENSITY:
885         /* replace RGBA with I */
886         if (!table->FloatTable) {
887            const GLfloat scale = (GLfloat) (table->Size - 1);
888            const GLchan *lut = (const GLchan *) table->Table;
889            GLuint i;
890            for (i = 0; i < n; i++) {
891               GLint j = IROUND(rgba[i][RCOMP] * scale);
892               GLfloat c = CHAN_TO_FLOAT(lut[j]);
893               rgba[i][RCOMP] = rgba[i][GCOMP] =
894                  rgba[i][BCOMP] = rgba[i][ACOMP] = c;
895            }
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 j = IROUND(rgba[i][RCOMP] * scale);
904               GLfloat c = lut[j];
905               rgba[i][RCOMP] = rgba[i][GCOMP] =
906                  rgba[i][BCOMP] = rgba[i][ACOMP] = c;
907            }
908         }
909         break;
910      case GL_LUMINANCE:
911         /* replace RGB with L */
912         if (!table->FloatTable) {
913            const GLfloat scale = (GLfloat) (table->Size - 1);
914            const GLchan *lut = (const GLchan *) table->Table;
915            GLuint i;
916            for (i = 0; i < n; i++) {
917               GLint j = IROUND(rgba[i][RCOMP] * scale);
918               GLfloat c = CHAN_TO_FLOAT(lut[j]);
919               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
920            }
921         }
922         else {
923            const GLfloat scale = (GLfloat) (table->Size - 1);
924            const GLfloat *lut = (const GLfloat *) table->Table;
925            GLuint i;
926            for (i = 0; i < n; i++) {
927               GLint j = IROUND(rgba[i][RCOMP] * scale);
928               GLfloat c = lut[j];
929               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
930            }
931         }
932         break;
933      case GL_ALPHA:
934         /* replace A with A */
935         if (!table->FloatTable) {
936            const GLfloat scale = (GLfloat) (table->Size - 1);
937            const GLchan *lut = (const GLchan *) table->Table;
938            GLuint i;
939            for (i = 0; i < n; i++) {
940               GLint j = IROUND(rgba[i][ACOMP] * scale);
941               rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[j]);
942            }
943         }
944         else  {
945            const GLfloat scale = (GLfloat) (table->Size - 1);
946            const GLfloat *lut = (const GLfloat *) table->Table;
947            GLuint i;
948            for (i = 0; i < n; i++) {
949               GLint j = IROUND(rgba[i][ACOMP] * scale);
950               rgba[i][ACOMP] = lut[j];
951            }
952         }
953         break;
954      case GL_LUMINANCE_ALPHA:
955         /* replace RGBA with LLLA */
956         if (!table->FloatTable) {
957            const GLfloat scale = (GLfloat) (table->Size - 1);
958            const GLchan *lut = (const GLchan *) table->Table;
959            GLuint i;
960            for (i = 0; i < n; i++) {
961               GLint jL = IROUND(rgba[i][RCOMP] * scale);
962               GLint jA = IROUND(rgba[i][ACOMP] * scale);
963               GLfloat luminance = CHAN_TO_FLOAT(lut[jL * 2 + 0]);
964               GLfloat alpha     = CHAN_TO_FLOAT(lut[jA * 2 + 1]);
965               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
966               rgba[i][ACOMP] = alpha;;
967            }
968         }
969         else {
970            const GLfloat scale = (GLfloat) (table->Size - 1);
971            const GLfloat *lut = (const GLfloat *) table->Table;
972            GLuint i;
973            for (i = 0; i < n; i++) {
974               GLint jL = IROUND(rgba[i][RCOMP] * scale);
975               GLint jA = IROUND(rgba[i][ACOMP] * scale);
976               GLfloat luminance = lut[jL * 2 + 0];
977               GLfloat alpha     = lut[jA * 2 + 1];
978               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
979               rgba[i][ACOMP] = alpha;;
980            }
981         }
982         break;
983      case GL_RGB:
984         /* replace RGB with RGB */
985         if (!table->FloatTable) {
986            const GLfloat scale = (GLfloat) (table->Size - 1);
987            const GLchan *lut = (const GLchan *) table->Table;
988            GLuint i;
989            for (i = 0; i < n; i++) {
990               GLint jR = IROUND(rgba[i][RCOMP] * scale);
991               GLint jG = IROUND(rgba[i][GCOMP] * scale);
992               GLint jB = IROUND(rgba[i][BCOMP] * scale);
993               rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 3 + 0]);
994               rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 3 + 1]);
995               rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 3 + 2]);
996            }
997         }
998         else {
999            const GLfloat scale = (GLfloat) (table->Size - 1);
1000            const GLfloat *lut = (const GLfloat *) table->Table;
1001            GLuint i;
1002            for (i = 0; i < n; i++) {
1003               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1004               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1005               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1006               rgba[i][RCOMP] = lut[jR * 3 + 0];
1007               rgba[i][GCOMP] = lut[jG * 3 + 1];
1008               rgba[i][BCOMP] = lut[jB * 3 + 2];
1009            }
1010         }
1011         break;
1012      case GL_RGBA:
1013         /* replace RGBA with RGBA */
1014         if (!table->FloatTable) {
1015            const GLfloat scale = (GLfloat) (table->Size - 1);
1016            const GLchan *lut = (const GLchan *) table->Table;
1017            GLuint i;
1018            for (i = 0; i < n; i++) {
1019               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1020               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1021               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1022               GLint jA = IROUND(rgba[i][ACOMP] * scale);
1023               rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 4 + 0]);
1024               rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 4 + 1]);
1025               rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 4 + 2]);
1026               rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[jA * 4 + 3]);
1027            }
1028         }
1029         else {
1030            const GLfloat scale = (GLfloat) (table->Size - 1);
1031            const GLfloat *lut = (const GLfloat *) table->Table;
1032            GLuint i;
1033            for (i = 0; i < n; i++) {
1034               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1035               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1036               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1037               GLint jA = IROUND(rgba[i][ACOMP] * scale);
1038               rgba[i][RCOMP] = lut[jR * 4 + 0];
1039               rgba[i][GCOMP] = lut[jG * 4 + 1];
1040               rgba[i][BCOMP] = lut[jB * 4 + 2];
1041               rgba[i][ACOMP] = lut[jA * 4 + 3];
1042            }
1043         }
1044         break;
1045      default:
1046         _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba");
1047         return;
1048   }
1049}
1050
1051
1052
1053/*
1054 * Apply color index shift and offset to an array of pixels.
1055 */
1056void
1057_mesa_shift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] )
1058{
1059   GLint shift = ctx->Pixel.IndexShift;
1060   GLint offset = ctx->Pixel.IndexOffset;
1061   GLuint i;
1062   if (shift > 0) {
1063      for (i=0;i<n;i++) {
1064         indexes[i] = (indexes[i] << shift) + offset;
1065      }
1066   }
1067   else if (shift < 0) {
1068      shift = -shift;
1069      for (i=0;i<n;i++) {
1070         indexes[i] = (indexes[i] >> shift) + offset;
1071      }
1072   }
1073   else {
1074      for (i=0;i<n;i++) {
1075         indexes[i] = indexes[i] + offset;
1076      }
1077   }
1078}
1079
1080
1081/*
1082 * Apply color index mapping to color indexes.
1083 */
1084void
1085_mesa_map_ci( const GLcontext *ctx, GLuint n, GLuint index[] )
1086{
1087   GLuint mask = ctx->Pixel.MapItoIsize - 1;
1088   GLuint i;
1089   for (i=0;i<n;i++) {
1090      index[i] = ctx->Pixel.MapItoI[ index[i] & mask ];
1091   }
1092}
1093
1094
1095/*
1096 * Map color indexes to rgba values.
1097 */
1098void
1099_mesa_map_ci_to_rgba_chan( const GLcontext *ctx, GLuint n,
1100                           const GLuint index[], GLchan rgba[][4] )
1101{
1102#if CHAN_BITS == 8
1103   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1104   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1105   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1106   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1107   const GLubyte *rMap = ctx->Pixel.MapItoR8;
1108   const GLubyte *gMap = ctx->Pixel.MapItoG8;
1109   const GLubyte *bMap = ctx->Pixel.MapItoB8;
1110   const GLubyte *aMap = ctx->Pixel.MapItoA8;
1111   GLuint i;
1112   for (i=0;i<n;i++) {
1113      rgba[i][RCOMP] = rMap[index[i] & rmask];
1114      rgba[i][GCOMP] = gMap[index[i] & gmask];
1115      rgba[i][BCOMP] = bMap[index[i] & bmask];
1116      rgba[i][ACOMP] = aMap[index[i] & amask];
1117   }
1118#else
1119   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1120   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1121   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1122   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1123   const GLfloat *rMap = ctx->Pixel.MapItoR;
1124   const GLfloat *gMap = ctx->Pixel.MapItoG;
1125   const GLfloat *bMap = ctx->Pixel.MapItoB;
1126   const GLfloat *aMap = ctx->Pixel.MapItoA;
1127   GLuint i;
1128   for (i=0;i<n;i++) {
1129      CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]);
1130      CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]);
1131      CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]);
1132      CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]);
1133   }
1134#endif
1135}
1136
1137
1138/*
1139 * Map color indexes to float rgba values.
1140 */
1141void
1142_mesa_map_ci_to_rgba( const GLcontext *ctx, GLuint n,
1143                      const GLuint index[], GLfloat rgba[][4] )
1144{
1145   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1146   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1147   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1148   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1149   const GLfloat *rMap = ctx->Pixel.MapItoR;
1150   const GLfloat *gMap = ctx->Pixel.MapItoG;
1151   const GLfloat *bMap = ctx->Pixel.MapItoB;
1152   const GLfloat *aMap = ctx->Pixel.MapItoA;
1153   GLuint i;
1154   for (i=0;i<n;i++) {
1155      rgba[i][RCOMP] = rMap[index[i] & rmask];
1156      rgba[i][GCOMP] = gMap[index[i] & gmask];
1157      rgba[i][BCOMP] = bMap[index[i] & bmask];
1158      rgba[i][ACOMP] = aMap[index[i] & amask];
1159   }
1160}
1161
1162
1163/*
1164 * Map 8-bit color indexes to rgb values.
1165 */
1166void
1167_mesa_map_ci8_to_rgba( const GLcontext *ctx, GLuint n, const GLubyte index[],
1168                       GLchan rgba[][4] )
1169{
1170#if CHAN_BITS == 8
1171   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1172   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1173   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1174   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1175   const GLubyte *rMap = ctx->Pixel.MapItoR8;
1176   const GLubyte *gMap = ctx->Pixel.MapItoG8;
1177   const GLubyte *bMap = ctx->Pixel.MapItoB8;
1178   const GLubyte *aMap = ctx->Pixel.MapItoA8;
1179   GLuint i;
1180   for (i=0;i<n;i++) {
1181      rgba[i][RCOMP] = rMap[index[i] & rmask];
1182      rgba[i][GCOMP] = gMap[index[i] & gmask];
1183      rgba[i][BCOMP] = bMap[index[i] & bmask];
1184      rgba[i][ACOMP] = aMap[index[i] & amask];
1185   }
1186#else
1187   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1188   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1189   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1190   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1191   const GLfloat *rMap = ctx->Pixel.MapItoR;
1192   const GLfloat *gMap = ctx->Pixel.MapItoG;
1193   const GLfloat *bMap = ctx->Pixel.MapItoB;
1194   const GLfloat *aMap = ctx->Pixel.MapItoA;
1195   GLuint i;
1196   for (i=0;i<n;i++) {
1197      CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]);
1198      CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]);
1199      CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]);
1200      CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]);
1201   }
1202#endif
1203}
1204
1205
1206void
1207_mesa_shift_and_offset_stencil( const GLcontext *ctx, GLuint n,
1208                                GLstencil stencil[] )
1209{
1210   GLuint i;
1211   GLint shift = ctx->Pixel.IndexShift;
1212   GLint offset = ctx->Pixel.IndexOffset;
1213   if (shift > 0) {
1214      for (i=0;i<n;i++) {
1215         stencil[i] = (stencil[i] << shift) + offset;
1216      }
1217   }
1218   else if (shift < 0) {
1219      shift = -shift;
1220      for (i=0;i<n;i++) {
1221         stencil[i] = (stencil[i] >> shift) + offset;
1222      }
1223   }
1224   else {
1225      for (i=0;i<n;i++) {
1226         stencil[i] = stencil[i] + offset;
1227      }
1228   }
1229
1230}
1231
1232
1233void
1234_mesa_map_stencil( const GLcontext *ctx, GLuint n, GLstencil stencil[] )
1235{
1236   GLuint mask = ctx->Pixel.MapStoSsize - 1;
1237   GLuint i;
1238   for (i=0;i<n;i++) {
1239      stencil[i] = ctx->Pixel.MapStoS[ stencil[i] & mask ];
1240   }
1241}
1242
1243
1244
1245/*
1246 * This function converts an array of GLchan colors to GLfloat colors.
1247 * Most importantly, it undoes the non-uniform quantization of pixel
1248 * values introduced when we convert shallow (< 8 bit) pixel values
1249 * to GLubytes in the ctx->Driver.ReadRGBASpan() functions.
1250 * This fixes a number of OpenGL conformance failures when running on
1251 * 16bpp displays, for example.
1252 */
1253void
1254_mesa_chan_to_float_span(const GLcontext *ctx, GLuint n,
1255                         CONST GLchan rgba[][4], GLfloat rgbaf[][4])
1256{
1257   const GLuint rShift = CHAN_BITS - ctx->Visual.redBits;
1258   const GLuint gShift = CHAN_BITS - ctx->Visual.greenBits;
1259   const GLuint bShift = CHAN_BITS - ctx->Visual.blueBits;
1260   GLuint aShift;
1261   const GLfloat rScale = 1.0 / (GLfloat) ((1 << ctx->Visual.redBits  ) - 1);
1262   const GLfloat gScale = 1.0 / (GLfloat) ((1 << ctx->Visual.greenBits) - 1);
1263   const GLfloat bScale = 1.0 / (GLfloat) ((1 << ctx->Visual.blueBits ) - 1);
1264   GLfloat aScale;
1265   GLuint i;
1266
1267   if (ctx->Visual.alphaBits > 0) {
1268      aShift = CHAN_BITS - ctx->Visual.alphaBits;
1269      aScale = 1.0 / (GLfloat) ((1 << ctx->Visual.alphaBits) - 1);
1270   }
1271   else {
1272      aShift = 0;
1273      aScale = 1.0F / CHAN_MAXF;
1274   }
1275
1276   for (i = 0; i < n; i++) {
1277      const GLint r = rgba[i][RCOMP] >> rShift;
1278      const GLint g = rgba[i][GCOMP] >> gShift;
1279      const GLint b = rgba[i][BCOMP] >> bShift;
1280      const GLint a = rgba[i][ACOMP] >> aShift;
1281      rgbaf[i][RCOMP] = (GLfloat) r * rScale;
1282      rgbaf[i][GCOMP] = (GLfloat) g * gScale;
1283      rgbaf[i][BCOMP] = (GLfloat) b * bScale;
1284      rgbaf[i][ACOMP] = (GLfloat) a * aScale;
1285   }
1286}
1287