qrcode.js 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177
  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. // qrcode
  19. //---------------------------------------------------------------------
  20. /**
  21. * qrcode
  22. * @param typeNumber 1 to 40
  23. * @param errorCorrectionLevel 'L','M','Q','H'
  24. */
  25. export default function qrcode(typeNumber, errorCorrectionLevel) {
  26. var PAD0 = 0xEC;
  27. var PAD1 = 0x11;
  28. var _typeNumber = typeNumber;
  29. var _errorCorrectionLevel = QRErrorCorrectionLevel[errorCorrectionLevel];
  30. var _modules = null;
  31. var _moduleCount = 0;
  32. var _dataCache = null;
  33. var _dataList = [];
  34. var _this = {};
  35. var makeImpl = function(test, maskPattern) {
  36. _moduleCount = _typeNumber * 4 + 17;
  37. _modules = function(moduleCount) {
  38. var modules = new Array(moduleCount);
  39. for (var row = 0; row < moduleCount; row += 1) {
  40. modules[row] = new Array(moduleCount);
  41. for (var col = 0; col < moduleCount; col += 1) {
  42. modules[row][col] = null;
  43. }
  44. }
  45. return modules;
  46. }(_moduleCount);
  47. setupPositionProbePattern(0, 0);
  48. setupPositionProbePattern(_moduleCount - 7, 0);
  49. setupPositionProbePattern(0, _moduleCount - 7);
  50. setupPositionAdjustPattern();
  51. setupTimingPattern();
  52. setupTypeInfo(test, maskPattern);
  53. if (_typeNumber >= 7) {
  54. setupTypeNumber(test);
  55. }
  56. if (_dataCache == null) {
  57. _dataCache = createData(_typeNumber, _errorCorrectionLevel, _dataList);
  58. }
  59. mapData(_dataCache, maskPattern);
  60. };
  61. var setupPositionProbePattern = function(row, col) {
  62. for (var r = -1; r <= 7; r += 1) {
  63. if (row + r <= -1 || _moduleCount <= row + r) continue;
  64. for (var c = -1; c <= 7; c += 1) {
  65. if (col + c <= -1 || _moduleCount <= col + c) continue;
  66. if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )
  67. || (0 <= c && c <= 6 && (r == 0 || r == 6) )
  68. || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {
  69. _modules[row + r][col + c] = true;
  70. } else {
  71. _modules[row + r][col + c] = false;
  72. }
  73. }
  74. }
  75. };
  76. var getBestMaskPattern = function() {
  77. var minLostPoint = 0;
  78. var pattern = 0;
  79. for (var i = 0; i < 8; i += 1) {
  80. makeImpl(true, i);
  81. var lostPoint = QRUtil.getLostPoint(_this);
  82. if (i == 0 || minLostPoint > lostPoint) {
  83. minLostPoint = lostPoint;
  84. pattern = i;
  85. }
  86. }
  87. return pattern;
  88. };
  89. var setupTimingPattern = function() {
  90. for (var r = 8; r < _moduleCount - 8; r += 1) {
  91. if (_modules[r][6] != null) {
  92. continue;
  93. }
  94. _modules[r][6] = (r % 2 == 0);
  95. }
  96. for (var c = 8; c < _moduleCount - 8; c += 1) {
  97. if (_modules[6][c] != null) {
  98. continue;
  99. }
  100. _modules[6][c] = (c % 2 == 0);
  101. }
  102. };
  103. var setupPositionAdjustPattern = function() {
  104. var pos = QRUtil.getPatternPosition(_typeNumber);
  105. for (var i = 0; i < pos.length; i += 1) {
  106. for (var j = 0; j < pos.length; j += 1) {
  107. var row = pos[i];
  108. var col = pos[j];
  109. if (_modules[row][col] != null) {
  110. continue;
  111. }
  112. for (var r = -2; r <= 2; r += 1) {
  113. for (var c = -2; c <= 2; c += 1) {
  114. if (r == -2 || r == 2 || c == -2 || c == 2
  115. || (r == 0 && c == 0) ) {
  116. _modules[row + r][col + c] = true;
  117. } else {
  118. _modules[row + r][col + c] = false;
  119. }
  120. }
  121. }
  122. }
  123. }
  124. };
  125. var setupTypeNumber = function(test) {
  126. var bits = QRUtil.getBCHTypeNumber(_typeNumber);
  127. for (var i = 0; i < 18; i += 1) {
  128. var mod = (!test && ( (bits >> i) & 1) == 1);
  129. _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod;
  130. }
  131. for (var i = 0; i < 18; i += 1) {
  132. var mod = (!test && ( (bits >> i) & 1) == 1);
  133. _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
  134. }
  135. };
  136. var setupTypeInfo = function(test, maskPattern) {
  137. var data = (_errorCorrectionLevel << 3) | maskPattern;
  138. var bits = QRUtil.getBCHTypeInfo(data);
  139. // vertical
  140. for (var i = 0; i < 15; i += 1) {
  141. var mod = (!test && ( (bits >> i) & 1) == 1);
  142. if (i < 6) {
  143. _modules[i][8] = mod;
  144. } else if (i < 8) {
  145. _modules[i + 1][8] = mod;
  146. } else {
  147. _modules[_moduleCount - 15 + i][8] = mod;
  148. }
  149. }
  150. // horizontal
  151. for (var i = 0; i < 15; i += 1) {
  152. var mod = (!test && ( (bits >> i) & 1) == 1);
  153. if (i < 8) {
  154. _modules[8][_moduleCount - i - 1] = mod;
  155. } else if (i < 9) {
  156. _modules[8][15 - i - 1 + 1] = mod;
  157. } else {
  158. _modules[8][15 - i - 1] = mod;
  159. }
  160. }
  161. // fixed module
  162. _modules[_moduleCount - 8][8] = (!test);
  163. };
  164. var mapData = function(data, maskPattern) {
  165. var inc = -1;
  166. var row = _moduleCount - 1;
  167. var bitIndex = 7;
  168. var byteIndex = 0;
  169. var maskFunc = QRUtil.getMaskFunction(maskPattern);
  170. for (var col = _moduleCount - 1; col > 0; col -= 2) {
  171. if (col == 6) col -= 1;
  172. while (true) {
  173. for (var c = 0; c < 2; c += 1) {
  174. if (_modules[row][col - c] == null) {
  175. var dark = false;
  176. if (byteIndex < data.length) {
  177. dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);
  178. }
  179. var mask = maskFunc(row, col - c);
  180. if (mask) {
  181. dark = !dark;
  182. }
  183. _modules[row][col - c] = dark;
  184. bitIndex -= 1;
  185. if (bitIndex == -1) {
  186. byteIndex += 1;
  187. bitIndex = 7;
  188. }
  189. }
  190. }
  191. row += inc;
  192. if (row < 0 || _moduleCount <= row) {
  193. row -= inc;
  194. inc = -inc;
  195. break;
  196. }
  197. }
  198. }
  199. };
  200. var createBytes = function(buffer, rsBlocks) {
  201. var offset = 0;
  202. var maxDcCount = 0;
  203. var maxEcCount = 0;
  204. var dcdata = new Array(rsBlocks.length);
  205. var ecdata = new Array(rsBlocks.length);
  206. for (var r = 0; r < rsBlocks.length; r += 1) {
  207. var dcCount = rsBlocks[r].dataCount;
  208. var ecCount = rsBlocks[r].totalCount - dcCount;
  209. maxDcCount = Math.max(maxDcCount, dcCount);
  210. maxEcCount = Math.max(maxEcCount, ecCount);
  211. dcdata[r] = new Array(dcCount);
  212. for (var i = 0; i < dcdata[r].length; i += 1) {
  213. dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset];
  214. }
  215. offset += dcCount;
  216. var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
  217. var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1);
  218. var modPoly = rawPoly.mod(rsPoly);
  219. ecdata[r] = new Array(rsPoly.getLength() - 1);
  220. for (var i = 0; i < ecdata[r].length; i += 1) {
  221. var modIndex = i + modPoly.getLength() - ecdata[r].length;
  222. ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0;
  223. }
  224. }
  225. var totalCodeCount = 0;
  226. for (var i = 0; i < rsBlocks.length; i += 1) {
  227. totalCodeCount += rsBlocks[i].totalCount;
  228. }
  229. var data = new Array(totalCodeCount);
  230. var index = 0;
  231. for (var i = 0; i < maxDcCount; i += 1) {
  232. for (var r = 0; r < rsBlocks.length; r += 1) {
  233. if (i < dcdata[r].length) {
  234. data[index] = dcdata[r][i];
  235. index += 1;
  236. }
  237. }
  238. }
  239. for (var i = 0; i < maxEcCount; i += 1) {
  240. for (var r = 0; r < rsBlocks.length; r += 1) {
  241. if (i < ecdata[r].length) {
  242. data[index] = ecdata[r][i];
  243. index += 1;
  244. }
  245. }
  246. }
  247. return data;
  248. };
  249. var createData = function(typeNumber, errorCorrectionLevel, dataList) {
  250. var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectionLevel);
  251. var buffer = qrBitBuffer();
  252. for (var i = 0; i < dataList.length; i += 1) {
  253. var data = dataList[i];
  254. buffer.put(data.getMode(), 4);
  255. buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );
  256. data.write(buffer);
  257. }
  258. // calc num max data.
  259. var totalDataCount = 0;
  260. for (var i = 0; i < rsBlocks.length; i += 1) {
  261. totalDataCount += rsBlocks[i].dataCount;
  262. }
  263. if (buffer.getLengthInBits() > totalDataCount * 8) {
  264. throw 'code length overflow. ('
  265. + buffer.getLengthInBits()
  266. + '>'
  267. + totalDataCount * 8
  268. + ')';
  269. }
  270. // end code
  271. if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
  272. buffer.put(0, 4);
  273. }
  274. // padding
  275. while (buffer.getLengthInBits() % 8 != 0) {
  276. buffer.putBit(false);
  277. }
  278. // padding
  279. while (true) {
  280. if (buffer.getLengthInBits() >= totalDataCount * 8) {
  281. break;
  282. }
  283. buffer.put(PAD0, 8);
  284. if (buffer.getLengthInBits() >= totalDataCount * 8) {
  285. break;
  286. }
  287. buffer.put(PAD1, 8);
  288. }
  289. return createBytes(buffer, rsBlocks);
  290. };
  291. _this.addData = function(data, mode) {
  292. mode = mode || 'Byte';
  293. var newData = null;
  294. switch(mode) {
  295. case 'Numeric' :
  296. newData = qrNumber(data);
  297. break;
  298. case 'Alphanumeric' :
  299. newData = qrAlphaNum(data);
  300. break;
  301. case 'Byte' :
  302. newData = qr8BitByte(data);
  303. break;
  304. case 'Kanji' :
  305. newData = qrKanji(data);
  306. break;
  307. default :
  308. throw 'mode:' + mode;
  309. }
  310. _dataList.push(newData);
  311. _dataCache = null;
  312. };
  313. _this.isDark = function(row, col) {
  314. if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) {
  315. throw row + ',' + col;
  316. }
  317. return _modules[row][col];
  318. };
  319. _this.getModuleCount = function() {
  320. return _moduleCount;
  321. };
  322. _this.make = function() {
  323. if (_typeNumber < 1) {
  324. var typeNumber = 1;
  325. for (; typeNumber < 40; typeNumber++) {
  326. var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, _errorCorrectionLevel);
  327. var buffer = qrBitBuffer();
  328. for (var i = 0; i < _dataList.length; i++) {
  329. var data = _dataList[i];
  330. buffer.put(data.getMode(), 4);
  331. buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );
  332. data.write(buffer);
  333. }
  334. var totalDataCount = 0;
  335. for (var i = 0; i < rsBlocks.length; i++) {
  336. totalDataCount += rsBlocks[i].dataCount;
  337. }
  338. if (buffer.getLengthInBits() <= totalDataCount * 8) {
  339. break;
  340. }
  341. }
  342. _typeNumber = typeNumber;
  343. }
  344. makeImpl(false, getBestMaskPattern() );
  345. };
  346. _this.createTableTag = function(cellSize, margin) {
  347. cellSize = cellSize || 2;
  348. margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
  349. var qrHtml = '';
  350. qrHtml += '<table style="';
  351. qrHtml += ' border-width: 0px; border-style: none;';
  352. qrHtml += ' border-collapse: collapse;';
  353. qrHtml += ' padding: 0px; margin: ' + margin + 'px;';
  354. qrHtml += '">';
  355. qrHtml += '<tbody>';
  356. for (var r = 0; r < _this.getModuleCount(); r += 1) {
  357. qrHtml += '<tr>';
  358. for (var c = 0; c < _this.getModuleCount(); c += 1) {
  359. qrHtml += '<td style="';
  360. qrHtml += ' border-width: 0px; border-style: none;';
  361. qrHtml += ' border-collapse: collapse;';
  362. qrHtml += ' padding: 0px; margin: 0px;';
  363. qrHtml += ' width: ' + cellSize + 'px;';
  364. qrHtml += ' height: ' + cellSize + 'px;';
  365. qrHtml += ' background-color: ';
  366. qrHtml += _this.isDark(r, c)? '#000000' : '#ffffff';
  367. qrHtml += ';';
  368. qrHtml += '"/>';
  369. }
  370. qrHtml += '</tr>';
  371. }
  372. qrHtml += '</tbody>';
  373. qrHtml += '</table>';
  374. return qrHtml;
  375. };
  376. _this.createSvgTag = function(cellSize, margin) {
  377. var opts = {};
  378. if (typeof arguments[0] == 'object') {
  379. // Called by options.
  380. opts = arguments[0];
  381. // overwrite cellSize and margin.
  382. cellSize = opts.cellSize;
  383. margin = opts.margin;
  384. }
  385. cellSize = cellSize || 2;
  386. margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
  387. var size = _this.getModuleCount() * cellSize + margin * 2;
  388. var c, mc, r, mr, qrSvg='', rect;
  389. rect = 'l' + cellSize + ',0 0,' + cellSize +
  390. ' -' + cellSize + ',0 0,-' + cellSize + 'z ';
  391. qrSvg += '<svg version="1.1" xmlns="http://www.w3.org/2000/svg"';
  392. qrSvg += !opts.scalable ? ' width="' + size + 'px" height="' + size + 'px"' : '';
  393. qrSvg += ' viewBox="0 0 ' + size + ' ' + size + '" ';
  394. qrSvg += ' preserveAspectRatio="xMinYMin meet">';
  395. qrSvg += '<rect width="100%" height="100%" fill="white" cx="0" cy="0"/>';
  396. qrSvg += '<path d="';
  397. for (r = 0; r < _this.getModuleCount(); r += 1) {
  398. mr = r * cellSize + margin;
  399. for (c = 0; c < _this.getModuleCount(); c += 1) {
  400. if (_this.isDark(r, c) ) {
  401. mc = c*cellSize+margin;
  402. qrSvg += 'M' + mc + ',' + mr + rect;
  403. }
  404. }
  405. }
  406. qrSvg += '" stroke="transparent" fill="black"/>';
  407. qrSvg += '</svg>';
  408. return qrSvg;
  409. };
  410. _this.createDataURL = function(cellSize, margin) {
  411. cellSize = cellSize || 2;
  412. margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
  413. var size = _this.getModuleCount() * cellSize + margin * 2;
  414. var min = margin;
  415. var max = size - margin;
  416. return createDataURL(size, size, function(x, y) {
  417. if (min <= x && x < max && min <= y && y < max) {
  418. var c = Math.floor( (x - min) / cellSize);
  419. var r = Math.floor( (y - min) / cellSize);
  420. return _this.isDark(r, c)? 0 : 1;
  421. } else {
  422. return 1;
  423. }
  424. } );
  425. };
  426. _this.createImgTag = function(cellSize, margin, alt) {
  427. cellSize = cellSize || 2;
  428. margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
  429. var size = _this.getModuleCount() * cellSize + margin * 2;
  430. var img = '';
  431. img += '<img';
  432. img += '\u0020src="';
  433. img += _this.createDataURL(cellSize, margin);
  434. img += '"';
  435. img += '\u0020width="';
  436. img += size;
  437. img += '"';
  438. img += '\u0020height="';
  439. img += size;
  440. img += '"';
  441. if (alt) {
  442. img += '\u0020alt="';
  443. img += alt;
  444. img += '"';
  445. }
  446. img += '/>';
  447. return img;
  448. };
  449. var _createHalfASCII = function(margin) {
  450. var cellSize = 1;
  451. margin = (typeof margin == 'undefined')? cellSize * 2 : margin;
  452. var size = _this.getModuleCount() * cellSize + margin * 2;
  453. var min = margin;
  454. var max = size - margin;
  455. var y, x, r1, r2, p;
  456. var blocks = {
  457. '██': '█',
  458. '█ ': '▀',
  459. ' █': '▄',
  460. ' ': ' '
  461. };
  462. var blocksLastLineNoMargin = {
  463. '██': '▀',
  464. '█ ': '▀',
  465. ' █': ' ',
  466. ' ': ' '
  467. };
  468. var ascii = '';
  469. for (y = 0; y < size; y += 2) {
  470. r1 = Math.floor((y - min) / cellSize);
  471. r2 = Math.floor((y + 1 - min) / cellSize);
  472. for (x = 0; x < size; x += 1) {
  473. p = '█';
  474. if (min <= x && x < max && min <= y && y < max && _this.isDark(r1, Math.floor((x - min) / cellSize))) {
  475. p = ' ';
  476. }
  477. if (min <= x && x < max && min <= y+1 && y+1 < max && _this.isDark(r2, Math.floor((x - min) / cellSize))) {
  478. p += ' ';
  479. }
  480. else {
  481. p += '█';
  482. }
  483. // Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square.
  484. ascii += (margin < 1 && y+1 >= max) ? blocksLastLineNoMargin[p] : blocks[p];
  485. }
  486. ascii += '\n';
  487. }
  488. if (size % 2 && margin > 0) {
  489. return ascii.substring(0, ascii.length - size - 1) + Array(size+1).join('▀');
  490. }
  491. return ascii.substring(0, ascii.length-1);
  492. };
  493. _this.createASCII = function(cellSize, margin) {
  494. cellSize = cellSize || 1;
  495. if (cellSize < 2) {
  496. return _createHalfASCII(margin);
  497. }
  498. cellSize -= 1;
  499. margin = (typeof margin == 'undefined')? cellSize * 2 : margin;
  500. var size = _this.getModuleCount() * cellSize + margin * 2;
  501. var min = margin;
  502. var max = size - margin;
  503. var y, x, r, p;
  504. var white = Array(cellSize+1).join('██');
  505. var black = Array(cellSize+1).join(' ');
  506. var ascii = '';
  507. var line = '';
  508. for (y = 0; y < size; y += 1) {
  509. r = Math.floor( (y - min) / cellSize);
  510. line = '';
  511. for (x = 0; x < size; x += 1) {
  512. p = 1;
  513. if (min <= x && x < max && min <= y && y < max && _this.isDark(r, Math.floor((x - min) / cellSize))) {
  514. p = 0;
  515. }
  516. // Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square.
  517. line += p ? white : black;
  518. }
  519. for (r = 0; r < cellSize; r += 1) {
  520. ascii += line + '\n';
  521. }
  522. }
  523. return ascii.substring(0, ascii.length-1);
  524. };
  525. _this.renderTo2dContext = function(context, cellSize) {
  526. cellSize = cellSize || 2;
  527. var length = _this.getModuleCount();
  528. for (var row = 0; row < length; row++) {
  529. for (var col = 0; col < length; col++) {
  530. context.fillStyle = _this.isDark(row, col) ? 'black' : 'white';
  531. context.fillRect(row * cellSize, col * cellSize, cellSize, cellSize);
  532. }
  533. }
  534. }
  535. return _this;
  536. };
  537. //---------------------------------------------------------------------
  538. // qrcode.stringToBytes
  539. //---------------------------------------------------------------------
  540. qrcode.stringToBytesFuncs = {
  541. 'default' : function(s) {
  542. var bytes = [];
  543. for (var i = 0; i < s.length; i += 1) {
  544. var c = s.charCodeAt(i);
  545. bytes.push(c & 0xff);
  546. }
  547. return bytes;
  548. }
  549. };
  550. qrcode.stringToBytes = qrcode.stringToBytesFuncs['default'];
  551. // /**
  552. // * @param unicodeData base64 string of byte array.
  553. // * [16bit Unicode],[16bit Bytes], ...
  554. // * @param numChars
  555. // */
  556. // qrcode.createStringToBytes = function(unicodeData, numChars) {
  557. //
  558. // // create conversion map.
  559. //
  560. // var unicodeMap = function() {
  561. //
  562. // var bin = base64DecodeInputStream(unicodeData);
  563. // var read = function() {
  564. // var b = bin.read();
  565. // if (b == -1) throw 'eof';
  566. // return b;
  567. // };
  568. //
  569. // var count = 0;
  570. // var unicodeMap = {};
  571. // while (true) {
  572. // var b0 = bin.read();
  573. // if (b0 == -1) break;
  574. // var b1 = read();
  575. // var b2 = read();
  576. // var b3 = read();
  577. // var k = String.fromCharCode( (b0 << 8) | b1);
  578. // var v = (b2 << 8) | b3;
  579. // unicodeMap[k] = v;
  580. // count += 1;
  581. // }
  582. // if (count != numChars) {
  583. // throw count + ' != ' + numChars;
  584. // }
  585. //
  586. // return unicodeMap;
  587. // }();
  588. //
  589. // var unknownChar = '?'.charCodeAt(0);
  590. //
  591. // return function(s) {
  592. // var bytes = [];
  593. // for (var i = 0; i < s.length; i += 1) {
  594. // var c = s.charCodeAt(i);
  595. // if (c < 128) {
  596. // bytes.push(c);
  597. // } else {
  598. // var b = unicodeMap[s.charAt(i)];
  599. // if (typeof b == 'number') {
  600. // if ( (b & 0xff) == b) {
  601. // // 1byte
  602. // bytes.push(b);
  603. // } else {
  604. // // 2bytes
  605. // bytes.push(b >>> 8);
  606. // bytes.push(b & 0xff);
  607. // }
  608. // } else {
  609. // bytes.push(unknownChar);
  610. // }
  611. // }
  612. // }
  613. // return bytes;
  614. // };
  615. // };
  616. //---------------------------------------------------------------------
  617. // QRMode
  618. //---------------------------------------------------------------------
  619. var QRMode = {
  620. MODE_NUMBER : 1 << 0,
  621. MODE_ALPHA_NUM : 1 << 1,
  622. MODE_8BIT_BYTE : 1 << 2,
  623. MODE_KANJI : 1 << 3
  624. };
  625. //---------------------------------------------------------------------
  626. // QRErrorCorrectionLevel
  627. //---------------------------------------------------------------------
  628. var QRErrorCorrectionLevel = {
  629. L : 1,
  630. M : 0,
  631. Q : 3,
  632. H : 2
  633. };
  634. //---------------------------------------------------------------------
  635. // QRMaskPattern
  636. //---------------------------------------------------------------------
  637. var QRMaskPattern = {
  638. PATTERN000 : 0,
  639. PATTERN001 : 1,
  640. PATTERN010 : 2,
  641. PATTERN011 : 3,
  642. PATTERN100 : 4,
  643. PATTERN101 : 5,
  644. PATTERN110 : 6,
  645. PATTERN111 : 7
  646. };
  647. //---------------------------------------------------------------------
  648. // QRUtil
  649. //---------------------------------------------------------------------
  650. var QRUtil = function() {
  651. var PATTERN_POSITION_TABLE = [
  652. [],
  653. [6, 18],
  654. [6, 22],
  655. [6, 26],
  656. [6, 30],
  657. [6, 34],
  658. [6, 22, 38],
  659. [6, 24, 42],
  660. [6, 26, 46],
  661. [6, 28, 50],
  662. [6, 30, 54],
  663. [6, 32, 58],
  664. [6, 34, 62],
  665. [6, 26, 46, 66],
  666. [6, 26, 48, 70],
  667. [6, 26, 50, 74],
  668. [6, 30, 54, 78],
  669. [6, 30, 56, 82],
  670. [6, 30, 58, 86],
  671. [6, 34, 62, 90],
  672. [6, 28, 50, 72, 94],
  673. [6, 26, 50, 74, 98],
  674. [6, 30, 54, 78, 102],
  675. [6, 28, 54, 80, 106],
  676. [6, 32, 58, 84, 110],
  677. [6, 30, 58, 86, 114],
  678. [6, 34, 62, 90, 118],
  679. [6, 26, 50, 74, 98, 122],
  680. [6, 30, 54, 78, 102, 126],
  681. [6, 26, 52, 78, 104, 130],
  682. [6, 30, 56, 82, 108, 134],
  683. [6, 34, 60, 86, 112, 138],
  684. [6, 30, 58, 86, 114, 142],
  685. [6, 34, 62, 90, 118, 146],
  686. [6, 30, 54, 78, 102, 126, 150],
  687. [6, 24, 50, 76, 102, 128, 154],
  688. [6, 28, 54, 80, 106, 132, 158],
  689. [6, 32, 58, 84, 110, 136, 162],
  690. [6, 26, 54, 82, 110, 138, 166],
  691. [6, 30, 58, 86, 114, 142, 170]
  692. ];
  693. var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);
  694. var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0);
  695. var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1);
  696. var _this = {};
  697. var getBCHDigit = function(data) {
  698. var digit = 0;
  699. while (data != 0) {
  700. digit += 1;
  701. data >>>= 1;
  702. }
  703. return digit;
  704. };
  705. _this.getBCHTypeInfo = function(data) {
  706. var d = data << 10;
  707. while (getBCHDigit(d) - getBCHDigit(G15) >= 0) {
  708. d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) );
  709. }
  710. return ( (data << 10) | d) ^ G15_MASK;
  711. };
  712. _this.getBCHTypeNumber = function(data) {
  713. var d = data << 12;
  714. while (getBCHDigit(d) - getBCHDigit(G18) >= 0) {
  715. d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) );
  716. }
  717. return (data << 12) | d;
  718. };
  719. _this.getPatternPosition = function(typeNumber) {
  720. return PATTERN_POSITION_TABLE[typeNumber - 1];
  721. };
  722. _this.getMaskFunction = function(maskPattern) {
  723. switch (maskPattern) {
  724. case QRMaskPattern.PATTERN000 :
  725. return function(i, j) { return (i + j) % 2 == 0; };
  726. case QRMaskPattern.PATTERN001 :
  727. return function(i, j) { return i % 2 == 0; };
  728. case QRMaskPattern.PATTERN010 :
  729. return function(i, j) { return j % 3 == 0; };
  730. case QRMaskPattern.PATTERN011 :
  731. return function(i, j) { return (i + j) % 3 == 0; };
  732. case QRMaskPattern.PATTERN100 :
  733. return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; };
  734. case QRMaskPattern.PATTERN101 :
  735. return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; };
  736. case QRMaskPattern.PATTERN110 :
  737. return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; };
  738. case QRMaskPattern.PATTERN111 :
  739. return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; };
  740. default :
  741. throw 'bad maskPattern:' + maskPattern;
  742. }
  743. };
  744. _this.getErrorCorrectPolynomial = function(errorCorrectLength) {
  745. var a = qrPolynomial([1], 0);
  746. for (var i = 0; i < errorCorrectLength; i += 1) {
  747. a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) );
  748. }
  749. return a;
  750. };
  751. _this.getLengthInBits = function(mode, type) {
  752. if (1 <= type && type < 10) {
  753. // 1 - 9
  754. switch(mode) {
  755. case QRMode.MODE_NUMBER : return 10;
  756. case QRMode.MODE_ALPHA_NUM : return 9;
  757. case QRMode.MODE_8BIT_BYTE : return 8;
  758. case QRMode.MODE_KANJI : return 8;
  759. default :
  760. throw 'mode:' + mode;
  761. }
  762. } else if (type < 27) {
  763. // 10 - 26
  764. switch(mode) {
  765. case QRMode.MODE_NUMBER : return 12;
  766. case QRMode.MODE_ALPHA_NUM : return 11;
  767. case QRMode.MODE_8BIT_BYTE : return 16;
  768. case QRMode.MODE_KANJI : return 10;
  769. default :
  770. throw 'mode:' + mode;
  771. }
  772. } else if (type < 41) {
  773. // 27 - 40
  774. switch(mode) {
  775. case QRMode.MODE_NUMBER : return 14;
  776. case QRMode.MODE_ALPHA_NUM : return 13;
  777. case QRMode.MODE_8BIT_BYTE : return 16;
  778. case QRMode.MODE_KANJI : return 12;
  779. default :
  780. throw 'mode:' + mode;
  781. }
  782. } else {
  783. throw 'type:' + type;
  784. }
  785. };
  786. _this.getLostPoint = function(qrcode) {
  787. var moduleCount = qrcode.getModuleCount();
  788. var lostPoint = 0;
  789. // LEVEL1
  790. for (var row = 0; row < moduleCount; row += 1) {
  791. for (var col = 0; col < moduleCount; col += 1) {
  792. var sameCount = 0;
  793. var dark = qrcode.isDark(row, col);
  794. for (var r = -1; r <= 1; r += 1) {
  795. if (row + r < 0 || moduleCount <= row + r) {
  796. continue;
  797. }
  798. for (var c = -1; c <= 1; c += 1) {
  799. if (col + c < 0 || moduleCount <= col + c) {
  800. continue;
  801. }
  802. if (r == 0 && c == 0) {
  803. continue;
  804. }
  805. if (dark == qrcode.isDark(row + r, col + c) ) {
  806. sameCount += 1;
  807. }
  808. }
  809. }
  810. if (sameCount > 5) {
  811. lostPoint += (3 + sameCount - 5);
  812. }
  813. }
  814. };
  815. // LEVEL2
  816. for (var row = 0; row < moduleCount - 1; row += 1) {
  817. for (var col = 0; col < moduleCount - 1; col += 1) {
  818. var count = 0;
  819. if (qrcode.isDark(row, col) ) count += 1;
  820. if (qrcode.isDark(row + 1, col) ) count += 1;
  821. if (qrcode.isDark(row, col + 1) ) count += 1;
  822. if (qrcode.isDark(row + 1, col + 1) ) count += 1;
  823. if (count == 0 || count == 4) {
  824. lostPoint += 3;
  825. }
  826. }
  827. }
  828. // LEVEL3
  829. for (var row = 0; row < moduleCount; row += 1) {
  830. for (var col = 0; col < moduleCount - 6; col += 1) {
  831. if (qrcode.isDark(row, col)
  832. && !qrcode.isDark(row, col + 1)
  833. && qrcode.isDark(row, col + 2)
  834. && qrcode.isDark(row, col + 3)
  835. && qrcode.isDark(row, col + 4)
  836. && !qrcode.isDark(row, col + 5)
  837. && qrcode.isDark(row, col + 6) ) {
  838. lostPoint += 40;
  839. }
  840. }
  841. }
  842. for (var col = 0; col < moduleCount; col += 1) {
  843. for (var row = 0; row < moduleCount - 6; row += 1) {
  844. if (qrcode.isDark(row, col)
  845. && !qrcode.isDark(row + 1, col)
  846. && qrcode.isDark(row + 2, col)
  847. && qrcode.isDark(row + 3, col)
  848. && qrcode.isDark(row + 4, col)
  849. && !qrcode.isDark(row + 5, col)
  850. && qrcode.isDark(row + 6, col) ) {
  851. lostPoint += 40;
  852. }
  853. }
  854. }
  855. // LEVEL4
  856. var darkCount = 0;
  857. for (var col = 0; col < moduleCount; col += 1) {
  858. for (var row = 0; row < moduleCount; row += 1) {
  859. if (qrcode.isDark(row, col) ) {
  860. darkCount += 1;
  861. }
  862. }
  863. }
  864. var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
  865. lostPoint += ratio * 10;
  866. return lostPoint;
  867. };
  868. return _this;
  869. }();
  870. //---------------------------------------------------------------------
  871. // QRMath
  872. //---------------------------------------------------------------------
  873. var QRMath = function() {
  874. var EXP_TABLE = new Array(256);
  875. var LOG_TABLE = new Array(256);
  876. // initialize tables
  877. for (var i = 0; i < 8; i += 1) {
  878. EXP_TABLE[i] = 1 << i;
  879. }
  880. for (var i = 8; i < 256; i += 1) {
  881. EXP_TABLE[i] = EXP_TABLE[i - 4]
  882. ^ EXP_TABLE[i - 5]
  883. ^ EXP_TABLE[i - 6]
  884. ^ EXP_TABLE[i - 8];
  885. }
  886. for (var i = 0; i < 255; i += 1) {
  887. LOG_TABLE[EXP_TABLE[i] ] = i;
  888. }
  889. var _this = {};
  890. _this.glog = function(n) {
  891. if (n < 1) {
  892. throw 'glog(' + n + ')';
  893. }
  894. return LOG_TABLE[n];
  895. };
  896. _this.gexp = function(n) {
  897. while (n < 0) {
  898. n += 255;
  899. }
  900. while (n >= 256) {
  901. n -= 255;
  902. }
  903. return EXP_TABLE[n];
  904. };
  905. return _this;
  906. }();
  907. //---------------------------------------------------------------------
  908. // qrPolynomial
  909. //---------------------------------------------------------------------
  910. function qrPolynomial(num, shift) {
  911. if (typeof num.length == 'undefined') {
  912. throw num.length + '/' + shift;
  913. }
  914. var _num = function() {
  915. var offset = 0;
  916. while (offset < num.length && num[offset] == 0) {
  917. offset += 1;
  918. }
  919. var _num = new Array(num.length - offset + shift);
  920. for (var i = 0; i < num.length - offset; i += 1) {
  921. _num[i] = num[i + offset];
  922. }
  923. return _num;
  924. }();
  925. var _this = {};
  926. _this.getAt = function(index) {
  927. return _num[index];
  928. };
  929. _this.getLength = function() {
  930. return _num.length;
  931. };
  932. _this.multiply = function(e) {
  933. var num = new Array(_this.getLength() + e.getLength() - 1);
  934. for (var i = 0; i < _this.getLength(); i += 1) {
  935. for (var j = 0; j < e.getLength(); j += 1) {
  936. num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) );
  937. }
  938. }
  939. return qrPolynomial(num, 0);
  940. };
  941. _this.mod = function(e) {
  942. if (_this.getLength() - e.getLength() < 0) {
  943. return _this;
  944. }
  945. var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) );
  946. var num = new Array(_this.getLength() );
  947. for (var i = 0; i < _this.getLength(); i += 1) {
  948. num[i] = _this.getAt(i);
  949. }
  950. for (var i = 0; i < e.getLength(); i += 1) {
  951. num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio);
  952. }
  953. // recursive call
  954. return qrPolynomial(num, 0).mod(e);
  955. };
  956. return _this;
  957. };
  958. //---------------------------------------------------------------------
  959. // QRRSBlock
  960. //---------------------------------------------------------------------
  961. var QRRSBlock = function() {
  962. var RS_BLOCK_TABLE = [
  963. // L
  964. // M
  965. // Q
  966. // H
  967. // 1
  968. [1, 26, 19],
  969. [1, 26, 16],
  970. [1, 26, 13],
  971. [1, 26, 9],
  972. // 2
  973. [1, 44, 34],
  974. [1, 44, 28],
  975. [1, 44, 22],
  976. [1, 44, 16],
  977. // 3
  978. [1, 70, 55],
  979. [1, 70, 44],
  980. [2, 35, 17],
  981. [2, 35, 13],
  982. // 4
  983. [1, 100, 80],
  984. [2, 50, 32],
  985. [2, 50, 24],
  986. [4, 25, 9],
  987. // 5
  988. [1, 134, 108],
  989. [2, 67, 43],
  990. [2, 33, 15, 2, 34, 16],
  991. [2, 33, 11, 2, 34, 12],
  992. // 6
  993. [2, 86, 68],
  994. [4, 43, 27],
  995. [4, 43, 19],
  996. [4, 43, 15],
  997. // 7
  998. [2, 98, 78],
  999. [4, 49, 31],
  1000. [2, 32, 14, 4, 33, 15],
  1001. [4, 39, 13, 1, 40, 14],
  1002. // 8
  1003. [2, 121, 97],
  1004. [2, 60, 38, 2, 61, 39],
  1005. [4, 40, 18, 2, 41, 19],
  1006. [4, 40, 14, 2, 41, 15],
  1007. // 9
  1008. [2, 146, 116],
  1009. [3, 58, 36, 2, 59, 37],
  1010. [4, 36, 16, 4, 37, 17],
  1011. [4, 36, 12, 4, 37, 13],
  1012. // 10
  1013. [2, 86, 68, 2, 87, 69],
  1014. [4, 69, 43, 1, 70, 44],
  1015. [6, 43, 19, 2, 44, 20],
  1016. [6, 43, 15, 2, 44, 16],
  1017. // 11
  1018. [4, 101, 81],
  1019. [1, 80, 50, 4, 81, 51],
  1020. [4, 50, 22, 4, 51, 23],
  1021. [3, 36, 12, 8, 37, 13],
  1022. // 12
  1023. [2, 116, 92, 2, 117, 93],
  1024. [6, 58, 36, 2, 59, 37],
  1025. [4, 46, 20, 6, 47, 21],
  1026. [7, 42, 14, 4, 43, 15],
  1027. // 13
  1028. [4, 133, 107],
  1029. [8, 59, 37, 1, 60, 38],
  1030. [8, 44, 20, 4, 45, 21],
  1031. [12, 33, 11, 4, 34, 12],
  1032. // 14
  1033. [3, 145, 115, 1, 146, 116],
  1034. [4, 64, 40, 5, 65, 41],
  1035. [11, 36, 16, 5, 37, 17],
  1036. [11, 36, 12, 5, 37, 13],
  1037. // 15
  1038. [5, 109, 87, 1, 110, 88],
  1039. [5, 65, 41, 5, 66, 42],
  1040. [5, 54, 24, 7, 55, 25],
  1041. [11, 36, 12, 7, 37, 13],
  1042. // 16
  1043. [5, 122, 98, 1, 123, 99],
  1044. [7, 73, 45, 3, 74, 46],
  1045. [15, 43, 19, 2, 44, 20],
  1046. [3, 45, 15, 13, 46, 16],
  1047. // 17
  1048. [1, 135, 107, 5, 136, 108],
  1049. [10, 74, 46, 1, 75, 47],
  1050. [1, 50, 22, 15, 51, 23],
  1051. [2, 42, 14, 17, 43, 15],
  1052. // 18
  1053. [5, 150, 120, 1, 151, 121],
  1054. [9, 69, 43, 4, 70, 44],
  1055. [17, 50, 22, 1, 51, 23],
  1056. [2, 42, 14, 19, 43, 15],
  1057. // 19
  1058. [3, 141, 113, 4, 142, 114],
  1059. [3, 70, 44, 11, 71, 45],
  1060. [17, 47, 21, 4, 48, 22],
  1061. [9, 39, 13, 16, 40, 14],
  1062. // 20
  1063. [3, 135, 107, 5, 136, 108],
  1064. [3, 67, 41, 13, 68, 42],
  1065. [15, 54, 24, 5, 55, 25],
  1066. [15, 43, 15, 10, 44, 16],
  1067. // 21
  1068. [4, 144, 116, 4, 145, 117],
  1069. [17, 68, 42],
  1070. [17, 50, 22, 6, 51, 23],
  1071. [19, 46, 16, 6, 47, 17],
  1072. // 22
  1073. [2, 139, 111, 7, 140, 112],
  1074. [17, 74, 46],
  1075. [7, 54, 24, 16, 55, 25],
  1076. [34, 37, 13],
  1077. // 23
  1078. [4, 151, 121, 5, 152, 122],
  1079. [4, 75, 47, 14, 76, 48],
  1080. [11, 54, 24, 14, 55, 25],
  1081. [16, 45, 15, 14, 46, 16],
  1082. // 24
  1083. [6, 147, 117, 4, 148, 118],
  1084. [6, 73, 45, 14, 74, 46],
  1085. [11, 54, 24, 16, 55, 25],
  1086. [30, 46, 16, 2, 47, 17],
  1087. // 25
  1088. [8, 132, 106, 4, 133, 107],
  1089. [8, 75, 47, 13, 76, 48],
  1090. [7, 54, 24, 22, 55, 25],
  1091. [22, 45, 15, 13, 46, 16],
  1092. // 26
  1093. [10, 142, 114, 2, 143, 115],
  1094. [19, 74, 46, 4, 75, 47],
  1095. [28, 50, 22, 6, 51, 23],
  1096. [33, 46, 16, 4, 47, 17],
  1097. // 27
  1098. [8, 152, 122, 4, 153, 123],
  1099. [22, 73, 45, 3, 74, 46],
  1100. [8, 53, 23, 26, 54, 24],
  1101. [12, 45, 15, 28, 46, 16],
  1102. // 28
  1103. [3, 147, 117, 10, 148, 118],
  1104. [3, 73, 45, 23, 74, 46],
  1105. [4, 54, 24, 31, 55, 25],
  1106. [11, 45, 15, 31, 46, 16],
  1107. // 29
  1108. [7, 146, 116, 7, 147, 117],
  1109. [21, 73, 45, 7, 74, 46],
  1110. [1, 53, 23, 37, 54, 24],
  1111. [19, 45, 15, 26, 46, 16],
  1112. // 30
  1113. [5, 145, 115, 10, 146, 116],
  1114. [19, 75, 47, 10, 76, 48],
  1115. [15, 54, 24, 25, 55, 25],
  1116. [23, 45, 15, 25, 46, 16],
  1117. // 31
  1118. [13, 145, 115, 3, 146, 116],
  1119. [2, 74, 46, 29, 75, 47],
  1120. [42, 54, 24, 1, 55, 25],
  1121. [23, 45, 15, 28, 46, 16],
  1122. // 32
  1123. [17, 145, 115],
  1124. [10, 74, 46, 23, 75, 47],
  1125. [10, 54, 24, 35, 55, 25],
  1126. [19, 45, 15, 35, 46, 16],
  1127. // 33
  1128. [17, 145, 115, 1, 146, 116],
  1129. [14, 74, 46, 21, 75, 47],
  1130. [29, 54, 24, 19, 55, 25],
  1131. [11, 45, 15, 46, 46, 16],
  1132. // 34
  1133. [13, 145, 115, 6, 146, 116],
  1134. [14, 74, 46, 23, 75, 47],
  1135. [44, 54, 24, 7, 55, 25],
  1136. [59, 46, 16, 1, 47, 17],
  1137. // 35
  1138. [12, 151, 121, 7, 152, 122],
  1139. [12, 75, 47, 26, 76, 48],
  1140. [39, 54, 24, 14, 55, 25],
  1141. [22, 45, 15, 41, 46, 16],
  1142. // 36
  1143. [6, 151, 121, 14, 152, 122],
  1144. [6, 75, 47, 34, 76, 48],
  1145. [46, 54, 24, 10, 55, 25],
  1146. [2, 45, 15, 64, 46, 16],
  1147. // 37
  1148. [17, 152, 122, 4, 153, 123],
  1149. [29, 74, 46, 14, 75, 47],
  1150. [49, 54, 24, 10, 55, 25],
  1151. [24, 45, 15, 46, 46, 16],
  1152. // 38
  1153. [4, 152, 122, 18, 153, 123],
  1154. [13, 74, 46, 32, 75, 47],
  1155. [48, 54, 24, 14, 55, 25],
  1156. [42, 45, 15, 32, 46, 16],
  1157. // 39
  1158. [20, 147, 117, 4, 148, 118],
  1159. [40, 75, 47, 7, 76, 48],
  1160. [43, 54, 24, 22, 55, 25],
  1161. [10, 45, 15, 67, 46, 16],
  1162. // 40
  1163. [19, 148, 118, 6, 149, 119],
  1164. [18, 75, 47, 31, 76, 48],
  1165. [34, 54, 24, 34, 55, 25],
  1166. [20, 45, 15, 61, 46, 16]
  1167. ];
  1168. var qrRSBlock = function(totalCount, dataCount) {
  1169. var _this = {};
  1170. _this.totalCount = totalCount;
  1171. _this.dataCount = dataCount;
  1172. return _this;
  1173. };
  1174. var _this = {};
  1175. var getRsBlockTable = function(typeNumber, errorCorrectionLevel) {
  1176. switch(errorCorrectionLevel) {
  1177. case QRErrorCorrectionLevel.L :
  1178. return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
  1179. case QRErrorCorrectionLevel.M :
  1180. return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
  1181. case QRErrorCorrectionLevel.Q :
  1182. return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
  1183. case QRErrorCorrectionLevel.H :
  1184. return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
  1185. default :
  1186. return undefined;
  1187. }
  1188. };
  1189. _this.getRSBlocks = function(typeNumber, errorCorrectionLevel) {
  1190. var rsBlock = getRsBlockTable(typeNumber, errorCorrectionLevel);
  1191. if (typeof rsBlock == 'undefined') {
  1192. throw 'bad rs block @ typeNumber:' + typeNumber +
  1193. '/errorCorrectionLevel:' + errorCorrectionLevel;
  1194. }
  1195. var length = rsBlock.length / 3;
  1196. var list = [];
  1197. for (var i = 0; i < length; i += 1) {
  1198. var count = rsBlock[i * 3 + 0];
  1199. var totalCount = rsBlock[i * 3 + 1];
  1200. var dataCount = rsBlock[i * 3 + 2];
  1201. for (var j = 0; j < count; j += 1) {
  1202. list.push(qrRSBlock(totalCount, dataCount) );
  1203. }
  1204. }
  1205. return list;
  1206. };
  1207. return _this;
  1208. }();
  1209. //---------------------------------------------------------------------
  1210. // qrBitBuffer
  1211. //---------------------------------------------------------------------
  1212. var qrBitBuffer = function() {
  1213. var _buffer = [];
  1214. var _length = 0;
  1215. var _this = {};
  1216. _this.getBuffer = function() {
  1217. return _buffer;
  1218. };
  1219. _this.getAt = function(index) {
  1220. var bufIndex = Math.floor(index / 8);
  1221. return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;
  1222. };
  1223. _this.put = function(num, length) {
  1224. for (var i = 0; i < length; i += 1) {
  1225. _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);
  1226. }
  1227. };
  1228. _this.getLengthInBits = function() {
  1229. return _length;
  1230. };
  1231. _this.putBit = function(bit) {
  1232. var bufIndex = Math.floor(_length / 8);
  1233. if (_buffer.length <= bufIndex) {
  1234. _buffer.push(0);
  1235. }
  1236. if (bit) {
  1237. _buffer[bufIndex] |= (0x80 >>> (_length % 8) );
  1238. }
  1239. _length += 1;
  1240. };
  1241. return _this;
  1242. };
  1243. //---------------------------------------------------------------------
  1244. // qrNumber
  1245. //---------------------------------------------------------------------
  1246. var qrNumber = function(data) {
  1247. var _mode = QRMode.MODE_NUMBER;
  1248. var _data = data;
  1249. var _this = {};
  1250. _this.getMode = function() {
  1251. return _mode;
  1252. };
  1253. _this.getLength = function(buffer) {
  1254. return _data.length;
  1255. };
  1256. _this.write = function(buffer) {
  1257. var data = _data;
  1258. var i = 0;
  1259. while (i + 2 < data.length) {
  1260. buffer.put(strToNum(data.substring(i, i + 3) ), 10);
  1261. i += 3;
  1262. }
  1263. if (i < data.length) {
  1264. if (data.length - i == 1) {
  1265. buffer.put(strToNum(data.substring(i, i + 1) ), 4);
  1266. } else if (data.length - i == 2) {
  1267. buffer.put(strToNum(data.substring(i, i + 2) ), 7);
  1268. }
  1269. }
  1270. };
  1271. var strToNum = function(s) {
  1272. var num = 0;
  1273. for (var i = 0; i < s.length; i += 1) {
  1274. num = num * 10 + chatToNum(s.charAt(i) );
  1275. }
  1276. return num;
  1277. };
  1278. var chatToNum = function(c) {
  1279. if ('0' <= c && c <= '9') {
  1280. return c.charCodeAt(0) - '0'.charCodeAt(0);
  1281. }
  1282. throw 'illegal char :' + c;
  1283. };
  1284. return _this;
  1285. };
  1286. //---------------------------------------------------------------------
  1287. // qrAlphaNum
  1288. //---------------------------------------------------------------------
  1289. var qrAlphaNum = function(data) {
  1290. var _mode = QRMode.MODE_ALPHA_NUM;
  1291. var _data = data;
  1292. var _this = {};
  1293. _this.getMode = function() {
  1294. return _mode;
  1295. };
  1296. _this.getLength = function(buffer) {
  1297. return _data.length;
  1298. };
  1299. _this.write = function(buffer) {
  1300. var s = _data;
  1301. var i = 0;
  1302. while (i + 1 < s.length) {
  1303. buffer.put(
  1304. getCode(s.charAt(i) ) * 45 +
  1305. getCode(s.charAt(i + 1) ), 11);
  1306. i += 2;
  1307. }
  1308. if (i < s.length) {
  1309. buffer.put(getCode(s.charAt(i) ), 6);
  1310. }
  1311. };
  1312. var getCode = function(c) {
  1313. if ('0' <= c && c <= '9') {
  1314. return c.charCodeAt(0) - '0'.charCodeAt(0);
  1315. } else if ('A' <= c && c <= 'Z') {
  1316. return c.charCodeAt(0) - 'A'.charCodeAt(0) + 10;
  1317. } else {
  1318. switch (c) {
  1319. case ' ' : return 36;
  1320. case '$' : return 37;
  1321. case '%' : return 38;
  1322. case '*' : return 39;
  1323. case '+' : return 40;
  1324. case '-' : return 41;
  1325. case '.' : return 42;
  1326. case '/' : return 43;
  1327. case ':' : return 44;
  1328. default :
  1329. throw 'illegal char :' + c;
  1330. }
  1331. }
  1332. };
  1333. return _this;
  1334. };
  1335. //---------------------------------------------------------------------
  1336. // qr8BitByte
  1337. //---------------------------------------------------------------------
  1338. var qr8BitByte = function(data) {
  1339. var _mode = QRMode.MODE_8BIT_BYTE;
  1340. var _data = data;
  1341. var _bytes = qrcode.stringToBytes(data);
  1342. var _this = {};
  1343. _this.getMode = function() {
  1344. return _mode;
  1345. };
  1346. _this.getLength = function(buffer) {
  1347. return _bytes.length;
  1348. };
  1349. _this.write = function(buffer) {
  1350. for (var i = 0; i < _bytes.length; i += 1) {
  1351. buffer.put(_bytes[i], 8);
  1352. }
  1353. };
  1354. return _this;
  1355. };
  1356. //---------------------------------------------------------------------
  1357. // qrKanji
  1358. //---------------------------------------------------------------------
  1359. var qrKanji = function(data) {
  1360. var _mode = QRMode.MODE_KANJI;
  1361. var _data = data;
  1362. var stringToBytes = qrcode.stringToBytesFuncs['SJIS'];
  1363. if (!stringToBytes) {
  1364. throw 'sjis not supported.';
  1365. }
  1366. !function(c, code) {
  1367. // self test for sjis support.
  1368. var test = stringToBytes(c);
  1369. if (test.length != 2 || ( (test[0] << 8) | test[1]) != code) {
  1370. throw 'sjis not supported.';
  1371. }
  1372. }('\u53cb', 0x9746);
  1373. var _bytes = stringToBytes(data);
  1374. var _this = {};
  1375. _this.getMode = function() {
  1376. return _mode;
  1377. };
  1378. _this.getLength = function(buffer) {
  1379. return ~~(_bytes.length / 2);
  1380. };
  1381. _this.write = function(buffer) {
  1382. var data = _bytes;
  1383. var i = 0;
  1384. while (i + 1 < data.length) {
  1385. var c = ( (0xff & data[i]) << 8) | (0xff & data[i + 1]);
  1386. if (0x8140 <= c && c <= 0x9FFC) {
  1387. c -= 0x8140;
  1388. } else if (0xE040 <= c && c <= 0xEBBF) {
  1389. c -= 0xC140;
  1390. } else {
  1391. throw 'illegal char at ' + (i + 1) + '/' + c;
  1392. }
  1393. c = ( (c >>> 8) & 0xff) * 0xC0 + (c & 0xff);
  1394. buffer.put(c, 13);
  1395. i += 2;
  1396. }
  1397. if (i < data.length) {
  1398. throw 'illegal char at ' + (i + 1);
  1399. }
  1400. };
  1401. return _this;
  1402. };
  1403. //=====================================================================
  1404. // GIF Support etc.
  1405. //
  1406. //---------------------------------------------------------------------
  1407. // byteArrayOutputStream
  1408. //---------------------------------------------------------------------
  1409. var byteArrayOutputStream = function() {
  1410. var _bytes = [];
  1411. var _this = {};
  1412. _this.writeByte = function(b) {
  1413. _bytes.push(b & 0xff);
  1414. };
  1415. _this.writeShort = function(i) {
  1416. _this.writeByte(i);
  1417. _this.writeByte(i >>> 8);
  1418. };
  1419. _this.writeBytes = function(b, off, len) {
  1420. off = off || 0;
  1421. len = len || b.length;
  1422. for (var i = 0; i < len; i += 1) {
  1423. _this.writeByte(b[i + off]);
  1424. }
  1425. };
  1426. _this.writeString = function(s) {
  1427. for (var i = 0; i < s.length; i += 1) {
  1428. _this.writeByte(s.charCodeAt(i) );
  1429. }
  1430. };
  1431. _this.toByteArray = function() {
  1432. return _bytes;
  1433. };
  1434. _this.toString = function() {
  1435. var s = '';
  1436. s += '[';
  1437. for (var i = 0; i < _bytes.length; i += 1) {
  1438. if (i > 0) {
  1439. s += ',';
  1440. }
  1441. s += _bytes[i];
  1442. }
  1443. s += ']';
  1444. return s;
  1445. };
  1446. return _this;
  1447. };
  1448. //---------------------------------------------------------------------
  1449. // base64EncodeOutputStream
  1450. //---------------------------------------------------------------------
  1451. var base64EncodeOutputStream = function() {
  1452. var _buffer = 0;
  1453. var _buflen = 0;
  1454. var _length = 0;
  1455. var _base64 = '';
  1456. var _this = {};
  1457. var writeEncoded = function(b) {
  1458. _base64 += String.fromCharCode(encode(b & 0x3f) );
  1459. };
  1460. var encode = function(n) {
  1461. if (n < 0) {
  1462. // error.
  1463. } else if (n < 26) {
  1464. return 0x41 + n;
  1465. } else if (n < 52) {
  1466. return 0x61 + (n - 26);
  1467. } else if (n < 62) {
  1468. return 0x30 + (n - 52);
  1469. } else if (n == 62) {
  1470. return 0x2b;
  1471. } else if (n == 63) {
  1472. return 0x2f;
  1473. }
  1474. throw 'n:' + n;
  1475. };
  1476. _this.writeByte = function(n) {
  1477. _buffer = (_buffer << 8) | (n & 0xff);
  1478. _buflen += 8;
  1479. _length += 1;
  1480. while (_buflen >= 6) {
  1481. writeEncoded(_buffer >>> (_buflen - 6) );
  1482. _buflen -= 6;
  1483. }
  1484. };
  1485. _this.flush = function() {
  1486. if (_buflen > 0) {
  1487. writeEncoded(_buffer << (6 - _buflen) );
  1488. _buffer = 0;
  1489. _buflen = 0;
  1490. }
  1491. if (_length % 3 != 0) {
  1492. // padding
  1493. var padlen = 3 - _length % 3;
  1494. for (var i = 0; i < padlen; i += 1) {
  1495. _base64 += '=';
  1496. }
  1497. }
  1498. };
  1499. _this.toString = function() {
  1500. return _base64;
  1501. };
  1502. return _this;
  1503. };
  1504. //---------------------------------------------------------------------
  1505. // gifImage (B/W)
  1506. //---------------------------------------------------------------------
  1507. var gifImage = function(width, height) {
  1508. var _width = width;
  1509. var _height = height;
  1510. var _data = new Array(width * height);
  1511. var _this = {};
  1512. _this.setPixel = function(x, y, pixel) {
  1513. _data[y * _width + x] = pixel;
  1514. };
  1515. _this.write = function(out) {
  1516. //---------------------------------
  1517. // GIF Signature
  1518. out.writeString('GIF87a');
  1519. //---------------------------------
  1520. // Screen Descriptor
  1521. out.writeShort(_width);
  1522. out.writeShort(_height);
  1523. out.writeByte(0x80); // 2bit
  1524. out.writeByte(0);
  1525. out.writeByte(0);
  1526. //---------------------------------
  1527. // Global Color Map
  1528. // black
  1529. out.writeByte(0x00);
  1530. out.writeByte(0x00);
  1531. out.writeByte(0x00);
  1532. // white
  1533. out.writeByte(0xff);
  1534. out.writeByte(0xff);
  1535. out.writeByte(0xff);
  1536. //---------------------------------
  1537. // Image Descriptor
  1538. out.writeString(',');
  1539. out.writeShort(0);
  1540. out.writeShort(0);
  1541. out.writeShort(_width);
  1542. out.writeShort(_height);
  1543. out.writeByte(0);
  1544. //---------------------------------
  1545. // Local Color Map
  1546. //---------------------------------
  1547. // Raster Data
  1548. var lzwMinCodeSize = 2;
  1549. var raster = getLZWRaster(lzwMinCodeSize);
  1550. out.writeByte(lzwMinCodeSize);
  1551. var offset = 0;
  1552. while (raster.length - offset > 255) {
  1553. out.writeByte(255);
  1554. out.writeBytes(raster, offset, 255);
  1555. offset += 255;
  1556. }
  1557. out.writeByte(raster.length - offset);
  1558. out.writeBytes(raster, offset, raster.length - offset);
  1559. out.writeByte(0x00);
  1560. //---------------------------------
  1561. // GIF Terminator
  1562. out.writeString(';');
  1563. };
  1564. var bitOutputStream = function(out) {
  1565. var _out = out;
  1566. var _bitLength = 0;
  1567. var _bitBuffer = 0;
  1568. var _this = {};
  1569. _this.write = function(data, length) {
  1570. if ( (data >>> length) != 0) {
  1571. throw 'length over';
  1572. }
  1573. while (_bitLength + length >= 8) {
  1574. _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) );
  1575. length -= (8 - _bitLength);
  1576. data >>>= (8 - _bitLength);
  1577. _bitBuffer = 0;
  1578. _bitLength = 0;
  1579. }
  1580. _bitBuffer = (data << _bitLength) | _bitBuffer;
  1581. _bitLength = _bitLength + length;
  1582. };
  1583. _this.flush = function() {
  1584. if (_bitLength > 0) {
  1585. _out.writeByte(_bitBuffer);
  1586. }
  1587. };
  1588. return _this;
  1589. };
  1590. var getLZWRaster = function(lzwMinCodeSize) {
  1591. var clearCode = 1 << lzwMinCodeSize;
  1592. var endCode = (1 << lzwMinCodeSize) + 1;
  1593. var bitLength = lzwMinCodeSize + 1;
  1594. // Setup LZWTable
  1595. var table = lzwTable();
  1596. for (var i = 0; i < clearCode; i += 1) {
  1597. table.add(String.fromCharCode(i) );
  1598. }
  1599. table.add(String.fromCharCode(clearCode) );
  1600. table.add(String.fromCharCode(endCode) );
  1601. var byteOut = byteArrayOutputStream();
  1602. var bitOut = bitOutputStream(byteOut);
  1603. // clear code
  1604. bitOut.write(clearCode, bitLength);
  1605. var dataIndex = 0;
  1606. var s = String.fromCharCode(_data[dataIndex]);
  1607. dataIndex += 1;
  1608. while (dataIndex < _data.length) {
  1609. var c = String.fromCharCode(_data[dataIndex]);
  1610. dataIndex += 1;
  1611. if (table.contains(s + c) ) {
  1612. s = s + c;
  1613. } else {
  1614. bitOut.write(table.indexOf(s), bitLength);
  1615. if (table.size() < 0xfff) {
  1616. if (table.size() == (1 << bitLength) ) {
  1617. bitLength += 1;
  1618. }
  1619. table.add(s + c);
  1620. }
  1621. s = c;
  1622. }
  1623. }
  1624. bitOut.write(table.indexOf(s), bitLength);
  1625. // end code
  1626. bitOut.write(endCode, bitLength);
  1627. bitOut.flush();
  1628. return byteOut.toByteArray();
  1629. };
  1630. var lzwTable = function() {
  1631. var _map = {};
  1632. var _size = 0;
  1633. var _this = {};
  1634. _this.add = function(key) {
  1635. if (_this.contains(key) ) {
  1636. throw 'dup key:' + key;
  1637. }
  1638. _map[key] = _size;
  1639. _size += 1;
  1640. };
  1641. _this.size = function() {
  1642. return _size;
  1643. };
  1644. _this.indexOf = function(key) {
  1645. return _map[key];
  1646. };
  1647. _this.contains = function(key) {
  1648. return typeof _map[key] != 'undefined';
  1649. };
  1650. return _this;
  1651. };
  1652. return _this;
  1653. };
  1654. var createDataURL = function(width, height, getPixel) {
  1655. var gif = gifImage(width, height);
  1656. for (var y = 0; y < height; y += 1) {
  1657. for (var x = 0; x < width; x += 1) {
  1658. gif.setPixel(x, y, getPixel(x, y) );
  1659. }
  1660. }
  1661. var b = byteArrayOutputStream();
  1662. gif.write(b);
  1663. var base64 = base64EncodeOutputStream();
  1664. var bytes = b.toByteArray();
  1665. for (var i = 0; i < bytes.length; i += 1) {
  1666. base64.writeByte(bytes[i]);
  1667. }
  1668. base64.flush();
  1669. return 'data:image/gif;base64,' + base64;
  1670. };
  1671. qrcode.stringToBytesFuncs['UTF-8'] = function(s) {
  1672. // http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array
  1673. function toUTF8Array(str) {
  1674. var utf8 = [];
  1675. for (var i=0; i < str.length; i++) {
  1676. var charcode = str.charCodeAt(i);
  1677. if (charcode < 0x80) utf8.push(charcode);
  1678. else if (charcode < 0x800) {
  1679. utf8.push(0xc0 | (charcode >> 6),
  1680. 0x80 | (charcode & 0x3f));
  1681. }
  1682. else if (charcode < 0xd800 || charcode >= 0xe000) {
  1683. utf8.push(0xe0 | (charcode >> 12),
  1684. 0x80 | ((charcode>>6) & 0x3f),
  1685. 0x80 | (charcode & 0x3f));
  1686. }
  1687. // surrogate pair
  1688. else {
  1689. i++;
  1690. // UTF-16 encodes 0x10000-0x10FFFF by
  1691. // subtracting 0x10000 and splitting the
  1692. // 20 bits of 0x0-0xFFFFF into two halves
  1693. charcode = 0x10000 + (((charcode & 0x3ff)<<10)
  1694. | (str.charCodeAt(i) & 0x3ff));
  1695. utf8.push(0xf0 | (charcode >>18),
  1696. 0x80 | ((charcode>>12) & 0x3f),
  1697. 0x80 | ((charcode>>6) & 0x3f),
  1698. 0x80 | (charcode & 0x3f));
  1699. }
  1700. }
  1701. return utf8;
  1702. }
  1703. return toUTF8Array(s);
  1704. };