HOWTO: Get the Color Table of a DIBSection in Windows CE

ID: Q196650

The information in this article applies to:

SUMMARY

The GetDIBColorTable() function is not implemented in Windows CE. This article describes a method that applications can use to implement their own version of the function.

MORE INFORMATION

Windows CE is designed to be lean, so only necessary functions are implemented to reduce the memory footprint of the operating system. For most uses in applications, DIB Sections can be created and used with a single static palette of colors. This palette can be shared throughout the application so it is not necessary to retrieve the colors from the DIB Section.

However, maintaining a palette with the DIB Section may be undesirable. This can be avoided by extracting the colors of the color table from the DIB Section.

How to Retrieve a Palette COLORREF

In a palettized DIB Section, the RGB COLORREF value for a palette entry of a pixel can be retrieved by calling GetPixel() against a memory Device Context (DC) in which the DIB Section has been selected.

To obtain a COLORREF for a specific palette entry, write the palette index into a pixel of the DIB Section via the pointer to the bits. Then, call the GetPixel() function on the memory DC to get a COLORREF for the pixel.

To obtain a full palette, execute a loop for all colors entries in the palette and apply this algorithm for each color index.

The following sample code uses this algorithm:

   /***********************************************************************
     UINT CEGetDIBColorTable( HDC, UINT, UINT, RGBQUAD * )
   
     PARAMETERS:
       HBITMAP - the Device Context in which the DIBSection is selected
       UINT - the index of the first color table entry to retrieve
       UINT - the number of color table entries to retrieve
       RGBQUAD - a buffer large enough to hold the number of RGBQUAD
                 entries requested
   
     RETURNS:
       UINT - the number of colors placed in the buffer
   
   **********************************************************************
   */ 
   UINT CEGetDIBColorTable(
   HDC hdc,
   UINT uStartIndex,
   UINT cEntries,
   RGBQUAD *pColors
   )
   {
       HBITMAP         hDIBSection;
       DIBSECTION      ds;
       DWORD           dwSize;
       UINT            iColor, cColors, TestPixelY;
       BYTE            OldPalIndex;
       LPBYTE          pBits;
       WORD            wIndexMask;
   
       if (pColors == NULL)
           return 0;                       // No place to put them, fail
   
       // Get a description of the DIB Section
       hDIBSection = GetCurrentObject( hdc, OBJ_BITMAP );
       dwSize = GetObject( hDIBSection, sizeof(DIBSECTION), &ds );
   
       if (dwSize != sizeof(DIBSECTION))
           return 0;                      // Must not be a DIBSection, fail
   
       if (ds.dsBmih.biBitCount > 8)
           return 0;                      // Not Palettized, fail
   
       // get the number of colors to return per BITMAPINFOHEADER docs
       if (ds.dsBmih.biClrUsed)
           cColors = ds.dsBmih.biClrUsed;
       else
           cColors = 1 << (ds.dsBmih.biBitCount*ds.dsBmih.biPlanes);
   
       // Create a mask for the palette index bits for 1, 2, 4, and 8 bpp
       wIndexMask = (0xFF << (8 - ds.dsBmih.biBitCount)) & 0x00FF;
   
       // Get the pointer to the image bits
       pBits = (LPBYTE) ds.dsBm.bmBits;
   
       // Initialize the loop variables
       cColors = min( cColors, cEntries );
       OldPalIndex = *pBits;
       if (ds.dsBmih.biHeight > 0 )
           // If button up DIB, pBits points to last row
           TestPixelY = ds.dsBm.bmHeight-1;
       else
           // If top down DIB, pBits points to first row
           TestPixelY = 0;
   
       for (iColor = uStartIndex; iColor < cColors; iColor++)
       {
           COLORREF    rgbColor;
   
           // Set the palette index for the test pixel,
           // modifying only the bits for one pixel
           *pBits = (iColor << (8 - ds.dsBmih.biBitCount)) |
                    (*pBits & ~wIndexMask);
   
           // now get the resulting color
           rgbColor = GetPixel( hdc, 0, TestPixelY );
   
           pColors[iColor - uStartIndex].rgbReserved = 0;
           pColors[iColor - uStartIndex].rgbBlue = GetBValue(rgbColor);
           pColors[iColor - uStartIndex].rgbRed = GetRValue(rgbColor);
           pColors[iColor - uStartIndex].rgbGreen = GetGValue(rgbColor);
   
       }
   
       // Restore the test pixel
       *pBits = OldPalIndex;
   
       return cColors;
   
   }

Additional query words: kbDSupport
Keywords          : kbWinCE200 
Version           : WINDOWS:2.0
Platform          : WINDOWS
Issue type        : kbhowto

Last Reviewed: December 5, 1998