Edge Rewrite
Jump to content

BMP file format

From Wikipedia, the free encyclopedia
(Redirected from Windows bitmap)
Windows Bitmap
Filename extension
.bmp, .dib
Internet media typeimage/bmp[1]
image/x-bmp
Type code'BMP '
'BMPf'
'BMPp'
Uniform Type Identifier (UTI)com.microsoft.bmp
Developed byMicrosoft Corporation
Initial releaseDecember 1987; 38 years ago (1987-12)
Type of formatRaster graphics
Open format?OSP for WMF

The BMP file format, also known as bitmap image file, the Windows Bitmap file format, or simply bitmap, is a raster graphics image file format used to store bitmap digital images, independently of the display device (such as a graphics adapter).[2] The underlying device-independent bitmap representation is commonly called a DIB: it consists of a DIB header, optional color information, and pixel data, describing the image independently of the display device; a BMP file wraps such a DIB in an additional 14-byte file header. It originated in the closely linked early development of Microsoft Windows and OS/2, whose bitmap formats were at first identical;[3]; used by the GDI subsystem of both platforms, it is sometimes called the Windows and OS/2 bitmap file format and is usually named with the file extension .bmp or .dib.[4]

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.[2]

The format's simplicity, its familiarity on Windows, and its status as a relatively well-documented, open format have made it very widely supported, so that image-processing programs on many operating systems can read and write BMP files.[5][4] The same bitmap structure is embedded in related Windows formats: ICO and CUR files, for example, contain images that begin with a BITMAPINFOHEADER. Because uncompressed BMP files hold a great deal of redundant data, they can often be reduced substantially by general-purpose lossless compression such as ZIP or RAR.

The bitmap header structures were documented from the outset in Microsoft's general Windows and OS/2 programmer's references rather than in a specification dedicated to BMP alone;[2] a formal specification of the same structures, using normative language, was only later folded into the Windows Metafile (WMF) specification,[6] which Microsoft placed under its Open Specification Promise.

History

[edit]

The bitmap formats associated with Microsoft Windows are among the oldest image formats on the IBM PC, having originated with the first release of Windows and evolved alongside it — and, for a time, alongside OS/2 — over the following decade. Because the format carries no field recording its header version, the successive variants are distinguished by the size of their header, and an application identifies a variant by reading the header-size field at the start of the bitmap header.[2][7]

Windows 1.0 (1985) introduced only a simple device-dependent bitmap (DDB) — not yet the device-independent, DIB-based file format described in this article — highly dependent on the output device for which it was created, so a bitmap suited to one display was not necessarily usable on another.[8] A program created such a bitmap through handle-based GDI calls and loaded it from a module's resources; the BITMAP structure recorded only its width, height, plane count and bits-per-pixel, and the raw bits followed in the device's own format, with no color table of its own.[9]

While these early versions of Windows were being developed, Microsoft shared responsibility with IBM for the first releases of OS/2, whose Presentation Manager graphical interface used a closely related bitmap format. According to the Encyclopedia of Graphics File Formats, support for a programmable color palette was added to both Windows and BMP as Windows 2.x (1987) was being developed, making its DIB format identical to that of OS/2 1.1 (1988).[2][3] This device-independent bitmap (DIB) emerged from that joint work, and sources differ over which side originated it — and even over when it reached Windows. The Encyclopedia credits Windows itself, with Presentation Manager adopting the format afterward.[3] Other accounts instead trace the DIB to OS/2: Charles Petzold writes that the DIB "is new in Windows 3" and "an extension of the bitmap format supported in the OS/2 1.1 Presentation Manager",[8][7] and a 1990 BYTE column reported that "DIBs first surfaced in OS/2 1.1 as the Graphics Programming Interface bit map".[10] Raymond Chen, a longtime Microsoft engineer, dates this earlier, to Windows 2.0, stating that "Windows 2.0 adopted OS/2's bitmap format in order to foster interoperability" between the two systems.[11]

That early format used a 12-byte information header — later named BITMAPCOREHEADER — whose leading size field was required to be 12.[12] IBM's own documentation,[13] and that same Microsoft reference,[12] instead name this OS/2 header BITMAPINFOHEADER — the same name Microsoft later gave the unrelated 40-byte structure below. To avoid that collision, some secondary sources instead call the OS/2 1.x and 2.x headers OS21XBITMAPHEADER and OS22XBITMAPHEADER;[3] this article uses IBM's own names for them.

Windows 3.0 (1990) carried the device-independent bitmap forward in the form still dominant today, built around a new 40-byte BITMAPINFOHEADER, which superseded the earlier 12-byte header. When written to disk with a BITMAPFILEHEADER, this became the basis of the modern BMP file format.[7][8] The release also added run-length encoding for 4- and 8-bit-per-pixel (bpp) images (BI_RLE4 and BI_RLE8),[7] and still accepted the older 12-byte header, which it documented as a BITMAPCOREHEADER "compatible with … OS/2 Presentation Manager versions 1.1 and 1.2".[7]

OS/2 2.0 (1992) then extended its version independently. The 64-byte BITMAPINFOHEADER2 widened the dimensions to 32 bits and added 24-bit RLE compression and Huffman 1D compression for bi-level images.[13][3] OS/2 also defined a bitmap-array container — identified by the BA signature and holding images tagged BM, IC, PT, CI or CP — that could bundle several device-dependent and device-independent renderings of a bitmap, icon or pointer in a single file, the device-independent version first.[13][3] As the two companies' operating-system efforts diverged, the Windows and OS/2 formats grew steadily further apart.[2]

Windows NT (1993) introduced support for using BI_BITFIELDS with 16- and 32-bpp DIBs, with the color masks following the 40-byte header instead of a color table.[2] Two further, historically undocumented header variants of 52 and 56 bytes, which fold those RGB masks (and an alpha mask) into the header itself, are also encountered (described below).

Windows 95 (1995) introduced the 108-byte BITMAPV4HEADER, later also supported by Windows NT 4.0 (1996), which added an explicit alpha-channel mask together with a color-space identifier, CIE color endpoints and per-channel gamma values, allowing Image Color Matching information to travel with the bitmap.[2] Windows 98 (1998) followed with the 124-byte BITMAPV5HEADER, later also supported by Windows 2000 (1999), which can embed or link an ICC color profile.[4]

