Description
When a .tif.ovr sidecar is loaded, local eager reads correctly swap the pixel buffer and TIFF header over to the sidecar (xrspatial/geotiff/_reader.py ~line 223). The georef extraction call right below it still passes the base file's data and header.byte_order (line 234). _read_geo_info in xrspatial/geotiff/__init__.py (~line 291) has the same bug.
This is harmless under the usual GDAL convention, where the sidecar has no geokeys and georef lives on the base file. It is not safe in general: if the sidecar IFD does carry its own GeoKeyDirectory or model tags, those tags get parsed against the wrong byte buffer and the returned geo_info is silently wrong.
Expected behavior
If the selected IFD lives in the sidecar and that IFD declares its own georef payload, parse the georef against the sidecar's bytes and byte order. If the sidecar IFD has no georef payload, fall back to the existing behavior and inherit from the base file's level-0 IFD.
Actual behavior
Georef tags on a sidecar IFD are parsed as if they lived in the base file. ModelPixelScale, ModelTiepoint, and ModelTransformation values come out of the wrong offsets, and GeoKeyDirectory entries that point into GeoDoubleParamsTag or GeoAsciiParamsTag dereference into the base file instead of the sidecar.
Fix shape
- Detect whether a sidecar IFD carries its own georef payload (any of tags 33550, 33922, 34264, 34735).
- When it does, run
extract_geo_info_with_overview_inheritance against the sidecar's data and header.byte_order for that IFD.
- When it does not, keep today's behavior.
- Apply the same rule at both call sites so the two paths agree.
- Add a regression test using a synthetic base + sidecar pair where the sidecar declares its own ModelPixelScale, ModelTiepoint, and GeoKeyDirectory differing from the base.
Files
xrspatial/geotiff/_reader.py:234 (eager read path)
xrspatial/geotiff/__init__.py:291 (metadata-only path used by the dask backend)
Description
When a
.tif.ovrsidecar is loaded, local eager reads correctly swap the pixel buffer and TIFF header over to the sidecar (xrspatial/geotiff/_reader.py~line 223). The georef extraction call right below it still passes the base file'sdataandheader.byte_order(line 234)._read_geo_infoinxrspatial/geotiff/__init__.py(~line 291) has the same bug.This is harmless under the usual GDAL convention, where the sidecar has no geokeys and georef lives on the base file. It is not safe in general: if the sidecar IFD does carry its own GeoKeyDirectory or model tags, those tags get parsed against the wrong byte buffer and the returned
geo_infois silently wrong.Expected behavior
If the selected IFD lives in the sidecar and that IFD declares its own georef payload, parse the georef against the sidecar's bytes and byte order. If the sidecar IFD has no georef payload, fall back to the existing behavior and inherit from the base file's level-0 IFD.
Actual behavior
Georef tags on a sidecar IFD are parsed as if they lived in the base file. ModelPixelScale, ModelTiepoint, and ModelTransformation values come out of the wrong offsets, and GeoKeyDirectory entries that point into GeoDoubleParamsTag or GeoAsciiParamsTag dereference into the base file instead of the sidecar.
Fix shape
extract_geo_info_with_overview_inheritanceagainst the sidecar'sdataandheader.byte_orderfor that IFD.Files
xrspatial/geotiff/_reader.py:234(eager read path)xrspatial/geotiff/__init__.py:291(metadata-only path used by the dask backend)