Languages - DevSource
DevSource: Microsoft Developer Resource DevSource Home Sponsored by Microsoft Home Add Ons Architecture Languages Techniques Using VS Forums
Home arrow Languages arrow Bitmaps and Palettes in Unmanaged C++
Bitmaps and Palettes in Unmanaged C++
By Rick Leinecker

Rate This Article: Add This Article To:

Bitmaps and Palettes in Unmanaged C++
( Page 1 of 3 )

Rendering Bitmaps in Visual C++ Can Make Your Applications Much Richer.

In this article, I’ll talk about using bitmaps in unmanaged Visual C++ programs. We’ll cover CBitmap objects, how to load bitmap data, drawing CBitmap objects, and palettes and colors.

At the heart of your computer’s video system is memory. This memory contains data that represent the patterns that appear on the monitor. Every time the mouse moves, a small amount of data in memory changes. You then see the mouse move across the screen. Each and every graphics operation affects video memory as the GDI makes its calculations, and alters video memory in an appropriate way.

ADVERTISEMENT

Bitmaps represent rectangular regions of RAM similar to video memory. At their core is a handle for a chunk of RAM. In terms of the Windows API, this handle is known as an HBITMAP. In this memory resides data that, if moved into video memory, would cause a pattern to appear on the monitor. A good example of this is a desktop icon. Icons are loaded from disk into memory. This memory is then moved into video memory at the appropriate addresses so that when video memory is rendered on the screen by the video hardware, the icon becomes visible.

Bitmaps add graphical objects to the screen in a different way than drawn objects such as lines and ellipses. Lines and ellipses are mathematically calculated, then the pixels in video memory are set in such a way that the object appears. Bitmap data isn’t calculated. The pattern already exists in bitmap memory. It’s simply a matter of copying a block of memory from the bitmap to video memory. Because of this, using bitmaps is preferable to using a series of draw operations when the end result is a complex graphics image. Imagine how many separate operations it would take to draw your photograph on the screen—it may take thousands. By using a bitmap, the complex photographic image can reside in bitmap memory. Then, with a single operation, the bitmap memory can be quickly copied to a region of video memory.

There are two types of bitmap objects. One is wrapped in the MFC CBitmap class. Bitmaps of this type are referred to as device-dependant bitmaps. They can only be drawn successfully on a video system that matches their own configuration. For instance, a device-dependent bitmap that has a color depth of 24 bits per pixel will only draw to a video system that’s 24 bits per pixel. The only exception to this rule is monochrome bitmaps of one bit plane with a color depth of one bit per pixel. These are able to be drawn to video memory of any configuration.

Before we get started, a few words on terminology are in order. In this article, the Windows GDI object known as an HBITMAP is referred to as a bitmap. The MFC class that wraps a bitmap is called a CBitmap object. A logical palette is a Windows GDI object, and we'll call them palettes in this article. The MFC class that wraps a palette is known as a CPalette object. A device independent bitmap such as the kind that make up BMP files will be called a Dib. Dibs can't be found in the Windows API or MFC anywhere as separate items.

Bits Per Pixel

Back when CGA video was the standard, there were four colors to choose from: black, cyan, magenta, and white. (There was another seldom-used variation that produced black, yellow, green, and red.) CGA video memory stores data for each pixel in two contiguous bits. Each byte of video memory contains enough data for four screen pixels. Oddly enough, the data is stored in two banks of memory. The first bank contains data for the odd scanlines, and the second contains data for the even scanlines.

Bit Planes

With the advent of EGA and VGA monitors, the number of possible colors expanded. In EGA/VGA, there are four variables to contend with: the red, blue, and green color bits, and the high/low intensity bit. By combining these four bits, you can create 16 colors (high-intensity green, low-intensity green, high-intensity green and red, and so on). The four variables became known as bit planes. The interesting thing to note for EGA/VGA video memory is that the bits for each of the four color variables reside in different banks of memory. For instance, all of the red memory for an EGA setting of 320x200 resides in a bank of memory of 8000 bytes.

MCGA systems introduced eight bits of information for each pixel. Since the concept of a color plane doesn't describe the capabilities of this type of system, the eight bits of information for each color have become known as the bits-per- pixel value. MCGA video memory contains a single byte for each screen pixel. To get the RGB value with which the video system will render the pixel, a lookup into a palette is used. MCGA palettes have only 256 entries, so MCGA video can only display 256 simultaneous colors.

To determine the actual bit-depth of a given video system, you must check both the bits- per-pixel value and the number of bit planes. You can call the GetDeviceCaps API function with the BITSPIXEL constant to determine the bits-per-pixel value. To determine the number of color planes, you can call the same API function with the PLANES constant.

A simple way to calculate the true bit-depth is to retrieve both of these values and multiply them. This calculation is valid because an EGA/VGA system will return one for the bits-per- pixel value, and a truecolor/highcolor system will return one for the color planes value.

We'll use MFC's CPalette object to perform all of our palette operations. For video adapters with pixel depths of 8 bits or less, effective use of palettes is essential for optimizing the appearance of bitmaps.

Device Independent Bitmaps

The second type of bitmap is a device-independent bitmap (DIB). I hope to write an article on these bitmap types fairly soon, but for now they are not covered in this article. These device independent bitmaps are not wrapped in an MFC class of any kind. The advantage that DIBs have over device-dependent bitmaps is that the DIB’s configuration doesn’t have to match the video configuration for a draw operation to be successful. The bitmap is drawn to the screen taking the configurations of the bitmap and the video into account. For instance, a 24-bit DIB will draw successfully to a video system of 8-, 16-, 24-, and 32-bits per pixel. When there’s a color depth mismatch, a color matching algorithm is used to achieve the best possible match. For instance, a 24-bit DIB that’s drawn to an 8-bit video system will have to reduce to the 256 colors that are available in the video system. When the DIB is drawn to the screen, the color downsizing is done during the draw operation. This doesn’t affect the DIB data that’s in memory. The drawback to this is that performance is greatly reduced. For this reason, if performance is an issue, DIBs should not be used. Instead, device-dependent bitmaps are recommended.



 
 
>>> More Languages Articles          >>> More By Rick Leinecker
 



Microsoft's Future: A Chat With Their CTO, Barry Briggs

Play Video >

All Videos >

Julia explores the Robotics Studio!

Read now >

Messages to Bill Gates!

Read now >

View Now
DevSource RSS FEEDS
XML Want an easy way to keep up with breaking tech news? And the Get DevSource headlines delivered to your desktop with RSS.