Important: The information in this document is obsolete and should not be used for new development.
Interacting With the User
Using selection menus, lists, and dialog boxes, you can provide your user with choices that influence the color-matching process. For example, you can offer the user
- a list of profiles to select from. You can allow the user to choose the appropriate profile for your printer in its current state. To provide a list of profiles for the user to select from, you must first search for the relevant profiles, as described in "Searching for Profiles and Displaying Their Names to the User" (page 6-12).
- a selection menu or dialog box for specifying how the image will be color matched. If the source profile is embedded with the image, the source profile specifies the rendering intent to be used. However, if the source profile is not provided and the system profile is used as the source profile, you should allow the user to select the rendering intent to be used. Your user has different requirements for different kinds of images, such as scanned photographs, posters, pie charts, and book illustrations. You can allow users to specify their intentions for the process to be used in matching the source image's colors when they fall out of gamut for your printer. After the user chooses a rendering intent, you can use the selection to set the source profile's header. "Setting the Rendering Intent Selected by the User" (page 6-15) explains this process.
- a selection menu or dialog box for choosing which color-matching quality of image to produce. A user may want to produce a draft of the image quickly for review before producing the best possible quality of the image. After the user chooses a color-matching quality, you can use the selection to set the source profile's header. "Setting the Color-Matching Quality Selected by the User" (page 6-17) explains how to do this.
Searching for Profiles and Displaying Their Names to the User
The ColorSync Manager search functions let you identify types of profiles or profiles having certain characteristics. You can use these functions to search through available version 2.x profiles in the ColorSync\x89 Profiles folder and hone in on profiles that meet criteria you specify. You can set up a search to look for certain classes of device profiles for a specific manufacturer's device, such as printer profiles designed for the printer model your device driver supports. You can even refine the search to look for a specific printer profile for the printer's current state, for example, a profile especially designed for your printer's use of foils and a certain type of ink.
Searching for profiles entails the following four steps:
- IMPORTANT
- The ColorSync Manager 2.x search functions can identify only version 2.x profiles in the ColorSync
\x89 Profiles folder. If the folder contains ColorSync 1.0 profiles, they are not investigated during the search.
- Defining the search criteria
You can define the search criteria broadly based on the profile's device type only or refine the search based on other specific characteristics of a profile carried in its header or elements. "Defining Search Criteria" (page 6-13) describes this step.
- Running the search
After you set up the search criteria, you must call the
CMNewProfileSearch
function to start the search and find all profiles that match your requirements. "Running the Search" (page 6-13) explains how to do this.- Gaining access to the search results
Using the search results, you can now obtain references to each of the profiles that match your criteria by calling the
CMSearchGetIndProfile
function. "Obtaining References to the Qualifying Profiles" (page 6-14) describes how to do this.- Getting the names of qualifying profiles to display to your user
Once you have references to each of the qualifying profiles, you can obtain the names of the profiles to present to your user. "Getting the Names of Qualifying Profiles" (page 6-14) explains this step.
Defining Search Criteria
Before you begin a profile search, you must describe aspects of the profiles you are looking for. To help you, the ColorSync Manager provides a data structure of typeCMSearchRecord
that you use to identify the search criteria. Your device driver can declare an instance of the search record and assign values to its fields to characterize the profiles you want to find. The search record data structure of typeCMSearchRecord
(page 3-51) is described in Advanced Color Imaging Reference.You define the parameters of a search by first setting the fields of the search record whose values you want matched and then setting the
searchMask
field to indicate the operative fields. If you don't set the field mask, your search criteria are ignored.To create a refined search that seeks all profiles belonging to a certain class that also meet other criteria, you must set multiple fields of the search record. For example, suppose you want to find all printer profiles for your manufacturer's printer and you also want to filter out profiles unless they are for a certain device model. To do this, you need to set the search record's
deviceManufacturer
field to the signature that identifies the manufacturer. This must be the same signature specified in the profile header'sdeviceManufacturer
field when the manufacturer or vendor created the profile. You must also set thedeviceModel
field to the value that identifies the printer model whose profiles you want to identify. After you set these fields, you must set thesearchMask
to identify the operative fields. To do this, you can use the constantscmMatchProfileClass
,cmMatchManufacturer
, andcmMatchModel
. After you define a search record that establishes your criteria, you must initiate the search.For a description of the enumeration that defines constants for profile class signatures, see "Profile Classes" (page 3-13) in Advanced Color Imaging Reference. For a description of the enumeration that defines constants for the search mask, see "Profile Search Record" (page 3-51) in the same book.
Running the Search
Passing to this function the search record whose fields you set in the previous step, you call theCMNewProfileSearch
function to run the search on all profiles in the ColorSync\x89 Profiles folder. The CMNewProfileSearch
function searches the ColorSync\x89 Profiles folder for version 2.x profiles that meet your criteria. In response, the function returns to your driver a reference to a search results private data structure containing a list of all profiles that match your description. The function also returns a one-based count telling you how many profiles are in the list. You use this count, along with the search result reference, to navigate the list in order to identify a specific profile and obtain information about it. Your device driver cannot gain direct access to the contents of the search result list.
Obtaining References to the Qualifying Profiles
Using the results of the search, you can now obtain references to each of the qualifying profiles. The one-based count returned by theCMNewProfileSearch
function identifies the number of profiles in the list. You can use this count to set the bounds of a loop you can define to obtain a profile reference for each qualifying profile. Identifying the index position of a profile in the search result list, you can call theCMSearchGetIndProfile
function repeatedly, incrementing through the list until you obtain references to all of its profiles. The sample code listing in "Searching for Profiles in the ColorSync(TM) Profiles Folder" (page 4-47) shows one approach you can take.The ColorSync Manager preserves the results of a search you perform until you discard the private data structure containing the search result list by calling CMDisposeProfileSearch. If you know that the user has updated the ColorSync
\x89 Profiles folder since you searched it, you can call the CMUpdateProfileSearch
function to update the search result without providing the search specification again.Getting the Names of Qualifying Profiles
After you obtain references to the profiles in the search result list, you must get the names of the profiles so that you can display them in the selection list your user interface provides. You can get the profile names either within your profile reference loop or outside it.When you are finished with the profiles, you must call the
CMCloseProfile
function for each one to dispose of the references and release the memory they use.Setting the Rendering Intent Selected by the User
The ColorSync Manager offers four rendering intents--perceptual, relative colorimetric, saturated, and absolute colorimetric. Every profile supports these. The first three are commonly used to render images matching the colors of a source image to the color gamut of the destination device on which the resulting image is to be rendered in the most optimum way for the type of image.If the source profile is embedded with the image, the source profile specifies the rendering intent to be used. However, if the source profile is not provided and the system profile is used as the source profile, you should allow the user to select the rendering intent to be used.
To allow users to choose the rendering intent most appropriate for color matching their graphical image, you can provide a menu or a dialog box identifying the rendering intent options available. To help your user in choosing the appropriate intent, you can provide meaningful information that identifies the best use of each intent. Users can then select the rendering intent that best maintains important aspects of the image.
Instead of simply listing the available rendering intents by the technical names used to refer to them, you can indicate how they are best used, basing your presentation on this background information:
After the user selects the intent to be used, you must modify the
- For perceptual matching, all the colors of a given gamut may be scaled to fit within another gamut. This intent is the best choice for realistic images, such as scanned photographs.
- For saturation matching, the relative saturation of colors is maintained from gamut to gamut. Rendering the image using this intent gives the strongest colors and is the best choice for bar graphs and pie charts, in which the actual color displayed is less important than its vividness.
- For relative colorimetric matching, the colors that fall within the gamuts of both devices are left unchanged. Some colors in both images will be exactly the same, a useful outcome when colors must match quantitatively. This intent is best suited for logos.
renderingIntent
field of the system profile's header to reflect the choice.To put the rendering intent chosen by the user in the profile header, follow these steps:
You can now use the system profile to create a color world for the color-matching process. For information on how to create a color world, see "Creating a Color World for Color Matching and Checking Using the Low-Level Functions" (page 4-25).
- Obtain a profile reference to the system profile.
"Identifying the Current Default System Profile" (page 4-20) describes how to do this.
- Get the profile header of the system profile.
Passing the profile reference to the function, you can use the
CMGetProfileHeader
function to obtain the profile's header. The function returns the profile header using a union of typeCMAppleProfileHeader
. You can use this function for both ColorSync 1.0 profiles and version 2.x profiles.For a version 2.x profile, you use the
CM2Header
data structure. For a version 1.0 profile, you use theCMHeade
r data structure. For a description of profile headers see "Apple Profile Header" (page 3-42) in Advanced Color Imaging Reference. In the same book, see theCMGetProfileHeader
function (page 3-88).- Assign the new rendering intent to the header field.
To assign a rendering intent to the system profile header's
renderingIntent
field, use the constants defined by the following enumeration:
enum {
cmPerceptual = 0,
cmRelativeColorimetric = 1,
cmSaturation = 2,
cmAbsoluteColorimetric = 3
};- Set the modified profile header of the system profile.
After you assign the rendering intent, you must replace the header by calling the
CMSetProfileHeader
function. You can use theCMSetProfileHeader
function to set a header for a version 1.0 or a version 2.x ColorSync profile. You pass the header you supply in theCMAppleProfileHeader
union, which is described in "Apple Profile Header" (page 3-42) in Advanced Color Imaging Reference.
The profile header is temporarily modified and the rendering intent change is discarded when you call the
CMCloseProfile
function. To preserve the change, you must call theCMUpdateProfile
function.Listing 6-1 (page 6-19) shows how to set the rendering intent for a profile.
Setting the Color-Matching Quality Selected by the User
The ColorSync Manager provides a feature, called the quality flags settings, that controls the quality of the color-matching process in relation to the time required to perform the match. This feature, which is not a standard feature defined by the ICC profile format specification, works by letting you manipulate certain bits of the profile header'sflags
field. There are three quality flag settings: normal, draft, and best. For a description of the profile header'sflags
field, see "ColorSync Manager Reference for Applications and Device Drivers" in Advanced Color Imaging Reference.Normal mode is the default setting. Color matching using draft mode takes the least time and produces the least exact results. Color matching using best mode takes the longest time but produces the finest results.
Users sometimes want to produce review drafts of images quickly before expending the time to produce the best-quality final copy. Your interface can allow them this flexibility by offering a selection menu or dialog box that provides the three options.
After the user selects the color-matching quality, you can use the selection to set the appropriate bits of the source profile's
flags
field. To set the color-matching quality chosen by the user, follow these steps:
- Obtain a profile reference to the source profile.
"Obtaining Profile References" (page 4-16) describes how to do this.
- Get the profile header of the source profile.
Passing the profile reference to the function, you can use the
CMGetProfileHeader
function to obtain the profile's header. The function returns the profile header using a union of typeCMAppleProfileHeader
.- Optionally, test the current setting of the source profile header's flags.
The
flags
field of the source profile header is a long word coded in big-endian notation. Big-endian notation is a means of encoding data in which the first byte within the 16-bit and 32-bit quantities is the most significant. The ICC profile consortium reserves the first 2 bits of the low word for its own use. The least significant 2 bits of the high word constitute the quality flag settings used to specify the quality for the color matching. To evaluate and interpret the current setting of the quality flags bits, you can take these steps, in order:
- Right-shift the 16 bits.
- Mask off the high 14 bits.
- Compare the result with values defined by the following enumeration:
enum { cmNormalMode= 0, cmDraftMode= 1,cmBestMode= 2 };You can now use the source profile to create a color world for the color-matching process. For information on how to create a color world, see "Creating a Color World for Color Matching and Checking Using the Low-Level Functions."
- Set the quality flags bits to the value your user selected.
To set the quality flag, you can use the constants defined by the enumeration provided by the ColorSync Manager and shown in step 3.
- Set the source profile with the modified profile header.
After you set the
flags
field based on the user's selection, you must replace the header by calling theCMSetProfileHeader
function. You use theCMSetProfileHeader
function to set the header. You pass the header you supply in theCMAppleProfileHeader
union, which is described in "ColorSync Manager Reference for Applications and Device Drivers" in Advanced Color Imaging Reference.
The profile header is temporarily modified and the
flags
field change is discarded when you call theCMCloseProfile
function. To preserve the change, you must call theCMUpdateProfile
function.Listing 6-1 shows how to set the system profile's quality flag to best mode for producing the highest-quality color-matched image, and shows how to set the rendering intent to saturation before setting up a color world based on the modified system profile and the printer profile.
The
MySetHeader
function shown in Listing 6-1 initializes theCMProfileRef
data structures it will use for the system profile and the printer profile before it calls the following two functions--the ColorSync ManagerCMGetSystemProfile
function to obtain a reference to the system profile and its ownMyGetPrinterProfile
function to obtain a reference to the profile for its printer.The source profile--in this case, the system profile--not the printer profile, determines the quality mode and the rendering intent to be used in color matching the image to the destination printer. Now that it has a reference to the system profile, the code can obtain the profile's header. It does this by calling the
CMGetProfileHeader
function, specifying the reference it obtained to the system profile.Using the
kSpeedAndQualityFlagMask
constant it defined earlier, the code clears the quality mode bits of the system profile'sflags
field. Then it sets the quality mode bits tocmBestMode
to specify best mode quality for color matching. The least significant 2 bits of theflags
field's high word constitute the quality flag. After setting the quality flag, the code sets the system profile header'srenderingIntent
field tocmSaturation.
Now that the code has modified the system profile's header to indicate the user's selections, it calls the
CMSetProfileHeader
function to write the profile header to the profile. Because the driver code intends to use the values the user selected only to color match the image in the user's document to be printed, it does not permanently preserve the header field changes. When the code closes its reference to the system profile after having built the color world, the system profile's header modifications are discarded. To write the changes to the profile to preserve them, the code must include a call to theCMUpdateProfile
function.Using the temporarily modified system profile, the code calls the
NCWNewColorWorld
function to create the color world, closes its references to both the system and printer profiles, and color matches the image before sending it to the printer. When it no longer needs the color world, the code calls theCWDisposeColorWorld
function to close the color world and release the memory it uses. Finally, the code tests to ensure that the profile references are closed.Listing 6-1 Modifying the system profile header's quality flag and setting the header
#include <Types.h> #include <CMApplication.h> #include <stdio.h> #include <assert.h> #define kMajorVersionMask0XFF000000 void MySetHeader(void); CMError MyGetPrinterProfile(CMProfileRef *printerProf); /* for CM2Header.profileVersion */ #define kMajorVersionMask 0XFF000000 /* two bits used to specify speed & quality; must be shifted left 16 bits in flag's long word */ #define kSpeedAndQualityFlagMask 0X00000003 void MySetHeader(void) { CMError cmErr; CMProfileRef sysProf; CMAppleProfileHeader sysHeader; CMProfileRef printerProf; CMWorldRef cw; sysProf= NULL; printerProf= NULL; cw = NULL; cmErr = CMGetSystemProfile(&sysProf); if (cmErr == noErr) { cmErr = MyGetPrinterProfile(&printerProf); } if (cmErr == noErr) { cmErr = CMGetProfileHeader(sysProf, &sysHeader); } if (cmErr == noErr) { sysHeader.cm2.flags&= ~(kSpeedAndQualityFlagMask << 16); sysHeader.cm2.flags|= (cmBestMode << 16); sysHeader.cm2.renderingIntent = cmSaturation; cmErr = CMSetProfileHeader(sysProf, &sysHeader); } if (cmErr == noErr) { cmErr = NCWNewColorWorld(&cw, sysProf, printerProf); (void) MyCMCloseProfile(sysProf); sysProf = NULL; (void) CMCloseProfile(printerProf); printerProf = NULL; } . . . /* device-driver functions that use the color world to color match the image and send it to the printer belong here */ . . . if (cw != NULL) { CWDisposeColorWorld(cw); } /* close open profiles in case of error */ if (sysProf != NULL) { (void) CMCloseProfile(sysProf); } if (printerProf != NULL) { (void) CMCloseProfile(printerProf); } }