Promisify emscripten modules & fix webp examples (#817)

This commit is contained in:
Trevor Manz
2020-09-29 19:05:59 -04:00
committed by GitHub
parent 42f9e4aed2
commit 63ac34a662
9 changed files with 23 additions and 36 deletions

View File

@@ -2,5 +2,5 @@ interface AVIFModule extends EmscriptenWasm.Module {
decode(data: BufferSource): ImageData | null; decode(data: BufferSource): ImageData | null;
} }
export default function(opts: EmscriptenWasm.ModuleOpts): AVIFModule; export default function(opts: EmscriptenWasm.ModuleOpts): Promise<AVIFModule>;

View File

@@ -4,4 +4,4 @@ interface AVIFModule extends EmscriptenWasm.Module {
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array | null; encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array | null;
} }
export default function(opts: EmscriptenWasm.ModuleOpts): AVIFModule; export default function(opts: EmscriptenWasm.ModuleOpts): Promise<AVIFModule>;

View File

@@ -3,4 +3,4 @@ interface QuantizerModule extends EmscriptenWasm.Module {
zx_quantize(data: BufferSource, width: number, height: number, dither: number): Uint8ClampedArray; zx_quantize(data: BufferSource, width: number, height: number, dither: number): Uint8ClampedArray;
} }
export default function(opts: EmscriptenWasm.ModuleOpts): QuantizerModule; export default function(opts: EmscriptenWasm.ModuleOpts): Promise<QuantizerModule>;

View File

@@ -4,4 +4,4 @@ interface MozJPEGModule extends EmscriptenWasm.Module {
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array; encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array;
} }
export default function(opts: EmscriptenWasm.ModuleOpts): MozJPEGModule; export default function(opts: EmscriptenWasm.ModuleOpts): Promise<MozJPEGModule>;

View File

@@ -1,22 +1,20 @@
<!doctype html> <!doctype html>
<script src='webp_dec.js'></script> <script src='webp_dec.js'></script>
<script> <script>
const Module = webp_dec();
async function loadFile(src) { async function loadFile(src) {
const resp = await fetch(src); const resp = await fetch(src);
return await resp.arrayBuffer(); return await resp.arrayBuffer();
} }
Module.onRuntimeInitialized = async _ => { webp_dec().then(async module => {
console.log('Version:', Module.version().toString(16)); console.log('Version:', module.version().toString(16));
const image = await loadFile('../../example.webp'); const image = await loadFile('../../example.webp');
const imageData = Module.decode(image); const imageData = module.decode(image);
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
canvas.width = result.width; canvas.width = imageData.width;
canvas.height = result.height; canvas.height = imageData.height;
document.body.appendChild(canvas); document.body.appendChild(canvas);
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
ctx.putImageData(imageData, 0, 0); ctx.putImageData(imageData, 0, 0);
}; });
</script> </script>

View File

@@ -2,4 +2,4 @@ interface WebPModule extends EmscriptenWasm.Module {
decode(data: BufferSource): ImageData | null; decode(data: BufferSource): ImageData | null;
} }
export default function(opts: EmscriptenWasm.ModuleOpts): WebPModule; export default function(opts: EmscriptenWasm.ModuleOpts): Promise<WebPModule>;

View File

@@ -1,8 +1,6 @@
<!doctype html> <!doctype html>
<script src='webp_enc.js'></script> <script src='webp_enc.js'></script>
<script> <script>
const module = webp_enc();
async function loadImage(src) { async function loadImage(src) {
// Load image // Load image
const img = document.createElement('img'); const img = document.createElement('img');
@@ -17,7 +15,7 @@
return ctx.getImageData(0, 0, img.width, img.height); return ctx.getImageData(0, 0, img.width, img.height);
} }
module.onRuntimeInitialized = async _ => { webp_enc().then(async module => {
console.log('Version:', module.version().toString(16)); console.log('Version:', module.version().toString(16));
const image = await loadImage('../../example.png'); const image = await loadImage('../../example.png');
const result = module.encode(image.data, image.width, image.height, { const result = module.encode(image.data, image.width, image.height, {
@@ -56,5 +54,5 @@
const img = document.createElement('img'); const img = document.createElement('img');
img.src = blobURL; img.src = blobURL;
document.body.appendChild(img); document.body.appendChild(img);
}; });
</script> </script>

View File

@@ -4,4 +4,4 @@ interface WebPModule extends EmscriptenWasm.Module {
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array | null; encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array | null;
} }
export default function(opts: EmscriptenWasm.ModuleOpts): WebPModule; export default function(opts: EmscriptenWasm.ModuleOpts): Promise<WebPModule>;

View File

@@ -1,28 +1,19 @@
type ModuleFactory<M extends EmscriptenWasm.Module> = ( type ModuleFactory<M extends EmscriptenWasm.Module> = (
opts: EmscriptenWasm.ModuleOpts, opts: EmscriptenWasm.ModuleOpts,
) => M; ) => Promise<M>;
export function initEmscriptenModule<T extends EmscriptenWasm.Module>( export function initEmscriptenModule<T extends EmscriptenWasm.Module>(
moduleFactory: ModuleFactory<T>, moduleFactory: ModuleFactory<T>,
wasmUrl: string, wasmUrl: string,
): Promise<T> { ): Promise<T> {
return new Promise((resolve) => { return moduleFactory({
const module = moduleFactory({ // Just to be safe, don't automatically invoke any wasm functions
// Just to be safe, don't automatically invoke any wasm functions noInitialRun: true,
noInitialRun: true, locateFile(url: string): string {
locateFile(url: string): string { // Redirect the request for the wasm binary to whatever webpack gave us.
// Redirect the request for the wasm binary to whatever webpack gave us. if (url.endsWith('.wasm')) return wasmUrl;
if (url.endsWith('.wasm')) return wasmUrl; return url;
return url; },
},
onRuntimeInitialized() {
// An Emscripten is a then-able that resolves with itself, causing an infite loop when you
// wrap it in a real promise. Delete the `then` prop solves this for now.
// https://github.com/kripken/emscripten/issues/5820
delete (module as any).then;
resolve(module);
},
});
}); });
} }