From fb414cc613374c50a3d4b0cb9b727e058d97fbf6 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 25 Nov 2023 01:41:47 +0100 Subject: [PATCH] GDALOverviewDataset::IRasterIO(): use parent dataset when possible for more efficiency Fixes https://lists.osgeo.org/pipermail/gdal-dev/2023-November/057996.html --- autotest/utilities/test_gdal_translate_lib.py | 22 +++++++++++++++++++ gcore/gdaloverviewdataset.cpp | 10 ++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/autotest/utilities/test_gdal_translate_lib.py b/autotest/utilities/test_gdal_translate_lib.py index e605feae2ec2..c133d68c04d0 100755 --- a/autotest/utilities/test_gdal_translate_lib.py +++ b/autotest/utilities/test_gdal_translate_lib.py @@ -1095,6 +1095,28 @@ def test_gdal_translate_lib_overview_level(tmp_vsimem): assert out_ds.RasterYSize == 20 +############################################################################### +# Test overviewLevel option in a situation where overview bands have not a +# dedicated owner dataset. +# Test last part of GDALOverviewDataset::IRasterIO() implementation + + +@pytest.mark.require_driver("JP2KAK") +def test_gdal_translate_lib_overview_level_freestanding(tmp_vsimem): + + tmp_filename = tmp_vsimem / "tmp.jp2" + + src_ds = gdal.Translate( + tmp_filename, + "../gcore/data/byte.tif", + width=20 * 32, + creationOptions=["QUALITY=100"], + format="JP2KAK", + ) + out_ds = gdal.Translate("", src_ds, format="MEM", overviewLevel=0, width=20) + assert out_ds.GetRasterBand(1).Checksum() == 4667 + + ############################################################################### # Test copying a raster with no input band diff --git a/gcore/gdaloverviewdataset.cpp b/gcore/gdaloverviewdataset.cpp index 29c73eb6aa47..c01abe263d93 100644 --- a/gcore/gdaloverviewdataset.cpp +++ b/gcore/gdaloverviewdataset.cpp @@ -200,6 +200,14 @@ GDALOverviewDataset::GDALOverviewDataset(GDALDataset *poMainDSIn, nBands = poMainDS->GetRasterCount(); for (int i = 0; i < nBands; ++i) { + if (poOvrDS) + { + // Check that all overview bands belong to the same dataset + auto poOvrBand = + GetOverviewEx(poMainDS->GetRasterBand(i + 1), nOvrLevel); + if (poOvrBand->GetDataset() != poOvrDS) + poOvrDS = nullptr; + } SetBand(i + 1, new GDALOverviewBand(this, i + 1)); } @@ -328,7 +336,7 @@ CPLErr GDALOverviewDataset::IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, // In case the overview bands are really linked to a dataset, then issue // the request to that dataset. - if (nOvrLevel != -1 && poOvrDS != nullptr) + if (poOvrDS != nullptr) { return poOvrDS->RasterIO(eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nBandCount,