Basic windows bitmap format

This article is about the file format. For the data structure/type of image, see Bitmap graphics.

Windows Bitmap

Filename extension

.bmp, .dib

Internet media type image/bmp[1]
image/x-bmp
Type code 'BMP '
'BMPf'
'BMPp'
Uniform Type Identifier (UTI) com.microsoft.bmp
Developed by Microsoft Corporation
Type of format Raster graphics
Open format? OSP for WMF

The BMP file format, or bitmap, is a raster graphics image file format used to store bitmap digital images, independently of the display device (such as a graphics adapter), especially on Microsoft Windows[2] and OS/2[3] operating systems.

The BMP file format is capable of storing two-dimensional digital images in various color depths, and optionally with data compression, alpha channels, and color profiles. The Windows Metafile (WMF) specification covers the BMP file format.[4]

Device-independent bitmaps and the BMP file format

[edit]

Diagram 1 – The structure of the bitmap image file

Microsoft has defined a particular representation of color bitmaps of different color depths, as an aid to exchanging bitmaps between devices and applications with a variety of internal representations. They called these device-independent bitmaps or DIBs, and the file format for them is called DIB file format or BMP image file format.

According to Microsoft support:[5]

A device-independent bitmap (DIB) is a format used to define device-independent bitmaps in various color resolutions. The main purpose of DIBs is to allow bitmaps to be moved from one device to another (hence, the device-independent part of the name). A DIB is an external format, in contrast to a device-dependent bitmap, which appears in the system as a bitmap object (created by an application…). A DIB is normally transported in metafiles (usually using the StretchDIBits() function), BMP files, and the Clipboard (CF_DIB data format).

The following sections discuss the data stored in the BMP file or DIB in detail. This is the standard BMP file format.[5] Some applications create bitmap image files which are not compliant with the Microsoft documentation. Also, not all fields are used; a value of 0 will be found in these unused fields.

The bitmap image file consists of fixed-size structures (headers) as well as variable-sized structures appearing in a predetermined sequence. Many different versions of some of these structures can appear in the file, due to the long evolution of this file format.

Referring to the diagram 1, the bitmap file is composed of structures in the following order:

Structure name Optional Size Purpose Comments
Bitmap file header No 14 bytes To store general information about the bitmap image file Not needed after the file is loaded in memory
DIB header No Fixed-size
(7 different versions exist)
To store detailed information about the bitmap image and define the pixel format Immediately follows the Bitmap file header
Extra bit masks Yes 3 or 4 DWORDs[6]
(12 or 16 bytes)
To define the pixel format Present only in case the DIB header is the BITMAPINFOHEADER and the Compression Method member is set to either BI_BITFIELDS or BI_ALPHABITFIELDS
Color table Semi-optional Variable size To define colors used by the bitmap image data (Pixel array) Mandatory for color depths ≤ 8 bits
Gap1 Yes Variable size Structure alignment An artifact of the File offset to Pixel array in the Bitmap file header
Pixel array No Variable size To define the actual values of the pixels The pixel format is defined by the DIB header or Extra bit masks. Each row in the Pixel array is padded to a multiple of 4 bytes in size
Gap2 Yes Variable size Structure alignment An artifact of the ICC profile data offset field in the DIB header
ICC color profile Yes Variable size To define the color profile for color management Can also contain a path to an external file containing the color profile. When loaded in memory as «non-packed DIB», it is located between the color table and Gap1.[7]

A bitmap image file loaded into memory becomes a DIB data structure – an important component of the Windows GDI API. The in-memory DIB data structure is almost the same as the BMP file format, but it does not contain the 14-byte bitmap file header and begins with the DIB header. For DIBs loaded in memory, the color table can also consist of 16-bit entries that constitute indexes to the currently realized palette[8] (an additional level of indirection), instead of explicit RGB color definitions. In all cases, the pixel array must begin at a memory address that is a multiple of 4 bytes. In non-packed DIBs loaded in memory, the optional color profile data should be located immediately after the color table and before the gap1 and pixel array (unlike in diag. 1).

When the size of gap1 and gap2 is zero, the in-memory DIB data structure is customarily referred to as «packed DIB» and can be referred to by a single pointer pointing to the beginning of the DIB header. In all cases, the pixel array must begin at a memory address that is a multiple of 4 bytes. In some cases it may be necessary to adjust the number of entries in the color table in order to force the memory address of the pixel array to a multiple of 4 bytes.[8] For «packed DIBs» loaded in memory, the optional color profile data should immediately follow the pixel array, as depicted in diag. 1 (with gap1=0 and gap2=0).
«Packed DIBs» are required by Windows clipboard API functions as well as by some Windows patterned brush and resource functions.[9]

This block of bytes is at the start of the file and is used to identify the file. A typical application reads this block first to ensure that the file is actually a BMP file and that it is not damaged. The first 2 bytes of the BMP file format are the character «B» then the character «M» in ASCII encoding. All of the integer values are stored in little-endian format (i.e. least-significant byte first).

Offset hex Offset dec Size Purpose
00 0 2 bytes The header field used to identify the BMP and DIB file is 0x42 0x4D in hexadecimal, same as BM in ASCII. The following entries are possible:

BM
Windows 3.1x, 95, NT, … etc.
BA
OS/2 struct bitmap array
CI
OS/2 struct color icon
CP
OS/2 const color pointer
IC
OS/2 struct icon
PT
OS/2 pointer
02 2 4 bytes The size of the BMP file in bytes
06 6 2 bytes Reserved; actual value depends on the application that creates the image, if created manually can be 0
08 8 2 bytes Reserved; actual value depends on the application that creates the image, if created manually can be 0
0A 10 4 bytes The offset, i.e. starting address, of the byte where the bitmap image data (pixel array) can be found.

This block of bytes tells the application detailed information about the image, which will be used to display the image on the screen. The block also matches the header used internally by Windows and OS/2 and has several different variants. All of them contain a dword (32-bit) field, specifying their size, so that an application can easily determine which header is used in the image. The reason that there are different headers is that Microsoft extended the DIB format several times. The new extended headers can be used with some GDI functions instead of the older ones, providing more functionality. Since the GDI supports a function for loading bitmap files, typical Windows applications use that functionality. One consequence of this is that for such applications, the BMP formats that they support match the formats supported by the Windows version being run. See the table below for more information.

Windows and OS/2 bitmap headers

Size Header name OS support Features Written by
12 BITMAPCOREHEADER
OS21XBITMAPHEADER
Windows 2.0 or later
OS/2 1.x[3]
64 OS22XBITMAPHEADER OS/2 BITMAPCOREHEADER2 Adds halftoning. Adds RLE and Huffman 1D compression.
16 OS22XBITMAPHEADER This variant of the previous header contains only the first 16 bytes and the remaining bytes are assumed to be zero values.[3]

An example of such a case is the graphic pal8os2v2-16.bmp[10]
of the BMP Suite.[11]

40 BITMAPINFOHEADER Windows NT, 3.1x or later[2] Extends bitmap width and height to 4 bytes. Adds 16 bpp and 32 bpp formats. Adds RLE compression.
52 BITMAPV2INFOHEADER Undocumented Adds RGB bit masks. Adobe Photoshop
56 BITMAPV3INFOHEADER Not officially documented, but this documentation was posted on Adobe’s forums, by an employee of Adobe with a statement that the standard was at one point in the past included in official MS documentation[12] Adds alpha channel bit mask. Adobe Photoshop
108 BITMAPV4HEADER Windows NT 4.0, 95 or later Adds color space type and gamma correction
124 BITMAPV5HEADER Windows NT 5.0, 98 or later Adds ICC color profiles The GIMP

OS/2 1.x bitmaps are uncompressed and cannot be 16 or 32 bpp.

Offset (hex) Offset (dec) Size (bytes) OS/2 1.x BITMAPCOREHEADER[3]
0E 14 4 The size of this header (12 bytes)
12 18 2 The bitmap width in pixels (unsigned 16-bit)
14 20 2 The bitmap height in pixels (unsigned 16-bit)
16 22 2 The number of color planes, must be 1
18 24 2 The number of bits per pixel

The Windows 2.x BITMAPCOREHEADER differs from the OS/2 1.x BITMAPCOREHEADER (shown in the table above) in the one detail that the image width and height fields are signed integers, not unsigned.[13]

Versions after BITMAPINFOHEADER only add fields to the end of the header of the previous version.
For example: BITMAPV2INFOHEADER adds fields to BITMAPINFOHEADER, and BITMAPV3INFOHEADER adds fields to BITMAPV2INFOHEADER.

An integrated alpha channel has been introduced with the undocumented BITMAPV3INFOHEADER and with the documented BITMAPV4HEADER (since Windows 95) and is used within Windows XP logon and theme system as well as Microsoft Office (since v2000); it is supported by some image editing software, such as Adobe Photoshop since version 7 and Adobe Flash since version MX 2004 (then known as Macromedia Flash). It is also supported by GIMP, Google Chrome, Microsoft PowerPoint and Microsoft Word.

For compatibility reasons, most applications use the older DIB headers for saving files. With OS/2 no longer supported after Windows 2000, for now the common Windows format is the BITMAPINFOHEADER header. See next table for its description. All values are stored as unsigned integers, unless explicitly noted.

Offset (hex) Offset (dec) Size (bytes) Windows BITMAPINFOHEADER[2]
0E 14 4 the size of this header, in bytes (40)
12 18 4 the bitmap width in pixels (signed integer)
16 22 4 the bitmap height in pixels (signed integer)
1A 26 2 the number of color planes (must be 1)
1C 28 2 the number of bits per pixel, which is the color depth of the image. Typical values are 1, 4, 8, 16, 24 and 32.
1E 30 4 the compression method being used. See the next table for a list of possible values
22 34 4 the image size. This is the size of the raw bitmap data; a dummy 0 can be given for BI_RGB bitmaps.
26 38 4 the horizontal resolution of the image. (pixel per metre, signed integer)
2A 42 4 the vertical resolution of the image. (pixel per metre, signed integer)
2E 46 4 the number of colors in the color palette, or 0 to default to 2n
32 50 4 the number of important colors used, or 0 when every color is important; generally ignored

The compression method (offset 30) can be:

Value Identified by Compression method Comments
0 BI_RGB none Most common
1 BI_RLE8 RLE 8-bit/pixel Can be used only with 8-bit/pixel bitmaps
2 BI_RLE4 RLE 4-bit/pixel Can be used only with 4-bit/pixel bitmaps
3 BI_BITFIELDS OS22XBITMAPHEADER: Huffman 1D BITMAPV2INFOHEADER: RGB bit field masks,
BITMAPV3INFOHEADER+: RGBA
4 BI_JPEG OS22XBITMAPHEADER: RLE-24 BITMAPV4INFOHEADER+: JPEG image for printing[14]
5 BI_PNG BITMAPV4INFOHEADER+: PNG image for printing[14]
6 BI_ALPHABITFIELDS RGBA bit field masks only Windows CE 5.0 with .NET 4.0 or later
11 BI_CMYK none only Windows Metafile CMYK[4]
12 BI_CMYKRLE8 RLE-8 only Windows Metafile CMYK
13 BI_CMYKRLE4 RLE-4 only Windows Metafile CMYK

