# HG changeset patch # User Claus Gittinger # Date 1503677244 -7200 # Node ID 5d915912216f442b7f97cfba55136411e5f617e6 # Parent 3cf74e1b8c214c2ffae015730798140bad662348 #FEATURE by cg class: TIFFReader class definition added: #positionToTile: #readTiledJPEGTiffImageData changed: #decodeTiffTag:numberType:length: #readThunderScanTiffImageData #readTiledTiffImageData class: TIFFReader class comment/format in: #documentation diff -r 3cf74e1b8c21 -r 5d915912216f TIFFReader.st --- 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"