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

UnidentifiedImageError opening simple PSD using shapes and masks #8034

Open
ppearsonhutch opened this issue Apr 30, 2024 · 7 comments
Open

Comments

@ppearsonhutch
Copy link

ppearsonhutch commented Apr 30, 2024

What did you do?

Attempted to open the supplied psd image with PIL.open() in python.

I didn't actually create this image myself, nor can I figure out what exactly is wrong with it, but I've managed to reduce the cause of the issue down to 2 shape layers, one with a layer mask. Removing either layer fixes the error. Additionally, inserting a new empty layer between the two layers also fixes the error. So it's not critical and I can work around it, but I have a feeling it's a bug in the psd opening logic if it's somehow fixed by adding blank layers.

Image below of the layers:
Screenshot 2024-04-30 at 21 34 44

What did you expect to happen?

No PIL.UnidentifiedImageError when opening the PSD.

What actually happened?

Received a PIL.UnidentifiedImageError when opening the PSD with PIL.open()

What are your OS, Python and Pillow versions?

  • OS: MacOS Sonoma 14.4.1
  • Python: 3.9.6 (via shim/pyenv)
  • Pillow: 10.3.0 (via pip)
--------------------------------------------------------------------
Pillow 10.3.0
Python 3.9.6 (default, Apr  6 2024, 22:52:34)
       [Clang 15.0.0 (clang-1500.3.9.4)]
--------------------------------------------------------------------
Python executable is /Users/<username>/.pyenv/versions/3.9.6/bin/python3
System Python files loaded from /Users/<username>/.pyenv/versions/3.9.6
--------------------------------------------------------------------
Python Pillow modules loaded from /Users/<username>/.pyenv/versions/3.9.6/lib/python3.9/site-packages/PIL
Binary Pillow modules loaded from /Users/<username>/.pyenv/versions/3.9.6/lib/python3.9/site-packages/PIL
--------------------------------------------------------------------
--- PIL CORE support ok, compiled for 10.3.0
--- TKINTER support ok, loaded 8.6
--- FREETYPE2 support ok, loaded 2.13.2
--- LITTLECMS2 support ok, loaded 2.16
--- WEBP support ok, loaded 1.3.2
--- WEBP Transparency support ok
--- WEBPMUX support ok
--- WEBP Animation support ok
--- JPEG support ok, compiled for libjpeg-turbo 3.0.2
--- OPENJPEG (JPEG2000) support ok, loaded 2.5.2
--- ZLIB (PNG/ZIP) support ok, loaded 1.3.1
--- LIBTIFF support ok, loaded 4.6.0
*** RAQM (Bidirectional Text) support not installed
*** LIBIMAGEQUANT (Quantization method) support not installed
--- XCB (X protocol) support ok
--------------------------------------------------------------------

Image is attached as zip because github doesn't allow psd attachments.
ExamplePSD.psd.zip (29kb)

Code to reproduce (simple open PSD script):

import sys
import PIL
from PIL import Image

def open_psd(psd_file_path):
    # Open the PSD file
    psd_image = Image.open(psd_file_path)
    
if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python3 piltest.py <input_psd_path>")
    else:
        psd_file_path = sys.argv[1]
        open_psd(psd_file_path)
@radarhere radarhere changed the title PIL.UnidentifiedImageError opening simple PSD using shapes and masks. UnidentifiedImageError opening simple PSD using shapes and masks Apr 30, 2024
@radarhere
Copy link
Member

Removing either layer fixes the error. Additionally, inserting a new empty layer between the two layers also fixes the error.

Would it be an easy task for you to attach these variations as well for comparison?

@ppearsonhutch
Copy link
Author

No problem at all. Here's four variants.
I've included in each zip a screen clipping of what the layers look like in photoshop.
All the following .psd files open successfully with PIL.

ExamplePSDWithBottomLayerMaskRemoved.zip

ExamplePSDWithTopMostLayerRemoved.zip

ExamplePSDWithEmptyLayerAdded.zip

ExamplePSDWithBottomLayerRemoved.zip

@radarhere
Copy link
Member

So, the specification states that

If the compression code is 1, the image data starts with the byte counts for all the scan lines in the channel (LayerBottom-LayerTop)

and as far as I can see, the byte counts in the first image become incorrect at the end, or end prematurely.

However, your code is only trying to open the image. You are not trying to access the PSD layers. I have created #8039 to delay parsing the layers until the user needs Pillow to do so, and with that, your image can be opened successfully - you just can't extract the layers individually.

@radarhere
Copy link
Member

Would that be sufficient to resolve this, or do you think that the image is valid and further investigation should be done into reading the layers?

@ppearsonhutch
Copy link
Author

ppearsonhutch commented May 13, 2024

Apologies for the delay replying. Thanks for the fix!
I do actually intend to access the layers later in my use case, so I'm not sure this fix is sufficient for my usage.

I'm pretty confident this image is valid, as I can open photoshop and create a similar image using the same layer format easily and get the same error. However I can easily fix these images by hand so any further fix is not urgently required.

@radarhere
Copy link
Member

radarhere commented May 18, 2024

If we were to figure out the error, then the 'blue 1' layer would be readable.

However, the 'blue' layer would still not be, as Pillow doesn't currently support reading layers with user supplied masks. If you're interested in accessing that as well, then this is a feature request - that doesn't change anything really, just letting you know it may be more difficult than you expected.

@ppearsonhutch
Copy link
Author

ppearsonhutch commented May 23, 2024

I appreciate this is probably quite tricky given the complexity of PSDs and layers.

I have done a bit of experimenting and realised that I am able to access the layer information by using a second library psd_tools which means the fix you've implemented so far does resolve the issue I was encountering. I can simply use Pillow to do the image conversion and psd_tools to access the layer information.

Thanks again for your help so far.

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

No branches or pull requests

2 participants