@sythos/js_barcode_universal 1.3.1 → 1.5.0

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 (101) hide show
  1. package/AI_USAGE.md +33 -0
  2. package/LICENSE +4 -2
  3. package/NOTICE.md +10 -5
  4. package/README.md +95 -31
  5. package/bundle/sythos-barcode.esm.js +11552 -8877
  6. package/bundle/sythos-barcode.js +11469 -8877
  7. package/examples/create.html +2 -1
  8. package/examples/read.html +6 -0
  9. package/licenses/README.md +5 -0
  10. package/licenses/aztec-rune.license +76 -0
  11. package/licenses/compact-pdf417.license +76 -0
  12. package/licenses/ean-2.license +75 -0
  13. package/licenses/ean-5.license +75 -0
  14. package/licenses/gs1-databar.license +84 -0
  15. package/package.json +16 -4
  16. package/src/aztec/decoder.js +1 -0
  17. package/src/aztec/detector.js +1 -0
  18. package/src/aztec/encoder.js +1 -0
  19. package/src/aztec/high-level.js +1 -0
  20. package/src/aztec/index.js +1 -0
  21. package/src/aztec/tables.js +1 -0
  22. package/src/aztecrune/decoder.js +156 -0
  23. package/src/aztecrune/detector.js +167 -0
  24. package/src/aztecrune/encoder.js +122 -0
  25. package/src/aztecrune/index.js +50 -0
  26. package/src/aztecrune/tables.js +138 -0
  27. package/src/compactpdf417/decoder.js +129 -0
  28. package/src/compactpdf417/detector.js +140 -0
  29. package/src/compactpdf417/encoder.js +141 -0
  30. package/src/compactpdf417/index.js +22 -0
  31. package/src/compactpdf417/tables.js +174 -0
  32. package/src/core/bit-buffer.js +1 -0
  33. package/src/core/bit-matrix.js +1 -0
  34. package/src/core/errors.js +1 -0
  35. package/src/core/galois-field.js +1 -0
  36. package/src/core/index.js +1 -0
  37. package/src/core/reed-solomon.js +1 -0
  38. package/src/databar/codec.js +182 -0
  39. package/src/databar/decoder.js +216 -0
  40. package/src/databar/encoder.js +97 -0
  41. package/src/databar/gs1.js +178 -0
  42. package/src/databar/index.js +69 -0
  43. package/src/databar/patterns.js +144 -0
  44. package/src/databar/tables.js +125 -0
  45. package/src/datamatrix/decoder.js +1 -0
  46. package/src/datamatrix/detector.js +1 -0
  47. package/src/datamatrix/encoder.js +1 -0
  48. package/src/datamatrix/index.js +1 -0
  49. package/src/datamatrix/tables.js +1 -0
  50. package/src/frameqr/decoder.js +16 -15
  51. package/src/frameqr/detector.js +3 -2
  52. package/src/frameqr/encoder.js +8 -7
  53. package/src/frameqr/index.js +1 -0
  54. package/src/frameqr/tables.js +11 -10
  55. package/src/image/binarizer.js +1 -0
  56. package/src/image/grid-sampler.js +1 -0
  57. package/src/image/index.js +1 -0
  58. package/src/image/luminance.js +1 -0
  59. package/src/image/perspective.js +1 -0
  60. package/src/index.js +101 -12
  61. package/src/micropdf417/compaction.js +1 -0
  62. package/src/micropdf417/decoder.js +1 -0
  63. package/src/micropdf417/detector.js +1 -0
  64. package/src/micropdf417/encoder.js +1 -0
  65. package/src/micropdf417/error-correction.js +1 -0
  66. package/src/micropdf417/index.js +1 -0
  67. package/src/micropdf417/tables.js +1 -0
  68. package/src/microqr/decoder.js +1 -0
  69. package/src/microqr/detector.js +1 -0
  70. package/src/microqr/encoder.js +1 -0
  71. package/src/microqr/index.js +1 -0
  72. package/src/microqr/tables.js +1 -0
  73. package/src/oned/addons.js +421 -0
  74. package/src/oned/index.js +21 -3
  75. package/src/oned/patterns.js +1 -0
  76. package/src/oned/reader.js +330 -11
  77. package/src/oned/writers.js +6 -0
  78. package/src/pdf417/compaction.js +1 -0
  79. package/src/pdf417/decoder.js +1 -0
  80. package/src/pdf417/detector.js +1 -0
  81. package/src/pdf417/encoder.js +1 -0
  82. package/src/pdf417/error-correction.js +1 -0
  83. package/src/pdf417/index.js +5 -0
  84. package/src/pdf417/tables.js +1 -0
  85. package/src/qr/decoder.js +1 -0
  86. package/src/qr/detector.js +1 -0
  87. package/src/qr/encoder.js +1 -0
  88. package/src/qr/index.js +1 -0
  89. package/src/qr/tables.js +1 -0
  90. package/src/render/image-data.js +1 -0
  91. package/src/render/index.js +1 -0
  92. package/src/render/options.js +1 -0
  93. package/src/render/png.js +1 -0
  94. package/src/render/svg.js +1 -0
  95. package/src/render/webgl.js +1 -0
  96. package/src/render/webgpu.js +1 -0
  97. package/src/rmqr/decoder.js +1 -0
  98. package/src/rmqr/detector.js +1 -0
  99. package/src/rmqr/encoder.js +1 -0
  100. package/src/rmqr/index.js +1 -0
  101. package/src/rmqr/tables.js +1 -0