Independently of this header-borne alpha mask (see below), the alpha-blending functions available in Windows 2000 and later could take a per-pixel alpha value directly from a 32-bit BI_RGB image, with no color mask involved.[14][15]

Rather than being defined in a single specification dedicated to BMP, the format's structures were documented release by release inside the general Windows and OS/2 programmer's references, header files and online help.[2] The later Windows Metafile specification was the first to define these structures formally, in normative language.[6]

Windows bitmap format

[edit]
Diagram 1 – The structure of a BMP file using the BITMAPV5HEADER
Diagram 1 – The structure of a BMP file using the BITMAPV5HEADER

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. Some applications create bitmap image files which are not compliant with the Microsoft documentation; not all fields are used, and a value of 0 will be found in these unused fields.[16] All multi-byte integer fields defined by the BMP and Windows/OS/2 bitmap structures — every header field, as well as the color masks — are stored in little-endian byte order, a heritage of the format's origin on Intel-based machines.[2]

A device-independent bitmap (DIB) is a format for defining bitmaps at various color resolutions so that an image can be moved from one device to another independently of the display hardware — hence the "device-independent" in the name. Unlike a device-dependent bitmap, which exists inside the system as a bitmap object, a DIB is an external format, normally transported in metafiles, in BMP files, and on the clipboard (the CF_DIB data format).[16] A BMP file and a bare DIB are not identical, however: the file begins with the 14-byte bitmap file header (BITMAPFILEHEADER), whereas a DIB transported in a metafile or on the clipboard omits that header and begins directly with the DIB header.

Diagram 1 shows the layout of a BMP file using the BITMAPV5HEADER, the most extensive Windows DIB header — it appears in the diagram because it contains every field added by the successive header extensions. Earlier DIB header variants contain fewer fields, but the structures they define form the initial part of the same layout; the variant actually present in a given file is determined by the DIB header's size field.

In its simplest form, a BMP file contains three structures in sequence: the 14-byte bitmap file header (BITMAPFILEHEADER), which identifies the file and records the offset of the pixel array; a DIB header — most commonly BITMAPINFOHEADER — whose size determines the header variant; and the pixel array, which holds the image data, with each row (scan line) padded to a multiple of four bytes.

Beyond this minimal layout, a file may contain further structures, depending on the pixel format and the header variant:

  • Color masks — RGB masks may follow a BITMAPINFOHEADER when biCompression is BI_BITFIELDS; in BITMAPV4HEADER and later, the masks are stored as header fields.
  • Color table — an array of RGBQUAD entries; required for indexed-color images (8 bpp or less) and normally absent at 16 bpp and above.
  • ICC color profile — available only with BITMAPV5HEADER; it may be embedded in the file or referenced by a path to an external profile.[17]

Because the pixel array and the optional profile are located by offset fields rather than fixed positions, the format also permits small alignment gaps before them. In practice such gaps are almost always absent.

File header

[edit]

This block of bytes (BITMAPFILEHEADER) stands at the start of the file and is used to identify it: an application typically reads it first to confirm that the file is a BMP file and is not damaged.

Windows BITMAPFILEHEADER[2]
Offset (bytes) Size (bytes) Member[18] Description
0 2 bfType The header field used to identify the file; it must be BM (the ASCII characters "B" and "M", 0x4D42).
2 4 bfSize The size of the BMP file in bytes
6 2 bfReserved1 Reserved; must be zero
8 2 bfReserved2 Reserved; must be zero
10 4 bfOffBits The offset, i.e. starting address, of the byte where the bitmap image data (pixel array) can be found.

DIB header

[edit]

The DIB header records the image's dimensions, color depth, compression method and related properties. It comes in several variants that all begin with a 32-bit size field, which tells an application which variant is present, since Microsoft extended the format several times. The 12-byte BITMAPCOREHEADER is the oldest and simplest variant; the 40-byte BITMAPINFOHEADER introduced with Windows 3.0 is the common format still written today, and BITMAPV4HEADER and later extend it further.

Windows DIB headers
Size (bytes) Header name OS support Features
12 BITMAPCOREHEADER OS/2 1.1[3]; Windows 3.0[7][8] The original and smallest DIB header; stores width and height as 16-bit values and supports no compression.
40 BITMAPINFOHEADER Windows 3.0[7][2] Extends bitmap width and height to 4 bytes. Adds RLE compression.
108 BITMAPV4HEADER Windows NT 4.0, 95[2] Adds color space type and gamma correction
124 BITMAPV5HEADER Windows 2000, 98[4] Adds a rendering intent and ICC color profiles

The 12-byte BITMAPCOREHEADER — identical to the OS/2 1.1 header (detailed below) — contains:

Windows BITMAPCOREHEADER[19]
Offset (bytes) Size (bytes) Member Description
14 4 bcSize The size of this header, in bytes (12)
18 2 bcWidth The bitmap width in pixels (unsigned 16-bit)
20 2 bcHeight The bitmap height in pixels (unsigned 16-bit)
22 2 bcPlanes The number of color planes (must be 1)
24 2 bcBitCount The number of bits per pixel

For compatibility reasons, most applications write the older BITMAPINFOHEADER, which remains the common Windows format; it is described in the next table. Unless explicitly noted, the members in this table are unsigned integers.

Windows BITMAPINFOHEADER[2]
Offset (bytes) Size (bytes) Member[20] Description
14 4 biSize The size of this header, in bytes (40)
18 4 biWidth The bitmap width in pixels (signed integer, but required to be positive)[21]
22 4 biHeight The bitmap height in pixels (signed integer, must not be zero); a negative value selects top-down row order (see below)[21]
26 2 biPlanes The number of color planes (must be 1)
28 2 biBitCount The number of bits per pixel, which is the color depth of the image. Typical values are 1, 4, 8, 16, 24 and 32.
30 4 biCompression The compression method being used. Listed below
34 4 biSizeImage The image size. This is the size of the raw bitmap data; a dummy 0 can be given for BI_RGB bitmaps.
38 4 biXPelsPerMeter The bitmap's intended horizontal resolution on the target device, in pixels per meter (signed integer); an application can use it to pick the best-matching resource or print scale, but GDI itself never reads the field. 0 means unspecified.[16]
42 4 biYPelsPerMeter The intended vertical resolution, in pixels per meter (signed integer); see biXPelsPerMeter above[16]
46 4 biClrUsed The number of color table entries used by the bitmap, or, for 16 bpp and higher, the size of a color table used for palette optimization only — not as an index table for pixel values; 0 means the default size (see below)
50 4 biClrImportant The number of color table entries considered important for display, or 0 if all are (see below)

