#BUGFIX by cg
authorClaus Gittinger <cg@exept.de>
Mon, 28 Aug 2017 11:23:48 +0200
changeset 3990 1edec82fe2fa
parent 3989 a1fa18648a9c
child 3991 a0cea747ba0b
#BUGFIX by cg class: PCXReader class definition changed: #readCompressedData #readRestAfterHeader
PCXReader.st
--- 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!