XBMReader.st
changeset 3 78aaa5408119
parent 0 3f9277473954
child 5 4d55b551dc57
--- a/XBMReader.st	Wed Oct 13 01:31:41 1993 +0100
+++ b/XBMReader.st	Wed Oct 13 01:32:33 1993 +0100
@@ -12,7 +12,7 @@
 
 ImageReader subclass:#XBMReader
          instanceVariableNames:''
-         classVariableNames:'reverseBits'
+         classVariableNames:''
          poolDictionaries:''
          category:'Graphics-Support'
 !
@@ -22,12 +22,107 @@
 COPYRIGHT (c) 1992-93 by Claus Gittinger
               All Rights Reserved
 
-this class provides methods for loading and saving xbitmap-file pictures.
+this class provides methods for loading and saving x-bitmap-file images.
+These images can (for example) be created using the bitmap editor supplied
+with X. Only monochrome images can be represented in thos format.
 
 %W% %E%
 written Sep 92 by claus
 '!
 
+!XBMReader methodsFor:'writing to file'!
+
+save:image onFile:aFileName
+    "save image as XBM file on aFileName"
+
+    |reverseBits bits srcIndex rowBytes|
+
+    outStream := FileStream newFileNamed:aFileName.
+    outStream isNil ifTrue:[
+        'create error' printNewline. 
+        ^ nil
+    ].
+
+    width := image width.
+    height := image height.
+    photometric := image photometric.
+    samplesPerPixel := image samplesPerPixel.
+    bitsPerSample := image bitsPerSample.
+    colorMap := image colorMap.
+
+    ((samplesPerPixel ~~ 1)
+    or:[((bitsPerSample at:1) ~~ 1)
+    or:[(photometric ~~ #blackIs0) and:[photometric ~~ #whiteIs0]]]) ifTrue:[
+        self error:'can only save Depth1Images'.
+        outStream close.
+        ^ nil.
+    ].
+
+    outStream nextPutAll: '#define xbm_width '.
+    outStream nextPutAll:(width printString).
+    outStream cr.
+    outStream nextPutAll: '#define xbm_height '.
+    outStream nextPutAll:(height printString).
+    outStream cr.
+    outStream nextPutAll: 'static char xbm_bits[] = {'; cr.
+
+    reverseBits := self class reverseBits.
+
+    rowBytes := width + 7 // 8.
+    data := image bits.
+    srcIndex := 1.
+
+    height timesRepeat:[
+        rowBytes timesRepeat:[
+            outStream nextPutAll: '0x'.
+            bits := data at:srcIndex. srcIndex := srcIndex + 1.
+            (reverseBits at:(bits + 1)) printOn:outStream radix:16.
+            outStream nextPutAll: ', '.
+        ].
+        outStream cr
+    ].
+    outStream nextPutAll: '};'; cr.
+    outStream close
+
+    "XBMReader save:(Image fromFile:'bitmaps/SBrowser.xbm') onFile:'test.xbm'"
+! !
+
+!XBMReader class methodsFor:'testing'!
+
+isValidImageFile:aFileName
+    "return true, if aFileName contains an x-bitmap-file image"
+
+    |line inStream index1 index2 keyword|
+
+    inStream := FileStream readonlyFileNamed:aFileName.
+    inStream isNil ifTrue:[^ false].
+
+    line := inStream nextLine.
+    line isNil ifTrue:[
+        inStream close.
+        ^ false
+    ].
+    [line startsWith:'#'] whileFalse:[
+        line := inStream nextLine.
+        line isNil ifTrue:[
+            inStream close.
+            ^ false
+        ]
+    ].
+    index1 := line indexOf:(Character space).
+    index2 := line indexOf:(Character space) startingAt:(index1 + 1).
+    (index2 == 0) ifTrue:[
+        inStream close.
+        ^ false
+    ].
+    keyword := line copyFrom:index1 to:(index2 - 1).
+    (keyword endsWith:'_width') ifFalse:[
+        ^ false
+    ].
+    inStream close.
+    ^ true
+! !
+
 !XBMReader methodsFor:'reading from file'!
 
 fromFile:aFileName
@@ -37,7 +132,8 @@
      bytesPerRow
      lo       "{ Class: SmallInteger }"
      hi       "{ Class: SmallInteger }"
-     val      "{ Class: SmallInteger }"|
+     val      "{ Class: SmallInteger }"
+     reverseBits|
 
     inStream := FileStream readonlyFileNamed:aFileName.
     inStream isNil ifTrue:[
@@ -81,22 +177,7 @@
         bytesPerRow := bytesPerRow + 1
     ].
 
-    reverseBits isNil ifTrue:[
-        reverseBits := ByteArray new:256.
-        0 to:255 do:[:i |
-            val := 0.
-            index := i.
-            (index bitTest:16r01) ifTrue:[val := val bitOr:16r80].
-            (index bitTest:16r02) ifTrue:[val := val bitOr:16r40].
-            (index bitTest:16r04) ifTrue:[val := val bitOr:16r20].
-            (index bitTest:16r08) ifTrue:[val := val bitOr:16r10].
-            (index bitTest:16r10) ifTrue:[val := val bitOr:16r08].
-            (index bitTest:16r20) ifTrue:[val := val bitOr:16r04].
-            (index bitTest:16r40) ifTrue:[val := val bitOr:16r02].
-            (index bitTest:16r80) ifTrue:[val := val bitOr:16r01].
-            reverseBits at:(index + 1) put:val
-        ]
-    ].
+    reverseBits := self class reverseBits.
 
     data := ByteArray new:(bytesPerRow * height).
     dstIndex := 1.