src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html
changeset 47216 71c04702a3d5
parent 42749 91fb907a8732
child 47716 c9181704b389
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/javax/imageio/metadata/doc-files/tiff_metadata.html	Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,1205 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+This code is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 2 only, as
+published by the Free Software Foundation.  Oracle designates this
+particular file as subject to the "Classpath" exception as provided
+by Oracle in the LICENSE file that accompanied this code.
+
+This code is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+version 2 for more details (a copy is included in the LICENSE file that
+accompanied this code).
+
+You should have received a copy of the GNU General Public License version
+2 along with this work; if not, write to the Free Software Foundation,
+Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+or visit www.oracle.com if you need additional information or have any
+questions.
+-->
+
+<title>TIFF Metadata Format Specification and Usage Notes</title>
+</head>
+
+<body bgcolor="white">
+
+<center><h1>
+TIFF Metadata Format Specification and Usage Notes
+</h1></center>
+
+    <p>
+<a href="#Reading">Reading Images</a><br/>
+<font size="-1">
+<ul>
+<li><a href="#ColorConversionRead">Color Conversion</a></li>
+<li><a href="#ColorSpacesRead">Color Spaces</a></li>
+<li><a href="#ICCProfilesRead">ICC Profiles</a></li>
+<li><a href="#MetadataIssuesRead">Metadata Issues</a>
+<font size="-2">
+<ul>
+<li><a href="#MapNativeStandard">Native to Standard Metadata Mapping</a></li>
+</ul>
+</font>
+</li>
+<li><a href="#ExifRead">Reading Exif Images</a>
+<font size="-2">
+<ul>
+<li><a href="#ExifReadTIFF">Reading Uncompressed Exif Images</a></li>
+<li><a href="#ExifReadJPEG">Reading Compressed Exif Images</a></li>
+</ul>
+</font>
+</li>
+</ul>
+</font>
+<a href="#Writing">Writing Images</a><br/>
+<font size="-1">
+<ul>
+<li><a href="#Compression">Compression</a></li>
+<li><a href="#ColorConversionWrite">Color Conversion</a></li>
+<li><a href="#ICCProfilesWrite">ICC Profiles</a></li>
+<li><a href="#MetadataIssuesWrite">Metadata Issues</a></li>
+<font size="-2">
+<ul>
+<li><a href="#MapStandardNative">Standard to Native Metadata Mapping</a></li>
+</ul>
+</font>
+<li><a href="#ExifWrite">Writing Exif Images</a>
+<font size="-2">
+<ul>
+<li><a href="#ExifWriteTIFF">Writing Uncompressed Exif Images</a></li>
+<li><a href="#ExifWriteJPEG">Writing Compressed Exif Images</a></li>
+</ul>
+</font>
+</li>
+</ul>
+</font>
+<a href="#StreamMetadata">Native Stream Metadata Format</a><br/>
+<a href="#ImageMetadata">Native Image Metadata Format</a>
+</p>
+
+<h3><a name="Reading"/>Reading Images</h3>
+
+TIFF images are read by an <a href="../../ImageReader.html">ImageReader</a>
+which may be controlled by its public interface as well as via a supplied
+<a href="../../plugins/tiff/TIFFImageReadParam.html">TIFFImageReadParam</a>.
+
+<!-- <h4>Supported Image Types</h4> -->
+
+<!-- Table? -->
+
+<h4><a name="ColorConversionRead"/>Color Conversion</h4>
+
+<p>If the source image data
+have photometric type CIE L*a*b* or YCbCr, and the destination color space
+type is RGB, then the source image data will be automatically converted to
+RGB using an internal color converter.</p>
+
+<h4><a name="ColorSpacesRead"/>Color Spaces</h4>
+
+The raw color space assigned by default, i.e., in the absence of a
+user-supplied <a href="../../ImageTypeSpecifier.html">ImageTypeSpecifier</a>,
+will be the first among the following which applies:
+
+<ul>
+<li>A color space created from the <a href="#ICCProfilesRead">ICC Profile</a>
+metadata field if it is present and compatible with the image data
+layout.</li>
+<a name="nonICCProfile"><li>sRGB if the image is monochrome/bilevel
+(a two-level color map is created internally).</li>
+<li>sRGB if the image is palette-color.</li>
+<li>Linear RGB if the image has three samples per pixel, has photometric type
+CIE L*a*b*, or has photometric type YCbCr and is <i>not</i>
+JPEG-compressed.</li>
+<li>A <a href="#DefaultCMYK">default CMYK color space</a> if the image has
+photometric type CMYK and four samples per pixel.</li>
+<li>Grayscale if the image has one or two samples per pixel and uniformly
+1, 2, 4, 8, 16, or 32 bits per sample or is floating point.</li>
+<li>sRGB if the image has three or four samples per pixel and uniformly
+1, 2, 4, 8, 16, or 32 bits per sample or is floating point.</li>
+<li>A fabricated, <a href="#GenericCS">generic color space</a> if the image
+has more than four samples per pixel and the number of bits per sample for
+all bands is the same and is a multiple of 8.</li>
+<li>Grayscale if the image has one or two samples per pixel regardless of
+the number of bits per sample.</li>
+<li>sRGB if the image has three or four samples per pixel regardless of
+the number of bits per sample.</li>
+<li>A fabricated, <a href="#GenericCS">generic color space</a> if the image
+has more than four samples per pixel regardless of the number of bits per
+sample.</li>
+</ul>
+
+<p><a name="DefaultCMYK"/>The normalized color coordinate transformations
+used for the default CMYK color space are defined as follows:
+
+<ul>
+<li>CMYK to linear RGB
+<pre>
+R = (1 - K)*(1 - C)
+G = (1 - K)*(1 - M)
+B = (1 - K)*(1 - Y)
+</pre>
+</li>
+<li>Linear RGB to CMYK
+<pre>
+K = min{1 - R, 1 - G, 1 - B}
+if(K != 1) {
+    C = (1 - R - K)/(1 - K)
+    M = (1 - G - K)/(1 - K)
+    Y = (1 - B - K)/(1 - K)
+} else {
+    C = M = Y = 0
+}
+</pre>
+</li>
+</ul>
+</p>
+
+<p><a name="GenericCS"/>The generic color space used when no other color space
+can be inferred is provided merely to enable the data to be loaded. It is not
+intended to provide accurate conversions of any kind.</p>
+
+<p>If the data are known to be in a color space not correctly handled by the
+foregoing, then an <code>ImageTypeSpecifier</code> should be
+supplied to the reader and should be derived from a color space which is correct
+for the data in question.</p>
+
+<h4><a name="ICCProfilesRead"/>ICC Profiles</h4>
+
+If an ICC profile is contained in the image metadata
+(<a href="../../plugins/tiff/BaselineTIFFTagSet.html">
+BaselineTIFFTagSet</a>.TAG_ICC_PROFILE, tag number 34675),
+an attempt will be made to use it to create the color space
+of the loaded image. It will be used if the data layout is of component type
+and the number of samples per pixel equals or is one greater than the number
+of components described by the ICC profile. If the ICC profile is not used
+then the color space will be inferred in one of the subsequent steps described
+<a href="#nonICCProfile">above</a>.
+
+<p>If for some reason the embedded ICC profile is not used automatically, then
+it may be used manually by following this procedure:
+
+<ol>
+<li>Obtain the image metadata from
+<code>ImageReader.getImageMetadata</code></li>
+<li>Extract the ICC profile field and its value.</li>
+<li>Create an <a href="../../../../java/awt/color/ICC_ColorSpace.html">
+ICC_ColorSpace</a> from an
+<a href="../../../../java/awt/color/ICC_Profile.html">
+ICC_Profile</a> created from the ICC profile field data
+using <code>ICC_Profile.getInstance(byte[])</code>.</li>
+<li>Create an <code>ImageTypeSpecifier</code> from the new color
+space using one of its factory methods which accepts an
+<code>ICC_ColorSpace</code>.
+<li>Create a compatible <a href="../../ImageReadParam.html">ImageReadParam</a>
+and set the <code>ImageTypeSpecifier</code> using
+<code>ImageReadParam.setDestinationType</code>.</li>
+<li>Pass the parameter object to the appropriate <code>read</code> method.</li>
+</ol>
+</p>
+
+<p>If the inferred color space not based on the ICC Profile field is compatible
+with the ICC profile-based color space, then a second
+<code>ImageTypeSpecifier</code> derived from this inferred color
+space will be included in the
+<a href="../../../../java/util/Iterator.html">Iterator</a> returned by
+<code>ImageReader.getImageTypes</code>. If the iterator contains
+more than one type, the first one will be based on the ICC profile and the
+second on the inferred color space.</p>
+
+<h4><a name="MetadataIssuesRead"/>Metadata Issues</h4>
+
+By default all recognized fields in the TIFF image file directory (IFD) are
+loaded into the native image metadata object. Which fields are loaded may be
+controlled by setting which TIFF tags the reader is allowed to recognize,
+whether to read fields with unrecognized tags, and whether to ignore all
+metadata. The reader is informed to disregard all metadata as usual via the
+<code>ignoreMetadata</code> parameter of
+<code>ImageReader.setInput(Object,boolean,boolean)</code>. It is
+informed of which <a href="../../plugins/tiff/TIFFTag.html">TIFFTag</a>s to
+recognize or not to recognize via
+<code>TIFFImageReadParam.addAllowedTagSet(TIFFTagSet)</code> and
+<code>TIFFImageReadParam.removeAllowedTagSet(TIFFTagSet)</code>.
+If <code>ignoreMetadata</code> is <code>true</code>, then only metadata
+essential to reading the image will be loaded into the native image metadata
+object. If <code>ignoreMetadata</code> is <code>false</code>, then the reader
+will by default load into the native image metadata object only those fields
+which are either essential to reading the image or have a <code>TIFFTag</code>
+contained in the one of the allowed <code>TIFFTagSet</code>s. Reading of
+fields with tags not in the allowed <code>TIFFTagSet</code>s may be forced
+by passing in a <code>TIFFImageReadParam</code> on which
+<code>TIFFImageReadParam.setReadUnknownTags(boolean)</code> has been
+invoked with parameter <code>true</code>.
+
+<p>Use of a <a href="../../plugins/tiff/TIFFDirectory.html">TIFFDirectory</a>
+object may simplify gaining access to metadata values. An instance of
+<code>TIFFDirectory</code> may be created from the <code>IIOMetadata</code>
+object returned by the TIFF reader using the
+<code>TIFFDirectory.createFromMetadata</code> method.</p>
+
+<h5><a name="MapNativeStandard"/>
+Mapping of TIFF Native Image Metadata to the Standard Metadata Format</h5>
+
+The derivation of standard metadata format
+<a href="standard_metadata.html">javax_imageio_1.0</a>
+elements from <a href="#ImageMetadata">TIFF native image metadata</a> is given
+in the following table.
+
+<p>
+<table border="1">
+<tr>
+<th>Standard Metadata Element</th>
+<th>Derivation from TIFF Fields</th>
+</tr>
+<tr>
+<td>/Chroma/ColorSpaceType@name</td>
+<td>PhotometricInterpretation: WhiteIsZero, BlackIsZero, TransparencyMask =
+"GRAY"; RGB, PaletteColor => "RGB"; CMYK => "CMYK";
+YCbCr => "YCbCr";
+CIELab, ICCLab => "Lab".</td>
+</tr>
+<tr>
+<td>/Chroma/NumChannels@value</td>
+<td>SamplesPerPixel</td>
+</tr>
+<tr>
+<td>/Chroma/BlackIsZero@value</td>
+<td>"TRUE" <=> PhotometricInterpretation => WhiteIsZero</td>
+</tr>
+<tr>
+<td>/Chroma/Palette</td>
+<td>ColorMap</td>
+</tr>
+<tr>
+<td>/Compression/CompressionTypeName@value</td>
+<td>Compression: Uncompressed => "none"; CCITT 1D => "CCITT
+RLE";
+Group 3 Fax => "CCITT T.4"; Group 4 Fax => "CCITT T.6";
+LZW => "LZW";
+JPEG => "Old JPEG"; New JPEG => "JPEG"; Zlib =>> "ZLib"; PackBits =>
+"PackBits";
+Deflate => "Deflate"; Exif JPEG => "JPEG".</td>
+</tr>
+<tr>
+<td>/Compression/Lossless@value</td>
+<td>Compression: JPEG or New JPEG => "FALSE"; otherwise "TRUE".</td>
+</tr>
+<tr>
+<td>/Data/PlanarConfiguration@value</td>
+<td>Chunky => "PixelInterleaved"; Planar => "PlaneInterleaved".</td>
+</tr>
+<tr>
+<td>/Data/SampleFormat@value</td>
+<td>PhotometricInterpretation PaletteColor => "Index";
+SampleFormat unsigned integer data => "UnsignedIntegral";
+SampleFormat two's complement signed integer data => "SignedIntegral";
+SampleFormat IEEE floating point data => "Real";
+otherwise element not emitted.
+</td>
+</tr>
+<tr>
+<td>/Data/BitsPerSample@value</td>
+<td>BitsPerSample as a space-separated list.</td>
+</tr>
+<tr>
+<td>/Data/SampleMSB@value</td>
+<td>FillOrder: left-to-right => space-separated list of BitsPerSample-1;
+right-to-left => space-separated list of 0s.</td>
+</tr>
+<tr>
+<td>/Dimension/PixelAspectRatio@value</td>
+<td>(1/XResolution)/(1/YResolution)</td>
+</tr>
+<tr>
+<td>/Dimension/ImageOrientation@value</td>
+<td>Orientation</td>
+</tr>
+<tr>
+<td>/Dimension/HorizontalPixelSize@value</td>
+<td>1/XResolution in millimeters if ResolutionUnit is not None.</td>
+</tr>
+<tr>
+<td>/Dimension/VerticalPixelSize@value</td>
+<td>1/YResolution in millimeters if ResolutionUnit is not None.</td>
+</tr>
+<tr>
+<td>/Dimension/HorizontalPosition@value</td>
+<td>XPosition in millimeters if ResolutionUnit is not None.</td>
+</tr>
+<tr>
+<td>/Dimension/VerticalPosition@value</td>
+<td>YPosition in millimeters if ResolutionUnit is not None.</td>
+</tr>
+<tr>
+<td>/Document/FormatVersion@value</td>
+<td>6.0</td>
+</tr>
+<tr>
+<td>/Document/SubimageInterpretation@value</td>
+<td>NewSubFileType: transparency => "TransparencyMask";
+reduced-resolution => "ReducedResolution";
+single page => "SinglePage".</td>
+</tr>
+<tr>
+<td>/Document/ImageCreationTime@value</td>
+<td>DateTime</td>
+</tr>
+<tr>
+<td>/Text/TextEntry</td>
+<td>DocumentName, ImageDescription, Make, Model, PageName, Software,
+Artist, HostComputer, InkNames, Copyright:
+/Text/TextEntry@keyword = field name,
+/Text/TextEntry@value = field value.<br>
+Example: TIFF Software field => /Text/TextEntry@keyword = "Software",
+/Text/TextEntry@value = Name and version number of the software package(s)
+used to create the image.</td>
+</tr>
+<tr>
+<td>/Transparency/Alpha@value</td>
+<td>ExtraSamples: associated alpha => "premultiplied";
+unassociated alpha => "nonpremultiplied".</td>
+</tr>
+</table>
+</p>
+
+<h4><a name="ExifRead"/>Reading Exif Images</h4>
+
+The TIFF reader may be used to read an uncompressed Exif image or the
+contents of the <tt>APP1</tt> marker segment of a compressed Exif image.
+
+<h5><a name="ExifReadTIFF"/>Reading Uncompressed Exif Images</h5>
+
+An uncompressed Exif image is a one- or two-page uncompressed TIFF image
+with a specific ordering of its IFD and image data content. Each pixel
+has three 8-bit samples with photometric interpretation RGB or YCbCr.
+The image stream must contain a single primary image and may contain a
+single thumbnail which if present must also be uncompressed. The usual
+<code>ImageReader</code> methods may be used to read the image
+data and metadata:
+
+<pre><code>
+    ImageInputStream input;
+    ImageReader tiffReader;
+    ImageReadParam tiffReadParam;
+
+    tiffReader.setInput(input);
+
+    // Read primary image and IFD.
+    BufferedImage image = tiffReader.read(0, tiffReadParam);
+    IIOMetadata primaryIFD = tiffReader.getImageMetadata(0);
+
+    // Read thumbnail if present.
+    BufferedImage thumbnail = null;
+    if (tiffReader.getNumImages(true) > 1) {
+        thumbnail = tiffReader.read(1, tiffReadParam);
+    }
+</code></pre>
+
+Note that the Exif thumbnail is treated as a separate page in the TIFF
+stream and not as a thumbnail, i.e.,
+<code>tiffReader.hasThumbnails(0)</code> will return <code>false</code>.
+
+<h5><a name="ExifReadJPEG"/>Reading Compressed Exif Images</h5>
+
+A compressed Exif image is a 3-band ISO/IEC 10918-1 baseline DCT JPEG stream
+with an inserted <tt>APP1</tt> marker segment. The parameters of the marker
+segment after the length are the 6-byte sequence
+<code>{'E',&nbsp;'x',&nbsp;'i',&nbsp;'f',&nbsp;0x00,&nbsp;0x00}</code></code>
+followed by a complete TIFF stream. The embedded TIFF stream contains a primary
+IFD describing the JPEG image optionally followed by a thumbnail IFD and
+compressed or uncompressed thumbnail image data. Note that the embedded TIFF
+stream does not contain any image data associated with the primary IFD
+nor any descriptive fields which duplicate information found in the JPEG
+stream itself.
+
+<p>The parameter content of the <tt>APP1</tt> marker segment may be obtained
+from the user object of the associated <code>Node</code> in a
+<tt>javax_imageio_jpeg_image_1.0</tt> native image metadata tree extracted
+from the image metadata object returned by the JPEG reader. This APP1 Exif
+node will be a child of the node named "markerSequence" and will
+have name <tt>unknown</tt> and an attribute named <tt>MarkerTag</tt> with
+integral value <code>0xE1</code> (<code>String</code> value
+<code>"225"</code>). The user object of this node will be a byte array
+which starts with the six bytes <code>{'E', 'x', 'i', 'f', '0', '0'}</code>.
+The primary IFD and the thumbnail IFD and image may be
+read from the user object by the usual <code>ImageReader</code>
+methods:
+
+<pre><code>
+    ImageReader jpegReader;
+    ImageReader tiffReader;
+
+    // Obtain the APP1 Exif marker data from the JPEG image metadata.
+    IIOMetadata jpegImageMetadata = jpegReader.getImageMetadata(0);
+    String nativeFormat = jpegImageMetadata.getNativeMetadataFormatName();
+    Node jpegImageMetadataTree = jpegImageMetadata.getAsTree(nativeFormat);
+
+    // getExifMarkerData() returns the byte array which is the user object
+    // of the APP1 Exif marker node.
+    byte[] app1Params = getExifMarkerData(jpegImageMetadataTree);
+    if (app1Params == null) {
+        throw new IIOException("APP1 Exif marker not found.");
+    }
+
+    // Set up input, skipping Exif ID 6-byte sequence.
+    MemoryCacheImageInputStream app1ExifInput
+        = new MemoryCacheImageInputStream
+            (new ByteArrayInputStream(app1Params, 6, app1Params.length - 6));
+    tiffReader.setInput(app1ExifInput);
+
+    // Read primary IFD.
+    IIOMetadata primaryIFD = tiffReader.getImageMetadata(0);
+
+    // Read thumbnail if present.
+    BufferedImage thumbnail = null;
+    if (tiffReader.getNumImages(true) > 1) {
+        thumbnail = tiffReader.read(1, tiffReadParam);
+    }
+
+    // Read the primary image.
+    BufferedImage image = jpegReader.read(0);
+</code></pre>
+
+Note that <code>tiffReader.getNumImages(true)</code> returns the number of
+IFDs in the embedded TIFF stream including those corresponding to empty
+images. Calling <code>tiffReader.read(0,&nbsp;readParam)</code> will throw
+an exception as the primary image in the embedded TIFF stream is always
+empty; the primary image should be obtained using the JPEG reader itself.
+</p>
+
+<h3><a name="Writing"/>Writing Images</h3>
+
+TIFF images are written by a <a href="../../ImageWriter.html">ImageWriter</a> which may be
+controlled by its public interface as well as via a supplied
+<a href="../../ImageWriteParam.html">ImageWriteParam</a>.  For an <code>ImageWriteParam</code> returned
+by the <code>getDefaultWriteParam()</code> method of the TIFF <code>ImageWriter</code>,
+the <code>canWriteTiles()</code> and <code>canWriteCompressed()</code> methods
+will return <code>true</code>; the <code>canOffsetTiles()</code> and
+<code>canWriteProgressive()</code> methods will return <code>false</code>.</p>
+
+The TIFF writer supports many optional capabilities including writing tiled
+images, inserting images, writing or inserting empty images, and replacing image
+data. Pixels may be replaced in either empty or non-empty images but if and
+only if the data are not compressed.
+
+<p> If tiles are being written, then each of their dimensions will be
+rounded to the nearest multiple of 16 per the TIFF specification. If
+JPEG-in-TIFF compression is being used, and tiles are being written
+each tile dimension will be rounded to the nearest multiple of 8 times
+the JPEG minimum coded unit (MCU) in that dimension. If JPEG-in-TIFF
+compression is being used and strips are being written, the number of
+rows per strip is rounded to a multiple of 8 times the maximum MCU over
+both dimensions.</p>
+ 
+ <!-- <h4>Supported Image Types</h4> -->
+
+<!-- Table? -->
+
+<h4><a name="Compression"/>Compression</h4>
+
+The compression type may be set via the <code>setCompressionType()</code> method of
+the <code>ImageWriteParam</code> after setting the compression mode to
+<code>MODE_EXPLICIT</code>. The set of innately
+supported compression types is listed in the following table:
+
+<table border=1>
+<caption><b>Supported Compression Types</b></caption>
+<tr><th>Compression Type</th> <th>Description</th> <th>Reference</th></tr>
+<tr>
+<td>CCITT RLE</td>
+<td>Modified Huffman compression</td>
+<td>TIFF 6.0 Specification, Section 10</td>
+</tr>
+<tr>
+<td>CCITT T.4</td>
+<td>CCITT T.4 bilevel encoding/Group 3 facsimile compression</td>
+<td>TIFF 6.0 Specification, Section 11</td>
+</tr>
+<tr>
+<td>CCITT T.6</td>
+<td>CCITT T.6 bilevel encoding/Group 4 facsimile compression</td>
+<td>TIFF 6.0 Specification, Section 11</td></tr>
+<tr>
+<td>LZW</td>
+<td>LZW compression</td>
+<td>TIFF 6.0 Specification, Section 13</td></tr>
+<tr>
+<td>JPEG</td>
+<td>"New" JPEG-in-TIFF compression</td>
+<td><a href="ftp://ftp.sgi.com/graphics/tiff/TTN2.draft.txt">TIFF
+Technical Note #2</a></td>
+</tr>
+<tr>
+<td>ZLib</td>
+<td>"Deflate/Inflate" compression (see note following this table)</td>
+<td><a href="http://partners.adobe.com/public/developer/en/tiff/TIFFphotoshop.pdf">
+Adobe Photoshop&#174; TIFF Technical Notes</a> (PDF)</td>
+</tr>
+<tr>
+<td>PackBits</td>
+<td>Byte-oriented, run length compression</td>
+<td>TIFF 6.0 Specification, Section 9</td>
+</tr>
+<tr>
+<td>Deflate</td>
+<td>"Zip-in-TIFF" compression (see note following this table)</td>
+<td><a href="https://tools.ietf.org/html/rfc1950">
+ZLIB Compressed Data Format Specification</a>,
+<a href="https://tools.ietf.org/html/rfc1951">
+DEFLATE Compressed Data Format Specification</a></td>
+</tr>
+<tr>
+<td>Exif JPEG</td>
+<td>Exif-specific JPEG compression (see note following this table)</td>
+<td><a href="http://www.exif.org/Exif2-2.PDF">Exif 2.2 Specification</a>
+(PDF), section 4.5.5, "Basic Structure of Thumbnail Data"</td>
+</table>
+
+<p>
+Old-style JPEG compression as described in section 22 of the TIFF 6.0
+Specification is <i>not</i> supported.
+</p>
+
+<p> The CCITT compression types are applicable to bilevel (1-bit)
+images only.  The JPEG compression type is applicable to byte
+grayscale (1-band) and RGB (3-band) images only.</p>
+
+<p>
+ZLib and Deflate compression are identical except for the value of the
+TIFF Compression field: for ZLib the Compression field has value 8
+whereas for Deflate it has value 32946 (0x80b2). In both cases each
+image segment (strip or tile) is written as a single complete zlib data
+stream.
+</p>
+
+<p>
+"Exif JPEG" is a compression type used when writing the contents of an
+APP1 Exif marker segment for inclusion in a JPEG native image metadata
+tree. The contents appended to the output when this compression type is
+used are a function of whether an empty or non-empty image is written.
+If the image is empty, then a TIFF IFD adhering to the specification of
+a compressed Exif primary IFD is appended. If the image is non-empty,
+then a complete IFD and image adhering to the specification of a
+compressed Exif thumbnail IFD and image are appended. Note that the
+data of the empty image may <i>not</i> later be appended using the pixel
+replacement capability of the TIFF writer.
+</p>
+
+<p> If ZLib/Deflate or JPEG compression is used, the compression quality
+may be set. For ZLib/Deflate the supplied floating point quality value is
+rescaled to the range <tt>[1,&nbsp;9]</tt> and truncated to an integer
+to derive the Deflate compression level. For JPEG the floating point
+quality value is passed directly to the JPEG writer plug-in which
+interprets it in the usual way.</p>
+
+<h4><a name="ColorConversionWrite"/>Color Conversion</h4>
+
+<p>If the source image data
+color space type is RGB, and the destination photometric type is CIE L*a*b* or
+YCbCr, then the source image data will be automatically converted from
+RGB using an internal color converter.</p>
+
+<h4><a name="ICCProfilesWrite"/>ICC Profiles</h4>
+
+An <tt>ICC Profile</tt> field will be written if either:
+<ul>
+<li>one is present in the native image metadata
+<a href="../IIOMetadata.html">IIOMetadata</a> instance supplied to the writer,
+or</li>
+<li>the <a href="../../../../java/awt/color/ColorSpace.html">ColorSpace</a>
+of the destination <code>ImageTypeSpecifier</code> is an instance of
+<code>ICC_ColorSpace</code> which is not one of the standard
+color spaces defined by the <tt>CS_*</tt> constants in the
+<code>ColorSpace</code> class. The destination type is set via
+<code>ImageWriteParam.setDestinationType(ImageTypeSpecifier)</code> and defaults
+to the <code>ImageTypeSpecifier</code> of the image being written.
+</li>
+</ul>
+
+<h4><a name="MetadataIssuesWrite"/>Metadata Issues</h4>
+
+Some behavior of the writer is affected by or may affect the contents of
+the image metadata which may be supplied by the user.
+
+<p>For bilevel images, the <tt>FillOrder</tt>, and <tt>T4Options</tt>
+fields affect the output data. The data will be filled right-to-left if
+<tt>FillOrder</tt> is present with a value of 2
+(<code>BaselineTIFFTagSet.FILL_ORDER_RIGHT_TO_LEFT</code>)
+and will be filled left-to-right otherwise. The value of <tt>T4Options</tt>
+specifies whether the data should be 1D- or 2D-encoded and whether EOL
+padding should be used.</p>
+
+<p>For all images the value of the <tt>RowsPerStrip</tt> field is used
+to the set the number of rows per strip if the image is not tiled. The
+default number of rows per strip is either 8 or the number of rows which
+would fill no more than 8 kilobytes, whichever is larger.</p>
+
+<p>For all images the tile dimensions may be set using the <tt>TileWidth</tt>
+and <tt>TileLength</tt> field values if the tiling mode is
+<code>ImageWriteParam.MODE_COPY_FROM_METADATA</code>. If this mode
+is set but the fields are not, their respective default values are the image
+width and height.</p>
+
+<p>When using JPEG-in-TIFF compression, a <tt>JPEGTables</tt> field will be
+written to the IFD and abbreviated JPEG streams to each strip or tile if and
+only if a <tt>JPEGTables</tt> field is contained in the metadata object
+provided to the writer. If the contents of the <tt>JPEGTables</tt> field is
+a valid tables-only JPEG stream, then it will be used; otherwise the contents
+of the field will be replaced with default visually lossless tables. If no
+such <tt>JPEGTables</tt> field is present in the metadata, then no
+<tt>JPEGTables</tt> field will be written to the output and each strip or
+tile will be written as a separate, self-contained JPEG stream.</p>
+
+<p>When using Deflate/ZLib or LZW compression, if the image has 8 bits per
+sample, a horizontal differencing predictor will be used if the
+<tt>Predictor</tt> field is present with a value of 2
+(<code>BaselineTIFFTagSet.PREDICTOR_HORIZONTAL_DIFFERENCING</code>).
+If prediction is so requested but the image does not have
+8 bits per sample the field will be reset to have the value 1
+(<code>BaselineTIFFTagSet.PREDICTOR_NONE</code>).
+</p>
+
+<p>Some fields may be added or modified:
+
+<ul>
+<li><tt>PhotometricInterpretation</tt> if not present.</li>
+<li><tt>PlanarConfiguration</tt> if this field is present with value
+<tt>Planar</tt> is is reset to <tt>Chunky</tt>.</li>
+<li><tt>Compression</tt> always.</li>
+<li><tt>BitsPerSample</tt> if the image is not bilevel.</li>
+<li><tt>SamplesPerPixel</tt> always.</li>
+<li><tt>ExtraSamples</tt> if an alpha channel is present.</li>
+<li><tt>SampleFormat</tt> if not present and the data are 16- or 32-bit
+integers or floating point.</li>
+<li><tt>ColorMap</tt> if the <tt>PhotometricInterpretation</tt> is
+<tt>RGBPalette</tt>.</li>
+<li><tt>ImageWidth</tt> and <tt>ImageLength</tt> always.</li>
+<li><tt>TileWidth</tt>, <tt>TileLength</tt>, <tt>TileOffsets</tt>, and
+<tt>TileByteCounts</tt> if a tiled image is being written.</li>
+<li><tt>RowsPerStrip</tt>, <tt>StripOffsets</tt>, and <tt>StripByteCounts</tt>
+if a tiled image is <i>not</i> being written.</li>
+<li><tt>XResolution</tt>, <tt>YResolution</tt>, and <tt>ResolutionUnit</tt>
+if none of these is present.</li>
+<li><tt>YCbCrSubsampling</tt> and <tt>YCbCrPositioning</tt> if the
+photometric interpretation is YCbCr and the compression type is not JPEG
+(only [1,&nbsp;1] subsampling and cosited positioning are supported for
+non-JPEG YCbCr output).</li>
+<li><tt>YCbCrSubsampling</tt>, <tt>YCbCrPositioning</tt>, and
+<tt>ReferenceBlackWhite</tt>: if the compression type is JPEG and the color
+space is RGB these will be reset to [2,&nbsp;2] centered subsampling with no
+headroom/footroom (0:255,128:255,128:255).</li>
+</ul>
+
+<p>Some fields may be removed:
+
+<ul>
+<li><tt>BitsPerSample</tt> if the image is bilevel.</li>
+<li><tt>ExtraSamples</tt> if the image does not have an alpha channel.</li>
+<li><tt>ColorMap</tt> if the photometric interpretation is not
+<tt>RGBPalette</tt>.</li>
+<li><tt>TileWidth</tt>, <tt>TileLength</tt>, <tt>TileOffsets</tt>, and
+<tt>TileByteCounts</tt> if tiling <i>is not</i> being used.</li>
+<li><tt>RowsPerStrip</tt>, <tt>StripOffsets</tt>, and <tt>StripByteCounts</tt>
+if tiling <i>is</i> being used.</li>
+<li><tt>YCbCrSubsampling</tt>, <tt>YCbCrPositioning</tt>, and
+<tt>ReferenceBlackWhite</tt> if the compression type is JPEG and the
+color space is grayscale.</li>
+<li><tt>JPEGProc</tt>, <tt>JPEGInterchangeFormat</tt>,
+<tt>JPEGInterchangeFormatLength</tt>, <tt>JPEGRestartInterval</tt>,
+<tt>JPEGLosslessPredictors</tt>, <tt>JPEGPointTransforms</tt>,
+<tt>JPEGQTables</tt>, <tt>JPEGDCTables</tt>, and
+<tt>JPEGACTables</tt> if the compression type is JPEG.</li>
+</ul>
+</p>
+
+<p>Other fields present in the supplied metadata are uninterpreted and will
+be written as supplied.</p>
+
+<p>If an Exif image is being written, the set of fields present and their
+values will be modified such that the result is in accord with the Exif 2.2
+specification.</p>
+
+<p>Setting up the image metadata to write to a TIFF stream may be simplified
+by using the <code>TIFFDirectory</code> class
+which represents a TIFF IFD. A field in a TIFF IFD is represented by an
+instance of <a href="../../plugins/tiff/TIFFField.html">TIFFField</a>. For each
+field to be written a <code>TIFFField</code> may be added to the
+<code>TIFFDirectory</code> and the latter converted to an
+<code>IIOMetadata</code> object by invoking
+<code>TIFFDirectory.getAsMetadata</code>. The
+<code>IIOMetadata</code> object so obtained may then be passed to the TIFF
+writer.</p>
+
+<h5><a name="MapStandardNative"/>
+Mapping of the Standard Metadata Format to TIFF Native Image Metadata</h5>
+
+The derivation of <a href="#ImageMetadata">TIFF native image metadata</a>
+elements from the standard metadata format
+<a href="standard_metadata.html">javax_imageio_1.0</a> is
+given in the following table.
+
+<p>
+<table border="1">
+<tr>
+<th>TIFF Field</th>
+<th>Derivation from Standard Metadata Elements</th>
+</tr>
+<tr>
+<td>
+PhotometricInterpretation
+</td>
+<td>/Chroma/ColorSpaceType@name: "GRAY" and /Chroma/BlackIsZero@value = "FALSE"
+=> WhiteIsZero; "GRAY" and /Document/SubimageInterpretation@value =
+"TransparencyMask" => TransparencyMask; "RGB" and /Chroma/Palette present =>
+PaletteColor; "GRAY" => BlackIsZero; "RGB" => RGB; "YCbCr" => YCbCr;
+"CMYK" => CMYK; "Lab" => CIELab.</td>
+</tr>
+<tr>
+<td>SamplesPerPixel</td>
+<td>/Chroma/NumChannels@value</td>
+</tr>
+<tr>
+<td>ColorMap</td>
+<td>/Chroma/Palette</td>
+</tr>
+<tr>
+<td>Compression</td>
+<td>/Compression/CompressionTypeName@value: "none" => Uncompressed;
+"CCITT RLE" => CCITT 1D; "CCITT T.4" => Group 3 Fax; "CCITT T.6" => Group 4
+Fax; "LZW" => LZW; "Old JPEG" => JPEG; "JPEG" => New JPEG; "ZLib" => ZLib;
+"PackBits" => PackBits; "Deflate" => Deflate.</td>
+</tr>
+<tr>
+<td>PlanarConfiguration</td>
+<td>/Data/PlanarConfiguration@value: "PixelInterleaved" => Chunky;
+"PlaneInterleaved" => Planar.</td>
+</tr>
+<tr>
+<td>SampleFormat</td>
+<td>/Data/SampleFormat@value: "SignedIntegral" => two's complement signed
+integer data; "UnsignedIntegral" => unsigned integer data; "Real" =>
+IEEE floating point data; "Index" => unsigned integer data.
+</td>
+</tr>
+<tr>
+<td>BitsPerSample</td>
+<td>/Data/BitsPerSample@value: space-separated list parsed to char array.</td>
+</tr>
+<tr>
+<td>FillOrder</td>
+<td>/Data/SampleMSB@value: if all values in space-separated list are 0s =>
+right-to-left; otherwise => left-to-right.
+</td>
+</tr>
+<tr>
+<td>XResolution</td>
+<td>(10 / /Dimension/HorizontalPixelSize@value) or
+(10 / (/Dimension/VerticalPixelSize@value *
+/Dimension/PixelAspectRatio@value))</td>
+</tr>
+<tr>
+<td>YResolution</td>
+<td>(10 / /Dimension/VerticalPixelSize@value) or
+(10 / (/Dimension/HorizontalPixelSize@value /
+/Dimension/PixelAspectRatio@value))</td>
+</tr>
+<tr>
+<td>ResolutionUnit</td>
+<td>Centimeter if XResolution or YResolution set; otherwise None.</td>
+</tr>
+<tr>
+<td>Orientation</td>
+<td>/Dimension/ImageOrientation@value</td>
+</tr>
+<tr>
+<td>XPosition</td>
+<td>/Dimension/HorizontalPosition@value / 10</td>
+</tr>
+<tr>
+<td>YPosition</td>
+<td>/Dimension/VerticalPosition@value / 10</td>
+</tr>
+<tr>
+<td>NewSubFileType</td>
+<td>/Document/SubimageInterpretation@value: "TransparencyMask" =>
+transparency mask; "ReducedResolution" => reduced-resolution;
+"SinglePage" => single page.</td>
+</tr>
+<tr>
+<td>DateTime</td>
+<td>/Document/ImageCreationTime@value</td>
+</tr>
+<tr>
+<td>DocumentName, ImageDescription, Make, Model, PageName, Software,
+Artist, HostComputer, InkNames, Copyright</td>
+<td>/Text/TextEntry: if /Text/TextEntry@keyword is the name of any of the
+TIFF Fields, e.g., "Software", then the field is added with content
+/Text/TextEntry@value and count 1.</td>
+</tr>
+<tr>
+<td>ExtraSamples</td>
+<td>/Transparency/Alpha@value: "premultiplied" => associated alpha, count 1;
+"nonpremultiplied" => unassociated alpha, count 1.</td>
+</tr>
+<tr>
+<td></td>
+<td></td>
+</tr>
+</table>
+</p>
+
+<h4><a name="ExifWrite"/>Writing Exif Images</h4>
+
+The TIFF writer may be used to write an uncompressed Exif image or the
+contents of the <tt>APP1</tt> marker segment of a compressed Exif image.
+
+<h5><a name="ExifWriteTIFF"/>Writing Uncompressed Exif Images</h5>
+
+When writing a sequence of images each image is normally recorded as
+{IFD,&nbsp;IFD Value,&nbsp;Image Data}. The Exif specification requires
+that an uncompressed Exif image be structured as follows:
+
+<ol>
+<a name="ExifStructure"/>
+<li>Image File Header</li>
+<li>Primary IFD</li>
+<li>Primary IFD Value</li>
+<li>Thumbnail IFD</li>
+<li>Thumbnail IFD Value</li>
+<li>Thumbnail Image Data</li>
+<li>Primary Image Data</li>
+</ol>
+
+To meet the requirement of the primary image data being recorded last, the
+primary image must be written initially as an empty image and have its data
+added via pixel replacement after the thumbnail IFD and image data have been
+written:
+
+<pre><code>
+    ImageWriter tiffWriter;
+    ImageWriteParam tiffWriteParam;
+    IIOMetadata tiffStreamMetadata;
+    IIOMetadata primaryIFD;
+    BufferedImage image;
+    BufferedImage thumbnail;
+
+    // Specify uncompressed output.
+    tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);
+
+    if (thumbnail != null) {
+        // Write the TIFF header.
+        tiffWriter.prepareWriteSequence(tiffStreamMetadata);
+
+        // Append the primary IFD.
+        tiffWriter.prepareInsertEmpty(-1, // append
+                new ImageTypeSpecifier(image),
+                image.getWidth(),
+                image.getHeight(),
+                primaryIFD,
+                null, // thumbnails
+                tiffWriteParam);
+        tiffWriter.endInsertEmpty();
+
+        // Append the thumbnail image data.
+        tiffWriter.writeToSequence(new IIOImage(thumbnail, null, null),
+                tiffWriteParam);
+
+        // Insert the primary image data.
+        tiffWriter.prepareReplacePixels(0, new Rectangle(image.getWidth(),
+                image.getHeight()));
+        tiffWriter.replacePixels(image, tiffWriteParam);
+        tiffWriter.endReplacePixels();
+
+        // End writing.
+        tiffWriter.endWriteSequence();
+    } else {
+        // Write only the primary IFD and image data.
+        tiffWriter.write(tiffStreamMetadata,
+                new IIOImage(image, null, primaryIFD),
+                tiffWriteParam);
+    }
+</code></pre>
+
+<h5><a name="ExifWriteJPEG"/>Writing Compressed Exif Images</h5>
+
+The structure of the embedded TIFF stream in the <tt>APP1</tt> segment of a
+compressed Exif image is identical to the <a href="#ExifStructure">
+uncompressed Exif image structure</a> except that there are no primary
+image data, i.e., the primary IFD does not refer to any image data.
+
+<pre><code>
+    ImageWriter tiffWriter;
+    ImageWriteParam tiffWriteParam;
+    IIOMetadata tiffStreamMetadata;
+    BufferedImage image;
+    BufferedImage thumbnail;
+    IIOMetadata primaryIFD;
+    ImageOutputStream output;
+
+    // Set up an output to contain the APP1 Exif TIFF stream.
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    MemoryCacheImageOutputStream app1ExifOutput =
+        new MemoryCacheImageOutputStream(baos);
+    tiffWriter.setOutput(app1ExifOutput);
+
+    // Set compression for the thumbnail.
+    tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
+    tiffWriteParam.setCompressionType("Exif JPEG");
+
+    // Write the APP1 Exif TIFF stream.
+    if (thumbnail != null) {
+        // Write the TIFF header.
+        tiffWriter.prepareWriteSequence(tiffStreamMetadata);
+
+        // Append the primary IFD.
+        tiffWriter.prepareInsertEmpty(-1, // append
+                new ImageTypeSpecifier(image),
+                image.getWidth(),
+                image.getHeight(),
+                primaryIFD,
+                null, // thumbnails
+                tiffWriteParam);
+        tiffWriter.endInsertEmpty();
+
+        // Append the thumbnail IFD and image data.
+        tiffWriter.writeToSequence(new IIOImage(thumbnail, null,
+                null), tiffWriteParam);
+
+        // End writing.
+        tiffWriter.endWriteSequence();
+    } else {
+        // Write only the primary IFD.
+        tiffWriter.prepareWriteEmpty(tiffStreamMetadata,
+                new ImageTypeSpecifier(image),
+                image.getWidth(),
+                image.getHeight(),
+                primaryIFD,
+                null, // thumbnails
+                tiffWriteParam);
+        tiffWriter.endWriteEmpty();
+    }
+
+    // Flush data into byte stream.
+    app1ExifOutput.flush();
+
+    // Create APP1 parameter array.
+    byte[] app1Parameters = new byte[6 + baos.size()];
+
+    // Add APP1 Exif ID bytes.
+    app1Parameters[0] = (byte) 'E';
+    app1Parameters[1] = (byte) 'x';
+    app1Parameters[2] = (byte) 'i';
+    app1Parameters[3] = (byte) 'f';
+    app1Parameters[4] = app1Parameters[5] = (byte) 0;
+
+    // Append TIFF stream to APP1 parameters.
+    System.arraycopy(baos.toByteArray(), 0, app1Parameters, 6, baos.size());
+
+    // Create the APP1 Exif node to be added to native JPEG image metadata.
+    IIOMetadataNode app1Node = new IIOMetadataNode("unknown");
+    app1Node.setAttribute("MarkerTag", String.valueOf(0xE1));
+    app1Node.setUserObject(app1Parameters);
+
+    // Append the APP1 Exif marker to the "markerSequence" node.
+    IIOMetadata jpegImageMetadata =
+        jpegWriter.getDefaultImageMetadata(new ImageTypeSpecifier(image),
+            jpegWriteParam);
+    String nativeFormat = jpegImageMetadata.getNativeMetadataFormatName();
+    Node tree = jpegImageMetadata.getAsTree(nativeFormat);
+    NodeList children = tree.getChildNodes();
+    int numChildren = children.getLength();
+    for (int i = 0; i < numChildren; i++) {
+        Node child = children.item(i);
+        if (child.getNodeName().equals("markerSequence")) {
+            child.appendChild(app1Node);
+            break;
+        }
+    }
+    jpegImageMetadata.setFromTree(nativeFormat, tree);
+
+    // Write the JPEG image data including the APP1 Exif marker.
+    jpegWriter.setOutput(output);
+    jpegWriter.write(new IIOImage(image, null, jpegImageMetadata));
+</code></pre>
+
+The <code>"unknown"</code> node created above would be appended to the
+<code>"markerSequence"</code> node of the native JPEG image metadata
+and written to the JPEG stream when the primary image is written using
+the JPEG writer.
+
+<h3><a name="StreamMetadata"/>Stream Metadata</h3>
+
+The DTD for the TIFF native stream metadata format is as follows:
+
+<pre>
+&lt;!DOCTYPE "javax_imageio_tiff_stream_1.0" [
+
+  &lt;!ELEMENT "javax_imageio_tiff_stream_1.0" (ByteOrder)>
+
+    &lt;!ELEMENT "ByteOrder" EMPTY&gt;
+      &lt;!-- The stream byte order --&gt; 
+      &lt;!ATTLIST "ByteOrder" "value" #CDATA #REQUIRED&gt;
+        &lt;!-- One of "BIG_ENDIAN" or "LITTLE_ENDIAN" --&gt; 
+        &lt;!-- Data type: String --&gt;
+]&gt;
+</pre>
+
+<h3><a name="ImageMetadata"/>Image Metadata</h3>
+
+The DTD for the TIFF native image metadata format is as follows:
+
+<pre>
+&lt;!DOCTYPE "javax_imageio_tiff_image_1.0" [
+
+  &lt;!ELEMENT "javax_imageio_tiff_image_1.0" (TIFFIFD)*&gt;
+
+    &lt;!ELEMENT "TIFFIFD" (TIFFField | TIFFIFD)*&gt;
+      &lt;!-- An IFD (directory) containing fields --&gt; 
+      &lt;!ATTLIST "TIFFIFD" "tagSets" #CDATA #REQUIRED&gt;
+        &lt;!-- Data type: String --&gt;
+      &lt;!ATTLIST "TIFFIFD" "parentTagNumber" #CDATA #IMPLIED&gt;
+        &lt;!-- The tag number of the field pointing to this IFD --&gt; 
+        &lt;!-- Data type: Integer --&gt;
+      &lt;!ATTLIST "TIFFIFD" "parentTagName" #CDATA #IMPLIED&gt;
+        &lt;!-- A mnemonic name for the field pointing to this IFD, if known 
+             --&gt; 
+        &lt;!-- Data type: String --&gt;
+
+      &lt;!ELEMENT "TIFFField" (TIFFBytes | TIFFAsciis |
+        TIFFShorts | TIFFSShorts | TIFFLongs | TIFFSLongs |
+        TIFFRationals | TIFFSRationals |
+        TIFFFloats | TIFFDoubles | TIFFUndefined)&gt;
+        &lt;!-- A field containing data --&gt; 
+        &lt;!ATTLIST "TIFFField" "number" #CDATA #REQUIRED&gt;
+          &lt;!-- The tag number asociated with the field --&gt; 
+          &lt;!-- Data type: String --&gt;
+        &lt;!ATTLIST "TIFFField" "name" #CDATA #IMPLIED&gt;
+          &lt;!-- A mnemonic name associated with the field, if known --&gt; 
+          &lt;!-- Data type: String --&gt;
+
+        &lt;!ELEMENT "TIFFBytes" (TIFFByte)*&gt;
+          &lt;!-- A sequence of TIFFByte nodes --&gt; 
+
+          &lt;!ELEMENT "TIFFByte" EMPTY&gt;
+            &lt;!-- An integral value between 0 and 255 --&gt; 
+            &lt;!ATTLIST "TIFFByte" "value" #CDATA #IMPLIED&gt;
+              &lt;!-- The value --&gt; 
+              &lt;!-- Data type: String --&gt;
+            &lt;!ATTLIST "TIFFByte" "description" #CDATA #IMPLIED&gt;
+              &lt;!-- A description, if available --&gt; 
+              &lt;!-- Data type: String --&gt;
+
+        &lt;!ELEMENT "TIFFAsciis" (TIFFAscii)*&gt;
+          &lt;!-- A sequence of TIFFAscii nodes --&gt; 
+
+          &lt;!ELEMENT "TIFFAscii" EMPTY&gt;
+            &lt;!-- A String value --&gt; 
+            &lt;!ATTLIST "TIFFAscii" "value" #CDATA #IMPLIED&gt;
+              &lt;!-- The value --&gt; 
+              &lt;!-- Data type: String --&gt;
+
+        &lt;!ELEMENT "TIFFShorts" (TIFFShort)*&gt;
+          &lt;!-- A sequence of TIFFShort nodes --&gt; 
+
+          &lt;!ELEMENT "TIFFShort" EMPTY&gt;
+            &lt;!-- An integral value between 0 and 65535 --&gt; 
+            &lt;!ATTLIST "TIFFShort" "value" #CDATA #IMPLIED&gt;
+              &lt;!-- The value --&gt; 
+              &lt;!-- Data type: String --&gt;
+            &lt;!ATTLIST "TIFFShort" "description" #CDATA #IMPLIED&gt;
+              &lt;!-- A description, if available --&gt; 
+              &lt;!-- Data type: String --&gt;
+
+        &lt;!ELEMENT "TIFFSShorts" (TIFFSShort)*&gt;
+          &lt;!-- A sequence of TIFFSShort nodes --&gt; 
+
+          &lt;!ELEMENT "TIFFSShort" EMPTY&gt;
+            &lt;!-- An integral value between -32768 and 32767 --&gt; 
+            &lt;!ATTLIST "TIFFSShort" "value" #CDATA #IMPLIED&gt;
+              &lt;!-- The value --&gt; 
+              &lt;!-- Data type: String --&gt;
+            &lt;!ATTLIST "TIFFSShort" "description" #CDATA #IMPLIED&gt;
+              &lt;!-- A description, if available --&gt; 
+              &lt;!-- Data type: String --&gt;
+
+        &lt;!ELEMENT "TIFFLongs" (TIFFLong)*&gt;
+          &lt;!-- A sequence of TIFFLong nodes --&gt; 
+
+          &lt;!ELEMENT "TIFFLong" EMPTY&gt;
+            &lt;!-- An integral value between 0 and 4294967295 --&gt; 
+            &lt;!ATTLIST "TIFFLong" "value" #CDATA #IMPLIED&gt;
+              &lt;!-- The value --&gt; 
+              &lt;!-- Data type: String --&gt;
+            &lt;!ATTLIST "TIFFLong" "description" #CDATA #IMPLIED&gt;
+              &lt;!-- A description, if available --&gt; 
+              &lt;!-- Data type: String --&gt;
+
+        &lt;!ELEMENT "TIFFSLongs" (TIFFSLong)*&gt;
+          &lt;!-- A sequence of TIFFSLong nodes --&gt; 
+
+          &lt;!ELEMENT "TIFFSLong" EMPTY&gt;
+            &lt;!-- An integral value between -2147483648 and 2147482647 --&gt; 
+            &lt;!ATTLIST "TIFFSLong" "value" #CDATA #IMPLIED&gt;
+              &lt;!-- The value --&gt; 
+              &lt;!-- Data type: String --&gt;
+            &lt;!ATTLIST "TIFFSLong" "description" #CDATA #IMPLIED&gt;
+              &lt;!-- A description, if available --&gt; 
+              &lt;!-- Data type: String --&gt;
+
+        &lt;!ELEMENT "TIFFRationals" (TIFFRational)*&gt;
+          &lt;!-- A sequence of TIFFRational nodes --&gt; 
+
+          &lt;!ELEMENT "TIFFRational" EMPTY&gt;
+            &lt;!-- A rational value consisting of an unsigned numerator and 
+                 denominator --&gt; 
+            &lt;!ATTLIST "TIFFRational" "value" #CDATA #IMPLIED&gt;
+              &lt;!-- The numerator and denominator, separated by a slash --&gt; 
+              &lt;!-- Data type: String --&gt;
+
+        &lt;!ELEMENT "TIFFSRationals" (TIFFSRational)*&gt;
+          &lt;!-- A sequence of TIFFSRational nodes --&gt; 
+
+          &lt;!ELEMENT "TIFFSRational" EMPTY&gt;
+            &lt;!-- A rational value consisting of a signed numerator and 
+                 denominator --&gt; 
+            &lt;!ATTLIST "TIFFSRational" "value" #CDATA #IMPLIED&gt;
+              &lt;!-- The numerator and denominator, separated by a slash --&gt; 
+              &lt;!-- Data type: String --&gt;
+
+        &lt;!ELEMENT "TIFFFloats" (TIFFFloat)*&gt;
+          &lt;!-- A sequence of TIFFFloat nodes --&gt; 
+
+          &lt;!ELEMENT "TIFFFloat" EMPTY&gt;
+            &lt;!-- A single-precision floating-point value --&gt; 
+            &lt;!ATTLIST "TIFFFloat" "value" #CDATA #IMPLIED&gt;
+              &lt;!-- The value --&gt; 
+              &lt;!-- Data type: String --&gt;
+
+        &lt;!ELEMENT "TIFFDoubles" (TIFFDouble)*&gt;
+          &lt;!-- A sequence of TIFFDouble nodes --&gt; 
+
+          &lt;!ELEMENT "TIFFDouble" EMPTY&gt;
+            &lt;!-- A double-precision floating-point value --&gt; 
+            &lt;!ATTLIST "TIFFDouble" "value" #CDATA #IMPLIED&gt;
+              &lt;!-- The value --&gt; 
+              &lt;!-- Data type: String --&gt;
+
+        &lt;!ELEMENT "TIFFUndefined" EMPTY&gt;
+          &lt;!-- Uninterpreted byte data --&gt; 
+          &lt;!ATTLIST "TIFFUndefined" "value" #CDATA #IMPLIED&gt;
+            &lt;!-- A list of comma-separated byte values --&gt; 
+            &lt;!-- Data type: String --&gt;
+]&gt;
+</pre>
+
+@since 9
+
+</body>
+</html>