Code Monkey home page Code Monkey logo

pillow_heif's People

Contributors

andrey18106 avatar aptalca avatar bigcat88 avatar jarikf avatar mara004 avatar pre-commit-ci[bot] avatar renovate[bot] avatar zerolab 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

pillow_heif's Issues

Opacity information is lost when reading a P mode image with transparency information

Describe the bug

If you have a PNG image with mode P and a custom transparency value, opacity information is lost when you convert to HEIC.

Steps/Code to Reproduce

from PIL import Image, ImageDraw
from pillow_heif import register_heif_opener

register_heif_opener()

# Draw a basic checkerboard image
im = Image.new("P", size=(100, 100))

draw = ImageDraw.Draw(im)
draw.rectangle(xy=[(0, 0),   (50, 50)],   fill=255)
draw.rectangle(xy=[(50, 50), (100, 100)], fill=255)

# Save the image as a PNG, marking the 0'th colour in the palette as transparent
im.save("checkerboard.png", transparency=0)

# Open the image, then save it as an AVIF
opened_im = Image.open("checkerboard.png")
opened_im.save("checkerboard.heic", transparency=0)

Expected Results

An image with a simple 2×2 checkerboard pattern, with transparent squares in the bottom left and top right.

Actual Results

The HEIC is rendered as a solid black image, losing the transparency from the PNG.

Screenshot 2024-04-29 at 22 39 05

Versions

3.11.8 (v3.11.8:db85d51d3e, Feb  6 2024, 18:02:37) [Clang 13.0.0 (clang-1300.0.29.30)]
macOS-13.6.6-x86_64-i386-64bit
0.16.0
{'libheif': '1.17.6', 'HEIF': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'AVIF': 'AOMedia Project AV1 Encoder 3.8.1', 'encoders': {'x265': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'aom': 'AOMedia Project AV1 Encoder 3.8.1', 'mask': 'mask'}, 'decoders': {'libde265': 'libde265 HEVC decoder, version 1.0.15', 'aom': 'AOMedia Project AV1 Decoder 3.8.1'}}

Issue installing on Arm based Mac OS

Using Python 3.8, Mac OS 12.0.1, M1 Max

Following the instructions,

Step One Output

➜  appsnacks git:(main) ✗ brew install libffi libheif
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> New Formulae
atmos                 fisher                luau                  rizin                 tfmigrate
btop                  git-branchless        mt32emu               rustfmt               tfproviderlint
cava                  java-service-wrapper  [email protected]               smug                  urlwatch
cgif                  kubeval               pip-tools             swiftplantuml
fastfec               libsoup@2             regula                symengine
==> Updated Formulae
Updated 1026 formulae.
==> Renamed Formulae
rt-audio -> rtaudio
==> Deleted Formulae
amap                                                    soundpipe

Warning: libffi 3.4.2 is already installed and up-to-date.
To reinstall 3.4.2, run:
  brew reinstall libffi
Warning: libheif 1.12.0_1 is already installed and up-to-date.
To reinstall 1.12.0_1, run:
  brew reinstall libheif

Step Two Output

➜  appsnacks git:(main) ✗ pip3 install --upgrade pillow_heif
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: pillow_heif in /Users/bob/Library/Python/3.8/lib/python/site-packages (0.1.3)
Collecting pillow_heif
  Using cached pillow_heif-0.1.4.tar.gz (19.5 MB)
  WARNING: Value for prefixed-purelib does not match. Please report this to <https://github.com/pypa/pip/issues/10151>
  distutils: /private/var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/pip-build-env-w5pe9h5e/normal/lib/python3.8/site-packages
  sysconfig: /Library/Python/3.8/site-packages
  WARNING: Value for prefixed-platlib does not match. Please report this to <https://github.com/pypa/pip/issues/10151>
  distutils: /private/var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/pip-build-env-w5pe9h5e/normal/lib/python3.8/site-packages
  sysconfig: /Library/Python/3.8/site-packages
  WARNING: Additional context:
  user = False
  home = None
  root = None
  prefix = '/private/var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/pip-build-env-w5pe9h5e/normal'
  WARNING: Value for prefixed-purelib does not match. Please report this to <https://github.com/pypa/pip/issues/10151>
  distutils: /private/var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/pip-build-env-w5pe9h5e/overlay/lib/python3.8/site-packages
  sysconfig: /Library/Python/3.8/site-packages
  WARNING: Value for prefixed-platlib does not match. Please report this to <https://github.com/pypa/pip/issues/10151>
  distutils: /private/var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/pip-build-env-w5pe9h5e/overlay/lib/python3.8/site-packages
  sysconfig: /Library/Python/3.8/site-packages
  WARNING: Additional context:
  user = False
  home = None
  root = None
  prefix = '/private/var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/pip-build-env-w5pe9h5e/overlay'
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... done
Requirement already satisfied: Pillow in /Users/bob/Library/Python/3.8/lib/python/site-packages (from pillow_heif) (8.4.0)
Requirement already satisfied: cffi>=1.0.0 in /Users/bob/Library/Python/3.8/lib/python/site-packages (from pillow_heif) (1.15.0)
Requirement already satisfied: pycparser in /Users/bob/Library/Python/3.8/lib/python/site-packages (from cffi>=1.0.0->pillow_heif) (2.20)
Building wheels for collected packages: pillow-heif
  Building wheel for pillow-heif (pyproject.toml) ... error
  ERROR: Command errored out with exit status 1:
   command: /Applications/Xcode.app/Contents/Developer/usr/bin/python3 /Users/bob/Library/Python/3.8/lib/python/site-packages/pip/_vendor/pep517/in_process/_in_process.py build_wheel /var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/tmpojyt2acz
       cwd: /private/var/folders/jp/t829x8110sl6tz4blxxd9_w00000gn/T/pip-install-bbaa9mji/pillow-heif_3ee714bb207345d0b75a1aa30b9915f3
  Complete output (24 lines):
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.macosx-10.14-arm64-3.8
  creating build/lib.macosx-10.14-arm64-3.8/pillow_heif
  copying pillow_heif/error.py -> build/lib.macosx-10.14-arm64-3.8/pillow_heif
  copying pillow_heif/as_opener.py -> build/lib.macosx-10.14-arm64-3.8/pillow_heif
  copying pillow_heif/constants.py -> build/lib.macosx-10.14-arm64-3.8/pillow_heif
  copying pillow_heif/__init__.py -> build/lib.macosx-10.14-arm64-3.8/pillow_heif
  copying pillow_heif/reader.py -> build/lib.macosx-10.14-arm64-3.8/pillow_heif
  copying pillow_heif/writer.py -> build/lib.macosx-10.14-arm64-3.8/pillow_heif
  running build_ext
  generating cffi module 'build/temp.macosx-10.14-arm64-3.8/pillow_heif._libheif.c'
  creating build/temp.macosx-10.14-arm64-3.8
  building 'pillow_heif._libheif' extension
  creating build/temp.macosx-10.14-arm64-3.8/build
  creating build/temp.macosx-10.14-arm64-3.8/build/temp.macosx-10.14-arm64-3.8
  clang -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -iwithsysroot/System/Library/Frameworks/System.framework/PrivateHeaders -iwithsysroot/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/Headers -arch arm64 -arch x86_64 -Werror=implicit-function-declaration -I/usr/local/include -I/usr/include -I/opt/local/include -I/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/include/python3.8 -c build/temp.macosx-10.14-arm64-3.8/pillow_heif._libheif.c -o build/temp.macosx-10.14-arm64-3.8/build/temp.macosx-10.14-arm64-3.8/pillow_heif._libheif.o
  build/temp.macosx-10.14-arm64-3.8/pillow_heif._libheif.c:570:15: fatal error: 'libheif/heif.h' file not found
       #include "libheif/heif.h"
                ^~~~~~~~~~~~~~~~
  1 error generated.
  error: command 'clang' failed with exit status 1
  ----------------------------------------
  ERROR: Failed building wheel for pillow-heif
Failed to build pillow-heif
ERROR: Could not build wheels for pillow-heif, which is required to install pyproject.toml-based projects

Depth Images support

In this commit I have added an example of such heic file taken on iPhone.

Here is the primary image:

pug

Here is the depth image:

test-depth

Here is an Aux image(urn/apple_photo/2020/aux/hdrgainmap):

test-urn_com_apple_photo_2020_aux_hdrgainmap

Does anyone need the opportunity to read them?

Benchmarks thread

After this issue #53 and as this project comes closer to final stage, wrote small tests, and will post them here for now.

Hardware: mac Mini M1 and Intel 10900k.
When benchmarking version 0.9.0 I set default number of decode threads to 8(for clarity), other versions do not support this parameter, but libheif defaults it to 4.

There was a bug in libheif, when it was compiled with Cmake it had turned off multithreading and was working in single threaded mode. That was fixed in new upcoming release and you can see it on graphs(0.5.1 for Linux has no this bug, 0.6.0 has).

Temporary code that was written today:

import sys
from subprocess import run
from time import perf_counter


def measure_decode(image, n_iterations):
    cmd = f"{sys.executable} {__file__} {n_iterations} {image}".split()
    start_time = perf_counter()
    run(cmd, check=True)
    total_time = perf_counter() - start_time
    return total_time / n_iterations


if __name__ == "__main__":
    from PIL import Image
    from pillow_heif import register_heif_opener, __version__


    _args = {}
    if __version__ != "0.1.6":
        _args["decode_threads"] = 8
    register_heif_opener(**_args)
    for i in range(int(sys.argv[1])):
        im = Image.open(sys.argv[2])
        im.load()
    sys.exit(0)

Two test images was taken from that issue and from this repo i took cat.hif (HDR image, with 2 thumbnails)

Image decode results
results_Linux
results_macOS
results_Windows

crash during encoding when using with cv2 [macOS]

Describe the bug

This program will crash on my iMac:

Steps/Code to Reproduce

from PIL import Image
import cv2
from pillow_heif import register_heif_opener


register_heif_opener()

with Image.open("10003860486.jpg") as img:
    img.load()
img.save("2.heic")

Expected Results

No crash

Actual Results

    10739 segmentation fault 

I am on Mac. Note that if I remove the line import cv2, or if I move it after from pillow_heif import register_heif_opener, then the program runs normally.

Versions

{'version': {'libheif': '1.14.2', 'x265': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'aom': 'AOMedia Project AV1 Encoder 3.5.0'}, 'decoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}, 'encoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}}

Armv7 support

Describe why it is important and where it will be useful

Needed for install on Raspberry Pi OS 32bit (Debian 11)

Describe your proposed solution

Wheels for arm 32bit architecture.

Describe alternatives you've considered, if relevant

No response

Additional context

No response

After decoding Image dimensions not equal the one in the headers

Discussed in #85

Originally posted by Soooda March 17, 2023
Hello all,

I tried to convert some of my HIF images into JPGs and found some of the images were throwing the below error:

