Skip to main content

opencodecs

PyPI Tests Build wheels

Native, parallel, cloud-aware codecs for scientific imaging. One unified Codec / Reader / Writer API across compression streams, single images, multi-frame stacks, and chunked containers — with HTTP range-fetch and per-chunk parallelism wired in at the bottom of the stack, not bolted on.

Built for fast modern storage (NVMe, 10 G NAS, S3) where the bottleneck is codec dispatch and per-tile parallelism, not raw I/O bandwidth. Native implementations of every codec — no runtime delegation to imagecodecs — though we use its excellent test suite as a parity reference.

pip install opencodecs
import opencodecs as oc

# 1. Look at any scientific image file
arr = oc.read("scan.czi")              # auto-detect by extension
arr = oc.read("photo.jxl")
arr = oc.read(blob)                    # auto-detect by magic bytes

# 2. Write with the right codec for the data
oc.write("out.jxl", arr, lossless=True)
oc.write("out.zst", b"...payload...", level=10)

# 3. Stream multi-frame / chunked formats
with oc.get_codec("czi").open(path) as r:
    print(r.shape, r.dtype, r.n_frames)
    for tile in r:                     # iter_frames
        ...
    tile5 = r[5]                       # random access

# 4. Fetch tiles of a remote pyramidal TIFF over HTTPS by range request
with oc.open_pyramid("https://example.com/slide.svs") as p:
    region = p.read_region(level=2, y=(1024, 2048), x=(1024, 2048))
    # → 2-3 HTTP Range requests, not a full slide download

# Discovery
oc.list_codecs()                       # capability table
oc.has_codec("avif")

Why opencodecs

Need What you get
Decode regions of cloud-hosted TIFF/Zarr/HDF5 without downloading the whole file Native HTTPDataSource with range-coalescing + adaptive read-ahead, wired into the TIFF/NDTiff/HDF5/Zarr/FITS pyramid readers
Per-chunk parallel decode of CZI/OME-TIFF/NDTiff stacks Built-in ThreadPoolExecutor orchestration with nogil-released codec calls; 3–10× over single-threaded reference readers on large stacks
Modern codec coverage (JPEG XL, AVIF, HEIF, JPEG-LS, Brunsli, Ultra HDR, OME-Zarr v3 sharded) All shipped, all with native bindings — no pip install ten-other-packages
Tier-1 scientific compressors (LERC, ZFP, SZ3, SPERR, pcodec, bitshuffle, blosc2, libaec) All shipped, source-built with -O3 + LTO + hidden-visibility for Pareto wins over distro builds
Lossless drop-in replacement for imagecodecs tifffile_patch opt-in shim reroutes tifffile's codec dispatch through opencodecs without changing your tifffile code

Codec capability matrix

All codecs below are native implementations linking against system or vendored C libraries. Build skips cleanly when an optional system library is missing — see INSTALL.md.

Compression (bytes → bytes)

Codec Encode Decode Backing library Extension
zstd system libzstd .zst
lz4 system liblz4 (frame) .lz4
brotli system libbrotli .br
blosc2 source-built c-blosc2 2.23 .b2
deflate libdeflate / zlib-ng / zlib (auto-selected at build time) .zlib
gzip stdlib gzip .gz
none identity (filter-chain placeholder)
bz2 stdlib bz2 .bz2
lzma stdlib lzma .xz
snappy system snappy .sz
bitshuffle vendored bitshuffle (filter)

bitshuffle is a filter, not a stand-alone compressor: bit-level transpose that radically improves LZ77 ratios on typed numerical data. Output size equals input size; pair with zstd / lz4. Aliases: bshuf.

deflate aliases: zlib, zlibng. Pass backend="isal" to opt into Intel ISA-L's igzip (~4× faster encode on x86_64; opt-in because output is ~19% bigger). The default backend is auto-selected at build time: libdeflate when present (fastest at default level), else zlib-ng-compat, else the stdlib zlib.

Scientific / numerical-array codecs (ndarray ↔ bytes, self-describing)

These four codecs target typed multidimensional arrays rather than images or raw bytes. The encoded blob carries shape and dtype in its header, so decode(blob) reconstructs the full ndarray without out-of-band metadata.

Codec Encode Decode Lossless Lossy modes Backing library Extension
b2nd system c-blosc2 (NDim API) .b2nd
aec system libaec (CCSDS 121.0-B-2) .aec
lerc max_z_error system liblerc (Esri) .lerc
zfp ✓ (reversible) rate / precision / accuracy system libzfp .zfp

In fixed-rate mode zfp blocks are individually addressable, so decode_block(data, n) reads one 4x4x4 block without touching the rest (0.0010 ms against 0.209 ms for the whole stream) and a full decode splits the block grid across threads (110 ms → 30 ms on a 67 MB volume). The variable-rate modes have no computable block position and fall back to a whole-stream decode.

