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