Partager via


ColorConverter (Compact 2013)

3/26/2014

The ColorConverter class contains GPE color conversion support.

The base ColorConverter class is defined in the Swconvrt.cpp file. This class enables translation among any combination of source and destination surface pixel types at the time bit blocks are written to the display.

The following table shows the pixel formats for surfaces.

Pixel format

Description

PAL_RGB

Each pixel is an unsigned long of the form 0x00BBGGRR.

This is identical to the PALETTEENTRY structure.

PAL_BGR

Each pixel is an unsigned long of the form 0x00RRGGBB.

This is identical to the RGBQUAD structure.

PAL_MASKED

The RGB channels of each pixel are isolated by using bitmasks to identify which specific bits are used for each channel.

This is most common for formats of 15 and 16 bpp.

PAL_INDEXED

Each pixel contains an index into the current palette for the surface.

Palette entries may be 1, 2, 4, or 8 bits long, depending on how many bits per pixel the display uses.

When display drivers call GPE functions with XLATEOBJ pointer parameters, the functions create and initialize ColorConverter objects to handle any color conversion. Alternatively, based on the value of the XLATEOBJ member iUniq, the functions can use a cached ColorConverter object from a previous call.

The ColorConverter object populates two pointers: pLookup and pConverter:

  • If both are NULL, no conversion is required because the source and destination formats are compatible and palettes, if any, are identical.
  • If pLookup is not NULL, the operation must convert each source pixel to a destination pixel, using the source pixel value as an index into the lookup table.
  • If pConverter is not NULL, it is the address of a function that is called to convert a source pixel to a destination pixel. Use this when source and destination formats are incompatible and the source format is not indexed.

At most, either pLookup or pConverter is set to non-NULL. Even if two palettes contain the same entries, the palettes are not considered to be the same if one palette is mutable and the other is not.

Because color conversion is optional, you can reduce or remove part it, which enables you to reduce the size of the driver. However, if you alter the color conversion, be sure to author all bitmaps to a bit depth or palette that the display driver supports.

The current size of the complete color converter is slightly over 2 kilobytes (KB) when compiled without debugging symbols.

GPE Color Conversion Algorithms

The following table defines the meanings of the surface types used in the descriptions of the color conversion algorithms.

Color Surface Type

Description

Mono       

1 bit per pixel (bpp)

Mono surfaces can only be destination surfaces for color conversions. They can never be source surfaces.

The ColorConverter object sets the flXlate member of the XLATEOBJ structure to XO_TO_MONO when a 1bpp destination surface is to be used as a Mono surface instead of an Indexed surface.

RGB        

Either 24 bpp or 32 bpp

BGR        

Either 24 bpp or 32 bpp

Masked     

Either 16 bpp, 24 bpp, or 32 bpp

Indexed    

Either 1 bpp, 2 bpp, 4 bpp, or 8 bpp

Indexed color values are in the BGR format.

The following color conversion algorithms are used within GPE.

Conversion from any type to Mono

If the source surface's pixel value is the same as the value of XLATEOBJ.pulXlate[0], the pixel value of the destination surface is set to 1, otherwise the destination pixel value is set to 0. The value in XLATEOBJ.pulXlate[0] uses the same pixel format as the source surface.

Conversion from RGB to BGR

Given an RGB source value of srcValue, the following code shows how the red and blue components are swapped to create the BGR destination value dstValue.

unsigned long dstValue = srcValue;
((unsigned char *)(&dstValue))[0] = ((unsigned char *)(&srcValue))[2];
((unsigned char *)(&dstValue))[2] = ((unsigned char *)(&srcValue))[0];

Conversion from RGB to Masked

Given an RGB source value of srcValue, the following code shows the conversion to a Masked value of dstValue.

unsigned long dstValue =
  ((( srcValue << 24 ) >> anDstShift[0] ) & aDstMask[0] ) |
  ((( srcValue << 16 ) >> anDstShift[1] ) & aDstMask[1] ) |
  ((( srcValue << 8  ) >> anDstShift[2] ) & aDstMask[2] );

Conversion from RGB to Indexed

If the source value is an RGB value, then the RGB value is converted to BGR and the BGR value is converted to Indexed.

Conversion from BGR to RGB

Given a BGR source value of srcValue, the following code shows how the red and blue components are swapped to create the RGB destination value dstValue.

