Graphics Importer Components

This chapter describes the functions you can use to obtain the services of graphics importer components and use them to draw and manipulate image files.

Displaying Still Images

Graphics importer components provide a standard method for applications to open and display still images contained within graphics documents. Graphics importer components allow you to work with any type of image data, regardless of the file format or compression used in the document.

You specify the document that contains the image, and the destination rectangle the image should be drawn into, and QuickTime handles the rest. More complex interactions are also supported.

To draw an image file, use the function shown in Listing 2-1.

Listing 2-1  The basic function used to draw an image file

void drawFile(const FSSpec *fss, const Rect *boundsRect)
    {
        GraphicsImportComponent gi;
        GetGraphicsImporterForFile(fss, &gi);
        GraphicsImportSetBoundsRect(gi, boundsRect);
        GraphicsImportDraw(gi);
        CloseComponent(gi);
    }

The same code can be used to display any image, regardless of the file format.

Image Formats with Multiple Images in a Single File

QuickTime includes support for image formats which can have multiple images in a single file. You can use GraphicsImportGetImageCount to find out how many images are in a file, and GraphicsImportSetImageIndex to select a particular image. Of the image formats supported by QuickTime, TIFF files can support multiple images, Photoshop files can contain multiple layers and FlashPix files can contain multiple resolutions.

Note that individual images in a file may have different characteristics (width and height, depth, and so on).

Use the following functions to deal with image counts, getting and setting image indexes:

  • GraphicsImportGetImageCount

  • GraphicsImportSetImageIndex

  • GraphicsImportGetImageIndex

Supporting 64-bit File Sizes and Offsets

QuickTime supports 64-bit file sizes and offsets. Four new functions have been added to the graphics importer API. Each is a 64-bit analog of an original 32-bit function. The base graphics importer’s implementation of some 32-bit functions have been modified to call the 64-bit version. (They may return fileOffsetTooBigErr in the event that a 64-bit value cannot be converted to a 32-bit value.) Applications and format-specific importers can call either version of each function.

Use the following functions to deal with 64-bit file sizes and offsets:

  • GraphicsImportGetDataOffsetAndSize64

  • GraphicsImportReadData64

  • GraphicsImportSetDataReferenceOffsetAndLimit64

  • GraphicsImportGetDataReferenceOffsetAndLimit64

Retrieving Default Settings

Some file formats, most notably FlashPix, can store a default matrix, clipping region, graphics mode and source rect in the image file. In order to display the image correctly, these settings should be used.

Use the following functions to deal with retrieving default settings:

  • GraphicsImportGetDefaultMatrix

  • GraphicsImportGetDefaultClip

  • GraphicsImportGetDefaultGraphicsMode

  • GraphicsImportGetDefaultSourceRect

Default settings from FlashPix files are not used automatically.

Getting ColorSyncProfiles

QuickTime includes support for extracting embedded ColorSync profiles from some image formats. Of the image formats supported by QuickTime, these are GIF, JPEG, PNG, QuickDraw Picture, QuickTime Image, and TIFF. Image files containing ColorSync profiles describe their own colorspaces in a self-contained manner.

Since it was introduced in QuickTime, the PNG graphics importer has performed built-in gamma correction. QuickTime includes a flag that can you can set using the GraphicsImportSetFlags function to turn this off. This is useful for applications that want to use some other mechanism for colorspace correction, such as ColorSync.

Use the following functions to deal with getting ColorSync profiles, and getting and setting import flags:

  • GraphicsImportGetColorSyncProfile

  • GraphicsImportSetFlags

  • GraphicsImportGetFlags

Getting/Setting the Destination Rectangle

QuickTime includes two calls that let applications access a graphics importer’s destination rectangle.

Use the following functions to deal with accessing a destination rectangle:

  • GraphicsImportSetDestRect

  • GraphicsImportGetDestRect

Figure 2-1 shows an example with the following four rectangles: natural bounds, source rectangle, bounds rectangle, and a destination rectangle. You can access the destination rectangle in QuickTime with these calls.

In Figure 2-1, the matrix scales by 200% vertically and translates 200 pixels to the right.

Figure 2-1  Matrix scaling and translation
Matrix scaling and translation

QuickTime Image File Format

