# Conflicts:
#	codecs/cpp.Dockerfile
#	codecs/imagequant/example.html
#	codecs/webp/dec/webp_dec.d.ts
#	codecs/webp/dec/webp_dec.js
#	codecs/webp/dec/webp_dec.wasm
#	codecs/webp/enc/webp_enc.d.ts
#	codecs/webp/enc/webp_enc.js
#	codecs/webp/enc/webp_enc.wasm
#	package-lock.json
#	package.json
#	src/codecs/tiny.webp
#	src_old/codecs/encoders.ts
#	src_old/codecs/processor-worker/tiny.avif
#	src_old/codecs/processor-worker/tiny.webp
#	src_old/codecs/tiny.webp
#	src_old/components/compress/index.tsx
#	src_old/lib/util.ts
#	src_old/sw/util.ts
This commit is contained in:
Jake Archibald
2020-09-16 09:59:24 +01:00
parent dfee848a39
commit a6477b82fc
202 changed files with 10435 additions and 16953 deletions

View File

@@ -0,0 +1,100 @@
import { h, Component } from 'preact';
import { bind } from '../../lib/initial-util';
import {
inputFieldValueAsNumber,
konami,
preventDefault,
} from '../../lib/util';
import { QuantizeOptions } from './processor-meta';
import * as style from '../../components/Options/style.scss';
import Expander from '../../components/expander';
import Select from '../../components/select';
import Range from '../../components/range';
const konamiPromise = konami();
interface Props {
options: QuantizeOptions;
onChange(newOptions: QuantizeOptions): void;
}
interface State {
extendedSettings: boolean;
}
export default class QuantizerOptions extends Component<Props, State> {
state: State = { extendedSettings: false };
componentDidMount() {
konamiPromise.then(() => {
this.setState({ extendedSettings: true });
});
}
@bind
onChange(event: Event) {
const form = (event.currentTarget as HTMLInputElement).closest(
'form',
) as HTMLFormElement;
const { options } = this.props;
const newOptions: QuantizeOptions = {
zx: inputFieldValueAsNumber(form.zx, options.zx),
maxNumColors: inputFieldValueAsNumber(
form.maxNumColors,
options.maxNumColors,
),
dither: inputFieldValueAsNumber(form.dither),
};
this.props.onChange(newOptions);
}
render({ options }: Props, { extendedSettings }: State) {
return (
<form class={style.optionsSection} onSubmit={preventDefault}>
<Expander>
{extendedSettings ? (
<label class={style.optionTextFirst}>
Type:
<Select
name="zx"
value={'' + options.zx}
onChange={this.onChange}
>
<option value="0">Standard</option>
<option value="1">ZX</option>
</Select>
</label>
) : null}
</Expander>
<Expander>
{options.zx ? null : (
<div class={style.optionOneCell}>
<Range
name="maxNumColors"
min="2"
max="256"
value={options.maxNumColors}
onInput={this.onChange}
>
Colors:
</Range>
</div>
)}
</Expander>
<div class={style.optionOneCell}>
<Range
name="dither"
min="0"
max="1"
step="0.01"
value={options.dither}
onInput={this.onChange}
>
Dithering:
</Range>
</div>
</form>
);
}
}

View File

@@ -0,0 +1,11 @@
export interface QuantizeOptions {
zx: number;
maxNumColors: number;
dither: number;
}
export const defaultOptions: QuantizeOptions = {
zx: 0,
maxNumColors: 256,
dither: 1.0,
};

View File

@@ -0,0 +1,30 @@
import imagequant, {
QuantizerModule,
} from '../../../codecs/imagequant/imagequant';
import wasmUrl from '../../../codecs/imagequant/imagequant.wasm';
import { QuantizeOptions } from './processor-meta';
import { initEmscriptenModule } from '../util';
let emscriptenModule: Promise<QuantizerModule>;
export async function process(
data: ImageData,
opts: QuantizeOptions,
): Promise<ImageData> {
if (!emscriptenModule)
emscriptenModule = initEmscriptenModule(imagequant, wasmUrl);
const module = await emscriptenModule;
const result = opts.zx
? module.zx_quantize(data.data, data.width, data.height, opts.dither)
: module.quantize(
data.data,
data.width,
data.height,
opts.maxNumColors,
opts.dither,
);
return new ImageData(result, data.width, data.height);
}