ImageRdr.st
changeset 105 6a4a21c17e5d
parent 97 dd6116883ac0
child 118 25e775072a89
equal deleted inserted replaced
104:aa39cabdc13b 105:6a4a21c17e5d
     8  be provided or otherwise made available to, or used by, any
     8  be provided or otherwise made available to, or used by, any
     9  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
       
    13 'From Smalltalk/X, Version:2.10.4 on 18-feb-1995 at 2:18:34 am'!
       
    14 
    13 Object subclass:#ImageReader
    15 Object subclass:#ImageReader
    14 	 instanceVariableNames:'width height data byteOrder inStream outStream
    16 	 instanceVariableNames:'width height data byteOrder inStream outStream photometric
    15 				photometric samplesPerPixel bitsPerSample
    17 		samplesPerPixel bitsPerSample colorMap'
    16 				colorMap'
       
    17 	 classVariableNames:'ReverseBits'
    18 	 classVariableNames:'ReverseBits'
    18 	 poolDictionaries:''
    19 	 poolDictionaries:''
    19 	 category:'Graphics-Images support'
    20 	 category:'Graphics-Images support'
    20 !
    21 !
    21 
    22 
    22 ImageReader comment:'
    23 ImageReader comment:'
    23 COPYRIGHT (c) 1991 by Claus Gittinger
    24 COPYRIGHT (c) 1991 by Claus Gittinger
    24 	      All Rights Reserved
    25 	      All Rights Reserved
    25 
    26 
    26 $Header: /cvs/stx/stx/libview/Attic/ImageRdr.st,v 1.14 1995-02-15 10:36:04 claus Exp $
    27 $Header: /cvs/stx/stx/libview/Attic/ImageRdr.st,v 1.15 1995-02-18 15:57:27 claus Exp $
    27 '!
    28 '!
    28 
    29 
    29 !ImageReader class methodsFor:'documentation'!
       
    30 
       
    31 copyright
       
    32 "
       
    33  COPYRIGHT (c) 1991 by Claus Gittinger
       
    34 	      All Rights Reserved
       
    35 
       
    36  This software is furnished under a license and may be used
       
    37  only in accordance with the terms of that license and with the
       
    38  inclusion of the above copyright notice.   This software may not
       
    39  be provided or otherwise made available to, or used by, any
       
    40  other person.  No title to or ownership of the software is
       
    41  hereby transferred.
       
    42 "
       
    43 !
       
    44 
       
    45 version
       
    46 "
       
    47 $Header: /cvs/stx/stx/libview/Attic/ImageRdr.st,v 1.14 1995-02-15 10:36:04 claus Exp $
       
    48 "
       
    49 !
       
    50 
       
    51 documentation
       
    52 "
       
    53     common functions for image-readers (i.e. TIFFReader, GIFReader etc.)
       
    54 "
       
    55 ! !
       
    56 
       
    57 !ImageReader class methodsFor:'cleanup'!
       
    58 
       
    59 lowSpaceCleanup
       
    60     "cleanup things we do not need"
       
    61 
       
    62     ReverseBits := nil
       
    63 ! !
       
    64 
       
    65 !ImageReader class methodsFor:'testing'!
       
    66 
       
    67 isValidImageFile:aFileName
       
    68     "return true, if aFileName contains an image this
       
    69      reader understands - should be redefined in subclasses"
       
    70 
       
    71     ^ false
       
    72 ! !
       
    73 
       
    74 !ImageReader class methodsFor:'constants'!
       
    75 
       
    76 reverseBits
       
    77     "return a table filled with bit reverse information.
       
    78      To convert from msbit-first to lsbit-first bytes, use
       
    79      the value as index into the table, retrieving the reverse
       
    80      value. Since indexing must start at 1, use (value + 1) as
       
    81      index."
       
    82 
       
    83     |val "{ Class: SmallInteger }" |
       
    84 
       
    85     ReverseBits isNil ifTrue:[
       
    86 	ReverseBits := ByteArray new:256.
       
    87 	0 to:255 do:[:i |
       
    88 	    val := 0.
       
    89 	    (i bitTest:16r01) ifTrue:[val := val bitOr:16r80].
       
    90 	    (i bitTest:16r02) ifTrue:[val := val bitOr:16r40].
       
    91 	    (i bitTest:16r04) ifTrue:[val := val bitOr:16r20].
       
    92 	    (i bitTest:16r08) ifTrue:[val := val bitOr:16r10].
       
    93 	    (i bitTest:16r10) ifTrue:[val := val bitOr:16r08].
       
    94 	    (i bitTest:16r20) ifTrue:[val := val bitOr:16r04].
       
    95 	    (i bitTest:16r40) ifTrue:[val := val bitOr:16r02].
       
    96 	    (i bitTest:16r80) ifTrue:[val := val bitOr:16r01].
       
    97 	    ReverseBits at:(i + 1) put:val
       
    98 	]
       
    99     ].
       
   100     ^ ReverseBits
       
   101 ! !
       
   102 
       
   103 !ImageReader class methodsFor:'fileIn / fileOut'!
       
   104 
       
   105 fromFile:aFileName
       
   106     "read an image (in my format) from aFileName"
       
   107 
       
   108     |reader image depth|
       
   109 
       
   110     reader := self new fromFile:aFileName.
       
   111     reader notNil ifTrue:[
       
   112 	depth := reader bitsPerPixel.
       
   113 	image := (Image implementorForDepth: depth) new.
       
   114 	image width:(reader width).
       
   115 	image height:(reader height).
       
   116 	image photometric:(reader photometric).
       
   117 	image samplesPerPixel:(reader samplesPerPixel).
       
   118 	image bitsPerSample:(reader bitsPerSample).
       
   119 	image colorMap:(reader colorMap).
       
   120 	image data:(reader data).
       
   121 	^ image
       
   122     ].
       
   123     ^ nil
       
   124 !
       
   125 
       
   126 save:anImage onFile:aFileName
       
   127     "save the image in my format on aFileName"
       
   128 
       
   129     ^ (self basicNew) save:anImage onFile:aFileName
       
   130 ! !
       
   131 
       
   132 !ImageReader class methodsFor:'i/o support'!
       
   133 
       
   134 streamReadingFile:aFilename
       
   135     "return a stream to read aFilename - if the filename ends with
       
   136      '.Z' or '.gz', read from a pipe to gunzip."
       
   137 
       
   138     |inStream|
       
   139 
       
   140     ((aFilename endsWith:'.Z') or:[aFilename endsWith:'.gz']) ifTrue:[
       
   141 	inStream := PipeStream readingFrom:'gunzip < ' , aFilename.
       
   142 	inStream isNil ifTrue:[
       
   143 	    inStream := PipeStream readingFrom:'uncompress < ' , aFilename.
       
   144 	]
       
   145     ] ifFalse:[
       
   146 	inStream := FileStream readonlyFileNamed:aFilename.
       
   147     ].
       
   148     inStream isNil ifTrue:[
       
   149 	'IMGREADER: open error on: ' errorPrint. aFilename errorPrintNL. 
       
   150     ].
       
   151     ^ inStream
       
   152 ! !
       
   153 
       
   154 !ImageReader methodsFor:'accessing'!
       
   155 
       
   156 width
       
   157     ^ width
       
   158 !
       
   159 
       
   160 height 
       
   161     ^ height
       
   162 !
       
   163 
       
   164 data 
       
   165     ^ data
       
   166 !
       
   167 
       
   168 photometric
       
   169     ^ photometric
       
   170 !
       
   171 
       
   172 colorMap
       
   173     ^ colorMap
       
   174 !
       
   175 
       
   176 samplesPerPixel
       
   177     ^ samplesPerPixel
       
   178 !
       
   179 
       
   180 bitsPerSample
       
   181     ^ bitsPerSample
       
   182 !
       
   183 
       
   184 bitsPerPixel
       
   185     "return the number of bits per pixel"
       
   186 
       
   187     ^ (bitsPerSample inject:0 into:[:sum :i | sum + i])
       
   188 ! !
       
   189 
       
   190 !ImageReader methodsFor:'fileIn / fileOut'!
       
   191 
       
   192 fromFile:aFileName
       
   193     ^ self subclassResponsibility
       
   194 !
       
   195 
       
   196 save:image onFile:aFileName
       
   197     ^ self subclassResponsibility
       
   198 ! !
       
   199 
       
   200 !ImageReader methodsFor:'i/o support'!
       
   201 
       
   202 readLong
       
   203     "return the next 4-byte long, honoring the byte-order"
       
   204 
       
   205     ^ inStream nextLongMSB:(byteOrder ~~ #lsb)
       
   206 !
       
   207 
       
   208 readShort
       
   209     "return the next 2-byte short, honoring the byte-order"
       
   210 
       
   211     ^ inStream nextUnsignedShortMSB:(byteOrder ~~ #lsb)
       
   212 !
       
   213 
       
   214 readShortLong
       
   215     "return the next 2-byte short, honoring the byte-order.
       
   216      There are actually 4 bytes read, but only 2 looked at."
       
   217 
       
   218     |bytes val|
       
   219 
       
   220     bytes := ByteArray new:4.
       
   221     inStream nextBytes:4 into:bytes.
       
   222     (byteOrder == #lsb) ifTrue:[
       
   223 	val := bytes at:2.
       
   224 	val := val * 256 + (bytes at:1)
       
   225     ] ifFalse:[
       
   226 	val := bytes at:3.
       
   227 	val := val * 256 + (bytes at:4)
       
   228     ].
       
   229     ^ val
       
   230 !
       
   231 
       
   232 writeLong:anInteger
       
   233     "write a 4-byte long, honoring the byte-order."
       
   234 
       
   235     outStream nextPutLong:anInteger MSB:(byteOrder ~~ #lsb)
       
   236 !
       
   237 
       
   238 writeShort:anInteger
       
   239     "write a 2-byte short, honoring the byte-order."
       
   240 
       
   241     outStream nextPutShort:anInteger MSB:(byteOrder ~~ #lsb)
       
   242 ! !
       
   243 
       
   244 !ImageReader class methodsFor:'decompression support'!
       
   245 
       
   246 decompressCCITT3From:srcBytes into:dstBytes startingAt:offset count:count 
       
   247     "decompress a CCITT Group 3 compressed image.
       
   248      count bytes from srcBytes are decompressed into dstBytes.
       
   249      Calls primitive c function for speed"
       
   250 %{
       
   251     if (__isByteArray(srcBytes) 
       
   252      && __isByteArray(dstBytes)
       
   253      && __bothSmallInteger(offset, count)) {
       
   254 	if (__decodeCCITTgroup3__(_ByteArrayInstPtr(srcBytes)->ba_element,
       
   255 			      _ByteArrayInstPtr(dstBytes)->ba_element
       
   256 			      + _intVal(offset) - 1,
       
   257 			      _intVal(count))) {
       
   258 	    RETURN ( self );
       
   259 	}
       
   260     }
       
   261 %}
       
   262 .
       
   263     self primitiveFailed
       
   264 !
       
   265 
       
   266 decompressLZWFrom:srcBytes count:count into:dstBytes startingAt:offset
       
   267     "decompress an LZW (tiff) compressed image.
       
   268      count bytes from srcBytes are decompressed into dstBytes.
       
   269      Calls primitive c function for speed"
       
   270 %{
       
   271     if (__isByteArray(srcBytes) 
       
   272      && __isByteArray(dstBytes)
       
   273      && __bothSmallInteger(offset, count)) {
       
   274 	if (__decodeLZW__(_ByteArrayInstPtr(srcBytes)->ba_element,
       
   275 		      _ByteArrayInstPtr(dstBytes)->ba_element
       
   276 		      + _intVal(offset) - 1,
       
   277 		      _intVal(count))) {
       
   278 	    RETURN ( self );
       
   279 	}
       
   280     }
       
   281 %}
       
   282 .
       
   283     self primitiveFailed
       
   284 !
       
   285 
       
   286 decompressGIFFrom:srcBytes count:count into:dstBytes startingAt:offset codeLen:codeLen
       
   287     "decompress a GIF compressed image.
       
   288      count bytes from srcBytes are decompressed into dstBytes.
       
   289      Calls primitive c function for speed"
       
   290 %{
       
   291     if (__isByteArray(srcBytes) 
       
   292      && __isByteArray(dstBytes)
       
   293      && __bothSmallInteger(codeLen, offset)
       
   294      && __isSmallInteger(count)) {
       
   295 	if (__decodeGIF__(_ByteArrayInstPtr(srcBytes)->ba_element,
       
   296 		      _ByteArrayInstPtr(dstBytes)->ba_element
       
   297 		      + _intVal(offset) - 1,
       
   298 		      _intVal(count),
       
   299 		      _intVal(codeLen))) {
       
   300 	    RETURN ( self );
       
   301 	}
       
   302     }
       
   303 %}
       
   304 .
       
   305     self primitiveFailed
       
   306 !
       
   307 decodeDelta:step in:data width:width height:height
       
   308     "perform NeXT special predictor delta decoding inplace in data.
       
   309      Calls primitive c function for speed"
       
   310 
       
   311     (step ~~ 3) ifTrue:[
       
   312 	^ self error:'only rgb pictures supported'
       
   313     ].
       
   314 
       
   315 %{
       
   316     if (__isByteArray(data)
       
   317      && __bothSmallInteger(width, height)) {
       
   318 	__decodeDelta__(_ByteArrayInstPtr(data)->ba_element,
       
   319 		    _intVal(width), _intVal(height));
       
   320 	RETURN ( self );
       
   321     }
       
   322 %}
       
   323 .
       
   324     self primitiveFailed
       
   325 ! !
       
   326 
       
   327 !ImageReader primitiveFunctions!
    30 !ImageReader primitiveFunctions!
   328 
       
   329 %{
    31 %{
   330 
    32 
   331 /*
    33 /*
   332  * ccitt decompression
    34  * ccitt decompression
   333  */
    35  */
  1052     return 1;
   754     return 1;
  1053 }
   755 }
  1054 
   756 
  1055 %}
   757 %}
  1056 ! !
   758 ! !
       
   759 
       
   760 !ImageReader class methodsFor:'documentation'!
       
   761 
       
   762 copyright
       
   763 "
       
   764  COPYRIGHT (c) 1991 by Claus Gittinger
       
   765 	      All Rights Reserved
       
   766 
       
   767  This software is furnished under a license and may be used
       
   768  only in accordance with the terms of that license and with the
       
   769  inclusion of the above copyright notice.   This software may not
       
   770  be provided or otherwise made available to, or used by, any
       
   771  other person.  No title to or ownership of the software is
       
   772  hereby transferred.
       
   773 "
       
   774 !
       
   775 
       
   776 version
       
   777 "
       
   778 $Header: /cvs/stx/stx/libview/Attic/ImageRdr.st,v 1.15 1995-02-18 15:57:27 claus Exp $
       
   779 "
       
   780 !
       
   781 
       
   782 documentation
       
   783 "
       
   784     Abstract class to provide common functions for image-readers 
       
   785     (i.e. TIFFReader, GIFReader etc.)
       
   786 
       
   787     ImageReaders are created temporary to read an image from a stream.
       
   788     They read the stream and collect all relevant information internally.
       
   789     Once done with reading, the image is asked for.
       
   790 
       
   791     See implementation of fromStream: in concrete subclasses.
       
   792     The public interfaces are:
       
   793 	 <ConcreteReaderClass> fromFile:aFilename
       
   794     or:
       
   795 	 <ConcreteReaderClass> fromStream:aStream
       
   796 
       
   797     However, usually this is done indirectly through
       
   798 	Image fromFile:aFileName
       
   799 "
       
   800 ! !
       
   801 
       
   802 !ImageReader class methodsFor:'i/o support'!
       
   803 
       
   804 streamReadingFile:aFilename
       
   805     "return a stream to read aFilename.
       
   806      If the filename ends with '.Z' or '.gz', return a stream
       
   807      to a pipe for the uncompressor. Otherwise, return a stream to read
       
   808      the file directly."
       
   809 
       
   810     |inStream name|
       
   811 
       
   812     name := aFilename asString.
       
   813     ((name endsWith:'.Z') or:[name endsWith:'.gz']) ifTrue:[
       
   814 	inStream := PipeStream readingFrom:'gunzip < ' , name.
       
   815 	inStream isNil ifTrue:[
       
   816 	    inStream := PipeStream readingFrom:'uncompress < ' , name.
       
   817 	]
       
   818     ] ifFalse:[
       
   819 	inStream := aFilename asFilename readStream.
       
   820     ].
       
   821     inStream isNil ifTrue:[
       
   822 	'IMGREADER: open error on: ' errorPrint. aFilename errorPrintNL. 
       
   823     ].
       
   824     ^ inStream
       
   825 ! !
       
   826 
       
   827 !ImageReader class methodsFor:'fileIn / fileOut'!
       
   828 
       
   829 fromStream:aStream
       
   830     "read an image (in my format) from aStream"
       
   831 
       
   832     |reader|
       
   833 
       
   834     reader := self new fromStream:aStream.
       
   835     reader notNil ifTrue:[
       
   836 	^ reader image
       
   837     ].
       
   838     ^ nil
       
   839 !
       
   840 
       
   841 fromFile:aFileName
       
   842     "read an image (in my format) from aFileName. 
       
   843      Return the image or nil on error."
       
   844 
       
   845     |result inStream|
       
   846 
       
   847     inStream := self streamReadingFile:aFileName.
       
   848     inStream isNil ifTrue:[
       
   849 	'IMGREADER: file open error' errorPrintNL.
       
   850 	^ nil
       
   851     ].
       
   852     result := self fromStream:inStream.
       
   853     inStream close.
       
   854     ^ result
       
   855 
       
   856     "
       
   857      XPMReader fromFile:'bitmaps/ljet.xpm'
       
   858      XBMReader fromFile:'bitmaps/SBrowser.xbm'
       
   859     " 
       
   860 !
       
   861 
       
   862 save:anImage onFile:aFileName
       
   863     "save the image in my format on aFileName"
       
   864 
       
   865     ^ (self basicNew) save:anImage onFile:aFileName
       
   866 ! !
       
   867 
       
   868 !ImageReader class methodsFor:'testing'!
       
   869 
       
   870 isValidImageFile:aFileName
       
   871     "return true, if aFileName contains an image this
       
   872      reader understands - should be redefined in subclasses"
       
   873 
       
   874     ^ false
       
   875 ! !
       
   876 
       
   877 !ImageReader class methodsFor:'constants'!
       
   878 
       
   879 reverseBits
       
   880     "return a table filled with bit reverse information.
       
   881      To convert from msbit-first to lsbit-first bytes, use
       
   882      the value as index into the table, retrieving the reverse
       
   883      value. Since indexing must start at 1, use (value + 1) as
       
   884      index."
       
   885 
       
   886     |val "{ Class: SmallInteger }" |
       
   887 
       
   888     ReverseBits isNil ifTrue:[
       
   889 	ReverseBits := ByteArray new:256.
       
   890 	0 to:255 do:[:i |
       
   891 	    val := 0.
       
   892 	    (i bitTest:16r01) ifTrue:[val := val bitOr:16r80].
       
   893 	    (i bitTest:16r02) ifTrue:[val := val bitOr:16r40].
       
   894 	    (i bitTest:16r04) ifTrue:[val := val bitOr:16r20].
       
   895 	    (i bitTest:16r08) ifTrue:[val := val bitOr:16r10].
       
   896 	    (i bitTest:16r10) ifTrue:[val := val bitOr:16r08].
       
   897 	    (i bitTest:16r20) ifTrue:[val := val bitOr:16r04].
       
   898 	    (i bitTest:16r40) ifTrue:[val := val bitOr:16r02].
       
   899 	    (i bitTest:16r80) ifTrue:[val := val bitOr:16r01].
       
   900 	    ReverseBits at:(i + 1) put:val
       
   901 	]
       
   902     ].
       
   903     ^ ReverseBits
       
   904 ! !
       
   905 
       
   906 !ImageReader class methodsFor:'cleanup'!
       
   907 
       
   908 lowSpaceCleanup
       
   909     "cleanup things we do not need"
       
   910 
       
   911     ReverseBits := nil
       
   912 ! !
       
   913 
       
   914 !ImageReader class methodsFor:'decompression support'!
       
   915 
       
   916 decompressCCITT3From:srcBytes into:dstBytes startingAt:offset count:count 
       
   917     "decompress CCITT Group 3 compressed image data.
       
   918      count bytes from srcBytes are decompressed into dstBytes.
       
   919      Calls primitive c function for speed"
       
   920 %{
       
   921     if (__isByteArray(srcBytes) 
       
   922      && __isByteArray(dstBytes)
       
   923      && __bothSmallInteger(offset, count)) {
       
   924 	if (__decodeCCITTgroup3__(_ByteArrayInstPtr(srcBytes)->ba_element,
       
   925 			      _ByteArrayInstPtr(dstBytes)->ba_element
       
   926 			      + _intVal(offset) - 1,
       
   927 			      _intVal(count))) {
       
   928 	    RETURN ( self );
       
   929 	}
       
   930     }
       
   931 %}
       
   932 .
       
   933     self primitiveFailed
       
   934 !
       
   935 
       
   936 decompressLZWFrom:srcBytes count:count into:dstBytes startingAt:offset
       
   937     "decompress LZW (tiff) compressed image data.
       
   938      count bytes from srcBytes are decompressed into dstBytes.
       
   939      Calls primitive c function for speed"
       
   940 %{
       
   941     if (__isByteArray(srcBytes) 
       
   942      && __isByteArray(dstBytes)
       
   943      && __bothSmallInteger(offset, count)) {
       
   944 	if (__decodeLZW__(_ByteArrayInstPtr(srcBytes)->ba_element,
       
   945 		      _ByteArrayInstPtr(dstBytes)->ba_element
       
   946 		      + _intVal(offset) - 1,
       
   947 		      _intVal(count))) {
       
   948 	    RETURN ( self );
       
   949 	}
       
   950     }
       
   951 %}
       
   952 .
       
   953     self primitiveFailed
       
   954 !
       
   955 
       
   956 decompressGIFFrom:srcBytes count:count into:dstBytes startingAt:offset codeLen:codeLen
       
   957     "decompress GIF compressed image data.
       
   958      count bytes from srcBytes are decompressed into dstBytes.
       
   959      Calls primitive c function for speed"
       
   960 %{
       
   961     if (__isByteArray(srcBytes) 
       
   962      && __isByteArray(dstBytes)
       
   963      && __bothSmallInteger(codeLen, offset)
       
   964      && __isSmallInteger(count)) {
       
   965 	if (__decodeGIF__(_ByteArrayInstPtr(srcBytes)->ba_element,
       
   966 		      _ByteArrayInstPtr(dstBytes)->ba_element
       
   967 		      + _intVal(offset) - 1,
       
   968 		      _intVal(count),
       
   969 		      _intVal(codeLen))) {
       
   970 	    RETURN ( self );
       
   971 	}
       
   972     }
       
   973 %}
       
   974 .
       
   975     self primitiveFailed
       
   976 !
       
   977 
       
   978 decodeDelta:step in:data width:width height:height
       
   979     "perform NeXT special predictor delta decoding inplace in data.
       
   980      Calls primitive c function for speed"
       
   981 
       
   982     (step ~~ 3) ifTrue:[
       
   983 	^ self error:'only rgb pictures supported'
       
   984     ].
       
   985 
       
   986 %{
       
   987     if (__isByteArray(data)
       
   988      && __bothSmallInteger(width, height)) {
       
   989 	__decodeDelta__(_ByteArrayInstPtr(data)->ba_element,
       
   990 		    _intVal(width), _intVal(height));
       
   991 	RETURN ( self );
       
   992     }
       
   993 %}
       
   994 .
       
   995     self primitiveFailed
       
   996 ! !
       
   997 
       
   998 !ImageReader methodsFor:'accessing'!
       
   999 
       
  1000 image
       
  1001     "return the image represented by myself"
       
  1002 
       
  1003     |image depth|
       
  1004 
       
  1005     depth := self bitsPerPixel.
       
  1006     image := (Image implementorForDepth:depth) new.
       
  1007     image width:width.
       
  1008     image height:height.
       
  1009     image photometric:photometric.
       
  1010     image samplesPerPixel:samplesPerPixel.
       
  1011     image bitsPerSample:bitsPerSample.
       
  1012     image colorMap:colorMap.
       
  1013     image data:data.
       
  1014     ^ image
       
  1015 !
       
  1016 
       
  1017 height 
       
  1018     ^ height
       
  1019 !
       
  1020 
       
  1021 photometric
       
  1022     ^ photometric
       
  1023 !
       
  1024 
       
  1025 width
       
  1026     ^ width
       
  1027 !
       
  1028 
       
  1029 samplesPerPixel
       
  1030     ^ samplesPerPixel
       
  1031 !
       
  1032 
       
  1033 data 
       
  1034     ^ data
       
  1035 !
       
  1036 
       
  1037 colorMap
       
  1038     ^ colorMap
       
  1039 !
       
  1040 
       
  1041 bitsPerSample
       
  1042     ^ bitsPerSample
       
  1043 !
       
  1044 
       
  1045 bitsPerPixel
       
  1046     "return the number of bits per pixel"
       
  1047 
       
  1048     ^ (bitsPerSample inject:0 into:[:sum :i | sum + i])
       
  1049 ! !
       
  1050 
       
  1051 !ImageReader methodsFor:'fileIn / fileOut'!
       
  1052 
       
  1053 save:image onFile:aFileName
       
  1054     "save image in my format on aFile"
       
  1055 
       
  1056     ^ self subclassResponsibility
       
  1057 !
       
  1058 
       
  1059 fromStream:aStream
       
  1060     "read imagedata in my format from aStream"
       
  1061 
       
  1062     ^ self subclassResponsibility
       
  1063 ! !
       
  1064 
       
  1065 !ImageReader methodsFor:'i/o support'!
       
  1066 
       
  1067 readLong
       
  1068     "return the next 4-byte long, honoring the byte-order"
       
  1069 
       
  1070     ^ inStream nextLongMSB:(byteOrder ~~ #lsb)
       
  1071 !
       
  1072 
       
  1073 readShort
       
  1074     "return the next 2-byte short, honoring the byte-order"
       
  1075 
       
  1076     ^ inStream nextUnsignedShortMSB:(byteOrder ~~ #lsb)
       
  1077 !
       
  1078 
       
  1079 readShortLong
       
  1080     "return the next 2-byte short, honoring the byte-order.
       
  1081      There are actually 4 bytes read, but only 2 looked at."
       
  1082 
       
  1083     |bytes val|
       
  1084 
       
  1085     bytes := ByteArray new:4.
       
  1086     inStream nextBytes:4 into:bytes.
       
  1087     (byteOrder == #lsb) ifTrue:[
       
  1088 	val := bytes at:2.
       
  1089 	val := val * 256 + (bytes at:1)
       
  1090     ] ifFalse:[
       
  1091 	val := bytes at:3.
       
  1092 	val := val * 256 + (bytes at:4)
       
  1093     ].
       
  1094     ^ val
       
  1095 !
       
  1096 
       
  1097 writeLong:anInteger
       
  1098     "write a 4-byte long, honoring the byte-order."
       
  1099 
       
  1100     outStream nextPutLong:anInteger MSB:(byteOrder ~~ #lsb)
       
  1101 !
       
  1102 
       
  1103 writeShort:anInteger
       
  1104     "write a 2-byte short, honoring the byte-order."
       
  1105 
       
  1106     outStream nextPutShort:anInteger MSB:(byteOrder ~~ #lsb)
       
  1107 ! !
       
  1108