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:
Ingvar Stepanyan
2019-08-01 17:01:25 +01:00
committed by Ingvar Stepanyan
parent 4621cbcae9
commit 629d64326d
34 changed files with 788 additions and 989 deletions

View File

@@ -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,

View File

@@ -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 cant run on SharedArrayBuffers, so we hard-cast to ArrayBuffer.
return result.buffer as ArrayBuffer;
}

View File

@@ -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';

View 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;
}

View File

@@ -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}

View File

@@ -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,
};

View File

@@ -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 })