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