@sythos/js_barcode_universal 1.2.5 → 1.4.1

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 (124) hide show
  1. package/AI_USAGE.md +33 -0
  2. package/LICENSE +11 -2
  3. package/NOTICE.md +10 -4
  4. package/README.md +601 -465
  5. package/bundle/sythos-barcode.esm.js +4669 -74
  6. package/bundle/sythos-barcode.js +4575 -72
  7. package/examples/create.html +1010 -730
  8. package/examples/read.html +1 -0
  9. package/licenses/README.md +40 -58
  10. package/licenses/aztec-code.license +15 -13
  11. package/licenses/aztec-rune.license +76 -0
  12. package/licenses/codabar.license +18 -15
  13. package/licenses/code-11.license +11 -9
  14. package/licenses/code-128.license +10 -8
  15. package/licenses/code-39.license +10 -8
  16. package/licenses/code-93.license +16 -14
  17. package/licenses/compact-pdf417.license +76 -0
  18. package/licenses/data-matrix.license +15 -13
  19. package/licenses/ean-13.license +10 -8
  20. package/licenses/ean-2.license +74 -0
  21. package/licenses/ean-5.license +74 -0
  22. package/licenses/ean-8.license +10 -8
  23. package/licenses/frameqr.license +84 -0
  24. package/licenses/gs1-128.license +10 -8
  25. package/licenses/gs1-databar.license +81 -0
  26. package/licenses/isbn.license +10 -8
  27. package/licenses/itf-14.license +10 -8
  28. package/licenses/itf.license +9 -7
  29. package/licenses/micro-qr.license +79 -0
  30. package/licenses/micropdf417.license +52 -67
  31. package/licenses/msi-plessey.license +13 -11
  32. package/licenses/pdf417.license +78 -37
  33. package/licenses/pharmacode.license +14 -12
  34. package/licenses/qr-code.license +9 -7
  35. package/licenses/rmqr.license +79 -0
  36. package/licenses/upc-a.license +12 -10
  37. package/licenses/upc-e.license +10 -8
  38. package/package.json +109 -88
  39. package/src/aztec/decoder.js +1 -0
  40. package/src/aztec/detector.js +1 -0
  41. package/src/aztec/encoder.js +1 -0
  42. package/src/aztec/high-level.js +1 -0
  43. package/src/aztec/index.js +1 -0
  44. package/src/aztec/tables.js +1 -0
  45. package/src/aztecrune/decoder.js +156 -0
  46. package/src/aztecrune/detector.js +167 -0
  47. package/src/aztecrune/encoder.js +122 -0
  48. package/src/aztecrune/index.js +50 -0
  49. package/src/aztecrune/tables.js +138 -0
  50. package/src/compactpdf417/decoder.js +129 -0
  51. package/src/compactpdf417/detector.js +140 -0
  52. package/src/compactpdf417/encoder.js +141 -0
  53. package/src/compactpdf417/index.js +22 -0
  54. package/src/compactpdf417/tables.js +174 -0
  55. package/src/core/bit-buffer.js +1 -0
  56. package/src/core/bit-matrix.js +1 -0
  57. package/src/core/errors.js +1 -0
  58. package/src/core/galois-field.js +1 -0
  59. package/src/core/index.js +1 -0
  60. package/src/core/reed-solomon.js +1 -0
  61. package/src/databar/codec.js +182 -0
  62. package/src/databar/decoder.js +115 -0
  63. package/src/databar/encoder.js +97 -0
  64. package/src/databar/gs1.js +178 -0
  65. package/src/databar/index.js +69 -0
  66. package/src/databar/patterns.js +144 -0
  67. package/src/databar/tables.js +125 -0
  68. package/src/datamatrix/decoder.js +263 -262
  69. package/src/datamatrix/detector.js +226 -225
  70. package/src/datamatrix/encoder.js +192 -191
  71. package/src/datamatrix/index.js +43 -42
  72. package/src/datamatrix/tables.js +124 -123
  73. package/src/frameqr/decoder.js +240 -0
  74. package/src/frameqr/detector.js +193 -0
  75. package/src/frameqr/encoder.js +157 -0
  76. package/src/frameqr/index.js +43 -0
  77. package/src/frameqr/tables.js +271 -0
  78. package/src/image/binarizer.js +1 -0
  79. package/src/image/grid-sampler.js +1 -0
  80. package/src/image/index.js +1 -0
  81. package/src/image/luminance.js +1 -0
  82. package/src/image/perspective.js +1 -0
  83. package/src/index.js +155 -2
  84. package/src/micropdf417/compaction.js +1 -0
  85. package/src/micropdf417/decoder.js +1 -0
  86. package/src/micropdf417/detector.js +1 -0
  87. package/src/micropdf417/encoder.js +1 -0
  88. package/src/micropdf417/error-correction.js +1 -0
  89. package/src/micropdf417/index.js +1 -0
  90. package/src/micropdf417/tables.js +1 -0
  91. package/src/microqr/decoder.js +246 -0
  92. package/src/microqr/detector.js +356 -0
  93. package/src/microqr/encoder.js +270 -0
  94. package/src/microqr/index.js +37 -0
  95. package/src/microqr/tables.js +317 -0
  96. package/src/oned/addons.js +421 -0
  97. package/src/oned/index.js +77 -59
  98. package/src/oned/patterns.js +1 -0
  99. package/src/oned/reader.js +1 -0
  100. package/src/oned/writers.js +1 -0
  101. package/src/pdf417/compaction.js +1 -0
  102. package/src/pdf417/decoder.js +1 -0
  103. package/src/pdf417/detector.js +1 -0
  104. package/src/pdf417/encoder.js +1 -0
  105. package/src/pdf417/error-correction.js +1 -0
  106. package/src/pdf417/index.js +5 -0
  107. package/src/pdf417/tables.js +1 -0
  108. package/src/qr/decoder.js +1 -0
  109. package/src/qr/detector.js +1 -0
  110. package/src/qr/encoder.js +1 -0
  111. package/src/qr/index.js +1 -0
  112. package/src/qr/tables.js +1 -0
  113. package/src/render/image-data.js +1 -0
  114. package/src/render/index.js +1 -0
  115. package/src/render/options.js +1 -0
  116. package/src/render/png.js +1 -0
  117. package/src/render/svg.js +1 -0
  118. package/src/render/webgl.js +1 -0
  119. package/src/render/webgpu.js +1 -0
  120. package/src/rmqr/decoder.js +102 -0
  121. package/src/rmqr/detector.js +91 -0
  122. package/src/rmqr/encoder.js +173 -0
  123. package/src/rmqr/index.js +38 -0
  124. package/src/rmqr/tables.js +155 -0
