All Downloads are FREE. Search and download functionalities are using the official Maven repository.

web.bower_components.jquery.qrcode.dist.jquery.qrcode.js Maven / Gradle / Ivy

/* jQuery.qrcode 0.11.0 - http://larsjung.de/jquery-qrcode/ - uses //github.com/kazuhikoarase/qrcode-generator (MIT) */
(function () {
'use strict';

var $ = jQuery;

// Wrapper for the original QR code generator.
function QRCode(text, level, version, quiet) {

    // `qrcode` is the single public function that will be defined by the `QR Code Generator`
    // at the end of the file.
    var qr = qrcode(version, level);
    qr.addData(text);
    qr.make();

    quiet = quiet || 0;

    var qrModuleCount = qr.getModuleCount();
    var quietModuleCount = qr.getModuleCount() + 2*quiet;

    function isDark(row, col) {

        row -= quiet;
        col -= quiet;

        if (row < 0 || row >= qrModuleCount || col < 0 || col >= qrModuleCount) {
            return false;
        }

        return qr.isDark(row, col);
    }

    var addBlank = function (l, t, r, b) {

        var prevIsDark = this.isDark;
        var moduleSize = 1 / quietModuleCount;

        this.isDark = function (row, col) {

            var ml = col * moduleSize;
            var mt = row * moduleSize;
            var mr = ml + moduleSize;
            var mb = mt + moduleSize;

            return prevIsDark(row, col) && (l > mr || ml > r || t > mb || mt > b);
        };
    };

    this.text = text;
    this.level = level;
    this.version = version;
    this.moduleCount = quietModuleCount;
    this.isDark = isDark;
    this.addBlank = addBlank;
}

// Check if canvas is available in the browser (as Modernizr does)
var hasCanvas = (function () {

        var elem = document.createElement('canvas');
        return !!(elem.getContext && elem.getContext('2d'));
    }());
var hasArcTo = Object.prototype.toString.call(window.opera) !== '[object Opera]';

// Returns a minimal QR code for the given text starting with version `minVersion`.
// Returns `undefined` if `text` is too long to be encoded in `maxVersion`.
function createQRCode(text, level, minVersion, maxVersion, quiet) {

    minVersion = Math.max(1, minVersion || 1);
    maxVersion = Math.min(40, maxVersion || 40);
    for (var version = minVersion; version <= maxVersion; version += 1) {
        try {
            return new QRCode(text, level, version, quiet);
        } catch (err) {}
    }
}

function drawBackgroundLabel(qr, context, settings) {

    var size = settings.size;
    var font = "bold " + (settings.mSize * size) + "px " + settings.fontname;
    var ctx = $('')[0].getContext("2d");

    ctx.font = font;

    var w = ctx.measureText(settings.label).width;
    var sh = settings.mSize;
    var sw = w / size;
    var sl = (1 - sw) * settings.mPosX;
    var st = (1 - sh) * settings.mPosY;
    var sr = sl + sw;
    var sb = st + sh;
    var pad = 0.01;

    if (settings.mode === 1) {
        // Strip
        qr.addBlank(0, st - pad, size, sb + pad);
    } else {
        // Box
        qr.addBlank(sl - pad, st - pad, sr + pad, sb + pad);
    }

    context.fillStyle = settings.fontcolor;
    context.font = font;
    context.fillText(settings.label, sl*size, st*size + 0.75 * settings.mSize * size);
}

function drawBackgroundImage(qr, context, settings) {

    var size = settings.size;
    var w = settings.image.naturalWidth || 1;
    var h = settings.image.naturalHeight || 1;
    var sh = settings.mSize;
    var sw = sh * w / h;
    var sl = (1 - sw) * settings.mPosX;
    var st = (1 - sh) * settings.mPosY;
    var sr = sl + sw;
    var sb = st + sh;
    var pad = 0.01;

    if (settings.mode === 3) {
        // Strip
        qr.addBlank(0, st - pad, size, sb + pad);
    } else {
        // Box
        qr.addBlank(sl - pad, st - pad, sr + pad, sb + pad);
    }

    context.drawImage(settings.image, sl*size, st*size, sw*size, sh*size);
}

function drawBackground(qr, context, settings) {

    if ($(settings.background).is('img')) {
        context.drawImage(settings.background, 0, 0, settings.size, settings.size);
    } else if (settings.background) {
        context.fillStyle = settings.background;
        context.fillRect(settings.left, settings.top, settings.size, settings.size);
    }

    var mode = settings.mode;
    if (mode === 1 || mode === 2) {
        drawBackgroundLabel(qr, context, settings);
    } else if (mode === 3 || mode === 4) {
        drawBackgroundImage(qr, context, settings);
    }
}

function drawModuleDefault(qr, context, settings, left, top, width, row, col) {

    if (qr.isDark(row, col)) {
        context.rect(left, top, width, width);
    }
}

function drawModuleRoundedDark(ctx, l, t, r, b, rad, nw, ne, se, sw) {

    if (nw) {
        ctx.moveTo(l + rad, t);
    } else {
        ctx.moveTo(l, t);
    }

    if (ne) {
        ctx.lineTo(r - rad, t);
        ctx.arcTo(r, t, r, b, rad);
    } else {
        ctx.lineTo(r, t);
    }

    if (se) {
        ctx.lineTo(r, b - rad);
        ctx.arcTo(r, b, l, b, rad);
    } else {
        ctx.lineTo(r, b);
    }

    if (sw) {
        ctx.lineTo(l + rad, b);
        ctx.arcTo(l, b, l, t, rad);
    } else {
        ctx.lineTo(l, b);
    }

    if (nw) {
        ctx.lineTo(l, t + rad);
        ctx.arcTo(l, t, r, t, rad);
    } else {
        ctx.lineTo(l, t);
    }
}

function drawModuleRoundendLight(ctx, l, t, r, b, rad, nw, ne, se, sw) {

    if (nw) {
        ctx.moveTo(l + rad, t);
        ctx.lineTo(l, t);
        ctx.lineTo(l, t + rad);
        ctx.arcTo(l, t, l + rad, t, rad);
    }

    if (ne) {
        ctx.moveTo(r - rad, t);
        ctx.lineTo(r, t);
        ctx.lineTo(r, t + rad);
        ctx.arcTo(r, t, r - rad, t, rad);
    }

    if (se) {
        ctx.moveTo(r - rad, b);
        ctx.lineTo(r, b);
        ctx.lineTo(r, b - rad);
        ctx.arcTo(r, b, r - rad, b, rad);
    }

    if (sw) {
        ctx.moveTo(l + rad, b);
        ctx.lineTo(l, b);
        ctx.lineTo(l, b - rad);
        ctx.arcTo(l, b, l + rad, b, rad);
    }
}

function drawModuleRounded(qr, context, settings, left, top, width, row, col) {

    var isDark = qr.isDark;
    var right = left + width;
    var bottom = top + width;
    var radius = settings.radius * width;
    var rowT = row - 1;
    var rowB = row + 1;
    var colL = col - 1;
    var colR = col + 1;
    var center = isDark(row, col);
    var northwest = isDark(rowT, colL);
    var north = isDark(rowT, col);
    var northeast = isDark(rowT, colR);
    var east = isDark(row, colR);
    var southeast = isDark(rowB, colR);
    var south = isDark(rowB, col);
    var southwest = isDark(rowB, colL);
    var west = isDark(row, colL);

    if (center) {
        drawModuleRoundedDark(context, left, top, right, bottom, radius, !north && !west, !north && !east, !south && !east, !south && !west);
    } else {
        drawModuleRoundendLight(context, left, top, right, bottom, radius, north && west && northwest, north && east && northeast, south && east && southeast, south && west && southwest);
    }
}

function drawModules(qr, context, settings) {

    var moduleCount = qr.moduleCount;
    var moduleSize = settings.size / moduleCount;
    var fn = drawModuleDefault;
    var row, col;

    if (hasArcTo && settings.radius > 0 && settings.radius <= 0.5) {
        fn = drawModuleRounded;
    }

    context.beginPath();
    for (row = 0; row < moduleCount; row += 1) {
        for (col = 0; col < moduleCount; col += 1) {

            var l = settings.left + col * moduleSize,
                t = settings.top + row * moduleSize,
                w = moduleSize;

            fn(qr, context, settings, l, t, w, row, col);
        }
    }
    if ($(settings.fill).is('img')) {
        context.strokeStyle = 'rgba(0,0,0,0.5)';
        context.lineWidth = 2;
        context.stroke();
        var prev = context.globalCompositeOperation;
        context.globalCompositeOperation = "destination-out";
        context.fill();
        context.globalCompositeOperation = prev;

        context.clip();
        context.drawImage(settings.fill, 0, 0, settings.size, settings.size);
        context.restore();
    } else {
        context.fillStyle = settings.fill;
        context.fill();
    }
}

// Draws QR code to the given `canvas` and returns it.
function drawOnCanvas(canvas, settings) {

    var qr = createQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
    if (!qr) {
        return null;
    }

    var $canvas = $(canvas).data('qrcode', qr);
    var context = $canvas[0].getContext('2d');

    drawBackground(qr, context, settings);
    drawModules(qr, context, settings);

    return $canvas;
}

// Returns a `canvas` element representing the QR code for the given settings.
function createCanvas(settings) {

    var $canvas = $('').attr('width', settings.size).attr('height', settings.size);
    return drawOnCanvas($canvas, settings);
}

// Returns an `image` element representing the QR code for the given settings.
function createImage(settings) {

    return $('').attr('src', createCanvas(settings)[0].toDataURL('image/png'));
}

// Returns a `div` element representing the QR code for the given settings.
function createDiv(settings) {

    var qr = createQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
    if (!qr) {
        return null;
    }

    // some shortcuts to improve compression
    var settings_size = settings.size;
    var settings_bgColor = settings.background;
    var math_floor = Math.floor;

    var moduleCount = qr.moduleCount;
    var moduleSize = math_floor(settings_size / moduleCount);
    var offset = math_floor(0.5 * (settings_size - moduleSize * moduleCount));

    var row, col;

    var containerCSS = {
            position: 'relative',
            left: 0,
            top: 0,
            padding: 0,
            margin: 0,
            width: settings_size,
            height: settings_size
        };
    var darkCSS = {
            position: 'absolute',
            padding: 0,
            margin: 0,
            width: moduleSize,
            height: moduleSize,
            'background-color': settings.fill
        };

    var $div = $('
').data('qrcode', qr).css(containerCSS); if (settings_bgColor) { $div.css('background-color', settings_bgColor); } for (row = 0; row < moduleCount; row += 1) { for (col = 0; col < moduleCount; col += 1) { if (qr.isDark(row, col)) { $('
') .css(darkCSS) .css({ left: offset + col * moduleSize, top: offset + row * moduleSize }) .appendTo($div); } } } return $div; } function createHTML(settings) { if (hasCanvas && settings.render === 'canvas') { return createCanvas(settings); } else if (hasCanvas && settings.render === 'image') { return createImage(settings); } return createDiv(settings); } // Plugin // ====== // Default settings // ---------------- var defaults = { // render method: `'canvas'`, `'image'` or `'div'` render: 'canvas', // version range somewhere in 1 .. 40 minVersion: 1, maxVersion: 40, // error correction level: `'L'`, `'M'`, `'Q'` or `'H'` ecLevel: 'L', // offset in pixel if drawn onto existing canvas left: 0, top: 0, // size in pixel size: 200, // code color or image element fill: '#000', // background color or image element, `null` for transparent background background: null, // content text: 'no text', // corner radius relative to module width: 0.0 .. 0.5 radius: 0, // quiet zone in modules quiet: 0, // modes // 0: normal // 1: label strip // 2: label box // 3: image strip // 4: image box mode: 0, mSize: 0.1, mPosX: 0.5, mPosY: 0.5, label: 'no label', fontname: 'sans', fontcolor: '#000', image: null }; // Register the plugin // ------------------- $.fn.qrcode = function(options) { var settings = $.extend({}, defaults, options); return this.each(function () { if (this.nodeName.toLowerCase() === 'canvas') { drawOnCanvas(this, settings); } else { $(this).append(createHTML(settings)); } }); }; // jQuery.qrcode plug in code ends here // QR Code Generator // ================= //--------------------------------------------------------------------- // // 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.get(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 || 2; margin = (typeof margin == 'undefined')? cellSize * 4 : 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 || 2; margin = (typeof margin == 'undefined')? cellSize * 4 : 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.get = 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.get(i) ) + QRMath.glog(e.get(j) ) ); } } return qrPolynomial(num, 0); }; _this.mod = function(e) { if (_this.getLength() - e.getLength() < 0) { return _this; } var ratio = QRMath.glog(_this.get(0) ) - QRMath.glog(e.get(0) ); var num = new Array(_this.getLength() ); for (var i = 0; i < _this.getLength(); i += 1) { num[i] = _this.get(i); } for (var i = 0; i < e.getLength(); i += 1) { num[i] ^= QRMath.gexp(QRMath.glog(e.get(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], // 11 [4, 101, 81], [1, 80, 50, 4, 81, 51], [4, 50, 22, 4, 51, 23], [3, 36, 12, 8, 37, 13], // 12 [2, 116, 92, 2, 117, 93], [6, 58, 36, 2, 59, 37], [4, 46, 20, 6, 47, 21], [7, 42, 14, 4, 43, 15], // 13 [4, 133, 107], [8, 59, 37, 1, 60, 38], [8, 44, 20, 4, 45, 21], [12, 33, 11, 4, 34, 12], // 14 [3, 145, 115, 1, 146, 116], [4, 64, 40, 5, 65, 41], [11, 36, 16, 5, 37, 17], [11, 36, 12, 5, 37, 13], // 15 [5, 109, 87, 1, 110, 88], [5, 65, 41, 5, 66, 42], [5, 54, 24, 7, 55, 25], [11, 36, 12], // 16 [5, 122, 98, 1, 123, 99], [7, 73, 45, 3, 74, 46], [15, 43, 19, 2, 44, 20], [3, 45, 15, 13, 46, 16], // 17 [1, 135, 107, 5, 136, 108], [10, 74, 46, 1, 75, 47], [1, 50, 22, 15, 51, 23], [2, 42, 14, 17, 43, 15], // 18 [5, 150, 120, 1, 151, 121], [9, 69, 43, 4, 70, 44], [17, 50, 22, 1, 51, 23], [2, 42, 14, 19, 43, 15], // 19 [3, 141, 113, 4, 142, 114], [3, 70, 44, 11, 71, 45], [17, 47, 21, 4, 48, 22], [9, 39, 13, 16, 40, 14], // 20 [3, 135, 107, 5, 136, 108], [3, 67, 41, 13, 68, 42], [15, 54, 24, 5, 55, 25], [15, 43, 15, 10, 44, 16], // 21 [4, 144, 116, 4, 145, 117], [17, 68, 42], [17, 50, 22, 6, 51, 23], [19, 46, 16, 6, 47, 17], // 22 [2, 139, 111, 7, 140, 112], [17, 74, 46], [7, 54, 24, 16, 55, 25], [34, 37, 13], // 23 [4, 151, 121, 5, 152, 122], [4, 75, 47, 14, 76, 48], [11, 54, 24, 14, 55, 25], [16, 45, 15, 14, 46, 16], // 24 [6, 147, 117, 4, 148, 118], [6, 73, 45, 14, 74, 46], [11, 54, 24, 16, 55, 25], [30, 46, 16, 2, 47, 17], // 25 [8, 132, 106, 4, 133, 107], [8, 75, 47, 13, 76, 48], [7, 54, 24, 22, 55, 25], [22, 45, 15, 13, 46, 16], // 26 [10, 142, 114, 2, 143, 115], [19, 74, 46, 4, 75, 47], [28, 50, 22, 6, 51, 23], [33, 46, 16, 4, 47, 17], // 27 [8, 152, 122, 4, 153, 123], [22, 73, 45, 3, 74, 46], [8, 53, 23, 26, 54, 24], [12, 45, 15, 28, 46, 16], // 28 [3, 147, 117, 10, 148, 118], [3, 73, 45, 23, 74, 46], [4, 54, 24, 31, 55, 25], [11, 45, 15, 31, 46, 16], // 29 [7, 146, 116, 7, 147, 117], [21, 73, 45, 7, 74, 46], [1, 53, 23, 37, 54, 24], [19, 45, 15, 26, 46, 16], // 30 [5, 145, 115, 10, 146, 116], [19, 75, 47, 10, 76, 48], [15, 54, 24, 25, 55, 25], [23, 45, 15, 25, 46, 16], // 31 [13, 145, 115, 3, 146, 116], [2, 74, 46, 29, 75, 47], [42, 54, 24, 1, 55, 25], [23, 45, 15, 28, 46, 16], // 32 [17, 145, 115], [10, 74, 46, 23, 75, 47], [10, 54, 24, 35, 55, 25], [19, 45, 15, 35, 46, 16], // 33 [17, 145, 115, 1, 146, 116], [14, 74, 46, 21, 75, 47], [29, 54, 24, 19, 55, 25], [11, 45, 15, 46, 46, 16], // 34 [13, 145, 115, 6, 146, 116], [14, 74, 46, 23, 75, 47], [44, 54, 24, 7, 55, 25], [59, 46, 16, 1, 47, 17], // 35 [12, 151, 121, 7, 152, 122], [12, 75, 47, 26, 76, 48], [39, 54, 24, 14, 55, 25], [22, 45, 15, 41, 46, 16], // 36 [6, 151, 121, 14, 152, 122], [6, 75, 47, 34, 76, 48], [46, 54, 24, 10, 55, 25], [2, 45, 15, 64, 46, 16], // 37 [17, 152, 122, 4, 153, 123], [29, 74, 46, 14, 75, 47], [49, 54, 24, 10, 55, 25], [24, 45, 15, 46, 46, 16], // 38 [4, 152, 122, 18, 153, 123], [13, 74, 46, 32, 75, 47], [48, 54, 24, 14, 55, 25], [42, 45, 15, 32, 46, 16], // 39 [20, 147, 117, 4, 148, 118], [40, 75, 47, 7, 76, 48], [43, 54, 24, 22, 55, 25], [10, 45, 15, 67, 46, 16], // 40 [19, 148, 118, 6, 149, 119], [18, 75, 47, 31, 76, 48], [34, 54, 24, 34, 55, 25], [20, 45, 15, 61, 46, 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.get = 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 += '




© 2015 - 2024 Weber Informatics LLC | Privacy Policy