unsigned long dstValue = srcValue;
((unsigned char *)(&dstValue))[0] = ((unsigned char *)(&srcValue))[2];
((unsigned char *)(&dstValue))[2] = ((unsigned char *)(&srcValue))[0];

Conversion from BGR to Indexed

The ColorConverter object converts a BGR source values of srcValue to an Indexed destination value of dstValue by finding the color in the destination surface's color table that minimizes the following error function:

RGBError = sqrt( ( srcValue.Red - dstValue.Red )^2
               + ( srcValue.Green - dstValue.Green )^2
               + ( srcValue.Blue - dstValue.Blue )^2 )

Conversion from BGR to Masked

Given a BGR source value of srcValue, the following code shows the conversion to a Masked value of dstValue.

unsigned long dstValue =
  ((( srcValue << 8  ) >> anDstShift[0] ) & aDstMask[0] ) |
  ((( srcValue << 16 ) >> anDstShift[1] ) & aDstMask[1] ) |
  ((( srcValue << 24 ) >> anDstShift[2] ) & aDstMask[2] );

Conversion from Indexed to BGR

If the source value is an index in the color table, then the BGR value of that color is read directly from the color table.

Conversion from Indexed to RGB

If the source value is an index in the color table, then the BGR value of the color is read directly from the table and then converted from BGR to RBG.

Conversion from Indexed to Masked

If the source value is an index in the color table, then the BGR value of the color is read directly from the table and then converted from BGR to Masked.

Conversion from Indexed to Indexed

If the source value is an index in the color table, then the BGR value of the color is read directly from the table and then converted from BGR to Indexed.

Conversion from Masked to RGB

Given a Masked source value of srcValue, the following code shows the conversion to an RGB value of dstValue.

unsigned long ulRed   = (srcValue & aSrcMask[0]) << anSrcShift[0];
unsigned long ulGreen = (srcValue & aSrcMask[1]) << anSrcShift[1];
unsigned long ulBlue  = (srcValue & aSrcMask[2]) << anSrcShift[2];

ulRed   |= ulRed   >> anSrcBits[0];
ulGreen |= ulGreen >> anSrcBits[1];
ulBlue  |= ulBlue  >> anSrcBits[2];

unsigned long dstValue =
  ((ulRed   >> 24)) |
  ((ulGreen >> 16) & 0x0000ff00) |
  ((ulBlue  >>  8) & 0x00ff0000);

Conversion from Masked to BGR

Given a Masked source value of srcValue, the following code shows the conversion to an RGB value of dstValue.

unsigned long ulRed   = (srcValue & aSrcMask[0]) << anSrcShift[0];
unsigned long ulGreen = (srcValue & aSrcMask[1]) << anSrcShift[1];
unsigned long ulBlue  = (srcValue & aSrcMask[2]) << anSrcShift[2];

ulRed   |= ulRed   >> anSrcBits[0];
ulGreen |= ulGreen >> anSrcBits[1];
ulBlue  |= ulBlue  >> anSrcBits[2];

unsigned long dstValue =
  ((ulRed   >>  8) & 0x00ff0000) | 
  ((ulGreen >> 16) & 0x0000ff00) |
  ((ulBlue  >> 24));

Conversion from Masked to Masked

Given a Masked source value of srcValue, the following code shows the conversion to a Masked value of dstValue.

unsigned long ulRed   = (maskedSrc & aSrcMask[0]) << anSrcShift[0];
unsigned long ulGreen = (maskedSrc & aSrcMask[1]) << anSrcShift[1];
unsigned long ulBlue  = (maskedSrc & aSrcMask[2]) << anSrcShift[2];

ulRed   |= ulRed   >> anSrcBits[0];
ulGreen |= ulGreen >> anSrcBits[1];
ulBlue  |= ulBlue  >> anSrcBits[2];

unsigned long dstValue =
  ((ulRed   >> anDstShift[0]) & aDstMask[0]) |
  ((ulGreen >> anDstShift[1]) & aDstMask[1]) | 
  ((ulBlue  >> anDstShift[2]) & aDstMask[2]);

Conversion from Masked to Indexed

If the source value is a Masked value, then the Masked value is converted to BGR and the BGR value is converted to Indexed.

See Also

Reference

GPE Base Classes