Skip to content

Commit

Permalink
Don't childProcess.spawn until the first .write call.
Browse files Browse the repository at this point in the history
  • Loading branch information
papandreou committed Sep 22, 2014
1 parent acfc186 commit d6b72e4
Showing 1 changed file with 53 additions and 35 deletions.
88 changes: 53 additions & 35 deletions lib/PngQuant.js
Expand Up @@ -12,46 +12,17 @@ var binPath = pngQuantBin ? pngQuantBin.path : 'pngquant';
function PngQuant(pngQuantArgs) {
Stream.call(this);

if (!pngQuantArgs || pngQuantArgs.length === 0) {
pngQuantArgs = [256];
this.pngQuantArgs = pngQuantArgs;

if (!this.pngQuantArgs || this.pngQuantArgs.length === 0) {
this.pngQuantArgs = [256];
}

this.writable = this.readable = true;
this.commandLine = binPath + (pngQuantArgs ? ' ' + pngQuantArgs.join(' ') : ''); // For debugging
this.pngQuantProcess = childProcess.spawn(binPath, pngQuantArgs);

this.hasEnded = false;
this.seenDataOnStdout = false;

this.pngQuantProcess.on('error', this._reportError.bind(this));

this.pngQuantProcess.stderr.on('data', function (data) {
if (!this.hasEnded) {
this._reportError(new Error('Saw pngquant output on stderr: ' + data.toString('ascii')));
this.hasEnded = true;
}
}.bind(this));

this.pngQuantProcess.on('exit', function (exitCode) {
if (exitCode > 0 && !this.hasEnded) {
this._reportError(new Error('The pngquant process exited with a non-zero exit code: ' + exitCode));
this.hasEnded = true;
}
}.bind(this));

this.pngQuantProcess.stdout.on('data', function (chunk) {
this.seenDataOnStdout = true;
this.emit('data', chunk);
}.bind(this)).on('end', function () {
if (!this.hasEnded) {
if (this.seenDataOnStdout) {
this.emit('end');
} else {
this._reportError(new Error('PngQuant: The stdout stream ended without emitting any data'));
}
this.hasEnded = true;
}
}.bind(this));
}

util.inherits(PngQuant, Stream);
Expand All @@ -64,22 +35,69 @@ PngQuant.prototype._reportError = function (err) {
};

PngQuant.prototype.write = function (chunk) {
if (!this.pngQuantProcess) {
this.pngQuantProcess = childProcess.spawn(binPath, this.pngQuantArgs);
this.pngQuantProcess.on('error', this._reportError.bind(this));

this.pngQuantProcess.stderr.on('data', function (data) {
if (!this.hasEnded) {
this._reportError(new Error('Saw pngquant output on stderr: ' + data.toString('ascii')));
this.hasEnded = true;
}
}.bind(this));

this.pngQuantProcess.on('exit', function (exitCode) {
if (exitCode > 0 && !this.hasEnded) {
this._reportError(new Error('The pngquant process exited with a non-zero exit code: ' + exitCode));
this.hasEnded = true;
}
}.bind(this));

this.pngQuantProcess.stdout.on('data', function (chunk) {
this.seenDataOnStdout = true;
this.emit('data', chunk);
}.bind(this)).on('end', function () {
if (!this.hasEnded) {
if (this.seenDataOnStdout) {
this.emit('end');
} else {
this._reportError(new Error('PngQuant: The stdout stream ended without emitting any data'));
}
this.hasEnded = true;
}
}.bind(this));

if (this.pauseStdoutOfPngQuantProcessAfterStartingIt) {
this.pngQuantProcess.stdout.pause();
}
}
this.pngQuantProcess.stdin.write(chunk);
};

PngQuant.prototype.end = function (chunk) {
if (chunk) {
this.write(chunk);
} else if (!this.pngQuantProcess) {
// No chunks have been rewritten. Write an empty one to make sure there's pngquant process.
this.write(new Buffer(0));
}
this.pngQuantProcess.stdin.end();
};

PngQuant.prototype.pause = function () {
this.pngQuantProcess.stdout.pause();
if (this.pngQuantProcess) {
this.pngQuantProcess.stdout.pause();
} else {
this.pauseStdoutOfPngQuantProcessAfterStartingIt = true;
}
};

PngQuant.prototype.resume = function () {
this.pngQuantProcess.stdout.resume();
if (this.pngQuantProcess) {
this.pngQuantProcess.stdout.resume();
} else {
this.pauseStdoutOfPngQuantProcessAfterStartingIt = false;
}
};

module.exports = PngQuant;

0 comments on commit d6b72e4

Please sign in to comment.