-
Notifications
You must be signed in to change notification settings - Fork 86
Description
Author of Proposal: @brendan
Reason or problem
The geotiff package supports nvCOMP for GPU-accelerated deflate and ZSTD, but can't read or write JPEG 2000 (compression tag 34712). Sentinel-2 and Landsat data commonly ship as J2K-compressed GeoTIFFs, so this is a real gap for satellite imagery workflows.
NVIDIA's nvJPEG2000 library does GPU-accelerated J2K encode/decode. It fits the same optional-library pattern we already use for nvCOMP.
Proposal
Design:
Two tiers, same pattern as existing codecs:
-
CPU fallback via
glymur(optional): Same approach as JPEG (Pillow) and ZSTD (zstandard). Module-level availability flag, lazy import, error message if missing. -
GPU via nvJPEG2000 (optional): Same approach as nvCOMP -- lazy
ctypes.CDLLloading oflibnvjpeg2k.so, cached handle, batch decode/encode. Falls back to CPU glymur when the library isn't found.
Where it plugs in:
_compression.py: CPU J2K decompress/compress via glymur_gpu_decode.py:_try_nvjpeg2k_decode()and_nvjpeg2k_encode()using the same ctypes pattern as nvCOMP_writer.py: Add'jpeg2000'/'j2k'to_compression_tag()(tag 34712)gpu_decode_tiles(): Try nvJPEG2000 first for tag 34712, fall back to CPUgpu_compress_tiles(): Use nvJPEG2000 when compression is 34712
Usage:
# Write with JPEG 2000 compression
write_geotiff(data, "output.tif", compression="jpeg2000")
# GPU write -- uses nvJPEG2000 if available, else CPU fallback
write_geotiff(cupy_data, "output.tif", compression="jpeg2000", gpu=True)
# Read auto-detects compression from the TIFF tag
da = read_geotiff("sentinel2_j2k.tif")
da = read_geotiff("sentinel2_j2k.tif", gpu=True) # nvJPEG2000 if availableSatellite imagery uses JPEG 2000 widely, and GPU J2K decode is much faster than CPU on large rasters. The integration follows the existing nvCOMP pattern with no new abstractions.
Stakeholders and impacts
Anyone working with satellite GeoTIFFs that use JPEG 2000 compression. The change is additive -- existing codecs and code paths stay untouched. Both nvJPEG2000 and glymur are optional; the package works fine without either.
Drawbacks
- nvJPEG2000 needs CUDA 11.x+ and compute capability 7.0+
- glymur depends on the system OpenJPEG C library
- JPEG 2000 is lossy by default (lossless mode exists but is less common in TIFF context)
Alternatives
- rasterio/GDAL handles J2K, but this package aims for zero GDAL dependency
- Pillow has an OpenJPEG plugin, but it's limited and doesn't cover all J2K profiles
Unresolved questions
- Whether to expose quality/compression-ratio parameters for lossy encoding
- How to handle J2K's own internal tile concept vs. TIFF tiles
Additional notes
TIFF compression tag 34712 is defined in TIFF/EP (ISO 12234-2). The nvJPEG2000 library ships with the CUDA toolkit and is available in RAPIDS conda environments.