@sythos/js_barcode_universal 1.5.8 → 1.5.10

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 +61 -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,219 +27,214 @@
27
27
  *
28
28
  * Original work. No code from any other barcode implementation.
29
29
  */
30
-
31
30
  /**
32
31
  * Micro QR decoder for an already sampled M1-M4 module matrix.
33
32
  *
34
33
  * @module microqr/decoder
35
34
  */
36
-
37
35
  import { ChecksumError, FormatError } from '../core/errors.js';
38
36
  import { GF256_QR } from '../core/galois-field.js';
39
37
  import { rsDecode } from '../core/reed-solomon.js';
40
- import {
41
- microQrBlockLayout,
42
- microQrDataModuleOrder,
43
- microQrDecodeFormatInfo,
44
- microQrFormatInfoPositions,
45
- microQrMaskBit,
46
- } from './tables.js';
47
-
38
+ import { microQrBlockLayout, microQrDataModuleOrder, microQrDecodeFormatInfo, microQrFormatInfoPositions, microQrMaskBit, } from './tables.js';
48
39
  const ALPHANUMERIC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:';
49
40
  const MODE_NAMES = ['numeric', 'alphanumeric', 'byte', 'kanji'];
50
41
  const COUNT_BITS = {
51
- numeric: [0, 3, 4, 5, 6],
52
- alphanumeric: [0, 0, 3, 4, 5],
53
- byte: [0, 0, 0, 4, 5],
54
- kanji: [0, 0, 0, 3, 4],
42
+ numeric: [0, 3, 4, 5, 6],
43
+ alphanumeric: [0, 0, 3, 4, 5],
44
+ byte: [0, 0, 0, 4, 5],
45
+ kanji: [0, 0, 0, 3, 4],
55
46
  };
56
-
57
47
  class LimitedBitReader {
58
- constructor(bytes, limit) {
59
- this.bytes = bytes;
60
- this.limit = limit;
61
- this.offset = 0;
62
- }
63
-
64
- available() { return this.limit - this.offset; }
65
-
66
- read(count) {
67
- if (!Number.isInteger(count) || count < 1 || count > 32 || count > this.available()) {
68
- throw new FormatError(`Micro QR: needed ${count} bits, ${Math.max(0, this.available())} remain`);
69
- }
70
- let value = 0;
71
- for (let i = 0; i < count; i++, this.offset++) {
72
- value = (value << 1) | ((this.bytes[this.offset >>> 3] >>> (7 - (this.offset & 7))) & 1);
73
- }
74
- return value >>> 0;
75
- }
48
+ constructor(bytes, limit) {
49
+ this.bytes = bytes;
50
+ this.limit = limit;
51
+ this.offset = 0;
52
+ }
53
+ available() { return this.limit - this.offset; }
54
+ read(count) {
55
+ if (!Number.isInteger(count) || count < 1 || count > 32 || count > this.available()) {
56
+ throw new FormatError(`Micro QR: needed ${count} bits, ${Math.max(0, this.available())} remain`);
57
+ }
58
+ let value = 0;
59
+ for (let i = 0; i < count; i++, this.offset++) {
60
+ value = (value << 1) | ((this.bytes[this.offset >>> 3] >>> (7 - (this.offset & 7))) & 1);
61
+ }
62
+ return value >>> 0;
63
+ }
76
64
  }
77
-
78
65
  function moduleAt(matrix, x, y, mirrored) {
79
- return mirrored ? matrix.get(y, x) : matrix.get(x, y);
66
+ return mirrored ? matrix.get(y, x) : matrix.get(x, y);
80
67
  }
81
-
82
68
  function readFormat(matrix, expectedVersion, mirrored) {
83
- let bits = 0;
84
- const positions = microQrFormatInfoPositions(matrix.width);
85
- for (let i = 0; i < positions.length; i++) {
86
- const [x, y] = positions[i];
87
- if (moduleAt(matrix, x, y, mirrored)) bits |= 1 << i;
88
- }
89
- const format = microQrDecodeFormatInfo(bits);
90
- if (!format) throw new FormatError('Micro QR: format information is unreadable');
91
- if (format.version !== expectedVersion) {
92
- throw new FormatError(
93
- `Micro QR: format identifies ${format.version}, but the matrix dimension identifies ${expectedVersion}`,
94
- );
95
- }
96
- return format;
69
+ let bits = 0;
70
+ const positions = microQrFormatInfoPositions(matrix.width);
71
+ for (let i = 0; i < positions.length; i++) {
72
+ const [x, y] = positions[i];
73
+ if (moduleAt(matrix, x, y, mirrored))
74
+ bits |= 1 << i;
75
+ }
76
+ const format = microQrDecodeFormatInfo(bits);
77
+ if (!format)
78
+ throw new FormatError('Micro QR: format information is unreadable');
79
+ if (format.version !== expectedVersion) {
80
+ throw new FormatError(`Micro QR: format identifies ${format.version}, but the matrix dimension identifies ${expectedVersion}`);
81
+ }
82
+ return format;
97
83
  }
