Color Mapping and Reduction

Palette-based image files usually include a color palette that defines the RGB color values for the image. In most cases, some of these colors will conflict with the Windows system colors (colors 0-9 and 246-255). This section explains how Fastgraph's image file display and creation functions avoid this conflict.

For monochrome and 16-color BMP and PCX files, fg_showbmp(), fg_showpcx(), and fg_loadpcx() always remap the color indices to avoid using the first ten Windows system colors. They do this by adding 10 to each pixel's value. This means 16-color images will use colors 10 to 25 in the logical palette, and monochrome images will use colors 10 and 11. Similarly, fg_makebmp() subtracts 10 from each pixel's value when creating a 16-color BMP file, and masks off all but the low-order bit of each pixel's value when creating a monochrome BMP file. The fg_makepcx() function always creates 256-color PCX files, so no adjustment is needed.

For 256-color BMP, PCX, and flic files, things are more complex. If the image uses more than 236 colors, the image display functions reduce the image to 236 colors (the number of non-system colors). After applying the color reduction, they compact the resulting palette and then add 10 to each pixel's value. For example, assume an image contained pixels of color 0 and 2, but none of color 1 (or that the color 1 pixels were eliminated during the color reduction process). The original color 0 pixels would be remapped to color 10, and the original color 2 pixels would be remapped to color 11. You can disable the color reduction process by specifying FG_KEEPCOLORS in the flags parameter. Disabling color reduction is more efficient when displaying 256-color image files that do not use the Windows system colors.

If you call an image display function with the FG_IGNOREPALETTE flag specified,, the images are displayed using the colors defined in the active logical palette. In this case, no pixel remapping or color reduction occur for 256-color images, so images that use any of the system colors will likely not display in the desired colors. Note that the pixels in monochrome and 16-color BMP and PCX files are always remapped into the range 10 through 25 (10 and 11 for monochrome), so the images are displayed using the logical palette values defined for colors 10 to 25 (10 and 11 for monochrome).

The color reduction algorithm for 256-color images eliminates colors based on their frequency and relative distances apart. It begins by counting the number of pixels in each color. If more than 236 colors are in the image, colors are removed one at a time until the image contains 236 colors. In each pass, the color reduction algorithm finds the two colors nearest to each other. By nearest, we mean the two colors whose RGB components yield the smallest value for the expression

(r2 - r1)2 + (g2 - g1)2 + (b2 - b1)2

among all remaining colors. If two or more color pairs are the same distance apart, we pick the pair containing the color that occurs the least. All pixels of the least frequent color are mapped to the other color in the pair (that is, the nearest color). We repeat this process until the image contains 236 colors.

Once the color reduction process has created a 236-color image, or if the original image did not use more than 236 of the 256 colors, we remap the colors to avoid using the Windows system colors. That means the color-reduced image will use colors 10 to 245. If the original image used less than 236 colors, the new image will use colors 10 to 10+C-1, where C is the number of unique colors. In any case, the image display functions change the logical palette values so they correspond to the colors in the color-reduced image.

You can also apply color reduction manually to any rectangular region of a 256-color virtual buffer using fg_reduce(). This function reduces a 256-color palette to the specified number of colors, and optionally applies an offset to the resulting palette. The fg_reduce() function applies the same color reduction algorithm as the image display functions to the pixels in the clipping region of the active virtual buffer (the clipping region defaults to the entire virtual buffer). On return, the pixels in the clipping region are transformed to the colors defined by the resulting (reduced) palette, but the palette itself is not made active. The fg_reduce() function's first parameter is the offset applied to the resulting palette, between 0 and 255. The second parameter specifies the number of colors desired in the resulting palette, between 1 and 256. The third parameter is a 768-byte array containing the palette's RGB color components, in the same format used with fg_getdacs() and fg_setdacs(). On return, this array will contain the RGB color components for the new palette. For example, the function call

C/C++:

fg_showpcx("MOUSE.PCX",0);

Delphi:

fg_showpcx('MOUSE.PCX'+chr(0),0);

Visual Basic:

Call fg_showpcx(App.Path & "\MOUSE.PCX", 0)

reduces a 256-color image to 236 non-system colors (colors 10 to 245) and is equivalent to the code shown here:

C/C++:

char RGBvalues[768];
fg_pcxpal("MOUSE.PCX",RGBvalues);
fg_showpcx("MOUSE.PCX",FG_KEEPCOLORS);
fg_reduce(10,236,RGBvalues);
fg_setdacs(10,236,&RGBvalues[10*3]);

Delphi:

var
  RGBvalues : array [0..767] of byte;
begin
  fg_pcxpal('MOUSE.PCX'+chr(0),RGBvalues);
  fg_showpcx('MOUSE.PCX'+chr(0),FG_KEEPCOLORS);
  fg_reduce(10,236,RGBvalues);
  fg_setdacs(10,236,RGBvalues[10*3]);

Visual Basic:

Dim RGBvalues(768) As Byte
Call fg_pcxpal("MOUSE.PCX", RGBvalues(0))
Call fg_showpcx(App.Path & "\MOUSE.PCX", FG_KEEPCOLORS)
Call fg_reduce(10, 236, RGBvalues(0))
Call fg_setdacs(10, 236, RGBvalues(10 * 3))

<< Prev

Next >>

Contents
Fastgraph Home Page

 

copyright 2001 Ted Gruber Software, Inc.