@sythos/js_barcode_universal 1.5.8 → 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.
Files changed (179) hide show
  1. package/LICENSE +5 -4
  2. package/NOTICE.md +2 -2
  3. package/README.md +17 -13
  4. package/bundle/sythos-barcode.esm.js +11658 -11244
  5. package/bundle/sythos-barcode.js +11658 -11244
  6. package/package.json +10 -3
  7. package/src/index.d.ts +1 -1
  8. package/src/index.js +508 -516
  9. package/src/js/aztec/decoder.js +208 -199
  10. package/src/js/aztec/detector.js +153 -126
  11. package/src/js/aztec/encoder.js +172 -153
  12. package/src/js/aztec/high-level.js +106 -101
  13. package/src/js/aztec/index.js +1 -12
  14. package/src/js/aztec/tables.js +106 -120
  15. package/src/js/aztecrune/decoder.js +76 -85
  16. package/src/js/aztecrune/detector.js +107 -93
  17. package/src/js/aztecrune/encoder.js +50 -68
  18. package/src/js/aztecrune/index.js +1 -16
  19. package/src/js/aztecrune/tables.js +59 -54
  20. package/src/js/compactpdf417/decoder.js +69 -74
  21. package/src/js/compactpdf417/detector.js +74 -75
  22. package/src/js/compactpdf417/encoder.js +68 -81
  23. package/src/js/compactpdf417/index.js +1 -13
  24. package/src/js/compactpdf417/tables.js +71 -80
  25. package/src/js/core/bit-buffer.js +106 -122
  26. package/src/js/core/bit-matrix.js +196 -194
  27. package/src/js/core/errors.js +13 -15
  28. package/src/js/core/galois-field.js +119 -133
  29. package/src/js/core/index.js +2 -19
  30. package/src/js/core/reed-solomon.js +195 -204
  31. package/src/js/databar/codec.js +93 -108
  32. package/src/js/databar/decoder.js +149 -140
  33. package/src/js/databar/encoder.js +47 -55
  34. package/src/js/databar/gs1.js +122 -123
  35. package/src/js/databar/index.js +4 -36
  36. package/src/js/databar/patterns.js +81 -85
  37. package/src/js/databar/tables.js +51 -52
  38. package/src/js/datamatrix/decoder.js +216 -182
  39. package/src/js/datamatrix/detector.js +161 -132
  40. package/src/js/datamatrix/encoder.js +192 -133
  41. package/src/js/datamatrix/index.js +1 -9
  42. package/src/js/datamatrix/tables.js +68 -69
  43. package/src/js/frameqr/decoder.js +102 -125
  44. package/src/js/frameqr/detector.js +101 -94
  45. package/src/js/frameqr/encoder.js +67 -80
  46. package/src/js/frameqr/index.js +1 -10
  47. package/src/js/frameqr/tables.js +145 -163
  48. package/src/js/image/binarizer.js +146 -162
  49. package/src/js/image/grid-sampler.js +63 -79
  50. package/src/js/image/index.js +0 -2
  51. package/src/js/image/luminance.js +129 -140
  52. package/src/js/image/perspective.js +112 -149
  53. package/src/js/micropdf417/compaction.js +64 -65
  54. package/src/js/micropdf417/decoder.js +106 -109
  55. package/src/js/micropdf417/detector.js +73 -70
  56. package/src/js/micropdf417/encoder.js +129 -154
  57. package/src/js/micropdf417/error-correction.js +6 -11
  58. package/src/js/micropdf417/index.js +2 -16
  59. package/src/js/micropdf417/tables.js +112 -99
  60. package/src/js/microqr/decoder.js +177 -182
  61. package/src/js/microqr/detector.js +240 -256
  62. package/src/js/microqr/encoder.js +239 -194
  63. package/src/js/microqr/index.js +0 -2
  64. package/src/js/microqr/tables.js +208 -200
  65. package/src/js/oned/addons.js +167 -191
  66. package/src/js/oned/index.js +27 -58
  67. package/src/js/oned/patterns.js +194 -213
  68. package/src/js/oned/reader.js +1003 -984
  69. package/src/js/oned/writers.js +411 -466
  70. package/src/js/pdf417/compaction.js +315 -222
  71. package/src/js/pdf417/decoder.js +71 -36
  72. package/src/js/pdf417/detector.js +377 -361
  73. package/src/js/pdf417/encoder.js +57 -46
  74. package/src/js/pdf417/error-correction.js +5 -8
  75. package/src/js/pdf417/tables.js +248 -250
  76. package/src/js/qr/decoder.js +311 -347
  77. package/src/js/qr/detector.js +378 -395
  78. package/src/js/qr/encoder.js +514 -599
  79. package/src/js/qr/index.js +0 -2
  80. package/src/js/qr/tables.js +375 -422
  81. package/src/js/render/image-data.js +57 -62
  82. package/src/js/render/index.js +21 -23
  83. package/src/js/render/options.js +82 -90
  84. package/src/js/render/png.js +144 -169
  85. package/src/js/render/svg.js +41 -44
  86. package/src/js/render/webgl.js +103 -109
  87. package/src/js/render/webgpu.js +205 -217
  88. package/src/js/rmqr/decoder.js +161 -53
  89. package/src/js/rmqr/detector.js +73 -41
  90. package/src/js/rmqr/encoder.js +253 -104
  91. package/src/js/rmqr/index.js +1 -5
  92. package/src/js/rmqr/tables.js +108 -85
  93. package/src/ts/aztec/decoder.ts +317 -0
  94. package/src/ts/aztec/detector.ts +224 -0
  95. package/src/ts/aztec/encoder.ts +257 -0
  96. package/src/ts/aztec/high-level.ts +211 -0
  97. package/src/ts/aztec/index.ts +45 -0
  98. package/src/ts/aztec/tables.ts +210 -0
  99. package/src/ts/aztecrune/decoder.ts +155 -0
  100. package/src/ts/aztecrune/detector.ts +166 -0
  101. package/src/ts/aztecrune/encoder.ts +121 -0
  102. package/src/ts/aztecrune/index.ts +49 -0
  103. package/src/ts/aztecrune/tables.ts +137 -0
  104. package/src/ts/compactpdf417/decoder.ts +128 -0
  105. package/src/ts/compactpdf417/detector.ts +139 -0
  106. package/src/ts/compactpdf417/encoder.ts +140 -0
  107. package/src/ts/compactpdf417/index.ts +17 -0
  108. package/src/ts/compactpdf417/tables.ts +173 -0
  109. package/src/ts/core/bit-buffer.ts +174 -0
  110. package/src/ts/core/bit-matrix.ts +241 -0
  111. package/src/ts/core/errors.ts +61 -0
  112. package/src/ts/core/galois-field.ts +207 -0
  113. package/src/ts/core/index.ts +56 -0
  114. package/src/ts/core/reed-solomon.ts +327 -0
  115. package/src/ts/databar/codec.ts +181 -0
  116. package/src/ts/databar/decoder.ts +215 -0
  117. package/src/ts/databar/encoder.ts +96 -0
  118. package/src/ts/databar/gs1.ts +177 -0
  119. package/src/ts/databar/index.ts +68 -0
  120. package/src/ts/databar/patterns.ts +143 -0
  121. package/src/ts/databar/tables.ts +124 -0
  122. package/src/ts/datamatrix/decoder.ts +262 -0
  123. package/src/ts/datamatrix/detector.ts +225 -0
  124. package/src/ts/datamatrix/encoder.ts +191 -0
  125. package/src/ts/datamatrix/index.ts +42 -0
  126. package/src/ts/datamatrix/tables.ts +123 -0
  127. package/src/ts/frameqr/decoder.ts +239 -0
  128. package/src/ts/frameqr/detector.ts +192 -0
  129. package/src/ts/frameqr/encoder.ts +156 -0
  130. package/src/ts/frameqr/index.ts +42 -0
  131. package/src/ts/frameqr/tables.ts +270 -0
  132. package/src/ts/image/binarizer.ts +270 -0
  133. package/src/ts/image/grid-sampler.ts +164 -0
  134. package/src/ts/image/index.ts +40 -0
  135. package/src/ts/image/luminance.ts +196 -0
  136. package/src/ts/image/perspective.ts +195 -0
  137. package/src/ts/index.d.ts +1 -1
  138. package/src/ts/index.ts +790 -0
  139. package/src/ts/micropdf417/compaction.ts +116 -0
  140. package/src/ts/micropdf417/decoder.ts +183 -0
  141. package/src/ts/micropdf417/detector.ts +149 -0
  142. package/src/ts/micropdf417/encoder.ts +209 -0
  143. package/src/ts/micropdf417/error-correction.ts +55 -0
  144. package/src/ts/micropdf417/index.ts +49 -0
  145. package/src/ts/micropdf417/tables.ts +184 -0
  146. package/src/ts/microqr/decoder.ts +245 -0
  147. package/src/ts/microqr/detector.ts +355 -0
  148. package/src/ts/microqr/encoder.ts +269 -0
  149. package/src/ts/microqr/index.ts +36 -0
  150. package/src/ts/microqr/tables.ts +316 -0
  151. package/src/ts/oned/addons.ts +420 -0
  152. package/src/ts/oned/index.ts +106 -0
  153. package/src/ts/oned/patterns.ts +384 -0
  154. package/src/ts/oned/reader.ts +1364 -0
  155. package/src/ts/oned/writers.ts +746 -0
  156. package/src/ts/pdf417/compaction.ts +298 -0
  157. package/src/ts/pdf417/decoder.ts +75 -0
  158. package/src/ts/pdf417/detector.ts +468 -0
  159. package/src/ts/pdf417/encoder.ts +91 -0
  160. package/src/ts/pdf417/error-correction.ts +47 -0
  161. package/src/ts/pdf417/index.ts +6 -0
  162. package/src/ts/pdf417/tables.ts +317 -0
  163. package/src/ts/qr/decoder.ts +575 -0
  164. package/src/ts/qr/detector.ts +630 -0
  165. package/src/ts/qr/encoder.ts +958 -0
  166. package/src/ts/qr/index.ts +44 -0
  167. package/src/ts/qr/tables.ts +737 -0
  168. package/src/ts/render/image-data.ts +125 -0
  169. package/src/ts/render/index.ts +130 -0
  170. package/src/ts/render/options.ts +160 -0
  171. package/src/ts/render/png.ts +295 -0
  172. package/src/ts/render/svg.ts +120 -0
  173. package/src/ts/render/webgl.ts +206 -0
  174. package/src/ts/render/webgpu.ts +369 -0
  175. package/src/ts/rmqr/decoder.ts +101 -0
  176. package/src/ts/rmqr/detector.ts +90 -0
  177. package/src/ts/rmqr/encoder.ts +172 -0
  178. package/src/ts/rmqr/index.ts +37 -0
  179. package/src/ts/rmqr/tables.ts +154 -0
