diff --git a/.travis.yml b/.travis.yml index 5b76e6d..cc4dba2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,4 @@ language: node_js node_js: - - "0.4" - - "0.6" - "0.8" - "0.10" diff --git a/lib/command.js b/lib/command.js index 9d384aa..571c9dc 100644 --- a/lib/command.js +++ b/lib/command.js @@ -206,6 +206,31 @@ module.exports = function (proto) { } self.sourceStream.pipe(proc.stdin); + + // We cache the buffers for get operations + // as we may use it again. + // This wouldn't make sense for a convert operation. + // We rely on garbage collection for optimization, + // so if want to kill trash the garbage quickly, + // do `this._buffers = null`. + // We do this in lieu of `bufferStream`, + // with this being more magical. + if (self.bufferStream && !this._buffering) { + // Incase there are multiple processes in parallel, + // we only need one + this._buffering = true + var buffers = [] + + self.sourceStream.on('data', function (chunk) { + buffers.push(chunk) + }) + + // Kill reference as we assume the stream is dead. + self.sourceStream.on('end', function () { + self.sourceBuffer = Buffer.concat(buffers) + self.sourceStream = null + }) + } } // for _exec operations (identify() mostly), we also diff --git a/lib/convenience/autoOrient.js b/lib/convenience/autoOrient.js index c2c82b0..1ae143e 100644 --- a/lib/convenience/autoOrient.js +++ b/lib/convenience/autoOrient.js @@ -18,7 +18,7 @@ module.exports = function (proto) { proto.autoOrient = function autoOrient () { this.preprocessor(function (callback) { - this.orientation(function (err, orientation) { + this.orientation({bufferStream: true}, function (err, orientation) { if (err) return callback(err); var transforms = exifTransforms[orientation.toLowerCase()]; diff --git a/lib/getters.js b/lib/getters.js index a5f03df..0b2749f 100644 --- a/lib/getters.js +++ b/lib/getters.js @@ -51,6 +51,8 @@ module.exports = function (gm) { self.on(getter, createListener(callback)); + self.bufferStream = !!opts.bufferStream; + if (val.verbose) { self.identify(opts, function (err, stdout, stderr, cmd) { if (err) { @@ -111,6 +113,8 @@ module.exports = function (gm) { self._identifyState = IDENTIFYING; + self.bufferStream = !!opts.bufferStream; + var args = makeArgs(self, { verbose: true }); self._exec(args, function (err, stdout, stderr, cmd) { diff --git a/test/autoOrientStream.js b/test/autoOrientStream.js new file mode 100644 index 0000000..6f19075 --- /dev/null +++ b/test/autoOrientStream.js @@ -0,0 +1,42 @@ + +// gm - Copyright Aaron Heckmann (MIT Licensed) +// This is a copy of `autoOrient.js` using streams + +var assert = require('assert') +var fs = require('fs') + +module.exports = function (_, dir, finish, gm) { + if (!gm.integration) + return finish(); + + var filename = dir + '/autoOrient.jpg'; + + gm(fs.createReadStream(dir + '/originalSideways.jpg')).orientation(function (err, o) { + if (err) return finish(err); + + assert.equal('RightTop', o); + assert.ok(!! this.data['Profile-EXIF'], 'No Profile-EXIF data found'); + assert.equal('155x460', this.data.Geometry); + + // this image is sideways, but may be auto-oriented by modern OS's + // try opening it in a browser to see its true orientation + gm(fs.createReadStream(dir + '/originalSideways.jpg')) + .autoOrient() + .write(filename, function autoOrient (err) { + if (err) return finish(err); + + // fs race condition + setTimeout(function () { + gm(filename).identify(function (err) { + if (err) return finish(err); + + assert.equal('Unknown', this.data.Orientation); + assert.ok(! this.data['Profile-EXIF'], 'Profile-EXIF still exists'); + assert.equal('460x155', this.data.Geometry); + + finish(err); + }); + }, 200); + }); + }); +} \ No newline at end of file diff --git a/test/streamInGetter.js b/test/streamInGetter.js index 4b0f208..9fed5f9 100644 --- a/test/streamInGetter.js +++ b/test/streamInGetter.js @@ -6,17 +6,10 @@ module.exports = function (_, dir, finish, gm) { if (!gm.integration) return finish(); - var imageStream = fs.createReadStream(dir + '/original.jpg') - - var buffers = [] - imageStream.on('data', function (chunk) { - buffers.push(chunk) - }) - - gm(imageStream) - .size(function (err, size) { - gm(Buffer.concat(buffers)).write(dir + '/streamInGetter.png', function streamInGetter (err){ + gm(fs.createReadStream(dir + '/original.jpg')) + .size({bufferStream: true}, function (err, size) { + this.write(dir + '/streamInGetter.png', function streamInGetter (err){ finish(err); }); }); -} +} \ No newline at end of file