-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Scaling works on native * It works in wasm * Integrate with UI * Remove benchmark * Integrate Hqx into Resizer module * Link against repo for hqx * Remove unused defaultOpts * Re-add test file * Adding size dropdown * Chrome: go and sit on the naughty step * Better docs * Review * Add link to crbug * Update src/codecs/processor-worker/index.ts Co-Authored-By: Jake Archibald <jaffathecake@gmail.com> * Terminate worker inbetween resize jobs
- Loading branch information
1 parent
24254df
commit 66feffc
Showing
25 changed files
with
539 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
**/*.rs.bk | ||
target | ||
Cargo.lock | ||
bin/ | ||
pkg/README.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
[package] | ||
name = "squooshhqx" | ||
version = "0.1.0" | ||
authors = ["Surma <surma@surma.link>"] | ||
|
||
[lib] | ||
crate-type = ["cdylib"] | ||
|
||
[features] | ||
default = ["console_error_panic_hook", "wee_alloc"] | ||
|
||
[dependencies] | ||
cfg-if = "0.1.2" | ||
wasm-bindgen = "0.2.38" | ||
# lazy_static = "1.0.0" | ||
hqx = {git = "https://github.com/CryZe/wasmboy-rs", tag="v0.1.2"} | ||
|
||
# The `console_error_panic_hook` crate provides better debugging of panics by | ||
# logging them with `console.error`. This is great for development, but requires | ||
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for | ||
# code size when deploying. | ||
console_error_panic_hook = { version = "0.1.1", optional = true } | ||
|
||
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size | ||
# compared to the default allocator's ~10K. It is slower than the default | ||
# allocator, however. | ||
# | ||
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now. | ||
wee_alloc = { version = "0.4.2", optional = true } | ||
|
||
[dev-dependencies] | ||
wasm-bindgen-test = "0.2" | ||
|
||
[profile.release] | ||
# Tell `rustc` to optimize for small code size. | ||
opt-level = "s" | ||
lto = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
FROM ubuntu | ||
RUN apt-get update && \ | ||
apt-get install -qqy git build-essential cmake python2.7 | ||
RUN git clone --recursive https://github.com/WebAssembly/wabt /usr/src/wabt | ||
RUN mkdir -p /usr/src/wabt/build | ||
WORKDIR /usr/src/wabt/build | ||
RUN cmake .. -DCMAKE_INSTALL_PREFIX=/opt/wabt && \ | ||
make && \ | ||
make install | ||
|
||
FROM rust | ||
RUN rustup install nightly && \ | ||
rustup target add --toolchain nightly wasm32-unknown-unknown && \ | ||
cargo install wasm-pack | ||
|
||
COPY --from=0 /opt/wabt /opt/wabt | ||
ENV PATH="/opt/wabt/bin:${PATH}" | ||
WORKDIR /src |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#!/bin/bash | ||
|
||
set -e | ||
|
||
echo "=============================================" | ||
echo "Compiling wasm" | ||
echo "=============================================" | ||
( | ||
rustup run nightly \ | ||
wasm-pack build --target no-modules | ||
wasm-strip pkg/squooshhqx_bg.wasm | ||
rm pkg/.gitignore | ||
) | ||
echo "=============================================" | ||
echo "Compiling wasm done" | ||
echo "=============================================" | ||
|
||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" | ||
echo "Did you update your docker image?" | ||
echo "Run \`docker pull ubuntu\`" | ||
echo "Run \`docker pull rust\`" | ||
echo "Run \`docker build -t squoosh-hqx .\`" | ||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<!doctype html> | ||
<script src ="./pkg/squooshhqx.js"></script> | ||
<script type="module"> | ||
async function run() { | ||
await wasm_bindgen("./pkg/squooshhqx_bg.wasm"); | ||
const bitmap = await createImageBitmap(await fetch("https://i.imgur.com/MNDnBSc.png").then(r => r.blob())); | ||
const canvas = document.createElement("canvas"); | ||
canvas.width = bitmap.width; | ||
canvas.height = bitmap.height; | ||
const ctx = canvas.getContext("2d"); | ||
ctx.drawImage(bitmap, 0, 0); | ||
const imgdata = ctx.getImageData(0, 0, bitmap.width, bitmap.height); | ||
const factor = 4; | ||
const r = wasm_bindgen.resize(new Uint32Array(imgdata.data.buffer), bitmap.width, bitmap.height, factor); | ||
|
||
canvas.width = bitmap.width * factor; | ||
canvas.height = bitmap.height * factor; | ||
const output = new ImageData(new Uint8ClampedArray(r.buffer), canvas.width, canvas.height); | ||
ctx.putImageData(output, 0, 0); | ||
canvas.style = `width: ${canvas.width}px; height: ${canvas.height}px; image-rendering: pixelated;`; | ||
document.body.append(canvas); | ||
} | ||
run(); | ||
</script> |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"name": "hqx", | ||
"scripts": { | ||
"build:image": "docker build -t squoosh-hqx .", | ||
"build": "docker run --rm -v $(pwd):/src squoosh-hqx ./build.sh" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"name": "squooshhqx", | ||
"collaborators": [ | ||
"Surma <surma@surma.link>" | ||
], | ||
"version": "0.1.0", | ||
"files": [ | ||
"squooshhqx_bg.wasm", | ||
"squooshhqx.js", | ||
"squooshhqx.d.ts" | ||
], | ||
"browser": "squooshhqx.js", | ||
"types": "squooshhqx.d.ts" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* tslint:disable */ | ||
/** | ||
* @param {Uint32Array} input_image | ||
* @param {number} input_width | ||
* @param {number} input_height | ||
* @param {number} factor | ||
* @returns {Uint32Array} | ||
*/ | ||
export function resize(input_image: Uint32Array, input_width: number, input_height: number, factor: number): Uint32Array; | ||
|
||
/** | ||
* If `module_or_path` is {RequestInfo}, makes a request and | ||
* for everything else, calls `WebAssembly.instantiate` directly. | ||
* | ||
* @param {RequestInfo | BufferSource | WebAssembly.Module} module_or_path | ||
* | ||
* @returns {Promise<any>} | ||
*/ | ||
export default function init (module_or_path: RequestInfo | BufferSource | WebAssembly.Module): Promise<any>; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
(function() { | ||
const __exports = {}; | ||
let wasm; | ||
|
||
let cachegetUint32Memory = null; | ||
function getUint32Memory() { | ||
if (cachegetUint32Memory === null || cachegetUint32Memory.buffer !== wasm.memory.buffer) { | ||
cachegetUint32Memory = new Uint32Array(wasm.memory.buffer); | ||
} | ||
return cachegetUint32Memory; | ||
} | ||
|
||
let WASM_VECTOR_LEN = 0; | ||
|
||
function passArray32ToWasm(arg) { | ||
const ptr = wasm.__wbindgen_malloc(arg.length * 4); | ||
getUint32Memory().set(arg, ptr / 4); | ||
WASM_VECTOR_LEN = arg.length; | ||
return ptr; | ||
} | ||
|
||
function getArrayU32FromWasm(ptr, len) { | ||
return getUint32Memory().subarray(ptr / 4, ptr / 4 + len); | ||
} | ||
|
||
let cachedGlobalArgumentPtr = null; | ||
function globalArgumentPtr() { | ||
if (cachedGlobalArgumentPtr === null) { | ||
cachedGlobalArgumentPtr = wasm.__wbindgen_global_argument_ptr(); | ||
} | ||
return cachedGlobalArgumentPtr; | ||
} | ||
/** | ||
* @param {Uint32Array} input_image | ||
* @param {number} input_width | ||
* @param {number} input_height | ||
* @param {number} factor | ||
* @returns {Uint32Array} | ||
*/ | ||
__exports.resize = function(input_image, input_width, input_height, factor) { | ||
const ptr0 = passArray32ToWasm(input_image); | ||
const len0 = WASM_VECTOR_LEN; | ||
const retptr = globalArgumentPtr(); | ||
wasm.resize(retptr, ptr0, len0, input_width, input_height, factor); | ||
const mem = getUint32Memory(); | ||
const rustptr = mem[retptr / 4]; | ||
const rustlen = mem[retptr / 4 + 1]; | ||
|
||
const realRet = getArrayU32FromWasm(rustptr, rustlen).slice(); | ||
wasm.__wbindgen_free(rustptr, rustlen * 4); | ||
return realRet; | ||
|
||
}; | ||
|
||
function init(module) { | ||
|
||
let result; | ||
const imports = {}; | ||
|
||
if (module instanceof URL || typeof module === 'string' || module instanceof Request) { | ||
|
||
const response = fetch(module); | ||
if (typeof WebAssembly.instantiateStreaming === 'function') { | ||
result = WebAssembly.instantiateStreaming(response, imports) | ||
.catch(e => { | ||
console.warn("`WebAssembly.instantiateStreaming` failed. Assuming this is because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); | ||
return response | ||
.then(r => r.arrayBuffer()) | ||
.then(bytes => WebAssembly.instantiate(bytes, imports)); | ||
}); | ||
} else { | ||
result = response | ||
.then(r => r.arrayBuffer()) | ||
.then(bytes => WebAssembly.instantiate(bytes, imports)); | ||
} | ||
} else { | ||
|
||
result = WebAssembly.instantiate(module, imports) | ||
.then(result => { | ||
if (result instanceof WebAssembly.Instance) { | ||
return { instance: result, module }; | ||
} else { | ||
return result; | ||
} | ||
}); | ||
} | ||
return result.then(({instance, module}) => { | ||
wasm = instance.exports; | ||
init.__wbindgen_wasm_module = module; | ||
|
||
return wasm; | ||
}); | ||
} | ||
|
||
self.wasm_bindgen = Object.assign(init, __exports); | ||
|
||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/* tslint:disable */ | ||
export const memory: WebAssembly.Memory; | ||
export function resize(a: number, b: number, c: number, d: number, e: number, f: number): void; | ||
export function __wbindgen_global_argument_ptr(): number; | ||
export function __wbindgen_malloc(a: number): number; | ||
export function __wbindgen_free(a: number, b: number): void; |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
extern crate cfg_if; | ||
extern crate hqx; | ||
extern crate wasm_bindgen; | ||
|
||
mod utils; | ||
|
||
use cfg_if::cfg_if; | ||
use wasm_bindgen::prelude::*; | ||
|
||
cfg_if! { | ||
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global | ||
// allocator. | ||
if #[cfg(feature = "wee_alloc")] { | ||
extern crate wee_alloc; | ||
#[global_allocator] | ||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; | ||
} | ||
} | ||
|
||
#[wasm_bindgen] | ||
#[no_mangle] | ||
pub fn resize( | ||
input_image: Vec<u32>, | ||
input_width: usize, | ||
input_height: usize, | ||
factor: usize, | ||
) -> Vec<u32> { | ||
let num_output_pixels = input_width * input_height * factor * factor; | ||
let mut output_image = Vec::<u32>::with_capacity(num_output_pixels * 4); | ||
output_image.resize(num_output_pixels, 0); | ||
|
||
match factor { | ||
2 => hqx::hq2x( | ||
input_image.as_slice(), | ||
output_image.as_mut_slice(), | ||
input_width, | ||
input_height, | ||
), | ||
3 => hqx::hq3x( | ||
input_image.as_slice(), | ||
output_image.as_mut_slice(), | ||
input_width, | ||
input_height, | ||
), | ||
4 => hqx::hq4x( | ||
input_image.as_slice(), | ||
output_image.as_mut_slice(), | ||
input_width, | ||
input_height, | ||
), | ||
_ => unreachable!(), | ||
}; | ||
|
||
return output_image; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
use cfg_if::cfg_if; | ||
|
||
cfg_if! { | ||
// When the `console_error_panic_hook` feature is enabled, we can call the | ||
// `set_panic_hook` function at least once during initialization, and then | ||
// we will get better error messages if our code ever panics. | ||
// | ||
// For more details see | ||
// https://github.com/rustwasm/console_error_panic_hook#readme | ||
if #[cfg(feature = "console_error_panic_hook")] { | ||
extern crate console_error_panic_hook; | ||
pub use self::console_error_panic_hook::set_once as set_panic_hook; | ||
} else { | ||
#[inline] | ||
pub fn set_panic_hook() {} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export interface HqxOptions { | ||
factor: 2 | 3 | 4; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import wasmUrl from '../../../codecs/hqx/pkg/squooshhqx_bg.wasm'; | ||
import '../../../codecs/hqx/pkg/squooshhqx'; | ||
import { HqxOptions } from './processor-meta'; | ||
|
||
interface WasmBindgenExports { | ||
resize: typeof import('../../../codecs/hqx/pkg/squooshhqx').resize; | ||
} | ||
|
||
type WasmBindgen = ((url: string) => Promise<void>) & WasmBindgenExports; | ||
|
||
declare var wasm_bindgen: WasmBindgen; | ||
|
||
const ready = wasm_bindgen(wasmUrl); | ||
|
||
export async function hqx( | ||
data: ImageData, | ||
opts: HqxOptions, | ||
): Promise<ImageData> { | ||
const input = data; | ||
await ready; | ||
const result = wasm_bindgen.resize( | ||
new Uint32Array(input.data.buffer), | ||
input.width, | ||
input.height, | ||
opts.factor, | ||
); | ||
return new ImageData( | ||
new Uint8ClampedArray(result.buffer), | ||
data.width * opts.factor, | ||
data.height * opts.factor, | ||
); | ||
} |
Oops, something went wrong.