ValueError: corrupted image(dimensions in header: (7008, 4672), decoded dimensions: (4672, 7008)

The root cause was that I had applied rotation to my images and on the IOS system, the rotation was applied to the EXIF rather than the image data itself.

image

I made use of exif_transpose() to compensate for that. But the error is still popping up. It looks like pillow_heif does not support exif_transpose() and I wonder if this is an intended behaviour?

from PIL import Image, ImageOps
from pillow_heif import register_heif_opener

register_heif_opener()

def save_jpg(path, quality=100, subsampling=0):
    temp, _ = path.split(".")
    temp += ".jpg"

    im = Image.open(path)
    im = ImageOps.exif_transpose(im)

    print(f"Saving to {temp}")
    im.save(temp, quality=quality, subsampling=subsampling)

# for filename in sys.argv[1:]:
#     save_jpg(filename)

name = "DSC03260.HIF"
save_jpg(name)

pillow-heif doubling filesize during PyInstaller Build

Describe the bug

My sv-dlp project started using pillow-heif (0.5.1) on its latest version (2022.07.30). Turns out compiling it with pillow-heif on a (GitHub Actions) Linux environment doubles the size from 26.6MB to 43.7MB.
I tried using UPX, installing the required system modules that (libaom, libde265, libx265), but it was still doubling the size for whatever reason.

Weird thing is, Windows (19.8MB -> 24.7MB) and MacOS (23.4MB -> 31.6MB) builds don't seem seriously affected by this, but still rises.

Below I'll leave a sample of my build script, requirements file, and the build results comparison using a WSL Arch environment

Steps/Code to Reproduce

I honestly don't know what to put here so I'll just put my build.py script

import PyInstaller.__main__
import platform

SYS_OS = platform.system()
SYS_ARCH = platform.architecture()[0][:2]
suffix = f"{'_macos' if SYS_OS == 'Darwin' else ''}{'_x86' if SYS_ARCH == '32' else ''}{'.exe' if SYS_OS == 'Windows' else ''}"

def main():
    opts = [
        'sv-dlp/__main__.py',
        '--onefile',
        f'--name=sv-dlp{suffix}'
    ]

    print(f"Building sv-dlp for platform {SYS_OS} with architecture {SYS_ARCH}")
    PyInstaller.__main__.run(opts)

if __name__ == '__main__':
    main()
altgraph==0.17.2
certifi==2022.6.15
charset-normalizer==2.1.0
colorama==0.4.5
future==0.18.2
idna==3.3
pefile==2021.9.3
Pillow==9.2.0
pillow-heif==0.5.1
pyinstaller==4.10
pyinstaller-hooks-contrib==2022.3
pylance==0.0.1
pyproj==3.3.1
pywin32-ctypes==0.2.0
requests==2.28.1
tqdm==4.64.0
urllib3==1.26.11
protobuf==4.21.4
pycryptodome==3.15.0
sudo apt-get install libaom0 libde265-0 libx265-179 # ubuntu
sudo pacman -S aom libde265 x265 # arch

Expected Results

Before installing pillow-heif

Building sv-dlp for platform Linux with architecture 64
84 INFO: PyInstaller: 4.10
84 INFO: Python: 3.10.5
85 INFO: Platform: Linux-5.10.16.3-microsoft-standard-WSL2-x86_64-with-glibc2.35
87 INFO: wrote /mnt/f/code/sv-dlp/sv-dlp.spec
89 INFO: UPX is available.
96 INFO: Extending PYTHONPATH with paths
['/mnt/f/code/sv-dlp/sv-dlp']
270 INFO: checking Analysis
271 INFO: Building Analysis because Analysis-00.toc is non existent
271 INFO: Initializing module dependency graph...
275 INFO: Caching module graph hooks...
279 INFO: Analyzing base_library.zip ...
3053 INFO: Caching module dependency graph...
3189 INFO: running Analysis Analysis-00.toc
3204 INFO: Analyzing /mnt/f/code/sv-dlp/sv-dlp/__main__.py
3271 INFO: Processing pre-safe import module hook urllib3.packages.six.moves from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/pre_safe_import_module/hook-urllib3.packages.six.moves.py'.
5354 INFO: Processing pre-find module path hook distutils from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/pre_find_module_path/hook-distutils.py'.
5371 INFO: distutils: retargeting to non-venv dir '/usr/lib/python3.10'
5776 INFO: Processing pre-safe import module hook win32com from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/pre_safe_import_module/hook-win32com.py'.
6751 INFO: Processing pre-find module path hook site from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/pre_find_module_path/hook-site.py'.
6752 INFO: site: retargeting to fake-dir '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/fake-modules'
7233 INFO: Processing module hooks...
7233 INFO: Loading module hook 'hook-pyproj.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7239 INFO: Loading module hook 'hook-appdirs.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7240 INFO: Loading module hook 'hook-cryptography.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7398 INFO: Loading module hook 'hook-pycparser.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7398 INFO: Loading module hook 'hook-Crypto.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7401 INFO: Loading module hook 'hook-certifi.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7402 INFO: Loading module hook 'hook-jaraco.text.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7403 INFO: Loading module hook 'hook-heapq.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7404 INFO: Loading module hook 'hook-pickle.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7405 INFO: Loading module hook 'hook-distutils.util.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7406 INFO: Loading module hook 'hook-setuptools.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7424 INFO: Loading module hook 'hook-distutils.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7432 INFO: Loading module hook 'hook-multiprocessing.util.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7433 INFO: Loading module hook 'hook-lib2to3.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7444 INFO: Loading module hook 'hook-xml.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7476 INFO: Loading module hook 'hook-difflib.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7477 INFO: Loading module hook 'hook-packaging.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7477 INFO: Loading module hook 'hook-PIL.Image.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7743 INFO: Loading module hook 'hook-PIL.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7750 INFO: Loading module hook 'hook-encodings.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7803 INFO: Loading module hook 'hook-pkg_resources.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7851 WARNING: Hidden import "pkg_resources.py2_warn" not found!
7852 WARNING: Hidden import "pkg_resources.markers" not found!
7852 WARNING: Hidden import "pkg_resources._vendor.jaraco.functools" not found!
7852 WARNING: Hidden import "pkg_resources._vendor.jaraco.context" not found!
7852 WARNING: Hidden import "pkg_resources._vendor.jaraco.text" not found!
7853 INFO: Loading module hook 'hook-sysconfig.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7853 INFO: Loading module hook 'hook-PIL.ImageFilter.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7854 INFO: Loading module hook 'hook-PIL.SpiderImagePlugin.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7856 INFO: Loading module hook 'hook-setuptools.msvc.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7856 INFO: Loading module hook 'hook-_tkinter.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.10/tkinter/__init__.py", line 37, in <module>
    import _tkinter # If this fails your Python may not be configured for Tk
ImportError: libtk8.6.so: cannot open shared object file: No such file or directory
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: libtk8.6.so: cannot open shared object file: No such file or directory
7903 ERROR: Tcl/Tk improperly installed on this system.
7916 INFO: Looking for ctypes DLLs
7936 INFO: Analyzing run-time hooks ...
7940 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_subprocess.py'
7941 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_pkgutil.py'
7943 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_multiprocessing.py'
7945 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_inspect.py'
7945 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_pkgres.py'
7948 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/rthooks/pyi_rth_pyproj.py'
7955 INFO: Looking for dynamic libraries
8238 WARNING: Cannot find libmpdec.so.3 (needed by /usr/lib/python3.10/lib-dynload/_decimal.cpython-310-x86_64-linux-gnu.so)
8477 WARNING: Cannot find libwebp-a2d91712.so.7.1.3 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libwebpdemux-df590b8f.so.2.0.9)
8481 WARNING: Cannot find libwebp-a2d91712.so.7.1.3 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libwebpmux-625e1d4a.so.3.0.8)
8494 WARNING: Cannot find libXau-154567c4.so.6.0.0 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libxcb-4971137c.so.1.1.0)
8512 WARNING: Cannot find liblzma-96284f0d.so.5.2.5 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libtiff-f706b4a5.so.5.8.0)
8512 WARNING: Cannot find libjpeg-a4c3d5e9.so.62.3.0 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libtiff-f706b4a5.so.5.8.0)
ldd: warning: you do not have execution permission for `/usr/lib/libgcc_s.so.1'
8529 WARNING: Cannot find libsqlite3-e6e8c34c.so.0.8.6 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libproj-3a67288e.so.22.2.0)
8529 WARNING: Cannot find libtiff-40073f1f.so.5.7.0 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libproj-3a67288e.so.22.2.0)
8529 WARNING: Cannot find libcurl-c54b2682.so.4.7.0 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libproj-3a67288e.so.22.2.0)
8538 WARNING: Cannot find libnghttp2-62f02794.so.14.20.1 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libcurl-c54b2682.so.4.7.0)
8542 INFO: Looking for eggs
8542 INFO: Using Python library /usr/lib/libpython3.10.so.1.0
8548 INFO: Warnings written to /mnt/f/code/sv-dlp/build/sv-dlp/warn-sv-dlp.txt
8608 INFO: Graph cross-reference written to /mnt/f/code/sv-dlp/build/sv-dlp/xref-sv-dlp.html
8634 INFO: checking PYZ
8635 INFO: Building PYZ because PYZ-00.toc is non existent
8635 INFO: Building PYZ (ZlibArchive) /mnt/f/code/sv-dlp/build/sv-dlp/PYZ-00.pyz
9235 INFO: Building PYZ (ZlibArchive) /mnt/f/code/sv-dlp/build/sv-dlp/PYZ-00.pyz completed successfully.
9247 INFO: checking PKG
9248 INFO: Building PKG because PKG-00.toc is non existent
9248 INFO: Building PKG (CArchive) sv-dlp.pkg
19969 INFO: Building PKG (CArchive) sv-dlp.pkg completed successfully.
19975 INFO: Bootloader /home/juan/.local/lib/python3.10/site-packages/PyInstaller/bootloader/Linux-64bit-intel/run
19975 INFO: checking EXE
19976 INFO: Building EXE because EXE-00.toc is non existent
19976 INFO: Building EXE from EXE-00.toc
19977 INFO: Copying bootloader EXE to /mnt/f/code/sv-dlp/dist/sv-dlp
19980 INFO: Appending PKG archive to custom ELF section in EXE
21227 INFO: Building EXE from EXE-00.toc completed successfully.

Actual Results

After installing pillow-heif

Building sv-dlp for platform Linux with architecture 64
84 INFO: PyInstaller: 4.10
84 INFO: Python: 3.10.5
84 INFO: Platform: Linux-5.10.16.3-microsoft-standard-WSL2-x86_64-with-glibc2.35
86 INFO: wrote /mnt/f/code/sv-dlp/sv-dlp.spec
88 INFO: UPX is available.
95 INFO: Extending PYTHONPATH with paths
['/mnt/f/code/sv-dlp/sv-dlp']
260 INFO: checking Analysis
261 INFO: Building Analysis because Analysis-00.toc is non existent
261 INFO: Initializing module dependency graph...
264 INFO: Caching module graph hooks...
269 INFO: Analyzing base_library.zip ...
2932 INFO: Caching module dependency graph...
3073 INFO: running Analysis Analysis-00.toc
3086 INFO: Analyzing /mnt/f/code/sv-dlp/sv-dlp/__main__.py
3154 INFO: Processing pre-safe import module hook urllib3.packages.six.moves from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/pre_safe_import_module/hook-urllib3.packages.six.moves.py'.
5214 INFO: Processing pre-find module path hook distutils from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/pre_find_module_path/hook-distutils.py'.
5231 INFO: distutils: retargeting to non-venv dir '/usr/lib/python3.10'
5628 INFO: Processing pre-safe import module hook win32com from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/pre_safe_import_module/hook-win32com.py'.
6645 INFO: Processing pre-find module path hook site from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/pre_find_module_path/hook-site.py'.
6645 INFO: site: retargeting to fake-dir '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/fake-modules'
7126 INFO: Processing module hooks...
7126 INFO: Loading module hook 'hook-pyproj.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7131 INFO: Loading module hook 'hook-appdirs.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7132 INFO: Loading module hook 'hook-cryptography.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7292 INFO: Loading module hook 'hook-pycparser.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7292 INFO: Loading module hook 'hook-Crypto.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7295 INFO: Loading module hook 'hook-certifi.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7296 INFO: Loading module hook 'hook-jaraco.text.py' from '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/stdhooks'...
7297 INFO: Loading module hook 'hook-heapq.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7298 INFO: Loading module hook 'hook-pickle.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7299 INFO: Loading module hook 'hook-distutils.util.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7300 INFO: Loading module hook 'hook-setuptools.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7318 INFO: Loading module hook 'hook-distutils.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7326 INFO: Loading module hook 'hook-multiprocessing.util.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7327 INFO: Loading module hook 'hook-lib2to3.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7337 INFO: Loading module hook 'hook-xml.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7369 INFO: Loading module hook 'hook-difflib.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7371 INFO: Loading module hook 'hook-packaging.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7371 INFO: Loading module hook 'hook-PIL.Image.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7643 INFO: Loading module hook 'hook-PIL.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7650 INFO: Loading module hook 'hook-encodings.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7703 INFO: Loading module hook 'hook-pkg_resources.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7752 WARNING: Hidden import "pkg_resources.py2_warn" not found!
7752 WARNING: Hidden import "pkg_resources.markers" not found!
7752 WARNING: Hidden import "pkg_resources._vendor.jaraco.functools" not found!
7752 WARNING: Hidden import "pkg_resources._vendor.jaraco.context" not found!
7752 WARNING: Hidden import "pkg_resources._vendor.jaraco.text" not found!
7754 INFO: Loading module hook 'hook-sysconfig.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7754 INFO: Loading module hook 'hook-PIL.ImageFilter.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7755 INFO: Loading module hook 'hook-PIL.SpiderImagePlugin.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7756 INFO: Loading module hook 'hook-setuptools.msvc.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
7757 INFO: Loading module hook 'hook-_tkinter.py' from '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks'...
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.10/tkinter/__init__.py", line 37, in <module>
    import _tkinter # If this fails your Python may not be configured for Tk
ImportError: libtk8.6.so: cannot open shared object file: No such file or directory
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: libtk8.6.so: cannot open shared object file: No such file or directory
7802 ERROR: Tcl/Tk improperly installed on this system.
7815 INFO: Looking for ctypes DLLs
7835 INFO: Analyzing run-time hooks ...
7838 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_subprocess.py'
7839 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_pkgutil.py'
7842 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_multiprocessing.py'
7843 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_inspect.py'
7844 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/PyInstaller/hooks/rthooks/pyi_rth_pkgres.py'
7846 INFO: Including run-time hook '/home/juan/.local/lib/python3.10/site-packages/_pyinstaller_hooks_contrib/hooks/rthooks/pyi_rth_pyproj.py'
7853 INFO: Looking for dynamic libraries
8096 WARNING: Cannot find libmpdec.so.3 (needed by /usr/lib/python3.10/lib-dynload/_decimal.cpython-310-x86_64-linux-gnu.so)
ldd: warning: you do not have execution permission for `/usr/lib/libgcc_s.so.1'
8345 WARNING: Cannot find libaom-0a65f09e.so.3.4.0 (needed by /home/juan/.local/lib/python3.10/site-packages/pillow_heif.libs/libheif-308f5ff2.so.1.12.0)
8345 WARNING: Cannot find libde265-f493bf68.so.0.1.1 (needed by /home/juan/.local/lib/python3.10/site-packages/pillow_heif.libs/libheif-308f5ff2.so.1.12.0)
8345 WARNING: Cannot find libx265-a25050ad.so.204 (needed by /home/juan/.local/lib/python3.10/site-packages/pillow_heif.libs/libheif-308f5ff2.so.1.12.0)
8370 WARNING: Cannot find libwebp-a2d91712.so.7.1.3 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libwebpmux-625e1d4a.so.3.0.8)
8374 WARNING: Cannot find libwebp-a2d91712.so.7.1.3 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libwebpdemux-df590b8f.so.2.0.9)
8383 WARNING: Cannot find liblzma-96284f0d.so.5.2.5 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libtiff-f706b4a5.so.5.8.0)
8383 WARNING: Cannot find libjpeg-a4c3d5e9.so.62.3.0 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libtiff-f706b4a5.so.5.8.0)
8387 WARNING: Cannot find libXau-154567c4.so.6.0.0 (needed by /home/juan/.local/lib/python3.10/site-packages/PIL/../Pillow.libs/libxcb-4971137c.so.1.1.0)
8405 WARNING: Cannot find libsqlite3-e6e8c34c.so.0.8.6 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libproj-3a67288e.so.22.2.0)
8405 WARNING: Cannot find libtiff-40073f1f.so.5.7.0 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libproj-3a67288e.so.22.2.0)
8405 WARNING: Cannot find libcurl-c54b2682.so.4.7.0 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libproj-3a67288e.so.22.2.0)
8410 WARNING: Cannot find libnghttp2-62f02794.so.14.20.1 (needed by /home/juan/.local/lib/python3.10/site-packages/pyproj/../pyproj.libs/libcurl-c54b2682.so.4.7.0)
8422 INFO: Looking for eggs
8422 INFO: Using Python library /usr/lib/libpython3.10.so.1.0
8428 INFO: Warnings written to /mnt/f/code/sv-dlp/build/sv-dlp/warn-sv-dlp.txt
8486 INFO: Graph cross-reference written to /mnt/f/code/sv-dlp/build/sv-dlp/xref-sv-dlp.html
8517 INFO: checking PYZ
8517 INFO: Building PYZ because PYZ-00.toc is non existent
8517 INFO: Building PYZ (ZlibArchive) /mnt/f/code/sv-dlp/build/sv-dlp/PYZ-00.pyz
9134 INFO: Building PYZ (ZlibArchive) /mnt/f/code/sv-dlp/build/sv-dlp/PYZ-00.pyz completed successfully.
9148 INFO: checking PKG
9149 INFO: Building PKG because PKG-00.toc is non existent
9149 INFO: Building PKG (CArchive) sv-dlp.pkg
25747 INFO: Building PKG (CArchive) sv-dlp.pkg completed successfully.
25753 INFO: Bootloader /home/juan/.local/lib/python3.10/site-packages/PyInstaller/bootloader/Linux-64bit-intel/run
25753 INFO: checking EXE
25754 INFO: Building EXE because EXE-00.toc is non existent
25754 INFO: Building EXE from EXE-00.toc
25755 INFO: Copying bootloader EXE to /mnt/f/code/sv-dlp/dist/sv-dlp
25758 INFO: Appending PKG archive to custom ELF section in EXE
27499 INFO: Building EXE from EXE-00.toc completed successfully.

