InsightSoftwareConsortium / InsightSoftwareConsortium/ITK
TIFFImageIO writes EXTRASAMPLE_ASSOCALPHA for non-alpha extra samples (mislabels VECTOR channels)
- Dominant language
- C++
- Stars
- 1.7k
- Forks
- 748
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 64
Description
## Summary
`TIFFImageIO::InternalWrite()` tags the **first extra sample** of a multi-component write as `EXTRASAMPLE_ASSOCALPHA` (premultiplied alpha) unconditionally, regardless of whether the source image is actually gray+alpha / RGBA. For ITK `VECTOR`-typed data (the common case for 2- and 4-component scientific images — displacement fields, complex data, multi-channel measurements), this mislabels an independent data channel as premultiplied alpha. Standard TIFF readers may then premultiply or otherwise reinterpret that channel, changing display and breaking round-trips through non-ITK tools.
## Where
`Modules/IO/TIFF/src/itkTIFFImageIO.cxx`, `InternalWrite()`:
```cpp
sample_info[0] = EXTRASAMPLE_ASSOCALPHA; // first extra sample
for (uint16_t cc = 1; cc < extra_samples; ++cc)
sample_info[cc] = EXTRASAMPLE_UNSPECIFIED;
```
- **4+ components:** pre-existing behavior (present before #6636).
- **2 components:** newly reaches this path via #6636 (B83), which correctly stopped writing 2-component images as `PHOTOMETRIC_RGB` and now writes `PHOTOMETRIC_MINISBLACK` + 1 extra sample — but that extra sample inherits the `ASSOCALPHA` tag.
## Why it's a design decision (not a drive-by fix)
The IO layer generally cannot distinguish "gray+alpha / RGBA with genuine premultiplied alpha" from "N-channel vector" from `NumberOfComponents` alone. Options:
1. Default all non-color extra samples to `EXTRASAMPLE_UNSPECIFIED` (safe: no reader premultiplies; loses the ability to signal genuine alpha).
2. Use `GetPixelType()` (`RGBA` → `ASSOCALPHA`, `VECTOR`/others → `UNSPECIFIED`) to pick per-image.
3. Keep `ASSOCALPHA` (status quo) and document that ITK TIFF writes assume alpha semantics for the first extra sample.
Option 2 is the most correct but changes long-standing 4-component output, so it needs maintainer sign-off and a round-trip-compatibility check. This is out of scope for the #6636 bug-fix batch.
## Related
- PR #6636 (introduces the 2-component path; greptile flagged this as P2 there)
- Raised by @greptileai review on #6636
Contributor guide
Research direction
Read Modules/IO/TIFF/src/itkTIFFImageIO.cxx, especially InternalWrite() and the EXTRASAMPLES block around lines 694–705. Check how GetPixelType() and the 2- and 4-component paths could distinguish RGBA from VECTOR data, then verify the chosen behavior with round-trip compatibility checks. Done means non-alpha vector channels are not labeled as premultiplied alpha while genuine alpha behavior is preserved or intentionally documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- computer-vision
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100