.ico stuff - ongoing work
authorClaus Gittinger <cg@exept.de>
Thu, 20 Jan 2005 16:26:36 +0100
changeset 2031 c8527bd15f50
parent 2030 cfe668c44a8c
child 2032 cf3b4dcc4ad3
.ico stuff - ongoing work
WindowsIconReader.st
--- a/WindowsIconReader.st	Fri Jan 07 15:35:42 2005 +0100
+++ b/WindowsIconReader.st	Thu Jan 20 16:26:36 2005 +0100
@@ -416,6 +416,7 @@
 
     inStream := aStream.
     aStream binary.
+    byteOrder := #lsb.
 
     "read the header"
 
@@ -515,6 +516,7 @@
     |fileSize header|
 
     inStream := aStream.
+    byteOrder := #lsb.
 
     aStream binary.
     fileSize := aStream fileSize.
@@ -525,43 +527,35 @@
 
     header := ByteArray uninitializedNew:4.
     aStream nextBytes:4 into:header.
+    aStream position:0.
 
     (header startsWith:#(66 77)) ifTrue:[     "BM"
-        aStream position1Based:1.
 "/        'WinIconReader [info]: Win3.x or OS/2 vsn 2 BM format' infoPrintNL.
         ^ self fromWindowsBMPStream:aStream
     ].
     (header startsWith:#(66 65)) ifTrue:[     "BA"
-        aStream position1Based:1.
 "/        'WinIconReader [info]: OS/2 vsn 2 BA format' infoPrintNL.
         ^ self fromOS2Stream:aStream
     ].                    
     (header startsWith:#(67 73)) ifTrue:[     "CI"
-        'WinIconReader [warning]: OS/2 CI format not supported:' infoPrintCR.
-        ^ nil.
-        aStream position1Based:1.
 "/        'WinIconReader [info]: OS/2 vsn 2 BA format' infoPrintNL.
-        ^ self fromOS2Stream:aStream
+"/        ^ self fromOS2Stream:aStream
+        ^ self fileFormatError:'OS/2 CI format not supported'.
     ].
     (header startsWith:#(73 67)) ifTrue:[     "IC"
-        aStream position1Based:1.
 "/        'WinIconReader [info]: OS/2 IC format' infoPrintNL.
         ^ self fromOS2Stream:aStream
     ].
     (header startsWith:#(80 84)) ifTrue:[     "PT"
-        aStream position1Based:1.
 "/        'WinIconReader [info]: OS/2 PT format' infoPrintNL.
         ^ self fromOS2Stream:aStream
     ].
     (header startsWith:#(16r53 16r5A)) ifTrue:[     "SZ"
-        'WinIconReader [warning]: OS/2 SZ format not supported:' infoPrintCR.
-        ^ nil.
-"/        aStream position1Based:1.
 "/        'WinIconReader [info]: OS/2 SZ format' infoPrintNL.
 "/        ^ self fromOS2Stream:aStream
+        ^ self fileFormatError:'OS/2 SZ format not supported'.
     ].
     (header startsWith:#(0 0 1 0)) ifTrue:[
-        aStream position1Based:1.
 "/        'WinIconReader [info]: Win3.x ICO format' infoPrintNL.
         ^ self fromWindowsICOStream:aStream
     ].
@@ -596,15 +590,15 @@
 fromWindowsBMPStream:aStream 
     "read an image from a windows BMP stream"
 
-    | fileSize header iSize inDepth inPlanes compression
+    | header iSize inDepth inPlanes compression
       imgSize resH resV numColor numImportantColor
       dataStart t
       bytesPerRow numBytesPerColorInColormap|
 
     inStream := aStream.
     aStream binary.
+    byteOrder := #lsb.
 
-    fileSize := aStream fileSize.
     "read the header"
 
     header := ByteArray uninitializedNew:16r54.
@@ -775,33 +769,62 @@
 fromWindowsICOStream:aStream
     "read an image from a windows ICO stream"
 
-    |header inDepth
-     srcIndex dstIndex
-     rawData tmp bytesPerRow nColor cmapSize|
+    |header numImages inDepth nPlanes nBitsPerPixel nBytesInResource imageOffset
+     bmHeader srcIndex dstIndex
+     rawData tmp bytesPerRow nColor cmapSize szHeader planes bitCount compression szImage xPelsPerMeter yPelsPerMeter 
+     nImportantColor widthBM heightBM nColorBM|
 
     inStream := aStream.
     aStream binary.