Versions

3.10.5 (main, Jun  6 2022, 18:49:26) [GCC 12.1.0]
Linux-5.10.16.3-microsoft-standard-WSL2-x86_64-with-glibc2.35
0.5.1
{'version': {'libheif': '1.12.0', 'x265': 'x265 HEVC encoder (3.5+1-f0c1022b6)', 'aom': 'AOMedia Project AV1 Encoder v3.4.0'}, 'decoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}, 'encoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}}

HEIF/AVIF file signature (magic number)

Hi there!

Recently I started to use pyheif-pillow-opener for one project to add support for heif/avif files. It was great until I faced with some issue, that I want to share with you, because I can see you start developing your addon a month ago and you hopefully can fix it faster on your side

So, in as_opener.py you have check_heif_magic method. It checks, if 5-8 bytes of signature is ftyp or 9-12 bytes of signature is one of the listed brands, but I think it should be logical and instead of logical or in return statement and that's why:

  1. Links in function comments strukturag/libheif#83 GNOME/gimp@e4bff4c shows, that acceptable magic numbers is ftypheic, ftypheix, ftypmif1 etc., not just ftyp or [heic, heix, mif1]
  2. I found out that some other files can have 5-8 bytes as ftyp, for my particular situation it was .m4a, it has ftypM4A magic number, and I found some other files, that is not HEIF/AVIF photos, but have 5-8 bytes as ftyp (here you can find some them, but I bet we can find more: https://www.garykessler.net/library/file_sigs.html) and because of that .m4a files can be validated as HEIF files with this function, but this is not HEIF at all

I can't find too much info about HEIF/AVIF file signature, so maybe I'm wrong, but from my experience and from discussions above I assume, that this could be a bug

Thank you for your attention, would be gladful if you fix this, or tell me that I've missed something!

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

This repository currently has no open or pending branches.

Detected dependencies

github-actions
.github/workflows/analysis-coverage.yml
  • actions/checkout v3
  • actions/cache v3
  • actions/cache v3
  • actions/upload-artifact v3
  • codecov/codecov-action v3
.github/workflows/build-cache-deps.yml
  • actions/checkout v3
  • docker/setup-qemu-action v2
  • actions/cache v3
  • actions/cache v3
  • actions/upload-artifact v3
.github/workflows/close-stale.yml
  • actions/stale v5
.github/workflows/create-release-draft.yml
  • actions/checkout v3
  • actions/upload-artifact v3
  • actions/checkout v3
  • msys2/setup-msys2 v2
  • actions/upload-artifact v3
  • actions/checkout v3
  • actions/upload-artifact v3
  • actions/checkout v3
  • docker/setup-qemu-action v2
  • actions/cache v3
  • actions/cache v3
  • actions/upload-artifact v3
  • actions/checkout v3
  • docker/setup-qemu-action v2
  • actions/cache v3
  • actions/cache v3
  • actions/upload-artifact v3
  • actions/checkout v3
  • codecov/codecov-action v3
  • actions/upload-artifact v3
  • actions/checkout v3
  • actions/download-artifact v3
  • ncipollo/release-action v1.10.0
.github/workflows/publish-pypi.yml
  • actions/checkout v3
  • i3h/download-release-asset v1
.github/workflows/test-src-build.yml
  • actions/checkout v3
.github/workflows/test-wheels.yml
  • actions/checkout v3
  • docker/setup-qemu-action v2
  • actions/checkout v3
  • actions/setup-python v4
  • actions/checkout v3
  • actions/setup-python v4
  • actions/checkout v3
  • actions/setup-python v4
pip_requirements
docs/rtd_docs_requirements.txt
  • sphinx ==5.1.0
  • sphinx-issues ==3.0.1
  • sphinx-rtd-theme ==1.0.0
  • pillow-heif ==0.5.0
setup-cfg
setup.cfg
  • cffi >=1.14.6
  • pillow >=6.2.0
  • sphinx >=4.4
  • sphinx-issues >=3.0.1
  • sphinx-rtd-theme >=1.0
  • pytest no version found
  • piexif no version found
  • defusedxml no version found
  • packaging no version found
  • pytest no version found
  • piexif no version found
  • defusedxml no version found
  • packaging no version found
  • numpy no version found
  • pympler no version found
  • pytest no version found
  • piexif no version found
  • defusedxml no version found
  • packaging no version found
  • numpy no version found
  • pympler no version found
  • opencv-python no version found
  • pre-commit no version found
  • pylint no version found
  • coverage no version found

  • Check this box to trigger a request for Renovate to run again on this repository

Saving: Native monochrome for "L" modes

Currently images get converted from "L" to "RGB" mode and saved using HeifChroma.INTERLEAVED_RGB and HeifColorspace.RGB

Disadvantages:

  • image data during saving are 3x bigger
  • saved image are a little bit bigger(7 633 bytes vs 7 341 bytes, on L_color_mode_image.png)
  • speed difference: ~30% slower at encoding

Missing metadata [spatial photos]

Describe the bug

I am loading an .HEIC "spatial photo" file coming from the VisionOS and I cannot see the relevant metadata in the metadata array or anywhere else.

Steps/Code to Reproduce

Here is my code:

if pillow_heif.is_supported("IMG_0009.HEIC"):
        heif_file = pillow_heif.open_heif("IMG_0009.HEIC")

Here is an example file:
IMG_0009.zip

Expected Results

There is metadata related to the camera extrinsics and intrinsics. They can be seen in the "info" box on the Mac, but they are nowhere to be seen from pillow-heif as far as I can tell. The Mac and AVP are using this to flag the files as "spatial photos" (stereoscopic image).

Expected: inspecting the file variable the metadata should be accessible somewhere.

Saving the file right after opening should produce a file with similar metadata as the original.

Actual Results

I can see info.exif, info.xmp but info.metadata is an empty array. I believe the metadata should be there.

Versions

3.10.8 (tags/v3.10.8:aaaf517, Oct 11 2022, 16:50:30) [MSC v.1933 64 bit (AMD64)]
Windows-10-10.0.19045-SP0
0.16.0
{'libheif': '1.17.6', 'HEIF': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'AVIF': 'AOMedia Project AV1 Encoder v3.8.2', 'encoders': {'x265': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'aom': 'AOMedia Project AV1 Encoder v3.8.2', 'mask': 
'mask'}, 'decoders': {'libde265': 'libde265 HEVC decoder, version 1.0.15', 'aom': 'AOMedia Project AV1 Decoder v3.8.2'}}

EXIF data are not transferred correctly

Describe the bug

With version pillow_heif==0.10.1, the code snip attached below worked perfectly. The EXIF data was read from a HEIC photo and added to a JPG.

With version pillow_heif==0.11.0, the EXIF data is no longer transferred correctly.

Please also compare the two file attachments.

Steps/Code to Reproduce

for files in os.listdir(path_source):
    if files.endswith('.HEIC'):
        filename = files.split('.')[0]
        heif_file = pillow_heif.open_heif(path_source + files, convert_hdr_to_8bit=False, bgr_mode=True)
        np_array = np.asarray(heif_file)
        cv2.imwrite(os.path.join(path_output, filename + '.jpg'), np_array)

        # Add exif to new image
        exif = heif_file.info['exif']
        image_new = Image.open(os.path.join(path_output, filename + '.jpg'))
        image_new.save(path_output + filename + '.jpg', 'JPEG', exif=exif)

Expected Results

The expected result, reproduced with version 0.10.1:
3.11.1 (tags/v3.11.1:a7a450f, Dec 6 2022, 19:58:39) [MSC v.1934 64 bit (AMD64)]
Windows-10-10.0.19045-SP0
0.10.1
{'libheif': '1.15.2', 'HEIF': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'AVIF': 'AOMedia Project AV1 Encoder v3.6.0'}
Version 0 10 1

Actual Results

Version 0 11 0

Versions

3.11.1 (tags/v3.11.1:a7a450f, Dec  6 2022, 19:58:39) [MSC v.1934 64 bit (AMD64)]
Windows-10-10.0.19045-SP0
0.11.0
{'libheif': '1.15.2', 'HEIF': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'AVIF': 'AOMedia Project AV1 Encoder v3.6.0'}

Ability to pass Pillow's `Exif` to save without calling `tobytes`

Describe why it is important and where it will be useful

im = Image.new("L", size=(1, 1))
exif = im.getexif()
exif[Base.ImageDescription.value] = "description"
buf = BytesIO()
im.save(buf, format="HEIF", exif=exif)  # <-- here 
print(Image.open(buf).getexif())

Describe your proposed solution

If passed object is Pillow's Exif then pillow-heif itself should call tobytes method.

Describe alternatives you've considered, if relevant

No response

Additional context

Pillow itself supports such thing...

Crash when trying to get exif image data

Describe the bug

When trying to apply the getexif() method to HEIF images made with my phone (stock Xiaomi), I get the error described below. As an example I've attached one of the problematic images: image.zip (sorry for using the zip format, uploading .heic files is not allowed).

Steps/Code to Reproduce

from PIL.Image import Exif, open as image_open
from pillow_heif import register_heif_opener

register_heif_opener()

with image_open("image.heic") as image:
    exif: Exif = image.getexif()
    print("Exif presents: {}".format(exif is not None))

Expected Results

Exif presents: True | Exif presents: False

Actual Results

Test machine 1:

Traceback (most recent call last):
  File "path-to-script.py", line 7, in <module>
    exif: Exif = image.getexif()
                 ^^^^^^^^^^^^^^^
  File "path-to-site-packages\PIL\Image.py", line 1455, in getexif
    self._exif.load(exif_info)
  File "path-to-site-packages\PIL\Image.py", line 3719, in load
    self._info = TiffImagePlugin.ImageFileDirectory_v2(self.head)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "path-to-site-packages\PIL\TiffImagePlugin.py", line 507, in __init__
    raise SyntaxError(msg)
SyntaxError: not a TIFF file (header b'\xff\xe18&Exif' not valid)

Test machine 2:

Traceback (most recent call last):
  File "path-to-script.py", line 7, in <module>
    exif: Exif = image.getexif()
  File "/usr/lib/python3/dist-packages/PIL/Image.py", line 1275, in getexif
    self._exif.load(self.info.get("exif"))
  File "/usr/lib/python3/dist-packages/PIL/Image.py", line 3237, in load
    self._info = TiffImagePlugin.ImageFileDirectory_v1(self.head)
  File "/usr/lib/python3/dist-packages/PIL/TiffImagePlugin.py", line 900, in __init__
    super().__init__(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/PIL/TiffImagePlugin.py", line 466, in __init__
    raise SyntaxError("not a TIFF file (header %r not valid)" % ifh)
SyntaxError: not a TIFF file (header b'if\x00\x00II*\x00' not valid)

Versions

Test machine 1:
3.11.2 (tags/v3.11.2:878ead1, Feb  7 2023, 16:38:35) [MSC v.1934 64 bit (AMD64)]
Windows-10-10.0.19045-SP0
0.10.1
{'libheif': '1.15.2', 'HEIF': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'AVIF': 'AOMedia Project AV1 Encoder v3.6.0'}

Test machine 1 additional information:
UTF-8 enabled for the whole system
Amernime Zone AMD 3rd party drivers
Pillow 9.5.0

Test machine 2:
3.8.10 (default, Mar 13 2023, 10:26:41) 
[GCC 9.4.0]
Linux-5.15.0-71-generic-x86_64-with-glibc2.29
0.10.1
{'libheif': '1.15.2', 'HEIF': 'x265 HEVC encoder (3.5+1-f0c1022b6)', 'AVIF': 'AOMedia Project AV1 Encoder v3.5.0'}

Test machine 2 additional information:
VirtualBox VM Xubuntu 20.04 (clean install)
Pillow 7.0.0

DLL load failed while importing libheif

As running the example, there is an error happened while importing ffi, lib form pillow_heif.libheif. Any suggestion, plz?

from pillow_heif.libheif import ffi, lib # pylint: disable=import-error, no-name-in-module.
ImportError: DLL load failed while importing libheif:

`0.10.x` version, changes topic.

Here will be information about changes for 0.10 version.

Release date: NEXT WEEK (21.02-23.02)

Main features of 0.10.0 version:

  • Removed CFFI bindings, added native C module, most parts of project were reworked.
  • Support for encoding of LA & LA;16 modes.
  • Ability to build project from source with LibHeif==1.12.0

pillow_heif.libheif_info() was simplified to such dictionary:

{
    'libheif': '1.14.2',
    'HEIF': 'x265 HEVC encoder (3.4+31-6722fce1f)',
    'AVIF': 'AOMedia Project AV1 Encoder 3.5.0'
}

Changes when using as a Pillow plugin:

  • no breaking changes.
  • in info dictionary metadata.content_type is now str instead of bytes.

Changes when using as a standalone:

  • convert_to method removed, instead optional bgr_mode parameter to open_heif & read_heif added.

  • open_heif/read_heif with convert_hdr_to_8bit=False will open 10/12 bit images in 16 bit mode automatically(and it faster now and takes less RAM during decoding).

    BGR modes(OpenCV) - old code:

    heif_file = pillow_heif.open_heif("images/rgb12.heif", convert_hdr_to_8bit=False)
    heif_file.convert_to("BGRA;16" if heif_file.has_alpha else "BGR;16")
    np_array = np.asarray(heif_file)
    cv2.imwrite("rgb16.png", np_array)

    ->

    heif_file = pillow_heif.open_heif("images/rgb12.heif", convert_hdr_to_8bit=False, bgr_mode=True)
    np_array = np.asarray(heif_file)
    cv2.imwrite("rgb16.png", np_array)
  • original_bit_depth in info dictionary was renamed to bit_depth, standalone bit_depth was removed.

    heif_file = pillow_heif.open_heif("images/rgb12.heif")
    print("image bit depth:" , heif_file.bit_depth)

    ->

    heif_file = pillow_heif.open_heif("images/rgb12.heif")
    print("image bit depth:" , heif_file.info["bit_depth"])

    it is standardized now and shows the bit-depth of image in file(not the decoded one, so it may differs from bit depth of mode), for both Pillow plugin and stand-alone usage.

  • thumbnails was simplified, temporary remove ability for getting their data and now it is just a list with thumbnails boxes.

    For both the Pillow plugin and standalone use, this list will be in the info dictionary. It simply allows you to delete thumbnails or add new ones without being able to retrieve their data. (I can’t make it universal for both modes, when there is an idea how to do it without loss of performance, I’ll do it)

  • encode function added.

    def encode(mode: str, size: tuple, data, fp, **kwargs) -> None:
        """Encodes data in a ``fp``.
    
        :param mode: `BGR(A);16`, `RGB(A);16`, LA;16`, `L;16`, `I;16L`, `BGR(A)`, `RGB(A)`, `LA`, `L`
        :param size: tuple with ``width`` and ``height`` of an image.
        :param data: bytes object with raw image data.
        :param fp: A filename (string), pathlib.Path object or an object with ``write`` method."""

    Useful in situations where you want just save one image to a new file.
    Old code that do the same(it still will be worked):

    cv_img = cv2.imread("images/jpeg_gif_png/RGBA_16.png", cv2.IMREAD_UNCHANGED)
    heif_file = pillow_heif.from_bytes(
        mode="BGRA;16",
        size=(cv_img.shape[1], cv_img.shape[0]),
        data=bytes(cv_img)
    )
    heif_file.save("RGBA_10bit.heic", quality=-1)

    New alternative:

    cv_img = cv2.imread("images/jpeg_gif_png/RGBA_16.png", cv2.IMREAD_UNCHANGED)
    pillow_heif.encode(
       mode="BGRA;16",
       size=(cv_img.shape[1], cv_img.shape[0]),
       data=bytes(cv_img),
       fp="RGBA_10bit.heic",
       quality=-1)

    Both methods are faster now, as data passes directly to LibHeif(encode will be faster as it does not create HeifFile class).

Encoding of images in `LA` mode without conversion

Describe why it is important and where it will be useful

elif frame.mode == "LA":  # libheif doesnt not support INTERLEAVED_MONOCHROME mode
    frame = frame.convert(mode="RGBA")

This is wrong, libheif supports adding MONOCHROME plane and Alpha plane for this situation.
And the resulted encoded image will be a bit smaller that case

Describe your proposed solution

Do not understand all code in this project, but maybe needed make some changes to:

    @property
    def data(self):

Is this possible?

Describe alternatives you've considered, if relevant

No response

Additional context

Not a big deal, but would be nice to see such improvement.

Created jpg image is skewed diagonally, clearly incorrect

Describe the bug

I put in an heic that I know is not weird.

I run the example code below, and it saves a jpg that looks weird and skewed.

Steps/Code to Reproduce

# main.py
if __name__ == '__main__':
    path = "C:\\Users\\whatever\\myimg.heic"
    heif_file = pillow_heif.open_heif(path)
    image = Image.frombytes(heif_file.mode, heif_file.size, heif_file.data, "raw")
    image.save("hi.jpg")

Expected Results

image

Actual Results

image

Versions

Windows 10


0.7.0
{'version': {'libheif': '1.13.0', 'x265': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'aom': 'AOMedia Project AV1 Encoder v3.4.0'}, 'decoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}, 'encoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}}

Performance, no multithreading for decoding

Describe the bug

Hi,

Thanks for developing this extension to Pillow. I had a question regarding performance converting a .heic to a .jpg file. Running heif-convert is about twice as fast as doing:

import pillow_heif.HeifImagePlugin

img = Image.open(path_heic)
img.save(path_jpg)

The command line I used was:

for file in *.heic; do heif-convert $file ${file/%.heic/.jpg}; done

Is this expected? For 100 images (of the smaller variety I attached), heif-convert took 42 seconds, pillow_heif took 75 seconds (threaded), and 208 seconds using one thread.

I've attached two files from two datasets I've observed this on.

Thanks,

Steps/Code to Reproduce

import pillow_heif.HeifImagePlugin

img = Image.open(path_heic)
img.save(path_jpg)

images.zip

Expected Results

Performance should mirror heif-converte

Actual Results

About two times slower.

Versions

0.8.0
{'version': {'libheif': '1.14.0', 'x265': 'x265 HEVC encoder (3.5+1-f0c1022b6)', 'aom': 'AOMedia Project AV1 Encoder v3.5.0'}, 'decoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}, 'encoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}}

