Skip to content

Commit 8047c56

Browse files
committed
VRT: fix slowness when downsampling from VRTs with explicit resampling=nearest
Fixes qgis/QGIS#63293
1 parent c943169 commit 8047c56

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

autotest/cpp/test_gdal.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "tilematrixset.hpp"
2121
#include "gdalcachedpixelaccessor.h"
2222
#include "memdataset.h"
23+
#include "vrtdataset.h"
2324

2425
#include <algorithm>
2526
#include <array>
@@ -711,6 +712,34 @@ TEST_F(test_gdal, GDALBuildVRT)
711712
GDALReleaseDataset(hOutDS);
712713
}
713714

715+
TEST_F(test_gdal, VRT_CanIRasterIOBeForwardedToEachSource)
716+
{
717+
if (!GDALGetDriverByName("VRT"))
718+
{
719+
GTEST_SKIP() << "VRT driver missing";
720+
}
721+
const char *pszVRT =
722+
"<VRTDataset rasterXSize=\"20\" rasterYSize=\"20\">"
723+
" <VRTRasterBand dataType=\"Byte\" band=\"1\">"
724+
" <NoDataValue>1</NoDataValue>"
725+
" <ColorInterp>Gray</ColorInterp>"
726+
" <ComplexSource resampline=\"nearest\">"
727+
" <SourceFilename>" GCORE_DATA_DIR "byte.tif</SourceFilename>"
728+
" <SourceBand>1</SourceBand>"
729+
" <NODATA>1</NODATA>"
730+
" </ComplexSource>"
731+
" </VRTRasterBand>"
732+
"</VRTDataset>";
733+
auto poDS = std::unique_ptr<GDALDataset>(GDALDataset::Open(pszVRT));
734+
ASSERT_TRUE(poDS != nullptr);
735+
auto poBand = dynamic_cast<VRTSourcedRasterBand *>(poDS->GetRasterBand(1));
736+
ASSERT_TRUE(poBand != nullptr);
737+
GDALRasterIOExtraArg sExtraArg;
738+
INIT_RASTERIO_EXTRA_ARG(sExtraArg);
739+
EXPECT_TRUE(poBand->CanIRasterIOBeForwardedToEachSource(
740+
GF_Read, 0, 0, 20, 20, 1, 1, &sExtraArg));
741+
}
742+
714743
// Test that GDALSwapWords() with unaligned buffers
715744
TEST_F(test_gdal, GDALSwapWords_unaligned_buffers)
716745
{

frmts/vrt/vrtsourcedrasterband.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,10 @@ bool VRTSourcedRasterBand::CanIRasterIOBeForwardedToEachSource(
136136
{
137137
auto *const poComplexSource =
138138
static_cast<VRTComplexSource *>(poSource.get());
139-
if (!poComplexSource->GetResampling().empty())
139+
const auto &osSourceResampling =
140+
poComplexSource->GetResampling();
141+
if (!osSourceResampling.empty() &&
142+
osSourceResampling != "nearest")
140143
return true;
141144
}
142145
}
@@ -172,7 +175,10 @@ bool VRTSourcedRasterBand::CanIRasterIOBeForwardedToEachSource(
172175
{
173176
auto *const poComplexSource =
174177
static_cast<VRTComplexSource *>(poSimpleSource);
175-
if (!poComplexSource->GetResampling().empty())
178+
const auto &osSourceResampling =
179+
poComplexSource->GetResampling();
180+
if (!osSourceResampling.empty() &&
181+
osSourceResampling != "nearest")
176182
{
177183
const int lMaskFlags =
178184
const_cast<VRTSourcedRasterBand *>(this)

0 commit comments

Comments
 (0)