Rework lower
This commit is contained in:
@@ -26,15 +26,6 @@ const needsJPEGConversionExtensions = [
|
||||
export const needsJPEGConversion = (extension: string) =>
|
||||
needsJPEGConversionExtensions.includes(extension.toLowerCase());
|
||||
|
||||
/**
|
||||
* Return true if {@link extension} _might_ be supported by the user's browser.
|
||||
*
|
||||
* For example, JPEG 2000 (jp2) is supported by Safari, but not by Chrome or
|
||||
* Firefox, and this function will return true for `jp2`.
|
||||
*/
|
||||
export const hasPartialBrowserSupport = (extension: string) =>
|
||||
["jp2"].includes(extension.toLowerCase());
|
||||
|
||||
/**
|
||||
* Return `true` if {@link extension} in for an HEIC-like file.
|
||||
*/
|
||||
|
||||
@@ -2,26 +2,19 @@ import { isDesktop } from "@/base/app";
|
||||
import log from "@/base/log";
|
||||
import { CustomErrorMessage } from "@/base/types/ipc";
|
||||
import { workerBridge } from "@/base/worker/worker-bridge";
|
||||
import { hasPartialBrowserSupport, needsJPEGConversion } from "@/media/formats";
|
||||
import { needsJPEGConversion } from "@/media/formats";
|
||||
import { heicToJPEG } from "@/media/heic-convert";
|
||||
import type { EnteFile } from "../types/file";
|
||||
import { detectFileTypeInfo } from "./detect-type";
|
||||
|
||||
class ModuleState {
|
||||
/**
|
||||
* This will be set to true if we get an error from the Node.js side of our
|
||||
* desktop app telling us that native JPEG conversion is not available for
|
||||
* the current OS/arch combination.
|
||||
*
|
||||
* That way, we can stop pestering it again and again (saving an IPC
|
||||
* round-trip).
|
||||
*
|
||||
* Note the double negative when it is used.
|
||||
*/
|
||||
isNativeJPEGConversionNotAvailable = false;
|
||||
}
|
||||
|
||||
const moduleState = new ModuleState();
|
||||
/**
|
||||
* This will be set to false if we get an error from the Node.js side of our
|
||||
* desktop app telling us that native JPEG conversion is not available for the
|
||||
* current OS/arch combination.
|
||||
*
|
||||
* That way, we can stop pestering it again and again, saving an IPC round-trip.
|
||||
*/
|
||||
let _isNativeJPEGConversionAvailable = true;
|
||||
|
||||
/**
|
||||
* @returns a string to use as an identifier when logging information about the
|
||||
@@ -78,8 +71,8 @@ export function mergeMetadata(files: EnteFile[]): EnteFile[] {
|
||||
* 1. Try to detect the MIME type of the file from its contents and/or name.
|
||||
*
|
||||
* 2. If this detected type is one of the types that we know that the browser
|
||||
* doesn't know how to render, continue. Otherwise return the imageBlob that
|
||||
* was passed in (after setting its MIME type).
|
||||
* likely cannot render, continue. Otherwise return the imageBlob that was
|
||||
* passed in (after setting its MIME type).
|
||||
*
|
||||
* 3. If we're running in our desktop app and this MIME type is something our
|
||||
* desktop app can natively convert to a JPEG (using ffmpeg), do that and
|
||||
@@ -88,27 +81,27 @@ export function mergeMetadata(files: EnteFile[]): EnteFile[] {
|
||||
* 4. If this is an HEIC file, use our (WASM) HEIC converter and return the
|
||||
* resultant JPEG blob.
|
||||
*
|
||||
* 5. Otherwise (or if any error occurs in the aforementioned steps), return
|
||||
* `undefined`.
|
||||
* 5. Otherwise return the original (with the MIME type if we were able to
|
||||
* deduce one).
|
||||
*
|
||||
* In will catch all errors and return the original in those cases.
|
||||
*/
|
||||
export const renderableImageBlob = async (
|
||||
fileName: string,
|
||||
imageBlob: Blob,
|
||||
) => {
|
||||
try {
|
||||
const tempFile = new File([imageBlob], fileName);
|
||||
const fileTypeInfo = await detectFileTypeInfo(tempFile);
|
||||
log.debug(
|
||||
() =>
|
||||
`Need renderable image for ${JSON.stringify({ fileName, ...fileTypeInfo })}`,
|
||||
);
|
||||
const { extension } = fileTypeInfo;
|
||||
const file = new File([imageBlob], fileName);
|
||||
const fileTypeInfo = await detectFileTypeInfo(file);
|
||||
const { extension, mimeType } = fileTypeInfo;
|
||||
|
||||
log.debug(() => ["Get renderable blob", { fileName, ...fileTypeInfo }]);
|
||||
|
||||
if (needsJPEGConversion(extension)) {
|
||||
const available = !moduleState.isNativeJPEGConversionNotAvailable;
|
||||
if (isDesktop && available) {
|
||||
// If we're running in our desktop app, see if our Node.js layer
|
||||
// can convert this into a JPEG using native tools.
|
||||
// If we're running in our desktop app, see if our Node.js layer can
|
||||
// convert this into a JPEG using native tools.
|
||||
|
||||
if (isDesktop && _isNativeJPEGConversionAvailable) {
|
||||
try {
|
||||
return await nativeConvertToJPEG(imageBlob);
|
||||
} catch (e) {
|
||||
@@ -116,23 +109,20 @@ export const renderableImageBlob = async (
|
||||
e instanceof Error &&
|
||||
e.message.endsWith(CustomErrorMessage.NotAvailable)
|
||||
) {
|
||||
moduleState.isNativeJPEGConversionNotAvailable = true;
|
||||
_isNativeJPEGConversionAvailable = false;
|
||||
} else {
|
||||
log.error("Native conversion to JPEG failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the previous step failed, or if native JPEG conversion is not
|
||||
// available on this platform, for HEIC/HEIF files we can fallback
|
||||
// to our web HEIC converter.
|
||||
|
||||
if (extension == "heic" || extension == "heif") {
|
||||
// If the previous step failed, or if native JPEG conversion is
|
||||
// not available on this platform, for HEIC/HEIF files we can
|
||||
// fallback to our web HEIC converter.
|
||||
return await heicToJPEG(imageBlob);
|
||||
}
|
||||
|
||||
// Continue if it might be possibly supported in some browsers,
|
||||
// otherwise bail out.
|
||||
if (!hasPartialBrowserSupport(extension)) return undefined;
|
||||
}
|
||||
|
||||
// Either it is something that the browser already knows how to render
|
||||
@@ -143,16 +133,21 @@ export const renderableImageBlob = async (
|
||||
//
|
||||
// Give it to the browser, attaching the mime type if possible.
|
||||
|
||||
const mimeType = fileTypeInfo.mimeType;
|
||||
if (!mimeType) {
|
||||
log.info("Trying to render a file without a MIME type", fileName);
|
||||
log.info(
|
||||
"Attempting to get renderable blob for a file without a MIME type",
|
||||
fileName,
|
||||
);
|
||||
return imageBlob;
|
||||
} else {
|
||||
return new Blob([imageBlob], { type: mimeType });
|
||||
}
|
||||
} catch (e) {
|
||||
log.error(`Failed to get renderable image for ${fileName}`, e);
|
||||
return undefined;
|
||||
log.error(
|
||||
`Failed to get renderable blob for ${fileName}, will fallback to the original`,
|
||||
e,
|
||||
);
|
||||
return imageBlob;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user