feat: oops wait no THIS is icns support

This commit is contained in:
not-nullptr 2025-04-15 15:11:13 +01:00
parent 8616651d2a
commit d9f3b21db3
7 changed files with 64 additions and 16 deletions

View File

@ -7,7 +7,6 @@
"@bjorn3/browser_wasi_shim": "^0.4.1",
"@ffmpeg/ffmpeg": "^0.12.15",
"@ffmpeg/util": "^0.12.2",
"@fiahfy/icns": "^0.0.7",
"@fontsource/azeret-mono": "^5.1.1",
"@fontsource/lexend": "^5.1.2",
"@fontsource/radio-canada-big": "^5.1.1",
@ -19,7 +18,9 @@
"music-metadata": "^11.0.0",
"p-queue": "^8.1.0",
"riff-file": "^1.0.3",
"vert-wasm": "^0.0.2",
"vite-plugin-static-copy": "^2.2.0",
"vite-plugin-wasm": "^3.4.1",
"wasm-vips": "^0.0.11",
},
"devDependencies": {
@ -121,10 +122,6 @@
"@ffmpeg/util": ["@ffmpeg/util@0.12.2", "", {}, "sha512-ouyoW+4JB7WxjeZ2y6KpRvB+dLp7Cp4ro8z0HIVpZVCM7AwFlHa0c4R8Y/a4M3wMqATpYKhC7lSFHQ0T11MEDw=="],
"@fiahfy/icns": ["@fiahfy/icns@0.0.7", "", { "dependencies": { "@fiahfy/packbits": "^0.0.6", "pngjs": "^6.0.0" } }, "sha512-0apAtbUXTU3Opy/Z4h69o53voBa+am8FmdZauyagUMskAVYN1a5yIRk48Sf+tEdBLlefbvqLWPJ4pxr/Y/QtTg=="],
"@fiahfy/packbits": ["@fiahfy/packbits@0.0.6", "", {}, "sha512-XuhF/edg+iIvXjkCWgfj6fWtRi/KrEPg2ILXj1l86EN4EssuOiPcLKgkMDr9cL8jTGtVd/MKUWW6Y0/ZVf1PGA=="],
"@fontsource/azeret-mono": ["@fontsource/azeret-mono@5.2.5", "", {}, "sha512-GRzKYuD1CVOS6Jag/ohDCycLV9a3TK6y1T73A8q0JoDZTVO85DNapqLK+SV2gYtTFldahNAlDSIaizv9MLhR1A=="],
"@fontsource/lexend": ["@fontsource/lexend@5.2.5", "", {}, "sha512-Mv2XQ+B4ek2lNCGRW5ddLTW8T3xTT17AnCk1IETpoef57XHz+e42fUfLAYMrmiJLOGpR44qnyJ5S6D323A5EIw=="],
@ -613,8 +610,6 @@
"pirates": ["pirates@4.0.6", "", {}, "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg=="],
"pngjs": ["pngjs@6.0.0", "", {}, "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="],
"postcss": ["postcss@8.5.3", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A=="],
"postcss-import": ["postcss-import@15.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="],
@ -739,10 +734,14 @@
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
"vert-wasm": ["vert-wasm@0.0.2", "", {}, "sha512-QCkhkATZkWp3OPpIrlcLVd5S4DQXeDEWIPI1eV+Ku+sUVoCM4s9DQbNKtnJ8s4leMW3AD4E7cY/gXB/9TsI3WA=="],
"vite": ["vite@5.4.14", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA=="],
"vite-plugin-static-copy": ["vite-plugin-static-copy@2.3.0", "", { "dependencies": { "chokidar": "^3.5.3", "fast-glob": "^3.2.11", "fs-extra": "^11.1.0", "p-map": "^7.0.3", "picocolors": "^1.0.0" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0" } }, "sha512-LLKwhhHetGaCnWz4mas4qqjjguDka6/6b4+SeIohRroj8aCE7QTfiZECfPecslFQkWZ3HdQuq5kOPmWZjNYlKA=="],
"vite-plugin-wasm": ["vite-plugin-wasm@3.4.1", "", { "peerDependencies": { "vite": "^2 || ^3 || ^4 || ^5 || ^6" } }, "sha512-ja3nSo2UCkVeitltJGkS3pfQHAanHv/DqGatdI39ja6McgABlpsZ5hVgl6wuR8Qx5etY3T5qgDQhOWzc5RReZA=="],
"vitefu": ["vitefu@1.0.6", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" }, "optionalPeers": ["vite"] }, "sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA=="],
"wasm-vips": ["wasm-vips@0.0.11", "", {}, "sha512-bzFU7WcimMY4WeqnZk7whKVpSXxpagISXPJwsk2VHF4lgIN9rl4uUo5sF9x6jOlACuCH6ITZUJ7QPTYmy60NCQ=="],

View File

@ -37,7 +37,6 @@
"@bjorn3/browser_wasi_shim": "^0.4.1",
"@ffmpeg/ffmpeg": "^0.12.15",
"@ffmpeg/util": "^0.12.2",
"@fiahfy/icns": "^0.0.7",
"@fontsource/azeret-mono": "^5.1.1",
"@fontsource/lexend": "^5.1.2",
"@fontsource/radio-canada-big": "^5.1.1",
@ -49,7 +48,9 @@
"music-metadata": "^11.0.0",
"p-queue": "^8.1.0",
"riff-file": "^1.0.3",
"vert-wasm": "^0.0.2",
"vite-plugin-static-copy": "^2.2.0",
"vite-plugin-wasm": "^3.4.1",
"wasm-vips": "^0.0.11"
}
}

View File

@ -1,4 +1,3 @@
import type { Converter } from "./converter.svelte";
import { FFmpegConverter } from "./ffmpeg.svelte";
import { PandocConverter } from "./pandoc.svelte";
import { VertdConverter } from "./vertd.svelte";

View File

@ -22,10 +22,11 @@ export class VipsConverter extends Converter {
new FormatInfo("jpg", true, true),
new FormatInfo("webp", true, true),
new FormatInfo("gif", true, true),
new FormatInfo("heic", true, false),
new FormatInfo("ico", true, false),
new FormatInfo("cur", true, false),
new FormatInfo("ani", true, false),
new FormatInfo("heic", true, false),
new FormatInfo("icns", true, false),
new FormatInfo("nef", true, false),
new FormatInfo("cr2", true, false),
new FormatInfo("hdr", true, true),

View File

View File

@ -10,7 +10,7 @@ import {
import { makeZip } from "client-zip";
import wasm from "@imagemagick/magick-wasm/magick.wasm?url";
import { parseAni } from "$lib/parse/ani";
import { Icns } from "@fiahfy/icns/dist";
import { parseIcns } from "vert-wasm";
const vipsPromise = Vips({
dynamicLibraries: [],
@ -158,8 +158,6 @@ const handleMessage = async (message: any): Promise<any> => {
}
}
console.log(message.input.from);
const img = MagickImage.create(
new Uint8Array(buffer),
new MagickReadSettings({
@ -178,11 +176,59 @@ const handleMessage = async (message: any): Promise<any> => {
}
if (message.input.from === ".icns") {
const icns = Icns.from(new Uint8Array(buffer));
console.log(icns);
const icns: Uint8Array[] = parseIcns(new Uint8Array(buffer));
// Result<T> in vert-wasm maps to a string in JS
if (typeof icns === "string") {
return {
type: "error",
error: `Failed to read ICNS -- ${icns}`,
};
}
const formats = [
MagickFormat.Png,
MagickFormat.Jpeg,
MagickFormat.Rgba,
MagickFormat.Rgb,
];
const outputs: Uint8Array[] = [];
for (const file of icns) {
for (const format of formats) {
try {
const img = MagickImage.create(
file,
new MagickReadSettings({
format: format,
}),
);
const converted = await magickConvert(
img,
message.to,
);
outputs.push(converted);
break;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (_) {
continue;
}
}
}
const zip = makeZip(
outputs.map(
(img, i) =>
new File([img], `image${i}.${message.to.slice(1)}`),
),
"images.zip",
);
const zipBytes = await readToEnd(zip.getReader());
return {
type: "finished",
output: zipBytes,
zip: true,
};
}
let image = vips.Image.newFromBuffer(buffer, "");
let image = vips.Image.newFromBuffer(buffer);
// check if animated image & keep it animated when converting
if (image.getTypeof("n-pages") > 0) {

View File

@ -2,6 +2,7 @@ import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";
import { viteStaticCopy } from "vite-plugin-static-copy";
import svg from "@poppanator/sveltekit-svg";
import wasm from "vite-plugin-wasm";
export default defineConfig({
plugins: [
@ -44,6 +45,7 @@ export default defineConfig({
},
],
}),
wasm(),
],
optimizeDeps: {
exclude: [