Skip to content

fix(psd): skip empty layers when reading PSD files - #5562

Merged
lgritz merged 7 commits into
AcademySoftwareFoundation:mainfrom
jeevan6996:fix/psd-empty-layers
Oct 18, 2026
Merged

lgritz merged 7 commits into
AcademySoftwareFoundation:mainfrom
jeevan6996:fix/psd-empty-layers

Conversation

@jeevan6996

@jeevan6996 jeevan6996 commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #5561.

Description

PSD files containing empty layers could fail to open. This change skips layers with zero width or height while preserving the composite image and the order of populated layers. Canvas validation and PSD/PSB dimension limits remain enforced.

Tests

Added checked-in PSD/PSB regression fixtures covering empty layers, subimage ordering and pixel hashes, compressed channels, layer masks, and invalid inputs. The fixture-generation script is retained for reference and maintenance.

The reporter confirmed that the patch fixes all three reported files. (#5562 (comment))

Assisted-by: Codex / GPT-6-Astra

@linux-foundation-easycla

linux-foundation-easycla Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

Allow empty dimensions only for layer records, preserving canvas and decoded channel validation and all upper size limits.

Assisted-by: Codex / model identifier unavailable
Signed-off-by: jeevan6996 <jeevanpawar5890@gmail.com>
Verify hidden empty layers retain subimage ordering and hashes, with a populated hidden-layer control.

Assisted-by: Codex / model identifier unavailable
Signed-off-by: jeevan6996 <jeevanpawar5890@gmail.com>
@jeevan6996
jeevan6996 force-pushed the fix/psd-empty-layers branch from c829a3b to f586041 Compare October 12, 2026 19:57
Comment thread src/psd.imageio/psdinput.cpp Outdated
Comment thread testsuite/psd-empty-layers/run.py Outdated
Comment thread CHANGES.md Outdated
@lgritz

lgritz commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

I think the most important thing that needs to happen here before finalizing the implementation is to decide what is the right behavior for empty layers: to gracefully allow PSD subimages with 0x0 images (presumably holding metadata only?), or whether to just "skip them" and not report their being in the file.

I honestly don't have a preference myself, and am hoping that people who deal with psd files regularly will give us some guidance.

Since OIIO doesn't currently output PSD files, we don't have to worry about situations like oiiotool in.psd -o out.psd and whether that obligates us to handle empty layers in order to faithfully preserve what's in the file. So we have more freedom than we would with other formats that we read and write. Though perhaps we have stronger feelings about what iinfo -v -a file.psd ought to say about a psd file with empty layers?

If we do read them fully, we should implement the supports("noimage") query in the PSD reader.

@lgritz

lgritz commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

I strongly encourage everybody to write your own PR messages using your actual brains. It's the best proof that you understand what you are submitting. At the very least, even if the robot writes the first draft, please edit it yourself to make it seem like a human thought about it and understood it. That means not including information that is obvious, irrelevant, or that is too specific your personal computer.

Since we won't merge a PR without fully passing CI (all tests, all platforms), most of the this information does not need to be stated in the PR description:

Local validation on macOS ARM64 with AppleClang 21:

* The unpatched source reproduces the failure on both supplied PSD files.

* The patched source opens both files, preserving their 5 and 32 subimages.

* Composite pixel hashes match the previously working 3.1.13.0 release.

* `psd`, `psd-colormodes`, and `psd-empty-layers` pass.

* Restoring strict layer validation makes the new regression fail.

* The unpatched 3.1.18.1 reader rejects both generated hidden empty-layer fixtures; the patched reader accepts them.

* Local clang-format and whitespace checks pass.

Command: ctest --test-dir build-psd -R '^psd' --output-on-failure

Result: 100% tests passed, 0 tests failed out of 3

Fork CI passed all 28 jobs, including clang-format, on the current PR commit f5860414a: https://github.com/jeevan6996/OpenImageIO/actions/runs/38301267940

Windows/Linux and sanitizer validation have not been performed locally. The exact file mentioned in the additional hidden-layer comment was not available for testing.

All the important information in this entire part could have been stated as:

"I checked that the images from the issue failed before and read correctly with this patch, and also that the composite pixel hashes exactly match the previously working release for images without empty layers."

jeevan6996 and others added 2 commits October 16, 2026 08:36
@jeevan6996
jeevan6996 force-pushed the fix/psd-empty-layers branch from 1f4a4f6 to c13d2e0 Compare October 16, 2026 23:28
Keep resolution validation strict and enforce layer size limits while tolerating empty rectangles. Expose only the composite and populated layers, deriving the public count from the resulting image specs.

Bound empty channel payloads before seeking past RLE or ZIP data. Preserve independent layer-mask decoding and populated-layer ordering.

Assisted-by: Codex / model identifier unavailable
Signed-off-by: jeevan6996 <jeevanpawar5890@gmail.com>
Replace runtime generation with fixed PSD/PSB inputs and retain the generator for maintenance. Include RLE row-length tables so compressed empty channels exercise the real parsing path.

Check subimage counts, layer order and pixel hashes in normal and raw modes. Cover hidden and trailing empty layers, masks, ZIP payloads, size limits and oversized declared channel lengths.

Assisted-by: Codex / model identifier unavailable
Signed-off-by: jeevan6996 <jeevanpawar5890@gmail.com>
@lgritz

lgritz commented Oct 17, 2026

Copy link
Copy Markdown
Collaborator

@jessey-git Is this ok and helpful to you as it stands?

@jessey-git

Copy link
Copy Markdown
Contributor

Yes, as it stands it fixes the issue on the 3 reported files for us.

@lgritz lgritz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@lgritz

lgritz commented Oct 17, 2026

Copy link
Copy Markdown
Collaborator

@jeevan6996 Before I merge, would you mind please editing the PR description to reflect the final state of the patch and what it does? It doesn't need to describe its history, like "the published patch [does thing it no longer does], then after revision [thing it now does]," and it doesn't need language that appears to be describing your personal machine or the state of the patch while it was still in development, like "the local copy..." or "tests pass locally."

And also please add our required AI tool attribution. It's obvious that an LLM was used, but there was no notice.

@jeevan6996 jeevan6996 changed the title fix(psd): accept empty layer rectangles fix(psd): skip empty layers when reading PSD files Oct 18, 2026
@jeevan6996

jeevan6996 commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor Author
  • CI status: run 39145910314 finished with 23 passed, one failed and four cancelled jobs.
  • Failure: GCC16/C++26 fails in nanobind’s nb_func.cpp because nb_func_check_redefined is unused and -Werror is enabled.
  • Evidence: the job tracks nanobind master; commit a1c8924 added that helper after OIIO’s earlier successful upstream run.
  • Conclusion: evidence points to a dependency regression rather than the PSD change, but no controlled unchanged-base rebuild has been performed.

Failed run (https://github.com/jeevan6996/OpenImageIO/actions/runs/39145910314).

Nanobind change (wjakob/nanobind@a1c8924).

@lgritz

lgritz commented Oct 18, 2026

Copy link
Copy Markdown
Collaborator
  • CI status: run 39145910314 finished with 23 passed, one failed and four cancelled jobs.

    • Failure: GCC16/C++26 fails in nanobind’s nb_func.cpp because nb_func_check_redefined is unused and -Werror is enabled.

    • Evidence: the job tracks nanobind master; commit a1c8924 added that helper after OIIO’s earlier successful upstream run.

    • Conclusion: evidence points to a dependency regression rather than the PSD change, but no controlled unchanged-base rebuild has been performed.

Failed run (https://github.com/jeevan6996/OpenImageIO/actions/runs/39145910314).

Nanobind change (wjakob/nanobind@a1c8924).

This is obviously written by a machine. Here's how I would have composed this comment:

"The 'bleeding edge' CI test is failing because of a recent change upstream in nanobind. It's unrelated to this PR."

@lgritz lgritz left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for this fix, and for going through a few iterations to get it just right.

@lgritz
lgritz merged commit 1694550 into AcademySoftwareFoundation:main Oct 18, 2026
65 of 67 checks passed
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

Successfully merging this pull request may close these issues.

bug: Some valid PSD files fail to load on recent versions - [Layer Record] invalid image width 0

5 participants