UNPKG

qrcoder

Version:

QRCoder is *a pure browser qrcode generation* which is standalone. It is based on a <a href='http://www.d-project.com/qrcode/index.html'>library</a> which build qrcode in various language.

173 lines (143 loc) 3.84 kB
import ByteArrayOutputStream from './bytearrayoutputstream' function BitOutputStream (out) { this._out = out this._bitLength = 0 this._bitBuffer = 0 } BitOutputStream.prototype = { write: function (data, length) { if ((data >>> length) !== 0) { throw new Error('length over') } while (this._bitLength + length >= 8) { this._out.writeByte(0xff & ((data << this._bitLength) | this._bitBuffer)) length -= (8 - this._bitLength) data >>>= (8 - this._bitLength) this._bitBuffer = 0 this._bitLength = 0 } this._bitBuffer = (data << this._bitLength) | this._bitBuffer this._bitLength = this._bitLength + length }, flush: function () { if (this._bitLength > 0) { this._out.writeByte(this._bitBuffer) } } } function LzwTable () { this._map = {} this._size = 0 } LzwTable.prototype = { add: function (key) { if (this.contains(key)) { throw new Error('dup key:' + key) } this._map[key] = this._size this._size += 1 }, size: function () { return this._size }, indexOf: function (key) { return this._map[key] }, contains: function (key) { return typeof this._map[key] !== 'undefined' } } function GifImage (width, height) { this._width = width this._height = height this._data = new Array(width * height) } GifImage.prototype = { setPixel: function (x, y, pixel) { this._data[y * this._width + x] = pixel }, write: function (out) { // GIF Signature out.writeString('GIF87a') // Screen Descriptor out.writeShort(this._width) out.writeShort(this._height) // 2bit out.writeByte(0x80) 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(this._width) out.writeShort(this._height) out.writeByte(0) // Local Color Map // Raster Data let lzwMinCodeSize = 2 let raster = this.getLZWRaster(lzwMinCodeSize) out.writeByte(lzwMinCodeSize) let 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(';') }, getLZWRaster: function (lzwMinCodeSize) { let clearCode = 1 << lzwMinCodeSize let endCode = (1 << lzwMinCodeSize) + 1 let bitLength = lzwMinCodeSize + 1 // Setup LZWTable let table = new LzwTable() for (let i = 0; i < clearCode; i += 1) { table.add(String.fromCharCode(i)) } table.add(String.fromCharCode(clearCode)) table.add(String.fromCharCode(endCode)) let byteOut = new ByteArrayOutputStream() let bitOut = new BitOutputStream(byteOut) // clear code bitOut.write(clearCode, bitLength) let dataIndex = 0 let s = String.fromCharCode(this._data[dataIndex]) dataIndex += 1 while (dataIndex < this._data.length) { let c = String.fromCharCode(this._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() } } export default GifImage