static void computeColormap(pixel ** const pixels, gray ** const alpha, int const cols, int const rows, gray const alphaMaxval, colorhist_vector * const chvP, colorhash_table * const chtP, unsigned int * const ncolorsP, bool * const transparentSomewhereP) { /*---------------------------------------------------------------------------- Compute the color map for the image 'pixels', which is 'cols' by 'rows', in Netpbm data structures (a colorhist_vector for index-to-color lookups and a colorhash_table for color-to-index lookups). Exclude pixels that alpha mask 'alpha' (which has maxval 'alphaMaxval') says are mostly transparent. alpha == NULL means all pixels are opaque. We return as *chvP an array of the colors present in 'pixels', excluding those that are mostly transparent. We return as *ncolorsP the number of such colors. We return *transparentSomewhereP == TRUE iff the image has at least one pixel that is mostly transparent. -----------------------------------------------------------------------------*/ colorhash_table histCht; pm_message("(Computing colormap..."); computecolorhash(pixels, alpha, cols, rows, alphaMaxval, &histCht, ncolorsP, transparentSomewhereP); pm_message("...Done. %d colors found.)", *ncolorsP); *chvP = ppm_colorhashtocolorhist(histCht, *ncolorsP); ppm_freecolorhash(histCht); /* Despite the name, the following generates an index on *chvP, with which given a color you can quickly find the entry number in *chvP that contains that color. */ *chtP = ppm_colorhisttocolorhash(*chvP, *ncolorsP); }
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; }
int main(int argc, char *argv[]) { struct cmdlineInfo cmdline; FILE* ifP; int rows, cols; pixval maxval; pixel **pixels; struct pcxCmapEntry * pcxcmap; colorhash_table cht; bool truecolor; int colors; ppm_init(&argc, argv); parseCommandLine(argc, argv, &cmdline); ifP = pm_openr(cmdline.inputFilespec); pixels = ppm_readppm(ifP, &cols, &rows, &maxval); pm_close(ifP); if (cmdline.truecolor) truecolor = TRUE; else { if (cmdline.stdpalette) { truecolor = FALSE; generateStandardPalette(&pcxcmap, maxval, &cht, &colors); } else if (cmdline.palette) { truecolor = FALSE; readPaletteFromFile(&pcxcmap, cmdline.palette, maxval, &cht, &colors); } else { bool tooManyColors; makePcxColormapFromImage(pixels, cols, rows, maxval, &pcxcmap, &cht, &colors, &tooManyColors); if (tooManyColors) { pm_message("too many colors - writing a 24bit PCX file"); pm_message("if you want a non-24bit file, " " a 'pnmquant %d'", MAXCOLORS); truecolor = TRUE; } else truecolor = FALSE; } } if (truecolor) ppmToTruecolorPcx(pixels, cols, rows, maxval, cmdline.xpos, cmdline.ypos); else { ppmToPalettePcx(pixels, cols, rows, maxval, cmdline.xpos, cmdline.ypos, pcxcmap, cht, colors, cmdline.packed, cmdline.planes, cmdline.use_8_bit); ppm_freecolorhash(cht); free(pcxcmap); } return 0; }
int main(int argc, char *argv[]) { FILE *ifp; int rows, cols; unsigned int ncolors; bool transparentSomewhere; pixval maxval, alphaMaxval; colorhash_table cht; colorhist_vector chv; colorhash_table colornameHash; /* Hash table to map colors to their names */ const char ** colornames; /* Table of color names; 'colornameHash' yields an index into this array. */ pixel **pixels; gray **alpha; /* Used for rgb value -> character-pixel string mapping */ cixel_map *cmap; /* malloc'ed */ /* The XPM colormap */ unsigned int cmapSize; /* Number of entries in 'cmap' */ unsigned int transIndex; /* Index into 'cmap' of the transparent color, if there is one */ unsigned int charsPerPixel; struct cmdlineInfo cmdline; ppm_init(&argc, argv); parseCommandLine(argc, argv, &cmdline); ifp = pm_openr(cmdline.inputFilename); pixels = ppm_readppm(ifp, &cols, &rows, &maxval); pm_close(ifp); if (cmdline.alpha_filename) readAlpha(cmdline.alpha_filename, &alpha, cols, rows, &alphaMaxval); else alpha = NULL; computeColormap(pixels, alpha, cols, rows, alphaMaxval, &chv, &cht, &ncolors, &transparentSomewhere); if (cmdline.hexonly) colornameHash = NULL; else if (cmdline.rgb) ppm_readcolornamefile(cmdline.rgb, TRUE, &colornameHash, &colornames); else ppm_readcolornamefile(NULL, FALSE, &colornameHash, &colornames); /* Now generate the character-pixel colormap table. */ genCmap(chv, ncolors, maxval, colornameHash, colornames, transparentSomewhere, &cmap, &transIndex, &cmapSize, &charsPerPixel); writeXpmFile(stdout, pixels, alpha, alphaMaxval, cmdline.name, cols, rows, cmapSize, charsPerPixel, cmap, cht, transIndex); if (colornameHash) { ppm_freecolorhash(colornameHash); ppm_freecolornames(colornames); } destroyCmap(cmap, cmapSize); ppm_freearray(pixels, rows); if (alpha) pgm_freearray(alpha, rows); return 0; }