colortab.c revision c7ac486261ad30ef654f6d0b1608da4e8483cd40
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 "glapi/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_COLOR_TABLE: 301 table = &ctx->ColorTable[COLORTABLE_PRECONVOLUTION]; 302 scale = ctx->Pixel.ColorTableScale[COLORTABLE_PRECONVOLUTION]; 303 bias = ctx->Pixel.ColorTableBias[COLORTABLE_PRECONVOLUTION]; 304 break; 305 case GL_PROXY_COLOR_TABLE: 306 table = &ctx->ProxyColorTable[COLORTABLE_PRECONVOLUTION]; 307 proxy = GL_TRUE; 308 break; 309 case GL_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->ColorTable); 315 scale = ctx->Pixel.TextureColorTableScale; 316 bias = ctx->Pixel.TextureColorTableBias; 317 break; 318 case GL_PROXY_TEXTURE_COLOR_TABLE_SGI: 319 if (!ctx->Extensions.SGI_texture_color_table) { 320 _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); 321 return; 322 } 323 table = &(texUnit->ProxyColorTable); 324 proxy = GL_TRUE; 325 break; 326 case GL_POST_CONVOLUTION_COLOR_TABLE: 327 table = &ctx->ColorTable[COLORTABLE_POSTCONVOLUTION]; 328 scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCONVOLUTION]; 329 bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCONVOLUTION]; 330 break; 331 case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE: 332 table = &ctx->ProxyColorTable[COLORTABLE_POSTCONVOLUTION]; 333 proxy = GL_TRUE; 334 break; 335 case GL_POST_COLOR_MATRIX_COLOR_TABLE: 336 table = &ctx->ColorTable[COLORTABLE_POSTCOLORMATRIX]; 337 scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX]; 338 bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX]; 339 break; 340 case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE: 341 table = &ctx->ProxyColorTable[COLORTABLE_POSTCOLORMATRIX]; 342 proxy = GL_TRUE; 343 break; 344 default: 345 /* try texture targets */ 346 { 347 struct gl_texture_object *texobj 348 = _mesa_select_tex_object(ctx, texUnit, target); 349 if (texobj) { 350 table = &texobj->Palette; 351 proxy = _mesa_is_proxy_texture(target); 352 } 353 else { 354 _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); 355 return; 356 } 357 } 358 } 359 360 assert(table); 361 362 if (!_mesa_is_legal_format_and_type(ctx, format, type) || 363 format == GL_INTENSITY) { 364 _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTable(format or type)"); 365 return; 366 } 367 368 baseFormat = base_colortab_format(internalFormat); 369 if (baseFormat < 0) { 370 _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(internalFormat)"); 371 return; 372 } 373 374 if (width < 0 || (width != 0 && !_mesa_is_pow_two(width))) { 375 /* error */ 376 if (proxy) { 377 table->Size = 0; 378 table->InternalFormat = (GLenum) 0; 379 table->_BaseFormat = (GLenum) 0; 380 } 381 else { 382 _mesa_error(ctx, GL_INVALID_VALUE, "glColorTable(width=%d)", width); 383 } 384 return; 385 } 386 387 if (width > (GLsizei) ctx->Const.MaxColorTableSize) { 388 if (proxy) { 389 table->Size = 0; 390 table->InternalFormat = (GLenum) 0; 391 table->_BaseFormat = (GLenum) 0; 392 } 393 else { 394 _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glColorTable(width)"); 395 } 396 return; 397 } 398 399 table->Size = width; 400 table->InternalFormat = internalFormat; 401 table->_BaseFormat = (GLenum) baseFormat; 402 403 comps = _mesa_components_in_format(table->_BaseFormat); 404 assert(comps > 0); /* error should have been caught sooner */ 405 406 if (!proxy) { 407 _mesa_free_colortable_data(table); 408 409 if (width > 0) { 410 table->TableF = (GLfloat *) _mesa_malloc(comps * width * sizeof(GLfloat)); 411 table->TableUB = (GLubyte *) _mesa_malloc(comps * width * sizeof(GLubyte)); 412 413 if (!table->TableF || !table->TableUB) { 414 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable"); 415 return; 416 } 417 418 store_colortable_entries(ctx, table, 419 0, width, /* start, count */ 420 format, type, data, 421 scale[0], bias[0], 422 scale[1], bias[1], 423 scale[2], bias[2], 424 scale[3], bias[3]); 425 } 426 } /* proxy */ 427 428 /* do this after the table's Type and Format are set */ 429 set_component_sizes(table); 430 431 if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) { 432 /* texture object palette, texObj==NULL means the shared palette */ 433 if (ctx->Driver.UpdateTexturePalette) { 434 (*ctx->Driver.UpdateTexturePalette)( ctx, texObj ); 435 } 436 } 437 438 ctx->NewState |= _NEW_PIXEL; 439} 440 441 442 443void GLAPIENTRY 444_mesa_ColorSubTable( GLenum target, GLsizei start, 445 GLsizei count, GLenum format, GLenum type, 446 const GLvoid *data ) 447{ 448 static const GLfloat one[4] = { 1.0, 1.0, 1.0, 1.0 }; 449 static const GLfloat zero[4] = { 0.0, 0.0, 0.0, 0.0 }; 450 GET_CURRENT_CONTEXT(ctx); 451 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); 452 struct gl_texture_object *texObj = NULL; 453 struct gl_color_table *table = NULL; 454 const GLfloat *scale = one, *bias = zero; 455 456 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 457 458 switch (target) { 459 case GL_SHARED_TEXTURE_PALETTE_EXT: 460 table = &ctx->Texture.Palette; 461 break; 462 case GL_COLOR_TABLE: 463 table = &ctx->ColorTable[COLORTABLE_PRECONVOLUTION]; 464 scale = ctx->Pixel.ColorTableScale[COLORTABLE_PRECONVOLUTION]; 465 bias = ctx->Pixel.ColorTableBias[COLORTABLE_PRECONVOLUTION]; 466 break; 467 case GL_TEXTURE_COLOR_TABLE_SGI: 468 if (!ctx->Extensions.SGI_texture_color_table) { 469 _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)"); 470 return; 471 } 472 table = &(texUnit->ColorTable); 473 scale = ctx->Pixel.TextureColorTableScale; 474 bias = ctx->Pixel.TextureColorTableBias; 475 break; 476 case GL_POST_CONVOLUTION_COLOR_TABLE: 477 table = &ctx->ColorTable[COLORTABLE_POSTCONVOLUTION]; 478 scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCONVOLUTION]; 479 bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCONVOLUTION]; 480 break; 481 case GL_POST_COLOR_MATRIX_COLOR_TABLE: 482 table = &ctx->ColorTable[COLORTABLE_POSTCOLORMATRIX]; 483 scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX]; 484 bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX]; 485 break; 486 default: 487 /* try texture targets */ 488 texObj = _mesa_select_tex_object(ctx, texUnit, target); 489 if (texObj && !_mesa_is_proxy_texture(target)) { 490 table = &texObj->Palette; 491 } 492 else { 493 _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)"); 494 return; 495 } 496 } 497 498 assert(table); 499 500 if (!_mesa_is_legal_format_and_type(ctx, format, type) || 501 format == GL_INTENSITY) { 502 _mesa_error(ctx, GL_INVALID_OPERATION, "glColorSubTable(format or type)"); 503 return; 504 } 505 506 if (count < 1) { 507 _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)"); 508 return; 509 } 510 511 /* error should have been caught sooner */ 512 assert(_mesa_components_in_format(table->_BaseFormat) > 0); 513 514 if (start + count > (GLint) table->Size) { 515 _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)"); 516 return; 517 } 518 519 if (!table->TableF || !table->TableUB) { 520 /* a GL_OUT_OF_MEMORY error would have been recorded previously */ 521 return; 522 } 523 524 store_colortable_entries(ctx, table, start, count, 525 format, type, data, 526 scale[0], bias[0], 527 scale[1], bias[1], 528 scale[2], bias[2], 529 scale[3], bias[3]); 530 531 if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) { 532 /* per-texture object palette */ 533 if (ctx->Driver.UpdateTexturePalette) { 534 (*ctx->Driver.UpdateTexturePalette)( ctx, texObj ); 535 } 536 } 537 538 ctx->NewState |= _NEW_PIXEL; 539} 540 541 542 543static void GLAPIENTRY 544_mesa_CopyColorTable(GLenum target, GLenum internalformat, 545 GLint x, GLint y, GLsizei width) 546{ 547 GET_CURRENT_CONTEXT(ctx); 548 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 549 550 if (!ctx->ReadBuffer->_ColorReadBuffer) { 551 return; /* no readbuffer - OK */ 552 } 553 554 ctx->Driver.CopyColorTable( ctx, target, internalformat, x, y, width ); 555} 556 557 558 559static void GLAPIENTRY 560_mesa_CopyColorSubTable(GLenum target, GLsizei start, 561 GLint x, GLint y, GLsizei width) 562{ 563 GET_CURRENT_CONTEXT(ctx); 564 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 565 566 if (!ctx->ReadBuffer->_ColorReadBuffer) { 567 return; /* no readbuffer - OK */ 568 } 569 570 ctx->Driver.CopyColorSubTable( ctx, target, start, x, y, width ); 571} 572 573 574 575static void GLAPIENTRY 576_mesa_GetColorTable( GLenum target, GLenum format, 577 GLenum type, GLvoid *data ) 578{ 579 GET_CURRENT_CONTEXT(ctx); 580 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); 581 struct gl_color_table *table = NULL; 582 GLfloat rgba[MAX_COLOR_TABLE_SIZE][4]; 583 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 584 585 if (ctx->NewState) { 586 _mesa_update_state(ctx); 587 } 588 589 switch (target) { 590 case GL_SHARED_TEXTURE_PALETTE_EXT: 591 table = &ctx->Texture.Palette; 592 break; 593 case GL_COLOR_TABLE: 594 table = &ctx->ColorTable[COLORTABLE_PRECONVOLUTION]; 595 break; 596 case GL_TEXTURE_COLOR_TABLE_SGI: 597 if (!ctx->Extensions.SGI_texture_color_table) { 598 _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); 599 return; 600 } 601 table = &(texUnit->ColorTable); 602 break; 603 case GL_POST_CONVOLUTION_COLOR_TABLE: 604 table = &ctx->ColorTable[COLORTABLE_POSTCONVOLUTION]; 605 break; 606 case GL_POST_COLOR_MATRIX_COLOR_TABLE: 607 table = &ctx->ColorTable[COLORTABLE_POSTCOLORMATRIX]; 608 break; 609 default: 610 /* try texture targets */ 611 { 612 struct gl_texture_object *texobj 613 = _mesa_select_tex_object(ctx, texUnit, target); 614 if (texobj && !_mesa_is_proxy_texture(target)) { 615 table = &texobj->Palette; 616 } 617 else { 618 _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); 619 return; 620 } 621 } 622 } 623 624 ASSERT(table); 625 626 if (table->Size <= 0) { 627 return; 628 } 629 630 switch (table->_BaseFormat) { 631 case GL_ALPHA: 632 { 633 GLuint i; 634 for (i = 0; i < table->Size; i++) { 635 rgba[i][RCOMP] = 0; 636 rgba[i][GCOMP] = 0; 637 rgba[i][BCOMP] = 0; 638 rgba[i][ACOMP] = table->TableF[i]; 639 } 640 } 641 break; 642 case GL_LUMINANCE: 643 { 644 GLuint i; 645 for (i = 0; i < table->Size; i++) { 646 rgba[i][RCOMP] = 647 rgba[i][GCOMP] = 648 rgba[i][BCOMP] = table->TableF[i]; 649 rgba[i][ACOMP] = 1.0F; 650 } 651 } 652 break; 653 case GL_LUMINANCE_ALPHA: 654 { 655 GLuint i; 656 for (i = 0; i < table->Size; i++) { 657 rgba[i][RCOMP] = 658 rgba[i][GCOMP] = 659 rgba[i][BCOMP] = table->TableF[i*2+0]; 660 rgba[i][ACOMP] = table->TableF[i*2+1]; 661 } 662 } 663 break; 664 case GL_INTENSITY: 665 { 666 GLuint i; 667 for (i = 0; i < table->Size; i++) { 668 rgba[i][RCOMP] = 669 rgba[i][GCOMP] = 670 rgba[i][BCOMP] = 671 rgba[i][ACOMP] = table->TableF[i]; 672 } 673 } 674 break; 675 case GL_RGB: 676 { 677 GLuint i; 678 for (i = 0; i < table->Size; i++) { 679 rgba[i][RCOMP] = table->TableF[i*3+0]; 680 rgba[i][GCOMP] = table->TableF[i*3+1]; 681 rgba[i][BCOMP] = table->TableF[i*3+2]; 682 rgba[i][ACOMP] = 1.0F; 683 } 684 } 685 break; 686 case GL_RGBA: 687 memcpy(rgba, table->TableF, 4 * table->Size * sizeof(GLfloat)); 688 break; 689 default: 690 _mesa_problem(ctx, "bad table format in glGetColorTable"); 691 return; 692 } 693 694 data = _mesa_map_validate_pbo_dest(ctx, 695 1, &ctx->Pack, table->Size, 1, 1, 696 format, type, data, 697 "glGetColorTable"); 698 if (!data) 699 return; 700 701 _mesa_pack_rgba_span_float(ctx, table->Size, rgba, 702 format, type, data, &ctx->Pack, 0x0); 703 704 _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 705} 706 707 708 709static void GLAPIENTRY 710_mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params) 711{ 712 GLfloat *scale, *bias; 713 GET_CURRENT_CONTEXT(ctx); 714 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 715 716 switch (target) { 717 case GL_COLOR_TABLE_SGI: 718 scale = ctx->Pixel.ColorTableScale[COLORTABLE_PRECONVOLUTION]; 719 bias = ctx->Pixel.ColorTableBias[COLORTABLE_PRECONVOLUTION]; 720 break; 721 case GL_TEXTURE_COLOR_TABLE_SGI: 722 scale = ctx->Pixel.TextureColorTableScale; 723 bias = ctx->Pixel.TextureColorTableBias; 724 break; 725 case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: 726 scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCONVOLUTION]; 727 bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCONVOLUTION]; 728 break; 729 case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: 730 scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX]; 731 bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX]; 732 break; 733 default: 734 _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)"); 735 return; 736 } 737 738 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 739 COPY_4V(scale, params); 740 } 741 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 742 COPY_4V(bias, params); 743 } 744 else { 745 _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); 746 return; 747 } 748 749 ctx->NewState |= _NEW_PIXEL; 750} 751 752 753 754static void GLAPIENTRY 755_mesa_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params) 756{ 757 GLfloat fparams[4]; 758 if (pname == GL_COLOR_TABLE_SGI || 759 pname == GL_TEXTURE_COLOR_TABLE_SGI || 760 pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI || 761 pname == GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI) { 762 /* four values */ 763 fparams[0] = (GLfloat) params[0]; 764 fparams[1] = (GLfloat) params[1]; 765 fparams[2] = (GLfloat) params[2]; 766 fparams[3] = (GLfloat) params[3]; 767 } 768 else { 769 /* one values */ 770 fparams[0] = (GLfloat) params[0]; 771 } 772 _mesa_ColorTableParameterfv(target, pname, fparams); 773} 774 775 776 777static void GLAPIENTRY 778_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params ) 779{ 780 GET_CURRENT_CONTEXT(ctx); 781 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); 782 struct gl_color_table *table = NULL; 783 ASSERT_OUTSIDE_BEGIN_END(ctx); 784 785 switch (target) { 786 case GL_SHARED_TEXTURE_PALETTE_EXT: 787 table = &ctx->Texture.Palette; 788 break; 789 case GL_COLOR_TABLE: 790 table = &ctx->ColorTable[COLORTABLE_PRECONVOLUTION]; 791 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 792 COPY_4V(params, ctx->Pixel.ColorTableScale[COLORTABLE_PRECONVOLUTION]); 793 return; 794 } 795 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 796 COPY_4V(params, ctx->Pixel.ColorTableBias[COLORTABLE_PRECONVOLUTION]); 797 return; 798 } 799 break; 800 case GL_PROXY_COLOR_TABLE: 801 table = &ctx->ProxyColorTable[COLORTABLE_PRECONVOLUTION]; 802 break; 803 case GL_TEXTURE_COLOR_TABLE_SGI: 804 if (!ctx->Extensions.SGI_texture_color_table) { 805 _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)"); 806 return; 807 } 808 table = &(texUnit->ColorTable); 809 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 810 COPY_4V(params, ctx->Pixel.TextureColorTableScale); 811 return; 812 } 813 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 814 COPY_4V(params, ctx->Pixel.TextureColorTableBias); 815 return; 816 } 817 break; 818 case GL_PROXY_TEXTURE_COLOR_TABLE_SGI: 819 if (!ctx->Extensions.SGI_texture_color_table) { 820 _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)"); 821 return; 822 } 823 table = &(texUnit->ProxyColorTable); 824 break; 825 case GL_POST_CONVOLUTION_COLOR_TABLE: 826 table = &ctx->ColorTable[COLORTABLE_POSTCONVOLUTION]; 827 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 828 COPY_4V(params, ctx->Pixel.ColorTableScale[COLORTABLE_POSTCONVOLUTION]); 829 return; 830 } 831 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 832 COPY_4V(params, ctx->Pixel.ColorTableBias[COLORTABLE_POSTCONVOLUTION]); 833 return; 834 } 835 break; 836 case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE: 837 table = &ctx->ProxyColorTable[COLORTABLE_POSTCONVOLUTION]; 838 break; 839 case GL_POST_COLOR_MATRIX_COLOR_TABLE: 840 table = &ctx->ColorTable[COLORTABLE_POSTCOLORMATRIX]; 841 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 842 COPY_4V(params, ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX]); 843 return; 844 } 845 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 846 COPY_4V(params, ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX]); 847 return; 848 } 849 break; 850 case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE: 851 table = &ctx->ProxyColorTable[COLORTABLE_POSTCOLORMATRIX]; 852 break; 853 default: 854 /* try texture targets */ 855 { 856 struct gl_texture_object *texobj 857 = _mesa_select_tex_object(ctx, texUnit, target); 858 if (texobj) { 859 table = &texobj->Palette; 860 } 861 else { 862 _mesa_error(ctx, GL_INVALID_ENUM, 863 "glGetColorTableParameterfv(target)"); 864 return; 865 } 866 } 867 } 868 869 assert(table); 870 871 switch (pname) { 872 case GL_COLOR_TABLE_FORMAT: 873 *params = (GLfloat) table->InternalFormat; 874 break; 875 case GL_COLOR_TABLE_WIDTH: 876 *params = (GLfloat) table->Size; 877 break; 878 case GL_COLOR_TABLE_RED_SIZE: 879 *params = (GLfloat) table->RedSize; 880 break; 881 case GL_COLOR_TABLE_GREEN_SIZE: 882 *params = (GLfloat) table->GreenSize; 883 break; 884 case GL_COLOR_TABLE_BLUE_SIZE: 885 *params = (GLfloat) table->BlueSize; 886 break; 887 case GL_COLOR_TABLE_ALPHA_SIZE: 888 *params = (GLfloat) table->AlphaSize; 889 break; 890 case GL_COLOR_TABLE_LUMINANCE_SIZE: 891 *params = (GLfloat) table->LuminanceSize; 892 break; 893 case GL_COLOR_TABLE_INTENSITY_SIZE: 894 *params = (GLfloat) table->IntensitySize; 895 break; 896 default: 897 _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(pname)" ); 898 return; 899 } 900} 901 902 903 904static void GLAPIENTRY 905_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params ) 906{ 907 GET_CURRENT_CONTEXT(ctx); 908 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); 909 struct gl_color_table *table = NULL; 910 ASSERT_OUTSIDE_BEGIN_END(ctx); 911 912 switch (target) { 913 case GL_SHARED_TEXTURE_PALETTE_EXT: 914 table = &ctx->Texture.Palette; 915 break; 916 case GL_COLOR_TABLE: 917 table = &ctx->ColorTable[COLORTABLE_PRECONVOLUTION]; 918 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 919 GLfloat *scale = ctx->Pixel.ColorTableScale[COLORTABLE_PRECONVOLUTION]; 920 params[0] = (GLint) scale[0]; 921 params[1] = (GLint) scale[1]; 922 params[2] = (GLint) scale[2]; 923 params[3] = (GLint) scale[3]; 924 return; 925 } 926 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 927 GLfloat *bias = ctx->Pixel.ColorTableBias[COLORTABLE_PRECONVOLUTION]; 928 params[0] = (GLint) bias[0]; 929 params[1] = (GLint) bias[1]; 930 params[2] = (GLint) bias[2]; 931 params[3] = (GLint) bias[3]; 932 return; 933 } 934 break; 935 case GL_PROXY_COLOR_TABLE: 936 table = &ctx->ProxyColorTable[COLORTABLE_PRECONVOLUTION]; 937 break; 938 case GL_TEXTURE_COLOR_TABLE_SGI: 939 if (!ctx->Extensions.SGI_texture_color_table) { 940 _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)"); 941 return; 942 } 943 table = &(texUnit->ColorTable); 944 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 945 params[0] = (GLint) ctx->Pixel.TextureColorTableScale[0]; 946 params[1] = (GLint) ctx->Pixel.TextureColorTableScale[1]; 947 params[2] = (GLint) ctx->Pixel.TextureColorTableScale[2]; 948 params[3] = (GLint) ctx->Pixel.TextureColorTableScale[3]; 949 return; 950 } 951 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 952 params[0] = (GLint) ctx->Pixel.TextureColorTableBias[0]; 953 params[1] = (GLint) ctx->Pixel.TextureColorTableBias[1]; 954 params[2] = (GLint) ctx->Pixel.TextureColorTableBias[2]; 955 params[3] = (GLint) ctx->Pixel.TextureColorTableBias[3]; 956 return; 957 } 958 break; 959 case GL_PROXY_TEXTURE_COLOR_TABLE_SGI: 960 if (!ctx->Extensions.SGI_texture_color_table) { 961 _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameter(target)"); 962 return; 963 } 964 table = &(texUnit->ProxyColorTable); 965 break; 966 case GL_POST_CONVOLUTION_COLOR_TABLE: 967 table = &ctx->ColorTable[COLORTABLE_POSTCONVOLUTION]; 968 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 969 GLfloat *scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCONVOLUTION]; 970 params[0] = (GLint) scale[0]; 971 params[1] = (GLint) scale[1]; 972 params[2] = (GLint) scale[2]; 973 params[3] = (GLint) scale[3]; 974 return; 975 } 976 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 977 GLfloat *bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCONVOLUTION]; 978 params[0] = (GLint) bias[0]; 979 params[1] = (GLint) bias[1]; 980 params[2] = (GLint) bias[2]; 981 params[3] = (GLint) bias[3]; 982 return; 983 } 984 break; 985 case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE: 986 table = &ctx->ProxyColorTable[COLORTABLE_POSTCONVOLUTION]; 987 break; 988 case GL_POST_COLOR_MATRIX_COLOR_TABLE: 989 table = &ctx->ColorTable[COLORTABLE_POSTCOLORMATRIX]; 990 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 991 GLfloat *scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX]; 992 params[0] = (GLint) scale[0]; 993 params[0] = (GLint) scale[1]; 994 params[0] = (GLint) scale[2]; 995 params[0] = (GLint) scale[3]; 996 return; 997 } 998 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 999 GLfloat *bias = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX]; 1000 params[0] = (GLint) bias[0]; 1001 params[1] = (GLint) bias[1]; 1002 params[2] = (GLint) bias[2]; 1003 params[3] = (GLint) bias[3]; 1004 return; 1005 } 1006 break; 1007 case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE: 1008 table = &ctx->ProxyColorTable[COLORTABLE_POSTCOLORMATRIX]; 1009 break; 1010 default: 1011 /* Try texture targets */ 1012 { 1013 struct gl_texture_object *texobj 1014 = _mesa_select_tex_object(ctx, texUnit, target); 1015 if (texobj) { 1016 table = &texobj->Palette; 1017 } 1018 else { 1019 _mesa_error(ctx, GL_INVALID_ENUM, 1020 "glGetColorTableParameteriv(target)"); 1021 return; 1022 } 1023 } 1024 } 1025 1026 assert(table); 1027 1028 switch (pname) { 1029 case GL_COLOR_TABLE_FORMAT: 1030 *params = table->InternalFormat; 1031 break; 1032 case GL_COLOR_TABLE_WIDTH: 1033 *params = table->Size; 1034 break; 1035 case GL_COLOR_TABLE_RED_SIZE: 1036 *params = table->RedSize; 1037 break; 1038 case GL_COLOR_TABLE_GREEN_SIZE: 1039 *params = table->GreenSize; 1040 break; 1041 case GL_COLOR_TABLE_BLUE_SIZE: 1042 *params = table->BlueSize; 1043 break; 1044 case GL_COLOR_TABLE_ALPHA_SIZE: 1045 *params = table->AlphaSize; 1046 break; 1047 case GL_COLOR_TABLE_LUMINANCE_SIZE: 1048 *params = table->LuminanceSize; 1049 break; 1050 case GL_COLOR_TABLE_INTENSITY_SIZE: 1051 *params = table->IntensitySize; 1052 break; 1053 default: 1054 _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(pname)" ); 1055 return; 1056 } 1057} 1058 1059 1060void 1061_mesa_init_colortable_dispatch(struct _glapi_table *disp) 1062{ 1063 SET_ColorSubTable(disp, _mesa_ColorSubTable); 1064 SET_ColorTable(disp, _mesa_ColorTable); 1065 SET_ColorTableParameterfv(disp, _mesa_ColorTableParameterfv); 1066 SET_ColorTableParameteriv(disp, _mesa_ColorTableParameteriv); 1067 SET_CopyColorSubTable(disp, _mesa_CopyColorSubTable); 1068 SET_CopyColorTable(disp, _mesa_CopyColorTable); 1069 SET_GetColorTable(disp, _mesa_GetColorTable); 1070 SET_GetColorTableParameterfv(disp, _mesa_GetColorTableParameterfv); 1071 SET_GetColorTableParameteriv(disp, _mesa_GetColorTableParameteriv); 1072} 1073 1074 1075#endif /* FEATURE_colortable */ 1076 1077 1078/**********************************************************************/ 1079/***** Initialization *****/ 1080/**********************************************************************/ 1081 1082 1083void 1084_mesa_init_colortable( struct gl_color_table *p ) 1085{ 1086 p->TableF = NULL; 1087 p->TableUB = NULL; 1088 p->Size = 0; 1089 p->InternalFormat = GL_RGBA; 1090} 1091 1092 1093 1094void 1095_mesa_free_colortable_data( struct gl_color_table *p ) 1096{ 1097 if (p->TableF) { 1098 _mesa_free(p->TableF); 1099 p->TableF = NULL; 1100 } 1101 if (p->TableUB) { 1102 _mesa_free(p->TableUB); 1103 p->TableUB = NULL; 1104 } 1105} 1106 1107 1108/* 1109 * Initialize all colortables for a context. 1110 */ 1111void 1112_mesa_init_colortables( GLcontext * ctx ) 1113{ 1114 GLuint i; 1115 for (i = 0; i < COLORTABLE_MAX; i++) { 1116 _mesa_init_colortable(&ctx->ColorTable[i]); 1117 _mesa_init_colortable(&ctx->ProxyColorTable[i]); 1118 } 1119} 1120 1121 1122/* 1123 * Free all colortable data for a context 1124 */ 1125void 1126_mesa_free_colortables_data( GLcontext *ctx ) 1127{ 1128 GLuint i; 1129 for (i = 0; i < COLORTABLE_MAX; i++) { 1130 _mesa_free_colortable_data(&ctx->ColorTable[i]); 1131 _mesa_free_colortable_data(&ctx->ProxyColorTable[i]); 1132 } 1133} 1134