Versions after BITMAPINFOHEADER only add fields to its end. Two further extensions, rarely encountered and never officially documented by Microsoft, are known: the 52-byte BITMAPV2INFOHEADER adds fields to BITMAPINFOHEADER for red, green and blue color masks, and the 56-byte BITMAPV3INFOHEADER in turn adds a field to BITMAPV2INFOHEADER for an alpha channel mask, together forming an RGBA mask set later standardized as header fields in BITMAPV4HEADER (see below). Their existence was confirmed by an Adobe employee, who stated that this documentation had at one point been included in official Microsoft documentation.[22] The same engineer stated that Photoshop writes only two DIB header sizes — the 40-byte BITMAPINFOHEADER and the 56-byte BITMAPV3INFOHEADER — reserving the latter for its advanced formats, among them 16-bpp images that carry an alpha channel, such as A1R5G5B5 and A4R4G4B4.[22] GIMP likewise offers 16-bpp A1R5G5B5 among its documented BMP export formats.[23]

The compression method (offset 30) is most often BI_RGB (0), meaning no compression. BI_RLE8 (1) and BI_RLE4 (2) apply run-length encoding and are limited to 8- and 4-bpp bitmaps respectively. BI_BITFIELDS (3), restricted to 16- or 32-bpp images,[20] means that three color masks specify the RGB bit layout for each pixel; their placement relative to the header is detailed below.

A handful of further values exist but are rarely encountered in practice: BI_JPEG (4) and BI_PNG (5) embed a JPEG or PNG image in place of raw pixel data (from BITMAPV4HEADER on); these values are documented as valid only for the StretchDIBits and SetDIBitsToDevice functions, and only when their destination is a printer device, letting an application forward already-compressed image data straight to printers with hardware JPEG/PNG support rather than for general bitmap storage or display.[24] BI_ALPHABITFIELDS (6) is a Windows CE extension, valid in Windows CE .NET 4.0 and later,[25] and is described below; Windows CE also departs from the desktop format with a non-standard 2 bpp format (below). BI_CMYK (11), BI_CMYKRLE8 (12) and BI_CMYKRLE4 (13) appear only inside Windows Metafiles, holding uncompressed, RLE-8 and RLE-4 CMYK images respectively.[6]

BITMAPV4HEADER and later reuse BITMAPINFOHEADER's first 40 bytes unchanged, each member merely renamed with a bV4/bV5 prefix, and then append further fields.

Windows BITMAPV4HEADER extension fields
Offset (bytes) Size (bytes) Member[26] Description
54 4 bV4RedMask Mask selecting the red bits of each pixel; used only when bV4Compression is BI_BITFIELDS (see Color masks below)
58 4 bV4GreenMask Mask selecting the green bits of each pixel
62 4 bV4BlueMask Mask selecting the blue bits of each pixel
66 4 bV4AlphaMask Mask selecting the alpha bits of each pixel
70 4 bV4CSType The color space of the DIB. The possible values are listed below
74 36 bV4Endpoints The CIE XYZ coordinates of the color space's red, green and blue endpoints, used only when bV4CSType is LCS_CALIBRATED_RGB
110 4 bV4GammaRed Gamma response curve for red, in unsigned 16.16 fixed-point format; used only when bV4CSType is LCS_CALIBRATED_RGB
114 4 bV4GammaGreen Gamma response curve for green
118 4 bV4GammaBlue Gamma response curve for blue

BITMAPV5HEADER in turn keeps every BITMAPV4HEADER field unchanged, renamed with a bV5 prefix, and appends four more fields to support linked or embedded ICC color profiles:

Windows BITMAPV5HEADER extension fields
Offset (bytes) Size (bytes) Member[27] Description
122 4 bV5Intent The rendering intent to use for the bitmap. The possible values are listed below
126 4 bV5ProfileData Offset, in bytes from the start of this header, to an embedded or linked ICC profile
130 4 bV5ProfileSize Size, in bytes, of the embedded profile data
134 4 bV5Reserved Reserved; should be zero

Color management

[edit]

bV4CSType and bV5CSType (offset 70) identify the color space of the DIB.[28][29] LCS_CALIBRATED_RGB (0) means the endpoints and gamma values are given in the endpoint and gamma fields of the BITMAPV4HEADER extension table above; LCS_sRGB (0x73524742) selects sRGB, and LCS_WINDOWS_COLOR_SPACE (0x57696E20) the Windows default color space, which on modern Windows is sRGB.[30] These three logical color-space values are available in BITMAPV4HEADER and are also valid in BITMAPV5HEADER.

BITMAPV5HEADER accepts two further values for bV5CSType: PROFILE_LINKED (0x4C494E4B) and PROFILE_EMBEDDED (0x4D424544), specific to it since BITMAPV4HEADER lacks the profile-data fields they require. For all values other than LCS_CALIBRATED_RGB, the endpoint and gamma fields above are ignored.[27]

When bV5CSType is PROFILE_LINKED or PROFILE_EMBEDDED, bV5ProfileData gives the offset, in bytes from the beginning of the BITMAPV5HEADER structure, to the profile data; for a packed DIB, and similarly in the BMP file format, this data follows the pixel array.[27] For PROFILE_EMBEDDED, the data found there is the ICC profile itself; for PROFILE_LINKED, it is instead the null-terminated path of an external profile file — which may be a fully qualified local or network path — composed of characters from the Windows-1252 code page, not Unicode. For an embedded profile, bV5ProfileSize gives the size of the profile data in bytes.[27]

bV5Intent (offset 122, BITMAPV5HEADER only) sets the rendering intent.[27][31][32] It can be LCS_GM_BUSINESS (1), the ICC Saturation intent, which maintains saturation and is used for business charts and other situations requiring undithered colors; LCS_GM_GRAPHICS (2), Relative Colorimetric, which maintains a colorimetric match and is used for graphic designs and named colors; LCS_GM_IMAGES (4), Perceptual, which maintains contrast and is used for photographs and natural images; or LCS_GM_ABS_COLORIMETRIC (8), Absolute Colorimetric, which maintains the white point and matches colors to their nearest color in the destination gamut.

