pixel.c revision 6dc85575000127630489b407c50a4b3ea87c9acb
1
2/*
3 * Mesa 3-D graphics library
4 * Version:  4.1
5 *
6 * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#include "glheader.h"
27#include "imports.h"
28#include "colormac.h"
29#include "context.h"
30#include "macros.h"
31#include "pixel.h"
32#include "mtypes.h"
33
34
35/**********************************************************************/
36/*****                    glPixelZoom                             *****/
37/**********************************************************************/
38
39
40
41void
42_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor )
43{
44   GET_CURRENT_CONTEXT(ctx);
45
46   if (ctx->Pixel.ZoomX == xfactor &&
47       ctx->Pixel.ZoomY == yfactor)
48      return;
49
50   FLUSH_VERTICES(ctx, _NEW_PIXEL);
51   ctx->Pixel.ZoomX = xfactor;
52   ctx->Pixel.ZoomY = yfactor;
53}
54
55
56
57/**********************************************************************/
58/*****                    glPixelStore                            *****/
59/**********************************************************************/
60
61
62void
63_mesa_PixelStorei( GLenum pname, GLint param )
64{
65   /* NOTE: this call can't be compiled into the display list */
66   GET_CURRENT_CONTEXT(ctx);
67   ASSERT_OUTSIDE_BEGIN_END(ctx);
68
69   switch (pname) {
70      case GL_PACK_SWAP_BYTES:
71	 if (param == (GLint)ctx->Pack.SwapBytes)
72	    return;
73	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
74         ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
75	 break;
76      case GL_PACK_LSB_FIRST:
77	 if (param == (GLint)ctx->Pack.LsbFirst)
78	    return;
79	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
80         ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
81	 break;
82      case GL_PACK_ROW_LENGTH:
83	 if (param<0) {
84	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
85	    return;
86	 }
87	 if (ctx->Pack.RowLength == param)
88	    return;
89	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
90	 ctx->Pack.RowLength = param;
91	 break;
92      case GL_PACK_IMAGE_HEIGHT:
93         if (param<0) {
94            _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
95	    return;
96	 }
97	 if (ctx->Pack.ImageHeight == param)
98	    return;
99	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
100	 ctx->Pack.ImageHeight = param;
101         break;
102      case GL_PACK_SKIP_PIXELS:
103	 if (param<0) {
104	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
105	    return;
106	 }
107	 if (ctx->Pack.SkipPixels == param)
108	    return;
109	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
110	 ctx->Pack.SkipPixels = param;
111	 break;
112      case GL_PACK_SKIP_ROWS:
113	 if (param<0) {
114	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
115	    return;
116	 }
117	 if (ctx->Pack.SkipRows == param)
118	    return;
119	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
120	 ctx->Pack.SkipRows = param;
121	 break;
122      case GL_PACK_SKIP_IMAGES:
123	 if (param<0) {
124	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
125	    return;
126	 }
127	 if (ctx->Pack.SkipImages == param)
128	    return;
129	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
130	 ctx->Pack.SkipImages = param;
131	 break;
132      case GL_PACK_ALIGNMENT:
133         if (param!=1 && param!=2 && param!=4 && param!=8) {
134	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
135	    return;
136	 }
137	 if (ctx->Pack.Alignment == param)
138	    return;
139	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
140	 ctx->Pack.Alignment = param;
141	 break;
142      case GL_PACK_INVERT_MESA:
143         if (!ctx->Extensions.MESA_pack_invert) {
144            _mesa_error( ctx, GL_INVALID_ENUM, "glPixelstore(pname)" );
145            return;
146         }
147         if (ctx->Pack.Invert == param)
148            return;
149         FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
150         ctx->Pack.Invert = param;
151         break;
152
153      case GL_UNPACK_SWAP_BYTES:
154	 if (param == (GLint)ctx->Unpack.SwapBytes)
155	    return;
156	 if ((GLint)ctx->Unpack.SwapBytes == param)
157	    return;
158	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
159	 ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
160         break;
161      case GL_UNPACK_LSB_FIRST:
162	 if (param == (GLint)ctx->Unpack.LsbFirst)
163	    return;
164	 if ((GLint)ctx->Unpack.LsbFirst == param)
165	    return;
166	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
167	 ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
168	 break;
169      case GL_UNPACK_ROW_LENGTH:
170	 if (param<0) {
171	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
172	    return;
173	 }
174	 if (ctx->Unpack.RowLength == param)
175	    return;
176	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
177	 ctx->Unpack.RowLength = param;
178	 break;
179      case GL_UNPACK_IMAGE_HEIGHT:
180         if (param<0) {
181            _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
182	    return;
183	 }
184	 if (ctx->Unpack.ImageHeight == param)
185	    return;
186
187	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
188	 ctx->Unpack.ImageHeight = param;
189         break;
190      case GL_UNPACK_SKIP_PIXELS:
191	 if (param<0) {
192	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
193	    return;
194	 }
195	 if (ctx->Unpack.SkipPixels == param)
196	    return;
197	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
198	 ctx->Unpack.SkipPixels = param;
199	 break;
200      case GL_UNPACK_SKIP_ROWS:
201	 if (param<0) {
202	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
203	    return;
204	 }
205	 if (ctx->Unpack.SkipRows == param)
206	    return;
207	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
208	 ctx->Unpack.SkipRows = param;
209	 break;
210      case GL_UNPACK_SKIP_IMAGES:
211	 if (param < 0) {
212	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
213	    return;
214	 }
215	 if (ctx->Unpack.SkipImages == param)
216	    return;
217	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
218	 ctx->Unpack.SkipImages = param;
219	 break;
220      case GL_UNPACK_ALIGNMENT:
221         if (param!=1 && param!=2 && param!=4 && param!=8) {
222	    _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore" );
223	    return;
224	 }
225	 if (ctx->Unpack.Alignment == param)
226	    return;
227	 FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
228	 ctx->Unpack.Alignment = param;
229	 break;
230      case GL_UNPACK_CLIENT_STORAGE_APPLE:
231         if (param == (GLint)ctx->Unpack.ClientStorage)
232            return;
233         FLUSH_VERTICES(ctx, _NEW_PACKUNPACK);
234         ctx->Unpack.ClientStorage = param ? GL_TRUE : GL_FALSE;
235         break;
236      default:
237	 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
238	 return;
239   }
240}
241
242
243void
244_mesa_PixelStoref( GLenum pname, GLfloat param )
245{
246   _mesa_PixelStorei( pname, (GLint) param );
247}
248
249
250
251/**********************************************************************/
252/*****                         glPixelMap                         *****/
253/**********************************************************************/
254
255
256
257void
258_mesa_PixelMapfv( GLenum map, GLint mapsize, const GLfloat *values )
259{
260   GLint i;
261   GET_CURRENT_CONTEXT(ctx);
262   ASSERT_OUTSIDE_BEGIN_END(ctx);
263
264   if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
265      _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
266      return;
267   }
268
269   if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
270      /* test that mapsize is a power of two */
271      if (_mesa_bitcount((GLuint) mapsize) != 1) {
272	 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
273         return;
274      }
275   }
276
277   FLUSH_VERTICES(ctx, _NEW_PIXEL);
278
279   switch (map) {
280      case GL_PIXEL_MAP_S_TO_S:
281         ctx->Pixel.MapStoSsize = mapsize;
282         for (i=0;i<mapsize;i++) {
283	    ctx->Pixel.MapStoS[i] = (GLint) values[i];
284	 }
285	 break;
286      case GL_PIXEL_MAP_I_TO_I:
287         ctx->Pixel.MapItoIsize = mapsize;
288         for (i=0;i<mapsize;i++) {
289	    ctx->Pixel.MapItoI[i] = (GLint) values[i];
290	 }
291	 break;
292      case GL_PIXEL_MAP_I_TO_R:
293         ctx->Pixel.MapItoRsize = mapsize;
294         for (i=0;i<mapsize;i++) {
295            GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
296	    ctx->Pixel.MapItoR[i] = val;
297	    ctx->Pixel.MapItoR8[i] = (GLint) (val * 255.0F);
298	 }
299	 break;
300      case GL_PIXEL_MAP_I_TO_G:
301         ctx->Pixel.MapItoGsize = mapsize;
302         for (i=0;i<mapsize;i++) {
303            GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
304	    ctx->Pixel.MapItoG[i] = val;
305	    ctx->Pixel.MapItoG8[i] = (GLint) (val * 255.0F);
306	 }
307	 break;
308      case GL_PIXEL_MAP_I_TO_B:
309         ctx->Pixel.MapItoBsize = mapsize;
310         for (i=0;i<mapsize;i++) {
311            GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
312	    ctx->Pixel.MapItoB[i] = val;
313	    ctx->Pixel.MapItoB8[i] = (GLint) (val * 255.0F);
314	 }
315	 break;
316      case GL_PIXEL_MAP_I_TO_A:
317         ctx->Pixel.MapItoAsize = mapsize;
318         for (i=0;i<mapsize;i++) {
319            GLfloat val = CLAMP( values[i], 0.0F, 1.0F );
320	    ctx->Pixel.MapItoA[i] = val;
321	    ctx->Pixel.MapItoA8[i] = (GLint) (val * 255.0F);
322	 }
323	 break;
324      case GL_PIXEL_MAP_R_TO_R:
325         ctx->Pixel.MapRtoRsize = mapsize;
326         for (i=0;i<mapsize;i++) {
327	    ctx->Pixel.MapRtoR[i] = CLAMP( values[i], 0.0F, 1.0F );
328	 }
329	 break;
330      case GL_PIXEL_MAP_G_TO_G:
331         ctx->Pixel.MapGtoGsize = mapsize;
332         for (i=0;i<mapsize;i++) {
333	    ctx->Pixel.MapGtoG[i] = CLAMP( values[i], 0.0F, 1.0F );
334	 }
335	 break;
336      case GL_PIXEL_MAP_B_TO_B:
337         ctx->Pixel.MapBtoBsize = mapsize;
338         for (i=0;i<mapsize;i++) {
339	    ctx->Pixel.MapBtoB[i] = CLAMP( values[i], 0.0F, 1.0F );
340	 }
341	 break;
342      case GL_PIXEL_MAP_A_TO_A:
343         ctx->Pixel.MapAtoAsize = mapsize;
344         for (i=0;i<mapsize;i++) {
345	    ctx->Pixel.MapAtoA[i] = CLAMP( values[i], 0.0F, 1.0F );
346	 }
347	 break;
348      default:
349         _mesa_error( ctx, GL_INVALID_ENUM, "glPixelMapfv(map)" );
350   }
351}
352
353
354
355void
356_mesa_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values )
357{
358   const GLint n = MIN2(mapsize, MAX_PIXEL_MAP_TABLE);
359   GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
360   GLint i;
361   if (map==GL_PIXEL_MAP_I_TO_I || map==GL_PIXEL_MAP_S_TO_S) {
362      for (i=0;i<n;i++) {
363         fvalues[i] = (GLfloat) values[i];
364      }
365   }
366   else {
367      for (i=0;i<n;i++) {
368         fvalues[i] = UINT_TO_FLOAT( values[i] );
369      }
370   }
371   _mesa_PixelMapfv(map, mapsize, fvalues);
372}
373
374
375
376void
377_mesa_PixelMapusv(GLenum map, GLint mapsize, const GLushort *values )
378{
379   const GLint n = MIN2(mapsize, MAX_PIXEL_MAP_TABLE);
380   GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
381   GLint i;
382   if (map==GL_PIXEL_MAP_I_TO_I || map==GL_PIXEL_MAP_S_TO_S) {
383      for (i=0;i<n;i++) {
384         fvalues[i] = (GLfloat) values[i];
385      }
386   }
387   else {
388      for (i=0;i<n;i++) {
389         fvalues[i] = USHORT_TO_FLOAT( values[i] );
390      }
391   }
392   _mesa_PixelMapfv(map, mapsize, fvalues);
393}
394
395
396
397void
398_mesa_GetPixelMapfv( GLenum map, GLfloat *values )
399{
400   GET_CURRENT_CONTEXT(ctx);
401   GLint i;
402   ASSERT_OUTSIDE_BEGIN_END(ctx);
403
404   switch (map) {
405      case GL_PIXEL_MAP_I_TO_I:
406         for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
407	    values[i] = (GLfloat) ctx->Pixel.MapItoI[i];
408	 }
409	 break;
410      case GL_PIXEL_MAP_S_TO_S:
411         for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
412	    values[i] = (GLfloat) ctx->Pixel.MapStoS[i];
413	 }
414	 break;
415      case GL_PIXEL_MAP_I_TO_R:
416         MEMCPY(values,ctx->Pixel.MapItoR,ctx->Pixel.MapItoRsize*sizeof(GLfloat));
417	 break;
418      case GL_PIXEL_MAP_I_TO_G:
419         MEMCPY(values,ctx->Pixel.MapItoG,ctx->Pixel.MapItoGsize*sizeof(GLfloat));
420	 break;
421      case GL_PIXEL_MAP_I_TO_B:
422         MEMCPY(values,ctx->Pixel.MapItoB,ctx->Pixel.MapItoBsize*sizeof(GLfloat));
423	 break;
424      case GL_PIXEL_MAP_I_TO_A:
425         MEMCPY(values,ctx->Pixel.MapItoA,ctx->Pixel.MapItoAsize*sizeof(GLfloat));
426	 break;
427      case GL_PIXEL_MAP_R_TO_R:
428         MEMCPY(values,ctx->Pixel.MapRtoR,ctx->Pixel.MapRtoRsize*sizeof(GLfloat));
429	 break;
430      case GL_PIXEL_MAP_G_TO_G:
431         MEMCPY(values,ctx->Pixel.MapGtoG,ctx->Pixel.MapGtoGsize*sizeof(GLfloat));
432	 break;
433      case GL_PIXEL_MAP_B_TO_B:
434         MEMCPY(values,ctx->Pixel.MapBtoB,ctx->Pixel.MapBtoBsize*sizeof(GLfloat));
435	 break;
436      case GL_PIXEL_MAP_A_TO_A:
437         MEMCPY(values,ctx->Pixel.MapAtoA,ctx->Pixel.MapAtoAsize*sizeof(GLfloat));
438	 break;
439      default:
440         _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
441   }
442}
443
444
445void
446_mesa_GetPixelMapuiv( GLenum map, GLuint *values )
447{
448   GET_CURRENT_CONTEXT(ctx);
449   GLint i;
450   ASSERT_OUTSIDE_BEGIN_END(ctx);
451
452   switch (map) {
453      case GL_PIXEL_MAP_I_TO_I:
454         MEMCPY(values, ctx->Pixel.MapItoI, ctx->Pixel.MapItoIsize*sizeof(GLint));
455	 break;
456      case GL_PIXEL_MAP_S_TO_S:
457         MEMCPY(values, ctx->Pixel.MapStoS, ctx->Pixel.MapStoSsize*sizeof(GLint));
458	 break;
459      case GL_PIXEL_MAP_I_TO_R:
460	 for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
461	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoR[i] );
462	 }
463	 break;
464      case GL_PIXEL_MAP_I_TO_G:
465	 for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
466	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoG[i] );
467	 }
468	 break;
469      case GL_PIXEL_MAP_I_TO_B:
470	 for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
471	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoB[i] );
472	 }
473	 break;
474      case GL_PIXEL_MAP_I_TO_A:
475	 for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
476	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoA[i] );
477	 }
478	 break;
479      case GL_PIXEL_MAP_R_TO_R:
480	 for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
481	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapRtoR[i] );
482	 }
483	 break;
484      case GL_PIXEL_MAP_G_TO_G:
485	 for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
486	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapGtoG[i] );
487	 }
488	 break;
489      case GL_PIXEL_MAP_B_TO_B:
490	 for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
491	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapBtoB[i] );
492	 }
493	 break;
494      case GL_PIXEL_MAP_A_TO_A:
495	 for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
496	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapAtoA[i] );
497	 }
498	 break;
499      default:
500         _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
501   }
502}
503
504
505void
506_mesa_GetPixelMapusv( GLenum map, GLushort *values )
507{
508   GET_CURRENT_CONTEXT(ctx);
509   GLint i;
510   ASSERT_OUTSIDE_BEGIN_END(ctx);
511
512   switch (map) {
513      case GL_PIXEL_MAP_I_TO_I:
514	 for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
515	    values[i] = (GLushort) ctx->Pixel.MapItoI[i];
516	 }
517	 break;
518      case GL_PIXEL_MAP_S_TO_S:
519	 for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
520	    values[i] = (GLushort) ctx->Pixel.MapStoS[i];
521	 }
522	 break;
523      case GL_PIXEL_MAP_I_TO_R:
524	 for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
525	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoR[i] );
526	 }
527	 break;
528      case GL_PIXEL_MAP_I_TO_G:
529	 for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
530	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoG[i] );
531	 }
532	 break;
533      case GL_PIXEL_MAP_I_TO_B:
534	 for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
535	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoB[i] );
536	 }
537	 break;
538      case GL_PIXEL_MAP_I_TO_A:
539	 for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
540	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoA[i] );
541	 }
542	 break;
543      case GL_PIXEL_MAP_R_TO_R:
544	 for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
545	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapRtoR[i] );
546	 }
547	 break;
548      case GL_PIXEL_MAP_G_TO_G:
549	 for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
550	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapGtoG[i] );
551	 }
552	 break;
553      case GL_PIXEL_MAP_B_TO_B:
554	 for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
555	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapBtoB[i] );
556	 }
557	 break;
558      case GL_PIXEL_MAP_A_TO_A:
559	 for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
560	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapAtoA[i] );
561	 }
562	 break;
563      default:
564         _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
565   }
566}
567
568
569
570/**********************************************************************/
571/*****                       glPixelTransfer                      *****/
572/**********************************************************************/
573
574
575/*
576 * Implements glPixelTransfer[fi] whether called immediately or from a
577 * display list.
578 */
579void
580_mesa_PixelTransferf( GLenum pname, GLfloat param )
581{
582   GET_CURRENT_CONTEXT(ctx);
583   ASSERT_OUTSIDE_BEGIN_END(ctx);
584
585   switch (pname) {
586      case GL_MAP_COLOR:
587         if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE))
588	    return;
589	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
590         ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
591	 break;
592      case GL_MAP_STENCIL:
593         if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE))
594	    return;
595	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
596         ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
597	 break;
598      case GL_INDEX_SHIFT:
599         if (ctx->Pixel.IndexShift == (GLint) param)
600	    return;
601	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
602         ctx->Pixel.IndexShift = (GLint) param;
603	 break;
604      case GL_INDEX_OFFSET:
605         if (ctx->Pixel.IndexOffset == (GLint) param)
606	    return;
607	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
608         ctx->Pixel.IndexOffset = (GLint) param;
609	 break;
610      case GL_RED_SCALE:
611         if (ctx->Pixel.RedScale == param)
612	    return;
613	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
614         ctx->Pixel.RedScale = param;
615	 break;
616      case GL_RED_BIAS:
617         if (ctx->Pixel.RedBias == param)
618	    return;
619	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
620         ctx->Pixel.RedBias = param;
621	 break;
622      case GL_GREEN_SCALE:
623         if (ctx->Pixel.GreenScale == param)
624	    return;
625	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
626         ctx->Pixel.GreenScale = param;
627	 break;
628      case GL_GREEN_BIAS:
629         if (ctx->Pixel.GreenBias == param)
630	    return;
631	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
632         ctx->Pixel.GreenBias = param;
633	 break;
634      case GL_BLUE_SCALE:
635         if (ctx->Pixel.BlueScale == param)
636	    return;
637	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
638         ctx->Pixel.BlueScale = param;
639	 break;
640      case GL_BLUE_BIAS:
641         if (ctx->Pixel.BlueBias == param)
642	    return;
643	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
644         ctx->Pixel.BlueBias = param;
645	 break;
646      case GL_ALPHA_SCALE:
647         if (ctx->Pixel.AlphaScale == param)
648	    return;
649	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
650         ctx->Pixel.AlphaScale = param;
651	 break;
652      case GL_ALPHA_BIAS:
653         if (ctx->Pixel.AlphaBias == param)
654	    return;
655	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
656         ctx->Pixel.AlphaBias = param;
657	 break;
658      case GL_DEPTH_SCALE:
659         if (ctx->Pixel.DepthScale == param)
660	    return;
661	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
662         ctx->Pixel.DepthScale = param;
663	 break;
664      case GL_DEPTH_BIAS:
665         if (ctx->Pixel.DepthBias == param)
666	    return;
667	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
668         ctx->Pixel.DepthBias = param;
669	 break;
670      case GL_POST_COLOR_MATRIX_RED_SCALE:
671         if (ctx->Pixel.PostColorMatrixScale[0] == param)
672	    return;
673	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
674         ctx->Pixel.PostColorMatrixScale[0] = param;
675	 break;
676      case GL_POST_COLOR_MATRIX_RED_BIAS:
677         if (ctx->Pixel.PostColorMatrixBias[0] == param)
678	    return;
679	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
680         ctx->Pixel.PostColorMatrixBias[0] = param;
681	 break;
682      case GL_POST_COLOR_MATRIX_GREEN_SCALE:
683         if (ctx->Pixel.PostColorMatrixScale[1] == param)
684	    return;
685	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
686         ctx->Pixel.PostColorMatrixScale[1] = param;
687	 break;
688      case GL_POST_COLOR_MATRIX_GREEN_BIAS:
689         if (ctx->Pixel.PostColorMatrixBias[1] == param)
690	    return;
691	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
692         ctx->Pixel.PostColorMatrixBias[1] = param;
693	 break;
694      case GL_POST_COLOR_MATRIX_BLUE_SCALE:
695         if (ctx->Pixel.PostColorMatrixScale[2] == param)
696	    return;
697	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
698         ctx->Pixel.PostColorMatrixScale[2] = param;
699	 break;
700      case GL_POST_COLOR_MATRIX_BLUE_BIAS:
701         if (ctx->Pixel.PostColorMatrixBias[2] == param)
702	    return;
703	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
704         ctx->Pixel.PostColorMatrixBias[2] = param;
705	 break;
706      case GL_POST_COLOR_MATRIX_ALPHA_SCALE:
707         if (ctx->Pixel.PostColorMatrixScale[3] == param)
708	    return;
709	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
710         ctx->Pixel.PostColorMatrixScale[3] = param;
711	 break;
712      case GL_POST_COLOR_MATRIX_ALPHA_BIAS:
713         if (ctx->Pixel.PostColorMatrixBias[3] == param)
714	    return;
715	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
716         ctx->Pixel.PostColorMatrixBias[3] = param;
717	 break;
718      case GL_POST_CONVOLUTION_RED_SCALE:
719         if (ctx->Pixel.PostConvolutionScale[0] == param)
720	    return;
721	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
722         ctx->Pixel.PostConvolutionScale[0] = param;
723	 break;
724      case GL_POST_CONVOLUTION_RED_BIAS:
725         if (ctx->Pixel.PostConvolutionBias[0] == param)
726	    return;
727	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
728         ctx->Pixel.PostConvolutionBias[0] = param;
729	 break;
730      case GL_POST_CONVOLUTION_GREEN_SCALE:
731         if (ctx->Pixel.PostConvolutionScale[1] == param)
732	    return;
733	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
734         ctx->Pixel.PostConvolutionScale[1] = param;
735	 break;
736      case GL_POST_CONVOLUTION_GREEN_BIAS:
737         if (ctx->Pixel.PostConvolutionBias[1] == param)
738	    return;
739	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
740         ctx->Pixel.PostConvolutionBias[1] = param;
741	 break;
742      case GL_POST_CONVOLUTION_BLUE_SCALE:
743         if (ctx->Pixel.PostConvolutionScale[2] == param)
744	    return;
745	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
746         ctx->Pixel.PostConvolutionScale[2] = param;
747	 break;
748      case GL_POST_CONVOLUTION_BLUE_BIAS:
749         if (ctx->Pixel.PostConvolutionBias[2] == param)
750	    return;
751	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
752         ctx->Pixel.PostConvolutionBias[2] = param;
753	 break;
754      case GL_POST_CONVOLUTION_ALPHA_SCALE:
755         if (ctx->Pixel.PostConvolutionScale[2] == param)
756	    return;
757	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
758         ctx->Pixel.PostConvolutionScale[2] = param;
759	 break;
760      case GL_POST_CONVOLUTION_ALPHA_BIAS:
761         if (ctx->Pixel.PostConvolutionBias[2] == param)
762	    return;
763	 FLUSH_VERTICES(ctx, _NEW_PIXEL);
764         ctx->Pixel.PostConvolutionBias[2] = param;
765	 break;
766      default:
767         _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
768         return;
769   }
770}
771
772
773void
774_mesa_PixelTransferi( GLenum pname, GLint param )
775{
776   _mesa_PixelTransferf( pname, (GLfloat) param );
777}
778
779/**********************************************************************/
780/*****                  Pixel processing functions               ******/
781/**********************************************************************/
782
783
784/*
785 * Apply scale and bias factors to an array of RGBA pixels.
786 */
787void
788_mesa_scale_and_bias_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4],
789                          GLfloat rScale, GLfloat gScale,
790                          GLfloat bScale, GLfloat aScale,
791                          GLfloat rBias, GLfloat gBias,
792                          GLfloat bBias, GLfloat aBias)
793{
794   if (rScale != 1.0 || rBias != 0.0) {
795      GLuint i;
796      for (i = 0; i < n; i++) {
797         rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias;
798      }
799   }
800   if (gScale != 1.0 || gBias != 0.0) {
801      GLuint i;
802      for (i = 0; i < n; i++) {
803         rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias;
804      }
805   }
806   if (bScale != 1.0 || bBias != 0.0) {
807      GLuint i;
808      for (i = 0; i < n; i++) {
809         rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias;
810      }
811   }
812   if (aScale != 1.0 || aBias != 0.0) {
813      GLuint i;
814      for (i = 0; i < n; i++) {
815         rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias;
816      }
817   }
818}
819
820
821/*
822 * Apply pixel mapping to an array of floating point RGBA pixels.
823 */
824void
825_mesa_map_rgba( const GLcontext *ctx, GLuint n, GLfloat rgba[][4] )
826{
827   const GLfloat rscale = (GLfloat) (ctx->Pixel.MapRtoRsize - 1);
828   const GLfloat gscale = (GLfloat) (ctx->Pixel.MapGtoGsize - 1);
829   const GLfloat bscale = (GLfloat) (ctx->Pixel.MapBtoBsize - 1);
830   const GLfloat ascale = (GLfloat) (ctx->Pixel.MapAtoAsize - 1);
831   const GLfloat *rMap = ctx->Pixel.MapRtoR;
832   const GLfloat *gMap = ctx->Pixel.MapGtoG;
833   const GLfloat *bMap = ctx->Pixel.MapBtoB;
834   const GLfloat *aMap = ctx->Pixel.MapAtoA;
835   GLuint i;
836   for (i=0;i<n;i++) {
837      GLfloat r = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
838      GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
839      GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
840      GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
841      rgba[i][RCOMP] = rMap[IROUND(r * rscale)];
842      rgba[i][GCOMP] = gMap[IROUND(g * gscale)];
843      rgba[i][BCOMP] = bMap[IROUND(b * bscale)];
844      rgba[i][ACOMP] = aMap[IROUND(a * ascale)];
845   }
846}
847
848
849/*
850 * Apply the color matrix and post color matrix scaling and biasing.
851 */
852void
853_mesa_transform_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4])
854{
855   const GLfloat rs = ctx->Pixel.PostColorMatrixScale[0];
856   const GLfloat rb = ctx->Pixel.PostColorMatrixBias[0];
857   const GLfloat gs = ctx->Pixel.PostColorMatrixScale[1];
858   const GLfloat gb = ctx->Pixel.PostColorMatrixBias[1];
859   const GLfloat bs = ctx->Pixel.PostColorMatrixScale[2];
860   const GLfloat bb = ctx->Pixel.PostColorMatrixBias[2];
861   const GLfloat as = ctx->Pixel.PostColorMatrixScale[3];
862   const GLfloat ab = ctx->Pixel.PostColorMatrixBias[3];
863   const GLfloat *m = ctx->ColorMatrixStack.Top->m;
864   GLuint i;
865   for (i = 0; i < n; i++) {
866      const GLfloat r = rgba[i][RCOMP];
867      const GLfloat g = rgba[i][GCOMP];
868      const GLfloat b = rgba[i][BCOMP];
869      const GLfloat a = rgba[i][ACOMP];
870      rgba[i][RCOMP] = (m[0] * r + m[4] * g + m[ 8] * b + m[12] * a) * rs + rb;
871      rgba[i][GCOMP] = (m[1] * r + m[5] * g + m[ 9] * b + m[13] * a) * gs + gb;
872      rgba[i][BCOMP] = (m[2] * r + m[6] * g + m[10] * b + m[14] * a) * bs + bb;
873      rgba[i][ACOMP] = (m[3] * r + m[7] * g + m[11] * b + m[15] * a) * as + ab;
874   }
875}
876
877
878/*
879 * Apply a color table lookup to an array of colors.
880 */
881void
882_mesa_lookup_rgba(const struct gl_color_table *table,
883                  GLuint n, GLfloat rgba[][4])
884{
885   if (!table->Table || table->Size == 0)
886      return;
887
888   switch (table->Format) {
889      case GL_INTENSITY:
890         /* replace RGBA with I */
891         if (!table->FloatTable) {
892            const GLint max = table->Size - 1;
893            const GLfloat scale = (GLfloat) max;
894            const GLchan *lut = (const GLchan *) table->Table;
895            GLuint i;
896            for (i = 0; i < n; i++) {
897               GLint j = IROUND(rgba[i][RCOMP] * scale);
898               GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
899               rgba[i][RCOMP] = rgba[i][GCOMP] =
900                  rgba[i][BCOMP] = rgba[i][ACOMP] = c;
901            }
902         }
903         else {
904            const GLint max = table->Size - 1;
905            const GLfloat scale = (GLfloat) max;
906            const GLfloat *lut = (const GLfloat *) table->Table;
907            GLuint i;
908            for (i = 0; i < n; i++) {
909               GLint j = IROUND(rgba[i][RCOMP] * scale);
910               GLfloat c = lut[CLAMP(j, 0, max)];
911               rgba[i][RCOMP] = rgba[i][GCOMP] =
912                  rgba[i][BCOMP] = rgba[i][ACOMP] = c;
913            }
914         }
915         break;
916      case GL_LUMINANCE:
917         /* replace RGB with L */
918         if (!table->FloatTable) {
919            const GLint max = table->Size - 1;
920            const GLfloat scale = (GLfloat) max;
921            const GLchan *lut = (const GLchan *) table->Table;
922            GLuint i;
923            for (i = 0; i < n; i++) {
924               GLint j = IROUND(rgba[i][RCOMP] * scale);
925               GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
926               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
927            }
928         }
929         else {
930            const GLint max = table->Size - 1;
931            const GLfloat scale = (GLfloat) max;
932            const GLfloat *lut = (const GLfloat *) table->Table;
933            GLuint i;
934            for (i = 0; i < n; i++) {
935               GLint j = IROUND(rgba[i][RCOMP] * scale);
936               GLfloat c = lut[CLAMP(j, 0, max)];
937               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c;
938            }
939         }
940         break;
941      case GL_ALPHA:
942         /* replace A with A */
943         if (!table->FloatTable) {
944            const GLint max = table->Size - 1;
945            const GLfloat scale = (GLfloat) max;
946            const GLchan *lut = (const GLchan *) table->Table;
947            GLuint i;
948            for (i = 0; i < n; i++) {
949               GLint j = IROUND(rgba[i][ACOMP] * scale);
950               rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]);
951            }
952         }
953         else  {
954            const GLint max = table->Size - 1;
955            const GLfloat scale = (GLfloat) max;
956            const GLfloat *lut = (const GLfloat *) table->Table;
957            GLuint i;
958            for (i = 0; i < n; i++) {
959               GLint j = IROUND(rgba[i][ACOMP] * scale);
960               rgba[i][ACOMP] = lut[CLAMP(j, 0, max)];
961            }
962         }
963         break;
964      case GL_LUMINANCE_ALPHA:
965         /* replace RGBA with LLLA */
966         if (!table->FloatTable) {
967            const GLint max = table->Size - 1;
968            const GLfloat scale = (GLfloat) max;
969            const GLchan *lut = (const GLchan *) table->Table;
970            GLuint i;
971            for (i = 0; i < n; i++) {
972               GLint jL = IROUND(rgba[i][RCOMP] * scale);
973               GLint jA = IROUND(rgba[i][ACOMP] * scale);
974               GLfloat luminance, alpha;
975               jL = CLAMP(jL, 0, max);
976               jA = CLAMP(jA, 0, max);
977               luminance = CHAN_TO_FLOAT(lut[jL * 2 + 0]);
978               alpha     = CHAN_TO_FLOAT(lut[jA * 2 + 1]);
979               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
980               rgba[i][ACOMP] = alpha;;
981            }
982         }
983         else {
984            const GLint max = table->Size - 1;
985            const GLfloat scale = (GLfloat) max;
986            const GLfloat *lut = (const GLfloat *) table->Table;
987            GLuint i;
988            for (i = 0; i < n; i++) {
989               GLint jL = IROUND(rgba[i][RCOMP] * scale);
990               GLint jA = IROUND(rgba[i][ACOMP] * scale);
991               GLfloat luminance, alpha;
992               jL = CLAMP(jL, 0, max);
993               jA = CLAMP(jA, 0, max);
994               luminance = lut[jL * 2 + 0];
995               alpha     = lut[jA * 2 + 1];
996               rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance;
997               rgba[i][ACOMP] = alpha;;
998            }
999         }
1000         break;
1001      case GL_RGB:
1002         /* replace RGB with RGB */
1003         if (!table->FloatTable) {
1004            const GLint max = table->Size - 1;
1005            const GLfloat scale = (GLfloat) max;
1006            const GLchan *lut = (const GLchan *) table->Table;
1007            GLuint i;
1008            for (i = 0; i < n; i++) {
1009               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1010               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1011               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1012               jR = CLAMP(jR, 0, max);
1013               jG = CLAMP(jG, 0, max);
1014               jB = CLAMP(jB, 0, max);
1015               rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 3 + 0]);
1016               rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 3 + 1]);
1017               rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 3 + 2]);
1018            }
1019         }
1020         else {
1021            const GLint max = table->Size - 1;
1022            const GLfloat scale = (GLfloat) max;
1023            const GLfloat *lut = (const GLfloat *) table->Table;
1024            GLuint i;
1025            for (i = 0; i < n; i++) {
1026               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1027               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1028               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1029               jR = CLAMP(jR, 0, max);
1030               jG = CLAMP(jG, 0, max);
1031               jB = CLAMP(jB, 0, max);
1032               rgba[i][RCOMP] = lut[jR * 3 + 0];
1033               rgba[i][GCOMP] = lut[jG * 3 + 1];
1034               rgba[i][BCOMP] = lut[jB * 3 + 2];
1035            }
1036         }
1037         break;
1038      case GL_RGBA:
1039         /* replace RGBA with RGBA */
1040         if (!table->FloatTable) {
1041            const GLint max = table->Size - 1;
1042            const GLfloat scale = (GLfloat) max;
1043            const GLchan *lut = (const GLchan *) table->Table;
1044            GLuint i;
1045            for (i = 0; i < n; i++) {
1046               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1047               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1048               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1049               GLint jA = IROUND(rgba[i][ACOMP] * scale);
1050               jR = CLAMP(jR, 0, max);
1051               jG = CLAMP(jG, 0, max);
1052               jB = CLAMP(jB, 0, max);
1053               jA = CLAMP(jA, 0, max);
1054               rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 4 + 0]);
1055               rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 4 + 1]);
1056               rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 4 + 2]);
1057               rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[jA * 4 + 3]);
1058            }
1059         }
1060         else {
1061            const GLint max = table->Size - 1;
1062            const GLfloat scale = (GLfloat) max;
1063            const GLfloat *lut = (const GLfloat *) table->Table;
1064            GLuint i;
1065            for (i = 0; i < n; i++) {
1066               GLint jR = IROUND(rgba[i][RCOMP] * scale);
1067               GLint jG = IROUND(rgba[i][GCOMP] * scale);
1068               GLint jB = IROUND(rgba[i][BCOMP] * scale);
1069               GLint jA = IROUND(rgba[i][ACOMP] * scale);
1070               jR = CLAMP(jR, 0, max);
1071               jG = CLAMP(jG, 0, max);
1072               jB = CLAMP(jB, 0, max);
1073               jA = CLAMP(jA, 0, max);
1074               rgba[i][RCOMP] = lut[jR * 4 + 0];
1075               rgba[i][GCOMP] = lut[jG * 4 + 1];
1076               rgba[i][BCOMP] = lut[jB * 4 + 2];
1077               rgba[i][ACOMP] = lut[jA * 4 + 3];
1078            }
1079         }
1080         break;
1081      default:
1082         _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba");
1083         return;
1084   }
1085}
1086
1087
1088
1089/*
1090 * Apply color index shift and offset to an array of pixels.
1091 */
1092void
1093_mesa_shift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] )
1094{
1095   GLint shift = ctx->Pixel.IndexShift;
1096   GLint offset = ctx->Pixel.IndexOffset;
1097   GLuint i;
1098   if (shift > 0) {
1099      for (i=0;i<n;i++) {
1100         indexes[i] = (indexes[i] << shift) + offset;
1101      }
1102   }
1103   else if (shift < 0) {
1104      shift = -shift;
1105      for (i=0;i<n;i++) {
1106         indexes[i] = (indexes[i] >> shift) + offset;
1107      }
1108   }
1109   else {
1110      for (i=0;i<n;i++) {
1111         indexes[i] = indexes[i] + offset;
1112      }
1113   }
1114}
1115
1116
1117/*
1118 * Apply color index mapping to color indexes.
1119 */
1120void
1121_mesa_map_ci( const GLcontext *ctx, GLuint n, GLuint index[] )
1122{
1123   GLuint mask = ctx->Pixel.MapItoIsize - 1;
1124   GLuint i;
1125   for (i=0;i<n;i++) {
1126      index[i] = ctx->Pixel.MapItoI[ index[i] & mask ];
1127   }
1128}
1129
1130
1131/*
1132 * Map color indexes to rgba values.
1133 */
1134void
1135_mesa_map_ci_to_rgba_chan( const GLcontext *ctx, GLuint n,
1136                           const GLuint index[], GLchan rgba[][4] )
1137{
1138#if CHAN_BITS == 8
1139   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1140   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1141   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1142   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1143   const GLubyte *rMap = ctx->Pixel.MapItoR8;
1144   const GLubyte *gMap = ctx->Pixel.MapItoG8;
1145   const GLubyte *bMap = ctx->Pixel.MapItoB8;
1146   const GLubyte *aMap = ctx->Pixel.MapItoA8;
1147   GLuint i;
1148   for (i=0;i<n;i++) {
1149      rgba[i][RCOMP] = rMap[index[i] & rmask];
1150      rgba[i][GCOMP] = gMap[index[i] & gmask];
1151      rgba[i][BCOMP] = bMap[index[i] & bmask];
1152      rgba[i][ACOMP] = aMap[index[i] & amask];
1153   }
1154#else
1155   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1156   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1157   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1158   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1159   const GLfloat *rMap = ctx->Pixel.MapItoR;
1160   const GLfloat *gMap = ctx->Pixel.MapItoG;
1161   const GLfloat *bMap = ctx->Pixel.MapItoB;
1162   const GLfloat *aMap = ctx->Pixel.MapItoA;
1163   GLuint i;
1164   for (i=0;i<n;i++) {
1165      CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]);
1166      CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]);
1167      CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]);
1168      CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]);
1169   }
1170#endif
1171}
1172
1173
1174/*
1175 * Map color indexes to float rgba values.
1176 */
1177void
1178_mesa_map_ci_to_rgba( const GLcontext *ctx, GLuint n,
1179                      const GLuint index[], GLfloat rgba[][4] )
1180{
1181   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1182   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1183   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1184   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1185   const GLfloat *rMap = ctx->Pixel.MapItoR;
1186   const GLfloat *gMap = ctx->Pixel.MapItoG;
1187   const GLfloat *bMap = ctx->Pixel.MapItoB;
1188   const GLfloat *aMap = ctx->Pixel.MapItoA;
1189   GLuint i;
1190   for (i=0;i<n;i++) {
1191      rgba[i][RCOMP] = rMap[index[i] & rmask];
1192      rgba[i][GCOMP] = gMap[index[i] & gmask];
1193      rgba[i][BCOMP] = bMap[index[i] & bmask];
1194      rgba[i][ACOMP] = aMap[index[i] & amask];
1195   }
1196}
1197
1198
1199/*
1200 * Map 8-bit color indexes to rgb values.
1201 */
1202void
1203_mesa_map_ci8_to_rgba( const GLcontext *ctx, GLuint n, const GLubyte index[],
1204                       GLchan rgba[][4] )
1205{
1206#if CHAN_BITS == 8
1207   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1208   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1209   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1210   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1211   const GLubyte *rMap = ctx->Pixel.MapItoR8;
1212   const GLubyte *gMap = ctx->Pixel.MapItoG8;
1213   const GLubyte *bMap = ctx->Pixel.MapItoB8;
1214   const GLubyte *aMap = ctx->Pixel.MapItoA8;
1215   GLuint i;
1216   for (i=0;i<n;i++) {
1217      rgba[i][RCOMP] = rMap[index[i] & rmask];
1218      rgba[i][GCOMP] = gMap[index[i] & gmask];
1219      rgba[i][BCOMP] = bMap[index[i] & bmask];
1220      rgba[i][ACOMP] = aMap[index[i] & amask];
1221   }
1222#else
1223   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
1224   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
1225   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
1226   GLuint amask = ctx->Pixel.MapItoAsize - 1;
1227   const GLfloat *rMap = ctx->Pixel.MapItoR;
1228   const GLfloat *gMap = ctx->Pixel.MapItoG;
1229   const GLfloat *bMap = ctx->Pixel.MapItoB;
1230   const GLfloat *aMap = ctx->Pixel.MapItoA;
1231   GLuint i;
1232   for (i=0;i<n;i++) {
1233      CLAMPED_FLOAT_TO_CHAN(rgba[i][RCOMP], rMap[index[i] & rmask]);
1234      CLAMPED_FLOAT_TO_CHAN(rgba[i][GCOMP], gMap[index[i] & gmask]);
1235      CLAMPED_FLOAT_TO_CHAN(rgba[i][BCOMP], bMap[index[i] & bmask]);
1236      CLAMPED_FLOAT_TO_CHAN(rgba[i][ACOMP], aMap[index[i] & amask]);
1237   }
1238#endif
1239}
1240
1241
1242void
1243_mesa_shift_and_offset_stencil( const GLcontext *ctx, GLuint n,
1244                                GLstencil stencil[] )
1245{
1246   GLuint i;
1247   GLint shift = ctx->Pixel.IndexShift;
1248   GLint offset = ctx->Pixel.IndexOffset;
1249   if (shift > 0) {
1250      for (i=0;i<n;i++) {
1251         stencil[i] = (stencil[i] << shift) + offset;
1252      }
1253   }
1254   else if (shift < 0) {
1255      shift = -shift;
1256      for (i=0;i<n;i++) {
1257         stencil[i] = (stencil[i] >> shift) + offset;
1258      }
1259   }
1260   else {
1261      for (i=0;i<n;i++) {
1262         stencil[i] = stencil[i] + offset;
1263      }
1264   }
1265
1266}
1267
1268
1269void
1270_mesa_map_stencil( const GLcontext *ctx, GLuint n, GLstencil stencil[] )
1271{
1272   GLuint mask = ctx->Pixel.MapStoSsize - 1;
1273   GLuint i;
1274   for (i=0;i<n;i++) {
1275      stencil[i] = ctx->Pixel.MapStoS[ stencil[i] & mask ];
1276   }
1277}
1278
1279
1280
1281/*
1282 * This function converts an array of GLchan colors to GLfloat colors.
1283 * Most importantly, it undoes the non-uniform quantization of pixel
1284 * values introduced when we convert shallow (< 8 bit) pixel values
1285 * to GLubytes in the ctx->Driver.ReadRGBASpan() functions.
1286 * This fixes a number of OpenGL conformance failures when running on
1287 * 16bpp displays, for example.
1288 */
1289void
1290_mesa_chan_to_float_span(const GLcontext *ctx, GLuint n,
1291                         CONST GLchan rgba[][4], GLfloat rgbaf[][4])
1292{
1293#if CHAN_TYPE == GL_FLOAT
1294   MEMCPY(rgbaf, rgba, n * 4 * sizeof(GLfloat));
1295#else
1296   const GLuint rShift = CHAN_BITS - ctx->Visual.redBits;
1297   const GLuint gShift = CHAN_BITS - ctx->Visual.greenBits;
1298   const GLuint bShift = CHAN_BITS - ctx->Visual.blueBits;
1299   GLuint aShift;
1300   const GLfloat rScale = 1.0F / (GLfloat) ((1 << ctx->Visual.redBits  ) - 1);
1301   const GLfloat gScale = 1.0F / (GLfloat) ((1 << ctx->Visual.greenBits) - 1);
1302   const GLfloat bScale = 1.0F / (GLfloat) ((1 << ctx->Visual.blueBits ) - 1);
1303   GLfloat aScale;
1304   GLuint i;
1305
1306   if (ctx->Visual.alphaBits > 0) {
1307      aShift = CHAN_BITS - ctx->Visual.alphaBits;
1308      aScale = 1.0F / (GLfloat) ((1 << ctx->Visual.alphaBits) - 1);
1309   }
1310   else {
1311      aShift = 0;
1312      aScale = 1.0F / CHAN_MAXF;
1313   }
1314
1315   for (i = 0; i < n; i++) {
1316      const GLint r = rgba[i][RCOMP] >> rShift;
1317      const GLint g = rgba[i][GCOMP] >> gShift;
1318      const GLint b = rgba[i][BCOMP] >> bShift;
1319      const GLint a = rgba[i][ACOMP] >> aShift;
1320      rgbaf[i][RCOMP] = (GLfloat) r * rScale;
1321      rgbaf[i][GCOMP] = (GLfloat) g * gScale;
1322      rgbaf[i][BCOMP] = (GLfloat) b * bScale;
1323      rgbaf[i][ACOMP] = (GLfloat) a * aScale;
1324   }
1325#endif
1326}
1327
1328/**********************************************************************/
1329/*****                    State Management                        *****/
1330/**********************************************************************/
1331
1332/*
1333 * Return a bitmask of IMAGE_*_BIT flags which to indicate which
1334 * pixel transfer operations are enabled.
1335 */
1336static void
1337update_image_transfer_state(GLcontext *ctx)
1338{
1339   GLuint mask = 0;
1340
1341   if (ctx->Pixel.RedScale   != 1.0F || ctx->Pixel.RedBias   != 0.0F ||
1342       ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F ||
1343       ctx->Pixel.BlueScale  != 1.0F || ctx->Pixel.BlueBias  != 0.0F ||
1344       ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F)
1345      mask |= IMAGE_SCALE_BIAS_BIT;
1346
1347   if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset)
1348      mask |= IMAGE_SHIFT_OFFSET_BIT;
1349
1350   if (ctx->Pixel.MapColorFlag)
1351      mask |= IMAGE_MAP_COLOR_BIT;
1352
1353   if (ctx->Pixel.ColorTableEnabled)
1354      mask |= IMAGE_COLOR_TABLE_BIT;
1355
1356   if (ctx->Pixel.Convolution1DEnabled ||
1357       ctx->Pixel.Convolution2DEnabled ||
1358       ctx->Pixel.Separable2DEnabled) {
1359      mask |= IMAGE_CONVOLUTION_BIT;
1360      if (ctx->Pixel.PostConvolutionScale[0] != 1.0F ||
1361          ctx->Pixel.PostConvolutionScale[1] != 1.0F ||
1362          ctx->Pixel.PostConvolutionScale[2] != 1.0F ||
1363          ctx->Pixel.PostConvolutionScale[3] != 1.0F ||
1364          ctx->Pixel.PostConvolutionBias[0] != 0.0F ||
1365          ctx->Pixel.PostConvolutionBias[1] != 0.0F ||
1366          ctx->Pixel.PostConvolutionBias[2] != 0.0F ||
1367          ctx->Pixel.PostConvolutionBias[3] != 0.0F) {
1368         mask |= IMAGE_POST_CONVOLUTION_SCALE_BIAS;
1369      }
1370   }
1371
1372   if (ctx->Pixel.PostConvolutionColorTableEnabled)
1373      mask |= IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT;
1374
1375   if (ctx->ColorMatrixStack.Top->type != MATRIX_IDENTITY ||
1376       ctx->Pixel.PostColorMatrixScale[0] != 1.0F ||
1377       ctx->Pixel.PostColorMatrixBias[0]  != 0.0F ||
1378       ctx->Pixel.PostColorMatrixScale[1] != 1.0F ||
1379       ctx->Pixel.PostColorMatrixBias[1]  != 0.0F ||
1380       ctx->Pixel.PostColorMatrixScale[2] != 1.0F ||
1381       ctx->Pixel.PostColorMatrixBias[2]  != 0.0F ||
1382       ctx->Pixel.PostColorMatrixScale[3] != 1.0F ||
1383       ctx->Pixel.PostColorMatrixBias[3]  != 0.0F)
1384      mask |= IMAGE_COLOR_MATRIX_BIT;
1385
1386   if (ctx->Pixel.PostColorMatrixColorTableEnabled)
1387      mask |= IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT;
1388
1389   if (ctx->Pixel.HistogramEnabled)
1390      mask |= IMAGE_HISTOGRAM_BIT;
1391
1392   if (ctx->Pixel.MinMaxEnabled)
1393      mask |= IMAGE_MIN_MAX_BIT;
1394
1395   ctx->_ImageTransferState = mask;
1396}
1397
1398
1399void _mesa_update_pixel( GLcontext *ctx, GLuint new_state )
1400{
1401   if (new_state & _NEW_COLOR_MATRIX)
1402      _math_matrix_analyse( ctx->ColorMatrixStack.Top );
1403
1404   /* References ColorMatrix.type (derived above).
1405    */
1406   if (new_state & _IMAGE_NEW_TRANSFER_STATE)
1407      update_image_transfer_state(ctx);
1408}
1409
1410
1411/**********************************************************************/
1412/*****                      Initialization                        *****/
1413/**********************************************************************/
1414
1415void _mesa_init_pixel( GLcontext * ctx )
1416{
1417   int i;
1418
1419   /* Pixel group */
1420   ctx->Pixel.RedBias = 0.0;
1421   ctx->Pixel.RedScale = 1.0;
1422   ctx->Pixel.GreenBias = 0.0;
1423   ctx->Pixel.GreenScale = 1.0;
1424   ctx->Pixel.BlueBias = 0.0;
1425   ctx->Pixel.BlueScale = 1.0;
1426   ctx->Pixel.AlphaBias = 0.0;
1427   ctx->Pixel.AlphaScale = 1.0;
1428   ctx->Pixel.DepthBias = 0.0;
1429   ctx->Pixel.DepthScale = 1.0;
1430   ctx->Pixel.IndexOffset = 0;
1431   ctx->Pixel.IndexShift = 0;
1432   ctx->Pixel.ZoomX = 1.0;
1433   ctx->Pixel.ZoomY = 1.0;
1434   ctx->Pixel.MapColorFlag = GL_FALSE;
1435   ctx->Pixel.MapStencilFlag = GL_FALSE;
1436   ctx->Pixel.MapStoSsize = 1;
1437   ctx->Pixel.MapItoIsize = 1;
1438   ctx->Pixel.MapItoRsize = 1;
1439   ctx->Pixel.MapItoGsize = 1;
1440   ctx->Pixel.MapItoBsize = 1;
1441   ctx->Pixel.MapItoAsize = 1;
1442   ctx->Pixel.MapRtoRsize = 1;
1443   ctx->Pixel.MapGtoGsize = 1;
1444   ctx->Pixel.MapBtoBsize = 1;
1445   ctx->Pixel.MapAtoAsize = 1;
1446   ctx->Pixel.MapStoS[0] = 0;
1447   ctx->Pixel.MapItoI[0] = 0;
1448   ctx->Pixel.MapItoR[0] = 0.0;
1449   ctx->Pixel.MapItoG[0] = 0.0;
1450   ctx->Pixel.MapItoB[0] = 0.0;
1451   ctx->Pixel.MapItoA[0] = 0.0;
1452   ctx->Pixel.MapItoR8[0] = 0;
1453   ctx->Pixel.MapItoG8[0] = 0;
1454   ctx->Pixel.MapItoB8[0] = 0;
1455   ctx->Pixel.MapItoA8[0] = 0;
1456   ctx->Pixel.MapRtoR[0] = 0.0;
1457   ctx->Pixel.MapGtoG[0] = 0.0;
1458   ctx->Pixel.MapBtoB[0] = 0.0;
1459   ctx->Pixel.MapAtoA[0] = 0.0;
1460   ctx->Pixel.HistogramEnabled = GL_FALSE;
1461   ctx->Pixel.MinMaxEnabled = GL_FALSE;
1462   ctx->Pixel.PixelTextureEnabled = GL_FALSE;
1463   ctx->Pixel.FragmentRgbSource = GL_PIXEL_GROUP_COLOR_SGIS;
1464   ctx->Pixel.FragmentAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS;
1465   ASSIGN_4V(ctx->Pixel.PostColorMatrixScale, 1.0, 1.0, 1.0, 1.0);
1466   ASSIGN_4V(ctx->Pixel.PostColorMatrixBias, 0.0, 0.0, 0.0, 0.0);
1467   ASSIGN_4V(ctx->Pixel.ColorTableScale, 1.0, 1.0, 1.0, 1.0);
1468   ASSIGN_4V(ctx->Pixel.ColorTableBias, 0.0, 0.0, 0.0, 0.0);
1469   ASSIGN_4V(ctx->Pixel.PCCTscale, 1.0, 1.0, 1.0, 1.0);
1470   ASSIGN_4V(ctx->Pixel.PCCTbias, 0.0, 0.0, 0.0, 0.0);
1471   ASSIGN_4V(ctx->Pixel.PCMCTscale, 1.0, 1.0, 1.0, 1.0);
1472   ASSIGN_4V(ctx->Pixel.PCMCTbias, 0.0, 0.0, 0.0, 0.0);
1473   ctx->Pixel.ColorTableEnabled = GL_FALSE;
1474   ctx->Pixel.PostConvolutionColorTableEnabled = GL_FALSE;
1475   ctx->Pixel.PostColorMatrixColorTableEnabled = GL_FALSE;
1476   ctx->Pixel.Convolution1DEnabled = GL_FALSE;
1477   ctx->Pixel.Convolution2DEnabled = GL_FALSE;
1478   ctx->Pixel.Separable2DEnabled = GL_FALSE;
1479   for (i = 0; i < 3; i++) {
1480      ASSIGN_4V(ctx->Pixel.ConvolutionBorderColor[i], 0.0, 0.0, 0.0, 0.0);
1481      ctx->Pixel.ConvolutionBorderMode[i] = GL_REDUCE;
1482      ASSIGN_4V(ctx->Pixel.ConvolutionFilterScale[i], 1.0, 1.0, 1.0, 1.0);
1483      ASSIGN_4V(ctx->Pixel.ConvolutionFilterBias[i], 0.0, 0.0, 0.0, 0.0);
1484   }
1485   for (i = 0; i < MAX_CONVOLUTION_WIDTH * MAX_CONVOLUTION_WIDTH * 4; i++) {
1486      ctx->Convolution1D.Filter[i] = 0.0;
1487      ctx->Convolution2D.Filter[i] = 0.0;
1488      ctx->Separable2D.Filter[i] = 0.0;
1489   }
1490   ASSIGN_4V(ctx->Pixel.PostConvolutionScale, 1.0, 1.0, 1.0, 1.0);
1491   ASSIGN_4V(ctx->Pixel.PostConvolutionBias, 0.0, 0.0, 0.0, 0.0);
1492
1493   /* Pixel transfer */
1494   ctx->Pack.Alignment = 4;
1495   ctx->Pack.RowLength = 0;
1496   ctx->Pack.ImageHeight = 0;
1497   ctx->Pack.SkipPixels = 0;
1498   ctx->Pack.SkipRows = 0;
1499   ctx->Pack.SkipImages = 0;
1500   ctx->Pack.SwapBytes = GL_FALSE;
1501   ctx->Pack.LsbFirst = GL_FALSE;
1502   ctx->Unpack.Alignment = 4;
1503   ctx->Unpack.RowLength = 0;
1504   ctx->Unpack.ImageHeight = 0;
1505   ctx->Unpack.SkipPixels = 0;
1506   ctx->Unpack.SkipRows = 0;
1507   ctx->Unpack.SkipImages = 0;
1508   ctx->Unpack.SwapBytes = GL_FALSE;
1509   ctx->Unpack.LsbFirst = GL_FALSE;
1510
1511   if (ctx->Visual.doubleBufferMode) {
1512      ctx->Pixel.ReadBuffer = GL_BACK;
1513      ctx->Pixel._ReadSrcMask = BACK_LEFT_BIT;
1514   }
1515   else {
1516      ctx->Pixel.ReadBuffer = GL_FRONT;
1517      ctx->Pixel._ReadSrcMask = FRONT_LEFT_BIT;
1518   }
1519
1520   /* Miscellaneous */
1521   ctx->_ImageTransferState = 0;
1522}
1523