QuickTime Image files are intended to provide the most useful container for QuickTime compressed still images. The format uses the same atom-based structure as a QuickTime movie.

Most still image file formats define both how images should be stored and compressed. However, two of the file formats supported by QuickTime are container formats, which describe storage mechanisms independent of compression. These formats are QuickDraw Picture (PICT) files and QuickTime Image (QTIF) files.

QuickTime has permitted compressed image data to be included in QuickDraw pictures since QuickTime was first introduced. However, the technical challenges of parsing, interpreting and spooling picture files can make them a discouraging choice for applications which are primarily interested in accessing the compressed data inside.

The QuickTime Image file format provides a much simpler container for QuickTime compressed still images. The format uses the same atom-based structure as a QuickTime movie. Because the QuickTime Image file is a single fork format, it works well in cross-platform applications. On Mac OS systems, QuickTime Image files are identified by the file type 'qtif'. On other platforms, Apple recommends that you use the filename extension .QTIF to identify QuickTime Image files.

Atom Types in QuickTime Image Files

There are two defined atom types: 'idsc', which contains an image description, and 'idat', which contains the image data. They are illustrated in Figure 2-2. For a JPEG image, the image description atom contains a QuickTime image description describing the JPEG image’s size, resolution, depth, and so on, and the image data atom contains the actual JPEG compressed data, as shown in Table 2-1.

In QuickTime, there is an optional atom type, 'iicc', which can store a ColorSync profile.

Figure 2-2  An 'idsc' atom followed by an 'idat' atom
An 'idsc' atom followed by an 'idat' atom
Table 2-1  A QuickTime Image file containing JPEG compressed data

Data

Description

0000005E

Atom size, 94 bytes

69647363

Atom type, 'idsc'

00000056

Image description size, 86 bytes

6A706567

Compressor identifier, 'jpeg'

00000000

Reserved, set to zero

0000

Reserved, set to zero

0000

Reserved, set to zero

00000000

Major and minor version of this data, zero if not applicable

6170706C

Vendor who compressed this data,'appl'

00000000

Temporal quality, zero (no temporal compression)

00000200

Spatial quality, codecNormalQuality

0140

Image width, 320

00F0

Image height, 240

00480000

Horizontal resolution, 72 dpi

00480000

Vertical resolution, 72 dpi

00003C57

Data size, 15447 bytes (use zero if unknown)

0001

Frame count, 1

0C 50 68 6F 74 6F 20 2D 20 4A 50 45 47 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Compressor name, "Photo - JPEG" (32 byte Pascal string)

0018

Image bit depth, 24

FFFF

Color look-up table ID, -1 (none)

00003C5F

Atom size, 15455 bytes

69646174

Atom type, 'idat'

FF D8 FF E0 00 10 4A 46 49 46 00 01 01 01 00 48 ...

JPEG compressed data

A QuickTime image file can also contain other atoms.

The exact order and size of atoms is not guaranteed to match the example in Table 2-1. Applications reading QuickTime image files should always use the atom size to traverse the file and ignore atoms of unrecognized types.

Like QuickTime movie files, QuickTime Image files are big-endian. However, image data is stored in the same byte order as usually specified by the particular compression format.

Obtaining Graphics Import Components

You can use the GetGraphicsImporterForFile function to open a suitable graphics import component for a file. If you have a data reference instead of a file, you can use GetGraphicsImporterForDataRef instead.

When the Image Compression Manager’s GetGraphicsImporterForFile function searches for a graphics import component, it tries, in order:

The last stage can be time-consuming, since it involves opening many components in turn. If you want to skip it, call GetGraphicsImporterForFileWithFlags (or GetGraphicsImporterForDataRefWithFlags ) and pass the kDontUseValidateToFindGraphicsImporter flag.

If you include kQTFileTypeQuickTimeImage ('qtif') in the list of types passed to StandardGetFilePreview, all files that can be opened with graphics importers are included in the file list. The slow validate approach is not used in this case.

When you are done with the graphics importer instance, you call CloseComponent.

If you expect to draw the same image more than once, you can improve performance by keeping the graphics importer component open, rather than creating and disposing of it each time.

Once you have a graphics import component for your file or data reference, you can query it to determine the properties of the file, configure drawing parameters, and draw or export the file. The next two sections explain how to do this.

Determining the Properties of the Image File