Several classic GDI bitmap functions use the color-space information in the header when performing color matching: CreateDIBitmap, CreateDIBSection, SetDIBits, SetDIBitsToDevice and StretchDIBits do so only when it is BITMAPV4HEADER or BITMAPV5HEADER; for any other header, the current device context's own color profile (or, failing that, sRGB) is used instead.[33]

Color masks

[edit]

Color masks specify exactly which bits, within a 16- or 32-bit pixel, belong to each color channel. These masks can be supplied in two ways: when the compression method is BI_BITFIELDS, three DWORD color masks — for red, green and blue — follow the header;[2] alternatively, versions after BITMAPINFOHEADER include the masks as part of the header itself (see above for how this developed across versions), with all four — red, green, blue and alpha — officially documented as header fields from BITMAPV4HEADER onward.[26] Of these, only the red, green and blue masks are tied to BI_BITFIELDS — valid only under that compression method, whichever way they are supplied — while the alpha mask, available only as a header field, carries no such restriction and is described as always valid, regardless of compression method.[26][34] The following example illustrates the mechanism:

A sample 16-bit color-mask layout, R5G6B5, from the most significant bit to the least
ChannelBit positionsWidth (bits)Mask
Red15–1150x0000F800
Green10–560x000007E0
Blue4–050x0000001F

The bit fields defined by the color masks must be contiguous and non-overlapping, but their order is arbitrary; a common bit-significance ordering is A-R-G-B, from the most significant bit to the least significant.[2]

A sample 32-bit color-mask layout, A8R8G8B8, in the most common order, with the alpha mask supplied as a header field
ChannelBit positionsWidth (bits)Mask
Alpha31–2480xFF000000
Red23–1680x00FF0000
Green15–880x0000FF00
Blue7–080x000000FF

When no masks are supplied at all, a fixed default layout is assumed for the bit depth, shown below for every depth.

The standard pixel formats in a DIB
Bits per pixel BITMAPCOREHEADER
(no compression)[19]
BITMAPINFOHEADER and later[20]d
BI_RGB BI_BITFIELDS
1 2 colorsa up to 2 colorsb Not defined
4 16 colorsa up to 16 colorsb Not defined
8 256 colorsa up to 256 colorsb Not defined
16 Not defined X1R5G5B5 user-defined masksc
24 R8G8B8 R8G8B8 Not defined
32 Not defined X8R8G8B8 user-defined masksc
a Color table entries are 3-byte RGBTRIPLE values, and the table is always full-size, with no biClrUsed-style override.[3][16]  

b Color table entries are 4-byte RGBQUAD values; a smaller count may be given instead.[16]   c Any contiguous, non-overlapping red, green and blue bit masks — for example R5G6B5 at 16 bpp.[2]  

d Versions after BITMAPINFOHEADER can also declare a separate alpha mask as a header field (see above), valid independently of whether the compression method is BI_RGB or BI_BITFIELDS.[26][34]

A less common extension, found on Windows CE, adds a fourth compression value, BI_ALPHABITFIELDS, which appends a fourth mask, for alpha, directly after the three color masks — the trailing-mask counterpart, for the plain BITMAPINFOHEADER, of the alpha mask that versions after it instead carry as a header field, officially documented as such from BITMAPV4HEADER onward.[25]

Color table

[edit]

The color table, or palette, lists the colors used by the image. In an indexed-color bitmap each pixel is stored as a number of bits (1, 4 or 8) that form an index into this table; the entry it selects gives the color the pixel is displayed in.[2] The table thus tells the application which actual color each index value represents. When present, it follows the header and any trailing color masks (see above).

For indexed-color images, the default number of entries is 2n, where n is the bit depth (the biBitCount member); a smaller count may be given instead in the biClrUsed member, and a value of zero means the table uses the full, default size for that bit depth.[20] The biClrImportant member can likewise record how many of those color indexes are actually required to display the bitmap; a value of zero means all of them are.[20] Unlike biClrUsed, biClrImportant is purely advisory for applications — GDI itself never reads it.[16]

In Windows bitmaps each entry occupies 4 bytes in the order blue, green, red, 0x00 — the X8R8G8B8 layout (a RGBQUAD), whose fourth byte is reserved rather than a true alpha channel.

The BITMAPCOREHEADER format handles the color table differently: it supports only the full-size table, with no biClrUsed-style override, and each entry is 3 bytes, in blue, green, red order (a RGBTRIPLE), rather than the 4-byte RGBQUAD used elsewhere.[3][16]

Because the palette is always stored explicitly in the file, the choice of colors is left to the encoder.[2] A monochrome (1 bpp) image carries a two-entry table that is most often black and white, although the two entries are ordinary palette colors and may be any pair. By convention, 16-color (4 bpp) images tend to use a fixed, standard palette — typically the 16-color VGA/EGA palette, whose entries also correspond closely to the reserved static colors that Windows keeps in its system palette and does not allow to be changed.[35] 256-color (8 bpp) images, by contrast, are more often given a palette tailored to the individual image through color quantization.

One edge case falls outside this description: for DIBs held in memory rather than in a file, the color table may instead consist of 2-byte entries that are indexes into the currently realized palette,[36] rather than explicit color values.

At 16 bpp and higher the pixels carry their color directly, so a color table is normally absent, but it may be present as a palette for optimizing colors on palette-based devices — in which case biClrUsed specifies its size.[20] Even then, it is not an indexed palette, and none of its entries are read back as pixel indices.

Pixel array

[edit]

The pixel array (also called the bitmap data) holds the actual image, one row (also called a scan line) at a time; its offset from the start of the file is given by the file header, after the DIB header and any color table or color masks.[16] The size of a stored row, including padding, is commonly called its stride. For uncompressed bitmaps, the pixel array consists of such DWORD-aligned scan lines; RLE-compressed bitmaps instead hold a variable-length encoded stream (see below).

Row order

[edit]

Rows are usually stored "bottom-up": the first row of the pixel data is the bottom of the image, and each row runs left to right.[16] When the Image Height value is negative, an uncompressed bitmap is instead stored "top-down", with the first row at the top of the image;[16] top-down DIBs cannot be compressed, so their compression value must be BI_RGB or BI_BITFIELDS.[20] BITMAPCOREHEADER can never select top-down order this way, since its height field is unsigned (see above).

Row padding

[edit]

The size of each row is rounded up to a multiple of 4 bytes (a 32-bit DWORD) by padding; the padding bytes are not necessarily zero.[37][38] The total number of bytes necessary to store one row of pixels can be calculated as:

