UNPKG

png-async

Version:

A simple and non-blocking PNG encoder / decoder.

75 lines 2.48 kB
"use strict"; const zlib = require("zlib"); const stream = require("stream"); const png = require("./index"); const constants = require("./constants"); const CrcStream = require("./crc"); const Filter = require("./filter"); class Packer extends stream.Readable { constructor(option) { super(); this._option = option; option.deflateChunkSize = option.deflateChunkSize || 32 * 1024; option.deflateLevel = option.deflateLevel || 9; if (option.deflateStrategy === undefined) { option.deflateStrategy = png.EDeflateStrategy.RLE; } this.readable = true; } pack(data, width, height) { // Signature this.emit("data", Buffer.from(constants.PNG_SIGNATURE)); this.emit("data", this._packIHDR(width, height)); // filter pixel data const filter = new Filter(width, height, 4, data, this._option); data = filter.filter(); // compress it const deflate = zlib.createDeflate({ chunkSize: this._option.deflateChunkSize, level: this._option.deflateLevel, strategy: this._option.deflateStrategy }); deflate.on("error", this.emit.bind(this, "error")); deflate.on("data", (data) => { this.emit("data", this._packIDAT(data)); }); deflate.on("end", () => { this.emit("data", this._packIEND()); this.emit("end"); }); deflate.end(data); } _read() { //todo } _packChunk(type, data) { const len = (data ? data.length : 0); const buf = Buffer.alloc(len + 12); buf.writeUInt32BE(len, 0); buf.writeUInt32BE(type, 4); if (data) { data.copy(buf, 8); } buf.writeInt32BE(CrcStream.crc32(buf.slice(4, buf.length - 4)), buf.length - 4); return buf; } _packIHDR(width, height) { const buf = Buffer.alloc(13); buf.writeUInt32BE(width, 0); buf.writeUInt32BE(height, 4); buf[8] = 8; buf[9] = 6; // colorType buf[10] = 0; // compression buf[11] = 0; // filter buf[12] = 0; // interlace return this._packChunk(constants.TYPE_IHDR, buf); } _packIDAT(data) { return this._packChunk(constants.TYPE_IDAT, data); } _packIEND() { return this._packChunk(constants.TYPE_IEND, null); } } module.exports = Packer; //# sourceMappingURL=packer.js.map