If you want to know the dimensions of the image, call the importer’s GraphicsImportGetNaturalBounds function. If you want to know other information that is represented in the image description, such as its depth or color table, call GraphicsImportGetImageDescription. If you want to extract meta-data from the image file (such as textual comments, like copyright information), call GraphicsImportGetMetaData. If you want to know information about the file format, such as the MIME types and MIME suggested file name suffixes, call GraphicsImportGetMIMETypeList.

Some image file formats can contain transparent regions, and hence may leave some pixels in their rectangular range unmodified even when drawing with a copying transfer mode and an identity matrix. If you would like to know whether a graphics importer’s format supports such transparent regions, call GraphicsImportDoesDrawAllPixels. If a graphics importer doesn’t support the GraphicsImportDoesDrawAllPixels call, you can assume it will draw all pixels.

Drawing and Converting Image Files

Before drawing, you may wish to set various parameters. Among those you can configure are the

  • source rectangle

  • transformation matrix

  • clipping region

  • graphics transfer mode

  • drawing quality

  • destination graphics port and device

These parameters are explained in detail in Table 2-2.

Table 2-2  Drawing parameters you may configure

Parameters

Description

source rectangle

Used to select a rectangular portion of the compressed image.

transformation matrix

Used to shift, scale, rotate, and apply perspective to the source portion of the image. (Set this with SetMatrix, SetBoundsRect, or SetDestRect.)

clipping region

Used to restrict the area to be drawn in the destination space.

graphics transfer mode

Used to define how source pixels modify destination pixels.

drawing quality

Used to specify quality vs. time tradeoffs; For example, if you're drawing a JPEG image to an 8-bit color screen, the drawing quality determines whether a slower or faster dither will be used.

destination graphics port and device

Defines the graphics environment for drawing.

Once you have set the drawing parameters, you can call Draw to draw the image.

You can also call GraphicsImportGetAsPicture to get the image in the form of a QuickDraw picture handle, GraphicsImportSaveAsPicture to save it in a PICT file, or GraphicsImportSaveAsQuickTimeImage to save it in a QuickTime Image file. To export it to other image file formats, you can use GraphicsImportExportImageFile, or GraphicsImportDoExportImageFileDialog to present a standard Export As.. dialog box.

When you are done with a graphics import component, you call CloseComponent.

Writing Graphics Import Components

This section describes how graphics import components work and briefly discusses how to write a component. If you’re interesting in writing a component, you should read this section.

Format-specific graphics import components, such as the importers for JPEG, PNG, TIFF etc., are simple components. When a format-specific graphics importer is opened, it opens and targets an instance of the base importer. Subsequently, it delegates most of its calls to the base importer instance, as shown in Figure 2-3.

Figure 2-3  Delegating calls to the base importer
Delegating calls to the base importer

The base importer communicates with data handler components to access image file data, and with the Image Compression Manager to arrange for image rendering. The only service a format-specific importer must provide is the GraphicsImportGetImageDescription call, which examines an image file and constructs an image description for it. The base importer uses this image description to respond to other calls such as GraphicsImportGetNaturalBounds and GraphicsImportDraw. (In the case of GraphicsImportDraw, the image description is passed to the Image Compression Manager, so the cType field must identify a codec that will be able to draw the image. If a graphics importer needs to pass extra information that the codec will need at PreDecompress time, it can pass it in an image description extension.)

Sometimes, the data to be passed to the image decompressor is only a portion of the file. In these cases, the format-specific importer should implement the GraphicsImportGetDataOffsetAndSize function to indicate the byte range to send to the image decompressor. It is often useful for this call to first call the generic importer’s implementation to find out the size of the input data stream.

In QuickTime, there is a 64-bit analog of this function, called GraphicsImportGetDataOffsetAndSize64. In order to provide compatibility with old graphics importers, the generic importer’s implementation of this function calls the 32-bit version. Format-specific importers may implement both the 32-bit and 64-bit versions if it makes sense for their file formats.

Graphics import components may override other calls, such as GraphicsImportGetMetaData, which extracts supplemental information from an image file, and GraphicsImportGetMIMETypeList, which provides information about the format.

