@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.
- package/LICENSE +5 -4
- package/NOTICE.md +2 -2
- package/README.md +61 -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/render/png.js
CHANGED
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
*
|
|
28
28
|
* Original work. No code from any other barcode implementation.
|
|
29
29
|
*/
|
|
30
|
-
|
|
31
30
|
/**
|
|
32
31
|
* PNG output, with no dependencies and no compression library of our own.
|
|
33
32
|
*
|
|
@@ -48,61 +47,54 @@
|
|
|
48
47
|
*
|
|
49
48
|
* @module render/png
|
|
50
49
|
*/
|
|
51
|
-
|
|
52
50
|
import { normalizeOptions, parseColor } from './options.js';
|
|
53
|
-
|
|
54
51
|
/* ------------------------------------------------------------------ *
|
|
55
52
|
* Checksums
|
|
56
53
|
* ------------------------------------------------------------------ */
|
|
57
|
-
|
|
58
54
|
const CRC_TABLE = (() => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
55
|
+
const table = new Uint32Array(256);
|
|
56
|
+
for (let n = 0; n < 256; n++) {
|
|
57
|
+
let c = n;
|
|
58
|
+
for (let k = 0; k < 8; k++) {
|
|
59
|
+
c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
60
|
+
}
|
|
61
|
+
table[n] = c >>> 0;
|
|
64
62
|
}
|
|
65
|
-
table
|
|
66
|
-
}
|
|
67
|
-
return table;
|
|
63
|
+
return table;
|
|
68
64
|
})();
|
|
69
|
-
|
|
70
65
|
/**
|
|
71
66
|
* @param {Uint8Array} bytes
|
|
72
67
|
* @returns {number}
|
|
73
68
|
*/
|
|
74
69
|
function crc32(bytes) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
70
|
+
let c = 0xffffffff;
|
|
71
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
72
|
+
c = CRC_TABLE[(c ^ bytes[i]) & 0xff] ^ (c >>> 8);
|
|
73
|
+
}
|
|
74
|
+
return (c ^ 0xffffffff) >>> 0;
|
|
80
75
|
}
|
|
81
|
-
|
|
82
76
|
/**
|
|
83
77
|
* @param {Uint8Array} bytes
|
|
84
78
|
* @returns {number}
|
|
85
79
|
*/
|
|
86
80
|
function adler32(bytes) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
81
|
+
let a = 1;
|
|
82
|
+
let b = 0;
|
|
83
|
+
// 5552 is the largest run that cannot overflow the 32-bit accumulator.
|
|
84
|
+
for (let i = 0; i < bytes.length;) {
|
|
85
|
+
const end = Math.min(i + 5552, bytes.length);
|
|
86
|
+
for (; i < end; i++) {
|
|
87
|
+
a += bytes[i];
|
|
88
|
+
b += a;
|
|
89
|
+
}
|
|
90
|
+
a %= 65521;
|
|
91
|
+
b %= 65521;
|
|
95
92
|
}
|
|
96
|
-
a
|
|
97
|
-
b %= 65521;
|
|
98
|
-
}
|
|
99
|
-
return ((b << 16) | a) >>> 0;
|
|
93
|
+
return ((b << 16) | a) >>> 0;
|
|
100
94
|
}
|
|
101
|
-
|
|
102
95
|
/* ------------------------------------------------------------------ *
|
|
103
96
|
* Deflate
|
|
104
97
|
* ------------------------------------------------------------------ */
|
|
105
|
-
|
|
106
98
|
/**
|
|
107
99
|
* Wrap data in stored (type 00) deflate blocks with a zlib header.
|
|
108
100
|
*
|
|
@@ -115,40 +107,33 @@ function adler32(bytes) {
|
|
|
115
107
|
* @returns {Uint8Array}
|
|
116
108
|
*/
|
|
117
109
|
export function deflateStored(data) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
out
|
|
140
|
-
p
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
out[p++] = (sum >>> 24) & 0xff; // adler32, big endian
|
|
145
|
-
out[p++] = (sum >>> 16) & 0xff;
|
|
146
|
-
out[p++] = (sum >>> 8) & 0xff;
|
|
147
|
-
out[p++] = sum & 0xff;
|
|
148
|
-
|
|
149
|
-
return out.subarray(0, p);
|
|
110
|
+
const MAX = 0xffff;
|
|
111
|
+
const blockCount = Math.max(1, Math.ceil(data.length / MAX));
|
|
112
|
+
const out = new Uint8Array(2 + blockCount * 5 + data.length + 4);
|
|
113
|
+
let p = 0;
|
|
114
|
+
// zlib header: deflate, 32K window, no preset dictionary. 0x78 0x01 is a
|
|
115
|
+
// valid FCHECK pair (0x7801 % 31 === 0).
|
|
116
|
+
out[p++] = 0x78;
|
|
117
|
+
out[p++] = 0x01;
|
|
118
|
+
for (let i = 0; i < blockCount; i++) {
|
|
119
|
+
const start = i * MAX;
|
|
120
|
+
const len = Math.min(MAX, data.length - start);
|
|
121
|
+
const isLast = i === blockCount - 1;
|
|
122
|
+
out[p++] = isLast ? 1 : 0; // BFINAL, BTYPE = 00
|
|
123
|
+
out[p++] = len & 0xff; // LEN, little endian
|
|
124
|
+
out[p++] = (len >>> 8) & 0xff;
|
|
125
|
+
out[p++] = ~len & 0xff; // NLEN, one's complement
|
|
126
|
+
out[p++] = (~len >>> 8) & 0xff;
|
|
127
|
+
out.set(data.subarray(start, start + len), p);
|
|
128
|
+
p += len;
|
|
129
|
+
}
|
|
130
|
+
const sum = adler32(data);
|
|
131
|
+
out[p++] = (sum >>> 24) & 0xff; // adler32, big endian
|
|
132
|
+
out[p++] = (sum >>> 16) & 0xff;
|
|
133
|
+
out[p++] = (sum >>> 8) & 0xff;
|
|
134
|
+
out[p++] = sum & 0xff;
|
|
135
|
+
return out.subarray(0, p);
|
|
150
136
|
}
|
|
151
|
-
|
|
152
137
|
/**
|
|
153
138
|
* Compress with whatever the platform provides, falling back to stored blocks.
|
|
154
139
|
*
|
|
@@ -156,52 +141,49 @@ export function deflateStored(data) {
|
|
|
156
141
|
* @returns {Promise<Uint8Array>}
|
|
157
142
|
*/
|
|
158
143
|
async function deflate(data) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
144
|
+
// Node: zlib is built in, so this is not a dependency.
|
|
145
|
+
if (typeof process !== 'undefined' && process.versions && process.versions.node) {
|
|
146
|
+
try {
|
|
147
|
+
const zlib = await import('node:zlib');
|
|
148
|
+
return new Uint8Array(zlib.deflateSync(data));
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
/* fall through */
|
|
152
|
+
}
|
|
166
153
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
154
|
+
// Browsers: CompressionStream('deflate') emits the zlib format PNG wants.
|
|
155
|
+
if (typeof CompressionStream === 'function') {
|
|
156
|
+
try {
|
|
157
|
+
const stream = new Blob([data]).stream().pipeThrough(new CompressionStream('deflate'));
|
|
158
|
+
const buffer = await new Response(stream).arrayBuffer();
|
|
159
|
+
return new Uint8Array(buffer);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
/* fall through */
|
|
163
|
+
}
|
|
177
164
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
return deflateStored(data);
|
|
165
|
+
return deflateStored(data);
|
|
181
166
|
}
|
|
182
|
-
|
|
183
167
|
/* ------------------------------------------------------------------ *
|
|
184
168
|
* PNG assembly
|
|
185
169
|
* ------------------------------------------------------------------ */
|
|
186
|
-
|
|
187
170
|
const SIGNATURE = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
|
|
188
|
-
|
|
189
171
|
/**
|
|
190
172
|
* @param {string} type Four ASCII characters.
|
|
191
173
|
* @param {Uint8Array} payload
|
|
192
174
|
* @returns {Uint8Array}
|
|
193
175
|
*/
|
|
194
176
|
function chunk(type, payload) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
177
|
+
const out = new Uint8Array(12 + payload.length);
|
|
178
|
+
const view = new DataView(out.buffer);
|
|
179
|
+
view.setUint32(0, payload.length);
|
|
180
|
+
for (let i = 0; i < 4; i++)
|
|
181
|
+
out[4 + i] = type.charCodeAt(i);
|
|
182
|
+
out.set(payload, 8);
|
|
183
|
+
// The CRC covers the type and the payload, but not the length.
|
|
184
|
+
view.setUint32(8 + payload.length, crc32(out.subarray(4, 8 + payload.length)));
|
|
185
|
+
return out;
|
|
203
186
|
}
|
|
204
|
-
|
|
205
187
|
/**
|
|
206
188
|
* Render to a PNG file.
|
|
207
189
|
*
|
|
@@ -210,72 +192,64 @@ function chunk(type, payload) {
|
|
|
210
192
|
* @returns {Promise<Uint8Array>}
|
|
211
193
|
*/
|
|
212
194
|
export async function toPNG(matrix, options = {}) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
195
|
+
const opts = normalizeOptions(matrix, options);
|
|
196
|
+
const { scale, source, pixelWidth, pixelHeight } = opts;
|
|
197
|
+
const dark = parseColor(opts.dark);
|
|
198
|
+
const light = parseColor(opts.light);
|
|
199
|
+
// --- Scanlines: filter byte 0, then one bit per pixel, MSB leftmost.
|
|
200
|
+
const bytesPerRow = (pixelWidth + 7) >> 3;
|
|
201
|
+
const raw = new Uint8Array((bytesPerRow + 1) * pixelHeight);
|
|
202
|
+
const rowBits = new Uint8Array(bytesPerRow);
|
|
203
|
+
for (let my = 0; my < source.height; my++) {
|
|
204
|
+
rowBits.fill(0);
|
|
205
|
+
for (let mx = 0; mx < source.width; mx++) {
|
|
206
|
+
if (!source.get(mx, my))
|
|
207
|
+
continue;
|
|
208
|
+
const from = mx * scale;
|
|
209
|
+
for (let px = from; px < from + scale; px++) {
|
|
210
|
+
rowBits[px >> 3] |= 0x80 >> (px & 7);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
for (let py = 0; py < scale; py++) {
|
|
214
|
+
const offset = (my * scale + py) * (bytesPerRow + 1);
|
|
215
|
+
raw[offset] = 0; // filter type 0 (None)
|
|
216
|
+
raw.set(rowBits, offset + 1);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// --- Chunks.
|
|
220
|
+
const ihdr = new Uint8Array(13);
|
|
221
|
+
const ihdrView = new DataView(ihdr.buffer);
|
|
222
|
+
ihdrView.setUint32(0, pixelWidth);
|
|
223
|
+
ihdrView.setUint32(4, pixelHeight);
|
|
224
|
+
ihdr[8] = 1; // bit depth
|
|
225
|
+
ihdr[9] = 3; // colour type 3: palette
|
|
226
|
+
ihdr[10] = 0; // compression: deflate
|
|
227
|
+
ihdr[11] = 0; // filter method
|
|
228
|
+
ihdr[12] = 0; // no interlace
|
|
229
|
+
// Palette index 0 is light (a clear module), index 1 is dark.
|
|
230
|
+
const plte = new Uint8Array([
|
|
231
|
+
light[0], light[1], light[2],
|
|
232
|
+
dark[0], dark[1], dark[2],
|
|
233
|
+
]);
|
|
234
|
+
const parts = [SIGNATURE, chunk('IHDR', ihdr), chunk('PLTE', plte)];
|
|
235
|
+
// tRNS is only emitted when something is actually translucent, so the common
|
|
236
|
+
// opaque case produces a file every decoder handles identically.
|
|
237
|
+
if (light[3] < 255 || dark[3] < 255) {
|
|
238
|
+
parts.push(chunk('tRNS', new Uint8Array([light[3], dark[3]])));
|
|
232
239
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
240
|
+
parts.push(chunk('IDAT', await deflate(raw)));
|
|
241
|
+
parts.push(chunk('IEND', new Uint8Array(0)));
|
|
242
|
+
let total = 0;
|
|
243
|
+
for (const part of parts)
|
|
244
|
+
total += part.length;
|
|
245
|
+
const file = new Uint8Array(total);
|
|
246
|
+
let offset = 0;
|
|
247
|
+
for (const part of parts) {
|
|
248
|
+
file.set(part, offset);
|
|
249
|
+
offset += part.length;
|
|
237
250
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
// --- Chunks.
|
|
241
|
-
const ihdr = new Uint8Array(13);
|
|
242
|
-
const ihdrView = new DataView(ihdr.buffer);
|
|
243
|
-
ihdrView.setUint32(0, pixelWidth);
|
|
244
|
-
ihdrView.setUint32(4, pixelHeight);
|
|
245
|
-
ihdr[8] = 1; // bit depth
|
|
246
|
-
ihdr[9] = 3; // colour type 3: palette
|
|
247
|
-
ihdr[10] = 0; // compression: deflate
|
|
248
|
-
ihdr[11] = 0; // filter method
|
|
249
|
-
ihdr[12] = 0; // no interlace
|
|
250
|
-
|
|
251
|
-
// Palette index 0 is light (a clear module), index 1 is dark.
|
|
252
|
-
const plte = new Uint8Array([
|
|
253
|
-
light[0], light[1], light[2],
|
|
254
|
-
dark[0], dark[1], dark[2],
|
|
255
|
-
]);
|
|
256
|
-
|
|
257
|
-
const parts = [SIGNATURE, chunk('IHDR', ihdr), chunk('PLTE', plte)];
|
|
258
|
-
|
|
259
|
-
// tRNS is only emitted when something is actually translucent, so the common
|
|
260
|
-
// opaque case produces a file every decoder handles identically.
|
|
261
|
-
if (light[3] < 255 || dark[3] < 255) {
|
|
262
|
-
parts.push(chunk('tRNS', new Uint8Array([light[3], dark[3]])));
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
parts.push(chunk('IDAT', await deflate(raw)));
|
|
266
|
-
parts.push(chunk('IEND', new Uint8Array(0)));
|
|
267
|
-
|
|
268
|
-
let total = 0;
|
|
269
|
-
for (const part of parts) total += part.length;
|
|
270
|
-
const file = new Uint8Array(total);
|
|
271
|
-
let offset = 0;
|
|
272
|
-
for (const part of parts) {
|
|
273
|
-
file.set(part, offset);
|
|
274
|
-
offset += part.length;
|
|
275
|
-
}
|
|
276
|
-
return file;
|
|
251
|
+
return file;
|
|
277
252
|
}
|
|
278
|
-
|
|
279
253
|
/**
|
|
280
254
|
* Render to a data URI usable as an `<img>` src or a download href.
|
|
281
255
|
*
|
|
@@ -284,12 +258,13 @@ export async function toPNG(matrix, options = {}) {
|
|
|
284
258
|
* @returns {Promise<string>}
|
|
285
259
|
*/
|
|
286
260
|
export async function toPNGDataURI(matrix, options = {}) {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
261
|
+
const bytes = await toPNG(matrix, options);
|
|
262
|
+
let binary = '';
|
|
263
|
+
for (let i = 0; i < bytes.length; i++)
|
|
264
|
+
binary += String.fromCharCode(bytes[i]);
|
|
265
|
+
const base64 = typeof btoa === 'function'
|
|
266
|
+
? btoa(binary)
|
|
267
|
+
/* eslint-disable-next-line no-undef */
|
|
268
|
+
: Buffer.from(bytes).toString('base64');
|
|
269
|
+
return 'data:image/png;base64,' + base64;
|
|
295
270
|
}
|
package/src/js/render/svg.js
CHANGED
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
*
|
|
28
28
|
* Original work. No code from any other barcode implementation.
|
|
29
29
|
*/
|
|
30
|
-
|
|
31
30
|
/**
|
|
32
31
|
* SVG output.
|
|
33
32
|
*
|
|
@@ -38,21 +37,18 @@
|
|
|
38
37
|
*
|
|
39
38
|
* @module render/svg
|
|
40
39
|
*/
|
|
41
|
-
|
|
42
40
|
import { normalizeOptions } from './options.js';
|
|
43
|
-
|
|
44
41
|
/**
|
|
45
42
|
* @param {string} value
|
|
46
43
|
* @returns {string}
|
|
47
44
|
*/
|
|
48
45
|
function escapeAttr(value) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
return String(value)
|
|
47
|
+
.replace(/&/g, '&')
|
|
48
|
+
.replace(/</g, '<')
|
|
49
|
+
.replace(/>/g, '>')
|
|
50
|
+
.replace(/"/g, '"');
|
|
54
51
|
}
|
|
55
|
-
|
|
56
52
|
/**
|
|
57
53
|
* Render to an SVG document.
|
|
58
54
|
*
|
|
@@ -61,34 +57,34 @@ function escapeAttr(value) {
|
|
|
61
57
|
* @returns {string}
|
|
62
58
|
*/
|
|
63
59
|
export function toSVG(matrix, options = {}) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
60
|
+
const opts = normalizeOptions(matrix, options);
|
|
61
|
+
const { scale, source, pixelWidth, pixelHeight, rowHeight } = opts;
|
|
62
|
+
let path = '';
|
|
63
|
+
for (let y = 0; y < source.height; y++) {
|
|
64
|
+
let x = 0;
|
|
65
|
+
while (x < source.width) {
|
|
66
|
+
if (!source.get(x, y)) {
|
|
67
|
+
x++;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
let run = 1;
|
|
71
|
+
while (x + run < source.width && source.get(x + run, y))
|
|
72
|
+
run++;
|
|
73
|
+
// Relative horizontal-vertical path commands: shorter than rects and
|
|
74
|
+
// free of the seams that appear between adjacent rects at some zooms.
|
|
75
|
+
path += `M${x * scale} ${y * rowHeight}h${run * scale}v${rowHeight}h${-run * scale}z`;
|
|
76
|
+
x += run;
|
|
77
|
+
}
|
|
78
78
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
bg +
|
|
88
|
-
`<path d="${path}" fill="${escapeAttr(opts.dark)}"/>` +
|
|
89
|
-
'</svg>';
|
|
79
|
+
const bg = opts.light === 'none'
|
|
80
|
+
? ''
|
|
81
|
+
: `<rect width="${pixelWidth}" height="${pixelHeight}" fill="${escapeAttr(opts.light)}"/>`;
|
|
82
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${pixelWidth}" height="${pixelHeight}" ` +
|
|
83
|
+
`viewBox="0 0 ${pixelWidth} ${pixelHeight}" shape-rendering="crispEdges">` +
|
|
84
|
+
bg +
|
|
85
|
+
`<path d="${path}" fill="${escapeAttr(opts.dark)}"/>` +
|
|
86
|
+
'</svg>';
|
|
90
87
|
}
|
|
91
|
-
|
|
92
88
|
/**
|
|
93
89
|
* Base64 that works identically in Node and the browser.
|
|
94
90
|
*
|
|
@@ -99,15 +95,16 @@ export function toSVG(matrix, options = {}) {
|
|
|
99
95
|
* @returns {string}
|
|
100
96
|
*/
|
|
101
97
|
function toBase64(text) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
98
|
+
const bytes = new TextEncoder().encode(text);
|
|
99
|
+
let binary = '';
|
|
100
|
+
for (let i = 0; i < bytes.length; i++)
|
|
101
|
+
binary += String.fromCharCode(bytes[i]);
|
|
102
|
+
if (typeof btoa === 'function')
|
|
103
|
+
return btoa(binary);
|
|
104
|
+
// Node before btoa was global, and non-browser embedders.
|
|
105
|
+
/* eslint-disable-next-line no-undef */
|
|
106
|
+
return Buffer.from(bytes).toString('base64');
|
|
109
107
|
}
|
|
110
|
-
|
|
111
108
|
/**
|
|
112
109
|
* Render to a data URI usable directly as an `<img>` src.
|
|
113
110
|
*
|
|
@@ -116,5 +113,5 @@ function toBase64(text) {
|
|
|
116
113
|
* @returns {string}
|
|
117
114
|
*/
|
|
118
115
|
export function toSVGDataURI(matrix, options = {}) {
|
|
119
|
-
|
|
116
|
+
return 'data:image/svg+xml;base64,' + toBase64(toSVG(matrix, options));
|
|
120
117
|
}
|