xref: /libtiff-4.0.7/html/libtiff.html (revision 201ee77d)
125cbff28SJoris Van Damme<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
225cbff28SJoris Van Damme<html lang="en">
325cbff28SJoris Van Damme<head>
425cbff28SJoris Van Damme  <title>Using The TIFF Library</title>
525cbff28SJoris Van Damme  <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
625cbff28SJoris Van Damme  <meta http-equiv="content-language" content="en">
725cbff28SJoris Van Damme  <style type="text/css">
825cbff28SJoris Van Damme  <!--
925cbff28SJoris Van Damme    th {text-align: left; vertical-align: top; font-style: italic; font-weight: normal}
1025cbff28SJoris Van Damme  -->
1125cbff28SJoris Van Damme  </style>
1225cbff28SJoris Van Damme</head>
1325cbff28SJoris Van Damme<body lang="en" text="#000000" bgcolor="#ffffff" link="#0000ff" alink="#0000ff" vlink="#0000ff">
1425cbff28SJoris Van Damme  <table border="0" cellspacing="0" cellpadding="0">
1525cbff28SJoris Van Damme    <tr>
16*201ee77dSJoris Van Damme      <td style="padding-left: 1em; padding-right: 1em"><img src="images/cat.gif" width="113" height="146" alt=""></td>
1725cbff28SJoris Van Damme      <td>
1825cbff28SJoris Van Damme        <h1>Using The TIFF Library</h1>
1925cbff28SJoris Van Damme        <p>
2025cbff28SJoris Van Damme          <tt>libtiff</tt> is a set of C functions (a library) that support
210ef31e1fSMike Welles          the manipulation of TIFF image files.
220ef31e1fSMike Welles          The library requires an ANSI C compilation environment for building
230ef31e1fSMike Welles          and presumes an ANSI C environment for use.
2425cbff28SJoris Van Damme        </p>
2525cbff28SJoris Van Damme      </td>
2625cbff28SJoris Van Damme    </tr>
2725cbff28SJoris Van Damme  </table>
2825cbff28SJoris Van Damme  <br>
2925cbff28SJoris Van Damme  <p>
3025cbff28SJoris Van Damme    <tt>libtiff</tt>
310ef31e1fSMike Welles    provides interfaces to image data at several layers of abstraction (and cost).
320ef31e1fSMike Welles    At the highest level image data can be read into an 8-bit/sample,
330ef31e1fSMike Welles    ABGR pixel raster format without regard for the underlying data organization,
340ef31e1fSMike Welles    colorspace, or compression scheme.  Below this high-level interface
350ef31e1fSMike Welles    the library provides scanline-, strip-, and tile-oriented interfaces that
360ef31e1fSMike Welles    return data decompressed but otherwise untransformed.  These interfaces
370ef31e1fSMike Welles    require that the application first identify the organization of stored
380ef31e1fSMike Welles    data and select either a strip-based or tile-based API for manipulating
390ef31e1fSMike Welles    data.  At the lowest level the library
400ef31e1fSMike Welles    provides access to the raw uncompressed strips or tiles,
410ef31e1fSMike Welles    returning the data exactly as it appears in the file.
4225cbff28SJoris Van Damme  </p>
4325cbff28SJoris Van Damme  <p>
440ef31e1fSMike Welles    The material presented in this chapter is a basic introduction
450ef31e1fSMike Welles    to the capabilities of the library; it is not an attempt to describe
460ef31e1fSMike Welles    everything a developer needs to know about the library or about TIFF.
470ef31e1fSMike Welles    Detailed information on the interfaces to the library are given in
4825cbff28SJoris Van Damme    the <a href="http://www.remotesensing.org/libtiff/man/index.html">UNIX
4925cbff28SJoris Van Damme    manual pages</a> that accompany this software.
5025cbff28SJoris Van Damme  </p>
5125cbff28SJoris Van Damme  <p>
5225cbff28SJoris Van Damme    Michael Still has also written a useful introduction to libtiff for the
53c7486651SFrank Warmerdam    IBM DeveloperWorks site available at
5425cbff28SJoris Van Damme    <a href="http://www.ibm.com/developerworks/linux/library/l-libtiff">http://www.ibm.com/developerworks/linux/library/l-libtiff</a>.
5525cbff28SJoris Van Damme  </p>
5625cbff28SJoris Van Damme  <p>
570ef31e1fSMike Welles    The following sections are found in this chapter:
5825cbff28SJoris Van Damme  </p>
5925cbff28SJoris Van Damme  <ul>
6025cbff28SJoris Van Damme    <li><a href="#version">How to tell which version you have</a></li>
6125cbff28SJoris Van Damme    <li><a href="#typedefs">Library Datatypes</a></li>
6225cbff28SJoris Van Damme    <li><a href="#mman">Memory Management</a></li>
6325cbff28SJoris Van Damme    <li><a href="#errors">Error Handling</a></li>
6425cbff28SJoris Van Damme    <li><a href="#fio">Basic File Handling</a></li>
6525cbff28SJoris Van Damme    <li><a href="#dirs">TIFF Directories</a></li>
6625cbff28SJoris Van Damme    <li><a href="#tags">TIFF Tags</a></li>
6725cbff28SJoris Van Damme    <li><a href="#compression">TIFF Compression Schemes</a></li>
6825cbff28SJoris Van Damme    <li><a href="#byteorder">Byte Order</a></li>
6925cbff28SJoris Van Damme    <li><a href="#dataplacement">Data Placement</a></li>
7025cbff28SJoris Van Damme    <li><a href="#tiffrgbaimage">TIFFRGBAImage Support</a></li>
7125cbff28SJoris Van Damme    <li><a href="#scanlines">Scanline-based Image I/O</a></li>
7225cbff28SJoris Van Damme    <li><a href="#strips">Strip-oriented Image I/O</a></li>
7325cbff28SJoris Van Damme    <li><a href="#tiles">Tile-oriented Image I/O</a></li>
7425cbff28SJoris Van Damme    <li><a href="#other">Other Stuff</a></li>
7525cbff28SJoris Van Damme  </ul>
7625cbff28SJoris Van Damme  <hr>
7725cbff28SJoris Van Damme  <h2 id="version">How to tell which version you have</h2>
7825cbff28SJoris Van Damme  <p>
790ef31e1fSMike Welles    The software version can be found by looking at the file named
8025cbff28SJoris Van Damme    <tt>VERSION</tt>
810ef31e1fSMike Welles    that is located at the top of the source tree; the precise alpha number
8225cbff28SJoris Van Damme    is given in the file <tt>dist/tiff.alpha</tt>.
830ef31e1fSMike Welles    If you have need to refer to this
840ef31e1fSMike Welles    specific software, you should identify it as:
8525cbff28SJoris Van Damme  </p>
8625cbff28SJoris Van Damme  <p style="margin-left: 40px">
8725cbff28SJoris Van Damme    <tt>TIFF &lt;<i>version</i>&gt; &lt;<i>alpha</i>&gt;</tt>
8825cbff28SJoris Van Damme  </p>
8925cbff28SJoris Van Damme  <p>
9025cbff28SJoris Van Damme    where <tt>&lt;<i>version</i>&gt;</tt> is whatever you get from
9125cbff28SJoris Van Damme    <tt>"cat VERSION"</tt> and <tt>&lt;<i>alpha</i>&gt;</tt> is
9225cbff28SJoris Van Damme    what you get from <tt>"cat dist/tiff.alpha"</tt>.
9325cbff28SJoris Van Damme  </p>
9425cbff28SJoris Van Damme  <p>
9525cbff28SJoris Van Damme    Within an application that uses <tt>libtiff</tt> the <tt>TIFFGetVersion</tt>
960ef31e1fSMike Welles    routine will return a pointer to a string that contains software version
970ef31e1fSMike Welles    information.
9825cbff28SJoris Van Damme    The library include file <tt>&lt;tiffio.h&gt;</tt> contains a C pre-processor
9925cbff28SJoris Van Damme    define <tt>TIFFLIB_VERSION</tt> that can be used to check library
1000ef31e1fSMike Welles    version compatiblity at compile time.
10125cbff28SJoris Van Damme  </p>
10225cbff28SJoris Van Damme  <hr>
10325cbff28SJoris Van Damme  <h2 id="typedefs">Library Datatypes</h2>
10425cbff28SJoris Van Damme  <p>
10525cbff28SJoris Van Damme    <tt>libtiff</tt> defines a portable programming interface through the
1060ef31e1fSMike Welles    use of a set of C type definitions.
10725cbff28SJoris Van Damme    These definitions, defined in in the files <b>tiff.h</b> and
10825cbff28SJoris Van Damme    <b>tiffio.h</b>,
10925cbff28SJoris Van Damme    isolate the <tt>libtiff</tt> API from the characteristics
1100ef31e1fSMike Welles    of the underlying machine.
1110ef31e1fSMike Welles    To insure portable code and correct operation, applications that use
11225cbff28SJoris Van Damme    <tt>libtiff</tt> should use the typedefs and follow the function
1130ef31e1fSMike Welles    prototypes for the library API.
11425cbff28SJoris Van Damme  </p>
11525cbff28SJoris Van Damme  <hr>
11625cbff28SJoris Van Damme  <h2 id="mman">Memory Management</h2>
11725cbff28SJoris Van Damme  <p>
11825cbff28SJoris Van Damme    <tt>libtiff</tt> uses a machine-specific set of routines for managing
1190ef31e1fSMike Welles    dynamically allocated memory.
12025cbff28SJoris Van Damme    <tt>_TIFFmalloc</tt>, <tt>_TIFFrealloc</tt>, and <tt>_TIFFfree</tt>
1210ef31e1fSMike Welles    mimic the normal ANSI C routines.
1220ef31e1fSMike Welles    Any dynamically allocated memory that is to be passed into the library
1230ef31e1fSMike Welles    should be allocated using these interfaces in order to insure pointer
1240ef31e1fSMike Welles    compatibility on machines with a segmented architecture.
12525cbff28SJoris Van Damme    (On 32-bit UNIX systems these routines just call the normal <tt>malloc</tt>,
12625cbff28SJoris Van Damme    <tt>realloc</tt>, and <tt>free</tt> routines in the C library.)
12725cbff28SJoris Van Damme  </p>
12825cbff28SJoris Van Damme  <p>
12925cbff28SJoris Van Damme    To deal with segmented pointer issues <tt>libtiff</tt> also provides
13025cbff28SJoris Van Damme    <tt>_TIFFmemcpy</tt>, <tt>_TIFFmemset</tt>, and <tt>_TIFFmemmove</tt>
1310ef31e1fSMike Welles    routines that mimic the equivalent ANSI C routines, but that are
13225cbff28SJoris Van Damme    intended for use with memory allocated through <tt>_TIFFmalloc</tt>
13325cbff28SJoris Van Damme    and <tt>_TIFFrealloc</tt>.
13425cbff28SJoris Van Damme  </p>
13525cbff28SJoris Van Damme  <hr>
13625cbff28SJoris Van Damme  <h2 id="errors">Error Handling</h2>
13725cbff28SJoris Van Damme  <p>
13825cbff28SJoris Van Damme    <tt>libtiff</tt> handles most errors by returning an invalid/erroneous
1390ef31e1fSMike Welles    value when returning from a function call.
1400ef31e1fSMike Welles    Various diagnostic messages may also be generated by the library.
1410ef31e1fSMike Welles    All error messages are directed to a single global error handler
14225cbff28SJoris Van Damme    routine that can be specified with a call to <tt>TIFFSetErrorHandler</tt>.
1430ef31e1fSMike Welles    Likewise warning messages are directed to a single handler routine
14425cbff28SJoris Van Damme    that can be specified with a call to <tt>TIFFSetWarningHandler</tt>
14525cbff28SJoris Van Damme  </p>
14625cbff28SJoris Van Damme  <hr>
14725cbff28SJoris Van Damme  <h2 id="fio">Basic File Handling</h2>
14825cbff28SJoris Van Damme  <p>
1490ef31e1fSMike Welles    The library is modeled after the normal UNIX stdio library.
1500ef31e1fSMike Welles    For example, to read from an existing TIFF image the
1510ef31e1fSMike Welles    file must first be opened:
15225cbff28SJoris Van Damme  </p>
15325cbff28SJoris Van Damme  <p style="margin-left: 40px">
15425cbff28SJoris Van Damme    <tt>#include "tiffio.h"<br>
15525cbff28SJoris Van Damme    main()<br>
15625cbff28SJoris Van Damme    {<br>
15725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;TIFF* tif = TIFFOpen("foo.tif", "r");<br>
15825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;... do stuff ...<br>
15925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;TIFFClose(tif);<br>
16025cbff28SJoris Van Damme    }</tt>
16125cbff28SJoris Van Damme  </p>
16225cbff28SJoris Van Damme  <p>
16325cbff28SJoris Van Damme    The handle returned by <tt>TIFFOpen</tt> is <i>opaque</i>, that is
1640ef31e1fSMike Welles    the application is not permitted to know about its contents.
1650ef31e1fSMike Welles    All subsequent library calls for this file must pass the handle
1660ef31e1fSMike Welles    as an argument.
16725cbff28SJoris Van Damme  </p>
16825cbff28SJoris Van Damme  <p>
1690ef31e1fSMike Welles    To create or overwrite a TIFF image the file is also opened, but with
17025cbff28SJoris Van Damme    a <tt>"w"</tt> argument:
17125cbff28SJoris Van Damme  <p>
17225cbff28SJoris Van Damme  <p style="margin-left: 40px">
17325cbff28SJoris Van Damme    <tt>#include "tiffio.h"<br>
17425cbff28SJoris Van Damme    main()<br>
17525cbff28SJoris Van Damme    {<br>
17625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;TIFF* tif = TIFFOpen("foo.tif", "w");<br>
17725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;... do stuff ...<br>
17825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;TIFFClose(tif);<br>
17925cbff28SJoris Van Damme    }</tt>
18025cbff28SJoris Van Damme  </p>
18125cbff28SJoris Van Damme  <p>
1820ef31e1fSMike Welles    If the file already exists it is first truncated to zero length.
18325cbff28SJoris Van Damme  </p>
18425cbff28SJoris Van Damme  <table>
18525cbff28SJoris Van Damme    <tr>
186*201ee77dSJoris Van Damme      <td valign=top><img src="images/warning.gif" width="40" height="40" alt=""></td>
18725cbff28SJoris Van Damme      <td><i>Note that unlike the stdio library TIFF image files may not be
1880ef31e1fSMike Welles        opened for both reading and writing;
18925cbff28SJoris Van Damme        there is no support for altering the contents of a TIFF file.</i></td>
19025cbff28SJoris Van Damme    </tr>
19125cbff28SJoris Van Damme  </table>
19225cbff28SJoris Van Damme  <p>
19325cbff28SJoris Van Damme    <tt>libtiff</tt> buffers much information associated with writing a
1940ef31e1fSMike Welles    valid TIFF image.  Consequently, when writing a TIFF image it is necessary
19525cbff28SJoris Van Damme    to always call <tt>TIFFClose</tt> or <tt>TIFFFlush</tt> to flush any
19625cbff28SJoris Van Damme    buffered information to a file.  Note that if you call <tt>TIFFClose</tt>
19725cbff28SJoris Van Damme    you do not need to call <tt>TIFFFlush</tt>.
19825cbff28SJoris Van Damme  </p>
19925cbff28SJoris Van Damme  <hr>
20025cbff28SJoris Van Damme  <h2 id="dirs">TIFF Directories</h2>
20125cbff28SJoris Van Damme  <p>
2020ef31e1fSMike Welles    TIFF supports the storage of multiple images in a single file.
20325cbff28SJoris Van Damme    Each image has an associated data structure termed a <i>directory</i>
2040ef31e1fSMike Welles    that houses all the information about the format and content of the
2050ef31e1fSMike Welles    image data.
2060ef31e1fSMike Welles    Images in a file are usually related but they do not need to be; it
2070ef31e1fSMike Welles    is perfectly alright to store a color image together with a black and
2080ef31e1fSMike Welles    white image.
2090ef31e1fSMike Welles    Note however that while images may be related their directories are
2100ef31e1fSMike Welles    not.
2110ef31e1fSMike Welles    That is, each directory stands on its own; their is no need to read
2120ef31e1fSMike Welles    an unrelated directory in order to properly interpret the contents
2130ef31e1fSMike Welles    of an image.
21425cbff28SJoris Van Damme  </p>
21525cbff28SJoris Van Damme  <p>
21625cbff28SJoris Van Damme    <tt>libtiff</tt> provides several routines for reading and writing
2170ef31e1fSMike Welles    directories.  In normal use there is no need to explicitly
2180ef31e1fSMike Welles    read or write a directory: the library automatically reads the first
2190ef31e1fSMike Welles    directory in a file when opened for reading, and directory information
2200ef31e1fSMike Welles    to be written is automatically accumulated and written when writing
22125cbff28SJoris Van Damme    (assuming <tt>TIFFClose</tt> or <tt>TIFFFlush</tt> are called).
22225cbff28SJoris Van Damme  </p>
22325cbff28SJoris Van Damme  <p>
22425cbff28SJoris Van Damme    For a file open for reading the <tt>TIFFSetDirectory</tt> routine can
2250ef31e1fSMike Welles    be used to select an arbitrary directory; directories are referenced by
2260ef31e1fSMike Welles    number with the numbering starting at 0.  Otherwise the
22725cbff28SJoris Van Damme    <tt>TIFFReadDirectory</tt> and <tt>TIFFWriteDirectory</tt> routines can
2280ef31e1fSMike Welles    be used for sequential access to directories.
2290ef31e1fSMike Welles    For example, to count the number of directories in a file the following
2300ef31e1fSMike Welles    code might be used:
23125cbff28SJoris Van Damme  </p>
23225cbff28SJoris Van Damme  <p style="margin-left: 40px">
23325cbff28SJoris Van Damme    <tt>#include "tiffio.h"<br>
23425cbff28SJoris Van Damme    main(int argc, char* argv[])<br>
23525cbff28SJoris Van Damme    {<br>
23625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;TIFF* tif = TIFFOpen(argv[1], "r");<br>
23725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;if (tif) {<br>
23825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int dircount = 0;<br>
23925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do {<br>
24025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dircount++;<br>
24125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} while (TIFFReadDirectory(tif));<br>
24225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d directories in %s\n", dircount, argv[1]);<br>
24325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFClose(tif);<br>
24425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;}<br>
24525cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;exit(0);<br>
24625cbff28SJoris Van Damme    }</tt>
24725cbff28SJoris Van Damme  </p>
24825cbff28SJoris Van Damme  <p>
2490ef31e1fSMike Welles    Finally, note that there are several routines for querying the
2500ef31e1fSMike Welles    directory status of an open file:
25125cbff28SJoris Van Damme    <tt>TIFFCurrentDirectory</tt> returns the index of the current
2520ef31e1fSMike Welles    directory and
25325cbff28SJoris Van Damme    <tt>TIFFLastDirectory</tt> returns an indication of whether the
2540ef31e1fSMike Welles    current directory is the last directory in a file.
25525cbff28SJoris Van Damme    There is also a routine, <tt>TIFFPrintDirectory</tt>, that can
2560ef31e1fSMike Welles    be called to print a formatted description of the contents of
2570ef31e1fSMike Welles    the current directory; consult the manual page for complete details.
25825cbff28SJoris Van Damme  </p>
25925cbff28SJoris Van Damme  <hr>
26025cbff28SJoris Van Damme  <h2 id="tags">TIFF Tags</h2>
26125cbff28SJoris Van Damme  <p>
2620ef31e1fSMike Welles    Image-related information such as the image width and height, number
2630ef31e1fSMike Welles    of samples, orientation, colorimetric information, etc.
2640ef31e1fSMike Welles    are stored in each image
26525cbff28SJoris Van Damme    directory in <i>fields</i> or <i>tags</i>.
2660ef31e1fSMike Welles    Tags are identified by a number that is usually a value registered
2670ef31e1fSMike Welles    with the Aldus (now Adobe) Corporation.
2680ef31e1fSMike Welles    Beware however that some vendors write
2690ef31e1fSMike Welles    TIFF images with tags that are unregistered; in this case interpreting
2700ef31e1fSMike Welles    their contents is usually a waste of time.
27125cbff28SJoris Van Damme  </p>
27225cbff28SJoris Van Damme  <p>
27325cbff28SJoris Van Damme    <tt>libtiff</tt> reads the contents of a directory all at once
2740ef31e1fSMike Welles    and converts the on-disk information to an appropriate in-memory
2750ef31e1fSMike Welles    form.  While the TIFF specification permits an arbitrary set of
2760ef31e1fSMike Welles    tags to be defined and used in a file, the library only understands
2770ef31e1fSMike Welles    a limited set of tags.
2780ef31e1fSMike Welles    Any unknown tags that are encountered in a file are ignored.
2790ef31e1fSMike Welles    There is a mechanism to extend the set of tags the library handles
2800ef31e1fSMike Welles    without modifying the library itself;
28125cbff28SJoris Van Damme    this is described <a href="addingtags.html">elsewhere</a>.
28225cbff28SJoris Van Damme  </p>
28325cbff28SJoris Van Damme  <p>
28425cbff28SJoris Van Damme    <tt>libtiff</tt> provides two interfaces for getting and setting tag
28525cbff28SJoris Van Damme    values: <tt>TIFFGetField</tt> and <tt>TIFFSetField</tt>.
2860ef31e1fSMike Welles    These routines use a variable argument list-style interface to pass
2870ef31e1fSMike Welles    parameters of different type through a single function interface.
28825cbff28SJoris Van Damme    The <i>get interface</i> takes one or more pointers to memory locations
2890ef31e1fSMike Welles    where the tag values are to be returned and also returns one or
2900ef31e1fSMike Welles    zero according to whether the requested tag is defined in the directory.
29125cbff28SJoris Van Damme    The <i>set interface</i> takes the tag values either by-reference or
2920ef31e1fSMike Welles    by-value.
2930ef31e1fSMike Welles    The TIFF specification defines
29425cbff28SJoris Van Damme    <i>default values</i> for some tags.
2950ef31e1fSMike Welles    To get the value of a tag, or its default value if it is undefined,
29625cbff28SJoris Van Damme    the <tt>TIFFGetFieldDefaulted</tt> interface may be used.
29725cbff28SJoris Van Damme  </p>
29825cbff28SJoris Van Damme  <p>
2990ef31e1fSMike Welles    The manual pages for the tag get and set routines specifiy the exact data types
3000ef31e1fSMike Welles    and calling conventions required for each tag supported by the library.
30125cbff28SJoris Van Damme  </p>
30225cbff28SJoris Van Damme  <hr>
30325cbff28SJoris Van Damme  <h2 id="compression">TIFF Compression Schemes</h2>
30425cbff28SJoris Van Damme  <p>
30525cbff28SJoris Van Damme    <tt>libtiff</tt> includes support for a wide variety of
3060ef31e1fSMike Welles    data compression schemes.
3070ef31e1fSMike Welles    In normal operation a compression scheme is automatically used when
30825cbff28SJoris Van Damme    the TIFF <tt>Compression</tt> tag is set, either by opening a file
3090ef31e1fSMike Welles    for reading, or by setting the tag when writing.
31025cbff28SJoris Van Damme  </p>
31125cbff28SJoris Van Damme  <p>
31225cbff28SJoris Van Damme    Compression schemes are implemented by software modules termed <i>codecs</i>
3130ef31e1fSMike Welles    that implement decoder and encoder routines that hook into the
3140ef31e1fSMike Welles    core library i/o support.
3150ef31e1fSMike Welles    Codecs other than those bundled with the library can be registered
31625cbff28SJoris Van Damme    for use with the <tt>TIFFRegisterCODEC</tt> routine.
3170ef31e1fSMike Welles    This interface can also be used to override the core-library
3180ef31e1fSMike Welles    implementation for a compression scheme.
31925cbff28SJoris Van Damme  </p>
32025cbff28SJoris Van Damme  <hr>
32125cbff28SJoris Van Damme  <h2 id="byteorder">Byte Order</h2>
32225cbff28SJoris Van Damme  <p>
3230ef31e1fSMike Welles    The TIFF specification says, and has always said, that
32425cbff28SJoris Van Damme    <em>a correct TIFF
32525cbff28SJoris Van Damme    reader must handle images in big-endian and little-endian byte order</em>.
32625cbff28SJoris Van Damme    <tt>libtiff</tt> conforms in this respect.
3270ef31e1fSMike Welles    Consequently there is no means to force a specific
3280ef31e1fSMike Welles    byte order for the data written to a TIFF image file (data is
3290ef31e1fSMike Welles    written in the native order of the host CPU unless appending to
3300ef31e1fSMike Welles    an existing file, in which case it is written in the byte order
3310ef31e1fSMike Welles    specified in the file).
33225cbff28SJoris Van Damme  </p>
33325cbff28SJoris Van Damme  <hr>
33425cbff28SJoris Van Damme  <h2 id="dataplacement">Data Placement</h2>
33525cbff28SJoris Van Damme  <p>
3360ef31e1fSMike Welles    The TIFF specification requires that all information except an
3370ef31e1fSMike Welles    8-byte header can be placed anywhere in a file.
3380ef31e1fSMike Welles    In particular, it is perfectly legitimate for directory information
3390ef31e1fSMike Welles    to be written after the image data itself.
3400ef31e1fSMike Welles    Consequently TIFF is inherently not suitable for passing through a
3410ef31e1fSMike Welles    stream-oriented mechanism such as UNIX pipes.
3420ef31e1fSMike Welles    Software that require that data be organized in a file in a particular
3430ef31e1fSMike Welles    order (e.g. directory information before image data) does not
3440ef31e1fSMike Welles    correctly support TIFF.
34525cbff28SJoris Van Damme    <tt>libtiff</tt> provides no mechanism for controlling the placement
3460ef31e1fSMike Welles    of data in a file; image data is typically written before directory
3470ef31e1fSMike Welles    information.
34825cbff28SJoris Van Damme  </p>
34925cbff28SJoris Van Damme  <hr>
35025cbff28SJoris Van Damme  <h2 id="tiffrgbaimage">TIFFRGBAImage Support</h2>
35125cbff28SJoris Van Damme  <p>
35225cbff28SJoris Van Damme    <tt>libtiff</tt> provides a high-level interface for reading image
3530ef31e1fSMike Welles    data from a TIFF file.  This interface handles the details of
3540ef31e1fSMike Welles    data organization and format for a wide variety of TIFF files;
3550ef31e1fSMike Welles    at least the large majority of those files that one would normally
3560ef31e1fSMike Welles    encounter.  Image data is, by default, returned as ABGR
3570ef31e1fSMike Welles    pixels packed into 32-bit words (8 bits per sample).  Rectangular
3580ef31e1fSMike Welles    rasters can be read or data can be intercepted at an intermediate
3590ef31e1fSMike Welles    level and packed into memory in a format more suitable to the
3600ef31e1fSMike Welles    application.
3610ef31e1fSMike Welles    The library handles all the details of the format of data stored on
3620ef31e1fSMike Welles    disk and, in most cases, if any colorspace conversions are required:
3630ef31e1fSMike Welles    bilevel to RGB, greyscale to RGB, CMYK to RGB, YCbCr to RGB, 16-bit
3640ef31e1fSMike Welles    samples to 8-bit samples, associated/unassociated alpha, etc.
36525cbff28SJoris Van Damme  </p>
36625cbff28SJoris Van Damme  <p>
3670ef31e1fSMike Welles    There are two ways to read image data using this interface.  If
3680ef31e1fSMike Welles    all the data is to be stored in memory and manipulated at once,
36925cbff28SJoris Van Damme    then the routine <tt>TIFFReadRGBAImage</tt> can be used:
37025cbff28SJoris Van Damme  </p>
37125cbff28SJoris Van Damme  <p>
37225cbff28SJoris Van Damme  <p style="margin-left: 40px">
37325cbff28SJoris Van Damme    <tt>#include "tiffio.h"<br>
37425cbff28SJoris Van Damme    main(int argc, char* argv[])<br>
37525cbff28SJoris Van Damme    {<br>
37625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;TIFF* tif = TIFFOpen(argv[1], "r");<br>
37725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;if (tif) {<br>
37825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint32 w, h;<br>
37925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t npixels;<br>
38025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint32* raster;<br>
38125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
38225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &amp;w);<br>
38325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &amp;h);<br>
38425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;npixels = w * h;<br>
38525cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));<br>
38625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (raster != NULL) {<br>
38725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (TIFFReadRGBAImage(tif, w, h, raster, 0)) {<br>
38825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...process raster data...<br>
38925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
39025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_TIFFfree(raster);<br>
39125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
39225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFClose(tif);<br>
39325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;}<br>
39425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;exit(0);<br>
39525cbff28SJoris Van Damme    }</tt>
39625cbff28SJoris Van Damme  </p>
39725cbff28SJoris Van Damme  <p>
39825cbff28SJoris Van Damme    Note above that <tt>_TIFFmalloc</tt> is used to allocate memory for
39925cbff28SJoris Van Damme    the raster passed to <tt>TIFFReadRGBAImage</tt>; this is important
4000ef31e1fSMike Welles    to insure the ``appropriate type of memory'' is passed on machines
4010ef31e1fSMike Welles    with segmented architectures.
40225cbff28SJoris Van Damme  </p>
40325cbff28SJoris Van Damme  <p>
40425cbff28SJoris Van Damme    Alternatively, <tt>TIFFReadRGBAImage</tt> can be replaced with a
4050ef31e1fSMike Welles    more low-level interface that permits an application to have more
4060ef31e1fSMike Welles    control over this reading procedure.  The equivalent to the above
4070ef31e1fSMike Welles    is:
40825cbff28SJoris Van Damme  </p>
40925cbff28SJoris Van Damme  <p style="margin-left: 40px">
41025cbff28SJoris Van Damme    <tt>#include "tiffio.h"<br>
41125cbff28SJoris Van Damme    main(int argc, char* argv[])<br>
41225cbff28SJoris Van Damme    {<br>
41325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;TIFF* tif = TIFFOpen(argv[1], "r");<br>
41425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;if (tif) {<br>
41525cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFRGBAImage img;<br>
41625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char emsg[1024];<br>
41725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
41825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (TIFFRGBAImageBegin(&amp;img, tif, 0, emsg)) {<br>
41925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_t npixels;<br>
42025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint32* raster;<br>
42125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
42225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;npixels = img.width * img.height;<br>
42325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));<br>
42425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (raster != NULL) {<br>
42525cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (TIFFRGBAImageGet(&amp;img, raster, img.width, img.height)) {<br>
42625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...process raster data...<br>
42725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
42825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_TIFFfree(raster);<br>
42925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
43025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFRGBAImageEnd(&amp;img);<br>
43125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else<br>
43225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFError(argv[1], emsg);<br>
43325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFClose(tif);<br>
43425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;}<br>
43525cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;exit(0);<br>
43625cbff28SJoris Van Damme    }</tt>
43725cbff28SJoris Van Damme  </p>
43825cbff28SJoris Van Damme  <p>
4390ef31e1fSMike Welles    However this usage does not take advantage of the more fine-grained
4400ef31e1fSMike Welles    control that's possible.  That is, by using this interface it is
4410ef31e1fSMike Welles    possible to:
44225cbff28SJoris Van Damme  </p>
44325cbff28SJoris Van Damme  <ul>
44425cbff28SJoris Van Damme    <li>repeatedly fetch (and manipulate) an image without opening
44525cbff28SJoris Van Damme      and closing the file</li>
44625cbff28SJoris Van Damme    <li>interpose a method for packing raster pixel data according to
44725cbff28SJoris Van Damme      application-specific needs (or write the data at all)</li>
44825cbff28SJoris Van Damme    <li>interpose methods that handle TIFF formats that are not already
44925cbff28SJoris Van Damme      handled by the core library</li>
45025cbff28SJoris Van Damme  </ul>
45125cbff28SJoris Van Damme  <p>
4520ef31e1fSMike Welles    The first item means that, for example, image viewers that want to
4530ef31e1fSMike Welles    handle multiple files can cache decoding information in order to
4540ef31e1fSMike Welles    speedup the work required to display a TIFF image.
45525cbff28SJoris Van Damme  </p>
45625cbff28SJoris Van Damme  <p>
4570ef31e1fSMike Welles    The second item is the main reason for this interface.  By interposing
45825cbff28SJoris Van Damme    a "put method" (the routine that is called to pack pixel data in
4590ef31e1fSMike Welles    the raster) it is possible share the core logic that understands how
4600ef31e1fSMike Welles    to deal with TIFF while packing the resultant pixels in a format that
4610ef31e1fSMike Welles    is optimized for the application.  This alternate format might be very
4620ef31e1fSMike Welles    different than the 8-bit per sample ABGR format the library writes by
4630ef31e1fSMike Welles    default.  For example, if the application is going to display the image
4640ef31e1fSMike Welles    on an 8-bit colormap display the put routine might take the data and
4650ef31e1fSMike Welles    convert it on-the-fly to the best colormap indices for display.
46625cbff28SJoris Van Damme  </p>
46725cbff28SJoris Van Damme  <p>
4680ef31e1fSMike Welles    The last item permits an application to extend the library
4690ef31e1fSMike Welles    without modifying the core code.
4700ef31e1fSMike Welles    By overriding the code provided an application might add support
4710ef31e1fSMike Welles    for some esoteric flavor of TIFF that it needs, or it might
4720ef31e1fSMike Welles    substitute a packing routine that is able to do optimizations
4730ef31e1fSMike Welles    using application/environment-specific information.
47425cbff28SJoris Van Damme  </p>
47525cbff28SJoris Van Damme  <p>
47625cbff28SJoris Van Damme    The TIFF image viewer found in <b>tools/sgigt.c</b> is an example
47725cbff28SJoris Van Damme    of an application that makes use of the <tt>TIFFRGBAImage</tt>
4780ef31e1fSMike Welles    support.
47925cbff28SJoris Van Damme  </p>
48025cbff28SJoris Van Damme  <hr>
48125cbff28SJoris Van Damme  <h2 id="scanlines">Scanline-based Image I/O</h2>
48225cbff28SJoris Van Damme  <p>
48325cbff28SJoris Van Damme    The simplest interface provided by <tt>libtiff</tt> is a
4840ef31e1fSMike Welles    scanline-oriented interface that can be used to read TIFF
4850ef31e1fSMike Welles    images that have their image data organized in strips
4860ef31e1fSMike Welles    (trying to use this interface to read data written in tiles
4870ef31e1fSMike Welles    will produce errors.)
4880ef31e1fSMike Welles    A scanline is a one pixel high row of image data whose width
4890ef31e1fSMike Welles    is the width of the image.
4900ef31e1fSMike Welles    Data is returned packed if the image data is stored with samples
4910ef31e1fSMike Welles    packed together, or as arrays of separate samples if the data
4920ef31e1fSMike Welles    is stored with samples separated.
4930ef31e1fSMike Welles    The major limitation of the scanline-oriented interface, other
4940ef31e1fSMike Welles    than the need to first identify an existing file as having a
4950ef31e1fSMike Welles    suitable organization, is that random access to individual
4960ef31e1fSMike Welles    scanlines can only be provided when data is not stored in a
4970ef31e1fSMike Welles    compressed format, or when the number of rows in a strip
49825cbff28SJoris Van Damme    of image data is set to one (<tt>RowsPerStrip</tt> is one).
49925cbff28SJoris Van Damme  </p>
50025cbff28SJoris Van Damme  <p>
5010ef31e1fSMike Welles    Two routines are provided for scanline-based i/o:
50225cbff28SJoris Van Damme    <tt>TIFFReadScanline</tt>
5030ef31e1fSMike Welles    and
50425cbff28SJoris Van Damme    <tt>TIFFWriteScanline</tt>.
5050ef31e1fSMike Welles    For example, to read the contents of a file that
5060ef31e1fSMike Welles    is assumed to be organized in strips, the following might be used:
50725cbff28SJoris Van Damme  </p>
50825cbff28SJoris Van Damme  <p style="margin-left: 40px">
50925cbff28SJoris Van Damme    <tt>#include "tiffio.h"<br>
51025cbff28SJoris Van Damme    main()<br>
51125cbff28SJoris Van Damme    {<br>
51225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;TIFF* tif = TIFFOpen("myfile.tif", "r");<br>
51325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;if (tif) {<br>
51425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint32 imagelength;<br>
51525cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdata_t buf;<br>
51625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint32 row;<br>
51725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
51825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &amp;imagelength);<br>
51925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf = _TIFFmalloc(TIFFScanlineSize(tif));<br>
52025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (row = 0; row &lt; imagelength; row++)<br>
52125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffreadscanline(tif, buf, row);<br>
52225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_tifffree(buf);<br>
52325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffclose(tif);<br>
52425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;}<br>
52525cbff28SJoris Van Damme    }</tt>
52625cbff28SJoris Van Damme  </p>
52725cbff28SJoris Van Damme  <p>
52825cbff28SJoris Van Damme    <tt>TIFFScanlineSize</tt> returns the number of bytes in
52925cbff28SJoris Van Damme    a decoded scanline, as returned by <tt>TIFFReadScanline</tt>.
5300ef31e1fSMike Welles    Note however that if the file had been create with samples
5310ef31e1fSMike Welles    written in separate planes, then the above code would only
5320ef31e1fSMike Welles    read data that contained the first sample of each pixel;
5330ef31e1fSMike Welles    to handle either case one might use the following instead:
53425cbff28SJoris Van Damme  </p>
53525cbff28SJoris Van Damme  <p style="margin-left: 40px">
53625cbff28SJoris Van Damme    <tt>#include "tiffio.h"<br>
53725cbff28SJoris Van Damme    main()<br>
53825cbff28SJoris Van Damme    {<br>
53925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;TIFF* tif = TIFFOpen("myfile.tif", "r");<br>
54025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;if (tif) {<br>
54125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint32 imagelength;<br>
54225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdata_t buf;<br>
54325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint32 row;<br>
54425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
54525cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &amp;imagelength);<br>
54625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &amp;config);<br>
54725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf = _TIFFmalloc(TIFFScanlineSize(tif));<br>
54825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (config == PLANARCONFIG_CONTIG) {<br>
54925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (row = 0; row &lt; imagelength; row++)<br>
55025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffreadscanline(tif, buf, row);<br>
55125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else if (config == planarconfig_separate) {<br>
55225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint16 s, nsamples;<br>
55325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
55425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffgetfield(tif, tifftag_samplesperpixel, &amp;nsamples);<br>
55525cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (s = 0; s &lt; nsamples; s++)<br>
55625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (row = 0; row &lt; imagelength; row++)<br>
55725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffreadscanline(tif, buf, row, s);<br>
55825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
55925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_tifffree(buf);<br>
56025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffclose(tif);<br>
56125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;}<br>
56225cbff28SJoris Van Damme    }</tt>
56325cbff28SJoris Van Damme  </p>
56425cbff28SJoris Van Damme  <p>
5650ef31e1fSMike Welles    Beware however that if the following code were used instead to
56625cbff28SJoris Van Damme    read data in the case <tt>PLANARCONFIG_SEPARATE</tt>,...
56725cbff28SJoris Van Damme  </p>
56825cbff28SJoris Van Damme  <p style="margin-left: 40px">
56925cbff28SJoris Van Damme    <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (row = 0; row &lt; imagelength; row++)<br>
57025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (s = 0; s &lt; nsamples; s++)<br>
57125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffreadscanline(tif, buf, row, s);</tt>
57225cbff28SJoris Van Damme  </p>
57325cbff28SJoris Van Damme  <p>
57425cbff28SJoris Van Damme    ...then problems would arise if <tt>RowsPerStrip</tt> was not one
5750ef31e1fSMike Welles    because the order in which scanlines are requested would require
5760ef31e1fSMike Welles    random access to data within strips (something that is not supported
5770ef31e1fSMike Welles    by the library when strips are compressed).
57825cbff28SJoris Van Damme  </p>
57925cbff28SJoris Van Damme  <hr>
58025cbff28SJoris Van Damme  <h2 id="strips">Strip-oriented Image I/O</h2>
58125cbff28SJoris Van Damme  <p>
5820ef31e1fSMike Welles    The strip-oriented interfaces provided by the library provide
5830ef31e1fSMike Welles    access to entire strips of data.  Unlike the scanline-oriented
5840ef31e1fSMike Welles    calls, data can be read or written compressed or uncompressed.
5850ef31e1fSMike Welles    Accessing data at a strip (or tile) level is often desirable
5860ef31e1fSMike Welles    because there are no complications with regard to random access
5870ef31e1fSMike Welles    to data within strips.
58825cbff28SJoris Van Damme  </p>
58925cbff28SJoris Van Damme  <p>
5900ef31e1fSMike Welles    A simple example of reading an image by strips is:
59125cbff28SJoris Van Damme  </p>
59225cbff28SJoris Van Damme  <p style="margin-left: 40px">
59325cbff28SJoris Van Damme    <tt>#include "tiffio.h"<br>
59425cbff28SJoris Van Damme    main()<br>
59525cbff28SJoris Van Damme    {<br>
59625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;TIFF* tif = TIFFOpen("myfile.tif", "r");<br>
59725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;if (tif) {<br>
59825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdata_t buf;<br>
59925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tstrip_t strip;<br>
60025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
60125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf = _TIFFmalloc(TIFFStripSize(tif));<br>
60225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (strip = 0; strip &lt; tiffnumberofstrips(tif); strip++)<br>
60325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffreadencodedstrip(tif, strip, buf, (tsize_t) -1);<br>
60425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_tifffree(buf);<br>
60525cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffclose(tif);<br>
60625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;}<br>
60725cbff28SJoris Van Damme    }</tt>
60825cbff28SJoris Van Damme  </p>
60925cbff28SJoris Van Damme  <p>
61025cbff28SJoris Van Damme    Notice how a strip size of <tt>-1</tt> is used; <tt>TIFFReadEncodedStrip</tt>
6110ef31e1fSMike Welles    will calculate the appropriate size in this case.
61225cbff28SJoris Van Damme  </p>
61325cbff28SJoris Van Damme  <p>
6140ef31e1fSMike Welles    The above code reads strips in the order in which the
6150ef31e1fSMike Welles    data is physically stored in the file.  If multiple samples
61625cbff28SJoris Van Damme    are present and data is stored with <tt>PLANARCONFIG_SEPARATE</tt>
6170ef31e1fSMike Welles    then all the strips of data holding the first sample will be
6180ef31e1fSMike Welles    read, followed by strips for the second sample, etc.
61925cbff28SJoris Van Damme  </p>
62025cbff28SJoris Van Damme  <p>
6210ef31e1fSMike Welles    Finally, note that the last strip of data in an image may have fewer
62225cbff28SJoris Van Damme    rows in it than specified by the <tt>RowsPerStrip</tt> tag.  A
6230ef31e1fSMike Welles    reader should not assume that each decoded strip contains a full
6240ef31e1fSMike Welles    set of rows in it.
62525cbff28SJoris Van Damme  </p>
62625cbff28SJoris Van Damme  <p>
6270ef31e1fSMike Welles    The following is an example of how to read raw strips of data from
6280ef31e1fSMike Welles    a file:
62925cbff28SJoris Van Damme  </p>
63025cbff28SJoris Van Damme  <p style="margin-left: 40px">
63125cbff28SJoris Van Damme    <tt>#include "tiffio.h"<br>
63225cbff28SJoris Van Damme    main()<br>
63325cbff28SJoris Van Damme    {<br>
63425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;TIFF* tif = TIFFOpen("myfile.tif", "r");<br>
63525cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;if (tif) {<br>
63625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdata_t buf;<br>
63725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tstrip_t strip;<br>
63825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint32* bc;<br>
63925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint32 stripsize;<br>
64025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
64125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &amp;bc);<br>
64225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stripsize = bc[0];<br>
64325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf = _TIFFmalloc(stripsize);<br>
64425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (strip = 0; strip &lt; tiffnumberofstrips(tif); strip++) {<br>
64525cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (bc[strip] &gt; stripsize) {<br>
64625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf = _TIFFrealloc(buf, bc[strip]);<br>
64725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stripsize = bc[strip];<br>
64825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
64925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFReadRawStrip(tif, strip, buf, bc[strip]);<br>
65025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
65125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_TIFFfree(buf);<br>
65225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFClose(tif);<br>
65325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;}<br>
65425cbff28SJoris Van Damme    }</tt>
65525cbff28SJoris Van Damme  </p>
65625cbff28SJoris Van Damme  <p>
6570ef31e1fSMike Welles    As above the strips are read in the order in which they are
6580ef31e1fSMike Welles    physically stored in the file; this may be different from the
6590ef31e1fSMike Welles    logical ordering expected by an application.
66025cbff28SJoris Van Damme  </p>
66125cbff28SJoris Van Damme  <hr>
66225cbff28SJoris Van Damme  <h2 id="tiles">Tile-oriented Image I/O</h2>
66325cbff28SJoris Van Damme  <p>
6640ef31e1fSMike Welles    Tiles of data may be read and written in a manner similar to strips.
6650ef31e1fSMike Welles    With this interface, an image is
6660ef31e1fSMike Welles    broken up into a set of rectangular areas that may have dimensions
6670ef31e1fSMike Welles    less than the image width and height.  All the tiles
6680ef31e1fSMike Welles    in an image have the same size, and the tile width and length must each
6690ef31e1fSMike Welles    be a multiple of 16 pixels.  Tiles are ordered left-to-right and
6700ef31e1fSMike Welles    top-to-bottom in an image.  As for scanlines, samples can be packed
6710ef31e1fSMike Welles    contiguously or separately.  When separated, all the tiles for a sample
6720ef31e1fSMike Welles    are colocated in the file.  That is, all the tiles for sample 0 appear
6730ef31e1fSMike Welles    before the tiles for sample 1, etc.
67425cbff28SJoris Van Damme  </p>
67525cbff28SJoris Van Damme  <p>
6760ef31e1fSMike Welles    Tiles and strips may also be extended in a z dimension to form
6770ef31e1fSMike Welles    volumes.  Data volumes are organized as "slices".  That is, all the
6780ef31e1fSMike Welles    data for a slice is colocated.  Volumes whose data is organized in
6790ef31e1fSMike Welles    tiles can also have a tile depth so that data can be organized in
6800ef31e1fSMike Welles    cubes.
68125cbff28SJoris Van Damme  </p>
68225cbff28SJoris Van Damme  <p>
6830ef31e1fSMike Welles    There are actually two interfaces for tiles.
6840ef31e1fSMike Welles    One interface is similar to scanlines,  to read a tiled image,
6850ef31e1fSMike Welles    code of the following sort might be used:
68625cbff28SJoris Van Damme  </p>
68725cbff28SJoris Van Damme  <p style="margin-left: 40px">
68825cbff28SJoris Van Damme    <tt>main()<br>
68925cbff28SJoris Van Damme    {<br>
69025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;TIFF* tif = TIFFOpen("myfile.tif", "r");<br>
69125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;if (tif) {<br>
69225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint32 imageWidth, imageLength;<br>
69325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint32 tileWidth, tileLength;<br>
69425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint32 x, y;<br>
69525cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdata_t buf;<br>
69625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
69725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &amp;imageWidth);<br>
69825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &amp;imageLength);<br>
69925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFGetField(tif, TIFFTAG_TILEWIDTH, &amp;tileWidth);<br>
70025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIFFGetField(tif, TIFFTAG_TILELENGTH, &amp;tileLength);<br>
70125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf = _TIFFmalloc(TIFFTileSize(tif));<br>
70225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (y = 0; y &lt; imagelength; y += tilelength)<br>
70325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (x = 0; x &lt; imagewidth; x += tilewidth)<br>
70425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffreadtile(tif, buf, x, y, 0);<br>
70525cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_tifffree(buf);<br>
70625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffclose(tif);<br>
70725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;}<br>
70825cbff28SJoris Van Damme    }</tt>
70925cbff28SJoris Van Damme  </p>
71025cbff28SJoris Van Damme  <p>
7110ef31e1fSMike Welles    (once again, we assume samples are packed contiguously.)
71225cbff28SJoris Van Damme  </p>
71325cbff28SJoris Van Damme  <p>
7140ef31e1fSMike Welles    Alternatively a direct interface to the low-level data is provided
7150ef31e1fSMike Welles    a la strips.  Tiles can be read with
71625cbff28SJoris Van Damme    <tt>TIFFReadEncodedTile</tt> or <tt>TIFFReadRawTile</tt>,
71725cbff28SJoris Van Damme    and written with <tt>TIFFWriteEncodedTile</tt> or
71825cbff28SJoris Van Damme    <tt>TIFFWriteRawTile</tt>. For example, to read all the tiles in an image:
71925cbff28SJoris Van Damme  </p>
72025cbff28SJoris Van Damme  <p style="margin-left: 40px">
72125cbff28SJoris Van Damme    <tt>#include "tiffio.h"<br>
72225cbff28SJoris Van Damme    main()<br>
72325cbff28SJoris Van Damme    {<br>
72425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;TIFF* tif = TIFFOpen("myfile.tif", "r");<br>
72525cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;if (tif) {<br>
72625cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tdata_t buf;<br>
72725cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ttile_t tile;<br>
72825cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
72925cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf = _TIFFmalloc(TIFFTileSize(tif));<br>
73025cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (tile = 0; tile &lt; tiffnumberoftiles(tif); tile++)<br>
73125cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffreadencodedtile(tif, tile, buf, (tsize_t) -1);<br>
73225cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_tifffree(buf);<br>
73325cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tiffclose(tif);<br>
73425cbff28SJoris Van Damme    &nbsp;&nbsp;&nbsp;&nbsp;}<br>
73525cbff28SJoris Van Damme    }</tt>
73625cbff28SJoris Van Damme  </p>
73725cbff28SJoris Van Damme  <hr>
73825cbff28SJoris Van Damme  <h2 id="other">Other Stuff</h2>
73925cbff28SJoris Van Damme  <p>
74025cbff28SJoris Van Damme    Some other stuff will almost certainly go here...
74125cbff28SJoris Van Damme  </p>
74225cbff28SJoris Van Damme  <hr>
74325cbff28SJoris Van Damme  <p>
744*201ee77dSJoris Van Damme    Last updated: $Date: 2005-12-28 06:53:18 $
74525cbff28SJoris Van Damme  </p>
74625cbff28SJoris Van Damme</body>
74725cbff28SJoris Van Damme</html>
748