static void getLookup(const char * const lookupFileName, tuple *** const lookupP, struct pam * const lookuppamP) { /*---------------------------------------------------------------------------- Get the lookup image (the one that maps integers to tuples, e.g. a color index / color map / palette) from the file named 'lookupFileName'. Return the image as *lookupP and *lookuppamP. -----------------------------------------------------------------------------*/ FILE * lookupfileP; struct pam inputLookuppam; tuple ** inputLookup; lookupfileP = pm_openr(lookupFileName); inputLookup = pnm_readpam(lookupfileP, &inputLookuppam, PAM_STRUCT_SIZE(tuple_type)); pm_close(lookupfileP); if (inputLookuppam.height != 1) pm_error("The lookup table image must be one row. " "Yours is %u rows.", inputLookuppam.height); *lookupP = inputLookup; *lookuppamP = inputLookuppam; }
static void processMapFile(const char * const mapFileName, struct pam * const outpamCommonP, tupletable * const colormapP, unsigned int * const colormapSizeP, tuple * const firstColorP) { /*---------------------------------------------------------------------------- Read a color map from the file named 'mapFileName'. It's a map that associates each color in that file with a unique whole number. Return the map as *colormapP, with the number of entries in it as *colormapSizeP. Also determine the first color (top left) in the map file and return that as *firstColorP. -----------------------------------------------------------------------------*/ FILE * mapfile; struct pam mappam; tuple ** maptuples; tuple firstColor; mapfile = pm_openr(mapFileName); maptuples = pnm_readpam(mapfile, &mappam, PAM_STRUCT_SIZE(tuple_type)); pm_close(mapfile); computeColorMapFromMap(&mappam, maptuples, colormapP, colormapSizeP); firstColor = pnm_allocpamtuple(&mappam); pnm_assigntuple(&mappam, firstColor, maptuples[0][0]); *firstColorP = firstColor; pnm_freepamarray(maptuples, &mappam); *outpamCommonP = mappam; outpamCommonP->file = stdout; }
static void initPatternPixel(outGenerator * const outGenP, struct cmdlineInfo const cmdline) { struct patternPixelState * stateP; FILE * patternFileP; MALLOCVAR_NOFAIL(stateP); patternFileP = pm_openr(cmdline.patFilespec); stateP->patTuples = pnm_readpam(patternFileP, &stateP->patPam, PAM_STRUCT_SIZE(tuple_type)); pm_close(patternFileP); stateP->xshift = cmdline.xshift; stateP->yshift = cmdline.yshift; stateP->magnifypat = cmdline.magnifypat; outGenP->stateP = stateP; outGenP->getTuple = &patternPixel; outGenP->terminateState = &termPatternPixel; outGenP->pam.format = stateP->patPam.format; outGenP->pam.plainformat = stateP->patPam.plainformat; outGenP->pam.depth = stateP->patPam.depth; outGenP->pam.maxval = stateP->patPam.maxval; strcpy(outGenP->pam.tuple_type, stateP->patPam.tuple_type); if (cmdline.verbose) reportImageParameters("Pattern file", &stateP->patPam); }
int main(int argc, char *argv[]) { struct cmdlineInfo cmdline; FILE * ifP; tuple ** tuples; struct pam pam; int ncolors; tupletable chv; tuplehash cht; struct ImageHeader tgaHeader; enum TGAbaseImageType baseImgType; bool withAlpha; const char *outName; pnm_init( &argc, argv ); parseCommandLine(argc, argv, &cmdline); ifP = pm_openr(cmdline.inputFilespec); computeOutName(cmdline, &outName); tuples = pnm_readpam(ifP, &pam, PAM_STRUCT_SIZE(tuple_type)); pm_close(ifP); computeImageType_cht(&pam, cmdline, tuples, &baseImgType, &withAlpha, &chv, &cht, &ncolors); /* Do the Targa header */ computeTgaHeader(&pam, baseImgType, withAlpha, !cmdline.norle, ncolors, 0, outName, &tgaHeader); writeTgaHeader(tgaHeader); if (baseImgType == TGA_MAP_TYPE) { /* Write out the Targa colormap. */ int i; for (i = 0; i < ncolors; ++i) putMapEntry(&pam, chv[i]->tuple, tgaHeader.CoSize); } writeTgaRaster(&pam, tuples, cht, baseImgType, withAlpha, !cmdline.norle, 0); if (cht) pnm_destroytuplehash(cht); if (chv) pnm_freetupletable(&pam, chv); releaseTgaHeader(tgaHeader); strfree(outName); pnm_freepamarray(tuples, &pam); return 0; }
int main(int argc, char *argv[]) { FILE * const rlefile = stdout; struct cmdlineInfo cmdline; FILE *ifP; /* Input (Netpbm) file */ struct pam pam; /* Description of the image */ tuple ** tupleArray; /* The image raster */ tupletable colormap; /* List of all of the colors used */ unsigned int numColors; /* Number of unique colors in the color map */ tuplehash colorhash; /* Mapping from color to index into colormap[] */ tuple transcolor; /* Color that should be considered transparent */ pnm_init (&argc, argv); parseCommandLine(argc, argv, &cmdline); ifP = pm_openr(cmdline.inputFilespec); tupleArray = pnm_readpam(ifP, &pam, PAM_STRUCT_SIZE(tuple_type)); transcolor = pnm_parsecolor(cmdline.transparent, pam.maxval); computeColorMap(&pam, tupleArray, &numColors, &colormap, &colorhash, cmdline.showcolormap); makeDjvurleHeader(rlefile, &pam, numColors, colormap); /* Write the raster */ { unsigned int row; for (row = 0; row < pam.height; ++row) writeDjvurleRow(rlefile, &pam, tupleArray[row], colorhash, transcolor); } /* Clean up */ pnm_freepamarray(tupleArray, &pam); pnm_freetupletable(&pam, colormap); pnm_destroytuplehash(colorhash); pnm_freepamtuple(transcolor); pm_close(ifP); return 0; }
static void wipeoutTb(FILE * const ifP, FILE * const ofP) { /* top-bottom we have to read the full image */ struct pam inpam, outpam; tuple ** tuples; tuples = pnm_readpam(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); outpam = inpam; outpam.file = ofP; wipeImgByRow(inpam, tuples); pnm_writepam(&outpam, tuples); pnm_freepamarray(tuples, &inpam); }
static void doHilbert(FILE * const ifP, unsigned int const clumpSize) { /*---------------------------------------------------------------------------- Use hilbert space filling curve dithering -----------------------------------------------------------------------------*/ /* * This is taken from the article "Digital Halftoning with * Space Filling Curves" by Luiz Velho, proceedings of * SIGRAPH '91, page 81. * * This is not a terribly efficient or quick version of * this algorithm, but it seems to work. - Graeme Gill. * [email protected] * */ struct pam graypam; struct pam bitpam; tuple ** grays; tuple ** bits; int end; int *x,*y; int sum; grays = pnm_readpam(ifP, &graypam, PAM_STRUCT_SIZE(tuple_type)); bitpam = makeOutputPam(graypam.width, graypam.height); bits = pnm_allocpamarray(&bitpam); MALLOCARRAY(x, clumpSize); MALLOCARRAY(y, clumpSize); if (x == NULL || y == NULL) pm_error("out of memory"); initHilbert(graypam.width, graypam.height); sum = 0; end = clumpSize; while (end == clumpSize) { unsigned int i; /* compute the next cluster co-ordinates along hilbert path */ for (i = 0; i < end; i++) { if (hilbert(&x[i],&y[i])==0) end = i; /* we reached the end */ } /* sum levels */ for (i = 0; i < end; i++) sum += grays[y[i]][x[i]][0]; /* dither half and half along path */ for (i = 0; i < end; i++) { unsigned int const row = y[i]; unsigned int const col = x[i]; if (sum >= graypam.maxval) { bits[row][col][0] = 1; sum -= graypam.maxval; } else bits[row][col][0] = 0; } } pnm_writepam(&bitpam, bits); pnm_freepamarray(bits, &bitpam); pnm_freepamarray(grays, &graypam); }