pixel.c revision 485f04074151686fa24d40e3eeb83029d3d8c425
1/* $Id: pixel.c,v 1.2 1999/10/08 09:27:11 keithw Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version:  3.1
6 *
7 * Copyright (C) 1999  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
29
30
31/*
32 * glPixelStore, glPixelTransfer, glPixelMap, glPixelZoom, etc.
33 */
34
35
36#ifdef PC_HEADER
37#include "all.h"
38#else
39#ifndef XFree86Server
40#include <assert.h>
41#include <stdio.h>
42#include <stdlib.h>
43#else
44#include "GL/xf86glx.h"
45#endif
46#include "context.h"
47#include "macros.h"
48#include "pixel.h"
49#include "types.h"
50#ifdef XFree86Server
51#include "GL/xf86glx.h"
52#endif
53#endif
54
55
56
57/**********************************************************************/
58/*****                    glPixelZoom                             *****/
59/**********************************************************************/
60
61
62
63void gl_PixelZoom( GLcontext *ctx, GLfloat xfactor, GLfloat yfactor )
64{
65   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPixelZoom");
66
67   ctx->Pixel.ZoomX = xfactor;
68   ctx->Pixel.ZoomY = yfactor;
69}
70
71
72
73/**********************************************************************/
74/*****                    glPixelStore                            *****/
75/**********************************************************************/
76
77
78void gl_PixelStorei( GLcontext *ctx, GLenum pname, GLint param )
79{
80   /* NOTE: this call can't be compiled into the display list */
81
82   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPixelStore");
83
84
85   switch (pname) {
86      case GL_PACK_SWAP_BYTES:
87         ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
88	 break;
89      case GL_PACK_LSB_FIRST:
90         ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
91	 break;
92      case GL_PACK_ROW_LENGTH:
93	 if (param<0) {
94	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
95	 }
96	 else {
97	    ctx->Pack.RowLength = param;
98	 }
99	 break;
100      case GL_PACK_IMAGE_HEIGHT:
101         if (param<0)
102            gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
103         else
104            ctx->Pack.ImageHeight = param;
105         break;
106      case GL_PACK_SKIP_PIXELS:
107	 if (param<0) {
108	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
109	 }
110	 else {
111	    ctx->Pack.SkipPixels = param;
112	 }
113	 break;
114      case GL_PACK_SKIP_ROWS:
115	 if (param<0) {
116	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
117	 }
118	 else {
119	    ctx->Pack.SkipRows = param;
120	 }
121	 break;
122      case GL_PACK_ALIGNMENT:
123         if (param==1 || param==2 || param==4 || param==8) {
124	    ctx->Pack.Alignment = param;
125	 }
126	 else {
127	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
128	 }
129	 break;
130      case GL_UNPACK_SWAP_BYTES:
131	 ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
132         break;
133      case GL_UNPACK_LSB_FIRST:
134	 ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
135	 break;
136      case GL_UNPACK_ROW_LENGTH:
137	 if (param<0) {
138	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
139	 }
140	 else {
141	    ctx->Unpack.RowLength = param;
142	 }
143	 break;
144      case GL_UNPACK_IMAGE_HEIGHT:
145         if (param<0)
146            gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
147         else
148            ctx->Unpack.ImageHeight = param;
149         break;
150      case GL_UNPACK_SKIP_PIXELS:
151	 if (param<0) {
152	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
153	 }
154	 else {
155	    ctx->Unpack.SkipPixels = param;
156	 }
157	 break;
158      case GL_UNPACK_SKIP_ROWS:
159	 if (param<0) {
160	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
161	 }
162	 else {
163	    ctx->Unpack.SkipRows = param;
164	 }
165	 break;
166      case GL_UNPACK_ALIGNMENT:
167         if (param==1 || param==2 || param==4 || param==8) {
168	    ctx->Unpack.Alignment = param;
169	 }
170	 else {
171	    gl_error( ctx, GL_INVALID_VALUE, "glPixelStore" );
172	 }
173	 break;
174      default:
175	 gl_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
176   }
177}
178
179
180
181
182
183/**********************************************************************/
184/*****                         glPixelMap                         *****/
185/**********************************************************************/
186
187
188
189void gl_PixelMapfv( GLcontext *ctx,
190                    GLenum map, GLint mapsize, const GLfloat *values )
191{
192   GLint i;
193
194   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPixelMapfv");
195
196
197   if (mapsize<0 || mapsize>MAX_PIXEL_MAP_TABLE) {
198      gl_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
199      return;
200   }
201
202   if (map>=GL_PIXEL_MAP_S_TO_S && map<=GL_PIXEL_MAP_I_TO_A) {
203      /* test that mapsize is a power of two */
204      GLuint p;
205      GLboolean ok = GL_FALSE;
206      for (p=1; p<=MAX_PIXEL_MAP_TABLE; p=p<<1) {
207	 if ( (p&mapsize) == p ) {
208	    ok = GL_TRUE;
209	    break;
210	 }
211      }
212      if (!ok) {
213	 gl_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
214         return;
215      }
216   }
217
218   switch (map) {
219      case GL_PIXEL_MAP_S_TO_S:
220         ctx->Pixel.MapStoSsize = mapsize;
221         for (i=0;i<mapsize;i++) {
222	    ctx->Pixel.MapStoS[i] = (GLint) values[i];
223	 }
224	 break;
225      case GL_PIXEL_MAP_I_TO_I:
226         ctx->Pixel.MapItoIsize = mapsize;
227         for (i=0;i<mapsize;i++) {
228	    ctx->Pixel.MapItoI[i] = (GLint) values[i];
229	 }
230	 break;
231      case GL_PIXEL_MAP_I_TO_R:
232         ctx->Pixel.MapItoRsize = mapsize;
233         for (i=0;i<mapsize;i++) {
234            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
235	    ctx->Pixel.MapItoR[i] = val;
236	    ctx->Pixel.MapItoR8[i] = (GLint) (val * 255.0F);
237	 }
238	 break;
239      case GL_PIXEL_MAP_I_TO_G:
240         ctx->Pixel.MapItoGsize = mapsize;
241         for (i=0;i<mapsize;i++) {
242            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
243	    ctx->Pixel.MapItoG[i] = val;
244	    ctx->Pixel.MapItoG8[i] = (GLint) (val * 255.0F);
245	 }
246	 break;
247      case GL_PIXEL_MAP_I_TO_B:
248         ctx->Pixel.MapItoBsize = mapsize;
249         for (i=0;i<mapsize;i++) {
250            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
251	    ctx->Pixel.MapItoB[i] = val;
252	    ctx->Pixel.MapItoB8[i] = (GLint) (val * 255.0F);
253	 }
254	 break;
255      case GL_PIXEL_MAP_I_TO_A:
256         ctx->Pixel.MapItoAsize = mapsize;
257         for (i=0;i<mapsize;i++) {
258            GLfloat val = CLAMP( values[i], 0.0, 1.0 );
259	    ctx->Pixel.MapItoA[i] = val;
260	    ctx->Pixel.MapItoA8[i] = (GLint) (val * 255.0F);
261	 }
262	 break;
263      case GL_PIXEL_MAP_R_TO_R:
264         ctx->Pixel.MapRtoRsize = mapsize;
265         for (i=0;i<mapsize;i++) {
266	    ctx->Pixel.MapRtoR[i] = CLAMP( values[i], 0.0, 1.0 );
267	 }
268	 break;
269      case GL_PIXEL_MAP_G_TO_G:
270         ctx->Pixel.MapGtoGsize = mapsize;
271         for (i=0;i<mapsize;i++) {
272	    ctx->Pixel.MapGtoG[i] = CLAMP( values[i], 0.0, 1.0 );
273	 }
274	 break;
275      case GL_PIXEL_MAP_B_TO_B:
276         ctx->Pixel.MapBtoBsize = mapsize;
277         for (i=0;i<mapsize;i++) {
278	    ctx->Pixel.MapBtoB[i] = CLAMP( values[i], 0.0, 1.0 );
279	 }
280	 break;
281      case GL_PIXEL_MAP_A_TO_A:
282         ctx->Pixel.MapAtoAsize = mapsize;
283         for (i=0;i<mapsize;i++) {
284	    ctx->Pixel.MapAtoA[i] = CLAMP( values[i], 0.0, 1.0 );
285	 }
286	 break;
287      default:
288         gl_error( ctx, GL_INVALID_ENUM, "glPixelMapfv(map)" );
289   }
290}
291
292
293
294
295
296void gl_GetPixelMapfv( GLcontext *ctx, GLenum map, GLfloat *values )
297{
298   GLint i;
299
300   ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetPixelMapfv");
301
302   switch (map) {
303      case GL_PIXEL_MAP_I_TO_I:
304         for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
305	    values[i] = (GLfloat) ctx->Pixel.MapItoI[i];
306	 }
307	 break;
308      case GL_PIXEL_MAP_S_TO_S:
309         for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
310	    values[i] = (GLfloat) ctx->Pixel.MapStoS[i];
311	 }
312	 break;
313      case GL_PIXEL_MAP_I_TO_R:
314         MEMCPY(values,ctx->Pixel.MapItoR,ctx->Pixel.MapItoRsize*sizeof(GLfloat));
315	 break;
316      case GL_PIXEL_MAP_I_TO_G:
317         MEMCPY(values,ctx->Pixel.MapItoG,ctx->Pixel.MapItoGsize*sizeof(GLfloat));
318	 break;
319      case GL_PIXEL_MAP_I_TO_B:
320         MEMCPY(values,ctx->Pixel.MapItoB,ctx->Pixel.MapItoBsize*sizeof(GLfloat));
321	 break;
322      case GL_PIXEL_MAP_I_TO_A:
323         MEMCPY(values,ctx->Pixel.MapItoA,ctx->Pixel.MapItoAsize*sizeof(GLfloat));
324	 break;
325      case GL_PIXEL_MAP_R_TO_R:
326         MEMCPY(values,ctx->Pixel.MapRtoR,ctx->Pixel.MapRtoRsize*sizeof(GLfloat));
327	 break;
328      case GL_PIXEL_MAP_G_TO_G:
329         MEMCPY(values,ctx->Pixel.MapGtoG,ctx->Pixel.MapGtoGsize*sizeof(GLfloat));
330	 break;
331      case GL_PIXEL_MAP_B_TO_B:
332         MEMCPY(values,ctx->Pixel.MapBtoB,ctx->Pixel.MapBtoBsize*sizeof(GLfloat));
333	 break;
334      case GL_PIXEL_MAP_A_TO_A:
335         MEMCPY(values,ctx->Pixel.MapAtoA,ctx->Pixel.MapAtoAsize*sizeof(GLfloat));
336	 break;
337      default:
338         gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
339   }
340}
341
342
343void gl_GetPixelMapuiv( GLcontext *ctx, GLenum map, GLuint *values )
344{
345   GLint i;
346
347   ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetPixelMapfv");
348
349   switch (map) {
350      case GL_PIXEL_MAP_I_TO_I:
351         MEMCPY(values, ctx->Pixel.MapItoI, ctx->Pixel.MapItoIsize*sizeof(GLint));
352	 break;
353      case GL_PIXEL_MAP_S_TO_S:
354         MEMCPY(values, ctx->Pixel.MapStoS, ctx->Pixel.MapStoSsize*sizeof(GLint));
355	 break;
356      case GL_PIXEL_MAP_I_TO_R:
357	 for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
358	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoR[i] );
359	 }
360	 break;
361      case GL_PIXEL_MAP_I_TO_G:
362	 for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
363	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoG[i] );
364	 }
365	 break;
366      case GL_PIXEL_MAP_I_TO_B:
367	 for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
368	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoB[i] );
369	 }
370	 break;
371      case GL_PIXEL_MAP_I_TO_A:
372	 for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
373	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoA[i] );
374	 }
375	 break;
376      case GL_PIXEL_MAP_R_TO_R:
377	 for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
378	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapRtoR[i] );
379	 }
380	 break;
381      case GL_PIXEL_MAP_G_TO_G:
382	 for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
383	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapGtoG[i] );
384	 }
385	 break;
386      case GL_PIXEL_MAP_B_TO_B:
387	 for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
388	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapBtoB[i] );
389	 }
390	 break;
391      case GL_PIXEL_MAP_A_TO_A:
392	 for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
393	    values[i] = FLOAT_TO_UINT( ctx->Pixel.MapAtoA[i] );
394	 }
395	 break;
396      default:
397         gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
398   }
399}
400
401
402void gl_GetPixelMapusv( GLcontext *ctx, GLenum map, GLushort *values )
403{
404   GLint i;
405
406   ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetPixelMapfv");
407
408   switch (map) {
409      case GL_PIXEL_MAP_I_TO_I:
410	 for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
411	    values[i] = (GLushort) ctx->Pixel.MapItoI[i];
412	 }
413	 break;
414      case GL_PIXEL_MAP_S_TO_S:
415	 for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
416	    values[i] = (GLushort) ctx->Pixel.MapStoS[i];
417	 }
418	 break;
419      case GL_PIXEL_MAP_I_TO_R:
420	 for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
421	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoR[i] );
422	 }
423	 break;
424      case GL_PIXEL_MAP_I_TO_G:
425	 for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
426	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoG[i] );
427	 }
428	 break;
429      case GL_PIXEL_MAP_I_TO_B:
430	 for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
431	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoB[i] );
432	 }
433	 break;
434      case GL_PIXEL_MAP_I_TO_A:
435	 for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
436	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoA[i] );
437	 }
438	 break;
439      case GL_PIXEL_MAP_R_TO_R:
440	 for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
441	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapRtoR[i] );
442	 }
443	 break;
444      case GL_PIXEL_MAP_G_TO_G:
445	 for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
446	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapGtoG[i] );
447	 }
448	 break;
449      case GL_PIXEL_MAP_B_TO_B:
450	 for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
451	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapBtoB[i] );
452	 }
453	 break;
454      case GL_PIXEL_MAP_A_TO_A:
455	 for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
456	    values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapAtoA[i] );
457	 }
458	 break;
459      default:
460         gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
461   }
462}
463
464
465
466/**********************************************************************/
467/*****                       glPixelTransfer                      *****/
468/**********************************************************************/
469
470
471/*
472 * Implements glPixelTransfer[fi] whether called immediately or from a
473 * display list.
474 */
475void gl_PixelTransferf( GLcontext *ctx, GLenum pname, GLfloat param )
476{
477   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPixelTransfer");
478
479
480   switch (pname) {
481      case GL_MAP_COLOR:
482         ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
483	 break;
484      case GL_MAP_STENCIL:
485         ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
486	 break;
487      case GL_INDEX_SHIFT:
488         ctx->Pixel.IndexShift = (GLint) param;
489	 break;
490      case GL_INDEX_OFFSET:
491         ctx->Pixel.IndexOffset = (GLint) param;
492	 break;
493      case GL_RED_SCALE:
494         ctx->Pixel.RedScale = param;
495	 break;
496      case GL_RED_BIAS:
497         ctx->Pixel.RedBias = param;
498	 break;
499      case GL_GREEN_SCALE:
500         ctx->Pixel.GreenScale = param;
501	 break;
502      case GL_GREEN_BIAS:
503         ctx->Pixel.GreenBias = param;
504	 break;
505      case GL_BLUE_SCALE:
506         ctx->Pixel.BlueScale = param;
507	 break;
508      case GL_BLUE_BIAS:
509         ctx->Pixel.BlueBias = param;
510	 break;
511      case GL_ALPHA_SCALE:
512         ctx->Pixel.AlphaScale = param;
513	 break;
514      case GL_ALPHA_BIAS:
515         ctx->Pixel.AlphaBias = param;
516	 break;
517      case GL_DEPTH_SCALE:
518         ctx->Pixel.DepthScale = param;
519	 break;
520      case GL_DEPTH_BIAS:
521         ctx->Pixel.DepthBias = param;
522	 break;
523      default:
524         gl_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
525         return;
526   }
527
528   if (ctx->Pixel.RedScale!=1.0F   || ctx->Pixel.RedBias!=0.0F ||
529       ctx->Pixel.GreenScale!=1.0F || ctx->Pixel.GreenBias!=0.0F ||
530       ctx->Pixel.BlueScale!=1.0F  || ctx->Pixel.BlueBias!=0.0F ||
531       ctx->Pixel.AlphaScale!=1.0F || ctx->Pixel.AlphaBias!=0.0F) {
532      ctx->Pixel.ScaleOrBiasRGBA = GL_TRUE;
533   }
534   else {
535      ctx->Pixel.ScaleOrBiasRGBA = GL_FALSE;
536   }
537}
538
539
540
541
542/*
543 * Pixel processing functions
544 */
545
546
547/*
548 * Apply scale and bias factors to an array of RGBA pixels.
549 */
550void gl_scale_and_bias_color( const GLcontext *ctx, GLuint n,
551                              GLfloat red[], GLfloat green[],
552                              GLfloat blue[], GLfloat alpha[] )
553{
554   GLuint i;
555   for (i=0;i<n;i++) {
556      GLfloat r = red[i]   * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
557      GLfloat g = green[i] * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
558      GLfloat b = blue[i]  * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
559      GLfloat a = alpha[i] * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
560      red[i]   = CLAMP( r, 0.0F, 1.0F );
561      green[i] = CLAMP( g, 0.0F, 1.0F );
562      blue[i]  = CLAMP( b, 0.0F, 1.0F );
563      alpha[i] = CLAMP( a, 0.0F, 1.0F );
564   }
565}
566
567
568/*
569 * Apply scale and bias factors to an array of RGBA pixels.
570 */
571void gl_scale_and_bias_rgba( const GLcontext *ctx, GLuint n, GLubyte rgba[][4] )
572{
573   GLfloat rbias = ctx->Pixel.RedBias   * 255.0F;
574   GLfloat gbias = ctx->Pixel.GreenBias * 255.0F;
575   GLfloat bbias = ctx->Pixel.BlueBias  * 255.0F;
576   GLfloat abias = ctx->Pixel.AlphaBias * 255.0F;
577   GLuint i;
578   for (i=0;i<n;i++) {
579      GLint r = (GLint) (rgba[i][RCOMP] * ctx->Pixel.RedScale   + rbias);
580      GLint g = (GLint) (rgba[i][GCOMP] * ctx->Pixel.GreenScale + gbias);
581      GLint b = (GLint) (rgba[i][BCOMP] * ctx->Pixel.BlueScale  + bbias);
582      GLint a = (GLint) (rgba[i][ACOMP] * ctx->Pixel.AlphaScale + abias);
583      rgba[i][RCOMP] = CLAMP( r, 0, 255 );
584      rgba[i][GCOMP] = CLAMP( g, 0, 255 );
585      rgba[i][BCOMP] = CLAMP( b, 0, 255 );
586      rgba[i][ACOMP] = CLAMP( a, 0, 255 );
587   }
588}
589
590
591/*
592 * Apply pixel mapping to an array of RGBA pixels.
593 */
594void gl_map_rgba( const GLcontext *ctx, GLuint n, GLubyte rgba[][4] )
595{
596   GLfloat rscale = (ctx->Pixel.MapRtoRsize - 1) / 255.0F;
597   GLfloat gscale = (ctx->Pixel.MapGtoGsize - 1) / 255.0F;
598   GLfloat bscale = (ctx->Pixel.MapBtoBsize - 1) / 255.0F;
599   GLfloat ascale = (ctx->Pixel.MapAtoAsize - 1) / 255.0F;
600   GLuint i;
601   for (i=0;i<n;i++) {
602      GLint ir = (GLint) (rgba[i][RCOMP] * rscale);
603      GLint ig = (GLint) (rgba[i][GCOMP] * gscale);
604      GLint ib = (GLint) (rgba[i][BCOMP] * bscale);
605      GLint ia = (GLint) (rgba[i][ACOMP] * ascale);
606      rgba[i][RCOMP] = (GLint) (ctx->Pixel.MapRtoR[ir] * 255.0F);
607      rgba[i][GCOMP] = (GLint) (ctx->Pixel.MapGtoG[ig] * 255.0F);
608      rgba[i][BCOMP] = (GLint) (ctx->Pixel.MapBtoB[ib] * 255.0F);
609      rgba[i][ACOMP] = (GLint) (ctx->Pixel.MapAtoA[ia] * 255.0F);
610   }
611}
612
613
614/*
615 * Apply pixel mapping to an array of RGBA pixels.
616 */
617void gl_map_color( const GLcontext *ctx, GLuint n,
618                   GLfloat red[], GLfloat green[],
619                   GLfloat blue[], GLfloat alpha[] )
620{
621   GLfloat rscale = ctx->Pixel.MapRtoRsize-1;
622   GLfloat gscale = ctx->Pixel.MapGtoGsize-1;
623   GLfloat bscale = ctx->Pixel.MapBtoBsize-1;
624   GLfloat ascale = ctx->Pixel.MapAtoAsize-1;
625   GLuint i;
626   for (i=0;i<n;i++) {
627      red[i]   = ctx->Pixel.MapRtoR[ (GLint) (red[i]   * rscale) ];
628      green[i] = ctx->Pixel.MapGtoG[ (GLint) (green[i] * gscale) ];
629      blue[i]  = ctx->Pixel.MapBtoB[ (GLint) (blue[i]  * bscale) ];
630      alpha[i] = ctx->Pixel.MapAtoA[ (GLint) (alpha[i] * ascale) ];
631   }
632}
633
634
635
636/*
637 * Apply color index shift and offset to an array of pixels.
638 */
639void gl_shift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] )
640{
641   GLint shift = ctx->Pixel.IndexShift;
642   GLint offset = ctx->Pixel.IndexOffset;
643   GLuint i;
644   if (shift > 0) {
645      for (i=0;i<n;i++) {
646         indexes[i] = (indexes[i] << shift) + offset;
647      }
648   }
649   else if (shift < 0) {
650      shift = -shift;
651      for (i=0;i<n;i++) {
652         indexes[i] = (indexes[i] >> shift) + offset;
653      }
654   }
655   else {
656      for (i=0;i<n;i++) {
657         indexes[i] = indexes[i] + offset;
658      }
659   }
660}
661
662
663/*
664 * Apply color index mapping to color indexes.
665 */
666void gl_map_ci( const GLcontext *ctx, GLuint n, GLuint index[] )
667{
668   GLuint mask = ctx->Pixel.MapItoIsize - 1;
669   GLuint i;
670   for (i=0;i<n;i++) {
671      index[i] = ctx->Pixel.MapItoI[ index[i] & mask ];
672   }
673}
674
675
676/*
677 * Map color indexes to rgb values.
678 */
679void gl_map_ci_to_rgba( const GLcontext *ctx, GLuint n, const GLuint index[],
680                        GLubyte rgba[][4] )
681{
682   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
683   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
684   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
685   GLuint amask = ctx->Pixel.MapItoAsize - 1;
686   const GLubyte *rMap = ctx->Pixel.MapItoR8;
687   const GLubyte *gMap = ctx->Pixel.MapItoG8;
688   const GLubyte *bMap = ctx->Pixel.MapItoB8;
689   const GLubyte *aMap = ctx->Pixel.MapItoA8;
690   GLuint i;
691   for (i=0;i<n;i++) {
692      rgba[i][RCOMP] = rMap[index[i] & rmask];
693      rgba[i][GCOMP] = gMap[index[i] & gmask];
694      rgba[i][BCOMP] = bMap[index[i] & bmask];
695      rgba[i][ACOMP] = aMap[index[i] & amask];
696   }
697}
698
699
700/*
701 * Map 8-bit color indexes to rgb values.
702 */
703void gl_map_ci8_to_rgba( const GLcontext *ctx, GLuint n, const GLubyte index[],
704                         GLubyte rgba[][4] )
705{
706   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
707   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
708   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
709   GLuint amask = ctx->Pixel.MapItoAsize - 1;
710   const GLubyte *rMap = ctx->Pixel.MapItoR8;
711   const GLubyte *gMap = ctx->Pixel.MapItoG8;
712   const GLubyte *bMap = ctx->Pixel.MapItoB8;
713   const GLubyte *aMap = ctx->Pixel.MapItoA8;
714   GLuint i;
715   for (i=0;i<n;i++) {
716      rgba[i][RCOMP] = rMap[index[i] & rmask];
717      rgba[i][GCOMP] = gMap[index[i] & gmask];
718      rgba[i][BCOMP] = bMap[index[i] & bmask];
719      rgba[i][ACOMP] = aMap[index[i] & amask];
720   }
721}
722
723
724void gl_map_ci_to_color( const GLcontext *ctx, GLuint n, const GLuint index[],
725                         GLfloat r[], GLfloat g[],
726                         GLfloat b[], GLfloat a[] )
727{
728   GLuint rmask = ctx->Pixel.MapItoRsize - 1;
729   GLuint gmask = ctx->Pixel.MapItoGsize - 1;
730   GLuint bmask = ctx->Pixel.MapItoBsize - 1;
731   GLuint amask = ctx->Pixel.MapItoAsize - 1;
732   GLuint i;
733   for (i=0;i<n;i++) {
734      r[i] = ctx->Pixel.MapItoR[index[i] & rmask];
735      g[i] = ctx->Pixel.MapItoG[index[i] & gmask];
736      b[i] = ctx->Pixel.MapItoB[index[i] & bmask];
737      a[i] = ctx->Pixel.MapItoA[index[i] & amask];
738   }
739}
740
741
742
743void gl_shift_and_offset_stencil( const GLcontext *ctx, GLuint n,
744                                  GLstencil stencil[] )
745{
746   GLuint i;
747   GLint shift = ctx->Pixel.IndexShift;
748   GLint offset = ctx->Pixel.IndexOffset;
749   if (shift > 0) {
750      for (i=0;i<n;i++) {
751         stencil[i] = (stencil[i] << shift) + offset;
752      }
753   }
754   else if (shift < 0) {
755      shift = -shift;
756      for (i=0;i<n;i++) {
757         stencil[i] = (stencil[i] >> shift) + offset;
758      }
759   }
760   else {
761      for (i=0;i<n;i++) {
762         stencil[i] = stencil[i] + offset;
763      }
764   }
765
766}
767
768
769
770void gl_map_stencil( const GLcontext *ctx, GLuint n, GLstencil stencil[] )
771{
772   GLuint mask = ctx->Pixel.MapStoSsize - 1;
773   GLuint i;
774   for (i=0;i<n;i++) {
775      stencil[i] = ctx->Pixel.MapStoS[ stencil[i] & mask ];
776   }
777}
778
779