@@ -4,7 +4,7 @@ UPC-A — format provenance and usability
4
4
  This file records where the UPC-A symbology comes from, what governs
5
5
  it, and the basis on which this project implements and redistributes it.
6
6
 
7
- It is an ENGINEERING INVENTORY, NOT LEGAL ADVICE. Items carrying a review label
7
+ It is an ENGINEERING INVENTORY, NOT LEGAL ADVICE. Items marked [TO VERIFY]
8
8
  have not been independently confirmed by the author.
9
9
 
10
10
 
@@ -13,8 +13,8 @@ ORIGIN
13
13
 
14
14
  The Universal Product Code, adopted in the United States in 1973 and first
15
15
  scanned in retail in 1974. The symbol encoding is commonly credited to
16
- work at IBM, but the corporate and personal credit is [LEGAL REVIEW] and no
17
- individual is named here. Administered today by GS1.
16
+ work at IBM, but the corporate and personal credit is [LEGAL REVIEW] and
17
+ no individual is named here. Administered today by GS1.
18
18
 
19
19
 
20
20
  SPECIFICATION
@@ -22,7 +22,7 @@ SPECIFICATION
22
22
 
23
23
  ISO/IEC 15420 — EAN/UPC bar code symbology specification.
24
24
  GS1 General Specifications, GS1 AISBL — freely published; redistribution