@@ -27,7 +27,6 @@
27
27
  *
28
28
  * Original work. No code from any other barcode implementation.
29
29
  */
30
-
31
30
  /**
32
31
  * Aztec Rune geometry.
33
32
  *
@@ -42,10 +41,8 @@
42
41
  *
43
42
  * @module aztecrune/tables
44
43
  */
45
-
46
44
  import { BitMatrix } from '../core/bit-matrix.js';
47
45
  import { fieldForWordSize } from '../aztec/tables.js';
48
-
49
46
  export const AZTEC_RUNE_SIZE = 11;
50
47
  export const AZTEC_RUNE_DATA_BITS = 8;
51
48
  export const AZTEC_RUNE_WORD_SIZE = 4;
@@ -53,23 +50,20 @@ export const AZTEC_RUNE_DATA_CODEWORDS = 2;
53
50
  export const AZTEC_RUNE_ECC_CODEWORDS = 5;
54
51
  export const AZTEC_RUNE_TOTAL_CODEWORDS = AZTEC_RUNE_DATA_CODEWORDS + AZTEC_RUNE_ECC_CODEWORDS;
55
52
  export const AZTEC_RUNE_MASK = 0b1010;
56
-
57
53
  /**
58
54
  * Data-module coordinates in wire order: clockwise, starting at the top.
59
55
  * Every side contributes seven modules, for 28 bits in total.
60
56
  */
61
57
  export const AZTEC_RUNE_DATA_POSITIONS = Object.freeze([
62
- ...Array.from({ length: 7 }, (_, i) => [i + 2, 0]),
63
- ...Array.from({ length: 7 }, (_, i) => [10, i + 2]),
64
- ...Array.from({ length: 7 }, (_, i) => [8 - i, 10]),
65
- ...Array.from({ length: 7 }, (_, i) => [0, 8 - i]),
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]),
66
62
  ].map(([x, y]) => Object.freeze([x, y])));
67
-
68
63
  const DATA_KEYS = new Set(AZTEC_RUNE_DATA_POSITIONS.map(([x, y]) => `${x},${y}`));
69
-
70
64
  /** @param {number} x @param {number} y @returns {boolean} */
71
65
  export function isAztecRuneDataPosition(x, y) {
72
- return DATA_KEYS.has(`${x},${y}`);
66
+ return DATA_KEYS.has(`${x},${y}`);
73
67
  }
74
68
  /**
75
69
  * Return the value of a structural module. Data positions return `null`.
@@ -81,57 +75,68 @@ export function isAztecRuneDataPosition(x, y) {
81
75
  * @returns {boolean|null}
82
76
  */
83
77
  export function aztecRuneStructuralValue(x, y) {
84
- if (!Number.isInteger(x) || !Number.isInteger(y) || x < 0 || y < 0 || x >= AZTEC_RUNE_SIZE || y >= AZTEC_RUNE_SIZE) {
85
- return null;
86
- }
87
- if (isAztecRuneDataPosition(x, y)) return null;
88
-
89
- const distance = Math.max(Math.abs(x - 5), Math.abs(y - 5));
90
- if (distance <= 4) return (distance & 1) === 0;
91
-
92
- // Corner orientation groups, clockwise from the upper-left corner:
93
- // three dark, white-dark-dark, dark-white-white, three white.
94
- if ((x === 0 && y <= 1) || (y === 0 && x <= 1)) return true;
95
- if ((x === 10 && y <= 1) || (y === 0 && x === 10)) return true;
96
- if (x === 9 && y === 0) return false;
97
- if (x === 10 && y === 10) return false;
98
- if (y === 10 && x >= 0 && x <= 1) return false;
99
- if (x === 0 && y >= 9) return false;
100
- if (x === 10 && y === 9) return true;
101
-
102
- // All non-data cells are covered by the bull's-eye or the four corners.
103
- return false;
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
104
  }
