diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2013-06-29 19:19:47 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2013-06-29 19:19:47 +0000 |
commit | 380588e187c12000ac8082cb2a20a905d3c422a5 (patch) | |
tree | 296b1324b7a9360646a34ae836b8eb486b7feede /converter/other/pnmtops.c | |
parent | f8b633c2be1231a0c194214271caa456dc669ecb (diff) | |
download | netpbm-mirror-380588e187c12000ac8082cb2a20a905d3c422a5.tar.gz netpbm-mirror-380588e187c12000ac8082cb2a20a905d3c422a5.tar.xz netpbm-mirror-380588e187c12000ac8082cb2a20a905d3c422a5.zip |
Release 10.63.00
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@1968 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other/pnmtops.c')
-rw-r--r-- | converter/other/pnmtops.c | 82 |
1 files changed, 59 insertions, 23 deletions
diff --git a/converter/other/pnmtops.c b/converter/other/pnmtops.c index dc55a7e3..1cf23be7 100644 --- a/converter/other/pnmtops.c +++ b/converter/other/pnmtops.c @@ -335,6 +335,22 @@ basebasename(const char * const filespec) { +static void +writeFile(const unsigned char * const buffer, + size_t const writeCt, + const char * const name, + FILE * const ofP) { + + size_t writtenCt; + + writtenCt = fwrite(buffer, 1, writeCt, ofP); + + if (writtenCt != writeCt) + pm_error("Error writing to %s output file", name); +} + + + #define MAX_FILTER_CT 10 /* The maximum number of filters this code is capable of applying */ @@ -494,18 +510,12 @@ flateFilter(FILE * const ifP, */ do { unsigned int have; - size_t bytesWritten; strm.avail_out = chunkSz; strm.next_out = out; deflate(&strm, flush); have = chunkSz - strm.avail_out; - bytesWritten = fwrite(out, 1, have, ofP); - if (ferror(ofP) || bytesWritten != have) { - deflateEnd(&strm); - pm_error("Error writing to internal pipe during " - "flate compression."); - } + writeFile(out, have, "flate filter", ofP); } while (strm.avail_out == 0); assert(strm.avail_in == 0); /* all input is used */ @@ -548,10 +558,8 @@ rlePutBuffer (unsigned int const repeat, if (repeat) { fputc(257 - count, fP); fputc(repeatitem, fP); - } else { - fputc(count - 1, fP); - fwrite(itembuf, 1, count, fP); - } + } else + writeFile(itembuf, count, "rlePutBuffer", fP); } @@ -673,23 +681,24 @@ asciiHexFilter(FILE * const ifP, unsigned char inbuff[40], outbuff[81]; for (eof = false; !eof; ) { - size_t bytesRead; + size_t readCt; - bytesRead = fread(inbuff, 1, 40, ifP); + readCt = fread(inbuff, 1, 40, ifP); - if (bytesRead == 0) + if (readCt == 0) eof = true; else { unsigned int i; - for (i = 0; i < bytesRead; ++i) { + for (i = 0; i < readCt; ++i) { int const item = inbuff[i]; outbuff[i*2] = hexits[item >> 4]; outbuff[i*2+1] = hexits[item & 15]; } } - outbuff[bytesRead * 2] = '\n'; - fwrite(outbuff, 1, bytesRead*2 + 1, ofP); + outbuff[readCt * 2] = '\n'; + + writeFile(outbuff, readCt * 2 + 1, "asciiHex filter", ofP); } fclose(ifP); @@ -737,7 +746,9 @@ ascii85Filter(FILE * const ifP, outbuff[1] = value % 85 + 33; outbuff[0] = value / 85 + 33; - fwrite(outbuff, 1, count + 1, ofP); + writeFile((const unsigned char *)outbuff, count + 1, + "ASCII 85 filter", ofP); + count = value = 0; outcount += 5; } @@ -759,7 +770,8 @@ ascii85Filter(FILE * const ifP, outbuff[0] = value / 85 + 33; outbuff[count + 1] = '\n'; - fwrite(outbuff, 1, count + 2, ofP); + writeFile((const unsigned char *)outbuff, count + 2, + "ASCII 85 filter", ofP); } fclose(ifP); @@ -869,13 +881,22 @@ addFilter(const char * const description, OutputEncoder * const oeP, FILE ** const feedFilePP, pid_t * const pidList) { +/*---------------------------------------------------------------------------- + Add a filter to the front of the chain. - pid_t pid; + Spawn a process to do the filtering, by running function 'filter'. + *feedFilePP is the present head of the chain. We make the new filter + process write its output to that and get its input from a new pipe. + We update *feedFilePP to the sending end of the new pipe. + + Add to the list pidList[] the PID of the process we spawn. +-----------------------------------------------------------------------------*/ FILE * const oldFeedFileP = *feedFilePP; FILE * newFeedFileP; - + pid_t pid; + spawnFilter(oldFeedFileP, filter, oeP, &newFeedFileP, &pid); if (verbose) @@ -883,7 +904,7 @@ addFilter(const char * const description, description, (unsigned)pid); fclose(oldFeedFileP); /* Child keeps this open now */ - + addToPidList(pidList, pid); *feedFilePP = newFeedFileP; @@ -1720,7 +1741,7 @@ convertRowPbm(struct pam * const pamP, bitrow[colChars-1] <<= padRight; /* right edge */ } - fwrite(bitrow, 1, colChars, fP); + writeFile(bitrow, colChars, "PBM reader", fP); } @@ -1863,6 +1884,21 @@ convertRaster(struct pam * const inpamP, +/* FILE MANAGEMENT: File management is pretty hairy here. A filter, which + runs in its own process, needs to be able to cause its output file to + close because it might be an internal pipe and the next stage needs to + know output is done. So the forking process must close its copy of the + file descriptor. BUT: if the output of the filter is not an internal + pipe but this program's output, then we don't want it closed when the + filter terminates because we'll need it to be open for the next image + the program converts (with a whole new chain of filters). + + To prevent the progam output file from getting closed, we pass a + duplicate of it to spawnFilters() and keep the original open. +*/ + + + static void convertPage(FILE * const ifP, int const turnflag, |