DEVICE-INDEPENDENT BITMAP (DIB) VERSION 3.0 This topic describes the graphics-file formats used by the Microsoft Windows operating system. Graphics files include bitmap files, icon-resource files, and cursor-resource files. 1.0 IMAGE-RESOURCE FILE FORMAT Windows bitmap files are stored in a device-independent bitmap (DIB) format that allows Windows to display the bitmap on any type of display device. The term "device independent" means that the bitmap specifies pixel color in a form independent of the method used by a display to represent color. The default filename extension of a Windows DIB file is .BMP. 1.1 File Structure Bitmap files are structured as follows: BITMAP FILE HEADER required 14 bytes BITMAP CORE/INFO HEADER required 12 or 40 bytes COLOR MAP DATA optional variable-length IMAGE DATA required variable-length 1.2 Bitmap File Header The file begins with a 14 bytes long file header that contains information about the type, size, and layout of a device-independent bitmap file. The header is structured as follows: CHAR bfType[2]; // Type of file. INT32 bfSize; // Size of the whole file, in bytes. INT16 bfReserved[2]; // Must be set to 0. INT32 bfOffBits; // Offset to the first byte of the image. Here is a discussion of various fields: bfType[2] Specifies the type of file, must be "BM". bfSize Length in bytes of the entire file. bfReserved[] Those two fields are reserved and must be set to 0. bfOffBits Position to the first byte of information of the image, relative to the beginning of the file (byte 0). 1.3 Bitmap Information Header Right after the file header comes the bitmap core header or the bitmap info header depending on the next INT32: INT32 biSize; // Size of the image header, in bytes. If biSize is 12, a bitmap core header should be read (BITMAPCOREHEADER in Microsoft's documentation). If biSize is 40, a bitmap info header should be read (BITMAPINFOHEADER in Microsoft's documentation). According to the official format specifications, biSize is part of both BITMAPCOREHEADER and BITMAPINFOHEADER structures and so, depending on the way you decide to read the content of the file, you may: * Go back 4 bytes and read the appropriate structure again. * Proceed to read all fields that belongs to either field except for biSize. * Store the first bfOffBits bytes of information from the file in a byte buffer, offset and convert your pointer to read the header properly. The bitmap core header is structured as follows: INT32 biSize; // Size of the image header, in bytes (12). INT16 biWidth; // Image width, in pixels. INT16 biHeight; // Image height, in pixels. INT16 biPlanes; // Number of planes. INT16 biBitCount; // Bits per pixel. The bitmap info header is structured as follows: INT32 biSize; // Size of the image header, in bytes (40). INT32 biWidth; // Image width, in pixels. INT32 biHeight; // Image height, in pixels. INT16 biPlanes; // Number of planes. INT16 biBitCount; // Bits per pixel. INT32 biCompression; // Compression type. INT32 biSizeImage; // Size of decompressed image, in bytes. INT32 biXPelsPerMeter; // Horizontal resolution, in pixels/meter. INT32 biYPelsPerMeter; // Vertical resolution, in pixels/meter. INT32 biClrUsed; // Number of colors used. INT32 biClrImportant; // Number of important colors. Here is a discussion of various fields: biSize Size in byte of the image header, including the biSize field. biWidth, biHeight Width and height of the image, in pixels. biPlanes Number of planes, must be 1. biBitCount Number of bits used to store one pixel. This value defines whether the image uses indexed or direct colors. While biBitCount provides the maximum number of colors the image can use, it may not provide the real size of the color map. Value Meaning 1 1 bit per pixel, always 2 colors, indexed image. 4 4 bits per pixel, at most 16 colors, indexed image. 8 8 bits per pixel, at most 256 colors, indexed image. 24 24 bits per pixel, direct color image. biCompression Specifies the type of compression for a compressed bitmap. It can be one of the following values: Value Meaning 0 Specifies that the bitmap is not compressed. 1 Specifies a run-length encoded format for bitmaps with 8 bits per pixel. The compression format is a 2-byte format consisting of a count byte followed by a byte containing a color index. 2 Specifies a run-length encoded format for bitmaps with 4 bits per pixel. The compression format is a 2-byte format consisting of a count byte followed by two word-length color indexes. biSizeImage Specifies the size, in bytes, of the image. It is valid to set this member to zero if the bitmap uses direct color. biXPelsPerMeter, biYPelsPerMeter Specifies the horizontal and vertical resolution, in pixels per meter, of the target device for the bitmap. An application can use this value to select a bitmap from a resource group that best matches the characteristics of the current device. biClrUsed This field contains the number of colors used in the image; For indexed color images (biBitCount is 1, 4 or 8,) this field may contain the number of colors in the color map. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member. biClrImportant Specifies the number of color indexes that are considered important for displaying the bitmap. If this value is zero, all colors are important. Note that colors in the color map should be stored in order of their importance (most to least.) 1.4 Color Map Data The color map only exists if biBitCount is 1, 4, or 8 bits per pixels. The block is at most 256 entries long. The number of colors in the color map is provided by biClrUsed; biClrUsed may be zero if all 256 entries are used. If the file contains a bitmap core header (biSize is 12), each entry is 3 bytes long (referenced as RGBTRIPLE in Microsoft's documentation). The RGBTRIPLE type is defined as follows: CHAR blue; // Blue intensity, 0 to 255. CHAR cGreen; // Red intensity, 0 to 255. CHAR cRed; // Green intensity, 0 to 255. If the file contains a bitmap info header (biSize is 40), each entry is 4 bytes long (referenced as RGBQUAD in Microsoft's documentation). The RGBQUAD type is defined as follows: CHAR cBlue; // Blue intensity, 0 to 255. CHAR cGreen; // Red intensity, 0 to 255. CHAR cRed; // Green intensity, 0 to 255. CHAR reserved; // Alpha channel. 1.5 Image Data The image data is an array of bytes defining the pixels of the bitmap. The bits in the array are packed together, but each scan line must be zero-padded to end on a LONG boundary (4 bytes.) Segment boundaries, however, can appear anywhere in the bitmap. The origin of the bitmap is the lower-left corner. biBitCount 1: Monochrome Color Mapped Bitmap is monochrome and the color table contains two entries. Each bit in the bitmap array represents a pixel. If the bit is clear, the pixel is displayed with the color of the first entry in the color table. If the bit is set, the pixel has the color of the second entry in the table. biBitCount 4: Color Mapped (16 colors max) Each pixel in the bitmap is represented by a 4-bit index into the color table. For example, if a byte has the value 0x1F, the first pixel contains the color in the second table entry and the second pixel contains the color in the sixteenth table entry. biCompression 2: RLE-Encoded 4-bit per pixel This format may be compressed in either of two modes: encoded and absolute. Both modes can occur anywhere throughout a single bitmap. Encoded mode consists of two bytes: the first byte of the pair contains the number of pixels to be drawn using the color indexes in the second byte. The second byte contains two color indexes, one in its high-order nibble (that is, its low-order four bits) and one in its low-order nibble. The first of the pixels is drawn using the color specified by the high-order nibble, the second is drawn using the color in the low-order nibble, the third is drawn with the color in the high-order nibble, and so on, until all the pixels specified by the first byte have been drawn. In addition, the first byte of the pair can be set to zero to indicate an escape that denotes an end of line, end of bitmap, or a delta. The interpretation of the escape depends on the value of the second byte of the pair. The following list shows the meaning of the second byte: Value Meaning 0 End of line. 1 End of bitmap. 2 Delta. The two bytes following the escape contain unsigned values indicating the horizontal and vertical offset of the next pixel from the current position. In absolute mode, the first byte contains zero, the second byte contains the number of color indexes that follow, and subsequent bytes contain color indexes in their high and low-order nibbles, one color index for each pixel. In absolute mode, each run must be aligned on a word boundary. Following is an example of a 4-bit RLE bitmap (the one-digit hexadecimal values in the second column represent a color index for a single pixel): Compressed data Expanded data 03 04 0 4 0 05 06 0 6 0 6 0 00 06 45 56 67 00 4 5 5 6 6 7 04 78 7 8 7 8 00 02 05 01 Move 5 right and 1 down 04 78 7 8 7 8 00 00 End of line 09 1E 1 E 1 E 1 E 1 E 1 00 01 End of RLE bitmap biBitCount 8: Color Mapped (256 colors max) Each pixel in the bitmap is represented by a 1-byte index into the color table. For example, if the first byte in the bitmap is 0x1F, the first pixel has the color of the thirty-second table entry. biCompression 1: RLE-Encoded 8-bit per pixel This format may be compressed in either of two modes: encoded and absolute. Both modes can occur anywhere throughout a single bitmap. Encoded mode consists of two bytes: the first byte specifies the number of consecutive pixels to be drawn using the color index contained in the second byte. The end-of-line, end-of-bitmap, and delta escapes also apply. Absolute mode is signaled by the first byte set to zero and the second byte set to a value between 0x03 and 0xFF. In absolute mode, the second byte represents the number of bytes that follow, each of which contains the color index of a single pixel. When the second byte is set to 2 or less, the escape has the same meaning as in encoded mode. In absolute mode, each run must be aligned on a word boundary. Following is an example of an 8-bit RLE bitmap (the two-digit hexadecimal values in the second column represent a color index for a single pixel): Compressed data Expanded data 03 04 04 04 04 05 06 06 06 06 06 06 00 03 45 56 67 00 45 56 67 02 78 78 78 00 02 05 01 Move 5 right and 1 down 02 78 78 78 00 00 End of line 09 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 00 01 End of RLE bitmap biBitCount 24: direct color Bitmap has a maximum of 2^24 colors. There is no color table and each 3-byte sequence in the bitmap array represents the relative intensities of red, green, and blue, respectively, for a pixel. 2.0 ICON-RESOURCE FILE FORMAT An icon-resource file contains image data for icons used by Windows softwares. The file consists of an icon directory identifying the number and types of icon images in the file, plus one or more icon images. The default filename extension for an icon-resource file is .ICO. 2.1 Icon Directory Each icon-resource file starts with an icon directory. The icon directory, defined as an ICONDIR structure, specifies the number of icons in the resource and the dimensions and color format of each icon image. The ICONDIR structure has the following form: INT16 idReserved; // Reserved, must be 0. INT16 idType; // Resource type. INT16 idCount; // Size of directory, in entries. ICONDIRENTRY idEntries[]; // Each entry (see below). Here is a discussion of various fields: idReserved Reserved, must be zero. idType Specifies the resource type. This member is set to 1 for icons. idCount Specifies the number of entries in the directory. idEntries[] Specifies an array of ICONDIRENTRY structures containing information about individual icons. The idCount member specifies the number of structures in the array. The ICONDIRENTRY structure specifies the dimensions and color format for an icon. The structure has the following form: CHAR bWidth; // Icon width, in pixels. CHAR bHeight; // Icon height, in pixels. CHAR bColorCount; // Number of colors in the icon. CHAR bReserved; // Reserved, must be 0. INT16 wPlanes; // Number of color planes. INT16 wBitCount; // Number of bits in the bitmap. INT32 dwBytesInRes; // Size of the icon image, in bytes. INT32 dwImageOffset; // Offset to the icon image. Here is a discussion of various fields: bWidth, bHeight Specifies the width and height of the icon, in pixels. Acceptable values are 16, 32, and 64. bColorCount Specifies the number of colors in the icon. Acceptable values are 2, 8, and 16. bReserved Reserved, must be zero. wPlanes Specifies the number of color planes in the icon bitmap. wBitCount Specifies the number of bits in the icon bitmap. dwBytesInRes Specifies the size of the resource, in bytes. dwImageOffset Specifies the offset, in bytes, from the beginning of the file to the icon image. 2.2 Icon Image Each icon-resource file contains one icon image for each image identified in the icon directory. An icon image consists of an icon-image header, a color table, an XOR mask, and an AND mask. The icon image has the following form: BITMAPINFOHEADER icHeader; // Bitmap header. RGBQUAD icColors[]; // Color map. CHAR icXOR[]; // XOR mask. CHAR icAND[]; // AND mask. The icon-image header, defined as a BITMAPINFOHEADER structure, specifies the dimensions and color format of the icon bitmap. Only the biSize through biBitCount members and the biSizeImage member are used. All other members (such as biCompression and biClrImportant) must be set to zero. The color table, defined as an array of RGBQUAD structures, specifies the colors used in the XOR mask. As with the color table in a bitmap file, the biBitCount member in the icon-image header determines the number of elements in the array. The XOR mask, immediately following the color table, is an array of BYTE values representing consecutive rows of a bitmap. The bitmap defines the basic shape and color of the icon image. As with the bitmap bits in a bitmap file, the bitmap data in an icon-resource file is organized in scan lines, with each byte representing one or more pixels, as defined by the color format. The AND mask, immediately following the XOR mask, is an array of BYTE values, representing a monochrome bitmap with the same width and height as the XOR mask. The array is organized in scan lines, with each byte representing eight pixels. When Windows draws an icon, it uses the AND and XOR masks to combine the icon image with the pixels already on the display surface. Windows first applies the AND mask by using a bitwise AND operation; this preserves or removes existing pixel color. Windows then applies the XOR mask by using a bitwise XOR operation. This sets the final color for each pixel. 3.0 CURSOR-RESOURCE FILE FORMAT A cursor-resource file contains image data for cursors used by Windows applications. The file consists of a cursor directory identifying the number and types of cursor images in the file, plus one or more cursor images. The default filename extension for a cursor-resource file is .CUR. 3.1 Cursor Directory Each cursor-resource file starts with a cursor directory. The cursor directory, defined as a CURSORDIR structure, specifies the number of cursors in the file and the dimensions and color format of each cursor image. The CURSORDIR structure has the following form: INT16 cdReserved; // Reserved, must be 0. INT16 cdType; // Resource type. INT16 cdCount; // Size of directory, in entries. CURSORDIRENTRY cdEntries[]; // Each entry (see below). Here is a discussion of various fields: cdReserved Reserved, must be zero. cdType Specifies the resource type. This member must be set to 2 for cursors. cdCount Specifies the number of cursors in the file. cdEntries[] Specifies an array of CURSORDIRENTRY structures containing information about individual cursors. The cdCount member specifies the number of structures in the array. A CURSORDIRENTRY structure specifies the dimensions and color format of a cursor image. The structure has the following form: CHAR bWidth; // Cursor width, in pixels. CHAR bHeight; // Cursor height, in pixels. CHAR bColorCount; // Reserved, must be 0. CHAR bReserved; // Reserved, must be 0. INT16 wXHotspot; // Hotspot horizontal coordinate. INT16 wYHotspot; // Hotspot vertical coordinate. INT32 lBytesInRes; // Resource size, in bytes. INT32 dwImageOffset; // Offset to the cursor image. Here is a discussion of various fields: bWidth, bHeight Specifies the width and height of the cursor, in pixels. bColorCount Reserved, must be zero. bReserved Reserved, must be zero. wXHotspot, wYHotspot Points to a pixel in the cursor bitmap that Windows must use to track the cursor active point. lBytesInRes Specifies the size of the resource, in bytes. dwImageOffset Specifies the offset, in bytes, from the start of the file to the cursor image. 3.2 Cursor Image Each cursor-resource file contains one cursor image for each image identified in the cursor directory. A cursor image consists of a cursor-image header, a color table, an XOR mask, and an AND mask. The cursor image has the following form: BITMAPINFOHEADER crHeader; // Bitmap header. RGBQUAD crColors[]; // Color map. CHAR crXOR[]; // XOR mask. CHAR crAND[]; // AND mask. The cursor-image header, defined as a BITMAPINFOHEADER structure, specifies the dimensions and color format of the cursor bitmap. Only the biSize through biBitCount members and the biSizeImage member are used. The biHeight member specifies the combined height of the XOR and AND masks for the cursor. This value is twice the height of the XOR mask. The biPlanes and biBitCount members must be 1. All other members (such as biCompression and biClrImportant) must be set to zero. The color table, defined as an array of RGBQUAD structures, specifies the colors used in the XOR mask. For a cursor image, the table contains exactly two structures, since the biBitCount member in the cursor-image header is always 1. Both XOR and AND masks behave the same way they do in icon images.