TIFFRdr.st
changeset 135 ff507d9a242b
parent 117 c0641e5d21e6
child 159 327da5085900
equal deleted inserted replaced
134:f83c245371c2 135:ff507d9a242b
     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 ImageReader subclass:#TIFFReader
    13 ImageReader subclass:#TIFFReader
    14 	 instanceVariableNames:'planarConfiguration
    14 	 instanceVariableNames:'planarConfiguration subFileType stripOffsets rowsPerStrip
    15 				subFileType stripOffsets rowsPerStrip
    15                 fillOrder compression group3options predictor stripByteCounts
    16 				fillOrder compression group3options predictor
    16                 currentOffset stripOffsetsPos stripByteCountsPos bitsPerSamplePos
    17 				stripByteCounts
    17                 colorMapPos'
    18 				currentOffset 
       
    19 				stripOffsetsPos stripByteCountsPos bitsPerSamplePos
       
    20 				colorMapPos'
       
    21 	 classVariableNames:''
    18 	 classVariableNames:''
    22 	 poolDictionaries:''
    19 	 poolDictionaries:''
    23 	 category:'Graphics-Images support'
    20 	 category:'Graphics-Images support'
    24 !
    21 !
    25 
    22 
    37  other person.  No title to or ownership of the software is
    34  other person.  No title to or ownership of the software is
    38  hereby transferred.
    35  hereby transferred.
    39 "
    36 "
    40 !
    37 !
    41 
    38 
    42 version
       
    43     ^ '$Header: /cvs/stx/stx/libview2/Attic/TIFFRdr.st,v 1.26 1995-11-22 12:06:32 cg Exp $'
       
    44 !
       
    45 
       
    46 documentation
    39 documentation
    47 "
    40 "
    48     This class knows how to read TIFF files and how to
    41     This class knows how to read TIFF files and how to
    49     write uncompressed TIFF files.
    42     write uncompressed TIFF files.
    50 
    43 
    72     Image fileFormats at:'.TIF'  put:self.
    65     Image fileFormats at:'.TIF'  put:self.
    73 ! !
    66 ! !
    74 
    67 
    75 !TIFFReader class methodsFor:'testing'!
    68 !TIFFReader class methodsFor:'testing'!
    76 
    69 
       
    70 canRepresent:anImage
       
    71     "return true, if anImage can be represented in my file format.
       
    72      Any image is supported."
       
    73 
       
    74     ^ true
       
    75 !
       
    76 
    77 isValidImageFile:aFileName
    77 isValidImageFile:aFileName
    78     "return true, if aFileName contains a GIF image"
    78     "return true, if aFileName contains a GIF image"
    79 
    79 
    80     |inStream char1 char2 version|
    80     |inStream char1 char2 version|
    81 
    81 
    94     version := inStream nextShortMSB:(char1 == $M).
    94     version := inStream nextShortMSB:(char1 == $M).
    95     inStream close.
    95     inStream close.
    96 
    96 
    97     (version ~~ 42) ifTrue:[^ false].
    97     (version ~~ 42) ifTrue:[^ false].
    98     ^ true
    98     ^ true
    99 !
       
   100 
       
   101 canRepresent:anImage
       
   102     "return true, if anImage can be represented in my file format.
       
   103      Any image is supported."
       
   104 
       
   105     ^ true
       
   106 ! !
    99 ! !
   107 
   100 
   108 !TIFFReader methodsFor:'reading from file'!
       
   109 
       
   110 fromStream:aStream
       
   111     "read an image from aStream"
       
   112 
       
   113     |char1 char2 version 
       
   114      numberOfTags "{ Class: SmallInteger }"
       
   115      tagType      "{ Class: SmallInteger }"
       
   116      numberType   "{ Class: SmallInteger }"
       
   117      length       "{ Class: SmallInteger }"
       
   118      result offset ok msb|
       
   119 
       
   120     inStream := aStream.
       
   121 
       
   122     char1 := aStream next.
       
   123     char2 := aStream next.
       
   124     (char1 ~~ char2) ifTrue:[
       
   125 	'TIFFReader: not a tiff file' errorPrintNL.
       
   126 	^ nil
       
   127     ].
       
   128     (char1 == $I) ifTrue:[
       
   129 	byteOrder := #lsb.
       
   130 	msb := false.
       
   131     ] ifFalse:[
       
   132 	(char1 == $M) ifTrue:[
       
   133 	    byteOrder := #msb.
       
   134 	    msb := true.
       
   135 	] ifFalse:[
       
   136 	    'TIFFReader: not a tiff file' errorPrintNL.
       
   137 	    ^ nil
       
   138 	]
       
   139     ].
       
   140 
       
   141     aStream binary.
       
   142 
       
   143     version := self readShort.
       
   144     (version ~~ 42) ifTrue:[
       
   145 	'TIFFReader: version of tiff-file not supported' errorPrintNL.
       
   146 	^ nil
       
   147     ].
       
   148 
       
   149     "setup default values"
       
   150 
       
   151     compression := 1. "none"
       
   152     fillOrder := #msb.
       
   153     planarConfiguration := 1.
       
   154     photometric := nil.
       
   155     bitsPerSample := 1.
       
   156     samplesPerPixel := 1.
       
   157     width := nil.
       
   158     height := nil.
       
   159     stripOffsets := nil.
       
   160     rowsPerStrip := nil.
       
   161     "resolutionUnit := 2."
       
   162     predictor := 1.
       
   163 
       
   164     offset := aStream nextLongMSB:msb.
       
   165     aStream position:offset + 1.
       
   166 
       
   167     numberOfTags := self readShort.
       
   168     1 to:numberOfTags do:[:index |
       
   169 	tagType := self readShort.
       
   170 	numberType := self readShort.
       
   171 	length := aStream nextLongMSB:msb.
       
   172 	self decodeTiffTag:tagType numberType:numberType length:length
       
   173     ].
       
   174 
       
   175     offset := aStream nextLongMSB:msb.
       
   176     (offset ~~ 0) ifTrue:[
       
   177 	'TIFFReader: more tags ignored' errorPrintNL
       
   178     ].
       
   179 
       
   180     "check for required tags"
       
   181     ok := true.
       
   182     width isNil ifTrue:[
       
   183 	'TIFFReader: missing width tag' errorPrintNL.
       
   184 	ok := false
       
   185     ].
       
   186 
       
   187     height isNil ifTrue:[
       
   188 	'TIFFReader: missing length tag' errorPrintNL.
       
   189 	ok := false
       
   190     ].
       
   191 
       
   192     photometric isNil ifTrue:[
       
   193 	'TIFFReader: missing photometric tag' errorPrintNL.
       
   194 	ok := false
       
   195     ].
       
   196 
       
   197     stripOffsets isNil ifTrue:[
       
   198 	'TIFFReader: missing stripOffsets tag' errorPrintNL.
       
   199 	ok := false
       
   200     ].
       
   201 
       
   202     stripByteCounts isNil ifTrue:[
       
   203 	stripOffsets size == 1 ifTrue:[
       
   204 	    stripByteCounts := Array with:(self bitsPerPixel // 8) * width * height
       
   205 	]
       
   206     ].
       
   207 
       
   208     stripByteCounts isNil ifTrue:[
       
   209 	'TIFFReader: missing stripByteCounts tag' errorPrintNL.
       
   210 	ok := false
       
   211     ].
       
   212 
       
   213     ok ifFalse:[
       
   214 	^ nil
       
   215     ].
       
   216 
       
   217     "given all the information, read the bits"
       
   218 
       
   219     rowsPerStrip isNil ifTrue:[
       
   220 	rowsPerStrip := height
       
   221     ].
       
   222 
       
   223     ok := false.
       
   224     (compression == 1) ifTrue:[
       
   225 	result := self readUncompressedTiffImageData.
       
   226 	ok := true
       
   227     ].
       
   228     (compression == 2) ifTrue:[
       
   229 	result := self readCCITT3RLETiffImageData.
       
   230 	ok := true
       
   231     ].
       
   232     (compression == 3) ifTrue:[
       
   233 	result := self readCCITTGroup3TiffImageData.
       
   234 	ok := true
       
   235     ]. 
       
   236     (compression == 4) ifTrue:[
       
   237 	result := self readCCITTGroup4TiffImageData.
       
   238 	ok := true
       
   239     ]. 
       
   240     (compression == 5) ifTrue:[
       
   241 	result := self readLZWTiffImageData.
       
   242 	ok := true
       
   243     ].
       
   244     (compression == 6) ifTrue:[
       
   245 	result := self readJPEGTiffImageData.
       
   246 	ok := true
       
   247     ].
       
   248     (compression == 32766) ifTrue:[
       
   249 	result := self readNeXTRLE2TiffImageData.
       
   250 	ok := true
       
   251     ].
       
   252     (compression == 32771) ifTrue:[
       
   253 	result := self readCCITTRLEWTiffImageData.
       
   254 	ok := true
       
   255     ].
       
   256     (compression == 32773) ifTrue:[
       
   257 	result := self readPackbitsTiffImageData.
       
   258 	ok := true
       
   259     ].
       
   260     (compression == 32865) ifTrue:[
       
   261 	result := self readNeXTJPEGTiffImageData.
       
   262 	ok := true
       
   263     ].
       
   264     ok ifFalse:[
       
   265 	'TIFFReader: compression type ' errorPrint. compression errorPrint.
       
   266 	' not known' errorPrintNL
       
   267     ].
       
   268     ^ result
       
   269 ! !
       
   270 
       
   271 !TIFFReader methodsFor:'writing to file'!
       
   272 
       
   273 save:image onFile:aFileName
       
   274     "save image as (uncompressed) TIFF file on aFileName"
       
   275 
       
   276     |pos1 pos|
       
   277 
       
   278     outStream := FileStream newFileNamed:aFileName.
       
   279     outStream isNil ifTrue:[
       
   280 	'TIFFReader: create error' errorPrintNL. 
       
   281 	^ nil
       
   282     ].
       
   283 
       
   284     "save as msb"
       
   285 
       
   286     byteOrder := #msb.
       
   287 "
       
   288     byteOrder := #lsb.
       
   289 "
       
   290     fillOrder := #msb.
       
   291     width := image width.
       
   292     height := image height.
       
   293     photometric := image photometric.
       
   294     samplesPerPixel := image samplesPerPixel.
       
   295     bitsPerSample := image bitsPerSample.
       
   296     colorMap := image colorMap.
       
   297     planarConfiguration := 1.
       
   298     compression := 1.   "none"
       
   299     data := image bits.
       
   300 
       
   301     currentOffset := 0.
       
   302 
       
   303     (byteOrder == #msb) ifTrue:[
       
   304 	outStream nextPut:$M.
       
   305 	outStream nextPut:$M.
       
   306     ] ifFalse:[
       
   307 	outStream nextPut:$I.
       
   308 	outStream nextPut:$I.
       
   309     ].
       
   310     currentOffset := currentOffset + 2.
       
   311 
       
   312     outStream binary.
       
   313 
       
   314     self writeShort:42.
       
   315     currentOffset := currentOffset + 2.
       
   316 
       
   317     pos1 := outStream position.
       
   318     self writeLong:0.           "start of tags - filled in later"
       
   319     currentOffset := currentOffset + 4.
       
   320 
       
   321     "output strips"
       
   322 
       
   323     self writeUncompressedBits. "this outputs bits as strips, sets stripOffsets and stripByteCounts"
       
   324     self writeStripOffsets.     "this outputs strip offsets, sets stripOffsetsPos"
       
   325     self writeStripByteCounts.  "this outputs strip bytecounts, sets stripByteCountPos"
       
   326     self writeBitsPerSample.    "this outputs bitsPerSample, sets bitsPerSamplePos"
       
   327     photometric == #palette ifTrue:[
       
   328 	self writeColorMap      "this outputs colorMap, sets colorMapPos"
       
   329     ].
       
   330 
       
   331     pos := outStream position.                  "backpatch tag offset"
       
   332     outStream position:pos1.
       
   333     self writeLong:(pos - 1).                   "fill in tag offset"
       
   334     outStream position:pos.
       
   335 "
       
   336 ('patch tag offset at: ', (pos1 printStringRadix:16) , ' to ',
       
   337 			 (pos printStringRadix:16)) printNewline.
       
   338 "
       
   339     "output tag data"
       
   340 
       
   341     photometric == #palette ifTrue:[
       
   342 	self writeShort:10.  "10 tags"
       
   343     ] ifFalse:[
       
   344 	self writeShort:9.   "9 tags"
       
   345     ].
       
   346     self writeTag:256.               "image width"
       
   347     self writeTag:257.               "image height"
       
   348     self writeTag:258.               "bits per sample"
       
   349     self writeTag:259.               "compression"
       
   350     self writeTag:262.               "photometric"
       
   351     self writeTag:273.               "strip offsets"
       
   352     self writeTag:278.               "rowsPerStrip"
       
   353     self writeTag:279.               "strip byte counts"
       
   354     self writeTag:284.               "planarconfig"
       
   355     photometric == #palette ifTrue:[
       
   356 	self writeTag:320            "colorMap"
       
   357     ].
       
   358     self writeLong:0.                "end of tags mark"
       
   359     outStream close
       
   360 ! !
       
   361 
       
   362 !TIFFReader methodsFor:'private'!
   101 !TIFFReader methodsFor:'private'!
   363 
       
   364 readLongs:nLongs
       
   365     "read nLongs long numbers (32bit) and return them in an array"
       
   366 
       
   367     |oldPos offset values msb 
       
   368      n "{ Class: SmallInteger }" |
       
   369 
       
   370     n := nLongs.
       
   371 
       
   372     msb := byteOrder ~~ #lsb.
       
   373     values := Array basicNew:n.
       
   374     (n == 1) ifTrue:[
       
   375 	values at:1 put:(inStream nextLongMSB:msb).
       
   376     ] ifFalse:[
       
   377 	offset := inStream nextLongMSB:msb.
       
   378 	oldPos := inStream position.
       
   379 	inStream position:(offset + 1).
       
   380 	1 to:n do:[:index |
       
   381 	    values at:index put:(inStream nextLongMSB:msb)
       
   382 	].
       
   383 	inStream position:oldPos
       
   384     ].
       
   385     ^ values
       
   386 !
       
   387 
       
   388 readShorts:nShorts
       
   389     "read nShorts short numbers (16bit) and return them in an array"
       
   390 
       
   391     |oldPos offset values msb val2
       
   392      n "{ Class: SmallInteger }" |
       
   393 
       
   394     n := nShorts.
       
   395 
       
   396     msb := (byteOrder ~~ #lsb).
       
   397     values := Array basicNew:n.
       
   398     (n <= 2) ifTrue:[
       
   399 	values at:1 put:(inStream nextUnsignedShortMSB:msb).
       
   400 	val2 := inStream nextUnsignedShortMSB:msb.
       
   401 
       
   402 	(n == 2) ifTrue:[
       
   403 	    values at:2 put:val2
       
   404 	]
       
   405     ] ifFalse:[
       
   406 	offset := inStream nextLongMSB:msb.
       
   407 	oldPos := inStream position.
       
   408 	inStream position:(offset + 1).
       
   409 	1 to:n do:[:index |
       
   410 	    values at:index put:(inStream nextUnsignedShortMSB:msb)
       
   411 	].
       
   412 	inStream position:oldPos
       
   413     ].
       
   414     ^ values
       
   415 !
       
   416 
       
   417 readChars:n
       
   418     "read n characters and return them in a string"
       
   419 
       
   420     |oldPos offset string|
       
   421 
       
   422     string := String new:(n - 1).
       
   423     (n <= 4) ifTrue:[
       
   424 	inStream nextBytes:(n - 1) into:string
       
   425     ] ifFalse:[
       
   426 	offset := inStream nextLongMSB:(byteOrder ~~ #lsb).
       
   427 	oldPos := inStream position.
       
   428 	inStream position:(offset + 1).
       
   429 	inStream nextBytes:(n - 1) into:string.
       
   430 	inStream position:oldPos
       
   431     ].
       
   432     ^ string
       
   433 !
       
   434 
       
   435 readFracts:nFracts
       
   436     "read nFracts fractions (2 32bit words) and return them in an array"
       
   437 
       
   438     |oldPos offset values numerator denominator msb
       
   439      n "{ Class: SmallInteger }" |
       
   440 
       
   441     n := nFracts.
       
   442 
       
   443     msb := byteOrder ~~ #lsb.
       
   444     values := Array basicNew:n.
       
   445     offset := inStream nextLongMSB:msb.
       
   446     oldPos := inStream position.
       
   447     inStream position:(offset + 1).
       
   448     1 to:n do:[:index |
       
   449 	numerator := inStream nextLongMSB:msb.
       
   450 	denominator := inStream nextLongMSB:msb.
       
   451 	values at:index put:(Fraction numerator:numerator denominator:denominator)
       
   452     ].
       
   453     inStream position:oldPos.
       
   454     ^ values
       
   455 !
       
   456 
   102 
   457 decodeTiffTag:tagType numberType:numberType length:length
   103 decodeTiffTag:tagType numberType:numberType length:length
   458     |offset value valueArray 
   104     |offset value valueArray 
   459      val scaleFactor rV gV bV
   105      val scaleFactor rV gV bV
   460      n  "{ Class: SmallInteger }"
   106      n  "{ Class: SmallInteger }"
  1016 ' val:' print. value print. ' valArr:' print. valueArray printNewline.  
   662 ' val:' print. value print. ' valArr:' print. valueArray printNewline.  
  1017 "
   663 "
  1018     'TIFFReader: unknown tag type ' errorPrint. tagType errorPrintNL
   664     'TIFFReader: unknown tag type ' errorPrint. tagType errorPrintNL
  1019 !
   665 !
  1020 
   666 
  1021 writeUncompressedBits
   667 readCCITT3RLETiffImageData
  1022     "write bits as one or multiple strips"
   668      'TIFFReader: ccitt mod Huffman (rle) compression not implemented' errorPrintNL.
  1023 
   669 !
  1024     |offs bytesPerRow nBytes
   670 
  1025      h "{ Class: SmallInteger }"|
   671 readCCITT3RLEWTiffImageData
  1026 
   672      'TIFFReader: ccitt mod Huffman (rlew) compression not implemented' errorPrintNL.
  1027     nBytes := data size.
   673 !
  1028     nBytes < 16rFFFF ifTrue:[
   674 
  1029 	stripOffsets := Array with:(outStream position - 1).
   675 readCCITTGroup3TiffImageData
  1030 	stripByteCounts := Array with:nBytes.
   676     "not really tested - all I got is a single
  1031 	outStream nextPutBytes:nBytes from:data.
   677      fax from NeXT step"
  1032 	rowsPerStrip := height
   678 
       
   679     |bytesPerRow bitsPerRow compressedStrip nPlanes 
       
   680      stripNr       "{ Class: SmallInteger }"
       
   681      offset        "{ Class: SmallInteger }"
       
   682      row           "{ Class: SmallInteger }"
       
   683      bytesPerStrip "{ Class: SmallInteger }" |
       
   684 
       
   685     nPlanes := samplesPerPixel.
       
   686     (nPlanes == 2) ifTrue:[
       
   687 	'TIFFReader: ignoring alpha plane' errorPrintNL.
       
   688 	nPlanes := 1
       
   689     ].
       
   690 
       
   691     (nPlanes ~~ 1) ifTrue:[
       
   692 	self error:'only monochrome/greyscale supported'.
       
   693 	^ nil
       
   694     ].
       
   695 
       
   696     stripByteCounts isNil ifTrue:[
       
   697 	self error:'currently require stripByteCounts'.
       
   698 	^ nil
       
   699     ].
       
   700     (rowsPerStrip ~~ 1) isNil ifTrue:[
       
   701 	self error:'currently require rowsPerStrip to be 1'.
       
   702 	^ nil
       
   703     ].
       
   704 
       
   705     'TIFFReader: decompressing CCITT-3 ...' infoPrintNL.
       
   706 
       
   707     bitsPerRow := width * (bitsPerSample at:1).
       
   708     bytesPerRow := bitsPerRow // 8.
       
   709     ((bitsPerRow \\ 8) ~~ 0) ifTrue:[
       
   710 	bytesPerRow := bytesPerRow + 1
       
   711     ].
       
   712 
       
   713     data := ByteArray new:(bytesPerRow * height).
       
   714     compressedStrip := ByteArray uninitializedNew:bytesPerRow.
       
   715 
       
   716     offset := 1.
       
   717     stripNr := 0.
       
   718 
       
   719     row := 1.
       
   720     bytesPerStrip := bytesPerRow * rowsPerStrip.
       
   721     [row <= height] whileTrue:[
       
   722 	stripNr := stripNr + 1.
       
   723 	inStream position:((stripOffsets at:stripNr) + 1).
       
   724 	inStream nextBytes:(stripByteCounts at:stripNr) into:compressedStrip.
       
   725 	self class decompressCCITT3From:compressedStrip
       
   726 				   into:data
       
   727 			     startingAt:offset
       
   728 				  count:width.
       
   729 	offset := offset + bytesPerStrip.
       
   730 	row := row + rowsPerStrip
       
   731     ]
       
   732 !
       
   733 
       
   734 readCCITTGroup4TiffImageData
       
   735     'TIFFReader: ccitt group4 fax compression not implemented' errorPrintNL.
       
   736 !
       
   737 
       
   738 readChars:n
       
   739     "read n characters and return them in a string"
       
   740 
       
   741     |oldPos offset string|
       
   742 
       
   743     string := String new:(n - 1).
       
   744     (n <= 4) ifTrue:[
       
   745 	inStream nextBytes:(n - 1) into:string
  1033     ] ifFalse:[
   746     ] ifFalse:[
  1034 	stripOffsets := Array basicNew:height.
   747 	offset := inStream nextLongMSB:(byteOrder ~~ #lsb).
  1035 	bytesPerRow := nBytes // height.
   748 	oldPos := inStream position.
  1036 	stripByteCounts := (Array basicNew:height) atAllPut:bytesPerRow.
   749 	inStream position:(offset + 1).
  1037 
   750 	inStream nextBytes:(n - 1) into:string.
  1038 	offs := 1.
   751 	inStream position:oldPos
  1039 	h := height.
   752     ].
  1040 	1 to:h do:[:row |
   753     ^ string
  1041 	    stripOffsets at:row put:(outStream position - 1).
   754 !
  1042 	    outStream nextPutBytes:bytesPerRow from:data startingAt:offs.
   755 
  1043 	    offs := offs + bytesPerRow
   756 readFracts:nFracts
  1044 	].
   757     "read nFracts fractions (2 32bit words) and return them in an array"
  1045 	rowsPerStrip := 1
   758 
  1046     ].
   759     |oldPos offset values numerator denominator msb
  1047 "
   760      n "{ Class: SmallInteger }" |
  1048     'stripOffsets: ' print. stripOffsets printNewline.
   761 
  1049     'stripByteCounts: ' print. stripByteCounts printNewline.
   762     n := nFracts.
  1050 "
   763 
  1051 !
   764     msb := byteOrder ~~ #lsb.
  1052 
   765     values := Array basicNew:n.
  1053 writeColorMap
   766     offset := inStream nextLongMSB:msb.
  1054     |n|
   767     oldPos := inStream position.
  1055 
   768     inStream position:(offset + 1).
  1056     colorMapPos := outStream position.
   769     1 to:n do:[:index |
  1057     #(red green blue) do:[:component |
   770 	numerator := inStream nextLongMSB:msb.
  1058 	n := 0.
   771 	denominator := inStream nextLongMSB:msb.
  1059 	colorMap do:[:clr |
   772 	values at:index put:(Fraction numerator:numerator denominator:denominator)
  1060 	    |entry|
   773     ].
  1061 
   774     inStream position:oldPos.
  1062 	    clr isNil ifTrue:[
   775     ^ values
  1063 		entry := 0
   776 !
  1064 	    ] ifFalse:[
   777 
  1065 		entry := clr perform:component.
   778 readJPEGTiffImageData
  1066 		"
   779     'TIFFReader: jpeg compression not implemented' errorPrintNL
  1067 		 tiff map is 16 bit - scale from percent to 0..16rFFFF
   780 !
  1068 		"
   781 
  1069 		entry := (entry * 16rFFFF / 100) rounded.
   782 readLZWTiffImageData
       
   783     "read LZW compressed tiff data; this method only
       
   784      handles 3x8 rgb and 1x2 or 2x2 greyscale images.
       
   785      For 2x2 greyscale images, the alpha plane is ignored.
       
   786      (maybe other formats work also - its simply not
       
   787       tested)"
       
   788 
       
   789     |bytesPerRow compressedStrip nPlanes 
       
   790      bytesPerStrip "{ Class: SmallInteger }"
       
   791      nBytes        "{ Class: SmallInteger }"
       
   792      prevSize      "{ Class: SmallInteger }"
       
   793      stripNr       "{ Class: SmallInteger }"
       
   794      offset        "{ Class: SmallInteger }"
       
   795      row           "{ Class: SmallInteger }" |
       
   796 
       
   797     nPlanes := samplesPerPixel.
       
   798 
       
   799     (nPlanes == 3) ifTrue:[
       
   800 	((bitsPerSample at:1) ~~ 8) ifTrue:[
       
   801 	    self error:'only 8 bit/sample supported'.
       
   802 	    ^ nil
       
   803 	].
       
   804 	((bitsPerSample at:2) ~~ 8) ifTrue:[
       
   805 	    self error:'only 8 bit/sample supported'.
       
   806 	    ^ nil
       
   807 	].
       
   808 	((bitsPerSample at:3) ~~ 8) ifTrue:[
       
   809 	    self error:'only 8 bit/sample supported'.
       
   810 	    ^ nil
       
   811 	].
       
   812 	bytesPerRow := width * samplesPerPixel.
       
   813     ] ifFalse:[
       
   814 	(nPlanes == 2) ifTrue:[
       
   815 	    (planarConfiguration ~~ 2) ifTrue:[
       
   816 		self error:'only separate planes supported'.
       
   817 		^ nil
  1070 	    ].
   818 	    ].
  1071 	    self writeShort:entry.
   819 	    'TIFFReader: ignoring alpha plane' errorPrintNL.
  1072 	    n := n + 1
   820 	    nPlanes := 1
  1073 	].
   821 	].
  1074 	"
   822 	(nPlanes == 1) ifFalse:[
  1075 	 fill to 256 entries
   823 	    self error:'only 3-sample rgb / monochrome supported'.
  1076 	"
   824 	    ^ nil
  1077 	[n < 256] whileTrue:[
   825 	].
  1078 	    self writeShort:0.
   826 	bytesPerRow := (width * (bitsPerSample at:1) + 7) // 8.
  1079 	    n := n + 1.
   827     ].
       
   828 
       
   829     stripByteCounts isNil ifTrue:[
       
   830 	self error:'currently require stripByteCounts'.
       
   831 	^ nil
       
   832     ].
       
   833 
       
   834     'TIFFReader: decompressing LZW ...' infoPrintNL.
       
   835 
       
   836     data := ByteArray uninitializedNew:(bytesPerRow * height).
       
   837 
       
   838     offset := 1.
       
   839     stripNr := 0.
       
   840 
       
   841     row := 1.
       
   842     bytesPerStrip := bytesPerRow * rowsPerStrip.
       
   843     prevSize := 0.
       
   844     [row <= height] whileTrue:[
       
   845 	stripNr := stripNr + 1.
       
   846 	inStream position:((stripOffsets at:stripNr) + 1).
       
   847 	nBytes := stripByteCounts at:stripNr.
       
   848 	(nBytes > prevSize) ifTrue:[
       
   849 	    compressedStrip := ByteArray uninitializedNew:nBytes.
       
   850 	    prevSize := nBytes
       
   851 	].
       
   852 	inStream nextBytes:nBytes
       
   853 		      into:compressedStrip.
       
   854 	self class decompressLZWFrom:compressedStrip
       
   855 			       count:nBytes
       
   856 				into:data
       
   857 			  startingAt:offset.
       
   858 	offset := offset + bytesPerStrip.
       
   859 	row := row + rowsPerStrip
       
   860     ].
       
   861 
       
   862     (predictor == 2) ifTrue:[
       
   863 	self class decodeDelta:3 in:data width:width height:height
       
   864     ]
       
   865 !
       
   866 
       
   867 readLongs:nLongs
       
   868     "read nLongs long numbers (32bit) and return them in an array"
       
   869 
       
   870     |oldPos offset values msb 
       
   871      n "{ Class: SmallInteger }" |
       
   872 
       
   873     n := nLongs.
       
   874 
       
   875     msb := byteOrder ~~ #lsb.
       
   876     values := Array basicNew:n.
       
   877     (n == 1) ifTrue:[
       
   878 	values at:1 put:(inStream nextLongMSB:msb).
       
   879     ] ifFalse:[
       
   880 	offset := inStream nextLongMSB:msb.
       
   881 	oldPos := inStream position.
       
   882 	inStream position:(offset + 1).
       
   883 	1 to:n do:[:index |
       
   884 	    values at:index put:(inStream nextLongMSB:msb)
       
   885 	].
       
   886 	inStream position:oldPos
       
   887     ].
       
   888     ^ values
       
   889 !
       
   890 
       
   891 readNeXTJPEGTiffImageData
       
   892     'TIFFReader: jpeg compression not implemented' errorPrintNL
       
   893 !
       
   894 
       
   895 readNeXTRLE2TiffImageData
       
   896     'TIFFReader: next 2bit rle compression not implemented' errorPrintNL.
       
   897 !
       
   898 
       
   899 readPackbitsTiffImageData
       
   900     "had no samples yet - however, packbits decompression
       
   901      is rather trivial to add ..."
       
   902 
       
   903     'TIFFReader: packbits compression not implemented' errorPrintNL
       
   904 !
       
   905 
       
   906 readShorts:nShorts
       
   907     "read nShorts short numbers (16bit) and return them in an array"
       
   908 
       
   909     |oldPos offset values msb val2
       
   910      n "{ Class: SmallInteger }" |
       
   911 
       
   912     n := nShorts.
       
   913 
       
   914     msb := (byteOrder ~~ #lsb).
       
   915     values := Array basicNew:n.
       
   916     (n <= 2) ifTrue:[
       
   917 	values at:1 put:(inStream nextUnsignedShortMSB:msb).
       
   918 	val2 := inStream nextUnsignedShortMSB:msb.
       
   919 
       
   920 	(n == 2) ifTrue:[
       
   921 	    values at:2 put:val2
  1080 	]
   922 	]
  1081     ]
       
  1082 !
       
  1083 
       
  1084 writeStripOffsets
       
  1085 "
       
  1086 'stripOffsets: ' print. stripOffsets printNewline.
       
  1087 'store stripoffsets at: ' print. outStream position printNewline.
       
  1088 "
       
  1089     stripOffsetsPos := outStream position.
       
  1090     stripOffsets do:[:o |
       
  1091 	self writeLong:o
       
  1092     ]
       
  1093 !
       
  1094 
       
  1095 writeStripByteCounts
       
  1096 "
       
  1097 'stripByteCounts: ' print. stripByteCounts printNewline.
       
  1098 'store stripbytecounts at: ' print. outStream position printNewline.
       
  1099 "
       
  1100     stripByteCountsPos := outStream position.
       
  1101     stripByteCounts do:[:c |
       
  1102 	self writeShort:c
       
  1103     ]
       
  1104 !
       
  1105 
       
  1106 writeBitsPerSample
       
  1107 "
       
  1108 'bitsPerSample: ' print. bitsPerSample printNewline.
       
  1109 'store bitspersample at: ' print. outStream position printNewline.
       
  1110 "
       
  1111     bitsPerSamplePos := outStream position.
       
  1112     bitsPerSample do:[:n |
       
  1113 	self writeShort:n
       
  1114     ]
       
  1115 !
       
  1116 
       
  1117 writeTag:tagType
       
  1118     self writeTiffTag:tagType.
       
  1119 !
       
  1120 
       
  1121 writeTiffTag:tagType
       
  1122     |value valueArray numberType count address|
       
  1123 
       
  1124     count := 1.
       
  1125     address := nil.
       
  1126     (tagType == 253) ifTrue:[
       
  1127 	"tiff class"
       
  1128     ].
       
  1129     (tagType == 254) ifTrue:[
       
  1130     ].
       
  1131     (tagType == 255) ifTrue:[
       
  1132 	"SubfileType"
       
  1133 	value := subFileType.
       
  1134 	numberType := #long.
       
  1135     ].
       
  1136     (tagType == 256) ifTrue:[
       
  1137 	"ImageWidth"
       
  1138 	value := width.
       
  1139 	numberType := #short.
       
  1140     ].
       
  1141     (tagType == 257) ifTrue:[
       
  1142 	"ImageHeight"
       
  1143 	value := height.
       
  1144 	numberType := #short.
       
  1145     ].
       
  1146     (tagType == 258) ifTrue:[
       
  1147 	"bitspersample"
       
  1148 	address := bitsPerSamplePos - 1.
       
  1149 	numberType := #short.
       
  1150 	count := bitsPerSample size.
       
  1151 	valueArray := bitsPerSample
       
  1152     ].
       
  1153     (tagType == 259) ifTrue:[
       
  1154 	"compression"
       
  1155 	value := compression.
       
  1156 	numberType := #short.
       
  1157     ].
       
  1158     (tagType == 262) ifTrue:[
       
  1159 	"photometric"
       
  1160 	(photometric == #whiteIs0) ifTrue:[
       
  1161 	  value := 0
       
  1162 	] ifFalse:[
       
  1163 	  (photometric == #blackIs0) ifTrue:[
       
  1164 	    value := 1
       
  1165 	  ] ifFalse:[
       
  1166 	    (photometric == #rgb) ifTrue:[
       
  1167 	      value := 2
       
  1168 	    ] ifFalse:[
       
  1169 	      (photometric == #palette) ifTrue:[
       
  1170 		value := 3
       
  1171 	      ] ifFalse:[
       
  1172 		(photometric == #transparency) ifTrue:[
       
  1173 		  value := 4
       
  1174 		] ifFalse:[
       
  1175 		  self error:'bad photometric'
       
  1176 		]
       
  1177 	      ]
       
  1178 	    ]
       
  1179 	  ]
       
  1180 	].
       
  1181 	numberType := #short.
       
  1182     ].
       
  1183     (tagType == 263) ifTrue:[
       
  1184     ].
       
  1185     (tagType == 264) ifTrue:[
       
  1186     ].
       
  1187     (tagType == 265) ifTrue:[
       
  1188     ].
       
  1189     (tagType == 266) ifTrue:[
       
  1190 	"fillOrder"
       
  1191 	(fillOrder == #msb) ifTrue:[
       
  1192 	    value := 1
       
  1193 	] ifFalse:[
       
  1194 	  (fillOrder == #lsb) ifTrue:[
       
  1195 	    value := 2
       
  1196 	  ] ifFalse:[
       
  1197 	    self error:'bad fillOrder'
       
  1198 	  ]
       
  1199 	].
       
  1200 	numberType := #short.
       
  1201     ].
       
  1202     (tagType == 269) ifTrue:[
       
  1203     ].
       
  1204     (tagType == 270) ifTrue:[
       
  1205     ].
       
  1206     (tagType == 271) ifTrue:[
       
  1207     ].
       
  1208     (tagType == 272) ifTrue:[
       
  1209     ].
       
  1210     (tagType == 273) ifTrue:[
       
  1211 	"stripoffsets"
       
  1212 	address := stripOffsetsPos - 1.
       
  1213 	numberType := #long.
       
  1214 	count := stripOffsets size.
       
  1215 	valueArray := stripOffsets
       
  1216     ].
       
  1217     (tagType == 274) ifTrue:[
       
  1218     ].
       
  1219     (tagType == 277) ifTrue:[
       
  1220 	"samplesPerPixel"
       
  1221 	value := samplesPerPixel.
       
  1222 	numberType := #short.
       
  1223     ].
       
  1224     (tagType == 278) ifTrue:[
       
  1225 	"rowsperstrip"
       
  1226 	value := rowsPerStrip.
       
  1227 	numberType := #short.
       
  1228     ].
       
  1229     (tagType == 279) ifTrue:[
       
  1230 	"stripbytecount"
       
  1231 	address := stripByteCountsPos - 1.
       
  1232 	numberType := #short.
       
  1233 	count := stripByteCounts size.
       
  1234 	valueArray := stripByteCounts
       
  1235     ].
       
  1236     (tagType == 280) ifTrue:[
       
  1237 	"min sample value"
       
  1238     ].
       
  1239     (tagType == 281) ifTrue:[
       
  1240 	"max sample value"
       
  1241     ].
       
  1242     (tagType == 282) ifTrue:[
       
  1243 	"x resolution"
       
  1244     ].
       
  1245     (tagType == 283) ifTrue:[
       
  1246 	"y resolution"
       
  1247     ].
       
  1248     (tagType == 284) ifTrue:[
       
  1249 	"planarconfig"
       
  1250 	value := planarConfiguration.
       
  1251 	numberType := #short.
       
  1252     ].
       
  1253     (tagType == 285) ifTrue:[
       
  1254 	"pageName"
       
  1255     ].
       
  1256     (tagType == 286) ifTrue:[
       
  1257 	"xPosition"
       
  1258     ].
       
  1259     (tagType == 287) ifTrue:[
       
  1260 	"yPosition"
       
  1261     ].
       
  1262     (tagType == 288) ifTrue:[
       
  1263 	"freeOffsets"
       
  1264     ].
       
  1265     (tagType == 289) ifTrue:[
       
  1266 	"freeByteCounts"
       
  1267     ].
       
  1268     (tagType == 290) ifTrue:[
       
  1269 	"grayResponceUnit"
       
  1270     ].
       
  1271     (tagType == 291) ifTrue:[
       
  1272 	"grayResponceCurve"
       
  1273     ].
       
  1274     (tagType == 292) ifTrue:[
       
  1275 	"group3options"
       
  1276 	value := group3options.
       
  1277 	numberType := #long.
       
  1278     ].
       
  1279     (tagType == 293) ifTrue:[
       
  1280 	"group4options"
       
  1281     ].
       
  1282     (tagType == 296) ifTrue:[
       
  1283 	"resolutionunit"
       
  1284 	^ self
       
  1285     ].
       
  1286     (tagType == 297) ifTrue:[
       
  1287 	"pageNumber"
       
  1288     ].
       
  1289     (tagType == 300) ifTrue:[
       
  1290 	"colorResponceUnit"
       
  1291     ].
       
  1292     (tagType == 301) ifTrue:[
       
  1293 	"colorResponceCurve"
       
  1294     ].
       
  1295     (tagType == 306) ifTrue:[
       
  1296 	"dateTime"
       
  1297     ].
       
  1298     (tagType == 315) ifTrue:[
       
  1299 	"artist"
       
  1300     ].
       
  1301     (tagType == 317) ifTrue:[
       
  1302 	"predictor"
       
  1303     ].
       
  1304     (tagType == 320) ifTrue:[
       
  1305 	"colormap"
       
  1306 	address := colorMapPos - 1.
       
  1307 	numberType := #short.
       
  1308 	count := 256 "(colorMap at:1) size" * 3.
       
  1309     ].
       
  1310 
       
  1311     (value isNil and:[address isNil]) ifTrue:[
       
  1312 	self error:'unhandled tag'.
       
  1313 	^ self
       
  1314     ].
       
  1315 
       
  1316 "
       
  1317 'tag:' print. tagType print. ' typ:' print. numberType print.
       
  1318 ' len:' print. count print.
       
  1319 ' val:' print. value printNewline.  
       
  1320 "
       
  1321 
       
  1322     self writeShort:tagType.
       
  1323     numberType == #short ifTrue:[
       
  1324 	self writeShort:3.
       
  1325 	self writeLong:count.
       
  1326     ] ifFalse:[
   923     ] ifFalse:[
  1327 	numberType == #long ifTrue:[
   924 	offset := inStream nextLongMSB:msb.
  1328 	    self writeShort:4.
   925 	oldPos := inStream position.
  1329 	    self writeLong:count.
   926 	inStream position:(offset + 1).
  1330 	] ifFalse:[
   927 	1 to:n do:[:index |
  1331 	    numberType == #byte ifTrue:[
   928 	    values at:index put:(inStream nextUnsignedShortMSB:msb)
  1332 		self writeShort:1.
   929 	].
  1333 		self writeLong:count.
   930 	inStream position:oldPos
  1334 	    ] ifFalse:[
   931     ].
  1335 		self error:'bad numbertype'
   932     ^ values
  1336 	    ]
       
  1337 	]
       
  1338     ].
       
  1339     address notNil ifTrue:[
       
  1340 	(numberType == #long and:[count == 1]) ifTrue:[
       
  1341 	    self writeLong:(valueArray at:1).
       
  1342 	    ^ self
       
  1343 	].
       
  1344 	(numberType == #short and:[count <= 2]) ifTrue:[
       
  1345 	    self writeShort:(valueArray at:1).
       
  1346 	    count == 2 ifTrue:[
       
  1347 		self writeShort:(valueArray at:2).
       
  1348 	    ] ifFalse:[
       
  1349 		self writeShort:0
       
  1350 	    ].
       
  1351 	    ^ self
       
  1352 	].
       
  1353 	(numberType == #byte and:[count <= 4]) ifTrue:[
       
  1354 	    outStream nextPut:(valueArray at:1).
       
  1355 	    count > 1 ifTrue:[
       
  1356 		outStream nextPut:(valueArray at:2).
       
  1357 		count > 2 ifTrue:[
       
  1358 		    outStream nextPut:(valueArray at:3).
       
  1359 		    count > 3 ifTrue:[
       
  1360 			outStream nextPut:(valueArray at:4).
       
  1361 		    ] ifFalse:[
       
  1362 			outStream nextPut:0
       
  1363 		    ].
       
  1364 		] ifFalse:[
       
  1365 		    outStream nextPut:0
       
  1366 		].
       
  1367 	    ] ifFalse:[
       
  1368 		outStream nextPut:0
       
  1369 	    ].
       
  1370 	    ^ self
       
  1371 	].
       
  1372 	self writeLong:address.
       
  1373 	^ self
       
  1374     ].
       
  1375     numberType == #short ifTrue:[
       
  1376 	self writeShort:value.
       
  1377 	self writeShort:0
       
  1378     ] ifFalse:[
       
  1379 	numberType == #long ifTrue:[
       
  1380 	    self writeLong:value
       
  1381 	] ifFalse:[
       
  1382 	    numberType == #byte ifTrue:[
       
  1383 		outStream nextPut:value.
       
  1384 		outStream nextPut:0.
       
  1385 		outStream nextPut:0.
       
  1386 		outStream nextPut:0.
       
  1387 	    ] ifFalse:[
       
  1388 		self error:'bad numbertype'
       
  1389 	    ]
       
  1390 	]
       
  1391     ].
       
  1392 !
   933 !
  1393 
   934 
  1394 readUncompressedTiffImageData
   935 readUncompressedTiffImageData
  1395     |bytesPerRow bitsPerRow nPlanes 
   936     |bytesPerRow bitsPerRow nPlanes 
  1396      stripNr       "{ Class: SmallInteger }"
   937      stripNr       "{ Class: SmallInteger }"
  1457 	offset := offset + nBytes.
   998 	offset := offset + nBytes.
  1458 	row := row + rowsPerStrip
   999 	row := row + rowsPerStrip
  1459     ]
  1000     ]
  1460 !
  1001 !
  1461 
  1002 
  1462 readLZWTiffImageData
  1003 writeBitsPerSample
  1463     "read LZW compressed tiff data; this method only
  1004 "
  1464      handles 3x8 rgb and 1x2 or 2x2 greyscale images.
  1005 'bitsPerSample: ' print. bitsPerSample printNewline.
  1465      For 2x2 greyscale images, the alpha plane is ignored.
  1006 'store bitspersample at: ' print. outStream position printNewline.
  1466      (maybe other formats work also - its simply not
  1007 "
  1467       tested)"
  1008     bitsPerSamplePos := outStream position.
  1468 
  1009     bitsPerSample do:[:n |
  1469     |bytesPerRow compressedStrip nPlanes 
  1010 	self writeShort:n
  1470      bytesPerStrip "{ Class: SmallInteger }"
  1011     ]
  1471      nBytes        "{ Class: SmallInteger }"
  1012 !
  1472      prevSize      "{ Class: SmallInteger }"
  1013 
  1473      stripNr       "{ Class: SmallInteger }"
  1014 writeColorMap
  1474      offset        "{ Class: SmallInteger }"
  1015     |n|
  1475      row           "{ Class: SmallInteger }" |
  1016 
  1476 
  1017     colorMapPos := outStream position.
  1477     nPlanes := samplesPerPixel.
  1018     #(red green blue) do:[:component |
  1478 
  1019 	n := 0.
  1479     (nPlanes == 3) ifTrue:[
  1020 	colorMap do:[:clr |
  1480 	((bitsPerSample at:1) ~~ 8) ifTrue:[
  1021 	    |entry|
  1481 	    self error:'only 8 bit/sample supported'.
  1022 
       
  1023 	    clr isNil ifTrue:[
       
  1024 		entry := 0
       
  1025 	    ] ifFalse:[
       
  1026 		entry := clr perform:component.
       
  1027 		"
       
  1028 		 tiff map is 16 bit - scale from percent to 0..16rFFFF
       
  1029 		"
       
  1030 		entry := (entry * 16rFFFF / 100) rounded.
       
  1031 	    ].
       
  1032 	    self writeShort:entry.
       
  1033 	    n := n + 1
       
  1034 	].
       
  1035 	"
       
  1036 	 fill to 256 entries
       
  1037 	"
       
  1038 	[n < 256] whileTrue:[
       
  1039 	    self writeShort:0.
       
  1040 	    n := n + 1.
       
  1041 	]
       
  1042     ]
       
  1043 !
       
  1044 
       
  1045 writeStripByteCounts
       
  1046 "
       
  1047 'stripByteCounts: ' print. stripByteCounts printNewline.
       
  1048 'store stripbytecounts at: ' print. outStream position printNewline.
       
  1049 "
       
  1050     stripByteCountsPos := outStream position.
       
  1051     stripByteCounts do:[:c |
       
  1052 	self writeShort:c
       
  1053     ]
       
  1054 !
       
  1055 
       
  1056 writeStripOffsets
       
  1057 "
       
  1058 'stripOffsets: ' print. stripOffsets printNewline.
       
  1059 'store stripoffsets at: ' print. outStream position printNewline.
       
  1060 "
       
  1061     stripOffsetsPos := outStream position.
       
  1062     stripOffsets do:[:o |
       
  1063 	self writeLong:o
       
  1064     ]
       
  1065 !
       
  1066 
       
  1067 writeTag:tagType
       
  1068     self writeTiffTag:tagType.
       
  1069 !
       
  1070 
       
  1071 writeTiffTag:tagType
       
  1072     |value valueArray numberType count address|
       
  1073 
       
  1074     count := 1.
       
  1075     address := nil.
       
  1076     (tagType == 253) ifTrue:[
       
  1077 	"tiff class"
       
  1078     ].
       
  1079     (tagType == 254) ifTrue:[
       
  1080     ].
       
  1081     (tagType == 255) ifTrue:[
       
  1082 	"SubfileType"
       
  1083 	value := subFileType.
       
  1084 	numberType := #long.
       
  1085     ].
       
  1086     (tagType == 256) ifTrue:[
       
  1087 	"ImageWidth"
       
  1088 	value := width.
       
  1089 	numberType := #short.
       
  1090     ].
       
  1091     (tagType == 257) ifTrue:[
       
  1092 	"ImageHeight"
       
  1093 	value := height.
       
  1094 	numberType := #short.
       
  1095     ].
       
  1096     (tagType == 258) ifTrue:[
       
  1097 	"bitspersample"
       
  1098 	address := bitsPerSamplePos - 1.
       
  1099 	numberType := #short.
       
  1100 	count := bitsPerSample size.
       
  1101 	valueArray := bitsPerSample
       
  1102     ].
       
  1103     (tagType == 259) ifTrue:[
       
  1104 	"compression"
       
  1105 	value := compression.
       
  1106 	numberType := #short.
       
  1107     ].
       
  1108     (tagType == 262) ifTrue:[
       
  1109 	"photometric"
       
  1110 	(photometric == #whiteIs0) ifTrue:[
       
  1111 	  value := 0
       
  1112 	] ifFalse:[
       
  1113 	  (photometric == #blackIs0) ifTrue:[
       
  1114 	    value := 1
       
  1115 	  ] ifFalse:[
       
  1116 	    (photometric == #rgb) ifTrue:[
       
  1117 	      value := 2
       
  1118 	    ] ifFalse:[
       
  1119 	      (photometric == #palette) ifTrue:[
       
  1120 		value := 3
       
  1121 	      ] ifFalse:[
       
  1122 		(photometric == #transparency) ifTrue:[
       
  1123 		  value := 4
       
  1124 		] ifFalse:[
       
  1125 		  self error:'bad photometric'
       
  1126 		]
       
  1127 	      ]
       
  1128 	    ]
       
  1129 	  ]
       
  1130 	].
       
  1131 	numberType := #short.
       
  1132     ].
       
  1133     (tagType == 263) ifTrue:[
       
  1134     ].
       
  1135     (tagType == 264) ifTrue:[
       
  1136     ].
       
  1137     (tagType == 265) ifTrue:[
       
  1138     ].
       
  1139     (tagType == 266) ifTrue:[
       
  1140 	"fillOrder"
       
  1141 	(fillOrder == #msb) ifTrue:[
       
  1142 	    value := 1
       
  1143 	] ifFalse:[
       
  1144 	  (fillOrder == #lsb) ifTrue:[
       
  1145 	    value := 2
       
  1146 	  ] ifFalse:[
       
  1147 	    self error:'bad fillOrder'
       
  1148 	  ]
       
  1149 	].
       
  1150 	numberType := #short.
       
  1151     ].
       
  1152     (tagType == 269) ifTrue:[
       
  1153     ].
       
  1154     (tagType == 270) ifTrue:[
       
  1155     ].
       
  1156     (tagType == 271) ifTrue:[
       
  1157     ].
       
  1158     (tagType == 272) ifTrue:[
       
  1159     ].
       
  1160     (tagType == 273) ifTrue:[
       
  1161 	"stripoffsets"
       
  1162 	address := stripOffsetsPos - 1.
       
  1163 	numberType := #long.
       
  1164 	count := stripOffsets size.
       
  1165 	valueArray := stripOffsets
       
  1166     ].
       
  1167     (tagType == 274) ifTrue:[
       
  1168     ].
       
  1169     (tagType == 277) ifTrue:[
       
  1170 	"samplesPerPixel"
       
  1171 	value := samplesPerPixel.
       
  1172 	numberType := #short.
       
  1173     ].
       
  1174     (tagType == 278) ifTrue:[
       
  1175 	"rowsperstrip"
       
  1176 	value := rowsPerStrip.
       
  1177 	numberType := #short.
       
  1178     ].
       
  1179     (tagType == 279) ifTrue:[
       
  1180 	"stripbytecount"
       
  1181 	address := stripByteCountsPos - 1.
       
  1182 	numberType := #short.
       
  1183 	count := stripByteCounts size.
       
  1184 	valueArray := stripByteCounts
       
  1185     ].
       
  1186     (tagType == 280) ifTrue:[
       
  1187 	"min sample value"
       
  1188     ].
       
  1189     (tagType == 281) ifTrue:[
       
  1190 	"max sample value"
       
  1191     ].
       
  1192     (tagType == 282) ifTrue:[
       
  1193 	"x resolution"
       
  1194     ].
       
  1195     (tagType == 283) ifTrue:[
       
  1196 	"y resolution"
       
  1197     ].
       
  1198     (tagType == 284) ifTrue:[
       
  1199 	"planarconfig"
       
  1200 	value := planarConfiguration.
       
  1201 	numberType := #short.
       
  1202     ].
       
  1203     (tagType == 285) ifTrue:[
       
  1204 	"pageName"
       
  1205     ].
       
  1206     (tagType == 286) ifTrue:[
       
  1207 	"xPosition"
       
  1208     ].
       
  1209     (tagType == 287) ifTrue:[
       
  1210 	"yPosition"
       
  1211     ].
       
  1212     (tagType == 288) ifTrue:[
       
  1213 	"freeOffsets"
       
  1214     ].
       
  1215     (tagType == 289) ifTrue:[
       
  1216 	"freeByteCounts"
       
  1217     ].
       
  1218     (tagType == 290) ifTrue:[
       
  1219 	"grayResponceUnit"
       
  1220     ].
       
  1221     (tagType == 291) ifTrue:[
       
  1222 	"grayResponceCurve"
       
  1223     ].
       
  1224     (tagType == 292) ifTrue:[
       
  1225 	"group3options"
       
  1226 	value := group3options.
       
  1227 	numberType := #long.
       
  1228     ].
       
  1229     (tagType == 293) ifTrue:[
       
  1230 	"group4options"
       
  1231     ].
       
  1232     (tagType == 296) ifTrue:[
       
  1233 	"resolutionunit"
       
  1234 	^ self
       
  1235     ].
       
  1236     (tagType == 297) ifTrue:[
       
  1237 	"pageNumber"
       
  1238     ].
       
  1239     (tagType == 300) ifTrue:[
       
  1240 	"colorResponceUnit"
       
  1241     ].
       
  1242     (tagType == 301) ifTrue:[
       
  1243 	"colorResponceCurve"
       
  1244     ].
       
  1245     (tagType == 306) ifTrue:[
       
  1246 	"dateTime"
       
  1247     ].
       
  1248     (tagType == 315) ifTrue:[
       
  1249 	"artist"
       
  1250     ].
       
  1251     (tagType == 317) ifTrue:[
       
  1252 	"predictor"
       
  1253     ].
       
  1254     (tagType == 320) ifTrue:[
       
  1255 	"colormap"
       
  1256 	address := colorMapPos - 1.
       
  1257 	numberType := #short.
       
  1258 	count := 256 "(colorMap at:1) size" * 3.
       
  1259     ].
       
  1260 
       
  1261     (value isNil and:[address isNil]) ifTrue:[
       
  1262 	self error:'unhandled tag'.
       
  1263 	^ self
       
  1264     ].
       
  1265 
       
  1266 "
       
  1267 'tag:' print. tagType print. ' typ:' print. numberType print.
       
  1268 ' len:' print. count print.
       
  1269 ' val:' print. value printNewline.  
       
  1270 "
       
  1271 
       
  1272     self writeShort:tagType.
       
  1273     numberType == #short ifTrue:[
       
  1274 	self writeShort:3.
       
  1275 	self writeLong:count.
       
  1276     ] ifFalse:[
       
  1277 	numberType == #long ifTrue:[
       
  1278 	    self writeShort:4.
       
  1279 	    self writeLong:count.
       
  1280 	] ifFalse:[
       
  1281 	    numberType == #byte ifTrue:[
       
  1282 		self writeShort:1.
       
  1283 		self writeLong:count.
       
  1284 	    ] ifFalse:[
       
  1285 		self error:'bad numbertype'
       
  1286 	    ]
       
  1287 	]
       
  1288     ].
       
  1289     address notNil ifTrue:[
       
  1290 	(numberType == #long and:[count == 1]) ifTrue:[
       
  1291 	    self writeLong:(valueArray at:1).
       
  1292 	    ^ self
       
  1293 	].
       
  1294 	(numberType == #short and:[count <= 2]) ifTrue:[
       
  1295 	    self writeShort:(valueArray at:1).
       
  1296 	    count == 2 ifTrue:[
       
  1297 		self writeShort:(valueArray at:2).
       
  1298 	    ] ifFalse:[
       
  1299 		self writeShort:0
       
  1300 	    ].
       
  1301 	    ^ self
       
  1302 	].
       
  1303 	(numberType == #byte and:[count <= 4]) ifTrue:[
       
  1304 	    outStream nextPut:(valueArray at:1).
       
  1305 	    count > 1 ifTrue:[
       
  1306 		outStream nextPut:(valueArray at:2).
       
  1307 		count > 2 ifTrue:[
       
  1308 		    outStream nextPut:(valueArray at:3).
       
  1309 		    count > 3 ifTrue:[
       
  1310 			outStream nextPut:(valueArray at:4).
       
  1311 		    ] ifFalse:[
       
  1312 			outStream nextPut:0
       
  1313 		    ].
       
  1314 		] ifFalse:[
       
  1315 		    outStream nextPut:0
       
  1316 		].
       
  1317 	    ] ifFalse:[
       
  1318 		outStream nextPut:0
       
  1319 	    ].
       
  1320 	    ^ self
       
  1321 	].
       
  1322 	self writeLong:address.
       
  1323 	^ self
       
  1324     ].
       
  1325     numberType == #short ifTrue:[
       
  1326 	self writeShort:value.
       
  1327 	self writeShort:0
       
  1328     ] ifFalse:[
       
  1329 	numberType == #long ifTrue:[
       
  1330 	    self writeLong:value
       
  1331 	] ifFalse:[
       
  1332 	    numberType == #byte ifTrue:[
       
  1333 		outStream nextPut:value.
       
  1334 		outStream nextPut:0.
       
  1335 		outStream nextPut:0.
       
  1336 		outStream nextPut:0.
       
  1337 	    ] ifFalse:[
       
  1338 		self error:'bad numbertype'
       
  1339 	    ]
       
  1340 	]
       
  1341     ].
       
  1342 !
       
  1343 
       
  1344 writeUncompressedBits
       
  1345     "write bits as one or multiple strips"
       
  1346 
       
  1347     |offs bytesPerRow nBytes
       
  1348      h "{ Class: SmallInteger }"|
       
  1349 
       
  1350     nBytes := data size.
       
  1351     nBytes < 16rFFFF ifTrue:[
       
  1352 	stripOffsets := Array with:(outStream position - 1).
       
  1353 	stripByteCounts := Array with:nBytes.
       
  1354 	outStream nextPutBytes:nBytes from:data.
       
  1355 	rowsPerStrip := height
       
  1356     ] ifFalse:[
       
  1357 	stripOffsets := Array basicNew:height.
       
  1358 	bytesPerRow := nBytes // height.
       
  1359 	stripByteCounts := (Array basicNew:height) atAllPut:bytesPerRow.
       
  1360 
       
  1361 	offs := 1.
       
  1362 	h := height.
       
  1363 	1 to:h do:[:row |
       
  1364 	    stripOffsets at:row put:(outStream position - 1).
       
  1365 	    outStream nextPutBytes:bytesPerRow from:data startingAt:offs.
       
  1366 	    offs := offs + bytesPerRow
       
  1367 	].
       
  1368 	rowsPerStrip := 1
       
  1369     ].
       
  1370 "
       
  1371     'stripOffsets: ' print. stripOffsets printNewline.
       
  1372     'stripByteCounts: ' print. stripByteCounts printNewline.
       
  1373 "
       
  1374 ! !
       
  1375 
       
  1376 !TIFFReader methodsFor:'reading from file'!
       
  1377 
       
  1378 fromStream:aStream
       
  1379     "read an image from aStream"
       
  1380 
       
  1381     |char1 char2 version 
       
  1382      numberOfTags "{ Class: SmallInteger }"
       
  1383      tagType      "{ Class: SmallInteger }"
       
  1384      numberType   "{ Class: SmallInteger }"
       
  1385      length       "{ Class: SmallInteger }"
       
  1386      result offset ok msb|
       
  1387 
       
  1388     inStream := aStream.
       
  1389 
       
  1390     char1 := aStream next.
       
  1391     char2 := aStream next.
       
  1392     (char1 ~~ char2) ifTrue:[
       
  1393 	'TIFFReader: not a tiff file' errorPrintNL.
       
  1394 	^ nil
       
  1395     ].
       
  1396     (char1 == $I) ifTrue:[
       
  1397 	byteOrder := #lsb.
       
  1398 	msb := false.
       
  1399     ] ifFalse:[
       
  1400 	(char1 == $M) ifTrue:[
       
  1401 	    byteOrder := #msb.
       
  1402 	    msb := true.
       
  1403 	] ifFalse:[
       
  1404 	    'TIFFReader: not a tiff file' errorPrintNL.
  1482 	    ^ nil
  1405 	    ^ nil
  1483 	].
  1406 	]
  1484 	((bitsPerSample at:2) ~~ 8) ifTrue:[
  1407     ].
  1485 	    self error:'only 8 bit/sample supported'.
  1408 
  1486 	    ^ nil
  1409     aStream binary.
  1487 	].
  1410 
  1488 	((bitsPerSample at:3) ~~ 8) ifTrue:[
  1411     version := self readShort.
  1489 	    self error:'only 8 bit/sample supported'.
  1412     (version ~~ 42) ifTrue:[
  1490 	    ^ nil
  1413 	'TIFFReader: version of tiff-file not supported' errorPrintNL.
  1491 	].
  1414 	^ nil
  1492 	bytesPerRow := width * samplesPerPixel.
  1415     ].
       
  1416 
       
  1417     "setup default values"
       
  1418 
       
  1419     compression := 1. "none"
       
  1420     fillOrder := #msb.
       
  1421     planarConfiguration := 1.
       
  1422     photometric := nil.
       
  1423     bitsPerSample := 1.
       
  1424     samplesPerPixel := 1.
       
  1425     width := nil.
       
  1426     height := nil.
       
  1427     stripOffsets := nil.
       
  1428     rowsPerStrip := nil.
       
  1429     "resolutionUnit := 2."
       
  1430     predictor := 1.
       
  1431 
       
  1432     offset := aStream nextLongMSB:msb.
       
  1433     aStream position:offset + 1.
       
  1434 
       
  1435     numberOfTags := self readShort.
       
  1436     1 to:numberOfTags do:[:index |
       
  1437 	tagType := self readShort.
       
  1438 	numberType := self readShort.
       
  1439 	length := aStream nextLongMSB:msb.
       
  1440 	self decodeTiffTag:tagType numberType:numberType length:length
       
  1441     ].
       
  1442 
       
  1443     offset := aStream nextLongMSB:msb.
       
  1444     (offset ~~ 0) ifTrue:[
       
  1445 	'TIFFReader: more tags ignored' errorPrintNL
       
  1446     ].
       
  1447 
       
  1448     "check for required tags"
       
  1449     ok := true.
       
  1450     width isNil ifTrue:[
       
  1451 	'TIFFReader: missing width tag' errorPrintNL.
       
  1452 	ok := false
       
  1453     ].
       
  1454 
       
  1455     height isNil ifTrue:[
       
  1456 	'TIFFReader: missing length tag' errorPrintNL.
       
  1457 	ok := false
       
  1458     ].
       
  1459 
       
  1460     photometric isNil ifTrue:[
       
  1461 	'TIFFReader: missing photometric tag' errorPrintNL.
       
  1462 	ok := false
       
  1463     ].
       
  1464 
       
  1465     stripOffsets isNil ifTrue:[
       
  1466 	'TIFFReader: missing stripOffsets tag' errorPrintNL.
       
  1467 	ok := false
       
  1468     ].
       
  1469 
       
  1470     stripByteCounts isNil ifTrue:[
       
  1471 	stripOffsets size == 1 ifTrue:[
       
  1472 	    stripByteCounts := Array with:(self bitsPerPixel // 8) * width * height
       
  1473 	]
       
  1474     ].
       
  1475 
       
  1476     stripByteCounts isNil ifTrue:[
       
  1477 	'TIFFReader: missing stripByteCounts tag' errorPrintNL.
       
  1478 	ok := false
       
  1479     ].
       
  1480 
       
  1481     ok ifFalse:[
       
  1482 	^ nil
       
  1483     ].
       
  1484 
       
  1485     "given all the information, read the bits"
       
  1486 
       
  1487     rowsPerStrip isNil ifTrue:[
       
  1488 	rowsPerStrip := height
       
  1489     ].
       
  1490 
       
  1491     ok := false.
       
  1492     (compression == 1) ifTrue:[
       
  1493 	result := self readUncompressedTiffImageData.
       
  1494 	ok := true
       
  1495     ].
       
  1496     (compression == 2) ifTrue:[
       
  1497 	result := self readCCITT3RLETiffImageData.
       
  1498 	ok := true
       
  1499     ].
       
  1500     (compression == 3) ifTrue:[
       
  1501 	result := self readCCITTGroup3TiffImageData.
       
  1502 	ok := true
       
  1503     ]. 
       
  1504     (compression == 4) ifTrue:[
       
  1505 	result := self readCCITTGroup4TiffImageData.
       
  1506 	ok := true
       
  1507     ]. 
       
  1508     (compression == 5) ifTrue:[
       
  1509 	result := self readLZWTiffImageData.
       
  1510 	ok := true
       
  1511     ].
       
  1512     (compression == 6) ifTrue:[
       
  1513 	result := self readJPEGTiffImageData.
       
  1514 	ok := true
       
  1515     ].
       
  1516     (compression == 32766) ifTrue:[
       
  1517 	result := self readNeXTRLE2TiffImageData.
       
  1518 	ok := true
       
  1519     ].
       
  1520     (compression == 32771) ifTrue:[
       
  1521 	result := self readCCITTRLEWTiffImageData.
       
  1522 	ok := true
       
  1523     ].
       
  1524     (compression == 32773) ifTrue:[
       
  1525 	result := self readPackbitsTiffImageData.
       
  1526 	ok := true
       
  1527     ].
       
  1528     (compression == 32865) ifTrue:[
       
  1529 	result := self readNeXTJPEGTiffImageData.
       
  1530 	ok := true
       
  1531     ].
       
  1532     ok ifFalse:[
       
  1533 	'TIFFReader: compression type ' errorPrint. compression errorPrint.
       
  1534 	' not known' errorPrintNL
       
  1535     ].
       
  1536     ^ result
       
  1537 ! !
       
  1538 
       
  1539 !TIFFReader methodsFor:'writing to file'!
       
  1540 
       
  1541 save:image onFile:aFileName
       
  1542     "save image as (uncompressed) TIFF file on aFileName"
       
  1543 
       
  1544     |pos1 pos|
       
  1545 
       
  1546     outStream := FileStream newFileNamed:aFileName.
       
  1547     outStream isNil ifTrue:[
       
  1548 	'TIFFReader: create error' errorPrintNL. 
       
  1549 	^ nil
       
  1550     ].
       
  1551 
       
  1552     "save as msb"
       
  1553 
       
  1554     byteOrder := #msb.
       
  1555 "
       
  1556     byteOrder := #lsb.
       
  1557 "
       
  1558     fillOrder := #msb.
       
  1559     width := image width.
       
  1560     height := image height.
       
  1561     photometric := image photometric.
       
  1562     samplesPerPixel := image samplesPerPixel.
       
  1563     bitsPerSample := image bitsPerSample.
       
  1564     colorMap := image colorMap.
       
  1565     planarConfiguration := 1.
       
  1566     compression := 1.   "none"
       
  1567     data := image bits.
       
  1568 
       
  1569     currentOffset := 0.
       
  1570 
       
  1571     (byteOrder == #msb) ifTrue:[
       
  1572 	outStream nextPut:$M.
       
  1573 	outStream nextPut:$M.
  1493     ] ifFalse:[
  1574     ] ifFalse:[
  1494 	(nPlanes == 2) ifTrue:[
  1575 	outStream nextPut:$I.
  1495 	    (planarConfiguration ~~ 2) ifTrue:[
  1576 	outStream nextPut:$I.
  1496 		self error:'only separate planes supported'.
  1577     ].
  1497 		^ nil
  1578     currentOffset := currentOffset + 2.
  1498 	    ].
  1579 
  1499 	    'TIFFReader: ignoring alpha plane' errorPrintNL.
  1580     outStream binary.
  1500 	    nPlanes := 1
  1581 
  1501 	].
  1582     self writeShort:42.
  1502 	(nPlanes == 1) ifFalse:[
  1583     currentOffset := currentOffset + 2.
  1503 	    self error:'only 3-sample rgb / monochrome supported'.
  1584 
  1504 	    ^ nil
  1585     pos1 := outStream position.
  1505 	].
  1586     self writeLong:0.           "start of tags - filled in later"
  1506 	bytesPerRow := (width * (bitsPerSample at:1) + 7) // 8.
  1587     currentOffset := currentOffset + 4.
  1507     ].
  1588 
  1508 
  1589     "output strips"
  1509     stripByteCounts isNil ifTrue:[
  1590 
  1510 	self error:'currently require stripByteCounts'.
  1591     self writeUncompressedBits. "this outputs bits as strips, sets stripOffsets and stripByteCounts"
  1511 	^ nil
  1592     self writeStripOffsets.     "this outputs strip offsets, sets stripOffsetsPos"
  1512     ].
  1593     self writeStripByteCounts.  "this outputs strip bytecounts, sets stripByteCountPos"
  1513 
  1594     self writeBitsPerSample.    "this outputs bitsPerSample, sets bitsPerSamplePos"
  1514     'TIFFReader: decompressing LZW ...' infoPrintNL.
  1595     photometric == #palette ifTrue:[
  1515 
  1596 	self writeColorMap      "this outputs colorMap, sets colorMapPos"
  1516     data := ByteArray uninitializedNew:(bytesPerRow * height).
  1597     ].
  1517 
  1598 
  1518     offset := 1.
  1599     pos := outStream position.                  "backpatch tag offset"
  1519     stripNr := 0.
  1600     outStream position:pos1.
  1520 
  1601     self writeLong:(pos - 1).                   "fill in tag offset"
  1521     row := 1.
  1602     outStream position:pos.
  1522     bytesPerStrip := bytesPerRow * rowsPerStrip.
  1603 "
  1523     prevSize := 0.
  1604 ('patch tag offset at: ', (pos1 printStringRadix:16) , ' to ',
  1524     [row <= height] whileTrue:[
  1605 			 (pos printStringRadix:16)) printNewline.
  1525 	stripNr := stripNr + 1.
  1606 "
  1526 	inStream position:((stripOffsets at:stripNr) + 1).
  1607     "output tag data"
  1527 	nBytes := stripByteCounts at:stripNr.
  1608 
  1528 	(nBytes > prevSize) ifTrue:[
  1609     photometric == #palette ifTrue:[
  1529 	    compressedStrip := ByteArray uninitializedNew:nBytes.
  1610 	self writeShort:10.  "10 tags"
  1530 	    prevSize := nBytes
  1611     ] ifFalse:[
  1531 	].
  1612 	self writeShort:9.   "9 tags"
  1532 	inStream nextBytes:nBytes
  1613     ].
  1533 		      into:compressedStrip.
  1614     self writeTag:256.               "image width"
  1534 	self class decompressLZWFrom:compressedStrip
  1615     self writeTag:257.               "image height"
  1535 			       count:nBytes
  1616     self writeTag:258.               "bits per sample"
  1536 				into:data
  1617     self writeTag:259.               "compression"
  1537 			  startingAt:offset.
  1618     self writeTag:262.               "photometric"
  1538 	offset := offset + bytesPerStrip.
  1619     self writeTag:273.               "strip offsets"
  1539 	row := row + rowsPerStrip
  1620     self writeTag:278.               "rowsPerStrip"
  1540     ].
  1621     self writeTag:279.               "strip byte counts"
  1541 
  1622     self writeTag:284.               "planarconfig"
  1542     (predictor == 2) ifTrue:[
  1623     photometric == #palette ifTrue:[
  1543 	self class decodeDelta:3 in:data width:width height:height
  1624 	self writeTag:320            "colorMap"
  1544     ]
  1625     ].
  1545 !
  1626     self writeLong:0.                "end of tags mark"
  1546 
  1627     outStream close
  1547 readCCITTGroup3TiffImageData
       
  1548     "not really tested - all I got is a single
       
  1549      fax from NeXT step"
       
  1550 
       
  1551     |bytesPerRow bitsPerRow compressedStrip nPlanes 
       
  1552      stripNr       "{ Class: SmallInteger }"
       
  1553      offset        "{ Class: SmallInteger }"
       
  1554      row           "{ Class: SmallInteger }"
       
  1555      bytesPerStrip "{ Class: SmallInteger }" |
       
  1556 
       
  1557     nPlanes := samplesPerPixel.
       
  1558     (nPlanes == 2) ifTrue:[
       
  1559 	'TIFFReader: ignoring alpha plane' errorPrintNL.
       
  1560 	nPlanes := 1
       
  1561     ].
       
  1562 
       
  1563     (nPlanes ~~ 1) ifTrue:[
       
  1564 	self error:'only monochrome/greyscale supported'.
       
  1565 	^ nil
       
  1566     ].
       
  1567 
       
  1568     stripByteCounts isNil ifTrue:[
       
  1569 	self error:'currently require stripByteCounts'.
       
  1570 	^ nil
       
  1571     ].
       
  1572     (rowsPerStrip ~~ 1) isNil ifTrue:[
       
  1573 	self error:'currently require rowsPerStrip to be 1'.
       
  1574 	^ nil
       
  1575     ].
       
  1576 
       
  1577     'TIFFReader: decompressing CCITT-3 ...' infoPrintNL.
       
  1578 
       
  1579     bitsPerRow := width * (bitsPerSample at:1).
       
  1580     bytesPerRow := bitsPerRow // 8.
       
  1581     ((bitsPerRow \\ 8) ~~ 0) ifTrue:[
       
  1582 	bytesPerRow := bytesPerRow + 1
       
  1583     ].
       
  1584 
       
  1585     data := ByteArray new:(bytesPerRow * height).
       
  1586     compressedStrip := ByteArray uninitializedNew:bytesPerRow.
       
  1587 
       
  1588     offset := 1.
       
  1589     stripNr := 0.
       
  1590 
       
  1591     row := 1.
       
  1592     bytesPerStrip := bytesPerRow * rowsPerStrip.
       
  1593     [row <= height] whileTrue:[
       
  1594 	stripNr := stripNr + 1.
       
  1595 	inStream position:((stripOffsets at:stripNr) + 1).
       
  1596 	inStream nextBytes:(stripByteCounts at:stripNr) into:compressedStrip.
       
  1597 	self class decompressCCITT3From:compressedStrip
       
  1598 				   into:data
       
  1599 			     startingAt:offset
       
  1600 				  count:width.
       
  1601 	offset := offset + bytesPerStrip.
       
  1602 	row := row + rowsPerStrip
       
  1603     ]
       
  1604 !
       
  1605 
       
  1606 readJPEGTiffImageData
       
  1607     'TIFFReader: jpeg compression not implemented' errorPrintNL
       
  1608 !
       
  1609 
       
  1610 readNeXTJPEGTiffImageData
       
  1611     'TIFFReader: jpeg compression not implemented' errorPrintNL
       
  1612 !
       
  1613 
       
  1614 readCCITT3RLETiffImageData
       
  1615      'TIFFReader: ccitt mod Huffman (rle) compression not implemented' errorPrintNL.
       
  1616 !
       
  1617 
       
  1618 readCCITT3RLEWTiffImageData
       
  1619      'TIFFReader: ccitt mod Huffman (rlew) compression not implemented' errorPrintNL.
       
  1620 !
       
  1621 
       
  1622 readCCITTGroup4TiffImageData
       
  1623     'TIFFReader: ccitt group4 fax compression not implemented' errorPrintNL.
       
  1624 !
       
  1625 
       
  1626 readNeXTRLE2TiffImageData
       
  1627     'TIFFReader: next 2bit rle compression not implemented' errorPrintNL.
       
  1628 !
       
  1629 
       
  1630 readPackbitsTiffImageData
       
  1631     "had no samples yet - however, packbits decompression
       
  1632      is rather trivial to add ..."
       
  1633 
       
  1634     'TIFFReader: packbits compression not implemented' errorPrintNL
       
  1635 ! !
  1628 ! !
       
  1629 
       
  1630 !TIFFReader class methodsFor:'documentation'!
       
  1631 
       
  1632 version
       
  1633     ^ '$Header: /cvs/stx/stx/libview2/Attic/TIFFRdr.st,v 1.27 1995-12-07 11:38:46 cg Exp $'
       
  1634 ! !
       
  1635 TIFFReader initialize!