WindowsIconReader.st
changeset 3 78aaa5408119
parent 0 3f9277473954
child 5 4d55b551dc57
--- a/WindowsIconReader.st	Wed Oct 13 01:31:41 1993 +0100
+++ b/WindowsIconReader.st	Wed Oct 13 01:32:33 1993 +0100
@@ -47,7 +47,7 @@
 
     "read the header"
 
-    header := ByteArray new:16r50.
+    header := ByteArray uninitializedNew:16r50.
     inStream nextBytes:16r50 into:header.
     width := header at:7.
     height := header at:8.
@@ -55,7 +55,7 @@
 
     "read the colormap"
 
-    rawMap := ByteArray new:(16*3).
+    rawMap := ByteArray uninitializedNew:(16*3).
     inStream nextBytes:(16*3) into:rawMap.
     rMap := Array new:16.
     gMap := Array new:16.
@@ -74,8 +74,8 @@
 
     "read the data bits"
 
-    bytesPerRow := width * inDepth / 8.
-    data4 := ByteArray new:(height * bytesPerRow).
+    bytesPerRow := width * inDepth + 7 // 8.
+    data4 := ByteArray uninitializedNew:(height * bytesPerRow).
     inStream nextBytes:(height * bytesPerRow) into:data4.
 
     "read mask"
@@ -87,7 +87,7 @@
 
     "stupid: last row first"
 
-    tmp := ByteArray new:(height * bytesPerRow).
+    tmp := ByteArray uninitializedNew:(height * bytesPerRow).
     srcIndex := 1.
     dstIndex := (height - 1) * bytesPerRow + 1.
     1 to:height do:[:row |
@@ -122,7 +122,7 @@
 fromOS2File: aFilename 
     | fileSize header inDepth
       rawMap rMap gMap bMap srcIndex dstIndex
-      data4 mask tmp bytesPerRow nColors|
+      data4 mask tmp bytesPerRow nColors nByte|
 
     inStream := FileStream readonlyFileNamed:aFilename.
     inStream isNil ifTrue:[
@@ -135,7 +135,7 @@
 
     "read the header"
 
-    header := ByteArray new:8r110.
+    header := ByteArray uninitializedNew:8r110.
     inStream nextBytes:16 into:header.
     (header startsWith:#(73 67)) ifTrue:[
         "IC format"
@@ -154,7 +154,7 @@
 
     nColors := 1 bitShift:inDepth.
 
-    rawMap := ByteArray new:(nColors*3).
+    rawMap := ByteArray uninitializedNew:(nColors*3).
     inStream nextBytes:(nColors*3) into:rawMap.
     rMap := Array new:nColors.
     gMap := Array new:nColors.
@@ -171,17 +171,18 @@
 
     "read mask"
 
-    mask := ByteArray new:(width * height / 8).
-    inStream nextBytes:(width * height / 8) into:mask.
+    nByte := width * height + 7 // 8.
+    mask := ByteArray uninitializedNew:nByte.
+    inStream nextBytes:nByte into:mask.
 
     "what is this"
 
-    inStream nextBytes:(width * height / 8) into:mask.
+    inStream nextBytes:nByte into:mask.
 
     "read the data bits"
 
-    bytesPerRow := width * inDepth / 8.
-    data4 := ByteArray new:(height * bytesPerRow).
+    bytesPerRow := width * inDepth + 7 // 8.
+    data4 := ByteArray uninitializedNew:(height * bytesPerRow).
     inStream nextBytes:(height * bytesPerRow) into:data4.
 
     "stupid: last row first"
@@ -217,6 +218,98 @@
     "
 !
 
+fromWindowsBMPFile: aFilename 
+    | fileSize header inDepth
+      rawMap rMap gMap bMap srcIndex dstIndex
+      data4 mask tmp bytesPerRow|
+
+    inStream := FileStream readonlyFileNamed:aFilename.
+    inStream isNil ifTrue:[
+        'open error' printNewline. 
+        ^ nil
+    ].
+
+    inStream binary.
+    fileSize := inStream size.
+
+    "read the header"
+
+    header := ByteArray uninitializedNew:16r50.
+    inStream nextBytes:16r50 into:header.
+    ((header at:15) == 40) ifTrue:[
+        width := (header at:19) + ((header at:20) * 256).
+        height := (header at:23) + ((header at:24) * 256).
+        inDepth := header at:29.
+    ].
+    ((header at:15) == 12) ifTrue:[
+        width := (header at:19) + ((header at:20) * 256).
+        height := (header at:21) + ((header at:22) * 256).
+        inDepth := header at:25.
+    ].
+
+    width isNil ifTrue:[
+        ^ nil
+    ].
+
+    "read the colormap"
+
+    rawMap := ByteArray uninitializedNew:(16*3).
+    inStream nextBytes:(16*3) into:rawMap.
+    rMap := Array new:16.
+    gMap := Array new:16.
+    bMap := Array new:16.
+    srcIndex := 1.
+    1 to:16 do:[:i |
+        rMap at:i put:(rawMap at:srcIndex).
+        srcIndex := srcIndex + 1.
+        gMap at:i put:(rawMap at:srcIndex).
+        srcIndex := srcIndex + 1.
+        bMap at:i put:(rawMap at:srcIndex).
+        srcIndex := srcIndex + 1.
+    ].
+
+    inStream position:16r78.
+
+    "read the data bits"
+
+    bytesPerRow := width * inDepth + 7 // 8.
+    data4 := ByteArray uninitializedNew:(height * bytesPerRow).
+    inStream nextBytes:(height * bytesPerRow) into:data4.
+
+    "read mask"
+
+"
+    mask := ByteArray new:(width * height / 8).
+    inStream nextBytes:(width * height / 8) into:mask.
+"
+
+    "stupid: last row first"
+
+    tmp := ByteArray uninitializedNew:(height * bytesPerRow).
+    srcIndex := 1.
+    dstIndex := (height - 1) * bytesPerRow + 1.
+    1 to:height do:[:row |
+        tmp replaceFrom:dstIndex to:(dstIndex + bytesPerRow - 1)
+                   with:data4 startingAt:srcIndex.
+        srcIndex := srcIndex + bytesPerRow.
+        dstIndex := dstIndex - bytesPerRow.
+    ].
+    data4 := tmp.
+
+    "expand into bytes"
+
+    data := ByteArray new:(width * height).
+    data4 expandPixels:inDepth width:width height:height
+                  into:data mapping:nil.
+
+    photometric := #palette.
+    samplesPerPixel := 1.
+    bitsPerSample := #(8).
+    colorMap := Array with:rMap with:gMap with:bMap.
+    inStream close.
+
+!
+
 fromFile: aFilename 
     | fileSize header |
 
@@ -235,8 +328,12 @@
         ^ nil
     ].
 
-    header := ByteArray new:16.
+    header := ByteArray uninitializedNew:16.
     inStream nextBytes:16 into:header.
+    (header startsWith:#(66 77)) ifTrue:[     "BM"
+        inStream close.
+        ^ self fromWindowsBMPFile:aFilename
+    ].
     (header startsWith:#(66 65)) ifTrue:[     "BA"
         inStream close.
         ^ self fromOS2File:aFilename