mirror of
https://github.com/serratus/quaggaJS.git
synced 2026-08-12 21:21:42 +08:00
Initial commit on EAN supplements; Relates to #71
This commit is contained in:
@@ -7,12 +7,16 @@ import Code39VINReader from '../reader/code_39_vin_reader';
|
||||
import CodabarReader from '../reader/codabar_reader';
|
||||
import UPCReader from '../reader/upc_reader';
|
||||
import EAN8Reader from '../reader/ean_8_reader';
|
||||
import EAN2Reader from '../reader/ean_2_reader';
|
||||
import EAN5Reader from '../reader/ean_5_reader';
|
||||
import UPCEReader from '../reader/upc_e_reader';
|
||||
import I2of5Reader from '../reader/i2of5_reader';
|
||||
|
||||
const READERS = {
|
||||
code_128_reader: Code128Reader,
|
||||
ean_reader: EANReader,
|
||||
ean_5_reader: EAN5Reader,
|
||||
ean_2_reader: EAN2Reader,
|
||||
ean_8_reader: EAN8Reader,
|
||||
code_39_reader: Code39Reader,
|
||||
code_39_vin_reader: Code39VINReader,
|
||||
@@ -74,7 +78,8 @@ export default {
|
||||
function initReaders() {
|
||||
config.readers.forEach(function(readerConfig) {
|
||||
var reader,
|
||||
configuration = {};
|
||||
configuration = {},
|
||||
supplements = [];
|
||||
|
||||
if (typeof readerConfig === 'object') {
|
||||
reader = readerConfig.format;
|
||||
@@ -85,7 +90,13 @@ export default {
|
||||
if (ENV.development) {
|
||||
console.log("Before registering reader: ", reader);
|
||||
}
|
||||
_barcodeReaders.push(new READERS[reader](configuration));
|
||||
if (configuration.supplements) {
|
||||
supplements = configuration
|
||||
.supplements.map((supplement) => {
|
||||
return new READERS[supplement]();
|
||||
});
|
||||
}
|
||||
_barcodeReaders.push(new READERS[reader](configuration, supplements));
|
||||
});
|
||||
if (ENV.development) {
|
||||
console.log("Registered Readers: " + _barcodeReaders
|
||||
@@ -243,7 +254,7 @@ export default {
|
||||
line = getLine(box);
|
||||
lineLength = getLineLength(line);
|
||||
lineAngle = Math.atan2(line[1].y - line[0].y, line[1].x - line[0].x);
|
||||
line = getExtendedLine(line, lineAngle, Math.floor(lineLength * 0.1));
|
||||
line = getExtendedLine(line, lineAngle, Math.floor(lineLength * 0.2));
|
||||
if (line === null){
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
function BarcodeReader(config) {
|
||||
function BarcodeReader(config, supplements) {
|
||||
this._row = [];
|
||||
this.config = config || {};
|
||||
this.supplements = supplements;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import EANReader from './ean_reader';
|
||||
|
||||
function EAN2Reader() {
|
||||
EANReader.call(this);
|
||||
}
|
||||
|
||||
var properties = {
|
||||
FORMAT: {value: "ean_2", writeable: false}
|
||||
};
|
||||
|
||||
EAN2Reader.prototype = Object.create(EANReader.prototype, properties);
|
||||
EAN2Reader.prototype.constructor = EAN2Reader;
|
||||
|
||||
EAN2Reader.prototype.decode = function(row, start) {
|
||||
this._row = row;
|
||||
var counters = [0, 0, 0, 0],
|
||||
codeFrequency = 0,
|
||||
i = 0,
|
||||
offset = start,
|
||||
end = this._row.length,
|
||||
code,
|
||||
result = [];
|
||||
|
||||
for (i = 0; i < 2 && offset < end; i++) {
|
||||
code = this._decodeCode(offset);
|
||||
if (!code) {
|
||||
return null;
|
||||
}
|
||||
result.push(code.code % 10);
|
||||
if (code.code >= this.CODE_G_START) {
|
||||
codeFrequency |= 1 << (1 - i);
|
||||
}
|
||||
if (i != 1) {
|
||||
offset = this._nextSet(this._row, code.end);
|
||||
offset = this._nextUnset(this._row, offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (result.length != 2 || (result.reduce((sum, i) => sum + i, 0) % 4 !== codeFrequency)) {
|
||||
return null;
|
||||
}
|
||||
console.log(result);
|
||||
return offset;
|
||||
};
|
||||
|
||||
export default EAN2Reader;
|
||||
@@ -0,0 +1,79 @@
|
||||
import EANReader from './ean_reader';
|
||||
|
||||
function EAN5Reader() {
|
||||
EANReader.call(this);
|
||||
}
|
||||
|
||||
var properties = {
|
||||
FORMAT: {value: "ean_5", writeable: false}
|
||||
};
|
||||
|
||||
const CHECK_DIGIT_ENCODINGS = [24, 20, 18, 17, 12, 6, 3, 10, 9, 5];
|
||||
|
||||
EAN5Reader.prototype = Object.create(EANReader.prototype, properties);
|
||||
EAN5Reader.prototype.constructor = EAN5Reader;
|
||||
|
||||
EAN5Reader.prototype.decode = function(row, start) {
|
||||
this._row = row;
|
||||
var counters = [0, 0, 0, 0],
|
||||
codeFrequency = 0,
|
||||
i = 0,
|
||||
offset = start,
|
||||
end = this._row.length,
|
||||
code,
|
||||
result = [];
|
||||
|
||||
for (i = 0; i < 5 && offset < end; i++) {
|
||||
code = this._decodeCode(offset);
|
||||
if (!code) {
|
||||
return null;
|
||||
}
|
||||
result.push(code.code % 10);
|
||||
if (code.code >= this.CODE_G_START) {
|
||||
codeFrequency |= 1 << (4 - i);
|
||||
}
|
||||
if (i != 4) {
|
||||
offset = this._nextSet(this._row, code.end);
|
||||
offset = this._nextUnset(this._row, offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (result.length != 5) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (extensionChecksum(result) !== determineCheckDigit(codeFrequency)) {
|
||||
return null;
|
||||
}
|
||||
console.log(result);
|
||||
return offset;
|
||||
};
|
||||
|
||||
function determineCheckDigit(codeFrequency) {
|
||||
var i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (codeFrequency === CHECK_DIGIT_ENCODINGS[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
function extensionChecksum(result) {
|
||||
var length = result.length,
|
||||
sum = 0,
|
||||
i;
|
||||
|
||||
for (i = length - 2; i >= 0; i -= 2) {
|
||||
sum += result[i];
|
||||
}
|
||||
sum *= 3;
|
||||
for (i = length - 1; i >= 0; i -= 2) {
|
||||
sum += result[i];
|
||||
}
|
||||
sum *= 3;
|
||||
return sum % 10;
|
||||
}
|
||||
|
||||
export default EAN5Reader;
|
||||
@@ -1,7 +1,18 @@
|
||||
import BarcodeReader from './barcode_reader';
|
||||
import {merge} from 'lodash';
|
||||
|
||||
function EANReader(opts) {
|
||||
BarcodeReader.call(this, opts);
|
||||
function EANReader(opts, supplements) {
|
||||
opts = merge(getDefaulConfig(), opts);
|
||||
BarcodeReader.call(this, opts, supplements);
|
||||
}
|
||||
|
||||
function getDefaulConfig() {
|
||||
var config = {};
|
||||
|
||||
Object.keys(EANReader.CONFIG_KEYS).forEach(function(key) {
|
||||
config[key] = EANReader.CONFIG_KEYS[key].default;
|
||||
});
|
||||
return config;
|
||||
}
|
||||
|
||||
var properties = {
|
||||
@@ -11,6 +22,7 @@ var properties = {
|
||||
START_PATTERN: {value: [1 / 3 * 7, 1 / 3 * 7, 1 / 3 * 7]},
|
||||
STOP_PATTERN: {value: [1 / 3 * 7, 1 / 3 * 7, 1 / 3 * 7]},
|
||||
MIDDLE_PATTERN: {value: [1 / 5 * 7, 1 / 5 * 7, 1 / 5 * 7, 1 / 5 * 7, 1 / 5 * 7]},
|
||||
EXTENSION_START_PATTERN: {value: [1 / 4 * 7, 1 / 4 * 7, 2 / 4 * 7]},
|
||||
CODE_PATTERN: {value: [
|
||||
[3, 2, 1, 1],
|
||||
[2, 2, 2, 1],
|
||||
@@ -301,6 +313,13 @@ EANReader.prototype._decode = function() {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.supplements.length > 0) {
|
||||
let ext = this._decodeExtensions(code.end);
|
||||
if (!ext) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
code: result.join(""),
|
||||
start: startInfo.start,
|
||||
@@ -311,6 +330,25 @@ EANReader.prototype._decode = function() {
|
||||
};
|
||||
};
|
||||
|
||||
EANReader.prototype._decodeExtensions = function(offset) {
|
||||
var i,
|
||||
start = this._nextSet(this._row, offset),
|
||||
code = this._findPattern(this.EXTENSION_START_PATTERN, start, false, false),
|
||||
result;
|
||||
|
||||
if (code === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (i = 0; i < this.supplements.length; i++) {
|
||||
result = this.supplements[i].decode(this._row, code.end);
|
||||
if (result !== null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
EANReader.prototype._checksum = function(result) {
|
||||
var sum = 0, i;
|
||||
|
||||
@@ -324,4 +362,12 @@ EANReader.prototype._checksum = function(result) {
|
||||
return sum % 10 === 0;
|
||||
};
|
||||
|
||||
EANReader.CONFIG_KEYS = {
|
||||
supplements: {
|
||||
'type': 'arrayOf(string)',
|
||||
'default': [],
|
||||
'description': 'Allowed extensions to be decoded (2 and/or 5)'
|
||||
}
|
||||
};
|
||||
|
||||
export default (EANReader);
|
||||
|
||||
Reference in New Issue
Block a user