123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- var Mode = require('./mode');
- var Polynomial = require('./Polynomial');
- var math = require('./math');
- var QRMaskPattern = {
- PATTERN000 : 0,
- PATTERN001 : 1,
- PATTERN010 : 2,
- PATTERN011 : 3,
- PATTERN100 : 4,
- PATTERN101 : 5,
- PATTERN110 : 6,
- PATTERN111 : 7
- };
- var QRUtil = {
- PATTERN_POSITION_TABLE : [
- [],
- [6, 18],
- [6, 22],
- [6, 26],
- [6, 30],
- [6, 34],
- [6, 22, 38],
- [6, 24, 42],
- [6, 26, 46],
- [6, 28, 50],
- [6, 30, 54],
- [6, 32, 58],
- [6, 34, 62],
- [6, 26, 46, 66],
- [6, 26, 48, 70],
- [6, 26, 50, 74],
- [6, 30, 54, 78],
- [6, 30, 56, 82],
- [6, 30, 58, 86],
- [6, 34, 62, 90],
- [6, 28, 50, 72, 94],
- [6, 26, 50, 74, 98],
- [6, 30, 54, 78, 102],
- [6, 28, 54, 80, 106],
- [6, 32, 58, 84, 110],
- [6, 30, 58, 86, 114],
- [6, 34, 62, 90, 118],
- [6, 26, 50, 74, 98, 122],
- [6, 30, 54, 78, 102, 126],
- [6, 26, 52, 78, 104, 130],
- [6, 30, 56, 82, 108, 134],
- [6, 34, 60, 86, 112, 138],
- [6, 30, 58, 86, 114, 142],
- [6, 34, 62, 90, 118, 146],
- [6, 30, 54, 78, 102, 126, 150],
- [6, 24, 50, 76, 102, 128, 154],
- [6, 28, 54, 80, 106, 132, 158],
- [6, 32, 58, 84, 110, 136, 162],
- [6, 26, 54, 82, 110, 138, 166],
- [6, 30, 58, 86, 114, 142, 170]
- ],
- G15 : (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
- G18 : (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
- G15_MASK : (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
- getBCHTypeInfo : function(data) {
- var d = data << 10;
- while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
- d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) );
- }
- return ( (data << 10) | d) ^ QRUtil.G15_MASK;
- },
- getBCHTypeNumber : function(data) {
- var d = data << 12;
- while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
- d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) );
- }
- return (data << 12) | d;
- },
- getBCHDigit : function(data) {
- var digit = 0;
- while (data != 0) {
- digit++;
- data >>>= 1;
- }
- return digit;
- },
- getPatternPosition : function(typeNumber) {
- return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
- },
- getMask : function(maskPattern, i, j) {
-
- switch (maskPattern) {
-
- case QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0;
- case QRMaskPattern.PATTERN001 : return i % 2 == 0;
- case QRMaskPattern.PATTERN010 : return j % 3 == 0;
- case QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0;
- case QRMaskPattern.PATTERN100 : return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0;
- case QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0;
- case QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0;
- case QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0;
- default :
- throw new Error("bad maskPattern:" + maskPattern);
- }
- },
- getErrorCorrectPolynomial : function(errorCorrectLength) {
- var a = new Polynomial([1], 0);
- for (var i = 0; i < errorCorrectLength; i++) {
- a = a.multiply(new Polynomial([1, math.gexp(i)], 0) );
- }
- return a;
- },
- getLengthInBits : function(mode, type) {
- if (1 <= type && type < 10) {
- // 1 - 9
- switch(mode) {
- case Mode.MODE_NUMBER : return 10;
- case Mode.MODE_ALPHA_NUM : return 9;
- case Mode.MODE_8BIT_BYTE : return 8;
- case Mode.MODE_KANJI : return 8;
- default :
- throw new Error("mode:" + mode);
- }
- } else if (type < 27) {
- // 10 - 26
- switch(mode) {
- case Mode.MODE_NUMBER : return 12;
- case Mode.MODE_ALPHA_NUM : return 11;
- case Mode.MODE_8BIT_BYTE : return 16;
- case Mode.MODE_KANJI : return 10;
- default :
- throw new Error("mode:" + mode);
- }
- } else if (type < 41) {
- // 27 - 40
- switch(mode) {
- case Mode.MODE_NUMBER : return 14;
- case Mode.MODE_ALPHA_NUM : return 13;
- case Mode.MODE_8BIT_BYTE : return 16;
- case Mode.MODE_KANJI : return 12;
- default :
- throw new Error("mode:" + mode);
- }
- } else {
- throw new Error("type:" + type);
- }
- },
- getLostPoint : function(qrCode) {
-
- var moduleCount = qrCode.getModuleCount();
-
- var lostPoint = 0;
-
- // LEVEL1
-
- for (var row = 0; row < moduleCount; row++) {
- for (var col = 0; col < moduleCount; col++) {
- var sameCount = 0;
- var dark = qrCode.isDark(row, col);
- for (var r = -1; r <= 1; r++) {
- if (row + r < 0 || moduleCount <= row + r) {
- continue;
- }
- for (var c = -1; c <= 1; c++) {
- if (col + c < 0 || moduleCount <= col + c) {
- continue;
- }
- if (r == 0 && c == 0) {
- continue;
- }
- if (dark == qrCode.isDark(row + r, col + c) ) {
- sameCount++;
- }
- }
- }
- if (sameCount > 5) {
- lostPoint += (3 + sameCount - 5);
- }
- }
- }
- // LEVEL2
- for (var row = 0; row < moduleCount - 1; row++) {
- for (var col = 0; col < moduleCount - 1; col++) {
- var count = 0;
- if (qrCode.isDark(row, col ) ) count++;
- if (qrCode.isDark(row + 1, col ) ) count++;
- if (qrCode.isDark(row, col + 1) ) count++;
- if (qrCode.isDark(row + 1, col + 1) ) count++;
- if (count == 0 || count == 4) {
- lostPoint += 3;
- }
- }
- }
- // LEVEL3
- for (var row = 0; row < moduleCount; row++) {
- for (var col = 0; col < moduleCount - 6; col++) {
- if (qrCode.isDark(row, col)
- && !qrCode.isDark(row, col + 1)
- && qrCode.isDark(row, col + 2)
- && qrCode.isDark(row, col + 3)
- && qrCode.isDark(row, col + 4)
- && !qrCode.isDark(row, col + 5)
- && qrCode.isDark(row, col + 6) ) {
- lostPoint += 40;
- }
- }
- }
- for (var col = 0; col < moduleCount; col++) {
- for (var row = 0; row < moduleCount - 6; row++) {
- if (qrCode.isDark(row, col)
- && !qrCode.isDark(row + 1, col)
- && qrCode.isDark(row + 2, col)
- && qrCode.isDark(row + 3, col)
- && qrCode.isDark(row + 4, col)
- && !qrCode.isDark(row + 5, col)
- && qrCode.isDark(row + 6, col) ) {
- lostPoint += 40;
- }
- }
- }
- // LEVEL4
-
- var darkCount = 0;
- for (var col = 0; col < moduleCount; col++) {
- for (var row = 0; row < moduleCount; row++) {
- if (qrCode.isDark(row, col) ) {
- darkCount++;
- }
- }
- }
-
- var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
- lostPoint += ratio * 10;
- return lostPoint;
- }
- };
- module.exports = QRUtil;
|