From b9293eaa2b5e6fcd93e8ef3e10fedbac753c506a Mon Sep 17 00:00:00 2001 From: Luke Page Date: Sun, 2 Aug 2015 23:09:08 +0100 Subject: [PATCH] support for transparent colour blocks without palettes --- lib/bitmapper.js | 22 +++++++--------- lib/parser.js | 66 ++++++++++++++++++++++++++++++++++++++---------- test/test.js | 2 +- 3 files changed, 62 insertions(+), 28 deletions(-) diff --git a/lib/bitmapper.js b/lib/bitmapper.js index 1be31d8..6fa1823 100644 --- a/lib/bitmapper.js +++ b/lib/bitmapper.js @@ -17,8 +17,7 @@ function bitRetriever(data, depth) { case 16: var byte2 = data[i]; i++; - byte = Math.floor((((byte << 8) + byte2) * 255) / (Math.pow(2, 16) - 1) + 0.5); - leftOver.push(byte); + leftOver.push(((byte << 8) + byte2)); break; case 4: var byte2 = byte & 0x0f; @@ -70,8 +69,14 @@ exports.dataToBitMap = function(data, width, height, bpp, depth, interlace) { if (depth !== 8) { var bits = bitRetriever(data, depth); } - var pxData = new Buffer(width * height * 4); - var maxBit = depth >= 8 ? 255 : (Math.pow(2, depth) - 1); + var pxData; + if (depth <= 8) { + pxData = new Buffer(width * height * 4); + } else { + // TODO: could be more effecient and use a buffer but change how we write to use 16 bit write methods with index * 2 + pxData = new Array(width * height * 4); + } + var maxBit = Math.pow(2, depth) - 1; var rawPos = 0; var pixelData; var images; @@ -90,15 +95,6 @@ exports.dataToBitMap = function(data, width, height, bpp, depth, interlace) { images = [{width: width, height: height}]; } - for (var y = 0; y < height; y++) { - for (var x = 0; x < width; x++) { - pxData[(y * 4 * width) + (x * 4) + 0] = 255; - pxData[(y * 4 * width) + (x * 4) + 1] = 0; - pxData[(y * 4 * width) + (x * 4) + 2] = 0; - pxData[(y * 4 * width) + (x * 4) + 3] = 255; - } - } - for(var imageIndex = 0; imageIndex < images.length; imageIndex++) { var imageWidth = images[imageIndex].width; var imageHeight = images[imageIndex].height; diff --git a/lib/parser.js b/lib/parser.js index cce23c2..72bb3c5 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -252,6 +252,13 @@ Parser.prototype._parseTRNS = function(data) { // 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)]; + } + if (this._colorType === 2) { + this._transColor = [data.readUInt16BE(0), data.readUInt16BE(2), data.readUInt16BE(4)]; + } this._handleChunkEnd(); }; @@ -300,7 +307,9 @@ Parser.prototype._parseIEND = function(data) { this.finished(); }; -Parser.prototype.reverseFiltered = function(data, depth, width, height) { +Parser.prototype.reverseFiltered = function(indata, depth, width, height) { + + var outdata = indata; // only different for 16 bits if (this._colorType == 3) { // paletted //console.log("paletted"); @@ -312,28 +321,57 @@ Parser.prototype.reverseFiltered = function(data, depth, width, height) { for (var x = 0; x < width; x++) { var pxPos = pxRowPos + (x << 2), - color = this._palette[data[pxPos]]; + color = this._palette[indata[pxPos]]; for (var i = 0; i < 4; i++) - data[pxPos + i] = color[i]; + indata[pxPos + i] = color[i]; } } - } else if (depth < 8) { - //console.log("adjusting"); + } else { var pxLineLength = width << 2; - var maxOutSample = 255; - var maxInSample = Math.pow(2, depth) - 1; - for (var y = 0; y < height; y++) { - var pxRowPos = y * pxLineLength; + if (this._transColor) { + for (var y = 0; y < height; y++) { + var pxRowPos = y * pxLineLength; - for (var x = 0; x < width; x++) { - var pxPos = pxRowPos + (x << 2); - for (var i = 0; i < 4; i++) - data[pxPos + i] = Math.floor((data[pxPos + i] * maxOutSample) / maxInSample + 0.5); + for (var x = 0; x < width; x++) { + var pxPos = pxRowPos + (x << 2); + var makeTrans = false; + //console.log(pxPos); + if (this._transColor.length === 1) { + if (this._transColor[0] === indata[pxPos]) { + makeTrans = true; + } + } else if (this._transColor[0] === indata[pxPos] && this._transColor[1] === indata[pxPos + 1] && this._transColor[2] === indata[pxPos + 2]) { + makeTrans = true; + } + if (makeTrans) { + for (var i = 0; i < 4; i++) { + indata[pxPos + i] = 0; + } + } + } + } + } + if (depth !== 8) { + if (depth === 16) { + outdata = new Buffer(width * height * 4); + } + //console.log("adjusting"); + var maxOutSample = 255; + var maxInSample = Math.pow(2, depth) - 1; + + for (var y = 0; y < height; y++) { + var pxRowPos = y * pxLineLength; + + for (var x = 0; x < width; x++) { + var pxPos = pxRowPos + (x << 2); + for (var i = 0; i < 4; i++) + outdata[pxPos + i] = Math.floor((indata[pxPos + i] * maxOutSample) / maxInSample + 0.5); + } } } } - return data; + return outdata; }; diff --git a/test/test.js b/test/test.js index ac2ab5f..805ba76 100644 --- a/test/test.js +++ b/test/test.js @@ -7,7 +7,7 @@ fs.readdir(__dirname + '/in/', function(err, files) { files.forEach(function(file) { - if (!file.match(/.*\.png$/i)) + if (!file.match(/\.png$/i)) return; var expectedError = false;