--- a/WindowsIconReader.st Fri Mar 04 19:12:00 2016 +0100
+++ b/WindowsIconReader.st Fri Mar 04 19:28:50 2016 +0100
@@ -453,7 +453,7 @@
"/ got odd count
aByteArray at:dstIndex put:clr1.
x := x + 1.
- self halt.
+ "/ self halt.
].
] ifFalse:[
"/ cnt == 0: escape codes */
@@ -488,7 +488,7 @@
clr1 := aStream nextByte.
aByteArray at:dstIndex put:clr1.
x := x + 1.
- self halt.
+ "/ self halt.
].
"/ odd count - padd
@@ -848,186 +848,195 @@
header := ByteArray uninitializedNew:16r54.
bytesAlreadyRead size > 0 ifTrue:[
- header replaceFrom:1 with:bytesAlreadyRead
+ header replaceFrom:1 with:bytesAlreadyRead
].
aStream nextBytes:(18-bytesAlreadyRead size) into:header startingAt:(1+bytesAlreadyRead size).
iSize := header at:(16r0E + 1).
(iSize == 40) ifTrue:[ "header-size"
- "/
- "/ a Windows3.x BMP file
- "/
- "/ 'WinIconReader [info]: Win3.x format' infoPrintCR.
+ "/
+ "/ a Windows3.x BMP file
+ "/
+ "/ 'WinIconReader [info]: Win3.x format' infoPrintCR.
- aStream nextBytes:(40-4) into:header startingAt:19.
+ aStream nextBytes:(40-4) into:header startingAt:19.
- width := header wordAt:(16r12 + 1) MSB:false.
- height := header wordAt:(16r16 + 1) MSB:false.
- inPlanes := header wordAt:(16r1A + 1) MSB:false.
- inDepth := header wordAt:(16r1C + 1) MSB:false.
- compression := header wordAt:(16r1E + 1) MSB:false.
- imgSize := header doubleWordAt:(16r22 + 1) MSB:false.
- resH := header doubleWordAt:(16r26 + 1) MSB:false.
- resV := header doubleWordAt:(16r2A + 1) MSB:false.
- numColor := header doubleWordAt:(16r2E + 1) MSB:false.
- numImportantColor := header doubleWordAt:(16r32 + 1) MSB:false.
- redMask := header doubleWordAt:(16r36 + 1) MSB:false.
- greenMask := header doubleWordAt:(16r3A + 1) MSB:false.
- blueMask := header doubleWordAt:(16r3E + 1) MSB:false.
- alphaMask := header doubleWordAt:(16r42 + 1) MSB:false.
+ width := header wordAt:(16r12 + 1) MSB:false.
+ height := header wordAt:(16r16 + 1) MSB:false.
+ inPlanes := header wordAt:(16r1A + 1) MSB:false.
+ inDepth := header wordAt:(16r1C + 1) MSB:false.
+ compression := header wordAt:(16r1E + 1) MSB:false.
+ imgSize := header doubleWordAt:(16r22 + 1) MSB:false.
+ resH := header doubleWordAt:(16r26 + 1) MSB:false.
+ resV := header doubleWordAt:(16r2A + 1) MSB:false.
+ numColor := header doubleWordAt:(16r2E + 1) MSB:false.
+ numImportantColor := header doubleWordAt:(16r32 + 1) MSB:false.
+ redMask := header doubleWordAt:(16r36 + 1) MSB:false.
+ greenMask := header doubleWordAt:(16r3A + 1) MSB:false.
+ blueMask := header doubleWordAt:(16r3E + 1) MSB:false.
+ alphaMask := header doubleWordAt:(16r42 + 1) MSB:false.
- numColor == 0 ifTrue:[
- "
- some bmp-writers seem to leave this as zero (which is wrong)
- "
- inDepth <= 8 ifTrue:[
- numColor := 1 bitShift:inDepth.
- "/ 'WinIconReader [warning]: missing nColor in header - assume ' infoPrint. numColor infoPrintCR
- ]
- ].
+ numColor == 0 ifTrue:[
+ "
+ some bmp-writers seem to leave this as zero (which is wrong)
+ "
+ inDepth <= 8 ifTrue:[
+ numColor := 1 bitShift:inDepth.
+ "/ 'WinIconReader [warning]: missing nColor in header - assume ' infoPrint. numColor infoPrintCR
+ ]
+ ].
- numBytesPerColorInColormap := 4.
- dataStart := header wordAt:(16r0A + 1) MSB:false
+ numBytesPerColorInColormap := 4.
+ dataStart := header wordAt:(16r0A + 1) MSB:false
] ifFalse:[
- ((iSize == 12) or:[iSize >= 64]) ifTrue:[
- "/
- "/ its an OS/2 BMP file
- "/
- "/ 'WinIconReader [info]: OS/2 format' infoPrintCR.
- aStream nextBytes:(iSize-4) into:header startingAt:19.
+ ((iSize == 12) or:[iSize >= 64]) ifTrue:[
+ "/
+ "/ its an OS/2 BMP file
+ "/
+ "/ 'WinIconReader [info]: OS/2 format' infoPrintCR.
+ aStream nextBytes:(iSize-4) into:header startingAt:19.
- numBytesPerColorInColormap := 3.
- dataStart := nil.
+ numBytesPerColorInColormap := 3.
+ dataStart := nil.
- iSize == 12 ifTrue:[
- width := header wordAt:(16r12 + 1) MSB:false.
- height := header wordAt:(16r14 + 1) MSB:false.
- inPlanes := header wordAt:(16r16 + 1) MSB:false.
- inDepth := header wordAt:(16r18 + 1) MSB:false.
- "/ dataStart := header wordAt:(16r0A + 1) MSB:false.
- compression := 0.
- ].
- iSize >= 64 ifTrue:[
- "/
- "/ its an OS/2 (vsn2) BMP file
- "/
- width := header doubleWordAt:(16r12 + 1) MSB:false.
- height := header doubleWordAt:(16r16 + 1) MSB:false.
- inPlanes := header wordAt:(16r1A + 1) MSB:false.
- inDepth := header wordAt:(16r1c + 1) MSB:false.
- compression := header doubleWordAt:(16r1e + 1) MSB:false.
- numColor := header doubleWordAt:(16r2E + 1) MSB:false.
- numImportantColor := header doubleWordAt:(16r32 + 1) MSB:false.
- dataStart := header wordAt:(16r0A + 1) MSB:false.
- ].
- numColor := 1 bitShift:inDepth.
- ] ifFalse:[
- ^ self fileFormatError:'unknown format'.
- ].
+ iSize == 12 ifTrue:[
+ width := header wordAt:(16r12 + 1) MSB:false.
+ height := header wordAt:(16r14 + 1) MSB:false.
+ inPlanes := header wordAt:(16r16 + 1) MSB:false.
+ inDepth := header wordAt:(16r18 + 1) MSB:false.
+ "/ dataStart := header wordAt:(16r0A + 1) MSB:false.
+ compression := 0.
+ ].
+ iSize >= 64 ifTrue:[
+ "/
+ "/ its an OS/2 (vsn2) BMP file
+ "/
+ width := header doubleWordAt:(16r12 + 1) MSB:false.
+ height := header doubleWordAt:(16r16 + 1) MSB:false.
+ inPlanes := header wordAt:(16r1A + 1) MSB:false.
+ inDepth := header wordAt:(16r1c + 1) MSB:false.
+ compression := header doubleWordAt:(16r1e + 1) MSB:false.
+ numColor := header doubleWordAt:(16r2E + 1) MSB:false.
+ numImportantColor := header doubleWordAt:(16r32 + 1) MSB:false.
+ dataStart := header wordAt:(16r0A + 1) MSB:false.
+ ].
+ numColor := 1 bitShift:inDepth.
+ ] ifFalse:[
+ ^ self fileFormatError:'unknown format'.
+ ].
].
-
+ width > 10000 ifTrue:[
+ ^ self fileFormatError:'unreasonable width'.
+ ].
+ height > 10000 ifTrue:[
+ ^ self fileFormatError:'unreasonable height'.
+ ].
+
self reportDimension.
numColor ~~ 0 ifTrue:[
- "read the colormap - notice: its in BGR order (sigh)"
+ "read the colormap - notice: its in BGR order (sigh)"
- colorMap := self
- readColorMap:numColor
- numBytesPerColor:numBytesPerColorInColormap
- from:aStream.
+ numColor > (2 raisedTo:inDepth) ifTrue:[
+ ^ self fileFormatError:'unreasonable colormap size'.
+ ].
+ colorMap := self
+ readColorMap:numColor
+ numBytesPerColor:numBytesPerColorInColormap
+ from:aStream.
- numColor > (1 bitShift:inDepth) ifTrue:[
- 'funny number of colors in image' infoPrintCR.
- numColor := 1 bitShift:inDepth.
- colorMap := colorMap copyTo:numColor.
- ].
+ numColor > (1 bitShift:inDepth) ifTrue:[
+ 'funny number of colors in image' infoPrintCR.
+ numColor := 1 bitShift:inDepth.
+ colorMap := colorMap copyTo:numColor.
+ ].
].
"/ check for valid compression
compression ~~ 0 ifTrue:[
- "/ some compression
- compression == 1 ifTrue:[
- "/ RLE8 - must be depth-8
- inDepth ~~ 8 ifTrue:[
- ^ self fileFormatError:'RLE8 compression only supported with depth8 images'.
- ].
- ].
- compression == 2 ifTrue:[
- "/ RLE4 - must be depth-4
- inDepth ~~ 4 ifTrue:[
- ^ self fileFormatError:'RLE4 compression only supported with depth4 images'.
- ].
- ].
- compression == 3 ifTrue:[
- "/ BITFIELDS - must be depth-16 or 32
- ((inDepth ~~ 16) and:[inDepth ~~ 32]) ifTrue:[
- ^ self fileFormatError:'BITFIELDS compression only supported with depth16/32 images'.
- ].
- ].
- compression >= 4 ifTrue:[
- ^ self fileFormatError:'unsupported compression'.
- ].
+ "/ some compression
+ compression == 1 ifTrue:[
+ "/ RLE8 - must be depth-8
+ inDepth ~~ 8 ifTrue:[
+ ^ self fileFormatError:'RLE8 compression only supported with depth8 images'.
+ ].
+ ].
+ compression == 2 ifTrue:[
+ "/ RLE4 - must be depth-4
+ inDepth ~~ 4 ifTrue:[
+ ^ self fileFormatError:'RLE4 compression only supported with depth4 images'.
+ ].
+ ].
+ compression == 3 ifTrue:[
+ "/ BITFIELDS - must be depth-16 or 32
+ ((inDepth ~~ 16) and:[inDepth ~~ 32]) ifTrue:[
+ ^ self fileFormatError:'BITFIELDS compression only supported with depth16/32 images'.
+ ].
+ ].
+ compression >= 4 ifTrue:[
+ ^ self fileFormatError:'unsupported compression'.
+ ].
].
inPlanes ~~ 1 ifTrue:[
- ^ self fileFormatError:'only 1 plane images supported'.
+ ^ self fileFormatError:'only 1 plane images supported'.
].
dataStart notNil ifTrue:[
- aStream position:dataStart.
+ aStream position:dataStart.
].
inDepth <= 8 ifTrue:[
- samplesPerPixel := 1.
- bitsPerSample := Array with:inDepth.
- photometric := #palette.
+ samplesPerPixel := 1.
+ bitsPerSample := Array with:inDepth.
+ photometric := #palette.
] ifFalse:[
- inDepth == 16 ifTrue:[
- photometric := #palette.
- samplesPerPixel := 3.
- bitsPerSample := #(5 5 5).
- colorMap := FixedPalette
- redShift:10 redMask:16r1f
- greenShift:5 greenMask:16r1f
- blueShift:0 blueMask:16r1F.
+ inDepth == 16 ifTrue:[
+ photometric := #palette.
+ samplesPerPixel := 3.
+ bitsPerSample := #(5 5 5).
+ colorMap := FixedPalette
+ redShift:10 redMask:16r1f
+ greenShift:5 greenMask:16r1f
+ blueShift:0 blueMask:16r1F.
- ] ifFalse:[
- inDepth == 24 ifTrue:[
- photometric := #rgb.
- samplesPerPixel := 3.
- bitsPerSample := #(8 8 8).
- ] ifFalse:[
- inDepth == 32 ifTrue:[
- photometric := #rgb.
- samplesPerPixel := 4.
- bitsPerSample := #(8 8 8 8).
- ] ifFalse:[
- ^ self fileFormatError:'unsupported depth'.
- ]
- ]
- ]
+ ] ifFalse:[
+ inDepth == 24 ifTrue:[
+ photometric := #rgb.
+ samplesPerPixel := 3.
+ bitsPerSample := #(8 8 8).
+ ] ifFalse:[
+ inDepth == 32 ifTrue:[
+ photometric := #rgb.
+ samplesPerPixel := 4.
+ bitsPerSample := #(8 8 8 8).
+ ] ifFalse:[
+ ^ self fileFormatError:'unsupported depth'.
+ ]
+ ]
+ ]
].
inDepth == 24 ifTrue:[
- bytesPerRow := width * 3
+ bytesPerRow := width * 3
] ifFalse:[
- inDepth == 16 ifTrue:[
- bytesPerRow := width * 2
- ] ifFalse:[
- inDepth == 32 ifTrue:[
- bytesPerRow := width * 4
- ] ifFalse:[
- bytesPerRow := self bytesPerRow
- ].
- ].
+ inDepth == 16 ifTrue:[
+ bytesPerRow := width * 2
+ ] ifFalse:[
+ inDepth == 32 ifTrue:[
+ bytesPerRow := width * 4
+ ] ifFalse:[
+ bytesPerRow := self bytesPerRow
+ ].
+ ].
].
data := ByteArray uninitializedNew:(height * bytesPerRow).
"/ read & possibly decompress
(self loadBMPWidth:width height:height depth:inDepth from:aStream into:data) ifFalse:[
- self fileFormatError:('read/decompression error').
- ^ nil
+ self fileFormatError:('read/decompression error').
+ ^ nil
].
^ self image