mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix: restore-photo colorize hang and AVIF decode failures
- Fix dispatcher pipe deadlock: drain stdout pipe in a background thread to prevent blocking when ONNX runtime output exceeds 64KB pipe buffer - Add 5-minute SSE stall timeout so the UI shows an error instead of hanging forever when async AI processing stalls - Guard CPU colorization: skip for images >2MP on CPU and when DDColor model is not installed, with clear user-facing messages - Add AVIF decode fallback via ImageMagick for bitstream variants that Sharp's bundled libheif cannot decode (affects all tools)
This commit is contained in:
@@ -90,6 +90,31 @@ export async function decodeToSharpCompat(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Last-resort decode: convert any image to PNG via ImageMagick.
|
||||
* Used when Sharp's bundled decoders fail (e.g. AVIF 2.0 bitstreams).
|
||||
*/
|
||||
export async function decodeAnyFormat(buffer: Buffer, format: string): Promise<Buffer> {
|
||||
const cmd = await findMagickCmd();
|
||||
const id = randomUUID();
|
||||
const ext = format || "img";
|
||||
const inputPath = join(tmpdir(), `any-in-${id}.${ext}`);
|
||||
const outputPath = join(tmpdir(), `any-out-${id}.png`);
|
||||
|
||||
try {
|
||||
await writeFile(inputPath, buffer);
|
||||
await execFileAsync(
|
||||
cmd,
|
||||
magickArgs(cmd, [inputPath, "-colorspace", "sRGB", `png:${outputPath}`]),
|
||||
{ timeout: 120_000 },
|
||||
);
|
||||
return await readFile(outputPath);
|
||||
} finally {
|
||||
await rm(inputPath, { force: true }).catch(() => {});
|
||||
await rm(outputPath, { force: true }).catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
// ── ImageMagick helpers ────────────────────────────────────────
|
||||
|
||||
let cachedMagickCmd: string | null = null;
|
||||
|
||||
Reference in New Issue
Block a user