105
-
106
105
  /** Build only the fixed finder/orientation structure. */
107
106
  export function buildAztecRuneStructure() {
108
- const matrix = new BitMatrix(AZTEC_RUNE_SIZE);
109
- for (let y = 0; y < AZTEC_RUNE_SIZE; y++) {
110
- for (let x = 0; x < AZTEC_RUNE_SIZE; x++) {
111
- const value = aztecRuneStructuralValue(x, y);
112
- if (value === true) matrix.set(x, y);
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
+ }
113
114
  }
114
- }
115
- return matrix;
115
+ return matrix;
116
116
  }
117
-
118
117
  /** Return the field used by Rune data/check words. */
119
118
  export function aztecRuneField() {
120
- return fieldForWordSize(AZTEC_RUNE_WORD_SIZE);
119
+ return fieldForWordSize(AZTEC_RUNE_WORD_SIZE);
121
120
  }
122
-
123
121
  /** Validate the fixed Rune contract and coordinate layout. */
124
122
  export function validateAztecRuneTables() {
125
- const problems = [];
126
- if (AZTEC_RUNE_SIZE !== 11) problems.push('Rune symbol size must be 11');
127
- if (AZTEC_RUNE_TOTAL_CODEWORDS * AZTEC_RUNE_WORD_SIZE !== 28) problems.push('Rune outer ring must carry 28 bits');
128
- if (AZTEC_RUNE_DATA_POSITIONS.length !== 28) problems.push('Rune data ring must contain 28 modules');
129
- if (new Set(AZTEC_RUNE_DATA_POSITIONS.map(([x, y]) => `${x},${y}`)).size !== 28) problems.push('Rune data coordinates must be unique');
130
- const structure = buildAztecRuneStructure();
131
- for (let y = 0; y < AZTEC_RUNE_SIZE; y++) for (let x = 0; x < AZTEC_RUNE_SIZE; x++) {
132
- if (isAztecRuneDataPosition(x, y)) continue;
133
- const expected = aztecRuneStructuralValue(x, y) === true;
134
- if (structure.get(x, y) !== expected) problems.push(`Rune structure mismatch at ${x},${y}`);
135
- }
136
- return problems;
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;
137
142
  }
@@ -27,30 +27,21 @@
27
27
  *
28
28
  * Original work. No code from any other barcode implementation.
29
29
  */
30
-
31
30
  /** Compact PDF417 decoder. @module compactpdf417/decoder */
32
-
33
31
  import { FormatError } from '../core/errors.js';
