[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 //--------------------------------------------------------------------- 2 // 3 // QR Code Generator for JavaScript 4 // 5 // Copyright (c) 2009 Kazuhiko Arase 6 // 7 // URL: http://www.d-project.com/ 8 // 9 // Licensed under the MIT license: 10 // http://www.opensource.org/licenses/mit-license.php 11 // 12 // The word 'QR Code' is registered trademark of 13 // DENSO WAVE INCORPORATED 14 // http://www.denso-wave.com/qrcode/faqpatent-e.html 15 // 16 //--------------------------------------------------------------------- 17 18 var qrcode = function() { 19 20 //--------------------------------------------------------------------- 21 // qrcode 22 //--------------------------------------------------------------------- 23 24 /** 25 * qrcode 26 * @param typeNumber 1 to 40 27 * @param errorCorrectionLevel 'L','M','Q','H' 28 */ 29 var qrcode = function(typeNumber, errorCorrectionLevel) { 30 31 var PAD0 = 0xEC; 32 var PAD1 = 0x11; 33 34 var _typeNumber = typeNumber; 35 var _errorCorrectionLevel = QRErrorCorrectionLevel[errorCorrectionLevel]; 36 var _modules = null; 37 var _moduleCount = 0; 38 var _dataCache = null; 39 var _dataList = []; 40 41 var _this = {}; 42 43 var makeImpl = function(test, maskPattern) { 44 45 _moduleCount = _typeNumber * 4 + 17; 46 _modules = function(moduleCount) { 47 var modules = new Array(moduleCount); 48 for (var row = 0; row < moduleCount; row += 1) { 49 modules[row] = new Array(moduleCount); 50 for (var col = 0; col < moduleCount; col += 1) { 51 modules[row][col] = null; 52 } 53 } 54 return modules; 55 }(_moduleCount); 56 57 setupPositionProbePattern(0, 0); 58 setupPositionProbePattern(_moduleCount - 7, 0); 59 setupPositionProbePattern(0, _moduleCount - 7); 60 setupPositionAdjustPattern(); 61 setupTimingPattern(); 62 setupTypeInfo(test, maskPattern); 63 64 if (_typeNumber >= 7) { 65 setupTypeNumber(test); 66 } 67 68 if (_dataCache == null) { 69 _dataCache = createData(_typeNumber, _errorCorrectionLevel, _dataList); 70 } 71 72 mapData(_dataCache, maskPattern); 73 }; 74 75 var setupPositionProbePattern = function(row, col) { 76 77 for (var r = -1; r <= 7; r += 1) { 78 79 if (row + r <= -1 || _moduleCount <= row + r) continue; 80 81 for (var c = -1; c <= 7; c += 1) { 82 83 if (col + c <= -1 || _moduleCount <= col + c) continue; 84 85 if ( (0 <= r && r <= 6 && (c == 0 || c == 6) ) 86 || (0 <= c && c <= 6 && (r == 0 || r == 6) ) 87 || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) { 88 _modules[row + r][col + c] = true; 89 } else { 90 _modules[row + r][col + c] = false; 91 } 92 } 93 } 94 }; 95 96 var getBestMaskPattern = function() { 97 98 var minLostPoint = 0; 99 var pattern = 0; 100 101 for (var i = 0; i < 8; i += 1) { 102 103 makeImpl(true, i); 104 105 var lostPoint = QRUtil.getLostPoint(_this); 106 107 if (i == 0 || minLostPoint > lostPoint) { 108 minLostPoint = lostPoint; 109 pattern = i; 110 } 111 } 112 113 return pattern; 114 }; 115 116 var setupTimingPattern = function() { 117 118 for (var r = 8; r < _moduleCount - 8; r += 1) { 119 if (_modules[r][6] != null) { 120 continue; 121 } 122 _modules[r][6] = (r % 2 == 0); 123 } 124 125 for (var c = 8; c < _moduleCount - 8; c += 1) { 126 if (_modules[6][c] != null) { 127 continue; 128 } 129 _modules[6][c] = (c % 2 == 0); 130 } 131 }; 132 133 var setupPositionAdjustPattern = function() { 134 135 var pos = QRUtil.getPatternPosition(_typeNumber); 136 137 for (var i = 0; i < pos.length; i += 1) { 138 139 for (var j = 0; j < pos.length; j += 1) { 140 141 var row = pos[i]; 142 var col = pos[j]; 143 144 if (_modules[row][col] != null) { 145 continue; 146 } 147 148 for (var r = -2; r <= 2; r += 1) { 149 150 for (var c = -2; c <= 2; c += 1) { 151 152 if (r == -2 || r == 2 || c == -2 || c == 2 153 || (r == 0 && c == 0) ) { 154 _modules[row + r][col + c] = true; 155 } else { 156 _modules[row + r][col + c] = false; 157 } 158 } 159 } 160 } 161 } 162 }; 163 164 var setupTypeNumber = function(test) { 165 166 var bits = QRUtil.getBCHTypeNumber(_typeNumber); 167 168 for (var i = 0; i < 18; i += 1) { 169 var mod = (!test && ( (bits >> i) & 1) == 1); 170 _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod; 171 } 172 173 for (var i = 0; i < 18; i += 1) { 174 var mod = (!test && ( (bits >> i) & 1) == 1); 175 _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod; 176 } 177 }; 178 179 var setupTypeInfo = function(test, maskPattern) { 180 181 var data = (_errorCorrectionLevel << 3) | maskPattern; 182 var bits = QRUtil.getBCHTypeInfo(data); 183 184 // vertical 185 for (var i = 0; i < 15; i += 1) { 186 187 var mod = (!test && ( (bits >> i) & 1) == 1); 188 189 if (i < 6) { 190 _modules[i][8] = mod; 191 } else if (i < 8) { 192 _modules[i + 1][8] = mod; 193 } else { 194 _modules[_moduleCount - 15 + i][8] = mod; 195 } 196 } 197 198 // horizontal 199 for (var i = 0; i < 15; i += 1) { 200 201 var mod = (!test && ( (bits >> i) & 1) == 1); 202 203 if (i < 8) { 204 _modules[8][_moduleCount - i - 1] = mod; 205 } else if (i < 9) { 206 _modules[8][15 - i - 1 + 1] = mod; 207 } else { 208 _modules[8][15 - i - 1] = mod; 209 } 210 } 211 212 // fixed module 213 _modules[_moduleCount - 8][8] = (!test); 214 }; 215 216 var mapData = function(data, maskPattern) { 217 218 var inc = -1; 219 var row = _moduleCount - 1; 220 var bitIndex = 7; 221 var byteIndex = 0; 222 var maskFunc = QRUtil.getMaskFunction(maskPattern); 223 224 for (var col = _moduleCount - 1; col > 0; col -= 2) { 225 226 if (col == 6) col -= 1; 227 228 while (true) { 229 230 for (var c = 0; c < 2; c += 1) { 231 232 if (_modules[row][col - c] == null) { 233 234 var dark = false; 235 236 if (byteIndex < data.length) { 237 dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1); 238 } 239 240 var mask = maskFunc(row, col - c); 241 242 if (mask) { 243 dark = !dark; 244 } 245 246 _modules[row][col - c] = dark; 247 bitIndex -= 1; 248 249 if (bitIndex == -1) { 250 byteIndex += 1; 251 bitIndex = 7; 252 } 253 } 254 } 255 256 row += inc; 257 258 if (row < 0 || _moduleCount <= row) { 259 row -= inc; 260 inc = -inc; 261 break; 262 } 263 } 264 } 265 }; 266 267 var createBytes = function(buffer, rsBlocks) { 268 269 var offset = 0; 270 271 var maxDcCount = 0; 272 var maxEcCount = 0; 273 274 var dcdata = new Array(rsBlocks.length); 275 var ecdata = new Array(rsBlocks.length); 276 277 for (var r = 0; r < rsBlocks.length; r += 1) { 278 279 var dcCount = rsBlocks[r].dataCount; 280 var ecCount = rsBlocks[r].totalCount - dcCount; 281 282 maxDcCount = Math.max(maxDcCount, dcCount); 283 maxEcCount = Math.max(maxEcCount, ecCount); 284 285 dcdata[r] = new Array(dcCount); 286 287 for (var i = 0; i < dcdata[r].length; i += 1) { 288 dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset]; 289 } 290 offset += dcCount; 291 292 var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); 293 var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1); 294 295 var modPoly = rawPoly.mod(rsPoly); 296 ecdata[r] = new Array(rsPoly.getLength() - 1); 297 for (var i = 0; i < ecdata[r].length; i += 1) { 298 var modIndex = i + modPoly.getLength() - ecdata[r].length; 299 ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0; 300 } 301 } 302 303 var totalCodeCount = 0; 304 for (var i = 0; i < rsBlocks.length; i += 1) { 305 totalCodeCount += rsBlocks[i].totalCount; 306 } 307 308 var data = new Array(totalCodeCount); 309 var index = 0; 310 311 for (var i = 0; i < maxDcCount; i += 1) { 312 for (var r = 0; r < rsBlocks.length; r += 1) { 313 if (i < dcdata[r].length) { 314 data[index] = dcdata[r][i]; 315 index += 1; 316 } 317 } 318 } 319 320 for (var i = 0; i < maxEcCount; i += 1) { 321 for (var r = 0; r < rsBlocks.length; r += 1) { 322 if (i < ecdata[r].length) { 323 data[index] = ecdata[r][i]; 324 index += 1; 325 } 326 } 327 } 328 329 return data; 330 }; 331 332 var createData = function(typeNumber, errorCorrectionLevel, dataList) { 333 334 var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectionLevel); 335 336 var buffer = qrBitBuffer(); 337 338 for (var i = 0; i < dataList.length; i += 1) { 339 var data = dataList[i]; 340 buffer.put(data.getMode(), 4); 341 buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) ); 342 data.write(buffer); 343 } 344 345 // calc num max data. 346 var totalDataCount = 0; 347 for (var i = 0; i < rsBlocks.length; i += 1) { 348 totalDataCount += rsBlocks[i].dataCount; 349 } 350 351 if (buffer.getLengthInBits() > totalDataCount * 8) { 352 throw 'code length overflow. (' 353 + buffer.getLengthInBits() 354 + '>' 355 + totalDataCount * 8 356 + ')'; 357 } 358 359 // end code 360 if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { 361 buffer.put(0, 4); 362 } 363 364 // padding 365 while (buffer.getLengthInBits() % 8 != 0) { 366 buffer.putBit(false); 367 } 368 369 // padding 370 while (true) { 371 372 if (buffer.getLengthInBits() >= totalDataCount * 8) { 373 break; 374 } 375 buffer.put(PAD0, 8); 376 377 if (buffer.getLengthInBits() >= totalDataCount * 8) { 378 break; 379 } 380 buffer.put(PAD1, 8); 381 } 382 383 return createBytes(buffer, rsBlocks); 384 }; 385 386 _this.addData = function(data, mode) { 387 388 mode = mode || 'Byte'; 389 390 var newData = null; 391 392 switch(mode) { 393 case 'Numeric' : 394 newData = qrNumber(data); 395 break; 396 case 'Alphanumeric' : 397 newData = qrAlphaNum(data); 398 break; 399 case 'Byte' : 400 newData = qr8BitByte(data); 401 break; 402 case 'Kanji' : 403 newData = qrKanji(data); 404 break; 405 default : 406 throw 'mode:' + mode; 407 } 408 409 _dataList.push(newData); 410 _dataCache = null; 411 }; 412 413 _this.isDark = function(row, col) { 414 if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) { 415 throw row + ',' + col; 416 } 417 return _modules[row][col]; 418 }; 419 420 _this.getModuleCount = function() { 421 return _moduleCount; 422 }; 423 424 _this.make = function() { 425 if (_typeNumber < 1) { 426 var typeNumber = 1; 427 428 for (; typeNumber < 40; typeNumber++) { 429 var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, _errorCorrectionLevel); 430 var buffer = qrBitBuffer(); 431 432 for (var i = 0; i < _dataList.length; i++) { 433 var data = _dataList[i]; 434 buffer.put(data.getMode(), 4); 435 buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) ); 436 data.write(buffer); 437 } 438 439 var totalDataCount = 0; 440 for (var i = 0; i < rsBlocks.length; i++) { 441 totalDataCount += rsBlocks[i].dataCount; 442 } 443 444 if (buffer.getLengthInBits() <= totalDataCount * 8) { 445 break; 446 } 447 } 448 449 _typeNumber = typeNumber; 450 } 451 452 makeImpl(false, getBestMaskPattern() ); 453 }; 454 455 _this.createTableTag = function(cellSize, margin) { 456 457 cellSize = cellSize || 2; 458 margin = (typeof margin == 'undefined')? cellSize * 4 : margin; 459 460 var qrHtml = ''; 461 462 qrHtml += '<table style="'; 463 qrHtml += ' border-width: 0px; border-style: none;'; 464 qrHtml += ' border-collapse: collapse;'; 465 qrHtml += ' padding: 0px; margin: ' + margin + 'px;'; 466 qrHtml += '">'; 467 qrHtml += '<tbody>'; 468 469 for (var r = 0; r < _this.getModuleCount(); r += 1) { 470 471 qrHtml += '<tr>'; 472 473 for (var c = 0; c < _this.getModuleCount(); c += 1) { 474 qrHtml += '<td style="'; 475 qrHtml += ' border-width: 0px; border-style: none;'; 476 qrHtml += ' border-collapse: collapse;'; 477 qrHtml += ' padding: 0px; margin: 0px;'; 478 qrHtml += ' width: ' + cellSize + 'px;'; 479 qrHtml += ' height: ' + cellSize + 'px;'; 480 qrHtml += ' background-color: '; 481 qrHtml += _this.isDark(r, c)? '#000000' : '#ffffff'; 482 qrHtml += ';'; 483 qrHtml += '"/>'; 484 } 485 486 qrHtml += '</tr>'; 487 } 488 489 qrHtml += '</tbody>'; 490 qrHtml += '</table>'; 491 492 return qrHtml; 493 }; 494 495 _this.createSvgTag = function(cellSize, margin, alt, title) { 496 497 var opts = {}; 498 if (typeof arguments[0] == 'object') { 499 // Called by options. 500 opts = arguments[0]; 501 // overwrite cellSize and margin. 502 cellSize = opts.cellSize; 503 margin = opts.margin; 504 alt = opts.alt; 505 title = opts.title; 506 } 507 508 cellSize = cellSize || 2; 509 margin = (typeof margin == 'undefined')? cellSize * 4 : margin; 510 511 // Compose alt property surrogate 512 alt = (typeof alt === 'string') ? {text: alt} : alt || {}; 513 alt.text = alt.text || null; 514 alt.id = (alt.text) ? alt.id || 'qrcode-description' : null; 515 516 // Compose title property surrogate 517 title = (typeof title === 'string') ? {text: title} : title || {}; 518 title.text = title.text || null; 519 title.id = (title.text) ? title.id || 'qrcode-title' : null; 520 521 var size = _this.getModuleCount() * cellSize + margin * 2; 522 var c, mc, r, mr, qrSvg='', rect; 523 524 rect = 'l' + cellSize + ',0 0,' + cellSize + 525 ' -' + cellSize + ',0 0,-' + cellSize + 'z '; 526 527 qrSvg += '<svg version="1.1" xmlns="http://www.w3.org/2000/svg"'; 528 qrSvg += !opts.scalable ? ' width="' + size + 'px" height="' + size + 'px"' : ''; 529 qrSvg += ' viewBox="0 0 ' + size + ' ' + size + '" '; 530 qrSvg += ' preserveAspectRatio="xMinYMin meet"'; 531 qrSvg += (title.text || alt.text) ? ' role="img" aria-labelledby="' + 532 escapeXml([title.id, alt.id].join(' ').trim() ) + '"' : ''; 533 qrSvg += '>'; 534 qrSvg += (title.text) ? '<title id="' + escapeXml(title.id) + '">' + 535 escapeXml(title.text) + '</title>' : ''; 536 qrSvg += (alt.text) ? '<description id="' + escapeXml(alt.id) + '">' + 537 escapeXml(alt.text) + '</description>' : ''; 538 qrSvg += '<rect width="100%" height="100%" fill="white" cx="0" cy="0"/>'; 539 qrSvg += '<path d="'; 540 541 for (r = 0; r < _this.getModuleCount(); r += 1) { 542 mr = r * cellSize + margin; 543 for (c = 0; c < _this.getModuleCount(); c += 1) { 544 if (_this.isDark(r, c) ) { 545 mc = c*cellSize+margin; 546 qrSvg += 'M' + mc + ',' + mr + rect; 547 } 548 } 549 } 550 551 qrSvg += '" stroke="transparent" fill="black"/>'; 552 qrSvg += '</svg>'; 553 554 return qrSvg; 555 }; 556 557 _this.createDataURL = function(cellSize, margin) { 558 559 cellSize = cellSize || 2; 560 margin = (typeof margin == 'undefined')? cellSize * 4 : margin; 561 562 var size = _this.getModuleCount() * cellSize + margin * 2; 563 var min = margin; 564 var max = size - margin; 565 566 return createDataURL(size, size, function(x, y) { 567 if (min <= x && x < max && min <= y && y < max) { 568 var c = Math.floor( (x - min) / cellSize); 569 var r = Math.floor( (y - min) / cellSize); 570 return _this.isDark(r, c)? 0 : 1; 571 } else { 572 return 1; 573 } 574 } ); 575 }; 576 577 _this.createImgTag = function(cellSize, margin, alt) { 578 579 cellSize = cellSize || 2; 580 margin = (typeof margin == 'undefined')? cellSize * 4 : margin; 581 582 var size = _this.getModuleCount() * cellSize + margin * 2; 583 584 var img = ''; 585 img += '<img'; 586 img += '\u0020src="'; 587 img += _this.createDataURL(cellSize, margin); 588 img += '"'; 589 img += '\u0020width="'; 590 img += size; 591 img += '"'; 592 img += '\u0020height="'; 593 img += size; 594 img += '"'; 595 if (alt) { 596 img += '\u0020alt="'; 597 img += escapeXml(alt); 598 img += '"'; 599 } 600 img += '/>'; 601 602 return img; 603 }; 604 605 var escapeXml = function(s) { 606 var escaped = ''; 607 for (var i = 0; i < s.length; i += 1) { 608 var c = s.charAt(i); 609 switch(c) { 610 case '<': escaped += '<'; break; 611 case '>': escaped += '>'; break; 612 case '&': escaped += '&'; break; 613 case '"': escaped += '"'; break; 614 default : escaped += c; break; 615 } 616 } 617 return escaped; 618 }; 619 620 var _createHalfASCII = function(margin) { 621 var cellSize = 1; 622 margin = (typeof margin == 'undefined')? cellSize * 2 : margin; 623 624 var size = _this.getModuleCount() * cellSize + margin * 2; 625 var min = margin; 626 var max = size - margin; 627 628 var y, x, r1, r2, p; 629 630 var blocks = { 631 '██': '█', 632 '█ ': '▀', 633 ' █': '▄', 634 ' ': ' ' 635 }; 636 637 var blocksLastLineNoMargin = { 638 '██': '▀', 639 '█ ': '▀', 640 ' █': ' ', 641 ' ': ' ' 642 }; 643 644 var ascii = ''; 645 for (y = 0; y < size; y += 2) { 646 r1 = Math.floor((y - min) / cellSize); 647 r2 = Math.floor((y + 1 - min) / cellSize); 648 for (x = 0; x < size; x += 1) { 649 p = '█'; 650 651 if (min <= x && x < max && min <= y && y < max && _this.isDark(r1, Math.floor((x - min) / cellSize))) { 652 p = ' '; 653 } 654 655 if (min <= x && x < max && min <= y+1 && y+1 < max && _this.isDark(r2, Math.floor((x - min) / cellSize))) { 656 p += ' '; 657 } 658 else { 659 p += '█'; 660 } 661 662 // Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square. 663 ascii += (margin < 1 && y+1 >= max) ? blocksLastLineNoMargin[p] : blocks[p]; 664 } 665 666 ascii += '\n'; 667 } 668 669 if (size % 2 && margin > 0) { 670 return ascii.substring(0, ascii.length - size - 1) + Array(size+1).join('▀'); 671 } 672 673 return ascii.substring(0, ascii.length-1); 674 }; 675 676 _this.createASCII = function(cellSize, margin) { 677 cellSize = cellSize || 1; 678 679 if (cellSize < 2) { 680 return _createHalfASCII(margin); 681 } 682 683 cellSize -= 1; 684 margin = (typeof margin == 'undefined')? cellSize * 2 : margin; 685 686 var size = _this.getModuleCount() * cellSize + margin * 2; 687 var min = margin; 688 var max = size - margin; 689 690 var y, x, r, p; 691 692 var white = Array(cellSize+1).join('██'); 693 var black = Array(cellSize+1).join(' '); 694 695 var ascii = ''; 696 var line = ''; 697 for (y = 0; y < size; y += 1) { 698 r = Math.floor( (y - min) / cellSize); 699 line = ''; 700 for (x = 0; x < size; x += 1) { 701 p = 1; 702 703 if (min <= x && x < max && min <= y && y < max && _this.isDark(r, Math.floor((x - min) / cellSize))) { 704 p = 0; 705 } 706 707 // Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square. 708 line += p ? white : black; 709 } 710 711 for (r = 0; r < cellSize; r += 1) { 712 ascii += line + '\n'; 713 } 714 } 715 716 return ascii.substring(0, ascii.length-1); 717 }; 718 719 _this.renderTo2dContext = function(context, cellSize) { 720 cellSize = cellSize || 2; 721 var length = _this.getModuleCount(); 722 for (var row = 0; row < length; row++) { 723 for (var col = 0; col < length; col++) { 724 context.fillStyle = _this.isDark(row, col) ? 'black' : 'white'; 725 context.fillRect(row * cellSize, col * cellSize, cellSize, cellSize); 726 } 727 } 728 } 729 730 return _this; 731 }; 732 733 //--------------------------------------------------------------------- 734 // qrcode.stringToBytes 735 //--------------------------------------------------------------------- 736 737 qrcode.stringToBytesFuncs = { 738 'default' : function(s) { 739 var bytes = []; 740 for (var i = 0; i < s.length; i += 1) { 741 var c = s.charCodeAt(i); 742 bytes.push(c & 0xff); 743 } 744 return bytes; 745 } 746 }; 747 748 qrcode.stringToBytes = qrcode.stringToBytesFuncs['default']; 749 750 //--------------------------------------------------------------------- 751 // qrcode.createStringToBytes 752 //--------------------------------------------------------------------- 753 754 /** 755 * @param unicodeData base64 string of byte array. 756 * [16bit Unicode],[16bit Bytes], ... 757 * @param numChars 758 */ 759 qrcode.createStringToBytes = function(unicodeData, numChars) { 760 761 // create conversion map. 762 763 var unicodeMap = function() { 764 765 var bin = base64DecodeInputStream(unicodeData); 766 var read = function() { 767 var b = bin.read(); 768 if (b == -1) throw 'eof'; 769 return b; 770 }; 771 772 var count = 0; 773 var unicodeMap = {}; 774 while (true) { 775 var b0 = bin.read(); 776 if (b0 == -1) break; 777 var b1 = read(); 778 var b2 = read(); 779 var b3 = read(); 780 var k = String.fromCharCode( (b0 << 8) | b1); 781 var v = (b2 << 8) | b3; 782 unicodeMap[k] = v; 783 count += 1; 784 } 785 if (count != numChars) { 786 throw count + ' != ' + numChars; 787 } 788 789 return unicodeMap; 790 }(); 791 792 var unknownChar = '?'.charCodeAt(0); 793 794 return function(s) { 795 var bytes = []; 796 for (var i = 0; i < s.length; i += 1) { 797 var c = s.charCodeAt(i); 798 if (c < 128) { 799 bytes.push(c); 800 } else { 801 var b = unicodeMap[s.charAt(i)]; 802 if (typeof b == 'number') { 803 if ( (b & 0xff) == b) { 804 // 1byte 805 bytes.push(b); 806 } else { 807 // 2bytes 808 bytes.push(b >>> 8); 809 bytes.push(b & 0xff); 810 } 811 } else { 812 bytes.push(unknownChar); 813 } 814 } 815 } 816 return bytes; 817 }; 818 }; 819 820 //--------------------------------------------------------------------- 821 // QRMode 822 //--------------------------------------------------------------------- 823 824 var QRMode = { 825 MODE_NUMBER : 1 << 0, 826 MODE_ALPHA_NUM : 1 << 1, 827 MODE_8BIT_BYTE : 1 << 2, 828 MODE_KANJI : 1 << 3 829 }; 830 831 //--------------------------------------------------------------------- 832 // QRErrorCorrectionLevel 833 //--------------------------------------------------------------------- 834 835 var QRErrorCorrectionLevel = { 836 L : 1, 837 M : 0, 838 Q : 3, 839 H : 2 840 }; 841 842 //--------------------------------------------------------------------- 843 // QRMaskPattern 844 //--------------------------------------------------------------------- 845 846 var QRMaskPattern = { 847 PATTERN000 : 0, 848 PATTERN001 : 1, 849 PATTERN010 : 2, 850 PATTERN011 : 3, 851 PATTERN100 : 4, 852 PATTERN101 : 5, 853 PATTERN110 : 6, 854 PATTERN111 : 7 855 }; 856 857 //--------------------------------------------------------------------- 858 // QRUtil 859 //--------------------------------------------------------------------- 860 861 var QRUtil = function() { 862 863 var PATTERN_POSITION_TABLE = [ 864 [], 865 [6, 18], 866 [6, 22], 867 [6, 26], 868 [6, 30], 869 [6, 34], 870 [6, 22, 38], 871 [6, 24, 42], 872 [6, 26, 46], 873 [6, 28, 50], 874 [6, 30, 54], 875 [6, 32, 58], 876 [6, 34, 62], 877 [6, 26, 46, 66], 878 [6, 26, 48, 70], 879 [6, 26, 50, 74], 880 [6, 30, 54, 78], 881 [6, 30, 56, 82], 882 [6, 30, 58, 86], 883 [6, 34, 62, 90], 884 [6, 28, 50, 72, 94], 885 [6, 26, 50, 74, 98], 886 [6, 30, 54, 78, 102], 887 [6, 28, 54, 80, 106], 888 [6, 32, 58, 84, 110], 889 [6, 30, 58, 86, 114], 890 [6, 34, 62, 90, 118], 891 [6, 26, 50, 74, 98, 122], 892 [6, 30, 54, 78, 102, 126], 893 [6, 26, 52, 78, 104, 130], 894 [6, 30, 56, 82, 108, 134], 895 [6, 34, 60, 86, 112, 138], 896 [6, 30, 58, 86, 114, 142], 897 [6, 34, 62, 90, 118, 146], 898 [6, 30, 54, 78, 102, 126, 150], 899 [6, 24, 50, 76, 102, 128, 154], 900 [6, 28, 54, 80, 106, 132, 158], 901 [6, 32, 58, 84, 110, 136, 162], 902 [6, 26, 54, 82, 110, 138, 166], 903 [6, 30, 58, 86, 114, 142, 170] 904 ]; 905 var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0); 906 var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0); 907 var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1); 908 909 var _this = {}; 910 911 var getBCHDigit = function(data) { 912 var digit = 0; 913 while (data != 0) { 914 digit += 1; 915 data >>>= 1; 916 } 917 return digit; 918 }; 919 920 _this.getBCHTypeInfo = function(data) { 921 var d = data << 10; 922 while (getBCHDigit(d) - getBCHDigit(G15) >= 0) { 923 d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) ); 924 } 925 return ( (data << 10) | d) ^ G15_MASK; 926 }; 927 928 _this.getBCHTypeNumber = function(data) { 929 var d = data << 12; 930 while (getBCHDigit(d) - getBCHDigit(G18) >= 0) { 931 d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) ); 932 } 933 return (data << 12) | d; 934 }; 935 936 _this.getPatternPosition = function(typeNumber) { 937 return PATTERN_POSITION_TABLE[typeNumber - 1]; 938 }; 939 940 _this.getMaskFunction = function(maskPattern) { 941 942 switch (maskPattern) { 943 944 case QRMaskPattern.PATTERN000 : 945 return function(i, j) { return (i + j) % 2 == 0; }; 946 case QRMaskPattern.PATTERN001 : 947 return function(i, j) { return i % 2 == 0; }; 948 case QRMaskPattern.PATTERN010 : 949 return function(i, j) { return j % 3 == 0; }; 950 case QRMaskPattern.PATTERN011 : 951 return function(i, j) { return (i + j) % 3 == 0; }; 952 case QRMaskPattern.PATTERN100 : 953 return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; }; 954 case QRMaskPattern.PATTERN101 : 955 return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; }; 956 case QRMaskPattern.PATTERN110 : 957 return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; }; 958 case QRMaskPattern.PATTERN111 : 959 return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; }; 960 961 default : 962 throw 'bad maskPattern:' + maskPattern; 963 } 964 }; 965 966 _this.getErrorCorrectPolynomial = function(errorCorrectLength) { 967 var a = qrPolynomial([1], 0); 968 for (var i = 0; i < errorCorrectLength; i += 1) { 969 a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) ); 970 } 971 return a; 972 }; 973 974 _this.getLengthInBits = function(mode, type) { 975 976 if (1 <= type && type < 10) { 977 978 // 1 - 9 979 980 switch(mode) { 981 case QRMode.MODE_NUMBER : return 10; 982 case QRMode.MODE_ALPHA_NUM : return 9; 983 case QRMode.MODE_8BIT_BYTE : return 8; 984 case QRMode.MODE_KANJI : return 8; 985 default : 986 throw 'mode:' + mode; 987 } 988 989 } else if (type < 27) { 990 991 // 10 - 26 992 993 switch(mode) { 994 case QRMode.MODE_NUMBER : return 12; 995 case QRMode.MODE_ALPHA_NUM : return 11; 996 case QRMode.MODE_8BIT_BYTE : return 16; 997 case QRMode.MODE_KANJI : return 10; 998 default : 999 throw 'mode:' + mode; 1000 } 1001 1002 } else if (type < 41) { 1003 1004 // 27 - 40 1005 1006 switch(mode) { 1007 case QRMode.MODE_NUMBER : return 14; 1008 case QRMode.MODE_ALPHA_NUM : return 13; 1009 case QRMode.MODE_8BIT_BYTE : return 16; 1010 case QRMode.MODE_KANJI : return 12; 1011 default : 1012 throw 'mode:' + mode; 1013 } 1014 1015 } else { 1016 throw 'type:' + type; 1017 } 1018 }; 1019 1020 _this.getLostPoint = function(qrcode) { 1021 1022 var moduleCount = qrcode.getModuleCount(); 1023 1024 var lostPoint = 0; 1025 1026 // LEVEL1 1027 1028 for (var row = 0; row < moduleCount; row += 1) { 1029 for (var col = 0; col < moduleCount; col += 1) { 1030 1031 var sameCount = 0; 1032 var dark = qrcode.isDark(row, col); 1033 1034 for (var r = -1; r <= 1; r += 1) { 1035 1036 if (row + r < 0 || moduleCount <= row + r) { 1037 continue; 1038 } 1039 1040 for (var c = -1; c <= 1; c += 1) { 1041 1042 if (col + c < 0 || moduleCount <= col + c) { 1043 continue; 1044 } 1045 1046 if (r == 0 && c == 0) { 1047 continue; 1048 } 1049 1050 if (dark == qrcode.isDark(row + r, col + c) ) { 1051 sameCount += 1; 1052 } 1053 } 1054 } 1055 1056 if (sameCount > 5) { 1057 lostPoint += (3 + sameCount - 5); 1058 } 1059 } 1060 }; 1061 1062 // LEVEL2 1063 1064 for (var row = 0; row < moduleCount - 1; row += 1) { 1065 for (var col = 0; col < moduleCount - 1; col += 1) { 1066 var count = 0; 1067 if (qrcode.isDark(row, col) ) count += 1; 1068 if (qrcode.isDark(row + 1, col) ) count += 1; 1069 if (qrcode.isDark(row, col + 1) ) count += 1; 1070 if (qrcode.isDark(row + 1, col + 1) ) count += 1; 1071 if (count == 0 || count == 4) { 1072 lostPoint += 3; 1073 } 1074 } 1075 } 1076 1077 // LEVEL3 1078 1079 for (var row = 0; row < moduleCount; row += 1) { 1080 for (var col = 0; col < moduleCount - 6; col += 1) { 1081 if (qrcode.isDark(row, col) 1082 && !qrcode.isDark(row, col + 1) 1083 && qrcode.isDark(row, col + 2) 1084 && qrcode.isDark(row, col + 3) 1085 && qrcode.isDark(row, col + 4) 1086 && !qrcode.isDark(row, col + 5) 1087 && qrcode.isDark(row, col + 6) ) { 1088 lostPoint += 40; 1089 } 1090 } 1091 } 1092 1093 for (var col = 0; col < moduleCount; col += 1) { 1094 for (var row = 0; row < moduleCount - 6; row += 1) { 1095 if (qrcode.isDark(row, col) 1096 && !qrcode.isDark(row + 1, col) 1097 && qrcode.isDark(row + 2, col) 1098 && qrcode.isDark(row + 3, col) 1099 && qrcode.isDark(row + 4, col) 1100 && !qrcode.isDark(row + 5, col) 1101 && qrcode.isDark(row + 6, col) ) { 1102 lostPoint += 40; 1103 } 1104 } 1105 } 1106 1107 // LEVEL4 1108 1109 var darkCount = 0; 1110 1111 for (var col = 0; col < moduleCount; col += 1) { 1112 for (var row = 0; row < moduleCount; row += 1) { 1113 if (qrcode.isDark(row, col) ) { 1114 darkCount += 1; 1115 } 1116 } 1117 } 1118 1119 var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; 1120 lostPoint += ratio * 10; 1121 1122 return lostPoint; 1123 }; 1124 1125 return _this; 1126 }(); 1127 1128 //--------------------------------------------------------------------- 1129 // QRMath 1130 //--------------------------------------------------------------------- 1131 1132 var QRMath = function() { 1133 1134 var EXP_TABLE = new Array(256); 1135 var LOG_TABLE = new Array(256); 1136 1137 // initialize tables 1138 for (var i = 0; i < 8; i += 1) { 1139 EXP_TABLE[i] = 1 << i; 1140 } 1141 for (var i = 8; i < 256; i += 1) { 1142 EXP_TABLE[i] = EXP_TABLE[i - 4] 1143 ^ EXP_TABLE[i - 5] 1144 ^ EXP_TABLE[i - 6] 1145 ^ EXP_TABLE[i - 8]; 1146 } 1147 for (var i = 0; i < 255; i += 1) { 1148 LOG_TABLE[EXP_TABLE[i] ] = i; 1149 } 1150 1151 var _this = {}; 1152 1153 _this.glog = function(n) { 1154 1155 if (n < 1) { 1156 throw 'glog(' + n + ')'; 1157 } 1158 1159 return LOG_TABLE[n]; 1160 }; 1161 1162 _this.gexp = function(n) { 1163 1164 while (n < 0) { 1165 n += 255; 1166 } 1167 1168 while (n >= 256) { 1169 n -= 255; 1170 } 1171 1172 return EXP_TABLE[n]; 1173 }; 1174 1175 return _this; 1176 }(); 1177 1178 //--------------------------------------------------------------------- 1179 // qrPolynomial 1180 //--------------------------------------------------------------------- 1181 1182 function qrPolynomial(num, shift) { 1183 1184 if (typeof num.length == 'undefined') { 1185 throw num.length + '/' + shift; 1186 } 1187 1188 var _num = function() { 1189 var offset = 0; 1190 while (offset < num.length && num[offset] == 0) { 1191 offset += 1; 1192 } 1193 var _num = new Array(num.length - offset + shift); 1194 for (var i = 0; i < num.length - offset; i += 1) { 1195 _num[i] = num[i + offset]; 1196 } 1197 return _num; 1198 }(); 1199 1200 var _this = {}; 1201 1202 _this.getAt = function(index) { 1203 return _num[index]; 1204 }; 1205 1206 _this.getLength = function() { 1207 return _num.length; 1208 }; 1209 1210 _this.multiply = function(e) { 1211 1212 var num = new Array(_this.getLength() + e.getLength() - 1); 1213 1214 for (var i = 0; i < _this.getLength(); i += 1) { 1215 for (var j = 0; j < e.getLength(); j += 1) { 1216 num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) ); 1217 } 1218 } 1219 1220 return qrPolynomial(num, 0); 1221 }; 1222 1223 _this.mod = function(e) { 1224 1225 if (_this.getLength() - e.getLength() < 0) { 1226 return _this; 1227 } 1228 1229 var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) ); 1230 1231 var num = new Array(_this.getLength() ); 1232 for (var i = 0; i < _this.getLength(); i += 1) { 1233 num[i] = _this.getAt(i); 1234 } 1235 1236 for (var i = 0; i < e.getLength(); i += 1) { 1237 num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio); 1238 } 1239 1240 // recursive call 1241 return qrPolynomial(num, 0).mod(e); 1242 }; 1243 1244 return _this; 1245 }; 1246 1247 //--------------------------------------------------------------------- 1248 // QRRSBlock 1249 //--------------------------------------------------------------------- 1250 1251 var QRRSBlock = function() { 1252 1253 var RS_BLOCK_TABLE = [ 1254 1255 // L 1256 // M 1257 // Q 1258 // H 1259 1260 // 1 1261 [1, 26, 19], 1262 [1, 26, 16], 1263 [1, 26, 13], 1264 [1, 26, 9], 1265 1266 // 2 1267 [1, 44, 34], 1268 [1, 44, 28], 1269 [1, 44, 22], 1270 [1, 44, 16], 1271 1272 // 3 1273 [1, 70, 55], 1274 [1, 70, 44], 1275 [2, 35, 17], 1276 [2, 35, 13], 1277 1278 // 4 1279 [1, 100, 80], 1280 [2, 50, 32], 1281 [2, 50, 24], 1282 [4, 25, 9], 1283 1284 // 5 1285 [1, 134, 108], 1286 [2, 67, 43], 1287 [2, 33, 15, 2, 34, 16], 1288 [2, 33, 11, 2, 34, 12], 1289 1290 // 6 1291 [2, 86, 68], 1292 [4, 43, 27], 1293 [4, 43, 19], 1294 [4, 43, 15], 1295 1296 // 7 1297 [2, 98, 78], 1298 [4, 49, 31], 1299 [2, 32, 14, 4, 33, 15], 1300 [4, 39, 13, 1, 40, 14], 1301 1302 // 8 1303 [2, 121, 97], 1304 [2, 60, 38, 2, 61, 39], 1305 [4, 40, 18, 2, 41, 19], 1306 [4, 40, 14, 2, 41, 15], 1307 1308 // 9 1309 [2, 146, 116], 1310 [3, 58, 36, 2, 59, 37], 1311 [4, 36, 16, 4, 37, 17], 1312 [4, 36, 12, 4, 37, 13], 1313 1314 // 10 1315 [2, 86, 68, 2, 87, 69], 1316 [4, 69, 43, 1, 70, 44], 1317 [6, 43, 19, 2, 44, 20], 1318 [6, 43, 15, 2, 44, 16], 1319 1320 // 11 1321 [4, 101, 81], 1322 [1, 80, 50, 4, 81, 51], 1323 [4, 50, 22, 4, 51, 23], 1324 [3, 36, 12, 8, 37, 13], 1325 1326 // 12 1327 [2, 116, 92, 2, 117, 93], 1328 [6, 58, 36, 2, 59, 37], 1329 [4, 46, 20, 6, 47, 21], 1330 [7, 42, 14, 4, 43, 15], 1331 1332 // 13 1333 [4, 133, 107], 1334 [8, 59, 37, 1, 60, 38], 1335 [8, 44, 20, 4, 45, 21], 1336 [12, 33, 11, 4, 34, 12], 1337 1338 // 14 1339 [3, 145, 115, 1, 146, 116], 1340 [4, 64, 40, 5, 65, 41], 1341 [11, 36, 16, 5, 37, 17], 1342 [11, 36, 12, 5, 37, 13], 1343 1344 // 15 1345 [5, 109, 87, 1, 110, 88], 1346 [5, 65, 41, 5, 66, 42], 1347 [5, 54, 24, 7, 55, 25], 1348 [11, 36, 12, 7, 37, 13], 1349 1350 // 16 1351 [5, 122, 98, 1, 123, 99], 1352 [7, 73, 45, 3, 74, 46], 1353 [15, 43, 19, 2, 44, 20], 1354 [3, 45, 15, 13, 46, 16], 1355 1356 // 17 1357 [1, 135, 107, 5, 136, 108], 1358 [10, 74, 46, 1, 75, 47], 1359 [1, 50, 22, 15, 51, 23], 1360 [2, 42, 14, 17, 43, 15], 1361 1362 // 18 1363 [5, 150, 120, 1, 151, 121], 1364 [9, 69, 43, 4, 70, 44], 1365 [17, 50, 22, 1, 51, 23], 1366 [2, 42, 14, 19, 43, 15], 1367 1368 // 19 1369 [3, 141, 113, 4, 142, 114], 1370 [3, 70, 44, 11, 71, 45], 1371 [17, 47, 21, 4, 48, 22], 1372 [9, 39, 13, 16, 40, 14], 1373 1374 // 20 1375 [3, 135, 107, 5, 136, 108], 1376 [3, 67, 41, 13, 68, 42], 1377 [15, 54, 24, 5, 55, 25], 1378 [15, 43, 15, 10, 44, 16], 1379 1380 // 21 1381 [4, 144, 116, 4, 145, 117], 1382 [17, 68, 42], 1383 [17, 50, 22, 6, 51, 23], 1384 [19, 46, 16, 6, 47, 17], 1385 1386 // 22 1387 [2, 139, 111, 7, 140, 112], 1388 [17, 74, 46], 1389 [7, 54, 24, 16, 55, 25], 1390 [34, 37, 13], 1391 1392 // 23 1393 [4, 151, 121, 5, 152, 122], 1394 [4, 75, 47, 14, 76, 48], 1395 [11, 54, 24, 14, 55, 25], 1396 [16, 45, 15, 14, 46, 16], 1397 1398 // 24 1399 [6, 147, 117, 4, 148, 118], 1400 [6, 73, 45, 14, 74, 46], 1401 [11, 54, 24, 16, 55, 25], 1402 [30, 46, 16, 2, 47, 17], 1403 1404 // 25 1405 [8, 132, 106, 4, 133, 107], 1406 [8, 75, 47, 13, 76, 48], 1407 [7, 54, 24, 22, 55, 25], 1408 [22, 45, 15, 13, 46, 16], 1409 1410 // 26 1411 [10, 142, 114, 2, 143, 115], 1412 [19, 74, 46, 4, 75, 47], 1413 [28, 50, 22, 6, 51, 23], 1414 [33, 46, 16, 4, 47, 17], 1415 1416 // 27 1417 [8, 152, 122, 4, 153, 123], 1418 [22, 73, 45, 3, 74, 46], 1419 [8, 53, 23, 26, 54, 24], 1420 [12, 45, 15, 28, 46, 16], 1421 1422 // 28 1423 [3, 147, 117, 10, 148, 118], 1424 [3, 73, 45, 23, 74, 46], 1425 [4, 54, 24, 31, 55, 25], 1426 [11, 45, 15, 31, 46, 16], 1427 1428 // 29 1429 [7, 146, 116, 7, 147, 117], 1430 [21, 73, 45, 7, 74, 46], 1431 [1, 53, 23, 37, 54, 24], 1432 [19, 45, 15, 26, 46, 16], 1433 1434 // 30 1435 [5, 145, 115, 10, 146, 116], 1436 [19, 75, 47, 10, 76, 48], 1437 [15, 54, 24, 25, 55, 25], 1438 [23, 45, 15, 25, 46, 16], 1439 1440 // 31 1441 [13, 145, 115, 3, 146, 116], 1442 [2, 74, 46, 29, 75, 47], 1443 [42, 54, 24, 1, 55, 25], 1444 [23, 45, 15, 28, 46, 16], 1445 1446 // 32 1447 [17, 145, 115], 1448 [10, 74, 46, 23, 75, 47], 1449 [10, 54, 24, 35, 55, 25], 1450 [19, 45, 15, 35, 46, 16], 1451 1452 // 33 1453 [17, 145, 115, 1, 146, 116], 1454 [14, 74, 46, 21, 75, 47], 1455 [29, 54, 24, 19, 55, 25], 1456 [11, 45, 15, 46, 46, 16], 1457 1458 // 34 1459 [13, 145, 115, 6, 146, 116], 1460 [14, 74, 46, 23, 75, 47], 1461 [44, 54, 24, 7, 55, 25], 1462 [59, 46, 16, 1, 47, 17], 1463 1464 // 35 1465 [12, 151, 121, 7, 152, 122], 1466 [12, 75, 47, 26, 76, 48], 1467 [39, 54, 24, 14, 55, 25], 1468 [22, 45, 15, 41, 46, 16], 1469 1470 // 36 1471 [6, 151, 121, 14, 152, 122], 1472 [6, 75, 47, 34, 76, 48], 1473 [46, 54, 24, 10, 55, 25], 1474 [2, 45, 15, 64, 46, 16], 1475 1476 // 37 1477 [17, 152, 122, 4, 153, 123], 1478 [29, 74, 46, 14, 75, 47], 1479 [49, 54, 24, 10, 55, 25], 1480 [24, 45, 15, 46, 46, 16], 1481 1482 // 38 1483 [4, 152, 122, 18, 153, 123], 1484 [13, 74, 46, 32, 75, 47], 1485 [48, 54, 24, 14, 55, 25], 1486 [42, 45, 15, 32, 46, 16], 1487 1488 // 39 1489 [20, 147, 117, 4, 148, 118], 1490 [40, 75, 47, 7, 76, 48], 1491 [43, 54, 24, 22, 55, 25], 1492 [10, 45, 15, 67, 46, 16], 1493 1494 // 40 1495 [19, 148, 118, 6, 149, 119], 1496 [18, 75, 47, 31, 76, 48], 1497 [34, 54, 24, 34, 55, 25], 1498 [20, 45, 15, 61, 46, 16] 1499 ]; 1500 1501 var qrRSBlock = function(totalCount, dataCount) { 1502 var _this = {}; 1503 _this.totalCount = totalCount; 1504 _this.dataCount = dataCount; 1505 return _this; 1506 }; 1507 1508 var _this = {}; 1509 1510 var getRsBlockTable = function(typeNumber, errorCorrectionLevel) { 1511 1512 switch(errorCorrectionLevel) { 1513 case QRErrorCorrectionLevel.L : 1514 return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; 1515 case QRErrorCorrectionLevel.M : 1516 return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; 1517 case QRErrorCorrectionLevel.Q : 1518 return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; 1519 case QRErrorCorrectionLevel.H : 1520 return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; 1521 default : 1522 return undefined; 1523 } 1524 }; 1525 1526 _this.getRSBlocks = function(typeNumber, errorCorrectionLevel) { 1527 1528 var rsBlock = getRsBlockTable(typeNumber, errorCorrectionLevel); 1529 1530 if (typeof rsBlock == 'undefined') { 1531 throw 'bad rs block @ typeNumber:' + typeNumber + 1532 '/errorCorrectionLevel:' + errorCorrectionLevel; 1533 } 1534 1535 var length = rsBlock.length / 3; 1536 1537 var list = []; 1538 1539 for (var i = 0; i < length; i += 1) { 1540 1541 var count = rsBlock[i * 3 + 0]; 1542 var totalCount = rsBlock[i * 3 + 1]; 1543 var dataCount = rsBlock[i * 3 + 2]; 1544 1545 for (var j = 0; j < count; j += 1) { 1546 list.push(qrRSBlock(totalCount, dataCount) ); 1547 } 1548 } 1549 1550 return list; 1551 }; 1552 1553 return _this; 1554 }(); 1555 1556 //--------------------------------------------------------------------- 1557 // qrBitBuffer 1558 //--------------------------------------------------------------------- 1559 1560 var qrBitBuffer = function() { 1561 1562 var _buffer = []; 1563 var _length = 0; 1564 1565 var _this = {}; 1566 1567 _this.getBuffer = function() { 1568 return _buffer; 1569 }; 1570 1571 _this.getAt = function(index) { 1572 var bufIndex = Math.floor(index / 8); 1573 return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1; 1574 }; 1575 1576 _this.put = function(num, length) { 1577 for (var i = 0; i < length; i += 1) { 1578 _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1); 1579 } 1580 }; 1581 1582 _this.getLengthInBits = function() { 1583 return _length; 1584 }; 1585 1586 _this.putBit = function(bit) { 1587 1588 var bufIndex = Math.floor(_length / 8); 1589 if (_buffer.length <= bufIndex) { 1590 _buffer.push(0); 1591 } 1592 1593 if (bit) { 1594 _buffer[bufIndex] |= (0x80 >>> (_length % 8) ); 1595 } 1596 1597 _length += 1; 1598 }; 1599 1600 return _this; 1601 }; 1602 1603 //--------------------------------------------------------------------- 1604 // qrNumber 1605 //--------------------------------------------------------------------- 1606 1607 var qrNumber = function(data) { 1608 1609 var _mode = QRMode.MODE_NUMBER; 1610 var _data = data; 1611 1612 var _this = {}; 1613 1614 _this.getMode = function() { 1615 return _mode; 1616 }; 1617 1618 _this.getLength = function(buffer) { 1619 return _data.length; 1620 }; 1621 1622 _this.write = function(buffer) { 1623 1624 var data = _data; 1625 1626 var i = 0; 1627 1628 while (i + 2 < data.length) { 1629 buffer.put(strToNum(data.substring(i, i + 3) ), 10); 1630 i += 3; 1631 } 1632 1633 if (i < data.length) { 1634 if (data.length - i == 1) { 1635 buffer.put(strToNum(data.substring(i, i + 1) ), 4); 1636 } else if (data.length - i == 2) { 1637 buffer.put(strToNum(data.substring(i, i + 2) ), 7); 1638 } 1639 } 1640 }; 1641 1642 var strToNum = function(s) { 1643 var num = 0; 1644 for (var i = 0; i < s.length; i += 1) { 1645 num = num * 10 + chatToNum(s.charAt(i) ); 1646 } 1647 return num; 1648 }; 1649 1650 var chatToNum = function(c) { 1651 if ('0' <= c && c <= '9') { 1652 return c.charCodeAt(0) - '0'.charCodeAt(0); 1653 } 1654 throw 'illegal char :' + c; 1655 }; 1656 1657 return _this; 1658 }; 1659 1660 //--------------------------------------------------------------------- 1661 // qrAlphaNum 1662 //--------------------------------------------------------------------- 1663 1664 var qrAlphaNum = function(data) { 1665 1666 var _mode = QRMode.MODE_ALPHA_NUM; 1667 var _data = data; 1668 1669 var _this = {}; 1670 1671 _this.getMode = function() { 1672 return _mode; 1673 }; 1674 1675 _this.getLength = function(buffer) { 1676 return _data.length; 1677 }; 1678 1679 _this.write = function(buffer) { 1680 1681 var s = _data; 1682 1683 var i = 0; 1684 1685 while (i + 1 < s.length) { 1686 buffer.put( 1687 getCode(s.charAt(i) ) * 45 + 1688 getCode(s.charAt(i + 1) ), 11); 1689 i += 2; 1690 } 1691 1692 if (i < s.length) { 1693 buffer.put(getCode(s.charAt(i) ), 6); 1694 } 1695 }; 1696 1697 var getCode = function(c) { 1698 1699 if ('0' <= c && c <= '9') { 1700 return c.charCodeAt(0) - '0'.charCodeAt(0); 1701 } else if ('A' <= c && c <= 'Z') { 1702 return c.charCodeAt(0) - 'A'.charCodeAt(0) + 10; 1703 } else { 1704 switch (c) { 1705 case ' ' : return 36; 1706 case '$' : return 37; 1707 case '%' : return 38; 1708 case '*' : return 39; 1709 case '+' : return 40; 1710 case '-' : return 41; 1711 case '.' : return 42; 1712 case '/' : return 43; 1713 case ':' : return 44; 1714 default : 1715 throw 'illegal char :' + c; 1716 } 1717 } 1718 }; 1719 1720 return _this; 1721 }; 1722 1723 //--------------------------------------------------------------------- 1724 // qr8BitByte 1725 //--------------------------------------------------------------------- 1726 1727 var qr8BitByte = function(data) { 1728 1729 var _mode = QRMode.MODE_8BIT_BYTE; 1730 var _data = data; 1731 var _bytes = qrcode.stringToBytes(data); 1732 1733 var _this = {}; 1734 1735 _this.getMode = function() { 1736 return _mode; 1737 }; 1738 1739 _this.getLength = function(buffer) { 1740 return _bytes.length; 1741 }; 1742 1743 _this.write = function(buffer) { 1744 for (var i = 0; i < _bytes.length; i += 1) { 1745 buffer.put(_bytes[i], 8); 1746 } 1747 }; 1748 1749 return _this; 1750 }; 1751 1752 //--------------------------------------------------------------------- 1753 // qrKanji 1754 //--------------------------------------------------------------------- 1755 1756 var qrKanji = function(data) { 1757 1758 var _mode = QRMode.MODE_KANJI; 1759 var _data = data; 1760 1761 var stringToBytes = qrcode.stringToBytesFuncs['SJIS']; 1762 if (!stringToBytes) { 1763 throw 'sjis not supported.'; 1764 } 1765 !function(c, code) { 1766 // self test for sjis support. 1767 var test = stringToBytes(c); 1768 if (test.length != 2 || ( (test[0] << 8) | test[1]) != code) { 1769 throw 'sjis not supported.'; 1770 } 1771 }('\u53cb', 0x9746); 1772 1773 var _bytes = stringToBytes(data); 1774 1775 var _this = {}; 1776 1777 _this.getMode = function() { 1778 return _mode; 1779 }; 1780 1781 _this.getLength = function(buffer) { 1782 return ~~(_bytes.length / 2); 1783 }; 1784 1785 _this.write = function(buffer) { 1786 1787 var data = _bytes; 1788 1789 var i = 0; 1790 1791 while (i + 1 < data.length) { 1792 1793 var c = ( (0xff & data[i]) << 8) | (0xff & data[i + 1]); 1794 1795 if (0x8140 <= c && c <= 0x9FFC) { 1796 c -= 0x8140; 1797 } else if (0xE040 <= c && c <= 0xEBBF) { 1798 c -= 0xC140; 1799 } else { 1800 throw 'illegal char at ' + (i + 1) + '/' + c; 1801 } 1802 1803 c = ( (c >>> 8) & 0xff) * 0xC0 + (c & 0xff); 1804 1805 buffer.put(c, 13); 1806 1807 i += 2; 1808 } 1809 1810 if (i < data.length) { 1811 throw 'illegal char at ' + (i + 1); 1812 } 1813 }; 1814 1815 return _this; 1816 }; 1817 1818 //===================================================================== 1819 // GIF Support etc. 1820 // 1821 1822 //--------------------------------------------------------------------- 1823 // byteArrayOutputStream 1824 //--------------------------------------------------------------------- 1825 1826 var byteArrayOutputStream = function() { 1827 1828 var _bytes = []; 1829 1830 var _this = {}; 1831 1832 _this.writeByte = function(b) { 1833 _bytes.push(b & 0xff); 1834 }; 1835 1836 _this.writeShort = function(i) { 1837 _this.writeByte(i); 1838 _this.writeByte(i >>> 8); 1839 }; 1840 1841 _this.writeBytes = function(b, off, len) { 1842 off = off || 0; 1843 len = len || b.length; 1844 for (var i = 0; i < len; i += 1) { 1845 _this.writeByte(b[i + off]); 1846 } 1847 }; 1848 1849 _this.writeString = function(s) { 1850 for (var i = 0; i < s.length; i += 1) { 1851 _this.writeByte(s.charCodeAt(i) ); 1852 } 1853 }; 1854 1855 _this.toByteArray = function() { 1856 return _bytes; 1857 }; 1858 1859 _this.toString = function() { 1860 var s = ''; 1861 s += '['; 1862 for (var i = 0; i < _bytes.length; i += 1) { 1863 if (i > 0) { 1864 s += ','; 1865 } 1866 s += _bytes[i]; 1867 } 1868 s += ']'; 1869 return s; 1870 }; 1871 1872 return _this; 1873 }; 1874 1875 //--------------------------------------------------------------------- 1876 // base64EncodeOutputStream 1877 //--------------------------------------------------------------------- 1878 1879 var base64EncodeOutputStream = function() { 1880 1881 var _buffer = 0; 1882 var _buflen = 0; 1883 var _length = 0; 1884 var _base64 = ''; 1885 1886 var _this = {}; 1887 1888 var writeEncoded = function(b) { 1889 _base64 += String.fromCharCode(encode(b & 0x3f) ); 1890 }; 1891 1892 var encode = function(n) { 1893 if (n < 0) { 1894 // error. 1895 } else if (n < 26) { 1896 return 0x41 + n; 1897 } else if (n < 52) { 1898 return 0x61 + (n - 26); 1899 } else if (n < 62) { 1900 return 0x30 + (n - 52); 1901 } else if (n == 62) { 1902 return 0x2b; 1903 } else if (n == 63) { 1904 return 0x2f; 1905 } 1906 throw 'n:' + n; 1907 }; 1908 1909 _this.writeByte = function(n) { 1910 1911 _buffer = (_buffer << 8) | (n & 0xff); 1912 _buflen += 8; 1913 _length += 1; 1914 1915 while (_buflen >= 6) { 1916 writeEncoded(_buffer >>> (_buflen - 6) ); 1917 _buflen -= 6; 1918 } 1919 }; 1920 1921 _this.flush = function() { 1922 1923 if (_buflen > 0) { 1924 writeEncoded(_buffer << (6 - _buflen) ); 1925 _buffer = 0; 1926 _buflen = 0; 1927 } 1928 1929 if (_length % 3 != 0) { 1930 // padding 1931 var padlen = 3 - _length % 3; 1932 for (var i = 0; i < padlen; i += 1) { 1933 _base64 += '='; 1934 } 1935 } 1936 }; 1937 1938 _this.toString = function() { 1939 return _base64; 1940 }; 1941 1942 return _this; 1943 }; 1944 1945 //--------------------------------------------------------------------- 1946 // base64DecodeInputStream 1947 //--------------------------------------------------------------------- 1948 1949 var base64DecodeInputStream = function(str) { 1950 1951 var _str = str; 1952 var _pos = 0; 1953 var _buffer = 0; 1954 var _buflen = 0; 1955 1956 var _this = {}; 1957 1958 _this.read = function() { 1959 1960 while (_buflen < 8) { 1961 1962 if (_pos >= _str.length) { 1963 if (_buflen == 0) { 1964 return -1; 1965 } 1966 throw 'unexpected end of file./' + _buflen; 1967 } 1968 1969 var c = _str.charAt(_pos); 1970 _pos += 1; 1971 1972 if (c == '=') { 1973 _buflen = 0; 1974 return -1; 1975 } else if (c.match(/^\s$/) ) { 1976 // ignore if whitespace. 1977 continue; 1978 } 1979 1980 _buffer = (_buffer << 6) | decode(c.charCodeAt(0) ); 1981 _buflen += 6; 1982 } 1983 1984 var n = (_buffer >>> (_buflen - 8) ) & 0xff; 1985 _buflen -= 8; 1986 return n; 1987 }; 1988 1989 var decode = function(c) { 1990 if (0x41 <= c && c <= 0x5a) { 1991 return c - 0x41; 1992 } else if (0x61 <= c && c <= 0x7a) { 1993 return c - 0x61 + 26; 1994 } else if (0x30 <= c && c <= 0x39) { 1995 return c - 0x30 + 52; 1996 } else if (c == 0x2b) { 1997 return 62; 1998 } else if (c == 0x2f) { 1999 return 63; 2000 } else { 2001 throw 'c:' + c; 2002 } 2003 }; 2004 2005 return _this; 2006 }; 2007 2008 //--------------------------------------------------------------------- 2009 // gifImage (B/W) 2010 //--------------------------------------------------------------------- 2011 2012 var gifImage = function(width, height) { 2013 2014 var _width = width; 2015 var _height = height; 2016 var _data = new Array(width * height); 2017 2018 var _this = {}; 2019 2020 _this.setPixel = function(x, y, pixel) { 2021 _data[y * _width + x] = pixel; 2022 }; 2023 2024 _this.write = function(out) { 2025 2026 //--------------------------------- 2027 // GIF Signature 2028 2029 out.writeString('GIF87a'); 2030 2031 //--------------------------------- 2032 // Screen Descriptor 2033 2034 out.writeShort(_width); 2035 out.writeShort(_height); 2036 2037 out.writeByte(0x80); // 2bit 2038 out.writeByte(0); 2039 out.writeByte(0); 2040 2041 //--------------------------------- 2042 // Global Color Map 2043 2044 // black 2045 out.writeByte(0x00); 2046 out.writeByte(0x00); 2047 out.writeByte(0x00); 2048 2049 // white 2050 out.writeByte(0xff); 2051 out.writeByte(0xff); 2052 out.writeByte(0xff); 2053 2054 //--------------------------------- 2055 // Image Descriptor 2056 2057 out.writeString(','); 2058 out.writeShort(0); 2059 out.writeShort(0); 2060 out.writeShort(_width); 2061 out.writeShort(_height); 2062 out.writeByte(0); 2063 2064 //--------------------------------- 2065 // Local Color Map 2066 2067 //--------------------------------- 2068 // Raster Data 2069 2070 var lzwMinCodeSize = 2; 2071 var raster = getLZWRaster(lzwMinCodeSize); 2072 2073 out.writeByte(lzwMinCodeSize); 2074 2075 var offset = 0; 2076 2077 while (raster.length - offset > 255) { 2078 out.writeByte(255); 2079 out.writeBytes(raster, offset, 255); 2080 offset += 255; 2081 } 2082 2083 out.writeByte(raster.length - offset); 2084 out.writeBytes(raster, offset, raster.length - offset); 2085 out.writeByte(0x00); 2086 2087 //--------------------------------- 2088 // GIF Terminator 2089 out.writeString(';'); 2090 }; 2091 2092 var bitOutputStream = function(out) { 2093 2094 var _out = out; 2095 var _bitLength = 0; 2096 var _bitBuffer = 0; 2097 2098 var _this = {}; 2099 2100 _this.write = function(data, length) { 2101 2102 if ( (data >>> length) != 0) { 2103 throw 'length over'; 2104 } 2105 2106 while (_bitLength + length >= 8) { 2107 _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) ); 2108 length -= (8 - _bitLength); 2109 data >>>= (8 - _bitLength); 2110 _bitBuffer = 0; 2111 _bitLength = 0; 2112 } 2113 2114 _bitBuffer = (data << _bitLength) | _bitBuffer; 2115 _bitLength = _bitLength + length; 2116 }; 2117 2118 _this.flush = function() { 2119 if (_bitLength > 0) { 2120 _out.writeByte(_bitBuffer); 2121 } 2122 }; 2123 2124 return _this; 2125 }; 2126 2127 var getLZWRaster = function(lzwMinCodeSize) { 2128 2129 var clearCode = 1 << lzwMinCodeSize; 2130 var endCode = (1 << lzwMinCodeSize) + 1; 2131 var bitLength = lzwMinCodeSize + 1; 2132 2133 // Setup LZWTable 2134 var table = lzwTable(); 2135 2136 for (var i = 0; i < clearCode; i += 1) { 2137 table.add(String.fromCharCode(i) ); 2138 } 2139 table.add(String.fromCharCode(clearCode) ); 2140 table.add(String.fromCharCode(endCode) ); 2141 2142 var byteOut = byteArrayOutputStream(); 2143 var bitOut = bitOutputStream(byteOut); 2144 2145 // clear code 2146 bitOut.write(clearCode, bitLength); 2147 2148 var dataIndex = 0; 2149 2150 var s = String.fromCharCode(_data[dataIndex]); 2151 dataIndex += 1; 2152 2153 while (dataIndex < _data.length) { 2154 2155 var c = String.fromCharCode(_data[dataIndex]); 2156 dataIndex += 1; 2157 2158 if (table.contains(s + c) ) { 2159 2160 s = s + c; 2161 2162 } else { 2163 2164 bitOut.write(table.indexOf(s), bitLength); 2165 2166 if (table.size() < 0xfff) { 2167 2168 if (table.size() == (1 << bitLength) ) { 2169 bitLength += 1; 2170 } 2171 2172 table.add(s + c); 2173 } 2174 2175 s = c; 2176 } 2177 } 2178 2179 bitOut.write(table.indexOf(s), bitLength); 2180 2181 // end code 2182 bitOut.write(endCode, bitLength); 2183 2184 bitOut.flush(); 2185 2186 return byteOut.toByteArray(); 2187 }; 2188 2189 var lzwTable = function() { 2190 2191 var _map = {}; 2192 var _size = 0; 2193 2194 var _this = {}; 2195 2196 _this.add = function(key) { 2197 if (_this.contains(key) ) { 2198 throw 'dup key:' + key; 2199 } 2200 _map[key] = _size; 2201 _size += 1; 2202 }; 2203 2204 _this.size = function() { 2205 return _size; 2206 }; 2207 2208 _this.indexOf = function(key) { 2209 return _map[key]; 2210 }; 2211 2212 _this.contains = function(key) { 2213 return typeof _map[key] != 'undefined'; 2214 }; 2215 2216 return _this; 2217 }; 2218 2219 return _this; 2220 }; 2221 2222 var createDataURL = function(width, height, getPixel) { 2223 var gif = gifImage(width, height); 2224 for (var y = 0; y < height; y += 1) { 2225 for (var x = 0; x < width; x += 1) { 2226 gif.setPixel(x, y, getPixel(x, y) ); 2227 } 2228 } 2229 2230 var b = byteArrayOutputStream(); 2231 gif.write(b); 2232 2233 var base64 = base64EncodeOutputStream(); 2234 var bytes = b.toByteArray(); 2235 for (var i = 0; i < bytes.length; i += 1) { 2236 base64.writeByte(bytes[i]); 2237 } 2238 base64.flush(); 2239 2240 return 'data:image/gif;base64,' + base64; 2241 }; 2242 2243 //--------------------------------------------------------------------- 2244 // returns qrcode function. 2245 2246 return qrcode; 2247 }(); 2248 2249 // multibyte support 2250 !function() { 2251 2252 qrcode.stringToBytesFuncs['UTF-8'] = function(s) { 2253 // http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array 2254 function toUTF8Array(str) { 2255 var utf8 = []; 2256 for (var i=0; i < str.length; i++) { 2257 var charcode = str.charCodeAt(i); 2258 if (charcode < 0x80) utf8.push(charcode); 2259 else if (charcode < 0x800) { 2260 utf8.push(0xc0 | (charcode >> 6), 2261 0x80 | (charcode & 0x3f)); 2262 } 2263 else if (charcode < 0xd800 || charcode >= 0xe000) { 2264 utf8.push(0xe0 | (charcode >> 12), 2265 0x80 | ((charcode>>6) & 0x3f), 2266 0x80 | (charcode & 0x3f)); 2267 } 2268 // surrogate pair 2269 else { 2270 i++; 2271 // UTF-16 encodes 0x10000-0x10FFFF by 2272 // subtracting 0x10000 and splitting the 2273 // 20 bits of 0x0-0xFFFFF into two halves 2274 charcode = 0x10000 + (((charcode & 0x3ff)<<10) 2275 | (str.charCodeAt(i) & 0x3ff)); 2276 utf8.push(0xf0 | (charcode >>18), 2277 0x80 | ((charcode>>12) & 0x3f), 2278 0x80 | ((charcode>>6) & 0x3f), 2279 0x80 | (charcode & 0x3f)); 2280 } 2281 } 2282 return utf8; 2283 } 2284 return toUTF8Array(s); 2285 }; 2286 2287 }(); 2288 2289 (function (factory) { 2290 if (typeof define === 'function' && define.amd) { 2291 define([], factory); 2292 } else if (typeof exports === 'object') { 2293 module.exports = factory(); 2294 } 2295 }(function () { 2296 return qrcode; 2297 }));
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |