diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2010-04-20 01:56:27 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2010-04-20 01:56:27 +0000 |
commit | 02cefc20e87ed0406131c4bf2e9b3648bc8adcf5 (patch) | |
tree | bce7b2c94dfc0e402de09756b280ec28a65a5233 /converter/other/pnmtopalm | |
parent | 939ec42422e7db7c56ff5f736c00565f1bf621ff (diff) | |
download | netpbm-mirror-02cefc20e87ed0406131c4bf2e9b3648bc8adcf5.tar.gz netpbm-mirror-02cefc20e87ed0406131c4bf2e9b3648bc8adcf5.tar.xz netpbm-mirror-02cefc20e87ed0406131c4bf2e9b3648bc8adcf5.zip |
Release 10.47.12
git-svn-id: http://svn.code.sf.net/p/netpbm/code/stable@1194 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other/pnmtopalm')
-rw-r--r-- | converter/other/pnmtopalm/palmtopnm.c | 67 |
1 files changed, 61 insertions, 6 deletions
diff --git a/converter/other/pnmtopalm/palmtopnm.c b/converter/other/pnmtopalm/palmtopnm.c index d6164680..7e4ca453 100644 --- a/converter/other/pnmtopalm/palmtopnm.c +++ b/converter/other/pnmtopalm/palmtopnm.c @@ -789,8 +789,8 @@ readRleRow(FILE * const ifP, if (j + incount > bytesPerRow) pm_error("Bytes in RLE compressed row exceed bytes per row. " "Bytes per row is %u. A run length of %u bytes " - "pushes the bytes in this row up to %u bytes (and then" - "we gave up.", bytesPerRow, incount, j + incount); + "pushes the bytes in this row up to %u bytes (and then " + "we gave up).", bytesPerRow, incount, j + incount); pm_readcharu(ifP, &inval); memset(palmrow + j, inval, incount); j += incount; @@ -800,6 +800,52 @@ readRleRow(FILE * const ifP, static void +readPackBitsRow16(FILE * const ifP, + unsigned char * const palmrow, + unsigned int const bytesPerRow) { + + /* From the Palm OS Programmer's API Reference: + + Although the [...] spec is byte-oriented, the 16-bit algorithm is + identical [to the 8-bit algorithm]: just substitute "word" for "byte". + */ + unsigned int j; + + for (j = 0; j < bytesPerRow; ) { + char incount; + pm_readchar(ifP, &incount); + if (incount < 0) { + /* How do we handle incount == -128 ? */ + unsigned int const runlength = (-incount + 1) * 2; + unsigned int k; + unsigned short inval; + pm_readlittleshortu(ifP, &inval); + for (k = 0; (k < runlength) && (j + k + 1 < bytesPerRow); k += 2) { + memcpy(palmrow + j + k, &inval, 2); + } + j += runlength; + } else { + /* We just read the stream of shorts as a stream of chars */ + unsigned int const nonrunlength = (incount + 1) * 2; + unsigned int k; + for (k = 0; (k < nonrunlength) && (j + k < bytesPerRow); ++k) { + unsigned char inval; + pm_readcharu(ifP, &inval); + palmrow[j + k] = inval; + } + j += nonrunlength; + } + if (j > bytesPerRow) + pm_error("Bytes in PackBits compressed row exceed bytes per row. " + "Bytes per row is %u. " + "The bytes in this row were pushed up to %u bytes " + "(and then we gave up).", bytesPerRow, j); + } +} + + + +static void readPackBitsRow(FILE * const ifP, unsigned char * const palmrow, unsigned int const bytesPerRow) { @@ -814,12 +860,13 @@ readPackBitsRow(FILE * const ifP, unsigned int const runlength = -incount + 1; unsigned char inval; pm_readcharu(ifP, &inval); - memset(palmrow + j, inval, runlength); + if (j + runlength < bytesPerRow) + memset(palmrow + j, inval, runlength); j += runlength; } else { unsigned int const nonrunlength = incount + 1; unsigned int k; - for (k = 0; k < nonrunlength; ++k) { + for (k = 0; k < nonrunlength && j + k < bytesPerRow; ++k) { unsigned char inval; pm_readcharu(ifP, &inval); palmrow[j + k] = inval; @@ -827,7 +874,10 @@ readPackBitsRow(FILE * const ifP, j += nonrunlength; } if (j > bytesPerRow) - pm_error("Bytes in PackBits compressed row exceed bytes per row."); + pm_error("Bytes in PackBits compressed row exceed bytes per row. " + "Bytes per row is %u. " + "The bytes in this row were pushed up to %u bytes " + "(and then we gave up).", bytesPerRow, j); } } @@ -853,6 +903,7 @@ readDecompressedRow(FILE * const ifP, unsigned char * const lastrow, enum palmCompressionType const compressionType, unsigned int const bytesPerRow, + unsigned int const pixelSize, bool const firstRow) { /*---------------------------------------------------------------------------- Read a row from Palm file 'ifP', in uncompressed form (i.e. decompress if @@ -881,7 +932,10 @@ readDecompressedRow(FILE * const ifP, readScanlineRow(ifP, palmrow, lastrow, bytesPerRow, firstRow); break; case COMPRESSION_PACKBITS: - readPackBitsRow(ifP, palmrow, bytesPerRow); + if (pixelSize != 16) + readPackBitsRow(ifP, palmrow, bytesPerRow); + else + readPackBitsRow16(ifP, palmrow, bytesPerRow); break; case COMPRESSION_NONE: readUncompressedRow(ifP, palmrow, bytesPerRow); @@ -1032,6 +1086,7 @@ writePnm(FILE * const ofP, readDecompressedRow(ifP, palmrow, lastrow, palmHeader.compressionType, palmHeader.bytesPerRow, + palmHeader.pixelSize, row == 0); if (palmHeader.directColor) { |