2867 lines
81 KiB
JavaScript
2867 lines
81 KiB
JavaScript
/* --------------------------------------------------
|
|
Javascript Only Barcode_Reader (BarcodeReader) V1.6 by Eddie Larsson <https://github.com/EddieLa/BarcodeReader>
|
|
|
|
This software is provided under the MIT license, http://opensource.org/licenses/MIT.
|
|
All use of this software must include this
|
|
text, including the reference to the creator of the original source code. The
|
|
originator accepts no responsibility of any kind pertaining to
|
|
use of this software.
|
|
|
|
Copyright (c) 2013 Eddie Larsson
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
|
|
------------------------ */
|
|
function Rotate(data, width, height, rotation) {
|
|
var newData = [];
|
|
var x, y;
|
|
switch (rotation) {
|
|
case 90:
|
|
for (x = 0; x < width * 4; x += 4) {
|
|
for (y = width * 4 * (height - 1); y >= 0; y -= width * 4) {
|
|
newData.push(data[x + y]);
|
|
newData.push(data[x + y + 1]);
|
|
newData.push(data[x + y + 2]);
|
|
newData.push(data[x + y + 3]);
|
|
}
|
|
}
|
|
break;
|
|
case -90:
|
|
for (x = width * 4 - 4; x >= 0; x -= 4) {
|
|
for (y = 0; y < data.length; y += width * 4) {
|
|
newData.push(data[x + y]);
|
|
newData.push(data[x + y + 1]);
|
|
newData.push(data[x + y + 2]);
|
|
newData.push(data[x + y + 3]);
|
|
}
|
|
}
|
|
break;
|
|
case 180:
|
|
for (y = width * 4 * (height - 1); y >= 0; y -= width * 4) {
|
|
for (x = width * 4 - 4; x >= 0; x -= 4) {
|
|
newData.push(data[x + y]);
|
|
newData.push(data[x + y + 1]);
|
|
newData.push(data[x + y + 2]);
|
|
newData.push(data[x + y + 3]);
|
|
}
|
|
}
|
|
}
|
|
return new Uint8ClampedArray(newData);
|
|
}
|
|
|
|
function BoxFilter(data, width, radius) {
|
|
var elements = [];
|
|
var sum = [];
|
|
var val;
|
|
var x, y, i;
|
|
for (x = 0; x < width; x++) {
|
|
elements.push([]);
|
|
sum.push(0);
|
|
for (y = 0; y < (radius + 1) * width; y += width) {
|
|
elements[elements.length - 1].push(data[x + y]);
|
|
sum[sum.length - 1] = sum[sum.length - 1] + data[x + y];
|
|
}
|
|
}
|
|
var newData = [];
|
|
for (y = 0; y < data.length; y += width) {
|
|
for (x = 0; x < width; x++) {
|
|
var newVal = 0;
|
|
var length = 0;
|
|
for (i = x; i >= 0; i--) {
|
|
newVal += sum[i];
|
|
length++;
|
|
if (length === radius + 1) break;
|
|
}
|
|
var tempLength = 0;
|
|
for (i = x + 1; i < width; i++) {
|
|
newVal += sum[i];
|
|
length++;
|
|
tempLength++;
|
|
if (tempLength === radius) break;
|
|
}
|
|
length *= elements[0].length;
|
|
newVal /= length;
|
|
newData.push(newVal);
|
|
}
|
|
if (y - radius * width >= 0) {
|
|
for (i = 0; i < elements.length; i++) {
|
|
val = elements[i].shift();
|
|
sum[i] = sum[i] - val;
|
|
}
|
|
}
|
|
if (y + (radius + 1) * width < data.length) {
|
|
for (i = 0; i < elements.length; i++) {
|
|
val = data[i + y + (radius + 1) * width];
|
|
elements[i].push(val);
|
|
sum[i] = sum[i] + val;
|
|
}
|
|
}
|
|
}
|
|
return newData;
|
|
}
|
|
|
|
function Scale(data, width, height) {
|
|
var newData = [];
|
|
var x, y;
|
|
for (y = 0; y < data.length; y += width * 8) {
|
|
for (x = 0; x < width * 4; x += 8) {
|
|
var r = (data[y + x] + data[y + x + 4] + data[y + width * 4 + x] + data[y + width * 4 + x + 4]) / 4;
|
|
newData.push(r);
|
|
var g = (data[y + x + 1] + data[y + x + 4 + 1] + data[y + width * 4 + x + 1] + data[y + width * 4 + x + 4 + 1]) / 4;
|
|
newData.push(g);
|
|
var b = (data[y + x + 2] + data[y + x + 4 + 2] + data[y + width * 4 + x + 2] + data[y + width * 4 + x + 4 + 2]) / 4;
|
|
newData.push(b);
|
|
newData.push(255);
|
|
}
|
|
}
|
|
return new Uint8ClampedArray(newData);
|
|
}
|
|
|
|
function IntensityGradient(data, width) {
|
|
var newData = [];
|
|
var max = Number.MIN_VALUE;
|
|
var min = Number.MAX_VALUE;
|
|
var x, y, i;
|
|
for (y = 0; y < data.length; y += width * 4) {
|
|
for (x = 0; x < width * 4; x += 4) {
|
|
var horizontalDiff = 0;
|
|
var verticalDiff = 0;
|
|
for (i = 1; i < 2; i++) {
|
|
if (x + i * 4 < width * 4) {
|
|
horizontalDiff = horizontalDiff + Math.abs(data[y + x] - data[y + x + i * 4]);
|
|
}
|
|
if (y + width * 4 * i < data.length) {
|
|
verticalDiff += verticalDiff + Math.abs(data[y + x] - data[y + x + width * 4 * i]);
|
|
}
|
|
}
|
|
var diff = horizontalDiff - verticalDiff;
|
|
max = diff > max ? diff : max;
|
|
min = diff < min ? diff : min;
|
|
newData.push(diff);
|
|
}
|
|
}
|
|
if (min < 0) {
|
|
for (i = 0; i < newData.length; i++) {
|
|
newData[i] = newData[i] - min;
|
|
}
|
|
min = 0;
|
|
}
|
|
return newData;
|
|
}
|
|
|
|
function greyScale(data) {
|
|
var i;
|
|
for (i = 0; i < data.length; i += 4) {
|
|
var max = 0;
|
|
var min = 255;
|
|
max = data[i] > max ? data[i] : max;
|
|
max = data[i + 1] > max ? data[i + 1] : max;
|
|
max = data[i + 2] > max ? data[i + 2] : max;
|
|
min = data[i] < min ? data[i] : min;
|
|
min = data[i + 1] < min ? data[i + 1] : min;
|
|
min = data[i + 2] < min ? data[i + 2] : min;
|
|
data[i] = data[i + 1] = data[i + 2] = (max + min) / 2;
|
|
}
|
|
}
|
|
|
|
function histogram(data) {
|
|
var i;
|
|
var hist = [];
|
|
for (i = 0; i < 256; i++) {
|
|
hist[i] = 0;
|
|
}
|
|
for (i = 0; i < data.length; i += 4) {
|
|
hist[data[i]] = hist[data[i]] + 1;
|
|
}
|
|
return hist;
|
|
}
|
|
|
|
function otsu(histogram, total) {
|
|
var i;
|
|
var sum = 0;
|
|
for (i = 1; i < histogram.length; ++i) sum += i * histogram[i];
|
|
var sumB = 0;
|
|
var wB = 0;
|
|
var wF = 0;
|
|
var mB;
|
|
var mF;
|
|
var max = 0.0;
|
|
var between = 0.0;
|
|
var threshold1 = 0.0;
|
|
var threshold2 = 0.0;
|
|
for (i = 0; i < histogram.length; ++i) {
|
|
wB += histogram[i];
|
|
if (wB === 0) continue;
|
|
wF = total - wB;
|
|
if (wF === 0) break;
|
|
sumB += i * histogram[i];
|
|
mB = sumB / wB;
|
|
mF = (sum - sumB) / wF;
|
|
between = wB * wF * Math.pow(mB - mF, 2);
|
|
if (between >= max) {
|
|
threshold1 = i;
|
|
if (between > max) {
|
|
threshold2 = i;
|
|
}
|
|
max = between;
|
|
}
|
|
}
|
|
return (threshold1 + threshold2) / 2.0;
|
|
}
|
|
|
|
function CreateImageData() {
|
|
Image.data = new Uint8ClampedArray(Image.width * Image.height * 4);
|
|
var Converter;
|
|
var x, y;
|
|
for (y = 0; y < Image.height; y++) {
|
|
for (x = 0; x < Image.width; x++) {
|
|
Converter = y * 4 * Image.width;
|
|
Image.data[Converter + x * 4] = Image.table[x][y][0];
|
|
Image.data[Converter + x * 4 + 1] = Image.table[x][y][1];
|
|
Image.data[Converter + x * 4 + 2] = Image.table[x][y][2];
|
|
Image.data[Converter + x * 4 + 3] = Image.table[x][y][3];
|
|
}
|
|
}
|
|
}
|
|
|
|
function CreateScanImageData() {
|
|
ScanImage.data = new Uint8ClampedArray(ScanImage.width * ScanImage.height * 4);
|
|
var Converter;
|
|
var x, y;
|
|
for (y = 0; y < ScanImage.height; y++) {
|
|
for (x = 0; x < ScanImage.width; x++) {
|
|
Converter = y * 4 * ScanImage.width;
|
|
ScanImage.data[Converter + x * 4] = ScanImage.table[x][y][0];
|
|
ScanImage.data[Converter + x * 4 + 1] = ScanImage.table[x][y][1];
|
|
ScanImage.data[Converter + x * 4 + 2] = ScanImage.table[x][y][2];
|
|
ScanImage.data[Converter + x * 4 + 3] = ScanImage.table[x][y][3];
|
|
}
|
|
}
|
|
}
|
|
|
|
function CreateTable() {
|
|
Image.table = [];
|
|
var tempArray = [];
|
|
var i, j;
|
|
for (i = 0; i < Image.width * 4; i += 4) {
|
|
tempArray = [];
|
|
for (j = i; j < Image.data.length; j += Image.width * 4) {
|
|
tempArray.push([Image.data[j], Image.data[j + 1], Image.data[j + 2], Image.data[j + 3]]);
|
|
}
|
|
Image.table.push(tempArray);
|
|
}
|
|
}
|
|
|
|
function CreateScanTable() {
|
|
ScanImage.table = [];
|
|
var tempArray = [];
|
|
var i, j;
|
|
for (i = 0; i < ScanImage.width * 4; i += 4) {
|
|
tempArray = [];
|
|
for (j = i; j < ScanImage.data.length; j += ScanImage.width * 4) {
|
|
tempArray.push([ScanImage.data[j], ScanImage.data[j + 1], ScanImage.data[j + 2], ScanImage.data[j + 3]]);
|
|
}
|
|
ScanImage.table.push(tempArray);
|
|
}
|
|
}
|
|
|
|
function EnlargeTable(h, w) {
|
|
var TempArray = [];
|
|
var x, y, i;
|
|
for (x = 0; x < Image.width; x++) {
|
|
TempArray = [];
|
|
for (y = 0; y < Image.height; y++) {
|
|
for (i = 0; i < h; i++) {
|
|
TempArray.push(Image.table[x][y]);
|
|
}
|
|
}
|
|
Image.table[x] = TempArray.slice();
|
|
}
|
|
TempArray = Image.table.slice();
|
|
for (x = 0; x < Image.width; x++) {
|
|
for (i = 0; i < w; i++) {
|
|
Image.table[x * w + i] = TempArray[x].slice();
|
|
}
|
|
}
|
|
Image.width = Image.table.length;
|
|
Image.height = Image.table[0].length;
|
|
CreateImageData();
|
|
}
|
|
|
|
function ScaleHeight(scale) {
|
|
var tempArray = [];
|
|
var avrgRed = 0;
|
|
var avrgGreen = 0;
|
|
var avrgBlue = 0;
|
|
var i, j, k;
|
|
for (i = 0; i < Image.height - scale; i += scale) {
|
|
for (j = 0; j < Image.width; j++) {
|
|
avrgRed = 0;
|
|
avrgGreen = 0;
|
|
avrgBlue = 0;
|
|
for (k = i; k < i + scale; k++) {
|
|
avrgRed += Image.table[j][k][0];
|
|
avrgGreen += Image.table[j][k][1];
|
|
avrgBlue += Image.table[j][k][2];
|
|
}
|
|
tempArray.push(avrgRed / scale);
|
|
tempArray.push(avrgGreen / scale);
|
|
tempArray.push(avrgBlue / scale);
|
|
tempArray.push(255);
|
|
}
|
|
}
|
|
return new Uint8ClampedArray(tempArray);
|
|
}
|
|
|
|
function Intersects(rectOne, rectTwo) {
|
|
return (rectOne[0][0] <= rectTwo[0][1] && rectTwo[0][0] <= rectOne[0][1] && rectOne[1][0] <= rectTwo[1][1] && rectTwo[1][0] <= rectOne[1][1]);
|
|
}
|
|
|
|
function maxLocalization(max, maxPos, data) {
|
|
var originalMax = max;
|
|
var rects = [];
|
|
var x, y, i;
|
|
do {
|
|
var startX = maxPos % Image.width;
|
|
var startY = (maxPos - startX) / Image.width;
|
|
var minY = 0;
|
|
var maxY = Image.height;
|
|
var minX = 0;
|
|
var maxX = Image.width - 1;
|
|
for (y = startY; y < Image.height - 1; y++) {
|
|
if (Image.table[startX][y + 1][0] === 0) {
|
|
maxY = y;
|
|
break;
|
|
}
|
|
}
|
|
for (y = startY; y > 0; y--) {
|
|
if (Image.table[startX][y - 1][0] === 0) {
|
|
minY = y;
|
|
break;
|
|
}
|
|
}
|
|
for (x = startX; x < Image.width - 1; x++) {
|
|
if (Image.table[x + 1][startY][0] === 0) {
|
|
maxX = x;
|
|
break;
|
|
}
|
|
}
|
|
for (x = startX; x > 0; x--) {
|
|
if (Image.table[x - 1][startY][0] === 0) {
|
|
minX = x;
|
|
break;
|
|
}
|
|
}
|
|
for (y = minY * Image.width; y <= maxY * Image.width; y += Image.width) {
|
|
for (x = minX; x <= maxX; x++) {
|
|
data[y + x] = 0;
|
|
}
|
|
}
|
|
var newRect = [
|
|
[minX, maxX],
|
|
[minY, maxY]
|
|
];
|
|
for (i = 0; i < rects.length; i++) {
|
|
if (Intersects(newRect, rects[i])) {
|
|
if (rects[i][0][1] - rects[i][0][0] > newRect[0][1] - newRect[0][0]) {
|
|
rects[i][0][0] = rects[i][0][0] < newRect[0][0] ? rects[i][0][0] : newRect[0][0];
|
|
rects[i][0][1] = rects[i][0][1] > newRect[0][1] ? rects[i][0][1] : newRect[0][1];
|
|
newRect = [];
|
|
break;
|
|
} else {
|
|
rects[i][0][0] = rects[i][0][0] < newRect[0][0] ? rects[i][0][0] : newRect[0][0];
|
|
rects[i][0][1] = rects[i][0][1] > newRect[0][1] ? rects[i][0][1] : newRect[0][1];
|
|
rects[i][1][0] = newRect[1][0];
|
|
rects[i][1][1] = newRect[1][1];
|
|
newRect = [];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (newRect.length > 0) {
|
|
rects.push(newRect);
|
|
}
|
|
max = 0;
|
|
maxPos = 0;
|
|
var newMaxPos = 0;
|
|
for (i = 0; i < data.length; i++) {
|
|
if (data[i] > max) {
|
|
max = data[i];
|
|
maxPos = i;
|
|
}
|
|
}
|
|
} while (max > originalMax * 0.70);
|
|
return rects;
|
|
}
|
|
|
|
function ImgProcessing() {
|
|
greyScale(Image.data);
|
|
var newData = IntensityGradient(Image.data, Image.width);
|
|
newData = BoxFilter(newData, Image.width, 15);
|
|
var min = newData[0];
|
|
var i, x, y;
|
|
for (i = 1; i < newData.length; i++) {
|
|
min = min > newData[i] ? newData[i] : min;
|
|
}
|
|
var max = 0;
|
|
var maxPos = 0;
|
|
var avrgLight = 0;
|
|
for (i = 0; i < newData.length; i++) {
|
|
newData[i] = Math.round((newData[i] - min));
|
|
avrgLight += newData[i];
|
|
if (max < newData[i]) {
|
|
max = newData[i];
|
|
maxPos = i;
|
|
}
|
|
}
|
|
avrgLight /= newData.length;
|
|
if (avrgLight < 15) {
|
|
newData = BoxFilter(newData, Image.width, 8);
|
|
min = newData[0];
|
|
for (i = 1; i < newData.length; i++) {
|
|
min = min > newData[i] ? newData[i] : min;
|
|
}
|
|
max = 0;
|
|
maxPos = 0;
|
|
for (i = 0; i < newData.length; i++) {
|
|
newData[i] = Math.round((newData[i] - min));
|
|
if (max < newData[i]) {
|
|
max = newData[i];
|
|
maxPos = i;
|
|
}
|
|
}
|
|
}
|
|
var hist = [];
|
|
for (i = 0; i <= max; i++) {
|
|
hist[i] = 0;
|
|
}
|
|
for (i = 0; i < newData.length; i++) {
|
|
hist[newData[i]] = hist[newData[i]] + 1;
|
|
}
|
|
var thresh = otsu(hist, newData.length);
|
|
for (i = 0; i < newData.length; i++) {
|
|
if (newData[i] < thresh) {
|
|
Image.data[i * 4] = Image.data[i * 4 + 1] = Image.data[i * 4 + 2] = 0;
|
|
} else {
|
|
Image.data[i * 4] = Image.data[i * 4 + 1] = Image.data[i * 4 + 2] = 255;
|
|
}
|
|
}
|
|
CreateTable();
|
|
var rects = maxLocalization(max, maxPos, newData);
|
|
var feedBack = [];
|
|
for (i = 0; i < rects.length; i++) {
|
|
feedBack.push({
|
|
x: rects[i][0][0],
|
|
y: rects[i][1][0],
|
|
width: rects[i][0][1] - rects[i][0][0],
|
|
height: rects[i][1][1] - rects[i][1][0]
|
|
});
|
|
}
|
|
if (feedBack.length > 0) postMessage({
|
|
result: feedBack,
|
|
success: "localization"
|
|
});
|
|
allTables = [];
|
|
for (i = 0; i < rects.length; i++) {
|
|
var newTable = [];
|
|
for (x = rects[i][0][0] * 2; x < rects[i][0][1] * 2; x++) {
|
|
var tempArray = [];
|
|
for (y = rects[i][1][0] * 2; y < rects[i][1][1] * 2; y++) {
|
|
tempArray.push([ScanImage.table[x][y][0], ScanImage.table[x][y][1], ScanImage.table[x][y][2], 255]);
|
|
}
|
|
newTable.push(tempArray);
|
|
}
|
|
if (newTable.length < 1) continue;
|
|
Image.table = newTable;
|
|
Image.width = newTable.length;
|
|
Image.height = newTable[0].length;
|
|
CreateImageData();
|
|
allTables.push({
|
|
table: newTable,
|
|
data: new Uint8ClampedArray(Image.data),
|
|
width: Image.width,
|
|
height: Image.height
|
|
});
|
|
}
|
|
}
|
|
|
|
function showImage(data, width, height) {
|
|
postMessage({
|
|
result: data,
|
|
width: width,
|
|
height: height,
|
|
success: "image"
|
|
});
|
|
}
|
|
|
|
function Main() {
|
|
ImgProcessing();
|
|
var allResults = [];
|
|
var tempObj;
|
|
var tempData;
|
|
var hist;
|
|
var val;
|
|
var thresh;
|
|
var start;
|
|
var end;
|
|
var z, i;
|
|
for (z = 0; z < allTables.length; z++) {
|
|
Image = allTables[z];
|
|
var scaled = ScaleHeight(30);
|
|
var variationData;
|
|
var incrmt = 0;
|
|
var format = "";
|
|
var first = true;
|
|
var eanStatistics = {};
|
|
var eanOrder = [];
|
|
Selection = false;
|
|
do {
|
|
tempData = scaled.subarray(incrmt, incrmt + Image.width * 4);
|
|
hist = [];
|
|
for (i = 0; i < 256; i++) {
|
|
hist[i] = 0;
|
|
}
|
|
for (i = 0; i < tempData.length; i += 4) {
|
|
val = Math.round((tempData[i] + tempData[i + 1] + tempData[i + 2]) / 3);
|
|
hist[val] = hist[val] + 1;
|
|
}
|
|
thresh = otsu(hist, tempData.length / 4);
|
|
start = thresh < 41 ? 1 : thresh - 40;
|
|
end = thresh > 254 - 40 ? 254 : thresh + 40;
|
|
variationData = yStraighten(tempData, start, end);
|
|
Selection = BinaryString(variationData);
|
|
if (Selection.string) {
|
|
format = Selection.format;
|
|
tempObj = Selection;
|
|
Selection = Selection.string;
|
|
if (format === "EAN-13") {
|
|
if (typeof eanStatistics[Selection] === 'undefined') {
|
|
eanStatistics[Selection] = {
|
|
count: 1,
|
|
correction: tempObj.correction
|
|
};
|
|
eanOrder.push(Selection);
|
|
} else {
|
|
eanStatistics[Selection].count = eanStatistics[Selection].count + 1;
|
|
eanStatistics[Selection].correction = eanStatistics[Selection].correction + tempObj.correction;
|
|
}
|
|
Selection = false;
|
|
}
|
|
} else {
|
|
Selection = false;
|
|
}
|
|
incrmt += Image.width * 4;
|
|
} while (!Selection && incrmt < scaled.length);
|
|
if (Selection && format !== "EAN-13") allResults.push({
|
|
Format: format,
|
|
Value: Selection
|
|
});
|
|
if (format === "EAN-13") Selection = false;
|
|
if (!Selection) {
|
|
EnlargeTable(4, 2);
|
|
incrmt = 0;
|
|
scaled = ScaleHeight(20);
|
|
do {
|
|
tempData = scaled.subarray(incrmt, incrmt + Image.width * 4);
|
|
hist = [];
|
|
for (i = 0; i < 256; i++) {
|
|
hist[i] = 0;
|
|
}
|
|
for (i = 0; i < tempData.length; i += 4) {
|
|
val = Math.round((tempData[i] + tempData[i + 1] + tempData[i + 2]) / 3);
|
|
hist[val] = hist[val] + 1;
|
|
}
|
|
thresh = otsu(hist, tempData.length / 4);
|
|
start = thresh < 40 ? 0 : thresh - 40;
|
|
end = thresh > 255 - 40 ? 255 : thresh + 40;
|
|
variationData = yStraighten(tempData, start, end);
|
|
Selection = BinaryString(variationData);
|
|
if (Selection.string) {
|
|
format = Selection.format;
|
|
tempObj = Selection;
|
|
Selection = Selection.string;
|
|
if (format === "EAN-13") {
|
|
if (typeof eanStatistics[Selection] === 'undefined') {
|
|
eanStatistics[Selection] = {
|
|
count: 1,
|
|
correction: tempObj.correction
|
|
};
|
|
eanOrder.push(Selection);
|
|
} else {
|
|
eanStatistics[Selection].count = eanStatistics[Selection].count + 1;
|
|
eanStatistics[Selection].correction = eanStatistics[Selection].correction + tempObj.correction;
|
|
}
|
|
Selection = false;
|
|
}
|
|
} else {
|
|
Selection = false;
|
|
}
|
|
incrmt += Image.width * 4;
|
|
} while (!Selection && incrmt < scaled.length);
|
|
if (format === "EAN-13") {
|
|
var points = {};
|
|
for (var key in eanStatistics) {
|
|
eanStatistics[key].correction = eanStatistics[key].correction / eanStatistics[key].count;
|
|
var pointTemp = eanStatistics[key].correction;
|
|
pointTemp -= eanStatistics[key].count;
|
|
pointTemp += eanOrder.indexOf(key);
|
|
points[key] = pointTemp;
|
|
}
|
|
var minPoints = Number.POSITIVE_INFINITY;
|
|
var tempString = "";
|
|
for (var point in points) {
|
|
if (points[point] < minPoints) {
|
|
minPoints = points[point];
|
|
tempString = key;
|
|
}
|
|
}
|
|
if (minPoints < 11) {
|
|
Selection = tempString;
|
|
} else {
|
|
Selection = false;
|
|
}
|
|
}
|
|
if (Selection) allResults.push({
|
|
Format: format,
|
|
Value: Selection
|
|
});
|
|
}
|
|
if (allResults.length > 0 && !Multiple) break;
|
|
}
|
|
return allResults;
|
|
}
|
|
|
|
function yStraighten(img, start, end) {
|
|
var average = 0;
|
|
var threshold;
|
|
var newImg = new Uint8ClampedArray(Image.width * (end - start + 1) * 4);
|
|
var i, j;
|
|
for (i = 0; i < newImg.length; i++) {
|
|
newImg[i] = 255;
|
|
}
|
|
for (i = 0; i < Image.width * 4; i += 4) {
|
|
threshold = end;
|
|
average = (img[i] + img[i + 1] + img[i + 2]) / 3;
|
|
if (i < Image.width * 4 - 4) {
|
|
average += (img[i + 4] + img[i + 5] + img[i + 6]) / 3;
|
|
average /= 2;
|
|
}
|
|
for (j = i; j < newImg.length; j += Image.width * 4) {
|
|
if (average < threshold) {
|
|
newImg[j] = newImg[j + 1] = newImg[j + 2] = 0;
|
|
}
|
|
threshold--;
|
|
}
|
|
}
|
|
return newImg;
|
|
}
|
|
|
|
function CheckEan13(values, middle) {
|
|
if (middle) {
|
|
if (values.length !== 5) return false;
|
|
} else {
|
|
if (values.length !== 3) return false;
|
|
}
|
|
var avrg = 0;
|
|
var i;
|
|
for (i = 0; i < values.length; i++) {
|
|
avrg += values[i];
|
|
}
|
|
avrg /= values.length;
|
|
for (i = 0; i < values.length; i++) {
|
|
if (values[i] / avrg < 0.5 || values[i] / avrg > 1.5) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function TwoOfFiveStartEnd(values, start) {
|
|
if (values.length < 5 || values.length > 6) return false;
|
|
var maximum = 0;
|
|
var TwoOfFiveMax = [0, 0];
|
|
var u;
|
|
for (u = 0; u < values.length; u++) {
|
|
if (values[u] > maximum) {
|
|
maximum = values[u];
|
|
TwoOfFiveMax[0] = u;
|
|
}
|
|
}
|
|
maximum = 0;
|
|
for (u = 0; u < values.length; u++) {
|
|
if (u === TwoOfFiveMax[0]) continue;
|
|
if (values[u] > maximum) {
|
|
maximum = values[u];
|
|
TwoOfFiveMax[1] = u;
|
|
}
|
|
}
|
|
if (start) {
|
|
return TwoOfFiveMax[0] + TwoOfFiveMax[1] === 2;
|
|
} else {
|
|
return TwoOfFiveMax[0] + TwoOfFiveMax[1] === 2;
|
|
}
|
|
}
|
|
|
|
function CheckInterleaved(values, start) {
|
|
var average = 0;
|
|
var i;
|
|
for (i = 0; i < values.length; i++) {
|
|
average += values[i];
|
|
}
|
|
average /= 4;
|
|
if (start) {
|
|
if (values.length !== 4) return false;
|
|
for (i = 0; i < values.length; i++) {
|
|
if (values[i] / average < 0.5 || values[i] / average > 1.5) return false;
|
|
}
|
|
return true;
|
|
} else {
|
|
if (values.length !== 3) return false;
|
|
var max = 0;
|
|
var pos;
|
|
for (i = 0; i < values.length; i++) {
|
|
if (values[i] > max) {
|
|
max = values[i];
|
|
pos = i;
|
|
}
|
|
}
|
|
if (pos !== 0) return false;
|
|
if (values[0] / average < 1.5 || values[0] / average > 2.5) return false;
|
|
for (i = 1; i < values.length; i++) {
|
|
if (values[i] / average < 0.5 || values[i] / average > 1.5) return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
function BinaryConfiguration(binaryString, type) {
|
|
var result = [];
|
|
var binTemp = [];
|
|
var count = 0;
|
|
var bars;
|
|
var len;
|
|
var totalBars;
|
|
var i;
|
|
if (type === "Code128" || type === "Code93") {
|
|
totalBars = 6;
|
|
len = binaryString[0];
|
|
if (type === "Code128") len /= 2;
|
|
for (i = 0; i < binaryString.length; i++) {
|
|
if (binaryString[i] > len * 6) {
|
|
binaryString.splice(i, binaryString.length);
|
|
break;
|
|
}
|
|
}
|
|
do {
|
|
if (binaryString.length === 7 && type === "Code128") {
|
|
result.push(binaryString.splice(0, binaryString.length));
|
|
} else {
|
|
result.push(binaryString.splice(0, totalBars));
|
|
}
|
|
if (type === "Code93" && binaryString.length < 6) binaryString.splice(0, totalBars);
|
|
} while (binaryString.length > 0);
|
|
}
|
|
if (type === "Code39") {
|
|
totalBars = 9;
|
|
len = binaryString[0];
|
|
for (i = 0; i < binaryString.length; i++) {
|
|
if (binaryString[i] > len * 5) {
|
|
binaryString.splice(i, binaryString.length);
|
|
break;
|
|
}
|
|
}
|
|
do {
|
|
result.push(binaryString.splice(0, totalBars));
|
|
binaryString.splice(0, 1);
|
|
} while (binaryString.length > 0);
|
|
}
|
|
if (type === "EAN-13") {
|
|
totalBars = 4;
|
|
len = binaryString[0];
|
|
var secureCount = 0;
|
|
for (i = 0; i < binaryString.length; i++) {
|
|
if (binaryString[i] > len * 6) {
|
|
binaryString.splice(i, binaryString.length);
|
|
break;
|
|
}
|
|
}
|
|
if (CheckEan13(binaryString.splice(0, 3), false)) secureCount++;
|
|
count = 0;
|
|
do {
|
|
result.push(binaryString.splice(0, totalBars));
|
|
count++;
|
|
if (count === 6)
|
|
if (CheckEan13(binaryString.splice(0, 5), true)) secureCount++;
|
|
} while (result.length < 12 && binaryString.length > 0);
|
|
if (CheckEan13(binaryString.splice(0, 3), false)) secureCount++;
|
|
if (secureCount < 2) return [];
|
|
}
|
|
if (type === "2Of5") {
|
|
totalBars = 5;
|
|
len = binaryString[0] / 2;
|
|
for (i = 0; i < binaryString.length; i++) {
|
|
if (binaryString[i] > len * 5) {
|
|
binaryString.splice(i, binaryString.length);
|
|
break;
|
|
}
|
|
}
|
|
var temp = binaryString.splice(0, 6);
|
|
result.push(temp);
|
|
do {
|
|
binTemp = [];
|
|
for (i = 0; i < totalBars; i++) {
|
|
binTemp.push(binaryString.splice(0, 1)[0]);
|
|
// binaryString.splice(0, 1)[0];
|
|
}
|
|
result.push(binTemp);
|
|
if (binaryString.length === 5) result.push(binaryString.splice(0, 5));
|
|
} while (binaryString.length > 0);
|
|
}
|
|
if (type === "Inter2Of5") {
|
|
totalBars = 5;
|
|
len = binaryString[0];
|
|
for (i = 0; i < binaryString.length; i++) {
|
|
if (binaryString[i] > len * 5) {
|
|
binaryString.splice(i, binaryString.length);
|
|
break;
|
|
}
|
|
}
|
|
result.push(binaryString.splice(0, 4));
|
|
var binTempWhite = [];
|
|
do {
|
|
binTemp = [];
|
|
binTempWhite = [];
|
|
for (i = 0; i < totalBars; i++) {
|
|
binTemp.push(binaryString.splice(0, 1)[0]);
|
|
binTempWhite.push(binaryString.splice(0, 1)[0]);
|
|
}
|
|
result.push(binTemp);
|
|
result.push(binTempWhite);
|
|
if (binaryString.length === 3) result.push(binaryString.splice(0, 3));
|
|
} while (binaryString.length > 0);
|
|
}
|
|
if (type === "Codabar") {
|
|
totalBars = 7;
|
|
len = binaryString[0];
|
|
for (i = 0; i < binaryString.length; i++) {
|
|
if (binaryString[i] > len * 5) {
|
|
binaryString.splice(i, binaryString.length);
|
|
break;
|
|
}
|
|
}
|
|
do {
|
|
result.push(binaryString.splice(0, totalBars));
|
|
binaryString.splice(0, 1);
|
|
} while (binaryString.length > 0);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function BinaryString(img, type) {
|
|
var binaryString = [];
|
|
var binTemp = [];
|
|
var container = 255;
|
|
var count = 0;
|
|
var format;
|
|
var tempString;
|
|
var j, i;
|
|
for (j = 0; j < img.length - Image.width * 4; j += Image.width * 4) {
|
|
var SlicedArray = img.subarray(j, j + Image.width * 4);
|
|
binaryString = [];
|
|
i = 0;
|
|
while (SlicedArray[i] === 255) {
|
|
i += 4;
|
|
}
|
|
while (i < SlicedArray.length) {
|
|
count = 0;
|
|
container = SlicedArray[i];
|
|
while (SlicedArray[i] === container && i < SlicedArray.length) {
|
|
count++;
|
|
i += 4;
|
|
}
|
|
binaryString.push(count);
|
|
}
|
|
if (binaryString.length > 2 && binaryString[0] <= binaryString[1] / 10) {
|
|
binaryString.splice(0, 2);
|
|
}
|
|
var binaryHolder = binaryString.slice();
|
|
var success = false;
|
|
for (i = 0; i < FormatPriority.length; i++) {
|
|
binaryString = binaryHolder.slice();
|
|
var first;
|
|
var second;
|
|
binaryString = BinaryConfiguration(binaryString, FormatPriority[i]);
|
|
if (FormatPriority[i] === "2Of5" || FormatPriority[i] === "Inter2Of5") {
|
|
first = binaryString.splice(0, 1)[0];
|
|
second = binaryString.splice(binaryString.length - 1, 1)[0];
|
|
}
|
|
binTemp = Distribution(binaryString, FormatPriority[i]);
|
|
if (FormatPriority[i] === "EAN-13") {
|
|
binaryString = binTemp.data;
|
|
corrections = binTemp.correction;
|
|
} else {
|
|
binaryString = binTemp;
|
|
}
|
|
if (typeof binaryString === 'undefined') continue;
|
|
if (binaryString.length > 4 || (FormatPriority[i] === "Code39" && binaryString.length > 2)) {
|
|
if (FormatPriority[i] === "Code128") {
|
|
if (CheckCode128(binaryString)) {
|
|
binaryString = DecodeCode128(binaryString);
|
|
success = true;
|
|
}
|
|
} else if (FormatPriority[i] === "Code93") {
|
|
if (CheckCode93(binaryString)) {
|
|
binaryString = DecodeCode93(binaryString);
|
|
success = true;
|
|
}
|
|
} else if (FormatPriority[i] === "Code39") {
|
|
if (CheckCode39(binaryString)) {
|
|
binaryString = DecodeCode39(binaryString);
|
|
success = true;
|
|
}
|
|
} else if (FormatPriority[i] === "EAN-13") {
|
|
tempString = DecodeEAN13(binaryString);
|
|
if (tempString) {
|
|
if (tempString.length === 13) {
|
|
binaryString = tempString;
|
|
success = true;
|
|
}
|
|
}
|
|
} else if (FormatPriority[i] === "2Of5" || FormatPriority[i] === "Inter2Of5") {
|
|
if (FormatPriority[i] === "2Of5") {
|
|
if (typeof first !== 'undefined')
|
|
if (!TwoOfFiveStartEnd(first, true)) continue;
|
|
if (typeof second !== 'undefined')
|
|
if (!TwoOfFiveStartEnd(second, false)) continue;
|
|
}
|
|
if (FormatPriority[i] === "Inter2Of5") {
|
|
if (typeof first !== 'undefined')
|
|
if (!CheckInterleaved(first, true)) continue;
|
|
if (typeof second !== 'undefined')
|
|
if (!CheckInterleaved(second, false)) continue;
|
|
}
|
|
tempString = Decode2Of5(binaryString);
|
|
if (tempString) {
|
|
binaryString = tempString;
|
|
success = true;
|
|
}
|
|
} else if (FormatPriority[i] === "Codabar") {
|
|
tempString = DecodeCodaBar(binaryString);
|
|
if (tempString) {
|
|
binaryString = tempString;
|
|
success = true;
|
|
}
|
|
}
|
|
}
|
|
if (success) {
|
|
format = FormatPriority[i];
|
|
if (format === "Inter2Of5") format = "Interleaved 2 of 5";
|
|
if (format === "2Of5") format = "Standard 2 of 5";
|
|
break;
|
|
}
|
|
}
|
|
if (success) break;
|
|
}
|
|
if (format === "Code128") {
|
|
if (typeof binaryString.string === 'string') {
|
|
return binaryString;
|
|
} else {
|
|
return {
|
|
string: false
|
|
};
|
|
}
|
|
}
|
|
if (typeof binaryString === 'string') {
|
|
if (format === "EAN-13") {
|
|
return {
|
|
string: binaryString,
|
|
format: format,
|
|
correction: corrections
|
|
};
|
|
} else {
|
|
return {
|
|
string: binaryString,
|
|
format: format
|
|
};
|
|
}
|
|
} else {
|
|
return {
|
|
string: false
|
|
};
|
|
}
|
|
}
|
|
|
|
function Distribution(totalBinArray, type) {
|
|
var testData = 0;
|
|
var result = [];
|
|
var totalBars;
|
|
var total;
|
|
var maxLength;
|
|
var k, i, j;
|
|
var blackMax;
|
|
var whiteMax;
|
|
var wideAvrg;
|
|
var narrowAvrg;
|
|
var prevPos;
|
|
var wideValues;
|
|
var max;
|
|
type = availableFormats.indexOf(type);
|
|
if (type === 0) {
|
|
total = 11;
|
|
totalBars = 6;
|
|
maxLength = 4;
|
|
} else if (type === 1) {
|
|
total = 9;
|
|
totalBars = 6;
|
|
maxLength = 4;
|
|
} else if (type === 2) {
|
|
total = 12;
|
|
totalBars = 9;
|
|
} else if (type === 3 && totalBinArray.length === 7) {
|
|
total = 4;
|
|
totalBars = 2;
|
|
maxLength = 2;
|
|
} else if (type === 3) {
|
|
total = 7;
|
|
totalBars = 4;
|
|
maxLength = 4;
|
|
} else if (type === 6) {
|
|
totalBars = 7;
|
|
}
|
|
for (k = 0; k < totalBinArray.length; k++) {
|
|
var BinArray = totalBinArray[k];
|
|
var sum = 0;
|
|
var counter = 0;
|
|
var tempBin = [];
|
|
var narrowArr = [];
|
|
var wideArr = [];
|
|
if (type === 6) {
|
|
var upperTolerance = 1.5;
|
|
var lowerTolerance = 1 / 2;
|
|
if (BinArray.length !== 7) return [];
|
|
if (k === 0 || k === totalBinArray.length - 1) {
|
|
whiteMax = [
|
|
[0, 0],
|
|
[0, 0]
|
|
];
|
|
blackMax = [0, 0];
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i % 2 === 0) {
|
|
if (BinArray[i] > blackMax[0]) {
|
|
blackMax[0] = BinArray[i];
|
|
blackMax[1] = i;
|
|
}
|
|
} else {
|
|
if (BinArray[i] > whiteMax[0][0]) {
|
|
whiteMax[0][0] = BinArray[i];
|
|
prevPos = whiteMax[0][1];
|
|
whiteMax[0][1] = i;
|
|
i = prevPos - 1;
|
|
continue;
|
|
}
|
|
if (BinArray[i] > whiteMax[1][0] && i !== whiteMax[0][1]) {
|
|
whiteMax[1][0] = BinArray[i];
|
|
whiteMax[1][1] = i;
|
|
}
|
|
}
|
|
}
|
|
if (SecureCodabar) {
|
|
wideAvrg = whiteMax[0][0] + whiteMax[1][0] + blackMax[0];
|
|
wideAvrg /= 3;
|
|
wideValues = [whiteMax[0][0], whiteMax[1][0], blackMax[0]];
|
|
for (i = 0; i < wideValues.length; i++) {
|
|
if (wideValues[i] / wideAvrg > upperTolerance || wideValues[i] / wideAvrg < lowerTolerance) return [];
|
|
}
|
|
narrowAvrg = 0;
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i === blackMax[1] || i === whiteMax[0][1] || i === whiteMax[1][1]) continue;
|
|
narrowAvrg += BinArray[i];
|
|
}
|
|
narrowAvrg /= 4;
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i === blackMax[1] || i === whiteMax[0][1] || i === whiteMax[1][1]) continue;
|
|
if (BinArray[i] / narrowAvrg > upperTolerance || BinArray[i] / narrowAvrg < lowerTolerance) return [];
|
|
}
|
|
}
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i === blackMax[1] || i === whiteMax[0][1] || i === whiteMax[1][1]) {
|
|
tempBin.push(1);
|
|
} else {
|
|
tempBin.push(0);
|
|
}
|
|
}
|
|
} else {
|
|
blackMax = [0, 0];
|
|
whiteMax = [0, 0];
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i % 2 === 0) {
|
|
if (BinArray[i] > blackMax[0]) {
|
|
blackMax[0] = BinArray[i];
|
|
blackMax[1] = i;
|
|
}
|
|
} else {
|
|
if (BinArray[i] > whiteMax[0]) {
|
|
whiteMax[0] = BinArray[i];
|
|
whiteMax[1] = i;
|
|
}
|
|
}
|
|
}
|
|
if (blackMax[0] / whiteMax[0] > 1.55) {
|
|
var tempArray = blackMax;
|
|
blackMax = [tempArray, [0, 0],
|
|
[0, 0]
|
|
];
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i % 2 === 0) {
|
|
if (BinArray[i] > blackMax[1][0] && i !== blackMax[0][1]) {
|
|
blackMax[1][0] = BinArray[i];
|
|
prevPos = blackMax[1][1];
|
|
blackMax[1][1] = i;
|
|
i = prevPos - 1;
|
|
continue;
|
|
}
|
|
if (BinArray[i] > blackMax[2][0] && i !== blackMax[0][1] && i !== blackMax[1][1]) {
|
|
blackMax[2][0] = BinArray[i];
|
|
blackMax[2][1] = i;
|
|
}
|
|
}
|
|
}
|
|
if (SecureCodabar) {
|
|
wideAvrg = blackMax[0][0] + blackMax[1][0] + blackMax[2][0];
|
|
wideAvrg /= 3;
|
|
for (i = 0; i < blackMax.length; i++) {
|
|
if (blackMax[i][0] / wideAvrg > upperTolerance || blackMax[i][0] / wideAvrg < lowerTolerance) return [];
|
|
}
|
|
narrowAvrg = 0;
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i === blackMax[0][1] || i === blackMax[1][1] || i === blackMax[2][1]) continue;
|
|
narrowAvrg += BinArray[i];
|
|
}
|
|
narrowAvrg /= 4;
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i === blackMax[0][1] || i === blackMax[1][1] || i === blackMax[2][1]) continue;
|
|
if (BinArray[i] / narrowAvrg > upperTolerance || BinArray[i] / narrowAvrg < lowerTolerance) return [];
|
|
}
|
|
}
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i === blackMax[0][1] || i === blackMax[1][1] || i === blackMax[2][1]) {
|
|
tempBin.push(1);
|
|
} else {
|
|
tempBin.push(0);
|
|
}
|
|
}
|
|
} else {
|
|
if (SecureCodabar) {
|
|
wideAvrg = blackMax[0] + whiteMax[0];
|
|
wideAvrg /= 2;
|
|
if (blackMax[0] / wideAvrg > 1.5 || blackMax[0] / wideAvrg < 0.5) return [];
|
|
if (whiteMax[0] / wideAvrg > 1.5 || whiteMax[0] / wideAvrg < 0.5) return [];
|
|
narrowAvrg = 0;
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i === blackMax[1] || i === whiteMax[1]) continue;
|
|
narrowAvrg += BinArray[i];
|
|
}
|
|
narrowAvrg /= 5;
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i === blackMax[1] || i === whiteMax[1]) continue;
|
|
if (BinArray[i] / narrowAvrg > upperTolerance || BinArray[i] / narrowAvrg < lowerTolerance) return [];
|
|
}
|
|
}
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i === blackMax[1] || i === whiteMax[1]) {
|
|
tempBin.push(1);
|
|
} else {
|
|
tempBin.push(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
result.push(tempBin);
|
|
continue;
|
|
}
|
|
if (type === 4 || type === 5) {
|
|
max = [
|
|
[0, 0],
|
|
[0, 0]
|
|
];
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (!isFinite(BinArray[i])) return [];
|
|
if (BinArray[i] > max[0][0]) {
|
|
max[0][0] = BinArray[i];
|
|
prevPos = max[0][1];
|
|
max[0][1] = i;
|
|
i = prevPos - 1;
|
|
}
|
|
if (BinArray[i] > max[1][0] && i !== max[0][1]) {
|
|
max[1][0] = BinArray[i];
|
|
max[1][1] = i;
|
|
}
|
|
}
|
|
if (Secure2Of5) {
|
|
wideAvrg = max[0][0] + max[1][0];
|
|
wideAvrg /= 2;
|
|
if (max[0][0] / wideAvrg > 1.3 || max[0][0] / wideAvrg < 0.7) return [];
|
|
if (max[1][0] / wideAvrg > 1.3 || max[1][0] / wideAvrg < 0.7) return [];
|
|
narrowAvrg = 0;
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i === max[0][1] || i === max[1][1]) continue;
|
|
narrowAvrg += BinArray[i];
|
|
}
|
|
narrowAvrg /= 3;
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i === max[0][1] || i === max[1][1]) continue;
|
|
if (BinArray[i] / narrowAvrg > 1.3 || BinArray[i] / narrowAvrg < 0.7) return [];
|
|
}
|
|
}
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i === max[0][1] || i === max[1][1]) {
|
|
tempBin.push(1);
|
|
continue;
|
|
}
|
|
tempBin.push(0);
|
|
}
|
|
result.push(tempBin);
|
|
continue;
|
|
}
|
|
while (counter < totalBars) {
|
|
sum += BinArray[counter];
|
|
counter++;
|
|
}
|
|
if (type === 2) {
|
|
var indexCount = [];
|
|
blackMax = [
|
|
[0, 0],
|
|
[0, 0]
|
|
];
|
|
whiteMax = [0, 0];
|
|
for (j = 0; j < BinArray.length; j++) {
|
|
if (j % 2 === 0) {
|
|
if (BinArray[j] > blackMax[0][0]) {
|
|
blackMax[0][0] = BinArray[j];
|
|
prevPos = blackMax[0][1];
|
|
blackMax[0][1] = j;
|
|
j = prevPos;
|
|
}
|
|
if (BinArray[j] > blackMax[1][0] && j !== blackMax[0][1]) {
|
|
blackMax[1][0] = BinArray[j];
|
|
blackMax[1][1] = j;
|
|
}
|
|
} else {
|
|
if (BinArray[j] > whiteMax[0]) {
|
|
whiteMax[0] = BinArray[j];
|
|
whiteMax[1] = j;
|
|
}
|
|
}
|
|
}
|
|
if (whiteMax[0] / blackMax[0][0] > 1.5 && whiteMax[0] / blackMax[1][0] > 1.5) {
|
|
blackMax = [
|
|
[0, 0],
|
|
[0, 0]
|
|
];
|
|
for (j = 0; j < BinArray.length; j++) {
|
|
if (j % 2 !== 0) {
|
|
if (BinArray[j] > blackMax[0][0] && j !== whiteMax[1]) {
|
|
blackMax[0][0] = BinArray[j];
|
|
prevPos = blackMax[0][1];
|
|
blackMax[0][1] = j;
|
|
j = prevPos;
|
|
}
|
|
if (BinArray[j] > blackMax[1][0] && j !== blackMax[0][1] && j !== whiteMax[1]) {
|
|
blackMax[1][0] = BinArray[j];
|
|
blackMax[1][1] = j;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
wideAvrg = blackMax[0][0] + blackMax[1][0] + whiteMax[0];
|
|
wideAvrg /= 3;
|
|
if (blackMax[0][0] / wideAvrg > 1.6 || blackMax[0][0] / wideAvrg < 0.4) return [];
|
|
if (blackMax[1][0] / wideAvrg > 1.6 || blackMax[1][0] / wideAvrg < 0.4) return [];
|
|
if (whiteMax[0] / wideAvrg > 1.6 || whiteMax[0] / wideAvrg < 0.4) return [];
|
|
narrowAvrg = 0;
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i === blackMax[0][1] || i === blackMax[1][1] || i === whiteMax[1]) continue;
|
|
narrowAvrg += BinArray[i];
|
|
}
|
|
narrowAvrg /= 6;
|
|
for (i = 0; i < BinArray.length; i++) {
|
|
if (i === blackMax[0][1] || i === blackMax[1][1] || i === whiteMax[1]) continue;
|
|
if (BinArray[i] / narrowAvrg > 1.6 || BinArray[i] / narrowAvrg < 0.4) return [];
|
|
}
|
|
for (j = 0; j < BinArray.length; j++) {
|
|
if (j === blackMax[0][1] || j === blackMax[1][1] || j === whiteMax[1]) {
|
|
tempBin.push(2);
|
|
} else {
|
|
tempBin.push(1);
|
|
}
|
|
}
|
|
result.push(tempBin);
|
|
continue;
|
|
}
|
|
if (type === 3) {
|
|
max = [
|
|
[0, 0],
|
|
[0, 0],
|
|
[0, 0]
|
|
];
|
|
for (j = 0; j < BinArray.length; j++) {
|
|
if (BinArray[j] > max[0][0]) {
|
|
max[0][0] = BinArray[j];
|
|
prevPos = max[0][1];
|
|
max[0][1] = j;
|
|
j = prevPos;
|
|
}
|
|
if (BinArray[j] > max[1][0] && j !== max[0][1]) {
|
|
max[1][0] = BinArray[j];
|
|
prevPos = max[1][1];
|
|
max[1][1] = j;
|
|
j = prevPos;
|
|
}
|
|
if (BinArray[j] > max[2][0] && j !== max[0][1] && j !== max[1][1]) {
|
|
max[2][0] = BinArray[j];
|
|
max[2][1] = j;
|
|
}
|
|
}
|
|
if (max[0][0] / max[1][0] >= 3) {
|
|
narrowAvrg = 0;
|
|
for (j = 0; j < BinArray.length; j++) {
|
|
if (j === max[0][1]) continue;
|
|
narrowAvrg += BinArray[j];
|
|
}
|
|
narrowAvrg /= 3;
|
|
for (j = 0; j < BinArray.length; j++) {
|
|
if (j === max[0][1]) continue;
|
|
if (BinArray[j] / narrowAvrg < 0.02 || BinArray[j] / narrowAvrg > 3) return {
|
|
data: [],
|
|
correction: 0
|
|
};
|
|
}
|
|
if (max[0][0] / narrowAvrg < 2.2 || max[0][0] / narrowAvrg > 6) return {
|
|
data: [],
|
|
correction: 0
|
|
};
|
|
for (j = 0; j < BinArray.length; j++) {
|
|
if (j === max[0][1]) {
|
|
tempBin.push(4);
|
|
} else {
|
|
tempBin.push(1);
|
|
}
|
|
}
|
|
result.push(tempBin);
|
|
} else if (max[0][0] / max[2][0] > 2) {
|
|
wideAvrg = max[0][0] + max[1][0];
|
|
wideAvrg /= 5;
|
|
if (max[0][0] / (wideAvrg * 3) < 0.02 || max[0][0] / (wideAvrg * 3) > 3) return {
|
|
data: [],
|
|
correction: 0
|
|
};
|
|
if (max[1][0] / (wideAvrg * 2) < 0.02 || max[1][0] / (wideAvrg * 2) > 3) return {
|
|
data: [],
|
|
correction: 0
|
|
};
|
|
narrowAvrg = 0;
|
|
for (j = 0; j < BinArray.length; j++) {
|
|
if (j === max[0][1] || j === max[1][1]) continue;
|
|
narrowAvrg += BinArray[j];
|
|
}
|
|
narrowAvrg /= 2;
|
|
for (j = 0; j < BinArray.length; j++) {
|
|
if (j === max[0][1] || j === max[1][1]) continue;
|
|
if (BinArray[j] / narrowAvrg < 0.02 || BinArray[j] / narrowAvrg > 3) return {
|
|
data: [],
|
|
correction: 0
|
|
};
|
|
}
|
|
for (j = 0; j < BinArray.length; j++) {
|
|
if (j === max[0][1]) {
|
|
tempBin.push(3);
|
|
} else if (j === max[1][1]) {
|
|
tempBin.push(2);
|
|
} else {
|
|
tempBin.push(1);
|
|
}
|
|
}
|
|
result.push(tempBin);
|
|
} else {
|
|
if (max[0][1] % 2 === max[1][1] % 2 && max[0][1] % 2 === max[2][1] % 2) {
|
|
var modMem = max[0][1] % 2;
|
|
max[2] = [0, 0];
|
|
for (j = 0; j < BinArray.length; j++) {
|
|
if (j % 2 === modMem) continue;
|
|
if (BinArray[j] > max[2][0]) {
|
|
max[2][0] = BinArray[j];
|
|
max[2][1] = j;
|
|
}
|
|
}
|
|
}
|
|
wideAvrg = max[0][0] + max[1][0] + max[2][0];
|
|
wideAvrg /= 3;
|
|
for (j = 0; j < max.length; j++) {
|
|
if (max[j][0] / wideAvrg < 0.02 || max[j][0] / wideAvrg > 3) return {
|
|
data: [],
|
|
correction: 0
|
|
};
|
|
}
|
|
var narrow = 0;
|
|
for (j = 0; j < BinArray.length; j++) {
|
|
if (j === max[0][1] || j === max[1][1] || j === max[2][1]) continue;
|
|
narrow = BinArray[j];
|
|
}
|
|
if (wideAvrg / narrow < 0.02 || wideAvrg / narrow > 3) return {
|
|
data: [],
|
|
correction: 0
|
|
};
|
|
for (j = 0; j < BinArray.length; j++) {
|
|
if (j === max[0][1] || j === max[1][1] || j === max[2][1]) {
|
|
tempBin.push(2);
|
|
} else {
|
|
tempBin.push(1);
|
|
}
|
|
}
|
|
result.push(tempBin);
|
|
}
|
|
for (j = 0; j < tempBin.length; j++) {
|
|
testData += Math.abs(tempBin[j] - (BinArray[j] / sum) * total);
|
|
}
|
|
continue;
|
|
}
|
|
counter = 0;
|
|
while (counter < totalBars) {
|
|
tempBin.push((BinArray[counter] / sum) * total);
|
|
counter++;
|
|
}
|
|
counter = 0;
|
|
while (counter < totalBars) {
|
|
tempBin[counter] = tempBin[counter] > maxLength ? maxLength : tempBin[counter];
|
|
tempBin[counter] = tempBin[counter] < 1 ? 1 : tempBin[counter];
|
|
tempBin[counter] = Math.round(tempBin[counter]);
|
|
counter++;
|
|
}
|
|
if (type === 3) {
|
|
var checking = 0;
|
|
for (i = 0; i < tempBin.length; i++) {
|
|
checking += tempBin[i];
|
|
}
|
|
if (checking > 7) {
|
|
max = 0;
|
|
var hitIndex = 0;
|
|
for (i = 0; i < tempBin.length; i++) {
|
|
if (tempBin[i] > max) {
|
|
max = tempBin[i];
|
|
hitIndex = i;
|
|
}
|
|
}
|
|
tempBin[hitIndex] = max - (checking - 7);
|
|
}
|
|
}
|
|
if (type === 3) {
|
|
for (i = 0; i < tempBin.length; i++) {
|
|
testData += Math.abs(tempBin[i] - (BinArray[i] / sum) * total);
|
|
}
|
|
}
|
|
result.push(tempBin);
|
|
}
|
|
if (type === 3) {
|
|
return {
|
|
data: result,
|
|
correction: testData
|
|
};
|
|
} else {
|
|
return result;
|
|
}
|
|
}
|
|
|
|
function CheckCode128(string) {
|
|
var checksum = string[string.length - 2].join("");
|
|
var i;
|
|
checksum = Code128Encoding.value.indexOf(checksum);
|
|
if (checksum === -1) return false;
|
|
var summarizer = Code128Encoding.value.indexOf(string[0].join(""));
|
|
if (summarizer === -1) return false;
|
|
var startChar = Code128Encoding[string[0].join("")];
|
|
if (typeof startChar === 'undefined') return false;
|
|
if (startChar !== "A" && startChar !== "B" && startChar !== "C") return false;
|
|
for (i = 1; i < (string.length - 2); i++) {
|
|
summarizer += Code128Encoding.value.indexOf(string[i].join("")) * i;
|
|
if (Code128Encoding.value.indexOf(string[i].join("")) === -1) return false;
|
|
}
|
|
return (summarizer % 103 === checksum);
|
|
}
|
|
|
|
function Decode2Of5(string) {
|
|
var result = "";
|
|
var i;
|
|
for (i = 0; i < string.length; i++) {
|
|
if (TwoOfFiveEncoding.indexOf(string[i].join("")) === -1) return false;
|
|
result += TwoOfFiveEncoding.indexOf(string[i].join(""));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function DecodeCodaBar(string) {
|
|
var result = "";
|
|
var start = string[0].join("");
|
|
var end = string[string.length - 1].join("");
|
|
var i;
|
|
if (!(CodaBarEncoding[start] === "A" || CodaBarEncoding[start] === "B" || CodaBarEncoding[start] === "C" || CodaBarEncoding[start] === "D")) return false;
|
|
if (!(CodaBarEncoding[end] === "A" || CodaBarEncoding[end] === "B" || CodaBarEncoding[end] === "C" || CodaBarEncoding[end] === "D")) return false;
|
|
for (i = 1; i < string.length - 1; i++) {
|
|
if (typeof CodaBarEncoding[string[i].join("")] === 'undefined') return false;
|
|
result += CodaBarEncoding[string[i].join("")];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function checkResultForEAN(resultArray) {
|
|
var weight = 3;
|
|
var sum = 0;
|
|
for (i = resultArray.length - 2; i >= 0; i--) {
|
|
sum += resultArray[i] * weight;
|
|
weight = weight === 3 ? 1 : 3;
|
|
}
|
|
sum = (10 - sum % 10) % 10;
|
|
return sum;
|
|
}
|
|
|
|
function DecodeEAN13(string) {
|
|
if (!(string.length === 12 || string.length === 7)) return false;
|
|
var md = 0;
|
|
if (string.length === 7) {
|
|
if (string[string.length - 1].join("") != "23") return false;
|
|
string.splice(string.length - 1, 1);
|
|
md = 1;
|
|
};
|
|
var leftSide = string.slice(0, 6);
|
|
var trigger = false;
|
|
var rightSide = string.slice(6, string.length);
|
|
var i;
|
|
for (i = 0; i < leftSide.length; i++) {
|
|
leftSide[i] = leftSide[i].join("");
|
|
if (leftSide[i].length !== 4) {
|
|
trigger = true;
|
|
break;
|
|
}
|
|
}
|
|
if (trigger) return false;
|
|
for (i = 0; i < rightSide.length; i++) {
|
|
rightSide[i] = rightSide[i].join("");
|
|
if (rightSide[i].length !== 4) {
|
|
trigger = true;
|
|
break;
|
|
}
|
|
}
|
|
if (trigger) return false;
|
|
var decodeFormat = [];
|
|
for (i = 0; i < leftSide.length; i++) {
|
|
if (typeof EAN13Encoding.L[leftSide[i]] !== 'undefined') {
|
|
decodeFormat.push("L");
|
|
} else if (typeof EAN13Encoding.G[leftSide[i]] !== 'undefined') {
|
|
decodeFormat.push("G");
|
|
} else {
|
|
trigger = true;
|
|
break;
|
|
}
|
|
}
|
|
if (trigger) return false;
|
|
var resultArray = [];
|
|
if (typeof EAN13Encoding.formats[decodeFormat.join("")] === 'undefined') return false;
|
|
resultArray.push(EAN13Encoding.formats[decodeFormat.join("")]);
|
|
for (i = 0; i < leftSide.length; i++) {
|
|
if (typeof EAN13Encoding[decodeFormat[i]][leftSide[i]] === 'undefined') {
|
|
trigger = true;
|
|
break;
|
|
}
|
|
resultArray.push(EAN13Encoding[decodeFormat[i]][leftSide[i]]);
|
|
}
|
|
if (trigger) return false;
|
|
for (i = 0; i < rightSide.length; i++) {
|
|
if (typeof EAN13Encoding["R"][rightSide[i]] !== 'undefined') {
|
|
resultArray.push(EAN13Encoding["R"][rightSide[i]]);
|
|
} else if (typeof EAN13Encoding["G"][rightSide[i]] !== 'undefined') {
|
|
resultArray.push(EAN13Encoding["G"][rightSide[i]]);
|
|
} else {
|
|
trigger = true;
|
|
break;
|
|
}
|
|
}
|
|
if (trigger) return false;
|
|
var sum = md ? resultArray[0] : checkResultForEAN(resultArray.join(""), 1);
|
|
if (resultArray[resultArray.length - 1] === sum || resultArray[0] === sum) {
|
|
return resultArray.join("");
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function CheckCode93(string) {
|
|
var checkOne = string[string.length - 3].join("");
|
|
var checkTwo = string[string.length - 2].join("");
|
|
var failSafe = true;
|
|
if (typeof Code93Encoding[checkOne] === 'undefined') return false;
|
|
if (typeof Code93Encoding[checkTwo] === 'undefined') return false;
|
|
var checkSum = Code93Encoding[checkOne].value;
|
|
var weight = 1;
|
|
var sum = 0;
|
|
var i;
|
|
for (i = string.length - 4; i > 0; i--) {
|
|
failSafe = typeof Code93Encoding[string[i].join("")] === 'undefined' ? false : failSafe;
|
|
if (!failSafe) break;
|
|
sum += Code93Encoding[string[i].join("")].value * weight;
|
|
weight++;
|
|
if (weight > 20) weight = 1;
|
|
}
|
|
var firstCheck = sum % 47;
|
|
var firstBool = firstCheck === checkSum;
|
|
if (!firstBool) return false;
|
|
if (!failSafe) return false;
|
|
sum = firstCheck;
|
|
weight = 2;
|
|
checkSum = Code93Encoding[checkTwo].value;
|
|
for (i = string.length - 4; i > 0; i--) {
|
|
failSafe = typeof Code93Encoding[string[i].join("")] === 'undefined' ? false : failSafe;
|
|
if (!failSafe) break;
|
|
sum += Code93Encoding[string[i].join("")].value * weight;
|
|
weight++;
|
|
if (weight > 15) weight = 1;
|
|
}
|
|
var secondCheck = sum % 47;
|
|
var secondBool = secondCheck === checkSum;
|
|
return secondBool && firstBool;
|
|
}
|
|
|
|
function CheckCode39(string) {
|
|
var trigger = true;
|
|
if (typeof Code39Encoding[string[0].join("")] === 'undefined') return false;
|
|
if (Code39Encoding[string[0].join("")].character !== "*") return false;
|
|
if (typeof Code39Encoding[string[string.length - 1].join("")] === 'undefined') return false;
|
|
if (Code39Encoding[string[string.length - 1].join("")].character !== "*") return false;
|
|
for (i = 1; i < string.length - 1; i++) {
|
|
if (typeof Code39Encoding[string[i].join("")] === 'undefined') {
|
|
trigger = false;
|
|
break;
|
|
}
|
|
}
|
|
return trigger;
|
|
}
|
|
|
|
function DecodeCode39(string) {
|
|
var resultString = "";
|
|
var special = false;
|
|
var character = "";
|
|
var specialchar = "";
|
|
for (i = 1; i < string.length - 1; i++) {
|
|
character = Code39Encoding[string[i].join("")].character;
|
|
if (character === "$" || character === "/" || character === "+" || character === "%") {
|
|
// if next character exists => this a special character
|
|
if (i + 1 < string.length - 1) {
|
|
special = true;
|
|
specialchar = character;
|
|
continue;
|
|
}
|
|
}
|
|
if (special) {
|
|
if (typeof ExtendedEncoding[specialchar + character] === 'undefined') {} else {
|
|
resultString += ExtendedEncoding[specialchar + character];
|
|
}
|
|
special = false;
|
|
continue;
|
|
}
|
|
resultString += character;
|
|
}
|
|
return resultString;
|
|
}
|
|
|
|
function DecodeCode93(string) {
|
|
var resultString = "";
|
|
var special = false;
|
|
var character = "";
|
|
var specialchar = "";
|
|
for (i = 1; i < string.length - 3; i++) {
|
|
character = Code93Encoding[string[i].join("")].character;
|
|
if (character === "($)" || character === "(/)" || character === "(+)" || character === "(%)") {
|
|
special = true;
|
|
specialchar = character[1];
|
|
continue;
|
|
}
|
|
if (special) {
|
|
if (typeof ExtendedEncoding[specialchar + character] === 'undefined') {} else {
|
|
resultString += ExtendedEncoding[specialchar + character];
|
|
}
|
|
special = false;
|
|
continue;
|
|
}
|
|
resultString += character;
|
|
}
|
|
return resultString;
|
|
}
|
|
|
|
function DecodeCode128(string) {
|
|
var set = Code128Encoding[string[0].join("")];
|
|
var symbol;
|
|
var Code128Format = "Code128";
|
|
var resultString = "";
|
|
var i;
|
|
for (i = 1; i < (string.length - 2); i++) {
|
|
symbol = Code128Encoding[string[i].join("")][set];
|
|
switch (symbol) {
|
|
case "FNC1":
|
|
if (i === 1) Code128Format = "GS1-128";
|
|
break;
|
|
case "FNC2":
|
|
case "FNC3":
|
|
case "FNC4":
|
|
break;
|
|
case "SHIFT_B":
|
|
i++;
|
|
resultString += Code128Encoding[string[i].join("")].B;
|
|
break;
|
|
case "SHIFT_A":
|
|
i++;
|
|
resultString += Code128Encoding[string[i].join("")].A;
|
|
break;
|
|
case "Code_A":
|
|
set = "A";
|
|
break;
|
|
case "Code_B":
|
|
set = "B";
|
|
break;
|
|
case "Code_C":
|
|
set = "C";
|
|
break;
|
|
default:
|
|
resultString += symbol;
|
|
}
|
|
}
|
|
return {
|
|
string: resultString,
|
|
format: Code128Format
|
|
};
|
|
}
|
|
|
|
function checkFinalResult(result) {
|
|
for (i = 0; i < result.length; i++) {
|
|
if (result[i].Format === 'EAN-13') {
|
|
if (result[i].Value.length === 7) {
|
|
result[i].Value = result[i].Value.substring(1, 7);
|
|
result[i].Format = 'UPC-E';
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
TwoOfFiveEncoding = ["00110", "10001", "01001", "11000", "00101", "10100", "01100", "00011", "10010", "01010"];
|
|
Code128Encoding = {
|
|
"212222": {
|
|
A: " ",
|
|
B: " ",
|
|
C: "00"
|
|
},
|
|
"222122": {
|
|
A: "!",
|
|
B: "!",
|
|
C: "01"
|
|
},
|
|
"222221": {
|
|
A: '"',
|
|
B: '"',
|
|
C: "02"
|
|
},
|
|
"121223": {
|
|
A: "#",
|
|
B: "#",
|
|
C: "03"
|
|
},
|
|
"121322": {
|
|
A: "$",
|
|
B: "$",
|
|
C: "04"
|
|
},
|
|
"131222": {
|
|
A: "%",
|
|
B: "%",
|
|
C: "05"
|
|
},
|
|
"122213": {
|
|
A: "&",
|
|
B: "&",
|
|
C: "06"
|
|
},
|
|
"122312": {
|
|
A: "'",
|
|
B: "'",
|
|
C: "07"
|
|
},
|
|
"132212": {
|
|
A: "(",
|
|
B: "(",
|
|
C: "08"
|
|
},
|
|
"221213": {
|
|
A: ")",
|
|
B: ")",
|
|
C: "09"
|
|
},
|
|
"221312": {
|
|
A: "*",
|
|
B: "*",
|
|
C: "10"
|
|
},
|
|
"231212": {
|
|
A: "+",
|
|
B: "+",
|
|
C: "11"
|
|
},
|
|
"112232": {
|
|
A: ",",
|
|
B: ",",
|
|
C: "12"
|
|
},
|
|
"122132": {
|
|
A: "-",
|
|
B: "-",
|
|
C: "13"
|
|
},
|
|
"122231": {
|
|
A: ".",
|
|
B: ".",
|
|
C: "14"
|
|
},
|
|
"113222": {
|
|
A: "/",
|
|
B: "/",
|
|
C: "15"
|
|
},
|
|
"123122": {
|
|
A: "0",
|
|
B: "0",
|
|
C: "16"
|
|
},
|
|
"123221": {
|
|
A: "1",
|
|
B: "1",
|
|
C: "17"
|
|
},
|
|
"223211": {
|
|
A: "2",
|
|
B: "2",
|
|
C: "18"
|
|
},
|
|
"221132": {
|
|
A: "3",
|
|
B: "3",
|
|
C: "19"
|
|
},
|
|
"221231": {
|
|
A: "4",
|
|
B: "4",
|
|
C: "20"
|
|
},
|
|
"213212": {
|
|
A: "5",
|
|
B: "5",
|
|
C: "21"
|
|
},
|
|
"223112": {
|
|
A: "6",
|
|
B: "6",
|
|
C: "22"
|
|
},
|
|
"312131": {
|
|
A: "7",
|
|
B: "7",
|
|
C: "23"
|
|
},
|
|
"311222": {
|
|
A: "8",
|
|
B: "8",
|
|
C: "24"
|
|
},
|
|
"321122": {
|
|
A: "9",
|
|
B: "9",
|
|
C: "25"
|
|
},
|
|
"321221": {
|
|
A: ":",
|
|
B: ":",
|
|
C: "26"
|
|
},
|
|
"312212": {
|
|
A: ";",
|
|
B: ";",
|
|
C: "27"
|
|
},
|
|
"322112": {
|
|
A: "<",
|
|
B: "<",
|
|
C: "28"
|
|
},
|
|
"322211": {
|
|
A: "=",
|
|
B: "=",
|
|
C: "29"
|
|
},
|
|
"212123": {
|
|
A: ">",
|
|
B: ">",
|
|
C: "30"
|
|
},
|
|
"212321": {
|
|
A: "?",
|
|
B: "?",
|
|
C: "31"
|
|
},
|
|
"232121": {
|
|
A: "@",
|
|
B: "@",
|
|
C: "32"
|
|
},
|
|
"111323": {
|
|
A: "A",
|
|
B: "A",
|
|
C: "33"
|
|
},
|
|
"131123": {
|
|
A: "B",
|
|
B: "B",
|
|
C: "34"
|
|
},
|
|
"131321": {
|
|
A: "C",
|
|
B: "C",
|
|
C: "35"
|
|
},
|
|
"112313": {
|
|
A: "D",
|
|
B: "D",
|
|
C: "36"
|
|
},
|
|
"132113": {
|
|
A: "E",
|
|
B: "E",
|
|
C: "37"
|
|
},
|
|
"132311": {
|
|
A: "F",
|
|
B: "F",
|
|
C: "38"
|
|
},
|
|
"211313": {
|
|
A: "G",
|
|
B: "G",
|
|
C: "39"
|
|
},
|
|
"231113": {
|
|
A: "H",
|
|
B: "H",
|
|
C: "40"
|
|
},
|
|
"231311": {
|
|
A: "I",
|
|
B: "I",
|
|
C: "41"
|
|
},
|
|
"112133": {
|
|
A: "J",
|
|
B: "J",
|
|
C: "42"
|
|
},
|
|
"112331": {
|
|
A: "K",
|
|
B: "K",
|
|
C: "43"
|
|
},
|
|
"132131": {
|
|
A: "L",
|
|
B: "L",
|
|
C: "44"
|
|
},
|
|
"113123": {
|
|
A: "M",
|
|
B: "M",
|
|
C: "45"
|
|
},
|
|
"113321": {
|
|
A: "N",
|
|
B: "N",
|
|
C: "46"
|
|
},
|
|
"133121": {
|
|
A: "O",
|
|
B: "O",
|
|
C: "47"
|
|
},
|
|
"313121": {
|
|
A: "P",
|
|
B: "P",
|
|
C: "48"
|
|
},
|
|
"211331": {
|
|
A: "Q",
|
|
B: "Q",
|
|
C: "49"
|
|
},
|
|
"231131": {
|
|
A: "R",
|
|
B: "R",
|
|
C: "50"
|
|
},
|
|
"213113": {
|
|
A: "S",
|
|
B: "S",
|
|
C: "51"
|
|
},
|
|
"213311": {
|
|
A: "T",
|
|
B: "T",
|
|
C: "52"
|
|
},
|
|
"213131": {
|
|
A: "U",
|
|
B: "U",
|
|
C: "53"
|
|
},
|
|
"311123": {
|
|
A: "V",
|
|
B: "V",
|
|
C: "54"
|
|
},
|
|
"311321": {
|
|
A: "W",
|
|
B: "W",
|
|
C: "55"
|
|
},
|
|
"331121": {
|
|
A: "X",
|
|
B: "X",
|
|
C: "56"
|
|
},
|
|
"312113": {
|
|
A: "Y",
|
|
B: "Y",
|
|
C: "57"
|
|
},
|
|
"312311": {
|
|
A: "Z",
|
|
B: "Z",
|
|
C: "58"
|
|
},
|
|
"332111": {
|
|
A: "[",
|
|
B: "[",
|
|
C: "59"
|
|
},
|
|
"314111": {
|
|
A: "\\",
|
|
B: "\\",
|
|
C: "60"
|
|
},
|
|
"221411": {
|
|
A: "]",
|
|
B: "]",
|
|
C: "61"
|
|
},
|
|
"431111": {
|
|
A: "^",
|
|
B: "^",
|
|
C: "62"
|
|
},
|
|
"111224": {
|
|
A: "_",
|
|
B: "_",
|
|
C: "63"
|
|
},
|
|
"111422": {
|
|
A: "NUL",
|
|
B: "`",
|
|
C: "64"
|
|
},
|
|
"121124": {
|
|
A: "SOH",
|
|
B: "a",
|
|
C: "65"
|
|
},
|
|
"121421": {
|
|
A: "STX",
|
|
B: "b",
|
|
C: "66"
|
|
},
|
|
"141122": {
|
|
A: "ETX",
|
|
B: "c",
|
|
C: "67"
|
|
},
|
|
"141221": {
|
|
A: "EOT",
|
|
B: "d",
|
|
C: "68"
|
|
},
|
|
"112214": {
|
|
A: "ENQ",
|
|
B: "e",
|
|
C: "69"
|
|
},
|
|
"112412": {
|
|
A: "ACK",
|
|
B: "f",
|
|
C: "70"
|
|
},
|
|
"122114": {
|
|
A: "BEL",
|
|
B: "g",
|
|
C: "71"
|
|
},
|
|
"122411": {
|
|
A: "BS",
|
|
B: "h",
|
|
C: "72"
|
|
},
|
|
"142112": {
|
|
A: "HT",
|
|
B: "i",
|
|
C: "73"
|
|
},
|
|
"142211": {
|
|
A: "LF",
|
|
B: "j",
|
|
C: "74"
|
|
},
|
|
"241211": {
|
|
A: "VT",
|
|
B: "k",
|
|
C: "75"
|
|
},
|
|
"221114": {
|
|
A: "FF",
|
|
B: "l",
|
|
C: "76"
|
|
},
|
|
"413111": {
|
|
A: "CR",
|
|
B: "m",
|
|
C: "77"
|
|
},
|
|
"241112": {
|
|
A: "SO",
|
|
B: "n",
|
|
C: "78"
|
|
},
|
|
"134111": {
|
|
A: "SI",
|
|
B: "o",
|
|
C: "79"
|
|
},
|
|
"111242": {
|
|
A: "DLE",
|
|
B: "p",
|
|
C: "80"
|
|
},
|
|
"121142": {
|
|
A: "DC1",
|
|
B: "q",
|
|
C: "81"
|
|
},
|
|
"121241": {
|
|
A: "DC2",
|
|
B: "r",
|
|
C: "82"
|
|
},
|
|
"114212": {
|
|
A: "DC3",
|
|
B: "s",
|
|
C: "83"
|
|
},
|
|
"124112": {
|
|
A: "DC4",
|
|
B: "t",
|
|
C: "84"
|
|
},
|
|
"124211": {
|
|
A: "NAK",
|
|
B: "u",
|
|
C: "85"
|
|
},
|
|
"411212": {
|
|
A: "SYN",
|
|
B: "v",
|
|
C: "86"
|
|
},
|
|
"421112": {
|
|
A: "ETB",
|
|
B: "w",
|
|
C: "87"
|
|
},
|
|
"421211": {
|
|
A: "CAN",
|
|
B: "x",
|
|
C: "88"
|
|
},
|
|
"212141": {
|
|
A: "EM",
|
|
B: "y",
|
|
C: "89"
|
|
},
|
|
"214121": {
|
|
A: "SUB",
|
|
B: "z",
|
|
C: "90"
|
|
},
|
|
"412121": {
|
|
A: "ESC",
|
|
B: "{",
|
|
C: "91"
|
|
},
|
|
"111143": {
|
|
A: "FS",
|
|
B: "|",
|
|
C: "92"
|
|
},
|
|
"111341": {
|
|
A: "GS",
|
|
B: "}",
|
|
C: "93"
|
|
},
|
|
"131141": {
|
|
A: "RS",
|
|
B: "~",
|
|
C: "94"
|
|
},
|
|
"114113": {
|
|
A: "US",
|
|
B: "DEL",
|
|
C: "95"
|
|
},
|
|
"114311": {
|
|
A: "FNC3",
|
|
B: "FNC3",
|
|
C: "96"
|
|
},
|
|
"411113": {
|
|
A: "FNC2",
|
|
B: "FNC2",
|
|
C: "97"
|
|
},
|
|
"411311": {
|
|
A: "SHIFT_B",
|
|
B: "SHIFT_A",
|
|
C: "98"
|
|
},
|
|
"113141": {
|
|
A: "Code_C",
|
|
B: "Code_C",
|
|
C: "99"
|
|
},
|
|
"114131": {
|
|
A: "Code_B",
|
|
B: "FNC4",
|
|
C: "Code_B"
|
|
},
|
|
"311141": {
|
|
A: "FNC4",
|
|
B: "Code_A",
|
|
C: "Code_A"
|
|
},
|
|
"411131": {
|
|
A: "FNC1",
|
|
B: "FNC1",
|
|
C: "FNC1"
|
|
},
|
|
"211412": "A",
|
|
"211214": "B",
|
|
"211232": "C",
|
|
"233111": {
|
|
A: "STOP",
|
|
B: "STOP",
|
|
C: "STOP"
|
|
},
|
|
value: ["212222", "222122", "222221", "121223", "121322", "131222", "122213", "122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231", "113222", "123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222", "321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121", "111323", "131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133", "112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131", "213113", "213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111", "221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214", "112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112", "134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112", "421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311", "411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214", "211232", "233111"]
|
|
};
|
|
Code93Encoding = {
|
|
"131112": {
|
|
value: 0,
|
|
character: "0"
|
|
},
|
|
"111213": {
|
|
value: 1,
|
|
character: "1"
|
|
},
|
|
"111312": {
|
|
value: 2,
|
|
character: "2"
|
|
},
|
|
"111411": {
|
|
value: 3,
|
|
character: "3"
|
|
},
|
|
"121113": {
|
|
value: 4,
|
|
character: "4"
|
|
},
|
|
"121212": {
|
|
value: 5,
|
|
character: "5"
|
|
},
|
|
"121311": {
|
|
value: 6,
|
|
character: "6"
|
|
},
|
|
"111114": {
|
|
value: 7,
|
|
character: "7"
|
|
},
|
|
"131211": {
|
|
value: 8,
|
|
character: "8"
|
|
},
|
|
"141111": {
|
|
value: 9,
|
|
character: "9"
|
|
},
|
|
"211113": {
|
|
value: 10,
|
|
character: "A"
|
|
},
|
|
"211212": {
|
|
value: 11,
|
|
character: "B"
|
|
},
|
|
"211311": {
|
|
value: 12,
|
|
character: "C"
|
|
},
|
|
"221112": {
|
|
value: 13,
|
|
character: "D"
|
|
},
|
|
"221211": {
|
|
value: 14,
|
|
character: "E"
|
|
},
|
|
"231111": {
|
|
value: 15,
|
|
character: "F"
|
|
},
|
|
"112113": {
|
|
value: 16,
|
|
character: "G"
|
|
},
|
|
"112212": {
|
|
value: 17,
|
|
character: "H"
|
|
},
|
|
"112311": {
|
|
value: 18,
|
|
character: "I"
|
|
},
|
|
"122112": {
|
|
value: 19,
|
|
character: "J"
|
|
},
|
|
"132111": {
|
|
value: 20,
|
|
character: "K"
|
|
},
|
|
"111123": {
|
|
value: 21,
|
|
character: "L"
|
|
},
|
|
"111222": {
|
|
value: 22,
|
|
character: "M"
|
|
},
|
|
"111321": {
|
|
value: 23,
|
|
character: "N"
|
|
},
|
|
"121122": {
|
|
value: 24,
|
|
character: "O"
|
|
},
|
|
"131121": {
|
|
value: 25,
|
|
character: "P"
|
|
},
|
|
"212112": {
|
|
value: 26,
|
|
character: "Q"
|
|
},
|
|
"212211": {
|
|
value: 27,
|
|
character: "R"
|
|
},
|
|
"211122": {
|
|
value: 28,
|
|
character: "S"
|
|
},
|
|
"211221": {
|
|
value: 29,
|
|
character: "T"
|
|
},
|
|
"221121": {
|
|
value: 30,
|
|
character: "U"
|
|
},
|
|
"222111": {
|
|
value: 31,
|
|
character: "V"
|
|
},
|
|
"112122": {
|
|
value: 32,
|
|
character: "W"
|
|
},
|
|
"112221": {
|
|
value: 33,
|
|
character: "X"
|
|
},
|
|
"122121": {
|
|
value: 34,
|
|
character: "Y"
|
|
},
|
|
"123111": {
|
|
value: 35,
|
|
character: "Z"
|
|
},
|
|
"121131": {
|
|
value: 36,
|
|
character: "-"
|
|
},
|
|
"311112": {
|
|
value: 37,
|
|
character: "."
|
|
},
|
|
"311211": {
|
|
value: 38,
|
|
character: " "
|
|
},
|
|
"321111": {
|
|
value: 39,
|
|
character: "$"
|
|
},
|
|
"112131": {
|
|
value: 40,
|
|
character: "/"
|
|
},
|
|
"113121": {
|
|
value: 41,
|
|
character: "+"
|
|
},
|
|
"211131": {
|
|
value: 42,
|
|
character: "%"
|
|
},
|
|
"121221": {
|
|
value: 43,
|
|
character: "($)"
|
|
},
|
|
"312111": {
|
|
value: 44,
|
|
character: "(%)"
|
|
},
|
|
"311121": {
|
|
value: 45,
|
|
character: "(/)"
|
|
},
|
|
"122211": {
|
|
value: 46,
|
|
character: "(+)"
|
|
},
|
|
"111141": {
|
|
value: -1,
|
|
character: "*"
|
|
}
|
|
};
|
|
Code39Encoding = {
|
|
"111221211": {
|
|
value: 0,
|
|
character: "0"
|
|
},
|
|
"211211112": {
|
|
value: 1,
|
|
character: "1"
|
|
},
|
|
"112211112": {
|
|
value: 2,
|
|
character: "2"
|
|
},
|
|
"212211111": {
|
|
value: 3,
|
|
character: "3"
|
|
},
|
|
"111221112": {
|
|
value: 4,
|
|
character: "4"
|
|
},
|
|
"211221111": {
|
|
value: 5,
|
|
character: "5"
|
|
},
|
|
"112221111": {
|
|
value: 6,
|
|
character: "6"
|
|
},
|
|
"111211212": {
|
|
value: 7,
|
|
character: "7"
|
|
},
|
|
"211211211": {
|
|
value: 8,
|
|
character: "8"
|
|
},
|
|
"112211211": {
|
|
value: 9,
|
|
character: "9"
|
|
},
|
|
"211112112": {
|
|
value: 10,
|
|
character: "A"
|
|
},
|
|
"112112112": {
|
|
value: 11,
|
|
character: "B"
|
|
},
|
|
"212112111": {
|
|
value: 12,
|
|
character: "C"
|
|
},
|
|
"111122112": {
|
|
value: 13,
|
|
character: "D"
|
|
},
|
|
"211122111": {
|
|
value: 14,
|
|
character: "E"
|
|
},
|
|
"112122111": {
|
|
value: 15,
|
|
character: "F"
|
|
},
|
|
"111112212": {
|
|
value: 16,
|
|
character: "G"
|
|
},
|
|
"211112211": {
|
|
value: 17,
|
|
character: "H"
|
|
},
|
|
"112112211": {
|
|
value: 18,
|
|
character: "I"
|
|
},
|
|
"111122211": {
|
|
value: 19,
|
|
character: "J"
|
|
},
|
|
"211111122": {
|
|
value: 20,
|
|
character: "K"
|
|
},
|
|
"112111122": {
|
|
value: 21,
|
|
character: "L"
|
|
},
|
|
"212111121": {
|
|
value: 22,
|
|
character: "M"
|
|
},
|
|
"111121122": {
|
|
value: 23,
|
|
character: "N"
|
|
},
|
|
"211121121": {
|
|
value: 24,
|
|
character: "O"
|
|
},
|
|
"112121121": {
|
|
value: 25,
|
|
character: "P"
|
|
},
|
|
"111111222": {
|
|
value: 26,
|
|
character: "Q"
|
|
},
|
|
"211111221": {
|
|
value: 27,
|
|
character: "R"
|
|
},
|
|
"112111221": {
|
|
value: 28,
|
|
character: "S"
|
|
},
|
|
"111121221": {
|
|
value: 29,
|
|
character: "T"
|
|
},
|
|
"221111112": {
|
|
value: 30,
|
|
character: "U"
|
|
},
|
|
"122111112": {
|
|
value: 31,
|
|
character: "V"
|
|
},
|
|
"222111111": {
|
|
value: 32,
|
|
character: "W"
|
|
},
|
|
"121121112": {
|
|
value: 33,
|
|
character: "X"
|
|
},
|
|
"221121111": {
|
|
value: 34,
|
|
character: "Y"
|
|
},
|
|
"122121111": {
|
|
value: 35,
|
|
character: "Z"
|
|
},
|
|
"121111212": {
|
|
value: 36,
|
|
character: "-"
|
|
},
|
|
"221111211": {
|
|
value: 37,
|
|
character: "."
|
|
},
|
|
"122111211": {
|
|
value: 38,
|
|
character: " "
|
|
},
|
|
"121212111": {
|
|
value: 39,
|
|
character: "$"
|
|
},
|
|
"121211121": {
|
|
value: 40,
|
|
character: "/"
|
|
},
|
|
"121112121": {
|
|
value: 41,
|
|
character: "+"
|
|
},
|
|
"111212121": {
|
|
value: 42,
|
|
character: "%"
|
|
},
|
|
"121121211": {
|
|
value: -1,
|
|
character: "*"
|
|
}
|
|
};
|
|
ExtendedEncoding = {
|
|
"/A": '!',
|
|
"/B": '"',
|
|
"/C": '#',
|
|
"/D": '$',
|
|
"/E": '%',
|
|
"/F": '&',
|
|
"/G": "'",
|
|
"/H": '(',
|
|
"/I": ')',
|
|
"/J": '*',
|
|
"/K": '+',
|
|
"/L": ',',
|
|
"/O": '/',
|
|
"/Z": ':',
|
|
"%F": ';',
|
|
"%G": '<',
|
|
"%H": '=',
|
|
"%I": '>',
|
|
"%J": '?',
|
|
"%K": '[',
|
|
"%L": "\\",
|
|
"%M": ']',
|
|
"%N": '^',
|
|
"%O": '_',
|
|
"+A": 'a',
|
|
"+B": 'b',
|
|
"+C": 'c',
|
|
"+D": 'd',
|
|
"+E": 'e',
|
|
"+F": 'f',
|
|
"+G": 'g',
|
|
"+H": 'h',
|
|
"+I": 'i',
|
|
"+J": 'j',
|
|
"+K": 'k',
|
|
"+L": 'l',
|
|
"+M": 'm',
|
|
"+N": 'n',
|
|
"+O": 'o',
|
|
"+P": 'p',
|
|
"+Q": 'q',
|
|
"+R": 'r',
|
|
"+S": 's',
|
|
"+T": 't',
|
|
"+U": 'u',
|
|
"+V": 'v',
|
|
"+W": 'w',
|
|
"+X": 'x',
|
|
"+Y": 'y',
|
|
"+Z": 'z',
|
|
"%P": "{",
|
|
"%Q": '|',
|
|
"%R": '|',
|
|
"%S": '~',
|
|
};
|
|
CodaBarEncoding = {
|
|
"0000011": "0",
|
|
"0000110": "1",
|
|
"0001001": "2",
|
|
"1100000": "3",
|
|
"0010010": "4",
|
|
"1000010": "5",
|
|
"0100001": "6",
|
|
"0100100": "7",
|
|
"0110000": "8",
|
|
"1001000": "9",
|
|
"0001100": "-",
|
|
"0011000": "$",
|
|
"1000101": ":",
|
|
"1010001": "/",
|
|
"1010100": ".",
|
|
"0011111": "+",
|
|
"0011010": "A",
|
|
"0001011": "B",
|
|
"0101001": "C",
|
|
"0001110": "D"
|
|
};
|
|
EAN13Encoding = {
|
|
"L": {
|
|
"3211": 0,
|
|
"2221": 1,
|
|
"2122": 2,
|
|
"1411": 3,
|
|
"1132": 4,
|
|
"1231": 5,
|
|
"1114": 6,
|
|
"1312": 7,
|
|
"1213": 8,
|
|
"3112": 9
|
|
},
|
|
"G": {
|
|
"1123": 0,
|
|
"1222": 1,
|
|
"2212": 2,
|
|
"1141": 3,
|
|
"2311": 4,
|
|
"1321": 5,
|
|
"4111": 6,
|
|
"2131": 7,
|
|
"3121": 8,
|
|
"2113": 9
|
|
},
|
|
"R": {
|
|
"3211": 0,
|
|
"2221": 1,
|
|
"2122": 2,
|
|
"1411": 3,
|
|
"1132": 4,
|
|
"1231": 5,
|
|
"1114": 6,
|
|
"1312": 7,
|
|
"1213": 8,
|
|
"3112": 9
|
|
},
|
|
formats: {
|
|
'GGGGGG': 0,
|
|
'GGLGLL': 1,
|
|
'GGLLGL': 2,
|
|
'GGLLLG': 3,
|
|
'GLGGLL': 4,
|
|
'GLLGGL': 5,
|
|
'GLLLGG': 6,
|
|
'GLGLGL': 7,
|
|
'GLGLLG': 8,
|
|
'GLLGLG': 9,
|
|
'LLLLLL': 0,
|
|
'LLGLGG': 1,
|
|
'LLGGLG': 2,
|
|
'LLGGGL': 3,
|
|
'LGLLGG': 4,
|
|
'LGGLLG': 5,
|
|
'LGGGLL': 6,
|
|
'LGLGLG': 7,
|
|
'LGLGGL': 8,
|
|
'LGGLGL': 9
|
|
}
|
|
};
|
|
self.onmessage = function(e) {
|
|
var width;
|
|
var i;
|
|
ScanImage = {
|
|
data: new Uint8ClampedArray(e.data.scan),
|
|
width: e.data.scanWidth,
|
|
height: e.data.scanHeight
|
|
};
|
|
switch (e.data.rotation) {
|
|
case 8:
|
|
ScanImage.data = Rotate(ScanImage.data, ScanImage.width, ScanImage.height, -90);
|
|
width = e.data.scanWidth;
|
|
ScanImage.width = ScanImage.height;
|
|
ScanImage.height = width;
|
|
break;
|
|
case 6:
|
|
ScanImage.data = Rotate(ScanImage.data, ScanImage.width, ScanImage.height, 90);
|
|
width = e.data.scanWidth;
|
|
ScanImage.width = ScanImage.height;
|
|
ScanImage.height = width;
|
|
break;
|
|
case 3:
|
|
ScanImage.data = Rotate(ScanImage.data, ScanImage.width, ScanImage.height, 180);
|
|
}
|
|
Image = {
|
|
data: Scale(ScanImage.data, ScanImage.width, ScanImage.height),
|
|
width: ScanImage.width / 2,
|
|
height: ScanImage.height / 2
|
|
};
|
|
if (e.data.postOrientation) {
|
|
postMessage({
|
|
result: Image,
|
|
success: "orientationData"
|
|
});
|
|
}
|
|
availableFormats = ["Code128", "Code93", "Code39", "EAN-13", "2Of5", "Inter2Of5", "Codabar"];
|
|
FormatPriority = [];
|
|
var decodeFormats = ["Code128", "Code93", "Code39", "EAN-13", "2Of5", "Inter2Of5", "Codabar"];
|
|
SecureCodabar = true;
|
|
Secure2Of5 = true;
|
|
Multiple = true;
|
|
if (typeof e.data.multiple !== 'undefined') {
|
|
Multiple = e.data.multiple;
|
|
}
|
|
if (typeof e.data.decodeFormats !== 'undefined') {
|
|
decodeFormats = e.data.decodeFormats;
|
|
}
|
|
for (i = 0; i < decodeFormats.length; i++) {
|
|
FormatPriority.push(decodeFormats[i]);
|
|
}
|
|
CreateTable();
|
|
CreateScanTable();
|
|
var FinalResult = Main();
|
|
if (FinalResult.length > 0) {
|
|
postMessage({
|
|
result: checkFinalResult(FinalResult),
|
|
success: true
|
|
});
|
|
} else {
|
|
postMessage({
|
|
result: FinalResult,
|
|
success: false
|
|
});
|
|
}
|
|
}; |