Chapter 1. Color Management

This chapter briefly introduces you to color management, the main components of the Coloratura color management system, the basic structure of a Coloratura application, and outlines a color conversion application.

These are the topics discussed in this chapter:

The Color Management Problem

This section briefly surveys the main problems of color management.

How digital color devices interpret colors varies from device to device. Even if two devices appear identical, detail differences can yield different images from the same data. You could say that no two devices "see" color in exactly the same way. Often the differences can dramatically affect image appearance if you transfer a color image from one device to another without a color management tool. These effects occur largely because the "recipe" for a particular color on one device rarely gives the same color on another device, that is, the specifications of which primary colors to use and how much of each do not agree in any obvious way.

A device's color space, that is, its set of colors and how they are parameterized, is a useful way of describing its interpretation of color. A device's color space results from a combination of design choices and physical constraints. Color spaces can differ in two main ways:

  • primary colors

  • color gamut

Device primary colors determine the method of parameterizing colors, and can differ in two fundamental ways:

  • The set of primaries used to describe colors can be obviously different. For example, a RGB device describes colors with combinations of red, green, and blue; but a CMYK device uses cyan, magenta, yellow, and black.

  • Spectral contents of primaries can differ, even if two devices use nominally the same primary colors; one device's red is not necessarily the same as another device's.

A central task of color management is maintaining a consistent method for translating between differing sets of color primaries.

The color gamut of a device is the set of possible colors that the device can produce. Clearly, these sets can vary. A typical practical problem for image development is the set of colors available on a color monitor is larger than that available on a printer.

How the Coloratura Color Management System Helps

The Coloratura color management system provides a framework for IRIX applications to reconcile device color spaces and to communicate colors accurately; that is it defines a color management system (CMS). The Coloratura CMS provides an API for access to device characterization profiles (ICC profiles) and for control of color transformation computations. For example, you can develop an application that will match your printer output to a scanned image, or simulate on your monitor the output of your printer.

In general terms, the elements required for a CMS are the following:

  • A standard file format to characterize device color characteristics.

  • A standard, device-independent color space with which to describe each device's color space.

  • Procedures to manipulate the standard descriptive information.

  • Tools to transform color image data.

The next few sections elaborate on how the Coloratura CMS provides these elements.

Profiles: Device-Independent Color Spaces

