From 94228b617b2fe44dc957a245f2b5577aaa72683f Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 16 Dec 2023 12:38:51 +0100 Subject: [PATCH] VRTComplexSource: fix excessive RAM usage with many sources (fixes #8967, 3.8.0 regression) m_abyWrkBuffer and m_abyWrkBufferMask were mistakenly put at the VRTComplexSource level, missing that there can be a big number of sources whose lifetime is the same as the VRT dataset, and thus it is inappropriate to have long-lived working buffers at that level. We can actually use one single instance of them for all sources, so move that at the dataset level. --- .../postgisraster/postgisrasterrasterband.cpp | 4 +- frmts/vrt/vrtdataset.h | 72 +++++++++++-------- frmts/vrt/vrtderivedrasterband.cpp | 3 +- frmts/vrt/vrtfilters.cpp | 9 ++- frmts/vrt/vrtmultidim.cpp | 14 ++-- frmts/vrt/vrtsourcedrasterband.cpp | 4 +- frmts/vrt/vrtsources.cpp | 65 +++++++++-------- 7 files changed, 101 insertions(+), 70 deletions(-) diff --git a/frmts/postgisraster/postgisrasterrasterband.cpp b/frmts/postgisraster/postgisrasterrasterband.cpp index 91cde24e8485..52927ae9fed1 100644 --- a/frmts/postgisraster/postgisrasterrasterband.cpp +++ b/frmts/postgisraster/postgisrasterrasterband.cpp @@ -609,6 +609,7 @@ CPLErr PostGISRasterRasterBand::IRasterIO( sizeof(PostGISRasterTileDataset *), SortTilesByPKID); } + VRTSource::WorkingState oWorkingState; for (i = 0; i < nFeatureCount && eErr == CE_None; i++) { PostGISRasterTileDataset *poTile = papsMatchingTiles[i]; @@ -617,7 +618,8 @@ CPLErr PostGISRasterRasterBand::IRasterIO( poTile->GetRasterBand(nBand)); eErr = poTileBand->poSource->RasterIO( eDataType, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, - nBufYSize, eBufType, nPixelSpace, nLineSpace, nullptr); + nBufYSize, eBufType, nPixelSpace, nLineSpace, nullptr, + oWorkingState); } // Free the object that holds pointers to matching tiles diff --git a/frmts/vrt/vrtdataset.h b/frmts/vrt/vrtdataset.h index 5da6ea70933c..4fecac8c107d 100644 --- a/frmts/vrt/vrtdataset.h +++ b/frmts/vrt/vrtdataset.h @@ -109,13 +109,39 @@ class VRTOverviewInfo class CPL_DLL VRTSource { public: + struct CPL_DLL WorkingState + { + // GByte whose initialization constructor does nothing +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Weffc++" +#endif + struct NoInitByte + { + GByte value; + // cppcheck-suppress uninitMemberVar + NoInitByte() + { + // do nothing + /* coverity[uninit_member] */ + } + }; +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + + std::vector m_abyWrkBuffer{}; + std::vector m_abyWrkBufferMask{}; + }; + virtual ~VRTSource(); virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, - GDALRasterIOExtraArg *psExtraArg) = 0; + GDALRasterIOExtraArg *psExtraArg, + WorkingState &oWorkingState) = 0; virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) = 0; virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) = 0; @@ -213,6 +239,8 @@ class CPL_DLL VRTDataset CPL_NON_FINAL : public GDALDataset std::map m_oMapSharedSources{}; std::shared_ptr m_poRootGroup{}; + VRTSource::WorkingState m_oWorkingState{}; + VRTRasterBand *InitBand(const char *pszSubclass, int nBand, bool bAllowPansharpened); static GDALDataset *OpenVRTProtocol(const char *pszSpec); @@ -1072,7 +1100,8 @@ class CPL_DLL VRTSimpleSource CPL_NON_FINAL : public VRTSource int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, - GDALRasterIOExtraArg *psExtraArgIn) override; + GDALRasterIOExtraArg *psExtraArgIn, + WorkingState &oWorkingState) override; virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override; virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override; @@ -1133,7 +1162,8 @@ class VRTAveragedSource final : public VRTSimpleSource int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, - GDALRasterIOExtraArg *psExtraArgIn) override; + GDALRasterIOExtraArg *psExtraArgIn, + WorkingState &oWorkingState) override; virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override; virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override; @@ -1172,28 +1202,6 @@ class CPL_DLL VRTComplexSource CPL_NON_FINAL : public VRTSimpleSource int m_nProcessingFlags = 0; - // GByte whose initialization constructor does nothing -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Weffc++" -#endif - struct NoInitByte - { - GByte value; - // cppcheck-suppress uninitMemberVar - NoInitByte() - { - // do nothing - /* coverity[uninit_member] */ - } - }; -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif - - std::vector m_abyWrkBuffer{}; - std::vector m_abyWrkBufferMask{}; - // adjusted value should be read with GetAdjustedNoDataValue() double m_dfNoDataValue = VRT_NODATA_UNSET; std::string @@ -1224,7 +1232,7 @@ class CPL_DLL VRTComplexSource CPL_NON_FINAL : public VRTSimpleSource int nReqXSize, int nReqYSize, void *pData, int nOutXSize, int nOutYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg, - GDALDataType eWrkDataType); + GDALDataType eWrkDataType, WorkingState &oWorkingState); template CPLErr RasterIOProcessNoData(GDALRasterBand *poSourceBand, @@ -1233,7 +1241,8 @@ class CPL_DLL VRTComplexSource CPL_NON_FINAL : public VRTSimpleSource void *pData, int nOutXSize, int nOutYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, - GDALRasterIOExtraArg *psExtraArg); + GDALRasterIOExtraArg *psExtraArg, + WorkingState &oWorkingState); public: VRTComplexSource() = default; @@ -1244,7 +1253,8 @@ class CPL_DLL VRTComplexSource CPL_NON_FINAL : public VRTSimpleSource int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, - GDALRasterIOExtraArg *psExtraArgIn) override; + GDALRasterIOExtraArg *psExtraArgIn, + WorkingState &oWorkingState) override; virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override; virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override; @@ -1313,7 +1323,8 @@ class VRTFilteredSource CPL_NON_FINAL : public VRTComplexSource int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, - GDALRasterIOExtraArg *psExtraArg) override; + GDALRasterIOExtraArg *psExtraArg, + WorkingState &oWorkingState) override; }; /************************************************************************/ @@ -1387,7 +1398,8 @@ class VRTFuncSource final : public VRTSource int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, - GDALRasterIOExtraArg *psExtraArg) override; + GDALRasterIOExtraArg *psExtraArg, + WorkingState &oWorkingState) override; virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override; virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override; diff --git a/frmts/vrt/vrtderivedrasterband.cpp b/frmts/vrt/vrtderivedrasterband.cpp index 8924219e8d54..9a982cb2f490 100644 --- a/frmts/vrt/vrtderivedrasterband.cpp +++ b/frmts/vrt/vrtderivedrasterband.cpp @@ -1125,6 +1125,7 @@ CPLErr VRTDerivedRasterBand::IRasterIO( // Load values for sources into packed buffers. CPLErr eErr = CE_None; + VRTSource::WorkingState oWorkingState; for (int iBuffer = 0; iBuffer < nBufferCount && eErr == CE_None; iBuffer++) { const int iSource = anMapBufferIdxToSourceIdx[iBuffer]; @@ -1136,7 +1137,7 @@ CPLErr VRTDerivedRasterBand::IRasterIO( (nYShiftInBuffer * nExtBufXSize + nXShiftInBuffer) * nSrcTypeSize, nExtBufXSizeReq, nExtBufYSizeReq, eSrcType, nSrcTypeSize, - nSrcTypeSize * nExtBufXSize, &sExtraArg); + nSrcTypeSize * nExtBufXSize, &sExtraArg, oWorkingState); // Extend first lines for (int iY = 0; iY < nYShiftInBuffer; iY++) diff --git a/frmts/vrt/vrtfilters.cpp b/frmts/vrt/vrtfilters.cpp index ddcd0c647946..0fbaed3c3e3f 100644 --- a/frmts/vrt/vrtfilters.cpp +++ b/frmts/vrt/vrtfilters.cpp @@ -128,7 +128,8 @@ CPLErr VRTFilteredSource::RasterIO(GDALDataType eVRTBandDataType, int nXOff, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, - GDALRasterIOExtraArg *psExtraArg) + GDALRasterIOExtraArg *psExtraArg, + WorkingState &oWorkingState) { /* -------------------------------------------------------------------- */ @@ -140,7 +141,8 @@ CPLErr VRTFilteredSource::RasterIO(GDALDataType eVRTBandDataType, int nXOff, { return VRTComplexSource::RasterIO( eVRTBandDataType, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, - nBufYSize, eBufType, nPixelSpace, nLineSpace, psExtraArg); + nBufYSize, eBufType, nPixelSpace, nLineSpace, psExtraArg, + oWorkingState); } double dfXOff = nXOff; @@ -321,7 +323,8 @@ CPLErr VRTFilteredSource::RasterIO(GDALDataType eVRTBandDataType, int nXOff, nFileYSize, pabyWorkData + nLineOffset * nTopFill + nPixelOffset * nLeftFill, nFileXSize, nFileYSize, eOperDataType, nPixelOffset, nLineOffset, - &sExtraArgs, bIsComplex ? GDT_CFloat32 : GDT_Float32); + &sExtraArgs, bIsComplex ? GDT_CFloat32 : GDT_Float32, + oWorkingState); if (eErr != CE_None) { diff --git a/frmts/vrt/vrtmultidim.cpp b/frmts/vrt/vrtmultidim.cpp index 380af50e4b27..6420805712c6 100644 --- a/frmts/vrt/vrtmultidim.cpp +++ b/frmts/vrt/vrtmultidim.cpp @@ -2602,8 +2602,8 @@ class VRTArraySource : public VRTSource CPLErr RasterIO(GDALDataType eBandDataType, int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, - GSpacing nLineSpace, - GDALRasterIOExtraArg *psExtraArg) override; + GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg, + WorkingState &oWorkingState) override; double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override { @@ -2641,11 +2641,13 @@ CPLErr VRTArraySource::RasterIO(GDALDataType eBandDataType, int nXOff, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, - GDALRasterIOExtraArg *psExtraArg) + GDALRasterIOExtraArg *psExtraArg, + WorkingState &oWorkingState) { - return m_poSimpleSource->RasterIO( - eBandDataType, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, - nBufYSize, eBufType, nPixelSpace, nLineSpace, psExtraArg); + return m_poSimpleSource->RasterIO(eBandDataType, nXOff, nYOff, nXSize, + nYSize, pData, nBufXSize, nBufYSize, + eBufType, nPixelSpace, nLineSpace, + psExtraArg, oWorkingState); } /************************************************************************/ diff --git a/frmts/vrt/vrtsourcedrasterband.cpp b/frmts/vrt/vrtsourcedrasterband.cpp index d12fef5154b3..509ab1094a7c 100644 --- a/frmts/vrt/vrtsourcedrasterband.cpp +++ b/frmts/vrt/vrtsourcedrasterband.cpp @@ -358,6 +358,7 @@ CPLErr VRTSourcedRasterBand::IRasterIO( /* Overlay each source in turn over top this. */ /* -------------------------------------------------------------------- */ CPLErr eErr = CE_None; + VRTSource::WorkingState oWorkingState; for (int iSource = 0; eErr == CE_None && iSource < nSources; iSource++) { psExtraArg->pfnProgress = GDALScaledProgress; @@ -369,7 +370,8 @@ CPLErr VRTSourcedRasterBand::IRasterIO( eErr = papoSources[iSource]->RasterIO( eDataType, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, - nBufYSize, eBufType, nPixelSpace, nLineSpace, psExtraArg); + nBufYSize, eBufType, nPixelSpace, nLineSpace, psExtraArg, + l_poDS ? l_poDS->m_oWorkingState : oWorkingState); GDALDestroyScaledProgress(psExtraArg->pProgressData); } diff --git a/frmts/vrt/vrtsources.cpp b/frmts/vrt/vrtsources.cpp index 8ad88172ad33..e6949bf4c12f 100644 --- a/frmts/vrt/vrtsources.cpp +++ b/frmts/vrt/vrtsources.cpp @@ -1280,7 +1280,8 @@ CPLErr VRTSimpleSource::RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, - GDALRasterIOExtraArg *psExtraArgIn) + GDALRasterIOExtraArg *psExtraArgIn, + WorkingState & /*oWorkingState*/) { GDALRasterIOExtraArg sExtraArg; @@ -1769,7 +1770,8 @@ CPLErr VRTAveragedSource::RasterIO(GDALDataType /*eVRTBandDataType*/, int nXOff, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, - GDALRasterIOExtraArg *psExtraArgIn) + GDALRasterIOExtraArg *psExtraArgIn, + WorkingState & /*oWorkingState*/) { GDALRasterIOExtraArg sExtraArg; @@ -2367,7 +2369,8 @@ CPLErr VRTComplexSource::RasterIO(GDALDataType eVRTBandDataType, int nXOff, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, - GDALRasterIOExtraArg *psExtraArgIn) + GDALRasterIOExtraArg *psExtraArgIn, + WorkingState &oWorkingState) { GDALRasterIOExtraArg sExtraArg; @@ -2454,13 +2457,13 @@ CPLErr VRTComplexSource::RasterIO(GDALDataType eVRTBandDataType, int nXOff, return VRTSimpleSource::RasterIO( eVRTBandDataType, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace, - psExtraArgIn); + psExtraArgIn, oWorkingState); } return RasterIOProcessNoData( poSourceBand, eVRTBandDataType, nReqXOff, nReqYOff, nReqXSize, nReqYSize, pabyOut, nOutXSize, nOutYSize, eBufType, nPixelSpace, - nLineSpace, psExtraArg); + nLineSpace, psExtraArg, oWorkingState); } else if (eSourceType == GDT_Int16) { @@ -2469,13 +2472,13 @@ CPLErr VRTComplexSource::RasterIO(GDALDataType eVRTBandDataType, int nXOff, return VRTSimpleSource::RasterIO( eVRTBandDataType, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace, - psExtraArgIn); + psExtraArgIn, oWorkingState); } return RasterIOProcessNoData( poSourceBand, eVRTBandDataType, nReqXOff, nReqYOff, nReqXSize, nReqYSize, pabyOut, nOutXSize, nOutYSize, eBufType, nPixelSpace, - nLineSpace, psExtraArg); + nLineSpace, psExtraArg, oWorkingState); } else if (eSourceType == GDT_UInt16) { @@ -2484,13 +2487,13 @@ CPLErr VRTComplexSource::RasterIO(GDALDataType eVRTBandDataType, int nXOff, return VRTSimpleSource::RasterIO( eVRTBandDataType, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace, - psExtraArgIn); + psExtraArgIn, oWorkingState); } return RasterIOProcessNoData( poSourceBand, eVRTBandDataType, nReqXOff, nReqYOff, nReqXSize, nReqYSize, pabyOut, nOutXSize, nOutYSize, eBufType, nPixelSpace, - nLineSpace, psExtraArg); + nLineSpace, psExtraArg, oWorkingState); } } @@ -2505,14 +2508,16 @@ CPLErr VRTComplexSource::RasterIO(GDALDataType eVRTBandDataType, int nXOff, eErr = RasterIOInternal( poSourceBand, eVRTBandDataType, nReqXOff, nReqYOff, nReqXSize, nReqYSize, pabyOut, nOutXSize, nOutYSize, eBufType, nPixelSpace, - nLineSpace, psExtraArg, bIsComplex ? GDT_CFloat64 : GDT_Float64); + nLineSpace, psExtraArg, bIsComplex ? GDT_CFloat64 : GDT_Float64, + oWorkingState); } else { eErr = RasterIOInternal( poSourceBand, eVRTBandDataType, nReqXOff, nReqYOff, nReqXSize, nReqYSize, pabyOut, nOutXSize, nOutYSize, eBufType, nPixelSpace, - nLineSpace, psExtraArg, bIsComplex ? GDT_CFloat32 : GDT_Float32); + nLineSpace, psExtraArg, bIsComplex ? GDT_CFloat32 : GDT_Float32, + oWorkingState); } return eErr; @@ -2544,7 +2549,8 @@ CPLErr VRTComplexSource::RasterIOProcessNoData( GDALRasterBand *poSourceBand, GDALDataType eVRTBandDataType, int nReqXOff, int nReqYOff, int nReqXSize, int nReqYSize, void *pData, int nOutXSize, int nOutYSize, GDALDataType eBufType, GSpacing nPixelSpace, - GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg) + GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg, + WorkingState &oWorkingState) { CPLAssert(m_nProcessingFlags == PROCESSING_FLAG_NODATA); CPLAssert(GDALIsValueInRange(m_dfNoDataValue)); @@ -2563,7 +2569,7 @@ CPLErr VRTComplexSource::RasterIOProcessNoData( "Too large temporary buffer"); return CE_Failure; } - m_abyWrkBuffer.resize(sizeof(SourceDT) * nPixelCount); + oWorkingState.m_abyWrkBuffer.resize(sizeof(SourceDT) * nPixelCount); } catch (const std::bad_alloc &e) { @@ -2571,7 +2577,7 @@ CPLErr VRTComplexSource::RasterIOProcessNoData( return CE_Failure; } const auto paSrcData = - reinterpret_cast(m_abyWrkBuffer.data()); + reinterpret_cast(oWorkingState.m_abyWrkBuffer.data()); const GDALRIOResampleAlg eResampleAlgBack = psExtraArg->eResampleAlg; if (!m_osResampling.empty()) @@ -2581,7 +2587,7 @@ CPLErr VRTComplexSource::RasterIOProcessNoData( const CPLErr eErr = poSourceBand->RasterIO( GF_Read, nReqXOff, nReqYOff, nReqXSize, nReqYSize, - m_abyWrkBuffer.data(), nOutXSize, nOutYSize, eSourceType, + oWorkingState.m_abyWrkBuffer.data(), nOutXSize, nOutYSize, eSourceType, sizeof(SourceDT), sizeof(SourceDT) * static_cast(nOutXSize), psExtraArg); if (!m_osResampling.empty()) @@ -2726,7 +2732,7 @@ CPLErr VRTComplexSource::RasterIOInternal( int nReqYOff, int nReqXSize, int nReqYSize, void *pData, int nOutXSize, int nOutYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg, - GDALDataType eWrkDataType) + GDALDataType eWrkDataType, WorkingState &oWorkingState) { const GDALColorTable *poColorTable = nullptr; const bool bIsComplex = CPL_TO_BOOL(GDALDataTypeIsComplex(eBufType)); @@ -2780,14 +2786,15 @@ CPLErr VRTComplexSource::RasterIOInternal( "Too large temporary buffer"); return CE_Failure; } - m_abyWrkBuffer.resize(nWordSize * nPixelCount); + oWorkingState.m_abyWrkBuffer.resize(nWordSize * nPixelCount); } catch (const std::bad_alloc &e) { CPLError(CE_Failure, CPLE_OutOfMemory, "%s", e.what()); return CE_Failure; } - pafData = reinterpret_cast(m_abyWrkBuffer.data()); + pafData = reinterpret_cast( + oWorkingState.m_abyWrkBuffer.data()); const GDALRIOResampleAlg eResampleAlgBack = psExtraArg->eResampleAlg; if (!m_osResampling.empty()) @@ -2798,9 +2805,9 @@ CPLErr VRTComplexSource::RasterIOInternal( const CPLErr eErr = poSourceBand->RasterIO( GF_Read, nReqXOff, nReqYOff, nReqXSize, nReqYSize, - m_abyWrkBuffer.data(), nOutXSize, nOutYSize, eWrkDataType, - nWordSize, nWordSize * static_cast(nOutXSize), - psExtraArg); + oWorkingState.m_abyWrkBuffer.data(), nOutXSize, nOutYSize, + eWrkDataType, nWordSize, + nWordSize * static_cast(nOutXSize), psExtraArg); if (!m_osResampling.empty()) psExtraArg->eResampleAlg = eResampleAlgBack; @@ -2818,7 +2825,7 @@ CPLErr VRTComplexSource::RasterIOInternal( { try { - m_abyWrkBufferMask.resize(nPixelCount); + oWorkingState.m_abyWrkBufferMask.resize(nPixelCount); } catch (const std::exception &) { @@ -2826,8 +2833,8 @@ CPLErr VRTComplexSource::RasterIOInternal( "Out of memory when allocating mask buffer"); return CE_Failure; } - pabyMask = - reinterpret_cast(m_abyWrkBufferMask.data()); + pabyMask = reinterpret_cast( + oWorkingState.m_abyWrkBufferMask.data()); auto poMaskBand = (poSourceBand->GetColorInterpretation() == GCI_AlphaBand || GetMaskBandMainBand() != nullptr) @@ -2835,8 +2842,9 @@ CPLErr VRTComplexSource::RasterIOInternal( : poSourceBand->GetMaskBand(); if (poMaskBand->RasterIO( GF_Read, nReqXOff, nReqYOff, nReqXSize, nReqYSize, - m_abyWrkBufferMask.data(), nOutXSize, nOutYSize, GDT_Byte, - 1, static_cast(nOutXSize), psExtraArg) != CE_None) + oWorkingState.m_abyWrkBufferMask.data(), nOutXSize, + nOutYSize, GDT_Byte, 1, static_cast(nOutXSize), + psExtraArg) != CE_None) { return CE_Failure; } @@ -3021,7 +3029,7 @@ template CPLErr VRTComplexSource::RasterIOInternal( int nReqYOff, int nReqXSize, int nReqYSize, void *pData, int nOutXSize, int nOutYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg, - GDALDataType eWrkDataType); + GDALDataType eWrkDataType, WorkingState &oWorkingState); /************************************************************************/ /* AreValuesUnchanged() */ @@ -3127,7 +3135,8 @@ CPLErr VRTFuncSource::RasterIO(GDALDataType /*eVRTBandDataType*/, int nXOff, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, - GDALRasterIOExtraArg * /* psExtraArg */) + GDALRasterIOExtraArg * /* psExtraArg */, + WorkingState & /* oWorkingState */) { if (nPixelSpace * 8 == GDALGetDataTypeSize(eBufType) && nLineSpace == nPixelSpace * nXSize && nBufXSize == nXSize &&