BMP/DIB image file format encoding and decoding utilities using binary structures.
This module provides coders for the classic Windows BMP container:
- bitmapFileHeader — the 14-byte BITMAPFILEHEADER (signature + sizes + pixel offset)
- bitmapInfoHeader — the 40-byte BITMAPINFOHEADER (the most common DIB header)
- bmp — a full file coder for uncompressed (BI_RGB) BITMAPINFOHEADER images without a colour palette, i.e. 16/24/32 bpp.
Design notes
- DIB variants: only BITMAPINFOHEADER (size = 40) is shipped. V4/V5 and the
OS/2 BITMAPCOREHEADER are intentionally out of scope — read the
sizefield from bitmapFileHeader and dispatch externally if you need them. - Pixel-data sizing: the file-level coder derives the pixel buffer length
from the DIB's
width/height/bppviarowStride * |height|, ignoring the (frequently-zero)imageSizefield. Use rowStride / pixelDataSize for stride math when composing your own coders. - Top-down images: a negative
heightis preserved verbatim. We never flip rows for you — pixel orientation is the caller's responsibility. - Palette: ≤ 8bpp images require a colour table between the DIB header and the pixel data; that path is not yet covered by bmp. Use the sub-coders to compose it yourself.
- Endianness: every BMP integer is little-endian.
Round-trip a tiny 2×2 24bpp BMP
Round-trip a tiny 2×2 24bpp BMP
import { assertEquals } from "@std/assert"; import { bmp } from "@binstruct/bmp"; const coder = bmp(); const image = { file: { signature: "BM", fileSize: 70, reserved1: 0, reserved2: 0, pixelOffset: 54, }, dib: { size: 40, width: 2, height: 2, planes: 1, bpp: 24, compression: 0, imageSize: 16, xPixelsPerMeter: 2835, yPixelsPerMeter: 2835, colorsUsed: 0, importantColors: 0, }, // 2 rows × stride 8 = 16 bytes of BGR pixels with 2 bytes padding per row. // deno-fmt-ignore pixelData: new Uint8Array([ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, ]), }; const buffer = new Uint8Array(image.file.fileSize); const bytesWritten = coder.encode(image, buffer); const [decoded, bytesRead] = coder.decode(buffer); assertEquals(bytesWritten, 70); assertEquals(bytesRead, 70); assertEquals(decoded.file.signature, "BM"); assertEquals(decoded.dib.bpp, 24); assertEquals(decoded.pixelData, image.pixelData);