opencodecs 0.6.0__tar.gz → 0.7.0__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.6.0 → opencodecs-0.7.0}/CHANGES.rst +42 -0
- {opencodecs-0.6.0/src/opencodecs.egg-info → opencodecs-0.7.0}/PKG-INFO +1 -1
- {opencodecs-0.6.0 → opencodecs-0.7.0}/pyproject.toml +1 -1
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/__init__.py +1 -1
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_czi_writer.py +127 -8
- {opencodecs-0.6.0 → opencodecs-0.7.0/src/opencodecs.egg-info}/PKG-INFO +1 -1
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_recompress.py +109 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/VENDOR.toml +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/bcdec/LICENSE +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/bcdec/README.md +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/bcdec/bcdec.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/bitshuffle/LICENSE +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/bitshuffle/README.rst +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/bitshuffle/bitshuffle.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/bitshuffle/bitshuffle.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/bitshuffle/bitshuffle_core.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/bitshuffle/bitshuffle_core.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/bitshuffle/bitshuffle_internals.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/bitshuffle/iochain.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/bitshuffle/iochain.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/cfitsio/License.txt +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/cfitsio/fits_hcompress.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/cfitsio/fits_hdecompress.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/cfitsio/fits_hdecompress_api.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/cfitsio/fitsio2.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/cfitsio/pliocomp.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/cfitsio/ricecomp.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/cfitsio/ricecomp.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/libspng/LICENSE +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/libspng/spng.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/libspng/spng.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/oc_eer/LICENSE +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/oc_eer/oc_eer.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/oc_eer/oc_eer.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/oc_giflzw/LICENSE +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/oc_giflzw/oc_giflzw.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/oc_giflzw/oc_giflzw.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/oc_tifflzw/LICENSE +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/oc_tifflzw/oc_tifflzw.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/oc_tifflzw/oc_tifflzw.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/qoi/LICENSE +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/qoi/qoi.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/rgbe/rgbe.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/rgbe/rgbe.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/rgbe/rgbe.txt +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/3rdparty/vendor_hashes.json +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/LICENSE +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/MANIFEST.in +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/README.md +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/THIRD-PARTY.md +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/bench/build_libjxl.sh +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/patches/libjxl/README.md +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/setup.cfg +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/setup.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_aec_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_avif_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_avif_heif_params.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_b2nd_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_bcn_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_bitshuffle_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_blosc2_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_bmp_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_brotli_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_brunsli_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_byteshuffle_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_bz2_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_cms_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_czi_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_czi_reader.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_deflate_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_dicom.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_dicom_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_dicom_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_dicomrle_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_dicomweb.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_dm.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_dm_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_eer_reader.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_emd.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_emd_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_ets.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_filter_args.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_fits.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_fits_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_fits_compressed.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_gif_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_gzip_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_h5_common.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_hdf5_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_hdf5_http.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_heif_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_htj2k_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_htj2k_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_imaris.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_jpeg2k_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_jpeg2k_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_jpeg_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_jpeg_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_jpegls_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_jxl_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_lerc_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_lif_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_lif_native.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_lz4_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_lzma_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_mozjpeg_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_mozjpeg_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_mrc.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_mrc_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_mrc_writer.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_n5.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_nd2_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_nd2_native.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_ndtiff.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_ndtiff_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_ndtiff_writer.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_nifti.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_nifti_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_nifti_writer.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_none_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_nrrd.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_nrrd_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_numpy_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_numpy_reader.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_oib_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_oib_native.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_oir_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_ole2.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_ome_xml.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_omezarr.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_omezarr_writer.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_packints_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_pcodec_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_png_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_predictor_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_pyramid_build.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_qoi_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_quantize_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_rcomp_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_rgbe.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_rgbe_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_scaled_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_snappy_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_sperr_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_sz3_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_tiff_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_tiff_http.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_tiff_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_tiff_writer.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_ultrahdr_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_vsi_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_vsi_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_webp_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_zarr_codecs.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_zfp_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/_zstd_codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/__init__.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_aec.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_avif.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_b2nd.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_bcdec.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_bitshuffle.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_blosc2.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_bmp.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_brotli.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_brunsli.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_bytetools.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_charls.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_deflate.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_eer.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_gif.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_hcomp.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_heif.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_isal.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_jpeg.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_jpeg2k.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_jpeg_common.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_jpegxr.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_jxl.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_lerc.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_lz4.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_mozjpeg.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_ndtiff.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_openjph.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_pcodec.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_plio.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_png.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_qoi.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_rcomp.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_registry.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_rgbe.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_snappy.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_sperr.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_sz3.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_tiff.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_uhdr.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_webp.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_zfp.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/_zstd.pyx +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/avif.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/b2nd.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/b2nd_helpers.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/b2nd_helpers.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/bcdec.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/bitshuffle.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/blosc2.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/brotli.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/brunsli.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/byteplanes.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/charls.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/eer.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/giflib.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/heif.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/heif_shim.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/isal_shim.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/jpegxr_shim.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/jpegxr_shim.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/lerc.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/libaec.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/libjxl.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/libuhdr.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/lz4.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/mozjpeg.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/oc_decoder_vtable.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/openjpeg.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/openjph.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/openjph_shim.cpp +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/openjph_shim.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/pcodec.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/qoi.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/rgbe.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/snappy.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/sperr.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/spng.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/sz3c.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/turbojpeg.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/webp.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/webp_shim.c +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/webp_shim.h +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/zfp.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/zlib_h.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/codecs/zstd.pxd +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/__init__.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/_io_helpers.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/_optional_backend.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/_range_index.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/_sidecar_header.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/_write_helpers.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/buffers.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/checksums.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/codec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/color.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/errors.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/io.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/native_source.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/parallel.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/pipeline.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/rows.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/scratch.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/segment_compression.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/streaming.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/tile_cache.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/core/verification.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/jxl.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/parallel.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/tiff_reader.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/uhdr.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs/zarr.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs.egg-info/SOURCES.txt +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs.egg-info/dependency_links.txt +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs.egg-info/requires.txt +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/src/opencodecs.egg-info/top_level.txt +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_auto_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_avif_heif_params.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_avif_sequence.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_b2nd_file_reader.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_bcdec.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_bcn_bands.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_bcn_rounding.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_bitshuffle_format.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_blosc2_partial.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_blosc2_threads.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_bmp_headers.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_bounded_pipeline.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_brunsli.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_byteplanes.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_bytestream_standards.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_capability_manifest.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_charls.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_chunked_means_cheap.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_codec_registry.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_container_pipeline.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_container_streaming.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_core_codec_api.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_corpus.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_corpus_codec_decode.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_corpus_manifest.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_corpus_native_fixtures.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_corpus_other.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_corpus_png.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_corpus_tiff.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_corpus_vendors.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_coverage_final.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_coverage_finishing.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_coverage_last.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_coverage_more.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_coverage_push.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_bounded_iteration.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_direct_decode.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_fixture.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_mixed_subblocks.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_parallel_write.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_pread_indices.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_read_dispatch.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_read_out.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_region_index.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_region_windows.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_segment_parts.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_slide_geometry.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_verification.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_write_pipeline.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_writer.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_czi_writer_shuffle.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_data_source.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_decode_releases_gil.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_deflate.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_delta_parity.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_dicom.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_dicom_encodings.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_dicom_parallel.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_dicom_slide_selection.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_dicom_wsi_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_dicomweb.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_direct_filter_outputs.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_dm.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_dm_offsets.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_dm_synthetic.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_edge_cases.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_eer.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_eer_parallel.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_eer_worker_budget.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_emd.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_encode_comprehensive.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_error_handling.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_fd_writes.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_filter_compat.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_filter_scratch.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_fits.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_fits_parallel.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_gif.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_gif_compositing.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_gzip_presized.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_hdf5_http.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_hdf5_local.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_hdf5_parallel.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_hdf5_remote.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_heif_avif_features.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_heif_multi_image.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_htj2k_compat.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_htj2k_conformance.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_http_byte_savings.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_http_prefetch.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_http_unified.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_imaris.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_incremental_byte_codecs.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_io_chunked.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_isal.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_jpeg.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_jpeg2k_compat.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_jpeg2k_region.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_jpegxr.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_jxl.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_lerc.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_lif_indexing.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_lif_native.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_live_archives.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_mozjpeg.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_mrc.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_mrc_mrcz_http.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_mrc_nifti_writers.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_n5.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_native_output_sinks.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_native_parity.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_native_source_callbacks.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_nd2_native.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_ndtiff.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_nifti.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_nrrd.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_nrrd_iteration.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_nrrd_slices.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_numpy_codec_format.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_offset_readers.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_oib_indexing.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_oib_native.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_ome_xml.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_omezarr.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_omezarr_sharded_range.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_open_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_openjph.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_optional_backend.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_owned_color_context.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_owned_image_decoders.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_parallel_jxl.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_phase4_filters.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_phase5_icc.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_phase6_codecs.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_phase7_cms.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_pipeline_budget.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_pipeline_catalog.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_pipeline_executor.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_platform_branches.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_png_row_sessions.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_png_standard.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_public_output_buffers.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_pyramid_batched_regions.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_qoi_standard.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_range_pipeline_completion.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_rcomp_truncated_input.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_read_file_into.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_reader_contract.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_reader_source_kinds.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_reader_streaming.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_reference_parity.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_rgbe.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_rgbe_toplevel.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_scaled_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_segment_encoder_binding.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_shared_io_regressions.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_sidecar_header.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_snappy.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_source_pool_lifetime.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_streaming_means_streaming.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_threading_policy.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tier1_scientific.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_codec_encode.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_fused_decode.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_http.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_native.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_parallel_decode.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_pipeline.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_predictor2_interop.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_predictor_loops.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_read_path.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_reader.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_spool.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_stack_read.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_workers.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_writer.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_writer_float_predictor.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tiff_writer_verification.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_tile_cache.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_uhdr.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_unified_api.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_url_sources.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_vendor_provenance.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_verified_encoding.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_version_consistency.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_vsi_oir.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_vsi_pyramid.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_webp_animation.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_webp_decode_options.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_webp_encode_standard.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_wrapper_streams.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_writer_contract.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_writer_pipeline_completion.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_writer_verification.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_zarr_adapters.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_zarr_region_fast_path.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_zfp_blocks.py +0 -0
- {opencodecs-0.6.0 → opencodecs-0.7.0}/tests/test_zstd_owned_output.py +0 -0
|
@@ -10,6 +10,48 @@ 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.7.0 (2026-10-03)
|
|
14
|
+
------------------
|
|
15
|
+
|
|
16
|
+
``czi_recompress`` takes ``recompress_when``, a predicate over the reader's
|
|
17
|
+
``CziSubBlockEntry``. Sub-blocks it accepts are decoded and re-encoded as
|
|
18
|
+
before; sub-blocks it rejects are carried across BYTE FOR BYTE, keeping their
|
|
19
|
+
original compression. The default stays ``None``, which re-encodes everything,
|
|
20
|
+
so existing callers are unaffected. The returned summary gains
|
|
21
|
+
``recompressed`` and ``carried`` counts.
|
|
22
|
+
|
|
23
|
+
This exists because a sub-block's compression is not a detail to be
|
|
24
|
+
normalized away. Re-encoding one that is already compressed is wasted work,
|
|
25
|
+
and re-encoding a LOSSY one is destructive: the pixels are decoded from a
|
|
26
|
+
lossy encoding and written back losslessly, so the file grows and the
|
|
27
|
+
artifacts become permanent. Measured on a 505 MB Axioscan slide scan of 481
|
|
28
|
+
JPEG XR sub-blocks:
|
|
29
|
+
|
|
30
|
+
==================================== ======== ========== ============
|
|
31
|
+
strategy time output vs source
|
|
32
|
+
==================================== ======== ========== ============
|
|
33
|
+
carry JPEG XR across (predicate) 0.36 s 489 MB 0.97x
|
|
34
|
+
re-encode everything (no predicate) 12.6 s 1309 MB 2.59x
|
|
35
|
+
==================================== ======== ========== ============
|
|
36
|
+
|
|
37
|
+
So the predicate is not a speed knob. Without it that file more than doubles
|
|
38
|
+
in size, takes 33x longer, and loses the option of ever recovering the
|
|
39
|
+
original encoding. This is what ZEISS's ``czicompress`` expresses with
|
|
40
|
+
``--strategy``, and the three strategies map directly::
|
|
41
|
+
|
|
42
|
+
uncompressed lambda e: e.compression == 0
|
|
43
|
+
uncompressed+zstd lambda e: e.compression in (0, 5, 6)
|
|
44
|
+
all None
|
|
45
|
+
|
|
46
|
+
Supporting this needed a writer that can emit a sub-block it cannot itself
|
|
47
|
+
produce. ``_build_subblock`` gained ``encoded=``, which writes the payload
|
|
48
|
+
exactly as given and records the compression code as-is, with no encode step
|
|
49
|
+
and no look at the pixels. That is the only path by which a JPEG XR sub-block
|
|
50
|
+
can reach a file this writer wrote, and it is why carrying one across cannot
|
|
51
|
+
alter it. Verification is refused on that path: nothing was encoded, so there
|
|
52
|
+
is nothing to check. ``verify=True`` therefore applies only to the sub-blocks
|
|
53
|
+
that were re-encoded.
|
|
54
|
+
|
|
13
55
|
0.6.0 (2026-10-03)
|
|
14
56
|
------------------
|
|
15
57
|
|
|
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "opencodecs"
|
|
10
|
-
version = "0.
|
|
10
|
+
version = "0.7.0"
|
|
11
11
|
description = "Streaming, network-aware image codecs for scientific imaging (prototype: JPEG XL)"
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
requires-python = ">=3.10"
|
|
@@ -74,6 +74,30 @@ class CziWriterError(RuntimeError):
|
|
|
74
74
|
"""Raised on writer state-machine violations."""
|
|
75
75
|
|
|
76
76
|
|
|
77
|
+
class _CarriedSubBlock:
|
|
78
|
+
"""A sub-block copied across unchanged, not re-encoded.
|
|
79
|
+
|
|
80
|
+
Carries the encoded payload and the compression code it was written
|
|
81
|
+
with, plus a zero-filled array of the right shape and dtype so the
|
|
82
|
+
existing header path can read shape/dtype without the pixels ever being
|
|
83
|
+
decoded. ``np.empty`` would do, but zeros make an accidental use of
|
|
84
|
+
these pixels obvious rather than random.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
__slots__ = ("payload", "compression", "dims", "pyramid_type",
|
|
88
|
+
"shape_array", "logical_shape", "pixel_type")
|
|
89
|
+
|
|
90
|
+
def __init__(self, payload, *, compression, dims, pyramid_type,
|
|
91
|
+
shape_array, logical_shape, pixel_type):
|
|
92
|
+
self.payload = payload
|
|
93
|
+
self.compression = compression
|
|
94
|
+
self.pixel_type = pixel_type
|
|
95
|
+
self.dims = dims
|
|
96
|
+
self.pyramid_type = pyramid_type
|
|
97
|
+
self.shape_array = shape_array
|
|
98
|
+
self.logical_shape = logical_shape
|
|
99
|
+
|
|
100
|
+
|
|
77
101
|
class CziCancelled(CziWriterError):
|
|
78
102
|
"""Raised when a caller's ``should_continue`` stops a rewrite.
|
|
79
103
|
|
|
@@ -339,6 +363,7 @@ def _build_subblock(
|
|
|
339
363
|
dims: tuple | None = None,
|
|
340
364
|
verification_input: list | None = None,
|
|
341
365
|
scratch=None,
|
|
366
|
+
encoded: object | None = None,
|
|
342
367
|
) -> tuple[_SubBlockSegment, dict]:
|
|
343
368
|
"""Build one ZISRAWSUBBLOCK segment as parts.
|
|
344
369
|
|
|
@@ -351,7 +376,21 @@ def _build_subblock(
|
|
|
351
376
|
check runs after this returns while the producer may already be
|
|
352
377
|
refilling ``array``. Without it nothing here outlives the call, so the
|
|
353
378
|
array's own buffer feeds the compressor or becomes the raw payload.
|
|
379
|
+
|
|
380
|
+
With ``encoded`` the payload is written exactly as given and
|
|
381
|
+
``compression_code`` is recorded as-is, with no encode step and no look
|
|
382
|
+
at the pixels. That is how a sub-block is carried across unchanged, and
|
|
383
|
+
it is the only path that can emit a compression this writer cannot
|
|
384
|
+
produce (JPEG XR, for instance). ``array`` is then used only for its
|
|
385
|
+
shape and dtype, so a zero-filled array of the right shape is enough.
|
|
386
|
+
Verification is not available on this path: there is nothing to check,
|
|
387
|
+
because nothing was encoded.
|
|
354
388
|
"""
|
|
389
|
+
if encoded is not None and verification_input is not None:
|
|
390
|
+
raise CziWriterError(
|
|
391
|
+
"czi: verification_input cannot be combined with encoded; a "
|
|
392
|
+
"carried-across sub-block is not re-encoded, so there is "
|
|
393
|
+
"nothing to verify")
|
|
355
394
|
h, w = array.shape[:2]
|
|
356
395
|
logical_h, logical_w = logical_shape
|
|
357
396
|
start_y, start_x = location
|
|
@@ -390,7 +429,10 @@ def _build_subblock(
|
|
|
390
429
|
pixels = memoryview(contiguous).cast("B")
|
|
391
430
|
keep = contiguous
|
|
392
431
|
itemsize = array.dtype.itemsize
|
|
393
|
-
if
|
|
432
|
+
if encoded is not None:
|
|
433
|
+
data = encoded
|
|
434
|
+
keep = encoded
|
|
435
|
+
elif compression_code == 0:
|
|
394
436
|
data = pixels
|
|
395
437
|
elif compression_code == 5:
|
|
396
438
|
from .codecs._zstd import encode as zstd_encode
|
|
@@ -687,6 +729,17 @@ class _CziStreamWriter(Writer):
|
|
|
687
729
|
workers = resolve_workers(None, 1 << 30, output_bytes=None, max_workers=8)
|
|
688
730
|
workers = max(1, int(workers))
|
|
689
731
|
|
|
732
|
+
def item_bytes(item):
|
|
733
|
+
"""Cost of one snapshotted item, for batching and reservation.
|
|
734
|
+
|
|
735
|
+
A carried sub-block has no array: its cost is the encoded payload
|
|
736
|
+
it already owns. Both batching sites go through here so they
|
|
737
|
+
cannot disagree about what an item weighs.
|
|
738
|
+
"""
|
|
739
|
+
if isinstance(item, _CarriedSubBlock):
|
|
740
|
+
return len(item.payload)
|
|
741
|
+
return item[0].nbytes
|
|
742
|
+
|
|
690
743
|
def snapshot(frame):
|
|
691
744
|
"""Own the frame's pixels before the producer can touch them.
|
|
692
745
|
|
|
@@ -695,6 +748,10 @@ class _CziStreamWriter(Writer):
|
|
|
695
748
|
it is a down-scaled level. Those forms are what make a faithful
|
|
696
749
|
re-encode possible on this path as well as on ``write_frame``.
|
|
697
750
|
"""
|
|
751
|
+
if isinstance(frame, _CarriedSubBlock):
|
|
752
|
+
# Nothing to snapshot: the payload is already bytes we own,
|
|
753
|
+
# and the pixels are never looked at.
|
|
754
|
+
return frame
|
|
698
755
|
dims = override_pyramid = None
|
|
699
756
|
if isinstance(frame, tuple):
|
|
700
757
|
if len(frame) == 2:
|
|
@@ -728,7 +785,7 @@ class _CziStreamWriter(Writer):
|
|
|
728
785
|
batch, batch_bytes = [], 0
|
|
729
786
|
for frame in frames:
|
|
730
787
|
item = snapshot(frame)
|
|
731
|
-
n = item
|
|
788
|
+
n = item_bytes(item)
|
|
732
789
|
if batch and batch_bytes + n > batch_limit:
|
|
733
790
|
yield batch
|
|
734
791
|
batch, batch_bytes = [], 0
|
|
@@ -738,7 +795,7 @@ class _CziStreamWriter(Writer):
|
|
|
738
795
|
yield batch
|
|
739
796
|
|
|
740
797
|
def size(batch):
|
|
741
|
-
n = sum(item
|
|
798
|
+
n = sum(item_bytes(item) for item in batch)
|
|
742
799
|
# Snapshot + encoded output (bounded by the input for these
|
|
743
800
|
# codecs) + decoded verification result and comparison scratch.
|
|
744
801
|
return 2 * n + (verification_reservation(n) if verify else 0)
|
|
@@ -746,7 +803,19 @@ class _CziStreamWriter(Writer):
|
|
|
746
803
|
def encode(batch):
|
|
747
804
|
out = []
|
|
748
805
|
scratch = _worker_scratch()
|
|
749
|
-
for
|
|
806
|
+
for item in batch:
|
|
807
|
+
if isinstance(item, _CarriedSubBlock):
|
|
808
|
+
segment, entry = _build_subblock(
|
|
809
|
+
item.shape_array,
|
|
810
|
+
pixel_type=item.pixel_type,
|
|
811
|
+
compression_code=item.compression, hilo=self._hilo,
|
|
812
|
+
file_position=0, logical_shape=item.logical_shape,
|
|
813
|
+
pyramid_type=item.pyramid_type, dims=item.dims,
|
|
814
|
+
verification_input=None, scratch=None,
|
|
815
|
+
encoded=item.payload)
|
|
816
|
+
out.append((segment, entry))
|
|
817
|
+
continue
|
|
818
|
+
pixels, logical_shape, pyramid_type, dims = item
|
|
750
819
|
captured = [] if verify else None
|
|
751
820
|
segment, entry = _build_subblock(
|
|
752
821
|
pixels, pixel_type=_DTYPE_TO_PIXELTYPE[pixels.dtype],
|
|
@@ -992,7 +1061,8 @@ __all__ = ["CziWriter", "CziPyramidWriter", "CziWriterError"]
|
|
|
992
1061
|
def czi_recompress(src, dst, *, compression: str = "zstdhdr", hilo: bool = True,
|
|
993
1062
|
workers=None, verify: bool = False,
|
|
994
1063
|
background_encode: bool = False,
|
|
995
|
-
should_continue=None
|
|
1064
|
+
should_continue=None,
|
|
1065
|
+
recompress_when=None) -> dict:
|
|
996
1066
|
"""Rewrite a CZI with different compression, keeping the container.
|
|
997
1067
|
|
|
998
1068
|
Every sub-block keeps its dimension coordinates, its scene and mosaic
|
|
@@ -1016,8 +1086,30 @@ def czi_recompress(src, dst, *, compression: str = "zstdhdr", hilo: bool = True,
|
|
|
1016
1086
|
know which. Encodes already dispatched still finish, so cancellation
|
|
1017
1087
|
takes effect within roughly ``workers`` sub-blocks rather than instantly.
|
|
1018
1088
|
|
|
1019
|
-
|
|
1020
|
-
|
|
1089
|
+
``recompress_when`` is an optional predicate over the reader's
|
|
1090
|
+
``CziSubBlockEntry``. Sub-blocks it accepts are decoded and re-encoded;
|
|
1091
|
+
sub-blocks it rejects are carried across BYTE FOR BYTE, keeping their
|
|
1092
|
+
original compression. Default ``None`` re-encodes everything, which is
|
|
1093
|
+
what earlier versions did.
|
|
1094
|
+
|
|
1095
|
+
This is what makes the selective strategies of ZEISS's ``czicompress``
|
|
1096
|
+
expressible, and the reason they exist: re-encoding an already-compressed
|
|
1097
|
+
sub-block is at best wasted work, and for a lossy one it is destructive.
|
|
1098
|
+
A JPEG XR sub-block decoded and re-encoded as lossless zstdhdr grows,
|
|
1099
|
+
and bakes the lossy artifacts in permanently. Carrying it across cannot
|
|
1100
|
+
do that.
|
|
1101
|
+
|
|
1102
|
+
uncompressed only lambda e: e.compression == 0
|
|
1103
|
+
uncompressed+zstd lambda e: e.compression in (0, 5, 6)
|
|
1104
|
+
everything None
|
|
1105
|
+
|
|
1106
|
+
``verify=True`` applies only to the sub-blocks that were re-encoded; a
|
|
1107
|
+
carried-across payload is unchanged by definition, so there is nothing
|
|
1108
|
+
to check.
|
|
1109
|
+
|
|
1110
|
+
Returns a summary dict: sub-block count, input and output sizes, the
|
|
1111
|
+
compression that was applied, and how many sub-blocks were re-encoded
|
|
1112
|
+
versus carried across.
|
|
1021
1113
|
"""
|
|
1022
1114
|
import os
|
|
1023
1115
|
|
|
@@ -1029,6 +1121,8 @@ def czi_recompress(src, dst, *, compression: str = "zstdhdr", hilo: bool = True,
|
|
|
1029
1121
|
raise CziWriterError(f"czi: {src} has no sub-blocks to recompress")
|
|
1030
1122
|
metadata = reader.metadata_bytes or b"<Metadata/>"
|
|
1031
1123
|
|
|
1124
|
+
counts = {"recompressed": 0, "carried": 0}
|
|
1125
|
+
|
|
1032
1126
|
def frames():
|
|
1033
1127
|
# One sub-block at a time: a slide scan does not fit in memory,
|
|
1034
1128
|
# and write_many only needs the next frame, not all of them.
|
|
@@ -1038,7 +1132,30 @@ def czi_recompress(src, dst, *, compression: str = "zstdhdr", hilo: bool = True,
|
|
|
1038
1132
|
f"czi: recompress of {src} cancelled after "
|
|
1039
1133
|
f"{i} of {n} sub-blocks")
|
|
1040
1134
|
entry = reader.entries[i]
|
|
1041
|
-
|
|
1135
|
+
if recompress_when is None or recompress_when(entry):
|
|
1136
|
+
counts["recompressed"] += 1
|
|
1137
|
+
yield reader[i], subblock_dims(entry), entry.pyramid_type
|
|
1138
|
+
else:
|
|
1139
|
+
# Carried across: the encoded bytes are copied straight
|
|
1140
|
+
# from the source and the original compression is kept,
|
|
1141
|
+
# so the pixels are never decoded and cannot change.
|
|
1142
|
+
counts["carried"] += 1
|
|
1143
|
+
d = subblock_dims(entry)
|
|
1144
|
+
axes = {name.rstrip(b"\x00"): (size, stored)
|
|
1145
|
+
for name, _start, size, _co, stored in d}
|
|
1146
|
+
log_h, st_h = axes[b"Y"]
|
|
1147
|
+
log_w, st_w = axes[b"X"]
|
|
1148
|
+
with reader._payload(entry) as view:
|
|
1149
|
+
# Copy: the reader hands back a buffer it reuses, so
|
|
1150
|
+
# a borrowed view would be overwritten by the next
|
|
1151
|
+
# sub-block before the writer emits this one.
|
|
1152
|
+
payload = bytes(view)
|
|
1153
|
+
yield _CarriedSubBlock(
|
|
1154
|
+
payload, compression=entry.compression,
|
|
1155
|
+
dims=d, pyramid_type=entry.pyramid_type,
|
|
1156
|
+
shape_array=np.zeros((st_h, st_w), entry.dtype),
|
|
1157
|
+
logical_shape=(log_h, log_w),
|
|
1158
|
+
pixel_type=entry.pixel_type)
|
|
1042
1159
|
|
|
1043
1160
|
try:
|
|
1044
1161
|
with CziWriter(str(dst), compression=compression, hilo=hilo,
|
|
@@ -1061,4 +1178,6 @@ def czi_recompress(src, dst, *, compression: str = "zstdhdr", hilo: bool = True,
|
|
|
1061
1178
|
"src_bytes": os.path.getsize(src),
|
|
1062
1179
|
"dst_bytes": os.path.getsize(dst),
|
|
1063
1180
|
"compression": compression,
|
|
1181
|
+
"recompressed": counts["recompressed"],
|
|
1182
|
+
"carried": counts["carried"],
|
|
1064
1183
|
}
|
|
@@ -351,3 +351,112 @@ def test_a_failing_predicate_also_leaves_no_output(tmp_path):
|
|
|
351
351
|
with pytest.raises(ValueError):
|
|
352
352
|
czi_recompress(src, dst, workers=PARTIAL_WORKERS, should_continue=boom)
|
|
353
353
|
assert not dst.exists()
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
# ------------------------------------------- selective recompression
|
|
357
|
+
# `recompress_when` exists so the selective strategies of ZEISS's czicompress
|
|
358
|
+
# are expressible. The point is NOT speed: re-encoding an already-compressed
|
|
359
|
+
# sub-block is wasted work, and for a LOSSY one it is destructive, because a
|
|
360
|
+
# JPEG XR block decoded and re-encoded as lossless zstdhdr grows and bakes the
|
|
361
|
+
# lossy artifacts in permanently.
|
|
362
|
+
#
|
|
363
|
+
# Every assertion here is on the OUTPUT'S COMPRESSION CODES, not just its
|
|
364
|
+
# pixels. A pass-through that quietly re-encoded would still produce a
|
|
365
|
+
# readable file with identical pixels, so comparing arrays cannot catch it.
|
|
366
|
+
|
|
367
|
+
def _mixed_src(tmp_path):
|
|
368
|
+
"""Two uncompressed sub-blocks and two already-zstd ones."""
|
|
369
|
+
raw = [(_tile(64, 64, 200 + i), (0, i * 64), [(b"C", i)]) for i in range(2)]
|
|
370
|
+
src_u = tmp_path / "u.czi"
|
|
371
|
+
src_u.write_bytes(mosaic_czi_bytes(raw, compression=0))
|
|
372
|
+
pre = tmp_path / "pre.czi"
|
|
373
|
+
czi_recompress(src_u, pre, compression="zstdhdr")
|
|
374
|
+
return src_u, pre
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
def _codes(path):
|
|
378
|
+
with CziReader(str(path)) as r:
|
|
379
|
+
return [e.compression for e in r.entries]
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def test_default_still_recompresses_everything(tmp_path):
|
|
383
|
+
src, _ = _mixed_src(tmp_path)
|
|
384
|
+
dst = tmp_path / "d.czi"
|
|
385
|
+
info = czi_recompress(src, dst, compression="zstdhdr")
|
|
386
|
+
assert info["recompressed"] == 2 and info["carried"] == 0
|
|
387
|
+
assert set(_codes(dst)) == {6}
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
def test_uncompressed_only_leaves_compressed_blocks_alone(tmp_path):
|
|
391
|
+
"""The czicompress default: only code 0 is touched."""
|
|
392
|
+
_, pre = _mixed_src(tmp_path)
|
|
393
|
+
assert set(_codes(pre)) == {6}, "fixture is not already compressed"
|
|
394
|
+
dst = tmp_path / "d.czi"
|
|
395
|
+
info = czi_recompress(pre, dst, compression="zstdhdr",
|
|
396
|
+
recompress_when=lambda e: e.compression == 0)
|
|
397
|
+
assert info["recompressed"] == 0, "re-encoded a block it was told to skip"
|
|
398
|
+
assert info["carried"] == 2
|
|
399
|
+
assert _codes(dst) == _codes(pre)
|
|
400
|
+
_assert_faithful(pre, dst)
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
def test_carried_payload_is_byte_identical(tmp_path):
|
|
404
|
+
"""Carried means copied, so the encoded bytes must match exactly."""
|
|
405
|
+
_, pre = _mixed_src(tmp_path)
|
|
406
|
+
dst = tmp_path / "d.czi"
|
|
407
|
+
czi_recompress(pre, dst, compression="none",
|
|
408
|
+
recompress_when=lambda e: False)
|
|
409
|
+
with CziReader(str(pre)) as a, CziReader(str(dst)) as b:
|
|
410
|
+
for ea, eb in zip(a.entries, b.entries):
|
|
411
|
+
with a._payload(ea) as pa, b._payload(eb) as pb:
|
|
412
|
+
assert bytes(pa) == bytes(pb), "carried payload was altered"
|
|
413
|
+
assert ea.compression == eb.compression
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def test_carried_blocks_keep_their_code_while_others_change(tmp_path):
|
|
417
|
+
"""A mixed file: some blocks re-encoded, some carried, in one pass."""
|
|
418
|
+
_, pre = _mixed_src(tmp_path)
|
|
419
|
+
extra = [(_tile(64, 64, 300 + i), (0, (i + 2) * 64), [(b"C", i + 2)])
|
|
420
|
+
for i in range(2)]
|
|
421
|
+
mixed = tmp_path / "mixed.czi"
|
|
422
|
+
mixed.write_bytes(mosaic_czi_bytes(extra, compression=0))
|
|
423
|
+
dst = tmp_path / "d.czi"
|
|
424
|
+
info = czi_recompress(mixed, dst, compression="zstdhdr",
|
|
425
|
+
recompress_when=lambda e: e.compression == 0)
|
|
426
|
+
assert info["recompressed"] == 2 and info["carried"] == 0
|
|
427
|
+
assert set(_codes(dst)) == {6}
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
def test_predicate_sees_a_real_entry(tmp_path):
|
|
431
|
+
"""The predicate gets the reader's entry, not an opaque index."""
|
|
432
|
+
src, _ = _mixed_src(tmp_path)
|
|
433
|
+
seen = []
|
|
434
|
+
|
|
435
|
+
def pred(e):
|
|
436
|
+
seen.append((e.compression, e.pixel_type, e.pyramid_type))
|
|
437
|
+
return True
|
|
438
|
+
|
|
439
|
+
czi_recompress(src, tmp_path / "d.czi", recompress_when=pred)
|
|
440
|
+
assert len(seen) == 2
|
|
441
|
+
assert all(c == 0 for c, _p, _y in seen)
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
def test_verify_applies_only_to_recompressed_blocks(tmp_path):
|
|
445
|
+
"""verify=True must not choke on a carried block it never encoded."""
|
|
446
|
+
_, pre = _mixed_src(tmp_path)
|
|
447
|
+
dst = tmp_path / "d.czi"
|
|
448
|
+
info = czi_recompress(pre, dst, compression="zstdhdr", verify=True,
|
|
449
|
+
recompress_when=lambda e: e.compression == 0)
|
|
450
|
+
assert info["carried"] == 2
|
|
451
|
+
_assert_faithful(pre, dst)
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
def test_encoded_and_verification_input_are_refused():
|
|
455
|
+
"""Verifying a carried block is meaningless; the writer says so."""
|
|
456
|
+
import numpy as np
|
|
457
|
+
from opencodecs._czi_writer import _build_subblock
|
|
458
|
+
with pytest.raises(CziWriterError, match="nothing to verify"):
|
|
459
|
+
_build_subblock(np.zeros((4, 4), "uint16"), pixel_type=1,
|
|
460
|
+
compression_code=0, hilo=False, file_position=0,
|
|
461
|
+
logical_shape=(4, 4), verification_input=[],
|
|
462
|
+
encoded=b"x")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|