diff --git a/web/apps/photos/src/services/heic-convert.ts b/web/apps/photos/src/services/heic-convert.ts index 21e8572d8..7d0f11a4f 100644 --- a/web/apps/photos/src/services/heic-convert.ts +++ b/web/apps/photos/src/services/heic-convert.ts @@ -7,16 +7,16 @@ import { retryAsyncFunction } from "@ente/shared/utils"; import QueueProcessor from "@ente/shared/utils/queueProcessor"; import { type DedicatedConvertWorker } from "worker/convert.worker"; -class HeicConversionService { - async convert(heicFileData: Blob): Promise { - try { - return await WasmHEICConverterService.convert(heicFileData); - } catch (e) { - log.error("failed to convert heic file", e); - throw e; - } - } -} +/** + * Convert a HEIC image to a JPEG. + * + * Behind the scenes, it uses a web worker pool to do the conversion using a + * WASM HEIC conversion package. + * + * @param heicBlob The HEIC blob to convert. + * @returns The JPEG blob. + */ +export const heicToJPEG = (heicBlob: Blob) => converter.convert(heicBlob); const WORKER_POOL_SIZE = 2; const WAIT_TIME_BEFORE_NEXT_ATTEMPT_IN_MICROSECONDS = [100, 100]; @@ -118,8 +118,8 @@ class HEICConverter { } } -const WasmHEICConverterService = new HEICConverter(); -export default new HeicConversionService(); +/** The singleton instance of {@link HEICConverter}. */ +const converter = new HEICConverter(); export const getDedicatedConvertWorker = () => { if (haveWindow()) { diff --git a/web/apps/photos/src/services/upload/thumbnail.ts b/web/apps/photos/src/services/upload/thumbnail.ts index fd7ed9a38..005b02265 100644 --- a/web/apps/photos/src/services/upload/thumbnail.ts +++ b/web/apps/photos/src/services/upload/thumbnail.ts @@ -5,7 +5,7 @@ import { CustomError } from "@ente/shared/error"; import { FILE_TYPE } from "constants/file"; import { BLACK_THUMBNAIL_BASE64 } from "constants/upload"; import * as FFmpegService from "services/ffmpeg"; -import HeicConversionService from "services/heic-convert"; +import { heicToJPEG } from "services/heic-convert"; import { ElectronFile, FileTypeInfo } from "types/upload"; import { isFileHEIC } from "utils/file"; import { getUint8ArrayView } from "../readerService"; @@ -136,15 +136,13 @@ async function generateImageThumbnailUsingCanvas( let imageURL = null; let timeout = null; - const isHEIC = isFileHEIC(fileTypeInfo.exactType); - if (isHEIC) { - log.info(`HEICConverter called for ${getFileNameSize(file)}`); - const convertedBlob = await HeicConversionService.convert( - new Blob([await file.arrayBuffer()]), - ); - file = new File([convertedBlob], file.name); - log.info(`${getFileNameSize(file)} successfully converted`); + + if (isFileHEIC(fileTypeInfo.exactType)) { + log.debug(() => `Pre-converting ${getFileName(file)} to HEIC`); + const jpegBlob = await heicToJPEG(new Blob([await file.arrayBuffer()])); + file = new File([jpegBlob], file.name); } + let image = new Image(); imageURL = URL.createObjectURL(new Blob([await file.arrayBuffer()])); await new Promise((resolve, reject) => { diff --git a/web/apps/photos/src/utils/file/index.ts b/web/apps/photos/src/utils/file/index.ts index f2fd9ba26..a6275f254 100644 --- a/web/apps/photos/src/utils/file/index.ts +++ b/web/apps/photos/src/utils/file/index.ts @@ -25,7 +25,7 @@ import { updateFileMagicMetadata, updateFilePublicMagicMetadata, } from "services/fileService"; -import heicConversionService from "services/heic-convert"; +import { heicToJPEG } from "services/heic-convert"; import { getFileType } from "services/typeDetectionService"; import { updateFileCreationDateInEXIF } from "services/upload/exifService"; import { @@ -311,7 +311,7 @@ export const getRenderableImage = async (fileName: string, imageBlob: Blob) => { if (!jpegBlob && isFileHEIC(exactType)) { // If it is an HEIC file, use our web HEIC converter. - jpegBlob = await heicConversionService.convert(imageBlob); + jpegBlob = await heicToJPEG(imageBlob); } return jpegBlob;