mirror of
https://github.com/DustinBrett/daedalOS.git
synced 2025-12-06 12:20:20 +01:00
HEIF support
This commit is contained in:
parent
325047b681
commit
a65ebb0fc0
|
|
@ -150,6 +150,7 @@
|
||||||
### Photos
|
### Photos
|
||||||
|
|
||||||
- [Supported Formats](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#supported_image_formats)
|
- [Supported Formats](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#supported_image_formats)
|
||||||
|
- [HEIF](https://github.com/catdad-experiments/libheif-js) (**_.heic, .heif_**)
|
||||||
- [JPEG XL](https://github.com/niutech/jxl.js) (**_.jxl_**)
|
- [JPEG XL](https://github.com/niutech/jxl.js) (**_.jxl_**)
|
||||||
- [QOI](https://gist.github.com/nicolaslegland/f0577cb49b1e56b729a2c0fc0aa151ba) (**_.qoi_**)
|
- [QOI](https://gist.github.com/nicolaslegland/f0577cb49b1e56b729a2c0fc0aa151ba) (**_.qoi_**)
|
||||||
- [TIFF](https://github.com/photopea/UTIF.js) (**_.tif, .tiff_**)
|
- [TIFF](https://github.com/photopea/UTIF.js) (**_.tif, .tiff_**)
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,13 @@ import { useViewport } from "contexts/viewport";
|
||||||
import useDoubleClick from "hooks/useDoubleClick";
|
import useDoubleClick from "hooks/useDoubleClick";
|
||||||
import Button from "styles/common/Button";
|
import Button from "styles/common/Button";
|
||||||
import {
|
import {
|
||||||
|
HEIF_IMAGE_FORMATS,
|
||||||
HIGH_PRIORITY_ELEMENT,
|
HIGH_PRIORITY_ELEMENT,
|
||||||
IMAGE_FILE_EXTENSIONS,
|
IMAGE_FILE_EXTENSIONS,
|
||||||
TIFF_IMAGE_FORMATS,
|
TIFF_IMAGE_FORMATS,
|
||||||
} from "utils/constants";
|
} from "utils/constants";
|
||||||
import {
|
import {
|
||||||
|
decodeHeic,
|
||||||
decodeJxl,
|
decodeJxl,
|
||||||
getExtension,
|
getExtension,
|
||||||
haltEvent,
|
haltEvent,
|
||||||
|
|
@ -62,6 +64,8 @@ const Photos: FC<ComponentProcessProps> = ({ id }) => {
|
||||||
const { decodeQoi } = await import("components/apps/Photos/qoi");
|
const { decodeQoi } = await import("components/apps/Photos/qoi");
|
||||||
|
|
||||||
fileContents = decodeQoi(fileContents);
|
fileContents = decodeQoi(fileContents);
|
||||||
|
} else if (HEIF_IMAGE_FORMATS.has(ext)) {
|
||||||
|
fileContents = await decodeHeic(fileContents);
|
||||||
} else if (TIFF_IMAGE_FORMATS.has(ext)) {
|
} else if (TIFF_IMAGE_FORMATS.has(ext)) {
|
||||||
fileContents = (await import("utif"))
|
fileContents = (await import("utif"))
|
||||||
.bufferToURI(fileContents)
|
.bufferToURI(fileContents)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import {
|
||||||
FOLDER_BACK_ICON,
|
FOLDER_BACK_ICON,
|
||||||
FOLDER_FRONT_ICON,
|
FOLDER_FRONT_ICON,
|
||||||
FOLDER_ICON,
|
FOLDER_ICON,
|
||||||
|
HEIF_IMAGE_FORMATS,
|
||||||
ICON_CACHE,
|
ICON_CACHE,
|
||||||
ICON_CACHE_EXTENSION,
|
ICON_CACHE_EXTENSION,
|
||||||
ICON_GIF_FPS,
|
ICON_GIF_FPS,
|
||||||
|
|
@ -45,6 +46,7 @@ import {
|
||||||
blobToBase64,
|
blobToBase64,
|
||||||
bufferToUrl,
|
bufferToUrl,
|
||||||
cleanUpBufferUrl,
|
cleanUpBufferUrl,
|
||||||
|
decodeHeic,
|
||||||
decodeJxl,
|
decodeJxl,
|
||||||
getExtension,
|
getExtension,
|
||||||
getGifJs,
|
getGifJs,
|
||||||
|
|
@ -785,6 +787,18 @@ export const getInfoWithExtension = (
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
} else if (HEIF_IMAGE_FORMATS.has(extension)) {
|
||||||
|
getInfoByFileExtension(PHOTO_ICON, (signal) =>
|
||||||
|
fs.readFile(path, async (error, contents = Buffer.from("")) => {
|
||||||
|
if (!error && contents.length > 0 && !signal.aborted) {
|
||||||
|
const icon = await decodeHeic(contents);
|
||||||
|
|
||||||
|
if (icon && !signal.aborted) {
|
||||||
|
getInfoByFileExtension(imageToBufferUrl(path, icon));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
} else if (IMAGE_FILE_EXTENSIONS.has(extension)) {
|
} else if (IMAGE_FILE_EXTENSIONS.has(extension)) {
|
||||||
getInfoByFileExtension(PHOTO_ICON, (signal) =>
|
getInfoByFileExtension(PHOTO_ICON, (signal) =>
|
||||||
fs.readFile(path, (error, contents = Buffer.from("")) => {
|
fs.readFile(path, (error, contents = Buffer.from("")) => {
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@
|
||||||
"idb": "^8.0.0",
|
"idb": "^8.0.0",
|
||||||
"ini": "^4.1.1",
|
"ini": "^4.1.1",
|
||||||
"isomorphic-git": "^1.25.6",
|
"isomorphic-git": "^1.25.6",
|
||||||
|
"libheif-js": "^1.17.1",
|
||||||
"mediainfo.js": "^0.2.1",
|
"mediainfo.js": "^0.2.1",
|
||||||
"minimist": "^1.2.8",
|
"minimist": "^1.2.8",
|
||||||
"multiformats": "^13.1.0",
|
"multiformats": "^13.1.0",
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ This project is greatly augmented by code from the open source community. Thank
|
||||||
- [Matrix](https://github.com/Rezmason/matrix)
|
- [Matrix](https://github.com/Rezmason/matrix)
|
||||||
- [QOI Decoder](https://gist.github.com/nicolaslegland/f0577cb49b1e56b729a2c0fc0aa151ba)
|
- [QOI Decoder](https://gist.github.com/nicolaslegland/f0577cb49b1e56b729a2c0fc0aa151ba)
|
||||||
- [jxl.js](https://github.com/niutech/jxl.js)
|
- [jxl.js](https://github.com/niutech/jxl.js)
|
||||||
|
- [libheif-js](https://github.com/catdad-experiments/libheif-js)
|
||||||
- [fix-webm-duration](https://github.com/yusitnikov/fix-webm-duration)
|
- [fix-webm-duration](https://github.com/yusitnikov/fix-webm-duration)
|
||||||
- [UAParser.js](https://github.com/faisalman/ua-parser-js)
|
- [UAParser.js](https://github.com/faisalman/ua-parser-js)
|
||||||
- [Web Stable Diffusion](https://github.com/mlc-ai/web-stable-diffusion)
|
- [Web Stable Diffusion](https://github.com/mlc-ai/web-stable-diffusion)
|
||||||
|
|
|
||||||
29
public/System/libheif/libheif-bundle.js
Normal file
29
public/System/libheif/libheif-bundle.js
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -77,6 +77,15 @@ export const LIST_VIEW_ANIMATION = {
|
||||||
transition: { duration: 0.15 },
|
transition: { duration: 0.15 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const HEIF_IMAGE_FORMATS = new Set([
|
||||||
|
".heic",
|
||||||
|
".heics",
|
||||||
|
".heif",
|
||||||
|
".heifs",
|
||||||
|
".avci",
|
||||||
|
".avcs",
|
||||||
|
]);
|
||||||
|
|
||||||
export const TIFF_IMAGE_FORMATS = new Set([
|
export const TIFF_IMAGE_FORMATS = new Set([
|
||||||
".cr2",
|
".cr2",
|
||||||
".dng",
|
".dng",
|
||||||
|
|
@ -88,6 +97,7 @@ export const TIFF_IMAGE_FORMATS = new Set([
|
||||||
export const CLIPBOARD_FILE_EXTENSIONS = new Set([".jpeg", ".jpg", ".png"]);
|
export const CLIPBOARD_FILE_EXTENSIONS = new Set([".jpeg", ".jpg", ".png"]);
|
||||||
|
|
||||||
export const IMAGE_FILE_EXTENSIONS = new Set([
|
export const IMAGE_FILE_EXTENSIONS = new Set([
|
||||||
|
...HEIF_IMAGE_FORMATS,
|
||||||
...TIFF_IMAGE_FORMATS,
|
...TIFF_IMAGE_FORMATS,
|
||||||
".ani",
|
".ani",
|
||||||
".apng",
|
".apng",
|
||||||
|
|
@ -112,6 +122,7 @@ export const IMAGE_FILE_EXTENSIONS = new Set([
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const UNSUPPORTED_BACKGROUND_EXTENSIONS = new Set([
|
export const UNSUPPORTED_BACKGROUND_EXTENSIONS = new Set([
|
||||||
|
...HEIF_IMAGE_FORMATS,
|
||||||
...TIFF_IMAGE_FORMATS,
|
...TIFF_IMAGE_FORMATS,
|
||||||
".jxl",
|
".jxl",
|
||||||
".qoi",
|
".qoi",
|
||||||
|
|
|
||||||
|
|
@ -358,6 +358,47 @@ export const getHtmlToImage = async (): Promise<
|
||||||
return htmlToImage;
|
return htmlToImage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type LibHeif = {
|
||||||
|
libheif: () => {
|
||||||
|
HeifDecoder: new () => {
|
||||||
|
decode: (file: Buffer) => {
|
||||||
|
display: (
|
||||||
|
imageData: ImageData,
|
||||||
|
callback: (data: ImageData) => void
|
||||||
|
) => void;
|
||||||
|
get_height: () => number;
|
||||||
|
get_width: () => number;
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
ready: Promise<void>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const decodeHeic = async (image: Buffer): Promise<Buffer> => {
|
||||||
|
await loadFiles(["/System/libheif/libheif-bundle.js"], false, true);
|
||||||
|
|
||||||
|
const { libheif } = window as unknown as Window & LibHeif;
|
||||||
|
const { HeifDecoder, ready } = libheif();
|
||||||
|
|
||||||
|
await ready;
|
||||||
|
|
||||||
|
const [decodedImage] = new HeifDecoder().decode(image);
|
||||||
|
const width = decodedImage.get_width();
|
||||||
|
const height = decodedImage.get_height();
|
||||||
|
const { data } = await new Promise<ImageData>((resolve) => {
|
||||||
|
decodedImage.display(
|
||||||
|
{
|
||||||
|
data: new Uint8ClampedArray(width * height * 4),
|
||||||
|
height,
|
||||||
|
width,
|
||||||
|
} as ImageData,
|
||||||
|
resolve
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return imgDataToBuffer(new ImageData(data, width, height));
|
||||||
|
};
|
||||||
|
|
||||||
export const pxToNum = (value: number | string = 0): number =>
|
export const pxToNum = (value: number | string = 0): number =>
|
||||||
typeof value === "number" ? value : Number.parseFloat(value);
|
typeof value === "number" ? value : Number.parseFloat(value);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4942,6 +4942,11 @@ levn@^0.4.1:
|
||||||
prelude-ls "^1.2.1"
|
prelude-ls "^1.2.1"
|
||||||
type-check "~0.4.0"
|
type-check "~0.4.0"
|
||||||
|
|
||||||
|
libheif-js@^1.17.1:
|
||||||
|
version "1.17.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/libheif-js/-/libheif-js-1.17.1.tgz#7772cc5a31098df0354f0fadb49a939030765acd"
|
||||||
|
integrity sha512-g9wBm/CasGZMjmH3B2sD9+AO7Y5+79F0oPS+sdAulSxQeYeCeiTIP+lDqvlPofD+y76wvfVtotKZ8AuvZQnWgg==
|
||||||
|
|
||||||
lie@~3.3.0:
|
lie@~3.3.0:
|
||||||
version "3.3.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a"
|
resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user