Skip to content

Commit

Permalink
VRTSourcedRasterBand::GetMinimum/GetMaximum(): limit to 1 second max …
Browse files Browse the repository at this point in the history
…when iterating over sources
  • Loading branch information
rouault committed Oct 26, 2023
1 parent 5d3638a commit 2ba9ef9
Showing 1 changed file with 83 additions and 1 deletion.
84 changes: 83 additions & 1 deletion frmts/vrt/vrtsourcedrasterband.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,37 @@ CPLErr VRTSourcedRasterBand::IReadBlock(int nBlockXOff, int nBlockYOff,
nPixelSize * nBlockXSize, &sExtraArg);
}

/************************************************************************/
/* CPLGettimeofday() */
/************************************************************************/

#if defined(_WIN32) && !defined(__CYGWIN__)
#include <sys/timeb.h>

namespace
{
struct CPLTimeVal
{
time_t tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};
} // namespace

static int CPLGettimeofday(struct CPLTimeVal *tp, void * /* timezonep*/)
{
struct _timeb theTime;

_ftime(&theTime);
tp->tv_sec = static_cast<time_t>(theTime.time);
tp->tv_usec = theTime.millitm * 1000;
return 0;
}
#else
#include <sys/time.h> /* for gettimeofday() */
#define CPLTimeVal timeval
#define CPLGettimeofday(t, u) gettimeofday(t, u)
#endif

/************************************************************************/
/* CanUseSourcesMinMaxImplementations() */
/************************************************************************/
Expand All @@ -552,6 +583,10 @@ bool VRTSourcedRasterBand::CanUseSourcesMinMaxImplementations()
// on the filesystem, whose open time and GetMinimum()/GetMaximum()
// implementations we hope to be fast enough.
// In case of doubt return FALSE.
struct CPLTimeVal tvStart;
memset(&tvStart, 0, sizeof(CPLTimeVal));
if (nSources > 1)
CPLGettimeofday(&tvStart, nullptr);
for (int iSource = 0; iSource < nSources; iSource++)
{
if (!(papoSources[iSource]->IsSimpleSource()))
Expand All @@ -572,7 +607,7 @@ bool VRTSourcedRasterBand::CanUseSourcesMinMaxImplementations()
{
if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
(ch >= '0' && ch <= '9') || ch == ':' || ch == '/' ||
ch == '\\' || ch == ' ' || ch == '.'))
ch == '\\' || ch == ' ' || ch == '.' || ch == '_'))
break;
}
if (ch != '\0')
Expand All @@ -581,6 +616,15 @@ bool VRTSourcedRasterBand::CanUseSourcesMinMaxImplementations()
VSIStatBuf sStat;
if (VSIStat(pszFilename, &sStat) != 0)
return false;
if (nSources > 1)
{
struct CPLTimeVal tvCur;
CPLGettimeofday(&tvCur, nullptr);
if (tvCur.tv_sec - tvStart.tv_sec +
(tvCur.tv_usec - tvStart.tv_usec) * 1e-6 >
1)
return false;
}
}
}
return true;
Expand Down Expand Up @@ -623,6 +667,10 @@ double VRTSourcedRasterBand::GetMinimum(int *pbSuccess)
return 0;
}

struct CPLTimeVal tvStart;
memset(&tvStart, 0, sizeof(CPLTimeVal));
if (nSources > 1)
CPLGettimeofday(&tvStart, nullptr);
double dfMin = 0;
for (int iSource = 0; iSource < nSources; iSource++)
{
Expand All @@ -636,7 +684,22 @@ double VRTSourcedRasterBand::GetMinimum(int *pbSuccess)
}

if (iSource == 0 || dfSourceMin < dfMin)
{
dfMin = dfSourceMin;
if (dfMin == 0 && eDataType == GDT_Byte)
break;
}
if (nSources > 1)
{
struct CPLTimeVal tvCur;
CPLGettimeofday(&tvCur, nullptr);
if (tvCur.tv_sec - tvStart.tv_sec +
(tvCur.tv_usec - tvStart.tv_usec) * 1e-6 >
1)
{
return GDALRasterBand::GetMinimum(pbSuccess);
}
}
}

if (pbSuccess != nullptr)
Expand Down Expand Up @@ -682,6 +745,10 @@ double VRTSourcedRasterBand::GetMaximum(int *pbSuccess)
return 0;
}

struct CPLTimeVal tvStart;
memset(&tvStart, 0, sizeof(CPLTimeVal));
if (nSources > 1)
CPLGettimeofday(&tvStart, nullptr);
double dfMax = 0;
for (int iSource = 0; iSource < nSources; iSource++)
{
Expand All @@ -695,7 +762,22 @@ double VRTSourcedRasterBand::GetMaximum(int *pbSuccess)
}

if (iSource == 0 || dfSourceMax > dfMax)
{
dfMax = dfSourceMax;
if (dfMax == 255.0 && eDataType == GDT_Byte)
break;
}
if (nSources > 1)
{
struct CPLTimeVal tvCur;
CPLGettimeofday(&tvCur, nullptr);
if (tvCur.tv_sec - tvStart.tv_sec +
(tvCur.tv_usec - tvStart.tv_usec) * 1e-6 >
1)
{
return GDALRasterBand::GetMaximum(pbSuccess);
}
}
}

if (pbSuccess != nullptr)
Expand Down

0 comments on commit 2ba9ef9

Please sign in to comment.