An OS/2 2.x OS22XBITMAPHEADER (BITMAPINFOHEADER2 in IBM’s documentation) contains 24 additional bytes:[3]

Offset (hex) Offset (dec) Size (bytes) OS/2 OS22XBITMAPHEADER (BITMAPINFOHEADER2)[3]
36 54 2 An enumerated value specifying the units for the horizontal and vertical resolutions (offsets 38 and 42). The only defined value is 0, meaning pixels per metre
38 56 2 Padding. Ignored and should be zero
3A 58 2 An enumerated value indicating the direction in which the bits fill the bitmap. The only defined value is 0, meaning the origin is the lower-left corner. Bits fill from left-to-right, then bottom-to-top.

Note that Windows bitmaps (which don’t include this field) can also specify an upper-left origin (bits fill from left-to-right, then top-to-bottom) by using a negative value for the image height

3C 60 2 An enumerated value indicating a halftoning algorithm that should be used when rendering the image.
3E 62 4 Halftoning parameter 1 (see below)
42 66 4 Halftoning parameter 2 (see below)
46 70 4 An enumerated value indicating the color encoding for each entry in the color table. The only defined value is 0, indicating RGB.
4A 74 4 An application-defined identifier. Not used for image rendering

The halftoning algorithm (offset 60) can be:

Value Halftoning algorithm Comments
0 none Most common
1 Error diffusion Halftoning parameter 1 (offset 64) is the percentage of error damping. 100 indicates no damping. 0 indicates that errors are not diffused
2 PANDA: Processing Algorithm for Noncoded Document Acquisition Halftoning parameters 1 and 2 (offsets 64 and 68, respectively) represent the X and Y dimensions, in pixels, respectively, of the halftoning pattern used
3 Super-circle Halftoning parameters 1 and 2 (offsets 64 and 68, respectively) represent the X and Y dimensions, in pixels, respectively, of the halftoning pattern used

The color table (palette) occurs in the BMP image file directly after the BMP file header, the DIB header, and after the optional three or four bitmasks if the BITMAPINFOHEADER header with BI_BITFIELDS (12 bytes) or BI_ALPHABITFIELDS (16 bytes) option is used. Therefore, its offset is the size of the BITMAPFILEHEADER plus the size of the DIB header (plus optional 12-16 bytes for the three or four bit masks).
Note: On Windows CE the BITMAPINFOHEADER header can be used with the BI_ALPHABITFIELDS[6] option in the biCompression member.

The number of entries in the palette is either 2n (where n is the number of bits per pixel) or a smaller number specified in the header (in the OS/2 BITMAPCOREHEADER header format, only the full-size palette is supported).[3][5] In most cases, each entry in the color table occupies 4 bytes, in the order blue, green, red, 0x00 (see below for exceptions). This is indexed in the BITMAPINFOHEADER in the structure member biBitCount.

The color table is a block of bytes (a table) listing the colors used by the image. Each pixel in an indexed color image is described by a number of bits (1, 4, or 8) which is an index of a single color described by this table. The purpose of the color palette in indexed color bitmaps is to inform the application about the actual color that each of these index values corresponds to. The purpose of the color table in non-indexed (non-palettized) bitmaps is to list the colors used by the bitmap for the purposes of optimization on devices with limited color display capability and to facilitate future conversion to different pixel formats and palettization.

The colors in the color table are usually specified in the 4-byte per entry ARGB32 format. The color table used with the OS/2 BITMAPCOREHEADER uses the 3-byte per entry RGB24 format.[3][5] For DIBs loaded in memory, the color table can optionally consist of 2-byte entries – these entries constitute indexes to the currently realized palette[8] instead of explicit RGB color definitions.

Microsoft does not disallow the presence of a valid alpha channel bit mask[15] in BITMAPV4HEADER and BITMAPV5HEADER for 1bpp, 4bpp and 8bpp indexed color images, which indicates that the color table entries can also specify an alpha component using the 8.8.8.[0-8].[0-8] format via the RGBQUAD.rgbReserved[16] member. However, some versions of Microsoft’s documentation disallow this feature by stating that the RGBQUAD.rgbReserved member «must be zero».

As mentioned above, the color table is normally not used when the pixels are in the 16-bit per pixel (16bpp) format (and higher); there are normally no color table entries in those bitmap image files. However, the Microsoft documentation (on the MSDN web site as of Nov. 16, 2010[17]) specifies that for 16bpp (and higher), the color table can be present to store a list of colors intended for optimization on devices with limited color display capability, while it also specifies, that in such cases, no indexed palette entries are present in this Color Table. This may seem like a contradiction if no distinction is made between the mandatory palette entries and the optional color list.

The bits representing the bitmap pixels are packed in rows (also known as strides or scan lines). The size of each row is rounded up to a multiple of 4 bytes (a 32-bit DWORD) by padding.[18]

For images with height above 1, multiple padded rows are stored consecutively, forming a Pixel Array.

The total number of bytes necessary to store one row of pixels can be calculated as:

{\displaystyle {\text{RowSize}}=\left\lceil {\frac {{\text{BitsPerPixel}}\cdot {\text{ImageWidth}}}{32}}\right\rceil \cdot 4=\left\lfloor {\frac {{\text{BitsPerPixel}}\cdot {\text{ImageWidth}}+31}{32}}\right\rfloor \cdot 4,}

The total number of bytes necessary to store an array of pixels in an n bits per pixel (bpp) image, with 2n colors, can be calculated by accounting for the effect of rounding up the size of each row to a multiple of 4 bytes, as follows:

ImageHeight is expressed in pixels. The absolute value is necessary because ImageHeight is expressed as a negative number for top-down images.

Pixel array (bitmap data)

[edit]

The pixel array is a block of 32-bit DWORDs, that describes the image pixel by pixel. Usually pixels are stored «bottom-up», starting in the lower left corner, going from left to right, and then row by row from the bottom to the top of the image.[5] Unless BITMAPCOREHEADER is used, uncompressed Windows bitmaps also can be stored from the top to bottom, when the Image Height value is negative.

In the original OS/2 DIB, the only four legal values of color depth were 1, 4, 8, and 24 bits per pixel (bpp).[5]
Contemporary DIB Headers allow pixel formats with 1, 2, 4, 8, 16, 24 and 32 bits per pixel (bpp).[19] GDI+ also permits 64 bits per pixel.[20]

Padding bytes (not necessarily 0) must be appended to the end of the rows in order to bring up the length of the rows to a multiple of four bytes. When the pixel array is loaded into memory, each row must begin at a memory address that is a multiple of 4. This address/offset restriction is mandatory only for Pixel Arrays loaded in memory. For file storage purposes, only the size of each row must be a multiple of 4 bytes while the file offset can be arbitrary.[5] A 24-bit bitmap with Width=1, would have 3 bytes of data per row (blue, green, red) and 1 byte of padding, while Width=2 would have 6 bytes of data and 2 bytes of padding, Width=3 would have 9 bytes of data and 3 bytes of padding, and Width=4 would have 12 bytes of data and no padding.

  • Indexed color images may be compressed with 4-bit or 8-bit RLE or Huffman 1D algorithm.
  • OS/2 BITMAPCOREHEADER2 24bpp images may be compressed with the 24-bit RLE algorithm.
  • The 16bpp and 32bpp images are always stored uncompressed.
  • Note that images in all color depths can be stored without compression if so desired.
  • The 1-bit per pixel (1bpp) format supports 2 distinct colors, (for example: black and white). The pixel values are stored in each bit, with the first (left-most) pixel in the most-significant bit of the first byte.[5] Each bit is an index into a table of 2 colors. An unset bit will refer to the first color table entry, and a set bit will refer to the last (second) color table entry.
  • The 2-bit per pixel (2bpp) format supports 4 distinct colors and stores 4 pixels per 1 byte, the left-most pixel being in the two most significant bits (Windows CE only:[21]). Each pixel value is a 2-bit index into a table of up to 4 colors.
  • The 4-bit per pixel (4bpp) format supports 16 distinct colors and stores 2 pixels per 1 byte, the left-most pixel being in the more significant nibble.[5] Each pixel value is a 4-bit index into a table of up to 16 colors.
  • The 8-bit per pixel (8bpp) format supports 256 distinct colors and stores 1 pixel per 1 byte. Each byte is an index into a table of up to 256 colors.
  • The 16-bit per pixel (16bpp) format supports 65536 distinct colors and stores 1 pixel per 2-byte WORD. Each WORD can define the alpha, red, green and blue samples of the pixel.
  • The 24-bit per pixel (24bpp) format supports 16,777,216 distinct colors and stores 1 pixel value per 3 bytes. Each pixel value defines the red, green and blue samples of the pixel (8.8.8.0.0 in RGBAX notation). Specifically, in the order: blue, green and red (8 bits per each sample).[5]
  • The 32-bit per pixel (32bpp) format supports 4,294,967,296 distinct colors and stores 1 pixel per 4-byte DWORD. Each DWORD can define the alpha, red, green and blue samples of the pixel.

In order to resolve the ambiguity of which bits define which samples, the DIB headers provide certain defaults as well as specific BITFIELDS, which are bit masks that define the membership of particular group of bits in a pixel to a particular channel. The following diagram defines this mechanism:

Diag. 2 – The BITFIELDS mechanism for a 32-bit pixel depicted in RGBAX sample length notation

Diag. 2 – The BITFIELDS mechanism for a 32-bit pixel depicted in RGBAX sample length notation

The sample fields defined by the BITFIELDS bit masks have to be contiguous and non-overlapping, but the order of the sample fields is arbitrary. The most ubiquitous field order is: Alpha, Blue, Green, Red (MSB to LSB). The red, green and blue bit masks are valid only when the Compression member of the DIB header is set to BI_BITFIELDS. The alpha bit mask is valid whenever it is present in the DIB header or when the Compression member of the DIB header is set to BI_ALPHABITFIELDS[6] (Windows CE only).

Diag. 3 – The pixel format with an alpha channel for a 16-bit pixel (in RGBAX sample Length notation) actually generated by Adobe Photoshop[22]

Diag. 3 – The pixel format with an alpha channel for a 16-bit pixel (in RGBAX sample Length notation) actually generated by Adobe Photoshop[22]

All of the possible pixel formats in a DIB

All of the possible pixel formats in a DIB

The BITFIELD mechanism described above allows for the definition of tens of thousands of different pixel formats, however only several of them are used in practice,[22] all palettized formats RGB8, RGB4, and RGB1 (marked in yellow in the table above, defined in dshow.h.MEDIASUBTYPE names):

Uncompressed RGB Video Subtypes[23]