| sz3 | ✓ | ✓ | — | abs / rel / psnr / norm | source-built SZ3 | .sz3 | | pcodec | ✓ | ✓ | ✓ | — | source-built pcodec (Rust) | .pco |

Quick guidance:

  • pcodec — modern lossless numerical compressor; often beats zstd by 1.5–3× on float / int arrays without a pre-filter.
  • b2nd — c-blosc2's multidim layer with shuffle/bitshuffle filters built in; great when you already use blosc2 elsewhere.
  • aec — entropy coder used by NetCDF-4 SZIP; lossless integers.
  • lerc — fast (lossy or lossless) raster codec used in Cloud-Optimized GeoTIFF, Esri MRF.
  • zfp — fast 1D-4D float / int compression with multiple lossy modes (predictable size, accuracy, or precision).
  • sz3 — error-bounded prediction-based scientific compressor; often beats zfp at the same error budget on simulation snapshots. Float only (the SZ3 v3 C API doesn't dispatch integer types).

Single-image codecs

Codec Encode Decode Color Backing library Extension
qoi RGB / RGBA vendored qoi.h .qoi
bmp gray / RGB / RGBA pure Python+numpy .bmp, .dib
gif 8-bit palette → RGB / RGBA; animated (decodes to a frame stack); encode takes palette indices system giflib + vendored LZW decoder .gif
png gray / RGB / RGBA, 8/16-bit vendored libspng + libdeflate .png
jpeg gray / RGB libjpeg-turbo (TJ v3) .jpg, .jpeg
mozjpeg gray / RGB, 8/12-bit system mozjpeg (TJ v2) .jpg
webp RGB / RGBA, lossy + lossless; animated (decodes to a frame stack, like gif) system libwebp (+ libwebpdemux) .webp
jpeg2k gray / RGB / RGBA, 8/16-bit, lossless + lossy OpenJPEG .jp2, .j2k, .jpx, .jpc
htj2k gray / RGB / RGBA, 8/16-bit, lossless + lossy OpenJPH 0.31.0 (source-built) .j2c
jpegls gray / RGB / RGBA, 2-16 bit, lossless + near-lossless system CharLS .jls
avif RGB / RGBA, lossy + lossless (YUV444+identity); image sequences (decode to a frame stack, like gif) libavif .avif
heif RGB / RGBA, lossless + lossy (HEVC); every top-level image, not just the primary libheif (+ aomenc) .heif, .heic
jxl gray / RGB / RGBA, P3, HDR, multi-frame vendored libjxl 0.11.2 .jxl
bcdec BC1-7 / DXT / BPTC GPU textures; band decode + threaded vendored bcdec.h .dds
rgbe float32 RGB HDR (Radiance) vendored rgbe.c .hdr
ultrahdr float16 / uint8 / uint16 RGBA HDR + SDR system libultrahdr 1.4.x .jpg (gainmap)

htj2k is JPEG-2000 Part 15 (High-Throughput) — same DWT front end as classic JPEG-2000 but ~10-20× faster entropy coding. Used by modern DICOM and remote-sensing pipelines.

jpegls (CharLS) is the lossless / near-lossless predictive JPEG variant standardized as ISO/IEC 14495-1 — the dominant codec in medical-imaging DICOM workflows.

mozjpeg is Mozilla's libjpeg-turbo fork; ~10-15% smaller files than libjpeg-turbo at the same quality. Built only when MozJPEG is on the system (keg-only on Homebrew so it doesn't collide with plain libjpeg-turbo).

rgbe is the canonical Radiance HDR format — float32 RGB shared- exponent encoding for high-dynamic-range photography and physically- based rendering output. ultrahdr is the ISO 21496 gainmap-JPEG format — Android Camera's default since A14 and what iOS 18+ reads natively. Decode dtype controls the output: float16 returns linear BT.2100 HDR; uint8 returns the SDR-tonemapped base JPEG.

Multi-frame / chunked formats

