From ed5af01d7c4ac4722dd82edc8d33179166899e02 Mon Sep 17 00:00:00 2001 From: danij Date: Sat, 16 Nov 2013 07:53:07 +0000 Subject: [PATCH] Refactor|ColorPalette|Resources: Translated ColorPalette to C++ --- doomsday/client/include/gl/gl_main.h | 12 +- doomsday/client/include/gl/gl_tex.h | 44 ++- .../client/include/resource/colorpalette.h | 176 +++++----- .../client/include/resource/colorpalettes.h | 4 +- doomsday/client/src/gl/gl_main.cpp | 18 +- doomsday/client/src/gl/gl_tex.cpp | 109 +++--- doomsday/client/src/resource/colorpalette.cpp | 327 +++++++----------- .../client/src/resource/colorpalettes.cpp | 146 ++++---- doomsday/client/src/resource/fontscheme.cpp | 2 +- .../client/src/resource/texturescheme.cpp | 2 +- 10 files changed, 396 insertions(+), 444 deletions(-) diff --git a/doomsday/client/include/gl/gl_main.h b/doomsday/client/include/gl/gl_main.h index 8885b6639f..0326ce8a46 100644 --- a/doomsday/client/include/gl/gl_main.h +++ b/doomsday/client/include/gl/gl_main.h @@ -19,8 +19,8 @@ * 02110-1301 USA */ -#ifndef LIBDENG_GL_MAIN_H -#define LIBDENG_GL_MAIN_H +#ifndef DENG_GL_MAIN_H +#define DENG_GL_MAIN_H #ifndef __CLIENT__ # error "gl only exists in the Client" @@ -37,11 +37,11 @@ #include "render/r_main.h" #include "Texture" -struct colorpalette_s; struct ColorRawf_s; struct material_s; struct texturevariant_s; +class ColorPalette; class Material; DENG_EXTERN_C int numTexUnits; @@ -262,7 +262,7 @@ int GL_ChooseSmartFilter(int width, int height, int flags); * 4 = RGBA */ uint8_t *GL_ConvertBuffer(uint8_t const *src, int width, int height, - int informat, struct colorpalette_s *palette, int outformat); + int informat, ColorPalette const *palette, int outformat); /** * @param method Unique identifier of the smart filtering method to apply. @@ -285,10 +285,10 @@ uint8_t *GL_SmartFilter(int method, uint8_t const *src, int width, int height, * Handles pixel sizes; 1 (==2), 3 and 4. */ void GL_CalcLuminance(uint8_t const *buffer, int width, int height, int comps, - struct colorpalette_s *palette, float *brightX, float *brightY, + ColorPalette const *palette, float *brightX, float *brightY, struct ColorRawf_s *color, float *lumSize); // Console commands. D_CMD(UpdateGammaRamp); -#endif /* LIBDENG_GL_MAIN_H */ +#endif // DENG_GL_MAIN_H diff --git a/doomsday/client/include/gl/gl_tex.h b/doomsday/client/include/gl/gl_tex.h index 0ba7b7d6bf..c0183f1741 100644 --- a/doomsday/client/include/gl/gl_tex.h +++ b/doomsday/client/include/gl/gl_tex.h @@ -1,9 +1,11 @@ -/** - * @file gl_tex.h - * Image manipulation and evaluation algorithms. @ingroup gl +/** @file gl_tex.h Image manipulation and evaluation algorithms. + * + * @ingroup gl * - * @authors Copyright © 2003-2013 Jaakko Keränen - * @authors Copyright © 2006-2013 Daniel Swanson + * @todo Belongs in the resource domain -- no ties to GL or related components. + * + * @authors Copyright © 2003-2013 Jaakko Keränen + * @authors Copyright © 2006-2013 Daniel Swanson * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -20,11 +22,13 @@ * 02110-1301 USA */ -#ifndef LIBDENG_IMAGE_MANIPULATION_H -#define LIBDENG_IMAGE_MANIPULATION_H +#ifndef DENG_GL_IMAGE_MANIPULATION_H +#define DENG_GL_IMAGE_MANIPULATION_H #include "color.h" +class ColorPalette; + typedef struct colorpalette_analysis_s { colorpaletteid_t paletteId; } colorpalette_analysis_t; @@ -43,10 +47,6 @@ typedef struct averagealpha_analysis_s { float coverage; ///< Fraction representing the ratio of alpha to non-alpha pixels. } averagealpha_analysis_t; -#ifdef __cplusplus -extern "C" { -#endif - /** * @param pixels Luminance image to be enhanced. * @param width Width of the image in pixels. @@ -155,7 +155,7 @@ void FindAverageColor(const uint8_t* pixels, int width, int height, * @param color Determined average color written here. */ void FindAverageColorIdx(const uint8_t* pixels, int width, int height, - const struct colorpalette_s* palette, boolean hasAlpha, ColorRawf* color); + ColorPalette const *palette, boolean hasAlpha, ColorRawf* color); /** * @param pixels RGB(a) image to evaluate. @@ -178,7 +178,7 @@ void FindAverageLineColor(const uint8_t* pixels, int width, int height, * @param color Determined average color written here. */ void FindAverageLineColorIdx(const uint8_t* pixels, int width, int height, - int line, const struct colorpalette_s* palette, boolean hasAlpha, ColorRawf* color); + int line, ColorPalette const *palette, boolean hasAlpha, ColorRawf* color); /** * @param pixels RGB(a) image to evaluate. @@ -200,7 +200,7 @@ void FindAverageAlpha(const uint8_t* pixels, int width, int height, int pixelSiz * @param coverage Fraction representing the ratio of alpha to non-alpha pixels. */ void FindAverageAlphaIdx(const uint8_t* pixels, int width, int height, - const struct colorpalette_s* palette, float* alpha, float* coverage); + ColorPalette const *palette, float* alpha, float* coverage); /** * Calculates a clip region for the image that excludes alpha pixels. @@ -259,22 +259,18 @@ void GL_DownMipmap32(uint8_t* pixels, int width, int height, int pixelSize); */ void GL_DownMipmap8(uint8_t* in, uint8_t* fadedOut, int width, int height, float fade); -boolean GL_PalettizeImage(uint8_t* out, int outformat, const struct colorpalette_s* palette, - boolean gammaCorrect, const uint8_t* in, int informat, int width, int height); +boolean GL_PalettizeImage(uint8_t *out, int outformat, ColorPalette const *palette, + boolean gammaCorrect, uint8_t const *in, int informat, int width, int height); -boolean GL_QuantizeImageToPalette(uint8_t* out, int outformat, - struct colorpalette_s* palette, const uint8_t* in, int informat, int width, int height); +boolean GL_QuantizeImageToPalette(uint8_t *out, int outformat, + ColorPalette const *palette, uint8_t const *in, int informat, int width, int height); /** * Desaturates the texture in the dest buffer by averaging the colour then * looking up the nearest match in the palette. Increases the brightness * to maximum. */ -void GL_DeSaturatePalettedImage(uint8_t* buffer, struct colorpalette_s* palette, +void GL_DeSaturatePalettedImage(uint8_t *buffer, ColorPalette const *palette, int width, int height); -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // LIBDENG_IMAGE_MANIPULATION_H +#endif // DENG_GL_IMAGE_MANIPULATION_H diff --git a/doomsday/client/include/resource/colorpalette.h b/doomsday/client/include/resource/colorpalette.h index d87339b5b1..a511e224fc 100644 --- a/doomsday/client/include/resource/colorpalette.h +++ b/doomsday/client/include/resource/colorpalette.h @@ -1,7 +1,6 @@ -/** - * @file colorpalette.h Color Palette. +/** @file colorpalette.h Color palette resource. * - * @author Copyright © 2009-2013 Daniel Swanson + * @authors Copyright © 2009-2013 Daniel Swanson * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -18,99 +17,92 @@ * 02110-1301 USA */ -#ifndef LIBDENG_RESOURCE_COLORPALETTE_H -#define LIBDENG_RESOURCE_COLORPALETTE_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup colorPaletteFlags Color Palette Flags - * @ingroup flags - */ -///@{ -#define CPF_UPDATE_18TO8 0x1 /// The 18To8 LUT needs updating. -///@} +#ifndef DENG_RESOURCE_COLORPALETTE_H +#define DENG_RESOURCE_COLORPALETTE_H -#define COLORPALETTE_MAX_COMPONENT_BITS (16) // Max bits per component. +#include "dd_types.h" +#include /** * Color Palette. * * @ingroup resource */ -typedef struct colorpalette_s { - /// @ref colorPaletteFlags - uint8_t _flags; - - /// R8G8B88 color triplets [_num * 3]. - uint8_t *_colorData; - int _colorCount; - - /// Nearest color lookup table. - int *_18To8LUT; -} colorpalette_t; - -colorpalette_t* ColorPalette_New(void); - -/** - * Constructs a new color palette. - * - * @param compOrder Component order. Examples: - *
 [0,1,2] == RGB
