@sythos/js_barcode_universal 1.5.8 → 1.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/LICENSE +5 -4
  2. package/NOTICE.md +2 -2
  3. package/README.md +17 -13
  4. package/bundle/sythos-barcode.esm.js +11658 -11244
  5. package/bundle/sythos-barcode.js +11658 -11244
  6. package/package.json +10 -3
  7. package/src/index.d.ts +1 -1
  8. package/src/index.js +508 -516
  9. package/src/js/aztec/decoder.js +208 -199
  10. package/src/js/aztec/detector.js +153 -126
  11. package/src/js/aztec/encoder.js +172 -153
  12. package/src/js/aztec/high-level.js +106 -101
  13. package/src/js/aztec/index.js +1 -12
  14. package/src/js/aztec/tables.js +106 -120
  15. package/src/js/aztecrune/decoder.js +76 -85
  16. package/src/js/aztecrune/detector.js +107 -93
  17. package/src/js/aztecrune/encoder.js +50 -68
  18. package/src/js/aztecrune/index.js +1 -16
  19. package/src/js/aztecrune/tables.js +59 -54
  20. package/src/js/compactpdf417/decoder.js +69 -74
  21. package/src/js/compactpdf417/detector.js +74 -75
  22. package/src/js/compactpdf417/encoder.js +68 -81
  23. package/src/js/compactpdf417/index.js +1 -13
  24. package/src/js/compactpdf417/tables.js +71 -80
  25. package/src/js/core/bit-buffer.js +106 -122
  26. package/src/js/core/bit-matrix.js +196 -194
  27. package/src/js/core/errors.js +13 -15
  28. package/src/js/core/galois-field.js +119 -133
  29. package/src/js/core/index.js +2 -19
  30. package/src/js/core/reed-solomon.js +195 -204
  31. package/src/js/databar/codec.js +93 -108
  32. package/src/js/databar/decoder.js +149 -140
  33. package/src/js/databar/encoder.js +47 -55
  34. package/src/js/databar/gs1.js +122 -123
  35. package/src/js/databar/index.js +4 -36
  36. package/src/js/databar/patterns.js +81 -85
  37. package/src/js/databar/tables.js +51 -52
  38. package/src/js/datamatrix/decoder.js +216 -182
  39. package/src/js/datamatrix/detector.js +161 -132
  40. package/src/js/datamatrix/encoder.js +192 -133
  41. package/src/js/datamatrix/index.js +1 -9
  42. package/src/js/datamatrix/tables.js +68 -69
  43. package/src/js/frameqr/decoder.js +102 -125
  44. package/src/js/frameqr/detector.js +101 -94
  45. package/src/js/frameqr/encoder.js +67 -80
  46. package/src/js/frameqr/index.js +1 -10
  47. package/src/js/frameqr/tables.js +145 -163
  48. package/src/js/image/binarizer.js +146 -162
  49. package/src/js/image/grid-sampler.js +63 -79
  50. package/src/js/image/index.js +0 -2
  51. package/src/js/image/luminance.js +129 -140
  52. package/src/js/image/perspective.js +112 -149
  53. package/src/js/micropdf417/compaction.js +64 -65
  54. package/src/js/micropdf417/decoder.js +106 -109
  55. package/src/js/micropdf417/detector.js +73 -70
  56. package/src/js/micropdf417/encoder.js +129 -154
  57. package/src/js/micropdf417/error-correction.js +6 -11
  58. package/src/js/micropdf417/index.js +2 -16
  59. package/src/js/micropdf417/tables.js +112 -99
  60. package/src/js/microqr/decoder.js +177 -182
  61. package/src/js/microqr/detector.js +240 -256
  62. package/src/js/microqr/encoder.js +239 -194
  63. package/src/js/microqr/index.js +0 -2
  64. package/src/js/microqr/tables.js +208 -200
  65. package/src/js/oned/addons.js +167 -191
  66. package/src/js/oned/index.js +27 -58
  67. package/src/js/oned/patterns.js +194 -213
  68. package/src/js/oned/reader.js +1003 -984
  69. package/src/js/oned/writers.js +411 -466
  70. package/src/js/pdf417/compaction.js +315 -222
  71. package/src/js/pdf417/decoder.js +71 -36
  72. package/src/js/pdf417/detector.js +377 -361
  73. package/src/js/pdf417/encoder.js +57 -46
  74. package/src/js/pdf417/error-correction.js +5 -8
  75. package/src/js/pdf417/tables.js +248 -250
  76. package/src/js/qr/decoder.js +311 -347
  77. package/src/js/qr/detector.js +378 -395
  78. package/src/js/qr/encoder.js +514 -599
  79. package/src/js/qr/index.js +0 -2
  80. package/src/js/qr/tables.js +375 -422
  81. package/src/js/render/image-data.js +57 -62
  82. package/src/js/render/index.js +21 -23
  83. package/src/js/render/options.js +82 -90
  84. package/src/js/render/png.js +144 -169
  85. package/src/js/render/svg.js +41 -44
  86. package/src/js/render/webgl.js +103 -109
  87. package/src/js/render/webgpu.js +205 -217
  88. package/src/js/rmqr/decoder.js +161 -53
  89. package/src/js/rmqr/detector.js +73 -41
  90. package/src/js/rmqr/encoder.js +253 -104
  91. package/src/js/rmqr/index.js +1 -5
  92. package/src/js/rmqr/tables.js +108 -85
  93. package/src/ts/aztec/decoder.ts +317 -0
  94. package/src/ts/aztec/detector.ts +224 -0
  95. package/src/ts/aztec/encoder.ts +257 -0
  96. package/src/ts/aztec/high-level.ts +211 -0
  97. package/src/ts/aztec/index.ts +45 -0
  98. package/src/ts/aztec/tables.ts +210 -0
  99. package/src/ts/aztecrune/decoder.ts +155 -0
  100. package/src/ts/aztecrune/detector.ts +166 -0
  101. package/src/ts/aztecrune/encoder.ts +121 -0
  102. package/src/ts/aztecrune/index.ts +49 -0
  103. package/src/ts/aztecrune/tables.ts +137 -0
  104. package/src/ts/compactpdf417/decoder.ts +128 -0
  105. package/src/ts/compactpdf417/detector.ts +139 -0
  106. package/src/ts/compactpdf417/encoder.ts +140 -0
  107. package/src/ts/compactpdf417/index.ts +17 -0
  108. package/src/ts/compactpdf417/tables.ts +173 -0
  109. package/src/ts/core/bit-buffer.ts +174 -0
  110. package/src/ts/core/bit-matrix.ts +241 -0
  111. package/src/ts/core/errors.ts +61 -0
  112. package/src/ts/core/galois-field.ts +207 -0
  113. package/src/ts/core/index.ts +56 -0
  114. package/src/ts/core/reed-solomon.ts +327 -0
  115. package/src/ts/databar/codec.ts +181 -0
  116. package/src/ts/databar/decoder.ts +215 -0
  117. package/src/ts/databar/encoder.ts +96 -0
  118. package/src/ts/databar/gs1.ts +177 -0
  119. package/src/ts/databar/index.ts +68 -0
  120. package/src/ts/databar/patterns.ts +143 -0
  121. package/src/ts/databar/tables.ts +124 -0
  122. package/src/ts/datamatrix/decoder.ts +262 -0
  123. package/src/ts/datamatrix/detector.ts +225 -0
  124. package/src/ts/datamatrix/encoder.ts +191 -0
  125. package/src/ts/datamatrix/index.ts +42 -0
  126. package/src/ts/datamatrix/tables.ts +123 -0
  127. package/src/ts/frameqr/decoder.ts +239 -0
  128. package/src/ts/frameqr/detector.ts +192 -0
  129. package/src/ts/frameqr/encoder.ts +156 -0
  130. package/src/ts/frameqr/index.ts +42 -0
  131. package/src/ts/frameqr/tables.ts +270 -0
  132. package/src/ts/image/binarizer.ts +270 -0
  133. package/src/ts/image/grid-sampler.ts +164 -0
  134. package/src/ts/image/index.ts +40 -0
  135. package/src/ts/image/luminance.ts +196 -0
  136. package/src/ts/image/perspective.ts +195 -0
  137. package/src/ts/index.d.ts +1 -1
  138. package/src/ts/index.ts +790 -0
  139. package/src/ts/micropdf417/compaction.ts +116 -0
  140. package/src/ts/micropdf417/decoder.ts +183 -0
  141. package/src/ts/micropdf417/detector.ts +149 -0
  142. package/src/ts/micropdf417/encoder.ts +209 -0
  143. package/src/ts/micropdf417/error-correction.ts +55 -0
  144. package/src/ts/micropdf417/index.ts +49 -0
  145. package/src/ts/micropdf417/tables.ts +184 -0
  146. package/src/ts/microqr/decoder.ts +245 -0
  147. package/src/ts/microqr/detector.ts +355 -0
  148. package/src/ts/microqr/encoder.ts +269 -0
  149. package/src/ts/microqr/index.ts +36 -0
  150. package/src/ts/microqr/tables.ts +316 -0
  151. package/src/ts/oned/addons.ts +420 -0
  152. package/src/ts/oned/index.ts +106 -0
  153. package/src/ts/oned/patterns.ts +384 -0
  154. package/src/ts/oned/reader.ts +1364 -0
  155. package/src/ts/oned/writers.ts +746 -0
  156. package/src/ts/pdf417/compaction.ts +298 -0
  157. package/src/ts/pdf417/decoder.ts +75 -0
  158. package/src/ts/pdf417/detector.ts +468 -0
  159. package/src/ts/pdf417/encoder.ts +91 -0
  160. package/src/ts/pdf417/error-correction.ts +47 -0
  161. package/src/ts/pdf417/index.ts +6 -0
  162. package/src/ts/pdf417/tables.ts +317 -0
  163. package/src/ts/qr/decoder.ts +575 -0
  164. package/src/ts/qr/detector.ts +630 -0
  165. package/src/ts/qr/encoder.ts +958 -0
  166. package/src/ts/qr/index.ts +44 -0
  167. package/src/ts/qr/tables.ts +737 -0
  168. package/src/ts/render/image-data.ts +125 -0
  169. package/src/ts/render/index.ts +130 -0
  170. package/src/ts/render/options.ts +160 -0
  171. package/src/ts/render/png.ts +295 -0
  172. package/src/ts/render/svg.ts +120 -0
  173. package/src/ts/render/webgl.ts +206 -0
  174. package/src/ts/render/webgpu.ts +369 -0
  175. package/src/ts/rmqr/decoder.ts +101 -0
  176. package/src/ts/rmqr/detector.ts +90 -0
  177. package/src/ts/rmqr/encoder.ts +172 -0
  178. package/src/ts/rmqr/index.ts +37 -0
  179. package/src/ts/rmqr/tables.ts +154 -0