34
32
  import { decodePdf417CompactionDetailed } from '../pdf417/compaction.js';
35
33
  import { pdf417CorrectErrors, pdf417EccLength } from '../pdf417/error-correction.js';
36
34
  import { pdf417CodewordForPattern } from '../pdf417/tables.js';
37
- import {
38
- COMPACT_PDF417_START_BITS,
39
- compactPdf417Geometry,
40
- compactPdf417Indicators,
41
- compactPdf417MatchingLevels,
42
- } from './tables.js';
43
-
35
+ import { COMPACT_PDF417_START_BITS, compactPdf417Geometry, compactPdf417MatchingLevels, } from './tables.js';
44
36
  function bits(matrix, y, x, width) {
45
- let value = 0;
46
- for (let index = 0; index < width; index++) value = (value << 1) | (matrix.get(x + index, y) ? 1 : 0);
47
- return value;
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;
48
41
  }
49
-
50
42
  function patternString(matrix, y, x, width) {
51
- return bits(matrix, y, x, width).toString(2).padStart(width, '0');
43
+ return bits(matrix, y, x, width).toString(2).padStart(width, '0');
52
44
  }
53
-
54
45
  /**
55
46
  * Decode a compact/truncated PDF417 module matrix.
56
47
  *
@@ -63,66 +54,70 @@ function patternString(matrix, y, x, width) {
63
54
  * @param {number} [options.rowHeight]
64
55
  */
65
56
  export function decodeCompactPDF417(matrix, options = {}) {
66
- if (!matrix?.width || !matrix?.height) throw new FormatError('Compact PDF417: no matrix supplied');
67
- const rowHeight = options.rowHeight ?? matrix.compactPdf417?.rowHeight ?? 3;
68
- let geometry;
69
- try { geometry = compactPdf417Geometry(matrix.width, matrix.height, rowHeight); }
70
- catch (error) { throw new FormatError(error.message); }
71
-
72
- const { rows, columns } = geometry;
73
- const all = [];
74
- const erasures = [];
75
- const leftIndicators = [];
76
-
77
- for (let row = 0; row < rows; row++) {
78
- const y = row * rowHeight;
79
- if (patternString(matrix, y, 0, 17) !== COMPACT_PDF417_START_BITS) {
80
- throw new FormatError('Compact PDF417: missing start pattern');
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);
81
63
  }
82
- const cluster = (row % 3) * 3;
83
- const leftDecoded = pdf417CodewordForPattern(bits(matrix, y, 17, 17));
84
- if (!leftDecoded || leftDecoded.cluster !== cluster) {
85
- throw new FormatError('Compact PDF417: invalid left row indicator');
64
+ catch (error) {
65
+ throw new FormatError(error.message);
86
66
  }
87
- leftIndicators.push(leftDecoded.codeword);
88
-
89
- const dataStart = 34;
90
- const stopX = dataStart + columns * 17;
91
- if (!matrix.get(stopX, y)) throw new FormatError('Compact PDF417: missing reduced stop module');
92
- for (let column = 0; column < columns; column++) {
93
- const decoded = pdf417CodewordForPattern(bits(matrix, y, dataStart + column * 17, 17));
94
- if (!decoded || decoded.cluster !== cluster) {
95
- erasures.push(all.length);
96
- all.push(0);
97
- } else {
98
- all.push(decoded.codeword);
99
- }
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
+ }
100
96
  }
101
- }
102
-
103
- const levels = compactPdf417MatchingLevels(leftIndicators, rows, columns);
104
- if (levels.length !== 1) throw new FormatError('Compact PDF417: row indicator mismatch');
105
- const level = levels[0];
106
- const eccLength = pdf417EccLength(level);
107
- if (all.length <= eccLength) throw new FormatError('Compact PDF417: insufficient codewords for ECC');
108
-
109
- const corrected = all.slice();
110
- const corrections = pdf417CorrectErrors(corrected, level, erasures);
111
- const length = corrected[0];
112
- if (length < 1 || length > corrected.length - eccLength) {
113
- throw new FormatError('Compact PDF417: invalid symbol length descriptor');
114
- }
115
- const payload = corrected.slice(1, length);
116
- const decoded = decodePdf417CompactionDetailed(payload);
117
- return {
118
- ...decoded,
119
- format: 'compact-pdf417',
120
- compact: true,
121
- codewords: corrected,
122
- rows,
123
- columns,
124
- eccLevel: level,
125
- rowHeight,
126
- corrections,
127
- };
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
+ };
128
123
  }
