diff --git a/examples/file_input.html b/examples/file_input.html
index 9452fc1..e49efc2 100644
--- a/examples/file_input.html
+++ b/examples/file_input.html
@@ -28,5 +28,5 @@ showInMenu: false
-
+
diff --git a/examples/js/quagga.js b/examples/js/quagga.js
index e2497ab..3f27ade 100644
--- a/examples/js/quagga.js
+++ b/examples/js/quagga.js
@@ -1,16 +1,14 @@
(function (root, factory) {
- if (typeof define === 'function' && define.amd) {
- //Allow using this built library as an AMD module
- //in another project. That other project will only
- //see this AMD call, not the internal modules in
- //the closure below.
- define([], factory);
+ var factorySource = factory.toString();
+
+ if (typeof module !== 'undefined') {
+ module.exports = factory(factorySource);
} else {
//Browser globals case. Just assign the
//result to a property on the global.
- root.Quagga = factory();
+ root.Quagga = factory(factorySource);
}
-}(this, function () {/**
+}(this, function (__factorySource__) {/**
* @license almond 0.2.9 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/almond for details
@@ -3684,27 +3682,6 @@ define("glMatrix", ["typedefs"], (function (global) {
};
}(this)));
-/*
-
-Copyright (C) 2011
- - Christoph Oberhofer (ar.oberhofer@gmail.com)
- - Jens Grubert (jg@jensgrubert.de)
- - Gerhard Reitmayr (reitmayr@icg.tugraz.at)
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-
/*
* glMatrixAddon.js
* Extension to the glMatrix library. The original glMatrix library
@@ -5489,6 +5466,7 @@ define('rasterizer',["tracer"], function(Tracer) {
define('skeletonizer',[],function() {
+ /* @preserve ASM BEGIN */
function Skeletonizer(stdlib, foreign, buffer) {
"use asm";
@@ -5682,6 +5660,7 @@ define('skeletonizer',[],function() {
skeletonize : skeletonize
};
}
+ /* @preserve ASM END */
return Skeletonizer;
});
@@ -7046,7 +7025,6 @@ define('config',[],function(){
controls: false,
locate: true,
numOfWorkers: 4,
- scriptName: 'quagga.js',
visual: {
show: true
},
@@ -7298,1135 +7276,12 @@ define('camera_access',["html_utils"], function(HtmlUtils) {
}
};
});
-/*!
- * async
- * https://github.com/caolan/async
- *
- * Copyright 2010-2014 Caolan McMahon
- * Released under the MIT license
- */
-/*jshint onevar: false, indent:4 */
-/*global setImmediate: false, setTimeout: false, console: false */
-(function () {
-
- var async = {};
-
- // global on the server, window in the browser
- var root, previous_async;
-
- root = this;
- if (root != null) {
- previous_async = root.async;
- }
-
- async.noConflict = function () {
- root.async = previous_async;
- return async;
- };
-
- function only_once(fn) {
- var called = false;
- return function() {
- if (called) throw new Error("Callback was already called.");
- called = true;
- fn.apply(root, arguments);
- }
- }
-
- //// cross-browser compatiblity functions ////
-
- var _toString = Object.prototype.toString;
-
- var _isArray = Array.isArray || function (obj) {
- return _toString.call(obj) === '[object Array]';
- };
-
- var _each = function (arr, iterator) {
- for (var i = 0; i < arr.length; i += 1) {
- iterator(arr[i], i, arr);
- }
- };
-
- var _map = function (arr, iterator) {
- if (arr.map) {
- return arr.map(iterator);
- }
- var results = [];
- _each(arr, function (x, i, a) {
- results.push(iterator(x, i, a));
- });
- return results;
- };
-
- var _reduce = function (arr, iterator, memo) {
- if (arr.reduce) {
- return arr.reduce(iterator, memo);
- }
- _each(arr, function (x, i, a) {
- memo = iterator(memo, x, i, a);
- });
- return memo;
- };
-
- var _keys = function (obj) {
- if (Object.keys) {
- return Object.keys(obj);
- }
- var keys = [];
- for (var k in obj) {
- if (obj.hasOwnProperty(k)) {
- keys.push(k);
- }
- }
- return keys;
- };
-
- //// exported async module functions ////
-
- //// nextTick implementation with browser-compatible fallback ////
- if (typeof process === 'undefined' || !(process.nextTick)) {
- if (typeof setImmediate === 'function') {
- async.nextTick = function (fn) {
- // not a direct alias for IE10 compatibility
- setImmediate(fn);
- };
- async.setImmediate = async.nextTick;
- }
- else {
- async.nextTick = function (fn) {
- setTimeout(fn, 0);
- };
- async.setImmediate = async.nextTick;
- }
- }
- else {
- async.nextTick = process.nextTick;
- if (typeof setImmediate !== 'undefined') {
- async.setImmediate = function (fn) {
- // not a direct alias for IE10 compatibility
- setImmediate(fn);
- };
- }
- else {
- async.setImmediate = async.nextTick;
- }
- }
-
- async.each = function (arr, iterator, callback) {
- callback = callback || function () {};
- if (!arr.length) {
- return callback();
- }
- var completed = 0;
- _each(arr, function (x) {
- iterator(x, only_once(done) );
- });
- function done(err) {
- if (err) {
- callback(err);
- callback = function () {};
- }
- else {
- completed += 1;
- if (completed >= arr.length) {
- callback();
- }
- }
- }
- };
- async.forEach = async.each;
-
- async.eachSeries = function (arr, iterator, callback) {
- callback = callback || function () {};
- if (!arr.length) {
- return callback();
- }
- var completed = 0;
- var iterate = function () {
- iterator(arr[completed], function (err) {
- if (err) {
- callback(err);
- callback = function () {};
- }
- else {
- completed += 1;
- if (completed >= arr.length) {
- callback();
- }
- else {
- iterate();
- }
- }
- });
- };
- iterate();
- };
- async.forEachSeries = async.eachSeries;
-
- async.eachLimit = function (arr, limit, iterator, callback) {
- var fn = _eachLimit(limit);
- fn.apply(null, [arr, iterator, callback]);
- };
- async.forEachLimit = async.eachLimit;
-
- var _eachLimit = function (limit) {
-
- return function (arr, iterator, callback) {
- callback = callback || function () {};
- if (!arr.length || limit <= 0) {
- return callback();
- }
- var completed = 0;
- var started = 0;
- var running = 0;
-
- (function replenish () {
- if (completed >= arr.length) {
- return callback();
- }
-
- while (running < limit && started < arr.length) {
- started += 1;
- running += 1;
- iterator(arr[started - 1], function (err) {
- if (err) {
- callback(err);
- callback = function () {};
- }
- else {
- completed += 1;
- running -= 1;
- if (completed >= arr.length) {
- callback();
- }
- else {
- replenish();
- }
- }
- });
- }
- })();
- };
- };
-
-
- var doParallel = function (fn) {
- return function () {
- var args = Array.prototype.slice.call(arguments);
- return fn.apply(null, [async.each].concat(args));
- };
- };
- var doParallelLimit = function(limit, fn) {
- return function () {
- var args = Array.prototype.slice.call(arguments);
- return fn.apply(null, [_eachLimit(limit)].concat(args));
- };
- };
- var doSeries = function (fn) {
- return function () {
- var args = Array.prototype.slice.call(arguments);
- return fn.apply(null, [async.eachSeries].concat(args));
- };
- };
-
-
- var _asyncMap = function (eachfn, arr, iterator, callback) {
- arr = _map(arr, function (x, i) {
- return {index: i, value: x};
- });
- if (!callback) {
- eachfn(arr, function (x, callback) {
- iterator(x.value, function (err) {
- callback(err);
- });
- });
- } else {
- var results = [];
- eachfn(arr, function (x, callback) {
- iterator(x.value, function (err, v) {
- results[x.index] = v;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
- });
- }
- };
- async.map = doParallel(_asyncMap);
- async.mapSeries = doSeries(_asyncMap);
- async.mapLimit = function (arr, limit, iterator, callback) {
- return _mapLimit(limit)(arr, iterator, callback);
- };
-
- var _mapLimit = function(limit) {
- return doParallelLimit(limit, _asyncMap);
- };
-
- // reduce only has a series version, as doing reduce in parallel won't
- // work in many situations.
- async.reduce = function (arr, memo, iterator, callback) {
- async.eachSeries(arr, function (x, callback) {
- iterator(memo, x, function (err, v) {
- memo = v;
- callback(err);
- });
- }, function (err) {
- callback(err, memo);
- });
- };
- // inject alias
- async.inject = async.reduce;
- // foldl alias
- async.foldl = async.reduce;
-
- async.reduceRight = function (arr, memo, iterator, callback) {
- var reversed = _map(arr, function (x) {
- return x;
- }).reverse();
- async.reduce(reversed, memo, iterator, callback);
- };
- // foldr alias
- async.foldr = async.reduceRight;
-
- var _filter = function (eachfn, arr, iterator, callback) {
- var results = [];
- arr = _map(arr, function (x, i) {
- return {index: i, value: x};
- });
- eachfn(arr, function (x, callback) {
- iterator(x.value, function (v) {
- if (v) {
- results.push(x);
- }
- callback();
- });
- }, function (err) {
- callback(_map(results.sort(function (a, b) {
- return a.index - b.index;
- }), function (x) {
- return x.value;
- }));
- });
- };
- async.filter = doParallel(_filter);
- async.filterSeries = doSeries(_filter);
- // select alias
- async.select = async.filter;
- async.selectSeries = async.filterSeries;
-
- var _reject = function (eachfn, arr, iterator, callback) {
- var results = [];
- arr = _map(arr, function (x, i) {
- return {index: i, value: x};
- });
- eachfn(arr, function (x, callback) {
- iterator(x.value, function (v) {
- if (!v) {
- results.push(x);
- }
- callback();
- });
- }, function (err) {
- callback(_map(results.sort(function (a, b) {
- return a.index - b.index;
- }), function (x) {
- return x.value;
- }));
- });
- };
- async.reject = doParallel(_reject);
- async.rejectSeries = doSeries(_reject);
-
- var _detect = function (eachfn, arr, iterator, main_callback) {
- eachfn(arr, function (x, callback) {
- iterator(x, function (result) {
- if (result) {
- main_callback(x);
- main_callback = function () {};
- }
- else {
- callback();
- }
- });
- }, function (err) {
- main_callback();
- });
- };
- async.detect = doParallel(_detect);
- async.detectSeries = doSeries(_detect);
-
- async.some = function (arr, iterator, main_callback) {
- async.each(arr, function (x, callback) {
- iterator(x, function (v) {
- if (v) {
- main_callback(true);
- main_callback = function () {};
- }
- callback();
- });
- }, function (err) {
- main_callback(false);
- });
- };
- // any alias
- async.any = async.some;
-
- async.every = function (arr, iterator, main_callback) {
- async.each(arr, function (x, callback) {
- iterator(x, function (v) {
- if (!v) {
- main_callback(false);
- main_callback = function () {};
- }
- callback();
- });
- }, function (err) {
- main_callback(true);
- });
- };
- // all alias
- async.all = async.every;
-
- async.sortBy = function (arr, iterator, callback) {
- async.map(arr, function (x, callback) {
- iterator(x, function (err, criteria) {
- if (err) {
- callback(err);
- }
- else {
- callback(null, {value: x, criteria: criteria});
- }
- });
- }, function (err, results) {
- if (err) {
- return callback(err);
- }
- else {
- var fn = function (left, right) {
- var a = left.criteria, b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
- };
- callback(null, _map(results.sort(fn), function (x) {
- return x.value;
- }));
- }
- });
- };
-
- async.auto = function (tasks, callback) {
- callback = callback || function () {};
- var keys = _keys(tasks);
- var remainingTasks = keys.length
- if (!remainingTasks) {
- return callback();
- }
-
- var results = {};
-
- var listeners = [];
- var addListener = function (fn) {
- listeners.unshift(fn);
- };
- var removeListener = function (fn) {
- for (var i = 0; i < listeners.length; i += 1) {
- if (listeners[i] === fn) {
- listeners.splice(i, 1);
- return;
- }
- }
- };
- var taskComplete = function () {
- remainingTasks--
- _each(listeners.slice(0), function (fn) {
- fn();
- });
- };
-
- addListener(function () {
- if (!remainingTasks) {
- var theCallback = callback;
- // prevent final callback from calling itself if it errors
- callback = function () {};
-
- theCallback(null, results);
- }
- });
-
- _each(keys, function (k) {
- var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];
- var taskCallback = function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- if (err) {
- var safeResults = {};
- _each(_keys(results), function(rkey) {
- safeResults[rkey] = results[rkey];
- });
- safeResults[k] = args;
- callback(err, safeResults);
- // stop subsequent errors hitting callback multiple times
- callback = function () {};
- }
- else {
- results[k] = args;
- async.setImmediate(taskComplete);
- }
- };
- var requires = task.slice(0, Math.abs(task.length - 1)) || [];
- var ready = function () {
- return _reduce(requires, function (a, x) {
- return (a && results.hasOwnProperty(x));
- }, true) && !results.hasOwnProperty(k);
- };
- if (ready()) {
- task[task.length - 1](taskCallback, results);
- }
- else {
- var listener = function () {
- if (ready()) {
- removeListener(listener);
- task[task.length - 1](taskCallback, results);
- }
- };
- addListener(listener);
- }
- });
- };
-
- async.retry = function(times, task, callback) {
- var DEFAULT_TIMES = 5;
- var attempts = [];
- // Use defaults if times not passed
- if (typeof times === 'function') {
- callback = task;
- task = times;
- times = DEFAULT_TIMES;
- }
- // Make sure times is a number
- times = parseInt(times, 10) || DEFAULT_TIMES;
- var wrappedTask = function(wrappedCallback, wrappedResults) {
- var retryAttempt = function(task, finalAttempt) {
- return function(seriesCallback) {
- task(function(err, result){
- seriesCallback(!err || finalAttempt, {err: err, result: result});
- }, wrappedResults);
- };
- };
- while (times) {
- attempts.push(retryAttempt(task, !(times-=1)));
- }
- async.series(attempts, function(done, data){
- data = data[data.length - 1];
- (wrappedCallback || callback)(data.err, data.result);
- });
- }
- // If a callback is passed, run this as a controll flow
- return callback ? wrappedTask() : wrappedTask
- };
-
- async.waterfall = function (tasks, callback) {
- callback = callback || function () {};
- if (!_isArray(tasks)) {
- var err = new Error('First argument to waterfall must be an array of functions');
- return callback(err);
- }
- if (!tasks.length) {
- return callback();
- }
- var wrapIterator = function (iterator) {
- return function (err) {
- if (err) {
- callback.apply(null, arguments);
- callback = function () {};
- }
- else {
- var args = Array.prototype.slice.call(arguments, 1);
- var next = iterator.next();
- if (next) {
- args.push(wrapIterator(next));
- }
- else {
- args.push(callback);
- }
- async.setImmediate(function () {
- iterator.apply(null, args);
- });
- }
- };
- };
- wrapIterator(async.iterator(tasks))();
- };
-
- var _parallel = function(eachfn, tasks, callback) {
- callback = callback || function () {};
- if (_isArray(tasks)) {
- eachfn.map(tasks, function (fn, callback) {
- if (fn) {
- fn(function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- callback.call(null, err, args);
- });
- }
- }, callback);
- }
- else {
- var results = {};
- eachfn.each(_keys(tasks), function (k, callback) {
- tasks[k](function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- results[k] = args;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
- });
- }
- };
-
- async.parallel = function (tasks, callback) {
- _parallel({ map: async.map, each: async.each }, tasks, callback);
- };
-
- async.parallelLimit = function(tasks, limit, callback) {
- _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);
- };
-
- async.series = function (tasks, callback) {
- callback = callback || function () {};
- if (_isArray(tasks)) {
- async.mapSeries(tasks, function (fn, callback) {
- if (fn) {
- fn(function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- callback.call(null, err, args);
- });
- }
- }, callback);
- }
- else {
- var results = {};
- async.eachSeries(_keys(tasks), function (k, callback) {
- tasks[k](function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- results[k] = args;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
- });
- }
- };
-
- async.iterator = function (tasks) {
- var makeCallback = function (index) {
- var fn = function () {
- if (tasks.length) {
- tasks[index].apply(null, arguments);
- }
- return fn.next();
- };
- fn.next = function () {
- return (index < tasks.length - 1) ? makeCallback(index + 1): null;
- };
- return fn;
- };
- return makeCallback(0);
- };
-
- async.apply = function (fn) {
- var args = Array.prototype.slice.call(arguments, 1);
- return function () {
- return fn.apply(
- null, args.concat(Array.prototype.slice.call(arguments))
- );
- };
- };
-
- var _concat = function (eachfn, arr, fn, callback) {
- var r = [];
- eachfn(arr, function (x, cb) {
- fn(x, function (err, y) {
- r = r.concat(y || []);
- cb(err);
- });
- }, function (err) {
- callback(err, r);
- });
- };
- async.concat = doParallel(_concat);
- async.concatSeries = doSeries(_concat);
-
- async.whilst = function (test, iterator, callback) {
- if (test()) {
- iterator(function (err) {
- if (err) {
- return callback(err);
- }
- async.whilst(test, iterator, callback);
- });
- }
- else {
- callback();
- }
- };
-
- async.doWhilst = function (iterator, test, callback) {
- iterator(function (err) {
- if (err) {
- return callback(err);
- }
- var args = Array.prototype.slice.call(arguments, 1);
- if (test.apply(null, args)) {
- async.doWhilst(iterator, test, callback);
- }
- else {
- callback();
- }
- });
- };
-
- async.until = function (test, iterator, callback) {
- if (!test()) {
- iterator(function (err) {
- if (err) {
- return callback(err);
- }
- async.until(test, iterator, callback);
- });
- }
- else {
- callback();
- }
- };
-
- async.doUntil = function (iterator, test, callback) {
- iterator(function (err) {
- if (err) {
- return callback(err);
- }
- var args = Array.prototype.slice.call(arguments, 1);
- if (!test.apply(null, args)) {
- async.doUntil(iterator, test, callback);
- }
- else {
- callback();
- }
- });
- };
-
- async.queue = function (worker, concurrency) {
- if (concurrency === undefined) {
- concurrency = 1;
- }
- function _insert(q, data, pos, callback) {
- if (!q.started){
- q.started = true;
- }
- if (!_isArray(data)) {
- data = [data];
- }
- if(data.length == 0) {
- // call drain immediately if there are no tasks
- return async.setImmediate(function() {
- if (q.drain) {
- q.drain();
- }
- });
- }
- _each(data, function(task) {
- var item = {
- data: task,
- callback: typeof callback === 'function' ? callback : null
- };
-
- if (pos) {
- q.tasks.unshift(item);
- } else {
- q.tasks.push(item);
- }
-
- if (q.saturated && q.tasks.length === q.concurrency) {
- q.saturated();
- }
- async.setImmediate(q.process);
- });
- }
-
- var workers = 0;
- var q = {
- tasks: [],
- concurrency: concurrency,
- saturated: null,
- empty: null,
- drain: null,
- started: false,
- paused: false,
- push: function (data, callback) {
- _insert(q, data, false, callback);
- },
- kill: function () {
- q.drain = null;
- q.tasks = [];
- },
- unshift: function (data, callback) {
- _insert(q, data, true, callback);
- },
- process: function () {
- if (!q.paused && workers < q.concurrency && q.tasks.length) {
- var task = q.tasks.shift();
- if (q.empty && q.tasks.length === 0) {
- q.empty();
- }
- workers += 1;
- var next = function () {
- workers -= 1;
- if (task.callback) {
- task.callback.apply(task, arguments);
- }
- if (q.drain && q.tasks.length + workers === 0) {
- q.drain();
- }
- q.process();
- };
- var cb = only_once(next);
- worker(task.data, cb);
- }
- },
- length: function () {
- return q.tasks.length;
- },
- running: function () {
- return workers;
- },
- idle: function() {
- return q.tasks.length + workers === 0;
- },
- pause: function () {
- if (q.paused === true) { return; }
- q.paused = true;
- },
- resume: function () {
- if (q.paused === false) { return; }
- q.paused = false;
- // Need to call q.process once per concurrent
- // worker to preserve full concurrency after pause
- for (var w = 1; w <= q.concurrency; w++) {
- async.setImmediate(q.process);
- }
- }
- };
- return q;
- };
-
- async.priorityQueue = function (worker, concurrency) {
-
- function _compareTasks(a, b){
- return a.priority - b.priority;
- };
-
- function _binarySearch(sequence, item, compare) {
- var beg = -1,
- end = sequence.length - 1;
- while (beg < end) {
- var mid = beg + ((end - beg + 1) >>> 1);
- if (compare(item, sequence[mid]) >= 0) {
- beg = mid;
- } else {
- end = mid - 1;
- }
- }
- return beg;
- }
-
- function _insert(q, data, priority, callback) {
- if (!q.started){
- q.started = true;
- }
- if (!_isArray(data)) {
- data = [data];
- }
- if(data.length == 0) {
- // call drain immediately if there are no tasks
- return async.setImmediate(function() {
- if (q.drain) {
- q.drain();
- }
- });
- }
- _each(data, function(task) {
- var item = {
- data: task,
- priority: priority,
- callback: typeof callback === 'function' ? callback : null
- };
-
- q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
+/* jshint undef: true, unused: true, browser:true, devel: true, evil: true */
+/* global define, vec2 */
- if (q.saturated && q.tasks.length === q.concurrency) {
- q.saturated();
- }
- async.setImmediate(q.process);
- });
- }
-
- // Start with a normal queue
- var q = async.queue(worker, concurrency);
-
- // Override push to accept second parameter representing priority
- q.push = function (data, priority, callback) {
- _insert(q, data, priority, callback);
- };
-
- // Remove unshift function
- delete q.unshift;
-
- return q;
- };
-
- async.cargo = function (worker, payload) {
- var working = false,
- tasks = [];
-
- var cargo = {
- tasks: tasks,
- payload: payload,
- saturated: null,
- empty: null,
- drain: null,
- drained: true,
- push: function (data, callback) {
- if (!_isArray(data)) {
- data = [data];
- }
- _each(data, function(task) {
- tasks.push({
- data: task,
- callback: typeof callback === 'function' ? callback : null
- });
- cargo.drained = false;
- if (cargo.saturated && tasks.length === payload) {
- cargo.saturated();
- }
- });
- async.setImmediate(cargo.process);
- },
- process: function process() {
- if (working) return;
- if (tasks.length === 0) {
- if(cargo.drain && !cargo.drained) cargo.drain();
- cargo.drained = true;
- return;
- }
-
- var ts = typeof payload === 'number'
- ? tasks.splice(0, payload)
- : tasks.splice(0, tasks.length);
-
- var ds = _map(ts, function (task) {
- return task.data;
- });
-
- if(cargo.empty) cargo.empty();
- working = true;
- worker(ds, function () {
- working = false;
-
- var args = arguments;
- _each(ts, function (data) {
- if (data.callback) {
- data.callback.apply(null, args);
- }
- });
-
- process();
- });
- },
- length: function () {
- return tasks.length;
- },
- running: function () {
- return working;
- }
- };
- return cargo;
- };
-
- var _console_fn = function (name) {
- return function (fn) {
- var args = Array.prototype.slice.call(arguments, 1);
- fn.apply(null, args.concat([function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (typeof console !== 'undefined') {
- if (err) {
- if (console.error) {
- console.error(err);
- }
- }
- else if (console[name]) {
- _each(args, function (x) {
- console[name](x);
- });
- }
- }
- }]));
- };
- };
- async.log = _console_fn('log');
- async.dir = _console_fn('dir');
- /*async.info = _console_fn('info');
- async.warn = _console_fn('warn');
- async.error = _console_fn('error');*/
-
- async.memoize = function (fn, hasher) {
- var memo = {};
- var queues = {};
- hasher = hasher || function (x) {
- return x;
- };
- var memoized = function () {
- var args = Array.prototype.slice.call(arguments);
- var callback = args.pop();
- var key = hasher.apply(null, args);
- if (key in memo) {
- async.nextTick(function () {
- callback.apply(null, memo[key]);
- });
- }
- else if (key in queues) {
- queues[key].push(callback);
- }
- else {
- queues[key] = [callback];
- fn.apply(null, args.concat([function () {
- memo[key] = arguments;
- var q = queues[key];
- delete queues[key];
- for (var i = 0, l = q.length; i < l; i++) {
- q[i].apply(null, arguments);
- }
- }]));
- }
- };
- memoized.memo = memo;
- memoized.unmemoized = fn;
- return memoized;
- };
-
- async.unmemoize = function (fn) {
- return function () {
- return (fn.unmemoized || fn).apply(null, arguments);
- };
- };
-
- async.times = function (count, iterator, callback) {
- var counter = [];
- for (var i = 0; i < count; i++) {
- counter.push(i);
- }
- return async.map(counter, iterator, callback);
- };
- async.timesSeries = function (count, iterator, callback) {
- var counter = [];
- for (var i = 0; i < count; i++) {
- counter.push(i);
- }
- return async.mapSeries(counter, iterator, callback);
- };
-
- async.seq = function (/* functions... */) {
- var fns = arguments;
- return function () {
- var that = this;
- var args = Array.prototype.slice.call(arguments);
- var callback = args.pop();
- async.reduce(fns, args, function (newargs, fn, cb) {
- fn.apply(that, newargs.concat([function () {
- var err = arguments[0];
- var nextargs = Array.prototype.slice.call(arguments, 1);
- cb(err, nextargs);
- }]))
- },
- function (err, results) {
- callback.apply(that, [err].concat(results));
- });
- };
- };
-
- async.compose = function (/* functions... */) {
- return async.seq.apply(null, Array.prototype.reverse.call(arguments));
- };
-
- var _applyEach = function (eachfn, fns /*args...*/) {
- var go = function () {
- var that = this;
- var args = Array.prototype.slice.call(arguments);
- var callback = args.pop();
- return eachfn(fns, function (fn, cb) {
- fn.apply(that, args.concat([cb]));
- },
- callback);
- };
- if (arguments.length > 2) {
- var args = Array.prototype.slice.call(arguments, 2);
- return go.apply(this, args);
- }
- else {
- return go;
- }
- };
- async.applyEach = doParallel(_applyEach);
- async.applyEachSeries = doSeries(_applyEach);
-
- async.forever = function (fn, callback) {
- function next(err) {
- if (err) {
- if (callback) {
- return callback(err);
- }
- throw err;
- }
- fn(next);
- }
- next();
- };
-
- // Node.js
- if (typeof module !== 'undefined' && module.exports) {
- module.exports = async;
- }
- // AMD / RequireJS
- else if (typeof define !== 'undefined' && define.amd) {
- define('async',[], function () {
- return async;
- });
- }
- // included directly via
-
+
diff --git a/examples/static_images.html b/examples/static_images.html
index 4d7a905..12bb896 100644
--- a/examples/static_images.html
+++ b/examples/static_images.html
@@ -30,7 +30,7 @@ showInMenu: false
-
+
diff --git a/index.md b/index.md
index 2b9eba8..3dd642b 100644
--- a/index.md
+++ b/index.md
@@ -7,15 +7,19 @@ showInMenu: true
quaggaJS
========
-- [Changelog](#changelog) (2015-03-12)
+- [Changelog](#changelog) (2015-03-16)
-QuaggaJS is a barcode-scanner entirely written in JavaScript supporting real-time localization and decoding of
-various types of barcodes such as __EAN__ and __CODE128__. 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.
+## What is QuaggaJS?
-Try some [examples]({{ site.baseurl }}/examples) and check out the blog post
-([How barcode-localization works in QuaggaJS](http://www.oberhofer.co/how-barcode-localization-works-in-quaggajs/))
+QuaggaJS is a barcode-scanner entirely written in JavaScript supporting real-
+time localization and decoding of various types of barcodes such as __EAN__,
+__CODE128__ and __CODE39__. 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.
+
+Try some [examples](http://serratus.github.io/quaggaJS/examples) and check out
+the blog post ([How barcode-localization works in QuaggaJS][oberhofer_co_how])
if you want to dive deeper into this topic.
![teaser][teaser_left]![teaser][teaser_right]
@@ -23,63 +27,70 @@ if you want to dive deeper into this topic.
## Yet another barcode library?
-This is not yet another port of the great [zxing][zxing_github] library, but more of an extension to it.
-This implementation features a barcode locator which is capable of finding a barcode-like pattern in an
-image resulting in an estimated bounding box including the rotation. Simply speaking, this reader is invariant
-to scale and rotation, whereas other libraries require the barcode to be aligned with the viewport.
+This is not yet another port of the great [zxing][zxing_github] library, but
+more of an extension to it. This implementation features a barcode locator which
+is capable of finding a barcode-like pattern in an image resulting in an
+estimated bounding box including the rotation. Simply speaking, this reader is
+invariant to scale and rotation, whereas other libraries require the barcode to
+be aligned with the viewport.
## Requirements
-In order to take full advantage of quaggaJS, the browser needs to support the `getUserMedia` API which is
-already implemented in recent versions of Firefox, Chrome and Opera. The API is also available on their
-mobile counterparts installed on Android. Safari and IE do not allow the access to the camera yet, neither
-on desktop, nor on mobile. You can check [caniuse][caniuse_getusermedia] for updates.
+In order to take full advantage of quaggaJS, the browser needs to support the
+`getUserMedia` API which is already implemented in recent versions of Firefox,
+Chrome and Opera. The API is also available on their mobile counterparts
+installed on Android. Safari and IE do not allow the access to the camera yet,
+neither on desktop, nor on mobile. You can check [caniuse][caniuse_getusermedia]
+for updates.
+
+In cases where real-time decoding is not needed, or the platform does not
+support `getUserMedia` QuaggaJS is also capable of decoding image-files using
+the File API or other URL sources.
-In cases where real-time decoding is not needed, or the platform does not support `getUserMedia` QuaggaJS is
-also capable of decoding image-files using the File API or other URL sources.
+## Getting Started
-## Installation
+You can simply include `dist/quagga.min.js` in your project and you are ready
+to go.
-Just clone the repository and include `dist/quagga.js` in your project. You can also build the library yourself
-by simply typing:
+If you want to keep your project modular, you can also install QuaggaJS via npm:
```console
-> npm install
-> grunt
+> npm install quagga
+```
+
+And then import it as dependency in your project:
+
+```javascript
+var quagga = require('quagga');
```
-### Minification
+For starters, have a look at the [examples][github_examples] to get an idea
+where to go from here.
-Currently, I strongly disapprove using `grunt uglify` since it does not handle asm.js code correctly
-(see [issue](https://github.com/mishoo/UglifyJS2/issues/167)). The resulting code still works, but
-the performance might suffer, especially in Firefox. Additionally it triggers some ugly log-warnings
-in the console.
+## Building
-This is how you create a minified version of quaggaJS (saved in `dist/quagga.min.js`):
+You can build the library yourself by simply cloning the repo and typing:
```console
-> grunt uglify
+> npm install
+> grunt dist
```
-Special care has to be taken if a minimized/uglified version of the code is needed. Basically the grunt task
-`grunt uglify` takes the `dist/quagga.js` as input and saves the minified code in `dist/quagga.min.js`.
-Since the introduction of web-workers in quaggaJS, the filename of the script is important, because
-the instantiation of the workers rely on it. This script-name defaults to `quagga.js` and can be changed
-in the config with the key `config.scriptName`. The supplied string must match the filename of the
-file being served by the webserver. Now, in the case of a minified version, the config must be adapted
-so that `config.scriptName` points to `quagga.min.js`.
-
-See the [config](#configobject) for all supported options.
+This grunt task builds a non optimized version `quagga.js` and a minified
+version `quagga.min.js` and places both files in the `dist` folder.
-## Usage
+## API
-You can check out the [examples]({{ site.baseurl }}/examples) to get an idea of how to use QuaggaJS.
-Basically the library exposes the following API:
+You can check out the [examples][github_examples] to get an idea of how to
+use QuaggaJS. Basically the library exposes the following API:
### Quagga.init(config, callback)
-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.
+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.
```javascript
Quagga.init({
@@ -98,31 +109,41 @@ Quagga.init({
### Quagga.start()
-When the library is initialized, the `start()` method starts the video-stream and begins locating and decoding
-the images.
+When the library is initialized, the `start()` method starts the video-stream
+and begins locating and decoding the images.
### Quagga.stop()
-If the decoder is currently running, after calling `stop()` the decoder does not process any more images. Additionally, if a camera-stream was requested upon initialization, this operation also disconnects the camera.
+If the decoder is currently running, after calling `stop()` the decoder does not
+process any more images. Additionally, if a camera-stream was requested upon
+initialization, this operation also disconnects the camera.
### Quagga.onProcessed(callback)
-This method registers a `callback(data)` function that is called for each frame after the processing is done. The `data` object contains detailed information about the success/failure of the operation. The output varies, depending whether the detection and/or decoding were successful or not.
+This method registers a `callback(data)` function that is called for each frame
+after the processing is done. The `data` object contains detailed information
+about the success/failure of the operation. The output varies, depending whether
+the detection and/or decoding were successful or not.
### Quagga.onDetected(callback)
-Registers a `callback(data)` function which is triggered whenever a barcode-pattern has been located and decoded
-successfully. The passed `data` object contains information about the decoding process including the detected code which can be obtained by calling `data.codeResult.code`.
+Registers a `callback(data)` function which is triggered whenever a barcode-
+pattern has been located and decoded successfully. The passed `data` object
+contains information about the decoding process including the detected code
+which can be obtained by calling `data.codeResult.code`.
### Quagga.decodeSingle(config, callback)
-In contrast to the calls described above, this method does not rely on `getUserMedia` and operates on a
-single image instead. The provided callback is the same as in `onDetected` and contains the result `data`
-object.
+In contrast to the calls described above, this method does not rely on
+`getUserMedia` and operates on a single image instead. The provided callback
+is the same as in `onDetected` and contains the result `data` object.
## The result object
-The callbacks passed into `onProcessed`, `onDetected` and `decodeSingle` receive a `data` object upon execution. The `data` object contains the following information. Depending on the success, some fields may be `undefined` or just empty.
+The callbacks passed into `onProcessed`, `onDetected` and `decodeSingle`
+receive a `data` object upon execution. The `data` object contains the following
+information. Depending on the success, some fields may be `undefined` or just
+empty.
```javascript
{
@@ -208,7 +229,6 @@ The default `config` object is set as followed:
controls: false,
locate: true,
numOfWorkers: 4,
- scriptName: 'quagga.js',
visual: {
show: true
},
@@ -241,8 +261,9 @@ The default `config` object is set as followed:
## Examples
-The following example takes an image `src` as input and prints the result on the console.
-The decoder is configured to detect _Code128_ barcodes and enables the locating-mechanism for more robust results.
+The following example takes an image `src` as input and prints the result on the
+console. The decoder is configured to detect _Code128_ barcodes and enables the
+locating-mechanism for more robust results.
```javascript
Quagga.decodeSingle({
@@ -256,7 +277,9 @@ Quagga.decodeSingle({
## Tests
-Unit Tests can be run with [Karma][karmaUrl] and written using [Mocha][mochaUrl], [Chai][chaiUrl] and [SinonJS][sinonUrl]. Coverage reports are automatically generated in the coverage/ folder.
+Unit Tests can be run with [Karma][karmaUrl] and written using
+[Mocha][mochaUrl], [Chai][chaiUrl] and [SinonJS][sinonUrl]. Coverage reports are
+automatically generated in the coverage/ folder.
```console
> npm install
@@ -264,10 +287,21 @@ Unit Tests can be run with [Karma][karmaUrl] and written using [Mocha][mochaUrl]
```
## Image Debugging
-In case you want to take a deeper dive into the inner workings of Quagga, get to know the _debugging_ capabilities of the current implementation. The various flags exposed through the `config` object give you the abilily to visualize almost every step in the processing. Because of the introduction of the web-workers, and their restriction not to have access to the DOM, the configuration must be explicitly set to `config.numOfWorkers = 0` in order to work.
+In case you want to take a deeper dive into the inner workings of Quagga, get to
+know the _debugging_ capabilities of the current implementation. The various
+flags exposed through the `config` object give you the abilily to visualize
+almost every step in the processing. Because of the introduction of the
+web-workers, and their restriction not to have access to the DOM, the
+configuration must be explicitly set to `config.numOfWorkers = 0` in order to
+work.
## Changelog
+### 2015-03-16
+- Improvements
+ - now includes minified version (23.3KB gzipped)
+ - No need for configuration of script-name any more
+
### 2015-03-12
- Improvements
- removed dependency on async.js
@@ -278,17 +312,25 @@ In case you want to take a deeper dive into the inner workings of Quagga, get to
### 2015-01-21
- Features
- - Added support for web-worker (using 4 workers as default, can be changed through `config.numOfWorkers`)
- - Due to the way how web-workers are created, the name of the script file (`config.scriptName`) should be kept in sync with your actual filename
- - Removed canvas-overlay for decoding (boxes & scanline) which can now be easily implemented using the existing API (see example)
+ - Added support for web-worker (using 4 workers as default, can be changed
+ through `config.numOfWorkers`)
+ - Due to the way how web-workers are created, the name of the script file
+ (`config.scriptName`) should be kept in sync with your actual filename
+ - Removed canvas-overlay for decoding (boxes & scanline) which can now be
+ easily implemented using the existing API (see example)
- API Changes
-In the course of implementing web-workers some breaking changes were introduced to the API.
- - The `Quagga.init` function no longer receives the callback as part of the config but rather as a second argument: `Quagga.init(config, cb)`
- - The callback to `Quagga.onDetected` now receives an object containing much more information in addition to the decoded code. (see [data](#resultobject))
- - Added `Quagga.onProcessed(callback)` which provides a way to get information for each image processed.
- The callback receives the same `data` object as `Quagga.onDetected` does. Depending on the success of the process the `data` object
- might not contain any `resultCode` and/or `box` properties.
-
+In the course of implementing web-workers some breaking changes were
+introduced to the API.
+ - The `Quagga.init` function no longer receives the callback as part of the
+ config but rather as a second argument: `Quagga.init(config, cb)`
+ - The callback to `Quagga.onDetected` now receives an object containing
+ much more information in addition to the decoded code.(see
+ [data](#resultobject))
+ - Added `Quagga.onProcessed(callback)` which provides a way to get information
+ for each image processed. The callback receives the same `data` object as
+ `Quagga.onDetected` does. Depending on the success of the process the `data`
+ object might not contain any `resultCode` and/or `box` properties.
+
[zxing_github]: https://github.com/zxing/zxing
[teaser_left]: {{ site.baseurl }}/assets/mobile-located.jpg
[teaser_right]: {{ site.baseurl }}/assets/mobile-detected.jpg
@@ -298,3 +340,5 @@ In the course of implementing web-workers some breaking changes were introduced
[mochaUrl]: https://github.com/mochajs/mocha
[karmaUrl]: http://karma-runner.github.io/
[code39_wiki]: http://en.wikipedia.org/wiki/Code_39
+[oberhofer_co_how]: http://www.oberhofer.co/how-barcode-localization-works-in-quaggajs/
+[github_examples]: http://serratus.github.io/quaggaJS/examples