Skip to content

Commit

Permalink
Merge pull request #282 from mpadillaruiz/validate/sparse-edge-tile
Browse files Browse the repository at this point in the history
Fix for issue #281 COG validation fails for sparse edge tiles
  • Loading branch information
vincentsarago committed Feb 9, 2024
2 parents 8d7969c + 6fa53eb commit 220c539
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 12 deletions.
77 changes: 65 additions & 12 deletions rio_cogeo/cogeo.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,20 +564,49 @@ def cog_validate( # noqa: C901
)
)

block_offset = src.get_tag_item("BLOCK_OFFSET_0_0", "TIFF", bidx=1)

data_offset = int(block_offset) if block_offset else 0
data_offsets = [data_offset]
details["data_offsets"] = {}
details["data_offsets"]["main"] = data_offset
# Get blocks size
block_size = src.block_shapes[0]

# Extract number of blocks per row and column
yblocks = (src.height + block_size[1] - 1) // block_size[1]
xblocks = (src.width + block_size[0] - 1) // block_size[0]

# Find the first block with a valid block_offset
for y in range(yblocks):
for x in range(xblocks):
data_offset = get_data_offset(src, x, y)
if data_offset > 0:
data_offsets = [data_offset]
details["data_offsets"] = {}
details["data_offsets"]["main"] = data_offset
break
else:
continue
break

for ix, _dec in enumerate(overviews):
block_offset = src.get_tag_item(
"BLOCK_OFFSET_0_0", "TIFF", bidx=1, ovr=ix
)
data_offset = int(block_offset) if block_offset else 0
data_offsets.append(data_offset)
details["data_offsets"]["overview_{}".format(ix)] = data_offset

# Get the width and height of the overview
overview_width = src.width // (_dec)
overview_height = src.height // (_dec)

# Extract number of blocks per row and column
yblocks = (overview_height + block_size[1] - 1) // block_size[1]
xblocks = (overview_width + block_size[0] - 1) // block_size[0]

for y in range(yblocks):
for x in range(xblocks):
data_offset = get_data_offset(src, x, y, ix)
if data_offset > 0:
data_offset = int(data_offset) if data_offset else 0
data_offsets.append(data_offset)
details["data_offsets"][
"overview_{}".format(ix)
] = data_offset
break
else:
continue
break

if data_offsets[-1] != 0 and data_offsets[-1] < ifd_offsets[-1]:
if len(overviews) > 0:
Expand Down Expand Up @@ -631,6 +660,30 @@ def cog_validate( # noqa: C901
return is_valid, errors, warnings


def get_data_offset(src, x, y, ix=None):
"""
Retrieves the data offset from the source based on the given block coordinates.
Parameters:
src : object
The source from which to retrieve the data offset.
x : int
The x-coordinate of the block.
y : int
The y-coordinate of the block.
ix : int, optional
The index of the overview. Default is None.
Returns:
int
The data offset retrieved from the source. Returns 0 if the data offset is None.
"""
data_offset = src.get_tag_item(
"BLOCK_OFFSET_%d_%d" % (x, y), "TIFF", bidx=1, ovr=ix
)
return int(data_offset) if data_offset is not None else 0


def cog_info(
src_path: Union[str, pathlib.PurePath],
strict: bool = False,
Expand Down
Binary file added tests/fixtures/validate/sparse.tif
Binary file not shown.
4 changes: 4 additions & 0 deletions tests/test_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
raster_jpeg = os.path.join(fixture_dir, "validate", "nontiff.jpg")
raster_big = os.path.join(fixture_dir, "image_2000px.tif")
raster_zero_offset = os.path.join(fixture_dir, "validate", "cog_no_offest.tif")
raster_sparse = os.path.join(fixture_dir, "validate", "sparse.tif")

# COG created with rio-cogeo but using gdal 3.1
raster_rioCOGgdal31 = os.path.join(fixture_dir, "validate", "image_rioCOG_gdal3.1.tif")
Expand Down Expand Up @@ -71,6 +72,9 @@ def test_cog_validate_valid(monkeypatch):
with pytest.warns(NotGeoreferencedWarning):
assert cog_validate(raster_zero_offset, config=config)

# Sparse COG with some overviews that contain zeros
assert cog_validate(raster_sparse, config=config)[0]


def test_cog_validate_return():
"""Checkout returned values."""
Expand Down

0 comments on commit 220c539

Please sign in to comment.