Palettes in Windows
Introduction:
This text gives an overview about how Windows handles color palettes in the 8-bit (256 colors) display mode.
8-Bit mode means that a maximum of 256 different colors can be displayed at any time. This restriction applies for the
whole screen. A color value in a palette consists of three bytes: one for the red component, one for green and one for the blue. This
method of encoding colors(RGB) allows a range of 16,7 millions different colors, however in 8-bit display mode only
256 can be displayed simultaneously. The 8-Bit display mode uses palettes to display the 256 colors. A bitmap that
uses
a palette doesn't contain a three-byte-value for every pixel describing the absolute RGB-value for this pixel (like in
true-color pictures) but rather a one-byte-pointer to a palette-entry. This palette entry contains the absolute RGB-value. This display mode
(using palettes) has the disadvantage that
conflicts between different images that are using different palettes can come up. For example if your desktop
picture is a photo of the mercury-surface and you are editing a photo of a beach in a window that doesn't take up the
whole screen, then the mercury-image will be displayed using the palette of the beach-photo. This happens because
the system can only display 256 colors at a time on the whole screen and the palette of the beach-photo is used
because it has higher priority (it is the window which currently is on top). But using bitmaps with palettes has some
advantages too, for example: you can use palettes for some tricks, for example to change the colors of an image very fast (see
Palette-Animation).
Different types of palettes:
Basically there are two different types of palettes: logical palettes and the system palette.
A logical palette is stored in the memory and belongs to a DIB (Device Independent
Bitmap). If there is a logical palette somewhere in your memory, it was probably loaded from a .bmp-file (which contains a
DIB) or maybe just created for a new image (this happens every time, you create a new 256-color bitmap in an
image-editing program). The only limit for the number of logical palettes is the amount of memory available.
The system palette (or hardware palette) contains 236 colors of the palette(s) with the highest priority (explained below),
as well as 20 reserved entries, that windows uses to draw windows, buttons,... Every
DDB (Device Dependent Bitmap) that is currently displayed has to use the colors of the
system palette. There only exists the system palette, which is managed by Windows itself. The programmer only
has in so far influence on the system palette as he tells Windows which (logical) palette to insert into the system
palette.
A special form of a logical palette is an identity palette. An identity palette contains the 20 reserved colors at the same
positions as the system palette does (details). In the other 236 entries the identity
palette contains the colors that its associated DIB uses. Using an identity palette has the advantage that the reserved
colors con also be used in the bitmap. However, using an identity palette only makes sense if the bitmap is displayed
in 256-colors display mode because in this mode there are only 236 bitmap-specific colors possible. When a bitmap
will be displayed in truecolor mode then it will probably be wiser to use a palette with 256 bitmap-specific
colors.
Palette-Management
Normally there are many logical palettes stored in the memory. Every logical palette belongs to a special bitmap or
window. To provide the greatest reconciliation possible between all those different windows, bitmaps and palettes,
there is this important rule: The window which currently has the focus also has the
privilege to be the first to map colors into the system palette. If this window doesn't use a palette or doesn't fill all the
236 entries available than this privilege is passed to the next window along the z-axis (the window which is the
second from top). This process is repeated as long as either the system palette is filled or every window had its
chance to map colors into the system palette. For every logical palette mapped to the system palette a
foreground-mapping is created. This foreground-mapping is nothing more than a table which can be used to
convert color indexes from the logical palette it belongs to into the color indexes of the (current) system palette. The
foreground-mapping provides the index in the system palette for every entry in the logical palette. For the windows
that couldn't map their colors to the system palette, the nearest matching colors in the system palette are assigned
to the colors in the logical palette.
If a DIB (which pixel values point to entries of its logical palette) is displayed on the screen, it must be converted to a
DDB (which pixel values point to entries of the current system palette). The foreground-mapping is used to convert the
pixel values. Note that this only applies to the 256-colors display mode. In truecolor display mode the pixel values do
not have to be converted because they can be displayed using their literal RGB values and not pointers to the system
palette.
Palette-Management API functions
There are not very much API palette functions, however four of them are rather important: AnimatePalette (see the text
Palette Animation for further discussion of AnimatePalette), CreatePalette, SelectPalette and RealizePalette.
For further explanation of the following functions see your API documentation.
The function CreatePalette is used to create a logical palette from a LOGPALETTE structure. The return value is the handle of the logical palette.
HPALETTE CreatePalette(lplogpal)
- const LOGPALETTE FAR* lplogpal
- this parameter is a pointer to the LOGPALETTE structure which contains the neccesary information to build a logical palette
The function SelectPalette is the SelectObject aequivalent for palettes. It selects the given logical palette
into the given device context and replaces the previous palette (in this device context). Note that you must use
SelectPalette to select a palette into a device context, SelectObject with a palette won't work. The return
value of SelectPalette is the handle of the previously selected palette in this device context.
HPALETTE SelectPalette(hdc, hpal, fPalBack)
- HDC hdc
- specifies the device context in which the logical palette is to be selected
- HPALETTE hpal
- specifies the logical palette to be selected (into hdc)
- BOOL fPalBack
- specifies if the palette should always be a background palette. In (nearly) all cases you will set this value to false.
The function RealizePalette maps the entries of the current logical palette of the given device context into the
system palette like described above).
UINT RealizePalette(HDC hdc)
- HDC hdc
- specifies the device context which contains the logical palette that is to be mapped to the system palette
To use a palette in the 256-color display mode, the first step is always to fill a LOGPALETTE stucture. Usually you will do
this by loading a color table from a .bmp-file. The second step is to create a logical palette using the data from the
LOGPALETTE structure and the function CreatePalette. Then you have to select the recently created logical
palette into a device context (using SelectPalette). At last you map the entries of the logical palette to the
system palette (using RealizePalette). Then you are able to use the colors from your logical palette.
Back to the main page
Copyright 1998 Stefan Hetzl. If you have questions or comments or have discovered an error,
send mail to hetzl@teleweb.at. You may forward this document or publish it on
your webpage as long as you don't change it and leave this notice at the end.
');
document.write('');
// document.write('');
document.write('');
document.write('');
if (document.cookie.indexOf('fcseenpop') == -1) {
pop_domain = document.domain.substring(document.domain.indexOf('.'));
expiry_date = new Date(new Date().getTime() + 86400000).toGMTString(); // 24 hours
document.write('');
document.cookie = 'fcseenpop=1; path=/; domain=' + pop_domain + '; expires=' + expiry_date;
}
}
}
// -->