Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

quagga

Package Overview
Dependencies
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

quagga - npm Package Compare versions

Comparing version 0.6.11 to 0.6.14

bower.json

5

package.json
{
"name": "quagga",
"version": "0.6.11",
"version": "0.6.14",
"description": "An advanced barcode-scanner written in JavaScript",

@@ -45,2 +45,5 @@ "main": "dist/quagga.js",

"code39",
"codabar",
"i2of5",
"upc",
"getusermedia",

@@ -47,0 +50,0 @@ "imageprocessing"

57

README.md
quaggaJS
========
- [Changelog](#changelog) (2015-06-21)
- [Changelog](#changelog) (2015-07-29)

@@ -10,7 +10,7 @@ ## What is QuaggaJS?

time localization and decoding of various types of barcodes such as __EAN__,
__CODE 128__, __CODE 39__, __EAN 8__, __UPC-A__, __UPC-C__ and __CODABAR__.
The library is also capable of using `getUserMedia` to get direct access to
the user's camera stream. Although the code relies on heavy image-processing
even recent smartphones are capable of locating and decoding barcodes in
real-time.
__CODE 128__, __CODE 39__, __EAN 8__, __UPC-A__, __UPC-C__, __I2of5__ and
__CODABAR__. The library is also capable of using `getUserMedia` to get direct
access to the user's camera stream. Although the code relies on heavy image-
processing even recent smartphones are capable of locating and decoding
barcodes in real-time.

@@ -84,8 +84,12 @@ Try some [examples](http://serratus.github.io/quaggaJS/examples) and check out

### Quagga.init(config, callback)
### <a name="quaggainit">Quagga.init(config, callback)</a>
This method initializes the library for a given configuration `config` (see
below) and invokes the `callback` when Quagga is ready to start. The
initialization process also requests for camera access if real-time detection is
configured.
below) and invokes the `callback(err)` when Quagga has finished its
bootstrapping phase. The initialization process also requests for camera
access if real-time detection is configured. In case of an error, the `err`
parameter is set and contains information about the cause. A potential cause
may be the `inputStream.type` is set to `LiveStream`, but the browser does
not support this API, or simply if the user denies the permission to use the
camera.

@@ -101,3 +105,7 @@ ```javascript

}
}, function() {
}, function(err) {
if (err) {
console.log(err);
return
}
console.log("Initialization finished. Ready to start");

@@ -277,7 +285,9 @@ Quagga.start();

Quagga.decodeSingle({
readers: ['code_128_reader'],
locate: true, // try to locate the barcode in the image
src: '/test/fixtures/code_128/image-001.jpg' // or 'data:image/jpg;base64,' + data
decoder: {
readers: ["code_128_reader"] // List of active readers
},
locate: true, // try to locate the barcode in the image
src: '/test/fixtures/code_128/image-001.jpg' // or 'data:image/jpg;base64,' + data
}, function(result){
console.log(result);
console.log(result);
});

@@ -364,2 +374,18 @@ ```

### 2015-07-29
- Features
- Added basic support for [ITF][i2of5_wiki] barcodes (`i2of5_reader`)
### 2015-07-08
- Improvements
- Parameter tweaking to reduce false-positives significantly (for the
entire EAN and UPC family)
- Fixing bug in parity check for UPC-E codes
- Fixing bug in alignment for EAN-8 codes
### 2015-07-06
- Improvements
- Added `err` parameter to [Quagga.init()](#quaggainit) callback
function
### 2015-06-21

@@ -465,1 +491,2 @@ - Features

[github_examples]: http://serratus.github.io/quaggaJS/examples
[i2of5_wiki]: https://en.wikipedia.org/wiki/Interleaved_2_of_5
define(['camera_access'], function(CameraAccess){
var originalURL,
originalUserMedia,
originalMediaStreamTrack,
video,
stream;
beforeEach(function() {

@@ -14,3 +13,2 @@ var tracks = [{

originalURL = window.URL;
originalUserMedia = window.getUserMedia;
originalMediaStreamTrack = window.MediaStreamTrack;

@@ -27,6 +25,3 @@ window.MediaStreamTrack = {};

sinon.spy(tracks[0], "stop");
navigator.getUserMedia = function(constraints, cb) {
cb(stream);
};
sinon.spy(navigator, "getUserMedia");
video = {

@@ -53,3 +48,2 @@ src: null,

afterEach(function() {
navigator.getUserMedia = originalUserMedia;
window.URL = originalURL;

@@ -59,23 +53,75 @@ window.MediaStreamTrack = originalMediaStreamTrack;

describe('request', function() {
it('should request the camera', function(done) {
CameraAccess.request(video, {}, function() {
expect(navigator.getUserMedia.calledOnce).to.equal(true);
expect(video.src).to.deep.equal(stream);
done();
describe('success', function() {
beforeEach(function() {
sinon.stub(navigator, "getUserMedia", function(constraints, success) {
success(stream);
});
});
afterEach(function() {
navigator.getUserMedia.restore();
});
describe('request', function () {
it('should request the camera', function (done) {
CameraAccess.request(video, {}, function () {
expect(navigator.getUserMedia.calledOnce).to.equal(true);
expect(video.src).to.deep.equal(stream);
done();
});
});
});
describe('release', function () {
it('should release the camera', function (done) {
CameraAccess.request(video, {}, function () {
expect(video.src).to.deep.equal(stream);
CameraAccess.release();
expect(video.src.getVideoTracks()).to.have.length(1);
expect(video.src.getVideoTracks()[0].stop.calledOnce).to.equal(true);
done();
});
});
});
});
describe('release', function() {
it('should release the camera', function(done) {
CameraAccess.request(video, {}, function() {
expect(video.src).to.deep.equal(stream);
CameraAccess.release();
expect(video.src.getVideoTracks()).to.have.length(1);
expect(video.src.getVideoTracks()[0].stop.calledOnce).to.equal(true);
done();
describe('failure', function() {
describe("permission denied", function(){
before(function() {
sinon.stub(navigator, "getUserMedia", function(constraints, success, failure) {
failure(new Error());
});
});
after(function() {
navigator.getUserMedia.restore();
});
it('should throw if getUserMedia not available', function(done) {
CameraAccess.request(video, {}, function(err) {
expect(err).to.be.defined;
done();
});
});
});
describe("not available", function(){
var originalGetUserMedia;
before(function() {
originalGetUserMedia = navigator.getUserMedia;
navigator.getUserMedia = undefined;
});
after(function() {
navigator.getUserMedia = originalGetUserMedia;
});
it('should throw if getUserMedia not available', function(done) {
CameraAccess.request(video, {}, function(err) {
expect(err).to.be.defined;
done();
});
});
});
});
});

@@ -29,4 +29,13 @@

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) {

@@ -75,3 +84,3 @@ async.eachSeries(testSet, function (sample, callback) {

{"name": "image-001.jpg", "result": "0001285112001000040801"},
{"name": "image-002.jpg", "result": "FANAVF1461710"},
// {"name": "image-002.jpg", "result": "FANAVF1461710"},
// {"name": "image-003.jpg", "result": "673023"},

@@ -99,3 +108,2 @@ // {"name": "image-004.jpg", "result": "010210150301625334"},

{"name": "image-001.jpg", "result": "B3% $DAD$"},
/*{"name": "image-002.jpg", "result": "QUAGGAJS"},*/
{"name": "image-003.jpg", "result": "CODE39"},

@@ -129,3 +137,3 @@ {"name": "image-004.jpg", "result": "QUAGGAJS"},

{"name": "image-007.jpg", "result": "42176817"},
/*{"name": "image-008.jpg", "result": "42191605"},*/
{"name": "image-008.jpg", "result": "42191605"},
{"name": "image-009.jpg", "result": "42242215"},

@@ -151,3 +159,3 @@ {"name": "image-010.jpg", "result": "42184799"}

{"name": "image-005.jpg", "result": "882428015343"},
{"name": "image-006.jpg", "result": "882428015046"},
/* {"name": "image-006.jpg", "result": "882428015046"}, */
{"name": "image-007.jpg", "result": "882428015084"},

@@ -200,3 +208,3 @@ {"name": "image-008.jpg", "result": "882428015046"},

{"name": "image-007.jpg", "result": "C$399.95A"},
/* {"name": "image-008.jpg", "result": "01264904"}, */
{"name": "image-008.jpg", "result": "A16:9/4:3/3:2D"},
{"name": "image-009.jpg", "result": "C$399.95A"},

@@ -213,3 +221,35 @@ {"name": "image-010.jpg", "result": "C$399.95A"}

});
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);
});
});
});

@@ -14,3 +14,4 @@ /* jshint undef: true, unused: true, browser:true, devel: true */

'ean_8_reader',
'upc_e_reader'
'upc_e_reader',
'i2of5_reader'
], function(

@@ -26,3 +27,4 @@ Bresenham,

EAN8Reader,
UPCEReader) {
UPCEReader,
I2of5Reader) {
"use strict";

@@ -38,3 +40,4 @@

upc_reader: UPCReader,
upc_e_reader: UPCEReader
upc_e_reader: UPCEReader,
i2of5_reader: I2of5Reader
};

@@ -92,7 +95,17 @@ var BarcodeDecoder = {

function initReaders() {
var i;
for ( i = 0; i < config.readers.length; i++) {
console.log(config.readers[i]);
_barcodeReaders.push(new readers[config.readers[i]]());
}
config.readers.forEach(function(readerConfig) {
var reader,
config = {};
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(', '));
}

@@ -99,0 +112,0 @@

@@ -8,4 +8,5 @@ /* jshint undef: true, unused: true, browser:true, devel: true */

function BarcodeReader() {
function BarcodeReader(config) {
this._row = [];
this.config = config || {};
return this;

@@ -188,2 +189,25 @@ }

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", {

@@ -204,2 +228,4 @@ value: 'unknown',

};
BarcodeReader.CONFIG_KEYS = {};

@@ -206,0 +232,0 @@ return (BarcodeReader);

@@ -120,2 +120,3 @@ /* jshint undef: true, unused: true, browser:true, devel: true */

slope,
slope2,
center = min + (max - min) / 2,

@@ -136,7 +137,8 @@ extrema = [],

});
for ( i = 0; i < line.length - 1; i++) {
for ( i = 0; i < line.length - 2; i++) {
slope = (line[i + 1] - line[i]);
if (slope < rThreshold && line[i + 1] < (center*1.5)) {
slope2 = (line[i + 2] - line[i + 1]);
if ((slope + slope2) < rThreshold && line[i + 1] < (center*1.5)) {
dir = Slope.DIR.DOWN;
} else if (slope > threshold && line[i + 1] > (center*0.5)) {
} else if ((slope + slope2) > threshold && line[i + 1] > (center*0.5)) {
dir = Slope.DIR.UP;

@@ -143,0 +145,0 @@ } else {

@@ -16,7 +16,11 @@ /* jshint undef: true, unused: true, browser:true, devel: true */

function getUserMedia(constraints, success, failure) {
navigator.getUserMedia(constraints, function(stream) {
streamRef = stream;
var videoSrc = (window.URL && window.URL.createObjectURL(stream)) || stream;
success.apply(null, [videoSrc]);
}, failure);
if (typeof navigator.getUserMedia !== 'undefined') {
navigator.getUserMedia(constraints, function (stream) {
streamRef = stream;
var videoSrc = (window.URL && window.URL.createObjectURL(stream)) || stream;
success.apply(null, [videoSrc]);
}, failure);
} else {
failure(new TypeError("getUserMedia not available"));
}
}

@@ -60,3 +64,3 @@

}, function(e) {
console.log(e);
callback(e);
});

@@ -84,3 +88,3 @@ }

if ( typeof MediaStreamTrack.getSources !== 'undefined') {
if ( typeof MediaStreamTrack !== 'undefined' && typeof MediaStreamTrack.getSources !== 'undefined') {
MediaStreamTrack.getSources(function(sourceInfos) {

@@ -87,0 +91,0 @@ var videoSourceId;

@@ -39,3 +39,3 @@ /* jshint undef: true, unused: true, browser:true, devel: true */

self._fillCounters();
this._counters = self._fillCounters();
start = self._findStart();

@@ -190,22 +190,2 @@ if (!start) {

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) {

@@ -212,0 +192,0 @@ var i,

@@ -165,11 +165,13 @@ /* jshint undef: true, unused: true, browser:true, devel: true */

normalized = self._normalize(counter);
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 (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;
}
}
bestMatch.end = i;
return bestMatch;
}
bestMatch.end = i;
return bestMatch;
} else {

@@ -214,14 +216,16 @@ counterPos++;

normalized = self._normalize(counter);
for ( code = self.START_CODE_A; code <= self.START_CODE_C; code++) {
error = self._matchPattern(normalized, self.CODE_PATTERN[code]);
if (error < bestMatch.error) {
bestMatch.code = code;
bestMatch.error = error;
if (normalized) {
for (code = self.START_CODE_A; code <= self.START_CODE_C; code++) {
error = self._matchPattern(normalized, self.CODE_PATTERN[code]);
if (error < bestMatch.error) {
bestMatch.code = code;
bestMatch.error = error;
}
}
if (bestMatch.error < self.AVG_CODE_ERROR) {
bestMatch.start = i - sum;
bestMatch.end = i;
return bestMatch;
}
}
if (bestMatch.error < self.AVG_CODE_ERROR) {
bestMatch.start = i - sum;
bestMatch.end = i;
return bestMatch;
}

@@ -228,0 +232,0 @@ for ( j = 0; j < 4; j++) {

@@ -35,3 +35,3 @@ /* jshint undef: true, unused: true, browser:true, devel: true */

code = self._findPattern(self.MIDDLE_PATTERN, code.end, true);
code = self._findPattern(self.MIDDLE_PATTERN, code.end, true, false);
if (code === null) {

@@ -38,0 +38,0 @@ return null;

@@ -45,4 +45,4 @@ /* jshint undef: true, unused: true, browser:true, devel: true */

CODE_FREQUENCY : {value: [0, 11, 13, 14, 19, 25, 28, 21, 22, 26]},
SINGLE_CODE_ERROR: {value: 0.7},
AVG_CODE_ERROR: {value: 0.3},
SINGLE_CODE_ERROR: {value: 0.67},
AVG_CODE_ERROR: {value: 0.27},
FORMAT: {value: "ean_13", writeable: false}

@@ -81,14 +81,16 @@ };

normalized = self._normalize(counter);
for ( code = 0; code < coderange; code++) {
error = self._matchPattern(normalized, self.CODE_PATTERN[code]);
if (error < bestMatch.error) {
bestMatch.code = code;
bestMatch.error = error;
if (normalized) {
for (code = 0; code < coderange; code++) {
error = self._matchPattern(normalized, self.CODE_PATTERN[code]);
if (error < bestMatch.error) {
bestMatch.code = code;
bestMatch.error = error;
}
}
bestMatch.end = i;
if (bestMatch.error > self.AVG_CODE_ERROR) {
return null;
}
return bestMatch;
}
bestMatch.end = i;
if (bestMatch.error > self.AVG_CODE_ERROR) {
return null;
}
return bestMatch;
} else {

@@ -150,9 +152,11 @@ counterPos++;

normalized = self._normalize(counter);
error = self._matchPattern(normalized, pattern);
if (normalized) {
error = self._matchPattern(normalized, pattern);
if (error < epsilon) {
bestMatch.error = error;
bestMatch.start = i - sum;
bestMatch.end = i;
return bestMatch;
if (error < epsilon) {
bestMatch.error = error;
bestMatch.start = i - sum;
bestMatch.end = i;
return bestMatch;
}
}

@@ -159,0 +163,0 @@ if (tryHarder) {

@@ -6,4 +6,2 @@ /* jshint undef: true, unused: true, browser:true, devel: true, evil: true */

define([
"code_128_reader",
"ean_reader",
"input_stream",

@@ -20,5 +18,3 @@ "image_wrapper",

"result_collector"],
function(Code128Reader,
EANReader,
InputStream,
function(InputStream,
ImageWrapper,

@@ -104,3 +100,3 @@ BarcodeLocator,

} else {
console.log(err);
return cb(err);
}

@@ -495,6 +491,2 @@ });

},
Reader: {
EANReader : EANReader,
Code128Reader : Code128Reader
},
ImageWrapper: ImageWrapper,

@@ -501,0 +493,0 @@ ImageDebug: ImageDebug,

@@ -39,4 +39,2 @@ /* jshint undef: true, unused: true, browser:true, devel: true */

codeFrequency |= 1 << (5 - i);
} else {
codeFrequency |= 0 << (5 - i);
}

@@ -46,3 +44,5 @@ result.push(code.code);

}
self._determineParity(codeFrequency, result);
if (!self._determineParity(codeFrequency, result)) {
return null;
}

@@ -62,6 +62,7 @@ return code;

result.push(i);
return;
return true;
}
}
}
return false;
};

@@ -68,0 +69,0 @@

@@ -50,3 +50,4 @@ var allTestFiles = [];

'async': 'node_modules/async/lib/async',
'result_collector': 'src/result_collector'
'result_collector': 'src/result_collector',
'i2of5_reader': 'src/i2of5_reader'
},

@@ -53,0 +54,0 @@ deps: allTestFiles,

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc