diff --git a/lib/parser-async.js b/lib/parser-async.js index b52d573..f27cd71 100644 --- a/lib/parser-async.js +++ b/lib/parser-async.js @@ -19,7 +19,9 @@ var ParserAsync = module.exports = function(options) { palette: this._handlePalette.bind(this), transColor: this._handleTransColor.bind(this), finished: this._finished.bind(this), - inflateData: this._inflateData.bind(this) + inflateData: this._inflateData.bind(this), + simpleTransparency: this._simpleTransparency.bind(this), + headersFinished: this._headersFinished.bind(this) }); this._options = options; this.writable = true; @@ -101,9 +103,7 @@ ParserAsync.prototype._inflateData = function(data) { }; ParserAsync.prototype._handleMetaData = function(metaData) { - - this.emit('metadata', metaData); - + this._metaData = metaData; this._bitmapInfo = Object.create(metaData); this._filter = new FilterAsync(this._bitmapInfo); @@ -117,6 +117,15 @@ ParserAsync.prototype._handlePalette = function(palette) { this._bitmapInfo.palette = palette; }; +ParserAsync.prototype._simpleTransparency = function() { + this._metaData.alpha = true; +}; + +ParserAsync.prototype._headersFinished = function() { + // Up until this point, we don't know if we have a tRNS chunk (alpha) + // so we can't emit metadata any earlier + this.emit('metadata', this._metaData); +}; ParserAsync.prototype._finished = function() { if (this.errord) { diff --git a/lib/parser-sync.js b/lib/parser-sync.js index 07d7091..d85f89f 100644 --- a/lib/parser-sync.js +++ b/lib/parser-sync.js @@ -37,6 +37,10 @@ module.exports = function(buffer, options) { metaData.palette = palette; } + function handleSimpleTransparency() { + metaData.alpha = true; + } + var gamma; function handleGamma(_gamma_) { gamma = _gamma_; @@ -56,7 +60,8 @@ module.exports = function(buffer, options) { gamma: handleGamma, palette: handlePalette, transColor: handleTransColor, - inflateData: handleInflateData + inflateData: handleInflateData, + simpleTransparency: handleSimpleTransparency }); parser.start(); diff --git a/lib/parser.js b/lib/parser.js index b730c8f..aac1599 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -11,6 +11,7 @@ var Parser = module.exports = function(options, dependencies) { this._hasIHDR = false; this._hasIEND = false; + this._emittedHeadersFinished = false; // input flags/metadata this._palette = []; @@ -33,6 +34,8 @@ var Parser = module.exports = function(options, dependencies) { this.parsed = dependencies.parsed; this.inflateData = dependencies.inflateData; this.finished = dependencies.finished; + this.simpleTransparency = dependencies.simpleTransparency; + this.headersFinished = dependencies.headersFinished || function(){}; }; Parser.prototype.start = function() { @@ -205,6 +208,7 @@ Parser.prototype._parsePLTE = function(data) { }; Parser.prototype._handleTRNS = function(length) { + this.simpleTransparency(); this.read(length, this._parseTRNS.bind(this)); }; Parser.prototype._parseTRNS = function(data) { @@ -252,6 +256,10 @@ Parser.prototype._parseGAMA = function(data) { }; Parser.prototype._handleIDAT = function(length) { + if (!this._emittedHeadersFinished) { + this._emittedHeadersFinished = true; + this.headersFinished(); + } this.read(-length, this._parseIDAT.bind(this, length)); }; Parser.prototype._parseIDAT = function(length, data) { diff --git a/test/png-parse-spec.js b/test/png-parse-spec.js index 61aa587..47b36d5 100644 --- a/test/png-parse-spec.js +++ b/test/png-parse-spec.js @@ -319,3 +319,12 @@ test("should return an error if a PNG is normal except for a missing IEND", func t.end(); }); }); + +test("should set alpha=true in metadata for images with tRNS chunk", function (t) { + fs.createReadStream(path.join(__dirname, "in", "tbbn0g04.png")) + .pipe(new PNG()) + .on('metadata', function (metadata) { + t.ok(metadata.alpha, "Image should have alpha=true"); + t.end(); + }); +});