58 initialize |
58 initialize |
59 Image fileFormats at:'.bmp' put:self. |
59 Image fileFormats at:'.bmp' put:self. |
60 Image fileFormats at:'.ico' put:self. |
60 Image fileFormats at:'.ico' put:self. |
61 ! ! |
61 ! ! |
62 |
62 |
63 !WindowsIconReader methodsFor:'reading from file'! |
63 !WindowsIconReader class methodsFor:'reading from file'! |
64 |
64 |
65 fromOS2File: aFilename |
65 fromOS2File: aFilename |
66 inStream := self class streamReadingFile:aFilename. |
66 |reader stream| |
67 inStream isNil ifTrue:[^ nil]. |
67 |
68 inStream binary. |
68 stream := self streamReadingFile:aFilename. |
69 ^ self fromOS2Stream. |
69 stream isNil ifTrue:[^ nil]. |
|
70 reader := (self new) fromOS2Stream:aStream. |
|
71 stream close. |
|
72 reader notNil ifTrue:[^ reader image]. |
|
73 ^ nil |
70 ! |
74 ! |
71 |
75 |
72 fromWindowsBMPFile: aFilename |
76 fromWindowsBMPFile: aFilename |
73 inStream := self class streamReadingFile:aFilename. |
77 |reader stream| |
74 inStream isNil ifTrue:[^ nil]. |
78 |
75 inStream binary. |
79 stream := self class streamReadingFile:aFilename. |
76 ^ self fromWindowsBMPStream. |
80 stream isNil ifTrue:[^ nil]. |
|
81 reader := (self new) fromWindowsBMPStream:aStream. |
|
82 stream close. |
|
83 reader notNil ifTrue:[^ reader image]. |
|
84 ^ nil |
77 ! |
85 ! |
78 |
86 |
79 fromWindowsICOFile: aFilename |
87 fromWindowsICOFile: aFilename |
80 inStream := self class streamReadingFile:aFilename. |
88 |reader stream| |
81 inStream isNil ifTrue:[^ nil]. |
89 |
82 ^ self fromWindowsICOStream. |
90 stream := self class streamReadingFile:aFilename. |
|
91 stream isNil ifTrue:[^ nil]. |
|
92 reader := (self new) fromWindowsICOStream:aStream. |
|
93 stream close. |
|
94 reader notNil ifTrue:[^ reader image]. |
|
95 ^ nil |
83 |
96 |
84 " |
97 " |
85 Image fromFile:'/phys/clam2//LocalLibrary/Images/WIN_icons/ibm.ico'. |
98 Image fromFile:'/phys/clam2//LocalLibrary/Images/WIN_icons/ibm.ico'. |
86 " |
99 " |
87 ! |
100 ! |
88 |
101 |
89 fromWindowsICOStream |
102 fromWindowsICOStream:aStream |
90 | header inDepth |
103 | header inDepth |
91 rawMap rMap gMap bMap srcIndex dstIndex |
104 rawMap rMap gMap bMap srcIndex dstIndex |
92 data4 mask tmp bytesPerRow nColor| |
105 data4 mask tmp bytesPerRow nColor| |
93 |
106 |
94 inStream binary. |
107 inStream := aStream. |
|
108 aStream binary. |
95 |
109 |
96 "read the header" |
110 "read the header" |
97 |
111 |
98 header := ByteArray uninitializedNew:(6 + 16 + 40). |
112 header := ByteArray uninitializedNew:(6 + 16 + 40). |
99 inStream nextBytes:(6 + 16 + 40) into:header. |
113 aStream nextBytes:(6 + 16 + 40) into:header. |
100 width := header at:(6+1). |
114 width := header at:(6+1). |
101 height := header at:(7+1). |
115 height := header at:(7+1). |
102 nColor := header at:(8+1). |
116 nColor := header at:(8+1). |
103 "10, 11, 12, 13, 14 ? (reserve)" |
117 "10, 11, 12, 13, 14 ? (reserve)" |
104 "15, 16, 17, 18 pixel array size" |
118 "15, 16, 17, 18 pixel array size" |
158 into:data mapping:nil. |
172 into:data mapping:nil. |
159 |
173 |
160 photometric := #palette. |
174 photometric := #palette. |
161 samplesPerPixel := 1. |
175 samplesPerPixel := 1. |
162 bitsPerSample := #(8). |
176 bitsPerSample := #(8). |
163 "/ colorMap := Array with:rMap with:gMap with:bMap. |
|
164 colorMap := Colormap redVector:rMap greenVector:gMap blueVector:bMap. |
177 colorMap := Colormap redVector:rMap greenVector:gMap blueVector:bMap. |
165 inStream close. |
|
166 |
178 |
167 " |
179 " |
168 WindowsIconReader new fromWindowsICOFile:'/phys/clam2//LocalLibrary/Images/WIN_icons/ibm.ico'. |
180 WindowsIconReader new fromWindowsICOFile:'/phys/clam2//LocalLibrary/Images/WIN_icons/ibm.ico'. |
169 " |
181 " |
170 ! |
182 ! |
171 |
183 |
172 fromWindowsBMPStream |
184 fromWindowsBMPStream:aStream |
173 | fileSize header inDepth inPlanes compression |
185 | fileSize header inDepth inPlanes compression |
174 imgSize resH resV numColor numImportantColor |
186 imgSize resH resV numColor numImportantColor |
175 dataStart |
187 dataStart |
176 rawMap rMap gMap bMap srcIndex dstIndex |
188 rawMap rMap gMap bMap srcIndex dstIndex |
177 data4 mask tmp bytesPerRow fourBytesPerColorInfo| |
189 data4 mask tmp bytesPerRow fourBytesPerColorInfo| |
178 |
190 |
179 fileSize := inStream size. |
191 inStream := aStream. |
|
192 aStream binary. |
|
193 |
|
194 fileSize := aStream size. |
180 "read the header" |
195 "read the header" |
181 |
196 |
182 header := ByteArray uninitializedNew:16r54. |
197 header := ByteArray uninitializedNew:16r54. |
183 inStream nextBytes:18 into:header. |
198 aStream nextBytes:18 into:header. |
184 |
199 |
185 ((header at:(16r0E + 1)) == 40) ifTrue:[ "header-size" |
200 ((header at:(16r0E + 1)) == 40) ifTrue:[ "header-size" |
186 " |
201 " |
187 its an Windows3.x BMP file |
202 its an Windows3.x BMP file |
188 or OS/2 vsn 2 BMP file |
203 or OS/2 vsn 2 BMP file |
189 " |
204 " |
190 'BMP: Win3.x or OS/2 vsn 2 format' errorPrintNL. |
205 'BMP: Win3.x or OS/2 vsn 2 format' errorPrintNL. |
191 |
206 |
192 inStream nextBytes:(40-4) into:header startingAt:19. |
207 aStream nextBytes:(40-4) into:header startingAt:19. |
193 |
208 |
194 width := header wordAt:(16r12 + 1). "(header at:19) + ((header at:20) * 256). " |
209 width := header wordAt:(16r12 + 1). "(header at:19) + ((header at:20) * 256). " |
195 height := header wordAt:(16r16 + 1). "(header at:23) + ((header at:24) * 256). " |
210 height := header wordAt:(16r16 + 1). "(header at:23) + ((header at:24) * 256). " |
196 inPlanes := header wordAt:(16r1A + 1). |
211 inPlanes := header wordAt:(16r1A + 1). |
197 inDepth := header wordAt:(16r1C + 1). |
212 inDepth := header wordAt:(16r1C + 1). |
208 " |
223 " |
209 numColor := 1 bitShift:inDepth. |
224 numColor := 1 bitShift:inDepth. |
210 'BMP: missing nColor in header - assume ' errorPrint. numColor errorPrintNL |
225 'BMP: missing nColor in header - assume ' errorPrint. numColor errorPrintNL |
211 ]. |
226 ]. |
212 rawMap := ByteArray uninitializedNew:(numColor * 4). |
227 rawMap := ByteArray uninitializedNew:(numColor * 4). |
213 inStream nextBytes:(numColor * 4) into:rawMap. |
228 aStream nextBytes:(numColor * 4) into:rawMap. |
214 fourBytesPerColorInfo := true. |
229 fourBytesPerColorInfo := true. |
215 dataStart := header wordAt:(16r0A + 1) |
230 dataStart := header wordAt:(16r0A + 1) |
216 ] ifFalse:[ |
231 ] ifFalse:[ |
217 ((header at:(16r0E + 1)) == 12) ifTrue:[ "core-info header size" |
232 ((header at:(16r0E + 1)) == 12) ifTrue:[ "core-info header size" |
218 " |
233 " |
219 its an OS/2 (vsn1.2) BMP file |
234 its an OS/2 (vsn1.2) BMP file |
220 " |
235 " |
221 'BMP: OS/2 vsn 1.2 format' errorPrintNL. |
236 'BMP: OS/2 vsn 1.2 format' errorPrintNL. |
222 inStream nextBytes:(12-4) into:header startingAt:19. |
237 aStream nextBytes:(12-4) into:header startingAt:19. |
223 |
238 |
224 width := header wordAt:(16r12 + 1). "(header at:19) + ((header at:20) * 256). " |
239 width := header wordAt:(16r12 + 1). "(header at:19) + ((header at:20) * 256). " |
225 height := header wordAt:(16r14 + 1). "(header at:21) + ((header at:22) * 256). " |
240 height := header wordAt:(16r14 + 1). "(header at:21) + ((header at:22) * 256). " |
226 inPlanes := header wordAt:(16r16 + 1). |
241 inPlanes := header wordAt:(16r16 + 1). |
227 inDepth := header wordAt:(16r18 + 1). |
242 inDepth := header wordAt:(16r18 + 1). |
228 numColor := 1 bitShift:inDepth. |
243 numColor := 1 bitShift:inDepth. |
229 rawMap := ByteArray uninitializedNew:(numColor * 3). |
244 rawMap := ByteArray uninitializedNew:(numColor * 3). |
230 inStream nextBytes:(numColor * 3) into:rawMap. |
245 aStream nextBytes:(numColor * 3) into:rawMap. |
231 fourBytesPerColorInfo := false. |
246 fourBytesPerColorInfo := false. |
232 compression := 0. |
247 compression := 0. |
233 dataStart := header wordAt:(16r0A + 1) |
248 dataStart := header wordAt:(16r0A + 1) |
234 ] ifFalse:[ |
249 ] ifFalse:[ |
235 'BMP: unknown format' errorPrintNL. |
250 'BMP: unknown format' errorPrintNL. |
236 inStream close. |
|
237 ^ nil |
251 ^ nil |
238 ]. |
252 ]. |
239 ]. |
253 ]. |
240 |
254 |
241 "read the colormap" |
255 "read the colormap" |
261 supported |
275 supported |
262 " |
276 " |
263 compression ~~ 0 ifTrue:[ |
277 compression ~~ 0 ifTrue:[ |
264 'BMP compression type ' errorPrint. compression errorPrint. |
278 'BMP compression type ' errorPrint. compression errorPrint. |
265 'not supported' errorPrintNL. |
279 'not supported' errorPrintNL. |
266 inStream close. |
|
267 ^ nil |
280 ^ nil |
268 ]. |
281 ]. |
269 inPlanes ~~ 1 ifTrue:[ |
282 inPlanes ~~ 1 ifTrue:[ |
270 'BMP only 1 plane images supported' errorPrintNL. |
283 'BMP only 1 plane images supported' errorPrintNL. |
271 inStream close. |
|
272 ^ nil |
284 ^ nil |
273 ]. |
285 ]. |
274 |
286 |
275 "read the data bits" |
287 "read the data bits" |
276 |
288 |
277 bytesPerRow := width * inDepth + 7 // 8. |
289 bytesPerRow := width * inDepth + 7 // 8. |
278 data4 := ByteArray uninitializedNew:(height * bytesPerRow). |
290 data4 := ByteArray uninitializedNew:(height * bytesPerRow). |
279 |
291 |
280 inStream position:(dataStart + 1). |
292 aStream position:(dataStart + 1). |
281 inStream nextBytes:(height * bytesPerRow) into:data4. |
293 aStream nextBytes:(height * bytesPerRow) into:data4. |
282 |
294 |
283 "read mask" |
295 "read mask" |
284 |
296 |
285 " |
297 " |
286 mask := ByteArray new:(width * height / 8). |
298 mask := ByteArray new:(width * height / 8). |
287 inStream nextBytes:(width * height / 8) into:mask. |
299 aStream nextBytes:(width * height / 8) into:mask. |
288 " |
300 " |
289 |
301 |
290 "stupid: last row first" |
302 "stupid: last row first" |
291 |
303 |
292 tmp := ByteArray uninitializedNew:(height * bytesPerRow). |
304 tmp := ByteArray uninitializedNew:(height * bytesPerRow). |
307 into:data mapping:nil. |
319 into:data mapping:nil. |
308 |
320 |
309 photometric := #palette. |
321 photometric := #palette. |
310 samplesPerPixel := 1. |
322 samplesPerPixel := 1. |
311 bitsPerSample := #(8). |
323 bitsPerSample := #(8). |
312 "/ colorMap := Array with:rMap with:gMap with:bMap. |
|
313 colorMap := Colormap redVector:rMap greenVector:gMap blueVector:bMap. |
324 colorMap := Colormap redVector:rMap greenVector:gMap blueVector:bMap. |
314 inStream close. |
325 ! |
315 ! |
326 |
316 |
327 fromStream:aStream |
317 fromFile: aFilename |
|
318 | fileSize header | |
328 | fileSize header | |
319 |
329 |
320 inStream := self class streamReadingFile:aFilename. |
330 inStream := aStream. |
321 inStream isNil ifTrue:[^ nil]. |
331 |
322 |
332 aStream binary. |
323 inStream binary. |
333 fileSize := aStream size. |
324 fileSize := inStream size. |
|
325 |
334 |
326 fileSize < 16 ifTrue:[ |
335 fileSize < 16 ifTrue:[ |
327 inStream close. |
336 'WINREADER: short file' errorPrintNL. |
328 self error:'WINREADER: short file'. |
|
329 ^ nil |
337 ^ nil |
330 ]. |
338 ]. |
331 |
339 |
332 header := ByteArray uninitializedNew:4. |
340 header := ByteArray uninitializedNew:4. |
333 inStream nextBytes:4 into:header. |
341 aStream nextBytes:4 into:header. |
334 |
342 |
335 (header startsWith:#(66 77)) ifTrue:[ "BM" |
343 (header startsWith:#(66 77)) ifTrue:[ "BM" |
336 inStream position:1. |
344 aStream position:1. |
337 'WINREADER: Win3.x or OS/2 vsn 2 BM format' errorPrintNL. |
345 'WINREADER: Win3.x or OS/2 vsn 2 BM format' errorPrintNL. |
338 ^ self fromWindowsBMPStream |
346 ^ self fromWindowsBMPStream:aStream |
339 ]. |
347 ]. |
340 (header startsWith:#(66 65)) ifTrue:[ "BA" |
348 (header startsWith:#(66 65)) ifTrue:[ "BA" |
341 inStream position:1. |
349 aStream position:1. |
342 'WINREADER: OS/2 vsn 2 BA format' errorPrintNL. |
350 'WINREADER: OS/2 vsn 2 BA format' errorPrintNL. |
343 ^ self fromOS2Stream |
351 ^ self fromOS2Stream:aStream |
344 ]. |
352 ]. |
345 (header startsWith:#(73 67)) ifTrue:[ "IC" |
353 (header startsWith:#(73 67)) ifTrue:[ "IC" |
346 inStream position:1. |
354 aStream position:1. |
347 'WINREADER: OS/2 IC format' errorPrintNL. |
355 'WINREADER: OS/2 IC format' errorPrintNL. |
348 ^ self fromOS2Stream |
356 ^ self fromOS2Stream:aStream |
349 ]. |
357 ]. |
350 (header startsWith:#(80 84)) ifTrue:[ "PT" |
358 (header startsWith:#(80 84)) ifTrue:[ "PT" |
351 inStream position:1. |
359 aStream position:1. |
352 'WINREADER: OS/2 PT format' errorPrintNL. |
360 'WINREADER: OS/2 PT format' errorPrintNL. |
353 ^ self fromOS2Stream |
361 ^ self fromOS2Stream:aStream |
354 ]. |
362 ]. |
355 (header startsWith:#(0 0 1 0)) ifTrue:[ |
363 (header startsWith:#(0 0 1 0)) ifTrue:[ |
356 inStream position:1. |
364 aStream position:1. |
357 'WINREADER: Win3.x ICO format' errorPrintNL. |
365 'WINREADER: Win3.x ICO format' errorPrintNL. |
358 ^ self fromWindowsICOStream |
366 ^ self fromWindowsICOStream:aStream |
359 ]. |
367 ]. |
360 self error:'WINREADER: format not supported'. |
368 'WINREADER: format not supported' errorPrintNL. |
361 inStream close. |
|
362 ^ nil |
369 ^ nil |
363 |
370 |
364 " |
371 " |
365 Image fromFile:'/phys/clam//LocalLibrary/Images/OS2_icons/dos.ico' |
372 Image fromFile:'/phys/clam//LocalLibrary/Images/OS2_icons/dos.ico' |
366 " |
373 " |
367 ! |
374 ! |
368 |
375 |
369 fromOS2Stream |
376 fromOS2Stream:aStream |
370 | header inDepth |
377 | header inDepth |
371 rawMap rMap gMap bMap srcIndex dstIndex |
378 rawMap rMap gMap bMap srcIndex dstIndex |
372 data4 mask tmp bytesPerRow nColors nByte| |
379 data4 mask tmp bytesPerRow nColors nByte| |
373 |
380 |
374 inStream binary. |
381 inStream := aStream. |
|
382 aStream binary. |
375 |
383 |
376 "read the header" |
384 "read the header" |
377 |
385 |
378 header := ByteArray uninitializedNew:8r110. |
386 header := ByteArray uninitializedNew:8r110. |
379 inStream nextBytes:16 into:header. |
387 aStream nextBytes:16 into:header. |
380 |
388 |
381 (header startsWith:#(73 67)) ifTrue:[ |
389 (header startsWith:#(73 67)) ifTrue:[ |
382 "IC format" |
390 "IC format" |
383 inStream nextBytes:10 into:header startingAt:17. |
391 aStream nextBytes:10 into:header startingAt:17. |
384 width := header at:7. |
392 width := header at:7. |
385 height := header at:9. |
393 height := header at:9. |
386 inDepth := 2 "header at:11". "where is it" |
394 inDepth := 2 "header at:11". "where is it" |
387 ] ifFalse:[ |
395 ] ifFalse:[ |
388 inStream nextBytes:(8r110-16) into:header startingAt:17. |
396 aStream nextBytes:(8r110-16) into:header startingAt:17. |
389 width := header at:8r101. |
397 width := header at:8r101. |
390 height := header at:8r103. |
398 height := header at:8r103. |
391 inDepth := header at:8r107. |
399 inDepth := header at:8r107. |
392 ]. |
400 ]. |
393 |
401 |
394 "read the colormap" |
402 "read the colormap" |
395 |
403 |
396 nColors := 1 bitShift:inDepth. |
404 nColors := 1 bitShift:inDepth. |
397 |
405 |
398 rawMap := ByteArray uninitializedNew:(nColors*3). |
406 rawMap := ByteArray uninitializedNew:(nColors*3). |
399 inStream nextBytes:(nColors*3) into:rawMap. |
407 aStream nextBytes:(nColors*3) into:rawMap. |
400 rMap := Array new:nColors. |
408 rMap := Array new:nColors. |
401 gMap := Array new:nColors. |
409 gMap := Array new:nColors. |
402 bMap := Array new:nColors. |
410 bMap := Array new:nColors. |
403 srcIndex := 1. |
411 srcIndex := 1. |
404 1 to:nColors do:[:i | |
412 1 to:nColors do:[:i | |