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; }
static int iFileCheckPaletteGray(imFile* ifile) { int i; imbyte r, g, b; imbyte remaped[256]; memset(remaped, 0, 256); for (i = 0; i < ifile->palette_count; i++) { imColorDecode(&r, &g, &b, ifile->palette[i]); /* if there are colors abort */ if (r != g || g != b) return 0; /* grays out of order, will be remapped, but must be unique, if there are duplicates maybe they are used for different pourposes */ if (i != r) { if (!remaped[r]) remaped[r] = 1; else return 0; } } return 1; }
void imFileFormatAVI::WritePalette(unsigned char* bmp_colors) { /* convert the color map to the IM format */ for (int c = 0; c < this->palette_count; c++) { int i = c * 4; imColorDecode(&bmp_colors[i + 2], &bmp_colors[i + 1], &bmp_colors[i], this->palette[c]); bmp_colors[i + 3] = 0; } }
static int iFileCheckPaletteBinary(imFile* ifile) { if (ifile->palette_count > 2) return 0; imbyte r, g, b; imColorDecode(&r, &g, &b, ifile->palette[0]); if ((r != 0 || g != 0 || b != 0) && (r != 1 || g != 1 || b != 1) && (r != 255 || g != 255 || b != 255)) return 0; imColorDecode(&r, &g, &b, ifile->palette[1]); if ((r != 0 || g != 0 || b != 0) && (r != 1 || g != 1 || b != 1) && (r != 255 || g != 255 || b != 255)) return 0; return 1; }
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; }
static void iConvertMapToRGB(const imbyte* src_map, imbyte* red, imbyte* green, imbyte* blue, int count, const long* palette, const int palette_count) { imbyte r[256], g[256], b[256]; for (int c = 0; c < palette_count; c++) imColorDecode(&r[c], &g[c], &b[c], palette[c]); for (int i = 0; i < count; i++) { int index = *src_map++; *red++ = r[index]; *green++ = g[index]; *blue++ = b[index]; } }
/***************************************************************************\ * Decodes a color previously created. * * im.ColorDecode(c: color) -> (r, g, b: number) * \***************************************************************************/ static int imlua_colordecode(lua_State *L) { long color_i; unsigned char red_i, green_i, blue_i; if (!lua_islightuserdata(L, 1)) luaL_argerror(L, 1, "color must be a light user data"); color_i = (long)lua_touserdata(L,1); imColorDecode(&red_i, &green_i, &blue_i, color_i); lua_pushinteger(L, red_i); lua_pushinteger(L, green_i); lua_pushinteger(L, blue_i); return 3; }
int imFileFormatRAS::WritePalette() { int c; unsigned char ras_colors[256 * 3]; /* convert the color map to the IM format */ for (c = 0; c < this->palette_count; c++) { imColorDecode(&ras_colors[c], &ras_colors[c+this->palette_count], &ras_colors[c+2*this->palette_count], this->palette[c]); } /* writes the color palette */ imBinFileWrite(handle, ras_colors, this->palette_count * 3, 1); if (imBinFileError(handle)) return IM_ERR_ACCESS; return IM_ERR_NONE; }
static void iFileCheckConvertGray(imFile* ifile, imbyte* data) { int i, do_remap = 0; imbyte remap[256], r, g, b; // enforce the palette to only have grays in the correct order. for (i = 0; i < ifile->palette_count; i++) { imColorDecode(&r, &g, &b, ifile->palette[i]); if (r != i) { ifile->palette[i] = imColorEncode((imbyte)i, (imbyte)i, (imbyte)i); do_remap = 1; } remap[i] = r; } if (!do_remap) return; int count = ifile->width*ifile->height; for(i = 0; i < count; i++) { *data = remap[*data]; data++; } int transp_count; imbyte* transp_map = (imbyte*)imFileGetAttribute(ifile, "TransparencyMap", NULL, &transp_count); if (transp_map) { imbyte new_transp_map[256]; for (i=0; i<transp_count; i++) new_transp_map[i] = transp_map[remap[i]]; imFileSetAttribute(ifile, "TransparencyMap", IM_BYTE, transp_count, new_transp_map); } }
/* this function can also be use for RGBA images */ void ConvertMapToGLData(unsigned char* data, int count, int depth, long* palette, int palette_count) { int c, i; unsigned char r[256], g[256], b[256]; unsigned char* src_data = data + count-1; unsigned char* dst_data = data + depth*(count-1); for (c = 0; c < palette_count; c++) imColorDecode(&r[c], &g[c], &b[c], palette[c]); for (i = 0; i < count; i++) { int index = *src_data; *dst_data = r[index]; *(dst_data+1) = g[index]; *(dst_data+2) = b[index]; dst_data -= depth; src_data--; } }
void imConvertMapToRGB(unsigned char* data, int count, int depth, int packed, long* palette, int palette_count) { int c, i, delta; unsigned char r[256], g[256], b[256]; unsigned char *r_data, *g_data, *b_data; unsigned char* src_data = data + count-1; if (packed) { r_data = data + depth*(count-1); g_data = r_data + 1; b_data = r_data + 2; delta = depth; } else { r_data = data + count - 1; g_data = data + 2*count - 1; b_data = data + 3*count - 1; delta = 1; } for (c = 0; c < palette_count; c++) imColorDecode(&r[c], &g[c], &b[c], palette[c]); for (i = 0; i < count; i++) { int index = *src_data; *r_data = r[index]; *g_data = g[index]; *b_data = b[index]; r_data -= delta; g_data -= delta; b_data -= delta; src_data--; } }
int imFileFormatLED::WritePalette() { int c; unsigned char r, g, b; imBinFileWrite(handle, (void*)"[\n", 2, 1); /* convert the color map from the IM format */ for (c = 0; c < this->palette_count; c++) { imColorDecode(&r, &g, &b, this->palette[c]); imBinFilePrintf(handle, "%d = \"%d %d %d\"", c, (int)r, (int)g, (int)b); if (c != this->palette_count - 1) imBinFileWrite(handle, (void*)",\n", 2, 1); } imBinFileWrite(handle, (void*)"]\n", 2, 1); if (imBinFileError(handle)) return IM_ERR_ACCESS; return IM_ERR_NONE; }
int imPaletteUniformIndex(long color) { imbyte red, green, blue; imColorDecode(&red, &green, &blue, color); return iTimes36Table[iDividedBy51Table[red]] + iTimes6Table[iDividedBy51Table[green]] + iDividedBy51Table[blue]; }
void imDecodeColor(unsigned char* Red, unsigned char* Green, unsigned char* Blue, long Color) { imColorDecode(Red, Green, Blue, Color); }
void imCalcGrayHistogram(const imImage* image, unsigned long* histo, int cumulative) { int hcount = imHistogramCount(image->data_type); if (image->color_space == IM_GRAY) imCalcHistogram(image, histo, 0, cumulative); else { int i; memset(histo, 0, hcount * sizeof(unsigned long)); if (image->color_space == IM_MAP || image->color_space == IM_BINARY) { imbyte* map = (imbyte*)image->data[0]; imbyte gray_map[256], r, g, b; for (i = 0; i < image->palette_count; i++) { imColorDecode(&r, &g, &b, image->palette[i]); gray_map[i] = imColorRGB2Luma(r, g, b); } #ifdef _OPENMP #pragma omp parallel for if (IM_OMP_MINCOUNT(image->count)) #endif for (i = 0; i < image->count; i++) { int index = gray_map[map[i]]; #ifdef _OPENMP #pragma omp atomic #endif histo[index]++; } } else // RGB { if (image->data_type == IM_USHORT) { imushort* r = (imushort*)image->data[0]; imushort* g = (imushort*)image->data[1]; imushort* b = (imushort*)image->data[2]; #ifdef _OPENMP #pragma omp parallel for if (IM_OMP_MINCOUNT(image->count)) #endif for (i = 0; i < image->count; i++) { imushort index = imColorRGB2Luma(*r++, *g++, *b++); #ifdef _OPENMP #pragma omp atomic #endif histo[index]++; } } else if (image->data_type == IM_SHORT) { short* r = (short*)image->data[0]; short* g = (short*)image->data[1]; short* b = (short*)image->data[2]; #ifdef _OPENMP #pragma omp parallel for if (IM_OMP_MINCOUNT(image->count)) #endif for (i = 0; i < image->count; i++) { int index = imColorRGB2Luma(*r++, *g++, *b++) + 32768; #ifdef _OPENMP #pragma omp atomic #endif histo[index]++; } } else { imbyte* r = (imbyte*)image->data[0]; imbyte* g = (imbyte*)image->data[1]; imbyte* b = (imbyte*)image->data[2]; #ifdef _OPENMP #pragma omp parallel for if (IM_OMP_MINCOUNT(image->count)) #endif for (i = 0; i < image->count; i++) { imbyte index = imColorRGB2Luma(*r++, *g++, *b++); #ifdef _OPENMP #pragma omp atomic #endif histo[index]++; } } } if (cumulative) { /* make cumulative histogram */ for (i = 1; i < hcount; i++) histo[i] += histo[i-1]; } } }