Skip to content

Tighten geotiff reader: partial-tile validation, ModelTransformation rotation guard#1491

Merged
brendancol merged 1 commit intomainfrom
issue-1486
May 5, 2026
Merged

Tighten geotiff reader: partial-tile validation, ModelTransformation rotation guard#1491
brendancol merged 1 commit intomainfrom
issue-1486

Conversation

@brendancol
Copy link
Copy Markdown
Contributor

Closes #1486.

Summary

Two accuracy fixes in xrspatial/geotiff/.

_decode_strip_or_tile now validates the decompressed byte count against the expected size before reshape. A truncated deflate stream used to surface as cannot reshape array of size N into shape (h, w) with no hint of which tile or what was expected. New error names the tile geometry, expected size, actual size, and points at corruption.

_extract_transform now checks ModelTransformationTag (34264) for non-zero rotation (M[1], M[4]) and z-coupling (M[2], M[6]) and raises NotImplementedError. The old code used only the diagonal terms and silently produced a corrupted GeoTransform on rotated rasters.

The audit also flagged a possible MinIsWhite + windowed-read issue. On close reading the window is clamped to image bounds before allocating output, so padding never reaches the inversion. Skipped with a note in the issue.

Test plan

  • test_truncated_tile_raises_clear_error - corrupt deflate stream raises ValueError with the size mismatch
  • test_valid_edge_tile_still_works - 9x9 image with 4x4 tiles round-trips cleanly (edge tiles are partial)
  • test_axis_aligned_extracts_correctly - ModelTransformationTag without rotation extracts origin/pixel sizes
  • test_rotation_raises - non-zero M[1]/M[4] raises NotImplementedError
  • test_z_coupling_raises - non-zero M[2]/M[6] raises NotImplementedError
  • Full geotiff suite: 478 passed (was 473), 3 pre-existing matplotlib RecursionError failures unrelated to this PR

… rotation guard (#1486)

Two accuracy fixes in the geotiff read path:

1. Validate decompressed tile/strip byte count in `_decode_strip_or_tile`
   before the reshape. A truncated deflate stream or a misbehaving
   compressor previously triggered an opaque "cannot reshape array of
   size N" message; now it raises ValueError with the expected size,
   actual size, and tile geometry. Edge tiles in valid TIFFs continue
   to decompress to the full tile_height x tile_width and pass the
   check unchanged.

2. Detect rotation, skew, and z-coupling in ModelTransformationTag
   (34264) and raise NotImplementedError. The previous code silently
   used only the diagonal terms, returning a corrupted GeoTransform
   for rotated rasters with no warning to the caller. Axis-aligned
   matrices keep working.

Notes the audit also flagged a possible MinIsWhite + windowed-read
issue, but the windowing path clamps to image bounds before allocating
the output, so no padding ever reaches the inversion. Skipped.

Adds 5 tests covering corrupt-tile detection, valid-edge-tile pass-through,
axis-aligned ModelTransformation extraction, and the two error paths.
@github-actions github-actions Bot added the performance PR touches performance-sensitive code label May 5, 2026
@brendancol brendancol merged commit a70a773 into main May 5, 2026
11 checks passed
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.

Tighten geotiff accuracy: partial-tile validation, ModelTransformationTag rotation

1 participant