reading support of monochrome images

Will try to add this as an option.NATIVE_MODE which will be set by default to False to not break any compatibility.

If image will be opened by read_heif NATIVE_MODE will be set to True for that image. (So behaviour of read_heif will be different)

For Pillow plugin and open_heif it will be available to change option with register_*_opener or by setting

options.NATIVE_MODE = True

Also this will allow to get and set in info dictionary original image subsampling value(currently it has name chroma in pillow_heif)

That will allow to read monochromic images in monochrome mode and not in RGB(A)/BGR(A)

AUX images support

Divided #83 topic into two separate.

Briefly: I can easy add AUX image support whenI will have any non iPhone image, with different auxiliary_type (e.g. non hdrgainmap)

Or when I get information from here: strukturag/libheif/issues/926

Currently we can not determine image mode, and I need to know, can all aux images be decoded as grayscales ones or not.
Cause if not, then algorithm will be a little bit weird, need first to try to decode as Greyscale and if decodes fails, then decode it as RGB/RGBA...

Offline build

Describe the bug

Hello, I'm trying to build this in a flatpak environment which has no network access, I added the necessary libraries listed in

LIBX265_URL = "https://bitbucket.org/multicoreware/x265_git/get/0b75c44c10e605fe9e9ebed58f04a46271131827.tar.gz"
LIBAOM_URL = "https://aomedia.googlesource.com/aom/+archive/v3.5.0.tar.gz"
LIBDE265_URL = "https://github.com/strukturag/libde265/releases/download/v1.0.12/libde265-1.0.12.tar.gz"
LIBHEIF_URL = "https://github.com/strukturag/libheif/releases/download/v1.16.2/libheif-1.16.2.tar.gz"

But it still seems to try downloading them for some reason. Is a fully offline build not possible?

