static void analyzeDistribution(struct pam * const inpamP, bool const verbose, const unsigned int ** const histogramP, struct range * const rangeP) { /*---------------------------------------------------------------------------- Find the distribution of the sample values -- minimum, maximum, and how many of each value -- in input image *inpamP, whose file is positioned to the raster. Return the minimum and maximum as *rangeP and the frequency distribution as *histogramP, an array such that histogram[i] is the number of pixels that have sample value i. Assume the file is positioned to the raster upon entry and leave it positioned at the same place. -----------------------------------------------------------------------------*/ unsigned int row; tuple * inrow; tuplen * inrown; unsigned int * histogram; /* malloced array */ unsigned int i; pm_filepos rasterPos; /* Position in input file of the raster */ pm_tell2(inpamP->file, &rasterPos, sizeof(rasterPos)); inrow = pnm_allocpamrow(inpamP); inrown = pnm_allocpamrown(inpamP); MALLOCARRAY(histogram, inpamP->maxval+1); if (histogram == NULL) pm_error("Unable to allocate space for %lu-entry histogram", inpamP->maxval+1); /* Initialize histogram -- zero occurrences of everything */ for (i = 0; i <= inpamP->maxval; ++i) histogram[i] = 0; initRange(rangeP); for (row = 0; row < inpamP->height; ++row) { unsigned int col; pnm_readpamrow(inpamP, inrow); pnm_normalizeRow(inpamP, inrow, NULL, inrown); for (col = 0; col < inpamP->width; ++col) { ++histogram[inrow[col][0]]; addToRange(rangeP, inrown[col][0]); } } *histogramP = histogram; pnm_freepamrow(inrow); pnm_freepamrown(inrown); pm_seek2(inpamP->file, &rasterPos, sizeof(rasterPos)); if (verbose) pm_message("Pixel values range from %f to %f", rangeP->min, rangeP->max); }
static void analyzeImage(FILE * const ifP, unsigned int const cols, unsigned int const rows, xelval const maxval, int const format, enum bg_choice const backgroundReq, imageFilePos const newFilePos, xel * const backgroundColorP, bool * const hasBordersP, borderSet * const borderSizeP) { /*---------------------------------------------------------------------------- Analyze the PNM image on file stream *ifP to determine its borders and the color of those borders (the assumed background color). Return as *backgroundColorP the background color. Return as *borderSizeP the set of border sizes (one for each of the four edges). But iff there are no borders, don't return anything as *borderSizeP and return *hasBordersP == false. Expect *ifP to be positioned right after the header and seekable. Return with it positioned either before or after the raster, as requested by 'newFilePos'. -----------------------------------------------------------------------------*/ pm_filepos rasterpos; xel background; pm_tell2(ifP, &rasterpos, sizeof(rasterpos)); background = computeBackground(ifP, cols, rows, maxval, format, backgroundReq); pm_seek2(ifP, &rasterpos, sizeof(rasterpos)); findBordersInImage(ifP, cols, rows, maxval, format, background, hasBordersP, borderSizeP); if (newFilePos == FILEPOS_BEG) pm_seek2(ifP, &rasterpos, sizeof(rasterpos)); *backgroundColorP = background; }
int main(int argc, char *argv[]) { struct cmdlineInfo cmdline; struct pam inpam; FILE * ifP; pm_filepos rasterpos; tuple backgroundColor; const unsigned char * const * pi; pnm_init(&argc, argv); parseCommandLine(argc, argv, &cmdline); ifP = pm_openr_seekable(cmdline.inputFileName); pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); pm_tell2(ifP, &rasterpos, sizeof(rasterpos)); determineBackgroundColor(&inpam, cmdline.verbose, &backgroundColor); pm_seek2(ifP, &rasterpos, sizeof(rasterpos)); findBackgroundPixels(&inpam, backgroundColor, cmdline.verbose, &pi); writeOutput(&inpam, pi); destroyPi(pi, inpam.height); pm_close(ifP); pnm_freepamtuple(backgroundColor); return 0; }
static void convertImage(FILE * const ifP, TIFF * const tifP, const char * const inputFileDescription, struct cmdlineInfo const cmdline) { tupletable chv; tuplehash cht; unsigned short ** tiffColorMap; /* malloc'ed */ struct pam pam; unsigned int colors; bool grayscale; unsigned short photometric; unsigned short samplesperpixel; unsigned short bitspersample; unsigned short tiff_maxval; /* This is the maxval of the samples in the tiff file. It is determined solely by the bits per sample ('bitspersample'). */ int bytesperrow; pm_filepos rasterPos; pnm_readpaminit(ifP, &pam, PAM_STRUCT_SIZE(tuple_type)); pm_tell2(ifP, &rasterPos, sizeof(rasterPos)); analyzeColors(&pam, cmdline, MAXCOLORS, &chv, &colors, &grayscale); /* Go back to beginning of raster */ pm_seek2(ifP, &rasterPos, sizeof(rasterPos)); /* Figure out TIFF parameters. */ computeRasterParm(&pam, chv, colors, grayscale, cmdline.compression, cmdline.minisblack, cmdline.miniswhite, cmdline.indexsizeAllowed, &samplesperpixel, &bitspersample, &photometric, &bytesperrow); tiff_maxval = pm_bitstomaxval(bitspersample); if (!chv) { cht = NULL; tiffColorMap = NULL; } else { createTiffColorMap(&pam, bitspersample, chv, colors, &tiffColorMap); /* Convert color vector to color hash table, for fast lookup. */ cht = pnm_computetupletablehash(&pam, chv, colors); pnm_freetupletable(&pam, chv); } setTiffFields(tifP, cmdline, &pam, bitspersample, photometric, samplesperpixel, tiffColorMap, inputFileDescription, cmdline.taglist); writeScanLines(&pam, tifP, cht, tiff_maxval, bitspersample, photometric, bytesperrow, cmdline.fillorder); if (tiffColorMap) destroyTiffColorMap(&pam, tiffColorMap); }