diff options
Diffstat (limited to 'converter/other/pamtotiff.c')
-rw-r--r-- | converter/other/pamtotiff.c | 452 |
1 files changed, 153 insertions, 299 deletions
diff --git a/converter/other/pamtotiff.c b/converter/other/pamtotiff.c index f2cc0e2b..0206678d 100644 --- a/converter/other/pamtotiff.c +++ b/converter/other/pamtotiff.c @@ -53,19 +53,16 @@ #define COMPRESSION_ADOBE_DEFLATE 8 #endif -typedef struct { +struct sizeset { bool b1, b2, b4, b8; -} SizeSet; +}; -typedef enum { TMPFILE, DIRECT_CREATE, DIRECT_APPEND } WriteMethod; -typedef enum { MUST_EXIST, MAY_CREATE } CreatePolicy; - -typedef struct { +struct cmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ - const char * inputFileName; + const char *input_filespec; /* Filespecs of input files */ int compression; /* COMPRESSION Tiff tag value, that corresponds to the compression option the user specified, or -1 if he didn't specify any. @@ -82,14 +79,13 @@ typedef struct { float xresolution; /* XRESOLUTION Tiff tag value or -1 for none */ float yresolution; /* YRESOLUTION Tiff tag value or -1 for none */ int resolutionunit; /* RESOLUTIONUNIT Tiff tag value */ - SizeSet indexsizeAllowed; + struct sizeset indexsizeAllowed; /* Which bit widths are allowable in a raster of palette indices */ unsigned int verbose; - WriteMethod writeMethod; /* Output mode */ - const char * output; /* -output option value. NULL if none. */ + unsigned int append; float resolution; /* X and Y resolution */ struct optNameValue * taglist; -} CmdlineInfo; +}; @@ -100,7 +96,7 @@ validateTagList(struct optNameValue const taglist[]) { for (i = 0; taglist[i].name; ++i) { const char * const tagName = taglist[i].name; const tagDefinition * tagDefP = tagDefFind(tagName); - + if (!tagDefP) pm_error("Unknown tag name '%s'", tagName); else { @@ -135,9 +131,9 @@ validateTagList(struct optNameValue const taglist[]) { static void -parseCommandLine(int argc, - const char ** const argv, - CmdlineInfo * const cmdlineP) { +parseCommandLine(int argc, + char ** const argv, + struct cmdlineInfo * const cmdlineP) { /*---------------------------------------------------------------------------- Note that the file spec array we return is stored in the storage that was passed to us as the argv array. @@ -151,9 +147,8 @@ parseCommandLine(int argc, char * indexbits; char * resolutionunit; - unsigned int appendSpec, outputSpec, predictorSpec, rowsperstripSpec, - xresolutionSpec, yresolutionSpec, indexbitsSpec, - resolutionunitSpec, tagSpec; + unsigned int predictorSpec, rowsperstripSpec, xresolutionSpec, + yresolutionSpec, indexbitsSpec, resolutionunitSpec, tagSpec; unsigned int option_def_index; @@ -161,6 +156,7 @@ parseCommandLine(int argc, option_def_index = 0; /* incremented by OPTENT3 */ OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); + OPTENT3(0, "append", OPT_FLAG, NULL, &cmdlineP->append, 0); OPTENT3(0, "none", OPT_FLAG, NULL, &none, 0); OPTENT3(0, "packbits", OPT_FLAG, NULL, &packbits, 0); OPTENT3(0, "lzw", OPT_FLAG, NULL, &lzw, 0); @@ -178,20 +174,17 @@ parseCommandLine(int argc, OPTENT3(0, "mw", OPT_FLAG, NULL, &cmdlineP->miniswhite, 0); OPTENT3(0, "truecolor", OPT_FLAG, NULL, &cmdlineP->truecolor, 0); OPTENT3(0, "color", OPT_FLAG, NULL, &cmdlineP->color, 0); - OPTENT3(0, "append", OPT_FLAG, NULL, &appendSpec, 0); - OPTENT3(0, "output", OPT_STRING, &cmdlineP->output, - &outputSpec, 0); - OPTENT3(0, "predictor", OPT_UINT, &cmdlineP->predictor, + OPTENT3(0, "predictor", OPT_UINT, &cmdlineP->predictor, &predictorSpec, 0); - OPTENT3(0, "rowsperstrip", OPT_UINT, &cmdlineP->rowsperstrip, + OPTENT3(0, "rowsperstrip", OPT_UINT, &cmdlineP->rowsperstrip, &rowsperstripSpec, 0); - OPTENT3(0, "xresolution", OPT_FLOAT, &cmdlineP->xresolution, + OPTENT3(0, "xresolution", OPT_FLOAT, &cmdlineP->xresolution, &xresolutionSpec, 0); - OPTENT3(0, "yresolution", OPT_FLOAT, &cmdlineP->yresolution, + OPTENT3(0, "yresolution", OPT_FLOAT, &cmdlineP->yresolution, &yresolutionSpec, 0); OPTENT3(0, "resolutionunit", OPT_STRING, &resolutionunit, &resolutionunitSpec, 0); - OPTENT3(0, "indexbits", OPT_STRING, &indexbits, + OPTENT3(0, "indexbits", OPT_STRING, &indexbits, &indexbitsSpec, 0); OPTENT3(0, "tag", OPT_NAMELIST, &cmdlineP->taglist, &tagSpec, 0); @@ -199,14 +192,14 @@ parseCommandLine(int argc, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - pm_optParseOptions3(&argc, (char**)argv, opt, sizeof(opt), 0); + pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (none + packbits + lzw + g3 + g4 + flate + adobeflate > 1) pm_error("You specified more than one compression option. " "Only one of -none, -packbits, -lze, -g3, and -g4 " "is allowed."); - + if (none) cmdlineP->compression = COMPRESSION_NONE; else if (packbits) @@ -223,7 +216,7 @@ parseCommandLine(int argc, cmdlineP->compression = COMPRESSION_DEFLATE; else cmdlineP->compression = COMPRESSION_NONE; - + if (msb2lsb + lsb2msb > 1) pm_error("You specified both -msb2lsb and -lsb2msb. " "These are conflicting options."); @@ -232,9 +225,9 @@ parseCommandLine(int argc, cmdlineP->fillorder = FILLORDER_MSB2LSB; else if (lsb2msb) cmdlineP->fillorder = FILLORDER_LSB2MSB; - else + else cmdlineP->fillorder = FILLORDER_MSB2LSB; - + if (cmdlineP->miniswhite && cmdlineP->minisblack) pm_error("You cannot specify both -miniswhite and -minisblack"); @@ -245,17 +238,9 @@ parseCommandLine(int argc, if (fill) cmdlineP->g3options |= GROUP3OPT_FILLBITS; - if (outputSpec) { - if (appendSpec) - cmdlineP->writeMethod = DIRECT_APPEND; - else - cmdlineP->writeMethod = DIRECT_CREATE; - } else - cmdlineP->writeMethod = TMPFILE; - if (predictorSpec) { if (cmdlineP->predictor != 1 && cmdlineP->predictor != 2) - pm_error("-predictor may be only 1 or 2. You specified %d.", + pm_error("-predictor may be only 1 or 2. You specified %d.", cmdlineP->predictor); } else cmdlineP->predictor = -1; @@ -333,13 +318,13 @@ parseCommandLine(int argc, cmdlineP->taglist[0].value = NULL; } - if (argc-1 == 0) - cmdlineP->inputFileName = "-"; + if (argc-1 == 0) + cmdlineP->input_filespec = "-"; else if (argc-1 != 1) pm_error("Program takes zero or one argument (filename). You " "specified %d", argc-1); else - cmdlineP->inputFileName = argv[1]; + cmdlineP->input_filespec = argv[1]; } @@ -361,9 +346,9 @@ fillRowOfSubBytePixels(struct pam * const pamP, int bitshift; /* The number of bits we have to shift a pixel value left to line it up with where the current pixel goes in the current byte of - the output buffer. + the output buffer. */ - int const firstbitshift = + int const firstbitshift = (fillorder == FILLORDER_MSB2LSB) ? 8 - bitspersample : 0; /* The value of 'bitshift' for the first pixel into a byte of the output buffer. (MSB2LSB is normal). @@ -378,7 +363,7 @@ fillRowOfSubBytePixels(struct pam * const pamP, /* The under-construction value of the byte pointed to by tP, above. */ - + bitshift = firstbitshift; byte = 0; for (col = 0, tP = buf; col < pamP->width; ++col) { @@ -387,7 +372,7 @@ fillRowOfSubBytePixels(struct pam * const pamP, s = tuplerow[col][0]; if (pamP->maxval != tiff_maxval ) s = (long) s * tiff_maxval / pamP->maxval; - + if (photometric == PHOTOMETRIC_MINISWHITE) s = tiff_maxval - s; } else { @@ -463,7 +448,7 @@ fillRowOfWholeBytePixels(struct pam * const pamP, unsigned int col; unsigned char * tP; unsigned int planes; - + if (photometric == PHOTOMETRIC_RGB) planes = pamP->depth; else @@ -480,18 +465,18 @@ fillRowOfWholeBytePixels(struct pam * const pamP, /* Advances tP */ } } -} +} static void writeScanLines(struct pam * const pamP, - TIFF * const tif, + TIFF * const tif, tuplehash const cht, unsigned short const tiffMaxval, - unsigned short const bitspersample, + unsigned short const bitspersample, unsigned short const photometric, - int const bytesperrow, + int const bytesperrow, int const fillorder) { /*---------------------------------------------------------------------------- Write out the raster for the input image described by 'pamP', whose @@ -525,7 +510,7 @@ writeScanLines(struct pam * const pamP, pm_error("can't allocate memory for row buffer"); tuplerow = pnm_allocpamrow(pamP); - + for (row = 0; row < pamP->height; ++row) { int col; @@ -547,9 +532,9 @@ writeScanLines(struct pam * const pamP, for (col = 0; col < pamP->width; ++col) { int si; int found; - + pnm_lookuptuple(pamP, cht, tuplerow[col], &found, &si); - + if (!found) pm_error("INTERNAL ERROR. We made a color map, and a " "color map we need is not in it! " @@ -573,12 +558,12 @@ writeScanLines(struct pam * const pamP, static void -analyzeColorsInRgbInput(struct pam * const pamP, - CmdlineInfo const cmdline, - int const maxcolors, - tupletable * const chvP, - unsigned int * const colorsP, - bool * const grayscaleP) { +analyzeColorsInRgbInput(struct pam * const pamP, + struct cmdlineInfo const cmdline, + int const maxcolors, + tupletable * const chvP, + unsigned int * const colorsP, + bool * const grayscaleP) { /*---------------------------------------------------------------------------- Same as analyzeColors(), except assuming input image has R/G/B tuples. -----------------------------------------------------------------------------*/ @@ -597,7 +582,7 @@ analyzeColorsInRgbInput(struct pam * const pamP, grayscale = FALSE; } else { unsigned int i; - pm_message("%u color%s found", + pm_message("%u color%s found", *colorsP, *colorsP == 1 ? "" : "s"); grayscale = TRUE; /* initial assumption */ for (i = 0; i < *colorsP && grayscale; ++i) { @@ -630,15 +615,15 @@ analyzeColorsInRgbInput(struct pam * const pamP, static void -analyzeColors(struct pam * const pamP, - CmdlineInfo const cmdline, - int const maxcolors, - tupletable * const chvP, - unsigned int * const colorsP, - bool * const grayscaleP) { +analyzeColors(struct pam * const pamP, + struct cmdlineInfo const cmdline, + int const maxcolors, + tupletable * const chvP, + unsigned int * const colorsP, + bool * const grayscaleP) { /*---------------------------------------------------------------------------- Analyze the colors in the input image described by 'pamP', whose file - is positioned to the raster. + is positioned to the raster. If the colors, combined with command line options 'cmdline', indicate a colormapped TIFF should be generated, return as *chvP the address @@ -667,13 +652,13 @@ analyzeColors(struct pam * const pamP, static void computeRasterParm(struct pam * const pamP, - tupletable const chv, - int const colors, + tupletable const chv, + int const colors, bool const grayscale, int const compression, bool const minisblack, bool const miniswhite, - SizeSet const indexsizeAllowed, + struct sizeset const indexsizeAllowed, unsigned short * const samplesperpixelP, unsigned short * const bitspersampleP, unsigned short * const photometricP, @@ -694,7 +679,7 @@ computeRasterParm(struct pam * const pamP, option. It is not clear why we don't use bits per pixel < 8 for RGB images. Note that code to handle maxvals <= 255 was written long before maxval > 255 was possible and there are - backward compatibility requirements. + backward compatibility requirements. */ if (pamP->depth == 1 && pamP->maxval == 1) { @@ -708,7 +693,7 @@ computeRasterParm(struct pam * const pamP, } else { if (chv) { *samplesperpixelP = 1; /* Pixel is just the one index value */ - *bitspersampleP = + *bitspersampleP = colors <= 2 && indexsizeAllowed.b1 ? 1 : colors <= 4 && indexsizeAllowed.b2 ? 2 : colors <= 16 && indexsizeAllowed.b4 ? 4 : @@ -761,53 +746,18 @@ computeRasterParm(struct pam * const pamP, +static void +validateSeekableOutputFile(int const ofd, + const char * const outFileName) { /*---------------------------------------------------------------------------- - WRITE MODES - ----------- - - The Tiff library does all output. There are several issues: - - 1) The manner of output is opaque to the library client. I.e. we cannot - see or control it. - - 2) The output file must be random-access. - - 3) The output file must be writable and readable for multiple-image - streams. (This includes append operations.) - - 4) The Tiff library produces unhelpful error messages when the above - conditions are not met. - - We provide two modes for output: - - 1. Tmpfile mode (default) - - We have the Tiff library direct output to an unnamed temporary file we - create which is seekable and readable. When output is complete, we copy - the file's contents to Standard Output. - - 2. Direct mode (specified with -output) - - We have the Tiff library write output to the specified file. As the Tiff - library requires taht it be be seekable and readable, we fail the program - rather than ask the Tiff library to use the file if it does not meet - these requirements. - - Direct mode is further divided into append and create. They are the same - except that in append mode, we insist that the file already exist, - whereas with create mode, we create it if necessary. In either case, if - the file already exists, he Tiff library appends the output to it. ------------------------------------------------------------------------------*/ - - + Validate that the file attached to file descriptor 'ofd' is capable + of seeking. If not, fail the program. -static bool -fileIsSeekable(int const ofd, - const char * const outFileName) { -/*---------------------------------------------------------------------------- - The file represented by 'ofd' iscapable of seeking. + This is useful because the TIFF library requires seekable output and + fails with an unhelpful error message about a file I/O error if it is + not. We, on the other hand, give a helpful error message. - As a side effect, we position the file to the beginning. + We leave the file positioned to the beginning. -----------------------------------------------------------------------------*/ int rc; @@ -821,160 +771,44 @@ fileIsSeekable(int const ofd, */ lseek(ofd, 1, SEEK_SET); rc = lseek(ofd, 0, SEEK_SET); - - return rc >= 0; - -} - - - -static void -validateReadableOutputFile(int const ofd) { -/*---------------------------------------------------------------------------- - Validate that file 'ofd' is readable and fail the program if it isn't. - - This is useful because there are situations in which the TIFF library must - read the output file and if it can't, it fails with an unhelpful error - message about a file I/O error. We, on the other hand, produce a helpful - error message. ------------------------------------------------------------------------------*/ -#if !MSVCRT - - int flags; - - flags = fcntl(ofd, F_GETFL); - - if (flags < 0) { - /* We couldn't get the flags. So just assume the file's OK */ - } else { - if ((flags & O_RDONLY) || (flags & O_RDWR)) { - /* File is readable. All is well. */ - } else - pm_error("Output is not opened for reading. " - "In order to create a multi-image TIFF stream, " - "output must be both readable and writable."); - } -#endif -} - - - -static void -createTiffGeneratorDirect(const char * const outputFileName, - CreatePolicy const createPolicy, - TIFF ** const tifPP, - int * const ofdP) { -/*---------------------------------------------------------------------------- - Create a TIFF generator that writes its output to the specified file. - - If the file doesn't already exist and 'createPolicy' is MayCreate, - create the file; otherwise fail the program. - - Fail the program if the specified file is not seekable and readable. - - Return the handle of the TIFF generator as *tifPP. Also return the - file descriptor for the output file as *ofdP. ------------------------------------------------------------------------------*/ - int fd; - - if (createPolicy == MUST_EXIST) - fd = open(outputFileName, O_RDWR); - else - fd = open(outputFileName, (O_RDWR | O_CREAT), 00644); - - if (fd == -1) { - if (errno == ENOENT) /* Possible only if MustExist */ - pm_error ("Cannot open file : '%s'. File does not exist.", - outputFileName); - else - pm_error ("Cannot open file : '%s'. open() failed with " - "errno %d (%s). ", - outputFileName, errno, strerror(errno)); - } - - if (!fileIsSeekable(fd, outputFileName)) - pm_error("Output file (%s) is not seekable. " - "lseek() returned errno %d (%s). " + + if (rc < 0) + pm_error("Output file (%s) is not seekable. lseek() returned " + "errno %d (%s). " "The TIFF library can write only to " - "a seekable file.", - outputFileName, errno, strerror(errno)); - - *tifPP = TIFFFdOpen(fd, outputFileName, "a"); - if (*tifPP == NULL) - pm_error("error opening file %s as TIFF file. " - "TIFFFdOpen() failed.", outputFileName); - - *ofdP = fd; + "a seekable file.", + outFileName, errno, strerror(errno)); } static void -createTiffGeneratorTmpfile(TIFF ** const tifPP, - int * const ofdP) { -/*---------------------------------------------------------------------------- - Create a TIFF generator that writes its output to an unnnamed temporary file - we create. - - Return the handle of the TIFF generator as *tifPP. Also return the file - descriptor for the temporary file as *ofdP. +createTiffGenerator(int const ofd, + const char * const outFileName, + bool const append, + TIFF ** const tifPP) { - The TIFF generator has a file name attribute, but it is just for messages; - it is not the name of a file. We use "Internal Temporary File". ------------------------------------------------------------------------------*/ - int fd; + const char * option; - fd = pm_tmpfile_fd(); + validateSeekableOutputFile(ofd, outFileName); - *tifPP = TIFFFdOpen(fd, "Internal Temporary File", "w"); + if (append) + option = "a"; + else + option = "w"; + *tifPP = TIFFFdOpen(ofd, outFileName, option); if (*tifPP == NULL) - pm_error("error opening temporary file as TIFF file. " + pm_error("error opening standard output as TIFF file. " "TIFFFdOpen() failed."); - - *ofdP = fd; -} - - - -static void -copyBufferToStdout(int const tmpfileFd) { - - FILE * tmpfileP; - - tmpfileP = fdopen(tmpfileFd, "rb"); - - fseek(tmpfileP, 0, SEEK_SET); - - while (!feof(tmpfileP) && !ferror(tmpfileP) && !ferror(stdout)) { - char buffer[4096]; - size_t bytesReadCt; - - bytesReadCt = fread(buffer, 1, sizeof(buffer), tmpfileP); - - if (ferror(tmpfileP)) - pm_error("Error reading from temporary file. " - "Incomplete output. " - "Errno = %s (%d)", strerror(errno), errno); - else - fwrite(buffer, 1, bytesReadCt, stdout); - } - - fclose(tmpfileP); } static void -destroyTiffGenerator(WriteMethod const writeMethod, - TIFF * const tifP, - int const ofd) { +destroyTiffGenerator(TIFF * const tifP) { TIFFFlushData(tifP); - - if (writeMethod == TMPFILE) - copyBufferToStdout(ofd); - TIFFClose(tifP); } @@ -991,11 +825,11 @@ createTiffColorMap(struct pam * const pamP, unsigned short ** tiffColorMap; unsigned int plane; unsigned int i; - + MALLOCARRAY_NOFAIL(tiffColorMap, pamP->depth); for (plane = 0; plane < pamP->depth; ++plane) MALLOCARRAY_NOFAIL(tiffColorMap[plane], colorMapSize); - + for (i = 0; i < colorMapSize; ++i) { unsigned int plane; for (plane = 0; plane < pamP->depth; ++plane) { @@ -1008,7 +842,7 @@ createTiffColorMap(struct pam * const pamP, } *tiffColorMapP = tiffColorMap; } - + static void @@ -1033,7 +867,7 @@ setTagListFields(const struct optNameValue * const taglist, for (i = 0; taglist[i].name; ++i) { const tagDefinition * const tagDefP = tagDefFind(taglist[i].name); - + if (tagDefP->put) tagDefP->put(tifP, tagDefP->tagnum, taglist[i].value, tagDefP->choices); @@ -1044,7 +878,7 @@ setTagListFields(const struct optNameValue * const taglist, static void setTiffFields(TIFF * const tifP, - CmdlineInfo const cmdline, + struct cmdlineInfo const cmdline, struct pam * const pamP, unsigned short const bitspersample, unsigned short const photometric, @@ -1106,7 +940,7 @@ setTiffFields(TIFF * const tifP, TIFFSetField(tifP, TIFFTAG_DOCUMENTNAME, inputFileDescription); TIFFSetField(tifP, TIFFTAG_IMAGEDESCRIPTION, "converted PNM file"); - + /* Some of taglist[] overrides defaults we set above. But taglist[] is defined not to specify any tag types that are not purely user choice. @@ -1117,10 +951,10 @@ setTiffFields(TIFF * const tifP, static void -convertImage(FILE * const ifP, - TIFF * const tifP, - const char * const inputFileDescription, - CmdlineInfo const cmdline) { +convertImage(FILE * const ifP, + TIFF * const tifP, + const char * const inputFileDescription, + struct cmdlineInfo const cmdline) { tupletable chv; tuplehash cht; @@ -1132,7 +966,7 @@ convertImage(FILE * const ifP, unsigned short samplesperpixel; unsigned short bitspersample; unsigned short tiff_maxval; - /* This is the maxval of the samples in the tiff file. It is + /* This is the maxval of the samples in the tiff file. It is determined solely by the bits per sample ('bitspersample'). */ int bytesperrow; @@ -1145,11 +979,11 @@ convertImage(FILE * const ifP, analyzeColors(&pam, cmdline, MAXCOLORS, &chv, &colors, &grayscale); /* Go back to beginning of raster */ - pm_seek2(ifP, &rasterPos, sizeof(rasterPos)); + pm_seek2(ifP, &rasterPos, sizeof(rasterPos)); /* Figure out TIFF parameters. */ - computeRasterParm(&pam, chv, colors, grayscale, + computeRasterParm(&pam, chv, colors, grayscale, cmdline.compression, cmdline.minisblack, cmdline.miniswhite, cmdline.indexsizeAllowed, @@ -1174,7 +1008,7 @@ convertImage(FILE * const ifP, cmdline.taglist); writeScanLines(&pam, tifP, cht, - tiff_maxval, bitspersample, photometric, bytesperrow, + tiff_maxval, bitspersample, photometric, bytesperrow, cmdline.fillorder); if (tiffColorMap) @@ -1183,41 +1017,63 @@ convertImage(FILE * const ifP, +static void +validateReadableStdout(void) { +/*---------------------------------------------------------------------------- + We validate that Standard Output is readable and fail the program if + it isn't. + + This is useful because there are situations in which the TIFF library + must read the output file and if it can't, it fails with an unhelpful + error message about a file I/O error. We, on the other hand, produce + a helpful error message. +-----------------------------------------------------------------------------*/ +#if !MSVCRT + + int flags; + + flags = fcntl(STDOUT_FILENO, F_GETFL); + + if (flags < 0) { + /* We couldn't get the flags. So just assume the file's OK */ + } else { + if ((flags & O_RDONLY) || (flags & O_RDWR)) { + /* File is readable. All is well. */ + } else + pm_error("Standard Output is not opened for reading. " + "In order to create a multi-image TIFF stream, " + "Standard Output must be both readable and writable."); + } +#endif +} int -main(int argc, const char *argv[]) { - CmdlineInfo cmdline; +main(int argc, char *argv[]) { + struct cmdlineInfo cmdline; const char * inputFileDescription; - FILE * ifP; - TIFF * tifP; - int ofd; + FILE* ifP; + TIFF* tifP; int eof; unsigned int imageSeq; - - pm_proginit(&argc, argv); - parseCommandLine(argc, argv, &cmdline); + pnm_init(&argc, argv); - ifP = pm_openr_seekable(cmdline.inputFileName); + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr_seekable(cmdline.input_filespec); - if (streq(cmdline.inputFileName, "-")) + if (streq(cmdline.input_filespec, "-")) inputFileDescription = "Standard Input"; - else - inputFileDescription = cmdline.inputFileName; - - switch (cmdline.writeMethod) { - case DIRECT_APPEND: - createTiffGeneratorDirect(cmdline.output, MUST_EXIST, &tifP, &ofd); - break; - case DIRECT_CREATE: - createTiffGeneratorDirect(cmdline.output, MAY_CREATE, &tifP, &ofd); - break; - case TMPFILE: - createTiffGeneratorTmpfile(&tifP, &ofd); - break; - } + else + inputFileDescription = cmdline.input_filespec; + + if (cmdline.append) + validateReadableStdout(); + + createTiffGenerator(STDOUT_FILENO, "Standard Output", cmdline.append, + &tifP); eof = FALSE; /* initial assumption */ imageSeq = 0; @@ -1225,17 +1081,17 @@ main(int argc, const char *argv[]) { while (!eof) { bool success; + if (cmdline.verbose) + pm_message("Converting Image %u", imageSeq); + pnm_nextimage(ifP, &eof); if (!eof) { if (imageSeq > 0) - validateReadableOutputFile(ofd); - - if (cmdline.verbose) - pm_message("Converting Image %u", imageSeq); + validateReadableStdout(); convertImage(ifP, tifP, inputFileDescription, cmdline); - + success = TIFFWriteDirectory(tifP); if (!success) pm_error("Unable to write TIFF image %u to file. " @@ -1244,10 +1100,8 @@ main(int argc, const char *argv[]) { } } - destroyTiffGenerator(cmdline.writeMethod, tifP, ofd); + destroyTiffGenerator(tifP); pm_close(ifP); return 0; } - - |