qrcode.js 35 KB

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