Compare commits
88 Commits
hqx-fix
...
lighthouse
Author | SHA1 | Date | |
---|---|---|---|
ce8c2eb20e | |||
42ae3451be | |||
1e3ad773d9 | |||
4a01d0d548 | |||
4a9c28f89f | |||
3aed873467 | |||
2b7f059b8f | |||
33726e9c68 | |||
3d29f486e7 | |||
79e8a26f06 | |||
e8efd54766 | |||
edcc774c16 | |||
746b33a590 | |||
8a264efc67 | |||
f0af6e97a0 | |||
043107c101 | |||
e9e3b923e0 | |||
aea6e91b1d | |||
9c4717a13d | |||
559cabce9e | |||
7f6a3de7ca | |||
f3adc87f52 | |||
6499e9f63d | |||
ac1f104e49 | |||
87f89e6b2f | |||
7f6404d5a8 | |||
8e857cd393 | |||
b8f801333d | |||
499956e216 | |||
3932ee2c00 | |||
68177b7590 | |||
0a2a4122dc | |||
e6299569d0 | |||
578ad8c291 | |||
eaa294b689 | |||
6e97cfb8d5 | |||
80a68c48b2 | |||
98865f8141 | |||
78da9fd144 | |||
94c50a989b | |||
3e525e767c | |||
dfcc1e24e4 | |||
f3aa8edfca | |||
ffd7ee6013 | |||
64bb09dbc5 | |||
35fcbc40ed | |||
1b55a48680 | |||
88fbb19d29 | |||
3dc1501ff7 | |||
b7576c559a | |||
69ed2e1d56 | |||
55f7f3d72a | |||
055d0b4ea1 | |||
7735346ed0 | |||
2a06fdbbe0 | |||
19169199e9 | |||
76f3c39b78 | |||
8da52acc4c | |||
9253522a3a | |||
cf39a3e5a5 | |||
a08877f0ac | |||
2f0dc1c067 | |||
535d8c9142 | |||
6dc2ba3bef | |||
93cfdc8f98 | |||
671544349e | |||
d3c1939692 | |||
99642aef96 | |||
ac4942b640 | |||
23cb004a86 | |||
4b6de60978 | |||
de204aa56a | |||
976f811b36 | |||
855fc9e602 | |||
a8848e717c | |||
90b99faf8b | |||
d3cfffbbcf | |||
fade7f9be8 | |||
b10dd055d3 | |||
7532f01222 | |||
2df09efdee | |||
bed4f49a12 | |||
2b7fefff8b | |||
bdcf2519ce | |||
3f8afb72a6 | |||
2f834db224 | |||
3541ce7492 | |||
b6fae0eb4c |
10
.travis.yml
10
.travis.yml
@ -1,4 +1,12 @@
|
||||
sudo: required
|
||||
dist: xenial
|
||||
language: node_js
|
||||
node_js:
|
||||
- '10'
|
||||
addons:
|
||||
chrome: stable
|
||||
cache: npm
|
||||
script: npm run build
|
||||
script:
|
||||
- npm run build
|
||||
- ./run_lighthouse.sh
|
||||
after_success: npm run sizereport
|
||||
|
@ -1,18 +1,12 @@
|
||||
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
|
||||
RUN rustup target add wasm32-unknown-unknown
|
||||
RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||
|
||||
COPY --from=0 /opt/wabt /opt/wabt
|
||||
ENV PATH="/opt/wabt/bin:${PATH}"
|
||||
RUN mkdir /opt/binaryen && \
|
||||
curl -L https://github.com/WebAssembly/binaryen/releases/download/1.38.32/binaryen-1.38.32-x86-linux.tar.gz | tar -xzf - -C /opt/binaryen --strip 1
|
||||
|
||||
RUN mkdir /opt/wabt && \
|
||||
curl -L https://github.com/WebAssembly/wabt/releases/download/1.0.11/wabt-1.0.11-linux.tar.gz | tar -xzf - -C /opt/wabt --strip 1
|
||||
|
||||
ENV PATH="/opt/binaryen:/opt/wabt:${PATH}"
|
||||
WORKDIR /src
|
||||
|
@ -6,9 +6,11 @@ echo "============================================="
|
||||
echo "Compiling wasm"
|
||||
echo "============================================="
|
||||
(
|
||||
rustup run nightly \
|
||||
wasm-pack build --target no-modules
|
||||
wasm-pack build
|
||||
wasm-strip pkg/squooshhqx_bg.wasm
|
||||
echo "Optimising Wasm so it doesn't break Chrome (this takes like 10-15mins. get a cup of tea)"
|
||||
echo "Once https://crbug.com/974804 is fixed, we can remove this step"
|
||||
wasm-opt -Os --no-validation -o pkg/squooshhqx_bg.wasm pkg/squooshhqx_bg.wasm
|
||||
rm pkg/.gitignore
|
||||
)
|
||||
echo "============================================="
|
||||
|
@ -1,24 +0,0 @@
|
||||
<!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>
|
@ -9,6 +9,7 @@
|
||||
"squooshhqx.js",
|
||||
"squooshhqx.d.ts"
|
||||
],
|
||||
"browser": "squooshhqx.js",
|
||||
"types": "squooshhqx.d.ts"
|
||||
"module": "squooshhqx.js",
|
||||
"types": "squooshhqx.d.ts",
|
||||
"sideEffects": "false"
|
||||
}
|
11
codecs/hqx/pkg/squooshhqx.d.ts
vendored
11
codecs/hqx/pkg/squooshhqx.d.ts
vendored
@ -7,14 +7,3 @@
|
||||
* @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>;
|
||||
|
@ -1,97 +1,46 @@
|
||||
(function() {
|
||||
const __exports = {};
|
||||
let wasm;
|
||||
import * as wasm from './squooshhqx_bg.wasm';
|
||||
|
||||
let cachegetUint32Memory = null;
|
||||
function getUint32Memory() {
|
||||
if (cachegetUint32Memory === null || cachegetUint32Memory.buffer !== wasm.memory.buffer) {
|
||||
cachegetUint32Memory = new Uint32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetUint32Memory;
|
||||
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;
|
||||
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 passArray32ToWasm(arg) {
|
||||
const ptr = wasm.__wbindgen_malloc(arg.length * 4);
|
||||
getUint32Memory().set(arg, ptr / 4);
|
||||
WASM_VECTOR_LEN = arg.length;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let cachegetInt32Memory = null;
|
||||
function getInt32Memory() {
|
||||
if (cachegetInt32Memory === null || cachegetInt32Memory.buffer !== wasm.memory.buffer) {
|
||||
cachegetInt32Memory = new Int32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetInt32Memory;
|
||||
}
|
||||
|
||||
function getArrayU32FromWasm(ptr, len) {
|
||||
return getUint32Memory().subarray(ptr / 4, ptr / 4 + len);
|
||||
}
|
||||
function getArrayU32FromWasm(ptr, len) {
|
||||
return getUint32Memory().subarray(ptr / 4, ptr / 4 + len);
|
||||
}
|
||||
/**
|
||||
* @param {Uint32Array} input_image
|
||||
* @param {number} input_width
|
||||
* @param {number} input_height
|
||||
* @param {number} factor
|
||||
* @returns {Uint32Array}
|
||||
*/
|
||||
export function resize(input_image, input_width, input_height, factor) {
|
||||
const retptr = 8;
|
||||
const ret = wasm.resize(retptr, passArray32ToWasm(input_image), WASM_VECTOR_LEN, input_width, input_height, factor);
|
||||
const memi32 = getInt32Memory();
|
||||
const v0 = getArrayU32FromWasm(memi32[retptr / 4 + 0], memi32[retptr / 4 + 1]).slice();
|
||||
wasm.__wbindgen_free(memi32[retptr / 4 + 0], memi32[retptr / 4 + 1] * 4);
|
||||
return v0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
})();
|
||||
|
3
codecs/hqx/pkg/squooshhqx_bg.d.ts
vendored
3
codecs/hqx/pkg/squooshhqx_bg.d.ts
vendored
@ -1,6 +1,5 @@
|
||||
/* 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;
|
||||
export function resize(a: number, b: number, c: number, d: number, e: number, f: number): void;
|
||||
|
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "squooshresize"
|
||||
name = "resize"
|
||||
version = "0.1.0"
|
||||
authors = ["Surma <surma@surma.link>"]
|
||||
|
||||
|
@ -1,18 +1,9 @@
|
||||
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
|
||||
RUN rustup target add wasm32-unknown-unknown
|
||||
RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||
|
||||
COPY --from=0 /opt/wabt /opt/wabt
|
||||
ENV PATH="/opt/wabt/bin:${PATH}"
|
||||
RUN mkdir /opt/wabt && \
|
||||
curl -L https://github.com/WebAssembly/wabt/releases/download/1.0.11/wabt-1.0.11-linux.tar.gz | tar -xzf - -C /opt/wabt --strip 1
|
||||
|
||||
ENV PATH="/opt/wabt:${PATH}"
|
||||
WORKDIR /src
|
||||
|
@ -1,53 +0,0 @@
|
||||
// THIS IS NOT A NODE SCRIPT
|
||||
// This is a d8 script. Please install jsvu[1] and install v8.
|
||||
// Then run `npm run --silent benchmark`.
|
||||
// [1]: https://github.com/GoogleChromeLabs/jsvu
|
||||
|
||||
self = global = this;
|
||||
load("./pkg/resize.js");
|
||||
|
||||
async function init() {
|
||||
// Adjustable constants.
|
||||
const inputDimensions = 2000;
|
||||
const outputDimensions = 1500;
|
||||
const algorithm = 3; // Lanczos
|
||||
const iterations = new Array(100);
|
||||
|
||||
// Constants. Don’t change.
|
||||
const imageByteSize = inputDimensions * inputDimensions * 4;
|
||||
const imageBuffer = new Uint8ClampedArray(imageByteSize);
|
||||
|
||||
const module = await WebAssembly.compile(readbuffer("./pkg/resize_bg.wasm"));
|
||||
await wasm_bindgen(module);
|
||||
[[false, false], [true, false], [false, true], [true, true]].forEach(
|
||||
opts => {
|
||||
print(`\npremultiplication: ${opts[0]}`);
|
||||
print(`color space conversion: ${opts[1]}`);
|
||||
print(`==============================`);
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const start = Date.now();
|
||||
wasm_bindgen.resize(
|
||||
imageBuffer,
|
||||
inputDimensions,
|
||||
inputDimensions,
|
||||
outputDimensions,
|
||||
outputDimensions,
|
||||
algorithm,
|
||||
...opts
|
||||
);
|
||||
iterations[i] = Date.now() - start;
|
||||
}
|
||||
const average =
|
||||
iterations.reduce((sum, c) => sum + c) / iterations.length;
|
||||
const stddev = Math.sqrt(
|
||||
iterations
|
||||
.map(i => Math.pow(i - average, 2))
|
||||
.reduce((sum, c) => sum + c) / iterations.length
|
||||
);
|
||||
print(`n = ${iterations.length}`);
|
||||
print(`Average: ${average}`);
|
||||
print(`StdDev: ${stddev}`);
|
||||
}
|
||||
);
|
||||
}
|
||||
init().catch(e => console.error(e, e.stack));
|
@ -6,9 +6,9 @@ echo "============================================="
|
||||
echo "Compiling wasm"
|
||||
echo "============================================="
|
||||
(
|
||||
rustup run nightly \
|
||||
wasm-pack build --target no-modules
|
||||
wasm-pack build
|
||||
wasm-strip pkg/resize_bg.wasm
|
||||
rm pkg/.gitignore
|
||||
)
|
||||
echo "============================================="
|
||||
echo "Compiling wasm done"
|
||||
|
@ -2,7 +2,6 @@
|
||||
"name": "resize",
|
||||
"scripts": {
|
||||
"build:image": "docker build -t squoosh-resize .",
|
||||
"build": "docker run --rm -v $(pwd):/src squoosh-resize ./build.sh",
|
||||
"benchmark": "v8 --no-liftoff --no-wasm-tier-up ./benchmark.js"
|
||||
"build": "docker run --rm -v $(pwd):/src squoosh-resize ./build.sh"
|
||||
}
|
||||
}
|
||||
|
15
codecs/resize/pkg/package.json
Normal file
15
codecs/resize/pkg/package.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "resize",
|
||||
"collaborators": [
|
||||
"Surma <surma@surma.link>"
|
||||
],
|
||||
"version": "0.1.0",
|
||||
"files": [
|
||||
"resize_bg.wasm",
|
||||
"resize.js",
|
||||
"resize.d.ts"
|
||||
],
|
||||
"module": "resize.js",
|
||||
"types": "resize.d.ts",
|
||||
"sideEffects": "false"
|
||||
}
|
18
codecs/resize/pkg/resize.d.ts
vendored
18
codecs/resize/pkg/resize.d.ts
vendored
@ -1,13 +1,13 @@
|
||||
/* tslint:disable */
|
||||
/**
|
||||
* @param {Uint8Array} arg0
|
||||
* @param {number} arg1
|
||||
* @param {number} arg2
|
||||
* @param {number} arg3
|
||||
* @param {number} arg4
|
||||
* @param {number} arg5
|
||||
* @param {boolean} arg6
|
||||
* @param {boolean} arg7
|
||||
* @param {Uint8Array} input_image
|
||||
* @param {number} input_width
|
||||
* @param {number} input_height
|
||||
* @param {number} output_width
|
||||
* @param {number} output_height
|
||||
* @param {number} typ_idx
|
||||
* @param {boolean} premultiply
|
||||
* @param {boolean} color_space_conversion
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function resize(arg0: Uint8Array, arg1: number, arg2: number, arg3: number, arg4: number, arg5: number, arg6: boolean, arg7: boolean): Uint8Array;
|
||||
export function resize(input_image: Uint8Array, input_width: number, input_height: number, output_width: number, output_height: number, typ_idx: number, premultiply: boolean, color_space_conversion: boolean): Uint8Array;
|
||||
|
@ -1,114 +1,50 @@
|
||||
(function() {
|
||||
var wasm;
|
||||
const __exports = {};
|
||||
import * as wasm from './resize_bg.wasm';
|
||||
|
||||
|
||||
let cachegetUint8Memory = null;
|
||||
function getUint8Memory() {
|
||||
if (cachegetUint8Memory === null || cachegetUint8Memory.buffer !== wasm.memory.buffer) {
|
||||
cachegetUint8Memory = new Uint8Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetUint8Memory;
|
||||
let cachegetUint8Memory = null;
|
||||
function getUint8Memory() {
|
||||
if (cachegetUint8Memory === null || cachegetUint8Memory.buffer !== wasm.memory.buffer) {
|
||||
cachegetUint8Memory = new Uint8Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetUint8Memory;
|
||||
}
|
||||
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
|
||||
function passArray8ToWasm(arg) {
|
||||
const ptr = wasm.__wbindgen_malloc(arg.length * 1);
|
||||
getUint8Memory().set(arg, ptr / 1);
|
||||
WASM_VECTOR_LEN = arg.length;
|
||||
return ptr;
|
||||
function passArray8ToWasm(arg) {
|
||||
const ptr = wasm.__wbindgen_malloc(arg.length * 1);
|
||||
getUint8Memory().set(arg, ptr / 1);
|
||||
WASM_VECTOR_LEN = arg.length;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let cachegetInt32Memory = null;
|
||||
function getInt32Memory() {
|
||||
if (cachegetInt32Memory === null || cachegetInt32Memory.buffer !== wasm.memory.buffer) {
|
||||
cachegetInt32Memory = new Int32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetInt32Memory;
|
||||
}
|
||||
|
||||
function getArrayU8FromWasm(ptr, len) {
|
||||
return getUint8Memory().subarray(ptr / 1, ptr / 1 + len);
|
||||
}
|
||||
function getArrayU8FromWasm(ptr, len) {
|
||||
return getUint8Memory().subarray(ptr / 1, ptr / 1 + len);
|
||||
}
|
||||
/**
|
||||
* @param {Uint8Array} input_image
|
||||
* @param {number} input_width
|
||||
* @param {number} input_height
|
||||
* @param {number} output_width
|
||||
* @param {number} output_height
|
||||
* @param {number} typ_idx
|
||||
* @param {boolean} premultiply
|
||||
* @param {boolean} color_space_conversion
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function resize(input_image, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion) {
|
||||
const retptr = 8;
|
||||
const ret = wasm.resize(retptr, passArray8ToWasm(input_image), WASM_VECTOR_LEN, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion);
|
||||
const memi32 = getInt32Memory();
|
||||
const v0 = getArrayU8FromWasm(memi32[retptr / 4 + 0], memi32[retptr / 4 + 1]).slice();
|
||||
wasm.__wbindgen_free(memi32[retptr / 4 + 0], memi32[retptr / 4 + 1] * 1);
|
||||
return v0;
|
||||
}
|
||||
|
||||
let cachedGlobalArgumentPtr = null;
|
||||
function globalArgumentPtr() {
|
||||
if (cachedGlobalArgumentPtr === null) {
|
||||
cachedGlobalArgumentPtr = wasm.__wbindgen_global_argument_ptr();
|
||||
}
|
||||
return cachedGlobalArgumentPtr;
|
||||
}
|
||||
|
||||
let cachegetUint32Memory = null;
|
||||
function getUint32Memory() {
|
||||
if (cachegetUint32Memory === null || cachegetUint32Memory.buffer !== wasm.memory.buffer) {
|
||||
cachegetUint32Memory = new Uint32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetUint32Memory;
|
||||
}
|
||||
/**
|
||||
* @param {Uint8Array} arg0
|
||||
* @param {number} arg1
|
||||
* @param {number} arg2
|
||||
* @param {number} arg3
|
||||
* @param {number} arg4
|
||||
* @param {number} arg5
|
||||
* @param {boolean} arg6
|
||||
* @param {boolean} arg7
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
__exports.resize = function(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
|
||||
const ptr0 = passArray8ToWasm(arg0);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
const retptr = globalArgumentPtr();
|
||||
wasm.resize(retptr, ptr0, len0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
const mem = getUint32Memory();
|
||||
const rustptr = mem[retptr / 4];
|
||||
const rustlen = mem[retptr / 4 + 1];
|
||||
|
||||
const realRet = getArrayU8FromWasm(rustptr, rustlen).slice();
|
||||
wasm.__wbindgen_free(rustptr, rustlen * 1);
|
||||
return realRet;
|
||||
|
||||
};
|
||||
|
||||
const heap = new Array(32);
|
||||
|
||||
heap.fill(undefined);
|
||||
|
||||
heap.push(undefined, null, true, false);
|
||||
|
||||
let heap_next = heap.length;
|
||||
|
||||
function dropObject(idx) {
|
||||
if (idx < 36) return;
|
||||
heap[idx] = heap_next;
|
||||
heap_next = idx;
|
||||
}
|
||||
|
||||
__exports.__wbindgen_object_drop_ref = function(i) { dropObject(i); };
|
||||
|
||||
function init(path_or_module) {
|
||||
let instantiation;
|
||||
const imports = { './resize': __exports };
|
||||
if (path_or_module instanceof WebAssembly.Module) {
|
||||
instantiation = WebAssembly.instantiate(path_or_module, imports)
|
||||
.then(instance => {
|
||||
return { instance, module: path_or_module }
|
||||
});
|
||||
} else {
|
||||
const data = fetch(path_or_module);
|
||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
instantiation = WebAssembly.instantiateStreaming(data, 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 data
|
||||
.then(r => r.arrayBuffer())
|
||||
.then(bytes => WebAssembly.instantiate(bytes, imports));
|
||||
});
|
||||
} else {
|
||||
instantiation = data
|
||||
.then(response => response.arrayBuffer())
|
||||
.then(buffer => WebAssembly.instantiate(buffer, imports));
|
||||
}
|
||||
}
|
||||
return instantiation.then(({instance}) => {
|
||||
wasm = init.wasm = instance.exports;
|
||||
|
||||
});
|
||||
};
|
||||
self.wasm_bindgen = Object.assign(init, __exports);
|
||||
})();
|
||||
|
1
codecs/resize/pkg/resize_bg.d.ts
vendored
1
codecs/resize/pkg/resize_bg.d.ts
vendored
@ -1,6 +1,5 @@
|
||||
/* tslint:disable */
|
||||
export const memory: WebAssembly.Memory;
|
||||
export function __wbindgen_global_argument_ptr(): number;
|
||||
export function __wbindgen_malloc(a: number): number;
|
||||
export function __wbindgen_free(a: number, b: number): void;
|
||||
export function resize(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number): void;
|
||||
|
Binary file not shown.
@ -1,17 +1,8 @@
|
||||
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
|
||||
RUN rustup target add wasm32-unknown-unknown
|
||||
|
||||
COPY --from=0 /opt/wabt /opt/wabt
|
||||
ENV PATH="/opt/wabt/bin:${PATH}"
|
||||
RUN mkdir /opt/wabt && \
|
||||
curl -L https://github.com/WebAssembly/wabt/releases/download/1.0.11/wabt-1.0.11-linux.tar.gz | tar -xzf - -C /opt/wabt --strip 1
|
||||
|
||||
ENV PATH="/opt/wabt:${PATH}"
|
||||
WORKDIR /src
|
||||
|
@ -6,8 +6,7 @@ echo "============================================="
|
||||
echo "Compiling wasm"
|
||||
echo "============================================="
|
||||
(
|
||||
rustup run nightly \
|
||||
cargo build \
|
||||
cargo build \
|
||||
--target wasm32-unknown-unknown \
|
||||
--release
|
||||
cp target/wasm32-unknown-unknown/release/rotate.wasm .
|
||||
|
Binary file not shown.
1517
package-lock.json
generated
1517
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
42
package.json
42
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "squoosh",
|
||||
"version": "1.8.0",
|
||||
"version": "1.8.1",
|
||||
"license": "apache-2.0",
|
||||
"scripts": {
|
||||
"start": "webpack-dev-server --host 0.0.0.0 --hot",
|
||||
@ -16,32 +16,32 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "10.14.9",
|
||||
"@types/node": "10.14.15",
|
||||
"@types/pretty-bytes": "5.1.0",
|
||||
"@types/webassembly-js-api": "0.0.3",
|
||||
"@webcomponents/custom-elements": "1.2.4",
|
||||
"@webpack-cli/serve": "0.1.8",
|
||||
"assets-webpack-plugin": "3.9.10",
|
||||
"chalk": "2.4.2",
|
||||
"chokidar": "3.0.1",
|
||||
"chokidar": "3.0.2",
|
||||
"classnames": "2.2.6",
|
||||
"clean-webpack-plugin": "1.0.1",
|
||||
"comlink": "3.1.1",
|
||||
"copy-webpack-plugin": "5.0.3",
|
||||
"critters-webpack-plugin": "2.3.0",
|
||||
"copy-webpack-plugin": "5.0.4",
|
||||
"critters-webpack-plugin": "2.4.0",
|
||||
"css-loader": "1.0.1",
|
||||
"ejs": "2.6.2",
|
||||
"escape-string-regexp": "2.0.0",
|
||||
"exports-loader": "0.7.0",
|
||||
"file-drop-element": "0.2.0",
|
||||
"file-loader": "4.0.0",
|
||||
"file-loader": "4.2.0",
|
||||
"gzip-size": "5.1.1",
|
||||
"html-webpack-plugin": "3.2.0",
|
||||
"husky": "2.4.1",
|
||||
"husky": "3.0.4",
|
||||
"idb-keyval": "3.2.0",
|
||||
"linkstate": "1.1.1",
|
||||
"loader-utils": "1.2.3",
|
||||
"mini-css-extract-plugin": "0.7.0",
|
||||
"mini-css-extract-plugin": "0.8.0",
|
||||
"minimatch": "3.0.4",
|
||||
"node-fetch": "2.6.0",
|
||||
"node-sass": "4.12.0",
|
||||
@ -49,28 +49,28 @@
|
||||
"pointer-tracker": "2.0.3",
|
||||
"preact": "8.4.2",
|
||||
"prerender-loader": "1.3.0",
|
||||
"pretty-bytes": "5.2.0",
|
||||
"pretty-bytes": "5.3.0",
|
||||
"progress-bar-webpack-plugin": "1.12.1",
|
||||
"raw-loader": "3.0.0",
|
||||
"readdirp": "3.0.2",
|
||||
"sass-loader": "7.1.0",
|
||||
"script-ext-html-webpack-plugin": "2.1.3",
|
||||
"raw-loader": "3.1.0",
|
||||
"readdirp": "3.1.2",
|
||||
"sass-loader": "7.3.1",
|
||||
"script-ext-html-webpack-plugin": "2.1.4",
|
||||
"source-map-loader": "0.2.4",
|
||||
"style-loader": "0.23.1",
|
||||
"terser-webpack-plugin": "1.3.0",
|
||||
"travis-size-report": "1.0.1",
|
||||
"style-loader": "1.0.0",
|
||||
"terser-webpack-plugin": "1.4.1",
|
||||
"travis-size-report": "1.1.0",
|
||||
"ts-loader": "6.0.3",
|
||||
"tslint": "5.17.0",
|
||||
"tslint": "5.19.0",
|
||||
"tslint-config-airbnb": "5.11.1",
|
||||
"tslint-config-semistandard": "8.0.1",
|
||||
"tslint-react": "4.0.0",
|
||||
"typed-css-modules": "0.4.2",
|
||||
"typescript": "3.5.2",
|
||||
"url-loader": "2.0.0",
|
||||
"typescript": "3.5.3",
|
||||
"url-loader": "2.1.0",
|
||||
"webpack": "4.28.0",
|
||||
"webpack-bundle-analyzer": "3.3.2",
|
||||
"webpack-bundle-analyzer": "3.4.1",
|
||||
"webpack-cli": "3.3.4",
|
||||
"webpack-dev-server": "3.7.1",
|
||||
"webpack-dev-server": "3.8.0",
|
||||
"worker-plugin": "3.1.0"
|
||||
}
|
||||
}
|
||||
|
13
run_lighthouse.sh
Executable file
13
run_lighthouse.sh
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
npx http-server -c0 -p 9000 build &
|
||||
|
||||
npm install -g @lhci/cli@next
|
||||
|
||||
lhci collect --url=http://localhost:9000/
|
||||
|
||||
lhci assert --preset="lighthouse:recommended"
|
||||
|
||||
EXIT_CODE=$?
|
||||
kill $!
|
||||
exit $EXIT_CODE
|
@ -1,24 +1,12 @@
|
||||
import wasmUrl from '../../../codecs/hqx/pkg/squooshhqx_bg.wasm';
|
||||
import '../../../codecs/hqx/pkg/squooshhqx';
|
||||
import { resize } from '../../../codecs/hqx/pkg';
|
||||
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(
|
||||
const result = resize(
|
||||
new Uint32Array(input.data.buffer),
|
||||
input.width,
|
||||
input.height,
|
||||
|
@ -24,19 +24,6 @@ interface State {
|
||||
|
||||
const sizePresets = [0.25, 0.3333, 0.5, 1, 2, 3, 4];
|
||||
|
||||
/**
|
||||
* Should we allow the user to select hqx? Chrome currently has a wasm bug, so we currently avoid it
|
||||
* there, unless overridden.
|
||||
* crbug.com/974804
|
||||
*/
|
||||
const allowHqx: boolean = (() => {
|
||||
const url = new URL(location.href);
|
||||
return url.searchParams.has('allow-hqx')
|
||||
// Yep. UA sniffing. Let's hope we can remove this soon.
|
||||
// Block browsers with Chrome/, unless they also have Edge/ (since the Edge UA includes Chrome/)
|
||||
|| !navigator.userAgent.includes('Chrome/') || navigator.userAgent.includes('Edge/');
|
||||
})();
|
||||
|
||||
export default class ResizerOptions extends Component<Props, State> {
|
||||
state: State = {
|
||||
maintainAspect: true,
|
||||
@ -163,7 +150,7 @@ export default class ResizerOptions extends Component<Props, State> {
|
||||
<option value="mitchell">Mitchell</option>
|
||||
<option value="catrom">Catmull-Rom</option>
|
||||
<option value="triangle">Triangle (bilinear)</option>
|
||||
{allowHqx && <option value="hqx">hqx (pixel art)</option>}
|
||||
<option value="hqx">hqx (pixel art)</option>
|
||||
<option value="browser-pixelated">Browser pixelated</option>
|
||||
<option value="browser-low">Browser low quality</option>
|
||||
<option value="browser-medium">Browser medium quality</option>
|
||||
|
@ -1,17 +1,6 @@
|
||||
import wasmUrl from '../../../codecs/resize/pkg/resize_bg.wasm';
|
||||
import '../../../codecs/resize/pkg/resize';
|
||||
import { WorkerResizeOptions } from './processor-meta';
|
||||
import { getContainOffsets } from './util';
|
||||
|
||||
interface WasmBindgenExports {
|
||||
resize: typeof import('../../../codecs/resize/pkg/resize').resize;
|
||||
}
|
||||
|
||||
type WasmBindgen = ((url: string) => Promise<void>) & WasmBindgenExports;
|
||||
|
||||
declare var wasm_bindgen: WasmBindgen;
|
||||
|
||||
const ready = wasm_bindgen(wasmUrl);
|
||||
import { resize as codecResize } from '../../../codecs/resize/pkg';
|
||||
|
||||
function crop(data: ImageData, sx: number, sy: number, sw: number, sh: number): ImageData {
|
||||
const inputPixels = new Uint32Array(data.data.buffer);
|
||||
@ -41,9 +30,7 @@ export async function resize(data: ImageData, opts: WorkerResizeOptions): Promis
|
||||
input = crop(input, Math.round(sx), Math.round(sy), Math.round(sw), Math.round(sh));
|
||||
}
|
||||
|
||||
await ready;
|
||||
|
||||
const result = wasm_bindgen.resize(
|
||||
const result = codecResize(
|
||||
new Uint8Array(input.data.buffer), input.width, input.height, opts.width, opts.height,
|
||||
resizeMethods.indexOf(opts.method), opts.premultiply, opts.linearRGB,
|
||||
);
|
||||
|
@ -1,4 +1,3 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const CleanPlugin = require('clean-webpack-plugin');
|
||||
@ -17,11 +16,7 @@ const CrittersPlugin = require('critters-webpack-plugin');
|
||||
const AssetTemplatePlugin = require('./config/asset-template-plugin');
|
||||
const addCssTypes = require('./config/add-css-types');
|
||||
|
||||
function readJson (filename) {
|
||||
return JSON.parse(fs.readFileSync(filename));
|
||||
}
|
||||
|
||||
const VERSION = readJson('./package.json').version;
|
||||
const VERSION = require('./package.json').version;
|
||||
|
||||
module.exports = async function (_, env) {
|
||||
const isProd = env.mode === 'production';
|
||||
@ -147,11 +142,14 @@ module.exports = async function (_, env) {
|
||||
},
|
||||
{
|
||||
// All the codec files define a global with the same name as their file name. `exports-loader` attaches those to `module.exports`.
|
||||
test: /\/codecs\/.*\.js$/,
|
||||
test: /\.js$/,
|
||||
include: path.join(__dirname, 'src/codecs'),
|
||||
loader: 'exports-loader'
|
||||
},
|
||||
{
|
||||
test: /\/codecs\/.*\.wasm$/,
|
||||
// Emscripten modules don't work with Webpack's Wasm loader.
|
||||
test: /\.wasm$/,
|
||||
exclude: /_bg\.wasm$/,
|
||||
// This is needed to make webpack NOT process wasm files.
|
||||
// See https://github.com/webpack/webpack/issues/6725
|
||||
type: 'javascript/auto',
|
||||
@ -160,6 +158,11 @@ module.exports = async function (_, env) {
|
||||
name: '[name].[hash:5].[ext]',
|
||||
},
|
||||
},
|
||||
{
|
||||
// Wasm modules generated by Rust + wasm-pack work great with Webpack.
|
||||
test: /_bg\.wasm$/,
|
||||
type: 'webassembly/experimental',
|
||||
},
|
||||
{
|
||||
test: /\.(png|svg|jpg|gif)$/,
|
||||
loader: 'file-loader',
|
||||
@ -172,7 +175,7 @@ module.exports = async function (_, env) {
|
||||
plugins: [
|
||||
new webpack.IgnorePlugin(
|
||||
/(fs|crypto|path)/,
|
||||
new RegExp(`${path.sep}codecs${path.sep}`)
|
||||
/[/\\]codecs[/\\]/
|
||||
),
|
||||
|
||||
// Pretty progressbar showing build progress:
|
||||
@ -239,7 +242,7 @@ module.exports = async function (_, env) {
|
||||
removeRedundantAttributes: true,
|
||||
removeComments: true
|
||||
},
|
||||
manifest: readJson('./src/manifest.json'),
|
||||
manifest: require('./src/manifest.json'),
|
||||
inject: 'body',
|
||||
compile: true
|
||||
}),
|
||||
|
Reference in New Issue
Block a user