+    byteOrder := #lsb.
 
     "read the header"
 
-    header := ByteArray uninitializedNew:(6 + 16 + 40).
-    aStream nextBytes:(6 + 16 + 40) into:header.
+    header := ByteArray uninitializedNew:(6 + 16).
+    aStream nextBytes:(6 + 16) into:header.
+    numImages := header wordAt:(4+1) MSB:false.
+
     width := header at:(6+1).
     height := header at:(7+1).
     nColor := header at:(8+1).
     "/ reserved := header at:(9+1).
-    "/ nPlanes := header wordAt:(10+1).
-    "/ nBitsPerPel := header wordAt:(12+1).
-    "/ nBytesInResource := header doubleWordAt:(14+1).
-    "/ ordinal := header wordAt:(18+1).
-    "21, 22               ?"
-    "23, ... , 62         ?"
+    nPlanes := header wordAt:(10+1) MSB:false.
+    nBitsPerPixel := header wordAt:(12+1) MSB:false.
+    nBytesInResource := header doubleWordAt:(14+1) MSB:false.
+    imageOffset := header doubleWordAt:(18+1) MSB:false.
+
+    aStream position:imageOffset.
+.
+    bmHeader := ByteArray uninitializedNew:40.
+    aStream nextBytes:40 into:bmHeader.
 
-    inDepth := header at:16r25.
-    "/ mhmh - some depth4 icons seem to have a 0 in the depth field ...
-    inDepth == 0 ifTrue:[
-        inDepth := 4
+    szHeader := bmHeader doubleWordAt:(0+1) MSB:false.
+    widthBM := bmHeader doubleWordAt:(4+1) MSB:false.
+    heightBM := bmHeader doubleWordAt:(8+1) MSB:false.
+    planes := bmHeader wordAt:(12+1) MSB:false.
+    inDepth := bmHeader wordAt:(14+1) MSB:false.
+    compression := bmHeader wordAt:(16+1) MSB:false.
+    szImage := bmHeader doubleWordAt:(20+1) MSB:false.
+    xPelsPerMeter := bmHeader doubleWordAt:(24+1) MSB:false.
+    yPelsPerMeter := bmHeader doubleWordAt:(28+1) MSB:false.
+    nColorBM := bmHeader doubleWordAt:(32+1) MSB:false.
+    nImportantColor := bmHeader doubleWordAt:(36+1) MSB:false.
+
+    szHeader ~~ 40 ifTrue:[
+        "/ not a bm-header
+        ^ self fileFormatError:'unhandled ico-image format (szBMHeader is ' , szHeader printString , ')'.
     ].
+
+    nColor := nColorBM.
+    nColor == 0 ifTrue:[
+        "
+         some bmp-writers seem to leave this as zero (which is wrong)
+        "
+        inDepth <= 8 ifTrue:[
+            nColor := 1 bitShift:inDepth.
+        ]
+    ].
+
     (#(4 8) includes:inDepth) ifFalse:[
         "/ only tested for depth 4/8 images.
         ^ self fileFormatError:'only depth 4/8 ico-images supported (depth is ' , inDepth printString , ')'.
@@ -809,22 +832,24 @@
     ].
     self reportDimension.
 
-    "read the colormap"
-    cmapSize := (1 bitShift:inDepth).
-
-    colorMap := self
-                readColorMap:cmapSize
+self halt.
+    nColor > 0 ifTrue:[
+        "read the colormap"
+        colorMap := self
+                readColorMap:nColor
                 numBytesPerColor:4
                 from:aStream.
+    ].
 
-    "read the data bits"
+    "read the bitmap data"
+
 
     bytesPerRow := width * inDepth + 7 // 8.
     rawData := ByteArray uninitializedNew:(height * bytesPerRow).
     aStream nextBytes:(height * bytesPerRow) into:rawData.
 
     "read mask"
-
+self halt.
 "
     mask := ByteArray new:(width * height / 8).
     aStream nextBytes:(width * height / 8) into:mask.
@@ -1111,7 +1136,7 @@
 !WindowsIconReader class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview2/WindowsIconReader.st,v 1.58 2003-11-19 15:38:30 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview2/WindowsIconReader.st,v 1.59 2005-01-20 15:26:36 cg Exp $'
 ! !
 
 WindowsIconReader initialize!