mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-14 09:39:15 +00:00
Extra Wp2 Options (#853)
* wip * wip * Add extra options * Even more options! * Update src/features/encoders/wp2/client/index.tsx Co-authored-by: Surma <surma@surma.dev> Co-authored-by: Surma <surma@surma.dev>
This commit is contained in:
@@ -7,7 +7,31 @@ using namespace emscripten;
|
|||||||
|
|
||||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
thread_local const val Uint8Array = val::global("Uint8Array");
|
||||||
|
|
||||||
val encode(std::string image_in, int image_width, int image_height, WP2::EncoderConfig config) {
|
struct WP2Options {
|
||||||
|
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 =
|
||||||
@@ -27,12 +51,16 @@ val encode(std::string image_in, int image_width, int image_height, WP2::Encoder
|
|||||||
}
|
}
|
||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
value_object<WP2::EncoderConfig>("WP2EncoderConfig")
|
value_object<WP2Options>("WP2Options")
|
||||||
.field("quality", &WP2::EncoderConfig::quality)
|
.field("quality", &WP2Options::quality)
|
||||||
.field("alpha_quality", &WP2::EncoderConfig::alpha_quality)
|
.field("alpha_quality", &WP2Options::alpha_quality)
|
||||||
.field("speed", &WP2::EncoderConfig::speed)
|
.field("speed", &WP2Options::speed)
|
||||||
.field("pass", &WP2::EncoderConfig::pass)
|
.field("pass", &WP2Options::pass)
|
||||||
.field("sns", &WP2::EncoderConfig::sns);
|
.field("uv_mode", &WP2Options::uv_mode)
|
||||||
|
.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,6 +4,24 @@ 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 = {
|
||||||
p: function (a, b, c, d) {
|
t: 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 [];
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
c: function (a, b, c, d, e) {
|
d: function (a, b, c, d, e) {
|
||||||
function g(l) {
|
function g(l) {
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
@@ -1000,10 +1000,10 @@ var wp2_enc = (function () {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
q: function (a, b, c, d, e, g) {
|
p: 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: [] };
|
||||||
},
|
},
|
||||||
e: function (a, b, c, d, e, g, m, h, k, l) {
|
c: 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);
|
||||||
},
|
},
|
||||||
t: function (a, b, c, d) {
|
q: 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);
|
||||||
},
|
},
|
||||||
d: function (a) {
|
e: 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.
@@ -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">4:2:0</option>
|
<option value="1">Half</option>
|
||||||
{/*<option value="2">4:2:2</option>*/}
|
{/*<option value="2">4:2:2</option>*/}
|
||||||
<option value="3">4:4:4</option>
|
<option value="3">Off</option>
|
||||||
</Select>
|
</Select>
|
||||||
</label>
|
</label>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
import { EncodeOptions } from '../shared/meta';
|
import { EncodeOptions, UVMode, Csp } 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 { inputFieldValueAsNumber, preventDefault } from 'client/lazy-app/util';
|
import { preventDefault, shallowEqual } 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,
|
||||||
@@ -18,93 +23,286 @@ 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> {
|
||||||
state: State = {
|
static getDerivedStateFromProps(
|
||||||
showAdvanced: false,
|
props: Props,
|
||||||
};
|
state: State,
|
||||||
|
): Partial<State> | null {
|
||||||
|
if (state.options && shallowEqual(state.options, props.options)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private onChange = (event: Event) => {
|
const { options } = props;
|
||||||
const form = (event.currentTarget as HTMLInputElement).closest(
|
|
||||||
'form',
|
const modifyState: Partial<State> = {
|
||||||
) as HTMLFormElement;
|
options,
|
||||||
const { options } = this.props;
|
effort: options.speed,
|
||||||
const newOptions: EncodeOptions = {
|
alphaQuality: options.alpha_quality,
|
||||||
quality: inputFieldValueAsNumber(form.quality, options.quality),
|
passes: options.pass,
|
||||||
alpha_quality: inputFieldValueAsNumber(
|
sns: options.sns,
|
||||||
form.alpha_quality,
|
uvMode: options.uv_mode,
|
||||||
options.alpha_quality,
|
colorSpace: options.csp_type,
|
||||||
),
|
errorDiffusion: options.error_diffusion,
|
||||||
speed: inputFieldValueAsNumber(form.speed, options.speed),
|
useRandomMatrix: options.use_random_matrix,
|
||||||
pass: inputFieldValueAsNumber(form.pass, options.pass),
|
separateAlpha: options.quality !== options.alpha_quality,
|
||||||
sns: inputFieldValueAsNumber(form.sns, options.sns),
|
|
||||||
};
|
};
|
||||||
this.props.onChange(newOptions);
|
|
||||||
|
// 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 = {
|
||||||
|
lossless: false,
|
||||||
|
slightLoss: 0,
|
||||||
|
quality: defaultOptions.quality,
|
||||||
|
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({ options }: Props) {
|
render(
|
||||||
|
{}: Props,
|
||||||
|
{
|
||||||
|
effort,
|
||||||
|
alphaQuality,
|
||||||
|
passes,
|
||||||
|
quality,
|
||||||
|
sns,
|
||||||
|
uvMode,
|
||||||
|
lossless,
|
||||||
|
slightLoss,
|
||||||
|
colorSpace,
|
||||||
|
errorDiffusion,
|
||||||
|
useRandomMatrix,
|
||||||
|
separateAlpha,
|
||||||
|
showAdvanced,
|
||||||
|
}: State,
|
||||||
|
) {
|
||||||
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={options.speed}
|
value={effort}
|
||||||
onInput={this.onChange}
|
onInput={this._inputChange('effort', 'number')}
|
||||||
>
|
>
|
||||||
Speed:
|
Effort:
|
||||||
</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,16 +11,21 @@
|
|||||||
* 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 };
|
export { EncodeOptions, UVMode, Csp };
|
||||||
|
|
||||||
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: 100,
|
alpha_quality: 75,
|
||||||
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