Codec Read Write Container Notes
jxl ISO BMFF (frame index) Streaming + parallel multi-frame decode
czi Zeiss ZISRAW mmap + parallel zstd; metadata accessor; parallel bulk HTTP fetch via CziReader.from_http(max_workers=N)
tiff TIFF 6.0 + BigTIFF Native reader + writer; tiled or strip; parallel encode; LZW encode; streaming write to unseekable sinks; EER cryo-EM dispatch
ndtiff Micro-Manager / Pycro-Manager NDTiff Streaming writer; os.writev hot path; cross-platform (POSIX + Windows-NTFS-safe pre-allocation)
hdf5 HDF5 Wraps h5py.Dataset. Remote HDF5 via open_remote_hdf5(url) — slices stream chunks over HTTP Range with one-shot parallel prefetch
eer Thermo Fisher EER (cryo-EM event-list) Native bitstream decoder + TIFF compression-tag dispatch (codes 65000-65002)
dicomweb WADO-RS HTTP frame retrieval Multipart/related parser; transfer-syntax dispatch through opencodecs's codec layer (JPEG-LS / HTJ2K / JPEG-2000 / RLE / raw)
fits FITS (astronomy) Multi-HDU walk; BITPIX 8/16/32/64/-32/-64; BZERO unsigned-int trick; compressed images (RICE_1, GZIP_1, GZIP_2, HCOMPRESS_1, NOCOMPRESS) with per-tile ZSCALE/ZZERO quantization. HTTP-range friendly — opening a 50 GB cube reads kilobytes.
mrc MRC2014 / CCP4 map (cryo-EM volumes, EMDB deposits) Read and write. MODE 0/1/2/6/12 plus complex; both byte orders; extended header; plane(i) for one z-section; canonical=True reorients a permuted MAPC/MAPR/MAPS to (z, y, x). MRCZ (blosc-compressed voxels) decodes too, and an http(s) URL reads through range requests: opening a 4 MB volume moves 64 KB.
nifti NIfTI-1 / NIfTI-2 (neuroimaging volumes) Read both, write NIfTI-1. Both header versions and byte orders; transparent gzip, since almost every NIfTI in the wild is .nii.gz; scl_slope/scl_inter applied when they change anything and skipped when they do not, so an unscaled integer volume stays integer.
n5 N5 (Janelia / Saalfeld chunked arrays) Read-only, via opencodecs.N5Array. Local directory, http(s) URL or a fetch callable, so an N5 on S3 reads like one on disk. raw/gzip/bzip2/xz plus blosc, lz4 and zstd through our own codecs; column-major dimensions reversed to C order; big-endian per-block headers; absent blocks read as zeros the way sparse datasets expect.
imaris Imaris .ims (Bitplane, HDF5-based) Read-only, via opencodecs.ImarisReader and open_pyramid. Resolution pyramid, timepoints and channels; crops the padding Imaris leaves in the stored array using each level's own ImageSize attributes; decodes the character-array attribute convention. Needs h5py.
dicom DICOM files (.dcm) Read-only, via opencodecs.DicomFile. Explicit and implicit VR, big-endian, deflated; native and encapsulated Pixel Data; multi-frame. Frames route through the same transfer-syntax dispatch DICOMweb uses, so JPEG, JPEG-LS, JPEG 2000, HTJ2K and RLE all work. Reconciles a codestream's signedness with Pixel Representation. Frames are indexed by the Basic Offset Table and decode across threads. VL Whole Slide Microscopy series read as pyramids through open_pyramid(dir, format="dicom").
nrrd NRRD / NHDR (3D Slicer, ITK) Read-only, via opencodecs.NrrdFile. raw, gzip, bzip2, ascii and hex encodings; both byte orders; detached .nhdr + .raw pairs; sizes is fastest-axis-first so the numpy shape is reversed.
dm Gatan Digital Micrograph (.dm3, .dm4) Read-only, via opencodecs.DmFile. Walks the tag tree; big-endian structure with little-endian samples; dm4's 64-bit counts; 2-D and 3-D stacks. The embedded thumbnail is identified from the file's own Thumbnails group and skipped, so image 0 is the acquisition.
vsi Olympus / Evident CellSens (.vsi + .ets) Read-only. The .vsi is an index; the pixels are in sibling _NAME_/stackN/frame_t*.ets files, each holding one image as a tiled JPEG pyramid. open_pyramid decodes only the tiles a region covers: a 256x256 window of an 8022x9367 slide moves 0.5 MB of a 32.6 MB file over HTTP. Separate stacks are separate images, so a multi-stack .vsi needs stack=. Clean-room parser, no GPL reader consulted.
emd EMD (Berkeley/NCEM and Thermo Velox) Read-only, via opencodecs.EmdFile. Two conventions share the extension, so the schema is detected from the structure rather than the filename. Berkeley dimN axis vectors are returned alongside the array; Velox JSON metadata is decoded. Arrays come back in stored order, so hyperspy's are the transpose.

TIFF writer specifics

from opencodecs._tiff_writer import TiffWriter

# Classic TIFF (<4 GiB)
with TiffWriter("out.tif") as w:
    w.write_page(arr, tile=(256, 256), compression="zstd")

# BigTIFF (>4 GiB; magic=43, 64-bit offsets)
with TiffWriter("huge.tif", bigtiff=True) as w:
    w.write_pyramid(levels, compression="zstd", subifds=True)

