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.
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 operating systems.
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 compatibility.
Profile types. There are three main types of device profile: input, display, and output. These types have the following signatures:
Profile 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:
Profile 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.
Profile 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.
Profile 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.
Accessing 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.
Embedding 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.
QuickDraw-specific 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.
Low-level 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.
Searching 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.
PostScript 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.
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 folder.
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.
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.*