1*0ef31e1fSMike Welles<HTML> 2*0ef31e1fSMike Welles<HEAD> 3*0ef31e1fSMike Welles<TITLE> 4*0ef31e1fSMike WellesUsing The TIFF Library 5*0ef31e1fSMike Welles</TITLE> 6*0ef31e1fSMike Welles</HEAD> 7*0ef31e1fSMike Welles 8*0ef31e1fSMike Welles<H1> 9*0ef31e1fSMike Welles<IMG SRC=images/cat.gif WIDTH=113 HEIGHT=146 BORDER=2 ALIGN=left HSPACE=6> 10*0ef31e1fSMike WellesUsing The TIFF Library 11*0ef31e1fSMike Welles</H1> 12*0ef31e1fSMike Welles 13*0ef31e1fSMike Welles<P> 14*0ef31e1fSMike Welles<TT>libtiff</TT> is a set of C functions (a library) that support 15*0ef31e1fSMike Wellesthe manipulation of TIFF image files. 16*0ef31e1fSMike WellesThe library requires an ANSI C compilation environment for building 17*0ef31e1fSMike Wellesand presumes an ANSI C environment for use. 18*0ef31e1fSMike Welles 19*0ef31e1fSMike Welles<P> 20*0ef31e1fSMike Welles<TT>libtiff</TT> 21*0ef31e1fSMike Wellesprovides interfaces to image data at several layers of abstraction (and cost). 22*0ef31e1fSMike WellesAt the highest level image data can be read into an 8-bit/sample, 23*0ef31e1fSMike WellesABGR pixel raster format without regard for the underlying data organization, 24*0ef31e1fSMike Wellescolorspace, or compression scheme. Below this high-level interface 25*0ef31e1fSMike Wellesthe library provides scanline-, strip-, and tile-oriented interfaces that 26*0ef31e1fSMike Wellesreturn data decompressed but otherwise untransformed. These interfaces 27*0ef31e1fSMike Wellesrequire that the application first identify the organization of stored 28*0ef31e1fSMike Wellesdata and select either a strip-based or tile-based API for manipulating 29*0ef31e1fSMike Wellesdata. At the lowest level the library 30*0ef31e1fSMike Wellesprovides access to the raw uncompressed strips or tiles, 31*0ef31e1fSMike Wellesreturning the data exactly as it appears in the file. 32*0ef31e1fSMike Welles 33*0ef31e1fSMike Welles<P> 34*0ef31e1fSMike WellesThe material presented in this chapter is a basic introduction 35*0ef31e1fSMike Wellesto the capabilities of the library; it is not an attempt to describe 36*0ef31e1fSMike Welleseverything a developer needs to know about the library or about TIFF. 37*0ef31e1fSMike WellesDetailed information on the interfaces to the library are given in 38*0ef31e1fSMike Wellesthe <A HREF="http://www-mipl.jpl.nasa.gov/~ndr/tiff/man/"> 39*0ef31e1fSMike WellesUNIX manual pages</A> that accompany this software. 40*0ef31e1fSMike Welles 41*0ef31e1fSMike Welles<P> 42*0ef31e1fSMike WellesThe following sections are found in this chapter: 43*0ef31e1fSMike Welles 44*0ef31e1fSMike Welles<UL> 45*0ef31e1fSMike Welles<LI><A HREF=#Version>How to tell which version you have</A> 46*0ef31e1fSMike Welles<LI><A HREF=#Typedefs>Library Datatypes</A> 47*0ef31e1fSMike Welles<LI><A HREF=#Mman>Memory Management</A> 48*0ef31e1fSMike Welles<LI><A HREF=#Errors>Error Handling</A> 49*0ef31e1fSMike Welles<LI><A HREF=#FIO>Basic File Handling</A> 50*0ef31e1fSMike Welles<LI><A HREF=#Dirs>TIFF Directories</A> 51*0ef31e1fSMike Welles<LI><A HREF=#Tags>TIFF Tags</A> 52*0ef31e1fSMike Welles<LI><A HREF=#Compression>TIFF Compression Schemes</A> 53*0ef31e1fSMike Welles<LI><A HREF=#ByteOrder>Byte Order</A> 54*0ef31e1fSMike Welles<LI><A HREF=#DataPlacement>Data Placement</A> 55*0ef31e1fSMike Welles<LI><A HREF=#TIFFRGBAImage>TIFFRGBAImage Support</A> 56*0ef31e1fSMike Welles<LI><A HREF=#Scanlines>Scanline-based Image I/O</A> 57*0ef31e1fSMike Welles<LI><A HREF=#Strips>Strip-oriented Image I/O</A> 58*0ef31e1fSMike Welles<LI><A HREF=#Tiles>Tile-oriented Image I/O</A> 59*0ef31e1fSMike Welles<LI><A HREF=#Other>Other Stuff</A> 60*0ef31e1fSMike Welles</UL> 61*0ef31e1fSMike Welles 62*0ef31e1fSMike Welles 63*0ef31e1fSMike Welles<A NAME="Version"><P><HR WIDTH=65% ALIGN=right><H3>How to tell which version you have</H3></A> 64*0ef31e1fSMike Welles 65*0ef31e1fSMike WellesThe software version can be found by looking at the file named 66*0ef31e1fSMike Welles<TT>VERSION</TT> 67*0ef31e1fSMike Wellesthat is located at the top of the source tree; the precise alpha number 68*0ef31e1fSMike Wellesis given in the file <TT>dist/tiff.alpha</TT>. 69*0ef31e1fSMike WellesIf you have need to refer to this 70*0ef31e1fSMike Wellesspecific software, you should identify it as: 71*0ef31e1fSMike Welles 72*0ef31e1fSMike Welles<PRE> 73*0ef31e1fSMike Welles TIFF <<I>version</I>> <<I>alpha</I>> 74*0ef31e1fSMike Welles</PRE> 75*0ef31e1fSMike Welles 76*0ef31e1fSMike Welleswhere <<I>version</I>> is whatever you get from 77*0ef31e1fSMike Welles<KBD>"cat VERSION"</KBD> and <<I>alpha</I>> is 78*0ef31e1fSMike Welleswhat you get from <KBD>"cat dist/tiff.alpha"</KBD>. 79*0ef31e1fSMike Welles 80*0ef31e1fSMike Welles<P> 81*0ef31e1fSMike WellesWithin an application that uses <TT>libtiff</TT> the <TT>TIFFGetVersion</TT> 82*0ef31e1fSMike Wellesroutine will return a pointer to a string that contains software version 83*0ef31e1fSMike Wellesinformation. 84*0ef31e1fSMike WellesThe library include file <TT><tiffio.h></TT> contains a C pre-processor 85*0ef31e1fSMike Wellesdefine <TT>TIFFLIB_VERSION</TT> that can be used to check library 86*0ef31e1fSMike Wellesversion compatiblity at compile time. 87*0ef31e1fSMike Welles 88*0ef31e1fSMike Welles<A NAME="Typedefs"><P><HR WIDTH=65% ALIGN=right><H3>Library Datatypes</H3></A> 89*0ef31e1fSMike Welles 90*0ef31e1fSMike Welles<TT>libtiff</TT> defines a portable programming interface through the 91*0ef31e1fSMike Wellesuse of a set of C type definitions. 92*0ef31e1fSMike WellesThese definitions, defined in in the files <B>tiff.h</B> and 93*0ef31e1fSMike Welles<B>tiffio.h</B>, 94*0ef31e1fSMike Wellesisolate the <TT>libtiff</TT> API from the characteristics 95*0ef31e1fSMike Wellesof the underlying machine. 96*0ef31e1fSMike WellesTo insure portable code and correct operation, applications that use 97*0ef31e1fSMike Welles<TT>libtiff</TT> should use the typedefs and follow the function 98*0ef31e1fSMike Wellesprototypes for the library API. 99*0ef31e1fSMike Welles 100*0ef31e1fSMike Welles<A NAME="Mman"><P><HR WIDTH=65% ALIGN=right><H3>Memory Management</H3></A> 101*0ef31e1fSMike Welles 102*0ef31e1fSMike Welles<TT>libtiff</TT> uses a machine-specific set of routines for managing 103*0ef31e1fSMike Wellesdynamically allocated memory. 104*0ef31e1fSMike Welles<TT>_TIFFmalloc</TT>, <TT>_TIFFrealloc</TT>, and <TT>_TIFFfree</TT> 105*0ef31e1fSMike Wellesmimic the normal ANSI C routines. 106*0ef31e1fSMike WellesAny dynamically allocated memory that is to be passed into the library 107*0ef31e1fSMike Wellesshould be allocated using these interfaces in order to insure pointer 108*0ef31e1fSMike Wellescompatibility on machines with a segmented architecture. 109*0ef31e1fSMike Welles(On 32-bit UNIX systems these routines just call the normal <TT>malloc</TT>, 110*0ef31e1fSMike Welles<TT>realloc</TT>, and <TT>free</TT> routines in the C library.) 111*0ef31e1fSMike Welles 112*0ef31e1fSMike Welles<P> 113*0ef31e1fSMike WellesTo deal with segmented pointer issues <TT>libtiff</TT> also provides 114*0ef31e1fSMike Welles<TT>_TIFFmemcpy</TT>, <TT>_TIFFmemset</TT>, and <TT>_TIFFmemmove</TT> 115*0ef31e1fSMike Wellesroutines that mimic the equivalent ANSI C routines, but that are 116*0ef31e1fSMike Wellesintended for use with memory allocated through <TT>_TIFFmalloc</TT> 117*0ef31e1fSMike Wellesand <TT>_TIFFrealloc</TT>. 118*0ef31e1fSMike Welles 119*0ef31e1fSMike Welles<A NAME="Errors"><P><HR WIDTH=65% ALIGN=right><H3>Error Handling</H3></A> 120*0ef31e1fSMike Welles 121*0ef31e1fSMike Welles<TT>libtiff</TT> handles most errors by returning an invalid/erroneous 122*0ef31e1fSMike Wellesvalue when returning from a function call. 123*0ef31e1fSMike WellesVarious diagnostic messages may also be generated by the library. 124*0ef31e1fSMike WellesAll error messages are directed to a single global error handler 125*0ef31e1fSMike Wellesroutine that can be specified with a call to <TT>TIFFSetErrorHandler</TT>. 126*0ef31e1fSMike WellesLikewise warning messages are directed to a single handler routine 127*0ef31e1fSMike Wellesthat can be specified with a call to <TT>TIFFSetWarningHandler</TT> 128*0ef31e1fSMike Welles 129*0ef31e1fSMike Welles<A NAME="FIO"><P><HR WIDTH=65% ALIGN=right><H3>Basic File Handling</H3></A> 130*0ef31e1fSMike Welles 131*0ef31e1fSMike WellesThe library is modeled after the normal UNIX stdio library. 132*0ef31e1fSMike WellesFor example, to read from an existing TIFF image the 133*0ef31e1fSMike Wellesfile must first be opened: 134*0ef31e1fSMike Welles 135*0ef31e1fSMike Welles<UL><LISTING> 136*0ef31e1fSMike Welles#include "tiffio.h" 137*0ef31e1fSMike Wellesmain() 138*0ef31e1fSMike Welles{ 139*0ef31e1fSMike Welles TIFF* tif = TIFFOpen("foo.tif", "r"); 140*0ef31e1fSMike Welles ... do stuff ... 141*0ef31e1fSMike Welles TIFFClose(tif); 142*0ef31e1fSMike Welles} 143*0ef31e1fSMike Welles</LISTING></UL> 144*0ef31e1fSMike Welles 145*0ef31e1fSMike WellesThe handle returned by <TT>TIFFOpen</TT> is <I>opaque</I>, that is 146*0ef31e1fSMike Wellesthe application is not permitted to know about its contents. 147*0ef31e1fSMike WellesAll subsequent library calls for this file must pass the handle 148*0ef31e1fSMike Wellesas an argument. 149*0ef31e1fSMike Welles 150*0ef31e1fSMike Welles<P> 151*0ef31e1fSMike WellesTo create or overwrite a TIFF image the file is also opened, but with 152*0ef31e1fSMike Wellesa <TT>"w"</TT> argument: 153*0ef31e1fSMike Welles 154*0ef31e1fSMike Welles<UL><LISTING> 155*0ef31e1fSMike Welles#include "tiffio.h" 156*0ef31e1fSMike Wellesmain() 157*0ef31e1fSMike Welles{ 158*0ef31e1fSMike Welles TIFF* tif = TIFFOpen("foo.tif", "w"); 159*0ef31e1fSMike Welles ... do stuff ... 160*0ef31e1fSMike Welles TIFFClose(tif); 161*0ef31e1fSMike Welles} 162*0ef31e1fSMike Welles</LISTING></UL> 163*0ef31e1fSMike Welles 164*0ef31e1fSMike WellesIf the file already exists it is first truncated to zero length. 165*0ef31e1fSMike Welles 166*0ef31e1fSMike Welles<P> 167*0ef31e1fSMike Welles<IMG SRC=images/warning.gif ALIGN=left HSPACE=6> 168*0ef31e1fSMike Welles<EM>Note that unlike the stdio library TIFF image files may not be 169*0ef31e1fSMike Wellesopened for both reading and writing; 170*0ef31e1fSMike Wellesthere is no support for altering the contents of a TIFF file. 171*0ef31e1fSMike Welles</EM> 172*0ef31e1fSMike Welles 173*0ef31e1fSMike Welles<P> 174*0ef31e1fSMike Welles<TT>libtiff</TT> buffers much information associated with writing a 175*0ef31e1fSMike Wellesvalid TIFF image. Consequently, when writing a TIFF image it is necessary 176*0ef31e1fSMike Wellesto always call <TT>TIFFClose</TT> or <TT>TIFFFlush</TT> to flush any 177*0ef31e1fSMike Wellesbuffered information to a file. Note that if you call <TT>TIFFClose</TT> 178*0ef31e1fSMike Wellesyou do not need to call <TT>TIFFFlush</TT>. 179*0ef31e1fSMike Welles 180*0ef31e1fSMike Welles<A NAME="Dirs"><P><HR WIDTH=65% ALIGN=right><H3>TIFF Directories</H3></A> 181*0ef31e1fSMike Welles 182*0ef31e1fSMike WellesTIFF supports the storage of multiple images in a single file. 183*0ef31e1fSMike WellesEach image has an associated data structure termed a <I>directory</I> 184*0ef31e1fSMike Wellesthat houses all the information about the format and content of the 185*0ef31e1fSMike Wellesimage data. 186*0ef31e1fSMike WellesImages in a file are usually related but they do not need to be; it 187*0ef31e1fSMike Wellesis perfectly alright to store a color image together with a black and 188*0ef31e1fSMike Welleswhite image. 189*0ef31e1fSMike WellesNote however that while images may be related their directories are 190*0ef31e1fSMike Wellesnot. 191*0ef31e1fSMike WellesThat is, each directory stands on its own; their is no need to read 192*0ef31e1fSMike Wellesan unrelated directory in order to properly interpret the contents 193*0ef31e1fSMike Wellesof an image. 194*0ef31e1fSMike Welles 195*0ef31e1fSMike Welles<P> 196*0ef31e1fSMike Welles<TT>libtiff</TT> provides several routines for reading and writing 197*0ef31e1fSMike Wellesdirectories. In normal use there is no need to explicitly 198*0ef31e1fSMike Wellesread or write a directory: the library automatically reads the first 199*0ef31e1fSMike Wellesdirectory in a file when opened for reading, and directory information 200*0ef31e1fSMike Wellesto be written is automatically accumulated and written when writing 201*0ef31e1fSMike Welles(assuming <TT>TIFFClose</TT> or <TT>TIFFFlush</TT> are called). 202*0ef31e1fSMike Welles 203*0ef31e1fSMike Welles<P> 204*0ef31e1fSMike WellesFor a file open for reading the <TT>TIFFSetDirectory</TT> routine can 205*0ef31e1fSMike Wellesbe used to select an arbitrary directory; directories are referenced by 206*0ef31e1fSMike Wellesnumber with the numbering starting at 0. Otherwise the 207*0ef31e1fSMike Welles<TT>TIFFReadDirectory</TT> and <TT>TIFFWriteDirectory</TT> routines can 208*0ef31e1fSMike Wellesbe used for sequential access to directories. 209*0ef31e1fSMike WellesFor example, to count the number of directories in a file the following 210*0ef31e1fSMike Wellescode might be used: 211*0ef31e1fSMike Welles 212*0ef31e1fSMike Welles<UL><LISTING> 213*0ef31e1fSMike Welles#include "tiffio.h" 214*0ef31e1fSMike Wellesmain(int argc, char* argv[]) 215*0ef31e1fSMike Welles{ 216*0ef31e1fSMike Welles TIFF* tif = TIFFOpen(argv[1], "r"); 217*0ef31e1fSMike Welles if (tif) { 218*0ef31e1fSMike Welles int dircount = 0; 219*0ef31e1fSMike Welles do { 220*0ef31e1fSMike Welles dircount++; 221*0ef31e1fSMike Welles } while (TIFFReadDirectory(tif)); 222*0ef31e1fSMike Welles printf("%d directories in %s\n", dircount, argv[1]); 223*0ef31e1fSMike Welles TIFFClose(tif); 224*0ef31e1fSMike Welles } 225*0ef31e1fSMike Welles exit(0); 226*0ef31e1fSMike Welles} 227*0ef31e1fSMike Welles</LISTING></UL> 228*0ef31e1fSMike Welles 229*0ef31e1fSMike Welles<P> 230*0ef31e1fSMike WellesFinally, note that there are several routines for querying the 231*0ef31e1fSMike Wellesdirectory status of an open file: 232*0ef31e1fSMike Welles<TT>TIFFCurrentDirectory</TT> returns the index of the current 233*0ef31e1fSMike Wellesdirectory and 234*0ef31e1fSMike Welles<TT>TIFFLastDirectory</TT> returns an indication of whether the 235*0ef31e1fSMike Wellescurrent directory is the last directory in a file. 236*0ef31e1fSMike WellesThere is also a routine, <TT>TIFFPrintDirectory</TT>, that can 237*0ef31e1fSMike Wellesbe called to print a formatted description of the contents of 238*0ef31e1fSMike Wellesthe current directory; consult the manual page for complete details. 239*0ef31e1fSMike Welles 240*0ef31e1fSMike Welles<A NAME="Tags"><P><HR WIDTH=65% ALIGN=right><H3>TIFF Tags</H3></A> 241*0ef31e1fSMike Welles 242*0ef31e1fSMike WellesImage-related information such as the image width and height, number 243*0ef31e1fSMike Wellesof samples, orientation, colorimetric information, etc. 244*0ef31e1fSMike Wellesare stored in each image 245*0ef31e1fSMike Wellesdirectory in <I>fields</I> or <I>tags</I>. 246*0ef31e1fSMike WellesTags are identified by a number that is usually a value registered 247*0ef31e1fSMike Welleswith the Aldus (now Adobe) Corporation. 248*0ef31e1fSMike WellesBeware however that some vendors write 249*0ef31e1fSMike WellesTIFF images with tags that are unregistered; in this case interpreting 250*0ef31e1fSMike Wellestheir contents is usually a waste of time. 251*0ef31e1fSMike Welles 252*0ef31e1fSMike Welles<P> 253*0ef31e1fSMike Welles<TT>libtiff</TT> reads the contents of a directory all at once 254*0ef31e1fSMike Wellesand converts the on-disk information to an appropriate in-memory 255*0ef31e1fSMike Wellesform. While the TIFF specification permits an arbitrary set of 256*0ef31e1fSMike Wellestags to be defined and used in a file, the library only understands 257*0ef31e1fSMike Wellesa limited set of tags. 258*0ef31e1fSMike WellesAny unknown tags that are encountered in a file are ignored. 259*0ef31e1fSMike WellesThere is a mechanism to extend the set of tags the library handles 260*0ef31e1fSMike Welleswithout modifying the library itself; 261*0ef31e1fSMike Wellesthis is described <A HREF=../contrib/tags/README>elsewhere</A>. 262*0ef31e1fSMike Welles 263*0ef31e1fSMike Welles<P> 264*0ef31e1fSMike Welles<TT>libtiff</TT> provides two interfaces for getting and setting tag 265*0ef31e1fSMike Wellesvalues: <TT>TIFFGetField</TT> and <TT>TIFFSetField</TT>. 266*0ef31e1fSMike WellesThese routines use a variable argument list-style interface to pass 267*0ef31e1fSMike Wellesparameters of different type through a single function interface. 268*0ef31e1fSMike WellesThe <I>get interface</I> takes one or more pointers to memory locations 269*0ef31e1fSMike Welleswhere the tag values are to be returned and also returns one or 270*0ef31e1fSMike Welleszero according to whether the requested tag is defined in the directory. 271*0ef31e1fSMike WellesThe <I>set interface</I> takes the tag values either by-reference or 272*0ef31e1fSMike Wellesby-value. 273*0ef31e1fSMike WellesThe TIFF specification defines 274*0ef31e1fSMike Welles<I>default values</I> for some tags. 275*0ef31e1fSMike WellesTo get the value of a tag, or its default value if it is undefined, 276*0ef31e1fSMike Wellesthe <TT>TIFFGetFieldDefaulted</TT> interface may be used. 277*0ef31e1fSMike Welles 278*0ef31e1fSMike Welles<P> 279*0ef31e1fSMike WellesThe manual pages for the tag get and set routines specifiy the exact data types 280*0ef31e1fSMike Wellesand calling conventions required for each tag supported by the library. 281*0ef31e1fSMike Welles 282*0ef31e1fSMike Welles<A NAME="Compression"><P><HR WIDTH=65% ALIGN=right><H3>TIFF Compression Schemes</H3></A> 283*0ef31e1fSMike Welles 284*0ef31e1fSMike Welles<TT>libtiff</TT> includes support for a wide variety of 285*0ef31e1fSMike Wellesdata compression schemes. 286*0ef31e1fSMike WellesIn normal operation a compression scheme is automatically used when 287*0ef31e1fSMike Wellesthe TIFF <TT>Compression</TT> tag is set, either by opening a file 288*0ef31e1fSMike Wellesfor reading, or by setting the tag when writing. 289*0ef31e1fSMike Welles 290*0ef31e1fSMike Welles<P> 291*0ef31e1fSMike WellesCompression schemes are implemented by software modules termed <I>codecs</I> 292*0ef31e1fSMike Wellesthat implement decoder and encoder routines that hook into the 293*0ef31e1fSMike Wellescore library i/o support. 294*0ef31e1fSMike WellesCodecs other than those bundled with the library can be registered 295*0ef31e1fSMike Wellesfor use with the <TT>TIFFRegisterCODEC</TT> routine. 296*0ef31e1fSMike WellesThis interface can also be used to override the core-library 297*0ef31e1fSMike Wellesimplementation for a compression scheme. 298*0ef31e1fSMike Welles 299*0ef31e1fSMike Welles<A NAME="ByteOrder"><P><HR WIDTH=65% ALIGN=right><H3>Byte Order</H3></A> 300*0ef31e1fSMike Welles 301*0ef31e1fSMike WellesThe TIFF specification says, and has always said, that 302*0ef31e1fSMike Welles<EM>a correct TIFF 303*0ef31e1fSMike Wellesreader must handle images in big-endian and little-endian byte order</EM>. 304*0ef31e1fSMike Welles<TT>libtiff</TT> conforms in this respect. 305*0ef31e1fSMike WellesConsequently there is no means to force a specific 306*0ef31e1fSMike Wellesbyte order for the data written to a TIFF image file (data is 307*0ef31e1fSMike Welleswritten in the native order of the host CPU unless appending to 308*0ef31e1fSMike Wellesan existing file, in which case it is written in the byte order 309*0ef31e1fSMike Wellesspecified in the file). 310*0ef31e1fSMike Welles 311*0ef31e1fSMike Welles 312*0ef31e1fSMike Welles<A NAME="DataPlacement"><P><HR WIDTH=65% ALIGN=right><H3>Data Placement</H3></A> 313*0ef31e1fSMike Welles 314*0ef31e1fSMike WellesThe TIFF specification requires that all information except an 315*0ef31e1fSMike Welles8-byte header can be placed anywhere in a file. 316*0ef31e1fSMike WellesIn particular, it is perfectly legitimate for directory information 317*0ef31e1fSMike Wellesto be written after the image data itself. 318*0ef31e1fSMike WellesConsequently TIFF is inherently not suitable for passing through a 319*0ef31e1fSMike Wellesstream-oriented mechanism such as UNIX pipes. 320*0ef31e1fSMike WellesSoftware that require that data be organized in a file in a particular 321*0ef31e1fSMike Wellesorder (e.g. directory information before image data) does not 322*0ef31e1fSMike Wellescorrectly support TIFF. 323*0ef31e1fSMike Welles<TT>libtiff</TT> provides no mechanism for controlling the placement 324*0ef31e1fSMike Wellesof data in a file; image data is typically written before directory 325*0ef31e1fSMike Wellesinformation. 326*0ef31e1fSMike Welles 327*0ef31e1fSMike Welles<A NAME="TIFFRGBAImage"><P><HR WIDTH=65% ALIGN=right><H3>TIFFRGBAImage Support</H3></A> 328*0ef31e1fSMike Welles 329*0ef31e1fSMike Welles<TT>libtiff</TT> provides a high-level interface for reading image 330*0ef31e1fSMike Wellesdata from a TIFF file. This interface handles the details of 331*0ef31e1fSMike Wellesdata organization and format for a wide variety of TIFF files; 332*0ef31e1fSMike Wellesat least the large majority of those files that one would normally 333*0ef31e1fSMike Wellesencounter. Image data is, by default, returned as ABGR 334*0ef31e1fSMike Wellespixels packed into 32-bit words (8 bits per sample). Rectangular 335*0ef31e1fSMike Wellesrasters can be read or data can be intercepted at an intermediate 336*0ef31e1fSMike Welleslevel and packed into memory in a format more suitable to the 337*0ef31e1fSMike Wellesapplication. 338*0ef31e1fSMike WellesThe library handles all the details of the format of data stored on 339*0ef31e1fSMike Wellesdisk and, in most cases, if any colorspace conversions are required: 340*0ef31e1fSMike Wellesbilevel to RGB, greyscale to RGB, CMYK to RGB, YCbCr to RGB, 16-bit 341*0ef31e1fSMike Wellessamples to 8-bit samples, associated/unassociated alpha, etc. 342*0ef31e1fSMike Welles 343*0ef31e1fSMike Welles<P> 344*0ef31e1fSMike WellesThere are two ways to read image data using this interface. If 345*0ef31e1fSMike Wellesall the data is to be stored in memory and manipulated at once, 346*0ef31e1fSMike Wellesthen the routine <TT>TIFFReadRGBAImage</TT> can be used: 347*0ef31e1fSMike Welles 348*0ef31e1fSMike Welles<UL><LISTING> 349*0ef31e1fSMike Welles#include "tiffio.h" 350*0ef31e1fSMike Wellesmain(int argc, char* argv[]) 351*0ef31e1fSMike Welles{ 352*0ef31e1fSMike Welles TIFF* tif = TIFFOpen(argv[1], "r"); 353*0ef31e1fSMike Welles if (tif) { 354*0ef31e1fSMike Welles uint32 w, h; 355*0ef31e1fSMike Welles size_t npixels; 356*0ef31e1fSMike Welles uint32* raster; 357*0ef31e1fSMike Welles 358*0ef31e1fSMike Welles TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); 359*0ef31e1fSMike Welles TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); 360*0ef31e1fSMike Welles npixels = w * h; 361*0ef31e1fSMike Welles raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); 362*0ef31e1fSMike Welles if (raster != NULL) { 363*0ef31e1fSMike Welles if (TIFFReadRGBAImage(tif, w, h, raster, 0)) { 364*0ef31e1fSMike Welles ...process raster data... 365*0ef31e1fSMike Welles } 366*0ef31e1fSMike Welles _TIFFfree(raster); 367*0ef31e1fSMike Welles } 368*0ef31e1fSMike Welles TIFFClose(tif); 369*0ef31e1fSMike Welles } 370*0ef31e1fSMike Welles exit(0); 371*0ef31e1fSMike Welles} 372*0ef31e1fSMike Welles</LISTING></UL> 373*0ef31e1fSMike Welles 374*0ef31e1fSMike WellesNote above that <TT>_TIFFmalloc</TT> is used to allocate memory for 375*0ef31e1fSMike Wellesthe raster passed to <TT>TIFFReadRGBAImage</TT>; this is important 376*0ef31e1fSMike Wellesto insure the ``appropriate type of memory'' is passed on machines 377*0ef31e1fSMike Welleswith segmented architectures. 378*0ef31e1fSMike Welles 379*0ef31e1fSMike Welles<P> 380*0ef31e1fSMike WellesAlternatively, <TT>TIFFReadRGBAImage</TT> can be replaced with a 381*0ef31e1fSMike Wellesmore low-level interface that permits an application to have more 382*0ef31e1fSMike Wellescontrol over this reading procedure. The equivalent to the above 383*0ef31e1fSMike Wellesis: 384*0ef31e1fSMike Welles 385*0ef31e1fSMike Welles<UL><LISTING> 386*0ef31e1fSMike Welles#include "tiffio.h" 387*0ef31e1fSMike Wellesmain(int argc, char* argv[]) 388*0ef31e1fSMike Welles{ 389*0ef31e1fSMike Welles TIFF* tif = TIFFOpen(argv[1], "r"); 390*0ef31e1fSMike Welles if (tif) { 391*0ef31e1fSMike Welles TIFFRGBAImage img; 392*0ef31e1fSMike Welles char emsg[1024]; 393*0ef31e1fSMike Welles 394*0ef31e1fSMike Welles if (TIFFRGBAImageBegin(&img, tif, 0, emsg)) { 395*0ef31e1fSMike Welles size_t npixels; 396*0ef31e1fSMike Welles uint32* raster; 397*0ef31e1fSMike Welles 398*0ef31e1fSMike Welles npixels = img.width * img.height; 399*0ef31e1fSMike Welles raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); 400*0ef31e1fSMike Welles if (raster != NULL) { 401*0ef31e1fSMike Welles if (TIFFRGBAImageGet(&img, raster, img.width, img.width)) { 402*0ef31e1fSMike Welles ...process raster data... 403*0ef31e1fSMike Welles } 404*0ef31e1fSMike Welles _TIFFfree(raster); 405*0ef31e1fSMike Welles } 406*0ef31e1fSMike Welles TIFFRGBAImageEnd(&img); 407*0ef31e1fSMike Welles } else 408*0ef31e1fSMike Welles TIFFError(argv[1], emsg); 409*0ef31e1fSMike Welles TIFFClose(tif); 410*0ef31e1fSMike Welles } 411*0ef31e1fSMike Welles exit(0); 412*0ef31e1fSMike Welles} 413*0ef31e1fSMike Welles</LISTING></UL> 414*0ef31e1fSMike Welles 415*0ef31e1fSMike WellesHowever this usage does not take advantage of the more fine-grained 416*0ef31e1fSMike Wellescontrol that's possible. That is, by using this interface it is 417*0ef31e1fSMike Wellespossible to: 418*0ef31e1fSMike Welles 419*0ef31e1fSMike Welles<UL> 420*0ef31e1fSMike Welles<LI>repeatedly fetch (and manipulate) an image without opening 421*0ef31e1fSMike Welles and closing the file 422*0ef31e1fSMike Welles<LI>interpose a method for packing raster pixel data according to 423*0ef31e1fSMike Welles application-specific needs (or write the data at all) 424*0ef31e1fSMike Welles<LI>interpose methods that handle TIFF formats that are not already 425*0ef31e1fSMike Welles handled by the core library 426*0ef31e1fSMike Welles</UL> 427*0ef31e1fSMike Welles 428*0ef31e1fSMike WellesThe first item means that, for example, image viewers that want to 429*0ef31e1fSMike Welleshandle multiple files can cache decoding information in order to 430*0ef31e1fSMike Wellesspeedup the work required to display a TIFF image. 431*0ef31e1fSMike Welles 432*0ef31e1fSMike Welles<P> 433*0ef31e1fSMike WellesThe second item is the main reason for this interface. By interposing 434*0ef31e1fSMike Wellesa ``put method'' (the routine that is called to pack pixel data in 435*0ef31e1fSMike Wellesthe raster) it is possible share the core logic that understands how 436*0ef31e1fSMike Wellesto deal with TIFF while packing the resultant pixels in a format that 437*0ef31e1fSMike Wellesis optimized for the application. This alternate format might be very 438*0ef31e1fSMike Wellesdifferent than the 8-bit per sample ABGR format the library writes by 439*0ef31e1fSMike Wellesdefault. For example, if the application is going to display the image 440*0ef31e1fSMike Welleson an 8-bit colormap display the put routine might take the data and 441*0ef31e1fSMike Wellesconvert it on-the-fly to the best colormap indices for display. 442*0ef31e1fSMike Welles 443*0ef31e1fSMike Welles<P> 444*0ef31e1fSMike WellesThe last item permits an application to extend the library 445*0ef31e1fSMike Welleswithout modifying the core code. 446*0ef31e1fSMike WellesBy overriding the code provided an application might add support 447*0ef31e1fSMike Wellesfor some esoteric flavor of TIFF that it needs, or it might 448*0ef31e1fSMike Wellessubstitute a packing routine that is able to do optimizations 449*0ef31e1fSMike Wellesusing application/environment-specific information. 450*0ef31e1fSMike Welles 451*0ef31e1fSMike Welles<P> 452*0ef31e1fSMike WellesThe TIFF image viewer found in <B>tools/sgigt.c</B> is an example 453*0ef31e1fSMike Wellesof an application that makes use of the <TT>TIFFRGBAImage</TT> 454*0ef31e1fSMike Wellessupport. 455*0ef31e1fSMike Welles 456*0ef31e1fSMike Welles<A NAME="Scanlines"><P><HR WIDTH=65% ALIGN=right><H3>Scanline-based Image I/O</H3></A> 457*0ef31e1fSMike Welles 458*0ef31e1fSMike WellesThe simplest interface provided by <TT>libtiff</TT> is a 459*0ef31e1fSMike Wellesscanline-oriented interface that can be used to read TIFF 460*0ef31e1fSMike Wellesimages that have their image data organized in strips 461*0ef31e1fSMike Welles(trying to use this interface to read data written in tiles 462*0ef31e1fSMike Welleswill produce errors.) 463*0ef31e1fSMike WellesA scanline is a one pixel high row of image data whose width 464*0ef31e1fSMike Wellesis the width of the image. 465*0ef31e1fSMike WellesData is returned packed if the image data is stored with samples 466*0ef31e1fSMike Wellespacked together, or as arrays of separate samples if the data 467*0ef31e1fSMike Wellesis stored with samples separated. 468*0ef31e1fSMike WellesThe major limitation of the scanline-oriented interface, other 469*0ef31e1fSMike Wellesthan the need to first identify an existing file as having a 470*0ef31e1fSMike Wellessuitable organization, is that random access to individual 471*0ef31e1fSMike Wellesscanlines can only be provided when data is not stored in a 472*0ef31e1fSMike Wellescompressed format, or when the number of rows in a strip 473*0ef31e1fSMike Wellesof image data is set to one (<TT>RowsPerStrip</TT> is one). 474*0ef31e1fSMike Welles 475*0ef31e1fSMike Welles<P> 476*0ef31e1fSMike WellesTwo routines are provided for scanline-based i/o: 477*0ef31e1fSMike Welles<TT>TIFFReadScanline</TT> 478*0ef31e1fSMike Wellesand 479*0ef31e1fSMike Welles<TT>TIFFWriteScanline</TT>. 480*0ef31e1fSMike WellesFor example, to read the contents of a file that 481*0ef31e1fSMike Wellesis assumed to be organized in strips, the following might be used: 482*0ef31e1fSMike Welles 483*0ef31e1fSMike Welles<UL><LISTING> 484*0ef31e1fSMike Welles#include "tiffio.h" 485*0ef31e1fSMike Wellesmain() 486*0ef31e1fSMike Welles{ 487*0ef31e1fSMike Welles TIFF* tif = TIFFOpen("myfile.tif", "r"); 488*0ef31e1fSMike Welles if (tif) { 489*0ef31e1fSMike Welles uint32 imagelength; 490*0ef31e1fSMike Welles tdata_t buf; 491*0ef31e1fSMike Welles uint32 row; 492*0ef31e1fSMike Welles 493*0ef31e1fSMike Welles TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength); 494*0ef31e1fSMike Welles buf = _TIFFmalloc(TIFFScanlineSize(tif)); 495*0ef31e1fSMike Welles for (row = 0; row < imagelength; row++) 496*0ef31e1fSMike Welles TIFFReadScanline(tif, buf, row); 497*0ef31e1fSMike Welles _TIFFfree(buf); 498*0ef31e1fSMike Welles TIFFClose(tif); 499*0ef31e1fSMike Welles } 500*0ef31e1fSMike Welles} 501*0ef31e1fSMike Welles</LISTING></UL> 502*0ef31e1fSMike Welles 503*0ef31e1fSMike Welles<TT>TIFFScanlineSize</TT> returns the number of bytes in 504*0ef31e1fSMike Wellesa decoded scanline, as returned by <TT>TIFFReadScanline</TT>. 505*0ef31e1fSMike WellesNote however that if the file had been create with samples 506*0ef31e1fSMike Welleswritten in separate planes, then the above code would only 507*0ef31e1fSMike Wellesread data that contained the first sample of each pixel; 508*0ef31e1fSMike Wellesto handle either case one might use the following instead: 509*0ef31e1fSMike Welles 510*0ef31e1fSMike Welles<UL><LISTING> 511*0ef31e1fSMike Welles#include "tiffio.h" 512*0ef31e1fSMike Wellesmain() 513*0ef31e1fSMike Welles{ 514*0ef31e1fSMike Welles TIFF* tif = TIFFOpen("myfile.tif", "r"); 515*0ef31e1fSMike Welles if (tif) { 516*0ef31e1fSMike Welles uint32 imagelength; 517*0ef31e1fSMike Welles tdata_t buf; 518*0ef31e1fSMike Welles uint32 row; 519*0ef31e1fSMike Welles 520*0ef31e1fSMike Welles TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength); 521*0ef31e1fSMike Welles TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &config); 522*0ef31e1fSMike Welles buf = _TIFFmalloc(TIFFScanlineSize(tif)); 523*0ef31e1fSMike Welles if (config == PLANARCONFIG_CONTIG) { 524*0ef31e1fSMike Welles for (row = 0; row < imagelength; row++) 525*0ef31e1fSMike Welles TIFFReadScanline(tif, buf, row); 526*0ef31e1fSMike Welles } else if (config == PLANARCONFIG_SEPARATE) { 527*0ef31e1fSMike Welles uint16 s, nsamples; 528*0ef31e1fSMike Welles 529*0ef31e1fSMike Welles TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &nsamples); 530*0ef31e1fSMike Welles for (s = 0; s < nsamples; s++) 531*0ef31e1fSMike Welles for (row = 0; row < imagelength; row++) 532*0ef31e1fSMike Welles TIFFReadScanline(tif, buf, row, s); 533*0ef31e1fSMike Welles } 534*0ef31e1fSMike Welles _TIFFfree(buf); 535*0ef31e1fSMike Welles TIFFClose(tif); 536*0ef31e1fSMike Welles } 537*0ef31e1fSMike Welles} 538*0ef31e1fSMike Welles</LISTING></UL> 539*0ef31e1fSMike Welles 540*0ef31e1fSMike WellesBeware however that if the following code were used instead to 541*0ef31e1fSMike Wellesread data in the case <TT>PLANARCONFIG_SEPARATE</TT>, 542*0ef31e1fSMike Welles 543*0ef31e1fSMike Welles<UL><LISTING> 544*0ef31e1fSMike Welles for (row = 0; row < imagelength; row++) 545*0ef31e1fSMike Welles for (s = 0; s < nsamples; s++) 546*0ef31e1fSMike Welles TIFFReadScanline(tif, buf, row, s); 547*0ef31e1fSMike Welles</LISTING></UL> 548*0ef31e1fSMike Welles 549*0ef31e1fSMike Wellesthen problems would arise if <TT>RowsPerStrip</TT> was not one 550*0ef31e1fSMike Wellesbecause the order in which scanlines are requested would require 551*0ef31e1fSMike Wellesrandom access to data within strips (something that is not supported 552*0ef31e1fSMike Wellesby the library when strips are compressed). 553*0ef31e1fSMike Welles 554*0ef31e1fSMike Welles<A NAME="Strips"><P><HR WIDTH=65% ALIGN=right><H3>Strip-oriented Image I/O</H3></A> 555*0ef31e1fSMike Welles 556*0ef31e1fSMike WellesThe strip-oriented interfaces provided by the library provide 557*0ef31e1fSMike Wellesaccess to entire strips of data. Unlike the scanline-oriented 558*0ef31e1fSMike Wellescalls, data can be read or written compressed or uncompressed. 559*0ef31e1fSMike WellesAccessing data at a strip (or tile) level is often desirable 560*0ef31e1fSMike Wellesbecause there are no complications with regard to random access 561*0ef31e1fSMike Wellesto data within strips. 562*0ef31e1fSMike Welles 563*0ef31e1fSMike Welles<P> 564*0ef31e1fSMike WellesA simple example of reading an image by strips is: 565*0ef31e1fSMike Welles 566*0ef31e1fSMike Welles<UL><LISTING> 567*0ef31e1fSMike Welles#include "tiffio.h" 568*0ef31e1fSMike Wellesmain() 569*0ef31e1fSMike Welles{ 570*0ef31e1fSMike Welles TIFF* tif = TIFFOpen("myfile.tif", "r"); 571*0ef31e1fSMike Welles if (tif) { 572*0ef31e1fSMike Welles tdata_t buf; 573*0ef31e1fSMike Welles tstrip_t strip; 574*0ef31e1fSMike Welles 575*0ef31e1fSMike Welles buf = _TIFFmalloc(TIFFStripSize(tif)); 576*0ef31e1fSMike Welles for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) 577*0ef31e1fSMike Welles TIFFReadEncodedStrip(tif, strip, buf, (tsize_t) -1); 578*0ef31e1fSMike Welles _TIFFfree(buf); 579*0ef31e1fSMike Welles TIFFClose(tif); 580*0ef31e1fSMike Welles } 581*0ef31e1fSMike Welles} 582*0ef31e1fSMike Welles</LISTING></UL> 583*0ef31e1fSMike Welles 584*0ef31e1fSMike WellesNotice how a strip size of <TT>-1</TT> is used; <TT>TIFFReadEncodedStrip</TT> 585*0ef31e1fSMike Welleswill calculate the appropriate size in this case. 586*0ef31e1fSMike Welles 587*0ef31e1fSMike Welles<P> 588*0ef31e1fSMike WellesThe above code reads strips in the order in which the 589*0ef31e1fSMike Wellesdata is physically stored in the file. If multiple samples 590*0ef31e1fSMike Wellesare present and data is stored with <TT>PLANARCONFIG_SEPARATE</TT> 591*0ef31e1fSMike Wellesthen all the strips of data holding the first sample will be 592*0ef31e1fSMike Wellesread, followed by strips for the second sample, etc. 593*0ef31e1fSMike Welles 594*0ef31e1fSMike Welles<P> 595*0ef31e1fSMike WellesFinally, note that the last strip of data in an image may have fewer 596*0ef31e1fSMike Wellesrows in it than specified by the <TT>RowsPerStrip</TT> tag. A 597*0ef31e1fSMike Wellesreader should not assume that each decoded strip contains a full 598*0ef31e1fSMike Wellesset of rows in it. 599*0ef31e1fSMike Welles 600*0ef31e1fSMike Welles<P> 601*0ef31e1fSMike WellesThe following is an example of how to read raw strips of data from 602*0ef31e1fSMike Wellesa file: 603*0ef31e1fSMike Welles 604*0ef31e1fSMike Welles<UL><LISTING> 605*0ef31e1fSMike Welles#include "tiffio.h" 606*0ef31e1fSMike Wellesmain() 607*0ef31e1fSMike Welles{ 608*0ef31e1fSMike Welles TIFF* tif = TIFFOpen("myfile.tif", "r"); 609*0ef31e1fSMike Welles if (tif) { 610*0ef31e1fSMike Welles tdata_t buf; 611*0ef31e1fSMike Welles tstrip_t strip; 612*0ef31e1fSMike Welles uint32* bc; 613*0ef31e1fSMike Welles uint32 stripsize; 614*0ef31e1fSMike Welles 615*0ef31e1fSMike Welles TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc); 616*0ef31e1fSMike Welles stripsize = bc[0]; 617*0ef31e1fSMike Welles buf = _TIFFmalloc(stripsize); 618*0ef31e1fSMike Welles for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) { 619*0ef31e1fSMike Welles if (bc[strip] > stripsize) { 620*0ef31e1fSMike Welles buf = _TIFFrealloc(buf, bc[strip]); 621*0ef31e1fSMike Welles stripsize = bc[strip]; 622*0ef31e1fSMike Welles } 623*0ef31e1fSMike Welles TIFFReadRawStrip(tif, strip, buf, bc[strip]); 624*0ef31e1fSMike Welles } 625*0ef31e1fSMike Welles _TIFFfree(buf); 626*0ef31e1fSMike Welles TIFFClose(tif); 627*0ef31e1fSMike Welles } 628*0ef31e1fSMike Welles} 629*0ef31e1fSMike Welles</LISTING></UL> 630*0ef31e1fSMike Welles 631*0ef31e1fSMike WellesAs above the strips are read in the order in which they are 632*0ef31e1fSMike Wellesphysically stored in the file; this may be different from the 633*0ef31e1fSMike Welleslogical ordering expected by an application. 634*0ef31e1fSMike Welles 635*0ef31e1fSMike Welles<A NAME="Tiles"><P><HR WIDTH=65% ALIGN=right><H3>Tile-oriented Image I/O</H3></A> 636*0ef31e1fSMike Welles 637*0ef31e1fSMike WellesTiles of data may be read and written in a manner similar to strips. 638*0ef31e1fSMike WellesWith this interface, an image is 639*0ef31e1fSMike Wellesbroken up into a set of rectangular areas that may have dimensions 640*0ef31e1fSMike Wellesless than the image width and height. All the tiles 641*0ef31e1fSMike Wellesin an image have the same size, and the tile width and length must each 642*0ef31e1fSMike Wellesbe a multiple of 16 pixels. Tiles are ordered left-to-right and 643*0ef31e1fSMike Wellestop-to-bottom in an image. As for scanlines, samples can be packed 644*0ef31e1fSMike Wellescontiguously or separately. When separated, all the tiles for a sample 645*0ef31e1fSMike Wellesare colocated in the file. That is, all the tiles for sample 0 appear 646*0ef31e1fSMike Wellesbefore the tiles for sample 1, etc. 647*0ef31e1fSMike Welles 648*0ef31e1fSMike Welles<P> 649*0ef31e1fSMike WellesTiles and strips may also be extended in a z dimension to form 650*0ef31e1fSMike Wellesvolumes. Data volumes are organized as "slices". That is, all the 651*0ef31e1fSMike Wellesdata for a slice is colocated. Volumes whose data is organized in 652*0ef31e1fSMike Wellestiles can also have a tile depth so that data can be organized in 653*0ef31e1fSMike Wellescubes. 654*0ef31e1fSMike Welles 655*0ef31e1fSMike Welles<P> 656*0ef31e1fSMike WellesThere are actually two interfaces for tiles. 657*0ef31e1fSMike WellesOne interface is similar to scanlines, to read a tiled image, 658*0ef31e1fSMike Wellescode of the following sort might be used: 659*0ef31e1fSMike Welles 660*0ef31e1fSMike Welles<UL><LISTING> 661*0ef31e1fSMike Wellesmain() 662*0ef31e1fSMike Welles{ 663*0ef31e1fSMike Welles TIFF* tif = TIFFOpen("myfile.tif", "r"); 664*0ef31e1fSMike Welles if (tif) { 665*0ef31e1fSMike Welles uint32 imageWidth, imageLength; 666*0ef31e1fSMike Welles uint32 tileWidth, tileLength; 667*0ef31e1fSMike Welles uint32 x, y; 668*0ef31e1fSMike Welles tdata_t buf; 669*0ef31e1fSMike Welles 670*0ef31e1fSMike Welles TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth); 671*0ef31e1fSMike Welles TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength); 672*0ef31e1fSMike Welles TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tileWidth); 673*0ef31e1fSMike Welles TIFFGetField(tif, TIFFTAG_TILELENGTH, &tileLength); 674*0ef31e1fSMike Welles buf = _TIFFmalloc(TIFFTileSize(tif)); 675*0ef31e1fSMike Welles for (y = 0; y < imageLength; y += tileLength) 676*0ef31e1fSMike Welles for (x = 0; x < imageWidth; x += tileWidth) 677*0ef31e1fSMike Welles TIFFReadTile(tif, buf, x, y, 0); 678*0ef31e1fSMike Welles _TIFFfree(buf); 679*0ef31e1fSMike Welles TIFFClose(tif); 680*0ef31e1fSMike Welles } 681*0ef31e1fSMike Welles} 682*0ef31e1fSMike Welles</LISTING></UL> 683*0ef31e1fSMike Welles 684*0ef31e1fSMike Welles(once again, we assume samples are packed contiguously.) 685*0ef31e1fSMike Welles 686*0ef31e1fSMike Welles<P> 687*0ef31e1fSMike WellesAlternatively a direct interface to the low-level data is provided 688*0ef31e1fSMike Wellesa la strips. Tiles can be read with 689*0ef31e1fSMike Welles<TT>TIFFReadEncodedTile</TT> or 690*0ef31e1fSMike Welles<TT>TIFFReadRawTile</TT>, 691*0ef31e1fSMike Wellesand written with 692*0ef31e1fSMike Welles<TT>TIFFWriteEncodedTile</TT> or 693*0ef31e1fSMike Welles<TT>TIFFWriteRawTile</TT>. 694*0ef31e1fSMike WellesFor example, to read all the tiles in an image: 695*0ef31e1fSMike Welles 696*0ef31e1fSMike Welles<UL><LISTING> 697*0ef31e1fSMike Welles#include "tiffio.h" 698*0ef31e1fSMike Wellesmain() 699*0ef31e1fSMike Welles{ 700*0ef31e1fSMike Welles TIFF* tif = TIFFOpen("myfile.tif", "r"); 701*0ef31e1fSMike Welles if (tif) { 702*0ef31e1fSMike Welles tdata_t buf; 703*0ef31e1fSMike Welles ttile_t tile; 704*0ef31e1fSMike Welles 705*0ef31e1fSMike Welles buf = _TIFFmalloc(TIFFTileSize(tif)); 706*0ef31e1fSMike Welles for (tile = 0; tile < TIFFNumberOfTiles(tif); tile++) 707*0ef31e1fSMike Welles TIFFReadEncodedTile(tif, tile, buf, (tsize_t) -1); 708*0ef31e1fSMike Welles _TIFFfree(buf); 709*0ef31e1fSMike Welles TIFFClose(tif); 710*0ef31e1fSMike Welles } 711*0ef31e1fSMike Welles} 712*0ef31e1fSMike Welles</LISTING></UL> 713*0ef31e1fSMike Welles 714*0ef31e1fSMike Welles 715*0ef31e1fSMike Welles 716*0ef31e1fSMike Welles<A NAME="Other"><P><HR WIDTH=65% ALIGN=right><H3>Other Stuff</H3></A> 717*0ef31e1fSMike Welles 718*0ef31e1fSMike Welles<P> 719*0ef31e1fSMike Welles<I>Some other stuff will almost certainly go here...</I> 720*0ef31e1fSMike Welles 721*0ef31e1fSMike Welles<P> 722*0ef31e1fSMike Welles<HR> 723*0ef31e1fSMike Welles 724*0ef31e1fSMike Welles<ADDRESS> 725*0ef31e1fSMike Welles<A HREF="sam.html">Sam Leffler</A> / <A HREF="mailto:[email protected]">[email protected]</A>. 726*0ef31e1fSMike WellesLast updated: $Date: 1999-07-27 21:50:27 $ 727*0ef31e1fSMike Welles</ADDRESS> 728*0ef31e1fSMike Welles 729*0ef31e1fSMike Welles</BODY> 730*0ef31e1fSMike Welles</HTML> 731