Skip to content

eugenezastrogin/ICDeno

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 

Repository files navigation

ICDeno

This is a research project to make Image CDN using wasm codecs from squoosh.

Summary

Main pain point is to make wasm codecs play ball with deno. Neither wasm-bindgen nor emscripten support deno at the moment. On top of this, squoosh relies on built-in image decoding via getImageData and deno doesn't have any canvas implementation yet, so we will have to use extra wasm library to decode images into RGBA first.

Libraries

Oxipng

Oxipng is written in rust, so this is relatively easy.

import * as wasm from "./squoosh_oxipng_bg.wasm";

This no longer works in deno, you have to use the following:

const f = await Deno.open("codecs/oxipng/pkg/squoosh_oxipng_bg.wasm");
const buf = await Deno.readAll(f);
const wasmModule = new WebAssembly.Module(buf);
const importObject = { "./squoosh_oxipng_bg.js": { __wbindgen_throw } };
const wasmInstance = new WebAssembly.Instance(wasmModule, importObject);
const wasm = wasmInstance.exports;

You have to import __wbindgen_throw js function explicitly into wasm module, not sure how it works implicitly in squoosh.

Be sure to --allow-read=codecs for this to work.

ImageQuant

ImageQuant uses emscripten, this is going to be a bit trickier.

Makefile changes to make js glue have proper es6 import:

  --s EXPORT_ES6=1 \

To interface js and c strings emscripten uses TextDecoder('utf-16le'), this is going to throw, deno does not support it at the moment (see PR). Since imagequant doesn't work with strings, it is safe to just replace it with utf-8.

Next problem is that emscripten glue uses its own wasm loading mechanism, based on the environment (and it is not aware of deno, so it fallbacks to generic web behavior). We have to overload readBinary function to work around erroneous environment detection.

PNG Decoder/Encoder

png is not in squoosh, but we need it to work around missing canvas. It is a rust library and can be built the same way ImageQuant was.

Usage

Launch server with:

deno run --allow-net --allow-read=codecs src/main.ts

Be sure to launch server from ICDeno root, otherwise deno won't find wasm modules (file reads in deno are relative to work dir).

Once the server is up use it like this:

http://server-address/fetch/http://image-adress.png?format=webp&q=75

For example, with default local server location:

http://localhost:3030/fetch/http://www.libpng.org/pub/png/PngSuite/basn4a08.png?format=webp&q=75