Code Monkey home page Code Monkey logo

imagecodecs's Introduction

Image transformation, compression, and decompression codecs

Imagecodecs is a Python library that provides block-oriented, in-memory buffer transformation, compression, and decompression functions for use in Tifffile, Czifile, Zarr, kerchunk, and other scientific image input/output packages.

Decode and/or encode functions are implemented for Zlib (DEFLATE), GZIP, ZStandard (ZSTD), Blosc, Brotli, Snappy, LZMA, BZ2, LZ4, LZ4F, LZ4HC, LZ4H5, LZW, LZO, LZF, LZFSE, LZHAM, PGLZ (PostgreSQL LZ), RCOMP (Rice), ZFP, SPERR, AEC, SZIP, LERC, EER, NPY, BCn, DDS, BMP, PNG, APNG, GIF, TIFF, WebP, QOI, JPEG 8 and 12-bit, Lossless JPEG (LJPEG, LJ92, JPEGLL), JPEG 2000 (JP2, J2K), JPEG LS, JPEG XL, JPEG XR (WDP, HD Photo), MOZJPEG, AVIF, HEIF, RGBE (HDR), Jetraw, DICOMRLE, PackBits, Packed Integers, Delta, XOR Delta, Floating Point Predictor, Bitorder reversal, Byteshuffle, Bitshuffle, Float24 (24-bit floating point), Quantize (Scale, BitGroom, BitRound, GranularBR), and CMS (color space transformations). Checksum functions are implemented for crc32, adler32, fletcher32, and Jenkins lookup3.

Author

Christoph Gohlke

License

BSD 3-Clause

Version

2024.1.1

DOI

10.5281/zenodo.6915978

Quickstart

Install the imagecodecs package and all dependencies from the Python Package Index:

python -m pip install -U imagecodecs[all]

Imagecodecs is also available in other package repositories such as Anaconda, MSYS2, and MacPorts.

See Requirements and Notes for building from source.

See Examples for using the programming interface.

Source code and support are available on GitHub.

Requirements

This revision was tested with the following requirements and dependencies (other versions may work):

  • CPython 3.9.13, 3.10.11, 3.11.7, 3.12.1, 64-bit
  • Numpy 1.26.2
  • numcodecs 0.12.1 (optional, for Zarr compatible codecs)

Build requirements:

Vendored requirements:

Test requirements:

Revisions

