Merged master

pull/65/head
Christoph Oberhofer 10 years ago
commit 9fe7db25b0

@ -1,17 +1,17 @@
quaggaJS quaggaJS
======== ========
- [Changelog](#changelog) (2015-07-08) - [Changelog](#changelog) (2015-08-13)
## What is QuaggaJS? ## What is QuaggaJS?
QuaggaJS is a barcode-scanner entirely written in JavaScript supporting real- QuaggaJS is a barcode-scanner entirely written in JavaScript supporting real-
time localization and decoding of various types of barcodes such as __EAN__, time localization and decoding of various types of barcodes such as __EAN__,
__CODE 128__, __CODE 39__, __EAN 8__, __UPC-A__, __UPC-C__ and __CODABAR__. __CODE 128__, __CODE 39__, __EAN 8__, __UPC-A__, __UPC-C__, __I2of5__ and
The library is also capable of using `getUserMedia` to get direct access to __CODABAR__. The library is also capable of using `getUserMedia` to get direct
the user's camera stream. Although the code relies on heavy image-processing access to the user's camera stream. Although the code relies on heavy image-
even recent smartphones are capable of locating and decoding barcodes in processing even recent smartphones are capable of locating and decoding
real-time. barcodes in real-time.
Try some [examples](http://serratus.github.io/quaggaJS/examples) and check out Try some [examples](http://serratus.github.io/quaggaJS/examples) and check out
the blog post ([How barcode-localization works in QuaggaJS][oberhofer_co_how]) the blog post ([How barcode-localization works in QuaggaJS][oberhofer_co_how])
@ -141,6 +141,16 @@ In contrast to the calls described above, this method does not rely on
`getUserMedia` and operates on a single image instead. The provided callback `getUserMedia` and operates on a single image instead. The provided callback
is the same as in `onDetected` and contains the result `data` object. is the same as in `onDetected` and contains the result `data` object.
### Quagga.offProcessed(handler)
In case the `onProcessed` event is no longer relevant, `offProcessed` removes
the given `handler` from the event-queue.
### Quagga.offDetected(handler)
In case the `onDetected` event is no longer relevant, `offDetected` removes
the given `handler` from the event-queue.
## <a name="resultobject">The result object</a> ## <a name="resultobject">The result object</a>
The callbacks passed into `onProcessed`, `onDetected` and `decodeSingle` The callbacks passed into `onProcessed`, `onDetected` and `decodeSingle`
@ -367,6 +377,15 @@ on the ``singleChannel`` flag in the configuration when using ``decodeSingle``.
## <a name="changelog">Changelog</a> ## <a name="changelog">Changelog</a>
### 2015-08-13
- Improvements
- Added `offProcessed` and `offDetected` methods for detaching event-
listeners from the event-queue.
### 2015-07-29
- Features
- Added basic support for [ITF][i2of5_wiki] barcodes (`i2of5_reader`)
### 2015-07-08 ### 2015-07-08
- Improvements - Improvements
- Parameter tweaking to reduce false-positives significantly (for the - Parameter tweaking to reduce false-positives significantly (for the
@ -479,3 +498,4 @@ introduced to the API.
[ean_8_wiki]: http://en.wikipedia.org/wiki/EAN-8 [ean_8_wiki]: http://en.wikipedia.org/wiki/EAN-8
[oberhofer_co_how]: http://www.oberhofer.co/how-barcode-localization-works-in-quaggajs/ [oberhofer_co_how]: http://www.oberhofer.co/how-barcode-localization-works-in-quaggajs/
[github_examples]: http://serratus.github.io/quaggaJS/examples [github_examples]: http://serratus.github.io/quaggaJS/examples
[i2of5_wiki]: https://en.wikipedia.org/wiki/Interleaved_2_of_5

@ -0,0 +1,68 @@
{
"name": "quagga",
"version": "0.6.14",
"description": "An advanced barcode-scanner written in JavaScript",
"main": "dist/quagga.js",
"ignore": [
"build",
"doc",
"spec",
"src",
"tasks",
"test",
".gitignore",
".npmignore",
"Gruntfile.js",
"karma-integration.conf.js",
"karma.conf.js",
"package.json",
"test-main.js"
],
"devDependencies": {
"async": "^0.9.0",
"grunt": "~0.4.5",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-nodeunit": "~0.4.1",
"grunt-contrib-uglify": "~0.5.0",
"grunt-karma": "^0.9.0",
"grunt-requirejs": "^0.4.2",
"karma": "latest",
"karma-chai": "latest",
"karma-chrome-launcher": "^0.1.12",
"karma-coverage": "^0.3.1",
"karma-mocha": "latest",
"karma-phantomjs-launcher": "^0.1.4",
"karma-requirejs": "^0.2.2",
"karma-sinon": "^1.0.4",
"karma-sinon-chai": "^0.2.0",
"sinon": "^1.12.1"
},
"directories": {
"doc": "doc"
},
"scripts": {
"test": "karma start"
},
"repository": {
"type": "git",
"url": "https://github.com/serratus/quaggaJS.git"
},
"bugs": {
"url": "https://github.com/serratus/quaggaJS/issues"
},
"keywords": [
"quagga",
"quaggajs",
"barcode",
"ean",
"code128",
"code39",
"codabar",
"i2of5",
"upc",
"getusermedia",
"imageprocessing"
],
"author": "Christoph Oberhofer <ch.oberhofer@gmail.com>",
"license": "MIT"
}

10647
dist/quagga.js vendored

File diff suppressed because it is too large Load Diff

11
dist/quagga.min.js vendored

File diff suppressed because one or more lines are too long

@ -116,12 +116,13 @@ define(['quagga'], function(Quagga) {
singleChannel: false singleChannel: false
}, },
locator: { locator: {
patchSize: "medium", patchSize: "large",
halfSample: true halfSample: true,
showCanvas: true
}, },
numOfWorkers: 0, numOfWorkers: 0,
decoder: { decoder: {
readers: ["code_128_reader"], readers: ["i2of5_reader"],
showFrequency: true, showFrequency: true,
showPattern: true showPattern: true
}, },

@ -41,6 +41,7 @@
<option value="upc">UPC</option> <option value="upc">UPC</option>
<option value="upc_e">UPC-E</option> <option value="upc_e">UPC-E</option>
<option value="codabar">Codabar</option> <option value="codabar">Codabar</option>
<option value="i2of5">I2of5</option>
</select> </select>
</label> </label>
<label> <label>

@ -2,7 +2,7 @@ $(function() {
var resultCollector = Quagga.ResultCollector.create({ var resultCollector = Quagga.ResultCollector.create({
capture: true, capture: true,
capacity: 20, capacity: 20,
blacklist: [{code: "3574660239843", format: "ean_13"}], blacklist: [{code: "2167361334", format: "i2of5"}],
filter: function(codeResult) { filter: function(codeResult) {
// only store results which match this constraint // only store results which match this constraint
// e.g.: codeResult // e.g.: codeResult
@ -127,7 +127,7 @@ $(function() {
}, },
numOfWorkers: 4, numOfWorkers: 4,
decoder: { decoder: {
readers : ["code_128_reader"] readers : [ "code_128_reader"]
}, },
locate: true locate: true
}, },

@ -43,6 +43,7 @@
<option value="upc">UPC</option> <option value="upc">UPC</option>
<option value="upc_e">UPC-E</option> <option value="upc_e">UPC-E</option>
<option value="codabar">Codabar</option> <option value="codabar">Codabar</option>
<option value="i2of5">I2of5</option>
</select> </select>
</fieldset> </fieldset>
</div> </div>

@ -1,14 +1,36 @@
$(function() { $(function() {
var App = { var App = {
init: function() { init: function() {
Quagga.init(this.state, function() { var config = this.config[this.state.decoder.readers[0]] || this.config.default;
config = $.extend(true, {}, config, this.state);
Quagga.init(config, function() {
App.attachListeners(); App.attachListeners();
Quagga.start(); Quagga.start();
}); });
}, },
config: { config: {
reader: "code_128", "default": {
length: 10 inputStream: { name: "Test",
type: "ImageStream",
length: 10,
size: 800
},
locator: {
patchSize: "medium",
halfSample: true
}
},
"i2of5_reader": {
inputStream: {
size: 800,
type: "ImageStream",
length: 5
},
locator: {
patchSize: "small",
halfSample: false
}
}
}, },
attachListeners: function() { attachListeners: function() {
var self = this; var self = this;
@ -58,6 +80,7 @@ $(function() {
paths.forEach(function(path) { paths.forEach(function(path) {
var mappedValue; var mappedValue;
if (typeof self._accessByPath(self.inputMapper, path) === "function") { if (typeof self._accessByPath(self.inputMapper, path) === "function") {
mappedValue = self._accessByPath(self.inputMapper, path)(value); mappedValue = self._accessByPath(self.inputMapper, path)(value);
} }
@ -82,10 +105,8 @@ $(function() {
} }
}, },
state: { state: {
inputStream: { name: "Test", inputStream: {
type: "ImageStream", src: "../test/fixtures/code_128/"
src: "../test/fixtures/code_128/",
length: 10
}, },
decoder : { decoder : {
readers : ["code_128_reader"] readers : ["code_128_reader"]

@ -1,6 +1,6 @@
{ {
"name": "quagga", "name": "quagga",
"version": "0.6.13", "version": "0.6.15",
"description": "An advanced barcode-scanner written in JavaScript", "description": "An advanced barcode-scanner written in JavaScript",
"main": "lib/quagga.js", "main": "lib/quagga.js",
"browser": "dist/quagga.js", "browser": "dist/quagga.js",
@ -44,6 +44,7 @@
"code128", "code128",
"code39", "code39",
"codabar", "codabar",
"i2of5",
"upc", "upc",
"getusermedia", "getusermedia",
"imageprocessing" "imageprocessing"

@ -26,7 +26,16 @@ define(['quagga', 'async'], function(Quagga, async) {
function _runTestSet(testSet, config) { function _runTestSet(testSet, config) {
var readers = config.decoder.readers.slice(), var readers = config.decoder.readers.slice(),
folder = baseFolder + readers[0].split('_').slice(0, -1).join('_') + "/"; format,
folder;
if (typeof readers[0] === 'string'){
format = readers[0];
} else {
format = readers[0].format;
}
folder = baseFolder + format.split('_').slice(0, -1).join('_') + "/";
it('should decode ' + folder + " correctly", function(done) { it('should decode ' + folder + " correctly", function(done) {
async.eachSeries(testSet, function (sample, callback) { async.eachSeries(testSet, function (sample, callback) {
@ -71,9 +80,9 @@ define(['quagga', 'async'], function(Quagga, async) {
var config = generateConfig(), var config = generateConfig(),
testSet = [ testSet = [
{"name": "image-001.jpg", "result": "0001285112001000040801"}, {"name": "image-001.jpg", "result": "0001285112001000040801"},
{"name": "image-002.jpg", "result": "FANAVF1461710"}, // {"name": "image-002.jpg", "result": "FANAVF1461710"},
// {"name": "image-003.jpg", "result": "673023"}, // {"name": "image-003.jpg", "result": "673023"},
{"name": "image-004.jpg", "result": "010210150301625334"}, // {"name": "image-004.jpg", "result": "010210150301625334"},
{"name": "image-005.jpg", "result": "419055603900009001012999"}, {"name": "image-005.jpg", "result": "419055603900009001012999"},
{"name": "image-006.jpg", "result": "419055603900009001012999"}, {"name": "image-006.jpg", "result": "419055603900009001012999"},
{"name": "image-007.jpg", "result": "T 000003552345"}, {"name": "image-007.jpg", "result": "T 000003552345"},
@ -96,7 +105,7 @@ define(['quagga', 'async'], function(Quagga, async) {
{"name": "image-001.jpg", "result": "B3% $DAD$"}, {"name": "image-001.jpg", "result": "B3% $DAD$"},
{"name": "image-003.jpg", "result": "CODE39"}, {"name": "image-003.jpg", "result": "CODE39"},
{"name": "image-004.jpg", "result": "QUAGGAJS"}, {"name": "image-004.jpg", "result": "QUAGGAJS"},
{"name": "image-005.jpg", "result": "CODE39"}, /* {"name": "image-005.jpg", "result": "CODE39"}, */
{"name": "image-006.jpg", "result": "2/4-8/16-32"}, {"name": "image-006.jpg", "result": "2/4-8/16-32"},
{"name": "image-007.jpg", "result": "2/4-8/16-32"}, {"name": "image-007.jpg", "result": "2/4-8/16-32"},
{"name": "image-008.jpg", "result": "CODE39"}, {"name": "image-008.jpg", "result": "CODE39"},
@ -203,5 +212,37 @@ define(['quagga', 'async'], function(Quagga, async) {
config.decoder.readers = ['codabar_reader']; config.decoder.readers = ['codabar_reader'];
_runTestSet(testSet, config); _runTestSet(testSet, config);
}); });
describe("I2of5 with localization", function() {
var config = {
inputStream: {
size: 800,
singleChannel: false
},
locator: {
patchSize: "small",
halfSample: false
},
numOfWorkers: 0,
decoder: {
readers: ["i2of5_reader"],
},
locate: true,
src: null
}, testSet = [
{"name": "image-001.jpg", "result": "2167361334"},
{"name": "image-002.jpg", "result": "2167361334"},
{"name": "image-003.jpg", "result": "2167361334"},
{"name": "image-004.jpg", "result": "2167361334"},
{"name": "image-005.jpg", "result": "2167361334"}
];
testSet.forEach(function(sample) {
sample.format = "i2of5";
});
_runTestSet(testSet, config);
});
}); });
}); });

@ -11,7 +11,8 @@ define([
'codabar_reader', 'codabar_reader',
'upc_reader', 'upc_reader',
'ean_8_reader', 'ean_8_reader',
'upc_e_reader' 'upc_e_reader',
'i2of5_reader'
], function( ], function(
Bresenham, Bresenham,
ImageDebug, ImageDebug,
@ -22,7 +23,8 @@ define([
CodabarReader, CodabarReader,
UPCReader, UPCReader,
EAN8Reader, EAN8Reader,
UPCEReader) { UPCEReader,
I2of5Reader) {
"use strict"; "use strict";
var readers = { var readers = {
@ -33,7 +35,8 @@ define([
code_39_vin_reader: Code39VINReader, code_39_vin_reader: Code39VINReader,
codabar_reader: CodabarReader, codabar_reader: CodabarReader,
upc_reader: UPCReader, upc_reader: UPCReader,
upc_e_reader: UPCEReader upc_e_reader: UPCEReader,
i2of5_reader: I2of5Reader
}; };
var BarcodeDecoder = { var BarcodeDecoder = {
create : function(config, inputImageWrapper) { create : function(config, inputImageWrapper) {
@ -86,11 +89,21 @@ define([
} }
function initReaders() { function initReaders() {
var i; config.readers.forEach(function(readerConfig) {
for ( i = 0; i < config.readers.length; i++) { var reader,
console.log(config.readers[i]); config = {};
_barcodeReaders.push(new readers[config.readers[i]]());
} if (typeof readerConfig === 'object') {
reader = readerConfig.format;
config = readerConfig.config;
} else if (typeof readerConfig === 'string') {
reader = readerConfig;
}
_barcodeReaders.push(new readers[reader](config));
});
console.log("Registered Readers: " + _barcodeReaders
.map(function(reader) {return JSON.stringify({format: reader.FORMAT, config: reader.config});})
.join(', '));
} }
function initConfig() { function initConfig() {

@ -5,8 +5,9 @@ define(
function() { function() {
"use strict"; "use strict";
function BarcodeReader() { function BarcodeReader(config) {
this._row = []; this._row = [];
this.config = config || {};
return this; return this;
} }
@ -184,6 +185,29 @@ define(
return true; return true;
}; };
BarcodeReader.prototype._fillCounters = function(offset, end, isWhite) {
var self = this,
counterPos = 0,
i,
counters = [];
isWhite = (typeof isWhite !== 'undefined') ? isWhite : true;
offset = (typeof offset !== 'undefined') ? offset : self._nextUnset(self._row);
end = end || self._row.length;
counters[counterPos] = 0;
for (i = offset; i < end; i++) {
if (self._row[i] ^ isWhite) {
counters[counterPos]++;
} else {
counterPos++;
counters[counterPos] = 1;
isWhite = !isWhite;
}
}
return counters;
};
Object.defineProperty(BarcodeReader.prototype, "FORMAT", { Object.defineProperty(BarcodeReader.prototype, "FORMAT", {
value: 'unknown', value: 'unknown',
writeable: false writeable: false
@ -200,6 +224,8 @@ define(
PatternNotFoundException : "Pattern could not be found!" PatternNotFoundException : "Pattern could not be found!"
}; };
BarcodeReader.CONFIG_KEYS = {};
return (BarcodeReader); return (BarcodeReader);
} }
); );

@ -36,7 +36,7 @@ define(
nextStart, nextStart,
end; end;
self._fillCounters(); this._counters = self._fillCounters();
start = self._findStart(); start = self._findStart();
if (!start) { if (!start) {
return null; return null;
@ -186,26 +186,6 @@ define(
return true; return true;
}; };
CodabarReader.prototype._fillCounters = function() {
var self = this,
counterPos = 0,
isWhite = true,
offset = self._nextUnset(self._row),
i;
self._counters.length = 0;
self._counters[counterPos] = 0;
for (i = offset; i < self._row.length; i++) {
if (self._row[i] ^ isWhite) {
this._counters[counterPos]++;
} else {
counterPos++;
this._counters[counterPos] = 1;
isWhite = !isWhite;
}
}
};
CodabarReader.prototype._patternToChar = function(pattern) { CodabarReader.prototype._patternToChar = function(pattern) {
var i, var i,
self = this; self = this;

@ -0,0 +1,344 @@
/* jshint undef: true, unused: true, browser:true, devel: true */
/* global define */
define(
[
"./barcode_reader",
"./html_utils"
],
function(BarcodeReader, HTMLUtils) {
"use strict";
function I2of5Reader(opts) {
opts = HTMLUtils.mergeObjects(getDefaulConfig(), opts);
BarcodeReader.call(this, opts);
this.barSpaceRatio = [1, 1];
if (opts.normalizeBarSpaceWidth) {
this.SINGLE_CODE_ERROR = 0.38;
this.AVG_CODE_ERROR = 0.09;
}
}
function getDefaulConfig() {
var config = {};
Object.keys(I2of5Reader.CONFIG_KEYS).forEach(function(key) {
config[key] = I2of5Reader.CONFIG_KEYS[key]['default'];
});
return config;
}
var N = 1,
W = 3,
properties = {
MODULO : {value: 10},
START_PATTERN : {value: [N*2.5, N*2.5, N*2.5, N*2.5]},
STOP_PATTERN : {value: [N*2, N*2, W*2]},
CODE_PATTERN : {value: [
[N, N, W, W, N],
[W, N, N, N, W],
[N, W, N, N, W],
[W, W, N, N, N],
[N, N, W, N, W],
[W, N, W, N, N],
[N, W, W, N, N],
[N, N, N, W, W],
[W, N, N, W, N],
[N, W, N, W, N]
]},
SINGLE_CODE_ERROR: {value: 0.78, writable: true},
AVG_CODE_ERROR: {value: 0.38, writable: true},
MAX_CORRECTION_FACTOR: {value: 5},
FORMAT: {value: "i2of5"}
};
I2of5Reader.prototype = Object.create(BarcodeReader.prototype, properties);
I2of5Reader.prototype.constructor = I2of5Reader;
I2of5Reader.prototype._matchPattern = function(counter, code) {
if (this.config.normalizeBarSpaceWidth) {
var i,
counterSum = [0, 0],
codeSum = [0, 0],
correction = [0, 0],
correctionRatio = this.MAX_CORRECTION_FACTOR,
correctionRatioInverse = 1 / correctionRatio;
for (i = 0; i < counter.length; i++) {
counterSum[i % 2] += counter[i];
codeSum[i % 2] += code[i];
}
correction[0] = codeSum[0] / counterSum[0];
correction[1] = codeSum[1] / counterSum[1];
correction[0] = Math.max(Math.min(correction[0], correctionRatio), correctionRatioInverse);
correction[1] = Math.max(Math.min(correction[1], correctionRatio), correctionRatioInverse);
this.barSpaceRatio = correction;
for (i = 0; i < counter.length; i++) {
counter[i] *= this.barSpaceRatio[i % 2];
}
}
return BarcodeReader.prototype._matchPattern.call(this, counter, code);
};
I2of5Reader.prototype._findPattern = function(pattern, offset, isWhite, tryHarder) {
var counter = [],
self = this,
i,
counterPos = 0,
bestMatch = {
error : Number.MAX_VALUE,
code : -1,
start : 0,
end : 0
},
error,
j,
sum,
normalized,
epsilon = self.AVG_CODE_ERROR;
isWhite = isWhite || false;
tryHarder = tryHarder || false;
if (!offset) {
offset = self._nextSet(self._row);
}
for ( i = 0; i < pattern.length; i++) {
counter[i] = 0;
}
for ( i = offset; i < self._row.length; i++) {
if (self._row[i] ^ isWhite) {
counter[counterPos]++;
} else {
if (counterPos === counter.length - 1) {
sum = 0;
for ( j = 0; j < counter.length; j++) {
sum += counter[j];
}
normalized = self._normalize(counter);
if (normalized) {
error = self._matchPattern(normalized, pattern);
if (error < epsilon) {
bestMatch.error = error;
bestMatch.start = i - sum;
bestMatch.end = i;
return bestMatch;
}
}
if (tryHarder) {
for (j = 0; j < counter.length - 2; j++) {
counter[j] = counter[j + 2];
}
counter[counter.length - 2] = 0;
counter[counter.length - 1] = 0;
counterPos--;
} else {
return null;
}
} else {
counterPos++;
}
counter[counterPos] = 1;
isWhite = !isWhite;
}
}
return null;
};
I2of5Reader.prototype._findStart = function() {
var self = this,
leadingWhitespaceStart,
offset = self._nextSet(self._row),
startInfo,
narrowBarWidth = 1;
while(!startInfo) {
startInfo = self._findPattern(self.START_PATTERN, offset, false, true);
if (!startInfo) {
return null;
}
narrowBarWidth = Math.floor((startInfo.end - startInfo.start) / 4);
leadingWhitespaceStart = startInfo.start - narrowBarWidth*10;
if (leadingWhitespaceStart >= 0) {
if (self._matchRange(leadingWhitespaceStart, startInfo.start, 0)) {
return startInfo;
}
}
offset = startInfo.end;
startInfo = null;
}
};
I2of5Reader.prototype._verifyTrailingWhitespace = function(endInfo) {
var self = this,
trailingWhitespaceEnd;
trailingWhitespaceEnd = endInfo.end + ((endInfo.end - endInfo.start) / 2);
if (trailingWhitespaceEnd < self._row.length) {
if (self._matchRange(endInfo.end, trailingWhitespaceEnd, 0)) {
return endInfo;
}
}
return null;
};
I2of5Reader.prototype._findEnd = function() {
var self = this,
endInfo,
tmp;
self._row.reverse();
endInfo = self._findPattern(self.STOP_PATTERN);
self._row.reverse();
if (endInfo === null) {
return null;
}
// reverse numbers
tmp = endInfo.start;
endInfo.start = self._row.length - endInfo.end;
endInfo.end = self._row.length - tmp;
return endInfo !== null ? self._verifyTrailingWhitespace(endInfo) : null;
};
I2of5Reader.prototype._decodePair = function(counterPair) {
var i,
code,
codes = [],
self = this;
for (i = 0; i < counterPair.length; i++) {
code = self._decodeCode(counterPair[i]);
if (!code) {
return null;
}
codes.push(code);
}
return codes;
};
I2of5Reader.prototype._decodeCode = function(counter) {
var j,
self = this,
sum = 0,
normalized,
error,
epsilon = self.AVG_CODE_ERROR,
code,
bestMatch = {
error : Number.MAX_VALUE,
code : -1,
start : 0,
end : 0
};
for ( j = 0; j < counter.length; j++) {
sum += counter[j];
}
normalized = self._normalize(counter);
if (normalized) {
for (code = 0; code < self.CODE_PATTERN.length; code++) {
error = self._matchPattern(normalized, self.CODE_PATTERN[code]);
if (error < bestMatch.error) {
bestMatch.code = code;
bestMatch.error = error;
}
}
if (bestMatch.error < epsilon) {
return bestMatch;
}
}
return null;
};
I2of5Reader.prototype._decodePayload = function(counters, result, decodedCodes) {
var i,
self = this,
pos = 0,
counterLength = counters.length,
counterPair = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0]],
codes;
while (pos < counterLength) {
for (i = 0; i < 5; i++) {
counterPair[0][i] = counters[pos]*this.barSpaceRatio[0];
counterPair[1][i] = counters[pos + 1]*this.barSpaceRatio[1];
pos += 2;
}
codes = self._decodePair(counterPair);
if (!codes) {
return null;
}
for (i = 0; i < codes.length; i++) {
result.push(codes[i].code + "");
decodedCodes.push(codes[i]);
}
}
return codes;
};
I2of5Reader.prototype._verifyCounterLength = function(counters) {
return (counters.length % 10 === 0);
};
I2of5Reader.prototype._decode = function() {
var startInfo,
endInfo,
self = this,
code,
result = [],
decodedCodes = [],
counters;
startInfo = self._findStart();
if (!startInfo) {
return null;
}
decodedCodes.push(startInfo);
endInfo = self._findEnd();
if (!endInfo) {
return null;
}
counters = self._fillCounters(startInfo.end, endInfo.start, false);
if (!self._verifyCounterLength(counters)) {
return null;
}
code = self._decodePayload(counters, result, decodedCodes);
if (!code) {
return null;
}
if (result.length % 2 !== 0 ||
result.length < 6) {
return null;
}
decodedCodes.push(endInfo);
return {
code : result.join(""),
start : startInfo.start,
end : endInfo.end,
startInfo : startInfo,
decodedCodes : decodedCodes
};
};
I2of5Reader.CONFIG_KEYS = {
normalizeBarSpaceWidth: {
'type': 'boolean',
'default': false,
'description': 'If true, the reader tries to normalize the' +
'width-difference between bars and spaces'
}
};
return (I2of5Reader);
}
);

@ -1,8 +1,6 @@
/* jshint undef: true, unused: true, browser:true, devel: true, evil: true */ /* jshint undef: true, unused: true, browser:true, devel: true, evil: true */
/* global define */ /* global define */
define([ define([
"code_128_reader",
"ean_reader",
"input_stream", "input_stream",
"image_wrapper", "image_wrapper",
"barcode_locator", "barcode_locator",
@ -15,9 +13,7 @@ define([
"image_debug", "image_debug",
"gl-matrix", "gl-matrix",
"result_collector"], "result_collector"],
function(Code128Reader, function(InputStream,
EANReader,
InputStream,
ImageWrapper, ImageWrapper,
BarcodeLocator, BarcodeLocator,
BarcodeDecoder, BarcodeDecoder,
@ -457,9 +453,15 @@ function(Code128Reader,
onDetected : function(callback) { onDetected : function(callback) {
Events.subscribe("detected", callback); Events.subscribe("detected", callback);
}, },
offDetected: function(callback) {
Events.unsubscribe("detected", callback);
},
onProcessed: function(callback) { onProcessed: function(callback) {
Events.subscribe("processed", callback); Events.subscribe("processed", callback);
}, },
offProcessed: function(callback) {
Events.unsubscribe("processed", callback);
},
setReaders: function(readers) { setReaders: function(readers) {
setReaders(readers); setReaders(readers);
}, },
@ -490,10 +492,6 @@ function(Code128Reader,
start(); start();
}); });
}, },
Reader: {
EANReader : EANReader,
Code128Reader : Code128Reader
},
ImageWrapper: ImageWrapper, ImageWrapper: ImageWrapper,
ImageDebug: ImageDebug, ImageDebug: ImageDebug,
ResultCollector: ResultCollector ResultCollector: ResultCollector

@ -47,7 +47,8 @@ require.config({
'upc_reader': 'src/upc_reader', 'upc_reader': 'src/upc_reader',
'async': 'node_modules/async/lib/async', 'async': 'node_modules/async/lib/async',
'gl-matrix': 'node_modules/gl-matrix/dist/gl-matrix', 'gl-matrix': 'node_modules/gl-matrix/dist/gl-matrix',
'result_collector': 'src/result_collector' 'result_collector': 'src/result_collector',
'i2of5_reader': 'src/i2of5_reader'
}, },
deps: allTestFiles, deps: allTestFiles,
callback: window.__karma__.start callback: window.__karma__.start

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 KiB

Loading…
Cancel
Save