@@ -27,243 +27,288 @@
27
27
  *
28
28
  * Original work. No code from any other barcode implementation.
29
29
  */
30
-
31
30
  import { BitMatrix } from '../core/bit-matrix.js';
32
31
  import { BitWriter } from '../core/bit-buffer.js';
33
32
  import { EncodeError } from '../core/errors.js';
34
33
  import { GF256_QR } from '../core/galois-field.js';
35
34
  import { rsEncode } from '../core/reed-solomon.js';
36
- import {
37
- MICROQR_VERSIONS, microQrBlockLayout, microQrDataModuleOrder,
38
- microQrFormatInfo, microQrFormatInfoPositions, microQrMaskBit,
39
- microQrSymbolNumber, microQrVersionSize,
40
- } from './tables.js';
41
-
35
+ import { MICROQR_VERSIONS, microQrBlockLayout, microQrDataModuleOrder, microQrFormatInfo, microQrFormatInfoPositions, microQrMaskBit, microQrSymbolNumber, microQrVersionSize, } from './tables.js';
42
36
  export const MICROQR_ALPHANUMERIC = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:';
43
37
  const MODE = { numeric: 0, alphanumeric: 1, byte: 2, kanji: 3 };
44
38
  const MODE_MIN_VERSION = { numeric: 1, alphanumeric: 2, byte: 3, kanji: 3 };
