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