forked from external-repos/squoosh
Compare commits
60 Commits
urls-bug
...
rollup-bui
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7346511fa1 | ||
|
|
39ca054112 | ||
|
|
1b80dd23ee | ||
|
|
d1ee92e884 | ||
|
|
f1da577ba3 | ||
|
|
52b3d0063f | ||
|
|
eb9d0d186c | ||
|
|
964390501e | ||
|
|
b412d4c2a5 | ||
|
|
7dfc9310ba | ||
|
|
b38069695a | ||
|
|
2d21406484 | ||
|
|
56f9d4b8c8 | ||
|
|
be4601b93a | ||
|
|
196e6e1aea | ||
|
|
6d0d9dc022 | ||
|
|
324c2b6cab | ||
|
|
b6fd14b6d3 | ||
|
|
9111aa89ae | ||
|
|
c17b5c36c6 | ||
|
|
4502abb069 | ||
|
|
5a027c7727 | ||
|
|
4da1887826 | ||
|
|
b1a639c182 | ||
|
|
6dbb182f7b | ||
|
|
a360191759 | ||
|
|
1cb1c16fa2 | ||
|
|
ec586bb529 | ||
|
|
4b8c0178fe | ||
|
|
0d298e3e0a | ||
|
|
13c5b76af6 | ||
|
|
7836d7e97c | ||
|
|
db2d6f4ca6 | ||
|
|
b11ae0b8c7 | ||
|
|
81d0b38dbd | ||
|
|
b47d6b4696 | ||
|
|
f96ae9bdee | ||
|
|
4d8efcea66 | ||
|
|
e11b4cf22c | ||
|
|
3f2466f44d | ||
|
|
778aa41f0d | ||
|
|
486957443d | ||
|
|
02e4eaf4b5 | ||
|
|
f5d9023ff3 | ||
|
|
455c868e55 | ||
|
|
6573103755 | ||
|
|
a30e38856e | ||
|
|
d2807ebb18 | ||
|
|
fd151fc70d | ||
|
|
812e727de0 | ||
|
|
2a6a83f56d | ||
|
|
21fc70cbdd | ||
|
|
d9e1177cd8 | ||
|
|
300809fdcb | ||
|
|
7540a15f8d | ||
|
|
f92e3c2194 | ||
|
|
7776134bc2 | ||
|
|
2583d689b9 | ||
|
|
25102095aa | ||
|
|
a6477b82fc |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -1,6 +1,11 @@
|
|||||||
|
.tmp
|
||||||
node_modules
|
node_modules
|
||||||
/build
|
|
||||||
/*.log
|
|
||||||
*.scss.d.ts
|
*.scss.d.ts
|
||||||
*.css.d.ts
|
*.css.d.ts
|
||||||
|
build
|
||||||
*.o
|
*.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"
|
||||||
|
}
|
||||||
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,136 +1,84 @@
|
|||||||
CODEC_URL = https://github.com/AOMediaCodec/libavif/archive/v0.8.1.tar.gz
|
CODEC_URL = https://github.com/AOMediaCodec/libavif/archive/31d7c6d1e32cf467ac24fb8c7a76c4902a4c00db.tar.gz
|
||||||
CODEC_PACKAGE = node_modules/libavif.tar.gz
|
CODEC_PACKAGE = node_modules/libavif.tar.gz
|
||||||
|
|
||||||
CODEC_ENC_DIR = node_modules/libavif-enc
|
|
||||||
CODEC_ENC_BUILD_DIR := $(CODEC_ENC_DIR)/build
|
|
||||||
CODEC_ENC_OUT := $(CODEC_ENC_BUILD_DIR)/libavif.a
|
|
||||||
|
|
||||||
CODEC_DEC_DIR = node_modules/libavif-dec
|
|
||||||
CODEC_DEC_BUILD_DIR := $(CODEC_DEC_DIR)/build
|
|
||||||
CODEC_DEC_OUT := $(CODEC_DEC_BUILD_DIR)/libavif.a
|
|
||||||
|
|
||||||
LIBAOM_URL = https://aomedia.googlesource.com/aom/+archive/v2.0.0.tar.gz
|
LIBAOM_URL = https://aomedia.googlesource.com/aom/+archive/v2.0.0.tar.gz
|
||||||
LIBAOM_PACKAGE = node_modules/libaom.tar.gz
|
LIBAOM_PACKAGE = node_modules/libaom.tar.gz
|
||||||
|
|
||||||
LIBAOM_ENC_DIR := $(CODEC_ENC_DIR)/ext/aom
|
export CODEC_DIR = node_modules/libavif
|
||||||
LIBAOM_ENC_BUILD_DIR := $(LIBAOM_ENC_DIR)/build.libavif
|
BUILD_DIR := node_modules/build
|
||||||
LIBAOM_ENC_OUT := $(LIBAOM_ENC_BUILD_DIR)/libaom.a
|
ENC_BUILD_DIR := $(BUILD_DIR)/enc
|
||||||
|
ENC_MT_BUILD_DIR := $(BUILD_DIR)/enc-mt
|
||||||
LIBAOM_DEC_DIR := $(CODEC_DEC_DIR)/ext/aom
|
DEC_BUILD_DIR := $(BUILD_DIR)/dec
|
||||||
LIBAOM_DEC_BUILD_DIR := $(LIBAOM_DEC_DIR)/build.libavif
|
export LIBAOM_DIR = node_modules/libaom
|
||||||
LIBAOM_DEC_OUT := $(LIBAOM_DEC_BUILD_DIR)/libaom.a
|
|
||||||
|
|
||||||
OUT_ENC_JS = enc/avif_enc.js
|
OUT_ENC_JS = enc/avif_enc.js
|
||||||
OUT_ENC_CPP = $(OUT_ENC_JS:.js=.cpp)
|
OUT_ENC_MT_JS = enc/avif_enc_mt.js
|
||||||
OUT_ENC_WASM = $(OUT_ENC_JS:.js=.wasm)
|
|
||||||
|
|
||||||
OUT_DEC_JS = dec/avif_dec.js
|
OUT_DEC_JS = dec/avif_dec.js
|
||||||
OUT_DEC_CPP = $(OUT_DEC_JS:.js=.cpp)
|
|
||||||
OUT_DEC_WASM = $(OUT_DEC_JS:.js=.wasm)
|
|
||||||
|
|
||||||
# ERROR_ON_UNDEFINED_SYMBOLS=0 is needed to seperate the encoder and decoder
|
OUT_ENC_CPP = enc/avif_enc.cpp
|
||||||
EMSCRIPTEN_FLAGS = ${CXXFLAGS} \
|
OUT_DEC_CPP = dec/avif_dec.cpp
|
||||||
${LDFLAGS} \
|
|
||||||
--bind \
|
|
||||||
--closure 1 \
|
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
|
||||||
-s MODULARIZE=1 \
|
|
||||||
-s ERROR_ON_UNDEFINED_SYMBOLS=0
|
|
||||||
|
|
||||||
CODEC_EMCMAKE = emcmake cmake \
|
HELPER_MAKEFLAGS := -f helper.Makefile
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
|
||||||
-DBUILD_SHARED_LIBS=0 \
|
|
||||||
-DAVIF_CODEC_AOM=1 \
|
|
||||||
-DAVIF_LOCAL_AOM=1 \
|
|
||||||
../
|
|
||||||
|
|
||||||
LIBAOM_FLAGS = -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
|
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
all: $(OUT_ENC_JS) $(OUT_DEC_JS)
|
all: $(OUT_ENC_JS) $(OUT_DEC_JS) $(OUT_ENC_MT_JS)
|
||||||
|
|
||||||
$(OUT_ENC_JS): $(OUT_ENC_CPP) $(LIBAOM_ENC_OUT) $(CODEC_ENC_OUT)
|
$(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
||||||
$(CXX) \
|
$(MAKE) \
|
||||||
-I $(CODEC_ENC_DIR)/include \
|
$(HELPER_MAKEFLAGS) \
|
||||||
${EMSCRIPTEN_FLAGS} \
|
BUILD_DIR=$(ENC_BUILD_DIR) \
|
||||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
OUT_JS=$@ \
|
||||||
-o $@ \
|
OUT_CPP=$< \
|
||||||
$+
|
LIBAOM_FLAGS="\
|
||||||
|
-DCONFIG_AV1_DECODER=0 \
|
||||||
|
-DCONFIG_MULTITHREAD=0 \
|
||||||
|
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
||||||
|
" \
|
||||||
|
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0"
|
||||||
|
|
||||||
$(OUT_DEC_JS): $(OUT_DEC_CPP) $(LIBAOM_DEC_OUT) $(CODEC_DEC_OUT)
|
$(OUT_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
||||||
$(CXX) \
|
$(MAKE) \
|
||||||
-I $(CODEC_DEC_DIR)/include \
|
$(HELPER_MAKEFLAGS) \
|
||||||
${EMSCRIPTEN_FLAGS} \
|
BUILD_DIR=$(ENC_MT_BUILD_DIR) \
|
||||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
OUT_JS=$@ \
|
||||||
-o $@ \
|
OUT_CPP=$< \
|
||||||
$+
|
LIBAOM_FLAGS="\
|
||||||
|
-DCONFIG_AV1_DECODER=0 \
|
||||||
|
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
||||||
|
" \
|
||||||
|
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0" \
|
||||||
|
OUT_FLAGS="-pthread"
|
||||||
|
|
||||||
$(CODEC_ENC_OUT): $(CODEC_ENC_DIR)/CMakeLists.txt $(LIBAOM_ENC_OUT)
|
$(OUT_DEC_JS): $(OUT_DEC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt
|
||||||
mkdir -p $(CODEC_ENC_BUILD_DIR)
|
$(MAKE) \
|
||||||
cd $(CODEC_ENC_BUILD_DIR) && \
|
$(HELPER_MAKEFLAGS) \
|
||||||
$(CODEC_EMCMAKE) && \
|
BUILD_DIR=$(DEC_BUILD_DIR) \
|
||||||
$(MAKE)
|
OUT_JS=$@ \
|
||||||
|
OUT_CPP=$< \
|
||||||
$(CODEC_DEC_OUT): $(CODEC_DEC_DIR)/CMakeLists.txt $(LIBAOM_DEC_OUT)
|
LIBAOM_FLAGS="\
|
||||||
mkdir -p $(CODEC_DEC_BUILD_DIR)
|
-DCONFIG_AV1_ENCODER=0 \
|
||||||
cd $(CODEC_DEC_BUILD_DIR) && \
|
-DCONFIG_MULTITHREAD=0 \
|
||||||
$(CODEC_EMCMAKE) && \
|
" \
|
||||||
$(MAKE)
|
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_ENCODE=0"
|
||||||
|
|
||||||
$(LIBAOM_ENC_OUT): $(LIBAOM_ENC_DIR)/CMakeLists.txt
|
|
||||||
mkdir -p $(LIBAOM_ENC_BUILD_DIR)
|
|
||||||
cd $(LIBAOM_ENC_BUILD_DIR) && \
|
|
||||||
emcmake cmake \
|
|
||||||
$(LIBAOM_FLAGS) \
|
|
||||||
-DCONFIG_AV1_DECODER=0 \
|
|
||||||
-DCONFIG_AV1_HIGHBITDEPTH=0 \
|
|
||||||
../ && \
|
|
||||||
$(MAKE)
|
|
||||||
|
|
||||||
$(LIBAOM_DEC_OUT): $(LIBAOM_DEC_DIR)/CMakeLists.txt
|
|
||||||
mkdir -p $(LIBAOM_DEC_BUILD_DIR)
|
|
||||||
cd $(LIBAOM_DEC_BUILD_DIR) && \
|
|
||||||
emcmake cmake \
|
|
||||||
$(LIBAOM_FLAGS) \
|
|
||||||
-DCONFIG_AV1_ENCODER=0 \
|
|
||||||
../ && \
|
|
||||||
$(MAKE)
|
|
||||||
|
|
||||||
$(CODEC_ENC_DIR)/CMakeLists.txt: $(CODEC_ENC_DIR)
|
|
||||||
$(CODEC_DEC_DIR)/CMakeLists.txt: $(CODEC_DEC_DIR)
|
|
||||||
|
|
||||||
$(LIBAOM_ENC_DIR)/CMakeLists.txt: $(LIBAOM_ENC_DIR)
|
|
||||||
$(LIBAOM_DEC_DIR)/CMakeLists.txt: $(LIBAOM_DEC_DIR)
|
|
||||||
|
|
||||||
$(CODEC_PACKAGE):
|
$(CODEC_PACKAGE):
|
||||||
|
mkdir -p $(@D)
|
||||||
curl -sL $(CODEC_URL) -o $@
|
curl -sL $(CODEC_URL) -o $@
|
||||||
|
|
||||||
$(LIBAOM_PACKAGE):
|
$(LIBAOM_PACKAGE):
|
||||||
|
mkdir -p $(@D)
|
||||||
curl -sL $(LIBAOM_URL) -o $@
|
curl -sL $(LIBAOM_URL) -o $@
|
||||||
|
|
||||||
$(CODEC_ENC_DIR) $(CODEC_DEC_DIR): $(CODEC_PACKAGE)
|
$(CODEC_DIR)/CMakeLists.txt: $(CODEC_PACKAGE)
|
||||||
mkdir -p $@
|
mkdir -p $(@D)
|
||||||
tar xz --strip 1 -C $@ -f $(CODEC_PACKAGE)
|
tar xzm --strip 1 -C $(@D) -f $(CODEC_PACKAGE)
|
||||||
|
|
||||||
$(LIBAOM_ENC_DIR) $(LIBAOM_DEC_DIR): $(LIBAOM_PACKAGE)
|
$(LIBAOM_DIR)/CMakeLists.txt: $(LIBAOM_PACKAGE)
|
||||||
mkdir -p $@
|
mkdir -p $(@D)
|
||||||
tar xz -C $@ -f $(LIBAOM_PACKAGE)
|
tar xzm -C $(@D) -f $(LIBAOM_PACKAGE)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) $(LIBAOM_PACKAGE) $(CODEC_PACKAGE) $(OUT_ENC_JS) $(OUT_ENC_WASM) $(OUT_DEC_JS) $(OUT_DEC_WASM)
|
$(MAKE) $(HELPER_MAKEFLAGS) BUILD_DIR=$(ENC_BUILD_DIR) OUT_JS=$(OUT_ENC_JS) clean
|
||||||
$(MAKE) -C $(CODEC_ENC_BUILD_DIR) clean
|
$(MAKE) $(HELPER_MAKEFLAGS) BUILD_DIR=$(ENC_MT_BUILD_DIR) OUT_JS=$(OUT_ENC_MT_JS) clean
|
||||||
$(MAKE) -C $(CODEC_DEC_BUILD_DIR) clean
|
$(MAKE) $(HELPER_MAKEFLAGS) BUILD_DIR=$(DEC_BUILD_DIR) OUT_JS=$(OUT_DEC_JS) clean
|
||||||
$(MAKE) -C $(LIBAOM_ENC_BUILD_DIR) clean
|
|
||||||
$(MAKE) -C $(LIBAOM_DEC_BUILD_DIR) clean
|
|
||||||
|
|||||||
@@ -8,15 +8,10 @@ thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");
|
|||||||
thread_local const val ImageData = val::global("ImageData");
|
thread_local const val ImageData = val::global("ImageData");
|
||||||
|
|
||||||
val decode(std::string avifimage) {
|
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();
|
avifImage* image = avifImageCreateEmpty();
|
||||||
avifDecoder* decoder = avifDecoderCreate();
|
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
|
// image is an independent copy of decoded data, decoder may be destroyed here
|
||||||
avifDecoderDestroy(decoder);
|
avifDecoderDestroy(decoder);
|
||||||
|
|
||||||
@@ -25,7 +20,8 @@ val decode(std::string avifimage) {
|
|||||||
if (decodeResult == AVIF_RESULT_OK) {
|
if (decodeResult == AVIF_RESULT_OK) {
|
||||||
// Convert to interleaved RGB(A)/BGR(A) using a libavif-allocated buffer.
|
// Convert to interleaved RGB(A)/BGR(A) using a libavif-allocated buffer.
|
||||||
avifRGBImage rgb;
|
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.
|
rgb.depth = 8; // Does not need to match image->depth. We always want 8-bit pixels.
|
||||||
|
|
||||||
avifRGBImageAllocatePixels(&rgb);
|
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.
|
// 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()`:
|
// 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:
|
// Now we can safely free the RGB pixels:
|
||||||
avifRGBImageFreePixels(&rgb);
|
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;
|
decode(data: BufferSource): ImageData | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function(opts: EmscriptenWasm.ModuleOpts): AVIFModule;
|
declare var moduleFactory: EmscriptenWasm.ModuleFactory<AVIFModule>;
|
||||||
|
|
||||||
|
export default moduleFactory;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,4 +1,5 @@
|
|||||||
#include <emscripten/bind.h>
|
#include <emscripten/bind.h>
|
||||||
|
#include <emscripten/threading.h>
|
||||||
#include <emscripten/val.h>
|
#include <emscripten/val.h>
|
||||||
#include "avif/avif.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);
|
avifImage* image = avifImageCreate(width, height, depth, format);
|
||||||
|
|
||||||
if (
|
if (options.maxQuantizer == AVIF_QUANTIZER_LOSSLESS &&
|
||||||
options.maxQuantizer == AVIF_QUANTIZER_LOSSLESS &&
|
options.minQuantizer == AVIF_QUANTIZER_LOSSLESS &&
|
||||||
options.minQuantizer == AVIF_QUANTIZER_LOSSLESS &&
|
options.minQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS &&
|
||||||
options.minQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS &&
|
options.maxQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS && format == AVIF_PIXEL_FORMAT_YUV444) {
|
||||||
options.maxQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS &&
|
|
||||||
format == AVIF_PIXEL_FORMAT_YUV444
|
|
||||||
) {
|
|
||||||
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_IDENTITY;
|
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_IDENTITY;
|
||||||
} else {
|
} else {
|
||||||
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT709;
|
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT709;
|
||||||
@@ -71,7 +69,7 @@ val encode(std::string buffer, int width, int height, AvifOptions options) {
|
|||||||
avifImageRGBToYUV(image, &srcRGB);
|
avifImageRGBToYUV(image, &srcRGB);
|
||||||
|
|
||||||
avifEncoder* encoder = avifEncoderCreate();
|
avifEncoder* encoder = avifEncoderCreate();
|
||||||
encoder->maxThreads = 1;
|
encoder->maxThreads = emscripten_num_logical_cores();
|
||||||
encoder->minQuantizer = options.minQuantizer;
|
encoder->minQuantizer = options.minQuantizer;
|
||||||
encoder->maxQuantizer = options.maxQuantizer;
|
encoder->maxQuantizer = options.maxQuantizer;
|
||||||
encoder->minQuantizerAlpha = options.minQuantizerAlpha;
|
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';
|
export interface EncodeOptions {
|
||||||
|
minQuantizer: number;
|
||||||
interface AVIFModule extends EmscriptenWasm.Module {
|
maxQuantizer: number;
|
||||||
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array | null;
|
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;
|
||||||
|
|||||||
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
Normal file
3268
codecs/avif/enc/avif_enc_mt.js
Normal file
File diff suppressed because it is too large
Load Diff
BIN
codecs/avif/enc/avif_enc_mt.wasm
Executable file
BIN
codecs/avif/enc/avif_enc_mt.wasm
Executable file
Binary file not shown.
103
codecs/avif/enc/avif_enc_mt.worker.js
Normal file
103
codecs/avif/enc/avif_enc_mt.worker.js
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
|
set -e
|
||||||
|
|
||||||
docker build -t squoosh-rust - < ../rust.Dockerfile
|
if [ ! -z "$RUST_IMG" ]
|
||||||
docker run --rm -v $PWD:/src squoosh-rust "$@"
|
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
|
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 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
|
# Build and cache standard libraries with these flags
|
||||||
RUN emcc ${CXXFLAGS} --bind -xc++ /dev/null -o /dev/null
|
RUN emcc ${CXXFLAGS} --bind -xc++ /dev/null -o /dev/null
|
||||||
WORKDIR /src
|
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",
|
"name": "hqx",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:image": "docker build -t squoosh-hqx - < Dockerfile",
|
"build": "RUST_IMG=rust:1.40 ../build-rust.sh"
|
||||||
"build": "docker run --rm -v $(pwd):/src squoosh-hqx ./build.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
vendored
52
codecs/hqx/pkg/squooshhqx.d.ts
vendored
@@ -1,10 +1,48 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
* @param {Uint32Array} input_image
|
* @param {Uint32Array} input_image
|
||||||
* @param {number} input_width
|
* @param {number} input_width
|
||||||
* @param {number} input_height
|
* @param {number} input_height
|
||||||
* @param {number} factor
|
* @param {number} factor
|
||||||
* @returns {Uint32Array}
|
* @returns {Uint32Array}
|
||||||
*/
|
*/
|
||||||
export function resize(input_image: Uint32Array, input_width: number, input_height: number, factor: number): 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>;
|
||||||
|
|||||||
@@ -1,2 +1,107 @@
|
|||||||
import * as wasm from "./squooshhqx_bg.wasm";
|
let wasm;
|
||||||
export * from "./squooshhqx_bg.js";
|
|
||||||
|
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;
|
||||||
|
|||||||
@@ -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 \
|
--closure 1 \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
-s MODULARIZE=1 \
|
-s MODULARIZE=1 \
|
||||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
-s TEXTDECODER=2 \
|
||||||
|
-s ENVIRONMENT='worker' \
|
||||||
|
-s EXPORT_ES6=1 \
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$+
|
$+
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<style>
|
<style>
|
||||||
canvas {
|
canvas {
|
||||||
image-rendering: pixelated;
|
image-rendering: pixelated;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script src='imagequant.js'></script>
|
<script type="module">
|
||||||
<script>
|
import imagequant from './imagequant.js';
|
||||||
const Module = imagequant();
|
|
||||||
|
|
||||||
async function loadImage(src) {
|
async function loadImage(src) {
|
||||||
// Load image
|
// Load image
|
||||||
const img = document.createElement('img');
|
const img = document.createElement('img');
|
||||||
img.src = src;
|
img.src = src;
|
||||||
await new Promise(resolve => img.onload = resolve);
|
await new Promise((resolve) => (img.onload = resolve));
|
||||||
// Make canvas same size as image
|
// Make canvas same size as image
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
[canvas.width, canvas.height] = [img.width, img.height];
|
[canvas.width, canvas.height] = [img.width, img.height];
|
||||||
@@ -22,19 +21,32 @@
|
|||||||
return ctx.getImageData(0, 0, img.width, img.height);
|
return ctx.getImageData(0, 0, img.width, img.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
Module.onRuntimeInitialized = async _ => {
|
async function main() {
|
||||||
console.log('Version:', Module.version().toString(16));
|
const module = await imagequant();
|
||||||
|
|
||||||
|
console.log('Version:', module.version().toString(16));
|
||||||
const image = await loadImage('../example.png');
|
const image = await loadImage('../example.png');
|
||||||
// const rawImage = Module.quantize(image.data, image.width, image.height, 256, 1.0);
|
const rawImage = module.quantize(
|
||||||
const rawImage = Module.zx_quantize(image.data, image.width, image.height, 1.0);
|
image.data,
|
||||||
|
image.width,
|
||||||
|
image.height,
|
||||||
|
256,
|
||||||
|
1.0,
|
||||||
|
);
|
||||||
console.log('done');
|
console.log('done');
|
||||||
|
|
||||||
const imageData = new ImageData(new Uint8ClampedArray(rawImage.buffer), image.width, image.height);
|
const imageData = new ImageData(
|
||||||
|
new Uint8ClampedArray(rawImage.buffer),
|
||||||
|
image.width,
|
||||||
|
image.height,
|
||||||
|
);
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
canvas.width = image.width;
|
canvas.width = image.width;
|
||||||
canvas.height = image.height;
|
canvas.height = image.height;
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
ctx.putImageData(imageData, 0, 0);
|
ctx.putImageData(imageData, 0, 0);
|
||||||
document.body.appendChild(canvas);
|
document.body.appendChild(canvas);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
21
codecs/imagequant/imagequant.d.ts
vendored
21
codecs/imagequant/imagequant.d.ts
vendored
@@ -1,6 +1,19 @@
|
|||||||
interface QuantizerModule extends EmscriptenWasm.Module {
|
export interface QuantizerModule extends EmscriptenWasm.Module {
|
||||||
quantize(data: BufferSource, width: number, height: number, numColors: number, dither: number): Uint8ClampedArray;
|
quantize(
|
||||||
zx_quantize(data: BufferSource, width: number, height: number, dither: number): Uint8ClampedArray;
|
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;
|
||||||
|
|||||||
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
|
||||||
72
codecs/jxl/dec/jxl_dec.cpp
Normal file
72
codecs/jxl/dec/jxl_dec.cpp
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#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
|
||||||
|
|
||||||
|
#define EXPECT_TRUE(a) \
|
||||||
|
if (!(a)) { \
|
||||||
|
return val::null(); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXPECT_EQ(a, b) EXPECT_TRUE((a) == (b));
|
||||||
|
|
||||||
|
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
Normal file
1195
codecs/jxl/dec/jxl_dec.js
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.
115
codecs/jxl/enc/jxl_enc.cpp
Normal file
115
codecs/jxl/enc/jxl_enc.cpp
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
#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.
|
||||||
|
cparams.options.nb_repeats = 0.1;
|
||||||
|
|
||||||
|
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.progressive_dc = 1;
|
||||||
|
cparams.responsive = 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
Normal file
1606
codecs/jxl/enc/jxl_enc.js
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) \
|
-I $(CODEC_DIR) \
|
||||||
${CXXFLAGS} \
|
${CXXFLAGS} \
|
||||||
${LDFLAGS} \
|
${LDFLAGS} \
|
||||||
--bind \
|
|
||||||
--closure 1 \
|
--closure 1 \
|
||||||
|
--bind \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
-s MODULARIZE=1 \
|
-s MODULARIZE=1 \
|
||||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
-s TEXTDECODER=2 \
|
||||||
|
-s ENVIRONMENT='worker' \
|
||||||
|
-s EXPORT_ES6=1 \
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$+
|
$+
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<script src='mozjpeg_enc.js'></script>
|
<script type="module">
|
||||||
<script>
|
import mozjpeg_enc from './mozjpeg_enc.js';
|
||||||
const module = mozjpeg_enc();
|
|
||||||
|
|
||||||
async function loadImage(src) {
|
async function loadImage(src) {
|
||||||
// Load image
|
// Load image
|
||||||
const img = document.createElement('img');
|
const img = document.createElement('img');
|
||||||
img.src = src;
|
img.src = src;
|
||||||
await new Promise(resolve => img.onload = resolve);
|
await new Promise((resolve) => (img.onload = resolve));
|
||||||
// Make canvas same size as image
|
// Make canvas same size as image
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
[canvas.width, canvas.height] = [img.width, img.height];
|
[canvas.width, canvas.height] = [img.width, img.height];
|
||||||
@@ -17,7 +16,9 @@
|
|||||||
return ctx.getImageData(0, 0, img.width, img.height);
|
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));
|
console.log('Version:', module.version().toString(16));
|
||||||
const image = await loadImage('../example.png');
|
const image = await loadImage('../example.png');
|
||||||
const result = module.encode(image.data, image.width, image.height, {
|
const result = module.encode(image.data, image.width, image.height, {
|
||||||
@@ -39,10 +40,12 @@
|
|||||||
chroma_quality: 75,
|
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 blobURL = URL.createObjectURL(blob);
|
||||||
const img = document.createElement('img');
|
const img = document.createElement('img');
|
||||||
img.src = blobURL;
|
img.src = blobURL;
|
||||||
document.body.appendChild(img);
|
document.body.appendChild(img);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
</script>
|
</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';
|
export const enum MozJpegColorSpace {
|
||||||
|
GRAYSCALE = 1,
|
||||||
interface MozJPEGModule extends EmscriptenWasm.Module {
|
RGB,
|
||||||
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array;
|
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;
|
||||||
|
|||||||
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.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "adler32"
|
name = "adler"
|
||||||
version = "1.1.0"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
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]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bit-vec"
|
name = "bit-vec"
|
||||||
@@ -38,9 +44,9 @@ checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.2.0"
|
version = "1.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37fa13df2292ecb479ec23aa06f4507928bef07839be9ef15281411076629431"
|
checksum = "41aa2ec95ca3b5c54cf73c91acf06d24f4495d5f1b1c12506ae3483d646177ac"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
@@ -50,9 +56,9 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.58"
|
version = "1.0.62"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518"
|
checksum = "f1770ced377336a88a67c473594ccc14eca6f4559217c34f64aac8f83d641b40"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@@ -60,6 +66,12 @@ version = "0.1.10"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cloudflare-zlib"
|
name = "cloudflare-zlib"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
@@ -78,6 +90,18 @@ dependencies = [
|
|||||||
"cc",
|
"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]]
|
[[package]]
|
||||||
name = "crc"
|
name = "crc"
|
||||||
version = "1.8.1"
|
version = "1.8.1"
|
||||||
@@ -89,58 +113,57 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.2.0"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
|
||||||
dependencies = [
|
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]]
|
[[package]]
|
||||||
name = "crossbeam-deque"
|
name = "crossbeam-deque"
|
||||||
version = "0.7.3"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
|
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
"crossbeam-epoch",
|
"crossbeam-epoch",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"maybe-uninit",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-epoch"
|
name = "crossbeam-epoch"
|
||||||
version = "0.8.2"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
|
checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"cfg-if 1.0.0",
|
||||||
"cfg-if",
|
"const_fn",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"maybe-uninit",
|
|
||||||
"memoffset",
|
"memoffset",
|
||||||
"scopeguard",
|
"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]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.7.2"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
|
checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"cfg-if",
|
"cfg-if 1.0.0",
|
||||||
|
"const_fn",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -156,27 +179,34 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.5.3"
|
version = "1.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
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]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.15"
|
version = "0.1.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
|
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "image"
|
name = "image"
|
||||||
version = "0.23.7"
|
version = "0.23.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2397fc43bd5648b7117aabb3c5e62d0e62c194826ec77b0b4d0c41e62744635"
|
checksum = "b4f0a8345b33b082aedec2f4d7d4a926b845cee184cbe78b703413066564431b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"color_quant",
|
||||||
"num-iter",
|
"num-iter",
|
||||||
"num-rational",
|
"num-rational",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
@@ -185,11 +215,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.4.0"
|
version = "1.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe"
|
checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
|
"hashbrown",
|
||||||
"rayon",
|
"rayon",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -210,39 +241,42 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.72"
|
version = "0.2.80"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701"
|
checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libdeflater"
|
name = "libdeflate-sys"
|
||||||
version = "0.2.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "66dca08b13369865b2f6dca1dd05f833985cbe6c12a676b04d55f78b85e80246"
|
checksum = "21e39efa87b84db3e13ff4e2dfac1e57220abcbd7fe8ec44d238f7f4f787cc1f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "libdeflater"
|
||||||
version = "0.4.8"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
checksum = "a4810980d791f26d470e2d7d91a3d4d22aa3a4b709fb7e9c5e43ee54f83a01f2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"libdeflate-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "maybe-uninit"
|
name = "log"
|
||||||
version = "2.0.0"
|
version = "0.4.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.10",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memoffset"
|
name = "memoffset"
|
||||||
version = "0.5.5"
|
version = "0.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f"
|
checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
@@ -257,10 +291,20 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-integer"
|
name = "miniz_oxide"
|
||||||
version = "0.1.43"
|
version = "0.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
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 = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
@@ -268,9 +312,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-iter"
|
name = "num-iter"
|
||||||
version = "0.1.41"
|
version = "0.1.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f"
|
checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
@@ -279,9 +323,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-rational"
|
name = "num-rational"
|
||||||
version = "0.3.0"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138"
|
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
@@ -290,9 +334,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.12"
|
version = "0.2.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
|
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
@@ -308,42 +352,59 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxipng"
|
name = "once_cell"
|
||||||
version = "3.0.0"
|
version = "1.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d5fd695858078338d73862ff3755f820eff0bf4f3304e4b52f22aba53463183a"
|
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "oxipng"
|
||||||
|
version = "4.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ea40b366cecfce76ee3b082e7e6567b82cdef75644a22442ca8584bc666ff4eb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit-vec",
|
"bit-vec",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"cloudflare-zlib",
|
"cloudflare-zlib",
|
||||||
"crc",
|
"crc",
|
||||||
|
"crossbeam-channel",
|
||||||
"image",
|
"image",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"itertools",
|
"itertools",
|
||||||
"libdeflater",
|
"libdeflater",
|
||||||
"log",
|
"log",
|
||||||
"miniz_oxide",
|
"miniz_oxide 0.4.3",
|
||||||
|
"rayon",
|
||||||
"rgb",
|
"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]]
|
[[package]]
|
||||||
name = "png"
|
name = "png"
|
||||||
version = "0.16.6"
|
version = "0.16.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c150bf7479fafe3dd8740dbe48cc33b2a3efb7b0fe3483aced8bbc39f6d0238d"
|
checksum = "dfe7f9f1c730833200b134370e1d5098964231af8450bce9b78ee3ab5278b970"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"deflate",
|
"deflate",
|
||||||
"miniz_oxide",
|
"miniz_oxide 0.3.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.18"
|
version = "1.0.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
|
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
@@ -359,9 +420,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon"
|
name = "rayon"
|
||||||
version = "1.3.1"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080"
|
checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"crossbeam-deque",
|
"crossbeam-deque",
|
||||||
@@ -371,12 +432,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon-core"
|
name = "rayon-core"
|
||||||
version = "1.7.1"
|
version = "1.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280"
|
checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"crossbeam-channel",
|
||||||
"crossbeam-deque",
|
"crossbeam-deque",
|
||||||
"crossbeam-queue",
|
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
@@ -384,33 +445,63 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rgb"
|
name = "rgb"
|
||||||
version = "0.8.20"
|
version = "0.8.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "90ef54b45ae131327a88597e2463fee4098ad6c88ba7b6af4b3987db8aad4098"
|
checksum = "287f3c3f8236abb92d8b7e36797f19159df4b58f0a658cc3fb6dd3004b1f3bd3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc_version"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "65c94201b44764d6d1f7e37c15a8289ed55e546c1762c7f1d57f616966e0c181"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
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]]
|
[[package]]
|
||||||
name = "squoosh-oxipng"
|
name = "squoosh-oxipng"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"crossbeam-channel",
|
||||||
"log",
|
"log",
|
||||||
|
"once_cell",
|
||||||
"oxipng",
|
"oxipng",
|
||||||
|
"rayon",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.34"
|
version = "1.0.48"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b"
|
checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -418,10 +509,10 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typed-arena"
|
name = "ucd-trie"
|
||||||
version = "1.7.0"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
|
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
@@ -431,19 +522,19 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.64"
|
version = "0.2.68"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a634620115e4a229108b71bde263bb4220c483b3f07f5ba514ee8d15064c4c2"
|
checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if 0.1.10",
|
||||||
"wasm-bindgen-macro",
|
"wasm-bindgen-macro",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-backend"
|
name = "wasm-bindgen-backend"
|
||||||
version = "0.2.64"
|
version = "0.2.68"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3e53963b583d18a5aa3aaae4b4c1cb535218246131ba22a71f05b518098571df"
|
checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
@@ -456,9 +547,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.2.64"
|
version = "0.2.68"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3fcfd5ef6eec85623b4c6e844293d4516470d8f19cd72d0d12246017eb9060b8"
|
checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"wasm-bindgen-macro-support",
|
"wasm-bindgen-macro-support",
|
||||||
@@ -466,9 +557,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro-support"
|
name = "wasm-bindgen-macro-support"
|
||||||
version = "0.2.64"
|
version = "0.2.68"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9adff9ee0e94b926ca81b57f57f86d5545cdcb1d259e21ec9bdd95b901754c75"
|
checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -479,18 +570,6 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-shared"
|
name = "wasm-bindgen-shared"
|
||||||
version = "0.2.64"
|
version = "0.2.68"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f7b90ea6c632dd06fd765d44542e234d5e63d9bb917ecd64d79778a13bd79ae"
|
checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
|
||||||
|
|
||||||
[[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",
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -5,14 +5,23 @@ authors = ["Ingvar Stepanyan <me@rreverser.com>"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
|
[package.metadata.wasm-pack.profile.release]
|
||||||
|
wasm-opt = ["-O", "--no-validation"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
oxipng = { version = "3.0.0", default-features = false }
|
oxipng = { version = "4.0.0", default-features = false, features = ["libdeflater"] }
|
||||||
wasm-bindgen = "0.2.64"
|
wasm-bindgen = "0.2.68"
|
||||||
log = { version = "0.4", features = ["release_max_level_off"] }
|
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]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
opt-level = "s"
|
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
|
|
||||||
8
codecs/oxipng/build.sh
Executable file
8
codecs/oxipng/build.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
rm -rf pkg,{-parallel}
|
||||||
|
wasm-pack build --target web
|
||||||
|
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory' wasm-pack build -t web -d pkg-parallel -- -Z build-std=panic_abort,std --features=parallel
|
||||||
|
rm pkg{,-parallel}/.gitignore
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "oxipng",
|
"name": "oxipng",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "../build-rust.sh"
|
"build": "RUST_IMG=rustlang/rust:8bb115b1090d ../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
|
||||||
|
}
|
||||||
53
codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts
vendored
Normal file
53
codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts
vendored
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/* 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>;
|
||||||
196
codecs/oxipng/pkg-parallel/squoosh_oxipng.js
Normal file
196
codecs/oxipng/pkg-parallel/squoosh_oxipng.js
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
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
vendored
Normal file
12
codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm.d.ts
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
|
||||||
36
codecs/oxipng/pkg/squoosh_oxipng.d.ts
vendored
36
codecs/oxipng/pkg/squoosh_oxipng.d.ts
vendored
@@ -1,8 +1,36 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
* @param {Uint8Array} data
|
* @param {Uint8Array} data
|
||||||
* @param {number} level
|
* @param {number} level
|
||||||
* @returns {Uint8Array}
|
* @returns {Uint8Array}
|
||||||
*/
|
*/
|
||||||
export function optimise(data: Uint8Array, level: number): 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>;
|
||||||
|
|||||||
@@ -1,2 +1,126 @@
|
|||||||
import * as wasm from "./squoosh_oxipng_bg.wasm";
|
let wasm;
|
||||||
export * from "./squoosh_oxipng_bg.js";
|
|
||||||
|
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;
|
||||||
|
|||||||
@@ -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,9 +1,12 @@
|
|||||||
mod malloc_shim;
|
|
||||||
|
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use oxipng::AlphaOptim;
|
use oxipng::AlphaOptim;
|
||||||
|
|
||||||
#[wasm_bindgen(catch)]
|
mod malloc_shim;
|
||||||
|
|
||||||
|
#[cfg(feature = "parallel")]
|
||||||
|
pub mod parallel;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
pub fn optimise(data: &[u8], level: u8) -> Vec<u8> {
|
pub fn optimise(data: &[u8], level: u8) -> Vec<u8> {
|
||||||
let mut options = oxipng::Options::from_preset(level);
|
let mut options = oxipng::Options::from_preset(level);
|
||||||
options.alphas.insert(AlphaOptim::Black);
|
options.alphas.insert(AlphaOptim::Black);
|
||||||
|
|||||||
61
codecs/oxipng/src/parallel.rs
Normal file
61
codecs/oxipng/src/parallel.rs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
use crossbeam_channel::{Sender, Receiver, bounded};
|
||||||
|
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
vendored
68
codecs/resize/pkg/squoosh_resize.d.ts
vendored
@@ -1,14 +1,60 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
* @param {Uint8Array} input_image
|
* @param {Uint8Array} input_image
|
||||||
* @param {number} input_width
|
* @param {number} input_width
|
||||||
* @param {number} input_height
|
* @param {number} input_height
|
||||||
* @param {number} output_width
|
* @param {number} output_width
|
||||||
* @param {number} output_height
|
* @param {number} output_height
|
||||||
* @param {number} typ_idx
|
* @param {number} typ_idx
|
||||||
* @param {boolean} premultiply
|
* @param {boolean} premultiply
|
||||||
* @param {boolean} color_space_conversion
|
* @param {boolean} color_space_conversion
|
||||||
* @returns {Uint8Array}
|
* @returns {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 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>;
|
||||||
|
|||||||
@@ -1,2 +1,131 @@
|
|||||||
import * as wasm from "./squoosh_resize_bg.wasm";
|
let wasm;
|
||||||
export * from "./squoosh_resize_bg.js";
|
|
||||||
|
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;
|
||||||
|
|||||||
@@ -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
|
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
|
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 rustup target add wasm32-unknown-unknown
|
||||||
|
RUN if [[ $RUST_IMG = rustlang/rust:* ]] ; then rustup component add rust-src ; fi
|
||||||
COPY --from=wasm-tools /emsdk/upstream/bin/wasm-opt /emsdk/upstream/bin/clang /usr/local/bin/
|
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/lib/ /usr/local/lib/
|
||||||
COPY --from=wasm-tools /emsdk/upstream/emscripten/system/include/libc/ /wasm32/include/
|
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"
|
ENV CPATH="/wasm32/include"
|
||||||
WORKDIR /src
|
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_DIR = node_modules/libwebp
|
||||||
CODEC_OUT_RELATIVE = src/.libs/libwebp.a
|
CODEC_OUT_RELATIVE = src/.libs/libwebp.a
|
||||||
CODEC_OUT := $(addprefix $(CODEC_DIR)/, $(CODEC_OUT_RELATIVE))
|
CODEC_OUT := $(addprefix $(CODEC_DIR)/, $(CODEC_OUT_RELATIVE))
|
||||||
@@ -18,7 +18,9 @@ all: $(OUT_JS)
|
|||||||
--closure 1 \
|
--closure 1 \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
-s MODULARIZE=1 \
|
-s MODULARIZE=1 \
|
||||||
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
-s TEXTDECODER=2 \
|
||||||
|
-s ENVIRONMENT='worker' \
|
||||||
|
-s EXPORT_ES6=1 \
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$+
|
$+
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<script src='webp_dec.js'></script>
|
<script src='webp_dec.js'></script>
|
||||||
<script>
|
<script>
|
||||||
const Module = webp_dec();
|
|
||||||
|
|
||||||
async function loadFile(src) {
|
async function loadFile(src) {
|
||||||
const resp = await fetch(src);
|
const resp = await fetch(src);
|
||||||
return await resp.arrayBuffer();
|
return await resp.arrayBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
Module.onRuntimeInitialized = async _ => {
|
webp_dec().then(async module => {
|
||||||
console.log('Version:', Module.version().toString(16));
|
console.log('Version:', module.version().toString(16));
|
||||||
const image = await loadFile('../../example.webp');
|
const image = await loadFile('../../example.webp');
|
||||||
const imageData = Module.decode(image);
|
const imageData = module.decode(image);
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
canvas.width = result.width;
|
canvas.width = imageData.width;
|
||||||
canvas.height = result.height;
|
canvas.height = imageData.height;
|
||||||
document.body.appendChild(canvas);
|
document.body.appendChild(canvas);
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
ctx.putImageData(imageData, 0, 0);
|
ctx.putImageData(imageData, 0, 0);
|
||||||
};
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
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;
|
decode(data: BufferSource): ImageData | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function(opts: EmscriptenWasm.ModuleOpts): WebPModule;
|
declare var moduleFactory: EmscriptenWasm.ModuleFactory<WebPModule>;
|
||||||
|
|
||||||
|
export default moduleFactory;
|
||||||
|
|||||||
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>
|
<!doctype html>
|
||||||
<script src='webp_enc.js'></script>
|
<script src='webp_enc.js'></script>
|
||||||
<script>
|
<script>
|
||||||
const module = webp_enc();
|
|
||||||
|
|
||||||
async function loadImage(src) {
|
async function loadImage(src) {
|
||||||
// Load image
|
// Load image
|
||||||
const img = document.createElement('img');
|
const img = document.createElement('img');
|
||||||
@@ -17,7 +15,7 @@
|
|||||||
return ctx.getImageData(0, 0, img.width, img.height);
|
return ctx.getImageData(0, 0, img.width, img.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.onRuntimeInitialized = async _ => {
|
webp_enc().then(async module => {
|
||||||
console.log('Version:', module.version().toString(16));
|
console.log('Version:', module.version().toString(16));
|
||||||
const image = await loadImage('../../example.png');
|
const image = await loadImage('../../example.png');
|
||||||
const result = module.encode(image.data, image.width, image.height, {
|
const result = module.encode(image.data, image.width, image.height, {
|
||||||
@@ -56,5 +54,5 @@
|
|||||||
const img = document.createElement('img');
|
const img = document.createElement('img');
|
||||||
img.src = blobURL;
|
img.src = blobURL;
|
||||||
document.body.appendChild(img);
|
document.body.appendChild(img);
|
||||||
};
|
});
|
||||||
</script>
|
</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';
|
export interface EncodeOptions {
|
||||||
|
quality: number;
|
||||||
interface WebPModule extends EmscriptenWasm.Module {
|
target_size: number;
|
||||||
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array | null;
|
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;
|
||||||
|
|||||||
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
Normal file
1185
codecs/wp2/dec/wp2_dec.js
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.
|
||||||
38
codecs/wp2/enc/wp2_enc.cpp
Normal file
38
codecs/wp2/enc/wp2_enc.cpp
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#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");
|
||||||
|
|
||||||
|
val encode(std::string image_in, int image_width, int image_height, WP2::EncoderConfig config) {
|
||||||
|
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<WP2::EncoderConfig>("WP2EncoderConfig")
|
||||||
|
.field("quality", &WP2::EncoderConfig::quality)
|
||||||
|
.field("alpha_quality", &WP2::EncoderConfig::alpha_quality)
|
||||||
|
.field("speed", &WP2::EncoderConfig::speed)
|
||||||
|
.field("pass", &WP2::EncoderConfig::pass)
|
||||||
|
.field("sns", &WP2::EncoderConfig::sns);
|
||||||
|
|
||||||
|
function("encode", &encode);
|
||||||
|
}
|
||||||
20
codecs/wp2/enc/wp2_enc.d.ts
vendored
Normal file
20
codecs/wp2/enc/wp2_enc.d.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
export interface EncodeOptions {
|
||||||
|
quality: number;
|
||||||
|
alpha_quality: number;
|
||||||
|
speed: number;
|
||||||
|
pass: number;
|
||||||
|
sns: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
Normal file
1277
codecs/wp2/enc/wp2_enc.js
Normal file
File diff suppressed because it is too large
Load Diff
BIN
codecs/wp2/enc/wp2_enc.wasm
Executable file
BIN
codecs/wp2/enc/wp2_enc.wasm
Executable file
Binary file not shown.
6
codecs/wp2/package.json
Normal file
6
codecs/wp2/package.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "wp2",
|
||||||
|
"scripts": {
|
||||||
|
"build": "../build-cpp.sh"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
const DtsCreator = require('typed-css-modules');
|
|
||||||
const chokidar = require('chokidar');
|
|
||||||
const util = require('util');
|
|
||||||
const sass = require('node-sass');
|
|
||||||
const normalizePath = require('normalize-path');
|
|
||||||
|
|
||||||
const sassRender = util.promisify(sass.render);
|
|
||||||
|
|
||||||
async function sassToCss(path) {
|
|
||||||
const result = await sassRender({ file: path });
|
|
||||||
return result.css;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} Opts
|
|
||||||
* @property {boolean} watch Watch for changes
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Create typing files for CSS & SCSS.
|
|
||||||
*
|
|
||||||
* @param {string[]} rootPaths Paths to search within
|
|
||||||
* @param {Opts} [opts={}] Options.
|
|
||||||
*/
|
|
||||||
function addCssTypes(rootPaths, opts = {}) {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const { watch = false } = opts;
|
|
||||||
|
|
||||||
const paths = [];
|
|
||||||
const preReadyPromises = [];
|
|
||||||
let ready = false;
|
|
||||||
|
|
||||||
for (const rootPath of rootPaths) {
|
|
||||||
const rootPathUnix = normalizePath(rootPath);
|
|
||||||
// Look for scss & css in each path.
|
|
||||||
paths.push(rootPathUnix + '/**/*.scss');
|
|
||||||
paths.push(rootPathUnix + '/**/*.css');
|
|
||||||
}
|
|
||||||
|
|
||||||
// For simplicity, the watcher is used even if we're not watching.
|
|
||||||
// If we're not watching, we stop the watcher after the initial files are found.
|
|
||||||
const watcher = chokidar.watch(paths, {
|
|
||||||
// Avoid processing already-processed files.
|
|
||||||
ignored: '*.d.*',
|
|
||||||
// Without this, travis and netlify builds never complete. I'm not sure why, but it might be
|
|
||||||
// related to https://github.com/paulmillr/chokidar/pull/758
|
|
||||||
persistent: watch,
|
|
||||||
});
|
|
||||||
|
|
||||||
function change(path) {
|
|
||||||
const promise = (async function() {
|
|
||||||
const creator = new DtsCreator({ camelCase: true });
|
|
||||||
const result = path.endsWith('.scss') ?
|
|
||||||
await creator.create(path, await sassToCss(path)) :
|
|
||||||
await creator.create(path);
|
|
||||||
|
|
||||||
await result.writeFile();
|
|
||||||
})();
|
|
||||||
|
|
||||||
if (!ready) preReadyPromises.push(promise);
|
|
||||||
}
|
|
||||||
|
|
||||||
watcher.on('change', change);
|
|
||||||
watcher.on('add', change);
|
|
||||||
|
|
||||||
// 'ready' is when events have been fired for file discovery.
|
|
||||||
watcher.on('ready', () => {
|
|
||||||
ready = true;
|
|
||||||
// Wait for the current set of processing to finish.
|
|
||||||
Promise.all(preReadyPromises).then(resolve);
|
|
||||||
// And if we're not watching, close the watcher.
|
|
||||||
if (!watch) watcher.close();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = addCssTypes;
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
|
||||||
const ejs = require('ejs');
|
|
||||||
const AssetsPlugin = require('assets-webpack-plugin');
|
|
||||||
|
|
||||||
module.exports = class AssetTemplatePlugin extends AssetsPlugin {
|
|
||||||
constructor(options) {
|
|
||||||
options = options || {};
|
|
||||||
if (!options.template) throw Error('AssetTemplatePlugin: template option is required.');
|
|
||||||
super({
|
|
||||||
useCompilerPath: true,
|
|
||||||
filename: options.filename,
|
|
||||||
processOutput: files => this._processOutput(files)
|
|
||||||
});
|
|
||||||
this._template = path.resolve(process.cwd(), options.template);
|
|
||||||
const ignore = options.ignore || /(manifest\.json|\.DS_Store)$/;
|
|
||||||
this._ignore = typeof ignore === 'function' ? ({ test: ignore }) : ignore;
|
|
||||||
}
|
|
||||||
|
|
||||||
_processOutput(files) {
|
|
||||||
const mapping = {
|
|
||||||
all: [],
|
|
||||||
byType: {},
|
|
||||||
entries: {}
|
|
||||||
};
|
|
||||||
for (const entryName in files) {
|
|
||||||
// non-entry-point-derived assets are collected under an empty string key
|
|
||||||
// since that's a bit awkward, we'll call them "assets"
|
|
||||||
const name = entryName === '' ? 'assets' : entryName;
|
|
||||||
const listing = files[entryName];
|
|
||||||
const entry = mapping.entries[name] = {
|
|
||||||
all: [],
|
|
||||||
byType: {}
|
|
||||||
};
|
|
||||||
for (let type in listing) {
|
|
||||||
const list = [].concat(listing[type]).filter(file => !this._ignore.test(file));
|
|
||||||
if (!list.length) continue;
|
|
||||||
mapping.all = mapping.all.concat(list);
|
|
||||||
mapping.byType[type] = (mapping.byType[type] || []).concat(list);
|
|
||||||
entry.all = entry.all.concat(list);
|
|
||||||
entry.byType[type] = (entry.byType[type] || []).concat(list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mapping.files = mapping.all;
|
|
||||||
return ejs.render(fs.readFileSync(this._template, 'utf8'), mapping);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
let loaderUtils = require('loader-utils');
|
|
||||||
let componentPath = require.resolve('./async-component');
|
|
||||||
|
|
||||||
module.exports = function () { };
|
|
||||||
module.exports.pitch = function (remainingRequest) {
|
|
||||||
this.cacheable && this.cacheable();
|
|
||||||
let query = loaderUtils.getOptions(this) || {};
|
|
||||||
let routeName = typeof query.name === 'function' ? query.name(this.resourcePath) : null;
|
|
||||||
let name;
|
|
||||||
if (routeName !== null) {
|
|
||||||
name = routeName;
|
|
||||||
}
|
|
||||||
else if ('name' in query) {
|
|
||||||
name = query.name;
|
|
||||||
}
|
|
||||||
else if ('formatName' in query) {
|
|
||||||
name = query.formatName(this.resourcePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return `
|
|
||||||
import async from ${JSON.stringify(componentPath)};
|
|
||||||
function load(cb) {
|
|
||||||
require.ensure([], function (require) {
|
|
||||||
cb( require(${loaderUtils.stringifyRequest(this, '!!' + remainingRequest)}) );
|
|
||||||
}${name ? (', ' + JSON.stringify(name)) : ''});
|
|
||||||
}
|
|
||||||
export default async(load);
|
|
||||||
`;
|
|
||||||
};
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import { h, Component } from 'preact';
|
|
||||||
|
|
||||||
export default function (req) {
|
|
||||||
function Async() {
|
|
||||||
Component.call(this);
|
|
||||||
|
|
||||||
let b, old;
|
|
||||||
this.componentWillMount = () => {
|
|
||||||
b = this.base = this.nextBase || this.__b; // short circuits 1st render
|
|
||||||
req(m => {
|
|
||||||
this.setState({ child: m.default || m });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.shouldComponentUpdate = (_, nxt) => {
|
|
||||||
nxt = nxt.child === void 0;
|
|
||||||
if (nxt && old === void 0 && !!b) {
|
|
||||||
old = h(b.nodeName, { dangerouslySetInnerHTML: { __html: b.innerHTML } });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
old = ''; // dump it
|
|
||||||
}
|
|
||||||
return !nxt;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.render = (p, s) => s.child ? h(s.child, p) : old;
|
|
||||||
}
|
|
||||||
(Async.prototype = new Component()).constructor = Async;
|
|
||||||
return Async;
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user