ImageWidth is expressed in pixels. The equation above uses the floor and ceiling functions.

For images with height above 1, multiple padded rows are stored consecutively, forming the pixel array, whose total size 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. This formula applies to uncompressed pixel arrays only; RLE-compressed bitmaps hold a variable-length encoded data stream instead (see below).

When the pixel array is loaded into memory, each row must begin at a memory address that is a multiple of 4; this restriction applies only in memory — for file storage, only the size of each row must be a multiple of 4 bytes, while the offset of the pixel array itself can be arbitrary.[16] A 24 bpp 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.

Pixel formats

[edit]

The BITMAPINFOHEADER (and later) supports 1, 4, 8, 16, 24 and 32 bpp;[20] the older BITMAPCOREHEADER is limited to 1, 4, 8 or 24 bpp, its bcBitCount field excluding 16 and 32.[19] Within a row, pixels are packed as follows:

  • At 1 bpp, each bit is one pixel, the left-most pixel in the most significant bit of the first byte; each bit indexes a two-entry color table.[16]
  • At 4 bpp, each byte holds two pixels, the left-most in the more significant nibble; each nibble indexes a color table of up to 16 colors.[16]
  • At 8 bpp, each byte is one pixel, indexing a color table of up to 256 colors.[16]
  • At 16 bpp, each pixel is a 2-byte WORD; by default its bits form the X1R5G5B5 layout (the top bit unused), or one given by color masks (commonly R5G6B5).[20]
  • At 24 bpp, each pixel is 3 bytes in blue, green, red order (R8G8B8).[16][38]
  • At 32 bpp, each pixel is a 4-byte DWORD; by default its bits form the X8R8G8B8 layout (the high byte unused), or one given by color masks (commonly A8R8G8B8).[20][39]

The standard BI_RGB layout does not assign a color channel to the fourth byte of a 32-bit pixel. Windows' GDI can nonetheless treat it as a per-pixel alpha value: its AlphaBlend function supports per-pixel alpha only for 32-bit BI_RGB data, always taking the alpha from a fixed high byte (the bytes being blue, green, red, alpha in memory) — no color mask is involved, and this holds regardless of which DIB header describes the bitmap, so even a BITMAPV4HEADER's or BITMAPV5HEADER's own bV4AlphaMask field is not consulted.[14] AlphaBlend expects the alpha to be premultiplied and has been available since Windows 2000.[15] Applications that parse the header themselves, by contrast, such as GIMP and Google Chrome, do honor a declared bV4AlphaMask when reading a file.[40][41]

A few pixel formats fall outside this standard set. At 2 bpp, found only on Windows CE, each byte holds four pixels, the left-most in the two most significant bits, each indexing a color table of up to 4 colors.[42] At 64 bpp, a GDI+-specific extension to the header's bit-depth field (undocumented in the core BITMAPINFOHEADER spec),[43] each of the alpha, red, green and blue channels occupies 16 bits.[39]

Compression

[edit]

Indexed images at 4 or 8 bpp may be compressed with a run-length encoding (RLE) scheme, BI_RLE4 or BI_RLE8 respectively (see the compression values above); ordinary pixel arrays at 1, 16, 24 or 32 bpp are otherwise always stored uncompressed, and any depth may be stored uncompressed if desired.[2] BI_JPEG and BI_PNG are a separate case, reserved for specific GDI printer operations rather than ordinary pixel storage (see the compression values above).[24] A run is normally encoded, in encoded mode, as a count byte followed by a single byte that either gives the color index to repeat (BI_RLE8) or packs two alternating color indices into its high and low nibbles (BI_RLE4); a count of zero instead introduces one of three escapes: end of line, end of bitmap, or a delta that skips to a new position without drawing. In absolute mode (also flagged by a zero count byte), the following byte instead gives the number, 3–255, of literal pixels that follow — one color-index byte per pixel for BI_RLE8, or two nibble-packed pixels per byte for BI_RLE4 — with the run zero-padded to end on a 16-bit word boundary.[44][38]

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

Example

[edit]

The following is an example of a 2×2-pixel, 24 bpp (R8G8B8) bitmap using the Windows BITMAPINFOHEADER DIB header.

Offset (bytes) Size (bytes) Hex value Value Description
File header
0 2 42 4D "BM" ID field (42 4D)
2 4 46 00 00 00 70 bytes (54+16) Size of the BMP file (54 bytes header + 16 bytes data)
6 2 00 00 0 bfReserved1 — reserved; must be zero
8 2 00 00 0 bfReserved2 — reserved; must be zero
10 4 36 00 00 00 54 bytes (14+40) Offset where the pixel array (bitmap data) can be found
DIB header
14 4 28 00 00 00 40 bytes Number of bytes in the DIB header (from this point)
18 4 02 00 00 00 2 pixels (left to right order) Width of the bitmap in pixels
22 4 02 00 00 00 2 pixels (bottom to top order) Height of the bitmap in pixels. Positive for bottom to top pixel order.
26 2 01 00 1 plane Number of color planes being used
28 2 18 00 24 bits Number of bits per pixel
30 4 00 00 00 00 0 BI_RGB, no pixel array compression used
34 4 10 00 00 00 16 bytes Size of the raw bitmap data (including padding)
38 4 13 0B 00 00 2835 pixels/metre horizontal Print resolution of the image,
72 DPI × 39.3701 inches per metre yields 2834.6472
42 4 13 0B 00 00 2835 pixels/metre vertical
46 4 00 00 00 00 0 colors Number of colors in the palette
50 4 00 00 00 00 0 important colors 0 means all colors are important
Pixel array
54 3 00 00 FF 0 0 255 Red, Pixel (x=0, y=1)
57 3 FF FF FF 255 255 255 White, Pixel (x=1, y=1)
60 2 00 00 0 0 Padding for 4 byte alignment (could be a value other than zero)
62 3 FF 00 00 255 0 0 Blue, Pixel (x=0, y=0)
65 3 00 FF 00 0 255 0 Green, Pixel (x=1, y=0)
68 2 00 00 0 0 Padding for 4 byte alignment (could be a value other than zero)

This example illustrates several properties of the BMP format at once. The pixel array begins at offset 54, immediately after the 14-byte file header and 40-byte DIB header. Because the image is 24 bpp and two pixels wide, each row contains 6 bytes of pixel data and 2 bytes of padding. The positive height means that the first stored row is the bottom row of the image.

