diff --git a/.eslintrc b/.eslintrc index 8560625..5028354 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,10 +2,10 @@ "ecmaFeatures": {}, "rules": { "no-alert": 2, - "no-array-constructor": 1, + "no-array-constructor": 0, "no-bitwise": 0, "no-caller": 2, - "no-catch-shadow": 1, + "no-catch-shadow": 2, "no-class-assign": 2, "no-cond-assign": 2, "no-console": 2, @@ -26,15 +26,15 @@ "no-eq-null": 0, "no-eval": 2, "no-ex-assign": 2, - "no-extend-native": 0, + "no-extend-native": 2, "no-extra-bind": 1, "no-extra-boolean-cast": 2, "no-extra-parens": 0, "no-extra-semi": 2, "no-fallthrough": 2, - "no-floating-decimal": 0, + "no-floating-decimal": 1, "no-func-assign": 2, - "no-implicit-coercion": 0, + "no-implicit-coercion": 1, "no-implied-eval": 1, "no-inline-comments": 0, "no-inner-declarations": [2, "functions"], @@ -45,26 +45,26 @@ "no-label-var": 1, "no-labels": 1, "no-lone-blocks": 1, - "no-lonely-if": 0, + "no-lonely-if": 1, "no-loop-func": 1, - "no-mixed-requires": [0, false], + "no-mixed-requires": [1, false], "no-mixed-spaces-and-tabs": [2, false], "linebreak-style": [0, "unix"], "no-multi-spaces": 1, "no-multi-str": 0, - "no-multiple-empty-lines": [0, {"max": 2}], - "no-native-reassign": 0, + "no-multiple-empty-lines": [1, {"max": 2}], + "no-native-reassign": 2, "no-negated-in-lhs": 2, - "no-nested-ternary": 0, - "no-new": 0, - "no-new-func": 0, - "no-new-object": 0, - "no-new-require": 0, - "no-new-wrappers": 0, + "no-nested-ternary": 1, + "no-new": 1, + "no-new-func": 1, + "no-new-object": 1, + "no-new-require": 1, + "no-new-wrappers": 1, "no-obj-calls": 2, "no-octal": 2, "no-octal-escape": 0, - "no-param-reassign": 0, + "no-param-reassign": 1, "no-path-concat": 0, "no-plusplus": 0, "no-process-env": 0, @@ -73,23 +73,23 @@ "no-redeclare": 2, "no-regex-spaces": 2, "no-restricted-modules": 0, - "no-return-assign": 0, + "no-return-assign": 1, "no-script-url": 0, - "no-self-compare": 0, - "no-sequences": 0, + "no-self-compare": 1, + "no-sequences": 1, "no-shadow": 1, - "no-shadow-restricted-names": 0, + "no-shadow-restricted-names": 1, "no-spaced-func": 1, "no-sparse-arrays": 2, "no-sync": 0, "no-ternary": 0, "no-trailing-spaces": 1, - "no-this-before-super": 0, - "no-throw-literal": 0, + "no-this-before-super": 1, + "no-throw-literal": 1, "no-undef": 2, - "no-undef-init": 0, + "no-undef-init": 1, "no-undefined": 0, - "no-unexpected-multiline": 0, + "no-unexpected-multiline": 1, "no-underscore-dangle": 0, "no-unneeded-ternary": 0, "no-unreachable": 2, @@ -99,73 +99,75 @@ "no-useless-call": 2, "no-void": 0, "no-var": 0, - "no-warning-comments": [0, { "terms": ["todo", "fixme", "xxx"], "location": "start" }], - "no-with": 0, + "no-warning-comments": [1, { "terms": ["todo", "fixme", "xxx"], "location": "start" }], + "no-with": 1, - "array-bracket-spacing": [0, "never"], - "arrow-parens": 0, - "arrow-spacing": 0, - "accessor-pairs": 0, + "array-bracket-spacing": [1, "never"], + "arrow-parens": 1, + "arrow-spacing": 1, + "accessor-pairs": 1, "block-scoped-var": 0, - "brace-style": [0, "1tbs"], - "callback-return": 0, - "camelcase": 0, + "brace-style": [1, "1tbs"], + "callback-return": [2, ["callback", "cb", "next"]], + "camelcase": [2, {"properties": "always"}], "comma-dangle": [2, "never"], - "comma-spacing": 0, - "comma-style": 0, - "complexity": [0, 11], + "comma-spacing": 2, + "comma-style": 1, + "complexity": [1, 10], "computed-property-spacing": [0, "never"], "consistent-return": 0, "consistent-this": [0, "that"], - "constructor-super": 0, - "curly": [0, "all"], - "default-case": 0, - "dot-location": 0, - "dot-notation": [0, { "allowKeywords": true }], + "constructor-super": 1, + "curly": [1, "all"], + "default-case": 1, + "dot-location": [1, "property"], + "dot-notation": [1, { "allowKeywords": true }], "eol-last": 0, - "eqeqeq": 0, + "eqeqeq": 1, "func-names": 0, "func-style": [0, "declaration"], "generator-star-spacing": 0, - "guard-for-in": 0, - "handle-callback-err": 0, - "id-length": 0, - "indent": 0, + "guard-for-in": 1, + "handle-callback-err": 2, + "id-length": [2, {"min": 3, "max": 20, "exceptions":["x", "y", "i", "j"]}], + "indent": [1, 2, {"SwitchCase": 1}], "init-declarations": 0, - "key-spacing": [0, { "beforeColon": false, "afterColon": true }], + "key-spacing": [1, { "beforeColon": false, "afterColon": true }], "lines-around-comment": 0, - "max-depth": [0, 4], - "max-len": [0, 80, 4], - "max-nested-callbacks": [0, 2], - "max-params": [0, 3], - "max-statements": [0, 10], - "new-cap": 0, - "new-parens": 0, + "max-depth": [1, 4], + "max-len": [1, 160, 2], + "max-nested-callbacks": [1, 2], + "max-params": [1, 5], + "max-statements": [1, 30], + "new-cap": 1, + "new-parens": 1, "newline-after-var": 0, - "object-curly-spacing": [0, "never"], + "object-curly-spacing": [1, "always"], "object-shorthand": 0, - "one-var": 0, + "one-var": [1, { + "initialized": "never" + }], "operator-assignment": [0, "always"], - "operator-linebreak": 0, + "operator-linebreak": [1, "after"], "padded-blocks": 0, "prefer-const": 0, "prefer-spread": 0, "prefer-reflect": 0, "quote-props": 0, - "quotes": [0, "double"], + "quotes": [1, "single"], "radix": 0, "id-match": 0, "require-yield": 0, - "semi": 0, - "semi-spacing": [0, {"before": false, "after": true}], + "semi": [1, "always"], + "semi-spacing": [1, {"before": false, "after": true}], "sort-vars": 0, - "space-after-keywords": [0, "always"], - "space-before-blocks": [0, "always"], - "space-before-function-paren": [0, "always"], - "space-in-parens": [0, "never"], - "space-infix-ops": 0, - "space-return-throw-case": 0, - "space-unary-ops": [0, { "words": true, "nonwords": false }], + "space-after-keywords": [1, "always"], + "space-before-blocks": [1, "always"], + "space-before-function-paren": [1, "never"], + "space-in-parens": [1, "never"], + "space-infix-ops": 1, + "space-return-throw-case": 1, + "space-unary-ops": [1, { "words": true, "nonwords": false }], "spaced-comment": 0, "strict": [2, "global"], "use-isnan": 2, diff --git a/lib/bitmapper.js b/lib/bitmapper.js index a6f3c11..2810302 100644 --- a/lib/bitmapper.js +++ b/lib/bitmapper.js @@ -33,16 +33,17 @@ function bitRetriever(data, depth) { var leftOver = []; var i = 0; + function split() { if (i === data.length) { - throw new Error("Ran out of data"); + throw new Error('Ran out of data'); } var byte = data[i]; i++; - var byte8, byte7, byte6, byte5, byte4, byte3, byte2, byte1 - switch(depth) { + var byte8, byte7, byte6, byte5, byte4, byte3, byte2, byte1; + switch (depth) { default: - throw new Error("unrecognised depth"); + throw new Error('unrecognised depth'); case 16: byte2 = data[i]; i++; @@ -73,9 +74,10 @@ function bitRetriever(data, depth) { break; } } + return { get: function(count) { - while(leftOver.length < count) { + while (leftOver.length < count) { split(); } var returner = leftOver.slice(0, count); @@ -87,7 +89,8 @@ function bitRetriever(data, depth) { }, end: function() { if (i !== data.length) { - throw new Error("extra data found"); + // todo these exceptions should be emitting errors + throw new Error('extra data found'); } } }; @@ -120,10 +123,10 @@ exports.dataToBitMap = function(data, width, height, bpp, depth, interlace) { nonInterlacedPxPos += 4; return returner; }; - images = [{width: width, height: height}]; + images = [{ width: width, height: height }]; } - for(var imageIndex = 0; imageIndex < images.length; imageIndex++) { + for (var imageIndex = 0; imageIndex < images.length; imageIndex++) { var imageWidth = images[imageIndex].width; var imageHeight = images[imageIndex].height; var imagePass = images[imageIndex].index; @@ -138,7 +141,7 @@ exports.dataToBitMap = function(data, width, height, bpp, depth, interlace) { var idx = pixelBppMap[bpp][i]; if (depth === 8) { if (i === data.length) { - throw new Error("Ran out of data"); + throw new Error('Ran out of data'); } pxData[pxPos + i] = idx !== 0xff ? data[idx + rawPos] : maxBit; } else { @@ -155,7 +158,7 @@ exports.dataToBitMap = function(data, width, height, bpp, depth, interlace) { } if (depth === 8) { if (rawPos !== data.length) { - throw new Error("extra data found"); + throw new Error('extra data found'); } } else { bits.end(); diff --git a/lib/chunkstream.js b/lib/chunkstream.js index feff3e4..f6e8939 100755 --- a/lib/chunkstream.js +++ b/lib/chunkstream.js @@ -21,180 +21,189 @@ 'use strict'; -var util = require('util'), - Stream = require('stream'); +var util = require('util'); +var Stream = require('stream'); var ChunkStream = module.exports = function() { - Stream.call(this); + Stream.call(this); - this._buffers = []; - this._buffered = 0; + this._buffers = []; + this._buffered = 0; - this._reads = []; - this._paused = false; + this._reads = []; + this._paused = false; - this._encoding = 'utf8'; - this.writable = true; + this._encoding = 'utf8'; + this.writable = true; }; util.inherits(ChunkStream, Stream); ChunkStream.prototype.read = function(length, callback) { - this._reads.push({ - length: Math.abs(length), // if length < 0 then at most this length - allowLess: length < 0, - func: callback - }); + this._reads.push({ + length: Math.abs(length), // if length < 0 then at most this length + allowLess: length < 0, + func: callback + }); - process.nextTick(function() { - this._process(); + process.nextTick(function() { + this._process(); - // its paused and there is not enought data then ask for more - if (this._paused && this._reads.length > 0) { - this._paused = false; + // its paused and there is not enought data then ask for more + if (this._paused && this._reads.length > 0) { + this._paused = false; - this.emit('drain'); - } - }.bind(this)); + this.emit('drain'); + } + }.bind(this)); }; ChunkStream.prototype.write = function(data, encoding) { - if (!this.writable) { - this.emit('error', new Error('Stream not writable')); - return false; - } + if (!this.writable) { + this.emit('error', new Error('Stream not writable')); + return false; + } - if (!Buffer.isBuffer(data)) - data = new Buffer(data, encoding || this._encoding); + var dataBuffer; + if (Buffer.isBuffer(data)) { + dataBuffer = data; + } else { + dataBuffer = new Buffer(data, encoding || this._encoding); + } - this._buffers.push(data); - this._buffered += data.length; + this._buffers.push(dataBuffer); + this._buffered += dataBuffer.length; - this._process(); + this._process(); - // ok if there are no more read requests - if (this._reads && this._reads.length == 0) - this._paused = true; + // ok if there are no more read requests + if (this._reads && this._reads.length == 0) { + this._paused = true; + } - return this.writable && !this._paused; + return this.writable && !this._paused; }; ChunkStream.prototype.end = function(data, encoding) { - if (data) this.write(data, encoding); + if (data) { + this.write(data, encoding); + } - this.writable = false; + this.writable = false; - // already destroyed - if (!this._buffers) return; + // already destroyed + if (!this._buffers) return; - // enqueue or handle end - if (this._buffers.length == 0) { - this._end(); - } else { - this._buffers.push(null); - this._process(); - } + // enqueue or handle end + if (this._buffers.length == 0) { + this._end(); + } else { + this._buffers.push(null); + this._process(); + } }; ChunkStream.prototype.destroySoon = ChunkStream.prototype.end; ChunkStream.prototype._end = function() { - if (this._reads.length > 0) { - this.emit('error', - new Error('There are some read requests waitng on finished stream') - ); - } + if (this._reads.length > 0) { + this.emit('error', + new Error('There are some read requests waitng on finished stream') + ); + } - this.destroy(); + this.destroy(); }; ChunkStream.prototype.destroy = function() { - if (!this._buffers) return; + if (!this._buffers) { + return; + } - this.writable = false; - this._reads = null; - this._buffers = null; + this.writable = false; + this._reads = null; + this._buffers = null; - this.emit('close'); + this.emit('close'); }; ChunkStream.prototype._process = function() { - // as long as there is any data and read requests - while (this._buffered > 0 && this._reads && this._reads.length > 0) { + // as long as there is any data and read requests + while (this._buffered > 0 && this._reads && this._reads.length > 0) { - var read = this._reads[0]; + var read = this._reads[0]; - // read any data (but no more than length) - if (read.allowLess) { + // read any data (but no more than length) + if (read.allowLess) { - // ok there is any data so that we can satisfy this request - this._reads.shift(); // == read + // ok there is any data so that we can satisfy this request + this._reads.shift(); // == read - // first we need to peek into first buffer - var smallerBuf = this._buffers[0]; + // first we need to peek into first buffer + var smallerBuf = this._buffers[0]; - // ok there is more data than we need - if (smallerBuf.length > read.length) { + // ok there is more data than we need + if (smallerBuf.length > read.length) { - this._buffered -= read.length; - this._buffers[0] = smallerBuf.slice(read.length); + this._buffered -= read.length; + this._buffers[0] = smallerBuf.slice(read.length); - read.func.call(this, smallerBuf.slice(0, read.length)); + read.func.call(this, smallerBuf.slice(0, read.length)); - } else { - // ok this is less than maximum length so use it all - this._buffered -= smallerBuf.length; - this._buffers.shift(); // == smallerBuf + } else { + // ok this is less than maximum length so use it all + this._buffered -= smallerBuf.length; + this._buffers.shift(); // == smallerBuf - read.func.call(this, smallerBuf); - } + read.func.call(this, smallerBuf); + } - } else if (this._buffered >= read.length) { - // ok we can meet some expectations + } else if (this._buffered >= read.length) { + // ok we can meet some expectations - this._reads.shift(); // == read + this._reads.shift(); // == read - var pos = 0, - count = 0, - data = new Buffer(read.length); + var pos = 0; + var count = 0; + var data = new Buffer(read.length); - // create buffer for all data - while (pos < read.length) { + // create buffer for all data + while (pos < read.length) { - var buf = this._buffers[count++], - len = Math.min(buf.length, read.length - pos); + var buf = this._buffers[count++]; + var len = Math.min(buf.length, read.length - pos); - buf.copy(data, pos, 0, len); - pos += len; + buf.copy(data, pos, 0, len); + pos += len; - // last buffer wasn't used all so just slice it and leave - if (len != buf.length) - this._buffers[--count] = buf.slice(len); - } + // last buffer wasn't used all so just slice it and leave + if (len != buf.length) + this._buffers[--count] = buf.slice(len); + } - // remove all used buffers - if (count > 0) - this._buffers.splice(0, count); + // remove all used buffers + if (count > 0) + this._buffers.splice(0, count); - this._buffered -= read.length; + this._buffered -= read.length; - read.func.call(this, data); + read.func.call(this, data); - } else { - // not enought data to satisfy first request in queue - // so we need to wait for more - break; - } + } else { + // not enought data to satisfy first request in queue + // so we need to wait for more + break; } + } - if (this._buffers && this._buffers.length > 0 && this._buffers[0] == null) { - this._end(); - } + if (this._buffers && this._buffers.length > 0 && this._buffers[0] == null) { + this._end(); + } }; diff --git a/lib/constants.js b/lib/constants.js index 1e74b79..d97fc03 100755 --- a/lib/constants.js +++ b/lib/constants.js @@ -23,16 +23,18 @@ module.exports = { - PNG_SIGNATURE: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], + PNG_SIGNATURE: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], - TYPE_IHDR: 0x49484452, - TYPE_IEND: 0x49454e44, - TYPE_IDAT: 0x49444154, - TYPE_PLTE: 0x504c5445, - TYPE_tRNS: 0x74524e53, - TYPE_gAMA: 0x67414d41, + TYPE_IHDR: 0x49484452, + TYPE_IEND: 0x49454e44, + TYPE_IDAT: 0x49444154, + TYPE_PLTE: 0x504c5445, + /*eslint camelcase: 0*/ + TYPE_tRNS: 0x74524e53, + TYPE_gAMA: 0x67414d41, + /*eslint camelcase: 1*/ - COLOR_PALETTE: 1, - COLOR_COLOR: 2, - COLOR_ALPHA: 4 + COLOR_PALETTE: 1, + COLOR_COLOR: 2, + COLOR_ALPHA: 4 }; diff --git a/lib/crc.js b/lib/crc.js index 712a2ac..9859237 100755 --- a/lib/crc.js +++ b/lib/crc.js @@ -23,41 +23,41 @@ var crcTable = []; (function() { - for (var i = 0; i < 256; i++) { - var c = i; - for (var j = 0; j < 8; j++) { - if (c & 1) { - c = 0xedb88320 ^ (c >>> 1); - } else { - c = c >>> 1; - } - } - crcTable[i] = c; + for (var i = 0; i < 256; i++) { + var currentCrc = i; + for (var j = 0; j < 8; j++) { + if (currentCrc & 1) { + currentCrc = 0xedb88320 ^ (currentCrc >>> 1); + } else { + currentCrc = currentCrc >>> 1; + } } + crcTable[i] = currentCrc; + } }()); var CrcCalculator = module.exports = function() { - this._crc = -1; + this._crc = -1; }; CrcCalculator.prototype.write = function(data) { - for (var i = 0; i < data.length; i++) { - this._crc = crcTable[(this._crc ^ data[i]) & 0xff] ^ (this._crc >>> 8); - } - return true; + for (var i = 0; i < data.length; i++) { + this._crc = crcTable[(this._crc ^ data[i]) & 0xff] ^ (this._crc >>> 8); + } + return true; }; CrcCalculator.prototype.crc32 = function() { - return this._crc ^ -1; + return this._crc ^ -1; }; CrcCalculator.crc32 = function(buf) { - var crc = -1; - for (var i = 0; i < buf.length; i++) { - crc = crcTable[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8); - } - return crc ^ -1; + var crc = -1; + for (var i = 0; i < buf.length; i++) { + crc = crcTable[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8); + } + return crc ^ -1; }; diff --git a/lib/filter-async.js b/lib/filter-async.js index 1b713e1..4d05eff 100644 --- a/lib/filter-async.js +++ b/lib/filter-async.js @@ -20,26 +20,26 @@ 'use strict'; -var util = require('util'), - ChunkStream = require('./chunkstream'), - Filter = require('./filter'); +var util = require('util'); +var ChunkStream = require('./chunkstream'); +var Filter = require('./filter'); var FilterAsync = module.exports = function(width, height, Bpp, depth, interlace, options) { - ChunkStream.call(this); + ChunkStream.call(this); - var buffers = []; - var that = this; - this._filter = new Filter(width, height, Bpp, depth, interlace, options, { - read: this.read.bind(this), - complete: function() { - that.emit('complete', Buffer.concat(buffers), width, height) - }, - write: function(buffer) { - buffers.push(buffer); - } - }); + var buffers = []; + var that = this; + this._filter = new Filter(width, height, Bpp, depth, interlace, options, { + read: this.read.bind(this), + complete: function() { + that.emit('complete', Buffer.concat(buffers), width, height) + }, + write: function(buffer) { + buffers.push(buffer); + } + }); - this._filter.start(); + this._filter.start(); }; util.inherits(FilterAsync, ChunkStream); diff --git a/lib/filter-sync.js b/lib/filter-sync.js index c261a06..5522ef5 100644 --- a/lib/filter-sync.js +++ b/lib/filter-sync.js @@ -20,24 +20,25 @@ 'use strict'; -var SyncReader = require('./sync-reader'), - Filter = require('./filter'); +var SyncReader = require('./sync-reader'); +var Filter = require('./filter'); exports.process = function(inBuffer, width, height, Bpp, depth, interlace, options) { - var outBuffers = []; - var reader = new SyncReader(inBuffer); - var filter = new Filter(width, height, Bpp, depth, interlace, options, { - read: reader.read.bind(reader), - write: function(bufferPart) { - outBuffers.push(bufferPart); - }, - complete: function(){} - }); + var outBuffers = []; + var reader = new SyncReader(inBuffer); + var filter = new Filter(width, height, Bpp, depth, interlace, options, { + read: reader.read.bind(reader), + write: function(bufferPart) { + outBuffers.push(bufferPart); + }, + complete: function() { + } + }); - filter.start(); - reader.process(); + filter.start(); + reader.process(); - return Buffer.concat(outBuffers); + return Buffer.concat(outBuffers); }; \ No newline at end of file diff --git a/lib/filter.js b/lib/filter.js index 0d45398..cd8a12f 100755 --- a/lib/filter.js +++ b/lib/filter.js @@ -23,265 +23,265 @@ var interlaceUtils = require('./interlace'); function getByteWidth(width, bpp, depth) { - var byteWidth = width * bpp; - if (depth !== 8) { - byteWidth = Math.ceil(byteWidth / (8 / depth)); - } - return byteWidth; + var byteWidth = width * bpp; + if (depth !== 8) { + byteWidth = Math.ceil(byteWidth / (8 / depth)); + } + return byteWidth; } function PaethPredictor(left, above, upLeft) { - var p = left + above - upLeft, - pLeft = Math.abs(p - left), - pAbove = Math.abs(p - above), - pUpLeft = Math.abs(p - upLeft); + var p = left + above - upLeft, + pLeft = Math.abs(p - left), + pAbove = Math.abs(p - above), + pUpLeft = Math.abs(p - upLeft); - if (pLeft <= pAbove && pLeft <= pUpLeft) { - return left; - } - if (pAbove <= pUpLeft) { - return above; - } - return upLeft; + if (pLeft <= pAbove && pLeft <= pUpLeft) { + return left; + } + if (pAbove <= pUpLeft) { + return above; + } + return upLeft; } var Filter = module.exports = function(width, height, Bpp, depth, interlace, options, dependencies) { - this._width = width; - this._height = height; - this._Bpp = Bpp; - this._depth = depth; - this._options = options; + this._width = width; + this._height = height; + this._Bpp = Bpp; + this._depth = depth; + this._options = options; - if (!('filterType' in options) || options.filterType == -1) { - options.filterType = [0, 1, 2, 3, 4]; - } else if (typeof options.filterType == 'number') { - options.filterType = [options.filterType]; - } - - this._filters = { - 0: this._filterNone.bind(this), - 1: this._filterSub.bind(this), - 2: this._filterUp.bind(this), - 3: this._filterAvg.bind(this), - 4: this._filterPaeth.bind(this) - }; - - this.read = dependencies.read; - this.write = dependencies.write; - this.complete = dependencies.complete; - - this._imageIndex = 0; - this._images = []; - if (interlace) { - var passes = interlaceUtils.getImagePasses(width, height); - for(var i = 0; i < passes.length; i++) { - this._images.push({ - byteWidth: getByteWidth(passes[i].width, Bpp, depth), - height: passes[i].height, - lineIndex: 0 - }); - } - } else { - this._images.push({ - byteWidth: getByteWidth(width, Bpp, depth), - height: height, - lineIndex: 0 - }); + if (!('filterType' in options) || options.filterType == -1) { + options.filterType = [0, 1, 2, 3, 4]; + } else if (typeof options.filterType == 'number') { + options.filterType = [options.filterType]; + } + + this._filters = { + 0: this._filterNone.bind(this), + 1: this._filterSub.bind(this), + 2: this._filterUp.bind(this), + 3: this._filterAvg.bind(this), + 4: this._filterPaeth.bind(this) + }; + + this.read = dependencies.read; + this.write = dependencies.write; + this.complete = dependencies.complete; + + this._imageIndex = 0; + this._images = []; + if (interlace) { + var passes = interlaceUtils.getImagePasses(width, height); + for (var i = 0; i < passes.length; i++) { + this._images.push({ + byteWidth: getByteWidth(passes[i].width, Bpp, depth), + height: passes[i].height, + lineIndex: 0 + }); } + } else { + this._images.push({ + byteWidth: getByteWidth(width, Bpp, depth), + height: height, + lineIndex: 0 + }); + } }; Filter.prototype.start = function() { - this.read(this._images[this._imageIndex].byteWidth + 1, this._reverseFilterLine.bind(this)); + this.read(this._images[this._imageIndex].byteWidth + 1, this._reverseFilterLine.bind(this)); }; Filter.prototype._reverseFilterLine = function(rawData) { - var currentImage = this._images[this._imageIndex]; - var line = new Buffer(currentImage.byteWidth); + var currentImage = this._images[this._imageIndex]; + var line = new Buffer(currentImage.byteWidth); - var filter = rawData[0]; + var filter = rawData[0]; - var xComparison = this._depth >= 8 ? ((this._depth === 16) ? this._Bpp * 2 : this._Bpp) : 1; - var xBiggerThan = xComparison - 1; + var xComparison = this._depth >= 8 ? ((this._depth === 16) ? this._Bpp * 2 : this._Bpp) : 1; + var xBiggerThan = xComparison - 1; - for (var x = 0; x < currentImage.byteWidth; x++) { - var rawByte = rawData[1 + x]; - switch(filter) { - case 0: - line[x] = rawByte; - break; - case 1: - var f1_left = x > xBiggerThan ? line[x - xComparison] : 0; - line[x] = rawByte + f1_left; - break; - case 2: - var f2_up = this._lastLine ? this._lastLine[x] : 0; - line[x] = rawByte + f2_up; - break; - case 3: - var f3_up = this._lastLine ? this._lastLine[x] : 0; - var f3_left = x > xBiggerThan ? line[x - xComparison] : 0; - var f3_add = Math.floor((f3_left + f3_up) / 2); - line[x] = rawByte + f3_add; - break; - case 4: - var f4_up = this._lastLine ? this._lastLine[x] : 0; - var f4_left = x > xBiggerThan ? line[x - xComparison] : 0; - var f4_upLeft = x > xBiggerThan && this._lastLine - ? this._lastLine[x - xComparison] : 0; - var f4_add = PaethPredictor(f4_left, f4_up, f4_upLeft); - line[x] = rawByte + f4_add; - break; - } - - //if (x === 5) { - // console.log("R", line[3], "G", line[4], "B", line[5]); - //} + for (var x = 0; x < currentImage.byteWidth; x++) { + var rawByte = rawData[1 + x]; + switch (filter) { + case 0: + line[x] = rawByte; + break; + case 1: + var f1_left = x > xBiggerThan ? line[x - xComparison] : 0; + line[x] = rawByte + f1_left; + break; + case 2: + var f2_up = this._lastLine ? this._lastLine[x] : 0; + line[x] = rawByte + f2_up; + break; + case 3: + var f3_up = this._lastLine ? this._lastLine[x] : 0; + var f3_left = x > xBiggerThan ? line[x - xComparison] : 0; + var f3_add = Math.floor((f3_left + f3_up) / 2); + line[x] = rawByte + f3_add; + break; + case 4: + var f4_up = this._lastLine ? this._lastLine[x] : 0; + var f4_left = x > xBiggerThan ? line[x - xComparison] : 0; + var f4_upLeft = x > xBiggerThan && this._lastLine + ? this._lastLine[x - xComparison] : 0; + var f4_add = PaethPredictor(f4_left, f4_up, f4_upLeft); + line[x] = rawByte + f4_add; + break; } - this.write(line); + //if (x === 5) { + // console.log("R", line[3], "G", line[4], "B", line[5]); + //} + } - currentImage.lineIndex++; - if (currentImage.lineIndex >= currentImage.height) { - this._lastLine = null; - this._imageIndex++; - currentImage = this._images[this._imageIndex]; - } else { - this._lastLine = line; - } + this.write(line); - if (currentImage) { - this.read(currentImage.byteWidth + 1, this._reverseFilterLine.bind(this)); - } else { - this.complete(this._width, this._height); - } + currentImage.lineIndex++; + if (currentImage.lineIndex >= currentImage.height) { + this._lastLine = null; + this._imageIndex++; + currentImage = this._images[this._imageIndex]; + } else { + this._lastLine = line; + } + + if (currentImage) { + this.read(currentImage.byteWidth + 1, this._reverseFilterLine.bind(this)); + } else { + this.complete(this._width, this._height); + } }; Filter.prototype.filter = function(pxData) { - var rawData = new Buffer(((this._width << 2) + 1) * this._height); + var rawData = new Buffer(((this._width << 2) + 1) * this._height); - for (var y = 0; y < this._height; y++) { + for (var y = 0; y < this._height; y++) { - // find best filter for this line (with lowest sum of values) - var filterTypes = this._options.filterType, - min = Infinity, - sel = 0; + // find best filter for this line (with lowest sum of values) + var filterTypes = this._options.filterType, + min = Infinity, + sel = 0; - for (var i = 0; i < filterTypes.length; i++) { - var sum = this._filters[filterTypes[i]](pxData, y, null); - if (sum < min) { - sel = filterTypes[i]; - min = sum; - } - } - - this._filters[sel](pxData, y, rawData); + for (var i = 0; i < filterTypes.length; i++) { + var sum = this._filters[filterTypes[i]](pxData, y, null); + if (sum < min) { + sel = filterTypes[i]; + min = sum; + } } - return rawData; + + this._filters[sel](pxData, y, rawData); + } + return rawData; }; Filter.prototype._filterNone = function(pxData, y, rawData) { - var pxRowLength = this._width << 2, - rawRowLength = pxRowLength + 1, - sum = 0; + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; - if (!rawData) { - for (var x = 0; x < pxRowLength; x++) - sum += Math.abs(pxData[y * pxRowLength + x]); + if (!rawData) { + for (var x = 0; x < pxRowLength; x++) + sum += Math.abs(pxData[y * pxRowLength + x]); - } else { - rawData[y * rawRowLength] = 0; - pxData.copy(rawData, rawRowLength * y + 1, pxRowLength * y, pxRowLength * (y + 1)); - } + } else { + rawData[y * rawRowLength] = 0; + pxData.copy(rawData, rawRowLength * y + 1, pxRowLength * y, pxRowLength * (y + 1)); + } - return sum; + return sum; }; Filter.prototype._filterSub = function(pxData, y, rawData) { - var pxRowLength = this._width << 2, - rawRowLength = pxRowLength + 1, - sum = 0; + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; - if (rawData) - rawData[y * rawRowLength] = 1; + if (rawData) + rawData[y * rawRowLength] = 1; - for (var x = 0; x < pxRowLength; x++) { + for (var x = 0; x < pxRowLength; x++) { - var left = x >= 4 ? pxData[y * pxRowLength + x - 4] : 0, - val = pxData[y * pxRowLength + x] - left; + var left = x >= 4 ? pxData[y * pxRowLength + x - 4] : 0, + val = pxData[y * pxRowLength + x] - left; - if (!rawData) sum += Math.abs(val); - else rawData[y * rawRowLength + 1 + x] = val; - } - return sum; + if (!rawData) sum += Math.abs(val); + else rawData[y * rawRowLength + 1 + x] = val; + } + return sum; }; Filter.prototype._filterUp = function(pxData, y, rawData) { - var pxRowLength = this._width << 2, - rawRowLength = pxRowLength + 1, - sum = 0; + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; - if (rawData) - rawData[y * rawRowLength] = 2; + if (rawData) + rawData[y * rawRowLength] = 2; - for (var x = 0; x < pxRowLength; x++) { + for (var x = 0; x < pxRowLength; x++) { - var up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0, - val = pxData[y * pxRowLength + x] - up; + var up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0, + val = pxData[y * pxRowLength + x] - up; - if (!rawData) sum += Math.abs(val); - else rawData[y * rawRowLength + 1 + x] = val; - } - return sum; + if (!rawData) sum += Math.abs(val); + else rawData[y * rawRowLength + 1 + x] = val; + } + return sum; }; Filter.prototype._filterAvg = function(pxData, y, rawData) { - var pxRowLength = this._width << 2, - rawRowLength = pxRowLength + 1, - sum = 0; + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; - if (rawData) - rawData[y * rawRowLength] = 3; + if (rawData) + rawData[y * rawRowLength] = 3; - for (var x = 0; x < pxRowLength; x++) { + for (var x = 0; x < pxRowLength; x++) { - var left = x >= 4 ? pxData[y * pxRowLength + x - 4] : 0, - up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0, - val = pxData[y * pxRowLength + x] - ((left + up) >> 1); + var left = x >= 4 ? pxData[y * pxRowLength + x - 4] : 0, + up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0, + val = pxData[y * pxRowLength + x] - ((left + up) >> 1); - if (!rawData) sum += Math.abs(val); - else rawData[y * rawRowLength + 1 + x] = val; - } - return sum; + if (!rawData) sum += Math.abs(val); + else rawData[y * rawRowLength + 1 + x] = val; + } + return sum; }; Filter.prototype._filterPaeth = function(pxData, y, rawData) { - var pxRowLength = this._width << 2, - rawRowLength = pxRowLength + 1, - sum = 0; + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; - if (rawData) - rawData[y * rawRowLength] = 4; + if (rawData) + rawData[y * rawRowLength] = 4; - for (var x = 0; x < pxRowLength; x++) { + for (var x = 0; x < pxRowLength; x++) { - var left = x >= 4 ? pxData[y * pxRowLength + x - 4] : 0, - up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0, - upLeft = x >= 4 && y > 0 ? pxData[(y - 1) * pxRowLength + x - 4] : 0, - val = pxData[y * pxRowLength + x] - PaethPredictor(left, up, upLeft); + var left = x >= 4 ? pxData[y * pxRowLength + x - 4] : 0, + up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0, + upLeft = x >= 4 && y > 0 ? pxData[(y - 1) * pxRowLength + x - 4] : 0, + val = pxData[y * pxRowLength + x] - PaethPredictor(left, up, upLeft); - if (!rawData) sum += Math.abs(val); - else rawData[y * rawRowLength + 1 + x] = val; - } - return sum; + if (!rawData) sum += Math.abs(val); + else rawData[y * rawRowLength + 1 + x] = val; + } + return sum; }; diff --git a/lib/interlace.js b/lib/interlace.js index 65c2957..aa76668 100644 --- a/lib/interlace.js +++ b/lib/interlace.js @@ -49,11 +49,11 @@ exports.getImagePasses = function(width, height) { var yLeftOver = height % 8; var xRepeats = (width - xLeftOver) / 8; var yRepeats = (width - yLeftOver) / 8; - for(var i = 0; i < imagePasses.length; i++) { + for (var i = 0; i < imagePasses.length; i++) { var pass = imagePasses[i]; var passWidth = xRepeats * pass.x.length; var passHeight = yRepeats * pass.y.length; - for(var j = 0; j < pass.x.length; j++) { + for (var j = 0; j < pass.x.length; j++) { if (pass.x[j] < xLeftOver) { passWidth++; } @@ -61,7 +61,7 @@ exports.getImagePasses = function(width, height) { break; } } - for(j = 0; j < pass.y.length; j++) { + for (j = 0; j < pass.y.length; j++) { if (pass.y[j] < yLeftOver) { passHeight++; } @@ -70,7 +70,7 @@ exports.getImagePasses = function(width, height) { } } if (passWidth > 0 && passHeight > 0) { - images.push({ width: passWidth, height: passHeight, index: i}); + images.push({width: passWidth, height: passHeight, index: i}); } } return images; @@ -79,7 +79,7 @@ exports.getImagePasses = function(width, height) { exports.getInterlaceIterator = function(width) { return function(x, y, pass) { var outerXLeftOver = x % imagePasses[pass].x.length; - var outerX = (((x - outerXLeftOver)/ imagePasses[pass].x.length) * 8) + imagePasses[pass].x[outerXLeftOver]; + var outerX = (((x - outerXLeftOver) / imagePasses[pass].x.length) * 8) + imagePasses[pass].x[outerXLeftOver]; var outerYLeftOver = y % imagePasses[pass].y.length; var outerY = (((y - outerYLeftOver) / imagePasses[pass].y.length) * 8) + imagePasses[pass].y[outerYLeftOver]; return (outerX * 4) + (outerY * width * 4); diff --git a/lib/packer.js b/lib/packer.js index 4803db1..85ec1ed 100755 --- a/lib/packer.js +++ b/lib/packer.js @@ -21,91 +21,91 @@ 'use strict'; -var util = require('util'), - Stream = require('stream'), - zlib = require('zlib'), - Filter = require('./filter'), - CrcStream = require('./crc'), - constants = require('./constants'); +var util = require('util'); +var Stream = require('stream'); +var zlib = require('zlib'); +var Filter = require('./filter'); +var CrcStream = require('./crc'); +var constants = require('./constants'); var Packer = module.exports = function(options) { - Stream.call(this); + Stream.call(this); - this._options = options; + this._options = options; - options.deflateChunkSize = options.deflateChunkSize || 32 * 1024; - options.deflateLevel = options.deflateLevel != null ? options.deflateLevel : 9; - options.deflateStrategy = options.deflateStrategy != null ? options.deflateStrategy : 3; + options.deflateChunkSize = options.deflateChunkSize || 32 * 1024; + options.deflateLevel = options.deflateLevel != null ? options.deflateLevel : 9; + options.deflateStrategy = options.deflateStrategy != null ? options.deflateStrategy : 3; - this.readable = true; + this.readable = true; }; util.inherits(Packer, Stream); Packer.prototype.pack = function(data, width, height) { - // Signature - this.emit('data', new Buffer(constants.PNG_SIGNATURE)); - this.emit('data', this._packIHDR(width, height)); + // Signature + this.emit('data', new Buffer(constants.PNG_SIGNATURE)); + this.emit('data', this._packIHDR(width, height)); - // filter pixel data - //TODO {} - var filter = new Filter(width, height, 4, 8, false, this._options, {}); - var filteredData = filter.filter(data); + // filter pixel data + //TODO {} + var filter = new Filter(width, height, 4, 8, false, this._options, {}); + var filteredData = filter.filter(data); - // compress it - var deflate = zlib.createDeflate({ - chunkSize: this._options.deflateChunkSize, - level: this._options.deflateLevel, - strategy: this._options.deflateStrategy - }); - deflate.on('error', this.emit.bind(this, 'error')); + // compress it + var deflate = zlib.createDeflate({ + chunkSize: this._options.deflateChunkSize, + level: this._options.deflateLevel, + strategy: this._options.deflateStrategy + }); + deflate.on('error', this.emit.bind(this, 'error')); - deflate.on('data', function(compressedData) { - this.emit('data', this._packIDAT(compressedData)); - }.bind(this)); + deflate.on('data', function(compressedData) { + this.emit('data', this._packIDAT(compressedData)); + }.bind(this)); - deflate.on('end', function() { - this.emit('data', this._packIEND()); - this.emit('end'); - }.bind(this)); + deflate.on('end', function() { + this.emit('data', this._packIEND()); + this.emit('end'); + }.bind(this)); - deflate.end(filteredData); + deflate.end(filteredData); }; Packer.prototype._packChunk = function(type, data) { - var len = (data ? data.length : 0), - buf = new Buffer(len + 12); + var len = (data ? data.length : 0), + buf = new Buffer(len + 12); - buf.writeUInt32BE(len, 0); - buf.writeUInt32BE(type, 4); + buf.writeUInt32BE(len, 0); + buf.writeUInt32BE(type, 4); - if (data) data.copy(buf, 8); + if (data) data.copy(buf, 8); - buf.writeInt32BE(CrcStream.crc32(buf.slice(4, buf.length - 4)), buf.length - 4); - return buf; + buf.writeInt32BE(CrcStream.crc32(buf.slice(4, buf.length - 4)), buf.length - 4); + return buf; }; Packer.prototype._packIHDR = function(width, height) { - var buf = new Buffer(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 + var buf = new Buffer(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); + return this._packChunk(constants.TYPE_IHDR, buf); }; Packer.prototype._packIDAT = function(data) { - return this._packChunk(constants.TYPE_IDAT, data); + return this._packChunk(constants.TYPE_IDAT, data); }; Packer.prototype._packIEND = function() { - return this._packChunk(constants.TYPE_IEND, null); + return this._packChunk(constants.TYPE_IEND, null); }; diff --git a/lib/parser-async.js b/lib/parser-async.js index 8ca1bc8..f3d1d7a 100644 --- a/lib/parser-async.js +++ b/lib/parser-async.js @@ -21,108 +21,108 @@ 'use strict'; -var util = require('util'), - zlib = require('zlib'), - ChunkStream = require('./chunkstream'), - FilterAsync = require('./filter-async'), - Parser = require('./parser'), - bitmapper = require('./bitmapper'); +var util = require('util'); +var zlib = require('zlib'); +var ChunkStream = require('./chunkstream'); +var FilterAsync = require('./filter-async'); +var Parser = require('./parser'); +var bitmapper = require('./bitmapper'); var ParserAsync = module.exports = function(options) { - ChunkStream.call(this); + ChunkStream.call(this); - this._parser = new Parser(options, { - read: this.read.bind(this), - error: this._handleError.bind(this), - metadata: this.emit.bind(this, "metadata"), - gamma: this.emit.bind(this, "gamma"), - finished: this._finished.bind(this), - inflateData: this._inflateData.bind(this), - createData: this._createData.bind(this) - }); - this._options = options; - this.writable = true; + this._parser = new Parser(options, { + read: this.read.bind(this), + error: this._handleError.bind(this), + metadata: this.emit.bind(this, "metadata"), + gamma: this.emit.bind(this, "gamma"), + finished: this._finished.bind(this), + inflateData: this._inflateData.bind(this), + createData: this._createData.bind(this) + }); + this._options = options; + this.writable = true; - this._parser.start(); + this._parser.start(); }; util.inherits(ParserAsync, ChunkStream); ParserAsync.prototype._handleError = function(err) { - this.emit('error', err); + this.emit('error', err); - this.writable = false; + this.writable = false; - this.destroy(); + this.destroy(); - if (this._inflate && this._inflate.destroy) { - this._inflate.destroy(); - } + if (this._inflate && this._inflate.destroy) { + this._inflate.destroy(); + } - this.errord = true; + this.errord = true; }; ParserAsync.prototype._inflateData = function(data) { - if (!this._inflate) { - this._inflate = zlib.createInflate(); + if (!this._inflate) { + this._inflate = zlib.createInflate(); - this._inflate.on('error', this.emit.bind(this, 'error')); - this._filter.on('complete', this._complete.bind(this)); + this._inflate.on('error', this.emit.bind(this, 'error')); + this._filter.on('complete', this._complete.bind(this)); - this._inflate.pipe(this._filter); - } - this._inflate.write(data); + this._inflate.pipe(this._filter); + } + this._inflate.write(data); }; ParserAsync.prototype._createData = function(width, height, bpp, depth, interlace) { - this._bpp = bpp; - this._depth = depth; - this._interlace = interlace; + this._bpp = bpp; + this._depth = depth; + this._interlace = interlace; - this._filter = new FilterAsync( - width, height, - bpp, - depth, - interlace, - this._options - ); + this._filter = new FilterAsync( + width, height, + bpp, + depth, + interlace, + this._options + ); }; ParserAsync.prototype._finished = function() { - if (this.errord) { - return; - } + if (this.errord) { + return; + } - if (!this._inflate) { - this.emit('error', 'No Inflate block'); - } else { - // no more data to inflate - this._inflate.end(); - } - this.destroySoon(); + if (!this._inflate) { + this.emit('error', 'No Inflate block'); + } else { + // no more data to inflate + this._inflate.end(); + } + this.destroySoon(); }; ParserAsync.prototype._complete = function(data, width, height) { - if (this.errord) { - return; - } + if (this.errord) { + return; + } - try { - data = bitmapper.dataToBitMap(data, width, height, - this._bpp, - this._depth, - this._interlace); + try { + data = bitmapper.dataToBitMap(data, width, height, + this._bpp, + this._depth, + this._interlace); - data = this._parser.reverseFiltered(data, this._depth, width, height); - } - catch(e) { - this._handleError(); - return; - } + data = this._parser.reverseFiltered(data, this._depth, width, height); + } + catch (e) { + this._handleError(); + return; + } - this.emit('parsed', data); + this.emit('parsed', data); }; diff --git a/lib/parser-sync.js b/lib/parser-sync.js index abd1426..cd43ec6 100644 --- a/lib/parser-sync.js +++ b/lib/parser-sync.js @@ -21,76 +21,77 @@ 'use strict'; -var zlib = require('zlib'), - SyncReader = require('./sync-reader'), - FilterSync = require('./filter-sync'), - Parser = require('./parser'), - bitmapper = require('./bitmapper'); +var zlib = require('zlib'); +var SyncReader = require('./sync-reader'); +var FilterSync = require('./filter-sync'); +var Parser = require('./parser'); +var bitmapper = require('./bitmapper'); var ParserSync = module.exports = function(buffer, options) { - var reader = new SyncReader(buffer); + var reader = new SyncReader(buffer); - this._inflateDataList = []; - this._parser = new Parser(options, { - read: reader.read.bind(reader), - error: this._handleError.bind(this), - metadata: this._metaData.bind(this), - gamma: this._gamma.bind(this), - finished: function() {}, - inflateData: this._inflateData.bind(this), - createData: this._createData.bind(this) - }); - this._options = options; + this._inflateDataList = []; + this._parser = new Parser(options, { + read: reader.read.bind(reader), + error: this._handleError.bind(this), + metadata: this._metaData.bind(this), + gamma: this._gamma.bind(this), + finished: function() { + }, + inflateData: this._inflateData.bind(this), + createData: this._createData.bind(this) + }); + this._options = options; - this._parser.start(); - reader.process(); + this._parser.start(); + reader.process(); - //join together the inflate datas - var inflateData = Buffer.concat(this._inflateDataList); + //join together the inflate datas + var inflateData = Buffer.concat(this._inflateDataList); - var data = zlib.inflateSync(inflateData); + var data = zlib.inflateSync(inflateData); - data = FilterSync.process( - data, - this._width, this._height, - this._bpp, - this._depth, - this._interlace, - this._options - ); + data = FilterSync.process( + data, + this._width, this._height, + this._bpp, + this._depth, + this._interlace, + this._options + ); - this._data = bitmapper.dataToBitMap(data, this._width, this._height, - this._bpp, - this._depth, - this._interlace); - // todo yuck - this.data = this._parser.reverseFiltered(this._data, this._depth, this._width, this._height); + this._data = bitmapper.dataToBitMap(data, this._width, this._height, + this._bpp, + this._depth, + this._interlace); + // todo yuck + this.data = this._parser.reverseFiltered(this._data, this._depth, this._width, this._height); }; ParserSync.prototype._handleError = function(err) { - this.err = err; + this.err = err; }; ParserSync.prototype._metaData = function(metaData) { - this.metaData = metaData; + this.metaData = metaData; }; ParserSync.prototype._gamma = function(gamma) { - this.gamma = gamma; + this.gamma = gamma; }; ParserSync.prototype._inflateData = function(data) { - this._inflateDataList.push(data); + this._inflateDataList.push(data); }; ParserSync.prototype._createData = function(width, height, bpp, depth, interlace) { - this._data = new Buffer(width * height * 4); - this._bpp = bpp; - this._width = width; - this._height = height; - this._depth = depth; - this._interlace = interlace; - return this._data; + this._data = new Buffer(width * height * 4); + this._bpp = bpp; + this._width = width; + this._height = height; + this._depth = depth; + this._interlace = interlace; + return this._data; }; diff --git a/lib/parser.js b/lib/parser.js index b7b9e0f..726fce2 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -21,8 +21,8 @@ 'use strict'; -var constants = require('./constants'), - CrcCalculator = require('./crc'); +var constants = require('./constants'); +var CrcCalculator = require('./crc'); var Parser = module.exports = function(options, dependencies) { @@ -52,7 +52,7 @@ var Parser = module.exports = function(options, dependencies) { this.parsed = dependencies.parsed; this.createData = dependencies.createData; this.inflateData = dependencies.inflateData; - this.finished = dependencies.finished; + this.finished = dependencies.finished; }; var colorTypeToBppMap = { @@ -221,7 +221,7 @@ Parser.prototype._parsePLTE = function(data) { this._palette.push([ data[i * 3], data[i * 3 + 1], - data[i * 3 + 2 ], + data[i * 3 + 2], 0xff ]); } diff --git a/lib/png-sync.js b/lib/png-sync.js index 3e10647..3f34084 100644 --- a/lib/png-sync.js +++ b/lib/png-sync.js @@ -26,17 +26,16 @@ var Parser = require('./parser-sync'); exports.read = function(buffer, options) { - options = options || {}; - var parser = new Parser(buffer, options); + var parser = new Parser(buffer, options || {}); - if (parser.err) { - throw parser.err; - } + if (parser.err) { + throw parser.err; + } - return { - data: parser.data, - width: parser._width, - height: parser._height, - gamma: parser.gamma || 0 - }; + return { + data: parser.data, + width: parser._width, + height: parser._height, + gamma: parser.gamma || 0 + }; }; diff --git a/lib/png.js b/lib/png.js index bb57a5b..68c90c5 100755 --- a/lib/png.js +++ b/lib/png.js @@ -21,47 +21,47 @@ 'use strict'; -var util = require('util'), - Stream = require('stream'), - Parser = require('./parser-async'), - Packer = require('./packer'), - PNGSync = require('./png-sync'); +var util = require('util'); +var Stream = require('stream'); +var Parser = require('./parser-async'); +var Packer = require('./packer'); +var PNGSync = require('./png-sync'); var PNG = exports.PNG = function(options) { - Stream.call(this); + Stream.call(this); - options = options || {}; + options = options || {}; // eslint-disable-line no-param-reassign - this.width = options.width || 0; - this.height = options.height || 0; + this.width = options.width || 0; + this.height = options.height || 0; - this.data = this.width > 0 && this.height > 0 - ? new Buffer(4 * this.width * this.height) : null; + this.data = this.width > 0 && this.height > 0 + ? new Buffer(4 * this.width * this.height) : null; - if(options.fill && this.data){ - this.data.fill(0); - } + if (options.fill && this.data) { + this.data.fill(0); + } - this.gamma = 0; - this.readable = this.writable = true; + this.gamma = 0; + this.readable = this.writable = true; - this._parser = new Parser(options || {}); + this._parser = new Parser(options || {}); - this._parser.on('error', this.emit.bind(this, 'error')); - this._parser.on('close', this._handleClose.bind(this)); - this._parser.on('metadata', this._metadata.bind(this)); - this._parser.on('gamma', this._gamma.bind(this)); - this._parser.on('parsed', function(data) { - this.data = data; - this.emit('parsed', data); - }.bind(this)); + this._parser.on('error', this.emit.bind(this, 'error')); + this._parser.on('close', this._handleClose.bind(this)); + this._parser.on('metadata', this._metadata.bind(this)); + this._parser.on('gamma', this._gamma.bind(this)); + this._parser.on('parsed', function(data) { + this.data = data; + this.emit('parsed', data); + }.bind(this)); - this._packer = new Packer(options); - this._packer.on('data', this.emit.bind(this, 'data')); - this._packer.on('end', this.emit.bind(this, 'end')); - this._parser.on('close', this._handleClose.bind(this)); - this._packer.on('error', this.emit.bind(this, 'error')); + this._packer = new Packer(options); + this._packer.on('data', this.emit.bind(this, 'data')); + this._packer.on('end', this.emit.bind(this, 'end')); + this._parser.on('close', this._handleClose.bind(this)); + this._packer.on('error', this.emit.bind(this, 'error')); }; util.inherits(PNG, Stream); @@ -70,103 +70,110 @@ PNG.sync = PNGSync; PNG.prototype.pack = function() { - process.nextTick(function() { - this._packer.pack(this.data, this.width, this.height); - }.bind(this)); + process.nextTick(function() { + this._packer.pack(this.data, this.width, this.height); + }.bind(this)); - return this; + return this; }; PNG.prototype.parse = function(data, callback) { - if (callback) { - var onParsed = null, onError = null; + if (callback) { + var onParsed, onError; - this.once('parsed', onParsed = function(parsedData) { - this.removeListener('error', onError); + onParsed = function(parsedData) { + this.removeListener('error', onError); - this.data = parsedData; - callback(null, this); + this.data = parsedData; + callback(null, this); + }.bind(this); - }.bind(this)); + onError = function(err) { + this.removeListener('parsed', onParsed); - this.once('error', onError = function(err) { - this.removeListener('parsed', onParsed); + callback(err, null); + }.bind(this); - callback(err, null); - }.bind(this)); - } + this.once('parsed', onParsed); + this.once('error', onError); + } - this.end(data); - return this; + this.end(data); + return this; }; PNG.prototype.write = function(data) { - this._parser.write(data); - return true; + this._parser.write(data); + return true; }; PNG.prototype.end = function(data) { - this._parser.end(data); + this._parser.end(data); }; PNG.prototype._metadata = function(metadata) { - this.width = metadata.width; - this.height = metadata.height; + this.width = metadata.width; + this.height = metadata.height; - this.emit('metadata', metadata); + this.emit('metadata', metadata); }; PNG.prototype._gamma = function(gamma) { - this.gamma = gamma; + this.gamma = gamma; }; PNG.prototype._handleClose = function() { - if (!this._parser.writable && !this._packer.readable) - this.emit('close'); -}; - -PNG.bitblt = function(src, dst, sx, sy, w, h, dx, dy) { - - if (sx > src.width || sy > src.height - || sx + w > src.width || sy + h > src.height) - throw new Error('bitblt reading outside image'); - if (dx > dst.width || dy > dst.height - || dx + w > dst.width || dy + h > dst.height) - throw new Error('bitblt writing outside image'); - - for (var y = 0; y < h; y++) { - src.data.copy(dst.data, - ((dy + y) * dst.width + dx) << 2, - ((sy + y) * src.width + sx) << 2, - ((sy + y) * src.width + sx + w) << 2 - ); - } + if (!this._parser.writable && !this._packer.readable) { + this.emit('close'); + } }; -PNG.prototype.bitblt = function(dst, sx, sy, w, h, dx, dy) { +PNG.bitblt = function(src, dst, srcX, srcY, width, height, deltaX, deltaY) { // eslint-disable-line max-params - PNG.bitblt(this, dst, sx, sy, w, h, dx, dy); - return this; + if (srcX > src.width || srcY > src.height || srcX + width > src.width || srcY + height > src.height) { + throw new Error('bitblt reading outside image'); + } + + if (deltaX > dst.width || deltaY > dst.height || deltaX + width > dst.width || deltaY + height > dst.height) { + throw new Error('bitblt writing outside image'); + } + + for (var y = 0; y < height; y++) { + src.data.copy(dst.data, + ((deltaY + y) * dst.width + deltaX) << 2, + ((srcY + y) * src.width + srcX) << 2, + ((srcY + y) * src.width + srcX + width) << 2 + ); + } +}; + + +PNG.prototype.bitblt = function(src, dst, srcX, srcY, width, height, deltaX, deltaY) { // eslint-disable-line max-params + + PNG.bitblt(this, dst, srcX, srcY, width, height, deltaX, deltaY); + return this; }; PNG.adjustGamma = function(src) { - if (src.gamma) { - for (var y = 0; y < src.height; y++) { - for (var x = 0; x < src.width; x++) { - var idx = (src.width * y + x) << 2; + if (src.gamma) { + for (var y = 0; y < src.height; y++) { + for (var x = 0; x < src.width; x++) { + var idx = (src.width * y + x) << 2; - for (var i = 0; i < 3; i++) { - var sample = src.data[idx + i] / 255; - sample = Math.pow(sample, 1 / 2.2 / src.gamma); - src.data[idx + i] = Math.round(sample * 255); - } - } + for (var i = 0; i < 3; i++) { + var sample = src.data[idx + i] / 255; + sample = Math.pow(sample, 1 / 2.2 / src.gamma); + src.data[idx + i] = Math.round(sample * 255); } - src.gamma = 0; + } } + src.gamma = 0; + } }; -PNG.prototype.adjustGamma = function() { PNG.adjustGamma(this); }; \ No newline at end of file +PNG.prototype.adjustGamma = function() { + PNG.adjustGamma(this); +}; \ No newline at end of file diff --git a/lib/sync-reader.js b/lib/sync-reader.js index bfc8e09..0718f36 100644 --- a/lib/sync-reader.js +++ b/lib/sync-reader.js @@ -20,13 +20,13 @@ 'use strict'; -var SyncReader = module.exports = function (buffer) { +var SyncReader = module.exports = function(buffer) { this._buffer = buffer; this._reads = []; }; -SyncReader.prototype.read = function (length, callback) { +SyncReader.prototype.read = function(length, callback) { this._reads.push({ length: Math.abs(length), // if length < 0 then at most this length @@ -35,7 +35,7 @@ SyncReader.prototype.read = function (length, callback) { }); }; -SyncReader.prototype.process = function () { +SyncReader.prototype.process = function() { // as long as there is any data and read requests while (this._reads.length > 0 && this._buffer.length) { @@ -54,13 +54,13 @@ SyncReader.prototype.process = function () { read.func.call(this, buf.slice(0, read.length)); } else { - break; + break; } } if (this._reads.length > 0) { - return new Error('There are some read requests waitng on finished stream'); + return new Error('There are some read requests waitng on finished stream'); } if (this._buffer.length > 0) {