Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Advanced Color Imaging on the Mac OS /
Chapter 4 - Developing ColorSync-Supportive Applications / Developing Your ColorSync-Supportive Application


Matching Colors Using the Low-Level Functions

Using the low-level CWMatchPixMap or CWMatchBitmap 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 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 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 it MyCMBitmapCallBackProc:

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 and CWMatchBitmap 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 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 CWMatchPixMap 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'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" (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 the CWMatchPixMap 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 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, 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 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. On successful output, ColorSync will change the space 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. The MyMatchImage 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);
   }
}

Previous Book Contents Book Index Next

© Apple Computer, Inc.
13 NOV 1996