@@ -4,6 +4,7 @@
4
4
  * MIT License
5
5
  *
6
6
  * Copyright (c) 2026 Sythos
7
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
7
8
  *
8
9
  * Permission is hereby granted, free of charge, to any person obtaining a copy
9
10
  * of this software and associated documentation files (the "Software"), to deal
@@ -29,7 +30,7 @@
29
30
  */
30
31
 
31
32
  /**
32
- * Structural contract for the Sythos Canvas QR profile.
33
+ * Structural contract for FrameQR Code.
33
34
  *
34
35
  * DENSO WAVE's public material describes FrameQR(R) as a proprietary symbol
35
36
  * with a freely shaped canvas, dedicated generation/reading software and no
@@ -41,7 +42,7 @@
41
42
  * symbol at level H and clears a bounded group of data modules. Its worst-case
42
43
  * damage is calculated per Reed-Solomon block and must remain within the
43
44
  * standard QR correction radius. Function modules are never canvas modules.
44
- * This provides a deterministic, independently testable canvas QR profile, but
45
+ * This provides a deterministic, independently testable FrameQR Code profile, but
45
46
  * it is explicitly non-certified and not a substitute for proprietary FrameQR
46
47
  * generation or validation software.
47
48
  *
@@ -58,7 +59,7 @@ import {
58
59
  /** Public identity and compatibility boundary of the implementable profile. */
