writing onto a stream
authorClaus Gittinger <cg@exept.de>
Fri, 12 Sep 2003 12:38:06 +0200
changeset 1812 5c902c4135f1
parent 1811 d3fabf23f595
child 1813 aa74c7bd22ad
writing onto a stream
XBMReader.st
XPMReader.st
--- a/XBMReader.st	Tue Sep 09 13:30:24 2003 +0200
+++ b/XBMReader.st	Fri Sep 12 12:38:06 2003 +0200
@@ -52,6 +52,42 @@
     [author:]
         Claus Gittinger
 "
+!
+
+examples
+"
+  Reading from a file:
+                                                                        [exBegin]
+    |image|
+
+    image := Image fromFile:('../../goodies/bitmaps/xbmBitmaps/TicTacToe.xbm').
+    image inspect
+                                                                        [exEnd]
+
+
+  Saving to a file:
+                                                                        [exBegin]
+    |image|
+
+    image := Image fromScreen:(0@0 corner:30@30).
+    image := image asThresholdMonochromeImage.
+    XBMReader save:image onFile:'/tmp/test.xbm'.
+    '/tmp/test.xbm' asFilename contents asString inspect.
+    (Image fromFile:('/tmp/test.xbm')) inspect.
+                                                                        [exEnd]
+
+
+  Or directly into a stream:
+                                                                        [exBegin]
+    |image stream|
+
+    image := Image fromScreen:(0@0 corner:30@30).
+    image := image asThresholdMonochromeImage.
+    stream := WriteStream on:(String new).
+    XPMReader save:image onStream:stream.
+    stream contents inspect.
+                                                                        [exEnd]
+"
 ! !
 
 !XBMReader class methodsFor:'initialization'!
@@ -284,6 +320,48 @@
     "save image as XBM file on aFileName.
      Only depth1 b&w images can be represented in this format."
 
+    |stream|
+
+    "sigh - must check before creating file"
+    (self class canRepresent:image) ifFalse:[
+        ^ Image cannotRepresentImageSignal 
+            raiseWith:image
+            errorString:('XBM format only supports monochrome images').
+    ].
+
+    image mask notNil ifTrue:[
+        Image informationLostQuerySignal
+            raiseWith:image
+            errorString:('XBM format does not support an imageMask').
+    ].
+
+    [
+        stream := aFileName asFilename newReadWriteStream.
+    ] on:FileStream openErrorSignal do:[:ex|
+        ^ Image fileCreationErrorSignal 
+            raiseWith:image
+            errorString:('file creation error: ' , aFileName asString).
+    ].
+
+    self save:image onStream:stream.
+    stream close
+
+    "
+     XBMReader save:(Image fromFile:'../../goodies/bitmaps/xbmBitmaps/TicTacToe.xbm') onFile:'/tmp/test.xbm'
+    "
+    "
+     convert sun icon to XBM format:
+
+     XBMReader save:(Image fromFile:'bitmaps/hello_world.icon') onFile:'test.xbm'
+    "
+
+    "Modified: 27.2.1997 / 12:46:49 / cg"
+!
+
+save:image onStream:aStream
+    "save image as XBM cdata on aStream.
+     Only depth1 b&w images can be represented in this format."
+
     |reverseBits bits byte
      h        "{ Class: SmallInteger }"
      srcIndex "{ Class: SmallInteger }"
@@ -301,13 +379,7 @@
             errorString:('XBM format does not support an imageMask').
     ].
 
-    [
-        outStream := aFileName asFilename newReadWriteStream.
-    ] on:FileStream openErrorSignal do:[:ex|
-        ^ Image fileCreationErrorSignal 
-            raiseWith:image
-            errorString:('file creation error: ' , aFileName asString).
-    ].
+    outStream := aStream.
 
     width := image width.
     height := image height.
@@ -348,24 +420,16 @@
         outStream cr
     ].
     outStream nextPutAll: '};'; cr.
-    outStream close
 
     "
-     XBMReader save:(Image fromFile:'bitmaps/SBrowser.xbm') onFile:'test.xbm'
-    "
+     XBMReader save:(Image fromFile:'../../goodies/bitmaps/xbmBitmaps/TicTacToe.xbm') onStream:Transcript
     "
