File Formats
  • Audio
  • Video
  • Images
  • 3D & CAD
  • Documents
  • Data
  • Code
  • System
Images
  • Raster
  • Vector
  • Camera raw
  • Layered projects
  • HDR & scientific
  • Icons
  • Retro
  1. Home
  2. Images
  3. Raster
  4. BMP
  5. BM
  6. Bit masks
.BMP
  • Overview
  • Windows bitmap (BM)
    • File header
    • DIB header
    • Colour spaces
    • Colour table
    • Bit masks
    • Pixel data
    • Compression
  • OS/2 bitmap array (BA)
  • OS/2 icon (IC)
  • OS/2 colour icon (CI)
  • OS/2 pointer (PT)
  • OS/2 colour pointer (CP)

Bit masks

A 16 or 32-bit pixel holds its colour directly, and bit masks say which of its bits belong to red, green, blue and alpha. They let a BMP store layouts such as 5-6-5 colour or 8-bit alpha.

00000036  00 F8 00 00 E0 07 00 00 1F 00 00 00
Red, green and blue masks for 5-6-5 colour, after a 40-byte header

When masks are used

Masks apply when the compression is BI_BITFIELDS (3), which gives red, green and blue masks, or BI_ALPHABITFIELDS (6), which adds an alpha mask. Both are only valid at 16 and 32 bits per pixel. BI_ALPHABITFIELDS came from Windows CE and is rarely seen elsewhere.

With BI_RGB, no masks are stored and the fixed defaults below apply.

Where they are stored

Where the masks sit depends on the version of the DIB header:

HeaderMasks
BITMAPINFOHEADER, 40 bytesStraight after the header: 12 bytes (red, green, blue) for BI_BITFIELDS, or 16 bytes (adding alpha) for BI_ALPHABITFIELDS.
V2, 52 bytesInside the header at offsets 40, 44 and 48. Nothing extra follows the header.
V3, V4 and V5Inside the header at offsets 40, 44, 48 and 52, including alpha. Nothing extra follows the header.

Each mask is a little-endian 32-bit number. In the example above, the red mask 00 F8 00 00 is 0x0000F800.

Reading a channel

To read a channel, AND the pixel with its mask and shift the result right by the number of zero bits below the mask. The result runs from 0 to the mask’s maximum, such as 31 for a 5-bit mask, so scale it to 0 to 255 for display:

const shift = trailingZeros(mask);
const max = mask >>> shift;
const value = (pixel & mask) >>> shift;
const channel = Math.round(value * 255 / max);
One channel of a pixel, scaled to 8 bits

The set bits of each mask must be one unbroken run, and masks must not overlap. A mask of zero means the channel is absent.

Default and common masks

LayoutRedGreenBlueAlpha
16-bit default, 5-5-50x7C000x03E00x001Fnone, top bit unused
16-bit 5-6-50xF8000x07E00x001Fnone
32-bit default, 8-8-80x00FF00000x0000FF000x000000FFnone, top byte unused
32-bit with alpha0x00FF00000x0000FF000x000000FF0xFF000000

The defaults are used with BI_RGB. For a 32-bit BI_RGB image the top byte is officially unused, though some programs store alpha there; a reader cannot tell for certain, so writers that want alpha should use BI_BITFIELDS with a V4 or V5 header and an alpha mask.

© 2026 fileformats.org About Contact Made by Lewpen