author | Claus Gittinger <cg@exept.de> |
Sun, 04 Feb 1996 22:03:27 +0100 | |
changeset 161 | c47f1fd6cf5b |
parent 160 | ee4d64b12c94 |
child 172 | ee7d84977c86 |
permissions | -rw-r--r-- |
0 | 1 |
" |
2 |
COPYRIGHT (c) 1993 by Claus Gittinger |
|
28 | 3 |
All Rights Reserved |
0 | 4 |
|
5 |
This software is furnished under a license and may be used |
|
6 |
only in accordance with the terms of that license and with the |
|
7 |
inclusion of the above copyright notice. This software may not |
|
8 |
be provided or otherwise made available to, or used by, any |
|
9 |
other person. No title to or ownership of the software is |
|
10 |
hereby transferred. |
|
11 |
" |
|
12 |
||
13 |
ImageReader subclass:#WindowsIconReader |
|
28 | 14 |
instanceVariableNames:'' |
15 |
classVariableNames:'' |
|
16 |
poolDictionaries:'' |
|
32 | 17 |
category:'Graphics-Images support' |
0 | 18 |
! |
19 |
||
21 | 20 |
!WindowsIconReader class methodsFor:'documentation'! |
21 |
||
22 |
copyright |
|
23 |
" |
|
24 |
COPYRIGHT (c) 1993 by Claus Gittinger |
|
28 | 25 |
All Rights Reserved |
0 | 26 |
|
21 | 27 |
This software is furnished under a license and may be used |
28 |
only in accordance with the terms of that license and with the |
|
29 |
inclusion of the above copyright notice. This software may not |
|
30 |
be provided or otherwise made available to, or used by, any |
|
31 |
other person. No title to or ownership of the software is |
|
32 |
hereby transferred. |
|
33 |
" |
|
34 |
! |
|
0 | 35 |
|
21 | 36 |
version |
161
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
37 |
^ '$Header: /cvs/stx/stx/libview2/WindowsIconReader.st,v 1.21 1996-02-04 21:03:27 cg Exp $' |
21 | 38 |
! |
39 |
||
40 |
documentation |
|
41 |
" |
|
32 | 42 |
this class provides methods for loading Windows and OS2 icon files. |
43 |
Image writing is not supported. |
|
21 | 44 |
" |
45 |
! ! |
|
0 | 46 |
|
28 | 47 |
!WindowsIconReader class methodsFor:'initialization'! |
48 |
||
49 |
initialize |
|
50 |
Image fileFormats at:'.bmp' put:self. |
|
51 |
Image fileFormats at:'.ico' put:self. |
|
52 |
! ! |
|
53 |
||
102 | 54 |
!WindowsIconReader class methodsFor:'testing'! |
55 |
||
56 |
isValidImageFile:aFileName |
|
57 |
"return true, if aFileName contains a valid windows bitmap-file image" |
|
58 |
||
59 |
|inStream header ok| |
|
60 |
||
61 |
inStream := self streamReadingFile:aFileName. |
|
62 |
inStream isNil ifTrue:[^ false]. |
|
63 |
||
64 |
inStream binary. |
|
104 | 65 |
ok := false. |
66 |
inStream size > 16 ifTrue:[ |
|
67 |
header := ByteArray uninitializedNew:4. |
|
68 |
inStream nextBytes:4 into:header. |
|
102 | 69 |
|
104 | 70 |
(header startsWith:#(66 77)) ifTrue:[ "BM" |
71 |
ok := true. |
|
72 |
"/ 'WINREADER: Win3.x or OS/2 vsn 2 BM format' infoPrintNL. |
|
73 |
]. |
|
74 |
(header startsWith:#(66 65)) ifTrue:[ "BA" |
|
75 |
ok := true. |
|
76 |
"/ 'WINREADER: OS/2 vsn 2 BA format' infoPrintNL. |
|
77 |
]. |
|
78 |
(header startsWith:#(73 67)) ifTrue:[ "IC" |
|
79 |
ok := true. |
|
80 |
"/ 'WINREADER: OS/2 IC format' infoPrintNL. |
|
81 |
]. |
|
82 |
(header startsWith:#(80 84)) ifTrue:[ "PT" |
|
83 |
ok := true. |
|
84 |
"/ 'WINREADER: OS/2 PT format' infoPrintNL. |
|
85 |
]. |
|
86 |
(header startsWith:#(0 0 1 0)) ifTrue:[ |
|
87 |
ok := true. |
|
88 |
"/ 'WINREADER: Win3.x ICO format' infoPrintNL. |
|
89 |
]. |
|
102 | 90 |
]. |
104 | 91 |
inStream close. |
92 |
^ ok |
|
102 | 93 |
|
94 |
" |
|
95 |
WindowsIconReader isValidImageFile:'/phys/clam2/LocalLibrary/Images/OS2_icons/dos.ico' |
|
96 |
" |
|
97 |
||
98 |
"Created: 17.9.1995 / 17:14:20 / claus" |
|
99 |
! ! |
|
100 |
||
103 | 101 |
!WindowsIconReader methodsFor:'private'! |
102 |
||
103 |
loadBMPWidth:w height:h depth:d compression:c from:aStream into:data |
|
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
104 |
|buff idx1 idx2 bytesPerRow| |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
105 |
|
103 | 106 |
d == 8 ifTrue:[ |
107 |
(self class loadBMP8Width:w height:h compression:c from:aStream into:data) ifFalse:[ |
|
108 |
'BMP: read/decompression failed' errorPrintNL. |
|
109 |
^ false |
|
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
110 |
]. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
111 |
^ true |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
112 |
]. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
113 |
d == 4 ifTrue:[ |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
114 |
(self class loadBMP4to8Width:w height:h compression:c from:aStream into:data) ifFalse:[ |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
115 |
'BMP: read/decompression failed' errorPrintNL. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
116 |
^ false |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
117 |
]. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
118 |
^ true |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
119 |
]. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
120 |
d == 2 ifTrue:[ |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
121 |
(self class loadBMP2to8Width:w height:h from:aStream into:data) ifFalse:[ |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
122 |
'BMP: read failed' errorPrintNL. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
123 |
^ false |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
124 |
]. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
125 |
^ true |
103 | 126 |
]. |
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
127 |
d == 1 ifTrue:[ |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
128 |
(self class loadBMP1to8Width:w height:h from:aStream into:data) ifFalse:[ |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
129 |
'BMP: read failed' errorPrintNL. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
130 |
^ false |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
131 |
]. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
132 |
^ true |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
133 |
]. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
134 |
d == 24 ifTrue:[ |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
135 |
bytesPerRow := w * 3. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
136 |
((aStream nextBytes:(h * bytesPerRow) into:data) ~~ (h * bytesPerRow)) ifTrue:[ |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
137 |
'BMP: read failed' errorPrintNL. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
138 |
^ false |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
139 |
]. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
140 |
"/ stupid - last row comes first |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
141 |
|
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
142 |
buff := ByteArray uninitializedNew:bytesPerRow. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
143 |
idx1 := 1. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
144 |
idx2 := 1 + (h-1 * bytesPerRow). |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
145 |
[idx1 < idx2] whileTrue:[ |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
146 |
buff replaceFrom:1 to:bytesPerRow with:data startingAt:idx1. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
147 |
data replaceFrom:idx1 to:(idx1 + bytesPerRow - 1) with:data startingAt:idx2. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
148 |
data replaceFrom:idx2 to:(idx2 + bytesPerRow - 1) with:buff startingAt:1. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
149 |
idx1 := idx1 + bytesPerRow. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
150 |
idx2 := idx2 - bytesPerRow. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
151 |
]. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
152 |
^ true |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
153 |
]. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
154 |
'BMP: unsupported depth:' errorPrint. d errorPrintNL. |
103 | 155 |
|
156 |
"Created: 17.9.1995 / 18:48:11 / claus" |
|
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
157 |
"Modified: 4.2.1996 / 18:04:44 / cg" |
103 | 158 |
! ! |
159 |
||
53 | 160 |
!WindowsIconReader methodsFor:'reading from file'! |
0 | 161 |
|
21 | 162 |
fromOS2File: aFilename |
41 | 163 |
|reader stream| |
164 |
||
165 |
stream := self streamReadingFile:aFilename. |
|
166 |
stream isNil ifTrue:[^ nil]. |
|
83 | 167 |
reader := (self new) fromOS2Stream:stream. |
41 | 168 |
stream close. |
169 |
reader notNil ifTrue:[^ reader image]. |
|
170 |
^ nil |
|
21 | 171 |
! |
0 | 172 |
|
21 | 173 |
fromWindowsBMPFile: aFilename |
41 | 174 |
|reader stream| |
175 |
||
176 |
stream := self class streamReadingFile:aFilename. |
|
177 |
stream isNil ifTrue:[^ nil]. |
|
83 | 178 |
reader := (self new) fromWindowsBMPStream:stream. |
41 | 179 |
stream close. |
180 |
reader notNil ifTrue:[^ reader image]. |
|
181 |
^ nil |
|
21 | 182 |
! |
183 |
||
184 |
fromWindowsICOFile: aFilename |
|
41 | 185 |
|reader stream| |
186 |
||
187 |
stream := self class streamReadingFile:aFilename. |
|
188 |
stream isNil ifTrue:[^ nil]. |
|
83 | 189 |
reader := (self new) fromWindowsICOStream:stream. |
41 | 190 |
stream close. |
191 |
reader notNil ifTrue:[^ reader image]. |
|
192 |
^ nil |
|
21 | 193 |
|
194 |
" |
|
195 |
Image fromFile:'/phys/clam2//LocalLibrary/Images/WIN_icons/ibm.ico'. |
|
196 |
" |
|
197 |
! |
|
198 |
||
41 | 199 |
fromWindowsICOStream:aStream |
21 | 200 |
| header inDepth |
201 |
rawMap rMap gMap bMap srcIndex dstIndex |
|
202 |
data4 mask tmp bytesPerRow nColor| |
|
0 | 203 |
|
41 | 204 |
inStream := aStream. |
205 |
aStream binary. |
|
0 | 206 |
|
207 |
"read the header" |
|
208 |
||
21 | 209 |
header := ByteArray uninitializedNew:(6 + 16 + 40). |
41 | 210 |
aStream nextBytes:(6 + 16 + 40) into:header. |
21 | 211 |
width := header at:(6+1). |
212 |
height := header at:(7+1). |
|
213 |
nColor := header at:(8+1). |
|
214 |
"10, 11, 12, 13, 14 ? (reserve)" |
|
215 |
"15, 16, 17, 18 pixel array size" |
|
216 |
"19, 20, 21, 22 offset " |
|
217 |
"23, ... , 62 ?" |
|
218 |
||
0 | 219 |
inDepth := header at:16r25. |
220 |
||
221 |
"read the colormap" |
|
222 |
||
21 | 223 |
rawMap := ByteArray uninitializedNew:(16*4). |
41 | 224 |
aStream nextBytes:(16*4) into:rawMap. |
0 | 225 |
rMap := Array new:16. |
226 |
gMap := Array new:16. |
|
227 |
bMap := Array new:16. |
|
228 |
srcIndex := 1. |
|
229 |
1 to:16 do:[:i | |
|
28 | 230 |
bMap at:i put:(rawMap at:srcIndex). |
231 |
srcIndex := srcIndex + 1. |
|
232 |
gMap at:i put:(rawMap at:srcIndex). |
|
233 |
srcIndex := srcIndex + 1. |
|
234 |
rMap at:i put:(rawMap at:srcIndex). |
|
235 |
srcIndex := srcIndex + 1. |
|
236 |
srcIndex := srcIndex + 1. |
|
0 | 237 |
]. |
238 |
||
239 |
"read the data bits" |
|
240 |
||
3 | 241 |
bytesPerRow := width * inDepth + 7 // 8. |
242 |
data4 := ByteArray uninitializedNew:(height * bytesPerRow). |
|
41 | 243 |
aStream nextBytes:(height * bytesPerRow) into:data4. |
0 | 244 |
|
245 |
"read mask" |
|
246 |
||
247 |
" |
|
248 |
mask := ByteArray new:(width * height / 8). |
|
41 | 249 |
aStream nextBytes:(width * height / 8) into:mask. |
0 | 250 |
" |
251 |
||
252 |
"stupid: last row first" |
|
253 |
||
3 | 254 |
tmp := ByteArray uninitializedNew:(height * bytesPerRow). |
0 | 255 |
srcIndex := 1. |
256 |
dstIndex := (height - 1) * bytesPerRow + 1. |
|
257 |
1 to:height do:[:row | |
|
28 | 258 |
tmp replaceFrom:dstIndex to:(dstIndex + bytesPerRow - 1) |
259 |
with:data4 startingAt:srcIndex. |
|
260 |
srcIndex := srcIndex + bytesPerRow. |
|
261 |
dstIndex := dstIndex - bytesPerRow. |
|
0 | 262 |
]. |
263 |
data4 := tmp. |
|
264 |
||
265 |
"expand into bytes" |
|
266 |
||
267 |
data := ByteArray new:(width * height). |
|
268 |
data4 expandPixels:inDepth width:width height:height |
|
28 | 269 |
into:data mapping:nil. |
0 | 270 |
|
271 |
photometric := #palette. |
|
272 |
samplesPerPixel := 1. |
|
273 |
bitsPerSample := #(8). |
|
36 | 274 |
colorMap := Colormap redVector:rMap greenVector:gMap blueVector:bMap. |
0 | 275 |
|
276 |
" |
|
21 | 277 |
WindowsIconReader new fromWindowsICOFile:'/phys/clam2//LocalLibrary/Images/WIN_icons/ibm.ico'. |
0 | 278 |
" |
279 |
! |
|
280 |
||
41 | 281 |
fromWindowsBMPStream:aStream |
21 | 282 |
| fileSize header inDepth inPlanes compression |
283 |
imgSize resH resV numColor numImportantColor |
|
284 |
dataStart |
|
103 | 285 |
rawMap rMap gMap bMap srcIndex dstIndex inBytesPerRow |
21 | 286 |
data4 mask tmp bytesPerRow fourBytesPerColorInfo| |
287 |
||
41 | 288 |
inStream := aStream. |
289 |
aStream binary. |
|
290 |
||
291 |
fileSize := aStream size. |
|
21 | 292 |
"read the header" |
293 |
||
294 |
header := ByteArray uninitializedNew:16r54. |
|
41 | 295 |
aStream nextBytes:18 into:header. |
21 | 296 |
|
297 |
((header at:(16r0E + 1)) == 40) ifTrue:[ "header-size" |
|
28 | 298 |
" |
299 |
its an Windows3.x BMP file |
|
300 |
or OS/2 vsn 2 BMP file |
|
301 |
" |
|
302 |
'BMP: Win3.x or OS/2 vsn 2 format' errorPrintNL. |
|
21 | 303 |
|
41 | 304 |
aStream nextBytes:(40-4) into:header startingAt:19. |
21 | 305 |
|
83 | 306 |
width := header wordAt:(16r12 + 1) MSB:false. "(header at:19) + ((header at:20) * 256). " |
307 |
height := header wordAt:(16r16 + 1) MSB:false. "(header at:23) + ((header at:24) * 256). " |
|
308 |
inPlanes := header wordAt:(16r1A + 1) MSB:false. |
|
309 |
inDepth := header wordAt:(16r1C + 1) MSB:false. |
|
310 |
compression := header wordAt:(16r1E + 1) MSB:false. |
|
311 |
imgSize := header doubleWordAt:(16r22 + 1) MSB:false. |
|
312 |
resH := header doubleWordAt:(16r26 + 1) MSB:false. |
|
313 |
resV := header doubleWordAt:(16r2A + 1) MSB:false. |
|
314 |
numColor := header doubleWordAt:(16r2E + 1) MSB:false. |
|
315 |
numImportantColor := header doubleWordAt:(16r32 + 1) MSB:false. |
|
21 | 316 |
|
28 | 317 |
numColor == 0 ifTrue:[ |
318 |
" |
|
319 |
some bmp-writers seem to leave this as zero (which is wrong) |
|
320 |
" |
|
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
321 |
inDepth <= 8 ifTrue:[ |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
322 |
numColor := 1 bitShift:inDepth. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
323 |
'BMP: missing nColor in header - assume ' errorPrint. numColor errorPrintNL |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
324 |
] |
28 | 325 |
]. |
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
326 |
|
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
327 |
numColor ~~ 0 ifTrue:[ |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
328 |
rawMap := ByteArray uninitializedNew:(numColor * 4). |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
329 |
aStream nextBytes:(numColor * 4) into:rawMap. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
330 |
fourBytesPerColorInfo := true. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
331 |
]. |
83 | 332 |
dataStart := header wordAt:(16r0A + 1) MSB:false |
21 | 333 |
] ifFalse:[ |
28 | 334 |
((header at:(16r0E + 1)) == 12) ifTrue:[ "core-info header size" |
335 |
" |
|
336 |
its an OS/2 (vsn1.2) BMP file |
|
337 |
" |
|
338 |
'BMP: OS/2 vsn 1.2 format' errorPrintNL. |
|
41 | 339 |
aStream nextBytes:(12-4) into:header startingAt:19. |
21 | 340 |
|
83 | 341 |
width := header wordAt:(16r12 + 1) MSB:false. "(header at:19) + ((header at:20) * 256). " |
342 |
height := header wordAt:(16r14 + 1) MSB:false. "(header at:21) + ((header at:22) * 256). " |
|
343 |
inPlanes := header wordAt:(16r16 + 1) MSB:false. |
|
344 |
inDepth := header wordAt:(16r18 + 1) MSB:false. |
|
28 | 345 |
numColor := 1 bitShift:inDepth. |
346 |
rawMap := ByteArray uninitializedNew:(numColor * 3). |
|
41 | 347 |
aStream nextBytes:(numColor * 3) into:rawMap. |
28 | 348 |
fourBytesPerColorInfo := false. |
349 |
compression := 0. |
|
83 | 350 |
dataStart := header wordAt:(16r0A + 1) MSB:false |
28 | 351 |
] ifFalse:[ |
352 |
'BMP: unknown format' errorPrintNL. |
|
353 |
^ nil |
|
354 |
]. |
|
21 | 355 |
]. |
356 |
||
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
357 |
numColor ~~ 0 ifTrue:[ |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
358 |
"read the colormap" |
21 | 359 |
|
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
360 |
rMap := Array new:numColor. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
361 |
gMap := Array new:numColor. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
362 |
bMap := Array new:numColor. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
363 |
srcIndex := 1. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
364 |
1 to:numColor do:[:i | |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
365 |
bMap at:i put:(rawMap at:srcIndex). |
28 | 366 |
srcIndex := srcIndex + 1. |
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
367 |
gMap at:i put:(rawMap at:srcIndex). |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
368 |
srcIndex := srcIndex + 1. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
369 |
rMap at:i put:(rawMap at:srcIndex). |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
370 |
srcIndex := srcIndex + 1. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
371 |
fourBytesPerColorInfo ifTrue:[ |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
372 |
srcIndex := srcIndex + 1. |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
373 |
] |
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
374 |
]. |
21 | 375 |
]. |
376 |
||
161
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
377 |
"/ check for valid compression |
102 | 378 |
|
21 | 379 |
compression ~~ 0 ifTrue:[ |
102 | 380 |
"/ some compression |
381 |
compression == 1 ifTrue:[ |
|
382 |
"/ RLE8 - must be depth-8 |
|
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
383 |
inDepth ~~ 8 ifTrue:[ |
102 | 384 |
'BMP: RLE8 compression only allowed with depth8 images' errorPrintNL. |
385 |
^ nil |
|
386 |
]. |
|
387 |
]. |
|
388 |
compression == 2 ifTrue:[ |
|
389 |
"/ RLE4 - must be depth-4 |
|
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
390 |
inDepth ~~ 4 ifTrue:[ |
102 | 391 |
'BMP: RLE4 compression only allowed with depth4 images' errorPrintNL. |
392 |
^ nil |
|
393 |
]. |
|
394 |
]. |
|
21 | 395 |
]. |
102 | 396 |
|
21 | 397 |
inPlanes ~~ 1 ifTrue:[ |
102 | 398 |
'BMP: only 1 plane images supported' errorPrintNL. |
28 | 399 |
^ nil |
21 | 400 |
]. |
401 |
||
41 | 402 |
aStream position:(dataStart + 1). |
21 | 403 |
|
161
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
404 |
inDepth == 24 ifTrue:[ |
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
405 |
bytesPerRow := width * 3 |
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
406 |
] ifFalse:[ |
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
407 |
bytesPerRow := width |
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
408 |
]. |
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
409 |
data := ByteArray uninitializedNew:(height * bytesPerRow). |
161
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
410 |
|
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
411 |
"/ read & possibly decompress |
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
412 |
|
103 | 413 |
(self loadBMPWidth:width height:height depth:inDepth compression:compression from:aStream into:data) ifFalse:[ |
414 |
^ nil |
|
21 | 415 |
]. |
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
416 |
|
161
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
417 |
inDepth == 24 ifTrue:[ |
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
418 |
photometric := #rgb. |
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
419 |
samplesPerPixel := 3. |
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
420 |
bitsPerSample := #(8 8 8). |
c47f1fd6cf5b
oops - last change broke other depth's
Claus Gittinger <cg@exept.de>
parents:
160
diff
changeset
|
421 |
^ self |
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
422 |
]. |
21 | 423 |
|
424 |
photometric := #palette. |
|
425 |
samplesPerPixel := 1. |
|
426 |
bitsPerSample := #(8). |
|
36 | 427 |
colorMap := Colormap redVector:rMap greenVector:gMap blueVector:bMap. |
103 | 428 |
|
429 |
"Modified: 17.9.1995 / 18:48:46 / claus" |
|
160
ee4d64b12c94
handle depth 24 rgb BMP files
Claus Gittinger <cg@exept.de>
parents:
114
diff
changeset
|
430 |
"Modified: 4.2.1996 / 17:57:50 / cg" |
21 | 431 |
! |
432 |
||
41 | 433 |
fromStream:aStream |
21 | 434 |
| fileSize header | |
0 | 435 |
|
41 | 436 |
inStream := aStream. |
0 | 437 |
|
41 | 438 |
aStream binary. |
439 |
fileSize := aStream size. |
|
0 | 440 |
|
21 | 441 |
fileSize < 16 ifTrue:[ |
41 | 442 |
'WINREADER: short file' errorPrintNL. |
28 | 443 |
^ nil |
21 | 444 |
]. |
445 |
||
446 |
header := ByteArray uninitializedNew:4. |
|
41 | 447 |
aStream nextBytes:4 into:header. |
21 | 448 |
|
449 |
(header startsWith:#(66 77)) ifTrue:[ "BM" |
|
41 | 450 |
aStream position:1. |
28 | 451 |
'WINREADER: Win3.x or OS/2 vsn 2 BM format' errorPrintNL. |
41 | 452 |
^ self fromWindowsBMPStream:aStream |
21 | 453 |
]. |
454 |
(header startsWith:#(66 65)) ifTrue:[ "BA" |
|
41 | 455 |
aStream position:1. |
28 | 456 |
'WINREADER: OS/2 vsn 2 BA format' errorPrintNL. |
41 | 457 |
^ self fromOS2Stream:aStream |
21 | 458 |
]. |
459 |
(header startsWith:#(73 67)) ifTrue:[ "IC" |
|
41 | 460 |
aStream position:1. |
28 | 461 |
'WINREADER: OS/2 IC format' errorPrintNL. |
41 | 462 |
^ self fromOS2Stream:aStream |
21 | 463 |
]. |
464 |
(header startsWith:#(80 84)) ifTrue:[ "PT" |
|
41 | 465 |
aStream position:1. |
28 | 466 |
'WINREADER: OS/2 PT format' errorPrintNL. |
41 | 467 |
^ self fromOS2Stream:aStream |
21 | 468 |
]. |
103 | 469 |
(header startsWith:#(16r53 16r5A)) ifTrue:[ "SZ" |
470 |
'WINREADER: SZ format not supported:' errorPrintNL. |
|
471 |
^ nil. |
|
472 |
aStream position:1. |
|
473 |
'WINREADER: OS/2 PT format' errorPrintNL. |
|
474 |
^ self fromOS2Stream:aStream |
|
475 |
]. |
|
21 | 476 |
(header startsWith:#(0 0 1 0)) ifTrue:[ |
41 | 477 |
aStream position:1. |
28 | 478 |
'WINREADER: Win3.x ICO format' errorPrintNL. |
41 | 479 |
^ self fromWindowsICOStream:aStream |
21 | 480 |
]. |
103 | 481 |
'WINREADER: format not supported:' errorPrint. |
482 |
((header at:1) printStringRadix:16) errorPrint. |
|
483 |
' ' errorPrint. |
|
484 |
((header at:2) printStringRadix:16) errorPrintNL. |
|
21 | 485 |
^ nil |
486 |
||
487 |
" |
|
488 |
Image fromFile:'/phys/clam//LocalLibrary/Images/OS2_icons/dos.ico' |
|
489 |
" |
|
103 | 490 |
|
491 |
"Modified: 17.9.1995 / 18:59:07 / claus" |
|
21 | 492 |
! |
493 |
||
41 | 494 |
fromOS2Stream:aStream |
21 | 495 |
| header inDepth |
103 | 496 |
rawMap rMap gMap bMap srcIndex dstIndex inBytesPerRow |
21 | 497 |
data4 mask tmp bytesPerRow nColors nByte| |
498 |
||
41 | 499 |
inStream := aStream. |
500 |
aStream binary. |
|
21 | 501 |
|
0 | 502 |
"read the header" |
503 |
||
3 | 504 |
header := ByteArray uninitializedNew:8r110. |
41 | 505 |
aStream nextBytes:16 into:header. |
21 | 506 |
|
0 | 507 |
(header startsWith:#(73 67)) ifTrue:[ |
28 | 508 |
"IC format" |
41 | 509 |
aStream nextBytes:10 into:header startingAt:17. |
28 | 510 |
width := header at:7. |
511 |
height := header at:9. |
|
512 |
inDepth := 2 "header at:11". "where is it" |
|
0 | 513 |
] ifFalse:[ |
41 | 514 |
aStream nextBytes:(8r110-16) into:header startingAt:17. |
28 | 515 |
width := header at:8r101. |
516 |
height := header at:8r103. |
|
517 |
inDepth := header at:8r107. |
|
0 | 518 |
]. |
519 |
||
520 |
"read the colormap" |
|
521 |
||
522 |
nColors := 1 bitShift:inDepth. |
|
523 |
||
3 | 524 |
rawMap := ByteArray uninitializedNew:(nColors*3). |
41 | 525 |
aStream nextBytes:(nColors*3) into:rawMap. |
0 | 526 |
rMap := Array new:nColors. |
527 |
gMap := Array new:nColors. |
|
528 |
bMap := Array new:nColors. |
|
529 |
srcIndex := 1. |
|
530 |
1 to:nColors do:[:i | |
|
28 | 531 |
bMap at:i put:(rawMap at:srcIndex). |
532 |
srcIndex := srcIndex + 1. |
|
533 |
gMap at:i put:(rawMap at:srcIndex). |
|
534 |
srcIndex := srcIndex + 1. |
|
535 |
rMap at:i put:(rawMap at:srcIndex). |
|
536 |
srcIndex := srcIndex + 1. |
|
0 | 537 |
]. |
538 |
||
539 |
"read mask" |
|
540 |
||
3 | 541 |
nByte := width * height + 7 // 8. |
542 |
mask := ByteArray uninitializedNew:nByte. |
|
41 | 543 |
aStream nextBytes:nByte into:mask. |
0 | 544 |
|
545 |
"what is this" |
|
546 |
||
41 | 547 |
aStream nextBytes:nByte into:mask. |
0 | 548 |
|
103 | 549 |
"/ "read the data bits" |
550 |
"/ |
|
551 |
"/ bytesPerRow := width * inDepth + 7 // 8. |
|
552 |
"/ data4 := ByteArray uninitializedNew:(height * bytesPerRow). |
|
553 |
"/ inDepth == 8 ifTrue:[ |
|
554 |
"/ ]. |
|
555 |
"/ aStream nextBytes:(height * bytesPerRow) into:data4. |
|
556 |
"/ |
|
557 |
"/ "stupid: last row first" |
|
558 |
"/ |
|
559 |
"/ tmp := ByteArray new:(height * bytesPerRow). |
|
560 |
"/ srcIndex := 1. |
|
561 |
"/ dstIndex := (height - 1) * bytesPerRow + 1. |
|
562 |
"/ 1 to:height do:[:row | |
|
563 |
"/ tmp replaceFrom:dstIndex to:(dstIndex + bytesPerRow - 1) |
|
564 |
"/ with:data4 startingAt:srcIndex. |
|
565 |
"/ srcIndex := srcIndex + bytesPerRow. |
|
566 |
"/ dstIndex := dstIndex - bytesPerRow. |
|
567 |
"/ ]. |
|
568 |
"/ data4 := tmp. |
|
569 |
"/ |
|
570 |
"/ "expand into bytes" |
|
571 |
"/ |
|
572 |
"/ data := ByteArray new:(width * height). |
|
573 |
"/ data4 expandPixels:inDepth width:width height:height |
|
574 |
"/ into:data mapping:nil. |
|
575 |
"/ |
|
0 | 576 |
|
3 | 577 |
bytesPerRow := width * inDepth + 7 // 8. |
103 | 578 |
"/ bmp data is always 32bit aligned; if required, |
579 |
inBytesPerRow := ((bytesPerRow + 3) // 4) * 4. |
|
0 | 580 |
|
103 | 581 |
data := ByteArray uninitializedNew:(height * width "bytesPerRow"). |
582 |
(self loadBMPWidth:width height:height depth:inDepth compression:0 from:aStream into:data) ifFalse:[ |
|
583 |
^ nil |
|
0 | 584 |
]. |
585 |
photometric := #palette. |
|
586 |
samplesPerPixel := 1. |
|
587 |
bitsPerSample := #(8). |
|
36 | 588 |
colorMap := Colormap redVector:rMap greenVector:gMap blueVector:bMap. |
0 | 589 |
|
590 |
" |
|
591 |
|i f| |
|
592 |
i := Image fromFile:'/LocalLibrary/Images/OS2/dos3.ico'. |
|
593 |
f := i asFormOn:Display. |
|
18 | 594 |
v displayOpaqueForm:(f magnifyBy:2@2) x:5 y:5 |
0 | 595 |
" |
103 | 596 |
|
597 |
"Modified: 17.9.1995 / 18:49:24 / claus" |
|
0 | 598 |
! ! |