169 XPMReader isValidImageFile:'../../goodies/bitmaps/xpmBitmaps/device_images/ljet.xpm' |
169 XPMReader isValidImageFile:'../../goodies/bitmaps/xpmBitmaps/device_images/ljet.xpm' |
170 XPMReader isValidImageFile:'bitmaps/gifImages/garfield.gif' |
170 XPMReader isValidImageFile:'bitmaps/gifImages/garfield.gif' |
171 " |
171 " |
172 |
172 |
173 "Modified: 24.4.1997 / 20:29:40 / cg" |
173 "Modified: 24.4.1997 / 20:29:40 / cg" |
|
174 ! ! |
|
175 |
|
176 !XPMReader methodsFor:'private-reading'! |
|
177 |
|
178 colorNameFrom:aStream |
|
179 "read either a color-name or value specified in X-notation |
|
180 (#rrggbb where rr, gg and bb are 2-digit hex numbers)" |
|
181 |
|
182 |s| |
|
183 |
|
184 aStream peek == $# ifTrue:[ |
|
185 aStream next. |
|
186 s := '#'. |
|
187 ] ifFalse:[ |
|
188 s := ''. |
|
189 ]. |
|
190 [aStream peek isLetterOrDigit] whileTrue:[ |
|
191 s := s copyWith:aStream next |
|
192 ]. |
|
193 ^ s |
|
194 ! |
|
195 |
|
196 readColorMap:colorMapSize |
|
197 |redMap greenMap blueMap s key lineDone state |
|
198 symbolicName monoName greyName grey4Name colorName| |
|
199 |
|
200 redMap := ByteArray new:colorMapSize. |
|
201 greenMap := ByteArray new:colorMapSize. |
|
202 blueMap := ByteArray new:colorMapSize. |
|
203 |
|
204 1 to:colorMapSize do:[:colorIndex | |
|
205 |index line color t word| |
|
206 |
|
207 line := inStream nextLine. |
|
208 [line notNil and:[line startsWith:'/*']] whileTrue:[ |
|
209 [line notNil and:[(line endsWith:'*/') not]] whileTrue:[ |
|
210 line := inStream nextLine. |
|
211 ]. |
|
212 line := inStream nextLine. |
|
213 ]. |
|
214 line notNil ifTrue:[ |
|
215 line := line withoutSeparators |
|
216 ]. |
|
217 (line notNil and:[line startsWith:'"']) ifFalse:[ |
|
218 ^ self fileFormatError:'format error (expected color spec)'. |
|
219 ]. |
|
220 |
|
221 s := ReadStream on:line. |
|
222 s next. "skip quote" |
|
223 charsPerPixel ~~ 1 ifTrue:[ |
|
224 key := s next:charsPerPixel. |
|
225 characterTranslation at:key put:colorIndex - 1. |
|
226 ] ifFalse:[ |
|
227 index := s next asciiValue. |
|
228 characterTranslation at:index put:colorIndex - 1. |
|
229 ]. |
|
230 |
|
231 lineDone := false. |
|
232 state := nil. |
|
233 |
|
234 [lineDone] whileFalse:[ |
|
235 s skipSeparators. |
|
236 s peek == $# ifTrue:[ |
|
237 word := self colorNameFrom:s |
|
238 ] ifFalse:[ |
|
239 word := s nextAlphaNumericWord. |
|
240 ]. |
|
241 word isNil ifTrue:[ |
|
242 lineDone := true |
|
243 ] ifFalse:[ |
|
244 word = 's' ifTrue:[ |
|
245 "/ symbolic name ... |
|
246 state := $s. symbolicName := ''. |
|
247 ] ifFalse:[ |
|
248 word = 'm' ifTrue:[ |
|
249 "/ monochrome data |
|
250 state := $m. monoName := ''. |
|
251 ] ifFalse:[ |
|
252 word = 'g' ifTrue:[ |
|
253 "/ grey data |
|
254 state := $g. greyName := ''. |
|
255 ] ifFalse:[ |
|
256 word = 'g4' ifTrue:[ |
|
257 "/ grey data |
|
258 state := $G. grey4Name := ''. |
|
259 ] ifFalse:[ |
|
260 word = 'c' ifTrue:[ |
|
261 "/ color data |
|
262 state := $c. colorName := ''. |
|
263 ] ifFalse:[ |
|
264 "/ append to name |
|
265 state isNil ifTrue:[ |
|
266 ^ self fileFormatError:('format error got: ' |
|
267 , word printString |
|
268 , ' (expected ''c'',''m'',''g'' or ''s'')'). |
|
269 ]. |
|
270 |
|
271 state == $m ifTrue:[ |
|
272 monoName := monoName , ' ' , word. |
|
273 ]. |
|
274 state == $g ifTrue:[ |
|
275 greyName := greyName , ' ' , word. |
|
276 ]. |
|
277 state == $G ifTrue:[ |
|
278 grey4Name := grey4Name , ' ' , word. |
|
279 ]. |
|
280 state == $c ifTrue:[ |
|
281 colorName := colorName , ' ' , word. |
|
282 ]. |
|
283 state == $s ifTrue:[ |
|
284 symbolicName := symbolicName , ' ' , word. |
|
285 ]. |
|
286 (word startsWith:'#') ifTrue:[ |
|
287 state := nil. |
|
288 ] |
|
289 ] |
|
290 ] |
|
291 ] |
|
292 ] |
|
293 ] |
|
294 ]. |
|
295 ]. |
|
296 |
|
297 colorName notNil ifTrue:[ |
|
298 colorName := colorName withoutSeparators |
|
299 ]. |
|
300 monoName notNil ifTrue:[ |
|
301 monoName := monoName withoutSeparators |
|
302 ]. |
|
303 greyName notNil ifTrue:[ |
|
304 greyName := greyName withoutSeparators |
|
305 ]. |
|
306 grey4Name notNil ifTrue:[ |
|
307 grey4Name := grey4Name withoutSeparators |
|
308 ]. |
|
309 symbolicName notNil ifTrue:[ |
|
310 symbolicName := symbolicName withoutSeparators |
|
311 ]. |
|
312 |
|
313 "/ |
|
314 "/ for now - ignore everything, except |
|
315 "/ colorName (if there is one) |
|
316 "/ |
|
317 colorName isNil ifTrue:[ |
|
318 colorName := greyName. |
|
319 colorName isNil ifTrue:[ |
|
320 colorName := monoName. |
|
321 ] |
|
322 ]. |
|
323 |
|
324 (colorName sameAs: 'none') ifTrue:[ |
|
325 color := Color noColor. "/ white |
|
326 redMap at:colorIndex put:0. |
|
327 greenMap at:colorIndex put:0. |
|
328 blueMap at:colorIndex put:0. |
|
329 maskPixelValue := colorIndex-1. |
|
330 ] ifFalse:[ |
|
331 color := Color name:colorName ifIllegal:(Color black). |
|
332 redMap at:colorIndex put:(color red asFloat * 255.0 // 100). |
|
333 greenMap at:colorIndex put:(color green asFloat * 255.0 // 100). |
|
334 blueMap at:colorIndex put:(color blue asFloat * 255.0 // 100). |
|
335 ]. |
|
336 ]. |
|
337 |
|
338 colorMap := MappedPalette redVector:redMap greenVector:greenMap blueVector:blueMap. |
|
339 ! ! |
|
340 |
|
341 !XPMReader methodsFor:'private-writing'! |
|
342 |
|
343 colorNameOf:aColor |
|
344 "generate a name for a color. If its a standard color, |
|
345 return its name; otherwise return the hex representation." |
|
346 |
|
347 #(white black red green blue |
|
348 yellow magenta cyan orange) do:[:aStandardColorName | |
|
349 aColor = (Color name:aStandardColorName) ifTrue:[ |
|
350 ^ aStandardColorName. |
|
351 ] |
|
352 ]. |
|
353 ^ '#' |
|
354 , (aColor redByte hexPrintString:2) |
|
355 , (aColor greenByte hexPrintString:2) |
|
356 , (aColor blueByte hexPrintString:2) |
|
357 |
|
358 "Created: / 27.2.1997 / 11:48:40 / cg" |
|
359 "Modified: / 6.6.1998 / 20:58:49 / cg" |
174 ! ! |
360 ! ! |
175 |
361 |
176 !XPMReader methodsFor:'reading'! |
362 !XPMReader methodsFor:'reading'! |
177 |
363 |
178 readImage |
364 readImage |
332 "Modified: / 24.9.1995 / 07:07:33 / claus" |
518 "Modified: / 24.9.1995 / 07:07:33 / claus" |
333 "Modified: / 5.7.1996 / 17:27:59 / stefan" |
519 "Modified: / 5.7.1996 / 17:27:59 / stefan" |
334 "Modified: / 27.7.1998 / 20:01:56 / cg" |
520 "Modified: / 27.7.1998 / 20:01:56 / cg" |
335 ! ! |
521 ! ! |
336 |
522 |
337 !XPMReader methodsFor:'reading-private'! |
|
338 |
|
339 colorNameFrom:aStream |
|
340 "read either a color-name or value specified in X-notation |
|
341 (#rrggbb where rr, gg and bb are 2-digit hex numbers)" |
|
342 |
|
343 |s| |
|
344 |
|
345 aStream peek == $# ifTrue:[ |
|
346 aStream next. |
|
347 s := '#'. |
|
348 ] ifFalse:[ |
|
349 s := ''. |
|
350 ]. |
|
351 [aStream peek isLetterOrDigit] whileTrue:[ |
|
352 s := s copyWith:aStream next |
|
353 ]. |
|
354 ^ s |
|
355 ! |
|
356 |
|
357 readColorMap:colorMapSize |
|
358 |redMap greenMap blueMap s key lineDone state |
|
359 symbolicName monoName greyName grey4Name colorName| |
|
360 |
|
361 redMap := ByteArray new:colorMapSize. |
|
362 greenMap := ByteArray new:colorMapSize. |
|
363 blueMap := ByteArray new:colorMapSize. |
|
364 |
|
365 1 to:colorMapSize do:[:colorIndex | |
|
366 |index line color t word| |
|
367 |
|
368 line := inStream nextLine. |
|
369 [line notNil and:[line startsWith:'/*']] whileTrue:[ |
|
370 [line notNil and:[(line endsWith:'*/') not]] whileTrue:[ |
|
371 line := inStream nextLine. |
|
372 ]. |
|
373 line := inStream nextLine. |
|
374 ]. |
|
375 line notNil ifTrue:[ |
|
376 line := line withoutSeparators |
|
377 ]. |
|
378 (line notNil and:[line startsWith:'"']) ifFalse:[ |
|
379 ^ self fileFormatError:'format error (expected color spec)'. |
|
380 ]. |
|
381 |
|
382 s := ReadStream on:line. |
|
383 s next. "skip quote" |
|
384 charsPerPixel ~~ 1 ifTrue:[ |
|
385 key := s next:charsPerPixel. |
|
386 characterTranslation at:key put:colorIndex - 1. |
|
387 ] ifFalse:[ |
|
388 index := s next asciiValue. |
|
389 characterTranslation at:index put:colorIndex - 1. |
|
390 ]. |
|
391 |
|
392 lineDone := false. |
|
393 state := nil. |
|
394 |
|
395 [lineDone] whileFalse:[ |
|
396 s skipSeparators. |
|
397 s peek == $# ifTrue:[ |
|
398 word := self colorNameFrom:s |
|
399 ] ifFalse:[ |
|
400 word := s nextAlphaNumericWord. |
|
401 ]. |
|
402 word isNil ifTrue:[ |
|
403 lineDone := true |
|
404 ] ifFalse:[ |
|
405 word = 's' ifTrue:[ |
|
406 "/ symbolic name ... |
|
407 state := $s. symbolicName := ''. |
|
408 ] ifFalse:[ |
|
409 word = 'm' ifTrue:[ |
|
410 "/ monochrome data |
|
411 state := $m. monoName := ''. |
|
412 ] ifFalse:[ |
|
413 word = 'g' ifTrue:[ |
|
414 "/ grey data |
|
415 state := $g. greyName := ''. |
|
416 ] ifFalse:[ |
|
417 word = 'g4' ifTrue:[ |
|
418 "/ grey data |
|
419 state := $G. grey4Name := ''. |
|
420 ] ifFalse:[ |
|
421 word = 'c' ifTrue:[ |
|
422 "/ color data |
|
423 state := $c. colorName := ''. |
|
424 ] ifFalse:[ |
|
425 "/ append to name |
|
426 state isNil ifTrue:[ |
|
427 ^ self fileFormatError:('format error got: ' |
|
428 , word printString |
|
429 , ' (expected ''c'',''m'',''g'' or ''s'')'). |
|
430 ]. |
|
431 |
|
432 state == $m ifTrue:[ |
|
433 monoName := monoName , ' ' , word. |
|
434 ]. |
|
435 state == $g ifTrue:[ |
|
436 greyName := greyName , ' ' , word. |
|
437 ]. |
|
438 state == $G ifTrue:[ |
|
439 grey4Name := grey4Name , ' ' , word. |
|
440 ]. |
|
441 state == $c ifTrue:[ |
|
442 colorName := colorName , ' ' , word. |
|
443 ]. |
|
444 state == $s ifTrue:[ |
|
445 symbolicName := symbolicName , ' ' , word. |
|
446 ]. |
|
447 (word startsWith:'#') ifTrue:[ |
|
448 state := nil. |
|
449 ] |
|
450 ] |
|
451 ] |
|
452 ] |
|
453 ] |
|
454 ] |
|
455 ]. |
|
456 ]. |
|
457 |
|
458 colorName notNil ifTrue:[ |
|
459 colorName := colorName withoutSeparators |
|
460 ]. |
|
461 monoName notNil ifTrue:[ |
|
462 monoName := monoName withoutSeparators |
|
463 ]. |
|
464 greyName notNil ifTrue:[ |
|
465 greyName := greyName withoutSeparators |
|
466 ]. |
|
467 grey4Name notNil ifTrue:[ |
|
468 grey4Name := grey4Name withoutSeparators |
|
469 ]. |
|
470 symbolicName notNil ifTrue:[ |
|
471 symbolicName := symbolicName withoutSeparators |
|
472 ]. |
|
473 |
|
474 "/ |
|
475 "/ for now - ignore everything, except |
|
476 "/ colorName (if there is one) |
|
477 "/ |
|
478 colorName isNil ifTrue:[ |
|
479 colorName := greyName. |
|
480 colorName isNil ifTrue:[ |
|
481 colorName := monoName. |
|
482 ] |
|
483 ]. |
|
484 |
|
485 (colorName sameAs: 'none') ifTrue:[ |
|
486 color := Color noColor. "/ white |
|
487 redMap at:colorIndex put:0. |
|
488 greenMap at:colorIndex put:0. |
|
489 blueMap at:colorIndex put:0. |
|
490 maskPixelValue := colorIndex-1. |
|
491 ] ifFalse:[ |
|
492 color := Color name:colorName ifIllegal:(Color black). |
|
493 redMap at:colorIndex put:(color red asFloat * 255.0 // 100). |
|
494 greenMap at:colorIndex put:(color green asFloat * 255.0 // 100). |
|
495 blueMap at:colorIndex put:(color blue asFloat * 255.0 // 100). |
|
496 ]. |
|
497 ]. |
|
498 |
|
499 colorMap := MappedPalette redVector:redMap greenVector:greenMap blueVector:blueMap. |
|
500 ! ! |
|
501 |
|
502 !XPMReader methodsFor:'writing'! |
523 !XPMReader methodsFor:'writing'! |
503 |
524 |
504 save:image onFile:aFileName |
525 save:image onFile:aFileName |
505 "save image as XPM file on aFileName. |
526 "save image as XPM file on aFileName. |
506 Caveat: currently, only a maximum of roughly 50 colors is handled |
527 Caveat: currently, only a maximum of roughly 50 colors is handled |
598 outStream nextPutLine:'};'. |
619 outStream nextPutLine:'};'. |
599 |
620 |
600 "Modified: / 28.7.1998 / 21:52:13 / cg" |
621 "Modified: / 28.7.1998 / 21:52:13 / cg" |
601 ! ! |
622 ! ! |
602 |
623 |
603 !XPMReader methodsFor:'writing-private'! |
|
604 |
|
605 colorNameOf:aColor |
|
606 "generate a name for a color. If its a standard color, |
|
607 return its name; otherwise return the hex representation." |
|
608 |
|
609 #(white black red green blue |
|
610 yellow magenta cyan orange) do:[:aStandardColorName | |
|
611 aColor = (Color name:aStandardColorName) ifTrue:[ |
|
612 ^ aStandardColorName. |
|
613 ] |
|
614 ]. |
|
615 ^ '#' |
|
616 , (aColor redByte hexPrintString:2) |
|
617 , (aColor greenByte hexPrintString:2) |
|
618 , (aColor blueByte hexPrintString:2) |
|
619 |
|
620 "Created: / 27.2.1997 / 11:48:40 / cg" |
|
621 "Modified: / 6.6.1998 / 20:58:49 / cg" |
|
622 ! ! |
|
623 |
|
624 !XPMReader class methodsFor:'documentation'! |
624 !XPMReader class methodsFor:'documentation'! |
625 |
625 |
626 version |
626 version |
627 ^ '$Header: /cvs/stx/stx/libview2/XPMReader.st,v 1.57 2003-11-19 15:24:31 cg Exp $' |
627 ^ '$Header: /cvs/stx/stx/libview2/XPMReader.st,v 1.58 2003-11-19 15:38:24 cg Exp $' |
628 ! ! |
628 ! ! |
629 |
629 |
630 XPMReader initialize! |
630 XPMReader initialize! |