diff options
Diffstat (limited to 'converter/other/pnmtopalm/palmcolormap.c')
-rw-r--r-- | converter/other/pnmtopalm/palmcolormap.c | 134 |
1 files changed, 82 insertions, 52 deletions
diff --git a/converter/other/pnmtopalm/palmcolormap.c b/converter/other/pnmtopalm/palmcolormap.c index 0f47558c..1341ca2b 100644 --- a/converter/other/pnmtopalm/palmcolormap.c +++ b/converter/other/pnmtopalm/palmcolormap.c @@ -4,18 +4,46 @@ #include "pm_c_util.h" #include "mallocvar.h" #include "pnm.h" - #include "palm.h" +#include "palmcolormap.h" + + + +static pixval +scaleSample(pixval const arg, + pixval const oldMaxval, + pixval const newMaxval) { + + return (arg * newMaxval + oldMaxval/2) / oldMaxval; +} + + + +ColormapEntry +palmcolor_mapEntryColorFmPixel(pixel const color, + pixval const maxval, + pixval const newMaxval) { + + + return + 0 + | (scaleSample(PPM_GETR(color), maxval, newMaxval) << 16) + | (scaleSample(PPM_GETG(color), maxval, newMaxval) << 8) + | (scaleSample(PPM_GETB(color), maxval, newMaxval) << 0); +} + + + int palmcolor_compare_indices(const void * const p1, const void * const p2) { /*---------------------------------------------------------------------------- This is a 'qsort' collation function. -----------------------------------------------------------------------------*/ - if ((*((Color) p1) & 0xFF000000) < (*((Color) p2) & 0xFF000000)) + if ((*((ColormapEntry *) p1) & 0xFF000000) < (*((ColormapEntry *) p2) & 0xFF000000)) return -1; - else if ((*((Color) p1) & 0xFF000000) > (*((Color) p2) & 0xFF000000)) + else if ((*((ColormapEntry *) p1) & 0xFF000000) > (*((ColormapEntry *) p2) & 0xFF000000)) return 1; else return 0; @@ -165,86 +193,88 @@ static int PalmPalette8bpp[256][3] = -Colormap +Colormap * palmcolor_build_default_8bit_colormap(void) { unsigned int i; - Colormap cm; + Colormap * cmP; - MALLOCVAR_NOFAIL(cm); - cm->nentries = 232; - MALLOCARRAY_NOFAIL(cm->color_entries, cm->nentries); + MALLOCVAR_NOFAIL(cmP); + cmP->nentries = 232; + MALLOCARRAY_NOFAIL(cmP->color_entries, cmP->nentries); /* Fill in the colors */ for (i = 0; i < 231; ++i) { - cm->color_entries[i] = ((i << 24) | + cmP->color_entries[i] = ((i << 24) | (PalmPalette8bpp[i][0] << 16) | (PalmPalette8bpp[i][1] << 8) | (PalmPalette8bpp[i][2])); } - cm->color_entries[231] = 0xFF000000; - cm->ncolors = 232; + cmP->color_entries[231] = 0xFF000000; + cmP->ncolors = 232; /* now sort the table */ - qsort (cm->color_entries, cm->ncolors, sizeof(Color_s), - palmcolor_compare_colors); - return cm; + qsort(cmP->color_entries, cmP->ncolors, sizeof(ColormapEntry), + palmcolor_compare_colors); + return cmP; } -Colormap -palmcolor_build_custom_8bit_colormap(unsigned int const rows, +Colormap * +palmcolor_build_custom_8bit_colormap(pixel ** const pixels, + unsigned int const rows, unsigned int const cols, - pixel ** const pixels) { + pixval const maxval) { + unsigned int row; - Colormap colormap; + Colormap * colormapP; - MALLOCVAR_NOFAIL(colormap); - colormap->nentries = 256; - MALLOCARRAY_NOFAIL(colormap->color_entries, colormap->nentries); - colormap->ncolors = 0; /* initial value */ + MALLOCVAR_NOFAIL(colormapP); + colormapP->nentries = 256; + MALLOCARRAY_NOFAIL(colormapP->color_entries, colormapP->nentries); + colormapP->ncolors = 0; /* initial value */ for (row = 0; row < rows; ++row) { unsigned int col; for (col = 0; col < cols; ++col) { - Color found; - Color_s temp; - - temp = ((PPM_GETR(pixels[row][col]) << 16) | - (PPM_GETG(pixels[row][col]) << 8) | - PPM_GETB(pixels[row][col])); - found = (bsearch (&temp, - colormap->color_entries, colormap->ncolors, - sizeof(Color_s), palmcolor_compare_colors)); - if (!found) { - if (colormap->ncolors >= colormap->nentries) + ColormapEntry * foundEntryP; + ColormapEntry const searchTarget = + palmcolor_mapEntryColorFmPixel(pixels[row][col], maxval, 255); + + foundEntryP = + bsearch(&searchTarget, + colormapP->color_entries, colormapP->ncolors, + sizeof(ColormapEntry), palmcolor_compare_colors); + if (!foundEntryP) { + if (colormapP->ncolors >= colormapP->nentries) pm_error("Too many colors for custom colormap " - "(max 256). " + "(max %u). " "Try using pnmquant to reduce the number " - "of colors."); + "of colors.", colormapP->nentries); else { /* add the new color, and re-sort */ - temp |= ((colormap->ncolors) << 24); - colormap->color_entries[colormap->ncolors] = temp; - colormap->ncolors += 1; - qsort(colormap->color_entries, colormap->ncolors, - sizeof(Color_s), palmcolor_compare_colors); + unsigned int const colorIndex = colormapP->ncolors++; + ColormapEntry const newEntry = + searchTarget | (colorIndex << 24); + colormapP->color_entries[colorIndex] = newEntry; + qsort(colormapP->color_entries, colormapP->ncolors, + sizeof(ColormapEntry), palmcolor_compare_colors); } } } } - return colormap; + return colormapP; } -Colormap +Colormap * palmcolor_read_colormap (FILE * const ifP) { unsigned short ncolors; - Colormap retval; + Colormap * retval; int rc; rc = pm_readbigshort(ifP, (short *) &ncolors); @@ -252,13 +282,13 @@ palmcolor_read_colormap (FILE * const ifP) { retval = NULL; else { long colorentry; - Colormap colormap; + Colormap * colormapP; unsigned int i; bool error; - MALLOCVAR_NOFAIL(colormap); - colormap->nentries = ncolors; - MALLOCARRAY_NOFAIL(colormap->color_entries, colormap->nentries); + MALLOCVAR_NOFAIL(colormapP); + colormapP->nentries = ncolors; + MALLOCARRAY_NOFAIL(colormapP->color_entries, colormapP->nentries); for (i = 0, error = FALSE; i < ncolors && !error; ++i) { int rc; @@ -266,15 +296,15 @@ palmcolor_read_colormap (FILE * const ifP) { if (rc != 0) error = TRUE; else - colormap->color_entries[i] = (colorentry & 0xFFFFFFFF); + colormapP->color_entries[i] = (colorentry & 0xFFFFFFFF); } if (error) { - free (colormap->color_entries); - free (colormap); + free (colormapP->color_entries); + free (colormapP); retval = NULL; } else { - colormap->ncolors = ncolors; - retval = colormap; + colormapP->ncolors = ncolors; + retval = colormapP; } } return retval; |