colortab.c revision fde5e2c5f182759aff78bdd12e6c928f3f13bbdc
1/* $Id: colortab.c,v 1.42 2001/09/15 18:02:49 brianp Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version:  3.5
6 *
7 * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28#ifdef PC_HEADER
29#include "all.h"
30#else
31#include "glheader.h"
32#include "colortab.h"
33#include "context.h"
34#include "image.h"
35#include "macros.h"
36#include "mem.h"
37#include "mmath.h"
38#include "state.h"
39#include "swrast/s_span.h" /* XXX SWRAST hack */
40#endif
41
42
43
44/*
45 * Given an internalFormat token passed to glColorTable,
46 * return the corresponding base format.
47 * Return -1 if invalid token.
48 */
49static GLint
50base_colortab_format( GLenum format )
51{
52   switch (format) {
53      case GL_ALPHA:
54      case GL_ALPHA4:
55      case GL_ALPHA8:
56      case GL_ALPHA12:
57      case GL_ALPHA16:
58         return GL_ALPHA;
59      case GL_LUMINANCE:
60      case GL_LUMINANCE4:
61      case GL_LUMINANCE8:
62      case GL_LUMINANCE12:
63      case GL_LUMINANCE16:
64         return GL_LUMINANCE;
65      case GL_LUMINANCE_ALPHA:
66      case GL_LUMINANCE4_ALPHA4:
67      case GL_LUMINANCE6_ALPHA2:
68      case GL_LUMINANCE8_ALPHA8:
69      case GL_LUMINANCE12_ALPHA4:
70      case GL_LUMINANCE12_ALPHA12:
71      case GL_LUMINANCE16_ALPHA16:
72         return GL_LUMINANCE_ALPHA;
73      case GL_INTENSITY:
74      case GL_INTENSITY4:
75      case GL_INTENSITY8:
76      case GL_INTENSITY12:
77      case GL_INTENSITY16:
78         return GL_INTENSITY;
79      case GL_RGB:
80      case GL_R3_G3_B2:
81      case GL_RGB4:
82      case GL_RGB5:
83      case GL_RGB8:
84      case GL_RGB10:
85      case GL_RGB12:
86      case GL_RGB16:
87         return GL_RGB;
88      case GL_RGBA:
89      case GL_RGBA2:
90      case GL_RGBA4:
91      case GL_RGB5_A1:
92      case GL_RGBA8:
93      case GL_RGB10_A2:
94      case GL_RGBA12:
95      case GL_RGBA16:
96         return GL_RGBA;
97      default:
98         return -1;  /* error */
99   }
100}
101
102
103void
104_mesa_init_colortable( struct gl_color_table *p )
105{
106   p->FloatTable = GL_FALSE;
107   p->Table = NULL;
108   p->Size = 0;
109   p->IntFormat = GL_RGBA;
110}
111
112
113
114void
115_mesa_free_colortable_data( struct gl_color_table *p )
116{
117   if (p->Table) {
118      FREE(p->Table);
119      p->Table = NULL;
120   }
121}
122
123
124/*
125 * Examine table's format and set the component sizes accordingly.
126 */
127static void
128set_component_sizes( struct gl_color_table *table )
129{
130   switch (table->Format) {
131      case GL_ALPHA:
132         table->RedSize = 0;
133         table->GreenSize = 0;
134         table->BlueSize = 0;
135         table->AlphaSize = CHAN_BITS;
136         table->IntensitySize = 0;
137         table->LuminanceSize = 0;
138         break;
139      case GL_LUMINANCE:
140         table->RedSize = 0;
141         table->GreenSize = 0;
142         table->BlueSize = 0;
143         table->AlphaSize = 0;
144         table->IntensitySize = 0;
145         table->LuminanceSize = CHAN_BITS;
146         break;
147      case GL_LUMINANCE_ALPHA:
148         table->RedSize = 0;
149         table->GreenSize = 0;
150         table->BlueSize = 0;
151         table->AlphaSize = CHAN_BITS;
152         table->IntensitySize = 0;
153         table->LuminanceSize = CHAN_BITS;
154         break;
155      case GL_INTENSITY:
156         table->RedSize = 0;
157         table->GreenSize = 0;
158         table->BlueSize = 0;
159         table->AlphaSize = 0;
160         table->IntensitySize = CHAN_BITS;
161         table->LuminanceSize = 0;
162         break;
163      case GL_RGB:
164         table->RedSize = CHAN_BITS;
165         table->GreenSize = CHAN_BITS;
166         table->BlueSize = CHAN_BITS;
167         table->AlphaSize = 0;
168         table->IntensitySize = 0;
169         table->LuminanceSize = 0;
170         break;
171      case GL_RGBA:
172         table->RedSize = CHAN_BITS;
173         table->GreenSize = CHAN_BITS;
174         table->BlueSize = CHAN_BITS;
175         table->AlphaSize = CHAN_BITS;
176         table->IntensitySize = 0;
177         table->LuminanceSize = 0;
178         break;
179      default:
180         _mesa_problem(NULL, "unexpected format in set_component_sizes");
181   }
182}
183
184
185
186void
187_mesa_ColorTable( GLenum target, GLenum internalFormat,
188                  GLsizei width, GLenum format, GLenum type,
189                  const GLvoid *data )
190{
191   GET_CURRENT_CONTEXT(ctx);
192   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
193   struct gl_texture_object *texObj = NULL;
194   struct gl_color_table *table = NULL;
195   GLboolean proxy = GL_FALSE;
196   GLint baseFormat;
197   GLfloat rScale = 1.0, gScale = 1.0, bScale = 1.0, aScale = 1.0;
198   GLfloat rBias  = 0.0, gBias  = 0.0, bBias  = 0.0, aBias  = 0.0;
199   GLboolean floatTable = GL_FALSE;
200   GLint comps;
201   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */
202
203   switch (target) {
204      case GL_TEXTURE_1D:
205         texObj = texUnit->Current1D;
206         table = &texObj->Palette;
207         break;
208      case GL_TEXTURE_2D:
209         texObj = texUnit->Current2D;
210         table = &texObj->Palette;
211         break;
212      case GL_TEXTURE_3D:
213         texObj = texUnit->Current3D;
214         table = &texObj->Palette;
215         break;
216      case GL_PROXY_TEXTURE_1D:
217         texObj = ctx->Texture.Proxy1D;
218         table = &texObj->Palette;
219         proxy = GL_TRUE;
220         break;
221      case GL_PROXY_TEXTURE_2D:
222         texObj = ctx->Texture.Proxy2D;
223         table = &texObj->Palette;
224         proxy = GL_TRUE;
225         break;
226      case GL_PROXY_TEXTURE_3D:
227         texObj = ctx->Texture.Proxy3D;
228         table = &texObj->Palette;
229         proxy = GL_TRUE;
230         break;
231      case GL_SHARED_TEXTURE_PALETTE_EXT:
232         table = &ctx->Texture.Palette;
233         break;
234      case GL_COLOR_TABLE:
235         table = &ctx->ColorTable;
236         floatTable = GL_TRUE;
237         rScale = ctx->Pixel.ColorTableScale[0];
238         gScale = ctx->Pixel.ColorTableScale[1];
239         bScale = ctx->Pixel.ColorTableScale[2];
240         aScale = ctx->Pixel.ColorTableScale[3];
241         rBias = ctx->Pixel.ColorTableBias[0];
242         gBias = ctx->Pixel.ColorTableBias[1];
243         bBias = ctx->Pixel.ColorTableBias[2];
244         aBias = ctx->Pixel.ColorTableBias[3];
245         break;
246      case GL_PROXY_COLOR_TABLE:
247         table = &ctx->ProxyColorTable;
248         proxy = GL_TRUE;
249         break;
250      case GL_POST_CONVOLUTION_COLOR_TABLE:
251         table = &ctx->PostConvolutionColorTable;
252         floatTable = GL_TRUE;
253         rScale = ctx->Pixel.PCCTscale[0];
254         gScale = ctx->Pixel.PCCTscale[1];
255         bScale = ctx->Pixel.PCCTscale[2];
256         aScale = ctx->Pixel.PCCTscale[3];
257         rBias = ctx->Pixel.PCCTbias[0];
258         gBias = ctx->Pixel.PCCTbias[1];
259         bBias = ctx->Pixel.PCCTbias[2];
260         aBias = ctx->Pixel.PCCTbias[3];
261         break;
262      case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
263         table = &ctx->ProxyPostConvolutionColorTable;
264         proxy = GL_TRUE;
265         break;
266      case GL_POST_COLOR_MATRIX_COLOR_TABLE:
267         table = &ctx->PostColorMatrixColorTable;
268         floatTable = GL_TRUE;
269         rScale = ctx->Pixel.PCMCTscale[0];
270         gScale = ctx->Pixel.PCMCTscale[1];
271         bScale = ctx->Pixel.PCMCTscale[2];
272         aScale = ctx->Pixel.PCMCTscale[3];
273         rBias = ctx->Pixel.PCMCTbias[0];
274         gBias = ctx->Pixel.PCMCTbias[1];
275         bBias = ctx->Pixel.PCMCTbias[2];
276         aBias = ctx->Pixel.PCMCTbias[3];
277         break;
278      case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
279         table = &ctx->ProxyPostColorMatrixColorTable;
280         proxy = GL_TRUE;
281         break;
282      default:
283         _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
284         return;
285   }
286
287   assert(table);
288
289   if (!_mesa_is_legal_format_and_type(format, type) ||
290       format == GL_INTENSITY) {
291      _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTable(format or type)");
292      return;
293   }
294
295   baseFormat = base_colortab_format(internalFormat);
296   if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) {
297      _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(internalFormat)");
298      return;
299   }
300
301   if (width < 0 || (width != 0 && _mesa_bitcount(width) != 1)) {
302      /* error */
303      if (proxy) {
304         table->Size = 0;
305         table->IntFormat = (GLenum) 0;
306         table->Format = (GLenum) 0;
307      }
308      else {
309         char msg[100];
310         sprintf(msg, "glColorTable(width=%d)", width);
311         _mesa_error(ctx, GL_INVALID_VALUE, msg);
312      }
313      return;
314   }
315
316   if (width > (GLsizei) ctx->Const.MaxColorTableSize) {
317      if (proxy) {
318         table->Size = 0;
319         table->IntFormat = (GLenum) 0;
320         table->Format = (GLenum) 0;
321      }
322      else {
323         _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glColorTable(width)");
324      }
325      return;
326   }
327
328   table->Size = width;
329   table->IntFormat = internalFormat;
330   table->Format = (GLenum) baseFormat;
331   set_component_sizes(table);
332
333   comps = _mesa_components_in_format(table->Format);
334   assert(comps > 0);  /* error should have been caught sooner */
335
336   if (!proxy) {
337      /* free old table, if any */
338      if (table->Table) {
339         FREE(table->Table);
340         table->Table = NULL;
341      }
342      if (width > 0) {
343         if (floatTable) {
344            GLfloat tempTab[MAX_COLOR_TABLE_SIZE * 4];
345            GLfloat *tableF;
346            GLint i;
347
348            _mesa_unpack_float_color_span(ctx, width, table->Format,
349                                          tempTab,  /* dest */
350                                          format, type, data, &ctx->Unpack,
351                                          0, GL_FALSE);
352
353            table->FloatTable = GL_TRUE;
354            table->Table = MALLOC(comps * width * sizeof(GLfloat));
355            if (!table->Table) {
356               _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable");
357               return;
358            }
359
360            tableF = (GLfloat *) table->Table;
361
362            switch (table->Format) {
363               case GL_INTENSITY:
364                  for (i = 0; i < width; i++) {
365                     tableF[i] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F);
366                  }
367                  break;
368               case GL_LUMINANCE:
369                  for (i = 0; i < width; i++) {
370                     tableF[i] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F);
371                  }
372                  break;
373               case GL_ALPHA:
374                  for (i = 0; i < width; i++) {
375                     tableF[i] = CLAMP(tempTab[i] * aScale + aBias, 0.0F, 1.0F);
376                  }
377                  break;
378               case GL_LUMINANCE_ALPHA:
379                  for (i = 0; i < width; i++) {
380                     tableF[i*2+0] = CLAMP(tempTab[i*2+0] * rScale + rBias, 0.0F, 1.0F);
381                     tableF[i*2+1] = CLAMP(tempTab[i*2+1] * aScale + aBias, 0.0F, 1.0F);
382                  }
383                  break;
384               case GL_RGB:
385                  for (i = 0; i < width; i++) {
386                     tableF[i*3+0] = CLAMP(tempTab[i*3+0] * rScale + rBias, 0.0F, 1.0F);
387                     tableF[i*3+1] = CLAMP(tempTab[i*3+1] * gScale + gBias, 0.0F, 1.0F);
388                     tableF[i*3+2] = CLAMP(tempTab[i*3+2] * bScale + bBias, 0.0F, 1.0F);
389                  }
390                  break;
391               case GL_RGBA:
392                  for (i = 0; i < width; i++) {
393                     tableF[i*4+0] = CLAMP(tempTab[i*4+0] * rScale + rBias, 0.0F, 1.0F);
394                     tableF[i*4+1] = CLAMP(tempTab[i*4+1] * gScale + gBias, 0.0F, 1.0F);
395                     tableF[i*4+2] = CLAMP(tempTab[i*4+2] * bScale + bBias, 0.0F, 1.0F);
396                     tableF[i*4+3] = CLAMP(tempTab[i*4+3] * aScale + aBias, 0.0F, 1.0F);
397                  }
398                  break;
399               default:
400                  _mesa_problem(ctx, "Bad format in _mesa_ColorTable");
401                  return;
402            }
403         }
404         else {
405            /* store GLchan table */
406            table->FloatTable = GL_FALSE;
407            table->Table = MALLOC(comps * width * sizeof(GLchan));
408            if (!table->Table) {
409               _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable");
410               return;
411            }
412            _mesa_unpack_chan_color_span(ctx, width, table->Format,
413                                         (GLchan *) table->Table,  /* dest */
414                                         format, type, data,
415                                         &ctx->Unpack, 0);
416         } /* floatTable */
417      } /* width > 0 */
418   } /* proxy */
419
420   if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) {
421      /* texture object palette, texObj==NULL means the shared palette */
422      if (ctx->Driver.UpdateTexturePalette) {
423         (*ctx->Driver.UpdateTexturePalette)( ctx, texObj );
424      }
425   }
426
427   ctx->NewState |= _NEW_PIXEL;
428}
429
430
431
432void
433_mesa_ColorSubTable( GLenum target, GLsizei start,
434                     GLsizei count, GLenum format, GLenum type,
435                     const GLvoid *data )
436{
437   GET_CURRENT_CONTEXT(ctx);
438   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
439   struct gl_texture_object *texObj = NULL;
440   struct gl_color_table *table = NULL;
441   GLfloat rScale = 1.0, gScale = 1.0, bScale = 1.0, aScale = 1.0;
442   GLfloat rBias  = 0.0, gBias  = 0.0, bBias  = 0.0, aBias  = 0.0;
443   GLint comps;
444   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
445
446   switch (target) {
447      case GL_TEXTURE_1D:
448         texObj = texUnit->Current1D;
449         table = &texObj->Palette;
450         break;
451      case GL_TEXTURE_2D:
452         texObj = texUnit->Current2D;
453         table = &texObj->Palette;
454         break;
455      case GL_TEXTURE_3D:
456         texObj = texUnit->Current3D;
457         table = &texObj->Palette;
458         break;
459      case GL_SHARED_TEXTURE_PALETTE_EXT:
460         table = &ctx->Texture.Palette;
461         break;
462      case GL_COLOR_TABLE:
463         table = &ctx->ColorTable;
464         rScale = ctx->Pixel.ColorTableScale[0];
465         gScale = ctx->Pixel.ColorTableScale[1];
466         bScale = ctx->Pixel.ColorTableScale[2];
467         aScale = ctx->Pixel.ColorTableScale[3];
468         rBias = ctx->Pixel.ColorTableBias[0];
469         gBias = ctx->Pixel.ColorTableBias[1];
470         bBias = ctx->Pixel.ColorTableBias[2];
471         aBias = ctx->Pixel.ColorTableBias[3];
472         break;
473      case GL_POST_CONVOLUTION_COLOR_TABLE:
474         table = &ctx->PostConvolutionColorTable;
475         rScale = ctx->Pixel.PCCTscale[0];
476         gScale = ctx->Pixel.PCCTscale[1];
477         bScale = ctx->Pixel.PCCTscale[2];
478         aScale = ctx->Pixel.PCCTscale[3];
479         rBias = ctx->Pixel.PCCTbias[0];
480         gBias = ctx->Pixel.PCCTbias[1];
481         bBias = ctx->Pixel.PCCTbias[2];
482         aBias = ctx->Pixel.PCCTbias[3];
483         break;
484      case GL_POST_COLOR_MATRIX_COLOR_TABLE:
485         table = &ctx->PostColorMatrixColorTable;
486         rScale = ctx->Pixel.PCMCTscale[0];
487         gScale = ctx->Pixel.PCMCTscale[1];
488         bScale = ctx->Pixel.PCMCTscale[2];
489         aScale = ctx->Pixel.PCMCTscale[3];
490         rBias = ctx->Pixel.PCMCTbias[0];
491         gBias = ctx->Pixel.PCMCTbias[1];
492         bBias = ctx->Pixel.PCMCTbias[2];
493         aBias = ctx->Pixel.PCMCTbias[3];
494         break;
495      default:
496         _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
497         return;
498   }
499
500   assert(table);
501
502   if (!_mesa_is_legal_format_and_type(format, type) ||
503       format == GL_INTENSITY) {
504      _mesa_error(ctx, GL_INVALID_OPERATION, "glColorSubTable(format or type)");
505      return;
506   }
507
508   if (count < 1) {
509      _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)");
510      return;
511   }
512
513   comps = _mesa_components_in_format(table->Format);
514   assert(comps > 0);  /* error should have been caught sooner */
515
516   if (start + count > (GLint) table->Size) {
517      _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)");
518      return;
519   }
520
521   if (!table->Table) {
522      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorSubTable");
523      return;
524   }
525
526   if (!table->FloatTable) {
527      GLchan *dest = (GLchan *) table->Table + start * comps * sizeof(GLchan);
528      _mesa_unpack_chan_color_span(ctx, count, table->Format, dest,
529                                   format, type, data, &ctx->Unpack, 0);
530   }
531   else {
532      GLfloat tempTab[MAX_COLOR_TABLE_SIZE * 4];
533      GLfloat *tableF;
534      GLint i;
535
536      ASSERT(table->FloatTable);
537
538      _mesa_unpack_float_color_span(ctx, count, table->Format,
539                                    tempTab,  /* dest */
540                                    format, type, data, &ctx->Unpack,
541                                    0, GL_FALSE);
542
543      tableF = (GLfloat *) table->Table;
544
545      switch (table->Format) {
546         case GL_INTENSITY:
547            for (i = 0; i < count; i++) {
548               GLuint j = start + i;
549               tableF[j] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F);
550            }
551            break;
552         case GL_LUMINANCE:
553            for (i = 0; i < count; i++) {
554               GLuint j = start + i;
555               tableF[j] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F);
556            }
557            break;
558         case GL_ALPHA:
559            for (i = 0; i < count; i++) {
560               GLuint j = start + i;
561               tableF[j] = CLAMP(tempTab[i] * aScale + aBias, 0.0F, 1.0F);
562            }
563            break;
564         case GL_LUMINANCE_ALPHA:
565            for (i = 0; i < count; i++) {
566               GLuint j = start + i;
567               tableF[j*2+0] = CLAMP(tempTab[i*2+0] * rScale + rBias, 0.0F, 1.0F);
568               tableF[j*2+1] = CLAMP(tempTab[i*2+1] * aScale + aBias, 0.0F, 1.0F);
569            }
570            break;
571         case GL_RGB:
572            for (i = 0; i < count; i++) {
573               GLuint j = start + i;
574               tableF[j*3+0] = CLAMP(tempTab[i*3+0] * rScale + rBias, 0.0F, 1.0F);
575               tableF[j*3+1] = CLAMP(tempTab[i*3+1] * gScale + gBias, 0.0F, 1.0F);
576               tableF[j*3+2] = CLAMP(tempTab[i*3+2] * bScale + bBias, 0.0F, 1.0F);
577            }
578            break;
579         case GL_RGBA:
580            for (i = 0; i < count; i++) {
581               GLuint j = start + i;
582               tableF[j*4+0] = CLAMP(tempTab[i*4+0] * rScale + rBias, 0.0F, 1.0F);
583               tableF[j*4+1] = CLAMP(tempTab[i*4+1] * gScale + gBias, 0.0F, 1.0F);
584               tableF[j*4+2] = CLAMP(tempTab[i*4+2] * bScale + bBias, 0.0F, 1.0F);
585               tableF[j*4+3] = CLAMP(tempTab[i*4+3] * aScale + aBias, 0.0F, 1.0F);
586            }
587            break;
588         default:
589            _mesa_problem(ctx, "Bad format in _mesa_ColorSubTable");
590            return;
591         }
592   }
593
594   if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) {
595      /* per-texture object palette */
596      if (ctx->Driver.UpdateTexturePalette) {
597         (*ctx->Driver.UpdateTexturePalette)( ctx, texObj );
598      }
599   }
600
601   ctx->NewState |= _NEW_PIXEL;
602}
603
604
605
606/* XXX not tested */
607void
608_mesa_CopyColorTable(GLenum target, GLenum internalformat,
609                     GLint x, GLint y, GLsizei width)
610{
611   GET_CURRENT_CONTEXT(ctx);
612   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
613
614   /* Select buffer to read from */
615   ctx->Driver.CopyColorTable( ctx, target, internalformat, x, y, width );
616}
617
618
619
620/* XXX not tested */
621void
622_mesa_CopyColorSubTable(GLenum target, GLsizei start,
623                        GLint x, GLint y, GLsizei width)
624{
625   GET_CURRENT_CONTEXT(ctx);
626   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
627
628   ctx->Driver.CopyColorSubTable( ctx, target, start, x, y, width );
629}
630
631
632
633void
634_mesa_GetColorTable( GLenum target, GLenum format,
635                     GLenum type, GLvoid *data )
636{
637   GET_CURRENT_CONTEXT(ctx);
638   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
639   struct gl_color_table *table = NULL;
640   GLchan rgba[MAX_COLOR_TABLE_SIZE][4];
641   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
642
643   if (ctx->NewState) {
644      _mesa_update_state(ctx);
645   }
646
647   switch (target) {
648      case GL_TEXTURE_1D:
649         table = &texUnit->Current1D->Palette;
650         break;
651      case GL_TEXTURE_2D:
652         table = &texUnit->Current2D->Palette;
653         break;
654      case GL_TEXTURE_3D:
655         table = &texUnit->Current3D->Palette;
656         break;
657      case GL_SHARED_TEXTURE_PALETTE_EXT:
658         table = &ctx->Texture.Palette;
659         break;
660      case GL_COLOR_TABLE:
661         table = &ctx->ColorTable;
662         break;
663      case GL_POST_CONVOLUTION_COLOR_TABLE:
664         table = &ctx->PostConvolutionColorTable;
665         break;
666      case GL_POST_COLOR_MATRIX_COLOR_TABLE:
667         table = &ctx->PostColorMatrixColorTable;
668         break;
669      default:
670         _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
671         return;
672   }
673
674   assert(table);
675
676   switch (table->Format) {
677      case GL_ALPHA:
678         if (table->FloatTable) {
679            const GLfloat *tableF = (const GLfloat *) table->Table;
680            GLuint i;
681            for (i = 0; i < table->Size; i++) {
682               rgba[i][RCOMP] = 0;
683               rgba[i][GCOMP] = 0;
684               rgba[i][BCOMP] = 0;
685               rgba[i][ACOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
686            }
687         }
688         else {
689            const GLchan *tableUB = (const GLchan *) table->Table;
690            GLuint i;
691            for (i = 0; i < table->Size; i++) {
692               rgba[i][RCOMP] = 0;
693               rgba[i][GCOMP] = 0;
694               rgba[i][BCOMP] = 0;
695               rgba[i][ACOMP] = tableUB[i];
696            }
697         }
698         break;
699      case GL_LUMINANCE:
700         if (table->FloatTable) {
701            const GLfloat *tableF = (const GLfloat *) table->Table;
702            GLuint i;
703            for (i = 0; i < table->Size; i++) {
704               rgba[i][RCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
705               rgba[i][GCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
706               rgba[i][BCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
707               rgba[i][ACOMP] = CHAN_MAX;
708            }
709         }
710         else {
711            const GLchan *tableUB = (const GLchan *) table->Table;
712            GLuint i;
713            for (i = 0; i < table->Size; i++) {
714               rgba[i][RCOMP] = tableUB[i];
715               rgba[i][GCOMP] = tableUB[i];
716               rgba[i][BCOMP] = tableUB[i];
717               rgba[i][ACOMP] = CHAN_MAX;
718            }
719         }
720         break;
721      case GL_LUMINANCE_ALPHA:
722         if (table->FloatTable) {
723            const GLfloat *tableF = (const GLfloat *) table->Table;
724            GLuint i;
725            for (i = 0; i < table->Size; i++) {
726               rgba[i][RCOMP] = IROUND_POS(tableF[i*2+0] * CHAN_MAXF);
727               rgba[i][GCOMP] = IROUND_POS(tableF[i*2+0] * CHAN_MAXF);
728               rgba[i][BCOMP] = IROUND_POS(tableF[i*2+0] * CHAN_MAXF);
729               rgba[i][ACOMP] = IROUND_POS(tableF[i*2+1] * CHAN_MAXF);
730            }
731         }
732         else {
733            const GLchan *tableUB = (const GLchan *) table->Table;
734            GLuint i;
735            for (i = 0; i < table->Size; i++) {
736               rgba[i][RCOMP] = tableUB[i*2+0];
737               rgba[i][GCOMP] = tableUB[i*2+0];
738               rgba[i][BCOMP] = tableUB[i*2+0];
739               rgba[i][ACOMP] = tableUB[i*2+1];
740            }
741         }
742         break;
743      case GL_INTENSITY:
744         if (table->FloatTable) {
745            const GLfloat *tableF = (const GLfloat *) table->Table;
746            GLuint i;
747            for (i = 0; i < table->Size; i++) {
748               rgba[i][RCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
749               rgba[i][GCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
750               rgba[i][BCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
751               rgba[i][ACOMP] = IROUND_POS(tableF[i] * CHAN_MAXF);
752            }
753         }
754         else {
755            const GLchan *tableUB = (const GLchan *) table->Table;
756            GLuint i;
757            for (i = 0; i < table->Size; i++) {
758               rgba[i][RCOMP] = tableUB[i];
759               rgba[i][GCOMP] = tableUB[i];
760               rgba[i][BCOMP] = tableUB[i];
761               rgba[i][ACOMP] = tableUB[i];
762            }
763         }
764         break;
765      case GL_RGB:
766         if (table->FloatTable) {
767            const GLfloat *tableF = (const GLfloat *) table->Table;
768            GLuint i;
769            for (i = 0; i < table->Size; i++) {
770               rgba[i][RCOMP] = IROUND_POS(tableF[i*3+0] * CHAN_MAXF);
771               rgba[i][GCOMP] = IROUND_POS(tableF[i*3+1] * CHAN_MAXF);
772               rgba[i][BCOMP] = IROUND_POS(tableF[i*3+2] * CHAN_MAXF);
773               rgba[i][ACOMP] = CHAN_MAX;
774            }
775         }
776         else {
777            const GLchan *tableUB = (const GLchan *) table->Table;
778            GLuint i;
779            for (i = 0; i < table->Size; i++) {
780               rgba[i][RCOMP] = tableUB[i*3+0];
781               rgba[i][GCOMP] = tableUB[i*3+1];
782               rgba[i][BCOMP] = tableUB[i*3+2];
783               rgba[i][ACOMP] = CHAN_MAX;
784            }
785         }
786         break;
787      case GL_RGBA:
788         if (table->FloatTable) {
789            const GLfloat *tableF = (const GLfloat *) table->Table;
790            GLuint i;
791            for (i = 0; i < table->Size; i++) {
792               rgba[i][RCOMP] = IROUND_POS(tableF[i*4+0] * CHAN_MAXF);
793               rgba[i][GCOMP] = IROUND_POS(tableF[i*4+1] * CHAN_MAXF);
794               rgba[i][BCOMP] = IROUND_POS(tableF[i*4+2] * CHAN_MAXF);
795               rgba[i][ACOMP] = IROUND_POS(tableF[i*4+3] * CHAN_MAXF);
796            }
797         }
798         else {
799            const GLchan *tableUB = (const GLchan *) table->Table;
800            GLuint i;
801            for (i = 0; i < table->Size; i++) {
802               rgba[i][RCOMP] = tableUB[i*4+0];
803               rgba[i][GCOMP] = tableUB[i*4+1];
804               rgba[i][BCOMP] = tableUB[i*4+2];
805               rgba[i][ACOMP] = tableUB[i*4+3];
806            }
807         }
808         break;
809      default:
810         _mesa_problem(ctx, "bad table format in glGetColorTable");
811         return;
812   }
813
814   _mesa_pack_rgba_span(ctx, table->Size, (const GLchan (*)[4]) rgba,
815                        format, type, data, &ctx->Pack, GL_FALSE);
816}
817
818
819
820void
821_mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params)
822{
823   GET_CURRENT_CONTEXT(ctx);
824   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
825
826   switch (target) {
827      case GL_COLOR_TABLE_SGI:
828         if (pname == GL_COLOR_TABLE_SCALE_SGI) {
829            ctx->Pixel.ColorTableScale[0] = params[0];
830            ctx->Pixel.ColorTableScale[1] = params[1];
831            ctx->Pixel.ColorTableScale[2] = params[2];
832            ctx->Pixel.ColorTableScale[3] = params[3];
833         }
834         else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
835            ctx->Pixel.ColorTableBias[0] = params[0];
836            ctx->Pixel.ColorTableBias[1] = params[1];
837            ctx->Pixel.ColorTableBias[2] = params[2];
838            ctx->Pixel.ColorTableBias[3] = params[3];
839         }
840         else {
841            _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)");
842            return;
843         }
844         break;
845      case GL_POST_CONVOLUTION_COLOR_TABLE_SGI:
846         if (pname == GL_COLOR_TABLE_SCALE_SGI) {
847            ctx->Pixel.PCCTscale[0] = params[0];
848            ctx->Pixel.PCCTscale[1] = params[1];
849            ctx->Pixel.PCCTscale[2] = params[2];
850            ctx->Pixel.PCCTscale[3] = params[3];
851         }
852         else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
853            ctx->Pixel.PCCTbias[0] = params[0];
854            ctx->Pixel.PCCTbias[1] = params[1];
855            ctx->Pixel.PCCTbias[2] = params[2];
856            ctx->Pixel.PCCTbias[3] = params[3];
857         }
858         else {
859            _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)");
860            return;
861         }
862         break;
863      case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI:
864         if (pname == GL_COLOR_TABLE_SCALE_SGI) {
865            ctx->Pixel.PCMCTscale[0] = params[0];
866            ctx->Pixel.PCMCTscale[1] = params[1];
867            ctx->Pixel.PCMCTscale[2] = params[2];
868            ctx->Pixel.PCMCTscale[3] = params[3];
869         }
870         else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
871            ctx->Pixel.PCMCTbias[0] = params[0];
872            ctx->Pixel.PCMCTbias[1] = params[1];
873            ctx->Pixel.PCMCTbias[2] = params[2];
874            ctx->Pixel.PCMCTbias[3] = params[3];
875         }
876         else {
877            _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)");
878            return;
879         }
880         break;
881      default:
882         _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)");
883         return;
884   }
885
886   ctx->NewState |= _NEW_PIXEL;
887}
888
889
890
891void
892_mesa_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params)
893{
894   GLfloat fparams[4];
895   if (pname == GL_COLOR_TABLE_SGI ||
896       pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI ||
897       pname == GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI) {
898      /* four values */
899      fparams[0] = (GLfloat) params[0];
900      fparams[1] = (GLfloat) params[1];
901      fparams[2] = (GLfloat) params[2];
902      fparams[3] = (GLfloat) params[3];
903   }
904   else {
905      /* one values */
906      fparams[0] = (GLfloat) params[0];
907   }
908   _mesa_ColorTableParameterfv(target, pname, fparams);
909}
910
911
912
913void
914_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params )
915{
916   GET_CURRENT_CONTEXT(ctx);
917   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
918   struct gl_color_table *table = NULL;
919   ASSERT_OUTSIDE_BEGIN_END(ctx);
920
921   switch (target) {
922      case GL_TEXTURE_1D:
923         table = &texUnit->Current1D->Palette;
924         break;
925      case GL_TEXTURE_2D:
926         table = &texUnit->Current2D->Palette;
927         break;
928      case GL_TEXTURE_3D:
929         table = &texUnit->Current3D->Palette;
930         break;
931      case GL_PROXY_TEXTURE_1D:
932         table = &ctx->Texture.Proxy1D->Palette;
933         break;
934      case GL_PROXY_TEXTURE_2D:
935         table = &ctx->Texture.Proxy2D->Palette;
936         break;
937      case GL_PROXY_TEXTURE_3D:
938         table = &ctx->Texture.Proxy3D->Palette;
939         break;
940      case GL_SHARED_TEXTURE_PALETTE_EXT:
941         table = &ctx->Texture.Palette;
942         break;
943      case GL_COLOR_TABLE:
944         table = &ctx->ColorTable;
945         if (pname == GL_COLOR_TABLE_SCALE_SGI) {
946            params[0] = ctx->Pixel.ColorTableScale[0];
947            params[1] = ctx->Pixel.ColorTableScale[1];
948            params[2] = ctx->Pixel.ColorTableScale[2];
949            params[3] = ctx->Pixel.ColorTableScale[3];
950            return;
951         }
952         else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
953            params[0] = ctx->Pixel.ColorTableBias[0];
954            params[1] = ctx->Pixel.ColorTableBias[1];
955            params[2] = ctx->Pixel.ColorTableBias[2];
956            params[3] = ctx->Pixel.ColorTableBias[3];
957            return;
958         }
959         break;
960      case GL_PROXY_COLOR_TABLE:
961         table = &ctx->ProxyColorTable;
962         break;
963      case GL_POST_CONVOLUTION_COLOR_TABLE:
964         table = &ctx->PostConvolutionColorTable;
965         if (pname == GL_COLOR_TABLE_SCALE_SGI) {
966            params[0] = ctx->Pixel.PCCTscale[0];
967            params[1] = ctx->Pixel.PCCTscale[1];
968            params[2] = ctx->Pixel.PCCTscale[2];
969            params[3] = ctx->Pixel.PCCTscale[3];
970            return;
971         }
972         else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
973            params[0] = ctx->Pixel.PCCTbias[0];
974            params[1] = ctx->Pixel.PCCTbias[1];
975            params[2] = ctx->Pixel.PCCTbias[2];
976            params[3] = ctx->Pixel.PCCTbias[3];
977            return;
978         }
979         break;
980      case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
981         table = &ctx->ProxyPostConvolutionColorTable;
982         break;
983      case GL_POST_COLOR_MATRIX_COLOR_TABLE:
984         table = &ctx->PostColorMatrixColorTable;
985         if (pname == GL_COLOR_TABLE_SCALE_SGI) {
986            params[0] = ctx->Pixel.PCMCTscale[0];
987            params[1] = ctx->Pixel.PCMCTscale[1];
988            params[2] = ctx->Pixel.PCMCTscale[2];
989            params[3] = ctx->Pixel.PCMCTscale[3];
990            return;
991         }
992         else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
993            params[0] = ctx->Pixel.PCMCTbias[0];
994            params[1] = ctx->Pixel.PCMCTbias[1];
995            params[2] = ctx->Pixel.PCMCTbias[2];
996            params[3] = ctx->Pixel.PCMCTbias[3];
997            return;
998         }
999         break;
1000      case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
1001         table = &ctx->ProxyPostColorMatrixColorTable;
1002         break;
1003      default:
1004         _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(target)");
1005         return;
1006   }
1007
1008   assert(table);
1009
1010   switch (pname) {
1011      case GL_COLOR_TABLE_FORMAT:
1012         *params = (GLfloat) table->IntFormat;
1013         break;
1014      case GL_COLOR_TABLE_WIDTH:
1015         *params = (GLfloat) table->Size;
1016         break;
1017      case GL_COLOR_TABLE_RED_SIZE:
1018         *params = table->RedSize;
1019         break;
1020      case GL_COLOR_TABLE_GREEN_SIZE:
1021         *params = table->GreenSize;
1022         break;
1023      case GL_COLOR_TABLE_BLUE_SIZE:
1024         *params = table->BlueSize;
1025         break;
1026      case GL_COLOR_TABLE_ALPHA_SIZE:
1027         *params = table->AlphaSize;
1028         break;
1029      case GL_COLOR_TABLE_LUMINANCE_SIZE:
1030         *params = table->LuminanceSize;
1031         break;
1032      case GL_COLOR_TABLE_INTENSITY_SIZE:
1033         *params = table->IntensitySize;
1034         break;
1035      default:
1036         _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(pname)" );
1037         return;
1038   }
1039}
1040
1041
1042
1043void
1044_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params )
1045{
1046   GET_CURRENT_CONTEXT(ctx);
1047   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1048   struct gl_color_table *table = NULL;
1049   ASSERT_OUTSIDE_BEGIN_END(ctx);
1050
1051   switch (target) {
1052      case GL_TEXTURE_1D:
1053         table = &texUnit->Current1D->Palette;
1054         break;
1055      case GL_TEXTURE_2D:
1056         table = &texUnit->Current2D->Palette;
1057         break;
1058      case GL_TEXTURE_3D:
1059         table = &texUnit->Current3D->Palette;
1060         break;
1061      case GL_PROXY_TEXTURE_1D:
1062         table = &ctx->Texture.Proxy1D->Palette;
1063         break;
1064      case GL_PROXY_TEXTURE_2D:
1065         table = &ctx->Texture.Proxy2D->Palette;
1066         break;
1067      case GL_PROXY_TEXTURE_3D:
1068         table = &ctx->Texture.Proxy3D->Palette;
1069         break;
1070      case GL_SHARED_TEXTURE_PALETTE_EXT:
1071         table = &ctx->Texture.Palette;
1072         break;
1073      case GL_COLOR_TABLE:
1074         table = &ctx->ColorTable;
1075         if (pname == GL_COLOR_TABLE_SCALE_SGI) {
1076            params[0] = (GLint) ctx->Pixel.ColorTableScale[0];
1077            params[1] = (GLint) ctx->Pixel.ColorTableScale[1];
1078            params[2] = (GLint) ctx->Pixel.ColorTableScale[2];
1079            params[3] = (GLint) ctx->Pixel.ColorTableScale[3];
1080            return;
1081         }
1082         else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
1083            params[0] = (GLint) ctx->Pixel.ColorTableBias[0];
1084            params[1] = (GLint) ctx->Pixel.ColorTableBias[1];
1085            params[2] = (GLint) ctx->Pixel.ColorTableBias[2];
1086            params[3] = (GLint) ctx->Pixel.ColorTableBias[3];
1087            return;
1088         }
1089         break;
1090      case GL_PROXY_COLOR_TABLE:
1091         table = &ctx->ProxyColorTable;
1092         break;
1093      case GL_POST_CONVOLUTION_COLOR_TABLE:
1094         table = &ctx->PostConvolutionColorTable;
1095         if (pname == GL_COLOR_TABLE_SCALE_SGI) {
1096            params[0] = (GLint) ctx->Pixel.PCCTscale[0];
1097            params[1] = (GLint) ctx->Pixel.PCCTscale[1];
1098            params[2] = (GLint) ctx->Pixel.PCCTscale[2];
1099            params[3] = (GLint) ctx->Pixel.PCCTscale[3];
1100            return;
1101         }
1102         else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
1103            params[0] = (GLint) ctx->Pixel.PCCTbias[0];
1104            params[1] = (GLint) ctx->Pixel.PCCTbias[1];
1105            params[2] = (GLint) ctx->Pixel.PCCTbias[2];
1106            params[3] = (GLint) ctx->Pixel.PCCTbias[3];
1107            return;
1108         }
1109         break;
1110      case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
1111         table = &ctx->ProxyPostConvolutionColorTable;
1112         break;
1113      case GL_POST_COLOR_MATRIX_COLOR_TABLE:
1114         table = &ctx->PostColorMatrixColorTable;
1115         if (pname == GL_COLOR_TABLE_SCALE_SGI) {
1116            params[0] = (GLint) ctx->Pixel.PCMCTscale[0];
1117            params[1] = (GLint) ctx->Pixel.PCMCTscale[1];
1118            params[2] = (GLint) ctx->Pixel.PCMCTscale[2];
1119            params[3] = (GLint) ctx->Pixel.PCMCTscale[3];
1120            return;
1121         }
1122         else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
1123            params[0] = (GLint) ctx->Pixel.PCMCTbias[0];
1124            params[1] = (GLint) ctx->Pixel.PCMCTbias[1];
1125            params[2] = (GLint) ctx->Pixel.PCMCTbias[2];
1126            params[3] = (GLint) ctx->Pixel.PCMCTbias[3];
1127            return;
1128         }
1129         break;
1130      case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
1131         table = &ctx->ProxyPostColorMatrixColorTable;
1132         break;
1133      default:
1134         _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(target)");
1135         return;
1136   }
1137
1138   assert(table);
1139
1140   switch (pname) {
1141      case GL_COLOR_TABLE_FORMAT:
1142         *params = table->IntFormat;
1143         break;
1144      case GL_COLOR_TABLE_WIDTH:
1145         *params = table->Size;
1146         break;
1147      case GL_COLOR_TABLE_RED_SIZE:
1148         *params = table->RedSize;
1149         break;
1150      case GL_COLOR_TABLE_GREEN_SIZE:
1151         *params = table->GreenSize;
1152         break;
1153      case GL_COLOR_TABLE_BLUE_SIZE:
1154         *params = table->BlueSize;
1155         break;
1156      case GL_COLOR_TABLE_ALPHA_SIZE:
1157         *params = table->AlphaSize;
1158         break;
1159      case GL_COLOR_TABLE_LUMINANCE_SIZE:
1160         *params = table->LuminanceSize;
1161         break;
1162      case GL_COLOR_TABLE_INTENSITY_SIZE:
1163         *params = table->IntensitySize;
1164         break;
1165      default:
1166         _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(pname)" );
1167         return;
1168   }
1169}
1170