From d91853e7112a8280b01a1b949020d68234effe7b Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 11 Aug 2022 18:06:47 +0200 Subject: [PATCH 01/18] Yay it compiles --- build.sh | 46 +++++++++++++++++++++- build/patches/brotli-fix-static-name.patch | 46 ++++++++++++++++++++++ build/patches/libjxl-deps.patch | 29 ++++++++++++++ playground/src/playground-runner.html | 1 + test/unit/index.html | 1 + 5 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 build/patches/brotli-fix-static-name.patch create mode 100644 build/patches/libjxl-deps.patch diff --git a/build.sh b/build.sh index f0d2c9c86..f3724cde0 100755 --- a/build.sh +++ b/build.sh @@ -116,7 +116,10 @@ VERSION_GLIB=2.73.3 # https://gitlab.gnome.org/GNOME/glib VERSION_EXPAT=2.4.8 # https://github.com/libexpat/libexpat VERSION_EXIF=0.6.24 # https://github.com/libexif/libexif VERSION_LCMS2=2.13.1 # https://github.com/mm2/Little-CMS +VERSION_HWY=1.0.0 # https://github.com/google/highway +VERSION_BROTLI=f4153a # https://github.com/google/brotli VERSION_JPEG=5c6a0f0 # https://github.com/mozilla/mozjpeg +VERSION_JXL=a4ad91a # https://github.com/libjxl/libjxl VERSION_SPNG=0.7.2 # https://github.com/randy408/libspng VERSION_IMAGEQUANT=2.4.1 # https://github.com/lovell/libimagequant VERSION_CGIF=0.3.0 # https://github.com/dloebl/cgif @@ -250,6 +253,30 @@ test -f "$TARGET/lib/pkgconfig/lcms2.pc" || ( make install SUBDIRS='src include' ) +echo "=============================================" +echo "Compiling hwy" +echo "=============================================" +test -f "$TARGET/lib/pkgconfig/libhwy.pc" || ( + mkdir $DEPS/hwy + curl -Ls https://github.com/google/highway/archive/$VERSION_HWY.tar.gz | tar xzC $DEPS/hwy --strip-components=1 + cd $DEPS/hwy + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DHWY_FORCE_STATIC_LIBS=TRUE \ + -DBUILD_TESTING=FALSE -DHWY_ENABLE_CONTRIB=FALSE -DHWY_ENABLE_EXAMPLES=FALSE + make -C _build install +) + +echo "=============================================" +echo "Compiling brotli" +echo "=============================================" +test -f "$TARGET/lib/pkgconfig/libbrotlicommon.pc" || ( + mkdir $DEPS/brotli + curl -Ls https://github.com/google/brotli/archive/$VERSION_BROTLI.tar.gz | tar xzC $DEPS/brotli --strip-components=1 + cd $DEPS/brotli + patch -p1 <$SOURCE_DIR/build/patches/brotli-fix-static-name.patch + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET + make -C _build install +) + echo "=============================================" echo "Compiling jpeg" echo "=============================================" @@ -263,6 +290,23 @@ test -f "$TARGET/lib/pkgconfig/libjpeg.pc" || ( make -C _build install ) +echo "=============================================" +echo "Compiling jxl" +echo "=============================================" +test -f "$TARGET/lib/pkgconfig/libjxl.pc" || ( + mkdir $DEPS/jxl + curl -Ls https://github.com/libjxl/libjxl/archive/$VERSION_JXL.tar.gz | tar xzC $DEPS/jxl --strip-components=1 + cd $DEPS/jxl + patch -p1 <$SOURCE_DIR/build/patches/libjxl-deps.patch + # Download dependencies for internal linking. When this lib stabilizes, these deps should be compiled externally to avoid bloat. + ./deps.sh + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DBUILD_TESTING=OFF -DJPEGXL_STATIC=TRUE \ + -DJPEGXL_ENABLE_FUZZERS=FALSE -DJPEGXL_ENABLE_DOXYGEN=FALSE \ + -DJPEGXL_ENABLE_MANPAGES=FALSE -DJPEGXL_ENABLE_BENCHMARK=FALSE -DJPEGXL_ENABLE_EXAMPLES=FALSE -DJPEGXL_ENABLE_JNI=FALSE \ + -DJPEGXL_ENABLE_SJPEG=FALSE -DJPEGXL_ENABLE_OPENEXR=FALSE #-DJPEGXL_FORCE_SYSTEM_HWY=TRUE -DJPEGXL_FORCE_SYSTEM_BROTLI=TRUE + make -C _build install +) + echo "=============================================" echo "Compiling spng" echo "=============================================" @@ -349,7 +393,7 @@ test -f "$TARGET/lib/pkgconfig/vips.pc" || ( sed -i'.bak' "/subdir('cplusplus')/{N;N;N;N;N;d;}" meson.build meson setup _build --prefix=$TARGET --cross-file=$MESON_CROSS --default-library=static --buildtype=release \ -Ddeprecated=false -Dintrospection=false -Dauto_features=disabled -Dcgif=enabled -Dexif=enabled \ - -Dimagequant=enabled -Djpeg=enabled -Dlcms=enabled -Dspng=enabled -Dtiff=enabled -Dwebp=enabled \ + -Dimagequant=enabled -Djpeg=enabled -Djpeg-xl=enabled -Dlcms=enabled -Dspng=enabled -Dtiff=enabled -Dwebp=enabled \ -Dnsgif=true -Dppm=true -Danalyze=true -Dradiance=true ninja -C _build install ) diff --git a/build/patches/brotli-fix-static-name.patch b/build/patches/brotli-fix-static-name.patch new file mode 100644 index 000000000..a35a4fc6f --- /dev/null +++ b/build/patches/brotli-fix-static-name.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Anton +Date: Thu Aug 11 17:17:52 2022 +0200 +Subject: [PATCH 1/1] Fix incorrect static lib names + +See: https://github.com/google/brotli/issues/795 + +Upstream-Status: Inappropriate [hack] +This is just a hack that only works for the emscripten build. Solving this issue properly requires substantial +changes to the makefiles, which also means substantial testing to make sure it works with all build systems. + +diff --git a/scripts/libbrotlicommon.pc.in b/scripts/libbrotlicommon.pc.in +index 1111111..2222222 100644 +--- a/scripts/libbrotlicommon.pc.in ++++ b/scripts/libbrotlicommon.pc.in +@@ -7,5 +7,5 @@ Name: libbrotlicommon + URL: https://github.com/google/brotli + Description: Brotli common dictionary library + Version: @PACKAGE_VERSION@ +-Libs: -L${libdir} -lbrotlicommon ++Libs: -L${libdir} -lbrotlicommon-static + Cflags: -I${includedir} +diff --git a/scripts/libbrotlidec.pc.in b/scripts/libbrotlidec.pc.in +index 1111111..2222222 100644 +--- a/scripts/libbrotlidec.pc.in ++++ b/scripts/libbrotlidec.pc.in +@@ -7,6 +7,6 @@ Name: libbrotlidec + URL: https://github.com/google/brotli + Description: Brotli decoder library + Version: @PACKAGE_VERSION@ +-Libs: -L${libdir} -lbrotlidec ++Libs: -L${libdir} -lbrotlidec-static + Requires.private: libbrotlicommon >= 1.0.2 + Cflags: -I${includedir} +diff --git a/scripts/libbrotlienc.pc.in b/scripts/libbrotlienc.pc.in +index 1111111..2222222 100644 +--- a/scripts/libbrotlienc.pc.in ++++ b/scripts/libbrotlienc.pc.in +@@ -7,6 +7,6 @@ Name: libbrotlienc + URL: https://github.com/google/brotli + Description: Brotli encoder library + Version: @PACKAGE_VERSION@ +-Libs: -L${libdir} -lbrotlienc ++Libs: -L${libdir} -lbrotlienc-static + Requires.private: libbrotlicommon >= 1.0.2 + Cflags: -I${includedir} diff --git a/build/patches/libjxl-deps.patch b/build/patches/libjxl-deps.patch new file mode 100644 index 000000000..77b110ba7 --- /dev/null +++ b/build/patches/libjxl-deps.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Anton +Date: Thu Aug 11 08:15:47 2022 +0200 +Subject: [PATCH 1/1] Alter how libjxl downloads dependencies + +Upstream-Status: Pending + +diff --git a/deps.sh b/deps.sh +index 1111111..2222222 100644 +--- a/deps.sh ++++ b/deps.sh +@@ -59,7 +59,7 @@ download_github() { + + + main() { +- if git -C "${MYDIR}" rev-parse; then ++ if false && git -C "${MYDIR}" rev-parse; then + cat >&2 < Date: Sat, 13 Aug 2022 13:34:41 +0200 Subject: [PATCH 02/18] brotli: prefer upstream patch --- build.sh | 3 +- build/patches/brotli-655.patch | 130 +++++++++++++++++++++ build/patches/brotli-fix-static-name.patch | 46 -------- 3 files changed, 132 insertions(+), 47 deletions(-) create mode 100644 build/patches/brotli-655.patch delete mode 100644 build/patches/brotli-fix-static-name.patch diff --git a/build.sh b/build.sh index f3724cde0..f308b6943 100755 --- a/build.sh +++ b/build.sh @@ -272,7 +272,8 @@ test -f "$TARGET/lib/pkgconfig/libbrotlicommon.pc" || ( mkdir $DEPS/brotli curl -Ls https://github.com/google/brotli/archive/$VERSION_BROTLI.tar.gz | tar xzC $DEPS/brotli --strip-components=1 cd $DEPS/brotli - patch -p1 <$SOURCE_DIR/build/patches/brotli-fix-static-name.patch + # https://github.com/google/brotli/pull/655 + patch -p1 <$SOURCE_DIR/build/patches/brotli-655.patch emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET make -C _build install ) diff --git a/build/patches/brotli-655.patch b/build/patches/brotli-655.patch new file mode 100644 index 000000000..334d281f2 --- /dev/null +++ b/build/patches/brotli-655.patch @@ -0,0 +1,130 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Adrian Perez de Castro +Date: Mon, 7 Sep 2020 12:14:22 +0300 +Subject: [PATCH 1/1] CMake: Allow using BUILD_SHARED_LIBS to choose static/shared + libs + +By convention projects using CMake which can build either static or +shared libraries use a BUILD_SHARED_LIBS flag to allow selecting between +both: the add_library() command automatically switches between both using +this variable when the library kind is not passed to add_library(). It +is also usual to expose the BUILD_SHARED_LIBS as an user-facing setting +with the option() command. + +This way, the following will both work as expected: + + % cmake -DBUILD_SHARED_LIBS=OFF ... + % cmake -DBUILS_SHARED_LIBS=ON ... + +This is helpful for distributions which need (or want) to build only +static libraries. + +Upstream-Status: Submitted [https://github.com/google/brotli/pull/655] + +[Fix: ensure libraries are still installed on Emscripten] +Signed-off-by: Kleis Auke Wolthuizen + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 1111111..2222222 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -11,6 +11,8 @@ cmake_minimum_required(VERSION 2.8.6) + cmake_policy(SET CMP0048 NEW) + project(brotli C) + ++option(BUILD_SHARED_LIBS "Build shared libraries" ON) ++ + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to Release as none was specified.") + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE) +@@ -142,10 +144,6 @@ set(BROTLI_LIBRARIES_CORE brotlienc brotlidec brotlicommon) + set(BROTLI_LIBRARIES ${BROTLI_LIBRARIES_CORE} ${LIBM_LIBRARY}) + mark_as_advanced(BROTLI_LIBRARIES) + +-set(BROTLI_LIBRARIES_CORE_STATIC brotlienc-static brotlidec-static brotlicommon-static) +-set(BROTLI_LIBRARIES_STATIC ${BROTLI_LIBRARIES_CORE_STATIC} ${LIBM_LIBRARY}) +-mark_as_advanced(BROTLI_LIBRARIES_STATIC) +- + if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + add_definitions(-DOS_LINUX) + elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") +@@ -166,29 +164,25 @@ transform_sources_list("scripts/sources.lst" "${CMAKE_CURRENT_BINARY_DIR}/source + include("${CMAKE_CURRENT_BINARY_DIR}/sources.lst.cmake") + + if(BROTLI_EMSCRIPTEN) +- set(BROTLI_SHARED_LIBS "") +-else() +- set(BROTLI_SHARED_LIBS brotlicommon brotlidec brotlienc) +- add_library(brotlicommon SHARED ${BROTLI_COMMON_C}) +- add_library(brotlidec SHARED ${BROTLI_DEC_C}) +- add_library(brotlienc SHARED ${BROTLI_ENC_C}) ++ set(BUILD_SHARED_LIBS OFF) + endif() + +-set(BROTLI_STATIC_LIBS brotlicommon-static brotlidec-static brotlienc-static) +-add_library(brotlicommon-static STATIC ${BROTLI_COMMON_C}) +-add_library(brotlidec-static STATIC ${BROTLI_DEC_C}) +-add_library(brotlienc-static STATIC ${BROTLI_ENC_C}) ++add_library(brotlicommon ${BROTLI_COMMON_C}) ++add_library(brotlidec ${BROTLI_DEC_C}) ++add_library(brotlienc ${BROTLI_ENC_C}) + + # Older CMake versions does not understand INCLUDE_DIRECTORIES property. + include_directories(${BROTLI_INCLUDE_DIRS}) + +-foreach(lib IN LISTS BROTLI_SHARED_LIBS) +- target_compile_definitions(${lib} PUBLIC "BROTLI_SHARED_COMPILATION" ) +- string(TOUPPER "${lib}" LIB) +- set_target_properties (${lib} PROPERTIES DEFINE_SYMBOL "${LIB}_SHARED_COMPILATION") +-endforeach() ++if(BUILD_SHARED_LIBS) ++ foreach(lib brotlicommon brotlidec brotlienc) ++ target_compile_definitions(${lib} PUBLIC "BROTLI_SHARED_COMPILATION" ) ++ string(TOUPPER "${lib}" LIB) ++ set_target_properties (${lib} PROPERTIES DEFINE_SYMBOL "${LIB}_SHARED_COMPILATION") ++ endforeach() ++endif() + +-foreach(lib IN LISTS BROTLI_SHARED_LIBS BROTLI_STATIC_LIBS) ++foreach(lib brotlicommon brotlidec brotlienc) + target_link_libraries(${lib} ${LIBM_LIBRARY}) + set_property(TARGET ${lib} APPEND PROPERTY INCLUDE_DIRECTORIES ${BROTLI_INCLUDE_DIRS}) + set_target_properties(${lib} PROPERTIES +@@ -205,9 +199,6 @@ target_link_libraries(brotlidec brotlicommon) + target_link_libraries(brotlienc brotlicommon) + endif() + +-target_link_libraries(brotlidec-static brotlicommon-static) +-target_link_libraries(brotlienc-static brotlicommon-static) +- + # For projects stuck on older versions of CMake, this will set the + # BROTLI_INCLUDE_DIRS and BROTLI_LIBRARIES variables so they still + # have a relatively easy way to use Brotli: +@@ -221,7 +212,7 @@ endif() + + # Build the brotli executable + add_executable(brotli ${BROTLI_CLI_C}) +-target_link_libraries(brotli ${BROTLI_LIBRARIES_STATIC}) ++target_link_libraries(brotli ${BROTLI_LIBRARIES}) + + # Installation + if(NOT BROTLI_BUNDLED_MODE) +@@ -230,17 +221,8 @@ if(NOT BROTLI_BUNDLED_MODE) + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ) + +- if(NOT BROTLI_EMSCRIPTEN) +- install( +- TARGETS ${BROTLI_LIBRARIES_CORE} +- ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" +- LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" +- RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" +- ) +- endif() # BROTLI_EMSCRIPTEN +- + install( +- TARGETS ${BROTLI_LIBRARIES_CORE_STATIC} ++ TARGETS ${BROTLI_LIBRARIES_CORE} + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" diff --git a/build/patches/brotli-fix-static-name.patch b/build/patches/brotli-fix-static-name.patch deleted file mode 100644 index a35a4fc6f..000000000 --- a/build/patches/brotli-fix-static-name.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Anton -Date: Thu Aug 11 17:17:52 2022 +0200 -Subject: [PATCH 1/1] Fix incorrect static lib names - -See: https://github.com/google/brotli/issues/795 - -Upstream-Status: Inappropriate [hack] -This is just a hack that only works for the emscripten build. Solving this issue properly requires substantial -changes to the makefiles, which also means substantial testing to make sure it works with all build systems. - -diff --git a/scripts/libbrotlicommon.pc.in b/scripts/libbrotlicommon.pc.in -index 1111111..2222222 100644 ---- a/scripts/libbrotlicommon.pc.in -+++ b/scripts/libbrotlicommon.pc.in -@@ -7,5 +7,5 @@ Name: libbrotlicommon - URL: https://github.com/google/brotli - Description: Brotli common dictionary library - Version: @PACKAGE_VERSION@ --Libs: -L${libdir} -lbrotlicommon -+Libs: -L${libdir} -lbrotlicommon-static - Cflags: -I${includedir} -diff --git a/scripts/libbrotlidec.pc.in b/scripts/libbrotlidec.pc.in -index 1111111..2222222 100644 ---- a/scripts/libbrotlidec.pc.in -+++ b/scripts/libbrotlidec.pc.in -@@ -7,6 +7,6 @@ Name: libbrotlidec - URL: https://github.com/google/brotli - Description: Brotli decoder library - Version: @PACKAGE_VERSION@ --Libs: -L${libdir} -lbrotlidec -+Libs: -L${libdir} -lbrotlidec-static - Requires.private: libbrotlicommon >= 1.0.2 - Cflags: -I${includedir} -diff --git a/scripts/libbrotlienc.pc.in b/scripts/libbrotlienc.pc.in -index 1111111..2222222 100644 ---- a/scripts/libbrotlienc.pc.in -+++ b/scripts/libbrotlienc.pc.in -@@ -7,6 +7,6 @@ Name: libbrotlienc - URL: https://github.com/google/brotli - Description: Brotli encoder library - Version: @PACKAGE_VERSION@ --Libs: -L${libdir} -lbrotlienc -+Libs: -L${libdir} -lbrotlienc-static - Requires.private: libbrotlicommon >= 1.0.2 - Cflags: -I${includedir} From 768046c81f45b17ebcfd9fdefd32484a7dd23481 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 13 Aug 2022 13:35:32 +0200 Subject: [PATCH 03/18] brotli: exclude internal dictionary --- build.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.sh b/build.sh index f308b6943..94b2646c6 100755 --- a/build.sh +++ b/build.sh @@ -274,7 +274,9 @@ test -f "$TARGET/lib/pkgconfig/libbrotlicommon.pc" || ( cd $DEPS/brotli # https://github.com/google/brotli/pull/655 patch -p1 <$SOURCE_DIR/build/patches/brotli-655.patch - emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET + # Exclude Brotli's internal dictionary, see: https://github.com/emscripten-core/emscripten/issues/9960 + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET \ + -DCMAKE_C_FLAGS="$CFLAGS -DBROTLI_EXTERNAL_DICTIONARY_DATA" -DCMAKE_CXX_FLAGS="$CXXFLAGS -DBROTLI_EXTERNAL_DICTIONARY_DATA" make -C _build install ) From 294f7d37ad4f17da80f9a88e844ccaa3a5e0444c Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 13 Aug 2022 13:35:47 +0200 Subject: [PATCH 04/18] brotli: disable tests --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 94b2646c6..35bf24222 100755 --- a/build.sh +++ b/build.sh @@ -275,7 +275,7 @@ test -f "$TARGET/lib/pkgconfig/libbrotlicommon.pc" || ( # https://github.com/google/brotli/pull/655 patch -p1 <$SOURCE_DIR/build/patches/brotli-655.patch # Exclude Brotli's internal dictionary, see: https://github.com/emscripten-core/emscripten/issues/9960 - emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET \ + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DBROTLI_DISABLE_TESTS=TRUE \ -DCMAKE_C_FLAGS="$CFLAGS -DBROTLI_EXTERNAL_DICTIONARY_DATA" -DCMAKE_CXX_FLAGS="$CXXFLAGS -DBROTLI_EXTERNAL_DICTIONARY_DATA" make -C _build install ) From aabe4e6379909ce9cbefa0788d863612c0583bc2 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 13 Aug 2022 13:37:34 +0200 Subject: [PATCH 05/18] libjxl: use 0.7rc tag instead --- build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index 35bf24222..34e9c5b43 100755 --- a/build.sh +++ b/build.sh @@ -119,7 +119,7 @@ VERSION_LCMS2=2.13.1 # https://github.com/mm2/Little-CMS VERSION_HWY=1.0.0 # https://github.com/google/highway VERSION_BROTLI=f4153a # https://github.com/google/brotli VERSION_JPEG=5c6a0f0 # https://github.com/mozilla/mozjpeg -VERSION_JXL=a4ad91a # https://github.com/libjxl/libjxl +VERSION_JXL=0.7rc # https://github.com/libjxl/libjxl VERSION_SPNG=0.7.2 # https://github.com/randy408/libspng VERSION_IMAGEQUANT=2.4.1 # https://github.com/lovell/libimagequant VERSION_CGIF=0.3.0 # https://github.com/dloebl/cgif @@ -261,7 +261,7 @@ test -f "$TARGET/lib/pkgconfig/libhwy.pc" || ( curl -Ls https://github.com/google/highway/archive/$VERSION_HWY.tar.gz | tar xzC $DEPS/hwy --strip-components=1 cd $DEPS/hwy emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DHWY_FORCE_STATIC_LIBS=TRUE \ - -DBUILD_TESTING=FALSE -DHWY_ENABLE_CONTRIB=FALSE -DHWY_ENABLE_EXAMPLES=FALSE + -DBUILD_TESTING=FALSE -DHWY_ENABLE_CONTRIB=FALSE -DHWY_ENABLE_EXAMPLES=FALSE make -C _build install ) @@ -298,7 +298,7 @@ echo "Compiling jxl" echo "=============================================" test -f "$TARGET/lib/pkgconfig/libjxl.pc" || ( mkdir $DEPS/jxl - curl -Ls https://github.com/libjxl/libjxl/archive/$VERSION_JXL.tar.gz | tar xzC $DEPS/jxl --strip-components=1 + curl -Ls https://github.com/libjxl/libjxl/archive/refs/tags/v$VERSION_JXL.tar.gz | tar xzC $DEPS/jxl --strip-components=1 cd $DEPS/jxl patch -p1 <$SOURCE_DIR/build/patches/libjxl-deps.patch # Download dependencies for internal linking. When this lib stabilizes, these deps should be compiled externally to avoid bloat. From f9ce5b72011f21ecd7990aa6d882d93827c57d96 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 13 Aug 2022 13:39:07 +0200 Subject: [PATCH 06/18] libjxl: avoid bundled deps + prefer lcms2 over skcms. --- build.sh | 18 ++++++++++-------- build/patches/libjxl-deps.patch | 29 ----------------------------- 2 files changed, 10 insertions(+), 37 deletions(-) delete mode 100644 build/patches/libjxl-deps.patch diff --git a/build.sh b/build.sh index 34e9c5b43..a202a6a8c 100755 --- a/build.sh +++ b/build.sh @@ -300,13 +300,15 @@ test -f "$TARGET/lib/pkgconfig/libjxl.pc" || ( mkdir $DEPS/jxl curl -Ls https://github.com/libjxl/libjxl/archive/refs/tags/v$VERSION_JXL.tar.gz | tar xzC $DEPS/jxl --strip-components=1 cd $DEPS/jxl - patch -p1 <$SOURCE_DIR/build/patches/libjxl-deps.patch - # Download dependencies for internal linking. When this lib stabilizes, these deps should be compiled externally to avoid bloat. - ./deps.sh - emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DBUILD_TESTING=OFF -DJPEGXL_STATIC=TRUE \ - -DJPEGXL_ENABLE_FUZZERS=FALSE -DJPEGXL_ENABLE_DOXYGEN=FALSE \ - -DJPEGXL_ENABLE_MANPAGES=FALSE -DJPEGXL_ENABLE_BENCHMARK=FALSE -DJPEGXL_ENABLE_EXAMPLES=FALSE -DJPEGXL_ENABLE_JNI=FALSE \ - -DJPEGXL_ENABLE_SJPEG=FALSE -DJPEGXL_ENABLE_OPENEXR=FALSE #-DJPEGXL_FORCE_SYSTEM_HWY=TRUE -DJPEGXL_FORCE_SYSTEM_BROTLI=TRUE + # Avoid bundling libpng + sed -i 's/JPEGXL_EMSCRIPTEN/& AND JPEGXL_BUNDLE_LIBPNG/' third_party/CMakeLists.txt + # CMake < 3.19 workaround, see: https://github.com/libjxl/libjxl/issues/1425 + sed -i 's/lcms2,INCLUDE_DIRECTORIES/lcms2,INTERFACE_INCLUDE_DIRECTORIES/' lib/jxl.cmake + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DJPEGXL_STATIC=TRUE -DBUILD_TESTING=FALSE \ + -DJPEGXL_ENABLE_TOOLS=FALSE -DJPEGXL_ENABLE_DOXYGEN=FALSE -DJPEGXL_ENABLE_MANPAGES=FALSE -DJPEGXL_ENABLE_BENCHMARK=FALSE \ + -DJPEGXL_ENABLE_EXAMPLES=FALSE -DJPEGXL_ENABLE_SJPEG=FALSE -DJPEGXL_ENABLE_OPENEXR=FALSE -DJPEGXL_ENABLE_SKCMS=FALSE \ + -DJPEGXL_BUNDLE_LIBPNG=FALSE -DJPEGXL_FORCE_SYSTEM_BROTLI=TRUE -DJPEGXL_FORCE_SYSTEM_LCMS2=TRUE -DJPEGXL_FORCE_SYSTEM_HWY=TRUE \ + -DCMAKE_FIND_ROOT_PATH=$TARGET make -C _build install ) @@ -348,7 +350,7 @@ test -f "$TARGET/lib/pkgconfig/cgif.pc" || ( curl -Ls https://github.com/dloebl/cgif/archive/V$VERSION_CGIF.tar.gz | tar xzC $DEPS/cgif --strip-components=1 cd $DEPS/cgif meson setup _build --prefix=$TARGET --cross-file=$MESON_CROSS --default-library=static --buildtype=release \ - -Dtests=false + -Dtests=false ninja -C _build install ) diff --git a/build/patches/libjxl-deps.patch b/build/patches/libjxl-deps.patch deleted file mode 100644 index 77b110ba7..000000000 --- a/build/patches/libjxl-deps.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Anton -Date: Thu Aug 11 08:15:47 2022 +0200 -Subject: [PATCH 1/1] Alter how libjxl downloads dependencies - -Upstream-Status: Pending - -diff --git a/deps.sh b/deps.sh -index 1111111..2222222 100644 ---- a/deps.sh -+++ b/deps.sh -@@ -59,7 +59,7 @@ download_github() { - - - main() { -- if git -C "${MYDIR}" rev-parse; then -+ if false && git -C "${MYDIR}" rev-parse; then - cat >&2 < Date: Sat, 13 Aug 2022 13:40:11 +0200 Subject: [PATCH 07/18] [WiP] Add libjxl tests --- test/unit/test_foreign.js | 52 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/test/unit/test_foreign.js b/test/unit/test_foreign.js index 021b263c3..5989681d9 100644 --- a/test/unit/test_foreign.js +++ b/test/unit/test_foreign.js @@ -14,6 +14,7 @@ describe('foreign', () => { const fileLoaders = { jpegload: file => vips.Image.jpegload(file), + jxlload: file => vips.Image.jxlload(file), pngload: file => vips.Image.pngload(file), webpload: file => vips.Image.webpload(file), tiffload: file => vips.Image.tiffload(file), @@ -23,6 +24,7 @@ describe('foreign', () => { const bufferLoaders = { jpegload_buffer: buffer => vips.Image.jpegloadBuffer(buffer), + jxlload_buffer: buffer => vips.Image.jxlloadBuffer(buffer), pngload_buffer: buffer => vips.Image.pngloadBuffer(buffer), webpload_buffer: buffer => vips.Image.webploadBuffer(buffer), tiffload_buffer: buffer => vips.Image.tiffloadBuffer(buffer), @@ -31,6 +33,7 @@ describe('foreign', () => { const bufferSavers = { jpegsave_buffer: (im, opts) => im.jpegsaveBuffer(opts), + jxlsave_buffer: (im, opts) => im.jxlsaveBuffer(opts), pngsave_buffer: (im, opts) => im.pngsaveBuffer(opts), tiffsave_buffer: (im, opts) => im.tiffsaveBuffer(opts), webpsave_buffer: (im, opts) => im.webpsaveBuffer(opts), @@ -855,6 +858,55 @@ describe('foreign', () => { saveBufferTempfile('radsave_buffer', '.hdr', rad, 0); }); + it('jxlsave', function () { + // Needs libjxl support + // FIXME(kleisauke): Enable this + if (!Helpers.have('jxlsave') || !0) { + return this.skip(); + } + + // save and load with an icc profile + saveLoadBuffer('jxlsave_buffer', 'jxlload_buffer', + colour, 120); + + // with no icc profile + const noProfile = colour.copy(); + noProfile.remove('icc-profile-data'); + saveLoadBuffer('jxlsave_buffer', 'jxlload_buffer', + noProfile, 120); + + // scrgb mode + const scrgb = colour.colourspace('scrgb'); + saveLoadBuffer('jxlsave_buffer', 'jxlload_buffer', + scrgb, 120); + + // scrgb mode, no profile + const scrgbNoProfile = scrgb.copy(); + scrgbNoProfile.remove('icc-profile-data'); + saveLoadBuffer('jxlsave_buffer', 'jxlload_buffer', + scrgbNoProfile, 120); + + // 16-bit mode + const rgb16 = colour.colourspace('rgb16'); + saveLoadBuffer('jxlsave_buffer', 'jxlload_buffer', + rgb16, 30000); + + // repeat for lossless mode + saveLoadBuffer('jxlsave_buffer', 'jxlload_buffer', + colour, 0, { lossless: true }); + saveLoadBuffer('jxlsave_buffer', 'jxlload_buffer', + noProfile, 0, { lossless: true }); + saveLoadBuffer('jxlsave_buffer', 'jxlload_buffer', + scrgb, 0, { lossless: true }); + saveLoadBuffer('jxlsave_buffer', 'jxlload_buffer', + scrgbNoProfile, 0, { lossless: true }); + + // lossy should be much smaller than lossless + const lossy = colour.jxlsaveBuffer(); + const lossless = colour.jxlsaveBuffer({ lossless: true }); + expect(lossy.byteLength).to.be.below(lossless.byteLength / 5); + }); + it('fail_on', function () { // csvload should spot trunc correctly const target = vips.Target.newToMemory(); From 01a4587ee15ce68dd3e9758d629f0794080c3f98 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 13 Aug 2022 14:02:52 +0200 Subject: [PATCH 08/18] brotli: remove redundant build option Brotli is a C-only library. --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index a202a6a8c..7e84ec859 100755 --- a/build.sh +++ b/build.sh @@ -276,7 +276,7 @@ test -f "$TARGET/lib/pkgconfig/libbrotlicommon.pc" || ( patch -p1 <$SOURCE_DIR/build/patches/brotli-655.patch # Exclude Brotli's internal dictionary, see: https://github.com/emscripten-core/emscripten/issues/9960 emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DBROTLI_DISABLE_TESTS=TRUE \ - -DCMAKE_C_FLAGS="$CFLAGS -DBROTLI_EXTERNAL_DICTIONARY_DATA" -DCMAKE_CXX_FLAGS="$CXXFLAGS -DBROTLI_EXTERNAL_DICTIONARY_DATA" + -DCMAKE_C_FLAGS="$CFLAGS -DBROTLI_EXTERNAL_DICTIONARY_DATA" make -C _build install ) From b9504dce5cf4fa64c0fd701ec910a1868a21345b Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 14 Aug 2022 12:09:30 +0200 Subject: [PATCH 09/18] mozjpeg: disable environment variables usage --- build.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 7e84ec859..842aa29d8 100755 --- a/build.sh +++ b/build.sh @@ -288,8 +288,10 @@ test -f "$TARGET/lib/pkgconfig/libjpeg.pc" || ( curl -Ls https://github.com/mozilla/mozjpeg/archive/$VERSION_JPEG.tar.gz | tar xzC $DEPS/jpeg --strip-components=1 cd $DEPS/jpeg # https://github.com/libjpeg-turbo/libjpeg-turbo/issues/250#issuecomment-407615180 + # Disable environment variables usage, see: https://github.com/libjpeg-turbo/libjpeg-turbo/issues/600 emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DENABLE_STATIC=TRUE \ - -DENABLE_SHARED=FALSE -DWITH_JPEG8=TRUE -DWITH_SIMD=FALSE -DWITH_TURBOJPEG=FALSE -DPNG_SUPPORTED=FALSE + -DENABLE_SHARED=FALSE -DWITH_JPEG8=TRUE -DWITH_SIMD=FALSE -DWITH_TURBOJPEG=FALSE -DPNG_SUPPORTED=FALSE \ + -DCMAKE_C_FLAGS="$CFLAGS -DNO_GETENV -DNO_PUTENV" make -C _build install ) From 9e8b3b15ad41d0c305ab8eecf7cea8171da1281c Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 14 Aug 2022 12:10:29 +0200 Subject: [PATCH 10/18] Unify comments --- build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index 842aa29d8..779e74cbd 100755 --- a/build.sh +++ b/build.sh @@ -274,7 +274,7 @@ test -f "$TARGET/lib/pkgconfig/libbrotlicommon.pc" || ( cd $DEPS/brotli # https://github.com/google/brotli/pull/655 patch -p1 <$SOURCE_DIR/build/patches/brotli-655.patch - # Exclude Brotli's internal dictionary, see: https://github.com/emscripten-core/emscripten/issues/9960 + # Exclude internal dictionary, see: https://github.com/emscripten-core/emscripten/issues/9960 emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DBROTLI_DISABLE_TESTS=TRUE \ -DCMAKE_C_FLAGS="$CFLAGS -DBROTLI_EXTERNAL_DICTIONARY_DATA" make -C _build install @@ -287,7 +287,7 @@ test -f "$TARGET/lib/pkgconfig/libjpeg.pc" || ( mkdir $DEPS/jpeg curl -Ls https://github.com/mozilla/mozjpeg/archive/$VERSION_JPEG.tar.gz | tar xzC $DEPS/jpeg --strip-components=1 cd $DEPS/jpeg - # https://github.com/libjpeg-turbo/libjpeg-turbo/issues/250#issuecomment-407615180 + # Compile without SIMD support, see: https://github.com/libjpeg-turbo/libjpeg-turbo/issues/250 # Disable environment variables usage, see: https://github.com/libjpeg-turbo/libjpeg-turbo/issues/600 emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DENABLE_STATIC=TRUE \ -DENABLE_SHARED=FALSE -DWITH_JPEG8=TRUE -DWITH_SIMD=FALSE -DWITH_TURBOJPEG=FALSE -DPNG_SUPPORTED=FALSE \ From 8a6e02d3309b5836277bdc6fa8b40b11d74fb5e6 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 14 Aug 2022 12:12:27 +0200 Subject: [PATCH 11/18] libjxl: disable concurrency We rely on libvips' thread pool instead. --- build.sh | 1 + .../vips-libjxl-disable-concurrency.patch | 33 +++++++++++++++++++ test/unit/test_foreign.js | 2 +- 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 build/patches/vips-libjxl-disable-concurrency.patch diff --git a/build.sh b/build.sh index 779e74cbd..838dd86ef 100755 --- a/build.sh +++ b/build.sh @@ -395,6 +395,7 @@ test -f "$TARGET/lib/pkgconfig/vips.pc" || ( # Emscripten specific patches patch -p1 <$SOURCE_DIR/build/patches/vips-remove-orc.patch patch -p1 <$SOURCE_DIR/build/patches/vips-1492-emscripten.patch + patch -p1 <$SOURCE_DIR/build/patches/vips-libjxl-disable-concurrency.patch #patch -p1 <$SOURCE_DIR/build/patches/vips-1492-profiler.patch # Disable building C++ bindings, man pages, gettext po files, tools, and (fuzz-)tests sed -i'.bak' "/subdir('cplusplus')/{N;N;N;N;N;d;}" meson.build diff --git a/build/patches/vips-libjxl-disable-concurrency.patch b/build/patches/vips-libjxl-disable-concurrency.patch new file mode 100644 index 000000000..30419213b --- /dev/null +++ b/build/patches/vips-libjxl-disable-concurrency.patch @@ -0,0 +1,33 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kleis Auke Wolthuizen +Date: Sun, 14 Aug 2022 12:12:00 +0200 +Subject: [PATCH 1/1] Disable concurrency in jxl{load,save} + +Upstream-Status: Inappropriate [Emscripten specific] + +diff --git a/libvips/foreign/jxlload.c b/libvips/foreign/jxlload.c +index 1111111..2222222 100644 +--- a/libvips/foreign/jxlload.c ++++ b/libvips/foreign/jxlload.c +@@ -157,7 +157,7 @@ vips_foreign_load_jxl_build( VipsObject *object ) + #endif /*DEBUG*/ + + jxl->runner = JxlThreadParallelRunnerCreate( NULL, +- vips_concurrency_get() ); ++ 0 ); + jxl->decoder = JxlDecoderCreate( NULL ); + + if( JxlDecoderSubscribeEvents( jxl->decoder, +diff --git a/libvips/foreign/jxlsave.c b/libvips/foreign/jxlsave.c +index 1111111..2222222 100644 +--- a/libvips/foreign/jxlsave.c ++++ b/libvips/foreign/jxlsave.c +@@ -253,7 +253,7 @@ vips_foreign_save_jxl_build( VipsObject *object ) + jxl->lossless = TRUE; + + jxl->runner = JxlThreadParallelRunnerCreate( NULL, +- vips_concurrency_get() ); ++ 0 ); + jxl->encoder = JxlEncoderCreate( NULL ); + + if( JxlEncoderSetParallelRunner( jxl->encoder, diff --git a/test/unit/test_foreign.js b/test/unit/test_foreign.js index 5989681d9..7a862415e 100644 --- a/test/unit/test_foreign.js +++ b/test/unit/test_foreign.js @@ -860,7 +860,7 @@ describe('foreign', () => { it('jxlsave', function () { // Needs libjxl support - // FIXME(kleisauke): Enable this + // FIXME(kleisauke): Fix jxlsave compatibility with libjxl 0.7 if (!Helpers.have('jxlsave') || !0) { return this.skip(); } From 7651f5cdfc68382aa2feb1b8d13f6a53781e2aa0 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 14 Aug 2022 13:06:39 +0200 Subject: [PATCH 12/18] highway: download from `/refs/tags/` URL --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 838dd86ef..3d8d89f1c 100755 --- a/build.sh +++ b/build.sh @@ -258,7 +258,7 @@ echo "Compiling hwy" echo "=============================================" test -f "$TARGET/lib/pkgconfig/libhwy.pc" || ( mkdir $DEPS/hwy - curl -Ls https://github.com/google/highway/archive/$VERSION_HWY.tar.gz | tar xzC $DEPS/hwy --strip-components=1 + curl -Ls https://github.com/google/highway/archive/refs/tags/$VERSION_HWY.tar.gz | tar xzC $DEPS/hwy --strip-components=1 cd $DEPS/hwy emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DHWY_FORCE_STATIC_LIBS=TRUE \ -DBUILD_TESTING=FALSE -DHWY_ENABLE_CONTRIB=FALSE -DHWY_ENABLE_EXAMPLES=FALSE From 3aff8575365702b63bfb377bf9acb47759d34cd1 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sun, 14 Aug 2022 16:32:16 +0200 Subject: [PATCH 13/18] vips: add patch for libjxl 0.7 compatibility See: https://github.com/libvips/libvips/pull/2988. --- build.sh | 1 + build/patches/vips-2988.patch | 28 ++++++++++++++++++++++++++++ test/unit/test_foreign.js | 5 ++--- 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 build/patches/vips-2988.patch diff --git a/build.sh b/build.sh index 3d8d89f1c..8a8f91cfe 100755 --- a/build.sh +++ b/build.sh @@ -396,6 +396,7 @@ test -f "$TARGET/lib/pkgconfig/vips.pc" || ( patch -p1 <$SOURCE_DIR/build/patches/vips-remove-orc.patch patch -p1 <$SOURCE_DIR/build/patches/vips-1492-emscripten.patch patch -p1 <$SOURCE_DIR/build/patches/vips-libjxl-disable-concurrency.patch + patch -p1 <$SOURCE_DIR/build/patches/vips-2988.patch #patch -p1 <$SOURCE_DIR/build/patches/vips-1492-profiler.patch # Disable building C++ bindings, man pages, gettext po files, tools, and (fuzz-)tests sed -i'.bak' "/subdir('cplusplus')/{N;N;N;N;N;d;}" meson.build diff --git a/build/patches/vips-2988.patch b/build/patches/vips-2988.patch new file mode 100644 index 000000000..ec404af96 --- /dev/null +++ b/build/patches/vips-2988.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kleis Auke Wolthuizen +Date: Sun, 14 Aug 2022 16:04:34 +0200 +Subject: [PATCH 1/1] jxlsave: correctly mark frame as last + +It's required to close the input, otherwise the encoder can't +know what the last frame is, resulting in an improper codestream. + +Resolves: #2987. + +Upstream-Status: Submitted [https://github.com/libvips/libvips/pull/2988] + +diff --git a/libvips/foreign/jxlsave.c b/libvips/foreign/jxlsave.c +index 1111111..2222222 100644 +--- a/libvips/foreign/jxlsave.c ++++ b/libvips/foreign/jxlsave.c +@@ -438,6 +438,11 @@ vips_foreign_save_jxl_build( VipsObject *object ) + return( -1 ); + } + ++ /* This function must be called after the final frame and/or box, ++ * otherwise the codestream will not be encoded correctly. ++ */ ++ JxlEncoderCloseInput( jxl->encoder ); ++ + do { + uint8_t *out; + size_t avail_out; diff --git a/test/unit/test_foreign.js b/test/unit/test_foreign.js index 7a862415e..599601849 100644 --- a/test/unit/test_foreign.js +++ b/test/unit/test_foreign.js @@ -859,9 +859,8 @@ describe('foreign', () => { }); it('jxlsave', function () { - // Needs libjxl support - // FIXME(kleisauke): Fix jxlsave compatibility with libjxl 0.7 - if (!Helpers.have('jxlsave') || !0) { + // Needs JPEG XL support + if (!Helpers.have('jxlsave')) { return this.skip(); } From 034a23847ce33bfdae433bf88d0a00b20b6723b5 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 16 Aug 2022 12:20:21 +0200 Subject: [PATCH 14/18] Update patch accepted upstream --- build/patches/vips-2988.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/patches/vips-2988.patch b/build/patches/vips-2988.patch index ec404af96..1ba256dbe 100644 --- a/build/patches/vips-2988.patch +++ b/build/patches/vips-2988.patch @@ -8,7 +8,7 @@ know what the last frame is, resulting in an improper codestream. Resolves: #2987. -Upstream-Status: Submitted [https://github.com/libvips/libvips/pull/2988] +Upstream-Status: Accepted [https://github.com/libvips/libvips/commit/34427d83a028690b098fd1f67e956f78bc724e22] diff --git a/libvips/foreign/jxlsave.c b/libvips/foreign/jxlsave.c index 1111111..2222222 100644 From e8cff44e3cee182b0471d4674dc73bde9d67df78 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 19 Aug 2022 11:42:08 +0200 Subject: [PATCH 15/18] Add simple load test --- test/unit/helpers.js | 2 ++ test/unit/images/sample.jxl | Bin 0 -> 13805 bytes test/unit/test_foreign.js | 21 +++++++++++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 test/unit/images/sample.jxl diff --git a/test/unit/helpers.js b/test/unit/helpers.js index 133ecedd6..408842131 100644 --- a/test/unit/helpers.js +++ b/test/unit/helpers.js @@ -1,6 +1,7 @@ 'use strict'; export const jpegFile = getPath('sample.jpg'); +export const jxlFile = getPath('sample.jxl'); export const truncatedFile = getPath('truncated.jpg'); export const pngFile = getPath('sample.png'); export const tifFile = getPath('sample.tif'); @@ -24,6 +25,7 @@ export const mosaicFiles = [ ]; export const testFiles = [ jpegFile, + jxlFile, truncatedFile, pngFile, tifFile, diff --git a/test/unit/images/sample.jxl b/test/unit/images/sample.jxl new file mode 100644 index 0000000000000000000000000000000000000000..17ff8916ea97cc609b2cb2f6412d233928879984 GIT binary patch literal 13805 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 { saveBufferTempfile('radsave_buffer', '.hdr', rad, 0); }); + it('jxl', function () { + // Needs JPEG XL support + if (!Helpers.have('jxlload')) { + return this.skip(); + } + + const jxlValid = (im) => { + const a = im.getpoint(10, 10); + // the delta might need to be adjusted up as new + // libjxl versions are released + Helpers.assertAlmostEqualObjects(a, [157, 129, 90], 0); + expect(im.width).to.equal(290); + expect(im.height).to.equal(442); + expect(im.bands).to.equal(4); + }; + + fileLoader('jxlload', Helpers.jxlFile, jxlValid); + bufferLoader('jxlload_buffer', Helpers.jxlFile, jxlValid); + + }); + it('jxlsave', function () { // Needs JPEG XL support if (!Helpers.have('jxlsave')) { From f97f1054ebef552bb5a25107be35e4f53de3e410 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 19 Aug 2022 11:46:25 +0200 Subject: [PATCH 16/18] whoops: fix lint issue --- test/unit/test_foreign.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unit/test_foreign.js b/test/unit/test_foreign.js index 073fea437..f0cc977f4 100644 --- a/test/unit/test_foreign.js +++ b/test/unit/test_foreign.js @@ -876,7 +876,6 @@ describe('foreign', () => { fileLoader('jxlload', Helpers.jxlFile, jxlValid); bufferLoader('jxlload_buffer', Helpers.jxlFile, jxlValid); - }); it('jxlsave', function () { From d2dc6f0ded035a7b6c15776f0a9f49d32df3d069 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 19 Aug 2022 12:25:42 +0200 Subject: [PATCH 17/18] playground: add jxl sample --- playground/samples/filter/duotone/sample.js | 1 + playground/src/images/INFO.md | 5 +++++ playground/src/images/owl.jxl | Bin 0 -> 37502 bytes playground/src/playground-runner.html | 2 +- playground/src/samples.js | 1 + playground/webpack.config.js | 2 +- 6 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 playground/src/images/owl.jxl diff --git a/playground/samples/filter/duotone/sample.js b/playground/samples/filter/duotone/sample.js index cca2f65ca..8c06fb212 100644 --- a/playground/samples/filter/duotone/sample.js +++ b/playground/samples/filter/duotone/sample.js @@ -20,6 +20,7 @@ lut = lut.colourspace(vips.Interpretation.srgb/* 'srgb' */, { // Image source: https://www.flickr.com/photos/jasonidzerda/3987784466 let im = vips.Image.newFromFile('owl.jpg'); // let im = vips.Image.newFromFile('owl.tif'); +// let im = vips.Image.newFromFile('owl.jxl'); // let im = vips.Image.newFromFile('transparency_demo.png'); // let im = vips.Image.newFromFile('banana.webp', { n: -1 }); // let im = vips.Image.newFromFile('banana.gif', { n: -1 }); diff --git a/playground/src/images/INFO.md b/playground/src/images/INFO.md index 331d85860..4411e4640 100644 --- a/playground/src/images/INFO.md +++ b/playground/src/images/INFO.md @@ -15,6 +15,11 @@ vips copy owl.jpg owl.tif[compression=jpeg,strip=true] vips copy owl.jpg owl.webp[strip=true] ``` +[`owl.jxl`](owl.jxl): +```bash +vips copy owl.jpg owl.jxl +``` + [`transparency_demo.png`](transparency_demo.png): ``` https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png diff --git a/playground/src/images/owl.jxl b/playground/src/images/owl.jxl new file mode 100644 index 0000000000000000000000000000000000000000..3e5004b13602c3962b60e67f0d12505c454240ba GIT binary patch literal 37502 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 literal 0 HcmV?d00001 diff --git a/playground/src/playground-runner.html b/playground/src/playground-runner.html index 3510c09ea..0c186a553 100644 --- a/playground/src/playground-runner.html +++ b/playground/src/playground-runner.html @@ -67,7 +67,7 @@ // module.ENV.VIPS_INFO = '1'; // module.ENV.VIPS_LEAK = '1'; - for (const image of ['owl.jpg', 'owl.tif', 'owl.webp', 'banana.webp', 'banana.gif', 'transparency_demo.png']) + for (const image of ['owl.jpg', 'owl.tif', 'owl.webp', 'owl.jxl', 'banana.webp', 'banana.gif', 'transparency_demo.png']) module.FS.createPreloadedFile('/', image, 'assets/images/' + image, true, false); }, postRun: (module) => { diff --git a/playground/src/samples.js b/playground/src/samples.js index ed2f8cbac..1d5bda311 100644 --- a/playground/src/samples.js +++ b/playground/src/samples.js @@ -1,6 +1,7 @@ import './images/owl.webp'; import './images/owl.tif'; import './images/owl.jpg'; +import './images/owl.jxl'; import './images/banana.webp'; import './images/banana.gif'; import './images/transparency_demo.png'; diff --git a/playground/webpack.config.js b/playground/webpack.config.js index 6271c29a4..9664228a9 100644 --- a/playground/webpack.config.js +++ b/playground/webpack.config.js @@ -32,7 +32,7 @@ module.exports = { ] }, { - test: /\.(jpe?g|png|gif|tiff?|webp|svg)$/, + test: /\.(jpe?g|png|gif|tiff?|webp|jxl|svg)$/, type: 'asset/resource', generator: { filename: 'assets/images/[name][ext][query]' From 855da2a9521a60ea78f9c4868d007866aa7a623e Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Thu, 1 Sep 2022 11:03:58 +0200 Subject: [PATCH 18/18] Prepare for merge --- build.sh | 13 ++++++------- test/unit/test_foreign.js | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/build.sh b/build.sh index 642a7ceb5..655906927 100755 --- a/build.sh +++ b/build.sh @@ -116,7 +116,7 @@ VERSION_GLIB=2.73.3 # https://gitlab.gnome.org/GNOME/glib VERSION_EXPAT=2.4.8 # https://github.com/libexpat/libexpat VERSION_EXIF=0.6.24 # https://github.com/libexif/libexif VERSION_LCMS2=2.13.1 # https://github.com/mm2/Little-CMS -VERSION_HWY=1.0.0 # https://github.com/google/highway +VERSION_HWY=1.0.1 # https://github.com/google/highway VERSION_BROTLI=f4153a # https://github.com/google/brotli VERSION_JPEG=4.1.1 # https://github.com/mozilla/mozjpeg VERSION_JXL=0.7rc # https://github.com/libjxl/libjxl @@ -262,7 +262,7 @@ test -f "$TARGET/lib/pkgconfig/libhwy.pc" || ( mkdir $DEPS/hwy curl -Ls https://github.com/google/highway/archive/refs/tags/$VERSION_HWY.tar.gz | tar xzC $DEPS/hwy --strip-components=1 cd $DEPS/hwy - emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DHWY_FORCE_STATIC_LIBS=TRUE \ + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DBUILD_SHARED_LIBS=FALSE \ -DBUILD_TESTING=FALSE -DHWY_ENABLE_CONTRIB=FALSE -DHWY_ENABLE_EXAMPLES=FALSE make -C _build install ) @@ -308,11 +308,10 @@ test -f "$TARGET/lib/pkgconfig/libjxl.pc" || ( sed -i 's/JPEGXL_EMSCRIPTEN/& AND JPEGXL_BUNDLE_LIBPNG/' third_party/CMakeLists.txt # CMake < 3.19 workaround, see: https://github.com/libjxl/libjxl/issues/1425 sed -i 's/lcms2,INCLUDE_DIRECTORIES/lcms2,INTERFACE_INCLUDE_DIRECTORIES/' lib/jxl.cmake - emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DJPEGXL_STATIC=TRUE -DBUILD_TESTING=FALSE \ - -DJPEGXL_ENABLE_TOOLS=FALSE -DJPEGXL_ENABLE_DOXYGEN=FALSE -DJPEGXL_ENABLE_MANPAGES=FALSE -DJPEGXL_ENABLE_BENCHMARK=FALSE \ - -DJPEGXL_ENABLE_EXAMPLES=FALSE -DJPEGXL_ENABLE_SJPEG=FALSE -DJPEGXL_ENABLE_OPENEXR=FALSE -DJPEGXL_ENABLE_SKCMS=FALSE \ - -DJPEGXL_BUNDLE_LIBPNG=FALSE -DJPEGXL_FORCE_SYSTEM_BROTLI=TRUE -DJPEGXL_FORCE_SYSTEM_LCMS2=TRUE -DJPEGXL_FORCE_SYSTEM_HWY=TRUE \ - -DCMAKE_FIND_ROOT_PATH=$TARGET + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DCMAKE_FIND_ROOT_PATH=$TARGET \ + -DBUILD_SHARED_LIBS=FALSE -DBUILD_TESTING=FALSE -DJPEGXL_ENABLE_TOOLS=FALSE -DJPEGXL_ENABLE_DOXYGEN=FALSE \ + -DJPEGXL_ENABLE_MANPAGES=FALSE -DJPEGXL_ENABLE_EXAMPLES=FALSE -DJPEGXL_ENABLE_SJPEG=FALSE -DJPEGXL_ENABLE_SKCMS=FALSE \ + -DJPEGXL_BUNDLE_LIBPNG=FALSE -DJPEGXL_FORCE_SYSTEM_BROTLI=TRUE -DJPEGXL_FORCE_SYSTEM_LCMS2=TRUE -DJPEGXL_FORCE_SYSTEM_HWY=TRUE make -C _build install ) diff --git a/test/unit/test_foreign.js b/test/unit/test_foreign.js index f0cc977f4..710fa3fcc 100644 --- a/test/unit/test_foreign.js +++ b/test/unit/test_foreign.js @@ -858,7 +858,7 @@ describe('foreign', () => { saveBufferTempfile('radsave_buffer', '.hdr', rad, 0); }); - it('jxl', function () { + it('jxlload', function () { // Needs JPEG XL support if (!Helpers.have('jxlload')) { return this.skip();