@pbk20191/icodec 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/avif.d.ts +90 -0
- package/lib/avif.js +47 -0
- package/lib/common.d.ts +27 -0
- package/lib/common.js +64 -0
- package/lib/heic.d.ts +69 -0
- package/lib/heic.js +43 -0
- package/lib/index.d.ts +67 -0
- package/lib/index.js +19 -0
- package/lib/jpeg.d.ts +99 -0
- package/lib/jpeg.js +53 -0
- package/lib/jxl.d.ts +179 -0
- package/lib/jxl.js +69 -0
- package/lib/png.d.ts +72 -0
- package/lib/png.js +45 -0
- package/lib/qoi.d.ts +13 -0
- package/lib/qoi.js +19 -0
- package/lib/webp.d.ts +219 -0
- package/lib/webp.js +62 -0
- package/lib/wp2.d.ts +71 -0
- package/lib/wp2.js +46 -0
- package/package.json +3 -4
package/lib/avif.d.ts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { ImageDataLike, WasmSource } from "./common.js";
|
|
2
|
+
export declare enum Subsampling {
|
|
3
|
+
YUV444 = 1,
|
|
4
|
+
YUV422 = 2,
|
|
5
|
+
YUV420 = 3,
|
|
6
|
+
YUV400 = 4
|
|
7
|
+
}
|
|
8
|
+
export declare enum AVIFTune {
|
|
9
|
+
Auto = 0,
|
|
10
|
+
PSNR = 1,
|
|
11
|
+
SSIM = 2
|
|
12
|
+
}
|
|
13
|
+
export interface Options {
|
|
14
|
+
/**
|
|
15
|
+
* [0 - 100], 0 = worst quality, 100 = lossless
|
|
16
|
+
*
|
|
17
|
+
* @default 50
|
|
18
|
+
*/
|
|
19
|
+
quality?: number;
|
|
20
|
+
/**
|
|
21
|
+
* As above, but -1 means 'use quality'
|
|
22
|
+
*
|
|
23
|
+
* @default -1
|
|
24
|
+
*/
|
|
25
|
+
qualityAlpha?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Range: [-1, 10], 0 = slowest, 10 = fastest, slower should make for a better quality image in less bytes.
|
|
28
|
+
* A combination of settings are tweaked to simulate this speed range.
|
|
29
|
+
*
|
|
30
|
+
* @default 6
|
|
31
|
+
*/
|
|
32
|
+
speed?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Chrome subsampling type.
|
|
35
|
+
*
|
|
36
|
+
* @default YUV420
|
|
37
|
+
*/
|
|
38
|
+
subsample?: Subsampling;
|
|
39
|
+
/**
|
|
40
|
+
* If true, ignores `tileRowsLog2` and `tileColsLog2` and automatically chooses suitable tiling values.
|
|
41
|
+
*
|
|
42
|
+
* @default false
|
|
43
|
+
*/
|
|
44
|
+
autoTiling?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* [0 - 6], Creates 2^n tiles in that dimension
|
|
47
|
+
*
|
|
48
|
+
* @default 0
|
|
49
|
+
*/
|
|
50
|
+
tileRowsLog2?: number;
|
|
51
|
+
tileColsLog2?: number;
|
|
52
|
+
/**
|
|
53
|
+
* Extra chroma compression, cannot be used in lossless mode.
|
|
54
|
+
*
|
|
55
|
+
* @default false
|
|
56
|
+
*/
|
|
57
|
+
chromaDeltaQ?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Bias towards block sharpness in rate-distortion optimization of transform coefficients [0, 7]
|
|
60
|
+
*
|
|
61
|
+
* @default 0
|
|
62
|
+
*/
|
|
63
|
+
sharpness?: number;
|
|
64
|
+
/**
|
|
65
|
+
* Amount of noise (from 0 = don't denoise, to 50)
|
|
66
|
+
*
|
|
67
|
+
* @default 0
|
|
68
|
+
*/
|
|
69
|
+
denoiseLevel?: number;
|
|
70
|
+
/**
|
|
71
|
+
* Distortion metric tuned with.
|
|
72
|
+
*
|
|
73
|
+
* @default AVIFTune.Auto
|
|
74
|
+
*/
|
|
75
|
+
tune?: AVIFTune;
|
|
76
|
+
/**
|
|
77
|
+
* Use libsharpyuv for RGB->YUV conversion if needed.
|
|
78
|
+
*
|
|
79
|
+
* @default false
|
|
80
|
+
*/
|
|
81
|
+
sharpYUV?: boolean;
|
|
82
|
+
}
|
|
83
|
+
export declare const defaultOptions: Required<Options>;
|
|
84
|
+
export declare const mimeType = "image/avif";
|
|
85
|
+
export declare const extension = "avif";
|
|
86
|
+
export declare const bitDepth: number[];
|
|
87
|
+
export declare function loadEncoder(input?: WasmSource): Promise<any>;
|
|
88
|
+
export declare function loadDecoder(input?: WasmSource): Promise<any>;
|
|
89
|
+
export declare function encode(image: ImageDataLike, options?: Options): Uint8Array<ArrayBufferLike>;
|
|
90
|
+
export declare function decode(input: BufferSource): ImageData;
|
package/lib/avif.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import wasmFactoryEnc from "../dist/avif-enc.js";
|
|
2
|
+
import wasmFactoryDec from "../dist/avif-dec.js";
|
|
3
|
+
import { check, encodeES, loadES } from "./common.js";
|
|
4
|
+
export var Subsampling;
|
|
5
|
+
(function (Subsampling) {
|
|
6
|
+
Subsampling[Subsampling["YUV444"] = 1] = "YUV444";
|
|
7
|
+
Subsampling[Subsampling["YUV422"] = 2] = "YUV422";
|
|
8
|
+
Subsampling[Subsampling["YUV420"] = 3] = "YUV420";
|
|
9
|
+
Subsampling[Subsampling["YUV400"] = 4] = "YUV400";
|
|
10
|
+
})(Subsampling || (Subsampling = {}));
|
|
11
|
+
export var AVIFTune;
|
|
12
|
+
(function (AVIFTune) {
|
|
13
|
+
AVIFTune[AVIFTune["Auto"] = 0] = "Auto";
|
|
14
|
+
AVIFTune[AVIFTune["PSNR"] = 1] = "PSNR";
|
|
15
|
+
AVIFTune[AVIFTune["SSIM"] = 2] = "SSIM";
|
|
16
|
+
})(AVIFTune || (AVIFTune = {}));
|
|
17
|
+
export const defaultOptions = {
|
|
18
|
+
quality: 50,
|
|
19
|
+
qualityAlpha: -1,
|
|
20
|
+
speed: 6,
|
|
21
|
+
subsample: Subsampling.YUV420,
|
|
22
|
+
autoTiling: false,
|
|
23
|
+
tileColsLog2: 0,
|
|
24
|
+
tileRowsLog2: 0,
|
|
25
|
+
chromaDeltaQ: false,
|
|
26
|
+
sharpness: 0,
|
|
27
|
+
denoiseLevel: 0,
|
|
28
|
+
tune: AVIFTune.Auto,
|
|
29
|
+
sharpYUV: false,
|
|
30
|
+
};
|
|
31
|
+
export const mimeType = "image/avif";
|
|
32
|
+
export const extension = "avif";
|
|
33
|
+
export const bitDepth = [8, 10, 12, 16];
|
|
34
|
+
let encoderWASM;
|
|
35
|
+
let decoderWASM;
|
|
36
|
+
export async function loadEncoder(input) {
|
|
37
|
+
return encoderWASM ??= await loadES(wasmFactoryEnc, input);
|
|
38
|
+
}
|
|
39
|
+
export async function loadDecoder(input) {
|
|
40
|
+
return decoderWASM ??= await loadES(wasmFactoryDec, input);
|
|
41
|
+
}
|
|
42
|
+
export function encode(image, options) {
|
|
43
|
+
return encodeES("AVIF Encode", encoderWASM, defaultOptions, image, options);
|
|
44
|
+
}
|
|
45
|
+
export function decode(input) {
|
|
46
|
+
return check(decoderWASM.decode(input), "AVIF Decode");
|
|
47
|
+
}
|
package/lib/common.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parameter type of `loadEncoder()` and `loadDecoder()`.
|
|
3
|
+
*
|
|
4
|
+
* - If is a string, it's the URL of WASM file to fetch.
|
|
5
|
+
* - If is BufferSource, it will be treated as the WASM bytes.
|
|
6
|
+
*/
|
|
7
|
+
export type WasmSource = string | BufferSource;
|
|
8
|
+
export declare function loadES(factory: any, source?: WasmSource): any;
|
|
9
|
+
export interface ImageDataLike {
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
depth: number;
|
|
13
|
+
data: Uint8Array | Uint8ClampedArray;
|
|
14
|
+
}
|
|
15
|
+
export declare function toBitDepth(image: ImageDataLike, value: number): ImageDataLike;
|
|
16
|
+
/**
|
|
17
|
+
* Node does not have `ImageData` class, so we define a pure version.
|
|
18
|
+
*/
|
|
19
|
+
export declare class PureImageData implements ImageDataLike {
|
|
20
|
+
readonly data: Uint8ClampedArray;
|
|
21
|
+
readonly width: number;
|
|
22
|
+
readonly height: number;
|
|
23
|
+
readonly depth: number;
|
|
24
|
+
constructor(data: Uint8ClampedArray, width: number, height: number, depth?: number);
|
|
25
|
+
}
|
|
26
|
+
export declare function encodeES<T>(name: string, wasm: any, defaults: T, image: ImageDataLike, options?: T): Uint8Array<ArrayBufferLike>;
|
|
27
|
+
export declare function check<T>(value: string | null | T, hint: string): T;
|
package/lib/common.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export function loadES(factory, source) {
|
|
2
|
+
return typeof source === "string"
|
|
3
|
+
? factory({ locateFile: () => source })
|
|
4
|
+
: factory({ wasmBinary: source });
|
|
5
|
+
}
|
|
6
|
+
export function toBitDepth(image, value) {
|
|
7
|
+
const { data, width, height, depth = 8 } = image;
|
|
8
|
+
if (value === depth) {
|
|
9
|
+
return image;
|
|
10
|
+
}
|
|
11
|
+
const pixels = width * height * 4;
|
|
12
|
+
const dist = value === 8
|
|
13
|
+
? new Uint8ClampedArray(pixels)
|
|
14
|
+
: new Uint16Array(pixels);
|
|
15
|
+
const view = depth === 8
|
|
16
|
+
? data
|
|
17
|
+
: new Uint16Array(data.buffer, data.byteOffset);
|
|
18
|
+
const from = (1 << depth) - 1;
|
|
19
|
+
const to = (1 << value) - 1;
|
|
20
|
+
for (let i = 0; i < pixels; i++) {
|
|
21
|
+
dist[i] = view[i] / from * to + 0.5;
|
|
22
|
+
}
|
|
23
|
+
const nd = new Uint8ClampedArray(dist.buffer, dist.byteOffset, dist.byteLength);
|
|
24
|
+
return _icodec_ImageData(nd, width, height, value);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Node does not have `ImageData` class, so we define a pure version.
|
|
28
|
+
*/
|
|
29
|
+
export class PureImageData {
|
|
30
|
+
data;
|
|
31
|
+
width;
|
|
32
|
+
height;
|
|
33
|
+
depth;
|
|
34
|
+
constructor(data, width, height, depth = 8) {
|
|
35
|
+
this.data = data;
|
|
36
|
+
this.width = width;
|
|
37
|
+
this.height = height;
|
|
38
|
+
this.depth = depth;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// @ts-expect-error
|
|
42
|
+
PureImageData.prototype.colorSpace = "srgb";
|
|
43
|
+
export function encodeES(name, wasm, defaults, image, options) {
|
|
44
|
+
options = { ...defaults, ...options };
|
|
45
|
+
const { data, width, height } = image;
|
|
46
|
+
options.bitDepth = image.depth ?? 8;
|
|
47
|
+
const result = wasm.encode(data, width, height, options);
|
|
48
|
+
if (result instanceof Error) {
|
|
49
|
+
throw result;
|
|
50
|
+
}
|
|
51
|
+
return check(result, name);
|
|
52
|
+
}
|
|
53
|
+
export function check(value, hint) {
|
|
54
|
+
if (typeof value === "string") {
|
|
55
|
+
throw new Error(`${hint}: ${value}`);
|
|
56
|
+
}
|
|
57
|
+
if (value instanceof Error) {
|
|
58
|
+
throw value;
|
|
59
|
+
}
|
|
60
|
+
if (value)
|
|
61
|
+
return value;
|
|
62
|
+
else
|
|
63
|
+
throw new Error(hint + " failed");
|
|
64
|
+
}
|
package/lib/heic.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ImageDataLike, WasmSource } from "./common.js";
|
|
2
|
+
export declare const Presets: readonly ["ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo"];
|
|
3
|
+
export declare const Subsampling: readonly ["420", "422", "444"];
|
|
4
|
+
export declare const Tune: readonly ["psnr", "ssim", "grain", "fastdecode"];
|
|
5
|
+
export interface Options {
|
|
6
|
+
/**
|
|
7
|
+
* Quality-based VBR [0, 100], it will map to `--crf` parameter of x265.
|
|
8
|
+
* quality=0 -> crf=50
|
|
9
|
+
* quality=50 -> crf=25
|
|
10
|
+
* quality=100 -> crf=0
|
|
11
|
+
*
|
|
12
|
+
* @default 50
|
|
13
|
+
*/
|
|
14
|
+
quality?: number;
|
|
15
|
+
/**
|
|
16
|
+
* If true, Bypass transform, quant and loop filters.
|
|
17
|
+
*
|
|
18
|
+
* Note: it does not bypass chroma subsampling, you need
|
|
19
|
+
* also to set `chroma` to "444" for exact lossless.
|
|
20
|
+
*
|
|
21
|
+
* @default false
|
|
22
|
+
*/
|
|
23
|
+
lossless?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Trade off performance for compression efficiency.
|
|
26
|
+
*
|
|
27
|
+
* @default "slow"
|
|
28
|
+
*/
|
|
29
|
+
preset?: typeof Presets[number];
|
|
30
|
+
/**
|
|
31
|
+
* Tune the settings for a particular type of source or situation.
|
|
32
|
+
*
|
|
33
|
+
* @default "ssim"
|
|
34
|
+
*/
|
|
35
|
+
tune?: typeof Tune[number];
|
|
36
|
+
/**
|
|
37
|
+
* Max TU recursive depth for intra CUs。
|
|
38
|
+
*
|
|
39
|
+
* [1, 4], default 2.
|
|
40
|
+
*/
|
|
41
|
+
tuIntraDepth?: number;
|
|
42
|
+
/**
|
|
43
|
+
* CPU effort, larger value increases encode time.
|
|
44
|
+
* Range is [0, 100], but only changes at a few values.
|
|
45
|
+
*
|
|
46
|
+
* @default 50
|
|
47
|
+
*/
|
|
48
|
+
complexity?: number;
|
|
49
|
+
/**
|
|
50
|
+
* Specify chroma subsampling method.
|
|
51
|
+
*
|
|
52
|
+
* @default "420"
|
|
53
|
+
*/
|
|
54
|
+
chroma?: typeof Subsampling[number];
|
|
55
|
+
/**
|
|
56
|
+
* Use more accurate and sharper RGB->YUV conversion if needed.
|
|
57
|
+
*
|
|
58
|
+
* @default false
|
|
59
|
+
*/
|
|
60
|
+
sharpYUV?: boolean;
|
|
61
|
+
}
|
|
62
|
+
export declare const defaultOptions: Required<Options>;
|
|
63
|
+
export declare const mimeType = "image/heic";
|
|
64
|
+
export declare const extension = "heic";
|
|
65
|
+
export declare const bitDepth: number[];
|
|
66
|
+
export declare function loadEncoder(input?: WasmSource): Promise<any>;
|
|
67
|
+
export declare function loadDecoder(input?: WasmSource): Promise<any>;
|
|
68
|
+
export declare function encode(image: ImageDataLike, options?: Options): Uint8Array<ArrayBufferLike>;
|
|
69
|
+
export declare function decode(input: BufferSource): ImageData;
|
package/lib/heic.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import wasmFactoryEnc from "../dist/heic-enc.js";
|
|
2
|
+
import wasmFactoryDec from "../dist/heic-dec.js";
|
|
3
|
+
import { check, encodeES, loadES } from "./common.js";
|
|
4
|
+
export const Presets = ["ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo"];
|
|
5
|
+
export const Subsampling = ["420", "422", "444"];
|
|
6
|
+
export const Tune = ["psnr", "ssim", "grain", "fastdecode"];
|
|
7
|
+
export const defaultOptions = {
|
|
8
|
+
quality: 50,
|
|
9
|
+
lossless: false,
|
|
10
|
+
preset: "slow",
|
|
11
|
+
tune: "ssim",
|
|
12
|
+
tuIntraDepth: 2,
|
|
13
|
+
complexity: 50,
|
|
14
|
+
chroma: "420",
|
|
15
|
+
sharpYUV: false,
|
|
16
|
+
};
|
|
17
|
+
export const mimeType = "image/heic";
|
|
18
|
+
export const extension = "heic";
|
|
19
|
+
export const bitDepth = [8, 10, 12];
|
|
20
|
+
let encoderWASM;
|
|
21
|
+
let decoderWASM;
|
|
22
|
+
export async function loadEncoder(input) {
|
|
23
|
+
return encoderWASM ??= await loadES(wasmFactoryEnc, input);
|
|
24
|
+
}
|
|
25
|
+
export async function loadDecoder(input) {
|
|
26
|
+
return decoderWASM ??= await loadES(wasmFactoryDec, input);
|
|
27
|
+
}
|
|
28
|
+
export function encode(image, options) {
|
|
29
|
+
const new_encode = (...args) => {
|
|
30
|
+
const holder = {};
|
|
31
|
+
encoderWASM.encode(...args, holder);
|
|
32
|
+
if (holder.error) {
|
|
33
|
+
return holder.error;
|
|
34
|
+
}
|
|
35
|
+
if (holder.success) {
|
|
36
|
+
return holder.success;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
return encodeES("HEIC Encode", { encode: new_encode }, defaultOptions, image, options);
|
|
40
|
+
}
|
|
41
|
+
export function decode(input) {
|
|
42
|
+
return check(decoderWASM.decode(input), "HEIC Decode");
|
|
43
|
+
}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { ImageDataLike, toBitDepth, WasmSource } from "./common.js";
|
|
2
|
+
export { ImageDataLike, toBitDepth };
|
|
3
|
+
export * as avif from "./avif.js";
|
|
4
|
+
export * as png from "./png.js";
|
|
5
|
+
export * as jpeg from "./jpeg.js";
|
|
6
|
+
export * as jxl from "./jxl.js";
|
|
7
|
+
export * as webp from "./webp.js";
|
|
8
|
+
export * as heic from "./heic.js";
|
|
9
|
+
export * as qoi from "./qoi.js";
|
|
10
|
+
export * as wp2 from "./wp2.js";
|
|
11
|
+
declare global {
|
|
12
|
+
var _icodec_ImageData: (data: Uint8ClampedArray, w: number, h: number, depth: number) => ImageDataLike;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Provides a uniform type for codec modules that support encoding.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* import { wp2, ICodecModule } from "icodec";
|
|
19
|
+
*
|
|
20
|
+
* const encoder: ICodecModule<wp2.Options> = wp2;
|
|
21
|
+
*/
|
|
22
|
+
export interface ICodecModule<T = any> {
|
|
23
|
+
/**
|
|
24
|
+
* The default options of `encode` function.
|
|
25
|
+
*/
|
|
26
|
+
defaultOptions: Required<T>;
|
|
27
|
+
/**
|
|
28
|
+
* The MIME type string of the format.
|
|
29
|
+
*/
|
|
30
|
+
mimeType: string;
|
|
31
|
+
/**
|
|
32
|
+
* File extension (without the dot) of this format.
|
|
33
|
+
*/
|
|
34
|
+
extension: string;
|
|
35
|
+
/**
|
|
36
|
+
* List of supported bit depth, from lower to higher.
|
|
37
|
+
*/
|
|
38
|
+
bitDepth: number[];
|
|
39
|
+
/**
|
|
40
|
+
* Load the decoder WASM file, must be called once before decode.
|
|
41
|
+
* Multiple calls are ignored, and return the first result.
|
|
42
|
+
*
|
|
43
|
+
* @param source If pass a string, it's the URL of WASM file to fetch,
|
|
44
|
+
* else it will be treated as the WASM bytes.
|
|
45
|
+
* @return the underlying WASM module, which is not part of
|
|
46
|
+
* the public API and can be changed at any time.
|
|
47
|
+
*/
|
|
48
|
+
loadDecoder(source?: WasmSource): Promise<any>;
|
|
49
|
+
/**
|
|
50
|
+
* Convert the image to raw RGBA data.
|
|
51
|
+
*/
|
|
52
|
+
decode(input: Uint8Array): ImageData;
|
|
53
|
+
/**
|
|
54
|
+
* Load the encoder WASM file, must be called once before encode.
|
|
55
|
+
* Multiple calls are ignored, and return the first result.
|
|
56
|
+
*
|
|
57
|
+
* @param source If pass a string, it's the URL of WASM file to fetch,
|
|
58
|
+
* else it will be treated as the WASM bytes.
|
|
59
|
+
* @return the underlying WASM module, which is not part of
|
|
60
|
+
* the public API and can be changed at any time.
|
|
61
|
+
*/
|
|
62
|
+
loadEncoder(source?: WasmSource): Promise<any>;
|
|
63
|
+
/**
|
|
64
|
+
* Encode an image with RGBA pixels data.
|
|
65
|
+
*/
|
|
66
|
+
encode(image: ImageDataLike, options?: T): Uint8Array;
|
|
67
|
+
}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { PureImageData, toBitDepth } from "./common.js";
|
|
2
|
+
export { toBitDepth };
|
|
3
|
+
export * as avif from "./avif.js";
|
|
4
|
+
export * as png from "./png.js";
|
|
5
|
+
export * as jpeg from "./jpeg.js";
|
|
6
|
+
export * as jxl from "./jxl.js";
|
|
7
|
+
export * as webp from "./webp.js";
|
|
8
|
+
export * as heic from "./heic.js";
|
|
9
|
+
export * as qoi from "./qoi.js";
|
|
10
|
+
export * as wp2 from "./wp2.js";
|
|
11
|
+
globalThis._icodec_ImageData = (data, w, h, depth) => {
|
|
12
|
+
if (depth === 8) {
|
|
13
|
+
return new ImageDataEx(data, w, h);
|
|
14
|
+
}
|
|
15
|
+
return new PureImageData(data, w, h, depth);
|
|
16
|
+
};
|
|
17
|
+
class ImageDataEx extends ImageData {
|
|
18
|
+
depth = 8;
|
|
19
|
+
}
|
package/lib/jpeg.d.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { ImageDataLike, WasmSource } from "./common.js";
|
|
2
|
+
export declare enum ColorSpace {
|
|
3
|
+
GRAYSCALE = 1,
|
|
4
|
+
RGB = 2,
|
|
5
|
+
YCbCr = 3
|
|
6
|
+
}
|
|
7
|
+
export declare enum Quantization {
|
|
8
|
+
JPEG_Annex_K = 0,
|
|
9
|
+
Flat = 1,
|
|
10
|
+
MSSIM_Tuned_Kodak = 2,
|
|
11
|
+
ImageMagick = 3,
|
|
12
|
+
PSNR_HVS_M_Tuned_Kodak = 4,
|
|
13
|
+
Klein_Silverstein_Carney = 5,
|
|
14
|
+
Watson_Taylor_Borthwick = 6,
|
|
15
|
+
Ahumada_Watson_Peterson = 7,
|
|
16
|
+
Peterson_Ahumada_Watson = 8
|
|
17
|
+
}
|
|
18
|
+
export interface Options {
|
|
19
|
+
/**
|
|
20
|
+
* Compression quality [0..100], 5-95 is most useful range.
|
|
21
|
+
*
|
|
22
|
+
* @default 75
|
|
23
|
+
*/
|
|
24
|
+
quality?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Create baseline JPEG file (disable progressive coding).
|
|
27
|
+
*
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
baseline?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Use arithmetic coding.
|
|
33
|
+
*
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
arithmetic?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Create progressive JPEG file.
|
|
39
|
+
*
|
|
40
|
+
* @default true
|
|
41
|
+
*/
|
|
42
|
+
progressive?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Optimize Huffman table (smaller file, but slow compression)
|
|
45
|
+
*
|
|
46
|
+
* @default true
|
|
47
|
+
*/
|
|
48
|
+
optimizeCoding?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Smooth dithered input (N=1..100 is strength)
|
|
51
|
+
*
|
|
52
|
+
* @default 0
|
|
53
|
+
*/
|
|
54
|
+
smoothing?: number;
|
|
55
|
+
/**
|
|
56
|
+
* @default ColorSpace.YCbCr
|
|
57
|
+
*/
|
|
58
|
+
colorSpace?: ColorSpace;
|
|
59
|
+
/**
|
|
60
|
+
* Select the predefined quantization table to use.
|
|
61
|
+
*
|
|
62
|
+
* @default Quantization.ImageMagick
|
|
63
|
+
*/
|
|
64
|
+
quantTable?: Quantization;
|
|
65
|
+
/**
|
|
66
|
+
* use scans in trellis optimization.
|
|
67
|
+
*
|
|
68
|
+
* @default false
|
|
69
|
+
*/
|
|
70
|
+
trellisMultipass?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* optimize for sequences of EOB
|
|
73
|
+
*/
|
|
74
|
+
trellisOptZero?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* optimize quant table in trellis loop.
|
|
77
|
+
*
|
|
78
|
+
* @default false
|
|
79
|
+
*/
|
|
80
|
+
trellisOptTable?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* number of trellis loops.
|
|
83
|
+
*
|
|
84
|
+
* @default 1
|
|
85
|
+
*/
|
|
86
|
+
trellisLoops?: number;
|
|
87
|
+
autoSubsample?: boolean;
|
|
88
|
+
chromaSubsample?: number;
|
|
89
|
+
separateChromaQuality?: boolean;
|
|
90
|
+
chromaQuality?: number;
|
|
91
|
+
}
|
|
92
|
+
export declare const defaultOptions: Required<Options>;
|
|
93
|
+
export declare const bitDepth: number[];
|
|
94
|
+
export declare const mimeType = "image/jpeg";
|
|
95
|
+
export declare const extension = "jpg";
|
|
96
|
+
export declare function loadEncoder(input?: WasmSource): Promise<any>;
|
|
97
|
+
export declare const loadDecoder: typeof loadEncoder;
|
|
98
|
+
export declare function encode(image: ImageDataLike, options?: Options): Uint8Array<ArrayBufferLike>;
|
|
99
|
+
export declare function decode(input: BufferSource): ImageData;
|
package/lib/jpeg.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import wasmFactoryEnc from "../dist/mozjpeg.js";
|
|
2
|
+
import { check, encodeES, loadES } from "./common.js";
|
|
3
|
+
export var ColorSpace;
|
|
4
|
+
(function (ColorSpace) {
|
|
5
|
+
ColorSpace[ColorSpace["GRAYSCALE"] = 1] = "GRAYSCALE";
|
|
6
|
+
ColorSpace[ColorSpace["RGB"] = 2] = "RGB";
|
|
7
|
+
ColorSpace[ColorSpace["YCbCr"] = 3] = "YCbCr";
|
|
8
|
+
})(ColorSpace || (ColorSpace = {}));
|
|
9
|
+
// https://github.com/mozilla/mozjpeg/blob/6c9f0897afa1c2738d7222a0a9ab49e8b536a267/jcparam.c#L74
|
|
10
|
+
export var Quantization;
|
|
11
|
+
(function (Quantization) {
|
|
12
|
+
Quantization[Quantization["JPEG_Annex_K"] = 0] = "JPEG_Annex_K";
|
|
13
|
+
Quantization[Quantization["Flat"] = 1] = "Flat";
|
|
14
|
+
Quantization[Quantization["MSSIM_Tuned_Kodak"] = 2] = "MSSIM_Tuned_Kodak";
|
|
15
|
+
Quantization[Quantization["ImageMagick"] = 3] = "ImageMagick";
|
|
16
|
+
Quantization[Quantization["PSNR_HVS_M_Tuned_Kodak"] = 4] = "PSNR_HVS_M_Tuned_Kodak";
|
|
17
|
+
Quantization[Quantization["Klein_Silverstein_Carney"] = 5] = "Klein_Silverstein_Carney";
|
|
18
|
+
Quantization[Quantization["Watson_Taylor_Borthwick"] = 6] = "Watson_Taylor_Borthwick";
|
|
19
|
+
Quantization[Quantization["Ahumada_Watson_Peterson"] = 7] = "Ahumada_Watson_Peterson";
|
|
20
|
+
Quantization[Quantization["Peterson_Ahumada_Watson"] = 8] = "Peterson_Ahumada_Watson";
|
|
21
|
+
})(Quantization || (Quantization = {}));
|
|
22
|
+
export const defaultOptions = {
|
|
23
|
+
quality: 75,
|
|
24
|
+
baseline: false,
|
|
25
|
+
arithmetic: false,
|
|
26
|
+
progressive: true,
|
|
27
|
+
optimizeCoding: true,
|
|
28
|
+
smoothing: 0,
|
|
29
|
+
colorSpace: ColorSpace.YCbCr,
|
|
30
|
+
quantTable: Quantization.ImageMagick,
|
|
31
|
+
trellisMultipass: false,
|
|
32
|
+
trellisOptZero: false,
|
|
33
|
+
trellisOptTable: false,
|
|
34
|
+
trellisLoops: 1,
|
|
35
|
+
autoSubsample: true,
|
|
36
|
+
chromaSubsample: 2,
|
|
37
|
+
separateChromaQuality: false,
|
|
38
|
+
chromaQuality: 75,
|
|
39
|
+
};
|
|
40
|
+
export const bitDepth = [8];
|
|
41
|
+
export const mimeType = "image/jpeg";
|
|
42
|
+
export const extension = "jpg";
|
|
43
|
+
let codecWASM;
|
|
44
|
+
export async function loadEncoder(input) {
|
|
45
|
+
return codecWASM = await loadES(wasmFactoryEnc, input);
|
|
46
|
+
}
|
|
47
|
+
export const loadDecoder = loadEncoder;
|
|
48
|
+
export function encode(image, options) {
|
|
49
|
+
return encodeES("JPEG Encode", codecWASM, defaultOptions, image, options);
|
|
50
|
+
}
|
|
51
|
+
export function decode(input) {
|
|
52
|
+
return check(codecWASM.decode(input), "JPEG Decode");
|
|
53
|
+
}
|