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

np.array(img) should not hide errors for corrupted images #5084

Closed
akamaus opened this issue Dec 10, 2020 · 5 comments · Fixed by #5379
Closed

np.array(img) should not hide errors for corrupted images #5084

akamaus opened this issue Dec 10, 2020 · 5 comments · Fixed by #5379
Labels

Comments

@akamaus
Copy link

akamaus commented Dec 10, 2020

What did you do?

I spent a lot of time debugging a code which loads png images from disk and converts them to numpy arrays to do some processing.

What did you expect to happen?

If I take any png and corrupt it, say, by truncating,

$ dd if=good.png of=corrupted.png bs=1024 count=10
$ python

I expect the following code to fail with some exception because image pixels can not be read into an array.

>>> from PIL import Image
>>> import numpy as np
>>> img = Image.open('corrupted.png') 
>>> arr = np.array(img)

What actually happened?

Instead, I got an object array with a single element:

>>> print(arr)
<PIL.PngImagePlugin.PngImageFile image mode=RGB size=384x288 at 0x7F38258C6240>

and now the code fails later with a strange error message, like:

>>> arr / 255
TypeError: unsupported operand type(s) for /: 'PngImageFile' and 'int'

img.verify() behaves strangely, too

Funny and counter-intuitive thing, if I try instead doing:

>>> img = Image.open('good.png') 
>>> img.verify()
>>> arr = np.array(img)
>>> arr / 255
TypeError: unsupported operand type(s) for /: 'PngImageFile' and 'int'

I still got an error presumably because calling verify() makes image unusable, but again, np.array() doesn't care. So now the code fails for all good images.

What are your OS, Python and Pillow versions?

  • OS: ubuntu-18.04
  • Python: 3.6
  • Pillow: 8.0.1
@radarhere
Copy link
Member

When I try and replicate this, I find that

img.__array_interface__

throws an OSError, but

np.array(img)

doesn't. So depending on how you look at this, the problem is either that Pillow's __array_interface__ isn't throwing the right kind of exception, or it is that numpy is catching the OSError.

@kmilos
Copy link
Contributor

kmilos commented Dec 14, 2020

I think this shows up in other guises, like #3863

Masking the real error is not ideal indeed.

@radarhere
Copy link
Member

Confirmed to be a bug in numpy - see the discussion starting at https://gitter.im/numpy/numpy?at=6067b4ef3153ce63a3b6dcad

Screen Shot 2021-04-03 at 11 44 27 am

We could raise a RecursionError or MemoryError to make np.array fail, but that wouldn't be reflecting the cause of the error.

@radarhere
Copy link
Member

I've taken the suggestion of using __array__ and created #5379

@radarhere
Copy link
Member

NumPy 1.23 has been released, fixing the bug.

The Pillow workaround has been reverted, and will no longer be present in the next release of Pillow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants