colortab.c revision 845117bd054862baae29c4df61d5b4a61dd97f62
1/* $Id: colortab.c,v 1.5 1999/11/11 17:50:04 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.3 6 * 7 * Copyright (C) 1999 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#endif 37 38 39 40/* 41 * Return GL_TRUE if k is a power of two, else return GL_FALSE. 42 */ 43static GLboolean 44power_of_two( GLint k ) 45{ 46 GLint i, m = 1; 47 for (i=0; i<32; i++) { 48 if (k == m) 49 return GL_TRUE; 50 m = m << 1; 51 } 52 return GL_FALSE; 53} 54 55 56static GLint 57decode_internal_format( GLint format ) 58{ 59 switch (format) { 60 case GL_ALPHA: 61 case GL_ALPHA4: 62 case GL_ALPHA8: 63 case GL_ALPHA12: 64 case GL_ALPHA16: 65 return GL_ALPHA; 66 case 1: 67 case GL_LUMINANCE: 68 case GL_LUMINANCE4: 69 case GL_LUMINANCE8: 70 case GL_LUMINANCE12: 71 case GL_LUMINANCE16: 72 return GL_LUMINANCE; 73 case 2: 74 case GL_LUMINANCE_ALPHA: 75 case GL_LUMINANCE4_ALPHA4: 76 case GL_LUMINANCE6_ALPHA2: 77 case GL_LUMINANCE8_ALPHA8: 78 case GL_LUMINANCE12_ALPHA4: 79 case GL_LUMINANCE12_ALPHA12: 80 case GL_LUMINANCE16_ALPHA16: 81 return GL_LUMINANCE_ALPHA; 82 case GL_INTENSITY: 83 case GL_INTENSITY4: 84 case GL_INTENSITY8: 85 case GL_INTENSITY12: 86 case GL_INTENSITY16: 87 return GL_INTENSITY; 88 case 3: 89 case GL_RGB: 90 case GL_R3_G3_B2: 91 case GL_RGB4: 92 case GL_RGB5: 93 case GL_RGB8: 94 case GL_RGB10: 95 case GL_RGB12: 96 case GL_RGB16: 97 return GL_RGB; 98 case 4: 99 case GL_RGBA: 100 case GL_RGBA2: 101 case GL_RGBA4: 102 case GL_RGB5_A1: 103 case GL_RGBA8: 104 case GL_RGB10_A2: 105 case GL_RGBA12: 106 case GL_RGBA16: 107 return GL_RGBA; 108 default: 109 return -1; /* error */ 110 } 111} 112 113 114void 115_mesa_ColorTableEXT( GLenum target, GLenum internalFormat, 116 GLsizei width, GLenum format, GLenum type, 117 const GLvoid *table ) 118{ 119 GET_CURRENT_CONTEXT(ctx); 120 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 121 struct gl_texture_object *texObj; 122 struct gl_palette *palette; 123 GLboolean proxy = GL_FALSE; 124 125 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorTableEXT"); 126 127 switch (target) { 128 case GL_TEXTURE_1D: 129 texObj = texUnit->CurrentD[1]; 130 palette = &texObj->Palette; 131 break; 132 case GL_TEXTURE_2D: 133 texObj = texUnit->CurrentD[2]; 134 palette = &texObj->Palette; 135 break; 136 case GL_TEXTURE_3D: 137 texObj = texUnit->CurrentD[3]; 138 palette = &texObj->Palette; 139 break; 140 case GL_PROXY_TEXTURE_1D: 141 texObj = ctx->Texture.Proxy1D; 142 palette = &texObj->Palette; 143 proxy = GL_TRUE; 144 break; 145 case GL_PROXY_TEXTURE_2D: 146 texObj = ctx->Texture.Proxy2D; 147 palette = &texObj->Palette; 148 proxy = GL_TRUE; 149 break; 150 case GL_PROXY_TEXTURE_3D: 151 texObj = ctx->Texture.Proxy3D; 152 palette = &texObj->Palette; 153 proxy = GL_TRUE; 154 break; 155 case GL_SHARED_TEXTURE_PALETTE_EXT: 156 texObj = NULL; 157 palette = &ctx->Texture.Palette; 158 break; 159 default: 160 gl_error(ctx, GL_INVALID_ENUM, "glColorTableEXT(target)"); 161 return; 162 } 163 164 assert(palette); 165 166 if (!gl_is_legal_format_and_type(format, type)) { 167 gl_error(ctx, GL_INVALID_ENUM, "glColorTableEXT(format or type)"); 168 return; 169 } 170 171 if (decode_internal_format(internalFormat) < 0) { 172 gl_error( ctx, GL_INVALID_ENUM, "glColorTableEXT(internalFormat)" ); 173 return; 174 } 175 176 if (width < 1 || width > MAX_TEXTURE_PALETTE_SIZE || !power_of_two(width)) { 177 gl_error(ctx, GL_INVALID_VALUE, "glColorTableEXT(width)"); 178 if (proxy) { 179 palette->Size = 0; 180 palette->IntFormat = (GLenum) 0; 181 palette->Format = (GLenum) 0; 182 } 183 return; 184 } 185 186 palette->Size = width; 187 palette->IntFormat = internalFormat; 188 palette->Format = (GLenum) decode_internal_format(internalFormat); 189 if (!proxy) { 190 _mesa_unpack_ubyte_color_span(ctx, width, palette->Format, 191 palette->Table, /* dest */ 192 format, type, table, 193 &ctx->Unpack, GL_FALSE); 194 } 195 if (texObj) { 196 /* per-texture object palette */ 197 if (ctx->Driver.UpdateTexturePalette) { 198 (*ctx->Driver.UpdateTexturePalette)( ctx, texObj ); 199 } 200 } 201 else { 202 /* shared texture palette */ 203 if (ctx->Driver.UpdateTexturePalette) { 204 (*ctx->Driver.UpdateTexturePalette)( ctx, NULL ); 205 } 206 } 207} 208 209 210 211void 212_mesa_ColorSubTableEXT( GLenum target, GLsizei start, 213 GLsizei count, GLenum format, GLenum type, 214 const GLvoid *table ) 215{ 216 GET_CURRENT_CONTEXT(ctx); 217 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 218 struct gl_texture_object *texObj; 219 struct gl_palette *palette; 220 GLint comps; 221 GLubyte *dest; 222 223 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorSubTable"); 224 225 switch (target) { 226 case GL_TEXTURE_1D: 227 texObj = texUnit->CurrentD[1]; 228 palette = &texObj->Palette; 229 break; 230 case GL_TEXTURE_2D: 231 texObj = texUnit->CurrentD[2]; 232 palette = &texObj->Palette; 233 break; 234 case GL_TEXTURE_3D: 235 texObj = texUnit->CurrentD[3]; 236 palette = &texObj->Palette; 237 break; 238 case GL_SHARED_TEXTURE_PALETTE_EXT: 239 texObj = NULL; 240 palette = &ctx->Texture.Palette; 241 break; 242 default: 243 gl_error(ctx, GL_INVALID_ENUM, "glColorSubTableEXT(target)"); 244 return; 245 } 246 247 assert(palette); 248 249 if (!gl_is_legal_format_and_type(format, type)) { 250 gl_error(ctx, GL_INVALID_ENUM, "glColorSubTableEXT(format or type)"); 251 return; 252 } 253 254 if (count < 1) { 255 gl_error(ctx, GL_INVALID_VALUE, "glColorSubTableEXT(count)"); 256 return; 257 } 258 259 comps = gl_components_in_format(format); 260 assert(comps > 0); /* error should be caught sooner */ 261 262 if (start + count > palette->Size) { 263 gl_error(ctx, GL_INVALID_VALUE, "glColorSubTableEXT(count)"); 264 return; 265 } 266 dest = palette->Table + start * comps * sizeof(GLubyte); 267 _mesa_unpack_ubyte_color_span(ctx, count, palette->Format, dest, 268 format, type, table, 269 &ctx->Unpack, GL_FALSE); 270 271 if (texObj) { 272 /* per-texture object palette */ 273 if (ctx->Driver.UpdateTexturePalette) { 274 (*ctx->Driver.UpdateTexturePalette)( ctx, texObj ); 275 } 276 } 277 else { 278 /* shared texture palette */ 279 if (ctx->Driver.UpdateTexturePalette) { 280 (*ctx->Driver.UpdateTexturePalette)( ctx, NULL ); 281 } 282 } 283} 284 285 286 287void 288_mesa_GetColorTableEXT( GLenum target, GLenum format, 289 GLenum type, GLvoid *table ) 290{ 291 GET_CURRENT_CONTEXT(ctx); 292 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 293 struct gl_palette *palette; 294 GLubyte rgba[MAX_TEXTURE_PALETTE_SIZE][4]; 295 GLint i; 296 297 ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetColorTableEXT"); 298 299 switch (target) { 300 case GL_TEXTURE_1D: 301 palette = &texUnit->CurrentD[1]->Palette; 302 break; 303 case GL_TEXTURE_2D: 304 palette = &texUnit->CurrentD[2]->Palette; 305 break; 306 case GL_TEXTURE_3D: 307 palette = &texUnit->CurrentD[3]->Palette; 308 break; 309 case GL_SHARED_TEXTURE_PALETTE_EXT: 310 palette = &ctx->Texture.Palette; 311 break; 312 default: 313 gl_error(ctx, GL_INVALID_ENUM, "glGetColorTableEXT(target)"); 314 return; 315 } 316 317 assert(palette); 318 319 switch (palette->Format) { 320 case GL_ALPHA: 321 for (i = 0; i < palette->Size; i++) { 322 rgba[i][RCOMP] = 0; 323 rgba[i][GCOMP] = 0; 324 rgba[i][BCOMP] = 0; 325 rgba[i][ACOMP] = palette->Table[i]; 326 } 327 break; 328 case GL_LUMINANCE: 329 for (i = 0; i < palette->Size; i++) { 330 rgba[i][RCOMP] = palette->Table[i]; 331 rgba[i][GCOMP] = palette->Table[i]; 332 rgba[i][BCOMP] = palette->Table[i]; 333 rgba[i][ACOMP] = 255; 334 } 335 break; 336 case GL_LUMINANCE_ALPHA: 337 for (i = 0; i < palette->Size; i++) { 338 rgba[i][RCOMP] = palette->Table[i*2+0]; 339 rgba[i][GCOMP] = palette->Table[i*2+0]; 340 rgba[i][BCOMP] = palette->Table[i*2+0]; 341 rgba[i][ACOMP] = palette->Table[i*2+1]; 342 } 343 break; 344 case GL_INTENSITY: 345 for (i = 0; i < palette->Size; i++) { 346 rgba[i][RCOMP] = palette->Table[i]; 347 rgba[i][GCOMP] = palette->Table[i]; 348 rgba[i][BCOMP] = palette->Table[i]; 349 rgba[i][ACOMP] = 255; 350 } 351 break; 352 case GL_RGB: 353 for (i = 0; i < palette->Size; i++) { 354 rgba[i][RCOMP] = palette->Table[i*3+0]; 355 rgba[i][GCOMP] = palette->Table[i*3+1]; 356 rgba[i][BCOMP] = palette->Table[i*3+2]; 357 rgba[i][ACOMP] = 255; 358 } 359 break; 360 case GL_RGBA: 361 for (i = 0; i < palette->Size; i++) { 362 rgba[i][RCOMP] = palette->Table[i*4+0]; 363 rgba[i][GCOMP] = palette->Table[i*4+1]; 364 rgba[i][BCOMP] = palette->Table[i*4+2]; 365 rgba[i][ACOMP] = palette->Table[i*4+3]; 366 } 367 break; 368 default: 369 gl_problem(ctx, "bad palette format in glGetColorTableEXT"); 370 return; 371 } 372 373 gl_pack_rgba_span(ctx, palette->Size, (const GLubyte (*)[]) rgba, 374 format, type, table, &ctx->Pack, GL_FALSE); 375 376 (void) format; 377 (void) type; 378 (void) table; 379} 380 381 382 383void 384_mesa_GetColorTableParameterfvEXT( GLenum target, GLenum pname, GLfloat *params ) 385{ 386 GLint iparams[10]; 387 _mesa_GetColorTableParameterivEXT( target, pname, iparams ); 388 *params = (GLfloat) iparams[0]; 389} 390 391 392 393void 394_mesa_GetColorTableParameterivEXT( GLenum target, GLenum pname, GLint *params ) 395{ 396 GET_CURRENT_CONTEXT(ctx); 397 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 398 struct gl_palette *palette; 399 400 ASSERT_OUTSIDE_BEGIN_END(ctx, "glGetColorTableParameterEXT"); 401 402 switch (target) { 403 case GL_TEXTURE_1D: 404 palette = &texUnit->CurrentD[1]->Palette; 405 break; 406 case GL_TEXTURE_2D: 407 palette = &texUnit->CurrentD[2]->Palette; 408 break; 409 case GL_TEXTURE_3D: 410 palette = &texUnit->CurrentD[3]->Palette; 411 break; 412 case GL_SHARED_TEXTURE_PALETTE_EXT: 413 palette = &ctx->Texture.Palette; 414 break; 415 default: 416 gl_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterEXT(target)"); 417 return; 418 } 419 420 switch (pname) { 421 case GL_COLOR_TABLE_FORMAT: 422 *params = palette->IntFormat; 423 break; 424 case GL_COLOR_TABLE_WIDTH: 425 *params = palette->Size; 426 break; 427 case GL_COLOR_TABLE_RED_SIZE: 428 *params = 8; 429 break; 430 case GL_COLOR_TABLE_GREEN_SIZE: 431 *params = 8; 432 break; 433 case GL_COLOR_TABLE_BLUE_SIZE: 434 *params = 8; 435 break; 436 case GL_COLOR_TABLE_ALPHA_SIZE: 437 *params = 8; 438 break; 439 case GL_COLOR_TABLE_LUMINANCE_SIZE: 440 *params = 8; 441 break; 442 case GL_COLOR_TABLE_INTENSITY_SIZE: 443 *params = 8; 444 break; 445 default: 446 gl_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterEXT" ); 447 return; 448 } 449} 450 451 452