98
-
99
84
  function readCodewords(matrix, layout, mask, mirrored) {
100
- const order = microQrDataModuleOrder(layout.version);
101
- const data = new Array(layout.dataCodewords).fill(0);
102
- const ecc = new Array(layout.eccCodewords).fill(0);
103
- let streamOffset = 0;
104
-
105
- const readBit = () => {
106
- const x = order[streamOffset * 2];
107
- const y = order[streamOffset * 2 + 1];
108
- if (x === undefined || y === undefined) throw new FormatError('Micro QR: encoding region is truncated');
109
- streamOffset++;
110
- return moduleAt(matrix, x, y, mirrored) !== microQrMaskBit(mask, x, y) ? 1 : 0;
111
- };
112
- const readInto = (target, index, count, highBit = 7) => {
113
- for (let bit = highBit; bit > highBit - count; bit--) target[index] |= readBit() << bit;
114
- };
115
-
116
- const fullData = layout.shortDataCodewordBits === 4 ? layout.dataCodewords - 1 : layout.dataCodewords;
117
- for (let i = 0; i < fullData; i++) readInto(data, i, 8);
118
- if (layout.shortDataCodewordBits === 4) readInto(data, data.length - 1, 4);
119
- for (let i = 0; i < ecc.length; i++) readInto(ecc, i, 8);
120
-
121
- if (streamOffset !== order.length / 2) {
122
- throw new FormatError(`Micro QR: read ${streamOffset} of ${order.length / 2} encoding modules`);
123
- }
124
- return data.concat(ecc);
85
+ const order = microQrDataModuleOrder(layout.version);
86
+ const data = new Array(layout.dataCodewords).fill(0);
87
+ const ecc = new Array(layout.eccCodewords).fill(0);
88
+ let streamOffset = 0;
89
+ const readBit = () => {
90
+ const x = order[streamOffset * 2];
91
+ const y = order[streamOffset * 2 + 1];
92
+ if (x === undefined || y === undefined)
93
+ throw new FormatError('Micro QR: encoding region is truncated');
94
+ streamOffset++;
95
+ return moduleAt(matrix, x, y, mirrored) !== microQrMaskBit(mask, x, y) ? 1 : 0;
96
+ };
97
+ const readInto = (target, index, count, highBit = 7) => {
98
+ for (let bit = highBit; bit > highBit - count; bit--)
99
+ target[index] |= readBit() << bit;
100
+ };
101
+ const fullData = layout.shortDataCodewordBits === 4 ? layout.dataCodewords - 1 : layout.dataCodewords;
102
+ for (let i = 0; i < fullData; i++)
103
+ readInto(data, i, 8);
104
+ if (layout.shortDataCodewordBits === 4)
105
+ readInto(data, data.length - 1, 4);
106
+ for (let i = 0; i < ecc.length; i++)
107
+ readInto(ecc, i, 8);
108
+ if (streamOffset !== order.length / 2) {
109
+ throw new FormatError(`Micro QR: read ${streamOffset} of ${order.length / 2} encoding modules`);
110
+ }
111
+ return data.concat(ecc);
125
112
  }
126
-
127
113
  function correctCodewords(received, layout) {
128
- const corrections = rsDecode(received, layout.eccCodewords, GF256_QR, 0);
129
- if (layout.version === 'M1' && corrections !== 0) {
130
- throw new ChecksumError('Micro QR: M1 provides error detection only');
131
- }
132
- return { data: Uint8Array.from(received.slice(0, layout.dataCodewords)), corrections };
114
+ const corrections = rsDecode(received, layout.eccCodewords, GF256_QR, 0);
115
+ if (layout.version === 'M1' && corrections !== 0) {
116
+ throw new ChecksumError('Micro QR: M1 provides error detection only');
117
+ }
118
+ return { data: Uint8Array.from(received.slice(0, layout.dataCodewords)), corrections };
133
119
  }
134
-
135
120
  function decodeKanjiValue(value) {
136
- const combined = (Math.floor(value / 0xc0) << 8) | (value % 0xc0);
137
- const sjis = combined + (combined < 0x1f00 ? 0x8140 : 0xc140);
138
- const bytes = Uint8Array.of(sjis >>> 8, sjis & 0xff);
139
- try {
140
- return new TextDecoder('shift_jis', { fatal: true }).decode(bytes);
141
- } catch {
142
- throw new FormatError(`Micro QR: invalid Kanji value ${value}`);
143
- }
121
+ const combined = (Math.floor(value / 0xc0) << 8) | (value % 0xc0);
122
+ const sjis = combined + (combined < 0x1f00 ? 0x8140 : 0xc140);
123
+ const bytes = Uint8Array.of(sjis >>> 8, sjis & 0xff);
124
+ try {
125
+ return new TextDecoder('shift_jis', { fatal: true }).decode(bytes);
126
+ }
127
+ catch {
128
+ throw new FormatError(`Micro QR: invalid Kanji value ${value}`);
129
+ }
144
130
  }
