@sythos/js_barcode_universal 1.5.7 → 1.5.9
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.
- package/LICENSE +5 -4
- package/NOTICE.md +2 -2
- package/README.md +50 -37
- package/bundle/sythos-barcode.esm.js +12051 -11484
- package/bundle/sythos-barcode.js +12051 -11484
- package/package.json +52 -45
- package/src/index.d.ts +363 -0
- package/src/index.js +573 -428
- package/src/js/aztec/decoder.js +326 -0
- package/src/js/aztec/detector.js +251 -0
- package/src/js/aztec/encoder.js +276 -0
- package/src/js/aztec/high-level.js +216 -0
- package/src/js/aztec/index.js +34 -0
- package/src/js/aztec/tables.js +196 -0
- package/src/js/aztecrune/decoder.js +146 -0
- package/src/js/aztecrune/detector.js +180 -0
- package/src/js/aztecrune/encoder.js +103 -0
- package/src/js/aztecrune/index.js +34 -0
- package/src/js/aztecrune/tables.js +142 -0
- package/src/js/compactpdf417/decoder.js +123 -0
- package/src/js/compactpdf417/detector.js +138 -0
- package/src/js/compactpdf417/encoder.js +127 -0
- package/src/js/compactpdf417/index.js +5 -0
- package/src/js/compactpdf417/tables.js +164 -0
- package/src/js/core/bit-buffer.js +158 -0
- package/src/js/core/bit-matrix.js +243 -0
- package/src/js/core/errors.js +59 -0
- package/src/js/core/galois-field.js +193 -0
- package/src/js/core/index.js +39 -0
- package/src/js/core/reed-solomon.js +318 -0
- package/src/js/databar/codec.js +166 -0
- package/src/js/databar/decoder.js +224 -0
- package/src/js/databar/encoder.js +88 -0
- package/src/js/databar/gs1.js +176 -0
- package/src/js/databar/index.js +36 -0
- package/src/js/databar/patterns.js +139 -0
- package/src/js/databar/tables.js +123 -0
- package/src/js/datamatrix/decoder.js +296 -0
- package/src/js/datamatrix/detector.js +254 -0
- package/src/js/datamatrix/encoder.js +250 -0
- package/src/js/datamatrix/index.js +34 -0
- package/src/js/datamatrix/tables.js +122 -0
- package/src/js/frameqr/decoder.js +216 -0
- package/src/js/frameqr/detector.js +199 -0
- package/src/js/frameqr/encoder.js +143 -0
- package/src/js/frameqr/index.js +33 -0
- package/src/js/frameqr/tables.js +252 -0
- package/src/js/image/binarizer.js +254 -0
- package/src/js/image/grid-sampler.js +148 -0
- package/src/js/image/index.js +38 -0
- package/src/js/image/luminance.js +185 -0
- package/src/js/image/perspective.js +158 -0
- package/src/js/micropdf417/compaction.js +115 -0
- package/src/js/micropdf417/decoder.js +180 -0
- package/src/js/micropdf417/detector.js +152 -0
- package/src/js/micropdf417/encoder.js +184 -0
- package/src/js/micropdf417/error-correction.js +50 -0
- package/src/js/micropdf417/index.js +35 -0
- package/src/js/micropdf417/tables.js +197 -0
- package/src/js/microqr/decoder.js +240 -0
- package/src/js/microqr/detector.js +339 -0
- package/src/js/microqr/encoder.js +314 -0
- package/src/js/microqr/index.js +34 -0
- package/src/js/microqr/tables.js +324 -0
- package/src/js/oned/addons.js +396 -0
- package/src/js/oned/index.js +75 -0
- package/src/js/oned/patterns.js +365 -0
- package/src/js/oned/reader.js +1383 -0
- package/src/js/oned/writers.js +691 -0
- package/src/js/pdf417/compaction.js +391 -0
- package/src/js/pdf417/decoder.js +110 -0
- package/src/js/pdf417/detector.js +484 -0
- package/src/js/pdf417/encoder.js +102 -0
- package/src/js/pdf417/error-correction.js +44 -0
- package/src/{pdf417 → js/pdf417}/index.js +0 -5
- package/src/js/pdf417/tables.js +315 -0
- package/src/js/qr/decoder.js +539 -0
- package/src/js/qr/detector.js +613 -0
- package/src/js/qr/encoder.js +873 -0
- package/src/js/qr/index.js +42 -0
- package/src/js/qr/tables.js +690 -0
- package/src/js/render/image-data.js +120 -0
- package/src/js/render/index.js +128 -0
- package/src/js/render/options.js +152 -0
- package/src/js/render/png.js +270 -0
- package/src/js/render/svg.js +117 -0
- package/src/js/render/webgl.js +200 -0
- package/src/js/render/webgpu.js +357 -0
- package/src/js/rmqr/decoder.js +209 -0
- package/src/js/rmqr/detector.js +122 -0
- package/src/js/rmqr/encoder.js +321 -0
- package/src/js/rmqr/index.js +33 -0
- package/src/js/rmqr/tables.js +177 -0
- package/src/{aztec/decoder.js → ts/aztec/decoder.ts} +0 -1
- package/{typings → src/ts}/aztec/detector.d.ts +2 -2
- package/src/{aztec/detector.js → ts/aztec/detector.ts} +0 -1
- package/src/{aztec/encoder.js → ts/aztec/encoder.ts} +0 -1
- package/src/{aztec/high-level.js → ts/aztec/high-level.ts} +0 -1
- package/src/{aztec/index.js → ts/aztec/index.ts} +0 -1
- package/src/{aztec/tables.js → ts/aztec/tables.ts} +0 -1
- package/src/{aztecrune/decoder.js → ts/aztecrune/decoder.ts} +0 -1
- package/src/{aztecrune/detector.js → ts/aztecrune/detector.ts} +0 -1
- package/src/{aztecrune/encoder.js → ts/aztecrune/encoder.ts} +0 -1
- package/src/{aztecrune/index.js → ts/aztecrune/index.ts} +0 -1
- package/src/{aztecrune/tables.js → ts/aztecrune/tables.ts} +0 -1
- package/src/{compactpdf417/decoder.js → ts/compactpdf417/decoder.ts} +0 -1
- package/src/{compactpdf417/detector.js → ts/compactpdf417/detector.ts} +0 -1
- package/src/{compactpdf417/encoder.js → ts/compactpdf417/encoder.ts} +0 -1
- package/src/{compactpdf417/index.js → ts/compactpdf417/index.ts} +0 -5
- package/src/{compactpdf417/tables.js → ts/compactpdf417/tables.ts} +0 -1
- package/src/{core/bit-buffer.js → ts/core/bit-buffer.ts} +0 -1
- package/src/{core/bit-matrix.js → ts/core/bit-matrix.ts} +0 -1
- package/src/{core/errors.js → ts/core/errors.ts} +0 -1
- package/src/{core/galois-field.js → ts/core/galois-field.ts} +0 -1
- package/src/{core/index.js → ts/core/index.ts} +0 -1
- package/src/{core/reed-solomon.js → ts/core/reed-solomon.ts} +0 -1
- package/src/{databar/codec.js → ts/databar/codec.ts} +0 -1
- package/src/{databar/decoder.js → ts/databar/decoder.ts} +0 -1
- package/src/{databar/encoder.js → ts/databar/encoder.ts} +0 -1
- package/src/{databar/gs1.js → ts/databar/gs1.ts} +0 -1
- package/src/{databar/index.js → ts/databar/index.ts} +0 -1
- package/src/{databar/patterns.js → ts/databar/patterns.ts} +0 -1
- package/src/{databar/tables.js → ts/databar/tables.ts} +0 -1
- package/src/{datamatrix/decoder.js → ts/datamatrix/decoder.ts} +0 -1
- package/{typings → src/ts}/datamatrix/detector.d.ts +2 -2
- package/src/{datamatrix/detector.js → ts/datamatrix/detector.ts} +0 -1
- package/src/{datamatrix/encoder.js → ts/datamatrix/encoder.ts} +0 -1
- package/src/{datamatrix/index.js → ts/datamatrix/index.ts} +0 -1
- package/src/{datamatrix/tables.js → ts/datamatrix/tables.ts} +0 -1
- package/src/{frameqr/decoder.js → ts/frameqr/decoder.ts} +15 -16
- package/src/{frameqr/detector.js → ts/frameqr/detector.ts} +2 -3
- package/src/{frameqr/encoder.js → ts/frameqr/encoder.ts} +7 -8
- package/src/{frameqr/index.js → ts/frameqr/index.ts} +0 -1
- package/src/{frameqr/tables.js → ts/frameqr/tables.ts} +10 -11
- package/src/{image/binarizer.js → ts/image/binarizer.ts} +0 -1
- package/src/{image/grid-sampler.js → ts/image/grid-sampler.ts} +0 -1
- package/src/{image/index.js → ts/image/index.ts} +0 -1
- package/src/{image/luminance.js → ts/image/luminance.ts} +0 -1
- package/src/{image/perspective.js → ts/image/perspective.ts} +0 -1
- package/{typings → src/ts}/index.d.ts +3 -3
- package/src/ts/index.ts +790 -0
- package/src/{micropdf417/compaction.js → ts/micropdf417/compaction.ts} +0 -1
- package/src/{micropdf417/decoder.js → ts/micropdf417/decoder.ts} +0 -1
- package/src/{micropdf417/detector.js → ts/micropdf417/detector.ts} +0 -1
- package/src/{micropdf417/encoder.js → ts/micropdf417/encoder.ts} +0 -1
- package/src/{micropdf417/error-correction.js → ts/micropdf417/error-correction.ts} +0 -1
- package/src/{micropdf417/index.js → ts/micropdf417/index.ts} +0 -1
- package/src/{micropdf417/tables.js → ts/micropdf417/tables.ts} +0 -1
- package/src/{microqr/decoder.js → ts/microqr/decoder.ts} +0 -1
- package/src/{microqr/detector.js → ts/microqr/detector.ts} +0 -1
- package/src/{microqr/encoder.js → ts/microqr/encoder.ts} +0 -1
- package/src/{microqr/index.js → ts/microqr/index.ts} +0 -1
- package/src/{microqr/tables.js → ts/microqr/tables.ts} +0 -1
- package/src/{oned/addons.js → ts/oned/addons.ts} +0 -1
- package/src/{oned/index.js → ts/oned/index.ts} +0 -1
- package/src/{oned/patterns.js → ts/oned/patterns.ts} +0 -1
- package/src/{oned/reader.js → ts/oned/reader.ts} +0 -1
- package/src/{oned/writers.js → ts/oned/writers.ts} +0 -1
- package/src/{pdf417/compaction.js → ts/pdf417/compaction.ts} +0 -1
- package/src/{pdf417/decoder.js → ts/pdf417/decoder.ts} +0 -1
- package/src/{pdf417/detector.js → ts/pdf417/detector.ts} +0 -1
- package/src/{pdf417/encoder.js → ts/pdf417/encoder.ts} +0 -1
- package/src/{pdf417/error-correction.js → ts/pdf417/error-correction.ts} +0 -1
- package/src/ts/pdf417/index.ts +6 -0
- package/src/{pdf417/tables.js → ts/pdf417/tables.ts} +0 -1
- package/src/{qr/decoder.js → ts/qr/decoder.ts} +0 -1
- package/src/{qr/detector.js → ts/qr/detector.ts} +0 -1
- package/src/{qr/encoder.js → ts/qr/encoder.ts} +0 -1
- package/src/{qr/index.js → ts/qr/index.ts} +0 -1
- package/src/{qr/tables.js → ts/qr/tables.ts} +0 -1
- package/src/{render/image-data.js → ts/render/image-data.ts} +0 -1
- package/src/{render/index.js → ts/render/index.ts} +0 -1
- package/src/{render/options.js → ts/render/options.ts} +0 -1
- package/src/{render/png.js → ts/render/png.ts} +0 -1
- package/src/{render/svg.js → ts/render/svg.ts} +0 -1
- package/src/{render/webgl.js → ts/render/webgl.ts} +0 -1
- package/src/{render/webgpu.js → ts/render/webgpu.ts} +0 -1
- package/src/{rmqr/decoder.js → ts/rmqr/decoder.ts} +0 -1
- package/src/{rmqr/detector.js → ts/rmqr/detector.ts} +0 -1
- package/src/{rmqr/encoder.js → ts/rmqr/encoder.ts} +0 -1
- package/src/{rmqr/index.js → ts/rmqr/index.ts} +0 -1
- package/src/{rmqr/tables.js → ts/rmqr/tables.ts} +0 -1
- /package/{typings → src/ts}/aztec/decoder.d.ts +0 -0
- /package/{typings → src/ts}/aztec/encoder.d.ts +0 -0
- /package/{typings → src/ts}/aztec/high-level.d.ts +0 -0
- /package/{typings → src/ts}/aztec/index.d.ts +0 -0
- /package/{typings → src/ts}/aztec/tables.d.ts +0 -0
- /package/{typings → src/ts}/aztecrune/decoder.d.ts +0 -0
- /package/{typings → src/ts}/aztecrune/detector.d.ts +0 -0
- /package/{typings → src/ts}/aztecrune/encoder.d.ts +0 -0
- /package/{typings → src/ts}/aztecrune/index.d.ts +0 -0
- /package/{typings → src/ts}/aztecrune/tables.d.ts +0 -0
- /package/{typings → src/ts}/bundle/sythos-barcode.d.ts +0 -0
- /package/{typings → src/ts}/bundle/sythos-barcode.esm.d.ts +0 -0
- /package/{typings → src/ts}/compactpdf417/decoder.d.ts +0 -0
- /package/{typings → src/ts}/compactpdf417/detector.d.ts +0 -0
- /package/{typings → src/ts}/compactpdf417/encoder.d.ts +0 -0
- /package/{typings → src/ts}/compactpdf417/index.d.ts +0 -0
- /package/{typings → src/ts}/compactpdf417/tables.d.ts +0 -0
- /package/{typings → src/ts}/core/bit-buffer.d.ts +0 -0
- /package/{typings → src/ts}/core/bit-matrix.d.ts +0 -0
- /package/{typings → src/ts}/core/errors.d.ts +0 -0
- /package/{typings → src/ts}/core/galois-field.d.ts +0 -0
- /package/{typings → src/ts}/core/index.d.ts +0 -0
- /package/{typings → src/ts}/core/reed-solomon.d.ts +0 -0
- /package/{typings → src/ts}/databar/codec.d.ts +0 -0
- /package/{typings → src/ts}/databar/decoder.d.ts +0 -0
- /package/{typings → src/ts}/databar/encoder.d.ts +0 -0
- /package/{typings → src/ts}/databar/gs1.d.ts +0 -0
- /package/{typings → src/ts}/databar/index.d.ts +0 -0
- /package/{typings → src/ts}/databar/patterns.d.ts +0 -0
- /package/{typings → src/ts}/databar/tables.d.ts +0 -0
- /package/{typings → src/ts}/datamatrix/decoder.d.ts +0 -0
- /package/{typings → src/ts}/datamatrix/encoder.d.ts +0 -0
- /package/{typings → src/ts}/datamatrix/index.d.ts +0 -0
- /package/{typings → src/ts}/datamatrix/tables.d.ts +0 -0
- /package/{typings → src/ts}/frameqr/decoder.d.ts +0 -0
- /package/{typings → src/ts}/frameqr/detector.d.ts +0 -0
- /package/{typings → src/ts}/frameqr/encoder.d.ts +0 -0
- /package/{typings → src/ts}/frameqr/index.d.ts +0 -0
- /package/{typings → src/ts}/frameqr/tables.d.ts +0 -0
- /package/{typings → src/ts}/image/binarizer.d.ts +0 -0
- /package/{typings → src/ts}/image/grid-sampler.d.ts +0 -0
- /package/{typings → src/ts}/image/index.d.ts +0 -0
- /package/{typings → src/ts}/image/luminance.d.ts +0 -0
- /package/{typings → src/ts}/image/perspective.d.ts +0 -0
- /package/{typings → src/ts}/micropdf417/compaction.d.ts +0 -0
- /package/{typings → src/ts}/micropdf417/decoder.d.ts +0 -0
- /package/{typings → src/ts}/micropdf417/detector.d.ts +0 -0
- /package/{typings → src/ts}/micropdf417/encoder.d.ts +0 -0
- /package/{typings → src/ts}/micropdf417/error-correction.d.ts +0 -0
- /package/{typings → src/ts}/micropdf417/index.d.ts +0 -0
- /package/{typings → src/ts}/micropdf417/tables.d.ts +0 -0
- /package/{typings → src/ts}/microqr/decoder.d.ts +0 -0
- /package/{typings → src/ts}/microqr/detector.d.ts +0 -0
- /package/{typings → src/ts}/microqr/encoder.d.ts +0 -0
- /package/{typings → src/ts}/microqr/index.d.ts +0 -0
- /package/{typings → src/ts}/microqr/tables.d.ts +0 -0
- /package/{typings → src/ts}/oned/addons.d.ts +0 -0
- /package/{typings → src/ts}/oned/index.d.ts +0 -0
- /package/{typings → src/ts}/oned/patterns.d.ts +0 -0
- /package/{typings → src/ts}/oned/reader.d.ts +0 -0
- /package/{typings → src/ts}/oned/writers.d.ts +0 -0
- /package/{typings → src/ts}/pdf417/compaction.d.ts +0 -0
- /package/{typings → src/ts}/pdf417/decoder.d.ts +0 -0
- /package/{typings → src/ts}/pdf417/detector.d.ts +0 -0
- /package/{typings → src/ts}/pdf417/encoder.d.ts +0 -0
- /package/{typings → src/ts}/pdf417/error-correction.d.ts +0 -0
- /package/{typings → src/ts}/pdf417/index.d.ts +0 -0
- /package/{typings → src/ts}/pdf417/tables.d.ts +0 -0
- /package/{typings → src/ts}/qr/decoder.d.ts +0 -0
- /package/{typings → src/ts}/qr/detector.d.ts +0 -0
- /package/{typings → src/ts}/qr/encoder.d.ts +0 -0
- /package/{typings → src/ts}/qr/index.d.ts +0 -0
- /package/{typings → src/ts}/qr/tables.d.ts +0 -0
- /package/{typings → src/ts}/render/image-data.d.ts +0 -0
- /package/{typings → src/ts}/render/index.d.ts +0 -0
- /package/{typings → src/ts}/render/options.d.ts +0 -0
- /package/{typings → src/ts}/render/png.d.ts +0 -0
- /package/{typings → src/ts}/render/svg.d.ts +0 -0
- /package/{typings → src/ts}/render/webgl.d.ts +0 -0
- /package/{typings → src/ts}/render/webgpu.d.ts +0 -0
- /package/{typings → src/ts}/rmqr/decoder.d.ts +0 -0
- /package/{typings → src/ts}/rmqr/detector.d.ts +0 -0
- /package/{typings → src/ts}/rmqr/encoder.d.ts +0 -0
- /package/{typings → src/ts}/rmqr/index.d.ts +0 -0
- /package/{typings → src/ts}/rmqr/tables.d.ts +0 -0
|
@@ -0,0 +1,142 @@
|
|
|
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-License-Identifier: MIT
|
|
27
|
+
*
|
|
28
|
+
* Original work. No code from any other barcode implementation.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Aztec Rune geometry.
|
|
32
|
+
*
|
|
33
|
+
* Aztec Rune is the 11x11, one-byte member of the Aztec family. Two 4-bit
|
|
34
|
+
* data words and five 4-bit Reed-Solomon check words are XORed with the fixed
|
|
35
|
+
* Aztec Rune mask and written clockwise on the outer data ring. The finder and
|
|
36
|
+
* corner orientation marks are independent of the value.
|
|
37
|
+
*
|
|
38
|
+
* The constants below are derived from the public Aztec Code specification and
|
|
39
|
+
* are kept separate from the general Aztec implementation so a normal Aztec
|
|
40
|
+
* decoder can never accidentally treat an 11x11 Rune as a regular symbol.
|
|
41
|
+
*
|
|
42
|
+
* @module aztecrune/tables
|
|
43
|
+
*/
|
|
44
|
+
import { BitMatrix } from '../core/bit-matrix.js';
|
|
45
|
+
import { fieldForWordSize } from '../aztec/tables.js';
|
|
46
|
+
export const AZTEC_RUNE_SIZE = 11;
|
|
47
|
+
export const AZTEC_RUNE_DATA_BITS = 8;
|
|
48
|
+
export const AZTEC_RUNE_WORD_SIZE = 4;
|
|
49
|
+
export const AZTEC_RUNE_DATA_CODEWORDS = 2;
|
|
50
|
+
export const AZTEC_RUNE_ECC_CODEWORDS = 5;
|
|
51
|
+
export const AZTEC_RUNE_TOTAL_CODEWORDS = AZTEC_RUNE_DATA_CODEWORDS + AZTEC_RUNE_ECC_CODEWORDS;
|
|
52
|
+
export const AZTEC_RUNE_MASK = 0b1010;
|
|
53
|
+
/**
|
|
54
|
+
* Data-module coordinates in wire order: clockwise, starting at the top.
|
|
55
|
+
* Every side contributes seven modules, for 28 bits in total.
|
|
56
|
+
*/
|
|
57
|
+
export const AZTEC_RUNE_DATA_POSITIONS = Object.freeze([
|
|
58
|
+
...Array.from({ length: 7 }, (_, i) => [i + 2, 0]),
|
|
59
|
+
...Array.from({ length: 7 }, (_, i) => [10, i + 2]),
|
|
60
|
+
...Array.from({ length: 7 }, (_, i) => [8 - i, 10]),
|
|
61
|
+
...Array.from({ length: 7 }, (_, i) => [0, 8 - i]),
|
|
62
|
+
].map(([x, y]) => Object.freeze([x, y])));
|
|
63
|
+
const DATA_KEYS = new Set(AZTEC_RUNE_DATA_POSITIONS.map(([x, y]) => `${x},${y}`));
|
|
64
|
+
/** @param {number} x @param {number} y @returns {boolean} */
|
|
65
|
+
export function isAztecRuneDataPosition(x, y) {
|
|
66
|
+
return DATA_KEYS.has(`${x},${y}`);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Return the value of a structural module. Data positions return `null`.
|
|
70
|
+
* The bull's-eye has five square rings including its one-module centre; its
|
|
71
|
+
* even-radius rings are dark. The four corner groups are the orientation marks
|
|
72
|
+
* described by the Aztec Rune specification.
|
|
73
|
+
*
|
|
74
|
+
* @param {number} x @param {number} y
|
|
75
|
+
* @returns {boolean|null}
|
|
76
|
+
*/
|
|
77
|
+
export function aztecRuneStructuralValue(x, y) {
|
|
78
|
+
if (!Number.isInteger(x) || !Number.isInteger(y) || x < 0 || y < 0 || x >= AZTEC_RUNE_SIZE || y >= AZTEC_RUNE_SIZE) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
if (isAztecRuneDataPosition(x, y))
|
|
82
|
+
return null;
|
|
83
|
+
const distance = Math.max(Math.abs(x - 5), Math.abs(y - 5));
|
|
84
|
+
if (distance <= 4)
|
|
85
|
+
return (distance & 1) === 0;
|
|
86
|
+
// Corner orientation groups, clockwise from the upper-left corner:
|
|
87
|
+
// three dark, white-dark-dark, dark-white-white, three white.
|
|
88
|
+
if ((x === 0 && y <= 1) || (y === 0 && x <= 1))
|
|
89
|
+
return true;
|
|
90
|
+
if ((x === 10 && y <= 1) || (y === 0 && x === 10))
|
|
91
|
+
return true;
|
|
92
|
+
if (x === 9 && y === 0)
|
|
93
|
+
return false;
|
|
94
|
+
if (x === 10 && y === 10)
|
|
95
|
+
return false;
|
|
96
|
+
if (y === 10 && x >= 0 && x <= 1)
|
|
97
|
+
return false;
|
|
98
|
+
if (x === 0 && y >= 9)
|
|
99
|
+
return false;
|
|
100
|
+
if (x === 10 && y === 9)
|
|
101
|
+
return true;
|
|
102
|
+
// All non-data cells are covered by the bull's-eye or the four corners.
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
/** Build only the fixed finder/orientation structure. */
|
|
106
|
+
export function buildAztecRuneStructure() {
|
|
107
|
+
const matrix = new BitMatrix(AZTEC_RUNE_SIZE);
|
|
108
|
+
for (let y = 0; y < AZTEC_RUNE_SIZE; y++) {
|
|
109
|
+
for (let x = 0; x < AZTEC_RUNE_SIZE; x++) {
|
|
110
|
+
const value = aztecRuneStructuralValue(x, y);
|
|
111
|
+
if (value === true)
|
|
112
|
+
matrix.set(x, y);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return matrix;
|
|
116
|
+
}
|
|
117
|
+
/** Return the field used by Rune data/check words. */
|
|
118
|
+
export function aztecRuneField() {
|
|
119
|
+
return fieldForWordSize(AZTEC_RUNE_WORD_SIZE);
|
|
120
|
+
}
|
|
121
|
+
/** Validate the fixed Rune contract and coordinate layout. */
|
|
122
|
+
export function validateAztecRuneTables() {
|
|
123
|
+
const problems = [];
|
|
124
|
+
if (AZTEC_RUNE_SIZE !== 11)
|
|
125
|
+
problems.push('Rune symbol size must be 11');
|
|
126
|
+
if (AZTEC_RUNE_TOTAL_CODEWORDS * AZTEC_RUNE_WORD_SIZE !== 28)
|
|
127
|
+
problems.push('Rune outer ring must carry 28 bits');
|
|
128
|
+
if (AZTEC_RUNE_DATA_POSITIONS.length !== 28)
|
|
129
|
+
problems.push('Rune data ring must contain 28 modules');
|
|
130
|
+
if (new Set(AZTEC_RUNE_DATA_POSITIONS.map(([x, y]) => `${x},${y}`)).size !== 28)
|
|
131
|
+
problems.push('Rune data coordinates must be unique');
|
|
132
|
+
const structure = buildAztecRuneStructure();
|
|
133
|
+
for (let y = 0; y < AZTEC_RUNE_SIZE; y++)
|
|
134
|
+
for (let x = 0; x < AZTEC_RUNE_SIZE; x++) {
|
|
135
|
+
if (isAztecRuneDataPosition(x, y))
|
|
136
|
+
continue;
|
|
137
|
+
const expected = aztecRuneStructuralValue(x, y) === true;
|
|
138
|
+
if (structure.get(x, y) !== expected)
|
|
139
|
+
problems.push(`Rune structure mismatch at ${x},${y}`);
|
|
140
|
+
}
|
|
141
|
+
return problems;
|
|
142
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
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-License-Identifier: MIT
|
|
27
|
+
*
|
|
28
|
+
* Original work. No code from any other barcode implementation.
|
|
29
|
+
*/
|
|
30
|
+
/** Compact PDF417 decoder. @module compactpdf417/decoder */
|
|
31
|
+
import { FormatError } from '../core/errors.js';
|
|
32
|
+
import { decodePdf417CompactionDetailed } from '../pdf417/compaction.js';
|
|
33
|
+
import { pdf417CorrectErrors, pdf417EccLength } from '../pdf417/error-correction.js';
|
|
34
|
+
import { pdf417CodewordForPattern } from '../pdf417/tables.js';
|
|
35
|
+
import { COMPACT_PDF417_START_BITS, compactPdf417Geometry, compactPdf417MatchingLevels, } from './tables.js';
|
|
36
|
+
function bits(matrix, y, x, width) {
|
|
37
|
+
let value = 0;
|
|
38
|
+
for (let index = 0; index < width; index++)
|
|
39
|
+
value = (value << 1) | (matrix.get(x + index, y) ? 1 : 0);
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
function patternString(matrix, y, x, width) {
|
|
43
|
+
return bits(matrix, y, x, width).toString(2).padStart(width, '0');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Decode a compact/truncated PDF417 module matrix.
|
|
47
|
+
*
|
|
48
|
+
* The high-level payload uses the normal PDF417 Text/Byte/Numeric compaction
|
|
49
|
+
* rules. This function only changes the physical row parser: no right row
|
|
50
|
+
* indicator is expected and the final module of each row must be dark.
|
|
51
|
+
*
|
|
52
|
+
* @param {import('../core/bit-matrix.js').BitMatrix} matrix
|
|
53
|
+
* @param {object} [options]
|
|
54
|
+
* @param {number} [options.rowHeight]
|
|
55
|
+
*/
|
|
56
|
+
export function decodeCompactPDF417(matrix, options = {}) {
|
|
57
|
+
if (!matrix?.width || !matrix?.height)
|
|
58
|
+
throw new FormatError('Compact PDF417: no matrix supplied');
|
|
59
|
+
const rowHeight = options.rowHeight ?? matrix.compactPdf417?.rowHeight ?? 3;
|
|
60
|
+
let geometry;
|
|
61
|
+
try {
|
|
62
|
+
geometry = compactPdf417Geometry(matrix.width, matrix.height, rowHeight);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
throw new FormatError(error.message);
|
|
66
|
+
}
|
|
67
|
+
const { rows, columns } = geometry;
|
|
68
|
+
const all = [];
|
|
69
|
+
const erasures = [];
|
|
70
|
+
const leftIndicators = [];
|
|
71
|
+
for (let row = 0; row < rows; row++) {
|
|
72
|
+
const y = row * rowHeight;
|
|
73
|
+
if (patternString(matrix, y, 0, 17) !== COMPACT_PDF417_START_BITS) {
|
|
74
|
+
throw new FormatError('Compact PDF417: missing start pattern');
|
|
75
|
+
}
|
|
76
|
+
const cluster = (row % 3) * 3;
|
|
77
|
+
const leftDecoded = pdf417CodewordForPattern(bits(matrix, y, 17, 17));
|
|
78
|
+
if (!leftDecoded || leftDecoded.cluster !== cluster) {
|
|
79
|
+
throw new FormatError('Compact PDF417: invalid left row indicator');
|
|
80
|
+
}
|
|
81
|
+
leftIndicators.push(leftDecoded.codeword);
|
|
82
|
+
const dataStart = 34;
|
|
83
|
+
const stopX = dataStart + columns * 17;
|
|
84
|
+
if (!matrix.get(stopX, y))
|
|
85
|
+
throw new FormatError('Compact PDF417: missing reduced stop module');
|
|
86
|
+
for (let column = 0; column < columns; column++) {
|
|
87
|
+
const decoded = pdf417CodewordForPattern(bits(matrix, y, dataStart + column * 17, 17));
|
|
88
|
+
if (!decoded || decoded.cluster !== cluster) {
|
|
89
|
+
erasures.push(all.length);
|
|
90
|
+
all.push(0);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
all.push(decoded.codeword);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const levels = compactPdf417MatchingLevels(leftIndicators, rows, columns);
|
|
98
|
+
if (levels.length !== 1)
|
|
99
|
+
throw new FormatError('Compact PDF417: row indicator mismatch');
|
|
100
|
+
const level = levels[0];
|
|
101
|
+
const eccLength = pdf417EccLength(level);
|
|
102
|
+
if (all.length <= eccLength)
|
|
103
|
+
throw new FormatError('Compact PDF417: insufficient codewords for ECC');
|
|
104
|
+
const corrected = all.slice();
|
|
105
|
+
const corrections = pdf417CorrectErrors(corrected, level, erasures);
|
|
106
|
+
const length = corrected[0];
|
|
107
|
+
if (length < 1 || length > corrected.length - eccLength) {
|
|
108
|
+
throw new FormatError('Compact PDF417: invalid symbol length descriptor');
|
|
109
|
+
}
|
|
110
|
+
const payload = corrected.slice(1, length);
|
|
111
|
+
const decoded = decodePdf417CompactionDetailed(payload);
|
|
112
|
+
return {
|
|
113
|
+
...decoded,
|
|
114
|
+
format: 'compact-pdf417',
|
|
115
|
+
compact: true,
|
|
116
|
+
codewords: corrected,
|
|
117
|
+
rows,
|
|
118
|
+
columns,
|
|
119
|
+
eccLevel: level,
|
|
120
|
+
rowHeight,
|
|
121
|
+
corrections,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
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-License-Identifier: MIT
|
|
27
|
+
*
|
|
28
|
+
* Original work. No code from any other barcode implementation.
|
|
29
|
+
*/
|
|
30
|
+
/** Compact PDF417 detector for clean, integer-scaled rasters. @module compactpdf417/detector */
|
|
31
|
+
import { BitMatrix } from '../core/bit-matrix.js';
|
|
32
|
+
import { compactPdf417Width } from './tables.js';
|
|
33
|
+
import { decodeCompactPDF417 } from './decoder.js';
|
|
34
|
+
function rotateClockwise(source) {
|
|
35
|
+
const out = new BitMatrix(source.height, source.width);
|
|
36
|
+
for (let y = 0; y < source.height; y++) {
|
|
37
|
+
for (let x = 0; x < source.width; x++) {
|
|
38
|
+
if (source.get(x, y))
|
|
39
|
+
out.set(source.height - 1 - y, x);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
function cropAndDownsample(source, box, width, height, scale) {
|
|
45
|
+
const out = new BitMatrix(width, height);
|
|
46
|
+
for (let y = 0; y < height; y++) {
|
|
47
|
+
for (let x = 0; x < width; x++) {
|
|
48
|
+
let dark = 0;
|
|
49
|
+
for (let dy = 0; dy < scale; dy++) {
|
|
50
|
+
for (let dx = 0; dx < scale; dx++) {
|
|
51
|
+
if (source.get(box.x + x * scale + dx, box.y + y * scale + dy))
|
|
52
|
+
dark++;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (dark * 2 >= scale * scale)
|
|
56
|
+
out.set(x, y);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
function cornersFor(box) {
|
|
62
|
+
return [
|
|
63
|
+
{ x: box.x, y: box.y },
|
|
64
|
+
{ x: box.x + box.width, y: box.y },
|
|
65
|
+
{ x: box.x + box.width, y: box.y + box.height },
|
|
66
|
+
{ x: box.x, y: box.y + box.height },
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
function mapCorners(corners, toOriginal) {
|
|
70
|
+
return corners.map((point) => toOriginal(point));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Detect one Compact PDF417 symbol in a binarized raster.
|
|
74
|
+
*
|
|
75
|
+
* The clean-raster detector uses the dark bounding box and enumerates legal
|
|
76
|
+
* compact widths, integer module scales, row counts and row heights. It is
|
|
77
|
+
* deliberately conservative: arbitrary perspective, non-integer resampling,
|
|
78
|
+
* grayscale thresholding and damaged stop bars belong to a future photo
|
|
79
|
+
* detector and are not claimed here.
|
|
80
|
+
*
|
|
81
|
+
* @param {import('../core/bit-matrix.js').BitMatrix} binaryImage
|
|
82
|
+
* @param {object} [options]
|
|
83
|
+
* @param {number} [options.rowHeight] Restrict the row-height search.
|
|
84
|
+
* @returns {object|null}
|
|
85
|
+
*/
|
|
86
|
+
export function detectCompactPDF417(binaryImage, options = {}) {
|
|
87
|
+
if (!binaryImage?.width || !binaryImage?.height || typeof binaryImage.get !== 'function')
|
|
88
|
+
return null;
|
|
89
|
+
let oriented = binaryImage;
|
|
90
|
+
let toOriginal = (point) => ({ x: point.x, y: point.y });
|
|
91
|
+
for (let rotation = 0; rotation < 4; rotation++) {
|
|
92
|
+
const bounds = oriented.getBounds();
|
|
93
|
+
if (bounds) {
|
|
94
|
+
for (let columns = 1; columns <= 30; columns++) {
|
|
95
|
+
const width = compactPdf417Width(columns);
|
|
96
|
+
const scale = bounds.width / width;
|
|
97
|
+
if (!Number.isInteger(scale) || scale < 1)
|
|
98
|
+
continue;
|
|
99
|
+
const baseHeight = bounds.height / scale;
|
|
100
|
+
const rowHeights = Number.isInteger(options.rowHeight)
|
|
101
|
+
? [options.rowHeight]
|
|
102
|
+
: Array.from({ length: 18 }, (_, index) => index + 3);
|
|
103
|
+
for (const rowHeight of rowHeights) {
|
|
104
|
+
if (!Number.isInteger(baseHeight / rowHeight))
|
|
105
|
+
continue;
|
|
106
|
+
const rows = baseHeight / rowHeight;
|
|
107
|
+
if (rows < 3 || rows > 90)
|
|
108
|
+
continue;
|
|
109
|
+
const matrix = cropAndDownsample(oriented, bounds, width, baseHeight, scale);
|
|
110
|
+
try {
|
|
111
|
+
const result = decodeCompactPDF417(matrix, { rowHeight });
|
|
112
|
+
const corners = mapCorners(cornersFor(bounds), toOriginal);
|
|
113
|
+
return {
|
|
114
|
+
...result,
|
|
115
|
+
matrix,
|
|
116
|
+
corners,
|
|
117
|
+
rotation: rotation * 90,
|
|
118
|
+
moduleSize: scale,
|
|
119
|
+
compact: true,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// Try another geometry; a standard PDF417 or random artwork should
|
|
124
|
+
// never be accepted unless the compact decoder validates every row.
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const previous = oriented;
|
|
130
|
+
const previousToOriginal = toOriginal;
|
|
131
|
+
oriented = rotateClockwise(previous);
|
|
132
|
+
toOriginal = (point) => previousToOriginal({ x: point.y, y: previous.height - point.x });
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
export function detectAndDecodeCompactPDF417(binaryImage, options = {}) {
|
|
137
|
+
return detectCompactPDF417(binaryImage, options);
|
|
138
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
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-License-Identifier: MIT
|
|
27
|
+
*
|
|
28
|
+
* Original work. No code from any other barcode implementation.
|
|
29
|
+
*/
|
|
30
|
+
/** Compact PDF417 (truncated PDF417) encoder. @module compactpdf417/encoder */
|
|
31
|
+
import { BitMatrix } from '../core/bit-matrix.js';
|
|
32
|
+
import { EncodeError } from '../core/errors.js';
|
|
33
|
+
import { compactPdf417 } from '../pdf417/compaction.js';
|
|
34
|
+
import { pdf417ErrorCorrection, pdf417EccLength } from '../pdf417/error-correction.js';
|
|
35
|
+
import { pdf417PatternForCodeword } from '../pdf417/tables.js';
|
|
36
|
+
import { COMPACT_PDF417_START, compactPdf417Indicators, compactPdf417Width, validateCompactPdf417Options, } from './tables.js';
|
|
37
|
+
function appendWidths(matrix, y, x, sequence, height) {
|
|
38
|
+
let dark = true;
|
|
39
|
+
for (const digit of sequence) {
|
|
40
|
+
const width = digit.charCodeAt(0) - 48;
|
|
41
|
+
if (!Number.isInteger(width) || width < 1 || width > 8) {
|
|
42
|
+
throw new EncodeError('Compact PDF417: invalid module-width sequence');
|
|
43
|
+
}
|
|
44
|
+
if (dark)
|
|
45
|
+
matrix.setRegion(x, y, width, height);
|
|
46
|
+
x += width;
|
|
47
|
+
dark = !dark;
|
|
48
|
+
}
|
|
49
|
+
return x;
|
|
50
|
+
}
|
|
51
|
+
function patternSequence(pattern) {
|
|
52
|
+
return pattern.toString(2).padStart(17, '0').replace(/0+|1+/g, (run) => String(run.length));
|
|
53
|
+
}
|
|
54
|
+
function dimensions(needed, level, options, rowHeight) {
|
|
55
|
+
const ecc = pdf417EccLength(level);
|
|
56
|
+
let best = null;
|
|
57
|
+
for (let rows = options.rows ?? 3; rows <= (options.rows ?? 90); rows++) {
|
|
58
|
+
for (let columns = options.columns ?? 1; columns <= (options.columns ?? 30); columns++) {
|
|
59
|
+
if (rows * columns > 928 || rows * columns - ecc < needed)
|
|
60
|
+
continue;
|
|
61
|
+
const ratio = compactPdf417Width(columns) / (rows * rowHeight);
|
|
62
|
+
const score = (rows * columns - ecc - needed) * 10 +
|
|
63
|
+
Math.abs(ratio - (options.aspectRatio ?? 3));
|
|
64
|
+
if (!best || score < best.score)
|
|
65
|
+
best = { rows, columns, score };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (!best) {
|
|
69
|
+
throw new EncodeError('Compact PDF417: payload does not fit the requested dimensions and error correction level');
|
|
70
|
+
}
|
|
71
|
+
return best;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Encode Compact PDF417.
|
|
75
|
+
*
|
|
76
|
+
* High-level Text/Byte/Numeric compaction is intentionally delegated to the
|
|
77
|
+
* existing PDF417 compaction implementation. `compact` here describes only
|
|
78
|
+
* the physical truncated layout: right row indicators are omitted and the
|
|
79
|
+
* stop pattern is reduced to one dark module.
|
|
80
|
+
*
|
|
81
|
+
* @param {string|Uint8Array|number[]} value
|
|
82
|
+
* @param {object} [options]
|
|
83
|
+
* @returns {import('../core/bit-matrix.js').BitMatrix}
|
|
84
|
+
*/
|
|
85
|
+
export function encodeCompactPDF417(value, options = {}) {
|
|
86
|
+
const rowHeight = validateCompactPdf417Options(options);
|
|
87
|
+
const level = options.eccLevel ?? 2;
|
|
88
|
+
if (!Number.isInteger(level) || level < 0 || level > 8) {
|
|
89
|
+
throw new EncodeError('Compact PDF417: eccLevel must be an integer in 0..8');
|
|
90
|
+
}
|
|
91
|
+
const payload = compactPdf417(value, { compaction: options.compaction, charset: options.charset });
|
|
92
|
+
const { rows, columns } = dimensions(payload.length + 1, level, options, rowHeight);
|
|
93
|
+
const eccLength = pdf417EccLength(level);
|
|
94
|
+
const dataLength = rows * columns - eccLength;
|
|
95
|
+
const data = [dataLength, ...payload];
|
|
96
|
+
while (data.length < dataLength)
|
|
97
|
+
data.push(900);
|
|
98
|
+
const codewords = data.concat(pdf417ErrorCorrection(data, level));
|
|
99
|
+
const matrix = new BitMatrix(compactPdf417Width(columns), rows * rowHeight);
|
|
100
|
+
for (let row = 0; row < rows; row++) {
|
|
101
|
+
const y = row * rowHeight;
|
|
102
|
+
const cluster = (row % 3) * 3;
|
|
103
|
+
let x = appendWidths(matrix, y, 0, COMPACT_PDF417_START, rowHeight);
|
|
104
|
+
const left = compactPdf417Indicators(row, rows, columns, level);
|
|
105
|
+
x = appendWidths(matrix, y, x, patternSequence(pdf417PatternForCodeword(left, cluster)), rowHeight);
|
|
106
|
+
for (let column = 0; column < columns; column++) {
|
|
107
|
+
const codeword = codewords[row * columns + column];
|
|
108
|
+
x = appendWidths(matrix, y, x, patternSequence(pdf417PatternForCodeword(codeword, cluster)), rowHeight);
|
|
109
|
+
}
|
|
110
|
+
// Compact PDF417 terminates every row with one dark module, not the normal
|
|
111
|
+
// right indicator plus 18-module stop pattern.
|
|
112
|
+
matrix.setRegion(x, y, 1, rowHeight);
|
|
113
|
+
x++;
|
|
114
|
+
if (x !== matrix.width)
|
|
115
|
+
throw new EncodeError('Compact PDF417: internal row width mismatch');
|
|
116
|
+
}
|
|
117
|
+
matrix.compactPdf417 = {
|
|
118
|
+
rows,
|
|
119
|
+
columns,
|
|
120
|
+
eccLevel: level,
|
|
121
|
+
rowHeight,
|
|
122
|
+
codewords,
|
|
123
|
+
layout: 'compact',
|
|
124
|
+
};
|
|
125
|
+
return matrix;
|
|
126
|
+
}
|
|
127
|
+
export { dimensions as compactPdf417Dimensions };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/* Compact PDF417 public module exports. */
|
|
2
|
+
export { COMPACT_PDF417_START, COMPACT_PDF417_START_BITS, COMPACT_PDF417_STOP_MODULES, COMPACT_PDF417_LIMITS, compactPdf417Width, compactPdf417Geometry, compactPdf417Indicators, compactPdf417MatchingLevels, validateCompactPdf417Options, validateCompactPdf417Tables, } from './tables.js';
|
|
3
|
+
export { encodeCompactPDF417, compactPdf417Dimensions } from './encoder.js';
|
|
4
|
+
export { decodeCompactPDF417 } from './decoder.js';
|
|
5
|
+
export { detectCompactPDF417, detectAndDecodeCompactPDF417 } from './detector.js';
|