Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when trying to get exif image data #92

Closed
mxsleo opened this issue Apr 27, 2023 · 6 comments
Closed

Crash when trying to get exif image data #92

mxsleo opened this issue Apr 27, 2023 · 6 comments
Labels
bug Something isn't working fixed Fixed in last version

Comments

@mxsleo
Copy link

mxsleo commented Apr 27, 2023

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
@bigcat88 bigcat88 self-assigned this Apr 27, 2023
@bigcat88 bigcat88 added the bug Something isn't working label Apr 27, 2023
@bigcat88
Copy link
Owner

Can I take this image to dataset for tests, e.g. what copyright does it have?

@mxsleo
Copy link
Author

mxsleo commented Apr 27, 2023

Of course, use it as you want. It is just a simple photo of nothing personal or copyright protected made by me with a camera application applying no additional copyright restrictions.

bigcat88 added a commit that referenced this issue Apr 27, 2023
Signed-off-by: bigcat88 <bigcat88@icloud.com>
@bigcat88
Copy link
Owner

bigcat88 commented Apr 27, 2023

As Pillow do not have all tag id's for this image, you can use: print(TAGS.get(k, "XXX"), ":", v) to display it(this is changed from what is in examples folder).

    exif = im.getexif()
    if exif:
        exif = exif._get_merged_dict()  # noqa
    for k, v in exif.items():
        if isinstance(v, bytes) and len(v) > 8:
            print(f"{TAGS[k]} : size {len(v)} bytes")
        else:
            print(TAGS.get(k, "XXX"), ":", v)

Can't promise that release will be in this week with fix, but in two weeks I will try to publish it, when will have what to fix more.

@bigcat88 bigcat88 added the fixed in upcoming release fix will arrive with next release label Apr 27, 2023
@mxsleo
Copy link
Author

mxsleo commented Apr 28, 2023

Thank you very much for the tip and for the fix! I will try this asap. Patiently waiting for the new release!

bigcat88 added a commit that referenced this issue Apr 30, 2023
Signed-off-by: bigcat88 <bigcat88@icloud.com>
@bigcat88
Copy link
Owner

The error was bigger than I thought at first.
There was also incorrect handling of EXIF data when EXIF did not start with bExif\x00\x00.
So, the new release fixes two EXIF bugs:

  1. Correct handling when EXIF does not start with bExif\x00\x00.
  2. Adding support for some data before the actual EXIF data (your case of Xiaomi storing 4 bytes with something before the actual EXIF)

@bigcat88 bigcat88 removed their assignment Apr 30, 2023
@bigcat88 bigcat88 added fixed Fixed in last version and removed fixed in upcoming release fix will arrive with next release labels Apr 30, 2023
@mxsleo
Copy link
Author

mxsleo commented Apr 30, 2023

It's great to see, that the bug was fixed. Thank you very much for your work! I guess, we can now close this issue?...

@mxsleo mxsleo closed this as completed Apr 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixed Fixed in last version
Projects
None yet
Development

No branches or pull requests

2 participants