145
-
146
131
  function parsePayload(data, version, dataBits) {
147
- const reader = new LimitedBitReader(data, dataBits);
148
- const modeValue = version === 1 ? 0 : reader.read(version - 1);
149
- if (modeValue > 3 || (version === 2 && modeValue > 1)) {
150
- throw new FormatError(`Micro QR: mode indicator ${modeValue} is unavailable in M${version}`);
151
- }
152
- const mode = MODE_NAMES[modeValue];
153
- const countWidth = COUNT_BITS[mode][version];
154
- if (!countWidth) throw new FormatError(`Micro QR: ${mode} mode is unavailable in M${version}`);
155
- const count = reader.read(countWidth);
156
- if (count === 0) throw new FormatError('Micro QR: zero-length data segment');
157
-
158
- let text = '';
159
- const rawBytes = [];
160
- if (mode === 'numeric') {
161
- let remaining = count;
162
- while (remaining >= 3) {
163
- const value = reader.read(10);
164
- if (value >= 1000) throw new FormatError(`Micro QR: invalid numeric triplet ${value}`);
165
- text += String(value).padStart(3, '0');
166
- remaining -= 3;
167
- }
168
- if (remaining === 2) {
169
- const value = reader.read(7);
170
- if (value >= 100) throw new FormatError(`Micro QR: invalid numeric pair ${value}`);
171
- text += String(value).padStart(2, '0');
172
- } else if (remaining === 1) {
173
- const value = reader.read(4);
174
- if (value >= 10) throw new FormatError(`Micro QR: invalid numeric digit ${value}`);
175
- text += String(value);
176
- }
177
- } else if (mode === 'alphanumeric') {
178
- let remaining = count;
179
- while (remaining >= 2) {
180
- const value = reader.read(11);
181
- if (value >= 45 * 45) throw new FormatError(`Micro QR: invalid alphanumeric pair ${value}`);
182
- text += ALPHANUMERIC[Math.floor(value / 45)] + ALPHANUMERIC[value % 45];
183
- remaining -= 2;
184
- }
185
- if (remaining === 1) {
186
- const value = reader.read(6);
187
- if (value >= 45) throw new FormatError(`Micro QR: invalid alphanumeric value ${value}`);
188
- text += ALPHANUMERIC[value];
189
- }
190
- } else if (mode === 'byte') {
191
- for (let i = 0; i < count; i++) {
192
- const value = reader.read(8);
193
- rawBytes.push(value);
194
- text += String.fromCharCode(value);
195
- }
196
- } else {
197
- for (let i = 0; i < count; i++) text += decodeKanjiValue(reader.read(13));
198
- }
199
- return { text, bytes: Uint8Array.from(rawBytes), mode };
132
+ const reader = new LimitedBitReader(data, dataBits);
133
+ const modeValue = version === 1 ? 0 : reader.read(version - 1);
134
+ if (modeValue > 3 || (version === 2 && modeValue > 1)) {
135
+ throw new FormatError(`Micro QR: mode indicator ${modeValue} is unavailable in M${version}`);
136
+ }
137
+ const mode = MODE_NAMES[modeValue];
138
+ const countWidth = COUNT_BITS[mode][version];
139
+ if (!countWidth)
140
+ throw new FormatError(`Micro QR: ${mode} mode is unavailable in M${version}`);
141
+ const count = reader.read(countWidth);
142
+ if (count === 0)
143
+ throw new FormatError('Micro QR: zero-length data segment');
144
+ let text = '';
145
+ const rawBytes = [];
146
+ if (mode === 'numeric') {
147
+ let remaining = count;
148
+ while (remaining >= 3) {
149
+ const value = reader.read(10);
150
+ if (value >= 1000)
151
+ throw new FormatError(`Micro QR: invalid numeric triplet ${value}`);
152
+ text += String(value).padStart(3, '0');
153
+ remaining -= 3;
154
+ }
155
+ if (remaining === 2) {
156
+ const value = reader.read(7);
157
+ if (value >= 100)
158
+ throw new FormatError(`Micro QR: invalid numeric pair ${value}`);
159
+ text += String(value).padStart(2, '0');
160
+ }
161
+ else if (remaining === 1) {
162
+ const value = reader.read(4);
163
+ if (value >= 10)
164
+ throw new FormatError(`Micro QR: invalid numeric digit ${value}`);
165
+ text += String(value);
166
+ }
167
+ }
168
+ else if (mode === 'alphanumeric') {
169
+ let remaining = count;
170
+ while (remaining >= 2) {
171
+ const value = reader.read(11);
172
+ if (value >= 45 * 45)
173
+ throw new FormatError(`Micro QR: invalid alphanumeric pair ${value}`);
174
+ text += ALPHANUMERIC[Math.floor(value / 45)] + ALPHANUMERIC[value % 45];
175
+ remaining -= 2;
176
+ }
177
+ if (remaining === 1) {
178
+ const value = reader.read(6);
179
+ if (value >= 45)
180
+ throw new FormatError(`Micro QR: invalid alphanumeric value ${value}`);
181
+ text += ALPHANUMERIC[value];
182
+ }
183
+ }
184
+ else if (mode === 'byte') {
185
+ for (let i = 0; i < count; i++) {
186
+ const value = reader.read(8);
187
+ rawBytes.push(value);
188
+ text += String.fromCharCode(value);
189
+ }
190
+ }
191
+ else {
192
+ for (let i = 0; i < count; i++)
193
+ text += decodeKanjiValue(reader.read(13));
194
+ }
195
+ return { text, bytes: Uint8Array.from(rawBytes), mode };
200
196
  }
