fix(psd): fix indexed transparency#5177
Conversation
avcodec_close (AVCodecContext *avctx) removing in ffmpeg 7.2 and was deprecated for couple years Signed-off-by: Vlad (Kuzmin) Erium <libalias@gmail.com>
0eb7507 to
937633d
Compare
|
There is some widespread outage of Ubuntu package related machines and it's causing a lot of our CI to fail, unrelated to the contents of any of our PRs or CI runs. It's across the board. We may no be able to trust failing CI results until tomorrow. Don't expend any effort fixing, give it a while to clear up. |
|
@ssh4net This is still failing one test -- psd-colormodes. Only on the "Linux ARM latest releases gcc14" variant, and curiously not on the nearly identical setup using clang. The failure is a hash. Maybe there is a LSB difference somewhere, only on ARM and only with gcc? Can you investigate? If there's no obvious culprit, maybe the test should be changed to not output the hash and do a pixel comparison with threshold? Or maybe if you inspect the results visibly and it looks fine, just commit a second reference output to the ref directory that will match for the other hash being reported? |
|
@lgritz Yes, will check. |
Signed-off-by: Vlad (Kuzmin) Erium <libalias@gmail.com>
937633d to
74c8ac1
Compare
|
Root cause: for transparent indexed pixels we synthesize RGBA = 0,0,0,0, then PSD composite alpha cleanup calls removeBackground(). With white background and alpha 0, it computes a negative RGB value and casts that float back to uint8_t. That conversion is implementation-dependent, so x86 and ARM can hash different pixels. |
Fixes indexed-color PSD transparency handling when the transparent
palette index is `0`.
Before this change, the PSD reader used `m_transparency_index` both as the
palette index value and as the signal that a transparency-index resource was
present. That made index `0` ambiguous: it is a valid transparent palette index,
but it evaluated as false when deciding whether to add an alpha channel.
As a result, an indexed PSD with transparency index `0` could expose a
3-channel output spec, then later `indexed_to_rgb()` would treat
`m_transparency_index >= 0` as meaning transparency exists and write 4
bytes per pixel. That could write a 4-channel row into a caller buffer sized for
3 channels.
The fix separates those two pieces of state:
- `m_has_transparency_index` records whether the transparency resource exists.
- `m_transparency_index` stores only the numeric palette index.
- Index `0` now correctly adds an alpha channel.
- Transparency indexes outside the valid palette range `0..255` are rejected.
- `indexed_to_rgb()` now checks source and destination spans before writing.
### Tests
Added regression coverage to `testsuite/psd-colormodes`.
The test now generates indexed PSD variants from the existing
`pattern2-8-indexed.psd` fixture with transparency indexes:
- `0`: valid, should report/read as 4-channel PSD.
- `255`: valid, should report/read as 4-channel PSD.
- `256`: invalid, should be rejected.
Validated locally with:
```bash
python3 -m py_compile testsuite/psd-colormodes/run.py \
testsuite/psd-colormodes/src/make-indexed-transparency-psds.py
ninja -C build-psd oiiotool iconvert idiff
```
Also ran the generated PSD cases and a manual full psd-colormodes test;
final out.txt matched the updated reference
Assisted-by: Codex GPT5.5xHigh
---------
Signed-off-by: Vlad (Kuzmin) Erium <libalias@gmail.com>
Description
Fixes indexed-color PSD transparency handling when the transparent palette index
is
0.Before this change, the PSD reader used
m_transparency_indexboth as thepalette index value and as the signal that a transparency-index resource was
present. That made index
0ambiguous: it is a valid transparent palette index,but it evaluated as false when deciding whether to add an alpha channel.
As a result, an indexed PSD with transparency index
0could expose a3-channel output spec, then later
indexed_to_rgb()would treatm_transparency_index >= 0as meaning transparency exists and write 4 bytes perpixel. That could write a 4-channel row into a caller buffer sized for
3 channels.
The fix separates those two pieces of state:
m_has_transparency_indexrecords whether the transparency resource exists.m_transparency_indexstores only the numeric palette index.0now correctly adds an alpha channel.0..255are rejected.indexed_to_rgb()now checks source and destination spans before writing.Tests
Added regression coverage to
testsuite/psd-colormodes.The test now generates indexed PSD variants from the existing
pattern2-8-indexed.psdfixture with transparency indexes:0: valid, should report/read as 4-channel PSD.255: valid, should report/read as 4-channel PSD.256: invalid, should be rejected.Validated locally with:
python3 -m py_compile testsuite/psd-colormodes/run.py \ testsuite/psd-colormodes/src/make-indexed-transparency-psds.py ninja -C build-psd oiiotool iconvert idiffAlso ran the generated PSD cases and a manual full psd-colormodes test; final
out.txt matched the updated reference
Checklist:
and if I used AI coding assistants, I have an
Assisted-by: Codex GPT5.5xHighline in the pull request description above.
behavior.
PR, by pushing the changes to my fork and seeing that the automated CI
passed there. (Exceptions: If most tests pass and you can't figure out why
the remaining ones fail, it's ok to submit the PR and ask for help. Or if
any failures seem entirely unrelated to your change; sometimes things break
on the GitHub runners.)
fixed any problems reported by the clang-format CI test.
corresponding Python bindings. If altering ImageBufAlgo functions, I also
exposed the new functionality as oiiotool options.