hexatess-code 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/LICENSE +1 -1
  2. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/PKG-INFO +9 -4
  3. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/README.md +7 -2
  4. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/pyproject.toml +1 -1
  5. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess/__init__.py +4 -4
  6. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess/cli.py +2 -2
  7. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess/decoder.py +1 -1
  8. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess/encoder.py +6 -4
  9. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess/header.py +1 -1
  10. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess_code.egg-info/PKG-INFO +9 -4
  11. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/tests/test_codec.py +1 -1
  12. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/tests/test_conformance.py +1 -1
  13. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/setup.cfg +0 -0
  14. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess/galois.py +0 -0
  15. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess/geometry.py +0 -0
  16. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess/masks.py +0 -0
  17. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess/reedsolomon.py +0 -0
  18. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess/render.py +0 -0
  19. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess/resilience.py +0 -0
  20. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess_code.egg-info/SOURCES.txt +0 -0
  21. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess_code.egg-info/dependency_links.txt +0 -0
  22. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess_code.egg-info/entry_points.txt +0 -0
  23. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess_code.egg-info/requires.txt +0 -0
  24. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/src/hexatess_code.egg-info/top_level.txt +0 -0
  25. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/tests/test_galois.py +0 -0
  26. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/tests/test_geometry.py +0 -0
  27. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/tests/test_header.py +0 -0
  28. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/tests/test_masks.py +0 -0
  29. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/tests/test_reedsolomon.py +0 -0
  30. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/tests/test_render.py +0 -0
  31. {hexatess_code-0.1.0 → hexatess_code-0.2.0}/tests/test_resilience.py +0 -0
@@ -27,4 +27,4 @@ The format specification (SPECIFICATION.md) is additionally released under
27
27
  the Creative Commons Attribution 4.0 International license (CC-BY-4.0), so
28
28
  that anyone may implement compatible encoders/decoders in any language,
29
29
  under any license, without restriction. Provide attribution as:
30
- "Hexatess Code Specification v0.1, https://github.com/<you>/hexatess-code".
30
+ "Hexatess Code Specification v0.2, https://github.com/<you>/hexatess-code".
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hexatess-code
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Hexatess Code - an experimental 2D barcode on a hexagonal grid with Reed-Solomon error correction
5
5
  Author: The Hexatess Code Authors
6
6
  License: MIT License
@@ -32,7 +32,7 @@ License: MIT License
32
32
  the Creative Commons Attribution 4.0 International license (CC-BY-4.0), so
33
33
  that anyone may implement compatible encoders/decoders in any language,
34
34
  under any license, without restriction. Provide attribution as:
35
- "Hexatess Code Specification v0.1, https://github.com/<you>/hexatess-code".
35
+ "Hexatess Code Specification v0.2, https://github.com/<you>/hexatess-code".
36
36
 
37
37
  Project-URL: Homepage, https://github.com/lovro-abram/hexatess-code
38
38
  Project-URL: Specification, https://github.com/lovro-abram/hexatess-code/blob/main/SPECIFICATION.md
@@ -59,6 +59,11 @@ Requires-Dist: pytest>=7.0; extra == "dev"
59
59
  Dynamic: license-file
60
60
 
61
61
  # Hexatess Code 🐝
