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