aboutsummaryrefslogtreecommitdiff
path: root/tools/gen_code_vectors.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gen_code_vectors.py')
-rw-r--r--tools/gen_code_vectors.py45
1 files changed, 45 insertions, 0 deletions
diff --git a/tools/gen_code_vectors.py b/tools/gen_code_vectors.py
index 5ce2611..1472bb7 100644
--- a/tools/gen_code_vectors.py
+++ b/tools/gen_code_vectors.py
@@ -23,6 +23,7 @@ from typing import Any, cast
import barcode_ref as ref
import ppf.datamatrix.codec_ascii # noqa: F401 (registers the datamatrix.ascii codec)
import segno
+from aztec_code_generator import AztecCode
from pdf417gen import encode as pdf417_encode
from ppf.datamatrix import DataMatrix
@@ -287,6 +288,42 @@ def pdf417_reference(payload: str, columns: int, level: int) -> tuple[int, int,
return len(rows), len(rows[0]), packed.hex()
+AZTEC_EC = [10, 23, 36, 50]
+
+
+def aztec_cases(rng: random.Random, count: int) -> list[tuple[str, int]]:
+ """(payload, EC option 0-3) with one character class each (capitals, small
+ letters or digits, plus spaces): for these the reference's optimal mode
+ sequence and the watch's encodation give the same bits, so the symbols
+ must match exactly. Sizes reach full range with reference grids."""
+ fixed = [
+ ("A", 1),
+ ("HELLO WORLD", 1),
+ ("hello world", 0),
+ ("0042 7731", 2),
+ ("FAKE TICKET " * 10, 1),
+ ("abc def " * 40, 3),
+ ("1234567890" * 60, 1),
+ ("Z" * 900, 0),
+ ]
+ out = list(fixed)
+ for _ in range(count):
+ alphabet = rng.choice([string.ascii_uppercase + " ", string.ascii_lowercase + " ", string.digits + " "])
+ n = rng.randint(1, 200)
+ payload = "".join(rng.choice(alphabet) for _ in range(n)).strip() or "X"
+ out.append((payload, rng.randrange(4)))
+ return out
+
+
+def aztec_reference(payload: str, option: int) -> tuple[int, str]:
+ """aztec_code_generator's (size, matrix as hex of row-major bits)."""
+ code = AztecCode(payload, ec_percent=AZTEC_EC[option])
+ bits = "".join(str(b) for row in code.matrix for b in row)
+ bits += "0" * (-len(bits) % 8)
+ packed = bytes(int(bits[i : i + 8], 2) for i in range(0, len(bits), 8))
+ return code.size, packed.hex()
+
+
def mc_string(text: str) -> str:
"""A Monkey C string literal body for text (quotes, backslashes, controls escaped)."""
out = []
@@ -342,6 +379,11 @@ def render(rows: list[tuple[int, str, int, str]], seed: int) -> str:
n_rows, width, hexbits = reference
pdf_lines.append(f' ["{mc_string(payload)}", {columns}, {level}, {n_rows}, {width}, "{hexbits}"]')
pdf_body = ",\n".join(pdf_lines)
+ aztec_lines = []
+ for payload, option in aztec_cases(random.Random(seed + 4), 16):
+ size, hexbits = aztec_reference(payload, option)
+ aztec_lines.append(f' ["{payload}", {option}, {size}, "{hexbits}"]')
+ aztec_body = ",\n".join(aztec_lines)
return (
"// Author: cirakg & claude ai\n"
"// Summary: zxing-cpp reference module rows for the linear barcode encoders (generated; do not edit).\n"
@@ -358,6 +400,9 @@ def render(rows: list[tuple[int, str, int, str]], seed: int) -> str:
+ "\n ];\n\n // [payload, columns, level, pdf417gen rows, width, one module row per PDF417 row as hex]\n"
+ " const PDF417 = [\n"
+ pdf_body
+ + "\n ];\n\n // [payload, EC option, aztec_code_generator size, its matrix as hex of row-major bits]\n"
+ + " const AZTEC = [\n"
+ + aztec_body
+ "\n ];\n}\n"
)