# COG-style streaming to an unseekable sink (pipe, S3 multipart, HTTP body)
with TiffWriter(sink, streaming=True) as w:
    w.write_stream(pages, total_pages=N, tile=(256, 256), compression="zstd")

Supported encode-side compressions: none, deflate (libdeflate / zlib-ng / zlib auto-detect), zstd, LZW, JPEG, JPEG2000, WebP, JXL, LERC. Horizontal predictor on byte-stream codecs.

OME-TIFF metadata

from opencodecs._ome_xml import write_ome_tiff, Channel

write_ome_tiff(
    "scan.ome.tif", arr_5d, axes="TCZYX",
    physical_size_um=(0.108, 0.108, 0.5),
    channels=[Channel(name="DAPI", emission_wavelength_nm=460),
              Channel(name="GFP",  emission_wavelength_nm=520)],
)

Round-trips through tifffile / Bio-Formats / QuPath. For schema elements outside the 80%-case subset, hand-author OME-XML and pass via TiffWriter's metadata= kwarg.

Remote HDF5

from opencodecs._hdf5_http import open_remote_hdf5, prefetch_hdf5_chunks

with open_remote_hdf5("https://bucket.s3.amazonaws.com/big.h5") as f:
    prefetch_hdf5_chunks(f["img"], np.s_[:1024, :1024])  # 1 syscall, N HTTP
    arr = f["img"][:1024, :1024]                          # all from cache

czi decodes types 0 (uncompressed) and 6 (ZSTDHDR) — the entire modern Zen archive. JPEG-XR sub-blocks (rare in 2022+ output) raise NotImplementedError. The reader exposes metadata_bytes and metadata_xml as lazy zero-copy accessors.

zarr v3 codecs

opencodecs._zarr_codecs registers our compressors as zarr v3 BytesBytesCodecs:

import zarr
from opencodecs._zarr_codecs import OcZstd, OcLz4, OcBlosc2, OcBrotli, OcDeflate

z = zarr.create_array(
    store=..., shape=..., dtype=..., chunks=...,
    compressors=[OcZstd(level=10)],
    zarr_format=3,
)

Performance

Headline numbers from the latest bench run (bench/run_benchmarks.py --fast, macOS M1 Ultra, vs imagecodecs / tifffile / ndstorage):

Workload opencodecs reference ratio
tiff_random_tile_read 0.70 ms 7.71 ms (tifffile) 11×
tiff_pyramid_crop_from_fullres 0.47 ms 8.60 ms 18×
ndtiff_index_parse_synthetic_10k 4.61 ms 28.0 ms (ndstorage) 6.1×
h2h_jxl_4mp_rgb (encode) 130 ms 3153 ms (imagecodecs) 24×
h2h_blosc2_10mb 4.63 ms 54.8 ms 12×
h2h_deflate_10mb (encode) 109 ms 296 ms 2.7×
h2h_png_4mp_rgb (encode) 142 ms 281 ms 2.0×
h2h_png_kodak_photo (encode) 19 ms 58 ms 3.1×
h2h_png_filterbound_u16 (encode) 2.0 ms 3.7 ms 1.8×
tiff_write_1gb 89 ms 91 ms parity, +14% on Windows
ndtiff_write_1gb (raw 800 MB) 159 ms 154 ms parity (1.04× on macOS, 2.4× on Windows after NTFS-friendly pre-alloc)

The PNG encode wins above stack two independent improvements: the libdeflate IDAT accumulator (already shipped) collapses zlib's per-scanline deflate() loop into a single one-shot call, and a per-filter split of libspng's filter_sum hot path lets the compiler autovectorize each branch into NEON/SSE — together they make every PNG-encode workload 1.5–3.1× faster than imagecodecs.

Remote-fetch workloads benefit from read_many (one batched HTTP fan-out + Range coalescing) — on a loopback Range-supporting server, 1024-chunk HDF5 slices land in 7 HTTP requests instead of 1010 (a ~50× request-count reduction; on real-network RTT this translates to 8× wall-clock).

Scientific microscopy CZI (66 MB, 14 sub-blocks of 2000×2000 uint16, ZSTDHDR), single-file warm cache:

Reader Mac M3 Threadripper x86_64
czifile (Python ref) 148 ms 414 ms
aicspylibczi (C++) 17 ms 140 ms
opencodecs 15 ms 46 ms

See docs/io_patterns.md for the lessons learned about coalesced I/O, mmap vs pread, persistent thread pools, and where parallelism actually pays off. The deflate path is libdeflate when available → zlib-ng-compat → stdlib zlib, auto-detected at build time.

Public API

Top-level dispatch

