mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-13 09:17:20 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8d35e0fb6 | ||
|
|
5f72c2ed74 |
22
README.md
22
README.md
@@ -15,8 +15,6 @@ However, Squoosh utilizes Google Analytics to collect the following:
|
|||||||
|
|
||||||
# Developing
|
# Developing
|
||||||
|
|
||||||
## Web App
|
|
||||||
|
|
||||||
To develop for Squoosh:
|
To develop for Squoosh:
|
||||||
|
|
||||||
1. Clone the repository
|
1. Clone the repository
|
||||||
@@ -33,28 +31,8 @@ To develop for Squoosh:
|
|||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
## Codecs
|
|
||||||
|
|
||||||
All build instructions for codecs are written using [Nix]. If you have Nix installed, you can rebuild the WebAssembly binaries by running:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# Build the codec
|
|
||||||
cd codec/<codec>
|
|
||||||
nix run '.#updateRepoBinaries'
|
|
||||||
```
|
|
||||||
|
|
||||||
If you do not have Nix installed, you can use the provided Docker image to create a shell with nix available:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# Build the image (only needs to be done once).
|
|
||||||
docker build -t squoosh-nix ./nix
|
|
||||||
docker run --name squoosh-nix -ti -v $PWD:/app squoosh-nix /bin/sh
|
|
||||||
# ... continue with the steps above
|
|
||||||
```
|
|
||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
Squoosh is an open-source project that appreciates all community involvement. To contribute to the project, follow the [contribute guide](/CONTRIBUTING.md).
|
Squoosh is an open-source project that appreciates all community involvement. To contribute to the project, follow the [contribute guide](/CONTRIBUTING.md).
|
||||||
|
|
||||||
[squoosh]: https://squoosh.app
|
[squoosh]: https://squoosh.app
|
||||||
[nix]: https://nixos.org
|
|
||||||
|
|||||||
1
codecs/.gitignore
vendored
1
codecs/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
!wasm_build
|
|
||||||
@@ -16,6 +16,8 @@ override CFLAGS += "-Wno-unused-macros"
|
|||||||
# See libavif/ext/libsharpyuv.cmd for more detail
|
# See libavif/ext/libsharpyuv.cmd for more detail
|
||||||
LIBWEBP_URL_WITH_SHARPYUV = https://chromium.googlesource.com/webm/libwebp/+archive/e2c85878f6a33f29948b43d3492d9cdaf801aa54.tar.gz
|
LIBWEBP_URL_WITH_SHARPYUV = https://chromium.googlesource.com/webm/libwebp/+archive/e2c85878f6a33f29948b43d3492d9cdaf801aa54.tar.gz
|
||||||
LIBWEBP_DIR := $(CODEC_DIR)/ext/libwebp
|
LIBWEBP_DIR := $(CODEC_DIR)/ext/libwebp
|
||||||
|
LIBSHARPYUV_ST := $(LIBWEBP_DIR)/build_st/libsharpyuv.a
|
||||||
|
LIBSHARPYUV_MT := $(LIBWEBP_DIR)/build_mt/libsharpyuv.a
|
||||||
export LIBSHARPYUV := $(LIBWEBP_DIR)/build/libsharpyuv.a
|
export LIBSHARPYUV := $(LIBWEBP_DIR)/build/libsharpyuv.a
|
||||||
|
|
||||||
OUT_ENC_JS = enc/avif_enc.js
|
OUT_ENC_JS = enc/avif_enc.js
|
||||||
@@ -36,7 +38,8 @@ HELPER_MAKEFLAGS := -f helper.Makefile
|
|||||||
all: $(OUT_ENC_JS) $(OUT_DEC_JS) $(OUT_ENC_MT_JS)
|
all: $(OUT_ENC_JS) $(OUT_DEC_JS) $(OUT_ENC_MT_JS)
|
||||||
|
|
||||||
# ST-Encoding
|
# ST-Encoding
|
||||||
$(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt $(LIBSHARPYUV)
|
$(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt $(LIBSHARPYUV_ST)
|
||||||
|
mkdir -p $(LIBWEBP_DIR)/build && cp $(LIBSHARPYUV_ST) $(LIBSHARPYUV)
|
||||||
$(MAKE) \
|
$(MAKE) \
|
||||||
$(HELPER_MAKEFLAGS) \
|
$(HELPER_MAKEFLAGS) \
|
||||||
OUT_JS=$@ \
|
OUT_JS=$@ \
|
||||||
@@ -50,7 +53,9 @@ $(OUT_ENC_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLis
|
|||||||
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0 -DAVIF_LOCAL_LIBSHARPYUV=ON"
|
LIBAVIF_FLAGS="-DAVIF_CODEC_AOM_DECODE=0 -DAVIF_LOCAL_LIBSHARPYUV=ON"
|
||||||
|
|
||||||
# MT-Encoding
|
# MT-Encoding
|
||||||
$(OUT_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt $(LIBSHARPYUV)
|
# We need to run the ST and MT tasks sequentially to avoid conflicts with the copy of libsharpyuv in the build directory
|
||||||
|
$(OUT_ENC_MT_JS): $(OUT_ENC_CPP) $(CODEC_DIR)/CMakeLists.txt $(LIBAOM_DIR)/CMakeLists.txt $(LIBSHARPYUV_MT) | $(OUT_ENC_JS)
|
||||||
|
mkdir -p $(LIBWEBP_DIR)/build && cp $(LIBSHARPYUV_MT) $(LIBSHARPYUV)
|
||||||
$(MAKE) \
|
$(MAKE) \
|
||||||
$(HELPER_MAKEFLAGS) \
|
$(HELPER_MAKEFLAGS) \
|
||||||
OUT_JS=$@ \
|
OUT_JS=$@ \
|
||||||
@@ -106,8 +111,29 @@ $(LIBWEBP_DIR)/CMakeLists.txt: $(CODEC_DIR)/CMakeLists.txt
|
|||||||
curl -sL $(LIBWEBP_URL_WITH_SHARPYUV) \
|
curl -sL $(LIBWEBP_URL_WITH_SHARPYUV) \
|
||||||
| tar xzm -C $(LIBWEBP_DIR)
|
| tar xzm -C $(LIBWEBP_DIR)
|
||||||
|
|
||||||
# Make libsharpyuv.a
|
# Make libsharpyuv.a for ST-Encoding
|
||||||
$(LIBSHARPYUV): $(LIBWEBP_DIR)/CMakeLists.txt
|
$(LIBSHARPYUV_ST): $(LIBWEBP_DIR)/CMakeLists.txt
|
||||||
|
mkdir -p $(@D)
|
||||||
|
emcmake cmake \
|
||||||
|
-DWEBP_USE_THREAD=OFF \
|
||||||
|
-DWEBP_BUILD_ANIM_UTILS=OFF \
|
||||||
|
-DWEBP_BUILD_CWEBP=OFF \
|
||||||
|
-DWEBP_BUILD_DWEBP=OFF \
|
||||||
|
-DWEBP_BUILD_GIF2WEBP=OFF \
|
||||||
|
-DWEBP_BUILD_IMG2WEBP=OFF \
|
||||||
|
-DWEBP_BUILD_VWEBP=OFF \
|
||||||
|
-DWEBP_BUILD_WEBPINFO=OFF \
|
||||||
|
-DWEBP_BUILD_LIBWEBPMUX=OFF \
|
||||||
|
-DWEBP_BUILD_WEBPMUX=OFF \
|
||||||
|
-DWEBP_BUILD_EXTRAS=OFF \
|
||||||
|
-DBUILD_SHARED_LIBS=OFF \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-S $(LIBWEBP_DIR) \
|
||||||
|
-B $(@D)
|
||||||
|
$(MAKE) -C $(@D) sharpyuv
|
||||||
|
|
||||||
|
# Make libsharpyuv.a for MT-Encoding
|
||||||
|
$(LIBSHARPYUV_MT): $(LIBWEBP_DIR)/CMakeLists.txt
|
||||||
mkdir -p $(@D)
|
mkdir -p $(@D)
|
||||||
emcmake cmake \
|
emcmake cmake \
|
||||||
-DWEBP_BUILD_ANIM_UTILS=OFF \
|
-DWEBP_BUILD_ANIM_UTILS=OFF \
|
||||||
|
|||||||
2
codecs/avif/enc/avif_enc.js
generated
2
codecs/avif/enc/avif_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1,31 +1,61 @@
|
|||||||
|
CODEC_URL := https://github.com/mozilla/mozjpeg/archive/v3.3.1.tar.gz
|
||||||
|
CODEC_DIR := node_modules/mozjpeg
|
||||||
|
CODEC_OUT_RELATIVE := .libs/libjpeg.a rdswitch.o
|
||||||
|
CODEC_OUT := $(addprefix $(CODEC_DIR)/, $(CODEC_OUT_RELATIVE))
|
||||||
ENVIRONMENT = worker
|
ENVIRONMENT = worker
|
||||||
|
|
||||||
OUT_JS := enc/mozjpeg_enc.js
|
OUT_JS := enc/mozjpeg_enc.js enc/mozjpeg_node_enc.js dec/mozjpeg_node_dec.js
|
||||||
OUT_WASM := $(OUT_JS:.js=.wasm)
|
OUT_WASM := $(OUT_JS:.js=.wasm)
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
all: $(OUT_JS)
|
all: $(OUT_JS)
|
||||||
|
|
||||||
|
# Define dependencies for all variations of build artifacts.
|
||||||
$(filter enc/%,$(OUT_JS)): enc/mozjpeg_enc.cpp
|
$(filter enc/%,$(OUT_JS)): enc/mozjpeg_enc.cpp
|
||||||
|
$(filter dec/%,$(OUT_JS)): dec/mozjpeg_dec.cpp
|
||||||
|
|
||||||
%.js:
|
enc/mozjpeg_node_enc.js dec/mozjpeg_node_dec.js: ENVIRONMENT = node
|
||||||
|
|
||||||
|
%.js: $(CODEC_OUT)
|
||||||
$(CXX) \
|
$(CXX) \
|
||||||
-O3 \
|
-I $(CODEC_DIR) \
|
||||||
-flto \
|
|
||||||
-s FILESYSTEM=0 \
|
|
||||||
-s PTHREAD_POOL_SIZE=navigator.hardwareConcurrency \
|
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
|
||||||
-s TEXTDECODER=2 \
|
|
||||||
-s NODEJS_CATCH_EXIT=0 -s NODEJS_CATCH_REJECTION=0 \
|
|
||||||
-s ENVIRONMENT=$(ENVIRONMENT) \
|
|
||||||
-s EXPORT_ES6=1 \
|
|
||||||
-lembind \
|
|
||||||
${CXXFLAGS} \
|
${CXXFLAGS} \
|
||||||
${LDFLAGS} \
|
${LDFLAGS} \
|
||||||
|
--bind \
|
||||||
|
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
|
-s EXPORT_ES6=1 \
|
||||||
-o $@ \
|
-o $@ \
|
||||||
-I ${MOZJPEG}/include \
|
|
||||||
-L ${MOZJPEG}/lib \
|
|
||||||
-ljpeg \
|
|
||||||
${MOZJPEG}/lib/rdswitch.o \
|
|
||||||
$+
|
$+
|
||||||
|
|
||||||
|
# This one is a bit special: there is no rule for .libs/libjpeg.a
|
||||||
|
# so we use libjpeg.la which implicitly builds that one instead.
|
||||||
|
$(CODEC_DIR)/.libs/libjpeg.a: $(CODEC_DIR)/Makefile
|
||||||
|
$(MAKE) -C $(CODEC_DIR) libjpeg.la
|
||||||
|
|
||||||
|
$(CODEC_DIR)/rdswitch.o: $(CODEC_DIR)/Makefile
|
||||||
|
$(MAKE) -C $(CODEC_DIR) rdswitch.o
|
||||||
|
|
||||||
|
$(CODEC_DIR)/Makefile: $(CODEC_DIR)/configure
|
||||||
|
cd $(CODEC_DIR) && ./configure \
|
||||||
|
--disable-shared \
|
||||||
|
--without-turbojpeg \
|
||||||
|
--without-simd \
|
||||||
|
--without-arith-enc \
|
||||||
|
--without-arith-dec \
|
||||||
|
--with-build-date=squoosh
|
||||||
|
# ^ If not provided with a dummy value, MozJPEG includes a build date in the
|
||||||
|
# binary as part of the version string, making binaries different each time.
|
||||||
|
|
||||||
|
$(CODEC_DIR)/configure: $(CODEC_DIR)/configure.ac
|
||||||
|
cd $(CODEC_DIR) && autoreconf -iv
|
||||||
|
|
||||||
|
$(CODEC_DIR)/configure.ac: $(CODEC_DIR)
|
||||||
|
|
||||||
|
$(CODEC_DIR):
|
||||||
|
mkdir -p $@
|
||||||
|
curl -sL $(CODEC_URL) | tar xz --strip 1 -C $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(OUT_JS) $(OUT_WASM)
|
||||||
|
$(MAKE) -C $(CODEC_DIR) clean
|
||||||
|
|||||||
57
codecs/mozjpeg/dec/mozjpeg_dec.cpp
Normal file
57
codecs/mozjpeg/dec/mozjpeg_dec.cpp
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#include <emscripten/bind.h>
|
||||||
|
#include <emscripten/val.h>
|
||||||
|
#include "config.h"
|
||||||
|
#include "jpeglib.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "cdjpeg.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) {
|
||||||
|
uint8_t* image_buffer = (uint8_t*)image_in.c_str();
|
||||||
|
|
||||||
|
jpeg_decompress_struct cinfo;
|
||||||
|
jpeg_error_mgr jerr;
|
||||||
|
// Initialize the JPEG decompression object with default error handling.
|
||||||
|
cinfo.err = jpeg_std_error(&jerr);
|
||||||
|
jpeg_create_decompress(&cinfo);
|
||||||
|
|
||||||
|
jpeg_mem_src(&cinfo, image_buffer, image_in.length());
|
||||||
|
// Read file header, set default decompression parameters
|
||||||
|
jpeg_read_header(&cinfo, TRUE);
|
||||||
|
// Force RGBA decoding, even for grayscale images
|
||||||
|
cinfo.out_color_space = JCS_EXT_RGBA;
|
||||||
|
jpeg_start_decompress(&cinfo);
|
||||||
|
|
||||||
|
// Prepare output buffer
|
||||||
|
size_t output_size = cinfo.output_width * cinfo.output_height * 4;
|
||||||
|
std::vector<uint8_t> output_buffer(output_size);
|
||||||
|
auto stride = cinfo.output_width * 4;
|
||||||
|
|
||||||
|
// Process data
|
||||||
|
while (cinfo.output_scanline < cinfo.output_height) {
|
||||||
|
uint8_t* ptr = &output_buffer[stride * cinfo.output_scanline];
|
||||||
|
jpeg_read_scanlines(&cinfo, &ptr, 1);
|
||||||
|
}
|
||||||
|
jpeg_finish_decompress(&cinfo);
|
||||||
|
|
||||||
|
// Step 7: release JPEG compression object
|
||||||
|
|
||||||
|
auto data = Uint8ClampedArray.new_(typed_memory_view(output_size, &output_buffer[0]));
|
||||||
|
auto js_result = ImageData.new_(data, cinfo.output_width, cinfo.output_height);
|
||||||
|
|
||||||
|
// This is an important step since it will release a good deal of memory.
|
||||||
|
jpeg_destroy_decompress(&cinfo);
|
||||||
|
|
||||||
|
// And we're done!
|
||||||
|
return js_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
EMSCRIPTEN_BINDINGS(my_module) {
|
||||||
|
function("decode", &decode);
|
||||||
|
}
|
||||||
16
codecs/mozjpeg/dec/mozjpeg_node_dec.js
generated
Normal file
16
codecs/mozjpeg/dec/mozjpeg_node_dec.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/mozjpeg/dec/mozjpeg_node_dec.wasm
Executable file
BIN
codecs/mozjpeg/dec/mozjpeg_node_dec.wasm
Executable file
Binary file not shown.
@@ -5,7 +5,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "jconfig.h"
|
#include "config.h"
|
||||||
#include "jpeglib.h"
|
#include "jpeglib.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
16
codecs/mozjpeg/enc/mozjpeg_enc.js
generated
Normal file
16
codecs/mozjpeg/enc/mozjpeg_enc.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/mozjpeg/enc/mozjpeg_enc.wasm
Executable file
BIN
codecs/mozjpeg/enc/mozjpeg_enc.wasm
Executable file
Binary file not shown.
16
codecs/mozjpeg/enc/mozjpeg_node_enc.js
generated
Normal file
16
codecs/mozjpeg/enc/mozjpeg_node_enc.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/mozjpeg/enc/mozjpeg_node_enc.wasm
Executable file
BIN
codecs/mozjpeg/enc/mozjpeg_node_enc.wasm
Executable file
Binary file not shown.
79
codecs/mozjpeg/flake.lock
generated
79
codecs/mozjpeg/flake.lock
generated
@@ -1,79 +0,0 @@
|
|||||||
{
|
|
||||||
"nodes": {
|
|
||||||
"flake-utils": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1710146030,
|
|
||||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mozjpeg-src": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1499684294,
|
|
||||||
"narHash": "sha256-frpQdkk7bJE5qbV70fdL1FsC4eI0Fm8FWshqBQxCRtk=",
|
|
||||||
"owner": "mozilla",
|
|
||||||
"repo": "mozjpeg",
|
|
||||||
"rev": "f154ccc091cbc22141cdfd531e5ad1fdc5bc53c7",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "mozilla",
|
|
||||||
"ref": "v3.3.1",
|
|
||||||
"repo": "mozjpeg",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1717179513,
|
|
||||||
"narHash": "sha256-vboIEwIQojofItm2xGCdZCzW96U85l9nDW3ifMuAIdM=",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "63dacb46bf939521bdc93981b4cbb7ecb58427a0",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nixos",
|
|
||||||
"ref": "24.05",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"mozjpeg-src": "mozjpeg-src",
|
|
||||||
"nixpkgs": "nixpkgs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": "root",
|
|
||||||
"version": 7
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
{
|
|
||||||
inputs = {
|
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/24.05";
|
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
|
||||||
mozjpeg-src = {
|
|
||||||
url = "github:mozilla/mozjpeg/v3.3.1";
|
|
||||||
flake = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
outputs =
|
|
||||||
{
|
|
||||||
self,
|
|
||||||
nixpkgs,
|
|
||||||
flake-utils,
|
|
||||||
mozjpeg-src,
|
|
||||||
}:
|
|
||||||
flake-utils.lib.eachDefaultSystem (
|
|
||||||
system:
|
|
||||||
let
|
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
|
||||||
inherit (pkgs) callPackage stdenv lib;
|
|
||||||
|
|
||||||
buildSquooshCppCodec = callPackage (import ../../nix/squoosh-cxx-builder) { };
|
|
||||||
squooshHelpers = callPackage (import ../../nix/squoosh-helpers) { };
|
|
||||||
inherit (squooshHelpers) forAllVariants mkRepoBinaryUpdater;
|
|
||||||
|
|
||||||
variants = {
|
|
||||||
base = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
src = lib.sources.sourceByRegex ./. [
|
|
||||||
"Makefile"
|
|
||||||
"enc(/.+)?"
|
|
||||||
];
|
|
||||||
|
|
||||||
builder = variantName: opts: {
|
|
||||||
mozjpeg-squoosh = buildSquooshCppCodec {
|
|
||||||
name = "mozjpeg-squoosh";
|
|
||||||
inherit src;
|
|
||||||
MOZJPEG = self.packages.${system}."mozjpeg-${variantName}";
|
|
||||||
|
|
||||||
dontConfigure = true;
|
|
||||||
decoder = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
mozjpeg = stdenv.mkDerivation {
|
|
||||||
name = "mozjpeg";
|
|
||||||
src = mozjpeg-src;
|
|
||||||
nativeBuildInputs = [
|
|
||||||
pkgs.autoconf
|
|
||||||
pkgs.automake
|
|
||||||
pkgs.libtool
|
|
||||||
pkgs.emscripten
|
|
||||||
pkgs.pkg-config
|
|
||||||
];
|
|
||||||
configurePhase = ''
|
|
||||||
# $HOME is required for Emscripten to work.
|
|
||||||
# See: https://nixos.org/manual/nixpkgs/stable/#emscripten
|
|
||||||
export HOME=$TMPDIR
|
|
||||||
autoreconf -ifv
|
|
||||||
emconfigure ./configure \
|
|
||||||
--disable-shared \
|
|
||||||
--without-turbojpeg \
|
|
||||||
--without-simd \
|
|
||||||
--without-arith-enc \
|
|
||||||
--without-arith-dec \
|
|
||||||
--with-build-date=squoosh \
|
|
||||||
--prefix=$out
|
|
||||||
'';
|
|
||||||
buildPhase = ''
|
|
||||||
export HOME=$TMPDIR
|
|
||||||
emmake make V=1 -j$(nproc) --trace
|
|
||||||
'';
|
|
||||||
installPhase = ''
|
|
||||||
make install
|
|
||||||
cp *.h $out/include
|
|
||||||
cp rdswitch.o $out/lib
|
|
||||||
'';
|
|
||||||
dontFixup = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
packageVariants = forAllVariants { inherit builder variants; };
|
|
||||||
in
|
|
||||||
|
|
||||||
mkRepoBinaryUpdater {
|
|
||||||
packages = packageVariants // {
|
|
||||||
default = packageVariants."mozjpeg-squoosh-base";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
4
codecs/mozjpeg/package-lock.json
generated
Normal file
4
codecs/mozjpeg/package-lock.json
generated
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "mozjpeg_enc",
|
||||||
|
"lockfileVersion": 1
|
||||||
|
}
|
||||||
5
codecs/mozjpeg/package.json
Normal file
5
codecs/mozjpeg/package.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"build": "../build-cpp.sh"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,239 +0,0 @@
|
|||||||
#include <emscripten/bind.h>
|
|
||||||
#include <emscripten/val.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <setjmp.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "jconfig.h"
|
|
||||||
#include "jpeglib.h"
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "cdjpeg.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace emscripten;
|
|
||||||
|
|
||||||
// MozJPEG doesn’t expose a numeric version, so I have to do some fun C macro
|
|
||||||
// hackery to turn it into a string. More details here:
|
|
||||||
// https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html
|
|
||||||
#define xstr(s) str(s)
|
|
||||||
#define str(s) #s
|
|
||||||
|
|
||||||
struct MozJpegOptions {
|
|
||||||
int quality;
|
|
||||||
bool baseline;
|
|
||||||
bool arithmetic;
|
|
||||||
bool progressive;
|
|
||||||
bool optimize_coding;
|
|
||||||
int smoothing;
|
|
||||||
int color_space;
|
|
||||||
int quant_table;
|
|
||||||
bool trellis_multipass;
|
|
||||||
bool trellis_opt_zero;
|
|
||||||
bool trellis_opt_table;
|
|
||||||
int trellis_loops;
|
|
||||||
bool auto_subsample;
|
|
||||||
int chroma_subsample;
|
|
||||||
bool separate_chroma_quality;
|
|
||||||
int chroma_quality;
|
|
||||||
};
|
|
||||||
|
|
||||||
int version() {
|
|
||||||
char buffer[] = xstr(MOZJPEG_VERSION);
|
|
||||||
int version = 0;
|
|
||||||
int last_index = 0;
|
|
||||||
for (int i = 0; i < strlen(buffer); i++) {
|
|
||||||
if (buffer[i] == '.') {
|
|
||||||
buffer[i] = '\0';
|
|
||||||
version = version << 8 | atoi(&buffer[last_index]);
|
|
||||||
buffer[i] = '.';
|
|
||||||
last_index = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
version = version << 8 | atoi(&buffer[last_index]);
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
|
||||||
|
|
||||||
val encode(std::string image_in, int image_width, int image_height, MozJpegOptions opts) {
|
|
||||||
uint8_t* image_buffer = (uint8_t*)image_in.c_str();
|
|
||||||
|
|
||||||
// The code below is basically the `write_JPEG_file` function from
|
|
||||||
// https://github.com/mozilla/mozjpeg/blob/master/example.c
|
|
||||||
// I just write to memory instead of a file.
|
|
||||||
|
|
||||||
/* Step 1: allocate and initialize JPEG compression object */
|
|
||||||
|
|
||||||
/* This struct contains the JPEG compression parameters and pointers to
|
|
||||||
* working space (which is allocated as needed by the JPEG library).
|
|
||||||
* It is possible to have several such structures, representing multiple
|
|
||||||
* compression/decompression processes, in existence at once. We refer
|
|
||||||
* to any one struct (and its associated working data) as a "JPEG object".
|
|
||||||
*/
|
|
||||||
jpeg_compress_struct cinfo;
|
|
||||||
/* This struct represents a JPEG error handler. It is declared separately
|
|
||||||
* because applications often want to supply a specialized error handler
|
|
||||||
* (see the second half of this file for an example). But here we just
|
|
||||||
* take the easy way out and use the standard error handler, which will
|
|
||||||
* print a message on stderr and call exit() if compression fails.
|
|
||||||
* Note that this struct must live as long as the main JPEG parameter
|
|
||||||
* struct, to avoid dangling-pointer problems.
|
|
||||||
*/
|
|
||||||
jpeg_error_mgr jerr;
|
|
||||||
/* We have to set up the error handler first, in case the initialization
|
|
||||||
* step fails. (Unlikely, but it could happen if you are out of memory.)
|
|
||||||
* This routine fills in the contents of struct jerr, and returns jerr's
|
|
||||||
* address which we place into the link field in cinfo.
|
|
||||||
*/
|
|
||||||
cinfo.err = jpeg_std_error(&jerr);
|
|
||||||
/* Now we can initialize the JPEG compression object. */
|
|
||||||
jpeg_create_compress(&cinfo);
|
|
||||||
|
|
||||||
/* Step 2: specify data destination (eg, a file) */
|
|
||||||
/* Note: steps 2 and 3 can be done in either order. */
|
|
||||||
|
|
||||||
/* Here we use the library-supplied code to send compressed data to a
|
|
||||||
* stdio stream. You can also write your own code to do something else.
|
|
||||||
* VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
|
|
||||||
* requires it in order to write binary files.
|
|
||||||
*/
|
|
||||||
// if ((outfile = fopen(filename, "wb")) == NULL) {
|
|
||||||
// fprintf(stderr, "can't open %s\n", filename);
|
|
||||||
// exit(1);
|
|
||||||
// }
|
|
||||||
uint8_t* output = nullptr;
|
|
||||||
unsigned long size = 0;
|
|
||||||
jpeg_mem_dest(&cinfo, &output, &size);
|
|
||||||
|
|
||||||
/* Step 3: set parameters for compression */
|
|
||||||
|
|
||||||
/* First we supply a description of the input image.
|
|
||||||
* Four fields of the cinfo struct must be filled in:
|
|
||||||
*/
|
|
||||||
cinfo.image_width = image_width; /* image width and height, in pixels */
|
|
||||||
cinfo.image_height = image_height;
|
|
||||||
cinfo.input_components = 4; /* # of color components per pixel */
|
|
||||||
cinfo.in_color_space = JCS_EXT_RGBA; /* colorspace of input image */
|
|
||||||
/* Now use the library's routine to set default compression parameters.
|
|
||||||
* (You must set at least cinfo.in_color_space before calling this,
|
|
||||||
* since the defaults depend on the source color space.)
|
|
||||||
*/
|
|
||||||
jpeg_set_defaults(&cinfo);
|
|
||||||
|
|
||||||
jpeg_set_colorspace(&cinfo, (J_COLOR_SPACE)opts.color_space);
|
|
||||||
|
|
||||||
if (opts.quant_table != -1) {
|
|
||||||
jpeg_c_set_int_param(&cinfo, JINT_BASE_QUANT_TBL_IDX, opts.quant_table);
|
|
||||||
}
|
|
||||||
|
|
||||||
cinfo.optimize_coding = opts.optimize_coding;
|
|
||||||
|
|
||||||
if (opts.arithmetic) {
|
|
||||||
cinfo.arith_code = TRUE;
|
|
||||||
cinfo.optimize_coding = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
cinfo.smoothing_factor = opts.smoothing;
|
|
||||||
|
|
||||||
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_USE_SCANS_IN_TRELLIS, opts.trellis_multipass);
|
|
||||||
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_EOB_OPT, opts.trellis_opt_zero);
|
|
||||||
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_TRELLIS_Q_OPT, opts.trellis_opt_table);
|
|
||||||
jpeg_c_set_int_param(&cinfo, JINT_TRELLIS_NUM_LOOPS, opts.trellis_loops);
|
|
||||||
jpeg_c_set_int_param(&cinfo, JINT_DC_SCAN_OPT_MODE, 0);
|
|
||||||
|
|
||||||
// A little hacky to build a string for this, but it means we can use
|
|
||||||
// set_quality_ratings which does some useful heuristic stuff.
|
|
||||||
std::string quality_str = std::to_string(opts.quality);
|
|
||||||
|
|
||||||
if (opts.separate_chroma_quality && opts.color_space == JCS_YCbCr) {
|
|
||||||
quality_str += "," + std::to_string(opts.chroma_quality);
|
|
||||||
}
|
|
||||||
|
|
||||||
char const* pqual = quality_str.c_str();
|
|
||||||
|
|
||||||
set_quality_ratings(&cinfo, (char*)pqual, opts.baseline);
|
|
||||||
|
|
||||||
if (!opts.auto_subsample && opts.color_space == JCS_YCbCr) {
|
|
||||||
cinfo.comp_info[0].h_samp_factor = opts.chroma_subsample;
|
|
||||||
cinfo.comp_info[0].v_samp_factor = opts.chroma_subsample;
|
|
||||||
|
|
||||||
if (opts.chroma_subsample > 2) {
|
|
||||||
// Otherwise encoding fails.
|
|
||||||
jpeg_c_set_int_param(&cinfo, JINT_DC_SCAN_OPT_MODE, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!opts.baseline && opts.progressive) {
|
|
||||||
jpeg_simple_progression(&cinfo);
|
|
||||||
} else {
|
|
||||||
cinfo.num_scans = 0;
|
|
||||||
cinfo.scan_info = NULL;
|
|
||||||
}
|
|
||||||
/* Step 4: Start compressor */
|
|
||||||
|
|
||||||
/* TRUE ensures that we will write a complete interchange-JPEG file.
|
|
||||||
* Pass TRUE unless you are very sure of what you're doing.
|
|
||||||
*/
|
|
||||||
jpeg_start_compress(&cinfo, TRUE);
|
|
||||||
|
|
||||||
/* Step 5: while (scan lines remain to be written) */
|
|
||||||
/* jpeg_write_scanlines(...); */
|
|
||||||
|
|
||||||
/* Here we use the library's state variable cinfo.next_scanline as the
|
|
||||||
* loop counter, so that we don't have to keep track ourselves.
|
|
||||||
* To keep things simple, we pass one scanline per call; you can pass
|
|
||||||
* more if you wish, though.
|
|
||||||
*/
|
|
||||||
int row_stride = image_width * 4; /* JSAMPLEs per row in image_buffer */
|
|
||||||
|
|
||||||
while (cinfo.next_scanline < cinfo.image_height) {
|
|
||||||
/* jpeg_write_scanlines expects an array of pointers to scanlines.
|
|
||||||
* Here the array is only one element long, but you could pass
|
|
||||||
* more than one scanline at a time if that's more convenient.
|
|
||||||
*/
|
|
||||||
|
|
||||||
JSAMPROW row_pointer =
|
|
||||||
&image_buffer[cinfo.next_scanline * row_stride]; /* pointer to JSAMPLE row[s] */
|
|
||||||
(void)jpeg_write_scanlines(&cinfo, &row_pointer, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Step 6: Finish compression */
|
|
||||||
|
|
||||||
jpeg_finish_compress(&cinfo);
|
|
||||||
|
|
||||||
/* Step 7: release JPEG compression object */
|
|
||||||
|
|
||||||
auto js_result = Uint8Array.new_(typed_memory_view(size, output));
|
|
||||||
|
|
||||||
/* This is an important step since it will release a good deal of memory. */
|
|
||||||
jpeg_destroy_compress(&cinfo);
|
|
||||||
free(output);
|
|
||||||
|
|
||||||
/* And we're done! */
|
|
||||||
return js_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
|
||||||
value_object<MozJpegOptions>("MozJpegOptions")
|
|
||||||
.field("quality", &MozJpegOptions::quality)
|
|
||||||
.field("baseline", &MozJpegOptions::baseline)
|
|
||||||
.field("arithmetic", &MozJpegOptions::arithmetic)
|
|
||||||
.field("progressive", &MozJpegOptions::progressive)
|
|
||||||
.field("optimize_coding", &MozJpegOptions::optimize_coding)
|
|
||||||
.field("smoothing", &MozJpegOptions::smoothing)
|
|
||||||
.field("color_space", &MozJpegOptions::color_space)
|
|
||||||
.field("quant_table", &MozJpegOptions::quant_table)
|
|
||||||
.field("trellis_multipass", &MozJpegOptions::trellis_multipass)
|
|
||||||
.field("trellis_opt_zero", &MozJpegOptions::trellis_opt_zero)
|
|
||||||
.field("trellis_opt_table", &MozJpegOptions::trellis_opt_table)
|
|
||||||
.field("trellis_loops", &MozJpegOptions::trellis_loops)
|
|
||||||
.field("chroma_subsample", &MozJpegOptions::chroma_subsample)
|
|
||||||
.field("auto_subsample", &MozJpegOptions::auto_subsample)
|
|
||||||
.field("separate_chroma_quality", &MozJpegOptions::separate_chroma_quality)
|
|
||||||
.field("chroma_quality", &MozJpegOptions::chroma_quality);
|
|
||||||
|
|
||||||
function("version", &version);
|
|
||||||
function("encode", &encode);
|
|
||||||
}
|
|
||||||
37
codecs/mozjpeg/wasm_build/enc/mozjpeg_enc.d.ts
vendored
37
codecs/mozjpeg/wasm_build/enc/mozjpeg_enc.d.ts
vendored
@@ -1,37 +0,0 @@
|
|||||||
export const enum MozJpegColorSpace {
|
|
||||||
GRAYSCALE = 1,
|
|
||||||
RGB,
|
|
||||||
YCbCr,
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EncodeOptions {
|
|
||||||
quality: number;
|
|
||||||
baseline: boolean;
|
|
||||||
arithmetic: boolean;
|
|
||||||
progressive: boolean;
|
|
||||||
optimize_coding: boolean;
|
|
||||||
smoothing: number;
|
|
||||||
color_space: MozJpegColorSpace;
|
|
||||||
quant_table: number;
|
|
||||||
trellis_multipass: boolean;
|
|
||||||
trellis_opt_zero: boolean;
|
|
||||||
trellis_opt_table: boolean;
|
|
||||||
trellis_loops: number;
|
|
||||||
auto_subsample: boolean;
|
|
||||||
chroma_subsample: number;
|
|
||||||
separate_chroma_quality: boolean;
|
|
||||||
chroma_quality: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MozJPEGModule extends EmscriptenWasm.Module {
|
|
||||||
encode(
|
|
||||||
data: BufferSource,
|
|
||||||
width: number,
|
|
||||||
height: number,
|
|
||||||
options: EncodeOptions,
|
|
||||||
): Uint8Array;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<MozJPEGModule>;
|
|
||||||
|
|
||||||
export default moduleFactory;
|
|
||||||
16
codecs/mozjpeg/wasm_build/enc/mozjpeg_enc.js
generated
16
codecs/mozjpeg/wasm_build/enc/mozjpeg_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
115
codecs/resize/flake.lock
generated
115
codecs/resize/flake.lock
generated
@@ -1,115 +0,0 @@
|
|||||||
{
|
|
||||||
"nodes": {
|
|
||||||
"fenix": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": "nixpkgs",
|
|
||||||
"rust-analyzer-src": "rust-analyzer-src"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1723616992,
|
|
||||||
"narHash": "sha256-jDHYfEECzFwZm4huz7AbPjlH3jJ4/2ns9PddtFA5XMY=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "fenix",
|
|
||||||
"rev": "7bad6c7ff73b784a9c7de9147626c8d5d5072809",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "fenix",
|
|
||||||
"rev": "7bad6c7ff73b784a9c7de9147626c8d5d5072809",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1710146030,
|
|
||||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1725432240,
|
|
||||||
"narHash": "sha256-+yj+xgsfZaErbfYM3T+QvEE2hU7UuE+Jf0fJCJ8uPS0=",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "ad416d066ca1222956472ab7d0555a6946746a80",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nixos",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1717179513,
|
|
||||||
"narHash": "sha256-vboIEwIQojofItm2xGCdZCzW96U85l9nDW3ifMuAIdM=",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "63dacb46bf939521bdc93981b4cbb7ecb58427a0",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nixos",
|
|
||||||
"ref": "24.05",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"fenix": "fenix",
|
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"nixpkgs": "nixpkgs_2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rust-analyzer-src": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1725548942,
|
|
||||||
"narHash": "sha256-ZnF5MaOAeiiKIATYN4rrqNsnhSQOQ+Hvfg0mHLvN04Y=",
|
|
||||||
"owner": "rust-lang",
|
|
||||||
"repo": "rust-analyzer",
|
|
||||||
"rev": "124c7482167ff6eea4f7663c0be87ea568ccd8c6",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "rust-lang",
|
|
||||||
"ref": "nightly",
|
|
||||||
"repo": "rust-analyzer",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": "root",
|
|
||||||
"version": 7
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
{
|
|
||||||
inputs = {
|
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/24.05";
|
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
|
||||||
fenix.url = "github:nix-community/fenix/7bad6c7ff73b784a9c7de9147626c8d5d5072809";
|
|
||||||
};
|
|
||||||
outputs =
|
|
||||||
{
|
|
||||||
self,
|
|
||||||
nixpkgs,
|
|
||||||
flake-utils,
|
|
||||||
fenix,
|
|
||||||
}:
|
|
||||||
flake-utils.lib.eachDefaultSystem (
|
|
||||||
system:
|
|
||||||
let
|
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
|
||||||
inherit (pkgs) callPackage lib;
|
|
||||||
|
|
||||||
buildSquooshRustCodec = callPackage (import ../../nix/squoosh-rust-builder) {
|
|
||||||
fenix = fenix.packages.${system};
|
|
||||||
};
|
|
||||||
squooshHelpers = callPackage (import ../../nix/squoosh-helpers) { };
|
|
||||||
inherit (squooshHelpers) mkRepoBinaryUpdater forAllVariants;
|
|
||||||
|
|
||||||
variants = {
|
|
||||||
base = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
src = lib.sources.sourceByRegex ./. [
|
|
||||||
"Cargo.*"
|
|
||||||
"build\.rs"
|
|
||||||
"src(/.+)?"
|
|
||||||
];
|
|
||||||
|
|
||||||
builder = variantName: opts: {
|
|
||||||
resize-squoosh = buildSquooshRustCodec {
|
|
||||||
name = "resize-squoosh";
|
|
||||||
inherit src;
|
|
||||||
cargoLock = {
|
|
||||||
lockFile = "${src}/Cargo.lock";
|
|
||||||
};
|
|
||||||
wasmBindgen = {
|
|
||||||
sha256 = "sha256-HTElSB76gqCpDu8S0ZJlfd/S4ftMrbwxFgJM9OXBRz8=";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
packageVariants = forAllVariants { inherit builder variants; };
|
|
||||||
in
|
|
||||||
mkRepoBinaryUpdater {
|
|
||||||
packages = packageVariants // {
|
|
||||||
default = packageVariants."resize-squoosh-base";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
4
codecs/resize/package-lock.json
generated
Normal file
4
codecs/resize/package-lock.json
generated
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "resize",
|
||||||
|
"lockfileVersion": 1
|
||||||
|
}
|
||||||
6
codecs/resize/package.json
Normal file
6
codecs/resize/package.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "resize",
|
||||||
|
"scripts": {
|
||||||
|
"build": "../build-rust.sh"
|
||||||
|
}
|
||||||
|
}
|
||||||
15
codecs/resize/pkg/package.json
Normal file
15
codecs/resize/pkg/package.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "squoosh-resize",
|
||||||
|
"collaborators": [
|
||||||
|
"Surma <surma@surma.link>"
|
||||||
|
],
|
||||||
|
"version": "0.1.0",
|
||||||
|
"files": [
|
||||||
|
"squoosh_resize_bg.wasm",
|
||||||
|
"squoosh_resize.js",
|
||||||
|
"squoosh_resize.d.ts"
|
||||||
|
],
|
||||||
|
"module": "squoosh_resize.js",
|
||||||
|
"types": "squoosh_resize.d.ts",
|
||||||
|
"sideEffects": false
|
||||||
|
}
|
||||||
0
codecs/resize/wasm_build/squoosh_resize.d.ts → codecs/resize/pkg/squoosh_resize.d.ts
generated
vendored
0
codecs/resize/wasm_build/squoosh_resize.d.ts → codecs/resize/pkg/squoosh_resize.d.ts
generated
vendored
BIN
codecs/resize/pkg/squoosh_resize_bg.wasm
Normal file
BIN
codecs/resize/pkg/squoosh_resize_bg.wasm
Normal file
Binary file not shown.
Binary file not shown.
115
codecs/rotate/flake.lock
generated
115
codecs/rotate/flake.lock
generated
@@ -1,115 +0,0 @@
|
|||||||
{
|
|
||||||
"nodes": {
|
|
||||||
"fenix": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": "nixpkgs",
|
|
||||||
"rust-analyzer-src": "rust-analyzer-src"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1723616992,
|
|
||||||
"narHash": "sha256-jDHYfEECzFwZm4huz7AbPjlH3jJ4/2ns9PddtFA5XMY=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "fenix",
|
|
||||||
"rev": "7bad6c7ff73b784a9c7de9147626c8d5d5072809",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "fenix",
|
|
||||||
"rev": "7bad6c7ff73b784a9c7de9147626c8d5d5072809",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1710146030,
|
|
||||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1723362943,
|
|
||||||
"narHash": "sha256-dFZRVSgmJkyM0bkPpaYRtG/kRMRTorUIDj8BxoOt1T4=",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "a58bc8ad779655e790115244571758e8de055e3d",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nixos",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1717179513,
|
|
||||||
"narHash": "sha256-vboIEwIQojofItm2xGCdZCzW96U85l9nDW3ifMuAIdM=",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "63dacb46bf939521bdc93981b4cbb7ecb58427a0",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nixos",
|
|
||||||
"ref": "24.05",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"fenix": "fenix",
|
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"nixpkgs": "nixpkgs_2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rust-analyzer-src": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1723561310,
|
|
||||||
"narHash": "sha256-a3KMMsIDvdo+ClLabh5wfJoa17YTSvy2wDLb8yZCXvc=",
|
|
||||||
"owner": "rust-lang",
|
|
||||||
"repo": "rust-analyzer",
|
|
||||||
"rev": "78c2bdce860dbd996a8083224d01a96660dd6a15",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "rust-lang",
|
|
||||||
"ref": "nightly",
|
|
||||||
"repo": "rust-analyzer",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": "root",
|
|
||||||
"version": 7
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
{
|
|
||||||
inputs = {
|
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/24.05";
|
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
|
||||||
fenix.url = "github:nix-community/fenix/7bad6c7ff73b784a9c7de9147626c8d5d5072809";
|
|
||||||
};
|
|
||||||
outputs =
|
|
||||||
{
|
|
||||||
self,
|
|
||||||
nixpkgs,
|
|
||||||
flake-utils,
|
|
||||||
fenix,
|
|
||||||
}:
|
|
||||||
flake-utils.lib.eachDefaultSystem (
|
|
||||||
system:
|
|
||||||
let
|
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
|
||||||
inherit (pkgs) callPackage lib;
|
|
||||||
|
|
||||||
buildSquooshRustCodec = callPackage (import ../../nix/squoosh-rust-builder) {
|
|
||||||
fenix = fenix.packages.${system};
|
|
||||||
};
|
|
||||||
squooshHelpers = callPackage (import ../../nix/squoosh-helpers) { };
|
|
||||||
inherit (squooshHelpers) mkRepoBinaryUpdater forAllVariants;
|
|
||||||
|
|
||||||
variants = {
|
|
||||||
base = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
src = lib.sources.sourceByRegex ./. [
|
|
||||||
"Cargo\.*"
|
|
||||||
".*\.rs"
|
|
||||||
];
|
|
||||||
|
|
||||||
builder = variantName: opts: {
|
|
||||||
rotate-squoosh = buildSquooshRustCodec {
|
|
||||||
name = "rotate-squoosh";
|
|
||||||
inherit src;
|
|
||||||
cargoLock = {
|
|
||||||
lockFile = "${src}/Cargo.lock";
|
|
||||||
};
|
|
||||||
wasmBindgen = null;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
packageVariants = forAllVariants { inherit builder variants; };
|
|
||||||
in
|
|
||||||
mkRepoBinaryUpdater {
|
|
||||||
packages = packageVariants // {
|
|
||||||
default = packageVariants."rotate-squoosh-base";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
BIN
codecs/rotate/rotate.wasm
Executable file
BIN
codecs/rotate/rotate.wasm
Executable file
Binary file not shown.
Binary file not shown.
@@ -1,7 +1,11 @@
|
|||||||
|
CODEC_URL = https://github.com/webmproject/libwebp/archive/d2e245ea9e959a5a79e1db0ed2085206947e98f2.tar.gz
|
||||||
|
CODEC_DIR = node_modules/libwebp
|
||||||
|
CODEC_BUILD_ROOT := $(CODEC_DIR)/build
|
||||||
|
CODEC_BASELINE_BUILD_DIR := $(CODEC_BUILD_ROOT)/baseline
|
||||||
|
CODEC_SIMD_BUILD_DIR := $(CODEC_BUILD_ROOT)/simd
|
||||||
ENVIRONMENT = worker
|
ENVIRONMENT = worker
|
||||||
|
|
||||||
# OUT_JS = enc/webp_enc.js enc/webp_enc_simd.js dec/webp_dec.js
|
OUT_JS = enc/webp_enc.js enc/webp_enc_simd.js dec/webp_dec.js enc/webp_node_enc.js dec/webp_node_dec.js
|
||||||
OUT_JS = enc/webp_enc.js dec/webp_dec.js
|
|
||||||
OUT_WASM := $(OUT_JS:.js=.wasm)
|
OUT_WASM := $(OUT_JS:.js=.wasm)
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
@@ -11,41 +15,54 @@ all: $(OUT_JS)
|
|||||||
# Define dependencies for all variations of build artifacts.
|
# Define dependencies for all variations of build artifacts.
|
||||||
$(filter enc/%,$(OUT_JS)): enc/webp_enc.o
|
$(filter enc/%,$(OUT_JS)): enc/webp_enc.o
|
||||||
$(filter dec/%,$(OUT_JS)): dec/webp_dec.o
|
$(filter dec/%,$(OUT_JS)): dec/webp_dec.o
|
||||||
# enc/webp_enc.js dec/webp_dec.js: $(CODEC_BASELINE_BUILD_DIR)/libwebp.a
|
enc/webp_node_enc.js dec/webp_node_dec.js: ENVIRONMENT = node
|
||||||
# enc/webp_enc_simd.js: $(CODEC_SIMD_BUILD_DIR)/libwebp.a
|
enc/webp_node_enc.js dec/webp_node_dec.js: $(CODEC_BASELINE_BUILD_DIR)/libwebp.a
|
||||||
|
enc/webp_enc.js dec/webp_dec.js: $(CODEC_BASELINE_BUILD_DIR)/libwebp.a
|
||||||
LIBWEBP_FLAGS = -I${WEBP}/include -L${WEBP}/lib -lwebp
|
enc/webp_enc_simd.js: $(CODEC_SIMD_BUILD_DIR)/libwebp.a
|
||||||
|
|
||||||
$(OUT_JS):
|
$(OUT_JS):
|
||||||
$(LD) \
|
$(LD) \
|
||||||
-O3 \
|
|
||||||
-flto \
|
|
||||||
-std=c++17 \
|
|
||||||
-s FILESYSTEM=0 \
|
|
||||||
-s PTHREAD_POOL_SIZE=navigator.hardwareConcurrency \
|
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
|
||||||
-s TEXTDECODER=2 \
|
|
||||||
-s NODEJS_CATCH_EXIT=0 -s NODEJS_CATCH_REJECTION=0 \
|
|
||||||
$(LIBWEBP_FLAGS) \
|
|
||||||
$(LDFLAGS) \
|
$(LDFLAGS) \
|
||||||
-lembind \
|
--bind \
|
||||||
-s ENVIRONMENT=$(ENVIRONMENT) \
|
-s ENVIRONMENT=$(ENVIRONMENT) \
|
||||||
-s EXPORT_ES6=1 \
|
-s EXPORT_ES6=1 \
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$+
|
$+
|
||||||
|
|
||||||
%.o: %.cpp
|
%.o: %.cpp $(CODEC_DIR)/CMakeLists.txt
|
||||||
$(CXX) -c \
|
$(CXX) -c \
|
||||||
-O3 \
|
|
||||||
-flto \
|
|
||||||
-std=c++17 \
|
|
||||||
-s FILESYSTEM=0 \
|
|
||||||
-s PTHREAD_POOL_SIZE=navigator.hardwareConcurrency \
|
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
|
||||||
-s TEXTDECODER=2 \
|
|
||||||
-s NODEJS_CATCH_EXIT=0 -s NODEJS_CATCH_REJECTION=0 \
|
|
||||||
$(LIBWEBP_FLAGS) \
|
|
||||||
$(CXXFLAGS) \
|
$(CXXFLAGS) \
|
||||||
|
-I $(CODEC_DIR) \
|
||||||
-o $@ \
|
-o $@ \
|
||||||
$<
|
$<
|
||||||
|
|
||||||
|
%/libwebp.a: %/Makefile
|
||||||
|
$(MAKE) -C $(@D)
|
||||||
|
|
||||||
|
# Enable SIMD on a SIMD build.
|
||||||
|
$(CODEC_SIMD_BUILD_DIR)/Makefile: CMAKE_FLAGS+=-DWEBP_ENABLE_SIMD=1
|
||||||
|
|
||||||
|
%/Makefile: $(CODEC_DIR)/CMakeLists.txt
|
||||||
|
emcmake cmake \
|
||||||
|
$(CMAKE_FLAGS) \
|
||||||
|
-DCMAKE_DISABLE_FIND_PACKAGE_Threads=1 \
|
||||||
|
-DWEBP_BUILD_ANIM_UTILS=0 \
|
||||||
|
-DWEBP_BUILD_CWEBP=0 \
|
||||||
|
-DWEBP_BUILD_DWEBP=0 \
|
||||||
|
-DWEBP_BUILD_GIF2WEBP=0 \
|
||||||
|
-DWEBP_BUILD_IMG2WEBP=0 \
|
||||||
|
-DWEBP_BUILD_VWEBP=0 \
|
||||||
|
-DWEBP_BUILD_WEBPINFO=0 \
|
||||||
|
-DWEBP_BUILD_WEBPMUX=0 \
|
||||||
|
-DWEBP_BUILD_EXTRAS=0 \
|
||||||
|
-B $(@D) \
|
||||||
|
$(<D)
|
||||||
|
|
||||||
|
$(CODEC_DIR)/CMakeLists.txt:
|
||||||
|
mkdir -p $(CODEC_DIR)
|
||||||
|
curl -sL $(CODEC_URL) | tar xz --strip 1 -C $(CODEC_DIR)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(OUT_JS) $(OUT_WASM)
|
||||||
|
$(MAKE) -C $(CODEC_BASELINE_BUILD_DIR) clean
|
||||||
|
$(MAKE) -C $(CODEC_SIMD_BUILD_DIR) clean
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include "emscripten/bind.h"
|
#include "emscripten/bind.h"
|
||||||
#include "emscripten/val.h"
|
#include "emscripten/val.h"
|
||||||
#include "webp/decode.h"
|
#include "src/webp/decode.h"
|
||||||
#include "webp/demux.h"
|
#include "src/webp/demux.h"
|
||||||
|
|
||||||
using namespace emscripten;
|
using namespace emscripten;
|
||||||
|
|
||||||
|
|||||||
16
codecs/webp/dec/webp_dec.js
generated
Normal file
16
codecs/webp/dec/webp_dec.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/webp/dec/webp_dec.wasm
Executable file
BIN
codecs/webp/dec/webp_dec.wasm
Executable file
Binary file not shown.
16
codecs/webp/dec/webp_node_dec.js
generated
Normal file
16
codecs/webp/dec/webp_node_dec.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/webp/dec/webp_node_dec.wasm
Executable file
BIN
codecs/webp/dec/webp_node_dec.wasm
Executable file
Binary file not shown.
@@ -3,7 +3,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include "webp/encode.h"
|
#include "src/webp/encode.h"
|
||||||
|
|
||||||
using namespace emscripten;
|
using namespace emscripten;
|
||||||
|
|
||||||
|
|||||||
16
codecs/webp/enc/webp_enc.js
generated
Normal file
16
codecs/webp/enc/webp_enc.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/webp/enc/webp_enc.wasm
Executable file
BIN
codecs/webp/enc/webp_enc.wasm
Executable file
Binary file not shown.
16
codecs/webp/enc/webp_enc_simd.js
generated
Normal file
16
codecs/webp/enc/webp_enc_simd.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/webp/enc/webp_enc_simd.wasm
Executable file
BIN
codecs/webp/enc/webp_enc_simd.wasm
Executable file
Binary file not shown.
16
codecs/webp/enc/webp_node_enc.js
generated
Normal file
16
codecs/webp/enc/webp_node_enc.js
generated
Normal file
File diff suppressed because one or more lines are too long
BIN
codecs/webp/enc/webp_node_enc.wasm
Executable file
BIN
codecs/webp/enc/webp_node_enc.wasm
Executable file
Binary file not shown.
79
codecs/webp/flake.lock
generated
79
codecs/webp/flake.lock
generated
@@ -1,79 +0,0 @@
|
|||||||
{
|
|
||||||
"nodes": {
|
|
||||||
"flake-utils": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1710146030,
|
|
||||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1717179513,
|
|
||||||
"narHash": "sha256-vboIEwIQojofItm2xGCdZCzW96U85l9nDW3ifMuAIdM=",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "63dacb46bf939521bdc93981b4cbb7ecb58427a0",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nixos",
|
|
||||||
"ref": "24.05",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"nixpkgs": "nixpkgs",
|
|
||||||
"webp-src": "webp-src"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"webp-src": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1606186400,
|
|
||||||
"narHash": "sha256-Emwd2wFbBONurMXSp8iwtwnSHgw4vcqBpuG0gyhZjFA=",
|
|
||||||
"owner": "webmproject",
|
|
||||||
"repo": "libwebp",
|
|
||||||
"rev": "d2e245ea9e959a5a79e1db0ed2085206947e98f2",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "webmproject",
|
|
||||||
"repo": "libwebp",
|
|
||||||
"rev": "d2e245ea9e959a5a79e1db0ed2085206947e98f2",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": "root",
|
|
||||||
"version": 7
|
|
||||||
}
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
{
|
|
||||||
inputs = {
|
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/24.05";
|
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
|
||||||
webp-src = {
|
|
||||||
url = "github:webmproject/libwebp/d2e245ea9e959a5a79e1db0ed2085206947e98f2";
|
|
||||||
flake = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
outputs =
|
|
||||||
{
|
|
||||||
self,
|
|
||||||
nixpkgs,
|
|
||||||
flake-utils,
|
|
||||||
webp-src,
|
|
||||||
}:
|
|
||||||
flake-utils.lib.eachDefaultSystem (
|
|
||||||
system:
|
|
||||||
let
|
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
|
||||||
inherit (pkgs) lib stdenv callPackage;
|
|
||||||
buildSquooshCppCodec = callPackage (import ../../nix/squoosh-cxx-builder) { };
|
|
||||||
squooshHelpers = callPackage (import ../../nix/squoosh-helpers) { };
|
|
||||||
inherit (squooshHelpers) forAllVariants mkRepoBinaryUpdater;
|
|
||||||
|
|
||||||
variants = {
|
|
||||||
base = {
|
|
||||||
simd = false;
|
|
||||||
};
|
|
||||||
simd = {
|
|
||||||
simd = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
src = lib.sources.sourceByRegex ./. [
|
|
||||||
"Makefile"
|
|
||||||
"enc(/.+)?"
|
|
||||||
"dec(/.+)?"
|
|
||||||
];
|
|
||||||
|
|
||||||
builder =
|
|
||||||
variantName:
|
|
||||||
{ simd }:
|
|
||||||
{
|
|
||||||
"webp-squoosh" = buildSquooshCppCodec {
|
|
||||||
name = "webp-squoosh-${variantName}";
|
|
||||||
inherit src;
|
|
||||||
nativeBuildInputs = [
|
|
||||||
pkgs.emscripten
|
|
||||||
self.packages.${system}."webp-${variantName}"
|
|
||||||
];
|
|
||||||
WEBP = self.packages.${system}."webp-${variantName}";
|
|
||||||
dontConfigure = true;
|
|
||||||
buildPhase = ''
|
|
||||||
export HOME=$TMPDIR
|
|
||||||
emmake make -j$(nproc)
|
|
||||||
'';
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out
|
|
||||||
cp -r enc dec $out
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"webp" = stdenv.mkDerivation {
|
|
||||||
name = "webp-${variantName}";
|
|
||||||
src = webp-src;
|
|
||||||
nativeBuildInputs = [
|
|
||||||
pkgs.emscripten
|
|
||||||
pkgs.cmake
|
|
||||||
];
|
|
||||||
configurePhase = ''
|
|
||||||
# $HOME is required for Emscripten to work.
|
|
||||||
# See: https://nixos.org/manual/nixpkgs/stable/#emscripten
|
|
||||||
export HOME=$TMPDIR
|
|
||||||
mkdir -p $TMPDIR/build
|
|
||||||
emcmake cmake \
|
|
||||||
-DCMAKE_INSTALL_PREFIX=$out \
|
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_Threads=1 \
|
|
||||||
-DWEBP_BUILD_ANIM_UTILS=0 \
|
|
||||||
-DWEBP_BUILD_CWEBP=0 \
|
|
||||||
-DWEBP_BUILD_DWEBP=0 \
|
|
||||||
-DWEBP_BUILD_GIF2WEBP=0 \
|
|
||||||
-DWEBP_BUILD_IMG2WEBP=0 \
|
|
||||||
-DWEBP_BUILD_VWEBP=0 \
|
|
||||||
-DWEBP_BUILD_WEBPINFO=0 \
|
|
||||||
-DWEBP_BUILD_WEBPMUX=0 \
|
|
||||||
-DWEBP_BUILD_EXTRAS=0 \
|
|
||||||
${if simd then "-DWEBP_ENABLE_SIMD=1" else ""} \
|
|
||||||
-B $TMPDIR/build \
|
|
||||||
.
|
|
||||||
'';
|
|
||||||
buildPhase = ''
|
|
||||||
export HOME=$TMPDIR
|
|
||||||
cd $TMPDIR/build
|
|
||||||
emmake make V=1 -j$(nproc) --trace
|
|
||||||
'';
|
|
||||||
installPhase = ''
|
|
||||||
cd $TMPDIR/build
|
|
||||||
make install
|
|
||||||
'';
|
|
||||||
dontFixup = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
packageVariants = forAllVariants { inherit builder variants; };
|
|
||||||
|
|
||||||
defaultPackage =
|
|
||||||
let
|
|
||||||
copyAllCodecs = lib.concatLines (
|
|
||||||
lib.mapAttrsToList (
|
|
||||||
name: _: "cp -r ${packageVariants."webp-squoosh-${name}"} $out/${name}"
|
|
||||||
) variants
|
|
||||||
);
|
|
||||||
in
|
|
||||||
stdenv.mkDerivation {
|
|
||||||
name = "all-variants";
|
|
||||||
phases = [ "buildPhase" ];
|
|
||||||
buildPhase = ''
|
|
||||||
mkdir -p $out;
|
|
||||||
${copyAllCodecs}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in
|
|
||||||
|
|
||||||
mkRepoBinaryUpdater {
|
|
||||||
packages = packageVariants // {
|
|
||||||
default = defaultPackage;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# WebP decoder
|
|
||||||
|
|
||||||
- Source: <https://github.com/webmproject/libwebp>
|
|
||||||
- Version: v1.0.2
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
See `example.html`
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### `int version()`
|
|
||||||
|
|
||||||
Returns the version of libwebp as a number. va.b.c is encoded as 0x0a0b0c
|
|
||||||
|
|
||||||
### `RawImage decode(std::string buffer)`
|
|
||||||
|
|
||||||
Decodes the given webp buffer into raw RGBA. `RawImage` is a class with 3 fields: `buffer`, `width`, and `height`.
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<script src='webp_dec.js'></script>
|
|
||||||
<script>
|
|
||||||
async function loadFile(src) {
|
|
||||||
const resp = await fetch(src);
|
|
||||||
return await resp.arrayBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
webp_dec().then(async module => {
|
|
||||||
console.log('Version:', module.version().toString(16));
|
|
||||||
const image = await loadFile('../../example.webp');
|
|
||||||
const imageData = module.decode(image);
|
|
||||||
const canvas = document.createElement('canvas');
|
|
||||||
canvas.width = imageData.width;
|
|
||||||
canvas.height = imageData.height;
|
|
||||||
document.body.appendChild(canvas);
|
|
||||||
const ctx = canvas.getContext('2d');
|
|
||||||
ctx.putImageData(imageData, 0, 0);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#include <string>
|
|
||||||
#include "emscripten/bind.h"
|
|
||||||
#include "emscripten/val.h"
|
|
||||||
#include "webp/decode.h"
|
|
||||||
#include "webp/demux.h"
|
|
||||||
|
|
||||||
using namespace emscripten;
|
|
||||||
|
|
||||||
int version() {
|
|
||||||
return WebPGetDecoderVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");
|
|
||||||
thread_local const val ImageData = val::global("ImageData");
|
|
||||||
|
|
||||||
val decode(std::string buffer) {
|
|
||||||
int width, height;
|
|
||||||
std::unique_ptr<uint8_t[]> rgba(
|
|
||||||
WebPDecodeRGBA((const uint8_t*)buffer.c_str(), buffer.size(), &width, &height));
|
|
||||||
return rgba ? ImageData.new_(
|
|
||||||
Uint8ClampedArray.new_(typed_memory_view(width * height * 4, rgba.get())),
|
|
||||||
width, height)
|
|
||||||
: val::null();
|
|
||||||
}
|
|
||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
|
||||||
function("decode", &decode);
|
|
||||||
function("version", &version);
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
export interface WebPModule extends EmscriptenWasm.Module {
|
|
||||||
decode(data: BufferSource): ImageData | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<WebPModule>;
|
|
||||||
|
|
||||||
export default moduleFactory;
|
|
||||||
16
codecs/webp/wasm_build/base/dec/webp_dec.js
generated
16
codecs/webp/wasm_build/base/dec/webp_dec.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1,22 +0,0 @@
|
|||||||
# WebP encoder
|
|
||||||
|
|
||||||
- Source: <https://github.com/webmproject/libwebp>
|
|
||||||
- Version: v1.0.2
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
- Docker
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
See `example.html`
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### `int version()`
|
|
||||||
|
|
||||||
Returns the version of libwebp as a number. va.b.c is encoded as 0x0a0b0c
|
|
||||||
|
|
||||||
### `UInt8Array encode(uint8_t* image_buffer, int image_width, int image_height, WebPConfig config)`
|
|
||||||
|
|
||||||
Encodes the given image with given dimension to WebP.
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<script src='webp_enc.js'></script>
|
|
||||||
<script>
|
|
||||||
async function loadImage(src) {
|
|
||||||
// Load image
|
|
||||||
const img = document.createElement('img');
|
|
||||||
img.src = src;
|
|
||||||
await new Promise(resolve => img.onload = resolve);
|
|
||||||
// Make canvas same size as image
|
|
||||||
const canvas = document.createElement('canvas');
|
|
||||||
[canvas.width, canvas.height] = [img.width, img.height];
|
|
||||||
// Draw image onto canvas
|
|
||||||
const ctx = canvas.getContext('2d');
|
|
||||||
ctx.drawImage(img, 0, 0);
|
|
||||||
return ctx.getImageData(0, 0, img.width, img.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
webp_enc().then(async module => {
|
|
||||||
console.log('Version:', module.version().toString(16));
|
|
||||||
const image = await loadImage('../../example.png');
|
|
||||||
const result = module.encode(image.data, image.width, image.height, {
|
|
||||||
quality: 75,
|
|
||||||
target_size: 0,
|
|
||||||
target_PSNR: 0,
|
|
||||||
method: 4,
|
|
||||||
sns_strength: 50,
|
|
||||||
filter_strength: 60,
|
|
||||||
filter_sharpness: 0,
|
|
||||||
filter_type: 1,
|
|
||||||
partitions: 0,
|
|
||||||
segments: 4,
|
|
||||||
pass: 1,
|
|
||||||
show_compressed: 0,
|
|
||||||
preprocessing: 0,
|
|
||||||
autofilter: 0,
|
|
||||||
partition_limit: 0,
|
|
||||||
alpha_compression: 1,
|
|
||||||
alpha_filtering: 1,
|
|
||||||
alpha_quality: 100,
|
|
||||||
lossless: 0,
|
|
||||||
exact: 0,
|
|
||||||
image_hint: 0,
|
|
||||||
emulate_jpeg_size: 0,
|
|
||||||
thread_level: 0,
|
|
||||||
low_memory: 0,
|
|
||||||
near_lossless: 100,
|
|
||||||
use_delta_palette: 0,
|
|
||||||
use_sharp_yuv: 0,
|
|
||||||
});
|
|
||||||
console.log('size', result.length);
|
|
||||||
const blob = new Blob([result], {type: 'image/webp'});
|
|
||||||
|
|
||||||
const blobURL = URL.createObjectURL(blob);
|
|
||||||
const img = document.createElement('img');
|
|
||||||
img.src = blobURL;
|
|
||||||
document.body.appendChild(img);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
#include <emscripten/bind.h>
|
|
||||||
#include <emscripten/val.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include "webp/encode.h"
|
|
||||||
|
|
||||||
using namespace emscripten;
|
|
||||||
|
|
||||||
int version() {
|
|
||||||
return WebPGetEncoderVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
|
||||||
|
|
||||||
val encode(std::string img, int width, int height, WebPConfig config) {
|
|
||||||
auto img_in = (uint8_t*)img.c_str();
|
|
||||||
|
|
||||||
// A lot of this is duplicated from Encode in picture_enc.c
|
|
||||||
WebPPicture pic;
|
|
||||||
WebPMemoryWriter wrt;
|
|
||||||
int ok;
|
|
||||||
|
|
||||||
if (!WebPPictureInit(&pic)) {
|
|
||||||
// shouldn't happen, except if system installation is broken
|
|
||||||
return val::null();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow quality to go higher than 0.
|
|
||||||
config.qmax = 100;
|
|
||||||
|
|
||||||
// Only use use_argb if we really need it, as it's slower.
|
|
||||||
pic.use_argb = config.lossless || config.use_sharp_yuv || config.preprocessing > 0;
|
|
||||||
pic.width = width;
|
|
||||||
pic.height = height;
|
|
||||||
pic.writer = WebPMemoryWrite;
|
|
||||||
pic.custom_ptr = &wrt;
|
|
||||||
|
|
||||||
WebPMemoryWriterInit(&wrt);
|
|
||||||
|
|
||||||
ok = WebPPictureImportRGBA(&pic, img_in, width * 4) && WebPEncode(&config, &pic);
|
|
||||||
WebPPictureFree(&pic);
|
|
||||||
val js_result = ok ? Uint8Array.new_(typed_memory_view(wrt.size, wrt.mem)) : val::null();
|
|
||||||
WebPMemoryWriterClear(&wrt);
|
|
||||||
return js_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
|
||||||
enum_<WebPImageHint>("WebPImageHint")
|
|
||||||
.value("WEBP_HINT_DEFAULT", WebPImageHint::WEBP_HINT_DEFAULT)
|
|
||||||
.value("WEBP_HINT_PICTURE", WebPImageHint::WEBP_HINT_PICTURE)
|
|
||||||
.value("WEBP_HINT_PHOTO", WebPImageHint::WEBP_HINT_PHOTO)
|
|
||||||
.value("WEBP_HINT_GRAPH", WebPImageHint::WEBP_HINT_GRAPH);
|
|
||||||
|
|
||||||
value_object<WebPConfig>("WebPConfig")
|
|
||||||
.field("lossless", &WebPConfig::lossless)
|
|
||||||
.field("quality", &WebPConfig::quality)
|
|
||||||
.field("method", &WebPConfig::method)
|
|
||||||
.field("image_hint", &WebPConfig::image_hint)
|
|
||||||
.field("target_size", &WebPConfig::target_size)
|
|
||||||
.field("target_PSNR", &WebPConfig::target_PSNR)
|
|
||||||
.field("segments", &WebPConfig::segments)
|
|
||||||
.field("sns_strength", &WebPConfig::sns_strength)
|
|
||||||
.field("filter_strength", &WebPConfig::filter_strength)
|
|
||||||
.field("filter_sharpness", &WebPConfig::filter_sharpness)
|
|
||||||
.field("filter_type", &WebPConfig::filter_type)
|
|
||||||
.field("autofilter", &WebPConfig::autofilter)
|
|
||||||
.field("alpha_compression", &WebPConfig::alpha_compression)
|
|
||||||
.field("alpha_filtering", &WebPConfig::alpha_filtering)
|
|
||||||
.field("alpha_quality", &WebPConfig::alpha_quality)
|
|
||||||
.field("pass", &WebPConfig::pass)
|
|
||||||
.field("show_compressed", &WebPConfig::show_compressed)
|
|
||||||
.field("preprocessing", &WebPConfig::preprocessing)
|
|
||||||
.field("partitions", &WebPConfig::partitions)
|
|
||||||
.field("partition_limit", &WebPConfig::partition_limit)
|
|
||||||
.field("emulate_jpeg_size", &WebPConfig::emulate_jpeg_size)
|
|
||||||
.field("low_memory", &WebPConfig::low_memory)
|
|
||||||
.field("near_lossless", &WebPConfig::near_lossless)
|
|
||||||
.field("exact", &WebPConfig::exact)
|
|
||||||
.field("use_delta_palette", &WebPConfig::use_delta_palette)
|
|
||||||
.field("use_sharp_yuv", &WebPConfig::use_sharp_yuv);
|
|
||||||
|
|
||||||
function("version", &version);
|
|
||||||
function("encode", &encode);
|
|
||||||
}
|
|
||||||
42
codecs/webp/wasm_build/base/enc/webp_enc.d.ts
vendored
42
codecs/webp/wasm_build/base/enc/webp_enc.d.ts
vendored
@@ -1,42 +0,0 @@
|
|||||||
export interface EncodeOptions {
|
|
||||||
quality: number;
|
|
||||||
target_size: number;
|
|
||||||
target_PSNR: number;
|
|
||||||
method: number;
|
|
||||||
sns_strength: number;
|
|
||||||
filter_strength: number;
|
|
||||||
filter_sharpness: number;
|
|
||||||
filter_type: number;
|
|
||||||
partitions: number;
|
|
||||||
segments: number;
|
|
||||||
pass: number;
|
|
||||||
show_compressed: number;
|
|
||||||
preprocessing: number;
|
|
||||||
autofilter: number;
|
|
||||||
partition_limit: number;
|
|
||||||
alpha_compression: number;
|
|
||||||
alpha_filtering: number;
|
|
||||||
alpha_quality: number;
|
|
||||||
lossless: number;
|
|
||||||
exact: number;
|
|
||||||
image_hint: number;
|
|
||||||
emulate_jpeg_size: number;
|
|
||||||
thread_level: number;
|
|
||||||
low_memory: number;
|
|
||||||
near_lossless: number;
|
|
||||||
use_delta_palette: number;
|
|
||||||
use_sharp_yuv: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface WebPModule extends EmscriptenWasm.Module {
|
|
||||||
encode(
|
|
||||||
data: BufferSource,
|
|
||||||
width: number,
|
|
||||||
height: number,
|
|
||||||
options: EncodeOptions,
|
|
||||||
): Uint8Array | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<WebPModule>;
|
|
||||||
|
|
||||||
export default moduleFactory;
|
|
||||||
16
codecs/webp/wasm_build/base/enc/webp_enc.js
generated
16
codecs/webp/wasm_build/base/enc/webp_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
export { default } from './webp_enc.js';
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# WebP decoder
|
|
||||||
|
|
||||||
- Source: <https://github.com/webmproject/libwebp>
|
|
||||||
- Version: v1.0.2
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
See `example.html`
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### `int version()`
|
|
||||||
|
|
||||||
Returns the version of libwebp as a number. va.b.c is encoded as 0x0a0b0c
|
|
||||||
|
|
||||||
### `RawImage decode(std::string buffer)`
|
|
||||||
|
|
||||||
Decodes the given webp buffer into raw RGBA. `RawImage` is a class with 3 fields: `buffer`, `width`, and `height`.
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<script src='webp_dec.js'></script>
|
|
||||||
<script>
|
|
||||||
async function loadFile(src) {
|
|
||||||
const resp = await fetch(src);
|
|
||||||
return await resp.arrayBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
webp_dec().then(async module => {
|
|
||||||
console.log('Version:', module.version().toString(16));
|
|
||||||
const image = await loadFile('../../example.webp');
|
|
||||||
const imageData = module.decode(image);
|
|
||||||
const canvas = document.createElement('canvas');
|
|
||||||
canvas.width = imageData.width;
|
|
||||||
canvas.height = imageData.height;
|
|
||||||
document.body.appendChild(canvas);
|
|
||||||
const ctx = canvas.getContext('2d');
|
|
||||||
ctx.putImageData(imageData, 0, 0);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#include <string>
|
|
||||||
#include "emscripten/bind.h"
|
|
||||||
#include "emscripten/val.h"
|
|
||||||
#include "webp/decode.h"
|
|
||||||
#include "webp/demux.h"
|
|
||||||
|
|
||||||
using namespace emscripten;
|
|
||||||
|
|
||||||
int version() {
|
|
||||||
return WebPGetDecoderVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");
|
|
||||||
thread_local const val ImageData = val::global("ImageData");
|
|
||||||
|
|
||||||
val decode(std::string buffer) {
|
|
||||||
int width, height;
|
|
||||||
std::unique_ptr<uint8_t[]> rgba(
|
|
||||||
WebPDecodeRGBA((const uint8_t*)buffer.c_str(), buffer.size(), &width, &height));
|
|
||||||
return rgba ? ImageData.new_(
|
|
||||||
Uint8ClampedArray.new_(typed_memory_view(width * height * 4, rgba.get())),
|
|
||||||
width, height)
|
|
||||||
: val::null();
|
|
||||||
}
|
|
||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
|
||||||
function("decode", &decode);
|
|
||||||
function("version", &version);
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
export interface WebPModule extends EmscriptenWasm.Module {
|
|
||||||
decode(data: BufferSource): ImageData | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<WebPModule>;
|
|
||||||
|
|
||||||
export default moduleFactory;
|
|
||||||
16
codecs/webp/wasm_build/simd/dec/webp_dec.js
generated
16
codecs/webp/wasm_build/simd/dec/webp_dec.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1,22 +0,0 @@
|
|||||||
# WebP encoder
|
|
||||||
|
|
||||||
- Source: <https://github.com/webmproject/libwebp>
|
|
||||||
- Version: v1.0.2
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
|
|
||||||
- Docker
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
See `example.html`
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### `int version()`
|
|
||||||
|
|
||||||
Returns the version of libwebp as a number. va.b.c is encoded as 0x0a0b0c
|
|
||||||
|
|
||||||
### `UInt8Array encode(uint8_t* image_buffer, int image_width, int image_height, WebPConfig config)`
|
|
||||||
|
|
||||||
Encodes the given image with given dimension to WebP.
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<script src='webp_enc.js'></script>
|
|
||||||
<script>
|
|
||||||
async function loadImage(src) {
|
|
||||||
// Load image
|
|
||||||
const img = document.createElement('img');
|
|
||||||
img.src = src;
|
|
||||||
await new Promise(resolve => img.onload = resolve);
|
|
||||||
// Make canvas same size as image
|
|
||||||
const canvas = document.createElement('canvas');
|
|
||||||
[canvas.width, canvas.height] = [img.width, img.height];
|
|
||||||
// Draw image onto canvas
|
|
||||||
const ctx = canvas.getContext('2d');
|
|
||||||
ctx.drawImage(img, 0, 0);
|
|
||||||
return ctx.getImageData(0, 0, img.width, img.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
webp_enc().then(async module => {
|
|
||||||
console.log('Version:', module.version().toString(16));
|
|
||||||
const image = await loadImage('../../example.png');
|
|
||||||
const result = module.encode(image.data, image.width, image.height, {
|
|
||||||
quality: 75,
|
|
||||||
target_size: 0,
|
|
||||||
target_PSNR: 0,
|
|
||||||
method: 4,
|
|
||||||
sns_strength: 50,
|
|
||||||
filter_strength: 60,
|
|
||||||
filter_sharpness: 0,
|
|
||||||
filter_type: 1,
|
|
||||||
partitions: 0,
|
|
||||||
segments: 4,
|
|
||||||
pass: 1,
|
|
||||||
show_compressed: 0,
|
|
||||||
preprocessing: 0,
|
|
||||||
autofilter: 0,
|
|
||||||
partition_limit: 0,
|
|
||||||
alpha_compression: 1,
|
|
||||||
alpha_filtering: 1,
|
|
||||||
alpha_quality: 100,
|
|
||||||
lossless: 0,
|
|
||||||
exact: 0,
|
|
||||||
image_hint: 0,
|
|
||||||
emulate_jpeg_size: 0,
|
|
||||||
thread_level: 0,
|
|
||||||
low_memory: 0,
|
|
||||||
near_lossless: 100,
|
|
||||||
use_delta_palette: 0,
|
|
||||||
use_sharp_yuv: 0,
|
|
||||||
});
|
|
||||||
console.log('size', result.length);
|
|
||||||
const blob = new Blob([result], {type: 'image/webp'});
|
|
||||||
|
|
||||||
const blobURL = URL.createObjectURL(blob);
|
|
||||||
const img = document.createElement('img');
|
|
||||||
img.src = blobURL;
|
|
||||||
document.body.appendChild(img);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
#include <emscripten/bind.h>
|
|
||||||
#include <emscripten/val.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include "webp/encode.h"
|
|
||||||
|
|
||||||
using namespace emscripten;
|
|
||||||
|
|
||||||
int version() {
|
|
||||||
return WebPGetEncoderVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_local const val Uint8Array = val::global("Uint8Array");
|
|
||||||
|
|
||||||
val encode(std::string img, int width, int height, WebPConfig config) {
|
|
||||||
auto img_in = (uint8_t*)img.c_str();
|
|
||||||
|
|
||||||
// A lot of this is duplicated from Encode in picture_enc.c
|
|
||||||
WebPPicture pic;
|
|
||||||
WebPMemoryWriter wrt;
|
|
||||||
int ok;
|
|
||||||
|
|
||||||
if (!WebPPictureInit(&pic)) {
|
|
||||||
// shouldn't happen, except if system installation is broken
|
|
||||||
return val::null();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow quality to go higher than 0.
|
|
||||||
config.qmax = 100;
|
|
||||||
|
|
||||||
// Only use use_argb if we really need it, as it's slower.
|
|
||||||
pic.use_argb = config.lossless || config.use_sharp_yuv || config.preprocessing > 0;
|
|
||||||
pic.width = width;
|
|
||||||
pic.height = height;
|
|
||||||
pic.writer = WebPMemoryWrite;
|
|
||||||
pic.custom_ptr = &wrt;
|
|
||||||
|
|
||||||
WebPMemoryWriterInit(&wrt);
|
|
||||||
|
|
||||||
ok = WebPPictureImportRGBA(&pic, img_in, width * 4) && WebPEncode(&config, &pic);
|
|
||||||
WebPPictureFree(&pic);
|
|
||||||
val js_result = ok ? Uint8Array.new_(typed_memory_view(wrt.size, wrt.mem)) : val::null();
|
|
||||||
WebPMemoryWriterClear(&wrt);
|
|
||||||
return js_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(my_module) {
|
|
||||||
enum_<WebPImageHint>("WebPImageHint")
|
|
||||||
.value("WEBP_HINT_DEFAULT", WebPImageHint::WEBP_HINT_DEFAULT)
|
|
||||||
.value("WEBP_HINT_PICTURE", WebPImageHint::WEBP_HINT_PICTURE)
|
|
||||||
.value("WEBP_HINT_PHOTO", WebPImageHint::WEBP_HINT_PHOTO)
|
|
||||||
.value("WEBP_HINT_GRAPH", WebPImageHint::WEBP_HINT_GRAPH);
|
|
||||||
|
|
||||||
value_object<WebPConfig>("WebPConfig")
|
|
||||||
.field("lossless", &WebPConfig::lossless)
|
|
||||||
.field("quality", &WebPConfig::quality)
|
|
||||||
.field("method", &WebPConfig::method)
|
|
||||||
.field("image_hint", &WebPConfig::image_hint)
|
|
||||||
.field("target_size", &WebPConfig::target_size)
|
|
||||||
.field("target_PSNR", &WebPConfig::target_PSNR)
|
|
||||||
.field("segments", &WebPConfig::segments)
|
|
||||||
.field("sns_strength", &WebPConfig::sns_strength)
|
|
||||||
.field("filter_strength", &WebPConfig::filter_strength)
|
|
||||||
.field("filter_sharpness", &WebPConfig::filter_sharpness)
|
|
||||||
.field("filter_type", &WebPConfig::filter_type)
|
|
||||||
.field("autofilter", &WebPConfig::autofilter)
|
|
||||||
.field("alpha_compression", &WebPConfig::alpha_compression)
|
|
||||||
.field("alpha_filtering", &WebPConfig::alpha_filtering)
|
|
||||||
.field("alpha_quality", &WebPConfig::alpha_quality)
|
|
||||||
.field("pass", &WebPConfig::pass)
|
|
||||||
.field("show_compressed", &WebPConfig::show_compressed)
|
|
||||||
.field("preprocessing", &WebPConfig::preprocessing)
|
|
||||||
.field("partitions", &WebPConfig::partitions)
|
|
||||||
.field("partition_limit", &WebPConfig::partition_limit)
|
|
||||||
.field("emulate_jpeg_size", &WebPConfig::emulate_jpeg_size)
|
|
||||||
.field("low_memory", &WebPConfig::low_memory)
|
|
||||||
.field("near_lossless", &WebPConfig::near_lossless)
|
|
||||||
.field("exact", &WebPConfig::exact)
|
|
||||||
.field("use_delta_palette", &WebPConfig::use_delta_palette)
|
|
||||||
.field("use_sharp_yuv", &WebPConfig::use_sharp_yuv);
|
|
||||||
|
|
||||||
function("version", &version);
|
|
||||||
function("encode", &encode);
|
|
||||||
}
|
|
||||||
42
codecs/webp/wasm_build/simd/enc/webp_enc.d.ts
vendored
42
codecs/webp/wasm_build/simd/enc/webp_enc.d.ts
vendored
@@ -1,42 +0,0 @@
|
|||||||
export interface EncodeOptions {
|
|
||||||
quality: number;
|
|
||||||
target_size: number;
|
|
||||||
target_PSNR: number;
|
|
||||||
method: number;
|
|
||||||
sns_strength: number;
|
|
||||||
filter_strength: number;
|
|
||||||
filter_sharpness: number;
|
|
||||||
filter_type: number;
|
|
||||||
partitions: number;
|
|
||||||
segments: number;
|
|
||||||
pass: number;
|
|
||||||
show_compressed: number;
|
|
||||||
preprocessing: number;
|
|
||||||
autofilter: number;
|
|
||||||
partition_limit: number;
|
|
||||||
alpha_compression: number;
|
|
||||||
alpha_filtering: number;
|
|
||||||
alpha_quality: number;
|
|
||||||
lossless: number;
|
|
||||||
exact: number;
|
|
||||||
image_hint: number;
|
|
||||||
emulate_jpeg_size: number;
|
|
||||||
thread_level: number;
|
|
||||||
low_memory: number;
|
|
||||||
near_lossless: number;
|
|
||||||
use_delta_palette: number;
|
|
||||||
use_sharp_yuv: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface WebPModule extends EmscriptenWasm.Module {
|
|
||||||
encode(
|
|
||||||
data: BufferSource,
|
|
||||||
width: number,
|
|
||||||
height: number,
|
|
||||||
options: EncodeOptions,
|
|
||||||
): Uint8Array | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare var moduleFactory: EmscriptenWasm.ModuleFactory<WebPModule>;
|
|
||||||
|
|
||||||
export default moduleFactory;
|
|
||||||
16
codecs/webp/wasm_build/simd/enc/webp_enc.js
generated
16
codecs/webp/wasm_build/simd/enc/webp_enc.js
generated
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
export { default } from './webp_enc.js';
|
|
||||||
@@ -10,12 +10,12 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { posix as pathUtils, isAbsolute } from 'path';
|
import { posix, isAbsolute, resolve } from 'path';
|
||||||
|
|
||||||
export default function resolveDirs(paths) {
|
export default function resolveDirs(paths) {
|
||||||
const pathBaseDir = paths.map((path) => [
|
const pathBaseDir = paths.map((path) => [
|
||||||
pathUtils.basename(path),
|
posix.basename(path),
|
||||||
pathUtils.dirname(path),
|
posix.dirname(path),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -31,7 +31,7 @@ export default function resolveDirs(paths) {
|
|||||||
throw new Error(`Couldn't find ${'./' + id}`);
|
throw new Error(`Couldn't find ${'./' + id}`);
|
||||||
}
|
}
|
||||||
if (isAbsolute(resolveResult.id)) return resolveResult.id;
|
if (isAbsolute(resolveResult.id)) return resolveResult.id;
|
||||||
return pathUtils.resolve(resolveResult.id);
|
return resolve(resolveResult.id);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ export default function simpleTS(mainPath, { noBuild, watch } = {}) {
|
|||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
const proc = spawn(tscPath, args, {
|
const proc = spawn(tscPath, args, {
|
||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
|
shell: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
proc.on('exit', (code) => {
|
proc.on('exit', (code) => {
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
FROM nixos/nix:2.24.5
|
|
||||||
|
|
||||||
RUN <<EOF
|
|
||||||
cat >> /etc/nix/nix.conf << EOL
|
|
||||||
experimental-features = nix-command flakes
|
|
||||||
EOL
|
|
||||||
EOF
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
CMD ["nix", "run", ".#updateRepoBinaries"]
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
{
|
|
||||||
rustPlatform,
|
|
||||||
jq,
|
|
||||||
rsync,
|
|
||||||
lib,
|
|
||||||
stdenv,
|
|
||||||
# openssl,
|
|
||||||
pkg-config,
|
|
||||||
fenix,
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
buildRustPackage =
|
|
||||||
{
|
|
||||||
target,
|
|
||||||
src,
|
|
||||||
cargoLock ? {
|
|
||||||
lockFile = "${src}/Cargo.lock";
|
|
||||||
},
|
|
||||||
release ? true,
|
|
||||||
...
|
|
||||||
}@args:
|
|
||||||
let
|
|
||||||
# Setup a toolchain for the the host system targeting `target`.
|
|
||||||
toolchain =
|
|
||||||
let
|
|
||||||
inherit (fenix) stable targets combine;
|
|
||||||
in
|
|
||||||
combine [
|
|
||||||
stable.rustc
|
|
||||||
stable.cargo
|
|
||||||
targets.${target}.stable.rust-std
|
|
||||||
];
|
|
||||||
|
|
||||||
# Create `vendor` folder with all dependencies.
|
|
||||||
vendoredDependencies = rustPlatform.importCargoLock cargoLock;
|
|
||||||
|
|
||||||
rustcTargetDir = "target/${target}/${if release then "release" else "debug"}";
|
|
||||||
in
|
|
||||||
stdenv.mkDerivation (
|
|
||||||
(removeAttrs args [ "cargoLock" ])
|
|
||||||
// {
|
|
||||||
nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [
|
|
||||||
toolchain
|
|
||||||
jq
|
|
||||||
rsync
|
|
||||||
pkg-config
|
|
||||||
# (lib.getDev openssl)
|
|
||||||
];
|
|
||||||
buildInputs = [
|
|
||||||
# openssl
|
|
||||||
];
|
|
||||||
dontConfigure = true;
|
|
||||||
buildPhase = ''
|
|
||||||
runHook preBuild
|
|
||||||
|
|
||||||
cargo build \
|
|
||||||
--config 'source.crates-io.replace-with="vendored-sources"' \
|
|
||||||
--config 'source.vendored-sources.directory="${vendoredDependencies}"' \
|
|
||||||
--offline \
|
|
||||||
--target ${target} ${if release then "-r" else ""}
|
|
||||||
|
|
||||||
runHook postBuild
|
|
||||||
'';
|
|
||||||
installPhase = ''
|
|
||||||
runHook preInstall;
|
|
||||||
mkdir -p $out
|
|
||||||
|
|
||||||
find ${rustcTargetDir} -type f -maxdepth 1 | \
|
|
||||||
xargs -I ___X -n1 cp ___X $out
|
|
||||||
|
|
||||||
runHook postInstall;
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
{
|
|
||||||
pkgs,
|
|
||||||
stdenv,
|
|
||||||
runCommand,
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
nativeBuildInputs ? [ ],
|
|
||||||
encoder ? "enc",
|
|
||||||
decoder ? "dec",
|
|
||||||
...
|
|
||||||
}@args:
|
|
||||||
|
|
||||||
stdenv.mkDerivation (
|
|
||||||
final:
|
|
||||||
args
|
|
||||||
// {
|
|
||||||
inherit name;
|
|
||||||
nativeBuildInputs = [ pkgs.emscripten ] ++ nativeBuildInputs;
|
|
||||||
buildPhase = ''
|
|
||||||
export HOME=$TMPDIR
|
|
||||||
emmake make -j$(nproc)
|
|
||||||
'';
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out
|
|
||||||
${if (encoder != null) then "cp -r ${encoder} $out" else ""}
|
|
||||||
${if (decoder != null) then "cp -r ${decoder} $out" else ""}
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
{
|
|
||||||
coreutils,
|
|
||||||
rsync,
|
|
||||||
writeShellScriptBin,
|
|
||||||
lib,
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
suffixAttrNames =
|
|
||||||
suffix: attrs: lib.mapAttrs' (name: val: lib.nameValuePair "${name}${suffix}" val) attrs;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
inherit suffixAttrNames;
|
|
||||||
|
|
||||||
mkRepoBinaryUpdater =
|
|
||||||
flake:
|
|
||||||
let
|
|
||||||
script = writeShellScriptBin "updateRepoBinaries.sh" ''
|
|
||||||
${coreutils}/bin/mkdir -p wasm_build
|
|
||||||
${rsync}/bin/rsync --chmod=u+w -r ${flake.packages.default}/* wasm_build/
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
lib.recursiveUpdate flake {
|
|
||||||
apps.updateRepoBinaries = {
|
|
||||||
type = "app";
|
|
||||||
program = "${script}/bin/updateRepoBinaries.sh";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
forAllVariants =
|
|
||||||
{ builder, variants }:
|
|
||||||
lib.lists.foldl (acc: v: acc // v) { } (
|
|
||||||
lib.mapAttrsToList (
|
|
||||||
variantName: value: suffixAttrNames "-${variantName}" (builder variantName value)
|
|
||||||
) variants
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
{
|
|
||||||
pkgs,
|
|
||||||
fenix,
|
|
||||||
wasm-bindgen ? pkgs.callPackage (import ../wasm-bindgen) { },
|
|
||||||
rust-helpers ? pkgs.callPackage (import ../rust-helpers) { inherit fenix; },
|
|
||||||
binaryen,
|
|
||||||
stdenv,
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
inherit (rust-helpers) buildRustPackage;
|
|
||||||
in
|
|
||||||
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
src,
|
|
||||||
cargoLock ? {
|
|
||||||
lockFile = "${src}/Cargo.lock";
|
|
||||||
},
|
|
||||||
wasmBindgen ? {
|
|
||||||
sha256 = "";
|
|
||||||
},
|
|
||||||
...
|
|
||||||
}@args:
|
|
||||||
let
|
|
||||||
codecBuild = buildRustPackage {
|
|
||||||
inherit src cargoLock;
|
|
||||||
name = "${name}-codec";
|
|
||||||
target = "wasm32-unknown-unknown";
|
|
||||||
};
|
|
||||||
|
|
||||||
wasm-bindgen-bin = wasm-bindgen.buildFromCargoLock {
|
|
||||||
inherit cargoLock;
|
|
||||||
sha256 = wasmBindgen.sha256;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
if wasmBindgen != null then
|
|
||||||
stdenv.mkDerivation (
|
|
||||||
(removeAttrs args [
|
|
||||||
"cargoLock"
|
|
||||||
"wasmBindgen"
|
|
||||||
])
|
|
||||||
// {
|
|
||||||
inherit codecBuild;
|
|
||||||
dontConfigure = true;
|
|
||||||
nativeBuildInputs = [ wasm-bindgen-bin ];
|
|
||||||
buildPhase = ''
|
|
||||||
runHook preBuild
|
|
||||||
|
|
||||||
wasm-bindgen --target web --out-dir $out $codecBuild/*.wasm
|
|
||||||
|
|
||||||
runHook postBuild
|
|
||||||
'';
|
|
||||||
dontInstall = true;
|
|
||||||
}
|
|
||||||
)
|
|
||||||
else
|
|
||||||
stdenv.mkDerivation (
|
|
||||||
(removeAttrs args [
|
|
||||||
"cargoLock"
|
|
||||||
"wasmBindgen"
|
|
||||||
])
|
|
||||||
// {
|
|
||||||
inherit codecBuild;
|
|
||||||
dontConfigure = true;
|
|
||||||
nativeBuildInputs = [ binaryen ];
|
|
||||||
buildPhase = ''
|
|
||||||
runHook preBuild
|
|
||||||
|
|
||||||
wasm-opt -O3 --strip -o optimized.wasm $codecBuild/*.wasm
|
|
||||||
|
|
||||||
runHook postBuild
|
|
||||||
'';
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out
|
|
||||||
cp optimized.wasm $out
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
fetchCrate,
|
|
||||||
rustPlatform,
|
|
||||||
curl,
|
|
||||||
stdenv,
|
|
||||||
openssl_1_1,
|
|
||||||
pkg-config,
|
|
||||||
darwin,
|
|
||||||
}:
|
|
||||||
rec {
|
|
||||||
build =
|
|
||||||
{ version, sha256 }:
|
|
||||||
let
|
|
||||||
src = fetchCrate {
|
|
||||||
pname = "wasm-bindgen-cli";
|
|
||||||
inherit version sha256;
|
|
||||||
};
|
|
||||||
|
|
||||||
cargoLock = {
|
|
||||||
lockFile = "${src}/Cargo.lock";
|
|
||||||
};
|
|
||||||
in
|
|
||||||
rustPlatform.buildRustPackage {
|
|
||||||
name = "wasm-bindgen-cli";
|
|
||||||
inherit src cargoLock;
|
|
||||||
nativeBuildInputs = [
|
|
||||||
pkg-config
|
|
||||||
];
|
|
||||||
buildInputs = [
|
|
||||||
openssl_1_1
|
|
||||||
] ++ lib.optionals stdenv.isDarwin [
|
|
||||||
darwin.apple_sdk.frameworks.IOKit
|
|
||||||
];
|
|
||||||
|
|
||||||
doCheck = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
buildFromCargoLock =
|
|
||||||
{ cargoLock, sha256 }:
|
|
||||||
assert (cargoLock.lockFile or null == null) != (cargoLock.lockFileContents or null == null);
|
|
||||||
let
|
|
||||||
lockFileContents =
|
|
||||||
if cargoLock.lockFile != null then
|
|
||||||
builtins.readFile cargoLock.lockFile
|
|
||||||
else
|
|
||||||
cargoLock.lockFileContents;
|
|
||||||
|
|
||||||
parsedLockFile = builtins.fromTOML lockFileContents;
|
|
||||||
|
|
||||||
wasm-bindgen-version =
|
|
||||||
(lib.lists.findFirst (x: x.name == "wasm-bindgen") null parsedLockFile.package).version;
|
|
||||||
in
|
|
||||||
assert wasm-bindgen-version != null;
|
|
||||||
build {
|
|
||||||
inherit sha256;
|
|
||||||
version = wasm-bindgen-version;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -10,14 +10,14 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import type { WebPModule } from 'codecs/webp/wasm_build/base/dec/webp_dec';
|
import type { WebPModule } from 'codecs/webp/dec/webp_dec';
|
||||||
import { initEmscriptenModule, blobToArrayBuffer } from 'features/worker-utils';
|
import { initEmscriptenModule, blobToArrayBuffer } from 'features/worker-utils';
|
||||||
|
|
||||||
let emscriptenModule: Promise<WebPModule>;
|
let emscriptenModule: Promise<WebPModule>;
|
||||||
|
|
||||||
export default async function decode(blob: Blob): Promise<ImageData> {
|
export default async function decode(blob: Blob): Promise<ImageData> {
|
||||||
if (!emscriptenModule) {
|
if (!emscriptenModule) {
|
||||||
const decoder = await import('codecs/webp/wasm_build/base/dec/webp_dec');
|
const decoder = await import('codecs/webp/dec/webp_dec');
|
||||||
emscriptenModule = initEmscriptenModule(decoder.default);
|
emscriptenModule = initEmscriptenModule(decoder.default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
import {
|
import {
|
||||||
EncodeOptions,
|
EncodeOptions,
|
||||||
MozJpegColorSpace,
|
MozJpegColorSpace,
|
||||||
} from 'codecs/mozjpeg/wasm_build/enc/mozjpeg_enc';
|
} from 'codecs/mozjpeg/enc/mozjpeg_enc';
|
||||||
export { EncodeOptions, MozJpegColorSpace };
|
export { EncodeOptions, MozJpegColorSpace };
|
||||||
|
|
||||||
export const label = 'MozJPEG';
|
export const label = 'MozJPEG';
|
||||||
|
|||||||
@@ -10,9 +10,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import mozjpeg_enc, {
|
import mozjpeg_enc, { MozJPEGModule } from 'codecs/mozjpeg/enc/mozjpeg_enc';
|
||||||
MozJPEGModule,
|
|
||||||
} from 'codecs/mozjpeg/wasm_build/enc/mozjpeg_enc';
|
|
||||||
import { EncodeOptions } from '../shared/meta';
|
import { EncodeOptions } from '../shared/meta';
|
||||||
import { initEmscriptenModule } from 'features/worker-utils';
|
import { initEmscriptenModule } from 'features/worker-utils';
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import type { EncodeOptions } from 'codecs/webp/wasm_build/base/enc/webp_enc';
|
import type { EncodeOptions } from 'codecs/webp/enc/webp_enc';
|
||||||
|
|
||||||
export { EncodeOptions };
|
export { EncodeOptions };
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import type { WebPModule } from 'codecs/webp/wasm_build/base/enc/webp_enc';
|
import type { WebPModule } from 'codecs/webp/enc/webp_enc';
|
||||||
import type { EncodeOptions } from '../shared/meta';
|
import type { EncodeOptions } from '../shared/meta';
|
||||||
|
|
||||||
import { initEmscriptenModule } from 'features/worker-utils';
|
import { initEmscriptenModule } from 'features/worker-utils';
|
||||||
@@ -20,12 +20,10 @@ let emscriptenModule: Promise<WebPModule>;
|
|||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
if (await simd()) {
|
if (await simd()) {
|
||||||
const webpEncoder = await import(
|
const webpEncoder = await import('codecs/webp/enc/webp_enc_simd');
|
||||||
'codecs/webp/wasm_build/simd/enc/webp_enc'
|
|
||||||
);
|
|
||||||
return initEmscriptenModule(webpEncoder.default);
|
return initEmscriptenModule(webpEncoder.default);
|
||||||
}
|
}
|
||||||
const webpEncoder = await import('codecs/webp/wasm_build/base/enc/webp_enc');
|
const webpEncoder = await import('codecs/webp/enc/webp_enc');
|
||||||
return initEmscriptenModule(webpEncoder.default);
|
return initEmscriptenModule(webpEncoder.default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import wasmUrl from 'url:codecs/rotate/wasm_build/optimized.wasm';
|
import wasmUrl from 'url:codecs/rotate/rotate.wasm';
|
||||||
import { Options } from '../shared/meta';
|
import { Options } from '../shared/meta';
|
||||||
|
|
||||||
export interface RotateModuleInstance {
|
export interface RotateModuleInstance {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import * as featuresWorker from 'entry-data:../features-worker';
|
|||||||
|
|
||||||
// Decoders (some are feature detected)
|
// Decoders (some are feature detected)
|
||||||
import * as avifDec from 'entry-data:codecs/avif/dec/avif_dec';
|
import * as avifDec from 'entry-data:codecs/avif/dec/avif_dec';
|
||||||
import * as webpDec from 'entry-data:codecs/webp/wasm_build/base/dec/webp_dec';
|
import * as webpDec from 'entry-data:codecs/webp/dec/webp_dec';
|
||||||
|
|
||||||
// AVIF
|
// AVIF
|
||||||
import * as avifEncMt from 'entry-data:codecs/avif/enc/avif_enc_mt';
|
import * as avifEncMt from 'entry-data:codecs/avif/enc/avif_enc_mt';
|
||||||
@@ -41,8 +41,8 @@ import * as oxiMt from 'entry-data:codecs/oxipng/pkg-parallel/squoosh_oxipng';
|
|||||||
import * as oxi from 'entry-data:codecs/oxipng/pkg/squoosh_oxipng';
|
import * as oxi from 'entry-data:codecs/oxipng/pkg/squoosh_oxipng';
|
||||||
|
|
||||||
// WebP
|
// WebP
|
||||||
import * as webpEncSimd from 'entry-data:codecs/webp/wasm_build/simd/enc/webp_enc';
|
import * as webpEncSimd from 'entry-data:codecs/webp/enc/webp_enc_simd';
|
||||||
import * as webpEnc from 'entry-data:codecs/webp/wasm_build/base/enc/webp_enc';
|
import * as webpEnc from 'entry-data:codecs/webp/enc/webp_enc';
|
||||||
|
|
||||||
// WP2
|
// WP2
|
||||||
import * as wp2EncMtSimd from 'entry-data:codecs/wp2/enc/wp2_enc_mt_simd';
|
import * as wp2EncMtSimd from 'entry-data:codecs/wp2/enc/wp2_enc_mt_simd';
|
||||||
|
|||||||
Reference in New Issue
Block a user