62
+ [![PyPI](https://img.shields.io/pypi/v/hexatess-code)](https://pypi.org/project/hexatess-code/)
63
+
64
+ [![Python](https://img.shields.io/pypi/pyversions/hexatess-code)](https://pypi.org/project/hexatess-code/)
65
+
66
+ [![CI](https://github.com/lovro-abram/hexatess-code/actions/workflows/ci.yml/badge.svg)](https://github.com/lovro-abram/hexatess-code/actions/workflows/ci.yml)
62
67
 
63
68
  **An experimental 2D barcode on a hexagonal grid** — with a hexagonal
64
69
  bullseye finder, spiral serialization and a continuously selectable
@@ -81,7 +86,7 @@ text, stats = decode(grid) # ('Hello, Hexatess!', {...})
81
86
  * **A** — a real encoded symbol: hexagonal bullseye finder (rings 0–4),
82
87
  orientation key (ring 5: two dark cells), data region (rings 6…)
83
88
  filled in spiral order, and a quiet zone of at least 1 module;
84
- * **B** — finder close-up: light centre (v0.1 rule `bit = ring mod 2`),
89
+ * **B** — finder close-up: dark centre (rule `bit = 1 − ring mod 2`),
85
90
  alternating dark/light rings, and the key — the first two canonical
86
91
  ring-5 cells set dark, breaking the 60-fold symmetry and marking the
87
92
  spiral start direction;
@@ -162,7 +167,7 @@ concentrate inside whole bytes.
162
167
  The format is deliberately **specification-first**: everything needed
163
168
  for an independent implementation is in
164
169
  [`SPECIFICATION.md`](SPECIFICATION.md), and
165
- [`test_vectors/vectors_v0.1.json`](test_vectors/vectors_v0.1.json)
170
+ [`test_vectors/vectors_v0.2.json`](test_vectors/vectors_v0.2.json)
166
171
  contains fixed inputs/outputs (grids, headers, damaged symbols, expected
167
172
  results) to verify conformance. If your Rust/Go/JS decoder passes the
168
173
  vectors, it speaks Hexatess Code.
@@ -1,4 +1,9 @@
1
1
  # Hexatess Code 🐝
2
+ [![PyPI](https://img.shields.io/pypi/v/hexatess-code)](https://pypi.org/project/hexatess-code/)
3
+
4
+ [![Python](https://img.shields.io/pypi/pyversions/hexatess-code)](https://pypi.org/project/hexatess-code/)
5
+
6
+ [![CI](https://github.com/lovro-abram/hexatess-code/actions/workflows/ci.yml/badge.svg)](https://github.com/lovro-abram/hexatess-code/actions/workflows/ci.yml)
2
7
 
3
8
  **An experimental 2D barcode on a hexagonal grid** — with a hexagonal
4
9
  bullseye finder, spiral serialization and a continuously selectable
@@ -21,7 +26,7 @@ text, stats = decode(grid) # ('Hello, Hexatess!', {...})
21
26
  * **A** — a real encoded symbol: hexagonal bullseye finder (rings 0–4),
22
27
  orientation key (ring 5: two dark cells), data region (rings 6…)
23
28
  filled in spiral order, and a quiet zone of at least 1 module;
24
- * **B** — finder close-up: light centre (v0.1 rule `bit = ring mod 2`),
29
+ * **B** — finder close-up: dark centre (rule `bit = 1 − ring mod 2`),
25
30
  alternating dark/light rings, and the key — the first two canonical
26
31
  ring-5 cells set dark, breaking the 60-fold symmetry and marking the
27
32
  spiral start direction;
@@ -102,7 +107,7 @@ concentrate inside whole bytes.
102
107
  The format is deliberately **specification-first**: everything needed
103
108
  for an independent implementation is in
104
109
  [`SPECIFICATION.md`](SPECIFICATION.md), and
105
- [`test_vectors/vectors_v0.1.json`](test_vectors/vectors_v0.1.json)
110
+ [`test_vectors/vectors_v0.2.json`](test_vectors/vectors_v0.2.json)
106
111
  contains fixed inputs/outputs (grids, headers, damaged symbols, expected
107
112
  results) to verify conformance. If your Rust/Go/JS decoder passes the
108
113
  vectors, it speaks Hexatess Code.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hexatess-code"
7
- version = "0.1.0"
7
+ version = "0.2.0"
8
8
  description = "Hexatess Code - an experimental 2D barcode on a hexagonal grid with Reed-Solomon error correction"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -1,6 +1,6 @@
1
1
  """Hexatess Code - an experimental 2D barcode on a hexagonal grid.
2
2
 
3
- Reference implementation of specification v0.1. The symbol is a
3
+ Reference implementation of specification v0.2. The symbol is a
4
4
  hexagonal lattice with a hexagonal bullseye finder, an
5
5
  orientation key ring, spiral serialization from the centre outwards,
6
6
  a Reed-Solomon protected header and a continuously selectable
@@ -18,7 +18,7 @@ Quick start
18
18
  'Hello, Hexatess!'
19
19
 
20
20
  See SPECIFICATION.md in the repository for the full format
21
- specification, and test_vectors/vectors_v0.1.json for conformance
21
+ specification, and test_vectors/vectors_v0.2.json for conformance
22
22
  data usable by independent implementations.
23
23
  """
24
24
 
@@ -57,8 +57,8 @@ from .reedsolomon import rs_correct_msg, rs_encode_msg
57
57
  from .render import render, sample_grid_from_image
58
58
  from .resilience import add_blob_damage, add_random_noise, run_tests
59
59
 
60
- __version__ = "0.1.0"
61
- SPEC_VERSION = "0.1"
60
+ __version__ = "0.2.0"
61
+ SPEC_VERSION = "0.2"
62
62
 
63
63
  __all__ = [
64
64
  # high-level API
@@ -25,7 +25,7 @@ def main(argv=None):
25
25
  ap = argparse.ArgumentParser(
26
26
  prog="hexatess",
27
27
  description="Hexatess Code - hexagonal-grid 2D barcode "
28
- "(reference implementation, spec v0.1)")
28
+ "(reference implementation, spec v0.2)")
29
29
  ap.add_argument("text", nargs="?", help="text to encode (UTF-8)")
30
30
  ap.add_argument("-o", "--output", default="hexatess.png",
31
31
  help="output PNG path (default: %(default)s)")
@@ -46,7 +46,7 @@ def main(argv=None):
46
46
  run_tests()
47
47
 
48
48
  if args.demo or args.text:
49
- text = args.text or "Hexatess Code v0.1 - " * 6
49
+ text = args.text or "Hexatess Code v0.2 - " * 6
50
50
  grid, params = encode(text, ec_pct=args.ec, mask_id="auto"
51
51
  if args.mask is None else args.mask)
52
52
  render(grid, args.output, size_px=args.size)
@@ -28,7 +28,7 @@ def decode(grid, params=None):
28
28
  grid : dict
29
29
  Mapping ``{(q, r): 0|1}``.
30
30
  params : dict, optional
31
- Ignored; kept for API symmetry with v0.1 of the prototype.
31
+ Ignored; kept for API symmetry with the original prototype.
32
32
 
33
33
  Returns
34
34
  -------
@@ -2,10 +2,11 @@
2
2
 
3
3
  Turns UTF-8 text into a hexagonal module grid ``{(q, r): 0|1}``.
4
4
 
5
- Layout summary (specification v0.1):
5
+ Layout summary (specification v0.2):
6
6
 
7
7
  * rings 0..4 -- hexagonal bullseye finder, ring ``k`` filled with
8
- ``k mod 2`` (bit 1 = dark module; the centre module is LIGHT in v0.1);
8
+ ``1 - (k mod 2)`` (bit 1 = dark module; the centre module is DARK
9
+ since spec v0.2);
9
10
  * ring 5 -- orientation key: all modules light except the first two
10
11
  cells of ``hex_ring(5)`` (``(-5, 5)`` and ``(-4, 5)``) which are dark;
11
12
  * rings 6..rmax -- payload bits in spiral order: header (80 bits,
@@ -62,7 +63,8 @@ def encode(text: str, ec_pct: int = 30, mask_id="auto", min_rings=None):
62
63
  data = text.encode("utf-8")
63
64
  if len(data) > MAX_DATA_BYTES:
64
65
  raise ValueError(
65
- "v0.1 supports up to %d bytes of data" % MAX_DATA_BYTES)
66
+ "the radius limit supports up to %d bytes of data"
67
+ % MAX_DATA_BYTES)
66
68
  blocks = plan_blocks(len(data), ec_pct)
67
69
  ecc_total = sum(e for _, e in blocks)
68
70
  need_bits = MODE_BITS + (len(data) + ecc_total) * 8
@@ -110,7 +112,7 @@ def encode(text: str, ec_pct: int = 30, mask_id="auto", min_rings=None):
110
112
  grid = {}
111
113
  for k in range(BULLSEYE_RINGS + 1):
112
114
  for c in hex_ring(k):
113
- grid[c] = k % 2 # centre LIGHT in v0.1, rings alternate
115
+ grid[c] = 1 - (k % 2) # centre DARK (v0.2), rings alternate
114
116
  for c in hex_ring(KEY_RING):
115
117
  grid[c] = 0
116
118
  key = hex_ring(KEY_RING)
@@ -7,7 +7,7 @@ import math
7
7
  from .reedsolomon import rs_encode_msg, rs_correct_msg
8
8
 
9
9
  # ----------------------------------------------------------------------
10
- # Symbol constants (fixed in specification v0.1)
10
+ # Symbol constants (fixed in specification v0.2)
11
11
  # ----------------------------------------------------------------------
12
12
 
13
13
  BULLSEYE_RINGS = 4 # rings 0..4 form the hexagonal bullseye finder
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hexatess-code
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Hexatess Code - an experimental 2D barcode on a hexagonal grid with Reed-Solomon error correction
5
5
  Author: The Hexatess Code Authors
6
6
  License: MIT License
@@ -32,7 +32,7 @@ License: MIT License
32
32
  the Creative Commons Attribution 4.0 International license (CC-BY-4.0), so
33
33
  that anyone may implement compatible encoders/decoders in any language,
34
34
  under any license, without restriction. Provide attribution as:
35
- "Hexatess Code Specification v0.1, https://github.com/<you>/hexatess-code".
35
+ "Hexatess Code Specification v0.2, https://github.com/<you>/hexatess-code".
36
36
 
37
37
  Project-URL: Homepage, https://github.com/lovro-abram/hexatess-code
38
38
  Project-URL: Specification, https://github.com/lovro-abram/hexatess-code/blob/main/SPECIFICATION.md
@@ -59,6 +59,11 @@ Requires-Dist: pytest>=7.0; extra == "dev"
59
59
  Dynamic: license-file
60
60
 
61
61
  # Hexatess Code 🐝
62
+ [![PyPI](https://img.shields.io/pypi/v/hexatess-code)](https://pypi.org/project/hexatess-code/)
63
+
64
+ [![Python](https://img.shields.io/pypi/pyversions/hexatess-code)](https://pypi.org/project/hexatess-code/)
65
+
66
+ [![CI](https://github.com/lovro-abram/hexatess-code/actions/workflows/ci.yml/badge.svg)](https://github.com/lovro-abram/hexatess-code/actions/workflows/ci.yml)
62
67
 
63
68
  **An experimental 2D barcode on a hexagonal grid** — with a hexagonal
64
69
  bullseye finder, spiral serialization and a continuously selectable
@@ -81,7 +86,7 @@ text, stats = decode(grid) # ('Hello, Hexatess!', {...})
81
86
  * **A** — a real encoded symbol: hexagonal bullseye finder (rings 0–4),
82
87
  orientation key (ring 5: two dark cells), data region (rings 6…)
83
88
  filled in spiral order, and a quiet zone of at least 1 module;
84
- * **B** — finder close-up: light centre (v0.1 rule `bit = ring mod 2`),
89
+ * **B** — finder close-up: dark centre (rule `bit = 1 − ring mod 2`),
85
90
  alternating dark/light rings, and the key — the first two canonical
86
91
  ring-5 cells set dark, breaking the 60-fold symmetry and marking the
87
92
  spiral start direction;
@@ -162,7 +167,7 @@ concentrate inside whole bytes.
162
167
  The format is deliberately **specification-first**: everything needed
163
168
  for an independent implementation is in
164
169
  [`SPECIFICATION.md`](SPECIFICATION.md), and
165
- [`test_vectors/vectors_v0.1.json`](test_vectors/vectors_v0.1.json)
170
+ [`test_vectors/vectors_v0.2.json`](test_vectors/vectors_v0.2.json)
166
171
  contains fixed inputs/outputs (grids, headers, damaged symbols, expected
167
172
  results) to verify conformance. If your Rust/Go/JS decoder passes the
168
173
  vectors, it speaks Hexatess Code.
@@ -67,7 +67,7 @@ def test_bullseye_pattern():
67
67
  grid, params = encode("bullseye", ec_pct=30)
68
68
  for k in range(BULLSEYE_RINGS + 1):
69
69
  for c in hex_ring(k):
70
- assert grid[c] == k % 2
70
+ assert grid[c] == 1 - (k % 2) # centre DARK (spec v0.2)
71
71
  key = hex_ring(KEY_RING)
72
72
  for c in key[2:]:
73
73
  assert grid[c] == 0
@@ -16,7 +16,7 @@ from test_vectors.generate_vectors import grid_from_hex
16
16
 
17
17
  HERE = os.path.dirname(os.path.abspath(__file__))
18
18
  ROOT = os.path.dirname(HERE)
19
- VECTOR_FILE = os.path.join(ROOT, "test_vectors", "vectors_v0.1.json")
19
+ VECTOR_FILE = os.path.join(ROOT, "test_vectors", "vectors_v0.2.json")
20
20
 
21
21
  with open(VECTOR_FILE, "r", encoding="utf-8") as fh:
22
22
  VECTORS = json.load(fh)
File without changes