25
- terms are GS1's own [LICENSE TERMS REVIEW REQUIRED]
25
+ terms are GS1's own [LEGAL REVIEW]
26
26
 
27
27
  Specification TEXT is copyrighted by its publisher. The SYMBOLOGY it
28
28
  describes is not — an encoding scheme is a system, not a work of
@@ -34,7 +34,7 @@ PATENT STATUS
34
34
  --------------------------------------------------------------------------
35
35
 
36
36
  The originating patents date from the early 1970s and are understood to
37
- have expired long ago. [PATENT FAMILY REVIEW REQUIRED]
37
+ have expired long ago. [LEGAL REVIEW]
38
38
 
39
39
 
40
40
  TRADEMARK
@@ -51,8 +51,10 @@ IMPLEMENTATION BASIS IN THIS PROJECT
51
51
 
52
52
  UPC-A is implemented here from published descriptions of the format,
53
53
  which are systems and facts rather than works of authorship. No source
54
- code and no constant table from any other barcode implementation was used,
55
- consulted or copied, under any licence.
54
+ code or constant table from any other barcode implementation is copied or
55
+ shipped. Public technical material and independent implementations may be
56
+ consulted for engineering review or black-box verification; provenance is
57
+ recorded in NOTICE.md.
56
58
 
57
59
 
58
60
  CONCLUSION
@@ -65,8 +67,8 @@ is distributed under the MIT License with no additional restriction.
65
67
  References relied upon:
66
68
  - ISO/IEC 15420, ISO/IEC
67
69
  - GS1 General Specifications, GS1 AISBL — freely published;
68
- redistribution terms are GS1's own [LICENSE TERMS REVIEW REQUIRED]
70
+ redistribution terms are GS1's own [LEGAL REVIEW]
69
71
 
70
- This is an engineering assessment, not legal advice. Open review labels
71
- Open review labels identify claims that have not been independently confirmed by the author. If your
72
+ This is an engineering assessment, not legal advice. Items marked
73
+ [TO VERIFY] have not been independently confirmed by the author. If your
72
74
  use is commercially sensitive, obtain your own legal review.
@@ -4,7 +4,7 @@ UPC-E — format provenance and usability
4
4
  This file records where the UPC-E symbology comes from, what governs
5
5
  it, and the basis on which this project implements and redistributes it.
6
6
 
7
- It is an ENGINEERING INVENTORY, NOT LEGAL ADVICE. Items carrying a review label
7
+ It is an ENGINEERING INVENTORY, NOT LEGAL ADVICE. Items marked [TO VERIFY]
8
8
  have not been independently confirmed by the author.
9
9
 
10
10
 
@@ -20,7 +20,7 @@ SPECIFICATION
20
20
 
21
21
  ISO/IEC 15420 — EAN/UPC bar code symbology specification.
22
22
  GS1 General Specifications, GS1 AISBL — freely published; redistribution
23
- terms are GS1's own [LICENSE TERMS REVIEW REQUIRED]
23
+ terms are GS1's own [LEGAL REVIEW]
24
24
 
25
25
  Specification TEXT is copyrighted by its publisher. The SYMBOLOGY it
26
26
  describes is not — an encoding scheme is a system, not a work of
@@ -31,7 +31,7 @@ redistribute or excerpt any specification document.
31
31
  PATENT STATUS
32
32
  --------------------------------------------------------------------------
33
33
 
34
- Shares the patent history of UPC-A; understood expired. [PATENT FAMILY REVIEW REQUIRED]
34
+ Shares the patent history of UPC-A; understood expired. [LEGAL REVIEW]
35
35
 
36
36
 
37
37
  TRADEMARK
@@ -48,8 +48,10 @@ IMPLEMENTATION BASIS IN THIS PROJECT
48
48
 
49
49
  UPC-E is implemented here from published descriptions of the format,
