diff options
| author | cirakg <cirakg@cirakg.xyz> | 2026-10-20 11:24:58 +0200 |
|---|---|---|
| committer | cirakg <cirakg@cirakg.xyz> | 2026-10-20 11:24:58 +0200 |
| commit | 1251aab9f8f9f38aa5bdefd4fed1f58236166cf8 (patch) | |
| tree | d9824a2430cff9f6659a5b14b6e437d6b1568b87 /tools/gen_pdf417_tables.py | |
| parent | d94eb32c80d2dbf00a45d7e69804f8247240a769 (diff) | |
test(codes): compare Data Matrix and PDF417 with references and decode them, also from screenshots
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'tools/gen_pdf417_tables.py')
| -rw-r--r-- | tools/gen_pdf417_tables.py | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/tools/gen_pdf417_tables.py b/tools/gen_pdf417_tables.py new file mode 100644 index 0000000..7a66677 --- /dev/null +++ b/tools/gen_pdf417_tables.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +# Author: cirakg & claude ai +# Summary: Generate the PDF417 table resources (patterns, EC factors, text table) from pdf417gen's published tables. +"""PDF417 tables for the watch (ISO/IEC 15438), taken from pdf417gen so the +2,787 bar patterns aren't typed by hand. Five JSON resources (the compiler +warns about resources over 8 KB): + +- codes0, codes1, codes2: the 17-module pattern of every codeword (0-928) + in clusters 0, 3 and 6 +- ec: the Reed-Solomon factors (mod 929) for levels 0-8 +- text: per text-compaction submode (upper, lower, mixed, punctuation), the + value of ASCII 0-126 in that submode, or -1 + +The app loads them only while it encodes a PDF417 code. + + gen_pdf417_tables.py [--out-dir resources/pdf417] +""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path + +from pdf417gen import codes, data + +SUBMODES = [data.UPPER, data.LOWER, data.MIXED, data.PUNCT] + + +HEADER = {"_author": "cirakg & claude ai"} + + +def tables() -> dict[str, object]: + """Resource name -> JSON content.""" + text = [[data.CHARACTERS_LOOKUP.get(c, {}).get(mode, -1) for c in range(127)] for mode in SUBMODES] + out: dict[str, object] = {} + for k in range(3): + out[f"codes{k}"] = { + **HEADER, + "_summary": f"PDF417 cluster {3 * k} patterns (generated; do not edit).", + "v": list(codes.CODES[k]), + } + out["ec"] = { + **HEADER, + "_summary": "PDF417 EC factors per level (generated; do not edit).", + "v": [list(f) for f in data.ERROR_CORRECTION_FACTORS], + } + out["text"] = {**HEADER, "_summary": "PDF417 text submode values (generated; do not edit).", "v": text} + return out + + +def resources_xml(names: list[str]) -> str: + rows = "\n".join(f' <jsonData id="Pdf417{name.capitalize()}" filename="{name}.json" />' for name in names) + return ( + "<!--\n Author: cirakg & claude ai\n" + " Summary: The PDF417 tables as JSON resources, loaded only while a PDF417 code is encoded (generated).\n-->\n" + f"<resources>\n{rows}\n</resources>\n" + ) + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) + parser.add_argument("--out-dir", type=Path, default=Path("resources/pdf417")) + args = parser.parse_args(argv) + args.out_dir.mkdir(parents=True, exist_ok=True) + for old in args.out_dir.glob("*.json"): + old.unlink() + content = tables() + for name, value in content.items(): + (args.out_dir / f"{name}.json").write_text(json.dumps(value, separators=(",", ":")) + "\n", encoding="utf-8") + (args.out_dir / "pdf417.xml").write_text(resources_xml(list(content)), encoding="utf-8") + print(f"wrote {len(content)} PDF417 table resources to {args.out_dir}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) |
