bmp/bmp
version 1.0
BMP with twelve header and depth layouts (OS/2, INFO, V3 to V5, RLE, bitfields, CMYK)
- Format
- Windows Bitmap (bmp)
- Authors
- The Fandango Fuzzer Team
- License
- Apache-2.0
- Fandango
- >=1.3
- Extensions
- bmp
- Media type
- image/bmp
- Specification
- https://learn.microsoft.com/en-us/windows/win32/gdi/bitmap-storage
- Its files should decode
- mostly
- In the registry
- specs/bmp/bmp/bmp.fan
Use it
fanbase install bmp fandango fuzz -F bmp -n 10
How it does
accepts 73%, covers 55.4%, 121/s. 1000 inputs, seed 1.
| Parser | Accepts | Version |
|---|---|---|
| ffmpeg | 60% | ffmpeg version 7.1.5-0+deb13u1 |
| imagemagick | 73% | Version: ImageMagick 7.1.1-43 Q16 x86_64 22550 |
| pillow | 61% | 12.3.0 |
| stb-bmp-cov | 60% | stb_image (BMP) 2c980bb |
The spec says its files decode mostly: as expected.
stb-bmp-cov
- lines reached
- 55.4% of 608
- real files reach
- 51.1%
- only the generated files
- 54 lines
- only the real files
- 28 lines
Cite it
@software{fanbase_bmp_bmp_1_0,
author = {{The Fandango Fuzzer Team}},
title = {Windows Bitmap (bmp/bmp), a Fandango input specification},
version = {1.0},
url = {https://github.com/fandango-fuzzer/fanbase},
note = {Fanbase registry, specs/bmp/bmp/bmp.fan, sha256 da51fd65e1bd},
}
Source
Source (131 lines)
# BMP/DIB with exact sizes and offsets: OS/2 core header at 1 bit, info header
# at 24, 8 and 4 bit, 565 bitfields, V3 alpha, V4 sRGB, V5 with a linked
# profile, RLE8, RLE4, OS/2 v2 and CMYK.
#
# TODO:
# * Mostly produced from existing BMP files, so not as much of a specification as it could be.
# * Break down headers into their constituent fields.
# * Replace constant strings with computed values.
# * Images are tiny.
<start> ::= <bmp_file>
<bmp_file> ::= <core_1bpp_bitmap> | \
<info_24bpp_bitmap> | \
<info_8bpp_bitmap> | \
<info_4bpp_bitmap> | \
<info_565_bitfields_bitmap> | \
<v3_alpha_bitmap> | \
<v4_srgb_bitmap> | \
<v5_linked_profile_bitmap> | \
<rle8_bitmap> | \
<rle4_bitmap> | \
<os2v2_24bpp_bitmap> | \
<cmyk_bitmap>
# BITMAPFILEHEADER + BITMAPCOREHEADER (the Windows 2.x / OS/2 1.x legacy form).
<core_1bpp_bitmap> ::= <fh_core_1> <bitmapcoreheader_1> <core_palette_bw> <mono_8x2_pixels>
<fh_core_1> ::= "BM\x28\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00"
<bitmapcoreheader_1> ::= "\x0c\x00\x00\x00\x08\x00\x02\x00\x01\x00\x01\x00"
<core_palette_bw> ::= <rgbtriple_black> <rgbtriple_white>
<rgbtriple_black> ::= "\x00\x00\x00"
<rgbtriple_white> ::= "\x7f\x7f\x7f"
<mono_8x2_pixels> ::= <mono_scanline> <mono_scanline>
<mono_scanline> ::= <octet> "\x00\x00\x00"
# BITMAPINFOHEADER, BI_RGB, 24 bpp. Rows are DWORD aligned and stored bottom-up.
<info_24bpp_bitmap> ::= <fh_info24> <bitmapinfoheader_24> <raw24_2x2_pixels>
<fh_info24> ::= "BM\x46\x00\x00\x00\x00\x00\x00\x00\x36\x00\x00\x00"
<bitmapinfoheader_24> ::= "\x28\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\x00\x18\x00\x00\x00\x00\x00\x10\x00\x00\x00\x13\x0b\x00\x00\x13\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
<raw24_2x2_pixels> ::= <scanline24_2> <scanline24_2>
<scanline24_2> ::= <bgr24> <bgr24> "\x00\x00"
<bgr24> ::= <octet> <octet> <octet>
# Negative height exercises the legal top-down BI_RGB orientation.
<info_topdown_32bpp_bitmap> ::= <fh_topdown32> <bitmapinfoheader_topdown32> <raw32_2x2_pixels>
<fh_topdown32> ::= "BM\x46\x00\x00\x00\x00\x00\x00\x00\x36\x00\x00\x00"
<bitmapinfoheader_topdown32> ::= "\x28\x00\x00\x00\x02\x00\x00\x00\xfe\xff\xff\xff\x01\x00\x20\x00\x00\x00\x00\x00\x10\x00\x00\x00\x13\x0b\x00\x00\x13\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
<raw32_2x2_pixels> ::= <bgra32> <bgra32> <bgra32> <bgra32>
<bgra32> ::= <octet> <octet> <octet> <octet>
# Indexed BITMAPINFOHEADER forms, including a small biClrUsed palette and the
# legacy maximum-sized 4-bpp palette. RGBQUAD's reserved byte is zero.
<info_8bpp_bitmap> ::= <fh_index8> <bitmapinfoheader_8> <palette4> <indexed8_2x2_pixels>
<fh_index8> ::= "BM\x4e\x00\x00\x00\x00\x00\x00\x00\x46\x00\x00\x00"
<bitmapinfoheader_8> ::= "\x28\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\x00\x08\x00\x00\x00\x00\x00\x08\x00\x00\x00\x13\x0b\x00\x00\x13\x0b\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00"
<palette4> ::= <rgbquad_black> <rgbquad_red> <rgbquad_green> <rgbquad_white>
<rgbquad_black> ::= "\x00\x00\x00\x00"
<rgbquad_red> ::= "\x00\x00\x7f\x00"
<rgbquad_green> ::= "\x00\x7f\x00\x00"
<rgbquad_white> ::= "\x7f\x7f\x7f\x00"
<indexed8_2x2_pixels> ::= <index8_row> <index8_row>
<index8_row> ::= <palette_index_0_3> <palette_index_0_3> "\x00\x00"
<palette_index_0_3> ::= "\x00" | "\x01" | "\x02" | "\x03"
<info_4bpp_bitmap> ::= <fh_index4> <bitmapinfoheader_4> <palette16> <indexed4_4x2_pixels>
<fh_index4> ::= "BM\x7e\x00\x00\x00\x00\x00\x00\x00\x76\x00\x00\x00"
<bitmapinfoheader_4> ::= "\x28\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x01\x00\x04\x00\x00\x00\x00\x00\x08\x00\x00\x00\x13\x0b\x00\x00\x13\x0b\x00\x00\x10\x00\x00\x00\x10\x00\x00\x00"
<palette16> ::= <rgbquad_black> <rgbquad_red> <rgbquad_green> <rgbquad_white> <rgbquad_random>{12}
<rgbquad_random> ::= <octet> <octet> <octet> "\x00"
<indexed4_4x2_pixels> ::= <index4_row> <index4_row>
<index4_row> ::= <packed_nibbles> <packed_nibbles> "\x00\x00"
<packed_nibbles> ::= <octet>
# BI_BITFIELDS with masks stored directly after the 40-byte header (RGB 5:6:5).
<info_565_bitfields_bitmap> ::= <fh_565> <bitmapinfoheader_565> <rgb565_masks> <raw16_2x2_pixels>
<fh_565> ::= "BM\x4a\x00\x00\x00\x00\x00\x00\x00\x42\x00\x00\x00"
<bitmapinfoheader_565> ::= "\x28\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\x00\x10\x00\x03\x00\x00\x00\x08\x00\x00\x00\x13\x0b\x00\x00\x13\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
<rgb565_masks> ::= "\x30\x00\x00\x00\x0c\x00\x00\x00\x03\x00\x00\x00"
<raw16_2x2_pixels> ::= <rgb565> <rgb565> <rgb565> <rgb565>
<rgb565> ::= <octet> <octet>
# BITMAPV3INFOHEADER (56 bytes), BI_ALPHABITFIELDS, explicit 8:8:8:8 masks.
<v3_alpha_bitmap> ::= <fh_v3alpha> <bitmapv3infoheader_alpha> <raw32_2x2_pixels>
<fh_v3alpha> ::= "BM\x56\x00\x00\x00\x00\x00\x00\x00\x46\x00\x00\x00"
<bitmapv3infoheader_alpha> ::= "\x38\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\x00\x20\x00\x06\x00\x00\x00\x10\x00\x00\x00\x13\x0b\x00\x00\x13\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x0c\x00\x00\x00\x03\x00\x00\x00\x00\x7f\x00\x00"
# BITMAPV4HEADER: calibrated fields are present; LCS_sRGB selects standard RGB.
<v4_srgb_bitmap> ::= <fh_v4> <bitmapv4header_srgb> <raw32_2x2_pixels> <v4_trailing_data>
<fh_v4> ::= "BM\x00\x01\x00\x00\x00\x00\x00\x00\x7a\x00\x00\x00"
<bitmapv4header_srgb> ::= "\x6c\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\x00\x20\x00\x03\x00\x00\x00\x10\x00\x00\x00\x13\x0b\x00\x00\x13\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x0c\x00\x00\x00\x03\x00\x00\x00\x00\x7f\x00\x00\x42\x47\x52\x73\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
<v4_trailing_data> ::= <octet>{118}
# BITMAPV5HEADER with a PROFILE_LINKED payload. bV5ProfileData is 140 bytes
# from the DIB start: 124 header bytes plus the 16-byte pixel array.
<v5_linked_profile_bitmap> ::= <fh_v5profile> <bitmapv5header_linked> <v5_gap> <raw32_2x2_pixels> <linked_profile> <v5_trailing_data>
<fh_v5profile> ::= "BM\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00"
<bitmapv5header_linked> ::= "\x7c\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\x00\x20\x00\x00\x00\x00\x00\x10\x00\x00\x00\x13\x0b\x00\x00\x13\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x00\x00\x00\x0c\x00\x00\x00\x03\x00\x00\x00\x00\x7f\x00\x00\x4c\x49\x4e\x4b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x02\x01\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00"
<v5_gap> ::= <octet>{118}
<linked_profile> ::= "sRGB.icm\x00"
<v5_trailing_data> ::= <octet>{231}
# Complete bounded RLE streams. Each uses encoded runs, EOL escapes and EOB;
# RLE4 additionally exercises packed high/low nibbles.
<rle8_bitmap> ::= <fh_rle> <bitmapinfoheader_rle8> <palette4> <rle8_stream>
<fh_rle> ::= "BM\x50\x00\x00\x00\x00\x00\x00\x00\x46\x00\x00\x00"
<bitmapinfoheader_rle8> ::= "\x28\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x01\x00\x08\x00\x01\x00\x00\x00\x0a\x00\x00\x00\x13\x0b\x00\x00\x13\x0b\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00"
<rle8_stream> ::= "\x04\x01\x00\x00\x04\x02\x00\x00\x00\x01"
<rle4_bitmap> ::= <fh_rle> <bitmapinfoheader_rle4> <palette4> <rle4_stream>
<bitmapinfoheader_rle4> ::= "\x28\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x01\x00\x04\x00\x02\x00\x00\x00\x0a\x00\x00\x00\x13\x0b\x00\x00\x13\x0b\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00"
<rle4_stream> ::= "\x04\x12\x00\x00\x04\x30\x00\x00\x00\x01"
# OS/2 2.x 64-byte BITMAPINFOHEADER2, including its units/recording/rendering,
# halftoning-size, color-encoding and application-identifier tail fields.
<os2v2_24bpp_bitmap> ::= <fh_os2v2> <os2_bitmapinfoheader2> <raw24_2x2_pixels>
<fh_os2v2> ::= "BM\x5e\x00\x00\x00\x00\x00\x00\x00\x4e\x00\x00\x00"
<os2_bitmapinfoheader2> ::= "\x40\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\x00\x18\x00\x00\x00\x00\x00\x10\x00\x00\x00\x13\x0b\x00\x00\x13\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
# BI_PNG permits a complete compressed image in place of DIB scanlines. This is
# a valid 1x1 RGBA PNG with fixed CRCs, bounded rather than recursively chunked.
<png_embedded_bitmap> ::= <fh_png> <bitmapinfoheader_png> <png_1x1_rgba>
<fh_png> ::= "BM\x79\x00\x00\x00\x00\x00\x00\x00\x36\x00\x00\x00"
<bitmapinfoheader_png> ::= "\x28\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x43\x00\x00\x00\x13\x0b\x00\x00\x13\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
<png_1x1_rgba> ::= "\x89PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\x0dIDAT\x78\x9c\x63\x60\x60\x60\x60\x00\x00\x00\x05\x00\x01\x0d\x0a\x2d\xb4\x00\x00\x00\x00IEND\xae\x42\x60\x82"
# Rare Windows BI_CMYK code (11), with bounded four-channel samples.
<cmyk_bitmap> ::= <fh_cmyk> <bitmapinfoheader_cmyk> <cmyk_2x2_pixels>
<fh_cmyk> ::= "BM\x46\x00\x00\x00\x00\x00\x00\x00\x36\x00\x00\x00"
<bitmapinfoheader_cmyk> ::= "\x28\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\x00\x20\x00\x0b\x00\x00\x00\x10\x00\x00\x00\x13\x0b\x00\x00\x13\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
<cmyk_2x2_pixels> ::= <cmyk32> <cmyk32> <cmyk32> <cmyk32>
<cmyk32> ::= <octet> <octet> <octet> <octet>
<octet> ::= r'[\x00-\x7f]'