Appendix A. Stream TIFF Data Format
Prev |  | Next

## Appendix A. Stream TIFF Data Format

This appendix describes the Stream TIFF data format (STIFF), the primary interchange file format between printer filters and drivers, and `libstiff;`, a C application program interface (API) used to read and write Stream TIFF files. Stream TIFF is also used by `gscan` to store images in TIFF files and to scan to the screen (in conjunction with `vstiff`).

The following major topics are discussed:

- “Library Description”

- “Library Access”

- “Library Functions”

- “Printing-Specific STIFF”

- “Generic STIFF File Structure”

## Library Description

`libstiff` provides a C application program interface (API) to the reading and writing of Stream TIFF files. Stream TIFF (STIFF) is a subset of the Tag Image File Format (TIFF) Revision 6.0 originally developed by Aldus Corporation. TIFF is an extremely flexible format, well suited for monochrome and color bitmap images. The primary difference between TIFF and STIFF is that while a TIFF file may require file seeking during reading or writing, a STIFF file does not. This means that a STIFF file can be read and written to both files and non-seekable streams such as pipes and sockets. STIFF can be used by application developers to write TIFF 6.0-compliant files, and a STIFF file can be read by any TIFF reader that conforms to the TIFF Revision 6.0 specifications. However, `libstiff` cannot be used to read many standard TIFF files since STIFF is a subset of TIFF.

The functions provided by `libstiff` greatly simplify the reading and writing of TIFF-compatible files. Using the STIFF API, TIFF 6.0-compatible STIFF files can be read and written without the need to understand the structure of a TIFF file and without the need to explicitly specify TIFF tags.

## Library Access

There are two sets of `libstiff` functions. One set comprises the generic `libstiff` API. These functions are designated by an ST prefix and may be used to read and write generic STIFF files. To access these functions, an application must include the header file `stiff.h` located in the `/usr/include` directory. The second set of `libstiff` functions is tailored to reading and writing STIFF files that are to be passed between printing filters and drivers. These printing-related functions are designated by the prefix PST and are accessed through the header file `printstiff.h`, also located in `/usr/include`. If `printstiff.h` is used, the header `stiff.h` need not be specified. The generic and printing-specific functions may be freely intermixed within an application.

Programs that call `libstiff` functions must link with the `libstiff.a` library located in the directory`/usr/lib`. An example command line is shown below:

    cc -o myprog myprog.c -lstiff

## Library Functions

`libstiff` provides the generic functions listed in Table A-1.

Table A-1. STIFF Generic Functions

Task | Function Name | Description
--- | --- | ---
Stream Handling | STOpen() STClose() STSkipTo() | Opens a STIFF stream on the specified file descriptor Closes a STIFF stream opened by STOpen() Skips forward on a specified stream
Reading and Writing | STReadImageHeader() STWriteImageHeader() STRead() STWrite() | Reads the STIFF image header from the specified stream Writes the image header to the specified stream Reads the specified amount of image data from the stream Writes the specified amount of image data to the stream
TIFF Tag Support | STAddTag() STRemoveTag() STGetTag() STPrintTags() | Adds the specified tag to the TIFF tag list Removes the specified tag from the output TIFF tag list Searches the tag list for the specified TIFF tag Prints the current TIFF tag list
Execution Error Handling | STPerror() STErrorString() | Prints error messages to standard error Gets the error string for the specified error code

STIFF also provides the printing-specific functions listed in Table A-2.

Table A-2. STIFF Printing-Specific Functions

Function Name | Description
--- | ---
PSTReadImageHeader() | Reads the printing-specific STIFF image header from the stream
PSTWriteImageHeader() | Writes the printing-specific STIFF image header to the stream

### Example Usage

The sequence of operations for writing a STIFF stream is as follows:

1. Obtain a writable file descriptor. Note that this descriptor can be associated with a non-seekable stream.