oc.read(src, *, format=None, **opts) -> ndarray | bytes
oc.write(dest, data, *, format=None, **opts) -> bytes | None
oc.codec_for_path(path) -> Codec | None
oc.codec_for_bytes(head) -> Codec | None

src and dest accept paths, file-like objects, bytes, and memoryview / mmap slices (zero-copy through the codec).

Any of these accept an http(s) URL wherever they accept a path. Formats that can reach storage by offset fetch only the bytes they need by Range request; the whole-codestream formats fetch once, which is the honest thing when every byte is needed anyway.

Which is which is not a list to keep in your head, or in this README where it would rot: capabilities.toml records it per codec and ci/check_capabilities.py verify re-derives every entry from the code on each CI run, so it cannot quietly stop being true.

import tomllib
caps = tomllib.load(open("capabilities.toml", "rb"))["codec"]
[c["name"] for c in caps if c["http"]]      # range-backed over HTTP
[c["name"] for c in caps if c["pyramid"]]   # codecs with a pyramid reader

The manifest covers the codec registry, so the reader-only backends (Imaris, OME-Zarr, NDTiff, N5) are not in it; they are listed in the tables above and reached through open_pyramid / their own classes.

Codec registry

oc.list_codecs() -> list[Codec]
oc.has_codec(name_or_alias) -> bool
oc.get_codec(name_or_alias) -> Codec

Codec interface

Each codec exposes:

codec.name            # "czi"
codec.file_extensions # (".czi",)
codec.has_native      # True for everything we ship
codec.can_encode / codec.can_decode
codec.multi_frame / codec.chunked / codec.streaming_decode / codec.parallel_decode
codec.supported_dtypes / codec.supports_color

codec.signature(head_bytes) -> bool
codec.encode(data, *, dest=None, **opts) -> bytes | None
codec.decode(src, **opts) -> ndarray | bytes
codec.open(src, **opts) -> Reader        # multi-frame / chunked

Reader interface (multi-frame / chunked)

reader.shape       # (n_frames, *frame_shape)
reader.dtype
reader.n_frames
reader.is_chunked  # True if [idx] random access works
reader.iter_frames()
reader.read()      # full eager decode
reader[idx]        # random access (chunked formats only)

CZI reader additionally exposes:

reader.entries                  # list[CziSubBlockEntry] — sub-block metadata
reader.metadata_bytes           # raw UTF-8 bytes (lazy + cached)
reader.metadata_xml             # decoded str (lazy + cached)
reader.subblock_metadata_bytes(i)

HDF5 reader additionally exposes:

reader.dataset_names            # all numeric datasets in the file
reader.select(name)             # switch to a different dataset

Streaming-reader examples

1. Fetch a region of a remote Aperio whole-slide TIFF

import opencodecs as oc

# Pyramidal SVS (Aperio) hosted on S3 / any HTTPS endpoint with Range support.
with oc.open_pyramid("https://example.com/slide.svs") as p:
    print(p.levels)               # [(80000, 60000, 3), (40000, 30000, 3), ...]
    region = p.read_region(level=2, y=(1024, 3072), x=(2048, 4096))
    # Total HTTP traffic: ~6 Range requests covering only the tiles
    # that intersect this 2048×2048 bbox — typically 200 KB–2 MB,
    # not the 4 GB whole slide.

The pyramid reader auto-detects the best level for the requested region, fetches only the intersecting TIFF tiles via HTTP Range, and assembles the output in-memory. Works the same on local files, NFS, SMB, S3, or any range-capable HTTP server.

open_pyramid dispatches on extension for TIFF/COG/SVS, OME-Zarr, CZI, Imaris, JPEG, JPEG 2000 and HTJ2K, and two whole-slide formats whose pyramid is not one file:

# Olympus / Evident CellSens. The .vsi is an index; the tiles live in
# a sibling _NAME_/stackN/frame_t*.ets. Only the tiles the box covers
# are decoded.
with oc.open_pyramid("slide.vsi") as p:
    p.shapes            # ((9367, 8022, 3), (4684, 4011, 3), ... 6 levels)
    tile = p.read_region(0, y=(1000, 1256), x=(2000, 2256))

# DICOM VL Whole Slide Microscopy. A slide is a SERIES of instances,
# one per resolution, so this takes a directory rather than a file --
# no extension can imply that, hence the explicit format=.
with oc.open_pyramid("study/slide_dir", format="dicom") as p:
    overview = p.read_region(p.best_level_for(max_pixels_y=1024))

2. Convert a multi-level pyramid to OME-Zarr v3 sharded

import opencodecs as oc

with oc.open_pyramid("input.ome.tiff") as p:
    levels = [p.read_region(level=i) for i in range(len(p.levels))]

