diff --git a/src/reader/barcode_reader.js b/src/reader/barcode_reader.js index ac2da266..c3fc411f 100644 --- a/src/reader/barcode_reader.js +++ b/src/reader/barcode_reader.js @@ -47,41 +47,42 @@ BarcodeReader.prototype._nextSet = function(line, offset) { return line.length; }; -BarcodeReader.prototype._normalize = function(counter, modulo) { +BarcodeReader.prototype._normalize = function(counter, correction) { var i, self = this, sum = 0, ratio, numOnes = 0, - normalized = [], - norm = 0; - - if (!modulo) { + normalized = new Array(counter.length), + norm = 0, modulo = self.MODULO; + + if (correction) { + correct(counter, correction.bar, [0, 2, 4]); + correct(counter, correction.space, [1, 3, 5]); } for (i = 0; i < counter.length; i++) { - if (counter[i] === 1) { - numOnes++; - } else { - sum += counter[i]; - } + sum += counter[i]; } ratio = sum / (modulo - numOnes); - if (ratio > 1.0) { - for (i = 0; i < counter.length; i++) { - norm = counter[i] === 1 ? counter[i] : counter[i] / ratio; - normalized.push(norm); - } - } else { - ratio = (sum + numOnes) / modulo; - for (i = 0; i < counter.length; i++) { - norm = counter[i] / ratio; - normalized.push(norm); - } + for (i = 0; i < counter.length; i++) { + norm = counter[i] === 1 ? counter[i] : counter[i] / ratio; + normalized[i] = norm; } return normalized; }; +function correct(counter, correction, indices) { + var length = indices.length, + tmp = 0; + while(length--) { + tmp = counter[indices[length]] * (1 - ((1 - correction) / 2)); + if (tmp > 1) { + counter[indices[length]] = tmp; + } + } +} + BarcodeReader.prototype._matchTrace = function(cmpCounter, epsilon) { var counter = [], i, diff --git a/src/reader/code_128_reader.js b/src/reader/code_128_reader.js index 513a7f37..5c7607e9 100644 --- a/src/reader/code_128_reader.js +++ b/src/reader/code_128_reader.js @@ -123,15 +123,15 @@ var properties = { [2, 1, 1, 2, 3, 2], [2, 3, 3, 1, 1, 1, 2] ]}, - SINGLE_CODE_ERROR: {value: 1}, - AVG_CODE_ERROR: {value: 0.5}, + SINGLE_CODE_ERROR: {value: 0.64}, + AVG_CODE_ERROR: {value: 0.30}, FORMAT: {value: "code_128", writeable: false} }; Code128Reader.prototype = Object.create(BarcodeReader.prototype, properties); Code128Reader.prototype.constructor = Code128Reader; -Code128Reader.prototype._decodeCode = function(start) { +Code128Reader.prototype._decodeCode = function(start, correction) { var counter = [0, 0, 0, 0, 0, 0], i, self = this, @@ -142,7 +142,11 @@ Code128Reader.prototype._decodeCode = function(start) { error: Number.MAX_VALUE, code: -1, start: start, - end: start + end: start, + correction: { + bar: 1, + space: 1 + } }, code, error, @@ -153,7 +157,7 @@ Code128Reader.prototype._decodeCode = function(start) { counter[counterPos]++; } else { if (counterPos === counter.length - 1) { - normalized = self._normalize(counter); + normalized = self._normalize(counter, correction); if (normalized) { for (code = 0; code < self.CODE_PATTERN.length; code++) { error = self._matchPattern(normalized, self.CODE_PATTERN[code]); @@ -163,6 +167,15 @@ Code128Reader.prototype._decodeCode = function(start) { } } bestMatch.end = i; + if (bestMatch.code === -1) { + return null; + } + if (self.CODE_PATTERN[bestMatch.code]) { + bestMatch.correction.bar = calculateCorrection( + self.CODE_PATTERN[bestMatch.code], normalized, [0, 2, 4]); + bestMatch.correction.space = calculateCorrection( + self.CODE_PATTERN[bestMatch.code], normalized, [1, 3, 5]); + } return bestMatch; } } else { @@ -175,6 +188,18 @@ Code128Reader.prototype._decodeCode = function(start) { return null; }; +function calculateCorrection(expected, normalized, indices) { + var length = indices.length, + sumNormalized = 0, + sumExpected = 0; + + while(length--) { + sumExpected += expected[indices[length]]; + sumNormalized += normalized[indices[length]]; + } + return sumExpected/sumNormalized; +} + Code128Reader.prototype._findStart = function() { var counter = [0, 0, 0, 0, 0, 0], i, @@ -186,7 +211,11 @@ Code128Reader.prototype._findStart = function() { error: Number.MAX_VALUE, code: -1, start: 0, - end: 0 + end: 0, + correction: { + bar: 1, + space: 1 + } }, code, error, @@ -215,6 +244,10 @@ Code128Reader.prototype._findStart = function() { if (bestMatch.error < self.AVG_CODE_ERROR) { bestMatch.start = i - sum; bestMatch.end = i; + bestMatch.correction.bar = calculateCorrection( + self.CODE_PATTERN[code], normalized, [0, 2, 4]); + bestMatch.correction.space = calculateCorrection( + self.CODE_PATTERN[code], normalized, [1, 3, 5]); return bestMatch; } } @@ -256,7 +289,11 @@ Code128Reader.prototype._decode = function() { code = { code: startInfo.code, start: startInfo.start, - end: startInfo.end + end: startInfo.end, + correction: { + bar: startInfo.correction.bar, + space: startInfo.correction.space + } }; decodedCodes.push(code); checksum = code.code; @@ -277,7 +314,7 @@ Code128Reader.prototype._decode = function() { while (!done) { unshift = shiftNext; shiftNext = false; - code = self._decodeCode(code.end); + code = self._decodeCode(code.end, code.correction); if (code !== null) { if (code.code !== self.STOP_CODE) { removeLastCharacter = true;