Important: The information in this document is obsolete and should not be used for new development.
Matching Colors Using the Low-Level Functions
Using the low-levelCWMatchPixMap
orCWMatchBitmap
ColorSync Manager function, your application can match the colors of a pixel image or a bitmap image to the display's color gamut and display the image 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 your user informed, you can provide a progress-reporting function. For example, your function can display an indicator, such as a thermometer, 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 theCWMatchBitmap
function, you can pass the function a pointer to your callback progress-reporting function and a reference constant containing data, such as the thermometer 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 if you were to name itMyCMBitmapCallBackProc:
pascal Boolean MyCMBitmapCallBackProc (long progress, void *refCon);For a complete description of the progress-reporting function declaration, see MyCMBitmapCallBackProc (page 3-170) in Advanced Color Imaging Reference.To use the
CWMatchPixMap
andCWMatchBitmap
functions, your application must first set up a color world that specifies the profiles involved in the color-matching session. The color world establishes how matching will take place between the profiles. 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). Listing 4-5 shows how to match the colors of a pixel map or a bitmap using the ColorSync Manager low-level functions that take a color world.The ColorSync Manager uses the
PixMap
data type defined by Color QuickDraw. The ColorSync Manager defines and uses thecmBitmap
data type, based on the classic QuickDrawBitmap
data type.Matching the Colors of a Pixel Map to the Display's Color Gamut
Your application can call theCWMatchPixMap
function to match the colors of a pixel image to the display's color gamut using a color world that you have previously created. The color world must be based on the source profile for the device used to create the pixel image and the system profile for the system's display.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'sdataColorSpace
element specifies RGB, you can use theCMGetProfileHeader
function to obtain the profile header. The profile header contains thedataColorSpace
element field. For a pixel image, the display profile'sdataColorSpace
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" (page 4-37). If the source profile is installed in the ColorSync(TM) Profiles folder, your application can display a list of profiles to the user to allow the user to select the appropriate one.
Listing 4-5 shows how to set up a color world for color matching of either a pixel map or a bitmap. After setting up the color world, the
MyMatchImage
function calls theCWMatchPixMap
function to match the pixel map in place.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 thespace
field of the bitmap. You can specify a bitmap image using any of the following data types:cmGraySpace
,cmGrayASpace
,cmRGB16Space
, cmRGB24Space,cmRGB32Space
,cmARGB32Space
,cmCMYK32Space
,cmHSV32Space
,cmHLS32Space
,cmYXY32Space
,cmXYZ32Space
,cmLUV32Space
,cmLAB24Space
,cmLAB32Space
, 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 theimage
field of theCMBitmap
structure. Because theCWMatchBitmap
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 thespace
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. On successful output, ColorSync will change thespace
field of the bitmap based on the color space of the destination profile.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 latter portion of the code in Listing 4-5 shows how to set up a bitmap for the resulting color-matched image before calling the
CWMatchBitmap
function to perform the color matching. TheMyMatchImage
function, depicted in this sample listing, uses the profile of the device that produced the image as the source profile and the system profile as the destination profile.Listing 4-5 Matching the colors of a pixel map or a bitmap using a color world
void MyMatchImage (void) { CMError cmErr; CMProfileRefsourceProf; CMProfileRefsysProf; CMWorldRef cw; CMBitmap bitmap; /* set up a color world */ cmErr = MyGetImageSourceProfile(&sourceProf); if (cmErr == noErr) { cmErr = CMGetSystemProfile(&sysProf); } if (cmErr == noErr) { cmErr = NCWNewColorWorld(&cw, sourceProf, sysProf); /* close profiles after setting up color world */ (void) CMCloseProfile(sourceProf); (void) CMCloseProfile(sysProf); } /* match pixmap */ if (cmErr == noErr) { cmErr = CWMatchPixMap(cw, gpPixMap, (CMBitmapCallBackUPP) NULL, NULL); } /* match CMBitmap */ if (cmErr == noErr) { /* CMBitmaps corresponding to QD 16 & 32 bit/pixel, RGBDirect pixmaps are supported by the ColorSync Manager */ if ((*gpPixMap).pixelType != RGBDirect) { cmErr = paramErr; } } if (cmErr == noErr) { /* set local CMBitmap structure so that it describes the pixmap */ bitmap.image = (*gpPixMap).baseAddr; bitmap.width = (*gpPixMap).bounds.right - (*gpPixMap).bounds.left; bitmap.height = (*gpPixMap).bounds.bottom - (*gpPixMap).bounds.top; /* mask QD rowBytes flag bits */ bitmap.rowBytes = (*gpPixMap).rowBytes & 0x3ffe; switch ((*gpPixMap).pixelSize) { case 16: bitmap.pixelSize = 16; bitmap.space = cmRGB16Space; break; case 32: bitmap.pixelSize = 32; bitmap.space = cmRGB32Space; break; default: cmErr = paramErr; break; } /* CMBitmap fields not used by the ColorSync Manager */ bitmap.user1 = 0; bitmap.user2 = 0; } if (cmErr == noErr) { /* match in place */ cmErr = CWMatchBitmap(cw, &bitmap, (CMBitmapCallBackUPP) NULL, NULL, (CMBitmap*) NULL); /* dispose of the colorworld */ CWDisposeColorWorld(cw); } }