Compare commits

..

6 Commits

Author SHA1 Message Date
Ingvar Stepanyan
e616f9feb3 Use latest wasm-opt instead of one in wasm-pack
wasm-pack auto-downloads and runs a fixed version of wasm-opt, but wasm-pack itself hasn't been maintained for a while, and so wasm-opt that comes with it is also severely outdated, leading to all sorts of hidden issues (compiler errors, broken atomics code, etc.) as well as missed optimisations.

This change disable wasm-opt feature of wasm-pack in all Rust codecs and runs the latest wasm-opt manually instead.
2021-01-20 21:50:29 +00:00
Surma
39c6be41df Merge pull request #937 from akrisrn/patch-1
Update CLI README.md
2021-01-20 12:34:42 +00:00
Surma
5603f2d6e7 Merge branch 'dev' into patch-1 2021-01-20 12:31:46 +00:00
Surma
0d72f652c5 Merge pull request #940 from GoogleChromeLabs/reproducible-mozjpeg
Make MozJPEG builds reproducible
2021-01-19 16:56:53 +00:00
Ingvar Stepanyan
7ce0c8a4fc Make MozJPEG builds reproducible
I was wondering why MozJPEG produces different Wasm binaries even when nothing is changed.

After looking at the binary diffs, I think I have figured & fixed the reason.
2021-01-19 13:21:00 +00:00
AkrISrn
5845e566da Update README.md 2021-01-16 01:24:27 +08:00
18 changed files with 114 additions and 120 deletions

View File

@@ -33,6 +33,7 @@ Options:
--resize [config] Resize the image before compressing
--quant [config] Reduce the number of colors used (aka. paletting)
--rotate [config] Rotate image
--mozjpeg [config] Use MozJPEG to generate a .jpg file with the given configuration
--webp [config] Use WebP to generate a .webp file with the given configuration
--avif [config] Use AVIF to generate a .avif file with the given configuration
--jxl [config] Use JPEG-XL to generate a .jxl file with the given configuration

View File

@@ -3,6 +3,9 @@ name = "squooshhqx"
version = "0.1.0"
authors = ["Surma <surma@surma.link>"]
[package.metadata.wasm-pack.profile.release]
wasm-opt = false
[lib]
crate-type = ["cdylib"]

54
codecs/hqx/pkg/squooshhqx.d.ts generated vendored
View File

@@ -1,48 +1,30 @@
/* tslint:disable */
/* eslint-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;
* @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;
export type InitInput =
| RequestInfo
| URL
| Response
| BufferSource
| WebAssembly.Module;
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
export interface InitOutput {
readonly memory: WebAssembly.Memory;
readonly resize: (
a: number,
b: number,
c: number,
d: number,
e: number,
f: number,
) => void;
readonly resize: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
readonly __wbindgen_malloc: (a: number) => number;
readonly __wbindgen_free: (a: number, b: number) => void;
}
/**
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
* for everything else, calls `WebAssembly.instantiate` directly.
*
* @param {InitInput | Promise<InitInput>} module_or_path
*
* @returns {Promise<InitOutput>}
*/
export default function init(
module_or_path?: InitInput | Promise<InitInput>,
): Promise<InitOutput>;
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
* for everything else, calls `WebAssembly.instantiate` directly.
*
* @param {InitInput | Promise<InitInput>} module_or_path
*
* @returns {Promise<InitOutput>}
*/
export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;

View File

@@ -1,107 +1,103 @@
let wasm;
let cachegetUint32Memory0 = null;
function getUint32Memory0() {
if (
cachegetUint32Memory0 === null ||
cachegetUint32Memory0.buffer !== wasm.memory.buffer
) {
cachegetUint32Memory0 = new Uint32Array(wasm.memory.buffer);
}
return cachegetUint32Memory0;
if (cachegetUint32Memory0 === null || cachegetUint32Memory0.buffer !== wasm.memory.buffer) {
cachegetUint32Memory0 = new Uint32Array(wasm.memory.buffer);
}
return cachegetUint32Memory0;
}
let WASM_VECTOR_LEN = 0;
function passArray32ToWasm0(arg, malloc) {
const ptr = malloc(arg.length * 4);
getUint32Memory0().set(arg, ptr / 4);
WASM_VECTOR_LEN = arg.length;
return ptr;
const ptr = malloc(arg.length * 4);
getUint32Memory0().set(arg, ptr / 4);
WASM_VECTOR_LEN = arg.length;
return ptr;
}
let cachegetInt32Memory0 = null;
function getInt32Memory0() {
if (
cachegetInt32Memory0 === null ||
cachegetInt32Memory0.buffer !== wasm.memory.buffer
) {
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
}
return cachegetInt32Memory0;
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
}
return cachegetInt32Memory0;
}
function getArrayU32FromWasm0(ptr, len) {
return getUint32Memory0().subarray(ptr / 4, ptr / 4 + len);
return getUint32Memory0().subarray(ptr / 4, ptr / 4 + len);
}
/**
* @param {Uint32Array} input_image
* @param {number} input_width
* @param {number} input_height
* @param {number} factor
* @returns {Uint32Array}
*/
* @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) {
var ptr0 = passArray32ToWasm0(input_image, wasm.__wbindgen_malloc);
var len0 = WASM_VECTOR_LEN;
wasm.resize(8, ptr0, len0, input_width, input_height, factor);
var r0 = getInt32Memory0()[8 / 4 + 0];
var r1 = getInt32Memory0()[8 / 4 + 1];
var v1 = getArrayU32FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 4);
return v1;
var ptr0 = passArray32ToWasm0(input_image, wasm.__wbindgen_malloc);
var len0 = WASM_VECTOR_LEN;
wasm.resize(8, ptr0, len0, input_width, input_height, factor);
var r0 = getInt32Memory0()[8 / 4 + 0];
var r1 = getInt32Memory0()[8 / 4 + 1];
var v1 = getArrayU32FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 4);
return v1;
}
async function load(module, imports) {
if (typeof Response === 'function' && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === 'function') {
try {
return await WebAssembly.instantiateStreaming(module, imports);
} catch (e) {
if (module.headers.get('Content-Type') != 'application/wasm') {
console.warn(
'`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n',
e,
);
} else {
throw e;
if (typeof Response === 'function' && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === 'function') {
try {
return await WebAssembly.instantiateStreaming(module, imports);
} catch (e) {
if (module.headers.get('Content-Type') != 'application/wasm') {
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
} else {
throw e;
}
}
}
}
}
const bytes = await module.arrayBuffer();
return await WebAssembly.instantiate(bytes, imports);
} else {
const instance = await WebAssembly.instantiate(module, imports);
const bytes = await module.arrayBuffer();
return await WebAssembly.instantiate(bytes, imports);
if (instance instanceof WebAssembly.Instance) {
return { instance, module };
} else {
return instance;
const instance = await WebAssembly.instantiate(module, imports);
if (instance instanceof WebAssembly.Instance) {
return { instance, module };
} else {
return instance;
}
}
}
}
async function init(input) {
if (typeof input === 'undefined') {
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
}
const imports = {};
if (typeof input === 'undefined') {
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
}
const imports = {};
if (
typeof input === 'string' ||
(typeof Request === 'function' && input instanceof Request) ||
(typeof URL === 'function' && input instanceof URL)
) {
input = fetch(input);
}
const { instance, module } = await load(await input, imports);
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
input = fetch(input);
}
wasm = instance.exports;
init.__wbindgen_wasm_module = module;
const { instance, module } = await load(await input, imports);
return wasm;
wasm = instance.exports;
init.__wbindgen_wasm_module = module;
return wasm;
}
export default init;