45
39
  const COUNT_BITS = {
46
- numeric: [0, 3, 4, 5, 6], alphanumeric: [0, 0, 3, 4, 5],
47
- byte: [0, 0, 0, 4, 5], kanji: [0, 0, 0, 3, 4],
40
+ numeric: [0, 3, 4, 5, 6], alphanumeric: [0, 0, 3, 4, 5],
41
+ byte: [0, 0, 0, 4, 5], kanji: [0, 0, 0, 3, 4],
48
42
  };
49
-
50
43
  function parseVersion(value) {
51
- if (value == null) return null;
52
- const match = /^M?([1-4])$/i.exec(String(value));
53
- if (!match) throw new EncodeError(`Micro QR: version must be M1-M4, got ${value}`);
54
- return Number(match[1]);
44
+ if (value == null)
45
+ return null;
46
+ const match = /^M?([1-4])$/i.exec(String(value));
47
+ if (!match)
48
+ throw new EncodeError(`Micro QR: version must be M1-M4, got ${value}`);
49
+ return Number(match[1]);
55
50
  }
56
-
57
51
  function versionNumber(version) {
58
- return typeof version === 'number' ? version : Number(String(version).slice(1));
52
+ return typeof version === 'number' ? version : Number(String(version).slice(1));
59
53
  }