R.G.B.A.X RGB subtype R.G.B.A.X ARGB subtype
8.8.8.0.8 RGB32 8.8.8.8.0 ARGB32
10.10.10.2.0 A2R10G10B10
8.8.8.0.0 RGB24 10.10.10.2.0 A2B10G10R10
5.6.5.0.0 RGB565 4.4.4.4.0 ARGB4444
5.5.5.0.1 RGB555 5.5.5.1.0 ARGB1555

Bit fields for ten RGB bits[23]

Bit field Offset Bits A2R10G10B10 Bits A2B10G10R10
Red 36h 00 00 F0 3F LE: 3FF00000 2029 FF 03 00 00 LE: 000003FF  0 9
Green 3Ah 00 FC 0F 00 LE: 000FFC00 1019 00 FC 0F 00 LE: 000FFC00 1019
Blue 3Eh FF 03 00 00 LE: 000003FF  0 9 00 00 F0 3F LE: 3FF00000 2029
Alpha 42h 00 00 00 C0 LE: C0000000 3031 00 00 00 C0 LE: C0000000 3031

In version 2.1.4 FFmpeg supported (in its own terminology) the BMP pixel formats bgra, bgr24, rgb565le, rgb555le, rgb444le, rgb8, bgr8, rgb4_byte, bgr4_byte, gray, pal8, and monob; i.e., bgra was the only supported pixel format with transparency.[24]

Example 1 of a 2×2 pixel bitmap, with 24 bits/pixel encoding

Following is an example of a 2×2 pixel, 24-bit bitmap (Windows DIB header BITMAPINFOHEADER) with pixel format RGB24.

Offset Size Hex value Value Description
BMP Header
0h 2 42 4D «BM» ID field (42h, 4Dh)
2h 4 46 00 00 00 70 bytes (54+16) Size of the BMP file (54 bytes header + 16 bytes data)
6h 2 00 00 Unused Application specific
8h 2 00 00 Unused Application specific
Ah 4 36 00 00 00 54 bytes (14+40) Offset where the pixel array (bitmap data) can be found
DIB Header
Eh 4 28 00 00 00 40 bytes Number of bytes in the DIB header (from this point)
12h 4 02 00 00 00 2 pixels (left to right order) Width of the bitmap in pixels
16h 4 02 00 00 00 2 pixels (bottom to top order) Height of the bitmap in pixels. Positive for bottom to top pixel order.
1Ah 2 01 00 1 plane Number of color planes being used
1Ch 2 18 00 24 bits Number of bits per pixel
1Eh 4 00 00 00 00 0 BI_RGB, no pixel array compression used
22h 4 10 00 00 00 16 bytes Size of the raw bitmap data (including padding)
26h 4 13 0B 00 00 2835 pixels/metre horizontal Print resolution of the image,
72 DPI × 39.3701 inches per metre yields 2834.6472
2Ah 4 13 0B 00 00 2835 pixels/metre vertical
2Eh 4 00 00 00 00 0 colors Number of colors in the palette
32h 4 00 00 00 00 0 important colors 0 means all colors are important
Start of pixel array (bitmap data)
36h 3 00 00 FF 0 0 255 Red, Pixel (x=0, y=1)
39h 3 FF FF FF 255 255 255 White, Pixel (x=1, y=1)
3Ch 2 00 00 0 0 Padding for 4 byte alignment (could be a value other than zero)
3Eh 3 FF 00 00 255 0 0 Blue, Pixel (x=0, y=0)
41h 3 00 FF 00 0 255 0 Green, Pixel (x=1, y=0)
44h 2 00 00 0 0 Padding for 4 byte alignment (could be a value other than zero)
Example 2 of a 4×2 pixel bitmap, with 32 bits/pixel encoding

Following is an example of a 4×2 pixel, 32-bit bitmap with opacity values in the alpha channel (Windows DIB Header BITMAPV4HEADER) with pixel format ARGB32.

Offset Size Hex value Value Description
BMP Header
0h 2 42 4D «BM» ID field (42h, 4Dh)
2h 4 9A 00 00 00 154 bytes (122+32) Size of the BMP file
6h 2 00 00 Unused Application specific
8h 2 00 00 Unused Application specific
Ah 4 7A 00 00 00 122 bytes (14+108) Offset where the pixel array (bitmap data) can be found
DIB Header
Eh 4 6C 00 00 00 108 bytes Number of bytes in the DIB header (from this point)
12h 4 04 00 00 00 4 pixels (left to right order) Width of the bitmap in pixels
16h 4 02 00 00 00 2 pixels (bottom to top order) Height of the bitmap in pixels
1Ah 2 01 00 1 plane Number of color planes being used
1Ch 2 20 00 32 bits Number of bits per pixel
1Eh 4 03 00 00 00 3 BI_BITFIELDS, no pixel array compression used
22h 4 20 00 00 00 32 bytes Size of the raw bitmap data (including padding)
26h 4 13 0B 00 00 2835 pixels/metre horizontal Print resolution of the image,
72 DPI × 39.3701 inches per metre yields 2834.6472
2Ah 4 13 0B 00 00 2835 pixels/metre vertical
2Eh 4 00 00 00 00 0 colors Number of colors in the palette
32h 4 00 00 00 00 0 important colors 0 means all colors are important
36h 4 00 00 FF 00 00FF0000 in big-endian Red channel bit mask (valid because BI_BITFIELDS is specified)
3Ah 4 00 FF 00 00 0000FF00 in big-endian Green channel bit mask (valid because BI_BITFIELDS is specified)
3Eh 4 FF 00 00 00 000000FF in big-endian Blue channel bit mask (valid because BI_BITFIELDS is specified)
42h 4 00 00 00 FF FF000000 in big-endian Alpha channel bit mask
46h 4 20 6E 69 57 little-endian «Win » LCS_WINDOWS_COLOR_SPACE
4Ah 24h 24h* 00…00 CIEXYZTRIPLE Color Space endpoints Unused for LCS «Win » or «sRGB»
6Eh 4 00 00 00 00 0 Red Gamma Unused for LCS «Win » or «sRGB»
72h 4 00 00 00 00 0 Green Gamma Unused for LCS «Win » or «sRGB»
76h 4 00 00 00 00 0 Blue Gamma Unused for LCS «Win » or «sRGB»
Start of the Pixel Array (the bitmap Data)
7Ah 4 FF 00 00 7F 255 0 0 127 Blue (Alpha: 127), Pixel (x=0, y=1)
7Eh 4 00 FF 00 7F 0 255 0 127 Green (Alpha: 127), Pixel (x=1, y=1)
82h 4 00 00 FF 7F 0 0 255 127 Red (Alpha: 127), Pixel (x=2, y=1)
86h 4 FF FF FF 7F 255 255 255 127 White (Alpha: 127), Pixel (x=3, y=1)
8Ah 4 FF 00 00 FF 255 0 0 255 Blue (Alpha: 255), Pixel (x=0, y=0)
8Eh 4 00 FF 00 FF 0 255 0 255 Green (Alpha: 255), Pixel (x=1, y=0)
92h 4 00 00 FF FF 0 0 255 255 Red (Alpha: 255), Pixel (x=2, y=0)
96h 4 FF FF FF FF 255 255 255 255 White (Alpha: 255), Pixel (x=3, y=0)

Note that the bitmap data starts with the lower left hand corner of the image.

Usage of BMP format

[edit]

The simplicity of the BMP file format, and its widespread familiarity in Windows and elsewhere, as well as the fact that this format is relatively well documented and has an open format, makes BMP a very common format that image processing programs from many operating systems can read and write. ICO and CUR files contain bitmaps starting with a BITMAPINFOHEADER.

Many older graphical user interfaces used bitmaps in their built-in graphics subsystems;[25] for example, the Microsoft Windows and OS/2 platforms’ GDI subsystem, where the specific format used is the Windows and OS/2 bitmap file format, usually named with the file extension of .BMP.[26]

While most BMP files have a relatively large file size due to lack of any compression (or generally low-ratio run-length encoding on palletized images), many BMP files can be considerably compressed with lossless data compression algorithms such as ZIP because they contain redundant data. Some formats, such as RAR, even include routines specifically targeted at efficient compression of such data.

The X Window System uses a similar XBM format for black-and-white images, and XPM (pixelmap) for color images. There are also a variety of «raw» formats, which save raw data with no other information. The Portable Pixmap (PPM) and Truevision TGA formats also exist, but are less often used – or only for special purposes; for example, TGA can contain transparency information.

  1. ^ «IANA Considerations». Windows Image Media Types. sec. 5. doi:10.17487/RFC7903. RFC 7903.
  2. ^ a b c James D. Murray; William vanRyper (April 1996). Encyclopedia of Graphics File Formats (Second ed.). O’Reilly. bmp. ISBN 1-56592-161-5. Retrieved 2014-03-07.
  3. ^ a b c d e f g h James D. Murray; William vanRyper (April 1996). Encyclopedia of Graphics File Formats (Second ed.). O’Reilly. os2bmp. ISBN 1-56592-161-5. Retrieved 2014-03-07.
  4. ^ a b «[MS-WMF]: Windows Metafile Format». MSDN. 2014-02-13. Retrieved 2014-03-12.
  5. ^ a b c d e f g h i j «DIBs and Their Uses». Microsoft Help and Support. Retrieved 2015-05-14.
  6. ^ a b c MSDN — BITMAPINFOHEADER (Windows CE 5.0): BI_ALPHABITFIELDS in biCompression member
  7. ^ a b c MSDN BITMAPINFO Structure
  8. ^ Feng Yuan — Windows graphics programming: Win32 GDI and DirectDraw: Packed Device-Independent Bitmap (CreateDIBPatternBrush, CreateDIBPatternBrushPt, FindResource, LoadResource, LockResource)
  9. ^ Summers, Jason (2015-10-30). «pal8os2v2-16.bmp». Retrieved 2016-07-06.
  10. ^ Summers, Jason (2015-10-30). «BMP Suite». Retrieved 2016-07-06.
  11. ^ Cox, Chris (2010-11-15). «Invalid BMP Format with Alpha channel». Photoshop Windows forum. Adobe. Archived from the original on 2015-01-27. Retrieved 2016-05-22.
  12. ^ «Microsoft Windows Bitmap: Summary from the Encyclopedia of Graphics File Formats».
  13. ^ a b
    «JPEG and PNG Extensions for Specific Bitmap Functions and Structures».
  14. ^ MSDN – BITMAPV4HEADER: The member bV4AlphaMask
  15. ^ MSDN – RGBQUAD: rgbReserved member
  16. ^ see note under biClrUsed MSDN BITMAPINFOHEADER
  17. ^ «Image Stride — Win32 apps». learn.microsoft.com.
  18. ^ MSDN — BITMAPINFOHEADER: The member biBitCount
  19. ^ «Types of Bitmaps». MSDN. 2012-06-03. Retrieved 2014-03-16.
  20. ^ MSDN: Windows CE — BITMAPINFOHEADER Structure
  21. ^ a b Adobe Photoshop: BMP Format Archived 2011-09-22 at the Wayback Machine
  22. ^ a b «Uncompressed RGB Video Subtypes». dshow.h. MSDN. Retrieved 2014-03-11.
  23. ^ «Image Formats». FFmpeg General Documentation. 2014. Retrieved 2014-02-23.
  24. ^ Julian Smart; Stefan Csomor & Kevin Hock (2006). Cross-Platform GUI Programming with Wxwidgets. Prentice Hall. ISBN 0-13-147381-6.
  25. ^ «Bitmap Image File (BMP), Version 5». Digital Preservation. Library of Congress. 2014-01-08. Retrieved 2014-03-11.
  • Bitmap File Structure, at digicamsoft.com
  • An introduction to DIBs (Device Independent Bitmaps), at herdsoft.com
  • A simple bitmap loader C++ class, at kalytta.com (A2R10G10B10 not yet supported)
  • The BMP File Format, Part 1 By David Charlap at Dr. Dobb’s journal of software tools (drdobbs.com), March 1995

