opencodecs 0.1.3__tar.gz → 0.1.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opencodecs-0.1.6/3rdparty/cfitsio/pliocomp.c +331 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/CHANGES.rst +222 -0
- {opencodecs-0.1.3/src/opencodecs.egg-info → opencodecs-0.1.6}/PKG-INFO +1 -1
- {opencodecs-0.1.3 → opencodecs-0.1.6}/pyproject.toml +7 -4
- {opencodecs-0.1.3 → opencodecs-0.1.6}/setup.py +199 -26
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/__init__.py +1 -1
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_eer_reader.py +35 -6
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_fits_compressed.py +34 -4
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_pyramid_build.py +66 -1
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_tiff_http.py +83 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_tiff_pyramid.py +38 -2
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_tiff_writer.py +51 -2
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/__init__.py +15 -3
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_bcdec.c +152 -152
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_bmp.c +152 -152
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_eer.c +152 -152
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_hcomp.c +152 -152
- opencodecs-0.1.6/src/opencodecs/codecs/_plio.c +30037 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_png.c +152 -152
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_qoi.c +152 -152
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_rcomp.c +152 -152
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_rgbe.c +152 -152
- opencodecs-0.1.6/src/opencodecs/uhdr.py +326 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6/src/opencodecs.egg-info}/PKG-INFO +1 -1
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs.egg-info/SOURCES.txt +4 -1
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_eer.py +61 -9
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_fits.py +14 -5
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_omezarr.py +13 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_tiff_http.py +74 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_tiff_writer.py +68 -0
- opencodecs-0.1.6/tests/test_uhdr.py +392 -0
- opencodecs-0.1.3/tests/test_ultrahdr.py +0 -130
- {opencodecs-0.1.3 → opencodecs-0.1.6}/3rdparty/bcdec/bcdec.h +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/3rdparty/bitshuffle/bitshuffle_core.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/3rdparty/bitshuffle/iochain.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/3rdparty/cfitsio/fits_hdecompress.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/3rdparty/cfitsio/ricecomp.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/3rdparty/imcd_eer/eer.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/3rdparty/imcd_eer/eer.h +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/3rdparty/imcd_lzw/lzw.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/3rdparty/imcd_lzw/lzw.h +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/3rdparty/libspng/spng.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/3rdparty/oc_tifflzw/oc_tifflzw.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/3rdparty/oc_tifflzw/oc_tifflzw.h +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/3rdparty/rgbe/rgbe.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/MANIFEST.in +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/README.md +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/bench/build_libjxl.sh +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/patches/libjxl/README.md +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/setup.cfg +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_aec_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_avif_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_b2nd_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_bcn_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_bitshuffle_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_blosc2_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_bmp_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_brotli_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_brunsli_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_byteshuffle_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_bz2_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_cms_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_czi_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_czi_reader.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_czi_writer.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_deflate_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_dicomrle_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_dicomweb.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_ets.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_fits.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_fits_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_gif_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_gzip_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_hdf5_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_hdf5_http.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_heif_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_htj2k_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_jpeg2k_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_jpeg_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_jpegls_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_jxl_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_lerc_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_lif_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_lif_native.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_lz4_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_lzma_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_mozjpeg_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_nd2_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_nd2_native.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_ndtiff.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_ndtiff_pyramid.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_ndtiff_writer.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_none_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_numpy_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_oib_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_oib_native.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_oir_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_ole2.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_ome_xml.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_omezarr.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_omezarr_writer.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_packints_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_pcodec_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_png_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_predictor_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_qoi_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_quantize_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_rcomp_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_rgbe.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_rgbe_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_snappy_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_sperr_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_sz3_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_tiff_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_ultrahdr_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_vsi_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_webp_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_zarr_codecs.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_zfp_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/_zstd_codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_bitshuffle.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_bytetools.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_deflate.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_lz4.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_ndtiff.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_registry.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_tiff.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/codecs/_zstd.c +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/core/__init__.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/core/_io_helpers.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/core/_optional_backend.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/core/codec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/core/color.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/core/errors.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/core/io.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/core/pyramid.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/core/segment_compression.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/jxl.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/parallel.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/tiff_reader.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/tifffile_patch.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs/zarr.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs.egg-info/dependency_links.txt +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs.egg-info/requires.txt +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/src/opencodecs.egg-info/top_level.txt +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_auto_pyramid.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_bcdec.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_brunsli.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_charls.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_core_codec_api.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_corpus.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_corpus_codec_decode.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_corpus_other.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_corpus_png.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_corpus_tiff.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_corpus_vendors.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_coverage_final.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_coverage_finishing.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_coverage_last.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_coverage_more.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_coverage_push.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_czi_fixture.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_czi_pyramid.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_czi_writer.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_data_source.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_deflate.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_dicomweb.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_edge_cases.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_encode_comprehensive.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_error_handling.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_gif.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_hdf5_http.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_hdf5_local.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_heif_avif_features.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_http_byte_savings.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_http_prefetch.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_http_unified.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_io_chunked.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_isal.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_jxl.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_lif_native.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_live_archives.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_mozjpeg.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_native_parity.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_nd2_native.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_ndtiff.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_oib_native.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_ome_xml.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_omezarr_sharded_range.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_open_pyramid.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_openjph.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_optional_backend.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_parallel_jxl.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_phase4_filters.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_phase5_icc.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_phase6_codecs.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_phase7_cms.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_rgbe.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_snappy.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_tier1_scientific.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_tiff_codec_encode.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_tiff_native.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_tiff_pyramid.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_tiff_reader.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_tifffile_patch.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_unified_api.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_vsi_oir.py +0 -0
- {opencodecs-0.1.3 → opencodecs-0.1.6}/tests/test_zarr_adapters.py +0 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/* stdlib is needed for the abs function */
|
|
2
|
+
#include <stdlib.h>
|
|
3
|
+
/*
|
|
4
|
+
The following prototype code was provided by Doug Tody, NRAO, for
|
|
5
|
+
performing conversion between pixel arrays and line lists. The
|
|
6
|
+
compression technique is used in IRAF.
|
|
7
|
+
*/
|
|
8
|
+
int pl_p2li (int *pxsrc, int xs, short *lldst, int npix);
|
|
9
|
+
int pl_l2pi (short *ll_src, int xs, int *px_dst, int npix);
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* PL_P2L -- Convert a pixel array to a line list. The length of the list is
|
|
14
|
+
* returned as the function value.
|
|
15
|
+
*
|
|
16
|
+
* Translated from the SPP version using xc -f, f2c. 8Sep99 DCT.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
#ifndef min
|
|
20
|
+
#define min(a,b) (((a)<(b))?(a):(b))
|
|
21
|
+
#endif
|
|
22
|
+
#ifndef max
|
|
23
|
+
#define max(a,b) (((a)>(b))?(a):(b))
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
int pl_p2li (int *pxsrc, int xs, short *lldst, int npix)
|
|
27
|
+
/* int *pxsrc; input pixel array */
|
|
28
|
+
/* int xs; starting index in pxsrc (?) */
|
|
29
|
+
/* short *lldst; encoded line list */
|
|
30
|
+
/* int npix; number of pixels to convert */
|
|
31
|
+
{
|
|
32
|
+
/* System generated locals */
|
|
33
|
+
int ret_val, i__1, i__2, i__3;
|
|
34
|
+
|
|
35
|
+
/* Local variables */
|
|
36
|
+
int zero, v, x1, hi, ip, dv, xe, np, op, iz, nv = 0, pv, nz;
|
|
37
|
+
|
|
38
|
+
/* Parameter adjustments */
|
|
39
|
+
--lldst;
|
|
40
|
+
--pxsrc;
|
|
41
|
+
|
|
42
|
+
/* Function Body */
|
|
43
|
+
if (! (npix <= 0)) {
|
|
44
|
+
goto L110;
|
|
45
|
+
}
|
|
46
|
+
ret_val = 0;
|
|
47
|
+
goto L100;
|
|
48
|
+
L110:
|
|
49
|
+
lldst[3] = -100;
|
|
50
|
+
lldst[2] = 7;
|
|
51
|
+
lldst[1] = 0;
|
|
52
|
+
lldst[6] = 0;
|
|
53
|
+
lldst[7] = 0;
|
|
54
|
+
xe = xs + npix - 1;
|
|
55
|
+
op = 8;
|
|
56
|
+
zero = 0;
|
|
57
|
+
/* Computing MAX */
|
|
58
|
+
i__1 = zero, i__2 = pxsrc[xs];
|
|
59
|
+
pv = max(i__1,i__2);
|
|
60
|
+
x1 = xs;
|
|
61
|
+
iz = xs;
|
|
62
|
+
hi = 1;
|
|
63
|
+
i__1 = xe;
|
|
64
|
+
for (ip = xs; ip <= i__1; ++ip) {
|
|
65
|
+
if (! (ip < xe)) {
|
|
66
|
+
goto L130;
|
|
67
|
+
}
|
|
68
|
+
/* Computing MAX */
|
|
69
|
+
i__2 = zero, i__3 = pxsrc[ip + 1];
|
|
70
|
+
nv = max(i__2,i__3);
|
|
71
|
+
if (! (nv == pv)) {
|
|
72
|
+
goto L140;
|
|
73
|
+
}
|
|
74
|
+
goto L120;
|
|
75
|
+
L140:
|
|
76
|
+
if (! (pv == 0)) {
|
|
77
|
+
goto L150;
|
|
78
|
+
}
|
|
79
|
+
pv = nv;
|
|
80
|
+
x1 = ip + 1;
|
|
81
|
+
goto L120;
|
|
82
|
+
L150:
|
|
83
|
+
goto L131;
|
|
84
|
+
L130:
|
|
85
|
+
if (! (pv == 0)) {
|
|
86
|
+
goto L160;
|
|
87
|
+
}
|
|
88
|
+
x1 = xe + 1;
|
|
89
|
+
L160:
|
|
90
|
+
L131:
|
|
91
|
+
np = ip - x1 + 1;
|
|
92
|
+
nz = x1 - iz;
|
|
93
|
+
if (! (pv > 0)) {
|
|
94
|
+
goto L170;
|
|
95
|
+
}
|
|
96
|
+
dv = pv - hi;
|
|
97
|
+
if (! (dv != 0)) {
|
|
98
|
+
goto L180;
|
|
99
|
+
}
|
|
100
|
+
hi = pv;
|
|
101
|
+
if (! (abs(dv) > 4095)) {
|
|
102
|
+
goto L190;
|
|
103
|
+
}
|
|
104
|
+
lldst[op] = (short) ((pv & 4095) + 4096);
|
|
105
|
+
++op;
|
|
106
|
+
lldst[op] = (short) (pv / 4096);
|
|
107
|
+
++op;
|
|
108
|
+
goto L191;
|
|
109
|
+
L190:
|
|
110
|
+
if (! (dv < 0)) {
|
|
111
|
+
goto L200;
|
|
112
|
+
}
|
|
113
|
+
lldst[op] = (short) (-dv + 12288);
|
|
114
|
+
goto L201;
|
|
115
|
+
L200:
|
|
116
|
+
lldst[op] = (short) (dv + 8192);
|
|
117
|
+
L201:
|
|
118
|
+
++op;
|
|
119
|
+
if (! (np == 1 && nz == 0)) {
|
|
120
|
+
goto L210;
|
|
121
|
+
}
|
|
122
|
+
v = lldst[op - 1];
|
|
123
|
+
lldst[op - 1] = (short) (v | 16384);
|
|
124
|
+
goto L91;
|
|
125
|
+
L210:
|
|
126
|
+
L191:
|
|
127
|
+
L180:
|
|
128
|
+
L170:
|
|
129
|
+
if (! (nz > 0)) {
|
|
130
|
+
goto L220;
|
|
131
|
+
}
|
|
132
|
+
L230:
|
|
133
|
+
if (! (nz > 0)) {
|
|
134
|
+
goto L232;
|
|
135
|
+
}
|
|
136
|
+
lldst[op] = (short) min(4095,nz);
|
|
137
|
+
++op;
|
|
138
|
+
/* L231: */
|
|
139
|
+
nz += -4095;
|
|
140
|
+
goto L230;
|
|
141
|
+
L232:
|
|
142
|
+
if (! (np == 1 && pv > 0)) {
|
|
143
|
+
goto L240;
|
|
144
|
+
}
|
|
145
|
+
lldst[op - 1] = (short) (lldst[op - 1] + 20481);
|
|
146
|
+
goto L91;
|
|
147
|
+
L240:
|
|
148
|
+
L220:
|
|
149
|
+
L250:
|
|
150
|
+
if (! (np > 0)) {
|
|
151
|
+
goto L252;
|
|
152
|
+
}
|
|
153
|
+
lldst[op] = (short) (min(4095,np) + 16384);
|
|
154
|
+
++op;
|
|
155
|
+
/* L251: */
|
|
156
|
+
np += -4095;
|
|
157
|
+
goto L250;
|
|
158
|
+
L252:
|
|
159
|
+
L91:
|
|
160
|
+
x1 = ip + 1;
|
|
161
|
+
iz = x1;
|
|
162
|
+
pv = nv;
|
|
163
|
+
L120:
|
|
164
|
+
;
|
|
165
|
+
}
|
|
166
|
+
/* L121: */
|
|
167
|
+
lldst[4] = (short) ((op - 1) % 32768);
|
|
168
|
+
lldst[5] = (short) ((op - 1) / 32768);
|
|
169
|
+
ret_val = op - 1;
|
|
170
|
+
goto L100;
|
|
171
|
+
L100:
|
|
172
|
+
return ret_val;
|
|
173
|
+
} /* plp2li_ */
|
|
174
|
+
|
|
175
|
+
/*
|
|
176
|
+
* PL_L2PI -- Translate a PLIO line list into an integer pixel array.
|
|
177
|
+
* The number of pixels output (always npix) is returned as the function
|
|
178
|
+
* value.
|
|
179
|
+
*
|
|
180
|
+
* Translated from the SPP version using xc -f, f2c. 8Sep99 DCT.
|
|
181
|
+
*/
|
|
182
|
+
|
|
183
|
+
int pl_l2pi (short *ll_src, int xs, int *px_dst, int npix)
|
|
184
|
+
/* short *ll_src; encoded line list */
|
|
185
|
+
/* int xs; starting index in ll_src */
|
|
186
|
+
/* int *px_dst; output pixel array */
|
|
187
|
+
/* int npix; number of pixels to convert */
|
|
188
|
+
{
|
|
189
|
+
/* System generated locals */
|
|
190
|
+
int ret_val, i__1, i__2;
|
|
191
|
+
|
|
192
|
+
/* Local variables */
|
|
193
|
+
int data, sw0001, otop, i__, lllen, i1, i2, x1, x2, ip, xe, np,
|
|
194
|
+
op, pv, opcode, llfirt;
|
|
195
|
+
int skipwd;
|
|
196
|
+
|
|
197
|
+
/* Parameter adjustments */
|
|
198
|
+
--px_dst;
|
|
199
|
+
--ll_src;
|
|
200
|
+
|
|
201
|
+
/* Function Body */
|
|
202
|
+
if (! (ll_src[3] > 0)) {
|
|
203
|
+
goto L110;
|
|
204
|
+
}
|
|
205
|
+
lllen = ll_src[3];
|
|
206
|
+
llfirt = 4;
|
|
207
|
+
goto L111;
|
|
208
|
+
L110:
|
|
209
|
+
lllen = (ll_src[5] << 15) + ll_src[4];
|
|
210
|
+
llfirt = ll_src[2] + 1;
|
|
211
|
+
L111:
|
|
212
|
+
if (! (npix <= 0 || lllen <= 0)) {
|
|
213
|
+
goto L120;
|
|
214
|
+
}
|
|
215
|
+
ret_val = 0;
|
|
216
|
+
goto L100;
|
|
217
|
+
L120:
|
|
218
|
+
xe = xs + npix - 1;
|
|
219
|
+
skipwd = 0;
|
|
220
|
+
op = 1;
|
|
221
|
+
x1 = 1;
|
|
222
|
+
pv = 1;
|
|
223
|
+
i__1 = lllen;
|
|
224
|
+
for (ip = llfirt; ip <= i__1; ++ip) {
|
|
225
|
+
if (! skipwd) {
|
|
226
|
+
goto L140;
|
|
227
|
+
}
|
|
228
|
+
skipwd = 0;
|
|
229
|
+
goto L130;
|
|
230
|
+
L140:
|
|
231
|
+
opcode = ll_src[ip] / 4096;
|
|
232
|
+
data = ll_src[ip] & 4095;
|
|
233
|
+
sw0001 = opcode;
|
|
234
|
+
goto L150;
|
|
235
|
+
L160:
|
|
236
|
+
x2 = x1 + data - 1;
|
|
237
|
+
i1 = max(x1,xs);
|
|
238
|
+
i2 = min(x2,xe);
|
|
239
|
+
np = i2 - i1 + 1;
|
|
240
|
+
if (! (np > 0)) {
|
|
241
|
+
goto L170;
|
|
242
|
+
}
|
|
243
|
+
otop = op + np - 1;
|
|
244
|
+
if (! (opcode == 4)) {
|
|
245
|
+
goto L180;
|
|
246
|
+
}
|
|
247
|
+
i__2 = otop;
|
|
248
|
+
for (i__ = op; i__ <= i__2; ++i__) {
|
|
249
|
+
px_dst[i__] = pv;
|
|
250
|
+
/* L190: */
|
|
251
|
+
}
|
|
252
|
+
/* L191: */
|
|
253
|
+
goto L181;
|
|
254
|
+
L180:
|
|
255
|
+
i__2 = otop;
|
|
256
|
+
for (i__ = op; i__ <= i__2; ++i__) {
|
|
257
|
+
px_dst[i__] = 0;
|
|
258
|
+
/* L200: */
|
|
259
|
+
}
|
|
260
|
+
/* L201: */
|
|
261
|
+
if (! (opcode == 5 && i2 == x2)) {
|
|
262
|
+
goto L210;
|
|
263
|
+
}
|
|
264
|
+
px_dst[otop] = pv;
|
|
265
|
+
L210:
|
|
266
|
+
L181:
|
|
267
|
+
op = otop + 1;
|
|
268
|
+
L170:
|
|
269
|
+
x1 = x2 + 1;
|
|
270
|
+
goto L151;
|
|
271
|
+
L220:
|
|
272
|
+
pv = (ll_src[ip + 1] << 12) + data;
|
|
273
|
+
skipwd = 1;
|
|
274
|
+
goto L151;
|
|
275
|
+
L230:
|
|
276
|
+
pv += data;
|
|
277
|
+
goto L151;
|
|
278
|
+
L240:
|
|
279
|
+
pv -= data;
|
|
280
|
+
goto L151;
|
|
281
|
+
L250:
|
|
282
|
+
pv += data;
|
|
283
|
+
goto L91;
|
|
284
|
+
L260:
|
|
285
|
+
pv -= data;
|
|
286
|
+
L91:
|
|
287
|
+
if (! (x1 >= xs && x1 <= xe)) {
|
|
288
|
+
goto L270;
|
|
289
|
+
}
|
|
290
|
+
px_dst[op] = pv;
|
|
291
|
+
++op;
|
|
292
|
+
L270:
|
|
293
|
+
++x1;
|
|
294
|
+
goto L151;
|
|
295
|
+
L150:
|
|
296
|
+
++sw0001;
|
|
297
|
+
if (sw0001 < 1 || sw0001 > 8) {
|
|
298
|
+
goto L151;
|
|
299
|
+
}
|
|
300
|
+
switch ((int)sw0001) {
|
|
301
|
+
case 1: goto L160;
|
|
302
|
+
case 2: goto L220;
|
|
303
|
+
case 3: goto L230;
|
|
304
|
+
case 4: goto L240;
|
|
305
|
+
case 5: goto L160;
|
|
306
|
+
case 6: goto L160;
|
|
307
|
+
case 7: goto L250;
|
|
308
|
+
case 8: goto L260;
|
|
309
|
+
}
|
|
310
|
+
L151:
|
|
311
|
+
if (! (x1 > xe)) {
|
|
312
|
+
goto L280;
|
|
313
|
+
}
|
|
314
|
+
goto L131;
|
|
315
|
+
L280:
|
|
316
|
+
L130:
|
|
317
|
+
;
|
|
318
|
+
}
|
|
319
|
+
L131:
|
|
320
|
+
i__1 = npix;
|
|
321
|
+
for (i__ = op; i__ <= i__1; ++i__) {
|
|
322
|
+
px_dst[i__] = 0;
|
|
323
|
+
/* L290: */
|
|
324
|
+
}
|
|
325
|
+
/* L291: */
|
|
326
|
+
ret_val = npix;
|
|
327
|
+
goto L100;
|
|
328
|
+
L100:
|
|
329
|
+
return ret_val;
|
|
330
|
+
} /* pll2pi_ */
|
|
331
|
+
|
|
@@ -10,6 +10,228 @@ Versions follow the same ``YYYY.M.D`` cadence as upstream when we
|
|
|
10
10
|
publish; the entries below cluster work by date rather than by
|
|
11
11
|
release because most of it has shipped continuously to ``main``.
|
|
12
12
|
|
|
13
|
+
0.1.6 (2026-06-01)
|
|
14
|
+
------------------
|
|
15
|
+
|
|
16
|
+
**libultrahdr now bundled (fixes missing ``_uhdr`` on PyPI wheels)**
|
|
17
|
+
|
|
18
|
+
* ``bench/build_codec_libs.sh::build_libultrahdr`` builds libuhdr
|
|
19
|
+
v1.4.0 (Apache-2.0) into ``$OPENCODECS_LIBS_PREFIX/{include,lib}``
|
|
20
|
+
alongside the other source-built codec libs. The Linux + Windows
|
|
21
|
+
CI ``--only=...`` lists pick it up; the macOS ``before-all`` brew
|
|
22
|
+
install now includes ``libultrahdr`` as well.
|
|
23
|
+
* setup.py's ``_uhdr`` Extension is now built by a probe
|
|
24
|
+
(``_maybe_build_uhdr_ext``) that finds the cached prefix, sets
|
|
25
|
+
``library_dirs``, and bakes the rpath into the resulting ``.so``
|
|
26
|
+
so delocate / auditwheel / delvewheel can bundle ``libuhdr``'s
|
|
27
|
+
dylib/.so/.dll into the wheel.
|
|
28
|
+
* ``_uhdr`` is now in ``MUST_SHIP_ALL_PLATFORMS`` in
|
|
29
|
+
``ci/check_wheel_contents.py``; a wheel without the Ultra-HDR
|
|
30
|
+
extension fails the wheel-coverage step.
|
|
31
|
+
* The stale ``_ultrahdr.pyx`` source file (orphaned in commit
|
|
32
|
+
``c9347f5`` when the direct libuhdr binding shipped as ``_uhdr``)
|
|
33
|
+
is removed.
|
|
34
|
+
|
|
35
|
+
**New API: ``opencodecs.uhdr.decode_native``**
|
|
36
|
+
|
|
37
|
+
Fused-Cython fast-path Ultra-HDR decoder. Uses libuhdr's parser to
|
|
38
|
+
pull out the compressed SDR base + gain-map JPEGs + metadata (no
|
|
39
|
+
pixel decode), then decodes both JPEGs in parallel via
|
|
40
|
+
``imagecodecs.jpeg_decode`` (libjpeg-turbo SIMD, GIL released) and
|
|
41
|
+
applies the gain map in a Cython kernel that uses the same sRGB
|
|
42
|
+
EOTF LUT + IEEE-754 polynomial ``exp2`` the encoder uses. ~1.4×
|
|
43
|
+
faster than libuhdr's reference decode on a 2k² float HDR (M-series
|
|
44
|
+
Mac: ~52 ms vs ~72 ms). Output matches libuhdr's decode to within
|
|
45
|
+
JPEG-q95 + 8-bit gain-quantisation noise. ``display_boost`` kwarg
|
|
46
|
+
exposes the ISO 21496-1 headroom scaler — default is full HDR
|
|
47
|
+
(``hdr_capacity_max``), pass ``1.0`` to match libuhdr's default
|
|
48
|
+
SDR-equivalent decode.
|
|
49
|
+
|
|
50
|
+
Backed by two new Cython helpers exposed for advanced callers:
|
|
51
|
+
|
|
52
|
+
* ``opencodecs.codecs._uhdr.extract_layers(data)`` — parse the
|
|
53
|
+
container, return ``{base_jpeg, gainmap_jpeg, gainmap_metadata,
|
|
54
|
+
width, height, gainmap_{width,height}}`` without decoding pixels.
|
|
55
|
+
* ``opencodecs.codecs._uhdr.apply_gainmap_fp32(sdr_u8, gain_u8,
|
|
56
|
+
metadata, display_boost=...)`` — the per-pixel gain-application
|
|
57
|
+
kernel.
|
|
58
|
+
|
|
59
|
+
**New API: ``opencodecs.uhdr.encode_to``**
|
|
60
|
+
|
|
61
|
+
Streaming variant of :func:`encode_native` — writes Ultra-HDR bytes
|
|
62
|
+
directly to a file-like (anything with ``write(bytes)``: open file,
|
|
63
|
+
``io.BytesIO``, HTTP upload streamer). Returns the byte count.
|
|
64
|
+
Forward-compatible alias: the libuhdr api-4 path we currently use
|
|
65
|
+
for container assembly doesn't expose a streaming writer, so the
|
|
66
|
+
function is ``fp.write(encode_native(...))`` today; the API exists
|
|
67
|
+
so callers can adopt it now and pick up any future libuhdr
|
|
68
|
+
streaming write-out without changing their code.
|
|
69
|
+
|
|
70
|
+
**CI / build robustness**
|
|
71
|
+
|
|
72
|
+
* ``_uhdr`` extension now links ``-lmvec -lm`` on Linux. GCC at
|
|
73
|
+
``-O3 -ffast-math`` auto-vectorises the sRGB LUT-init ``pow()``
|
|
74
|
+
calls into ``_ZGV*`` symbols from glibc's libmvec. AlmaLinux 8's
|
|
75
|
+
manylinux toolchain auto-links libmvec so the issue was masked
|
|
76
|
+
in CI, but Ubuntu's GCC doesn't — caught when verifying on a
|
|
77
|
+
threadripper Ubuntu 25.04 box.
|
|
78
|
+
* The libaec source URL moved from ``gitlab.dkrz.de`` (now
|
|
79
|
+
auth-gated; anonymous requests redirect to ``/users/sign_in``)
|
|
80
|
+
to DKRZ's GitHub mirror at
|
|
81
|
+
``github.com/Deutsches-Klimarechenzentrum/libaec``.
|
|
82
|
+
* ``fetch_tar`` now has a 4-attempt shell retry loop with empty-
|
|
83
|
+
extract detection — covers transient mirror outages that
|
|
84
|
+
curl's own ``--retry`` doesn't see (e.g. 200 OK with a
|
|
85
|
+
truncated body).
|
|
86
|
+
|
|
87
|
+
0.1.5 (2026-05-31)
|
|
88
|
+
------------------
|
|
89
|
+
|
|
90
|
+
**New codecs**
|
|
91
|
+
|
|
92
|
+
* ``opencodecs.uhdr`` — Ultra-HDR / ISO 21496-1 (gainmap JPEG) via a
|
|
93
|
+
direct Cython binding to Google's libultrahdr. ``encode(hdr, ...)``
|
|
94
|
+
wraps libuhdr's full pipeline; ``encode_native(hdr, sdr=None, ...)``
|
|
95
|
+
is a fused-Cython fast path that computes SDR base + gain map in
|
|
96
|
+
``nogil`` kernels (IEEE-754 polynomial log2/pow, cross-platform —
|
|
97
|
+
no Apple Accelerate intrinsics), JPEG-encodes both layers in
|
|
98
|
+
parallel via a 3-worker ThreadPoolExecutor, then hands the
|
|
99
|
+
pre-encoded JPEGs to libuhdr's api-4 for container assembly.
|
|
100
|
+
Measured 31 ms median for a 2000² float HDR on M-series Mac vs
|
|
101
|
+
~173 ms for the libuhdr reference path — 5.5× faster. The
|
|
102
|
+
``sdr=`` argument lets callers (notably tilescan pipelines) supply
|
|
103
|
+
their own SDR base instead of accepting the peak-normalised default.
|
|
104
|
+
|
|
105
|
+
* ``PLIO_1`` — IRAF run-length mask coding closes the last FITS
|
|
106
|
+
tile-compression gap. Vendors cfitsio's ``pliocomp.c`` (Doug Tody /
|
|
107
|
+
NRAO, public-domain) and adds the tiny
|
|
108
|
+
``opencodecs.codecs._plio.decode_raw`` shim. Round-trip tested
|
|
109
|
+
against astropy. The ``COMPRESSED_DATA`` BINTABLE column walker
|
|
110
|
+
now tracks per-column element byte width so the ``1PI`` (int16
|
|
111
|
+
opcodes) layout PLIO uses works alongside the ``1PB`` byte VLA the
|
|
112
|
+
other compressors use.
|
|
113
|
+
|
|
114
|
+
**New API**
|
|
115
|
+
|
|
116
|
+
* ``EerReader.sum(start, stop, *, weights=None, dtype=...)`` —
|
|
117
|
+
per-frame dose curve. ``weights[k]`` multiplies the k-th frame in
|
|
118
|
+
the requested range; output promotes to float64 when weights are
|
|
119
|
+
given so fractional contributions don't truncate. Use case:
|
|
120
|
+
beam-induced-motion correction and temporal-binning schemes that
|
|
121
|
+
emphasise different exposures across the acquisition.
|
|
122
|
+
|
|
123
|
+
**Bug fixes**
|
|
124
|
+
|
|
125
|
+
* HEIF encode against libheif ≥ 1.18 — newer libheif calls
|
|
126
|
+
``strlen()`` on the user write-callback's ``heif_error.message``
|
|
127
|
+
even on success and rejects a ``NULL`` pointer with *"heif_writer
|
|
128
|
+
callback returned a null error text"*. The callback now hands back
|
|
129
|
+
a static empty string on success and a descriptive string on OOM.
|
|
130
|
+
Six tests (``test_heif_*``, ``test_phase5_icc.py[heif]``) go back
|
|
131
|
+
to green across every CI matrix entry.
|
|
132
|
+
|
|
133
|
+
**CI / build**
|
|
134
|
+
|
|
135
|
+
* ``bench/build_codec_libs.sh`` — the ``is_built`` cache-marker now
|
|
136
|
+
records the install dir alongside the version and re-verifies the
|
|
137
|
+
install dir exists before short-circuiting a recipe. Without this,
|
|
138
|
+
cibuildwheel's manylinux cache (which only covers ``/cibw-jxl-prefix``)
|
|
139
|
+
preserved the marker for recipes that install to
|
|
140
|
+
``~/.cache/opencodecs/<lib>/`` outside the cached prefix —
|
|
141
|
+
``lerc``, ``mozjpeg``, ``brotli``, ``zstd``, ``giflib`` — so the
|
|
142
|
+
recipe thought it was done while the actual library files were
|
|
143
|
+
gone. ``_lerc`` + ``_mozjpeg`` had been silently dropped from
|
|
144
|
+
Linux wheels for this reason; the fix restores them.
|
|
145
|
+
|
|
146
|
+
* ``test_omezarr.py`` skips at module level on zarr-python < 3 —
|
|
147
|
+
fixtures use the v3 API surface, which doesn't exist on the v2
|
|
148
|
+
branch pip resolves on Python 3.10.
|
|
149
|
+
|
|
150
|
+
* ``test_eer_imagecodecs_cross_validate`` is now symmetric on
|
|
151
|
+
decoder error: if either implementation raises, both must raise
|
|
152
|
+
for the combo to count. Tolerates imagecodecs ≥ 2026.5's tighter
|
|
153
|
+
output-buffer sizing.
|
|
154
|
+
|
|
155
|
+
0.1.4 (2026-05-25)
|
|
156
|
+
------------------
|
|
157
|
+
|
|
158
|
+
**libvips-inspired streaming improvements**
|
|
159
|
+
|
|
160
|
+
* ``HTTPDataSource(access='sequential', sequential_chunk_bytes=4*1024*1024)``
|
|
161
|
+
— opt-in libvips-style sequential read mode. Replaces the LRU +
|
|
162
|
+
adaptive read-ahead with a single rolling buffer that slides forward
|
|
163
|
+
as the caller reads. Memory stays bounded to one chunk regardless of
|
|
164
|
+
file size. Target workload: tile-by-tile raster scan over a huge
|
|
165
|
+
COG / OME-TIFF served over HTTP. Backward seeks still work but
|
|
166
|
+
invalidate the buffer; ``stats['sequential_backward_seeks']`` tracks
|
|
167
|
+
the count so users can spot a workload that's actually random and
|
|
168
|
+
would benefit from ``access='random'``.
|
|
169
|
+
|
|
170
|
+
* ``TiffPyramidReader.read_region`` now parallelises tile decode
|
|
171
|
+
across a thread pool (default ``min(cpu_count(), 8)``). The
|
|
172
|
+
compressed-tile decoders (JPEG, JPEG-2000, deflate, zstd, LZW, WebP,
|
|
173
|
+
LERC) all release the GIL in their C path, so threads scale across
|
|
174
|
+
cores on CPython. Kicks in only when the region covers 4+ tiles —
|
|
175
|
+
fewer than that and thread-pool spin-up cost dominates. Pass
|
|
176
|
+
``num_decode_workers=1`` to force the serial path for benchmarks /
|
|
177
|
+
regression-diff.
|
|
178
|
+
|
|
179
|
+
* ``TiffWriter.write_pyramid_auto`` gained ``stream_levels=True``
|
|
180
|
+
(default for COG layout). Computes and writes one level at a time
|
|
181
|
+
via a new ``iter_pyramid_levels`` generator, dropping each finished
|
|
182
|
+
level before computing the next. Peak memory drops from
|
|
183
|
+
``~1.33 × level0`` (entire geometric series materialised) to
|
|
184
|
+
``~2 × current_level``. Useful when level 0 already dominates RAM
|
|
185
|
+
(whole-slide pathology, cryo-EM tomograms). Output file is
|
|
186
|
+
byte-identical to the materialize-all path. SubIFD layout
|
|
187
|
+
(``subifds=True``) still uses the materialize path because that
|
|
188
|
+
layout writes sub-resolution IFD offsets into the main IFD's tag
|
|
189
|
+
330 — sub-level offsets have to be known up front.
|
|
190
|
+
|
|
191
|
+
Validated via tests:
|
|
192
|
+
``test_http_sequential_serves_from_rolling_buffer``,
|
|
193
|
+
``test_http_sequential_backward_seek_counted``,
|
|
194
|
+
``test_pyramid_reader_parallel_decode_matches_serial``,
|
|
195
|
+
``test_pyramid_auto_stream_matches_materialize``,
|
|
196
|
+
``test_iter_pyramid_levels_matches_make_pyramid_levels``.
|
|
197
|
+
|
|
198
|
+
**MozJPEG ships on every wheel**
|
|
199
|
+
|
|
200
|
+
* Added MozJPEG (Mozilla's libjpeg-turbo fork) to the cibuildwheel
|
|
201
|
+
codec-lib build set on Linux, macOS, and Windows. MozJPEG produces
|
|
202
|
+
JPEG files ~10-15% smaller than baseline libjpeg-turbo at the same
|
|
203
|
+
quality setting (progressive encoding + trellis quantization +
|
|
204
|
+
better quantization tables). The ``_mozjpeg`` extension has shipped
|
|
205
|
+
on macOS wheels for a while via brew; v0.1.4 brings it to
|
|
206
|
+
Linux + Windows so the codec is available everywhere.
|
|
207
|
+
* New ``build_mozjpeg`` recipe in ``bench/build_codec_libs.sh``
|
|
208
|
+
installs into a keg-style ``mozjpeg/`` subdir under the prefix
|
|
209
|
+
(rather than the shared ``$PREFIX/{include,lib}``) to avoid the
|
|
210
|
+
libturbojpeg / libjpeg name collision with the libjpeg-turbo 3.x
|
|
211
|
+
install. setup.py's mozjpeg probe was extended to recognise the
|
|
212
|
+
new candidate paths on Linux (``~/.cache/opencodecs/mozjpeg``),
|
|
213
|
+
Windows (``$CONDA_PREFIX/Library/mozjpeg``), and the Windows
|
|
214
|
+
fallback (no ``nm``: trust the keg-style directory name).
|
|
215
|
+
* Locally validated on win-vm (MSVC 14.44 — same as CI) and
|
|
216
|
+
kevin-tower (Linux x86_64): ``bash bench/build_codec_libs.sh
|
|
217
|
+
--only=mozjpeg`` followed by ``setup.py build_ext --inplace``
|
|
218
|
+
produces ``_mozjpeg.{pyd,so}`` cleanly. Per the new lesson in
|
|
219
|
+
CLAUDE.md, this iteration was validated end-to-end through the
|
|
220
|
+
same script CI runs, with the same env vars, before any push.
|
|
221
|
+
|
|
222
|
+
**Post-publish wheel coverage check (CI hardening)**
|
|
223
|
+
|
|
224
|
+
* New ``ci/check_wheel_contents.py`` runs in the wheel-build job
|
|
225
|
+
immediately after ``cibuildwheel`` produces each wheel. It unzips
|
|
226
|
+
the wheel, walks ``opencodecs/codecs/``, and asserts every codec
|
|
227
|
+
in the ``MUST_SHIP_ALL_PLATFORMS`` set has a ``.pyd``/``.so``
|
|
228
|
+
present. Missing codec → matrix job fails → publish step gated.
|
|
229
|
+
* Catches the v0.1.2-style "changelog overclaim" silent-drop class
|
|
230
|
+
of bugs at build time instead of after publish. v0.1.2's Windows
|
|
231
|
+
wheels shipped without ``_sperr``/``_brunsli`` despite the
|
|
232
|
+
changelog claim; this check would have failed that build.
|
|
233
|
+
|
|
234
|
+
|
|
13
235
|
0.1.3 (2026-05-22)
|
|
14
236
|
------------------
|
|
15
237
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "opencodecs"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.6"
|
|
8
8
|
description = "Streaming, network-aware image codecs for scientific imaging (prototype: JPEG XL)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -142,7 +142,7 @@ before-all = [
|
|
|
142
142
|
# bench/build_codec_libs.sh into the cached /cibw-jxl-prefix mount.
|
|
143
143
|
# Skips encoders (aom, x265) — wheel ships decode-only AVIF/HEIF to
|
|
144
144
|
# keep build < 12 min cold + avoid GPL x265.
|
|
145
|
-
"bash -c 'PATH=$HOME/.cargo/bin:$PATH bash bench/build_codec_libs.sh --only=libjpeg-turbo,c-blosc2,libde265,dav1d,libavif,libheif,libaec,lerc,zfp,SZ3,pcodec,SPERR,brunsli'",
|
|
145
|
+
"bash -c 'PATH=$HOME/.cargo/bin:$PATH bash bench/build_codec_libs.sh --only=libjpeg-turbo,c-blosc2,libde265,dav1d,libavif,libheif,libaec,lerc,zfp,SZ3,pcodec,SPERR,brunsli,mozjpeg,libultrahdr'",
|
|
146
146
|
"bash bench/build_libjxl.sh",
|
|
147
147
|
]
|
|
148
148
|
# Don't set OPENCODECS_*_PREFIX here — build_wheels.yml's
|
|
@@ -159,8 +159,11 @@ before-all = [
|
|
|
159
159
|
# cache by bench/build_codec_libs.sh. brunsli vendors brotli as a
|
|
160
160
|
# submodule so the brew brotli isn't required at link time.
|
|
161
161
|
before-all = [
|
|
162
|
-
|
|
163
|
-
|
|
162
|
+
# mozjpeg removed from this brew install — the formula ships libjpeg
|
|
163
|
+
# only, not libturbojpeg, so the _mozjpeg probe couldn't find what it
|
|
164
|
+
# needed. Source-build via build_codec_libs.sh produces both libs.
|
|
165
|
+
"brew install jpeg-xl libavif libheif webp libpng jpeg-turbo openjpeg zstd brotli c-blosc2 lz4 libdeflate libaec liblerc zfp rust cmake ninja libultrahdr",
|
|
166
|
+
"bash bench/build_codec_libs.sh --only=SZ3,pcodec,SPERR,brunsli,mozjpeg",
|
|
164
167
|
]
|
|
165
168
|
# macos-latest is now macOS 15 (Sequoia) on arm64. Homebrew formulas are
|
|
166
169
|
# compiled for 15.x, so any wheel target lower than 15 fails the delocate
|