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