diff --git a/lib/bitmapper.js b/lib/bitmapper.js index 2591b95..c59f1f6 100644 --- a/lib/bitmapper.js +++ b/lib/bitmapper.js @@ -135,7 +135,13 @@ function mapImageCustomBit(image, pxData, getPxPos, bpp, bits, maxBit) { // esli } } -exports.dataToBitMap = function(data, width, height, bpp, depth, interlace) { +exports.dataToBitMap = function(data, bitmapInfo) { + + var width = bitmapInfo.width; + var height = bitmapInfo.height; + var depth = bitmapInfo.depth; + var bpp = bitmapInfo.bpp; + var interlace = bitmapInfo.interlace; if (depth !== 8) { var bits = bitRetriever(data, depth); diff --git a/lib/filter-parse-async.js b/lib/filter-parse-async.js index 37f1790..560c30e 100644 --- a/lib/filter-parse-async.js +++ b/lib/filter-parse-async.js @@ -5,18 +5,18 @@ var ChunkStream = require('./chunkstream'); var Filter = require('./filter-parse'); -var FilterAsync = module.exports = function(width, height, Bpp, depth, interlace) { +var FilterAsync = module.exports = function(bitmapInfo) { ChunkStream.call(this); var buffers = []; var that = this; - this._filter = new Filter(width, height, Bpp, depth, interlace, { + this._filter = new Filter(bitmapInfo, { read: this.read.bind(this), - complete: function() { - that.emit('complete', Buffer.concat(buffers), width, height); - }, write: function(buffer) { buffers.push(buffer); + }, + complete: function() { + that.emit('complete', Buffer.concat(buffers)); } }); diff --git a/lib/filter-parse-sync.js b/lib/filter-parse-sync.js index 308c886..958c676 100644 --- a/lib/filter-parse-sync.js +++ b/lib/filter-parse-sync.js @@ -4,11 +4,11 @@ var SyncReader = require('./sync-reader'); var Filter = require('./filter-parse'); -exports.process = function(inBuffer, width, height, Bpp, depth, interlace) { +exports.process = function(inBuffer, bitmapInfo) { var outBuffers = []; var reader = new SyncReader(inBuffer); - var filter = new Filter(width, height, Bpp, depth, interlace, { + var filter = new Filter(bitmapInfo, { read: reader.read.bind(reader), write: function(bufferPart) { outBuffers.push(bufferPart); diff --git a/lib/filter-parse.js b/lib/filter-parse.js index 84d9de4..3f0e14b 100644 --- a/lib/filter-parse.js +++ b/lib/filter-parse.js @@ -11,12 +11,13 @@ function getByteWidth(width, bpp, depth) { return byteWidth; } -var Filter = module.exports = function(width, height, Bpp, depth, interlace, dependencies) { +var Filter = module.exports = function(bitmapInfo, dependencies) { - this._width = width; - this._height = height; - this._Bpp = Bpp; //TODO rename - this._depth = depth; + var width = bitmapInfo.width; + var height = bitmapInfo.height; + var interlace = bitmapInfo.interlace; + var bpp = bitmapInfo.bpp; + var depth = bitmapInfo.depth; this.read = dependencies.read; this.write = dependencies.write; @@ -28,7 +29,7 @@ var Filter = module.exports = function(width, height, Bpp, depth, interlace, dep var passes = interlaceUtils.getImagePasses(width, height); for (var i = 0; i < passes.length; i++) { this._images.push({ - byteWidth: getByteWidth(passes[i].width, Bpp, depth), + byteWidth: getByteWidth(passes[i].width, bpp, depth), height: passes[i].height, lineIndex: 0 }); @@ -36,7 +37,7 @@ var Filter = module.exports = function(width, height, Bpp, depth, interlace, dep } else { this._images.push({ - byteWidth: getByteWidth(width, Bpp, depth), + byteWidth: getByteWidth(width, bpp, depth), height: height, lineIndex: 0 }); @@ -47,10 +48,10 @@ var Filter = module.exports = function(width, height, Bpp, depth, interlace, dep // so if the depth is byte compatible (8 or 16) we subtract the bpp in order to compare back // a pixel rather than just a different byte part. However if we are sub byte, we ignore. if (depth === 8) { - this._xComparison = Bpp; + this._xComparison = bpp; } else if (depth === 16) { - this._xComparison = this._Bpp * 2; + this._xComparison = bpp * 2; } else { this._xComparison = 1; @@ -164,6 +165,7 @@ Filter.prototype._reverseFilterLine = function(rawData) { this.read(currentImage.byteWidth + 1, this._reverseFilterLine.bind(this)); } else { - this.complete(this._width, this._height); + this._lastLine = null; + this.complete(); } }; diff --git a/lib/parser-async.js b/lib/parser-async.js index f245a62..ef36667 100644 --- a/lib/parser-async.js +++ b/lib/parser-async.js @@ -14,11 +14,12 @@ var ParserAsync = module.exports = function(options) { this._parser = new Parser(options, { read: this.read.bind(this), error: this._handleError.bind(this), - metadata: this.emit.bind(this, 'metadata'), + metadata: this._handleMetaData.bind(this), gamma: this.emit.bind(this, 'gamma'), + palette: this._handlePalette.bind(this), + transColor: this._handleTransColor.bind(this), finished: this._finished.bind(this), - inflateData: this._inflateData.bind(this), - bitmapInfo: this._handleBitmapInfo.bind(this) + inflateData: this._inflateData.bind(this) }); this._options = options; this.writable = true; @@ -55,20 +56,24 @@ ParserAsync.prototype._inflateData = function(data) { this._inflate.write(data); }; -ParserAsync.prototype._handleBitmapInfo = function(width, height, bpp, depth, interlace) { +ParserAsync.prototype._handleMetaData = function(metaData) { - this._bpp = bpp; - this._depth = depth; - this._interlace = interlace; + this.emit('metadata', metaData); - this._filter = new FilterAsync( - width, height, - bpp, - depth, - interlace - ); + this._bitmapInfo = Object.create(metaData); + + this._filter = new FilterAsync(this._bitmapInfo); }; +ParserAsync.prototype._handleTransColor = function(transColor) { + this._bitmapInfo.transColor = transColor; +}; + +ParserAsync.prototype._handlePalette = function(palette) { + this._bitmapInfo.palette = palette; +}; + + ParserAsync.prototype._finished = function() { if (this.errord) { return; @@ -84,31 +89,22 @@ ParserAsync.prototype._finished = function() { this.destroySoon(); }; -ParserAsync.prototype._complete = function(filteredData, width, height) { +ParserAsync.prototype._complete = function(filteredData) { if (this.errord) { return; } try { - var bitmapData = bitmapper.dataToBitMap(filteredData, width, height, - this._bpp, - this._depth, - this._interlace); + var bitmapData = bitmapper.dataToBitMap(filteredData, this._bitmapInfo); - // todo not bitmap data any more - bitmapData = formatNormaliser(bitmapData, { - depth: this._depth, // TODO always store in this format - width: width, - height: height, - colorType: this._parser._colorType, - palette: this._parser._palette, - transColor: this._parser._transColor }); + var normalisedBitmapData = formatNormaliser(bitmapData, this._bitmapInfo); + bitmapData = null; } catch (ex) { this._handleError(ex); return; } - this.emit('parsed', bitmapData); + this.emit('parsed', normalisedBitmapData); }; diff --git a/lib/parser-sync.js b/lib/parser-sync.js index 875e9e1..126fabe 100644 --- a/lib/parser-sync.js +++ b/lib/parser-sync.js @@ -16,19 +16,18 @@ module.exports = function(buffer, options) { err = _err_; } - var bpp, width, height, depth, interlace; - function handleBitmapInfo(_width_, _height_, _bpp_, _depth_, _interlace_) { - - bpp = _bpp_; - width = _width_; - height = _height_; - depth = _depth_; - interlace = _interlace_; - } - - var metaData; + var metaData, bitmapInfo; function handleMetaData(_metaData_) { metaData = _metaData_; + bitmapInfo = Object.create(metaData); + } + + function handleTransColor(transColor) { + bitmapInfo.transColor = transColor; + } + + function handlePalette(palette) { + bitmapInfo.palette = palette; } var gamma; @@ -48,8 +47,9 @@ module.exports = function(buffer, options) { error: handleError, metadata: handleMetaData, gamma: handleGamma, - inflateData: handleInflateData, - bitmapInfo: handleBitmapInfo + palette: handlePalette, + transColor: handleTransColor, + inflateData: handleInflateData }); parser.start(); @@ -70,29 +70,13 @@ module.exports = function(buffer, options) { throw new Error('bad png - invalid inflate data response'); } - var unfilteredData = FilterSync.process( - inflatedData, - width, - height, - bpp, - depth, - interlace - ); + var unfilteredData = FilterSync.process(inflatedData, bitmapInfo); inflateData = null; - var bitmapData = bitmapper.dataToBitMap(unfilteredData, width, height, - bpp, - depth, - interlace); + var bitmapData = bitmapper.dataToBitMap(unfilteredData, bitmapInfo); unfilteredData = null; - var normalisedBitmapData = formatNormaliser(bitmapData, { - depth: depth, // TODO always store in this format - width: width, - height: height, - colorType: parser._colorType, //TODO event this - palette: parser._palette, - transColor: parser._transColor }); + var normalisedBitmapData = formatNormaliser(bitmapData, bitmapInfo); metaData.data = normalisedBitmapData; metaData.gamma = gamma || 0; diff --git a/lib/parser.js b/lib/parser.js index 845ee2c..4573794 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -28,8 +28,10 @@ var Parser = module.exports = function(options, dependencies) { this.error = dependencies.error; this.metadata = dependencies.metadata; this.gamma = dependencies.gamma; + this.transColor = dependencies.transColor; + this.palette = dependencies.palette; this.parsed = dependencies.parsed; - this.bitmapInfo = dependencies.bitmapInfo; + this.inflateData = dependencies.inflateData; this.inflateData = dependencies.inflateData; this.finished = dependencies.finished; }; @@ -168,7 +170,6 @@ Parser.prototype._parseIHDR = function(data) { this._colorType = colorType; var bpp = colorTypeToBppMap[this._colorType]; - this.bitmapInfo(width, height, bpp, depth, interlace, colorType); this._hasIHDR = true; @@ -179,7 +180,9 @@ Parser.prototype._parseIHDR = function(data) { interlace: Boolean(interlace), palette: Boolean(colorType & constants.COLOR_PALETTE), color: Boolean(colorType & constants.COLOR_COLOR), - alpha: Boolean(colorType & constants.COLOR_ALPHA) + alpha: Boolean(colorType & constants.COLOR_ALPHA), + bpp: bpp, + colorType: colorType }); this._handleChunkEnd(); @@ -205,6 +208,8 @@ Parser.prototype._parsePLTE = function(data) { ]); } + this.palette(this._palette); + this._handleChunkEnd(); }; @@ -225,19 +230,20 @@ Parser.prototype._parseTRNS = function(data) { this.error(new Error('More transparent colors than palette size')); return; } - for (var i = 0; i < this._palette.length; i++) { - this._palette[i][3] = i < data.length ? data[i] : 0xff; + for (var i = 0; i < data.length; i++) { + this._palette[i][3] = data[i]; } + this.palette(this._palette); } // for colorType 0 (grayscale) and 2 (rgb) // there might be one gray/color defined as transparent if (this._colorType === 0) { // grey, 2 bytes - this._transColor = [data.readUInt16BE(0)]; + this.transColor([data.readUInt16BE(0)]); } if (this._colorType === 2) { - this._transColor = [data.readUInt16BE(0), data.readUInt16BE(2), data.readUInt16BE(4)]; + this.transColor([data.readUInt16BE(0), data.readUInt16BE(2), data.readUInt16BE(4)]); } this._handleChunkEnd();