59
60
  export const FRAMEQR_PROFILE = Object.freeze({
60
61
  id: 'sythos-canvas-qr/1',
61
- name: 'Sythos Canvas QR profile',
62
+ name: 'FrameQR Code',
62
63
  certified: false,
63
64
  densoFrameQrCompatible: false,
64
65
  baseSymbology: 'QR Code Model 2',
@@ -77,7 +78,7 @@ function oddAtMost(value, maximum) {
77
78
 
78
79
  function assertSymbolSize(symbolSize) {
79
80
  if (!Number.isInteger(symbolSize) || symbolSize < 21 || symbolSize > 177 || (symbolSize - 17) % 4 !== 0) {
80
- throw new RangeError(`Frame QR profile: ${symbolSize} is not a QR Model 2 symbol size`);
81
+ throw new RangeError(`FrameQR Code: ${symbolSize} is not a QR Model 2 symbol size`);
81
82
  }
82
83
  }
83
84
 
@@ -95,12 +96,12 @@ function assertSymbolSize(symbolSize) {
95
96
  export function normalizeCanvasSpec(symbolSize, canvas = {}) {
96
97
  assertSymbolSize(symbolSize);
97
98
  if (canvas === null || typeof canvas !== 'object' || Array.isArray(canvas)) {
98
- throw new TypeError('Frame QR profile: canvas must be an object');
99
+ throw new TypeError('FrameQR Code: canvas must be an object');
99
100
  }
100
101
 
101
102
  const shape = String(canvas.shape ?? 'square').toLowerCase();
102
103
  if (!FRAMEQR_CANVAS_SHAPES.includes(shape)) {
103
- throw new RangeError(`Frame QR profile: unsupported canvas shape "${shape}"`);
104
+ throw new RangeError(`FrameQR Code: unsupported canvas shape "${shape}"`);
104
105
  }
105
106
 
106
107
  const defaultSize = oddAtMost(Math.max(3, Math.round(symbolSize * 0.17)), symbolSize - 16);
@@ -111,7 +112,7 @@ export function normalizeCanvasSpec(symbolSize, canvas = {}) {
111
112
  for (const [name, value] of [['width', requestedWidth], ['height', requestedHeight]]) {
112
113
  if (!Number.isFinite(Number(value)) || Number(value) < 1 || Number(value) > maximumDimension) {
113
114
  throw new RangeError(
114
- `Frame QR profile: canvas ${name} must be between 1 and ${maximumDimension} modules`
115
+ `FrameQR Code: canvas ${name} must be between 1 and ${maximumDimension} modules`
115
116
  );
116
117
  }
117
118
  }
@@ -122,10 +123,10 @@ export function normalizeCanvasSpec(symbolSize, canvas = {}) {
122
123
  const angle = ((Number(canvas.angle ?? 0) % 360) + 360) % 360;
123
124
 
124
125
  if (![0, 90, 180, 270].includes(angle)) {
125
- throw new RangeError('Frame QR profile: angle must be 0, 90, 180 or 270 degrees');
126
+ throw new RangeError('FrameQR Code: angle must be 0, 90, 180 or 270 degrees');
126
127
  }
127
128
  if (centerX < 8 || centerY < 8 || centerX >= symbolSize - 8 || centerY >= symbolSize - 8) {
128
- throw new RangeError('Frame QR profile: canvas centre must remain inside the finder-pattern boundary');
129
+ throw new RangeError('FrameQR Code: canvas centre must remain inside the finder-pattern boundary');
129
130
  }
130
131
 
131
132
  return { shape, centerX, centerY, width, height, angle };
@@ -196,7 +197,7 @@ function codewordBlockMap(layout) {
196
197
  */
197
198
  export function analyzeCanvasDamage(version, canvas = {}) {
198
199
  if (!Number.isInteger(version) || version < 1 || version > 40) {
199
- throw new RangeError(`Frame QR profile: version must be an integer 1-40, got ${version}`);
200
+ throw new RangeError(`FrameQR Code: version must be an integer 1-40, got ${version}`);
200
201
  }
201
202
  const symbolSize = versionSize(version);
202
203
  const spec = normalizeCanvasSpec(symbolSize, canvas);
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
package/src/index.js CHANGED
@@ -4,6 +4,7 @@
4
4
  * MIT License
5
5
  *
6
6
  * Copyright (c) 2026 Sythos
7
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
7
8
  *
8
9
  * Permission is hereby granted, free of charge, to any person obtaining a copy
9
10
  * of this software and associated documentation files (the "Software"), to deal
@@ -59,6 +60,9 @@ import * as micropdf417 from './micropdf417/index.js';
59
60
  import * as microqr from './microqr/index.js';
60
61
  import * as rmqr from './rmqr/index.js';
61
62
  import * as frameqr from './frameqr/index.js';
63
+ import * as aztecRune from './aztecrune/index.js';
64
+ import * as compactPdf417 from './compactpdf417/index.js';
65
+ import * as databar from './databar/index.js';
62
66
 
63
67
  export { BitMatrix };
64
68
  export {
@@ -77,7 +81,12 @@ export {
77
81
  encodeDataMatrix, decodeDataMatrix, detectDataMatrix, detectAndDecodeDataMatrix,
78
82
  } from './datamatrix/index.js';
79
83
  export { encodeAztec, decodeAztec, detectAztec, detectAndDecodeAztec } from './aztec/index.js';
84
+ export * from './aztecrune/index.js';
80
85
  export { encodePDF417, decodePDF417, detectPDF417, detectAndDecodePDF417 } from './pdf417/index.js';
86
+ export * from './compactpdf417/index.js';
87
+ // DataBar exports include both the verified GTIN/data layer and the
88
+ // Omnidirectional/Truncated physical image path.
89
+ export * from './databar/index.js';
81
90
  export {
82
91
  encodeMicroPDF417, decodeMicroPDF417, detectMicroPDF417, detectAndDecodeMicroPDF417,
83
92
  } from './micropdf417/index.js';
@@ -94,6 +103,7 @@ export {
94
103
  * @property {boolean} canWrite
95
104
  * @property {boolean} canRead
96
105
  * @property {'1D' | '2D'} kind
106
+ * @property {'supplement'} [role]
97
107
  */
98
108
 
99
109
  // Writing and reading a format are separate capabilities that can land at
@@ -127,6 +137,12 @@ const rmqrCanEncode = typeof rmqr.encodeRMQR === 'function';
127
137
  const rmqrCanDecode = typeof rmqr.detectAndDecodeRMQR === 'function';
128
138
  const frameQrCanEncode = typeof frameqr.encodeFrameQR === 'function';
129
139
  const frameQrCanDecode = typeof frameqr.detectAndDecodeFrameQR === 'function';
140
+ const aztecRuneCanEncode = typeof aztecRune.encodeAztecRune === 'function';
141
+ const aztecRuneCanDecode = typeof aztecRune.detectAndDecodeAztecRune === 'function';
142
+ const compactPdf417CanEncode = typeof compactPdf417.encodeCompactPDF417 === 'function';
143
+ const compactPdf417CanDecode = typeof compactPdf417.detectAndDecodeCompactPDF417 === 'function';
144
+ const dataBarCanEncode = typeof databar.encodeDataBar14 === 'function';
145
+ const dataBarCanDecode = typeof databar.decodeDataBar14Scanline === 'function';
130
146
 
131
147
  /**
132
148
  * Every format this build supports.
@@ -145,6 +161,7 @@ export function listFormats() {
145
161
  canWrite: true,
146
162
  canRead: info.readable,
147
163
  kind: /** @type {'1D'} */ ('1D'),
164
+ ...(info.role ? { role: info.role } : {}),
148
165
  }));
149
166
 
150
167
  formats.push({
@@ -168,6 +185,13 @@ export function listFormats() {
168
185
  canRead: aztecCanDecode,
169
186
  kind: /** @type {'2D'} */ ('2D'),
170
187
  });
188
+ formats.push({
189
+ id: 'aztecrune',
190
+ label: 'Aztec Rune',
191
+ canWrite: aztecRuneCanEncode,
192
+ canRead: aztecRuneCanDecode,
193
+ kind: /** @type {'2D'} */ ('2D'),
194
+ });
171
195
  formats.push({
172
196
  id: 'pdf417',
173
197
  label: 'PDF417',
@@ -175,6 +199,13 @@ export function listFormats() {
175
199
  canRead: pdf417CanDecode,
176
200
  kind: /** @type {'2D'} */ ('2D'),
177
201
  });
202
+ formats.push({
203
+ id: 'compactpdf417',
204
+ label: 'Compact PDF417',
205
+ canWrite: compactPdf417CanEncode,
206
+ canRead: compactPdf417CanDecode,
207
+ kind: /** @type {'2D'} */ ('2D'),
208
+ });
178
209
  formats.push({
179
210
  id: 'micropdf417',
180
211
  label: 'MicroPDF417',
@@ -198,11 +229,18 @@ export function listFormats() {
198
229
  });
199
230
  formats.push({
200
231
  id: 'frameqr',
201
- label: 'Sythos Canvas QR profile',
232
+ label: 'FrameQR Code',
202
233
  canWrite: frameQrCanEncode,
203
234
  canRead: frameQrCanDecode,
204
235
  kind: /** @type {'2D'} */ ('2D'),
205
236
  });
237
+ formats.push({
238
+ id: 'gs1databar14',
239
+ label: 'GS1 DataBar Omnidirectional / Truncated',
240
+ canWrite: dataBarCanEncode,
241
+ canRead: dataBarCanDecode,
242
+ kind: /** @type {'1D'} */ ('1D'),
243
+ });
206
244
 
207
245
  return formats;
208
246
  }
@@ -233,7 +271,7 @@ export function listFormats() {
233
271
  * @param {'auto'|'text'|'byte'|'numeric'} [options.compaction] PDF417 compaction mode.
234
272
  * @param {number} [options.eci] MicroPDF417 byte-compaction ECI assignment (3 or 26).
235
273
  * @param {number} [options.aspectRatio] Preferred MicroPDF417 symbol aspect ratio.
236
- * @param {object} [options.canvas] Sythos Canvas QR artwork reservation.
274
+ * @param {object} [options.canvas] FrameQR Code artwork reservation.
237
275
  * @param {'square'|'circle'|'diamond'} [options.canvas.shape] Canvas shape.
238
276
  * @param {number} [options.canvas.size] Odd canvas size in QR modules.
239
277
  * @param {number} [options.canvas.width] Canvas width in QR modules.
@@ -256,9 +294,15 @@ export function encode(text, options = {}) {
256
294
  if (format === 'aztec' || format === 'aztec-code') {
257
295
  return aztec.encodeAztec(value, options);
258
296
  }
297
+ if (format === 'aztecrune' || format === 'aztec-rune' || format === 'rune') {
298
+ return aztecRune.encodeAztecRune(value, options);
299
+ }
259
300
  if (format === 'pdf417' || format === 'pdf-417') {
260
301
  return pdf417.encodePDF417(value, options);
261
302
  }
303
+ if (format === 'compactpdf417' || format === 'compact-pdf417' || format === 'compact-pdf-417') {
304
+ return compactPdf417.encodeCompactPDF417(value, options);
305
+ }
262
306
  if (format === 'micropdf417' || format === 'micro-pdf417' || format === 'micro-pdf-417') {
263
307
  return micropdf417.encodeMicroPDF417(value, options);
264
308
  }
@@ -271,10 +315,13 @@ export function encode(text, options = {}) {
271
315
  if (format === 'frameqr' || format === 'frame-qr' || format === 'canvas-qr') {
272
316
  return frameqr.encodeFrameQR(value, options);
273
317
  }
318
+ if (format === 'gs1databar14' || format === 'gs1-databar14' || format === 'databar') {
319
+ return databar.encodeDataBar14(value, options);
320
+ }
274
321
 
275
322
  const entry = ONED_FORMATS[format];
276
323
  if (!entry) {
277
- const known = [...Object.keys(ONED_FORMATS), 'qr', 'datamatrix', 'aztec', 'pdf417', 'micropdf417', 'microqr', 'rmqr', 'frameqr'].join(', ');
324
+ const known = [...Object.keys(ONED_FORMATS), 'qr', 'datamatrix', 'aztec', 'aztecrune', 'pdf417', 'compactpdf417', 'micropdf417', 'microqr', 'rmqr', 'frameqr', 'gs1databar14'].join(', ');
278
325
  throw new EncodeError(`Unknown format "${format}". Known formats: ${known}`);
279
326
  }
280
327
  return entry.encode(value, options);
@@ -297,9 +344,16 @@ export function encode(text, options = {}) {
297
344
  * @property {number} [rowHeight] PDF417 row height in modules.
298
345
  * @property {number} [variant] MicroPDF417 predefined variant number.
299
346
  * @property {number} [eccCodewords] MicroPDF417 fixed error-correction codewords.
300
- * @property {string} [profile] Sythos Canvas QR profile identifier.
347
+ * @property {string} [profile] FrameQR Code profile identifier.
301
348
  * @property {boolean} [certified] Whether the profile is certified by its originator.
302
- * @property {object} [canvas] Canvas reservation metadata for the Sythos profile.
349
+ * @property {object} [canvas] Canvas reservation metadata for the FrameQR Code profile.
350
+ * @property {{format:'ean2'|'ean5', text:string, parity:string, checksum?:number}} [addon] Attached EAN/UPC supplement.
351
+ * @property {boolean} [gs1] Whether the physical symbol is classified as GS1.
352
+ * @property {string} [symbologyIdentifier] GS1 symbology identifier.
353
+ * @property {Array<{ai:string,value:string,fixed?:boolean}>} [elements] Parsed GS1 Application Identifier fields.
354
+ * @property {string} [gs1ParseError] Semantic GS1 parsing error after a valid physical read.
355
+ * @property {string} [gtin] GS1 DataBar GTIN-14 payload.
356
+ * @property {boolean} [linkage] GS1 DataBar linkage flag.
303
357
  */
304
358
 
305
359
  /**
@@ -314,7 +368,7 @@ export function encode(text, options = {}) {
314
368
  * @param {string[]} [options.formats] Restrict to these format ids.
315
369
  * @param {boolean} [options.tryHarder] Retry inverted and rotated. Default true.
316
370
  * @param {'global'|'hybrid'|'auto'} [options.binarizer]
317
- * @param {object} [options.frameqr] Sythos Canvas QR detector options when
371
+ * @param {object} [options.frameqr] FrameQR Code detector options when
318
372
  * the profile marker is not preserved through image rendering.
319
373
  * @returns {DecodeResult[]}
320
374
  */
@@ -324,12 +378,15 @@ export function decode(image, options = {}) {
324
378
  const wantQR = !want || want.has('qr') || want.has('qrcode');
325
379
  const wantDataMatrix = !want || want.has('datamatrix') || want.has('data-matrix');
326
380
  const wantAztec = !want || want.has('aztec') || want.has('aztec-code');
381
+ const wantAztecRune = !want || want.has('aztecrune') || want.has('aztec-rune') || want.has('rune');
327
382
  const wantPDF417 = !want || want.has('pdf417') || want.has('pdf-417');
383
+ const wantCompactPDF417 = !want || want.has('compactpdf417') || want.has('compact-pdf417') || want.has('compact-pdf-417');
328
384
  const wantMicroPDF417 = !want || want.has('micropdf417') || want.has('micro-pdf417') || want.has('micro-pdf-417');
329
385
  const wantMicroQR = !want || want.has('microqr') || want.has('micro-qr');
330
386
  const wantRMQR = !want || want.has('rmqr') || want.has('r-mqr') || want.has('rectangular-micro-qr');
331
387
  const wantFrameQR = !want || want.has('frameqr') || want.has('frame-qr') || want.has('canvas-qr');
332
- const wantOneD = !want || [...want].some((f) => f in ONED_FORMATS);
388
+ const oneDAliases = new Set(['gs1databar14', 'databar', 'gs1-databar14']);
389
+ const wantOneD = !want || [...want].some((f) => f in ONED_FORMATS || oneDAliases.has(f));
333
390
 
334
391
  const source = LuminanceSource.fromImageData(image);
335
392
  const results = [];
@@ -381,6 +438,15 @@ export function decode(image, options = {}) {
381
438
  }
382
439
  }
383
440
 
441
+ if (wantAztecRune && aztecRuneCanDecode) {
442
+ try {
443
+ const found = aztecRune.detectAndDecodeAztecRune(bits);
444
+ if (found) results.push({ ...found, format: 'aztecrune' });
445
+ } catch {
446
+ /* no Aztec Rune in this pass */
447
+ }
448
+ }
449
+
384
450
  if (wantPDF417 && pdf417CanDecode) {
385
451
  try {
386
452
  const found = pdf417.detectAndDecodePDF417(bits);
@@ -390,6 +456,15 @@ export function decode(image, options = {}) {
390
456
  }
391
457
  }
392
458
 
459
+ if (wantCompactPDF417 && compactPdf417CanDecode) {
460
+ try {
461
+ const found = compactPdf417.detectAndDecodeCompactPDF417(bits);
462
+ if (found) results.push({ ...found, format: 'compactpdf417' });
463
+ } catch {
464
+ /* no Compact PDF417 in this pass */
465
+ }
466
+ }
467
+
393
468
  if (wantMicroPDF417 && microPdf417CanDecode) {
394
469
  // MicroPDF417 detection measures runs across the whole raster. Hybrid
395
470
  // thresholding can alter uniform modules near local-window boundaries,
@@ -430,14 +505,28 @@ export function decode(image, options = {}) {
430
505
  results.push({ ...found, format: 'frameqr' });
431
506
  }
432
507
  } catch {
433
- /* no Sythos Canvas QR profile in this pass */
508
+ /* no FrameQR Code in this pass */
434
509
  }
435
510
  }
436
511
 
437
512
  if (wantOneD) {
438
- const oneDFormats = want ? [...want].filter((f) => f in ONED_FORMATS) : null;
439
- for (const found of decodeOneD(bits, { formats: oneDFormats, tryHarder })) {
440
- results.push({ text: found.text, format: found.format });
513
+ const oneDFormats = want
514
+ ? [...want].filter((f) => f in ONED_FORMATS || oneDAliases.has(f))
515
+ : null;
516
+ for (const found of decodeOneD(bits, { ...options, formats: oneDFormats, tryHarder })) {
517
+ const { row, ...publicFound } = found;
518
+ void row;
519
+ if (publicFound.gs1) {
520
+ const semanticText = publicFound.format === 'gs1databar14'
521
+ ? `01${publicFound.gtin ?? publicFound.text}`
522
+ : publicFound.text;
523
+ try {
524
+ publicFound.elements = databar.decodeGS1ElementString(semanticText);
525
+ } catch (error) {
526
+ publicFound.gs1ParseError = error instanceof Error ? error.message : String(error);
527
+ }
528
+ }
529
+ results.push(publicFound);
441
530
  }
442
531
  }
443
532
 
@@ -468,4 +557,4 @@ export function decodeStrict(image, options) {
468
557
  }
469
558
 
470
559
  /** Library version, matching package.json. */
471
- export const VERSION = '1.3.1';
560
+ export const VERSION = '1.4.1';
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.
@@ -23,6 +23,7 @@
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
25
  *
26
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
26
27
  * SPDX-License-Identifier: MIT
27
28
  *
28
29
  * Original work. No code from any other barcode implementation.