Binary file not shown.

View File

@@ -46,7 +46,10 @@ $(CODEC_DIR)/Makefile: $(CODEC_DIR)/configure
--without-turbojpeg \
--without-simd \
--without-arith-enc \
--without-arith-dec
--without-arith-dec \
--with-build-date=squoosh
# ^ If not provided with a dummy value, MozJPEG includes a build date in the
# binary as part of the version string, making binaries different each time.
$(CODEC_DIR)/configure: $(CODEC_DIR)/configure.ac
cd $(CODEC_DIR) && autoreconf -iv

Binary file not shown.

View File

@@ -6,7 +6,7 @@ edition = "2018"
publish = false
[package.metadata.wasm-pack.profile.release]
wasm-opt = ["-O", "--no-validation"]
wasm-opt = false
[lib]
crate-type = ["cdylib"]

View File

@@ -4,8 +4,12 @@ set -e
rm -rf pkg,{-parallel}
export CFLAGS="${CFLAGS} -DUNALIGNED_ACCESS_IS_FAST=1"
wasm-pack build -t web
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory' wasm-pack build -t web -d pkg-parallel -- -Z build-std=panic_abort,std --features=parallel
wasm-pack build -t web -- --locked
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory' wasm-pack build -t web -d pkg-parallel -- -Z build-std=panic_abort,std --features=parallel --locked
# Workaround https://github.com/rustwasm/wasm-bindgen/issues/2133:
sed -i "s|maybe_memory:|maybe_memory?:|" pkg-parallel/squoosh_oxipng.d.ts
# Workaround wasm-pack using a very old wasm-opt.
echo "Optimizing wasm binaries with \`wasm-opt\`..."
wasm-opt -O pkg/squoosh_oxipng_bg.wasm -o pkg/squoosh_oxipng_bg.wasm
wasm-opt -O pkg-parallel/squoosh_oxipng_bg.wasm -o pkg-parallel/squoosh_oxipng_bg.wasm
rm pkg{,-parallel}/.gitignore

View File

@@ -6,7 +6,7 @@ edition = "2018"
publish = false
[package.metadata.wasm-pack.profile.release]
wasm-opt = ["-O", "--no-validation"]
wasm-opt = false
[lib]
crate-type = ["cdylib"]

Binary file not shown.

View File

@@ -4,8 +4,10 @@ version = "0.1.0"
authors = ["Surma <surma@surma.link>"]
publish = false
[package.metadata.wasm-pack.profile.release]
wasm-opt = false
[lib]
#crate-type = ["cdylib", "rlib"]
crate-type = ["cdylib"]
[features]
@@ -25,8 +27,6 @@ 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]

View File

@@ -16,4 +16,11 @@ COPY --from=wasm-tools /opt/wasm-tools/wasm-pack /usr/local/cargo/bin/
ENV CPATH="/wasm32/include"
WORKDIR /src
CMD ["sh", "-c", "rm -rf pkg && wasm-pack build --target web -- --verbose --locked && rm pkg/.gitignore"]
CMD ["sh", "-c", "\
rm -rf pkg && \
wasm-pack build --target web -- --locked && \
echo 'Optimising binaries...' && \
wasm-opt -O --enable-mutable-globals pkg/*.wasm -o pkg/*.wasm && \
rm pkg/.gitignore && \
echo Done \
"]

View File

@@ -58,11 +58,9 @@ for (const methodName of methodNames) {
signal.removeEventListener('abort', onAbort);
// Start a timer to clear up the worker.
if (__PRODUCTION__) {
this._workerTimeout = setTimeout(() => {
this._terminateWorker();
}, workerTimeout);
}
this._workerTimeout = setTimeout(() => {
this._terminateWorker();
}, workerTimeout);
});
});