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