PATHDocumentation > Mac OS 8 and 9 > Mutlimedia and Graphics > ColorSync Manager >

Managing Color With ColorSync


Interacting With the User

Using lists and dialog boxes, you can provide choices that influence the color-matching process. For example, you can offer any of the following:

Setting a User-Selected Rendering Intent

The ColorSync Manager supports the four standard rendering intents defined by the ICC--perceptual, relative colorimetric, saturated, and absolute colorimetric. Every profile supports these four intents, which are commonly used to match the colors of a source image to the color gamut of the destination device in the most optimum way for the type of image. These intents are described in detail in Rendering Intents .

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 available and the system profile must be used as the source profile, you should allow the user to select the rendering intent to be used.

Note

Starting with ColorSync 2.5, your application can call CMGetDefaultProfileBySpace to obtain an appropriate source profile for matching, rather than using the default system profile. However, you may still wish to allow the user to specify a rendering intent.

To allow users to choose the rendering intent most appropriate for color matching a graphical image, you can provide a pop-up menu or a dialog box identifying the rendering intent options available. By providing a description of the available rendering intents, you can help a user select the rendering intent that best maintains important aspects of the image.

Color professionals and technically-sophisticated users are likely to be familiar with the ICC terms for rendering intent and the gamut-matching strategies they represent. If your application is aimed at novice users, however, you may prefer to use a simplified terminology based on the typical image content associated with a rendering intent, as described in Table 2-1 . For example, you might note the following:

After the user selects the intent to be used, you must modify the 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:

  1. Obtain a profile reference to the system profile.

    Identifying the Current System Profile describes how to do this.

  2. Get the profile header of the system profile.

    You call the function CMGetProfileHeader , passing the profile reference, to obtain the profile's header. The function returns the profile header using a union of type CMAppleProfileHeader . 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 data structure CM2Header . For a version 1.0 profile, you use the CMHeader data structure. For more information on profile headers, see Profile Header .

  3. 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                             
    };

    These constants are described in Rendering Intent Values for Version 2.x Profiles .

  4. Set the modified profile header of the system profile.

    After you assign the rendering intent, you must replace the header by calling the function CMSetProfileHeader . You can use this function to set a header for a version 1.0 or a version 2.x ColorSync profile. You pass the header using the union CMAppleProfileHeader .

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 to Use With the General Purpose Functions .

IMPORTANT

When you call CMSetProfileHeader , the profile header is modified temporarily. The rendering intent change is discarded when you call the function CMCloseProfile . To preserve the change, you must call the function CMUpdateProfile .

Listing 4-1 includes code that uses the cmSaturation constant to set the rendering intent for a profile.

Setting a User-Selected Color-Matching Quality Flag

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's flags field. There are three quality flag settings: normal, draft, and best. For a description of the profile header's flags field, see Quality Flag Values for Version 2.x Profiles .

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 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:

  1. Obtain a profile reference to the source profile.

    Obtaining Profile References describes how to do this.

  2. Get the profile header of the source profile.

    You call the function CMGetProfileHeader , passing the profile reference, to obtain the profile's header. The function returns the profile header using a union of type CMAppleProfileHeader .

  3. 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 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. The bit definitions for the flags field are shown in Figure 5-1 .

    To evaluate and interpret the current setting of the quality flags bits, you can take these steps, in order:

    • Right-shift by 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
            };

    These constants are described in Flag Mask Definitions for Version 2.x Profiles .

  4. Set the quality flags bits to the user-selected value.

    To set the quality flag, you can use the constants defined by the enumeration provided by the ColorSync Manager and shown in step 3.

  5. 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 the function CMSetProfileHeader . You pass the header using the union CMAppleProfileHeader .

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 to Use With the General Purpose Functions .

IMPORTANT

When you call CMSetProfileHeader , the profile header is modified temporarily. Changes to the flags field are discarded when you call the function CMCloseProfile . To preserve the change, you must call the function CMUpdateProfile .

Listing 4-1 shows how to set the system profile's quality flag to best mode for producing the highest-quality color-matched image. It also sets 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 4-1 initializes the CMProfileRef data structures it will use for the system profile and the printer profile before it calls the following two functions--the ColorSync Manager function CMGetSystemProfile to obtain a reference to the system profile and its own function MyGetPrinterProfile 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 function CMGetProfileHeader , 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's flags field. Then it sets the quality mode bits to cmBestMode to specify best mode quality for color matching. The least significant 2 bits of the flags field's high word constitute the quality flag. After setting the quality flag, the code sets the system profile header's renderingIntent field to cmSaturation .

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 to be printed, it does not permanently preserve the header field changes by calling CMUpdateProfile to write the changes to the profile. When the code closes its reference to the system profile after having built the color world, the system profile's header modifications are discarded.

The code calls the NCWNewColorWorld function, passing the temporarily modified system profile, to create the color world. It then 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 the CWDisposeColorWorld 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 4-1 Modifying a profile header's quality flag and setting the rendering intent

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)
    {
        /* clear the current quality and then set it to best */
        sysHeader.cm2.flags &= ~(kSpeedAndQualityFlagMask << 16);
        sysHeader.cm2.flags |= (cmBestMode << 16);

        /* set rendering intent to saturation */
        sysHeader.cm2.renderingIntent = cmSaturation;
        cmErr = CMSetProfileHeader(sysProf, &sysHeader);
    }

    if (cmErr == noErr)
    {
        cmErr = NCWNewColorWorld(&cw, sysProf, printerProf);
    }

    /* close any open profiles */
    if (sysProf != NULL)
    {
        (void) CMCloseProfile(sysProf);
    }

    if (printerProf != NULL)
    {
        (void) CMCloseProfile(printerProf);
    }
                    .
                    .
                    .
        /* 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);
    }   
}

© 1988-1999 Apple Computer, Inc. — (Last Updated 20 Jan 99)