#FEATURE
class: WindowsIconReader
added: #loadRLECompressedBMP4From:into:
changed:
#loadBMPWidth:height:bytesPerPixel:from:into:
#loadBMPWidth:height:depth:from:into:
compression 3 (16/24 bit) and RLE4 compression.
--- a/WindowsIconReader.st Wed Mar 02 14:25:19 2016 +0100
+++ b/WindowsIconReader.st Fri Mar 04 19:12:00 2016 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 1993 by Claus Gittinger
All Rights Reserved
@@ -352,27 +350,32 @@
align := 4.
- compression == 0 ifTrue:[
- imgBytesPerRow := w * bpp.
- fileBytesPerRow := imgBytesPerRow.
- (fileBytesPerRow bitAnd:(align-1)) ~~ 0 ifTrue:[
- fileBytesPerRow := (fileBytesPerRow bitAnd:((align-1) bitInvert)) + align.
- ].
- "/
- "/ stupid - last row comes first
- "/
- idx := imgBytesPerRow * (h - 1) + 1.
- buff := ByteArray uninitializedNew:fileBytesPerRow.
+ ((compression == 0) or:[compression == 3]) ifTrue:[
+ imgBytesPerRow := w * bpp.
+ fileBytesPerRow := imgBytesPerRow.
+ (fileBytesPerRow bitAnd:(align-1)) ~~ 0 ifTrue:[
+ fileBytesPerRow := (fileBytesPerRow bitAnd:((align-1) bitInvert)) + align.
+ ].
+ "/
+ "/ stupid - last row comes first
+ "/
+ idx := imgBytesPerRow * (h - 1) + 1.
+ buff := ByteArray uninitializedNew:fileBytesPerRow.
- 1 to:h do:[:row |
- (aStream nextBytes:fileBytesPerRow into:buff) ~~ fileBytesPerRow ifTrue:[
- ^ false
- ].
- data replaceFrom:idx to:idx+imgBytesPerRow-1 with:buff.
- idx := idx - imgBytesPerRow.
- ].
- ^ true
+ 1 to:h do:[:row |
+ (aStream nextBytes:fileBytesPerRow into:buff) == fileBytesPerRow ifFalse:[
+ ^ false
+ ].
+ data replaceFrom:idx to:idx+imgBytesPerRow-1 with:buff.
+ idx := idx - imgBytesPerRow.
+ ].
+ compression == 3 ifTrue:[
+ self breakPoint:#cg. "/ TODO: check what we have to do here...
+ ].
+ ^ true
].
+ "/ 'BMPReader: unsupported compression: ' infoPrint. compression infoPrintCR.
+ self fileFormatError:('unsupported compression:', compression printString).
^ false.
!
@@ -386,7 +389,8 @@
compression == 1 ifTrue:[
^ self loadRLECompressedBMP8From:aStream into:data.
].
- self breakPoint:#cg info:'unhandled compression'.
+ "/ self breakPoint:#cg info:'unhandled compression'.
+ self fileFormatError:('unsupported compression:', compression printString).
^ false
].
d == 4 ifTrue:[
@@ -415,12 +419,89 @@
^ true
].
+ self fileFormatError:('unsupported depth:', d printString).
^ false
"Created: / 17.9.1995 / 18:48:11 / claus"
"Modified: / 3.2.1998 / 20:21:16 / cg"
!
+loadRLECompressedBMP4From:aStream into:aByteArray
+ "load bmp-rle-4 pixel imagedata"
+
+ |bytesPerRowInData x y dstIndex lineStartIndex cnt pair clr1 clr2 code n nbyte|
+
+ bytesPerRowInData := self bytesPerRow.
+ x := 0.
+ y := height - 1.
+ lineStartIndex := (y * bytesPerRowInData) + 1.
+ dstIndex := lineStartIndex.
+
+ [ y < height ] whileTrue:[
+ cnt := aStream nextByte.
+ pair := aStream nextByte.
+ cnt ~~ 0 ifTrue:[
+ clr1 := pair bitShift:-4.
+ clr2 := pair bitAnd:16rF.
+ [cnt > 1] whileTrue:[
+ aByteArray at:dstIndex put:((clr2 << 4) bitOr:clr1).
+ dstIndex := dstIndex + 1.
+ cnt := cnt - 2.
+ x := x + 2.
+ ].
+ (cnt > 0) ifTrue:[
+ "/ got odd count
+ aByteArray at:dstIndex put:clr1.
+ x := x + 1.
+ self halt.
+ ].
+ ] ifFalse:[
+ "/ cnt == 0: escape codes */
+ code := pair.
+ code == 0 ifTrue:[
+ "/ end of line
+ x := 0.
+ y := y - 1.
+ lineStartIndex := lineStartIndex - bytesPerRowInData.
+ dstIndex := lineStartIndex.
+ ] ifFalse:[
+ code == 1 ifTrue:[
+ "/ end of pic
+ ^ true
+ ].
+ code == 2 ifTrue:[
+ "/ delta
+ x := x + aStream nextSignedByte.
+ y := y - aStream nextSignedByte.
+ lineStartIndex := (y * bytesPerRowInData) + 1.
+ dstIndex := lineStartIndex + x.
+ ] ifFalse:[
+ "/ absolute; cnt pixels coming
+ cnt := code.
+ nbyte := cnt // 2.
+ n := aStream nextBytes:nbyte into:aByteArray startingAt:dstIndex.
+ n ~~ nbyte ifTrue:[^ false].
+ dstIndex := dstIndex + nbyte.
+ x := x + cnt.
+
+ cnt odd ifTrue:[
+ clr1 := aStream nextByte.
+ aByteArray at:dstIndex put:clr1.
+ x := x + 1.
+ self halt.
+ ].
+
+ "/ odd count - padd
+ nbyte odd ifTrue:[
+ aStream skip:1.
+ ].
+ ].
+ ].
+ ].
+ ].
+ ^ true.
+!
+
loadRLECompressedBMP8From:aStream into:aByteArray
"load bmp-8 bit per pixel imagedata"