Note: the constants BI_RGB, BI_RLE8, and BI_RLE4 have the values 0, 1, and
2, respectively.

Graphics File Formats

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.

Bitmap-File Formats

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.

Bitmap-File Structures

Each bitmap file contains a bitmap-file header, a bitmap-information header, a
color table, and an array of bytes that defines the bitmap bits. The file has
the following form:

BITMAPFILEHEADER  bmfh;
BITMAPINFOHEADER  bmih;
RGBQUAD           aColors[];
uint8_t           aBitmapBits[];

The bitmap-file header contains information about the type, size, and layout
of a device-independent bitmap file. The header is defined as a
BITMAPFILEHEADER structure.

The bitmap-information header, defined as a BITMAPINFOHEADER structure,
specifies the dimensions, compression type, and color format for the bitmap.

The color table, defined as an array of RGBQUAD structures, contains as many
elements as there are colors in the bitmap. The color table is not present for
bitmaps with 24 color bits because each pixel is represented by 24-bit red-
green-blue (RGB) values in the actual bitmap data area. The colors in the table
should appear in order of importance. This helps a display driver render a
bitmap on a device that cannot display as many colors as there are in the
bitmap. If the DIB is in Windows version 3.0 or later format, the driver can
use the biClrImportant member of the BITMAPINFOHEADER structure to determine
which colors are important.

The BITMAPINFO structure can be used to represent a combined bitmap-
information header and color table. The bitmap bits, immediately following the
color table, consist of an array of uint8_t values representing consecutive
rows, or «scan lines,» of the bitmap. Each scan line consists of consecutive
bytes representing the pixels in the scan line, in left-to-right order. The
number of bytes representing a scan line depends on the color format and the
width, in pixels, of the bitmap. If necessary, a scan line must be zero-padded
to end on a 32-bit boundary. However, segment boundaries can appear anywhere in
the bitmap. The scan lines in the bitmap are stored from bottom up. This means
that the first byte in the array represents the pixels in the lower-left corner
of the bitmap and the last byte represents the pixels in the upper-right corner.

The biBitCount member of the BITMAPINFOHEADER structure determines the
number of bits that define each pixel and the maximum number of colors in the
bitmap. These members can have any of the following values:

Value Meaning
1 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.
4 Bitmap has a maximum of 16 colors. Each pixel in the bitmap is represented by a 4-bit index into the color table. For example, if the first byte in the bitmap is 0x1F, the byte represents two pixels. The first pixel contains the color in the second table entry, and the second pixel contains the color in the sixteenth table entry.
8 Bitmap has a maximum of 256 colors. 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.
24 Bitmap has a maximum of 2^24 colors. The bmiColors (or bmciColors) member is NULL, and each 3-byte sequence in the bitmap array represents the relative intensities of red, green, and blue, respectively, for a pixel.

The biClrUsed member of the BITMAPINFOHEADER structure specifies the number
of color indexes in the color table actually used by the bitmap. If the
biClrUsed member is set to zero, the bitmap uses the maximum number of colors
corresponding to the value of the biBitCount member. An alternative form of
bitmap file uses the BITMAPCOREINFO, BITMAPCOREHEADER, and RGBTRIPLE
structures.

Bitmap Compression

Windows versions 3.0 and later support run-length encoded (RLE) formats for
compressing bitmaps that use 4 bits per pixel and 8 bits per pixel. Compression
reduces the disk and memory storage required for a bitmap.

Compression of 8-Bits-per-Pixel Bitmaps

When the biCompression member of the BITMAPINFOHEADER structure is set to
BI_RLE8, the DIB is compressed using a run-length encoded format for a
256-color bitmap. This format uses two modes: encoded mode and absolute mode.
Both modes can occur anywhere throughout a single bitmap.

Encoded Mode

A unit of information in 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 first byte of the pair can be set to zero to
indicate an escape that denotes the end of a line, the end of the bitmap, or a
delta. The interpretation of the escape depends on the value of the second byte
of the pair, which must be in the range 0x00 through 0x02.

Following are the meanings of the escape values that can be used in the second
byte:

Second byte

Value Description
0 End of line.
1 End of bitmap.
2 Delta. The two bytes following the escape contain unsigned values indicating the horizontal and vertical offsets of the next pixel from the current position.

Absolute Mode

Absolute mode is signaled by the first byte in the pair being set to zero and
the second byte to a value between 0x03 and 0xFF. The second byte represents
the number of bytes that follow, each of which contains the color index of a
single pixel. 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

Compression of 4-Bits-per-Pixel Bitmaps

When the biCompression member of the BITMAPINFOHEADER structure is set to
BI_RLE4, the DIB is compressed using a run-length encoded format for a
16-color bitmap. This format uses two modes: encoded mode and absolute mode.

Encoded Mode

A unit of information in 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 4 bits) and one in its low-order nibble.

The first pixel 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.

The first byte of the pair can be set to zero to indicate an escape that denotes
the end of a line, the end of the bitmap, or a delta. The interpretation of the
escape depends on the value of the second byte of the pair. In encoded mode, the
second byte has a value in the range 0x00 through 0x02. The meaning of these
values is the same as for a DIB with 8 bits per pixel.

Absolute Mode

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. 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

Bitmap Example

The following example is a text dump of a 16-color bitmap (4 bits per pixel):

Win3DIBFile
              BitmapFileHeader
                  Type       19778
                  Size       3118
                  Reserved1  0
                  Reserved2  0
                  OffsetBits 118
              BitmapInfoHeader
                  Size            40
                  Width           80
                  Height          75
                  Planes          1
                  BitCount        4
                  Compression     0
                  SizeImage       3000

                  XPelsPerMeter   0
                  YPelsPerMeter   0
                  ColorsUsed      16
                  ColorsImportant 16
              Win3ColorTable
                  Blue  Green  Red  Unused
[00000000]        84    252    84   0
[00000001]        252   252    84   0
[00000002]        84    84     252  0
[00000003]        252   84     252  0
[00000004]        84    252    252  0
[00000005]        252   252    252  0
[00000006]        0     0      0    0
[00000007]        168   0      0    0
[00000008]        0     168    0    0
[00000009]        168   168    0    0
[0000000A]        0     0      168  0
[0000000B]        168   0      168  0
[0000000C]        0     168    168  0
[0000000D]        168   168    168  0
[0000000E]        84    84     84   0
[0000000F]        252   84     84   0
              Image
    .
    .                                           Bitmap data
    .

Icon-Resource File Format

An icon-resource file contains image data for icons used by Windows
applications. 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.

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:

typedef struct ICONDIR {
    uint16_t     idReserved;
    uint16_t     idType;
    uint16_t     idCount;
    ICONDIRENTRY idEntries[1];
} ICONHEADER;

Following are the members in the ICONDIR structure:

Name Description
idReserved Reserved; must be zero.
idType Specifies the resource type. This member is set to 1.
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:

struct IconDirectoryEntry {
    uint8_t   bWidth;
    uint8_t   bHeight;
    uint8_t   bColorCount;
    uint8_t   bReserved;
    uint16_t  wPlanes;
    uint16_t  wBitCount;
    uint32_t  dwBytesInRes;
    uint32_t  dwImageOffset;
};

Following are the members in the ICONDIRENTRY structure:

Name Description
bWidth Specifies the width of the icon, in pixels. Acceptable values are 16, 32, and 64.
bHeight Specifies the 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.

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;
RGBQUAD           icColors[];
uint8_t           icXOR[];
uint8_t           icAND[];

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 uint8_t
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 uint8_t
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 8
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.

The following illustration shows the XOR and AND masks that create a monochrome
icon (measuring 8 pixels by 8 pixels) in the form of an uppercase K.

Windows Icon Selection

Windows detects the resolution of the current display and matches it against
the width and height specified for each version of the icon image. If Windows
determines that there is an exact match between an icon image and the current
device, it uses the matching image. Otherwise, it selects the closest match
and stretches the image to the proper size.

If an icon-resource file contains more than one image for a particular
resolution, Windows uses the icon image that most closely matches the color
capabilities of the current display. If no image matches the device
capabilities exactly, Windows selects the image that has the greatest number
of colors without exceeding the number of display colors. If all images
exceed the color capabilities of the current display, Windows uses the icon
image with the least number of colors.

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.

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:

typedef struct _CURSORDIR {
    uint16_t        cdReserved;
    uint16_t        cdType;
    uint16_t        cdCount;
    CURSORDIRENTRY  cdEntries[];
} CURSORDIR;

Following are the members in the CURSORDIR structure:

Name Description
cdReserved Reserved; must be zero.
cdType Specifies the resource type. This member must be set to 2.
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:

typedef struct _CURSORDIRENTRY {
    uint8_t   bWidth;
    uint8_t   bHeight;
    uint8_t   bColorCount;
    uint8_t   bReserved;
    uint16_t  wXHotspot;
    uint16_t  wYHotspot;
    uint32_t  lBytesInRes;
    uint32_t  dwImageOffset;
} CURSORDIRENTRY;

Following are the members in the CURSORDIRENTRY structure:

Name Description
bWidth Specifies the width of the cursor, in pixels.
bHeight Specifies the height of the cursor, in pixels.
bColorCount Reserved; must be zero.
bReserved Reserved; must be zero.
wXHotspot Specifies the x-coordinate, in pixels, of the hot spot.
wYHotspot Specifies the y-coordinate, in pixels, of the hot spot.
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.

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;
RGBQUAD           crColors[];
uint8_t           crXOR[];
uint8_t           crAND[];

The cursor hot spot is a single pixel in the cursor bitmap that Windows uses to
track the cursor. The crXHotspot and crYHotspot members specify the x- and
y-coordinates of the cursor hot spot. These coordinates are 16-bit integers.

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.

The XOR mask, immediately following the color table, is an array of uint8_t
values representing consecutive rows of a bitmap. The bitmap defines the basic
shape and color of the cursor image. As with the bitmap bits in a bitmap file,
the bitmap data in a cursor-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 uint8_t
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 8
pixels.

