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:
@@ -11,7 +11,7 @@ import { formatZodErrors } from "../../lib/errors.js";
|
||||
import { isToolInstalled } from "../../lib/feature-status.js";
|
||||
import { validateImageBuffer } from "../../lib/file-validation.js";
|
||||
import { sanitizeFilename } from "../../lib/filename.js";
|
||||
import { decodeToSharpCompat, needsCliDecode } from "../../lib/format-decoders.js";
|
||||
import { decodeAnyFormat, decodeToSharpCompat, needsCliDecode } from "../../lib/format-decoders.js";
|
||||
import { decodeHeic } from "../../lib/heic-converter.js";
|
||||
import { resolveOutputFormat } from "../../lib/output-format.js";
|
||||
import { createWorkspace } from "../../lib/workspace.js";
|
||||
@@ -113,6 +113,21 @@ export function registerRestorePhoto(app: FastifyInstance) {
|
||||
|
||||
// Auto-orient to fix EXIF rotation
|
||||
fileBuffer = await autoOrient(fileBuffer);
|
||||
|
||||
// AVIF can pass metadata validation but fail pixel decode when
|
||||
// Sharp's bundled libheif lacks support for the bitstream version.
|
||||
// Convert early (the sidecar needs PNG anyway); fall back to ImageMagick.
|
||||
if (validation.format === "avif") {
|
||||
try {
|
||||
fileBuffer = await sharp(fileBuffer).png().toBuffer();
|
||||
} catch {
|
||||
request.log.warn(
|
||||
{ toolId: "restore-photo" },
|
||||
"Sharp AVIF decode failed, using ImageMagick",
|
||||
);
|
||||
fileBuffer = await decodeAnyFormat(fileBuffer, "avif");
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
request.log.error({ err, toolId: "restore-photo" }, "Input decoding failed");
|
||||
return reply.status(422).send({
|
||||
|
||||
Reference in New Issue
Block a user