mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-18 19:49:04 +00:00
Swap OptiPNG with OxiPNG
This makes building simpler and allows us to potentially use multithreading version in the future. For now points to a custom fork of OxiPNG that enables WebAssembly support, as PR is still pending review.
This commit is contained in:
committed by
Ingvar Stepanyan
parent
4621cbcae9
commit
629d64326d
@@ -1,5 +1,5 @@
|
||||
import * as identity from './identity/encoder-meta';
|
||||
import * as optiPNG from './optipng/encoder-meta';
|
||||
import * as oxiPNG from './oxipng/encoder-meta';
|
||||
import * as mozJPEG from './mozjpeg/encoder-meta';
|
||||
import * as webP from './webp/encoder-meta';
|
||||
import * as browserPNG from './browser-png/encoder-meta';
|
||||
@@ -17,7 +17,7 @@ export interface EncoderSupportMap {
|
||||
|
||||
export type EncoderState =
|
||||
identity.EncoderState |
|
||||
optiPNG.EncoderState |
|
||||
oxiPNG.EncoderState |
|
||||
mozJPEG.EncoderState |
|
||||
webP.EncoderState |
|
||||
browserPNG.EncoderState |
|
||||
@@ -31,7 +31,7 @@ export type EncoderState =
|
||||
|
||||
export type EncoderOptions =
|
||||
identity.EncodeOptions |
|
||||
optiPNG.EncodeOptions |
|
||||
oxiPNG.EncodeOptions |
|
||||
mozJPEG.EncodeOptions |
|
||||
webP.EncodeOptions |
|
||||
browserPNG.EncodeOptions |
|
||||
@@ -47,7 +47,7 @@ export type EncoderType = keyof typeof encoderMap;
|
||||
|
||||
export const encoderMap = {
|
||||
[identity.type]: identity,
|
||||
[optiPNG.type]: optiPNG,
|
||||
[oxiPNG.type]: oxiPNG,
|
||||
[mozJPEG.type]: mozJPEG,
|
||||
[webP.type]: webP,
|
||||
[browserPNG.type]: browserPNG,
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import optipng, { OptiPngModule } from '../../../codecs/optipng/optipng';
|
||||
import wasmUrl from '../../../codecs/optipng/optipng.wasm';
|
||||
import { EncodeOptions } from './encoder-meta';
|
||||
import { initEmscriptenModule } from '../util';
|
||||
|
||||
let emscriptenModule: Promise<OptiPngModule>;
|
||||
|
||||
export async function compress(data: BufferSource, options: EncodeOptions): Promise<ArrayBuffer> {
|
||||
if (!emscriptenModule) emscriptenModule = initEmscriptenModule(optipng, wasmUrl);
|
||||
|
||||
const module = await emscriptenModule;
|
||||
const resultView = module.compress(data, options);
|
||||
const result = new Uint8Array(resultView);
|
||||
module.free_result();
|
||||
|
||||
// wasm can’t run on SharedArrayBuffers, so we hard-cast to ArrayBuffer.
|
||||
return result.buffer as ArrayBuffer;
|
||||
}
|
||||
@@ -4,7 +4,7 @@ export interface EncodeOptions {
|
||||
export interface EncoderState { type: typeof type; options: EncodeOptions; }
|
||||
|
||||
export const type = 'png';
|
||||
export const label = 'OptiPNG';
|
||||
export const label = 'OxiPNG';
|
||||
export const mimeType = 'image/png';
|
||||
export const extension = 'png';
|
||||
|
||||
6
src/codecs/oxipng/encoder.ts
Normal file
6
src/codecs/oxipng/encoder.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { optimise } from '../../../codecs/oxipng/pkg';
|
||||
import { EncodeOptions } from './encoder-meta';
|
||||
|
||||
export async function compress(data: ArrayBuffer, options: EncodeOptions): Promise<ArrayBuffer> {
|
||||
return optimise(new Uint8Array(data), options.level).buffer;
|
||||
}
|
||||
@@ -10,7 +10,7 @@ type Props = {
|
||||
onChange(newOptions: EncodeOptions): void;
|
||||
};
|
||||
|
||||
export default class OptiPNGEncoderOptions extends Component<Props, {}> {
|
||||
export default class OxiPNGEncoderOptions extends Component<Props, {}> {
|
||||
@bind
|
||||
onChange(event: Event) {
|
||||
const form = (event.currentTarget as HTMLInputElement).closest('form') as HTMLFormElement;
|
||||
@@ -28,7 +28,7 @@ export default class OptiPNGEncoderOptions extends Component<Props, {}> {
|
||||
<Range
|
||||
name="level"
|
||||
min="0"
|
||||
max="7"
|
||||
max="6"
|
||||
step="1"
|
||||
value={options.level}
|
||||
onInput={this.onChange}
|
||||
@@ -57,13 +57,13 @@ async function resize(
|
||||
return timed('resize', () => resize(data, opts));
|
||||
}
|
||||
|
||||
async function optiPngEncode(
|
||||
data: BufferSource, options: import('../optipng/encoder-meta').EncodeOptions,
|
||||
async function oxiPngEncode(
|
||||
data: ArrayBuffer, options: import('../oxipng/encoder-meta').EncodeOptions,
|
||||
): Promise<ArrayBuffer> {
|
||||
const { compress } = await import(
|
||||
/* webpackChunkName: "process-optipng" */
|
||||
'../optipng/encoder');
|
||||
return timed('optiPngEncode', () => compress(data, options));
|
||||
/* webpackChunkName: "process-oxipng" */
|
||||
'../oxipng/encoder');
|
||||
return timed('oxiPngEncode', () => compress(data, options));
|
||||
}
|
||||
|
||||
async function webpEncode(
|
||||
@@ -87,7 +87,7 @@ const exports = {
|
||||
quantize,
|
||||
rotate,
|
||||
resize,
|
||||
optiPngEncode,
|
||||
oxiPngEncode,
|
||||
webpEncode,
|
||||
webpDecode,
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import { proxy } from 'comlink';
|
||||
import { QuantizeOptions } from './imagequant/processor-meta';
|
||||
import { canvasEncode, blobToArrayBuffer } from '../lib/util';
|
||||
import { EncodeOptions as MozJPEGEncoderOptions } from './mozjpeg/encoder-meta';
|
||||
import { EncodeOptions as OptiPNGEncoderOptions } from './optipng/encoder-meta';
|
||||
import { EncodeOptions as OxiPNGEncoderOptions } from './oxipng/encoder-meta';
|
||||
import { EncodeOptions as WebPEncoderOptions } from './webp/encoder-meta';
|
||||
import { EncodeOptions as BrowserJPEGOptions } from './browser-jpeg/encoder-meta';
|
||||
import { EncodeOptions as BrowserWebpEncodeOptions } from './browser-webp/encoder-meta';
|
||||
@@ -143,13 +143,13 @@ export default class Processor {
|
||||
}
|
||||
|
||||
@Processor._processingJob({ needsWorker: true })
|
||||
async optiPngEncode(
|
||||
data: ImageData, opts: OptiPNGEncoderOptions,
|
||||
async oxiPngEncode(
|
||||
data: ImageData, opts: OxiPNGEncoderOptions,
|
||||
): Promise<ArrayBuffer> {
|
||||
// OptiPNG expects PNG input.
|
||||
// OxiPNG expects PNG input.
|
||||
const pngBlob = await canvasEncode(data, 'image/png');
|
||||
const pngBuffer = await blobToArrayBuffer(pngBlob);
|
||||
return this._workerApi!.optiPngEncode(pngBuffer, opts);
|
||||
return this._workerApi!.oxiPngEncode(pngBuffer, opts);
|
||||
}
|
||||
|
||||
@Processor._processingJob({ needsWorker: true })
|
||||
|
||||
Reference in New Issue
Block a user