A
device-independent bitmap (or DIB) is an
image format used mostly
internally by the
Windows operating system. It allows
GDI to work with and
manipulate an image, regardless of the device
capabilities of the
display device or
driver. The DIB
mechanism is an
abstraction designed to work as a
lossless intermediary step between
device-dependant formats;
essentially, it necessitates only having a converter available to and from
DIB rather than between all the other formats. The term device independent is misleading in that it refers to pixel depth of the output device; if the color depth of a DIB is higher than that of the output device, it will definitely look differently on that device (due to
dithering and other
color approximation processes).
DIBs are also a standard way to pass items between one another in
Windows. One program can pass a
DIB along as a
Windows metafile, across the
clipboard, or in a random
memory segment and still be
guaranteed “display-able” on the
current device. This is very useful for many
programs that need to interact with each other (especially going to a more complicated program, such as
Microsoft Word).
DIBs have been around since
Windows 3.0 for drawing and displaying graphic. Their use however was very limited until
Windows 95, under which many operations opened up, such as being able to actually write to a
DIB, being able to transfer back and forth between
surfaces, etc.
OS/2 also used DIB as an internal format for many of its drawing operations, and (almost surprisingly)
Windows is built to remain compatible with it.
A
DIB structure in
memory stores all of the information necessary to display a
bitmap on any set of
drivers or
device:
color depth,
pixel resolution,
height,
width,
compressing scheme used, etc. There are two different ways DIBs can be
represented in memory in Windows, either through the use of
RGBTRIPLEs or
RGBQUADs.
Windows does not natively use RGBTRIPLEs, except for convenience and backwards-compatibility for working with
OS/2 created images.
RGBTRIPLE DIB Structures:
RGBQUAD DIB Structures:
BITMAPINFO (and its cousin
BITMAPCOREINFO) is a structure that contains a BITMAPINFOHEADER of some type and an array of RGBQUAD structures that define the color table for the current bitmap. The important information is thus contained in the BITMAPINFOHEADER. As it is defined in
wingdi.h
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, *PBITMAPINFOHEADER;
In this slightly confusing Hungarian Notation above, bi* stands for BitmapInfo. As you can see, size is first, as with many other extensible API structures in Windows. This line should always be:
myBitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
This is so that Windows can use the older drawing code to remain compatible with the older
API standards. Many programs rely on the weird quirks of older
engines, so close emulation is largely unacceptable for compatibility. This allows it to switch code for the version it is looking for (provided largely by the compiler). This means the size information is always in the same block when we pass it to the API. Other examples are
WNDCLASSEX (compare with the older
WNDCLASS, before people knew any better) and
WINDOWINFO.
In the structure above,
biHeight and
biWidth are fairly easy to understand,
biPlanes seems to be the number of layers to an object, and according the documentation should always be set to be 1.
biBitCount is the number of bits per pixel. It can be zero (meaning that it is implied by the compression scheme, or it can be 1 (monochrome), 4, 8, 16, 24, or 32. Keep in mind that 32-bit DIBs take up much more space than is probably
necessary to acurately
display a
bitmap.
The next field,
biCompression describes the compression format of the bitmap. Now this goes
somewhat against the "device independent" nature of the
structure, but it implies that
Windows knows how to undo compressed bitmaps of a certain type. Typically you'd work with
uncompressed bitmaps for most small items (backgrounds and the like) and set it to
BI_RGB. Windows 98 and higher allows you to work with items in
PNG or
JPG format for increased convenience.
The next three fields are fairly simple:
biSizeImage describes how many bytes are in the image (if it is compressed; uncompressed items do not need this).
biXPelsPerMeter and
biYPelsPerMeter describe the resolution of the bitmap in terms of
pixels per meter. The final two fields allow a person to optimize a bitmap and its display by shaping the current color ramp into an optimized version. This is a fairly advanced feature, and you can usually get away with setting these items to be zero.
For more information on how to work with a DIB in memory, see
How to create a bitmap in memory in Windows, or the following Windows API calls (which relate to device-independent bitmaps, instead of DC's):
DIBs on disk (.dib or the more common
Windows Bitmap .bmp) are very
simple. They are described by the
BITMAPFILEINFO structure tacked on to the remainder of the DIB (BITMAPHEADERINFO + RGBQUADS for the color table + bitmap info). This simply describes the
file, gives it size, and tells the offset to where the
DIB info lives in the file.
Sources:
An introduction to DIBs : http://www.herdsoft.com/ti/davincie/imex3j8i.htm
MSDN Platform SDK documentation: http://msdn.microsoft.com