//---------------------------------------------------------------------
//
// qr code generator for javascript
//
// copyright (c) 2009 kazuhiko arase
//
// url: http://www.d-project.com/
//
// licensed under the mit license:
// http://www.opensource.org/licenses/mit-license.php
//
// the word 'qr code' is registered trademark of
// denso wave incorporated
// http://www.denso-wave.com/qrcode/faqpatent-e.html
//
//---------------------------------------------------------------------
var qrcode = function() {
//---------------------------------------------------------------------
// qrcode
//---------------------------------------------------------------------
/**
* qrcode
* @param typenumber 1 to 10
* @param errorcorrectlevel 'l','m','q','h'
*/
var qrcode = function(typenumber, errorcorrectlevel) {
var pad0 = 0xec;
var pad1 = 0x11;
var _typenumber = typenumber;
var _errorcorrectlevel = qrerrorcorrectlevel[errorcorrectlevel];
var _modules = null;
var _modulecount = 0;
var _datacache = null;
var _datalist = new array();
var _this = {};
var makeimpl = function(test, maskpattern) {
_modulecount = _typenumber * 4 + 17;
_modules = function(modulecount) {
var modules = new array(modulecount);
for (var row = 0; row < modulecount; row += 1) {
modules[row] = new array(modulecount);
for (var col = 0; col < modulecount; col += 1) {
modules[row][col] = null;
}
}
return modules;
}(_modulecount);
setuppositionprobepattern(0, 0);
setuppositionprobepattern(_modulecount - 7, 0);
setuppositionprobepattern(0, _modulecount - 7);
setuppositionadjustpattern();
setuptimingpattern();
setuptypeinfo(test, maskpattern);
if (_typenumber >= 7) {
setuptypenumber(test);
}
if (_datacache == null) {
_datacache = createdata(_typenumber, _errorcorrectlevel, _datalist);
}
mapdata(_datacache, maskpattern);
};
var setuppositionprobepattern = function(row, col) {
for (var r = -1; r <= 7; r += 1) {
if (row + r <= -1 || _modulecount <= row + r) continue;
for (var c = -1; c <= 7; c += 1) {
if (col + c <= -1 || _modulecount <= col + c) continue;
if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )
|| (0 <= c && c <= 6 && (r == 0 || r == 6) )
|| (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {
_modules[row + r][col + c] = true;
} else {
_modules[row + r][col + c] = false;
}
}
}
};
var getbestmaskpattern = function() {
var minlostpoint = 0;
var pattern = 0;
for (var i = 0; i < 8; i += 1) {
makeimpl(true, i);
var lostpoint = qrutil.getlostpoint(_this);
if (i == 0 || minlostpoint > lostpoint) {
minlostpoint = lostpoint;
pattern = i;
}
}
return pattern;
};
var setuptimingpattern = function() {
for (var r = 8; r < _modulecount - 8; r += 1) {
if (_modules[r][6] != null) {
continue;
}
_modules[r][6] = (r % 2 == 0);
}
for (var c = 8; c < _modulecount - 8; c += 1) {
if (_modules[6][c] != null) {
continue;
}
_modules[6][c] = (c % 2 == 0);
}
};
var setuppositionadjustpattern = function() {
var pos = qrutil.getpatternposition(_typenumber);
for (var i = 0; i < pos.length; i += 1) {
for (var j = 0; j < pos.length; j += 1) {
var row = pos[i];
var col = pos[j];
if (_modules[row][col] != null) {
continue;
}
for (var r = -2; r <= 2; r += 1) {
for (var c = -2; c <= 2; c += 1) {
if (r == -2 || r == 2 || c == -2 || c == 2
|| (r == 0 && c == 0) ) {
_modules[row + r][col + c] = true;
} else {
_modules[row + r][col + c] = false;
}
}
}
}
}
};
var setuptypenumber = function(test) {
var bits = qrutil.getbchtypenumber(_typenumber);
for (var i = 0; i < 18; i += 1) {
var mod = (!test && ( (bits >> i) & 1) == 1);
_modules[math.floor(i / 3)][i % 3 + _modulecount - 8 - 3] = mod;
}
for (var i = 0; i < 18; i += 1) {
var mod = (!test && ( (bits >> i) & 1) == 1);
_modules[i % 3 + _modulecount - 8 - 3][math.floor(i / 3)] = mod;
}
};
var setuptypeinfo = function(test, maskpattern) {
var data = (_errorcorrectlevel << 3) | maskpattern;
var bits = qrutil.getbchtypeinfo(data);
// vertical
for (var i = 0; i < 15; i += 1) {
var mod = (!test && ( (bits >> i) & 1) == 1);
if (i < 6) {
_modules[i][8] = mod;
} else if (i < 8) {
_modules[i + 1][8] = mod;
} else {
_modules[_modulecount - 15 + i][8] = mod;
}
}
// horizontal
for (var i = 0; i < 15; i += 1) {
var mod = (!test && ( (bits >> i) & 1) == 1);
if (i < 8) {
_modules[8][_modulecount - i - 1] = mod;
} else if (i < 9) {
_modules[8][15 - i - 1 + 1] = mod;
} else {
_modules[8][15 - i - 1] = mod;
}
}
// fixed module
_modules[_modulecount - 8][8] = (!test);
};
var mapdata = function(data, maskpattern) {
var inc = -1;
var row = _modulecount - 1;
var bitindex = 7;
var byteindex = 0;
var maskfunc = qrutil.getmaskfunction(maskpattern);
for (var col = _modulecount - 1; col > 0; col -= 2) {
if (col == 6) col -= 1;
while (true) {
for (var c = 0; c < 2; c += 1) {
if (_modules[row][col - c] == null) {
var dark = false;
if (byteindex < data.length) {
dark = ( ( (data[byteindex] >>> bitindex) & 1) == 1);
}
var mask = maskfunc(row, col - c);
if (mask) {
dark = !dark;
}
_modules[row][col - c] = dark;
bitindex -= 1;
if (bitindex == -1) {
byteindex += 1;
bitindex = 7;
}
}
}
row += inc;
if (row < 0 || _modulecount <= row) {
row -= inc;
inc = -inc;
break;
}
}
}
};
var createbytes = function(buffer, rsblocks) {
var offset = 0;
var maxdccount = 0;
var maxeccount = 0;
var dcdata = new array(rsblocks.length);
var ecdata = new array(rsblocks.length);
for (var r = 0; r < rsblocks.length; r += 1) {
var dccount = rsblocks[r].datacount;
var eccount = rsblocks[r].totalcount - dccount;
maxdccount = math.max(maxdccount, dccount);
maxeccount = math.max(maxeccount, eccount);
dcdata[r] = new array(dccount);
for (var i = 0; i < dcdata[r].length; i += 1) {
dcdata[r][i] = 0xff & buffer.getbuffer()[i + offset];
}
offset += dccount;
var rspoly = qrutil.geterrorcorrectpolynomial(eccount);
var rawpoly = qrpolynomial(dcdata[r], rspoly.getlength() - 1);
var modpoly = rawpoly.mod(rspoly);
ecdata[r] = new array(rspoly.getlength() - 1);
for (var i = 0; i < ecdata[r].length; i += 1) {
var modindex = i + modpoly.getlength() - ecdata[r].length;
ecdata[r][i] = (modindex >= 0)? modpoly.getat(modindex) : 0;
}
}
var totalcodecount = 0;
for (var i = 0; i < rsblocks.length; i += 1) {
totalcodecount += rsblocks[i].totalcount;
}
var data = new array(totalcodecount);
var index = 0;
for (var i = 0; i < maxdccount; i += 1) {
for (var r = 0; r < rsblocks.length; r += 1) {
if (i < dcdata[r].length) {
data[index] = dcdata[r][i];
index += 1;
}
}
}
for (var i = 0; i < maxeccount; i += 1) {
for (var r = 0; r < rsblocks.length; r += 1) {
if (i < ecdata[r].length) {
data[index] = ecdata[r][i];
index += 1;
}
}
}
return data;
};
var createdata = function(typenumber, errorcorrectlevel, datalist) {
var rsblocks = qrrsblock.getrsblocks(typenumber, errorcorrectlevel);
var buffer = qrbitbuffer();
for (var i = 0; i < datalist.length; i += 1) {
var data = datalist[i];
buffer.put(data.getmode(), 4);
buffer.put(data.getlength(), qrutil.getlengthinbits(data.getmode(), typenumber) );
data.write(buffer);
}
// calc num max data.
var totaldatacount = 0;
for (var i = 0; i < rsblocks.length; i += 1) {
totaldatacount += rsblocks[i].datacount;
}
if (buffer.getlengthinbits() > totaldatacount * 8) {
throw new error('code length overflow. ('
+ buffer.getlengthinbits()
+ '>'
+ totaldatacount * 8
+ ')');
}
// end code
if (buffer.getlengthinbits() + 4 <= totaldatacount * 8) {
buffer.put(0, 4);
}
// padding
while (buffer.getlengthinbits() % 8 != 0) {
buffer.putbit(false);
}
// padding
while (true) {
if (buffer.getlengthinbits() >= totaldatacount * 8) {
break;
}
buffer.put(pad0, 8);
if (buffer.getlengthinbits() >= totaldatacount * 8) {
break;
}
buffer.put(pad1, 8);
}
return createbytes(buffer, rsblocks);
};
_this.adddata = function(data) {
var newdata = qr8bitbyte(data);
_datalist.push(newdata);
_datacache = null;
};
_this.isdark = function(row, col) {
if (row < 0 || _modulecount <= row || col < 0 || _modulecount <= col) {
throw new error(row + ',' + col);
}
return _modules[row][col];
};
_this.getmodulecount = function() {
return _modulecount;
};
_this.make = function() {
makeimpl(false, getbestmaskpattern() );
};
_this.createtabletag = function(cellsize, margin) {
cellsize = cellsize || 4;
margin = (typeof margin == 'undefined')? cellsize * 1 : margin;
var qrhtml = '';
qrhtml += '
';
qrhtml += '';
for (var r = 0; r < _this.getmodulecount(); r += 1) {
qrhtml += '';
for (var c = 0; c < _this.getmodulecount(); c += 1) {
qrhtml += ' | ';
}
qrhtml += '
';
}
qrhtml += '';
qrhtml += '
';
return qrhtml;
};
_this.createimgtag = function(cellsize, margin) {
cellsize = cellsize || 4;
margin = (typeof margin == 'undefined')? cellsize * 1 : margin;
var size = _this.getmodulecount() * cellsize + margin * 2;
var min = margin;
var max = size - margin;
return createimgtag(size, size, function(x, y) {
if (min <= x && x < max && min <= y && y < max) {
var c = math.floor( (x - min) / cellsize);
var r = math.floor( (y - min) / cellsize);
return _this.isdark(r, c)? 0 : 1;
} else {
return 1;
}
} );
};
return _this;
};
//---------------------------------------------------------------------
// qrcode.stringtobytes
//---------------------------------------------------------------------
qrcode.stringtobytes = function(s) {
var bytes = new array();
for (var i = 0; i < s.length; i += 1) {
var c = s.charcodeat(i);
bytes.push(c & 0xff);
}
return bytes;
};
//---------------------------------------------------------------------
// qrcode.createstringtobytes
//---------------------------------------------------------------------
/**
* @param unicodedata base64 string of byte array.
* [16bit unicode],[16bit bytes], ...
* @param numchars
*/
qrcode.createstringtobytes = function(unicodedata, numchars) {
// create conversion map.
var unicodemap = function() {
var bin = base64decodeinputstream(unicodedata);
var read = function() {
var b = bin.read();
if (b == -1) throw new error();
return b;
};
var count = 0;
var unicodemap = {};
while (true) {
var b0 = bin.read();
if (b0 == -1) break;
var b1 = read();
var b2 = read();
var b3 = read();
var k = string.fromcharcode( (b0 << 8) | b1);
var v = (b2 << 8) | b3;
unicodemap[k] = v;
count += 1;
}
if (count != numchars) {
throw new error(count + ' != ' + numchars);
}
return unicodemap;
}();
var unknownchar = '?'.charcodeat(0);
return function(s) {
var bytes = new array();
for (var i = 0; i < s.length; i += 1) {
var c = s.charcodeat(i);
if (c < 128) {
bytes.push(c);
} else {
var b = unicodemap[s.charat(i)];
if (typeof b == 'number') {
if ( (b & 0xff) == b) {
// 1byte
bytes.push(b);
} else {
// 2bytes
bytes.push(b >>> 8);
bytes.push(b & 0xff);
}
} else {
bytes.push(unknownchar);
}
}
}
return bytes;
};
};
//---------------------------------------------------------------------
// qrmode
//---------------------------------------------------------------------
var qrmode = {
mode_number : 1 << 0,
mode_alpha_num : 1 << 1,
mode_8bit_byte : 1 << 2,
mode_kanji : 1 << 3
};
//---------------------------------------------------------------------
// qrerrorcorrectlevel
//---------------------------------------------------------------------
var qrerrorcorrectlevel = {
l : 1,
m : 0,
q : 3,
h : 2
};
//---------------------------------------------------------------------
// qrmaskpattern
//---------------------------------------------------------------------
var qrmaskpattern = {
pattern000 : 0,
pattern001 : 1,
pattern010 : 2,
pattern011 : 3,
pattern100 : 4,
pattern101 : 5,
pattern110 : 6,
pattern111 : 7
};
//---------------------------------------------------------------------
// qrutil
//---------------------------------------------------------------------
var qrutil = function() {
var pattern_position_table = [
[],
[6, 18],
[6, 22],
[6, 26],
[6, 30],
[6, 34],
[6, 22, 38],
[6, 24, 42],
[6, 26, 46],
[6, 28, 50],
[6, 30, 54],
[6, 32, 58],
[6, 34, 62],
[6, 26, 46, 66],
[6, 26, 48, 70],
[6, 26, 50, 74],
[6, 30, 54, 78],
[6, 30, 56, 82],
[6, 30, 58, 86],
[6, 34, 62, 90],
[6, 28, 50, 72, 94],
[6, 26, 50, 74, 98],
[6, 30, 54, 78, 102],
[6, 28, 54, 80, 106],
[6, 32, 58, 84, 110],
[6, 30, 58, 86, 114],
[6, 34, 62, 90, 118],
[6, 26, 50, 74, 98, 122],
[6, 30, 54, 78, 102, 126],
[6, 26, 52, 78, 104, 130],
[6, 30, 56, 82, 108, 134],
[6, 34, 60, 86, 112, 138],
[6, 30, 58, 86, 114, 142],
[6, 34, 62, 90, 118, 146],
[6, 30, 54, 78, 102, 126, 150],
[6, 24, 50, 76, 102, 128, 154],
[6, 28, 54, 80, 106, 132, 158],
[6, 32, 58, 84, 110, 136, 162],
[6, 26, 54, 82, 110, 138, 166],
[6, 30, 58, 86, 114, 142, 170]
];
var g15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);
var g18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0);
var g15_mask = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1);
var _this = {};
var getbchdigit = function(data) {
var digit = 0;
while (data != 0) {
digit += 1;
data >>>= 1;
}
return digit;
};
_this.getbchtypeinfo = function(data) {
var d = data << 10;
while (getbchdigit(d) - getbchdigit(g15) >= 0) {
d ^= (g15 << (getbchdigit(d) - getbchdigit(g15) ) );
}
return ( (data << 10) | d) ^ g15_mask;
};
_this.getbchtypenumber = function(data) {
var d = data << 12;
while (getbchdigit(d) - getbchdigit(g18) >= 0) {
d ^= (g18 << (getbchdigit(d) - getbchdigit(g18) ) );
}
return (data << 12) | d;
};
_this.getpatternposition = function(typenumber) {
return pattern_position_table[typenumber - 1];
};
_this.getmaskfunction = function(maskpattern) {
switch (maskpattern) {
case qrmaskpattern.pattern000 :
return function(i, j) { return (i + j) % 2 == 0; };
case qrmaskpattern.pattern001 :
return function(i, j) { return i % 2 == 0; };
case qrmaskpattern.pattern010 :
return function(i, j) { return j % 3 == 0; };
case qrmaskpattern.pattern011 :
return function(i, j) { return (i + j) % 3 == 0; };
case qrmaskpattern.pattern100 :
return function(i, j) { return (math.floor(i / 2) + math.floor(j / 3) ) % 2 == 0; };
case qrmaskpattern.pattern101 :
return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; };
case qrmaskpattern.pattern110 :
return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; };
case qrmaskpattern.pattern111 :
return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; };
default :
throw new error('bad maskpattern:' + maskpattern);
}
};
_this.geterrorcorrectpolynomial = function(errorcorrectlength) {
var a = qrpolynomial([1], 0);
for (var i = 0; i < errorcorrectlength; i += 1) {
a = a.multiply(qrpolynomial([1, qrmath.gexp(i)], 0) );
}
return a;
};
_this.getlengthinbits = function(mode, type) {
if (1 <= type && type < 10) {
// 1 - 9
switch(mode) {
case qrmode.mode_number : return 10;
case qrmode.mode_alpha_num : return 9;
case qrmode.mode_8bit_byte : return 8;
case qrmode.mode_kanji : return 8;
default :
throw new error('mode:' + mode);
}
} else if (type < 27) {
// 10 - 26
switch(mode) {
case qrmode.mode_number : return 12;
case qrmode.mode_alpha_num : return 11;
case qrmode.mode_8bit_byte : return 16;
case qrmode.mode_kanji : return 10;
default :
throw new error('mode:' + mode);
}
} else if (type < 41) {
// 27 - 40
switch(mode) {
case qrmode.mode_number : return 14;
case qrmode.mode_alpha_num : return 13;
case qrmode.mode_8bit_byte : return 16;
case qrmode.mode_kanji : return 12;
default :
throw new error('mode:' + mode);
}
} else {
throw new error('type:' + type);
}
};
_this.getlostpoint = function(qrcode) {
var modulecount = qrcode.getmodulecount();
var lostpoint = 0;
// level1
for (var row = 0; row < modulecount; row += 1) {
for (var col = 0; col < modulecount; col += 1) {
var samecount = 0;
var dark = qrcode.isdark(row, col);
for (var r = -1; r <= 1; r += 1) {
if (row + r < 0 || modulecount <= row + r) {
continue;
}
for (var c = -1; c <= 1; c += 1) {
if (col + c < 0 || modulecount <= col + c) {
continue;
}
if (r == 0 && c == 0) {
continue;
}
if (dark == qrcode.isdark(row + r, col + c) ) {
samecount += 1;
}
}
}
if (samecount > 5) {
lostpoint += (3 + samecount - 5);
}
}
};
// level2
for (var row = 0; row < modulecount - 1; row += 1) {
for (var col = 0; col < modulecount - 1; col += 1) {
var count = 0;
if (qrcode.isdark(row, col) ) count += 1;
if (qrcode.isdark(row + 1, col) ) count += 1;
if (qrcode.isdark(row, col + 1) ) count += 1;
if (qrcode.isdark(row + 1, col + 1) ) count += 1;
if (count == 0 || count == 4) {
lostpoint += 3;
}
}
}
// level3
for (var row = 0; row < modulecount; row += 1) {
for (var col = 0; col < modulecount - 6; col += 1) {
if (qrcode.isdark(row, col)
&& !qrcode.isdark(row, col + 1)
&& qrcode.isdark(row, col + 2)
&& qrcode.isdark(row, col + 3)
&& qrcode.isdark(row, col + 4)
&& !qrcode.isdark(row, col + 5)
&& qrcode.isdark(row, col + 6) ) {
lostpoint += 40;
}
}
}
for (var col = 0; col < modulecount; col += 1) {
for (var row = 0; row < modulecount - 6; row += 1) {
if (qrcode.isdark(row, col)
&& !qrcode.isdark(row + 1, col)
&& qrcode.isdark(row + 2, col)
&& qrcode.isdark(row + 3, col)
&& qrcode.isdark(row + 4, col)
&& !qrcode.isdark(row + 5, col)
&& qrcode.isdark(row + 6, col) ) {
lostpoint += 40;
}
}
}
// level4
var darkcount = 0;
for (var col = 0; col < modulecount; col += 1) {
for (var row = 0; row < modulecount; row += 1) {
if (qrcode.isdark(row, col) ) {
darkcount += 1;
}
}
}
var ratio = math.abs(100 * darkcount / modulecount / modulecount - 50) / 5;
lostpoint += ratio * 10;
return lostpoint;
};
return _this;
}();
//---------------------------------------------------------------------
// qrmath
//---------------------------------------------------------------------
var qrmath = function() {
var exp_table = new array(256);
var log_table = new array(256);
// initialize tables
for (var i = 0; i < 8; i += 1) {
exp_table[i] = 1 << i;
}
for (var i = 8; i < 256; i += 1) {
exp_table[i] = exp_table[i - 4]
^ exp_table[i - 5]
^ exp_table[i - 6]
^ exp_table[i - 8];
}
for (var i = 0; i < 255; i += 1) {
log_table[exp_table[i] ] = i;
}
var _this = {};
_this.glog = function(n) {
if (n < 1) {
throw new error('glog(' + n + ')');
}
return log_table[n];
};
_this.gexp = function(n) {
while (n < 0) {
n += 255;
}
while (n >= 256) {
n -= 255;
}
return exp_table[n];
};
return _this;
}();
//---------------------------------------------------------------------
// qrpolynomial
//---------------------------------------------------------------------
function qrpolynomial(num, shift) {
if (typeof num.length == 'undefined') {
throw new error(num.length + '/' + shift);
}
var _num = function() {
var offset = 0;
while (offset < num.length && num[offset] == 0) {
offset += 1;
}
var _num = new array(num.length - offset + shift);
for (var i = 0; i < num.length - offset; i += 1) {
_num[i] = num[i + offset];
}
return _num;
}();
var _this = {};
_this.getat = function(index) {
return _num[index];
};
_this.getlength = function() {
return _num.length;
};
_this.multiply = function(e) {
var num = new array(_this.getlength() + e.getlength() - 1);
for (var i = 0; i < _this.getlength(); i += 1) {
for (var j = 0; j < e.getlength(); j += 1) {
num[i + j] ^= qrmath.gexp(qrmath.glog(_this.getat(i) ) + qrmath.glog(e.getat(j) ) );
}
}
return qrpolynomial(num, 0);
};
_this.mod = function(e) {
if (_this.getlength() - e.getlength() < 0) {
return _this;
}
var ratio = qrmath.glog(_this.getat(0) ) - qrmath.glog(e.getat(0) );
var num = new array(_this.getlength() );
for (var i = 0; i < _this.getlength(); i += 1) {
num[i] = _this.getat(i);
}
for (var i = 0; i < e.getlength(); i += 1) {
num[i] ^= qrmath.gexp(qrmath.glog(e.getat(i) ) + ratio);
}
// recursive call
return qrpolynomial(num, 0).mod(e);
};
return _this;
};
//---------------------------------------------------------------------
// qrrsblock
//---------------------------------------------------------------------
var qrrsblock = function() {
var rs_block_table = [
// l
// m
// q
// h
// 1
[1, 26, 19],
[1, 26, 16],
[1, 26, 13],
[1, 26, 9],
// 2
[1, 44, 34],
[1, 44, 28],
[1, 44, 22],
[1, 44, 16],
// 3
[1, 70, 55],
[1, 70, 44],
[2, 35, 17],
[2, 35, 13],
// 4
[1, 100, 80],
[2, 50, 32],
[2, 50, 24],
[4, 25, 9],
// 5
[1, 134, 108],
[2, 67, 43],
[2, 33, 15, 2, 34, 16],
[2, 33, 11, 2, 34, 12],
// 6
[2, 86, 68],
[4, 43, 27],
[4, 43, 19],
[4, 43, 15],
// 7
[2, 98, 78],
[4, 49, 31],
[2, 32, 14, 4, 33, 15],
[4, 39, 13, 1, 40, 14],
// 8
[2, 121, 97],
[2, 60, 38, 2, 61, 39],
[4, 40, 18, 2, 41, 19],
[4, 40, 14, 2, 41, 15],
// 9
[2, 146, 116],
[3, 58, 36, 2, 59, 37],
[4, 36, 16, 4, 37, 17],
[4, 36, 12, 4, 37, 13],
// 10
[2, 86, 68, 2, 87, 69],
[4, 69, 43, 1, 70, 44],
[6, 43, 19, 2, 44, 20],
[6, 43, 15, 2, 44, 16]
];
var qrrsblock = function(totalcount, datacount) {
var _this = {};
_this.totalcount = totalcount;
_this.datacount = datacount;
return _this;
};
var _this = {};
var getrsblocktable = function(typenumber, errorcorrectlevel) {
switch(errorcorrectlevel) {
case qrerrorcorrectlevel.l :
return rs_block_table[(typenumber - 1) * 4 + 0];
case qrerrorcorrectlevel.m :
return rs_block_table[(typenumber - 1) * 4 + 1];
case qrerrorcorrectlevel.q :
return rs_block_table[(typenumber - 1) * 4 + 2];
case qrerrorcorrectlevel.h :
return rs_block_table[(typenumber - 1) * 4 + 3];
default :
return undefined;
}
};
_this.getrsblocks = function(typenumber, errorcorrectlevel) {
var rsblock = getrsblocktable(typenumber, errorcorrectlevel);
if (typeof rsblock == 'undefined') {
throw new error('bad rs block @ typenumber:' + typenumber +
'/errorcorrectlevel:' + errorcorrectlevel);
}
var length = rsblock.length / 3;
var list = new array();
for (var i = 0; i < length; i += 1) {
var count = rsblock[i * 3 + 0];
var totalcount = rsblock[i * 3 + 1];
var datacount = rsblock[i * 3 + 2];
for (var j = 0; j < count; j += 1) {
list.push(qrrsblock(totalcount, datacount) );
}
}
return list;
};
return _this;
}();
//---------------------------------------------------------------------
// qrbitbuffer
//---------------------------------------------------------------------
var qrbitbuffer = function() {
var _buffer = new array();
var _length = 0;
var _this = {};
_this.getbuffer = function() {
return _buffer;
};
_this.getat = function(index) {
var bufindex = math.floor(index / 8);
return ( (_buffer[bufindex] >>> (7 - index % 8) ) & 1) == 1;
};
_this.put = function(num, length) {
for (var i = 0; i < length; i += 1) {
_this.putbit( ( (num >>> (length - i - 1) ) & 1) == 1);
}
};
_this.getlengthinbits = function() {
return _length;
};
_this.putbit = function(bit) {
var bufindex = math.floor(_length / 8);
if (_buffer.length <= bufindex) {
_buffer.push(0);
}
if (bit) {
_buffer[bufindex] |= (0x80 >>> (_length % 8) );
}
_length += 1;
};
return _this;
};
//---------------------------------------------------------------------
// qr8bitbyte
//---------------------------------------------------------------------
var qr8bitbyte = function(data) {
var _mode = qrmode.mode_8bit_byte;
var _data = data;
var _bytes = qrcode.stringtobytes(data);
var _this = {};
_this.getmode = function() {
return _mode;
};
_this.getlength = function(buffer) {
return _bytes.length;
};
_this.write = function(buffer) {
for (var i = 0; i < _bytes.length; i += 1) {
buffer.put(_bytes[i], 8);
}
};
return _this;
};
//=====================================================================
// gif support etc.
//
//---------------------------------------------------------------------
// bytearrayoutputstream
//---------------------------------------------------------------------
var bytearrayoutputstream = function() {
var _bytes = new array();
var _this = {};
_this.writebyte = function(b) {
_bytes.push(b & 0xff);
};
_this.writeshort = function(i) {
_this.writebyte(i);
_this.writebyte(i >>> 8);
};
_this.writebytes = function(b, off, len) {
off = off || 0;
len = len || b.length;
for (var i = 0; i < len; i += 1) {
_this.writebyte(b[i + off]);
}
};
_this.writestring = function(s) {
for (var i = 0; i < s.length; i += 1) {
_this.writebyte(s.charcodeat(i) );
}
};
_this.tobytearray = function() {
return _bytes;
};
_this.tostring = function() {
var s = '';
s += '[';
for (var i = 0; i < _bytes.length; i += 1) {
if (i > 0) {
s += ',';
}
s += _bytes[i];
}
s += ']';
return s;
};
return _this;
};
//---------------------------------------------------------------------
// base64encodeoutputstream
//---------------------------------------------------------------------
var base64encodeoutputstream = function() {
var _buffer = 0;
var _buflen = 0;
var _length = 0;
var _base64 = '';
var _this = {};
var writeencoded = function(b) {
_base64 += string.fromcharcode(encode(b & 0x3f) );
};
var encode = function(n) {
if (n < 0) {
// error.
} else if (n < 26) {
return 0x41 + n;
} else if (n < 52) {
return 0x61 + (n - 26);
} else if (n < 62) {
return 0x30 + (n - 52);
} else if (n == 62) {
return 0x2b;
} else if (n == 63) {
return 0x2f;
}
throw new error('n:' + n);
};
_this.writebyte = function(n) {
_buffer = (_buffer << 8) | (n & 0xff);
_buflen += 8;
_length += 1;
while (_buflen >= 6) {
writeencoded(_buffer >>> (_buflen - 6) );
_buflen -= 6;
}
};
_this.flush = function() {
if (_buflen > 0) {
writeencoded(_buffer << (6 - _buflen) );
_buffer = 0;
_buflen = 0;
}
if (_length % 3 != 0) {
// padding
var padlen = 3 - _length % 3;
for (var i = 0; i < padlen; i += 1) {
_base64 += '=';
}
}
};
_this.tostring = function() {
return _base64;
};
return _this;
};
//---------------------------------------------------------------------
// base64decodeinputstream
//---------------------------------------------------------------------
var base64decodeinputstream = function(str) {
var _str = str;
var _pos = 0;
var _buffer = 0;
var _buflen = 0;
var _this = {};
_this.read = function() {
while (_buflen < 8) {
if (_pos >= _str.length) {
if (_buflen == 0) {
return -1;
}
throw new error('unexpected end of file./' + _buflen);
}
var c = _str.charat(_pos);
_pos += 1;
if (c == '=') {
_buflen = 0;
return -1;
} else if (c.match(/^\s$/) ) {
// ignore if whitespace.
continue;
}
_buffer = (_buffer << 6) | decode(c.charcodeat(0) );
_buflen += 6;
}
var n = (_buffer >>> (_buflen - 8) ) & 0xff;
_buflen -= 8;
return n;
};
var decode = function(c) {
if (0x41 <= c && c <= 0x5a) {
return c - 0x41;
} else if (0x61 <= c && c <= 0x7a) {
return c - 0x61 + 26;
} else if (0x30 <= c && c <= 0x39) {
return c - 0x30 + 52;
} else if (c == 0x2b) {
return 62;
} else if (c == 0x2f) {
return 63;
} else {
throw new error('c:' + c);
}
};
return _this;
};
//---------------------------------------------------------------------
// gifimage (b/w)
//---------------------------------------------------------------------
var gifimage = function(width, height) {
var _width = width;
var _height = height;
var _data = new array(width * height);
var _this = {};
_this.setpixel = function(x, y, pixel) {
_data[y * _width + x] = pixel;
};
_this.write = function(out) {
//---------------------------------
// gif signature
out.writestring('gif87a');
//---------------------------------
// screen descriptor
out.writeshort(_width);
out.writeshort(_height);
out.writebyte(0x80); // 2bit
out.writebyte(0);
out.writebyte(0);
//---------------------------------
// global color map
// black
out.writebyte(0x00);
out.writebyte(0x00);
out.writebyte(0x00);
// white
out.writebyte(0xff);
out.writebyte(0xff);
out.writebyte(0xff);
//---------------------------------
// image descriptor
out.writestring(',');
out.writeshort(0);
out.writeshort(0);
out.writeshort(_width);
out.writeshort(_height);
out.writebyte(0);
//---------------------------------
// local color map
//---------------------------------
// raster data
var lzwmincodesize = 2;
var raster = getlzwraster(lzwmincodesize);
out.writebyte(lzwmincodesize);
var offset = 0;
while (raster.length - offset > 255) {
out.writebyte(255);
out.writebytes(raster, offset, 255);
offset += 255;
}
out.writebyte(raster.length - offset);
out.writebytes(raster, offset, raster.length - offset);
out.writebyte(0x00);
//---------------------------------
// gif terminator
out.writestring(';');
};
var bitoutputstream = function(out) {
var _out = out;
var _bitlength = 0;
var _bitbuffer = 0;
var _this = {};
_this.write = function(data, length) {
if ( (data >>> length) != 0) {
throw new error('length over');
}
while (_bitlength + length >= 8) {
_out.writebyte(0xff & ( (data << _bitlength) | _bitbuffer) );
length -= (8 - _bitlength);
data >>>= (8 - _bitlength);
_bitbuffer = 0;
_bitlength = 0;
}
_bitbuffer = (data << _bitlength) | _bitbuffer;
_bitlength = _bitlength + length;
};
_this.flush = function() {
if (_bitlength > 0) {
_out.writebyte(_bitbuffer);
}
};
return _this;
};
var getlzwraster = function(lzwmincodesize) {
var clearcode = 1 << lzwmincodesize;
var endcode = (1 << lzwmincodesize) + 1;
var bitlength = lzwmincodesize + 1;
// setup lzwtable
var table = lzwtable();
for (var i = 0; i < clearcode; i += 1) {
table.add(string.fromcharcode(i) );
}
table.add(string.fromcharcode(clearcode) );
table.add(string.fromcharcode(endcode) );
var byteout = bytearrayoutputstream();
var bitout = bitoutputstream(byteout);
// clear code
bitout.write(clearcode, bitlength);
var dataindex = 0;
var s = string.fromcharcode(_data[dataindex]);
dataindex += 1;
while (dataindex < _data.length) {
var c = string.fromcharcode(_data[dataindex]);
dataindex += 1;
if (table.contains(s + c) ) {
s = s + c;
} else {
bitout.write(table.indexof(s), bitlength);
if (table.size() < 0xfff) {
if (table.size() == (1 << bitlength) ) {
bitlength += 1;
}
table.add(s + c);
}
s = c;
}
}
bitout.write(table.indexof(s), bitlength);
// end code
bitout.write(endcode, bitlength);
bitout.flush();
return byteout.tobytearray();
};
var lzwtable = function() {
var _map = {};
var _size = 0;
var _this = {};
_this.add = function(key) {
if (_this.contains(key) ) {
throw new error('dup key:' + key);
}
_map[key] = _size;
_size += 1;
};
_this.size = function() {
return _size;
};
_this.indexof = function(key) {
return _map[key];
};
_this.contains = function(key) {
return typeof _map[key] != 'undefined';
};
return _this;
};
return _this;
};
var createimgtag = function(width, height, getpixel, alt) {
var gif = gifimage(width, height);
for (var y = 0; y < height; y += 1) {
for (var x = 0; x < width; x += 1) {
gif.setpixel(x, y, getpixel(x, y) );
}
}
var b = bytearrayoutputstream();
gif.write(b);
var base64 = base64encodeoutputstream();
var bytes = b.tobytearray();
for (var i = 0; i < bytes.length; i += 1) {
base64.writebyte(bytes[i]);
}
base64.flush();
var img = '';
img += '';
return img;
};
//---------------------------------------------------------------------
// returns qrcode function.
return qrcode;
}();
function zshowapp(zappdir,xcx_qrcode)
{
var s1;
s1 = zappdir.substring(zappdir.length-4,zappdir.length);
if ((s1==".jpg")||(s1==".gif")||(s1==".png")){
//alert(s1);
if(document.getelementbyid('qr')){document.getelementbyid('qr').innerhtml = "";}
if( zappdir.indexof("_wx2wm.")>0 ){document.getelementbyid('sytxt').style.display="none";}
}else{
var isie = document.all && window.external;
var qr = qrcode("" || 3, "" || 'l');
qr.adddata(zappdir);
qr.make();
if(isie){
var _ie = (function(){
var v = 3, div = document.createelement('div'), all = div.getelementsbytagname('i');
while (div.innerhtml = '',all[0]);
return v > 4 ? v : false ;
}());
if(_ie<8){
var sh=qr.createtabletag();
}else{
var sh=qr.createimgtag();
}
}else{
var sh=qr.createimgtag();
}
// 增加菊花玛,而不用二维码 by zdc 20190515
if ( xcx_qrcode !== null || xcx_qrcode !== undefined || xcx_qrcode !== '')
{
sh="" ;
}
if(document.getelementbyid('qr')){document.getelementbyid('qr').innerhtml = sh;}
}
}