Skip to content

Commit 98a1746

Browse files
authored
Merge pull request #23 from 343dev/improvement/exec-buffer
Remove exec-buffer dep
2 parents 71ba3f5 + b18d77f commit 98a1746

File tree

4 files changed

+77
-70
lines changed

4 files changed

+77
-70
lines changed

optimize.js

Lines changed: 63 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
import { spawn } from 'node:child_process';
12
import fs from 'node:fs';
23
import os from 'node:os';
34
import path from 'node:path';
45

56
import guetzli from '@343dev/guetzli';
6-
import execBuffer from 'exec-buffer';
77
import gifsicle from 'gifsicle';
88
import pLimit from 'p-limit';
99
import sharp from 'sharp';
@@ -164,28 +164,30 @@ async function processJpeg({ fileBuffer, config, isLossless }) {
164164
const sharpImage = sharp(fileBuffer)
165165
.rotate(); // Rotate image using information from EXIF Orientation tag
166166

167-
if (isLossless) {
168-
const inputBuffer = await sharpImage
169-
.toColorspace('srgb') // Replace colorspace (guetzli works only with sRGB)
170-
.jpeg({ quality: 100, optimizeCoding: false }) // Applying maximum quality to minimize losses during image processing with sharp
167+
if (!isLossless) {
168+
return sharpImage
169+
.jpeg(config?.jpeg?.lossy || {})
171170
.toBuffer();
172-
173-
return execBuffer({
174-
bin: guetzli,
175-
args: [
176-
...optionsToArguments({
177-
options: config?.jpeg?.lossless || {},
178-
}),
179-
execBuffer.input,
180-
execBuffer.output,
181-
],
182-
input: inputBuffer,
183-
});
184171
}
185172

186-
return sharpImage
187-
.jpeg(config?.jpeg?.lossy || {})
173+
const inputBuffer = await sharpImage
174+
.toColorspace('srgb') // Replace colorspace (guetzli works only with sRGB)
175+
.jpeg({ quality: 100, optimizeCoding: false }) // Applying maximum quality to minimize losses during image processing with sharp
188176
.toBuffer();
177+
178+
const commandOptions = [
179+
...optionsToArguments({
180+
options: config?.jpeg?.lossless || {},
181+
}),
182+
'-',
183+
'-',
184+
];
185+
186+
return pipe({
187+
command: guetzli,
188+
commandOptions,
189+
inputBuffer,
190+
});
189191
}
190192

191193
function processPng({ fileBuffer, config, isLossless }) {
@@ -195,20 +197,20 @@ function processPng({ fileBuffer, config, isLossless }) {
195197
}
196198

197199
function processGif({ fileBuffer, config, isLossless }) {
198-
return execBuffer({
199-
bin: gifsicle,
200-
args: [
201-
...optionsToArguments({
202-
options: (isLossless ? config?.gif?.lossless : config?.gif?.lossy) || {},
203-
concat: true,
204-
}),
205-
`--threads=${os.cpus().length}`,
206-
'--no-warnings',
207-
'--output',
208-
execBuffer.output,
209-
execBuffer.input,
210-
],
211-
input: fileBuffer,
200+
const commandOptions = [
201+
...optionsToArguments({
202+
options: (isLossless ? config?.gif?.lossless : config?.gif?.lossy) || {},
203+
concat: true,
204+
}),
205+
`--threads=${os.cpus().length}`,
206+
'--no-warnings',
207+
'-',
208+
];
209+
210+
return pipe({
211+
command: gifsicle,
212+
commandOptions,
213+
inputBuffer: fileBuffer,
212214
});
213215
}
214216

@@ -220,3 +222,31 @@ function processSvg({ fileBuffer, config }) {
220222
).data,
221223
);
222224
}
225+
226+
function pipe({ command, commandOptions, inputBuffer }) {
227+
return new Promise((resolve, reject) => {
228+
const process = spawn(command, commandOptions);
229+
230+
process.stdin.write(inputBuffer);
231+
process.stdin.end();
232+
233+
const stdoutChunks = [];
234+
process.stdout.on('data', chunk => {
235+
stdoutChunks.push(chunk);
236+
});
237+
238+
process.on('error', error => {
239+
reject(new Error(`Error processing image: ${error.message}`));
240+
});
241+
242+
process.on('close', code => {
243+
if (code !== 0) {
244+
reject(new Error(`Image optimization process exited with code ${code}`));
245+
return;
246+
}
247+
248+
const processedFileBuffer = Buffer.concat(stdoutChunks);
249+
resolve(processedFileBuffer);
250+
});
251+
});
252+
}

package-lock.json

Lines changed: 12 additions & 34 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,9 @@
4545
"node": ">=18.18"
4646
},
4747
"dependencies": {
48-
"@343dev/guetzli": "^1.0.1",
48+
"@343dev/guetzli": "^1.1.0",
4949
"cli-progress": "^3.11.0",
5050
"commander": "^12.1.0",
51-
"exec-buffer": "^3.2.0",
5251
"fdir": "^6.4.0",
5352
"gifsicle": "^7.0.1",
5453
"p-limit": "^6.1.0",

tests/cli.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ describe('CLI', () => {
8888
const stdout = runCliWithParameters(`--lossless ${workDirectory}${file}`);
8989

9090
expectFileRatio({
91-
stdout, file, maxRatio: 50, minRatio: 45,
91+
stdout, file, maxRatio: 55, minRatio: 45,
9292
});
9393
});
9494

0 commit comments

Comments
 (0)