#BUGFIX by cg
class: PCXReader
class definition
changed:
#readCompressedData
#readRestAfterHeader
--- a/PCXReader.st Mon Aug 28 03:43:38 2017 +0200
+++ b/PCXReader.st Mon Aug 28 11:23:48 2017 +0200
@@ -9,11 +9,12 @@
other person. No title to or ownership of the software is
hereby transferred.
"
-
"{ Package: 'stx:libview2' }"
+"{ NameSpace: Smalltalk }"
+
ImageReader subclass:#PCXReader
- instanceVariableNames:'header buffer nBuffer bufferIndex sourceBytesPerRow'
+ instanceVariableNames:'header buffer nBuffer bufferIndex sourceBytesPerRow depth'
classVariableNames:''
poolDictionaries:''
category:'Graphics-Images-Readers'
@@ -196,11 +197,11 @@
].
"/ have to compress - above code reads sourceBytesPerRow
- "/ (to keep in sync with RLE); but we want width bytesPerRow
+ "/ (to keep in sync with RLE); but we want width bytesPerRow in the image data.
"/ Can compress in the data-area; leftover pixels are simply ignored
"/ by other image processing code
"/
- sourceBytesPerRow ~~ width ifTrue:[
+ sourceBytesPerRow ~~ (((width * depth) + 7) // 8) ifTrue:[
dstIndex := width + 1.
srcIndex := sourceBytesPerRow + 1.
2 to:height do:[:row |
@@ -210,52 +211,55 @@
]
].
nBuffer := endIndex - bufferIndex.
+
+ "Modified (comment): / 28-08-2017 / 10:57:53 / cg"
!
readRestAfterHeader
"read an raw image in pcx format from aStream.
The header has already been read into the header argument."
- | inDepth version compression nPlanes xmin ymin xmax ymax
+ | version compression nPlanes xmin ymin xmax ymax
paletteType
byte "{Class: SmallInteger }"
nMaxPad|
"/ typedef struct { /*header for PCX bitmap files*/
- "/ unsigned char signature; /*1 PCX file identifier*/
- "/ unsigned char version; /*2 version compatibility level*/
- "/ unsigned char encoding; /*3 encoding method*/
- "/ unsigned char bitsperpix; /*4 bits per pixel, or depth*/
- "/ unsigned short Xleft; /*5 X position of left edge*/
- "/ unsigned short Ytop; /*7 Y position of top edge*/
- "/ unsigned short Xright; /*9 X position of right edge*/
- "/ unsigned short Ybottom; /*11 Y position of bottom edge*/
- "/ unsigned short Xscreensize; /*13 X screen res of source image*/
- "/ unsigned short Yscreensize; /*15 Y screen res of source image*/
- "/ unsigned char PCXpalette[16][3]; /*17 PCX color map*/
- "/ unsigned char reserved1; /*17+48 should be 0, 1 if std res fax*/
+ "/ unsigned char signature; /*1 PCX file identifier */
+ "/ unsigned char version; /*2 version compatibility level */
+ "/ unsigned char encoding; /*3 compression method */
+ "/ unsigned char bitsperpix; /*4 bits per pixel, or depth */
+ "/ unsigned short Xleft; /*5 X position of left edge */
+ "/ unsigned short Ytop; /*7 Y position of top edge */
+ "/ unsigned short Xright; /*9 X position of right edge */
+ "/ unsigned short Ybottom; /*11 Y position of bottom edge */
+ "/ unsigned short Xscreensize; /*13 X screen res of source image */
+ "/ unsigned short Yscreensize; /*15 Y screen res of source image */
+ "/ unsigned char PCXpalette[16][3]; /*17 PCX color map */
+ "/ unsigned char reserved1; /*17+48 should be 0, 1 if std res fax */
"/ unsigned char planes; /*66 bit planes in image*/
"/ unsigned short linesize; /*67 byte delta between scanlines */
- "/ unsigned short paletteinfo; /*0 == undef
+ "/ unsigned char paletteinfo; /*69 paletteType */
+ "/ /*0 == undef
"/ 1 == color
"/ 2 == grayscale*/
- "/ unsigned char reserved2[58]; /*fill to struct size of 128*/
+ "/ unsigned char reserved2[58]; /*70 fill to struct size of 128*/
"/ } PCX_HEADER;
version := header at:2.
-"/ 'version=' print. version printNL.
+ "/ 'version=' print. version printNL.
compression := header at:3.
-"/ 'compression=' print. compression printNL.
+ "/ 'compression=' print. compression printNL.
(#(0 1) includes:compression) ifFalse:[
^ self fileFormatError:'unknown compression'.
].
- inDepth := header at:4.
-"/ 'depth=' print. inDepth printNL.
+ depth := header at:4.
+ "/ 'depth=' print. depth printNL.
nPlanes := header at:66.
-"/ 'planes=' print. nPlanes printNL.
+ "/ 'planes=' print. nPlanes printNL.
sourceBytesPerRow := header wordAt:67 MSB:false.
-"/ 'srcBytesPerRow=' print. srcBytesPerRow printNL.
+ "/ 'srcBytesPerRow=' print. srcBytesPerRow printNL.
paletteType := header at:69.
"
@@ -263,10 +267,10 @@
I have no test pictures for other formats.
So its not (yet) implemented
"
- ((inDepth ~~ 8) or:[nPlanes ~~ 1]) ifTrue:[
-"/ 'PCXReader: depth: ' errorPrint. inDepth errorPrint.
-"/ ' planes:' errorPrint. nPlanes errorPrintNL.
- ^ self fileFormatError:'can only handle 1-plane 256 color images'.
+ ((#(1 2 4 8) includes:depth) and:[nPlanes == 1]) ifFalse:[
+ "/ 'PCXReader: depth: ' errorPrint. depth errorPrint.
+ "/ ' planes:' errorPrint. nPlanes errorPrintNL.
+ ^ self fileFormatError:'can only handle single-plane images (and depth 1,2,4 or 8)'.
].
xmin := header wordAt:5 MSB:false.
@@ -276,40 +280,56 @@
width := (xmax - xmin + 1).
height := (ymax - ymin + 1).
-"/ 'width=' print. width printNL.
-"/ 'height=' print. width printNL.
+ "/ 'width=' print. width printNL.
+ "/ 'height=' print. width printNL.
self reportDimension.
- (version == 2) ifTrue:[
- colorMap := self extractColorMap16.
- ].
-
compression == 1 ifTrue:[
self readCompressedData
] ifFalse:[
self readUncompressedData
].
- (version == 5) ifTrue:[
- "/ RLE data is padded - skip over zeros for the 0C-byte
- nMaxPad := 15.
- byte := self nextByteFromBufferOrStream.
-
- [(byte ~~ 16r0C) and:[nMaxPad > 0]] whileTrue:[
- byte := self nextByteFromBufferOrStream.
+ paletteType == 2 ifTrue:[
+ photometric := #blackIs0.
+ ] ifFalse:[
+ depth == 1 ifTrue:[
+ photometric := #blackIs0.
+ ] ifFalse:[
+ photometric := #palette.
].
- (byte == 16r0C) ifFalse:[
- 'PCXREADER: no valid 256-entry palette (got' errorPrint.
- byte errorPrint. '; expected ' errorPrint. 16rC0 errorPrint. ')' errorPrintCR.
- ].
-
- colorMap := self readColorMap256.
].
- photometric := #palette.
+ (version == 5) ifTrue:[
+ photometric == #palette ifTrue:[
+ depth == 8 ifTrue:[
+ "/ RLE data is padded - skip over zeros for the 0C-byte
+ nMaxPad := 15.
+ byte := self nextByteFromBufferOrStream.
+
+ [(byte ~~ 16r0C) and:[nMaxPad > 0]] whileTrue:[
+ byte := self nextByteFromBufferOrStream.
+ nMaxPad := nMaxPad - 1.
+ ].
+ (byte == 16r0C) ifFalse:[
+ 'PCXREADER: no valid 256-entry palette (got' errorPrint.
+ byte errorPrint. '; expected ' errorPrint. 16rC0 errorPrint. ')' errorPrintCR.
+ ].
+
+ colorMap := self readColorMap256.
+ ].
+ ].
+ ].
+
+ ((version == 2)
+ or:[ (depth <= 4 and:[photometric == #palette]) ]) ifTrue:[
+ "/ palette from header
+ colorMap := self extractColorMap16.
+ ].
+
samplesPerPixel := 1.
- bitsPerSample := #(8).
+ bitsPerSample := { depth }.
"
|i f|
@@ -317,7 +337,7 @@
i inspect.
"
- "Modified: / 3.2.1998 / 17:59:03 / cg"
+ "Modified: / 28-08-2017 / 11:22:11 / cg"
!
readUncompressedData
@@ -362,7 +382,8 @@
!PCXReader class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/PCXReader.st,v 1.33 2003-11-19 15:38:20 cg Exp $'
+ ^ '$Header$'
! !
+
PCXReader initialize!