When Windows draws a cursor, it uses the AND and XOR masks to combine the cursor
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. Window then applies the XOR mask by using a bitwise XOR operation.
This sets the final color for each pixel.

The following illustration shows the XOR and the AND masks that create a cursor
(measuring 8 pixels by 8 pixels) in the form of an arrow:

Following are the bit-mask values necessary to produce black, white,
inverted, and transparent results:

Pixel result AND mask XOR mask
Black 0 0
White 0 1
Transparent 1 0
Inverted 1 1

Windows Cursor Selection

If a cursor-resource file contains more than one cursor image, Windows
determines the best match for a particular display by examining the width and
height of the cursor images.

Structures

BITMAPFILEHEADER

/* bmfh */
typedef struct tagBITMAPFILEHEADER {
    uint32_t  bfType;
    uint32_t  bfSize;
    uint32_t  bfReserved1;
    uint32_t  bfReserved2;
    uint32_t  bfOffBits;
} BITMAPFILEHEADER;

The BITMAPFILEHEADER structure contains information about the type, size, and
layout of a device-independent bitmap (DIB) file.

Member Description
bfType Specifies the type of file. This member must be BM.
bfSize Specifies the size of the file, in bytes.
bfReserved1 Reserved; must be set to zero.
bfReserved2 Reserved; must be set to zero.
bfOffBits Specifies the byte offset from the BITMAPFILEHEADER structure to the actual bitmap data in the file.

Comments

A BITMAPINFO or BITMAPCOREINFO structure immediately follows the
BITMAPFILEHEADER structure in the DIB file.

See Also

BITMAPCOREINFO, BITMAPINFO

BITMAPINFO

/* bmi */
typedef struct tagBITMAPINFO {
    BITMAPINFOHEADER  bmiHeader;
    RGBQUAD           bmiColors[1];
} BITMAPINFO;

The BITMAPINFO structure fully defines the dimensions and color information
for a Windows 3.0 or later device-independent bitmap (DIB).

Member Description
bmiHeader Specifies a BITMAPINFOHEADER structure that contains information about the dimensions and color format of a DIB.
bmiColors Specifies an array of RGBQUAD structures that define the colors in the bitmap.

Comments

A Windows 3.0 or later DIB consists of two distinct parts: a BITMAPINFO
structure, which describes the dimensions and colors of the bitmap, and 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 uint32_t boundary.
Segment boundaries, however, can appear anywhere in the bitmap. The origin of
the bitmap is the lower-left corner.

The biBitCount member of the BITMAPINFOHEADER structure determines the
number of bits which define each pixel and the maximum number of colors in the
bitmap. This member may be set to any of the following values:

Value Meaning
1 The bitmap is monochrome, and the bmciColors member must contain 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 bmciColors table. If the bit is set, the pixel has the color of the second entry in the table.
4 The bitmap has a maximum of 16 colors, and the bmciColors member contains 16 entries. Each pixel in the bitmap is represented by a four-bit index into the color table. For example, if the first byte in the bitmap is 0x1F, the byte represents two pixels. The first pixel contains the color in the second table entry, and the second pixel contains the color in the sixteenth table entry.
8 The bitmap has a maximum of 256 colors, and the bmciColors member contains 256 entries. In this case, each byte in the array represents a single pixel.
24 The bitmap has a maximum of 2^24 colors. The bmciColors member is NULL, and each 3-byte sequence in the bitmap array represents the relative intensities of red, green, and blue, respectively, of a pixel.

The biClrUsed member of the BITMAPINFOHEADER structure specifies the number
of color indexes in the color table actually used by the bitmap. If the
biClrUsed member is set to zero, the bitmap uses the maximum number of colors
corresponding to the value of the biBitCount member.

The colors in the bmiColors table should appear in order of importance.
Alternatively, for functions that use DIBs, the bmiColors member can be an
array of 16-bit unsigned integers that specify an index into the currently
realized logical palette instead of explicit RGB values. In this case, an
application using the bitmap must call DIB functions with the wUsage parameter
set to DIB_PAL_COLORS.

Note: The bmiColors member should not contain palette indexes if the bitmap
is to be stored in a file or transferred to another application. Unless the
application uses the bitmap exclusively and under its complete control, the
bitmap color table should contain explicit RGB values.

See Also

BITMAPINFOHEADER, RGBQUAD

BITMAPINFOHEADER

typedef struct tagBITMAPINFOHEADER {    /* bmih */
    uint32_t  biSize;
    uint32_t  biWidth;
    uint32_t  biHeight;
    uint16_t  biPlanes;
    uint16_t  biBitCount;
    uint32_t  biCompression;
    uint32_t  biSizeImage;
    uint32_t  biXPelsPerMeter;
    uint32_t  biYPelsPerMeter;
    uint32_t  biClrUsed;
    uint32_t  biClrImportant;
} BITMAPINFOHEADER;

The BITMAPINFOHEADER structure contains information about the dimensions and
color format of a Windows 3.0 or later device-independent bitmap (DIB).

Member Description
biSize Specifies the number of bytes required by the BITMAPINFOHEADER structure.
biWidth Specifies the width of the bitmap, in pixels.
biHeight Specifies the height of the bitmap, in pixels.
biPlanes Specifies the number of planes for the target device. This member must be set to 1.
biBitCount Specifies the number of bits per pixel. This value must be 1, 4, 8, or 24.
biCompression Specifies the type of compression for a compressed bitmap. It can be one of the following values:
Value Meaning
BI_RGB Specifies that the bitmap is not compressed.
BI_RLE8 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.
BI_RLE4 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 is in the BI_RGB format.
biXPelsPerMeter Specifies the horizontal 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.
biYPelsPerMeter Specifies the vertical resolution, in pixels per meter, of the target device for the bitmap.
biClrUsed Specifies the number of color indexes in the color table actually used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member. For more information on the maximum sizes of the color table, see the description of the BITMAPINFO structure earlier in this topic.
biClrImportant Specifies the number of color indexes that are considered important for displaying the bitmap. If this value is zero, all colors are important.

Comments

If the biClrUsed member is nonzero, it specifies the actual number of colors
that the graphics engine or device driver will access if the biBitCount member
is less than 24. If biBitCount is set to 24, biClrUsed specifies the size of
the reference color table used to optimize performance of Windows color
palettes. If the bitmap is a packed bitmap (that is, a bitmap in which the
bitmap array immediately follows the BITMAPINFO header and which is referenced
by a single pointer), the biClrUsed member must be set to zero or to the
actual size of the color table.

The BITMAPINFO structure combines the BITMAPINFOHEADER structure and a color
table to provide a complete definition of the dimensions and colors of a Windows
3.0 or later DIB. For more information about specifying a Windows 3.0 DIB, see
the description of the BITMAPINFO structure.

An application should use the information stored in the biSize member to
locate the color table in a BITMAPINFO structure as follows:

pColor = ((LPSTR) pBitmapInfo + (uint16_t) (pBitmapInfo->bmiHeader.biSize))

Windows supports formats for compressing bitmaps that define their colors
with 8 bits per pixel and with 4 bits per pixel. Compression reduces the disk
and memory storage required for the bitmap. The following paragraphs describe
these formats.

BI_RLE8

When the biCompression member is set to BI_RLE8, the bitmap is compressed
using a run-length encoding format for an 8-bit bitmap. 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. 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.

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. The following example shows the hexadecimal values
of an 8-bit compressed bitmap:

03 04 05 06 00 03 45 56 67 00 02 78 00 02 05 01
02 78 00 00 09 1E 00 01

This bitmap would expand as follows (two-digit values represent a color index
for a single pixel):

04 04 04
06 06 06 06 06
45 56 67
78 78
move current position 5 right and 1 down
78 78
end of line
1E 1E 1E 1E 1E 1E 1E 1E 1E
end of RLE bitmap

BI_RLE4

When the biCompression member is set to BI_RLE4, the bitmap is compressed
using a run-length encoding (RLE) format for a 4-bit bitmap, which also uses
encoded and absolute modes. In encoded mode, 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
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. The
end-of-line, end-of-bitmap, and delta escapes also apply to BI_RLE4.

The following example shows the hexadecimal values of a 4-bit compressed
bitmap:

03 04 05 06 00 06 45 56 67 00 04 78 00 02 05 01
04 78 00 00 09 1E 00 01

This bitmap would expand as follows (single-digit values represent a color
index for a single pixel):

0 4 0
0 6 0 6 0
4 5 5 6 6 7
7 8 7 8
move current position 5 right and 1 down
7 8 7 8
end of line
1 E 1 E 1 E 1 E 1
end of RLE bitmap

See Also

BITMAPINFO

RGBQUAD

typedef struct tagRGBQUAD {     /* rgbq */
    uint8_t  rgbBlue;
    uint8_t  rgbGreen;
    uint8_t  rgbRed;
    uint8_t  rgbReserved;
} RGBQUAD;

The RGBQUAD structure describes a color consisting of relative intensities of
red, green, and blue. The bmiColors member of the BITMAPINFO structure
consists of an array of RGBQUAD structures.

Member Description
rgbBlue Specifies the intensity of blue in the color.
rgbGreen Specifies the intensity of green in the color.
rgbRed Specifies the intensity of red in the color.
rgbReserved Not used; must be set to zero.

See Also

BITMAPINFO

RGB

COLORREF RGB(cRed, cGreen, cBlue)
uint8_t  cRed;   // red component of color
uint8_t  cGreen; // green component of color
uint8_t  cBlue;  // blue component of color

The RGB macro selects an RGB color based on the parameters supplied and the
color capabilities of the output device.

Parameter Description
cRed Specifies the intensity of the red color field.
cGreen Specifies the intensity of the green color field.
cBlue Specifies the intensity of the blue color field.

Returns

The return value specifies the resultant RGB color.

Comments

The intensity for each argument can range from 0 through 255. If all three
intensities are specified as zero, the result is black. If all three
intensities are specified as 255, the result is white.

The RGB macro is defined in WINDOWS.H as follows:

#define RGB(r,g,b) \
  ((COLORREF)(((uint8_t)(r)|((uint16_t)(g)<<8))| (((uint32_t)(uint8_t)(b))<<16)))

See Also

GetBValue, GetGValue, GetRValue, PALETTEINDEX, PALETTERGB

BITMAPCOREINFO

/* bmci */
typedef struct tagBITMAPCOREINFO {
    BITMAPCOREHEADER  bmciHeader;
    RGBTRIPLE         bmciColors[1];
} BITMAPCOREINFO;

The BITMAPCOREINFO structure fully defines the dimensions and color
information for a device-independent bitmap (DIB). Windows applications
should use the BITMAPINFO structure instead of BITMAPCOREINFO whenever
possible.

Member Description
bmciHeader Specifies a BITMAPCOREHEADER structure that contains information about the dimensions and color format of a DIB.
bmciColors Specifies an array of RGBTRIPLE structures that define the colors in the bitmap.

Comments

