diff --git a/src/client/lazy-app/Compress/index.tsx b/src/client/lazy-app/Compress/index.tsx index 232fe667..19e30fcb 100644 --- a/src/client/lazy-app/Compress/index.tsx +++ b/src/client/lazy-app/Compress/index.tsx @@ -11,6 +11,7 @@ import { canDecodeImageType, abortable, assertSignal, + ImageMimeTypes, } from '../util'; import { PreprocessorState, @@ -102,7 +103,7 @@ async function decodeImage( if (mimeType === 'image/webp') { return await workerBridge.webpDecode(signal, blob); } - if (mimeType === 'image/jpegxl') { + if (mimeType === 'image/jxl') { return await workerBridge.jxlDecode(signal, blob); } if (mimeType === 'image/webp2') { @@ -178,10 +179,13 @@ async function compressImage( encodeData.options as any, ); + // This type ensures the image mimetype is consistent with our mimetype sniffer + const type: ImageMimeTypes = encoder.meta.mimeType; + return new File( [compressedData], sourceFilename.replace(/.[^.]*$/, `.${encoder.meta.extension}`), - { type: encoder.meta.mimeType }, + { type }, ); } diff --git a/src/client/lazy-app/util/index.ts b/src/client/lazy-app/util/index.ts index 208bd194..3c6dd6bc 100644 --- a/src/client/lazy-app/util/index.ts +++ b/src/client/lazy-app/util/index.ts @@ -137,7 +137,7 @@ export function blobToText(blob: Blob): Promise { return new Response(blob).text(); } -const magicNumberToMimeType = new Map([ +const magicNumberMapInput = [ [/^%PDF-/, 'application/pdf'], [/^GIF87a/, 'image/gif'], [/^GIF89a/, 'image/gif'], @@ -150,11 +150,17 @@ const magicNumberToMimeType = new Map([ [/^RIFF....WEBPVP8[LX ]/, 'image/webp'], [/^\xF4\xFF\x6F/, 'image/webp2'], [/^\x00\x00\x00 ftypavif\x00\x00\x00\x00/, 'image/avif'], - [/^\xff\x0a/, 'image/jpegxl'], - [/^\x00\x00\x00\x0cJXL \x0d\x0a\x87\x0a/, 'image/jpegxl'], -]); + [/^\xff\x0a/, 'image/jxl'], + [/^\x00\x00\x00\x0cJXL \x0d\x0a\x87\x0a/, 'image/jxl'], +] as const; -export async function sniffMimeType(blob: Blob): Promise { +export type ImageMimeTypes = typeof magicNumberMapInput[number][1]; + +const magicNumberToMimeType = new Map( + magicNumberMapInput, +); + +export async function sniffMimeType(blob: Blob): Promise { const firstChunk = await blobToArrayBuffer(blob.slice(0, 16)); const firstChunkString = Array.from(new Uint8Array(firstChunk)) .map((v) => String.fromCodePoint(v)) diff --git a/src/features/encoders/jxl/shared/meta.ts b/src/features/encoders/jxl/shared/meta.ts index 03e797db..cb47e292 100644 --- a/src/features/encoders/jxl/shared/meta.ts +++ b/src/features/encoders/jxl/shared/meta.ts @@ -15,7 +15,7 @@ import type { EncodeOptions } from 'codecs/jxl/enc/jxl_enc'; export { EncodeOptions }; export const label = 'JPEG XL (beta)'; -export const mimeType = 'image/jpegxl'; +export const mimeType = 'image/jxl'; export const extension = 'jxl'; export const defaultOptions: EncodeOptions = { speed: 4,