annotate src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html @ 16334:96d44ff3c70f

8154058: [TIFF] ignoreMetadata parameter of TIFFImageReader's setInput() method affects TIFFImageReadParam in non-obvious way Summary: Add readUnknownTags to TIFFImageReadParam and add ReadParamTest Reviewed-by: prr
author bpb
date Tue, 13 Dec 2016 12:02:37 -0800
parents df43cdd4bb33
children
rev   line source
bpb@13242 1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
bpb@13242 2 <html>
bpb@13242 3 <head>
bpb@13242 4 <!--
bpb@13242 5 Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
bpb@13242 6 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
bpb@13242 7
bpb@13242 8 This code is free software; you can redistribute it and/or modify it
bpb@13242 9 under the terms of the GNU General Public License version 2 only, as
bpb@13242 10 published by the Free Software Foundation. Oracle designates this
bpb@13242 11 particular file as subject to the "Classpath" exception as provided
bpb@13242 12 by Oracle in the LICENSE file that accompanied this code.
bpb@13242 13
bpb@13242 14 This code is distributed in the hope that it will be useful, but WITHOUT
bpb@13242 15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
bpb@13242 16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
bpb@13242 17 version 2 for more details (a copy is included in the LICENSE file that
bpb@13242 18 accompanied this code).
bpb@13242 19
bpb@13242 20 You should have received a copy of the GNU General Public License version
bpb@13242 21 2 along with this work; if not, write to the Free Software Foundation,
bpb@13242 22 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
bpb@13242 23
bpb@13242 24 Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
bpb@13242 25 or visit www.oracle.com if you need additional information or have any
bpb@13242 26 questions.
bpb@13242 27 -->
bpb@13242 28
bpb@13242 29 <title>TIFF Metadata Format Specification and Usage Notes</title>
bpb@13242 30 </head>
bpb@13242 31
bpb@13242 32 <body bgcolor="white">
bpb@13242 33
bpb@13242 34 <center><h1>
bpb@13242 35 TIFF Metadata Format Specification and Usage Notes
bpb@13242 36 </h1></center>
bpb@13242 37
bpb@13242 38 <p>
bpb@13242 39 <a href="#Reading">Reading Images</a><br/>
bpb@13242 40 <font size="-1">
bpb@13242 41 <ul>
bpb@13242 42 <li><a href="#ColorConversionRead">Color Conversion</a></li>
bpb@13242 43 <li><a href="#ColorSpacesRead">Color Spaces</a></li>
bpb@13242 44 <li><a href="#ICCProfilesRead">ICC Profiles</a></li>
bpb@13242 45 <li><a href="#MetadataIssuesRead">Metadata Issues</a>
bpb@13242 46 <font size="-2">
bpb@13242 47 <ul>
bpb@13242 48 <li><a href="#MapNativeStandard">Native to Standard Metadata Mapping</a></li>
bpb@13242 49 </ul>
bpb@13242 50 </font>
bpb@13242 51 </li>
bpb@13242 52 <li><a href="#ExifRead">Reading Exif Images</a>
bpb@13242 53 <font size="-2">
bpb@13242 54 <ul>
bpb@13242 55 <li><a href="#ExifReadTIFF">Reading Uncompressed Exif Images</a></li>
bpb@13242 56 <li><a href="#ExifReadJPEG">Reading Compressed Exif Images</a></li>
bpb@13242 57 </ul>
bpb@13242 58 </font>
bpb@13242 59 </li>
bpb@13242 60 </ul>
bpb@13242 61 </font>
bpb@13242 62 <a href="#Writing">Writing Images</a><br/>
bpb@13242 63 <font size="-1">
bpb@13242 64 <ul>
bpb@13242 65 <li><a href="#Compression">Compression</a></li>
bpb@13242 66 <li><a href="#ColorConversionWrite">Color Conversion</a></li>
bpb@13242 67 <li><a href="#ICCProfilesWrite">ICC Profiles</a></li>
bpb@13242 68 <li><a href="#MetadataIssuesWrite">Metadata Issues</a></li>
bpb@13242 69 <font size="-2">
bpb@13242 70 <ul>
bpb@13242 71 <li><a href="#MapStandardNative">Standard to Native Metadata Mapping</a></li>
bpb@13242 72 </ul>
bpb@13242 73 </font>
bpb@13242 74 <li><a href="#ExifWrite">Writing Exif Images</a>
bpb@13242 75 <font size="-2">
bpb@13242 76 <ul>
bpb@13242 77 <li><a href="#ExifWriteTIFF">Writing Uncompressed Exif Images</a></li>
bpb@13242 78 <li><a href="#ExifWriteJPEG">Writing Compressed Exif Images</a></li>
bpb@13242 79 </ul>
bpb@13242 80 </font>
bpb@13242 81 </li>
bpb@13242 82 </ul>
bpb@13242 83 </font>
bpb@13242 84 <a href="#StreamMetadata">Native Stream Metadata Format</a><br/>
bpb@13242 85 <a href="#ImageMetadata">Native Image Metadata Format</a>
bpb@13242 86 </p>
bpb@13242 87
bpb@13242 88 <h3><a name="Reading"/>Reading Images</h3>
bpb@13242 89
bpb@13242 90 TIFF images are read by an <a href="../../ImageReader.html">ImageReader</a>
bpb@13242 91 which may be controlled by its public interface as well as via a supplied
bpb@13242 92 <a href="../../plugins/tiff/TIFFImageReadParam.html">TIFFImageReadParam</a>.
bpb@13242 93
bpb@13242 94 <!-- <h4>Supported Image Types</h4> -->
bpb@13242 95
bpb@13242 96 <!-- Table? -->
bpb@13242 97
bpb@13242 98 <h4><a name="ColorConversionRead"/>Color Conversion</h4>
bpb@13242 99
bpb@13242 100 <p>If the source image data
bpb@13242 101 have photometric type CIE L*a*b* or YCbCr, and the destination color space
bpb@13242 102 type is RGB, then the source image data will be automatically converted to
bpb@13242 103 RGB using an internal color converter.</p>
bpb@13242 104
bpb@13242 105 <h4><a name="ColorSpacesRead"/>Color Spaces</h4>
bpb@13242 106
bpb@13242 107 The raw color space assigned by default, i.e., in the absence of a
bpb@13242 108 user-supplied <a href="../../ImageTypeSpecifier.html">ImageTypeSpecifier</a>,
bpb@13242 109 will be the first among the following which applies:
bpb@13242 110
bpb@13242 111 <ul>
bpb@13242 112 <li>A color space created from the <a href="#ICCProfilesRead">ICC Profile</a>
bpb@13242 113 metadata field if it is present and compatible with the image data
bpb@13242 114 layout.</li>
bpb@13242 115 <a name="nonICCProfile"><li>sRGB if the image is monochrome/bilevel
bpb@13242 116 (a two-level color map is created internally).</li>
bpb@13242 117 <li>sRGB if the image is palette-color.</li>
bpb@13242 118 <li>Linear RGB if the image has three samples per pixel, has photometric type
bpb@13242 119 CIE L*a*b*, or has photometric type YCbCr and is <i>not</i>
bpb@13242 120 JPEG-compressed.</li>
bpb@13242 121 <li>A <a href="#DefaultCMYK">default CMYK color space</a> if the image has
bpb@13242 122 photometric type CMYK and four samples per pixel.</li>
bpb@13242 123 <li>Grayscale if the image has one or two samples per pixel and uniformly
bpb@13242 124 1, 2, 4, 8, 16, or 32 bits per sample or is floating point.</li>
bpb@13242 125 <li>sRGB if the image has three or four samples per pixel and uniformly
bpb@13242 126 1, 2, 4, 8, 16, or 32 bits per sample or is floating point.</li>
bpb@13242 127 <li>A fabricated, <a href="#GenericCS">generic color space</a> if the image
bpb@13242 128 has more than four samples per pixel and the number of bits per sample for
bpb@13242 129 all bands is the same and is a multiple of 8.</li>
bpb@13242 130 <li>Grayscale if the image has one or two samples per pixel regardless of
bpb@13242 131 the number of bits per sample.</li>
bpb@13242 132 <li>sRGB if the image has three or four samples per pixel regardless of
bpb@13242 133 the number of bits per sample.</li>
bpb@13242 134 <li>A fabricated, <a href="#GenericCS">generic color space</a> if the image
bpb@13242 135 has more than four samples per pixel regardless of the number of bits per
bpb@13242 136 sample.</li>
bpb@13242 137 </ul>
bpb@13242 138
bpb@13242 139 <p><a name="DefaultCMYK"/>The normalized color coordinate transformations
bpb@13242 140 used for the default CMYK color space are defined as follows:
bpb@13242 141
bpb@13242 142 <ul>
bpb@13242 143 <li>CMYK to linear RGB
bpb@13242 144 <pre>
bpb@13242 145 R = (1 - K)*(1 - C)
bpb@13242 146 G = (1 - K)*(1 - M)
bpb@13242 147 B = (1 - K)*(1 - Y)
bpb@13242 148 </pre>
bpb@13242 149 </li>
bpb@13242 150 <li>Linear RGB to CMYK
bpb@13242 151 <pre>
bpb@13242 152 K = min{1 - R, 1 - G, 1 - B}
bpb@13242 153 if(K != 1) {
bpb@13242 154 C = (1 - R - K)/(1 - K)
bpb@13242 155 M = (1 - G - K)/(1 - K)
bpb@13242 156 Y = (1 - B - K)/(1 - K)
bpb@13242 157 } else {
bpb@13242 158 C = M = Y = 0
bpb@13242 159 }
bpb@13242 160 </pre>
bpb@13242 161 </li>
bpb@13242 162 </ul>
bpb@13242 163 </p>
bpb@13242 164
bpb@13242 165 <p><a name="GenericCS"/>The generic color space used when no other color space
bpb@13242 166 can be inferred is provided merely to enable the data to be loaded. It is not
bpb@13242 167 intended to provide accurate conversions of any kind.</p>
bpb@13242 168
bpb@13242 169 <p>If the data are known to be in a color space not correctly handled by the
bpb@13242 170 foregoing, then an <code>ImageTypeSpecifier</code> should be
bpb@13242 171 supplied to the reader and should be derived from a color space which is correct
bpb@13242 172 for the data in question.</p>
bpb@13242 173
bpb@13242 174 <h4><a name="ICCProfilesRead"/>ICC Profiles</h4>
bpb@13242 175
bpb@13242 176 If an ICC profile is contained in the image metadata
bpb@13242 177 (<a href="../../plugins/tiff/BaselineTIFFTagSet.html">
bpb@13242 178 BaselineTIFFTagSet</a>.TAG_ICC_PROFILE, tag number 34675),
bpb@13242 179 an attempt will be made to use it to create the color space
bpb@13242 180 of the loaded image. It will be used if the data layout is of component type
bpb@13242 181 and the number of samples per pixel equals or is one greater than the number
bpb@13242 182 of components described by the ICC profile. If the ICC profile is not used
bpb@13242 183 then the color space will be inferred in one of the subsequent steps described
bpb@13242 184 <a href="#nonICCProfile">above</a>.
bpb@13242 185
bpb@13242 186 <p>If for some reason the embedded ICC profile is not used automatically, then
bpb@13242 187 it may be used manually by following this procedure:
bpb@13242 188
bpb@13242 189 <ol>
bpb@13242 190 <li>Obtain the image metadata from
bpb@13242 191 <code>ImageReader.getImageMetadata</code></li>
bpb@13242 192 <li>Extract the ICC profile field and its value.</li>
bpb@13242 193 <li>Create an <a href="../../../../java/awt/color/ICC_ColorSpace.html">
bpb@13242 194 ICC_ColorSpace</a> from an
bpb@13242 195 <a href="../../../../java/awt/color/ICC_Profile.html">
bpb@13242 196 ICC_Profile</a> created from the ICC profile field data
bpb@13242 197 using <code>ICC_Profile.getInstance(byte[])</code>.</li>
bpb@13242 198 <li>Create an <code>ImageTypeSpecifier</code> from the new color
bpb@13242 199 space using one of its factory methods which accepts an
bpb@13242 200 <code>ICC_ColorSpace</code>.
bpb@13242 201 <li>Create a compatible <a href="../../ImageReadParam.html">ImageReadParam</a>
bpb@13242 202 and set the <code>ImageTypeSpecifier</code> using
bpb@13242 203 <code>ImageReadParam.setDestinationType</code>.</li>
bpb@13242 204 <li>Pass the parameter object to the appropriate <code>read</code> method.</li>
bpb@13242 205 </ol>
bpb@13242 206 </p>
bpb@13242 207
bpb@13242 208 <p>If the inferred color space not based on the ICC Profile field is compatible
bpb@13242 209 with the ICC profile-based color space, then a second
bpb@13242 210 <code>ImageTypeSpecifier</code> derived from this inferred color
bpb@13242 211 space will be included in the
bpb@13242 212 <a href="../../../../java/util/Iterator.html">Iterator</a> returned by
bpb@13242 213 <code>ImageReader.getImageTypes</code>. If the iterator contains
bpb@13242 214 more than one type, the first one will be based on the ICC profile and the
bpb@13242 215 second on the inferred color space.</p>
bpb@13242 216
bpb@13242 217 <h4><a name="MetadataIssuesRead"/>Metadata Issues</h4>
bpb@13242 218
bpb@16334 219 By default all recognized fields in the TIFF image file directory (IFD) are
bpb@16334 220 loaded into the native image metadata object. Which fields are loaded may be
bpb@16334 221 controlled by setting which TIFF tags the reader is allowed to recognize,
bpb@16334 222 whether to read fields with unrecognized tags, and whether to ignore all
bpb@16334 223 metadata. The reader is informed to disregard all metadata as usual via the
bpb@16334 224 <code>ignoreMetadata</code> parameter of
bpb@13242 225 <code>ImageReader.setInput(Object,boolean,boolean)</code>. It is
bpb@13242 226 informed of which <a href="../../plugins/tiff/TIFFTag.html">TIFFTag</a>s to
bpb@13242 227 recognize or not to recognize via
bpb@16334 228 <code>TIFFImageReadParam.addAllowedTagSet(TIFFTagSet)</code> and
bpb@13242 229 <code>TIFFImageReadParam.removeAllowedTagSet(TIFFTagSet)</code>.
bpb@16334 230 If <code>ignoreMetadata</code> is <code>true</code>, then only metadata
bpb@16334 231 essential to reading the image will be loaded into the native image metadata
bpb@16334 232 object. If <code>ignoreMetadata</code> is <code>false</code>, then the reader
bpb@16334 233 will by default load into the native image metadata object only those fields
bpb@16334 234 which are either essential to reading the image or have a <code>TIFFTag</code>
bpb@16334 235 contained in the one of the allowed <code>TIFFTagSet</code>s. Reading of
bpb@16334 236 fields with tags not in the allowed <code>TIFFTagSet</code>s may be forced
bpb@16334 237 by passing in a <code>TIFFImageReadParam</code> on which
bpb@16334 238 <code>TIFFImageReadParam.setReadUnknownTags(boolean)</code> has been
bpb@16334 239 invoked with parameter <code>true</code>.
bpb@13242 240
bpb@13242 241 <p>Use of a <a href="../../plugins/tiff/TIFFDirectory.html">TIFFDirectory</a>
bpb@13242 242 object may simplify gaining access to metadata values. An instance of
bpb@13242 243 <code>TIFFDirectory</code> may be created from the <code>IIOMetadata</code>
bpb@13242 244 object returned by the TIFF reader using the
bpb@13242 245 <code>TIFFDirectory.createFromMetadata</code> method.</p>
bpb@13242 246
bpb@13242 247 <h5><a name="MapNativeStandard"/>
bpb@13242 248 Mapping of TIFF Native Image Metadata to the Standard Metadata Format</h5>
bpb@13242 249
bpb@13242 250 The derivation of standard metadata format
bpb@13242 251 <a href="standard_metadata.html">javax_imageio_1.0</a>
bpb@13242 252 elements from <a href="#ImageMetadata">TIFF native image metadata</a> is given
bpb@13242 253 in the following table.
bpb@13242 254
bpb@13242 255 <p>
bpb@13242 256 <table border="1">
bpb@13242 257 <tr>
bpb@13242 258 <th>Standard Metadata Element</th>
bpb@13242 259 <th>Derivation from TIFF Fields</th>
bpb@13242 260 </tr>
bpb@13242 261 <tr>
bpb@13242 262 <td>/Chroma/ColorSpaceType@name</td>
bpb@13242 263 <td>PhotometricInterpretation: WhiteIsZero, BlackIsZero, TransparencyMask =
bpb@13242 264 "GRAY"; RGB, PaletteColor => "RGB"; CMYK => "CMYK";
bpb@13242 265 YCbCr => "YCbCr";
bpb@13242 266 CIELab, ICCLab => "Lab".</td>
bpb@13242 267 </tr>
bpb@13242 268 <tr>
bpb@13242 269 <td>/Chroma/NumChannels@value</td>
bpb@13242 270 <td>SamplesPerPixel</td>
bpb@13242 271 </tr>
bpb@13242 272 <tr>
bpb@13242 273 <td>/Chroma/BlackIsZero@value</td>
bpb@13242 274 <td>"TRUE" <=> PhotometricInterpretation => WhiteIsZero</td>
bpb@13242 275 </tr>
bpb@13242 276 <tr>
bpb@13242 277 <td>/Chroma/Palette</td>
bpb@13242 278 <td>ColorMap</td>
bpb@13242 279 </tr>
bpb@13242 280 <tr>
bpb@13242 281 <td>/Compression/CompressionTypeName@value</td>
bpb@13242 282 <td>Compression: Uncompressed => "none"; CCITT 1D => "CCITT
bpb@13242 283 RLE";
bpb@13242 284 Group 3 Fax => "CCITT T.4"; Group 4 Fax => "CCITT T.6";
bpb@13242 285 LZW => "LZW";
bpb@13242 286 JPEG => "Old JPEG"; New JPEG => "JPEG"; Zlib =>> "ZLib"; PackBits =>
bpb@13242 287 "PackBits";
bpb@13242 288 Deflate => "Deflate"; Exif JPEG => "JPEG".</td>
bpb@13242 289 </tr>
bpb@13242 290 <tr>
bpb@13242 291 <td>/Compression/Lossless@value</td>
bpb@13242 292 <td>Compression: JPEG or New JPEG => "FALSE"; otherwise "TRUE".</td>
bpb@13242 293 </tr>
bpb@13242 294 <tr>
bpb@13242 295 <td>/Data/PlanarConfiguration@value</td>
bpb@13242 296 <td>Chunky => "PixelInterleaved"; Planar => "PlaneInterleaved".</td>
bpb@13242 297 </tr>
bpb@13242 298 <tr>
bpb@13242 299 <td>/Data/SampleFormat@value</td>
bpb@13242 300 <td>PhotometricInterpretation PaletteColor => "Index";
bpb@13242 301 SampleFormat unsigned integer data => "UnsignedIntegral";
bpb@13242 302 SampleFormat two's complement signed integer data => "SignedIntegral";
bpb@13242 303 SampleFormat IEEE floating point data => "Real";
bpb@13242 304 otherwise element not emitted.
bpb@13242 305 </td>
bpb@13242 306 </tr>
bpb@13242 307 <tr>
bpb@13242 308 <td>/Data/BitsPerSample@value</td>
bpb@13242 309 <td>BitsPerSample as a space-separated list.</td>
bpb@13242 310 </tr>
bpb@13242 311 <tr>
bpb@13242 312 <td>/Data/SampleMSB@value</td>
bpb@13242 313 <td>FillOrder: left-to-right => space-separated list of BitsPerSample-1;
bpb@13242 314 right-to-left => space-separated list of 0s.</td>
bpb@13242 315 </tr>
bpb@13242 316 <tr>
bpb@13242 317 <td>/Dimension/PixelAspectRatio@value</td>
bpb@13242 318 <td>(1/XResolution)/(1/YResolution)</td>
bpb@13242 319 </tr>
bpb@13242 320 <tr>
bpb@13242 321 <td>/Dimension/ImageOrientation@value</td>
bpb@13242 322 <td>Orientation</td>
bpb@13242 323 </tr>
bpb@13242 324 <tr>
bpb@13242 325 <td>/Dimension/HorizontalPixelSize@value</td>
bpb@13242 326 <td>1/XResolution in millimeters if ResolutionUnit is not None.</td>
bpb@13242 327 </tr>
bpb@13242 328 <tr>
bpb@13242 329 <td>/Dimension/VerticalPixelSize@value</td>
bpb@13242 330 <td>1/YResolution in millimeters if ResolutionUnit is not None.</td>
bpb@13242 331 </tr>
bpb@13242 332 <tr>
bpb@13242 333 <td>/Dimension/HorizontalPosition@value</td>
bpb@13242 334 <td>XPosition in millimeters if ResolutionUnit is not None.</td>
bpb@13242 335 </tr>
bpb@13242 336 <tr>
bpb@13242 337 <td>/Dimension/VerticalPosition@value</td>
bpb@13242 338 <td>YPosition in millimeters if ResolutionUnit is not None.</td>
bpb@13242 339 </tr>
bpb@13242 340 <tr>
bpb@13242 341 <td>/Document/FormatVersion@value</td>
bpb@13242 342 <td>6.0</td>
bpb@13242 343 </tr>
bpb@13242 344 <tr>
bpb@13242 345 <td>/Document/SubimageInterpretation@value</td>
bpb@13242 346 <td>NewSubFileType: transparency => "TransparencyMask";
bpb@13242 347 reduced-resolution => "ReducedResolution";
bpb@13242 348 single page => "SinglePage".</td>
bpb@13242 349 </tr>
bpb@13242 350 <tr>
bpb@13242 351 <td>/Document/ImageCreationTime@value</td>
bpb@13242 352 <td>DateTime</td>
bpb@13242 353 </tr>
bpb@13242 354 <tr>
bpb@13242 355 <td>/Text/TextEntry</td>
bpb@13242 356 <td>DocumentName, ImageDescription, Make, Model, PageName, Software,
bpb@13242 357 Artist, HostComputer, InkNames, Copyright:
bpb@13242 358 /Text/TextEntry@keyword = field name,
bpb@13242 359 /Text/TextEntry@value = field value.<br>
bpb@13242 360 Example: TIFF Software field => /Text/TextEntry@keyword = "Software",
bpb@13242 361 /Text/TextEntry@value = Name and version number of the software package(s)
bpb@13242 362 used to create the image.</td>
bpb@13242 363 </tr>
bpb@13242 364 <tr>
bpb@13242 365 <td>/Transparency/Alpha@value</td>
bpb@13242 366 <td>ExtraSamples: associated alpha => "premultiplied";
bpb@13242 367 unassociated alpha => "nonpremultiplied".</td>
bpb@13242 368 </tr>
bpb@13242 369 </table>
bpb@13242 370 </p>
bpb@13242 371
bpb@13242 372 <h4><a name="ExifRead"/>Reading Exif Images</h4>
bpb@13242 373
bpb@13242 374 The TIFF reader may be used to read an uncompressed Exif image or the
bpb@13242 375 contents of the <tt>APP1</tt> marker segment of a compressed Exif image.
bpb@13242 376
bpb@13242 377 <h5><a name="ExifReadTIFF"/>Reading Uncompressed Exif Images</h5>
bpb@13242 378
bpb@13242 379 An uncompressed Exif image is a one- or two-page uncompressed TIFF image
bpb@13242 380 with a specific ordering of its IFD and image data content. Each pixel
bpb@13242 381 has three 8-bit samples with photometric interpretation RGB or YCbCr.
bpb@13242 382 The image stream must contain a single primary image and may contain a
bpb@13242 383 single thumbnail which if present must also be uncompressed. The usual
bpb@13242 384 <code>ImageReader</code> methods may be used to read the image
bpb@13242 385 data and metadata:
bpb@13242 386
bpb@13242 387 <pre><code>
bpb@13242 388 ImageInputStream input;
bpb@13242 389 ImageReader tiffReader;
bpb@13242 390 ImageReadParam tiffReadParam;
bpb@13242 391
bpb@13242 392 tiffReader.setInput(input);
bpb@13242 393
bpb@13242 394 // Read primary image and IFD.
bpb@13242 395 BufferedImage image = tiffReader.read(0, tiffReadParam);
bpb@13242 396 IIOMetadata primaryIFD = tiffReader.getImageMetadata(0);
bpb@13242 397
bpb@13242 398 // Read thumbnail if present.
bpb@13242 399 BufferedImage thumbnail = null;
bpb@13242 400 if (tiffReader.getNumImages(true) > 1) {
bpb@13242 401 thumbnail = tiffReader.read(1, tiffReadParam);
bpb@13242 402 }
bpb@13242 403 </code></pre>
bpb@13242 404
bpb@13242 405 Note that the Exif thumbnail is treated as a separate page in the TIFF
bpb@13242 406 stream and not as a thumbnail, i.e.,
bpb@13242 407 <code>tiffReader.hasThumbnails(0)</code> will return <code>false</code>.
bpb@13242 408
bpb@13242 409 <h5><a name="ExifReadJPEG"/>Reading Compressed Exif Images</h5>
bpb@13242 410
bpb@13242 411 A compressed Exif image is a 3-band ISO/IEC 10918-1 baseline DCT JPEG stream
bpb@13242 412 with an inserted <tt>APP1</tt> marker segment. The parameters of the marker
bpb@13242 413 segment after the length are the 6-byte sequence
bpb@13242 414 <code>{'E',&nbsp;'x',&nbsp;'i',&nbsp;'f',&nbsp;0x00,&nbsp;0x00}</code></code>
bpb@13242 415 followed by a complete TIFF stream. The embedded TIFF stream contains a primary
bpb@13242 416 IFD describing the JPEG image optionally followed by a thumbnail IFD and
bpb@13242 417 compressed or uncompressed thumbnail image data. Note that the embedded TIFF
bpb@13242 418 stream does not contain any image data associated with the primary IFD
bpb@13242 419 nor any descriptive fields which duplicate information found in the JPEG
bpb@13242 420 stream itself.
bpb@13242 421
bpb@13242 422 <p>The parameter content of the <tt>APP1</tt> marker segment may be obtained
bpb@13242 423 from the user object of the associated <code>Node</code> in a
bpb@13242 424 <tt>javax_imageio_jpeg_image_1.0</tt> native image metadata tree extracted
bpb@13242 425 from the image metadata object returned by the JPEG reader. This APP1 Exif
bpb@13242 426 node will be a child of the node named "markerSequence" and will
bpb@13242 427 have name <tt>unknown</tt> and an attribute named <tt>MarkerTag</tt> with
bpb@13242 428 integral value <code>0xE1</code> (<code>String</code> value
bpb@13242 429 <code>"225"</code>). The user object of this node will be a byte array
bpb@13242 430 which starts with the six bytes <code>{'E', 'x', 'i', 'f', '0', '0'}</code>.
bpb@13242 431 The primary IFD and the thumbnail IFD and image may be
bpb@13242 432 read from the user object by the usual <code>ImageReader</code>
bpb@13242 433 methods:
bpb@13242 434
bpb@13242 435 <pre><code>
bpb@13242 436 ImageReader jpegReader;
bpb@13242 437 ImageReader tiffReader;
bpb@13242 438
bpb@13242 439 // Obtain the APP1 Exif marker data from the JPEG image metadata.
bpb@13242 440 IIOMetadata jpegImageMetadata = jpegReader.getImageMetadata(0);
bpb@13242 441 String nativeFormat = jpegImageMetadata.getNativeMetadataFormatName();
bpb@13242 442 Node jpegImageMetadataTree = jpegImageMetadata.getAsTree(nativeFormat);
bpb@13242 443
bpb@13242 444 // getExifMarkerData() returns the byte array which is the user object
bpb@13242 445 // of the APP1 Exif marker node.
bpb@13242 446 byte[] app1Params = getExifMarkerData(jpegImageMetadataTree);
bpb@13242 447 if (app1Params == null) {
bpb@13242 448 throw new IIOException("APP1 Exif marker not found.");
bpb@13242 449 }
bpb@13242 450
bpb@13242 451 // Set up input, skipping Exif ID 6-byte sequence.
bpb@13242 452 MemoryCacheImageInputStream app1ExifInput
bpb@13242 453 = new MemoryCacheImageInputStream
bpb@13242 454 (new ByteArrayInputStream(app1Params, 6, app1Params.length - 6));
bpb@13242 455 tiffReader.setInput(app1ExifInput);
bpb@13242 456
bpb@13242 457 // Read primary IFD.
bpb@13242 458 IIOMetadata primaryIFD = tiffReader.getImageMetadata(0);
bpb@13242 459
bpb@13242 460 // Read thumbnail if present.
bpb@13242 461 BufferedImage thumbnail = null;
bpb@13242 462 if (tiffReader.getNumImages(true) > 1) {
bpb@13242 463 thumbnail = tiffReader.read(1, tiffReadParam);
bpb@13242 464 }
bpb@13242 465
bpb@13242 466 // Read the primary image.
bpb@13242 467 BufferedImage image = jpegReader.read(0);
bpb@13242 468 </code></pre>
bpb@13242 469
bpb@13242 470 Note that <code>tiffReader.getNumImages(true)</code> returns the number of
bpb@13242 471 IFDs in the embedded TIFF stream including those corresponding to empty
bpb@13242 472 images. Calling <code>tiffReader.read(0,&nbsp;readParam)</code> will throw
bpb@13242 473 an exception as the primary image in the embedded TIFF stream is always
bpb@13242 474 empty; the primary image should be obtained using the JPEG reader itself.
bpb@13242 475 </p>
bpb@13242 476
bpb@13242 477 <h3><a name="Writing"/>Writing Images</h3>
bpb@13242 478
bpb@13242 479 TIFF images are written by a <a href="../../ImageWriter.html">ImageWriter</a> which may be
bpb@13242 480 controlled by its public interface as well as via a supplied
bpb@13242 481 <a href="../../ImageWriteParam.html">ImageWriteParam</a>. For an <code>ImageWriteParam</code> returned
bpb@13242 482 by the <code>getDefaultWriteParam()</code> method of the TIFF <code>ImageWriter</code>,
bpb@13242 483 the <code>canWriteTiles()</code> and <code>canWriteCompressed()</code> methods
bpb@13242 484 will return <code>true</code>; the <code>canOffsetTiles()</code> and
bpb@13242 485 <code>canWriteProgressive()</code> methods will return <code>false</code>.</p>
bpb@13242 486
bpb@13242 487 The TIFF writer supports many optional capabilities including writing tiled
bpb@13242 488 images, inserting images, writing or inserting empty images, and replacing image
bpb@13242 489 data. Pixels may be replaced in either empty or non-empty images but if and
bpb@13242 490 only if the data are not compressed.
bpb@13242 491
bpb@13242 492 <p> If tiles are being written, then each of their dimensions will be
bpb@13242 493 rounded to the nearest multiple of 16 per the TIFF specification. If
bpb@13242 494 JPEG-in-TIFF compression is being used, and tiles are being written
bpb@13242 495 each tile dimension will be rounded to the nearest multiple of 8 times
bpb@13242 496 the JPEG minimum coded unit (MCU) in that dimension. If JPEG-in-TIFF
bpb@13242 497 compression is being used and strips are being written, the number of
bpb@13242 498 rows per strip is rounded to a multiple of 8 times the maximum MCU over
bpb@13242 499 both dimensions.</p>
bpb@13242 500
bpb@13242 501 <!-- <h4>Supported Image Types</h4> -->
bpb@13242 502
bpb@13242 503 <!-- Table? -->
bpb@13242 504
bpb@13242 505 <h4><a name="Compression"/>Compression</h4>
bpb@13242 506
bpb@13242 507 The compression type may be set via the <code>setCompressionType()</code> method of
bpb@13242 508 the <code>ImageWriteParam</code> after setting the compression mode to
bpb@13242 509 <code>MODE_EXPLICIT</code>. The set of innately
bpb@13242 510 supported compression types is listed in the following table:
bpb@13242 511
bpb@13242 512 <table border=1>
bpb@13242 513 <caption><b>Supported Compression Types</b></caption>
bpb@13242 514 <tr><th>Compression Type</th> <th>Description</th> <th>Reference</th></tr>
bpb@13242 515 <tr>
bpb@13242 516 <td>CCITT RLE</td>
bpb@13242 517 <td>Modified Huffman compression</td>
bpb@13242 518 <td>TIFF 6.0 Specification, Section 10</td>
bpb@13242 519 </tr>
bpb@13242 520 <tr>
bpb@13242 521 <td>CCITT T.4</td>
bpb@13242 522 <td>CCITT T.4 bilevel encoding/Group 3 facsimile compression</td>
bpb@13242 523 <td>TIFF 6.0 Specification, Section 11</td>
bpb@13242 524 </tr>
bpb@13242 525 <tr>
bpb@13242 526 <td>CCITT T.6</td>
bpb@13242 527 <td>CCITT T.6 bilevel encoding/Group 4 facsimile compression</td>
bpb@13242 528 <td>TIFF 6.0 Specification, Section 11</td></tr>
bpb@13242 529 <tr>
bpb@13242 530 <td>LZW</td>
bpb@13242 531 <td>LZW compression</td>
bpb@13242 532 <td>TIFF 6.0 Specification, Section 13</td></tr>
bpb@13242 533 <tr>
bpb@13242 534 <td>JPEG</td>
bpb@13242 535 <td>"New" JPEG-in-TIFF compression</td>
bpb@13242 536 <td><a href="ftp://ftp.sgi.com/graphics/tiff/TTN2.draft.txt">TIFF
bpb@13242 537 Technical Note #2</a></td>
bpb@13242 538 </tr>
bpb@13242 539 <tr>
bpb@13242 540 <td>ZLib</td>
bpb@13242 541 <td>"Deflate/Inflate" compression (see note following this table)</td>
bpb@16303 542 <td><a href="http://partners.adobe.com/public/developer/en/tiff/TIFFphotoshop.pdf">
bpb@13242 543 Adobe Photoshop&#174; TIFF Technical Notes</a> (PDF)</td>
bpb@13242 544 </tr>
bpb@13242 545 <tr>
bpb@13242 546 <td>PackBits</td>
bpb@13242 547 <td>Byte-oriented, run length compression</td>
bpb@13242 548 <td>TIFF 6.0 Specification, Section 9</td>
bpb@13242 549 </tr>
bpb@13242 550 <tr>
bpb@13242 551 <td>Deflate</td>
bpb@13242 552 <td>"Zip-in-TIFF" compression (see note following this table)</td>
bpb@16303 553 <td><a href="https://tools.ietf.org/html/rfc1950">
bpb@13242 554 ZLIB Compressed Data Format Specification</a>,
bpb@16303 555 <a href="https://tools.ietf.org/html/rfc1951">
bpb@13242 556 DEFLATE Compressed Data Format Specification</a></td>
bpb@13242 557 </tr>
bpb@13242 558 <tr>
bpb@13242 559 <td>Exif JPEG</td>
bpb@13242 560 <td>Exif-specific JPEG compression (see note following this table)</td>
bpb@13242 561 <td><a href="http://www.exif.org/Exif2-2.PDF">Exif 2.2 Specification</a>
bpb@13242 562 (PDF), section 4.5.5, "Basic Structure of Thumbnail Data"</td>
bpb@13242 563 </table>
bpb@13242 564
bpb@13242 565 <p>
bpb@13242 566 Old-style JPEG compression as described in section 22 of the TIFF 6.0
bpb@13242 567 Specification is <i>not</i> supported.
bpb@13242 568 </p>
bpb@13242 569
bpb@13242 570 <p> The CCITT compression types are applicable to bilevel (1-bit)
bpb@13242 571 images only. The JPEG compression type is applicable to byte
bpb@13242 572 grayscale (1-band) and RGB (3-band) images only.</p>
bpb@13242 573
bpb@13242 574 <p>
bpb@13242 575 ZLib and Deflate compression are identical except for the value of the
bpb@13242 576 TIFF Compression field: for ZLib the Compression field has value 8
bpb@13242 577 whereas for Deflate it has value 32946 (0x80b2). In both cases each
bpb@13242 578 image segment (strip or tile) is written as a single complete zlib data
bpb@13242 579 stream.
bpb@13242 580 </p>
bpb@13242 581
bpb@13242 582 <p>
bpb@13242 583 "Exif JPEG" is a compression type used when writing the contents of an
bpb@13242 584 APP1 Exif marker segment for inclusion in a JPEG native image metadata
bpb@13242 585 tree. The contents appended to the output when this compression type is
bpb@13242 586 used are a function of whether an empty or non-empty image is written.
bpb@13242 587 If the image is empty, then a TIFF IFD adhering to the specification of
bpb@13242 588 a compressed Exif primary IFD is appended. If the image is non-empty,
bpb@13242 589 then a complete IFD and image adhering to the specification of a
bpb@13242 590 compressed Exif thumbnail IFD and image are appended. Note that the
bpb@13242 591 data of the empty image may <i>not</i> later be appended using the pixel
bpb@13242 592 replacement capability of the TIFF writer.
bpb@13242 593 </p>
bpb@13242 594
bpb@13242 595 <p> If ZLib/Deflate or JPEG compression is used, the compression quality
bpb@13242 596 may be set. For ZLib/Deflate the supplied floating point quality value is
bpb@13242 597 rescaled to the range <tt>[1,&nbsp;9]</tt> and truncated to an integer
bpb@13242 598 to derive the Deflate compression level. For JPEG the floating point
bpb@13242 599 quality value is passed directly to the JPEG writer plug-in which
bpb@13242 600 interprets it in the usual way.</p>
bpb@13242 601
bpb@13242 602 <h4><a name="ColorConversionWrite"/>Color Conversion</h4>
bpb@13242 603
bpb@13242 604 <p>If the source image data
bpb@13242 605 color space type is RGB, and the destination photometric type is CIE L*a*b* or
bpb@13242 606 YCbCr, then the source image data will be automatically converted from
bpb@13242 607 RGB using an internal color converter.</p>
bpb@13242 608
bpb@13242 609 <h4><a name="ICCProfilesWrite"/>ICC Profiles</h4>
bpb@13242 610
bpb@13242 611 An <tt>ICC Profile</tt> field will be written if either:
bpb@13242 612 <ul>
bpb@13242 613 <li>one is present in the native image metadata
bpb@13242 614 <a href="../IIOMetadata.html">IIOMetadata</a> instance supplied to the writer,
bpb@13242 615 or</li>
bpb@13242 616 <li>the <a href="../../../../java/awt/color/ColorSpace.html">ColorSpace</a>
bpb@13242 617 of the destination <code>ImageTypeSpecifier</code> is an instance of
bpb@13242 618 <code>ICC_ColorSpace</code> which is not one of the standard
bpb@13242 619 color spaces defined by the <tt>CS_*</tt> constants in the
bpb@13242 620 <code>ColorSpace</code> class. The destination type is set via
bpb@13242 621 <code>ImageWriteParam.setDestinationType(ImageTypeSpecifier)</code> and defaults
bpb@13242 622 to the <code>ImageTypeSpecifier</code> of the image being written.
bpb@13242 623 </li>
bpb@13242 624 </ul>
bpb@13242 625
bpb@13242 626 <h4><a name="MetadataIssuesWrite"/>Metadata Issues</h4>
bpb@13242 627
bpb@13242 628 Some behavior of the writer is affected by or may affect the contents of
bpb@13242 629 the image metadata which may be supplied by the user.
bpb@13242 630
bpb@13242 631 <p>For bilevel images, the <tt>FillOrder</tt>, and <tt>T4Options</tt>
bpb@13242 632 fields affect the output data. The data will be filled right-to-left if
bpb@13242 633 <tt>FillOrder</tt> is present with a value of 2
bpb@13242 634 (<code>BaselineTIFFTagSet.FILL_ORDER_RIGHT_TO_LEFT</code>)
bpb@13242 635 and will be filled left-to-right otherwise. The value of <tt>T4Options</tt>
bpb@13242 636 specifies whether the data should be 1D- or 2D-encoded and whether EOL
bpb@13242 637 padding should be used.</p>
bpb@13242 638
bpb@13242 639 <p>For all images the value of the <tt>RowsPerStrip</tt> field is used
bpb@13242 640 to the set the number of rows per strip if the image is not tiled. The
bpb@13242 641 default number of rows per strip is either 8 or the number of rows which
bpb@13242 642 would fill no more than 8 kilobytes, whichever is larger.</p>
bpb@13242 643
bpb@13242 644 <p>For all images the tile dimensions may be set using the <tt>TileWidth</tt>
bpb@13242 645 and <tt>TileLength</tt> field values if the tiling mode is
bpb@13242 646 <code>ImageWriteParam.MODE_COPY_FROM_METADATA</code>. If this mode
bpb@13242 647 is set but the fields are not, their respective default values are the image
bpb@13242 648 width and height.</p>
bpb@13242 649
bpb@13242 650 <p>When using JPEG-in-TIFF compression, a <tt>JPEGTables</tt> field will be
bpb@13242 651 written to the IFD and abbreviated JPEG streams to each strip or tile if and
bpb@13242 652 only if a <tt>JPEGTables</tt> field is contained in the metadata object
bpb@13242 653 provided to the writer. If the contents of the <tt>JPEGTables</tt> field is
bpb@13242 654 a valid tables-only JPEG stream, then it will be used; otherwise the contents
bpb@13242 655 of the field will be replaced with default visually lossless tables. If no
bpb@13242 656 such <tt>JPEGTables</tt> field is present in the metadata, then no
bpb@13242 657 <tt>JPEGTables</tt> field will be written to the output and each strip or
bpb@13242 658 tile will be written as a separate, self-contained JPEG stream.</p>
bpb@13242 659
bpb@13242 660 <p>When using Deflate/ZLib or LZW compression, if the image has 8 bits per
bpb@13242 661 sample, a horizontal differencing predictor will be used if the
bpb@13242 662 <tt>Predictor</tt> field is present with a value of 2
bpb@13242 663 (<code>BaselineTIFFTagSet.PREDICTOR_HORIZONTAL_DIFFERENCING</code>).
bpb@13242 664 If prediction is so requested but the image does not have
bpb@13242 665 8 bits per sample the field will be reset to have the value 1
bpb@13242 666 (<code>BaselineTIFFTagSet.PREDICTOR_NONE</code>).
bpb@13242 667 </p>
bpb@13242 668
bpb@13242 669 <p>Some fields may be added or modified:
bpb@13242 670
bpb@13242 671 <ul>
bpb@13242 672 <li><tt>PhotometricInterpretation</tt> if not present.</li>
bpb@13242 673 <li><tt>PlanarConfiguration</tt> if this field is present with value
bpb@13242 674 <tt>Planar</tt> is is reset to <tt>Chunky</tt>.</li>
bpb@13242 675 <li><tt>Compression</tt> always.</li>
bpb@13242 676 <li><tt>BitsPerSample</tt> if the image is not bilevel.</li>
bpb@13242 677 <li><tt>SamplesPerPixel</tt> always.</li>
bpb@13242 678 <li><tt>ExtraSamples</tt> if an alpha channel is present.</li>
bpb@13242 679 <li><tt>SampleFormat</tt> if not present and the data are 16- or 32-bit
bpb@13242 680 integers or floating point.</li>
bpb@13242 681 <li><tt>ColorMap</tt> if the <tt>PhotometricInterpretation</tt> is
bpb@13242 682 <tt>RGBPalette</tt>.</li>
bpb@13242 683 <li><tt>ImageWidth</tt> and <tt>ImageLength</tt> always.</li>
bpb@13242 684 <li><tt>TileWidth</tt>, <tt>TileLength</tt>, <tt>TileOffsets</tt>, and
bpb@13242 685 <tt>TileByteCounts</tt> if a tiled image is being written.</li>
bpb@13242 686 <li><tt>RowsPerStrip</tt>, <tt>StripOffsets</tt>, and <tt>StripByteCounts</tt>
bpb@13242 687 if a tiled image is <i>not</i> being written.</li>
bpb@13242 688 <li><tt>XResolution</tt>, <tt>YResolution</tt>, and <tt>ResolutionUnit</tt>
bpb@13242 689 if none of these is present.</li>
bpb@13242 690 <li><tt>YCbCrSubsampling</tt> and <tt>YCbCrPositioning</tt> if the
bpb@13242 691 photometric interpretation is YCbCr and the compression type is not JPEG
bpb@13242 692 (only [1,&nbsp;1] subsampling and cosited positioning are supported for
bpb@13242 693 non-JPEG YCbCr output).</li>
bpb@13242 694 <li><tt>YCbCrSubsampling</tt>, <tt>YCbCrPositioning</tt>, and
bpb@13242 695 <tt>ReferenceBlackWhite</tt>: if the compression type is JPEG and the color
bpb@13242 696 space is RGB these will be reset to [2,&nbsp;2] centered subsampling with no
bpb@13242 697 headroom/footroom (0:255,128:255,128:255).</li>
bpb@13242 698 </ul>
bpb@13242 699
bpb@13242 700 <p>Some fields may be removed:
bpb@13242 701
bpb@13242 702 <ul>
bpb@13242 703 <li><tt>BitsPerSample</tt> if the image is bilevel.</li>
bpb@13242 704 <li><tt>ExtraSamples</tt> if the image does not have an alpha channel.</li>
bpb@13242 705 <li><tt>ColorMap</tt> if the photometric interpretation is not
bpb@13242 706 <tt>RGBPalette</tt>.</li>
bpb@13242 707 <li><tt>TileWidth</tt>, <tt>TileLength</tt>, <tt>TileOffsets</tt>, and
bpb@13242 708 <tt>TileByteCounts</tt> if tiling <i>is not</i> being used.</li>
bpb@13242 709 <li><tt>RowsPerStrip</tt>, <tt>StripOffsets</tt>, and <tt>StripByteCounts</tt>
bpb@13242 710 if tiling <i>is</i> being used.</li>
bpb@13242 711 <li><tt>YCbCrSubsampling</tt>, <tt>YCbCrPositioning</tt>, and
bpb@13242 712 <tt>ReferenceBlackWhite</tt> if the compression type is JPEG and the
bpb@13242 713 color space is grayscale.</li>
bpb@13242 714 <li><tt>JPEGProc</tt>, <tt>JPEGInterchangeFormat</tt>,
bpb@13242 715 <tt>JPEGInterchangeFormatLength</tt>, <tt>JPEGRestartInterval</tt>,
bpb@13242 716 <tt>JPEGLosslessPredictors</tt>, <tt>JPEGPointTransforms</tt>,
bpb@13242 717 <tt>JPEGQTables</tt>, <tt>JPEGDCTables</tt>, and
bpb@13242 718 <tt>JPEGACTables</tt> if the compression type is JPEG.</li>
bpb@13242 719 </ul>
bpb@13242 720 </p>
bpb@13242 721
bpb@13242 722 <p>Other fields present in the supplied metadata are uninterpreted and will
bpb@13242 723 be written as supplied.</p>
bpb@13242 724
bpb@13242 725 <p>If an Exif image is being written, the set of fields present and their
bpb@13242 726 values will be modified such that the result is in accord with the Exif 2.2
bpb@13242 727 specification.</p>
bpb@13242 728
bpb@13242 729 <p>Setting up the image metadata to write to a TIFF stream may be simplified
bpb@13242 730 by using the <code>TIFFDirectory</code> class
bpb@13242 731 which represents a TIFF IFD. A field in a TIFF IFD is represented by an
bpb@13242 732 instance of <a href="../../plugins/tiff/TIFFField.html">TIFFField</a>. For each
bpb@13242 733 field to be written a <code>TIFFField</code> may be added to the
bpb@13242 734 <code>TIFFDirectory</code> and the latter converted to an
bpb@13242 735 <code>IIOMetadata</code> object by invoking
bpb@13242 736 <code>TIFFDirectory.getAsMetadata</code>. The
bpb@13242 737 <code>IIOMetadata</code> object so obtained may then be passed to the TIFF
bpb@13242 738 writer.</p>
bpb@13242 739
bpb@13242 740 <h5><a name="MapStandardNative"/>
bpb@13242 741 Mapping of the Standard Metadata Format to TIFF Native Image Metadata</h5>
bpb@13242 742
bpb@13242 743 The derivation of <a href="#ImageMetadata">TIFF native image metadata</a>
bpb@13242 744 elements from the standard metadata format
bpb@13242 745 <a href="standard_metadata.html">javax_imageio_1.0</a> is
bpb@13242 746 given in the following table.
bpb@13242 747
bpb@13242 748 <p>
bpb@13242 749 <table border="1">
bpb@13242 750 <tr>
bpb@13242 751 <th>TIFF Field</th>
bpb@13242 752 <th>Derivation from Standard Metadata Elements</th>
bpb@13242 753 </tr>
bpb@13242 754 <tr>
bpb@13242 755 <td>
bpb@13242 756 PhotometricInterpretation
bpb@13242 757 </td>
bpb@13242 758 <td>/Chroma/ColorSpaceType@name: "GRAY" and /Chroma/BlackIsZero@value = "FALSE"
bpb@13242 759 => WhiteIsZero; "GRAY" and /Document/SubimageInterpretation@value =
bpb@13242 760 "TransparencyMask" => TransparencyMask; "RGB" and /Chroma/Palette present =>
bpb@13242 761 PaletteColor; "GRAY" => BlackIsZero; "RGB" => RGB; "YCbCr" => YCbCr;
bpb@13242 762 "CMYK" => CMYK; "Lab" => CIELab.</td>
bpb@13242 763 </tr>
bpb@13242 764 <tr>
bpb@13242 765 <td>SamplesPerPixel</td>
bpb@13242 766 <td>/Chroma/NumChannels@value</td>
bpb@13242 767 </tr>
bpb@13242 768 <tr>
bpb@13242 769 <td>ColorMap</td>
bpb@13242 770 <td>/Chroma/Palette</td>
bpb@13242 771 </tr>
bpb@13242 772 <tr>
bpb@13242 773 <td>Compression</td>
bpb@13242 774 <td>/Compression/CompressionTypeName@value: "none" => Uncompressed;
bpb@13242 775 "CCITT RLE" => CCITT 1D; "CCITT T.4" => Group 3 Fax; "CCITT T.6" => Group 4
bpb@13242 776 Fax; "LZW" => LZW; "Old JPEG" => JPEG; "JPEG" => New JPEG; "ZLib" => ZLib;
bpb@13242 777 "PackBits" => PackBits; "Deflate" => Deflate.</td>
bpb@13242 778 </tr>
bpb@13242 779 <tr>
bpb@13242 780 <td>PlanarConfiguration</td>
bpb@13242 781 <td>/Data/PlanarConfiguration@value: "PixelInterleaved" => Chunky;
bpb@13242 782 "PlaneInterleaved" => Planar.</td>
bpb@13242 783 </tr>
bpb@13242 784 <tr>
bpb@13242 785 <td>SampleFormat</td>
bpb@13242 786 <td>/Data/SampleFormat@value: "SignedIntegral" => two's complement signed
bpb@13242 787 integer data; "UnsignedIntegral" => unsigned integer data; "Real" =>
bpb@13242 788 IEEE floating point data; "Index" => unsigned integer data.
bpb@13242 789 </td>
bpb@13242 790 </tr>
bpb@13242 791 <tr>
bpb@13242 792 <td>BitsPerSample</td>
bpb@13242 793 <td>/Data/BitsPerSample@value: space-separated list parsed to char array.</td>
bpb@13242 794 </tr>
bpb@13242 795 <tr>
bpb@13242 796 <td>FillOrder</td>
bpb@13242 797 <td>/Data/SampleMSB@value: if all values in space-separated list are 0s =>
bpb@13242 798 right-to-left; otherwise => left-to-right.
bpb@13242 799 </td>
bpb@13242 800 </tr>
bpb@13242 801 <tr>
bpb@13242 802 <td>XResolution</td>
bpb@13242 803 <td>(10 / /Dimension/HorizontalPixelSize@value) or
bpb@13242 804 (10 / (/Dimension/VerticalPixelSize@value *
bpb@13242 805 /Dimension/PixelAspectRatio@value))</td>
bpb@13242 806 </tr>
bpb@13242 807 <tr>
bpb@13242 808 <td>YResolution</td>
bpb@13242 809 <td>(10 / /Dimension/VerticalPixelSize@value) or
bpb@13242 810 (10 / (/Dimension/HorizontalPixelSize@value /
bpb@13242 811 /Dimension/PixelAspectRatio@value))</td>
bpb@13242 812 </tr>
bpb@13242 813 <tr>
bpb@13242 814 <td>ResolutionUnit</td>
bpb@13242 815 <td>Centimeter if XResolution or YResolution set; otherwise None.</td>
bpb@13242 816 </tr>
bpb@13242 817 <tr>
bpb@13242 818 <td>Orientation</td>
bpb@13242 819 <td>/Dimension/ImageOrientation@value</td>
bpb@13242 820 </tr>
bpb@13242 821 <tr>
bpb@13242 822 <td>XPosition</td>
bpb@13242 823 <td>/Dimension/HorizontalPosition@value / 10</td>
bpb@13242 824 </tr>
bpb@13242 825 <tr>
bpb@13242 826 <td>YPosition</td>
bpb@13242 827 <td>/Dimension/VerticalPosition@value / 10</td>
bpb@13242 828 </tr>
bpb@13242 829 <tr>
bpb@13242 830 <td>NewSubFileType</td>
bpb@13242 831 <td>/Document/SubimageInterpretation@value: "TransparencyMask" =>
bpb@13242 832 transparency mask; "ReducedResolution" => reduced-resolution;
bpb@13242 833 "SinglePage" => single page.</td>
bpb@13242 834 </tr>
bpb@13242 835 <tr>
bpb@13242 836 <td>DateTime</td>
bpb@13242 837 <td>/Document/ImageCreationTime@value</td>
bpb@13242 838 </tr>
bpb@13242 839 <tr>
bpb@13242 840 <td>DocumentName, ImageDescription, Make, Model, PageName, Software,
bpb@13242 841 Artist, HostComputer, InkNames, Copyright</td>
bpb@13242 842 <td>/Text/TextEntry: if /Text/TextEntry@keyword is the name of any of the
bpb@13242 843 TIFF Fields, e.g., "Software", then the field is added with content
bpb@13242 844 /Text/TextEntry@value and count 1.</td>
bpb@13242 845 </tr>
bpb@13242 846 <tr>
bpb@13242 847 <td>ExtraSamples</td>
bpb@13242 848 <td>/Transparency/Alpha@value: "premultiplied" => associated alpha, count 1;
bpb@13242 849 "nonpremultiplied" => unassociated alpha, count 1.</td>
bpb@13242 850 </tr>
bpb@13242 851 <tr>
bpb@13242 852 <td></td>
bpb@13242 853 <td></td>
bpb@13242 854 </tr>
bpb@13242 855 </table>
bpb@13242 856 </p>
bpb@13242 857
bpb@13242 858 <h4><a name="ExifWrite"/>Writing Exif Images</h4>
bpb@13242 859
bpb@13242 860 The TIFF writer may be used to write an uncompressed Exif image or the
bpb@13242 861 contents of the <tt>APP1</tt> marker segment of a compressed Exif image.
bpb@13242 862
bpb@13242 863 <h5><a name="ExifWriteTIFF"/>Writing Uncompressed Exif Images</h5>
bpb@13242 864
bpb@13242 865 When writing a sequence of images each image is normally recorded as
bpb@13242 866 {IFD,&nbsp;IFD Value,&nbsp;Image Data}. The Exif specification requires
bpb@13242 867 that an uncompressed Exif image be structured as follows:
bpb@13242 868
bpb@13242 869 <ol>
bpb@13242 870 <a name="ExifStructure"/>
bpb@13242 871 <li>Image File Header</li>
bpb@13242 872 <li>Primary IFD</li>
bpb@13242 873 <li>Primary IFD Value</li>
bpb@13242 874 <li>Thumbnail IFD</li>
bpb@13242 875 <li>Thumbnail IFD Value</li>
bpb@13242 876 <li>Thumbnail Image Data</li>
bpb@13242 877 <li>Primary Image Data</li>
bpb@13242 878 </ol>
bpb@13242 879
bpb@13242 880 To meet the requirement of the primary image data being recorded last, the
bpb@13242 881 primary image must be written initially as an empty image and have its data
bpb@13242 882 added via pixel replacement after the thumbnail IFD and image data have been
bpb@13242 883 written:
bpb@13242 884
bpb@13242 885 <pre><code>
bpb@13242 886 ImageWriter tiffWriter;
bpb@13242 887 ImageWriteParam tiffWriteParam;
bpb@13242 888 IIOMetadata tiffStreamMetadata;
bpb@13242 889 IIOMetadata primaryIFD;
bpb@13242 890 BufferedImage image;
bpb@13242 891 BufferedImage thumbnail;
bpb@13242 892
bpb@13242 893 // Specify uncompressed output.
bpb@13242 894 tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);
bpb@13242 895
bpb@13242 896 if (thumbnail != null) {
bpb@13242 897 // Write the TIFF header.
bpb@13242 898 tiffWriter.prepareWriteSequence(tiffStreamMetadata);
bpb@13242 899
bpb@13242 900 // Append the primary IFD.
bpb@13242 901 tiffWriter.prepareInsertEmpty(-1, // append
bpb@13242 902 new ImageTypeSpecifier(image),
bpb@13242 903 image.getWidth(),
bpb@13242 904 image.getHeight(),
bpb@13242 905 primaryIFD,
bpb@13242 906 null, // thumbnails
bpb@13242 907 tiffWriteParam);
bpb@13242 908 tiffWriter.endInsertEmpty();
bpb@13242 909
bpb@13242 910 // Append the thumbnail image data.
bpb@13242 911 tiffWriter.writeToSequence(new IIOImage(thumbnail, null, null),
bpb@13242 912 tiffWriteParam);
bpb@13242 913
bpb@13242 914 // Insert the primary image data.
bpb@13242 915 tiffWriter.prepareReplacePixels(0, new Rectangle(image.getWidth(),
bpb@13242 916 image.getHeight()));
bpb@13242 917 tiffWriter.replacePixels(image, tiffWriteParam);
bpb@13242 918 tiffWriter.endReplacePixels();
bpb@13242 919
bpb@13242 920 // End writing.
bpb@13242 921 tiffWriter.endWriteSequence();
bpb@13242 922 } else {
bpb@13242 923 // Write only the primary IFD and image data.
bpb@13242 924 tiffWriter.write(tiffStreamMetadata,
bpb@13242 925 new IIOImage(image, null, primaryIFD),
bpb@13242 926 tiffWriteParam);
bpb@13242 927 }
bpb@13242 928 </code></pre>
bpb@13242 929
bpb@13242 930 <h5><a name="ExifWriteJPEG"/>Writing Compressed Exif Images</h5>
bpb@13242 931
bpb@13242 932 The structure of the embedded TIFF stream in the <tt>APP1</tt> segment of a
bpb@13242 933 compressed Exif image is identical to the <a href="#ExifStructure">
bpb@13242 934 uncompressed Exif image structure</a> except that there are no primary
bpb@13242 935 image data, i.e., the primary IFD does not refer to any image data.
bpb@13242 936
bpb@13242 937 <pre><code>
bpb@13242 938 ImageWriter tiffWriter;
bpb@13242 939 ImageWriteParam tiffWriteParam;
bpb@13242 940 IIOMetadata tiffStreamMetadata;
bpb@13242 941 BufferedImage image;
bpb@13242 942 BufferedImage thumbnail;
bpb@13242 943 IIOMetadata primaryIFD;
bpb@13242 944 ImageOutputStream output;
bpb@13242 945
bpb@13242 946 // Set up an output to contain the APP1 Exif TIFF stream.
bpb@13242 947 ByteArrayOutputStream baos = new ByteArrayOutputStream();
bpb@13242 948 MemoryCacheImageOutputStream app1ExifOutput =
bpb@13242 949 new MemoryCacheImageOutputStream(baos);
bpb@13242 950 tiffWriter.setOutput(app1ExifOutput);
bpb@13242 951
bpb@13242 952 // Set compression for the thumbnail.
bpb@13242 953 tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
bpb@13242 954 tiffWriteParam.setCompressionType("Exif JPEG");
bpb@13242 955
bpb@13242 956 // Write the APP1 Exif TIFF stream.
bpb@13242 957 if (thumbnail != null) {
bpb@13242 958 // Write the TIFF header.
bpb@13242 959 tiffWriter.prepareWriteSequence(tiffStreamMetadata);
bpb@13242 960
bpb@13242 961 // Append the primary IFD.
bpb@13242 962 tiffWriter.prepareInsertEmpty(-1, // append
bpb@13242 963 new ImageTypeSpecifier(image),
bpb@13242 964 image.getWidth(),
bpb@13242 965 image.getHeight(),
bpb@13242 966 primaryIFD,
bpb@13242 967 null, // thumbnails
bpb@13242 968 tiffWriteParam);
bpb@13242 969 tiffWriter.endInsertEmpty();
bpb@13242 970
bpb@13242 971 // Append the thumbnail IFD and image data.
bpb@13242 972 tiffWriter.writeToSequence(new IIOImage(thumbnail, null,
bpb@13242 973 null), tiffWriteParam);
bpb@13242 974
bpb@13242 975 // End writing.
bpb@13242 976 tiffWriter.endWriteSequence();
bpb@13242 977 } else {
bpb@13242 978 // Write only the primary IFD.
bpb@13242 979 tiffWriter.prepareWriteEmpty(tiffStreamMetadata,
bpb@13242 980 new ImageTypeSpecifier(image),
bpb@13242 981 image.getWidth(),
bpb@13242 982 image.getHeight(),
bpb@13242 983 primaryIFD,
bpb@13242 984 null, // thumbnails
bpb@13242 985 tiffWriteParam);
bpb@13242 986 tiffWriter.endWriteEmpty();
bpb@13242 987 }
bpb@13242 988
bpb@13242 989 // Flush data into byte stream.
bpb@13242 990 app1ExifOutput.flush();
bpb@13242 991
bpb@13242 992 // Create APP1 parameter array.
bpb@13242 993 byte[] app1Parameters = new byte[6 + baos.size()];
bpb@13242 994
bpb@13242 995 // Add APP1 Exif ID bytes.
bpb@13242 996 app1Parameters[0] = (byte) 'E';
bpb@13242 997 app1Parameters[1] = (byte) 'x';
bpb@13242 998 app1Parameters[2] = (byte) 'i';
bpb@13242 999 app1Parameters[3] = (byte) 'f';
bpb@13242 1000 app1Parameters[4] = app1Parameters[5] = (byte) 0;
bpb@13242 1001
bpb@13242 1002 // Append TIFF stream to APP1 parameters.
bpb@13242 1003 System.arraycopy(baos.toByteArray(), 0, app1Parameters, 6, baos.size());
bpb@13242 1004
bpb@13242 1005 // Create the APP1 Exif node to be added to native JPEG image metadata.
bpb@13242 1006 IIOMetadataNode app1Node = new IIOMetadataNode("unknown");
bpb@13242 1007 app1Node.setAttribute("MarkerTag", String.valueOf(0xE1));
bpb@13242 1008 app1Node.setUserObject(app1Parameters);
bpb@13242 1009
bpb@13242 1010 // Append the APP1 Exif marker to the "markerSequence" node.
bpb@13242 1011 IIOMetadata jpegImageMetadata =
bpb@13242 1012 jpegWriter.getDefaultImageMetadata(new ImageTypeSpecifier(image),
bpb@13242 1013 jpegWriteParam);
bpb@13242 1014 String nativeFormat = jpegImageMetadata.getNativeMetadataFormatName();
bpb@13242 1015 Node tree = jpegImageMetadata.getAsTree(nativeFormat);
bpb@13242 1016 NodeList children = tree.getChildNodes();
bpb@13242 1017 int numChildren = children.getLength();
bpb@13242 1018 for (int i = 0; i < numChildren; i++) {
bpb@13242 1019 Node child = children.item(i);
bpb@13242 1020 if (child.getNodeName().equals("markerSequence")) {
bpb@13242 1021 child.appendChild(app1Node);
bpb@13242 1022 break;
bpb@13242 1023 }
bpb@13242 1024 }
bpb@13242 1025 jpegImageMetadata.setFromTree(nativeFormat, tree);
bpb@13242 1026
bpb@13242 1027 // Write the JPEG image data including the APP1 Exif marker.
bpb@13242 1028 jpegWriter.setOutput(output);
bpb@13242 1029 jpegWriter.write(new IIOImage(image, null, jpegImageMetadata));
bpb@13242 1030 </code></pre>
bpb@13242 1031
bpb@13242 1032 The <code>"unknown"</code> node created above would be appended to the
bpb@13242 1033 <code>"markerSequence"</code> node of the native JPEG image metadata
bpb@13242 1034 and written to the JPEG stream when the primary image is written using
bpb@13242 1035 the JPEG writer.
bpb@13242 1036
bpb@13242 1037 <h3><a name="StreamMetadata"/>Stream Metadata</h3>
bpb@13242 1038
bpb@13242 1039 The DTD for the TIFF native stream metadata format is as follows:
bpb@13242 1040
bpb@13242 1041 <pre>
bpb@13242 1042 &lt;!DOCTYPE "javax_imageio_tiff_stream_1.0" [
bpb@13242 1043
bpb@13242 1044 &lt;!ELEMENT "javax_imageio_tiff_stream_1.0" (ByteOrder)>
bpb@13242 1045
bpb@13242 1046 &lt;!ELEMENT "ByteOrder" EMPTY&gt;
bpb@13242 1047 &lt;!-- The stream byte order --&gt;
bpb@13242 1048 &lt;!ATTLIST "ByteOrder" "value" #CDATA #REQUIRED&gt;
bpb@13242 1049 &lt;!-- One of "BIG_ENDIAN" or "LITTLE_ENDIAN" --&gt;
bpb@13242 1050 &lt;!-- Data type: String --&gt;
bpb@13242 1051 ]&gt;
bpb@13242 1052 </pre>
bpb@13242 1053
bpb@13242 1054 <h3><a name="ImageMetadata"/>Image Metadata</h3>
bpb@13242 1055
bpb@13242 1056 The DTD for the TIFF native image metadata format is as follows:
bpb@13242 1057
bpb@13242 1058 <pre>
bpb@13242 1059 &lt;!DOCTYPE "javax_imageio_tiff_image_1.0" [
bpb@13242 1060
bpb@13242 1061 &lt;!ELEMENT "javax_imageio_tiff_image_1.0" (TIFFIFD)*&gt;
bpb@13242 1062
bpb@13242 1063 &lt;!ELEMENT "TIFFIFD" (TIFFField | TIFFIFD)*&gt;
bpb@13242 1064 &lt;!-- An IFD (directory) containing fields --&gt;
bpb@13242 1065 &lt;!ATTLIST "TIFFIFD" "tagSets" #CDATA #REQUIRED&gt;
bpb@13242 1066 &lt;!-- Data type: String --&gt;
bpb@13242 1067 &lt;!ATTLIST "TIFFIFD" "parentTagNumber" #CDATA #IMPLIED&gt;
bpb@13242 1068 &lt;!-- The tag number of the field pointing to this IFD --&gt;
bpb@13242 1069 &lt;!-- Data type: Integer --&gt;
bpb@13242 1070 &lt;!ATTLIST "TIFFIFD" "parentTagName" #CDATA #IMPLIED&gt;
bpb@13242 1071 &lt;!-- A mnemonic name for the field pointing to this IFD, if known
bpb@13242 1072 --&gt;
bpb@13242 1073 &lt;!-- Data type: String --&gt;
bpb@13242 1074
bpb@13242 1075 &lt;!ELEMENT "TIFFField" (TIFFBytes | TIFFAsciis |
bpb@13242 1076 TIFFShorts | TIFFSShorts | TIFFLongs | TIFFSLongs |
bpb@13242 1077 TIFFRationals | TIFFSRationals |
bpb@13242 1078 TIFFFloats | TIFFDoubles | TIFFUndefined)&gt;
bpb@13242 1079 &lt;!-- A field containing data --&gt;
bpb@13242 1080 &lt;!ATTLIST "TIFFField" "number" #CDATA #REQUIRED&gt;
bpb@13242 1081 &lt;!-- The tag number asociated with the field --&gt;
bpb@13242 1082 &lt;!-- Data type: String --&gt;
bpb@13242 1083 &lt;!ATTLIST "TIFFField" "name" #CDATA #IMPLIED&gt;
bpb@13242 1084 &lt;!-- A mnemonic name associated with the field, if known --&gt;
bpb@13242 1085 &lt;!-- Data type: String --&gt;
bpb@13242 1086
bpb@13242 1087 &lt;!ELEMENT "TIFFBytes" (TIFFByte)*&gt;
bpb@13242 1088 &lt;!-- A sequence of TIFFByte nodes --&gt;
bpb@13242 1089
bpb@13242 1090 &lt;!ELEMENT "TIFFByte" EMPTY&gt;
bpb@13242 1091 &lt;!-- An integral value between 0 and 255 --&gt;
bpb@13242 1092 &lt;!ATTLIST "TIFFByte" "value" #CDATA #IMPLIED&gt;
bpb@13242 1093 &lt;!-- The value --&gt;
bpb@13242 1094 &lt;!-- Data type: String --&gt;
bpb@13242 1095 &lt;!ATTLIST "TIFFByte" "description" #CDATA #IMPLIED&gt;
bpb@13242 1096 &lt;!-- A description, if available --&gt;
bpb@13242 1097 &lt;!-- Data type: String --&gt;
bpb@13242 1098
bpb@13242 1099 &lt;!ELEMENT "TIFFAsciis" (TIFFAscii)*&gt;
bpb@13242 1100 &lt;!-- A sequence of TIFFAscii nodes --&gt;
bpb@13242 1101
bpb@13242 1102 &lt;!ELEMENT "TIFFAscii" EMPTY&gt;
bpb@13242 1103 &lt;!-- A String value --&gt;
bpb@13242 1104 &lt;!ATTLIST "TIFFAscii" "value" #CDATA #IMPLIED&gt;
bpb@13242 1105 &lt;!-- The value --&gt;
bpb@13242 1106 &lt;!-- Data type: String --&gt;
bpb@13242 1107
bpb@13242 1108 &lt;!ELEMENT "TIFFShorts" (TIFFShort)*&gt;
bpb@13242 1109 &lt;!-- A sequence of TIFFShort nodes --&gt;
bpb@13242 1110
bpb@13242 1111 &lt;!ELEMENT "TIFFShort" EMPTY&gt;
bpb@13242 1112 &lt;!-- An integral value between 0 and 65535 --&gt;
bpb@13242 1113 &lt;!ATTLIST "TIFFShort" "value" #CDATA #IMPLIED&gt;
bpb@13242 1114 &lt;!-- The value --&gt;
bpb@13242 1115 &lt;!-- Data type: String --&gt;
bpb@13242 1116 &lt;!ATTLIST "TIFFShort" "description" #CDATA #IMPLIED&gt;
bpb@13242 1117 &lt;!-- A description, if available --&gt;
bpb@13242 1118 &lt;!-- Data type: String --&gt;
bpb@13242 1119
bpb@13242 1120 &lt;!ELEMENT "TIFFSShorts" (TIFFSShort)*&gt;
bpb@13242 1121 &lt;!-- A sequence of TIFFSShort nodes --&gt;
bpb@13242 1122
bpb@13242 1123 &lt;!ELEMENT "TIFFSShort" EMPTY&gt;
bpb@13242 1124 &lt;!-- An integral value between -32768 and 32767 --&gt;
bpb@13242 1125 &lt;!ATTLIST "TIFFSShort" "value" #CDATA #IMPLIED&gt;
bpb@13242 1126 &lt;!-- The value --&gt;
bpb@13242 1127 &lt;!-- Data type: String --&gt;
bpb@13242 1128 &lt;!ATTLIST "TIFFSShort" "description" #CDATA #IMPLIED&gt;
bpb@13242 1129 &lt;!-- A description, if available --&gt;
bpb@13242 1130 &lt;!-- Data type: String --&gt;
bpb@13242 1131
bpb@13242 1132 &lt;!ELEMENT "TIFFLongs" (TIFFLong)*&gt;
bpb@13242 1133 &lt;!-- A sequence of TIFFLong nodes --&gt;
bpb@13242 1134
bpb@13242 1135 &lt;!ELEMENT "TIFFLong" EMPTY&gt;
bpb@13242 1136 &lt;!-- An integral value between 0 and 4294967295 --&gt;
bpb@13242 1137 &lt;!ATTLIST "TIFFLong" "value" #CDATA #IMPLIED&gt;
bpb@13242 1138 &lt;!-- The value --&gt;
bpb@13242 1139 &lt;!-- Data type: String --&gt;
bpb@13242 1140 &lt;!ATTLIST "TIFFLong" "description" #CDATA #IMPLIED&gt;
bpb@13242 1141 &lt;!-- A description, if available --&gt;
bpb@13242 1142 &lt;!-- Data type: String --&gt;
bpb@13242 1143
bpb@13242 1144 &lt;!ELEMENT "TIFFSLongs" (TIFFSLong)*&gt;
bpb@13242 1145 &lt;!-- A sequence of TIFFSLong nodes --&gt;
bpb@13242 1146
bpb@13242 1147 &lt;!ELEMENT "TIFFSLong" EMPTY&gt;
bpb@13242 1148 &lt;!-- An integral value between -2147483648 and 2147482647 --&gt;
bpb@13242 1149 &lt;!ATTLIST "TIFFSLong" "value" #CDATA #IMPLIED&gt;
bpb@13242 1150 &lt;!-- The value --&gt;
bpb@13242 1151 &lt;!-- Data type: String --&gt;
bpb@13242 1152 &lt;!ATTLIST "TIFFSLong" "description" #CDATA #IMPLIED&gt;
bpb@13242 1153 &lt;!-- A description, if available --&gt;
bpb@13242 1154 &lt;!-- Data type: String --&gt;
bpb@13242 1155
bpb@13242 1156 &lt;!ELEMENT "TIFFRationals" (TIFFRational)*&gt;
bpb@13242 1157 &lt;!-- A sequence of TIFFRational nodes --&gt;
bpb@13242 1158
bpb@13242 1159 &lt;!ELEMENT "TIFFRational" EMPTY&gt;
bpb@13242 1160 &lt;!-- A rational value consisting of an unsigned numerator and
bpb@13242 1161 denominator --&gt;
bpb@13242 1162 &lt;!ATTLIST "TIFFRational" "value" #CDATA #IMPLIED&gt;
bpb@13242 1163 &lt;!-- The numerator and denominator, separated by a slash --&gt;
bpb@13242 1164 &lt;!-- Data type: String --&gt;
bpb@13242 1165
bpb@13242 1166 &lt;!ELEMENT "TIFFSRationals" (TIFFSRational)*&gt;
bpb@13242 1167 &lt;!-- A sequence of TIFFSRational nodes --&gt;
bpb@13242 1168
bpb@13242 1169 &lt;!ELEMENT "TIFFSRational" EMPTY&gt;
bpb@13242 1170 &lt;!-- A rational value consisting of a signed numerator and
bpb@13242 1171 denominator --&gt;
bpb@13242 1172 &lt;!ATTLIST "TIFFSRational" "value" #CDATA #IMPLIED&gt;
bpb@13242 1173 &lt;!-- The numerator and denominator, separated by a slash --&gt;
bpb@13242 1174 &lt;!-- Data type: String --&gt;
bpb@13242 1175
bpb@13242 1176 &lt;!ELEMENT "TIFFFloats" (TIFFFloat)*&gt;
bpb@13242 1177 &lt;!-- A sequence of TIFFFloat nodes --&gt;
bpb@13242 1178
bpb@13242 1179 &lt;!ELEMENT "TIFFFloat" EMPTY&gt;
bpb@13242 1180 &lt;!-- A single-precision floating-point value --&gt;
bpb@13242 1181 &lt;!ATTLIST "TIFFFloat" "value" #CDATA #IMPLIED&gt;
bpb@13242 1182 &lt;!-- The value --&gt;
bpb@13242 1183 &lt;!-- Data type: String --&gt;
bpb@13242 1184
bpb@13242 1185 &lt;!ELEMENT "TIFFDoubles" (TIFFDouble)*&gt;
bpb@13242 1186 &lt;!-- A sequence of TIFFDouble nodes --&gt;
bpb@13242 1187
bpb@13242 1188 &lt;!ELEMENT "TIFFDouble" EMPTY&gt;
bpb@13242 1189 &lt;!-- A double-precision floating-point value --&gt;
bpb@13242 1190 &lt;!ATTLIST "TIFFDouble" "value" #CDATA #IMPLIED&gt;
bpb@13242 1191 &lt;!-- The value --&gt;
bpb@13242 1192 &lt;!-- Data type: String --&gt;
bpb@13242 1193
bpb@13242 1194 &lt;!ELEMENT "TIFFUndefined" EMPTY&gt;
bpb@13242 1195 &lt;!-- Uninterpreted byte data --&gt;
bpb@13242 1196 &lt;!ATTLIST "TIFFUndefined" "value" #CDATA #IMPLIED&gt;
bpb@13242 1197 &lt;!-- A list of comma-separated byte values --&gt;
bpb@13242 1198 &lt;!-- Data type: String --&gt;
bpb@13242 1199 ]&gt;
bpb@13242 1200 </pre>
bpb@13242 1201
iris@13532 1202 @since 9
bpb@13242 1203
bpb@13242 1204 </body>
bpb@13242 1205 </html>