New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

qrcode-pure

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

qrcode-pure - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

lib/encode.js

1738

lib/decode.js

@@ -9,1081 +9,1081 @@ /**

function QRDecode() {
this.image = null;
this.imageTop = 0;
this.imageBottom = 0;
this.imageLeft = 0;
this.imageRight = 0;
this.nModules = 0;
this.moduleSize = 0;
this.version = 0;
this.functionalGrade = 0;
this.ECLevel = 0;
this.mask = 0;
this.maskPattern = [];
this.nBlockEcWords = 0;
this.blockIndices = [];
this.blockDataLengths = [];
this.image = null;
this.imageTop = 0;
this.imageBottom = 0;
this.imageLeft = 0;
this.imageRight = 0;
this.nModules = 0;
this.moduleSize = 0;
this.version = 0;
this.functionalGrade = 0;
this.ECLevel = 0;
this.mask = 0;
this.maskPattern = [];
this.nBlockEcWords = 0;
this.blockIndices = [];
this.blockDataLengths = [];
}
QRDecode.prototype = {
/**
* Decode a pixel array
* @param pix
* @returns {*}
*/
decodePix: function(pix) {
return this.decodeImage(pix);
},
/**
* Decode image data as QR Code
* @param imageData The image data (canvas.getContext('2d').getImageData, pixel array or similar)
* @param imageWidth The pixel width of the image
* @param imageHeight The pixel height of the image
*/
decodeImageData: function(imageData, imageWidth, imageHeight) {
this.setImageData(imageData, imageWidth, imageHeight);
/**
* Decode a pixel array
* @param pix
* @returns {*}
*/
decodePix: function (pix) {
return this.decodeImage(pix);
},
/**
* Decode image data as QR Code
* @param imageData The image data (canvas.getContext('2d').getImageData, pixel array or similar)
* @param imageWidth The pixel width of the image
* @param imageHeight The pixel height of the image
*/
decodeImageData: function (imageData, imageWidth, imageHeight) {
this.setImageData(imageData, imageWidth, imageHeight);
return this.decode();
},
/**
* Decode image data as QR Code
* @param imageData The image data (canvas.getContext('2d').getImageData, pixel array or similar)
* @param imageWidth The pixel width of the image
* @param imageHeight The pixel height of the image
* @param left Leftmost pixel of image
* @param right Rightmost pixel of image
* @param top Top pixel of image
* @param bottom Bottom pixel of image
* @param maxVersion Do not try to decode with version higher than this
*/
decodeImageDataInsideBordersWithMaxVersion: function(imageData, imageWidth, imageHeight, left, right, top, bottom, maxVersion) {
this.setImageData(imageData, imageWidth, imageHeight);
this.imageLeft = left;
this.imageRight = right;
this.imageTop = top;
this.imageBottom = bottom;
this.imageSize = ((this.imageRight - this.imageLeft + 1) + (this.imageBottom - this.imageTop + 1)) / 2.0;
this.maxVersion = maxVersion;
return this.decode();
},
/**
* Decode image data as QR Code
* @param imageData The image data (canvas.getContext('2d').getImageData, pixel array or similar)
* @param imageWidth The pixel width of the image
* @param imageHeight The pixel height of the image
* @param left Leftmost pixel of image
* @param right Rightmost pixel of image
* @param top Top pixel of image
* @param bottom Bottom pixel of image
* @param maxVersion Do not try to decode with version higher than this
*/
decodeImageDataInsideBordersWithMaxVersion: function (imageData, imageWidth, imageHeight, left, right, top, bottom, maxVersion) {
this.setImageData(imageData, imageWidth, imageHeight);
this.imageLeft = left;
this.imageRight = right;
this.imageTop = top;
this.imageBottom = bottom;
this.imageSize = ((this.imageRight - this.imageLeft + 1) + (this.imageBottom - this.imageTop + 1)) / 2.0;
this.maxVersion = maxVersion;
return this.decodeInsideBordersWithMaxVersion();
},
/**
* Set image data in preparation for decoding QR Code
* @param imageData The image data (canvas.getContext('2d').getImageData, pixel array or similar)
* @param imageWidth The pixel width of the image
* @param imageHeight The pixel height of the image
*/
setImageData: function(imageData, imageWidth, imageHeight) {
var total = 0,
x, y, p, v;
return this.decodeInsideBordersWithMaxVersion();
},
/**
* Set image data in preparation for decoding QR Code
* @param imageData The image data (canvas.getContext('2d').getImageData, pixel array or similar)
* @param imageWidth The pixel width of the image
* @param imageHeight The pixel height of the image
*/
setImageData: function (imageData, imageWidth, imageHeight) {
var total = 0,
x, y, p, v;
imageData.minCol = 255;
imageData.maxCol = 0;
imageData.minCol = 255;
imageData.maxCol = 0;
for (x = 0; x < imageWidth; x++) {
for (y = 0; y < imageHeight; y++) {
p = x * 4 + y * imageWidth * 4;
v = 0.30 * imageData.data[p] + 0.59 * imageData.data[p + 1] + 0.11 * imageData.data[p + 2];
total += v;
for (x = 0; x < imageWidth; x++) {
for (y = 0; y < imageHeight; y++) {
p = x * 4 + y * imageWidth * 4;
v = 0.30 * imageData.data[p] + 0.59 * imageData.data[p + 1] + 0.11 * imageData.data[p + 2];
total += v;
if (v < imageData.minCol) {
imageData.minCol = v;
}
if (v > imageData.maxCol) {
imageData.maxCol = v;
}
}
if (v < imageData.minCol) {
imageData.minCol = v;
}
if (imageData.maxCol - imageData.minCol < 255 / 10) {
throw new QRBase.QRError(
'Image does not have enough contrast (this.image_data.min_col=' +
imageData.minCol + ' this.image_data.max_col=' + imageData.maxCol + ')',
2, { minCol: imageData.minCol, maxCol: imageData.maxCol });
if (v > imageData.maxCol) {
imageData.maxCol = v;
}
}
}
imageData.threshold = total / (imageWidth * imageHeight);
if (imageData.maxCol - imageData.minCol < 255 / 10) {
throw new QRBase.QRError(
'Image does not have enough contrast (this.image_data.min_col=' +
imageData.minCol + ' this.image_data.max_col=' + imageData.maxCol + ')',
2, { minCol: imageData.minCol, maxCol: imageData.maxCol });
}
imageData.getGray = function(x, y, d) {
var n = 0,
i, j, p;
imageData.threshold = total / (imageWidth * imageHeight);
for (i = x; i < x + d; i++) {
for (j = y; j < y + d; j++) {
p = i * 4 + j * this.width * 4;
n = n + 0.30 * this.data[p] + 0.59 * this.data[p + 1] + 0.11 * this.data[p + 2];
}
}
imageData.getGray = function (x, y, d) {
var n = 0,
i, j, p;
return n / d / d;
};
for (i = x; i < x + d; i++) {
for (j = y; j < y + d; j++) {
p = i * 4 + j * this.width * 4;
n = n + 0.30 * this.data[p] + 0.59 * this.data[p + 1] + 0.11 * this.data[p + 2];
}
}
imageData.isDark = function(x, y, d) {
var g = this.getGray(x, y, d);
return g < this.threshold;
};
return n / d / d;
};
this.image = imageData;
},
/**
* Decode a QR Code in an image.
* The image MUST already have .getGray set
*/
decodeImage: function(image) {
this.image = image;
imageData.isDark = function (x, y, d) {
var g = this.getGray(x, y, d);
return g < this.threshold;
};
return this.decode();
},
/**
* Decode a QR Code in an image which has already been set.
*/
decode: function() {
this.findImageBorders();
this.maxVersion = 40;
this.decodeInsideBordersWithMaxVersion();
this.image = imageData;
},
/**
* Decode a QR Code in an image.
* The image MUST already have .getGray set
*/
decodeImage: function (image) {
this.image = image;
return this.data;
},
/**
* Decode a QR Code in an image which has already been set -
* inside borders already defined
*/
decodeInsideBordersWithMaxVersion: function() {
this.findModuleSize();
QRBase.setFunctionalPattern(this);
this.extractCodewords();
QRBase.setBlocks(this);
this.correctErrors();
this.extractData();
return this.decode();
},
/**
* Decode a QR Code in an image which has already been set.
*/
decode: function () {
this.findImageBorders();
this.maxVersion = 40;
this.decodeInsideBordersWithMaxVersion();
return this.data;
},
/**
* QRCode internal decoding functions
*/
findImageBorders: function() {
var i, j, n,
limit = 7,
skewLimit = 2;
return this.data;
},
/**
* Decode a QR Code in an image which has already been set -
* inside borders already defined
*/
decodeInsideBordersWithMaxVersion: function () {
this.findModuleSize();
QRBase.setFunctionalPattern(this);
this.extractCodewords();
QRBase.setBlocks(this);
this.correctErrors();
this.extractData();
for (i = 0; i < this.image.width; i++) {
n = 0;
return this.data;
},
/**
* QRCode internal decoding functions
*/
findImageBorders: function () {
var i, j, n,
limit = 7,
skewLimit = 2;
for (j = 0; j < this.image.height; j++) {
n = n + this.image.isDark(i, j, 1);
}
for (i = 0; i < this.image.width; i++) {
n = 0;
if (n >= limit) {
break;
}
}
for (j = 0; j < this.image.height; j++) {
n = n + this.image.isDark(i, j, 1);
}
this.imageLeft = i;
if (n >= limit) {
break;
}
}
for (i = this.image.width - 1; i >= 0; i--) {
n = 0;
this.imageLeft = i;
for (j = 0; j < this.image.height; j++) {
n = n + this.image.isDark(i, j, 1);
}
for (i = this.image.width - 1; i >= 0; i--) {
n = 0;
if (n >= limit) {
break;
}
}
for (j = 0; j < this.image.height; j++) {
n = n + this.image.isDark(i, j, 1);
}
this.imageRight = i;
if (n >= limit) {
break;
}
}
for (j = 0; j < this.image.height; j++) {
n = 0;
this.imageRight = i;
for (i = 0; i < this.image.width; i++) {
n = n + this.image.isDark(i, j, 1);
}
for (j = 0; j < this.image.height; j++) {
n = 0;
if (n >= limit) {
break;
}
}
for (i = 0; i < this.image.width; i++) {
n = n + this.image.isDark(i, j, 1);
}
this.imageTop = j;
if (n >= limit) {
break;
}
}
for (j = this.image.height - 1; j >= 0; j--) {
n = 0;
this.imageTop = j;
for (i = 0; i < this.image.width; i++) {
n = n + this.image.isDark(i, j, 1);
}
for (j = this.image.height - 1; j >= 0; j--) {
n = 0;
if (n >= limit) {
break;
}
}
for (i = 0; i < this.image.width; i++) {
n = n + this.image.isDark(i, j, 1);
}
this.imageBottom = j;
if (n >= limit) {
break;
}
}
if ((this.imageRight - this.imageLeft + 1 < 21) || (this.imageBottom - this.imageTop + 1 < 21)) {
throw new QRBase.QRError('Found no image data to decode', 3);
}
this.imageBottom = j;
if (Math.abs((this.imageRight - this.imageLeft) - (this.imageBottom - this.imageTop)) > skewLimit) {
throw new QRBase.QRError('Image data is not rectangular', 4);
}
if ((this.imageRight - this.imageLeft + 1 < 21) || (this.imageBottom - this.imageTop + 1 < 21)) {
throw new QRBase.QRError('Found no image data to decode', 3);
}
this.imageSize = ((this.imageRight - this.imageLeft + 1) + (this.imageBottom - this.imageTop + 1)) / 2.0;
},
findModuleSize: function() {
/**
* returns number of matches found
* perferct is 8*8 = 64
*/
function matchFinderPattern(qr, x, y, quietX, quietY, moduleSize) {
var i, j,
n = 0;
if (Math.abs((this.imageRight - this.imageLeft) - (this.imageBottom - this.imageTop)) > skewLimit) {
throw new QRBase.QRError('Image data is not rectangular', 4);
}
// Outer 7x7 black boundary
for (i = 0; i <= 5; i++) {
if (qr.isDarkWithSize(x + i, y, moduleSize)) {
n = n + 1;
}
this.imageSize = ((this.imageRight - this.imageLeft + 1) + (this.imageBottom - this.imageTop + 1)) / 2.0;
},
findModuleSize: function () {
/**
* returns number of matches found
* perferct is 8*8 = 64
*/
function matchFinderPattern(qr, x, y, quietX, quietY, moduleSize) {
var i, j,
n = 0;
if (qr.isDarkWithSize(x + 6, y + i, moduleSize)) {
n = n + 1;
}
// Outer 7x7 black boundary
for (i = 0; i <= 5; i++) {
if (qr.isDarkWithSize(x + i, y, moduleSize)) {
n = n + 1;
}
if (qr.isDarkWithSize(x + 6 - i, y + 6, moduleSize)) {
n = n + 1;
}
if (qr.isDarkWithSize(x + 6, y + i, moduleSize)) {
n = n + 1;
}
if (qr.isDarkWithSize(x, y + 6 - i, moduleSize)) {
n = n + 1;
}
}
if (qr.isDarkWithSize(x + 6 - i, y + 6, moduleSize)) {
n = n + 1;
}
// Intermediate 5*5 white
for (i = 0; i <= 3; i++) {
if (!qr.isDarkWithSize(x + i + 1, y + 1, moduleSize)) {
n = n + 1;
}
if (qr.isDarkWithSize(x, y + 6 - i, moduleSize)) {
n = n + 1;
}
}
if (!qr.isDarkWithSize(x + 5, y + i + 1, moduleSize)) {
n = n + 1;
}
// Intermediate 5*5 white
for (i = 0; i <= 3; i++) {
if (!qr.isDarkWithSize(x + i + 1, y + 1, moduleSize)) {
n = n + 1;
}
if (!qr.isDarkWithSize(x + 5 - i, y + 5, moduleSize)) {
n = n + 1;
}
if (!qr.isDarkWithSize(x + 5, y + i + 1, moduleSize)) {
n = n + 1;
}
if (!qr.isDarkWithSize(x + 1, y + 5 - i, moduleSize)) {
n = n + 1;
}
}
if (!qr.isDarkWithSize(x + 5 - i, y + 5, moduleSize)) {
n = n + 1;
}
// Inner 3*3 black box
for (i = 0; i <= 2; i++) {
for (j = 0; j <= 2; j++) {
if (qr.isDarkWithSize(3 + x, 3 + y, moduleSize)) {
n = n + 1;
}
}
}
if (!qr.isDarkWithSize(x + 1, y + 5 - i, moduleSize)) {
n = n + 1;
}
}
// quiet area
for (i = 0; i <= 6; i++) {
if (!qr.isDarkWithSize(x + quietX, y + i, moduleSize)) {
n = n + 1;
}
// Inner 3*3 black box
for (i = 0; i <= 2; i++) {
for (j = 0; j <= 2; j++) {
if (qr.isDarkWithSize(3 + x, 3 + y, moduleSize)) {
n = n + 1;
}
}
}
if (!qr.isDarkWithSize(x + i, y + quietY, moduleSize)) {
n = n + 1;
}
}
// quiet area
for (i = 0; i <= 6; i++) {
if (!qr.isDarkWithSize(x + quietX, y + i, moduleSize)) {
n = n + 1;
}
// 'bottom right' quiet area
if (!qr.isDarkWithSize(x + quietX, y + quietY, moduleSize)) {
n = n + 1;
}
return n;
if (!qr.isDarkWithSize(x + i, y + quietY, moduleSize)) {
n = n + 1;
}
}
function matchTimingPattern(qr, horizontal, nModules, moduleSize) {
var n = 0,
x0 = 6,
y0 = 8,
dx = 0,
dy = 1,
consecutive = 5,
ok = [],
c,
black = true,
i,
x, y,
last5;
// 'bottom right' quiet area
if (!qr.isDarkWithSize(x + quietX, y + quietY, moduleSize)) {
n = n + 1;
}
if (horizontal) {
x0 = 8;
y0 = 6;
dx = 1;
dy = 0;
}
return n;
}
for (c = 0; c < consecutive; c++) {
ok.push(1);
}
function matchTimingPattern(qr, horizontal, nModules, moduleSize) {
var n = 0,
x0 = 6,
y0 = 8,
dx = 0,
dy = 1,
consecutive = 5,
ok = [],
c,
black = true,
i,
x, y,
last5;
for (i = 0; i < nModules - 8 - 8; i++) {
x = x0 + i * dx;
y = y0 + i * dy;
if (horizontal) {
x0 = 8;
y0 = 6;
dx = 1;
dy = 0;
}
if (black === qr.isDarkWithSize(x, y, moduleSize)) {
n++;
ok.push(1);
} else {
ok.push(0);
}
for (c = 0; c < consecutive; c++) {
ok.push(1);
}
black = !black;
last5 = 0;
for (i = 0; i < nModules - 8 - 8; i++) {
x = x0 + i * dx;
y = y0 + i * dy;
for (c = ok.length - consecutive; c < ok.length - 1; c++) {
if (ok[c]) {
last5 = last5 + 1;
}
}
if (black === qr.isDarkWithSize(x, y, moduleSize)) {
n++;
ok.push(1);
} else {
ok.push(0);
}
if (last5 < 3) {
return 0;
}
}
black = !black;
last5 = 0;
return n;
for (c = ok.length - consecutive; c < ok.length - 1; c++) {
if (ok[c]) {
last5 = last5 + 1;
}
}
function matchOneAlignmentPattern(qr, x, y, moduleSize) {
var n = 0,
i;
if (last5 < 3) {
return 0;
}
}
// Outer 5x5 black boundary
for (i = 0; i <= 3; i++) {
if (qr.isDarkWithSize(x + i, y, moduleSize)) {
n = n + 1;
}
return n;
}
if (qr.isDarkWithSize(x + 4, y + i, moduleSize)) {
n = n + 1;
}
function matchOneAlignmentPattern(qr, x, y, moduleSize) {
var n = 0,
i;
if (qr.isDarkWithSize(x + 4 - i, y + 4, moduleSize)) {
n = n + 1;
}
// Outer 5x5 black boundary
for (i = 0; i <= 3; i++) {
if (qr.isDarkWithSize(x + i, y, moduleSize)) {
n = n + 1;
}
if (qr.isDarkWithSize(x, y + 4 - i, moduleSize)) {
n = n + 1;
}
}
if (qr.isDarkWithSize(x + 4, y + i, moduleSize)) {
n = n + 1;
}
// Intermediate 3*3 white
for (i = 0; i <= 1; i++) {
if (!qr.isDarkWithSize(x + i + 1, y + 1, moduleSize)) {
n = n + 1;
}
if (qr.isDarkWithSize(x + 4 - i, y + 4, moduleSize)) {
n = n + 1;
}
if (!qr.isDarkWithSize(x + 3, y + i + 1, moduleSize)) {
n = n + 1;
}
if (qr.isDarkWithSize(x, y + 4 - i, moduleSize)) {
n = n + 1;
}
}
if (!qr.isDarkWithSize(x + 3 - i, y + 3, moduleSize)) {
n = n + 1;
}
// Intermediate 3*3 white
for (i = 0; i <= 1; i++) {
if (!qr.isDarkWithSize(x + i + 1, y + 1, moduleSize)) {
n = n + 1;
}
if (!qr.isDarkWithSize(x + 1, y + 3 - i, moduleSize)) {
n = n + 1;
}
}
if (!qr.isDarkWithSize(x + 3, y + i + 1, moduleSize)) {
n = n + 1;
}
// center black
if (qr.isDarkWithSize(x + 2, y + 2, moduleSize)) {
n = n + 1;
}
if (!qr.isDarkWithSize(x + 3 - i, y + 3, moduleSize)) {
n = n + 1;
}
return n;
if (!qr.isDarkWithSize(x + 1, y + 3 - i, moduleSize)) {
n = n + 1;
}
}
function matchAlignmentPatterns(qr, version, moduleSize) {
var a = 0,
n = QRBase.alignmentPatterns[version].length,
i, j, na;
// center black
if (qr.isDarkWithSize(x + 2, y + 2, moduleSize)) {
n = n + 1;
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (((i === 0) && (j === 0)) || ((i === 0) && (j === n - 1)) || ((i === n - 1) && (j === 0))) {
continue;
}
return n;
}
na = matchOneAlignmentPattern(
qr,
QRBase.alignmentPatterns[version][i] - 2,
QRBase.alignmentPatterns[version][j] - 2,
moduleSize
);
function matchAlignmentPatterns(qr, version, moduleSize) {
var a = 0,
n = QRBase.alignmentPatterns[version].length,
i, j, na;
if (na > 24) { a++; }
}
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (((i === 0) && (j === 0)) || ((i === 0) && (j === n - 1)) || ((i === n - 1) && (j === 0))) {
continue;
}
return a;
na = matchOneAlignmentPattern(
qr,
QRBase.alignmentPatterns[version][i] - 2,
QRBase.alignmentPatterns[version][j] - 2,
moduleSize
);
if (na > 24) { a++; }
}
}
function matchVersionCode(qr, pattern) {
var v, hd;
return a;
}
for (v = 7; v <= 40; v++) {
hd = qr.hammingDistance(pattern, QRBase.versionInfo[v]);
if (hd <= 3) { return [v, hd]; }
}
function matchVersionCode(qr, pattern) {
var v, hd;
return [0, 4];
}
for (v = 7; v <= 40; v++) {
hd = qr.hammingDistance(pattern, QRBase.versionInfo[v]);
if (hd <= 3) { return [v, hd]; }
}
function matchVersionTopright(qr, nModules, moduleSize) {
var factor = 1,
pattern = 0,
x, y;
return [0, 4];
}
for (y = 0; y < 6; y++) {
for (x = nModules - 11; x < nModules - 11 + 3; x++) {
if (qr.isDarkWithSize(x, y, moduleSize)) {
pattern += factor;
}
factor *= 2;
}
}
function matchVersionTopright(qr, nModules, moduleSize) {
var factor = 1,
pattern = 0,
x, y;
return matchVersionCode(qr, pattern);
for (y = 0; y < 6; y++) {
for (x = nModules - 11; x < nModules - 11 + 3; x++) {
if (qr.isDarkWithSize(x, y, moduleSize)) {
pattern += factor;
}
factor *= 2;
}
}
function matchVersionBottomleft(qr, nModules, moduleSize) {
var factor = 1,
pattern = 0,
x, y;
return matchVersionCode(qr, pattern);
}
for (x = 0; x < 6; x++) {
for (y = nModules - 11; y < nModules - 11 + 3; y++) {
if (qr.isDarkWithSize(x, y, moduleSize)) {
pattern += factor;
}
function matchVersionBottomleft(qr, nModules, moduleSize) {
var factor = 1,
pattern = 0,
x, y;
factor *= 2;
}
}
for (x = 0; x < 6; x++) {
for (y = nModules - 11; y < nModules - 11 + 3; y++) {
if (qr.isDarkWithSize(x, y, moduleSize)) {
pattern += factor;
}
return matchVersionCode(qr, pattern);
factor *= 2;
}
}
function matchFormatCode(qr, pattern) {
var f, hd;
return matchVersionCode(qr, pattern);
}
for (f = 0; f < 32; f++) {
hd = qr.hammingDistance(pattern, QRBase.formatInfo[f]);
function matchFormatCode(qr, pattern) {
var f, hd;
if (hd <= 3) {
return [f, hd];
}
}
for (f = 0; f < 32; f++) {
hd = qr.hammingDistance(pattern, QRBase.formatInfo[f]);
return [0, 4];
if (hd <= 3) {
return [f, hd];
}
}
function matchFormatNW(qr, nModules, moduleSize) {
var factor = 1,
pattern = 0,
x = 8,
y;
return [0, 4];
}
for (y = 0; y <= 5; y++) {
if (qr.isDarkWithSize(x, y, moduleSize)) {
pattern += factor;
}
function matchFormatNW(qr, nModules, moduleSize) {
var factor = 1,
pattern = 0,
x = 8,
y;
factor *= 2;
}
for (y = 0; y <= 5; y++) {
if (qr.isDarkWithSize(x, y, moduleSize)) {
pattern += factor;
}
if (qr.isDarkWithSize(8, 7, moduleSize)) {
pattern += factor;
}
factor *= 2;
}
factor *= 2;
if (qr.isDarkWithSize(8, 7, moduleSize)) {
pattern += factor;
}
if (qr.isDarkWithSize(8, 8, moduleSize)) {
pattern += factor;
}
factor *= 2;
factor *= 2;
if (qr.isDarkWithSize(8, 8, moduleSize)) {
pattern += factor;
}
if (qr.isDarkWithSize(7, 8, moduleSize)) {
pattern += factor;
}
factor *= 2;
factor *= 2;
y = 8;
if (qr.isDarkWithSize(7, 8, moduleSize)) {
pattern += factor;
}
for (x = 5; x >= 0; x--) {
if (qr.isDarkWithSize(x, y, moduleSize)) {
pattern += factor;
}
factor *= 2;
y = 8;
factor *= 2;
}
return matchFormatCode(qr, pattern);
for (x = 5; x >= 0; x--) {
if (qr.isDarkWithSize(x, y, moduleSize)) {
pattern += factor;
}
function matchFormatNESW(qr, nModules, moduleSize) {
var factor = 1,
pattern = 0,
x,
y = 8;
factor *= 2;
}
for (x = nModules - 1; x > nModules - 1 - 8; x--) {
if (qr.isDarkWithSize(x, y, moduleSize)) {
pattern += factor;
}
return matchFormatCode(qr, pattern);
}
factor *= 2;
}
function matchFormatNESW(qr, nModules, moduleSize) {
var factor = 1,
pattern = 0,
x,
y = 8;
x = 8;
for (x = nModules - 1; x > nModules - 1 - 8; x--) {
if (qr.isDarkWithSize(x, y, moduleSize)) {
pattern += factor;
}
for (y = nModules - 7; y < nModules - 1; y++) {
if (qr.isDarkWithSize(x, y, moduleSize)) {
pattern += factor;
}
factor *= 2;
}
factor *= 2;
}
x = 8;
return matchFormatCode(qr, pattern);
for (y = nModules - 7; y < nModules - 1; y++) {
if (qr.isDarkWithSize(x, y, moduleSize)) {
pattern += factor;
}
function gradeFinderPatterns(finderPattern) {
var g = 4,
i;
factor *= 2;
}
for (i = 0; i < 3; i++) {
g = g - (64 - finderPattern[i]);
}
return matchFormatCode(qr, pattern);
}
if (g < 0) {
g = 0;
}
function gradeFinderPatterns(finderPattern) {
var g = 4,
i;
return g;
}
for (i = 0; i < 3; i++) {
g = g - (64 - finderPattern[i]);
}
function gradeTimingPatterns(timingPattern, n) {
var t = (timingPattern[0] + timingPattern[1]) / (2 * n);
if (g < 0) {
g = 0;
}
t = 1 - t;
return g;
}
if (t >= 0.14) {
return 0;
}
function gradeTimingPatterns(timingPattern, n) {
var t = (timingPattern[0] + timingPattern[1]) / (2 * n);
if (t >= 0.11) {
return 1;
}
t = 1 - t;
if (t >= 0.07) {
return 2;
}
if (t >= 0.14) {
return 0;
}
if (t >= 0.00001) {
return 3;
}
if (t >= 0.11) {
return 1;
}
return 4;
}
if (t >= 0.07) {
return 2;
}
function gradeAlignmentPatterns(alignmentPatterns, n) {
var a = alignmentPatterns / n;
if (t >= 0.00001) {
return 3;
}
a = 1 - a;
return 4;
}
if (a >= 0.30) {
return 0;
}
function gradeAlignmentPatterns(alignmentPatterns, n) {
var a = alignmentPatterns / n;
if (a >= 0.20) {
return 1;
}
a = 1 - a;
if (a >= 0.10) {
return 2;
}
if (a >= 0.30) {
return 0;
}
if (a >= 0.00001) {
return 3;
}
if (a >= 0.20) {
return 1;
}
return 4;
}
if (a >= 0.10) {
return 2;
}
function matchVersion(qr, version) {
var g,
grades = [],
nModules = QRBase.nModulesFromVersion(version),
moduleSize = qr.imageSize / nModules,
finderPattern = [0, 0, 0],
versionTopright = [0, 0],
versionBottomleft = [0, 0],
timingPattern = [0, 0],
alignmentPatterns = -3,
format = 0,
v1, formatNW, formatNESW,
ECLevel, mask, grade = 4,
i;
if (a >= 0.00001) {
return 3;
}
finderPattern[0] = matchFinderPattern(qr, 0, 0, 7, 7, moduleSize);
return 4;
}
if (finderPattern[0] < 64 - 3) {
return [version, 0]; // performance hack!
}
function matchVersion(qr, version) {
var g,
grades = [],
nModules = QRBase.nModulesFromVersion(version),
moduleSize = qr.imageSize / nModules,
finderPattern = [0, 0, 0],
versionTopright = [0, 0],
versionBottomleft = [0, 0],
timingPattern = [0, 0],
alignmentPatterns = -3,
format = 0,
v1, formatNW, formatNESW,
ECLevel, mask, grade = 4,
i;
finderPattern[1] = matchFinderPattern(qr, 0, nModules - 7, 7, -1, moduleSize);
finderPattern[0] = matchFinderPattern(qr, 0, 0, 7, 7, moduleSize);
if (finderPattern[0] + finderPattern[1] < 64 + 64 - 3) {
return [version, 0]; // performance hack!
}
if (finderPattern[0] < 64 - 3) {
return [version, 0]; // performance hack!
}
finderPattern[2] = matchFinderPattern(qr, nModules - 7, 0, -1, 7, moduleSize);
g = gradeFinderPatterns(finderPattern);
finderPattern[1] = matchFinderPattern(qr, 0, nModules - 7, 7, -1, moduleSize);
if (g < 1) {
return [version, 0];
} else {
grades.push(g);
}
if (finderPattern[0] + finderPattern[1] < 64 + 64 - 3) {
return [version, 0]; // performance hack!
}
if (version >= 7) {
versionTopright = matchVersionTopright(qr, nModules, moduleSize);
versionBottomleft = matchVersionBottomleft(qr, nModules, moduleSize);
v1 = version;
finderPattern[2] = matchFinderPattern(qr, nModules - 7, 0, -1, 7, moduleSize);
g = gradeFinderPatterns(finderPattern);
if (versionTopright[1] < versionBottomleft[1]) {
if (versionTopright[1] < 4) { v1 = versionTopright[0]; }
} else {
if (versionBottomleft[1] < 4) { v1 = versionBottomleft[0]; }
}
if (g < 1) {
return [version, 0];
} else {
grades.push(g);
}
if (v1 !== version) {
version = v1;
}
if (version >= 7) {
versionTopright = matchVersionTopright(qr, nModules, moduleSize);
versionBottomleft = matchVersionBottomleft(qr, nModules, moduleSize);
v1 = version;
nModules = QRBase.nModulesFromVersion(version);
moduleSize = qr.imageSize / nModules;
g = Math.round(((4 - versionTopright[1]) + (4 - versionBottomleft[1])) / 2);
if (versionTopright[1] < versionBottomleft[1]) {
if (versionTopright[1] < 4) { v1 = versionTopright[0]; }
} else {
if (versionBottomleft[1] < 4) { v1 = versionBottomleft[0]; }
}
if (g < 1) {
return [version, 0];
} else {
grades.push(g);
}
}
if (v1 !== version) {
version = v1;
}
timingPattern[0] = matchTimingPattern(qr, true, nModules, moduleSize);
timingPattern[1] = matchTimingPattern(qr, false, nModules, moduleSize);
g = gradeTimingPatterns(timingPattern, nModules - 8 - 8);
nModules = QRBase.nModulesFromVersion(version);
moduleSize = qr.imageSize / nModules;
g = Math.round(((4 - versionTopright[1]) + (4 - versionBottomleft[1])) / 2);
if (g < 1) {
return [version, 0];
} else {
grades.push(g);
}
if (g < 1) {
return [version, 0];
} else {
grades.push(g);
}
}
if (version > 1) {
alignmentPatterns = matchAlignmentPatterns(qr, version, moduleSize);
}
timingPattern[0] = matchTimingPattern(qr, true, nModules, moduleSize);
timingPattern[1] = matchTimingPattern(qr, false, nModules, moduleSize);
g = gradeTimingPatterns(timingPattern, nModules - 8 - 8);
g = gradeAlignmentPatterns(alignmentPatterns,
QRBase.alignmentPatterns[version].length * QRBase.alignmentPatterns[version].length - 3);
if (g < 1) {
return [version, 0];
} else {
grades.push(g);
}
if (g < 1) {
return [version, 0];
} else {
grades.push(g);
}
if (version > 1) {
alignmentPatterns = matchAlignmentPatterns(qr, version, moduleSize);
}
formatNW = matchFormatNW(qr, nModules, moduleSize);
formatNESW = matchFormatNESW(qr, nModules, moduleSize);
g = gradeAlignmentPatterns(alignmentPatterns,
QRBase.alignmentPatterns[version].length * QRBase.alignmentPatterns[version].length - 3);
if (formatNW[1] < formatNESW[1]) {
format = formatNW[0];
} else {
format = formatNESW[0];
}
if (g < 1) {
return [version, 0];
} else {
grades.push(g);
}
ECLevel = Math.floor(format / 8);
mask = format % 8;
g = Math.round(((4 - formatNW[1]) + (4 - formatNESW[1])) / 2);
formatNW = matchFormatNW(qr, nModules, moduleSize);
formatNESW = matchFormatNESW(qr, nModules, moduleSize);
if (g < 1) {
return [version, 0];
} else {
grades.push(g);
}
if (formatNW[1] < formatNESW[1]) {
format = formatNW[0];
} else {
format = formatNESW[0];
}
for (i = 0; i < grades.length; i++) {
if (grades[i] < grade) {
grade = grades[i];
}
}
ECLevel = Math.floor(format / 8);
mask = format % 8;
g = Math.round(((4 - formatNW[1]) + (4 - formatNESW[1])) / 2);
return [version, grade, ECLevel, mask];
if (g < 1) {
return [version, 0];
} else {
grades.push(g);
}
for (i = 0; i < grades.length; i++) {
if (grades[i] < grade) {
grade = grades[i];
}
}
/**
* findModuleSize
*/
var bestMatchSoFar = [0, 0],
version, match;
return [version, grade, ECLevel, mask];
}
for (version = 1; version <= this.maxVersion; version++) {
match = matchVersion(this, version);
/**
* findModuleSize
*/
var bestMatchSoFar = [0, 0],
version, match;
if (match[1] > bestMatchSoFar[1]) { bestMatchSoFar = match; }
if (match[1] === 4) { break; }
}
for (version = 1; version <= this.maxVersion; version++) {
match = matchVersion(this, version);
this.version = bestMatchSoFar[0];
this.nModules = QRBase.nModulesFromVersion(this.version);
this.moduleSize = this.imageSize / this.nModules;
this.functionalGrade = bestMatchSoFar[1];
this.ECLevel = bestMatchSoFar[2];
this.mask = bestMatchSoFar[3];
if (match[1] > bestMatchSoFar[1]) { bestMatchSoFar = match; }
if (match[1] === 4) { break; }
}
if (this.functionalGrade < 1) {
throw new QRBase.QRError('Unable to decode a function pattern', 5);
}
},
extractCodewords: function() {
function getUnmasked(qr, j, i) {
var m, u;
this.version = bestMatchSoFar[0];
this.nModules = QRBase.nModulesFromVersion(this.version);
this.moduleSize = this.imageSize / this.nModules;
this.functionalGrade = bestMatchSoFar[1];
this.ECLevel = bestMatchSoFar[2];
this.mask = bestMatchSoFar[3];
switch (qr.mask) {
case 0:
m = (i + j) % 2;
break;
case 1:
m = i % 2;
break;
case 2:
m = j % 3;
break;
case 3:
m = (i + j) % 3;
break;
case 4:
m = (Math.floor(i / 2) + Math.floor(j / 3)) % 2;
break;
case 5:
m = (i * j) % 2 + (i * j) % 3;
break;
case 6:
m = ((i * j) % 2 + (i * j) % 3) % 2;
break;
case 7:
m = ((i + j) % 2 + (i * j) % 3) % 2;
break;
}
if (this.functionalGrade < 1) {
throw new QRBase.QRError('Unable to decode a function pattern', 5);
}
},
extractCodewords: function () {
function getUnmasked(qr, j, i) {
var m, u;
if (m === 0) {
u = !qr.isDark(j, i);
} else {
u = qr.isDark(j, i);
}
switch (qr.mask) {
case 0:
m = (i + j) % 2;
break;
case 1:
m = i % 2;
break;
case 2:
m = j % 3;
break;
case 3:
m = (i + j) % 3;
break;
case 4:
m = (Math.floor(i / 2) + Math.floor(j / 3)) % 2;
break;
case 5:
m = (i * j) % 2 + (i * j) % 3;
break;
case 6:
m = ((i * j) % 2 + (i * j) % 3) % 2;
break;
case 7:
m = ((i + j) % 2 + (i * j) % 3) % 2;
break;
}
return u;
}
if (m === 0) {
u = !qr.isDark(j, i);
} else {
u = qr.isDark(j, i);
}
/**
* extractCodewords
* Original Java version by Sean Owen
* Copyright 2007 ZXing authors
*/
this.codewords = [];
return u;
}
var readingUp = true,
currentByte = 0,
factor = 128,
bitsRead = 0,
i, j, col, count;
/**
* extractCodewords
* Original Java version by Sean Owen
* Copyright 2007 ZXing authors
*/
this.codewords = [];
// Read columns in pairs, from right to left
for (j = this.nModules - 1; j > 0; j -= 2) {
if (j === 6) {
// Skip whole column with vertical alignment pattern;
// saves time and makes the other code proceed more cleanly
j--;
}
var readingUp = true,
currentByte = 0,
factor = 128,
bitsRead = 0,
i, j, col, count;
// Read alternatingly from bottom to top then top to bottom
for (count = 0; count < this.nModules; count++) {
i = readingUp ? this.nModules - 1 - count : count;
// Read columns in pairs, from right to left
for (j = this.nModules - 1; j > 0; j -= 2) {
if (j === 6) {
// Skip whole column with vertical alignment pattern;
// saves time and makes the other code proceed more cleanly
j--;
}
for (col = 0; col < 2; col++) {
// Ignore bits covered by the function pattern
if (!this.functionalPattern[j - col][i]) {
// Read a bit
if (getUnmasked(this, j - col, i)) {
currentByte += factor;
}
// Read alternatingly from bottom to top then top to bottom
for (count = 0; count < this.nModules; count++) {
i = readingUp ? this.nModules - 1 - count : count;
factor /= 2;
// If we've made a whole byte, save it off
if (factor < 1) {
this.codewords.push(currentByte);
bitsRead = 0;
factor = 128;
currentByte = 0;
}
}
}
for (col = 0; col < 2; col++) {
// Ignore bits covered by the function pattern
if (!this.functionalPattern[j - col][i]) {
// Read a bit
if (getUnmasked(this, j - col, i)) {
currentByte += factor;
}
readingUp ^= true; // switch directions
}
},
extractData: function() {
function extract(qr, bytes, pos, len) {
// http://stackoverflow.com/questions/3846711/extract-bit-sequences-of-arbitrary-length-from-byte-array-efficiently
var shift = 24 - (pos & 7) - len,
mask = (1 << len) - 1,
byteIndex = pos >>> 3;
factor /= 2;
return (((bytes[byteIndex] << 16) | (bytes[++byteIndex] << 8) | bytes[++byteIndex]) >> shift) & mask;
// If we've made a whole byte, save it off
if (factor < 1) {
this.codewords.push(currentByte);
bitsRead = 0;
factor = 128;
currentByte = 0;
}
}
}
}
function extract8bit(qr, bytes) {
var nCountBits = QRBase.nCountBits(QRBase.MODE.EightBit, qr.version),
n = extract(qr, bytes, qr.bitIdx, nCountBits),
data = '',
i, a;
readingUp ^= true; // switch directions
}
},
extractData: function () {
function extract(qr, bytes, pos, len) {
// http://stackoverflow.com/questions/3846711/extract-bit-sequences-of-arbitrary-length-from-byte-array-efficiently
var shift = 24 - (pos & 7) - len,
mask = (1 << len) - 1,
byteIndex = pos >>> 3;
qr.bitIdx += nCountBits;
return (((bytes[byteIndex] << 16) | (bytes[++byteIndex] << 8) | bytes[++byteIndex]) >> shift) & mask;
}
for (i = 0; i < n; i++) {
a = extract(qr, bytes, qr.bitIdx, 8);
data += String.fromCharCode(a);
qr.bitIdx += 8;
}
function extract8bit(qr, bytes) {
var nCountBits = QRBase.nCountBits(QRBase.MODE.EightBit, qr.version),
n = extract(qr, bytes, qr.bitIdx, nCountBits),
data = '',
i, a;
return QRBase.utf8Tounicode(data);
}
qr.bitIdx += nCountBits;
function extractAlphanum(qr, bytes) {
var nCountBits = QRBase.nCountBits(QRBase.MODE.AlphaNumeric, qr.version),
n = extract(qr, bytes, qr.bitIdx, nCountBits),
data = '',
i, x;
for (i = 0; i < n; i++) {
a = extract(qr, bytes, qr.bitIdx, 8);
data += String.fromCharCode(a);
qr.bitIdx += 8;
}
qr.bitIdx += nCountBits;
return QRBase.utf8Tounicode(data);
}
for (i = 0; i < Math.floor(n / 2); i++) {
x = extract(qr, bytes, qr.bitIdx, 11);
data += qr.alphanum[Math.floor(x / 45)];
data += qr.alphanum[x % 45];
qr.bitIdx += 11;
}
function extractAlphanum(qr, bytes) {
var nCountBits = QRBase.nCountBits(QRBase.MODE.AlphaNumeric, qr.version),
n = extract(qr, bytes, qr.bitIdx, nCountBits),
data = '',
i, x;
if (n % 2) {
data += qr.alphanum[extract(qr, bytes, qr.bitIdx, 6)];
qr.bitIdx += 6;
}
qr.bitIdx += nCountBits;
return data;
}
for (i = 0; i < Math.floor(n / 2); i++) {
x = extract(qr, bytes, qr.bitIdx, 11);
data += qr.alphanum[Math.floor(x / 45)];
data += qr.alphanum[x % 45];
qr.bitIdx += 11;
}
function extractNumeric(qr, bytes) {
var nCountBits = QRBase.nCountBits(QRBase.MODE.Numeric, qr.version),
n = extract(qr, bytes, qr.bitIdx, nCountBits),
data = '',
x, c1, c2, c3,
i;
if (n % 2) {
data += qr.alphanum[extract(qr, bytes, qr.bitIdx, 6)];
qr.bitIdx += 6;
}
qr.bitIdx += nCountBits;
return data;
}
for (i = 0; i < Math.floor(n / 3); i++) {
x = extract(qr, bytes, qr.bitIdx, 10);
qr.bitIdx += 10;
c1 = Math.floor(x / 100);
c2 = Math.floor((x % 100) / 10);
c3 = x % 10;
data += String.fromCharCode(48 + c1, 48 + c2, 48 + c3);
}
function extractNumeric(qr, bytes) {
var nCountBits = QRBase.nCountBits(QRBase.MODE.Numeric, qr.version),
n = extract(qr, bytes, qr.bitIdx, nCountBits),
data = '',
x, c1, c2, c3,
i;
if (n % 3 === 1) {
x = extract(qr, bytes, qr.bitIdx, 4);
qr.bitIdx += 4;
data += String.fromCharCode(48 + x);
} else if (n % 3 === 2) {
x = extract(qr, bytes, qr.bitIdx, 7);
qr.bitIdx += 7;
c1 = Math.floor(x / 10);
c2 = x % 10;
data += String.fromCharCode(48 + c1, 48 + c2);
}
qr.bitIdx += nCountBits;
return data;
}
for (i = 0; i < Math.floor(n / 3); i++) {
x = extract(qr, bytes, qr.bitIdx, 10);
qr.bitIdx += 10;
c1 = Math.floor(x / 100);
c2 = Math.floor((x % 100) / 10);
c3 = x % 10;
data += String.fromCharCode(48 + c1, 48 + c2, 48 + c3);
}
// extractData
var bytes = this.bytes,
nBits = bytes.length * 8,
i, mode;
if (n % 3 === 1) {
x = extract(qr, bytes, qr.bitIdx, 4);
qr.bitIdx += 4;
data += String.fromCharCode(48 + x);
} else if (n % 3 === 2) {
x = extract(qr, bytes, qr.bitIdx, 7);
qr.bitIdx += 7;
c1 = Math.floor(x / 10);
c2 = x % 10;
data += String.fromCharCode(48 + c1, 48 + c2);
}
for (i = 0; i < 4; i++) {
bytes.push(0);
}
return data;
}
this.data = '';
this.bitIdx = 0;
// extractData
var bytes = this.bytes,
nBits = bytes.length * 8,
i, mode;
while (this.bitIdx < nBits - 4) {
mode = extract(this, bytes, this.bitIdx, 4);
this.bitIdx += 4;
for (i = 0; i < 4; i++) {
bytes.push(0);
}
if (mode === QRBase.MODE.Terminator) { break; } else if (mode === QRBase.MODE.AlphaNumeric) { this.data += extractAlphanum(this, bytes); } else if (mode === QRBase.MODE.EightBit) { this.data += extract8bit(this, bytes); } else if (mode === QRBase.MODE.Numeric) { this.data += extractNumeric(this, bytes); } else { throw new QRBase.QRError('Unsupported ECI mode: ' + mode, 1, mode); }
}
},
correctErrors: function() {
var rs = new ReedSolomon(this.nBlockEcWords),
errors = [],
bytes = [],
b,
bytesIn, bytesOut,
i;
this.data = '';
this.bitIdx = 0;
for (b = 0; b < this.blockIndices.length; b++) {
bytesIn = [];
while (this.bitIdx < nBits - 4) {
mode = extract(this, bytes, this.bitIdx, 4);
this.bitIdx += 4;
for (i = 0; i < this.blockIndices[b].length; i++) {
bytesIn.push(this.codewords[this.blockIndices[b][i]]);
}
if (mode === QRBase.MODE.Terminator) { break; } else if (mode === QRBase.MODE.AlphaNumeric) { this.data += extractAlphanum(this, bytes); } else if (mode === QRBase.MODE.EightBit) { this.data += extract8bit(this, bytes); } else if (mode === QRBase.MODE.Numeric) { this.data += extractNumeric(this, bytes); } else { throw new QRBase.QRError('Unsupported ECI mode: ' + mode, 1, mode); }
}
},
correctErrors: function () {
var rs = new ReedSolomon(this.nBlockEcWords),
errors = [],
bytes = [],
b,
bytesIn, bytesOut,
i;
bytesOut = rs.decode(bytesIn);
for (b = 0; b < this.blockIndices.length; b++) {
bytesIn = [];
if (!rs.corrected) {
this.errorGrade = 0;
throw new QRBase.QRError('Unable to correct errors (' + rs.uncorrected_reason + ')', 6, rs.uncorrected_reason);
}
for (i = 0; i < this.blockIndices[b].length; i++) {
bytesIn.push(this.codewords[this.blockIndices[b][i]]);
}
bytes = bytes.concat(bytesOut);
errors.push(rs.n_errors);
}
bytesOut = rs.decode(bytesIn);
this.errors = errors;
this.bytes = bytes;
this.errorGrade = this.gradeErrors(errors);
},
gradeErrors: function(errors) {
var ecw = this.nBlockEcWords,
max = 0,
grade = 4,
i;
if (!rs.corrected) {
this.errorGrade = 0;
throw new QRBase.QRError('Unable to correct errors (' + rs.uncorrected_reason + ')', 6, rs.uncorrected_reason);
}
for (i = 0; i < errors.length; i++) {
if (errors[i] > max) { max = errors[i]; }
}
bytes = bytes.concat(bytesOut);
errors.push(rs.n_errors);
}
if (max > ecw / 2 - 1) {
grade = 0;
} else if (max > ecw / 2 - 2) {
grade = 1;
} else if (max > ecw / 2 - 3) {
grade = 2;
} else if (max > ecw / 2 - 4) {
grade = 3;
}
this.errors = errors;
this.bytes = bytes;
this.errorGrade = this.gradeErrors(errors);
},
gradeErrors: function (errors) {
var ecw = this.nBlockEcWords,
max = 0,
grade = 4,
i;
return grade;
},
hammingDistance: function(a, b) {
function nBits(n) {
var c;
for (i = 0; i < errors.length; i++) {
if (errors[i] > max) { max = errors[i]; }
}
for (c = 0; n; c++) {
n &= n - 1; // clear the least significant bit set
}
if (max > ecw / 2 - 1) {
grade = 0;
} else if (max > ecw / 2 - 2) {
grade = 1;
} else if (max > ecw / 2 - 3) {
grade = 2;
} else if (max > ecw / 2 - 4) {
grade = 3;
}
return c;
}
return grade;
},
hammingDistance: function (a, b) {
function nBits(n) {
var c;
var d = a ^ b;
for (c = 0; n; c++) {
n &= n - 1; // clear the least significant bit set
}
return nBits(d);
},
/**
* QRCodeDecode IMAGE FUNCTIONS
*/
isDarkWithSize: function(x, y, moduleSize) {
return this.image.isDark(Math.round(this.imageLeft + x * moduleSize),
Math.round(this.imageTop + y * moduleSize), Math.round(moduleSize));
},
isDark: function(x, y) {
return this.isDarkWithSize(x, y, this.moduleSize);
},
/**
* QRCode decode constants
*/
alphanum: [
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
' ',
'$',
'%',
'*',
'+',
'-',
'.',
'/',
':'
]
return c;
}
var d = a ^ b;
return nBits(d);
},
/**
* QRCodeDecode IMAGE FUNCTIONS
*/
isDarkWithSize: function (x, y, moduleSize) {
return this.image.isDark(Math.round(this.imageLeft + x * moduleSize),
Math.round(this.imageTop + y * moduleSize), Math.round(moduleSize));
},
isDark: function (x, y) {
return this.isDarkWithSize(x, y, this.moduleSize);
},
/**
* QRCode decode constants
*/
alphanum: [
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
' ',
'$',
'%',
'*',
'+',
'-',
'.',
'/',
':'
]
};
export default QRDecode
export default QRDecode
/**
* QRDecode
* QREncode
*/
'use strict';
import QRDecode from './decode'
import QREncode from './encode'
let QREncodeConf = {
/**
* 配置
*/
config: {
text: 'QRCode', // 默认文字
render: 'canvas',
bgColor: '#FFF', // 背景色
moduleColor: '#000', // 前景色
moduleSize: 5, // 模块大小
mode: 4, // 编码格式,默认8字节编码
ECLevel: 2, // 纠错码等级,默认30%
margin: 4, // 留白
logo: '', // logo;
error: () => { }
},
Render: {
canvas: function (self, callback) {
var i;
var j;
var cfg = self.config;
var mSize = cfg.moduleSize;
var size = self.pixArr.length;
var outSize = 2 * cfg.margin + size;
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
function getRGB(color) {
var red, green, blue;
if (color.indexOf('#') === 0) {
color = color.substr(1);
}
if (color.length === 6) {
red = color.substr(0, 2);
green = color.substr(2, 2);
blue = color.substr(4, 2);
} else if (color.length === 3) {
red = color.substr(0, 1);
red += red;
green = color.substr(1, 1);
green += green;
blue = color.substr(2, 1);
blue += blue;
} else {
throw new Error('Error color');
}
return 'rgb(' + parseInt(red, 16) + ', ' + parseInt(green, 16) + ', ' + parseInt(blue, 16) + ')';
}
// 初始化画布
function init(size) {
size = cfg.margin * 2 + size;
canvas.width = size * mSize;
canvas.height = size * mSize;
ctx.fillStyle = getRGB(cfg.bgColor);
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
// 设置色块
function setBlock(i, j) {
ctx.fillStyle = getRGB(cfg.moduleColor);
ctx.fillRect(i * mSize, j * mSize, mSize, mSize);
}
// 渲染logo
function renderLogo(callback) {
var img = new Image();
img.onload = function () {
var x;
var y;
var zoom;
var imgW = img.width;
var imgH = img.height;
var imgSize = Math.max(imgW, imgH);
if (imgSize > size * mSize * 0.3) {
zoom = (size * mSize * 0.3) / imgSize;
imgW = imgW * zoom;
imgH = imgH * zoom;
}
x = Math.round((outSize * mSize - imgW) / 2);
y = Math.round((outSize * mSize - imgH) / 2);
ctx.drawImage(img, x, y, imgW, imgH);
typeof callback === 'function' && callback();
img.onload = null;
};
img.src = cfg.logo;
}
init(size);
for (i = cfg.margin; i < size + cfg.margin; i++) {
for (j = cfg.margin; j < size + cfg.margin; j++) {
if (self.pixArr[i - cfg.margin][j - cfg.margin]) {
setBlock(i, j, getRGB(cfg.moduleColor));
}
}
}
if (cfg.logo) {
renderLogo(function () {
typeof callback === 'function' && callback(canvas);
});
} else {
typeof callback === 'function' && callback(canvas);
}
}
}
};
/**
* 二维码解码
* @param canvas
* @param error
* 二维码编码
* @param config
* @param callback
* @returns {*}
* @constructor
*/
function Decode(canvas, error) {
this.text = this._init(this.getImageData(canvas), error);
function Encode(config, callback) {
this.config = config;
// 初始化
return this._init(callback);
}
Decode.prototype = {
_init: function (imageData, error) {
var text = '';
var qr = new QRDecode();
Encode.prototype = {
_init: function (callback) {
var config = this.config;
this.qr = new QREncode();
// 含有 Logo,使用最大容错
if (config.logo) {
config.ECLevel = 2;
}
try {
text = qr.decodeImageData(imageData, this.width, this.height);
this.version = this.qr.getVersionFromLength(config.ECLevel, config.mode, config.text);
this.pixArr = this.qr.encodeToPix(config.mode, config.text, this.version, config.ECLevel);
} catch (e) {
typeof error === 'function' && error(e);
typeof error === 'function' && config.error(e);
}
return text;
},
getImageData: function (canvas) {
var ctx;
if (canvas.nodeName.toLowerCase() !== 'canvas') {
canvas = canvas
if (!canvas) return null;
}
ctx = canvas.getContext('2d');
this.width = canvas.width;
this.height = canvas.height;
return ctx.getImageData(0, 0, canvas.width, canvas.height);
this.pixArr && QREncodeConf.Render[config.render](this, callback);
}

@@ -46,15 +164,27 @@ };

/**
* 二维码解码
* @param error
* @returns {string}
* 二维码编码
* @param cfg
* @constructor
*/
export default function (canvas) {
var text = '';
var error = function (e) {
console.log('error', e)
export default function (cfg) {
var that = this;
var config = {};
if (typeof (cfg) === 'string') {
config.text = cfg;
} else {
config = Object.assign({}, QREncodeConf.config, cfg)
}
text = (new Decode(canvas, error)).text;
return text;
config.moduleSize = Math.round(config.moduleSize);
config.margin = Math.round(config.margin);
config.moduleSize = config.moduleSize > 0 ? config.moduleSize : QREncodeConf.config.moduleSize;
config.margin = config.margin < 0 ? QREncodeConf.config.margin : config.margin;
let result
let encodeobj = new Encode(config, function (qrdom) {
result = qrdom
})
return result
};
{
"name": "qrcode-pure",
"version": "0.0.1",
"version": "0.0.2",
"description": "qrcode encode and decode",

@@ -15,4 +15,4 @@ "main": "index.js",

"webpack": "^4.10.2",
"webpack-cli": "^3.0.0"
"webpack-cli": "^3.0.1"
}
}

@@ -1,2 +0,86 @@

# qrcode-tool
# qrcode-pure
### 简介
qrcode encode and decode in js (without jquery)
生成\解码二维码的函数。核心源码来自项目[qrcode](https://github.com/nuintun/qrcode),但qrcode使用的是jquery封装,qrcode-pure在此将两个功能拆分了出来。
### 安装
``` bash
# 安装依赖
npm i install --save qrcode-pure
```
### 使用
#### 解码
在项目中使用:(vue单文件组件为例)
``` html
<!-- template -->
<input type="file" @change="handleChange">
<canvas ref="decode-canvas">
<button @click="decode">点击解码</button>
```
``` javascript
// 引入解码函数
// script
import qedecode from 'qrcode-pure/lib/qrdecode'
// methods
handleChange(e) {
var canvas = this.$refs['decode-canvas'],
ctx = canvas.getContext('2d'),
file = e.target.files[0],
reader = new FileReader()
reader.onload = function(e) {
var img = new Image()
img.onload = function() {
canvas.width = img.width
canvas.height = img.height
ctx.drawImage(img, 0, 0)
}
img.src = e.target.result
}
file && reader.readAsDataURL(file)
}
// 调用解码函数
// 传入一个canvas,内容为二维码
// 如果是上传的图片,需要调用canvas的drawImage方法,生成canvas
function decode(){
let result = qedecode(this.$refs['decode-canvas')
// result返回值为解码后的值
console.log('result', result)
}
```
#### 编码
在项目中使用:(vue单文件组件为例)
``` html
<!-- template -->
<el-button @click="encode" type="primary" size="mini" class="m-l_2">编码</el-button>
```
``` javascript
// 引入解码函数
// script
import qrencode from 'qrcode-pure/lib/qrencode'
// methods
encode() {
// 调用 qrencode 编码函数,可接受一个对象参数
// 参数具体内容请参考项目[qrcode](https://github.com/nuintun/qrcode),在此不再赘述。
// 返回值为二维码canvas的DOM
let result = qrencode({ text: 'https://pkjy.github.io' })
}
```
### 在线体验
[qrcode-pure尝试](https://pkjy.github.io/#/gallery/qrcode-pure)
SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc