Return a correct alpha value in the metadata callback when a tRNS chunk is present (#119)

* Fix "metadata" alpha property to respect presence of tRNS chunk

* Emit metadata at first IDAT chunk

* Fix typo
This commit is contained in:
Liam McLoughlin 2019-03-08 05:27:54 +00:00 committed by Luke Page
parent 2d78949365
commit decc76f686
4 changed files with 36 additions and 5 deletions

View file

@ -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) {

View file

@ -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();

View file

@ -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) {

View file

@ -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();
});
});