2. Call `STOpen()` with the writable file descriptor and the flag ST_WRITE.

3. Fill in the STIFF image header (`STImageHeader()` or `PSTImageHeader()`).

4. Optionally, add any application-specific TIFF tags to the file using `STAddTag()`.

5. Call the image header write function `STWriteImageHeader()` or `PSTWriteImageHeader()`.

6. Write the image data using `STWrite()`.

7. Repeat steps 3 through 6 for each page of image data.

8. Close the STIFF file using `STClose()`.

9. Close the file descriptor.

The sequence of operations for reading a STIFF stream is as follows:

1. Obtain a readable file descriptor. Note that this descriptor can be associated with a non-seekable stream.

2. Call `STOpen()` with the readable file descriptor and the flag ST_READ.

3. Call the image header read function `STReadImageHeader()` or `PSTReadImageHeader()`.

4. Access the fields of the image header structure to determine the amount of image data to be read for this page.

5. Optionally, retrieve any application-specific TIFF tags from the file using `STGetTag()`.

6. Read the image data using `STRead()`.

7. Repeat steps 3 through 6 for each page of image data. The last page of image data is an empty page (that is, the amount of data equals zero). An STEEOF error occurs if an attempt is made to read past the end of the STIFF.

8. Close the STIFF stream using `STClose()`.

9. Close the file descriptor.

If an error condition is returned by a `libstiff` function, `STPerror()` can be used to print a diagnostic error message to the standard error, and `STErrorString()` can be used to obtain an appropriate error message for display to the user by other means.

## Printing-Specific STIFF

The printing-specific functions (PST) provided by `libstiff` read and write STIFF files as described above. The printing-specific aspect of these functions is found in the image header structure. `PSTImageHeader()`, the printing-specific image header, contains all fields of the `STImageHeader()` plus printing-specific information fields such as image resolution and halftoning method.

If a STIFF file is written using the generic functions and is read using the printing-specific functions, default values are used for the `PSTImageHeader()` fields not found in the STIFF. Similarly, a STIFF file written using the printing-specific functions can be read by the generic functions. In this case, the additional information in the stream can be ignored or obtained using the `STGetTag()` function.

Refer to the header file `/usr/include/printstiff.h` for additional information regarding printing-specific STIFF.

Printer driver developers should pay special attention to the command-line options string that is part of a PST image header. See the LaserJet example driver for an example of how to combine parsing the command-line and image-header driver options.

## Generic STIFF File Structure

While it is not necessary to understand the STIFF file structure to use `libstiff`, this explanation is provided for those who need to know. A Stream TIFF file is first and foremost a valid TIFF file. STIFF is derived from the TIFF 6.0 specifications available from Aldus Corporation (see below). The terms used below to describe a STIFF file (for example, IFD) are explained in the TIFF specifications and are not described here.

The primary restriction STIFF places on the TIFF structure is that all data must be read from or written to the file without the need to seek within the file. Specifically, within a STIFF file, these things must be true:

1. The bitmap image data must be in page-number order.

2. Data that does not fit in the value section of a tag must be located immediately after the IFD and must occur in the same order in which the tags are encountered. The exception to this is the image data itself, which must come last for each page.

3. Image data must immediately follow the IFD and any associated offset values.

4. A terminating, empty IFD is always added to the end of the STIFF file. This IFD guarantees that an IFD with 0000 in its “next IFD” field appears in the IFD chain. Note that this empty IFD is not encountered when following IFD pointers if the last “real” IFD is written with the last parameter set to 1. While the TIFF specification states that IFDs should not be empty, relaxing this restriction appears to have no impact on TIFF compatibility.

A generic STIFF file can be represented as shown in Figure A-1.

Figure A-1. Generic STIFF File Structure

The `libstiff` functions support only the Motorola® (MM) byte ordering. In addition to supporting TIFF class RGB data, `libstiff` supports the CMYK color image data type (PhotoMetricInterpretation = 5 and InkSet = 1) and four additional color image separation types: CMY, YMC, YMCK, and KCMY.

