From 5a422aba704c375a307a902bafe658342e209906 Mon Sep 17 00:00:00 2001 From: scuri Date: Fri, 17 Oct 2008 06:10:15 +0000 Subject: First commit - moving from LuaForge to SourceForge --- src/im_palette.cpp | 551 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 551 insertions(+) create mode 100644 src/im_palette.cpp (limited to 'src/im_palette.cpp') diff --git a/src/im_palette.cpp b/src/im_palette.cpp new file mode 100644 index 0000000..0e6f967 --- /dev/null +++ b/src/im_palette.cpp @@ -0,0 +1,551 @@ +/** \file + * \brief Palette Generators + * Creates several standard palettes + * + * See Copyright Notice in im_lib.h + * $Id: im_palette.cpp,v 1.1 2008/10/17 06:10:16 scuri Exp $ + */ + +#include "im.h" +#include "im_util.h" +#include "im_palette.h" +#include "im_colorhsi.h" + +#include +#include +#include +#include + +static inline int iSqr(int x) +{ + return x*x; +} + +static inline int iAbs(int x) +{ + return x < 0? -x: x; +} + +int imPaletteFindNearest(const long* palette, int palette_count, long color) +{ + assert(palette); + assert(palette_count); + + int lSqrDiff, lBestDiff = (unsigned int)-1; + int pIndex = -1; + + imbyte red1, green1, blue1; + imColorDecode(&red1, &green1, &blue1, color); + + for (int lIndex = 0; lIndex < palette_count; lIndex++, palette++) + { + if (color == *palette) + return lIndex; + + imbyte red2, green2, blue2; + imColorDecode(&red2, &green2, &blue2, *palette); + + lSqrDiff = iSqr(red1 - red2) + + iSqr(green1 - green2) + + iSqr(blue1 - blue2); + + if (lSqrDiff < lBestDiff) + { + lBestDiff = lSqrDiff; + pIndex = lIndex; + } + } + + return pIndex; +} + +int imPaletteFindColor(const long* palette, int palette_count, long color, unsigned char tol) +{ + assert(palette); + assert(palette_count); + + /* Divides in two section for faster results when Tolerance is 0.*/ + if (tol == 0) + { + for (int lIndex = 0; lIndex < palette_count; lIndex++, palette++) + { + if (color == *palette) + return lIndex; + } + } + else + { + imbyte red1, green1, blue1; + imColorDecode(&red1, &green1, &blue1, color); + + for (int lIndex = 0; lIndex < palette_count; lIndex++, palette++) + { + imbyte red2, green2, blue2; + imColorDecode(&red2, &green2, &blue2, *palette); + + if (iAbs(red1 - red2) < tol && + iAbs(green1 - green2) < tol && + iAbs(blue1 - blue2) < tol) + { + return lIndex; + } + } + } + + return -1; +} + +long* imPaletteGray(void) +{ + long* palette = (long*)malloc(sizeof(long)*256); + long* ct = palette; + + for (int lIndex = 0; lIndex < 256; lIndex++) + { + /* From (0, 0, 0) to (255, 255, 255)*/ + /* From Black to White */ + *(ct++) = imColorEncode((imbyte)lIndex, (imbyte)lIndex, (imbyte)lIndex); + } + + return palette; +} + +long* imPaletteRed(void) +{ + long* palette = (long*)malloc(sizeof(long)*256); + long* ct = palette; + + for (int lIndex = 0; lIndex < 256; lIndex++) + { + /* From (0, 0, 0) to (255, 0, 0) */ + /* From Black to Red */ + *(ct++) = imColorEncode((imbyte)lIndex, 0, 0); + } + + return palette; +} + +long* imPaletteGreen(void) +{ + long* palette = (long*)malloc(sizeof(long)*256); + long* ct = palette; + + for (int lIndex = 0; lIndex < 256; lIndex++) + { + /* From (0, 0, 0) to (0, 255, 0)*/ + /* From Black to Green */ + *(ct++) = imColorEncode(0, (imbyte)lIndex, 0); + } + + return palette; +} + +long* imPaletteBlue(void) +{ + long* palette = (long*)malloc(sizeof(long)*256); + long* ct = palette; + + for (int lIndex = 0; lIndex < 256; lIndex++) + { + /* From (0, 0, 0) to (0, 0, 255)*/ + /* From Black to Blue */ + *(ct++) = imColorEncode(0, 0, (imbyte)lIndex); + } + + return palette; +} + +long* imPaletteYellow(void) +{ + long* palette = (long*)malloc(sizeof(long)*256); + long* ct = palette; + + for (int lIndex = 0; lIndex < 256; lIndex++) + { + /* From (0, 0, 0) to (255, 255, 0)*/ + /* From Black to Yellow */ + *(ct++) = imColorEncode((imbyte)lIndex, (imbyte)lIndex, 0); + } + + return palette; +} + +long* imPaletteMagenta(void) +{ + long* palette = (long*)malloc(sizeof(long)*256); + long* ct = palette; + + for (int lIndex = 0; lIndex < 256; lIndex++) + { + /* From (0, 0, 0) to (255, 0, 255)*/ + /* From Black to Magenta */ + *(ct++) = imColorEncode((imbyte)lIndex, 0, (imbyte)lIndex); + } + + return palette; +} + +long* imPaletteCian(void) +{ + long* palette = (long*)malloc(sizeof(long)*256); + long* ct = palette; + + for (int lIndex = 0; lIndex < 256; lIndex++) + { + /* From (0, 0, 0) to (0, 255, 255)*/ + /* From Black to Cian */ + *(ct++) = imColorEncode(0, (imbyte)lIndex, (imbyte)lIndex); + } + + return palette; +} + +long* imPaletteHues(void) +{ + long* palette = (long*)malloc(sizeof(long)*256); + long* ct = palette; + int i; + float tone, step1 = 255.0f/41.0f, step2 = 255.0f/42.0f; + + /* 1+42+1+41+1+42+1+41+1+42+1+41+1 = 256 */ + + /* red */ + *(ct++) = imColorEncode((imbyte)255, 0, 0); + + for (tone = step2, i = 0; i < 42; i++, tone += step2) + { + /* From (255, 0, 0) to (255, 255, 0) */ + /* From Red to Yellow */ + *(ct++) = imColorEncode((imbyte)255, (imbyte)tone, 0); + } + + /* yellow */ + *(ct++) = imColorEncode((imbyte)255, (imbyte)255, 0); + + for (tone = step1, i = 0; i < 41; i++, tone += step1) + { + /* From (255, 255, 0) to (0, 255, 0) */ + /* From Yellow to Green */ + *(ct++) = imColorEncode((imbyte)(255.0f-tone), (imbyte)255, 0); + } + + /* green */ + *(ct++) = imColorEncode(0, (imbyte)255, 0);; + + for (tone = step2, i = 0; i < 42; i++, tone += step2) + { + /* From (0, 255, 0) to (0, 255, 255) */ + /* From Green to Cian */ + *(ct++) = imColorEncode(0, (imbyte)255, (imbyte)tone); + } + + /* cian */ + *(ct++) = imColorEncode(0, (imbyte)255, (imbyte)255); + + for (tone = step1, i = 0; i < 41; i++, tone += step1) + { + /* From (0, 255, 255) to (0, 0, 255) */ + /* From Cian to Blue */ + *(ct++) = imColorEncode(0, (imbyte)(255.0f-tone), (imbyte)255); + } + + /* blue */ + *(ct++) = imColorEncode(0, 0, (imbyte)255); + + for (tone = step2, i = 0; i < 42; i++, tone += step2) + { + /* From (0, 0, 255) to (255, 0, 255) */ + /* From Blue to Magenta */ + *(ct++) = imColorEncode((imbyte)tone, 0, (imbyte)255); + } + + /* magenta */ + *(ct++) = imColorEncode((imbyte)255, 0, (imbyte)255); + + for (tone = step1, i = 0; i < 41; i++, tone += step1) + { + /* From (255, 0, 255) to (255, 0, 0) */ + /* From Magenta to Red */ + *(ct++) = imColorEncode((imbyte)255, 0, (imbyte)(255.0f-tone)); + } + + /* black */ + *(ct++) = imColorEncode(0, 0, 0);; + + return palette; +} + +long* imPaletteRainbow(void) +{ + long* palette = (long*)malloc(sizeof(long)*256); + long* ct = palette; + int hue; + unsigned char r, g, b; + float h, s, i, factor, H; + + s = 1.0f; + factor = 360.0f / 256.0f; + + for (hue = 0; hue < 256; hue++) + { + h = hue * factor; + h = 300-h; + if (h < 0) h += 360; + H = h/57.2957795131f; + + i = imColorHSI_ImaxS(H, cos(H), sin(H)); + + imColorHSI2RGBbyte(h, s, i, &r, &g, &b); + + *(ct++) = imColorEncode(r, g, b);; + } + + return palette; +} + +long* imPaletteBlueIce(void) +{ + long* palette = (long*)malloc(sizeof(long)*256); + long* ct = palette; + + for (int lIndex = 0; lIndex < 256; lIndex++) + { + /* From (0, 0, 255) to (255, 255, 255)*/ + /* From Blue to White */ + *(ct++) = imColorEncode((imbyte)lIndex, (imbyte)lIndex, 255); + } + + return palette; +} + +long* imPaletteHotIron(void) +{ + long* palette = (long*)malloc(sizeof(long)*256); + long* ct = palette; + int lIndex, lSubIndex; + + for (lIndex = 0, lSubIndex = 0; lSubIndex < 128; lSubIndex++, lIndex += 2) + { + /* From (0, 0, 0) to (254, 0, 0) */ + /* From Black to ~Red */ + *(ct++) = imColorEncode((imbyte)lIndex, 0, 0); + } + + for (lIndex = 0, lSubIndex = 0; lSubIndex < 64; lSubIndex++, lIndex += 2) + { + /* From (255, 0, 0) to (255, 126, 0) */ + /* From Red to ~Orange */ + *(ct++) = imColorEncode(255, (imbyte)lIndex, 0); + } + + for (lIndex = 0, lSubIndex = 0; lSubIndex < 63; lSubIndex++, lIndex += 2) + { + /* From (255, 128, 0) to (255, 252, 252)*/ + /* From Orange to ~White */ + imbyte red = 255; + imbyte green = (imbyte)(128 + lIndex); + imbyte blue = (imbyte)(lIndex * 2 + 4); + + *(ct++) = imColorEncode(red, green, blue); + } + + *(ct++) = imColorEncode(255, 255, 255); + + return palette; +} + +long* imPaletteBlackBody(void) +{ + long* palette = (long*)malloc(sizeof(long)*256); + long* ct = palette; + int lIndex, lSubIndex; + + for (lIndex = 0, lSubIndex = 0; lSubIndex < 85; lSubIndex++, lIndex += 3) + { + /* From (0, 0, 0) to (252, 0, 0) */ + /* From Black to ~Red */ + *(ct++) = imColorEncode((imbyte)lIndex, 0, 0); + } + + for (lIndex = 0, lSubIndex = 0; lSubIndex < 85; lSubIndex++, lIndex += 3) + { + /* From (255, 0, 0) to (255, 252, 0)*/ + /* From Red to ~Yellow */ + *(ct++) = imColorEncode(255, (imbyte)lIndex, 0); + } + + for (lIndex = 0, lSubIndex = 0; lSubIndex < 86; lSubIndex++, lIndex += 3) + { + /* From (255, 255, 0) to (255, 255, 255)*/ + /* From Yellow to White */ + *(ct++) = imColorEncode(255, 255, (imbyte)lIndex); + } + + return palette; +} + +long* imPaletteHighContrast(void) +{ + long* palette = (long*)malloc(sizeof(long)*256); + long* ct = palette; + int lIndex; + + static struct{unsigned char r, g, b;} HighContrastColors[65] = { + { 0,0,0 }, + + { 255,0,0 }, { 128,0,0 }, { 64,0,0 }, { 192,0,0 }, + { 0,255,0 }, { 0,128,0 }, { 0,64,0 }, { 0,192,0 }, + { 0,0,255 }, { 0,0,128 }, { 0,0,64 }, { 0,0,192 }, + { 255,255,0 }, { 128,128,0 }, { 64,64,0 }, { 192,192,0 }, + { 255,0,255 }, { 128,0,128 }, { 64,0,64 }, { 192,0,192 }, + { 0,255,255 }, { 0,128,128 }, { 0,64,64 }, { 0,192,192 }, + { 255,255,255 }, { 128,128,128 }, { 64,64,64 }, { 192,192,192 }, + + { 255,128,128 }, { 64,255,255 }, { 192,255,255 }, + { 128,255,128 }, { 255,64,255 }, { 255,192,255 }, + { 128,128,255 }, { 255,255,64 }, { 255,255,192 }, + { 255,255,128 }, { 64,64,255 }, { 192,192,255 }, + { 255,128,255 }, { 64,255,64 }, { 192,255,192 }, + { 128,255,255 }, { 255,64,64 }, { 255,192,192 }, + + { 128,64,64 }, { 128,192,192 }, + { 64,128,64 }, { 192,128,192 }, + { 64,64,128 }, { 192,192,128 }, + { 128,128,64 }, { 128,128,192 }, + { 128,64,128 }, { 128,192,128 }, + { 64,128,128 }, { 192,128,128 }, + + { 192,64,64 }, + { 64,192,64 }, + { 64,64,192 }, + { 192,192,64 }, + { 192,64,192 }, + { 64,192,192 }, + }; + + for (lIndex = 0; lIndex < 65; lIndex++) + { + *(ct++) = imColorEncode(HighContrastColors[lIndex].r, + HighContrastColors[lIndex].g, + HighContrastColors[lIndex].b); + } + + for (; lIndex < 256; lIndex++) + { + *(ct++) = imColorEncode((imbyte)lIndex, (imbyte)lIndex, (imbyte)lIndex); + } + + return palette; +} + +/* 256 divided in 6 steps results in these steps.*/ +static int iSixStepsTable[6] = {0, 51, 102, 153, 204, 255}; + +long* imPaletteUniform(void) +{ + long* palette = (long*)malloc(sizeof(long)*256); + long* ct = palette; + + for (int lRedIndex = 0; lRedIndex < 6; lRedIndex++) + for (int lGreenIndex = 0; lGreenIndex < 6; lGreenIndex++) + for (int lBlueIndex = 0; lBlueIndex < 6; lBlueIndex++) + { + imbyte red = (imbyte)iSixStepsTable[lRedIndex]; + imbyte green = (imbyte)iSixStepsTable[lGreenIndex]; + imbyte blue = (imbyte)iSixStepsTable[lBlueIndex]; + + *(ct++) = imColorEncode(red, green, blue); + } + + /* We initialize only 216 colors (6x6x6), rest 40 colors.*/ + /* Fill them with a gray scale palette.*/ + for (int lIndex = 6; lIndex < 246; lIndex += 6) + { + *(ct++) = imColorEncode((imbyte)lIndex, (imbyte)lIndex, (imbyte)lIndex); + } + + return palette; +} + +/* X divided by 51. Convert to 216 color space. */ +static int iDividedBy51Table[256] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5 +}; + +/* X multiplied by 36. Shift to red position.*/ +static int iTimes36Table[6] = {0, 36, 72, 108, 144, 180}; + +/* X multiplied by 36. Shift to green position.*/ +static int iTimes6Table[6] = {0, 6, 12, 18, 24, 30}; + +int imPaletteUniformIndex(long color) +{ + imbyte red, green, blue; + imColorDecode(&red, &green, &blue, color); + return iTimes36Table[iDividedBy51Table[red]] + iTimes6Table[iDividedBy51Table[green]] + iDividedBy51Table[blue]; +} + +/* Remainder of X divided by 51. Used to position in the halftone*/ +static int iModulo51Table[256] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 0 +}; + +/* Dither matrices for 8 bit to 2.6 bit halftones.*/ +static int iHalftone8x8Table[64] = +{ + 0, 38, 9, 47, 2, 40, 11, 50, + 25, 12, 35, 22, 27, 15, 37, 24, + 6, 44, 3, 41, 8, 47, 5, 43, + 31, 19, 28, 15, 34, 21, 31, 18, + 1, 39, 11, 49, 0, 39, 10, 48, + 27, 14, 36, 23, 26, 13, 35, 23, + 7, 46, 4, 43, 7, 45, 3, 42, + 33, 20, 30, 17, 32, 19, 29, 16 +}; + +int imPaletteUniformIndexHalftoned(long color, int x, int y) +{ + int lHalf = iHalftone8x8Table[(x % 8) * 8 + y % 8]; + + imbyte red, green, blue; + imColorDecode(&red, &green, &blue, color); + + /* Now, look up each value in the halftone matrix using an 8x8 ordered dither.*/ + int lRed = iDividedBy51Table[red] + (iModulo51Table[red] > lHalf? 1: 0); + int lGreen = iDividedBy51Table[green] + (iModulo51Table[green] > lHalf? 1: 0); + int lBlue = iDividedBy51Table[blue] + (iModulo51Table[blue] > lHalf? 1: 0); + + return iTimes36Table[lRed] + iTimes6Table[lGreen] + lBlue; +} -- cgit v1.2.3