========================================================================
Building module python3-pillow-heif in /srv/buildbot/worker/build-x86_64-4/build/.flatpak-builder/build/python3-pillow-heif-1
========================================================================
�]2;flatpak-builder: Building python3-pillow-heif��]2;flatpak-builder: Installing python3-pillow-heif�Running: pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}" --prefix=${FLATPAK_DEST} "pillow-heif>=0.12.0" --no-build-isolation
FB: Running 'flatpak build --die-with-parent --env=FLATPAK_BUILDER_BUILDDIR=/run/build/python3-pillow-heif --nofilesystem=host:reset --filesystem=/srv/buildbot/worker/build-x86_64-4/build/.flatpak-builder/build/python3-pillow-heif-1 --bind-mount=/run/build/python3-pillow-heif=/srv/buildbot/worker/build-x86_64-4/build/.flatpak-builder/build/python3-pillow-heif-1 --build-dir=/run/build/python3-pillow-heif --bind-mount=/run/ccache=/srv/buildbot/worker/build-x86_64-4/build/.flatpak-builder/ccache --unshare=network --env=SOURCE_DATE_EPOCH=1691637318 '--env=CFLAGS=-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fno-omit-frame-pointer ' '--env=CXXFLAGS=-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -fno-omit-frame-pointer ' '--env=LDFLAGS=-L/app/lib -Wl,-z,relro,-z,now -Wl,--as-needed ' --env=BASEAPP_REMOVE_WEBENGINE=1 --env=CCACHE_DIR=/run/ccache/disabled --env=PATH=/app/bin:/usr/bin --env=LD_LIBRARY_PATH=/app/lib --env=PKG_CONFIG_PATH=/app/lib/pkgconfig:/app/share/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig --env=FLATPAK_BUILDER_N_JOBS=64 /srv/buildbot/worker/build-x86_64-4/build/.flatpak-builder/rofiles/rofiles-wxYmbx /bin/sh -c 'pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}" --prefix=${FLATPAK_DEST} "pillow-heif>=0.12.0" --no-build-isolation'' on host
Using pip 23.1.2 from /usr/lib/python3.10/site-packages/pip (python 3.10)
Looking in links: file:///run/build/python3-pillow-heif
Processing ./pillow_heif-0.13.0.tar.gz
  Running command Preparing metadata (pyproject.toml)
  running dist_info
  creating /tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info
  writing /tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info/PKG-INFO
  writing dependency_links to /tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info/dependency_links.txt
  writing requirements to /tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info/requires.txt
  writing top-level names to /tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info/top_level.txt
  writing manifest file '/tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info/SOURCES.txt'
  listing git files failed - pretending there aren't any
  reading manifest file '/tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info/SOURCES.txt'
  reading manifest template 'MANIFEST.in'
  warning: no previously-included files found matching '*.yaml'
  warning: no previously-included files found matching '*.yml'
  warning: no previously-included files found matching '.cirrus.star'
  no previously-included directories found matching 'ci'
  no previously-included directories found matching 'docs'
  no previously-included directories found matching 'docker'
  no previously-included directories found matching 'benchmarks'
  warning: no previously-included files matching '*' found under directory 'pi-heif'
  adding license file 'LICENSE.txt'
  adding license file 'LICENSES_bundled.txt'
  writing manifest file '/tmp/pip-modern-metadata-jr_l72lo/pillow_heif.egg-info/SOURCES.txt'
  creating '/tmp/pip-modern-metadata-jr_l72lo/pillow_heif-0.13.0.dist-info'
  Preparing metadata (pyproject.toml) ... �[?25l�[?25hdone
Requirement already satisfied: pillow>=9.1.1 in /app/lib/python3.10/site-packages (from pillow-heif>=0.12.0) (10.0.0)
Building wheels for collected packages: pillow-heif
  Running command Building wheel for pillow-heif (pyproject.toml)
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build/lib.linux-x86_64-cpython-310
  creating build/lib.linux-x86_64-cpython-310/pillow_heif
  copying pillow_heif/options.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
  copying pillow_heif/misc.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
  copying pillow_heif/heif.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
  copying pillow_heif/constants.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
  copying pillow_heif/as_plugin.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
  copying pillow_heif/_version.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
  copying pillow_heif/_lib_info.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
  copying pillow_heif/_deffered_error.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
  copying pillow_heif/__init__.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
  copying pillow_heif/HeifImagePlugin.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
  copying pillow_heif/AvifImagePlugin.py -> build/lib.linux-x86_64-cpython-310/pillow_heif
  running build_ext
  Tool cmake with version 3.26.4 satisfy requirements.
  Tool nasm with version 2.16.01 satisfy requirements.
  tar: /tmp/ph_build_stuff/x265/download.tar.gz: Cannot open: No such file or directory
  tar: Error is not recoverable: exiting now
  Traceback (most recent call last):
    File "/usr/lib/python3.10/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
      main()
    File "/usr/lib/python3.10/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
      json_out['return_val'] = hook(**hook_input['kwargs'])
    File "/usr/lib/python3.10/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 251, in build_wheel
      return _build_backend().build_wheel(wheel_directory, config_settings,
    File "/usr/lib/python3.10/site-packages/setuptools/build_meta.py", line 416, in build_wheel
      return self._build_with_temp_dir(['bdist_wheel'], '.whl',
    File "/usr/lib/python3.10/site-packages/setuptools/build_meta.py", line 401, in _build_with_temp_dir
      self.run_setup()
    File "/usr/lib/python3.10/site-packages/setuptools/build_meta.py", line 487, in run_setup
      super(_BuildMetaLegacyBackend,
    File "/usr/lib/python3.10/site-packages/setuptools/build_meta.py", line 338, in run_setup
      exec(code, locals())
    File "<string>", line 143, in <module>
    File "/usr/lib/python3.10/site-packages/setuptools/__init__.py", line 107, in setup
      return distutils.core.setup(**attrs)
    File "/usr/lib/python3.10/site-packages/setuptools/_distutils/core.py", line 185, in setup
      return run_commands(dist)
    File "/usr/lib/python3.10/site-packages/setuptools/_distutils/core.py", line 201, in run_commands
      dist.run_commands()
    File "/usr/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands
      self.run_command(cmd)
    File "/usr/lib/python3.10/site-packages/setuptools/dist.py", line 1244, in run_command
      super().run_command(command)
    File "/usr/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
      cmd_obj.run()
    File "/usr/lib/python3.10/site-packages/wheel/bdist_wheel.py", line 325, in run
      self.run_command("build")
    File "/usr/lib/python3.10/site-packages/setuptools/_distutils/cmd.py", line 318, in run_command
      self.distribution.run_command(command)
    File "/usr/lib/python3.10/site-packages/setuptools/dist.py", line 1244, in run_command
      super().run_command(command)
    File "/usr/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
      cmd_obj.run()
    File "/usr/lib/python3.10/site-packages/setuptools/_distutils/command/build.py", line 131, in run
      self.run_command(cmd_name)
    File "/usr/lib/python3.10/site-packages/setuptools/_distutils/cmd.py", line 318, in run_command
      self.distribution.run_command(command)
    File "/usr/lib/python3.10/site-packages/setuptools/dist.py", line 1244, in run_command
      super().run_command(command)
    File "/usr/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
      cmd_obj.run()
    File "/usr/lib/python3.10/site-packages/setuptools/command/build_ext.py", line 84, in run
      _build_ext.run(self)
    File "/usr/lib/python3.10/site-packages/Cython/Distutils/old_build_ext.py", line 186, in run
      _build_ext.build_ext.run(self)
    File "/usr/lib/python3.10/site-packages/setuptools/_distutils/command/build_ext.py", line 345, in run
      self.build_extensions()
    File "<string>", line 112, in build_extensions
    File "/tmp/pip-install-4b_iq5_j/pillow-heif_2e7e8dbcd4654c23872a1b3e6b6113c6/libheif/linux_build_libs.py", line 226, in build_libs
      build_lib_linux(LIBX265_URL, "x265", _is_musllinux)
    File "/tmp/pip-install-4b_iq5_j/pillow-heif_2e7e8dbcd4654c23872a1b3e6b6113c6/libheif/linux_build_libs.py", line 136, in build_lib_linux
      download_extract_to(url, _lib_path)
    File "/tmp/pip-install-4b_iq5_j/pillow-heif_2e7e8dbcd4654c23872a1b3e6b6113c6/libheif/linux_build_libs.py", line 56, in download_extract_to
      run(_tar_cmd.split(), check=True)
    File "/usr/lib/python3.10/subprocess.py", line 526, in run
      raise CalledProcessError(retcode, process.args,
  subprocess.CalledProcessError: Command '['tar', '-xf', '/tmp/ph_build_stuff/x265/download.tar.gz', '-C', '/tmp/ph_build_stuff/x265', '--strip-components', '1']' returned non-zero exit status 2.
  error: subprocess-exited-with-error
  
  × Building wheel for pillow-heif (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> See above for output.
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  full command: /usr/bin/python3 /usr/lib/python3.10/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py build_wheel /tmp/tmpm1kufndh
  cwd: /tmp/pip-install-4b_iq5_j/pillow-heif_2e7e8dbcd4654c23872a1b3e6b6113c6
  Building wheel for pillow-heif (pyproject.toml) ... �[?25l�[?25herror
  ERROR: Failed building wheel for pillow-heif

Dependencies I added:

See the minimal manifest below

Steps/Code to Reproduce

  1. Install flatpak, flatpak-builder, set up the flathub repo
  2. flatpak install org.freedesktop.Platform//22.08, flatpak install org.freedesktop.Sdk//22.08
  3. Use this manifest:
app-id: com.example.test
runtime: org.freedesktop.Platform
runtime-version: '22.08'
sdk: org.freedesktop.Sdk

modules:

  - name: libaom
    buildsystem: cmake-ninja
    builddir: true
    config-opts:
      - -DBUILD_SHARED_LIBS=1
      - -DENABLE_EXAMPLES=OFF
      - -DENABLE_TESTDATA=OFF
      - -DENABLE_TESTS=OFF
      - -DENABLE_TOOLS=OFF
    sources:
      - type: archive
        url: https://storage.googleapis.com/aom-releases/libaom-3.6.1.tar.gz
        sha256: 42b862f58b3d00bd3902d2dc469526574f5b012e5b178e6a9652845a113d6887

  - name: libde265
    buildsystem: cmake-ninja
    sources:
      - type: archive
        url: https://github.com/strukturag/libde265/archive/v1.0.12/libde265-1.0.12.tar.gz
        sha256: c7e5443c9387ef2ee7bd3a25b4cfeb1a66d038584cf0ab21a4a28db64f224584
    cleanup:
      - /bin

  - name: x265
    builddir: true
    subdir: source
    buildsystem: cmake-ninja
    config-opts:
      - -DBUILD_SHARED_LIBS=ON
    sources:
      - type: archive
        url: https://bitbucket.org/multicoreware/x265_git/downloads/x265_3.5.tar.gz
        sha256: e70a3335cacacbba0b3a20ec6fecd6783932288ebc8163ad74bcc9606477cae8

  - name: libheif
    buildsystem: cmake-ninja
    builddir: true
    config-opts:
      - -DAOM_ENCODER=ON
      - -DWITH_EXAMPLES=OFF
    sources:
      - type: archive
        url: https://github.com/strukturag/libheif/archive/v1.16.2/libheif-1.16.2.tar.gz
        sha256: d207f2ff5c86e6af3621c237f186130b985b7a9ff657875944b58ac5d27ba71c

  - name: python3-pillow-heif
    buildsystem: simple
    build-commands:
      - pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}" --prefix=${FLATPAK_DEST} "pillow-heif" --no-build-isolation
    sources:
      - type: file
        url: https://files.pythonhosted.org/packages/0f/8b/2ebaf9adcf4260c00f842154865f8730cf745906aa5dd499141fb6063e26/Pillow-10.0.0.tar.gz
        sha256: 9c82b5b3e043c7af0d95792d0d20ccf68f61a1fec6b3530e718b688422727396
      - type: file
        url: https://files.pythonhosted.org/packages/52/27/39f219e702744c6d7075626517de4ffe331550229e95897a26ba3e55b979/pillow_heif-0.13.0.tar.gz
        sha256: be337495d0be5accf4d6ea6614f61293c40c86dc8d3e5e6eb63661f90f472362
  1. flatpak-builder build --force-clean test.yaml
  2. See above error

Expected Results

It should find that libaom, libde265, libheif and x265 are already installed

Actual Results

Tries to download them

Versions

0.13.0

test_heif_primary_image[AVIF] causes SIGKILL on aarch64-darwin with libaom 3.9.0 version

Describe the bug

When running the test suite on aarch64-darwin in nixpkgs, we see test_heif_primary_image[AVIF] cause a SIGILL and crash the whole python interpreter.

Steps/Code to Reproduce

Run the test suite on MacOS.

> sw_vers                                                                                                                                                                     ~
ProductName:		macOS
ProductVersion:		14.4.1
BuildVersion:		23E224

Expected Results

The test suite should succeed or show errors, not crash the interpreter.

Actual Results

============================= test session starts ==============================
platform darwin -- Python 3.12.3, pytest-8.1.1, pluggy-1.4.0 -- /nix/store/2r8fbgpabanb42zbdm4lngayc35wby8i-python3-3.12.3/bin/python3.12
cachedir: .pytest_cache
rootdir: /private/tmp/nix-build-python3.12-pillow-heif-0.16.0.drv-0/source
configfile: pyproject.toml
testpaths: tests
collected 913 items / 2 deselected / 1 skipped / 911 selected                  

tests/basic_test.py::test_libheif_info PASSED                            [  0%]
tests/basic_test.py::test_pillow_register_avif_plugin SKIPPED (Only when
AVIF support missing.)                                                   [  0%]
tests/basic_test.py::test_get_file_mimetype[img_path0] PASSED            [  0%]
tests/basic_test.py::test_get_file_mimetype[img_path1] PASSED            [  0%]
tests/basic_test.py::test_get_file_mimetype[img_path2] PASSED            [  0%]
tests/basic_test.py::test_get_file_mimetype[img_path3] PASSED            [  0%]
tests/basic_test.py::test_get_file_mimetype[img_path4] PASSED            [  0%]
tests/basic_test.py::test_get_file_mimetype[img_path5] PASSED            [  0%]
tests/basic_test.py::test_get_file_mimetype[img_path6] PASSED            [  0%]
tests/basic_test.py::test_get_file_mimetype[img_path7] PASSED            [  1%]
tests/basic_test.py::test_get_file_mimetype[img_path8] PASSED            [  1%]
tests/basic_test.py::test_get_file_mimetype[img_path9] PASSED            [  1%]
tests/basic_test.py::test_get_file_mimetype[img_path10] PASSED           [  1%]
tests/basic_test.py::test_get_file_mimetype[img_path11] PASSED           [  1%]
tests/basic_test.py::test_get_file_mimetype[img_path12] PASSED           [  1%]
tests/basic_test.py::test_get_file_mimetype[img_path13] PASSED           [  1%]
tests/basic_test.py::test_get_file_mimetype[img_path14] PASSED           [  1%]
tests/basic_test.py::test_get_file_mimetype[img_path15] PASSED           [  1%]
tests/basic_test.py::test_get_file_mimetype[img_path16] PASSED           [  2%]
tests/basic_test.py::test_get_file_mimetype[img_path17] PASSED           [  2%]
tests/basic_test.py::test_get_file_mimetype[img_path18] PASSED           [  2%]
tests/basic_test.py::test_get_file_mimetype[img_path19] PASSED           [  2%]
tests/basic_test.py::test_get_file_mimetype[img_path20] PASSED           [  2%]
tests/basic_test.py::test_get_file_mimetype[img_path21] PASSED           [  2%]
tests/basic_test.py::test_get_file_mimetype[img_path22] PASSED           [  2%]
tests/basic_test.py::test_get_file_mimetype[img_path23] PASSED           [  2%]
tests/basic_test.py::test_get_file_mimetype[img_path24] PASSED           [  2%]
tests/basic_test.py::test_get_file_mimetype[img_path25] PASSED           [  3%]
tests/basic_test.py::test_get_file_mimetype[img_path26] PASSED           [  3%]
tests/basic_test.py::test_get_file_mimetype[img_path27] PASSED           [  3%]
tests/basic_test.py::test_get_file_mimetype[img_path28] PASSED           [  3%]
tests/basic_test.py::test_get_file_mimetype[img_path29] PASSED           [  3%]
tests/basic_test.py::test_get_file_mimetype[img_path30] PASSED           [  3%]
tests/basic_test.py::test_get_file_mimetype[img_path31] PASSED           [  3%]
tests/basic_test.py::test_get_file_mimetype[img_path32] PASSED           [  3%]
tests/basic_test.py::test_get_file_mimetype[img_path33] PASSED           [  3%]
tests/basic_test.py::test_get_file_mimetype[img_path34] PASSED           [  4%]
tests/basic_test.py::test_get_file_mimetype[img_path35] PASSED           [  4%]
tests/basic_test.py::test_get_file_mimetype[img_path36] PASSED           [  4%]
tests/basic_test.py::test_get_file_mimetype[img_path37] PASSED           [  4%]
tests/basic_test.py::test_get_file_mimetype[img_path38] PASSED           [  4%]
tests/basic_test.py::test_get_file_mimetype[img_path39] PASSED           [  4%]
tests/basic_test.py::test_get_file_mimetype[img_path40] PASSED           [  4%]
tests/basic_test.py::test_get_file_mimetype[img_path41] PASSED           [  4%]
tests/basic_test.py::test_get_file_mimetype[img_path42] PASSED           [  4%]
tests/basic_test.py::test_get_file_mimetype[img_path43] PASSED           [  5%]
tests/basic_test.py::test_get_file_mimetype[img_path44] PASSED           [  5%]
tests/basic_test.py::test_get_file_mimetype[img_path45] PASSED           [  5%]
tests/basic_test.py::test_get_file_mimetype[img_path46] PASSED           [  5%]
tests/basic_test.py::test_get_file_mimetype[img_path47] PASSED           [  5%]
tests/basic_test.py::test_get_file_mimetype[img_path48] PASSED           [  5%]
tests/basic_test.py::test_get_file_mimetype[img_path49] PASSED           [  5%]
tests/basic_test.py::test_get_file_mimetype[img_path50] PASSED           [  5%]
tests/basic_test.py::test_get_file_mimetype[img_path51] PASSED           [  5%]
tests/basic_test.py::test_get_file_mimetype[img_path52] PASSED           [  6%]
tests/basic_test.py::test_get_file_mimetype[img_path53] PASSED           [  6%]
tests/basic_test.py::test_get_file_mimetype[img_path54] PASSED           [  6%]
tests/basic_test.py::test_get_file_mimetype[img_path55] PASSED           [  6%]
tests/basic_test.py::test_get_file_mimetype[img_path56] PASSED           [  6%]
tests/basic_test.py::test_get_file_mimetype[img_path57] PASSED           [  6%]
tests/basic_test.py::test_get_file_mimetype[img_path58] PASSED           [  6%]
tests/basic_test.py::test_get_file_mimetype[img_path59] PASSED           [  6%]
tests/basic_test.py::test_get_file_mimetype[img_path60] PASSED           [  6%]
tests/basic_test.py::test_get_file_mimetype[img_path61] PASSED           [  7%]
tests/basic_test.py::test_get_file_mimetype[img_path62] PASSED           [  7%]
tests/basic_test.py::test_get_file_mimetype[img_path63] PASSED           [  7%]
tests/basic_test.py::test_get_file_mimetype[img_path64] PASSED           [  7%]
tests/basic_test.py::test_get_file_mimetype[img_path65] PASSED           [  7%]
tests/basic_test.py::test_get_file_mimetype[img_path66] PASSED           [  7%]
tests/basic_test.py::test_get_file_mimetype[img_path67] PASSED           [  7%]
tests/basic_test.py::test_get_file_mimetype_not_supported PASSED         [  7%]
tests/basic_test.py::test_get_file_mimetype_invalid[] PASSED             [  7%]
tests/basic_test.py::test_get_file_mimetype_invalid[\x00\x00\x00$ftyp] PASSED [  8%]
tests/basic_test.py::test_get_file_mimetype_invalid[\x00\x00\x00$ftypheiZ] PASSED [  8%]
tests/basic_test.py::test_is_supported[img_path0] PASSED                 [  8%]
tests/basic_test.py::test_is_supported[img_path1] PASSED                 [  8%]
tests/basic_test.py::test_is_supported[img_path2] PASSED                 [  8%]
tests/basic_test.py::test_is_supported[img_path3] PASSED                 [  8%]
tests/basic_test.py::test_is_supported[img_path4] PASSED                 [  8%]
tests/basic_test.py::test_is_supported[img_path5] PASSED                 [  8%]
tests/basic_test.py::test_is_supported[img_path6] PASSED                 [  8%]
tests/basic_test.py::test_is_supported[img_path7] PASSED                 [  9%]
tests/basic_test.py::test_is_supported[img_path8] PASSED                 [  9%]
tests/basic_test.py::test_is_supported[img_path9] PASSED                 [  9%]
tests/basic_test.py::test_is_supported[img_path10] PASSED                [  9%]
tests/basic_test.py::test_is_supported[img_path11] PASSED                [  9%]
tests/basic_test.py::test_is_supported[img_path12] PASSED                [  9%]
tests/basic_test.py::test_is_supported[img_path13] PASSED                [  9%]
tests/basic_test.py::test_is_supported[img_path14] PASSED                [  9%]
tests/basic_test.py::test_is_supported[img_path15] PASSED                [  9%]
tests/basic_test.py::test_is_supported[img_path16] PASSED                [  9%]
tests/basic_test.py::test_is_supported[img_path17] PASSED                [ 10%]
tests/basic_test.py::test_is_supported[img_path18] PASSED                [ 10%]
tests/basic_test.py::test_is_supported[img_path19] PASSED                [ 10%]
tests/basic_test.py::test_is_supported[img_path20] PASSED                [ 10%]
tests/basic_test.py::test_is_supported[img_path21] PASSED                [ 10%]
tests/basic_test.py::test_is_supported[img_path22] PASSED                [ 10%]
tests/basic_test.py::test_is_supported[img_path23] PASSED                [ 10%]
tests/basic_test.py::test_is_supported[img_path24] PASSED                [ 10%]
tests/basic_test.py::test_is_supported[img_path25] PASSED                [ 10%]
tests/basic_test.py::test_is_supported[img_path26] PASSED                [ 11%]
tests/basic_test.py::test_is_supported[img_path27] PASSED                [ 11%]
tests/basic_test.py::test_is_supported[img_path28] PASSED                [ 11%]
tests/basic_test.py::test_is_supported[img_path29] PASSED                [ 11%]
tests/basic_test.py::test_is_supported[img_path30] PASSED                [ 11%]
tests/basic_test.py::test_is_supported[img_path31] PASSED                [ 11%]
tests/basic_test.py::test_is_supported[img_path32] PASSED                [ 11%]
tests/basic_test.py::test_is_supported[img_path33] PASSED                [ 11%]
tests/basic_test.py::test_is_supported[img_path34] PASSED                [ 11%]
tests/basic_test.py::test_is_supported[img_path35] PASSED                [ 12%]
tests/basic_test.py::test_is_supported[img_path36] PASSED                [ 12%]
tests/basic_test.py::test_is_supported[img_path37] PASSED                [ 12%]
tests/basic_test.py::test_is_supported[img_path38] PASSED                [ 12%]
tests/basic_test.py::test_is_supported[img_path39] PASSED                [ 12%]
tests/basic_test.py::test_is_supported[img_path40] PASSED                [ 12%]
tests/basic_test.py::test_is_supported[img_path41] PASSED                [ 12%]
tests/basic_test.py::test_is_supported[img_path42] PASSED                [ 12%]
tests/basic_test.py::test_is_supported[img_path43] PASSED                [ 12%]
tests/basic_test.py::test_is_supported[img_path44] PASSED                [ 13%]
tests/basic_test.py::test_is_supported[img_path45] PASSED                [ 13%]
tests/basic_test.py::test_is_supported[img_path46] PASSED                [ 13%]
tests/basic_test.py::test_is_supported[img_path47] PASSED                [ 13%]
tests/basic_test.py::test_is_supported[img_path48] PASSED                [ 13%]
tests/basic_test.py::test_is_supported[img_path49] PASSED                [ 13%]
tests/basic_test.py::test_is_supported[img_path50] PASSED                [ 13%]
tests/basic_test.py::test_is_supported[img_path51] PASSED                [ 13%]
tests/basic_test.py::test_is_supported[img_path52] PASSED                [ 13%]
tests/basic_test.py::test_is_supported[img_path53] PASSED                [ 14%]
tests/basic_test.py::test_is_supported[img_path54] PASSED                [ 14%]
tests/basic_test.py::test_is_supported[img_path55] PASSED                [ 14%]
tests/basic_test.py::test_is_supported[img_path56] PASSED                [ 14%]
tests/basic_test.py::test_is_supported[img_path57] PASSED                [ 14%]
tests/basic_test.py::test_is_supported[img_path58] PASSED                [ 14%]
tests/basic_test.py::test_is_supported[img_path59] PASSED                [ 14%]
tests/basic_test.py::test_is_supported[img_path60] PASSED                [ 14%]
tests/basic_test.py::test_is_supported[img_path61] PASSED                [ 14%]
tests/basic_test.py::test_is_supported[img_path62] PASSED                [ 15%]
tests/basic_test.py::test_is_supported[img_path63] PASSED                [ 15%]
tests/basic_test.py::test_is_supported[img_path64] PASSED                [ 15%]
tests/basic_test.py::test_is_supported[img_path65] PASSED                [ 15%]
tests/basic_test.py::test_is_supported[img_path66] PASSED                [ 15%]
tests/basic_test.py::test_is_supported[img_path67] PASSED                [ 15%]
tests/basic_test.py::test_is_supported_fails[] PASSED                    [ 15%]
tests/basic_test.py::test_is_supported_fails[\x00\x00\x00$] PASSED       [ 15%]
tests/basic_test.py::test_is_supported_fails[\x00\x00\x00$ftyp] PASSED   [ 15%]
tests/basic_test.py::test_is_supported_fails[\x00\x00\x00$ftypheiZ] PASSED [ 16%]
tests/basic_test.py::test_is_supported_fails[img4] PASSED                [ 16%]
tests/basic_test.py::test_heif_str PASSED                                [ 16%]
tests/basic_test.py::test_full_build SKIPPED (Only when building full
release)                                                                 [ 16%]
tests/basic_test.py::test_light_build SKIPPED (Only when building light
release)                                                                 [ 16%]
tests/basic_test.py::test_load_plugin SKIPPED (Only when plugins
present)                                                                 [ 16%]
tests/leaks_test.py::test_open_save_objects_leaks[image0] PASSED         [ 16%]
tests/leaks_test.py::test_open_save_objects_leaks[image1] PASSED         [ 16%]
tests/leaks_test.py::test_open_to_numpy_mem_leaks SKIPPED (run only on
x86_64)                                                                  [ 16%]
tests/leaks_test.py::test_color_profile_leaks[images/heif_other/cat.hif-NCLX] SKIPPED [ 17%]
tests/leaks_test.py::test_color_profile_leaks[images/heif_other/arrow.heic-ICC] SKIPPED [ 17%]
tests/leaks_test.py::test_metadata_leaks SKIPPED (run only on x86_64)    [ 17%]
tests/leaks_test.py::test_pillow_plugin_leaks SKIPPED (run only on
x86_64)                                                                  [ 17%]
tests/metadata_etc_test.py::test_heif_primary_image[HEIF] PASSED         [ 17%]
tests/metadata_etc_test.py::test_heif_primary_image[AVIF] Fatal Python error: Illegal instruction

Current thread 0x00000001f3a73ac0 (most recent call first):
  File "/private/tmp/nix-build-python3.12-pillow-heif-0.16.0.drv-0/source/pillow_heif/misc.py", line 405 in _finish_add_image
  File "/private/tmp/nix-build-python3.12-pillow-heif-0.16.0.drv-0/source/pillow_heif/misc.py", line 379 in add_image
  File "/private/tmp/nix-build-python3.12-pillow-heif-0.16.0.drv-0/source/pillow_heif/heif.py", line 574 in _encode_images
  File "/private/tmp/nix-build-python3.12-pillow-heif-0.16.0.drv-0/source/pillow_heif/heif.py", line 362 in save
  File "/private/tmp/nix-build-python3.12-pillow-heif-0.16.0.drv-0/source/tests/helpers.py", line 142 in create_heif
  File "/private/tmp/nix-build-python3.12-pillow-heif-0.16.0.drv-0/source/tests/metadata_etc_test.py", line 17 in test_heif_primary_image
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/python.py", line 195 in pytest_pyfunc_call
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/python.py", line 1772 in runtest
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/runner.py", line 172 in pytest_runtest_call
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/runner.py", line 240 in <lambda>
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/runner.py", line 340 in from_call
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/runner.py", line 239 in call_and_report
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/runner.py", line 134 in runtestprotocol
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/runner.py", line 115 in pytest_runtest_protocol
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/main.py", line 364 in pytest_runtestloop
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/main.py", line 339 in _main
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/main.py", line 285 in wrap_session
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/main.py", line 332 in pytest_cmdline_main
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_callers.py", line 102 in _multicall
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_manager.py", line 119 in _hookexec
  File "/nix/store/brvm1brl3klrkqh1dh8zqiba8v0aa9sn-python3.12-pluggy-1.4.0/lib/python3.12/site-packages/pluggy/_hooks.py", line 501 in __call__
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/config/__init__.py", line 174 in main
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/_pytest/config/__init__.py", line 197 in console_main
  File "/nix/store/ggjx693a2vl9sha4q1qqy50m6j0k6mm9-python3.12-pytest-8.1.1/lib/python3.12/site-packages/pytest/__main__.py", line 7 in <module>
  File "<frozen runpy>", line 88 in _run_code
  File "<frozen runpy>", line 198 in _run_module_as_main

Extension modules: PIL._imaging, PIL._imagingmath, _pillow_heif, numpy.core._multiarray_umath, numpy.core._multiarray_tests, numpy.linalg._umath_linalg, numpy.fft._pocketfft_internal, numpy.random._common, numpy.random.bit_generator, numpy.random._bounded_integers, numpy.random._mt19937, numpy.random.mtrand, numpy.random._philox, numpy.random._pcg64, numpy.random._sfc64, numpy.random._generator, PIL._webp, cv2, PIL._imagingcms, _testcapi (total: 20)
/nix/store/cgbhb3fyw74b3y1i5lm22ypz5hl9qmf0-pytest-check-hook/nix-support/setup-hook: line 53: 55863 Illegal instruction: 4  /nix/store/2r8fbgpabanb42zbdm4lngayc35wby8i-python3-3.12.3/bin/python3.12 -m pytest -k "not test_decode_threads and not test_opencv_crash" -vvv

Versions

3.11.9 (main, Apr  2 2024, 08:25:04) [Clang 16.0.6 ]
macOS-14.4.1-arm64-arm-64bit
0.16.0
{'libheif': '1.17.6', 'HEIF': 'x265 HEVC encoder (3.5+1-f0c1022b6)', 'AVIF': 'AOMedia Project AV1 Encoder 3.9.0', 'encoders': {'x265': 'x265 HEVC encoder (3.5+1-f0c1022b6)', 'aom': 'AOMedia Project AV1 Encoder 3.9.0', 'mask': 'mask'}, 'decoders': {'libde265': 'libde265 HEVC decoder, version 1.0.15', 'aom': 'AOMedia Project AV1 Decoder 3.9.0'}}

Reworked `options()` from `0.9.0` version

As we come closer to 1.0.0 version we need more consistent API for setting options.
Was looking how it is done in Pillow and liked it.

Current code:

pillow_heif.options().thumbnails = False

in new version will be changed to:

pillow_heif.options.THUMBNAILS= False

Usage when it is used a plugin will not be changed, old code will work the same way:

from pillow_heif import register_heif_opener
register_heif_opener(thumbnails=False)

It will require less code from me to support, will not break API for plugin use, and such code will be a bit faster.

Changes for code when use it not as a plugin:
pillow_heif.options().thumbnails=False -> pillow_heif.options.THUMBNAILS=False
pillow_heif.options().quality=100 -> pillow_heif.options.QUALITY=100
pillow_heif.options().save_to_12bit=True -> pillow_heif.options.SAVE_HDR_TO_12BIT=True

New IMPORTANT options (list will be updated as I currently working on this):

DECODE_THREADS=4
Option to set number of decode threads(when it is possible). Benchmarks will be posted after update released.
Usage of option for register_heif_opener :

register_heif_opener(decode_threads=10)

or

pillow_heif.options.DECODE_THREADS= 10

Libheif plugin support

Describe why it is important and where it will be useful

libheif has released a new version that has a number of new codec plugins, notably ffmpeg which would allow hardware accelerated encoding.

Describe your proposed solution

Using the dynamically compiled option for the plugins and having an option in the python library to specify the codec plugin to use.

Describe alternatives you've considered, if relevant

No response

Additional context

No response

Small memory leak when opening image with `nclx` color profile

Did not find the function call heif_nclx_color_profile_free in the sources, look like i missed it. :(

    im_heif = pillow_heif.open_heif("../tests/images/heif_other/cat.hif")  # from this repo
    for i in range(10000000):
        nclx = pillow_heif.private.read_color_profile(im_heif[0]._handle)

Eats 500mb of RAM at the end... ~60 bytes for each opening of image with nclx profile.

Affected Versions: This leak is present in all versions. Will add test for this...

Cannot install via PIP on raspberry pi

Describe the bug

When trying to install using PIP I get a very long error

Steps/Code to Reproduce

Try to install on raspberry pi using:
python3 -m pip install pi-heif

Expected Results

succesfull install

Actual Results

pi@frame:~ $ python3 -m pip install pi-heif
Defaulting to user installation because normal site-packages is not writeable
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting pi-heif
Using cached pi_heif-0.12.0.tar.gz (14.8 MB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Collecting pillow>=8.4.0 (from pi-heif)
Using cached https://www.piwheels.org/simple/pillow/Pillow-9.5.0-cp37-cp37m-linux_armv6l.whl (820 kB)
Building wheels for collected packages: pi-heif
Building wheel for pi-heif (pyproject.toml) ... error
error: subprocess-exited-with-error

× Building wheel for pi-heif (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> [162 lines of output]
running bdist_wheel
running build
running build_py
creating build
creating build/lib.linux-armv6l-cpython-37
creating build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/constants.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/_deffered_error.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/_version.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/HeifImagePlugin.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/_lib_info.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/init.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/as_plugin.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/AvifImagePlugin.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/options.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/misc.py -> build/lib.linux-armv6l-cpython-37/pi_heif
copying pi_heif/heif.py -> build/lib.linux-armv6l-cpython-37/pi_heif
running build_ext
libheif is already present.
building '_pi_heif' extension
creating build/temp.linux-armv6l-cpython-37
creating build/temp.linux-armv6l-cpython-37/pi_heif
arm-linux-gnueabihf-gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -g -flto -fuse-linker-plugin -ffat-lto-
objects -fPIC -I/usr/include -I/usr/local/include -I/usr/include/python3.7m -c pi_heif/_pi_heif.c -o build/temp.linux-armv6l-cpython-37/pi_heif/_pi_heif.o -Ofast -Werror
pi_heif/_pi_heif.c: In function ‘check_error’:
pi_heif/_pi_heif.c:31:14: error: ‘heif_error_Color_profile_does_not_exist’ undeclared (first use in this function); did you mean ‘heif_error_Input_does_not_exist’?
case heif_error_Color_profile_does_not_exist:
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_error_Input_does_not_exist
pi_heif/_pi_heif.c:31:14: note: each undeclared identifier is reported only once for each function it appears in
pi_heif/_pi_heif.c: In function ‘_CtxWriteImage_add_plane’:
pi_heif/_pi_heif.c:110:76: error: ‘heif_chroma_interleaved_RRGGBBAA_LE’ undeclared (first use in this function); did you mean ‘heif_chroma_interleaved_RGBA’?
if ((self->chroma == heif_chroma_interleaved_RGBA) || (self->chroma == heif_chroma_interleaved_RRGGBBAA_LE)) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_chroma_interleaved_RGBA
pi_heif/_pi_heif.c: In function ‘_CtxWriteImage_set_icc_profile’:
pi_heif/_pi_heif.c:474:13: error: implicit declaration of function ‘heif_image_set_raw_color_profile’; did you mean ‘heif_image_get_colorspace’? [-Werror=implicit-function-declaration]
error = heif_image_set_raw_color_profile(self->image, type, buffer.buf, (int)buffer.len);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_get_colorspace
pi_heif/_pi_heif.c:474:11: error: incompatible types when assigning to type ‘struct heif_error’ from type ‘int’
error = heif_image_set_raw_color_profile(self->image, type, buffer.buf, (int)buffer.len);
^
pi_heif/_pi_heif.c: In function ‘_CtxWriteImage_set_nclx_profile’:
pi_heif/_pi_heif.c:490:58: error: implicit declaration of function ‘heif_nclx_color_profile_alloc’ [-Werror=implicit-function-declaration]
struct heif_color_profile_nclx* nclx_color_profile = heif_nclx_color_profile_alloc();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pi_heif/_pi_heif.c:490:58: error: initialization of ‘struct heif_color_profile_nclx *’ from ‘int’ makes pointer from integer without a cast [-Werror=int-conversion]
pi_heif/_pi_heif.c:491:23: error: dereferencing pointer to incomplete type ‘struct heif_color_profile_nclx’
nclx_color_profile->color_primaries = color_primaries;
^~
pi_heif/_pi_heif.c:495:13: error: implicit declaration of function ‘heif_image_set_nclx_color_profile’; did you mean ‘heif_image_get_colorspace’? [-Werror=implicit-function-declaration]
error = heif_image_set_nclx_color_profile(self->image, nclx_color_profile);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_get_colorspace
pi_heif/_pi_heif.c:495:11: error: incompatible types when assigning to type ‘struct heif_error’ from type ‘int’
error = heif_image_set_nclx_color_profile(self->image, nclx_color_profile);
^
pi_heif/_pi_heif.c:496:5: error: implicit declaration of function ‘heif_nclx_color_profile_free’ [-Werror=implicit-function-declaration]
heif_nclx_color_profile_free(nclx_color_profile);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
pi_heif/_pi_heif.c: In function ‘_CtxWriteImage_set_metadata’:
pi_heif/_pi_heif.c:567:13: error: implicit declaration of function ‘heif_context_add_generic_metadata’; did you mean ‘heif_context_add_exif_metadata’? [-Werror=implicit-function-declaration]
error = heif_context_add_generic_metadata(ctx_write->ctx, self->handle, buffer.buf, (int)buffer.len, type, content_type);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_context_add_exif_metadata
pi_heif/_pi_heif.c:567:11: error: incompatible types when assigning to type ‘struct heif_error’ from type ‘int’
error = heif_context_add_generic_metadata(ctx_write->ctx, self->handle, buffer.buf, (int)buffer.len, type, content_type);
^
pi_heif/_pi_heif.c: In function ‘_CtxWriteImage_create’:
pi_heif/_pi_heif.c:654:9: error: implicit declaration of function ‘heif_image_set_premultiplied_alpha’; did you mean ‘heif_image_get_plane_readonly’? [-Werror=implicit-function-declaration]
heif_image_set_premultiplied_alpha(image, 1);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_get_plane_readonly
pi_heif/_pi_heif.c: In function ‘_CtxImage’:
pi_heif/_pi_heif.c:719:33: error: implicit declaration of function ‘heif_image_handle_is_premultiplied_alpha’; did you mean ‘heif_image_handle_is_primary_image’? [-Werror=implicit-function-declarat
ion]
strcat(ctx_image->mode, heif_image_handle_is_premultiplied_alpha(handle) ? "a" : "A");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_handle_is_primary_image
pi_heif/_pi_heif.c:720:23: error: implicit declaration of function ‘heif_image_handle_get_luma_bits_per_pixel’; did you mean ‘heif_image_get_bits_per_pixel’? [-Werror=implicit-function-declaration]
ctx_image->bits = heif_image_handle_get_luma_bits_per_pixel(handle);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_get_bits_per_pixel
pi_heif/_pi_heif.c: In function ‘_CtxImage_color_profile’:
pi_heif/_pi_heif.c:760:10: error: variable ‘profile_type’ has initializer but incomplete type
enum heif_color_profile_type profile_type = heif_image_handle_get_color_profile_type(self->handle);
^~~~~~~~~~~~~~~~~~~~~~~
pi_heif/_pi_heif.c:760:49: error: implicit declaration of function ‘heif_image_handle_get_color_profile_type’; did you mean ‘heif_image_handle_get_metadata_type’? [-Werror=implicit-function-declara
tion]
enum heif_color_profile_type profile_type = heif_image_handle_get_color_profile_type(self->handle);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_handle_get_metadata_type
pi_heif/_pi_heif.c:760:34: error: storage size of ‘profile_type’ isn’t known
enum heif_color_profile_type profile_type = heif_image_handle_get_color_profile_type(self->handle);
^~~~~~~~~~~~
pi_heif/_pi_heif.c:761:25: error: ‘heif_color_profile_type_not_present’ undeclared (first use in this function); did you mean ‘heif_color_profile_type’?
if (profile_type == heif_color_profile_type_not_present)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_handle_get_metadata_size 13:15:12 [10/255]
pi_heif/_pi_heif.c:803:30: error: implicit declaration of function ‘heif_image_handle_get_raw_color_profile’; did you mean ‘heif_image_handle_get_metadata_size’? [-Werror=implicit-function-declarat
ion]
if (!check_error(heif_image_handle_get_raw_color_profile(self->handle, data)))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_handle_get_metadata_size
pi_heif/_pi_heif.c:803:30: error: incompatible type for argument 1 of ‘check_error’
if (!check_error(heif_image_handle_get_raw_color_profile(self->handle, data)))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pi_heif/_pi_heif.c:13:35: note: expected ‘struct heif_error’ but argument is of type ‘int’
int check_error(struct heif_error error) {
~~~~~~~~~~~~~~~~~~^~~~~
pi_heif/_pi_heif.c:760:34: error: unused variable ‘profile_type’ [-Werror=unused-variable]
enum heif_color_profile_type profile_type = heif_image_handle_get_color_profile_type(self->handle);
^~~~~~~~~~~~
pi_heif/_pi_heif.c: In function ‘decode_image’:
pi_heif/_pi_heif.c:903:19: error: ‘struct heif_decoding_options’ has no member named ‘convert_hdr_to_8bit’
decode_options->convert_hdr_to_8bit = self->hdr_to_8bit;
^~
pi_heif/_pi_heif.c:918:22: error: ‘heif_chroma_interleaved_RRGGBBAA_LE’ undeclared (first use in this function); did you mean ‘heif_chroma_interleaved_RGBA’?
chroma = heif_chroma_interleaved_RRGGBBAA_LE;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_chroma_interleaved_RGBA
pi_heif/_pi_heif.c:922:22: error: ‘heif_chroma_interleaved_RRGGBB_LE’ undeclared (first use in this function); did you mean ‘heif_chroma_interleaved_RGBA’?
chroma = heif_chroma_interleaved_RRGGBB_LE;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_chroma_interleaved_RGBA
pi_heif/_pi_heif.c:941:25: error: implicit declaration of function ‘heif_image_get_primary_width’; did you mean ‘heif_image_get_width’? [-Werror=implicit-function-declaration]
int decoded_width = heif_image_get_primary_width(self->heif_image);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_get_width
pi_heif/_pi_heif.c:942:26: error: implicit declaration of function ‘heif_image_get_primary_height’; did you mean ‘heif_image_get_height’? [-Werror=implicit-function-declaration]
int decoded_height = heif_image_get_primary_height(self->heif_image);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
heif_image_get_height
pi_heif/_pi_heif.c: In function ‘setup_module’:
pi_heif/_pi_heif.c:1181:52: error: ‘heif_compression_AV1’ undeclared (first use in this function); did you mean ‘heif_compression_AVC’?
if (heif_context_get_encoder_descriptors(NULL, heif_compression_AV1, NULL, &encoder_descriptor, 1))
^~~~~~~~~~~~~~~~~~~~
heif_compression_AVC
cc1: all warnings being treated as errors
error: command '/usr/bin/arm-linux-gnueabihf-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: Failed building wheel for pi-heif
Failed to build pi-heif
ERROR: Could not build wheels for pi-heif, which is required to install pyproject.toml-based projects

Versions

> import platform, sys, pillow_heif
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'pillow_heif'

issue with heic files using Pillow-SIMD but not Pillow

Describe the bug

The script below works with pillow-10.1.0 but throws an error with Pillow-SIMD-9.0.0.post1

Steps/Code to Reproduce

from PIL import Image
from pillow_heif import register_heif_opener

register_heif_opener()

im = Image.open('testimage.heic')
im.thumbnail((200, 200))
im.save('test.jpg', 'jpeg')

Expected Results

No error is thrown using Pillow-SIMD

Actual Results

PIL.UnidentifiedImageError: cannot identify image file "/Users/testuser/testimage.heic"

Versions

3.11.5 (main, Sep  1 2023, 11:37:07) [Clang 14.0.3 (clang-1403.0.22.14.1)]
macOS-13.6.1-x86_64-i386-64bit
0.13.1
{'libheif': '1.16.2', 'HEIF': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'AVIF': 'AOMedia Project AV1 Encoder 3.7.0'}

Libheif: Update to version 1.13.0

Most changes are already present in last pillow-heif release, but anyway...

  • PR to MSYS2 repository with update
  • Update heif.h with only necessary changes
  • Wait for brew update
  • Adjust tests to pass both 1.12 and 1.13 versions
  • Remove patches for libheif
  • Customize GA release workflows with some nice things

Approximately one to three weeks until the new release

Tracking issue to updating libheif to 1.14.0

New LibHeif release
Brew PR
MSYS2 PR

LibHeif 1.14.0 will be included in 0.8.0 version.
Estimated time for release approximately 3-5 days.

Notes:

  • SVT binaries will not be included, for now.
  • add XMP header compression (using zlib) - will still be missed, do not want to remove ability to build this project with 1.12.0 version
  • EXIF/XMP is already get handled, so no changes will be there, at least for now.

A little bug

Describe the bug

origin:as_opener.py line58

extensions = [".heic", ".hif"]

I think it may be follow:

extensions = [".heic", ".heif"]

Steps/Code to Reproduce

none

Expected Results

none

Actual Results

none

Versions

none

How to save "nclx_profile" in a HEIC image?

I'm trying to add the "nclx_profile" metadata to a new HEIC file.
I'm setting this key as a dict in pil_image.info, but when I save and load the photo the data isn't there.

Full example code to reproduce:

import numpy as np
import pillow_heif
from PIL import Image
from io import BytesIO

from pillow_heif import register_heif_opener
register_heif_opener()

nclx_profile = {
 'color_primaries': 1,
 'transfer_characteristics': 2,
 'matrix_coefficients': 1,
 'full_range_flag': 1,
 'color_primary_red_x': 0.0,
 'color_primary_red_y': 0.0,
 'color_primary_green_x': 0.0,
 'color_primary_green_y': 0.0,
 'color_primary_blue_x': 0.0,
 'color_primary_blue_y': 0.0,
 'color_primary_white_x': 0.0,
 'color_primary_white_y': 0.0
}

# create a new, blank image
pil_image = Image.fromarray(np.ones((16, 16, 3)).astype(np.uint8))
# sset nclx_profile
pil_image.info['nclx_profile'] = nclx_profile
# save to an in-memory file (works if we save to disk too)
tmp = BytesIO()
pil_image.save(tmp, format="heif")
# re-open the image and see if nclx_profile is there
Image.open(tmp).info['nclx_profile']    # KeyError!

Pillow plugin: not proper `mimetype` get registered

def register_heif_opener():
    ...
    Image.register_mime(HeifImageFile.format, "image/heic")
    Image.register_mime(HeifImageFile.format, "image/heic-sequence")
    Image.register_mime(HeifImageFile.format, "image/heif")
    Image.register_mime(HeifImageFile.format, "image/heif-sequence")
    ...

In the end format HEIF has registered mimetype to image/heif-sequence

The main question, what mimetype choose for HEIF format: image/heic or image/heif ?
We can choose only one...

Can't build wheel on ubuntu focal

Hi,

I was trying to build a wheel for armhf on ubuntu focal and it never completes successfully. Then I tried to build it for amd64 to rule out 32bit related issues and that also fails (with the option --no-binary pillow_heif).

The official wheels seem to work, but since there are no wheels for armhf, I have to compile.

I do have the listed build deps libffi, libheif-dev and libde265-dev installed (along with a whole lot of other build deps for other wheels). For reference, I'm using this dockerfile: https://github.com/linuxserver/wheelie/blob/main/Dockerfile

Here's the output of pip wheel --wheel-dir=/build --no-cache-dir -v --no-binary pillow_heif pillow_heif on ubuntu focal amd64:
https://pastebin.com/vngx8kqx

Am I missing another build dep? Any ideas?

Thanks

Failed to build x265 in freebsd 13.2

Describe the bug

Impossible to build x265 dependency on freebsd 13.2.

Missing the <sys/stat.h> header in ringmem.cpp

Fix it in tmp directory is useless because the build script at each call replace in tmp dir with the buggy x265.

Steps/Code to Reproduce

Clone this repo on freebsd with python 3.9 and clang 15.0.7 x265 will fail.

Expected Results

X265 be build.

Actual Results

[ 98%] Building CXX object common/CMakeFiles/common.dir/ringmem.cpp.o 1 warning generated. /tmp/ph_build_stuff/x265/source/common/ringmem.cpp:163:27: error: use of undeclared identifier 'S_IRUSR' mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; ^ /tmp/ph_build_stuff/x265/source/common/ringmem.cpp:163:37: error: use of undeclared identifier 'S_IWUSR' mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; ^ /tmp/ph_build_stuff/x265/source/common/ringmem.cpp:163:47: error: use of undeclared identifier 'S_IRGRP' mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; ^ /tmp/ph_build_stuff/x265/source/common/ringmem.cpp:163:57: error: use of undeclared identifier 'S_IWGRP' mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; ^ /tmp/ph_build_stuff/x265/source/common/ringmem.cpp:163:67: error: use of undeclared identifier 'S_IROTH' mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; ^ /tmp/ph_build_stuff/x265/source/common/ringmem.cpp:163:77: error: use of undeclared identifier 'S_IWOTH' mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; ^

Versions

Imposible to install pillow_heif.

XMP containing invalid bytes leading fail to decode image

Describe the bug

Fail to decode image just because of some invalid bytes in XMP.

Steps/Code to Reproduce

from PIL import Image
from pillow_heif import register_heif_opener

register_heif_opener()

im = Image.open("images/input.heic")  # do whatever need with a Pillow image

input.heic: https://easyupload.io/2p5p0d

Expected Results

No error is thrown or warning prompt.

Actual Results

image

Versions

3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)]
Windows-10-10.0.19041-SP0
0.9.2
{'version': {'libheif': '1.14.2', 'x265': 'x265 HEVC encoder (3.4+31-6722fce1f)', 'aom': 'AOMedia Project AV1 Encoder v3.5.0'}, 'decoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}, 'encoders': {'HEVC': 1, 'AV1': 1, 'AVC': 0}}

support of native non-shifted HDR [v0.11.2]

background

Initially, pillow_heif contained such a feature, in versions 0.9.x it was, by default all 10/12 bit files were opened in 10/12 bit mode, and after that you could optionally convert the image to 16 bit with the call to convert_to

As I did not see any code that uses this, and OpenCV uses 16 bit for HDR by default, I made an assumption that make a default 16 bit mode is fine and removed that possibility to open images in 10/12 bit mode( RGB;10, BGR;10, etc if someone remeber).

As in that time there was a request to make version without cffi with native C module, I moved all that conversions to C module and it even did not get slower(with additional shifting of 10/12 bit images to 16 bit, I mean)

currently

I was very impressed to see this message: strukturag/libheif#562 (comment)

There is shifting before saving and after opening.

What made me think, is it possible to return the native modes of 10/12 bits from versions 0.9.x?
In the way that there would be no loss of compatibility with what is already here, because idea to open images in 16 bit mode by default.

And I can reply to myself after small investigation, that yes, it is possible and will be useful in future.

Changes:

Currently there is a hidden parameter postprocess to open_heif/read_heif.

It will be removed (it was not documented)

Two new parameters that will instead appears:

remove_stride - default True (this will be still undocumented, cause I do not know cases when someone will wanted this behaviour off)
hdr_to_16bit - default True (this will be documented)

This change is fully compatible with 0.10-0.11 versions, no need to change anything.

This allows rewrite code from post without shifting, just do:

im = pillow_heif.open_heif("image.heic", convert_hdr_to_8bit =False, hdr_to_16bit=False)

If image was HDR, then it will be opened in 10 or 12 bit mode(in that bitness in which it is).

Also restore ability to accept RGB,BGR,10,12 bit and so on. See commit: 129d9f8

Packaging as egg says "ModuleNotFoundError: No module named '_pillow_heif_cffi'"

Describe the bug

I wanted to make this usable on a system where I can't run pip to install this. I did the usual python3 setup.py bdist_egg and got an .egg file.

But upon trying to import something, I get:

  File "/etc/hooks/myScript.py", line 13, in <module>
    from pillow_heif import register_heif_opener
  File "/etc/hooks/./pillow_heif.egg/pillow_heif/__init__.py", line 7, in <module>
  File "/etc/hooks/./pillow_heif.egg/pillow_heif/_lib_info.py", line 5, in <module>
ModuleNotFoundError: No module named '_pillow_heif_cffi'

Same result with building a .whl with python3 -m build

Steps/Code to Reproduce

Package as .egg and try to import it a pillow_heif module.

Expected Results

I can use pillow_heif.

Actual Results

I can't use pillow_heif.

Versions

Python 3.10, Linux 64-bit, latest pillow_heif release

AttributeError when calling Image.verify()

Problem description

When calling Image.verify() on a .heic image, the program raise an AttributeError exception with the following message:

AttributeError: 'NoneType' object has no attribute 'close'

Code

You can reproduce the error with the following code.

from PIL import Image
from pillow_heif import register_heif_opener

register_heif_opener()

image = Image.open("filename.heic")
image.verify()

System Info

  • OS: Mac BigSur & Debian 10
  • Python 3.8.12
  • Pillow 9.0.1
  • pillow-heif 0.1.6

Sigal support

Describe why it is important and where it will be useful

Currently investigating if it is needed...

Describe your proposed solution

Adding file to pass to register as a plugin with Sigal

Describe alternatives you've considered, if relevant

Registration of plugins-modules in Sigal

    for plugin in settings['plugins']:
        try:
            if isinstance(plugin, str):
                mod = importlib.import_module(plugin)
                mod.register(settings)
            else:
                plugin.register(settings)
            logger.debug('Registered plugin %s', plugin)

Additional context

Will be good if someone who uses Sigal, says how to use it in proper way. And when to register module and when a plugin.

Like @Simon566 for example.

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.