The BITMAPCOREINFO structure describes the dimensions and colors of a bitmap.
It is followed immediately in memory by an array of bytes which define 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 uint32_t boundary. Segment boundaries,
however, can appear anywhere in the bitmap. The origin of the bitmap is the
lower-left corner.

The bcBitCount member of the BITMAPCOREHEADER structure determines the number
of bits that define each pixel and the maximum number of colors in the
bitmap. This member may be set to any of the following values:

Value Meaning
1 The bitmap is monochrome, and the bmciColors member must contain 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 bmciColors table. If the bit is set, the pixel has the color of the second entry in the table.
4 The bitmap has a maximum of 16 colors, and the bmciColors member contains 16 entries. Each pixel in the bitmap is represented by a four-bit index into the color table.
8 The bitmap has a maximum of 256 colors, and the bmciColors member contains 256 entries. In this case, each byte in the array represents a single pixel.
24 The bitmap has a maximum of 2^24 colors. The bmciColors member is NULL, and each 3-byte sequence in the bitmap array represents the relative intensities of red, green, and blue, respectively, of a pixel.

The colors in the bmciColors table should appear in order of importance.
Alternatively, for functions that use DIBs, the bmciColors member can be an
array of 16-bit unsigned integers that specify an index into the currently
realized logical palette instead of explicit RGB values. In this case, an
application using the bitmap must call DIB functions with the wUsage
parameter set to DIB_PAL_COLORS.

Note: The bmciColors member should not contain palette indexes if the
bitmap is to be stored in a file or transferred to another application.
Unless the application uses the bitmap exclusively and under its complete
control, the bitmap color table should contain explicit RGB values.

See Also

BITMAPINFO, BITMAPCOREHEADER, RGBTRIPLE

BITMAPCOREHEADER

typedef struct tagBITMAPCOREHEADER {    /* bmch */
    uint32_t  bcSize;
    int16_t   bcWidth;
    int16_t   bcHeight;
    uint16_t  bcPlanes;
    uint16_t  bcBitCount;
} BITMAPCOREHEADER;

The BITMAPCOREHEADER structure contains information about the dimensions and
color format of a device-independent bitmap (DIB). Windows applications
should use the BITMAPINFOHEADER structure instead of BITMAPCOREHEADER
whenever possible.

Member Description
bcSize Specifies the number of bytes required by the BITMAPCOREHEADER structure.
bcWidth Specifies the width of the bitmap, in pixels.
bcHeight Specifies the height of the bitmap, in pixels.
bcPlanes Specifies the number of planes for the target device. This member must be set to 1.
bcBitCount Specifies the number of bits per pixel. This value must be 1, 4, 8, or 24.

Comments

The BITMAPCOREINFO structure combines the BITMAPCOREHEADER structure and a
color table to provide a complete definition of the dimensions and colors of
a DIB. See the description of the BITMAPCOREINFO structure for more
information about specifying a DIB.

An application should use the information stored in the bcSize member to
locate the color table in a BITMAPCOREINFO structure with a method such as
the following:

lpColor = ((LPSTR) pBitmapCoreInfo + (uint32_t) (pBitmapCoreInfo->bcSize))

See Also

BITMAPCOREINFO, BITMAPINFOHEADER, BITMAPINFOHEADER

RGBTRIPLE

/* rgbt */
typedef struct tagRGBTRIPLE {
    uint8_t  rgbtBlue;
    uint8_t  rgbtGreen;
    uint8_t  rgbtRed;
} RGBTRIPLE;

The RGBTRIPLE structure describes a color consisting of relative intensities
of red, green, and blue. The bmciColors member of the BITMAPCOREINFO
structure consists of an array of RGBTRIPLE structures. Windows applications
should use the BITMAPINFO structure instead of BITMAPCOREINFO whenever
possible. The BITMAPINFO structure uses an RGBQUAD structure instead of the
RGBTRIPLE structure.

Member Description
rgbtBlue Specifies the intensity of blue in the color.
rgbtGreen Specifies the intensity of green in the color.
rgbtRed Specifies the intensity of red in the color.

See Also

BITMAPCOREINFO, BITMAPINFO, RGBQUAD

BMP file format

Applies to:

BG1, BG1: TotS, BG2, BG2: ToB, PST, IWD, IWD:HoW, IWD:TotL, IWD2

General Description

http://www.daubnet.com/formats/BMP.html

Table of Contents

  • Basic Description
  • Basic File Format
  • Raster Data Encoding
  • Portability
  • Trademarks, Patents and Royalties
  • Cross Checking Software
  • Resources
    • Online
    • Paper

Last updated: Jan 14. 1998


Basic Description
This file format is the MS-Windows standard format. It holds black&white-,
16-color, 256-color and Truecolor images. The palletized 16-color and 256-color
images may be compressed via run length encoding. Notice there is also a OS/2-BMP format.


Basic File Format

Name Size Description
Header 14 bytes Windows Structure:
BITMAPFILEHEADER
0x00 Signature 2 bytes ‘BM’
0x02 FileSize 4 bytes File size in bytes
0x06 Reserved 4 bytes unused (=0)
0x0a DataOffset 4 bytes File offset to Raster Data
InfoHeader 40 bytes Windows Structure:
BITMAPINFOHEADER
0x0e Size 4 bytes Size of InfoHeader =40 
0x12 Width 4 bytes Bitmap Width
0x16 Height 4 bytes Bitmap Height
0x1a Planes 2 bytes Number of Planes (=1)
0x1c BitCount 2 bytes Bits per Pixel  
1 = monochrome palette. NumColors =
1  
4 = 4bit palletized. NumColors = 16  
8 = 8bit palletized. NumColors =
256 
16 = 16bit RGB. NumColors = 65536
(?) 
24 = 24bit RGB. NumColors = 16M
0x1e Compression 4 bytes Type of Compression  
0 = BI_RGB   no
compression  
1 = BI_RLE8 8bit
RLE encoding  
2 = BI_RLE4 4bit
RLE encoding
0x22 ImageSize 4 bytes (compressed) Size of Image 
It is valid to set this =0 if
Compression = 0
0x26 XpixelsPerM 4 bytes horizontal resolution:
Pixels/meter
0x2a YpixelsPerM 4 bytes vertical resolution: Pixels/meter
0x2e ColorsUsed 4 bytes Number of actually used colors
0x32 ColorsImportant 4 bytes Number of important colors 
0 = all
0x36 ColorTable 4 * NumColors bytes present only if Info.BitsPerPixel
<= 8  
colors should be ordered by
importance
    Red 1 byte Red intensity
Green 1 byte Green intensity
Blue 1 byte Blue intensity
reserved 1 byte unused (=0)
repeated NumColors
times
Raster Data Info.ImageSize bytes The pixel data

Raster Data encoding

Depending on the image’s BitCount and on
the Compression flag there are 6 different encoding schemes. All of them
share the following: 

Pixels are stored bottom-up,
left-to-right. Pixel lines are padded with zeros to end on a 32bit
(4byte) boundary. For uncompressed formats every line will have the same
number of bytes. Color indices are zero based, meaning a pixel color of
0 represents the first color table entry, a pixel color of 255 (if there
are that many) represents the 256th entry. For images with more than 256
colors there is no color table. 

 

Raster Data encoding for 1bit / black & white images

BitCount = 1 Compression = 0 
Every byte holds 8 pixels, its highest
order bit representing the leftmost pixel of those. There are 2 color
table entries. Some readers will ignore them though, and assume that 0
is black and 1 is white. If you are storing black and white pictures you
should stick to this, with any other 2 colors this is not an issue.
Remember padding with zeros up to a 32bit boundary (This can be up to 31
zeros/pixels!) 

 

Raster Data encoding for 4bit / 16 color images

BitCount = 4 Compression = 0 
Every byte holds 2 pixels, its high order 4
bits representing the left of those. There are 16 color table entries.
These colors do not have to be the 16 MS-Windows standard colors.
Padding each line with zeros up to a 32bit boundary will result in up to
28 zeros = 7 ‘wasted pixels’.

 

Raster Data encoding for 8bit / 256 color images

BitCount = 8 Compression = 0 
Every byte holds 1 pixel. There are 256
color table entries. Padding each line with zeros up to a 32bit boundary
will result in up to 3 bytes of zeros = 3 ‘wasted pixels’.

 

Raster Data encoding for 16bit / hicolor images

BitCount = 16 Compression = 0 
Every 2bytes / 16bit holds 1 pixel.  
<information missing: the 16 bit
was introduced together with Video For Windows? Is it a
memory-only-format?> 
The pixels are no color table pointers.
There are no color table entries. Padding each line with zeros up to a
16bit boundary will result in up to 2 zero bytes.

 

Raster Data encoding for 24bit / truecolor images

BitCount = 24 Compression = 0 
Every 4bytes / 32bit holds 1 pixel. The
first holds its red, the second its green, and the third its blue
intensity. The fourth byte is reserved and should be zero. There are no
color table entries. The pixels are no color table pointers. No zero
padding necessary.

 

Raster Data compression for 4bit / 16 color images

BitCount = 4 Compression = 2 
The pixel data is stored in 2bytes / 16bit
chunks.  The first of these specifies the number of consecutive
pixels with the same pair of color. The second byte defines two color
indices. The resulting pixel pattern will be interleaved high-order
4bits and low order 4 bits (ABABA…). If the first byte is zero, the
second defines an escape code. The End-of-Bitmap is zero padded to end
on a 32bit boundary. Due to the 16bit-ness of this structure this will
always be either two zero bytes or none.  
 

n (byte 1) c (Byte 2) Description
>0 any n pixels are to be drawn.
The 1st, 3rd, 5th, … pixels’ color is in c‘s high-order
4 bits, the even pixels’ color is in c‘s low-order 4
bits. If both color indices are the same, it results in just n
pixels of color c
0 0 End-of-line
0 1 End-of-Bitmap
0 2 Delta. The following 2 bytes
define an unsigned offset in x and y direction (y being up) The
skipped pixels should get a color zero.
0 >=3 The following c bytes will
be read as single pixel colors just as in uncompressed files. up
to 12 bits of zeros follow, to put the file/memory pointer on a
16bit boundary again.

 
Example for 4bit RLE

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 up. (Windows
docs say down, which is wrong)
00 00 End-of-line
09 1E 1 E 1 E 1 E 1 E 1
00 01 EndofBitmap
00 00 Zero padding for 32bit boundary

 

 

Raster Data compression for 8bit / 256 color images

BitCount = 8 Compression = 1 
The pixel data is stored in 2bytes / 16bit
chunks.  The first of these specifies the number of consecutive
pixels with the same color. The second byte defines their color index.
If the first byte is zero, the second defines an escape code. The
End-of-Bitmap is zero padded to end on a 32bit boundary. Due to the
16bit-ness of this structure this will always be either two zero bytes
or none.  
 

