This page describes the background of how images and graphics are displayed in a Windows environment.It talks about the different colour modes and how colour palettes are used. It does not describe Direct 3D or other 3D-Acceleration software.
To truly represent a colour, 24 bits are used : 8 bits each for the amount of red, green and blue in the colour. The value indicates the intensity of the colour : 0 for nothing, 255 for maximum intensity.
A bitmap image consists of a series of pixel values, where each pixel represents a dot on the screen. The value of each pixel determines the colour of the corresponding dot. The video card interprets the pixel values so that it can show a dot of the right colour in the right position.
Bitmap images that use all 24 bits for each pixel can be large and slow to display, because of the size of the data. 24 bits means 3 bytes for each pixel. A 400 by 300 image, for example, would be 360K bytes in size, and to display that image all the bytes have to be copied around. Usually though, bitmap images can get away with only using 1 or 2 bytes for each pixel.
When using 2 bytes for each pixel, each primary colour (red, green, blue) is represented by only 5 bits instead of 8 bits. This means that small differences in colour cannot be represented, but for most images, there is very little difference.
When using 1 byte for each pixel, a different approach is taken. One byte (8 bits) only allows 256 different values, so instead of the value directly representing a colour, it refers to a table of 24-bit colours. To display each pixel, its value is used to look up the corresponding 24-bit colour in the image's colour table. This technique limits the whole bitmap to only 256 different colours. Images that use 2 bytes for each pixel can have 65K different colours, and those that use 3 bytes (the full 24 bits) can have 16M different colours.
A 256-colour '.bmp' file containing a displayable image consists of three
main parts :
The 'colour-depth' dictates the size of each pixel. For 256-colour bitmap images, each pixel is 8 bits long i.e. one byte per pixel. The value of each pixel is an index into the table of colours.
The table of colours is a list of colours used in the image, and contains up to 256 entries. Each entry in the table is a 24 bit colour value.
When displaying the image, the colour table is used to convert each pixel value to its associated colour.
Nowadays, most PCs and video cards work fine in 65K or 16M colour mode. The mode indicates how many bits are used by the video card for each pixel.
16M colour mode is also known as true colour mode, and assumes 24 bits (3 bytes) for each pixel. The screen can display a range of 16M different colours.
65K colour mode is also known as high colour mode, and assumes 16 bits (2 bytes) for each pixel. The screen can display a range of 65K different colours.
256 colour mode assumes just 8 bits (1 byte) for each pixel. The screen can only display 256 different colours. This causes difficulties when you want to display multiple bitmaps and the combined number of colours is more than 256. You have to cope with this by manipulating palettes, discussed next. It will be a relief when nobody uses 256-colour mode anymore, because then programs will not have to worry about palettes.
When in '256 colour' mode, a list is kept of the 256 different colours that can currently be displayed. This list of possible colours is referred to as a 'palette'. Therefore, a palette contains 256 entries where each entry defines a 24 bit colour.
When a bitmap image is to be displayed on the screen, the image's colours must be matched to the colours in the palette. The image's range of colours and the palette's range may not be the same. One approach is to match each image colour with the closest matching colour in the palette, without changing the palette. Another approach is to change the palette to contain the image's colours, before displaying the image. Changing the palette alters the set of 256 colours that can be displayed on the screen.
If there are other images on the screen, altering the palette may mean that some colours can no longer be displayed. Affected images will need to be displayed again by rematching their colours with the new set of colours in the palette. This is because when in 256 colour mode, the video device driver stores pixels for the whole screen image as 8-bit values. Each pixel value is an index into the palette, i.e. the list of 256 24-bit colours. Changing the 24-bit colour associated with an entry in the hardware palette will immediately affect all pixels on the screen that refer to that entry. They will all change colour, and probably look very weird! This action can sometimes be seen when using Windows to display images : other images' colours seem to change to random values before snapping back to correct colours. What is happening is that first the hardware palette is being altered to suit the new image, then the other images are being rematched with the new hardware palette to get the closest colours before being redisplayed.
There are actually several colour palettes involved when trying to display a bitmap image. Each palette has a slightly different purpose.
A table of the colours currently displayable on the screen. This table is kept in the video card. Windows presents images to the video card as 8-bit pixel values, where each value is an index into the hardware palette.
A copy of the hardware palette. Windows keeps a copy of the current hardware palette so that it knows the actual range of displayable colours and can work out how to convert pixels that use other palettes to the correct values.
Each program that wants to display 256-colour images creates and uses one or more logical palettes, representing the colours that the program would like to use. These colours will not necessarily be the same as the colours in the system and hardware palette, so Windows works out how best to match colours in a logical palette with those in the system palette.
Windows ".bmp" files contain 256-colour images have a set of pixels and a colour table. The colour table is effectively a palette for the image.
Windows does a large amount of processing to display a 256-colour image.
The steps involved for each pixel are :
When all the pixels have been converted, the area where they have been stored
is copied to the video driver so that the image can be displayed.
As images can contain tens or hundreds of thousands of pixels, there is a lot of processing to be done before the image gets onto the screen.
Programs are responsible for creating the logical palettes, and for filling in the colours they wish to use. For example, this can be based directly on the colour table associated with an image in a file, or a combination of images' colour tables if the program wants to display more than one image.
Creating a logical palette does not affect the system and hardware palettes.
Before an image can be displayed, Windows needs to work out the system palette indices that correspond to each logical palette entry. A program gets Windows to do this by using two Windows routines, 'SelectPalette' and 'RealizePalette'.
The 'SelectPalette' routine works out the mapping from logical palette colours to the system palette colours. The mapping is actually stored as a hidden part of the logical palette.
'SelectPalette' can change or add colours to the system palette.
If a logical palette is selected as a 'background' palette, Windows will not alter any colours in the system palette that are being used, but may add new colours if there are system palette entries not being used. This means that other displayed images are not affected, but images that will use the logical palette may have to put up with approximate colours if they are not already in the system palette.
If a logical palette is selected as a 'foreground' palette, Windows will update the system palette with all the colours from the logical palette, even if it means overwriting existing system palette colours. Currently displayed images that are affected will have to be redisplayed (to work out the new colour mappings), but images that will use the logical palette will be accurately displayed.
The program that has the current active window should select its logical palette as a 'foreground' palette. Other programs should select 'background' palettes. The reasoning behind this is that the current active window should be displayed as accurately as possible, whereas the other windows need only be shown using approximate colours.
'SelectPalette' can update the system palette, but does not affect the hardware palette. This is where the other routine comes in.
The 'RealizePalette' routine updates the hardware palette using the system palette. This may change the colours associated with the pixels currently displayed. It is the 'RealizePalette' routine that causes the displayed colours to briefly go awry until the affected images are redisplayed.
The 'SelectPalette' and 'RealizePalette' routines are usually called directly after one another, so that any changes to the system palette are immediately reflected in the hardware palette.
When an application calls 'SelectPalette' and 'RealizePalette' to select a foreground palette, Windows actually checks to see if the application is drawing to the current active window or not. If it is not the current active window, the palette will only get selected as a background palette.
When Windows changes the hardware palette (as a result of a 'RealizePalette' call), it sends a 'palette changed' message to all the current programs. It is up to each program to respond to this message and redisplay its images relative to the new system palette.
The system palette and hardware palette almost always contains a fixed set of 20 basic colours.
These are the colours deemed necessary for Windows, that should always be available.
These static colours are :
red green blue Black 0 0 0 Dark Red 128 0 0 Dark Green 0 128 0 Dark Yellow 128 128 0 Dark Blue 0 0 128 Dark Magenta 128 0 128 Dark Cyan 0 128 128 Light Gray 192 192 192 Money Green 192 230 192 Sky Blue 166 202 240 Cream 255 251 240 Gray 160 160 164 Medium Gray 128 128 128 Red 255 0 0 Green 0 255 0 Yellow 255 255 0 Blue 0 0 255 Magenta 255 0 255 Cyan 0 255 255 White 255 255 255
When a program starts, it is given a default logical palette, containing these 20 static colours. If the program does not want to display any colours outside of this range, then it does not have to concern itself with palettes. The default logical palette is sufficient to display the 20 static colours.
However, to display colours outside this range, the program will need to create, select and realize a logical palette.
Static colours are important because they can be displayed correctly without having to select and realize palettes. This is because they are always present in the default palette.
When 'high-colour' or 'true-colour' display modes are used, there is no need for colour palettes, as pixel values directly contain colour values..
'high-colour' mode uses 16 bits for each pixel : 5 bits each for red, green and blue. 24 bit colours are converted to 16 bit by ignoring the least significant 3 bits of each primary colours.
'true-colour' mode uses 24 bits for each pixel : 8 bits each for red, green and blue.
When in high-colour or true-colour mode, 16-bit and 24-bit images can be displayed directly. When displaying 256-colour images, Windows can ignore the logical, system and hardware palettes, because the colour can be derived directly from the image's colour table.
There are a number of techniques that can be used to speed up the process of displaying 256-colour images.
Usually, an image's pixel values are indices to the image's colour table, which is used to get the 24 bit colour associated with the pixel. The colour can then be matched with the logical palette to find the closest matching colour.
If the image's pixels are changed so that they match the logical palette instead of the image's colour table, then the colour matching process can be skipped out. Windows can ignore the image's own colour table, and go straight to the logical palette.
Windows supports this, by allowing an option in the routines that are used to display images, to specify that pixel values are direct logical palette indices.
The system palette and hardware palette are usually identical, but a program's logical palette will not normally be the same as the system palette. Windows needs to create a mapping from the logical palette to the system palette, and use this mapping when displaying images. After working out the logical palette index for each pixel, it needs to be converted to the corresponding system palette index.
If the program makes the logical palette identical with the system palette, then this mapping and conversion step is not required. The logical palette index can be used directly as a system palette index ( and therefore a hardware palette index).
Windows recognizes when the logical and system palettes are identical, and will eliminate the logical-to-system palette mapping and conversion.
A logical palette that is identical to the system palette is sometimes referred to as an 'identity palette'.
If an image's pixels also match the logical palette, then Windows can use the pixel values directly as hardware palette values. No palette mappings are required. This combination is the ideal.
Usually, when displaying an image, the pixels are copied into an area of memory as they get converted to hardware palette index values. Once that step is done, the whole memory area is copied to an area accessible to the video card. This means a whole lot of pixels are getting copied.
Windows allows creation of a special shared memory location, called a "DIB section", that can be more readily accessed by the video driver. This eliminates some of the memory copying that is done in order to display an image.
Using DIB sections speeds up displaying of images for all screen colour modes, not just 256-colour mode.
When these techniques are used in combination, Windows is able to display images simply by directly copying the pixels into the DIB section, for access by the video driver. This eliminates all the mapping and conversion steps. However, the program needs to contain all the code to make use of these techniques!
I am planning to add sample C++ code to my site to demonstrate how to achieve all this.