feat(nitro): convert imported SWF bundles to WebP Lossless

Newly converted .nitro bundles now store their spritesheet as WebP VP8L
instead of PNG, so imports land much smaller without changing a single
pixel. The texture member and spritesheet.meta.image are both labelled
from the actual bytes, never from a caller's assumption.

- encode through sharp with lossless and exact, so colour hidden under
  alpha 0 survives; this mirrors ImageSharp's TransparentColorMode.Preserve
- detect PNG/WebP by magic bytes and reject anything the client cannot
  render, on create, download and upload paths
- keep the source format when deriving size-32 sheets, scaling composites
  and editing metadata, so existing bundles are never silently rewritten
- report fidelity in the studio: the compression panel re-encodes with the
  same options the importer uses, so it cannot drift and invent false
  warnings, and shows PNG/WebP size estimates

convertSwfToNitro and buildSpritesheet are now async, so the worker, the
main-thread fallback and every import call site await them. PNG stays
supported for existing bundles and icon sidecars are untouched.
This commit is contained in:
openhands
2026-09-27 15:42:21 +02:00
parent 420210ffa0
commit 17de94d984
22 changed files with 1118 additions and 125 deletions
+1 -1
View File
@@ -78,7 +78,7 @@ export async function importSinglePet(params: {
onProgress?.("converting");
try {
const swfBuffer = await fs.readFile(/*turbopackIgnore: true*/ swfPath);
const result = convertSwfToNitro(swfBuffer, lib);
const result = await convertSwfToNitro(swfBuffer, lib);
await fs.writeFile(
/*turbopackIgnore: true*/ nitroPathFor(lib),
result.bundle,