#FEATURE by cg
class: TIFFReader
class definition
added:
#positionToTile:
#readTiledJPEGTiffImageData
changed:
#decodeTiffTag:numberType:length:
#readThunderScanTiffImageData
#readTiledTiffImageData
class: TIFFReader class
comment/format in: #documentation
--- a/TIFFReader.st Fri Aug 25 15:25:12 2017 +0200
+++ b/TIFFReader.st Fri Aug 25 18:07:24 2017 +0200
@@ -18,7 +18,7 @@
fillOrder compression group3options predictor stripByteCounts
currentOffset stripOffsetsPos stripByteCountsPos bitsPerSamplePos
colorMapPos orientation isBigTiff'
- classVariableNames:''
+ classVariableNames:'Verbose'
poolDictionaries:''
category:'Graphics-Images-Readers'
!
@@ -64,6 +64,7 @@
It should write (at least) mono, 8-bit palette and 24 bit rgb formats.
- bigTiff is supported
+ - some dng tags are supported
More formats will come... (will they ever be needed?)
@@ -140,854 +141,6 @@
"Modified: / 25-08-2017 / 08:39:20 / cg"
! !
-!TIFFReader methodsFor:'private'!
-
-decodeTiffTag:tagType numberType:numberType length:length
- |offset value valueArray
- val scaleFactor rV gV bV
- n "{ Class: SmallInteger }"
- i2 "{ Class: SmallInteger }"
- i3 "{ Class: SmallInteger }" |
-
- "/ 'tiffTag: ' print. tagType printCR.
-
- (numberType == 3 "TIFF_SHORT") ifTrue:[
- "16 bit ushort"
- valueArray := self readShorts:length signed:false.
- value := valueArray at:1
- ] ifFalse:[(numberType == 4 "TIFF_LONG") ifTrue:[
- "32 bit uinteger"
- valueArray := self readLongs:length signed:false.
- value := valueArray at:1
- ] ifFalse:[(numberType == 2 "TIFF_ASCII") ifTrue:[
- "ascii characters"
- value := self readChars:length
- ] ifFalse:[(numberType == 5 "TIFF_RATIONAL") ifTrue:[
- "64 (32+32) bit ufraction"
- valueArray := self readFracts:length signed:false.
- value := valueArray at:1
- ] ifFalse:[(numberType == 1 "TIFF_BYTE") ifTrue:[
- "8bit uinteger"
- value := self readBytes:length signed:false
- ] ifFalse:[(numberType == 6 "TIFF_SBYTE") ifTrue:[
- "TIFF6: 8bit signed integer"
- value := self readBytes:length signed:true
- ] ifFalse:[(numberType == 8 "TIFF_SSHORT") ifTrue:[
- "TIFF6: 16bit signed integer"
- valueArray := self readShorts:length signed:true.
- value := valueArray at:1
- ] ifFalse:[(numberType == 9 "TIFF_SLONG") ifTrue:[
- "TIFF6: 32bit signed integer"
- valueArray := self readLongs:length signed:true.
- value := valueArray at:1
- ] ifFalse:[(numberType == 10 "TIFF_SRATIONAL") ifTrue:[
- "TIFF6: 64 (32+32) bit signed fraction"
- valueArray := self readFracts:length signed:true.
- value := valueArray at:1
- ] ifFalse:[(numberType == 11 "TIFF_FLOAT") ifTrue:[
- "TIFF6: 32 bit IEEE float"
- valueArray := self readFloats:length.
- value := valueArray at:1
- ] ifFalse:[(numberType == 12 "TIFF_DOUBLE") ifTrue:[
- "TIFF6: 64 bit IEEE double"
- valueArray := self readDoubles:length.
- value := valueArray at:1
-
- ] ifFalse:[(numberType == 7 "TIFF_UNDEFINED") ifTrue:[
- "8bit anything"
- value := self readBytes:length signed:false
-
- "/ the following are preps for the propsed bigTiff format
- ] ifFalse:[(numberType == 16 "TIFF_LONG8") ifTrue:[
- "BIGTIFF: 8-byte unsigned integer"
- valueArray := self readLong8s:length signed:false.
- value := valueArray at:1.
- ] ifFalse:[(numberType == 17 "TIFF_SLONG8") ifTrue:[
- "BIGTIFF: 8-byte signed integer"
- valueArray := self readLong8s:length signed:true.
- value := valueArray at:1.
- ] ifFalse:[(numberType == 18 "TIFF_IFD8") ifTrue:[
- "BIGTIFF: 8-byte unsigned IFD offset"
- valueArray := self readLong8s:length signed:false.
- value := valueArray at:1.
- ] ifFalse:[
- isBigTiff ifTrue:[
- offset := (inStream nextInt64MSB:(byteOrder ~~ #lsb))
- ] ifFalse:[
- offset := (inStream nextInt32MSB:(byteOrder ~~ #lsb))
- ]
- ]]]]]]]]]]]]]]].
-
- (tagType between:200 and:299) ifTrue:[
- (tagType == 254) ifTrue:[
- "/ New SubfileType
- "/ REDUCEDIMAGE -> 1
- "/ PAGE -> 2
- "/ MASK -> 4
- "newSubFileType := value."
-
- "/ 'newSubfiletype ' print. value printNewline.
-
- ^ self
- ].
- (tagType == 255) ifTrue:[
- "/ Old SubfileType
- "/ IMAGE -> 1
- "/ REDUCEDIMAGE -> 2
- "/ PAGE -> 3
- subFileType := value.
-
- "/ 'subfiletype ' print. value printNewline.
-
- ^ self
- ].
- (tagType == 256) ifTrue:[
- "ImageWidth"
- width := value.
-
- "/ 'width ' print. width printNewline.
-
- ^ self
- ].
- (tagType == 257) ifTrue:[
- "ImageHeight"
- height := value.
-
- "/ 'height ' print. height printNewline.
-
- ^ self
- ].
- (tagType == 258) ifTrue:[
- "bitspersample"
- bitsPerSample := valueArray.
-
- "/ 'bitspersample ' print. bitsPerSample printNewline.
-
- ^ self
- ].
- (tagType == 259) ifTrue:[
- "/ compression
- "/ NONE -> 1
- "/ CCITTRLE -> 2
- "/ CCITTFAX3 -> 3
- "/ CCITTFAX4 -> 4
- "/ LZW -> 5
- "/ OJPEG -> 6
- "/ JPEG -> 7
- "/ NEXT -> 32766 (NeXT 2-bit encoding)
- "/ CCITTRLEW -> 32771
- "/ PACKBITS -> 32773
- "/ THUNDERSCAN -> 32809 (ThunderScan 4-bit encoding)
- "/ PIXARFILM -> 32908
- "/ PIXARLOG -> 32909 (Pixar companded 11-bit ZIP encoding)
- "/ DEFLATE -> 32946 (PKZIP-style Deflate encoding)
- "/ DCS -> 32947
- "/ JBIG -> 34661
- "/ SGI32 -> 34676 (SGI 32-bit Log Luminance encoding)
- "/ SGI24 -> 34677 (SGI 24-bit Log Luminance encoding)
-
- compression := value.
-
- "/ 'compression ' print. compression printNewline.
-
- ^ self
- ].
- (tagType == 262) ifTrue:[
- "photometric"
-
- (value == 0) ifTrue:[
- photometric := #whiteIs0
- ] ifFalse:[
- (value == 1) ifTrue:[
- photometric := #blackIs0
- ] ifFalse:[
- (value == 2) ifTrue:[
- photometric := #rgb
- ] ifFalse:[
- (value == 3) ifTrue:[
- photometric := #palette
- ] ifFalse:[
- (value == 4) ifTrue:[
- photometric := #transparencyMask
- ] ifFalse:[
- (value == 5) ifTrue:[
- photometric := #cmyk "/ color separations
- ] ifFalse:[
- (value == 6) ifTrue:[
- photometric := #ycbcr "/ CCIR 601
- ] ifFalse:[
- (value == 8) ifTrue:[
- photometric := #cielab "/ 1976 CIE L*a*b*
- ] ifFalse:[
- photometric := nil
- ]
- ]
- ]
- ]
- ]
- ]
- ]
- ].
-
- "/ 'photometric ' print. photometric printNewline.
-
- ^ self
- ].
- (tagType == 263) ifTrue:[
- "/ Thresholding
- "/ BILEVEL -> 1
- "/ HALFTONE -> 2
- "/ ERRORDIFFUSE -> 3
-
- "thresholding := value."
-
- "/ 'thresholding ' print. value printNewline.
-
- ^ self
- ].
- (tagType == 264) ifTrue:[
- "CellWidth"
- "/ 'cellWidth ' print. value printNewline.
- metaData at:#CellWidth put:value.
-
- ^ self
- ].
- (tagType == 265) ifTrue:[
- "CellLength"
- "/ 'cellLength ' print. value printNewline.
- metaData at:#CellLength put:value.
- ^ self
- ].
- (tagType == 266) ifTrue:[
- "fillOrder"
- (value == 1) ifTrue:[
- fillOrder := #msb
- ] ifFalse:[
- (value == 2) ifTrue:[
- fillOrder := #lsb
- ] ifFalse:[
- fillOrder := nil
- ]
- ].
- "/ 'fillorder ' print. fillOrder printNewline.
- ^ self
- ].
- (tagType == 269) ifTrue:[
- "documentName - info only"
- "/ 'documentName ' print. value printNewline.
- metaData at:#DocumentName put:value.
- ^ self
- ].
- (tagType == 270) ifTrue:[
- "imageDescription - info only"
- "/ 'imageDescription ' print. value printNewline.
- metaData at:#ImageDescription put:value.
- ^ self
- ].
- (tagType == 271) ifTrue:[
- "make - info only"
- "/ 'make ' print. value printNewline.
- metaData at:#Make put:value.
- ^ self
- ].
- (tagType == 272) ifTrue:[
- "model - info only"
- "/ 'model ' print. value printNewline.
- metaData at:#Model put:value.
- ^ self
- ].
- (tagType == 273) ifTrue:[
- stripOffsets := valueArray.
- "/ 'stripOffsets Array(' print. stripOffsets size print. ')' printNewline.
- ^ self
- ].
- (tagType == 274) ifTrue:[
- "Orientation"
-
- orientation :=
- #( nil "/ 1 normal (topLeft)
- unsupported "/ 2 horizontal flip
- unsupported "/ 3 horizontal & vertical flip
- vFlip "/ 4 vertical flip
- unsupported "/ 5 rot 90' counter clock-wise
- unsupported "/ 6 rot 90' clock-wise
- unsupported "/ 7 rot 90' & flip
- unsupported "/ 8 rot 90' ccw & flip
- ) at:value ifAbsent:#unsupported.
- metaData at:#Orientation put:value.
- "/ 'orientation ' print. value printNewline.
- ^ self
- ].
- (tagType == 277) ifTrue:[
- samplesPerPixel := value.
- "/ 'samplesperpixel ' print. samplesPerPixel printNewline.
- ^ self
- ].
- (tagType == 278) ifTrue:[
- rowsPerStrip := value.
- "/ 'rowsperstrip ' print. rowsPerStrip printNewline.
- ^ self
- ].
- (tagType == 279) ifTrue:[
- "stripbytecount"
- stripByteCounts := valueArray.
- "/ 'stripByteCounts Array(' print.
- "/ stripByteCounts size print.
- "/ ')' printNewline.
- ^ self
- ].
- (tagType == 280) ifTrue:[
- "/ 'minSampleValue ' print. value printNewline.
- metaData at:#MinSampleValue put:value.
- ^ self
- ].
- (tagType == 281) ifTrue:[
- "/ 'maxSampleValue ' print. value printNewline.
- metaData at:#MaxSampleValue put:value.
- ^ self
- ].
- (tagType == 282) ifTrue:[
- "/ 'xResolution ' print. value printNewline.
- metaData at:#ResolutionX put:value.
- ^ self
- ].
- (tagType == 283) ifTrue:[
- "/ 'yResolution ' print. value printNewline.
- metaData at:#ResolutionY put:value.
- ^ self
- ].
- (tagType == 284) ifTrue:[
- (value == 1) ifTrue:[
- planarConfiguration := 1
- ] ifFalse:[
- (value == 2) ifTrue:[
- planarConfiguration := 2
- ] ifFalse:[
- planarConfiguration := nil
- ]
- ].
- "/ 'planarconfig ' print. planarConfiguration printNewline.
- ^ self
- ].
- (tagType == 285) ifTrue:[
- "/ 'pageName ' print. value printNewline.
- metaData at:#PageName put:value.
- ^ self
- ].
- (tagType == 286) ifTrue:[
- "/ 'xPosition ' print. value printNewline.
- metaData at:#PositionX put:value.
- ^ self
- ].
- (tagType == 287) ifTrue:[
- "/ 'yPosition ' print. value printNewline.
- metaData at:#PositionY put:value.
- ^ self
- ].
- (tagType == 288) ifTrue:[
- "/ 'freeOffsets ' print. value printNewline.
- ^ self
- ].
- (tagType == 289) ifTrue:[
- "/ 'freeByteCounts ' print. value printNewline.
- ^ self
- ].
- (tagType == 290) ifTrue:[
- "/ 'grayResponceUnit' print. value printNewline.
- metaData at:#GrayResponceUnit put:value.
- ^ self
- ].
- (tagType == 291) ifTrue:[
- "/ 'grayResponceCurve' print. value printNewline.
- metaData at:#GrayResponceCurve put:value.
- ^ self
- ].
- (tagType == 292) ifTrue:[
- "/ group3options (now called T4Options)
- "/ 2DENCODING -> 1
- "/ UNCOMPRESSED -> 2
- "/ FILLBITS -> 4
-
- group3options := value.
- "/ 'group3options ' print. group3options printNewline.
- ^ self
- ].
- (tagType == 293) ifTrue:[
- "/ group4options (now called T6Options)
- "/ UNCOMPRESSED -> 2
-
- "group4options := value."
- "/ 'group4options ' print. value printNewline.
- ^ self
- ].
- (tagType == 296) ifTrue:[
- "resolutionunit"
-
- "/ (value == 1) ifTrue:[
- "/ 'res-unit pixel' printNewline
- "/ ] ifFalse:[
- "/ (value == 2) ifTrue:[
- "/ 'res-unit inch' printNewline
- "/ ] ifFalse:[
- "/ (value == 3) ifTrue:[
- "/ 'res-unit mm' printNewline
- "/ ] ifFalse:[
- "/ 'res-unit invalid' printNewline
- "/ ]
- "/ ]
- "/ ].
- metaData at:#ResolutionUnit put:value.
- ^ self
- ].
- (tagType == 297) ifTrue:[
- "/ 'pageNumber ' print. value printNewline.
- metaData at:#PageNumber put:value.
- ^ self
- ].
- ].
-
- (tagType between:300 and:399) ifTrue:[
- (tagType == 300) ifTrue:[
- "/ 'colorResponceUnit' print. value printNewline.
- metaData at:#ColorResponceUnit put:value.
- ^ self
- ].
- (tagType == 301) ifTrue:[
- "/ 'colorResponceCurve' print. value printNewline.
- metaData at:#ColorResponceCurve put:value.
- ^ self
- ].
- (tagType == 305) ifTrue:[
- "software - info only"
- "/ 'software' print. value printNewline.
- metaData at:#Software put:value.
- ^ self
- ].
- (tagType == 306) ifTrue:[
- "dateTime - info only"
- "/ 'dateTime ' print. value printNewline.
- metaData at:#DateTime put:value.
- ^ self
- ].
- (tagType == 315) ifTrue:[
- "artist - info only"
- "/ 'artist ' print. value printNewline.
- metaData at:#Artist put:value.
- ^ self
- ].
- (tagType == 316) ifTrue:[
- "host computer - info only"
- "/ 'host ' print. value printNewline.
- metaData at:#HostComputer put:value.
- ^ self
- ].
- (tagType == 317) ifTrue:[
- "/ 'predictor ' print. predictor printNewline.
- predictor := value.
- ^ self
- ].
- (tagType == 318) ifTrue:[
- "/ 'whitePoint ' print. value printNewline.
- metaData at:#WhitePoint put:value.
- ^ self
- ].
- (tagType == 319) ifTrue:[
- "/ 'primaryChromatics ' print. value printNewline.
- metaData at:#PrimaryChromatics put:value.
- ^ self
- ].
- (tagType == 320) ifTrue:[
- "/ 'colorMap (size=' print. valueArray size print. ')' printNewline.
-
- "
- the tiff colormap contains 16bit values;
- our colormap expects 8bit values
- "
- n := valueArray size // 3.
-
- rV := ByteArray uninitializedNew:n.
- gV := ByteArray uninitializedNew:n.
- bV := ByteArray uninitializedNew:n.
- scaleFactor := 255.0 / 16rFFFF.
- i2 := n+1.
- i3 := 2*n+1.
- 1 to:n do:[:vi |
- val := ((valueArray at:vi) * scaleFactor) rounded.
- rV at:vi put:val.
- val := ((valueArray at:i2) * scaleFactor) rounded.
- gV at:vi put:val.
- val := ((valueArray at:i3) * scaleFactor) rounded.
- bV at:vi put:val.
- i2 := i2 + 1.
- i3 := i3 + 1.
- ].
- colorMap := MappedPalette redVector:rV greenVector:gV blueVector:bV.
- ^ self
- ].
- (tagType == 321) ifTrue:[
- "/ 'halftonehints' print. value printNewline.
- metaData at:#HalftoneHints put:value.
- ^ self
- ].
- (tagType == 322) ifTrue:[
- "/ 'tilewidth' print. value printNewline.
- metaData at:#TileWidth put:value.
- ^ self
- ].
- (tagType == 323) ifTrue:[
- "/ 'tilelength' print. value printNewline.
- metaData at:#TileLength put:value.
- ^ self
- ].
- (tagType == 324) ifTrue:[
- "/ 'tileoffsets' print. value printNewline.
- metaData at:#TileOffsets put:valueArray.
- ^ self
- ].
- (tagType == 325) ifTrue:[
- "/ 'tilebytecounts' print. value printNewline.
- metaData at:#TileByteCounts put:valueArray.
- ^ self
- ].
- (tagType == 326) ifTrue:[
- "/ 'badFaxLines' print. value printNewline.
- ^ self
- ].
- (tagType == 327) ifTrue:[
- "CleanFaxData"
-
- "/ 'cleanfaxdata' print. value printNewline.
- "/ (value == 0) ifTrue:[
- "/ 'no lines with incorrect pixel counts' printNewline
- "/ ] ifFalse:[
- "/ (value == 1) ifTrue:[
- "/ 'incorrect lines were regenerated' printNewline
- "/ ] ifFalse:[
- "/ (value == 2) ifTrue:[
- "/ 'incorrect lines were not regenerated' printNewline
- "/ ] ifFalse:[
- "/ 'cleanfaxdata invalid' printNewline
- "/ ]
- "/ ]
- "/ ].
-
- ^ self
- ].
- (tagType == 328) ifTrue:[
- "/ 'consecutiveBadFaxLines' print. value printNewline.
- ^ self
- ].
- (tagType == 330) ifTrue:[
- "/ 'subifd' print. value printNewline.
- ^ self
- ].
- (tagType == 332) ifTrue:[
- "/ 'ink set' print. value printNewline.
- ^ self
- ].
- (tagType == 333) ifTrue:[
- "/ 'ink names' print. value printNewline.
- metaData at:#IncNames put:value.
- ^ self
- ].
- (tagType == 334) ifTrue:[
- "/ 'numinks' print. value printNewline.
- ^ self
- ].
- (tagType == 336) ifTrue:[
- "/ 'dot range' print. value printNewline.
- ^ self
- ].
- (tagType == 337) ifTrue:[
- "/ 'target printer' print. value printNewline.
- ^ self
- ].
- (tagType == 338) ifTrue:[
- "/ 'extrasamples' print. value printNewline.
- ^ self
- ].
- (tagType == 339) ifTrue:[
- "/ 'sample format' print. value printNewline.
- ^ self
- ].
- (tagType == 340) ifTrue:[
- "/ 'min sample value' print. value printNewline.
- ^ self
- ].
- (tagType == 341) ifTrue:[
- "/ 'max sample value' print. value printNewline.
- ^ self
- ].
- (tagType == 342) ifTrue:[
- "/ 'transfer range' print. value printNewline.
- ^ self
- ].
- (tagType == 343) ifTrue:[
- "/ 'clip path' print. value printNewline.
- ^ self
- ].
- (tagType == 344) ifTrue:[
- "/ 'xclip path units' print. value printNewline.
- ^ self
- ].
- (tagType == 345) ifTrue:[
- "/ 'yclip path units' print. value printNewline.
- ^ self
- ].
- (tagType == 347) ifTrue:[
- "/ 'jpegtables' print. value printNewline.
- ^ self
- ].
- ].
-
- (tagType between:400 and:499) ifTrue:[
- (tagType == 400) ifTrue:[
- "/ 'GlobalParametersIFD' print. value printNewline.
- ^ self
- ].
- (tagType == 401) ifTrue:[
- "/ 'ProfileType' print. value printNewline.
- ^ self
- ].
- (tagType == 402) ifTrue:[
- "/ 'FaxProfile' print. value printNewline.
- ^ self
- ].
- (tagType == 403) ifTrue:[
- "/ 'CodingMethods' print. value printNewline.
- ^ self
- ].
- (tagType == 404) ifTrue:[
- "/ 'VersionYear' print. value printNewline.
- ^ self
- ].
- (tagType == 405) ifTrue:[
- "/ 'ModeNumber' print. value printNewline.
- ^ self
- ].
- (tagType == 433) ifTrue:[
- "/ 'Decode' print. value printNewline.
- ^ self
- ].
- (tagType == 434) ifTrue:[
- "/ 'DefaultImageColor' print. value printNewline.
- ^ self
- ].
- ].
-
- (tagType between:500 and:599) ifTrue:[
- "/ obsolete JPEG tags
- (tagType == 512) ifTrue:[
- "/ 'jpeg proc' print. value printNewline.
- ^ self
- ].
- (tagType == 513) ifTrue:[
- "/ 'jpeg proc' print. value printNewline.
- ^ self
- ].
- (tagType == 514) ifTrue:[
- "/ 'jpeg ifByteCount' print. value printNewline.
- ^ self
- ].
- (tagType == 515) ifTrue:[
- "/ 'jpeg restartInterval' print. value printNewline.
- ^ self
- ].
- (tagType == 517) ifTrue:[
- "/ 'jpeg glossLessPredictors' print. value printNewline.
- ^ self
- ].
- (tagType == 518) ifTrue:[
- "/ 'jpeg pointTransform' print. value printNewline.
- ^ self
- ].
- (tagType == 519) ifTrue:[
- "/ 'jpeg qTables' print. value printNewline.
- ^ self
- ].
- (tagType == 520) ifTrue:[
- "/ 'jpeg dcTables' print. value printNewline.
- ^ self
- ].
- (tagType == 521) ifTrue:[
- "/ 'jpeg acTables' print. value printNewline.
- ^ self
- ].
-
-
- (tagType == 529) ifTrue:[
- "/ 'ycbr coeff' print. value printNewline.
- ^ self
- ].
- (tagType == 530) ifTrue:[
- "/ 'ycbr subsampling' print. value printNewline.
- ^ self
- ].
- (tagType == 531) ifTrue:[
- "/ 'ycbr positioning' print. value printNewline.
- ^ self
- ].
- (tagType == 532) ifTrue:[
- "/ 'referenceBlackWhite' print. value printNewline.
- ^ self
- ].
- (tagType == 559) ifTrue:[
- "/ 'stripRowCounts' print. value printNewline.
- ^ self
- ].
- ].
-
- (tagType between:700 and:799) ifTrue:[
- (tagType == 700) ifTrue:[
- "XMLPACKET"
-
- "/ In TIFF files, the XML Packet containing XMP metadata is pointed to
- "/ by an entry in the Image File Directory (IFD). That entry has a Tag
- "/ value of 700, as shown in Table 1.1, "TIFF IFD Directory Entry for
- "/ XML Packets
-
- "/ 'XMLPACKET' print. value printNewline.
- ^ self
- ].
- ].
-
- (tagType > 32000) ifTrue:[
- (tagType == 32781) ifTrue:[
- "/'imageid' print. value printNewline.
- ^ self
- ].
- (tagType == 32932) ifTrue:[
- "/'wang annotation' print. value printNewline.
- ^ self
- ].
-
- "/ Private Island graphics tags
- (tagType == 32953) ifTrue:[
- "/'ref points' print. value printNewline.
- ^ self
- ].
- (tagType == 32954) ifTrue:[
- "/ 'regionTagPoint' print. value printNewline.
- ^ self
- ].
- (tagType == 32955) ifTrue:[
- "/ 'regionWarpCorners' print. value printNewline.
- ^ self
- ].
- (tagType == 32956) ifTrue:[
- "/ 'regionAffine' print. value printNewline.
- ^ self
- ].
-
-
- "/ Private SGI tags
- (tagType == 32995) ifTrue:[
- "/ 'matteing' print. value printNewline.
- ^ self
- ].
- (tagType == 32996) ifTrue:[
- "/ 'datatype' print. value printNewline.
- ^ self
- ].
- (tagType == 32997) ifTrue:[
- "/ 'imagedepth' print. value printNewline.
- ^ self
- ].
- (tagType == 32998) ifTrue:[
- "/ 'tiledepth' print. value printNewline.
- ^ self
- ].
-
- "/ Private Pixar tags
- (tagType == 33300) ifTrue:[
- "/ 'image full width' print. value printNewline.
- ^ self
- ].
- (tagType == 33301) ifTrue:[
- "/ 'image full length' print. value printNewline.
- ^ self
- ].
-
- "/ Private Eastman Kodak tags
- (tagType == 33405) ifTrue:[
- "/ 'write serial number' print. value printNewline.
- ^ self
- ].
-
- "/ unknown
- (tagType == 33432) ifTrue:[
- "/ 'copyright' print. value printNewline.
- ^ self
- ].
-
- (tagType == 33550) ifTrue:[
- "/ 'geotiff modelpixelscaletag' print. value printNewline.
- ^ self
- ].
-
- (tagType == 33723) ifTrue:[
- "/ 'RICHTIFFIPTC' print. value printNewline.
- ^ self
- ].
-
- "/ Private Texas instruments
- (tagType == 34232) ifTrue:[
- "/ 'sequence frame count' print. value printNewline.
- ^ self
- ].
-
- "/ Private Pixel magic
- (tagType == 34232) ifTrue:[
- "/ 'jbig options' print. value printNewline.
- ^ self
- ].
-
- "/ private Photoshop
- (tagType == 34377) ifTrue:[
- "/ 'photoshop RICHTIFFIPTC' print. value printNewline.
- ^ self
- ].
- (tagType == 34665) ifTrue:[
- "/ 'EXIFIFD' print. value printNewline.
- ^ self
- ].
- (tagType == 34675) ifTrue:[
- "/ 'ICCPROFILE' print. value printNewline.
- ^ self
- ].
-
- (tagType == 34732) ifTrue:[
- "/ 'ImageLayer' print. value printNewline.
- ^ self
- ].
-
- "/ More Private SGI
- (tagType == 34908) ifTrue:[
- "/ 'fax recv params' print. value printNewline.
- ^ self
- ].
- (tagType == 34909) ifTrue:[
- "/ 'fax subaddress' print. value printNewline.
- ^ self
- ].
- (tagType == 34910) ifTrue:[
- "/ 'fax recv time' print. value printNewline.
- ^ self
- ].
- ].
-
-"/
-"/ 'TIFFReader: tag:' print. tagType print. ' typ:' print. numberType print.
-"/ ' len:' print. length print. ' offs:' print. offset print.
-"/ ' val:' print. value print. ' valArr:' print. valueArray printNewline.
-"/
- 'TIFFReader [warning]: unknown tag type ' errorPrint. tagType errorPrintCR
-
- "Modified (format): / 23-05-2017 / 16:12:58 / mawalch"
- "Modified: / 25-08-2017 / 00:24:44 / cg"
- "Modified (format): / 25-08-2017 / 11:16:19 / cg"
-! !
-
!TIFFReader methodsFor:'private-data reading'!
readCCITT3RLETiffImageData
@@ -1305,9 +458,135 @@
!
readThunderScanTiffImageData
- ^ self fileFormatError:'thunderScan compression not implemented' .
+ |bytesPerRow compressedStrip nPlanes overAllBytes
+ bytesPerStrip "{ Class: SmallInteger }"
+ nBytes "{ Class: SmallInteger }"
+ prevSize "{ Class: SmallInteger }"
+ stripNr "{ Class: SmallInteger }"
+ offset "{ Class: SmallInteger }"
+ row "{ Class: SmallInteger }"
+ pixelIndex
+ i even gen highNibble lastPixel d1 d2 d3|
+
+ nPlanes := samplesPerPixel.
+
+ (nPlanes == 2) ifTrue:[
+ (planarConfiguration ~~ 2) ifTrue:[
+ ^ self fileFormatError:'only separate planes are supported'.
+ ].
+ 'TIFFReader [info]: ignoring alpha plane' infoPrintCR.
+ nPlanes := 1
+ ].
+ (nPlanes == 1) ifFalse:[
+ ^ self fileFormatError:'unsupported nPlanes: ' , nPlanes printString.
+ ].
+ (bitsPerSample at:1) == 4 ifFalse:[
+ ^ self fileFormatError:('unsupported bitsPerSample: %1 (only 4 supported)' bindWith:(bitsPerSample at:1)).
+ ].
+ bytesPerRow := (width * (bitsPerSample at:1) + 7) // 8.
+
+ "/ 'TIFFReader: decompressing ThunderScan ...' infoPrintNL.
+
+ overAllBytes := bytesPerRow * height.
+ bytesPerRow == width ifTrue:[
+ data := ByteArray uninitializedNew:overAllBytes.
+ ] ifFalse:[
+ data := ByteArray new:overAllBytes.
+ ].
+
+ offset := 1.
+ stripNr := 0.
+
+ gen := [:pixel |
+ even ifTrue:[
+ highNibble := pixel.
+ even := false.
+ ] ifFalse:[
+ data at:pixelIndex put:((highNibble bitShift:4) bitOr:pixel).
+ pixelIndex := pixelIndex + 1.
+ even := true.
+ ].
+ ].
+ even := true.
+ lastPixel := 0.
+
+ row := 1.
+ bytesPerStrip := bytesPerRow * rowsPerStrip.
+ prevSize := 0.
+ [row <= height] whileTrue:[
+ stripNr := stripNr + 1.
+ self positionToStrip:stripNr.
+ nBytes := stripByteCounts at:stripNr.
+ (nBytes > prevSize) ifTrue:[
+ compressedStrip := ByteArray uninitializedNew:nBytes.
+ prevSize := nBytes
+ ].
+ (inStream nextBytes:nBytes into:compressedStrip) == nBytes ifFalse:[ self error:'short read' ].
- "Modified: / 3.2.1998 / 18:12:01 / cg"
+ "/ RLE decode... (see http://fileformats.archiveteam.org/wiki/ThunderScan_compression)
+ i := 1.
+ pixelIndex := offset.
+
+ [i <= nBytes] whileTrue:[
+ |code|
+
+ code := compressedStrip at:i.
+ i := i + 1.
+ code >= 2r11000000 ifTrue:[
+ "/ a single pixel
+ lastPixel := code bitAnd:2r00111111.
+ self assert:(lastPixel <= 2r1111).
+
+ gen value:lastPixel.
+ ] ifFalse:[
+ code >= 2r10000000 ifTrue:[
+ "/ three bit deltas (2 pixels)
+
+ d1 := (code rightShift:3) bitAnd:2r111.
+ d2 := code bitAnd:2r111.
+ d1 ~~ 4 ifTrue:[
+ lastPixel := lastPixel + (#(0 1 2 3 0 -3 -2 -1) at:d1+1).
+ gen value:lastPixel.
+ ].
+ d2 ~~ 4 ifTrue:[
+ lastPixel := lastPixel + (#(0 1 2 3 0 -3 -2 -1) at:d2+1).
+ gen value:lastPixel.
+ ].
+ ] ifFalse:[
+ code >= 2r01000000 ifTrue:[
+ "/ two bit deltas (3 pixels)
+ d1 := (code rightShift:4) bitAnd:2r11.
+ d2 := (code rightShift:2) bitAnd:2r11.
+ d3 := code bitAnd:2r11.
+ d1 ~~ 2 ifTrue:[
+ lastPixel := lastPixel + (#(0 1 0 -1) at:d1+1).
+ gen value:lastPixel.
+ ].
+ d2 ~~ 2 ifTrue:[
+ lastPixel := lastPixel + (#(0 1 0 -1) at:d2+1).
+ gen value:lastPixel.
+ ].
+ d3 ~~ 2 ifTrue:[
+ lastPixel := lastPixel + (#(0 1 0 -1) at:d3+1).
+ gen value:lastPixel.
+ ].
+ ] ifFalse:[
+ code timesRepeat:[ gen value:lastPixel ].
+ ].
+ ].
+ ].
+ ].
+ "/ self assert:(pixelIndex == (offset + bytesPerStrip)).
+
+ offset := offset + bytesPerStrip.
+ row := row + rowsPerStrip
+ ].
+
+ (predictor ~~ 1) ifTrue:[
+ ^ self fileFormatError:('unsupported predictor: %1' bindWith:predictor).
+ ].
+
+ "Modified: / 25-08-2017 / 17:43:00 / cg"
!
readTiffImageData
@@ -1376,6 +655,12 @@
"Modified: / 25-08-2017 / 11:17:25 / cg"
!
+readTiledJPEGTiffImageData
+ ^ self fileFormatError:'jpeg compression not implemented (in tile mode)'.
+
+ "Created: / 25-08-2017 / 16:27:28 / cg"
+!
+
readTiledLZWTiffImageData
^ self fileFormatError:'tiled LZW data not implemented' .
@@ -1389,10 +674,14 @@
(compression == 5) ifTrue:[
^ self readTiledLZWTiffImageData.
].
+ (compression == 6) ifTrue:[
+ ^ self readTiledJPEGTiffImageData.
+ ].
- ^ self fileFormatError:('compression type ' , compression printString , ' not known').
+ ^ self fileFormatError:('compression type ' , compression printString , ' not supported (in tile mode)').
"Created: / 25-08-2017 / 00:19:14 / cg"
+ "Modified: / 25-08-2017 / 16:27:40 / cg"
!
readTiledUncompressedTiffImageData
@@ -1616,10 +905,1164 @@
!TIFFReader methodsFor:'private-reading'!
+decodeTiffTag:tagType numberType:numberType length:length
+ |offset value valueArray
+ val scaleFactor rV gV bV
+ n "{ Class: SmallInteger }"
+ i2 "{ Class: SmallInteger }"
+ i3 "{ Class: SmallInteger }" |
+
+ Verbose == true ifTrue:[ Logger info:'tiffTag: %1' with:tagType ].
+
+ (numberType == 3 "TIFF_SHORT") ifTrue:[
+ "16 bit ushort"
+ valueArray := self readShorts:length signed:false.
+ value := valueArray at:1
+ ] ifFalse:[(numberType == 4 "TIFF_LONG") ifTrue:[
+ "32 bit uinteger"
+ valueArray := self readLongs:length signed:false.
+ value := valueArray at:1
+ ] ifFalse:[(numberType == 2 "TIFF_ASCII") ifTrue:[
+ "ascii characters"
+ value := self readChars:length
+ ] ifFalse:[(numberType == 5 "TIFF_RATIONAL") ifTrue:[
+ "64 (32+32) bit ufraction"
+ valueArray := self readFracts:length signed:false.
+ value := valueArray at:1
+ ] ifFalse:[(numberType == 1 "TIFF_BYTE") ifTrue:[
+ "8bit uinteger"
+ value := self readBytes:length signed:false
+ ] ifFalse:[(numberType == 6 "TIFF_SBYTE") ifTrue:[
+ "TIFF6: 8bit signed integer"
+ value := self readBytes:length signed:true
+ ] ifFalse:[(numberType == 8 "TIFF_SSHORT") ifTrue:[
+ "TIFF6: 16bit signed integer"
+ valueArray := self readShorts:length signed:true.
+ value := valueArray at:1
+ ] ifFalse:[(numberType == 9 "TIFF_SLONG") ifTrue:[
+ "TIFF6: 32bit signed integer"
+ valueArray := self readLongs:length signed:true.
+ value := valueArray at:1
+ ] ifFalse:[(numberType == 10 "TIFF_SRATIONAL") ifTrue:[
+ "TIFF6: 64 (32+32) bit signed fraction"
+ valueArray := self readFracts:length signed:true.
+ value := valueArray at:1
+ ] ifFalse:[(numberType == 11 "TIFF_FLOAT") ifTrue:[
+ "TIFF6: 32 bit IEEE float"
+ valueArray := self readFloats:length.
+ value := valueArray at:1
+ ] ifFalse:[(numberType == 12 "TIFF_DOUBLE") ifTrue:[
+ "TIFF6: 64 bit IEEE double"
+ valueArray := self readDoubles:length.
+ value := valueArray at:1
+
+ ] ifFalse:[(numberType == 7 "TIFF_UNDEFINED") ifTrue:[
+ "8bit anything"
+ value := self readBytes:length signed:false
+
+ "/ the following are preps for the propsed bigTiff format
+ ] ifFalse:[(numberType == 16 "TIFF_LONG8") ifTrue:[
+ "BIGTIFF: 8-byte unsigned integer"
+ valueArray := self readLong8s:length signed:false.
+ value := valueArray at:1.
+ ] ifFalse:[(numberType == 17 "TIFF_SLONG8") ifTrue:[
+ "BIGTIFF: 8-byte signed integer"
+ valueArray := self readLong8s:length signed:true.
+ value := valueArray at:1.
+ ] ifFalse:[(numberType == 18 "TIFF_IFD8") ifTrue:[
+ "BIGTIFF: 8-byte unsigned IFD offset"
+ valueArray := self readLong8s:length signed:false.
+ value := valueArray at:1.
+ ] ifFalse:[
+ isBigTiff ifTrue:[
+ offset := (inStream nextInt64MSB:(byteOrder ~~ #lsb))
+ ] ifFalse:[
+ offset := (inStream nextInt32MSB:(byteOrder ~~ #lsb))
+ ]
+ ]]]]]]]]]]]]]]].
+
+ (tagType between:200 and:299) ifTrue:[
+ (tagType == 254) ifTrue:[
+ "/ New SubfileType
+ "/ REDUCEDIMAGE -> 1
+ "/ PAGE -> 2
+ "/ MASK -> 4
+ "newSubFileType := value."
+
+ "/ 'newSubfiletype ' print. value printNewline.
+ Verbose == true ifTrue:[
+ Logger info:' newSubfiletype: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 255) ifTrue:[
+ "/ Old SubfileType
+ "/ IMAGE -> 1
+ "/ REDUCEDIMAGE -> 2
+ "/ PAGE -> 3
+ subFileType := value.
+
+ Verbose == true ifTrue:[
+ Logger info:' oldSubfiletype: %1' with:value
+ ].
+
+ ^ self
+ ].
+ (tagType == 256) ifTrue:[
+ "ImageWidth"
+ width := value.
+
+ Verbose == true ifTrue:[
+ Logger info:' width: %1' with:value
+ ].
+
+ ^ self
+ ].
+ (tagType == 257) ifTrue:[
+ "ImageHeight"
+ height := value.
+
+ Verbose == true ifTrue:[
+ Logger info:' height: %1' with:value
+ ].
+
+ ^ self
+ ].
+ (tagType == 258) ifTrue:[
+ "bitspersample"
+ bitsPerSample := valueArray.
+
+ Verbose == true ifTrue:[
+ Logger info:' bitspersample: %1' with:valueArray
+ ].
+
+ ^ self
+ ].
+ (tagType == 259) ifTrue:[
+ "/ compression
+ "/ NONE -> 1
+ "/ CCITTRLE -> 2
+ "/ CCITTFAX3 -> 3
+ "/ CCITTFAX4 -> 4
+ "/ LZW -> 5
+ "/ OJPEG -> 6 (old style jpeg)
+ "/ JPEG -> 7 (new style jpeg)
+ "/ ADOBE_DEFLATE -> 8
+ "/ JBIG -> 9 (ITU-T T85)
+ "/ JBIG -> 10 (ITU-T T43)
+
+ "/ NEXT -> 32766 (NeXT 2-bit encoding)
+ "/ CCITTRLEW -> 32771
+ "/ PACKBITS -> 32773
+ "/ THUNDERSCAN -> 32809 (ThunderScan 4-bit encoding)
+ "/ IT8CTPAD -> 32895
+ "/ IT8LW -> 32896
+ "/ IT8MP -> 32897
+ "/ IT8BL -> 32898
+ "/ PIXARFILM -> 32908
+ "/ PIXARLOG -> 32909 (Pixar companded 11-bit ZIP encoding)
+ "/ DEFLATE -> 32946 (PKZIP-style Deflate encoding)
+ "/ DCS -> 32947 (kodac)
+ "/ JBIG -> 34661
+ "/ SGI32 -> 34676 (SGI 32-bit Log Luminance encoding)
+ "/ SGI24 -> 34677 (SGI 24-bit Log Luminance encoding)
+ "/ JPEG2000 -> 34712 JPEG2000
+ "/ NIKON_NEF -> 34713
+ "/ JBIG2 -> 34715
+ compression := value.
+
+ Verbose == true ifTrue:[
+ Logger info:' compression: %1' with:value
+ ].
+
+ ^ self
+ ].
+ (tagType == 262) ifTrue:[
+ "photometric"
+
+ (value between:0 and:10) ifTrue:[
+ photometric := #(
+ whiteIs0 "/ 0 - grayscale or monochrome; faxes
+ blackIs0 "/ 1 - grayscale or monochrome; faxes
+ rgb "/ 2
+ palette "/ 3
+ transparencyMask "/ 4
+ cmyk "/ 5 - color separations
+ YCbCr "/ 6 - CCIR 601
+ nil "/ 7
+ CIElab "/ 8 - 1976 CIE L*a*b*
+ ICClab "/ 9 - ICC L*a*b*
+ ITUlab "/ 10 - see ITO-T- Rec T42 (RFC 2301)
+ ) at:(value + 1)
+ ] ifFalse:[
+ (value == 32803) ifTrue:[
+ photometric := #ColorFilterArray "/ camera rw format
+ ].
+ (value == 32844) ifTrue:[
+ photometric := #PixarLogL
+ ].
+ (value == 32845) ifTrue:[
+ photometric := #PixarLogLuv
+ ].
+ (value == 34892) ifTrue:[
+ photometric := #LinearRaw "/ camera rw format
+ ].
+ ].
+ Verbose == true ifTrue:[
+ Logger info:' photometric: %1 (%2)' with:photometric with:value
+ ].
+ ^ self
+ ].
+ (tagType == 263) ifTrue:[
+ "/ Thresholding
+ "/ BILEVEL -> 1
+ "/ HALFTONE -> 2
+ "/ ERRORDIFFUSE -> 3
+
+ "thresholding := value."
+
+ "/ 'thresholding ' print. value printNewline.
+
+ ^ self
+ ].
+ (tagType == 264) ifTrue:[
+ "CellWidth"
+ "/ 'cellWidth ' print. value printNewline.
+ metaData at:#CellWidth put:value.
+
+ ^ self
+ ].
+ (tagType == 265) ifTrue:[
+ "CellLength"
+ "/ 'cellLength ' print. value printNewline.
+ metaData at:#CellLength put:value.
+ ^ self
+ ].
+ (tagType == 266) ifTrue:[
+ "fillOrder"
+ (value == 1) ifTrue:[
+ fillOrder := #msb
+ ] ifFalse:[
+ (value == 2) ifTrue:[
+ fillOrder := #lsb
+ ] ifFalse:[
+ fillOrder := nil
+ ]
+ ].
+ "/ 'fillorder ' print. fillOrder printNewline.
+ ^ self
+ ].
+ (tagType == 269) ifTrue:[
+ "documentName - info only"
+ "/ 'documentName ' print. value printNewline.
+ metaData at:#DocumentName put:value.
+ ^ self
+ ].
+ (tagType == 270) ifTrue:[
+ "imageDescription - info only"
+ "/ 'imageDescription ' print. value printNewline.
+ metaData at:#ImageDescription put:value.
+ ^ self
+ ].
+ (tagType == 271) ifTrue:[
+ "make - info only"
+ metaData at:#Make put:value.
+ Verbose == true ifTrue:[
+ Logger info:' make: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 272) ifTrue:[
+ "model - info only"
+ metaData at:#Model put:value.
+ Verbose == true ifTrue:[
+ Logger info:' model: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 273) ifTrue:[
+ "stripOffsets"
+ stripOffsets := valueArray.
+ Verbose == true ifTrue:[
+ Logger info:' stripOffsets: %1' with:valueArray
+ ].
+ ^ self
+ ].
+ (tagType == 274) ifTrue:[
+ "Orientation"
+
+ orientation :=
+ #( nil "/ 1 normal (topLeft)
+ unsupported "/ 2 horizontal flip
+ unsupported "/ 3 horizontal & vertical flip
+ vFlip "/ 4 vertical flip
+ unsupported "/ 5 rot 90' counter clock-wise
+ unsupported "/ 6 rot 90' clock-wise
+ unsupported "/ 7 rot 90' & flip
+ unsupported "/ 8 rot 90' ccw & flip
+ ) at:value ifAbsent:#unsupported.
+ metaData at:#Orientation put:value.
+ Verbose == true ifTrue:[
+ Logger info:' orientation: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 277) ifTrue:[
+ samplesPerPixel := value.
+ Verbose == true ifTrue:[
+ Logger info:' samplesperpixel: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 278) ifTrue:[
+ rowsPerStrip := value.
+ Verbose == true ifTrue:[
+ Logger info:' rowsPerStrip: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 279) ifTrue:[
+ "stripbytecount"
+ stripByteCounts := valueArray.
+ "/ 'stripByteCounts Array(' print.
+ "/ stripByteCounts size print.
+ "/ ')' printNewline.
+ Verbose == true ifTrue:[
+ Logger info:' stripByteCounts: %1' with:valueArray
+ ].
+ ^ self
+ ].
+ (tagType == 280) ifTrue:[
+ "/ 'minSampleValue ' print. value printNewline.
+ metaData at:#MinSampleValue put:value.
+ ^ self
+ ].
+ (tagType == 281) ifTrue:[
+ "/ 'maxSampleValue ' print. value printNewline.
+ metaData at:#MaxSampleValue put:value.
+ ^ self
+ ].
+ (tagType == 282) ifTrue:[
+ "/ xResolution
+ metaData at:#ResolutionX put:value.
+ Verbose == true ifTrue:[
+ Logger info:' xResolution: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 283) ifTrue:[
+ "/ yResolution
+ metaData at:#ResolutionY put:value.
+ Verbose == true ifTrue:[
+ Logger info:' yResolution: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 284) ifTrue:[
+ (value == 1) ifTrue:[
+ planarConfiguration := 1
+ ] ifFalse:[
+ (value == 2) ifTrue:[
+ planarConfiguration := 2
+ ] ifFalse:[
+ planarConfiguration := nil
+ ]
+ ].
+ Verbose == true ifTrue:[
+ Logger info:' planarConfiguration: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 285) ifTrue:[
+ "/ 'pageName ' print. value printNewline.
+ metaData at:#PageName put:value.
+ ^ self
+ ].
+ (tagType == 286) ifTrue:[
+ "/ 'xPosition ' print. value printNewline.
+ metaData at:#PositionX put:value.
+ ^ self
+ ].
+ (tagType == 287) ifTrue:[
+ "/ 'yPosition ' print. value printNewline.
+ metaData at:#PositionY put:value.
+ ^ self
+ ].
+ (tagType == 288) ifTrue:[
+ "/ 'freeOffsets ' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 289) ifTrue:[
+ "/ 'freeByteCounts ' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 290) ifTrue:[
+ "/ 'grayResponceUnit' print. value printNewline.
+ metaData at:#GrayResponceUnit put:value.
+ ^ self
+ ].
+ (tagType == 291) ifTrue:[
+ "/ 'grayResponceCurve' print. value printNewline.
+ metaData at:#GrayResponceCurve put:value.
+ ^ self
+ ].
+ (tagType == 292) ifTrue:[
+ "/ group3options (now called T4Options)
+ "/ 2DENCODING -> 1
+ "/ UNCOMPRESSED -> 2
+ "/ FILLBITS -> 4
+
+ group3options := value.
+ "/ 'group3options ' print. group3options printNewline.
+ ^ self
+ ].
+ (tagType == 293) ifTrue:[
+ "/ group4options (now called T6Options)
+ "/ UNCOMPRESSED -> 2
+
+ "group4options := value."
+ "/ 'group4options ' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 296) ifTrue:[
+ "resolutionunit"
+
+ "/ (value == 1) ifTrue:[
+ "/ 'res-unit pixel' printNewline
+ "/ ] ifFalse:[
+ "/ (value == 2) ifTrue:[
+ "/ 'res-unit inch' printNewline
+ "/ ] ifFalse:[
+ "/ (value == 3) ifTrue:[
+ "/ 'res-unit mm' printNewline
+ "/ ] ifFalse:[
+ "/ 'res-unit invalid' printNewline
+ "/ ]
+ "/ ]
+ "/ ].
+ metaData at:#ResolutionUnit put:value.
+ Verbose == true ifTrue:[
+ Logger info:' resolutionUnit: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 297) ifTrue:[
+ "/ 'pageNumber ' print. value printNewline.
+ metaData at:#PageNumber put:value.
+ ^ self
+ ].
+ ].
+
+ (tagType between:300 and:399) ifTrue:[
+ (tagType == 300) ifTrue:[
+ "/ 'colorResponceUnit' print. value printNewline.
+ metaData at:#ColorResponceUnit put:value.
+ ^ self
+ ].
+ (tagType == 301) ifTrue:[
+ "/ 'colorResponceCurve' print. value printNewline.
+ metaData at:#ColorResponceCurve put:value.
+ ^ self
+ ].
+ (tagType == 305) ifTrue:[
+ "software - info only"
+ metaData at:#Software put:value asString.
+ Verbose == true ifTrue:[
+ Logger info:' software: %1' with:value asString
+ ].
+ ^ self
+ ].
+ (tagType == 306) ifTrue:[
+ "dateTime - info only"
+ metaData at:#DateTime put:value asString.
+ Verbose == true ifTrue:[
+ Logger info:' dateTime: %1' with:value asString
+ ].
+ ^ self
+ ].
+ (tagType == 315) ifTrue:[
+ "artist - info only"
+ metaData at:#Artist put:value asString.
+ Verbose == true ifTrue:[
+ Logger info:' artist: %1' with:value asString
+ ].
+ ^ self
+ ].
+ (tagType == 316) ifTrue:[
+ "host computer - info only"
+ metaData at:#HostComputer put:value asString.
+ Verbose == true ifTrue:[
+ Logger info:' host: %1' with:value asString
+ ].
+ ^ self
+ ].
+ (tagType == 317) ifTrue:[
+ "/ 'predictor ' print. predictor printNewline.
+ "/ 1 -> no predictor
+ "/ 2 -> horiz. difference (see tiff spec 6.0)
+ "/ 3 -> flt pnt (see adobe tech notes)
+ "/ 34892 -> horiz difference x2
+ "/ 34893 -> horiz difference x4
+ "/ 34894 -> flt pnt x2
+ "/ 34895 -> flt pnt x4
+ predictor := value.
+ ^ self
+ ].
+ (tagType == 318) ifTrue:[
+ "/ 'whitePoint ' print. value printNewline.
+ metaData at:#WhitePoint put:value.
+ ^ self
+ ].
+ (tagType == 319) ifTrue:[
+ "/ 'primaryChromatics ' print. value printNewline.
+ metaData at:#PrimaryChromatics put:value.
+ ^ self
+ ].
+ (tagType == 320) ifTrue:[
+ "/ 'colorMap (size=' print. valueArray size print. ')' printNewline.
+
+ "
+ the tiff colormap contains 16bit values;
+ our colormap expects 8bit values
+ "
+ n := valueArray size // 3.
+
+ rV := ByteArray uninitializedNew:n.
+ gV := ByteArray uninitializedNew:n.
+ bV := ByteArray uninitializedNew:n.
+ scaleFactor := 255.0 / 16rFFFF.
+ i2 := n+1.
+ i3 := 2*n+1.
+ 1 to:n do:[:vi |
+ val := ((valueArray at:vi) * scaleFactor) rounded.
+ rV at:vi put:val.
+ val := ((valueArray at:i2) * scaleFactor) rounded.
+ gV at:vi put:val.
+ val := ((valueArray at:i3) * scaleFactor) rounded.
+ bV at:vi put:val.
+ i2 := i2 + 1.
+ i3 := i3 + 1.
+ ].
+ colorMap := MappedPalette redVector:rV greenVector:gV blueVector:bV.
+ ^ self
+ ].
+ (tagType == 321) ifTrue:[
+ "/ 'halftonehints' print. value printNewline.
+ metaData at:#HalftoneHints put:value.
+ ^ self
+ ].
+ (tagType == 322) ifTrue:[
+ "/ 'tilewidth' print. value printNewline.
+ metaData at:#TileWidth put:value.
+ ^ self
+ ].
+ (tagType == 323) ifTrue:[
+ "/ 'tilelength' print. value printNewline.
+ metaData at:#TileLength put:value.
+ ^ self
+ ].
+ (tagType == 324) ifTrue:[
+ "/ 'tileoffsets' print. value printNewline.
+ metaData at:#TileOffsets put:valueArray.
+ ^ self
+ ].
+ (tagType == 325) ifTrue:[
+ "/ 'tilebytecounts' print. value printNewline.
+ metaData at:#TileByteCounts put:valueArray.
+ ^ self
+ ].
+ (tagType == 326) ifTrue:[
+ "/ 'badFaxLines' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 327) ifTrue:[
+ "CleanFaxData"
+
+ "/ 'cleanfaxdata' print. value printNewline.
+ "/ (value == 0) ifTrue:[
+ "/ 'no lines with incorrect pixel counts' printNewline
+ "/ ] ifFalse:[
+ "/ (value == 1) ifTrue:[
+ "/ 'incorrect lines were regenerated' printNewline
+ "/ ] ifFalse:[
+ "/ (value == 2) ifTrue:[
+ "/ 'incorrect lines were not regenerated' printNewline
+ "/ ] ifFalse:[
+ "/ 'cleanfaxdata invalid' printNewline
+ "/ ]
+ "/ ]
+ "/ ].
+
+ ^ self
+ ].
+ (tagType == 328) ifTrue:[
+ "/ 'consecutiveBadFaxLines' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 330) ifTrue:[
+ "/ subifd
+ Verbose == true ifTrue:[
+ Logger info:' subifd: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 332) ifTrue:[
+ "/ 'ink set' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 333) ifTrue:[
+ "/ 'ink names' print. value printNewline.
+ metaData at:#IncNames put:value.
+ ^ self
+ ].
+ (tagType == 334) ifTrue:[
+ "/ 'numinks' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 336) ifTrue:[
+ "/ 'dot range' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 337) ifTrue:[
+ "/ 'target printer' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 338) ifTrue:[
+ "/ 'extrasamples' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 339) ifTrue:[
+ "/ 'sample format' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 340) ifTrue:[
+ "/ 'min sample value' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 341) ifTrue:[
+ "/ 'max sample value' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 342) ifTrue:[
+ "/ 'transfer range' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 343) ifTrue:[
+ "/ 'clip path' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 344) ifTrue:[
+ "/ 'xclip path units' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 345) ifTrue:[
+ "/ 'yclip path units' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 347) ifTrue:[
+ "/ 'jpegtables' print. value printNewline.
+ ^ self
+ ].
+ ].
+
+ (tagType between:400 and:499) ifTrue:[
+ (tagType == 400) ifTrue:[
+ "/ 'GlobalParametersIFD' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 401) ifTrue:[
+ "/ 'ProfileType' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 402) ifTrue:[
+ "/ 'FaxProfile' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 403) ifTrue:[
+ "/ 'CodingMethods' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 404) ifTrue:[
+ "/ 'VersionYear' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 405) ifTrue:[
+ "/ 'ModeNumber' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 433) ifTrue:[
+ "/ 'Decode' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 434) ifTrue:[
+ "/ 'DefaultImageColor' print. value printNewline.
+ ^ self
+ ].
+ ].
+
+ (tagType between:500 and:599) ifTrue:[
+ "/ obsolete JPEG tags
+ (tagType == 512) ifTrue:[
+ "/ 'jpeg proc' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 513) ifTrue:[
+ "/ 'jpeg proc' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 514) ifTrue:[
+ "/ 'jpeg ifByteCount' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 515) ifTrue:[
+ "/ 'jpeg restartInterval' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 517) ifTrue:[
+ "/ 'jpeg glossLessPredictors' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 518) ifTrue:[
+ "/ 'jpeg pointTransform' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 519) ifTrue:[
+ "/ 'jpeg qTables' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 520) ifTrue:[
+ "/ 'jpeg dcTables' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 521) ifTrue:[
+ "/ 'jpeg acTables' print. value printNewline.
+ ^ self
+ ].
+
+
+ (tagType == 529) ifTrue:[
+ "/ ycbr coeff
+ Verbose == true ifTrue:[
+ Logger info:' ycbr coeff: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 530) ifTrue:[
+ "/ ycbr subsampling
+ Verbose == true ifTrue:[
+ Logger info:' ycbr subsampling: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 531) ifTrue:[
+ "/ ycbr positioning
+ Verbose == true ifTrue:[
+ Logger info:' ycbr positioning: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 532) ifTrue:[
+ "/ referenceBlackWhite
+ Verbose == true ifTrue:[
+ Logger info:' referenceBlackWhite: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 559) ifTrue:[
+ "/ 'stripRowCounts' print. value printNewline.
+ ^ self
+ ].
+ ].
+
+ (tagType between:700 and:799) ifTrue:[
+ (tagType == 700) ifTrue:[
+ "XMLPACKET"
+
+ "/ In TIFF files, the XML Packet containing XMP metadata is pointed to
+ "/ by an entry in the Image File Directory (IFD). That entry has a Tag
+ "/ value of 700, as shown in Table 1.1, "TIFF IFD Directory Entry for
+ "/ XML Packets
+
+ Verbose == true ifTrue:[
+ Logger info:' XMLPACKET: %1' with:value asString
+ ].
+ ^ self
+ ].
+ ].
+
+ (tagType between:32000 and:32999) ifTrue:[
+ (tagType == 32781) ifTrue:[
+ "/'imageid' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 32932) ifTrue:[
+ "/'wang annotation' print. value printNewline.
+ ^ self
+ ].
+
+ "/ Private Island graphics tags
+ (tagType == 32953) ifTrue:[
+ "/'ref points' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 32954) ifTrue:[
+ "/ 'regionTagPoint' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 32955) ifTrue:[
+ "/ 'regionWarpCorners' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 32956) ifTrue:[
+ "/ 'regionAffine' print. value printNewline.
+ ^ self
+ ].
+
+
+ "/ Private SGI tags
+ (tagType == 32995) ifTrue:[
+ "/ 'matteing' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 32996) ifTrue:[
+ "/ 'datatype' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 32997) ifTrue:[
+ "/ 'imagedepth' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 32998) ifTrue:[
+ "/ 'tiledepth' print. value printNewline.
+ ^ self
+ ].
+ ].
+
+ (tagType between:33000 and:33999) ifTrue:[
+ "/ Private Pixar tags
+ (tagType == 33300) ifTrue:[
+ "/ 'image full width' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 33301) ifTrue:[
+ "/ 'image full length' print. value printNewline.
+ ^ self
+ ].
+
+ "/ Private Eastman Kodak tags
+ (tagType == 33405) ifTrue:[
+ "/ 'write serial number' print. value printNewline.
+ ^ self
+ ].
+
+ "/ unknown
+ (tagType == 33432) ifTrue:[
+ "/ 'copyright' print. value printNewline.
+ ^ self
+ ].
+
+ (tagType == 33550) ifTrue:[
+ "/ 'geotiff modelpixelscaletag' print. value printNewline.
+ ^ self
+ ].
+
+ (tagType == 33723) ifTrue:[
+ "/ 'RICHTIFFIPTC' print. value printNewline.
+ ^ self
+ ].
+ ].
+
+ (tagType between:34000 and:34999) ifTrue:[
+ "/ Private Texas instruments
+ (tagType == 34232) ifTrue:[
+ "/ 'sequence frame count' print. value printNewline.
+ ^ self
+ ].
+
+ "/ Private Pixel magic
+ (tagType == 34232) ifTrue:[
+ "/ 'jbig options' print. value printNewline.
+ ^ self
+ ].
+
+ "/ private Photoshop
+ (tagType == 34377) ifTrue:[
+ "/ 'photoshop RICHTIFFIPTC' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 34665) ifTrue:[
+ "/ EXIFIFD
+ Verbose == true ifTrue:[
+ Logger info:' EXIFIFD: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 34675) ifTrue:[
+ "/ 'ICCPROFILE' print. value printNewline.
+ ^ self
+ ].
+
+ (tagType == 34732) ifTrue:[
+ "/ 'ImageLayer' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 34859) ifTrue:[
+ "/ '???' print. value printNewline.
+ Verbose == true ifTrue:[
+ Logger info:' ?: %1' with:value
+ ].
+ ^ self
+ ].
+
+ "/ More Private SGI
+ (tagType == 34908) ifTrue:[
+ "/ 'fax recv params' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 34909) ifTrue:[
+ "/ 'fax subaddress' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 34910) ifTrue:[
+ "/ 'fax recv time' print. value printNewline.
+ ^ self
+ ].
+ ].
+
+ (tagType between:36000 and:36999) ifTrue:[
+ (tagType == 36867) ifTrue:[
+ "/ '???' print. value printNewline.
+ ^ self
+ ].
+ ].
+
+ (tagType between:37000 and:37999) ifTrue:[
+ (tagType == 37390) ifTrue:[
+ "/ '???' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 37391) ifTrue:[
+ "/ '???' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 37392) ifTrue:[
+ "/ '???' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 37398) ifTrue:[
+ "/ '???' print. value printNewline.
+ ^ self
+ ].
+ ].
+
+ (tagType between:42000 and:42999) ifTrue:[
+ (tagType == 42112) ifTrue:[
+ "/ 'GDAL_METADATA' print. value printNewline.
+ ^ self
+ ].
+ ].
+
+ "/ dng tags (see http://wwwimages.adobe.com/content/dam/Adobe/en/products/photoshop/pdfs/dng_spec_1.4.0.0.pdf)
+ (tagType between:50000 and:50999) ifTrue:[
+ (tagType == 50706) ifTrue:[
+ "/ DNGVersion
+ Verbose == true ifTrue:[
+ Logger info:' DNGVersion: %1' with:value
+ ].
+ ^ self
+ ].
+ (tagType == 50707) ifTrue:[
+ "/ DNGBackwardVersion
+ ^ self
+ ].
+ (tagType == 50708) ifTrue:[
+ "/ UniqueCameraModel
+ Verbose == true ifTrue:[
+ Logger info:' UniqueCameraModel: %1' with:value asString
+ ].
+ ^ self
+ ].
+ (tagType == 50709) ifTrue:[
+ "/ LocalizedCameraModel
+ Verbose == true ifTrue:[
+ Logger info:' LocalizedCameraModel: %1' with:value asString
+ ].
+ ^ self
+ ].
+ (tagType == 50710) ifTrue:[
+ "/ 'CFAPlaneColor' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50711) ifTrue:[
+ "/ 'CFALayout' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50712) ifTrue:[
+ "/ 'LinearizationTable' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50713) ifTrue:[
+ "/ 'BlackLevelRepeatDim' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50714) ifTrue:[
+ "/ 'BlackLevel' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50715) ifTrue:[
+ "/ 'BlackLevelDeltaH' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50716) ifTrue:[
+ "/ 'BlackLevelDeltaV' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50717) ifTrue:[
+ "/ 'WhiteLevel' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50718) ifTrue:[
+ "/ 'DefaultScale' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50719) ifTrue:[
+ "/ 'DefaultCropOrigin' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50720) ifTrue:[
+ "/ 'DefaultCropSize' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50721) ifTrue:[
+ "/ 'ColorMatrix1' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50722) ifTrue:[
+ "/ 'ColorMatrix2' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50723) ifTrue:[
+ "/ 'CameraCalibrarion1' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50724) ifTrue:[
+ "/ 'CameraCalibrarion2' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50725) ifTrue:[
+ "/ 'ReductionMatrix1' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50726) ifTrue:[
+ "/ 'ReductionMatrix2' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50727) ifTrue:[
+ "/ 'AnalogBalance' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50728) ifTrue:[
+ "/ 'AsShotNeutral' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50729) ifTrue:[
+ "/ 'AsShotWhiteXY' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50730) ifTrue:[
+ "/ 'BaselineExposure' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50731) ifTrue:[
+ "/ 'BaselineNoise' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50732) ifTrue:[
+ "/ 'BaselineSharpness' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50733) ifTrue:[
+ "/ 'ByerGreenSplit' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50734) ifTrue:[
+ "/ 'LinearResponseLimit' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50735) ifTrue:[
+ "/ 'CameraSerialNumber' print. value printNewline.
+ Verbose == true ifTrue:[
+ Logger info:' CameraSerialNumber: %1' with:value asString
+ ].
+ ^ self
+ ].
+ (tagType == 50736) ifTrue:[
+ "/ 'LensInfo' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50737) ifTrue:[
+ "/ 'ChromaBlurRadius' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50738) ifTrue:[
+ "/ 'AntiAliasStrength' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50739) ifTrue:[
+ "/ 'ShadowScale' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50740) ifTrue:[
+ "/ 'DNGPrivateData' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50741) ifTrue:[
+ "/ 'MakerNoteSafety' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50778) ifTrue:[
+ "/ 'CalibrationIlluminant1' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50779) ifTrue:[
+ "/ 'CalibrationIlluminant2' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50780) ifTrue:[
+ "/ 'BestQualityScale' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50781) ifTrue:[
+ "/ 'RawDataUniqueID' print. value printNewline.
+ ^ self
+ ].
+ (tagType == 50827) ifTrue:[
+ "/ 'OriginalRawFileName' print. value printNewline.
+ ^ self
+ ].
+ ].
+
+"/
+"/ 'TIFFReader: tag:' print. tagType print. ' typ:' print. numberType print.
+"/ ' len:' print. length print. ' offs:' print. offset print.
+"/ ' val:' print. value print. ' valArr:' print. valueArray printNewline.
+"/
+ 'TIFFReader [warning]: unknown tag type ' errorPrint. tagType errorPrintCR
+
+ "Modified (format): / 23-05-2017 / 16:12:58 / mawalch"
+ "Modified (format): / 25-08-2017 / 17:02:57 / cg"
+!
+
positionToStrip:stripNr
inStream position:(stripOffsets at:stripNr).
!
+positionToTile:tileNr
+ inStream position:((metaData at:#'TileOffsets') at:tileNr).
+
+ "Created: / 25-08-2017 / 13:43:30 / cg"
+!
+
readBytes:n signed:isSigned
"read n 8bit signed or unsigned integers and return them in an array or byteArray"