TIFF 6.0 Specification Coverage

The library is capable of dealing with images that are written to follow the 5.0 or 6.0 TIFF spec. There is also considerable support for some of the more esoteric portions of the 6.0 TIFF spec.

Core requirements Both "MM" and "II" byte orders are handled. Both packed and separated planar configuration of samples. Any number of samples per pixel (memory permitting). Any image width and height (memory permitting). Multiple subfiles can be read and written. Editing is not supported in that related subfiles (e.g. a reduced resolution version of an image) are not automatically updated.

Tags handled: ExtraSamples, ImageWidth, ImageLength, NewSubfileType, ResolutionUnit. Rowsperstrip, StripOffsets, StripByteCounts, XResolution, YResolution,

Tiled Images TileWidth, TileLength, TileOffsets, TileByteCounts
Image Colorimetry Information WhitePoint, PrimaryChromaticities, TransferFunction, ReferenceBlackWhite
Class B for bilevel images SamplesPerPixel = 1
BitsPerSample = 1
Compression = 1 (none), 2 (CCITT 1D), or 32773 (PackBits)
PhotometricInterpretation = 0 (Min-is-White), 1 (Min-is-Black)
Class G for grayscale images SamplesPerPixel = 1
BitsPerSample = 4, 8
Compression = 1 (none) 5 (LZW)
PhotometricInterpretation = 0 (Min-is-White), 1 (Min-is-Black)
Class P for palette color images SamplesPerPixel = 1
BitsPerSample = 1-8
Compression = 1 (none) 5 (LZW)
PhotometricInterpretation = 3 (Palette RGB)
ColorMap
Class R for RGB full color images SamplesPerPixel = 3
BitsPerSample = <8,8,8>
PlanarConfiguration = 1, 2
Compression = 1 (none) 5 (LZW)
PhotometricInterpretation = 2 (RGB)
Class F for facsimile (Class B tags plus...)
Compression = 3 (CCITT Group 3), 4 (CCITT Group 4)
FillOrder = 1 (MSB), 2 (LSB)
Group3Options = 1 (2d encoding), 4 (zero fill), 5 (2d+fill)
ImageWidth = 1728, 2048, 2482
NewSubFileType = 2
ResolutionUnit = 2 (Inch), 3 (Centimeter)
PageNumber, XResolution, YResolution, Software, BadFaxLines, CleanFaxData, ConsecutiveBadFaxLines, DateTime, DocumentName, ImageDescription, Orientation
Class S for separated images SamplesPerPixel = 4
PlanarConfiguration = 1, 2
Compression = 1 (none), 5 (LZW)
PhotometricInterpretation = 5 (Separated)
InkSet = 1 (CMYK)
DotRange, InkNames, DotRange, TargetPrinter
Class Y for YCbCr images SamplesPerPixel = 3
BitsPerSample = <8,8,8>
PlanarConfiguration = 1, 2
Compression = 1 (none), tionRowsPerStrip is one).

Two routines are provided for scanline-based i/o: TIFFReadScanline and TIFFWriteScanline. For example, to read the contents of a file that is assumed to be organized in strips, the following might be used:

    #include "tiffio.h" main() { TIFF* tif = TIFFOpen("myfile.tif", "r"); if (tif) { uint32 imagelength; tdata_t buf; uint32 row; TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength); buf = _TIFFmalloc(TIFFScanlineSize(tif)); for (row = 0; row < imagelength; row++) TIFFReadScanline(tif, buf, row); _TIFFfree(buf); TIFFClose(tif); } }
TIFFScanlineSize returns the number of bytes in a decoded scanline, as returned by TIFFReadScanline. Note however that if the file had been create with samples written in separate planes, then the above code would only read data that contained the first sample of each pixel; to handle either case one might use the following instead:
    #include "tiffio.h" main() { TIFF* tif = TIFFOpen("myfile.tif", "r"); if (tif) { uint32 imagelength; tdata_t buf; uint32 row; TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength); TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &config); buf = _TIFFmalloc(TIFFScanlineSize(tif)); if (config == PLANARCONFIG_CONTIG) { for (row = 0; row < imagelength; row++) TIFFReadScanline(tif, buf, row); } else if (config == PLANARCONFIG_SEPARATE) { uint16 s, nsamples; TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &nsamples); for (s = 0; s < nsamples; s++) for (row = 0; row < imagelength; row++) TIFFReadScanline(tif, buf, row, s); } _TIFFfree(buf); TIFFClose(tif); } }
Beware however that if the following code were used instead to read data in the case PLANARCONFIG_SEPARATE,
    for (row = 0; row < imagelength; row++) for (s = 0; s < nsamples; s++) TIFFReadScanline(tif, buf, row, s);
then problems would arise if RowsPerStrip was not one because the order in which scanlines are requested would require random access to data within strips (something that is not supported by the library when strips are compressed).


Strip-oriented Image I/O

The strip-oriented interfaces provided by the library provide access to entire strips of data. Unlike the scanline-oriented calls, data can be read or written compressed or uncompressed. Accessing data at a strip (or tile) level is often desirable because there are no complications with regard to random access to data within strips.

A simple example of reading an image by strips is:

    #include "tiffio.h" main() { TIFF* tif = TIFFOpen("myfile.tif", "r"); if (tif) { tdata_t buf; tstrip_t strip; buf = _TIFFmalloc(TIFFStripSize(tif)); for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) TIFFReadEncodedStrip(tif, strip, buf, (tsize_t) -1); _TIFFfree(buf); TIFFClose(tif); } }
Notice how a strip size of -1 is used; TIFFReadEncodedStrip will calculate the appropriate size in this case.

