static void extractOneImage(FILE * const infileP, FILE * const outfileP) { struct pam inpam; struct pam outpam; enum pm_check_code checkRetval; unsigned int row; tuple * tuplerow; pnm_readpaminit(infileP, &inpam, PAM_STRUCT_SIZE(tuple_type)); pnm_checkpam(&inpam, PM_CHECK_BASIC, &checkRetval); outpam = inpam; outpam.file = outfileP; pnm_writepaminit(&outpam); tuplerow = pnm_allocpamrow(&inpam); for (row = 0; row < inpam.height; ++row) { pnm_readpamrow(&inpam, tuplerow); pnm_writepamrow(&outpam, tuplerow); } pnm_freepamrow(tuplerow); }
static void wipeoutLr(FILE * const ifP, FILE * const ofP) { /* left-right we can read row-by-row */ struct pam inpam, outpam; tuple ** tuples; tuple * tuplerow; unsigned int row; pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); outpam = inpam; outpam.file = ofP; pnm_writepaminit(&outpam); tuplerow = pnm_allocpamrow(&inpam); for (row = 0; row < inpam.height; ++row) { pnm_readpamrow(&inpam, tuplerow); wipeRowByCol(inpam, tuples, tuplerow); pnm_writepamrow(&outpam, tuplerow); } pnm_freepamrow(tuplerow); }
static void extractOneImage(FILE * const infileP, FILE * const outfileP) { /*---------------------------------------------------------------------------- Copy a complete image from input stream *infileP to output stream *outfileP. But if outfileP == NULL, just read the image and discard it. -----------------------------------------------------------------------------*/ struct pam inpam; struct pam outpam; enum pm_check_code checkRetval; unsigned int row; tuple * tuplerow; pnm_readpaminit(infileP, &inpam, PAM_STRUCT_SIZE(tuple_type)); pnm_checkpam(&inpam, PM_CHECK_BASIC, &checkRetval); outpam = inpam; outpam.file = outfileP; if (outfileP) pnm_writepaminit(&outpam); tuplerow = pnm_allocpamrow(&inpam); for (row = 0; row < inpam.height; ++row) { pnm_readpamrow(&inpam, tuplerow); if (outfileP) pnm_writepamrow(&outpam, tuplerow); } pnm_freepamrow(tuplerow); }
static void readRelevantPixels(const char * const inputFilename, unsigned int const hstepReq, unsigned int const vstepReq, unsigned int * const hstepP, unsigned int * const vstepP, sample *** const pixelsP, struct pam * const pamP, unsigned int * const hsamplesP) { /*---------------------------------------------------------------------------- load the image, saving only the pixels we might actually inspect -----------------------------------------------------------------------------*/ FILE * ifP; unsigned int hstep; unsigned int vstep; ifP = pm_openr(inputFilename); pnm_readpaminit(ifP, pamP, PAM_STRUCT_SIZE(tuple_type)); computeSteps(pamP, hstepReq, vstepReq, &hstep, &vstep); load(pamP, hstep, pixelsP, hsamplesP); *hstepP = hstep; *vstepP = vstep; pm_close(ifP); }
int main(int argc, char **argv) { FILE * ifP; struct cmdlineInfo cmdline; struct pam inpam, outpam; int eof; /* No more images in input stream */ pnm_init(&argc, argv); parseCommandLine(argc, argv, &cmdline); if (cmdline.simple || cmdline.local) ifP = pm_openr(cmdline.inputFileName); else ifP = pm_openr_seekable(cmdline.inputFileName); /* Threshold each image in the PAM file */ eof = FALSE; while (!eof) { pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); /* Set output image parameters for a bilevel image */ outpam.size = sizeof(outpam); outpam.len = PAM_STRUCT_SIZE(tuple_type); outpam.file = stdout; outpam.format = PAM_FORMAT; outpam.plainformat = 0; outpam.height = inpam.height; outpam.width = inpam.width; outpam.maxval = 1; outpam.bytes_per_sample = 1; if (inpam.depth > 1) { strcpy(outpam.tuple_type, "BLACKANDWHITE_ALPHA"); outpam.depth = 2; } else { strcpy(outpam.tuple_type, "BLACKANDWHITE"); outpam.depth = 1; } pnm_writepaminit(&outpam); /* Do the thresholding */ if (cmdline.simple) thresholdSimple(&inpam, &outpam, cmdline.threshold); else if (cmdline.local || cmdline.dual) thresholdLocal(&inpam, &outpam, cmdline); else thresholdIterative(&inpam, &outpam, cmdline.verbose); pnm_nextimage(ifP, &eof); } pm_close(ifP); return 0; }
int main(int argc, char *argv[]) { FILE * ifP; tuple * tuplerow; /* Row from input image */ unsigned int row; struct cmdlineInfo cmdline; struct pam inpam; struct pam outpam; pnm_init( &argc, argv ); parseCommandLine(argc, argv, &cmdline); ifP = pm_openr(cmdline.inputFilespec); pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); tuplerow = pnm_allocpamrow(&inpam); outpam = inpam; /* Initial value -- most fields should be same */ outpam.file = stdout; if (inpam.height % 2 == 0) outpam.height = inpam.height / 2; else { if (cmdline.rowsToTake == ODD) outpam.height = inpam.height / 2; else outpam.height = inpam.height / 2 + 1; } pnm_writepaminit(&outpam); { unsigned int modulusToTake; /* The row number mod 2 of the rows that are supposed to go into the output. */ switch (cmdline.rowsToTake) { case EVEN: modulusToTake = 0; break; case ODD: modulusToTake = 1; break; default: pm_error("INTERNAL ERROR: invalid rowsToTake"); } /* Read input and write out rows extracted from it */ for (row = 0; row < inpam.height; row++) { pnm_readpamrow(&inpam, tuplerow); if (row % 2 == modulusToTake) pnm_writepamrow(&outpam, tuplerow); } } pnm_freepamrow(tuplerow); pm_close(inpam.file); pm_close(outpam.file); return 0; }
static void readFileHeaders(struct pam * const imgPam, unsigned int const fileCt) { unsigned int i; for (i = 0; i < fileCt; ++i) pnm_readpaminit(imgPam[i].file, &imgPam[i], PAM_STRUCT_SIZE(tuple_type)); }
static void remap(FILE * const ifP, const struct pam * const outpamCommonP, tupletable const colormap, unsigned int const colormapSize, bool const floyd, bool const randomize, tuple const defaultColor, bool const verbose) { /*---------------------------------------------------------------------------- Remap the pixels from the raster on *ifP to the 'colormapSize' colors in 'colormap'. Where the input pixel's color is in the map, just use that for the output. Where it isn't, use 'defaultColor', except if that is NULL, use the closest color in the map to the input color. But if 'floyd' is true and 'defaultColor' is NULL, also do Floyd-Steinberg dithering on the output so the aggregate color of a region is about the same as that of the input even though the individual pixels have different colors. -----------------------------------------------------------------------------*/ int eof; eof = FALSE; while (!eof) { struct pam inpam, outpam; unsigned int missingCount; /* Number of pixels that were mapped to 'defaultColor' because they weren't present in the color map. */ pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(allocation_depth)); outpam = *outpamCommonP; outpam.width = inpam.width; outpam.height = inpam.height; pnm_writepaminit(&outpam); /* Set up so input buffers have extra space as needed to convert the input to the output depth. */ pnm_setminallocationdepth(&inpam, outpam.depth); copyRaster(&inpam, &outpam, colormap, colormapSize, floyd, randomize, defaultColor, &missingCount); if (verbose) pm_message("%u pixels not matched in color map", missingCount); pnm_nextimage(ifP, &eof); } }
int main(int argc, const char ** argv) { struct cmdlineInfo cmdline; FILE * ifP; tuple ** outTuples; /* Output image */ scaler * scalerP; struct pam inpam; struct pam outpam; pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); ifP = pm_openr(cmdline.inputFileName); pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(allocation_depth)); pnm_setminallocationdepth(&inpam, 3); outpam.size = sizeof(outpam); outpam.len = PAM_STRUCT_SIZE(tuple_type); outpam.file = stdout; outpam.width = inpam.width; outpam.height = inpam.height; outpam.depth = 3; outpam.maxval = pm_lcm(cmdline.colorRes.c[RED]-1, cmdline.colorRes.c[GRN]-1, cmdline.colorRes.c[BLU]-1, PPM_MAXMAXVAL); outpam.bytes_per_sample = inpam.bytes_per_sample; STRSCPY(outpam.tuple_type, "RGB"); outpam.format = RPPM_FORMAT; outpam.plainformat = false; scaler_create(outpam.maxval, cmdline.colorRes, &scalerP); ditherImage(&inpam, scalerP, cmdline.dim, cmdline.colorRes, &outpam, &outTuples); pnm_writepam(&outpam, outTuples); scaler_destroy(scalerP); pnm_freepamarray(outTuples, &outpam); pm_close(ifP); return 0; }
int main(int argc, char *argv[]) { struct cmdlineInfo cmdline; FILE* ifP; struct pam inpam; /* Input PAM image */ struct pam outpam; /* Output PNM image */ pnm_init(&argc, argv); parseCommandLine(argc, argv, &cmdline); ifP = pm_openr(cmdline.inputFilespec); pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); validateTupleType(inpam, cmdline.assume); outpam = inpam; outpam.file = stdout; if (inpam.depth < 3) { outpam.depth = 1; if (inpam.maxval == 1) outpam.format = PBM_FORMAT; else outpam.format = PGM_FORMAT; } else { outpam.depth = 3; outpam.format = PPM_FORMAT; } pnm_writepaminit(&outpam); { tuple *tuplerow; tuplerow = pnm_allocpamrow(&inpam); { int row; for (row = 0; row < inpam.height; row++) { pnm_readpamrow(&inpam, tuplerow); pnm_writepamrow(&outpam, tuplerow); } } pnm_freepamrow(tuplerow); } return 0; }
static void doOneImage(const char * const name, unsigned int const imageDoneCount, FILE * const fileP, bool const allimages, bool const justCount, bool const wantComments, bool * const eofP) { struct pam pam; const char * comments; enum pm_check_code checkRetval; pam.comment_p = &comments; pnm_readpaminit(fileP, &pam, PAM_STRUCT_SIZE(comment_p)); if (!justCount) { if (allimages) printf("%s:\tImage %d:\t", name, imageDoneCount); else printf("%s:\t", name); dumpHeader(pam); if (wantComments) dumpComments(comments); } strfree(comments); pnm_checkpam(&pam, PM_CHECK_BASIC, &checkRetval); if (allimages) { tuple * tuplerow; unsigned int row; tuplerow = pnm_allocpamrow(&pam); for (row = 0; row < pam.height; ++row) pnm_readpamrow(&pam, tuplerow); pnm_freepamrow(tuplerow); pnm_nextimage(fileP, eofP); } }
int main(int argc, const char ** const argv) { struct CmdlineInfo cmdline; struct pam inpam; FILE * ifP; struct pam lookuppam; tuple ** lookup; tuplehash lookupHash; pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); ifP = pm_openr(cmdline.inputFileName); pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); getLookup(cmdline.lookupfile, &lookup, &lookuppam); if (inpam.depth != lookuppam.depth) pm_error("The lookup image has depth %u, but the input image " "has depth %u. They must be the same", lookuppam.depth, inpam.depth); if (!streq(inpam.tuple_type, lookuppam.tuple_type)) pm_error("The lookup image has tupel type '%s', " "but the input image " "has tuple type '%s'. They must be the same", lookuppam.tuple_type, inpam.tuple_type); makeReverseLookupHash(&lookuppam, lookup, &lookupHash); doUnlookup(&inpam, lookupHash, lookuppam.width-1, stdout); pm_close(ifP); pnm_destroytuplehash(lookupHash); pnm_freepamarray(lookup, &lookuppam); return 0; }
static void initAlphaFile(struct cmdlineInfo const cmdline, struct pam * const overlayPamP, FILE ** const filePP, struct pam * const pamP) { FILE * fileP; if (cmdline.alphaFilespec) { fileP = pm_openr(cmdline.alphaFilespec); pamP->comment_p = NULL; pnm_readpaminit(fileP, pamP, PAM_STRUCT_SIZE(opacity_plane)); if (overlayPamP->width != pamP->width || overlayPamP->height != pamP->height) pm_error("Opacity map and overlay image are not the same size"); } else fileP = NULL; *filePP = fileP; }
int main(int argc, char **argv) { struct cmdlineInfo cmdline; FILE *ifP; struct pam inpam; jas_image_t * jasperP; pnm_init(&argc, argv); parseCommandLine(argc, argv, &cmdline); { int rc; rc = jas_init(); if ( rc != 0 ) pm_error("Failed to initialize Jasper library. " "jas_init() returns rc %d", rc ); } jas_setdbglevel(cmdline.debuglevel); ifP = pm_openr(cmdline.inputFilename); pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); convertToJasperImage(&inpam, &jasperP); writeJpc(jasperP, cmdline, stdout); jas_image_destroy(jasperP); pm_close(ifP); pm_close(stdout); return 0; }
static void produceStereogram(FILE * const ifP, struct cmdlineInfo const cmdline) { struct pam inPam; /* PAM information for the height-map file */ outGenerator * outputGeneratorP; /* Handle of an object that generates background pixels */ pnm_readpaminit(ifP, &inPam, PAM_STRUCT_SIZE(tuple_type)); createoutputGenerator(cmdline, &inPam, &outputGeneratorP); if (cmdline.verbose) { reportImageParameters("Input (height map) file", &inPam); if (inPam.depth > 1) pm_message("Ignoring all but the first plane of input."); reportImageParameters("Output (stereogram) file", &outputGeneratorP->pam); } pnm_writepaminit(&outputGeneratorP->pam); /* Draw guide boxes at the top, if desired. */ if (cmdline.guidesize < 0) drawguides(-cmdline.guidesize, &outputGeneratorP->pam, cmdline.eyesep, cmdline.dpi, cmdline.depth); makeImageRows(&inPam, outputGeneratorP, cmdline.depth, cmdline.eyesep, cmdline.dpi, cmdline.crosseyed, cmdline.makemask); /* Draw guide boxes at the bottom, if desired. */ if (cmdline.guidesize > 0) drawguides(cmdline.guidesize, &outputGeneratorP->pam, cmdline.eyesep, cmdline.dpi, cmdline.depth); destroyoutputGenerator(outputGeneratorP); }
static void cutOneImage(FILE * const ifP, struct cmdlineInfo const cmdline, FILE * const ofP) { int leftcol, rightcol, toprow, bottomrow; struct pam inpam; /* Input PAM image */ struct pam outpam; /* Output PAM image */ pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); computeCutBounds(inpam.width, inpam.height, cmdline.left, cmdline.right, cmdline.top, cmdline.bottom, cmdline.width, cmdline.height, &leftcol, &rightcol, &toprow, &bottomrow); rejectOutOfBounds(inpam.width, inpam.height, leftcol, rightcol, toprow, bottomrow, cmdline.pad); if (cmdline.verbose) { pm_message("Image goes from Row 0, Column 0 through Row %u, Column %u", inpam.height-1, inpam.width-1); pm_message("Cutting from Row %d, Column %d through Row %d Column %d", toprow, leftcol, bottomrow, rightcol); } outpam = inpam; /* Initial value -- most fields should be same */ outpam.file = ofP; outpam.width = rightcol - leftcol + 1; outpam.height = bottomrow - toprow + 1; pnm_writepaminit(&outpam); if (PNM_FORMAT_TYPE(outpam.format) == PBM_TYPE) extractRowsPBM(&inpam, &outpam, leftcol, rightcol, toprow, bottomrow); else extractRowsGen(&inpam, &outpam, leftcol, rightcol, toprow, bottomrow); }
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; }
int main(int argc, char *argv[]) { FILE *ifP; struct cmdlineInfo cmdline; struct pam inpam, outpam; unsigned int row; tuple * inrow; tuple * outrow; tuple * prevrow; pnm_init( &argc, argv ); parseCommandLine(argc, argv, &cmdline); ifP = pm_openr(cmdline.inputFilespec); pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); outpam = inpam; outpam.file = stdout; outpam.format = PAM_FORMAT; strcpy(outpam.tuple_type, "hdiff"); pnm_writepaminit(&outpam); inrow = pnm_allocpamrow(&inpam); outrow = pnm_allocpamrow(&outpam); prevrow = pnm_allocpamrow(&inpam); pnm_setpamrow(&inpam, prevrow, 0); /* All arithmetic in this operation and in the reverse operation (to recover the image) is done modulus the maxval+1 (the hdiff PAM and the image have the same maxval) in order to produce legal PAM samples (which must be in the range 0..maxval). This might seem to throw away information, but it doesn't. Example: maxval is 99. Intensity goes from 90 in Row 0 to 10 in Row 1. The difference is -80. -80 mod 100 is 20, so 20 goes in the hdiff output. On reconstructing the image, the interpreter knows the "20" can't be +20, because that would create the sample 90 + 20 = 110, and violate maxval. So it must be -80. Modulus arithmetic by the interpreter effectively makes that decision. */ /* The bias is just to make it easier to look at the output visually. If you display the values as intensities, and your differences are all +/- half of maxval, you can see positive transitions as bright spots and negative transitions as dark spots. */ { unsigned int const bias = outpam.maxval/2; for (row = 0; row < inpam.height; ++row) { unsigned int col; pnm_readpamrow(&inpam, inrow); for (col = 0; col < inpam.width; ++col) { unsigned int plane; for (plane = 0; plane < inpam.depth; ++plane) { sample const sampleValue = inrow[col][plane]; int const difference = sampleValue - prevrow[col][plane]; outrow[col][plane] = (difference + bias) % (outpam.maxval+1); prevrow[col][plane] = sampleValue; } } pnm_writepamrow(&outpam, outrow); } } pnm_freepamrow(prevrow); pnm_freepamrow(outrow); pnm_freepamrow(inrow); exit(0); }
static void convertPage(FILE * const ifP, int const turnflag, int const turnokflag, bool const psfilter, bool const rle, bool const flate, bool const ascii85, bool const setpage, bool const showpage, bool const center, float const scale, int const dpiX, int const dpiY, int const pagewid, int const pagehgt, int const imagewidth, int const imageheight, bool const equalpixels, char const name[], bool const dict, bool const vmreclaim, bool const levelIsGiven, bool const levelGiven) { struct pam inpam; tuple* tuplerow; unsigned int padright; /* Number of bits we must add to the right end of each Postscript output line in order to have an integral number of bytes of output. E.g. at 2 bits per sample with 10 columns, this would be 4. */ int row; unsigned int ps_maxval; /* The maxval of the Postscript program */ float scols, srows; float llx, lly; bool turned; bool color; unsigned int postscriptLevel; struct bmepsoe * bmepsoeP; pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); if (!STRSEQ(inpam.tuple_type, PAM_PBM_TUPLETYPE) && !STRSEQ(inpam.tuple_type, PAM_PGM_TUPLETYPE) && !STRSEQ(inpam.tuple_type, PAM_PPM_TUPLETYPE)) pm_error("Unrecognized tuple type %s. This program accepts only " "PBM, PGM, PPM, and equivalent PAM input images", inpam.tuple_type); color = STRSEQ(inpam.tuple_type, PAM_PPM_TUPLETYPE); selectPostscriptLevel(levelIsGiven, levelGiven, color, dict, flate, ascii85, &postscriptLevel); if (color) pm_message("generating color Postscript program."); computeDepth(inpam.maxval, &bitspersample, &ps_maxval); { unsigned int const realBitsPerLine = inpam.width * bitspersample; unsigned int const paddedBitsPerLine = ((realBitsPerLine + 7) / 8) * 8; padright = (paddedBitsPerLine - realBitsPerLine) / bitspersample; } /* In positioning/scaling the image, we treat the input image as if it has a density of 72 pixels per inch. */ computeImagePosition(dpiX, dpiY, inpam.width, inpam.height, turnflag, turnokflag, center, pagewid, pagehgt, scale, imagewidth, imageheight, equalpixels, &scols, &srows, &llx, &lly, &turned); putinit(postscriptLevel, name, inpam.width, inpam.height, scols, srows, llx, lly, padright, bitspersample, pagewid, pagehgt, color, turned, rle, flate, ascii85, setpage, psfilter, dict); createBmepsOutputEncoder(&bmepsoeP, stdout, rle, flate, ascii85); initNativeOutputEncoder(rle, bitspersample); tuplerow = pnm_allocpamrow(&inpam); for (row = 0; row < inpam.height; ++row) { pnm_readpamrow(&inpam, tuplerow); if (psfilter) convertRowPsFilter(&inpam, tuplerow, bmepsoeP); else convertRowNative(&inpam, tuplerow, ps_maxval, rle, padright); } pnm_freepamrow(tuplerow); if (psfilter) flushBmepsOutput(bmepsoeP); else flushNativeOutput(rle); destroyBmepsOutputEncoder(bmepsoeP); putEnd(showpage, psfilter, ascii85, dict, vmreclaim); }
static void computeHistogram(FILE * const ifP, int * const formatP, struct pam * const freqPamP, tupletable2 * const colorfreqtableP) { /*---------------------------------------------------------------------------- Make a histogram of the colors in the image stream in the file '*ifP'. Return as *freqPamP a description of the tuple values in the histogram. Only the fields of *freqPamP that describe individual tuples are meaningful (depth, maxval, tuple type); As a fringe benefit, also return the format of the input file as *formatP. ----------------------------------------------------------------------------*/ unsigned int imageSeq; struct pam firstPam; tuplehash tuplehash; unsigned int colorCount; int eof; pm_message("making histogram..."); tuplehash = pnm_createtuplehash(); colorCount = 0; eof = FALSE; for (imageSeq = 0; !eof; ++imageSeq) { struct pam inpam; pm_message("Scanning image %u", imageSeq); pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); if (imageSeq == 0) firstPam = inpam; else validateCompatibleImage(&inpam, &firstPam, imageSeq); addImageColorsToHash(&inpam, tuplehash, &colorCount); pm_message("%u colors so far", colorCount); pnm_nextimage(ifP, &eof); } colorfreqtableP->table = pnm_tuplehashtotable(&firstPam, tuplehash, colorCount); colorfreqtableP->size = colorCount; pnm_destroytuplehash(tuplehash); pm_message("%u colors found", colorfreqtableP->size); freqPamP->size = sizeof(*freqPamP); freqPamP->len = PAM_STRUCT_SIZE(tuple_type); freqPamP->maxval = firstPam.maxval; freqPamP->bytes_per_sample = pnm_bytespersample(freqPamP->maxval); freqPamP->depth = firstPam.depth; STRSCPY(freqPamP->tuple_type, firstPam.tuple_type); *formatP = firstPam.format; }
int main(int argc, char *argv[]) { struct cmdlineInfo cmdline; FILE * underlayFileP; FILE * overlayFileP; FILE * alphaFileP; struct pam underlayPam; struct pam overlayPam; struct pam alphaPam; struct pam composedPam; int originLeft, originTop; pnm_init(&argc, argv); parseCommandLine(argc, argv, &cmdline); overlayFileP = pm_openr(cmdline.overlayFilespec); pnm_readpaminit(overlayFileP, &overlayPam, PAM_STRUCT_SIZE(allocation_depth)); if (cmdline.alphaFilespec) { alphaFileP = pm_openr(cmdline.alphaFilespec); pnm_readpaminit(alphaFileP, &alphaPam, PAM_STRUCT_SIZE(allocation_depth)); if (overlayPam.width != alphaPam.width || overlayPam.height != alphaPam.height) pm_error("Opacity map and overlay image are not the same size"); } else alphaFileP = NULL; underlayFileP = pm_openr(cmdline.underlyingFilespec); pnm_readpaminit(underlayFileP, &underlayPam, PAM_STRUCT_SIZE(allocation_depth)); computeOverlayPosition(underlayPam.width, underlayPam.height, overlayPam.width, overlayPam.height, cmdline, &originLeft, &originTop); composedPam.size = sizeof(composedPam); composedPam.len = PAM_STRUCT_SIZE(allocation_depth); composedPam.allocation_depth = 0; composedPam.file = pm_openw(cmdline.outputFilespec); determineOutputType(&composedPam, &underlayPam, &overlayPam); pnm_setminallocationdepth(&underlayPam, composedPam.depth); pnm_setminallocationdepth(&overlayPam, composedPam.depth); composite(originLeft, originTop, &underlayPam, &overlayPam, alphaFileP ? &alphaPam : NULL, cmdline.alphaInvert, cmdline.opacity, &composedPam, cmdline.linear); if (alphaFileP) pm_close(alphaFileP); pm_close(overlayFileP); pm_close(underlayFileP); pm_close(composedPam.file); /* If the program failed, it previously aborted with nonzero completion code, via various function calls. */ return 0; }
int main(int argc, const char *argv[]) { struct cmdlineInfo cmdline; FILE * underlayFileP; FILE * overlayFileP; FILE * alphaFileP; struct pam underlayPam; struct pam overlayPam; struct pam alphaPam; struct pam composedPam; int originLeft, originTop; pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); overlayFileP = pm_openr(cmdline.overlayFilespec); overlayPam.comment_p = NULL; pnm_readpaminit(overlayFileP, &overlayPam, PAM_STRUCT_SIZE(opacity_plane)); if (overlayPam.len < PAM_STRUCT_SIZE(opacity_plane)) pm_error("Libnetpbm is too old. This program requires libnetpbm from " "Netpbm 10.56 (September 2011) or newer"); if (!overlayPam.visual) pm_error("Overlay image has tuple type '%s', which is not a " "standard visual type. We don't know how to compose.", overlayPam.tuple_type); initAlphaFile(cmdline, &overlayPam, &alphaFileP, &alphaPam); underlayFileP = pm_openr(cmdline.underlyingFilespec); underlayPam.comment_p = NULL; pnm_readpaminit(underlayFileP, &underlayPam, PAM_STRUCT_SIZE(opacity_plane)); assert(underlayPam.len >= PAM_STRUCT_SIZE(opacity_plane)); if (!overlayPam.visual) pm_error("Overlay image has tuple type '%s', which is not a " "standard visual type. We don't know how to compose.", overlayPam.tuple_type); computeOverlayPosition(underlayPam.width, underlayPam.height, overlayPam.width, overlayPam.height, cmdline, &originLeft, &originTop); composedPam.size = PAM_STRUCT_SIZE(opacity_plane); composedPam.len = PAM_STRUCT_SIZE(allocation_depth); composedPam.allocation_depth = 0; composedPam.file = pm_openw(cmdline.outputFilespec); composedPam.comment_p = NULL; determineOutputType(&underlayPam, &overlayPam, &composedPam); pnm_setminallocationdepth(&underlayPam, composedPam.depth); pnm_setminallocationdepth(&overlayPam, composedPam.depth); composite(originLeft, originTop, &underlayPam, &overlayPam, alphaFileP ? &alphaPam : NULL, cmdline.alphaInvert, cmdline.opacity, &composedPam, cmdline.linear, cmdline.mixtransparency); if (alphaFileP) pm_close(alphaFileP); pm_close(overlayFileP); pm_close(underlayFileP); pm_close(composedPam.file); /* If the program failed, it previously aborted with nonzero completion code, via various function calls. */ return 0; }
int main(int argc, char** args) { int argchar; char* infn = NULL; char* outfn = NULL; unsigned int row; int bits; FILE* fid = stdin; FILE* fout = stdout; int loglvl = LOG_MSG; char* progname = args[0]; int bzero = 0; int outformat; qfits_header* hdr; unsigned int plane; off_t datastart; anbool onepass = FALSE; bl* pixcache = NULL; #if HAVE_NETPBM struct pam img; tuple * tuplerow; #else void* rowbuf; #endif int W, H, depth, maxval; while ((argchar = getopt (argc, args, OPTIONS)) != -1) switch (argchar) { case '?': case 'h': printHelp(progname); exit(0); case 'v': loglvl++; break; case 'q': loglvl--; break; case 'o': outfn = optarg; break; } log_init(loglvl); log_to(stderr); fits_use_error_system(); if (optind == argc) { // ok, stdin to stdout. } else if (optind == argc-1) { infn = args[optind]; } else if (optind == argc-2) { infn = args[optind]; outfn = args[optind+1]; } else { printHelp(progname); exit(-1); } if (infn && !streq(infn, "-")) { fid = fopen(infn, "rb"); if (!fid) { SYSERROR("Failed to open input file %s", infn); exit(-1); } } if (outfn) { fout = fopen(outfn, "wb"); if (!fid) { SYSERROR("Failed to open output file %s", outfn); exit(-1); } } else outfn = "stdout"; #if HAVE_NETPBM pm_init(args[0], 0); pnm_readpaminit(fid, &img, // PAM_STRUCT_SIZE isn't defined until Netpbm 10.23 (July 2004) #if defined(PAM_STRUCT_SIZE) PAM_STRUCT_SIZE(tuple_type) #else sizeof(struct pam) #endif ); W = img.width; H = img.height; depth = img.depth; maxval = img.maxval; tuplerow = pnm_allocpamrow(&img); bits = pm_maxvaltobits(img.maxval); bits = (bits <= 8) ? 8 : 16; #else // No NETPBM if (parse_pnm_header(fid, &W, &H, &depth, &maxval)) { ERROR("Failed to parse PNM header from file: %s\n", infn ? infn : "<stdin>"); exit(-1); } bits = 8 * maxval_to_bytes(maxval); rowbuf = malloc(W * depth * (bits/8)); #endif logmsg("Read file %s: %i x %i pixels x %i color(s); maxval %i\n", infn ? infn : "stdin", W, H, depth, maxval); if (bits == 8) outformat = BPP_8_UNSIGNED; else { outformat = BPP_16_SIGNED; if (maxval >= INT16_MAX) bzero = 0x8000; } logmsg("Using %i-bit output\n", bits); hdr = fits_get_header_for_image3(W, H, outformat, depth, NULL); if (bzero) fits_header_add_int(hdr, "BZERO", bzero, "Number that has been subtracted from pixel values"); if (qfits_header_dump(hdr, fout)) { ERROR("Failed to write FITS header to file %s", outfn); exit(-1); } qfits_header_destroy(hdr); datastart = ftello(fid); // Figure out if we can seek backward in this input file... if ((fid == stdin) || (fseeko(fid, 0, SEEK_SET) || fseeko(fid, datastart, SEEK_SET))) // Nope! onepass = TRUE; if (onepass && depth > 1) { logmsg("Reading in one pass\n"); pixcache = bl_new(16384, bits/8); } for (plane=0; plane<depth; plane++) { if (plane > 0) { if (fseeko(fid, datastart, SEEK_SET)) { SYSERROR("Failed to seek back to start of image data"); exit(-1); } } for (row = 0; row<H; row++) { unsigned int column; #if HAVE_NETPBM pnm_readpamrow(&img, tuplerow); #else read_pnm_row(fid, W, depth, maxval, rowbuf); #endif for (column = 0; column<W; column++) { int rtn; int pixval; #if HAVE_NETPBM pixval = tuplerow[column][plane]; #else pixval = (bits == 8 ? ((uint8_t *)rowbuf)[column*depth + plane] : ((uint16_t*)rowbuf)[column*depth + plane]); #endif if (outformat == BPP_8_UNSIGNED) rtn = fits_write_data_B(fout, pixval); else rtn = fits_write_data_I(fout, pixval-bzero, TRUE); if (rtn) { ERROR("Failed to write FITS pixel"); exit(-1); } } if (onepass && depth > 1) { for (column = 0; column<W; column++) { for (plane=1; plane<depth; plane++) { int pixval; #if HAVE_NETPBM pixval = tuplerow[column][plane]; #else pixval = (bits == 8 ? ((uint8_t *)rowbuf)[column*depth + plane] : ((uint16_t*)rowbuf)[column*depth + plane]); #endif if (outformat == BPP_8_UNSIGNED) { uint8_t pix = pixval; bl_append(pixcache, &pix); } else { int16_t pix = pixval - bzero; bl_append(pixcache, &pix); } } } } } } #if HAVE_NETPBM pnm_freepamrow(tuplerow); #else free(rowbuf); #endif if (pixcache) { int i, j; int step = (depth - 1); logverb("Writing %zu queued pixels\n", bl_size(pixcache)); for (plane=1; plane<depth; plane++) { j = (plane - 1); for (i=0; i<(W * H); i++) { int rtn; if (outformat == BPP_8_UNSIGNED) { uint8_t* pix = bl_access(pixcache, j); rtn = fits_write_data_B(fout, *pix); } else { int16_t* pix = bl_access(pixcache, j); rtn = fits_write_data_I(fout, *pix, TRUE); } if (rtn) { ERROR("Failed to write FITS pixel"); exit(-1); } j += step; } } bl_free(pixcache); } if (fid != stdin) fclose(fid); if (fits_pad_file(fout)) { ERROR("Failed to pad output file \"%s\"", outfn); return -1; } if (fout != stdout) if (fclose(fout)) { SYSERROR("Failed to close output file %s", outfn); exit(-1); } return 0; }
int main(int argc, char **argv) { struct pam *imgs; struct pam outimg; struct pam p; int nfiles; int i, j; unsigned int q[10]; coord *coords; const char *headfname = NULL; const char *datafname = NULL; const char *prefix = ""; FILE *header; FILE *data; char **names; char *c; optEntry *option_def = malloc(100*sizeof(optEntry)); /* Instructions to OptParseOptions3 on how to parse our options. */ optStruct3 opt; unsigned int option_def_index; option_def_index = 0; /* incremented by OPTENTRY */ OPTENT3( 0, "data", OPT_STRING, &datafname, NULL, 0); OPTENT3( 0, "header", OPT_STRING, &headfname, NULL, 0); OPTENT3('q', "quality", OPT_UINT, &qfactor, NULL, 0); OPTENT3('p', "prefix", OPT_STRING, &prefix, NULL, 0); OPTENT3('0', "0", OPT_FLAG, NULL, &q[0], 0); OPTENT3('1', "1", OPT_FLAG, NULL, &q[1], 0); OPTENT3('2', "2", OPT_FLAG, NULL, &q[2], 0); OPTENT3('3', "3", OPT_FLAG, NULL, &q[3], 0); OPTENT3('4', "4", OPT_FLAG, NULL, &q[4], 0); OPTENT3('5', "5", OPT_FLAG, NULL, &q[5], 0); OPTENT3('6', "6", OPT_FLAG, NULL, &q[6], 0); OPTENT3('7', "7", OPT_FLAG, NULL, &q[7], 0); OPTENT3('8', "8", OPT_FLAG, NULL, &q[8], 0); OPTENT3('9', "9", OPT_FLAG, NULL, &q[9], 0); opt.opt_table = option_def; opt.short_allowed = FALSE; opt.allowNegNum = FALSE; pnm_init(&argc, argv); /* Check for flags. */ optParseOptions3(&argc, argv, opt, sizeof(opt), 0); if (headfname) header = pm_openw(headfname); if (datafname) data = pm_openw(datafname); for (i = 0; i < 10; ++i) { if (q[i]) { quality = i; switch (quality) { case 0: case 1: break; case 2: case 3: case 4: case 5: case 6: qfactor = 100 * (8 - quality); break; case 7: qfactor = 150; break; case 8: qfactor = 125; break; case 9: qfactor = 100; break; } } } if (1 < argc) nfiles = argc - 1; else nfiles = 1; MALLOCARRAY(imgs, nfiles); MALLOCARRAY(coords, nfiles); MALLOCARRAY(names, nfiles); if (!imgs || !coords || !names) pm_error("out of memory"); if (1 < argc) { for (i = 0; i < nfiles; ++i) { if (strchr(argv[i+1], ':')) { imgs[i].file = pm_openr(strchr(argv[i+1], ':') + 1); *strchr(argv[i+1], ':') = 0; names[i] = argv[i+1]; } else { imgs[i].file = pm_openr(argv[i+1]); names[i] = argv[i+1]; } } } else { imgs[0].file = stdin; } pnm_readpaminit(imgs[0].file, &imgs[0], PAM_STRUCT_SIZE(tuple_type)); outimg.maxval = imgs[0].maxval; outimg.format = imgs[0].format; memcpy(outimg.tuple_type, imgs[0].tuple_type, sizeof(imgs[0].tuple_type)); outimg.depth = imgs[0].depth; for (i = 1; i < nfiles; ++i) { pnm_readpaminit(imgs[i].file, &imgs[i], PAM_STRUCT_SIZE(tuple_type)); if (PAM_FORMAT_TYPE(imgs[i].format) > PAM_FORMAT_TYPE(outimg.format)) outimg.format = imgs[i].format, memcpy(outimg.tuple_type, imgs[i].tuple_type, sizeof(imgs[i].tuple_type)); outimg.maxval = imax(imgs[i].maxval, outimg.maxval); outimg.depth = imax(imgs[i].depth, outimg.depth); } for (i = 0; i < nfiles - 1; ++i) for (j = i + 1; j < nfiles; ++j) if (imgs[j].width * imgs[j].height > imgs[i].width * imgs[i].height) p = imgs[i], imgs[i] = imgs[j], imgs[j] = p, c = names[i], names[i] = names[j], names[j] = c; findpack(imgs, nfiles, coords); outimg.height = outimg.width = 0; for (i = 0; i < nfiles; ++i) { outimg.width = imax(outimg.width, imgs[i].width + coords[i].x); outimg.height = imax(outimg.height, imgs[i].height + coords[i].y); } outimg.size = sizeof(outimg); outimg.len = sizeof(outimg); outimg.file = stdout; outimg.bytes_per_sample = 0; for (i = outimg.maxval; i; i >>= 8) ++outimg.bytes_per_sample; writePam(&outimg, nfiles, coords, imgs); if (datafname) { fprintf(data, ":0:0:%u:%u\n", outimg.width, outimg.height); for (i = 0; i < nfiles; ++i) { fprintf(data, "%s:%u:%u:%u:%u\n", names[i], coords[i].x, coords[i].y, imgs[i].width, imgs[i].height); } } if (headfname) { fprintf(header, "#define %sOVERALLX %u\n" "#define %sOVERALLY %u\n" "\n", prefix, outimg.width, prefix, outimg.height); for (i = 0; i < nfiles; ++i) { *strchr(names[i], '.') = 0; for (j = 0; names[i][j]; ++j) { if (ISLOWER(names[i][j])) names[i][j] = TOUPPER(names[i][j]); } fprintf(header, "#define %s%sX %u\n" "#define %s%sY %u\n" "#define %s%sSZX %u\n" "#define %s%sSZY %u\n" "\n", prefix, names[i], coords[i].x, prefix, names[i], coords[i].y, prefix, names[i], imgs[i].width, prefix, names[i], imgs[i].height); } } for (i = 0; i < nfiles; ++i) pm_close(imgs[i].file); pm_close(stdout); if (headfname) pm_close(header); if (datafname) pm_close(data); return 0; }
int main(int argc, char *argv[]) { struct cmdlineInfo cmdline; FILE* ifP; pgm_init(&argc, argv); parseCommandLine(argc, argv, &cmdline); srand(cmdline.randomseedSpec ? cmdline.randomseed : pm_randseed()); ifP = pm_openr(cmdline.inputFilespec); if (cmdline.halftone == QT_HILBERT) doHilbert(ifP, cmdline.clumpSize); else { struct converter converter; struct pam graypam; struct pam bitpam; tuplen * grayrow; tuple * bitrow; int row; pnm_readpaminit(ifP, &graypam, PAM_STRUCT_SIZE(tuple_type)); bitpam = makeOutputPam(graypam.width, graypam.height); pnm_writepaminit(&bitpam); switch (cmdline.halftone) { case QT_FS: converter = createFsConverter(&graypam, cmdline.threshval); break; case QT_ATKINSON: converter = createAtkinsonConverter(&graypam, cmdline.threshval); break; case QT_THRESH: converter = createThreshConverter(&graypam, cmdline.threshval); break; case QT_DITHER8: converter = createClusterConverter(&graypam, DT_REGULAR, 8); break; case QT_CLUSTER: converter = createClusterConverter(&graypam, DT_CLUSTER, cmdline.clusterRadius); break; case QT_HILBERT: pm_error("INTERNAL ERROR: halftone is QT_HILBERT where it " "shouldn't be."); break; } grayrow = pnm_allocpamrown(&graypam); bitrow = pnm_allocpamrow(&bitpam); for (row = 0; row < graypam.height; ++row) { pnm_readpamrown(&graypam, grayrow); converter.convertRow(&converter, row, grayrow, bitrow); pnm_writepamrow(&bitpam, bitrow); } pnm_freepamrow(bitrow); pnm_freepamrow(grayrow); if (converter.destroy) converter.destroy(&converter); } pm_close(ifP); 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); }