50
50
  which are systems and facts rather than works of authorship. No source
51
- code and no constant table from any other barcode implementation was used,
52
- consulted or copied, under any licence.
51
+ code or constant table from any other barcode implementation is copied or
52
+ shipped. Public technical material and independent implementations may be
53
+ consulted for engineering review or black-box verification; provenance is
54
+ recorded in NOTICE.md.
53
55
 
54
56
 
55
57
  CONCLUSION
@@ -62,8 +64,8 @@ is distributed under the MIT License with no additional restriction.
62
64
  References relied upon:
63
65
  - ISO/IEC 15420, ISO/IEC
64
66
  - GS1 General Specifications, GS1 AISBL — freely published;
65
- redistribution terms are GS1's own [LICENSE TERMS REVIEW REQUIRED]
67
+ redistribution terms are GS1's own [LEGAL REVIEW]
66
68
 
67
- This is an engineering assessment, not legal advice. Open review labels
68
- Open review labels identify claims that have not been independently confirmed by the author. If your
69
+ This is an engineering assessment, not legal advice. Items marked
70
+ [TO VERIFY] have not been independently confirmed by the author. If your
69
71
  use is commercially sensitive, obtain your own legal review.
package/package.json CHANGED
@@ -1,102 +1,123 @@
1
- {
2
- "name": "@sythos/js_barcode_universal",
3
- "version": "1.2.5",
4
- "description": "Read and write barcodes in JavaScript with zero runtime dependencies. Aztec Code, Data Matrix ECC 200, MicroPDF417, PDF417, QR Code, EAN/UPC, ISBN, Code 128, Code 39, Code 93, ITF, Codabar, MSI, Code 11 and Pharmacode.",
5
- "author": "Sythos",
6
- "license": "MIT",
7
- "type": "module",
8
- "main": "./src/index.js",
9
- "module": "./src/index.js",
10
- "browser": "./bundle/sythos-barcode.js",
11
- "unpkg": "./bundle/sythos-barcode.js",
12
- "jsdelivr": "./bundle/sythos-barcode.js",
13
- "sideEffects": false,
14
- "engines": {
15
- "node": ">=18"
16
- },
17
- "publishConfig": {
18
- "access": "public"
19
- },
20
- "exports": {
21
- ".": "./src/index.js",
22
- "./core": "./src/core/index.js",
23
- "./image": "./src/image/index.js",
24
- "./oned": "./src/oned/index.js",
1
+ {
2
+ "name": "@sythos/js_barcode_universal",
3
+ "version": "1.4.1",
4
+ "description": "Read and write barcodes in JavaScript with zero runtime dependencies. QR Code, Micro QR, rMQR, FrameQR Code, Aztec Code and Rune, PDF417 variants, GS1 DataBar Omnidirectional/Truncated, EAN supplements and one-dimensional formats.",
5
+ "author": {
6
+ "name": "Sythos",
7
+ "url": "https://www.sythos.net"
8
+ },
9
+ "license": "MIT",
10
+ "type": "module",
11
+ "main": "./src/index.js",
12
+ "module": "./src/index.js",
13
+ "browser": "./bundle/sythos-barcode.js",
14
+ "unpkg": "./bundle/sythos-barcode.js",
15
+ "jsdelivr": "./bundle/sythos-barcode.js",
16
+ "sideEffects": false,
17
+ "engines": {
18
+ "node": ">=18"
19
+ },
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "exports": {
24
+ ".": "./src/index.js",
25
+ "./core": "./src/core/index.js",
26
+ "./image": "./src/image/index.js",
27
+ "./oned": "./src/oned/index.js",
25
28
  "./qr": "./src/qr/index.js",
26
29
  "./datamatrix": "./src/datamatrix/index.js",
30
+ "./databar": "./src/databar/index.js",
27
31
  "./aztec": "./src/aztec/index.js",
32
+ "./aztecrune": "./src/aztecrune/index.js",
28
33
  "./pdf417": "./src/pdf417/index.js",
34
+ "./compactpdf417": "./src/compactpdf417/index.js",
29
35
  "./micropdf417": "./src/micropdf417/index.js",
30
- "./render": "./src/render/index.js",
31
- "./render/svg": "./src/render/svg.js",
32
- "./render/png": "./src/render/png.js",
33
- "./render/image-data": "./src/render/image-data.js",
34
- "./bundle": "./bundle/sythos-barcode.esm.js",
35
- "./bundle/iife": "./bundle/sythos-barcode.js",
36
- "./package.json": "./package.json"
37
- },
38
- "files": [
39
- "src",
40
- "bundle",
41
- "examples",
42
- "licenses",
43
- "LICENSE",
44
- "NOTICE.md",
45
- "README.md"
46
- ],
47
- "keywords": [
48
- "barcode",
36
+ "./microqr": "./src/microqr/index.js",
37
+ "./rmqr": "./src/rmqr/index.js",
38
+ "./frameqr": "./src/frameqr/index.js",
39
+ "./render": "./src/render/index.js",
40
+ "./render/svg": "./src/render/svg.js",
41
+ "./render/png": "./src/render/png.js",
42
+ "./render/image-data": "./src/render/image-data.js",
43
+ "./bundle": "./bundle/sythos-barcode.esm.js",
44
+ "./bundle/iife": "./bundle/sythos-barcode.js",
45
+ "./package.json": "./package.json"
46
+ },
47
+ "files": [
48
+ "src",
49
+ "bundle",
50
+ "examples",
51
+ "licenses",
52
+ "LICENSE",
53
+ "NOTICE.md",
54
+ "README.md",
55
+ "AI_USAGE.md"
56
+ ],
57
+ "keywords": [
58
+ "barcode",
49
59
  "datamatrix",
50
60
  "ecc200",
51
61
  "aztec",
62
+ "aztec-rune",
63
+ "compact-pdf417",
64
+ "gs1-databar",
65
+ "ean2",
66
+ "ean5",
52
67
  "aztec-code",
53
68
  "pdf417",
54
69
  "pdf-417",
55
70
  "micropdf417",
56
71
  "micro-pdf417",
72
+ "microqr",
73
+ "micro-qr",
74
+ "rmqr",
75
+ "rectangular-micro-qr",
76
+ "frameqr",
77
+ "canvas-qr",
57
78
  "sdk",
58
- "barcode-generator",
59
- "barcode-scanner",
60
- "qrcode",
61
- "qr",
62
- "qr-code",
63
- "ean",
64
- "ean13",
65
- "ean8",
66
- "upc",
67
- "upca",
68
- "upce",
69
- "isbn",
70
- "code128",
71
- "gs1-128",
72
- "code39",
73
- "code93",
74
- "itf",
75
- "itf14",
76
- "codabar",
77
- "msi",
78
- "code11",
79
- "pharmacode",
80
- "scanner",
81
- "decoder",
82
- "encoder",
83
- "generator",
84
- "reader",
85
- "writer",
86
- "zero-dependencies",
87
- "no-dependencies",
88
- "browser",
89
- "nodejs",
90
- "esm"
91
- ],
92
- "repository": {
93
- "type": "git",
94
- "url": "git+https://github.com/Sythos/JS_Barcode_Universal.git"
95
- },
96
- "bugs": {
97
- "url": "https://github.com/Sythos/JS_Barcode_Universal/issues"
98
- },
99
- "homepage": "https://github.com/Sythos/JS_Barcode_Universal#readme",
100
- "dependencies": {},
101
- "devDependencies": {}
102
- }
79
+ "barcode-generator",
80
+ "barcode-scanner",
81
+ "qrcode",
82
+ "qr",
83
+ "qr-code",
84
+ "ean",
85
+ "ean13",
86
+ "ean8",
87
+ "upc",
88
+ "upca",
89
+ "upce",
90
+ "isbn",
91
+ "code128",
92
+ "gs1-128",
93
+ "code39",
94
+ "code93",
95
+ "itf",
96
+ "itf14",
97
+ "codabar",
98
+ "msi",
99
+ "code11",
100
+ "pharmacode",
101
+ "scanner",
102
+ "decoder",
103
+ "encoder",
104
+ "generator",
105
+ "reader",
106
+ "writer",
107
+ "zero-dependencies",
108
+ "no-dependencies",
109
+ "browser",
110
+ "nodejs",
111
+ "esm"
112
+ ],
113
+ "repository": {
114
+ "type": "git",
115
+ "url": "git+https://github.com/Sythos/JS_Barcode_Universal.git"
116
+ },
117
+ "bugs": {
118
+ "url": "https://github.com/Sythos/JS_Barcode_Universal/issues"
119
+ },
120
+ "homepage": "https://github.com/Sythos/JS_Barcode_Universal#readme",
121
+ "dependencies": {},
122
+ "devDependencies": {}
123
+ }
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -0,0 +1,156 @@
1
+ /*!
2
+ * Sythos Barcode Suite
3
+ *
4
+ * MIT License
5
+ *
6
+ * Copyright (c) 2026 Sythos
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in all
16
+ * copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ * SOFTWARE.
25
+ *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
27
+ * SPDX-License-Identifier: MIT
28
+ *
29
+ * Original work. No code from any other barcode implementation.
30
+ */
31
+
32
+ /**
33
+ * Aztec Rune decoder.
34
+ *
35
+ * The input is a square 11x11 module matrix. Structural modules are checked
36
+ * before the seven masked GF(16) codewords are Reed-Solomon corrected. The
37
+ * decoder tries the four in-plane quarter turns and both polarities, allowing
38
+ * it to consume an oriented sampled image while still rejecting ordinary
39
+ * Aztec/QR matrices.
40
+ *
41
+ * @module aztecrune/decoder
42
+ */
43
+
44
+ import { FormatError } from '../core/errors.js';
45
+ import { rsDecode } from '../core/reed-solomon.js';
46
+ import {
47
+ AZTEC_RUNE_DATA_CODEWORDS,
48
+ AZTEC_RUNE_DATA_POSITIONS,
49
+ AZTEC_RUNE_ECC_CODEWORDS,
50
+ AZTEC_RUNE_MASK,
51
+ AZTEC_RUNE_SIZE,
52
+ aztecRuneField,
53
+ aztecRuneStructuralValue,
54
+ } from './tables.js';
55
+
56
+ /** @param {import('../core/bit-matrix.js').BitMatrix} source @param {number} turns */
57
+ function rotateClockwise(source, turns) {
58
+ let current = source.clone();
59
+ for (let turn = 0; turn < turns; turn++) {
60
+ const out = new source.constructor(current.height, current.width);
61
+ for (let y = 0; y < current.height; y++) for (let x = 0; x < current.width; x++) {
62
+ if (current.get(x, y)) out.set(current.height - 1 - y, x);
63
+ }
64
+ current = out;
65
+ }
66
+ return current;
67
+ }
68
+
69
+ /** @param {import('../core/bit-matrix.js').BitMatrix} matrix */
70
+ function invert(matrix) {
71
+ const out = matrix.clone();
72
+ for (let y = 0; y < out.height; y++) for (let x = 0; x < out.width; x++) out.flip(x, y);
73
+ return out;
74
+ }
75
+
76
+ /** @param {import('../core/bit-matrix.js').BitMatrix} matrix @param {boolean} inverted */
77
+ function structureMatches(matrix, inverted) {
78
+ for (let y = 0; y < AZTEC_RUNE_SIZE; y++) for (let x = 0; x < AZTEC_RUNE_SIZE; x++) {
79
+ const expected = aztecRuneStructuralValue(x, y);
80
+ if (expected === null) continue;
81
+ if (matrix.get(x, y) !== (inverted ? !expected : expected)) return false;
82
+ }
83
+ return true;
84
+ }
85
+
86
+ /** @param {import('../core/bit-matrix.js').BitMatrix} matrix @param {boolean} inverted */
87
+ function readCodewords(matrix, inverted) {
88
+ const words = new Array(2 + AZTEC_RUNE_ECC_CODEWORDS).fill(0);
89
+ for (let at = 0; at < AZTEC_RUNE_DATA_POSITIONS.length; at++) {
90
+ const [x, y] = AZTEC_RUNE_DATA_POSITIONS[at];
91
+ const bit = matrix.get(x, y) !== inverted;
92
+ words[at >>> 2] = (words[at >>> 2] << 1) | (bit ? 1 : 0);
93
+ }
94
+ return words.map((word) => word ^ AZTEC_RUNE_MASK);
95
+ }
96
+
97
+ /** @param {number} value @param {boolean} inverted @param {number} rotation @param {number} corrections */
98
+ function result(value, inverted, rotation, corrections) {
99
+ return {
100
+ format: 'aztecrune',
101
+ value,
102
+ text: String(value).padStart(3, '0'),
103
+ bytes: Uint8Array.of(value),
104
+ dimension: AZTEC_RUNE_SIZE,
105
+ inverted,
106
+ rotation,
107
+ corrections,
108
+ };
109
+ }
110
+
111
+ /**
112
+ * Decode a square Aztec Rune matrix.
113
+ *
114
+ * @param {import('../core/bit-matrix.js').BitMatrix} matrix
115
+ * @param {{inverted?: boolean|'auto', rotation?: number|'auto'}} [options]
116
+ * @returns {{format:'aztecrune',value:number,text:string,bytes:Uint8Array,dimension:number,inverted:boolean,rotation:number,corrections:number}}
117
+ * @throws {FormatError} For non-Rune geometry, structure or uncorrectable data.
118
+ */
119
+ export function decodeAztecRune(matrix, options = {}) {
120
+ if (!matrix || matrix.width !== AZTEC_RUNE_SIZE || matrix.height !== AZTEC_RUNE_SIZE) {
121
+ throw new FormatError(`Aztec Rune: expected an ${AZTEC_RUNE_SIZE}x${AZTEC_RUNE_SIZE} module matrix`);
122
+ }
123
+ const invertedModes = options.inverted === true ? [true] : options.inverted === false ? [false] : [false, true];
124
+ const rotations = Number.isInteger(options.rotation)
125
+ ? [((options.rotation % 360) + 360) % 360]
126
+ : [0, 90, 180, 270];
127
+
128
+ let checksumError = null;
129
+ for (const requestedRotation of rotations) {
130
+ if (requestedRotation % 90 !== 0) continue;
131
+ // To canonicalize an input rotated clockwise by k degrees, rotate it
132
+ // counter-clockwise by k. `turns` is the clockwise operation we apply.
133
+ const turns = (4 - requestedRotation / 90) % 4;
134
+ const canonicalRotation = requestedRotation;
135
+ const rotated = turns === 0 ? matrix.clone() : rotateClockwise(matrix, turns);
136
+ for (const inverted of invertedModes) {
137
+ const canonical = inverted ? invert(rotated) : rotated;
138
+ if (!structureMatches(canonical, false)) continue;
139
+ const words = readCodewords(canonical, false);
140
+ try {
141
+ const corrections = rsDecode(words, AZTEC_RUNE_ECC_CODEWORDS, aztecRuneField(), 1);
142
+ const value = (words[0] << 4) | words[1];
143
+ return result(value, inverted, canonicalRotation, corrections);
144
+ } catch (error) {
145
+ checksumError = error;
146
+ }
147
+ }
148
+ }
149
+
150
+ if (checksumError) {
151
+ throw new FormatError(`Aztec Rune: Reed-Solomon check failed: ${checksumError.message}`);
152
+ }
153
+ throw new FormatError('Aztec Rune: structural pattern or orientation is invalid');
154
+ }
155
+
156
+ export { readCodewords, structureMatches };