Another optional call is GraphicsImportValidate, which attempts to ascertain quickly whether a file matches the importer’s format. This is especially useful for formats which start with identifying codes or “magic numbers” (such as PNG and TIFF) in situations where image files do not have correct file types or suffixes. In situations like this, the Image Compression Manager may ask many graphics importers in turn to validate until it finds one that accepts the file, so it is important that GraphicsImportValidate calls not be too slow. Format-specific importers that implement the GraphicsImportValidate call should have the canMovieImportValidateFile bit set in their component flags.

Graphics importers supporting image formats which can have transparent regions should implement the GraphicsImportDoesDrawAllPixels call so as to warn applications that they may need to erase the destination area before drawing.

Registering Graphics Import Components

Graphics import components have component type 'grip'. The interpretation of the subtype depends on the movieImportSubTypeIsFileExtension component flag. If this flag is clear, the subtype is a Macintosh file type. If this flag is set, the subtype is a file name suffix; it should be in uppercase and followed by space characters to pad it out to four characters. For instance, the file name suffix .png would be represented by the subtype 'PNG '.

It is often useful to register graphics import components multiple times, so that both the file type and file name suffix may be matched. An efficient way to do this is to register the second and subsequent components as component aliases to the first.

Graphics import components that use the base importer’s Draw method should set the graphicsImporterUsesImageDecompressor flag in their component flags.

Getting Image Characteristics

These functions are called by applications to obtain information about images:

Format-specific graphics importers always implement GraphicsImportGetImageDescription and may optionally implement the remaining functions listed above.

Setting Drawing Parameters

The functions listed below allow you to specify various parameters for drawing operations, such as clipping, scaling, graphics mode, and decompression quality. All of these functions are based on corresponding routines in the Image Compression Manager for working with image decompression sequences:

Drawing Images

These functions are used to draw images:

Saving Image Files

Graphics import components can save data in several formats, including QuickDraw pictures and QuickTime Image files. This capability is only needed by applications that perform file format translation. Applications that only wish to draw the image can use the GraphicsImportDraw function.

Getting MIME Types

Your graphics import component can support MIME types that correspond to graphics formats it supports. To make a list of these MIME types available to applications or other software, it must implement this function:

Specifying the Data Source

Graphics importer components use QuickTime data handler components to obtain their data. Applications, however, will use the graphics importer component functions described in this section, rather than directly calling a data handler. These functions allow the data source to be a file, a handle, or a QuickTime data reference.

You do not need to call the functions in this section if you use one of the GetGraphicsImporter functions. The GetGraphicsImporter functions automatically set the graphics importer component’s data source. You only need to use these functions if you open the graphics importer component directly.

Retrieving Image Data

This function is used by format-specific graphics import components to read data from the data source; it is implemented by the base graphics importer:

Graphics Importer Flags for Gamma Correction

You can set the kGraphicsImporterDontDoGammaCorrection flag when you want to tell the Graphics Importer not to perform gamma correction

enum {
    kGraphicsImporterDontDoGammaCorrection = 1L
};

Term

Definition

kGraphicsImporterDontDoGammaCorrection

Specifies not to perform a gamma correction.

Image Description Atoms in QuickTime Image Files

These atoms may appear in QuickTime image files:

enum {
    quickTimeImageFileImageDescriptionAtom = FOUR_CHAR_CODE('idsc'),
    quickTimeImageFileImageDataAtom = FOUR_CHAR_CODE('idat'),
    quickTimeImageFileMetaDataAtom = FOUR_CHAR_CODE('meta'),
};

ColorSync Atoms in QuickTime Image Files

QuickTime includes a ColorSync atom type, which can be used to store ColorSync profile information:

enum {
    quickTimeImageFileColorSyncProfileAtom = FOUR_CHAR_CODE('iicc')
};

Graphics Importer Component Type

Graphics importer components have this component type:

enum {
    GraphicsImporterComponentType = 'grip'
};

MIME Type List

The GraphicsImportGetMIMETypeList function returns a list of the MIME types supported by a graphics importer component. This list is contained in the QT atom container described in this section.

At the top level of the atom container are three atoms for each supported MIME type. The atoms whose IDs are 1 describe the first supported MIME type, the atoms whose IDs are 2 describe the second supported MIME type, and so on. Note that the IDs have to be consecutive.

Figure 2-4 illustrates a MIME type list.

Figure 2-4  A MIME type list
A MIME type list