@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.
- package/LICENSE +5 -4
- package/NOTICE.md +2 -2
- package/README.md +17 -13
- package/bundle/sythos-barcode.esm.js +11658 -11244
- package/bundle/sythos-barcode.js +11658 -11244
- package/package.json +10 -3
- package/src/index.d.ts +1 -1
- package/src/index.js +508 -516
- package/src/js/aztec/decoder.js +208 -199
- package/src/js/aztec/detector.js +153 -126
- package/src/js/aztec/encoder.js +172 -153
- package/src/js/aztec/high-level.js +106 -101
- package/src/js/aztec/index.js +1 -12
- package/src/js/aztec/tables.js +106 -120
- package/src/js/aztecrune/decoder.js +76 -85
- package/src/js/aztecrune/detector.js +107 -93
- package/src/js/aztecrune/encoder.js +50 -68
- package/src/js/aztecrune/index.js +1 -16
- package/src/js/aztecrune/tables.js +59 -54
- package/src/js/compactpdf417/decoder.js +69 -74
- package/src/js/compactpdf417/detector.js +74 -75
- package/src/js/compactpdf417/encoder.js +68 -81
- package/src/js/compactpdf417/index.js +1 -13
- package/src/js/compactpdf417/tables.js +71 -80
- package/src/js/core/bit-buffer.js +106 -122
- package/src/js/core/bit-matrix.js +196 -194
- package/src/js/core/errors.js +13 -15
- package/src/js/core/galois-field.js +119 -133
- package/src/js/core/index.js +2 -19
- package/src/js/core/reed-solomon.js +195 -204
- package/src/js/databar/codec.js +93 -108
- package/src/js/databar/decoder.js +149 -140
- package/src/js/databar/encoder.js +47 -55
- package/src/js/databar/gs1.js +122 -123
- package/src/js/databar/index.js +4 -36
- package/src/js/databar/patterns.js +81 -85
- package/src/js/databar/tables.js +51 -52
- package/src/js/datamatrix/decoder.js +216 -182
- package/src/js/datamatrix/detector.js +161 -132
- package/src/js/datamatrix/encoder.js +192 -133
- package/src/js/datamatrix/index.js +1 -9
- package/src/js/datamatrix/tables.js +68 -69
- package/src/js/frameqr/decoder.js +102 -125
- package/src/js/frameqr/detector.js +101 -94
- package/src/js/frameqr/encoder.js +67 -80
- package/src/js/frameqr/index.js +1 -10
- package/src/js/frameqr/tables.js +145 -163
- package/src/js/image/binarizer.js +146 -162
- package/src/js/image/grid-sampler.js +63 -79
- package/src/js/image/index.js +0 -2
- package/src/js/image/luminance.js +129 -140
- package/src/js/image/perspective.js +112 -149
- package/src/js/micropdf417/compaction.js +64 -65
- package/src/js/micropdf417/decoder.js +106 -109
- package/src/js/micropdf417/detector.js +73 -70
- package/src/js/micropdf417/encoder.js +129 -154
- package/src/js/micropdf417/error-correction.js +6 -11
- package/src/js/micropdf417/index.js +2 -16
- package/src/js/micropdf417/tables.js +112 -99
- package/src/js/microqr/decoder.js +177 -182
- package/src/js/microqr/detector.js +240 -256
- package/src/js/microqr/encoder.js +239 -194
- package/src/js/microqr/index.js +0 -2
- package/src/js/microqr/tables.js +208 -200
- package/src/js/oned/addons.js +167 -191
- package/src/js/oned/index.js +27 -58
- package/src/js/oned/patterns.js +194 -213
- package/src/js/oned/reader.js +1003 -984
- package/src/js/oned/writers.js +411 -466
- package/src/js/pdf417/compaction.js +315 -222
- package/src/js/pdf417/decoder.js +71 -36
- package/src/js/pdf417/detector.js +377 -361
- package/src/js/pdf417/encoder.js +57 -46
- package/src/js/pdf417/error-correction.js +5 -8
- package/src/js/pdf417/tables.js +248 -250
- package/src/js/qr/decoder.js +311 -347
- package/src/js/qr/detector.js +378 -395
- package/src/js/qr/encoder.js +514 -599
- package/src/js/qr/index.js +0 -2
- package/src/js/qr/tables.js +375 -422
- package/src/js/render/image-data.js +57 -62
- package/src/js/render/index.js +21 -23
- package/src/js/render/options.js +82 -90
- package/src/js/render/png.js +144 -169
- package/src/js/render/svg.js +41 -44
- package/src/js/render/webgl.js +103 -109
- package/src/js/render/webgpu.js +205 -217
- package/src/js/rmqr/decoder.js +161 -53
- package/src/js/rmqr/detector.js +73 -41
- package/src/js/rmqr/encoder.js +253 -104
- package/src/js/rmqr/index.js +1 -5
- package/src/js/rmqr/tables.js +108 -85
- package/src/ts/aztec/decoder.ts +317 -0
- package/src/ts/aztec/detector.ts +224 -0
- package/src/ts/aztec/encoder.ts +257 -0
- package/src/ts/aztec/high-level.ts +211 -0
- package/src/ts/aztec/index.ts +45 -0
- package/src/ts/aztec/tables.ts +210 -0
- package/src/ts/aztecrune/decoder.ts +155 -0
- package/src/ts/aztecrune/detector.ts +166 -0
- package/src/ts/aztecrune/encoder.ts +121 -0
- package/src/ts/aztecrune/index.ts +49 -0
- package/src/ts/aztecrune/tables.ts +137 -0
- package/src/ts/compactpdf417/decoder.ts +128 -0
- package/src/ts/compactpdf417/detector.ts +139 -0
- package/src/ts/compactpdf417/encoder.ts +140 -0
- package/src/ts/compactpdf417/index.ts +17 -0
- package/src/ts/compactpdf417/tables.ts +173 -0
- package/src/ts/core/bit-buffer.ts +174 -0
- package/src/ts/core/bit-matrix.ts +241 -0
- package/src/ts/core/errors.ts +61 -0
- package/src/ts/core/galois-field.ts +207 -0
- package/src/ts/core/index.ts +56 -0
- package/src/ts/core/reed-solomon.ts +327 -0
- package/src/ts/databar/codec.ts +181 -0
- package/src/ts/databar/decoder.ts +215 -0
- package/src/ts/databar/encoder.ts +96 -0
- package/src/ts/databar/gs1.ts +177 -0
- package/src/ts/databar/index.ts +68 -0
- package/src/ts/databar/patterns.ts +143 -0
- package/src/ts/databar/tables.ts +124 -0
- package/src/ts/datamatrix/decoder.ts +262 -0
- package/src/ts/datamatrix/detector.ts +225 -0
- package/src/ts/datamatrix/encoder.ts +191 -0
- package/src/ts/datamatrix/index.ts +42 -0
- package/src/ts/datamatrix/tables.ts +123 -0
- package/src/ts/frameqr/decoder.ts +239 -0
- package/src/ts/frameqr/detector.ts +192 -0
- package/src/ts/frameqr/encoder.ts +156 -0
- package/src/ts/frameqr/index.ts +42 -0
- package/src/ts/frameqr/tables.ts +270 -0
- package/src/ts/image/binarizer.ts +270 -0
- package/src/ts/image/grid-sampler.ts +164 -0
- package/src/ts/image/index.ts +40 -0
- package/src/ts/image/luminance.ts +196 -0
- package/src/ts/image/perspective.ts +195 -0
- package/src/ts/index.d.ts +1 -1
- package/src/ts/index.ts +790 -0
- package/src/ts/micropdf417/compaction.ts +116 -0
- package/src/ts/micropdf417/decoder.ts +183 -0
- package/src/ts/micropdf417/detector.ts +149 -0
- package/src/ts/micropdf417/encoder.ts +209 -0
- package/src/ts/micropdf417/error-correction.ts +55 -0
- package/src/ts/micropdf417/index.ts +49 -0
- package/src/ts/micropdf417/tables.ts +184 -0
- package/src/ts/microqr/decoder.ts +245 -0
- package/src/ts/microqr/detector.ts +355 -0
- package/src/ts/microqr/encoder.ts +269 -0
- package/src/ts/microqr/index.ts +36 -0
- package/src/ts/microqr/tables.ts +316 -0
- package/src/ts/oned/addons.ts +420 -0
- package/src/ts/oned/index.ts +106 -0
- package/src/ts/oned/patterns.ts +384 -0
- package/src/ts/oned/reader.ts +1364 -0
- package/src/ts/oned/writers.ts +746 -0
- package/src/ts/pdf417/compaction.ts +298 -0
- package/src/ts/pdf417/decoder.ts +75 -0
- package/src/ts/pdf417/detector.ts +468 -0
- package/src/ts/pdf417/encoder.ts +91 -0
- package/src/ts/pdf417/error-correction.ts +47 -0
- package/src/ts/pdf417/index.ts +6 -0
- package/src/ts/pdf417/tables.ts +317 -0
- package/src/ts/qr/decoder.ts +575 -0
- package/src/ts/qr/detector.ts +630 -0
- package/src/ts/qr/encoder.ts +958 -0
- package/src/ts/qr/index.ts +44 -0
- package/src/ts/qr/tables.ts +737 -0
- package/src/ts/render/image-data.ts +125 -0
- package/src/ts/render/index.ts +130 -0
- package/src/ts/render/options.ts +160 -0
- package/src/ts/render/png.ts +295 -0
- package/src/ts/render/svg.ts +120 -0
- package/src/ts/render/webgl.ts +206 -0
- package/src/ts/render/webgpu.ts +369 -0
- package/src/ts/rmqr/decoder.ts +101 -0
- package/src/ts/rmqr/detector.ts +90 -0
- package/src/ts/rmqr/encoder.ts +172 -0
- package/src/ts/rmqr/index.ts +37 -0
- 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
|
-
|
|
47
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
52
|
+
return typeof version === 'number' ? version : Number(String(version).slice(1));
|
|
59
53
|
}
|
|
60
|
-
|
|
61
54
|
function latin1Bytes(text) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
-
|
|
106
|
-
return result;
|
|
110
|
+
sjisReverseMap = result;
|
|
111
|
+
return result;
|
|
107
112
|
}
|
|
108
|
-
|
|
109
113
|
function kanjiValues(text) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
145
|
-
|
|
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
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
169
|
+
return ((writer.bytes[index >>> 3] >>> (7 - (index & 7))) & 1) === 1;
|
|
160
170
|
}
|
|
161
|
-
|
|
162
171
|
function writeData(text, mode, version, layout) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
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
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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
|
-
|
|
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
|
}
|
package/src/js/microqr/index.js
CHANGED
|
@@ -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';
|