hexatess-code 0.1.0__tar.gz → 0.3.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.
Potentially problematic release.
This version of hexatess-code might be problematic. Click here for more details.
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/LICENSE +1 -1
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/PKG-INFO +30 -13
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/README.md +24 -11
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/pyproject.toml +6 -1
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess/__init__.py +4 -4
- hexatess_code-0.3.0/src/hexatess/camera.py +840 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess/cli.py +39 -4
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess/decoder.py +1 -1
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess/encoder.py +6 -4
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess/header.py +1 -1
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess_code.egg-info/PKG-INFO +30 -13
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess_code.egg-info/SOURCES.txt +2 -0
- hexatess_code-0.3.0/src/hexatess_code.egg-info/requires.txt +9 -0
- hexatess_code-0.3.0/tests/test_camera.py +75 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/tests/test_codec.py +1 -1
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/tests/test_conformance.py +1 -1
- hexatess_code-0.1.0/src/hexatess_code.egg-info/requires.txt +0 -4
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/setup.cfg +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess/galois.py +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess/geometry.py +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess/masks.py +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess/reedsolomon.py +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess/render.py +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess/resilience.py +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess_code.egg-info/dependency_links.txt +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess_code.egg-info/entry_points.txt +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/src/hexatess_code.egg-info/top_level.txt +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/tests/test_galois.py +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/tests/test_geometry.py +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/tests/test_header.py +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/tests/test_masks.py +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/tests/test_reedsolomon.py +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.0}/tests/test_render.py +0 -0
- {hexatess_code-0.1.0 → hexatess_code-0.3.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.
|
|
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.
|
|
3
|
+
Version: 0.3.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.
|
|
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
|
|
@@ -56,9 +56,18 @@ License-File: LICENSE
|
|
|
56
56
|
Requires-Dist: pillow>=9.0
|
|
57
57
|
Provides-Extra: dev
|
|
58
58
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
59
|
+
Provides-Extra: camera
|
|
60
|
+
Requires-Dist: numpy>=1.24; extra == "camera"
|
|
61
|
+
Requires-Dist: opencv-python>=4.8; extra == "camera"
|
|
62
|
+
Requires-Dist: scipy>=1.10; extra == "camera"
|
|
59
63
|
Dynamic: license-file
|
|
60
64
|
|
|
61
65
|
# Hexatess Code 🐝
|
|
66
|
+
[](https://pypi.org/project/hexatess-code/)
|
|
67
|
+
|
|
68
|
+
[](https://pypi.org/project/hexatess-code/)
|
|
69
|
+
|
|
70
|
+
[](https://github.com/lovro-abram/hexatess-code/actions/workflows/ci.yml)
|
|
62
71
|
|
|
63
72
|
**An experimental 2D barcode on a hexagonal grid** — with a hexagonal
|
|
64
73
|
bullseye finder, spiral serialization and a continuously selectable
|
|
@@ -81,7 +90,7 @@ text, stats = decode(grid) # ('Hello, Hexatess!', {...})
|
|
|
81
90
|
* **A** — a real encoded symbol: hexagonal bullseye finder (rings 0–4),
|
|
82
91
|
orientation key (ring 5: two dark cells), data region (rings 6…)
|
|
83
92
|
filled in spiral order, and a quiet zone of at least 1 module;
|
|
84
|
-
* **B** — finder close-up:
|
|
93
|
+
* **B** — finder close-up: dark centre (rule `bit = 1 − ring mod 2`),
|
|
85
94
|
alternating dark/light rings, and the key — the first two canonical
|
|
86
95
|
ring-5 cells set dark, breaking the 60-fold symmetry and marking the
|
|
87
96
|
spiral start direction;
|
|
@@ -104,27 +113,32 @@ text, stats = decode(grid) # ('Hello, Hexatess!', {...})
|
|
|
104
113
|
|
|
105
114
|
> **Status: experimental.** This is a young format: the symbol
|
|
106
115
|
> specification and reference implementation are solid and heavily
|
|
107
|
-
> tested (2,500+ tests, conformance vectors)
|
|
108
|
-
>
|
|
109
|
-
>
|
|
110
|
-
>
|
|
116
|
+
> tested (2,500+ tests, conformance vectors). A **camera decoder**
|
|
117
|
+
> (`hexatess.camera`, optional `[camera]` extra) already reads symbols
|
|
118
|
+
> from real photographs — printed labels, foil transparencies, tilted
|
|
119
|
+
> and rotated shots. See the roadmap below. Adopting a young format
|
|
120
|
+
> is a deliberate bet; the [full format specification](SPECIFICATION.md)
|
|
121
|
+
> is the insurance.
|
|
111
122
|
|
|
112
123
|
## Installation
|
|
113
124
|
|
|
114
125
|
```bash
|
|
115
126
|
pip install hexatess-code # from PyPI (once published)
|
|
127
|
+
pip install "hexatess-code[camera]" # + photo decoding (numpy, opencv, scipy)
|
|
116
128
|
# or from a source checkout:
|
|
117
129
|
pip install -e .
|
|
118
130
|
```
|
|
119
131
|
|
|
120
|
-
Requires Python ≥ 3.8
|
|
132
|
+
Requires Python ≥ 3.8; Pillow for rendering, numpy + OpenCV + SciPy
|
|
133
|
+
for the optional camera decoder.
|
|
121
134
|
|
|
122
135
|
## Command line
|
|
123
136
|
|
|
124
137
|
```bash
|
|
125
138
|
hexatess "Hello world" -o koda.png --ec 30
|
|
126
139
|
hexatess "Important URL https://example.org" -o url.png --ec 55
|
|
127
|
-
hexatess
|
|
140
|
+
hexatess --demo # demo symbol + robustness statistics
|
|
141
|
+
hexatess decode-photo photo1.jpg photo2.jpg # read symbols from photos
|
|
128
142
|
```
|
|
129
143
|
|
|
130
144
|
## API
|
|
@@ -136,6 +150,7 @@ hexatess-code --demo # demo symbol + robustness statistics
|
|
|
136
150
|
| `render(grid, path, size_px=18, ...)` | grid → PNG (pointy-top hexagons, quiet zone, supersampling) |
|
|
137
151
|
| `sample_grid_from_image(path, rmax, ...)` | ideal re-sampling of a rendered PNG (self-test helper) |
|
|
138
152
|
| `run_tests(...)` | noise/blob robustness statistics |
|
|
153
|
+
| `hexatess.camera.decode_photo(path)` | photograph → `(text, stats)`; finder detection, perspective handling, adaptive sampling (optional `[camera]` extra) |
|
|
139
154
|
|
|
140
155
|
`params` / `stats` contain `rmax` (radius in rings), `mask`, `ec`,
|
|
141
156
|
`blocks` (list of `(data_bytes, ecc_bytes)`) and `data_len`.
|
|
@@ -162,16 +177,18 @@ concentrate inside whole bytes.
|
|
|
162
177
|
The format is deliberately **specification-first**: everything needed
|
|
163
178
|
for an independent implementation is in
|
|
164
179
|
[`SPECIFICATION.md`](SPECIFICATION.md), and
|
|
165
|
-
[`test_vectors/vectors_v0.
|
|
180
|
+
[`test_vectors/vectors_v0.2.json`](test_vectors/vectors_v0.2.json)
|
|
166
181
|
contains fixed inputs/outputs (grids, headers, damaged symbols, expected
|
|
167
182
|
results) to verify conformance. If your Rust/Go/JS decoder passes the
|
|
168
183
|
vectors, it speaks Hexatess Code.
|
|
169
184
|
|
|
170
185
|
## Roadmap
|
|
171
186
|
|
|
172
|
-
1.
|
|
173
|
-
|
|
174
|
-
|
|
187
|
+
1. ~~v0.2/0.3 — camera decoding~~ **done (v0.3.0):** `hexatess.camera`
|
|
188
|
+
reads symbols from photographs — bullseye detection, homography +
|
|
189
|
+
correction-field warp handling, adaptive sampling; validated on
|
|
190
|
+
printed foil with curl and glare.
|
|
191
|
+
2. **Erasure decoding:** declare blob-occluded modules as
|
|
175
192
|
erasures → doubles correctable symbol counts.
|
|
176
193
|
3. **JavaScript/TypeScript SDK** + online playground (generate a code
|
|
177
194
|
in the browser in 10 seconds).
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
# Hexatess Code 🐝
|
|
2
|
+
[](https://pypi.org/project/hexatess-code/)
|
|
3
|
+
|
|
4
|
+
[](https://pypi.org/project/hexatess-code/)
|
|
5
|
+
|
|
6
|
+
[](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:
|
|
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;
|
|
@@ -44,27 +49,32 @@ text, stats = decode(grid) # ('Hello, Hexatess!', {...})
|
|
|
44
49
|
|
|
45
50
|
> **Status: experimental.** This is a young format: the symbol
|
|
46
51
|
> specification and reference implementation are solid and heavily
|
|
47
|
-
> tested (2,500+ tests, conformance vectors)
|
|
48
|
-
>
|
|
49
|
-
>
|
|
50
|
-
>
|
|
52
|
+
> tested (2,500+ tests, conformance vectors). A **camera decoder**
|
|
53
|
+
> (`hexatess.camera`, optional `[camera]` extra) already reads symbols
|
|
54
|
+
> from real photographs — printed labels, foil transparencies, tilted
|
|
55
|
+
> and rotated shots. See the roadmap below. Adopting a young format
|
|
56
|
+
> is a deliberate bet; the [full format specification](SPECIFICATION.md)
|
|
57
|
+
> is the insurance.
|
|
51
58
|
|
|
52
59
|
## Installation
|
|
53
60
|
|
|
54
61
|
```bash
|
|
55
62
|
pip install hexatess-code # from PyPI (once published)
|
|
63
|
+
pip install "hexatess-code[camera]" # + photo decoding (numpy, opencv, scipy)
|
|
56
64
|
# or from a source checkout:
|
|
57
65
|
pip install -e .
|
|
58
66
|
```
|
|
59
67
|
|
|
60
|
-
Requires Python ≥ 3.8
|
|
68
|
+
Requires Python ≥ 3.8; Pillow for rendering, numpy + OpenCV + SciPy
|
|
69
|
+
for the optional camera decoder.
|
|
61
70
|
|
|
62
71
|
## Command line
|
|
63
72
|
|
|
64
73
|
```bash
|
|
65
74
|
hexatess "Hello world" -o koda.png --ec 30
|
|
66
75
|
hexatess "Important URL https://example.org" -o url.png --ec 55
|
|
67
|
-
hexatess
|
|
76
|
+
hexatess --demo # demo symbol + robustness statistics
|
|
77
|
+
hexatess decode-photo photo1.jpg photo2.jpg # read symbols from photos
|
|
68
78
|
```
|
|
69
79
|
|
|
70
80
|
## API
|
|
@@ -76,6 +86,7 @@ hexatess-code --demo # demo symbol + robustness statistics
|
|
|
76
86
|
| `render(grid, path, size_px=18, ...)` | grid → PNG (pointy-top hexagons, quiet zone, supersampling) |
|
|
77
87
|
| `sample_grid_from_image(path, rmax, ...)` | ideal re-sampling of a rendered PNG (self-test helper) |
|
|
78
88
|
| `run_tests(...)` | noise/blob robustness statistics |
|
|
89
|
+
| `hexatess.camera.decode_photo(path)` | photograph → `(text, stats)`; finder detection, perspective handling, adaptive sampling (optional `[camera]` extra) |
|
|
79
90
|
|
|
80
91
|
`params` / `stats` contain `rmax` (radius in rings), `mask`, `ec`,
|
|
81
92
|
`blocks` (list of `(data_bytes, ecc_bytes)`) and `data_len`.
|
|
@@ -102,16 +113,18 @@ concentrate inside whole bytes.
|
|
|
102
113
|
The format is deliberately **specification-first**: everything needed
|
|
103
114
|
for an independent implementation is in
|
|
104
115
|
[`SPECIFICATION.md`](SPECIFICATION.md), and
|
|
105
|
-
[`test_vectors/vectors_v0.
|
|
116
|
+
[`test_vectors/vectors_v0.2.json`](test_vectors/vectors_v0.2.json)
|
|
106
117
|
contains fixed inputs/outputs (grids, headers, damaged symbols, expected
|
|
107
118
|
results) to verify conformance. If your Rust/Go/JS decoder passes the
|
|
108
119
|
vectors, it speaks Hexatess Code.
|
|
109
120
|
|
|
110
121
|
## Roadmap
|
|
111
122
|
|
|
112
|
-
1.
|
|
113
|
-
|
|
114
|
-
|
|
123
|
+
1. ~~v0.2/0.3 — camera decoding~~ **done (v0.3.0):** `hexatess.camera`
|
|
124
|
+
reads symbols from photographs — bullseye detection, homography +
|
|
125
|
+
correction-field warp handling, adaptive sampling; validated on
|
|
126
|
+
printed foil with curl and glare.
|
|
127
|
+
2. **Erasure decoding:** declare blob-occluded modules as
|
|
115
128
|
erasures → doubles correctable symbol counts.
|
|
116
129
|
3. **JavaScript/TypeScript SDK** + online playground (generate a code
|
|
117
130
|
in the browser in 10 seconds).
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "hexatess-code"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.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"
|
|
@@ -36,6 +36,11 @@ dependencies = [
|
|
|
36
36
|
dev = [
|
|
37
37
|
"pytest>=7.0",
|
|
38
38
|
]
|
|
39
|
+
camera = [
|
|
40
|
+
"numpy>=1.24",
|
|
41
|
+
"opencv-python>=4.8",
|
|
42
|
+
"scipy>=1.10",
|
|
43
|
+
]
|
|
39
44
|
|
|
40
45
|
[project.urls]
|
|
41
46
|
Homepage = "https://github.com/lovro-abram/hexatess-code"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Hexatess Code - an experimental 2D barcode on a hexagonal grid.
|
|
2
2
|
|
|
3
|
-
Reference implementation of specification v0.
|
|
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.
|
|
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.
|
|
61
|
-
SPEC_VERSION = "0.
|
|
60
|
+
__version__ = "0.3.0"
|
|
61
|
+
SPEC_VERSION = "0.2"
|
|
62
62
|
|
|
63
63
|
__all__ = [
|
|
64
64
|
# high-level API
|