201
-
202
197
  function decodeOrientation(matrix, expectedVersion, mirrored) {
203
- const format = readFormat(matrix, expectedVersion, mirrored);
204
- const layout = microQrBlockLayout(format.version, format.ecc);
205
- const received = readCodewords(matrix, layout, format.mask, mirrored);
206
- const { data, corrections } = correctCodewords(received, layout);
207
- const payload = parsePayload(data, Number(format.version.slice(1)), layout.dataBits);
208
- return {
209
- text: payload.text,
210
- bytes: payload.bytes,
211
- mode: payload.mode,
212
- version: format.version,
213
- ecc: format.ecc,
214
- mask: format.mask,
215
- corrections,
216
- formatCorrections: format.correctedBits,
217
- mirrored,
218
- };
198
+ const format = readFormat(matrix, expectedVersion, mirrored);
199
+ const layout = microQrBlockLayout(format.version, format.ecc);
200
+ const received = readCodewords(matrix, layout, format.mask, mirrored);
201
+ const { data, corrections } = correctCodewords(received, layout);
202
+ const payload = parsePayload(data, Number(format.version.slice(1)), layout.dataBits);
203
+ return {
204
+ text: payload.text,
205
+ bytes: payload.bytes,
206
+ mode: payload.mode,
207
+ version: format.version,
208
+ ecc: format.ecc,
209
+ mask: format.mask,
210
+ corrections,
211
+ formatCorrections: format.correctedBits,
212
+ mirrored,
213
+ };
219
214
  }
220
-
221
215
  /** Decode a sampled Micro QR Code symbol without its quiet zone. */
222
216
  export function decodeMicroQR(matrix) {
223
- if (!matrix || !Number.isInteger(matrix.width) || typeof matrix.get !== 'function') {
224
- throw new FormatError('Micro QR: no matrix supplied');
225
- }
226
- if (matrix.height !== matrix.width) {
227
- throw new FormatError(`Micro QR: symbol must be square, got ${matrix.width}x${matrix.height}`);
228
- }
229
- const version = (matrix.width - 9) / 2;
230
- if (!Number.isInteger(version) || version < 1 || version > 4) {
231
- throw new FormatError(`Micro QR: ${matrix.width} modules is not a valid M1-M4 symbol size`);
232
- }
233
- const expectedVersion = `M${version}`;
234
- try {
235
- return decodeOrientation(matrix, expectedVersion, false);
236
- } catch (primaryError) {
217
+ if (!matrix || !Number.isInteger(matrix.width) || typeof matrix.get !== 'function') {
218
+ throw new FormatError('Micro QR: no matrix supplied');
219
+ }
220
+ if (matrix.height !== matrix.width) {
221
+ throw new FormatError(`Micro QR: symbol must be square, got ${matrix.width}x${matrix.height}`);
222
+ }
223
+ const version = (matrix.width - 9) / 2;
224
+ if (!Number.isInteger(version) || version < 1 || version > 4) {
225
+ throw new FormatError(`Micro QR: ${matrix.width} modules is not a valid M1-M4 symbol size`);
226
+ }
227
+ const expectedVersion = `M${version}`;
237
228
  try {
238
- return decodeOrientation(matrix, expectedVersion, true);
239
- } catch {
240
- throw primaryError;
229
+ return decodeOrientation(matrix, expectedVersion, false);
230
+ }
231
+ catch (primaryError) {
232
+ try {
233
+ return decodeOrientation(matrix, expectedVersion, true);
234
+ }
235
+ catch {
236
+ throw primaryError;
237
+ }
241
238
  }
242
- }
243
239
  }
244
-
245
240
  export { ChecksumError, FormatError };