Problem
open_geotiff(path, overview_level=N) selects the Nth IFD without checking the NewSubfileType (tag 254) of each IFD. TIFF allows several non-overview IFDs in the chain:
NewSubfileType=0 — full-resolution image
NewSubfileType=1 — reduced-resolution overview
NewSubfileType=2 — page of a multi-page document
NewSubfileType=4 — transparency mask
- combinations (e.g., 5 = overview of a mask)
GDAL writes mask IFDs interleaved with overview IFDs in some COG variants. Indexing by raw IFD position returns a binary mask layer where the user expected an overview.
Where
xrspatial/geotiff/_reader.py and xrspatial/geotiff/__init__.py — overview selection logic.
Fix sketch
Before applying overview_level, filter the IFD list to those with NewSubfileType & 1 == 1 (overview bit set) AND NewSubfileType & 4 == 0 (not a mask). Then index into the filtered list.
For COGs the overview IFDs are also typically ordered by descending pixel size, so an alternative API is to select by requested resolution rather than ordinal index.
Severity
Silent wrong-layer return when masks are present. Standard COGs without masks are unaffected.
Problem
open_geotiff(path, overview_level=N)selects the Nth IFD without checking theNewSubfileType(tag 254) of each IFD. TIFF allows several non-overview IFDs in the chain:NewSubfileType=0— full-resolution imageNewSubfileType=1— reduced-resolution overviewNewSubfileType=2— page of a multi-page documentNewSubfileType=4— transparency maskGDAL writes mask IFDs interleaved with overview IFDs in some COG variants. Indexing by raw IFD position returns a binary mask layer where the user expected an overview.
Where
xrspatial/geotiff/_reader.pyandxrspatial/geotiff/__init__.py— overview selection logic.Fix sketch
Before applying
overview_level, filter the IFD list to those withNewSubfileType & 1 == 1(overview bit set) ANDNewSubfileType & 4 == 0(not a mask). Then index into the filtered list.For COGs the overview IFDs are also typically ordered by descending pixel size, so an alternative API is to select by requested resolution rather than ordinal index.
Severity
Silent wrong-layer return when masks are present. Standard COGs without masks are unaffected.