#BUGFIX by cg
class: PCXReader
changed:
#readCompressedData
#readRestAfterHeader
class: PCXReader class
comment/format in:
#documentation
#examples
--- 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