Skip to content

Instantly share code, notes, and snippets.

@valpackett
Created July 25, 2019 12:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save valpackett/638f8f489a1e0ebd53e3788c04264c41 to your computer and use it in GitHub Desktop.
Save valpackett/638f8f489a1e0ebd53e3788c04264c41 to your computer and use it in GitHub Desktop.
oxipng wasm wrapper
(async function () {
await wasm_bindgen('oxipng_wasm_bg.wasm')
window.oxi = wasm_bindgen
oxi.init()
const resp = await fetch('y.png')
const arb = await resp.arrayBuffer()
const uarr = new Uint8Array(arb)
console.log(uarr)
const t0 = performance.now()
window.result = oxi.optimize_from_memory(uarr)
const t1 = performance.now()
console.log(result)
console.log(`Took ${t1 - t0} ms`)
alert(`Took ${t1 - t0} ms`)
})()
#![feature(proc_macro, wasm_custom_section, wasm_import_module, set_stdio)]
use std::{io, panic};
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
#[wasm_bindgen(js_namespace = console)]
fn error(s: &str);
}
type PrintFn = extern "C" fn(&str);
struct Printer {
printfn: PrintFn,
buffer: String,
is_buffered: bool,
}
impl Printer {
fn new(printfn: PrintFn, is_buffered: bool) -> Printer {
Printer {
buffer: String::new(),
printfn,
is_buffered,
}
}
}
impl io::Write for Printer {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.buffer.push_str(&String::from_utf8_lossy(buf));
if !self.is_buffered {
(self.printfn)(&self.buffer);
self.buffer.clear();
return Ok(buf.len());
}
if let Some(i) = self.buffer.rfind('\n') {
let buffered = {
let (first, last) = self.buffer.split_at(i);
(self.printfn)(first);
String::from(&last[1..])
};
self.buffer.clear();
self.buffer.push_str(&buffered);
}
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
(self.printfn)(&self.buffer);
self.buffer.clear();
Ok(())
}
}
#[wasm_bindgen]
pub fn init() {
io::set_print(Some(Box::new(Printer::new(log, true))));
io::set_panic(Some(Box::new(Printer::new(error, true))));
panic::set_hook(Box::new(|info| {
let file = info.location().unwrap().file();
let line = info.location().unwrap().line();
let col = info.location().unwrap().column();
let msg = match info.payload().downcast_ref::<&'static str>() {
Some(s) => *s,
None => {
match info.payload().downcast_ref::<String>() {
Some(s) => &s[..],
None => "Box<Any>",
}
}
};
let err_info = format!("Panicked at '{}', {}:{}:{}", msg, file, line, col);
error(&err_info);
}));
}
#[wasm_bindgen]
pub fn optimize_from_memory(data: &[u8]) -> Vec<u8> {
let mut opts: oxipng::Options = Default::default();
eprintln!("OPTS {:?}", opts);
oxipng::optimize_from_memory(data, &opts).unwrap()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment