19.4.3 Using a Palette When Drawing Bitmaps

A device-independent bitmap's color table can contain indices into the currently selected logical palette instead of explicit RGB values. (For more information, see Section 19.3.1, “Creating a LOGPALETTE Structure.”) This allows Windows to avoid color matching and can significantly increase the speed with which images are rendered. The ShowDIB code sample demonstrates this by converting its DIB color table into palette indices, as shown in the following example:

lpbi = (VOID FAR *) GlobalLock(hbiCurrent);
if (lpbi->biBitCount != 24) {
    fPalColors = TRUE;

    pw = (WORD FAR *) ((LPSTR) lpbi + lpbi->biSize);

    for (i = 0; i<(int) lpbi->biClrUsed; i++)
        *pw++ = (WORD) i;
}
GlobalUnlock(hbiCurrent);

Note that ShowDIB had already set the biClrUsed member of the BITMAPINFOHEADER structure to the number of colors in the color table.

After converting the DIB color table into palette indices, ShowDIB calls the SetDIBits function with the DIB_PAL_COLORS flag, as shown in the following example:

/* Set the DIB bits to a device-dependent format */

if (lpbi->biHeight != (LONG) SetDIBits(hMemDC,
        hBitmap,
        0,
        (WORD) lpbi->biHeight,
        pBuf,
        (LPBITMAPINFO) lpbi,
        fPalColors ?
        DIB_PAL_COLORS :
        DIB_RGB_COLORS))  {
    ErrMsg("Could not draw DIB scans!");
    GlobalUnlock(hBuf);
    GlobalFree(hBuf);
    GlobalUnlock(hbiCurrent);
    _lclose(fh);
    return;
}

Depending on whether the original device-independent bitmap used 24-bit pixels, ShowDIB sets the wUsage parameter of SetDIBits to DIB_RGB_COLORS (for a 24-bit bitmap) or DIB_PAL_COLORS (for all other bitmaps). DIB_RGB_COLORS instructs Windows to use the color values in the BITMAPINFO color table when setting the bits in the device-dependent memory bitmap. If the wUsage parameter is set to DIB_PAL_COLORS, however, Windows interprets the color table as 16-bit indices into a logical palette and sets the bits in the memory bitmap by using the indicated color values in the logical palette of the current device context.

If the BITMAPINFO color table contains explicit RGB values instead of palette indices, Windows matches those values to the nearest colors in the currently selected logical palette, as though they were palette-relative RGB values.

Note:

If the source and destination device contexts have selected and realized different palettes, the BitBlt function does not properly move bitmap bits to or from a memory device context. In such a case, you must call the GetDIBits function with the wUsage parameter set to DIB_RGB_COLORS to retrieve the bitmap bits from the source bitmap in a device-independent format. You then use the SetDIBits function to set the retrieved bits in the destination bitmap. This ensures that Windows will properly match colors between the two device contexts. BitBlt can successfully move bitmap bits between two screen display contexts, even if they have selected and realized different palettes. The StretchBlt function properly moves bitmap bits between device contexts whether or not they use different palettes.