60
-
61
54
  function latin1Bytes(text) {
62
- const bytes = new Uint8Array(text.length);
63
- for (let i = 0; i < text.length; i++) {
64
- const cp = text.charCodeAt(i);
65
- if (cp > 0xff) throw new EncodeError('Micro QR: byte mode supports ISO-8859-1 only (ECI is unavailable)');
66
- bytes[i] = cp;
67
- }
68
- return bytes;
55
+ const bytes = new Uint8Array(text.length);
56
+ for (let i = 0; i < text.length; i++) {
57
+ const cp = text.charCodeAt(i);
58
+ if (cp > 0xff)
59
+ throw new EncodeError('Micro QR: byte mode supports ISO-8859-1 only (ECI is unavailable)');
60
+ bytes[i] = cp;
61
+ }
62
+ return bytes;
69
63
  }
70
-
71
64
  let sjisReverseMap;
72
-
73
65
  function sjisToThirteenBits(sjis) {
74
- const trail = sjis & 0xff;
75
- if (trail < 0x40 || trail === 0x7f || trail > 0xfc) return -1;
76
- let adjusted;
77
- if (sjis >= 0x8140 && sjis <= 0x9ffc) adjusted = sjis - 0x8140;
78
- else if (sjis >= 0xe040 && sjis <= 0xebbf) adjusted = sjis - 0xc140;
79
- else return -1;
80
- const packed = (adjusted >>> 8) * 0xc0 + (adjusted & 0xff);
81
- return packed <= 0x1fff ? packed : -1;
66
+ const trail = sjis & 0xff;
67
+ if (trail < 0x40 || trail === 0x7f || trail > 0xfc)
68
+ return -1;
69
+ let adjusted;
70
+ if (sjis >= 0x8140 && sjis <= 0x9ffc)
71
+ adjusted = sjis - 0x8140;
72
+ else if (sjis >= 0xe040 && sjis <= 0xebbf)
73
+ adjusted = sjis - 0xc140;
74
+ else
75
+ return -1;
76
+ const packed = (adjusted >>> 8) * 0xc0 + (adjusted & 0xff);
77
+ return packed <= 0x1fff ? packed : -1;
82
78
  }
