mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-12 08:47:31 +00:00
Add a call-out to Web Codecs API
This commit is contained in:
@@ -34,6 +34,7 @@ import { resize } from 'features/processors/resize/client';
|
|||||||
import type SnackBarElement from 'shared/custom-els/snack-bar';
|
import type SnackBarElement from 'shared/custom-els/snack-bar';
|
||||||
import { Arrow, ExpandIcon } from '../icons';
|
import { Arrow, ExpandIcon } from '../icons';
|
||||||
import { generateCliInvocation } from '../util/cli';
|
import { generateCliInvocation } from '../util/cli';
|
||||||
|
import * as WebCodecs from '../util/web-codecs';
|
||||||
|
|
||||||
export type OutputType = EncoderType | 'identity';
|
export type OutputType = EncoderType | 'identity';
|
||||||
|
|
||||||
@@ -109,8 +110,12 @@ async function decodeImage(
|
|||||||
if (mimeType === 'image/webp2') {
|
if (mimeType === 'image/webp2') {
|
||||||
return await workerBridge.wp2Decode(signal, blob);
|
return await workerBridge.wp2Decode(signal, blob);
|
||||||
}
|
}
|
||||||
// If it's not one of those types, fall through and try built-in decoding for a laugh.
|
|
||||||
}
|
}
|
||||||
|
// If none of those work, let’s see if Web Codecs API is available
|
||||||
|
if (await WebCodecs.isTypeSupported(mimeType)) {
|
||||||
|
return await abortable(signal, WebCodecs.decode(blob, mimeType));
|
||||||
|
}
|
||||||
|
// Otherwise fall through and try built-in decoding for a laugh.
|
||||||
return await abortable(signal, builtinDecode(blob));
|
return await abortable(signal, builtinDecode(blob));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.name === 'AbortError') throw err;
|
if (err.name === 'AbortError') throw err;
|
||||||
|
|||||||
26
src/client/lazy-app/util/web-codecs/index.ts
Normal file
26
src/client/lazy-app/util/web-codecs/index.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { drawableToImageData } from 'client/lazy-app/util';
|
||||||
|
|
||||||
|
const hasImageDecoder = typeof ImageDecoder !== 'undefined';
|
||||||
|
export async function isTypeSupported(mimeType: string): Promise<boolean> {
|
||||||
|
if (!hasImageDecoder) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ImageDecoder.isTypeSupported(mimeType);
|
||||||
|
}
|
||||||
|
export async function decode(
|
||||||
|
blob: Blob | File,
|
||||||
|
mimeType: string,
|
||||||
|
): Promise<ImageData> {
|
||||||
|
if (!hasImageDecoder) {
|
||||||
|
throw Error(
|
||||||
|
`This browser does not support ImageDecoder. This function should not have been called.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const decoder = new ImageDecoder({
|
||||||
|
type: mimeType,
|
||||||
|
// Non-obvious way to turn an Blob into a ReadableStream
|
||||||
|
data: new Response(blob).body!,
|
||||||
|
});
|
||||||
|
const result = await decoder.decode();
|
||||||
|
return drawableToImageData(result.image);
|
||||||
|
}
|
||||||
28
src/client/lazy-app/util/web-codecs/missing-types.d.ts
vendored
Normal file
28
src/client/lazy-app/util/web-codecs/missing-types.d.ts
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
interface ImageDecoderInit {
|
||||||
|
type: string;
|
||||||
|
data: BufferSource | ReadableStream;
|
||||||
|
premultiplyAlpha?: PremultiplyAlpha;
|
||||||
|
colorSpaceConversion?: ColorSpaceConversion;
|
||||||
|
desiredWidth?: number;
|
||||||
|
desiredHeight?: number;
|
||||||
|
preferAnimation?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImageDecodeOptions {
|
||||||
|
frameIndex: number;
|
||||||
|
completeFramesOnly: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ImageDecodeResult {
|
||||||
|
image: VideoFrame;
|
||||||
|
complete: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Absolutely not correct, but it’s all we need and I’m lazy.
|
||||||
|
type VideoFrame = ImageBitmap;
|
||||||
|
|
||||||
|
declare class ImageDecoder {
|
||||||
|
static isTypeSupported(type: string): Promise<boolean>;
|
||||||
|
constructor(desc: ImageDecoderInit);
|
||||||
|
decode(opts?: Partial<ImageDecodeOptions>): Promise<ImageDecodeResult>;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user