mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-12 16:57:26 +00:00
Compare commits
60 Commits
cli-invoc
...
rollup-bui
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7346511fa1 | ||
|
|
39ca054112 | ||
|
|
1b80dd23ee | ||
|
|
d1ee92e884 | ||
|
|
f1da577ba3 | ||
|
|
52b3d0063f | ||
|
|
eb9d0d186c | ||
|
|
964390501e | ||
|
|
b412d4c2a5 | ||
|
|
7dfc9310ba | ||
|
|
b38069695a | ||
|
|
2d21406484 | ||
|
|
56f9d4b8c8 | ||
|
|
be4601b93a | ||
|
|
196e6e1aea | ||
|
|
6d0d9dc022 | ||
|
|
324c2b6cab | ||
|
|
b6fd14b6d3 | ||
|
|
9111aa89ae | ||
|
|
c17b5c36c6 | ||
|
|
4502abb069 | ||
|
|
5a027c7727 | ||
|
|
4da1887826 | ||
|
|
b1a639c182 | ||
|
|
6dbb182f7b | ||
|
|
a360191759 | ||
|
|
1cb1c16fa2 | ||
|
|
ec586bb529 | ||
|
|
4b8c0178fe | ||
|
|
0d298e3e0a | ||
|
|
13c5b76af6 | ||
|
|
7836d7e97c | ||
|
|
db2d6f4ca6 | ||
|
|
b11ae0b8c7 | ||
|
|
81d0b38dbd | ||
|
|
b47d6b4696 | ||
|
|
f96ae9bdee | ||
|
|
4d8efcea66 | ||
|
|
e11b4cf22c | ||
|
|
3f2466f44d | ||
|
|
778aa41f0d | ||
|
|
486957443d | ||
|
|
02e4eaf4b5 | ||
|
|
f5d9023ff3 | ||
|
|
455c868e55 | ||
|
|
6573103755 | ||
|
|
a30e38856e | ||
|
|
d2807ebb18 | ||
|
|
fd151fc70d | ||
|
|
812e727de0 | ||
|
|
2a6a83f56d | ||
|
|
21fc70cbdd | ||
|
|
d9e1177cd8 | ||
|
|
300809fdcb | ||
|
|
7540a15f8d | ||
|
|
f92e3c2194 | ||
|
|
7776134bc2 | ||
|
|
2583d689b9 | ||
|
|
25102095aa | ||
|
|
a6477b82fc |
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,2 +0,0 @@
|
|||||||
/codecs/**/*.js linguist-generated=true
|
|
||||||
/codecs/*/pkg*/*.d.ts linguist-generated=true
|
|
||||||
22
.github/workflows/node.js.yml
vendored
22
.github/workflows/node.js.yml
vendored
@@ -1,22 +0,0 @@
|
|||||||
name: Node.js CI
|
|
||||||
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, windows-latest]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- id: nvmrc
|
|
||||||
uses: browniebroke/read-nvmrc-action@v1
|
|
||||||
- uses: actions/setup-node@v1
|
|
||||||
with:
|
|
||||||
node-version: '${{ steps.nvmrc.outputs.node_version }}'
|
|
||||||
- run: npm ci
|
|
||||||
- run: npm run build
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
codecs
|
|
||||||
.tmp
|
|
||||||
node_modules
|
|
||||||
*.scss.d.ts
|
|
||||||
*.css.d.ts
|
|
||||||
build
|
|
||||||
*.o
|
|
||||||
|
|
||||||
# Auto-generated by lib/feature-plugin.js
|
|
||||||
src/features-worker/index.ts
|
|
||||||
src/client/lazy-app/worker-bridge/meta.ts
|
|
||||||
src/client/lazy-app/feature-meta/index.ts
|
|
||||||
7
.travis.yml
Normal file
7
.travis.yml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
language: node_js
|
||||||
|
cache: npm
|
||||||
|
script: npm run build
|
||||||
|
after_success: npm run sizereport
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
- windows
|
||||||
0
codecs/avif/enc/avif_enc_mt.wasm
Normal file → Executable file
0
codecs/avif/enc/avif_enc_mt.wasm
Normal file → Executable file
@@ -14,33 +14,12 @@ thread_local const val ImageData = val::global("ImageData");
|
|||||||
// R, G, B, A
|
// R, G, B, A
|
||||||
#define COMPONENTS_PER_PIXEL 4
|
#define COMPONENTS_PER_PIXEL 4
|
||||||
|
|
||||||
#ifndef JXL_DEBUG_ON_ALL_ERROR
|
|
||||||
#define JXL_DEBUG_ON_ALL_ERROR 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if JXL_DEBUG_ON_ALL_ERROR
|
|
||||||
#define EXPECT_TRUE(a) \
|
|
||||||
if (!(a)) { \
|
|
||||||
fprintf(stderr, "Assertion failure (%d): %s\n", __LINE__, #a); \
|
|
||||||
return val::null(); \
|
|
||||||
}
|
|
||||||
#define EXPECT_EQ(a, b) \
|
|
||||||
{ \
|
|
||||||
int a_ = a; \
|
|
||||||
int b_ = b; \
|
|
||||||
if (a_ != b_) { \
|
|
||||||
fprintf(stderr, "Assertion failure (%d): %s (%d) != %s (%d)\n", __LINE__, #a, a_, #b, b_); \
|
|
||||||
return val::null(); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define EXPECT_TRUE(a) \
|
#define EXPECT_TRUE(a) \
|
||||||
if (!(a)) { \
|
if (!(a)) { \
|
||||||
return val::null(); \
|
return val::null(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EXPECT_EQ(a, b) EXPECT_TRUE((a) == (b));
|
#define EXPECT_EQ(a, b) EXPECT_TRUE((a) == (b));
|
||||||
#endif
|
|
||||||
|
|
||||||
val decode(std::string data) {
|
val decode(std::string data) {
|
||||||
std::unique_ptr<JxlDecoder,
|
std::unique_ptr<JxlDecoder,
|
||||||
|
|||||||
Binary file not shown.
@@ -38,14 +38,7 @@ val encode(std::string image, int width, int height, JXLOptions options) {
|
|||||||
|
|
||||||
// Reduce memory usage of tree learning for lossless data.
|
// Reduce memory usage of tree learning for lossless data.
|
||||||
// TODO(veluca93): this is a mitigation for excessive memory usage in the JXL encoder.
|
// TODO(veluca93): this is a mitigation for excessive memory usage in the JXL encoder.
|
||||||
float megapixels = width * height * 0.000001;
|
cparams.options.nb_repeats = 0.1;
|
||||||
if (megapixels > 8) {
|
|
||||||
cparams.options.nb_repeats = 0.1;
|
|
||||||
} else if (megapixels > 4) {
|
|
||||||
cparams.options.nb_repeats = 0.3;
|
|
||||||
} else {
|
|
||||||
// default is OK.
|
|
||||||
}
|
|
||||||
|
|
||||||
float quality = options.quality;
|
float quality = options.quality;
|
||||||
|
|
||||||
@@ -66,10 +59,8 @@ val encode(std::string image, int width, int height, JXLOptions options) {
|
|||||||
|
|
||||||
if (options.progressive) {
|
if (options.progressive) {
|
||||||
cparams.qprogressive_mode = true;
|
cparams.qprogressive_mode = true;
|
||||||
|
cparams.progressive_dc = 1;
|
||||||
cparams.responsive = 1;
|
cparams.responsive = 1;
|
||||||
if (!cparams.modular_mode) {
|
|
||||||
cparams.progressive_dc = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cparams.modular_mode) {
|
if (cparams.modular_mode) {
|
||||||
|
|||||||
Binary file not shown.
12
codecs/oxipng/Cargo.lock
generated
12
codecs/oxipng/Cargo.lock
generated
@@ -247,18 +247,18 @@ checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libdeflate-sys"
|
name = "libdeflate-sys"
|
||||||
version = "0.6.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2f5b1582a0ebf8c55a46166c04d7c66f6bb17add3a6cbf69a082ac2219f31671"
|
checksum = "21e39efa87b84db3e13ff4e2dfac1e57220abcbd7fe8ec44d238f7f4f787cc1f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libdeflater"
|
name = "libdeflater"
|
||||||
version = "0.6.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "93edd93a53970951da84ef733a8b6e30189a8f8a9e19610f69e4cc5bb1f4d654"
|
checksum = "a4810980d791f26d470e2d7d91a3d4d22aa3a4b709fb7e9c5e43ee54f83a01f2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libdeflate-sys",
|
"libdeflate-sys",
|
||||||
]
|
]
|
||||||
@@ -359,9 +359,9 @@ checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxipng"
|
name = "oxipng"
|
||||||
version = "4.0.1"
|
version = "4.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fefb26bde273c3db896a313151301a69e698a7495ee577fe2168ed7065c29c4"
|
checksum = "ea40b366cecfce76ee3b082e7e6567b82cdef75644a22442ca8584bc666ff4eb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit-vec",
|
"bit-vec",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
|||||||
4
codecs/oxipng/build.sh
Normal file → Executable file
4
codecs/oxipng/build.sh
Normal file → Executable file
@@ -3,8 +3,6 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
rm -rf pkg,{-parallel}
|
rm -rf pkg,{-parallel}
|
||||||
wasm-pack build -t web
|
wasm-pack build --target web
|
||||||
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory' wasm-pack build -t web -d pkg-parallel -- -Z build-std=panic_abort,std --features=parallel
|
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory' wasm-pack build -t web -d pkg-parallel -- -Z build-std=panic_abort,std --features=parallel
|
||||||
# Workaround https://github.com/rustwasm/wasm-bindgen/issues/2133:
|
|
||||||
sed -i "s|maybe_memory:|maybe_memory?:|" pkg-parallel/squoosh_oxipng.d.ts
|
|
||||||
rm pkg{,-parallel}/.gitignore
|
rm pkg{,-parallel}/.gitignore
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "oxipng",
|
"name": "oxipng",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "RUST_IMG=rustlang/rust@sha256:744aeea5a38f95aa7a96ec37269a65f0c6197a1cdd87d6534e12bb869141d807 ../build-rust.sh ./build.sh"
|
"build": "RUST_IMG=rustlang/rust:8bb115b1090d ../build-rust.sh ./build.sh"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
47
codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts
vendored
47
codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts
vendored
@@ -1,24 +1,29 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
* @param {Uint8Array} data
|
* @param {Uint8Array} data
|
||||||
* @param {number} level
|
* @param {number} level
|
||||||
* @returns {Uint8Array}
|
* @returns {Uint8Array}
|
||||||
*/
|
*/
|
||||||
export function optimise(data: Uint8Array, level: number): Uint8Array;
|
export function optimise(data: Uint8Array, level: number): Uint8Array;
|
||||||
/**
|
/**
|
||||||
* @param {number} num
|
* @param {number} num
|
||||||
* @returns {any}
|
* @returns {any}
|
||||||
*/
|
*/
|
||||||
export function worker_initializer(num: number): any;
|
export function worker_initializer(num: number): any;
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function start_main_thread(): void;
|
export function start_main_thread(): void;
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function start_worker_thread(): void;
|
export function start_worker_thread(): void;
|
||||||
|
|
||||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
export type InitInput =
|
||||||
|
| RequestInfo
|
||||||
|
| URL
|
||||||
|
| Response
|
||||||
|
| BufferSource
|
||||||
|
| WebAssembly.Module;
|
||||||
|
|
||||||
export interface InitOutput {
|
export interface InitOutput {
|
||||||
readonly optimise: (a: number, b: number, c: number, d: number) => void;
|
readonly optimise: (a: number, b: number, c: number, d: number) => void;
|
||||||
@@ -34,13 +39,15 @@ export interface InitOutput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
||||||
* for everything else, calls `WebAssembly.instantiate` directly.
|
* for everything else, calls `WebAssembly.instantiate` directly.
|
||||||
*
|
*
|
||||||
* @param {InitInput | Promise<InitInput>} module_or_path
|
* @param {InitInput | Promise<InitInput>} module_or_path
|
||||||
* @param {WebAssembly.Memory} maybe_memory
|
* @param {WebAssembly.Memory} maybe_memory
|
||||||
*
|
*
|
||||||
* @returns {Promise<InitOutput>}
|
* @returns {Promise<InitOutput>}
|
||||||
*/
|
*/
|
||||||
export default function init (module_or_path?: InitInput | Promise<InitInput>, maybe_memory?: WebAssembly.Memory): Promise<InitOutput>;
|
export default function init(
|
||||||
|
module_or_path?: InitInput | Promise<InitInput>,
|
||||||
|
maybe_memory?: WebAssembly.Memory,
|
||||||
|
): Promise<InitOutput>;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
let wasm;
|
let wasm;
|
||||||
let memory;
|
let memory;
|
||||||
|
|
||||||
@@ -9,172 +8,189 @@ heap.push(undefined, null, true, false);
|
|||||||
let heap_next = heap.length;
|
let heap_next = heap.length;
|
||||||
|
|
||||||
function addHeapObject(obj) {
|
function addHeapObject(obj) {
|
||||||
if (heap_next === heap.length) heap.push(heap.length + 1);
|
if (heap_next === heap.length) heap.push(heap.length + 1);
|
||||||
const idx = heap_next;
|
const idx = heap_next;
|
||||||
heap_next = heap[idx];
|
heap_next = heap[idx];
|
||||||
|
|
||||||
heap[idx] = obj;
|
heap[idx] = obj;
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
let cachedTextDecoder = new TextDecoder('utf-8', {
|
||||||
|
ignoreBOM: true,
|
||||||
|
fatal: true,
|
||||||
|
});
|
||||||
|
|
||||||
cachedTextDecoder.decode();
|
cachedTextDecoder.decode();
|
||||||
|
|
||||||
let cachegetUint8Memory0 = null;
|
let cachegetUint8Memory0 = null;
|
||||||
function getUint8Memory0() {
|
function getUint8Memory0() {
|
||||||
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.__wbindgen_export_0.buffer) {
|
if (
|
||||||
cachegetUint8Memory0 = new Uint8Array(wasm.__wbindgen_export_0.buffer);
|
cachegetUint8Memory0 === null ||
|
||||||
}
|
cachegetUint8Memory0.buffer !== wasm.__wbindgen_export_0.buffer
|
||||||
return cachegetUint8Memory0;
|
) {
|
||||||
|
cachegetUint8Memory0 = new Uint8Array(wasm.__wbindgen_export_0.buffer);
|
||||||
|
}
|
||||||
|
return cachegetUint8Memory0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStringFromWasm0(ptr, len) {
|
function getStringFromWasm0(ptr, len) {
|
||||||
return cachedTextDecoder.decode(getUint8Memory0().slice(ptr, ptr + len));
|
return cachedTextDecoder.decode(getUint8Memory0().slice(ptr, ptr + len));
|
||||||
}
|
}
|
||||||
|
|
||||||
let WASM_VECTOR_LEN = 0;
|
let WASM_VECTOR_LEN = 0;
|
||||||
|
|
||||||
function passArray8ToWasm0(arg, malloc) {
|
function passArray8ToWasm0(arg, malloc) {
|
||||||
const ptr = malloc(arg.length * 1);
|
const ptr = malloc(arg.length * 1);
|
||||||
getUint8Memory0().set(arg, ptr / 1);
|
getUint8Memory0().set(arg, ptr / 1);
|
||||||
WASM_VECTOR_LEN = arg.length;
|
WASM_VECTOR_LEN = arg.length;
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cachegetInt32Memory0 = null;
|
let cachegetInt32Memory0 = null;
|
||||||
function getInt32Memory0() {
|
function getInt32Memory0() {
|
||||||
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.__wbindgen_export_0.buffer) {
|
if (
|
||||||
cachegetInt32Memory0 = new Int32Array(wasm.__wbindgen_export_0.buffer);
|
cachegetInt32Memory0 === null ||
|
||||||
}
|
cachegetInt32Memory0.buffer !== wasm.__wbindgen_export_0.buffer
|
||||||
return cachegetInt32Memory0;
|
) {
|
||||||
|
cachegetInt32Memory0 = new Int32Array(wasm.__wbindgen_export_0.buffer);
|
||||||
|
}
|
||||||
|
return cachegetInt32Memory0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getArrayU8FromWasm0(ptr, len) {
|
function getArrayU8FromWasm0(ptr, len) {
|
||||||
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {Uint8Array} data
|
* @param {Uint8Array} data
|
||||||
* @param {number} level
|
* @param {number} level
|
||||||
* @returns {Uint8Array}
|
* @returns {Uint8Array}
|
||||||
*/
|
*/
|
||||||
export function optimise(data, level) {
|
export function optimise(data, level) {
|
||||||
try {
|
try {
|
||||||
const retptr = wasm.__wbindgen_export_1.value - 16;
|
const retptr = wasm.__wbindgen_export_1.value - 16;
|
||||||
wasm.__wbindgen_export_1.value = retptr;
|
wasm.__wbindgen_export_1.value = retptr;
|
||||||
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
||||||
var len0 = WASM_VECTOR_LEN;
|
var len0 = WASM_VECTOR_LEN;
|
||||||
wasm.optimise(retptr, ptr0, len0, level);
|
wasm.optimise(retptr, ptr0, len0, level);
|
||||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||||
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
||||||
wasm.__wbindgen_free(r0, r1 * 1);
|
wasm.__wbindgen_free(r0, r1 * 1);
|
||||||
return v1;
|
return v1;
|
||||||
} finally {
|
} finally {
|
||||||
wasm.__wbindgen_export_1.value += 16;
|
wasm.__wbindgen_export_1.value += 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getObject(idx) { return heap[idx]; }
|
function getObject(idx) {
|
||||||
|
return heap[idx];
|
||||||
|
}
|
||||||
|
|
||||||
function dropObject(idx) {
|
function dropObject(idx) {
|
||||||
if (idx < 36) return;
|
if (idx < 36) return;
|
||||||
heap[idx] = heap_next;
|
heap[idx] = heap_next;
|
||||||
heap_next = idx;
|
heap_next = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
function takeObject(idx) {
|
function takeObject(idx) {
|
||||||
const ret = getObject(idx);
|
const ret = getObject(idx);
|
||||||
dropObject(idx);
|
dropObject(idx);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {number} num
|
* @param {number} num
|
||||||
* @returns {any}
|
* @returns {any}
|
||||||
*/
|
*/
|
||||||
export function worker_initializer(num) {
|
export function worker_initializer(num) {
|
||||||
var ret = wasm.worker_initializer(num);
|
var ret = wasm.worker_initializer(num);
|
||||||
return takeObject(ret);
|
return takeObject(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function start_main_thread() {
|
export function start_main_thread() {
|
||||||
wasm.start_main_thread();
|
wasm.start_main_thread();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function start_worker_thread() {
|
export function start_worker_thread() {
|
||||||
wasm.start_worker_thread();
|
wasm.start_worker_thread();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function load(module, imports, maybe_memory) {
|
async function load(module, imports, maybe_memory) {
|
||||||
if (typeof Response === 'function' && module instanceof Response) {
|
if (typeof Response === 'function' && module instanceof Response) {
|
||||||
memory = imports.wbg.memory = new WebAssembly.Memory({initial:17,maximum:16384,shared:true});
|
memory = imports.wbg.memory = new WebAssembly.Memory({
|
||||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
initial: 17,
|
||||||
try {
|
maximum: 16384,
|
||||||
return await WebAssembly.instantiateStreaming(module, imports);
|
shared: true,
|
||||||
|
});
|
||||||
} catch (e) {
|
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||||
if (module.headers.get('Content-Type') != 'application/wasm') {
|
try {
|
||||||
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);
|
return await WebAssembly.instantiateStreaming(module, imports);
|
||||||
|
} catch (e) {
|
||||||
} else {
|
if (module.headers.get('Content-Type') != 'application/wasm') {
|
||||||
throw e;
|
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,
|
||||||
}
|
);
|
||||||
|
|
||||||
const bytes = await module.arrayBuffer();
|
|
||||||
return await WebAssembly.instantiate(bytes, imports);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
memory = imports.wbg.memory = maybe_memory;
|
|
||||||
const instance = await WebAssembly.instantiate(module, imports);
|
|
||||||
|
|
||||||
if (instance instanceof WebAssembly.Instance) {
|
|
||||||
return { instance, module };
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return instance;
|
throw e;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bytes = await module.arrayBuffer();
|
||||||
|
return await WebAssembly.instantiate(bytes, imports);
|
||||||
|
} else {
|
||||||
|
memory = imports.wbg.memory = maybe_memory;
|
||||||
|
const instance = await WebAssembly.instantiate(module, imports);
|
||||||
|
|
||||||
|
if (instance instanceof WebAssembly.Instance) {
|
||||||
|
return { instance, module };
|
||||||
|
} else {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function init(input, maybe_memory) {
|
async function init(input, maybe_memory) {
|
||||||
if (typeof input === 'undefined') {
|
if (typeof input === 'undefined') {
|
||||||
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
|
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
|
||||||
}
|
}
|
||||||
const imports = {};
|
const imports = {};
|
||||||
imports.wbg = {};
|
imports.wbg = {};
|
||||||
imports.wbg.__wbindgen_module = function() {
|
imports.wbg.__wbindgen_module = function () {
|
||||||
var ret = init.__wbindgen_wasm_module;
|
var ret = init.__wbindgen_wasm_module;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_memory = function() {
|
imports.wbg.__wbindgen_memory = function () {
|
||||||
var ret = wasm.__wbindgen_export_0;
|
var ret = wasm.__wbindgen_export_0;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_of_6510501edc06d65e = function(arg0, arg1) {
|
imports.wbg.__wbg_of_6510501edc06d65e = function (arg0, arg1) {
|
||||||
var ret = Array.of(takeObject(arg0), takeObject(arg1));
|
var ret = Array.of(takeObject(arg0), takeObject(arg1));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
imports.wbg.__wbindgen_throw = function (arg0, arg1) {
|
||||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
|
if (
|
||||||
input = fetch(input);
|
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, maybe_memory);
|
const { instance, module } = await load(await input, imports, maybe_memory);
|
||||||
|
|
||||||
wasm = instance.exports;
|
wasm = instance.exports;
|
||||||
init.__wbindgen_wasm_module = module;
|
init.__wbindgen_wasm_module = module;
|
||||||
wasm.__wbindgen_start();
|
wasm.__wbindgen_start();
|
||||||
return wasm;
|
return wasm;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default init;
|
export default init;
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
34
codecs/oxipng/pkg/squoosh_oxipng.d.ts
vendored
34
codecs/oxipng/pkg/squoosh_oxipng.d.ts
vendored
@@ -1,13 +1,18 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
* @param {Uint8Array} data
|
* @param {Uint8Array} data
|
||||||
* @param {number} level
|
* @param {number} level
|
||||||
* @returns {Uint8Array}
|
* @returns {Uint8Array}
|
||||||
*/
|
*/
|
||||||
export function optimise(data: Uint8Array, level: number): Uint8Array;
|
export function optimise(data: Uint8Array, level: number): Uint8Array;
|
||||||
|
|
||||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
export type InitInput =
|
||||||
|
| RequestInfo
|
||||||
|
| URL
|
||||||
|
| Response
|
||||||
|
| BufferSource
|
||||||
|
| WebAssembly.Module;
|
||||||
|
|
||||||
export interface InitOutput {
|
export interface InitOutput {
|
||||||
readonly memory: WebAssembly.Memory;
|
readonly memory: WebAssembly.Memory;
|
||||||
@@ -19,12 +24,13 @@ export interface InitOutput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
||||||
* for everything else, calls `WebAssembly.instantiate` directly.
|
* for everything else, calls `WebAssembly.instantiate` directly.
|
||||||
*
|
*
|
||||||
* @param {InitInput | Promise<InitInput>} module_or_path
|
* @param {InitInput | Promise<InitInput>} module_or_path
|
||||||
*
|
*
|
||||||
* @returns {Promise<InitOutput>}
|
* @returns {Promise<InitOutput>}
|
||||||
*/
|
*/
|
||||||
export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;
|
export default function init(
|
||||||
|
module_or_path?: InitInput | Promise<InitInput>,
|
||||||
|
): Promise<InitOutput>;
|
||||||
|
|||||||
@@ -1,118 +1,126 @@
|
|||||||
|
|
||||||
let wasm;
|
let wasm;
|
||||||
|
|
||||||
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
let cachedTextDecoder = new TextDecoder('utf-8', {
|
||||||
|
ignoreBOM: true,
|
||||||
|
fatal: true,
|
||||||
|
});
|
||||||
|
|
||||||
cachedTextDecoder.decode();
|
cachedTextDecoder.decode();
|
||||||
|
|
||||||
let cachegetUint8Memory0 = null;
|
let cachegetUint8Memory0 = null;
|
||||||
function getUint8Memory0() {
|
function getUint8Memory0() {
|
||||||
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
|
if (
|
||||||
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
|
cachegetUint8Memory0 === null ||
|
||||||
}
|
cachegetUint8Memory0.buffer !== wasm.memory.buffer
|
||||||
return cachegetUint8Memory0;
|
) {
|
||||||
|
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetUint8Memory0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStringFromWasm0(ptr, len) {
|
function getStringFromWasm0(ptr, len) {
|
||||||
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
||||||
}
|
}
|
||||||
|
|
||||||
let WASM_VECTOR_LEN = 0;
|
let WASM_VECTOR_LEN = 0;
|
||||||
|
|
||||||
function passArray8ToWasm0(arg, malloc) {
|
function passArray8ToWasm0(arg, malloc) {
|
||||||
const ptr = malloc(arg.length * 1);
|
const ptr = malloc(arg.length * 1);
|
||||||
getUint8Memory0().set(arg, ptr / 1);
|
getUint8Memory0().set(arg, ptr / 1);
|
||||||
WASM_VECTOR_LEN = arg.length;
|
WASM_VECTOR_LEN = arg.length;
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cachegetInt32Memory0 = null;
|
let cachegetInt32Memory0 = null;
|
||||||
function getInt32Memory0() {
|
function getInt32Memory0() {
|
||||||
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
|
if (
|
||||||
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
cachegetInt32Memory0 === null ||
|
||||||
}
|
cachegetInt32Memory0.buffer !== wasm.memory.buffer
|
||||||
return cachegetInt32Memory0;
|
) {
|
||||||
|
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetInt32Memory0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getArrayU8FromWasm0(ptr, len) {
|
function getArrayU8FromWasm0(ptr, len) {
|
||||||
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {Uint8Array} data
|
* @param {Uint8Array} data
|
||||||
* @param {number} level
|
* @param {number} level
|
||||||
* @returns {Uint8Array}
|
* @returns {Uint8Array}
|
||||||
*/
|
*/
|
||||||
export function optimise(data, level) {
|
export function optimise(data, level) {
|
||||||
try {
|
try {
|
||||||
const retptr = wasm.__wbindgen_export_0.value - 16;
|
const retptr = wasm.__wbindgen_export_0.value - 16;
|
||||||
wasm.__wbindgen_export_0.value = retptr;
|
wasm.__wbindgen_export_0.value = retptr;
|
||||||
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
||||||
var len0 = WASM_VECTOR_LEN;
|
var len0 = WASM_VECTOR_LEN;
|
||||||
wasm.optimise(retptr, ptr0, len0, level);
|
wasm.optimise(retptr, ptr0, len0, level);
|
||||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||||
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
||||||
wasm.__wbindgen_free(r0, r1 * 1);
|
wasm.__wbindgen_free(r0, r1 * 1);
|
||||||
return v1;
|
return v1;
|
||||||
} finally {
|
} finally {
|
||||||
wasm.__wbindgen_export_0.value += 16;
|
wasm.__wbindgen_export_0.value += 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function load(module, imports) {
|
async function load(module, imports) {
|
||||||
if (typeof Response === 'function' && module instanceof Response) {
|
if (typeof Response === 'function' && module instanceof Response) {
|
||||||
|
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
try {
|
||||||
try {
|
return await WebAssembly.instantiateStreaming(module, imports);
|
||||||
return await WebAssembly.instantiateStreaming(module, imports);
|
} catch (e) {
|
||||||
|
if (module.headers.get('Content-Type') != 'application/wasm') {
|
||||||
} catch (e) {
|
console.warn(
|
||||||
if (module.headers.get('Content-Type') != 'application/wasm') {
|
'`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',
|
||||||
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);
|
e,
|
||||||
|
);
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const bytes = await module.arrayBuffer();
|
|
||||||
return await WebAssembly.instantiate(bytes, imports);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
const instance = await WebAssembly.instantiate(module, imports);
|
|
||||||
|
|
||||||
if (instance instanceof WebAssembly.Instance) {
|
|
||||||
return { instance, module };
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return instance;
|
throw e;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bytes = await module.arrayBuffer();
|
||||||
|
return await WebAssembly.instantiate(bytes, imports);
|
||||||
|
} else {
|
||||||
|
const instance = await WebAssembly.instantiate(module, imports);
|
||||||
|
|
||||||
|
if (instance instanceof WebAssembly.Instance) {
|
||||||
|
return { instance, module };
|
||||||
|
} else {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function init(input) {
|
async function init(input) {
|
||||||
if (typeof input === 'undefined') {
|
if (typeof input === 'undefined') {
|
||||||
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
|
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
|
||||||
}
|
}
|
||||||
const imports = {};
|
const imports = {};
|
||||||
imports.wbg = {};
|
imports.wbg = {};
|
||||||
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
imports.wbg.__wbindgen_throw = function (arg0, arg1) {
|
||||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
|
if (
|
||||||
input = fetch(input);
|
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);
|
const { instance, module } = await load(await input, imports);
|
||||||
|
|
||||||
wasm = instance.exports;
|
wasm = instance.exports;
|
||||||
init.__wbindgen_wasm_module = module;
|
init.__wbindgen_wasm_module = module;
|
||||||
|
|
||||||
return wasm;
|
return wasm;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default init;
|
export default init;
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
use oxipng::AlphaOptim;
|
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
use oxipng::AlphaOptim;
|
||||||
|
|
||||||
mod malloc_shim;
|
mod malloc_shim;
|
||||||
|
|
||||||
@@ -8,14 +8,14 @@ pub mod parallel;
|
|||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn optimise(data: &[u8], level: u8) -> Vec<u8> {
|
pub fn optimise(data: &[u8], level: u8) -> Vec<u8> {
|
||||||
let mut options = oxipng::Options::from_preset(level);
|
let mut options = oxipng::Options::from_preset(level);
|
||||||
options.alphas.insert(AlphaOptim::Black);
|
options.alphas.insert(AlphaOptim::Black);
|
||||||
options.alphas.insert(AlphaOptim::White);
|
options.alphas.insert(AlphaOptim::White);
|
||||||
options.alphas.insert(AlphaOptim::Up);
|
options.alphas.insert(AlphaOptim::Up);
|
||||||
options.alphas.insert(AlphaOptim::Down);
|
options.alphas.insert(AlphaOptim::Down);
|
||||||
options.alphas.insert(AlphaOptim::Left);
|
options.alphas.insert(AlphaOptim::Left);
|
||||||
options.alphas.insert(AlphaOptim::Right);
|
options.alphas.insert(AlphaOptim::Right);
|
||||||
|
|
||||||
options.deflate = oxipng::Deflaters::Libdeflater;
|
options.deflate = oxipng::Deflaters::Libdeflater;
|
||||||
oxipng::optimize_from_memory(data, &options).unwrap_throw()
|
oxipng::optimize_from_memory(data, &options).unwrap_throw()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crossbeam_channel::{bounded, Receiver, Sender};
|
use crossbeam_channel::{Sender, Receiver, bounded};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use wasm_bindgen::JsValue;
|
use wasm_bindgen::JsValue;
|
||||||
@@ -35,8 +35,7 @@ extern "C" {
|
|||||||
// shared memory and blocks the current thread until they're all grabbed.
|
// shared memory and blocks the current thread until they're all grabbed.
|
||||||
// 4) Provide a `worker_initializer` that is expected to be invoked from various workers,
|
// 4) Provide a `worker_initializer` that is expected to be invoked from various workers,
|
||||||
// reads one `threadPtr` from the shared channel and starts running it.
|
// reads one `threadPtr` from the shared channel and starts running it.
|
||||||
static CHANNEL: OnceCell<(Sender<rayon::ThreadBuilder>, Receiver<rayon::ThreadBuilder>)> =
|
static CHANNEL: OnceCell<(Sender<rayon::ThreadBuilder>, Receiver<rayon::ThreadBuilder>)> = OnceCell::new();
|
||||||
OnceCell::new();
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn worker_initializer(num: usize) -> JsValue {
|
pub fn worker_initializer(num: usize) -> JsValue {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ RUN wget -qO- https://github.com/rustwasm/wasm-pack/releases/download/v0.9.1/was
|
|||||||
FROM $RUST_IMG AS rust
|
FROM $RUST_IMG AS rust
|
||||||
ARG RUST_IMG
|
ARG RUST_IMG
|
||||||
RUN rustup target add wasm32-unknown-unknown
|
RUN rustup target add wasm32-unknown-unknown
|
||||||
RUN case $RUST_IMG in rustlang/rust@*) rustup component add rust-src; esac
|
RUN if [[ $RUST_IMG = rustlang/rust:* ]] ; then rustup component add rust-src ; fi
|
||||||
COPY --from=wasm-tools /emsdk/upstream/bin/wasm-opt /emsdk/upstream/bin/clang /usr/local/bin/
|
COPY --from=wasm-tools /emsdk/upstream/bin/wasm-opt /emsdk/upstream/bin/clang /usr/local/bin/
|
||||||
COPY --from=wasm-tools /emsdk/upstream/lib/ /usr/local/lib/
|
COPY --from=wasm-tools /emsdk/upstream/lib/ /usr/local/lib/
|
||||||
COPY --from=wasm-tools /emsdk/upstream/emscripten/system/include/libc/ /wasm32/include/
|
COPY --from=wasm-tools /emsdk/upstream/emscripten/system/include/libc/ /wasm32/include/
|
||||||
|
|||||||
@@ -17,10 +17,7 @@ val decode(std::string buffer) {
|
|||||||
int width, height;
|
int width, height;
|
||||||
std::unique_ptr<uint8_t[]> rgba(
|
std::unique_ptr<uint8_t[]> rgba(
|
||||||
WebPDecodeRGBA((const uint8_t*)buffer.c_str(), buffer.size(), &width, &height));
|
WebPDecodeRGBA((const uint8_t*)buffer.c_str(), buffer.size(), &width, &height));
|
||||||
return rgba ? ImageData.new_(
|
return rgba ? ImageData.new_(Uint8ClampedArray.new_(typed_memory_view(width * height * 4, rgba.get())), width, height) : val::null();
|
||||||
Uint8ClampedArray.new_(typed_memory_view(width * height * 4, rgba.get())),
|
|
||||||
width, height)
|
|
||||||
: val::null();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
|
|||||||
@@ -7,31 +7,7 @@ using namespace emscripten;
|
|||||||
|
|
||||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
thread_local const val Uint8Array = val::global("Uint8Array");
|
||||||
|
|
||||||
struct WP2Options {
|
val encode(std::string image_in, int image_width, int image_height, WP2::EncoderConfig config) {
|
||||||
float quality;
|
|
||||||
float alpha_quality;
|
|
||||||
int speed;
|
|
||||||
int pass;
|
|
||||||
int uv_mode;
|
|
||||||
float sns;
|
|
||||||
int csp_type;
|
|
||||||
int error_diffusion;
|
|
||||||
bool use_random_matrix;
|
|
||||||
};
|
|
||||||
|
|
||||||
val encode(std::string image_in, int image_width, int image_height, WP2Options options) {
|
|
||||||
WP2::EncoderConfig config = {};
|
|
||||||
|
|
||||||
config.quality = options.quality;
|
|
||||||
config.alpha_quality = options.alpha_quality;
|
|
||||||
config.speed = options.speed;
|
|
||||||
config.pass = options.pass;
|
|
||||||
config.uv_mode = static_cast<WP2::EncoderConfig::UVMode>(options.uv_mode);
|
|
||||||
config.csp_type = static_cast<WP2::Csp>(options.csp_type);
|
|
||||||
config.sns = options.sns;
|
|
||||||
config.error_diffusion = options.error_diffusion;
|
|
||||||
config.use_random_matrix = options.use_random_matrix;
|
|
||||||
|
|
||||||
uint8_t* image_buffer = (uint8_t*)image_in.c_str();
|
uint8_t* image_buffer = (uint8_t*)image_in.c_str();
|
||||||
WP2::ArgbBuffer src = WP2::ArgbBuffer();
|
WP2::ArgbBuffer src = WP2::ArgbBuffer();
|
||||||
WP2Status status =
|
WP2Status status =
|
||||||
@@ -51,16 +27,12 @@ val encode(std::string image_in, int image_width, int image_height, WP2Options o
|
|||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
value_object<WP2Options>("WP2Options")
|
value_object<WP2::EncoderConfig>("WP2EncoderConfig")
|
||||||
.field("quality", &WP2Options::quality)
|
.field("quality", &WP2::EncoderConfig::quality)
|
||||||
.field("alpha_quality", &WP2Options::alpha_quality)
|
.field("alpha_quality", &WP2::EncoderConfig::alpha_quality)
|
||||||
.field("speed", &WP2Options::speed)
|
.field("speed", &WP2::EncoderConfig::speed)
|
||||||
.field("pass", &WP2Options::pass)
|
.field("pass", &WP2::EncoderConfig::pass)
|
||||||
.field("uv_mode", &WP2Options::uv_mode)
|
.field("sns", &WP2::EncoderConfig::sns);
|
||||||
.field("csp_type", &WP2Options::csp_type)
|
|
||||||
.field("error_diffusion", &WP2Options::error_diffusion)
|
|
||||||
.field("use_random_matrix", &WP2Options::use_random_matrix)
|
|
||||||
.field("sns", &WP2Options::sns);
|
|
||||||
|
|
||||||
function("encode", &encode);
|
function("encode", &encode);
|
||||||
}
|
}
|
||||||
|
|||||||
18
codecs/wp2/enc/wp2_enc.d.ts
vendored
18
codecs/wp2/enc/wp2_enc.d.ts
vendored
@@ -4,24 +4,6 @@ export interface EncodeOptions {
|
|||||||
speed: number;
|
speed: number;
|
||||||
pass: number;
|
pass: number;
|
||||||
sns: number;
|
sns: number;
|
||||||
uv_mode: UVMode;
|
|
||||||
csp_type: Csp;
|
|
||||||
error_diffusion: number;
|
|
||||||
use_random_matrix: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const enum UVMode {
|
|
||||||
UVModeAdapt = 0, // Mix of 420 and 444 (per block)
|
|
||||||
UVMode420, // All blocks 420
|
|
||||||
UVMode444, // All blocks 444
|
|
||||||
UVModeAuto, // Choose any of the above automatically
|
|
||||||
}
|
|
||||||
|
|
||||||
export const enum Csp {
|
|
||||||
kYCoCg,
|
|
||||||
kYCbCr,
|
|
||||||
kCustom,
|
|
||||||
kYIQ,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WP2Module extends EmscriptenWasm.Module {
|
export interface WP2Module extends EmscriptenWasm.Module {
|
||||||
|
|||||||
@@ -576,7 +576,7 @@ var wp2_enc = (function () {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
var ob = {
|
var ob = {
|
||||||
t: function (a, b, c, d) {
|
p: function (a, b, c, d) {
|
||||||
A(
|
A(
|
||||||
'Assertion failed: ' +
|
'Assertion failed: ' +
|
||||||
C(a) +
|
C(a) +
|
||||||
@@ -807,7 +807,7 @@ var wp2_enc = (function () {
|
|||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
d: function (a, b, c, d, e) {
|
c: function (a, b, c, d, e) {
|
||||||
function g(l) {
|
function g(l) {
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
@@ -1000,10 +1000,10 @@ var wp2_enc = (function () {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
p: function (a, b, c, d, e, g) {
|
q: function (a, b, c, d, e, g) {
|
||||||
Fa[a] = { name: U(b), da: Y(c, d), ea: Y(e, g), U: [] };
|
Fa[a] = { name: U(b), da: Y(c, d), ea: Y(e, g), U: [] };
|
||||||
},
|
},
|
||||||
c: function (a, b, c, d, e, g, m, h, k, l) {
|
e: function (a, b, c, d, e, g, m, h, k, l) {
|
||||||
Fa[a].U.push({
|
Fa[a].U.push({
|
||||||
X: U(b),
|
X: U(b),
|
||||||
aa: c,
|
aa: c,
|
||||||
@@ -1034,7 +1034,7 @@ var wp2_enc = (function () {
|
|||||||
m: function (a) {
|
m: function (a) {
|
||||||
4 < a && (X[a].T += 1);
|
4 < a && (X[a].T += 1);
|
||||||
},
|
},
|
||||||
q: function (a, b, c, d) {
|
t: function (a, b, c, d) {
|
||||||
a || W('Cannot use deleted val. handle = ' + a);
|
a || W('Cannot use deleted val. handle = ' + a);
|
||||||
a = X[a].value;
|
a = X[a].value;
|
||||||
var e = ib[b];
|
var e = ib[b];
|
||||||
@@ -1079,7 +1079,7 @@ var wp2_enc = (function () {
|
|||||||
u: function (a, b, c) {
|
u: function (a, b, c) {
|
||||||
D.copyWithin(a, b, b + c);
|
D.copyWithin(a, b, b + c);
|
||||||
},
|
},
|
||||||
e: function (a) {
|
d: function (a) {
|
||||||
a >>>= 0;
|
a >>>= 0;
|
||||||
var b = D.length;
|
var b = D.length;
|
||||||
if (2147483648 < a) return !1;
|
if (2147483648 < a) return !1;
|
||||||
|
|||||||
Binary file not shown.
@@ -11,7 +11,6 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import rollup from 'rollup';
|
import rollup from 'rollup';
|
||||||
import * as path from 'path';
|
|
||||||
|
|
||||||
const prefix = 'client-bundle:';
|
const prefix = 'client-bundle:';
|
||||||
const entryPathPlaceholder = 'CLIENT_BUNDLE_PLUGIN_ENTRY_PATH';
|
const entryPathPlaceholder = 'CLIENT_BUNDLE_PLUGIN_ENTRY_PATH';
|
||||||
@@ -120,10 +119,9 @@ export default function (inputOptions, outputOptions, resolveFileUrl) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = path.normalize(entryPointPlaceholderMap.get(num));
|
const id = entryPointPlaceholderMap.get(num);
|
||||||
const clientEntry = clientOutput.find(
|
const clientEntry = clientOutput.find(
|
||||||
(item) =>
|
(item) => item.facadeModuleId === id,
|
||||||
item.facadeModuleId && path.normalize(item.facadeModuleId) === id,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (property.startsWith(entryPathPlaceholder)) {
|
if (property.startsWith(entryPathPlaceholder)) {
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ import {
|
|||||||
resolve as resolvePath,
|
resolve as resolvePath,
|
||||||
dirname,
|
dirname,
|
||||||
normalize as nomalizePath,
|
normalize as nomalizePath,
|
||||||
sep as pathSep,
|
|
||||||
posix,
|
|
||||||
} from 'path';
|
} from 'path';
|
||||||
|
|
||||||
import postcss from 'postcss';
|
import postcss from 'postcss';
|
||||||
@@ -174,15 +172,14 @@ export default function (resolveFileUrl) {
|
|||||||
return `export default ${cssStr};`;
|
return `export default ${cssStr};`;
|
||||||
}
|
}
|
||||||
if (id.startsWith(addPrefix)) {
|
if (id.startsWith(addPrefix)) {
|
||||||
const path = nomalizePath(id.slice(addPrefix.length));
|
const path = id.slice(addPrefix.length);
|
||||||
return (
|
return (
|
||||||
`import css from ${JSON.stringify('css:' + path)};\n` +
|
`import css from 'css:${path}';\n` +
|
||||||
`import appendCss from '${appendCssModule}';\n` +
|
`import appendCss from '${appendCssModule}';\n` +
|
||||||
`appendCss(css);\n`
|
`appendCss(css);\n`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (id.endsWith(moduleSuffix)) {
|
if (id.endsWith(moduleSuffix)) {
|
||||||
const path = nomalizePath(id.slice(0, -moduleSuffix.length));
|
|
||||||
if (!pathToResult.has(id)) {
|
if (!pathToResult.has(id)) {
|
||||||
throw Error(`Cannot find ${id} in pathToResult`);
|
throw Error(`Cannot find ${id} in pathToResult`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,16 +19,15 @@ import glob from 'glob';
|
|||||||
const globP = promisify(glob);
|
const globP = promisify(glob);
|
||||||
|
|
||||||
const moduleId = 'initial-css:';
|
const moduleId = 'initial-css:';
|
||||||
const initialCssModule = '\0initialCss';
|
|
||||||
|
|
||||||
export default function initialCssPlugin() {
|
export default function initialCssPlugin() {
|
||||||
return {
|
return {
|
||||||
name: 'initial-css-plugin',
|
name: 'initial-css-plugin',
|
||||||
resolveId(id) {
|
resolveId(id) {
|
||||||
if (id === moduleId) return initialCssModule;
|
if (id === moduleId) return moduleId;
|
||||||
},
|
},
|
||||||
async load(id) {
|
async load(id) {
|
||||||
if (id !== initialCssModule) return;
|
if (id !== moduleId) return;
|
||||||
|
|
||||||
const matches = await globP('shared/initial-app/**/*.css', {
|
const matches = await globP('shared/initial-app/**/*.css', {
|
||||||
nodir: true,
|
nodir: true,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { posix as pathUtils, isAbsolute } from 'path';
|
import { posix as pathUtils } from 'path';
|
||||||
|
|
||||||
export default function resolveDirs(paths) {
|
export default function resolveDirs(paths) {
|
||||||
const pathBaseDir = paths.map((path) => [
|
const pathBaseDir = paths.map((path) => [
|
||||||
@@ -30,7 +30,6 @@ export default function resolveDirs(paths) {
|
|||||||
if (!resolveResult) {
|
if (!resolveResult) {
|
||||||
throw new Error(`Couldn't find ${'./' + id}`);
|
throw new Error(`Couldn't find ${'./' + id}`);
|
||||||
}
|
}
|
||||||
if (isAbsolute(resolveResult.id)) return resolveResult.id;
|
|
||||||
return pathUtils.resolve(resolveResult.id);
|
return pathUtils.resolve(resolveResult.id);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -127,6 +127,15 @@ export default function simpleTS(mainPath, { noBuild, watch } = {}) {
|
|||||||
relative(process.cwd(), id),
|
relative(process.cwd(), id),
|
||||||
).replace(extRe, '.js');
|
).replace(extRe, '.js');
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`simple-ts mapping`,
|
||||||
|
id,
|
||||||
|
'to',
|
||||||
|
newId,
|
||||||
|
'with outDir',
|
||||||
|
config.options.outDir,
|
||||||
|
);
|
||||||
|
|
||||||
return fsp.readFile(newId, { encoding: 'utf8' });
|
return fsp.readFile(newId, { encoding: 'utf8' });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
8538
package-lock.json
generated
8538
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@@ -6,9 +6,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rollup -c && node lib/move-output.js",
|
"build": "rollup -c && node lib/move-output.js",
|
||||||
"debug": "node --inspect-brk node_modules/.bin/rollup -c",
|
"debug": "node --inspect-brk node_modules/.bin/rollup -c",
|
||||||
"dev": "run-p watch serve",
|
"dev": "rollup -cw & npm run serve",
|
||||||
"watch": "rollup -cw",
|
"serve": "serve --config server.json .tmp/build/static"
|
||||||
"serve": "serve --config ../../../serve.json .tmp/build/static"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-commonjs": "^15.1.0",
|
"@rollup/plugin-commonjs": "^15.1.0",
|
||||||
@@ -26,7 +25,6 @@
|
|||||||
"lint-staged": "^10.5.1",
|
"lint-staged": "^10.5.1",
|
||||||
"lodash.camelcase": "^4.3.0",
|
"lodash.camelcase": "^4.3.0",
|
||||||
"mime-types": "^2.1.27",
|
"mime-types": "^2.1.27",
|
||||||
"npm-run-all": "^4.1.5",
|
|
||||||
"pointer-tracker": "^2.4.0",
|
"pointer-tracker": "^2.4.0",
|
||||||
"postcss": "^7.0.35",
|
"postcss": "^7.0.35",
|
||||||
"postcss-modules": "^3.2.2",
|
"postcss-modules": "^3.2.2",
|
||||||
@@ -49,9 +47,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.{js,css,json,md,ts,tsx}": "prettier --write",
|
"*.{js,css,json,md,ts,tsx}": [
|
||||||
"*.{c,h,cpp,hpp}": "clang-format -i",
|
"prettier --write"
|
||||||
"*.rs": "rustfmt"
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"wasm-feature-detect": "^1.2.9"
|
"wasm-feature-detect": "^1.2.9"
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ function jsFileName(chunkInfo) {
|
|||||||
const parsedPath = path.parse(chunkInfo.facadeModuleId);
|
const parsedPath = path.parse(chunkInfo.facadeModuleId);
|
||||||
if (parsedPath.name !== 'index') return jsPath;
|
if (parsedPath.name !== 'index') return jsPath;
|
||||||
// Come up with a better name than 'index'
|
// Come up with a better name than 'index'
|
||||||
const name = parsedPath.dir.split(/\\|\//).slice(-1);
|
const name = parsedPath.dir.split('/').slice(-1);
|
||||||
return jsPath.replace('[name]', name);
|
return jsPath.replace('[name]', name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,5 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"redirects": [{ "source": "/editor", "destination": "/" }]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export default class App extends Component<Props, State> {
|
|||||||
// really breaks things on Squoosh, as you can easily end up zooming the UI when you mean to
|
// really breaks things on Squoosh, as you can easily end up zooming the UI when you mean to
|
||||||
// zoom the image. Once you've done this, it's really difficult to undo. Anyway, this seems to
|
// zoom the image. Once you've done this, it's really difficult to undo. Anyway, this seems to
|
||||||
// prevent it.
|
// prevent it.
|
||||||
document.body.addEventListener('gesturestart', (event: any) => {
|
document.body.addEventListener('gesturestart', (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -115,7 +115,11 @@ export default class App extends Component<Props, State> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={style.app}>
|
<div class={style.app}>
|
||||||
<file-drop onfiledrop={this.onFileDrop} class={style.drop}>
|
<file-drop
|
||||||
|
accept="image/*"
|
||||||
|
onfiledrop={this.onFileDrop}
|
||||||
|
class={style.drop}
|
||||||
|
>
|
||||||
{showSpinner ? (
|
{showSpinner ? (
|
||||||
<loading-spinner class={style.appLoader} />
|
<loading-spinner class={style.appLoader} />
|
||||||
) : isEditorOpen ? (
|
) : isEditorOpen ? (
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import 'add-css:./style.css';
|
|||||||
import { cleanSet, cleanMerge } from '../../util/clean-modify';
|
import { cleanSet, cleanMerge } from '../../util/clean-modify';
|
||||||
|
|
||||||
import type { SourceImage, OutputType } from '..';
|
import type { SourceImage, OutputType } from '..';
|
||||||
import type SnackBarElement from 'shared/initial-app/custom-els/snack-bar';
|
|
||||||
import {
|
import {
|
||||||
EncoderOptions,
|
EncoderOptions,
|
||||||
EncoderState,
|
EncoderState,
|
||||||
@@ -19,10 +18,7 @@ import Select from './Select';
|
|||||||
import { Options as QuantOptionsComponent } from 'features/processors/quantize/client';
|
import { Options as QuantOptionsComponent } from 'features/processors/quantize/client';
|
||||||
import { Options as ResizeOptionsComponent } from 'features/processors/resize/client';
|
import { Options as ResizeOptionsComponent } from 'features/processors/resize/client';
|
||||||
|
|
||||||
import { generateCliInvocation } from '../../util/cli-invocation-generator';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
showSnack: SnackBarElement['showSnackbar'];
|
|
||||||
mobileView: boolean;
|
mobileView: boolean;
|
||||||
source?: SourceImage;
|
source?: SourceImage;
|
||||||
encoderState?: EncoderState;
|
encoderState?: EncoderState;
|
||||||
@@ -101,22 +97,6 @@ export default class Options extends Component<Props, State> {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
private onCreateCLIInvocation = () => {
|
|
||||||
if (!this.props.encoderState) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const cliInvocation = generateCliInvocation(
|
|
||||||
this.props.encoderState,
|
|
||||||
this.props.processorState,
|
|
||||||
);
|
|
||||||
navigator.clipboard.writeText(cliInvocation);
|
|
||||||
} catch (e) {
|
|
||||||
this.props.showSnack(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
render(
|
render(
|
||||||
{ source, encoderState, processorState, onEncoderOptionsChange }: Props,
|
{ source, encoderState, processorState, onEncoderOptionsChange }: Props,
|
||||||
{ supportedEncoderMap }: State,
|
{ supportedEncoderMap }: State,
|
||||||
@@ -130,9 +110,7 @@ export default class Options extends Component<Props, State> {
|
|||||||
<Expander>
|
<Expander>
|
||||||
{!encoderState ? null : (
|
{!encoderState ? null : (
|
||||||
<div>
|
<div>
|
||||||
<h3 class={style.optionsTitle}>
|
<h3 class={style.optionsTitle}>Edit</h3>
|
||||||
<button onClick={this.onCreateCLIInvocation}>CLI</button>Edit
|
|
||||||
</h3>
|
|
||||||
<label class={style.sectionEnabler}>
|
<label class={style.sectionEnabler}>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
name="resize.enable"
|
name="resize.enable"
|
||||||
|
|||||||
@@ -649,7 +649,6 @@ export default class Compress extends Component<Props, State> {
|
|||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.name === 'AbortError') return;
|
if (err.name === 'AbortError') return;
|
||||||
this.setState({ loading: false });
|
|
||||||
this.props.showSnack(`Preprocessing error: ${err}`);
|
this.props.showSnack(`Preprocessing error: ${err}`);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@@ -773,12 +772,6 @@ export default class Compress extends Component<Props, State> {
|
|||||||
this.activeSideJobs[sideIndex] = undefined;
|
this.activeSideJobs[sideIndex] = undefined;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.name === 'AbortError') return;
|
if (err.name === 'AbortError') return;
|
||||||
this.setState((currentState) => {
|
|
||||||
const sides = cleanMerge(currentState.sides, sideIndex, {
|
|
||||||
loading: false,
|
|
||||||
});
|
|
||||||
return { sides };
|
|
||||||
});
|
|
||||||
this.props.showSnack(`Processing error: ${err}`);
|
this.props.showSnack(`Processing error: ${err}`);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@@ -786,7 +779,7 @@ export default class Compress extends Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render(
|
render(
|
||||||
{ onBack, showSnack }: Props,
|
{ onBack }: Props,
|
||||||
{ loading, sides, source, mobileView, preprocessorState }: State,
|
{ loading, sides, source, mobileView, preprocessorState }: State,
|
||||||
) {
|
) {
|
||||||
const [leftSide, rightSide] = sides;
|
const [leftSide, rightSide] = sides;
|
||||||
@@ -794,7 +787,6 @@ export default class Compress extends Component<Props, State> {
|
|||||||
|
|
||||||
const options = sides.map((side, index) => (
|
const options = sides.map((side, index) => (
|
||||||
<Options
|
<Options
|
||||||
showSnack={showSnack}
|
|
||||||
source={source}
|
source={source}
|
||||||
mobileView={mobileView}
|
mobileView={mobileView}
|
||||||
processorState={side.latestSettings.processorState}
|
processorState={side.latestSettings.processorState}
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2020 Google Inc. All Rights Reserved.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { EncoderState, ProcessorState } from '../feature-meta';
|
|
||||||
|
|
||||||
// Maps our encoder.type values to CLI parameter names
|
|
||||||
const typeMap = new Map<string, string>([
|
|
||||||
['avif', '--avif'],
|
|
||||||
["jxl", "--jxl"],
|
|
||||||
['mozJPEG', '--mozjpeg'],
|
|
||||||
['oxiPNG', '--oxipng'],
|
|
||||||
['webP', '--webp'],
|
|
||||||
["wp2", "--wp2"],
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Same as JSON.stringify, but with single quotes around the entire value
|
|
||||||
// so that shells don’t do weird stuff.
|
|
||||||
function cliJson<T>(v: T): string {
|
|
||||||
return "'" + JSON.stringify(v) + "'";
|
|
||||||
}
|
|
||||||
|
|
||||||
export function generateCliInvocation(
|
|
||||||
encoder: EncoderState,
|
|
||||||
processor: ProcessorState,
|
|
||||||
): string {
|
|
||||||
if (!typeMap.has(encoder.type)) {
|
|
||||||
throw Error(`Encoder ${encoder.type} is unsupported in the CLI`);
|
|
||||||
}
|
|
||||||
return [
|
|
||||||
'npx',
|
|
||||||
'@squoosh/cli',
|
|
||||||
...(processor.resize.enabled
|
|
||||||
? ['--resize', cliJson(processor.resize)]
|
|
||||||
: []),
|
|
||||||
...(processor.quantize.enabled
|
|
||||||
? ['--quant', cliJson(processor.quantize)]
|
|
||||||
: []),
|
|
||||||
typeMap.get(encoder.type)!,
|
|
||||||
cliJson(encoder.options),
|
|
||||||
].join(' ');
|
|
||||||
}
|
|
||||||
@@ -315,9 +315,9 @@ export class Options extends Component<Props, State> {
|
|||||||
value={subsample}
|
value={subsample}
|
||||||
onChange={this._inputChange('subsample', 'number')}
|
onChange={this._inputChange('subsample', 'number')}
|
||||||
>
|
>
|
||||||
<option value="1">Half</option>
|
<option value="1">4:2:0</option>
|
||||||
{/*<option value="2">4:2:2</option>*/}
|
{/*<option value="2">4:2:2</option>*/}
|
||||||
<option value="3">Off</option>
|
<option value="3">4:4:4</option>
|
||||||
</Select>
|
</Select>
|
||||||
</label>
|
</label>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ interface State {
|
|||||||
edgePreservingFilter: number;
|
edgePreservingFilter: number;
|
||||||
lossless: boolean;
|
lossless: boolean;
|
||||||
slightLoss: boolean;
|
slightLoss: boolean;
|
||||||
autoEdgePreservingFilter: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxSpeed = 7;
|
const maxSpeed = 7;
|
||||||
@@ -49,10 +48,9 @@ export class Options extends Component<Props, State> {
|
|||||||
effort: maxSpeed - options.speed,
|
effort: maxSpeed - options.speed,
|
||||||
quality: options.quality,
|
quality: options.quality,
|
||||||
progressive: options.progressive,
|
progressive: options.progressive,
|
||||||
edgePreservingFilter: options.epf === -1 ? 2 : options.epf,
|
edgePreservingFilter: options.epf,
|
||||||
lossless: options.quality === 100,
|
lossless: options.quality === 100,
|
||||||
slightLoss: options.lossyPalette,
|
slightLoss: options.lossyPalette,
|
||||||
autoEdgePreservingFilter: options.epf === -1,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,9 +86,7 @@ export class Options extends Component<Props, State> {
|
|||||||
speed: maxSpeed - optionState.effort,
|
speed: maxSpeed - optionState.effort,
|
||||||
quality: optionState.lossless ? 100 : optionState.quality,
|
quality: optionState.lossless ? 100 : optionState.quality,
|
||||||
progressive: optionState.progressive,
|
progressive: optionState.progressive,
|
||||||
epf: optionState.autoEdgePreservingFilter
|
epf: optionState.edgePreservingFilter,
|
||||||
? -1
|
|
||||||
: optionState.edgePreservingFilter,
|
|
||||||
nearLossless: 0,
|
nearLossless: 0,
|
||||||
lossyPalette: optionState.lossless ? optionState.slightLoss : false,
|
lossyPalette: optionState.lossless ? optionState.slightLoss : false,
|
||||||
};
|
};
|
||||||
@@ -116,7 +112,6 @@ export class Options extends Component<Props, State> {
|
|||||||
edgePreservingFilter,
|
edgePreservingFilter,
|
||||||
lossless,
|
lossless,
|
||||||
slightLoss,
|
slightLoss,
|
||||||
autoEdgePreservingFilter,
|
|
||||||
}: State,
|
}: State,
|
||||||
) {
|
) {
|
||||||
// I'm rendering both lossy and lossless forms, as it becomes much easier when
|
// I'm rendering both lossy and lossless forms, as it becomes much easier when
|
||||||
@@ -157,34 +152,16 @@ export class Options extends Component<Props, State> {
|
|||||||
Quality:
|
Quality:
|
||||||
</Range>
|
</Range>
|
||||||
</div>
|
</div>
|
||||||
<label class={style.optionInputFirst}>
|
<div class={style.optionOneCell}>
|
||||||
<Checkbox
|
<Range
|
||||||
name="autoEdgeFilter"
|
min="0"
|
||||||
checked={autoEdgePreservingFilter}
|
max="3"
|
||||||
onChange={this._inputChange(
|
value={edgePreservingFilter}
|
||||||
'autoEdgePreservingFilter',
|
onInput={this._inputChange('edgePreservingFilter', 'number')}
|
||||||
'boolean',
|
>
|
||||||
)}
|
Edge preserving filter:
|
||||||
/>
|
</Range>
|
||||||
Auto edge filter
|
</div>
|
||||||
</label>
|
|
||||||
<Expander>
|
|
||||||
{!autoEdgePreservingFilter && (
|
|
||||||
<div class={style.optionOneCell}>
|
|
||||||
<Range
|
|
||||||
min="0"
|
|
||||||
max="3"
|
|
||||||
value={edgePreservingFilter}
|
|
||||||
onInput={this._inputChange(
|
|
||||||
'edgePreservingFilter',
|
|
||||||
'number',
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
Edge preserving filter:
|
|
||||||
</Range>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Expander>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Expander>
|
</Expander>
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ export const label = 'JPEG XL (beta)';
|
|||||||
export const mimeType = 'image/jpegxl';
|
export const mimeType = 'image/jpegxl';
|
||||||
export const extension = 'jxl';
|
export const extension = 'jxl';
|
||||||
export const defaultOptions: EncodeOptions = {
|
export const defaultOptions: EncodeOptions = {
|
||||||
speed: 4,
|
speed: 5,
|
||||||
quality: 75,
|
quality: 50,
|
||||||
progressive: false,
|
progressive: false,
|
||||||
epf: -1,
|
epf: 2,
|
||||||
nearLossless: 0,
|
nearLossless: 0,
|
||||||
lossyPalette: false,
|
lossyPalette: false,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
import { EncodeOptions, UVMode, Csp } from '../shared/meta';
|
import { EncodeOptions } from '../shared/meta';
|
||||||
import { defaultOptions } from '../shared/meta';
|
|
||||||
import type WorkerBridge from 'client/lazy-app/worker-bridge';
|
import type WorkerBridge from 'client/lazy-app/worker-bridge';
|
||||||
import { h, Component } from 'preact';
|
import { h, Component } from 'preact';
|
||||||
import { preventDefault, shallowEqual } from 'client/lazy-app/util';
|
import { inputFieldValueAsNumber, preventDefault } from 'client/lazy-app/util';
|
||||||
import * as style from 'client/lazy-app/Compress/Options/style.css';
|
import * as style from 'client/lazy-app/Compress/Options/style.css';
|
||||||
import Range from 'client/lazy-app/Compress/Options/Range';
|
import Range from 'client/lazy-app/Compress/Options/Range';
|
||||||
import Select from 'client/lazy-app/Compress/Options/Select';
|
|
||||||
import Checkbox from 'client/lazy-app/Compress/Options/Checkbox';
|
|
||||||
import Expander from 'client/lazy-app/Compress/Options/Expander';
|
|
||||||
import linkState from 'linkstate';
|
|
||||||
|
|
||||||
export const encode = (
|
export const encode = (
|
||||||
signal: AbortSignal,
|
signal: AbortSignal,
|
||||||
@@ -23,286 +18,93 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
options: EncodeOptions;
|
|
||||||
effort: number;
|
|
||||||
quality: number;
|
|
||||||
alphaQuality: number;
|
|
||||||
passes: number;
|
|
||||||
sns: number;
|
|
||||||
uvMode: number;
|
|
||||||
lossless: boolean;
|
|
||||||
slightLoss: number;
|
|
||||||
colorSpace: number;
|
|
||||||
errorDiffusion: number;
|
|
||||||
useRandomMatrix: boolean;
|
|
||||||
showAdvanced: boolean;
|
showAdvanced: boolean;
|
||||||
separateAlpha: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Options extends Component<Props, State> {
|
export class Options extends Component<Props, State> {
|
||||||
static getDerivedStateFromProps(
|
|
||||||
props: Props,
|
|
||||||
state: State,
|
|
||||||
): Partial<State> | null {
|
|
||||||
if (state.options && shallowEqual(state.options, props.options)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { options } = props;
|
|
||||||
|
|
||||||
const modifyState: Partial<State> = {
|
|
||||||
options,
|
|
||||||
effort: options.speed,
|
|
||||||
alphaQuality: options.alpha_quality,
|
|
||||||
passes: options.pass,
|
|
||||||
sns: options.sns,
|
|
||||||
uvMode: options.uv_mode,
|
|
||||||
colorSpace: options.csp_type,
|
|
||||||
errorDiffusion: options.error_diffusion,
|
|
||||||
useRandomMatrix: options.use_random_matrix,
|
|
||||||
separateAlpha: options.quality !== options.alpha_quality,
|
|
||||||
};
|
|
||||||
|
|
||||||
// If quality is > 95, it's lossless with slight loss
|
|
||||||
if (options.quality > 95) {
|
|
||||||
modifyState.lossless = true;
|
|
||||||
modifyState.slightLoss = 100 - options.quality;
|
|
||||||
} else {
|
|
||||||
modifyState.quality = options.quality;
|
|
||||||
modifyState.lossless = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return modifyState;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Other state is set in getDerivedStateFromProps
|
|
||||||
state: State = {
|
state: State = {
|
||||||
lossless: false,
|
|
||||||
slightLoss: 0,
|
|
||||||
quality: defaultOptions.quality,
|
|
||||||
showAdvanced: false,
|
showAdvanced: false,
|
||||||
} as State;
|
|
||||||
|
|
||||||
private _inputChangeCallbacks = new Map<string, (event: Event) => void>();
|
|
||||||
|
|
||||||
private _inputChange = (prop: keyof State, type: 'number' | 'boolean') => {
|
|
||||||
// Cache the callback for performance
|
|
||||||
if (!this._inputChangeCallbacks.has(prop)) {
|
|
||||||
this._inputChangeCallbacks.set(prop, (event: Event) => {
|
|
||||||
const formEl = event.target as HTMLInputElement | HTMLSelectElement;
|
|
||||||
const newVal =
|
|
||||||
type === 'boolean'
|
|
||||||
? 'checked' in formEl
|
|
||||||
? formEl.checked
|
|
||||||
: !!formEl.value
|
|
||||||
: Number(formEl.value);
|
|
||||||
|
|
||||||
const newState: Partial<State> = {
|
|
||||||
[prop]: newVal,
|
|
||||||
};
|
|
||||||
|
|
||||||
const optionState = {
|
|
||||||
...this.state,
|
|
||||||
...newState,
|
|
||||||
};
|
|
||||||
|
|
||||||
const newOptions: EncodeOptions = {
|
|
||||||
speed: optionState.effort,
|
|
||||||
quality: optionState.lossless
|
|
||||||
? 100 - optionState.slightLoss
|
|
||||||
: optionState.quality,
|
|
||||||
alpha_quality: optionState.separateAlpha
|
|
||||||
? optionState.alphaQuality
|
|
||||||
: optionState.quality,
|
|
||||||
pass: optionState.passes,
|
|
||||||
sns: optionState.sns,
|
|
||||||
uv_mode: optionState.uvMode,
|
|
||||||
csp_type: optionState.colorSpace,
|
|
||||||
error_diffusion: optionState.errorDiffusion,
|
|
||||||
use_random_matrix: optionState.useRandomMatrix,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Updating options, so we don't recalculate in getDerivedStateFromProps.
|
|
||||||
newState.options = newOptions;
|
|
||||||
|
|
||||||
this.setState(newState);
|
|
||||||
|
|
||||||
this.props.onChange(newOptions);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._inputChangeCallbacks.get(prop)!;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render(
|
private onChange = (event: Event) => {
|
||||||
{}: Props,
|
const form = (event.currentTarget as HTMLInputElement).closest(
|
||||||
{
|
'form',
|
||||||
effort,
|
) as HTMLFormElement;
|
||||||
alphaQuality,
|
const { options } = this.props;
|
||||||
passes,
|
const newOptions: EncodeOptions = {
|
||||||
quality,
|
quality: inputFieldValueAsNumber(form.quality, options.quality),
|
||||||
sns,
|
alpha_quality: inputFieldValueAsNumber(
|
||||||
uvMode,
|
form.alpha_quality,
|
||||||
lossless,
|
options.alpha_quality,
|
||||||
slightLoss,
|
),
|
||||||
colorSpace,
|
speed: inputFieldValueAsNumber(form.speed, options.speed),
|
||||||
errorDiffusion,
|
pass: inputFieldValueAsNumber(form.pass, options.pass),
|
||||||
useRandomMatrix,
|
sns: inputFieldValueAsNumber(form.sns, options.sns),
|
||||||
separateAlpha,
|
};
|
||||||
showAdvanced,
|
this.props.onChange(newOptions);
|
||||||
}: State,
|
};
|
||||||
) {
|
|
||||||
|
render({ options }: Props) {
|
||||||
return (
|
return (
|
||||||
<form class={style.optionsSection} onSubmit={preventDefault}>
|
<form class={style.optionsSection} onSubmit={preventDefault}>
|
||||||
<label class={style.optionInputFirst}>
|
|
||||||
<Checkbox
|
|
||||||
checked={lossless}
|
|
||||||
onChange={this._inputChange('lossless', 'boolean')}
|
|
||||||
/>
|
|
||||||
Lossless
|
|
||||||
</label>
|
|
||||||
<Expander>
|
|
||||||
{lossless && (
|
|
||||||
<div class={style.optionOneCell}>
|
|
||||||
<Range
|
|
||||||
min="0"
|
|
||||||
max="5"
|
|
||||||
step="0.1"
|
|
||||||
value={slightLoss}
|
|
||||||
onInput={this._inputChange('slightLoss', 'number')}
|
|
||||||
>
|
|
||||||
Slight loss:
|
|
||||||
</Range>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Expander>
|
|
||||||
<Expander>
|
|
||||||
{!lossless && (
|
|
||||||
<div>
|
|
||||||
<div class={style.optionOneCell}>
|
|
||||||
<Range
|
|
||||||
min="0"
|
|
||||||
max="95"
|
|
||||||
step="0.1"
|
|
||||||
value={quality}
|
|
||||||
onInput={this._inputChange('quality', 'number')}
|
|
||||||
>
|
|
||||||
Quality:
|
|
||||||
</Range>
|
|
||||||
</div>
|
|
||||||
<label class={style.optionInputFirst}>
|
|
||||||
<Checkbox
|
|
||||||
checked={separateAlpha}
|
|
||||||
onChange={this._inputChange('separateAlpha', 'boolean')}
|
|
||||||
/>
|
|
||||||
Separate alpha quality
|
|
||||||
</label>
|
|
||||||
<Expander>
|
|
||||||
{separateAlpha && (
|
|
||||||
<div class={style.optionOneCell}>
|
|
||||||
<Range
|
|
||||||
min="0"
|
|
||||||
max="100"
|
|
||||||
step="1"
|
|
||||||
value={alphaQuality}
|
|
||||||
onInput={this._inputChange('alphaQuality', 'number')}
|
|
||||||
>
|
|
||||||
Alpha Quality:
|
|
||||||
</Range>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Expander>
|
|
||||||
<label class={style.optionInputFirst}>
|
|
||||||
<Checkbox
|
|
||||||
checked={showAdvanced}
|
|
||||||
onChange={linkState(this, 'showAdvanced')}
|
|
||||||
/>
|
|
||||||
Show advanced settings
|
|
||||||
</label>
|
|
||||||
<Expander>
|
|
||||||
{showAdvanced && (
|
|
||||||
<div>
|
|
||||||
<div class={style.optionOneCell}>
|
|
||||||
<Range
|
|
||||||
min="1"
|
|
||||||
max="10"
|
|
||||||
step="1"
|
|
||||||
value={passes}
|
|
||||||
onInput={this._inputChange('passes', 'number')}
|
|
||||||
>
|
|
||||||
Passes:
|
|
||||||
</Range>
|
|
||||||
</div>
|
|
||||||
<div class={style.optionOneCell}>
|
|
||||||
<Range
|
|
||||||
min="0"
|
|
||||||
max="100"
|
|
||||||
step="1"
|
|
||||||
value={sns}
|
|
||||||
onInput={this._inputChange('sns', 'number')}
|
|
||||||
>
|
|
||||||
Spatial noise shaping:
|
|
||||||
</Range>
|
|
||||||
</div>
|
|
||||||
<div class={style.optionOneCell}>
|
|
||||||
<Range
|
|
||||||
min="0"
|
|
||||||
max="100"
|
|
||||||
step="1"
|
|
||||||
value={errorDiffusion}
|
|
||||||
onInput={this._inputChange('errorDiffusion', 'number')}
|
|
||||||
>
|
|
||||||
Error diffusion:
|
|
||||||
</Range>
|
|
||||||
</div>
|
|
||||||
<label class={style.optionTextFirst}>
|
|
||||||
Subsample chroma:
|
|
||||||
<Select
|
|
||||||
value={uvMode}
|
|
||||||
onInput={this._inputChange('uvMode', 'number')}
|
|
||||||
>
|
|
||||||
<option value={UVMode.UVModeAuto}>Auto</option>
|
|
||||||
<option value={UVMode.UVModeAdapt}>Vary</option>
|
|
||||||
<option value={UVMode.UVMode420}>Half</option>
|
|
||||||
<option value={UVMode.UVMode444}>Off</option>
|
|
||||||
</Select>
|
|
||||||
</label>
|
|
||||||
<label class={style.optionTextFirst}>
|
|
||||||
Color space:
|
|
||||||
<Select
|
|
||||||
value={colorSpace}
|
|
||||||
onInput={this._inputChange('colorSpace', 'number')}
|
|
||||||
>
|
|
||||||
<option value={Csp.kYCoCg}>YCoCg</option>
|
|
||||||
<option value={Csp.kYCbCr}>YCbCr</option>
|
|
||||||
<option value={Csp.kYIQ}>YIQ</option>
|
|
||||||
</Select>
|
|
||||||
</label>
|
|
||||||
<label class={style.optionInputFirst}>
|
|
||||||
<Checkbox
|
|
||||||
checked={useRandomMatrix}
|
|
||||||
onChange={this._inputChange(
|
|
||||||
'useRandomMatrix',
|
|
||||||
'boolean',
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
Random matrix
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Expander>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Expander>
|
|
||||||
<div class={style.optionOneCell}>
|
<div class={style.optionOneCell}>
|
||||||
<Range
|
<Range
|
||||||
|
name="quality"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
step="1"
|
||||||
|
value={options.quality}
|
||||||
|
onInput={this.onChange}
|
||||||
|
>
|
||||||
|
Quality:
|
||||||
|
</Range>
|
||||||
|
</div>
|
||||||
|
<div class={style.optionOneCell}>
|
||||||
|
<Range
|
||||||
|
name="alpha_quality"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
step="1"
|
||||||
|
value={options.alpha_quality}
|
||||||
|
onInput={this.onChange}
|
||||||
|
>
|
||||||
|
Alpha Quality:
|
||||||
|
</Range>
|
||||||
|
</div>
|
||||||
|
<div class={style.optionOneCell}>
|
||||||
|
<Range
|
||||||
|
name="speed"
|
||||||
min="0"
|
min="0"
|
||||||
max="9"
|
max="9"
|
||||||
step="1"
|
step="1"
|
||||||
value={effort}
|
value={options.speed}
|
||||||
onInput={this._inputChange('effort', 'number')}
|
onInput={this.onChange}
|
||||||
>
|
>
|
||||||
Effort:
|
Speed:
|
||||||
|
</Range>
|
||||||
|
</div>
|
||||||
|
<div class={style.optionOneCell}>
|
||||||
|
<Range
|
||||||
|
name="pass"
|
||||||
|
min="1"
|
||||||
|
max="10"
|
||||||
|
step="1"
|
||||||
|
value={options.pass}
|
||||||
|
onInput={this.onChange}
|
||||||
|
>
|
||||||
|
Pass:
|
||||||
|
</Range>
|
||||||
|
</div>
|
||||||
|
<div class={style.optionOneCell}>
|
||||||
|
<Range
|
||||||
|
name="sns"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
step="1"
|
||||||
|
value={options.sns}
|
||||||
|
onInput={this.onChange}
|
||||||
|
>
|
||||||
|
Spatial noise shaping:
|
||||||
</Range>
|
</Range>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -11,21 +11,16 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import type { EncodeOptions } from 'codecs/wp2/enc/wp2_enc';
|
import type { EncodeOptions } from 'codecs/wp2/enc/wp2_enc';
|
||||||
import { UVMode, Csp } from 'codecs/wp2/enc/wp2_enc';
|
|
||||||
|
|
||||||
export { EncodeOptions, UVMode, Csp };
|
export { EncodeOptions };
|
||||||
|
|
||||||
export const label = 'WebP v2 (unstable)';
|
export const label = 'WebP v2 (unstable)';
|
||||||
export const mimeType = 'image/webp2';
|
export const mimeType = 'image/webp2';
|
||||||
export const extension = 'wp2';
|
export const extension = 'wp2';
|
||||||
export const defaultOptions: EncodeOptions = {
|
export const defaultOptions: EncodeOptions = {
|
||||||
quality: 75,
|
quality: 75,
|
||||||
alpha_quality: 75,
|
alpha_quality: 100,
|
||||||
speed: 5,
|
speed: 5,
|
||||||
pass: 1,
|
pass: 1,
|
||||||
sns: 50,
|
sns: 50,
|
||||||
uv_mode: UVMode.UVModeAuto,
|
|
||||||
csp_type: Csp.kYCoCg,
|
|
||||||
error_diffusion: 0,
|
|
||||||
use_random_matrix: false,
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user