-     convert sun icon to XBM format:
-
-     XBMReader save:(Image fromFile:'bitmaps/hello_world.icon') onFile:'test.xbm'
-    "
-
-    "Modified: 27.2.1997 / 12:46:49 / cg"
 ! !
 
 !XBMReader class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview2/XBMReader.st,v 1.48 2003-09-01 14:47:52 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview2/XBMReader.st,v 1.49 2003-09-12 10:38:06 cg Exp $'
 ! !
 
 XBMReader initialize!
--- a/XPMReader.st	Tue Sep 09 13:30:24 2003 +0200
+++ b/XPMReader.st	Fri Sep 12 12:38:06 2003 +0200
@@ -37,10 +37,13 @@
 
 documentation
 "
-    this class provides methods for loading x-pixmap-file (xpm) images.
+    This class provides methods for loading x-pixmap-file (xpm) images.
 
-    These images are used (in X) for palette images (see ctwm or hp-vue for a lot
-    of them). 
+    These images are used (in X) for palette images 
+    (see ctwm or hp-vue for a lot of them).
+    The format is actually a piece of C-code, which can be compiled by the C-compiler
+    into a constant image data structure.
+
     The code here is a hack - it may not work for all images 
     (it works for the testfiles I got here).
 
@@ -53,9 +56,9 @@
         Only understands single-word color names (i.e. names with spaces 
         are not supported)
 
-        Image writing is only supported for images with less than about 50
-        colors (single byte encoding). If present, the mask must be a
-        single bit mask (i.e. no alpha channel).
+        Image writing is only supported for images with less than about 200
+        colors (single byte encoding). 
+        If present, the mask must be a single bit mask (i.e. no alpha channel).
         Due to the algorithm, writing may be slow for big images
 
     Suggestions: adapt & use the XPM library here.
@@ -67,6 +70,45 @@
         ST80FormReader SunRasterReader TargaReader TIFFReader WindowsIconReader 
         XBMReader XWDReader 
 "
+!
+
+examples
+"
+  Reading from a file:
+                                                                        [exBegin]
+    |image|
+
+    image := Image fromFile:('../../goodies/bitmaps/xpmBitmaps/INFO.xpm').
+    image inspect
+                                                                        [exEnd]
+
+
+  Saving to a file:
+                                                                        [exBegin]
+    |image|
+
+    image := Image fromScreen:(0@0 corner:30@30).
+    image usedColors size > 256 ifTrue:[
+        image := image asDitheredImageUsing:(Color standardDitherColorsForDepth8) depth:8.
+    ].
+    XPMReader save:image onFile:'/tmp/test.xpm'.
+    '/tmp/test.xpm' asFilename contents asString inspect
+                                                                        [exEnd]
+
+
+  Or directly into a stream:
+                                                                        [exBegin]
+    |image stream|
+
+    image := Image fromScreen:(0@0 corner:30@30).
+    image usedColors size > 256 ifTrue:[
+        image := image asDitheredImageUsing:(Color standardDitherColorsForDepth8) depth:8.
+    ].
+    stream := WriteStream on:(String new).
+    XPMReader save:image onStream:stream.
+    stream contents inspect
+                                                                        [exEnd]
+"
 ! !
 
 !XPMReader class methodsFor:'initialization'!
@@ -462,7 +504,73 @@
      Caveat: currently, only a maximum of roughly 50 colors is handled
              (i.e. very simple images)"
 
