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

Error and Corruption When Reopening PSD Files Saved with psd-tools #372

Open
magurotaisa opened this issue Jul 31, 2023 · 2 comments
Open
Labels

Comments

@magurotaisa
Copy link

Describe the bug
When attempting to reopen a psd file saved using psd-tools, an error occurs, preventing successful reopening.

To Reproduce

Steps to reproduce the behavior:

  1. Open a PSD file using psd-tools, e.g., "error_sample.psd".
  2. Save the opened PSD file as "sample.psd" using the following code in Python:
psd = PSDImage.open("error_sample.psd")
psd.save("sample.psd")
  1. Try to reopen "sample.psd" using psd-tools with the following code in Python:
PSDImage.open("sample.psd")

Expected behavior
Both "error_sample.psd" and "sample.psd" should be identical, and "sample.psd" should be successfully reopened without any errors.

File and screenshots
Error file:
error_sample.psd.zip

Error log:

File ~/.pyenv/versions/3.8.10/lib/python3.8/enum.py:663, in Enum.__new__(cls, value)
    661 ve_exc = ValueError("%r is not a valid %s" % (value, cls.__name__))
    662 if result is None and exc is None:
--> 663     raise ve_exc
    664 elif exc is None:
    665     exc = TypeError(
    666             'error in %s._missing_: returned %r instead of None or a valid member'
    667             % (cls.__name__, result)
    668             )

ValueError: b'loat' is not a valid OSType

Environment

  • Python [3.8.10]
  • Version [v1.9.28]

Additional context
After investigating the issue, it has been discovered that the error occurs when there are layers that require clipping during the Lab to RGB conversion process.

@kyamagu kyamagu added the bug label Aug 1, 2023
@kyamagu
Copy link
Contributor

kyamagu commented Aug 1, 2023

This is likely a bug in the low-level psd structure

@oh-ok
Copy link
Contributor

oh-ok commented Feb 22, 2024

Found the cause of this. It affects every PSD that contains a SolidColor layer encoded with stringID instead of charID.

The redFloat, blueFloat and greenFloat keys are being written out as OSTypes rather than Pascal strings since they're in this _TERMS set:

def write_length_and_key(fp, value):
"""
Helper to write descriptor key.
"""
written = write_fmt(fp, "I", 0 if value in _TERMS else len(value))
written += write_bytes(fp, value)
return written

Since those are the only keys with length greater than 4 (at least at the moment) you can just add a condition to only include length 4 byte strings to fix this, or move the keys to their own separate class.

_TERMS = set(
item.value for kls in (Klass, Enum, Event, Form, Key, Type, Unit) for item in kls
)

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

No branches or pull requests

3 participants