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