mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-12 16:57:26 +00:00
Compare commits
28 Commits
rollup-bui
...
webpack-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc2f2e48c9 | ||
|
|
e691860999 | ||
|
|
fd87ae7d2a | ||
|
|
5df7dd7590 | ||
|
|
013946b137 | ||
|
|
81c183b0d6 | ||
|
|
f523db6403 | ||
|
|
cc6ea9e11c | ||
|
|
bd4b67037b | ||
|
|
8c5c97e106 | ||
|
|
a9d3bd71b5 | ||
|
|
0d0a9b4cdf | ||
|
|
f583770696 | ||
|
|
bae243ccdb | ||
|
|
02c113a68f | ||
|
|
600eead007 | ||
|
|
05416768d5 | ||
|
|
35d31f2324 | ||
|
|
82fadac70e | ||
|
|
47f9d22dd8 | ||
|
|
9420dba3bc | ||
|
|
e462875807 | ||
|
|
0747d2c419 | ||
|
|
4c658b79ef | ||
|
|
685558847f | ||
|
|
63ac34a662 | ||
|
|
42f9e4aed2 | ||
|
|
e14790f0b9 |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -1,11 +1,6 @@
|
|||||||
.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
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "all"
|
|
||||||
}
|
|
||||||
23
_headers.ejs
Normal file
23
_headers.ejs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
# COOP+COEP for WebAssembly threads.
|
||||||
|
/*
|
||||||
|
Cross-Origin-Embedder-Policy: require-corp
|
||||||
|
Cross-Origin-Opener-Policy: same-origin
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"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/**/*"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
5
codecs/avif/dec/avif_dec.d.ts
vendored
5
codecs/avif/dec/avif_dec.d.ts
vendored
@@ -1,7 +1,6 @@
|
|||||||
export interface AVIFModule extends EmscriptenWasm.Module {
|
interface AVIFModule extends EmscriptenWasm.Module {
|
||||||
decode(data: BufferSource): ImageData | null;
|
decode(data: BufferSource): ImageData | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<AVIFModule>;
|
export default function(opts: EmscriptenWasm.ModuleOpts): Promise<AVIFModule>;
|
||||||
|
|
||||||
export default moduleFactory;
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
#include <emscripten/bind.h>
|
#include <emscripten/bind.h>
|
||||||
#include <emscripten/threading.h>
|
|
||||||
#include <emscripten/val.h>
|
#include <emscripten/val.h>
|
||||||
|
#include <emscripten/threading.h>
|
||||||
#include "avif/avif.h"
|
#include "avif/avif.h"
|
||||||
|
|
||||||
using namespace emscripten;
|
using namespace emscripten;
|
||||||
@@ -51,10 +51,13 @@ 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 (options.maxQuantizer == AVIF_QUANTIZER_LOSSLESS &&
|
if (
|
||||||
options.minQuantizer == AVIF_QUANTIZER_LOSSLESS &&
|
options.maxQuantizer == AVIF_QUANTIZER_LOSSLESS &&
|
||||||
options.minQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS &&
|
options.minQuantizer == AVIF_QUANTIZER_LOSSLESS &&
|
||||||
options.maxQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS && format == AVIF_PIXEL_FORMAT_YUV444) {
|
options.minQuantizerAlpha == AVIF_QUANTIZER_LOSSLESS &&
|
||||||
|
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;
|
||||||
|
|||||||
26
codecs/avif/enc/avif_enc.d.ts
vendored
26
codecs/avif/enc/avif_enc.d.ts
vendored
@@ -1,23 +1,7 @@
|
|||||||
export interface EncodeOptions {
|
import { EncodeOptions } from '../../../src/codecs/avif/encoder-meta';
|
||||||
minQuantizer: number;
|
|
||||||
maxQuantizer: number;
|
interface AVIFModule extends EmscriptenWasm.Module {
|
||||||
minQuantizerAlpha: number;
|
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array | null;
|
||||||
maxQuantizerAlpha: number;
|
|
||||||
tileRowsLog2: number;
|
|
||||||
tileColsLog2: number;
|
|
||||||
speed: number;
|
|
||||||
subsample: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AVIFModule extends EmscriptenWasm.Module {
|
export default function(opts: EmscriptenWasm.ModuleOpts): Promise<AVIFModule>;
|
||||||
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
2
codecs/avif/enc/avif_enc_mt.d.ts
vendored
@@ -1,2 +0,0 @@
|
|||||||
export * from './avif_enc';
|
|
||||||
export { default } from './avif_enc';
|
|
||||||
File diff suppressed because it is too large
Load Diff
BIN
codecs/avif/enc/avif_enc_mt.wasm
Executable file → Normal file
BIN
codecs/avif/enc/avif_enc_mt.wasm
Executable file → Normal file
Binary file not shown.
@@ -1,103 +1 @@
|
|||||||
var threadInfoStruct = 0;
|
var threadInfoStruct=0;var selfThreadId=0;var parentThreadId=0;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["DYNAMIC_BASE"]=e.data.DYNAMIC_BASE;Module["DYNAMICTOP_PTR"]=e.data.DYNAMICTOP_PTR;Module["wasmModule"]=e.data.wasmModule;Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob==="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}avif_enc_mt(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);/*EM_THREAD_STATUS_RUNNING*/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.stack)err(ex.stack);throw ex}};if(typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string"){self={location:{href:__filename}};var onmessage=this.onmessage;var nodeWorkerThreads=require("worker_threads");global.Worker=nodeWorkerThreads.Worker;var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",function(data){onmessage({data:data})});var nodeFS=require("fs");var nodeRead=function(filename){return nodeFS.readFileSync(filename,"utf8")};function globalEval(x){global.require=require;global.Module=Module;eval.call(null,x)}importScripts=function(f){globalEval(nodeRead(f))};postMessage=function(msg){parentPort.postMessage(msg)};if(typeof performance==="undefined"){performance={now:function(){return Date.now()}}}}
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -32,10 +32,7 @@ $(OUT_JS): $(OUT_CPP) $(LIBAOM_OUT) $(CODEC_OUT)
|
|||||||
--closure 1 \
|
--closure 1 \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
-s MODULARIZE=1 \
|
-s MODULARIZE=1 \
|
||||||
-s TEXTDECODER=2 \
|
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
||||||
-s ENVIRONMENT='worker' \
|
|
||||||
-s EXPORT_ES6=1 \
|
|
||||||
-s EXPORT_NAME="$(basename $(@F))" \
|
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$+
|
$+
|
||||||
|
|
||||||
|
|||||||
4
codecs/build-rust-nightly.sh
Normal file
4
codecs/build-rust-nightly.sh
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
set -e
|
||||||
|
|
||||||
|
docker build -t squoosh-rust-nightly --build-arg RUST_IMG=rustlang/rust@sha256:744aeea5a38f95aa7a96ec37269a65f0c6197a1cdd87d6534e12bb869141d807 - < ../rust.Dockerfile
|
||||||
|
docker run --rm -v $PWD:/src squoosh-rust-nightly "$@"
|
||||||
@@ -1,10 +1,4 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ ! -z "$RUST_IMG" ]
|
docker build -t squoosh-rust - < ../rust.Dockerfile
|
||||||
then
|
docker run --rm -v $PWD:/src squoosh-rust "$@"
|
||||||
# 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,4 +1,4 @@
|
|||||||
FROM emscripten/emsdk:2.0.8
|
FROM emscripten/emsdk:1.40.0
|
||||||
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 "-O3 -flto"
|
ENV CFLAGS "-O3 -flto"
|
||||||
ENV CXXFLAGS "${CFLAGS} -std=c++17"
|
ENV CXXFLAGS "${CFLAGS} -std=c++17"
|
||||||
|
|||||||
11
codecs/hqx/Dockerfile
Normal file
11
codecs/hqx/Dockerfile
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# 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
|
||||||
21
codecs/hqx/build.sh
Executable file
21
codecs/hqx/build.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/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,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "hqx",
|
"name": "hqx",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "RUST_IMG=rust:1.40 ../build-rust.sh"
|
"build:image": "docker build -t squoosh-hqx - < Dockerfile",
|
||||||
|
"build": "docker run --rm -v $(pwd):/src squoosh-hqx ./build.sh"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
# 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,48 +1,10 @@
|
|||||||
/* 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(
|
export function resize(input_image: Uint32Array, input_width: number, input_height: number, factor: number): Uint32Array;
|
||||||
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,107 +1,2 @@
|
|||||||
let wasm;
|
import * as wasm from "./squooshhqx_bg.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;
|
|
||||||
48
codecs/hqx/pkg/squooshhqx_bg.js
Normal file
48
codecs/hqx/pkg/squooshhqx_bg.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
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,9 +18,7 @@ all: $(OUT_JS)
|
|||||||
--closure 1 \
|
--closure 1 \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
-s MODULARIZE=1 \
|
-s MODULARIZE=1 \
|
||||||
-s TEXTDECODER=2 \
|
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
||||||
-s ENVIRONMENT='worker' \
|
|
||||||
-s EXPORT_ES6=1 \
|
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$+
|
$+
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<style>
|
<style>
|
||||||
canvas {
|
canvas {
|
||||||
image-rendering: pixelated;
|
image-rendering: pixelated;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script type="module">
|
<script src='imagequant.js'></script>
|
||||||
import imagequant from './imagequant.js';
|
<script>
|
||||||
|
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];
|
||||||
@@ -21,32 +22,19 @@
|
|||||||
return ctx.getImageData(0, 0, img.width, img.height);
|
return ctx.getImageData(0, 0, img.width, img.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
Module.onRuntimeInitialized = async _ => {
|
||||||
const module = await imagequant();
|
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 rawImage = module.quantize(
|
// const rawImage = Module.quantize(image.data, image.width, image.height, 256, 1.0);
|
||||||
image.data,
|
const rawImage = Module.zx_quantize(image.data, image.width, image.height, 1.0);
|
||||||
image.width,
|
|
||||||
image.height,
|
|
||||||
256,
|
|
||||||
1.0,
|
|
||||||
);
|
|
||||||
console.log('done');
|
console.log('done');
|
||||||
|
|
||||||
const imageData = new ImageData(
|
const imageData = new ImageData(new Uint8ClampedArray(rawImage.buffer), image.width, image.height);
|
||||||
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,19 +1,6 @@
|
|||||||
export interface QuantizerModule extends EmscriptenWasm.Module {
|
interface QuantizerModule extends EmscriptenWasm.Module {
|
||||||
quantize(
|
quantize(data: BufferSource, width: number, height: number, numColors: number, dither: number): Uint8ClampedArray;
|
||||||
data: BufferSource,
|
zx_quantize(data: BufferSource, width: number, height: number, dither: number): Uint8ClampedArray;
|
||||||
width: number,
|
|
||||||
height: number,
|
|
||||||
numColors: number,
|
|
||||||
dither: number,
|
|
||||||
): Uint8ClampedArray;
|
|
||||||
zx_quantize(
|
|
||||||
data: BufferSource,
|
|
||||||
width: number,
|
|
||||||
height: number,
|
|
||||||
dither: number,
|
|
||||||
): Uint8ClampedArray;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<QuantizerModule>;
|
export default function(opts: EmscriptenWasm.ModuleOpts): Promise<QuantizerModule>;
|
||||||
|
|
||||||
export default moduleFactory;
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
BIN
codecs/imagequant/imagequant.wasm
Executable file → Normal file
BIN
codecs/imagequant/imagequant.wasm
Executable file → Normal file
Binary file not shown.
@@ -1,59 +0,0 @@
|
|||||||
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
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
#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
7
codecs/jxl/dec/jxl_dec.d.ts
vendored
@@ -1,7 +0,0 @@
|
|||||||
export interface JXLModule extends EmscriptenWasm.Module {
|
|
||||||
decode(data: BufferSource): ImageData | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<JXLModule>;
|
|
||||||
|
|
||||||
export default moduleFactory;
|
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,115 +0,0 @@
|
|||||||
#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
21
codecs/jxl/enc/jxl_enc.d.ts
vendored
@@ -1,21 +0,0 @@
|
|||||||
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;
|
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "jxl",
|
|
||||||
"scripts": {
|
|
||||||
"build": "../build-cpp.sh"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -14,13 +14,11 @@ all: $(OUT_JS)
|
|||||||
-I $(CODEC_DIR) \
|
-I $(CODEC_DIR) \
|
||||||
${CXXFLAGS} \
|
${CXXFLAGS} \
|
||||||
${LDFLAGS} \
|
${LDFLAGS} \
|
||||||
--closure 1 \
|
|
||||||
--bind \
|
--bind \
|
||||||
|
--closure 1 \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
-s MODULARIZE=1 \
|
-s MODULARIZE=1 \
|
||||||
-s TEXTDECODER=2 \
|
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
||||||
-s ENVIRONMENT='worker' \
|
|
||||||
-s EXPORT_ES6=1 \
|
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$+
|
$+
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<script type="module">
|
<script src='mozjpeg_enc.js'></script>
|
||||||
import mozjpeg_enc from './mozjpeg_enc.js';
|
<script>
|
||||||
|
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];
|
||||||
@@ -16,9 +17,7 @@
|
|||||||
return ctx.getImageData(0, 0, img.width, img.height);
|
return ctx.getImageData(0, 0, img.width, img.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
module.onRuntimeInitialized = async _ => {
|
||||||
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, {
|
||||||
@@ -40,12 +39,10 @@
|
|||||||
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,37 +1,7 @@
|
|||||||
export const enum MozJpegColorSpace {
|
import { EncodeOptions } from '../../src/codecs/mozjpeg/encoder-meta';
|
||||||
GRAYSCALE = 1,
|
|
||||||
RGB,
|
interface MozJPEGModule extends EmscriptenWasm.Module {
|
||||||
YCbCr,
|
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EncodeOptions {
|
export default function(opts: EmscriptenWasm.ModuleOpts): Promise<MozJPEGModule>;
|
||||||
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
Executable file → Normal file
BIN
codecs/mozjpeg_enc/mozjpeg_enc.wasm
Executable file → Normal file
Binary file not shown.
173
codecs/oxipng/Cargo.lock
generated
173
codecs/oxipng/Cargo.lock
generated
@@ -56,9 +56,9 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.62"
|
version = "1.0.60"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1770ced377336a88a67c473594ccc14eca6f4559217c34f64aac8f83d641b40"
|
checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@@ -66,12 +66,6 @@ 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"
|
||||||
@@ -90,18 +84,6 @@ 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"
|
||||||
@@ -113,57 +95,57 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.2.1"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
|
checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-channel"
|
name = "crossbeam-channel"
|
||||||
version = "0.5.0"
|
version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
|
checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
|
"maybe-uninit",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-deque"
|
name = "crossbeam-deque"
|
||||||
version = "0.8.0"
|
version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
|
checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
|
||||||
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.9.0"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f"
|
checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"autocfg",
|
||||||
"const_fn",
|
"cfg-if",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"maybe-uninit",
|
||||||
"memoffset",
|
"memoffset",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.0"
|
version = "0.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5"
|
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"cfg-if 1.0.0",
|
"cfg-if",
|
||||||
"const_fn",
|
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -185,28 +167,27 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.9.1"
|
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 = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
checksum = "00d63df3d41950fb462ed38308eea019113ad1508da725bbedcd0fa5a85ef5f7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.17"
|
version = "0.1.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
|
checksum = "4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "image"
|
name = "image"
|
||||||
version = "0.23.11"
|
version = "0.23.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4f0a8345b33b082aedec2f4d7d4a926b845cee184cbe78b703413066564431b"
|
checksum = "974e194911d1f7efe3cd8a8f9db3b767e43536327e899e8bc9a12ef5711b74d2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"color_quant",
|
|
||||||
"num-iter",
|
"num-iter",
|
||||||
"num-rational",
|
"num-rational",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
@@ -241,9 +222,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.80"
|
version = "0.2.77"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
|
checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libdeflate-sys"
|
name = "libdeflate-sys"
|
||||||
@@ -269,9 +250,15 @@ 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 = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "maybe-uninit"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memoffset"
|
name = "memoffset"
|
||||||
version = "0.5.6"
|
version = "0.5.6"
|
||||||
@@ -292,9 +279,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.4.3"
|
version = "0.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
|
checksum = "c60c0dfe32c10b43a144bad8fc83538c52f58302c92300ea7ec7bf7b38d5a7b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler",
|
"adler",
|
||||||
"autocfg",
|
"autocfg",
|
||||||
@@ -302,9 +289,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-integer"
|
name = "num-integer"
|
||||||
version = "0.1.44"
|
version = "0.1.43"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
@@ -312,9 +299,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-iter"
|
name = "num-iter"
|
||||||
version = "0.1.42"
|
version = "0.1.41"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
|
checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
@@ -323,9 +310,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-rational"
|
name = "num-rational"
|
||||||
version = "0.3.2"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
|
checksum = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
@@ -334,9 +321,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.14"
|
version = "0.2.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
@@ -353,15 +340,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.5.2"
|
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 = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
|
checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxipng"
|
name = "oxipng"
|
||||||
version = "4.0.0"
|
version = "3.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/RReverser/oxipng?branch=crossbeam#0df4a32921f7b88d2be4649deb1b6fb7e5707ad8"
|
||||||
checksum = "ea40b366cecfce76ee3b082e7e6567b82cdef75644a22442ca8584bc666ff4eb"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit-vec",
|
"bit-vec",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
@@ -373,19 +359,11 @@ dependencies = [
|
|||||||
"itertools",
|
"itertools",
|
||||||
"libdeflater",
|
"libdeflater",
|
||||||
"log",
|
"log",
|
||||||
"miniz_oxide 0.4.3",
|
"miniz_oxide 0.4.2",
|
||||||
"rayon",
|
"rayon",
|
||||||
"rgb",
|
"rgb",
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
]
|
"zopfli",
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pest"
|
|
||||||
version = "2.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
|
||||||
dependencies = [
|
|
||||||
"ucd-trie",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -402,9 +380,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.24"
|
version = "1.0.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
@@ -420,9 +398,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon"
|
name = "rayon"
|
||||||
version = "1.5.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 = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
|
checksum = "dcf6960dc9a5b4ee8d3e4c5787b4a112a8818e0290a42ff664ad60692fdf2032"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"crossbeam-deque",
|
"crossbeam-deque",
|
||||||
@@ -432,9 +410,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon-core"
|
name = "rayon-core"
|
||||||
version = "1.9.0"
|
version = "1.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
|
checksum = "e8c4fec834fb6e6d2dd5eece3c7b432a52f0ba887cf40e595190c4107edc08bf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"crossbeam-deque",
|
"crossbeam-deque",
|
||||||
@@ -454,9 +432,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.3.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 = "65c94201b44764d6d1f7e37c15a8289ed55e546c1762c7f1d57f616966e0c181"
|
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"semver",
|
"semver",
|
||||||
]
|
]
|
||||||
@@ -469,21 +447,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "0.11.0"
|
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 = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
|
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"semver-parser",
|
"semver-parser",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver-parser"
|
name = "semver-parser"
|
||||||
version = "0.10.1"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42ef146c2ad5e5f4b037cd6ce2ebb775401729b19a82040c1beac9d36c7d1428"
|
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
dependencies = [
|
|
||||||
"pest",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "squoosh-oxipng"
|
name = "squoosh-oxipng"
|
||||||
@@ -499,9 +474,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.48"
|
version = "1.0.41"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac"
|
checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -509,10 +484,10 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ucd-trie"
|
name = "typed-arena"
|
||||||
version = "0.1.3"
|
version = "1.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
@@ -526,7 +501,7 @@ 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 = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42"
|
checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10",
|
"cfg-if",
|
||||||
"wasm-bindgen-macro",
|
"wasm-bindgen-macro",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -573,3 +548,15 @@ name = "wasm-bindgen-shared"
|
|||||||
version = "0.2.68"
|
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 = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
|
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,19 +5,20 @@ 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 = "4.0.0", default-features = false, features = ["libdeflater"] }
|
oxipng = { version = "3.0.0", default-features = false }
|
||||||
wasm-bindgen = "0.2.68"
|
wasm-bindgen = "0.2.64"
|
||||||
log = { version = "0.4.11", features = ["release_max_level_off"] }
|
log = { version = "0.4", features = ["release_max_level_off"] }
|
||||||
rayon = { version = "1.5.0", optional = true }
|
rayon = { version = "1.3.0", optional = true }
|
||||||
once_cell = { version = "1.5.2", optional = true }
|
once_cell = { version = "1.3.1", optional = true }
|
||||||
crossbeam-channel = { version = "0.5.0", optional = true }
|
crossbeam-channel = { version = "0.4.2", optional = true }
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
# TODO: replace with upstream version once https://github.com/shssoichiro/oxipng/pull/327 is merged.
|
||||||
|
oxipng = { git = "https://github.com/RReverser/oxipng", branch = "crossbeam" }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
@@ -25,3 +26,6 @@ opt-level = "s"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
parallel = ["oxipng/parallel", "rayon", "crossbeam-channel", "once_cell"]
|
parallel = ["oxipng/parallel", "rayon", "crossbeam-channel", "once_cell"]
|
||||||
|
|
||||||
|
[package.metadata.wasm-pack.profile.release]
|
||||||
|
wasm-opt = ["-O", "--no-validation"]
|
||||||
|
|||||||
3
codecs/oxipng/build.sh
Executable file → Normal file
3
codecs/oxipng/build.sh
Executable file → Normal file
@@ -3,6 +3,7 @@
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
rm -rf pkg,{-parallel}
|
rm -rf pkg,{-parallel}
|
||||||
wasm-pack build --target web
|
wasm-pack build
|
||||||
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory' wasm-pack build -t web -d pkg-parallel -- -Z build-std=panic_abort,std --features=parallel
|
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory' wasm-pack build -t web -d pkg-parallel -- -Z build-std=panic_abort,std --features=parallel
|
||||||
|
sed -i "s|input = import.meta.url.replace(/\\\.js$/, '_bg.wasm');||" pkg{,-parallel}/squoosh_oxipng.js
|
||||||
rm pkg{,-parallel}/.gitignore
|
rm pkg{,-parallel}/.gitignore
|
||||||
|
|||||||
10
codecs/oxipng/index.ts
Normal file
10
codecs/oxipng/index.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { threads } from 'wasm-feature-detect';
|
||||||
|
|
||||||
|
async function init() {
|
||||||
|
if (await threads()) {
|
||||||
|
return (await import('./spawn')).default;
|
||||||
|
}
|
||||||
|
return import('./pkg');
|
||||||
|
}
|
||||||
|
|
||||||
|
export default init();
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "oxipng",
|
"name": "oxipng",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "RUST_IMG=rustlang/rust:8bb115b1090d ../build-rust.sh ./build.sh"
|
"build": "../build-rust-nightly.sh ./build.sh"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,4 +12,4 @@
|
|||||||
"module": "squoosh_oxipng.js",
|
"module": "squoosh_oxipng.js",
|
||||||
"types": "squoosh_oxipng.d.ts",
|
"types": "squoosh_oxipng.d.ts",
|
||||||
"sideEffects": false
|
"sideEffects": false
|
||||||
}
|
}
|
||||||
53
codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts
vendored
53
codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts
vendored
@@ -1,37 +1,32 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
* @param {Uint8Array} data
|
* @param {number} num
|
||||||
* @param {number} level
|
* @returns {any}
|
||||||
* @returns {Uint8Array}
|
*/
|
||||||
*/
|
|
||||||
export function optimise(data: Uint8Array, level: number): Uint8Array;
|
|
||||||
/**
|
|
||||||
* @param {number} num
|
|
||||||
* @returns {any}
|
|
||||||
*/
|
|
||||||
export function worker_initializer(num: number): any;
|
export function worker_initializer(num: number): any;
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function start_main_thread(): void;
|
export function start_main_thread(): void;
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function start_worker_thread(): void;
|
export function start_worker_thread(): void;
|
||||||
|
/**
|
||||||
|
* @param {Uint8Array} data
|
||||||
|
* @param {number} level
|
||||||
|
* @returns {Uint8Array}
|
||||||
|
*/
|
||||||
|
export function optimise(data: Uint8Array, level: number): Uint8Array;
|
||||||
|
|
||||||
export type InitInput =
|
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||||
| RequestInfo
|
|
||||||
| URL
|
|
||||||
| Response
|
|
||||||
| BufferSource
|
|
||||||
| WebAssembly.Module;
|
|
||||||
|
|
||||||
export interface InitOutput {
|
export interface InitOutput {
|
||||||
readonly optimise: (a: number, b: number, c: number, d: number) => void;
|
|
||||||
readonly malloc: (a: number) => number;
|
readonly malloc: (a: number) => number;
|
||||||
readonly free: (a: number) => void;
|
readonly free: (a: number) => void;
|
||||||
readonly worker_initializer: (a: number) => number;
|
readonly worker_initializer: (a: number) => number;
|
||||||
readonly start_main_thread: () => void;
|
readonly start_main_thread: () => void;
|
||||||
readonly start_worker_thread: () => void;
|
readonly start_worker_thread: () => void;
|
||||||
|
readonly optimise: (a: number, b: number, c: number, d: number) => void;
|
||||||
readonly __wbindgen_export_0: WebAssembly.Memory;
|
readonly __wbindgen_export_0: WebAssembly.Memory;
|
||||||
readonly __wbindgen_malloc: (a: number) => number;
|
readonly __wbindgen_malloc: (a: number) => number;
|
||||||
readonly __wbindgen_free: (a: number, b: number) => void;
|
readonly __wbindgen_free: (a: number, b: number) => void;
|
||||||
@@ -39,15 +34,13 @@ export interface InitOutput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
||||||
* for everything else, calls `WebAssembly.instantiate` directly.
|
* for everything else, calls `WebAssembly.instantiate` directly.
|
||||||
*
|
*
|
||||||
* @param {InitInput | Promise<InitInput>} module_or_path
|
* @param {InitInput | Promise<InitInput>} module_or_path
|
||||||
* @param {WebAssembly.Memory} maybe_memory
|
* @param {WebAssembly.Memory} maybe_memory
|
||||||
*
|
*
|
||||||
* @returns {Promise<InitOutput>}
|
* @returns {Promise<InitOutput>}
|
||||||
*/
|
*/
|
||||||
export default function init(
|
export default function init (module_or_path?: InitInput | Promise<InitInput>, maybe_memory: WebAssembly.Memory): Promise<InitOutput>;
|
||||||
module_or_path?: InitInput | Promise<InitInput>,
|
|
||||||
maybe_memory?: WebAssembly.Memory,
|
|
||||||
): Promise<InitOutput>;
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
let wasm;
|
let wasm;
|
||||||
let memory;
|
let memory;
|
||||||
|
|
||||||
@@ -8,189 +9,172 @@ heap.push(undefined, null, true, false);
|
|||||||
let heap_next = heap.length;
|
let heap_next = heap.length;
|
||||||
|
|
||||||
function addHeapObject(obj) {
|
function addHeapObject(obj) {
|
||||||
if (heap_next === heap.length) heap.push(heap.length + 1);
|
if (heap_next === heap.length) heap.push(heap.length + 1);
|
||||||
const idx = heap_next;
|
const idx = heap_next;
|
||||||
heap_next = heap[idx];
|
heap_next = heap[idx];
|
||||||
|
|
||||||
heap[idx] = obj;
|
heap[idx] = obj;
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cachedTextDecoder = new TextDecoder('utf-8', {
|
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
||||||
ignoreBOM: true,
|
|
||||||
fatal: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
cachedTextDecoder.decode();
|
cachedTextDecoder.decode();
|
||||||
|
|
||||||
let cachegetUint8Memory0 = null;
|
let cachegetUint8Memory0 = null;
|
||||||
function getUint8Memory0() {
|
function getUint8Memory0() {
|
||||||
if (
|
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.__wbindgen_export_0.buffer) {
|
||||||
cachegetUint8Memory0 === null ||
|
cachegetUint8Memory0 = new Uint8Array(wasm.__wbindgen_export_0.buffer);
|
||||||
cachegetUint8Memory0.buffer !== wasm.__wbindgen_export_0.buffer
|
}
|
||||||
) {
|
return cachegetUint8Memory0;
|
||||||
cachegetUint8Memory0 = new Uint8Array(wasm.__wbindgen_export_0.buffer);
|
|
||||||
}
|
|
||||||
return cachegetUint8Memory0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStringFromWasm0(ptr, len) {
|
function getStringFromWasm0(ptr, len) {
|
||||||
return cachedTextDecoder.decode(getUint8Memory0().slice(ptr, ptr + len));
|
return cachedTextDecoder.decode(getUint8Memory0().slice(ptr, ptr + len));
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
let WASM_VECTOR_LEN = 0;
|
let WASM_VECTOR_LEN = 0;
|
||||||
|
|
||||||
function passArray8ToWasm0(arg, malloc) {
|
function passArray8ToWasm0(arg, malloc) {
|
||||||
const ptr = malloc(arg.length * 1);
|
const ptr = malloc(arg.length * 1);
|
||||||
getUint8Memory0().set(arg, ptr / 1);
|
getUint8Memory0().set(arg, ptr / 1);
|
||||||
WASM_VECTOR_LEN = arg.length;
|
WASM_VECTOR_LEN = arg.length;
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cachegetInt32Memory0 = null;
|
let cachegetInt32Memory0 = null;
|
||||||
function getInt32Memory0() {
|
function getInt32Memory0() {
|
||||||
if (
|
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.__wbindgen_export_0.buffer) {
|
||||||
cachegetInt32Memory0 === null ||
|
cachegetInt32Memory0 = new Int32Array(wasm.__wbindgen_export_0.buffer);
|
||||||
cachegetInt32Memory0.buffer !== wasm.__wbindgen_export_0.buffer
|
}
|
||||||
) {
|
return cachegetInt32Memory0;
|
||||||
cachegetInt32Memory0 = new Int32Array(wasm.__wbindgen_export_0.buffer);
|
|
||||||
}
|
|
||||||
return cachegetInt32Memory0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getArrayU8FromWasm0(ptr, len) {
|
function getArrayU8FromWasm0(ptr, len) {
|
||||||
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @param {Uint8Array} data
|
* @param {Uint8Array} data
|
||||||
* @param {number} level
|
* @param {number} level
|
||||||
* @returns {Uint8Array}
|
* @returns {Uint8Array}
|
||||||
*/
|
*/
|
||||||
export function optimise(data, level) {
|
export function optimise(data, level) {
|
||||||
try {
|
try {
|
||||||
const retptr = wasm.__wbindgen_export_1.value - 16;
|
const retptr = wasm.__wbindgen_export_1.value - 16;
|
||||||
wasm.__wbindgen_export_1.value = retptr;
|
wasm.__wbindgen_export_1.value = retptr;
|
||||||
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
||||||
var len0 = WASM_VECTOR_LEN;
|
var len0 = WASM_VECTOR_LEN;
|
||||||
wasm.optimise(retptr, ptr0, len0, level);
|
wasm.optimise(retptr, ptr0, len0, level);
|
||||||
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
var r0 = getInt32Memory0()[retptr / 4 + 0];
|
||||||
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
var r1 = getInt32Memory0()[retptr / 4 + 1];
|
||||||
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
var v1 = getArrayU8FromWasm0(r0, r1).slice();
|
||||||
wasm.__wbindgen_free(r0, r1 * 1);
|
wasm.__wbindgen_free(r0, r1 * 1);
|
||||||
return v1;
|
return v1;
|
||||||
} finally {
|
} finally {
|
||||||
wasm.__wbindgen_export_1.value += 16;
|
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) {
|
async function load(module, imports, maybe_memory) {
|
||||||
if (typeof Response === 'function' && module instanceof Response) {
|
if (typeof Response === 'function' && module instanceof Response) {
|
||||||
memory = imports.wbg.memory = new WebAssembly.Memory({
|
memory = imports.wbg.memory = new WebAssembly.Memory({initial:17,maximum:16384,shared:true});
|
||||||
initial: 17,
|
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||||
maximum: 16384,
|
try {
|
||||||
shared: true,
|
return await WebAssembly.instantiateStreaming(module, imports);
|
||||||
});
|
|
||||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
} catch (e) {
|
||||||
try {
|
if (module.headers.get('Content-Type') != 'application/wasm') {
|
||||||
return await WebAssembly.instantiateStreaming(module, imports);
|
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);
|
||||||
} catch (e) {
|
|
||||||
if (module.headers.get('Content-Type') != 'application/wasm') {
|
} else {
|
||||||
console.warn(
|
throw e;
|
||||||
'`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();
|
const bytes = await module.arrayBuffer();
|
||||||
return await WebAssembly.instantiate(bytes, imports);
|
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 {
|
} else {
|
||||||
return instance;
|
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) {
|
async function init(input, maybe_memory) {
|
||||||
if (typeof input === 'undefined') {
|
if (typeof input === 'undefined') {
|
||||||
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
|
|
||||||
}
|
}
|
||||||
const imports = {};
|
const imports = {};
|
||||||
imports.wbg = {};
|
imports.wbg = {};
|
||||||
imports.wbg.__wbindgen_module = function () {
|
imports.wbg.__wbindgen_module = function() {
|
||||||
var ret = init.__wbindgen_wasm_module;
|
var ret = init.__wbindgen_wasm_module;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_memory = function () {
|
imports.wbg.__wbindgen_memory = function() {
|
||||||
var ret = wasm.__wbindgen_export_0;
|
var ret = wasm.__wbindgen_export_0;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_of_6510501edc06d65e = function (arg0, arg1) {
|
imports.wbg.__wbg_of_6510501edc06d65e = function(arg0, arg1) {
|
||||||
var ret = Array.of(takeObject(arg0), takeObject(arg1));
|
var ret = Array.of(takeObject(arg0), takeObject(arg1));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_throw = function (arg0, arg1) {
|
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
||||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||||
};
|
};
|
||||||
|
|
||||||
if (
|
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
|
||||||
typeof input === 'string' ||
|
input = fetch(input);
|
||||||
(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);
|
const { instance, module } = await load(await input, imports, maybe_memory);
|
||||||
|
|
||||||
wasm = instance.exports;
|
wasm = instance.exports;
|
||||||
init.__wbindgen_wasm_module = module;
|
init.__wbindgen_wasm_module = module;
|
||||||
wasm.__wbindgen_start();
|
wasm.__wbindgen_start();
|
||||||
return wasm;
|
return wasm;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default init;
|
export default init;
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,11 +1,11 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
export function optimise(a: number, b: number, c: number, d: number): void;
|
|
||||||
export function malloc(a: number): number;
|
export function malloc(a: number): number;
|
||||||
export function free(a: number): void;
|
export function free(a: number): void;
|
||||||
export function worker_initializer(a: number): number;
|
export function worker_initializer(a: number): number;
|
||||||
export function start_main_thread(): void;
|
export function start_main_thread(): void;
|
||||||
export function start_worker_thread(): void;
|
export function start_worker_thread(): void;
|
||||||
|
export function optimise(a: number, b: number, c: number, d: number): void;
|
||||||
export const __wbindgen_export_0: WebAssembly.Memory;
|
export const __wbindgen_export_0: WebAssembly.Memory;
|
||||||
export function __wbindgen_malloc(a: number): number;
|
export function __wbindgen_malloc(a: number): number;
|
||||||
export function __wbindgen_free(a: number, b: number): void;
|
export function __wbindgen_free(a: number, b: number): void;
|
||||||
|
|||||||
36
codecs/oxipng/pkg/squoosh_oxipng.d.ts
vendored
36
codecs/oxipng/pkg/squoosh_oxipng.d.ts
vendored
@@ -1,36 +1,8 @@
|
|||||||
/* 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,126 +1,2 @@
|
|||||||
let wasm;
|
import * as wasm from "./squoosh_oxipng_bg.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;
|
|
||||||
66
codecs/oxipng/pkg/squoosh_oxipng_bg.js
Normal file
66
codecs/oxipng/pkg/squoosh_oxipng_bg.js
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
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) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const __wbindgen_throw = function(arg0, arg1) {
|
||||||
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||||
|
};
|
||||||
|
|
||||||
Binary file not shown.
52
codecs/oxipng/spawn.ts
Normal file
52
codecs/oxipng/spawn.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import initOxiPNG, {
|
||||||
|
worker_initializer,
|
||||||
|
start_main_thread,
|
||||||
|
optimise,
|
||||||
|
} from './pkg-parallel';
|
||||||
|
// @ts-ignore
|
||||||
|
import wasmUrl from './pkg-parallel/squoosh_oxipng_bg.wasm';
|
||||||
|
import { WorkerInit } from './worker';
|
||||||
|
|
||||||
|
function initWorker(worker: Worker, workerInit: WorkerInit) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
worker.postMessage(workerInit);
|
||||||
|
worker.addEventListener('message', () => resolve(), { once: true });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function startMainThread() {
|
||||||
|
const num = navigator.hardwareConcurrency;
|
||||||
|
|
||||||
|
// First, let browser fetch and spawn Workers for our pool in the background.
|
||||||
|
// This is fairly expensive, so we want to start it as early as possible.
|
||||||
|
const workers = Array.from({ length: num }, () => new Worker('./worker', { type: 'module' }));
|
||||||
|
|
||||||
|
// Meanwhile, asynchronously compile, instantiate and initialise Wasm on our main thread.
|
||||||
|
await initOxiPNG(fetch(wasmUrl), undefined as any);
|
||||||
|
|
||||||
|
// Get module+memory from the Wasm instance.
|
||||||
|
//
|
||||||
|
// Ideally we wouldn't go via Wasm bindings here, since both are just JS variables, but memory is
|
||||||
|
// currently not exposed on the Wasm instance correctly by wasm-bindgen.
|
||||||
|
const workerInit: WorkerInit = worker_initializer(num);
|
||||||
|
|
||||||
|
// Once done, we want to send module+memory to each Worker so that they instantiate Wasm too.
|
||||||
|
// While doing so, we need to wait for Workers to acknowledge that they have received our message.
|
||||||
|
// Ideally this shouldn't be necessary, but Chromium currently doesn't conform to the spec:
|
||||||
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=1075645
|
||||||
|
//
|
||||||
|
// If we didn't do this ping-pong game, the `start_main_thread` below would block the current
|
||||||
|
// thread on an atomic before even *sending* the `postMessage` containing memory,
|
||||||
|
// so Workers would never be able to unblock us back.
|
||||||
|
await Promise.all(workers.map(worker => initWorker(worker, workerInit)));
|
||||||
|
|
||||||
|
// Finally, instantiate rayon pool - this will use shared Wasm memory to send tasks to the
|
||||||
|
// Workers and then block until they're all ready.
|
||||||
|
start_main_thread();
|
||||||
|
|
||||||
|
return {
|
||||||
|
optimise,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default startMainThread();
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import initOxiPNG, {
|
/// <reference lib="webworker" />
|
||||||
start_worker_thread,
|
|
||||||
} from 'codecs/oxipng/pkg-parallel/squoosh_oxipng';
|
import initOxiPNG, { start_worker_thread } from './pkg-parallel';
|
||||||
|
|
||||||
export type WorkerInit = [WebAssembly.Module, WebAssembly.Memory];
|
export type WorkerInit = [WebAssembly.Module, WebAssembly.Memory];
|
||||||
|
|
||||||
@@ -15,7 +15,6 @@ addEventListener(
|
|||||||
// Note that we don't need to wait for Wasm instantiation here - it's
|
// Note that we don't need to wait for Wasm instantiation here - it's
|
||||||
// better to start main thread as early as possible, and then it blocks
|
// better to start main thread as early as possible, and then it blocks
|
||||||
// on a shared atomic anyway until Worker is fully ready.
|
// on a shared atomic anyway until Worker is fully ready.
|
||||||
// @ts-ignore
|
|
||||||
postMessage(null);
|
postMessage(null);
|
||||||
|
|
||||||
await initOxiPNG(...(event.data as WorkerInit));
|
await initOxiPNG(...(event.data as WorkerInit));
|
||||||
68
codecs/resize/pkg/squoosh_resize.d.ts
vendored
68
codecs/resize/pkg/squoosh_resize.d.ts
vendored
@@ -1,60 +1,14 @@
|
|||||||
/* 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(
|
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;
|
||||||
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,131 +1,2 @@
|
|||||||
let wasm;
|
import * as wasm from "./squoosh_resize_bg.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;
|
|
||||||
52
codecs/resize/pkg/squoosh_resize_bg.js
Normal file
52
codecs/resize/pkg/squoosh_resize_bg.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
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,13 +1,13 @@
|
|||||||
ARG RUST_IMG=rust:1.47
|
ARG RUST_IMG=rust:1.44-stretch
|
||||||
|
|
||||||
FROM emscripten/emsdk:2.0.8 AS wasm-tools
|
FROM emscripten/emsdk:1.39.19 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_IMG AS rust
|
FROM $RUST_IMG AS rust
|
||||||
ARG RUST_IMG
|
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
|
RUN rustup component add rust-src
|
||||||
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/
|
||||||
@@ -16,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 --target web -- --verbose --locked && rm pkg/.gitignore"]
|
CMD ["sh", "-c", "rm -rf pkg && wasm-pack build -- --verbose --locked && rm pkg/.gitignore"]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
CODEC_URL := https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.1.0.tar.gz
|
CODEC_URL := https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.2.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,9 +18,7 @@ all: $(OUT_JS)
|
|||||||
--closure 1 \
|
--closure 1 \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
-s MODULARIZE=1 \
|
-s MODULARIZE=1 \
|
||||||
-s TEXTDECODER=2 \
|
-s 'EXPORT_NAME="$(basename $(@F))"' \
|
||||||
-s ENVIRONMENT='worker' \
|
|
||||||
-s EXPORT_ES6=1 \
|
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$+
|
$+
|
||||||
|
|
||||||
|
|||||||
6
codecs/webp/dec/webp_dec.d.ts
vendored
6
codecs/webp/dec/webp_dec.d.ts
vendored
@@ -1,7 +1,5 @@
|
|||||||
export interface WebPModule extends EmscriptenWasm.Module {
|
interface WebPModule extends EmscriptenWasm.Module {
|
||||||
decode(data: BufferSource): ImageData | null;
|
decode(data: BufferSource): ImageData | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<WebPModule>;
|
export default function(opts: EmscriptenWasm.ModuleOpts): Promise<WebPModule>;
|
||||||
|
|
||||||
export default moduleFactory;
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
BIN
codecs/webp/dec/webp_dec.wasm
Executable file → Normal file
BIN
codecs/webp/dec/webp_dec.wasm
Executable file → Normal file
Binary file not shown.
45
codecs/webp/enc/webp_enc.d.ts
vendored
45
codecs/webp/enc/webp_enc.d.ts
vendored
@@ -1,42 +1,7 @@
|
|||||||
export interface EncodeOptions {
|
import { EncodeOptions } from '../../../src/codecs/webp/encoder-meta';
|
||||||
quality: number;
|
|
||||||
target_size: number;
|
interface WebPModule extends EmscriptenWasm.Module {
|
||||||
target_PSNR: number;
|
encode(data: BufferSource, width: number, height: number, options: EncodeOptions): Uint8Array | null;
|
||||||
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 interface WebPModule extends EmscriptenWasm.Module {
|
export default function(opts: EmscriptenWasm.ModuleOpts): Promise<WebPModule>;
|
||||||
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
Executable file → Normal file
BIN
codecs/webp/enc/webp_enc.wasm
Executable file → Normal file
Binary file not shown.
@@ -1,50 +0,0 @@
|
|||||||
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
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
# 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`.
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#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
7
codecs/wp2/dec/wp2_dec.d.ts
vendored
@@ -1,7 +0,0 @@
|
|||||||
export interface WP2Module extends EmscriptenWasm.Module {
|
|
||||||
decode(data: BufferSource): ImageData | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<WP2Module>;
|
|
||||||
|
|
||||||
export default moduleFactory;
|
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,17 +0,0 @@
|
|||||||
# 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.
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#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
20
codecs/wp2/enc/wp2_enc.d.ts
vendored
@@ -1,20 +0,0 @@
|
|||||||
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;
|
|
||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "wp2",
|
|
||||||
"scripts": {
|
|
||||||
"build": "../build-cpp.sh"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
76
config/add-css-types.js
Normal file
76
config/add-css-types.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
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;
|
||||||
47
config/asset-template-plugin.js
Normal file
47
config/asset-template-plugin.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
29
config/async-component-loader.js
Normal file
29
config/async-component-loader.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
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);
|
||||||
|
`;
|
||||||
|
};
|
||||||
30
config/async-component.js
Normal file
30
config/async-component.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
158
config/auto-sw-plugin.js
Normal file
158
config/auto-sw-plugin.js
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
const util = require('util');
|
||||||
|
const minimatch = require('minimatch');
|
||||||
|
const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
|
||||||
|
const WebWorkerTemplatePlugin = require('webpack/lib/webworker/WebWorkerTemplatePlugin');
|
||||||
|
const ParserHelpers = require('webpack/lib/ParserHelpers');
|
||||||
|
|
||||||
|
const NAME = 'auto-sw-plugin';
|
||||||
|
const JS_TYPES = ['auto', 'esm', 'dynamic'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically finds and bundles Service Workers by looking for navigator.serviceWorker.register(..).
|
||||||
|
* An Array of webpack assets is injected into the Service Worker bundle as a `BUILD_ASSETS` global.
|
||||||
|
* Hidden and `.map` files are excluded by default, and this can be customized using the include & exclude options.
|
||||||
|
* @example
|
||||||
|
* // webpack config
|
||||||
|
* plugins: [
|
||||||
|
* new AutoSWPlugin({
|
||||||
|
* exclude: [
|
||||||
|
* '**\/.*', // don't expose hidden files (default)
|
||||||
|
* '**\/*.map', // don't precache sourcemaps (default)
|
||||||
|
* 'index.html' // don't cache the page itself
|
||||||
|
* ]
|
||||||
|
* })
|
||||||
|
* ]
|
||||||
|
* @param {Object} [options={}]
|
||||||
|
* @param {string[]} [options.exclude] Minimatch pattern(s) of which assets to omit from BUILD_ASSETS.
|
||||||
|
* @param {string[]} [options.include] Minimatch pattern(s) of assets to allow in BUILD_ASSETS.
|
||||||
|
*/
|
||||||
|
module.exports = class AutoSWPlugin {
|
||||||
|
constructor(options) {
|
||||||
|
this.options = Object.assign({
|
||||||
|
exclude: [
|
||||||
|
'**/*.map',
|
||||||
|
'**/.*'
|
||||||
|
]
|
||||||
|
}, options || {});
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(compiler) {
|
||||||
|
const serviceWorkers = [];
|
||||||
|
|
||||||
|
compiler.hooks.emit.tapPromise(NAME, compilation => this.emit(compiler, compilation, serviceWorkers));
|
||||||
|
|
||||||
|
compiler.hooks.normalModuleFactory.tap(NAME, (factory) => {
|
||||||
|
for (const type of JS_TYPES) {
|
||||||
|
factory.hooks.parser.for(`javascript/${type}`).tap(NAME, parser => {
|
||||||
|
let counter = 0;
|
||||||
|
|
||||||
|
const processRegisterCall = expr => {
|
||||||
|
const dep = parser.evaluateExpression(expr.arguments[0]);
|
||||||
|
|
||||||
|
if (!dep.isString()) {
|
||||||
|
parser.state.module.warnings.push({
|
||||||
|
message: 'navigator.serviceWorker.register() will only be bundled if passed a String literal.'
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filename = dep.string;
|
||||||
|
const outputFilename = this.options.filename || 'serviceworker.js'
|
||||||
|
const context = parser.state.current.context;
|
||||||
|
serviceWorkers.push({
|
||||||
|
outputFilename,
|
||||||
|
filename,
|
||||||
|
context
|
||||||
|
});
|
||||||
|
|
||||||
|
const id = `__webpack__serviceworker__${++counter}`;
|
||||||
|
ParserHelpers.toConstantDependency(parser, id)(expr.arguments[0]);
|
||||||
|
return ParserHelpers.addParsedVariableToModule(parser, id, '__webpack_public_path__ + ' + JSON.stringify(outputFilename));
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.hooks.call.for('navigator.serviceWorker.register').tap(NAME, processRegisterCall);
|
||||||
|
parser.hooks.call.for('self.navigator.serviceWorker.register').tap(NAME, processRegisterCall);
|
||||||
|
parser.hooks.call.for('window.navigator.serviceWorker.register').tap(NAME, processRegisterCall);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
createFilter(list) {
|
||||||
|
const filters = [].concat(list);
|
||||||
|
for (let i=0; i<filters.length; i++) {
|
||||||
|
if (typeof filters[i] === 'string') {
|
||||||
|
filters[i] = minimatch.filter(filters[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filters;
|
||||||
|
}
|
||||||
|
|
||||||
|
async emit(compiler, compilation, serviceWorkers) {
|
||||||
|
let assetMapping = Object.keys(compilation.assets);
|
||||||
|
if (this.options.include) {
|
||||||
|
const filters = this.createFilter(this.options.include);
|
||||||
|
assetMapping = assetMapping.filter(filename => {
|
||||||
|
for (const filter of filters) {
|
||||||
|
if (filter(filename)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this.options.exclude) {
|
||||||
|
const filters = this.createFilter(this.options.exclude);
|
||||||
|
assetMapping = assetMapping.filter(filename => {
|
||||||
|
for (const filter of filters) {
|
||||||
|
if (filter(filename)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
await Promise.all(serviceWorkers.map(
|
||||||
|
(serviceWorker, index) => this.compileServiceWorker(compiler, compilation, serviceWorker, index, assetMapping)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
async compileServiceWorker(compiler, compilation, options, index, assetMapping) {
|
||||||
|
const entryFilename = options.filename;
|
||||||
|
|
||||||
|
const chunkFilename = compiler.options.output.chunkFilename.replace(/\.([a-z]+)$/i, '.serviceworker.$1');
|
||||||
|
const workerOptions = {
|
||||||
|
filename: options.outputFilename, // chunkFilename.replace(/\.?\[(?:chunkhash|contenthash|hash)(:\d+(?::\d+)?)?\]/g, ''),
|
||||||
|
chunkFilename: this.options.chunkFilename || chunkFilename,
|
||||||
|
globalObject: 'self'
|
||||||
|
};
|
||||||
|
|
||||||
|
const childCompiler = compilation.createChildCompiler(NAME, { filename: workerOptions.filename });
|
||||||
|
(new WebWorkerTemplatePlugin(workerOptions)).apply(childCompiler);
|
||||||
|
|
||||||
|
/* The duplication DefinePlugin ends up causing is problematic (it doesn't hoist injections), so we'll do it manually. */
|
||||||
|
// (new DefinePlugin({
|
||||||
|
// BUILD_ASSETS: JSON.stringify(assetMapping)
|
||||||
|
// })).apply(childCompiler);
|
||||||
|
(new SingleEntryPlugin(options.context, entryFilename, workerOptions.filename)).apply(childCompiler);
|
||||||
|
|
||||||
|
const subCache = `subcache ${__dirname} ${entryFilename} ${index}`;
|
||||||
|
let childCompilation;
|
||||||
|
childCompiler.hooks.compilation.tap(NAME, c => {
|
||||||
|
childCompilation = c;
|
||||||
|
if (childCompilation.cache) {
|
||||||
|
if (!childCompilation.cache[subCache]) childCompilation.cache[subCache] = {};
|
||||||
|
childCompilation.cache = childCompilation.cache[subCache];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await (util.promisify(childCompiler.runAsChild.bind(childCompiler)))();
|
||||||
|
|
||||||
|
const versionVar = this.options.version ?
|
||||||
|
`var VERSION = ${JSON.stringify(this.options.version)};` : '';
|
||||||
|
const original = childCompilation.assets[workerOptions.filename].source();
|
||||||
|
const source = `${versionVar}var BUILD_ASSETS=${JSON.stringify(assetMapping)};${original}`;
|
||||||
|
childCompilation.assets[workerOptions.filename] = {
|
||||||
|
source: () => source,
|
||||||
|
size: () => Buffer.byteLength(source, 'utf8')
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.assign(compilation.assets, childCompilation.assets);
|
||||||
|
}
|
||||||
|
};
|
||||||
30
config/watch-timestamps-plugin.js
Normal file
30
config/watch-timestamps-plugin.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
/** A Webpack plugin to refresh file mtime values from disk before compiling.
|
||||||
|
* This is used in order to account for SCSS-generated .d.ts files written
|
||||||
|
* as part of compilation so they trigger only a single recompile per write.
|
||||||
|
*
|
||||||
|
* All credit for the technique and implementation goes to @reiv. See:
|
||||||
|
* https://github.com/Jimdo/typings-for-css-modules-loader/issues/48#issuecomment-347036461
|
||||||
|
*/
|
||||||
|
module.exports = class WatchTimestampsPlugin {
|
||||||
|
constructor(patterns) {
|
||||||
|
this.patterns = patterns;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.watchRun.tapAsync('watch-timestamps-plugin', (watch, callback) => {
|
||||||
|
const patterns = this.patterns;
|
||||||
|
const timestamps = watch.fileTimestamps;
|
||||||
|
|
||||||
|
for (const filepath of timestamps) {
|
||||||
|
if (patterns.some(pat => pat instanceof RegExp ? pat.test(filepath) : filepath.indexOf(pat) === 0)) {
|
||||||
|
let time = fs.statSync(filepath).mtime;
|
||||||
|
if (timestamps instanceof Map) timestamps.set(filepath, time);
|
||||||
|
else timestamps[filepath] = time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
51
emscripten-types.d.ts → emscripten-wasm.d.ts
vendored
51
emscripten-types.d.ts → emscripten-wasm.d.ts
vendored
@@ -1,11 +1,7 @@
|
|||||||
// These types roughly model the object that the JS files generated by Emscripten define. Copied from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/emscripten/index.d.ts and turned into a type definition rather than a global to support our way of using Emscripten.
|
// These types roughly model the object that the JS files generated by Emscripten define. Copied from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/emscripten/index.d.ts and turned into a type definition rather than a global to support our way of using Emscripten.
|
||||||
// TODO(@surma): Upstream this?
|
// TODO(@surma): Upstream this?
|
||||||
declare namespace EmscriptenWasm {
|
declare namespace EmscriptenWasm {
|
||||||
type ModuleFactory<T extends Module = Module> = (
|
type EnvironmentType = "WEB" | "NODE" | "SHELL" | "WORKER";
|
||||||
moduleOverrides?: ModuleOpts,
|
|
||||||
) => Promise<T>;
|
|
||||||
|
|
||||||
type EnvironmentType = 'WEB' | 'NODE' | 'SHELL' | 'WORKER';
|
|
||||||
|
|
||||||
// Options object for modularized Emscripten files. Shoe-horned by @surma.
|
// Options object for modularized Emscripten files. Shoe-horned by @surma.
|
||||||
// FIXME: This an incomplete definition!
|
// FIXME: This an incomplete definition!
|
||||||
@@ -21,9 +17,9 @@ declare namespace EmscriptenWasm {
|
|||||||
printErr(str: string): void;
|
printErr(str: string): void;
|
||||||
arguments: string[];
|
arguments: string[];
|
||||||
environment: EnvironmentType;
|
environment: EnvironmentType;
|
||||||
preInit: { (): void }[];
|
preInit: { (): void }[];
|
||||||
preRun: { (): void }[];
|
preRun: { (): void }[];
|
||||||
postRun: { (): void }[];
|
postRun: { (): void }[];
|
||||||
preinitializedWebGLContext: WebGLRenderingContext;
|
preinitializedWebGLContext: WebGLRenderingContext;
|
||||||
noInitialRun: boolean;
|
noInitialRun: boolean;
|
||||||
noExitRuntime: boolean;
|
noExitRuntime: boolean;
|
||||||
@@ -32,25 +28,17 @@ declare namespace EmscriptenWasm {
|
|||||||
wasmBinary: ArrayBuffer;
|
wasmBinary: ArrayBuffer;
|
||||||
|
|
||||||
destroy(object: object): void;
|
destroy(object: object): void;
|
||||||
getPreloadedPackage(
|
getPreloadedPackage(remotePackageName: string, remotePackageSize: number): ArrayBuffer;
|
||||||
remotePackageName: string,
|
|
||||||
remotePackageSize: number,
|
|
||||||
): ArrayBuffer;
|
|
||||||
instantiateWasm(
|
instantiateWasm(
|
||||||
imports: WebAssembly.Imports,
|
imports: WebAssembly.Imports,
|
||||||
successCallback: (module: WebAssembly.Module) => void,
|
successCallback: (module: WebAssembly.Module) => void
|
||||||
): WebAssembly.Exports;
|
): WebAssembly.Exports;
|
||||||
locateFile(url: string): string;
|
locateFile(url: string): string;
|
||||||
onCustomMessage(event: MessageEvent): void;
|
onCustomMessage(event: MessageEvent): void;
|
||||||
|
|
||||||
Runtime: any;
|
Runtime: any;
|
||||||
|
|
||||||
ccall(
|
ccall(ident: string, returnType: string | null, argTypes: string[], args: any[]): any;
|
||||||
ident: string,
|
|
||||||
returnType: string | null,
|
|
||||||
argTypes: string[],
|
|
||||||
args: any[],
|
|
||||||
): any;
|
|
||||||
cwrap(ident: string, returnType: string | null, argTypes: string[]): any;
|
cwrap(ident: string, returnType: string | null, argTypes: string[]): any;
|
||||||
|
|
||||||
setValue(ptr: number, value: any, type: string, noSafe?: boolean): void;
|
setValue(ptr: number, value: any, type: string, noSafe?: boolean): void;
|
||||||
@@ -63,12 +51,7 @@ declare namespace EmscriptenWasm {
|
|||||||
ALLOC_NONE: number;
|
ALLOC_NONE: number;
|
||||||
|
|
||||||
allocate(slab: any, types: string, allocator: number, ptr: number): number;
|
allocate(slab: any, types: string, allocator: number, ptr: number): number;
|
||||||
allocate(
|
allocate(slab: any, types: string[], allocator: number, ptr: number): number;
|
||||||
slab: any,
|
|
||||||
types: string[],
|
|
||||||
allocator: number,
|
|
||||||
ptr: number,
|
|
||||||
): number;
|
|
||||||
|
|
||||||
Pointer_stringify(ptr: number, length?: number): string;
|
Pointer_stringify(ptr: number, length?: number): string;
|
||||||
UTF16ToString(ptr: number): string;
|
UTF16ToString(ptr: number): string;
|
||||||
@@ -85,7 +68,7 @@ declare namespace EmscriptenWasm {
|
|||||||
HEAP8: Int8Array;
|
HEAP8: Int8Array;
|
||||||
HEAP16: Int16Array;
|
HEAP16: Int16Array;
|
||||||
HEAP32: Int32Array;
|
HEAP32: Int32Array;
|
||||||
HEAPU8: Uint8Array;
|
HEAPU8: Uint8Array;
|
||||||
HEAPU16: Uint16Array;
|
HEAPU16: Uint16Array;
|
||||||
HEAPU32: Uint32Array;
|
HEAPU32: Uint32Array;
|
||||||
HEAPF32: Float32Array;
|
HEAPF32: Float32Array;
|
||||||
@@ -102,23 +85,16 @@ declare namespace EmscriptenWasm {
|
|||||||
addOnPostRun(cb: () => any): void;
|
addOnPostRun(cb: () => any): void;
|
||||||
|
|
||||||
// Tools
|
// Tools
|
||||||
intArrayFromString(
|
intArrayFromString(stringy: string, dontAddNull?: boolean, length?: number): number[];
|
||||||
stringy: string,
|
|
||||||
dontAddNull?: boolean,
|
|
||||||
length?: number,
|
|
||||||
): number[];
|
|
||||||
intArrayToString(array: number[]): string;
|
intArrayToString(array: number[]): string;
|
||||||
writeStringToMemory(
|
writeStringToMemory(str: string, buffer: number, dontAddNull: boolean): void;
|
||||||
str: string,
|
|
||||||
buffer: number,
|
|
||||||
dontAddNull: boolean,
|
|
||||||
): void;
|
|
||||||
writeArrayToMemory(array: number[], buffer: number): void;
|
writeArrayToMemory(array: number[], buffer: number): void;
|
||||||
writeAsciiToMemory(str: string, buffer: number, dontAddNull: boolean): void;
|
writeAsciiToMemory(str: string, buffer: number, dontAddNull: boolean): void;
|
||||||
|
|
||||||
addRunDependency(id: any): void;
|
addRunDependency(id: any): void;
|
||||||
removeRunDependency(id: any): void;
|
removeRunDependency(id: any): void;
|
||||||
|
|
||||||
|
|
||||||
preloadedImages: any;
|
preloadedImages: any;
|
||||||
preloadedAudios: any;
|
preloadedAudios: any;
|
||||||
|
|
||||||
@@ -129,3 +105,4 @@ declare namespace EmscriptenWasm {
|
|||||||
onRuntimeInitialized: () => void | null;
|
onRuntimeInitialized: () => void | null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ES2019",
|
|
||||||
"downlevelIteration": true,
|
|
||||||
"module": "esnext",
|
|
||||||
"jsx": "react",
|
|
||||||
"jsxFactory": "h",
|
|
||||||
"strict": true,
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"composite": true,
|
|
||||||
"declarationMap": true,
|
|
||||||
"baseUrl": "./",
|
|
||||||
"rootDir": "./",
|
|
||||||
"outDir": ".tmp/ts",
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"paths": {
|
|
||||||
"static-build/*": ["src/static-build/*"],
|
|
||||||
"client/*": ["src/client/*"],
|
|
||||||
"shared/*": ["src/shared/*"],
|
|
||||||
"features/*": ["src/features/*"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
23
global.d.ts
vendored
Normal file
23
global.d.ts
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
declare const __webpack_public_path__: string;
|
||||||
|
declare const PRERENDER: boolean;
|
||||||
|
|
||||||
|
declare interface NodeModule {
|
||||||
|
hot: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare interface Window {
|
||||||
|
STATE: any;
|
||||||
|
ga: typeof ga;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare namespace JSX {
|
||||||
|
interface Element { }
|
||||||
|
interface IntrinsicElements { }
|
||||||
|
interface HTMLAttributes {
|
||||||
|
decoding?: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'classnames' {
|
||||||
|
export default function classnames(...args: any[]): string;
|
||||||
|
}
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2020 Google Inc. All Rights Reserved.
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import rollup from 'rollup';
|
|
||||||
|
|
||||||
const prefix = 'client-bundle:';
|
|
||||||
const entryPathPlaceholder = 'CLIENT_BUNDLE_PLUGIN_ENTRY_PATH';
|
|
||||||
const importsPlaceholder = 'CLIENT_BUNDLE_PLUGIN_IMPORTS';
|
|
||||||
const allSrcPlaceholder = 'CLIENT_BUNDLE_PLUGIN_ALL_SRC';
|
|
||||||
|
|
||||||
export function getDependencies(clientOutput, item) {
|
|
||||||
const crawlDependencies = new Set([item.fileName]);
|
|
||||||
|
|
||||||
for (const fileName of crawlDependencies) {
|
|
||||||
const chunk = clientOutput.find((v) => v.fileName === fileName);
|
|
||||||
|
|
||||||
for (const dep of chunk.imports) {
|
|
||||||
crawlDependencies.add(dep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't add self as dependency
|
|
||||||
crawlDependencies.delete(item.fileName);
|
|
||||||
|
|
||||||
return [...crawlDependencies];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function (inputOptions, outputOptions, resolveFileUrl) {
|
|
||||||
let cache;
|
|
||||||
let entryPointPlaceholderMap;
|
|
||||||
let exportCounter;
|
|
||||||
let clientBundle;
|
|
||||||
let clientOutput;
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: 'client-bundle',
|
|
||||||
buildStart() {
|
|
||||||
entryPointPlaceholderMap = new Map();
|
|
||||||
exportCounter = 0;
|
|
||||||
},
|
|
||||||
async resolveId(id, importer) {
|
|
||||||
if (!id.startsWith(prefix)) return null;
|
|
||||||
|
|
||||||
const realId = id.slice(prefix.length);
|
|
||||||
const resolveResult = await this.resolve(realId, importer);
|
|
||||||
// Add an additional .js to the end so it ends up with .js at the end in the _virtual folder.
|
|
||||||
if (resolveResult) return prefix + resolveResult.id + '.js';
|
|
||||||
// This Rollup couldn't resolve it, but maybe the inner one can.
|
|
||||||
return id + '.js';
|
|
||||||
},
|
|
||||||
load(id) {
|
|
||||||
if (!id.startsWith(prefix)) return;
|
|
||||||
|
|
||||||
const realId = id.slice(prefix.length, -'.js'.length);
|
|
||||||
|
|
||||||
exportCounter++;
|
|
||||||
|
|
||||||
entryPointPlaceholderMap.set(exportCounter, realId);
|
|
||||||
|
|
||||||
return [
|
|
||||||
`export default import.meta.${entryPathPlaceholder + exportCounter};`,
|
|
||||||
`export const imports = import.meta.${
|
|
||||||
importsPlaceholder + exportCounter
|
|
||||||
};`,
|
|
||||||
`export const allSrc = import.meta.${
|
|
||||||
allSrcPlaceholder + exportCounter
|
|
||||||
};`,
|
|
||||||
].join('\n');
|
|
||||||
},
|
|
||||||
async buildEnd(error) {
|
|
||||||
const entryPoints = [...entryPointPlaceholderMap.values()];
|
|
||||||
// The static-build is done, so now we can perform our client build.
|
|
||||||
// Exit early if there's nothing to build.
|
|
||||||
if (error || entryPoints.length === 0) return;
|
|
||||||
|
|
||||||
clientBundle = await rollup.rollup({
|
|
||||||
...inputOptions,
|
|
||||||
cache,
|
|
||||||
input: entryPoints,
|
|
||||||
});
|
|
||||||
|
|
||||||
cache = clientBundle.cache;
|
|
||||||
},
|
|
||||||
async renderStart(staticBuildOutputOpts) {
|
|
||||||
// The static-build has started generating output, so we can do the same for our client build.
|
|
||||||
// Exit early if there's nothing to build.
|
|
||||||
if (!clientBundle) return;
|
|
||||||
const copiedOutputOptions = {
|
|
||||||
assetFileNames: staticBuildOutputOpts.assetFileNames,
|
|
||||||
};
|
|
||||||
clientOutput = (
|
|
||||||
await clientBundle.generate({
|
|
||||||
...copiedOutputOptions,
|
|
||||||
...outputOptions,
|
|
||||||
})
|
|
||||||
).output;
|
|
||||||
},
|
|
||||||
resolveImportMeta(property, { moduleId, format }) {
|
|
||||||
// Pick up the placeholder exports we created earlier, and fill in the correct details.
|
|
||||||
let num = undefined;
|
|
||||||
|
|
||||||
if (property.startsWith(entryPathPlaceholder)) {
|
|
||||||
num = Number(property.slice(entryPathPlaceholder.length));
|
|
||||||
} else if (property.startsWith(importsPlaceholder)) {
|
|
||||||
num = Number(property.slice(importsPlaceholder.length));
|
|
||||||
} else if (property.startsWith(allSrcPlaceholder)) {
|
|
||||||
num = Number(property.slice(allSrcPlaceholder.length));
|
|
||||||
} else {
|
|
||||||
// This isn't one of our placeholders.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const id = entryPointPlaceholderMap.get(num);
|
|
||||||
const clientEntry = clientOutput.find(
|
|
||||||
(item) => item.facadeModuleId === id,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (property.startsWith(entryPathPlaceholder)) {
|
|
||||||
return resolveFileUrl({
|
|
||||||
fileName: clientEntry.fileName,
|
|
||||||
moduleId,
|
|
||||||
format,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const dependencies = getDependencies(clientOutput, clientEntry);
|
|
||||||
|
|
||||||
if (property.startsWith(allSrcPlaceholder)) {
|
|
||||||
return JSON.stringify(
|
|
||||||
[clientEntry.code, ...dependencies.map((d) => d.code)].join(';'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
'[' +
|
|
||||||
dependencies
|
|
||||||
.map((item) => {
|
|
||||||
const entry = clientOutput.find((v) => v.fileName === item);
|
|
||||||
|
|
||||||
return resolveFileUrl({
|
|
||||||
fileName: entry.fileName,
|
|
||||||
moduleId,
|
|
||||||
format: outputOptions.format,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.join(',') +
|
|
||||||
']'
|
|
||||||
);
|
|
||||||
},
|
|
||||||
async generateBundle(options, bundle) {
|
|
||||||
// Exit early if there's nothing to build.
|
|
||||||
if (!clientOutput) return;
|
|
||||||
// Copy everything from the client bundle into the main bundle.
|
|
||||||
for (const clientEntry of clientOutput) {
|
|
||||||
// Skip if the file already exists
|
|
||||||
if (clientEntry.fileName in bundle) continue;
|
|
||||||
|
|
||||||
this.emitFile({
|
|
||||||
type: 'asset',
|
|
||||||
source: clientEntry.code || clientEntry.source,
|
|
||||||
fileName: clientEntry.fileName,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user