@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.
Files changed (267) hide show
  1. package/LICENSE +5 -4
  2. package/NOTICE.md +2 -2
  3. package/README.md +50 -37
  4. package/bundle/sythos-barcode.esm.js +12051 -11484
  5. package/bundle/sythos-barcode.js +12051 -11484
  6. package/package.json +52 -45
  7. package/src/index.d.ts +363 -0
  8. package/src/index.js +573 -428
  9. package/src/js/aztec/decoder.js +326 -0
  10. package/src/js/aztec/detector.js +251 -0
  11. package/src/js/aztec/encoder.js +276 -0
  12. package/src/js/aztec/high-level.js +216 -0
  13. package/src/js/aztec/index.js +34 -0
  14. package/src/js/aztec/tables.js +196 -0
  15. package/src/js/aztecrune/decoder.js +146 -0
  16. package/src/js/aztecrune/detector.js +180 -0
  17. package/src/js/aztecrune/encoder.js +103 -0
  18. package/src/js/aztecrune/index.js +34 -0
  19. package/src/js/aztecrune/tables.js +142 -0
  20. package/src/js/compactpdf417/decoder.js +123 -0
  21. package/src/js/compactpdf417/detector.js +138 -0
  22. package/src/js/compactpdf417/encoder.js +127 -0
  23. package/src/js/compactpdf417/index.js +5 -0
  24. package/src/js/compactpdf417/tables.js +164 -0
  25. package/src/js/core/bit-buffer.js +158 -0
  26. package/src/js/core/bit-matrix.js +243 -0
  27. package/src/js/core/errors.js +59 -0
  28. package/src/js/core/galois-field.js +193 -0
  29. package/src/js/core/index.js +39 -0
  30. package/src/js/core/reed-solomon.js +318 -0
  31. package/src/js/databar/codec.js +166 -0
  32. package/src/js/databar/decoder.js +224 -0
  33. package/src/js/databar/encoder.js +88 -0
  34. package/src/js/databar/gs1.js +176 -0
  35. package/src/js/databar/index.js +36 -0
  36. package/src/js/databar/patterns.js +139 -0
  37. package/src/js/databar/tables.js +123 -0
  38. package/src/js/datamatrix/decoder.js +296 -0
  39. package/src/js/datamatrix/detector.js +254 -0
  40. package/src/js/datamatrix/encoder.js +250 -0
  41. package/src/js/datamatrix/index.js +34 -0
  42. package/src/js/datamatrix/tables.js +122 -0
  43. package/src/js/frameqr/decoder.js +216 -0
  44. package/src/js/frameqr/detector.js +199 -0
  45. package/src/js/frameqr/encoder.js +143 -0
  46. package/src/js/frameqr/index.js +33 -0
  47. package/src/js/frameqr/tables.js +252 -0
  48. package/src/js/image/binarizer.js +254 -0
  49. package/src/js/image/grid-sampler.js +148 -0
  50. package/src/js/image/index.js +38 -0
  51. package/src/js/image/luminance.js +185 -0
  52. package/src/js/image/perspective.js +158 -0
  53. package/src/js/micropdf417/compaction.js +115 -0
  54. package/src/js/micropdf417/decoder.js +180 -0
  55. package/src/js/micropdf417/detector.js +152 -0
  56. package/src/js/micropdf417/encoder.js +184 -0
  57. package/src/js/micropdf417/error-correction.js +50 -0
  58. package/src/js/micropdf417/index.js +35 -0
  59. package/src/js/micropdf417/tables.js +197 -0
  60. package/src/js/microqr/decoder.js +240 -0
  61. package/src/js/microqr/detector.js +339 -0
  62. package/src/js/microqr/encoder.js +314 -0
  63. package/src/js/microqr/index.js +34 -0
  64. package/src/js/microqr/tables.js +324 -0
  65. package/src/js/oned/addons.js +396 -0
  66. package/src/js/oned/index.js +75 -0
  67. package/src/js/oned/patterns.js +365 -0
  68. package/src/js/oned/reader.js +1383 -0
  69. package/src/js/oned/writers.js +691 -0
  70. package/src/js/pdf417/compaction.js +391 -0
  71. package/src/js/pdf417/decoder.js +110 -0
  72. package/src/js/pdf417/detector.js +484 -0
  73. package/src/js/pdf417/encoder.js +102 -0
  74. package/src/js/pdf417/error-correction.js +44 -0
  75. package/src/{pdf417 → js/pdf417}/index.js +0 -5
  76. package/src/js/pdf417/tables.js +315 -0
  77. package/src/js/qr/decoder.js +539 -0
  78. package/src/js/qr/detector.js +613 -0
  79. package/src/js/qr/encoder.js +873 -0
  80. package/src/js/qr/index.js +42 -0
  81. package/src/js/qr/tables.js +690 -0
  82. package/src/js/render/image-data.js +120 -0
  83. package/src/js/render/index.js +128 -0
  84. package/src/js/render/options.js +152 -0
  85. package/src/js/render/png.js +270 -0
  86. package/src/js/render/svg.js +117 -0
  87. package/src/js/render/webgl.js +200 -0
  88. package/src/js/render/webgpu.js +357 -0
  89. package/src/js/rmqr/decoder.js +209 -0
  90. package/src/js/rmqr/detector.js +122 -0
  91. package/src/js/rmqr/encoder.js +321 -0
  92. package/src/js/rmqr/index.js +33 -0
  93. package/src/js/rmqr/tables.js +177 -0
  94. package/src/{aztec/decoder.js → ts/aztec/decoder.ts} +0 -1
  95. package/{typings → src/ts}/aztec/detector.d.ts +2 -2
  96. package/src/{aztec/detector.js → ts/aztec/detector.ts} +0 -1
  97. package/src/{aztec/encoder.js → ts/aztec/encoder.ts} +0 -1
  98. package/src/{aztec/high-level.js → ts/aztec/high-level.ts} +0 -1
  99. package/src/{aztec/index.js → ts/aztec/index.ts} +0 -1
  100. package/src/{aztec/tables.js → ts/aztec/tables.ts} +0 -1
  101. package/src/{aztecrune/decoder.js → ts/aztecrune/decoder.ts} +0 -1
  102. package/src/{aztecrune/detector.js → ts/aztecrune/detector.ts} +0 -1
  103. package/src/{aztecrune/encoder.js → ts/aztecrune/encoder.ts} +0 -1
  104. package/src/{aztecrune/index.js → ts/aztecrune/index.ts} +0 -1
  105. package/src/{aztecrune/tables.js → ts/aztecrune/tables.ts} +0 -1
  106. package/src/{compactpdf417/decoder.js → ts/compactpdf417/decoder.ts} +0 -1
  107. package/src/{compactpdf417/detector.js → ts/compactpdf417/detector.ts} +0 -1
  108. package/src/{compactpdf417/encoder.js → ts/compactpdf417/encoder.ts} +0 -1
  109. package/src/{compactpdf417/index.js → ts/compactpdf417/index.ts} +0 -5
  110. package/src/{compactpdf417/tables.js → ts/compactpdf417/tables.ts} +0 -1
  111. package/src/{core/bit-buffer.js → ts/core/bit-buffer.ts} +0 -1
  112. package/src/{core/bit-matrix.js → ts/core/bit-matrix.ts} +0 -1
  113. package/src/{core/errors.js → ts/core/errors.ts} +0 -1
  114. package/src/{core/galois-field.js → ts/core/galois-field.ts} +0 -1
  115. package/src/{core/index.js → ts/core/index.ts} +0 -1
  116. package/src/{core/reed-solomon.js → ts/core/reed-solomon.ts} +0 -1
  117. package/src/{databar/codec.js → ts/databar/codec.ts} +0 -1
  118. package/src/{databar/decoder.js → ts/databar/decoder.ts} +0 -1
  119. package/src/{databar/encoder.js → ts/databar/encoder.ts} +0 -1
  120. package/src/{databar/gs1.js → ts/databar/gs1.ts} +0 -1
  121. package/src/{databar/index.js → ts/databar/index.ts} +0 -1
  122. package/src/{databar/patterns.js → ts/databar/patterns.ts} +0 -1
  123. package/src/{databar/tables.js → ts/databar/tables.ts} +0 -1
  124. package/src/{datamatrix/decoder.js → ts/datamatrix/decoder.ts} +0 -1
  125. package/{typings → src/ts}/datamatrix/detector.d.ts +2 -2
  126. package/src/{datamatrix/detector.js → ts/datamatrix/detector.ts} +0 -1
  127. package/src/{datamatrix/encoder.js → ts/datamatrix/encoder.ts} +0 -1
  128. package/src/{datamatrix/index.js → ts/datamatrix/index.ts} +0 -1
  129. package/src/{datamatrix/tables.js → ts/datamatrix/tables.ts} +0 -1
  130. package/src/{frameqr/decoder.js → ts/frameqr/decoder.ts} +15 -16
  131. package/src/{frameqr/detector.js → ts/frameqr/detector.ts} +2 -3
  132. package/src/{frameqr/encoder.js → ts/frameqr/encoder.ts} +7 -8
  133. package/src/{frameqr/index.js → ts/frameqr/index.ts} +0 -1
  134. package/src/{frameqr/tables.js → ts/frameqr/tables.ts} +10 -11
  135. package/src/{image/binarizer.js → ts/image/binarizer.ts} +0 -1
  136. package/src/{image/grid-sampler.js → ts/image/grid-sampler.ts} +0 -1
  137. package/src/{image/index.js → ts/image/index.ts} +0 -1
  138. package/src/{image/luminance.js → ts/image/luminance.ts} +0 -1
  139. package/src/{image/perspective.js → ts/image/perspective.ts} +0 -1
  140. package/{typings → src/ts}/index.d.ts +3 -3
  141. package/src/ts/index.ts +790 -0
  142. package/src/{micropdf417/compaction.js → ts/micropdf417/compaction.ts} +0 -1
  143. package/src/{micropdf417/decoder.js → ts/micropdf417/decoder.ts} +0 -1
  144. package/src/{micropdf417/detector.js → ts/micropdf417/detector.ts} +0 -1
  145. package/src/{micropdf417/encoder.js → ts/micropdf417/encoder.ts} +0 -1
  146. package/src/{micropdf417/error-correction.js → ts/micropdf417/error-correction.ts} +0 -1
  147. package/src/{micropdf417/index.js → ts/micropdf417/index.ts} +0 -1
  148. package/src/{micropdf417/tables.js → ts/micropdf417/tables.ts} +0 -1
  149. package/src/{microqr/decoder.js → ts/microqr/decoder.ts} +0 -1
  150. package/src/{microqr/detector.js → ts/microqr/detector.ts} +0 -1
  151. package/src/{microqr/encoder.js → ts/microqr/encoder.ts} +0 -1
  152. package/src/{microqr/index.js → ts/microqr/index.ts} +0 -1
  153. package/src/{microqr/tables.js → ts/microqr/tables.ts} +0 -1
  154. package/src/{oned/addons.js → ts/oned/addons.ts} +0 -1
  155. package/src/{oned/index.js → ts/oned/index.ts} +0 -1
  156. package/src/{oned/patterns.js → ts/oned/patterns.ts} +0 -1
  157. package/src/{oned/reader.js → ts/oned/reader.ts} +0 -1
  158. package/src/{oned/writers.js → ts/oned/writers.ts} +0 -1
  159. package/src/{pdf417/compaction.js → ts/pdf417/compaction.ts} +0 -1
  160. package/src/{pdf417/decoder.js → ts/pdf417/decoder.ts} +0 -1
  161. package/src/{pdf417/detector.js → ts/pdf417/detector.ts} +0 -1
  162. package/src/{pdf417/encoder.js → ts/pdf417/encoder.ts} +0 -1
  163. package/src/{pdf417/error-correction.js → ts/pdf417/error-correction.ts} +0 -1
  164. package/src/ts/pdf417/index.ts +6 -0
  165. package/src/{pdf417/tables.js → ts/pdf417/tables.ts} +0 -1
  166. package/src/{qr/decoder.js → ts/qr/decoder.ts} +0 -1
  167. package/src/{qr/detector.js → ts/qr/detector.ts} +0 -1
  168. package/src/{qr/encoder.js → ts/qr/encoder.ts} +0 -1
  169. package/src/{qr/index.js → ts/qr/index.ts} +0 -1
  170. package/src/{qr/tables.js → ts/qr/tables.ts} +0 -1
  171. package/src/{render/image-data.js → ts/render/image-data.ts} +0 -1
  172. package/src/{render/index.js → ts/render/index.ts} +0 -1
  173. package/src/{render/options.js → ts/render/options.ts} +0 -1
  174. package/src/{render/png.js → ts/render/png.ts} +0 -1
  175. package/src/{render/svg.js → ts/render/svg.ts} +0 -1
  176. package/src/{render/webgl.js → ts/render/webgl.ts} +0 -1
  177. package/src/{render/webgpu.js → ts/render/webgpu.ts} +0 -1
  178. package/src/{rmqr/decoder.js → ts/rmqr/decoder.ts} +0 -1
  179. package/src/{rmqr/detector.js → ts/rmqr/detector.ts} +0 -1
  180. package/src/{rmqr/encoder.js → ts/rmqr/encoder.ts} +0 -1
  181. package/src/{rmqr/index.js → ts/rmqr/index.ts} +0 -1
  182. package/src/{rmqr/tables.js → ts/rmqr/tables.ts} +0 -1
  183. /package/{typings → src/ts}/aztec/decoder.d.ts +0 -0
  184. /package/{typings → src/ts}/aztec/encoder.d.ts +0 -0
  185. /package/{typings → src/ts}/aztec/high-level.d.ts +0 -0
  186. /package/{typings → src/ts}/aztec/index.d.ts +0 -0
  187. /package/{typings → src/ts}/aztec/tables.d.ts +0 -0
  188. /package/{typings → src/ts}/aztecrune/decoder.d.ts +0 -0
  189. /package/{typings → src/ts}/aztecrune/detector.d.ts +0 -0
  190. /package/{typings → src/ts}/aztecrune/encoder.d.ts +0 -0
  191. /package/{typings → src/ts}/aztecrune/index.d.ts +0 -0
  192. /package/{typings → src/ts}/aztecrune/tables.d.ts +0 -0
  193. /package/{typings → src/ts}/bundle/sythos-barcode.d.ts +0 -0
  194. /package/{typings → src/ts}/bundle/sythos-barcode.esm.d.ts +0 -0
  195. /package/{typings → src/ts}/compactpdf417/decoder.d.ts +0 -0
  196. /package/{typings → src/ts}/compactpdf417/detector.d.ts +0 -0
  197. /package/{typings → src/ts}/compactpdf417/encoder.d.ts +0 -0
  198. /package/{typings → src/ts}/compactpdf417/index.d.ts +0 -0
  199. /package/{typings → src/ts}/compactpdf417/tables.d.ts +0 -0
  200. /package/{typings → src/ts}/core/bit-buffer.d.ts +0 -0
  201. /package/{typings → src/ts}/core/bit-matrix.d.ts +0 -0
  202. /package/{typings → src/ts}/core/errors.d.ts +0 -0
  203. /package/{typings → src/ts}/core/galois-field.d.ts +0 -0
  204. /package/{typings → src/ts}/core/index.d.ts +0 -0
  205. /package/{typings → src/ts}/core/reed-solomon.d.ts +0 -0
  206. /package/{typings → src/ts}/databar/codec.d.ts +0 -0
  207. /package/{typings → src/ts}/databar/decoder.d.ts +0 -0
  208. /package/{typings → src/ts}/databar/encoder.d.ts +0 -0
  209. /package/{typings → src/ts}/databar/gs1.d.ts +0 -0
  210. /package/{typings → src/ts}/databar/index.d.ts +0 -0
  211. /package/{typings → src/ts}/databar/patterns.d.ts +0 -0
  212. /package/{typings → src/ts}/databar/tables.d.ts +0 -0
  213. /package/{typings → src/ts}/datamatrix/decoder.d.ts +0 -0
  214. /package/{typings → src/ts}/datamatrix/encoder.d.ts +0 -0
  215. /package/{typings → src/ts}/datamatrix/index.d.ts +0 -0
  216. /package/{typings → src/ts}/datamatrix/tables.d.ts +0 -0
  217. /package/{typings → src/ts}/frameqr/decoder.d.ts +0 -0
  218. /package/{typings → src/ts}/frameqr/detector.d.ts +0 -0
  219. /package/{typings → src/ts}/frameqr/encoder.d.ts +0 -0
  220. /package/{typings → src/ts}/frameqr/index.d.ts +0 -0
  221. /package/{typings → src/ts}/frameqr/tables.d.ts +0 -0
  222. /package/{typings → src/ts}/image/binarizer.d.ts +0 -0
  223. /package/{typings → src/ts}/image/grid-sampler.d.ts +0 -0
  224. /package/{typings → src/ts}/image/index.d.ts +0 -0
  225. /package/{typings → src/ts}/image/luminance.d.ts +0 -0
  226. /package/{typings → src/ts}/image/perspective.d.ts +0 -0
  227. /package/{typings → src/ts}/micropdf417/compaction.d.ts +0 -0
  228. /package/{typings → src/ts}/micropdf417/decoder.d.ts +0 -0
  229. /package/{typings → src/ts}/micropdf417/detector.d.ts +0 -0
  230. /package/{typings → src/ts}/micropdf417/encoder.d.ts +0 -0
  231. /package/{typings → src/ts}/micropdf417/error-correction.d.ts +0 -0
  232. /package/{typings → src/ts}/micropdf417/index.d.ts +0 -0
  233. /package/{typings → src/ts}/micropdf417/tables.d.ts +0 -0
  234. /package/{typings → src/ts}/microqr/decoder.d.ts +0 -0
  235. /package/{typings → src/ts}/microqr/detector.d.ts +0 -0
  236. /package/{typings → src/ts}/microqr/encoder.d.ts +0 -0
  237. /package/{typings → src/ts}/microqr/index.d.ts +0 -0
  238. /package/{typings → src/ts}/microqr/tables.d.ts +0 -0
  239. /package/{typings → src/ts}/oned/addons.d.ts +0 -0
  240. /package/{typings → src/ts}/oned/index.d.ts +0 -0
  241. /package/{typings → src/ts}/oned/patterns.d.ts +0 -0
  242. /package/{typings → src/ts}/oned/reader.d.ts +0 -0
  243. /package/{typings → src/ts}/oned/writers.d.ts +0 -0
  244. /package/{typings → src/ts}/pdf417/compaction.d.ts +0 -0
  245. /package/{typings → src/ts}/pdf417/decoder.d.ts +0 -0
  246. /package/{typings → src/ts}/pdf417/detector.d.ts +0 -0
  247. /package/{typings → src/ts}/pdf417/encoder.d.ts +0 -0
  248. /package/{typings → src/ts}/pdf417/error-correction.d.ts +0 -0
  249. /package/{typings → src/ts}/pdf417/index.d.ts +0 -0
  250. /package/{typings → src/ts}/pdf417/tables.d.ts +0 -0
  251. /package/{typings → src/ts}/qr/decoder.d.ts +0 -0
  252. /package/{typings → src/ts}/qr/detector.d.ts +0 -0
  253. /package/{typings → src/ts}/qr/encoder.d.ts +0 -0
  254. /package/{typings → src/ts}/qr/index.d.ts +0 -0
  255. /package/{typings → src/ts}/qr/tables.d.ts +0 -0
  256. /package/{typings → src/ts}/render/image-data.d.ts +0 -0
  257. /package/{typings → src/ts}/render/index.d.ts +0 -0
  258. /package/{typings → src/ts}/render/options.d.ts +0 -0
  259. /package/{typings → src/ts}/render/png.d.ts +0 -0
  260. /package/{typings → src/ts}/render/svg.d.ts +0 -0
  261. /package/{typings → src/ts}/render/webgl.d.ts +0 -0
  262. /package/{typings → src/ts}/render/webgpu.d.ts +0 -0
  263. /package/{typings → src/ts}/rmqr/decoder.d.ts +0 -0
  264. /package/{typings → src/ts}/rmqr/detector.d.ts +0 -0
  265. /package/{typings → src/ts}/rmqr/encoder.d.ts +0 -0
  266. /package/{typings → src/ts}/rmqr/index.d.ts +0 -0
  267. /package/{typings → src/ts}/rmqr/tables.d.ts +0 -0
