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