colortab.c revision 6c227e57e69158e4da40c69322db0eac4c31086c
1/*
2 * Mesa 3-D graphics library
3 * Version:  7.1
4 *
5 * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26#include "glheader.h"
27#include "bufferobj.h"
28#include "colortab.h"
29#include "context.h"
30#include "image.h"
31#include "macros.h"
32#include "state.h"
33#include "teximage.h"
34#include "texstate.h"
35#include "main/dispatch.h"
36
37
38#if FEATURE_colortable
39
40
41/**
42 * Given an internalFormat token passed to glColorTable,
43 * return the corresponding base format.
44 * Return -1 if invalid token.
45 */
46static GLint
47base_colortab_format( GLenum format )
48{
49   switch (format) {
50      case GL_ALPHA:
51      case GL_ALPHA4:
52      case GL_ALPHA8:
53      case GL_ALPHA12:
54      case GL_ALPHA16:
55         return GL_ALPHA;
56      case GL_LUMINANCE:
57      case GL_LUMINANCE4:
58      case GL_LUMINANCE8:
59      case GL_LUMINANCE12:
60      case GL_LUMINANCE16:
61         return GL_LUMINANCE;
62      case GL_LUMINANCE_ALPHA:
63      case GL_LUMINANCE4_ALPHA4:
64      case GL_LUMINANCE6_ALPHA2:
65      case GL_LUMINANCE8_ALPHA8:
66      case GL_LUMINANCE12_ALPHA4:
67      case GL_LUMINANCE12_ALPHA12:
68      case GL_LUMINANCE16_ALPHA16:
69         return GL_LUMINANCE_ALPHA;
70      case GL_INTENSITY:
71      case GL_INTENSITY4:
72      case GL_INTENSITY8:
73      case GL_INTENSITY12:
74      case GL_INTENSITY16:
75         return GL_INTENSITY;
76      case GL_RGB:
77      case GL_R3_G3_B2:
78      case GL_RGB4:
79      case GL_RGB5:
80      case GL_RGB8:
81      case GL_RGB10:
82      case GL_RGB12:
83      case GL_RGB16:
84         return GL_RGB;
85      case GL_RGBA:
86      case GL_RGBA2:
87      case GL_RGBA4:
88      case GL_RGB5_A1:
89      case GL_RGBA8:
90      case GL_RGB10_A2:
91      case GL_RGBA12:
92      case GL_RGBA16:
93         return GL_RGBA;
94      default:
95         return -1;  /* error */
96   }
97}
98
99
100
101/**
102 * Examine table's format and set the component sizes accordingly.
103 */
104static void
105set_component_sizes( struct gl_color_table *table )
106{
107   /* assuming the ubyte table */
108   const GLubyte sz = 8;
109
110   switch (table->_BaseFormat) {
111      case GL_ALPHA:
112         table->RedSize = 0;
113         table->GreenSize = 0;
114         table->BlueSize = 0;
115         table->AlphaSize = sz;
116         table->IntensitySize = 0;
117         table->LuminanceSize = 0;
118         break;
119      case GL_LUMINANCE:
120         table->RedSize = 0;
121         table->GreenSize = 0;
122         table->BlueSize = 0;
123         table->AlphaSize = 0;
124         table->IntensitySize = 0;
125         table->LuminanceSize = sz;
126         break;
127      case GL_LUMINANCE_ALPHA:
128         table->RedSize = 0;
129         table->GreenSize = 0;
130         table->BlueSize = 0;
131         table->AlphaSize = sz;
132         table->IntensitySize = 0;
133         table->LuminanceSize = sz;
134         break;
135      case GL_INTENSITY:
136         table->RedSize = 0;
137         table->GreenSize = 0;
138         table->BlueSize = 0;
139         table->AlphaSize = 0;
140         table->IntensitySize = sz;
141         table->LuminanceSize = 0;
142         break;
143      case GL_RGB:
144         table->RedSize = sz;
145         table->GreenSize = sz;
146         table->BlueSize = sz;
147         table->AlphaSize = 0;
148         table->IntensitySize = 0;
149         table->LuminanceSize = 0;
150         break;
151      case GL_RGBA:
152         table->RedSize = sz;
153         table->GreenSize = sz;
154         table->BlueSize = sz;
155         table->AlphaSize = sz;
156         table->IntensitySize = 0;
157         table->LuminanceSize = 0;
158         break;
159      default:
160         _mesa_problem(NULL, "unexpected format in set_component_sizes");
161   }
162}
163
164
165
166/**
167 * Update/replace all or part of a color table.  Helper function
168 * used by _mesa_ColorTable() and _mesa_ColorSubTable().
169 * The table->Table buffer should already be allocated.
170 * \param start first entry to update
171 * \param count number of entries to update
172 * \param format format of user-provided table data
173 * \param type datatype of user-provided table data
174 * \param data user-provided table data
175 * \param [rgba]Scale - RGBA scale factors
176 * \param [rgba]Bias - RGBA bias factors
177 */
178static void
179store_colortable_entries(GLcontext *ctx, struct gl_color_table *table,
180			 GLsizei start, GLsizei count,
181			 GLenum format, GLenum type, const GLvoid *data,
182			 GLfloat rScale, GLfloat rBias,
183			 GLfloat gScale, GLfloat gBias,
184			 GLfloat bScale, GLfloat bBias,
185			 GLfloat aScale, GLfloat aBias)
186{
187   data = _mesa_map_validate_pbo_source(ctx,
188                                        1, &ctx->Unpack, count, 1, 1,
189                                        format, type, data,
190                                        "glColor[Sub]Table");
191   if (!data)
192      return;
193
194   {
195      /* convert user-provided data to GLfloat values */
196      GLfloat tempTab[MAX_COLOR_TABLE_SIZE * 4];
197      GLfloat *tableF;
198      GLint i;
199
200      _mesa_unpack_color_span_float(ctx,
201                                    count,         /* number of pixels */
202                                    table->_BaseFormat, /* dest format */
203                                    tempTab,       /* dest address */
204                                    format, type,  /* src format/type */
205                                    data,          /* src data */
206                                    &ctx->Unpack,
207                                    IMAGE_CLAMP_BIT); /* transfer ops */
208
209      /* the destination */
210      tableF = table->TableF;
211
212      /* Apply scale & bias & clamp now */
213      switch (table->_BaseFormat) {
214         case GL_INTENSITY:
215            for (i = 0; i < count; i++) {
216               GLuint j = start + i;
217               tableF[j] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F);
218            }
219            break;
220         case GL_LUMINANCE:
221            for (i = 0; i < count; i++) {
222               GLuint j = start + i;
223               tableF[j] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F);
224            }
225            break;
226         case GL_ALPHA:
227            for (i = 0; i < count; i++) {
228               GLuint j = start + i;
229               tableF[j] = CLAMP(tempTab[i] * aScale + aBias, 0.0F, 1.0F);
230            }
231            break;
232         case GL_LUMINANCE_ALPHA:
233            for (i = 0; i < count; i++) {
234               GLuint j = start + i;
235               tableF[j*2+0] = CLAMP(tempTab[i*2+0] * rScale + rBias, 0.0F, 1.0F);
236               tableF[j*2+1] = CLAMP(tempTab[i*2+1] * aScale + aBias, 0.0F, 1.0F);
237            }
238            break;
239         case GL_RGB:
240            for (i = 0; i < count; i++) {
241               GLuint j = start + i;
242               tableF[j*3+0] = CLAMP(tempTab[i*3+0] * rScale + rBias, 0.0F, 1.0F);
243               tableF[j*3+1] = CLAMP(tempTab[i*3+1] * gScale + gBias, 0.0F, 1.0F);
244               tableF[j*3+2] = CLAMP(tempTab[i*3+2] * bScale + bBias, 0.0F, 1.0F);
245            }
246            break;
247         case GL_RGBA:
248            for (i = 0; i < count; i++) {
249               GLuint j = start + i;
250               tableF[j*4+0] = CLAMP(tempTab[i*4+0] * rScale + rBias, 0.0F, 1.0F);
251               tableF[j*4+1] = CLAMP(tempTab[i*4+1] * gScale + gBias, 0.0F, 1.0F);
252               tableF[j*4+2] = CLAMP(tempTab[i*4+2] * bScale + bBias, 0.0F, 1.0F);
253               tableF[j*4+3] = CLAMP(tempTab[i*4+3] * aScale + aBias, 0.0F, 1.0F);
254            }
255            break;
256         default:
257            _mesa_problem(ctx, "Bad format in store_colortable_entries");
258            return;
259         }
260   }
261
262   /* update the ubyte table */
263   {
264      const GLint comps = _mesa_components_in_format(table->_BaseFormat);
265      const GLfloat *tableF = table->TableF + start * comps;
266      GLubyte *tableUB = table->TableUB + start * comps;
267      GLint i;
268      for (i = 0; i < count * comps; i++) {
269         CLAMPED_FLOAT_TO_UBYTE(tableUB[i], tableF[i]);
270      }
271   }
272
273   _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
274}
275
276
277
278void GLAPIENTRY
279_mesa_ColorTable( GLenum target, GLenum internalFormat,
280                  GLsizei width, GLenum format, GLenum type,
281                  const GLvoid *data )
282{
283   static const GLfloat one[4] = { 1.0, 1.0, 1.0, 1.0 };
284   static const GLfloat zero[4] = { 0.0, 0.0, 0.0, 0.0 };
285   GET_CURRENT_CONTEXT(ctx);
286   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
287   struct gl_texture_object *texObj = NULL;
288   struct gl_color_table *table = NULL;
289   GLboolean proxy = GL_FALSE;
290   GLint baseFormat;
291   const GLfloat *scale = one, *bias = zero;
292   GLint comps;
293
294   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */
295
296   switch (target) {
297      case GL_SHARED_TEXTURE_PALETTE_EXT:
298         table = &ctx->Texture.Palette;
299         break;
300      case GL_TEXTURE_COLOR_TABLE_SGI:
301         if (!ctx->Extensions.SGI_texture_color_table) {
302            _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
303            return;
304         }
305         table = &(texUnit->ColorTable);
306         scale = ctx->Pixel.TextureColorTableScale;
307         bias = ctx->Pixel.TextureColorTableBias;
308         break;
309      case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
310         if (!ctx->Extensions.SGI_texture_color_table) {
311            _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
312            return;
313         }
314         table = &(texUnit->ProxyColorTable);
315         proxy = GL_TRUE;
316         break;
317      default:
318         /* try texture targets */
319         {
320            struct gl_texture_object *texobj
321               = _mesa_select_tex_object(ctx, texUnit, target);
322            if (texobj) {
323               table = &texobj->Palette;
324               proxy = _mesa_is_proxy_texture(target);
325            }
326            else {
327               _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
328               return;
329            }
330         }
331   }
332
333   assert(table);
334
335   if (!_mesa_is_legal_format_and_type(ctx, format, type) ||
336       format == GL_INTENSITY) {
337      _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTable(format or type)");
338      return;
339   }
340
341   baseFormat = base_colortab_format(internalFormat);
342   if (baseFormat < 0) {
343      _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(internalFormat)");
344      return;
345   }
346
347   if (width < 0 || (width != 0 && !_mesa_is_pow_two(width))) {
348      /* error */
349      if (proxy) {
350         table->Size = 0;
351         table->InternalFormat = (GLenum) 0;
352         table->_BaseFormat = (GLenum) 0;
353      }
354      else {
355         _mesa_error(ctx, GL_INVALID_VALUE, "glColorTable(width=%d)", width);
356      }
357      return;
358   }
359
360   if (width > (GLsizei) ctx->Const.MaxColorTableSize) {
361      if (proxy) {
362         table->Size = 0;
363         table->InternalFormat = (GLenum) 0;
364         table->_BaseFormat = (GLenum) 0;
365      }
366      else {
367         _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glColorTable(width)");
368      }
369      return;
370   }
371
372   table->Size = width;
373   table->InternalFormat = internalFormat;
374   table->_BaseFormat = (GLenum) baseFormat;
375
376   comps = _mesa_components_in_format(table->_BaseFormat);
377   assert(comps > 0);  /* error should have been caught sooner */
378
379   if (!proxy) {
380      _mesa_free_colortable_data(table);
381
382      if (width > 0) {
383         table->TableF = (GLfloat *) malloc(comps * width * sizeof(GLfloat));
384         table->TableUB = (GLubyte *) malloc(comps * width * sizeof(GLubyte));
385
386	 if (!table->TableF || !table->TableUB) {
387	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable");
388	    return;
389	 }
390
391	 store_colortable_entries(ctx, table,
392				  0, width,  /* start, count */
393				  format, type, data,
394				  scale[0], bias[0],
395				  scale[1], bias[1],
396				  scale[2], bias[2],
397				  scale[3], bias[3]);
398      }
399   } /* proxy */
400
401   /* do this after the table's Type and Format are set */
402   set_component_sizes(table);
403
404   if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) {
405      /* texture object palette, texObj==NULL means the shared palette */
406      if (ctx->Driver.UpdateTexturePalette) {
407         (*ctx->Driver.UpdateTexturePalette)( ctx, texObj );
408      }
409   }
410
411   ctx->NewState |= _NEW_PIXEL;
412}
413
414
415
416void GLAPIENTRY
417_mesa_ColorSubTable( GLenum target, GLsizei start,
418                     GLsizei count, GLenum format, GLenum type,
419                     const GLvoid *data )
420{
421   static const GLfloat one[4] = { 1.0, 1.0, 1.0, 1.0 };
422   static const GLfloat zero[4] = { 0.0, 0.0, 0.0, 0.0 };
423   GET_CURRENT_CONTEXT(ctx);
424   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
425   struct gl_texture_object *texObj = NULL;
426   struct gl_color_table *table = NULL;
427   const GLfloat *scale = one, *bias = zero;
428
429   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
430
431   switch (target) {
432      case GL_SHARED_TEXTURE_PALETTE_EXT:
433         table = &ctx->Texture.Palette;
434         break;
435      case GL_TEXTURE_COLOR_TABLE_SGI:
436         if (!ctx->Extensions.SGI_texture_color_table) {
437            _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
438            return;
439         }
440         table = &(texUnit->ColorTable);
441         scale = ctx->Pixel.TextureColorTableScale;
442         bias = ctx->Pixel.TextureColorTableBias;
443         break;
444      default:
445         /* try texture targets */
446         texObj = _mesa_select_tex_object(ctx, texUnit, target);
447         if (texObj && !_mesa_is_proxy_texture(target)) {
448            table = &texObj->Palette;
449         }
450         else {
451            _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
452            return;
453         }
454   }
455
456   assert(table);
457
458   if (!_mesa_is_legal_format_and_type(ctx, format, type) ||
459       format == GL_INTENSITY) {
460      _mesa_error(ctx, GL_INVALID_OPERATION, "glColorSubTable(format or type)");
461      return;
462   }
463
464   if (count < 1) {
465      _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)");
466      return;
467   }
468
469   /* error should have been caught sooner */
470   assert(_mesa_components_in_format(table->_BaseFormat) > 0);
471
472   if (start + count > (GLint) table->Size) {
473      _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)");
474      return;
475   }
476
477   if (!table->TableF || !table->TableUB) {
478      /* a GL_OUT_OF_MEMORY error would have been recorded previously */
479      return;
480   }
481
482   store_colortable_entries(ctx, table, start, count,
483			    format, type, data,
484                            scale[0], bias[0],
485                            scale[1], bias[1],
486                            scale[2], bias[2],
487                            scale[3], bias[3]);
488
489   if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) {
490      /* per-texture object palette */
491      if (ctx->Driver.UpdateTexturePalette) {
492         (*ctx->Driver.UpdateTexturePalette)( ctx, texObj );
493      }
494   }
495
496   ctx->NewState |= _NEW_PIXEL;
497}
498
499
500
501static void GLAPIENTRY
502_mesa_CopyColorTable(GLenum target, GLenum internalformat,
503                     GLint x, GLint y, GLsizei width)
504{
505   GET_CURRENT_CONTEXT(ctx);
506   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
507
508   if (!ctx->ReadBuffer->_ColorReadBuffer) {
509      return;      /* no readbuffer - OK */
510   }
511
512   ctx->Driver.CopyColorTable( ctx, target, internalformat, x, y, width );
513}
514
515
516
517static void GLAPIENTRY
518_mesa_CopyColorSubTable(GLenum target, GLsizei start,
519                        GLint x, GLint y, GLsizei width)
520{
521   GET_CURRENT_CONTEXT(ctx);
522   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
523
524   if (!ctx->ReadBuffer->_ColorReadBuffer) {
525      return;      /* no readbuffer - OK */
526   }
527
528   ctx->Driver.CopyColorSubTable( ctx, target, start, x, y, width );
529}
530
531
532
533static void GLAPIENTRY
534_mesa_GetColorTable( GLenum target, GLenum format,
535                     GLenum type, GLvoid *data )
536{
537   GET_CURRENT_CONTEXT(ctx);
538   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
539   struct gl_color_table *table = NULL;
540   GLfloat rgba[MAX_COLOR_TABLE_SIZE][4];
541   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
542
543   if (ctx->NewState) {
544      _mesa_update_state(ctx);
545   }
546
547   switch (target) {
548      case GL_SHARED_TEXTURE_PALETTE_EXT:
549         table = &ctx->Texture.Palette;
550         break;
551      case GL_TEXTURE_COLOR_TABLE_SGI:
552         if (!ctx->Extensions.SGI_texture_color_table) {
553            _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
554            return;
555         }
556         table = &(texUnit->ColorTable);
557         break;
558      default:
559         /* try texture targets */
560         {
561            struct gl_texture_object *texobj
562               = _mesa_select_tex_object(ctx, texUnit, target);
563            if (texobj && !_mesa_is_proxy_texture(target)) {
564               table = &texobj->Palette;
565            }
566            else {
567               _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
568               return;
569            }
570         }
571   }
572
573   ASSERT(table);
574
575   if (table->Size <= 0) {
576      return;
577   }
578
579   switch (table->_BaseFormat) {
580   case GL_ALPHA:
581      {
582         GLuint i;
583         for (i = 0; i < table->Size; i++) {
584            rgba[i][RCOMP] = 0;
585            rgba[i][GCOMP] = 0;
586            rgba[i][BCOMP] = 0;
587            rgba[i][ACOMP] = table->TableF[i];
588         }
589      }
590      break;
591   case GL_LUMINANCE:
592      {
593         GLuint i;
594         for (i = 0; i < table->Size; i++) {
595            rgba[i][RCOMP] =
596            rgba[i][GCOMP] =
597            rgba[i][BCOMP] = table->TableF[i];
598            rgba[i][ACOMP] = 1.0F;
599         }
600      }
601      break;
602   case GL_LUMINANCE_ALPHA:
603      {
604         GLuint i;
605         for (i = 0; i < table->Size; i++) {
606            rgba[i][RCOMP] =
607            rgba[i][GCOMP] =
608            rgba[i][BCOMP] = table->TableF[i*2+0];
609            rgba[i][ACOMP] = table->TableF[i*2+1];
610         }
611      }
612      break;
613   case GL_INTENSITY:
614      {
615         GLuint i;
616         for (i = 0; i < table->Size; i++) {
617            rgba[i][RCOMP] =
618            rgba[i][GCOMP] =
619            rgba[i][BCOMP] =
620            rgba[i][ACOMP] = table->TableF[i];
621         }
622      }
623      break;
624   case GL_RGB:
625      {
626         GLuint i;
627         for (i = 0; i < table->Size; i++) {
628            rgba[i][RCOMP] = table->TableF[i*3+0];
629            rgba[i][GCOMP] = table->TableF[i*3+1];
630            rgba[i][BCOMP] = table->TableF[i*3+2];
631            rgba[i][ACOMP] = 1.0F;
632         }
633      }
634      break;
635   case GL_RGBA:
636      memcpy(rgba, table->TableF, 4 * table->Size * sizeof(GLfloat));
637      break;
638   default:
639      _mesa_problem(ctx, "bad table format in glGetColorTable");
640      return;
641   }
642
643   data = _mesa_map_validate_pbo_dest(ctx,
644                                      1, &ctx->Pack, table->Size, 1, 1,
645                                      format, type, data,
646                                      "glGetColorTable");
647   if (!data)
648      return;
649
650   _mesa_pack_rgba_span_float(ctx, table->Size, rgba,
651                              format, type, data, &ctx->Pack, 0x0);
652
653   _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
654}
655
656
657
658static void GLAPIENTRY
659_mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params)
660{
661   GLfloat *scale, *bias;
662   GET_CURRENT_CONTEXT(ctx);
663   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
664
665   switch (target) {
666   case GL_TEXTURE_COLOR_TABLE_SGI:
667      scale = ctx->Pixel.TextureColorTableScale;
668      bias  = ctx->Pixel.TextureColorTableBias;
669      break;
670   default:
671      _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)");
672      return;
673   }
674
675   if (pname == GL_COLOR_TABLE_SCALE_SGI) {
676      COPY_4V(scale, params);
677   }
678   else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
679      COPY_4V(bias, params);
680   }
681   else {
682      _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)");
683      return;
684   }
685
686   ctx->NewState |= _NEW_PIXEL;
687}
688
689
690
691static void GLAPIENTRY
692_mesa_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params)
693{
694   GLfloat fparams[4];
695   if (pname == GL_TEXTURE_COLOR_TABLE_SGI) {
696      /* four values */
697      fparams[0] = (GLfloat) params[0];
698      fparams[1] = (GLfloat) params[1];
699      fparams[2] = (GLfloat) params[2];
700      fparams[3] = (GLfloat) params[3];
701   }
702   else {
703      /* one values */
704      fparams[0] = (GLfloat) params[0];
705   }
706   _mesa_ColorTableParameterfv(target, pname, fparams);
707}
708
709
710
711static void GLAPIENTRY
712_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params )
713{
714   GET_CURRENT_CONTEXT(ctx);
715   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
716   struct gl_color_table *table = NULL;
717   ASSERT_OUTSIDE_BEGIN_END(ctx);
718
719   switch (target) {
720      case GL_SHARED_TEXTURE_PALETTE_EXT:
721         table = &ctx->Texture.Palette;
722         break;
723      case GL_TEXTURE_COLOR_TABLE_SGI:
724         if (!ctx->Extensions.SGI_texture_color_table) {
725            _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)");
726            return;
727         }
728         table = &(texUnit->ColorTable);
729         if (pname == GL_COLOR_TABLE_SCALE_SGI) {
730            COPY_4V(params, ctx->Pixel.TextureColorTableScale);
731            return;
732         }
733         else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
734            COPY_4V(params, ctx->Pixel.TextureColorTableBias);
735            return;
736         }
737         break;
738      case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
739         if (!ctx->Extensions.SGI_texture_color_table) {
740            _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)");
741            return;
742         }
743         table = &(texUnit->ProxyColorTable);
744         break;
745      default:
746         /* try texture targets */
747         {
748            struct gl_texture_object *texobj
749               = _mesa_select_tex_object(ctx, texUnit, target);
750            if (texobj) {
751               table = &texobj->Palette;
752            }
753            else {
754               _mesa_error(ctx, GL_INVALID_ENUM,
755                           "glGetColorTableParameterfv(target)");
756               return;
757            }
758         }
759   }
760
761   assert(table);
762
763   switch (pname) {
764      case GL_COLOR_TABLE_FORMAT:
765         *params = (GLfloat) table->InternalFormat;
766         break;
767      case GL_COLOR_TABLE_WIDTH:
768         *params = (GLfloat) table->Size;
769         break;
770      case GL_COLOR_TABLE_RED_SIZE:
771         *params = (GLfloat) table->RedSize;
772         break;
773      case GL_COLOR_TABLE_GREEN_SIZE:
774         *params = (GLfloat) table->GreenSize;
775         break;
776      case GL_COLOR_TABLE_BLUE_SIZE:
777         *params = (GLfloat) table->BlueSize;
778         break;
779      case GL_COLOR_TABLE_ALPHA_SIZE:
780         *params = (GLfloat) table->AlphaSize;
781         break;
782      case GL_COLOR_TABLE_LUMINANCE_SIZE:
783         *params = (GLfloat) table->LuminanceSize;
784         break;
785      case GL_COLOR_TABLE_INTENSITY_SIZE:
786         *params = (GLfloat) table->IntensitySize;
787         break;
788      default:
789         _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(pname)" );
790         return;
791   }
792}
793
794
795
796static void GLAPIENTRY
797_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params )
798{
799   GET_CURRENT_CONTEXT(ctx);
800   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
801   struct gl_color_table *table = NULL;
802   ASSERT_OUTSIDE_BEGIN_END(ctx);
803
804   switch (target) {
805      case GL_SHARED_TEXTURE_PALETTE_EXT:
806         table = &ctx->Texture.Palette;
807         break;
808      case GL_TEXTURE_COLOR_TABLE_SGI:
809         if (!ctx->Extensions.SGI_texture_color_table) {
810            _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)");
811            return;
812         }
813         table = &(texUnit->ColorTable);
814         if (pname == GL_COLOR_TABLE_SCALE_SGI) {
815            params[0] = (GLint) ctx->Pixel.TextureColorTableScale[0];
816            params[1] = (GLint) ctx->Pixel.TextureColorTableScale[1];
817            params[2] = (GLint) ctx->Pixel.TextureColorTableScale[2];
818            params[3] = (GLint) ctx->Pixel.TextureColorTableScale[3];
819            return;
820         }
821         else if (pname == GL_COLOR_TABLE_BIAS_SGI) {
822            params[0] = (GLint) ctx->Pixel.TextureColorTableBias[0];
823            params[1] = (GLint) ctx->Pixel.TextureColorTableBias[1];
824            params[2] = (GLint) ctx->Pixel.TextureColorTableBias[2];
825            params[3] = (GLint) ctx->Pixel.TextureColorTableBias[3];
826            return;
827         }
828         break;
829      case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
830         if (!ctx->Extensions.SGI_texture_color_table) {
831            _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)");
832            return;
833         }
834         table = &(texUnit->ProxyColorTable);
835         break;
836      default:
837         /* Try texture targets */
838         {
839            struct gl_texture_object *texobj
840               = _mesa_select_tex_object(ctx, texUnit, target);
841            if (texobj) {
842               table = &texobj->Palette;
843            }
844            else {
845               _mesa_error(ctx, GL_INVALID_ENUM,
846                           "glGetColorTableParameteriv(target)");
847               return;
848            }
849         }
850   }
851
852   assert(table);
853
854   switch (pname) {
855      case GL_COLOR_TABLE_FORMAT:
856         *params = table->InternalFormat;
857         break;
858      case GL_COLOR_TABLE_WIDTH:
859         *params = table->Size;
860         break;
861      case GL_COLOR_TABLE_RED_SIZE:
862         *params = table->RedSize;
863         break;
864      case GL_COLOR_TABLE_GREEN_SIZE:
865         *params = table->GreenSize;
866         break;
867      case GL_COLOR_TABLE_BLUE_SIZE:
868         *params = table->BlueSize;
869         break;
870      case GL_COLOR_TABLE_ALPHA_SIZE:
871         *params = table->AlphaSize;
872         break;
873      case GL_COLOR_TABLE_LUMINANCE_SIZE:
874         *params = table->LuminanceSize;
875         break;
876      case GL_COLOR_TABLE_INTENSITY_SIZE:
877         *params = table->IntensitySize;
878         break;
879      default:
880         _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(pname)" );
881         return;
882   }
883}
884
885
886void
887_mesa_init_colortable_dispatch(struct _glapi_table *disp)
888{
889   SET_ColorSubTable(disp, _mesa_ColorSubTable);
890   SET_ColorTable(disp, _mesa_ColorTable);
891   SET_ColorTableParameterfv(disp, _mesa_ColorTableParameterfv);
892   SET_ColorTableParameteriv(disp, _mesa_ColorTableParameteriv);
893   SET_CopyColorSubTable(disp, _mesa_CopyColorSubTable);
894   SET_CopyColorTable(disp, _mesa_CopyColorTable);
895   SET_GetColorTable(disp, _mesa_GetColorTable);
896   SET_GetColorTableParameterfv(disp, _mesa_GetColorTableParameterfv);
897   SET_GetColorTableParameteriv(disp, _mesa_GetColorTableParameteriv);
898}
899
900
901#endif /* FEATURE_colortable */
902
903
904/**********************************************************************/
905/*****                      Initialization                        *****/
906/**********************************************************************/
907
908
909void
910_mesa_init_colortable( struct gl_color_table *p )
911{
912   p->TableF = NULL;
913   p->TableUB = NULL;
914   p->Size = 0;
915   p->InternalFormat = GL_RGBA;
916}
917
918
919
920void
921_mesa_free_colortable_data( struct gl_color_table *p )
922{
923   if (p->TableF) {
924      free(p->TableF);
925      p->TableF = NULL;
926   }
927   if (p->TableUB) {
928      free(p->TableUB);
929      p->TableUB = NULL;
930   }
931}
932