Skip to content

to_geotiff(cog=True) writes overview IFDs in wrong block order (rio-cogeo validator failure) #2308

@brendancol

Description

@brendancol

Surfaced by the new pytest-cog-validator job from #2302. With rio-cogeo installed, cog_validate(path, strict=False) on a basic to_geotiff(da, path, cog=True, overview_levels=[2, 4]) output returns:

- The offset of the first block of overview of index 0 should be after the one of the overview of index 1
- The offset of the first block of the main resolution image should be after the one of the overview of index 1

The COG spec requires overview tile blocks to be laid out smallest-overview-first, then progressively larger, with the main resolution image's blocks last. The current writer interleaves or reverses this order, so external readers that rely on monotonically increasing decimation reject the file.

Repro

import numpy as np, xarray as xr
from xrspatial.geotiff import to_geotiff
from rio_cogeo.cogeo import cog_validate

arr = np.random.RandomState(17).rand(256, 256).astype("float32")
da = xr.DataArray(
    arr,
    dims=("y", "x"),
    coords={"y": np.linspace(45, 44, 256), "x": np.linspace(-120, -119, 256)},
    attrs={"crs": 4326},
)
to_geotiff(da, "out.tif", compression="deflate", cog=True, tile_size=64, overview_levels=[2, 4])
print(cog_validate("out.tif", strict=False))
# (False, [...two block-order errors...], [...])

CI evidence: PR #2304 run run (3.12) -- https://github.com/xarray-contrib/xarray-spatial/actions/runs/26288974021/job/77383787093

Scope

  • The in-process round-trip and the local _assert_ifds_before_data layout check both pass. The bug is specifically in tile block ordering across overview IFDs, not the IFD chain.
  • Fix lives in the writer's overview-emit path (_writer.py / overview assembly).
  • Once fixed, drop the xfail on test_external_cog_validator (added in Make rio-cogeo COG validator a required CI gate (#2302) #2304) so the validator gate is fully green.

Acceptance

  • cog_validate(path, strict=False) returns valid=True, errors=[] on the same input shape used in test_external_cog_validator.
  • xfail removed from test_external_cog_validator; the COG-validator CI job is green.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions