PATHMac OS 8 Developer Documentation > Mutlimedia and Graphics > ColorSync Manager >

Managing Color With ColorSync


Matching Colors Using the General Purpose Functions

When Color Matching Occurs describes both general purpose and QuickDraw-specific ColorSync functions for color matching. Using the general purpose functions CWMatchPixMap or CWMatchBitmap , your application can match the colors of a pixel image or a bitmap image to the display's color gamut without relying on QuickDraw.

Color matching occurs relatively quickly, but for a session involving a large pixel image or bitmap image, the color-matching process may take some time. To keep the user informed, you can provide a progress-reporting function. For example, your function can display an indicator, such as a progress bar, to depict how much of the matching has been done and how much remains. Your function can also allow the user to interrupt the color-matching process.

When your application calls either the CWMatchPixMap function or the CWMatchBitmap function, you can pass the function a pointer to your callback progress-reporting function and a reference constant containing data, such as the progress bar dialog box's window reference. When the CMM used to match the colors calls your progress-reporting function, it passes the reference constant to it. If you provide a progress-reporting function, here is how you should declare the function, assuming you name it MyCMBitmapCallBackProc:

pascal Boolean MyCMBitmapCallBackProc (long progress, void *refCon);

For a complete description of the progress-reporting function declaration, see MyCMBitmapCallBackProc.

To use the CWMatchPixMap and CWMatchBitmap functions, your application must first set up a color world that specifies the profiles involved in the color-matching session as described in Creating a Color World to Use With the General Purpose Functions . The color world establishes how matching will take place between the profiles. Listing 3-7 shows how to match the colors of a bitmap using the general purpose functions that take a color world.

The ColorSync Manager uses the PixMap data type defined by Color QuickDraw. The ColorSync Manager defines and uses the cmBitmap data type, based on the classic QuickDraw Bitmap data type.

Matching the Colors of a Pixel Map to the Display's Color Gamut

Your application can call the function CWMatchPixMap to match the colors of a pixel image to the display's color gamut. To use CWMatchPixMap , you first create a color world, as described in Creating a Color World to Use With the General Purpose Functions . The color world is based on the source profile for the device used to create the pixel image and the destination profile for the display on which the image is shown.

To match the colors of a pixel image to the display's color gamut, the source profile for the color world must specify a data color space of RGB as its dataColorSpace element value to correspond to the pixel map data type, which is implicitly RGB. If the source profile you specify for the color world is the original source profile used to create the pixel image, most likely these values match. However, if you want to verify that the source profile's dataColorSpace element specifies RGB, you can use the CMGetProfileHeader function to obtain the profile header. The profile header contains the dataColorSpace element field. For a pixel image, the display profile's dataColorSpace element must also be set to RGB; this is the color space commonly used for displays.

If the source profile is embedded in the document containing the pixel map, your application can extract the profile and open a reference to it before you create the color world. For information on how to extract an embedded profile, see Extracting Profiles Embedded in Pictures . If the source profile is installed in the ColorSync Profiles folder, your application can display a list of profiles to the user to allow the user to select the appropriate one.

Matching the Colors of a Bitmap Image to the Display's Color Gamut

Matching the colors of a bitmap image to the current system's display is similar to the process of matching a pixel map's colors, except that the data type of a bitmap image is explicitly stated in the space field of the bitmap. You can specify a bitmap image using any of the following data types: cmGraySpace , cmGrayASpace , cmRGB16Space , cmRGB24Space, cmRGB32Space , cmARGB32Space , cmRGB48Space , cmCMYK32Space , cmCMYK64Space , cmHSV32Space , cmHLS32Space , cmYXY32Space , cmXYZ32Space , cmLUV32Space , cmLAB24Space , cmLab32Space , cmLAB48Space , cmNamedIndexed32Space, cmMCFive8Space, cmMCSix8Space, cmMCSeven8Space, or cmMCEight8Space. The data type of the source bitmap image must correspond to the data color space specified by the color world's source profile.

When you call the CWMatchBitmap function, you can pass it a pointer to a bitmap to hold the resulting image. In this case, you must allocate the pixel buffer pointed to by the image field of the CMBitmap structure. Because the CWMatchBitmap function allows you to specify a separate bitmap to hold the resulting color-matched image, you must ensure that the data type you specify in the space field of the resulting bitmap matches the destination's color data space. On input, the color space of the source profile must match the color space of the bitmap. If you specify NULL for the destination bitmap, on successful output, ColorSync will change the space field of the source bitmap to reflect the bitmap space to which the source image was mapped.

Rather than create a bitmap for the color-matched image, you can match the bitmap in place. To do so, you specify NULL instead of passing a pointer to a resulting bitmap.

The code in Listing 3-7 shows how to set up a bitmap for the resulting color-matched image before calling the CWMatchBitmap function to perform the color matching. The MyMatchImage function calls the MyGetImageProfile function (not shown) to obtain an embedded profile from the image. If none is found, it calls the MyGetImageSpace function (also not shown) to determine the color space for the profile, then calls the ColorSync routine CMGetDefaultProfileBySpace to obtain the default profile for that space.

The MyMatchImage function then calls GetProfileForMainDisplay, shown in Listing 3-5 , to get the destination profile. It uses the source and destination profiles to set up a color world by calling NCWNewColorWorld , then uses the resulting color world when it calls CWMatchBitmap to match the colors to the display.

Listing 3-7 Matching the colors of a bitmap using a color world

void MyMatchImage (FSSpec theImage)
{
    CMError         theErr;
    CMProfileRef    sourceProf;
    CMProfileRef    destProf;
    CMWorldRef      cw;
    CMBitmap        bitmap;
    OSType          theSpace;
    
    /* Init for error handling. If any error during process,
        jump to cleanup area and quit trying. */
    theErr = noErr;
    sourceProf = nil;
    destProf = nil;
    cw = nil;
    bitmap.image = nil;
    
    // Determine source profile.
    // 1st - try to find an embedded profile
    theErr = MyGetImageProfile(theImage, &sourceProf);
    if (theErr == noErr)
    {
        // 2nd - use default profile for the image space
        theErr = MyGetImageSpace(theSpace, &sourceProf);
        require(theErr == noErr, cleanup);
        
        theErr = CMGetDefaultProfileBySpace(theSpace, &sourceProf);
        require(theErr == noErr, cleanup);
    }
    require(theErr == noErr, cleanup);
    
    // Determine dest profile.
    theErr = GetProfileForMainDisplay(&destProf);
    require(theErr == noErr, cleanup);
    
    // Set up a color world.
    theErr = NCWNewColorWorld(&cw, sourceProf, destProf);
    require(theErr == noErr, cleanup);
        
    // close profiles after setting up color world.
    if (sourceProf)
        CMCloseProfile(sourceProf);
    if (destProf)
        CMCloseProfile(destProf);
    sourceProf = destProf = nil;
    
    // Read the image into the CMBitmap structure
    theErr = MyGetImageBitmap(theImage, &bitmap);
    require(theErr == noErr, cleanup);
    
    // Match bitmap in place.
    theErr = CWMatchBitmap(cw, &bitmap, nil, nil, nil);
    require(theErr == noErr, cleanup);
    
    // Render results here ... (code not shown)
    
/* Do any necessary cleanup:close profiles and dispose of
    color world and bitmap. */
cleanup:
    
    if (sourceProf)
        CMCloseProfile(sourceProf);
    if (destProf)
        CMCloseProfile(destProf);
    if (cw)
        CWDisposeColorWorld(cw);
    if (bitmap.image)
        DisposePtr(bitmap.image);
    
    return theErr;
}

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