2024.1.1

  • Pass 7420 tests.
  • Add 8/24-bit BMP codec.
  • Add SPERR codec based on SPERR library.
  • Add LZO decoder based on lzokay library.
  • Add DICOMRLE decoder.
  • Enable float16 in CMS codec.
  • Enable MCT for lossless JPEG2K encoder (#88).
  • Ignore pad-byte in PackBits decoder (#86).
  • Fix heif_write_callback error message not set.
  • Require lcms2 2.16 with issue-420 fixes.
  • Require libjxl 0.9, libaec 1.1, Cython 3.

2023.9.18

  • Rebuild with updated dependencies fixes CVE-2024-4863.

2023.9.4

  • Map avif_encode level parameter to quality (breaking).
  • Support monochrome images in avif_encode.
  • Add numthreads parameter to avif_decode (fix imread of AVIF).
  • Add quantize filter (BitGroom, BitRound, GBR) via nc4var.c.
  • Add LZ4H5 codec.
  • Support more BCn compressed DDS fourcc types.
  • Require libavif 1.0.

2023.8.12

  • Add EER (Electron Event Representation) decoder.
  • Add option to pass initial value to crc32 and adler32 checksum functions.
  • Add fletcher32 and lookup3 checksum functions via HDF5's h5checksum.c.
  • Add Checksum codec for numcodecs.

2023.7.10

  • Rebuild with optimized compile flags.

2023.7.4

  • Add BCn and DDS decoder via bcdec library.
  • Add functions to transcode JPEG XL to/from JPEG (#78).
  • Add option to decode select frames from animated WebP.
  • Use legacy JPEG8 codec when building without libjpeg-turbo 3 (#65).
  • Change blosc2_encode defaults to match blosc2-python (breaking).
  • Fix segfault writing JPEG2K with more than 4 samples.
  • Fix some codecs returning bytearray by default.
  • Fully vendor cfitsio's ricecomp.c.
  • Drop support for Python 3.8 and numpy < 1.21 (NEP29).

2023.3.16

  • Require libjpeg-turbo 2.1.91 (3.0 beta) and c-blosc2 2.7.1.
  • Add experimental type hints.
  • Add SZIP codec via libaec library.
  • Use Zstd streaming API to decode blocks with unknown decompressed size.
  • Remove unused level, index, and numthreads parameters (breaking).
  • Make AEC and BLOSC constants enums (breaking).
  • Capitalize numcodecs class names (breaking).
  • Remove JPEG12 codec (breaking; use JPEG8 instead).
  • Encode and decode lossless and 12-bit JPEG with JPEG8 codec by default.
  • Remove JPEGSOF3 fallback in JPEG codec.
  • Fix slow IFD seeking with libtiff 4.5.
  • Fixes for Cython 3.0.

2023.1.23

  • Require libjxl 0.8.
  • Change mapping of level to distance parameter in jpegxl_encode.
  • Add option to specify bitspersample in jpegxl_encode.
  • Add option to pass de/linearize tables to LJPEG codec.
  • Fix lj92 decoder for SSSS=16 (#59).
  • Prefer ljpeg over jpegsof3 codec.
  • Add option to specify AVIF encoder codec.
  • Support LERC with Zstd or Deflate compression.
  • Squeeze chunk arrays by default in numcodecs image compression codecs.

2022.12.24

Refer to the CHANGES file for older revisions.

Objectives

Many scientific image storage formats like TIFF, CZI, DICOM, HDF, and Zarr are containers that hold large numbers of small data segments (chunks, tiles, stripes), which are encoded using a variety of compression and pre-filtering methods. Metadata common to all data segments are typically stored separate from the segments.

The purpose of the Imagecodecs library is to support Python modules in encoding and decoding such data segments. The specific aims are:

  • Provide functions for encoding and decoding small image data segments in-memory (not in-file) from and to bytes or numpy arrays for many compression and filtering methods.
  • Support image formats and compression methods not available elsewhere in the Python ecosystem.
  • Reduce the runtime dependency on numerous, large, inapt, or unmaintained Python packages. The imagecodecs package only depends on numpy.
  • Implement codecs as Cython wrappers of 3rd party libraries with a C API and permissive license if exists, else use own C library. Provide Cython definition files for the wrapped C libraries.
  • Release the Python global interpreter lock (GIL) during extended native/C function calls for multi-threaded use.

Accessing parts of large data segments and reading metadata from segments are out of the scope of this library.

Notes

This library is largely a work in progress.

The API is not stable yet and might change between revisions.

Python <= 3.8 is no longer supported. 32-bit versions are deprecated.

Works on little-endian platforms only.

Supported platforms are win_amd64, win_arm64, win32, macosx_x86_64, macosx_arm64, and manylinux_x86_64.

Wheels may not be available for all platforms and all releases.

Only the win_amd64 wheels include all features.

The tiff, bcn, dds, dicomrle, eer, lzo, packints, and jpegsof3 codecs are currently decode-only.

The heif and jetraw codecs are distributed as source code only due to license and possible patent usage issues.

The latest Microsoft Visual C++ Redistributable for Visual Studio 2015-2022 is required on Windows.

Refer to the imagecodecs/licenses folder for 3rd-party library licenses.

This software is based in part on the work of the Independent JPEG Group.

Update pip and setuptools to the latest version before installing imagecodecs:

python -m pip install -U pip setuptools wheel Cython

Install the requirements for building imagecodecs from source code on latest Ubuntu Linux distributions:

sudo apt-get install build-essential python3-dev cython3 python3-setuptools python3-pip python3-wheel python3-numpy python3-zarr python3-pytest python3-blosc python3-brotli python3-snappy python3-lz4 libz-dev libblosc-dev liblzma-dev liblz4-dev libzstd-dev libpng-dev libwebp-dev libbz2-dev libopenjp2-7-dev libjpeg-dev libjxr-dev liblcms2-dev libcharls-dev libaec-dev libbrotli-dev libsnappy-dev libzopfli-dev libgif-dev libtiff-dev libdeflate-dev libavif-dev libheif-dev

Use the --lite build option to only build extensions without 3rd-party dependencies. Use the --skip-extension build options to skip building specific extensions, for example:

python -m pip install imagecodecs --global-option="build_ext" --global-option="--skip-bitshuffle"

The apng, avif, jetraw, jpegls, jpegxl, lerc, lz4f, lzfse, lzham, lzo, mozjpeg, sperr, zfp, and zlibng extensions are disabled by default when building from source.

To modify other build settings such as library names and compiler arguments, provide a imagecodecs_distributor_setup.customize_build function, which is imported and executed during setup. See setup.py for examples.

Other Python packages and C libraries providing imaging or compression codecs: Python zlib, Python bz2, Python lzma, backports.lzma, python-lzo, python-lzw, python-lerc, wavpack-numcodecs, packbits, isa-l.igzip, fpzip, libmng, OpenEXR (EXR, PIZ, PXR24, B44, DWA), pyJetraw, tinyexr, pytinyexr, pyroexr, JasPer, libjpeg (GPL), pylibjpeg, pylibjpeg-libjpeg (GPL), pylibjpeg-openjpeg, pylibjpeg-rle, glymur, pyheif, pyrus-cramjam, PyLZHAM, BriefLZ, QuickLZ (GPL), LZO (GPL), nvJPEG, nvJPEG2K, PyTurboJPEG, CCSDS123, LPC-Rice, CompressionAlgorithms, Compressonator, Wuffs, TinyDNG, OpenJPH, Grok (AGPL), MAFISC, B3D.

Examples

Import the JPEG2K codec:

>>> from imagecodecs import ( ... jpeg2k_encode, jpeg2k_decode, jpeg2k_check, jpeg2k_version, JPEG2K ... )

Check that the JPEG2K codec is available in the imagecodecs build:

>>> JPEG2K.available True

Print the version of the JPEG2K codec's underlying OpenJPEG library:

>>> jpeg2k_version() 'openjpeg 2.5.0'

Encode a numpy array in lossless JP2 format:

>>> array = numpy.random.randint(100, 200, (256, 256, 3), numpy.uint8) >>> encoded = jpeg2k_encode(array, level=0) >>> bytes(encoded[:12]) b'x00x00x00x0cjP rnx87n'

Check that the encoded bytes likely contain a JPEG 2000 stream:

>>> jpeg2k_check(encoded) True

Decode the JP2 encoded bytes to a numpy array:

>>> decoded = jpeg2k_decode(encoded) >>> numpy.array_equal(decoded, array) True

Decode the JP2 encoded bytes to an existing numpy array:

>>> out = numpy.empty_like(array) >>> _ = jpeg2k_decode(encoded, out=out) >>> numpy.array_equal(out, array) True

Not all codecs are fully implemented, raising exceptions at runtime:

>>> from imagecodecs import tiff_encode >>> tiff_encode(array) Traceback (most recent call last): ... NotImplementedError: tiff_encode

Write the numpy array to a JP2 file:

>>> from imagecodecs import imwrite, imread >>> imwrite('_test.jp2', array)

Read the image from the JP2 file as numpy array:

>>> image = imread('_test.jp2') >>> numpy.array_equal(image, array) True

Create a JPEG 2000 compressed Zarr array:

>>> import zarr >>> import numcodecs >>> from imagecodecs.numcodecs import Jpeg2k >>> numcodecs.register_codec(Jpeg2k) >>> zarr.zeros( ... (4, 5, 512, 512, 3), ... chunks=(1, 1, 256, 256, 3), ... dtype='u1', ... compressor=Jpeg2k() ... ) <zarr.core.Array (4, 5, 512, 512, 3) uint8>

Access image data in a sequence of JP2 files via tifffile.FileSequence and dask.array:

>>> import tifffile >>> import dask.array >>> def jp2_read(filename): ... with open(filename, 'rb') as fh: ... data = fh.read() ... return jpeg2k_decode(data) >>> with tifffile.FileSequence(jp2_read, '*.jp2') as ims: ... with ims.aszarr() as store: ... dask.array.from_zarr(store) dask.array<from-zarr, shape=(1, 256, 256, 3)...chunksize=(1, 256, 256, 3)...

Write the Zarr store to a fsspec ReferenceFileSystem in JSON format and open it as a Zarr array:

>>> store.write_fsspec( ... 'temp.json', url='file://', codec_id='imagecodecs_jpeg2k' ... ) >>> import fsspec >>> mapper = fsspec.get_mapper( ... 'reference://', fo='temp.json', target_protocol='file' ... ) >>> zarr.open(mapper, mode='r') <zarr.core.Array (1, 256, 256, 3) uint8 read-only>

View the image in the JP2 file from the command line:

$ python -m imagecodecs _test.jp2

imagecodecs's People

Contributors

cgohlke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

imagecodecs's Issues

JxlDecoderProcessInput returned JXL_DEC_ERROR on certain images

Hi Christoph,
Thank you so much for maintaining this package! It's super handy for my current research project.
I'm currently countering a bug with JpegXL on Ubuntu 20.04 with this image (attached as png).
Minimal reproducible example:

import imagecodecs
img = imagecodecs.png_decode(open('test.png', 'rb').read())
imagecodecs.jpegxl_decode(imagecodecs.jpegxl_encode(img, level=4, lossless=False))

test

imagecodecs 2023.3.16 build error: unknown type name 'J12SAMPROW'

While attempting to update the py-imagecodecs Portfile to version 2023.3.16 under MacPorts, I ran into the following build error:

/usr/bin/clang -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -pipe -Os -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk -arch arm64 -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk -Iimagecodecs -I/opt/local/Library/Frameworks/Python.framework/Versions/3.11/include/python3.11 -I/opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/numpy/core/include -c imagecodecs/_jpeg8.c -o build/temp.macosx-12.0-arm64-cpython-311/imagecodecs/_jpeg8.o
In file included from imagecodecs/_jpeg8.c:746:
In file included from /opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/numpy/core/include/numpy/arrayobject.h:5:
In file included from /opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/numpy/core/include/numpy/ndarrayobject.h:12:
In file included from /opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/numpy/core/include/numpy/ndarraytypes.h:1940:
/opt/local/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-W#warnings]
#warning "Using deprecated NumPy API, disable it with "
^
imagecodecs/_jpeg8.c:3843:3: error: unknown type name 'J12SAMPROW'; did you mean 'JSAMPROW'?
J12SAMPROW __pyx_v_rowpointer12;
^~~~~~~~~~
JSAMPROW
/opt/local/include/jpeglib.h:69:18: note: 'JSAMPROW' declared here
typedef JSAMPLE JSAMPROW; / ptr to one image row of pixel samples. */
^
imagecodecs/_jpeg8.c:3844:3: error: unknown type name 'J16SAMPROW'; did you mean 'JSAMPROW'?
J16SAMPROW __pyx_v_rowpointer16;
^~~~~~~~~~
JSAMPROW
/opt/local/include/jpeglib.h:69:18: note: 'JSAMPROW' declared here
typedef JSAMPLE JSAMPROW; / ptr to one image row of pixel samples. */
^
imagecodecs/_jpeg8.c:5434:11: error: implicit declaration of function 'jpeg_enable_lossless' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
jpeg_enable_lossless((&__pyx_v_cinfo), __pyx_v_predictor_selection_value, 0);
^
imagecodecs/_jpeg8.c:5655:38: error: use of undeclared identifier 'J12SAMPROW'
__pyx_v_rowpointer12 = ((J12SAMPROW)(((char *)__pyx_v_src->data) + (__pyx_v_cinfo.next_scanline * __pyx_v_rowstride)));
^
imagecodecs/_jpeg8.c:5664:20: error: implicit declaration of function 'jpeg12_write_scanlines' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
(void)(jpeg12_write_scanlines((&__pyx_v_cinfo), (&__pyx_v_rowpointer12), 1));
^
imagecodecs/_jpeg8.c:5664:20: note: did you mean 'jpeg_write_scanlines'?
/opt/local/include/jpeglib.h:953:20: note: 'jpeg_write_scanlines' declared here
EXTERN(JDIMENSION) jpeg_write_scanlines(j_compress_ptr cinfo,
^
imagecodecs/_jpeg8.c:5695:38: error: use of undeclared identifier 'J16SAMPROW'
__pyx_v_rowpointer16 = ((J16SAMPROW)(((char *)__pyx_v_src->data) + (__pyx_v_cinfo.next_scanline * __pyx_v_rowstride)));
^
imagecodecs/_jpeg8.c:5704:20: error: implicit declaration of function 'jpeg16_write_scanlines' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
(void)(jpeg16_write_scanlines((&__pyx_v_cinfo), (&__pyx_v_rowpointer16), 1));
^
imagecodecs/_jpeg8.c:5704:20: note: did you mean 'jpeg_write_scanlines'?
/opt/local/include/jpeglib.h:953:20: note: 'jpeg_write_scanlines' declared here
EXTERN(JDIMENSION) jpeg_write_scanlines(j_compress_ptr cinfo,
^
imagecodecs/_jpeg8.c:6071:3: error: unknown type name 'J12SAMPROW'; did you mean 'JSAMPROW'?
J12SAMPROW __pyx_v_rowpointer12;
^~~~~~~~~~
JSAMPROW
/opt/local/include/jpeglib.h:69:18: note: 'JSAMPROW' declared here
typedef JSAMPLE JSAMPROW; / ptr to one image row of pixel samples. */
^
imagecodecs/_jpeg8.c:6072:3: error: unknown type name 'J16SAMPROW'; did you mean 'JSAMPROW'?
J16SAMPROW __pyx_v_rowpointer16;
^~~~~~~~~~
JSAMPROW
/opt/local/include/jpeglib.h:69:18: note: 'JSAMPROW' declared here
typedef JSAMPLE JSAMPROW; / ptr to one image row of pixel samples. */
^
imagecodecs/_jpeg8.c:7035:36: error: use of undeclared identifier 'J12SAMPROW'
__pyx_v_rowpointer12 = ((J12SAMPROW)__pyx_v_dst->data);
^
imagecodecs/_jpeg8.c:7055:20: error: implicit declaration of function 'jpeg12_read_scanlines' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
(void)(jpeg12_read_scanlines((&__pyx_v_cinfo), (&__pyx_v_rowpointer12), 1));
^
imagecodecs/_jpeg8.c:7055:20: note: did you mean 'jpeg_read_scanlines'?
/opt/local/include/jpeglib.h:998:20: note: 'jpeg_read_scanlines' declared here
EXTERN(JDIMENSION) jpeg_read_scanlines(j_decompress_ptr cinfo,
^
imagecodecs/_jpeg8.c:7085:36: error: use of undeclared identifier 'J16SAMPROW'
__pyx_v_rowpointer16 = ((J16SAMPROW)__pyx_v_dst->data);
^
imagecodecs/_jpeg8.c:7105:20: error: implicit declaration of function 'jpeg16_read_scanlines' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
(void)(jpeg16_read_scanlines((&__pyx_v_cinfo), (&__pyx_v_rowpointer16), 1));
^
imagecodecs/_jpeg8.c:7105:20: note: did you mean 'jpeg_read_scanlines'?
/opt/local/include/jpeglib.h:998:20: note: 'jpeg_read_scanlines' declared here
EXTERN(JDIMENSION) jpeg_read_scanlines(j_decompress_ptr cinfo,
^
1 warning and 13 errors generated.
error: command '/usr/bin/clang' failed with exit code 1

ERROR Backend subprocess exited when trying to invoke build_wheel

Pip install of imagecodecs 2020.12.22 fails on Mac

On macOS 10.15.7 "pip3 install imagecodecs" tries to compile from source because there is no binary Mac PyPi wheel and then fails with

imagecodecs/_aec.c:617:10: fatal error: 'libaec.h' file not found
#include "libaec.h"
         ^~~~~~~~~~
1 warning and 1 error generated.
error: command 'clang' failed with exit status 1

JPEG XL decoding problem: "RuntimeError: no frames found"

When attempting to decode a specific JPEG XL file created using the libjxl binaries, RuntimeError: no frames found was thrown.

import imagecodecs

fname = "jxl_q10.jxl"
with open(fname, 'rb') as fh:
    jxlbytes = fh.read()
nparr = imagecodecs.jpegxl_decode(jxlbytes)

The libjxl decoder and imagemagick can decode it just fine, with djxl.exe .\jxl_q10.jxl out.png or magick convert .\jxl_q10.jxl out.png.

Code and sample file in this repository.

Metadata (e.g EXIF tags) Support

Is it in the scope of imagecodecs to support reading/writing of EXIF metadata (and PNG chunks etc.)? This would be a really useful but likely also non-trivial addition. In particular the EXIF resolution tags (and maybe PNG physical pixel/subject scale chunks) are of interest to me.

JPEGXL support on Mac Release

Hi @cgohlke, Thank you for releasing this software package. This is the best package for interacting with JXL files in python right now! However, I noticed that the MacOS release on PyPi does not have the JXL support compiled into it, although I already have libjxl installed through homebrew. On manylinux, everything works well. Is it possible to enable the JPEGXL support on the macos wheel package? Thank you!

Improve zopfli header search

Some platforms put it at include/zopfli.h, while some at include/zopfli/zopfli.h

Rather than hard-coding zopfli/zopfli.h in zopfli.pxd, might be better to remove the prefix and handle it instead in setup.py customize_build_* just like others (e.g. jxrlib).

imagecodecs.numcodecs.register_codecs: RuntimeError

Hi @cgohlke,

In a CI run, I just saw a RuntimeError: dictionary changed size during iteration in register_codecs
It only failed on Python3.11 on ubuntu. And rerunning the job could not reproduce the error, so this might be just some artefact.

Reporting it just in case it pops up again.

https://github.com/bayer-science-for-a-better-life/tiffslide/actions/runs/4292134595/jobs/7478191925#step:6:257

imagecodecs-2023.1.23
numcodecs-0.11.0

[...]
>       ts = from_kerchunk(kc)

tiffslide/tests/test_kerchunk.py:28: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tiffslide/_kerchunk.py:155: in from_kerchunk
    register_codecs(verbose=False)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

codecs = None, force = False, verbose = False

    def register_codecs(codecs=None, force=False, verbose=True):
        """Register codecs in this module with numcodecs."""
>       for name, cls in globals().items():
E       RuntimeError: dictionary changed size during iteration

/opt/hostedtoolcache/Python/3.11.2/x64/lib/python3.11/site-packages/imagecodecs/numcodecs.py:1339: RuntimeError

Cheers,
Andreas

level parameter seems to have no effect in encode_jpeg2k

Lot of thanks @cgohlke for this amazing package.

During my experiments, I found that the level parameter in encode_jpeg2k seems to have no effect on the compression size and quality :/
Here is a code sample demonstrating this behavior:

import numpy as np
from skimage.data import cat
from skimage.metrics import normalized_root_mse
import tqdm
from skimage import data
from time import time
from imagecodecs import jpeg2k_encode, jpeg2k_decode


img0 = data.cat()

level = np.arange(0, 1001, 100)
level[0] = 1
time_rep = 10

for lev in tqdm.tqdm(level):
    tqdm.tqdm.write(f"\nlevel: {lev}")
    t = 0
    for _ in range(time_rep):
        t0 = time()
        buf = jpeg2k_encode(img0, level=lev, reversible=0, verbose=0)
        t1 = time()
        t += t1 - t0

    t /= time_rep

    size = len(buf) * 1e-3

    err = normalized_root_mse(img0, jpeg2k_decode(buf))
    tqdm.tqdm.write(f"\tTime: {t:.04f}sec -- Size: {size:.02f}Kb -- " +
                    f"NMSE: {err:.02e}")

Gives on my machine

level: 1
        Time: 0.0200sec -- Size: 92.98Kb -- NMSE: 6.09e-03                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                  
level: 100
        Time: 0.0201sec -- Size: 92.98Kb -- NMSE: 6.09e-03                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                  
level: 200
        Time: 0.0200sec -- Size: 92.98Kb -- NMSE: 6.09e-03                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                  
level: 300
        Time: 0.0200sec -- Size: 92.98Kb -- NMSE: 6.09e-03                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                  
level: 400
        Time: 0.0200sec -- Size: 92.98Kb -- NMSE: 6.09e-03                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                  
level: 500
        Time: 0.0201sec -- Size: 92.98Kb -- NMSE: 6.09e-03                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                  
level: 600
        Time: 0.0199sec -- Size: 92.98Kb -- NMSE: 6.09e-03                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                  
level: 700
        Time: 0.0200sec -- Size: 92.98Kb -- NMSE: 6.09e-03                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                  
level: 800
        Time: 0.0201sec -- Size: 92.98Kb -- NMSE: 6.09e-03                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                  
level: 900
        Time: 0.0200sec -- Size: 92.98Kb -- NMSE: 6.09e-03                                                                                                                                                                                                                        
                                                                                                                                                                                                                                                                                  
level: 1000
        Time: 0.0200sec -- Size: 92.98Kb -- NMSE: 6.09e-03

Thank you for your help :)

pyinstaller package throw error "could not import name 'zlib_encode' from 'imagecodecs'"

Dear author

I make a program create tiff use tifffile, when I create package with pyinstaller,run the package exe throw an error

 could not import name 'zlib_encode' from 'imagecodecs'

I found the dist directory imagecodecs folder only has one file _shared.cp37-win_amd64.pyd, copy _zlib.cp37-win_amd64.pyd to imagecodecs folder of dist, above error not throw!

could you fix the problem?

my env:
windows 10 64bit
python 3.7 64bit
tifffile 2021.1.14
imagecodecs 2021.1.11

error: use of undeclared identifier 'JPEG_LIB_VERSION_MAJOR'

While building py39-imagecodecs 2021.8.26 under MacPorts I get the following error:

:info:build In file included from imagecodecs/_jpegsof3.c:620:
:info:build In file included from /opt/local/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/numpy/core/include/numpy/arrayobject.h:4:
:info:build In file included from /opt/local/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/numpy/core/include/numpy/ndarrayobject.h:12:
:info:build In file included from /opt/local/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/numpy/core/include/numpy/ndarraytypes.h:1969:
:info:build /opt/local/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: "Using deprecated NumPy API, disable it with "          "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-W#warnings]
:info:build #warning "Using deprecated NumPy API, disable it with " \
:info:build  ^
:info:build building 'imagecodecs._ljpeg' extension
:info:build creating build/temp.macosx-10.14-x86_64-3.9/3rdparty/liblj92
:info:build imagecodecs/_jpeg8.c:2928:40: error: use of undeclared identifier 'JPEG_LIB_VERSION_MAJOR'
:info:build   __pyx_t_4 = __Pyx_PyUnicode_From_int(JPEG_LIB_VERSION_MAJOR, 0, ' ', 'd'); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 91, __pyx_L1_error)
:info:build                                        ^
:info:build /opt/local/var/macports/build/_Users_marius_Development_MacPorts_ports_python_py-imagecodecs/py39-imagecodecs/work/compwrap/cc/usr/bin/clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -pipe -Os -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -arch x86_64 -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -Iimagecodecs -I3rdparty/liblj92 -I/opt/local/Library/Frameworks/Python.framework/Versions/3.9/include/python3.9 -I/opt/local/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/numpy/core/include -c 3rdparty/liblj92/lj92.c -o build/temp.macosx-10.14-x86_64-3.9/3rdparty/liblj92/lj92.o
:info:build imagecodecs/_jpeg8.c:2938:40: error: use of undeclared identifier 'JPEG_LIB_VERSION_MINOR'
:info:build   __pyx_t_4 = __Pyx_PyUnicode_From_int(JPEG_LIB_VERSION_MINOR, 0, ' ', 'd'); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 91, __pyx_L1_error)
:info:build                                        ^
:info:build 1 warning and 2 errors generated.

Issue with pip install on a ARM device

I cant successfully install it on a arm64 device.

      imagecodecs/_brunsli.c:697:10: fatal error: brunsli/decode.h: No such file or directory
        697 | #include "brunsli/decode.h"
            |          ^~~~~~~~~~~~~~~~~~
      compilation terminated.
      error: command '/usr/bin/aarch64-linux-gnu-gcc' failed with exit code 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure

× Encountered error while trying to install package.
╰─> imagecodecs

note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.

openjpeg include dir mismatch

imagecodes release 2022.2.22 hardcode the include path for openjpeg,

('/usr/include/openjpeg-2.3', '/usr/include/openjpeg-2.4')

('%PREFIX%/include/openjpeg-2.3', '%PREFIX%/include/openjpeg-2.4')

imagecodecs/setup.py

Lines 521 to 522 in 92a8620

sys.prefix + '/include/openjpeg-2.3',
sys.prefix + '/include/openjpeg-2.4',

and we could not build imagecodecs on ArchLinux with opejpeg 2.5.
error logs:

creating build/temp.linux-x86_64-3.10/3rdparty/openjpeg
gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -flto=auto -ffat-lto-objects -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -flto=auto -march=x86-64 -mtune=generic -O3 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -flto=auto -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -flto=auto -fPIC -Iimagecodecs -I3rdparty/openjpeg -I/usr/include/openjpeg-2.3 -I/usr/include/openjpeg-2.4 -I/usr/include/python3.10 -I/usr/lib/python3.10/site-packages/numpy/core/include -c 3rdparty/openjpeg/color.c -o build/temp.linux-x86_64-3.10/3rdparty/openjpeg/color.o
3rdparty/openjpeg/color.c:45:10: fatal error: openjpeg.h: No such file or directory
   45 | #include "openjpeg.h"
      |          ^~~~~~~~~~~~
compilation terminated.
error: command '/usr/bin/gcc' failed with exit code 1
==> ERROR: A failure occurred in build().

see also the full log here.
related issue #7, related AUR link.

DelayedImportError: could not import name 'jpegxl_encode' from 'imagecodecs'

Thanks so much for your work on this awesome library!

Sorry if I'm doing something wrong but I'm bumping into this exception with numcodecs 2021.11.20 (installed using conda today):

---------------------------------------------------------------------------
DelayedImportError                        Traceback (most recent call last)
Input In [29], in <module>
----> 1 encoded = jpegxl_encode(input_buffer, distance=0)

File ~/miniconda3/envs/jpegxl/lib/python3.10/site-packages/imagecodecs/imagecodecs.py:616, in _stub.<locals>.stub_encode(*args, **kwargs)
    614 def stub_encode(*args, **kwargs):
    615     """Stub for imagecodecs.codec_encode function."""
--> 616     raise DelayedImportError(name)

DelayedImportError: could not import name 'jpegxl_encode' from 'imagecodecs'

Steps to reproduce

conda install imagecodecs numpy

from imagecodecs import jpegxl_encode
import numpy as np

input_buffer = np.arange(1000000, dtype='uint8').reshape(1000, 1000)
encoded = jpegxl_encode(input_buffer, distance=0)

Context

I'm running this Python code in Jupyter Lab.

I installed libjxl v0.7.0 dev (compiling from HEAD, yesterday) before installing imagecodecs. cjxl appears to work correctly. I'm on Ubuntu 21.04.

I've also tried installing the libjxl 0.6.1 release now using the Ubuntu .deb file and re-installing imagecodecs but that didn't appear to help.

install via pip on M1 fails due to wrong include dir for openjpeg

I am trying to install imagecodecs via pip (from pyenv) on M1 with the following command:

pip install --global-option=build_ext --global-option="-I/opt/homebrew/include/" --global-option="-L/opt/homebrew/lib" -U imagecodecs

Even though, I specify the include dir, pip can't find the openjpeg.h (which is present in /opt/homebrew/include/openjpeg-2.5/ )

The output looks something like this:

      building 'imagecodecs._jpeg2k' extension
      creating build/temp.macosx-12.6-arm64-3.9/3rdparty/openjpeg
      clang -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -Iimagecodecs -I3rdparty/openjpeg -I/usr/include/openjpeg-2.3 -I/usr/include/openjpeg-2.4 -I/usr/include/openjpeg-2.5 -I/opt/homebrew/include/ -I/Users/unknownms/.pyenv/versions/3.9-dev/include/python3.9 -I/Users/unknownms/.pyenv/versions/3.9-dev/lib/python3.9/site-packages/numpy/core/include -c 3rdparty/openjpeg/color.c -o build/temp.macosx-12.6-arm64-3.9/3rdparty/openjpeg/color.o
      3rdparty/openjpeg/color.c:45:10: fatal error: 'openjpeg.h' file not found
      #include "openjpeg.h"
               ^~~~~~~~~~~~
      1 error generated.
      error: command '/usr/bin/clang' failed with exit code 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure

× Encountered error while trying to install package.
╰─> imagecodecs

note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.

what am I missing?

libjxl v0.7rc1

Thanks again for all your work on imagecodecs!

After almost a year since the release of libjxl v0.6.1, v0.7rc of libjxl has been released. (libjxl is the reference implementation of the JPEG XL codec).

I plan to experiment with using imagecodecs and libjxl v0.7rc over the coming weeks. If I find that any changes are necessary to the imagecodecs code to make it compatible with libjxl v0.7rc then should I submit a PR to imagecodecs?

I guess my main question is to ask whether you're already working on updating imagecodecs to work with libjxl v0.7, because I don't want to duplicate your work! (No worries either way, I know you're busy!)

(To give some context: I'm working on trying to store a 12-channel satellite image in a single JPEG XL file, using imagecodecs, Zarr, and xarray).

PYPI package for arm64 OSX

Could you please provide OSX arm64 package for PyPI?
It's unreal to build it from sources because of huge number of dependencies.
I would assume that source pypi package must contain all dependencies internally, because I've tried to build pypi package and gave up with this on 6th dependency.

Failed to install imagecodecs==2021.11.20 with pip

System:

  • OS: Debian 4.19.208-1 (2021-09-29) x86_64 GNU/Linux
  • Python: Python 3.7.3
  • pip: 21.3.1
  • setuptools: 59.5.0

Installation fails on numpy dependency:

    Complete output from command python setup.py egg_info:
    running egg_info
    creating pip-egg-info/imagecodecs.egg-info
    writing pip-egg-info/imagecodecs.egg-info/PKG-INFO
    writing dependency_links to pip-egg-info/imagecodecs.egg-info/dependency_links.txt                                                    
    writing entry points to pip-egg-info/imagecodecs.egg-info/entry_points.txt                                                            
    writing requirements to pip-egg-info/imagecodecs.egg-info/requires.txt                                                                
    writing top-level names to pip-egg-info/imagecodecs.egg-info/top_level.txt                                                            
    writing manifest file 'pip-egg-info/imagecodecs.egg-info/SOURCES.txt'                                                                 
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-9q1vp2c6/imagecodecs/setup.py", line 692, in <module>                                                        
        'Programming Language :: Python :: Implementation :: CPython',                                                                    
      File "/home/exesse/wsi-til/wsi/lib/python3.7/site-packages/setuptools/__init__.py", line 145, in setup                              
        return distutils.core.setup(**attrs)
      File "/usr/lib/python3.7/distutils/core.py", line 148, in setup                                                                     
        dist.run_commands()
      File "/usr/lib/python3.7/distutils/dist.py", line 966, in run_commands                                                              
        self.run_command(cmd)
      File "/usr/lib/python3.7/distutils/dist.py", line 985, in run_command                                                               
        cmd_obj.run()
      File "/home/exesse/wsi-til/wsi/lib/python3.7/site-packages/setuptools/command/egg_info.py", line 296, in run                        
        self.find_sources()
      File "/home/exesse/wsi-til/wsi/lib/python3.7/site-packages/setuptools/command/egg_info.py", line 303, in find_sources               
        mm.run()
      File "/home/exesse/wsi-til/wsi/lib/python3.7/site-packages/setuptools/command/egg_info.py", line 534, in run                        
        self.add_defaults()
      File "/home/exesse/wsi-til/wsi/lib/python3.7/site-packages/setuptools/command/egg_info.py", line 570, in add_defaults               
        sdist.add_defaults(self)
      File "/usr/lib/python3.7/distutils/command/sdist.py", line 228, in add_defaults                                                     
        self._add_defaults_ext()
      File "/usr/lib/python3.7/distutils/command/sdist.py", line 311, in _add_defaults_ext                                                
        build_ext = self.get_finalized_command('build_ext')
      File "/usr/lib/python3.7/distutils/cmd.py", line 299, in get_finalized_command                                                      
        cmd_obj.ensure_finalized()
      File "/usr/lib/python3.7/distutils/cmd.py", line 107, in ensure_finalized                                                           
        self.finalize_options()
      File "/tmp/pip-install-9q1vp2c6/imagecodecs/setup.py", line 600, in finalize_options                                                
        import numpy
    ModuleNotFoundError: No module named 'numpy'

If I would install numpy fisrt will fail with another error:

pip install imagecodecs                                                                                 
Collecting imagecodecs                                                                                                                     
  Using cached https://files.pythonhosted.org/packages/51/72/09eb4cdf8f2a8887cf87cedefdd6be063c85005918ec107a9d8dce432375/imagecodecs-2021$
11.20.tar.gz                                                                                                                               
Requirement already satisfied: numpy>=1.16.5 in ./wsi/lib/python3.7/site-packages (from imagecodecs) (1.21.4)                              
Building wheels for collected packages: imagecodecs                                                                                        
  Running setup.py bdist_wheel for imagecodecs ... error                                                                                   
  Complete output from command /home/exesse/wsi-til/wsi/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-v1pharh0$
imagecodecs/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file_$
, 'exec'))" bdist_wheel -d /tmp/pip-wheel-6uexafag --python-tag cp37:                                                                      
  usage: -c [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]                                                                          
     or: -c --help [cmd1 cmd2 ...]                                                                                                         
     or: -c --help-commands                                                                                                                
     or: -c cmd --help                                                                                                                     
                                                                                                                                           
  error: invalid command 'bdist_wheel'                                                                                                     
                                                                                                                                           
  ----------------------------------------                                                                                                 
  Failed building wheel for imagecodecs                                                                                                    
  Running setup.py clean for imagecodecs                                                                                                   
Failed to build imagecodecs                                                                                                                
Installing collected packages: imagecodecs                                                                                                 
  Running setup.py install for imagecodecs ... error                                                                                       
    Complete output from command /home/exesse/wsi-til/wsi/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-v1phar$
0/imagecodecs/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __fil$
__, 'exec'))" install --record /tmp/pip-record-c9jhdbs8/install-record.txt --single-version-externally-managed --compile --install-headers 
/home/exesse/wsi-til/wsi/include/site/python3.7/imagecodecs:                                                                               
    running install                                                                                                                        
    running build                                                                                                                          
    running build_py                                                                                                                       
    creating build                                                                                                                         
    creating build/lib.linux-x86_64-3.7                                                                                                    
    creating build/lib.linux-x86_64-3.7/imagecodecs                                                                                        
    copying imagecodecs/__main__.py -> build/lib.linux-x86_64-3.7/imagecodecs                                                              
    copying imagecodecs/numcodecs.py -> build/lib.linux-x86_64-3.7/imagecodecs                                                             
    copying imagecodecs/__init__.py -> build/lib.linux-x86_64-3.7/imagecodecs                                                              
    copying imagecodecs/imagecodecs.py -> build/lib.linux-x86_64-3.7/imagecodecs                                                           
    copying imagecodecs/_imagecodecs.py -> build/lib.linux-x86_64-3.7/imagecodecs                                                          
    creating build/lib.linux-x86_64-3.7/imagecodecs/licenses                                                                               
    copying imagecodecs/licenses/LICENSE-libspng -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                        
    copying imagecodecs/licenses/LICENSE-jpeg -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                           
    copying imagecodecs/licenses/LICENSE-dav1d -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                          
    copying imagecodecs/licenses/LICENSE-libtiff -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                        
    copying imagecodecs/licenses/LICENSE-snappy -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                        
    copying imagecodecs/licenses/LICENSE-aom -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                           
    copying imagecodecs/licenses/PATENTS-rav1e -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                         
    copying imagecodecs/licenses/LICENSE-libaec -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                        
    copying imagecodecs/licenses/LICENSE-brotli -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                        
    copying imagecodecs/licenses/LICENSE-zlib -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                          
    copying imagecodecs/licenses/LICENSE-zstd -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                          
    copying imagecodecs/licenses/LICENSE-libjxl -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                        
    copying imagecodecs/licenses/LICENSE-libwebp -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                       
    copying imagecodecs/licenses/LICENSE-zlib-ng -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                       
    copying imagecodecs/licenses/LICENSE-liblzma -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                       
    copying imagecodecs/licenses/LICENSE-postgresql -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                    
    copying imagecodecs/licenses/LICENSE-lcms2 -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                         
    copying imagecodecs/licenses/LICENSE-libmng -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                        
    copying imagecodecs/licenses/LICENSE-liblj92 -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                       
    copying imagecodecs/licenses/LICENSE-libpng -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                        
    copying imagecodecs/licenses/LICENSE-zopfli -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                        
    copying imagecodecs/licenses/LICENSE-lz4 -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                           
    copying imagecodecs/licenses/LICENSE-bitshuffle -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                    
    copying imagecodecs/licenses/LICENSE-charls -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                        
    copying imagecodecs/licenses/LICENSE-cfitsio -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                       
    copying imagecodecs/licenses/LICENSE-lzf -> build/lib.linux-x86_64-3.7/imagecodecs/licenses                                           
    copying imagecodecs/licenses/LICENSE-libjpeg-turbo -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-jxrlib -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-libdeflate -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-fastlz -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-fastlz -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-libaivf -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-libjpeg -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-zfp -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-highway -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-bzip2 -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-giflib -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-blosc2 -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-lerc -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-jpg_0xc3 -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-brunsli -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-mozjpeg -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-openjpeg -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-blosc -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    copying imagecodecs/licenses/LICENSE-rav1e -> build/lib.linux-x86_64-3.7/imagecodecs/licenses
    running build_ext
    building 'imagecodecs._aec' extension
    creating build/temp.linux-x86_64-3.7
    creating build/temp.linux-x86_64-3.7/imagecodecs
    x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -$
_FORTIFY_SOURCE=2 -fPIC -Iimagecodecs -I/home/exesse/wsi-til/wsi/include -I/usr/include/python3.7m -I/home/exesse/wsi-til/wsi/lib/python3.$
/site-packages/numpy/core/include -c imagecodecs/_aec.c -o build/temp.linux-x86_64-3.7/imagecodecs/_aec.o
    In file included from /home/exesse/wsi-til/wsi/lib/python3.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1969,
                     from /home/exesse/wsi-til/wsi/lib/python3.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
                     from /home/exesse/wsi-til/wsi/lib/python3.7/site-packages/numpy/core/include/numpy/arrayobject.h:4,
                     from imagecodecs/_aec.c:620:
    /home/exesse/wsi-til/wsi/lib/python3.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning "Using $
eprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
     #warning "Using deprecated NumPy API, disable it with " \
      ^~~~~~~
    imagecodecs/_aec.c:627:10: fatal error: libaec.h: No such file or directory
     #include "libaec.h"
              ^~~~~~~~~~
    compilation terminated.
    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

    ----------------------------------------
Command "/home/exesse/wsi-til/wsi/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-install-v1pharh0/imagecodecs/setup.py'$
f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install -$
record /tmp/pip-record-c9jhdbs8/install-record.txt --single-version-externally-managed --compile --install-headers /home/exesse/wsi-til/ws$
/include/site/python3.7/imagecodecs" failed with error code 1 in /tmp/pip-install-v1pharh0/imagecodecs/

pip list output:

Package       Version
------------- -------
numpy         1.21.4 
pip           18.1   
pkg-resources 0.0.0  
setuptools    40.8.0 

Compressing "technical" imagery using JPEG-XL

Hi again!

I've been having a really interesting conversation with the JPEG-XL folks about using JPEG-XL to compress "technical" imagery (where we want to recover the original numerical values; and we don't care much about the images looking good to humans. In my case, I want to compress multi-channel satellite imagery. The images will mostly be consumed by machines, not humans).

The thread has thrown up a bunch of interesting ideas. I'm going to try modifying imagecodecs/_jpegxl.pyx to implement some of these ideas as a separate PR.

If there's a "development version" of imagecodes, please may I see the latest version of imagecodecs/_jpegxl.pyx, just to make it easy to merge my PR into master if my PR proves useful? No worries if not!

The level parameter marginally affects output size and quality in jpegxl_encode

I performed few experiments trying to understand the effect of the different parameters of jpegxl_encode, and I found that only the distance parameter affects the output size and the image quality.

Generally, in other formats (JPEG, JPEGXR, JPEG2000, AVIF), the level parameter is used to set compression quality and size.
What about making level parameter in jpegxl_encode depend on the actual distance parameter for consistency?

Here are the results of my experiments:

Evaluation

Using two test images from skimage (cat and astronaut), I measured 4 quantities: output size, Normalized root MSE (NMSE) and finally encoding and decoding time:

from tqdm import tqdm, trange
import numpy as np
from itertools import product
from imagecodecs import jpegxl_encode, jpegxl_decode
from skimage.metrics import normalized_root_mse
from skimage import data
from time import time

time_rep = 10
level = range(5)
distance = np.arange(0., 3.1, 0.5)
effort = range(3, 10)

measures = {}

fname = "results/jxl.json"

for func in tqdm([data.cat, data.astronaut]):
    results = {}
    img0 = func()

    for lev, dist, eff in tqdm(list(product(level, distance, effort)), leave=False):
        tqdm.write(
            f"\nlevel: {lev} - distance: {dist:.01f} - effort: {eff}")
        t = 0
        for _ in trange(time_rep, leave=False):
            t0 = time()
            buf = jpegxl_encode(img0, level=lev, effort=eff,
                                distance=dist, lossless=0)
            t1 = time()
            t += t1 - t0

        t /= time_rep

        t_dec = 0
        for _ in trange(time_rep, leave=False):
            t0 = time()
            jpegxl_decode(buf)
            t1 = time()
            t_dec += t1 - t0

        t_dec /= time_rep

        size = len(buf) * 1e-3

        err = normalized_root_mse(img0, jpegxl_decode(buf))

        tqdm.write(f"\tEnc Time: {t:.04f}sec -- "
                        f"Dec Time: {t_dec:.04f}sec -- " +
                        f"Size: {size:.02f}Kb -- NMSE: {err:.02e}")

        results[f"{lev}, {dist}, {eff}"] = {"enc_time": t, "dec_time": t_dec,
                                            "nmse": err, "size": size}
    measures[func.__name__] = results

Results

Measures on both test images are consistent:

Effort parameter influence

NMSE and output size are marginally affected by the effort parameter

effort

Level parameter influence

effort is set to 3
Again, NMSE and output size are marginally affected by the level parameter

level

distance parameter influence

effort is set to 3 and level to 4

NMSE and output size are controled by the distance parameter

distance

Consider changing the way `option_lossess` is set in `jpegxl_encode`?

Thanks again for all your work on imagecodecs!

In jpegxl_encode, option_lossless is set to True if level is None or level < 0 (line 160 of _jpegxl.pyx).

The level argument to jpegxl_encode is passed to JxlEncoderOptionsSetDecodingSpeed which sets the decoding speed, not whether the image is lossless or not 🙂. That is, level is somewhat orthogonal to whether lossless mode should be engaged or not.

An improvement might be to set option_lossless to True if distance is 0.0. (See the docs for distance)

(Also, would it be worth considering renaming level to decoding_speed or something like that?)

CI and building for PyPy

Over at conda-forge they have started rolling out support for pypy3.7, and the CI run hangs. Have you considered running CI here? github actions would be a good candidate since they offer a nice recipe for python versions including pypy (probably best to test for pypy3.7, 3.6 is not long for the world). If you want to go all out and deploy from the repo, the cibuildwheel project builds, tests, and deploys for all the chosen python versions (https://cibuildwheel.readthedocs.io/en/stable/options/#build-skip)in one run per platfom.

Edit: fix link to conda-forge issue

Where can I get the usage of this package

I want to read some lossless JPEG images with SOF3 via Python , but I can't find any usage!I'll be appricaite if somebody give me a address or some code as a example。

could not import name 'jetraw_decode' from 'imagecodecs'

Hello,

I tried to read an image compressed with jetraw, but I have the following error message:

imagecodecs.imagecodecs.DelayedImportError: could not import name 'jetraw_decode' from 'imagecodecs'

I am using imagecodecs 2023.3.16 from Pypi on Windows x64.

Should I install something else (e.g. jetraw binaries)?

Installation on linux

I want to install the latest version on Linux. I have tried both ways.

  1. pip install imagecodecs
    It installs 2020.5.30 version, no matter what I do

  2. python setup.py install
    It tries to install the latest version(2021.3.31) but it throws an error.

Terminal output::

python setup.py install
running install
running bdist_egg
running egg_info
writing imagecodecs.egg-info/PKG-INFO
writing dependency_links to imagecodecs.egg-info/dependency_links.txt
writing entry points to imagecodecs.egg-info/entry_points.txt
writing requirements to imagecodecs.egg-info/requires.txt
writing top-level names to imagecodecs.egg-info/top_level.txt
reading manifest file 'imagecodecs.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no files found matching '3rdparty/'
warning: no files found matching 'tests/
.zfp'
warning: no files found matching 'tests/.tif'
warning: no previously-included files found matching 'tests/tiff/gray.movie.u1.tif'
warning: no previously-included files found matching 'tests/libaec/121B2TestData/ExtendedParameters/
.'
warning: no previously-included files found matching 'tests/33792x79872.jpg'
warning: no previously-included files found matching 'tests/jpegxr.czi'
warning: no previously-included files matching 'pycache' found under directory '
'
warning: no previously-included files matching '.py[co]' found under directory ''
warning: no previously-included files matching '-' found under directory ''
warning: no previously-included files matching '.html' found under directory ''
warning: no previously-included files matching 'Copy.' found under directory ''
writing manifest file 'imagecodecs.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_py
running build_ext
skipping 'imagecodecs/_aec.c' Cython extension (up-to-date)
skipping 'imagecodecs/_bitshuffle.c' Cython extension (up-to-date)
skipping 'imagecodecs/_blosc.c' Cython extension (up-to-date)
building 'imagecodecs._blosc' extension
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -Iimagecodecs -I/usr/include/python3.6m -I/usr/local/lib/python3.6/dist-packages/numpy/core/include -c imagecodecs/_blosc.c -o build/temp.linux-x86_64-3.6/imagecodecs/_blosc.o
In file included from /usr/local/lib/python3.6/dist-packages/numpy/core/include/numpy/ndarraytypes.h:1822:0,
from /usr/local/lib/python3.6/dist-packages/numpy/core/include/numpy/ndarrayobject.h:12,
from /usr/local/lib/python3.6/dist-packages/numpy/core/include/numpy/arrayobject.h:4,
from imagecodecs/_blosc.c:593:
/usr/local/lib/python3.6/dist-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
#warning "Using deprecated NumPy API, disable it with "
^
imagecodecs/_blosc.c:597:19: fatal error: blosc.h: No such file or directory
compilation terminated.
error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

Build fails: imagecodecs/_avif.c:3955:26: error: storage size of ‘__pyx_v_flags’ isn’t known

While building imagecodecs package for openSUSE/Tumbleweed (using Python 3.8 or 3.9, numpy 1.20.3) I got this build error:

[   52s] gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-o
[   53s] In file included from /usr/lib64/python3.9/site-packages/numpy/core/include/numpy/ndarraytypes,
[   53s]                  from /usr/lib64/python3.9/site-packages/numpy/core/include/numpy/ndarrayobjec,
[   53s]                  from /usr/lib64/python3.9/site-packages/numpy/core/include/numpy/arrayobject.,
[   53s]                  from imagecodecs/_aec.c:633:
[   53s] /usr/lib64/python3.9/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: war]
[   53s]    17 | #warning "Using deprecated NumPy API, disable it with " \
[   53s]       |  ^~~~~~~
[   53s] gcc -pthread -shared -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fo
[   55s] building 'imagecodecs._avif' extension
[   55s] gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-o
[   56s] In file included from /usr/lib64/python3.9/site-packages/numpy/core/include/numpy/ndarraytypes,
[   56s]                  from /usr/lib64/python3.9/site-packages/numpy/core/include/numpy/ndarrayobjec,
[   56s]                  from /usr/lib64/python3.9/site-packages/numpy/core/include/numpy/arrayobject.,
[   56s]                  from imagecodecs/_avif.c:636:
[   56s] /usr/lib64/python3.9/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: war]
[   56s]    17 | #warning "Using deprecated NumPy API, disable it with " \
[   56s]       |  ^~~~~~~
[   56s] imagecodecs/_avif.c: In function ‘__pyx_pf_11imagecodecs_5_avif_4avif_encode’:
[   56s] imagecodecs/_avif.c:3955:26: error: storage size of ‘__pyx_v_flags’ isn’t known
[   56s]  3955 |   enum avifAddImageFlags __pyx_v_flags;
[   56s]       |                          ^~~~~~~~~~~~~
[   56s] imagecodecs/_avif.c:3955:26: warning: unused variable ‘__pyx_v_flags’ [-Wunused-variable]
[   56s] error: command '/var/lib/build/ccache/bin/gcc' failed with exit code 1
[   56s] error: Bad exit status from /var/tmp/rpm-tmp.O5YKOv (%build)

Complete build log with list of all packages used and detailed steps to achieve this result.

[openSUSE] test_blosc_roundtrip pytest failed

Hello,

I am trying to update imagecodecs for openSUSE Tumbleweed https://build.opensuse.org/package/show/home:andythe_great:branches:devel:languages:python/python-imagecodecs

The test regarding blosc failed, I'm not sure what the issue could be.

The installed dependencies are as follows.

Full log here: https://build.opensuse.org/package/live_build_log/home:andythe_great:branches:devel:languages:python/python-imagecodecs/andythe_great_TW/x86_64

python3-Cython-0.29.21
python3-Pillow-7.2.0
python3-blosc-1.9.1
python3-lz4-3.0.2
python3-matplotlib-3.3.0
python3-numpy-devel-1.18.4
python3-pytest-5.4.3
python3-scikit-image-0.16.2
python3-tifffile-2020.5.30
python3-zstd-1.4.5
CharLS-devel-2.1.0
brunsli-devel-v0.1
giflib-devel-5.1.4
jxrlib-devel-1.1
libaec-devel-1.0.4
libbitstream1-1.4.1
libbrotli-devel
libjpeg62-62.3.0
libtiff-devel-4.1.0
libzopfli-devel-1.0.3
blosc-devel-1.19.0
bzip2-1.0.8
liblcms2-2-2.9
liblz4-devel-1.9.2
liblzma5-5.2.5
libopenjp2-7-2.3.1
libpng16-devel-1.6.37
libwebp-devel-1.1.0
libzstd-devel-1.4.5
zlib-devel-1.2.11
[  194s] =================================== FAILURES ===================================
[  194s] ________________ test_blosc_roundtrip[snappy-noshuffle-None-1] _________________
[  194s] 
[  194s] compressor = 'snappy', shuffle = 'noshuffle', level = None, numthreads = 1
[  194s] 
[  194s]     @pytest.mark.skipif(not imagecodecs.BLOSC, reason='blosc missing')
[  194s]     @pytest.mark.parametrize('numthreads', [1, 6])
[  194s]     @pytest.mark.parametrize('level', [None, 1])
[  194s]     @pytest.mark.parametrize('shuffle', ['noshuffle', 'shuffle', 'bitshuffle'])
[  194s]     @pytest.mark.parametrize('compressor', ['blosclz', 'lz4', 'lz4hc', 'snappy',
[  194s]                                             'zlib', 'zstd'])
[  194s]     def test_blosc_roundtrip(compressor, shuffle, level, numthreads):
[  194s]         """Test Blosc codec."""
[  194s]         encode = imagecodecs.blosc_encode
[  194s]         decode = imagecodecs.blosc_decode
[  194s]         data = numpy.random.randint(255, size=2021, dtype='uint8').tobytes()
[  194s] >       encoded = encode(data, level=level, compressor=compressor,
[  194s]                          shuffle=shuffle, numthreads=numthreads)
[  194s] 
[  194s] tests/test_imagecodecs.py:927: 
[  194s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  194s] 
[  194s] >   ???
[  194s] E   imagecodecs._blosc.BloscError: blosc_compress_ctx returned -5
[  194s] 
[  194s] imagecodecs\_blosc.pyx:136: BloscError
[  194s] ----------------------------- Captured stderr call -----------------------------
[  194s] Blosc has not been compiled with '(null)' compression support.  Please use one having it.
[  194s] ________________ test_blosc_roundtrip[snappy-noshuffle-None-6] _________________
[  194s] 
[  194s] compressor = 'snappy', shuffle = 'noshuffle', level = None, numthreads = 6
[  194s] 
[  194s]     @pytest.mark.skipif(not imagecodecs.BLOSC, reason='blosc missing')
[  194s]     @pytest.mark.parametrize('numthreads', [1, 6])
[  194s]     @pytest.mark.parametrize('level', [None, 1])
[  194s]     @pytest.mark.parametrize('shuffle', ['noshuffle', 'shuffle', 'bitshuffle'])
[  194s]     @pytest.mark.parametrize('compressor', ['blosclz', 'lz4', 'lz4hc', 'snappy',
[  194s]                                             'zlib', 'zstd'])
[  194s]     def test_blosc_roundtrip(compressor, shuffle, level, numthreads):
[  194s]         """Test Blosc codec."""
[  194s]         encode = imagecodecs.blosc_encode
[  194s]         decode = imagecodecs.blosc_decode
[  194s]         data = numpy.random.randint(255, size=2021, dtype='uint8').tobytes()
[  194s] >       encoded = encode(data, level=level, compressor=compressor,
[  194s]                          shuffle=shuffle, numthreads=numthreads)
[  194s] 
[  194s] tests/test_imagecodecs.py:927: 
[  194s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  194s] 
[  194s] >   ???
[  194s] E   imagecodecs._blosc.BloscError: blosc_compress_ctx returned -5
[  194s] 
[  194s] imagecodecs\_blosc.pyx:136: BloscError
[  194s] ----------------------------- Captured stderr call -----------------------------
[  194s] Blosc has not been compiled with '(null)' compression support.  Please use one having it.
[  194s] __________________ test_blosc_roundtrip[snappy-noshuffle-1-1] __________________
[  194s] 
[  194s] compressor = 'snappy', shuffle = 'noshuffle', level = 1, numthreads = 1
[  194s] 
[  194s]     @pytest.mark.skipif(not imagecodecs.BLOSC, reason='blosc missing')
[  194s]     @pytest.mark.parametrize('numthreads', [1, 6])
[  194s]     @pytest.mark.parametrize('level', [None, 1])
[  194s]     @pytest.mark.parametrize('shuffle', ['noshuffle', 'shuffle', 'bitshuffle'])
[  194s]     @pytest.mark.parametrize('compressor', ['blosclz', 'lz4', 'lz4hc', 'snappy',
[  194s]                                             'zlib', 'zstd'])
[  194s]     def test_blosc_roundtrip(compressor, shuffle, level, numthreads):
[  194s]         """Test Blosc codec."""
[  194s]         encode = imagecodecs.blosc_encode
[  194s]         decode = imagecodecs.blosc_decode
[  194s]         data = numpy.random.randint(255, size=2021, dtype='uint8').tobytes()
[  194s] >       encoded = encode(data, level=level, compressor=compressor,
[  194s]                          shuffle=shuffle, numthreads=numthreads)
[  194s] 
[  194s] tests/test_imagecodecs.py:927: 
[  194s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  194s] 
[  194s] >   ???
[  194s] E   imagecodecs._blosc.BloscError: blosc_compress_ctx returned -5
[  194s] 
[  194s] imagecodecs\_blosc.pyx:136: BloscError
[  194s] ----------------------------- Captured stderr call -----------------------------
[  194s] Blosc has not been compiled with '(null)' compression support.  Please use one having it.
[  194s] __________________ test_blosc_roundtrip[snappy-noshuffle-1-6] __________________
[  194s] 
[  194s] compressor = 'snappy', shuffle = 'noshuffle', level = 1, numthreads = 6
[  194s] 
[  194s]     @pytest.mark.skipif(not imagecodecs.BLOSC, reason='blosc missing')
[  194s]     @pytest.mark.parametrize('numthreads', [1, 6])
[  194s]     @pytest.mark.parametrize('level', [None, 1])
[  194s]     @pytest.mark.parametrize('shuffle', ['noshuffle', 'shuffle', 'bitshuffle'])
[  194s]     @pytest.mark.parametrize('compressor', ['blosclz', 'lz4', 'lz4hc', 'snappy',
[  194s]                                             'zlib', 'zstd'])
[  194s]     def test_blosc_roundtrip(compressor, shuffle, level, numthreads):
[  194s]         """Test Blosc codec."""
[  194s]         encode = imagecodecs.blosc_encode
[  194s]         decode = imagecodecs.blosc_decode
[  194s]         data = numpy.random.randint(255, size=2021, dtype='uint8').tobytes()
[  194s] >       encoded = encode(data, level=level, compressor=compressor,
[  194s]                          shuffle=shuffle, numthreads=numthreads)
[  194s] 
[  194s] tests/test_imagecodecs.py:927: 
[  194s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  194s] 
[  194s] >   ???
[  194s] E   imagecodecs._blosc.BloscError: blosc_compress_ctx returned -5
[  194s] 
[  194s] imagecodecs\_blosc.pyx:136: BloscError
[  194s] ----------------------------- Captured stderr call -----------------------------
[  194s] Blosc has not been compiled with '(null)' compression support.  Please use one having it.
[  194s] _________________ test_blosc_roundtrip[snappy-shuffle-None-1] __________________
[  194s] 
[  194s] compressor = 'snappy', shuffle = 'shuffle', level = None, numthreads = 1
[  194s] 
[  194s]     @pytest.mark.skipif(not imagecodecs.BLOSC, reason='blosc missing')
[  194s]     @pytest.mark.parametrize('numthreads', [1, 6])
[  194s]     @pytest.mark.parametrize('level', [None, 1])
[  194s]     @pytest.mark.parametrize('shuffle', ['noshuffle', 'shuffle', 'bitshuffle'])
[  194s]     @pytest.mark.parametrize('compressor', ['blosclz', 'lz4', 'lz4hc', 'snappy',
[  194s]                                             'zlib', 'zstd'])
[  194s]     def test_blosc_roundtrip(compressor, shuffle, level, numthreads):
[  194s]         """Test Blosc codec."""
[  194s]         encode = imagecodecs.blosc_encode
[  194s]         decode = imagecodecs.blosc_decode
[  194s]         data = numpy.random.randint(255, size=2021, dtype='uint8').tobytes()
[  194s] >       encoded = encode(data, level=level, compressor=compressor,
[  194s]                          shuffle=shuffle, numthreads=numthreads)
[  194s] 
[  194s] tests/test_imagecodecs.py:927: 
[  194s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  194s] 
[  194s] >   ???
[  194s] E   imagecodecs._blosc.BloscError: blosc_compress_ctx returned -5
[  194s] 
[  194s] imagecodecs\_blosc.pyx:136: BloscError
[  194s] ----------------------------- Captured stderr call -----------------------------
[  194s] Blosc has not been compiled with '(null)' compression support.  Please use one having it.
[  194s] _________________ test_blosc_roundtrip[snappy-shuffle-None-6] __________________
[  194s] 
[  194s] compressor = 'snappy', shuffle = 'shuffle', level = None, numthreads = 6
[  194s] 
[  194s]     @pytest.mark.skipif(not imagecodecs.BLOSC, reason='blosc missing')
[  194s]     @pytest.mark.parametrize('numthreads', [1, 6])
[  194s]     @pytest.mark.parametrize('level', [None, 1])
[  194s]     @pytest.mark.parametrize('shuffle', ['noshuffle', 'shuffle', 'bitshuffle'])
[  194s]     @pytest.mark.parametrize('compressor', ['blosclz', 'lz4', 'lz4hc', 'snappy',
[  194s]                                             'zlib', 'zstd'])
[  194s]     def test_blosc_roundtrip(compressor, shuffle, level, numthreads):
[  194s]         """Test Blosc codec."""
[  194s]         encode = imagecodecs.blosc_encode
[  194s]         decode = imagecodecs.blosc_decode
[  194s]         data = numpy.random.randint(255, size=2021, dtype='uint8').tobytes()
[  194s] >       encoded = encode(data, level=level, compressor=compressor,
[  194s]                          shuffle=shuffle, numthreads=numthreads)
[  194s] 
[  194s] tests/test_imagecodecs.py:927: 
[  194s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  194s] 
[  194s] >   ???
[  194s] E   imagecodecs._blosc.BloscError: blosc_compress_ctx returned -5
[  194s] 
[  194s] imagecodecs\_blosc.pyx:136: BloscError
[  194s] ----------------------------- Captured stderr call -----------------------------
[  194s] Blosc has not been compiled with '(null)' compression support.  Please use one having it.
[  194s] ___________________ test_blosc_roundtrip[snappy-shuffle-1-1] ___________________
[  194s] 
[  194s] compressor = 'snappy', shuffle = 'shuffle', level = 1, numthreads = 1
[  194s] 
[  194s]     @pytest.mark.skipif(not imagecodecs.BLOSC, reason='blosc missing')
[  194s]     @pytest.mark.parametrize('numthreads', [1, 6])
[  194s]     @pytest.mark.parametrize('level', [None, 1])
[  194s]     @pytest.mark.parametrize('shuffle', ['noshuffle', 'shuffle', 'bitshuffle'])
[  194s]     @pytest.mark.parametrize('compressor', ['blosclz', 'lz4', 'lz4hc', 'snappy',
[  194s]                                             'zlib', 'zstd'])
[  194s]     def test_blosc_roundtrip(compressor, shuffle, level, numthreads):
[  194s]         """Test Blosc codec."""
[  194s]         encode = imagecodecs.blosc_encode
[  194s]         decode = imagecodecs.blosc_decode
[  194s]         data = numpy.random.randint(255, size=2021, dtype='uint8').tobytes()
[  194s] >       encoded = encode(data, level=level, compressor=compressor,
[  194s]                          shuffle=shuffle, numthreads=numthreads)
[  194s] 
[  194s] tests/test_imagecodecs.py:927: 
[  194s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  194s] 
[  194s] >   ???
[  194s] E   imagecodecs._blosc.BloscError: blosc_compress_ctx returned -5
[  194s] 
[  194s] imagecodecs\_blosc.pyx:136: BloscError
[  194s] ----------------------------- Captured stderr call -----------------------------
[  194s] Blosc has not been compiled with '(null)' compression support.  Please use one having it.
[  194s] ___________________ test_blosc_roundtrip[snappy-shuffle-1-6] ___________________
[  194s] 
[  194s] compressor = 'snappy', shuffle = 'shuffle', level = 1, numthreads = 6
[  194s] 
[  194s]     @pytest.mark.skipif(not imagecodecs.BLOSC, reason='blosc missing')
[  194s]     @pytest.mark.parametrize('numthreads', [1, 6])
[  194s]     @pytest.mark.parametrize('level', [None, 1])
[  194s]     @pytest.mark.parametrize('shuffle', ['noshuffle', 'shuffle', 'bitshuffle'])
[  194s]     @pytest.mark.parametrize('compressor', ['blosclz', 'lz4', 'lz4hc', 'snappy',
[  194s]                                             'zlib', 'zstd'])
[  194s]     def test_blosc_roundtrip(compressor, shuffle, level, numthreads):
[  194s]         """Test Blosc codec."""
[  194s]         encode = imagecodecs.blosc_encode
[  194s]         decode = imagecodecs.blosc_decode
[  194s]         data = numpy.random.randint(255, size=2021, dtype='uint8').tobytes()
[  194s] >       encoded = encode(data, level=level, compressor=compressor,
[  194s]                          shuffle=shuffle, numthreads=numthreads)
[  194s] 
[  194s] tests/test_imagecodecs.py:927: 
[  194s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  194s] 
[  194s] >   ???
[  194s] E   imagecodecs._blosc.BloscError: blosc_compress_ctx returned -5
[  194s] 
[  194s] imagecodecs\_blosc.pyx:136: BloscError
[  194s] ----------------------------- Captured stderr call -----------------------------
[  194s] Blosc has not been compiled with '(null)' compression support.  Please use one having it.
[  194s] ________________ test_blosc_roundtrip[snappy-bitshuffle-None-1] ________________
[  194s] 
[  194s] compressor = 'snappy', shuffle = 'bitshuffle', level = None, numthreads = 1
[  194s] 
[  194s]     @pytest.mark.skipif(not imagecodecs.BLOSC, reason='blosc missing')
[  194s]     @pytest.mark.parametrize('numthreads', [1, 6])
[  194s]     @pytest.mark.parametrize('level', [None, 1])
[  194s]     @pytest.mark.parametrize('shuffle', ['noshuffle', 'shuffle', 'bitshuffle'])
[  194s]     @pytest.mark.parametrize('compressor', ['blosclz', 'lz4', 'lz4hc', 'snappy',
[  194s]                                             'zlib', 'zstd'])
[  194s]     def test_blosc_roundtrip(compressor, shuffle, level, numthreads):
[  194s]         """Test Blosc codec."""
[  194s]         encode = imagecodecs.blosc_encode
[  194s]         decode = imagecodecs.blosc_decode
[  194s]         data = numpy.random.randint(255, size=2021, dtype='uint8').tobytes()
[  194s] >       encoded = encode(data, level=level, compressor=compressor,
[  194s]                          shuffle=shuffle, numthreads=numthreads)
[  194s] 
[  194s] tests/test_imagecodecs.py:927: 
[  194s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  194s] 
[  194s] >   ???
[  194s] E   imagecodecs._blosc.BloscError: blosc_compress_ctx returned -5
[  194s] 
[  194s] imagecodecs\_blosc.pyx:136: BloscError
[  194s] ----------------------------- Captured stderr call -----------------------------
[  194s] Blosc has not been compiled with '(null)' compression support.  Please use one having it.
[  194s] ________________ test_blosc_roundtrip[snappy-bitshuffle-None-6] ________________
[  194s] 
[  194s] compressor = 'snappy', shuffle = 'bitshuffle', level = None, numthreads = 6
[  194s] 
[  194s]     @pytest.mark.skipif(not imagecodecs.BLOSC, reason='blosc missing')
[  194s]     @pytest.mark.parametrize('numthreads', [1, 6])
[  194s]     @pytest.mark.parametrize('level', [None, 1])
[  194s]     @pytest.mark.parametrize('shuffle', ['noshuffle', 'shuffle', 'bitshuffle'])
[  194s]     @pytest.mark.parametrize('compressor', ['blosclz', 'lz4', 'lz4hc', 'snappy',
[  194s]                                             'zlib', 'zstd'])
[  194s]     def test_blosc_roundtrip(compressor, shuffle, level, numthreads):
[  194s]         """Test Blosc codec."""
[  194s]         encode = imagecodecs.blosc_encode
[  194s]         decode = imagecodecs.blosc_decode
[  194s]         data = numpy.random.randint(255, size=2021, dtype='uint8').tobytes()
[  194s] >       encoded = encode(data, level=level, compressor=compressor,
[  194s]                          shuffle=shuffle, numthreads=numthreads)
[  194s] 
[  194s] tests/test_imagecodecs.py:927: 
[  194s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  194s] 
[  194s] >   ???
[  194s] E   imagecodecs._blosc.BloscError: blosc_compress_ctx returned -5
[  194s] 
[  194s] imagecodecs\_blosc.pyx:136: BloscError
[  194s] ----------------------------- Captured stderr call -----------------------------
[  194s] Blosc has not been compiled with '(null)' compression support.  Please use one having it.
[  194s] _________________ test_blosc_roundtrip[snappy-bitshuffle-1-1] __________________
[  194s] 
[  194s] compressor = 'snappy', shuffle = 'bitshuffle', level = 1, numthreads = 1
[  194s] 
[  194s]     @pytest.mark.skipif(not imagecodecs.BLOSC, reason='blosc missing')
[  194s]     @pytest.mark.parametrize('numthreads', [1, 6])
[  194s]     @pytest.mark.parametrize('level', [None, 1])
[  194s]     @pytest.mark.parametrize('shuffle', ['noshuffle', 'shuffle', 'bitshuffle'])
[  194s]     @pytest.mark.parametrize('compressor', ['blosclz', 'lz4', 'lz4hc', 'snappy',
[  194s]                                             'zlib', 'zstd'])
[  194s]     def test_blosc_roundtrip(compressor, shuffle, level, numthreads):
[  194s]         """Test Blosc codec."""
[  194s]         encode = imagecodecs.blosc_encode
[  194s]         decode = imagecodecs.blosc_decode
[  194s]         data = numpy.random.randint(255, size=2021, dtype='uint8').tobytes()
[  194s] >       encoded = encode(data, level=level, compressor=compressor,
[  194s]                          shuffle=shuffle, numthreads=numthreads)
[  194s] 
[  194s] tests/test_imagecodecs.py:927: 
[  194s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  194s] 
[  194s] >   ???
[  194s] E   imagecodecs._blosc.BloscError: blosc_compress_ctx returned -5
[  194s] 
[  194s] imagecodecs\_blosc.pyx:136: BloscError
[  194s] ----------------------------- Captured stderr call -----------------------------
[  194s] Blosc has not been compiled with '(null)' compression support.  Please use one having it.
[  194s] _________________ test_blosc_roundtrip[snappy-bitshuffle-1-6] __________________
[  194s] 
[  194s] compressor = 'snappy', shuffle = 'bitshuffle', level = 1, numthreads = 6
[  194s] 
[  194s]     @pytest.mark.skipif(not imagecodecs.BLOSC, reason='blosc missing')
[  194s]     @pytest.mark.parametrize('numthreads', [1, 6])
[  194s]     @pytest.mark.parametrize('level', [None, 1])
[  194s]     @pytest.mark.parametrize('shuffle', ['noshuffle', 'shuffle', 'bitshuffle'])
[  194s]     @pytest.mark.parametrize('compressor', ['blosclz', 'lz4', 'lz4hc', 'snappy',
[  194s]                                             'zlib', 'zstd'])
[  194s]     def test_blosc_roundtrip(compressor, shuffle, level, numthreads):
[  194s]         """Test Blosc codec."""
[  194s]         encode = imagecodecs.blosc_encode
[  194s]         decode = imagecodecs.blosc_decode
[  194s]         data = numpy.random.randint(255, size=2021, dtype='uint8').tobytes()
[  194s] >       encoded = encode(data, level=level, compressor=compressor,
[  194s]                          shuffle=shuffle, numthreads=numthreads)
[  194s] 
[  194s] tests/test_imagecodecs.py:927: 
[  194s] _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
[  194s] 
[  194s] >   ???
[  194s] E   imagecodecs._blosc.BloscError: blosc_compress_ctx returned -5
[  194s] 
[  194s] imagecodecs\_blosc.pyx:136: BloscError
[  194s] ----------------------------- Captured stderr call -----------------------------
[  194s] Blosc has not been compiled with '(null)' compression support.  Please use one having it.
[  194s] ___________________________ test_jpegxl_encode_jpeg ____________________________
[  194s] 
[  194s]     @pytest.mark.skipif(not imagecodecs.JPEGXL, reason='jpegxl missing')
[  194s]     def test_jpegxl_encode_jpeg():
[  194s]         """Test JPEG XL encoder with JPEG input."""
[  194s]         encode = imagecodecs.jpegxl_encode
[  194s]         decode = imagecodecs.jpegxl_decode
[  194s]         jpg = readfile('rgba.u1.jpg')
[  194s]         jxl = readfile('rgba.u1.jxl')
[  194s]     
[  194s]         assert imagecodecs.jpegxl_check(jpg) in (None, True)
[  194s]         assert imagecodecs.jpegxl_check(jxl) in (None, True)
[  194s]     
[  194s]         encoded = encode(jpg)
[  194s] >       assert encoded == jxl
[  194s] E       assert bytearray(b'\...x17\x1d\xfc#') == b'\n\x04B\xd2...\x93\xbf8\xea'
[  194s] E         At index 13 diff: 11 != 3
[  194s] E         Right contains one more item: 234
[  194s] E         Full diff:
[  194s] E         - (
[  194s] E         -  b'\n\x04B\xd2\xd5N\x12\x08\x08\x1f\x10 \x18\x03 \x00"\x92\x00\x1b@\x10Z\x06'
[  194s] E         ? ^                                              ^                  ----------
[  194s] E         + bytearray(b'\n\x04B\xd2\xd5N\x12\x08\x08\x1f\x10 \x18\x0b \x00"\x92\x00\x1b'...
[  194s] E         
[  194s] E         ...Full output truncated (100 lines hidden), use '-vv' to show
[  194s] 
[  194s] tests/test_imagecodecs.py:1293: AssertionError
[  194s] =========================== short test summary info ============================
[  194s] FAILED tests/test_imagecodecs.py::test_blosc_roundtrip[snappy-noshuffle-None-1]
[  194s] FAILED tests/test_imagecodecs.py::test_blosc_roundtrip[snappy-noshuffle-None-6]
[  194s] FAILED tests/test_imagecodecs.py::test_blosc_roundtrip[snappy-noshuffle-1-1]
[  194s] FAILED tests/test_imagecodecs.py::test_blosc_roundtrip[snappy-noshuffle-1-6]
[  194s] FAILED tests/test_imagecodecs.py::test_blosc_roundtrip[snappy-shuffle-None-1]
[  194s] FAILED tests/test_imagecodecs.py::test_blosc_roundtrip[snappy-shuffle-None-6]
[  194s] FAILED tests/test_imagecodecs.py::test_blosc_roundtrip[snappy-shuffle-1-1] - ...
[  194s] FAILED tests/test_imagecodecs.py::test_blosc_roundtrip[snappy-shuffle-1-6] - ...
[  194s] FAILED tests/test_imagecodecs.py::test_blosc_roundtrip[snappy-bitshuffle-None-1]
[  194s] FAILED tests/test_imagecodecs.py::test_blosc_roundtrip[snappy-bitshuffle-None-6]
[  194s] FAILED tests/test_imagecodecs.py::test_blosc_roundtrip[snappy-bitshuffle-1-1]
[  194s] FAILED tests/test_imagecodecs.py::test_blosc_roundtrip[snappy-bitshuffle-1-6]
[  194s] FAILED tests/test_imagecodecs.py::test_jpegxl_encode_jpeg - assert bytearray(...
[  194s] === 13 failed, 3167 passed, 1692 skipped, 1320 xfailed in 111.41s (0:01:51) ====

UnicodeDecodeError in imagecodecs.numcodecs

Hello @cgohlke,

I ran into a UnicodeDecodeError:

~/Environments/envs/pasu/lib/python3.8/site-packages/numcodecs/abc.py in __eq__(self, other)
    111         # override in sub-class if need special equality comparison
    112         try:
--> 113             return self.get_config() == other.get_config()
    114         except AttributeError:
    115             return False

~/Environments/envs/pasu/lib/python3.8/site-packages/imagecodecs/numcodecs.py in get_config(self)
    445                     import base64
    446 
--> 447                     value = base64.b64encode(value.decode())
    448                 config[key] = value
    449         return config

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

It occurs here:

if value is not None and key in ('header', 'tables'):
import base64
value = base64.b64encode(value.decode())
config[key] = value

And this change fixes it:

value = base64.b64encode(value).decode() 

Cheers,
Andreas 😃

Which codecs work with 3D or even N-Dimensional images?

Hi,

I have a lot of 3D medical and non-medical images and am currently experimenting with different compression codecs. However, I find it difficult to find information on which of the codecs also work for 3D or even ND images. I believe all or most codecs provided in the Numcodecs library work with ND images.
Do you know which of the other codecs provided in your library also work with 3D or ND images (e.g. JpegXL, Avif, and others)?

Best
Karol

Failing to build manylinux2014 AArch64 wheels

On AArch64 machine, pip installl imagecodecs tries to build the wheels from source code and fails with below error-

    /opt/_internal/cpython-3.8.12/lib/python3.8/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
       17 | #warning "Using deprecated NumPy API, disable it with " \
          |  ^~~~~~~
    imagecodecs/_blosc2.c:627:10: fatal error: blosc2.h: No such file or directory
      627 | #include "blosc2.h"
          |          ^~~~~~~~~~
    compilation terminated.
    error: command 'gcc' failed with exit status 1

@cgohlke, can you please let me know your interest in deploying AArch64 wheels on PyPI? Can you please point out your wheel builder? I would like to help in this.

Error in importing imagecodecs into colab to run program:imcd_lzw_decode returned IMCD_LZW_CORRUPT

I import imagecodecs package into colab to read all TIF images in a folder. When I read the 231st TIF image, I will report an error: IMCD_ lzw_ decode returned IMCD_ LZW_ .However, when reading a small number of images, no error will be reported. What is the reason for this?

At the same time, I modified the source code of detectron2 to process the data in TIF format, in which I also used the imagecodecs package. However, the training process can only be iterated about 150 times, and then an error is reported: imagecodecs/_ imcd.pyx in imagecodecs._ imcd.ImcdError .__ init__ ()
TypeError: __ init__ () takes exactly 3 positional arguments (2 given)

Are there any reliable suggestions?

Cannot Install Library using poetry

Build failed for the library, however installing the library with pip works, oddly.

imagecodecs_stacktrace_err.log

StackTrace logfile, uploaded on github. (Attached as link because github does not allow me to paste such a long trace)

Few lines of the trace :

gcc -pthread -B /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/compiler_compat -shared -Wl,--allow-shlib-undefined -Wl,-rpath,/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib -Wl,-rpath-link,/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib -L/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib -Wl,--allow-shlib-undefined -Wl,-rpath,/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib -Wl,-rpath-link,/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib -L/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib build/temp.linux-x86_64-cpython-311/imagecodecs/_deflate.o -lm -ldeflate -o build/lib.linux-x86_64-cpython-311/imagecodecs/_deflate.cpython-311-x86_64-linux-gnu.so
        building 'imagecodecs._gif' extension
        gcc -pthread -B /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/compiler_compat -DNDEBUG -fwrapv -O2 -Wall -fPIC -O2 -isystem /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/include -fPIC -O2 -isystem /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/include -fPIC -Iimagecodecs -I/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/include/python3.11 -I/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib/python3.11/site-packages/numpy/core/include -c imagecodecs/_gif.c -o build/temp.linux-x86_64-cpython-311/imagecodecs/_gif.o
        In file included from /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib/python3.11/site-packages/numpy/core/include/numpy/ndarraytypes.h:1948,
                         from /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib/python3.11/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
                         from /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib/python3.11/site-packages/numpy/core/include/numpy/arrayobject.h:5,
                         from imagecodecs/_gif.c:746:
        /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib/python3.11/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
           17 | #warning "Using deprecated NumPy API, disable it with " \
              |  ^~~~~~~
        gcc -pthread -B /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/compiler_compat -shared -Wl,--allow-shlib-undefined -Wl,-rpath,/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib -Wl,-rpath-link,/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib -L/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib -Wl,--allow-shlib-undefined -Wl,-rpath,/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib -Wl,-rpath-link,/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib -L/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib build/temp.linux-x86_64-cpython-311/imagecodecs/_gif.o -lm -lgif -o build/lib.linux-x86_64-cpython-311/imagecodecs/_gif.cpython-311-x86_64-linux-gnu.so
        building 'imagecodecs._heif' extension
        gcc -pthread -B /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/compiler_compat -DNDEBUG -fwrapv -O2 -Wall -fPIC -O2 -isystem /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/include -fPIC -O2 -isystem /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/include -fPIC -Iimagecodecs -I/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/include/python3.11 -I/home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib/python3.11/site-packages/numpy/core/include -c imagecodecs/_heif.c -o build/temp.linux-x86_64-cpython-311/imagecodecs/_heif.o
        In file included from /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib/python3.11/site-packages/numpy/core/include/numpy/ndarraytypes.h:1948,
                         from /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib/python3.11/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
                         from /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib/python3.11/site-packages/numpy/core/include/numpy/arrayobject.h:5,
                         from imagecodecs/_heif.c:746:
        /home/hello/work/anaconda3/envs/internal-python-api-services-py3.11/lib/python3.11/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: warning: #warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
           17 | #warning "Using deprecated NumPy API, disable it with " \
              |  ^~~~~~~
        imagecodecs/_heif.c: In function ‘__pyx_pf_11imagecodecs_5_heif_4heif_encode’:
        imagecodecs/_heif.c:5565:30: warning: implicit declaration of function ‘heif_nclx_color_profile_alloc’ [-Wimplicit-function-declaration]
         5565 |               __pyx_v_nclx = heif_nclx_color_profile_alloc();
              |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        imagecodecs/_heif.c:5565:28: warning: assignment to ‘struct heif_color_profile_nclx *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
         5565 |               __pyx_v_nclx = heif_nclx_color_profile_alloc();
              |                            ^
        imagecodecs/_heif.c:5692:30: error: ‘struct heif_encoding_options’ has no member named ‘output_nclx_profile’
         5692 |               __pyx_v_options->output_nclx_profile = __pyx_v_nclx;
              |                              ^~
        imagecodecs/_heif.c:7433:9: warning: implicit declaration of function ‘heif_nclx_color_profile_free’ [-Wimplicit-function-declaration]
         7433 |         heif_nclx_color_profile_free(__pyx_v_nclx);
              |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
        imagecodecs/_heif.c: In function ‘__pyx_pf_11imagecodecs_5_heif_6heif_decode’:
        imagecodecs/_heif.c:9306:44: warning: implicit declaration of function ‘heif_image_get_primary_width’; did you mean ‘heif_image_get_width’? [-Wimplicit-function-declaration]
         9306 |               __pyx_v_width = ((Py_ssize_t)heif_image_get_primary_width(__pyx_v_image));
              |                                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
              |                                            heif_image_get_width
        imagecodecs/_heif.c:9315:45: warning: implicit declaration of function ‘heif_image_get_primary_height’; did you mean ‘heif_image_get_height’? [-Wimplicit-function-declaration]
         9315 |               __pyx_v_height = ((Py_ssize_t)heif_image_get_primary_height(__pyx_v_image));
              |                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              |                                             heif_image_get_height
        imagecodecs/_heif.c: In function ‘__pyx_f_11imagecodecs_5_heif_heif_compression’:
        imagecodecs/_heif.c:11438:62: error: ‘heif_compression_AV1’ undeclared (first use in this function); did you mean ‘heif_compression_AVC’?
        11438 |   __pyx_t_4 = __Pyx_PyInt_From_enum__heif_compression_format(heif_compression_AV1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 751, __pyx_L1_error)
              |                                                              ^~~~~~~~~~~~~~~~~~~~
              |                                                              heif_compression_AVC
        imagecodecs/_heif.c:11438:62: note: each undeclared identifier is reported only once for each function it appears in
        imagecodecs/_heif.c: In function ‘__pyx_pymod_exec__heif’:
        imagecodecs/_heif.c:28738:62: error: ‘heif_compression_AV1’ undeclared (first use in this function); did you mean ‘heif_compression_AVC’?
        28738 |   __pyx_t_6 = __Pyx_PyInt_From_enum__heif_compression_format(heif_compression_AV1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 60, __pyx_L1_error)
              |                                                              ^~~~~~~~~~~~~~~~~~~~
              |                                                              heif_compression_AVC
        At top level:
        imagecodecs/_heif.c:12249:12: warning: ‘__pyx_f_11imagecodecs_5_heif_output_seek’ defined but not used [-Wunused-function]
        12249 | static int __pyx_f_11imagecodecs_5_heif_output_seek(__pyx_t_11imagecodecs_5_heif_output_t *__pyx_v_output, size_t __pyx_v_pos) {
              |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        error: command '/usr/bin/gcc' failed with exit code 1
        [end of output]

Kindly have a look and help if possible, @cgohlke

liblzf fails to build with mingw-w64

Could not build python-imagecodecs for mingw64 due to this error:

liblzf-3.6/lzf_c.c: In function 'lzf_compress':
liblzf-3.6/lzf_c.c:123:19: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'off'
  123 |   unsigned _int64 off; /* workaround for missing POSIX compliance */
      |                   ^~~
liblzf-3.6/lzf_c.c:123:19: error: 'off' undeclared (first use in this function)

I guess _int64 is MSVC only, so the test should either change to MSVC if that was the intention, or one should use a more standard uint64_t from stdint.h?

Think this is irrespective of whether imagecodecs/patches/python-lzf.diff is applied or not...

Numpy Missing During Setuptools

Hi there, I am having an issue where sometimes setuptools is running the finalize_options function but numpy is not installed yet:

...
File "/opt/python/3.7.1/lib/python3.7/distutils/cmd.py", line 107, in ensure_finalized
        self.finalize_options()
File "/tmp/pip-install-9ehdn6oz/imagecodecs/setup.py", line 600, in finalize_options
        import numpy
    ModuleNotFoundError: No module named 'numpy'

This appears to only happen on certain setups, perhaps just if pip tries to install imagecodecs before NumPy.

I found the recommendation to add numpy to setup_requires (see numpy/numpy#2434) in addition to install_requires but I see that you have commented this out here

# setup_requires=['setuptools>=18.0', 'numpy>=1.19.2'], # cython>=0.29.27

I just wanted to check if there is a reason it was commented out or if you have any advice to avoid this issue? I am currently just using a regular pip install from a requirements file.

openjpeg include dir mismatch

For version 2021.1.8, dependency openjpeg is upgraded to 2.4.0, but the include dir is not updated, check here

'/usr/include/openjpeg-2.3'

I could not build imagecodecs 2021.1.8 for ArchLinux due to mismatch include dir, see the complete build log here.

ljpeg (lj92.c) ge bug with example file

I have been working on trying to decode some ljpeg images from here
http://www.eng.usf.edu/cvprg/mammography/database.html

I spent some time with gdcm and your library with not much luck.
I have run their binary in linux and it decodes their files ok, it seems its an old a rare bug, but older medical scans seem to have it.
I feel that my skill set is not up to patching and compiling.
Unfortunately I am more comfortable in windows with precompiled

That being said, I think the key may be ~ line 555 of lj92.c or ~ line 560? of jpegsof3.cpp
decoding with jpegsof3_decode or ljpeg_decode both give same bad graduated pattern

Sample file with the pvrg patch they found
stanford.pvrg.jpeg.ge_solaris_combo.patch.zip
test1-ljpeg.zip

Error when build from source

I tried to build from source instead of run pip install (I used python setup.py install). But it failed and I don't know what to do
My pip version is 21.2.4 from python 3.8

Screenshot from 2021-09-07 12-32-59

zfp 1.0

Just flagging this here. zfp just released their 1.0 system and it seems like they moved some headers around causing builds to fail

conda-forge/imagecodecs-feedstock#62

I think you want to change bitstream.h to zfp/bitstream.h but I haven't studied change (if any) to the API orthe underlying structures.

KeyError: 'sources'

When building imagecodecs 2020.12.22 under MacPorts, I get the following error:

Executing: cd "/opt/local/var/macports/build/Users_marius_Development_MacPorts_ports_python_py-imagecodecs/py38-imagecodecs/work/imagecodecs-2020.12.22" && /opt/local/Library/Frameworks/Python.framework/Versions/3.8/bin/python3.8 setup.py --no-user-cfg build -j8
Traceback (most recent call last):
File "setup.py", line 509, in
ext_modules=[extension(name) for name in sorted(EXTENSIONS)],
File "setup.py", line 509, in
ext_modules=[extension(name) for name in sorted(EXTENSIONS)],
File "setup.py", line 460, in extension
sources=[f'imagecodecs/
{name}' + EXT] + ext['sources'],
KeyError: 'sources'

It looks like there was a rather significant rewrite of setup.py with this update. I haven't been able to trace the issue, but my guess is that that somehow the key 'sources' doesn't get defined.

fail to build release v2021.1.28 for ArchLinux

related log:

Traceback (most recent call last):
  File "/build/python-imagecodecs/src/imagecodecs-2021.1.28/setup.py", line 442, in <module>
    customize_build(EXTENSIONS, OPTIONS)
  File "/build/python-imagecodecs/src/imagecodecs-2021.1.28/setup.py", line 204, in customize_build_default
    EXTENSIONS['zopfli']['include_dirs'].append('/usr/include/zopfli')
KeyError: 'zopfli'

see also the complete build log here.

according to

imagecodecs/setup.py

Lines 190 to 204 in 926078f

if 'arch' in platform.platform():
del EXTENSIONS['zopfli'] # zopfli/zopfli.h does not exist
else:
del EXTENSIONS['jpegls'] # CharLS 2.1 library not commonly available
del EXTENSIONS['jpegxl'] # Brunsli library not commonly available
del EXTENSIONS['zfp'] # ZFP library not commonly available
if sys.platform == 'win32':
EXTENSIONS['bz2']['libraries'] = ['libbz2']
else:
EXTENSIONS['jpeg2k']['include_dirs'].extend(
('/usr/include/openjpeg-2.3', '/usr/include/openjpeg-2.4')
)
EXTENSIONS['jpegxr']['include_dirs'].append('/usr/include/jxrlib')
EXTENSIONS['zopfli']['include_dirs'].append('/usr/include/zopfli')

key zopfli is deleted when platform is ArchLinux, and but it uses this key later.
Actually, there is a zopfli pkg in ArchLinux, installed file lists:

usr/
usr/bin/
usr/bin/zopfli
usr/bin/zopflipng
usr/include/
usr/include/zopfli.h
usr/include/zopflipng_lib.h
usr/lib/
usr/lib/cmake/
usr/lib/cmake/Zopfli/
usr/lib/cmake/Zopfli/ZopfliConfig-release.cmake
usr/lib/cmake/Zopfli/ZopfliConfig.cmake
usr/lib/cmake/Zopfli/ZopfliConfigVersion.cmake
usr/lib/libzopfli.so
usr/lib/libzopfli.so.1
usr/lib/libzopfli.so.1.0.3
usr/lib/libzopflipng.so
usr/lib/libzopflipng.so.1
usr/lib/libzopflipng.so.1.0.3
usr/share/
usr/share/doc/
usr/share/doc/zopfli/
usr/share/doc/zopfli/README
usr/share/doc/zopfli/README.zopflipng

see also this issue #10, any plan to improve zopfli header search?

Feature Request: HEVC/H.265 Support

It would be nice to have support for other HEIF codecs in addition to the AVIF support that is already in place. I see that there are a few libraries which may be useful for this:

  • libde265
  • libheif which uses libde265
  • ffmpeg (which is using a fork of libde265)

I have also been trying to figure out if these would also work with hardware acceleration, e.g. with Intel CPUs, but I am a little unclear on this. There is some useful information on the Arch wiki here https://wiki.archlinux.org/title/Hardware_video_acceleration.

Thank you for putting together this package. It's been incredibly useful.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.