mirror of
https://github.com/danbulant/pngjs
synced 2026-05-27 22:02:22 +00:00
commit
5ee7782212
7 changed files with 143 additions and 45 deletions
11
README.md
11
README.md
|
|
@ -245,6 +245,17 @@ var data = fs.readFileSync('in.png');
|
|||
var png = PNG.sync.read(data);
|
||||
```
|
||||
|
||||
### PNG.sync.write(png)
|
||||
|
||||
Take a PNG image and returns a buffer. The properties on the image include the meta data and `data` as per the async API above.
|
||||
|
||||
```
|
||||
var data = fs.readFileSync('in.png');
|
||||
var png = PNG.sync.read(data);
|
||||
var buffer = PNG.sync.write(png);
|
||||
fs.writeFileSync('out.png', buffer);
|
||||
```
|
||||
|
||||
### PNG.adjustGamma(src)
|
||||
|
||||
Adjusts the gamma of a sync image. See the async adjustGamma.
|
||||
|
|
|
|||
19
examples/sync.js
Normal file
19
examples/sync.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var fs = require('fs'),
|
||||
PNG = require('../lib/png').PNG;
|
||||
|
||||
|
||||
var srcFname = process.argv[2],
|
||||
dstFname = process.argv[3] || 'out.png';
|
||||
|
||||
// Read a PNG file
|
||||
var data = fs.readFileSync(srcFname);
|
||||
// Parse it
|
||||
var png = PNG.sync.read(data, {
|
||||
filterType: -1
|
||||
});
|
||||
// Pack it back into a PNG data
|
||||
var buff = PNG.sync.write(png);
|
||||
// Write a PNG file
|
||||
fs.writeFileSync(dstFname, buff);
|
||||
45
lib/packer-async.js
Normal file
45
lib/packer-async.js
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
var Stream = require('stream');
|
||||
var constants = require('./constants');
|
||||
var Packer = require('./packer');
|
||||
|
||||
var PackerAsync = module.exports = function(opt) {
|
||||
Stream.call(this);
|
||||
|
||||
var options = opt || {};
|
||||
|
||||
this._packer = new Packer(options);
|
||||
this._deflate = this._packer.createDeflate();
|
||||
|
||||
this.readable = true;
|
||||
};
|
||||
util.inherits(PackerAsync, Stream);
|
||||
|
||||
|
||||
PackerAsync.prototype.pack = function(data, width, height, gamma) {
|
||||
// Signature
|
||||
this.emit('data', new Buffer(constants.PNG_SIGNATURE));
|
||||
this.emit('data', this._packer.packIHDR(width, height));
|
||||
|
||||
if (gamma) {
|
||||
this.emit('data', this._packer.packGAMA(gamma));
|
||||
}
|
||||
|
||||
var filteredData = this._packer.filterData(data, width, height);
|
||||
|
||||
// compress it
|
||||
this._deflate.on('error', this.emit.bind(this, 'error'));
|
||||
|
||||
this._deflate.on('data', function(compressedData) {
|
||||
this.emit('data', this._packer.packIDAT(compressedData));
|
||||
}.bind(this));
|
||||
|
||||
this._deflate.on('end', function() {
|
||||
this.emit('data', this._packer.packIEND());
|
||||
this.emit('end');
|
||||
}.bind(this));
|
||||
|
||||
this._deflate.end(filteredData);
|
||||
};
|
||||
39
lib/packer-sync.js
Normal file
39
lib/packer-sync.js
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
'use strict';
|
||||
|
||||
var zlib = require('zlib');
|
||||
var constants = require('./constants');
|
||||
var Packer = require('./packer');
|
||||
|
||||
module.exports = function(metaData, opt) {
|
||||
var options = opt || {};
|
||||
|
||||
var packer = new Packer(options);
|
||||
|
||||
var chunks = [];
|
||||
|
||||
// Signature
|
||||
chunks.push(new Buffer(constants.PNG_SIGNATURE));
|
||||
|
||||
// Header
|
||||
chunks.push(packer.packIHDR(metaData.width, metaData.height));
|
||||
|
||||
if (metaData.gamma) {
|
||||
chunks.push(packer.packGAMA(metaData.gamma));
|
||||
}
|
||||
|
||||
var filteredData = packer.filterData(metaData.data, metaData.width, metaData.height);
|
||||
|
||||
// compress it
|
||||
var compressedData = zlib.deflateSync(filteredData, packer.getDeflateOptions());
|
||||
filteredData = null;
|
||||
|
||||
if (!compressedData || !compressedData.length) {
|
||||
throw new Error('bad png - invalid compressed data response');
|
||||
}
|
||||
chunks.push(packer.packIDAT(compressedData));
|
||||
|
||||
// End
|
||||
chunks.push(packer.packIEND());
|
||||
|
||||
return Buffer.concat(chunks);
|
||||
};
|
||||
|
|
@ -1,16 +1,12 @@
|
|||
'use strict';
|
||||
|
||||
var util = require('util');
|
||||
var Stream = require('stream');
|
||||
var zlib = require('zlib');
|
||||
var filter = require('./filter-pack');
|
||||
var CrcStream = require('./crc');
|
||||
var constants = require('./constants');
|
||||
var CrcStream = require('./crc');
|
||||
var bitPacker = require('./bitpacker');
|
||||
var filter = require('./filter-pack');
|
||||
var zlib = require('zlib');
|
||||
|
||||
var Packer = module.exports = function(options) {
|
||||
Stream.call(this);
|
||||
|
||||
this._options = options;
|
||||
|
||||
options.deflateChunkSize = options.deflateChunkSize || 32 * 1024;
|
||||
|
|
@ -27,46 +23,28 @@ var Packer = module.exports = function(options) {
|
|||
if (options.bitDepth !== 8) {
|
||||
throw new Error('option bit depth:' + options.bitDepth + ' is not supported at present');
|
||||
}
|
||||
|
||||
this.readable = true;
|
||||
};
|
||||
util.inherits(Packer, Stream);
|
||||
|
||||
Packer.prototype.getDeflateOptions = function() {
|
||||
return {
|
||||
chunkSize: this._options.deflateChunkSize,
|
||||
level: this._options.deflateLevel,
|
||||
strategy: this._options.deflateStrategy
|
||||
};
|
||||
};
|
||||
|
||||
Packer.prototype.pack = function(data, width, height, gamma) {
|
||||
// Signature
|
||||
this.emit('data', new Buffer(constants.PNG_SIGNATURE));
|
||||
this.emit('data', this._packIHDR(width, height, this._options.bitDepth, this._options.colorType));
|
||||
|
||||
if (gamma) {
|
||||
this.emit('data', this._packGAMA(gamma));
|
||||
}
|
||||
Packer.prototype.createDeflate = function() {
|
||||
return this._options.deflateFactory(this.getDeflateOptions());
|
||||
};
|
||||
|
||||
Packer.prototype.filterData = function(data, width, height) {
|
||||
// convert to correct format for filtering (e.g. right bpp and bit depth)
|
||||
var packedData = bitPacker(data, width, height, this._options);
|
||||
|
||||
// filter pixel data
|
||||
var bpp = constants.COLORTYPE_TO_BPP_MAP[this._options.colorType];
|
||||
var filteredData = filter(packedData, width, height, this._options, bpp);
|
||||
|
||||
// compress it
|
||||
var deflate = this._options.deflateFactory({
|
||||
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('end', function() {
|
||||
this.emit('data', this._packIEND());
|
||||
this.emit('end');
|
||||
}.bind(this));
|
||||
|
||||
deflate.end(filteredData);
|
||||
return filteredData;
|
||||
};
|
||||
|
||||
Packer.prototype._packChunk = function(type, data) {
|
||||
|
|
@ -85,19 +63,19 @@ Packer.prototype._packChunk = function(type, data) {
|
|||
return buf;
|
||||
};
|
||||
|
||||
Packer.prototype._packGAMA = function(gamma) {
|
||||
Packer.prototype.packGAMA = function(gamma) {
|
||||
var buf = new Buffer(4);
|
||||
buf.writeUInt32BE(Math.floor(gamma * constants.GAMMA_DIVISION), 0);
|
||||
return this._packChunk(constants.TYPE_gAMA, buf);
|
||||
};
|
||||
|
||||
Packer.prototype._packIHDR = function(width, height, bitDepth, colorType) {
|
||||
Packer.prototype.packIHDR = function(width, height) {
|
||||
|
||||
var buf = new Buffer(13);
|
||||
buf.writeUInt32BE(width, 0);
|
||||
buf.writeUInt32BE(height, 4);
|
||||
buf[8] = bitDepth; // Bit depth
|
||||
buf[9] = colorType; // colorType
|
||||
buf[8] = this._options.bitDepth; // Bit depth
|
||||
buf[9] = this._options.colorType; // colorType
|
||||
buf[10] = 0; // compression
|
||||
buf[11] = 0; // filter
|
||||
buf[12] = 0; // interlace
|
||||
|
|
@ -105,10 +83,10 @@ Packer.prototype._packIHDR = function(width, height, bitDepth, colorType) {
|
|||
return this._packChunk(constants.TYPE_IHDR, buf);
|
||||
};
|
||||
|
||||
Packer.prototype._packIDAT = function(data) {
|
||||
Packer.prototype.packIDAT = function(data) {
|
||||
return this._packChunk(constants.TYPE_IDAT, data);
|
||||
};
|
||||
|
||||
Packer.prototype._packIEND = function() {
|
||||
Packer.prototype.packIEND = function() {
|
||||
return this._packChunk(constants.TYPE_IEND, null);
|
||||
};
|
||||
};
|
||||
|
|
@ -2,9 +2,15 @@
|
|||
|
||||
|
||||
var parse = require('./parser-sync');
|
||||
var pack = require('./packer-sync');
|
||||
|
||||
|
||||
exports.read = function(buffer, options) {
|
||||
|
||||
return parse(buffer, options || {});
|
||||
};
|
||||
|
||||
exports.write = function(png) {
|
||||
|
||||
return pack(png);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
var util = require('util');
|
||||
var Stream = require('stream');
|
||||
var Parser = require('./parser-async');
|
||||
var Packer = require('./packer');
|
||||
var Packer = require('./packer-async');
|
||||
var PNGSync = require('./png-sync');
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue