diff --git a/.github/workflows/build-imagecodecs.yml b/.github/workflows/build-imagecodecs.yml index 699dc0c280d0..6efe92d2c997 100644 --- a/.github/workflows/build-imagecodecs.yml +++ b/.github/workflows/build-imagecodecs.yml @@ -92,18 +92,32 @@ jobs: # dropped like upstream's own customize_build_macports does; wavpack is # packaged but too old (5.6.0, predates the multithreaded-encoding API # _wavpack.pyx calls); libdeflate isn't packaged either, so it's built - # from its own small upstream source. + # from its own small upstream source. Rocky 10's snappy predates the + # compression-level API (snappy_compress_with_level, SNAPPY_*_COMPRESSION_LEVEL) + # that _snappy.pyx uses from 2026.10.10, so snappy is built from source too -- + # at 1.3.1: the API is absent from snappy 1.2.2 (the latest tag until 1.3.0) + # and first appears in the 1.3.0 tag's snappy-c.h. CIBW_BEFORE_ALL_LINUX: | dnf install -y \ lcms2-devel lz4-devel libzstd-devel liblerc-devel openjpeg2-devel \ libjpeg-turbo-devel xz-devel libpng-devel libtiff-devel libwebp-devel \ - zlib-ng-compat-devel brotli-devel snappy-devel giflib-devel bzip2-devel + zlib-ng-compat-devel brotli-devel giflib-devel bzip2-devel curl -sSL https://github.com/ebiggers/libdeflate/archive/refs/tags/v1.26.tar.gz | tar xz -C /tmp cmake -S /tmp/libdeflate-1.26 -B /tmp/libdeflate-1.26/build -DCMAKE_BUILD_TYPE=Release -DLIBDEFLATE_BUILD_STATIC_LIB=OFF -DLIBDEFLATE_BUILD_GZIP=OFF cmake --build /tmp/libdeflate-1.26/build -j"$(nproc)" cmake --install /tmp/libdeflate-1.26/build + curl -sSLf https://github.com/google/snappy/archive/refs/tags/1.3.1.tar.gz | tar xz -C /tmp + cmake -S /tmp/snappy-1.3.1 -B /tmp/snappy-1.3.1/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DSNAPPY_BUILD_TESTS=OFF -DSNAPPY_BUILD_BENCHMARKS=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_POLICY_VERSION_MINIMUM=3.5 + cmake --build /tmp/snappy-1.3.1/build -j"$(nproc)" + cmake --install /tmp/snappy-1.3.1/build + ldconfig + # CPATH puts /usr/local/include (snappy 1.3.1, libdeflate) ahead of any + # older system header of the same name. CIBW_ENVIRONMENT: >- IMAGECODECS_RISCV64=1 + CPATH=/usr/local/include + LIBRARY_PATH=/usr/local/lib + LD_LIBRARY_PATH=/usr/local/lib PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ CIBW_TEST_REQUIRES: pytest tifffile CIBW_TEST_SOURCES: tests diff --git a/docs/packages/imagecodecs.yaml b/docs/packages/imagecodecs.yaml index 15bf97928ec1..5ad98be06742 100644 --- a/docs/packages/imagecodecs.yaml +++ b/docs/packages/imagecodecs.yaml @@ -12,3 +12,4 @@ versions: - filename: imagecodecs-2026.8.16-cp314-cp314t-manylinux_2_35_riscv64.manylinux_2_39_riscv64.whl sha256: 5d775d794373da6b92d124f477dea1f7ba1f2b01eeef33db70d7a1f0502ed2f8 requires-python: '>=3.12' +- version: 2026.10.10 diff --git a/patches/imagecodecs/2026.10.10/0001-setup-add-a-riscv64-build-customization.patch b/patches/imagecodecs/2026.10.10/0001-setup-add-a-riscv64-build-customization.patch new file mode 100644 index 000000000000..b2894e847dac --- /dev/null +++ b/patches/imagecodecs/2026.10.10/0001-setup-add-a-riscv64-build-customization.patch @@ -0,0 +1,75 @@ +From d1cf8a782d921f42fdb4afe4785b62d741f0179a Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Sat, 12 Sep 2026 01:27:31 +0200 +Subject: [PATCH] setup: add a riscv64 (Rocky 10 / pypi.riseproject.dev) build + customization + +setup.py's customize_build dispatch relies on importing +imagecodecs_distributor_setup, but that module is not reliably +importable from inside cibuildwheel's isolated `python -m build` +subprocess (build isolation does not put the project directory on +sys.path), so the build silently falls back to customize_build_default +-- which still tries to compile the jpegxr extension against jxrlib, +a library Rocky 10 does not package for riscv64 at all. + +Add customize_build_riscv64, selected via an IMAGECODECS_RISCV64 env +var checked directly in the dispatch chain (no import needed), so it +does not depend on that mechanism working. It trims EXTENSIONS to the +codecs backed by Rocky 10 appstream/crb dnf packages (plus lzf, which +bundles its own source and needs no system library), drops jpegxr +(like upstream's own customize_build_macports already does when +jxrlib is unavailable) and wavpack (Rocky 10 packages WavPack 5.6.0, +which predates the worker_threads/OPEN_THREADS_SHFT multithreaded- +encoding API imagecodecs' _wavpack.pyx calls unconditionally), and +clears the jpeg8 legacy sources so it builds against libjpeg-turbo 3 +(matching every other customize_build_* preset that runs on a modern +libjpeg-turbo). + +Upstream-Status: Inappropriate [riscv64/pypi.riseproject.dev-specific build customization] +--- + setup.py | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/setup.py b/setup.py +index 3a91795..30e4e56 100644 +--- a/setup.py ++++ b/setup.py +@@ -677,6 +677,24 @@ def customize_build_cibuildwheel( + extensions.pop('jpegxl', None) + + ++def customize_build_riscv64( ++ extensions: dict[str, Any], ++ options: dict[str, Any], ++) -> None: ++ """Customize build for Rocky 10 riscv64 (pypi.riseproject.dev).""" ++ keep = { ++ 'shared', 'imcd', 'bmp', 'brotli', 'bz2', 'ccitt', 'cms', 'czi', ++ 'deflate', 'gif', 'jpeg2k', 'jpeg8', 'lerc', 'ljpeg', 'lz4', 'lzf', ++ 'lzma', 'pixarlog', 'png', 'snappy', 'tiff', 'webp', 'zlib', 'zstd', ++ } ++ del options['shared_utility_qualified_name'] ++ extensions['jpeg2k']['include_dirs'].append('/usr/include/openjpeg-2.5') ++ extensions['jpeg8']['sources'] = [] # use libjpeg-turbo 3 ++ for name in list(extensions): ++ if name not in keep: ++ extensions.pop(name) ++ ++ + def customize_build_condaforge( + extensions: dict[str, Any], + options: dict[str, Any], +@@ -1024,7 +1042,9 @@ if 'sdist' not in sys.argv: + with add_to_path(HERE): + from imagecodecs_distributor_setup import customize_build + except ImportError: +- if os.environ.get('PYODIDE', ''): ++ if os.environ.get('IMAGECODECS_RISCV64', ''): ++ customize_build = customize_build_riscv64 ++ elif os.environ.get('PYODIDE', ''): + customize_build = customize_build_pyodide + elif os.environ.get('COMPUTERNAME', '').startswith('CG-'): + customize_build = customize_build_cgohlke +-- +2.50.1 (Apple Git-155) + diff --git a/patches/imagecodecs/2026.10.10/0002-png-drop-cICP-call-libpng-1.6.40.patch b/patches/imagecodecs/2026.10.10/0002-png-drop-cICP-call-libpng-1.6.40.patch new file mode 100644 index 000000000000..752c497d9e04 --- /dev/null +++ b/patches/imagecodecs/2026.10.10/0002-png-drop-cICP-call-libpng-1.6.40.patch @@ -0,0 +1,46 @@ +From 7ee627a1f393d5c9ae83bdd3def1ee1c54089961 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Fri, 11 Sep 2026 23:02:16 +0200 +Subject: [PATCH] _png: drop the png_set_cICP call, unavailable before libpng + 1.6.45 + +png_set_cICP() was added to libpng in 1.6.45 (Jan 2025); Rocky 10 +riscv64's system libpng-devel is 1.6.40, which does not declare or +export the symbol at all, so the Cython-generated call fails to +compile (implicit-function-declaration under GCC 14) and would fail +to link even with that warning silenced. + +Drop the call so png_encode compiles against libpng 1.6.40; passing +primaries/transfer/matrix to png_encode becomes a silent no-op +instead of writing a cICP chunk, since that colour-primaries metadata +is not the primary use case this port targets. + +Upstream-Status: Inappropriate [riscv64/pypi.riseproject.dev-specific: works around an older system libpng on the manylinux_riscv64 image, not an imagecodecs bug] +--- + imagecodecs/_png.pyx | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/imagecodecs/_png.pyx b/imagecodecs/_png.pyx +index 10eb338..0082e21 100644 +--- a/imagecodecs/_png.pyx ++++ b/imagecodecs/_png.pyx +@@ -307,16 +307,6 @@ def png_encode( + PNG_FILTER_TYPE_DEFAULT + ) + +- if primaries_ >= 0 or transfer_ >= 0 or matrix_ >= 0: +- png_set_cICP( +- png_ptr, +- info_ptr, +- (primaries_ if primaries_ >= 0 else 2), +- (transfer_ if transfer_ >= 0 else 2), +- (matrix_ if matrix_ >= 0 else 2), +- 1 +- ) +- + png_write_info(png_ptr, info_ptr) + png_set_compression_level(png_ptr, level_) + png_set_compression_strategy(png_ptr, strategy_) +-- +2.50.1 (Apple Git-155) +