@sythos/js_barcode_universal 1.5.13 → 1.5.15
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 +22 -4
- package/NOTICE.md +10 -1
- package/README.md +416 -22
- package/bundle/sythos-barcode.esm.js +22176 -11991
- package/bundle/sythos-barcode.js +22059 -11991
- package/licenses/README.md +12 -1
- package/licenses/codablockf.license +51 -0
- package/licenses/code16k.license +52 -0
- package/licenses/code25.license +58 -0
- package/licenses/code32.license +51 -0
- package/licenses/dotcode.license +66 -0
- package/licenses/gs1-composite.license +106 -0
- package/licenses/gs1-databar.license +21 -14
- package/licenses/hanxin.license +95 -0
- package/licenses/maxicode.license +62 -0
- package/licenses/postal.license +61 -0
- package/licenses/pzn.license +53 -0
- package/licenses/telepen.license +73 -0
- package/llms.txt +62 -6
- package/package.json +47 -3
- package/src/index.d.ts +111 -6
- package/src/index.js +362 -13
- package/src/js/codablockf/decoder.js +198 -0
- package/src/js/codablockf/encoder.js +97 -0
- package/src/js/codablockf/index.js +3 -0
- package/src/js/code16k/decoder.js +303 -0
- package/src/js/code16k/detector.js +187 -0
- package/src/js/code16k/encoder.js +153 -0
- package/src/js/code16k/index.js +14 -0
- package/src/js/code16k/tables.js +152 -0
- package/src/js/composite/index.js +570 -0
- package/src/js/core/detection-contract.js +185 -0
- package/src/js/core/symbol-layout.js +155 -0
- package/src/js/databar/expanded.js +968 -0
- package/src/js/databar/index.js +4 -0
- package/src/js/databar/layout.js +192 -0
- package/src/js/databar/limited.js +533 -0
- package/src/js/databar/stacked-omnidirectional.js +548 -0
- package/src/js/databar/stacked.js +528 -0
- package/src/js/dotcode/decoder.js +548 -0
- package/src/js/dotcode/detector.js +251 -0
- package/src/js/dotcode/encoder.js +453 -0
- package/src/js/dotcode/index.js +34 -0
- package/src/js/dotcode/tables.js +168 -0
- package/src/js/hanxin/decoder.js +299 -0
- package/src/js/hanxin/detector.js +122 -0
- package/src/js/hanxin/encoder.js +259 -0
- package/src/js/hanxin/index.js +16 -0
- package/src/js/hanxin/tables.js +316 -0
- package/src/js/image/height-coded.js +164 -0
- package/src/js/maxicode/decoder.js +275 -0
- package/src/js/maxicode/detector.js +118 -0
- package/src/js/maxicode/encoder.js +438 -0
- package/src/js/maxicode/index.js +34 -0
- package/src/js/maxicode/tables.js +132 -0
- package/src/js/oned/code25.js +148 -0
- package/src/js/oned/index.js +21 -3
- package/src/js/oned/postal.js +889 -0
- package/src/js/oned/reader.js +272 -7
- package/src/js/oned/telepen.js +361 -0
- package/src/js/oned/writers.js +186 -12
- package/src/js/stacked128/common.js +208 -0
- package/src/ts/codablockf/decoder.ts +212 -0
- package/src/ts/codablockf/encoder.ts +128 -0
- package/src/ts/codablockf/index.d.ts +31 -0
- package/src/ts/codablockf/index.ts +6 -0
- package/src/ts/code16k/decoder.d.ts +25 -0
- package/src/ts/code16k/decoder.ts +313 -0
- package/src/ts/code16k/detector.d.ts +21 -0
- package/src/ts/code16k/detector.ts +203 -0
- package/src/ts/code16k/encoder.d.ts +26 -0
- package/src/ts/code16k/encoder.ts +198 -0
- package/src/ts/code16k/index.d.ts +10 -0
- package/src/ts/code16k/index.ts +47 -0
- package/src/ts/code16k/tables.d.ts +54 -0
- package/src/ts/code16k/tables.ts +195 -0
- package/src/ts/composite/index.d.ts +74 -0
- package/src/ts/composite/index.ts +547 -0
- package/src/ts/core/detection-contract.d.ts +119 -0
- package/src/ts/core/detection-contract.ts +267 -0
- package/src/ts/core/symbol-layout.d.ts +108 -0
- package/src/ts/core/symbol-layout.ts +236 -0
- package/src/ts/databar/expanded.d.ts +40 -0
- package/src/ts/databar/expanded.ts +948 -0
- package/src/ts/databar/index.d.ts +48 -0
- package/src/ts/databar/index.ts +48 -0
- package/src/ts/databar/layout.d.ts +122 -0
- package/src/ts/databar/layout.ts +275 -0
- package/src/ts/databar/limited.d.ts +85 -0
- package/src/ts/databar/limited.ts +553 -0
- package/src/ts/databar/stacked-omnidirectional.d.ts +128 -0
- package/src/ts/databar/stacked-omnidirectional.ts +559 -0
- package/src/ts/databar/stacked.d.ts +96 -0
- package/src/ts/databar/stacked.ts +549 -0
- package/src/ts/dotcode/decoder.d.ts +58 -0
- package/src/ts/dotcode/decoder.ts +467 -0
- package/src/ts/dotcode/detector.d.ts +63 -0
- package/src/ts/dotcode/detector.ts +263 -0
- package/src/ts/dotcode/encoder.d.ts +69 -0
- package/src/ts/dotcode/encoder.ts +427 -0
- package/src/ts/dotcode/index.d.ts +37 -0
- package/src/ts/dotcode/index.ts +72 -0
- package/src/ts/dotcode/tables.d.ts +74 -0
- package/src/ts/dotcode/tables.ts +174 -0
- package/src/ts/hanxin/decoder.d.ts +48 -0
- package/src/ts/hanxin/decoder.ts +314 -0
- package/src/ts/hanxin/detector.d.ts +45 -0
- package/src/ts/hanxin/detector.ts +124 -0
- package/src/ts/hanxin/encoder.d.ts +41 -0
- package/src/ts/hanxin/encoder.ts +290 -0
- package/src/ts/hanxin/index.d.ts +16 -0
- package/src/ts/hanxin/index.ts +18 -0
- package/src/ts/hanxin/tables.d.ts +80 -0
- package/src/ts/hanxin/tables.ts +348 -0
- package/src/ts/image/height-coded.d.ts +101 -0
- package/src/ts/image/height-coded.ts +227 -0
- package/src/ts/index.d.ts +46 -2
- package/src/ts/index.ts +380 -13
- package/src/ts/maxicode/decoder.ts +265 -0
- package/src/ts/maxicode/detector.ts +109 -0
- package/src/ts/maxicode/encoder.ts +414 -0
- package/src/ts/maxicode/index.d.ts +96 -0
- package/src/ts/maxicode/index.ts +44 -0
- package/src/ts/maxicode/tables.ts +136 -0
- package/src/ts/oned/code25.d.ts +42 -0
- package/src/ts/oned/code25.ts +170 -0
- package/src/ts/oned/index.d.ts +7 -2
- package/src/ts/oned/index.ts +45 -3
- package/src/ts/oned/postal.d.ts +44 -0
- package/src/ts/oned/postal.ts +819 -0
- package/src/ts/oned/reader.d.ts +35 -0
- package/src/ts/oned/reader.ts +261 -7
- package/src/ts/oned/telepen.d.ts +65 -0
- package/src/ts/oned/telepen.ts +368 -0
- package/src/ts/oned/writers.d.ts +32 -0
- package/src/ts/oned/writers.ts +184 -13
- package/src/ts/stacked128/common.ts +225 -0
package/src/js/oned/reader.js
CHANGED
|
@@ -48,9 +48,12 @@
|
|
|
48
48
|
*/
|
|
49
49
|
import { NotFoundError } from '../core/errors.js';
|
|
50
50
|
import { EAN_L, EAN_G, EAN_R, EAN13_PARITY, UPCE_PARITY, CODE39, CODE39_CHECK_SET, CODE93, CODE93_VALUES, CODE128, CODE128_START_A, CODE128_START_B, CODE128_START_C, CODE128_STOP, CODE128_FNC1, CODE128_CODE_A, CODE128_CODE_B, CODE128_CODE_C, CODE128_SHIFT, ITF, CODABAR, CODABAR_START_STOP, CODE11, CODE11_START_STOP, } from './patterns.js';
|
|
51
|
-
import { ean13CheckDigit, upceToUpcaBody } from './writers.js';
|
|
51
|
+
import { ean13CheckDigit, upceToUpcaBody, decodeCode32Payload, decodePZNPayload, } from './writers.js';
|
|
52
52
|
import { EAN2_PARITY, EAN5_PARITY, ean5Checksum, } from './addons.js';
|
|
53
53
|
import { decodeDataBar14Scanline } from '../databar/decoder.js';
|
|
54
|
+
import { decodeTelepen } from './telepen.js';
|
|
55
|
+
import { CODE25_DIGIT_PATTERNS, CODE25_VARIANTS, CODE25_MAX_DIGITS, code25CheckDigit, } from './code25.js';
|
|
56
|
+
import { decodePostal } from './postal.js';
|
|
54
57
|
/* ------------------------------------------------------------------ *
|
|
55
58
|
* Pattern matching primitives
|
|
56
59
|
* ------------------------------------------------------------------ */
|
|
@@ -936,6 +939,31 @@ function decodeCode39(row, options = {}) {
|
|
|
936
939
|
}
|
|
937
940
|
return { format: 'code39', text };
|
|
938
941
|
}
|
|
942
|
+
/** Decode Italian Code 32 after validating its Code 39/base-32 payload. */
|
|
943
|
+
export function decodeCode32(row) {
|
|
944
|
+
const base = decodeCode39(row);
|
|
945
|
+
if (!base)
|
|
946
|
+
return null;
|
|
947
|
+
const parsed = decodeCode32Payload(base.text);
|
|
948
|
+
return parsed
|
|
949
|
+
? { format: 'code32', text: parsed.text, checkDigit: true }
|
|
950
|
+
: null;
|
|
951
|
+
}
|
|
952
|
+
/** Decode PZN-7 or PZN-8 after validating its Code 39 payload/check digit. */
|
|
953
|
+
export function decodePZN(row) {
|
|
954
|
+
const base = decodeCode39(row);
|
|
955
|
+
if (!base)
|
|
956
|
+
return null;
|
|
957
|
+
const parsed = decodePZNPayload(base.text);
|
|
958
|
+
return parsed
|
|
959
|
+
? {
|
|
960
|
+
format: 'pzn',
|
|
961
|
+
text: parsed.text,
|
|
962
|
+
pznVariant: parsed.variant,
|
|
963
|
+
checkDigit: true,
|
|
964
|
+
}
|
|
965
|
+
: null;
|
|
966
|
+
}
|
|
939
967
|
/* ------------------------------------------------------------------ *
|
|
940
968
|
* Code 93
|
|
941
969
|
* ------------------------------------------------------------------ */
|
|
@@ -1068,6 +1096,161 @@ function decodeITF(row) {
|
|
|
1068
1096
|
return null;
|
|
1069
1097
|
return { format: 'itf', text: digits.join('') };
|
|
1070
1098
|
}
|
|
1099
|
+
/* ------------------------------------------------------------------ *
|
|
1100
|
+
* Code 25 family
|
|
1101
|
+
* ------------------------------------------------------------------ */
|
|
1102
|
+
/** Convert a Code 25 width description into the measured module widths. */
|
|
1103
|
+
function code25Widths(pattern, ratio) {
|
|
1104
|
+
return [...pattern].map((width) => Number(width) > 1 ? ratio : 1);
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Match a Code 25 guard or digit at an exact offset. The writer permits a
|
|
1108
|
+
* configurable wide-bar ratio, so a small bounded set of ratios is considered
|
|
1109
|
+
* while matching rather than assuming one printer's dimensions.
|
|
1110
|
+
*
|
|
1111
|
+
* @param {Uint8Array} row
|
|
1112
|
+
* @param {number} start
|
|
1113
|
+
* @param {string} pattern
|
|
1114
|
+
* @param {number|undefined} preferredRatio
|
|
1115
|
+
* @returns {{end:number, score:number, ratio:number}|null}
|
|
1116
|
+
*/
|
|
1117
|
+
function matchCode25(row, start, pattern, preferredRatio) {
|
|
1118
|
+
const counters = new Array(pattern.length).fill(0);
|
|
1119
|
+
if (!recordPattern(row, start, counters))
|
|
1120
|
+
return null;
|
|
1121
|
+
const candidates = preferredRatio
|
|
1122
|
+
? [preferredRatio]
|
|
1123
|
+
: [2, 3, 4, 5, 6, 7, 8];
|
|
1124
|
+
let best = null;
|
|
1125
|
+
for (const ratio of candidates) {
|
|
1126
|
+
const score = patternVariance(counters, code25Widths(pattern, ratio), 0.75);
|
|
1127
|
+
if (!Number.isFinite(score))
|
|
1128
|
+
continue;
|
|
1129
|
+
if (!best || score < best.score)
|
|
1130
|
+
best = { score, ratio };
|
|
1131
|
+
}
|
|
1132
|
+
if (!best || best.score >= 0.38)
|
|
1133
|
+
return null;
|
|
1134
|
+
return {
|
|
1135
|
+
end: start + counters.reduce((sum, width) => sum + width, 0),
|
|
1136
|
+
score: best.score,
|
|
1137
|
+
ratio: best.ratio,
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
/** Find the strongest Code 25 start guard in a scanline. */
|
|
1141
|
+
function findCode25Start(row, startPattern) {
|
|
1142
|
+
let best = null;
|
|
1143
|
+
for (let offset = 0; offset < row.length; offset++) {
|
|
1144
|
+
if (row[offset] !== 1 || (offset > 0 && row[offset - 1] === 1))
|
|
1145
|
+
continue;
|
|
1146
|
+
const found = matchCode25(row, offset, startPattern);
|
|
1147
|
+
if (found && (!best || found.score < best.score)) {
|
|
1148
|
+
best = { start: offset, ...found };
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
return best;
|
|
1152
|
+
}
|
|
1153
|
+
/**
|
|
1154
|
+
* Decode a Code 25/Industrial 2 of 5/IATA 2 of 5 scanline.
|
|
1155
|
+
*
|
|
1156
|
+
* Standard 2 of 5 and Industrial 2 of 5 intentionally share the canonical
|
|
1157
|
+
* industrial frame in this SDK; the public variant labels remain explicit so
|
|
1158
|
+
* callers can select the terminology used by their data source.
|
|
1159
|
+
*
|
|
1160
|
+
* @param {Uint8Array} row
|
|
1161
|
+
* @param {'standard'|'industrial'|'iata'} variant
|
|
1162
|
+
* @param {object} options
|
|
1163
|
+
* @returns {{format:'industrial2of5'|'iata2of5',text:string,checkDigit:boolean}|null}
|
|
1164
|
+
*/
|
|
1165
|
+
function decodeCode25Variant(row, variant, options = {}) {
|
|
1166
|
+
const profile = CODE25_VARIANTS[variant];
|
|
1167
|
+
const start = findCode25Start(row, profile.start);
|
|
1168
|
+
if (!start)
|
|
1169
|
+
return null;
|
|
1170
|
+
let offset = start.end;
|
|
1171
|
+
let digits = '';
|
|
1172
|
+
let stop = null;
|
|
1173
|
+
// The IATA start guard is all narrow bars and therefore carries no ratio
|
|
1174
|
+
// information. Infer its ratio from the first data digit instead of
|
|
1175
|
+
// hard-coding the first candidate (which would make a 3:1 symbol look like
|
|
1176
|
+
// a truncated stop pattern).
|
|
1177
|
+
let ratio = variant === 'iata' ? undefined : start.ratio;
|
|
1178
|
+
const counters = new Array(10).fill(0);
|
|
1179
|
+
for (let count = 0; count < CODE25_MAX_DIGITS; count++) {
|
|
1180
|
+
const candidateStop = matchCode25(row, offset, profile.stop, ratio);
|
|
1181
|
+
const stopGap = candidateStop
|
|
1182
|
+
? (() => {
|
|
1183
|
+
let nextDark = candidateStop.end;
|
|
1184
|
+
while (nextDark < row.length && row[nextDark] === 0)
|
|
1185
|
+
nextDark++;
|
|
1186
|
+
return nextDark === row.length ? Infinity : nextDark - candidateStop.end;
|
|
1187
|
+
})()
|
|
1188
|
+
: 0;
|
|
1189
|
+
if (candidateStop && stopGap >= Math.max(3, Math.ceil((ratio ?? candidateStop.ratio) * 3))) {
|
|
1190
|
+
stop = candidateStop;
|
|
1191
|
+
break;
|
|
1192
|
+
}
|
|
1193
|
+
if (!recordPattern(row, offset, counters))
|
|
1194
|
+
return null;
|
|
1195
|
+
let bestDigit = null;
|
|
1196
|
+
for (let digit = 0; digit < CODE25_DIGIT_PATTERNS.length; digit++) {
|
|
1197
|
+
const candidates = ratio ? [ratio] : [2, 3, 4, 5, 6, 7, 8];
|
|
1198
|
+
for (const candidateRatio of candidates) {
|
|
1199
|
+
const score = patternVariance(counters, code25Widths(CODE25_DIGIT_PATTERNS[digit], candidateRatio), 0.75);
|
|
1200
|
+
if (!Number.isFinite(score))
|
|
1201
|
+
continue;
|
|
1202
|
+
if (!bestDigit || score < bestDigit.score) {
|
|
1203
|
+
bestDigit = { digit, score, ratio: candidateRatio };
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
if (!bestDigit || bestDigit.score >= 0.38)
|
|
1208
|
+
return null;
|
|
1209
|
+
ratio ?? (ratio = bestDigit.ratio);
|
|
1210
|
+
digits += String(bestDigit.digit);
|
|
1211
|
+
offset += counters.reduce((sum, width) => sum + width, 0);
|
|
1212
|
+
}
|
|
1213
|
+
if (!stop || digits.length === 0)
|
|
1214
|
+
return null;
|
|
1215
|
+
const stopEnd = stop.end;
|
|
1216
|
+
let nextDark = stopEnd;
|
|
1217
|
+
while (nextDark < row.length && row[nextDark] === 0)
|
|
1218
|
+
nextDark++;
|
|
1219
|
+
if (nextDark !== row.length && nextDark - stopEnd < Math.max(3, Math.ceil(start.ratio * 3))) {
|
|
1220
|
+
return null;
|
|
1221
|
+
}
|
|
1222
|
+
let checkDigit = false;
|
|
1223
|
+
if (options.checkDigit === true || options.profile === 'camera') {
|
|
1224
|
+
if (digits.length < 2)
|
|
1225
|
+
return null;
|
|
1226
|
+
const body = digits.slice(0, -1);
|
|
1227
|
+
if (code25CheckDigit(body) !== Number(digits.at(-1)))
|
|
1228
|
+
return null;
|
|
1229
|
+
digits = body;
|
|
1230
|
+
checkDigit = true;
|
|
1231
|
+
}
|
|
1232
|
+
return {
|
|
1233
|
+
format: profile.id,
|
|
1234
|
+
text: digits,
|
|
1235
|
+
checkDigit,
|
|
1236
|
+
};
|
|
1237
|
+
}
|
|
1238
|
+
/** Decode the canonical Standard/Industrial 2 of 5 frame. */
|
|
1239
|
+
export function decodeIndustrial2of5(row, options = {}) {
|
|
1240
|
+
return decodeCode25Variant(row, 'industrial', options);
|
|
1241
|
+
}
|
|
1242
|
+
/** Decode IATA 2 of 5 with its shorter guard frame. */
|
|
1243
|
+
export function decodeIATA2of5(row, options = {}) {
|
|
1244
|
+
return decodeCode25Variant(row, 'iata', options);
|
|
1245
|
+
}
|
|
1246
|
+
/** Decode the canonical Standard 2 of 5 frame. */
|
|
1247
|
+
export function decodeStandard2of5(row, options = {}) {
|
|
1248
|
+
return decodeCode25Variant(row, 'standard', options);
|
|
1249
|
+
}
|
|
1250
|
+
/** Decode any Code 25 family frame using the canonical Standard profile. */
|
|
1251
|
+
export function decodeCode25(row, options = {}) {
|
|
1252
|
+
return decodeCode25Variant(row, 'standard', options);
|
|
1253
|
+
}
|
|
1071
1254
|
/* ------------------------------------------------------------------ *
|
|
1072
1255
|
* Codabar
|
|
1073
1256
|
* ------------------------------------------------------------------ */
|
|
@@ -1147,9 +1330,15 @@ const DECODERS = [
|
|
|
1147
1330
|
['code128', decodeCode128],
|
|
1148
1331
|
['code11', decodeCode11],
|
|
1149
1332
|
['msi', decodeMSI],
|
|
1333
|
+
['telepen', decodeTelepen],
|
|
1334
|
+
['telepennumeric', (row, options = {}) => decodeTelepen(row, { ...options, numeric: true })],
|
|
1150
1335
|
['gs1databar14', decodeDataBar14Scanline],
|
|
1336
|
+
['code32', decodeCode32],
|
|
1337
|
+
['pzn', decodePZN],
|
|
1151
1338
|
['code39', decodeCode39],
|
|
1152
1339
|
['code93', decodeCode93],
|
|
1340
|
+
['industrial2of5', decodeIndustrial2of5],
|
|
1341
|
+
['iata2of5', decodeIATA2of5],
|
|
1153
1342
|
['itf', decodeITF],
|
|
1154
1343
|
['codabar', decodeCodabar],
|
|
1155
1344
|
];
|
|
@@ -1195,7 +1384,7 @@ function cameraRowGeometry(row) {
|
|
|
1195
1384
|
};
|
|
1196
1385
|
}
|
|
1197
1386
|
/** @param {string} format @param {object} options @returns {boolean|null} */
|
|
1198
|
-
function checksumStatus(format, options) {
|
|
1387
|
+
function checksumStatus(format, options, result = null) {
|
|
1199
1388
|
if (format === 'ean13' || format === 'ean8' || format === 'upca' || format === 'upce' ||
|
|
1200
1389
|
format === 'code93' || format === 'code128' || format === 'gs1128' ||
|
|
1201
1390
|
format === 'gs1databar14')
|
|
@@ -1203,11 +1392,21 @@ function checksumStatus(format, options) {
|
|
|
1203
1392
|
if (format === 'code11' || format === 'msi' || format === 'code39') {
|
|
1204
1393
|
return options.profile === 'camera' || options.checkDigit === true ? true : null;
|
|
1205
1394
|
}
|
|
1395
|
+
if (format === 'code32' || format === 'pzn')
|
|
1396
|
+
return true;
|
|
1397
|
+
if (format === 'industrial2of5' || format === 'iata2of5') {
|
|
1398
|
+
return result?.checkDigit === true ? true : null;
|
|
1399
|
+
}
|
|
1400
|
+
if (format === 'telepen' || format === 'telepennumeric')
|
|
1401
|
+
return true;
|
|
1402
|
+
if (format === 'postnet' || format === 'planet' || format === 'rm4scc'
|
|
1403
|
+
|| format === 'auspost' || format === 'japanpost' || format === 'imb')
|
|
1404
|
+
return true;
|
|
1206
1405
|
return null;
|
|
1207
1406
|
}
|
|
1208
1407
|
/** @param {object} result @param {object} geometry @param {Set<number>} rows @param {object} options @returns {object} */
|
|
1209
1408
|
function cameraMetadata(result, geometry, rows, options) {
|
|
1210
|
-
const checksum = checksumStatus(result.format, options);
|
|
1409
|
+
const checksum = checksumStatus(result.format, options, result);
|
|
1211
1410
|
const consistency = Math.min(1, rows.size / 3);
|
|
1212
1411
|
const confidence = Math.min(1, 0.4 + (geometry.quietZone ? 0.2 : 0) +
|
|
1213
1412
|
(checksum === true ? 0.2 : 0) + consistency * 0.2);
|
|
@@ -1241,10 +1440,28 @@ export function decodeOneD(image, options = {}) {
|
|
|
1241
1440
|
const cameraProfile = profile === 'camera';
|
|
1242
1441
|
const enabled = formats ? new Set(formats) : null;
|
|
1243
1442
|
const active = DECODERS.filter(([id]) => {
|
|
1443
|
+
// Telepen Numeric uses the same guards as Telepen Alpha and is therefore
|
|
1444
|
+
// only attempted when the caller explicitly requests the numeric mode.
|
|
1445
|
+
// Auto-detecting it as ASCII would turn valid digit pairs into plausible
|
|
1446
|
+
// but incorrect control characters.
|
|
1244
1447
|
if (!enabled)
|
|
1245
|
-
return
|
|
1448
|
+
return id !== 'telepennumeric';
|
|
1246
1449
|
if (enabled.has(id))
|
|
1247
1450
|
return true;
|
|
1451
|
+
if (id === 'telepen')
|
|
1452
|
+
return enabled.has('telepen-alpha');
|
|
1453
|
+
if (id === 'telepennumeric')
|
|
1454
|
+
return enabled.has('telepen-numeric');
|
|
1455
|
+
if (id === 'code32')
|
|
1456
|
+
return enabled.has('italian-pharmacode');
|
|
1457
|
+
if (id === 'pzn')
|
|
1458
|
+
return enabled.has('pzn7') || enabled.has('pzn8');
|
|
1459
|
+
if (id === 'industrial2of5') {
|
|
1460
|
+
return enabled.has('code2of5') || enabled.has('standard2of5')
|
|
1461
|
+
|| enabled.has('standard-2-of-5') || enabled.has('industrial-2-of-5');
|
|
1462
|
+
}
|
|
1463
|
+
if (id === 'iata2of5')
|
|
1464
|
+
return enabled.has('iata-2-of-5');
|
|
1248
1465
|
if (id === 'ean13' || id === 'ean8' || id === 'upca' || id === 'upce') {
|
|
1249
1466
|
return enabled.has('ean2') || enabled.has('ean5') ||
|
|
1250
1467
|
(id === 'ean13' && enabled.has('isbn'));
|
|
@@ -1255,10 +1472,27 @@ export function decodeOneD(image, options = {}) {
|
|
|
1255
1472
|
return enabled.has('databar') || enabled.has('gs1-databar14');
|
|
1256
1473
|
return false;
|
|
1257
1474
|
});
|
|
1258
|
-
if (active.length === 0)
|
|
1259
|
-
return [];
|
|
1260
1475
|
const results = [];
|
|
1261
1476
|
const seen = new Set();
|
|
1477
|
+
// Postal symbols carry information in the vertical bar state rather than
|
|
1478
|
+
// in a horizontal run-width alphabet. Decode that shared path once before
|
|
1479
|
+
// the ordinary scanline readers; an explicit non-postal filter yields no
|
|
1480
|
+
// postal attempt and therefore cannot broaden a caller's format request.
|
|
1481
|
+
const postalResults = decodePostal(image, {
|
|
1482
|
+
...options,
|
|
1483
|
+
profile: cameraProfile ? 'camera' : undefined,
|
|
1484
|
+
formats: formats ? formats : undefined,
|
|
1485
|
+
});
|
|
1486
|
+
const postalRow = image.height >> 1;
|
|
1487
|
+
for (const result of postalResults) {
|
|
1488
|
+
const key = `${result.format}:${result.text}`;
|
|
1489
|
+
if (seen.has(key))
|
|
1490
|
+
continue;
|
|
1491
|
+
seen.add(key);
|
|
1492
|
+
results.push({ ...result, row: postalRow });
|
|
1493
|
+
}
|
|
1494
|
+
if (active.length === 0)
|
|
1495
|
+
return results;
|
|
1262
1496
|
const height = image.height;
|
|
1263
1497
|
const buffer = new Uint8Array(image.width);
|
|
1264
1498
|
const cameraCandidates = new Map();
|
|
@@ -1280,7 +1514,8 @@ export function decodeOneD(image, options = {}) {
|
|
|
1280
1514
|
try {
|
|
1281
1515
|
// Code 11 and MSI checks are optional in their base standards, but
|
|
1282
1516
|
// a camera frame cannot safely promote their short unchecked forms.
|
|
1283
|
-
const decoderOptions = cameraProfile && (id === 'code11' || id === 'msi'
|
|
1517
|
+
const decoderOptions = cameraProfile && (id === 'code11' || id === 'msi'
|
|
1518
|
+
|| id === 'industrial2of5' || id === 'iata2of5')
|
|
1284
1519
|
? { ...options, checkDigit: true }
|
|
1285
1520
|
: options;
|
|
1286
1521
|
result = decoder(scan, decoderOptions);
|
|
@@ -1317,6 +1552,36 @@ export function decodeOneD(image, options = {}) {
|
|
|
1317
1552
|
if (!enabled.has('gs1databar14') && !enabled.has('databar') && !enabled.has('gs1-databar14'))
|
|
1318
1553
|
continue;
|
|
1319
1554
|
}
|
|
1555
|
+
else if (result.format === 'telepen') {
|
|
1556
|
+
if (!enabled.has('telepen') && !enabled.has('telepen-alpha'))
|
|
1557
|
+
continue;
|
|
1558
|
+
}
|
|
1559
|
+
else if (result.format === 'telepennumeric') {
|
|
1560
|
+
if (!enabled.has('telepennumeric') && !enabled.has('telepen-numeric'))
|
|
1561
|
+
continue;
|
|
1562
|
+
}
|
|
1563
|
+
else if (result.format === 'code32') {
|
|
1564
|
+
if (!enabled.has('code32') && !enabled.has('italian-pharmacode'))
|
|
1565
|
+
continue;
|
|
1566
|
+
}
|
|
1567
|
+
else if (result.format === 'pzn') {
|
|
1568
|
+
if (!enabled.has('pzn') && !enabled.has('pzn7') && !enabled.has('pzn8'))
|
|
1569
|
+
continue;
|
|
1570
|
+
if (enabled.has('pzn7') && result.pznVariant !== 'pzn7')
|
|
1571
|
+
continue;
|
|
1572
|
+
if (enabled.has('pzn8') && result.pznVariant !== 'pzn8')
|
|
1573
|
+
continue;
|
|
1574
|
+
}
|
|
1575
|
+
else if (result.format === 'industrial2of5') {
|
|
1576
|
+
if (!enabled.has('industrial2of5') && !enabled.has('industrial-2-of-5')
|
|
1577
|
+
&& !enabled.has('code2of5') && !enabled.has('standard2of5')
|
|
1578
|
+
&& !enabled.has('standard-2-of-5'))
|
|
1579
|
+
continue;
|
|
1580
|
+
}
|
|
1581
|
+
else if (result.format === 'iata2of5') {
|
|
1582
|
+
if (!enabled.has('iata2of5') && !enabled.has('iata-2-of-5'))
|
|
1583
|
+
continue;
|
|
1584
|
+
}
|
|
1320
1585
|
else if (!enabled.has(result.format)) {
|
|
1321
1586
|
continue;
|
|
1322
1587
|
}
|