oc.write_omezarr_pyramid(
    "output.zarr",
    levels,
    chunks=(512, 512),
    shards=(2048, 2048),         # 16 chunks per shard, one file each
    compressor="zstd",
    zarr_format=3,
)
# 1 file per shard on disk instead of 1 file per chunk; per-chunk
# random access still works via Range fetches into the shard.

For data going to S3, sharded Zarr v3 cuts your PUT and LIST costs by 1–2 orders of magnitude vs unsharded chunks while preserving per-chunk random-access via HTTP Range — the reader above understands the shard index automatically.

3. Fast JPEG XL thumbnails (native progressive decode)

import opencodecs.jxl as jxl

# downsample=8 uses libjxl's native progressive decoder — stops at
# the DC pass without reconstructing full-resolution pixels.
thumb = jxl.read("scan.jxl", downsample=8, subsample="center")
# 4Kx4K input → 512x512 ndarray in ~28 ms on macOS arm64
# (vs ~40 ms for a full decode), positionally centroid-correct
# so SVG / GL renderers don't get a ½-block shift.

# For a partial JXL bitstream usable as a tiny browser-direct
# thumbnail (works in Safari + modern Chrome):
prefix = jxl.thumbnail_bytes("scan.jxl")
# → ~85 KB out of a 3.5 MB source for a 4Kx4K image

Install

pip install opencodecs

Wheels are published for CPython 3.10–3.13 on macOS (arm64), Linux (x86_64 + aarch64), and Windows (amd64). Each wheel bundles libjxl, libavif, libheif, libwebp, libdeflate, c-blosc2, and friends — no system dependencies needed.

For a source install, system development headers, or to build a tuned local libjxl, see INSTALL.md. Wheel publishing runs through docs/publishing.md.

# Source install — auto-detects system libs, source-builds libjxl
git clone https://github.com/kevinjohncutler/opencodecs.git
cd opencodecs
pip install -e .

The build skips cleanly for any system library that's missing — useful extensions still build, missing ones print a one-line notice. libjxl 0.11.2 is auto-built from source via bench/build_libjxl.sh and cached under ~/Library/Caches/opencodecs/ (macOS) / ~/.cache/opencodecs/ (Linux). See INSTALL.md for the rationale (Homebrew/apt builds are 0.5-0.7× slower than a tuned -O3 + LTO build).

Status

  • v0.1.1 on PyPI (May 2026). Core API stable; 1066 tests passing on Mac M1 Ultra + Linux x86_64/aarch64 + Windows VM
  • Native readers + writers for the common scientific containers (TIFF, BigTIFF, OME-TIFF, CZI, NDTiff, HDF5, JXL, FITS, OME-Zarr v2 + v3 sharded)
  • Cross-platform bench coverage: Mac arm64 (canonical), Windows 11 LTSC (libvirt VM), Linux x86_64 (Threadripper-class)
  • Compression backend auto-detect (libdeflate → zlib-ng-compat → stdlib)
  • Cloud I/O primitives (HTTPDataSource with covering-cache + adaptive read-ahead) wired into TIFF / HDF5 / DICOMweb / CZI / FITS / Zarr v3 readers
  • tifffile_patch opt-in shim reroutes tifffile's codec dispatch through opencodecs for users who want only a partial swap

