#BUGFIX by cg
authorClaus Gittinger <cg@exept.de>
Mon, 28 Aug 2017 13:34:44 +0200
changeset 3992 b7c4e0a78b6b
parent 3991 a0cea747ba0b
child 3993 921798977590
#BUGFIX by cg class: PCXReader changed: #readCompressedData #readRestAfterHeader class: PCXReader class comment/format in: #documentation #examples
PCXReader.st
--- a/PCXReader.st	Mon Aug 28 13:20:16 2017 +0200
+++ b/PCXReader.st	Mon Aug 28 13:34:44 2017 +0200
@@ -38,26 +38,33 @@
 
 documentation
 "
-    this class provides methods for loading 8-plane PCX bitmap files.
-
-    Due to not having too many examples for testing, this could fail
-    to read some files. 
+    this class provides methods to load PCX bitmap files.
+    PCX used to be a popular image format in the early PC times,
+    but became almost obsolete in the meantime.
+    
+    Due to not having too many examples for testing, 
+    this could fail to read some files. 
     (especially, I have no uncompressed files for testing).
 
-    Only 8-bit (i.e. 256 color) PCX images are supported.
-    Image writing is not supported.
+    Only 1,2,4,8 and 24-bit PCX images are supported.
+    Image writing is not.
 
     [See also:]
-	Image Form Icon
-	BlitImageReader FaceReader GIFReader JPEGReader PBMReader 
-	ST80FormReader SunRasterReader TargaReader TIFFReader WindowsIconReader 
-	XBMReader XPMReader XWDReader 
+        Image Form Icon
+        BlitImageReader FaceReader GIFReader JPEGReader PBMReader 
+        ST80FormReader SunRasterReader TargaReader TIFFReader WindowsIconReader 
+        XBMReader XPMReader XWDReader 
 "
 !
 
 examples
 "
+                                                        [exBegin]
     Image fromFile:'/usr/share/lilo/suse_640x480.pcx'
+                                                        [exEnd]
+                                                        [exBegin]
+    Image fromFile:'../../goodies/bitmaps/pcxImages/lena_depth8_palette.pcx'
+                                                        [exEnd]
 "
 ! !
 
@@ -210,6 +217,30 @@
     ].
     nBuffer := endIndex - bufferIndex.
 
+    "/ now merge the planes
+    nPlanes > 1 ifTrue:[
+        depth == 8 ifTrue:[
+            (nPlanes == 3 or:[nPlanes == 4]) ifTrue:[
+                "/ a simple rgb image
+                data := ByteArray uninitializedNew:(nPlanes*width*height).
+                srcIndex := dstIndex := 1.
+                1 to:height do:[:y |
+                    1 to:width do:[:x |
+                        1 to:nPlanes do:[:p |
+                            data at:dstIndex put:((planeData at:p) at:srcIndex).
+                            dstIndex := dstIndex + 1.
+                        ].    
+                        srcIndex := srcIndex + 1.
+                    ].
+                ].
+            ].
+            depth := nPlanes * depth.
+            photometric := #rgb.
+        ] ifFalse:[
+            self halt.
+        ].    
+    ].
+
 "/    sourceBytesPerRow ~~ (((width * depth) + 7) // 8) ifTrue:[
 "/        "/ have to compress - above code reads sourceBytesPerRow
 "/        "/ (to keep in sync with RLE); but we want width bytesPerRow in the image data.
@@ -231,7 +262,7 @@
 "/        ].
 "/    ].
 
-    "Modified: / 28-08-2017 / 12:24:45 / cg"
+    "Modified: / 28-08-2017 / 13:28:56 / cg"
 !
 
 readRestAfterHeader
@@ -299,17 +330,16 @@
     ((#(1 2 4 8) includes:depth) "and:[nPlanes == 1]") ifFalse:[
         "/        'PCXReader: depth: ' errorPrint. depth errorPrint. 
         "/        ' planes:' errorPrint. nPlanes errorPrintNL.
-        ^ self fileFormatError:'can only handle depth 1,2,4 or 8 images'.
+        ^ self fileFormatError:'can only handle depth''s 1,2,4 or 8'.
+    ].
+    (nPlanes between:1 and:4) ifFalse:[
+        ^ self fileFormatError:'can only handle 1 to 4 planes'.
     ].
 
     self reportDimension.
 
-    compression == 1 ifTrue:[
-        self readCompressedData
-    ] ifFalse:[
-        self readUncompressedData
-    ].
-
+    "/ precompute a first guess at the photometric;
+    "/ warning: might be changed by readCompressedData
     paletteType == 2 ifTrue:[
         photometric := #blackIs0.
     ] ifFalse:[
@@ -320,6 +350,12 @@
         ].
     ].
 
+    compression == 1 ifTrue:[
+        self readCompressedData
+    ] ifFalse:[
+        self readUncompressedData
+    ].
+
     photometric == #palette ifTrue:[ 
        (version == 5) ifTrue:[
             true "depth == 8" ifTrue:[
@@ -352,16 +388,21 @@
         ].    
     ].
         
-    samplesPerPixel := 1.
-    bitsPerSample := { depth }.
-
+    depth == 24 ifTrue:[
+        samplesPerPixel := 3.
+        bitsPerSample := #( 8 8 8 ).
+    ] ifFalse:[    
+        samplesPerPixel := 1.
+        bitsPerSample := { depth }.
+    ].
+    
     "
      |i f|
      i := Image fromFile:'somefile.pcx'.
      i inspect.
     "
 
-    "Modified: / 28-08-2017 / 13:18:27 / cg"
+    "Modified: / 28-08-2017 / 13:30:58 / cg"
 !
 
 readUncompressedData