diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 262215e..3aecfa3 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM emscripten/emsdk:3.1.53 +FROM emscripten/emsdk:3.1.54 # Avoid warnings by switching to noninteractive ENV DEBIAN_FRONTEND=noninteractive diff --git a/.gitmodules b/.gitmodules index 3511dba..767bf22 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "packages/charls/extern/charls"] path = packages/charls/extern/charls url = https://github.com/cornerstonejs/charls.git +[submodule "packages/libjxl/extern/libjxl"] + path = packages/libjxl/extern/libjxl + url = https://github.com/libjxl/libjxl.git diff --git a/packages/libjxl/.gitignore b/packages/libjxl/.gitignore new file mode 100644 index 0000000..cd1e51f --- /dev/null +++ b/packages/libjxl/.gitignore @@ -0,0 +1,108 @@ +build/ +build-native/ + +.DS_Store + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port diff --git a/packages/libjxl/.gitmodules b/packages/libjxl/.gitmodules new file mode 100644 index 0000000..cba02d8 --- /dev/null +++ b/packages/libjxl/.gitmodules @@ -0,0 +1,3 @@ +[submodule "extern/libjxl"] + path = extern/libjxl + url = https://github.com/libjxl/libjxl.git diff --git a/packages/libjxl/CMakeLists.txt b/packages/libjxl/CMakeLists.txt new file mode 100644 index 0000000..1b10f43 --- /dev/null +++ b/packages/libjxl/CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 3.16) + +project (libjxl-js + LANGUAGES CXX) + +# set the build type if not specified +set(default_build_type "Release") +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to '${default_build_type}' as none was specified.") + set(CMAKE_BUILD_TYPE "${default_build_type}") +endif() + +if(NOT EXISTS "${PROJECT_SOURCE_DIR}/extern/libjxl/CMakeLists.txt") + message(FATAL_ERROR "The submodules were not downloaded! GIT_SUBMODULE was turned off or failed. Please update submodules and try again.") +endif() + +option(BUILD_SHARED_LIBS "" OFF) + +# add the external library +add_subdirectory(extern/libjxl EXCLUDE_FROM_ALL) + +# add the js wrapper +if(EMSCRIPTEN) + add_subdirectory(src) +endif() + +# c++ native test case +if(NOT EMSCRIPTEN) + add_subdirectory(test/cpp) +endif() \ No newline at end of file diff --git a/packages/libjxl/Docker/Dockerfile b/packages/libjxl/Docker/Dockerfile new file mode 100644 index 0000000..b6a491f --- /dev/null +++ b/packages/libjxl/Docker/Dockerfile @@ -0,0 +1,45 @@ +#------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. +#------------------------------------------------------------------------------------------------------------- + +#FROM mcr.microsoft.com/vscode/devcontainers/base:0-debian-9 +FROM emscripten/emsdk:3.1.54 + +# Avoid warnings by switching to noninteractive +ENV DEBIAN_FRONTEND=noninteractive + +# This Dockerfile's base image has a non-root user with sudo access. Use the "remoteUser" +# property in devcontainer.json to use it. On Linux, the container user's GID/UIDs +# will be updated to match your local UID/GID (when using the dockerFile property). +# See https://aka.ms/vscode-remote/containers/non-root-user for details. +ARG USERNAME=vscode +ARG USER_UID=1000 +ARG USER_GID=$USER_UID + +# Configure apt and install packages +RUN apt-get update \ + # + # Install C++ tools + #&& apt-get -y install build-essential cmake cppcheck valgrind \ + && apt-get -y install build-essential cppcheck valgrind pkg-config libbrotli-dev clang \ + # libjxl deps + && apt-get -y install pkg-config libbrotli-dev libgflags-dev \ + # version 3.17 of cmake + #& wget -qO- "https://cmake.org/files/v3.17/cmake-3.17.0-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local\ + #& wget -qO- "https://cmake.org/files/v3.17/cmake-3.17.0-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local\ + # + # [Optional] Update UID/GID if needed + && if [ "$USER_GID" != "1000" ] || [ "$USER_UID" != "1000" ]; then \ + groupmod --gid $USER_GID $USERNAME \ + && usermod --uid $USER_UID --gid $USER_GID $USERNAME \ + && chown -R $USER_UID:$USER_GID /home/$USERNAME; \ + fi \ + # + # Clean up + && apt-get autoremove -y \ + && apt-get clean -y \ + && rm -rf /var/lib/apt/lists/* + +# Switch back to dialog for any ad-hoc use of apt-get +ENV DEBIAN_FRONTEND=dialog \ No newline at end of file diff --git a/packages/libjxl/Docker/build.sh b/packages/libjxl/Docker/build.sh new file mode 100644 index 0000000..a5b5452 --- /dev/null +++ b/packages/libjxl/Docker/build.sh @@ -0,0 +1 @@ +docker build -t jxlbuild . diff --git a/packages/libjxl/Docker/docker.sh b/packages/libjxl/Docker/docker.sh new file mode 100644 index 0000000..4568115 --- /dev/null +++ b/packages/libjxl/Docker/docker.sh @@ -0,0 +1,4 @@ +docker run -it --rm \ + --user $(id -u):$(id -g) \ + -v $HOME/src/github/chafey/libjxl-js:/libjxl-js -w /libjxl-js \ + jxlbuild bash diff --git a/packages/libjxl/Docker/run.sh b/packages/libjxl/Docker/run.sh new file mode 100644 index 0000000..5c7c91f --- /dev/null +++ b/packages/libjxl/Docker/run.sh @@ -0,0 +1,3 @@ +docker run -it --rm \ + -v $HOME/src/github/chafey/libjxl-js:/libjxl-js -w /libjxl-js \ + emscripten/emsdk:3.1.54 bash \ No newline at end of file diff --git a/packages/libjxl/Dockerfile b/packages/libjxl/Dockerfile new file mode 100644 index 0000000..2340f05 --- /dev/null +++ b/packages/libjxl/Dockerfile @@ -0,0 +1,37 @@ +FROM emscripten/emsdk:3.1.54 + +# Avoid warnings by switching to noninteractive +ENV DEBIAN_FRONTEND=noninteractive + +# default username, userid and group id to use in the container. +# NOTE - scripts/docker-build.sh overrides these using current user info via command line args +ARG USERNAME=dev +ARG USER_UID=1000 +ARG USER_GID=$USER_UID + +# delete emscripten user and create user with sudo privelege that matches current user +RUN userdel emscripten \ + # && groupadd -g $USER_GID $USERNAME \ + && useradd -ms /bin/bash -u $USER_UID -g $USER_GID $USERNAME \ + && usermod -aG sudo $USERNAME \ + && printf "\n$USERNAME ALL=(ALL) NOPASSWD: ALL\n" >> /etc/sudoers + +# Configure apt and install packages +RUN apt-get update \ + # + # Install nvm + && su - $USERNAME -c "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash" \ + # + # Install C++ tools + && apt-get -y install build-essential cppcheck valgrind pkg-config libbrotli-dev clang \ + # + # version 3.17 of cmake + #& wget -qO- "https://cmake.org/files/v3.17/cmake-3.17.0-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local\ + # + # Clean up + && apt-get autoremove -y \ + && apt-get clean -y \ + && rm -rf /var/lib/apt/lists/* + +# Switch back to dialog for any ad-hoc use of apt-get +ENV DEBIAN_FRONTEND=dialog \ No newline at end of file diff --git a/packages/libjxl/LICENSE b/packages/libjxl/LICENSE new file mode 100644 index 0000000..b24dbde --- /dev/null +++ b/packages/libjxl/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Chris Hafey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/libjxl/README.md b/packages/libjxl/README.md new file mode 100644 index 0000000..d6f6150 --- /dev/null +++ b/packages/libjxl/README.md @@ -0,0 +1,54 @@ +# libjxl-js +JS/WASM build of libjxl (JPEG-XL) + +## Try It Out! + +Try it in your browser [here](https://chafey.github.io/libjxl-js/test/browser/index.html) + +## Building + +This project uses git submodules to pull in libjxl. If developing, initialize the git submodules first: + +``` +> git submodule update --init --recursive +``` + +This project uses Docker to provide a consistent developer environment. + +Create docker container 'libjxljsbuild' + +``` +> scripts/docker-build.sh +``` + +Create shell inside libjxljsbuild container: + +``` +> scripts/docker-sh.sh +``` + +Install node 16 (inside docker shell): +``` +> nvm install 16 +``` + +To build WASM (inside docker shell): +``` +> scripts/wasm-build.sh +``` + +To build native C/C++ version (inside docker shell): +``` +> scripts/native-build.sh +``` + +Run performance test (inside docker shell): +``` +> scripts/performance.sh +``` + +## NOTES + +Luca's suggestions for cjxl parameters to use for progressive lossless encoding + +* ./tools/cjxl -P 0 -R 1 -I 0 -s 4 -g 0 in.png out.jxl \ No newline at end of file diff --git a/packages/libjxl/build-native.sh b/packages/libjxl/build-native.sh new file mode 100644 index 0000000..899b18b --- /dev/null +++ b/packages/libjxl/build-native.sh @@ -0,0 +1,7 @@ +#!/bin/sh +rm -rf build-native +mkdir -p build-native +(cd build-native && CC=clang CXX=clang++ cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DJPEGXL_ENABLE_TOOLS=false ..) +#(cd build && cmake ..) +(cd build-native && CC=clang CXX=clang++ make VERBOSE=1 -j 8) +(build-native/test/cpp/cpptest) \ No newline at end of file diff --git a/packages/libjxl/build.sh b/packages/libjxl/build.sh new file mode 100644 index 0000000..fae1175 --- /dev/null +++ b/packages/libjxl/build.sh @@ -0,0 +1,11 @@ +#!/bin/sh +mkdir -p build +mkdir -p dist +#(cd build && CXXFLAGS=-msimd128 emcmake cmake -DCMAKE_BUILD_TYPE=Debug ..) +(./extern/libjxl/deps.sh) +(cd build && CXXFLAGS=-msimd128 emcmake cmake -DCMAKE_BUILD_TYPE=Debug ..) +(cd build && emmake make VERBOSE=1 -j ${nprocs}) +cp ./build/src/libjxl.js ./dist +cp ./build/src/libjxl.wasm ./dist +# disable tests for now since CI doesn't like to run with SIMD +# (cd test/node; npm run test) diff --git a/packages/libjxl/extern/libjxl b/packages/libjxl/extern/libjxl new file mode 160000 index 0000000..fb8b6fd --- /dev/null +++ b/packages/libjxl/extern/libjxl @@ -0,0 +1 @@ +Subproject commit fb8b6fdd4007baa3034e15ca426ee9d70b71ff10 diff --git a/packages/libjxl/package.json b/packages/libjxl/package.json new file mode 100644 index 0000000..78062a0 --- /dev/null +++ b/packages/libjxl/package.json @@ -0,0 +1,28 @@ +{ + "name": "@cornerstonejs/codec-libjxl", + "version": "0.0.1", + "description": "JS/WASM Build of [libjxl](https://github.com/libjxl/libjxl)", + "main": "dist/libjxljs.js", + "publishConfig": { + "access": "public" + }, + "directories": { + "test": "test" + }, + "engines": { + "node": ">=0.16" + }, + "files": [ + "package.json", + "README.md", + "dist" + ], + "scripts": { + "build": "bash build.sh", + "build:ci": "yarn run build", + "test": "echo \"Error: no test specified\" && exit 1", + "prepublishOnly": "yarn run build" + }, + "author": "", + "license": "ISC" +} diff --git a/packages/libjxl/performance.csv b/packages/libjxl/performance.csv new file mode 100644 index 0000000..cb56a38 --- /dev/null +++ b/packages/libjxl/performance.csv @@ -0,0 +1,487 @@ +argv= [ + '/emsdk/node/16.20.0_64bit/bin/node', + '/workspaces/codecs/packages/libjxl/test/node/index.js', + '--experimental-wasm-simd', + '1' +] +🚀 ~ encode ~ imageFrame: { + width: 512, + height: 512, + bitsPerSample: 16, + componentCount: 1, + isSigned: true +} +🚀 ~ encode ~ decodedBytes: Uint8Array(524288) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 524188 more items +] +WASM-encode CT1 19.390145 +🚀 ~ encode ~ imageFrame: { + width: 512, + height: 512, + bitsPerSample: 16, + componentCount: 1, + isSigned: true +} +🚀 ~ encode ~ decodedBytes: Uint8Array(524288) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 524188 more items +] +WASM-encode CT2 17.751437 +🚀 ~ encode ~ imageFrame: { + width: 3064, + height: 4774, + bitsPerSample: 16, + componentCount: 1, + isSigned: false +} +🚀 ~ encode ~ decodedBytes: Uint8Array(29255072) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 29254972 more items +] +WASM-encode MG1 1081.4533239999998 +🚀 ~ encode ~ imageFrame: { + width: 512, + height: 512, + bitsPerSample: 16, + componentCount: 1, + isSigned: true +} +🚀 ~ encode ~ decodedBytes: Uint8Array(524288) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 524188 more items +] +WASM-encode MR1 19.346917 +🚀 ~ encode ~ imageFrame: { + width: 1024, + height: 1024, + bitsPerSample: 16, + componentCount: 1, + isSigned: false +} +🚀 ~ encode ~ decodedBytes: Uint8Array(2097152) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 2097052 more items +] +WASM-encode MR2 67.08852399999999 +🚀 ~ encode ~ imageFrame: { + width: 512, + height: 512, + bitsPerSample: 16, + componentCount: 1, + isSigned: true +} +🚀 ~ encode ~ decodedBytes: Uint8Array(524288) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 524188 more items +] +WASM-encode MR3 16.005475 +🚀 ~ encode ~ imageFrame: { + width: 512, + height: 512, + bitsPerSample: 16, + componentCount: 1, + isSigned: false +} +🚀 ~ encode ~ decodedBytes: Uint8Array(524288) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 524188 more items +] +WASM-encode MR4 16.282674 +🚀 ~ encode ~ imageFrame: { + width: 256, + height: 1024, + bitsPerSample: 16, + componentCount: 1, + isSigned: true +} +🚀 ~ encode ~ decodedBytes: Uint8Array(524288) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 524188 more items +] +WASM-encode NM1 19.378936 +🚀 ~ encode ~ imageFrame: { + width: 1841, + height: 1955, + bitsPerSample: 16, + componentCount: 1, + isSigned: false +} +🚀 ~ encode ~ decodedBytes: Uint8Array(7198310) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 7198210 more items +] +WASM-encode RG1 239.348162 +🚀 ~ encode ~ imageFrame: { + width: 1760, + height: 2140, + bitsPerSample: 16, + componentCount: 1, + isSigned: false +} +🚀 ~ encode ~ decodedBytes: Uint8Array(7532800) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 7532700 more items +] +WASM-encode RG2 229.379357 +🚀 ~ encode ~ imageFrame: { + width: 1760, + height: 1760, + bitsPerSample: 16, + componentCount: 1, + isSigned: false +} +🚀 ~ encode ~ decodedBytes: Uint8Array(6195200) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 6195100 more items +] +WASM-encode RG3 175.255875 +🚀 ~ encode ~ imageFrame: { + width: 2048, + height: 2487, + bitsPerSample: 16, + componentCount: 1, + isSigned: false +} +🚀 ~ encode ~ decodedBytes: Uint8Array(10186752) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 10186652 more items +] +WASM-encode SC1 316.645901 +🚀 ~ encode ~ imageFrame: { + width: 1024, + height: 1024, + bitsPerSample: 16, + componentCount: 1, + isSigned: false +} +🚀 ~ encode ~ decodedBytes: Uint8Array(2097152) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 2097052 more items +] +WASM-encode XA1 62.380252 +🚀 ~ decode ~ encodedBitStream: +🚀 ~ decode ~ encodedBuffer: Uint8Array(160802) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 160702 more items +] +decodeDuration= [ 0, 15011032 ] +decodeDurationInSections 0.015011032 0 15011032 1 +decodeTimeMS 15.011032 +WASM-decode CT1 15.011032 +🚀 ~ decode ~ encodedBitStream: +🚀 ~ decode ~ encodedBuffer: Uint8Array(104401) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 104301 more items +] +decodeDuration= [ 0, 16079103 ] +decodeDurationInSections 0.016079103 0 16079103 1 +decodeTimeMS 16.079103 +WASM-decode CT2 16.079103 +🚀 ~ decode ~ encodedBitStream: +🚀 ~ decode ~ encodedBuffer: Uint8Array(12071593) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 12071493 more items +] +decodeDuration= [ 0, 762361318 ] +decodeDurationInSections 0.762361318 0 762361318 1 +decodeTimeMS 762.361318 +WASM-decode MG1 762.361318 +🚀 ~ decode ~ encodedBitStream: +🚀 ~ decode ~ encodedBuffer: Uint8Array(226076) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 225976 more items +] +decodeDuration= [ 0, 14561507 ] +decodeDurationInSections 0.014561507 0 14561507 1 +decodeTimeMS 14.561506999999999 +WASM-decode MR1 14.561506999999999 +🚀 ~ decode ~ encodedBitStream: +🚀 ~ decode ~ encodedBuffer: Uint8Array(591882) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 591782 more items +] +decodeDuration= [ 0, 54735166 ] +decodeDurationInSections 0.054735166 0 54735166 1 +decodeTimeMS 54.735166 +WASM-decode MR2 54.735166 +🚀 ~ decode ~ encodedBitStream: +🚀 ~ decode ~ encodedBuffer: Uint8Array(110727) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 110627 more items +] +decodeDuration= [ 0, 13920699 ] +decodeDurationInSections 0.013920699 0 13920699 1 +decodeTimeMS 13.920698999999999 +WASM-decode MR3 13.920698999999999 +🚀 ~ decode ~ encodedBitStream: +🚀 ~ decode ~ encodedBuffer: Uint8Array(109131) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 109031 more items +] +decodeDuration= [ 0, 14032940 ] +decodeDurationInSections 0.01403294 0 14032940 1 +decodeTimeMS 14.03294 +WASM-decode MR4 14.03294 +🚀 ~ decode ~ encodedBitStream: +🚀 ~ decode ~ encodedBuffer: Uint8Array(84801) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 84701 more items +] +decodeDuration= [ 0, 14181715 ] +decodeDurationInSections 0.014181715 0 14181715 1 +decodeTimeMS 14.181714999999999 +WASM-decode NM1 14.181714999999999 +🚀 ~ decode ~ encodedBitStream: +🚀 ~ decode ~ encodedBuffer: Uint8Array(4193780) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 4193680 more items +] +decodeDuration= [ 0, 197072753 ] +decodeDurationInSections 0.197072753 0 197072753 1 +decodeTimeMS 197.07275299999998 +WASM-decode RG1 197.07275299999998 +🚀 ~ decode ~ encodedBitStream: +🚀 ~ decode ~ encodedBuffer: Uint8Array(1408252) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 1408152 more items +] +decodeDuration= [ 0, 192026021 ] +decodeDurationInSections 0.192026021 0 192026021 1 +decodeTimeMS 192.026021 +WASM-decode RG2 192.026021 +🚀 ~ decode ~ encodedBitStream: +🚀 ~ decode ~ encodedBuffer: Uint8Array(825982) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 825882 more items +] +decodeDuration= [ 0, 148020985 ] +decodeDurationInSections 0.148020985 0 148020985 1 +decodeTimeMS 148.020985 +WASM-decode RG3 148.020985 +🚀 ~ decode ~ encodedBitStream: +🚀 ~ decode ~ encodedBuffer: Uint8Array(2090300) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 2090200 more items +] +decodeDuration= [ 0, 268771334 ] +decodeDurationInSections 0.268771334 0 268771334 1 +decodeTimeMS 268.77133399999997 +WASM-decode SC1 268.77133399999997 +🚀 ~ decode ~ encodedBitStream: +🚀 ~ decode ~ encodedBuffer: Uint8Array(382875) [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ... 382775 more items +] +decodeDuration= [ 0, 61347106 ] +decodeDurationInSections 0.061347106 0 61347106 1 +decodeTimeMS 61.347106 +WASM-decode XA1 61.347106 diff --git a/packages/libjxl/scripts/docker-build.sh b/packages/libjxl/scripts/docker-build.sh new file mode 100644 index 0000000..4ac3fc0 --- /dev/null +++ b/packages/libjxl/scripts/docker-build.sh @@ -0,0 +1,3 @@ +docker build \ + --build-arg USER_UID=$(id -u) --build-arg USER_GID=$(id -g) --build-arg USERNAME=$(whoami) \ + -t libjxljsbuild . \ No newline at end of file diff --git a/packages/libjxl/scripts/docker-sh.sh b/packages/libjxl/scripts/docker-sh.sh new file mode 100644 index 0000000..7f6ba6c --- /dev/null +++ b/packages/libjxl/scripts/docker-sh.sh @@ -0,0 +1,4 @@ +docker run -it --rm \ + --user $(id -u):$(id -g) \ + -v "$(pwd)":/libjxl-js -w /libjxl-js \ + libjxljsbuild bash -login \ No newline at end of file diff --git a/packages/libjxl/scripts/native-build.sh b/packages/libjxl/scripts/native-build.sh new file mode 100644 index 0000000..82a4b31 --- /dev/null +++ b/packages/libjxl/scripts/native-build.sh @@ -0,0 +1,6 @@ +#!/bin/sh +mkdir -p build-native +#(cd build-native && cmake -DCMAKE_BUILD_TYPE=Debug ..) && +(cd build-native && cmake -DBUILD_TESTING=OFF -DCMAKE_C_FLAGS="-march=native" ..) && +(cd build-native && make VERBOSE=1 -j ${nprocs}) && +(build-native/test/cpp/cpptest) \ No newline at end of file diff --git a/packages/libjxl/scripts/performance.sh b/packages/libjxl/scripts/performance.sh new file mode 100644 index 0000000..168da89 --- /dev/null +++ b/packages/libjxl/scripts/performance.sh @@ -0,0 +1,10 @@ +#!/bin/sh +rm -rf build; scripts/wasm-build.sh +rm -rf build-native; scripts/native-build.sh +rm performance.csv +echo "running native tests" +(build-native/test/cpp/cpptest 1 >> performance.csv) +echo "running WASM tests" +(cd test/node; npm run test 1 > ../../wasm-performance.csv) +sed 1,4d wasm-performance.csv >> performance.csv +rm wasm-performance.csv diff --git a/packages/libjxl/scripts/wasm-build.sh b/packages/libjxl/scripts/wasm-build.sh new file mode 100644 index 0000000..d195c06 --- /dev/null +++ b/packages/libjxl/scripts/wasm-build.sh @@ -0,0 +1,11 @@ +#!/bin/sh +#rm -rf build +mkdir -p build +#(cd build && emconfigure cmake -DCMAKE_BUILD_TYPE=Debug ..) && +# enabling simd has no effort as of Oct 9, 2021 +#(cd build && emcmake cmake -DCMAKE_C_FLAGS="-msimd128" ..) && +(cd build && emcmake cmake -DCMAKE_C_FLAGS="" ..) && +(cd build && emmake make VERBOSE=1 -j ${nprocs}) && +cp ./build/src/libjxljs.js ./dist +cp ./build/src/libjxljs.wasm ./dist +(cd test/node; npm run test) diff --git a/packages/libjxl/src/CMakeLists.txt b/packages/libjxl/src/CMakeLists.txt new file mode 100644 index 0000000..524a5e0 --- /dev/null +++ b/packages/libjxl/src/CMakeLists.txt @@ -0,0 +1,31 @@ +add_executable(libjxljs jslib.cpp) + +target_link_libraries(libjxljs jxl-static) + +target_compile_features(libjxljs PUBLIC cxx_std_11) + +include_directories(../build/extern/libjxl/lib/include/) + +if (CMAKE_BUILD_TYPE STREQUAL Debug) + SET(linkFlags "-g4") +else() # Either MinSizeRel, RelWithDebInfo or Release, all which run with optimizations enabled. + SET(linkFlags "-O3") +endif() + +set(CMAKE_CXX_FLAGS_RELEASE "-O3 -fexceptions") + +set_target_properties( + libjxljs + PROPERTIES + LINK_FLAGS "\ + --bind \ + -s DISABLE_EXCEPTION_CATCHING=1 \ + -s ASSERTIONS=0 \ + -s NO_EXIT_RUNTIME=1 \ + -s MALLOC=emmalloc \ + -s ALLOW_MEMORY_GROWTH=1 \ + -s TOTAL_MEMORY=1073741824 \ + -s FILESYSTEM=0 \ + -s EXPORTED_FUNCTIONS=[___cxa_is_pointer_type] \ + -s EXPORTED_RUNTIME_METHODS=[ccall] \ + ") \ No newline at end of file diff --git a/packages/libjxl/src/FrameInfo.hpp b/packages/libjxl/src/FrameInfo.hpp new file mode 100644 index 0000000..9bd17a6 --- /dev/null +++ b/packages/libjxl/src/FrameInfo.hpp @@ -0,0 +1,28 @@ +// Copyright (c) Chris Hafey. +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +struct FrameInfo { + /// + /// Width of the image, range [1, 65535]. + /// + uint16_t width; + + /// + /// Height of the image, range [1, 65535]. + /// + uint16_t height; + + /// + /// Number of bits per sample, range [2, 16] + /// + uint8_t bitsPerSample; + + /// + /// Number of components contained in the frame, range [1, 255] + /// + uint8_t componentCount; +}; \ No newline at end of file diff --git a/packages/libjxl/src/JpegXLDecoder.hpp b/packages/libjxl/src/JpegXLDecoder.hpp new file mode 100644 index 0000000..4ef5511 --- /dev/null +++ b/packages/libjxl/src/JpegXLDecoder.hpp @@ -0,0 +1,159 @@ +// Copyright (c) Chris Hafey. +// SPDX-License-Identifier: MIT + +#pragma once + +#include "FrameInfo.hpp" +#include + +#include "jxl/decode.h" +#include "jxl/decode_cxx.h" + +#ifdef __EMSCRIPTEN__ +#include +#endif + +/// +/// JavaScript API for decoding JPEG-LS bistreams with CharLS +/// +class JpegXLDecoder { + public: + /// + /// Constructor for decoding a JPEG-LS image from JavaScript. + /// + JpegXLDecoder() { + } + +#ifdef __EMSCRIPTEN__ + /// + /// Resizes encoded buffer and returns a TypedArray of the buffer allocated + /// in WASM memory space that will hold the JPEG-LS encoded bitstream. + /// JavaScript code needs to copy the JPEG-LS encoded bistream into the + /// returned TypedArray. This copy operation is needed because WASM runs + /// in a sandbox and cannot access memory managed by JavaScript. + /// + emscripten::val getEncodedBuffer(size_t encodedSize) { + encoded_.resize(encodedSize); + return emscripten::val(emscripten::typed_memory_view(encoded_.size(), encoded_.data())); + } + + /// + /// Returns a TypedArray of the buffer allocated in WASM memory space that + /// holds the decoded pixel data + /// + emscripten::val getDecodedBuffer() { + return emscripten::val(emscripten::typed_memory_view(decoded_.size(), decoded_.data())); + } +#else + /// + /// Returns the buffer to store the encoded bytes. This method is not exported + /// to JavaScript, it is intended to be called by C++ code + /// + std::vector& getEncodedBytes() { + return encoded_; + } + + /// + /// Returns the buffer to store the decoded bytes. This method is not exported + /// to JavaScript, it is intended to be called by C++ code + /// + const std::vector& getDecodedBytes() const { + return decoded_; + } +#endif + + /// + /// Decodes the encoded JPEG-LS bitstream. The caller must have copied the + /// JPEG-LS encoded bitstream into the encoded buffer before calling this + /// method, see getEncodedBuffer() above. + /// + int decode() { + auto dec = JxlDecoderMake(nullptr); + + if (JXL_DEC_SUCCESS != JxlDecoderSubscribeEvents(dec.get(), JXL_DEC_BASIC_INFO | + JXL_DEC_COLOR_ENCODING | + JXL_DEC_FULL_IMAGE)) { + return -1; + } + + JxlPixelFormat format; + JxlBasicInfo info; + JxlDecoderSetInput(dec.get(), encoded_.data(), encoded_.size()); + + std::vector icc_profile; + + for (;;) { + JxlDecoderStatus status = JxlDecoderProcessInput(dec.get()); + //printf("Status = %x\n", status); + if (status == JXL_DEC_ERROR) { + return -2; + } else if (status == JXL_DEC_NEED_MORE_INPUT) { + JxlDecoderFlushImage(dec.get()); + return -3; + } else if (status == JXL_DEC_BASIC_INFO) { + if (JXL_DEC_SUCCESS != JxlDecoderGetBasicInfo(dec.get(), &info)) { + return -4; + } + frameInfo_.width = info.xsize; + frameInfo_.height = info.ysize; + frameInfo_.componentCount = info.num_color_channels; + frameInfo_.bitsPerSample = info.bits_per_sample; + JxlDataType dataType = frameInfo_.bitsPerSample <= 8 ? JXL_TYPE_UINT8 : JXL_TYPE_UINT16; + format = {frameInfo_.componentCount, dataType, JXL_NATIVE_ENDIAN, 0}; + } else if (status == JXL_DEC_COLOR_ENCODING) { + // Get the ICC color profile of the pixel data + size_t icc_size; + if (JXL_DEC_SUCCESS != + JxlDecoderGetICCProfileSize( + dec.get(), JXL_COLOR_PROFILE_TARGET_DATA, &icc_size)) { + return -5; + } + icc_profile.resize(icc_size); + if (JXL_DEC_SUCCESS != JxlDecoderGetColorAsICCProfile( + dec.get(), + JXL_COLOR_PROFILE_TARGET_DATA, + icc_profile.data(), icc_profile.size())) { + return -6; + } + } else if (status == JXL_DEC_NEED_IMAGE_OUT_BUFFER) { + size_t buffer_size; + if (JXL_DEC_SUCCESS != + JxlDecoderImageOutBufferSize(dec.get(), &format, &buffer_size)) { + return -7; + } + decoded_.resize(buffer_size); + void* pixels_buffer = (void*)decoded_.data(); + size_t pixels_buffer_size = decoded_.size(); + if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(), &format, + pixels_buffer, + pixels_buffer_size)) { + return -9; + } + } else if (status == JXL_DEC_FULL_IMAGE) { + // Nothing to do. Do not yet return. If the image is an animation, more + // full frames may be decoded. This example only keeps the last one. + } else if (status == JXL_DEC_SUCCESS) { + // All decoding successfully finished. + // It's not required to call JxlDecoderReleaseInput(dec.get()) here since + // the decoder will be destroyed. + return 0; + } else { + return -10; + } + } + return 0; + } + + /// + /// returns the FrameInfo object for the decoded image. + /// + const FrameInfo& getFrameInfo() const { + return frameInfo_; + } + + private: + std::vector encoded_; + std::vector decoded_; + FrameInfo frameInfo_; +}; + diff --git a/packages/libjxl/src/JpegXLEncoder.hpp b/packages/libjxl/src/JpegXLEncoder.hpp new file mode 100644 index 0000000..087d1bb --- /dev/null +++ b/packages/libjxl/src/JpegXLEncoder.hpp @@ -0,0 +1,200 @@ +// Copyright (c) Chris Hafey. +// SPDX-License-Identifier: MIT + +#pragma once + +#include "FrameInfo.hpp" +#include + +#include "jxl/encode.h" +#include "jxl/encode_cxx.h" + +#ifdef __EMSCRIPTEN__ +#include +#endif + +/// +/// JavaScript API for encoding images to JPEG-XL bitstreams +/// +class JpegXLEncoder { + public: + /// + /// Constructor for encoding a JPEG-XL image from JavaScript. + /// + JpegXLEncoder() : effort_(4), progressive_(true), lossless_(true), distance_(0.0f) { + } +#ifdef __EMSCRIPTEN__ + /// + /// Resizes the decoded buffer to accomodate the specified frameInfo. + /// Returns a TypedArray of the buffer allocated in WASM memory space that + /// will hold the pixel data to be encoded. JavaScript code needs + /// to copy the pixel data into the returned TypedArray. This copy + /// operation is needed because WASM runs in a sandbox and cannot access + /// data managed by JavaScript + /// + /// FrameInfo that describes the pixel data to be encoded + /// + /// TypedArray for the buffer allocated in WASM memory space for the + /// source pixel data to be encoded. + /// + emscripten::val getDecodedBuffer(const FrameInfo& frameInfo) { + frameInfo_ = frameInfo; + const size_t bytesPerPixel = (frameInfo_.bitsPerSample + 8 - 1) / 8; + const size_t decodedSize = frameInfo_.width * frameInfo_.height * frameInfo_.componentCount * bytesPerPixel; + decoded_.resize(decodedSize); + return emscripten::val(emscripten::typed_memory_view(decoded_.size(), decoded_.data())); + } + + /// + /// Returns a TypedArray of the buffer allocated in WASM memory space that + /// holds the encoded pixel data. + /// + /// + /// TypedArray for the buffer allocated in WASM memory space for the + /// encoded pixel data. + /// + emscripten::val getEncodedBuffer() { + return emscripten::val(emscripten::typed_memory_view(encoded_.size(), encoded_.data())); + } +#else + /// + /// Returns the buffer to store the decoded bytes. This method is not + /// exported to JavaScript, it is intended to be called by C++ code + /// + std::vector& getDecodedBytes(const FrameInfo& frameInfo) { + frameInfo_ = frameInfo; + return decoded_; + } + + /// + /// Returns the buffer to store the encoded bytes. This method is not + /// exported to JavaScript, it is intended to be called by C++ code + /// + const std::vector& getEncodedBytes() const { + return encoded_; + } +#endif + + /// + /// Sets encoder effort/speed level without affecting decoding speed. + /// Valid values are, from faster to slower speed: + /// 1:lightning + /// 2:thunder + /// 3:falcon (default) + /// 4:cheetah + /// 5:hare + /// 6:wombat + /// 7:squirrel + /// 8:kitten + /// 9:tortoise + /// + void setEffort(int effort) { + effort_ = effort; + } + + /// + /// Sets the progressive flag (default is off/false) + /// + void setProgressive(bool progressive) { + progressive_ = progressive; + } + + /// + /// Sets the quality (default is lossless) + /// + void setQuality(bool lossless, float distance) { + lossless_ = lossless; + distance_ = distance; + } + + /// + /// Executes an JPEG-XL encode using the data in the source buffer. The + /// JavaScript code must copy the source image frame into the source + /// buffer before calling this method. See documentation on getSourceBytes() + /// above + /// + int encode() { + auto enc = JxlEncoderMake(/*memory_manager=*/nullptr); + + JxlDataType dataType = frameInfo_.bitsPerSample <= 8 ? JXL_TYPE_UINT8 : JXL_TYPE_UINT16; + JxlPixelFormat pixel_format = {frameInfo_.componentCount, dataType, JXL_NATIVE_ENDIAN, 0}; + + JxlBasicInfo basic_info; + JxlEncoderInitBasicInfo(&basic_info); + basic_info.bits_per_sample = frameInfo_.bitsPerSample; + basic_info.exponent_bits_per_sample = 0; + basic_info.xsize = frameInfo_.width; + basic_info.ysize = frameInfo_.height; + basic_info.uses_original_profile = 1; + if (JXL_ENC_SUCCESS != JxlEncoderSetBasicInfo(enc.get(), &basic_info)) { + return -1; + } + + if(frameInfo_.componentCount == 1) { + // grayscale path + JxlColorEncoding color_encoding = {}; + color_encoding.transfer_function = JXL_TRANSFER_FUNCTION_GAMMA; + color_encoding.gamma = 0.454550; + color_encoding.color_space = JXL_COLOR_SPACE_GRAY; + color_encoding.rendering_intent = JXL_RENDERING_INTENT_RELATIVE; + color_encoding.white_point = JXL_WHITE_POINT_D65; + if (JXL_ENC_SUCCESS != JxlEncoderSetColorEncoding(enc.get(), &color_encoding)) { + return -2; + } + } else { + JxlColorEncoding color_encoding = {}; + JxlColorEncodingSetToSRGB(&color_encoding, + /*is_gray=*/pixel_format.num_channels < 3); + if (JXL_ENC_SUCCESS != + JxlEncoderSetColorEncoding(enc.get(), &color_encoding)) { + return -2; + } + } + + JxlEncoderOptions* options = JxlEncoderOptionsCreate(enc.get(), nullptr); + JxlEncoderFrameSettingsSetOption(options, JXL_ENC_FRAME_SETTING_EFFORT, effort_); + if(progressive_) { + JxlEncoderFrameSettingsSetOption(options, JXL_ENC_FRAME_SETTING_RESPONSIVE, 1); + JxlEncoderFrameSettingsSetOption(options, JXL_ENC_FRAME_SETTING_QPROGRESSIVE_AC, true); + } + JxlEncoderFrameSettingsSetOption(options, JXL_ENC_FRAME_SETTING_MODULAR_MA_TREE_LEARNING_PERCENT, 0); + JxlEncoderFrameSettingsSetOption(options, JXL_ENC_FRAME_SETTING_MODULAR_GROUP_SIZE, 0); + + if(lossless_) { + JxlEncoderOptionsSetLossless(options, true); + } else { + JxlEncoderOptionsSetDistance(options, distance_); + } + + if (JXL_ENC_SUCCESS != JxlEncoderAddImageFrame(options, + &pixel_format, (void*)decoded_.data(), + decoded_.size())) { + return -3; + } + + encoded_.resize(64); + uint8_t* next_out = encoded_.data(); + size_t avail_out = encoded_.size() - (next_out - encoded_.data()); + JxlEncoderStatus process_result = JXL_ENC_NEED_MORE_OUTPUT; + while (process_result == JXL_ENC_NEED_MORE_OUTPUT) { + process_result = JxlEncoderProcessOutput(enc.get(), &next_out, &avail_out); + if (process_result == JXL_ENC_NEED_MORE_OUTPUT) { + size_t offset = next_out - encoded_.data(); + encoded_.resize(encoded_.size() * 2); + next_out = encoded_.data() + offset; + avail_out = encoded_.size() - offset; + } + } + encoded_.resize(next_out - encoded_.data()); + return 0; + } + + private: + std::vector decoded_; + std::vector encoded_; + FrameInfo frameInfo_; + int effort_; + bool progressive_; + bool lossless_; + float distance_; +}; diff --git a/packages/libjxl/src/jslib.cpp b/packages/libjxl/src/jslib.cpp new file mode 100644 index 0000000..47d31c1 --- /dev/null +++ b/packages/libjxl/src/jslib.cpp @@ -0,0 +1,40 @@ +// Copyright (c) Chris Hafey. +// SPDX-License-Identifier: MIT + +#include "JpegXLDecoder.hpp" +#include "JpegXLEncoder.hpp" + +#include +#include + +using namespace emscripten; + +EMSCRIPTEN_BINDINGS(FrameInfo) { + value_object("FrameInfo") + .field("width", &FrameInfo::width) + .field("height", &FrameInfo::height) + .field("bitsPerSample", &FrameInfo::bitsPerSample) + .field("componentCount", &FrameInfo::componentCount) + ; +} + +EMSCRIPTEN_BINDINGS(JpegXLDecoder) { + class_("JpegXLDecoder") + .constructor<>() + .function("getEncodedBuffer", &JpegXLDecoder::getEncodedBuffer) + .function("getDecodedBuffer", &JpegXLDecoder::getDecodedBuffer) + .function("decode", &JpegXLDecoder::decode) + .function("getFrameInfo", &JpegXLDecoder::getFrameInfo) + ; +} + +EMSCRIPTEN_BINDINGS(JpegXLEncoder) { + class_("JpegXLEncoder") + .constructor<>() + .function("getDecodedBuffer", &JpegXLEncoder::getDecodedBuffer) + .function("getEncodedBuffer", &JpegXLEncoder::getEncodedBuffer) + .function("setEffort", &JpegXLEncoder::setEffort) + .function("setQuality", &JpegXLEncoder::setQuality) + .function("encode", &JpegXLEncoder::encode) + ; +} \ No newline at end of file diff --git a/packages/libjxl/test/browser/index.html b/packages/libjxl/test/browser/index.html new file mode 100644 index 0000000..150a8d2 --- /dev/null +++ b/packages/libjxl/test/browser/index.html @@ -0,0 +1,516 @@ + + + + + + + + + + + +
+ +
+ +
+
+
Status:
+
+
+
Encode Time:
+
Decode Time:
+
Display Time:
+
+
+
Encoded Size:
+
Decoded Size:
+
Compression Ratio:
+
+
+
Resolution:
+
Pixel Format:
+
Component Count:
+
+
+
Min Pixel:
+
Max Pixel:
+
Dynamic Range:
+
+
+
+
+ Decoding Parameters +
+
+
+
+ Encoded Bytes Read: 0 + +
+
+
+
+
+ Encoding Parameters +
+
+
+
+ +
+
+ +
+
+ Distance: 0 + +
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+ + + + + \ No newline at end of file diff --git a/packages/libjxl/test/cpp/CMakeLists.txt b/packages/libjxl/test/cpp/CMakeLists.txt new file mode 100644 index 0000000..e3b34c8 --- /dev/null +++ b/packages/libjxl/test/cpp/CMakeLists.txt @@ -0,0 +1,10 @@ +# Tests need to be added as executables first +add_executable(cpptest main.cpp) + +# Should be linked to the main library, as well as the Catch2 testing library +target_link_libraries(cpptest PRIVATE jxl-static) + +#C++ 14 +target_compile_features(cpptest PUBLIC cxx_std_14) + +set(CMAKE_CXX_FLAGS_RELEASE "-O3") \ No newline at end of file diff --git a/packages/libjxl/test/cpp/main.cpp b/packages/libjxl/test/cpp/main.cpp new file mode 100644 index 0000000..ff20895 --- /dev/null +++ b/packages/libjxl/test/cpp/main.cpp @@ -0,0 +1,180 @@ +// Copyright (c) Chris Hafey. +// SPDX-License-Identifier: MIT + +#include "../../src/JpegXLDecoder.hpp" +#include "../../src/JpegXLEncoder.hpp" + + +#include +#include +#include +#include +#include +#include + + +void readFile(std::string fileName, std::vector& vec) { + // open the file: + std::ifstream file(fileName, std::ios::in | std::ios::binary); + // Stop eating new lines in binary mode!!! + file.unsetf(std::ios::skipws); + + // get its size: + std::streampos fileSize; + file.seekg(0, std::ios::end); + fileSize = file.tellg(); + file.seekg(0, std::ios::beg); + + // reserve capacity + vec.reserve(fileSize); + + // read the data: + vec.insert(vec.begin(), + std::istream_iterator(file), + std::istream_iterator()); + + //std::istreambuf_iterator iter(file); + //std::copy(iter.begin(), iter.end(), std::back_inserter(vec)); +} + +void writeFile(std::string fileName, const std::vector& vec) { + std::ofstream file(fileName, std::ios::out | std::ofstream::binary); + std::copy(vec.begin(), vec.end(), std::ostreambuf_iterator(file)); +} + +enum { NS_PER_SECOND = 1000000000 }; + +void sub_timespec(struct timespec t1, struct timespec t2, struct timespec *td) +{ + td->tv_nsec = t2.tv_nsec - t1.tv_nsec; + td->tv_sec = t2.tv_sec - t1.tv_sec; + if (td->tv_sec > 0 && td->tv_nsec < 0) + { + td->tv_nsec += NS_PER_SECOND; + td->tv_sec--; + } + else if (td->tv_sec < 0 && td->tv_nsec > 0) + { + td->tv_nsec -= NS_PER_SECOND; + td->tv_sec++; + } +} +void decodeFile(const char* inPath, size_t iterations = 1) { + //std::string inPath = "test/fixtures/jxl-progressive/"; + //inPath += imageName; + + JpegXLDecoder decoder; + std::vector& encodedBytes = decoder.getEncodedBytes(); + readFile(inPath, encodedBytes); + + timespec start, finish, delta; + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); + for(int i=0; i < iterations; i++) { + const size_t result = decoder.decode(); + if(result !=0) { + printf("ERROR - decode() returned = %ld (length=%ld)\n", result, encodedBytes.size()); + } + } + + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &finish); + sub_timespec(start, finish, &delta); + auto frameInfo = decoder.getFrameInfo(); + + auto ns = delta.tv_sec * 1000000000.0 + delta.tv_nsec; + auto totalTimeMS = ns / 1000000.0; + auto timePerFrameMS = ns / 1000000.0 / (double)iterations; + auto pixels = (frameInfo.width * frameInfo.height); + auto megaPixels = (double)pixels / (1024.0 * 1024.0); + auto fps = 1000 / timePerFrameMS; + auto mps = (double)(megaPixels) * fps; + + printf("Native-decode %s Pixels=%d megaPixels=%f TotalTime= %.2f ms TPF=%.2f ms (%.2f MP/s, %.2f FPS)\n", inPath, pixels, megaPixels, totalTimeMS, timePerFrameMS, mps, fps); +} + + +void encodeFile(const char* imageName, const FrameInfo frameInfo, size_t iterations = 1) { + std::string inPath = "test/fixtures/raw/"; + inPath += imageName; + inPath += ".RAW"; + + JpegXLEncoder encoder; + std::vector& rawBytes = encoder.getDecodedBytes(frameInfo); + readFile(inPath, rawBytes); + + timespec start, finish, delta; + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); + + for(int i=0; i < iterations; i++) { + const size_t result = encoder.encode(); + if(result !=0) { + printf("ERROR - encode() returned = %ld (length=%ld)\n", result, rawBytes.size()); + } + } + + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &finish); + sub_timespec(start, finish, &delta); + + auto ns = delta.tv_sec * 1000000000.0 + delta.tv_nsec; + auto totalTimeMS = ns / 1000000.0; + auto timePerFrameMS = ns / 1000000.0 / (double)iterations; + auto pixels = (frameInfo.width * frameInfo.height); + auto megaPixels = (double)pixels / (1024.0 * 1024.0); + auto fps = 1000 / timePerFrameMS; + auto mps = (double)(megaPixels) * fps; + + printf("Native-encode %s Pixels=%d megaPixels=%f TotalTime= %.2f ms TPF=%.2f ms (%.2f MP/s, %.2f FPS)\n", imageName, pixels, megaPixels, totalTimeMS, timePerFrameMS, mps, fps); +} + +int main(int argc, char** argv) { + const size_t iterations = (argc > 1) ? atoi(argv[1]) : 10; + JpegXLEncoder encoder; + + encodeFile("CT1", {.width = 512, .height = 512, .bitsPerSample = 16, .componentCount = 1}, iterations); + /*encodeFile("CT2", {.width = 512, .height = 512, .bitsPerSample = 16, .componentCount = 1}, iterations); + encodeFile("MG1", {.width = 3064, .height = 4664, .bitsPerSample = 16, .componentCount = 1}, iterations); + encodeFile("MR1", {.width = 512, .height = 512, .bitsPerSample = 16, .componentCount = 1}, iterations); + encodeFile("MR2", {.width = 1024, .height = 1024, .bitsPerSample = 16, .componentCount = 1}, iterations); + encodeFile("MR3", {.width = 512, .height = 512, .bitsPerSample = 16, .componentCount = 1}, iterations); + encodeFile("MR4", {.width = 512, .height = 512, .bitsPerSample = 16, .componentCount = 1}, iterations); + encodeFile("NM1", {.width = 256, .height = 1024, .bitsPerSample = 16, .componentCount = 1}, iterations); + encodeFile("RG1", {.width = 1841, .height = 1955, .bitsPerSample = 16, .componentCount = 1}, iterations); + encodeFile("RG2", {.width = 1760, .height = 2140, .bitsPerSample = 16, .componentCount = 1}, iterations); + encodeFile("RG3", {.width = 1760, .height = 1760, .bitsPerSample = 16, .componentCount = 1}, iterations); + encodeFile("SC1", {.width = 2048, .height = 2487, .bitsPerSample = 16, .componentCount = 1}, iterations); + encodeFile("US1", {.width = 640, .height = 480, .bitsPerSample = 8, .componentCount = 3}, iterations); + encodeFile("VL1", {.width = 756, .height = 486, .bitsPerSample = 8, .componentCount = 3}, iterations); + encodeFile("VL2", {.width = 756, .height = 486, .bitsPerSample = 8, .componentCount = 3}, iterations); + encodeFile("VL3", {.width = 756, .height = 486, .bitsPerSample = 8, .componentCount = 3}, iterations); + encodeFile("VL4", {.width = 2226, .height = 1868, .bitsPerSample = 8, .componentCount = 3}, iterations); + encodeFile("VL5", {.width = 2670, .height = 3340, .bitsPerSample = 8, .componentCount = 3}, iterations); + encodeFile("VL6", {.width = 756, .height = 486, .bitsPerSample = 8, .componentCount = 3}, iterations); + encodeFile("XA1", {.width = 1024, .height = 1024, .bitsPerSample = 16, .componentCount = 1}, iterations); +*/ + decodeFile("test/fixtures/jxl-progressive/CT1.j2k.png.jxl", iterations); + //decodeFile("CT2", iterations); + decodeFile("test/fixtures/jxl-progressive/MG1.j2k.png.jxl", iterations); + + + decodeFile("test/fixtures/jxl/CT1.jxl", iterations); + decodeFile("test/fixtures/jxl/MG1.jxl", iterations); + + /*decodeFile("MR1", iterations); + decodeFile("MR2", iterations); + decodeFile("MR3", iterations); + decodeFile("MR4", iterations); + decodeFile("NM1", iterations); + decodeFile("RG1", iterations); + decodeFile("RG2", iterations); + decodeFile("RG3", iterations); + decodeFile("SC1", iterations); + decodeFile("US1", iterations); + decodeFile("VL1", iterations); + decodeFile("VL2", iterations); + decodeFile("VL3", iterations); + decodeFile("VL4", iterations); + decodeFile("VL5", iterations); + decodeFile("VL6", iterations); + decodeFile("XA1", iterations);*/ + + return 0; +} \ No newline at end of file diff --git a/packages/libjxl/test/fixtures/jxl-progressive/CT1-0decomp.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/CT1-0decomp.j2k.png.jxl new file mode 100644 index 0000000..909a409 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/CT1-0decomp.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/CT1.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/CT1.j2k.png.jxl new file mode 100644 index 0000000..909a409 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/CT1.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/CT2.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/CT2.j2k.png.jxl new file mode 100644 index 0000000..ef64395 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/CT2.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/M2.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/M2.j2k.png.jxl new file mode 100644 index 0000000..52dc105 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/M2.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/MG1.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/MG1.j2k.png.jxl new file mode 100644 index 0000000..9234e73 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/MG1.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/MR1.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/MR1.j2k.png.jxl new file mode 100644 index 0000000..e77407c Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/MR1.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/MR2.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/MR2.j2k.png.jxl new file mode 100644 index 0000000..52dc105 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/MR2.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/MR3.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/MR3.j2k.png.jxl new file mode 100644 index 0000000..a4b33f3 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/MR3.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/MR4.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/MR4.j2k.png.jxl new file mode 100644 index 0000000..2497fd8 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/MR4.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/NM1.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/NM1.j2k.png.jxl new file mode 100644 index 0000000..c9e48ea Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/NM1.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/RG1.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/RG1.j2k.png.jxl new file mode 100644 index 0000000..df094e6 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/RG1.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/RG2.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/RG2.j2k.png.jxl new file mode 100644 index 0000000..2a76dd9 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/RG2.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/RG3.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/RG3.j2k.png.jxl new file mode 100644 index 0000000..df9778a Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/RG3.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/SC1.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/SC1.j2k.png.jxl new file mode 100644 index 0000000..d9ea2f3 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/SC1.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/US1.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/US1.j2k.png.jxl new file mode 100644 index 0000000..e542ddc Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/US1.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/VL1.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/VL1.j2k.png.jxl new file mode 100644 index 0000000..1f35160 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/VL1.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/VL2.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/VL2.j2k.png.jxl new file mode 100644 index 0000000..67a9f9e Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/VL2.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/VL3.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/VL3.j2k.png.jxl new file mode 100644 index 0000000..d341b79 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/VL3.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/VL4.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/VL4.j2k.png.jxl new file mode 100644 index 0000000..0ea8039 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/VL4.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/VL5.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/VL5.j2k.png.jxl new file mode 100644 index 0000000..39a0ad8 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/VL5.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/VL6.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/VL6.j2k.png.jxl new file mode 100644 index 0000000..23adf86 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/VL6.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/XA1.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/XA1.j2k.png.jxl new file mode 100644 index 0000000..88a53d9 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/XA1.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl-progressive/image.j2k.png.jxl b/packages/libjxl/test/fixtures/jxl-progressive/image.j2k.png.jxl new file mode 100644 index 0000000..401924e Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl-progressive/image.j2k.png.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/CT1.jxl b/packages/libjxl/test/fixtures/jxl/CT1.jxl new file mode 100644 index 0000000..24482c6 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/CT1.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/CT2.jxl b/packages/libjxl/test/fixtures/jxl/CT2.jxl new file mode 100644 index 0000000..5c5c46d Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/CT2.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/MG1.jxl b/packages/libjxl/test/fixtures/jxl/MG1.jxl new file mode 100644 index 0000000..b341d44 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/MG1.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/MR1.jxl b/packages/libjxl/test/fixtures/jxl/MR1.jxl new file mode 100644 index 0000000..6f24206 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/MR1.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/MR2.jxl b/packages/libjxl/test/fixtures/jxl/MR2.jxl new file mode 100644 index 0000000..b1213bc Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/MR2.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/MR3.jxl b/packages/libjxl/test/fixtures/jxl/MR3.jxl new file mode 100644 index 0000000..14b5e88 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/MR3.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/MR4.jxl b/packages/libjxl/test/fixtures/jxl/MR4.jxl new file mode 100644 index 0000000..021599e Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/MR4.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/NM1.jxl b/packages/libjxl/test/fixtures/jxl/NM1.jxl new file mode 100644 index 0000000..9c45780 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/NM1.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/RG1.jxl b/packages/libjxl/test/fixtures/jxl/RG1.jxl new file mode 100644 index 0000000..1427a0b Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/RG1.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/RG2.jxl b/packages/libjxl/test/fixtures/jxl/RG2.jxl new file mode 100644 index 0000000..6fd47eb Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/RG2.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/RG3.jxl b/packages/libjxl/test/fixtures/jxl/RG3.jxl new file mode 100644 index 0000000..0b989be Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/RG3.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/SC1.jxl b/packages/libjxl/test/fixtures/jxl/SC1.jxl new file mode 100644 index 0000000..4fa7ab1 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/SC1.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/US1.jxl b/packages/libjxl/test/fixtures/jxl/US1.jxl new file mode 100644 index 0000000..932be57 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/US1.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/VL1.jxl b/packages/libjxl/test/fixtures/jxl/VL1.jxl new file mode 100644 index 0000000..d37b004 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/VL1.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/VL2.jxl b/packages/libjxl/test/fixtures/jxl/VL2.jxl new file mode 100644 index 0000000..819c439 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/VL2.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/VL3.jxl b/packages/libjxl/test/fixtures/jxl/VL3.jxl new file mode 100644 index 0000000..5db821c Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/VL3.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/VL4.jxl b/packages/libjxl/test/fixtures/jxl/VL4.jxl new file mode 100644 index 0000000..221d085 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/VL4.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/VL5.jxl b/packages/libjxl/test/fixtures/jxl/VL5.jxl new file mode 100644 index 0000000..e1473e3 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/VL5.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/VL6.jxl b/packages/libjxl/test/fixtures/jxl/VL6.jxl new file mode 100644 index 0000000..893f95e Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/VL6.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/XA1.jxl b/packages/libjxl/test/fixtures/jxl/XA1.jxl new file mode 100644 index 0000000..2424d29 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/XA1.jxl differ diff --git a/packages/libjxl/test/fixtures/jxl/nature_picture.jxl b/packages/libjxl/test/fixtures/jxl/nature_picture.jxl new file mode 100644 index 0000000..f700871 Binary files /dev/null and b/packages/libjxl/test/fixtures/jxl/nature_picture.jxl differ diff --git a/packages/libjxl/test/fixtures/raw/CT1.RAW b/packages/libjxl/test/fixtures/raw/CT1.RAW new file mode 100644 index 0000000..92cca6a Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/CT1.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/CT2.RAW b/packages/libjxl/test/fixtures/raw/CT2.RAW new file mode 100644 index 0000000..ce0820b Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/CT2.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/MG1.RAW b/packages/libjxl/test/fixtures/raw/MG1.RAW new file mode 100644 index 0000000..c68aab2 Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/MG1.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/MR1.RAW b/packages/libjxl/test/fixtures/raw/MR1.RAW new file mode 100644 index 0000000..64a37d0 Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/MR1.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/MR2.RAW b/packages/libjxl/test/fixtures/raw/MR2.RAW new file mode 100644 index 0000000..c974155 Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/MR2.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/MR3.RAW b/packages/libjxl/test/fixtures/raw/MR3.RAW new file mode 100644 index 0000000..38d772e Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/MR3.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/MR4.RAW b/packages/libjxl/test/fixtures/raw/MR4.RAW new file mode 100644 index 0000000..8dac045 Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/MR4.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/NM1.RAW b/packages/libjxl/test/fixtures/raw/NM1.RAW new file mode 100644 index 0000000..3c9a30f Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/NM1.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/RG1.RAW b/packages/libjxl/test/fixtures/raw/RG1.RAW new file mode 100644 index 0000000..2931d9a Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/RG1.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/RG2.RAW b/packages/libjxl/test/fixtures/raw/RG2.RAW new file mode 100644 index 0000000..3f25406 Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/RG2.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/RG3.RAW b/packages/libjxl/test/fixtures/raw/RG3.RAW new file mode 100644 index 0000000..0c8bc10 Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/RG3.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/SC1.RAW b/packages/libjxl/test/fixtures/raw/SC1.RAW new file mode 100644 index 0000000..493959c Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/SC1.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/US1.RAW b/packages/libjxl/test/fixtures/raw/US1.RAW new file mode 100644 index 0000000..1476bef Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/US1.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/VL1.RAW b/packages/libjxl/test/fixtures/raw/VL1.RAW new file mode 100644 index 0000000..d0fafcb Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/VL1.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/VL2.RAW b/packages/libjxl/test/fixtures/raw/VL2.RAW new file mode 100644 index 0000000..ad5f317 Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/VL2.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/VL3.RAW b/packages/libjxl/test/fixtures/raw/VL3.RAW new file mode 100644 index 0000000..1e001ea Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/VL3.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/VL4.RAW b/packages/libjxl/test/fixtures/raw/VL4.RAW new file mode 100644 index 0000000..e3b0f49 Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/VL4.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/VL5.RAW b/packages/libjxl/test/fixtures/raw/VL5.RAW new file mode 100644 index 0000000..18d0e9c Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/VL5.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/VL6.RAW b/packages/libjxl/test/fixtures/raw/VL6.RAW new file mode 100644 index 0000000..f56a272 Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/VL6.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/XA1.RAW b/packages/libjxl/test/fixtures/raw/XA1.RAW new file mode 100644 index 0000000..18b3045 Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/XA1.RAW differ diff --git a/packages/libjxl/test/fixtures/raw/nature_picture.raw b/packages/libjxl/test/fixtures/raw/nature_picture.raw new file mode 100644 index 0000000..e25a4b8 Binary files /dev/null and b/packages/libjxl/test/fixtures/raw/nature_picture.raw differ diff --git a/packages/libjxl/test/node/codec-helper.js b/packages/libjxl/test/node/codec-helper.js new file mode 100644 index 0000000..a60972e --- /dev/null +++ b/packages/libjxl/test/node/codec-helper.js @@ -0,0 +1,53 @@ +function decode(decoder, encodedBitStream, iterations=1) { + const encodedBuffer = decoder.getEncodedBuffer(encodedBitStream.length) + console.log("🚀 ~ decode ~ encodedBitStream:", encodedBitStream) + console.log("🚀 ~ decode ~ encodedBuffer:", encodedBuffer) + encodedBuffer.set(encodedBitStream) + + const beginDecode = process.hrtime(); + for(let i=0; i < iterations; i++) { + decoder.decode() + } + + const decodeDuration = process.hrtime(beginDecode); // hrtime returns seconds/nanoseconds tuple + console.log("decodeDuration=", decodeDuration); + const decodeDurationInSeconds = (decodeDuration[0] + (decodeDuration[1] / 1000000000)); + console.log("decodeDurationInSections", decodeDurationInSeconds, decodeDuration[0], decodeDuration[1], iterations); + const decodeTimeMS = ((decodeDurationInSeconds / iterations * 1000)) + console.log("decodeTimeMS", decodeTimeMS); + const frameInfo = decoder.getFrameInfo() + const pixels = decoder.getDecodedBuffer() + + return { + frameInfo, + pixels, + decodeTimeMS + } +} + +function encode(encoder, uncompressedImageFrame, imageFrame, iterations = 1) { + const decodedBytes = encoder.getDecodedBuffer(imageFrame); + console.log("🚀 ~ encode ~ imageFrame:", imageFrame) + console.log("🚀 ~ encode ~ decodedBytes:", decodedBytes) + decodedBytes.set(uncompressedImageFrame); + + const encodeBegin = process.hrtime(); + for(let i=0; i < iterations;i++) { + encoder.encode(); + } + + const encodeDuration = process.hrtime(encodeBegin); + const encodeDurationInSeconds = (encodeDuration[0] + (encodeDuration[1] / 1000000000)); + const encodeTimeMS = ((encodeDurationInSeconds / iterations * 1000)) + const encodedBytes = encoder.getEncodedBuffer(); + + return { + encodedBytes, + encodeTimeMS + } +} + +module.exports = { + decode, + encode +} \ No newline at end of file diff --git a/packages/libjxl/test/node/index.js b/packages/libjxl/test/node/index.js new file mode 100644 index 0000000..e60ab70 --- /dev/null +++ b/packages/libjxl/test/node/index.js @@ -0,0 +1,61 @@ +// Copyright (c) Chris Hafey. +// SPDX-License-Identifier: MIT +let libjxljs = require('../../dist/libjxljs.js'); +const codecHelper = require('./codec-helper.js') +const fs = require('fs') + +function decodeFile(codec, imageName, iterations = 1) { + const encodedImagePath = '../fixtures/jxl/' + imageName + ".jxl" + encodedBitStream = fs.readFileSync(encodedImagePath) + const decoder = new codec.JpegXLDecoder() + const result = codecHelper.decode(decoder, encodedBitStream, iterations) + console.log("WASM-decode ", imageName, result.decodeTimeMS); + decoder.delete(); + return result +} + +function encodeFile(codec, imageName, imageFrame, iterations = 1) { + const pathToUncompressedImageFrame = '../fixtures/raw/' + imageName + ".RAW" + const uncompressedImageFrame = fs.readFileSync(pathToUncompressedImageFrame); + const encoder = new codec.JpegXLEncoder(); + //encoder.setQuality(false, 0.001); + const result = codecHelper.encode(encoder, uncompressedImageFrame, imageFrame, iterations) + console.log("WASM-encode ", imageName, result.encodeTimeMS); + encoder.delete(); + return result +} + +function main(codec) { + const iterations = isNaN(parseInt(process.argv[process.argv.length-1])) ? 1 : parseInt(process.argv[process.argv.length-1]); + encodeFile(codec, 'CT1', {width: 512, height: 512, bitsPerSample: 16, componentCount: 1, isSigned: true}, iterations) + encodeFile(codec, 'CT2', {width: 512, height: 512, bitsPerSample: 16, componentCount: 1, isSigned: true}, iterations); + encodeFile(codec, 'MG1', {width: 3064, height: 4774, bitsPerSample: 16, componentCount: 1, isSigned: false}, iterations); + encodeFile(codec, 'MR1', {width: 512, height: 512, bitsPerSample: 16, componentCount: 1, isSigned: true}, iterations); + encodeFile(codec, 'MR2', {width: 1024, height: 1024, bitsPerSample: 16, componentCount: 1, isSigned: false}, iterations); + encodeFile(codec, 'MR3', {width: 512, height: 512, bitsPerSample: 16, componentCount: 1, isSigned: true}, iterations); + encodeFile(codec, 'MR4', {width: 512, height: 512, bitsPerSample: 16, componentCount: 1, isSigned: false}, iterations); + encodeFile(codec, 'NM1', {width: 256, height: 1024, bitsPerSample: 16, componentCount: 1, isSigned: true}, iterations); + encodeFile(codec, 'RG1', {width: 1841, height: 1955, bitsPerSample: 16, componentCount: 1, isSigned: false}, iterations); + encodeFile(codec, 'RG2', {width: 1760, height: 2140, bitsPerSample: 16, componentCount: 1, isSigned: false}, iterations); + encodeFile(codec, 'RG3', {width: 1760, height: 1760, bitsPerSample: 16, componentCount: 1, isSigned: false}, iterations); + encodeFile(codec, 'SC1', {width: 2048, height: 2487, bitsPerSample: 16, componentCount: 1, isSigned: false}, iterations); + encodeFile(codec, 'XA1', {width: 1024, height: 1024, bitsPerSample: 16, componentCount: 1, isSigned: false}, iterations); + decodeFile(codec, 'CT1', iterations) + decodeFile(codec, 'CT2', iterations) + decodeFile(codec, 'MG1', iterations) + decodeFile(codec, 'MR1', iterations) + decodeFile(codec, 'MR2', iterations) + decodeFile(codec, 'MR3', iterations) + decodeFile(codec, 'MR4', iterations) + decodeFile(codec, 'NM1', iterations) + decodeFile(codec, 'RG1', iterations) + decodeFile(codec, 'RG2', iterations) + decodeFile(codec, 'RG3', iterations) + decodeFile(codec, 'SC1', iterations) + decodeFile(codec, 'XA1', iterations) +} + +libjxljs.onRuntimeInitialized = async _ => { + main(libjxljs); +} + diff --git a/packages/libjxl/test/node/package.json b/packages/libjxl/test/node/package.json new file mode 100644 index 0000000..16884be --- /dev/null +++ b/packages/libjxl/test/node/package.json @@ -0,0 +1,12 @@ +{ + "name": "node", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "node index.js --experimental-wasm-simd" + }, + "keywords": [], + "author": "", + "license": "ISC" + } \ No newline at end of file diff --git a/packages/openjpeg/extern/openjpeg b/packages/openjpeg/extern/openjpeg index 2d60670..6af3931 160000 --- a/packages/openjpeg/extern/openjpeg +++ b/packages/openjpeg/extern/openjpeg @@ -1 +1 @@ -Subproject commit 2d606701e8b7aa83f657d113c3367508e99bd12b +Subproject commit 6af39314bdb43cb9c7adcdbc7aa9381af42b52ba