Deferred work (see docs/TODO_DEFERRED.md):

  • Windows wheels currently miss _sz3, _pcodec, _sperr, _brunsli — toolchain mismatch (conda's bash picks GCC over MSVC for CMake); v0.1.2 will restore them. macOS + Linux wheels have the full set.
  • CCITT Fax3/Fax4 encode — legacy fax; zero scientific users
  • JPEG-XR — abandoned format outside niche DICOM
  • libspng filter_sum SIMD — off the bench-tracked workload (h2h_png_4mp_rgb is at 1.14× already); filter-bound PNG-encode users could see another 2-3×

License

BSD-3-Clause; see LICENSE.

Vendored source, the Cython declaration files derived from imagecodecs (BSD-3-Clause, Copyright (c) 2008-2026 Christoph Gohlke), and the codec libraries bundled into the binary wheels each retain their own license. The full inventory is in THIRD-PARTY.md.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

opencodecs-0.2.0.tar.gz (1.1 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

opencodecs-0.2.0-cp313-cp313-win_amd64.whl (22.1 MB view details)

Uploaded CPython 3.13Windows x86-64

opencodecs-0.2.0-cp313-cp313-manylinux_2_28_x86_64.whl (37.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

opencodecs-0.2.0-cp313-cp313-manylinux_2_28_aarch64.whl (36.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

opencodecs-0.2.0-cp313-cp313-macosx_15_0_arm64.whl (15.7 MB view details)

Uploaded CPython 3.13macOS 15.0+ ARM64

opencodecs-0.2.0-cp312-cp312-win_amd64.whl (22.1 MB view details)

Uploaded CPython 3.12Windows x86-64

opencodecs-0.2.0-cp312-cp312-manylinux_2_28_x86_64.whl (37.8 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

opencodecs-0.2.0-cp312-cp312-manylinux_2_28_aarch64.whl (36.2 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

opencodecs-0.2.0-cp312-cp312-macosx_15_0_arm64.whl (15.7 MB view details)

Uploaded CPython 3.12macOS 15.0+ ARM64

opencodecs-0.2.0-cp311-cp311-win_amd64.whl (22.1 MB view details)

Uploaded CPython 3.11Windows x86-64

opencodecs-0.2.0-cp311-cp311-manylinux_2_28_x86_64.whl (38.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

opencodecs-0.2.0-cp311-cp311-manylinux_2_28_aarch64.whl (37.0 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

opencodecs-0.2.0-cp311-cp311-macosx_15_0_arm64.whl (15.7 MB view details)

Uploaded CPython 3.11macOS 15.0+ ARM64

opencodecs-0.2.0-cp310-cp310-win_amd64.whl (22.1 MB view details)

Uploaded CPython 3.10Windows x86-64

opencodecs-0.2.0-cp310-cp310-manylinux_2_28_x86_64.whl (37.1 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

opencodecs-0.2.0-cp310-cp310-manylinux_2_28_aarch64.whl (35.7 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

opencodecs-0.2.0-cp310-cp310-macosx_15_0_arm64.whl (15.7 MB view details)

Uploaded CPython 3.10macOS 15.0+ ARM64

File details

Details for the file opencodecs-0.2.0.tar.gz.

File metadata

  • Download URL: opencodecs-0.2.0.tar.gz
  • Upload date:
  • Size: 1.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for opencodecs-0.2.0.tar.gz
Algorithm Hash digest
SHA256 662233b6cf66be0e2820bc4e6b30803fcab19e5e92f94d3e7c39efd77fb583dd
MD5 dcb0c69392ff8fe15b1c0a70e2fcd74e
BLAKE2b-256 7a557f420b0053b5a7d2007ccb72fc3aea843eb75bf5c14f4e595a9c4cd954e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0.tar.gz:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: opencodecs-0.2.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 22.1 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for opencodecs-0.2.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 5189364aa2af8b15f457391aa598077d6341b162670dc600eb9320d53c29c8c8
MD5 a7415b6781bb38054c6f68252654a6ce
BLAKE2b-256 925d6f3fad7d5ded038f0fce34f5fc8b4e48f8d24fabf381e679e7d55f29ec1a

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp313-cp313-win_amd64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for opencodecs-0.2.0-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 12e0b045385cc82a1812b7b59090fbc3eea1c266c3547a872a2a83612f35c729
MD5 c72c761f921305aa92953c2a38db52e3
BLAKE2b-256 4abe4d97f2a60749dbaea20e07ba3e3b9aa87ff8fed173bce905ccc958295d72

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp313-cp313-manylinux_2_28_x86_64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp313-cp313-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for opencodecs-0.2.0-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e96f7805a704fa4a92529958e41da750141eb96942fd4045102d20238dcdccc9
MD5 9fcab8a4d53de7ca48019f873b4f392e
BLAKE2b-256 1c89e502695abbf824d158199409a4b0accb90cfac5cc1feda323ba774a0f501

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp313-cp313-manylinux_2_28_aarch64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp313-cp313-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for opencodecs-0.2.0-cp313-cp313-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 2610bc10cf1a418c48035f3d2f65552375db2ccc5ab27e713b59470f757b41e8
MD5 dec561e530279196f1a2e4b6e8757153
BLAKE2b-256 ca021774640033ff02cc5d2325dfa4748ca7987578df596982838affee4565aa

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp313-cp313-macosx_15_0_arm64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: opencodecs-0.2.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 22.1 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for opencodecs-0.2.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 82cd661a47774b1ff3752769a18d6cbbf1cda5f6c46fa7774042cabea3495575
MD5 25c1bed4e4320daaecde7d6f7dfb5598
BLAKE2b-256 d2d5005cff1e185a147b1be58978d09a71734be873f068fab00d173296cd1f8a

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp312-cp312-win_amd64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for opencodecs-0.2.0-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 cc38c3c2a6343faca5049ba3b32678fe9fb61d34c5f7ded8887cebae8a91be5d
MD5 aa5f77cd55ab4e960fde0592eae1deed
BLAKE2b-256 9628845dc01d162968836d367e31d4b82e415b17cd3662c9fba2e1fe8911c6c2

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp312-cp312-manylinux_2_28_x86_64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp312-cp312-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for opencodecs-0.2.0-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 120273b57cf00ada29c9a91f6515d532141a58ec0300d0fb743e03def8e0258f
MD5 58b9674e5a7513ecff3e62f647ee19f5
BLAKE2b-256 3cc2cc80ff0b9f6605cd43be5153455bdb32a5a90827d12330b8ad6c8e659021

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp312-cp312-manylinux_2_28_aarch64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp312-cp312-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for opencodecs-0.2.0-cp312-cp312-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 92dc5592820b01b7e6c15cd80552d03025eca060c248e95dcbc33263c6930805
MD5 7a238ca030cc816a2165e311540fbf29
BLAKE2b-256 6c63479947f73412e96d4051e25d1120122f5049d09e31b6abb54810a922002f

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp312-cp312-macosx_15_0_arm64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: opencodecs-0.2.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 22.1 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for opencodecs-0.2.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 b577412b1576a14613cca9474ccdbb665fc3299e43fbccb138529800c7df1c75
MD5 12e2bb397b3ab3d11eedca60c1cd5c36
BLAKE2b-256 50fa07b71044956e39e682478e07220b723eb951e759aad6f1a956e341c8d85c

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp311-cp311-win_amd64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for opencodecs-0.2.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 8ab73ca0b6dd82af62dfeb2c7c9c4abe3ebe2410bf492a9afeb38a1473293aad
MD5 ef0128995e06d2dc51c48488a67f0b92
BLAKE2b-256 e9de6327cb3bc91c816325e68e1c06fd220409b4a6cbf31775c3da6455b48abc

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp311-cp311-manylinux_2_28_x86_64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp311-cp311-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for opencodecs-0.2.0-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 fd7988230de8acdda0e99b5ad5abd572450ee6014cd363250b6cd3b25ffa62b7
MD5 a59b959bd986680a4f80128c4a8b7750
BLAKE2b-256 676e8a0802916a27c15426ca63a8879b2f56fac9c42bccc6e89d3e9cd68f660b

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp311-cp311-manylinux_2_28_aarch64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp311-cp311-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for opencodecs-0.2.0-cp311-cp311-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 7a190f0511310f0a3c12fdb1cf8c2dbcb7f4e454a9544d91d75438d446a26cb5
MD5 4a887ee31b7188ddd852136a187f211b
BLAKE2b-256 2e6a97057bf4cef91ed8c82c9aa8c2afbf4a3bbd33a521920d1b737f7e4697d5

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp311-cp311-macosx_15_0_arm64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: opencodecs-0.2.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 22.1 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for opencodecs-0.2.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 078d23ade9dfff1209cfc4ca37dace35d624af7a228cc07c940d058b35762dd7
MD5 e6454d4ad051b95d926916eabbd3498c
BLAKE2b-256 ff1fd7c9a0edf3353df5e330d46ba52af44be88620c9223ecb10cfee5ecadd57

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp310-cp310-win_amd64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for opencodecs-0.2.0-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 29e19e70d77cc5cc9839c9f4d1e2eb0811ddcd0708c5bf777503a260e7e7f007
MD5 e13948174bce601e6ae1e1ad33ab7c2b
BLAKE2b-256 01cac5357f9b45a409bae87c40b59798158f1b606d30ba4c7cf7fef3c9e9562f

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp310-cp310-manylinux_2_28_x86_64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp310-cp310-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for opencodecs-0.2.0-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 cc33f583405a10185bdfa127d67d0d3286f1db03e41409e58daf08071fb474e0
MD5 52a0db8de85c131d83890cc3b0954558
BLAKE2b-256 b6c9ff23435320c867c184a14784cf246a13f0ca9d0977662717f3f865242e54

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp310-cp310-manylinux_2_28_aarch64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file opencodecs-0.2.0-cp310-cp310-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for opencodecs-0.2.0-cp310-cp310-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 fbf9a1d680b689f54af4a4080d6d49359c556cd6b1f84008c3f28f2d43a53ded
MD5 edf08e4a578e71211b3a50ba6b5604ad
BLAKE2b-256 362750dd12c420608a4d1efc9639f3b4b5738f2d2fabe915c4593cf1ab66b78c

See more details on using hashes here.

Provenance

The following attestation bundles were made for opencodecs-0.2.0-cp310-cp310-macosx_15_0_arm64.whl:

Publisher: build_wheels.yml on kevinjohncutler/opencodecs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.2.0 This release

17 files

0.1.13

17 files

0.1.12

17 files

0.1.11

17 files

0.1.10

17 files

0.1.9

17 files

0.1.8

17 files

0.1.7

17 files

0.1.6

17 files

0.1.5

17 files

0.1.3

17 files

0.1.2

17 files

0.1.1

17 files

0.1.0

17 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page