--- a/PCXReader.st Tue Aug 29 12:38:15 2017 +0200
+++ b/PCXReader.st Tue Aug 29 13:08:29 2017 +0200
@@ -40,6 +40,7 @@
documentation
"
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.
This reader is not tuned and performs slow on non-8bit images;
@@ -50,14 +51,16 @@
this could fail to read some files.
(especially, I have no uncompressed files for testing).
- Only 1,2,4,8 and 24-bit PCX images are supported.
+ 1,2,4,8 and 24-bit PCX images are supported, both in single and separate
+ plane formats.
+
Image writing is not.
[See also:]
Image Form Icon
BlitImageReader FaceReader GIFReader JPEGReader PBMReader
ST80FormReader SunRasterReader TargaReader TIFFReader WindowsIconReader
- XBMReader XPMReader XWDReader
+ XBMReader XPMReader XWDReader PNGReader JPEGReader
"
!
@@ -464,7 +467,6 @@
photometric := #palette.
].
].
- self readImageData.
depth == 24 ifTrue:[
samplesPerPixel := 3.
@@ -481,6 +483,8 @@
].
].
+ self readImageData.
+
photometric == #palette ifTrue:[
(version == 5) ifTrue:[
true "depth == 8" ifTrue:[
@@ -520,7 +524,7 @@
i inspect.
"
- "Modified: / 29-08-2017 / 12:24:11 / cg"
+ "Modified: / 29-08-2017 / 13:00:56 / cg"
!
readScanlineTo:data startingAt:startIndex
@@ -582,9 +586,13 @@
].
] ifFalse:[
"/ need some bit-stuffing to merge planes...
+ "/ the following code is a q&d, straight forward, and
+ "/ completely untuned hack.
+
depth <= 8 ifTrue:[
"/ merge into bytes
- |m0 srcByteIndex inShift mask outBitCount pixelBits outShift xOffs bits|
+ |m0 srcByteIndex inShift mask outBitCount
+ pixelBits outShift xOffs bits rowOffsets|
m0 := #( 16r80 16rC0 nil 16rF0 ) at:bitsPerPixelIn.
mask := #( 1 3 0 7 ) at:bitsPerPixelIn.
@@ -595,17 +603,20 @@
inShift := 8-bitsPerPixelIn.
outShift := 8-(depth).
+ rowOffsets := { 0 . sourceBytesPerRow . (sourceBytesPerRow*2) . (sourceBytesPerRow*3) }.
+ rowOffsets := (rowOffsets copyTo:nPlanesUsed) reversed.
+
1 to:width do:[:x |
"/ collect pixel's bits from planes
pixelBits := 0.
- rowOffset := 0.
+ "/ rowOffset := 0.
1 to:nPlanesUsed do:[:p |
- byte := rowBytes at:xOffs+rowOffset.
+ byte := rowBytes at:xOffs+(rowOffsets at:p).
bits := (byte rightShift:inShift) bitAnd:mask.
"/ bits now contains the plane's bits in the low bit positions
pixelBits := (pixelBits bitShift:bitsPerPixelIn) bitOr:bits.
- rowOffset := rowOffset + sourceBytesPerRow.
+ "/ rowOffset := rowOffset + sourceBytesPerRow.
].
inShift := inShift - bitsPerPixelIn.
inShift < 0 ifTrue:[
@@ -625,14 +636,16 @@
outShift := 8-(depth).
dstIndex := dstIndex + 1.
].
- ]
+ ].
] ifFalse:[
depth == 16 ifTrue:[
"/ merge into 16bit ints
+ "/ in theory, this is possible (eg. bitsPerPixel=4; nPlanes=3),
+ "/ but I never saw such a file in the wild...
self halt.
] ifFalse:[
- self error.
].
+ self fileFormatError:('unsupported: depth%1 with %2 planes' bindWith:bitsPerPixelIn with:nPlanes).
].
].
] ifFalse:[
@@ -640,7 +653,7 @@
].
"Created: / 29-08-2017 / 09:49:41 / cg"
- "Modified: / 29-08-2017 / 12:27:12 / cg"
+ "Modified: / 29-08-2017 / 13:08:03 / cg"
! !
!PCXReader methodsFor:'reading'!