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