97 lines
2.7 KiB
Plaintext
97 lines
2.7 KiB
Plaintext
import { cpus } from "node:os";
|
|
import { fileURLToPath } from "node:url";
|
|
import { isMainThread } from "node:worker_threads";
|
|
import { getModuleURL } from "./emscripten-utils.js";
|
|
import * as impl from "./impl.js";
|
|
import execOnce from "./utils/execOnce.js";
|
|
import WorkerPool from "./utils/workerPool.js";
|
|
const getWorker = execOnce(() => {
|
|
return new WorkerPool(
|
|
// There will be at most 7 workers needed since each worker will take
|
|
// at least 1 operation type.
|
|
Math.max(1, Math.min(cpus().length - 1, 7)),
|
|
fileURLToPath(getModuleURL(import.meta.url))
|
|
);
|
|
});
|
|
function handleJob(params) {
|
|
switch (params.operation) {
|
|
case "decode":
|
|
return impl.decodeBuffer(params.buffer);
|
|
case "resize":
|
|
return impl.resize({
|
|
image: params.imageData,
|
|
width: params.width,
|
|
height: params.height
|
|
});
|
|
case "rotate":
|
|
return impl.rotate(params.imageData, params.numRotations);
|
|
case "encodeavif":
|
|
return impl.encodeAvif(params.imageData, { quality: params.quality });
|
|
case "encodejpeg":
|
|
return impl.encodeJpeg(params.imageData, { quality: params.quality });
|
|
case "encodepng":
|
|
return impl.encodePng(params.imageData);
|
|
case "encodewebp":
|
|
return impl.encodeWebp(params.imageData, { quality: params.quality });
|
|
default:
|
|
throw Error(`Invalid job "${params.operation}"`);
|
|
}
|
|
}
|
|
async function processBuffer(buffer, operations, encoding, quality) {
|
|
const worker = await getWorker();
|
|
let imageData = await worker.dispatchJob({
|
|
operation: "decode",
|
|
buffer
|
|
});
|
|
for (const operation of operations) {
|
|
if (operation.type === "rotate") {
|
|
imageData = await worker.dispatchJob({
|
|
operation: "rotate",
|
|
imageData,
|
|
numRotations: operation.numRotations
|
|
});
|
|
} else if (operation.type === "resize") {
|
|
imageData = await worker.dispatchJob({
|
|
operation: "resize",
|
|
imageData,
|
|
height: operation.height,
|
|
width: operation.width
|
|
});
|
|
}
|
|
}
|
|
switch (encoding) {
|
|
case "avif":
|
|
return await worker.dispatchJob({
|
|
operation: "encodeavif",
|
|
imageData,
|
|
quality
|
|
});
|
|
case "jpeg":
|
|
case "jpg":
|
|
return await worker.dispatchJob({
|
|
operation: "encodejpeg",
|
|
imageData,
|
|
quality
|
|
});
|
|
case "png":
|
|
return await worker.dispatchJob({
|
|
operation: "encodepng",
|
|
imageData
|
|
});
|
|
case "webp":
|
|
return await worker.dispatchJob({
|
|
operation: "encodewebp",
|
|
imageData,
|
|
quality
|
|
});
|
|
default:
|
|
throw Error(`Unsupported encoding format`);
|
|
}
|
|
}
|
|
if (!isMainThread) {
|
|
WorkerPool.useThisThreadAsWorker(handleJob);
|
|
}
|
|
export {
|
|
processBuffer
|
|
};
|