forked from external-repos/squoosh
Merge remote-tracking branch 'origin/dev' into visdif-error
This commit is contained in:
4
codecs/resize/pkg/squoosh_resize.d.ts
generated
vendored
4
codecs/resize/pkg/squoosh_resize.d.ts
generated
vendored
@@ -9,9 +9,9 @@
|
|||||||
* @param {number} typ_idx
|
* @param {number} typ_idx
|
||||||
* @param {boolean} premultiply
|
* @param {boolean} premultiply
|
||||||
* @param {boolean} color_space_conversion
|
* @param {boolean} color_space_conversion
|
||||||
* @returns {Uint8Array}
|
* @returns {Uint8ClampedArray}
|
||||||
*/
|
*/
|
||||||
export function resize(input_image: Uint8Array, input_width: number, input_height: number, output_width: number, output_height: number, typ_idx: number, premultiply: boolean, color_space_conversion: boolean): Uint8Array;
|
export function resize(input_image: Uint8Array, input_width: number, input_height: number, output_width: number, output_height: number, typ_idx: number, premultiply: boolean, color_space_conversion: boolean): Uint8ClampedArray;
|
||||||
|
|
||||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||||
|
|
||||||
|
|||||||
16
codecs/resize/pkg/squoosh_resize.js
generated
16
codecs/resize/pkg/squoosh_resize.js
generated
@@ -26,8 +26,16 @@ function getInt32Memory0() {
|
|||||||
return cachegetInt32Memory0;
|
return cachegetInt32Memory0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getArrayU8FromWasm0(ptr, len) {
|
let cachegetUint8ClampedMemory0 = null;
|
||||||
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
function getUint8ClampedMemory0() {
|
||||||
|
if (cachegetUint8ClampedMemory0 === null || cachegetUint8ClampedMemory0.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetUint8ClampedMemory0 = new Uint8ClampedArray(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetUint8ClampedMemory0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getClampedArrayU8FromWasm0(ptr, len) {
|
||||||
|
return getUint8ClampedMemory0().subarray(ptr / 1, ptr / 1 + len);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {Uint8Array} input_image
|
* @param {Uint8Array} input_image
|
||||||
@@ -38,7 +46,7 @@ function getArrayU8FromWasm0(ptr, len) {
|
|||||||
* @param {number} typ_idx
|
* @param {number} typ_idx
|
||||||
* @param {boolean} premultiply
|
* @param {boolean} premultiply
|
||||||
* @param {boolean} color_space_conversion
|
* @param {boolean} color_space_conversion
|
||||||
* @returns {Uint8Array}
|
* @returns {Uint8ClampedArray}
|
||||||
*/
|
*/
|
||||||
export function resize(input_image, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion) {
|
export function resize(input_image, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion) {
|
||||||
try {
|
try {
|
||||||
@@ -48,7 +56,7 @@ export function resize(input_image, input_width, input_height, output_width, out
|
|||||||
wasm.resize(retptr, ptr0, len0, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion);
|
wasm.resize(retptr, ptr0, len0, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion);
|
||||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||||
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
var v1 = getClampedArrayU8FromWasm0(r0, r1).slice();
|
||||||
wasm.__wbindgen_free(r0, r1 * 1);
|
wasm.__wbindgen_free(r0, r1 * 1);
|
||||||
return v1;
|
return v1;
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
Binary file not shown.
7
codecs/resize/pkg/squoosh_resize_bg.wasm.d.ts
generated
vendored
Normal file
7
codecs/resize/pkg/squoosh_resize_bg.wasm.d.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export const memory: WebAssembly.Memory;
|
||||||
|
export function resize(a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number): void;
|
||||||
|
export function __wbindgen_add_to_stack_pointer(a: number): number;
|
||||||
|
export function __wbindgen_malloc(a: number): number;
|
||||||
|
export function __wbindgen_free(a: number, b: number): void;
|
||||||
@@ -8,6 +8,7 @@ use cfg_if::cfg_if;
|
|||||||
use resize::Pixel;
|
use resize::Pixel;
|
||||||
use resize::Type;
|
use resize::Type;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
use wasm_bindgen::Clamped;
|
||||||
|
|
||||||
mod srgb;
|
mod srgb;
|
||||||
use srgb::{linear_to_srgb, Clamp};
|
use srgb::{linear_to_srgb, Clamp};
|
||||||
@@ -66,7 +67,7 @@ pub fn resize(
|
|||||||
typ_idx: usize,
|
typ_idx: usize,
|
||||||
premultiply: bool,
|
premultiply: bool,
|
||||||
color_space_conversion: bool,
|
color_space_conversion: bool,
|
||||||
) -> Vec<u8> {
|
) -> Clamped<Vec<u8>> {
|
||||||
let typ = match typ_idx {
|
let typ = match typ_idx {
|
||||||
0 => Type::Triangle,
|
0 => Type::Triangle,
|
||||||
1 => Type::Catrom,
|
1 => Type::Catrom,
|
||||||
@@ -91,7 +92,7 @@ pub fn resize(
|
|||||||
typ,
|
typ,
|
||||||
);
|
);
|
||||||
resizer.resize(input_image.as_slice(), output_image.as_mut_slice());
|
resizer.resize(input_image.as_slice(), output_image.as_mut_slice());
|
||||||
return output_image;
|
return Clamped(output_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, we convert to f32 images to keep the
|
// Otherwise, we convert to f32 images to keep the
|
||||||
@@ -138,5 +139,5 @@ pub fn resize(
|
|||||||
.clamp(0.0, 255.0) as u8;
|
.clamp(0.0, 255.0) as u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
return output_image;
|
return Clamped(output_image);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ The returned `image` object is a representation of the original image, that you
|
|||||||
When an image has been ingested, you can start preprocessing it and encoding it to other formats. This example will resize the image and then encode it to a `.jpg` and `.jxl` image:
|
When an image has been ingested, you can start preprocessing it and encoding it to other formats. This example will resize the image and then encode it to a `.jpg` and `.jxl` image:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
await image.decoded; //Wait until the image is decoded before running preprocessors
|
await image.decoded; //Wait until the image is decoded before running preprocessors.
|
||||||
|
|
||||||
const preprocessOptions: {
|
const preprocessOptions = {
|
||||||
resize: {
|
resize: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
width: 100,
|
width: 100,
|
||||||
@@ -50,7 +50,7 @@ const preprocessOptions: {
|
|||||||
}
|
}
|
||||||
await image.preprocess(preprocessOptions);
|
await image.preprocess(preprocessOptions);
|
||||||
|
|
||||||
const encodeOptions: {
|
const encodeOptions = {
|
||||||
mozjpeg: {}, //an empty object means 'use default settings'
|
mozjpeg: {}, //an empty object means 'use default settings'
|
||||||
jxl: {
|
jxl: {
|
||||||
quality: 90,
|
quality: 90,
|
||||||
|
|||||||
132
libsquoosh/src/WebAssembly.d.ts
vendored
Normal file
132
libsquoosh/src/WebAssembly.d.ts
vendored
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
/**
|
||||||
|
* WebAssembly definitions are not available in `@types/node` yet,
|
||||||
|
* so these are copied from `lib.dom.d.ts`
|
||||||
|
*/
|
||||||
|
declare namespace WebAssembly {
|
||||||
|
interface CompileError {}
|
||||||
|
|
||||||
|
var CompileError: {
|
||||||
|
prototype: CompileError;
|
||||||
|
new (): CompileError;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Global {
|
||||||
|
value: any;
|
||||||
|
valueOf(): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
var Global: {
|
||||||
|
prototype: Global;
|
||||||
|
new (descriptor: GlobalDescriptor, v?: any): Global;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Instance {
|
||||||
|
readonly exports: Exports;
|
||||||
|
}
|
||||||
|
|
||||||
|
var Instance: {
|
||||||
|
prototype: Instance;
|
||||||
|
new (module: Module, importObject?: Imports): Instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface LinkError {}
|
||||||
|
|
||||||
|
var LinkError: {
|
||||||
|
prototype: LinkError;
|
||||||
|
new (): LinkError;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Memory {
|
||||||
|
readonly buffer: ArrayBuffer;
|
||||||
|
grow(delta: number): number;
|
||||||
|
}
|
||||||
|
|
||||||
|
var Memory: {
|
||||||
|
prototype: Memory;
|
||||||
|
new (descriptor: MemoryDescriptor): Memory;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Module {}
|
||||||
|
|
||||||
|
var Module: {
|
||||||
|
prototype: Module;
|
||||||
|
new (bytes: BufferSource): Module;
|
||||||
|
customSections(moduleObject: Module, sectionName: string): ArrayBuffer[];
|
||||||
|
exports(moduleObject: Module): ModuleExportDescriptor[];
|
||||||
|
imports(moduleObject: Module): ModuleImportDescriptor[];
|
||||||
|
};
|
||||||
|
|
||||||
|
interface RuntimeError {}
|
||||||
|
|
||||||
|
var RuntimeError: {
|
||||||
|
prototype: RuntimeError;
|
||||||
|
new (): RuntimeError;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Table {
|
||||||
|
readonly length: number;
|
||||||
|
get(index: number): Function | null;
|
||||||
|
grow(delta: number): number;
|
||||||
|
set(index: number, value: Function | null): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
var Table: {
|
||||||
|
prototype: Table;
|
||||||
|
new (descriptor: TableDescriptor): Table;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface GlobalDescriptor {
|
||||||
|
mutable?: boolean;
|
||||||
|
value: ValueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MemoryDescriptor {
|
||||||
|
initial: number;
|
||||||
|
maximum?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ModuleExportDescriptor {
|
||||||
|
kind: ImportExportKind;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ModuleImportDescriptor {
|
||||||
|
kind: ImportExportKind;
|
||||||
|
module: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TableDescriptor {
|
||||||
|
element: TableKind;
|
||||||
|
initial: number;
|
||||||
|
maximum?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WebAssemblyInstantiatedSource {
|
||||||
|
instance: Instance;
|
||||||
|
module: Module;
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImportExportKind = 'function' | 'global' | 'memory' | 'table';
|
||||||
|
type TableKind = 'anyfunc';
|
||||||
|
type ValueType = 'f32' | 'f64' | 'i32' | 'i64';
|
||||||
|
type ExportValue = Function | Global | Memory | Table;
|
||||||
|
type Exports = Record<string, ExportValue>;
|
||||||
|
type ImportValue = ExportValue | number;
|
||||||
|
type ModuleImports = Record<string, ImportValue>;
|
||||||
|
type Imports = Record<string, ModuleImports>;
|
||||||
|
function compile(bytes: BufferSource): Promise<Module>;
|
||||||
|
// `compileStreaming` does not exist in NodeJS
|
||||||
|
// function compileStreaming(source: Response | Promise<Response>): Promise<Module>;
|
||||||
|
function instantiate(
|
||||||
|
bytes: BufferSource,
|
||||||
|
importObject?: Imports,
|
||||||
|
): Promise<WebAssemblyInstantiatedSource>;
|
||||||
|
function instantiate(
|
||||||
|
moduleObject: Module,
|
||||||
|
importObject?: Imports,
|
||||||
|
): Promise<Instance>;
|
||||||
|
// `instantiateStreaming` does not exist in NodeJS
|
||||||
|
// function instantiateStreaming(response: Response | PromiseLike<Response>, importObject?: Imports): Promise<WebAssemblyInstantiatedSource>;
|
||||||
|
function validate(bytes: BufferSource): boolean;
|
||||||
|
}
|
||||||
@@ -1,6 +1,37 @@
|
|||||||
import { promises as fsp } from 'fs';
|
import { promises as fsp } from 'fs';
|
||||||
import { instantiateEmscriptenWasm, pathify } from './emscripten-utils.js';
|
import { instantiateEmscriptenWasm, pathify } from './emscripten-utils.js';
|
||||||
|
|
||||||
|
interface RotateModuleInstance {
|
||||||
|
exports: {
|
||||||
|
memory: WebAssembly.Memory;
|
||||||
|
rotate(width: number, height: number, rotate: number): void;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ResizeWithAspectParams {
|
||||||
|
input_width: number;
|
||||||
|
input_height: number;
|
||||||
|
target_width: number;
|
||||||
|
target_height: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ResizeInstantiateOptions {
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
method: string;
|
||||||
|
premultiply: boolean;
|
||||||
|
linearRGB: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
// Needed for being able to use ImageData as type in codec types
|
||||||
|
type ImageData = typeof import('./image_data.js');
|
||||||
|
// Needed for being able to assign to `globalThis.ImageData`
|
||||||
|
var ImageData: ImageData['constructor'];
|
||||||
|
}
|
||||||
|
|
||||||
|
import type { QuantizerModule } from '../../codecs/imagequant/imagequant.js';
|
||||||
|
|
||||||
// MozJPEG
|
// MozJPEG
|
||||||
import mozEnc from '../../codecs/mozjpeg/enc/mozjpeg_node_enc.js';
|
import mozEnc from '../../codecs/mozjpeg/enc/mozjpeg_node_enc.js';
|
||||||
import mozEncWasm from 'asset-url:../../codecs/mozjpeg/enc/mozjpeg_node_enc.wasm';
|
import mozEncWasm from 'asset-url:../../codecs/mozjpeg/enc/mozjpeg_node_enc.wasm';
|
||||||
@@ -51,16 +82,22 @@ const resizePromise = resize.default(fsp.readFile(pathify(resizeWasm)));
|
|||||||
// rotate
|
// rotate
|
||||||
import rotateWasm from 'asset-url:../../codecs/rotate/rotate.wasm';
|
import rotateWasm from 'asset-url:../../codecs/rotate/rotate.wasm';
|
||||||
|
|
||||||
|
// TODO(ergunsh): Type definitions of some modules do not exist
|
||||||
|
// Figure out creating type definitions for them and remove `allowJs` rule
|
||||||
|
// We shouldn't need to use Promise<QuantizerModule> below after getting type definitions for imageQuant
|
||||||
// ImageQuant
|
// ImageQuant
|
||||||
import imageQuant from '../../codecs/imagequant/imagequant_node.js';
|
import imageQuant from '../../codecs/imagequant/imagequant_node.js';
|
||||||
import imageQuantWasm from 'asset-url:../../codecs/imagequant/imagequant_node.wasm';
|
import imageQuantWasm from 'asset-url:../../codecs/imagequant/imagequant_node.wasm';
|
||||||
const imageQuantPromise = instantiateEmscriptenWasm(imageQuant, imageQuantWasm);
|
const imageQuantPromise: Promise<QuantizerModule> = instantiateEmscriptenWasm(
|
||||||
|
imageQuant,
|
||||||
|
imageQuantWasm,
|
||||||
|
);
|
||||||
|
|
||||||
// Our decoders currently rely on a `ImageData` global.
|
// Our decoders currently rely on a `ImageData` global.
|
||||||
import ImageData from './image_data.js';
|
import ImageData from './image_data.js';
|
||||||
globalThis.ImageData = ImageData;
|
globalThis.ImageData = ImageData;
|
||||||
|
|
||||||
function resizeNameToIndex(name) {
|
function resizeNameToIndex(name: string) {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case 'triangle':
|
case 'triangle':
|
||||||
return 0;
|
return 0;
|
||||||
@@ -80,25 +117,26 @@ function resizeWithAspect({
|
|||||||
input_height,
|
input_height,
|
||||||
target_width,
|
target_width,
|
||||||
target_height,
|
target_height,
|
||||||
}) {
|
}: ResizeWithAspectParams): { width: number; height: number } {
|
||||||
if (!target_width && !target_height) {
|
if (!target_width && !target_height) {
|
||||||
throw Error('Need to specify at least width or height when resizing');
|
throw Error('Need to specify at least width or height when resizing');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_width && target_height) {
|
if (target_width && target_height) {
|
||||||
return { width: target_width, height: target_height };
|
return { width: target_width, height: target_height };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target_width) {
|
if (!target_width) {
|
||||||
return {
|
return {
|
||||||
width: Math.round((input_width / input_height) * target_height),
|
width: Math.round((input_width / input_height) * target_height),
|
||||||
height: target_height,
|
height: target_height,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (!target_height) {
|
|
||||||
return {
|
return {
|
||||||
width: target_width,
|
width: target_width,
|
||||||
height: Math.round((input_height / input_width) * target_width),
|
height: Math.round((input_height / input_width) * target_width),
|
||||||
};
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const preprocessors = {
|
export const preprocessors = {
|
||||||
@@ -108,10 +146,16 @@ export const preprocessors = {
|
|||||||
instantiate: async () => {
|
instantiate: async () => {
|
||||||
await resizePromise;
|
await resizePromise;
|
||||||
return (
|
return (
|
||||||
buffer,
|
buffer: Uint8Array,
|
||||||
input_width,
|
input_width: number,
|
||||||
input_height,
|
input_height: number,
|
||||||
{ width, height, method, premultiply, linearRGB },
|
{
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
method,
|
||||||
|
premultiply,
|
||||||
|
linearRGB,
|
||||||
|
}: ResizeInstantiateOptions,
|
||||||
) => {
|
) => {
|
||||||
({ width, height } = resizeWithAspect({
|
({ width, height } = resizeWithAspect({
|
||||||
input_width,
|
input_width,
|
||||||
@@ -148,7 +192,12 @@ export const preprocessors = {
|
|||||||
description: 'Reduce the number of colors used (aka. paletting)',
|
description: 'Reduce the number of colors used (aka. paletting)',
|
||||||
instantiate: async () => {
|
instantiate: async () => {
|
||||||
const imageQuant = await imageQuantPromise;
|
const imageQuant = await imageQuantPromise;
|
||||||
return (buffer, width, height, { numColors, dither }) =>
|
return (
|
||||||
|
buffer: Uint8Array,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
{ numColors, dither }: { numColors: number; dither: number },
|
||||||
|
) =>
|
||||||
new ImageData(
|
new ImageData(
|
||||||
imageQuant.quantize(buffer, width, height, numColors, dither),
|
imageQuant.quantize(buffer, width, height, numColors, dither),
|
||||||
width,
|
width,
|
||||||
@@ -164,13 +213,18 @@ export const preprocessors = {
|
|||||||
name: 'Rotate',
|
name: 'Rotate',
|
||||||
description: 'Rotate image',
|
description: 'Rotate image',
|
||||||
instantiate: async () => {
|
instantiate: async () => {
|
||||||
return async (buffer, width, height, { numRotations }) => {
|
return async (
|
||||||
|
buffer: Uint8Array,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
{ numRotations }: { numRotations: number },
|
||||||
|
) => {
|
||||||
const degrees = (numRotations * 90) % 360;
|
const degrees = (numRotations * 90) % 360;
|
||||||
const sameDimensions = degrees == 0 || degrees == 180;
|
const sameDimensions = degrees == 0 || degrees == 180;
|
||||||
const size = width * height * 4;
|
const size = width * height * 4;
|
||||||
const { instance } = await WebAssembly.instantiate(
|
const instance = (
|
||||||
await fsp.readFile(pathify(rotateWasm)),
|
await WebAssembly.instantiate(await fsp.readFile(pathify(rotateWasm)))
|
||||||
);
|
).instance as RotateModuleInstance;
|
||||||
const { memory } = instance.exports;
|
const { memory } = instance.exports;
|
||||||
const additionalPagesNeeded = Math.ceil(
|
const additionalPagesNeeded = Math.ceil(
|
||||||
(size * 2 - memory.buffer.byteLength + 8) / (64 * 1024),
|
(size * 2 - memory.buffer.byteLength + 8) / (64 * 1024),
|
||||||
@@ -346,13 +400,18 @@ export const codecs = {
|
|||||||
await pngEncDecPromise;
|
await pngEncDecPromise;
|
||||||
await oxipngPromise;
|
await oxipngPromise;
|
||||||
return {
|
return {
|
||||||
encode: (buffer, width, height, opts) => {
|
encode: (
|
||||||
|
buffer: Uint8Array,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
opts: { level: number },
|
||||||
|
) => {
|
||||||
const simplePng = pngEncDec.encode(
|
const simplePng = pngEncDec.encode(
|
||||||
new Uint8Array(buffer),
|
new Uint8Array(buffer),
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
);
|
);
|
||||||
return oxipng.optimise(simplePng, opts.level);
|
return oxipng.optimise(simplePng, opts.level, false);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
export function pathify(path) {
|
export function pathify(path: string): string {
|
||||||
if (path.startsWith('file://')) {
|
if (path.startsWith('file://')) {
|
||||||
path = fileURLToPath(path);
|
path = fileURLToPath(path);
|
||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function instantiateEmscriptenWasm(factory, path) {
|
export function instantiateEmscriptenWasm<T extends EmscriptenWasm.Module>(
|
||||||
|
factory: EmscriptenWasm.ModuleFactory<T>,
|
||||||
|
path: string,
|
||||||
|
): Promise<T> {
|
||||||
return factory({
|
return factory({
|
||||||
locateFile() {
|
locateFile() {
|
||||||
return pathify(path);
|
return pathify(path);
|
||||||
38
libsquoosh/src/missing-types.d.ts
vendored
Normal file
38
libsquoosh/src/missing-types.d.ts
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/// <reference path="../../missing-types.d.ts" />
|
||||||
|
|
||||||
|
declare module 'asset-url:*' {
|
||||||
|
const value: string;
|
||||||
|
export default value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Somehow TS picks up definitions from the module itself
|
||||||
|
// instead of using `asset-url:*`. It is probably related to
|
||||||
|
// specifity of the module declaration and these declarations below fix it
|
||||||
|
declare module 'asset-url:../../codecs/png/pkg/squoosh_png_bg.wasm' {
|
||||||
|
const value: string;
|
||||||
|
export default value;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'asset-url:../../codecs/oxipng/pkg/squoosh_oxipng_bg.wasm' {
|
||||||
|
const value: string;
|
||||||
|
export default value;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'asset-url:../../codecs/resize/pkg/squoosh_resize_bg.wasm' {
|
||||||
|
const value: string;
|
||||||
|
export default value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These don't exist in NodeJS types so we're not able to use them but they are referenced in some emscripten and codec types
|
||||||
|
// Thus, we need to explicitly assign them to be `never`
|
||||||
|
// We're also not able to use the APIs that use these types
|
||||||
|
// So, if we want to use those APIs we need to supply its dependencies ourselves
|
||||||
|
// However, probably those APIs are more suited to be used in web (i.e. there can be other
|
||||||
|
// dependencies to web APIs that might not work in Node)
|
||||||
|
type RequestInfo = never;
|
||||||
|
type Response = never;
|
||||||
|
type WebGLRenderingContext = never;
|
||||||
|
type MessageEvent = never;
|
||||||
|
|
||||||
|
type BufferSource = ArrayBufferView | ArrayBuffer;
|
||||||
|
type URL = import('url').URL;
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
"extends": "../generic-tsconfig.json",
|
"extends": "../generic-tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"lib": ["esnext"],
|
"lib": ["esnext"],
|
||||||
"types": ["node"]
|
"types": ["node"],
|
||||||
|
"allowJs": true
|
||||||
},
|
},
|
||||||
"include": ["src/**/*"]
|
"include": ["src/**/*", "../codecs/**/*"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ export default class TwoUp extends HTMLElement {
|
|||||||
*/
|
*/
|
||||||
private _everConnected = false;
|
private _everConnected = false;
|
||||||
|
|
||||||
|
private _resizeObserver?: ResizeObserver;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this._handle.className = styles.twoUpHandle;
|
this._handle.className = styles.twoUpHandle;
|
||||||
@@ -45,13 +47,6 @@ export default class TwoUp extends HTMLElement {
|
|||||||
childList: true,
|
childList: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Watch for element size changes.
|
|
||||||
if ('ResizeObserver' in window) {
|
|
||||||
new ResizeObserver(() => this._resetPosition()).observe(this);
|
|
||||||
} else {
|
|
||||||
window.addEventListener('resize', () => this._resetPosition());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Watch for pointers on the handle.
|
// Watch for pointers on the handle.
|
||||||
const pointerTracker: PointerTracker = new PointerTracker(this._handle, {
|
const pointerTracker: PointerTracker = new PointerTracker(this._handle, {
|
||||||
start: (_, event) => {
|
start: (_, event) => {
|
||||||
@@ -68,8 +63,6 @@ export default class TwoUp extends HTMLElement {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('keydown', (event) => this._onKeyDown(event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
@@ -84,12 +77,23 @@ export default class TwoUp extends HTMLElement {
|
|||||||
}</svg>
|
}</svg>
|
||||||
`}</div>`;
|
`}</div>`;
|
||||||
|
|
||||||
|
// Watch for element size changes.
|
||||||
|
this._resizeObserver = new ResizeObserver(() => this._resetPosition());
|
||||||
|
this._resizeObserver.observe(this);
|
||||||
|
|
||||||
|
window.addEventListener('keydown', this._onKeyDown);
|
||||||
|
|
||||||
if (!this._everConnected) {
|
if (!this._everConnected) {
|
||||||
this._resetPosition();
|
this._resetPosition();
|
||||||
this._everConnected = true;
|
this._everConnected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
window.removeEventListener('keydown', this._onKeyDown);
|
||||||
|
if (this._resizeObserver) this._resizeObserver.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
attributeChangedCallback(name: string) {
|
attributeChangedCallback(name: string) {
|
||||||
if (name === orientationAttr) {
|
if (name === orientationAttr) {
|
||||||
this._resetPosition();
|
this._resetPosition();
|
||||||
@@ -97,7 +101,7 @@ export default class TwoUp extends HTMLElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// KeyDown event handler
|
// KeyDown event handler
|
||||||
private _onKeyDown(event: KeyboardEvent) {
|
private _onKeyDown = (event: KeyboardEvent) => {
|
||||||
const target = event.target;
|
const target = event.target;
|
||||||
if (target instanceof HTMLElement && target.closest('input')) return;
|
if (target instanceof HTMLElement && target.closest('input')) return;
|
||||||
|
|
||||||
@@ -122,7 +126,7 @@ export default class TwoUp extends HTMLElement {
|
|||||||
this._relativePosition = this._position / bounds[dimensionAxis];
|
this._relativePosition = this._position / bounds[dimensionAxis];
|
||||||
this._setPosition();
|
this._setPosition();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
private _resetPosition() {
|
private _resetPosition() {
|
||||||
// Set the initial position of the handle.
|
// Set the initial position of the handle.
|
||||||
|
|||||||
@@ -377,6 +377,7 @@ export default class Compress extends Component<Props, State> {
|
|||||||
|
|
||||||
componentWillUnmount(): void {
|
componentWillUnmount(): void {
|
||||||
updateDocumentTitle({ loading: false });
|
updateDocumentTitle({ loading: false });
|
||||||
|
this.widthQuery.removeListener(this.onMobileWidthChange);
|
||||||
this.mainAbortController.abort();
|
this.mainAbortController.abort();
|
||||||
for (const controller of this.sideAbortControllers) {
|
for (const controller of this.sideAbortControllers) {
|
||||||
controller.abort();
|
controller.abort();
|
||||||
|
|||||||
Reference in New Issue
Block a user