For these additional types, PhotoMetricInterpretation = 5, InkSet = 2, NumberOfInks = 3 or 4, and the InkNames tag is used to indicate the inks contained in each channel.

When reading an image header, `libstiff` parses the ink names for these additional types and sets the type field of the STImageHeader structure to the appropriate value defined in `stiff.h`. When writing an image header, `libstiff` writes the appropriate PhotoMetricInterpretation, InkSet, NumberOfInks, and InkNames tags based on the value of the type field of the STImageHeader structure.

The CMYK data format is a TIFF data format extension, as shown in Table A-3.

Table A-3. CMYK Data Format

Tag | Possible Values
--- | ---
BitsPerSample | (1,1,1,1) (4,4,4,4) (8,8,8,8)
PhotoMetricInterpretation | 5
SamplesPerPixel | 4
PlanarConfiguration | 1, 2
NumberOfInks | 4

The CMY data class is a subset of the CMYK class and differs from the CMYK class in a TIFF-compliant manner, as shown in Table A-4.

Table A-4. CMY Data Format

Tag | Possible Values
--- | ---
BitsPerSample | (1,1,1,1) (1,1,1) (4,4,4) (8,8,8)
PhotoMetricInterpretation | 5
SamplesPerPixel | 3 (4 or 8 bits, 1-bit planar) or 4 (1-bit chunky)
PlanarConfiguration | 1, 2
NumberOfInks | 3

The YMC data class is similar to the CMY class except that data is organized as YMC instead of CMY (see Table A-5). When using `libstiff`, YMC data corresponds to the data type ST_TYPE_YMC.

Table A-5. YMC Data Format

Tag | Possible Values
--- | ---
BitsPerSample | (1,1,1,1) (1,1,1) (4,4,4) (8,8,8)
PhotoMetricInterpretation | 5
SamplesPerPixel | 3 (4 or 8 bits, 1-bit planar) or 4 (1-bit chunky)
PlanarConfiguration | 1, 2
NumberOfInks | 3
InkSet | 2
InkNames | yellow, magenta, cyan

The YMCK class is similar to the CMYK class except that data is organized as YMCK instead of CMYK (see Table A-6). When using `libstiff`, YMCK data corresponds to the data type ST_TYPE_YMCK.

Table A-6. YMCK Data Format

Tag | Possible Values
--- | ---
BitsPerSample | (1,1,1,1) (4,4,4,4) (8,8,8,8)
PhotoMetricInterpretation | 5
SamplesPerPixel | 4
PlanarConfiguration | 1, 2
NumberOfInks | 4
InkSet | 2
InkNames | yellow, magenta, cyan, black

The KCMY class is similar to the CMYK class except that the data is organized as KCMY instead of CMYK (see Table A-7). When using `libstiff`, KCMY data corresponds to the data type ST_TYPE_KCMY.

Table A-7. KCMY Data Format

Tag | Possible Values
--- | ---
BitsPerSample | (1,1,1,1) (4,4,4,4) (8,8,8,8)
PhotoMetricInterpretation | 5
SamplesPerPixel | 4
PlanarConfiguration | 1, 2
NumberOfInks | 4
InkSet | 2
InkNames | black, cyan, magenta, yellow

Note that for the RGB, CMY, and YMC classes with BitsPerSample values of (1,1,1) and a PlanarConfiguration value of 1, pixels are stored two to a byte, with the bits ordered from most-significant to least-significant.

For example, CMY data is stored as

CMY0CMY0

Rows are padded to contain an integral number of bytes.

Refer to the header file `stiff.h` for additional information regarding the STIFF file structure.

Prev | Table of Contents | Next
Chapter 11. Enhancing Impressario With Plug-Ins |  | Appendix B. Silicon Graphics Image File Format API