mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-15 10:09:45 +00:00
Update libavif (#1381)
* Update libavif (v1.0.0-main) * Update libavif for improved compression and speed * v1.0.0 deprecates usage of min and max-quantizers; we use `quality` and `qualityAlpha` instead * Renamed `maxSpeed` to `MAX_EFFORT` for better readability * Update libavif (v1.0.1-main) * Refactor variable names for clarity * Update libaom (v3.7.0) * Add checks for API return values * Rename variables for readability Changes `cqlevel` to `quality`, and `cqAlphaLevel` to `qualityAlpha` * Minor patches in logic * Minor patches in lossless calculation * Add chroma subsampling options to AVIF * Add skeleton for sharp downsampling param * Try to use libsharpyuv * Encoder working, decoder isnt * Make sure sharpyuv is disabled for decoder * Add AVIF_LOCAL flags for sharp yuv * Get AVIF sharp YUV working * Clean up AVIF makefiles * AVIF: Make sharpyuv conditional on subsample * AVIF: Flags to speed up sharpyuv build * AVIF: Minor refactoring in enc.cpp * AVIF: Minor refactoring & renaming * AVIF: Use smart pointers to prevent memory leaks * AVIF: Minor refactoring * AVIF: Revert defaultoptions logic change --------- Co-authored-by: Surma <surma@surma.dev> Co-authored-by: Jake Archibald <jaffathecake@gmail.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { EncodeOptions, defaultOptions, AVIFTune } from '../shared/meta';
|
||||
import { EncodeOptions, AVIFTune, defaultOptions } from '../shared/meta';
|
||||
import type WorkerBridge from 'client/lazy-app/worker-bridge';
|
||||
import { h, Component } from 'preact';
|
||||
import { preventDefault, shallowEqual } from 'client/lazy-app/util';
|
||||
@@ -36,12 +36,20 @@ interface State {
|
||||
effort: number;
|
||||
sharpness: number;
|
||||
denoiseLevel: number;
|
||||
aqMode: number;
|
||||
tune: AVIFTune;
|
||||
enableSharpYUV: boolean;
|
||||
}
|
||||
|
||||
const maxQuant = 63;
|
||||
const maxSpeed = 10;
|
||||
/**
|
||||
* AVIF quality ranges from 0 (worst) to 100 (lossless).
|
||||
* Since lossless is a separate checkbox, we cap user-inputted quality at 99
|
||||
*
|
||||
* AVIF speed ranges from 0 (slowest) to 10 (fastest).
|
||||
* We display it as 'effort' to the user since it conveys the speed-size tradeoff
|
||||
* much better: speed = 10 - effort
|
||||
*/
|
||||
const MAX_QUALITY = 100;
|
||||
const MAX_EFFORT = 10;
|
||||
|
||||
export class Options extends Component<Props, State> {
|
||||
static getDerivedStateFromProps(
|
||||
@@ -55,34 +63,28 @@ export class Options extends Component<Props, State> {
|
||||
const { options } = props;
|
||||
|
||||
const lossless =
|
||||
options.cqLevel === 0 &&
|
||||
options.cqAlphaLevel <= 0 &&
|
||||
options.quality === MAX_QUALITY &&
|
||||
(options.qualityAlpha == -1 || options.qualityAlpha == MAX_QUALITY) &&
|
||||
options.subsample == 3;
|
||||
|
||||
const separateAlpha = options.cqAlphaLevel !== -1;
|
||||
|
||||
const cqLevel = lossless ? defaultOptions.cqLevel : options.cqLevel;
|
||||
const separateAlpha = options.qualityAlpha !== -1;
|
||||
|
||||
// Create default form state from options
|
||||
return {
|
||||
options,
|
||||
lossless,
|
||||
quality: maxQuant - cqLevel,
|
||||
quality: lossless ? defaultOptions.quality : options.quality,
|
||||
separateAlpha,
|
||||
alphaQuality:
|
||||
maxQuant -
|
||||
(separateAlpha ? options.cqAlphaLevel : defaultOptions.cqLevel),
|
||||
subsample:
|
||||
options.subsample === 0 || lossless
|
||||
? defaultOptions.subsample
|
||||
: options.subsample,
|
||||
alphaQuality: separateAlpha ? options.qualityAlpha : options.quality,
|
||||
subsample: options.subsample,
|
||||
tileRows: options.tileRowsLog2,
|
||||
tileCols: options.tileColsLog2,
|
||||
effort: maxSpeed - options.speed,
|
||||
effort: MAX_EFFORT - options.speed,
|
||||
chromaDeltaQ: options.chromaDeltaQ,
|
||||
sharpness: options.sharpness,
|
||||
denoiseLevel: options.denoiseLevel,
|
||||
tune: options.tune,
|
||||
enableSharpYUV: options.enableSharpYUV,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -120,20 +122,21 @@ export class Options extends Component<Props, State> {
|
||||
};
|
||||
|
||||
const newOptions: EncodeOptions = {
|
||||
cqLevel: optionState.lossless ? 0 : maxQuant - optionState.quality,
|
||||
cqAlphaLevel:
|
||||
quality: optionState.lossless ? MAX_QUALITY : optionState.quality,
|
||||
qualityAlpha:
|
||||
optionState.lossless || !optionState.separateAlpha
|
||||
? -1
|
||||
: maxQuant - optionState.alphaQuality,
|
||||
? -1 // Set qualityAlpha to quality
|
||||
: optionState.alphaQuality,
|
||||
// Always set to 4:4:4 if lossless
|
||||
subsample: optionState.lossless ? 3 : optionState.subsample,
|
||||
tileColsLog2: optionState.tileCols,
|
||||
tileRowsLog2: optionState.tileRows,
|
||||
speed: maxSpeed - optionState.effort,
|
||||
speed: MAX_EFFORT - optionState.effort,
|
||||
chromaDeltaQ: optionState.chromaDeltaQ,
|
||||
sharpness: optionState.sharpness,
|
||||
denoiseLevel: optionState.denoiseLevel,
|
||||
tune: optionState.tune,
|
||||
enableSharpYUV: optionState.enableSharpYUV,
|
||||
};
|
||||
|
||||
// Updating options, so we don't recalculate in getDerivedStateFromProps.
|
||||
@@ -167,6 +170,7 @@ export class Options extends Component<Props, State> {
|
||||
sharpness,
|
||||
denoiseLevel,
|
||||
tune,
|
||||
enableSharpYUV,
|
||||
}: State,
|
||||
) {
|
||||
return (
|
||||
@@ -183,7 +187,7 @@ export class Options extends Component<Props, State> {
|
||||
<div class={style.optionOneCell}>
|
||||
<Range
|
||||
min="0"
|
||||
max="63"
|
||||
max={MAX_QUALITY - 1} // MAX_QUALITY would mean lossless
|
||||
value={quality}
|
||||
onInput={this._inputChange('quality', 'number')}
|
||||
>
|
||||
@@ -211,11 +215,26 @@ export class Options extends Component<Props, State> {
|
||||
value={subsample}
|
||||
onChange={this._inputChange('subsample', 'number')}
|
||||
>
|
||||
<option value="1">Half</option>
|
||||
{/*<option value="2">4:2:2</option>*/}
|
||||
<option value="3">Off</option>
|
||||
<option value="0">4:0:0</option>
|
||||
<option value="1">4:2:0</option>
|
||||
<option value="2">4:2:2</option>
|
||||
<option value="3">4:4:4</option>
|
||||
</Select>
|
||||
</label>
|
||||
<Expander>
|
||||
{subsample === 1 && (
|
||||
<label class={style.optionToggle}>
|
||||
Sharp YUV Downsampling
|
||||
<Checkbox
|
||||
checked={enableSharpYUV}
|
||||
onChange={this._inputChange(
|
||||
'enableSharpYUV',
|
||||
'boolean',
|
||||
)}
|
||||
/>
|
||||
</label>
|
||||
)}
|
||||
</Expander>
|
||||
<label class={style.optionToggle}>
|
||||
Separate alpha quality
|
||||
<Checkbox
|
||||
@@ -228,7 +247,7 @@ export class Options extends Component<Props, State> {
|
||||
<div class={style.optionOneCell}>
|
||||
<Range
|
||||
min="0"
|
||||
max="63"
|
||||
max={MAX_QUALITY - 1} // MAX_QUALITY would mean lossless
|
||||
value={alphaQuality}
|
||||
onInput={this._inputChange(
|
||||
'alphaQuality',
|
||||
@@ -307,7 +326,7 @@ export class Options extends Component<Props, State> {
|
||||
<div class={style.optionOneCell}>
|
||||
<Range
|
||||
min="0"
|
||||
max="10"
|
||||
max={MAX_EFFORT}
|
||||
value={effort}
|
||||
onInput={this._inputChange('effort', 'number')}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user