class

PrismatIQ::BMPParser

Inherits PrismatIQ::BinaryReader < Reference < Object

BMPParser: Parser for legacy BMP/DIB format parsing

This class handles parsing of Windows BMP/DIB (Device Independent Bitmap) format data embedded within ICO files or as standalone BMP files.

Supported Formats

  • 1bpp (monochrome) with 2-color palette
  • 4bpp (16-color) with 16-color palette
  • 8bpp (256-color) with 256-color palette
  • 16bpp with optional bitfield masks
  • 24bpp (true color, BGR order)
  • 32bpp (true color with alpha, BGRA order)

Features

  • Supports both bottom-up (standard) and top-down BMP formats
  • Handles AND mask for transparency in legacy icons
  • Bitfield compression support (BI_BITFIELDS)
  • 4-byte row alignment handling
  • Converts all formats to RGBA for consistent processing

Usage

parser = BMPParser.new(bmp_slice)
if parser.valid?
  image = parser.to_image
  width = image.width
  height = image.height
  pixels = image.pixels
end

BMP File Format Reference

A BMP/DIB image in an ICO file consists of:

  • BITMAPINFOHEADER: 40 bytes (or larger for extended headers)
  • Color Palette: 4 bytes per entry (B, G, R, Reserved) - present for <=8bpp
  • XOR Mask: Pixel data (size varies by dimensions and bit depth)
  • AND Mask: 1bpp transparency mask (height equals image height for ICO)

Constants

MAX_PIXEL_COUNT = 268435456_i64

Constructors

new(data : Slice(UInt8), width : Int32, height : Int32, config : Config = Config.default)
new(data : Slice(UInt8), config : Config = Config.default)

Class methods

from_slice?(data : Slice(UInt8), config : Config = Config.default) : BMPParser | Nil

Creates a BMPParser from raw bytes, returning nil on failure

This is a convenience factory method that catches exceptions.

parser = BMPParser.from_slice?(bytes)
if parser && parser.valid?
  # process
end

Instance methods

bit_count
colors_used
compression
height
to_image

Returns a ParsedImage struct containing width, height, and RGBA pixels

This is a convenience method that combines dimension retrieval and pixel decoding.

image = parser.to_image
puts "Size: #{image.width}x#{image.height}"
to_rgba

Returns the pixel data as RGBA bytes

Returns a Slice(UInt8) of size width * height * 4 containing RGBA pixel data in row-major order (top-to-bottom).

Raises BMPParseError if the image is not valid.

pixels = parser.to_rgba
# pixels[0..3] = first pixel R, G, B, A
valid?
width

Nested types