-    |usedColors nColorsUsed nColors nChars baseName map maskColorIndex
+    |nColorsUsed nColors imageName imageMask stream|
+
+    "sigh - check this before creating the file"
+    nColors := nColorsUsed := image usedColors size.
+    (imageMask := image mask) notNil ifTrue:[
+        nColors := nColors + 1.
+    ].
+    nColors > 256 ifTrue:[
+        ^ Image cannotRepresentImageSignal 
+            raiseWith:image
+            errorString:('XPMReader cannot represent this image (too many colors)').
+    ].
+
+    [
+        stream := aFileName asFilename newReadWriteStream.
+    ] on:FileStream openErrorSignal do:[:ex|
+        ^ Image fileCreationErrorSignal 
+            raiseWith:image
+            errorString:('file creation error: ' , aFileName asString).
+    ].
+
+    imageName := aFileName asFilename baseName asFilename withoutSuffix asString.
+    imageName replaceAll:$. with:$_.
+
+    self save:image onStream:stream named:imageName.
+
+    stream close.
+!
+
+save:image onStream:aStream
+    "save image as XPM file on aStream.
+     Caveat: currently, only a maximum of roughly 50 colors is handled
+            (i.e. very simple images)"
+
+    ^ self
+        save:image 
+        onStream:aStream 
+        named:'unnamed'
+! !
+
+!XPMReader methodsFor:'writing-private'!
+
+colorNameOf:aColor
+    "generate a name for a color. If its a standard color,
+     return its name; otherwise return the hex representation."
+
+    #(white black red green blue
+      yellow magenta cyan orange) do:[:aStandardColorName |
+        aColor = (Color name:aStandardColorName) ifTrue:[
+            ^ aStandardColorName.
+        ]
+    ].
+    ^ '#' 
+     , (aColor redByte hexPrintString:2)
+     , (aColor greenByte hexPrintString:2)
+     , (aColor blueByte hexPrintString:2)
+
+    "Created: / 27.2.1997 / 11:48:40 / cg"
+    "Modified: / 6.6.1998 / 20:58:49 / cg"
+!
+
+save:image onStream:aStream named:imageName
+    "save image as XPM file on aStream.
+     Caveat: currently, only a maximum of 256 colors is handled
+            (i.e. very simple images)"
+
+    |usedColors nColorsUsed nColors nChars map maskColorIndex
      isMasked imageMask|
 
     usedColors := image usedColors asArray.
@@ -484,9 +592,6 @@
     nChars := 1.
 
     nColors > map size ifTrue:[
-"/        ^ Image cannotRepresentImageSignal 
-"/            raiseWith:image
-"/            errorString:('XPMReader cannot represent this image (too many colors)').
         map := OrderedCollection new.
         $a to: $j do:[:c1 |
             map addAll:(($a to: $z) collect:[:c2 | c1 asString , c2 asString]).
@@ -494,19 +599,10 @@
         nChars := 2.
     ].
 
-    [
-        outStream := aFileName asFilename newReadWriteStream.
-    ] on:FileStream openErrorSignal do:[:ex|
-        ^ Image fileCreationErrorSignal 
-            raiseWith:image
-            errorString:('file creation error: ' , aFileName asString).
-    ].
-
-    baseName := aFileName asFilename baseName asFilename withoutSuffix asString.
-    baseName replaceAll:$. with:$_.
+    outStream := aStream.
 
     outStream nextPutLine:'/* XPM */'.
-    outStream nextPutLine:'static char *' , baseName , '_xpm[] = {'.
+    outStream nextPutLine:'static char *' , imageName , '_xpm[] = {'.
     outStream nextPutLine:'/* width height ncolors chars_per_pixel */'.
     outStream nextPutLine:'"' , image width printString , ' '
                               , image height printString , ' '
@@ -553,36 +649,14 @@
         outStream nextPutLine:'",'.
     ].
     outStream nextPutLine:'};'.
-    outStream close.
 
     "Modified: / 28.7.1998 / 21:52:13 / cg"
 ! !
 
-!XPMReader methodsFor:'writing-private'!
-
-colorNameOf:aColor
-    "generate a name for a color. If its a standard color,
-     return its name; otherwise return the hex representation."
-
-    #(white black red green blue
-      yellow magenta cyan orange) do:[:aStandardColorName |
-        aColor = (Color name:aStandardColorName) ifTrue:[
-            ^ aStandardColorName.
-        ]
-    ].
-    ^ '#' 
-     , (aColor redByte hexPrintString:2)
-     , (aColor greenByte hexPrintString:2)
-     , (aColor blueByte hexPrintString:2)
-
-    "Created: / 27.2.1997 / 11:48:40 / cg"
-    "Modified: / 6.6.1998 / 20:58:49 / cg"
-! !
-
 !XPMReader class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview2/XPMReader.st,v 1.54 2003-09-01 14:47:55 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview2/XPMReader.st,v 1.55 2003-09-12 10:38:04 cg Exp $'
 ! !
 
 XPMReader initialize!