XPMReader.st
changeset 1812 5c902c4135f1
parent 1805 93f557cbe600
child 1814 2f204c2a957d
equal deleted inserted replaced
1811:d3fabf23f595 1812:5c902c4135f1
    35 "
    35 "
    36 !
    36 !
    37 
    37 
    38 documentation
    38 documentation
    39 "
    39 "
    40     this class provides methods for loading x-pixmap-file (xpm) images.
    40     This class provides methods for loading x-pixmap-file (xpm) images.
    41 
    41 
    42     These images are used (in X) for palette images (see ctwm or hp-vue for a lot
    42     These images are used (in X) for palette images 
    43     of them). 
    43     (see ctwm or hp-vue for a lot of them).
       
    44     The format is actually a piece of C-code, which can be compiled by the C-compiler
       
    45     into a constant image data structure.
       
    46 
    44     The code here is a hack - it may not work for all images 
    47     The code here is a hack - it may not work for all images 
    45     (it works for the testfiles I got here).
    48     (it works for the testfiles I got here).
    46 
    49 
    47     Limitations: 
    50     Limitations: 
    48         only reads the full-color specification, ignoring monochrome
    51         only reads the full-color specification, ignoring monochrome
    51         Can only handle single-character index.
    54         Can only handle single-character index.
    52 
    55 
    53         Only understands single-word color names (i.e. names with spaces 
    56         Only understands single-word color names (i.e. names with spaces 
    54         are not supported)
    57         are not supported)
    55 
    58 
    56         Image writing is only supported for images with less than about 50
    59         Image writing is only supported for images with less than about 200
    57         colors (single byte encoding). If present, the mask must be a
    60         colors (single byte encoding). 
    58         single bit mask (i.e. no alpha channel).
    61         If present, the mask must be a single bit mask (i.e. no alpha channel).
    59         Due to the algorithm, writing may be slow for big images
    62         Due to the algorithm, writing may be slow for big images
    60 
    63 
    61     Suggestions: adapt & use the XPM library here.
    64     Suggestions: adapt & use the XPM library here.
    62 
    65 
    63 
    66 
    64     [See also:]
    67     [See also:]
    65         Image Form Icon
    68         Image Form Icon
    66         BlitImageReader FaceReader GIFReader JPEGReader PBMReader PCXReader 
    69         BlitImageReader FaceReader GIFReader JPEGReader PBMReader PCXReader 
    67         ST80FormReader SunRasterReader TargaReader TIFFReader WindowsIconReader 
    70         ST80FormReader SunRasterReader TargaReader TIFFReader WindowsIconReader 
    68         XBMReader XWDReader 
    71         XBMReader XWDReader 
       
    72 "
       
    73 !
       
    74 
       
    75 examples
       
    76 "
       
    77   Reading from a file:
       
    78                                                                         [exBegin]
       
    79     |image|
       
    80 
       
    81     image := Image fromFile:('../../goodies/bitmaps/xpmBitmaps/INFO.xpm').
       
    82     image inspect
       
    83                                                                         [exEnd]
       
    84 
       
    85 
       
    86   Saving to a file:
       
    87                                                                         [exBegin]
       
    88     |image|
       
    89 
       
    90     image := Image fromScreen:(0@0 corner:30@30).
       
    91     image usedColors size > 256 ifTrue:[
       
    92         image := image asDitheredImageUsing:(Color standardDitherColorsForDepth8) depth:8.
       
    93     ].
       
    94     XPMReader save:image onFile:'/tmp/test.xpm'.
       
    95     '/tmp/test.xpm' asFilename contents asString inspect
       
    96                                                                         [exEnd]
       
    97 
       
    98 
       
    99   Or directly into a stream:
       
   100                                                                         [exBegin]
       
   101     |image stream|
       
   102 
       
   103     image := Image fromScreen:(0@0 corner:30@30).
       
   104     image usedColors size > 256 ifTrue:[
       
   105         image := image asDitheredImageUsing:(Color standardDitherColorsForDepth8) depth:8.
       
   106     ].
       
   107     stream := WriteStream on:(String new).
       
   108     XPMReader save:image onStream:stream.
       
   109     stream contents inspect
       
   110                                                                         [exEnd]
    69 "
   111 "
    70 ! !
   112 ! !
    71 
   113 
    72 !XPMReader class methodsFor:'initialization'!
   114 !XPMReader class methodsFor:'initialization'!
    73 
   115 
   460 save:image onFile:aFileName
   502 save:image onFile:aFileName
   461     "save image as XPM file on aFileName.
   503     "save image as XPM file on aFileName.
   462      Caveat: currently, only a maximum of roughly 50 colors is handled
   504      Caveat: currently, only a maximum of roughly 50 colors is handled
   463              (i.e. very simple images)"
   505              (i.e. very simple images)"
   464 
   506 
   465     |usedColors nColorsUsed nColors nChars baseName map maskColorIndex
   507     |nColorsUsed nColors imageName imageMask stream|
       
   508 
       
   509     "sigh - check this before creating the file"
       
   510     nColors := nColorsUsed := image usedColors size.
       
   511     (imageMask := image mask) notNil ifTrue:[
       
   512         nColors := nColors + 1.
       
   513     ].
       
   514     nColors > 256 ifTrue:[
       
   515         ^ Image cannotRepresentImageSignal 
       
   516             raiseWith:image
       
   517             errorString:('XPMReader cannot represent this image (too many colors)').
       
   518     ].
       
   519 
       
   520     [
       
   521         stream := aFileName asFilename newReadWriteStream.
       
   522     ] on:FileStream openErrorSignal do:[:ex|
       
   523         ^ Image fileCreationErrorSignal 
       
   524             raiseWith:image
       
   525             errorString:('file creation error: ' , aFileName asString).
       
   526     ].
       
   527 
       
   528     imageName := aFileName asFilename baseName asFilename withoutSuffix asString.
       
   529     imageName replaceAll:$. with:$_.
       
   530 
       
   531     self save:image onStream:stream named:imageName.
       
   532 
       
   533     stream close.
       
   534 !
       
   535 
       
   536 save:image onStream:aStream
       
   537     "save image as XPM file on aStream.
       
   538      Caveat: currently, only a maximum of roughly 50 colors is handled
       
   539             (i.e. very simple images)"
       
   540 
       
   541     ^ self
       
   542         save:image 
       
   543         onStream:aStream 
       
   544         named:'unnamed'
       
   545 ! !
       
   546 
       
   547 !XPMReader methodsFor:'writing-private'!
       
   548 
       
   549 colorNameOf:aColor
       
   550     "generate a name for a color. If its a standard color,
       
   551      return its name; otherwise return the hex representation."
       
   552 
       
   553     #(white black red green blue
       
   554       yellow magenta cyan orange) do:[:aStandardColorName |
       
   555         aColor = (Color name:aStandardColorName) ifTrue:[
       
   556             ^ aStandardColorName.
       
   557         ]
       
   558     ].
       
   559     ^ '#' 
       
   560      , (aColor redByte hexPrintString:2)
       
   561      , (aColor greenByte hexPrintString:2)
       
   562      , (aColor blueByte hexPrintString:2)
       
   563 
       
   564     "Created: / 27.2.1997 / 11:48:40 / cg"
       
   565     "Modified: / 6.6.1998 / 20:58:49 / cg"
       
   566 !
       
   567 
       
   568 save:image onStream:aStream named:imageName
       
   569     "save image as XPM file on aStream.
       
   570      Caveat: currently, only a maximum of 256 colors is handled
       
   571             (i.e. very simple images)"
       
   572 
       
   573     |usedColors nColorsUsed nColors nChars map maskColorIndex
   466      isMasked imageMask|
   574      isMasked imageMask|
   467 
   575 
   468     usedColors := image usedColors asArray.
   576     usedColors := image usedColors asArray.
   469     nColors := nColorsUsed := usedColors size.
   577     nColors := nColorsUsed := usedColors size.
   470     (imageMask := image mask) notNil ifTrue:[
   578     (imageMask := image mask) notNil ifTrue:[
   482     map addAll:($0 to: $9) asOrderedCollection.
   590     map addAll:($0 to: $9) asOrderedCollection.
   483     map addAll:#($. $, $` $^ $* $: $; $< $> $? $% $# $& $( $) $- $+ $=) asOrderedCollection.
   591     map addAll:#($. $, $` $^ $* $: $; $< $> $? $% $# $& $( $) $- $+ $=) asOrderedCollection.
   484     nChars := 1.
   592     nChars := 1.
   485 
   593 
   486     nColors > map size ifTrue:[
   594     nColors > map size ifTrue:[
   487 "/        ^ Image cannotRepresentImageSignal 
       
   488 "/            raiseWith:image
       
   489 "/            errorString:('XPMReader cannot represent this image (too many colors)').
       
   490         map := OrderedCollection new.
   595         map := OrderedCollection new.
   491         $a to: $j do:[:c1 |
   596         $a to: $j do:[:c1 |
   492             map addAll:(($a to: $z) collect:[:c2 | c1 asString , c2 asString]).
   597             map addAll:(($a to: $z) collect:[:c2 | c1 asString , c2 asString]).
   493         ].
   598         ].
   494         nChars := 2.
   599         nChars := 2.
   495     ].
   600     ].
   496 
   601 
   497     [
   602     outStream := aStream.
   498         outStream := aFileName asFilename newReadWriteStream.
       
   499     ] on:FileStream openErrorSignal do:[:ex|
       
   500         ^ Image fileCreationErrorSignal 
       
   501             raiseWith:image
       
   502             errorString:('file creation error: ' , aFileName asString).
       
   503     ].
       
   504 
       
   505     baseName := aFileName asFilename baseName asFilename withoutSuffix asString.
       
   506     baseName replaceAll:$. with:$_.
       
   507 
   603 
   508     outStream nextPutLine:'/* XPM */'.
   604     outStream nextPutLine:'/* XPM */'.
   509     outStream nextPutLine:'static char *' , baseName , '_xpm[] = {'.
   605     outStream nextPutLine:'static char *' , imageName , '_xpm[] = {'.
   510     outStream nextPutLine:'/* width height ncolors chars_per_pixel */'.
   606     outStream nextPutLine:'/* width height ncolors chars_per_pixel */'.
   511     outStream nextPutLine:'"' , image width printString , ' '
   607     outStream nextPutLine:'"' , image width printString , ' '
   512                               , image height printString , ' '
   608                               , image height printString , ' '
   513                               , nColors printString , ' '
   609                               , nColors printString , ' '
   514                               , nChars printString , '",'.
   610                               , nChars printString , '",'.
   551             ]
   647             ]
   552         ].
   648         ].
   553         outStream nextPutLine:'",'.
   649         outStream nextPutLine:'",'.
   554     ].
   650     ].
   555     outStream nextPutLine:'};'.
   651     outStream nextPutLine:'};'.
   556     outStream close.
       
   557 
   652 
   558     "Modified: / 28.7.1998 / 21:52:13 / cg"
   653     "Modified: / 28.7.1998 / 21:52:13 / cg"
   559 ! !
   654 ! !
   560 
   655 
   561 !XPMReader methodsFor:'writing-private'!
       
   562 
       
   563 colorNameOf:aColor
       
   564     "generate a name for a color. If its a standard color,
       
   565      return its name; otherwise return the hex representation."
       
   566 
       
   567     #(white black red green blue
       
   568       yellow magenta cyan orange) do:[:aStandardColorName |
       
   569         aColor = (Color name:aStandardColorName) ifTrue:[
       
   570             ^ aStandardColorName.
       
   571         ]
       
   572     ].
       
   573     ^ '#' 
       
   574      , (aColor redByte hexPrintString:2)
       
   575      , (aColor greenByte hexPrintString:2)
       
   576      , (aColor blueByte hexPrintString:2)
       
   577 
       
   578     "Created: / 27.2.1997 / 11:48:40 / cg"
       
   579     "Modified: / 6.6.1998 / 20:58:49 / cg"
       
   580 ! !
       
   581 
       
   582 !XPMReader class methodsFor:'documentation'!
   656 !XPMReader class methodsFor:'documentation'!
   583 
   657 
   584 version
   658 version
   585     ^ '$Header: /cvs/stx/stx/libview2/XPMReader.st,v 1.54 2003-09-01 14:47:55 cg Exp $'
   659     ^ '$Header: /cvs/stx/stx/libview2/XPMReader.st,v 1.55 2003-09-12 10:38:04 cg Exp $'
   586 ! !
   660 ! !
   587 
   661 
   588 XPMReader initialize!
   662 XPMReader initialize!