September 95 - Print Hints: Syncing Up With ColorSync 2.0
Syncing Up With ColorSync 2.0
In March of this year, Apple announced a major upgrade to the ColorSync
extension and API: ColorSync 2.0. Like version 1.0, ColorSync 2.0 is a powerful
color management system that allows applications and device drivers to produce
consistent color across different devices. However, ColorSync 2.0 dramatically
improves the quality, flexibility, and performance of color management. This
column focuses on the new features of ColorSync 2.0 and how applications can
take advantage of them. (For a good review of ColorSync 1.0 and color
management in general, see John Wang's Print Hints column in develop Issue 14.)
ColorSync 2.0 is an extension to the Mac OS that provides a color management
system for applications, scanner drivers, printer drivers, and other components
of the OS such as QuickDraw and QuickDraw GX. The objective of the color
management system is to provide consistent color across devices that have
different color ranges, or gamuts
All the versions of QuickDraw GX that have shipped as of this writing (v1.0.1
through v1.1.2) use the ColorSync 1.0 API. ColorSync 2.0 is backward
compatible, so QuickDraw GX will work fine if ColorSync 2.0 is installed.
QuickDraw GX version 1.2 will add full ColorSync 2.0 support.*
To understand the task of color management, consider the process of scanning,
displaying, editing, and printing a color document: In a typical configuration,
a color document may interact with three devices -- scanner, monitor, and
printer -- each of which works with color in different ways. A scanner contains
a CCD array, which is nonlinearly sensitive to specific frequencies of red,
green, and blue light. A monitor hurls electrons at special phosphors to
produce varying amounts of red, green, and blue light. And a color printer
relies on a mixture of dyes, waxes, or toner to subtract cyan, magenta, yellow,
and black from white paper. Because each of these devices uses different
physical systems in different color spaces with different gamuts, providing
consistent color is difficult. The goal is to provide the best consistency
given the physical limitations of each device.
To meet this goal, ColorSync 2.0 requires detailed information about each
device and how it represents or characterizes color. This information is
encapsulated in a device profile. A ColorSync-savvy scanner stores (or
"embeds") its profile in the document it creates. A ColorSync-savvy application
uses the profile embedded in the document and displays it according to the
monitor's profile; a ColorSync-savvy printer renders the document according to
the printer's profile.
Device profiles are the key ingredient of any color management system because
they define the unique color behavior of each device. They're used by color
(CMM) components, which perform the low-level calculations
required to transform colors from a source device color space to a destination
device color space.
CMM used to stand for color matching method. There was disagreement with that
name because a CMM component does a lot more than just color matching. So we
changed the name to color management module to be more accurate.*
ColorSync 2.0 uses a new profile format defined by the
International Color Consortium (ICC), the founding members of which include
Apple, Adobe Systems, Agfa-Gevaert, Eastman-Kodak, Microsoft, Silicon Graphics,
Sun, and FOGRA (honorary). The International Color Consortium Profile Format
states the following in its introduction:
The intent of this format is to provide a cross-platform device profile format.
Such device profiles can be used to translate color data created on one device
into another device's native color space. The acceptance of this format by
operating system vendors allows end users to transparently move profiles and
images with embedded profiles between different operating systems. For example,
this allows a printer manufacturer to create a single profile for multiple
The ICC profile format is designed to be flexible and extensible so that it can
be used on a wide variety of platforms and devices. The profile structure is
defined as a header followed by a tag table followed by a series of tagged
elements that can be accessed randomly and individually. In a valid profile, a
minimal set of tags must be present, but optional and private tags may be added
depending on implementation needs. Complete definitions of the required tags
can be found in the profile format specification. Perhaps just as important,
Apple and Adobe have defined how profiles can be embedded in the common
graphics file formats PICT, EPS, and TIFF.
There have been changes in the way ColorSync works with profiles as a result of
this new format. For example, with ColorSync 1.0, the entire profile format was
compact enough to be used as a memory-based data structure, whereas with
ColorSync 2.0, profiles can be much larger and typically are disk-based.
However, ColorSync 2.0 can still make use of old 1.0 profiles for backward
types. There are three main types of device profile: input, display, and
output. These types have the following signatures:
- 'scnr' -- input devices such as scanners or digital cameras
- 'mntr' -- display devices such as monitors or liquid crystal displays
- 'prtr' -- output devices such as printers
In addition to these
basic types, three other device profile types are defined:
- 'link' -- Device link profiles concatenate into one profile a series of
profiles that are commonly used together. A profile of this type can simplify
and expedite the processing of batch files when the same combination of device
profiles and non-device profiles is used repeatedly.
- 'spac' -- Color space conversion profiles are used by CMMs to perform
intermediate conversions between different device-independent color spaces.
- 'abst' -- Abstract profiles provide a generic method for users to make
subjective color changes to images or graphic objects by transforming the color
quality and rendering intent. Typically you can think of a profile as a
self-contained set of data that contains all the information needed for a CMM
to perform a color match. Therefore, if an application wants to embed a profile
in a document, it shouldn't have to make any changes to the profile -- the
profile is just a black box of data. This is true for the most part, but there
are a few attributes of a profile that an application can change to modify the
behavior of the profile. So, it's better to conceptualize a profile as a black
box of data with a few switches on the outside. Before embedding a profile in a
document, an application can toggle any of these switches by setting the
appropriate bit or bits in the profile's header. One of the switches determines
the profile's quality and another specifies its rendering intent:
- The quality flag bits provide a convenient place in the profile for an
application to indicate the desired quality of a color match (potentially at
the expense of speed and memory) as normal, draft, or best quality. In
ColorSync 2.0 these qualities do not mandate the use of one algorithm over
another; they're just "recommendations" that the CMM may choose to ignore or
implement as it sees fit.
- The rendering intent determines how the CMM performs the match. The
possible intents are photographic matching, saturation matching, relative
colormetric matching, and absolute colormetric matching.
header structure: CMAppleProfileHeader.
In the ColorSync 1.0 profile format, the first member of the profile header
structure (CMAppleProfileHeader) is a CMHeader structure, which contains all
the basic information about the profile. Similarly, the ColorSync 2.0 profile
begins with a CM2Header structure. The fields of the CM2Header structure are
slightly different from those in the old CMHeader, to reflect some of the
improvements provided by the new ICC profile format. However, to be
backward-compatible with 1.0, ColorSync 2.0 defines a union of the two header
structures. Because the version field is at the same offset in both header
structures, it can be used to determine the version of the profile format.
Because ColorSync 2.0 provides support for ColorSync 1.0 profiles, your
application should be prepared to handle both formats. Your code should always
check the version field of the header before accessing any of the other fields
in the header or reading any of the profile's tags.
location structure: CMProfileLocation.
ColorSync 2.0 profiles are typically disk-based files, but they can also be
memory-based handles or pointers. To allow this flexibility, whenever a profile
location needs to be specified (as a parameter for CMOpenProfile, for example)
a CMProfileLocation structure is used. This structure contains a type flag
followed by a union of an FSSpec, a handle, and a pointer.
reference structure: CMProfileRef. Once a profile has been opened, a private
structure is created by ColorSync to maintain the profile until it's closed. A
CMProfileRef (defined as a pointer to the private structure) can be used to
refer to the profile.
A color world
is a reference to a private ColorSync structure that represents a
unique color-matching session. Although profiles can be large, a color world is
a compact representation of the mapping needed to match between profiles.
Conceptually, you can think of a color world as a sort of "matrix
multiplication" of two or more profiles that distills all the information
contained in the profiles into a fast multidimensional lookup table. A color
world can be created explicitly with low-level routines such as
NCWNewColorWorld or automatically with high-level routines like
Here I'll briefly describe the most commonly used ColorSync 2.0 routines,
grouped according to purpose.
The API naming convention is as follows: Calls prefixed with "CM" are
high-level color management routines, while those prefixed with "CW" are
low-level routines that take a color world as an argument. An "N" before "CM"
or "CW" indicates calls that are new to ColorSync 2.0, to distinguish them from
the old ColorSync 1.0 calls (which are still supported for backward
profile files. There is a set of basic routines to work with profiles as a
whole. For example, CMNewProfile, CMOpenProfile, CMCopyProfile, and
CMGetSystemProfile do what you would expect from their names.
Accessing profile elements. These routines perform more specific operations on profiles and profile elements. CMValidate Profile checks whether a profile contains all the needed tags, CMGetProfileElement gets a specific tag type from a profile, and CMGetProfileHeader gets the important header information of a profile.
profiles. NCMUseProfile is a simple routine for embedding a profile into a
PICT. If you need to extract a profile or embed a profile into a different file
format, you can use CMFlattenProfile to embed or CMUnflattenProfile to extract.
matching. These high-level routines provide a basic API to simplify color
matching for QuickDraw drawing routines. NCMBeginMatching tells Color QuickDraw
to begin matching for the current graphics device using the specified source
and destination profiles. NCMUseProfileComment inserts a profile as a picture
comment into an open picture. NCMDrawMatchedPicture draws a picture using color
matching. CWMatchPixMap matches a PixMap using the specified color world.
matching. These low-level routines create color worlds and perform color
matching. NCWNewColorWorld creates a color world using the specified source and
destination profiles, while CWConcatColorWorld creates one using an array of
two or more profiles. Using the specified color world, CWMatchColors matches a
list of colors and CWMatchBitmap matches a generic bitmap.
profile files. This set of routines allows your application to search the
ColorSync(TM) Profiles folder for the subset of profiles that meets your needs.
For example, you could search for only printer profiles and use the search
result to provide a pop-up menu for the user. CMNewProfileSearch searches the
ColorSync(TM) Profiles folder for all profile files that match the supplied
CMSearchRecord. The matches aren't returned to the caller, but the number of
profiles matched and a reference to the search result are returned. The search
result is a CMProfileSearch structure that points to private structures
maintained by ColorSync and can be accessed with a call like
CMSearchGetIndProfile, which opens and returns a CMProfileRef for the nth
member of the search result.
code generation. This set of routines allows your application or printer driver
to generate PostScript(TM) code that can be sent to a PostScript Level 2
printer so that the actual matching calculations will be performed in the
printer instead of on the user's computer. CMGetPS2ColorRendering gets a color
rendering dictionary (CRD) for a specified source and destination profile.
CMGetPS2ColorSpace gets a color space array (CSA) for a specified source profile.
At the very least, your application should respect any embedded profiles in the
documents it works with. For example, if your application works with PICT
files, it shouldn't do anything that would strip out the ColorSync picture
comments used for embedding. Even though your application may choose not to
make use of the profiles, another application or printer driver may be able to
take advantage of them.
If your application prints QuickDraw data to a ColorSync-savvy printer driver,
you need do nothing to get matched output. When the stream of QuickDraw data
sent to the driver contains an embedded profile in picture comments, the
ColorSync-savvy printer driver will create a new color world to match from the
embedded profile to the printer's profile. The driver will then match
subsequent QuickDraw operations accordingly before sending them to the printer.
If the QuickDraw data stream doesn't contain embedded profiles, the driver will
use the current system profile (the profile that the user selected in the
ColorSync control panel) as the source profile. That way, the printed output
will match the screen display.
One example of a ColorSync-savvy printer driver is the LaserWriter 8.3 driver.
Whereas previous versions of LaserWriter 8 allowed the user to choose between
"Black and White" and "Color/Grayscale" in the Print dialog, this version adds
two new choices. "ColorSync Color Matching" tells the driver to use ColorSync
to match an image on the host Macintosh before sending it to the printer. The
other option, "PostScript Color Matching," instructs the driver to generate
PostScript CSAs and CRDs, which are sent to the printer so that the actual
matching is performed in the printer. (The ColorSync API is used to generate
the CSAs and CRDs according to the source profiles that may be embedded in the
document and the destination profile of the printer.) In either case, the
LaserWriter 8.3 driver allows the user to choose a printer profile from a list
of printer profiles installed in the ColorSync(TM) Profiles
Because ColorSync-savvy printer drivers do much of the work for you, it's best
if your application prints documents with QuickDraw even if they're not PICT
files. For example, if your application reads and prints TIFF files, the best
approach is to convert the TIFF data (which may have a profile embedded in
tags) to a PicHandle (which would have the profile embedded in picture
comments). To print, you draw the PicHandle with DrawPicture into the printer's
color graphics port.
If the printer's driver doesn't support ColorSync, your application can still
use ColorSync to produce matched output as long as you have an appropriate
profile for the device. (There are several commercial tools that build ICC
profiles.) Given a source and destination profile, you can use the ColorSync
API to match the image or, if your application must send PostScript data
directly to a printer, to generate CRDs.
There is much that an application can do with ColorSync that will help the user
work with color. For starters, an application could do the following:
- Provide the user with information on any profiles embedded in a document,
and possibly also allow the user to change the quality and rendering intent
settings of embedded profiles.
- Include a print preview mode that shows a "soft proof" of the matched
output on the display. The application accomplishes this by building a color
world with CWConcatColorWorld that matches through three profiles: from the
source profile (which is embedded in the document) to the printer's profile
(which you allow the user to pick from a list of installed printer profiles)
and back to the screen profile (which is the current system profile).
- Along with soft-proofing, it's useful to show the user what colors in
the document are out of gamut according to the current destination profile.
Gamut checking can be done with routines such as CWCheckColors and
Note that the LaserWriter engineering team is designing new
PrGeneral code for the 8.3.1 version of the driver. This will allow an
application to determine what profile is selected in the Print dialog.
Everything you need to use ColorSync 2.0, including interfaces, libraries,
sample code, utilities, and the ICC profile format specification, is on this
issue's CD and in the Mac OS Software Developer's Kit. The technical reference
for ColorSync 2.0 consists of several chapters in the book Advanced Color
Imaging on the Macintosh
, which is also included on this issue's CD and will
soon be available in print from Addison-Wesley; this documentation covers
everything from a high-level discussion of color management theory to a
detailed description of the ColorSync 2.0 API. Why not take a closer look and
see how you can take of advantage of this new improved technology in your
DAVID HAYWARD (AppleLink HAYWARD.D) has been working in the Printing, Imaging,
and Graphics group in Developer Technical Support for over a year. His proudest
achievement to date is the ability to make his hour-long commute every morning
without waking up until he hits the speed bumps on Apple's R&D campus.
Currently Dave is developing a ColorSync CMM for his closet so that he no
longer has to worry about mismatching his clothes.*
Thanks to Paul Danbold, Steve Swen, Nick Thompson, and John Wang for reviewing