The above code reads strips in the order in which the data is physically stored in the file. If multiple samples are present and data is stored with PLANARCONFIG_SEPARATE then all the strips of data holding the first sample will be read, followed by strips for the second sample, etc.

Finally, note that the last strip of data in an image may have fewer rows in it than specified by the RowsPerStrip tag. A reader should not assume that each decoded strip contains a full set of rows in it.

The following is an example of how to read raw strips of data from a file:

    #include "tiffio.h" main() { TIFF* tif = TIFFOpen("myfile.tif", "r"); if (tif) { tdata_t buf; tstrip_t strip; uint32* bc; uint32 stripsize; TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc); stripsize = bc[0]; buf = _TIFFmalloc(stripsize); for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) { if (bc[strip] > stripsize) { buf = _TIFFrealloc(buf, bc[strip]); stripsize = bc[strip]; } TIFFReadRawStrip(tif, strip, buf, bc[strip]); } _TIFFfree(buf); TIFFClose(tif); } }
As above the strips are read in the order in which they are physically stored in the file; this may be different from the logical ordering expected by an application.


Tile-oriented Image I/O

Tiles of data may be read and written in a manner similar to strips. With this interface, an image is broken up into a set of rectangular areas that may have dimensions less than the image width and height. All the tiles in an image have the same size, and the tile width and length must each be a multiple of 16 pixels. Tiles are ordered left-to-right and top-to-bottom in an image. As for scanlines, samples can be packed contiguously or separately. When separated, all the tiles for a sample are colocated in the file. That is, all the tiles for sample 0 appear before the tiles for sample 1, etc.

Tiles and strips may also be extended in a z dimension to form volumes. Data volumes are organized as "slices". That is, all the data for a slice is colocated. Volumes whose data is organized in tiles can also have a tile depth so that data can be organized in cubes.

There are actually two interfaces for tiles. One interface is similar to scanlines, to read a tiled image, code of the following sort might be used:

    main() { TIFF* tif = TIFFOpen("myfile.tif", "r"); if (tif) { uint32 imageWidth, imageLength; uint32 tileWidth, tileLength; uint32 x, y; tdata_t buf; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength); TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tileWidth); TIFFGetField(tif, TIFFTAG_TILELENGTH, &tileLength); buf = _TIFFmalloc(TIFFTileSize(tif)); for (y = 0; y < imageLength; y += tileLength) for (x = 0; x < imageWidth; x += tileWidth) TIFFReadTile(tif, buf, x, y, 0); _TIFFfree(buf); TIFFClose(tif); } }
(once again, we assume samples are packed contiguously.)

Alternatively a direct interface to the low-level data is provided a la strips. Tiles can be read with TIFFReadEncodedTile or TIFFReadRawTile, and written with TIFFWriteEncodedTile or TIFFWriteRawTile. For example, to read all the tiles in an image:

    #include "tiffio.h" main() { TIFF* tif = TIFFOpen("myfile.tif", "r"); if (tif) { tdata_t buf; ttile_t tile; buf = _TIFFmalloc(TIFFTileSize(tif)); for (tile = 0; tile < TIFFNumberOfTiles(tif); tile++) TIFFReadEncodedTile(tif, tile, buf, (tsize_t) -1); _TIFFfree(buf); TIFFClose(tif); } }


Other Stuff

Some other stuff will almost certainly go here...


Last updated: $Date: 1999/08/13 19:30:57 $ ./usr/share/doc/libtiff3g/html/misc.html0100644000000000000000000000645307076735255017060 0ustar rootroot Acknowledgments and Other Issues

Acknowledgments and Other Issues

Silicon Graphics has seen fit to allow me to give this work away. It is free. There is no support or guarantee of any sort as to its operations, correctness, or whatever. If you do anything useful with all or parts of it you need to honor the copyright notices. I would also be interested in knowing about it and, hopefully, be acknowledged.

Acknowledgements

The LZW algorithm is derived from the compress program (the proper attribution is included in the source code). The Group 3 fax stuff originated as code from Jef Poskanzer, but has since been rewritten several times. The latest version uses an algorithm from Frank Cringle -- consult libtiff/mkg3states.c and libtiff/tif_fax3.h for further information. The JPEG support was written by Tom Lane and is dependent on the excellent work of Tom Lane and the Independent JPEG Group (IJG) who distribute their work under friendly licensing similar to this software. Many other people have by now helped with bug fixes and code; a few of the more persistent contributors have been:
    Bjorn P. Brox		Dan McCoy
    J.T. Conklin		Richard Minner
    Frank D. Cringle		Richard Mlynarik
    Soren Pingel Dalsgaard	Niles Ritter
    Steve Johnson		Karsten Spang
    Tom Lane
(my apology to anyone that was inadvertently not listed.)

Warning

It appears that Unisys is actively pursuing copyright control on the LZW compression algorithm. In particular, users of the LZW compression within the TIFF framework. For this reason the TIFF 6.0 spec states that LZW compression is not recommended. It is unclear at this time what compression algorithm will be used in place of it. I have no idea what this means to you or to this library. I make no warranty or guarantees with regard to the LZW support in this library.

Use and Copyright

Copyright (c) 1988-1997 Sam Leffler
Copyright (c) 1991-1997 Silicon Graphics, Inc.

Permission to use, copy, modify, distribute, and sell this software and 
its documentation for any purpose is hereby granted without fee, provided
that (i) the above copyright notices and this permission notice appear in
all copies of the software and related documentation, and (ii) the names of
Sam Leffler and Silicon Graphics may not be used in any advertising or
publicity relating to the software without the specific, prior written
permission of Sam Leffler and Silicon Graphics.

THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  

IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
OF THIS SOFTWARE.


Last updated: $Date: 1999/08/13 19:30:57 $