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