Skip to content

Commit 6bf9270

Browse files
committed
Fix COG cubic overview poisoned by nodata sentinel (#1623)
`to_geotiff(cog=True, overview_resampling='cubic', nodata=<finite>)` on a float raster with NaN regions produced overview pixels with severe ringing near nodata borders. Same class of bug as #1613, but for the `cubic` branch: the writer rewrites NaN to the finite sentinel before reduction, then `_block_reduce_2d(method='cubic')` handed the sentinel-poisoned array straight to `scipy.ndimage.zoom(order=3)`. The cubic spline blended the sentinel into neighbouring cells (values like 1133.44 and -10290.08 appeared where the source data was a constant 100). Fix: when `nodata` is supplied on a float dtype and the sentinel is present in the input, mask sentinel to NaN, run cubic with `prefilter=False` so a single NaN does not poison the entire row/column (the default B-spline prefilter is global), then rewrite any NaN in the result back to the sentinel. `prefilter=False` only fires when a sentinel is actually found in the input, so the default cubic semantics still apply to inputs without nodata. GPU side: `_block_reduce_2d_gpu` previously raised `ValueError` on `method='cubic'`. Added a CPU fallback the same way the helper already handles `mode`, so the GPU writer path produces byte-equivalent overviews to the CPU writer when cubic + nodata are combined. `GPU_OVERVIEW_METHODS` now includes `'cubic'`. 12 regression tests in `test_cog_cubic_overview_nodata_1623.py`: helper no-ringing, poisoning repro, no-nodata path unchanged, end-to-end COG round-trip, GPU fallback, CPU/GPU byte-match, +/-inf nodata masking, NaN-sentinel no-op, and the `GPU_OVERVIEW_METHODS` contract. All 1256 existing geotiff tests still pass. Found by deep-sweep-accuracy 2026-05-11. State CSV updated with the pass-16 record.
1 parent 9a5f55e commit 6bf9270

4 files changed

Lines changed: 343 additions & 8 deletions

File tree

0 commit comments

Comments
 (0)