@@ -0,0 +1,185 @@
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
+ * Greyscale conversion — the boundary between "an image" and "our problem".
32
+ *
33
+ * The whole library accepts exactly one image shape: `{ data, width, height }`
34
+ * with `data` in RGBA order. That is what `ImageData` is, so a `<canvas>`, an
35
+ * `OffscreenCanvas`, `createImageBitmap`, sharp, jimp and node-canvas all
36
+ * satisfy it without an adapter. Nothing below this file knows about the DOM,
37
+ * the filesystem, or any image codec.
38
+ *
39
+ * @module image/luminance
40
+ */
41
+ import { NotFoundError } from '../core/errors.js';
42
+ /**
43
+ * @typedef {object} ImageLike
44
+ * @property {Uint8ClampedArray | Uint8Array | number[]} data RGBA, 4 bytes per pixel.
45
+ * @property {number} width
46
+ * @property {number} height
47
+ */
48
+ export class LuminanceSource {
49
+ /**
50
+ * @param {Uint8Array} grey One byte per pixel.
51
+ * @param {number} width
52
+ * @param {number} height
53
+ */
54
+ constructor(grey, width, height) {
55
+ this.grey = grey;
56
+ this.width = width;
57
+ this.height = height;
58
+ }
59
+ /**
60
+ * Build from any ImageData-shaped object.
61
+ *
62
+ * Transparent pixels are composited over white rather than read as black:
63
+ * a PNG barcode with a transparent background is common, and treating alpha
64
+ * as ink turns the entire quiet zone into a solid dark field.
65
+ *
66
+ * @param {ImageLike} image
67
+ * @returns {LuminanceSource}
68
+ */
69
+ static fromImageData(image) {
70
+ const { data, width, height } = image;
71
+ if (!data || !width || !height) {
72
+ throw new NotFoundError('Image must be { data, width, height } with RGBA data');
73
+ }
74
+ if (data.length < width * height * 4) {
75
+ throw new NotFoundError(`Image data too short: ${data.length} bytes for ${width}x${height} RGBA ` +
76
+ `(expected ${width * height * 4})`);
77
+ }
78
+ const grey = new Uint8Array(width * height);
79
+ for (let i = 0, p = 0; i < grey.length; i++, p += 4) {
80
+ const a = data[p + 3];
81
+ let r = data[p], g = data[p + 1], b = data[p + 2];
82
+ if (a !== 255) {
83
+ // Composite over white.
84
+ const inv = 255 - a;
85
+ r = (r * a + 255 * inv) / 255;
86
+ g = (g * a + 255 * inv) / 255;
87
+ b = (b * a + 255 * inv) / 255;
88
+ }
89
+ // Integer luma approximation of Rec. 601: 0.299/0.587/0.114 scaled by 256.
90
+ grey[i] = (r * 77 + g * 150 + b * 29) >> 8;
91
+ }
92
+ return new LuminanceSource(grey, width, height);
93
+ }
94
+ /**
95
+ * Build directly from single-channel data, skipping conversion.
96
+ *
97
+ * @param {Uint8Array} grey
98
+ * @param {number} width
99
+ * @param {number} height
100
+ * @returns {LuminanceSource}
101
+ */
102
+ static fromGrey(grey, width, height) {
103
+ if (grey.length < width * height) {
104
+ throw new NotFoundError('Greyscale buffer shorter than width * height');
105
+ }
106
+ return new LuminanceSource(grey, width, height);
107
+ }
108
+ /**
109
+ * @param {number} x @param {number} y
110
+ * @returns {number} 0-255.
111
+ */
112
+ get(x, y) {
113
+ return this.grey[y * this.width + x];
114
+ }
115
+ /**
116
+ * @param {number} y
117
+ * @param {Uint8Array} [out]
118
+ * @returns {Uint8Array}
119
+ */
120
+ getRow(y, out) {
121
+ const row = out && out.length >= this.width ? out : new Uint8Array(this.width);
122
+ row.set(this.grey.subarray(y * this.width, (y + 1) * this.width));
123
+ return row;
124
+ }
125
+ /**
126
+ * Rotate 90 degrees clockwise.
127
+ *
128
+ * The 1D readers scan horizontally, so this is how they find vertically
129
+ * oriented barcodes: scan, rotate, scan again.
130
+ *
131
+ * @returns {LuminanceSource}
132
+ */
133
+ rotate90() {
134
+ const { width: w, height: h, grey } = this;
135
+ const out = new Uint8Array(grey.length);
136
+ for (let y = 0; y < h; y++) {
137
+ for (let x = 0; x < w; x++) {
138
+ out[x * h + (h - 1 - y)] = grey[y * w + x];
139
+ }
140
+ }
141
+ return new LuminanceSource(out, h, w);
142
+ }
143
+ /**
144
+ * Downscale by an integer factor with box averaging.
145
+ *
146
+ * Large camera frames are slow to scan and no more informative than a
147
+ * half-size copy; detectors use this to find candidates cheaply.
148
+ *
149
+ * @param {number} factor
150
+ * @returns {LuminanceSource}
151
+ */
152
+ downscale(factor) {
153
+ const f = Math.max(1, Math.floor(factor));
154
+ if (f === 1)
155
+ return this;
156
+ const w = Math.floor(this.width / f);
157
+ const h = Math.floor(this.height / f);
158
+ const out = new Uint8Array(w * h);
159
+ const area = f * f;
160
+ for (let y = 0; y < h; y++) {
161
+ for (let x = 0; x < w; x++) {
162
+ let sum = 0;
163
+ for (let dy = 0; dy < f; dy++) {
164
+ const base = (y * f + dy) * this.width + x * f;
165
+ for (let dx = 0; dx < f; dx++)
166
+ sum += this.grey[base + dx];
167
+ }
168
+ out[y * w + x] = (sum / area) | 0;
169
+ }
170
+ }
171
+ return new LuminanceSource(out, w, h);
172
+ }
173
+ /**
174
+ * Invert. Some symbols are printed light-on-dark, and readers retry inverted
175
+ * when a first pass finds nothing.
176
+ *
177
+ * @returns {LuminanceSource}
178
+ */
179
+ invert() {
180
+ const out = new Uint8Array(this.grey.length);
181
+ for (let i = 0; i < out.length; i++)
182
+ out[i] = 255 - this.grey[i];
183
+ return new LuminanceSource(out, this.width, this.height);
184
+ }
185
+ }
@@ -0,0 +1,158 @@
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
+ * Projective (perspective) transforms.
32
+ *
33
+ * A 2D symbol photographed off-axis is not a rotated square — it is a
34
+ * quadrilateral with converging edges. Correcting that needs a full projective
35
+ * map, not an affine one; an affine approximation reads the near edge of a
36
+ * tilted symbol correctly and drifts a module or more by the far edge.
37
+ *
38
+ * The map is a 3x3 homogeneous matrix. Points are transformed as
39
+ * (x, y, 1) * M, then divided through by the resulting w.
40
+ *
41
+ * @module image/perspective
42
+ */
43
+ export class PerspectiveTransform {
44
+ /* eslint-disable-next-line max-params */
45
+ constructor(a11, a21, a31, a12, a22, a32, a13, a23, a33) {
46
+ this.a11 = a11;
47
+ this.a21 = a21;
48
+ this.a31 = a31;
49
+ this.a12 = a12;
50
+ this.a22 = a22;
51
+ this.a32 = a32;
52
+ this.a13 = a13;
53
+ this.a23 = a23;
54
+ this.a33 = a33;
55
+ }
56
+ /**
57
+ * Transform points in place.
58
+ *
59
+ * @param {Float32Array | number[]} points Interleaved [x0, y0, x1, y1, ...].
60
+ * @returns {Float32Array | number[]} The same array.
61
+ */
62
+ transform(points) {
63
+ const { a11, a21, a31, a12, a22, a32, a13, a23, a33 } = this;
64
+ for (let i = 0; i < points.length; i += 2) {
65
+ const x = points[i];
66
+ const y = points[i + 1];
67
+ const w = a13 * x + a23 * y + a33;
68
+ points[i] = (a11 * x + a21 * y + a31) / w;
69
+ points[i + 1] = (a12 * x + a22 * y + a32) / w;
70
+ }
71
+ return points;
72
+ }
73
+ /**
74
+ * Transform a single point.
75
+ *
76
+ * @param {number} x @param {number} y
77
+ * @returns {{x: number, y: number}}
78
+ */
79
+ transformPoint(x, y) {
80
+ const w = this.a13 * x + this.a23 * y + this.a33;
81
+ return {
82
+ x: (this.a11 * x + this.a21 * y + this.a31) / w,
83
+ y: (this.a12 * x + this.a22 * y + this.a32) / w,
84
+ };
85
+ }
86
+ /**
87
+ * Map the unit square — (0,0), (1,0), (1,1), (0,1) — onto an arbitrary quad.
88
+ *
89
+ * Corners are given in that same order, i.e. going around the quad, not
90
+ * as opposite pairs.
91
+ *
92
+ * @returns {PerspectiveTransform}
93
+ */
94
+ /* eslint-disable-next-line max-params */
95
+ static squareToQuad(x0, y0, x1, y1, x2, y2, x3, y3) {
96
+ const dx3 = x0 - x1 + x2 - x3;
97
+ const dy3 = y0 - y1 + y2 - y3;
98
+ if (dx3 === 0 && dy3 === 0) {
99
+ // The quad is a parallelogram, so the map is affine and the projective
100
+ // terms vanish. Worth special-casing: it is the common case for flat
101
+ // scans, and the general solution divides by zero here.
102
+ return new PerspectiveTransform(x1 - x0, x2 - x1, x0, y1 - y0, y2 - y1, y0, 0, 0, 1);
103
+ }
104
+ const dx1 = x1 - x2;
105
+ const dx2 = x3 - x2;
106
+ const dy1 = y1 - y2;
107
+ const dy2 = y3 - y2;
108
+ const denominator = dx1 * dy2 - dx2 * dy1;
109
+ const a13 = (dx3 * dy2 - dx2 * dy3) / denominator;
110
+ const a23 = (dx1 * dy3 - dx3 * dy1) / denominator;
111
+ return new PerspectiveTransform(x1 - x0 + a13 * x1, x3 - x0 + a23 * x3, x0, y1 - y0 + a13 * y1, y3 - y0 + a23 * y3, y0, a13, a23, 1);
112
+ }
113
+ /**
114
+ * Map an arbitrary quad onto the unit square — the inverse of
115
+ * {@link squareToQuad}, via the adjugate.
116
+ *
117
+ * @returns {PerspectiveTransform}
118
+ */
119
+ /* eslint-disable-next-line max-params */
120
+ static quadToSquare(x0, y0, x1, y1, x2, y2, x3, y3) {
121
+ return PerspectiveTransform.squareToQuad(x0, y0, x1, y1, x2, y2, x3, y3).inverse();
122
+ }
123
+ /**
124
+ * Map one quad onto another, corner for corner.
125
+ *
126
+ * This is what turns four detected finder corners into a sampling grid:
127
+ * compose "detected quad -> unit square" with "unit square -> ideal grid".
128
+ *
129
+ * @returns {PerspectiveTransform}
130
+ */
131
+ /* eslint-disable-next-line max-params */
132
+ static quadToQuad(sx0, sy0, sx1, sy1, sx2, sy2, sx3, sy3, dx0, dy0, dx1, dy1, dx2, dy2, dx3, dy3) {
133
+ const toSquare = PerspectiveTransform.quadToSquare(sx0, sy0, sx1, sy1, sx2, sy2, sx3, sy3);
134
+ const toQuad = PerspectiveTransform.squareToQuad(dx0, dy0, dx1, dy1, dx2, dy2, dx3, dy3);
135
+ return toSquare.times(toQuad);
136
+ }
137
+ /**
138
+ * Adjugate — the inverse up to a scale factor, which is irrelevant in
139
+ * homogeneous coordinates because the division by w cancels it.
140
+ *
141
+ * @returns {PerspectiveTransform}
142
+ */
143
+ inverse() {
144
+ const { a11, a21, a31, a12, a22, a32, a13, a23, a33 } = this;
145
+ return new PerspectiveTransform(a22 * a33 - a23 * a32, a23 * a31 - a21 * a33, a21 * a32 - a22 * a31, a13 * a32 - a12 * a33, a11 * a33 - a13 * a31, a12 * a31 - a11 * a32, a12 * a23 - a13 * a22, a13 * a21 - a11 * a23, a11 * a22 - a12 * a21);
146
+ }
147
+ /**
148
+ * Matrix product: apply `this` first, then `other`.
149
+ *
150
+ * @param {PerspectiveTransform} other
151
+ * @returns {PerspectiveTransform}
152
+ */
153
+ times(other) {
154
+ const { a11, a21, a31, a12, a22, a32, a13, a23, a33 } = this;
155
+ const o = other;
156
+ return new PerspectiveTransform(o.a11 * a11 + o.a21 * a12 + o.a31 * a13, o.a11 * a21 + o.a21 * a22 + o.a31 * a23, o.a11 * a31 + o.a21 * a32 + o.a31 * a33, o.a12 * a11 + o.a22 * a12 + o.a32 * a13, o.a12 * a21 + o.a22 * a22 + o.a32 * a23, o.a12 * a31 + o.a22 * a32 + o.a32 * a33, o.a13 * a11 + o.a23 * a12 + o.a33 * a13, o.a13 * a21 + o.a23 * a22 + o.a33 * a23, o.a13 * a31 + o.a23 * a32 + o.a33 * a33);
157
+ }
158
+ }
@@ -0,0 +1,115 @@
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
+ /** MicroPDF417 high-level compaction adapter. @module micropdf417/compaction */
31
+ import { EncodeError } from '../core/errors.js';
32
+ import { compactPdf417Bytes, compactPdf417Numeric, compactPdf417Text, } from '../pdf417/compaction.js';
33
+ function byteLength(value) {
34
+ if (value instanceof Uint8Array)
35
+ return value.byteLength;
36
+ if (ArrayBuffer.isView(value))
37
+ return value.byteLength;
38
+ return -1;
39
+ }
40
+ function assertNotEmpty(value) {
41
+ if ((typeof value === 'string' && value.length === 0) || byteLength(value) === 0) {
42
+ throw new EncodeError('MicroPDF417: value must not be empty');
43
+ }
44
+ }
45
+ function latin1Bytes(value) {
46
+ if (typeof value !== 'string')
47
+ return value;
48
+ const bytes = [];
49
+ for (const character of value) {
50
+ const codePoint = character.codePointAt(0);
51
+ if (codePoint > 255) {
52
+ throw new EncodeError('MicroPDF417 ECI 3: string contains a character outside ISO-8859-1');
53
+ }
54
+ bytes.push(codePoint);
55
+ }
56
+ return Uint8Array.from(bytes);
57
+ }
58
+ function compactByte(value, eci) {
59
+ if (eci === undefined)
60
+ return compactPdf417Bytes(value);
61
+ if (eci === 3)
62
+ return compactPdf417Bytes(latin1Bytes(value));
63
+ if (eci === 26) {
64
+ if (typeof value !== 'string') {
65
+ throw new EncodeError('MicroPDF417 ECI 26: value must be a string so UTF-8 validity is known');
66
+ }
67
+ const encoded = compactPdf417Bytes(value);
68
+ return encoded[0] === 927 && encoded[1] === 26 ? encoded : [927, 26, ...encoded];
69
+ }
70
+ throw new EncodeError('MicroPDF417: supported ECI assignment numbers are 3 and 26');
71
+ }
72
+ /**
73
+ * Compact one MicroPDF417 value.
74
+ *
75
+ * Unlike PDF417, MicroPDF417 starts in Byte Compaction. Text therefore needs
76
+ * an explicit 900 latch. Byte compaction always emits 901 or 924 so its start
77
+ * state is unambiguous, including when an ECI designator precedes it.
78
+ */
79
+ export function compactMicroPDF417(value, options = {}) {
80
+ assertNotEmpty(value);
81
+ const mode = options.compaction ?? 'auto';
82
+ const eci = options.eci;
83
+ if (eci !== undefined && eci !== 3 && eci !== 26) {
84
+ throw new EncodeError('MicroPDF417: supported ECI assignment numbers are 3 and 26');
85
+ }
86
+ if (mode === 'text') {
87
+ if (eci !== undefined)
88
+ throw new EncodeError('MicroPDF417: explicit ECI is supported only with byte compaction');
89
+ return [900, ...compactPdf417Text(value)];
90
+ }
91
+ if (mode === 'numeric') {
92
+ if (eci !== undefined)
93
+ throw new EncodeError('MicroPDF417: explicit ECI is supported only with byte compaction');
94
+ return compactPdf417Numeric(value);
95
+ }
96
+ if (mode === 'byte')
97
+ return compactByte(value, eci);
98
+ if (mode !== 'auto') {
99
+ throw new EncodeError(`MicroPDF417: unsupported compaction mode ${JSON.stringify(mode)}`);
100
+ }
101
+ if (eci !== undefined)
102
+ return compactByte(value, eci);
103
+ if (typeof value === 'string' && /^\d{13,}$/.test(value))
104
+ return compactPdf417Numeric(value);
105
+ if (typeof value === 'string') {
106
+ try {
107
+ return [900, ...compactPdf417Text(value)];
108
+ }
109
+ catch (error) {
110
+ if (!(error instanceof EncodeError))
111
+ throw error;
112
+ }
113
+ }
114
+ return compactPdf417Bytes(value);
115
+ }
@@ -0,0 +1,180 @@
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
+ * Direct-module MicroPDF417 decoder.
32
+ *
33
+ * This module reads an already sampled, axis-aligned `BitMatrix`. Image finding,
34
+ * perspective correction, and recognition from photographic pixels are deliberately
35
+ * outside this first decoder boundary. The RAP sequence is authoritative for format
36
+ * detection; matrix metadata is used only as an optional row-height hint.
37
+ *
38
+ * @module micropdf417/decoder
39
+ */
40
+ import { FormatError } from '../core/errors.js';
41
+ import { decodePdf417CompactionDetailed } from '../pdf417/compaction.js';
42
+ import { pdf417CodewordForPattern } from '../pdf417/tables.js';
43
+ import { microPdf417CorrectErrors } from './error-correction.js';
44
+ import { MICROPDF417_VARIANTS, microPdf417RapSequence, microPdf417RowAddress, microPdf417VariantByNumber, } from './tables.js';
45
+ function symbolWidth(columns) {
46
+ return 21 + columns * 17 + (columns > 2 ? 10 : 0);
47
+ }
48
+ function bits(matrix, y, x, width) {
49
+ let value = 0;
50
+ for (let i = 0; i < width; i++)
51
+ value = (value << 1) | (matrix.get(x + i, y) ? 1 : 0);
52
+ return value;
53
+ }
54
+ function widthsToBits(widths) {
55
+ let dark = true;
56
+ let out = '';
57
+ for (const digit of widths) {
58
+ out += (dark ? '1' : '0').repeat(digit.charCodeAt(0) - 48);
59
+ dark = !dark;
60
+ }
61
+ return out;
62
+ }
63
+ function hasExpectedBits(matrix, y, x, sequence) {
64
+ const expected = widthsToBits(sequence);
65
+ for (let i = 0; i < expected.length; i++) {
66
+ if ((matrix.get(x + i, y) ? '1' : '0') !== expected[i])
67
+ return false;
68
+ }
69
+ return true;
70
+ }
71
+ function centralRapAfter(entry, column) {
72
+ return (entry.columns === 3 && column === 0) ||
73
+ (entry.columns === 4 && column === 1);
74
+ }
75
+ /** Return true when all address patterns for this format candidate agree. */
76
+ function hasValidRowAddresses(matrix, entry, rowHeight) {
77
+ for (let row = 0; row < entry.rows; row++) {
78
+ const y = row * rowHeight;
79
+ const address = microPdf417RowAddress(entry, row);
80
+ let x = 0;
81
+ if (!hasExpectedBits(matrix, y, x, microPdf417RapSequence(address.left, 'side')))
82
+ return false;
83
+ x += 10;
84
+ for (let column = 0; column < entry.columns; column++) {
85
+ x += 17;
86
+ if (centralRapAfter(entry, column)) {
87
+ if (address.center === null ||
88
+ !hasExpectedBits(matrix, y, x, microPdf417RapSequence(address.center, 'center')))
89
+ return false;
90
+ x += 10;
91
+ }
92
+ }
93
+ if (!hasExpectedBits(matrix, y, x, microPdf417RapSequence(address.right, 'side')))
94
+ return false;
95
+ x += 10;
96
+ if (!matrix.get(x, y) || x + 1 !== matrix.width)
97
+ return false;
98
+ }
99
+ return true;
100
+ }
101
+ function candidateFormats(matrix, options) {
102
+ const metadataHeight = matrix.micropdf417?.rowHeight;
103
+ const requestedHeight = options.rowHeight ?? metadataHeight;
104
+ if (requestedHeight !== undefined && (!Number.isInteger(requestedHeight) || requestedHeight < 1)) {
105
+ throw new FormatError('MicroPDF417: rowHeight must be a positive integer');
106
+ }
107
+ const requestedVariant = options.variant === undefined ? null : microPdf417VariantByNumber(options.variant);
108
+ const pool = requestedVariant ? [requestedVariant] : MICROPDF417_VARIANTS;
109
+ const candidates = [];
110
+ for (const entry of pool) {
111
+ if (matrix.width !== symbolWidth(entry.columns))
112
+ continue;
113
+ if (matrix.height % entry.rows)
114
+ continue;
115
+ const rowHeight = matrix.height / entry.rows;
116
+ if (requestedHeight !== undefined && rowHeight !== requestedHeight)
117
+ continue;
118
+ if (hasValidRowAddresses(matrix, entry, rowHeight))
119
+ candidates.push({ entry, rowHeight });
120
+ }
121
+ return candidates;
122
+ }
123
+ function resolveFormat(matrix, options) {
124
+ if (!matrix?.width || !matrix?.height || typeof matrix.get !== 'function') {
125
+ throw new FormatError('MicroPDF417: matrix with width, height and get() is required');
126
+ }
127
+ const candidates = candidateFormats(matrix, options);
128
+ if (!candidates.length)
129
+ throw new FormatError('MicroPDF417: no variant matches matrix geometry and row-address patterns');
130
+ if (candidates.length > 1)
131
+ throw new FormatError('MicroPDF417: row-address patterns do not identify a unique variant');
132
+ return candidates[0];
133
+ }
134
+ function readCodewords(matrix, entry, rowHeight) {
135
+ const codewords = [];
136
+ const erasures = [];
137
+ for (let row = 0; row < entry.rows; row++) {
138
+ const y = row * rowHeight;
139
+ const address = microPdf417RowAddress(entry, row);
140
+ let x = 10;
141
+ for (let column = 0; column < entry.columns; column++) {
142
+ const decoded = pdf417CodewordForPattern(bits(matrix, y, x, 17));
143
+ if (!decoded || decoded.cluster !== address.cluster) {
144
+ erasures.push(codewords.length);
145
+ codewords.push(0);
146
+ }
147
+ else {
148
+ codewords.push(decoded.codeword);
149
+ }
150
+ x += 17;
151
+ if (centralRapAfter(entry, column))
152
+ x += 10;
153
+ }
154
+ }
155
+ return { codewords, erasures };
156
+ }
157
+ /**
158
+ * Decode a sampled MicroPDF417 matrix.
159
+ *
160
+ * The complete fixed data region is compacted after correction. Encoder padding
161
+ * is PDF417 Text latch 900, which contributes no characters at the end of the
162
+ * payload. This avoids relying on non-symbol metadata for payload length.
163
+ */
164
+ export function decodeMicroPDF417(matrix, options = {}) {
165
+ const { entry, rowHeight } = resolveFormat(matrix, options);
166
+ const { codewords, erasures } = readCodewords(matrix, entry, rowHeight);
167
+ const corrections = microPdf417CorrectErrors(codewords, entry, erasures);
168
+ const data = codewords.slice(0, entry.dataCodewords);
169
+ const decoded = decodePdf417CompactionDetailed(data);
170
+ return {
171
+ ...decoded,
172
+ codewords,
173
+ rows: entry.rows,
174
+ columns: entry.columns,
175
+ variant: entry.id,
176
+ eccCodewords: entry.eccCodewords,
177
+ rowHeight,
178
+ corrections,
179
+ };
180
+ }