diff options
| author | Pixel <pixel@nobis-crew.org> | 2009-11-04 11:56:41 -0800 | 
|---|---|---|
| committer | Pixel <pixel@nobis-crew.org> | 2009-11-04 11:59:33 -0800 | 
| commit | d577d991b97ae2b5ee1af23641bcffc3f83af5b2 (patch) | |
| tree | 590639d50205d1bcfaff2a7d2dc6ebf3f373c7ed /im/src/im_palette.cpp | |
Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux.
Diffstat (limited to 'im/src/im_palette.cpp')
| -rwxr-xr-x | im/src/im_palette.cpp | 551 | 
1 files changed, 551 insertions, 0 deletions
diff --git a/im/src/im_palette.cpp b/im/src/im_palette.cpp new file mode 100755 index 0000000..0e6f967 --- /dev/null +++ b/im/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 <stdlib.h> +#include <memory.h> +#include <assert.h> +#include <math.h> + +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; +}  | 
