mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-11 16:26:20 +00:00
Compare commits
79 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9988505b2c | ||
|
|
0e6610c007 | ||
|
|
74477dfe6b | ||
|
|
59713b7687 | ||
|
|
62102fecab | ||
|
|
b1fc4d1c57 | ||
|
|
02e0206285 | ||
|
|
8f21972e70 | ||
|
|
8d9ed5ad3e | ||
|
|
be5a96a42a | ||
|
|
eeafef4e14 | ||
|
|
067ce686b5 | ||
|
|
c78ad6c795 | ||
|
|
be818caf48 | ||
|
|
4abc7f40d1 | ||
|
|
903c8b5d02 | ||
|
|
4c03ceee04 | ||
|
|
a2c465abdf | ||
|
|
251dc2ce9b | ||
|
|
e8948167db | ||
|
|
9e1fb6dfb4 | ||
|
|
2d1a3b543a | ||
|
|
4aaa5ffa78 | ||
|
|
6fa13b919b | ||
|
|
fcef2b2d3e | ||
|
|
4d5761c780 | ||
|
|
be3ab8b6d1 | ||
|
|
49620e4c8f | ||
|
|
3d1ecc1215 | ||
|
|
25fb1a9c80 | ||
|
|
3ae1cf86f5 | ||
|
|
a699a5c4dc | ||
|
|
613401c541 | ||
|
|
f450373e3f | ||
|
|
750872aca6 | ||
|
|
beaabe47dc | ||
|
|
8f7369068c | ||
|
|
10bfd60e20 | ||
|
|
7f08348509 | ||
|
|
f77ddac652 | ||
|
|
13631f1cfc | ||
|
|
f11e692d58 | ||
|
|
f0221b626d | ||
|
|
10c5ed0495 | ||
|
|
d945c79796 | ||
|
|
30b628c1b9 | ||
|
|
6ebf94d1b6 | ||
|
|
a229662bed | ||
|
|
e995b445ef | ||
|
|
6da590c7d0 | ||
|
|
56e10b3aa2 | ||
|
|
fd87ae7d2a | ||
|
|
5df7dd7590 | ||
|
|
013946b137 | ||
|
|
81c183b0d6 | ||
|
|
f523db6403 | ||
|
|
cc6ea9e11c | ||
|
|
bd4b67037b | ||
|
|
8c5c97e106 | ||
|
|
a9d3bd71b5 | ||
|
|
0d0a9b4cdf | ||
|
|
f583770696 | ||
|
|
bae243ccdb | ||
|
|
02c113a68f | ||
|
|
600eead007 | ||
|
|
05416768d5 | ||
|
|
35d31f2324 | ||
|
|
82fadac70e | ||
|
|
47f9d22dd8 | ||
|
|
9420dba3bc | ||
|
|
e462875807 | ||
|
|
0747d2c419 | ||
|
|
4c658b79ef | ||
|
|
685558847f | ||
|
|
63ac34a662 | ||
|
|
42f9e4aed2 | ||
|
|
e14790f0b9 | ||
|
|
dfee848a39 | ||
|
|
a437afdf2b |
@@ -7,3 +7,6 @@ end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
|
||||
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/codecs/**/*.js linguist-generated=true
|
||||
/codecs/*/pkg*/*.d.ts linguist-generated=true
|
||||
22
.github/workflows/node.js.yml
vendored
Normal file
22
.github/workflows/node.js.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Node.js CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- id: nvmrc
|
||||
uses: browniebroke/read-nvmrc-action@v1
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '${{ steps.nvmrc.outputs.node_version }}'
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -1,6 +1,11 @@
|
||||
.tmp
|
||||
node_modules
|
||||
/build
|
||||
/*.log
|
||||
*.scss.d.ts
|
||||
*.css.d.ts
|
||||
build
|
||||
*.o
|
||||
|
||||
# Auto-generated by lib/feature-plugin.js
|
||||
src/features-worker/index.ts
|
||||
src/client/lazy-app/worker-bridge/meta.ts
|
||||
src/client/lazy-app/feature-meta/index.ts
|
||||
|
||||
12
.prettierignore
Normal file
12
.prettierignore
Normal file
@@ -0,0 +1,12 @@
|
||||
codecs
|
||||
.tmp
|
||||
node_modules
|
||||
*.scss.d.ts
|
||||
*.css.d.ts
|
||||
build
|
||||
*.o
|
||||
|
||||
# Auto-generated by lib/feature-plugin.js
|
||||
src/features-worker/index.ts
|
||||
src/client/lazy-app/worker-bridge/meta.ts
|
||||
src/client/lazy-app/feature-meta/index.ts
|
||||
4
.prettierrc.json
Normal file
4
.prettierrc.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all"
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
language: node_js
|
||||
cache: npm
|
||||
script: npm run build
|
||||
after_success: npm run sizereport
|
||||
os:
|
||||
- linux
|
||||
- windows
|
||||
18
_headers.ejs
18
_headers.ejs
@@ -1,18 +0,0 @@
|
||||
# Long-term cache by default.
|
||||
/*
|
||||
Cache-Control: max-age=31536000
|
||||
|
||||
# And here are the exceptions:
|
||||
/
|
||||
Cache-Control: no-cache
|
||||
|
||||
/serviceworker.js
|
||||
Cache-Control: no-cache
|
||||
|
||||
/manifest.json
|
||||
Cache-Control: must-revalidate, max-age=3600
|
||||
|
||||
# URLs in /assets do not include a hash and are mutable.
|
||||
# But it isn't a big deal if the user gets an old version.
|
||||
/assets/*
|
||||
Cache-Control: must-revalidate, max-age=3600
|
||||
19
client-tsconfig.json
Normal file
19
client-tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "./generic-tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"lib": ["esnext", "dom", "dom.iterable"],
|
||||
"types": []
|
||||
},
|
||||
"include": [
|
||||
"src/features/**/client/**/*",
|
||||
"src/features/**/shared/**/*",
|
||||
"src/features/client-utils/**/*",
|
||||
"src/shared/**/*",
|
||||
"src/client/**/*",
|
||||
// Not really clean, but we need these to access the type of the functions
|
||||
// for comlink
|
||||
"src/features/**/worker/**/*",
|
||||
"src/features-worker/**/*",
|
||||
"src/features/worker-utils/**/*"
|
||||
]
|
||||
}
|
||||
@@ -1,76 +1,84 @@
|
||||
CODEC_URL = https://github.com/AOMediaCodec/libavif/archive/v0.8.1.tar.gz
|
||||
CODEC_DIR = node_modules/libavif
|
||||
CODEC_BUILD_DIR := $(CODEC_DIR)/build
|
||||
CODEC_OUT := $(CODEC_BUILD_DIR)/libavif.a
|
||||
CODEC_URL = https://github.com/AOMediaCodec/libavif/archive/31d7c6d1e32cf467ac24fb8c7a76c4902a4c00db.tar.gz
|
||||
CODEC_PACKAGE = node_modules/libavif.tar.gz
|
||||
|
||||
LIBAOM_URL = https://aomedia.googlesource.com/aom/+archive/v2.0.0.tar.gz
|
||||
LIBAOM_DIR := $(CODEC_DIR)/ext/aom
|
||||
LIBAOM_BUILD_DIR := $(LIBAOM_DIR)/build.libavif
|
||||
LIBAOM_OUT := $(LIBAOM_BUILD_DIR)/libaom.a
|
||||
LIBAOM_PACKAGE = node_modules/libaom.tar.gz
|
||||
|
||||
OUT_JS = enc/avif_enc.js dec/avif_dec.js
|
||||
OUT_WASM = $(OUT_JS:.js=.wasm)
|
||||
export CODEC_DIR = node_modules/libavif
|
||||
BUILD_DIR := node_modules/build
|
||||
ENC_BUILD_DIR := $(BUILD_DIR)/enc
|
||||
ENC_MT_BUILD_DIR := $(BUILD_DIR)/enc-mt
|
||||
DEC_BUILD_DIR := $(BUILD_DIR)/dec
|
||||
export LIBAOM_DIR = node_modules/libaom
|
||||
|
||||
OUT_ENC_JS = enc/avif_enc.js
|
||||
OUT_ENC_MT_JS = enc/avif_enc_mt.js
|
||||
OUT_DEC_JS = dec/avif_dec.js
|
||||
|
||||
OUT_ENC_CPP = enc/avif_enc.cpp
|
||||
OUT_DEC_CPP = dec/avif_dec.cpp
|
||||
|
||||
HELPER_MAKEFLAGS := -f helper.Makefile
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(OUT_JS)
|
||||
all: $(OUT_ENC_JS) $(OUT_DEC_JS) $(OUT_ENC_MT_JS)
|
||||
|
||||
%.js: %.cpp $(LIBAOM_OUT) $(CODEC_OUT)
|
||||
$(CXX) \
|
||||
-I $(CODEC_DIR)/include \
|
||||
${CXXFLAGS} \
|
||||
${LDFLAGS} \
|
||||
--bind \
|
||||
--closure 1 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s MODULARIZE=1 \
|
||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
||||
-o $@ \
|
||||
$+
|
||||
$(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
||||
$(MAKE) \
|
||||
$(HELPER_MAKEFLAGS) \
|
||||
BUILD_DIR=$(ENC_BUILD_DIR) \
|
||||
OUT_JS=$@ \
|
||||
OUT_CPP=$< \
|
||||
LIBAOM_FLAGS="\
|
||||
-DCONFIG_AV1_DECODER=0 \
|
||||
-DCONFIG_MULTITHREAD=0 \
|
||||
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
||||
" \
|
||||
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0"
|
||||
|
||||
$(CODEC_OUT): $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_OUT)
|
||||
mkdir -p $(CODEC_BUILD_DIR)
|
||||
cd $(CODEC_BUILD_DIR) && \
|
||||
emcmake cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_SHARED_LIBS=0 \
|
||||
-DAVIF_CODEC_AOM=1 \
|
||||
-DAVIF_LOCAL_AOM=1 \
|
||||
../ && \
|
||||
$(MAKE)
|
||||
$(OUT_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
||||
$(MAKE) \
|
||||
$(HELPER_MAKEFLAGS) \
|
||||
BUILD_DIR=$(ENC_MT_BUILD_DIR) \
|
||||
OUT_JS=$@ \
|
||||
OUT_CPP=$< \
|
||||
LIBAOM_FLAGS="\
|
||||
-DCONFIG_AV1_DECODER=0 \
|
||||
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
||||
" \
|
||||
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0" \
|
||||
OUT_FLAGS="-pthread"
|
||||
|
||||
$(LIBAOM_OUT): $(LIBAOM_DIR)/CMakeLists.txt
|
||||
mkdir -p $(LIBAOM_BUILD_DIR)
|
||||
cd $(LIBAOM_BUILD_DIR) && \
|
||||
emcmake cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DENABLE_CCACHE=0 \
|
||||
-DAOM_TARGET_CPU=generic \
|
||||
-DENABLE_DOCS=0 \
|
||||
-DENABLE_TESTS=0 \
|
||||
-DENABLE_EXAMPLES=0 \
|
||||
-DENABLE_TOOLS=0 \
|
||||
-DCONFIG_ACCOUNTING=1 \
|
||||
-DCONFIG_INSPECTION=0 \
|
||||
-DCONFIG_MULTITHREAD=0 \
|
||||
-DCONFIG_RUNTIME_CPU_DETECT=0 \
|
||||
-DCONFIG_WEBM_IO=0 \
|
||||
../ && \
|
||||
$(MAKE)
|
||||
$(OUT_DEC_JS): $(OUT_DEC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
||||
$(MAKE) \
|
||||
$(HELPER_MAKEFLAGS) \
|
||||
BUILD_DIR=$(DEC_BUILD_DIR) \
|
||||
OUT_JS=$@ \
|
||||
OUT_CPP=$< \
|
||||
LIBAOM_FLAGS="\
|
||||
-DCONFIG_AV1_ENCODER=0 \
|
||||
-DCONFIG_MULTITHREAD=0 \
|
||||
" \
|
||||
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_ENCODE=0"
|
||||
|
||||
$(CODEC_DIR)/CMakeLists.txt: $(CODEC_DIR)
|
||||
$(CODEC_PACKAGE):
|
||||
mkdir -p $(@D)
|
||||
curl -sL $(CODEC_URL) -o $@
|
||||
|
||||
$(LIBAOM_DIR)/CMakeLists.txt: $(LIBAOM_DIR)
|
||||
$(LIBAOM_PACKAGE):
|
||||
mkdir -p $(@D)
|
||||
curl -sL $(LIBAOM_URL) -o $@
|
||||
|
||||
$(CODEC_DIR):
|
||||
mkdir -p $@
|
||||
curl -sL $(CODEC_URL) | tar xz --strip 1 -C $@
|
||||
$(CODEC_DIR)/CMakeLists.txt: $(CODEC_PACKAGE)
|
||||
mkdir -p $(@D)
|
||||
tar xzm --strip 1 -C $(@D) -f $(CODEC_PACKAGE)
|
||||
|
||||
$(LIBAOM_DIR):
|
||||
mkdir -p $@
|
||||
curl -sL $(LIBAOM_URL) | tar xz -C $@
|
||||
$(LIBAOM_DIR)/CMakeLists.txt: $(LIBAOM_PACKAGE)
|
||||
mkdir -p $(@D)
|
||||
tar xzm -C $(@D) -f $(LIBAOM_PACKAGE)
|
||||
|
||||
clean:
|
||||
$(RM) $(OUT_JS) $(OUT_WASM)
|
||||
$(MAKE) -C $(CODEC_BUILD_DIR) clean
|
||||
$(MAKE) -C $(LIBAOM_BUILD_DIR) clean
|
||||
$(MAKE) $(HELPER_MAKEFLAGS) BUILD_DIR=$(ENC_BUILD_DIR) OUT_JS=$(OUT_ENC_JS) clean
|
||||
$(MAKE) $(HELPER_MAKEFLAGS) BUILD_DIR=$(ENC_MT_BUILD_DIR) OUT_JS=$(OUT_ENC_MT_JS) clean
|
||||
$(MAKE) $(HELPER_MAKEFLAGS) BUILD_DIR=$(DEC_BUILD_DIR) OUT_JS=$(OUT_DEC_JS) clean
|
||||
|
||||
@@ -8,15 +8,10 @@ thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");
|
||||
thread_local const val ImageData = val::global("ImageData");
|
||||
|
||||
val decode(std::string avifimage) {
|
||||
// point raw.data and raw.size to the contents of an .avif(s)
|
||||
avifROData raw = {
|
||||
.data = (uint8_t*)avifimage.c_str(),
|
||||
.size = avifimage.length()
|
||||
};
|
||||
|
||||
avifImage* image = avifImageCreateEmpty();
|
||||
avifDecoder* decoder = avifDecoderCreate();
|
||||
avifResult decodeResult = avifDecoderRead(decoder, image, &raw);
|
||||
avifResult decodeResult =
|
||||
avifDecoderReadMemory(decoder, image, (uint8_t*)avifimage.c_str(), avifimage.length());
|
||||
// image is an independent copy of decoded data, decoder may be destroyed here
|
||||
avifDecoderDestroy(decoder);
|
||||
|
||||
@@ -25,7 +20,8 @@ val decode(std::string avifimage) {
|
||||
if (decodeResult == AVIF_RESULT_OK) {
|
||||
// Convert to interleaved RGB(A)/BGR(A) using a libavif-allocated buffer.
|
||||
avifRGBImage rgb;
|
||||
avifRGBImageSetDefaults(&rgb, image); // Defaults to AVIF_RGB_FORMAT_RGBA which is what we want.
|
||||
avifRGBImageSetDefaults(&rgb,
|
||||
image); // Defaults to AVIF_RGB_FORMAT_RGBA which is what we want.
|
||||
rgb.depth = 8; // Does not need to match image->depth. We always want 8-bit pixels.
|
||||
|
||||
avifRGBImageAllocatePixels(&rgb);
|
||||
@@ -33,7 +29,9 @@ val decode(std::string avifimage) {
|
||||
|
||||
// We want to create a *copy* of the decoded data to be owned by the JavaScript side.
|
||||
// For that, we perform `new Uint8Array(wasmMemBuffer, wasmPtr, wasmSize).slice()`:
|
||||
result = ImageData.new_(Uint8ClampedArray.new_(typed_memory_view(rgb.rowBytes * rgb.height, rgb.pixels)), rgb.width, rgb.height);
|
||||
result = ImageData.new_(
|
||||
Uint8ClampedArray.new_(typed_memory_view(rgb.rowBytes * rgb.height, rgb.pixels)), rgb.width,
|
||||
rgb.height);
|
||||
|
||||
// Now we can safely free the RGB pixels:
|
||||
avifRGBImageFreePixels(&rgb);
|
||||
|
||||
5
codecs/avif/dec/avif_dec.d.ts
vendored
5
codecs/avif/dec/avif_dec.d.ts
vendored
@@ -1,6 +1,7 @@
|
||||
interface AVIFModule extends EmscriptenWasm.Module {
|
||||
export interface AVIFModule extends EmscriptenWasm.Module {
|
||||
decode(data: BufferSource): ImageData | null;
|
||||
}
|
||||
|
||||
export default function(opts: EmscriptenWasm.ModuleOpts): AVIFModule;
|
||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<AVIFModule>;
|
||||
|
||||
export default moduleFactory;
|
||||
|
||||
1335
codecs/avif/dec/avif_dec.js
generated
1335
codecs/avif/dec/avif_dec.js
generated
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,4 +1,5 @@
|
||||
#include <emscripten/bind.h>
|
||||
#include <emscripten/threading.h>
|
||||
#include <emscripten/val.h>
|
||||
#include "avif/avif.h"
|
||||
|
||||
@@ -50,13 +51,10 @@ val encode(std::string buffer, int width, int height, AvifOptions options) {
|
||||
|
||||
avifImage* image = avifImageCreate(width, height, depth, format);
|
||||
|
||||
if (
|
||||
options.maxQuantizer == AVIF_QUANTIZER_LOSSLESS &&
|
||||
options.minQuantizer == AVIF_QUANTIZER_LOSSLESS &&
|
||||
options.minQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS &&
|
||||
options.maxQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS &&
|
||||
format == AVIF_PIXEL_FORMAT_YUV444
|
||||
) {
|
||||
if (options.maxQuantizer == AVIF_QUANTIZER_LOSSLESS &&
|
||||
options.minQuantizer == AVIF_QUANTIZER_LOSSLESS &&
|
||||
options.minQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS &&
|
||||
options.maxQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS && format == AVIF_PIXEL_FORMAT_YUV444) {
|
||||
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_IDENTITY;
|
||||
} else {
|
||||
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT709;
|
||||
@@ -71,7 +69,7 @@ val encode(std::string buffer, int width, int height, AvifOptions options) {
|
||||
avifImageRGBToYUV(image, &srcRGB);
|
||||
|
||||
avifEncoder* encoder = avifEncoderCreate();
|
||||
encoder->maxThreads = 1;
|
||||
encoder->maxThreads = emscripten_num_logical_cores();
|
||||
encoder->minQuantizer = options.minQuantizer;
|
||||
encoder->maxQuantizer = options.maxQuantizer;
|
||||
encoder->minQuantizerAlpha = options.minQuantizerAlpha;
|
||||
|
||||
26
codecs/avif/enc/avif_enc.d.ts
vendored
26
codecs/avif/enc/avif_enc.d.ts
vendored
@@ -1,7 +1,23 @@
|
||||
import { EncodeOptions } from '../../../src/codecs/avif/encoder-meta';
|
||||
|
||||
interface AVIFModule extends EmscriptenWasm.Module {
|
||||
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array | null;
|
||||
export interface EncodeOptions {
|
||||
minQuantizer: number;
|
||||
maxQuantizer: number;
|
||||
minQuantizerAlpha: number;
|
||||
maxQuantizerAlpha: number;
|
||||
tileRowsLog2: number;
|
||||
tileColsLog2: number;
|
||||
speed: number;
|
||||
subsample: number;
|
||||
}
|
||||
|
||||
export default function(opts: EmscriptenWasm.ModuleOpts): AVIFModule;
|
||||
export interface AVIFModule extends EmscriptenWasm.Module {
|
||||
encode(
|
||||
data: BufferSource,
|
||||
width: number,
|
||||
height: number,
|
||||
options: EncodeOptions,
|
||||
): Uint8Array | null;
|
||||
}
|
||||
|
||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<AVIFModule>;
|
||||
|
||||
export default moduleFactory;
|
||||
|
||||
2549
codecs/avif/enc/avif_enc.js
generated
2549
codecs/avif/enc/avif_enc.js
generated
File diff suppressed because it is too large
Load Diff
Binary file not shown.
2
codecs/avif/enc/avif_enc_mt.d.ts
vendored
Normal file
2
codecs/avif/enc/avif_enc_mt.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './avif_enc';
|
||||
export { default } from './avif_enc';
|
||||
3268
codecs/avif/enc/avif_enc_mt.js
generated
Normal file
3268
codecs/avif/enc/avif_enc_mt.js
generated
Normal file
File diff suppressed because it is too large
Load Diff
BIN
codecs/avif/enc/avif_enc_mt.wasm
Normal file
BIN
codecs/avif/enc/avif_enc_mt.wasm
Normal file
Binary file not shown.
103
codecs/avif/enc/avif_enc_mt.worker.js
generated
Normal file
103
codecs/avif/enc/avif_enc_mt.worker.js
generated
Normal file
@@ -0,0 +1,103 @@
|
||||
var threadInfoStruct = 0;
|
||||
var selfThreadId = 0;
|
||||
var parentThreadId = 0;
|
||||
var initializedJS = false;
|
||||
var Module = {};
|
||||
function threadPrintErr() {
|
||||
var text = Array.prototype.slice.call(arguments).join(' ');
|
||||
console.error(text);
|
||||
}
|
||||
function threadAlert() {
|
||||
var text = Array.prototype.slice.call(arguments).join(' ');
|
||||
postMessage({ cmd: 'alert', text: text, threadId: selfThreadId });
|
||||
}
|
||||
var err = threadPrintErr;
|
||||
this.alert = threadAlert;
|
||||
Module['instantiateWasm'] = function (info, receiveInstance) {
|
||||
var instance = new WebAssembly.Instance(Module['wasmModule'], info);
|
||||
Module['wasmModule'] = null;
|
||||
receiveInstance(instance);
|
||||
return instance.exports;
|
||||
};
|
||||
this.onmessage = function (e) {
|
||||
try {
|
||||
if (e.data.cmd === 'load') {
|
||||
Module['wasmModule'] = e.data.wasmModule;
|
||||
Module['wasmMemory'] = e.data.wasmMemory;
|
||||
Module['buffer'] = Module['wasmMemory'].buffer;
|
||||
Module['ENVIRONMENT_IS_PTHREAD'] = true;
|
||||
import(e.data.urlOrBlob)
|
||||
.then(function (avif_enc_mt) {
|
||||
return avif_enc_mt.default(Module);
|
||||
})
|
||||
.then(function (instance) {
|
||||
Module = instance;
|
||||
postMessage({ cmd: 'loaded' });
|
||||
});
|
||||
} else if (e.data.cmd === 'objectTransfer') {
|
||||
Module['PThread'].receiveObjectTransfer(e.data);
|
||||
} else if (e.data.cmd === 'run') {
|
||||
Module['__performance_now_clock_drift'] = performance.now() - e.data.time;
|
||||
threadInfoStruct = e.data.threadInfoStruct;
|
||||
Module['registerPthreadPtr'](
|
||||
threadInfoStruct,
|
||||
/*isMainBrowserThread=*/ 0,
|
||||
/*isMainRuntimeThread=*/ 0,
|
||||
);
|
||||
selfThreadId = e.data.selfThreadId;
|
||||
parentThreadId = e.data.parentThreadId;
|
||||
var max = e.data.stackBase;
|
||||
var top = e.data.stackBase + e.data.stackSize;
|
||||
Module['establishStackSpace'](top, max);
|
||||
Module['_emscripten_tls_init']();
|
||||
Module['PThread'].receiveObjectTransfer(e.data);
|
||||
Module['PThread'].setThreadStatus(Module['_pthread_self'](), 1);
|
||||
if (!initializedJS) {
|
||||
Module['___embind_register_native_and_builtin_types']();
|
||||
initializedJS = true;
|
||||
}
|
||||
try {
|
||||
var result = Module['dynCall']('ii', e.data.start_routine, [
|
||||
e.data.arg,
|
||||
]);
|
||||
if (!Module['getNoExitRuntime']()) Module['PThread'].threadExit(result);
|
||||
} catch (ex) {
|
||||
if (ex === 'Canceled!') {
|
||||
Module['PThread'].threadCancel();
|
||||
} else if (ex != 'unwind') {
|
||||
Atomics.store(
|
||||
Module['HEAPU32'],
|
||||
(threadInfoStruct + 4) >> /*C_STRUCTS.pthread.threadExitCode*/ 2,
|
||||
ex instanceof Module['ExitStatus'] ? ex.status : -2,
|
||||
);
|
||||
/*A custom entry specific to Emscripten denoting that the thread crashed.*/ Atomics.store(
|
||||
Module['HEAPU32'],
|
||||
(threadInfoStruct + 0) >> /*C_STRUCTS.pthread.threadStatus*/ 2,
|
||||
1,
|
||||
);
|
||||
Module['_emscripten_futex_wake'](
|
||||
threadInfoStruct + 0,
|
||||
/*C_STRUCTS.pthread.threadStatus*/ 2147483647,
|
||||
);
|
||||
if (!(ex instanceof Module['ExitStatus'])) throw ex;
|
||||
}
|
||||
}
|
||||
} else if (e.data.cmd === 'cancel') {
|
||||
if (threadInfoStruct) {
|
||||
Module['PThread'].threadCancel();
|
||||
}
|
||||
} else if (e.data.target === 'setimmediate') {
|
||||
} else if (e.data.cmd === 'processThreadQueue') {
|
||||
if (threadInfoStruct) {
|
||||
Module['_emscripten_current_thread_process_queued_calls']();
|
||||
}
|
||||
} else {
|
||||
err('worker.js received unknown command ' + e.data.cmd);
|
||||
err(e.data);
|
||||
}
|
||||
} catch (ex) {
|
||||
err('worker.js onmessage() captured an uncaught exception: ' + ex);
|
||||
if (ex && ex.stack) err(ex.stack);
|
||||
throw ex;
|
||||
}
|
||||
};
|
||||
75
codecs/avif/helper.Makefile
Normal file
75
codecs/avif/helper.Makefile
Normal file
@@ -0,0 +1,75 @@
|
||||
# This is a helper Makefile for building LibAVIF + LibAOM with given params.
|
||||
#
|
||||
# Params that must be supplied by the caller:
|
||||
# $(CODEC_DIR)
|
||||
# $(LIBAOM_DIR)
|
||||
# $(BUILD_DIR)
|
||||
# $(OUT_JS)
|
||||
# $(OUT_CPP)
|
||||
# $(LIBAOM_FLAGS)
|
||||
# $(LIBAVIF_FLAGS)
|
||||
|
||||
CODEC_BUILD_DIR := $(BUILD_DIR)/libavif
|
||||
CODEC_OUT := $(CODEC_BUILD_DIR)/libavif.a
|
||||
|
||||
LIBAOM_BUILD_DIR := $(BUILD_DIR)/libaom
|
||||
LIBAOM_OUT := $(LIBAOM_BUILD_DIR)/libaom.a
|
||||
|
||||
OUT_WASM = $(OUT_JS:.js=.wasm)
|
||||
OUT_WORKER=$(OUT_JS:.js=.worker.js)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(OUT_JS)
|
||||
|
||||
$(OUT_JS): $(OUT_CPP) $(LIBAOM_OUT) $(CODEC_OUT)
|
||||
$(CXX) \
|
||||
-I $(CODEC_DIR)/include \
|
||||
$(CXXFLAGS) \
|
||||
$(LDFLAGS) \
|
||||
$(OUT_FLAGS) \
|
||||
--bind \
|
||||
--closure 1 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s MODULARIZE=1 \
|
||||
-s TEXTDECODER=2 \
|
||||
-s ENVIRONMENT='worker' \
|
||||
-s EXPORT_ES6=1 \
|
||||
-s EXPORT_NAME="$(basename $(@F))" \
|
||||
-o $@ \
|
||||
$+
|
||||
|
||||
$(CODEC_OUT): $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_OUT)
|
||||
emcmake cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DBUILD_SHARED_LIBS=0 \
|
||||
-DAVIF_CODEC_AOM=1 \
|
||||
-DAOM_LIBRARY=$(LIBAOM_OUT) \
|
||||
-DAOM_INCLUDE_DIR=$(LIBAOM_DIR) \
|
||||
$(LIBAVIF_FLAGS) \
|
||||
-B $(CODEC_BUILD_DIR) \
|
||||
$(CODEC_DIR) && \
|
||||
$(MAKE) -C $(CODEC_BUILD_DIR)
|
||||
|
||||
$(LIBAOM_OUT): $(LIBAOM_DIR)/CMakeLists.txt
|
||||
emcmake cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DENABLE_CCACHE=0 \
|
||||
-DAOM_TARGET_CPU=generic \
|
||||
-DENABLE_DOCS=0 \
|
||||
-DENABLE_TESTS=0 \
|
||||
-DENABLE_EXAMPLES=0 \
|
||||
-DENABLE_TOOLS=0 \
|
||||
-DCONFIG_ACCOUNTING=1 \
|
||||
-DCONFIG_INSPECTION=0 \
|
||||
-DCONFIG_RUNTIME_CPU_DETECT=0 \
|
||||
-DCONFIG_WEBM_IO=0 \
|
||||
$(LIBAOM_FLAGS) \
|
||||
-B $(LIBAOM_BUILD_DIR) \
|
||||
$(LIBAOM_DIR) && \
|
||||
$(MAKE) -C $(LIBAOM_BUILD_DIR)
|
||||
|
||||
clean:
|
||||
$(RM) $(OUT_JS) $(OUT_WASM) $(OUT_WORKER)
|
||||
$(MAKE) -C $(CODEC_BUILD_DIR) clean
|
||||
$(MAKE) -C $(LIBAOM_BUILD_DIR) clean
|
||||
@@ -1,4 +1,10 @@
|
||||
set -e
|
||||
|
||||
docker build -t squoosh-rust - < ../rust.Dockerfile
|
||||
docker run --rm -v $PWD:/src squoosh-rust "$@"
|
||||
if [ ! -z "$RUST_IMG" ]
|
||||
then
|
||||
# Get part after ":" (https://stackoverflow.com/a/15149278/439965).
|
||||
IMG_SUFFIX=-${RUST_IMG#*:}
|
||||
fi
|
||||
IMG_NAME=squoosh-rust$IMG_SUFFIX
|
||||
docker build -t $IMG_NAME --build-arg RUST_IMG - < ../rust.Dockerfile
|
||||
docker run --rm -v $PWD:/src $IMG_NAME "$@"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
FROM emscripten/emsdk:1.40.0
|
||||
FROM emscripten/emsdk:2.0.8
|
||||
RUN apt-get update && apt-get install -qqy autoconf libtool pkg-config
|
||||
ENV CFLAGS "-Os -flto"
|
||||
ENV CFLAGS "-O3 -flto"
|
||||
ENV CXXFLAGS "${CFLAGS} -std=c++17"
|
||||
ENV LDFLAGS "${CFLAGS}"
|
||||
ENV LDFLAGS "${CFLAGS} -s PTHREAD_POOL_SIZE=navigator.hardwareConcurrency"
|
||||
# Build and cache standard libraries with these flags
|
||||
RUN emcc ${CXXFLAGS} --bind -xc++ /dev/null -o /dev/null
|
||||
WORKDIR /src
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# This is intentionally an old version of Rust. Newer versions
|
||||
# generate _significantly_ bigger Wasm binaries.
|
||||
FROM rust:1.37
|
||||
RUN rustup target add wasm32-unknown-unknown
|
||||
RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||
|
||||
RUN mkdir /opt/binaryen && \
|
||||
curl -L https://github.com/WebAssembly/binaryen/releases/download/1.38.32/binaryen-1.38.32-x86-linux.tar.gz | tar -xzf - -C /opt/binaryen --strip 1
|
||||
|
||||
ENV PATH="/opt/binaryen:${PATH}"
|
||||
WORKDIR /src
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "============================================="
|
||||
echo "Compiling wasm"
|
||||
echo "============================================="
|
||||
(
|
||||
wasm-pack build -- --verbose --locked
|
||||
rm pkg/.gitignore
|
||||
)
|
||||
echo "============================================="
|
||||
echo "Compiling wasm done"
|
||||
echo "============================================="
|
||||
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
echo "Did you update your docker image?"
|
||||
echo "Run \`docker pull ubuntu\`"
|
||||
echo "Run \`docker pull rust\`"
|
||||
echo "Run \`docker build -t squoosh-hqx .\`"
|
||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"name": "hqx",
|
||||
"scripts": {
|
||||
"build:image": "docker build -t squoosh-hqx - < Dockerfile",
|
||||
"build": "docker run --rm -v $(pwd):/src squoosh-hqx ./build.sh"
|
||||
"build": "RUST_IMG=rust:1.40 ../build-rust.sh"
|
||||
}
|
||||
}
|
||||
|
||||
5
codecs/hqx/pkg/README.md
Normal file
5
codecs/hqx/pkg/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# HQX
|
||||
|
||||
- Source: <https://github.com/CryZe/wasmboy-rs>
|
||||
- Version: v0.1.2
|
||||
- License: Apache 2.0
|
||||
52
codecs/hqx/pkg/squooshhqx.d.ts
generated
vendored
52
codecs/hqx/pkg/squooshhqx.d.ts
generated
vendored
@@ -1,10 +1,48 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* @param {Uint32Array} input_image
|
||||
* @param {number} input_width
|
||||
* @param {number} input_height
|
||||
* @param {number} factor
|
||||
* @returns {Uint32Array}
|
||||
*/
|
||||
export function resize(input_image: Uint32Array, input_width: number, input_height: number, factor: number): Uint32Array;
|
||||
* @param {Uint32Array} input_image
|
||||
* @param {number} input_width
|
||||
* @param {number} input_height
|
||||
* @param {number} factor
|
||||
* @returns {Uint32Array}
|
||||
*/
|
||||
export function resize(
|
||||
input_image: Uint32Array,
|
||||
input_width: number,
|
||||
input_height: number,
|
||||
factor: number,
|
||||
): Uint32Array;
|
||||
|
||||
export type InitInput =
|
||||
| RequestInfo
|
||||
| URL
|
||||
| Response
|
||||
| BufferSource
|
||||
| WebAssembly.Module;
|
||||
|
||||
export interface InitOutput {
|
||||
readonly memory: WebAssembly.Memory;
|
||||
readonly resize: (
|
||||
a: number,
|
||||
b: number,
|
||||
c: number,
|
||||
d: number,
|
||||
e: number,
|
||||
f: number,
|
||||
) => void;
|
||||
readonly __wbindgen_malloc: (a: number) => number;
|
||||
readonly __wbindgen_free: (a: number, b: number) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
||||
* for everything else, calls `WebAssembly.instantiate` directly.
|
||||
*
|
||||
* @param {InitInput | Promise<InitInput>} module_or_path
|
||||
*
|
||||
* @returns {Promise<InitOutput>}
|
||||
*/
|
||||
export default function init(
|
||||
module_or_path?: InitInput | Promise<InitInput>,
|
||||
): Promise<InitOutput>;
|
||||
|
||||
109
codecs/hqx/pkg/squooshhqx.js
generated
109
codecs/hqx/pkg/squooshhqx.js
generated
@@ -1,2 +1,107 @@
|
||||
import * as wasm from "./squooshhqx_bg.wasm";
|
||||
export * from "./squooshhqx_bg.js";
|
||||
let wasm;
|
||||
|
||||
let cachegetUint32Memory0 = null;
|
||||
function getUint32Memory0() {
|
||||
if (
|
||||
cachegetUint32Memory0 === null ||
|
||||
cachegetUint32Memory0.buffer !== wasm.memory.buffer
|
||||
) {
|
||||
cachegetUint32Memory0 = new Uint32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetUint32Memory0;
|
||||
}
|
||||
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
|
||||
function passArray32ToWasm0(arg, malloc) {
|
||||
const ptr = malloc(arg.length * 4);
|
||||
getUint32Memory0().set(arg, ptr / 4);
|
||||
WASM_VECTOR_LEN = arg.length;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let cachegetInt32Memory0 = null;
|
||||
function getInt32Memory0() {
|
||||
if (
|
||||
cachegetInt32Memory0 === null ||
|
||||
cachegetInt32Memory0.buffer !== wasm.memory.buffer
|
||||
) {
|
||||
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetInt32Memory0;
|
||||
}
|
||||
|
||||
function getArrayU32FromWasm0(ptr, len) {
|
||||
return getUint32Memory0().subarray(ptr / 4, ptr / 4 + len);
|
||||
}
|
||||
/**
|
||||
* @param {Uint32Array} input_image
|
||||
* @param {number} input_width
|
||||
* @param {number} input_height
|
||||
* @param {number} factor
|
||||
* @returns {Uint32Array}
|
||||
*/
|
||||
export function resize(input_image, input_width, input_height, factor) {
|
||||
var ptr0 = passArray32ToWasm0(input_image, wasm.__wbindgen_malloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
wasm.resize(8, ptr0, len0, input_width, input_height, factor);
|
||||
var r0 = getInt32Memory0()[8 / 4 + 0];
|
||||
var r1 = getInt32Memory0()[8 / 4 + 1];
|
||||
var v1 = getArrayU32FromWasm0(r0, r1).slice();
|
||||
wasm.__wbindgen_free(r0, r1 * 4);
|
||||
return v1;
|
||||
}
|
||||
|
||||
async function load(module, imports) {
|
||||
if (typeof Response === 'function' && module instanceof Response) {
|
||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
try {
|
||||
return await WebAssembly.instantiateStreaming(module, imports);
|
||||
} catch (e) {
|
||||
if (module.headers.get('Content-Type') != 'application/wasm') {
|
||||
console.warn(
|
||||
'`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n',
|
||||
e,
|
||||
);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bytes = await module.arrayBuffer();
|
||||
return await WebAssembly.instantiate(bytes, imports);
|
||||
} else {
|
||||
const instance = await WebAssembly.instantiate(module, imports);
|
||||
|
||||
if (instance instanceof WebAssembly.Instance) {
|
||||
return { instance, module };
|
||||
} else {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function init(input) {
|
||||
if (typeof input === 'undefined') {
|
||||
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
|
||||
}
|
||||
const imports = {};
|
||||
|
||||
if (
|
||||
typeof input === 'string' ||
|
||||
(typeof Request === 'function' && input instanceof Request) ||
|
||||
(typeof URL === 'function' && input instanceof URL)
|
||||
) {
|
||||
input = fetch(input);
|
||||
}
|
||||
|
||||
const { instance, module } = await load(await input, imports);
|
||||
|
||||
wasm = instance.exports;
|
||||
init.__wbindgen_wasm_module = module;
|
||||
|
||||
return wasm;
|
||||
}
|
||||
|
||||
export default init;
|
||||
|
||||
48
codecs/hqx/pkg/squooshhqx_bg.js
generated
48
codecs/hqx/pkg/squooshhqx_bg.js
generated
@@ -1,48 +0,0 @@
|
||||
import * as wasm from './squooshhqx_bg.wasm';
|
||||
|
||||
let cachegetUint32Memory0 = null;
|
||||
function getUint32Memory0() {
|
||||
if (cachegetUint32Memory0 === null || cachegetUint32Memory0.buffer !== wasm.memory.buffer) {
|
||||
cachegetUint32Memory0 = new Uint32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetUint32Memory0;
|
||||
}
|
||||
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
|
||||
function passArray32ToWasm0(arg, malloc) {
|
||||
const ptr = malloc(arg.length * 4);
|
||||
getUint32Memory0().set(arg, ptr / 4);
|
||||
WASM_VECTOR_LEN = arg.length;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let cachegetInt32Memory0 = null;
|
||||
function getInt32Memory0() {
|
||||
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
|
||||
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetInt32Memory0;
|
||||
}
|
||||
|
||||
function getArrayU32FromWasm0(ptr, len) {
|
||||
return getUint32Memory0().subarray(ptr / 4, ptr / 4 + len);
|
||||
}
|
||||
/**
|
||||
* @param {Uint32Array} input_image
|
||||
* @param {number} input_width
|
||||
* @param {number} input_height
|
||||
* @param {number} factor
|
||||
* @returns {Uint32Array}
|
||||
*/
|
||||
export function resize(input_image, input_width, input_height, factor) {
|
||||
var ptr0 = passArray32ToWasm0(input_image, wasm.__wbindgen_malloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
wasm.resize(8, ptr0, len0, input_width, input_height, factor);
|
||||
var r0 = getInt32Memory0()[8 / 4 + 0];
|
||||
var r1 = getInt32Memory0()[8 / 4 + 1];
|
||||
var v1 = getArrayU32FromWasm0(r0, r1).slice();
|
||||
wasm.__wbindgen_free(r0, r1 * 4);
|
||||
return v1;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -18,7 +18,9 @@ all: $(OUT_JS)
|
||||
--closure 1 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s MODULARIZE=1 \
|
||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
||||
-s TEXTDECODER=2 \
|
||||
-s ENVIRONMENT='worker' \
|
||||
-s EXPORT_ES6=1 \
|
||||
-o $@ \
|
||||
$+
|
||||
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<style>
|
||||
canvas {
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
</style>
|
||||
<script src='imagequant.js'></script>
|
||||
<script>
|
||||
const Module = imagequant();
|
||||
<script type="module">
|
||||
import imagequant from './imagequant.js';
|
||||
|
||||
async function loadImage(src) {
|
||||
// Load image
|
||||
const img = document.createElement('img');
|
||||
img.src = src;
|
||||
await new Promise(resolve => img.onload = resolve);
|
||||
await new Promise((resolve) => (img.onload = resolve));
|
||||
// Make canvas same size as image
|
||||
const canvas = document.createElement('canvas');
|
||||
[canvas.width, canvas.height] = [img.width, img.height];
|
||||
@@ -22,19 +21,32 @@
|
||||
return ctx.getImageData(0, 0, img.width, img.height);
|
||||
}
|
||||
|
||||
Module.onRuntimeInitialized = async _ => {
|
||||
console.log('Version:', Module.version().toString(16));
|
||||
async function main() {
|
||||
const module = await imagequant();
|
||||
|
||||
console.log('Version:', module.version().toString(16));
|
||||
const image = await loadImage('../example.png');
|
||||
// const rawImage = Module.quantize(image.data, image.width, image.height, 256, 1.0);
|
||||
const rawImage = Module.zx_quantize(image.data, image.width, image.height, 1.0);
|
||||
const rawImage = module.quantize(
|
||||
image.data,
|
||||
image.width,
|
||||
image.height,
|
||||
256,
|
||||
1.0,
|
||||
);
|
||||
console.log('done');
|
||||
|
||||
const imageData = new ImageData(new Uint8ClampedArray(rawImage.buffer), rawImage.width, rawImage.height);
|
||||
const imageData = new ImageData(
|
||||
new Uint8ClampedArray(rawImage.buffer),
|
||||
image.width,
|
||||
image.height,
|
||||
);
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = image.width;
|
||||
canvas.height = image.height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
document.body.appendChild(canvas);
|
||||
};
|
||||
}
|
||||
|
||||
main();
|
||||
</script>
|
||||
|
||||
21
codecs/imagequant/imagequant.d.ts
vendored
21
codecs/imagequant/imagequant.d.ts
vendored
@@ -1,6 +1,19 @@
|
||||
interface QuantizerModule extends EmscriptenWasm.Module {
|
||||
quantize(data: BufferSource, width: number, height: number, numColors: number, dither: number): Uint8ClampedArray;
|
||||
zx_quantize(data: BufferSource, width: number, height: number, dither: number): Uint8ClampedArray;
|
||||
export interface QuantizerModule extends EmscriptenWasm.Module {
|
||||
quantize(
|
||||
data: BufferSource,
|
||||
width: number,
|
||||
height: number,
|
||||
numColors: number,
|
||||
dither: number,
|
||||
): Uint8ClampedArray;
|
||||
zx_quantize(
|
||||
data: BufferSource,
|
||||
width: number,
|
||||
height: number,
|
||||
dither: number,
|
||||
): Uint8ClampedArray;
|
||||
}
|
||||
|
||||
export default function(opts: EmscriptenWasm.ModuleOpts): QuantizerModule;
|
||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<QuantizerModule>;
|
||||
|
||||
export default moduleFactory;
|
||||
|
||||
1198
codecs/imagequant/imagequant.js
generated
1198
codecs/imagequant/imagequant.js
generated
File diff suppressed because it is too large
Load Diff
BIN
codecs/imagequant/imagequant.wasm
Normal file → Executable file
BIN
codecs/imagequant/imagequant.wasm
Normal file → Executable file
Binary file not shown.
59
codecs/jxl/Makefile
Normal file
59
codecs/jxl/Makefile
Normal file
@@ -0,0 +1,59 @@
|
||||
CODEC_URL = https://gitlab.com/wg1/jpeg-xl.git
|
||||
CODEC_VERSION = v0.1
|
||||
CODEC_DIR = node_modules/jxl
|
||||
CODEC_BUILD_DIR := $(CODEC_DIR)/build
|
||||
CODEC_OUT := $(CODEC_BUILD_DIR)/lib/libjxl.a
|
||||
|
||||
OUT_JS = enc/jxl_enc.js dec/jxl_dec.js
|
||||
OUT_WASM = $(OUT_JS:.js=.wasm)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(OUT_JS)
|
||||
|
||||
%.js: %.cpp $(LIBAOM_OUT) $(CODEC_OUT)
|
||||
$(CXX) \
|
||||
-I $(CODEC_DIR) \
|
||||
-I $(CODEC_DIR)/lib \
|
||||
-I $(CODEC_DIR)/lib/include \
|
||||
-I $(CODEC_BUILD_DIR)/lib/include \
|
||||
-I $(CODEC_DIR)/third_party/highway \
|
||||
-I $(CODEC_DIR)/third_party/skcms \
|
||||
-I $(CODEC_DIR)/third_party/brunsli \
|
||||
-I $(CODEC_DIR)/third_party/brunsli/c/include \
|
||||
${CXXFLAGS} \
|
||||
${LDFLAGS} \
|
||||
--bind \
|
||||
--closure 1 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s MODULARIZE=1 \
|
||||
-s TEXTDECODER=2 \
|
||||
-s ENVIRONMENT='worker' \
|
||||
-s EXPORT_ES6=1 \
|
||||
-s EXPORT_NAME="$(basename $(@F))" \
|
||||
-o $@ \
|
||||
$+ \
|
||||
$(CODEC_BUILD_DIR)/artifacts/libbrunslienc-static.bc \
|
||||
$(CODEC_BUILD_DIR)/artifacts/libbrunslicommon-static.bc \
|
||||
$(CODEC_BUILD_DIR)/artifacts/libbrunslidec-static.bc \
|
||||
$(CODEC_BUILD_DIR)/third_party/brotli/libbrotlidec-static.a \
|
||||
$(CODEC_BUILD_DIR)/third_party/brotli/libbrotlienc-static.a \
|
||||
$(CODEC_BUILD_DIR)/third_party/brotli/libbrotlicommon-static.a \
|
||||
$(CODEC_BUILD_DIR)/third_party/libskcms.a \
|
||||
$(CODEC_BUILD_DIR)/third_party/highway/libhwy.a
|
||||
|
||||
$(CODEC_OUT): $(CODEC_DIR)/CMakeLists.txt
|
||||
mkdir -p $(CODEC_BUILD_DIR)
|
||||
cd $(CODEC_BUILD_DIR) && \
|
||||
emcmake cmake ../ && \
|
||||
$(MAKE) jxl-static
|
||||
|
||||
$(CODEC_DIR)/CMakeLists.txt: $(CODEC_DIR)
|
||||
|
||||
$(CODEC_DIR):
|
||||
mkdir -p $@
|
||||
git clone $(CODEC_URL) --recursive -j`nproc` --depth 1 --branch $(CODEC_VERSION) $@
|
||||
|
||||
clean:
|
||||
$(RM) $(OUT_JS) $(OUT_WASM)
|
||||
$(MAKE) -C $(CODEC_BUILD_DIR) clean
|
||||
93
codecs/jxl/dec/jxl_dec.cpp
Normal file
93
codecs/jxl/dec/jxl_dec.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
#include <emscripten/bind.h>
|
||||
#include <emscripten/val.h>
|
||||
|
||||
#include <jxl/decode.h>
|
||||
#include "lib/jxl/color_encoding_internal.h"
|
||||
|
||||
#include "skcms.h"
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");
|
||||
thread_local const val ImageData = val::global("ImageData");
|
||||
|
||||
// R, G, B, A
|
||||
#define COMPONENTS_PER_PIXEL 4
|
||||
|
||||
#ifndef JXL_DEBUG_ON_ALL_ERROR
|
||||
#define JXL_DEBUG_ON_ALL_ERROR 0
|
||||
#endif
|
||||
|
||||
#if JXL_DEBUG_ON_ALL_ERROR
|
||||
#define EXPECT_TRUE(a) \
|
||||
if (!(a)) { \
|
||||
fprintf(stderr, "Assertion failure (%d): %s\n", __LINE__, #a); \
|
||||
return val::null(); \
|
||||
}
|
||||
#define EXPECT_EQ(a, b) \
|
||||
{ \
|
||||
int a_ = a; \
|
||||
int b_ = b; \
|
||||
if (a_ != b_) { \
|
||||
fprintf(stderr, "Assertion failure (%d): %s (%d) != %s (%d)\n", __LINE__, #a, a_, #b, b_); \
|
||||
return val::null(); \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define EXPECT_TRUE(a) \
|
||||
if (!(a)) { \
|
||||
return val::null(); \
|
||||
}
|
||||
|
||||
#define EXPECT_EQ(a, b) EXPECT_TRUE((a) == (b));
|
||||
#endif
|
||||
|
||||
val decode(std::string data) {
|
||||
std::unique_ptr<JxlDecoder,
|
||||
std::integral_constant<decltype(&JxlDecoderDestroy), JxlDecoderDestroy>>
|
||||
dec(JxlDecoderCreate(nullptr));
|
||||
EXPECT_EQ(JXL_DEC_SUCCESS,
|
||||
JxlDecoderSubscribeEvents(
|
||||
dec.get(), JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING | JXL_DEC_FULL_IMAGE));
|
||||
|
||||
auto next_in = (const uint8_t*)data.c_str();
|
||||
auto avail_in = data.size();
|
||||
EXPECT_EQ(JXL_DEC_BASIC_INFO, JxlDecoderProcessInput(dec.get(), &next_in, &avail_in));
|
||||
JxlBasicInfo info;
|
||||
EXPECT_EQ(JXL_DEC_SUCCESS, JxlDecoderGetBasicInfo(dec.get(), &info));
|
||||
size_t pixel_count = info.xsize * info.ysize;
|
||||
size_t component_count = pixel_count * COMPONENTS_PER_PIXEL;
|
||||
|
||||
EXPECT_EQ(JXL_DEC_COLOR_ENCODING, JxlDecoderProcessInput(dec.get(), &next_in, &avail_in));
|
||||
static const JxlPixelFormat format = {COMPONENTS_PER_PIXEL, JXL_TYPE_FLOAT, JXL_LITTLE_ENDIAN, 0};
|
||||
size_t icc_size;
|
||||
EXPECT_EQ(JXL_DEC_SUCCESS, JxlDecoderGetICCProfileSize(dec.get(), &format,
|
||||
JXL_COLOR_PROFILE_TARGET_DATA, &icc_size));
|
||||
std::vector<uint8_t> icc_profile(icc_size);
|
||||
EXPECT_EQ(JXL_DEC_SUCCESS,
|
||||
JxlDecoderGetColorAsICCProfile(dec.get(), &format, JXL_COLOR_PROFILE_TARGET_DATA,
|
||||
icc_profile.data(), icc_profile.size()));
|
||||
|
||||
auto float_pixels = std::make_unique<float[]>(component_count);
|
||||
EXPECT_EQ(JXL_DEC_SUCCESS, JxlDecoderSetImageOutBuffer(dec.get(), &format, float_pixels.get(),
|
||||
component_count * sizeof(float)));
|
||||
EXPECT_EQ(JXL_DEC_FULL_IMAGE, JxlDecoderProcessInput(dec.get(), &next_in, &avail_in));
|
||||
|
||||
auto byte_pixels = std::make_unique<uint8_t[]>(component_count);
|
||||
// Convert to sRGB.
|
||||
skcms_ICCProfile jxl_profile;
|
||||
EXPECT_TRUE(skcms_Parse(icc_profile.data(), icc_profile.size(), &jxl_profile));
|
||||
EXPECT_TRUE(skcms_Transform(
|
||||
float_pixels.get(), skcms_PixelFormat_RGBA_ffff,
|
||||
info.alpha_premultiplied ? skcms_AlphaFormat_PremulAsEncoded : skcms_AlphaFormat_Unpremul,
|
||||
&jxl_profile, byte_pixels.get(), skcms_PixelFormat_RGBA_8888, skcms_AlphaFormat_Unpremul,
|
||||
skcms_sRGB_profile(), pixel_count));
|
||||
|
||||
return ImageData.new_(
|
||||
Uint8ClampedArray.new_(typed_memory_view(component_count, byte_pixels.get())), info.xsize,
|
||||
info.ysize);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
function("decode", &decode);
|
||||
}
|
||||
7
codecs/jxl/dec/jxl_dec.d.ts
vendored
Normal file
7
codecs/jxl/dec/jxl_dec.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export interface JXLModule extends EmscriptenWasm.Module {
|
||||
decode(data: BufferSource): ImageData | null;
|
||||
}
|
||||
|
||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<JXLModule>;
|
||||
|
||||
export default moduleFactory;
|
||||
1195
codecs/jxl/dec/jxl_dec.js
generated
Normal file
1195
codecs/jxl/dec/jxl_dec.js
generated
Normal file
File diff suppressed because it is too large
Load Diff
BIN
codecs/jxl/dec/jxl_dec.wasm
Executable file
BIN
codecs/jxl/dec/jxl_dec.wasm
Executable file
Binary file not shown.
124
codecs/jxl/enc/jxl_enc.cpp
Normal file
124
codecs/jxl/enc/jxl_enc.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include <emscripten/bind.h>
|
||||
#include <emscripten/val.h>
|
||||
|
||||
#include "lib/jxl/enc_file.h"
|
||||
#include "lib/jxl/external_image.h"
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
||||
|
||||
struct JXLOptions {
|
||||
// 1 = slowest
|
||||
// 7 = fastest
|
||||
int speed;
|
||||
float quality;
|
||||
bool progressive;
|
||||
int epf;
|
||||
int nearLossless;
|
||||
bool lossyPalette;
|
||||
};
|
||||
|
||||
val encode(std::string image, int width, int height, JXLOptions options) {
|
||||
jxl::CompressParams cparams;
|
||||
jxl::PassesEncoderState passes_enc_state;
|
||||
jxl::CodecInOut io;
|
||||
jxl::PaddedBytes bytes;
|
||||
jxl::ImageBundle* main = &io.Main();
|
||||
|
||||
cparams.epf = options.epf;
|
||||
cparams.speed_tier = static_cast<jxl::SpeedTier>(options.speed);
|
||||
cparams.near_lossless = options.nearLossless;
|
||||
|
||||
if (options.lossyPalette) {
|
||||
cparams.lossy_palette = true;
|
||||
cparams.palette_colors = 0;
|
||||
cparams.options.predictor = jxl::Predictor::Zero;
|
||||
}
|
||||
|
||||
// Reduce memory usage of tree learning for lossless data.
|
||||
// TODO(veluca93): this is a mitigation for excessive memory usage in the JXL encoder.
|
||||
float megapixels = width * height * 0.000001;
|
||||
if (megapixels > 8) {
|
||||
cparams.options.nb_repeats = 0.1;
|
||||
} else if (megapixels > 4) {
|
||||
cparams.options.nb_repeats = 0.3;
|
||||
} else {
|
||||
// default is OK.
|
||||
}
|
||||
|
||||
float quality = options.quality;
|
||||
|
||||
// Quality settings roughly match libjpeg qualities.
|
||||
if (quality < 7 || quality == 100) {
|
||||
cparams.modular_mode = true;
|
||||
// Internal modular quality to roughly match VarDCT size.
|
||||
cparams.quality_pair.first = cparams.quality_pair.second =
|
||||
std::min(35 + (quality - 7) * 3.0f, 100.0f);
|
||||
} else {
|
||||
cparams.modular_mode = false;
|
||||
if (quality >= 30) {
|
||||
cparams.butteraugli_distance = 0.1 + (100 - quality) * 0.09;
|
||||
} else {
|
||||
cparams.butteraugli_distance = 6.4 + pow(2.5, (30 - quality) / 5.0f) / 6.25f;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.progressive) {
|
||||
cparams.qprogressive_mode = true;
|
||||
cparams.responsive = 1;
|
||||
if (!cparams.modular_mode) {
|
||||
cparams.progressive_dc = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (cparams.modular_mode) {
|
||||
if (cparams.quality_pair.first != 100 || cparams.quality_pair.second != 100) {
|
||||
cparams.color_transform = jxl::ColorTransform::kXYB;
|
||||
} else {
|
||||
cparams.color_transform = jxl::ColorTransform::kNone;
|
||||
}
|
||||
}
|
||||
|
||||
if (cparams.near_lossless) {
|
||||
// Near-lossless assumes -R 0
|
||||
cparams.responsive = 0;
|
||||
cparams.modular_mode = true;
|
||||
}
|
||||
|
||||
io.metadata.m.SetAlphaBits(8);
|
||||
if (!io.metadata.size.Set(width, height)) {
|
||||
return val::null();
|
||||
}
|
||||
|
||||
uint8_t* inBuffer = (uint8_t*)image.c_str();
|
||||
|
||||
auto result = jxl::ConvertImage(
|
||||
jxl::Span<const uint8_t>(reinterpret_cast<const uint8_t*>(image.data()), image.size()), width,
|
||||
height, jxl::ColorEncoding::SRGB(/*is_gray=*/false), /*has_alpha=*/true,
|
||||
/*alpha_is_premultiplied=*/false, /*bits_per_alpha=*/8, /*bits_per_sample=*/8,
|
||||
/*big_endian=*/false, /*flipped_y=*/false, /*pool=*/nullptr, main);
|
||||
|
||||
if (!result) {
|
||||
return val::null();
|
||||
}
|
||||
|
||||
auto js_result = val::null();
|
||||
if (EncodeFile(cparams, &io, &passes_enc_state, &bytes)) {
|
||||
js_result = Uint8Array.new_(typed_memory_view(bytes.size(), bytes.data()));
|
||||
}
|
||||
|
||||
return js_result;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
value_object<JXLOptions>("JXLOptions")
|
||||
.field("speed", &JXLOptions::speed)
|
||||
.field("quality", &JXLOptions::quality)
|
||||
.field("progressive", &JXLOptions::progressive)
|
||||
.field("nearLossless", &JXLOptions::nearLossless)
|
||||
.field("lossyPalette", &JXLOptions::lossyPalette)
|
||||
.field("epf", &JXLOptions::epf);
|
||||
|
||||
function("encode", &encode);
|
||||
}
|
||||
21
codecs/jxl/enc/jxl_enc.d.ts
vendored
Normal file
21
codecs/jxl/enc/jxl_enc.d.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
export interface EncodeOptions {
|
||||
speed: number;
|
||||
quality: number;
|
||||
progressive: boolean;
|
||||
epf: number;
|
||||
nearLossless: number;
|
||||
lossyPalette: boolean;
|
||||
}
|
||||
|
||||
export interface JXLModule extends EmscriptenWasm.Module {
|
||||
encode(
|
||||
data: BufferSource,
|
||||
width: number,
|
||||
height: number,
|
||||
options: EncodeOptions,
|
||||
): Uint8Array | null;
|
||||
}
|
||||
|
||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<JXLModule>;
|
||||
|
||||
export default moduleFactory;
|
||||
1606
codecs/jxl/enc/jxl_enc.js
generated
Normal file
1606
codecs/jxl/enc/jxl_enc.js
generated
Normal file
File diff suppressed because it is too large
Load Diff
BIN
codecs/jxl/enc/jxl_enc.wasm
Executable file
BIN
codecs/jxl/enc/jxl_enc.wasm
Executable file
Binary file not shown.
6
codecs/jxl/package.json
Normal file
6
codecs/jxl/package.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "jxl",
|
||||
"scripts": {
|
||||
"build": "../build-cpp.sh"
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,13 @@ all: $(OUT_JS)
|
||||
-I $(CODEC_DIR) \
|
||||
${CXXFLAGS} \
|
||||
${LDFLAGS} \
|
||||
--bind \
|
||||
--closure 1 \
|
||||
--bind \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s MODULARIZE=1 \
|
||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
||||
-s TEXTDECODER=2 \
|
||||
-s ENVIRONMENT='worker' \
|
||||
-s EXPORT_ES6=1 \
|
||||
-o $@ \
|
||||
$+
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
<!doctype html>
|
||||
<script src='mozjpeg_enc.js'></script>
|
||||
<script>
|
||||
const module = mozjpeg_enc();
|
||||
<!DOCTYPE html>
|
||||
<script type="module">
|
||||
import mozjpeg_enc from './mozjpeg_enc.js';
|
||||
|
||||
async function loadImage(src) {
|
||||
// Load image
|
||||
const img = document.createElement('img');
|
||||
img.src = src;
|
||||
await new Promise(resolve => img.onload = resolve);
|
||||
await new Promise((resolve) => (img.onload = resolve));
|
||||
// Make canvas same size as image
|
||||
const canvas = document.createElement('canvas');
|
||||
[canvas.width, canvas.height] = [img.width, img.height];
|
||||
@@ -17,7 +16,9 @@
|
||||
return ctx.getImageData(0, 0, img.width, img.height);
|
||||
}
|
||||
|
||||
module.onRuntimeInitialized = async _ => {
|
||||
async function main() {
|
||||
const module = await mozjpeg_enc();
|
||||
|
||||
console.log('Version:', module.version().toString(16));
|
||||
const image = await loadImage('../example.png');
|
||||
const result = module.encode(image.data, image.width, image.height, {
|
||||
@@ -39,10 +40,12 @@
|
||||
chroma_quality: 75,
|
||||
});
|
||||
|
||||
const blob = new Blob([result], {type: 'image/jpeg'});
|
||||
const blob = new Blob([result], { type: 'image/jpeg' });
|
||||
const blobURL = URL.createObjectURL(blob);
|
||||
const img = document.createElement('img');
|
||||
img.src = blobURL;
|
||||
document.body.appendChild(img);
|
||||
};
|
||||
}
|
||||
|
||||
main();
|
||||
</script>
|
||||
|
||||
40
codecs/mozjpeg_enc/mozjpeg_enc.d.ts
vendored
40
codecs/mozjpeg_enc/mozjpeg_enc.d.ts
vendored
@@ -1,7 +1,37 @@
|
||||
import { EncodeOptions } from '../../src/codecs/mozjpeg/encoder-meta';
|
||||
|
||||
interface MozJPEGModule extends EmscriptenWasm.Module {
|
||||
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array;
|
||||
export const enum MozJpegColorSpace {
|
||||
GRAYSCALE = 1,
|
||||
RGB,
|
||||
YCbCr,
|
||||
}
|
||||
|
||||
export default function(opts: EmscriptenWasm.ModuleOpts): MozJPEGModule;
|
||||
export interface EncodeOptions {
|
||||
quality: number;
|
||||
baseline: boolean;
|
||||
arithmetic: boolean;
|
||||
progressive: boolean;
|
||||
optimize_coding: boolean;
|
||||
smoothing: number;
|
||||
color_space: MozJpegColorSpace;
|
||||
quant_table: number;
|
||||
trellis_multipass: boolean;
|
||||
trellis_opt_zero: boolean;
|
||||
trellis_opt_table: boolean;
|
||||
trellis_loops: number;
|
||||
auto_subsample: boolean;
|
||||
chroma_subsample: number;
|
||||
separate_chroma_quality: boolean;
|
||||
chroma_quality: number;
|
||||
}
|
||||
|
||||
export interface MozJPEGModule extends EmscriptenWasm.Module {
|
||||
encode(
|
||||
data: BufferSource,
|
||||
width: number,
|
||||
height: number,
|
||||
options: EncodeOptions,
|
||||
): Uint8Array;
|
||||
}
|
||||
|
||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<MozJPEGModule>;
|
||||
|
||||
export default moduleFactory;
|
||||
|
||||
1345
codecs/mozjpeg_enc/mozjpeg_enc.js
generated
1345
codecs/mozjpeg_enc/mozjpeg_enc.js
generated
File diff suppressed because it is too large
Load Diff
BIN
codecs/mozjpeg_enc/mozjpeg_enc.wasm
Normal file → Executable file
BIN
codecs/mozjpeg_enc/mozjpeg_enc.wasm
Normal file → Executable file
Binary file not shown.
299
codecs/oxipng/Cargo.lock
generated
299
codecs/oxipng/Cargo.lock
generated
@@ -1,16 +1,22 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.1.0"
|
||||
name = "adler"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d"
|
||||
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
|
||||
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
@@ -38,9 +44,9 @@ checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.2.0"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37fa13df2292ecb479ec23aa06f4507928bef07839be9ef15281411076629431"
|
||||
checksum = "41aa2ec95ca3b5c54cf73c91acf06d24f4495d5f1b1c12506ae3483d646177ac"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
@@ -50,9 +56,9 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.58"
|
||||
version = "1.0.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518"
|
||||
checksum = "f1770ced377336a88a67c473594ccc14eca6f4559217c34f64aac8f83d641b40"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@@ -60,6 +66,12 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cloudflare-zlib"
|
||||
version = "0.2.5"
|
||||
@@ -78,6 +90,18 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "const_fn"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c478836e029dcef17fb47c89023448c64f781a046e0300e257ad8225ae59afab"
|
||||
|
||||
[[package]]
|
||||
name = "crc"
|
||||
version = "1.8.1"
|
||||
@@ -89,58 +113,57 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.2.0"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.7.3"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
|
||||
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
"maybe-uninit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.8.2"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
|
||||
checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"const_fn",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"maybe-uninit",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"maybe-uninit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.7.2"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
|
||||
checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"cfg-if 1.0.0",
|
||||
"const_fn",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
@@ -156,27 +179,34 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.5.3"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.15"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
|
||||
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.23.7"
|
||||
version = "0.23.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2397fc43bd5648b7117aabb3c5e62d0e62c194826ec77b0b4d0c41e62744635"
|
||||
checksum = "b4f0a8345b33b082aedec2f4d7d4a926b845cee184cbe78b703413066564431b"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"color_quant",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
@@ -185,11 +215,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.4.0"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe"
|
||||
checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
@@ -210,39 +241,42 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.72"
|
||||
version = "0.2.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701"
|
||||
checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
|
||||
|
||||
[[package]]
|
||||
name = "libdeflater"
|
||||
version = "0.2.0"
|
||||
name = "libdeflate-sys"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66dca08b13369865b2f6dca1dd05f833985cbe6c12a676b04d55f78b85e80246"
|
||||
checksum = "2f5b1582a0ebf8c55a46166c04d7c66f6bb17add3a6cbf69a082ac2219f31671"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.8"
|
||||
name = "libdeflater"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
checksum = "93edd93a53970951da84ef733a8b6e30189a8f8a9e19610f69e4cc5bb1f4d654"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libdeflate-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maybe-uninit"
|
||||
version = "2.0.0"
|
||||
name = "log"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
||||
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.5.5"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f"
|
||||
checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
@@ -257,10 +291,20 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.43"
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
|
||||
checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
@@ -268,9 +312,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.41"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f"
|
||||
checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
@@ -279,9 +323,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.3.0"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138"
|
||||
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
@@ -290,9 +334,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.12"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
@@ -308,42 +352,59 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oxipng"
|
||||
version = "3.0.0"
|
||||
name = "once_cell"
|
||||
version = "1.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5fd695858078338d73862ff3755f820eff0bf4f3304e4b52f22aba53463183a"
|
||||
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
|
||||
|
||||
[[package]]
|
||||
name = "oxipng"
|
||||
version = "4.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fefb26bde273c3db896a313151301a69e698a7495ee577fe2168ed7065c29c4"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
"byteorder",
|
||||
"cloudflare-zlib",
|
||||
"crc",
|
||||
"crossbeam-channel",
|
||||
"image",
|
||||
"indexmap",
|
||||
"itertools",
|
||||
"libdeflater",
|
||||
"log",
|
||||
"miniz_oxide",
|
||||
"miniz_oxide 0.4.3",
|
||||
"rayon",
|
||||
"rgb",
|
||||
"zopfli",
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||
dependencies = [
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.16.6"
|
||||
version = "0.16.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c150bf7479fafe3dd8740dbe48cc33b2a3efb7b0fe3483aced8bbc39f6d0238d"
|
||||
checksum = "dfe7f9f1c730833200b134370e1d5098964231af8450bce9b78ee3ab5278b970"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
"deflate",
|
||||
"miniz_oxide",
|
||||
"miniz_oxide 0.3.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.18"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
@@ -359,9 +420,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.3.1"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080"
|
||||
checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"crossbeam-deque",
|
||||
@@ -371,12 +432,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.7.1"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280"
|
||||
checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-queue",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
@@ -384,33 +445,63 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rgb"
|
||||
version = "0.8.20"
|
||||
version = "0.8.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ef54b45ae131327a88597e2463fee4098ad6c88ba7b6af4b3987db8aad4098"
|
||||
checksum = "287f3c3f8236abb92d8b7e36797f19159df4b58f0a658cc3fb6dd3004b1f3bd3"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65c94201b44764d6d1f7e37c15a8289ed55e546c1762c7f1d57f616966e0c181"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ef146c2ad5e5f4b037cd6ce2ebb775401729b19a82040c1beac9d36c7d1428"
|
||||
dependencies = [
|
||||
"pest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "squoosh-oxipng"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"log",
|
||||
"once_cell",
|
||||
"oxipng",
|
||||
"rayon",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.34"
|
||||
version = "1.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b"
|
||||
checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -418,10 +509,10 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typed-arena"
|
||||
version = "1.7.0"
|
||||
name = "ucd-trie"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
|
||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
@@ -431,19 +522,19 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.64"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a634620115e4a229108b71bde263bb4220c483b3f07f5ba514ee8d15064c4c2"
|
||||
checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cfg-if 0.1.10",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.64"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e53963b583d18a5aa3aaae4b4c1cb535218246131ba22a71f05b518098571df"
|
||||
checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
@@ -456,9 +547,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.64"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fcfd5ef6eec85623b4c6e844293d4516470d8f19cd72d0d12246017eb9060b8"
|
||||
checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -466,9 +557,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.64"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9adff9ee0e94b926ca81b57f57f86d5545cdcb1d259e21ec9bdd95b901754c75"
|
||||
checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -479,18 +570,6 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.64"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f7b90ea6c632dd06fd765d44542e234d5e63d9bb917ecd64d79778a13bd79ae"
|
||||
|
||||
[[package]]
|
||||
name = "zopfli"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4079b79464426ade2a1b0177fb0ce8396ba6b4084267407e333573c666073964"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
"byteorder",
|
||||
"crc",
|
||||
"typed-arena",
|
||||
]
|
||||
checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
|
||||
|
||||
@@ -5,14 +5,23 @@ authors = ["Ingvar Stepanyan <me@rreverser.com>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[package.metadata.wasm-pack.profile.release]
|
||||
wasm-opt = ["-O", "--no-validation"]
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
oxipng = { version = "3.0.0", default-features = false }
|
||||
wasm-bindgen = "0.2.64"
|
||||
log = { version = "0.4", features = ["release_max_level_off"] }
|
||||
oxipng = { version = "4.0.0", default-features = false, features = ["libdeflater"] }
|
||||
wasm-bindgen = "0.2.68"
|
||||
log = { version = "0.4.11", features = ["release_max_level_off"] }
|
||||
rayon = { version = "1.5.0", optional = true }
|
||||
once_cell = { version = "1.5.2", optional = true }
|
||||
crossbeam-channel = { version = "0.5.0", optional = true }
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
opt-level = "s"
|
||||
|
||||
[features]
|
||||
parallel = ["oxipng/parallel", "rayon", "crossbeam-channel", "once_cell"]
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
FROM rust
|
||||
RUN rustup target add wasm32-unknown-unknown
|
||||
RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||
|
||||
RUN mkdir /opt/wabt && \
|
||||
curl -L https://github.com/WebAssembly/wabt/releases/download/1.0.17/wabt-1.0.17-ubuntu.tar.gz | tar -xzf - -C /opt/wabt --strip 1
|
||||
|
||||
RUN mkdir /opt/wasi-sdk && \
|
||||
curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-11/wasi-sdk-11.0-linux.tar.gz | tar -xzf - -C /opt/wasi-sdk --strip 1
|
||||
|
||||
ENV PATH="/opt/wabt/bin:/opt/wasi-sdk/bin:${PATH}"
|
||||
WORKDIR /src
|
||||
10
codecs/oxipng/build.sh
Normal file
10
codecs/oxipng/build.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
rm -rf pkg,{-parallel}
|
||||
wasm-pack build -t web
|
||||
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory' wasm-pack build -t web -d pkg-parallel -- -Z build-std=panic_abort,std --features=parallel
|
||||
# Workaround https://github.com/rustwasm/wasm-bindgen/issues/2133:
|
||||
sed -i "s|maybe_memory:|maybe_memory?:|" pkg-parallel/squoosh_oxipng.d.ts
|
||||
rm pkg{,-parallel}/.gitignore
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "oxipng",
|
||||
"scripts": {
|
||||
"build": "../build-rust.sh"
|
||||
"build": "RUST_IMG=rustlang/rust@sha256:744aeea5a38f95aa7a96ec37269a65f0c6197a1cdd87d6534e12bb869141d807 ../build-rust.sh ./build.sh"
|
||||
}
|
||||
}
|
||||
|
||||
5
codecs/oxipng/pkg-parallel/README.md
Normal file
5
codecs/oxipng/pkg-parallel/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# OxiPNG
|
||||
|
||||
- Source: <https://github.com/shssoichiro/oxipng>
|
||||
- Version: v3.0.0
|
||||
- License: MIT
|
||||
15
codecs/oxipng/pkg-parallel/package.json
Normal file
15
codecs/oxipng/pkg-parallel/package.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "squoosh-oxipng",
|
||||
"collaborators": [
|
||||
"Ingvar Stepanyan <me@rreverser.com>"
|
||||
],
|
||||
"version": "0.1.0",
|
||||
"files": [
|
||||
"squoosh_oxipng_bg.wasm",
|
||||
"squoosh_oxipng.js",
|
||||
"squoosh_oxipng.d.ts"
|
||||
],
|
||||
"module": "squoosh_oxipng.js",
|
||||
"types": "squoosh_oxipng.d.ts",
|
||||
"sideEffects": false
|
||||
}
|
||||
46
codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts
generated
vendored
Normal file
46
codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* @param {Uint8Array} data
|
||||
* @param {number} level
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function optimise(data: Uint8Array, level: number): Uint8Array;
|
||||
/**
|
||||
* @param {number} num
|
||||
* @returns {any}
|
||||
*/
|
||||
export function worker_initializer(num: number): any;
|
||||
/**
|
||||
*/
|
||||
export function start_main_thread(): void;
|
||||
/**
|
||||
*/
|
||||
export function start_worker_thread(): void;
|
||||
|
||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
export interface InitOutput {
|
||||
readonly optimise: (a: number, b: number, c: number, d: number) => void;
|
||||
readonly malloc: (a: number) => number;
|
||||
readonly free: (a: number) => void;
|
||||
readonly worker_initializer: (a: number) => number;
|
||||
readonly start_main_thread: () => void;
|
||||
readonly start_worker_thread: () => void;
|
||||
readonly __wbindgen_export_0: WebAssembly.Memory;
|
||||
readonly __wbindgen_malloc: (a: number) => number;
|
||||
readonly __wbindgen_free: (a: number, b: number) => void;
|
||||
readonly __wbindgen_start: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
||||
* for everything else, calls `WebAssembly.instantiate` directly.
|
||||
*
|
||||
* @param {InitInput | Promise<InitInput>} module_or_path
|
||||
* @param {WebAssembly.Memory} maybe_memory
|
||||
*
|
||||
* @returns {Promise<InitOutput>}
|
||||
*/
|
||||
export default function init (module_or_path?: InitInput | Promise<InitInput>, maybe_memory?: WebAssembly.Memory): Promise<InitOutput>;
|
||||
|
||||
180
codecs/oxipng/pkg-parallel/squoosh_oxipng.js
generated
Normal file
180
codecs/oxipng/pkg-parallel/squoosh_oxipng.js
generated
Normal file
@@ -0,0 +1,180 @@
|
||||
|
||||
let wasm;
|
||||
let memory;
|
||||
|
||||
const heap = new Array(32).fill(undefined);
|
||||
|
||||
heap.push(undefined, null, true, false);
|
||||
|
||||
let heap_next = heap.length;
|
||||
|
||||
function addHeapObject(obj) {
|
||||
if (heap_next === heap.length) heap.push(heap.length + 1);
|
||||
const idx = heap_next;
|
||||
heap_next = heap[idx];
|
||||
|
||||
heap[idx] = obj;
|
||||
return idx;
|
||||
}
|
||||
|
||||
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
||||
|
||||
cachedTextDecoder.decode();
|
||||
|
||||
let cachegetUint8Memory0 = null;
|
||||
function getUint8Memory0() {
|
||||
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.__wbindgen_export_0.buffer) {
|
||||
cachegetUint8Memory0 = new Uint8Array(wasm.__wbindgen_export_0.buffer);
|
||||
}
|
||||
return cachegetUint8Memory0;
|
||||
}
|
||||
|
||||
function getStringFromWasm0(ptr, len) {
|
||||
return cachedTextDecoder.decode(getUint8Memory0().slice(ptr, ptr + len));
|
||||
}
|
||||
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
|
||||
function passArray8ToWasm0(arg, malloc) {
|
||||
const ptr = malloc(arg.length * 1);
|
||||
getUint8Memory0().set(arg, ptr / 1);
|
||||
WASM_VECTOR_LEN = arg.length;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let cachegetInt32Memory0 = null;
|
||||
function getInt32Memory0() {
|
||||
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.__wbindgen_export_0.buffer) {
|
||||
cachegetInt32Memory0 = new Int32Array(wasm.__wbindgen_export_0.buffer);
|
||||
}
|
||||
return cachegetInt32Memory0;
|
||||
}
|
||||
|
||||
function getArrayU8FromWasm0(ptr, len) {
|
||||
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
||||
}
|
||||
/**
|
||||
* @param {Uint8Array} data
|
||||
* @param {number} level
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function optimise(data, level) {
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_export_1.value - 16;
|
||||
wasm.__wbindgen_export_1.value = retptr;
|
||||
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
wasm.optimise(retptr, ptr0, len0, level);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
||||
wasm.__wbindgen_free(r0, r1 * 1);
|
||||
return v1;
|
||||
} finally {
|
||||
wasm.__wbindgen_export_1.value += 16;
|
||||
}
|
||||
}
|
||||
|
||||
function getObject(idx) { return heap[idx]; }
|
||||
|
||||
function dropObject(idx) {
|
||||
if (idx < 36) return;
|
||||
heap[idx] = heap_next;
|
||||
heap_next = idx;
|
||||
}
|
||||
|
||||
function takeObject(idx) {
|
||||
const ret = getObject(idx);
|
||||
dropObject(idx);
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @param {number} num
|
||||
* @returns {any}
|
||||
*/
|
||||
export function worker_initializer(num) {
|
||||
var ret = wasm.worker_initializer(num);
|
||||
return takeObject(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
export function start_main_thread() {
|
||||
wasm.start_main_thread();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
export function start_worker_thread() {
|
||||
wasm.start_worker_thread();
|
||||
}
|
||||
|
||||
async function load(module, imports, maybe_memory) {
|
||||
if (typeof Response === 'function' && module instanceof Response) {
|
||||
memory = imports.wbg.memory = new WebAssembly.Memory({initial:17,maximum:16384,shared:true});
|
||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
try {
|
||||
return await WebAssembly.instantiateStreaming(module, imports);
|
||||
|
||||
} catch (e) {
|
||||
if (module.headers.get('Content-Type') != 'application/wasm') {
|
||||
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
|
||||
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bytes = await module.arrayBuffer();
|
||||
return await WebAssembly.instantiate(bytes, imports);
|
||||
|
||||
} else {
|
||||
memory = imports.wbg.memory = maybe_memory;
|
||||
const instance = await WebAssembly.instantiate(module, imports);
|
||||
|
||||
if (instance instanceof WebAssembly.Instance) {
|
||||
return { instance, module };
|
||||
|
||||
} else {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function init(input, maybe_memory) {
|
||||
if (typeof input === 'undefined') {
|
||||
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
|
||||
}
|
||||
const imports = {};
|
||||
imports.wbg = {};
|
||||
imports.wbg.__wbindgen_module = function() {
|
||||
var ret = init.__wbindgen_wasm_module;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_memory = function() {
|
||||
var ret = wasm.__wbindgen_export_0;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_of_6510501edc06d65e = function(arg0, arg1) {
|
||||
var ret = Array.of(takeObject(arg0), takeObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||
};
|
||||
|
||||
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
|
||||
input = fetch(input);
|
||||
}
|
||||
|
||||
const { instance, module } = await load(await input, imports, maybe_memory);
|
||||
|
||||
wasm = instance.exports;
|
||||
init.__wbindgen_wasm_module = module;
|
||||
wasm.__wbindgen_start();
|
||||
return wasm;
|
||||
}
|
||||
|
||||
export default init;
|
||||
|
||||
BIN
codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm
Normal file
BIN
codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm
Normal file
Binary file not shown.
12
codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm.d.ts
generated
vendored
Normal file
12
codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm.d.ts
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export function optimise(a: number, b: number, c: number, d: number): void;
|
||||
export function malloc(a: number): number;
|
||||
export function free(a: number): void;
|
||||
export function worker_initializer(a: number): number;
|
||||
export function start_main_thread(): void;
|
||||
export function start_worker_thread(): void;
|
||||
export const __wbindgen_export_0: WebAssembly.Memory;
|
||||
export function __wbindgen_malloc(a: number): number;
|
||||
export function __wbindgen_free(a: number, b: number): void;
|
||||
export function __wbindgen_start(): void;
|
||||
5
codecs/oxipng/pkg/README.md
Normal file
5
codecs/oxipng/pkg/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# OxiPNG
|
||||
|
||||
- Source: <https://github.com/shssoichiro/oxipng>
|
||||
- Version: v3.0.0
|
||||
- License: MIT
|
||||
22
codecs/oxipng/pkg/squoosh_oxipng.d.ts
generated
vendored
22
codecs/oxipng/pkg/squoosh_oxipng.d.ts
generated
vendored
@@ -6,3 +6,25 @@
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function optimise(data: Uint8Array, level: number): Uint8Array;
|
||||
|
||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
export interface InitOutput {
|
||||
readonly memory: WebAssembly.Memory;
|
||||
readonly optimise: (a: number, b: number, c: number, d: number) => void;
|
||||
readonly malloc: (a: number) => number;
|
||||
readonly free: (a: number) => void;
|
||||
readonly __wbindgen_malloc: (a: number) => number;
|
||||
readonly __wbindgen_free: (a: number, b: number) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
||||
* for everything else, calls `WebAssembly.instantiate` directly.
|
||||
*
|
||||
* @param {InitInput | Promise<InitInput>} module_or_path
|
||||
*
|
||||
* @returns {Promise<InitOutput>}
|
||||
*/
|
||||
export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;
|
||||
|
||||
120
codecs/oxipng/pkg/squoosh_oxipng.js
generated
120
codecs/oxipng/pkg/squoosh_oxipng.js
generated
@@ -1,2 +1,118 @@
|
||||
import * as wasm from "./squoosh_oxipng_bg.wasm";
|
||||
export * from "./squoosh_oxipng_bg.js";
|
||||
|
||||
let wasm;
|
||||
|
||||
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
||||
|
||||
cachedTextDecoder.decode();
|
||||
|
||||
let cachegetUint8Memory0 = null;
|
||||
function getUint8Memory0() {
|
||||
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
|
||||
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetUint8Memory0;
|
||||
}
|
||||
|
||||
function getStringFromWasm0(ptr, len) {
|
||||
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
||||
}
|
||||
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
|
||||
function passArray8ToWasm0(arg, malloc) {
|
||||
const ptr = malloc(arg.length * 1);
|
||||
getUint8Memory0().set(arg, ptr / 1);
|
||||
WASM_VECTOR_LEN = arg.length;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let cachegetInt32Memory0 = null;
|
||||
function getInt32Memory0() {
|
||||
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
|
||||
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetInt32Memory0;
|
||||
}
|
||||
|
||||
function getArrayU8FromWasm0(ptr, len) {
|
||||
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
||||
}
|
||||
/**
|
||||
* @param {Uint8Array} data
|
||||
* @param {number} level
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function optimise(data, level) {
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_export_0.value - 16;
|
||||
wasm.__wbindgen_export_0.value = retptr;
|
||||
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
wasm.optimise(retptr, ptr0, len0, level);
|
||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
||||
wasm.__wbindgen_free(r0, r1 * 1);
|
||||
return v1;
|
||||
} finally {
|
||||
wasm.__wbindgen_export_0.value += 16;
|
||||
}
|
||||
}
|
||||
|
||||
async function load(module, imports) {
|
||||
if (typeof Response === 'function' && module instanceof Response) {
|
||||
|
||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
try {
|
||||
return await WebAssembly.instantiateStreaming(module, imports);
|
||||
|
||||
} catch (e) {
|
||||
if (module.headers.get('Content-Type') != 'application/wasm') {
|
||||
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
|
||||
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bytes = await module.arrayBuffer();
|
||||
return await WebAssembly.instantiate(bytes, imports);
|
||||
|
||||
} else {
|
||||
|
||||
const instance = await WebAssembly.instantiate(module, imports);
|
||||
|
||||
if (instance instanceof WebAssembly.Instance) {
|
||||
return { instance, module };
|
||||
|
||||
} else {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function init(input) {
|
||||
if (typeof input === 'undefined') {
|
||||
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
|
||||
}
|
||||
const imports = {};
|
||||
imports.wbg = {};
|
||||
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||
};
|
||||
|
||||
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
|
||||
input = fetch(input);
|
||||
}
|
||||
|
||||
const { instance, module } = await load(await input, imports);
|
||||
|
||||
wasm = instance.exports;
|
||||
init.__wbindgen_wasm_module = module;
|
||||
|
||||
return wasm;
|
||||
}
|
||||
|
||||
export default init;
|
||||
|
||||
|
||||
60
codecs/oxipng/pkg/squoosh_oxipng_bg.js
generated
60
codecs/oxipng/pkg/squoosh_oxipng_bg.js
generated
@@ -1,60 +0,0 @@
|
||||
import * as wasm from './squoosh_oxipng_bg.wasm';
|
||||
|
||||
const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder;
|
||||
|
||||
let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
||||
|
||||
cachedTextDecoder.decode();
|
||||
|
||||
let cachegetUint8Memory0 = null;
|
||||
function getUint8Memory0() {
|
||||
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
|
||||
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetUint8Memory0;
|
||||
}
|
||||
|
||||
function getStringFromWasm0(ptr, len) {
|
||||
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
||||
}
|
||||
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
|
||||
function passArray8ToWasm0(arg, malloc) {
|
||||
const ptr = malloc(arg.length * 1);
|
||||
getUint8Memory0().set(arg, ptr / 1);
|
||||
WASM_VECTOR_LEN = arg.length;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let cachegetInt32Memory0 = null;
|
||||
function getInt32Memory0() {
|
||||
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
|
||||
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetInt32Memory0;
|
||||
}
|
||||
|
||||
function getArrayU8FromWasm0(ptr, len) {
|
||||
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
||||
}
|
||||
/**
|
||||
* @param {Uint8Array} data
|
||||
* @param {number} level
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function optimise(data, level) {
|
||||
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
wasm.optimise(8, ptr0, len0, level);
|
||||
var r0 = getInt32Memory0()[8 / 4 + 0];
|
||||
var r1 = getInt32Memory0()[8 / 4 + 1];
|
||||
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
||||
wasm.__wbindgen_free(r0, r1 * 1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
export const __wbindgen_throw = function(arg0, arg1) {
|
||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||
};
|
||||
|
||||
Binary file not shown.
1
codecs/oxipng/rust-toolchain
Normal file
1
codecs/oxipng/rust-toolchain
Normal file
@@ -0,0 +1 @@
|
||||
nightly
|
||||
@@ -1,18 +1,21 @@
|
||||
use oxipng::AlphaOptim;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
mod malloc_shim;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
use oxipng::AlphaOptim;
|
||||
#[cfg(feature = "parallel")]
|
||||
pub mod parallel;
|
||||
|
||||
#[wasm_bindgen(catch)]
|
||||
#[wasm_bindgen]
|
||||
pub fn optimise(data: &[u8], level: u8) -> Vec<u8> {
|
||||
let mut options = oxipng::Options::from_preset(level);
|
||||
options.alphas.insert(AlphaOptim::Black);
|
||||
options.alphas.insert(AlphaOptim::White);
|
||||
options.alphas.insert(AlphaOptim::Up);
|
||||
options.alphas.insert(AlphaOptim::Down);
|
||||
options.alphas.insert(AlphaOptim::Left);
|
||||
options.alphas.insert(AlphaOptim::Right);
|
||||
let mut options = oxipng::Options::from_preset(level);
|
||||
options.alphas.insert(AlphaOptim::Black);
|
||||
options.alphas.insert(AlphaOptim::White);
|
||||
options.alphas.insert(AlphaOptim::Up);
|
||||
options.alphas.insert(AlphaOptim::Down);
|
||||
options.alphas.insert(AlphaOptim::Left);
|
||||
options.alphas.insert(AlphaOptim::Right);
|
||||
|
||||
options.deflate = oxipng::Deflaters::Libdeflater;
|
||||
oxipng::optimize_from_memory(data, &options).unwrap_throw()
|
||||
options.deflate = oxipng::Deflaters::Libdeflater;
|
||||
oxipng::optimize_from_memory(data, &options).unwrap_throw()
|
||||
}
|
||||
|
||||
62
codecs/oxipng/src/parallel.rs
Normal file
62
codecs/oxipng/src/parallel.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
use crossbeam_channel::{bounded, Receiver, Sender};
|
||||
use once_cell::sync::OnceCell;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsValue;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = Array, js_name = of)]
|
||||
fn array_of_2(a: JsValue, b: JsValue) -> JsValue;
|
||||
}
|
||||
|
||||
// This is one of the parts that work around Chromium incorrectly implementing postMessage:
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=1075645
|
||||
//
|
||||
// rayon::ThreadPoolBuilder (used below) executes spawn handler to populate the worker pool,
|
||||
// and then blocks the current thread until each worker unblocks its (opaque) lock.
|
||||
//
|
||||
// Normally, we could use postMessage directly inside the spawn handler to
|
||||
// post module + memory + threadPtr to each worker, and the block the current thread.
|
||||
//
|
||||
// However, that bug means that postMessage is currently delayed until the next event loop,
|
||||
// which will never spin since we block the current thread, and so the other workers will
|
||||
// never be able to unblock us.
|
||||
//
|
||||
// To work around this problem, we:
|
||||
// 1) Expose `worker_initializer` that returns module + memory pair (without threadPtr)
|
||||
// that workers can be initialised with to become native threads.
|
||||
// JavaScript can postMessage this pair in advance, and asynchronously wait for workers
|
||||
// to acknowledge the receipt.
|
||||
// 2) Create a global communication channel on the Rust side using crossbeam.
|
||||
// It will be used to send threadPtr to the pre-initialised workers
|
||||
// instead of postMessage.
|
||||
// 3) Provide a separate `start_main_thread` that expects all workers to be ready,
|
||||
// and just uses the provided channel to send `threadPtr`s using the
|
||||
// shared memory and blocks the current thread until they're all grabbed.
|
||||
// 4) Provide a `worker_initializer` that is expected to be invoked from various workers,
|
||||
// reads one `threadPtr` from the shared channel and starts running it.
|
||||
static CHANNEL: OnceCell<(Sender<rayon::ThreadBuilder>, Receiver<rayon::ThreadBuilder>)> =
|
||||
OnceCell::new();
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn worker_initializer(num: usize) -> JsValue {
|
||||
CHANNEL.get_or_init(|| bounded(num));
|
||||
array_of_2(wasm_bindgen::module(), wasm_bindgen::memory())
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn start_main_thread() {
|
||||
let (sender, _) = CHANNEL.get().unwrap();
|
||||
|
||||
rayon::ThreadPoolBuilder::new()
|
||||
.num_threads(sender.capacity().unwrap())
|
||||
.spawn_handler(|thread| Ok(sender.send(thread).unwrap_throw()))
|
||||
.build_global()
|
||||
.unwrap_throw()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn start_worker_thread() {
|
||||
let (_, receiver) = CHANNEL.get().unwrap();
|
||||
receiver.recv().unwrap_throw().run()
|
||||
}
|
||||
68
codecs/resize/pkg/squoosh_resize.d.ts
generated
vendored
68
codecs/resize/pkg/squoosh_resize.d.ts
generated
vendored
@@ -1,14 +1,60 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* @param {Uint8Array} input_image
|
||||
* @param {number} input_width
|
||||
* @param {number} input_height
|
||||
* @param {number} output_width
|
||||
* @param {number} output_height
|
||||
* @param {number} typ_idx
|
||||
* @param {boolean} premultiply
|
||||
* @param {boolean} color_space_conversion
|
||||
* @returns {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): Uint8Array;
|
||||
* @param {Uint8Array} input_image
|
||||
* @param {number} input_width
|
||||
* @param {number} input_height
|
||||
* @param {number} output_width
|
||||
* @param {number} output_height
|
||||
* @param {number} typ_idx
|
||||
* @param {boolean} premultiply
|
||||
* @param {boolean} color_space_conversion
|
||||
* @returns {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,
|
||||
): Uint8Array;
|
||||
|
||||
export type InitInput =
|
||||
| RequestInfo
|
||||
| URL
|
||||
| Response
|
||||
| BufferSource
|
||||
| WebAssembly.Module;
|
||||
|
||||
export interface InitOutput {
|
||||
readonly memory: WebAssembly.Memory;
|
||||
readonly resize: (
|
||||
a: number,
|
||||
b: number,
|
||||
c: number,
|
||||
d: number,
|
||||
e: number,
|
||||
f: number,
|
||||
g: number,
|
||||
h: number,
|
||||
i: number,
|
||||
j: number,
|
||||
) => void;
|
||||
readonly __wbindgen_malloc: (a: number) => number;
|
||||
readonly __wbindgen_free: (a: number, b: number) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
||||
* for everything else, calls `WebAssembly.instantiate` directly.
|
||||
*
|
||||
* @param {InitInput | Promise<InitInput>} module_or_path
|
||||
*
|
||||
* @returns {Promise<InitOutput>}
|
||||
*/
|
||||
export default function init(
|
||||
module_or_path?: InitInput | Promise<InitInput>,
|
||||
): Promise<InitOutput>;
|
||||
|
||||
133
codecs/resize/pkg/squoosh_resize.js
generated
133
codecs/resize/pkg/squoosh_resize.js
generated
@@ -1,2 +1,131 @@
|
||||
import * as wasm from "./squoosh_resize_bg.wasm";
|
||||
export * from "./squoosh_resize_bg.js";
|
||||
let wasm;
|
||||
|
||||
let cachegetUint8Memory0 = null;
|
||||
function getUint8Memory0() {
|
||||
if (
|
||||
cachegetUint8Memory0 === null ||
|
||||
cachegetUint8Memory0.buffer !== wasm.memory.buffer
|
||||
) {
|
||||
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetUint8Memory0;
|
||||
}
|
||||
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
|
||||
function passArray8ToWasm0(arg, malloc) {
|
||||
const ptr = malloc(arg.length * 1);
|
||||
getUint8Memory0().set(arg, ptr / 1);
|
||||
WASM_VECTOR_LEN = arg.length;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let cachegetInt32Memory0 = null;
|
||||
function getInt32Memory0() {
|
||||
if (
|
||||
cachegetInt32Memory0 === null ||
|
||||
cachegetInt32Memory0.buffer !== wasm.memory.buffer
|
||||
) {
|
||||
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetInt32Memory0;
|
||||
}
|
||||
|
||||
function getArrayU8FromWasm0(ptr, len) {
|
||||
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
||||
}
|
||||
/**
|
||||
* @param {Uint8Array} input_image
|
||||
* @param {number} input_width
|
||||
* @param {number} input_height
|
||||
* @param {number} output_width
|
||||
* @param {number} output_height
|
||||
* @param {number} typ_idx
|
||||
* @param {boolean} premultiply
|
||||
* @param {boolean} color_space_conversion
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function resize(
|
||||
input_image,
|
||||
input_width,
|
||||
input_height,
|
||||
output_width,
|
||||
output_height,
|
||||
typ_idx,
|
||||
premultiply,
|
||||
color_space_conversion,
|
||||
) {
|
||||
var ptr0 = passArray8ToWasm0(input_image, wasm.__wbindgen_malloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
wasm.resize(
|
||||
8,
|
||||
ptr0,
|
||||
len0,
|
||||
input_width,
|
||||
input_height,
|
||||
output_width,
|
||||
output_height,
|
||||
typ_idx,
|
||||
premultiply,
|
||||
color_space_conversion,
|
||||
);
|
||||
var r0 = getInt32Memory0()[8 / 4 + 0];
|
||||
var r1 = getInt32Memory0()[8 / 4 + 1];
|
||||
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
||||
wasm.__wbindgen_free(r0, r1 * 1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
async function load(module, imports) {
|
||||
if (typeof Response === 'function' && module instanceof Response) {
|
||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
try {
|
||||
return await WebAssembly.instantiateStreaming(module, imports);
|
||||
} catch (e) {
|
||||
if (module.headers.get('Content-Type') != 'application/wasm') {
|
||||
console.warn(
|
||||
'`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n',
|
||||
e,
|
||||
);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bytes = await module.arrayBuffer();
|
||||
return await WebAssembly.instantiate(bytes, imports);
|
||||
} else {
|
||||
const instance = await WebAssembly.instantiate(module, imports);
|
||||
|
||||
if (instance instanceof WebAssembly.Instance) {
|
||||
return { instance, module };
|
||||
} else {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function init(input) {
|
||||
if (typeof input === 'undefined') {
|
||||
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
|
||||
}
|
||||
const imports = {};
|
||||
|
||||
if (
|
||||
typeof input === 'string' ||
|
||||
(typeof Request === 'function' && input instanceof Request) ||
|
||||
(typeof URL === 'function' && input instanceof URL)
|
||||
) {
|
||||
input = fetch(input);
|
||||
}
|
||||
|
||||
const { instance, module } = await load(await input, imports);
|
||||
|
||||
wasm = instance.exports;
|
||||
init.__wbindgen_wasm_module = module;
|
||||
|
||||
return wasm;
|
||||
}
|
||||
|
||||
export default init;
|
||||
|
||||
52
codecs/resize/pkg/squoosh_resize_bg.js
generated
52
codecs/resize/pkg/squoosh_resize_bg.js
generated
@@ -1,52 +0,0 @@
|
||||
import * as wasm from './squoosh_resize_bg.wasm';
|
||||
|
||||
let cachegetUint8Memory0 = null;
|
||||
function getUint8Memory0() {
|
||||
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
|
||||
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetUint8Memory0;
|
||||
}
|
||||
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
|
||||
function passArray8ToWasm0(arg, malloc) {
|
||||
const ptr = malloc(arg.length * 1);
|
||||
getUint8Memory0().set(arg, ptr / 1);
|
||||
WASM_VECTOR_LEN = arg.length;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let cachegetInt32Memory0 = null;
|
||||
function getInt32Memory0() {
|
||||
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
|
||||
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetInt32Memory0;
|
||||
}
|
||||
|
||||
function getArrayU8FromWasm0(ptr, len) {
|
||||
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
||||
}
|
||||
/**
|
||||
* @param {Uint8Array} input_image
|
||||
* @param {number} input_width
|
||||
* @param {number} input_height
|
||||
* @param {number} output_width
|
||||
* @param {number} output_height
|
||||
* @param {number} typ_idx
|
||||
* @param {boolean} premultiply
|
||||
* @param {boolean} color_space_conversion
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function resize(input_image, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion) {
|
||||
var ptr0 = passArray8ToWasm0(input_image, wasm.__wbindgen_malloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
wasm.resize(8, ptr0, len0, input_width, input_height, output_width, output_height, typ_idx, premultiply, color_space_conversion);
|
||||
var r0 = getInt32Memory0()[8 / 4 + 0];
|
||||
var r1 = getInt32Memory0()[8 / 4 + 1];
|
||||
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
||||
wasm.__wbindgen_free(r0, r1 * 1);
|
||||
return v1;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,9 +1,13 @@
|
||||
FROM emscripten/emsdk:1.39.19 AS wasm-tools
|
||||
ARG RUST_IMG=rust:1.47
|
||||
|
||||
FROM emscripten/emsdk:2.0.8 AS wasm-tools
|
||||
WORKDIR /opt/wasm-tools
|
||||
RUN wget -qO- https://github.com/rustwasm/wasm-pack/releases/download/v0.9.1/wasm-pack-v0.9.1-x86_64-unknown-linux-musl.tar.gz | tar -xzf - --strip 1
|
||||
|
||||
FROM rust:1.44-stretch AS rust
|
||||
FROM $RUST_IMG AS rust
|
||||
ARG RUST_IMG
|
||||
RUN rustup target add wasm32-unknown-unknown
|
||||
RUN case $RUST_IMG in rustlang/rust@*) rustup component add rust-src; esac
|
||||
COPY --from=wasm-tools /emsdk/upstream/bin/wasm-opt /emsdk/upstream/bin/clang /usr/local/bin/
|
||||
COPY --from=wasm-tools /emsdk/upstream/lib/ /usr/local/lib/
|
||||
COPY --from=wasm-tools /emsdk/upstream/emscripten/system/include/libc/ /wasm32/include/
|
||||
@@ -12,4 +16,4 @@ COPY --from=wasm-tools /opt/wasm-tools/wasm-pack /usr/local/cargo/bin/
|
||||
|
||||
ENV CPATH="/wasm32/include"
|
||||
WORKDIR /src
|
||||
CMD ["sh", "-c", "rm -rf pkg && wasm-pack build -- --verbose --locked && rm pkg/.gitignore"]
|
||||
CMD ["sh", "-c", "rm -rf pkg && wasm-pack build --target web -- --verbose --locked && rm pkg/.gitignore"]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
CODEC_URL := https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.tar.gz
|
||||
CODEC_URL := https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.1.0.tar.gz
|
||||
CODEC_DIR = node_modules/libwebp
|
||||
CODEC_OUT_RELATIVE = src/.libs/libwebp.a
|
||||
CODEC_OUT := $(addprefix $(CODEC_DIR)/, $(CODEC_OUT_RELATIVE))
|
||||
@@ -18,7 +18,9 @@ all: $(OUT_JS)
|
||||
--closure 1 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s MODULARIZE=1 \
|
||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
||||
-s TEXTDECODER=2 \
|
||||
-s ENVIRONMENT='worker' \
|
||||
-s EXPORT_ES6=1 \
|
||||
-o $@ \
|
||||
$+
|
||||
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
<!doctype html>
|
||||
<script src='webp_dec.js'></script>
|
||||
<script>
|
||||
const Module = webp_dec();
|
||||
|
||||
async function loadFile(src) {
|
||||
const resp = await fetch(src);
|
||||
return await resp.arrayBuffer();
|
||||
}
|
||||
|
||||
Module.onRuntimeInitialized = async _ => {
|
||||
console.log('Version:', Module.version().toString(16));
|
||||
webp_dec().then(async module => {
|
||||
console.log('Version:', module.version().toString(16));
|
||||
const image = await loadFile('../../example.webp');
|
||||
const imageData = Module.decode(image);
|
||||
const imageData = module.decode(image);
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = result.width;
|
||||
canvas.height = result.height;
|
||||
canvas.width = imageData.width;
|
||||
canvas.height = imageData.height;
|
||||
document.body.appendChild(canvas);
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -17,7 +17,10 @@ val decode(std::string buffer) {
|
||||
int width, height;
|
||||
std::unique_ptr<uint8_t[]> rgba(
|
||||
WebPDecodeRGBA((const uint8_t*)buffer.c_str(), buffer.size(), &width, &height));
|
||||
return rgba ? ImageData.new_(Uint8ClampedArray.new_(typed_memory_view(width * height * 4, rgba.get())), width, height) : val::null();
|
||||
return rgba ? ImageData.new_(
|
||||
Uint8ClampedArray.new_(typed_memory_view(width * height * 4, rgba.get())),
|
||||
width, height)
|
||||
: val::null();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
|
||||
6
codecs/webp/dec/webp_dec.d.ts
vendored
6
codecs/webp/dec/webp_dec.d.ts
vendored
@@ -1,5 +1,7 @@
|
||||
interface WebPModule extends EmscriptenWasm.Module {
|
||||
export interface WebPModule extends EmscriptenWasm.Module {
|
||||
decode(data: BufferSource): ImageData | null;
|
||||
}
|
||||
|
||||
export default function(opts: EmscriptenWasm.ModuleOpts): WebPModule;
|
||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<WebPModule>;
|
||||
|
||||
export default moduleFactory;
|
||||
|
||||
1165
codecs/webp/dec/webp_dec.js
generated
1165
codecs/webp/dec/webp_dec.js
generated
File diff suppressed because it is too large
Load Diff
BIN
codecs/webp/dec/webp_dec.wasm
Normal file → Executable file
BIN
codecs/webp/dec/webp_dec.wasm
Normal file → Executable file
Binary file not shown.
@@ -1,8 +1,6 @@
|
||||
<!doctype html>
|
||||
<script src='webp_enc.js'></script>
|
||||
<script>
|
||||
const module = webp_enc();
|
||||
|
||||
async function loadImage(src) {
|
||||
// Load image
|
||||
const img = document.createElement('img');
|
||||
@@ -17,7 +15,7 @@
|
||||
return ctx.getImageData(0, 0, img.width, img.height);
|
||||
}
|
||||
|
||||
module.onRuntimeInitialized = async _ => {
|
||||
webp_enc().then(async module => {
|
||||
console.log('Version:', module.version().toString(16));
|
||||
const image = await loadImage('../../example.png');
|
||||
const result = module.encode(image.data, image.width, image.height, {
|
||||
@@ -56,5 +54,5 @@
|
||||
const img = document.createElement('img');
|
||||
img.src = blobURL;
|
||||
document.body.appendChild(img);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
45
codecs/webp/enc/webp_enc.d.ts
vendored
45
codecs/webp/enc/webp_enc.d.ts
vendored
@@ -1,7 +1,42 @@
|
||||
import { EncodeOptions } from '../../../src/codecs/webp/encoder-meta';
|
||||
|
||||
interface WebPModule extends EmscriptenWasm.Module {
|
||||
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array | null;
|
||||
export interface EncodeOptions {
|
||||
quality: number;
|
||||
target_size: number;
|
||||
target_PSNR: number;
|
||||
method: number;
|
||||
sns_strength: number;
|
||||
filter_strength: number;
|
||||
filter_sharpness: number;
|
||||
filter_type: number;
|
||||
partitions: number;
|
||||
segments: number;
|
||||
pass: number;
|
||||
show_compressed: number;
|
||||
preprocessing: number;
|
||||
autofilter: number;
|
||||
partition_limit: number;
|
||||
alpha_compression: number;
|
||||
alpha_filtering: number;
|
||||
alpha_quality: number;
|
||||
lossless: number;
|
||||
exact: number;
|
||||
image_hint: number;
|
||||
emulate_jpeg_size: number;
|
||||
thread_level: number;
|
||||
low_memory: number;
|
||||
near_lossless: number;
|
||||
use_delta_palette: number;
|
||||
use_sharp_yuv: number;
|
||||
}
|
||||
|
||||
export default function(opts: EmscriptenWasm.ModuleOpts): WebPModule;
|
||||
export interface WebPModule extends EmscriptenWasm.Module {
|
||||
encode(
|
||||
data: BufferSource,
|
||||
width: number,
|
||||
height: number,
|
||||
options: EncodeOptions,
|
||||
): Uint8Array | null;
|
||||
}
|
||||
|
||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<WebPModule>;
|
||||
|
||||
export default moduleFactory;
|
||||
|
||||
1295
codecs/webp/enc/webp_enc.js
generated
1295
codecs/webp/enc/webp_enc.js
generated
File diff suppressed because it is too large
Load Diff
BIN
codecs/webp/enc/webp_enc.wasm
Normal file → Executable file
BIN
codecs/webp/enc/webp_enc.wasm
Normal file → Executable file
Binary file not shown.
50
codecs/wp2/Makefile
Normal file
50
codecs/wp2/Makefile
Normal file
@@ -0,0 +1,50 @@
|
||||
CODEC_URL = https://chromium.googlesource.com/codecs/libwebp2/+archive/c90b5b476004c9a98731ae1c175cebab5de50fbf.tar.gz
|
||||
CODEC_DIR = node_modules/wp2
|
||||
CODEC_BUILD_DIR := $(CODEC_DIR)/.build
|
||||
CODEC_OUT := $(CODEC_BUILD_DIR)/libwebp2.a
|
||||
|
||||
OUT_JS = enc/wp2_enc.js dec/wp2_dec.js
|
||||
OUT_WASM = $(OUT_JS:.js=.wasm)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(OUT_JS)
|
||||
|
||||
%.js: %.cpp $(CODEC_OUT)
|
||||
$(CXX) \
|
||||
-I $(CODEC_DIR) \
|
||||
${CXXFLAGS} \
|
||||
${LDFLAGS} \
|
||||
--bind \
|
||||
--closure 1 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s MODULARIZE=1 \
|
||||
-s TEXTDECODER=2 \
|
||||
-s ENVIRONMENT='worker' \
|
||||
-s EXPORT_ES6=1 \
|
||||
-s EXPORT_NAME="$(basename $(@F))" \
|
||||
-o $@ \
|
||||
$+
|
||||
|
||||
$(CODEC_OUT): $(CODEC_BUILD_DIR)/Makefile
|
||||
cd $(CODEC_BUILD_DIR) && \
|
||||
$(MAKE)
|
||||
|
||||
$(CODEC_BUILD_DIR)/Makefile: $(CODEC_DIR)/CMakeLists.txt
|
||||
mkdir -p $(CODEC_BUILD_DIR)
|
||||
cd $(CODEC_BUILD_DIR) && \
|
||||
emcmake cmake \
|
||||
-DWP2_ENABLE_SIMD=0 \
|
||||
-DWP2_BUILD_TESTS=0 \
|
||||
-DWP2_ENABLE_TESTS=0 \
|
||||
-DWP2_BUILD_EXAMPLES=0 \
|
||||
-DWP2_BUILD_EXTRAS=0 \
|
||||
../
|
||||
|
||||
$(CODEC_DIR)/CMakeLists.txt:
|
||||
mkdir -p $(CODEC_DIR)
|
||||
curl -sL $(CODEC_URL) | tar xz -C $(CODEC_DIR)
|
||||
|
||||
clean:
|
||||
$(RM) $(OUT_JS) $(OUT_WASM)
|
||||
$(MAKE) -C $(CODEC_BUILD_DIR) clean
|
||||
17
codecs/wp2/dec/README.md
Normal file
17
codecs/wp2/dec/README.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# WebP2 decoder
|
||||
|
||||
- Source: <https://chromium.googlesource.com/codecs/libwebp2>
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Docker
|
||||
|
||||
## Example
|
||||
|
||||
N/A
|
||||
|
||||
## API
|
||||
|
||||
### `ImageData decode(uint8_t* image_buffer, int image_width, int image_height)`
|
||||
|
||||
Decodes the given WebP2 buffer into raw RGBA represented as an `ImageData`.
|
||||
24
codecs/wp2/dec/wp2_dec.cpp
Normal file
24
codecs/wp2/dec/wp2_dec.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <emscripten/bind.h>
|
||||
#include <emscripten/val.h>
|
||||
#include <cstdio>
|
||||
#include "src/wp2/decode.h"
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");
|
||||
thread_local const val ImageData = val::global("ImageData");
|
||||
|
||||
val decode(std::string image_in) {
|
||||
WP2::ArgbBuffer buffer(WP2_rgbA_32);
|
||||
WP2Status status = WP2::Decode(image_in, &buffer);
|
||||
if (status != WP2_STATUS_OK) {
|
||||
return val::null();
|
||||
}
|
||||
return ImageData.new_(
|
||||
Uint8ClampedArray.new_(typed_memory_view(buffer.stride * buffer.height, buffer.GetRow8(0))),
|
||||
buffer.width, buffer.height);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
function("decode", &decode);
|
||||
}
|
||||
7
codecs/wp2/dec/wp2_dec.d.ts
vendored
Normal file
7
codecs/wp2/dec/wp2_dec.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export interface WP2Module extends EmscriptenWasm.Module {
|
||||
decode(data: BufferSource): ImageData | null;
|
||||
}
|
||||
|
||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<WP2Module>;
|
||||
|
||||
export default moduleFactory;
|
||||
1185
codecs/wp2/dec/wp2_dec.js
generated
Normal file
1185
codecs/wp2/dec/wp2_dec.js
generated
Normal file
File diff suppressed because it is too large
Load Diff
BIN
codecs/wp2/dec/wp2_dec.wasm
Executable file
BIN
codecs/wp2/dec/wp2_dec.wasm
Executable file
Binary file not shown.
17
codecs/wp2/enc/README.md
Normal file
17
codecs/wp2/enc/README.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# WebP2 encoder
|
||||
|
||||
- Source: <https://chromium.googlesource.com/codecs/libwebp2>
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Docker
|
||||
|
||||
## Example
|
||||
|
||||
N/A
|
||||
|
||||
## API
|
||||
|
||||
### `UInt8Array encode(uint8_t* image_buffer, int image_width, int image_height, WP2::EncoderConfig config)`
|
||||
|
||||
Encodes the given image with given dimension to WebP2.
|
||||
66
codecs/wp2/enc/wp2_enc.cpp
Normal file
66
codecs/wp2/enc/wp2_enc.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#include <emscripten/bind.h>
|
||||
#include <emscripten/val.h>
|
||||
#include <cstdio>
|
||||
#include "src/wp2/encode.h"
|
||||
|
||||
using namespace emscripten;
|
||||
|
||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
||||
|
||||
struct WP2Options {
|
||||
float quality;
|
||||
float alpha_quality;
|
||||
int speed;
|
||||
int pass;
|
||||
int uv_mode;
|
||||
float sns;
|
||||
int csp_type;
|
||||
int error_diffusion;
|
||||
bool use_random_matrix;
|
||||
};
|
||||
|
||||
val encode(std::string image_in, int image_width, int image_height, WP2Options options) {
|
||||
WP2::EncoderConfig config = {};
|
||||
|
||||
config.quality = options.quality;
|
||||
config.alpha_quality = options.alpha_quality;
|
||||
config.speed = options.speed;
|
||||
config.pass = options.pass;
|
||||
config.uv_mode = static_cast<WP2::EncoderConfig::UVMode>(options.uv_mode);
|
||||
config.csp_type = static_cast<WP2::Csp>(options.csp_type);
|
||||
config.sns = options.sns;
|
||||
config.error_diffusion = options.error_diffusion;
|
||||
config.use_random_matrix = options.use_random_matrix;
|
||||
|
||||
uint8_t* image_buffer = (uint8_t*)image_in.c_str();
|
||||
WP2::ArgbBuffer src = WP2::ArgbBuffer();
|
||||
WP2Status status =
|
||||
src.Import(WP2_rgbA_32, // Format. WP2_RGBA_32 is the same but NOT premultiplied alpha
|
||||
image_width, image_height, image_buffer, 4 * image_width);
|
||||
if (status != WP2_STATUS_OK) {
|
||||
return val::null();
|
||||
}
|
||||
|
||||
WP2::MemoryWriter memory_writer;
|
||||
status = WP2::Encode(src, &memory_writer, config);
|
||||
if (status != WP2_STATUS_OK) {
|
||||
return val::null();
|
||||
}
|
||||
|
||||
return Uint8Array.new_(typed_memory_view(memory_writer.size_, memory_writer.mem_));
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(my_module) {
|
||||
value_object<WP2Options>("WP2Options")
|
||||
.field("quality", &WP2Options::quality)
|
||||
.field("alpha_quality", &WP2Options::alpha_quality)
|
||||
.field("speed", &WP2Options::speed)
|
||||
.field("pass", &WP2Options::pass)
|
||||
.field("uv_mode", &WP2Options::uv_mode)
|
||||
.field("csp_type", &WP2Options::csp_type)
|
||||
.field("error_diffusion", &WP2Options::error_diffusion)
|
||||
.field("use_random_matrix", &WP2Options::use_random_matrix)
|
||||
.field("sns", &WP2Options::sns);
|
||||
|
||||
function("encode", &encode);
|
||||
}
|
||||
38
codecs/wp2/enc/wp2_enc.d.ts
vendored
Normal file
38
codecs/wp2/enc/wp2_enc.d.ts
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
export interface EncodeOptions {
|
||||
quality: number;
|
||||
alpha_quality: number;
|
||||
speed: number;
|
||||
pass: number;
|
||||
sns: number;
|
||||
uv_mode: UVMode;
|
||||
csp_type: Csp;
|
||||
error_diffusion: number;
|
||||
use_random_matrix: boolean;
|
||||
}
|
||||
|
||||
export const enum UVMode {
|
||||
UVModeAdapt = 0, // Mix of 420 and 444 (per block)
|
||||
UVMode420, // All blocks 420
|
||||
UVMode444, // All blocks 444
|
||||
UVModeAuto, // Choose any of the above automatically
|
||||
}
|
||||
|
||||
export const enum Csp {
|
||||
kYCoCg,
|
||||
kYCbCr,
|
||||
kCustom,
|
||||
kYIQ,
|
||||
}
|
||||
|
||||
export interface WP2Module extends EmscriptenWasm.Module {
|
||||
encode(
|
||||
data: BufferSource,
|
||||
width: number,
|
||||
height: number,
|
||||
options: EncodeOptions,
|
||||
): Uint8Array | null;
|
||||
}
|
||||
|
||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<WP2Module>;
|
||||
|
||||
export default moduleFactory;
|
||||
1277
codecs/wp2/enc/wp2_enc.js
generated
Normal file
1277
codecs/wp2/enc/wp2_enc.js
generated
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user