void GLAPIENTRY _mesa_ColorTable( GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *data ) { static const GLfloat one[4] = { 1.0, 1.0, 1.0, 1.0 }; static const GLfloat zero[4] = { 0.0, 0.0, 0.0, 0.0 }; GET_CURRENT_CONTEXT(ctx); struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); struct gl_texture_object *texObj = NULL; struct gl_color_table *table = NULL; GLboolean proxy = GL_FALSE; GLint baseFormat; const GLfloat *scale = one, *bias = zero; GLint comps; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */ switch (target) { case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; case GL_COLOR_TABLE: table = &ctx->ColorTable[COLORTABLE_PRECONVOLUTION]; scale = ctx->Pixel.ColorTableScale[COLORTABLE_PRECONVOLUTION]; bias = ctx->Pixel.ColorTableBias[COLORTABLE_PRECONVOLUTION]; break; case GL_PROXY_COLOR_TABLE: table = &ctx->ProxyColorTable[COLORTABLE_PRECONVOLUTION]; proxy = GL_TRUE; break; case GL_TEXTURE_COLOR_TABLE_SGI: if (!ctx->Extensions.SGI_texture_color_table) { _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); return; } table = &(texUnit->ColorTable); scale = ctx->Pixel.TextureColorTableScale; bias = ctx->Pixel.TextureColorTableBias; break; case GL_PROXY_TEXTURE_COLOR_TABLE_SGI: if (!ctx->Extensions.SGI_texture_color_table) { _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); return; } table = &(texUnit->ProxyColorTable); proxy = GL_TRUE; break; case GL_POST_CONVOLUTION_COLOR_TABLE: table = &ctx->ColorTable[COLORTABLE_POSTCONVOLUTION]; scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCONVOLUTION]; bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCONVOLUTION]; break; case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE: table = &ctx->ProxyColorTable[COLORTABLE_POSTCONVOLUTION]; proxy = GL_TRUE; break; case GL_POST_COLOR_MATRIX_COLOR_TABLE: table = &ctx->ColorTable[COLORTABLE_POSTCOLORMATRIX]; scale = ctx->Pixel.ColorTableScale[COLORTABLE_POSTCOLORMATRIX]; bias = ctx->Pixel.ColorTableBias[COLORTABLE_POSTCOLORMATRIX]; break; case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE: table = &ctx->ProxyColorTable[COLORTABLE_POSTCOLORMATRIX]; proxy = GL_TRUE; break; default: /* try texture targets */ { struct gl_texture_object *texobj = _mesa_select_tex_object(ctx, texUnit, target); if (texobj) { table = &texobj->Palette; proxy = _mesa_is_proxy_texture(target); } else { _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); return; } } } assert(table); if (!_mesa_is_legal_format_and_type(ctx, format, type) || format == GL_INTENSITY) { _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTable(format or type)"); return; } baseFormat = base_colortab_format(internalFormat); if (baseFormat < 0) { _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(internalFormat)"); return; } if (width < 0 || (width != 0 && !_mesa_is_pow_two(width))) { /* error */ if (proxy) { table->Size = 0; table->InternalFormat = (GLenum) 0; table->_BaseFormat = (GLenum) 0; } else { _mesa_error(ctx, GL_INVALID_VALUE, "glColorTable(width=%d)", width); } return; } if (width > (GLsizei) ctx->Const.MaxColorTableSize) { if (proxy) { table->Size = 0; table->InternalFormat = (GLenum) 0; table->_BaseFormat = (GLenum) 0; } else { _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glColorTable(width)"); } return; } table->Size = width; table->InternalFormat = internalFormat; table->_BaseFormat = (GLenum) baseFormat; comps = _mesa_components_in_format(table->_BaseFormat); assert(comps > 0); /* error should have been caught sooner */ if (!proxy) { _mesa_free_colortable_data(table); if (width > 0) { table->TableF = (GLfloat *) _mesa_malloc(comps * width * sizeof(GLfloat)); table->TableUB = (GLubyte *) _mesa_malloc(comps * width * sizeof(GLubyte)); if (!table->TableF || !table->TableUB) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable"); return; } store_colortable_entries(ctx, table, 0, width, /* start, count */ format, type, data, scale[0], bias[0], scale[1], bias[1], scale[2], bias[2], scale[3], bias[3]); } } /* proxy */ /* do this after the table's Type and Format are set */ set_component_sizes(table); if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) { /* texture object palette, texObj==NULL means the shared palette */ if (ctx->Driver.UpdateTexturePalette) { (*ctx->Driver.UpdateTexturePalette)( ctx, texObj ); } } ctx->NewState |= _NEW_PIXEL; }
void GLAPIENTRY _mesa_ColorTable( GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *data ) { GET_CURRENT_CONTEXT(ctx); struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; struct gl_texture_object *texObj = NULL; struct gl_color_table *table = NULL; GLboolean proxy = GL_FALSE; GLint baseFormat; GLfloat rScale = 1.0, gScale = 1.0, bScale = 1.0, aScale = 1.0; GLfloat rBias = 0.0, gBias = 0.0, bBias = 0.0, aBias = 0.0; GLenum tableType = CHAN_TYPE; GLint comps; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */ switch (target) { case GL_TEXTURE_1D: texObj = texUnit->Current1D; table = &texObj->Palette; break; case GL_TEXTURE_2D: texObj = texUnit->Current2D; table = &texObj->Palette; break; case GL_TEXTURE_3D: texObj = texUnit->Current3D; table = &texObj->Palette; break; case GL_TEXTURE_CUBE_MAP_ARB: if (!ctx->Extensions.ARB_texture_cube_map) { _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); return; } texObj = texUnit->CurrentCubeMap; table = &texObj->Palette; break; case GL_PROXY_TEXTURE_1D: texObj = ctx->Texture.Proxy1D; table = &texObj->Palette; proxy = GL_TRUE; break; case GL_PROXY_TEXTURE_2D: texObj = ctx->Texture.Proxy2D; table = &texObj->Palette; proxy = GL_TRUE; break; case GL_PROXY_TEXTURE_3D: texObj = ctx->Texture.Proxy3D; table = &texObj->Palette; proxy = GL_TRUE; break; case GL_PROXY_TEXTURE_CUBE_MAP_ARB: if (!ctx->Extensions.ARB_texture_cube_map) { _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); return; } texObj = ctx->Texture.ProxyCubeMap; table = &texObj->Palette; break; case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; case GL_COLOR_TABLE: table = &ctx->ColorTable; tableType = GL_FLOAT; rScale = ctx->Pixel.ColorTableScale[0]; gScale = ctx->Pixel.ColorTableScale[1]; bScale = ctx->Pixel.ColorTableScale[2]; aScale = ctx->Pixel.ColorTableScale[3]; rBias = ctx->Pixel.ColorTableBias[0]; gBias = ctx->Pixel.ColorTableBias[1]; bBias = ctx->Pixel.ColorTableBias[2]; aBias = ctx->Pixel.ColorTableBias[3]; break; case GL_PROXY_COLOR_TABLE: table = &ctx->ProxyColorTable; proxy = GL_TRUE; break; case GL_TEXTURE_COLOR_TABLE_SGI: if (!ctx->Extensions.SGI_texture_color_table) { _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); return; } table = &(texUnit->ColorTable); tableType = GL_FLOAT; rScale = ctx->Pixel.TextureColorTableScale[0]; gScale = ctx->Pixel.TextureColorTableScale[1]; bScale = ctx->Pixel.TextureColorTableScale[2]; aScale = ctx->Pixel.TextureColorTableScale[3]; rBias = ctx->Pixel.TextureColorTableBias[0]; gBias = ctx->Pixel.TextureColorTableBias[1]; bBias = ctx->Pixel.TextureColorTableBias[2]; aBias = ctx->Pixel.TextureColorTableBias[3]; break; case GL_PROXY_TEXTURE_COLOR_TABLE_SGI: if (!ctx->Extensions.SGI_texture_color_table) { _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); return; } table = &(texUnit->ProxyColorTable); proxy = GL_TRUE; break; case GL_POST_CONVOLUTION_COLOR_TABLE: table = &ctx->PostConvolutionColorTable; tableType = GL_FLOAT; rScale = ctx->Pixel.PCCTscale[0]; gScale = ctx->Pixel.PCCTscale[1]; bScale = ctx->Pixel.PCCTscale[2]; aScale = ctx->Pixel.PCCTscale[3]; rBias = ctx->Pixel.PCCTbias[0]; gBias = ctx->Pixel.PCCTbias[1]; bBias = ctx->Pixel.PCCTbias[2]; aBias = ctx->Pixel.PCCTbias[3]; break; case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE: table = &ctx->ProxyPostConvolutionColorTable; proxy = GL_TRUE; break; case GL_POST_COLOR_MATRIX_COLOR_TABLE: table = &ctx->PostColorMatrixColorTable; tableType = GL_FLOAT; rScale = ctx->Pixel.PCMCTscale[0]; gScale = ctx->Pixel.PCMCTscale[1]; bScale = ctx->Pixel.PCMCTscale[2]; aScale = ctx->Pixel.PCMCTscale[3]; rBias = ctx->Pixel.PCMCTbias[0]; gBias = ctx->Pixel.PCMCTbias[1]; bBias = ctx->Pixel.PCMCTbias[2]; aBias = ctx->Pixel.PCMCTbias[3]; break; case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE: table = &ctx->ProxyPostColorMatrixColorTable; proxy = GL_TRUE; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); return; } assert(table); if (!_mesa_is_legal_format_and_type(ctx, format, type) || format == GL_INTENSITY) { _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTable(format or type)"); return; } baseFormat = base_colortab_format(internalFormat); if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(internalFormat)"); return; } if (width < 0 || (width != 0 && _mesa_bitcount(width) != 1)) { /* error */ if (proxy) { table->Size = 0; table->IntFormat = (GLenum) 0; table->Format = (GLenum) 0; } else { _mesa_error(ctx, GL_INVALID_VALUE, "glColorTable(width=%d)", width); } return; } if (width > (GLsizei) ctx->Const.MaxColorTableSize) { if (proxy) { table->Size = 0; table->IntFormat = (GLenum) 0; table->Format = (GLenum) 0; } else { _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glColorTable(width)"); } return; } table->Size = width; table->IntFormat = internalFormat; table->Format = (GLenum) baseFormat; set_component_sizes(table); comps = _mesa_components_in_format(table->Format); assert(comps > 0); /* error should have been caught sooner */ if (!proxy) { /* free old table, if any */ if (table->Table) { FREE(table->Table); table->Table = NULL; } if (width > 0) { if (tableType == GL_FLOAT) { table->Type = GL_FLOAT; table->Table = MALLOC(comps * width * sizeof(GLfloat)); } else { table->Type = CHAN_TYPE; table->Table = MALLOC(comps * width * sizeof(GLchan)); } if (!table->Table) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable"); return; } store_colortable_entries(ctx, table, 0, width, /* start, count */ format, type, data, rScale, rBias, gScale, gBias, bScale, bBias, aScale, aBias); } } /* proxy */ if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) { /* texture object palette, texObj==NULL means the shared palette */ if (ctx->Driver.UpdateTexturePalette) { (*ctx->Driver.UpdateTexturePalette)( ctx, texObj ); } } ctx->NewState |= _NEW_PIXEL; }