n (byte 1) c (Byte 2) Description
>0 any n pixels of color number c
0 0 End-of-line
0 1 EndOfBitmap
0 2 Delta. The following 2 bytes
define an unsigned offset in x and y direction (y being up) The
skipped pixels should get a color zero.
0 >=3 The following c bytes will
be read as single pixel colors just as in uncompressed files. A
zero follows, if c is odd, putting the file/memory
pointer on a 16bit boundary again.

 
Example for 8bit RLE

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 up. (Windows
docs say down, which is wrong)
00 00 End-of-line
09 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E
00 01 End-of-bitmap
00 00 Zero padding for 32bit boundary

 


Portability
Although BMPs were invented by Microsoft for its Windows platform,
a lot of programs on other platforms are capable of reading and
writing them. Notice the Intel order in 2byte and 4-byte integer values
(Least significant byte first). The 16bit BMPs have been introduced to
Windows after the others, still puzzling many applications.


Trademarks, Patents and Royalties
To my knowledge: None.


Cross-Checking Software
This section is for programmers, who wish to cross-check their implementation
with others. This is an incomplete list of programs, which are available as
freeware / shareware / try-before-buy etc.

The following software is able to decode BMP files

  • easiest: Make the file the MS-Windows’ background.
  • MS-Paint / Paintbrush
  • JASC Paint Shop Pro

The following software is able to encode BMP files

  • JASC Paint Shop Pro
  • MS-Paint / Paintbrush


Online Resources
http://www.dcs.ed.ac.uk/~mxr/gfx/


Paper Resources
MS-Windows SDK
[German:] Referenzhandbuch Dateiformate by Günter Born.

The following suggestions are from the Graphics Fileformats FAQ:

  • Inside Windows File Formats, Tom Swan, Sams Publishing 1993.
    ISBN 0-672-30338-8 $24.95 softcover, 337 pages and 1 disk (3.5 in.).
    Order: Sams Publishing, 2201 West 103rd Street, Indianapolis,
    IN 46290 
  • Luse, Marv. «The BMP File Format,» Dr. Dobb’s Journal, #219 September
    1994 (Vol 9, Issue 10), pp. 18-22.
    code available at: ftp://ftp.mv.com/pub/ddj/1994/1994.09/bmp.zip
  • The BMP File Format: Part I+II, Dr.
    Dobb’s Journal, David Charlap, #228+#229
    March+April 1995 (Vol. 20, Issue 3+4).
    code available at: ftp://ftp.mv.com/pub/ddj/1995/1995.03/bmp.zip

Часть
3. Реализация некоторых задач.

03.06.2005

Графика.

Определение
размеров изображения в графических файлах BMP.
Формат BMP-файла.

При загрузке картинок в
проект VB постоянно возникает проблема их вывода размером, удобным для просмотра.
В большинстве примеров и статей, размещенных в глобальной сети, авторы ограничиваются
установкой размеров Image или PictureBox’а равным размеру формы, видимо предполагая,
что картинка не может быть размером более 1024 х 768 пикселей. Уверяю тебя,
это предположение верно только для картинок, скаченных с Интернета. Обычные
фотографии (сделанные не мобильником) значительно больше.

Для того, чтобы
вывести фотографию любым, меньшим чем оригинал размером, достаточно установить
свойство Image.Stretch=True. Тогда картинка впишется в рамки установленного
размера Image. Проблема остается в том, что нарушается пропорция между шириной
и длиной картинки и изображение искажается. Для того, чтобы избежать этого,
надо заранее, перед загрузкой картинки в Image, знать реальный размер загружаемой
картинки и установить Image.Width и Image.Hight пропорционально
этим размерам. В главе 6 мы, для того, чтобы определить размер изображения,
использовали дополнительно элемент Picture. Загрузив картинку в Picture, мы
по свойствам Picture.ScaleWidth и Picture.ScaleHight определяли реальный размер
изображения и исходя из него, устанавливали размер Image. После этого копировали
картинку из Picture в Image (или в другой Picture) с помощью метода PaintPicture.
Желаемый результат, мы как говориться, в большинстве случаев получали. Однако,
работа с графикой не является сильным местом VB, и этот процесс при значительных
размерах картинки занимал достаточно много времени и отнимал много ресурсов.
Например, на компьютере Pentium III 700Мгц c оперативной памятью 128 Мб под
Win98 при размере файла картинки JPG более 1.2 мб этот процесс вообще не имел
счастливого завершения и уменьшенной копии картинки из таких файлов я так и
не увидел (причем, что на Pentium IV 1500 Мгц и 256 Мб оперативки под Windows
XP, это работало).

Такое положение
вещей приводит к логическому выводу: хорошо бы сразу знать размер графического
изображения, не загружая файла, тогда можно будет выставить размер Image перед
загрузкой картинки. При этом отпадает необходимость вспомогательного PictureBox,
что естественно экономит ресурсы и ускорет процесс.
Даже не изучая вопроса графического хранения и сжатия информации ясно, что в
файле картинки где-то черным по-белому прописан размер изображения. Нам надо
только его найти и считать. Сразу скажу, что нашей целью не является подробный
анализ внутренней структуры графических файлов и написание кодировщика-раскодировщика
этих файлов. Наша цель — получить нужную нам информацию (конкретно — размер
изображения). Мы попробуем по рабоче-крестьянски проанализировать три самых
распространенных формата BMP, GIF и JPG (JFIF), при этом особо, если получится,
не напрягая наши драгоценные мозги. Для того, чтобы поработать с внутренним
устройством графических файлов нам понадобится шестнадцатеричный редактор. Если
его нет под рукой, скачать простой бесплатный редактор можно здесь
(507 kb). Если тебе все это лениво, то можешь просто воспользоваться результатами
в виде готового кода (исходник вверху страницы).

Итак, начнем
с самого простого и приближенного к Windows:

Растровый
файл BMP (Bitmap).

Этот формат
является основным для Windows, так называемый Bitmap. Кроме того из него довольно-таки
легко получить искомую нам информацию. Эти файлы обычно имеют расширение .bmp
и используются Windows везде, где только возможно, хотя размер таких файлов
значительно больше, чем аналогичных JPG или GIF.
Структура файла такова, что нужная нам информация хранится в первых 54 байтах
файла. Ниже представлена таблица с подробным представлением этих самых байт
для файла BMP с размером изображения 719 х 781 пикселов.

Таблица заголовка BMP-файла.

Область

Заголовок
файла

Заголовок
растра

Информация

Идентиф.
BMP

Размер
файла

Не
используется

Место
растра

Длина
заголовка растра

Номер
байта (десятичное)

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

Пример
значения (шестнадцат.)

42

4D

E6

BD

19

00

00

00

00

00

36

00

00

00

28

00

00

00

продолжение таблицы

Область

Заголовок
растра

Информация

Ширина
изображения

Высота
изображения

Число цветовых плоскостей

Бит.пиксель

Метод сжатия

Номер
байта (десятичное)

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

Пример
значения (шестнадцат.)

CF

02

00

00

0D

03

00

00

01

00

18

00

00

00

00

00

окончание таблицы

Область

Заголовок
растра

Информация

Длина
растра

Горизонтальное
разрешение

Вертикальное
разрешение

Число
цветов изображения

Число
основных цветов

Номер
байта (десятичное)

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

Пример
значения (шестнадцат.)

00

00

00

00

40

0B

00

00

40

0B

00

00

00

00

00

00

00

00

00

00

Все это вы сможете увидеть,
открыв какой-нибудь BMP-файл с помощью шестнадцатеричного редактора.
Естественно, для работы с основным виндусовым файлом предусмотрены
широкие воможности, которые реализованы большим набором структур, которые обычно
используются совместно с API-функциями: BITMAP, BITMAPCOREHEADER, BITMAPCOREINFO,
BITMAPINFO, но интересующую нас информацию о типе графического изображения можно
получить с помощью структуры BITMAPFILEHEADER, а о размере — с помощью структуры
BITMAPINFOHEADER. Ниже представлено их объявление и краткое описание.

Type
BITMAPFILEHEADER '14 первых байт файла BMP
bfType As Integer 'символы
"BM" (&H4D42 или 19778), обозначающие bmp-файл

bfSize As Long 'размер файла
bfReserved1 As Integer 'не
используется, должно равняться нулю

bfReserved2 As Integer 'не
используется, должно равняться нулю

bfOffBits As Long 'смещение
графических данных от конца структуры

End Type

Type
BITMAPINFOHEADER '40 байт - общие характеристики растра
biSize As Long 'размер структуры
в байтах, всегда 40 байт

biWidth As Long 'ширина растра
в пикселах

biHeight As Long 'высота
растра в пикселах

biPlanes As Integer 'количество
цветовых плоскостей - всегда 1

biBitCount As Integer 'задает
количество бит на пиксел:
'1 - для монохромного растра
' 4 - для 16 цветов
' 8 - для 256 цветов
'16 - для 16-разрядных цветов RGB
'24 - для 24-разрядных цветов RGB
'32 - для 32-разрядных цветов RGB

biCompression As Long 'тип
сжатия (если BI_RGB, то сжатие не используется)

biSizeImage As Long 'размер
изображения в байтах

biXPelsPerMeter As Long 'количество
пикселов на метр по-горизонтали, для DIB

biYPelsPerMeter As Long 'количество
пикселов на метр по-вертикали, для DIB

biClrUsed As Long 'количество
фактически используемых элементов в цветовой таблице DIP

biClrImportant As Long 'количество
значащих элементов в таблице DIP

End Type

Реализуем это на практике.
Создадим exe-проект, положим на форму Text1 и Command1. Добавим к проекту стандартный
модуль и запишем в него объявления наших двух структур BITMAPFILEHEADER и BITMAPINFOHEADER.
Можно скопировать прямо с этой страницы. Закроем стандартный модуль. И далее
в форме в процедуре командной кнопки напишем код, позволяющий вывести в текстовое
поле тип файла в виде десятичного числа 19778 (что соответствует &H4D42
или буквам BM), его размер в байтах, а также ширину и высоту графического изображения
в пикселах.

Private Sub Command1_Click()
'объявим переменные с типами наших структур
Dim bmpInfo As BITMAPINFOHEADER
Dim bmpType As BITMAPFILEHEADER
'откроем файл для двоичного доступа
Open App.Path & "\untitled.bmp" For
Binary As
#1
'читаем первую структуру (14 байт от начала файла)
Get #1, , bmpType
'читаем вторую структуру (40 байт) с 15-го байта, т.е.
с байта, на котором остановилась первая структура

Get #1, , bmpInfo
' закрываем файл и выводим нашу информацию в Text1
Close #1
Text1 = "Тип изображения " & bmpType.bfType & vbCrLf
Text1 = Text1 & "Размер файла=" & bmpType.bfSize & vbCrLf
Text1 = Text1 & "Ширина картинки=" & bmpInfo.biWidth &
vbCrLf
Text1 = Text1 & "Высота картинки=" & bmpInfo.biHeight &
vbCrLf
End Sub

На всякий случай скачать
исходник этого кода можно здесь.