A device profile is a file in a standard format that characterizes a device's color interpretation. The characterization translates the device's color space into either of two device-independent color spaces, CIELAB or CIEXYZ, developed by the CIE (Commission Internationale d'Eclarage, that is, International Committee of Illumination) to describe human color perception. The profile format used by the Coloratura CMS is described by the International Color Consortium Color Profile Format Specification, which can be found at http://www.color.org.

The device-independent color space is called a profile connection space (PCS); it allows you to transform data characterized by one ICC profile to data characterized by another, with a minimum distortion of color information. The PCS provides a common language to describe how colors appear to devices.

The data in a profile is organized into individual blocks, tag data. Tag data detail specific device characteristics, the information needed to transform image data. For example, profiles can supply parameters indicating a preferred color conversion algorithm. Another example of tag data: the ICC Profile Format Specification includes a tag to characterize rendering intent, which describes how to reconcile differing gamuts when image data are converted from one color space to another. This tag is useful because the ideal process of transforming from one color space to another by simply translating a given color from one color space to another rarely occurs; typically the color gamuts of input and output devices differ. In any case, often with a change in medium or lighting conditions you want to modify color content. For more information on rendering intents, see the ICC Profile Format Specification.

The Coloratura CMS provides tools to examine profiles on disk, read them, write them, delete them, and edit their tag data. You can also read and write profile data embedded in image files. See Chapter 3, "Profile Management," and Chapter 4, "Tag Management."

Transforms: Color Processing from Profiles

You combine profiles into a transform to determine the flow of color information. For example, suppose you want to drive a printer, which typically uses CMYK, with data taken from a display screen, which uses RGB. You combine the input profile for the screen and the output profile for the printer into a transform. Then you apply this transform to each buffer full of data from the screen to create a buffer full of data for the printer.

As another example, to simulate on your monitor the output of a printer using input from your scanner, you create a transform using a sequence of profiles for these devices in the following order: scanner to printer to monitor.

The Coloratura CMS provides tools to build transforms from profiles, save them, examine the gamut of transformed image data, and apply transforms to image data. See Chapter 5, "Transform Management." To apply the transforms, you need to select a color manipulation module, discussed in the next section.

Color Manipulation Modules: Algorithms from Transforms

A color manipulation module (CMM) uses the information in a transform to define a color conversion algorithm. Profiles can be more or less exact in how they characterize the relationship between a device's color space and the profile connection space, and CMMs can be distinguished by how they interpret sparse profile data.

The Coloratura CMS allows you to use several CMMs, which are implemented as dynamic shared objects (DSOs). The Coloratura framework serves as a dispatcher between your application and available CMMs, supplying a unified API to them. A default CMM ships with the Coloratura CMS. Not all CMMs necessarily support all possible profiles, however the default CMM does.

A CMM is likely to achieve the best quality with profiles generated specifically for that CMM. Profiles can identify a "preferred" CMM, which best interprets the profile, as well as any specified rendering intent. This information guides the development of the transformation algorithm. When performing a transformation, a CMM uses the rendering intent to make appropriate color adjustments. This can be particularly useful for generating accurate image simulations.

The Coloratura CMS provides tools to examine the available CMMs on your system. See Chapter 6, "Color Manipulation Module Management."

Schematics of Program Architecture and Data Flow

You Coloratura application does not interact directly with profile data on disk, nor with CMMs. The Coloratura CMS mediates the interaction by establishing the relationships between your application, ICC profiles on disk and CMMs that are illustrated in Figure 1-1. Also shown in Figure 1-1 are the internal data structures the Coloratura CMS uses to manage profiles, tags, and transforms. Blocks that are adjacent in the figure indicate direct communication between the objects.

Figure 1-1. Components of a Color-Management Application

Figure 1-1 Components of a Color-Management Application

Figure 1-2 illustrates the data flow for a typical application. It schematically compares the flow to that of an application that does not use color management, but, in this example, uses a "1-minus" conversion from RGB to CMYK. Two input and output paths are shown for the Coloratura application, corresponding to two likely sources and destinations for data: devices or image files. Ironically, color managed images are unavailable for this document, so the color distortions shown in Figure 1-2 can only be rough illustrations of the effects.

Figure 1-2. Data Flow for a Typical Color-Management Application

Figure 1-2 Data Flow for a Typical Color-Management Application

Pseudocode Example for a Color Conversion

The following lines of code illustrate the basic programming elements of the Coloratura CMS. The example is not working code, but provides the essential components of a program for driving a CMYK printer with data taken from a workstation's monitor. The next section outlines in more detail the procedures of a color management application, and Appendix B, "Listing of the Application cocoifl," presents the code of a working program that implements these operations.


Note: For the Coloratura CMS, function names all start with "cms", type names all start with "CMS", and library constant names all start with "CMS_".


  • First, allocate data structures and open the Coloratura CMS. The header file cms.h defines the data types and specifies the function prototypes.

    /* Typedefs for some of the variables used in the pseudocode */
    CMSContext      ctxt;
    CMSProfile      profSource, profDest, profiles[2];
    CMSParameter    param;
    char           *profSpecDest;
    CMSTransform    tfm;
     
    cmsOpen( &ctxt );

  • Next, find the necessary device profiles. The following lines get the source, that is the monitor's, profile from the settings and assumes you know the destination profile.

    cmsOpenProfile( ctxt, CMS_DEFAULT_MONITOR, &profSource );
    cmsOpenProfile( ctxt, profSpecDest, &profDest );

  • The first profile added to a transform is assumed to be the input device; the last profile, the output device. For this example, we need only two profiles:

    profiles[0] = profSource;
    profiles[1] = profDest;
    cmsCreateTfm( ctxt, 2, profiles, CMS_USE_DEFAULT_CMM, &tfm )

  • Finally, for each buffer full of pixels from the screen, apply the transform that corrects for the differing device color mappings and converts the pixels from the display screen's RGB space into the printer's CMYK space. The example skips over allocating data storage for the input and output buffers. Note that buffers are usually of different sizes.

    while (GetPixelsFromScreen( &pbufIn.data) != NO_MORE_PIXELS) {
        cmsTfmApply( ctxt, tfm, &pbufIn, &pbufOut );
        WritePixelsToPrinter( pbufOut.data );
       }

Example Outline of a Color Conversion Program

This section outlines the procedures in a color conversion application that is more realistic than the example in the last section. The procedures introduce the main Coloratura data structures and functions, and the discussion directs you to details in the rest of this guide.

The data flow of the program is the same as that outlined in Figure 1-2, but without any intermediate profiles. C++ code for the program, called cocoifl, is in /usr/cms/examples/ and is listed in Appendix B, "Listing of the Application cocoifl."

Below are the program steps described in this section. Some details, error handling, for example, have been left out; look at the source code to see how these details are handled.

Loading Header Files

The program begins by including standard C++ library header files, Image Format Library (see IFL(3)) headers, and the two files that are sufficient to use the Coloratura CMS, ic.h and cms.h. These latter two declare Coloratura functions, and ICC profile structures.

Declaring Variables

The program declares local variables and the Coloratura data structures it needs:

Opening the Coloratura CMS, the Input Image File, and the Output Profile

In any Coloratura application, the first call is to cmsOpen(), discussed in the section "Initializing the Coloratura CMS: cmsOpen()". The program then manages the command-line arguments and uses an IFL function to open the input image file.

With a call to cmsOpenProfile(), the program then brings an output ICC profile from disk into the Coloratura data structure identified by a CMSProfile, discussed in "Loading Profile Data: cmsOpenProfile()". From the open profile, cocoifl gets ICC header information by using the function cmsGetProfileHeader(), discussed in "Getting Open-Profile Header Information: cmsGetProfileHeader()".

Preparing the Output Pixel Buffer and Open an Output Image File

The program places some of the output profile header information into the output CMSPixelBuffer, and sets the IFL color model. It uses an IFL function to creates the output image file.

Selecting an Input Profile

The program has a hierarchy of possible input profile sources:

  • a profile designated to override profile information that might be embedded in the source image

  • an profile embedded in the source

  • a profile designated to be used if no embedded profile is found

  • a default profile

If no overriding profile is specified, cocoifl determines if an ICC profile is embedded in the source image and uses an IFL function to read it from the image file. You call cmsImportProfile() to convert the profile data to the Coloratura CMS's internal data structure. This function is discussed in "Importing an ICC Profile from a Buffer: cmsImportProfile()".

Without explicit profile information, cocoifl uses one of two default profiles, depending on whether the image data are RGB or CMYK data. The default profiles are specified by the constants CMS_DEFAULT_MONITOR and CMS_DEFAULT_CMYK. See the section "Loading Profile Data: cmsOpenProfile()".

Creating a Transform and Initializing Buffers

With a source and destination profile, the program creates a transform by calling cmsCreateTfm(), discussed in "Creating a Transform: cmsCreateTfm()".

The iflRGBPalette color map creates a special case, because of the unique way it handles color information; the pixel data are indices to a color palette. For this case, the program cocoifl sets up the input and output CMSPixelBuffers, and transforms the data.

For all other color maps, pixel data are coordinates in device color spaces. The program only initialize the output CMSPixelBuffer, and sets up the input CMSPixelBuffer with header information and pixel data. The program applies the color transformation later.

If no input profile was found, or if the input data use the iflRGBPalette color map and, so, have already been transformed, the program passes the input directly to the output buffer.

Embedding the Output Profile in the Output Image File

The program calls cmsExportProfile() to create an ICC formatted data structure, and embeds the output profile in the output image with a call to an IFL function. The function cmsExportProfile() is discussed in "Creating an ICC Profile in a Buffer: cmsExportProfile()".

In general, when you are through with data structures created by the Coloratura CMS, you free the allocated memory. After embedding the profile in the output image, cocoifl calls cmsFreeProfileExport() to clear the data created by cmsExportProfile(). cmsFreeProfileExport() is discussed in "Deleting an ICC Profile Buffer: cmsFreeProfileExport()"

Transforming Pixel Data and Cleaning Up

The program uses IFL calls to get image-file data one tile at a time, reads data from the input file to the input CMSPixelBuffer, and, with a call to cmsApplyTfm(), applies the transform that was created by cmsCreateTfm() (see "Applying a Transform: cmsApplyTfm()").

Finally the program frees memory it has allocated.