xbm/xbm
version 1.0
X11 (unsigned char/char) and X10 (short) XBM dialects, with and without a cursor hotspot
- Format
- X BitMap (xbm)
- Authors
- The Fandango Fuzzer Team
- License
- Apache-2.0
- Fandango
- >=1.3
- Extensions
- xbm
- Media type
- image/x-xbitmap
- Specification
- https://www.x.org/releases/current/doc/libX11/libX11/libX11.pdf
- Its files should decode
- always
- In the registry
- specs/xbm/xbm/xbm.fan
Use it
fanbase install xbm fandango fuzz -F xbm -n 10
How it does
accepts 100%, covers 86.7%, 1.6/s. 179 inputs, seed 1.
| Parser | Accepts | Version |
|---|---|---|
| ffmpeg | 100% | ffmpeg version 7.1.5-0+deb13u1 |
| ffmpeg-xbm-cov | 100% | FFmpeg (XBM) 9.0.2 |
| imagemagick | 100% | Version: ImageMagick 7.1.1-43 Q16 x86_64 22550 |
| pillow | 59% | 12.3.0 |
The spec says its files decode always: as expected.
ffmpeg-xbm-cov
- lines reached
- 86.7% of 60
- real files reach
- 76.7%
- only the generated files
- 6 lines
- only the real files
- 0 lines
Cite it
@software{fanbase_xbm_xbm_1_0,
author = {{The Fandango Fuzzer Team}},
title = {X BitMap (xbm/xbm), a Fandango input specification},
version = {1.0},
url = {https://github.com/fandango-fuzzer/fanbase},
note = {Fanbase registry, specs/xbm/xbm/xbm.fan, sha256 b3d928577d95},
}
Source
Source (91 lines)
# XBM: X11 ("static unsigned char NAME_bits[] = {0xNN, ...}", one byte per
# 8 pixels) and the deprecated X10 dialect ("static short", one 16-bit word
# per 16 pixels), both row-padded to a byte/word boundary, with an optional
# x_hot/y_hot cursor hotspot pair.
<start> ::= <xbm>
<xbm> ::= <x11_plain> | <x11_char> | <x11_hotspot> | <x10_short> | <x10_hotspot>
# 1. X11, "unsigned char", no hotspot
<x11_plain> ::= (
"#define image_width " <w1> "\n"
"#define image_height " <h1> "\n"
"static unsigned char image_bits[] = {\n "
<bytes1>
" };\n"
)
where len(str(<bytes1>).split(", ")) == ((int(<w1>) + 7) // 8) * int(<h1>)
# 2. X11, plain "char" element type
<x11_char> ::= (
"#define picture_width " <w2> "\n"
"#define picture_height " <h2> "\n"
"static char picture_bits[] = {\n "
<bytes2>
" };\n"
)
where len(str(<bytes2>).split(", ")) == ((int(<w2>) + 7) // 8) * int(<h2>)
# 3. X11 with an x_hot / y_hot cursor hotspot
<x11_hotspot> ::= (
"#define cursor_width " <w3> "\n"
"#define cursor_height " <h3> "\n"
"#define cursor_x_hot " <xh3> "\n"
"#define cursor_y_hot " <yh3> "\n"
"static unsigned char cursor_bits[] = {\n "
<bytes3>
" };\n"
)
where len(str(<bytes3>).split(", ")) == ((int(<w3>) + 7) // 8) * int(<h3>)
# 4. X10, 16-bit "short" words, no hotspot
<x10_short> ::= (
"#define bitmap_width " <w4> "\n"
"#define bitmap_height " <h4> "\n"
"static short bitmap_bits[] = {\n "
<words4>
" };\n"
)
where len(str(<words4>).split(", ")) == ((int(<w4>) + 15) // 16) * int(<h4>)
# 5. X10, 16-bit "short" words, with hotspot
<x10_hotspot> ::= (
"#define glyph_width " <w5> "\n"
"#define glyph_height " <h5> "\n"
"#define glyph_x_hot " <xh5> "\n"
"#define glyph_y_hot " <yh5> "\n"
"static short glyph_bits[] = {\n "
<words5>
" };\n"
)
where len(str(<words5>).split(", ")) == ((int(<w5>) + 15) // 16) * int(<h5>)
# dimensions (mandatory, positive, bounded to keep files small)
<w1> ::= <dim>
<h1> ::= <dim>
<w2> ::= <dim>
<h2> ::= <dim>
<w3> ::= <dim>
<h3> ::= <dim>
<w4> ::= <dim>
<h4> ::= <dim>
<w5> ::= <dim>
<h5> ::= <dim>
<dim> ::= "8" | "16" | "24" | "32"
# hotspot coordinates: any non-negative integer within the image
<xh3> ::= <coord>
<yh3> ::= <coord>
<xh5> ::= <coord>
<yh5> ::= <coord>
<coord> ::= "0" | "1" | "3" | "7" | "8" | "15"
# array bodies
<bytes1> ::= <byte> (", " <byte>)*
<bytes2> ::= <byte> (", " <byte>)*
<bytes3> ::= <byte> (", " <byte>)*
<words4> ::= <word> (", " <word>)*
<words5> ::= <word> (", " <word>)*
<byte> ::= r'0x[0-9a-f][0-9a-f]'
<word> ::= r'0x[0-9a-f][0-9a-f][0-9a-f][0-9a-f]'