1var QRMode = require('./QRMode'); 2var QRPolynomial = require('./QRPolynomial'); 3var QRMath = require('./QRMath'); 4var QRMaskPattern = require('./QRMaskPattern'); 5 6var QRUtil = { 7 8 PATTERN_POSITION_TABLE : [ 9 [], 10 [6, 18], 11 [6, 22], 12 [6, 26], 13 [6, 30], 14 [6, 34], 15 [6, 22, 38], 16 [6, 24, 42], 17 [6, 26, 46], 18 [6, 28, 50], 19 [6, 30, 54], 20 [6, 32, 58], 21 [6, 34, 62], 22 [6, 26, 46, 66], 23 [6, 26, 48, 70], 24 [6, 26, 50, 74], 25 [6, 30, 54, 78], 26 [6, 30, 56, 82], 27 [6, 30, 58, 86], 28 [6, 34, 62, 90], 29 [6, 28, 50, 72, 94], 30 [6, 26, 50, 74, 98], 31 [6, 30, 54, 78, 102], 32 [6, 28, 54, 80, 106], 33 [6, 32, 58, 84, 110], 34 [6, 30, 58, 86, 114], 35 [6, 34, 62, 90, 118], 36 [6, 26, 50, 74, 98, 122], 37 [6, 30, 54, 78, 102, 126], 38 [6, 26, 52, 78, 104, 130], 39 [6, 30, 56, 82, 108, 134], 40 [6, 34, 60, 86, 112, 138], 41 [6, 30, 58, 86, 114, 142], 42 [6, 34, 62, 90, 118, 146], 43 [6, 30, 54, 78, 102, 126, 150], 44 [6, 24, 50, 76, 102, 128, 154], 45 [6, 28, 54, 80, 106, 132, 158], 46 [6, 32, 58, 84, 110, 136, 162], 47 [6, 26, 54, 82, 110, 138, 166], 48 [6, 30, 58, 86, 114, 142, 170] 49 ], 50 51 G15 : (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0), 52 G18 : (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0), 53 G15_MASK : (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1), 54 55 getBCHTypeInfo : function(data) { 56 var d = data << 10; 57 while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) { 58 d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) ); 59 } 60 return ( (data << 10) | d) ^ QRUtil.G15_MASK; 61 }, 62 63 getBCHTypeNumber : function(data) { 64 var d = data << 12; 65 while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) { 66 d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) ); 67 } 68 return (data << 12) | d; 69 }, 70 71 getBCHDigit : function(data) { 72 73 var digit = 0; 74 75 while (data !== 0) { 76 digit++; 77 data >>>= 1; 78 } 79 80 return digit; 81 }, 82 83 getPatternPosition : function(typeNumber) { 84 return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]; 85 }, 86 87 getMask : function(maskPattern, i, j) { 88 89 switch (maskPattern) { 90 91 case QRMaskPattern.PATTERN000 : return (i + j) % 2 === 0; 92 case QRMaskPattern.PATTERN001 : return i % 2 === 0; 93 case QRMaskPattern.PATTERN010 : return j % 3 === 0; 94 case QRMaskPattern.PATTERN011 : return (i + j) % 3 === 0; 95 case QRMaskPattern.PATTERN100 : return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 === 0; 96 case QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 === 0; 97 case QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 === 0; 98 case QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 === 0; 99 100 default : 101 throw new Error("bad maskPattern:" + maskPattern); 102 } 103 }, 104 105 getErrorCorrectPolynomial : function(errorCorrectLength) { 106 107 var a = new QRPolynomial([1], 0); 108 109 for (var i = 0; i < errorCorrectLength; i++) { 110 a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0) ); 111 } 112 113 return a; 114 }, 115 116 getLengthInBits : function(mode, type) { 117 118 if (1 <= type && type < 10) { 119 120 // 1 - 9 121 122 switch(mode) { 123 case QRMode.MODE_NUMBER : return 10; 124 case QRMode.MODE_ALPHA_NUM : return 9; 125 case QRMode.MODE_8BIT_BYTE : return 8; 126 case QRMode.MODE_KANJI : return 8; 127 default : 128 throw new Error("mode:" + mode); 129 } 130 131 } else if (type < 27) { 132 133 // 10 - 26 134 135 switch(mode) { 136 case QRMode.MODE_NUMBER : return 12; 137 case QRMode.MODE_ALPHA_NUM : return 11; 138 case QRMode.MODE_8BIT_BYTE : return 16; 139 case QRMode.MODE_KANJI : return 10; 140 default : 141 throw new Error("mode:" + mode); 142 } 143 144 } else if (type < 41) { 145 146 // 27 - 40 147 148 switch(mode) { 149 case QRMode.MODE_NUMBER : return 14; 150 case QRMode.MODE_ALPHA_NUM : return 13; 151 case QRMode.MODE_8BIT_BYTE : return 16; 152 case QRMode.MODE_KANJI : return 12; 153 default : 154 throw new Error("mode:" + mode); 155 } 156 157 } else { 158 throw new Error("type:" + type); 159 } 160 }, 161 162 getLostPoint : function(qrCode) { 163 164 var moduleCount = qrCode.getModuleCount(); 165 var lostPoint = 0; 166 var row = 0; 167 var col = 0; 168 169 170 // LEVEL1 171 172 for (row = 0; row < moduleCount; row++) { 173 174 for (col = 0; col < moduleCount; col++) { 175 176 var sameCount = 0; 177 var dark = qrCode.isDark(row, col); 178 179 for (var r = -1; r <= 1; r++) { 180 181 if (row + r < 0 || moduleCount <= row + r) { 182 continue; 183 } 184 185 for (var c = -1; c <= 1; c++) { 186 187 if (col + c < 0 || moduleCount <= col + c) { 188 continue; 189 } 190 191 if (r === 0 && c === 0) { 192 continue; 193 } 194 195 if (dark === qrCode.isDark(row + r, col + c) ) { 196 sameCount++; 197 } 198 } 199 } 200 201 if (sameCount > 5) { 202 lostPoint += (3 + sameCount - 5); 203 } 204 } 205 } 206 207 // LEVEL2 208 209 for (row = 0; row < moduleCount - 1; row++) { 210 for (col = 0; col < moduleCount - 1; col++) { 211 var count = 0; 212 if (qrCode.isDark(row, col ) ) count++; 213 if (qrCode.isDark(row + 1, col ) ) count++; 214 if (qrCode.isDark(row, col + 1) ) count++; 215 if (qrCode.isDark(row + 1, col + 1) ) count++; 216 if (count === 0 || count === 4) { 217 lostPoint += 3; 218 } 219 } 220 } 221 222 // LEVEL3 223 224 for (row = 0; row < moduleCount; row++) { 225 for (col = 0; col < moduleCount - 6; col++) { 226 if (qrCode.isDark(row, col) && 227 !qrCode.isDark(row, col + 1) && 228 qrCode.isDark(row, col + 2) && 229 qrCode.isDark(row, col + 3) && 230 qrCode.isDark(row, col + 4) && 231 !qrCode.isDark(row, col + 5) && 232 qrCode.isDark(row, col + 6) ) { 233 lostPoint += 40; 234 } 235 } 236 } 237 238 for (col = 0; col < moduleCount; col++) { 239 for (row = 0; row < moduleCount - 6; row++) { 240 if (qrCode.isDark(row, col) && 241 !qrCode.isDark(row + 1, col) && 242 qrCode.isDark(row + 2, col) && 243 qrCode.isDark(row + 3, col) && 244 qrCode.isDark(row + 4, col) && 245 !qrCode.isDark(row + 5, col) && 246 qrCode.isDark(row + 6, col) ) { 247 lostPoint += 40; 248 } 249 } 250 } 251 252 // LEVEL4 253 254 var darkCount = 0; 255 256 for (col = 0; col < moduleCount; col++) { 257 for (row = 0; row < moduleCount; row++) { 258 if (qrCode.isDark(row, col) ) { 259 darkCount++; 260 } 261 } 262 } 263 264 var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; 265 lostPoint += ratio * 10; 266 267 return lostPoint; 268 } 269 270}; 271 272module.exports = QRUtil; 273