Pillow icon indicating copy to clipboard operation
Pillow copied to clipboard

Image.open() fails with struct.error with Photoshop .psd files

Open kporangehat opened this issue 1 year ago • 1 comments

What did you do?

Trying to process a bunch of Photoshop images primarily to obtain their size, mode, and resolution. These files open fine natively without warnings or errors.

Sample file process:

from PIL import ImageFile, Image

ImageFile.LOAD_TRUNCATED_IMAGES = True

with Image.open("/Users/kp/dev/pil_psd_test/struct_error_file.psd") as img:
    print(img.format, img.size, img.mode)

What did you expect to happen?

The file to open and report the format, size, and mode

What actually happened?

Traceback (most recent call last):
  File "/Users/kp/dev/sandbox/pil_psd_test.py", line 48, in <module>
    with Image.open("/Users/kp/dev/pil_psd_test/struct_error_file.psd") as img:
  File "/Users/kp/dev/sandbox/.venv/lib/python3.9/site-packages/PIL/Image.py", line 3309, in open
    raise UnidentifiedImageError(msg)
PIL.UnidentifiedImageError: cannot identify image file '/Users/kp/dev/pil_psd_test/struct_error_file.psd'

Turning on the debug log message here, I can see the actual error is:

...
DEBUG:PIL.Image:
Traceback (most recent call last):
  File "/Users/kp/dev/sandbox/.venv/lib/python3.9/site-packages/PIL/ImageFile.py", line 137, in __init__
    self._open()
  File "/Users/kp/dev/sandbox/.venv/lib/python3.9/site-packages/PIL/PsdImagePlugin.py", line 132, in _open
    self.layers = _layerinfo(_layer_data, size)
  File "/Users/kp/dev/sandbox/.venv/lib/python3.9/site-packages/PIL/PsdImagePlugin.py", line 249, in _layerinfo
    t = _maketile(fp, m, bbox, 1)
  File "/Users/kp/dev/sandbox/.venv/lib/python3.9/site-packages/PIL/PsdImagePlugin.py", line 261, in _maketile
    compression = i16(read(2))
  File "/Users/kp/dev/sandbox/.venv/lib/python3.9/site-packages/PIL/_binary.py", line 81, in i16be
    return unpack_from(">H", c, o)[0]
struct.error: unpack_from requires a buffer of at least 2 bytes for unpacking 2 bytes at offset 0 (actual buffer size is 0)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/kp/dev/sandbox/.venv/lib/python3.9/site-packages/PIL/Image.py", line 3276, in _open_core
    im = factory(fp, filename)
  File "/Users/kp/dev/sandbox/.venv/lib/python3.9/site-packages/PIL/ImageFile.py", line 145, in __init__
    raise SyntaxError(v) from v
SyntaxError: unpack_from requires a buffer of at least 2 bytes for unpacking 2 bytes at offset 0 (actual buffer size is 0)
...

Sample image is here: struct_error_file.psd.zip

What are your OS, Python and Pillow versions?

  • OS: MacOS 14.2.1 (23C71)
  • Python: 3.9.17
  • Pillow: 10.2.0
see above

kporangehat avatar Jan 09 '24 14:01 kporangehat

Looking at your image with GIMP, one of the layers has a negative offset. bg1

I've created PR #7706 to handle this. With that,

from PIL import Image
with Image.open("struct_error_file.psd") as img:
    img.save("out.png")

gives out

radarhere avatar Jan 10 '24 07:01 radarhere