- * [2,1,0] == BGR
- * @param compBits Number of bits per component [R,G,B]. - * @param colorData Color triplets (at least @a numColors * 3). - * @param colorCount Number of color triplets. - */ -colorpalette_t *ColorPalette_NewWithColorTable(int const compOrder[3], - uint8_t const compBits[3], uint8_t const *colorData, int colorCount); - -void ColorPalette_Delete(colorpalette_t *pal); - -/// @return Number of colors in the palette. -ushort ColorPalette_Size(colorpalette_t *pal); - -/** - * Replace the entire color table. - * - * @param pal Color palette. - * @param compOrder Component order. Examples: - *
 [0,1,2] == RGB
- * [2,1,0] == BGR
- * @param compBits Number of bits per component [R,G,B]. - * @param colorData Color triplets (at least @a numColors * 3). - * @param colorCount Number of color triplets. - */ -void ColorPalette_ReplaceColorTable(colorpalette_t *pal, int const compOrder[3], - uint8_t const compBits[3], uint8_t const *colorData, int colorCount); - -/** - * Lookup a color in the palette. - * - * @note If the specified color index is out of range it will be clamped to - * a valid value before use. - * - * @param pal Color palette. - * @param colorIdx Index of the color to lookup. - * @param rgb Associated R8G8B8 color triplet is written here. - */ -void ColorPalette_Color(colorpalette_t const *pal, int colorIdx, uint8_t rgb[3]); - -/** - * Given an R8G8B8 color triplet return the closet matching color index. - * - * @param pal Color palette. - * @param rgb R8G8B8 color to be matched. - * - * @return Closet matching color index or @c -1 if no colors in the palette. - */ -int ColorPalette_NearestIndexv(colorpalette_t *pal, uint8_t const rgb[3]); -int ColorPalette_NearestIndex(colorpalette_t *pal, uint8_t red, uint8_t green, uint8_t blue); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif /* LIBDENG_RESOURCE_COLORPALETTE_H */ +class ColorPalette +{ +public: + /// Maximum number of bits per color component. + static int const max_component_bits = 16; + +public: + /** + * Construct a new empty color palette. + */ + ColorPalette(); + + /** + * Constructs a new color palette using the specified color table. + * + * @param compOrder Component order. Examples: + *
 [0,1,2] == RGB
+     * [2,1,0] == BGR
+     * 
+ * + * @param compBits Number of bits per component [R,G,B]. + * @param colorData Color triplets (at least @a numColors * 3). + * @param colorCount Number of color triplets. + */ + ColorPalette(int const compOrder[3], uint8_t const compBits[3], + uint8_t const *colorData, int colorCount); + + /** + * Returns the total number of colors in the palette. + */ + int size() const; + + /** + * Replace the entire color table. + * + * @param compOrder Component order. Examples: + *
 [0,1,2] == RGB
+     * [2,1,0] == BGR
+     * 
+ * + * @param compBits Number of bits per component [R,G,B]. + * @param colorData Color triplets (at least @a numColors * 3). + * @param colorCount Number of color triplets. + */ + void replaceColorTable(int const compOrder[3], uint8_t const compBits[3], + uint8_t const *colorData, int colorCount); + + /** + * Lookup a color in the palette by @a colorIndex. If the specified index is + * out of valid [0..colorCount) range it will be clamped. + * + * @param colorIndex Index of the color in the palette. + * + * @return Associated R8G8B8 color triplet. + * + * @see colorf() + */ + de::Vector3ub color(int colorIndex) const; + + /** + * Same as @ref color() except the color is returned in [0..1] floating-point. + */ + de::Vector3f colorf(int colorIndex) const; + + /** + * Given an R8G8B8 color triplet return the closet matching color index. + * + * @param rgb R8G8B8 color to be matched. + * + * @return Closet matching color index or @c -1 if no colors in the palette. + */ + int nearestIndex(de::Vector3ub const &rgb) const; + +private: + DENG2_PRIVATE(d) +}; + +#endif // DENG_RESOURCE_COLORPALETTE_H diff --git a/doomsday/client/include/resource/colorpalettes.h b/doomsday/client/include/resource/colorpalettes.h index b5b7b4af06..f6f4790d3f 100644 --- a/doomsday/client/include/resource/colorpalettes.h +++ b/doomsday/client/include/resource/colorpalettes.h @@ -51,13 +51,13 @@ void R_DestroyColorPalettes(void); int R_ColorPaletteCount(void); /// @return ColorPalette associated with unique @a id, else @c NULL. -colorpalette_t *R_ToColorPalette(colorpaletteid_t id); +ColorPalette *R_ToColorPalette(colorpaletteid_t id); /** * Given a color palette list index return the ColorPalette. * @return ColorPalette if found else @c NULL */ -colorpalette_t *R_GetColorPaletteByIndex(int paletteIdx); +ColorPalette *R_GetColorPaletteByIndex(int paletteIdx); /** * Change the default color palette. diff --git a/doomsday/client/src/gl/gl_main.cpp b/doomsday/client/src/gl/gl_main.cpp index 6e78138759..8e437073d9 100644 --- a/doomsday/client/src/gl/gl_main.cpp +++ b/doomsday/client/src/gl/gl_main.cpp @@ -989,12 +989,12 @@ uint8_t* GL_SmartFilter(int method, const uint8_t* src, int width, int height, return out; } -uint8_t* GL_ConvertBuffer(const uint8_t* in, int width, int height, int informat, - colorpalette_t* palette, int outformat) +uint8_t *GL_ConvertBuffer(uint8_t const *in, int width, int height, int informat, + ColorPalette const *palette, int outformat) { - assert(in); - { - uint8_t* out; + DENG2_ASSERT(in != 0); + + uint8_t *out; if(width <= 0 || height <= 0) { @@ -1048,11 +1048,10 @@ uint8_t* GL_ConvertBuffer(const uint8_t* in, int width, int height, int informat } } return out; - } } void GL_CalcLuminance(uint8_t const *buffer, int width, int height, int pixelSize, - colorpalette_t *palette, float *retBrightX, float *retBrightY, + ColorPalette const *palette, float *retBrightX, float *retBrightY, ColorRawf *retColor, float *retLumSize) { DENG_ASSERT(buffer && retBrightX && retBrightY && retColor && retLumSize); @@ -1133,7 +1132,10 @@ void GL_CalcLuminance(uint8_t const *buffer, int width, int height, int pixelSiz if(pixelSize == 1) { - ColorPalette_Color(palette, *src, rgb); + Vector3ub palColor = palette->color(*src); + rgb[CR] = palColor.x; + rgb[CG] = palColor.y; + rgb[CB] = palColor.z; } else if(pixelSize >= 3) { diff --git a/doomsday/client/src/gl/gl_tex.cpp b/doomsday/client/src/gl/gl_tex.cpp index 48a25ff2c3..8dedadfa5c 100644 --- a/doomsday/client/src/gl/gl_tex.cpp +++ b/doomsday/client/src/gl/gl_tex.cpp @@ -752,7 +752,7 @@ void GL_DownMipmap8(uint8_t* in, uint8_t* fadedOut, int width, int height, float } } -boolean GL_PalettizeImage(uint8_t *out, int outformat, colorpalette_t const *palette, +boolean GL_PalettizeImage(uint8_t *out, int outformat, ColorPalette const *palette, boolean applyTexGamma, uint8_t const *in, int informat, int width, int height) { DENG2_ASSERT(in && out && palette); @@ -768,7 +768,12 @@ boolean GL_PalettizeImage(uint8_t *out, int outformat, colorpalette_t const *pal for(long i = 0; i < numPels; ++i) { - ColorPalette_Color(palette, *in, out); + de::Vector3ub palColor = palette->color(*in); + + out[CR] = palColor.x; + out[CG] = palColor.y; + out[CB] = palColor.z; + if(applyTexGamma) { out[CR] = texGammaLut[out[CR]]; @@ -792,10 +797,11 @@ boolean GL_PalettizeImage(uint8_t *out, int outformat, colorpalette_t const *pal return false; } -boolean GL_QuantizeImageToPalette(uint8_t* out, int outformat, colorpalette_t* palette, - const uint8_t* in, int informat, int width, int height) +boolean GL_QuantizeImageToPalette(uint8_t *out, int outformat, ColorPalette const *palette, + uint8_t const *in, int informat, int width, int height) { - assert(out && in && palette); + DENG2_ASSERT(out != 0 && in != 0 && palette != 0); + if(informat >= 3 && outformat <= 2 && width > 0 && height > 0) { int inSize = (informat == 2 ? 1 : informat); @@ -805,7 +811,7 @@ boolean GL_QuantizeImageToPalette(uint8_t* out, int outformat, colorpalette_t* p for(i = 0; i < numPixels; ++i, in += inSize, out += outSize) { // Convert the color value. - *out = ColorPalette_NearestIndexv(palette, in); + *out = palette->nearestIndex(de::Vector3ub(in)); // Alpha channel? if(outformat == 2) @@ -821,59 +827,56 @@ boolean GL_QuantizeImageToPalette(uint8_t* out, int outformat, colorpalette_t* p return false; } -void GL_DeSaturatePalettedImage(uint8_t* buffer, colorpalette_t* palette, +void GL_DeSaturatePalettedImage(uint8_t *buffer, ColorPalette const *palette, int width, int height) { - assert(buffer && palette); - { - const long numPels = width * height; - uint8_t rgb[3]; - int max, temp; + DENG2_ASSERT(buffer != 0 && palette != 0); + + if(!width || !height) return; - if(width == 0 || height == 0) - return; // Nothing to do. + long const numPels = width * height; // What is the maximum color value? - max = 0; - { long i; - for(i = 0; i < numPels; ++i) + int max = 0; + for(long i = 0; i < numPels; ++i) { - ColorPalette_Color(palette, buffer[i], rgb); - if(rgb[CR] == rgb[CG] && rgb[CR] == rgb[CB]) + de::Vector3ub palColor = palette->color(buffer[i]); + if(palColor.x == palColor.y && palColor.x == palColor.z) { - if(rgb[CR] > max) - max = rgb[CR]; + if(palColor.x > max) + { + max = palColor.x; + } continue; } - temp = (2 * (int)rgb[CR] + 4 * (int)rgb[CG] + 3 * (int)rgb[CB]) / 9; - if(temp > max) - max = temp; - }} + int temp = (2 * int( palColor.x ) + 4 * int( palColor.y ) + 3 * int( palColor.z )) / 9; + if(temp > max) max = temp; + } - { long i; - for(i = 0; i < numPels; ++i) + for(long i = 0; i < numPels; ++i) { - ColorPalette_Color(palette, buffer[i], rgb); - if(rgb[CR] == rgb[CG] && rgb[CR] == rgb[CB]) + de::Vector3ub palColor = palette->color(buffer[i]); + if(palColor.x == palColor.y && palColor.x == palColor.z) + { continue; + } // Calculate a weighted average. - temp = (2 * (int)rgb[CR] + 4 * (int)rgb[CG] + 3 * (int)rgb[CB]) / 9; - if(max) - temp *= 255.f / max; - buffer[i] = ColorPalette_NearestIndex(palette, temp, temp, temp); - }} + int temp = (2 * int( palColor.x ) + 4 * int( palColor.y ) + 3 * int( palColor.z )) / 9; + if(max) temp *= 255.f / max; + + buffer[i] = palette->nearestIndex(de::Vector3ub(temp, temp, temp)); } } -void FindAverageLineColorIdx(const uint8_t* data, int w, int h, int line, - const colorpalette_t* palette, boolean hasAlpha, ColorRawf* color) +void FindAverageLineColorIdx(uint8_t const *data, int w, int h, int line, + ColorPalette const *palette, boolean hasAlpha, ColorRawf *color) { + DENG2_ASSERT(data != 0 && color != 0); + long i, count, numpels, avg[3] = { 0, 0, 0 }; - const uint8_t* start, *alphaStart; - DGLubyte rgbUBV[3]; - assert(data && color); + uint8_t const *start, *alphaStart; if(w <= 0 || h <= 0) { @@ -898,10 +901,10 @@ void FindAverageLineColorIdx(const uint8_t* data, int w, int h, int line, { if(!hasAlpha || alphaStart[i]) { - ColorPalette_Color(palette, start[i], rgbUBV); - avg[CR] += rgbUBV[CR]; - avg[CG] += rgbUBV[CG]; - avg[CB] += rgbUBV[CB]; + de::Vector3ub palColor = palette->color(start[i]); + avg[CR] += palColor.x; + avg[CG] += palColor.y; + avg[CB] += palColor.z; ++count; } } @@ -986,13 +989,13 @@ void FindAverageColor(const uint8_t* pixels, int width, int height, avg[CB] / numpels * reciprocal255); } -void FindAverageColorIdx(const uint8_t* data, int w, int h, const colorpalette_t* palette, - boolean hasAlpha, ColorRawf* color) +void FindAverageColorIdx(uint8_t const *data, int w, int h, ColorPalette const *palette, + boolean hasAlpha, ColorRawf *color) { + DENG2_ASSERT(data != 0 && color != 0); + long i, numpels, count, avg[3] = { 0, 0, 0 }; - const uint8_t* alphaStart; - DGLubyte rgb[3]; - assert(data && color); + uint8_t const *alphaStart; if(w <= 0 || h <= 0) { @@ -1007,10 +1010,10 @@ void FindAverageColorIdx(const uint8_t* data, int w, int h, const colorpalette_t { if(!hasAlpha || alphaStart[i]) { - ColorPalette_Color(palette, data[i], rgb); - avg[CR] += rgb[CR]; - avg[CG] += rgb[CG]; - avg[CB] += rgb[CB]; + de::Vector3ub palColor = palette->color(data[i]); + avg[CR] += palColor.x; + avg[CG] += palColor.y; + avg[CB] += palColor.z; ++count; } } @@ -1074,7 +1077,7 @@ void FindAverageAlpha(const uint8_t* pixels, int width, int height, } /// @todo @a palette is unused; should be removed? -void FindAverageAlphaIdx(const uint8_t* pixels, int w, int h, const colorpalette_t* /*palette*/, +void FindAverageAlphaIdx(const uint8_t* pixels, int w, int h, const ColorPalette* /*palette*/, float* alpha, float* coverage) { long i, numPels, avg = 0, alphaCount = 0; diff --git a/doomsday/client/src/resource/colorpalette.cpp b/doomsday/client/src/resource/colorpalette.cpp index d3895763e9..8f4bace665 100644 --- a/doomsday/client/src/resource/colorpalette.cpp +++ b/doomsday/client/src/resource/colorpalette.cpp @@ -1,7 +1,7 @@ -/** @file colorpalette.cpp Color Palette. +/** @file colorpalette.cpp Color palette resource. * - * @authors Copyright © 1999-2013 Jaakko Keränen - * @authors Copyright © 2005-2013 Daniel Swanson + * @authors Copyright © 1999-2013 Jaakko Keränen + * @authors Copyright © 2005-2013 Daniel Swanson * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -18,261 +18,190 @@ * 02110-1301 USA */ -#include "de_platform.h" -#include "de_console.h" -#include "dd_def.h" -#include "m_misc.h" // for M_ReadBits - #include "resource/colorpalette.h" -#define RGB18(r, g, b) ((r)+((g)<<6)+((b)<<12)) +#include "dd_share.h" // reciprocal255 +#include "m_misc.h" // M_ReadBits +#include +#include +#include -static void prepareNearestLUT(colorpalette_t* pal); -static void prepareColorTable(colorpalette_t* pal, const int compOrder[3], - const uint8_t compBits[3], const uint8_t* colorData, int colorCount); +using namespace de; -colorpalette_t* ColorPalette_New(void) -{ - colorpalette_t* pal = (colorpalette_t*) malloc(sizeof(*pal)); - if(NULL == pal) - Con_Error("ColorPalette::Construct: Failed on allocation of %lu bytes for " - "new ColorPalette.", (unsigned long) sizeof(*pal)); - - pal->_flags = CPF_UPDATE_18TO8; // Defer creation of the nearest color LUT. - pal->_colorCount = 0; - pal->_colorData = NULL; - pal->_18To8LUT = NULL; - return pal; -} +#define RGB18(r, g, b) ((r)+((g)<<6)+((b)<<12)) -colorpalette_t* ColorPalette_NewWithColorTable(const int compOrder[3], - const uint8_t compBits[3], const uint8_t* colorData, int colorCount) +DENG2_PIMPL_NOREF(ColorPalette) { - assert(compOrder && compBits); + typedef Vector3ub Color; + typedef QVector ColorTable; + ColorTable colors; + + /// 18-bit to 8-bit, nearest color translation table. + typedef QVector XLat18To8; + QScopedPointer xlat18To8; + bool need18To8Update; + + Instance() : need18To8Update(false) // No color table yet. + {} + + /// @note A time-consuming operation. + void prepareNearestLUT() { - colorpalette_t* pal = ColorPalette_New(); - if(colorCount > 0 && NULL != colorData) - prepareColorTable(pal, compOrder, compBits, colorData, colorCount); - return pal; - } -} +#define COLORS18BIT 262144 -void ColorPalette_Delete(colorpalette_t* pal) -{ - assert(pal); - if(pal->_colorData) - free(pal->_colorData); - if(pal->_18To8LUT) - free(pal->_18To8LUT); - free(pal); -} + need18To8Update = false; -void ColorPalette_ReplaceColorTable(colorpalette_t* pal, const int compOrder[3], - const uint8_t compBits[3], const uint8_t* colorData, int colorCount) -{ - prepareColorTable(pal, compOrder, compBits, colorData, colorCount); -} + if(xlat18To8.isNull()) + { + xlat18To8.reset(new XLat18To8(COLORS18BIT)); + } -void ColorPalette_Color(const colorpalette_t* pal, int colorIdx, uint8_t rgb[3]) -{ - DENG_ASSERT(pal && rgb); + for(int r = 0; r < 64; ++r) + for(int g = 0; g < 64; ++g) + for(int b = 0; b < 64; ++b) + { + int nearest = 0; + int smallestDiff = DDMAXINT; + for(int i = 0; i < colors.count(); ++i) + { + Color const &color = colors[i]; + int diff = (color.x - (r << 2)) * (color.x - (r << 2)) + + (color.y - (g << 2)) * (color.y - (g << 2)) + + (color.z - (b << 2)) * (color.z - (b << 2)); + if(diff < smallestDiff) + { + smallestDiff = diff; + nearest = i; + } + } -#if _DEBUG - if(colorIdx < 0 || colorIdx >= pal->_colorCount) - Con_Message("Warning: ColorPalette::Color: ColorIdx %u out of range [0..%u).", - colorIdx, pal->_colorCount); -#endif + (*xlat18To8)[RGB18(r, g, b)] = nearest; + } - if(0 == pal->_colorCount) - { - rgb[CR] = rgb[CG] = rgb[CB] = 0; - return; +#undef COLORS18BIT } +}; - size_t offset = 3 * (size_t)MINMAX_OF(0, colorIdx, pal->_colorCount-1); - rgb[CR] = pal->_colorData[offset + CR]; - rgb[CG] = pal->_colorData[offset + CG]; - rgb[CB] = pal->_colorData[offset + CB]; -} - -int ColorPalette_NearestIndex(colorpalette_t* pal, uint8_t red, uint8_t green, uint8_t blue) -{ - assert(pal); - if(0 == pal->_colorCount) - return -1; - // Ensure we've prepared the 18 to 8 table. - prepareNearestLUT(pal); - return pal->_18To8LUT[RGB18(red >> 2, green >> 2, blue >> 2)]; -} +ColorPalette::ColorPalette() : d(new Instance()) +{} -int ColorPalette_NearestIndexv(colorpalette_t* pal, const uint8_t rgb[3]) +ColorPalette::ColorPalette(int const compOrder[3], uint8_t const compBits[3], + uint8_t const *colorData, int colorCount) + : d(new Instance()) { - return ColorPalette_NearestIndex(pal, rgb[CR], rgb[CG], rgb[CB]); + DENG2_ASSERT(compOrder != 0 && compBits != 0); + if(colorCount > 0 && colorData) + { + replaceColorTable(compOrder, compBits, colorData, colorCount); + } } -static void prepareColorTable(colorpalette_t* pal, const int compOrder[3], - const uint8_t compBits[3], const uint8_t* colorData, int colorCount) +void ColorPalette::replaceColorTable(int const compOrder[3], + uint8_t const compBits[3], uint8_t const *colorData, int colorCount) { - assert(pal); - { - uint8_t order[3], bits[3], cb; - const uint8_t* src; + // We may need a new 18 => 8 bit xlat table. + d->need18To8Update = true; // Ensure input is in range. - order[0] = MINMAX_OF(0, compOrder[0], 2); - order[1] = MINMAX_OF(0, compOrder[1], 2); - order[2] = MINMAX_OF(0, compOrder[2], 2); + Vector3i order(de::clamp(0, compOrder[0], 2), + de::clamp(0, compOrder[1], 2), + de::clamp(0, compOrder[2], 2)); - bits[CR] = MIN_OF(compBits[CR], COLORPALETTE_MAX_COMPONENT_BITS); - bits[CG] = MIN_OF(compBits[CG], COLORPALETTE_MAX_COMPONENT_BITS); - bits[CB] = MIN_OF(compBits[CB], COLORPALETTE_MAX_COMPONENT_BITS); + Vector3ub bits = Vector3ub(compBits).min(Vector3ub(max_component_bits, + max_component_bits, + max_component_bits)); - if(NULL != pal->_colorData) - { - free(pal->_colorData); pal->_colorData = NULL; - pal->_colorCount = 0; - } - - if(NULL != pal->_18To8LUT) - { - free(pal->_18To8LUT); pal->_18To8LUT = NULL; - pal->_flags |= CPF_UPDATE_18TO8; - } - - pal->_colorCount = colorCount; - if(NULL == (pal->_colorData = (uint8_t*) malloc(pal->_colorCount * 3 * sizeof(uint8_t)))) - Con_Error("ColorPalette::prepareColorTable: Failed on allocation of %lu bytes for " - "color table.", (unsigned long) (pal->_colorCount * 3 * sizeof(uint8_t))); + d->colors.resize(colorCount); // Already in the format we want? - if(8 == bits[CR] && 8 == bits[CG] && 8 == bits[CB]) - { // Great! Just copy it as-is. - memcpy(pal->_colorData, colorData, pal->_colorCount * 3); - - // Do we need to adjust the order? - if(0 != order[CR]|| 1 != order[CG] || 2 != order[CB]) + if(8 == bits.x && 8 == bits.y && 8 == bits.z) + { + // Great! Just copy it as-is. + uint8_t const *src = colorData; + for(int i = 0; i < colorCount; ++i, src += 3) { - int i; - for(i = 0; i < pal->_colorCount; ++i) - { - uint8_t* dst = &pal->_colorData[i * 3]; - uint8_t tmp[3]; - - tmp[0] = dst[0]; - tmp[1] = dst[1]; - tmp[2] = dst[2]; - - dst[CR] = tmp[order[CR]]; - dst[CG] = tmp[order[CG]]; - dst[CB] = tmp[order[CB]]; - } + d->colors[i] = Vector3ub(src[order.x], src[order.y], src[order.z]); } return; } // Conversion is necessary. - src = colorData; - cb = 0; - { int i; - for(i = 0; i < pal->_colorCount; ++i) + uint8_t const *src = colorData; + uint8_t cb = 0; + for(int i = 0; i < colorCount; ++i) { - uint8_t* dst = &pal->_colorData[i * 3]; - int tmp[3]; + Vector3ub &dst = d->colors[i]; - tmp[CR] = tmp[CG] = tmp[CB] = 0; - - M_ReadBits(bits[order[CR]], &src, &cb, (uint8_t*) &(tmp[order[CR]])); - M_ReadBits(bits[order[CG]], &src, &cb, (uint8_t*) &(tmp[order[CG]])); - M_ReadBits(bits[order[CB]], &src, &cb, (uint8_t*) &(tmp[order[CB]])); + Vector3i tmp; + M_ReadBits(bits[order.x], &src, &cb, (uint8_t *) &(tmp[order.x])); + M_ReadBits(bits[order.y], &src, &cb, (uint8_t *) &(tmp[order.y])); + M_ReadBits(bits[order.z], &src, &cb, (uint8_t *) &(tmp[order.z])); // Need to do any scaling? - if(8 != bits[CR]) + if(8 != bits.x) { - if(bits[CR] < 8) - tmp[CR] <<= 8 - bits[CR]; + if(bits.x < 8) + tmp.x <<= 8 - bits.x; else - tmp[CR] >>= bits[CR] - 8; + tmp.x >>= bits.x - 8; } - if(8 != bits[CG]) + if(8 != bits.y) { - if(bits[CG] < 8) - tmp[CG] <<= 8 - bits[CG]; + if(bits.y < 8) + tmp.y <<= 8 - bits.y; else - tmp[CG] >>= bits[CG] - 8; + tmp.y >>= bits.y - 8; } - if(8 != bits[CB]) + if(8 != bits.z) { - if(bits[CB] < 8) - tmp[CB] <<= 8 - bits[CB]; + if(bits.z < 8) + tmp.z <<= 8 - bits.z; else - tmp[CB] >>= bits[CB] - 8; + tmp.z >>= bits.z - 8; } // Store the final color. - dst[CR] = (uint8_t) MINMAX_OF(0, tmp[CR], 255); - dst[CG] = (uint8_t) MINMAX_OF(0, tmp[CG], 255); - dst[CB] = (uint8_t) MINMAX_OF(0, tmp[CB], 255); - }} + dst = Vector3ub(de::clamp(0, tmp.x, 255), + de::clamp(0, tmp.y, 255), + de::clamp(0, tmp.z, 255)); } } -/// @note A time-consuming operation. -static void prepareNearestLUT(colorpalette_t* pal) +Vector3ub ColorPalette::color(int colorIndex) const { -#define SIZEOF18TO8 (sizeof(int) * 262144) + LOG_AS("ColorPalette::color"); - assert(pal); - if((pal->_flags & CPF_UPDATE_18TO8) || !pal->_18To8LUT) + if(colorIndex < 0 || colorIndex >= d->colors.count()) { - int r, g, b, i, nearest, smallestDiff; + LOG_DEBUG("Index %i out of range %s, will clamp.") + << colorIndex << Rangeui(0, d->colors.count()).asText(); + } - if(!pal->_18To8LUT) - { - if(NULL == (pal->_18To8LUT = (int*) malloc(SIZEOF18TO8))) - Con_Error("ColorPalette::prepareNearestLUT: Failed on allocation of %lu bytes for " - "lookup table.", (unsigned long) SIZEOF18TO8); - } + if(!d->colors.isEmpty()) + { + return d->colors[de::clamp(0, colorIndex, d->colors.count() - 1)]; + } - for(r = 0; r < 64; ++r) - { - for(g = 0; g < 64; ++g) - { - for(b = 0; b < 64; ++b) - { - nearest = 0; - smallestDiff = DDMAXINT; - for(i = 0; i < pal->_colorCount; ++i) - { - const uint8_t* rgb = &pal->_colorData[i * 3]; - int diff = - (rgb[CR] - (r << 2)) * (rgb[CR] - (r << 2)) + - (rgb[CG] - (g << 2)) * (rgb[CG] - (g << 2)) + - (rgb[CB] - (b << 2)) * (rgb[CB] - (b << 2)); - - if(diff < smallestDiff) - { - smallestDiff = diff; - nearest = i; - } - } - - pal->_18To8LUT[RGB18(r, g, b)] = nearest; - } - } - } + return Vector3ub(); +} - pal->_flags &= ~CPF_UPDATE_18TO8; +Vector3f ColorPalette::colorf(int colorIdx) const +{ + return color(colorIdx).toVector3f() * reciprocal255; +} - /*if(ArgCheck("-dump_pal18to8")) - { - FILE* file = fopen("colorpalette18To8.lmp", "wb"); - fwrite(pal->_18To8LUT, SIZEOF18TO8, 1, file); - fclose(file); - }*/ +int ColorPalette::nearestIndex(Vector3ub const &rgb) const +{ + if(d->colors.isEmpty()) return -1; + + // Ensure we've prepared the 18 to 8 table. + if(d->need18To8Update || d->xlat18To8.isNull()) + { + d->prepareNearestLUT(); } -#undef SIZEOF18TO8 + return (*d->xlat18To8)[RGB18(rgb.x >> 2, rgb.y >> 2, rgb.z >> 2)]; } diff --git a/doomsday/client/src/resource/colorpalettes.cpp b/doomsday/client/src/resource/colorpalettes.cpp index 2f67c5bfc6..24934d4a73 100644 --- a/doomsday/client/src/resource/colorpalettes.cpp +++ b/doomsday/client/src/resource/colorpalettes.cpp @@ -1,6 +1,6 @@ -/** @file colorpalettes.cpp ColorPalette repository and related bookkeeping. +/** @file colorpalettes.cpp Color palette resource collection * - * @authors Copyright © 2009-2013 Daniel Swanson + * @authors Copyright © 2009-2013 Daniel Swanson * * @par License * GPL: http://www.gnu.org/licenses/gpl.html @@ -28,6 +28,10 @@ #include "resource/colorpalettes.h" +using namespace de; + +byte *translationTables; + #define COLORPALETTENAME_MAXLEN (32) /** @@ -42,39 +46,39 @@ struct ColorPaletteBind colorpaletteid_t defaultColorPalette; -byte* translationTables; - static boolean initedColorPalettes = false; static int numColorPalettes; -static colorpalette_t** colorPalettes; +static ColorPalette **colorPalettes; static int numColorPaletteBinds; -static ColorPaletteBind* colorPaletteBinds; +static ColorPaletteBind *colorPaletteBinds; -static colorpaletteid_t colorPaletteNumForName(char const* name) +static colorpaletteid_t colorPaletteNumForName(char const *name) { - DENG_ASSERT(initedColorPalettes); + DENG2_ASSERT(initedColorPalettes); + // Linear search (sufficiently fast enough given the probably small set // and infrequency of searches). for(int i = 0; i < numColorPaletteBinds; ++i) { - ColorPaletteBind* pal = &colorPaletteBinds[i]; + ColorPaletteBind *pal = &colorPaletteBinds[i]; if(!strnicmp(pal->name, name, COLORPALETTENAME_MAXLEN)) + { return i + 1; // Already registered. 1-based index. + } } + return 0; // Not found. } static int createColorPalette(int const compOrder[3], uint8_t const compSize[3], - uint8_t const* data, ushort num) + uint8_t const *data, ushort num) { - DENG_ASSERT(initedColorPalettes && compOrder && compSize && data); + DENG2_ASSERT(initedColorPalettes && compOrder && compSize && data); - colorpalette_t* pal = ColorPalette_NewWithColorTable(compOrder, compSize, data, num); - - colorPalettes = (colorpalette_t**) M_Realloc(colorPalettes, (numColorPalettes + 1) * sizeof(*colorPalettes)); - if(!colorPalettes) Con_Error("createColorPalette: Failed on (re)allocation of %lu bytes for color palette list.", (unsigned long) ((numColorPalettes + 1) * sizeof(*colorPalettes))); + ColorPalette *pal = new ColorPalette(compOrder, compSize, data, num); + colorPalettes = (ColorPalette **) M_Realloc(colorPalettes, (numColorPalettes + 1) * sizeof(*colorPalettes)); colorPalettes[numColorPalettes] = pal; return ++numColorPalettes; // 1-based index. @@ -84,7 +88,7 @@ void R_InitTranslationTables() { // The translation tables consist of a number of translation maps, each // containing 256 palette indices. - translationTables = (byte*) Z_Calloc(NUM_TRANSLATION_TABLES * 256, PU_REFRESHTRANS, 0); + translationTables = (byte *) Z_Calloc(NUM_TRANSLATION_TABLES * 256, PU_REFRESHTRANS, 0); } void R_UpdateTranslationTables() @@ -98,7 +102,7 @@ byte const *R_TranslationTable(int tclass, int tmap) // Is translation unnecessary? if(!tclass && !tmap) return 0; - int trans = MAX_OF(0, NUM_TRANSLATION_MAPS_PER_CLASS * tclass + tmap - 1); + int trans = de::max(0, NUM_TRANSLATION_MAPS_PER_CLASS * tclass + tmap - 1); LOG_DEBUG("tclass=%i tmap=%i => TransPal# %i") << tclass << tmap << trans; return translationTables + trans * 256; @@ -131,7 +135,7 @@ void R_DestroyColorPalettes() { for(int i = 0; i < numColorPalettes; ++i) { - ColorPalette_Delete(colorPalettes[i]); + delete(colorPalettes[i]); } M_Free(colorPalettes); colorPalettes = 0; numColorPalettes = 0; @@ -148,23 +152,28 @@ void R_DestroyColorPalettes() int R_ColorPaletteCount() { - DENG_ASSERT(initedColorPalettes); + DENG2_ASSERT(initedColorPalettes); return numColorPalettes; } -colorpalette_t* R_ToColorPalette(colorpaletteid_t id) +ColorPalette *R_ToColorPalette(colorpaletteid_t id) { - DENG_ASSERT(initedColorPalettes); + DENG2_ASSERT(initedColorPalettes); if(id == 0 || id - 1 >= (unsigned) numColorPaletteBinds) + { id = defaultColorPalette; + } + if(id != 0 && numColorPaletteBinds > 0) + { return colorPalettes[colorPaletteBinds[id-1].idx-1]; - return NULL; + } + return 0; } -colorpalette_t* R_GetColorPaletteByIndex(int paletteIdx) +ColorPalette *R_GetColorPaletteByIndex(int paletteIdx) { - DENG_ASSERT(initedColorPalettes); + DENG2_ASSERT(initedColorPalettes); if(paletteIdx > 0 && numColorPalettes >= paletteIdx) { return colorPalettes[paletteIdx-1]; @@ -175,24 +184,24 @@ colorpalette_t* R_GetColorPaletteByIndex(int paletteIdx) boolean R_SetDefaultColorPalette(colorpaletteid_t id) { - DENG_ASSERT(initedColorPalettes); + DENG2_ASSERT(initedColorPalettes); if(id - 1 < (unsigned) numColorPaletteBinds) { defaultColorPalette = id; return true; } - VERBOSE( Con_Message("R_SetDefaultColorPalette: Invalid id %u.", id) ); + LOG_VERBOSE("R_SetDefaultColorPalette: Invalid id %u.") << id; return false; } #undef R_CreateColorPalette -DENG_EXTERN_C colorpaletteid_t R_CreateColorPalette(char const* fmt, char const* name, - uint8_t const* colorData, int colorCount) +DENG_EXTERN_C colorpaletteid_t R_CreateColorPalette(char const *fmt, char const *name, + uint8_t const *colorData, int colorCount) { - static char const* compNames[] = { "red", "green", "blue" }; + static char const *compNames[] = { "red", "green", "blue" }; colorpaletteid_t id; - ColorPaletteBind* bind; - char const* c, *end; + ColorPaletteBind *bind; + char const *c, *end; int i, pos, compOrder[3]; uint8_t compSize[3]; @@ -212,7 +221,7 @@ DENG_EXTERN_C colorpaletteid_t R_CreateColorPalette(char const* fmt, char const* Con_Error("R_CreateColorPalette: Failed creating \"%s\", cannot create a zero-sized palette.", name); // All arguments supplied. Parse the format string. - memset(compOrder, -1, sizeof(compOrder)); + std::memset(compOrder, -1, sizeof(compOrder)); pos = 0; end = fmt + (strlen(fmt) - 1); c = fmt; @@ -229,7 +238,7 @@ DENG_EXTERN_C colorpaletteid_t R_CreateColorPalette(char const* fmt, char const* if(compOrder[comp] == -1) { // No. - char const * start; + char const *start; size_t numDigits; compOrder[comp] = pos++; @@ -244,13 +253,13 @@ DENG_EXTERN_C colorpaletteid_t R_CreateColorPalette(char const* fmt, char const* { char buf[3]; - memset(buf, 0, sizeof(buf)); - memcpy(buf, start, numDigits); + std::memset(buf, 0, sizeof(buf)); + std::memcpy(buf, start, numDigits); compSize[comp] = atoi(buf); - if(pos == 3) - break; // We're done. + // Are we done? + if(pos == 3) break; // Unread the last character. c--; @@ -263,12 +272,14 @@ DENG_EXTERN_C colorpaletteid_t R_CreateColorPalette(char const* fmt, char const* } while(++c <= end); if(pos != 3) + { Con_Error("R_CreateColorPalette: Failed creating \"%s\", incomplete format specification.\n", name); + } // Check validity of bits per component. for(i = 0; i < 3; ++i) { - if(compSize[i] == 0 || compSize[i] > COLORPALETTE_MAX_COMPONENT_BITS) + if(compSize[i] == 0 || compSize[i] > ColorPalette::max_component_bits) { Con_Error("R_CreateColorPalette: Failed creating \"%s\", unsupported bit depth %i for %s component.\n", name, compSize[i], compNames[compOrder[i]]); } @@ -278,8 +289,7 @@ DENG_EXTERN_C colorpaletteid_t R_CreateColorPalette(char const* fmt, char const* { // Replacing an existing palette. bind = &colorPaletteBinds[id - 1]; - colorpalette_t *palette = R_GetColorPaletteByIndex(bind->idx); - ColorPalette_ReplaceColorTable(palette, compOrder, compSize, colorData, colorCount); + R_GetColorPaletteByIndex(bind->idx)->replaceColorTable(compOrder, compSize, colorData, colorCount); #ifdef __CLIENT__ GL_ReleaseTexturesByColorPalette(id); @@ -309,27 +319,35 @@ DENG_EXTERN_C colorpaletteid_t R_CreateColorPalette(char const* fmt, char const* } #undef R_GetColorPaletteNumForName -DENG_EXTERN_C colorpaletteid_t R_GetColorPaletteNumForName(char const* name) +DENG_EXTERN_C colorpaletteid_t R_GetColorPaletteNumForName(char const *name) { if(!initedColorPalettes) + { Con_Error("R_GetColorPaletteNumForName: Color palettes not yet initialized."); + } if(name && name[0] && qstrlen(name) <= COLORPALETTENAME_MAXLEN) + { return colorPaletteNumForName(name); + } return 0; } #undef R_GetColorPaletteNameForNum -DENG_EXTERN_C char const* R_GetColorPaletteNameForNum(colorpaletteid_t id) +DENG_EXTERN_C char const *R_GetColorPaletteNameForNum(colorpaletteid_t id) { if(!initedColorPalettes) + { Con_Error("R_GetColorPaletteNameForNum: Color palettes not yet initialized."); + } if(id != 0 && id - 1 < (unsigned)numColorPaletteBinds) + { return colorPaletteBinds[id-1].name; + } - return NULL; + return 0; } #undef R_GetColorPaletteRGBubv @@ -337,9 +355,13 @@ DENG_EXTERN_C void R_GetColorPaletteRGBubv(colorpaletteid_t paletteId, int color boolean applyTexGamma) { if(!initedColorPalettes) + { Con_Error("R_GetColorPaletteRGBubv: Color palettes not yet initialized."); + } if(!rgb) + { Con_Error("R_GetColorPaletteRGBubv: Invalid arguments (rgb==NULL)."); + } if(colorIdx < 0) { @@ -347,10 +369,12 @@ DENG_EXTERN_C void R_GetColorPaletteRGBubv(colorpaletteid_t paletteId, int color return; } - colorpalette_t* palette = R_ToColorPalette(paletteId); - if(palette) + if(ColorPalette *palette = R_ToColorPalette(paletteId)) { - ColorPalette_Color(palette, colorIdx, rgb); + Vector3ub palColor = palette->color(colorIdx); + rgb[CR] = palColor.x; + rgb[CG] = palColor.y; + rgb[CB] = palColor.z; if(applyTexGamma) { rgb[CR] = texGammaLut[rgb[CR]]; @@ -360,7 +384,7 @@ DENG_EXTERN_C void R_GetColorPaletteRGBubv(colorpaletteid_t paletteId, int color return; } - Con_Message("Warning: R_GetColorPaletteRGBubv: Failed to locate ColorPalette for id %i.", paletteId); + LOG_WARNING("R_GetColorPaletteRGBubv: Failed to locate ColorPalette for id %i.") << paletteId; } #undef R_GetColorPaletteRGBf @@ -368,9 +392,13 @@ DENG_EXTERN_C void R_GetColorPaletteRGBf(colorpaletteid_t paletteId, int colorId boolean applyTexGamma) { if(!initedColorPalettes) + { Con_Error("R_GetColorPaletteRGBf: Color palettes not yet initialized."); + } if(!rgb) + { Con_Error("R_GetColorPaletteRGBf: Invalid arguments (rgb==NULL)."); + } if(colorIdx < 0) { @@ -378,22 +406,24 @@ DENG_EXTERN_C void R_GetColorPaletteRGBf(colorpaletteid_t paletteId, int colorId return; } - colorpalette_t* palette = R_ToColorPalette(paletteId); - if(palette) + if(ColorPalette *palette = R_ToColorPalette(paletteId)) { - uint8_t ubv[3]; - ColorPalette_Color(palette, colorIdx, ubv); if(applyTexGamma) { - ubv[CR] = texGammaLut[ubv[CR]]; - ubv[CG] = texGammaLut[ubv[CG]]; - ubv[CB] = texGammaLut[ubv[CB]]; + Vector3ub palColor = palette->color(colorIdx); + rgb[CR] = texGammaLut[palColor.x] * reciprocal255; + rgb[CG] = texGammaLut[palColor.y] * reciprocal255; + rgb[CB] = texGammaLut[palColor.z] * reciprocal255; + } + else + { + Vector3f palColor = palette->colorf(colorIdx); + rgb[CR] = palColor.x; + rgb[CG] = palColor.y; + rgb[CB] = palColor.z; } - rgb[CR] = ubv[CR] * reciprocal255; - rgb[CG] = ubv[CG] * reciprocal255; - rgb[CB] = ubv[CB] * reciprocal255; return; } - Con_Message("Warning: R_GetColorPaletteRGBf: Failed to locate ColorPalette for id %i.", paletteId); + LOG_WARNING("R_GetColorPaletteRGBf: Failed to locate ColorPalette for id %i.") << paletteId; } diff --git a/doomsday/client/src/resource/fontscheme.cpp b/doomsday/client/src/resource/fontscheme.cpp index 16c16a2d87..2f33bc3da4 100644 --- a/doomsday/client/src/resource/fontscheme.cpp +++ b/doomsday/client/src/resource/fontscheme.cpp @@ -184,7 +184,7 @@ FontScheme::Manifest &FontScheme::declare(Path const &path) if(d->index.size() != sizeBefore) { // We want notification if/when the manifest's uniqueId changes. - newManifest->audienceForUniqueIdChanged += this; + newManifest->audienceForUniqueIdChange += this; // We want notification when the manifest is about to be deleted. newManifest->audienceForDeletion += this; diff --git a/doomsday/client/src/resource/texturescheme.cpp b/doomsday/client/src/resource/texturescheme.cpp index 3032859bee..28c0c80cee 100644 --- a/doomsday/client/src/resource/texturescheme.cpp +++ b/doomsday/client/src/resource/texturescheme.cpp @@ -196,7 +196,7 @@ TextureManifest &TextureScheme::declare(Path const &path, d->uniqueIdLutDirty = true; // We want notification if/when the manifest's uniqueId changes. - newManifest->audienceForUniqueIdChanged += this; + newManifest->audienceForUniqueIdChange += this; // We want notification when the manifest is about to be deleted. newManifest->audienceForDeletion += this;