4"""Emit a minimal baseline JPEG to seed the libFuzzer corpus.
6This generator only needs to satisfy the parser in libs/ra8_hal/src/
7ra8_jpeg_sw.c well enough for the fuzzer to start from real coverage:
8valid SOI, valid SOF0 with parseable WxH, and either valid entropy
9bytes or an EOI marker right after SOS. The generator does NOT have
10to produce a visually decodable image.
13 python3 scripts/gen/gen_jpeg_fixture.py --width 8 --height 8 -o seed.jpg
19from pathlib
import Path
26def build_minimal_jpeg(width: int, height: int) -> bytes:
27 """Build a minimal baseline JPEG with the requested SOF0 dimensions.
29 The DCT coefficients in the entropy segment are not meaningful. This
30 is a parser-coverage seed only.
32 if not (JPEG_DIM_MIN <= width <= JPEG_DIM_MAX)
or not (JPEG_DIM_MIN <= height <= JPEG_DIM_MAX):
33 msg =
"width/height must be in 1..65535"
42 app0 = b
"JFIF\x00" + b
"\x01\x01" + b
"\x00" + b
"\x00\x01\x00\x01" + b
"\x00\x00"
43 out += b
"\xff\xe0" + struct.pack(
">H", 2 + len(app0)) + app0
46 dqt = b
"\x00" + (b
"\x01" * 64)
47 out += b
"\xff\xdb" + struct.pack(
">H", 2 + len(dqt)) + dqt
51 b
"\x08" + struct.pack(
">H", height) + struct.pack(
">H", width) + b
"\x01" + b
"\x01\x11\x00"
53 out += b
"\xff\xc0" + struct.pack(
">H", 2 + len(sof0)) + sof0
56 dht_dc = b
"\x00" + bytes([0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]) + bytes(range(12))
57 out += b
"\xff\xc4" + struct.pack(
">H", 2 + len(dht_dc)) + dht_dc
61 b
"\x10" + bytes([0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7D]) + bytes(range(0xA2))
63 out += b
"\xff\xc4" + struct.pack(
">H", 2 + len(dht_ac)) + dht_ac
66 sos = b
"\x01" + b
"\x01\x00" + b
"\x00\x3f\x00"
67 out += b
"\xff\xda" + struct.pack(
">H", 2 + len(sos)) + sos
72 out += bytes([0x00] * 16)
81 """Emit one baseline JPEG of the requested size to stdout or a file.
83 Defaults to stdout (``-``) so the fixture can be piped straight into a
84 corpus directory without a temporary file.
86 parser = argparse.ArgumentParser(
87 description=
"Emit a minimal baseline JPEG seed for the libFuzzer corpus."
89 parser.add_argument(
"--width", type=int, default=8)
90 parser.add_argument(
"--height", type=int, default=8)
91 parser.add_argument(
"-o",
"--output", default=
"-", help=
"Output file (default: stdout).")
92 args = parser.parse_args()
94 blob = build_minimal_jpeg(args.width, args.height)
95 if args.output ==
"-":
96 sys.stdout.buffer.write(blob)
98 with Path(args.output).open(
"wb")
as fh:
103if __name__ ==
"__main__":
void main(void)
The application entry point Reset_Handler hands control to.