Ensure Readable can start flowing after Writable finish #671

This commit is contained in:
Lovell Fuller 2017-01-22 14:03:06 +00:00
parent d241efcdbe
commit d8df503404
4 changed files with 49 additions and 4 deletions

View File

@ -6,6 +6,10 @@ Requires libvips v8.4.2.
#### v0.17.2 - TBD #### v0.17.2 - TBD
* Ensure Readable side of Stream can start flowing after Writable side has finished.
[#671](https://github.com/lovell/sharp/issues/671)
[@danhaller](https://github.com/danhaller)
* Expose WebP alpha quality, lossless and near-lossless output options. * Expose WebP alpha quality, lossless and near-lossless output options.
[#685](https://github.com/lovell/sharp/pull/685) [#685](https://github.com/lovell/sharp/pull/685)
[@rnanwani](https://github.com/rnanwani) [@rnanwani](https://github.com/rnanwani)

View File

@ -64,6 +64,12 @@ const _write = function _write (chunk, encoding, callback) {
if (Array.isArray(this.options.input.buffer)) { if (Array.isArray(this.options.input.buffer)) {
/* istanbul ignore else */ /* istanbul ignore else */
if (is.buffer(chunk)) { if (is.buffer(chunk)) {
if (this.options.input.buffer.length === 0) {
const that = this;
this.on('finish', function () {
that.streamInFinished = true;
});
}
this.options.input.buffer.push(chunk); this.options.input.buffer.push(chunk);
callback(); callback();
} else { } else {

View File

@ -378,6 +378,18 @@ const _pipeline = function _pipeline (callback) {
// output=stream // output=stream
if (this._isStreamInput()) { if (this._isStreamInput()) {
// output=stream, input=stream // output=stream, input=stream
if (this.streamInFinished) {
this._flattenBufferIn();
sharp.pipeline(this.options, function (err, data, info) {
if (err) {
that.emit('error', err);
} else {
that.emit('info', info);
that.push(data);
}
that.push(null);
});
} else {
this.on('finish', function () { this.on('finish', function () {
that._flattenBufferIn(); that._flattenBufferIn();
sharp.pipeline(that.options, function (err, data, info) { sharp.pipeline(that.options, function (err, data, info) {
@ -390,6 +402,7 @@ const _pipeline = function _pipeline (callback) {
that.push(null); that.push(null);
}); });
}); });
}
} else { } else {
// output=stream, input=file/buffer // output=stream, input=file/buffer
sharp.pipeline(this.options, function (err, data, info) { sharp.pipeline(this.options, function (err, data, info) {

View File

@ -157,6 +157,28 @@ describe('Input/output', function () {
readableButNotAnImage.pipe(writable); readableButNotAnImage.pipe(writable);
}); });
it('Readable side of Stream can start flowing after Writable side has finished', function (done) {
const readable = fs.createReadStream(fixtures.inputJpg);
const writable = fs.createWriteStream(fixtures.outputJpg);
writable.on('finish', function () {
sharp(fixtures.outputJpg).toBuffer(function (err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual(data.length, info.size);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
fs.unlinkSync(fixtures.outputJpg);
done();
});
});
const pipeline = sharp().resize(320, 240);
readable.pipe(pipeline);
pipeline.on('finish', function () {
pipeline.pipe(writable);
});
});
it('Sequential read, force JPEG', function (done) { it('Sequential read, force JPEG', function (done) {
sharp(fixtures.inputJpg) sharp(fixtures.inputJpg)
.sequentialRead() .sequentialRead()