OS/2 bitmap format

[edit]

The headers and behavior described in this section are OS/2-specific — rarely produced by current software, but still occasionally encountered when reading older bitmap files.

IBM's documentation, and the Microsoft-published OS/2 Programmer's Reference, name the OS/2 1.x and 2.x DIB headers BITMAPINFOHEADER and BITMAPINFOHEADER2 respectively — the names this section uses below.[13][12]

Structurally, an OS/2 bitmap file is a chain of structures, each nested as a literal member of the structure enclosing it, down to the pixel array at the bottom. When the file uses the bitmap-array container format (see below), a bitmap-array header sits at the very top of this chain — itself never nested inside anything else — wrapping an ordinary file header, which in turn wraps a DIB header, itself immediately followed by a color table when one is present.[13] Because of this nesting, each structure's own recorded size is cumulative: a BITMAPFILEHEADER is 26 bytes (14 plus its nested 12-byte BITMAPINFOHEADER), a BITMAPFILEHEADER2 up to 78 (14 plus a BITMAPINFOHEADER2 of up to 64 bytes, less if truncated; see below), a BITMAPARRAYFILEHEADER 40 (14 plus the 26-byte BITMAPFILEHEADER), and a BITMAPARRAYFILEHEADER2 up to 92 (14 plus a BITMAPFILEHEADER2 of up to 78 bytes).[13][45] In practice, though, this recorded size (cbSize) is often simply written as 0;[3] parsers should instead rely on the nested header's own size field to determine its variant — just as usType (below) determines the resource type — and on offNext rather than cbSize to walk a bitmap array.[45]

File headers

[edit]

This file header is analogous to the Windows BITMAPFILEHEADER (above), but with two differences: Windows' two reserved 16-bit fields instead hold the X and Y coordinates of a hotspot, used only when the file is an icon or pointer; and the size field records the size of the header structure itself, rather than the size of the whole file.[13][46]

Its type field (usType in IBM's BITMAPFILEHEADER/BITMAPFILEHEADER2, bfType in Windows) also records which kind of resource the file holds:

OS/2 usType signatures[13][3]
Signature Value (hex) Constant Resource type
BM 0x4D42 BFT_BMAP Bitmap
BA 0x4142 BFT_BITMAPARRAY Bitmap array
IC 0x4349 BFT_ICON Icon
CI 0x4943 BFT_COLORICON Color icon
PT 0x5450 BFT_POINTER Pointer (mouse cursor)
CP 0x5043 BFT_COLORPOINTER Color pointer
OS/2 BITMAPFILEHEADER/BITMAPFILEHEADER2[13][46][12]
Offset (bytes) Size (bytes) Member Description
0 2 usType The resource-type signature (see the table above)
2 4 cbSize The size of this file header structure in bytes — nominally cumulative with its nested DIB header, but in practice often simply written as 0 (see above); Windows' bfSize instead gives the size of the entire file
6 2 xHotspot For an icon or pointer, the X coordinate of its hotspot; ignored for plain bitmaps (occupies the position of Windows' unused bfReserved1)
8 2 yHotspot The corresponding Y coordinate of the hotspot (Windows' bfReserved2)
10 4 offBits The offset, in bytes, from the start of this structure to the pixel data (Windows' bfOffBits)
14 variable bmp / bmp2 The nested information header: BITMAPINFOHEADER inside a BITMAPFILEHEADER, BITMAPINFOHEADER2 inside a BITMAPFILEHEADER2 (see below)

Bitmap arrays

[edit]

A separate container format, with no Windows counterpart, bundles several device-dependent or device-independent renderings of the same bitmap, icon or pointer — for different display resolutions or color depths — together in one file as a bitmap array. Each rendering gets its own complete chain, headed by a BITMAPARRAYFILEHEADER (OS/2 1.x) or BITMAPARRAYFILEHEADER2 (OS/2 2.x), signature BA, wrapping an ordinary file header for that rendering. These per-rendering chains sit side by side in the file rather than nested inside one another: their array headers form a singly linked list, each one pointing, via an absolute file offset rather than one relative to itself, to the next (zero ending the chain); each also carries the pixel dimensions of the display device it targets (for example, 640×480 for VGA), and the device-independent rendering is required to come first.[13][3]

OS/2 BITMAPARRAYFILEHEADER/BITMAPARRAYFILEHEADER2[13][3]
Offset (bytes) Size (bytes) Member Description
0 2 usType BFT_BITMAPARRAY (BA)
2 4 cbSize The size of this array-header structure in bytes — nominally cumulative with its nested file header (see above)
6 4 offNext The absolute file offset of the next array header — not an offset relative to this one — or zero if this is the last one
10 2 cxDisplay The width, in pixels, of the display device this rendering targets (for example, 640 for VGA)
12 2 cyDisplay The corresponding height of the target display device (for example, 480 for VGA)
14 variable bfh / bfh2 The file header for this rendering (BITMAPFILEHEADER or BITMAPFILEHEADER2)

IBM shipped its own system icons this way: a single array could bundle a 32×32 4 bpp rendering for VGA together with a 40×40 4 bpp rendering for 8514/A and XGA displays, alongside smaller 1 bpp 32×32, 20×20 and 16×16 mini-icon renderings.[13]

Icons and pointers

[edit]

Icons and pointers (mouse cursors) are stored as bitmaps using the same family of file headers, with the hotspot recorded in the file header. The AND and XOR masks always occupy a single 1-bit-per-pixel bitmap twice the declared height (BFT_ICON/BFT_POINTER), XOR first and AND second — the same arrangement used by monochrome Windows icons and cursors. A color icon or pointer (BFT_COLORICON/BFT_COLORPOINTER) adds a separate color layer after this one, giving two consecutive file headers: the AND/XOR bitmap first, the color layer second. For the mechanics of combining these masks, see ICO/CUR.[13][47]

DIB headers

[edit]

The OS/2 1.1 header (BITMAPINFOHEADER) is byte-for-byte identical to the Windows BITMAPCOREHEADER (detailed above), merely using IBM's own field names — cbFix, cx, cy, cPlanes and cBitCount, corresponding to Windows' bcSize, bcWidth, bcHeight, bcPlanes and bcBitCount respectively.[19]

The OS/2 2.x BITMAPINFOHEADER2 corresponds field-for-field to the Windows 3.0 BITMAPINFOHEADER (above), then adds 24 further bytes:[13][3][48]

OS/2 BITMAPINFOHEADER2, additional fields[3]
Offset (bytes) Size (bytes) Member[13] Description[3]
54 2 usUnits An enumerated value specifying the units for the horizontal and vertical resolutions (offsets 38 and 42). The default value, BRU_METRIC (0), means pixels per metre
56 2 usReserved Padding. Ignored and should be zero
58 2 usRecording An enumerated value indicating the direction in which the bits fill the bitmap. The default value, BRA_BOTTOMUP (0), means 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

60 2 usRendering An enumerated value indicating a halftoning algorithm that should be used when rendering the image.
62 4 cSize1 Halftoning parameter 1 (see below)
66 4 cSize2 Halftoning parameter 2 (see below)
70 4 ulColorEncoding An enumerated value indicating the color encoding for each entry in the color table. The default value, BCE_RGB (0), specifies RGB triples
74 4 ulIdentifier An application-defined identifier. Not used for image rendering

The structure can be truncated after cBitCount or any subsequent field, with the omitted fields taking their default (generally zero) values[13][49] — a truncated 16-byte form of the BITMAPINFOHEADER2 is encountered[3] in, for example, the file pal8os2v2-16.bmp[50] of the BMP Suite.[51]

OS/2 bitmaps support only 1, 4, 8, or 24 bpp.[13][3][16]

Compression

[edit]

OS/2 2.x stores the compression scheme in the same field as Windows (ulCompression), but assigns some of the same values to different, OS/2-specific schemes: besides RLE for 4- and 8-bpp images (shared with Windows), it defines BCA_HUFFMAN1D (3), a modified Huffman encoding for bi-level (1 bpp) images, and BCA_RLE24 (4), a run-length encoding for 24 bpp images.[13][3]

Halftoning

[edit]

Rather than affecting how the pixel data itself is stored, usRendering (offset 60) records which halftoning algorithm should be used when rendering the image.[13] Its default and most common value, BRH_NOTHALFTONED (0), disables halftoning. BRH_ERRORDIFFUSION (1) selects error diffusion, whose damping is set by halftoning parameter 1 (cSize1, offset 62) as a percentage — 100 indicating no damping, 0 indicating that errors are not diffused. BRH_PANDA (2) selects PANDA, the Processing Algorithm for Non-coded Document Acquisition,[52] and BRH_SUPERCIRCLE (3) selects the Super Circle algorithm;[53] for both, halftoning parameters 1 and 2 (cSize1/cSize2, offsets 62 and 66, respectively) give the X and Y dimensions, in pixels, of the halftoning pattern used.

References

[edit]
  1. ↑ "IANA Considerations". Windows Image Media Types. IETF. sec. 5. doi:10.17487/RFC7903. RFC 7903.
  2. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 James D. Murray; William vanRyper (April 1996). "Microsoft Windows Bitmap". Encyclopedia of Graphics File Formats (Second ed.). O'Reilly. p. 572. ISBN 1-56592-161-5. Retrieved 2014-03-07.
  3. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 James D. Murray; William vanRyper (April 1996). "OS/2 Bitmap". Encyclopedia of Graphics File Formats (Second ed.). O'Reilly. p. 630. ISBN 1-56592-161-5. Retrieved 2014-03-07.
  4. 1 2 3 4 "Bitmap Image File (BMP), Version 5". Digital Preservation. Library of Congress. 2014-01-08. Retrieved 2014-03-11.
  5. ↑ Julian Smart; Stefan Csomor & Kevin Hock (2006). Cross-Platform GUI Programming with Wxwidgets. Prentice Hall. ISBN 0-13-147381-6.
  6. 1 2 3 "[MS-WMF]: Windows Metafile Format". Open Specifications. Microsoft. Retrieved 2026-09-13.
  7. 1 2 3 4 5 6 7 Microsoft Corporation (1990). Microsoft Windows Programmer's Reference. Microsoft Press. "Device-Independent Bitmap Functions"; the BITMAPINFOHEADER, BITMAPFILEHEADER, and BITMAPCOREHEADER structures. ISBN 1-55615-309-0. Retrieved 2026-09-13.
  8. 1 2 3 4 Petzold, Charles (1990). "Bits, Bits, and Metafiles". Programming Windows (2nd ed.). Microsoft Press. Retrieved 2026-09-13.
  9. ↑ Microsoft Corporation (1987). Microsoft Windows Software Development Kit: Programmer's Reference (Version 2.0 ed.). Microsoft Corporation. BITMAP data structure; CreateBitmap and CreateCompatibleBitmap functions. Document No. 050051053-200-102-1087. Retrieved 2026-09-13.
  10. ↑ Heller, Martin (December 1990). "I've Got DIBs". Beyond DOS: Windows and OS/2. BYTE. pp. 101–104. Retrieved 2026-09-18.
  11. ↑ Chen, Raymond (2021-05-25). "Why are device-independent bitmaps upside-down?". The Old New Thing. Microsoft. Retrieved 2026-09-19.
  12. 1 2 3 4 Microsoft Corporation (1989). Microsoft Operating System/2 Programmer's Reference (PDF). Vol. 2 (Version 1.1 ed.). Microsoft Press. BITMAPINFO and BITMAPINFOHEADER data types. ISBN 1-55615-221-3. Retrieved 2026-09-13.
  13. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 IBM Corporation (March 1992). OS/2 2.0 Presentation Manager Programming Reference, Volume 3 (First ed.). IBM. Appendix A ("Data Types") and Appendix D ("Standard Bit-Map Formats"). Order No. S10G-6272-00. Retrieved 2026-09-13.
  14. 1 2 "Alpha Blending (Windows GDI)". Win32 apps. Microsoft. "Alpha values per pixel are only supported for 32-bpp BI_RGB". Retrieved 2026-09-14.
  15. 1 2 "BLENDFUNCTION (wingdi.h)". Win32 apps. Microsoft. the AC_SRC_ALPHA value of the AlphaFormat member, and Remarks. Retrieved 2026-09-14.
  16. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 "DIBs and Their Use". Microsoft. Retrieved 2026-09-13.
  17. ↑ "Bitmap Header Types". Win32 apps. Microsoft. Retrieved 2026-09-13.
  18. ↑ "BITMAPFILEHEADER (wingdi.h)". Win32 apps. Microsoft. Retrieved 2026-09-13.
  19. 1 2 3 4 "BITMAPCOREHEADER (wingdi.h)". Win32 apps. Microsoft. Retrieved 2026-09-14.
  20. 1 2 3 4 5 6 7 8 9 10 "BITMAPINFOHEADER structure". Microsoft. biClrUsed, biClrImportant and biBitCount members. Retrieved 2026-09-13.
  21. 1 2 "[MS-WMF]: BitmapInfoHeader Object". Open Specifications. Microsoft. Retrieved 2026-09-15.
  22. 1 2 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.
  23. ↑ "Export as BMP". GIMP User Manual. The GIMP Documentation Team. Retrieved 2026-09-16.
  24. 1 2 "JPEG and PNG Extensions for Specific Bitmap Functions and Structures". Win32 apps. Microsoft. Retrieved 2026-09-13.
  25. 1 2 "BITMAPINFOHEADER (Windows CE 5.0)". Microsoft. BI_ALPHABITFIELDS in the biCompression member. Retrieved 2026-09-13.
  26. 1 2 3 4 "BITMAPV4HEADER (wingdi.h)". Win32 apps. Microsoft. bV4RedMask, bV4GreenMask, bV4BlueMask and bV4AlphaMask members. Retrieved 2026-09-14.
  27. 1 2 3 4 5 "BITMAPV5HEADER (wingdi.h)". Win32 apps. Microsoft. Retrieved 2026-09-14.
  28. ↑ "[MS-WMF]: LogicalColorSpace Enumeration". Open Specifications. Microsoft. Retrieved 2026-09-15.
  29. ↑ "[MS-WMF]: LogicalColorSpaceV5 Enumeration". Open Specifications. Microsoft. Retrieved 2026-09-15.
  30. ↑ "Using Structures in WCS 1.0". Win32 apps. Microsoft. table "Differences Between V4 and V5 Headers". Retrieved 2026-09-14.
  31. ↑ "[MS-WMF]: GamutMappingIntent Enumeration". Open Specifications. Microsoft. Retrieved 2026-09-15.
  32. ↑ "Rendering Intents". Win32 apps. Microsoft. Retrieved 2026-09-16.
  33. ↑ "Using GDI Functions With WCS". Win32 apps. Microsoft. table "Bitmap Functions with WCS". Retrieved 2026-09-14.
  34. 1 2 "[MS-WMF]: BitmapV4Header Object". Open Specifications. Microsoft. RedMask, GreenMask and BlueMask ("MUST be ignored" unless BI_BITFIELDS) vs. AlphaMask (no such restriction). Retrieved 2026-09-15.
  35. ↑ "RGBA Mode and Windows Palette Management". Win32 apps. Microsoft. the defaultpal array; "the standard 20 colors in the system palette cannot be changed". Retrieved 2026-09-14.
  36. ↑ "BITMAPINFO (wingdi.h)". Win32 apps. Microsoft. Retrieved 2026-09-13.
  37. ↑ "Image Stride". Win32 apps. Microsoft. Retrieved 2026-09-13.
  38. 1 2 3 Charlap, David (April 1995). "The BMP File Format, Part 2". Dr. Dobb's Journal. the sections on row padding, 24-bit pixel encoding, and run-length encoding. Retrieved 2026-09-15.
  39. 1 2 "Image Pixel Format Constants (Gdipluspixelformats.h)". Win32 apps. Microsoft. PixelFormat32bppARGB and PixelFormat64bppARGB members, and Remarks. Retrieved 2026-09-15.
  40. ↑ "bmp-load.c". GIMP source code. GIMP. function ReadImage: reads the alpha mask into masks[3] and, if it is nonzero, sets image_type = GIMP_RGBA_IMAGE. Retrieved 2026-09-14.
  41. ↑ "bmp_image_reader.cc". Chromium source code. Chromium. function ProcessBitmasks: "BITMAPV3HEADER+ have an alpha bitmask in the info header... so we respect it at all times". Retrieved 2026-09-14.
  42. ↑ "BITMAPINFOHEADER Structure (Windows CE)". Microsoft. Retrieved 2026-09-13.
  43. ↑ "Types of Bitmaps". Win32 apps. Microsoft. Retrieved 2026-09-13.
  44. ↑ "Bitmap Compression". Win32 apps. Microsoft. Retrieved 2026-09-14.
  45. 1 2 Charlap, David (March 1995). "The BMP File Format, Part 1". Dr. Dobb's Journal. the size field of BITMAPFILEHEADER "is a count of bytes used for the BITMAPFILEHEADER combined with the subsequent BITMAPHEADER". Retrieved 2026-09-15.
  46. 1 2 Microsoft Corporation (1989). Microsoft Operating System/2 Programmer's Reference (PDF). Vol. 3 (Version 1.1 ed.). Microsoft Press. Chapter 5, "File Formats," §5.4.1–5.4.2; the BITMAPFILEHEADER data type. ISBN 1-55615-222-1. Retrieved 2026-09-14.
  47. ↑ Petzold, Charles (1989). "Bitmaps, Icons, Pointers, and Strings". Programming the OS/2 Presentation Manager (PDF). Microsoft Press. ISBN 1-55615-170-5. Retrieved 2026-09-14.
  48. ↑ Kathleen Panov; Arthur Panov & Larry Salomon Jr. (1995). "Resources". The Art of OS/2 Warp Programming. Wiley. ISBN 0-471-08633-9.
  49. ↑ Tabi, Timur (December 1993). "Using OS/2 2.x bitmap files". EDM/2. Vol. 1, no. 7. the cbFix field and its editor's note on variable-length initialization. Retrieved 2026-09-15.
  50. ↑ Summers, Jason (2015-10-30). "pal8os2v2-16.bmp". Retrieved 2016-07-06.
  51. ↑ Summers, Jason (2015-10-30). "BMP Suite". Retrieved 2016-07-06.
  52. ↑ Yi-Hsin Chen; Frederick C. Mintzer; Keith S. Pennington (January 1987). "PANDA: Processing Algorithm for Noncoded Document Acquisition" (PDF). IBM Journal of Research and Development. 31 (1): 32–43. Retrieved 2026-09-14.
  53. ↑ P. Stucki (May 1978). "Halftone Conversion Technique—Super Circle, Symmetric and Asymmetric Dot Placement". IBM Technical Disclosure Bulletin. 20 (12): 5320–5322.
[edit]
  • BMP Suite – a collection of test BMP files covering edge cases and non-standard variants, useful for exercising decoders