Skip to content

Reject mixed BitsPerSample per band in TIFF readers#1519

Open
brendancol wants to merge 1 commit intoxarray-contrib:mainfrom
brendancol:fix-1505-mixed-bps
Open

Reject mixed BitsPerSample per band in TIFF readers#1519
brendancol wants to merge 1 commit intoxarray-contrib:mainfrom
brendancol:fix-1505-mixed-bps

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

Closes #1505

A TIFF whose BitsPerSample tag holds a different value per band (e.g. (16, 16, 16, 8) for RGB plus an 8-bit alpha) was silently decoded with the first band's width applied to every band, so the mismatched bands came back as garbage.

The fix adds a _dtypes.resolve_bits_per_sample(bps) helper and threads every reader site through it: stripped CPU, tiled CPU, GPU, VRT, the geo-info probe, and the palette colormap path. The helper accepts a scalar or a tuple/list whose entries all agree, and raises ValueError with the mixed values and a gdal_translate hint when they don't.

Decoding each band separately and promoting to a common dtype was the alternative; it's more code for a rare case, and silent promotion raises follow-up questions (whose nodata wins, what does the user actually want). An explicit error lets the user convert with GDAL or rasterio.

Test plan

  • pytest xrspatial/geotiff/tests/test_mixed_bps.py -- 9 new tests: the helper plus an end-to-end RGB+8-bit-alpha file built from raw IFD bytes
  • pytest xrspatial/geotiff/tests/ -- 699 passed; 3 pre-existing matplotlib palette failures are unrelated

A TIFF whose BitsPerSample tag holds a different value per band (e.g.
(16, 16, 16, 8) for RGB plus an 8-bit alpha) was silently decoded with
the first band's width applied to every band, so the mismatched bands
came back as garbage.

The fix adds a _dtypes.resolve_bits_per_sample(bps) helper and threads
every reader site through it: stripped CPU, tiled CPU, GPU, VRT, the
geo-info probe, and the palette colormap path. The helper accepts a
scalar or a tuple/list whose entries all agree, and raises ValueError
with the mixed values and a gdal_translate hint when they don't.

Closes xarray-contrib#1505
@github-actions github-actions Bot added the performance PR touches performance-sensitive code label May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance PR touches performance-sensitive code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mixed BitsPerSample per band silently uses bps[0]

1 participant