@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
package/src/js/rmqr/encoder.js
CHANGED
|
@@ -27,146 +27,295 @@
|
|
|
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
|
-
FORMAT_MASK_FINDER, FORMAT_MASK_SUB, dataBitCapacity, dataModuleOrder, formatBits,
|
|
38
|
-
functionModules, maskBit, versionForSize, versionInfo,
|
|
39
|
-
} from './tables.js';
|
|
40
|
-
|
|
35
|
+
import { FORMAT_MASK_FINDER, FORMAT_MASK_SUB, dataBitCapacity, dataModuleOrder, formatBits, functionModules, maskBit, versionForSize, versionInfo, } from './tables.js';
|
|
41
36
|
export const ALPHANUMERIC_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:';
|
|
42
37
|
const MODE = Object.freeze({ TERMINATOR: 0, NUMERIC: 1, ALPHANUMERIC: 2, BYTE: 3, KANJI: 4, FNC1: 5, FNC1_SECOND: 6, ECI: 7 });
|
|
43
|
-
|
|
44
38
|
function utf8Bytes(text) { return new TextEncoder().encode(text); }
|
|
45
|
-
function latin1Bytes(text) { const out = new Uint8Array(text.length); for (let i = 0; i < text.length; i++) {
|
|
46
|
-
|
|
39
|
+
function latin1Bytes(text) { const out = new Uint8Array(text.length); for (let i = 0; i < text.length; i++) {
|
|
40
|
+
const c = text.charCodeAt(i);
|
|
41
|
+
if (c > 255)
|
|
42
|
+
throw new EncodeError('rMQR: text is not ISO-8859-1');
|
|
43
|
+
out[i] = c;
|
|
44
|
+
} return out; }
|
|
45
|
+
function isAlpha(text) { for (const ch of text)
|
|
46
|
+
if (ALPHANUMERIC_CHARS.indexOf(ch) < 0)
|
|
47
|
+
return false; return true; }
|
|
47
48
|
function isNumeric(text) { return /^[0-9]*$/.test(text); }
|
|
48
|
-
|
|
49
49
|
let sjisMap;
|
|
50
50
|
function getSjisMap() {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
if (sjisMap !== undefined)
|
|
52
|
+
return sjisMap;
|
|
53
|
+
try {
|
|
54
|
+
const decoder = new TextDecoder('shift_jis', { fatal: true });
|
|
55
|
+
if (decoder.decode(new Uint8Array([0x82, 0xa0])) !== 'あ')
|
|
56
|
+
return (sjisMap = null);
|
|
57
|
+
const map = new Map();
|
|
58
|
+
const buf = new Uint8Array(2);
|
|
59
|
+
for (const [lo, hi] of [[0x8140, 0x9ffc], [0xe040, 0xebbf]])
|
|
60
|
+
for (let sjis = lo; sjis <= hi; sjis++) {
|
|
61
|
+
const trail = sjis & 255;
|
|
62
|
+
if (trail < 0x40 || trail === 0x7f || trail > 0xfc)
|
|
63
|
+
continue;
|
|
64
|
+
buf[0] = sjis >> 8;
|
|
65
|
+
buf[1] = trail;
|
|
66
|
+
let text;
|
|
67
|
+
try {
|
|
68
|
+
text = decoder.decode(buf);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (Array.from(text).length === 1 && !map.has(text))
|
|
74
|
+
map.set(text, sjis);
|
|
75
|
+
}
|
|
76
|
+
return (sjisMap = map);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return (sjisMap = null);
|
|
60
80
|
}
|
|
61
|
-
return (sjisMap = map);
|
|
62
|
-
} catch { return (sjisMap = null); }
|
|
63
81
|
}
|
|
64
82
|
function kanjiValue(ch) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
83
|
+
const sjis = getSjisMap()?.get(ch);
|
|
84
|
+
if (sjis === undefined)
|
|
85
|
+
return -1;
|
|
86
|
+
let v;
|
|
87
|
+
if (sjis >= 0x8140 && sjis <= 0x9ffc)
|
|
88
|
+
v = sjis - 0x8140;
|
|
89
|
+
else if (sjis >= 0xe040 && sjis <= 0xebbf)
|
|
90
|
+
v = sjis - 0xc140;
|
|
91
|
+
else
|
|
92
|
+
return -1;
|
|
93
|
+
return ((v >> 8) * 0xc0) + (v & 0xff);
|
|
68
94
|
}
|
|
69
|
-
|
|
70
95
|
function chooseMode(text, requested) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
96
|
+
if (requested === 'numeric' || requested === 'alphanumeric' || requested === 'byte' || requested === 'kanji')
|
|
97
|
+
return requested;
|
|
98
|
+
if (isNumeric(text))
|
|
99
|
+
return 'numeric';
|
|
100
|
+
if (isAlpha(text))
|
|
101
|
+
return 'alphanumeric';
|
|
102
|
+
return 'byte';
|
|
75
103
|
}
|
|
76
|
-
|
|
77
104
|
function modeBits(mode) { return MODE[mode.toUpperCase()] ?? MODE.BYTE; }
|
|
78
105
|
function charCount(mode, text, bytes) { return mode === 'byte' ? bytes.length : mode === 'kanji' ? Array.from(text).length : text.length; }
|
|
79
106
|
function payloadBits(mode, text, bytes) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
107
|
+
if (mode === 'numeric') {
|
|
108
|
+
let n = 0;
|
|
109
|
+
for (let i = 0; i < text.length; i += 3)
|
|
110
|
+
n += text.length - i >= 3 ? 10 : text.length - i === 2 ? 7 : 4;
|
|
111
|
+
return n;
|
|
112
|
+
}
|
|
113
|
+
if (mode === 'alphanumeric')
|
|
114
|
+
return Math.floor(text.length / 2) * 11 + (text.length & 1 ? 6 : 0);
|
|
115
|
+
if (mode === 'kanji')
|
|
116
|
+
return Array.from(text).length * 13;
|
|
117
|
+
return bytes.length * 8;
|
|
84
118
|
}
|
|
85
|
-
|
|
86
119
|
function putEci(writer, assignment) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
120
|
+
writer.put(MODE.ECI, 3);
|
|
121
|
+
if (assignment <= 127)
|
|
122
|
+
writer.put(assignment, 8);
|
|
123
|
+
else if (assignment <= 16383)
|
|
124
|
+
writer.put(0x8000 | assignment, 16);
|
|
125
|
+
else if (assignment <= 999999)
|
|
126
|
+
writer.put(0xc00000 | assignment, 24);
|
|
127
|
+
else
|
|
128
|
+
throw new EncodeError(`rMQR: invalid ECI assignment ${assignment}`);
|
|
92
129
|
}
|
|
93
|
-
|
|
94
130
|
function makeData(text, v, ecc, options) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
131
|
+
const requested = options.mode;
|
|
132
|
+
const mode = chooseMode(text, requested);
|
|
133
|
+
const charset = options.charset || (mode === 'byte' && Array.from(text).every((ch) => ch.charCodeAt(0) <= 255) ? 'iso-8859-1' : 'utf-8');
|
|
134
|
+
const bytes = mode === 'byte' ? (charset === 'iso-8859-1' ? latin1Bytes(text) : utf8Bytes(text)) : new Uint8Array();
|
|
135
|
+
const countBits = v.countBits(mode);
|
|
136
|
+
if (!countBits)
|
|
137
|
+
throw new EncodeError(`rMQR: unsupported mode ${mode}`);
|
|
138
|
+
const writer = new BitWriter();
|
|
139
|
+
if (options.eci !== undefined)
|
|
140
|
+
putEci(writer, options.eci);
|
|
141
|
+
else if (mode === 'byte' && charset === 'utf-8')
|
|
142
|
+
putEci(writer, 26);
|
|
143
|
+
writer.put(modeBits(mode), 3);
|
|
144
|
+
writer.put(charCount(mode, text, bytes), countBits); // header
|
|
145
|
+
if (mode === 'numeric')
|
|
146
|
+
for (let i = 0; i < text.length; i += 3) {
|
|
147
|
+
const s = text.slice(i, i + 3);
|
|
148
|
+
writer.put(Number(s), s.length === 3 ? 10 : s.length === 2 ? 7 : 4);
|
|
149
|
+
}
|
|
150
|
+
else if (mode === 'alphanumeric')
|
|
151
|
+
for (let i = 0; i < text.length; i += 2) {
|
|
152
|
+
const a = ALPHANUMERIC_CHARS.indexOf(text[i]);
|
|
153
|
+
const b = i + 1 < text.length ? ALPHANUMERIC_CHARS.indexOf(text[i + 1]) : -1;
|
|
154
|
+
if (a < 0 || (b < 0 && i + 1 < text.length))
|
|
155
|
+
throw new EncodeError('rMQR: invalid alphanumeric character');
|
|
156
|
+
writer.put(b < 0 ? a : a * 45 + b, b < 0 ? 6 : 11);
|
|
157
|
+
}
|
|
158
|
+
else if (mode === 'kanji')
|
|
159
|
+
for (const ch of Array.from(text)) {
|
|
160
|
+
const value = kanjiValue(ch);
|
|
161
|
+
if (value < 0)
|
|
162
|
+
throw new EncodeError(`rMQR: character ${ch} is not encodable in Kanji mode`);
|
|
163
|
+
writer.put(value, 13);
|
|
164
|
+
}
|
|
165
|
+
else
|
|
166
|
+
writer.putBytes(bytes);
|
|
167
|
+
const capacity = dataBitCapacity(v.version, ecc);
|
|
168
|
+
if (writer.length > capacity)
|
|
169
|
+
throw new EncodeError(`rMQR: payload does not fit ${v.name}-${ecc}`);
|
|
170
|
+
if (writer.length + 3 <= capacity)
|
|
171
|
+
writer.put(0, 3);
|
|
172
|
+
while (writer.length & 7)
|
|
173
|
+
writer.putBit(false);
|
|
174
|
+
const dataBytes = v.blockLayout(ecc).totalDataCodewords;
|
|
175
|
+
let pad = 0xec;
|
|
176
|
+
while (writer.toBytes().length < dataBytes) {
|
|
177
|
+
writer.put(pad, 8);
|
|
178
|
+
pad = pad === 0xec ? 0x11 : 0xec;
|
|
179
|
+
}
|
|
180
|
+
return writer.toBytes();
|
|
116
181
|
}
|
|
117
|
-
|
|
118
182
|
function interleave(data, v, ecc) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
183
|
+
const layout = v.blockLayout(ecc);
|
|
184
|
+
const blocks = [];
|
|
185
|
+
let offset = 0;
|
|
186
|
+
for (const b of layout.blocks) {
|
|
187
|
+
const d = Array.from(data.slice(offset, offset + b.data));
|
|
188
|
+
offset += b.data;
|
|
189
|
+
blocks.push({ data: d, ecc: rsEncode(d, b.ecc, GF256_QR, 0) });
|
|
190
|
+
}
|
|
191
|
+
const out = [];
|
|
192
|
+
const maxData = Math.max(...blocks.map((b) => b.data.length));
|
|
193
|
+
const maxEcc = Math.max(...blocks.map((b) => b.ecc.length));
|
|
194
|
+
for (let i = 0; i < maxData; i++)
|
|
195
|
+
for (const b of blocks)
|
|
196
|
+
if (i < b.data.length)
|
|
197
|
+
out.push(b.data[i]);
|
|
198
|
+
for (let i = 0; i < maxEcc; i++)
|
|
199
|
+
for (const b of blocks)
|
|
200
|
+
if (i < b.ecc.length)
|
|
201
|
+
out.push(b.ecc[i]);
|
|
202
|
+
return Uint8Array.from(out);
|
|
125
203
|
}
|
|
126
|
-
|
|
127
204
|
function drawFunctions(m, version) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
205
|
+
const v = versionInfo(version);
|
|
206
|
+
const fn = functionModules(version);
|
|
207
|
+
const { width: w, height: h } = v;
|
|
208
|
+
const setIfData = (x, y, on) => { if (!fn.get(x, y))
|
|
209
|
+
m.setValue(x, y, on); };
|
|
210
|
+
for (let x = 0; x < w; x++) {
|
|
211
|
+
m.setValue(x, 0, (x & 1) === 0);
|
|
212
|
+
m.setValue(x, h - 1, (x & 1) === 0);
|
|
213
|
+
}
|
|
214
|
+
for (const x of [0, w - 1, ...new Set([...(awaitableAlignment(version))])])
|
|
215
|
+
for (let y = 0; y < h; y++)
|
|
216
|
+
setIfData(x, y, (y & 1) === 0);
|
|
217
|
+
for (const cx of awaitableAlignment(version))
|
|
218
|
+
for (const y of [0, 1, h - 2, h - 1])
|
|
219
|
+
m.setValue(cx + (y === 0 || y === h - 1 ? 0 : 0), y, false);
|
|
220
|
+
// Alignment patterns (top and bottom).
|
|
221
|
+
for (const cx of awaitableAlignment(version))
|
|
222
|
+
for (let i = 0; i < 3; i++)
|
|
223
|
+
for (let j = 0; j < 3; j++) {
|
|
224
|
+
const on = i === 0 || i === 2 || j === 0 || j === 2;
|
|
225
|
+
m.setValue(cx + j - 1, i, on);
|
|
226
|
+
m.setValue(cx + j - 1, h - 1 - i, on);
|
|
227
|
+
}
|
|
228
|
+
// Finder and separator.
|
|
229
|
+
for (let i = 0; i < 7; i++)
|
|
230
|
+
for (let j = 0; j < 7; j++)
|
|
231
|
+
m.setValue(j, i, i === 0 || i === 6 || j === 0 || j === 6 || (i >= 2 && i <= 4 && j >= 2 && j <= 4));
|
|
232
|
+
for (let n = 0; n < 8; n++) {
|
|
233
|
+
if (n < h)
|
|
234
|
+
m.setValue(7, n, false);
|
|
235
|
+
if (h >= 9)
|
|
236
|
+
m.setValue(n, 7, false);
|
|
237
|
+
}
|
|
238
|
+
for (let i = 0; i < 5; i++)
|
|
239
|
+
for (let j = 0; j < 5; j++)
|
|
240
|
+
m.setValue(w - j - 1, h - i - 1, i === 0 || i === 4 || j === 0 || j === 4 || (i === 2 && j === 2));
|
|
241
|
+
m.set(w - 1, 0);
|
|
242
|
+
m.set(w - 2, 0);
|
|
243
|
+
m.set(w - 1, 1);
|
|
244
|
+
if (h >= 11) {
|
|
245
|
+
m.set(0, h - 1);
|
|
246
|
+
m.set(1, h - 1);
|
|
247
|
+
m.set(2, h - 1);
|
|
248
|
+
m.set(0, h - 2);
|
|
249
|
+
}
|
|
140
250
|
}
|
|
141
|
-
|
|
142
251
|
// Kept as a local helper so drawFunctions stays independent of mutable tables.
|
|
143
252
|
function awaitableAlignment(version) { return ({ 27: [], 43: [21], 59: [19, 39], 77: [25, 51], 99: [23, 49, 75], 139: [27, 55, 83, 111] })[versionInfo(version).width] || []; }
|
|
144
|
-
|
|
145
253
|
function drawFormat(m, version, ecc) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
254
|
+
const v = versionInfo(version);
|
|
255
|
+
let bits = formatBits(version, ecc) ^ FORMAT_MASK_FINDER;
|
|
256
|
+
for (let n = 0; n < 18; n++)
|
|
257
|
+
m.setValue(8 + Math.floor(n / 5), 1 + (n % 5), ((bits >>> n) & 1) !== 0);
|
|
258
|
+
bits = formatBits(version, ecc) ^ FORMAT_MASK_SUB;
|
|
259
|
+
for (let n = 0; n < 15; n++)
|
|
260
|
+
m.setValue(v.width - 8 + Math.floor(n / 5), v.height - 6 + (n % 5), ((bits >>> n) & 1) !== 0);
|
|
261
|
+
for (let n = 15; n < 18; n++)
|
|
262
|
+
m.setValue(v.width - 5 + (n - 15), v.height - 6, ((bits >>> n) & 1) !== 0);
|
|
151
263
|
}
|
|
152
|
-
|
|
153
264
|
function buildMatrix(version, ecc, codewords) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
265
|
+
const v = versionInfo(version);
|
|
266
|
+
const m = new BitMatrix(v.width, v.height);
|
|
267
|
+
drawFunctions(m, version);
|
|
268
|
+
drawFormat(m, version, ecc);
|
|
269
|
+
const fn = functionModules(version);
|
|
270
|
+
const order = dataModuleOrder(version);
|
|
271
|
+
let bit = 0;
|
|
272
|
+
for (const [x, y] of order) {
|
|
273
|
+
let on = bit < codewords.length * 8 && ((codewords[bit >>> 3] >>> (7 - (bit & 7))) & 1) !== 0;
|
|
274
|
+
if (maskBit(x, y))
|
|
275
|
+
on = !on;
|
|
276
|
+
m.setValue(x, y, on);
|
|
277
|
+
bit++;
|
|
278
|
+
}
|
|
279
|
+
return m;
|
|
157
280
|
}
|
|
158
|
-
|
|
159
281
|
/** Encode text into a rMQR module matrix. */
|
|
160
282
|
export function encodeRMQR(text, options = {}) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
283
|
+
if (typeof text !== 'string' || text.length === 0)
|
|
284
|
+
throw new EncodeError('rMQR: text must be a non-empty string');
|
|
285
|
+
const ecc = options.ecc || 'M';
|
|
286
|
+
if (ecc !== 'M' && ecc !== 'H')
|
|
287
|
+
throw new EncodeError('rMQR: ECC must be M or H');
|
|
288
|
+
let forced = options.version;
|
|
289
|
+
if (typeof forced === 'string') {
|
|
290
|
+
const match = /^R(\d+)x(\d+)$/i.exec(forced);
|
|
291
|
+
if (!match)
|
|
292
|
+
throw new EncodeError(`rMQR: invalid version ${forced}`);
|
|
293
|
+
const info = versionForSize(Number(match[2]), Number(match[1]));
|
|
294
|
+
if (!info)
|
|
295
|
+
throw new EncodeError(`rMQR: unsupported version ${forced}`);
|
|
296
|
+
forced = info.version;
|
|
297
|
+
}
|
|
298
|
+
if (forced !== undefined && (!Number.isInteger(forced) || forced < 1 || forced > 32))
|
|
299
|
+
throw new EncodeError('rMQR: version must be 1-32');
|
|
300
|
+
const versions = forced ? [forced] : Array.from({ length: 32 }, (_, i) => i + 1);
|
|
301
|
+
let selected = null;
|
|
302
|
+
for (const n of versions) {
|
|
303
|
+
const v = versionInfo(n);
|
|
304
|
+
try {
|
|
305
|
+
const data = makeData(text, v, ecc, options);
|
|
306
|
+
selected = { v, data };
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
if (forced)
|
|
311
|
+
throw error;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (!selected)
|
|
315
|
+
throw new EncodeError(`rMQR: text is too long for ECC ${ecc}`);
|
|
316
|
+
const codewords = interleave(selected.data, selected.v, ecc);
|
|
317
|
+
const matrix = buildMatrix(selected.v.version, ecc, codewords);
|
|
318
|
+
matrix.rmqr = { version: selected.v.version, name: selected.v.name, ecc };
|
|
319
|
+
return matrix;
|
|
170
320
|
}
|
|
171
|
-
|
|
172
321
|
export { MODE };
|
package/src/js/rmqr/index.js
CHANGED
|
@@ -27,11 +27,7 @@
|
|
|
27
27
|
*
|
|
28
28
|
* Original work. No code from any other barcode implementation.
|
|
29
29
|
*/
|
|
30
|
-
|
|
31
30
|
export { encodeRMQR, ALPHANUMERIC_CHARS } from './encoder.js';
|
|
32
31
|
export { decodeRMQR } from './decoder.js';
|
|
33
32
|
export { detectRMQR, detectAndDecodeRMQR } from './detector.js';
|
|
34
|
-
export {
|
|
35
|
-
RMQR_SIZES, versionInfo, versionForSize, alignmentCoordinates, dataModuleOrder,
|
|
36
|
-
functionModules, dataBitCapacity, formatBits, maskBit, validateTables,
|
|
37
|
-
} from './tables.js';
|
|
33
|
+
export { RMQR_SIZES, versionInfo, versionForSize, alignmentCoordinates, dataModuleOrder, functionModules, dataBitCapacity, formatBits, maskBit, validateTables, } from './tables.js';
|