1//--------------------------------------------------------------------- 2// QRCode for JavaScript 3// 4// Copyright (c) 2009 Kazuhiko Arase 5// 6// URL: http://www.d-project.com/ 7// 8// Licensed under the MIT license: 9// http://www.opensource.org/licenses/mit-license.php 10// 11// The word "QR Code" is registered trademark of 12// DENSO WAVE INCORPORATED 13// http://www.denso-wave.com/qrcode/faqpatent-e.html 14// 15//--------------------------------------------------------------------- 16 17//--------------------------------------------------------------------- 18// QR8bitByte 19//--------------------------------------------------------------------- 20 21function QR8bitByte(data) { 22 this.mode = QRMode.MODE_8BIT_BYTE; 23 this.data = data; 24} 25 26QR8bitByte.prototype = { 27 28 getLength : function(buffer) { 29 return this.data.length; 30 }, 31 32 write : function(buffer) { 33 for (var i = 0; i < this.data.length; i++) { 34 // not JIS ... 35 buffer.put(this.data.charCodeAt(i), 8); 36 } 37 } 38}; 39 40//--------------------------------------------------------------------- 41// QRCode 42//--------------------------------------------------------------------- 43 44function QRCode(typeNumber, errorCorrectLevel) { 45 this.typeNumber = typeNumber; 46 this.errorCorrectLevel = errorCorrectLevel; 47 this.modules = null; 48 this.moduleCount = 0; 49 this.dataCache = null; 50 this.dataList = new Array(); 51} 52 53QRCode.prototype = { 54 55 addData : function(data) { 56 var newData = new QR8bitByte(data); 57 this.dataList.push(newData); 58 this.dataCache = null; 59 }, 60 61 isDark : function(row, col) { 62 if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) { 63 throw new Error(row + "," + col); 64 } 65 return this.modules[row][col]; 66 }, 67 68 getModuleCount : function() { 69 return this.moduleCount; 70 }, 71 72 make : function() { 73 // Calculate automatically typeNumber if provided is < 1 74 if (this.typeNumber < 1 ){ 75 var typeNumber = 1; 76 for (typeNumber = 1; typeNumber < 40; typeNumber++) { 77 var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel); 78 79 var buffer = new QRBitBuffer(); 80 var totalDataCount = 0; 81 for (var i = 0; i < rsBlocks.length; i++) { 82 totalDataCount += rsBlocks[i].dataCount; 83 } 84 85 for (var i = 0; i < this.dataList.length; i++) { 86 var data = this.dataList[i]; 87 buffer.put(data.mode, 4); 88 buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber) ); 89 data.write(buffer); 90 } 91 if (buffer.getLengthInBits() <= totalDataCount * 8) 92 break; 93 } 94 this.typeNumber = typeNumber; 95 } 96 this.makeImpl(false, this.getBestMaskPattern() ); 97 }, 98 99 makeImpl : function(test, maskPattern) { 100 101 this.moduleCount = this.typeNumber * 4 + 17; 102 this.modules = new Array(this.moduleCount); 103 104 for (var row = 0; row < this.moduleCount; row++) { 105 106 this.modules[row] = new Array(this.moduleCount); 107 108 for (var col = 0; col < this.moduleCount; col++) { 109 this.modules[row][col] = null;//(col + row) % 3; 110 } 111 } 112 113 this.setupPositionProbePattern(0, 0); 114 this.setupPositionProbePattern(this.moduleCount - 7, 0); 115 this.setupPositionProbePattern(0, this.moduleCount - 7); 116 this.setupPositionAdjustPattern(); 117 this.setupTimingPattern(); 118 this.setupTypeInfo(test, maskPattern); 119 120 if (this.typeNumber >= 7) { 121 this.setupTypeNumber(test); 122 } 123 124 if (this.dataCache == null) { 125 this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList); 126 } 127 128 this.mapData(this.dataCache, maskPattern); 129 }, 130 131 setupPositionProbePattern : function(row, col) { 132 133 for (var r = -1; r <= 7; r++) { 134 135 if (row + r <= -1 || this.moduleCount <= row + r) continue; 136 137 for (var c = -1; c <= 7; c++) { 138 139 if (col + c <= -1 || this.moduleCount <= col + c) continue; 140 141 if ( (0 <= r && r <= 6 && (c == 0 || c == 6) ) 142 || (0 <= c && c <= 6 && (r == 0 || r == 6) ) 143 || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) { 144 this.modules[row + r][col + c] = true; 145 } else { 146 this.modules[row + r][col + c] = false; 147 } 148 } 149 } 150 }, 151 152 getBestMaskPattern : function() { 153 154 var minLostPoint = 0; 155 var pattern = 0; 156 157 for (var i = 0; i < 8; i++) { 158 159 this.makeImpl(true, i); 160 161 var lostPoint = QRUtil.getLostPoint(this); 162 163 if (i == 0 || minLostPoint > lostPoint) { 164 minLostPoint = lostPoint; 165 pattern = i; 166 } 167 } 168 169 return pattern; 170 }, 171 172 createMovieClip : function(target_mc, instance_name, depth) { 173 174 var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth); 175 var cs = 1; 176 177 this.make(); 178 179 for (var row = 0; row < this.modules.length; row++) { 180 181 var y = row * cs; 182 183 for (var col = 0; col < this.modules[row].length; col++) { 184 185 var x = col * cs; 186 var dark = this.modules[row][col]; 187 188 if (dark) { 189 qr_mc.beginFill(0, 100); 190 qr_mc.moveTo(x, y); 191 qr_mc.lineTo(x + cs, y); 192 qr_mc.lineTo(x + cs, y + cs); 193 qr_mc.lineTo(x, y + cs); 194 qr_mc.endFill(); 195 } 196 } 197 } 198 199 return qr_mc; 200 }, 201 202 setupTimingPattern : function() { 203 204 for (var r = 8; r < this.moduleCount - 8; r++) { 205 if (this.modules[r][6] != null) { 206 continue; 207 } 208 this.modules[r][6] = (r % 2 == 0); 209 } 210 211 for (var c = 8; c < this.moduleCount - 8; c++) { 212 if (this.modules[6][c] != null) { 213 continue; 214 } 215 this.modules[6][c] = (c % 2 == 0); 216 } 217 }, 218 219 setupPositionAdjustPattern : function() { 220 221 var pos = QRUtil.getPatternPosition(this.typeNumber); 222 223 for (var i = 0; i < pos.length; i++) { 224 225 for (var j = 0; j < pos.length; j++) { 226 227 var row = pos[i]; 228 var col = pos[j]; 229 230 if (this.modules[row][col] != null) { 231 continue; 232 } 233 234 for (var r = -2; r <= 2; r++) { 235 236 for (var c = -2; c <= 2; c++) { 237 238 if (r == -2 || r == 2 || c == -2 || c == 2 239 || (r == 0 && c == 0) ) { 240 this.modules[row + r][col + c] = true; 241 } else { 242 this.modules[row + r][col + c] = false;
vendor: 17,852 bytes, lines 243-1074
243 } 244 } 245 } 246 } 247 } 248 }, 249 250 setupTypeNumber : function(test) { 251 252 var bits = QRUtil.getBCHTypeNumber(this.typeNumber); 253 254 for (var i = 0; i < 18; i++) { 255 var mod = (!test && ( (bits >> i) & 1) == 1); 256 this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod; 257 } 258 259 for (var i = 0; i < 18; i++) { 260 var mod = (!test && ( (bits >> i) & 1) == 1); 261 this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod; 262 } 263 }, 264 265 setupTypeInfo : function(test, maskPattern) { 266 267 var data = (this.errorCorrectLevel << 3) | maskPattern; 268 var bits = QRUtil.getBCHTypeInfo(data); 269 270 // vertical 271 for (var i = 0; i < 15; i++) { 272 273 var mod = (!test && ( (bits >> i) & 1) == 1); 274 275 if (i < 6) { 276 this.modules[i][8] = mod; 277 } else if (i < 8) { 278 this.modules[i + 1][8] = mod; 279 } else { 280 this.modules[this.moduleCount - 15 + i][8] = mod; 281 } 282 } 283 284 // horizontal 285 for (var i = 0; i < 15; i++) { 286 287 var mod = (!test && ( (bits >> i) & 1) == 1); 288 289 if (i < 8) { 290 this.modules[8][this.moduleCount - i - 1] = mod; 291 } else if (i < 9) { 292 this.modules[8][15 - i - 1 + 1] = mod; 293 } else { 294 this.modules[8][15 - i - 1] = mod; 295 } 296 } 297 298 // fixed module 299 this.modules[this.moduleCount - 8][8] = (!test); 300 301 }, 302 303 mapData : function(data, maskPattern) { 304 305 var inc = -1; 306 var row = this.moduleCount - 1; 307 var bitIndex = 7; 308 var byteIndex = 0; 309 310 for (var col = this.moduleCount - 1; col > 0; col -= 2) { 311 312 if (col == 6) col--; 313 314 while (true) { 315 316 for (var c = 0; c < 2; c++) { 317 318 if (this.modules[row][col - c] == null) { 319 320 var dark = false; 321 322 if (byteIndex < data.length) { 323 dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1); 324 } 325 326 var mask = QRUtil.getMask(maskPattern, row, col - c); 327 328 if (mask) { 329 dark = !dark; 330 } 331 332 this.modules[row][col - c] = dark; 333 bitIndex--; 334 335 if (bitIndex == -1) { 336 byteIndex++; 337 bitIndex = 7; 338 } 339 } 340 } 341 342 row += inc; 343 344 if (row < 0 || this.moduleCount <= row) { 345 row -= inc; 346 inc = -inc; 347 break; 348 } 349 } 350 } 351 352 } 353 354}; 355 356QRCode.PAD0 = 0xEC; 357QRCode.PAD1 = 0x11; 358 359QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) { 360 361 var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel); 362 363 var buffer = new QRBitBuffer(); 364 365 for (var i = 0; i < dataList.length; i++) { 366 var data = dataList[i]; 367 buffer.put(data.mode, 4); 368 buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber) ); 369 data.write(buffer); 370 } 371 372 // calc num max data. 373 var totalDataCount = 0; 374 for (var i = 0; i < rsBlocks.length; i++) { 375 totalDataCount += rsBlocks[i].dataCount; 376 } 377 378 if (buffer.getLengthInBits() > totalDataCount * 8) { 379 throw new Error("code length overflow. (" 380 + buffer.getLengthInBits() 381 + ">" 382 + totalDataCount * 8 383 + ")"); 384 } 385 386 // end code 387 if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { 388 buffer.put(0, 4); 389 } 390 391 // padding 392 while (buffer.getLengthInBits() % 8 != 0) { 393 buffer.putBit(false); 394 } 395 396 // padding 397 while (true) { 398 399 if (buffer.getLengthInBits() >= totalDataCount * 8) { 400 break; 401 } 402 buffer.put(QRCode.PAD0, 8); 403 404 if (buffer.getLengthInBits() >= totalDataCount * 8) { 405 break; 406 } 407 buffer.put(QRCode.PAD1, 8); 408 } 409 410 return QRCode.createBytes(buffer, rsBlocks); 411} 412 413QRCode.createBytes = function(buffer, rsBlocks) { 414 415 var offset = 0; 416 417 var maxDcCount = 0; 418 var maxEcCount = 0; 419 420 var dcdata = new Array(rsBlocks.length); 421 var ecdata = new Array(rsBlocks.length); 422 423 for (var r = 0; r < rsBlocks.length; r++) { 424 425 var dcCount = rsBlocks[r].dataCount; 426 var ecCount = rsBlocks[r].totalCount - dcCount; 427 428 maxDcCount = Math.max(maxDcCount, dcCount); 429 maxEcCount = Math.max(maxEcCount, ecCount); 430 431 dcdata[r] = new Array(dcCount); 432 433 for (var i = 0; i < dcdata[r].length; i++) { 434 dcdata[r][i] = 0xff & buffer.buffer[i + offset]; 435 } 436 offset += dcCount; 437 438 var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); 439 var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1); 440 441 var modPoly = rawPoly.mod(rsPoly); 442 ecdata[r] = new Array(rsPoly.getLength() - 1); 443 for (var i = 0; i < ecdata[r].length; i++) { 444 var modIndex = i + modPoly.getLength() - ecdata[r].length; 445 ecdata[r][i] = (modIndex >= 0)? modPoly.get(modIndex) : 0; 446 } 447 448 } 449 450 var totalCodeCount = 0; 451 for (var i = 0; i < rsBlocks.length; i++) { 452 totalCodeCount += rsBlocks[i].totalCount; 453 } 454 455 var data = new Array(totalCodeCount); 456 var index = 0; 457 458 for (var i = 0; i < maxDcCount; i++) { 459 for (var r = 0; r < rsBlocks.length; r++) { 460 if (i < dcdata[r].length) { 461 data[index++] = dcdata[r][i]; 462 } 463 } 464 } 465 466 for (var i = 0; i < maxEcCount; i++) { 467 for (var r = 0; r < rsBlocks.length; r++) { 468 if (i < ecdata[r].length) { 469 data[index++] = ecdata[r][i]; 470 } 471 } 472 } 473 474 return data; 475 476} 477 478//--------------------------------------------------------------------- 479// QRMode 480//--------------------------------------------------------------------- 481 482var QRMode = { 483 MODE_NUMBER : 1 << 0, 484 MODE_ALPHA_NUM : 1 << 1, 485 MODE_8BIT_BYTE : 1 << 2, 486 MODE_KANJI : 1 << 3 487}; 488 489//--------------------------------------------------------------------- 490// QRErrorCorrectLevel 491//--------------------------------------------------------------------- 492 493var QRErrorCorrectLevel = { 494 L : 1, 495 M : 0, 496 Q : 3, 497 H : 2 498}; 499 500//--------------------------------------------------------------------- 501// QRMaskPattern 502//--------------------------------------------------------------------- 503 504var QRMaskPattern = { 505 PATTERN000 : 0, 506 PATTERN001 : 1, 507 PATTERN010 : 2, 508 PATTERN011 : 3, 509 PATTERN100 : 4, 510 PATTERN101 : 5, 511 PATTERN110 : 6, 512 PATTERN111 : 7 513}; 514 515//--------------------------------------------------------------------- 516// QRUtil 517//--------------------------------------------------------------------- 518 519var QRUtil = { 520 521 PATTERN_POSITION_TABLE : [ 522 [], 523 [6, 18], 524 [6, 22], 525 [6, 26], 526 [6, 30], 527 [6, 34], 528 [6, 22, 38], 529 [6, 24, 42], 530 [6, 26, 46], 531 [6, 28, 50], 532 [6, 30, 54], 533 [6, 32, 58], 534 [6, 34, 62], 535 [6, 26, 46, 66], 536 [6, 26, 48, 70], 537 [6, 26, 50, 74], 538 [6, 30, 54, 78], 539 [6, 30, 56, 82], 540 [6, 30, 58, 86], 541 [6, 34, 62, 90], 542 [6, 28, 50, 72, 94], 543 [6, 26, 50, 74, 98], 544 [6, 30, 54, 78, 102], 545 [6, 28, 54, 80, 106], 546 [6, 32, 58, 84, 110], 547 [6, 30, 58, 86, 114], 548 [6, 34, 62, 90, 118], 549 [6, 26, 50, 74, 98, 122], 550 [6, 30, 54, 78, 102, 126], 551 [6, 26, 52, 78, 104, 130], 552 [6, 30, 56, 82, 108, 134], 553 [6, 34, 60, 86, 112, 138], 554 [6, 30, 58, 86, 114, 142], 555 [6, 34, 62, 90, 118, 146], 556 [6, 30, 54, 78, 102, 126, 150], 557 [6, 24, 50, 76, 102, 128, 154], 558 [6, 28, 54, 80, 106, 132, 158], 559 [6, 32, 58, 84, 110, 136, 162], 560 [6, 26, 54, 82, 110, 138, 166], 561 [6, 30, 58, 86, 114, 142, 170] 562 ], 563 564 G15 : (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0), 565 G18 : (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0), 566 G15_MASK : (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1), 567 568 getBCHTypeInfo : function(data) { 569 var d = data << 10; 570 while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) { 571 d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) ); 572 } 573 return ( (data << 10) | d) ^ QRUtil.G15_MASK; 574 }, 575 576 getBCHTypeNumber : function(data) { 577 var d = data << 12; 578 while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) { 579 d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) ); 580 } 581 return (data << 12) | d; 582 }, 583 584 getBCHDigit : function(data) { 585 586 var digit = 0; 587 588 while (data != 0) { 589 digit++; 590 data >>>= 1; 591 } 592 593 return digit; 594 }, 595 596 getPatternPosition : function(typeNumber) { 597 return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]; 598 }, 599 600 getMask : function(maskPattern, i, j) { 601 602 switch (maskPattern) { 603 604 case QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0; 605 case QRMaskPattern.PATTERN001 : return i % 2 == 0; 606 case QRMaskPattern.PATTERN010 : return j % 3 == 0; 607 case QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0; 608 case QRMaskPattern.PATTERN100 : return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; 609 case QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0; 610 case QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; 611 case QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; 612 613 default : 614 throw new Error("bad maskPattern:" + maskPattern); 615 } 616 }, 617 618 getErrorCorrectPolynomial : function(errorCorrectLength) { 619 620 var a = new QRPolynomial([1], 0); 621 622 for (var i = 0; i < errorCorrectLength; i++) { 623 a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0) ); 624 } 625 626 return a; 627 }, 628 629 getLengthInBits : function(mode, type) { 630 631 if (1 <= type && type < 10) { 632 633 // 1 - 9 634 635 switch(mode) { 636 case QRMode.MODE_NUMBER : return 10; 637 case QRMode.MODE_ALPHA_NUM : return 9; 638 case QRMode.MODE_8BIT_BYTE : return 8; 639 case QRMode.MODE_KANJI : return 8; 640 default : 641 throw new Error("mode:" + mode); 642 } 643 644 } else if (type < 27) { 645 646 // 10 - 26 647 648 switch(mode) { 649 case QRMode.MODE_NUMBER : return 12; 650 case QRMode.MODE_ALPHA_NUM : return 11; 651 case QRMode.MODE_8BIT_BYTE : return 16; 652 case QRMode.MODE_KANJI : return 10; 653 default : 654 throw new Error("mode:" + mode); 655 } 656 657 } else if (type < 41) { 658 659 // 27 - 40 660 661 switch(mode) { 662 case QRMode.MODE_NUMBER : return 14; 663 case QRMode.MODE_ALPHA_NUM : return 13; 664 case QRMode.MODE_8BIT_BYTE : return 16; 665 case QRMode.MODE_KANJI : return 12; 666 default : 667 throw new Error("mode:" + mode); 668 } 669 670 } else { 671 throw new Error("type:" + type); 672 } 673 }, 674 675 getLostPoint : function(qrCode) { 676 677 var moduleCount = qrCode.getModuleCount(); 678 679 var lostPoint = 0; 680 681 // LEVEL1 682 683 for (var row = 0; row < moduleCount; row++) { 684 685 for (var col = 0; col < moduleCount; col++) { 686 687 var sameCount = 0; 688 var dark = qrCode.isDark(row, col); 689 690 for (var r = -1; r <= 1; r++) { 691 692 if (row + r < 0 || moduleCount <= row + r) { 693 continue; 694 } 695 696 for (var c = -1; c <= 1; c++) { 697 698 if (col + c < 0 || moduleCount <= col + c) { 699 continue; 700 } 701 702 if (r == 0 && c == 0) { 703 continue; 704 } 705 706 if (dark == qrCode.isDark(row + r, col + c) ) { 707 sameCount++; 708 } 709 } 710 } 711 712 if (sameCount > 5) { 713 lostPoint += (3 + sameCount - 5); 714 } 715 } 716 } 717 718 // LEVEL2 719 720 for (var row = 0; row < moduleCount - 1; row++) { 721 for (var col = 0; col < moduleCount - 1; col++) { 722 var count = 0; 723 if (qrCode.isDark(row, col ) ) count++; 724 if (qrCode.isDark(row + 1, col ) ) count++; 725 if (qrCode.isDark(row, col + 1) ) count++; 726 if (qrCode.isDark(row + 1, col + 1) ) count++; 727 if (count == 0 || count == 4) { 728 lostPoint += 3; 729 } 730 } 731 } 732 733 // LEVEL3 734 735 for (var row = 0; row < moduleCount; row++) { 736 for (var col = 0; col < moduleCount - 6; col++) { 737 if (qrCode.isDark(row, col) 738 && !qrCode.isDark(row, col + 1) 739 && qrCode.isDark(row, col + 2) 740 && qrCode.isDark(row, col + 3) 741 && qrCode.isDark(row, col + 4) 742 && !qrCode.isDark(row, col + 5) 743 && qrCode.isDark(row, col + 6) ) { 744 lostPoint += 40; 745 } 746 } 747 } 748 749 for (var col = 0; col < moduleCount; col++) { 750 for (var row = 0; row < moduleCount - 6; row++) { 751 if (qrCode.isDark(row, col) 752 && !qrCode.isDark(row + 1, col) 753 && qrCode.isDark(row + 2, col) 754 && qrCode.isDark(row + 3, col) 755 && qrCode.isDark(row + 4, col) 756 && !qrCode.isDark(row + 5, col) 757 && qrCode.isDark(row + 6, col) ) { 758 lostPoint += 40; 759 } 760 } 761 } 762 763 // LEVEL4 764 765 var darkCount = 0; 766 767 for (var col = 0; col < moduleCount; col++) { 768 for (var row = 0; row < moduleCount; row++) { 769 if (qrCode.isDark(row, col) ) { 770 darkCount++; 771 } 772 } 773 } 774 775 var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; 776 lostPoint += ratio * 10; 777 778 return lostPoint; 779 } 780 781}; 782 783 784//--------------------------------------------------------------------- 785// QRMath 786//--------------------------------------------------------------------- 787 788var QRMath = { 789 790 glog : function(n) { 791 792 if (n < 1) { 793 throw new Error("glog(" + n + ")"); 794 } 795 796 return QRMath.LOG_TABLE[n]; 797 }, 798 799 gexp : function(n) { 800 801 while (n < 0) { 802 n += 255; 803 } 804 805 while (n >= 256) { 806 n -= 255; 807 } 808 809 return QRMath.EXP_TABLE[n]; 810 }, 811 812 EXP_TABLE : new Array(256), 813 814 LOG_TABLE : new Array(256) 815 816}; 817 818for (var i = 0; i < 8; i++) { 819 QRMath.EXP_TABLE[i] = 1 << i; 820} 821for (var i = 8; i < 256; i++) { 822 QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] 823 ^ QRMath.EXP_TABLE[i - 5] 824 ^ QRMath.EXP_TABLE[i - 6] 825 ^ QRMath.EXP_TABLE[i - 8]; 826} 827for (var i = 0; i < 255; i++) { 828 QRMath.LOG_TABLE[QRMath.EXP_TABLE[i] ] = i; 829} 830 831//--------------------------------------------------------------------- 832// QRPolynomial 833//--------------------------------------------------------------------- 834 835function QRPolynomial(num, shift) { 836 837 if (num.length == undefined) { 838 throw new Error(num.length + "/" + shift); 839 } 840 841 var offset = 0; 842 843 while (offset < num.length && num[offset] == 0) { 844 offset++; 845 } 846 847 this.num = new Array(num.length - offset + shift); 848 for (var i = 0; i < num.length - offset; i++) { 849 this.num[i] = num[i + offset]; 850 } 851} 852 853QRPolynomial.prototype = { 854 855 get : function(index) { 856 return this.num[index]; 857 }, 858 859 getLength : function() { 860 return this.num.length; 861 }, 862 863 multiply : function(e) { 864 865 var num = new Array(this.getLength() + e.getLength() - 1); 866 867 for (var i = 0; i < this.getLength(); i++) { 868 for (var j = 0; j < e.getLength(); j++) { 869 num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i) ) + QRMath.glog(e.get(j) ) ); 870 } 871 } 872 873 return new QRPolynomial(num, 0); 874 }, 875 876 mod : function(e) { 877 878 if (this.getLength() - e.getLength() < 0) { 879 return this; 880 } 881 882 var ratio = QRMath.glog(this.get(0) ) - QRMath.glog(e.get(0) ); 883 884 var num = new Array(this.getLength() ); 885 886 for (var i = 0; i < this.getLength(); i++) { 887 num[i] = this.get(i); 888 } 889 890 for (var i = 0; i < e.getLength(); i++) { 891 num[i] ^= QRMath.gexp(QRMath.glog(e.get(i) ) + ratio); 892 } 893 894 // recursive call 895 return new QRPolynomial(num, 0).mod(e); 896 } 897}; 898 899//--------------------------------------------------------------------- 900// QRRSBlock 901//--------------------------------------------------------------------- 902 903function QRRSBlock(totalCount, dataCount) { 904 this.totalCount = totalCount; 905 this.dataCount = dataCount; 906} 907 908QRRSBlock.RS_BLOCK_TABLE = [ 909 910 // L 911 // M 912 // Q 913 // H 914 915 // 1 916 [1, 26, 19], 917 [1, 26, 16], 918 [1, 26, 13], 919 [1, 26, 9], 920 921 // 2 922 [1, 44, 34], 923 [1, 44, 28], 924 [1, 44, 22], 925 [1, 44, 16], 926 927 // 3 928 [1, 70, 55], 929 [1, 70, 44], 930 [2, 35, 17], 931 [2, 35, 13], 932 933 // 4 934 [1, 100, 80], 935 [2, 50, 32], 936 [2, 50, 24], 937 [4, 25, 9], 938 939 // 5 940 [1, 134, 108], 941 [2, 67, 43], 942 [2, 33, 15, 2, 34, 16], 943 [2, 33, 11, 2, 34, 12], 944 945 // 6 946 [2, 86, 68], 947 [4, 43, 27], 948 [4, 43, 19], 949 [4, 43, 15], 950 951 // 7 952 [2, 98, 78], 953 [4, 49, 31], 954 [2, 32, 14, 4, 33, 15], 955 [4, 39, 13, 1, 40, 14], 956 957 // 8 958 [2, 121, 97], 959 [2, 60, 38, 2, 61, 39], 960 [4, 40, 18, 2, 41, 19], 961 [4, 40, 14, 2, 41, 15], 962 963 // 9 964 [2, 146, 116], 965 [3, 58, 36, 2, 59, 37], 966 [4, 36, 16, 4, 37, 17], 967 [4, 36, 12, 4, 37, 13], 968 969 // 10 970 [2, 86, 68, 2, 87, 69], 971 [4, 69, 43, 1, 70, 44], 972 [6, 43, 19, 2, 44, 20], 973 [6, 43, 15, 2, 44, 16], 974 975 // 11 976 [4, 101, 81], 977 [1, 80, 50, 4, 81, 51], 978 [4, 50, 22, 4, 51, 23], 979 [3, 36, 12, 8, 37, 13], 980 981 // 12 982 [2, 116, 92, 2, 117, 93], 983 [6, 58, 36, 2, 59, 37], 984 [4, 46, 20, 6, 47, 21], 985 [7, 42, 14, 4, 43, 15], 986 987 // 13 988 [4, 133, 107], 989 [8, 59, 37, 1, 60, 38], 990 [8, 44, 20, 4, 45, 21], 991 [12, 33, 11, 4, 34, 12], 992 993 // 14 994 [3, 145, 115, 1, 146, 116], 995 [4, 64, 40, 5, 65, 41], 996 [11, 36, 16, 5, 37, 17], 997 [11, 36, 12, 5, 37, 13], 998 999 // 15 1000 [5, 109, 87, 1, 110, 88], 1001 [5, 65, 41, 5, 66, 42], 1002 [5, 54, 24, 7, 55, 25], 1003 [11, 36, 12], 1004 1005 // 16 1006 [5, 122, 98, 1, 123, 99], 1007 [7, 73, 45, 3, 74, 46], 1008 [15, 43, 19, 2, 44, 20], 1009 [3, 45, 15, 13, 46, 16], 1010 1011 // 17 1012 [1, 135, 107, 5, 136, 108], 1013 [10, 74, 46, 1, 75, 47], 1014 [1, 50, 22, 15, 51, 23], 1015 [2, 42, 14, 17, 43, 15], 1016 1017 // 18 1018 [5, 150, 120, 1, 151, 121], 1019 [9, 69, 43, 4, 70, 44], 1020 [17, 50, 22, 1, 51, 23], 1021 [2, 42, 14, 19, 43, 15], 1022 1023 // 19 1024 [3, 141, 113, 4, 142, 114], 1025 [3, 70, 44, 11, 71, 45], 1026 [17, 47, 21, 4, 48, 22], 1027 [9, 39, 13, 16, 40, 14], 1028 1029 // 20 1030 [3, 135, 107, 5, 136, 108], 1031 [3, 67, 41, 13, 68, 42], 1032 [15, 54, 24, 5, 55, 25], 1033 [15, 43, 15, 10, 44, 16], 1034 1035 // 21 1036 [4, 144, 116, 4, 145, 117], 1037 [17, 68, 42], 1038 [17, 50, 22, 6, 51, 23], 1039 [19, 46, 16, 6, 47, 17], 1040 1041 // 22 1042 [2, 139, 111, 7, 140, 112], 1043 [17, 74, 46], 1044 [7, 54, 24, 16, 55, 25], 1045 [34, 37, 13], 1046 1047 // 23 1048 [4, 151, 121, 5, 152, 122], 1049 [4, 75, 47, 14, 76, 48], 1050 [11, 54, 24, 14, 55, 25], 1051 [16, 45, 15, 14, 46, 16], 1052 1053 // 24 1054 [6, 147, 117, 4, 148, 118], 1055 [6, 73, 45, 14, 74, 46], 1056 [11, 54, 24, 16, 55, 25], 1057 [30, 46, 16, 2, 47, 17], 1058 1059 // 25 1060 [8, 132, 106, 4, 133, 107], 1061 [8, 75, 47, 13, 76, 48], 1062 [7, 54, 24, 22, 55, 25], 1063 [22, 45, 15, 13, 46, 16], 1064 1065 // 26 1066 [10, 142, 114, 2, 143, 115], 1067 [19, 74, 46, 4, 75, 47], 1068 [28, 50, 22, 6, 51, 23], 1069 [33, 46, 16, 4, 47, 17], 1070 1071 // 27 1072 [8, 152, 122, 4, 153, 123], 1073 [22, 73, 45, 3, 74, 46], 1074 [8, 53, 23, 26, 54, 24],
1075 [12, 45, 15, 28, 46, 16], 1076 1077 // 28 1078 [3, 147, 117, 10, 148, 118], 1079 [3, 73, 45, 23, 74, 46], 1080 [4, 54, 24, 31, 55, 25], 1081 [11, 45, 15, 31, 46, 16], 1082 1083 // 29 1084 [7, 146, 116, 7, 147, 117], 1085 [21, 73, 45, 7, 74, 46], 1086 [1, 53, 23, 37, 54, 24], 1087 [19, 45, 15, 26, 46, 16], 1088 1089 // 30 1090 [5, 145, 115, 10, 146, 116], 1091 [19, 75, 47, 10, 76, 48], 1092 [15, 54, 24, 25, 55, 25], 1093 [23, 45, 15, 25, 46, 16], 1094 1095 // 31 1096 [13, 145, 115, 3, 146, 116], 1097 [2, 74, 46, 29, 75, 47], 1098 [42, 54, 24, 1, 55, 25], 1099 [23, 45, 15, 28, 46, 16], 1100 1101 // 32 1102 [17, 145, 115], 1103 [10, 74, 46, 23, 75, 47], 1104 [10, 54, 24, 35, 55, 25], 1105 [19, 45, 15, 35, 46, 16], 1106 1107 // 33 1108 [17, 145, 115, 1, 146, 116], 1109 [14, 74, 46, 21, 75, 47], 1110 [29, 54, 24, 19, 55, 25], 1111 [11, 45, 15, 46, 46, 16], 1112 1113 // 34 1114 [13, 145, 115, 6, 146, 116], 1115 [14, 74, 46, 23, 75, 47], 1116 [44, 54, 24, 7, 55, 25], 1117 [59, 46, 16, 1, 47, 17], 1118 1119 // 35 1120 [12, 151, 121, 7, 152, 122], 1121 [12, 75, 47, 26, 76, 48], 1122 [39, 54, 24, 14, 55, 25], 1123 [22, 45, 15, 41, 46, 16], 1124 1125 // 36 1126 [6, 151, 121, 14, 152, 122], 1127 [6, 75, 47, 34, 76, 48], 1128 [46, 54, 24, 10, 55, 25], 1129 [2, 45, 15, 64, 46, 16], 1130 1131 // 37 1132 [17, 152, 122, 4, 153, 123], 1133 [29, 74, 46, 14, 75, 47], 1134 [49, 54, 24, 10, 55, 25], 1135 [24, 45, 15, 46, 46, 16], 1136 1137 // 38 1138 [4, 152, 122, 18, 153, 123], 1139 [13, 74, 46, 32, 75, 47], 1140 [48, 54, 24, 14, 55, 25], 1141 [42, 45, 15, 32, 46, 16], 1142 1143 // 39 1144 [20, 147, 117, 4, 148, 118], 1145 [40, 75, 47, 7, 76, 48], 1146 [43, 54, 24, 22, 55, 25], 1147 [10, 45, 15, 67, 46, 16], 1148 1149 // 40 1150 [19, 148, 118, 6, 149, 119], 1151 [18, 75, 47, 31, 76, 48], 1152 [34, 54, 24, 34, 55, 25], 1153 [20, 45, 15, 61, 46, 16] 1154]; 1155 1156QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) { 1157 1158 var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel); 1159 1160 if (rsBlock == undefined) { 1161 throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel); 1162 } 1163 1164 var length = rsBlock.length / 3; 1165 1166 var list = new Array(); 1167 1168 for (var i = 0; i < length; i++) { 1169 1170 var count = rsBlock[i * 3 + 0]; 1171 var totalCount = rsBlock[i * 3 + 1]; 1172 var dataCount = rsBlock[i * 3 + 2]; 1173 1174 for (var j = 0; j < count; j++) { 1175 list.push(new QRRSBlock(totalCount, dataCount) ); 1176 } 1177 } 1178 1179 return list; 1180} 1181 1182QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) { 1183 1184 switch(errorCorrectLevel) { 1185 case QRErrorCorrectLevel.L : 1186 return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; 1187 case QRErrorCorrectLevel.M : 1188 return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; 1189 case QRErrorCorrectLevel.Q : 1190 return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; 1191 case QRErrorCorrectLevel.H : 1192 return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; 1193 default : 1194 return undefined; 1195 } 1196} 1197 1198//--------------------------------------------------------------------- 1199// QRBitBuffer 1200//--------------------------------------------------------------------- 1201 1202function QRBitBuffer() { 1203 this.buffer = new Array(); 1204 this.length = 0; 1205} 1206 1207QRBitBuffer.prototype = { 1208 1209 get : function(index) { 1210 var bufIndex = Math.floor(index / 8); 1211 return ( (this.buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1; 1212 }, 1213 1214 put : function(num, length) { 1215 for (var i = 0; i < length; i++) { 1216 this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1); 1217 } 1218 }, 1219 1220 getLengthInBits : function() { 1221 return this.length; 1222 }, 1223 1224 putBit : function(bit) { 1225 1226 var bufIndex = Math.floor(this.length / 8); 1227 if (this.buffer.length <= bufIndex) { 1228 this.buffer.push(0); 1229 } 1230 1231 if (bit) { 1232 this.buffer[bufIndex] |= (0x80 >>> (this.length % 8) ); 1233 } 1234 1235 this.length++; 1236 } 1237};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.