colortab.c revision 709892459922a32096fe9dd8261d0d92337bb02f
1/* $Id: colortab.c,v 1.38 2001/03/19 02:25:35 keithw Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.5 6 * 7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 28#ifdef PC_HEADER 29#include "all.h" 30#else 31#include "glheader.h" 32#include "colortab.h" 33#include "context.h" 34#include "image.h" 35#include "macros.h" 36#include "mem.h" 37#include "mmath.h" 38#include "state.h" 39#include "swrast/s_span.h" /* XXX SWRAST hack */ 40#endif 41 42 43 44/* 45 * Given an internalFormat token passed to glColorTable, 46 * return the corresponding base format. 47 * Return -1 if invalid token. 48 */ 49static GLint 50base_colortab_format( GLenum format ) 51{ 52 switch (format) { 53 case GL_ALPHA: 54 case GL_ALPHA4: 55 case GL_ALPHA8: 56 case GL_ALPHA12: 57 case GL_ALPHA16: 58 return GL_ALPHA; 59 case GL_LUMINANCE: 60 case GL_LUMINANCE4: 61 case GL_LUMINANCE8: 62 case GL_LUMINANCE12: 63 case GL_LUMINANCE16: 64 return GL_LUMINANCE; 65 case GL_LUMINANCE_ALPHA: 66 case GL_LUMINANCE4_ALPHA4: 67 case GL_LUMINANCE6_ALPHA2: 68 case GL_LUMINANCE8_ALPHA8: 69 case GL_LUMINANCE12_ALPHA4: 70 case GL_LUMINANCE12_ALPHA12: 71 case GL_LUMINANCE16_ALPHA16: 72 return GL_LUMINANCE_ALPHA; 73 case GL_INTENSITY: 74 case GL_INTENSITY4: 75 case GL_INTENSITY8: 76 case GL_INTENSITY12: 77 case GL_INTENSITY16: 78 return GL_INTENSITY; 79 case GL_RGB: 80 case GL_R3_G3_B2: 81 case GL_RGB4: 82 case GL_RGB5: 83 case GL_RGB8: 84 case GL_RGB10: 85 case GL_RGB12: 86 case GL_RGB16: 87 return GL_RGB; 88 case GL_RGBA: 89 case GL_RGBA2: 90 case GL_RGBA4: 91 case GL_RGB5_A1: 92 case GL_RGBA8: 93 case GL_RGB10_A2: 94 case GL_RGBA12: 95 case GL_RGBA16: 96 return GL_RGBA; 97 default: 98 return -1; /* error */ 99 } 100} 101 102 103void 104_mesa_init_colortable( struct gl_color_table *p ) 105{ 106 p->FloatTable = GL_FALSE; 107 p->Table = NULL; 108 p->Size = 0; 109 p->IntFormat = GL_RGBA; 110} 111 112 113 114void 115_mesa_free_colortable_data( struct gl_color_table *p ) 116{ 117 if (p->Table) { 118 FREE(p->Table); 119 p->Table = NULL; 120 } 121} 122 123 124/* 125 * Examine table's format and set the component sizes accordingly. 126 */ 127static void 128set_component_sizes( struct gl_color_table *table ) 129{ 130 /* XXX what about GLfloat tables? */ 131 switch (table->Format) { 132 case GL_ALPHA: 133 table->RedSize = 0; 134 table->GreenSize = 0; 135 table->BlueSize = 0; 136 table->AlphaSize = CHAN_BITS; 137 table->IntensitySize = 0; 138 table->LuminanceSize = 0; 139 break; 140 case GL_LUMINANCE: 141 table->RedSize = 0; 142 table->GreenSize = 0; 143 table->BlueSize = 0; 144 table->AlphaSize = 0; 145 table->IntensitySize = 0; 146 table->LuminanceSize = CHAN_BITS; 147 break; 148 case GL_LUMINANCE_ALPHA: 149 table->RedSize = 0; 150 table->GreenSize = 0; 151 table->BlueSize = 0; 152 table->AlphaSize = CHAN_BITS; 153 table->IntensitySize = 0; 154 table->LuminanceSize = CHAN_BITS; 155 break; 156 case GL_INTENSITY: 157 table->RedSize = 0; 158 table->GreenSize = 0; 159 table->BlueSize = 0; 160 table->AlphaSize = 0; 161 table->IntensitySize = CHAN_BITS; 162 table->LuminanceSize = 0; 163 break; 164 case GL_RGB: 165 table->RedSize = CHAN_BITS; 166 table->GreenSize = CHAN_BITS; 167 table->BlueSize = CHAN_BITS; 168 table->AlphaSize = 0; 169 table->IntensitySize = 0; 170 table->LuminanceSize = 0; 171 break; 172 case GL_RGBA: 173 table->RedSize = CHAN_BITS; 174 table->GreenSize = CHAN_BITS; 175 table->BlueSize = CHAN_BITS; 176 table->AlphaSize = CHAN_BITS; 177 table->IntensitySize = 0; 178 table->LuminanceSize = 0; 179 break; 180 default: 181 _mesa_problem(NULL, "unexpected format in set_component_sizes"); 182 } 183} 184 185 186 187void 188_mesa_ColorTable( GLenum target, GLenum internalFormat, 189 GLsizei width, GLenum format, GLenum type, 190 const GLvoid *data ) 191{ 192 GET_CURRENT_CONTEXT(ctx); 193 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 194 struct gl_texture_object *texObj = NULL; 195 struct gl_color_table *table = NULL; 196 GLboolean proxy = GL_FALSE; 197 GLint baseFormat; 198 GLfloat rScale = 1.0, gScale = 1.0, bScale = 1.0, aScale = 1.0; 199 GLfloat rBias = 0.0, gBias = 0.0, bBias = 0.0, aBias = 0.0; 200 GLboolean floatTable = GL_FALSE; 201 GLint comps; 202 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */ 203 204 switch (target) { 205 case GL_TEXTURE_1D: 206 texObj = texUnit->Current1D; 207 table = &texObj->Palette; 208 break; 209 case GL_TEXTURE_2D: 210 texObj = texUnit->Current2D; 211 table = &texObj->Palette; 212 break; 213 case GL_TEXTURE_3D: 214 texObj = texUnit->Current3D; 215 table = &texObj->Palette; 216 break; 217 case GL_PROXY_TEXTURE_1D: 218 texObj = ctx->Texture.Proxy1D; 219 table = &texObj->Palette; 220 proxy = GL_TRUE; 221 break; 222 case GL_PROXY_TEXTURE_2D: 223 texObj = ctx->Texture.Proxy2D; 224 table = &texObj->Palette; 225 proxy = GL_TRUE; 226 break; 227 case GL_PROXY_TEXTURE_3D: 228 texObj = ctx->Texture.Proxy3D; 229 table = &texObj->Palette; 230 proxy = GL_TRUE; 231 break; 232 case GL_SHARED_TEXTURE_PALETTE_EXT: 233 table = &ctx->Texture.Palette; 234 break; 235 case GL_COLOR_TABLE: 236 table = &ctx->ColorTable; 237 floatTable = GL_TRUE; 238 rScale = ctx->Pixel.ColorTableScale[0]; 239 gScale = ctx->Pixel.ColorTableScale[1]; 240 bScale = ctx->Pixel.ColorTableScale[2]; 241 aScale = ctx->Pixel.ColorTableScale[3]; 242 rBias = ctx->Pixel.ColorTableBias[0]; 243 gBias = ctx->Pixel.ColorTableBias[1]; 244 bBias = ctx->Pixel.ColorTableBias[2]; 245 aBias = ctx->Pixel.ColorTableBias[3]; 246 break; 247 case GL_PROXY_COLOR_TABLE: 248 table = &ctx->ProxyColorTable; 249 proxy = GL_TRUE; 250 break; 251 case GL_POST_CONVOLUTION_COLOR_TABLE: 252 table = &ctx->PostConvolutionColorTable; 253 floatTable = GL_TRUE; 254 rScale = ctx->Pixel.PCCTscale[0]; 255 gScale = ctx->Pixel.PCCTscale[1]; 256 bScale = ctx->Pixel.PCCTscale[2]; 257 aScale = ctx->Pixel.PCCTscale[3]; 258 rBias = ctx->Pixel.PCCTbias[0]; 259 gBias = ctx->Pixel.PCCTbias[1]; 260 bBias = ctx->Pixel.PCCTbias[2]; 261 aBias = ctx->Pixel.PCCTbias[3]; 262 break; 263 case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE: 264 table = &ctx->ProxyPostConvolutionColorTable; 265 proxy = GL_TRUE; 266 break; 267 case GL_POST_COLOR_MATRIX_COLOR_TABLE: 268 table = &ctx->PostColorMatrixColorTable; 269 floatTable = GL_TRUE; 270 rScale = ctx->Pixel.PCMCTscale[0]; 271 gScale = ctx->Pixel.PCMCTscale[1]; 272 bScale = ctx->Pixel.PCMCTscale[2]; 273 aScale = ctx->Pixel.PCMCTscale[3]; 274 rBias = ctx->Pixel.PCMCTbias[0]; 275 gBias = ctx->Pixel.PCMCTbias[1]; 276 bBias = ctx->Pixel.PCMCTbias[2]; 277 aBias = ctx->Pixel.PCMCTbias[3]; 278 break; 279 case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE: 280 table = &ctx->ProxyPostColorMatrixColorTable; 281 proxy = GL_TRUE; 282 break; 283 default: 284 _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); 285 return; 286 } 287 288 assert(table); 289 290 if (!_mesa_is_legal_format_and_type(format, type) || 291 format == GL_INTENSITY) { 292 _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTable(format or type)"); 293 return; 294 } 295 296 baseFormat = base_colortab_format(internalFormat); 297 if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { 298 _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(internalFormat)"); 299 return; 300 } 301 302 if (width < 0 || (width != 0 && _mesa_bitcount(width) != 1)) { 303 /* error */ 304 if (proxy) { 305 table->Size = 0; 306 table->IntFormat = (GLenum) 0; 307 table->Format = (GLenum) 0; 308 } 309 else { 310 char msg[100]; 311 sprintf(msg, "glColorTable(width=%d)", width); 312 _mesa_error(ctx, GL_INVALID_VALUE, msg); 313 } 314 return; 315 } 316 317 if (width > (GLsizei) ctx->Const.MaxColorTableSize) { 318 if (proxy) { 319 table->Size = 0; 320 table->IntFormat = (GLenum) 0; 321 table->Format = (GLenum) 0; 322 } 323 else { 324 _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glColorTable(width)"); 325 } 326 return; 327 } 328 329 table->Size = width; 330 table->IntFormat = internalFormat; 331 table->Format = (GLenum) baseFormat; 332 set_component_sizes(table); 333 334 comps = _mesa_components_in_format(table->Format); 335 assert(comps > 0); /* error should have been caught sooner */ 336 337 if (!proxy) { 338 /* free old table, if any */ 339 if (table->Table) { 340 FREE(table->Table); 341 table->Table = NULL; 342 } 343 if (width > 0) { 344 if (floatTable) { 345 GLfloat tempTab[MAX_COLOR_TABLE_SIZE * 4]; 346 GLfloat *tableF; 347 GLint i; 348 349 _mesa_unpack_float_color_span(ctx, width, table->Format, 350 tempTab, /* dest */ 351 format, type, data, &ctx->Unpack, 352 0, GL_FALSE); 353 354 table->FloatTable = GL_TRUE; 355 table->Table = MALLOC(comps * width * sizeof(GLfloat)); 356 if (!table->Table) { 357 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable"); 358 return; 359 } 360 361 tableF = (GLfloat *) table->Table; 362 363 switch (table->Format) { 364 case GL_INTENSITY: 365 for (i = 0; i < width; i++) { 366 tableF[i] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F); 367 } 368 break; 369 case GL_LUMINANCE: 370 for (i = 0; i < width; i++) { 371 tableF[i] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F); 372 } 373 break; 374 case GL_ALPHA: 375 for (i = 0; i < width; i++) { 376 tableF[i] = CLAMP(tempTab[i] * aScale + aBias, 0.0F, 1.0F); 377 } 378 break; 379 case GL_LUMINANCE_ALPHA: 380 for (i = 0; i < width; i++) { 381 tableF[i*2+0] = CLAMP(tempTab[i*2+0] * rScale + rBias, 0.0F, 1.0F); 382 tableF[i*2+1] = CLAMP(tempTab[i*2+1] * aScale + aBias, 0.0F, 1.0F); 383 } 384 break; 385 case GL_RGB: 386 for (i = 0; i < width; i++) { 387 tableF[i*3+0] = CLAMP(tempTab[i*3+0] * rScale + rBias, 0.0F, 1.0F); 388 tableF[i*3+1] = CLAMP(tempTab[i*3+1] * gScale + gBias, 0.0F, 1.0F); 389 tableF[i*3+2] = CLAMP(tempTab[i*3+2] * bScale + bBias, 0.0F, 1.0F); 390 } 391 break; 392 case GL_RGBA: 393 for (i = 0; i < width; i++) { 394 tableF[i*4+0] = CLAMP(tempTab[i*4+0] * rScale + rBias, 0.0F, 1.0F); 395 tableF[i*4+1] = CLAMP(tempTab[i*4+1] * gScale + gBias, 0.0F, 1.0F); 396 tableF[i*4+2] = CLAMP(tempTab[i*4+2] * bScale + bBias, 0.0F, 1.0F); 397 tableF[i*4+3] = CLAMP(tempTab[i*4+3] * aScale + aBias, 0.0F, 1.0F); 398 } 399 break; 400 default: 401 _mesa_problem(ctx, "Bad format in _mesa_ColorTable"); 402 return; 403 } 404 } 405 else { 406 /* store GLchan table */ 407 table->FloatTable = GL_FALSE; 408 table->Table = MALLOC(comps * width * sizeof(GLchan)); 409 if (!table->Table) { 410 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable"); 411 return; 412 } 413 _mesa_unpack_chan_color_span(ctx, width, table->Format, 414 (GLchan *) table->Table, /* dest */ 415 format, type, data, 416 &ctx->Unpack, 0); 417 } /* floatTable */ 418 } /* width > 0 */ 419 } /* proxy */ 420 421 if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) { 422 /* texture object palette, texObj==NULL means the shared palette */ 423 if (ctx->Driver.UpdateTexturePalette) { 424 (*ctx->Driver.UpdateTexturePalette)( ctx, texObj ); 425 } 426 } 427 428 ctx->NewState |= _NEW_PIXEL; 429} 430 431 432 433void 434_mesa_ColorSubTable( GLenum target, GLsizei start, 435 GLsizei count, GLenum format, GLenum type, 436 const GLvoid *data ) 437{ 438 GET_CURRENT_CONTEXT(ctx); 439 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 440 struct gl_texture_object *texObj = NULL; 441 struct gl_color_table *table = NULL; 442 GLfloat rScale = 1.0, gScale = 1.0, bScale = 1.0, aScale = 1.0; 443 GLfloat rBias = 0.0, gBias = 0.0, bBias = 0.0, aBias = 0.0; 444 GLint comps; 445 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 446 447 switch (target) { 448 case GL_TEXTURE_1D: 449 texObj = texUnit->Current1D; 450 table = &texObj->Palette; 451 break; 452 case GL_TEXTURE_2D: 453 texObj = texUnit->Current2D; 454 table = &texObj->Palette; 455 break; 456 case GL_TEXTURE_3D: 457 texObj = texUnit->Current3D; 458 table = &texObj->Palette; 459 break; 460 case GL_SHARED_TEXTURE_PALETTE_EXT: 461 table = &ctx->Texture.Palette; 462 break; 463 case GL_COLOR_TABLE: 464 table = &ctx->ColorTable; 465 rScale = ctx->Pixel.ColorTableScale[0]; 466 gScale = ctx->Pixel.ColorTableScale[1]; 467 bScale = ctx->Pixel.ColorTableScale[2]; 468 aScale = ctx->Pixel.ColorTableScale[3]; 469 rBias = ctx->Pixel.ColorTableBias[0]; 470 gBias = ctx->Pixel.ColorTableBias[1]; 471 bBias = ctx->Pixel.ColorTableBias[2]; 472 aBias = ctx->Pixel.ColorTableBias[3]; 473 break; 474 case GL_POST_CONVOLUTION_COLOR_TABLE: 475 table = &ctx->PostConvolutionColorTable; 476 rScale = ctx->Pixel.PCCTscale[0]; 477 gScale = ctx->Pixel.PCCTscale[1]; 478 bScale = ctx->Pixel.PCCTscale[2]; 479 aScale = ctx->Pixel.PCCTscale[3]; 480 rBias = ctx->Pixel.PCCTbias[0]; 481 gBias = ctx->Pixel.PCCTbias[1]; 482 bBias = ctx->Pixel.PCCTbias[2]; 483 aBias = ctx->Pixel.PCCTbias[3]; 484 break; 485 case GL_POST_COLOR_MATRIX_COLOR_TABLE: 486 table = &ctx->PostColorMatrixColorTable; 487 rScale = ctx->Pixel.PCMCTscale[0]; 488 gScale = ctx->Pixel.PCMCTscale[1]; 489 bScale = ctx->Pixel.PCMCTscale[2]; 490 aScale = ctx->Pixel.PCMCTscale[3]; 491 rBias = ctx->Pixel.PCMCTbias[0]; 492 gBias = ctx->Pixel.PCMCTbias[1]; 493 bBias = ctx->Pixel.PCMCTbias[2]; 494 aBias = ctx->Pixel.PCMCTbias[3]; 495 break; 496 default: 497 _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)"); 498 return; 499 } 500 501 assert(table); 502 503 if (!_mesa_is_legal_format_and_type(format, type) || 504 format == GL_INTENSITY) { 505 _mesa_error(ctx, GL_INVALID_OPERATION, "glColorSubTable(format or type)"); 506 return; 507 } 508 509 if (count < 1) { 510 _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)"); 511 return; 512 } 513 514 comps = _mesa_components_in_format(table->Format); 515 assert(comps > 0); /* error should have been caught sooner */ 516 517 if (start + count > (GLint) table->Size) { 518 _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)"); 519 return; 520 } 521 522 if (!table->Table) { 523 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorSubTable"); 524 return; 525 } 526 527 if (!table->FloatTable) { 528 GLchan *dest = (GLchan *) table->Table + start * comps * sizeof(GLchan); 529 _mesa_unpack_chan_color_span(ctx, count, table->Format, dest, 530 format, type, data, &ctx->Unpack, 0); 531 } 532 else { 533 GLfloat tempTab[MAX_COLOR_TABLE_SIZE * 4]; 534 GLfloat *tableF; 535 GLint i; 536 537 ASSERT(table->FloatTable); 538 539 _mesa_unpack_float_color_span(ctx, count, table->Format, 540 tempTab, /* dest */ 541 format, type, data, &ctx->Unpack, 542 0, GL_FALSE); 543 544 tableF = (GLfloat *) table->Table; 545 546 switch (table->Format) { 547 case GL_INTENSITY: 548 for (i = 0; i < count; i++) { 549 GLuint j = start + i; 550 tableF[j] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F); 551 } 552 break; 553 case GL_LUMINANCE: 554 for (i = 0; i < count; i++) { 555 GLuint j = start + i; 556 tableF[j] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F); 557 } 558 break; 559 case GL_ALPHA: 560 for (i = 0; i < count; i++) { 561 GLuint j = start + i; 562 tableF[j] = CLAMP(tempTab[i] * aScale + aBias, 0.0F, 1.0F); 563 } 564 break; 565 case GL_LUMINANCE_ALPHA: 566 for (i = 0; i < count; i++) { 567 GLuint j = start + i; 568 tableF[j*2+0] = CLAMP(tempTab[i*2+0] * rScale + rBias, 0.0F, 1.0F); 569 tableF[j*2+1] = CLAMP(tempTab[i*2+1] * aScale + aBias, 0.0F, 1.0F); 570 } 571 break; 572 case GL_RGB: 573 for (i = 0; i < count; i++) { 574 GLuint j = start + i; 575 tableF[j*3+0] = CLAMP(tempTab[i*3+0] * rScale + rBias, 0.0F, 1.0F); 576 tableF[j*3+1] = CLAMP(tempTab[i*3+1] * gScale + gBias, 0.0F, 1.0F); 577 tableF[j*3+2] = CLAMP(tempTab[i*3+2] * bScale + bBias, 0.0F, 1.0F); 578 } 579 break; 580 case GL_RGBA: 581 for (i = 0; i < count; i++) { 582 GLuint j = start + i; 583 tableF[j*4+0] = CLAMP(tempTab[i*4+0] * rScale + rBias, 0.0F, 1.0F); 584 tableF[j*4+1] = CLAMP(tempTab[i*4+1] * gScale + gBias, 0.0F, 1.0F); 585 tableF[j*4+2] = CLAMP(tempTab[i*4+2] * bScale + bBias, 0.0F, 1.0F); 586 tableF[j*4+3] = CLAMP(tempTab[i*4+3] * aScale + aBias, 0.0F, 1.0F); 587 } 588 break; 589 default: 590 _mesa_problem(ctx, "Bad format in _mesa_ColorSubTable"); 591 return; 592 } 593 } 594 595 if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) { 596 /* per-texture object palette */ 597 if (ctx->Driver.UpdateTexturePalette) { 598 (*ctx->Driver.UpdateTexturePalette)( ctx, texObj ); 599 } 600 } 601 602 ctx->NewState |= _NEW_PIXEL; 603} 604 605 606 607/* XXX not tested */ 608void 609_mesa_CopyColorTable(GLenum target, GLenum internalformat, 610 GLint x, GLint y, GLsizei width) 611{ 612 GET_CURRENT_CONTEXT(ctx); 613 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 614 615 /* Select buffer to read from */ 616 ctx->Driver.CopyColorTable( ctx, target, internalformat, x, y, width ); 617} 618 619 620 621/* XXX not tested */ 622void 623_mesa_CopyColorSubTable(GLenum target, GLsizei start, 624 GLint x, GLint y, GLsizei width) 625{ 626 GET_CURRENT_CONTEXT(ctx); 627 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 628 629 ctx->Driver.CopyColorSubTable( ctx, target, start, x, y, width ); 630} 631 632 633 634void 635_mesa_GetColorTable( GLenum target, GLenum format, 636 GLenum type, GLvoid *data ) 637{ 638 GET_CURRENT_CONTEXT(ctx); 639 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 640 struct gl_color_table *table = NULL; 641 GLchan rgba[MAX_COLOR_TABLE_SIZE][4]; 642 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 643 644 if (ctx->NewState) { 645 _mesa_update_state(ctx); 646 } 647 648 switch (target) { 649 case GL_TEXTURE_1D: 650 table = &texUnit->Current1D->Palette; 651 break; 652 case GL_TEXTURE_2D: 653 table = &texUnit->Current2D->Palette; 654 break; 655 case GL_TEXTURE_3D: 656 table = &texUnit->Current3D->Palette; 657 break; 658 case GL_SHARED_TEXTURE_PALETTE_EXT: 659 table = &ctx->Texture.Palette; 660 break; 661 case GL_COLOR_TABLE: 662 table = &ctx->ColorTable; 663 break; 664 case GL_POST_CONVOLUTION_COLOR_TABLE: 665 table = &ctx->PostConvolutionColorTable; 666 break; 667 case GL_POST_COLOR_MATRIX_COLOR_TABLE: 668 table = &ctx->PostColorMatrixColorTable; 669 break; 670 default: 671 _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); 672 return; 673 } 674 675 assert(table); 676 677 switch (table->Format) { 678 case GL_ALPHA: 679 if (table->FloatTable) { 680 const GLfloat *tableF = (const GLfloat *) table->Table; 681 GLuint i; 682 for (i = 0; i < table->Size; i++) { 683 rgba[i][RCOMP] = 0; 684 rgba[i][GCOMP] = 0; 685 rgba[i][BCOMP] = 0; 686 rgba[i][ACOMP] = (GLint) (tableF[i] * CHAN_MAXF); 687 } 688 } 689 else { 690 const GLchan *tableUB = (const GLchan *) table->Table; 691 GLuint i; 692 for (i = 0; i < table->Size; i++) { 693 rgba[i][RCOMP] = 0; 694 rgba[i][GCOMP] = 0; 695 rgba[i][BCOMP] = 0; 696 rgba[i][ACOMP] = tableUB[i]; 697 } 698 } 699 break; 700 case GL_LUMINANCE: 701 if (table->FloatTable) { 702 const GLfloat *tableF = (const GLfloat *) table->Table; 703 GLuint i; 704 for (i = 0; i < table->Size; i++) { 705 rgba[i][RCOMP] = (GLint) (tableF[i] * CHAN_MAXF); 706 rgba[i][GCOMP] = (GLint) (tableF[i] * CHAN_MAXF); 707 rgba[i][BCOMP] = (GLint) (tableF[i] * CHAN_MAXF); 708 rgba[i][ACOMP] = CHAN_MAX; 709 } 710 } 711 else { 712 const GLchan *tableUB = (const GLchan *) table->Table; 713 GLuint i; 714 for (i = 0; i < table->Size; i++) { 715 rgba[i][RCOMP] = tableUB[i]; 716 rgba[i][GCOMP] = tableUB[i]; 717 rgba[i][BCOMP] = tableUB[i]; 718 rgba[i][ACOMP] = CHAN_MAX; 719 } 720 } 721 break; 722 case GL_LUMINANCE_ALPHA: 723 if (table->FloatTable) { 724 const GLfloat *tableF = (const GLfloat *) table->Table; 725 GLuint i; 726 for (i = 0; i < table->Size; i++) { 727 rgba[i][RCOMP] = (GLint) (tableF[i*2+0] * CHAN_MAXF); 728 rgba[i][GCOMP] = (GLint) (tableF[i*2+0] * CHAN_MAXF); 729 rgba[i][BCOMP] = (GLint) (tableF[i*2+0] * CHAN_MAXF); 730 rgba[i][ACOMP] = (GLint) (tableF[i*2+1] * CHAN_MAXF); 731 } 732 } 733 else { 734 const GLchan *tableUB = (const GLchan *) table->Table; 735 GLuint i; 736 for (i = 0; i < table->Size; i++) { 737 rgba[i][RCOMP] = tableUB[i*2+0]; 738 rgba[i][GCOMP] = tableUB[i*2+0]; 739 rgba[i][BCOMP] = tableUB[i*2+0]; 740 rgba[i][ACOMP] = tableUB[i*2+1]; 741 } 742 } 743 break; 744 case GL_INTENSITY: 745 if (table->FloatTable) { 746 const GLfloat *tableF = (const GLfloat *) table->Table; 747 GLuint i; 748 for (i = 0; i < table->Size; i++) { 749 rgba[i][RCOMP] = (GLint) (tableF[i] * CHAN_MAXF); 750 rgba[i][GCOMP] = (GLint) (tableF[i] * CHAN_MAXF); 751 rgba[i][BCOMP] = (GLint) (tableF[i] * CHAN_MAXF); 752 rgba[i][ACOMP] = (GLint) (tableF[i] * CHAN_MAXF); 753 } 754 } 755 else { 756 const GLchan *tableUB = (const GLchan *) table->Table; 757 GLuint i; 758 for (i = 0; i < table->Size; i++) { 759 rgba[i][RCOMP] = tableUB[i]; 760 rgba[i][GCOMP] = tableUB[i]; 761 rgba[i][BCOMP] = tableUB[i]; 762 rgba[i][ACOMP] = tableUB[i]; 763 } 764 } 765 break; 766 case GL_RGB: 767 if (table->FloatTable) { 768 const GLfloat *tableF = (const GLfloat *) table->Table; 769 GLuint i; 770 for (i = 0; i < table->Size; i++) { 771 rgba[i][RCOMP] = (GLint) (tableF[i*3+0] * CHAN_MAXF); 772 rgba[i][GCOMP] = (GLint) (tableF[i*3+1] * CHAN_MAXF); 773 rgba[i][BCOMP] = (GLint) (tableF[i*3+2] * CHAN_MAXF); 774 rgba[i][ACOMP] = CHAN_MAX; 775 } 776 } 777 else { 778 const GLchan *tableUB = (const GLchan *) table->Table; 779 GLuint i; 780 for (i = 0; i < table->Size; i++) { 781 rgba[i][RCOMP] = tableUB[i*3+0]; 782 rgba[i][GCOMP] = tableUB[i*3+1]; 783 rgba[i][BCOMP] = tableUB[i*3+2]; 784 rgba[i][ACOMP] = CHAN_MAX; 785 } 786 } 787 break; 788 case GL_RGBA: 789 if (table->FloatTable) { 790 const GLfloat *tableF = (const GLfloat *) table->Table; 791 GLuint i; 792 for (i = 0; i < table->Size; i++) { 793 rgba[i][RCOMP] = (GLint) (tableF[i*4+0] * CHAN_MAXF + 0.5F); 794 rgba[i][GCOMP] = (GLint) (tableF[i*4+1] * CHAN_MAXF + 0.5F); 795 rgba[i][BCOMP] = (GLint) (tableF[i*4+2] * CHAN_MAXF + 0.5F); 796 rgba[i][ACOMP] = (GLint) (tableF[i*4+3] * CHAN_MAXF + 0.5F); 797 } 798 } 799 else { 800 const GLchan *tableUB = (const GLchan *) table->Table; 801 GLuint i; 802 for (i = 0; i < table->Size; i++) { 803 rgba[i][RCOMP] = tableUB[i*4+0]; 804 rgba[i][GCOMP] = tableUB[i*4+1]; 805 rgba[i][BCOMP] = tableUB[i*4+2]; 806 rgba[i][ACOMP] = tableUB[i*4+3]; 807 } 808 } 809 break; 810 default: 811 _mesa_problem(ctx, "bad table format in glGetColorTable"); 812 return; 813 } 814 815 _mesa_pack_rgba_span(ctx, table->Size, (const GLchan (*)[]) rgba, 816 format, type, data, &ctx->Pack, GL_FALSE); 817} 818 819 820 821void 822_mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params) 823{ 824 GET_CURRENT_CONTEXT(ctx); 825 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 826 827 switch (target) { 828 case GL_COLOR_TABLE_SGI: 829 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 830 ctx->Pixel.ColorTableScale[0] = params[0]; 831 ctx->Pixel.ColorTableScale[1] = params[1]; 832 ctx->Pixel.ColorTableScale[2] = params[2]; 833 ctx->Pixel.ColorTableScale[3] = params[3]; 834 } 835 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 836 ctx->Pixel.ColorTableBias[0] = params[0]; 837 ctx->Pixel.ColorTableBias[1] = params[1]; 838 ctx->Pixel.ColorTableBias[2] = params[2]; 839 ctx->Pixel.ColorTableBias[3] = params[3]; 840 } 841 else { 842 _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); 843 return; 844 } 845 break; 846 case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: 847 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 848 ctx->Pixel.PCCTscale[0] = params[0]; 849 ctx->Pixel.PCCTscale[1] = params[1]; 850 ctx->Pixel.PCCTscale[2] = params[2]; 851 ctx->Pixel.PCCTscale[3] = params[3]; 852 } 853 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 854 ctx->Pixel.PCCTbias[0] = params[0]; 855 ctx->Pixel.PCCTbias[1] = params[1]; 856 ctx->Pixel.PCCTbias[2] = params[2]; 857 ctx->Pixel.PCCTbias[3] = params[3]; 858 } 859 else { 860 _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); 861 return; 862 } 863 break; 864 case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: 865 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 866 ctx->Pixel.PCMCTscale[0] = params[0]; 867 ctx->Pixel.PCMCTscale[1] = params[1]; 868 ctx->Pixel.PCMCTscale[2] = params[2]; 869 ctx->Pixel.PCMCTscale[3] = params[3]; 870 } 871 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 872 ctx->Pixel.PCMCTbias[0] = params[0]; 873 ctx->Pixel.PCMCTbias[1] = params[1]; 874 ctx->Pixel.PCMCTbias[2] = params[2]; 875 ctx->Pixel.PCMCTbias[3] = params[3]; 876 } 877 else { 878 _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); 879 return; 880 } 881 break; 882 default: 883 _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)"); 884 return; 885 } 886 887 ctx->NewState |= _NEW_PIXEL; 888} 889 890 891 892void 893_mesa_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params) 894{ 895 GLfloat fparams[4]; 896 if (pname == GL_COLOR_TABLE_SGI || 897 pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI || 898 pname == GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI) { 899 /* four values */ 900 fparams[0] = (GLfloat) params[0]; 901 fparams[1] = (GLfloat) params[1]; 902 fparams[2] = (GLfloat) params[2]; 903 fparams[3] = (GLfloat) params[3]; 904 } 905 else { 906 /* one values */ 907 fparams[0] = (GLfloat) params[0]; 908 } 909 _mesa_ColorTableParameterfv(target, pname, fparams); 910} 911 912 913 914void 915_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params ) 916{ 917 GET_CURRENT_CONTEXT(ctx); 918 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 919 struct gl_color_table *table = NULL; 920 ASSERT_OUTSIDE_BEGIN_END(ctx); 921 922 switch (target) { 923 case GL_TEXTURE_1D: 924 table = &texUnit->Current1D->Palette; 925 break; 926 case GL_TEXTURE_2D: 927 table = &texUnit->Current2D->Palette; 928 break; 929 case GL_TEXTURE_3D: 930 table = &texUnit->Current3D->Palette; 931 break; 932 case GL_PROXY_TEXTURE_1D: 933 table = &ctx->Texture.Proxy1D->Palette; 934 break; 935 case GL_PROXY_TEXTURE_2D: 936 table = &ctx->Texture.Proxy2D->Palette; 937 break; 938 case GL_PROXY_TEXTURE_3D: 939 table = &ctx->Texture.Proxy3D->Palette; 940 break; 941 case GL_SHARED_TEXTURE_PALETTE_EXT: 942 table = &ctx->Texture.Palette; 943 break; 944 case GL_COLOR_TABLE: 945 table = &ctx->ColorTable; 946 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 947 params[0] = ctx->Pixel.ColorTableScale[0]; 948 params[1] = ctx->Pixel.ColorTableScale[1]; 949 params[2] = ctx->Pixel.ColorTableScale[2]; 950 params[3] = ctx->Pixel.ColorTableScale[3]; 951 return; 952 } 953 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 954 params[0] = ctx->Pixel.ColorTableBias[0]; 955 params[1] = ctx->Pixel.ColorTableBias[1]; 956 params[2] = ctx->Pixel.ColorTableBias[2]; 957 params[3] = ctx->Pixel.ColorTableBias[3]; 958 return; 959 } 960 break; 961 case GL_PROXY_COLOR_TABLE: 962 table = &ctx->ProxyColorTable; 963 break; 964 case GL_POST_CONVOLUTION_COLOR_TABLE: 965 table = &ctx->PostConvolutionColorTable; 966 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 967 params[0] = ctx->Pixel.PCCTscale[0]; 968 params[1] = ctx->Pixel.PCCTscale[1]; 969 params[2] = ctx->Pixel.PCCTscale[2]; 970 params[3] = ctx->Pixel.PCCTscale[3]; 971 return; 972 } 973 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 974 params[0] = ctx->Pixel.PCCTbias[0]; 975 params[1] = ctx->Pixel.PCCTbias[1]; 976 params[2] = ctx->Pixel.PCCTbias[2]; 977 params[3] = ctx->Pixel.PCCTbias[3]; 978 return; 979 } 980 break; 981 case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE: 982 table = &ctx->ProxyPostConvolutionColorTable; 983 break; 984 case GL_POST_COLOR_MATRIX_COLOR_TABLE: 985 table = &ctx->PostColorMatrixColorTable; 986 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 987 params[0] = ctx->Pixel.PCMCTscale[0]; 988 params[1] = ctx->Pixel.PCMCTscale[1]; 989 params[2] = ctx->Pixel.PCMCTscale[2]; 990 params[3] = ctx->Pixel.PCMCTscale[3]; 991 return; 992 } 993 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 994 params[0] = ctx->Pixel.PCMCTbias[0]; 995 params[1] = ctx->Pixel.PCMCTbias[1]; 996 params[2] = ctx->Pixel.PCMCTbias[2]; 997 params[3] = ctx->Pixel.PCMCTbias[3]; 998 return; 999 } 1000 break; 1001 case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE: 1002 table = &ctx->ProxyPostColorMatrixColorTable; 1003 break; 1004 default: 1005 _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(target)"); 1006 return; 1007 } 1008 1009 assert(table); 1010 1011 switch (pname) { 1012 case GL_COLOR_TABLE_FORMAT: 1013 *params = table->IntFormat; 1014 break; 1015 case GL_COLOR_TABLE_WIDTH: 1016 *params = table->Size; 1017 break; 1018 case GL_COLOR_TABLE_RED_SIZE: 1019 *params = table->RedSize; 1020 break; 1021 case GL_COLOR_TABLE_GREEN_SIZE: 1022 *params = table->GreenSize; 1023 break; 1024 case GL_COLOR_TABLE_BLUE_SIZE: 1025 *params = table->BlueSize; 1026 break; 1027 case GL_COLOR_TABLE_ALPHA_SIZE: 1028 *params = table->AlphaSize; 1029 break; 1030 case GL_COLOR_TABLE_LUMINANCE_SIZE: 1031 *params = table->LuminanceSize; 1032 break; 1033 case GL_COLOR_TABLE_INTENSITY_SIZE: 1034 *params = table->IntensitySize; 1035 break; 1036 default: 1037 _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(pname)" ); 1038 return; 1039 } 1040} 1041 1042 1043 1044void 1045_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params ) 1046{ 1047 GET_CURRENT_CONTEXT(ctx); 1048 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1049 struct gl_color_table *table = NULL; 1050 ASSERT_OUTSIDE_BEGIN_END(ctx); 1051 1052 switch (target) { 1053 case GL_TEXTURE_1D: 1054 table = &texUnit->Current1D->Palette; 1055 break; 1056 case GL_TEXTURE_2D: 1057 table = &texUnit->Current2D->Palette; 1058 break; 1059 case GL_TEXTURE_3D: 1060 table = &texUnit->Current3D->Palette; 1061 break; 1062 case GL_PROXY_TEXTURE_1D: 1063 table = &ctx->Texture.Proxy1D->Palette; 1064 break; 1065 case GL_PROXY_TEXTURE_2D: 1066 table = &ctx->Texture.Proxy2D->Palette; 1067 break; 1068 case GL_PROXY_TEXTURE_3D: 1069 table = &ctx->Texture.Proxy3D->Palette; 1070 break; 1071 case GL_SHARED_TEXTURE_PALETTE_EXT: 1072 table = &ctx->Texture.Palette; 1073 break; 1074 case GL_COLOR_TABLE: 1075 table = &ctx->ColorTable; 1076 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 1077 params[0] = (GLint) ctx->Pixel.ColorTableScale[0]; 1078 params[1] = (GLint) ctx->Pixel.ColorTableScale[1]; 1079 params[2] = (GLint) ctx->Pixel.ColorTableScale[2]; 1080 params[3] = (GLint) ctx->Pixel.ColorTableScale[3]; 1081 return; 1082 } 1083 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 1084 params[0] = (GLint) ctx->Pixel.ColorTableBias[0]; 1085 params[1] = (GLint) ctx->Pixel.ColorTableBias[1]; 1086 params[2] = (GLint) ctx->Pixel.ColorTableBias[2]; 1087 params[3] = (GLint) ctx->Pixel.ColorTableBias[3]; 1088 return; 1089 } 1090 break; 1091 case GL_PROXY_COLOR_TABLE: 1092 table = &ctx->ProxyColorTable; 1093 break; 1094 case GL_POST_CONVOLUTION_COLOR_TABLE: 1095 table = &ctx->PostConvolutionColorTable; 1096 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 1097 params[0] = (GLint) ctx->Pixel.PCCTscale[0]; 1098 params[1] = (GLint) ctx->Pixel.PCCTscale[1]; 1099 params[2] = (GLint) ctx->Pixel.PCCTscale[2]; 1100 params[3] = (GLint) ctx->Pixel.PCCTscale[3]; 1101 return; 1102 } 1103 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 1104 params[0] = (GLint) ctx->Pixel.PCCTbias[0]; 1105 params[1] = (GLint) ctx->Pixel.PCCTbias[1]; 1106 params[2] = (GLint) ctx->Pixel.PCCTbias[2]; 1107 params[3] = (GLint) ctx->Pixel.PCCTbias[3]; 1108 return; 1109 } 1110 break; 1111 case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE: 1112 table = &ctx->ProxyPostConvolutionColorTable; 1113 break; 1114 case GL_POST_COLOR_MATRIX_COLOR_TABLE: 1115 table = &ctx->PostColorMatrixColorTable; 1116 if (pname == GL_COLOR_TABLE_SCALE_SGI) { 1117 params[0] = (GLint) ctx->Pixel.PCMCTscale[0]; 1118 params[1] = (GLint) ctx->Pixel.PCMCTscale[1]; 1119 params[2] = (GLint) ctx->Pixel.PCMCTscale[2]; 1120 params[3] = (GLint) ctx->Pixel.PCMCTscale[3]; 1121 return; 1122 } 1123 else if (pname == GL_COLOR_TABLE_BIAS_SGI) { 1124 params[0] = (GLint) ctx->Pixel.PCMCTbias[0]; 1125 params[1] = (GLint) ctx->Pixel.PCMCTbias[1]; 1126 params[2] = (GLint) ctx->Pixel.PCMCTbias[2]; 1127 params[3] = (GLint) ctx->Pixel.PCMCTbias[3]; 1128 return; 1129 } 1130 break; 1131 case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE: 1132 table = &ctx->ProxyPostColorMatrixColorTable; 1133 break; 1134 default: 1135 _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(target)"); 1136 return; 1137 } 1138 1139 assert(table); 1140 1141 switch (pname) { 1142 case GL_COLOR_TABLE_FORMAT: 1143 *params = table->IntFormat; 1144 break; 1145 case GL_COLOR_TABLE_WIDTH: 1146 *params = table->Size; 1147 break; 1148 case GL_COLOR_TABLE_RED_SIZE: 1149 *params = table->RedSize; 1150 break; 1151 case GL_COLOR_TABLE_GREEN_SIZE: 1152 *params = table->GreenSize; 1153 break; 1154 case GL_COLOR_TABLE_BLUE_SIZE: 1155 *params = table->BlueSize; 1156 break; 1157 case GL_COLOR_TABLE_ALPHA_SIZE: 1158 *params = table->AlphaSize; 1159 break; 1160 case GL_COLOR_TABLE_LUMINANCE_SIZE: 1161 *params = table->LuminanceSize; 1162 break; 1163 case GL_COLOR_TABLE_INTENSITY_SIZE: 1164 *params = table->IntensitySize; 1165 break; 1166 default: 1167 _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(pname)" ); 1168 return; 1169 } 1170} 1171