@@ -27,51 +27,48 @@
27
27
  *
28
28
  * Original work. No code from any other barcode implementation.
29
29
  */
30
-
31
30
  /** Compact PDF417 detector for clean, integer-scaled rasters. @module compactpdf417/detector */
32
-
33
31
  import { BitMatrix } from '../core/bit-matrix.js';
34
32
  import { compactPdf417Width } from './tables.js';
35
33
  import { decodeCompactPDF417 } from './decoder.js';
36
-
37
34
  function rotateClockwise(source) {
38
- const out = new BitMatrix(source.height, source.width);
39
- for (let y = 0; y < source.height; y++) {
40
- for (let x = 0; x < source.width; x++) {
41
- if (source.get(x, y)) out.set(source.height - 1 - y, x);
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
+ }
42
41
  }
43
- }
44
- return out;
42
+ return out;
45
43
  }
46
44
  function cropAndDownsample(source, box, width, height, scale) {
47
- const out = new BitMatrix(width, height);
48
- for (let y = 0; y < height; y++) {
49
- for (let x = 0; x < width; x++) {
50
- let dark = 0;
51
- for (let dy = 0; dy < scale; dy++) {
52
- for (let dx = 0; dx < scale; dx++) {
53
- if (source.get(box.x + x * scale + dx, box.y + y * scale + dy)) dark++;
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);
54
57
  }
55
- }
56
- if (dark * 2 >= scale * scale) out.set(x, y);
57
58
  }
58
- }
59
- return out;
59
+ return out;
60
60
  }
61
-
62
61
  function cornersFor(box) {
63
- return [
64
- { x: box.x, y: box.y },
65
- { x: box.x + box.width, y: box.y },
66
- { x: box.x + box.width, y: box.y + box.height },
67
- { x: box.x, y: box.y + box.height },
68
- ];
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
+ ];
69
68
  }
70
-
71
69
  function mapCorners(corners, toOriginal) {
72
- return corners.map((point) => toOriginal(point));
70
+ return corners.map((point) => toOriginal(point));
73
71
  }
74
-
75
72
  /**
76
73
  * Detect one Compact PDF417 symbol in a binarized raster.
77
74
  *
@@ -87,53 +84,55 @@ function mapCorners(corners, toOriginal) {
87
84
  * @returns {object|null}
88
85
  */
89
86
  export function detectCompactPDF417(binaryImage, options = {}) {
90
- if (!binaryImage?.width || !binaryImage?.height || typeof binaryImage.get !== 'function') return null;
91
-
92
- let oriented = binaryImage;
93
- let toOriginal = (point) => ({ x: point.x, y: point.y });
94
- for (let rotation = 0; rotation < 4; rotation++) {
95
- const bounds = oriented.getBounds();
96
- if (bounds) {
97
- for (let columns = 1; columns <= 30; columns++) {
98
- const width = compactPdf417Width(columns);
99
- const scale = bounds.width / width;
100
- if (!Number.isInteger(scale) || scale < 1) continue;
101
- const baseHeight = bounds.height / scale;
102
- const rowHeights = Number.isInteger(options.rowHeight)
103
- ? [options.rowHeight]
104
- : Array.from({ length: 18 }, (_, index) => index + 3);
105
- for (const rowHeight of rowHeights) {
106
- if (!Number.isInteger(baseHeight / rowHeight)) continue;
107
- const rows = baseHeight / rowHeight;
108
- if (rows < 3 || rows > 90) 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
- } catch {
122
- // Try another geometry; a standard PDF417 or random artwork should
123
- // never be accepted unless the compact decoder validates every row.
124
- }
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
+ }
125
128
  }
126
- }
129
+ const previous = oriented;
130
+ const previousToOriginal = toOriginal;
131
+ oriented = rotateClockwise(previous);
132
+ toOriginal = (point) => previousToOriginal({ x: point.y, y: previous.height - point.x });
127
133
  }
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;
134
+ return null;
135
135
  }
136
-
137
136
  export function detectAndDecodeCompactPDF417(binaryImage, options = {}) {
138
- return detectCompactPDF417(binaryImage, options);
137
+ return detectCompactPDF417(binaryImage, options);
139
138
  }