83
-
84
79
  function getSjisReverseMap() {
85
- if (sjisReverseMap !== undefined) return sjisReverseMap;
86
- let decoder;
87
- try {
88
- decoder = new TextDecoder('shift_jis', { fatal: true });
89
- if (decoder.decode(new Uint8Array([0x82, 0xa0])) !== '') return (sjisReverseMap = null);
90
- } catch {
91
- return (sjisReverseMap = null);
92
- }
93
- const result = new Map();
94
- const bytes = new Uint8Array(2);
95
- for (const [start, end] of [[0x8140, 0x9ffc], [0xe040, 0xebbf]]) {
96
- for (let value = start; value <= end; value++) {
97
- if (sjisToThirteenBits(value) < 0) continue;
98
- bytes[0] = value >>> 8;
99
- bytes[1] = value & 0xff;
100
- let character;
101
- try { character = decoder.decode(bytes); } catch { continue; }
102
- if (Array.from(character).length === 1 && !result.has(character)) result.set(character, value);
80
+ if (sjisReverseMap !== undefined)
81
+ return sjisReverseMap;
82
+ let decoder;
83
+ try {
84
+ decoder = new TextDecoder('shift_jis', { fatal: true });
85
+ if (decoder.decode(new Uint8Array([0x82, 0xa0])) !== 'あ')
86
+ return (sjisReverseMap = null);
87
+ }
88
+ catch {
89
+ return (sjisReverseMap = null);
90
+ }
91
+ const result = new Map();
92
+ const bytes = new Uint8Array(2);
93
+ for (const [start, end] of [[0x8140, 0x9ffc], [0xe040, 0xebbf]]) {
94
+ for (let value = start; value <= end; value++) {
95
+ if (sjisToThirteenBits(value) < 0)
96
+ continue;
97
+ bytes[0] = value >>> 8;
98
+ bytes[1] = value & 0xff;
99
+ let character;
100
+ try {
101
+ character = decoder.decode(bytes);
102
+ }
103
+ catch {
104
+ continue;
105
+ }
106
+ if (Array.from(character).length === 1 && !result.has(character))
107
+ result.set(character, value);
108
+ }
103
109
  }
104
- }
105
- sjisReverseMap = result;
106
- return result;
110
+ sjisReverseMap = result;
111
+ return result;
107
112
  }
108
-
109
113
  function kanjiValues(text) {
110
- const reverse = getSjisReverseMap();
111
- if (!reverse) return null;
112
- const values = [];
113
- for (const character of text) {
114
- const sjis = reverse.get(character);
115
- if (sjis == null) return null;
116
- values.push(sjisToThirteenBits(sjis));
117
- }
118
- return values;
114
+ const reverse = getSjisReverseMap();
115
+ if (!reverse)
116
+ return null;
117
+ const values = [];
118
+ for (const character of text) {
119
+ const sjis = reverse.get(character);
120
+ if (sjis == null)
121
+ return null;
122
+ values.push(sjisToThirteenBits(sjis));
123
+ }
124
+ return values;
119
125
  }
120
-
121
126
  function chooseMode(text, forced) {
122
- const mode = forced == null ? (/^\d+$/.test(text) ? 'numeric' :
123
- [...text].every((ch) => MICROQR_ALPHANUMERIC.includes(ch)) ? 'alphanumeric' :
124
- kanjiValues(text) ? 'kanji' : 'byte') :
125
- String(forced).toLowerCase();
126
- if (!(mode in MODE)) throw new EncodeError(`Micro QR: unsupported mode "${forced}"`);
127
- if (mode === 'numeric' && !/^\d+$/.test(text)) throw new EncodeError('Micro QR: numeric mode accepts digits only');
128
- if (mode === 'alphanumeric' && ![...text].every((ch) => MICROQR_ALPHANUMERIC.includes(ch))) {
129
- throw new EncodeError('Micro QR: alphanumeric mode contains an unsupported character');
130
- }
131
- if (mode === 'kanji' && !kanjiValues(text)) {
132
- throw new EncodeError('Micro QR: kanji mode requires characters representable in the QR Shift_JIS ranges');
133
- }
134
- return mode;
127
+ const mode = forced == null ? (/^\d+$/.test(text) ? 'numeric' :
128
+ [...text].every((ch) => MICROQR_ALPHANUMERIC.includes(ch)) ? 'alphanumeric' :
129
+ kanjiValues(text) ? 'kanji' : 'byte') :
130
+ String(forced).toLowerCase();
131
+ if (!(mode in MODE))
132
+ throw new EncodeError(`Micro QR: unsupported mode "${forced}"`);
133
+ if (mode === 'numeric' && !/^\d+$/.test(text))
134
+ throw new EncodeError('Micro QR: numeric mode accepts digits only');
135
+ if (mode === 'alphanumeric' && ![...text].every((ch) => MICROQR_ALPHANUMERIC.includes(ch))) {
136
+ throw new EncodeError('Micro QR: alphanumeric mode contains an unsupported character');
137
+ }
138
+ if (mode === 'kanji' && !kanjiValues(text)) {
139
+ throw new EncodeError('Micro QR: kanji mode requires characters representable in the QR Shift_JIS ranges');
140
+ }
141
+ return mode;
135
142
  }
136
-
137
143
  function encodePayload(text, mode) {
138
- const w = new BitWriter();
139
- if (mode === 'numeric') {
140
- for (let i = 0; i < text.length; i += 3) {
141
- const n = Math.min(3, text.length - i);
142
- w.put(Number(text.slice(i, i + n)), n === 3 ? 10 : n === 2 ? 7 : 4);
144
+ const w = new BitWriter();
145
+ if (mode === 'numeric') {
146
+ for (let i = 0; i < text.length; i += 3) {
147
+ const n = Math.min(3, text.length - i);
148
+ w.put(Number(text.slice(i, i + n)), n === 3 ? 10 : n === 2 ? 7 : 4);
149
+ }
150
+ }
151
+ else if (mode === 'alphanumeric') {
152
+ let i = 0;
153
+ for (; i + 1 < text.length; i += 2) {
154
+ w.put(MICROQR_ALPHANUMERIC.indexOf(text[i]) * 45 + MICROQR_ALPHANUMERIC.indexOf(text[i + 1]), 11);
155
+ }
156
+ if (i < text.length)
157
+ w.put(MICROQR_ALPHANUMERIC.indexOf(text[i]), 6);
143
158
  }
144
- } else if (mode === 'alphanumeric') {
145
- let i = 0;
146
- for (; i + 1 < text.length; i += 2) {
147
- w.put(MICROQR_ALPHANUMERIC.indexOf(text[i]) * 45 + MICROQR_ALPHANUMERIC.indexOf(text[i + 1]), 11);
159
+ else if (mode === 'byte') {
160
+ w.putBytes(latin1Bytes(text));
148
161
  }
149
- if (i < text.length) w.put(MICROQR_ALPHANUMERIC.indexOf(text[i]), 6);
150
- } else if (mode === 'byte') {
151
- w.putBytes(latin1Bytes(text));
152
- } else {
153
- for (const value of kanjiValues(text)) w.put(value, 13);
154
- }
155
- return w;
162
+ else {
163
+ for (const value of kanjiValues(text))
164
+ w.put(value, 13);
165
+ }
166
+ return w;
156
167
  }
157
-
158
168
  function getBit(writer, index) {
159
- return ((writer.bytes[index >>> 3] >>> (7 - (index & 7))) & 1) === 1;
169
+ return ((writer.bytes[index >>> 3] >>> (7 - (index & 7))) & 1) === 1;
160
170
  }
161
-
162
171
  function writeData(text, mode, version, layout) {
163
- const numericVersion = versionNumber(version);
164
- const payload = encodePayload(text, mode);
165
- const writer = new BitWriter();
166
- if (numericVersion > 1) writer.put(MODE[mode], numericVersion - 1);
167
- const count = mode === 'byte' ? latin1Bytes(text).length : [...text].length;
168
- const countWidth = COUNT_BITS[mode][numericVersion];
169
- if (countWidth === 0 || count >= 2 ** countWidth) return null;
170
- writer.put(count, countWidth);
171
- for (let i = 0; i < payload.length; i++) writer.putBit(getBit(payload, i));
172
- if (writer.length > layout.dataBits) return null;
173
- for (let i = 0, n = Math.min(2 * numericVersion + 1, layout.dataBits - writer.length); i < n; i++) writer.putBit(false);
174
- if (numericVersion !== 1 && numericVersion !== 3) {
175
- while ((writer.length & 7) && writer.length < layout.dataBits) writer.putBit(false);
176
- }
177
- if (numericVersion === 1 || numericVersion === 3) {
178
- while (writer.length < layout.dataBits) writer.putBit(false);
172
+ const numericVersion = versionNumber(version);
173
+ const payload = encodePayload(text, mode);
174
+ const writer = new BitWriter();
175
+ if (numericVersion > 1)
176
+ writer.put(MODE[mode], numericVersion - 1);
177
+ const count = mode === 'byte' ? latin1Bytes(text).length : [...text].length;
178
+ const countWidth = COUNT_BITS[mode][numericVersion];
179
+ if (countWidth === 0 || count >= 2 ** countWidth)
180
+ return null;
181
+ writer.put(count, countWidth);
182
+ for (let i = 0; i < payload.length; i++)
183
+ writer.putBit(getBit(payload, i));
184
+ if (writer.length > layout.dataBits)
185
+ return null;
186
+ for (let i = 0, n = Math.min(2 * numericVersion + 1, layout.dataBits - writer.length); i < n; i++)
187
+ writer.putBit(false);
188
+ if (numericVersion !== 1 && numericVersion !== 3) {
189
+ while ((writer.length & 7) && writer.length < layout.dataBits)
190
+ writer.putBit(false);
191
+ }
192
+ if (numericVersion === 1 || numericVersion === 3) {
193
+ while (writer.length < layout.dataBits)
194
+ writer.putBit(false);
195
+ return writer;
196
+ }
197
+ let pad = 0;
198
+ while (writer.length + 8 <= layout.dataBits)
199
+ writer.put(pad++ & 1 ? 0x11 : 0xec, 8);
200
+ while (writer.length < layout.dataBits)
201
+ writer.putBit(false);
179
202
  return writer;
180
- }
181
- let pad = 0;
182
- while (writer.length + 8 <= layout.dataBits) writer.put(pad++ & 1 ? 0x11 : 0xec, 8);
183
- while (writer.length < layout.dataBits) writer.putBit(false);
184
- return writer;
185
203
  }
186
-
187
204
  function finalMessage(dataWriter, layout) {
188
- const bytes = Array.from(dataWriter.toBytes());
189
- if (layout.shortDataCodewordBits === 4) bytes[bytes.length - 1] &= 0xf0;
190
- const ecc = rsEncode(bytes, layout.eccCodewords, GF256_QR, 0);
191
- const out = [];
192
- const full = layout.shortDataCodewordBits === 4 ? bytes.length - 1 : bytes.length;
193
- for (let i = 0; i < full; i++) for (let b = 7; b >= 0; b--) out.push((bytes[i] >>> b) & 1);
194
- if (layout.shortDataCodewordBits === 4) for (let b = 7; b >= 4; b--) out.push((bytes[bytes.length - 1] >>> b) & 1);
195
- for (const value of ecc) for (let b = 7; b >= 0; b--) out.push((value >>> b) & 1);
196
- return out;
205
+ const bytes = Array.from(dataWriter.toBytes());
206
+ if (layout.shortDataCodewordBits === 4)
207
+ bytes[bytes.length - 1] &= 0xf0;
208
+ const ecc = rsEncode(bytes, layout.eccCodewords, GF256_QR, 0);
209
+ const out = [];
210
+ const full = layout.shortDataCodewordBits === 4 ? bytes.length - 1 : bytes.length;
211
+ for (let i = 0; i < full; i++)
212
+ for (let b = 7; b >= 0; b--)
213
+ out.push((bytes[i] >>> b) & 1);
214
+ if (layout.shortDataCodewordBits === 4)
215
+ for (let b = 7; b >= 4; b--)
216
+ out.push((bytes[bytes.length - 1] >>> b) & 1);
217
+ for (const value of ecc)
218
+ for (let b = 7; b >= 0; b--)
219
+ out.push((value >>> b) & 1);
220
+ return out;
197
221
  }
198
-
199
222
  function drawFunctions(matrix) {
200
- const size = matrix.width;
201
- for (let y = 0; y < 7; y++) for (let x = 0; x < 7; x++) {
202
- const ring = x === 0 || x === 6 || y === 0 || y === 6;
203
- const core = x >= 2 && x <= 4 && y >= 2 && y <= 4;
204
- matrix.setValue(x, y, ring || core);
205
- }
206
- for (let i = 0; i < 8; i++) { matrix.unset(7, i); matrix.unset(i, 7); }
207
- for (let i = 8; i < size; i++) if ((i & 1) === 0) { matrix.set(i, 0); matrix.set(0, i); }
223
+ const size = matrix.width;
224
+ for (let y = 0; y < 7; y++)
225
+ for (let x = 0; x < 7; x++) {
226
+ const ring = x === 0 || x === 6 || y === 0 || y === 6;
227
+ const core = x >= 2 && x <= 4 && y >= 2 && y <= 4;
228
+ matrix.setValue(x, y, ring || core);
229
+ }
230
+ for (let i = 0; i < 8; i++) {
231
+ matrix.unset(7, i);
232
+ matrix.unset(i, 7);
233
+ }
234
+ for (let i = 8; i < size; i++)
235
+ if ((i & 1) === 0) {
236
+ matrix.set(i, 0);
237
+ matrix.set(0, i);
238
+ }
208
239
  }
209
-
210
240
  function microMaskScore(matrix) {
211
- let right = 0, bottom = 0;
212
- for (let i = 1; i < matrix.width; i++) {
213
- if (matrix.get(matrix.width - 1, i)) right++;
214
- if (matrix.get(i, matrix.height - 1)) bottom++;
215
- }
216
- return Math.min(right, bottom) * 16 + Math.max(right, bottom);
241
+ let right = 0, bottom = 0;
242
+ for (let i = 1; i < matrix.width; i++) {
243
+ if (matrix.get(matrix.width - 1, i))
244
+ right++;
245
+ if (matrix.get(i, matrix.height - 1))
246
+ bottom++;
247
+ }
248
+ return Math.min(right, bottom) * 16 + Math.max(right, bottom);
217
249
  }
218
-
219
250
  function buildMatrix(version, ecc, mask, bits) {
220
- const matrix = new BitMatrix(microQrVersionSize(version));
221
- drawFunctions(matrix);
222
- const order = microQrDataModuleOrder(version);
223
- for (let i = 0; i < bits.length; i++) {
224
- const x = order[i * 2], y = order[i * 2 + 1];
225
- matrix.setValue(x, y, (bits[i] === 1) !== microQrMaskBit(mask, x, y));
226
- }
227
- const format = microQrFormatInfo(microQrSymbolNumber(version, ecc), mask);
228
- const positions = microQrFormatInfoPositions(matrix.width);
229
- for (let i = 0; i < 15; i++) matrix.setValue(positions[i][0], positions[i][1], ((format >>> i) & 1) === 1);
230
- return matrix;
251
+ const matrix = new BitMatrix(microQrVersionSize(version));
252
+ drawFunctions(matrix);
253
+ const order = microQrDataModuleOrder(version);
254
+ for (let i = 0; i < bits.length; i++) {
255
+ const x = order[i * 2], y = order[i * 2 + 1];
256
+ matrix.setValue(x, y, (bits[i] === 1) !== microQrMaskBit(mask, x, y));
257
+ }
258
+ const format = microQrFormatInfo(microQrSymbolNumber(version, ecc), mask);
259
+ const positions = microQrFormatInfoPositions(matrix.width);
260
+ for (let i = 0; i < 15; i++)
261
+ matrix.setValue(positions[i][0], positions[i][1], ((format >>> i) & 1) === 1);
262
+ return matrix;
231
263
  }
232
-
233
264
  export function encodeMicroQR(text, options = {}) {
234
- text = String(text);
235
- if (!text) throw new EncodeError('Micro QR: payload must not be empty');
236
- if (options.eci != null || options.gs1 === true) throw new EncodeError('Micro QR: ECI and GS1/FNC1 are unavailable');
237
- const mode = chooseMode(text, options.mode);
238
- const wantedVersion = parseVersion(options.version);
239
- const wantedEcc = options.ecc == null ? null : String(options.ecc).toUpperCase();
240
- if (wantedEcc === 'H') throw new EncodeError('Micro QR: error correction level H is unavailable');
241
- if (options.mask != null && (!Number.isInteger(options.mask) || options.mask < 0 || options.mask > 3)) {
242
- throw new EncodeError(`Micro QR: mask must be an integer 0-3, got ${options.mask}`);
243
- }
244
-
245
- let selected;
246
- for (const version of MICROQR_VERSIONS) {
247
- if (wantedVersion != null && version !== wantedVersion) continue;
248
- const numericVersion = versionNumber(version);
249
- if (numericVersion < MODE_MIN_VERSION[mode]) continue;
250
- const levels = numericVersion === 1 ? ['DETECT'] : numericVersion < 4 ? ['L', 'M'] : ['L', 'M', 'Q'];
251
- for (const ecc of levels) {
252
- if (wantedEcc != null && ecc !== wantedEcc) continue;
253
- const layout = microQrBlockLayout(version, ecc);
254
- const data = writeData(text, mode, version, layout);
255
- if (data) { selected = { version, ecc, layout, data }; break; }
265
+ text = String(text);
266
+ if (!text)
267
+ throw new EncodeError('Micro QR: payload must not be empty');
268
+ if (options.eci != null || options.gs1 === true)
269
+ throw new EncodeError('Micro QR: ECI and GS1/FNC1 are unavailable');
270
+ const mode = chooseMode(text, options.mode);
271
+ const wantedVersion = parseVersion(options.version);
272
+ const wantedEcc = options.ecc == null ? null : String(options.ecc).toUpperCase();
273
+ if (wantedEcc === 'H')
274
+ throw new EncodeError('Micro QR: error correction level H is unavailable');
275
+ if (options.mask != null && (!Number.isInteger(options.mask) || options.mask < 0 || options.mask > 3)) {
276
+ throw new EncodeError(`Micro QR: mask must be an integer 0-3, got ${options.mask}`);
277
+ }
278
+ let selected;
279
+ for (const version of MICROQR_VERSIONS) {
280
+ if (wantedVersion != null && version !== wantedVersion)
281
+ continue;
282
+ const numericVersion = versionNumber(version);
283
+ if (numericVersion < MODE_MIN_VERSION[mode])
284
+ continue;
285
+ const levels = numericVersion === 1 ? ['DETECT'] : numericVersion < 4 ? ['L', 'M'] : ['L', 'M', 'Q'];
286
+ for (const ecc of levels) {
287
+ if (wantedEcc != null && ecc !== wantedEcc)
288
+ continue;
289
+ const layout = microQrBlockLayout(version, ecc);
290
+ const data = writeData(text, mode, version, layout);
291
+ if (data) {
292
+ selected = { version, ecc, layout, data };
293
+ break;
294
+ }
295
+ }
296
+ if (selected)
297
+ break;
298
+ }
299
+ if (!selected)
300
+ throw new EncodeError('Micro QR: payload does not fit the requested version/error level');
301
+ const bits = finalMessage(selected.data, selected.layout);
302
+ if (options.mask != null)
303
+ return buildMatrix(selected.version, selected.ecc, options.mask, bits);
304
+ let best, score = -1;
305
+ for (let mask = 0; mask < 4; mask++) {
306
+ const candidate = buildMatrix(selected.version, selected.ecc, mask, bits);
307
+ const candidateScore = microMaskScore(candidate);
308
+ if (candidateScore > score) {
309
+ score = candidateScore;
310
+ best = candidate;
311
+ }
256
312
  }
257
- if (selected) break;
258
- }
259
- if (!selected) throw new EncodeError('Micro QR: payload does not fit the requested version/error level');
260
- const bits = finalMessage(selected.data, selected.layout);
261
- if (options.mask != null) return buildMatrix(selected.version, selected.ecc, options.mask, bits);
262
- let best, score = -1;
263
- for (let mask = 0; mask < 4; mask++) {
264
- const candidate = buildMatrix(selected.version, selected.ecc, mask, bits);
265
- const candidateScore = microMaskScore(candidate);
266
- if (candidateScore > score) { score = candidateScore; best = candidate; }
267
- }
268
- return best;
313
+ return best;
269
314
  }
@@ -27,9 +27,7 @@
27
27
  *
28
28
  * Original work. No code from any other barcode implementation.
29
29
  */
30
-
31
30
  /** Micro QR Code M1-M4 public module surface. @module microqr */
32
-
33
31
  export { encodeMicroQR } from './encoder.js';
34
32
  export { decodeMicroQR } from './decoder.js';
35
33
  export { detectMicroQR, detectAndDecodeMicroQR } from './detector.js';