mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-11 16:26:20 +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 { Arrow, ExpandIcon } from '../icons';
|
||||
import { generateCliInvocation } from '../util/cli';
|
||||
import * as WebCodecs from '../util/web-codecs';
|
||||
|
||||
export type OutputType = EncoderType | 'identity';
|
||||
|
||||
@@ -109,8 +110,12 @@ async function decodeImage(
|
||||
if (mimeType === 'image/webp2') {
|
||||
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));
|
||||
} catch (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