Однако с другими форматами
(GIF или JPG) все далеко не так просто и структур для них в VIsual Basic нету.
И с ними придется работать собственными слабыми силами. Поэтому потренируемся
на BMP, так как это самый простой формат по которому мы уже имеем кучу информации.
Давайте реализуем ту же задачу не используя структур BITMAPFILEHEADER и BITMAPINFOHEADER.
Не зря же я рисовал в начале таблицу структуры заголовка BMP-файла.
На самом деле, все очень просто. Мы будем просто читать необходимые нам байты
и обязательно в шестнадцатеричном представлении. Для полной ясности проговорим
все пошагово. К исходнику примера приложен файл BMP, который называется «untitled.bmp»
размером 80 768 байтов с графическим изображением 157 x 171 пиксель. Каким образом
мы получаем эти данные?
Создадим новый exe-проект и положим на форму Text1 (Multiline=True) и Command1.
Процедуру определения информации из BMP-файла пишем в командной кнопке.

Private Sub Command1_Click()
'Сначала объявим переменные
Dim FileName As String
'имя открываемого файла
Dim TypeOfFile As String
'тип файл (BM)
Dim b As Byte
Dim RazmW As String
'ширина изображения
Dim RazmH As String
'высота изображения
Dim RazmF As String
'размер файла в байтах
Dim x As Long
'установим имя файла
FileName = App.Path & "\untitled.bmp"
'и откроем его
Open FileName For Binary
As
#1
'Первым делом, нам надо установить, что это файл BMP,

' в противном случае, считываемая информация будет неверна. Первые два байта
должны
' содержать символы "BM". Считываем эти 2 байта в переменную TypeOfFile.

TypeOfFile = String(2, " ")
Get #1, , TypeOfFile
'Проверяем, эти ли символы
If TypeOfFile = "BM" Then
'если да, то выводим в Text1 соответствующий текст
Text1 = "BMP-файл" & vbCrLf

Далее, читаем размер файла.
Он находится в байтах 3, 4, 5 и 6. Однако порядок записи данных в формате BMP
таков, что старший байт находится в младшем, т.е нам наши четыре байта надо
читать наоборот, с 6-го по 3-й. Сделаем это в цикле.


For
x = 6 To 3 Step
-1
Get #1, x, b


С каждым тактом цикла в переменную
b будет считываться один байт. Он будет в десятичной системе счисления
(0, 1, 59,128). Но из этого мы не можем получить число, соответствующее размеру
файла. Нам нужны данные в шестнадцатеричной форме. Перевести можно с помощью
функции Hex. Но и этого недостаточно. Если у нас в байте было число,
например 0D, то при переводе оно превратится в D, а это недопустимо, так как
полностью исказит результат. Поэтому я здесь применил такую лихую формулу. Смысл
ее в том, что в случае, если полученное шестнадцатеричное число состоит из одного
знака, мы вперед добавляем ноль.

RazmF = RazmF & String((Len(Hex(b))
— 2) * -1, 0) & Hex(b)

Таким образом, наши десятичные
числа b преобразуются в строковые шестнадцатеричные и, сцепляясь в переменной
RazmF образуют строковое шестнадцатеричное число: RazmF = «00» &
«01» & «3B» & «80» = «13B80».
Это и есть искомый размер файла. Нам надо только перевести его в десятичную
систему счисления. Для этого можно использовать функцию ConvertDec() в стандартном
модуле Модуль1. Подробное описание алгоритма и кода функции можно прочитать
в статье «Шестнадцатеричное представление
числа. Перевод из шестнадцатеричной системы счисления в десятичную».

Next
x
'Переводим число в десятичное и получаем как раз 80768
байт - размер файла. Выводим это в Text1

Text1 = Text1 & "Размер файла = " & ConvertDec(RazmF) &
" bytes" & vbCrLf
'ширину получаем точно также
For x = 22 To 19 Step
-1
Get #1, x, b
RazmW = RazmW & String((Len(Hex(b)) - 2) * -1, 0) & Hex(b)
Next x
Text1 = Text1 & "Ширина изображения = " & ConvertDec(RazmW)
& " pixels" & vbCrLf
'аналогично получаем и высоту
For x = 26 To 23 Step
-1
Get #1, x, b
RazmH = RazmH & String((Len(Hex(b)) - 2) * -1, 0) & Hex(b)
Next x
Text1 = Text1 & "Высота изображения = " & ConvertDec(RazmH)
& " pixels" & vbCrLf
Else
' если файл начинается не с BM выводим соответствующий
текст

Text1 = "Это не BMP-файл"
End If
Close
End Sub

Вот, в общем, и вся реализация.
Скачать исходник примера «InfoBMP» можно вверху страницы.
Продолжение практического анализа графических форматов GIF и JPG (JFIF) смотри
в следующих статьях.


Copyright
©
2005 4us

Сайт создан в системе uCoz

Chances are you’ve created or seen a bitmap file before, it’s a binary file so it won’t be easily deciphered by a plain text editor but at its core it’s basically a large array of pixel data. We’ll examine the structure of bitmap files and write a small function to create one. We are using the bitmap format because of how simple it is, there are simpler more archaic formats such as ppm which can actually be created with a text editor but requires a 3rd party program to view.

Bitmaps aren’t very common especially when we have made such advancements in image compression technology over the last few decades, such things as pngs, mozilla jpeg and bulky formats such as psd.

What we will be writing is a function to save a 24 bit bitmap without compression. This tutorial is also more about implementing a file format from specifications as opposed to creating images as there are faster formats such as PPM.

Bitmap format

Basically a bitmap file has a header (or two depending on how you class them) and then a body, the rest are optional and not really needed if you just want to get something out. See BMP_file_format#/File_structure.

Notice 3 structures that aren’t optional, those are what we need. They are Bitmap file header, DIB/image header and pixel array. Also note the size restriction(s), the file header has to be 14 bytes while our pixel array can be as large as we want. A larger image will lead to a larger file size as we will see soon.

Again, the file header has exactly 14 bytes split into 5 fields

Field name Size in bytes Description
bfType 2 The characters ‘BM’
bfSize 4 The size of the file in bytes
bfReserved1 2 Unused — must be 0
bfReserved2 2 Unused — must be 0
bfOffBits 4 Offset to start of pixel data
Field name Size in bytes Description
bfType 2 The characters ‘BM’
bfSize 4 The size of the file in bytes
bfReserved1 2 Unused — must be 0
bfReserved2 2 Unused — must be 0
bfOffBits 4 Offset to start of pixel data

Implementation

Let’s start by creating a struct to hold some simple RGB data.

struct rgb_data {
    float r, g, b;
};

Next we create the function definition

void save_bitmap(const char *file_name, int width, int height, int dpi, rgb_type *pixel_data);

As input we take a filename, a width, height, dpi (dots per inch) and our array of pixels that we want to use to construct the image.

// create a file object that we will use to write our image
FILE *image;
// we want to know how many pixels to reserve
int image_size = width * height;
// a byte is 4 bits but we are creating a 24 bit image so we can represent a pixel with 3
// our final file size of our image is the width * height * 4 + size of bitmap header
int file_size = 54 + 4 * image_size;
// pixels per meter https://www.wikiwand.com/en/Dots_per_inch
int ppm = dpi * 39.375;

// bitmap file header (14 bytes)
// we could be savages and just create 2 array but since this is for learning lets
// use structs so it can be parsed by someone without having to refer to the spec

// since we have a non-natural set of bytes, we must explicitly tell the
// compiler to not pad anything, on gcc the attribute alone doesn't work so
// a nifty trick is if we declare the smallest data type last the compiler
// *might* ignore padding, in some cases we can use a pragma or gcc's
// __attribute__((__packed__)) when declaring the struct
// we do this so we can have an accurate sizeof() which should be 14, however
// this won't work here since we need to order the bytes as they are written
struct bitmap_file_header {
    unsigned char   bitmap_type[2];     // 2 bytes
    int             file_size;          // 4 bytes
    short           reserved1;          // 2 bytes
    short           reserved2;          // 2 bytes
    unsigned int    offset_bits;        // 4 bytes
} bfh;

// bitmap image header (40 bytes)
struct bitmap_image_header {
    unsigned int    size_header;        // 4 bytes
    unsigned int    width;              // 4 bytes
    unsigned int    height;             // 4 bytes
    short int       planes;             // 2 bytes
    short int       bit_count;          // 2 bytes
    unsigned int    compression;        // 4 bytes
    unsigned int    image_size;         // 4 bytes
    unsigned int    ppm_x;              // 4 bytes
    unsigned int    ppm_y;              // 4 bytes
    unsigned int    clr_used;           // 4 bytes
    unsigned int    clr_important;      // 4 bytes
} bih;

// if you are on Windows you can include <windows.h>
// and make use of the BITMAPFILEHEADER and BITMAPINFOHEADER structs

memcpy(&bfh.bitmap_type, "BM", 2);
bfh.file_size       = file_size;
bfh.reserved1       = 0;
bfh.reserved2       = 0;
bfh.offset_bits     = 0;

bih.size_header     = sizeof(bih);
bih.width           = width;
bih.height          = height;
bih.planes          = 1;
bih.bit_count       = 24;
bih.compression     = 0;
bih.image_size      = file_size;
bih.ppm_x           = ppm;
bih.ppm_y           = ppm;
bih.clr_used        = 0;
bih.clr_important   = 0;

image = fopen(file_name, "wb");

// compiler woes so we will just use the constant 14 we know we have
fwrite(&bfh, 1, 14, image);
fwrite(&bih, 1, sizeof(bih), image);

// write out pixel data, one last important this to know is the ordering is backwards
// we have to go BGR as opposed to RGB
for (int i = 0; i < image_size; i++) {
   rgb_data BGR = data[i];

   float red   = (BGR.r);
   float green = (BGR.g);
   float blue  = (BGR.b);

   // if you don't follow BGR image will be flipped!
   unsigned char color[3] = {
       blue, green, red
   };

   fwrite(color, 1, sizeof(color), image);
}

fclose(image);

Now let’s render out a sample image

int width  = 400,
    height = 400,
    dpi = 96;

rgb_data *pixels = new rgb_data[width * height];

for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
        int a = y * width + x;

        if ((x > 50 && x < 350) && (y > 50 && y < 350)) {
            pixels[a].r = 255;
            pixels[a].g = 255;
            pixels[a].b = 5;
        } else {
            pixels[a].r = 55;
            pixels[a].g = 55;
            pixels[a].b = 55;
        }
    }
}

save_bitmap("black_border.bmp", width, height, dpi, pixels);

Voila, you’ve created a bitmap.

Final bitmap

You can take it the next step and probably look at the compression field and see if you can make any changes to the filesize or reverse the save_bitmap(...) function to read one instead and use some SetPixel() function in a library such as SDL to draw a bitmap on screen.

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Настройки четкости шрифта windows 10
  • Настроить windows hello чтобы изменить этот параметр
  • Flussonic watcher для windows
  • Как удалить драйвер пак солюшен с компьютера полностью windows 10
  • Какая должна быть файловая система на флешке для установки windows 10