static void generateStandardPalette(struct pcxCmapEntry ** const pcxcmapP, pixval const maxval, colorhash_table * const chtP, int * const colorsP) { unsigned int const stdPaletteSize = 16; unsigned int colorIndex; struct pcxCmapEntry * pcxcmap; colorhash_table cht; MALLOCARRAY_NOFAIL(pcxcmap, MAXCOLORS); *pcxcmapP = pcxcmap; cht = ppm_alloccolorhash(); for (colorIndex = 0; colorIndex < stdPaletteSize; ++colorIndex) { pixel pcxColor; /* The color of this colormap entry, in PCX resolution */ pcxcmap[colorIndex] = stdPalette[colorIndex]; PPM_ASSIGN(pcxColor, stdPalette[colorIndex].r, stdPalette[colorIndex].g, stdPalette[colorIndex].b); putPcxColorInHash(cht, pcxColor, colorIndex, maxval); } *chtP = cht; *colorsP = stdPaletteSize; }
static void computecolorhash(pixel ** const pixels, gray ** const alpha, int const cols, int const rows, gray const alphaMaxval, colorhash_table * const chtP, unsigned int * const ncolorsP, bool * const transparentSomewhereP) { /*---------------------------------------------------------------------------- Compute a colorhash_table with one entry for each color in 'pixels' that is not mostly transparent according to alpha mask 'alpha' (which has maxval 'alphaMaxval'). alpha == NULL means all pixels are opaque. The value associated with the color in the hash we build is meaningless. Return the colorhash_table as *chtP, and the number of colors in it as *ncolorsP. Return *transparentSomewhereP == TRUE iff the image has at least one pixel that is mostly transparent. -----------------------------------------------------------------------------*/ colorhash_table cht; int row; cht = ppm_alloccolorhash( ); *ncolorsP = 0; /* initial value */ *transparentSomewhereP = FALSE; /* initial assumption */ /* Go through the entire image, building a hash table of colors. */ for (row = 0; row < rows; ++row) { int col; for (col = 0; col < cols; ++col) { if (!alpha || alpha[row][col] > alphaMaxval/2) { /* It's mostly opaque, so add this color to the hash if it's not already there. */ pixel const color = pixels[row][col]; int const lookupRc = ppm_lookupcolor(cht, &color); if (lookupRc < 0) { /* It's not in the hash yet, so add it */ ppm_addtocolorhash(cht, &color, 0); ++(*ncolorsP); } } else *transparentSomewhereP = TRUE; } } *chtP = cht; }
void ppm_readcolordict(const char * const fileName, int const mustOpen, unsigned int * const nColorsP, const char *** const colornamesP, pixel ** const colorsP, colorhash_table * const chtP) { colorhash_table cht; const char ** colornames; pixel * colors; unsigned int nColors; cht = ppm_alloccolorhash(); MALLOCARRAY(colornames, MAXCOLORNAMES); colors = ppm_allocrow(MAXCOLORNAMES); if (colornames == NULL) pm_error("Unable to allocate space for colorname table."); readcolordict(fileName, mustOpen, &nColors, colornames, colors, cht); if (chtP) *chtP = cht; else ppm_freecolorhash(cht); if (colornamesP) *colornamesP = colornames; else ppm_freecolornames(colornames); if (colorsP) *colorsP = colors; else ppm_freerow(colors); if (nColorsP) *nColorsP = nColors; }
static void readPaletteFromFile(struct pcxCmapEntry ** const pcxcmapP, const char * const paletteFileName, pixval const maxval, colorhash_table * const chtP, int * const colorsP) { unsigned int colorIndex; pixel ppmPalette[MAXCOLORS]; unsigned int paletteSize; struct pcxCmapEntry * pcxcmap; colorhash_table cht; readPpmPalette(paletteFileName, &ppmPalette, &paletteSize); MALLOCARRAY_NOFAIL(pcxcmap, MAXCOLORS); *pcxcmapP = pcxcmap; cht = ppm_alloccolorhash(); for (colorIndex = 0; colorIndex < paletteSize; ++colorIndex) { pixel pcxColor; /* The color of this colormap entry, in PCX resolution */ pcxcmap[colorIndex] = pcxCmapEntryFromPixel(ppmPalette[colorIndex]); PPM_ASSIGN(pcxColor, ppmPalette[colorIndex].r, ppmPalette[colorIndex].g, ppmPalette[colorIndex].b); putPcxColorInHash(cht, pcxColor, colorIndex, maxval); } *chtP = cht; *colorsP = paletteSize; }