LCOV - code coverage report
Current view: top level - frmts/vrt - vrtdataset.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 206 220 93.6 %
Date: 2024-11-21 22:18:42 Functions: 67 71 94.4 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Project:  Virtual GDAL Datasets
       5             :  * Purpose:  Declaration of virtual gdal dataset classes.
       6             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2001, Frank Warmerdam <warmerdam@pobox.com>
      10             :  * Copyright (c) 2007-2013, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #ifndef VIRTUALDATASET_H_INCLUDED
      16             : #define VIRTUALDATASET_H_INCLUDED
      17             : 
      18             : #ifndef DOXYGEN_SKIP
      19             : 
      20             : #include "cpl_hash_set.h"
      21             : #include "cpl_minixml.h"
      22             : #include "gdal_pam.h"
      23             : #include "gdal_priv.h"
      24             : #include "gdal_rat.h"
      25             : #include "gdal_vrt.h"
      26             : #include "gdal_rat.h"
      27             : 
      28             : #include <atomic>
      29             : #include <deque>
      30             : #include <functional>
      31             : #include <map>
      32             : #include <memory>
      33             : #include <mutex>
      34             : #include <vector>
      35             : 
      36             : CPLErr GDALRegisterDefaultPixelFunc();
      37             : void GDALVRTRegisterDefaultProcessedDatasetFuncs();
      38             : CPLString CPL_DLL VRTSerializeNoData(double dfVal, GDALDataType eDataType,
      39             :                                      int nPrecision);
      40             : 
      41             : #if 0
      42             : int VRTWarpedOverviewTransform( void *pTransformArg, int bDstToSrc,
      43             :                                 int nPointCount,
      44             :                                 double *padfX, double *padfY, double *padfZ,
      45             :                                 int *panSuccess );
      46             : void* VRTDeserializeWarpedOverviewTransformer( CPLXMLNode *psTree );
      47             : #endif
      48             : 
      49             : /************************************************************************/
      50             : /*                          VRTOverviewInfo()                           */
      51             : /************************************************************************/
      52             : class VRTOverviewInfo
      53             : {
      54             :     CPL_DISALLOW_COPY_ASSIGN(VRTOverviewInfo)
      55             : 
      56             :   public:
      57             :     CPLString osFilename{};
      58             :     int nBand = 0;
      59             :     GDALRasterBand *poBand = nullptr;
      60             :     int bTriedToOpen = FALSE;
      61             : 
      62          16 :     VRTOverviewInfo() = default;
      63             : 
      64           0 :     VRTOverviewInfo(VRTOverviewInfo &&oOther) noexcept
      65           0 :         : osFilename(std::move(oOther.osFilename)), nBand(oOther.nBand),
      66           0 :           poBand(oOther.poBand), bTriedToOpen(oOther.bTriedToOpen)
      67             :     {
      68           0 :         oOther.poBand = nullptr;
      69           0 :     }
      70             : 
      71          16 :     ~VRTOverviewInfo()
      72          16 :     {
      73          16 :         CloseDataset();
      74          16 :     }
      75             : 
      76          32 :     bool CloseDataset()
      77             :     {
      78          32 :         if (poBand == nullptr)
      79          23 :             return false;
      80             : 
      81           9 :         GDALDataset *poDS = poBand->GetDataset();
      82             :         // Nullify now, to prevent recursion in some cases !
      83           9 :         poBand = nullptr;
      84           9 :         if (poDS->GetShared())
      85           9 :             GDALClose(/* (GDALDatasetH) */ poDS);
      86             :         else
      87           0 :             poDS->Dereference();
      88             : 
      89           9 :         return true;
      90             :     }
      91             : };
      92             : 
      93             : /************************************************************************/
      94             : /*                            VRTMapSharedResources                     */
      95             : /************************************************************************/
      96             : 
      97             : /** Map of shared datasets */
      98             : class CPL_DLL VRTMapSharedResources
      99             : {
     100             :   public:
     101        4097 :     VRTMapSharedResources() = default;
     102             : 
     103             :     /** Return a dataset from its key */
     104             :     GDALDataset *Get(const std::string &osKey) const;
     105             : 
     106             :     /** Inserts a dataset. It must be kept alive while this
     107             :      * VRTMapSharedResources is alive.
     108             :      */
     109             :     void Insert(const std::string &osKey, GDALDataset *poDS);
     110             : 
     111             :     /** To be called before any attempt at using this instance in a
     112             :      * multi-threaded context.
     113             :      */
     114             :     void InitMutex();
     115             : 
     116             :   private:
     117             :     std::mutex oMutex{};
     118             :     std::mutex *poMutex = nullptr;
     119             :     std::map<std::string, GDALDataset *> oMap{};
     120             : 
     121             :     CPL_DISALLOW_COPY_ASSIGN(VRTMapSharedResources)
     122             : };
     123             : 
     124             : /************************************************************************/
     125             : /*                              VRTSource                               */
     126             : /************************************************************************/
     127             : 
     128             : class CPL_DLL VRTSource
     129             : {
     130             :   public:
     131             :     struct CPL_DLL WorkingState
     132             :     {
     133             :         // GByte whose initialization constructor does nothing
     134             : #ifdef __GNUC__
     135             : #pragma GCC diagnostic push
     136             : #pragma GCC diagnostic ignored "-Weffc++"
     137             : #endif
     138             :         struct NoInitByte
     139             :         {
     140             :             GByte value;
     141             : 
     142             :             // cppcheck-suppress uninitMemberVar
     143    13904800 :             NoInitByte()
     144    13904800 :             {
     145             :                 // do nothing
     146             :                 /* coverity[uninit_member] */
     147    13904800 :             }
     148             : 
     149          27 :             inline operator GByte() const
     150             :             {
     151          27 :                 return value;
     152             :             }
     153             :         };
     154             : #ifdef __GNUC__
     155             : #pragma GCC diagnostic pop
     156             : #endif
     157             : 
     158             :         std::vector<NoInitByte> m_abyWrkBuffer{};
     159             :         std::vector<NoInitByte> m_abyWrkBufferMask{};
     160             :     };
     161             : 
     162             :     virtual ~VRTSource();
     163             : 
     164             :     virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
     165             :                             int nXSize, int nYSize, void *pData, int nBufXSize,
     166             :                             int nBufYSize, GDALDataType eBufType,
     167             :                             GSpacing nPixelSpace, GSpacing nLineSpace,
     168             :                             GDALRasterIOExtraArg *psExtraArg,
     169             :                             WorkingState &oWorkingState) = 0;
     170             : 
     171             :     virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) = 0;
     172             :     virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) = 0;
     173             :     virtual CPLErr GetHistogram(int nXSize, int nYSize, double dfMin,
     174             :                                 double dfMax, int nBuckets,
     175             :                                 GUIntBig *panHistogram, int bIncludeOutOfRange,
     176             :                                 int bApproxOK, GDALProgressFunc pfnProgress,
     177             :                                 void *pProgressData) = 0;
     178             : 
     179             :     virtual CPLErr XMLInit(const CPLXMLNode *psTree, const char *,
     180             :                            VRTMapSharedResources &) = 0;
     181             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) = 0;
     182             : 
     183             :     virtual void GetFileList(char ***ppapszFileList, int *pnSize,
     184             :                              int *pnMaxSize, CPLHashSet *hSetFiles);
     185             : 
     186             :     /** Returns whether this instance can be cast to a VRTSimpleSource
     187             :      * (and its subclasses).
     188             :      */
     189          63 :     virtual bool IsSimpleSource() const
     190             :     {
     191          63 :         return false;
     192             :     }
     193             : 
     194             :     /** Returns a string with the VRTSource class type.
     195             :      * This method must be implemented in all subclasses
     196             :      */
     197             :     virtual const char *GetType() const = 0;
     198             : 
     199          25 :     virtual CPLErr FlushCache(bool /*bAtClosing*/)
     200             :     {
     201          25 :         return CE_None;
     202             :     }
     203             : };
     204             : 
     205             : typedef VRTSource *(*VRTSourceParser)(const CPLXMLNode *, const char *,
     206             :                                       VRTMapSharedResources &oMapSharedSources);
     207             : 
     208             : VRTSource *VRTParseCoreSources(const CPLXMLNode *psTree, const char *,
     209             :                                VRTMapSharedResources &oMapSharedSources);
     210             : VRTSource *VRTParseFilterSources(const CPLXMLNode *psTree, const char *,
     211             :                                  VRTMapSharedResources &oMapSharedSources);
     212             : VRTSource *VRTParseArraySource(const CPLXMLNode *psTree, const char *,
     213             :                                VRTMapSharedResources &oMapSharedSources);
     214             : 
     215             : /************************************************************************/
     216             : /*                              VRTDataset                              */
     217             : /************************************************************************/
     218             : 
     219             : class VRTRasterBand;
     220             : 
     221             : template <class T> struct VRTFlushCacheStruct
     222             : {
     223             :     static CPLErr FlushCache(T &obj, bool bAtClosing);
     224             : };
     225             : 
     226             : class VRTWarpedDataset;
     227             : class VRTPansharpenedDataset;
     228             : class VRTProcessedDataset;
     229             : class VRTGroup;
     230             : class VRTSimpleSource;
     231             : 
     232             : class CPL_DLL VRTDataset CPL_NON_FINAL : public GDALDataset
     233             : {
     234             :     friend class VRTRasterBand;
     235             :     friend struct VRTFlushCacheStruct<VRTDataset>;
     236             :     friend struct VRTFlushCacheStruct<VRTWarpedDataset>;
     237             :     friend struct VRTFlushCacheStruct<VRTPansharpenedDataset>;
     238             :     friend struct VRTFlushCacheStruct<VRTProcessedDataset>;
     239             :     friend class VRTSourcedRasterBand;
     240             :     friend class VRTSimpleSource;
     241             :     friend VRTDatasetH CPL_STDCALL VRTCreate(int nXSize, int nYSize);
     242             : 
     243             :     std::vector<gdal::GCP> m_asGCPs{};
     244             :     std::unique_ptr<OGRSpatialReference, OGRSpatialReferenceReleaser>
     245             :         m_poGCP_SRS{};
     246             : 
     247             :     bool m_bNeedsFlush = false;
     248             :     bool m_bWritable = true;
     249             :     bool m_bCanTakeRef = true;
     250             : 
     251             :     char *m_pszVRTPath = nullptr;
     252             : 
     253             :     VRTRasterBand *m_poMaskBand = nullptr;
     254             : 
     255             :     mutable int m_nCompatibleForDatasetIO = -1;
     256             :     bool CheckCompatibleForDatasetIO() const;
     257             : 
     258             :     // Virtual (ie not materialized) overviews, created either implicitly
     259             :     // when it is cheap to do it, or explicitly.
     260             :     std::vector<GDALDataset *> m_apoOverviews{};
     261             :     std::vector<GDALDataset *> m_apoOverviewsBak{};
     262             :     CPLStringList m_aosOverviewList{};  // only temporarily set during Open()
     263             :     CPLString m_osOverviewResampling{};
     264             :     std::vector<int> m_anOverviewFactors{};
     265             : 
     266             :     char **m_papszXMLVRTMetadata = nullptr;
     267             : 
     268             :     VRTMapSharedResources m_oMapSharedSources{};
     269             :     std::shared_ptr<VRTGroup> m_poRootGroup{};
     270             : 
     271             :     // Used by VRTSourcedRasterBand::IRasterIO() in single-threaded situations
     272             :     VRTSource::WorkingState m_oWorkingState{};
     273             : 
     274             :     // Used by VRTSourcedRasterBand::IRasterIO() when using multi-threading
     275             :     struct QueueWorkingStates
     276             :     {
     277             :         std::mutex oMutex{};
     278             :         std::vector<std::unique_ptr<VRTSource::WorkingState>> oStates{};
     279             :     };
     280             : 
     281             :     QueueWorkingStates m_oQueueWorkingStates{};
     282             : 
     283             :     bool m_bMultiThreadedRasterIOLastUsed = false;
     284             : 
     285             :     static constexpr const char *const apszSpecialSyntax[] = {
     286             :         "NITF_IM:{ANY}:{FILENAME}", "PDF:{ANY}:{FILENAME}",
     287             :         "RASTERLITE:{FILENAME},{ANY}", "TILEDB:\"{FILENAME}\":{ANY}",
     288             :         "TILEDB:{FILENAME}:{ANY}"};
     289             : 
     290             :     VRTRasterBand *InitBand(const char *pszSubclass, int nBand,
     291             :                             bool bAllowPansharpenedOrProcessed);
     292             :     static GDALDataset *OpenVRTProtocol(const char *pszSpec);
     293             :     bool AddVirtualOverview(int nOvFactor, const char *pszResampling);
     294             : 
     295             :     bool GetShiftedDataset(int nXOff, int nYOff, int nXSize, int nYSize,
     296             :                            GDALDataset *&poSrcDataset, int &nSrcXOff,
     297             :                            int &nSrcYOff);
     298             : 
     299             :     /** Structure used to declare a threaded job to satisfy IRasterIO()
     300             :      * on a given source.
     301             :      */
     302             :     struct RasterIOJob
     303             :     {
     304             :         std::atomic<int> *pnCompletedJobs = nullptr;
     305             :         std::atomic<bool> *pbSuccess = nullptr;
     306             : 
     307             :         GDALDataType eVRTBandDataType = GDT_Unknown;
     308             :         int nXOff = 0;
     309             :         int nYOff = 0;
     310             :         int nXSize = 0;
     311             :         int nYSize = 0;
     312             :         void *pData = nullptr;
     313             :         int nBufXSize = 0;
     314             :         int nBufYSize = 0;
     315             :         int nBandCount = 0;
     316             :         BANDMAP_TYPE panBandMap = nullptr;
     317             :         GDALDataType eBufType = GDT_Unknown;
     318             :         GSpacing nPixelSpace = 0;
     319             :         GSpacing nLineSpace = 0;
     320             :         GSpacing nBandSpace = 0;
     321             :         GDALRasterIOExtraArg *psExtraArg = nullptr;
     322             :         VRTSimpleSource *poSource = nullptr;
     323             : 
     324             :         static void Func(void *pData);
     325             :     };
     326             : 
     327             :     CPL_DISALLOW_COPY_ASSIGN(VRTDataset)
     328             : 
     329             :   protected:
     330             :     bool m_bBlockSizeSpecified = false;
     331             :     int m_nBlockXSize = 0;
     332             :     int m_nBlockYSize = 0;
     333             : 
     334             :     std::unique_ptr<OGRSpatialReference, OGRSpatialReferenceReleaser> m_poSRS{};
     335             : 
     336             :     int m_bGeoTransformSet = false;
     337             :     double m_adfGeoTransform[6];
     338             : 
     339             :     virtual int CloseDependentDatasets() override;
     340             : 
     341             :   public:
     342             :     VRTDataset(int nXSize, int nYSize, int nBlockXSize = 0,
     343             :                int nBlockYSize = 0);
     344             :     virtual ~VRTDataset();
     345             : 
     346       66663 :     void SetNeedsFlush()
     347             :     {
     348       66663 :         m_bNeedsFlush = true;
     349       66663 :     }
     350             : 
     351             :     virtual CPLErr FlushCache(bool bAtClosing) override;
     352             : 
     353         185 :     void SetWritable(int bWritableIn)
     354             :     {
     355         185 :         m_bWritable = CPL_TO_BOOL(bWritableIn);
     356         185 :     }
     357             : 
     358             :     virtual CPLErr CreateMaskBand(int nFlags) override;
     359             :     void SetMaskBand(VRTRasterBand *poMaskBand);
     360             : 
     361        8798 :     const OGRSpatialReference *GetSpatialRef() const override
     362             :     {
     363        8798 :         return m_poSRS.get();
     364             :     }
     365             : 
     366             :     CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
     367             : 
     368             :     virtual CPLErr GetGeoTransform(double *) override;
     369             :     virtual CPLErr SetGeoTransform(double *) override;
     370             : 
     371             :     virtual CPLErr SetMetadata(char **papszMetadata,
     372             :                                const char *pszDomain = "") override;
     373             :     virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
     374             :                                    const char *pszDomain = "") override;
     375             : 
     376             :     virtual char **GetMetadata(const char *pszDomain = "") override;
     377             :     virtual const char *GetMetadataItem(const char *pszName,
     378             :                                         const char *pszDomain = "") override;
     379             : 
     380             :     virtual int GetGCPCount() override;
     381             : 
     382          51 :     const OGRSpatialReference *GetGCPSpatialRef() const override
     383             :     {
     384          51 :         return m_poGCP_SRS.get();
     385             :     }
     386             : 
     387             :     virtual const GDAL_GCP *GetGCPs() override;
     388             :     using GDALDataset::SetGCPs;
     389             :     CPLErr SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList,
     390             :                    const OGRSpatialReference *poSRS) override;
     391             : 
     392             :     virtual CPLErr AddBand(GDALDataType eType,
     393             :                            char **papszOptions = nullptr) override;
     394             : 
     395             :     virtual char **GetFileList() override;
     396             : 
     397             :     virtual CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
     398             :                              int nXSize, int nYSize, void *pData, int nBufXSize,
     399             :                              int nBufYSize, GDALDataType eBufType,
     400             :                              int nBandCount, BANDMAP_TYPE panBandMap,
     401             :                              GSpacing nPixelSpace, GSpacing nLineSpace,
     402             :                              GSpacing nBandSpace,
     403             :                              GDALRasterIOExtraArg *psExtraArg) override;
     404             : 
     405             :     virtual CPLStringList
     406             :     GetCompressionFormats(int nXOff, int nYOff, int nXSize, int nYSize,
     407             :                           int nBandCount, const int *panBandList) override;
     408             :     virtual CPLErr ReadCompressedData(const char *pszFormat, int nXOff,
     409             :                                       int nYOff, int nXSize, int nYSize,
     410             :                                       int nBandCount, const int *panBandList,
     411             :                                       void **ppBuffer, size_t *pnBufferSize,
     412             :                                       char **ppszDetailedFormat) override;
     413             : 
     414             :     virtual CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize,
     415             :                               int nBufXSize, int nBufYSize, GDALDataType eDT,
     416             :                               int nBandCount, int *panBandList,
     417             :                               char **papszOptions) override;
     418             : 
     419             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath);
     420             :     virtual CPLErr XMLInit(const CPLXMLNode *, const char *);
     421             : 
     422             :     virtual CPLErr IBuildOverviews(const char *, int, const int *, int,
     423             :                                    const int *, GDALProgressFunc, void *,
     424             :                                    CSLConstList papszOptions) override;
     425             : 
     426             :     std::shared_ptr<GDALGroup> GetRootGroup() const override;
     427             : 
     428             :     void ClearStatistics() override;
     429             : 
     430             :     /** To be called when a new source is added, to invalidate cached states. */
     431       12810 :     void SourceAdded()
     432             :     {
     433       12810 :         m_nCompatibleForDatasetIO = -1;
     434       12810 :     }
     435             : 
     436             :     /* Used by PDF driver for example */
     437             :     GDALDataset *GetSingleSimpleSource();
     438             :     void BuildVirtualOverviews();
     439             : 
     440             :     void UnsetPreservedRelativeFilenames();
     441             : 
     442         292 :     bool IsBlockSizeSpecified() const
     443             :     {
     444         292 :         return m_bBlockSizeSpecified;
     445             :     }
     446             : 
     447         292 :     int GetBlockXSize() const
     448             :     {
     449         292 :         return m_nBlockXSize;
     450             :     }
     451             : 
     452         292 :     int GetBlockYSize() const
     453             :     {
     454         292 :         return m_nBlockYSize;
     455             :     }
     456             : 
     457             :     static int Identify(GDALOpenInfo *);
     458             :     static GDALDataset *Open(GDALOpenInfo *);
     459             :     static VRTDataset *OpenXML(const char *, const char * = nullptr,
     460             :                                GDALAccess eAccess = GA_ReadOnly);
     461             :     static GDALDataset *Create(const char *pszName, int nXSize, int nYSize,
     462             :                                int nBands, GDALDataType eType,
     463             :                                char **papszOptions);
     464             :     static GDALDataset *
     465             :     CreateMultiDimensional(const char *pszFilename,
     466             :                            CSLConstList papszRootGroupOptions,
     467             :                            CSLConstList papszOptions);
     468             :     static CPLErr Delete(const char *pszFilename);
     469             : 
     470             :     static std::string BuildSourceFilename(const char *pszFilename,
     471             :                                            const char *pszVRTPath,
     472             :                                            bool bRelativeToVRT);
     473             : 
     474             :     static int GetNumThreads(GDALDataset *poDS);
     475             : };
     476             : 
     477             : /************************************************************************/
     478             : /*                           VRTWarpedDataset                           */
     479             : /************************************************************************/
     480             : 
     481             : class GDALWarpOperation;
     482             : class VRTWarpedRasterBand;
     483             : 
     484             : class CPL_DLL VRTWarpedDataset final : public VRTDataset
     485             : {
     486             :     GDALWarpOperation *m_poWarper;
     487             : 
     488             :     bool m_bIsOverview = false;
     489             :     std::vector<VRTWarpedDataset *> m_apoOverviews{};
     490             :     int m_nSrcOvrLevel;
     491             : 
     492             :     bool GetOverviewSize(GDALDataset *poSrcDS, int iOvr, int iSrcOvr,
     493             :                          int &nOvrXSize, int &nOvrYSize, double &dfSrcRatioX,
     494             :                          double &dfSrcRatioY) const;
     495             :     int GetOverviewCount() const;
     496             :     int GetSrcOverviewLevel(int iOvr, bool &bThisLevelOnlyOut) const;
     497             :     VRTWarpedDataset *CreateImplicitOverview(int iOvr) const;
     498             :     void CreateImplicitOverviews();
     499             : 
     500             :     friend class VRTWarpedRasterBand;
     501             : 
     502             :     CPL_DISALLOW_COPY_ASSIGN(VRTWarpedDataset)
     503             : 
     504             :   protected:
     505             :     virtual int CloseDependentDatasets() override;
     506             : 
     507             :   public:
     508             :     VRTWarpedDataset(int nXSize, int nYSize, int nBlockXSize = 0,
     509             :                      int nBlockYSize = 0);
     510             :     virtual ~VRTWarpedDataset();
     511             : 
     512             :     virtual CPLErr FlushCache(bool bAtClosing) override;
     513             : 
     514             :     CPLErr Initialize(/* GDALWarpOptions */ void *);
     515             : 
     516             :     virtual CPLErr IBuildOverviews(const char *, int, const int *, int,
     517             :                                    const int *, GDALProgressFunc, void *,
     518             :                                    CSLConstList papszOptions) override;
     519             : 
     520             :     virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
     521             :                                    const char *pszDomain = "") override;
     522             : 
     523             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
     524             :     virtual CPLErr XMLInit(const CPLXMLNode *, const char *) override;
     525             : 
     526             :     virtual CPLErr AddBand(GDALDataType eType,
     527             :                            char **papszOptions = nullptr) override;
     528             : 
     529             :     virtual char **GetFileList() override;
     530             : 
     531             :     virtual CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
     532             :                              int nXSize, int nYSize, void *pData, int nBufXSize,
     533             :                              int nBufYSize, GDALDataType eBufType,
     534             :                              int nBandCount, BANDMAP_TYPE panBandMap,
     535             :                              GSpacing nPixelSpace, GSpacing nLineSpace,
     536             :                              GSpacing nBandSpace,
     537             :                              GDALRasterIOExtraArg *psExtraArg) override;
     538             : 
     539             :     CPLErr ProcessBlock(int iBlockX, int iBlockY);
     540             : 
     541             :     void GetBlockSize(int *, int *) const;
     542             : };
     543             : 
     544             : /************************************************************************/
     545             : /*                        VRTPansharpenedDataset                        */
     546             : /************************************************************************/
     547             : 
     548             : class GDALPansharpenOperation;
     549             : 
     550             : typedef enum
     551             : {
     552             :     GTAdjust_Union,
     553             :     GTAdjust_Intersection,
     554             :     GTAdjust_None,
     555             :     GTAdjust_NoneWithoutWarning
     556             : } GTAdjustment;
     557             : 
     558             : class VRTPansharpenedDataset final : public VRTDataset
     559             : {
     560             :     friend class VRTPansharpenedRasterBand;
     561             : 
     562             :     GDALPansharpenOperation *m_poPansharpener;
     563             :     VRTPansharpenedDataset *m_poMainDataset;
     564             :     std::vector<VRTPansharpenedDataset *> m_apoOverviewDatasets{};
     565             :     // Map from absolute to relative.
     566             :     std::map<CPLString, CPLString> m_oMapToRelativeFilenames{};
     567             : 
     568             :     int m_bLoadingOtherBands;
     569             : 
     570             :     GByte *m_pabyLastBufferBandRasterIO;
     571             :     int m_nLastBandRasterIOXOff;
     572             :     int m_nLastBandRasterIOYOff;
     573             :     int m_nLastBandRasterIOXSize;
     574             :     int m_nLastBandRasterIOYSize;
     575             :     GDALDataType m_eLastBandRasterIODataType;
     576             : 
     577             :     GTAdjustment m_eGTAdjustment;
     578             :     int m_bNoDataDisabled;
     579             : 
     580             :     std::vector<GDALDataset *> m_apoDatasetsToClose{};
     581             : 
     582             :     CPL_DISALLOW_COPY_ASSIGN(VRTPansharpenedDataset)
     583             : 
     584             :   protected:
     585             :     virtual int CloseDependentDatasets() override;
     586             : 
     587             :   public:
     588             :     VRTPansharpenedDataset(int nXSize, int nYSize, int nBlockXSize = 0,
     589             :                            int nBlockYSize = 0);
     590             :     virtual ~VRTPansharpenedDataset();
     591             : 
     592             :     virtual CPLErr FlushCache(bool bAtClosing) override;
     593             : 
     594             :     virtual CPLErr XMLInit(const CPLXMLNode *, const char *) override;
     595             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
     596             : 
     597             :     CPLErr XMLInit(const CPLXMLNode *psTree, const char *pszVRTPath,
     598             :                    GDALRasterBandH hPanchroBandIn, int nInputSpectralBandsIn,
     599             :                    GDALRasterBandH *pahInputSpectralBandsIn);
     600             : 
     601             :     virtual CPLErr AddBand(GDALDataType eType,
     602             :                            char **papszOptions = nullptr) override;
     603             : 
     604             :     virtual char **GetFileList() override;
     605             : 
     606             :     virtual CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
     607             :                              int nXSize, int nYSize, void *pData, int nBufXSize,
     608             :                              int nBufYSize, GDALDataType eBufType,
     609             :                              int nBandCount, BANDMAP_TYPE panBandMap,
     610             :                              GSpacing nPixelSpace, GSpacing nLineSpace,
     611             :                              GSpacing nBandSpace,
     612             :                              GDALRasterIOExtraArg *psExtraArg) override;
     613             : 
     614             :     void GetBlockSize(int *, int *) const;
     615             : 
     616             :     GDALPansharpenOperation *GetPansharpener()
     617             :     {
     618             :         return m_poPansharpener;
     619             :     }
     620             : };
     621             : 
     622             : /************************************************************************/
     623             : /*                        VRTPansharpenedDataset                        */
     624             : /************************************************************************/
     625             : 
     626             : /** Specialized implementation of VRTDataset that chains several processing
     627             :  * steps applied on all bands at a time.
     628             :  *
     629             :  * @since 3.9
     630             :  */
     631             : class VRTProcessedDataset final : public VRTDataset
     632             : {
     633             :   public:
     634             :     VRTProcessedDataset(int nXSize, int nYSize);
     635             :     ~VRTProcessedDataset() override;
     636             : 
     637             :     virtual CPLErr FlushCache(bool bAtClosing) override;
     638             : 
     639             :     virtual CPLErr XMLInit(const CPLXMLNode *, const char *) override;
     640             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
     641             : 
     642             :     void GetBlockSize(int *, int *) const;
     643             : 
     644             :     // GByte whose initialization constructor does nothing
     645             : #ifdef __GNUC__
     646             : #pragma GCC diagnostic push
     647             : #pragma GCC diagnostic ignored "-Weffc++"
     648             : #endif
     649             :     struct NoInitByte
     650             :     {
     651             :         GByte value;
     652             : 
     653             :         // cppcheck-suppress uninitMemberVar
     654     1576980 :         NoInitByte()
     655     1576980 :         {
     656             :             // do nothing
     657             :             /* coverity[uninit_member] */
     658     1576980 :         }
     659             : 
     660             :         inline operator GByte() const
     661             :         {
     662             :             return value;
     663             :         }
     664             :     };
     665             : #ifdef __GNUC__
     666             : #pragma GCC diagnostic pop
     667             : #endif
     668             : 
     669             :   private:
     670             :     friend class VRTProcessedRasterBand;
     671             : 
     672             :     //! Data for a processing step.
     673             :     struct Step
     674             :     {
     675             :         //! Algorithm name
     676             :         std::string osAlgorithm{};
     677             : 
     678             :         //! Arguments to pass to the processing function.
     679             :         CPLStringList aosArguments{};
     680             : 
     681             :         //! Data type of the input buffer.
     682             :         GDALDataType eInDT = GDT_Unknown;
     683             : 
     684             :         //! Data type of the output buffer.
     685             :         GDALDataType eOutDT = GDT_Unknown;
     686             : 
     687             :         //! Number of input bands.
     688             :         int nInBands = 0;
     689             : 
     690             :         //! Number of output bands.
     691             :         int nOutBands = 0;
     692             : 
     693             :         //! Nodata values (nInBands) of the input bands.
     694             :         std::vector<double> adfInNoData{};
     695             : 
     696             :         //! Nodata values (nOutBands) of the output bands.
     697             :         std::vector<double> adfOutNoData{};
     698             : 
     699             :         //! Working data structure (private data of the implementation of the function)
     700             :         VRTPDWorkingDataPtr pWorkingData = nullptr;
     701             : 
     702             :         // NOTE: if adding a new member, edit the move constructor and
     703             :         // assignment operators!
     704             : 
     705          44 :         Step() = default;
     706             :         ~Step();
     707             :         Step(Step &&);
     708             :         Step &operator=(Step &&);
     709             : 
     710             :       private:
     711             :         Step(const Step &) = delete;
     712             :         Step &operator=(const Step &) = delete;
     713             :         void deinit();
     714             :     };
     715             : 
     716             :     //! Directory of the VRT
     717             :     std::string m_osVRTPath{};
     718             : 
     719             :     //! Source dataset
     720             :     std::unique_ptr<GDALDataset> m_poSrcDS{};
     721             : 
     722             :     //! Processing steps.
     723             :     std::vector<Step> m_aoSteps{};
     724             : 
     725             :     //! Backup XML tree passed to XMLInit()
     726             :     CPLXMLTreeCloser m_oXMLTree{nullptr};
     727             : 
     728             :     //! Overview datasets (dynamically generated from the ones of m_poSrcDS)
     729             :     std::vector<std::unique_ptr<GDALDataset>> m_apoOverviewDatasets{};
     730             : 
     731             :     //! Input buffer of a processing step
     732             :     std::vector<NoInitByte> m_abyInput{};
     733             : 
     734             :     //! Output buffer of a processing step
     735             :     std::vector<NoInitByte> m_abyOutput{};
     736             : 
     737             :     CPLErr Init(const CPLXMLNode *, const char *,
     738             :                 const VRTProcessedDataset *poParentDS,
     739             :                 GDALDataset *poParentSrcDS, int iOvrLevel);
     740             : 
     741             :     bool ParseStep(const CPLXMLNode *psStep, bool bIsFinalStep,
     742             :                    GDALDataType &eCurrentDT, int &nCurrentBandCount,
     743             :                    std::vector<double> &adfInNoData,
     744             :                    std::vector<double> &adfOutNoData);
     745             :     bool ProcessRegion(int nXOff, int nYOff, int nBufXSize, int nBufYSize);
     746             : };
     747             : 
     748             : /************************************************************************/
     749             : /*                            VRTRasterBand                             */
     750             : /*                                                                      */
     751             : /*      Provides support for all the various kinds of metadata but      */
     752             : /*      no raster access.  That is handled by derived classes.          */
     753             : /************************************************************************/
     754             : 
     755             : constexpr double VRT_DEFAULT_NODATA_VALUE = -10000.0;
     756             : 
     757             : class CPL_DLL VRTRasterBand CPL_NON_FINAL : public GDALRasterBand
     758             : {
     759             :   private:
     760             :     void ResetNoDataValues();
     761             : 
     762             :   protected:
     763             :     friend class VRTDataset;
     764             : 
     765             :     int m_bIsMaskBand = FALSE;
     766             : 
     767             :     int m_bNoDataValueSet = FALSE;
     768             :     // If set to true, will not report the existence of nodata.
     769             :     int m_bHideNoDataValue = FALSE;
     770             :     double m_dfNoDataValue = VRT_DEFAULT_NODATA_VALUE;
     771             : 
     772             :     bool m_bNoDataSetAsInt64 = false;
     773             :     int64_t m_nNoDataValueInt64 = GDAL_PAM_DEFAULT_NODATA_VALUE_INT64;
     774             : 
     775             :     bool m_bNoDataSetAsUInt64 = false;
     776             :     uint64_t m_nNoDataValueUInt64 = GDAL_PAM_DEFAULT_NODATA_VALUE_UINT64;
     777             : 
     778             :     std::unique_ptr<GDALColorTable> m_poColorTable{};
     779             : 
     780             :     GDALColorInterp m_eColorInterp = GCI_Undefined;
     781             : 
     782             :     char *m_pszUnitType = nullptr;
     783             :     CPLStringList m_aosCategoryNames{};
     784             : 
     785             :     double m_dfOffset = 0.0;
     786             :     double m_dfScale = 1.0;
     787             : 
     788             :     CPLXMLNode *m_psSavedHistograms = nullptr;
     789             : 
     790             :     void Initialize(int nXSize, int nYSize);
     791             : 
     792             :     std::vector<VRTOverviewInfo> m_aoOverviewInfos{};
     793             : 
     794             :     VRTRasterBand *m_poMaskBand = nullptr;
     795             : 
     796             :     std::unique_ptr<GDALRasterAttributeTable> m_poRAT{};
     797             : 
     798             :     CPL_DISALLOW_COPY_ASSIGN(VRTRasterBand)
     799             : 
     800             :     bool IsNoDataValueInDataTypeRange() const;
     801             : 
     802             :   public:
     803             :     VRTRasterBand();
     804             :     virtual ~VRTRasterBand();
     805             : 
     806             :     virtual CPLErr XMLInit(const CPLXMLNode *, const char *,
     807             :                            VRTMapSharedResources &);
     808             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath,
     809             :                                        bool &bHasWarnedAboutRAMUsage,
     810             :                                        size_t &nAccRAMUsage);
     811             : 
     812             :     CPLErr SetNoDataValue(double) override;
     813             :     CPLErr SetNoDataValueAsInt64(int64_t nNoData) override;
     814             :     CPLErr SetNoDataValueAsUInt64(uint64_t nNoData) override;
     815             :     double GetNoDataValue(int *pbSuccess = nullptr) override;
     816             :     int64_t GetNoDataValueAsInt64(int *pbSuccess = nullptr) override;
     817             :     uint64_t GetNoDataValueAsUInt64(int *pbSuccess = nullptr) override;
     818             :     CPLErr DeleteNoDataValue() override;
     819             : 
     820             :     virtual CPLErr SetColorTable(GDALColorTable *) override;
     821             :     virtual GDALColorTable *GetColorTable() override;
     822             : 
     823             :     virtual GDALRasterAttributeTable *GetDefaultRAT() override;
     824             :     virtual CPLErr
     825             :     SetDefaultRAT(const GDALRasterAttributeTable *poRAT) override;
     826             : 
     827             :     virtual CPLErr SetColorInterpretation(GDALColorInterp) override;
     828             :     virtual GDALColorInterp GetColorInterpretation() override;
     829             : 
     830             :     virtual const char *GetUnitType() override;
     831             :     CPLErr SetUnitType(const char *) override;
     832             : 
     833             :     virtual char **GetCategoryNames() override;
     834             :     virtual CPLErr SetCategoryNames(char **) override;
     835             : 
     836             :     virtual CPLErr SetMetadata(char **papszMD,
     837             :                                const char *pszDomain = "") override;
     838             :     virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
     839             :                                    const char *pszDomain = "") override;
     840             : 
     841             :     virtual double GetOffset(int *pbSuccess = nullptr) override;
     842             :     CPLErr SetOffset(double) override;
     843             :     virtual double GetScale(int *pbSuccess = nullptr) override;
     844             :     CPLErr SetScale(double) override;
     845             : 
     846             :     virtual int GetOverviewCount() override;
     847             :     virtual GDALRasterBand *GetOverview(int) override;
     848             : 
     849             :     virtual CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets,
     850             :                                 GUIntBig *panHistogram, int bIncludeOutOfRange,
     851             :                                 int bApproxOK, GDALProgressFunc,
     852             :                                 void *pProgressData) override;
     853             : 
     854             :     virtual CPLErr GetDefaultHistogram(double *pdfMin, double *pdfMax,
     855             :                                        int *pnBuckets, GUIntBig **ppanHistogram,
     856             :                                        int bForce, GDALProgressFunc,
     857             :                                        void *pProgressData) override;
     858             : 
     859             :     virtual CPLErr SetDefaultHistogram(double dfMin, double dfMax, int nBuckets,
     860             :                                        GUIntBig *panHistogram) override;
     861             : 
     862             :     CPLErr CopyCommonInfoFrom(GDALRasterBand *);
     863             : 
     864             :     virtual void GetFileList(char ***ppapszFileList, int *pnSize,
     865             :                              int *pnMaxSize, CPLHashSet *hSetFiles);
     866             : 
     867             :     virtual void SetDescription(const char *) override;
     868             : 
     869             :     virtual GDALRasterBand *GetMaskBand() override;
     870             :     virtual int GetMaskFlags() override;
     871             : 
     872             :     virtual CPLErr CreateMaskBand(int nFlagsIn) override;
     873             : 
     874             :     void SetMaskBand(VRTRasterBand *poMaskBand);
     875             : 
     876             :     void SetIsMaskBand();
     877             : 
     878             :     virtual bool IsMaskBand() const override;
     879             : 
     880             :     CPLErr UnsetNoDataValue();
     881             : 
     882             :     virtual int CloseDependentDatasets();
     883             : 
     884         118 :     virtual int IsSourcedRasterBand()
     885             :     {
     886         118 :         return FALSE;
     887             :     }
     888             : 
     889           7 :     virtual int IsPansharpenRasterBand()
     890             :     {
     891           7 :         return FALSE;
     892             :     }
     893             : };
     894             : 
     895             : /************************************************************************/
     896             : /*                         VRTSourcedRasterBand                         */
     897             : /************************************************************************/
     898             : 
     899             : class VRTSimpleSource;
     900             : 
     901             : class CPL_DLL VRTSourcedRasterBand CPL_NON_FINAL : public VRTRasterBand
     902             : {
     903             :   private:
     904             :     CPLString m_osLastLocationInfo{};
     905             :     char **m_papszSourceList = nullptr;
     906             :     int m_nSkipBufferInitialization = -1;
     907             : 
     908             :     bool CanUseSourcesMinMaxImplementations();
     909             : 
     910             :     bool IsMosaicOfNonOverlappingSimpleSourcesOfFullRasterNoResAndTypeChange(
     911             :         bool bAllowMaxValAdjustment) const;
     912             : 
     913             :     /** Structure used to declare a threaded job to satisfy IRasterIO()
     914             :      * on a given source.
     915             :      */
     916             :     struct RasterIOJob
     917             :     {
     918             :         std::atomic<int> *pnCompletedJobs = nullptr;
     919             :         std::atomic<bool> *pbSuccess = nullptr;
     920             :         VRTDataset::QueueWorkingStates *poQueueWorkingStates = nullptr;
     921             : 
     922             :         GDALDataType eVRTBandDataType = GDT_Unknown;
     923             :         int nXOff = 0;
     924             :         int nYOff = 0;
     925             :         int nXSize = 0;
     926             :         int nYSize = 0;
     927             :         void *pData = nullptr;
     928             :         int nBufXSize = 0;
     929             :         int nBufYSize = 0;
     930             :         GDALDataType eBufType = GDT_Unknown;
     931             :         GSpacing nPixelSpace = 0;
     932             :         GSpacing nLineSpace = 0;
     933             :         GDALRasterIOExtraArg *psExtraArg = nullptr;
     934             :         VRTSimpleSource *poSource = nullptr;
     935             : 
     936             :         static void Func(void *pData);
     937             :     };
     938             : 
     939             :     CPL_DISALLOW_COPY_ASSIGN(VRTSourcedRasterBand)
     940             : 
     941             :   protected:
     942             :     bool SkipBufferInitialization();
     943             : 
     944             :   public:
     945             :     int nSources = 0;
     946             :     VRTSource **papoSources = nullptr;
     947             : 
     948             :     VRTSourcedRasterBand(GDALDataset *poDS, int nBand);
     949             :     VRTSourcedRasterBand(GDALDataType eType, int nXSize, int nYSize);
     950             :     VRTSourcedRasterBand(GDALDataset *poDS, int nBand, GDALDataType eType,
     951             :                          int nXSize, int nYSize);
     952             :     VRTSourcedRasterBand(GDALDataset *poDS, int nBand, GDALDataType eType,
     953             :                          int nXSize, int nYSize, int nBlockXSizeIn,
     954             :                          int nBlockYSizeIn);
     955             :     virtual ~VRTSourcedRasterBand();
     956             : 
     957             :     virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
     958             :                              GDALDataType, GSpacing nPixelSpace,
     959             :                              GSpacing nLineSpace,
     960             :                              GDALRasterIOExtraArg *psExtraArg) override;
     961             : 
     962             :     virtual int IGetDataCoverageStatus(int nXOff, int nYOff, int nXSize,
     963             :                                        int nYSize, int nMaskFlagStop,
     964             :                                        double *pdfDataPct) override;
     965             : 
     966             :     virtual char **GetMetadataDomainList() override;
     967             :     virtual const char *GetMetadataItem(const char *pszName,
     968             :                                         const char *pszDomain = "") override;
     969             :     virtual char **GetMetadata(const char *pszDomain = "") override;
     970             :     virtual CPLErr SetMetadata(char **papszMetadata,
     971             :                                const char *pszDomain = "") override;
     972             :     virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
     973             :                                    const char *pszDomain = "") override;
     974             : 
     975             :     virtual CPLErr XMLInit(const CPLXMLNode *, const char *,
     976             :                            VRTMapSharedResources &) override;
     977             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath,
     978             :                                        bool &bHasWarnedAboutRAMUsage,
     979             :                                        size_t &nAccRAMUsage) override;
     980             : 
     981             :     virtual double GetMinimum(int *pbSuccess = nullptr) override;
     982             :     virtual double GetMaximum(int *pbSuccess = nullptr) override;
     983             :     virtual CPLErr ComputeRasterMinMax(int bApproxOK,
     984             :                                        double *adfMinMax) override;
     985             :     virtual CPLErr ComputeStatistics(int bApproxOK, double *pdfMin,
     986             :                                      double *pdfMax, double *pdfMean,
     987             :                                      double *pdfStdDev,
     988             :                                      GDALProgressFunc pfnProgress,
     989             :                                      void *pProgressData) override;
     990             :     virtual CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets,
     991             :                                 GUIntBig *panHistogram, int bIncludeOutOfRange,
     992             :                                 int bApproxOK, GDALProgressFunc pfnProgress,
     993             :                                 void *pProgressData) override;
     994             : 
     995             :     CPLErr AddSource(VRTSource *);
     996             : 
     997             :     CPLErr AddSimpleSource(const char *pszFilename, int nBand,
     998             :                            double dfSrcXOff = -1, double dfSrcYOff = -1,
     999             :                            double dfSrcXSize = -1, double dfSrcYSize = -1,
    1000             :                            double dfDstXOff = -1, double dfDstYOff = -1,
    1001             :                            double dfDstXSize = -1, double dfDstYSize = -1,
    1002             :                            const char *pszResampling = "near",
    1003             :                            double dfNoDataValue = VRT_NODATA_UNSET);
    1004             : 
    1005             :     CPLErr AddSimpleSource(GDALRasterBand *poSrcBand, double dfSrcXOff = -1,
    1006             :                            double dfSrcYOff = -1, double dfSrcXSize = -1,
    1007             :                            double dfSrcYSize = -1, double dfDstXOff = -1,
    1008             :                            double dfDstYOff = -1, double dfDstXSize = -1,
    1009             :                            double dfDstYSize = -1,
    1010             :                            const char *pszResampling = "near",
    1011             :                            double dfNoDataValue = VRT_NODATA_UNSET);
    1012             : 
    1013             :     CPLErr AddComplexSource(const char *pszFilename, int nBand,
    1014             :                             double dfSrcXOff = -1, double dfSrcYOff = -1,
    1015             :                             double dfSrcXSize = -1, double dfSrcYSize = -1,
    1016             :                             double dfDstXOff = -1, double dfDstYOff = -1,
    1017             :                             double dfDstXSize = -1, double dfDstYSize = -1,
    1018             :                             double dfScaleOff = 0.0, double dfScaleRatio = 1.0,
    1019             :                             double dfNoDataValue = VRT_NODATA_UNSET,
    1020             :                             int nColorTableComponent = 0);
    1021             : 
    1022             :     CPLErr AddComplexSource(GDALRasterBand *poSrcBand, double dfSrcXOff = -1,
    1023             :                             double dfSrcYOff = -1, double dfSrcXSize = -1,
    1024             :                             double dfSrcYSize = -1, double dfDstXOff = -1,
    1025             :                             double dfDstYOff = -1, double dfDstXSize = -1,
    1026             :                             double dfDstYSize = -1, double dfScaleOff = 0.0,
    1027             :                             double dfScaleRatio = 1.0,
    1028             :                             double dfNoDataValue = VRT_NODATA_UNSET,
    1029             :                             int nColorTableComponent = 0);
    1030             : 
    1031             :     CPLErr AddMaskBandSource(GDALRasterBand *poSrcBand, double dfSrcXOff = -1,
    1032             :                              double dfSrcYOff = -1, double dfSrcXSize = -1,
    1033             :                              double dfSrcYSize = -1, double dfDstXOff = -1,
    1034             :                              double dfDstYOff = -1, double dfDstXSize = -1,
    1035             :                              double dfDstYSize = -1);
    1036             : 
    1037             :     CPLErr AddFuncSource(VRTImageReadFunc pfnReadFunc, void *hCBData,
    1038             :                          double dfNoDataValue = VRT_NODATA_UNSET);
    1039             : 
    1040             :     void ConfigureSource(VRTSimpleSource *poSimpleSource,
    1041             :                          GDALRasterBand *poSrcBand, int bAddAsMaskBand,
    1042             :                          double dfSrcXOff, double dfSrcYOff, double dfSrcXSize,
    1043             :                          double dfSrcYSize, double dfDstXOff, double dfDstYOff,
    1044             :                          double dfDstXSize, double dfDstYSize);
    1045             : 
    1046             :     void RemoveCoveredSources(CSLConstList papszOptions = nullptr);
    1047             : 
    1048             :     bool CanIRasterIOBeForwardedToEachSource(
    1049             :         GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize,
    1050             :         int nBufXSize, int nBufYSize, GDALRasterIOExtraArg *psExtraArg) const;
    1051             : 
    1052             :     bool CanMultiThreadRasterIO(double dfXOff, double dfYOff, double dfXSize,
    1053             :                                 double dfYSize,
    1054             :                                 int &nContributingSources) const;
    1055             : 
    1056             :     virtual CPLErr IReadBlock(int, int, void *) override;
    1057             : 
    1058             :     virtual void GetFileList(char ***ppapszFileList, int *pnSize,
    1059             :                              int *pnMaxSize, CPLHashSet *hSetFiles) override;
    1060             : 
    1061             :     virtual int CloseDependentDatasets() override;
    1062             : 
    1063        7576 :     virtual int IsSourcedRasterBand() override
    1064             :     {
    1065        7576 :         return TRUE;
    1066             :     }
    1067             : 
    1068             :     virtual CPLErr FlushCache(bool bAtClosing) override;
    1069             : };
    1070             : 
    1071             : /************************************************************************/
    1072             : /*                         VRTWarpedRasterBand                          */
    1073             : /************************************************************************/
    1074             : 
    1075             : class CPL_DLL VRTWarpedRasterBand final : public VRTRasterBand
    1076             : {
    1077             :   public:
    1078             :     VRTWarpedRasterBand(GDALDataset *poDS, int nBand,
    1079             :                         GDALDataType eType = GDT_Unknown);
    1080             :     virtual ~VRTWarpedRasterBand();
    1081             : 
    1082             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath,
    1083             :                                        bool &bHasWarnedAboutRAMUsage,
    1084             :                                        size_t &nAccRAMUsage) override;
    1085             : 
    1086             :     virtual CPLErr IReadBlock(int, int, void *) override;
    1087             :     virtual CPLErr IWriteBlock(int, int, void *) override;
    1088             : 
    1089             :     virtual CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
    1090             :                              int nXSize, int nYSize, void *pData, int nBufXSize,
    1091             :                              int nBufYSize, GDALDataType eBufType,
    1092             :                              GSpacing nPixelSpace, GSpacing nLineSpace,
    1093             :                              GDALRasterIOExtraArg *psExtraArg) override;
    1094             : 
    1095             :     virtual int GetOverviewCount() override;
    1096             :     virtual GDALRasterBand *GetOverview(int) override;
    1097             : 
    1098             :   private:
    1099             :     int m_nIRasterIOCounter =
    1100             :         0;  //! Protects against infinite recursion inside IRasterIO()
    1101             : 
    1102             :     int GetBestOverviewLevel(int &nXOff, int &nYOff, int &nXSize, int &nYSize,
    1103             :                              int nBufXSize, int nBufYSize,
    1104             :                              GDALRasterIOExtraArg *psExtraArg) const;
    1105             : };
    1106             : 
    1107             : /************************************************************************/
    1108             : /*                        VRTPansharpenedRasterBand                     */
    1109             : /************************************************************************/
    1110             : 
    1111             : class VRTPansharpenedRasterBand final : public VRTRasterBand
    1112             : {
    1113             :     int m_nIndexAsPansharpenedBand;
    1114             : 
    1115             :   public:
    1116             :     VRTPansharpenedRasterBand(GDALDataset *poDS, int nBand,
    1117             :                               GDALDataType eDataType = GDT_Unknown);
    1118             :     virtual ~VRTPansharpenedRasterBand();
    1119             : 
    1120             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath,
    1121             :                                        bool &bHasWarnedAboutRAMUsage,
    1122             :                                        size_t &nAccRAMUsage) override;
    1123             : 
    1124             :     virtual CPLErr IReadBlock(int, int, void *) override;
    1125             : 
    1126             :     virtual CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
    1127             :                              int nXSize, int nYSize, void *pData, int nBufXSize,
    1128             :                              int nBufYSize, GDALDataType eBufType,
    1129             :                              GSpacing nPixelSpace, GSpacing nLineSpace,
    1130             :                              GDALRasterIOExtraArg *psExtraArg) override;
    1131             : 
    1132             :     virtual int GetOverviewCount() override;
    1133             :     virtual GDALRasterBand *GetOverview(int) override;
    1134             : 
    1135         251 :     virtual int IsPansharpenRasterBand() override
    1136             :     {
    1137         251 :         return TRUE;
    1138             :     }
    1139             : 
    1140          25 :     void SetIndexAsPansharpenedBand(int nIdx)
    1141             :     {
    1142          25 :         m_nIndexAsPansharpenedBand = nIdx;
    1143          25 :     }
    1144             : 
    1145           3 :     int GetIndexAsPansharpenedBand() const
    1146             :     {
    1147           3 :         return m_nIndexAsPansharpenedBand;
    1148             :     }
    1149             : };
    1150             : 
    1151             : /************************************************************************/
    1152             : /*                        VRTProcessedRasterBand                        */
    1153             : /************************************************************************/
    1154             : 
    1155             : class VRTProcessedRasterBand final : public VRTRasterBand
    1156             : {
    1157             :   public:
    1158             :     VRTProcessedRasterBand(VRTProcessedDataset *poDS, int nBand,
    1159             :                            GDALDataType eDataType = GDT_Unknown);
    1160             : 
    1161             :     virtual CPLErr IReadBlock(int, int, void *) override;
    1162             : 
    1163             :     virtual int GetOverviewCount() override;
    1164             :     virtual GDALRasterBand *GetOverview(int) override;
    1165             : 
    1166             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath,
    1167             :                                        bool &bHasWarnedAboutRAMUsage,
    1168             :                                        size_t &nAccRAMUsage) override;
    1169             : };
    1170             : 
    1171             : /************************************************************************/
    1172             : /*                         VRTDerivedRasterBand                         */
    1173             : /************************************************************************/
    1174             : 
    1175             : class VRTDerivedRasterBandPrivateData;
    1176             : 
    1177             : class CPL_DLL VRTDerivedRasterBand CPL_NON_FINAL : public VRTSourcedRasterBand
    1178             : {
    1179             :     VRTDerivedRasterBandPrivateData *m_poPrivate;
    1180             :     bool InitializePython();
    1181             :     CPLErr
    1182             :     GetPixelFunctionArguments(const CPLString &,
    1183             :                               std::vector<std::pair<CPLString, CPLString>> &);
    1184             : 
    1185             :     CPL_DISALLOW_COPY_ASSIGN(VRTDerivedRasterBand)
    1186             : 
    1187             :   public:
    1188             :     char *pszFuncName;
    1189             :     GDALDataType eSourceTransferType;
    1190             : 
    1191             :     using PixelFunc =
    1192             :         std::function<CPLErr(void **, int, void *, int, int, GDALDataType,
    1193             :                              GDALDataType, int, int, CSLConstList)>;
    1194             : 
    1195             :     VRTDerivedRasterBand(GDALDataset *poDS, int nBand);
    1196             :     VRTDerivedRasterBand(GDALDataset *poDS, int nBand, GDALDataType eType,
    1197             :                          int nXSize, int nYSize);
    1198             :     virtual ~VRTDerivedRasterBand();
    1199             : 
    1200             :     virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
    1201             :                              GDALDataType, GSpacing nPixelSpace,
    1202             :                              GSpacing nLineSpace,
    1203             :                              GDALRasterIOExtraArg *psExtraArg) override;
    1204             : 
    1205             :     virtual int IGetDataCoverageStatus(int nXOff, int nYOff, int nXSize,
    1206             :                                        int nYSize, int nMaskFlagStop,
    1207             :                                        double *pdfDataPct) override;
    1208             : 
    1209             :     static CPLErr AddPixelFunction(const char *pszFuncNameIn,
    1210             :                                    GDALDerivedPixelFunc pfnPixelFunc);
    1211             :     static CPLErr AddPixelFunction(const char *pszFuncNameIn,
    1212             :                                    GDALDerivedPixelFuncWithArgs pfnPixelFunc,
    1213             :                                    const char *pszMetadata);
    1214             : 
    1215             :     static const std::pair<PixelFunc, std::string> *
    1216             :     GetPixelFunction(const char *pszFuncNameIn);
    1217             : 
    1218             :     void SetPixelFunctionName(const char *pszFuncNameIn);
    1219             :     void SetSourceTransferType(GDALDataType eDataType);
    1220             :     void SetPixelFunctionLanguage(const char *pszLanguage);
    1221             : 
    1222             :     virtual CPLErr XMLInit(const CPLXMLNode *, const char *,
    1223             :                            VRTMapSharedResources &) override;
    1224             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath,
    1225             :                                        bool &bHasWarnedAboutRAMUsage,
    1226             :                                        size_t &nAccRAMUsage) override;
    1227             : 
    1228             :     virtual double GetMinimum(int *pbSuccess = nullptr) override;
    1229             :     virtual double GetMaximum(int *pbSuccess = nullptr) override;
    1230             :     virtual CPLErr ComputeRasterMinMax(int bApproxOK,
    1231             :                                        double *adfMinMax) override;
    1232             :     virtual CPLErr ComputeStatistics(int bApproxOK, double *pdfMin,
    1233             :                                      double *pdfMax, double *pdfMean,
    1234             :                                      double *pdfStdDev,
    1235             :                                      GDALProgressFunc pfnProgress,
    1236             :                                      void *pProgressData) override;
    1237             :     virtual CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets,
    1238             :                                 GUIntBig *panHistogram, int bIncludeOutOfRange,
    1239             :                                 int bApproxOK, GDALProgressFunc pfnProgress,
    1240             :                                 void *pProgressData) override;
    1241             : 
    1242             :     static void Cleanup();
    1243             : };
    1244             : 
    1245             : /************************************************************************/
    1246             : /*                           VRTRawRasterBand                           */
    1247             : /************************************************************************/
    1248             : 
    1249             : class RawRasterBand;
    1250             : 
    1251             : class CPL_DLL VRTRawRasterBand CPL_NON_FINAL : public VRTRasterBand
    1252             : {
    1253             :     RawRasterBand *m_poRawRaster;
    1254             : 
    1255             :     char *m_pszSourceFilename;
    1256             :     int m_bRelativeToVRT;
    1257             : 
    1258             :     CPL_DISALLOW_COPY_ASSIGN(VRTRawRasterBand)
    1259             : 
    1260             :   public:
    1261             :     VRTRawRasterBand(GDALDataset *poDS, int nBand,
    1262             :                      GDALDataType eType = GDT_Unknown);
    1263             :     virtual ~VRTRawRasterBand();
    1264             : 
    1265             :     virtual CPLErr XMLInit(const CPLXMLNode *, const char *,
    1266             :                            VRTMapSharedResources &) override;
    1267             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath,
    1268             :                                        bool &bHasWarnedAboutRAMUsage,
    1269             :                                        size_t &nAccRAMUsage) override;
    1270             : 
    1271             :     virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
    1272             :                              GDALDataType, GSpacing nPixelSpace,
    1273             :                              GSpacing nLineSpace,
    1274             :                              GDALRasterIOExtraArg *psExtraArg) override;
    1275             : 
    1276             :     virtual CPLErr IReadBlock(int, int, void *) override;
    1277             :     virtual CPLErr IWriteBlock(int, int, void *) override;
    1278             : 
    1279             :     CPLErr SetRawLink(const char *pszFilename, const char *pszVRTPath,
    1280             :                       int bRelativeToVRT, vsi_l_offset nImageOffset,
    1281             :                       int nPixelOffset, int nLineOffset,
    1282             :                       const char *pszByteOrder);
    1283             : 
    1284             :     void ClearRawLink();
    1285             : 
    1286             :     CPLVirtualMem *GetVirtualMemAuto(GDALRWFlag eRWFlag, int *pnPixelSpace,
    1287             :                                      GIntBig *pnLineSpace,
    1288             :                                      char **papszOptions) override;
    1289             : 
    1290             :     virtual void GetFileList(char ***ppapszFileList, int *pnSize,
    1291             :                              int *pnMaxSize, CPLHashSet *hSetFiles) override;
    1292             : };
    1293             : 
    1294             : /************************************************************************/
    1295             : /*                              VRTDriver                               */
    1296             : /************************************************************************/
    1297             : 
    1298             : class VRTDriver final : public GDALDriver
    1299             : {
    1300             :     CPL_DISALLOW_COPY_ASSIGN(VRTDriver)
    1301             : 
    1302             :     std::map<std::string, VRTSourceParser> m_oMapSourceParser{};
    1303             : 
    1304             :   public:
    1305             :     VRTDriver();
    1306             :     virtual ~VRTDriver();
    1307             : 
    1308             :     char **papszSourceParsers;
    1309             : 
    1310             :     virtual char **GetMetadataDomainList() override;
    1311             :     virtual char **GetMetadata(const char *pszDomain = "") override;
    1312             :     virtual CPLErr SetMetadata(char **papszMetadata,
    1313             :                                const char *pszDomain = "") override;
    1314             : 
    1315             :     VRTSource *ParseSource(const CPLXMLNode *psSrc, const char *pszVRTPath,
    1316             :                            VRTMapSharedResources &oMapSharedSources);
    1317             :     void AddSourceParser(const char *pszElementName, VRTSourceParser pfnParser);
    1318             : };
    1319             : 
    1320             : /************************************************************************/
    1321             : /*                           VRTSimpleSource                            */
    1322             : /************************************************************************/
    1323             : 
    1324       13075 : class CPL_DLL VRTSimpleSource CPL_NON_FINAL : public VRTSource
    1325             : {
    1326             :     CPL_DISALLOW_COPY_ASSIGN(VRTSimpleSource)
    1327             : 
    1328             :   private:
    1329             :     // Owned by the VRTDataset
    1330             :     VRTMapSharedResources *m_poMapSharedSources = nullptr;
    1331             : 
    1332             :     mutable GDALRasterBand *m_poRasterBand = nullptr;
    1333             : 
    1334             :     // When poRasterBand is a mask band, poMaskBandMainBand is the band
    1335             :     // from which the mask band is taken.
    1336             :     mutable GDALRasterBand *m_poMaskBandMainBand = nullptr;
    1337             : 
    1338             :     CPLStringList m_aosOpenOptionsOri{};  // as read in the original source XML
    1339             :     CPLStringList
    1340             :         m_aosOpenOptions{};  // same as above, but potentially augmented with ROOT_PATH
    1341             :     bool m_bSrcDSNameFromVRT =
    1342             :         false;  // whereas content in m_osSrcDSName is a <VRTDataset> XML node
    1343             : 
    1344             :     void OpenSource() const;
    1345             : 
    1346             :   protected:
    1347             :     friend class VRTSourcedRasterBand;
    1348             :     friend class VRTDataset;
    1349             :     friend class GDALTileIndexDataset;
    1350             :     friend class GDALTileIndexBand;
    1351             : 
    1352             :     int m_nBand = 0;
    1353             :     bool m_bGetMaskBand = false;
    1354             : 
    1355             :     /* Value for uninitialized source or destination window. It is chosen such
    1356             :      * that SrcToDst() and DstToSrc() are no-ops if both source and destination
    1357             :      * windows are unset.
    1358             :      */
    1359             :     static constexpr double UNINIT_WINDOW = -1.0;
    1360             : 
    1361             :     double m_dfSrcXOff = UNINIT_WINDOW;
    1362             :     double m_dfSrcYOff = UNINIT_WINDOW;
    1363             :     double m_dfSrcXSize = UNINIT_WINDOW;
    1364             :     double m_dfSrcYSize = UNINIT_WINDOW;
    1365             : 
    1366             :     double m_dfDstXOff = UNINIT_WINDOW;
    1367             :     double m_dfDstYOff = UNINIT_WINDOW;
    1368             :     double m_dfDstXSize = UNINIT_WINDOW;
    1369             :     double m_dfDstYSize = UNINIT_WINDOW;
    1370             : 
    1371             :     CPLString m_osResampling{};
    1372             : 
    1373             :     int m_nMaxValue = 0;
    1374             : 
    1375             :     int m_bRelativeToVRTOri = -1;
    1376             :     CPLString m_osSourceFileNameOri{};
    1377             :     int m_nExplicitSharedStatus = -1;  // -1 unknown, 0 = unshared, 1 = shared
    1378             :     CPLString m_osSrcDSName{};
    1379             : 
    1380             :     bool m_bDropRefOnSrcBand = true;
    1381             : 
    1382             :     int NeedMaxValAdjustment() const;
    1383             : 
    1384           3 :     GDALRasterBand *GetRasterBandNoOpen() const
    1385             :     {
    1386           3 :         return m_poRasterBand;
    1387             :     }
    1388             : 
    1389         461 :     void SetRasterBand(GDALRasterBand *poBand, bool bDropRef)
    1390             :     {
    1391         461 :         m_poRasterBand = poBand;
    1392         461 :         m_bDropRefOnSrcBand = bDropRef;
    1393         461 :     }
    1394             : 
    1395         962 :     virtual bool ValidateOpenedBand(GDALRasterBand * /*poBand*/) const
    1396             :     {
    1397         962 :         return true;
    1398             :     }
    1399             : 
    1400             :     /** Returns whether the source window is set */
    1401       72230 :     bool IsSrcWinSet() const
    1402             :     {
    1403         301 :         return m_dfSrcXOff != UNINIT_WINDOW || m_dfSrcYOff != UNINIT_WINDOW ||
    1404       72531 :                m_dfSrcXSize != UNINIT_WINDOW || m_dfSrcYSize != UNINIT_WINDOW;
    1405             :     }
    1406             : 
    1407             :     /** Returns whether the destination window is set */
    1408       73303 :     bool IsDstWinSet() const
    1409             :     {
    1410         310 :         return m_dfDstXOff != UNINIT_WINDOW || m_dfDstYOff != UNINIT_WINDOW ||
    1411       73613 :                m_dfDstXSize != UNINIT_WINDOW || m_dfDstYSize != UNINIT_WINDOW;
    1412             :     }
    1413             : 
    1414             :     void AddSourceFilenameNode(const char *pszVRTPath, CPLXMLNode *psSrc);
    1415             : 
    1416             :   public:
    1417             :     VRTSimpleSource();
    1418             :     VRTSimpleSource(const VRTSimpleSource *poSrcSource, double dfXDstRatio,
    1419             :                     double dfYDstRatio);
    1420             :     virtual ~VRTSimpleSource();
    1421             : 
    1422             :     virtual CPLErr XMLInit(const CPLXMLNode *psTree, const char *,
    1423             :                            VRTMapSharedResources &) override;
    1424             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
    1425             : 
    1426             :     CPLErr ParseSrcRectAndDstRect(const CPLXMLNode *psSrc);
    1427             : 
    1428             :     void SetSrcBand(const char *pszFilename, int nBand);
    1429             :     void SetSrcBand(GDALRasterBand *);
    1430             :     void SetSrcMaskBand(GDALRasterBand *);
    1431             :     void SetSrcWindow(double, double, double, double);
    1432             :     void SetDstWindow(double, double, double, double);
    1433             :     void GetDstWindow(double &, double &, double &, double &) const;
    1434             :     bool DstWindowIntersects(double dfXOff, double dfYOff, double dfXSize,
    1435             :                              double dfYSize) const;
    1436             : 
    1437           3 :     const std::string &GetSourceDatasetName() const
    1438             :     {
    1439           3 :         return m_osSrcDSName;
    1440             :     }
    1441             : 
    1442        1918 :     const CPLString &GetResampling() const
    1443             :     {
    1444        1918 :         return m_osResampling;
    1445             :     }
    1446             : 
    1447             :     void SetResampling(const char *pszResampling);
    1448             : 
    1449             :     int GetSrcDstWindow(double, double, double, double, int, int,
    1450             :                         double *pdfReqXOff, double *pdfReqYOff,
    1451             :                         double *pdfReqXSize, double *pdfReqYSize, int *, int *,
    1452             :                         int *, int *, int *, int *, int *, int *,
    1453             :                         bool &bErrorOut);
    1454             : 
    1455             :     virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
    1456             :                             int nXSize, int nYSize, void *pData, int nBufXSize,
    1457             :                             int nBufYSize, GDALDataType eBufType,
    1458             :                             GSpacing nPixelSpace, GSpacing nLineSpace,
    1459             :                             GDALRasterIOExtraArg *psExtraArgIn,
    1460             :                             WorkingState &oWorkingState) override;
    1461             : 
    1462             :     virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
    1463             :     virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
    1464             :     virtual CPLErr GetHistogram(int nXSize, int nYSize, double dfMin,
    1465             :                                 double dfMax, int nBuckets,
    1466             :                                 GUIntBig *panHistogram, int bIncludeOutOfRange,
    1467             :                                 int bApproxOK, GDALProgressFunc pfnProgress,
    1468             :                                 void *pProgressData) override;
    1469             : 
    1470             :     void DstToSrc(double dfX, double dfY, double &dfXOut, double &dfYOut) const;
    1471             :     void SrcToDst(double dfX, double dfY, double &dfXOut, double &dfYOut) const;
    1472             : 
    1473             :     virtual void GetFileList(char ***ppapszFileList, int *pnSize,
    1474             :                              int *pnMaxSize, CPLHashSet *hSetFiles) override;
    1475             : 
    1476       24542 :     bool IsSimpleSource() const override
    1477             :     {
    1478       24542 :         return true;
    1479             :     }
    1480             : 
    1481             :     /** Returns the same value as GetType() called on objects that are exactly
    1482             :      * instances of VRTSimpleSource.
    1483             :      */
    1484             :     static const char *GetTypeStatic();
    1485             : 
    1486             :     const char *GetType() const override;
    1487             : 
    1488             :     virtual CPLErr FlushCache(bool bAtClosing) override;
    1489             : 
    1490             :     GDALRasterBand *GetRasterBand() const;
    1491             :     GDALRasterBand *GetMaskBandMainBand();
    1492             :     bool IsSameExceptBandNumber(const VRTSimpleSource *poOtherSource) const;
    1493             :     CPLErr DatasetRasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
    1494             :                            int nXSize, int nYSize, void *pData, int nBufXSize,
    1495             :                            int nBufYSize, GDALDataType eBufType, int nBandCount,
    1496             :                            const int *panBandMap, GSpacing nPixelSpace,
    1497             :                            GSpacing nLineSpace, GSpacing nBandSpace,
    1498             :                            GDALRasterIOExtraArg *psExtraArg);
    1499             : 
    1500             :     void UnsetPreservedRelativeFilenames();
    1501             : 
    1502          47 :     void SetMaxValue(int nVal)
    1503             :     {
    1504          47 :         m_nMaxValue = nVal;
    1505          47 :     }
    1506             : };
    1507             : 
    1508             : /************************************************************************/
    1509             : /*                          VRTAveragedSource                           */
    1510             : /************************************************************************/
    1511             : 
    1512             : class VRTAveragedSource final : public VRTSimpleSource
    1513             : {
    1514             :     CPL_DISALLOW_COPY_ASSIGN(VRTAveragedSource)
    1515             : 
    1516             :     int m_bNoDataSet = false;
    1517             :     double m_dfNoDataValue = VRT_NODATA_UNSET;
    1518             : 
    1519             :   public:
    1520             :     VRTAveragedSource();
    1521             :     virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
    1522             :                             int nXSize, int nYSize, void *pData, int nBufXSize,
    1523             :                             int nBufYSize, GDALDataType eBufType,
    1524             :                             GSpacing nPixelSpace, GSpacing nLineSpace,
    1525             :                             GDALRasterIOExtraArg *psExtraArgIn,
    1526             :                             WorkingState &oWorkingState) override;
    1527             : 
    1528             :     virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
    1529             :     virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
    1530             :     virtual CPLErr GetHistogram(int nXSize, int nYSize, double dfMin,
    1531             :                                 double dfMax, int nBuckets,
    1532             :                                 GUIntBig *panHistogram, int bIncludeOutOfRange,
    1533             :                                 int bApproxOK, GDALProgressFunc pfnProgress,
    1534             :                                 void *pProgressData) override;
    1535             : 
    1536             :     void SetNoDataValue(double dfNoDataValue);
    1537             : 
    1538             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
    1539             : 
    1540             :     /** Returns the same value as GetType() called on objects that are exactly
    1541             :      * instances of VRTAveragedSource.
    1542             :      */
    1543             :     static const char *GetTypeStatic();
    1544             : 
    1545             :     const char *GetType() const override;
    1546             : };
    1547             : 
    1548             : /************************************************************************/
    1549             : /*                       VRTNoDataFromMaskSource                        */
    1550             : /************************************************************************/
    1551             : 
    1552             : class VRTNoDataFromMaskSource final : public VRTSimpleSource
    1553             : {
    1554             :     CPL_DISALLOW_COPY_ASSIGN(VRTNoDataFromMaskSource)
    1555             : 
    1556             :     bool m_bNoDataSet = false;
    1557             :     double m_dfNoDataValue = 0;
    1558             :     double m_dfMaskValueThreshold = 0;
    1559             :     bool m_bHasRemappedValue = false;
    1560             :     double m_dfRemappedValue = 0;
    1561             : 
    1562             :   public:
    1563             :     VRTNoDataFromMaskSource();
    1564             :     virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
    1565             :                             int nXSize, int nYSize, void *pData, int nBufXSize,
    1566             :                             int nBufYSize, GDALDataType eBufType,
    1567             :                             GSpacing nPixelSpace, GSpacing nLineSpace,
    1568             :                             GDALRasterIOExtraArg *psExtraArgIn,
    1569             :                             WorkingState &oWorkingState) override;
    1570             : 
    1571             :     virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
    1572             :     virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
    1573             :     virtual CPLErr GetHistogram(int nXSize, int nYSize, double dfMin,
    1574             :                                 double dfMax, int nBuckets,
    1575             :                                 GUIntBig *panHistogram, int bIncludeOutOfRange,
    1576             :                                 int bApproxOK, GDALProgressFunc pfnProgress,
    1577             :                                 void *pProgressData) override;
    1578             : 
    1579             :     void SetParameters(double dfNoDataValue, double dfMaskValueThreshold);
    1580             :     void SetParameters(double dfNoDataValue, double dfMaskValueThreshold,
    1581             :                        double dfRemappedValue);
    1582             : 
    1583             :     virtual CPLErr XMLInit(const CPLXMLNode *psTree, const char *,
    1584             :                            VRTMapSharedResources &) override;
    1585             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
    1586             : 
    1587             :     /** Returns the same value as GetType() called on objects that are exactly
    1588             :      * instances of VRTNoDataFromMaskSource.
    1589             :      */
    1590             :     static const char *GetTypeStatic();
    1591             : 
    1592             :     const char *GetType() const override;
    1593             : };
    1594             : 
    1595             : /************************************************************************/
    1596             : /*                           VRTComplexSource                           */
    1597             : /************************************************************************/
    1598             : 
    1599             : class CPL_DLL VRTComplexSource CPL_NON_FINAL : public VRTSimpleSource
    1600             : {
    1601             :     CPL_DISALLOW_COPY_ASSIGN(VRTComplexSource)
    1602             : 
    1603             :   protected:
    1604             :     static constexpr int PROCESSING_FLAG_NODATA = 1 << 0;
    1605             :     static constexpr int PROCESSING_FLAG_USE_MASK_BAND =
    1606             :         1 << 1;  // Mutually exclusive with NODATA
    1607             :     static constexpr int PROCESSING_FLAG_SCALING_LINEAR = 1 << 2;
    1608             :     static constexpr int PROCESSING_FLAG_SCALING_EXPONENTIAL =
    1609             :         1 << 3;  // Mutually exclusive with SCALING_LINEAR
    1610             :     static constexpr int PROCESSING_FLAG_COLOR_TABLE_EXPANSION = 1 << 4;
    1611             :     static constexpr int PROCESSING_FLAG_LUT = 1 << 5;
    1612             : 
    1613             :     int m_nProcessingFlags = 0;
    1614             : 
    1615             :     // adjusted value should be read with GetAdjustedNoDataValue()
    1616             :     double m_dfNoDataValue = VRT_NODATA_UNSET;
    1617             :     std::string
    1618             :         m_osNoDataValueOri{};  // string value read in XML deserialization
    1619             : 
    1620             :     double m_dfScaleOff = 0;    // For linear scaling.
    1621             :     double m_dfScaleRatio = 1;  // For linear scaling.
    1622             : 
    1623             :     // For non-linear scaling with a power function.
    1624             :     bool m_bSrcMinMaxDefined = false;
    1625             :     double m_dfSrcMin = 0;
    1626             :     double m_dfSrcMax = 0;
    1627             :     double m_dfDstMin = 0;
    1628             :     double m_dfDstMax = 0;
    1629             :     double m_dfExponent = 1;
    1630             : 
    1631             :     int m_nColorTableComponent = 0;
    1632             : 
    1633             :     std::vector<double> m_adfLUTInputs{};
    1634             :     std::vector<double> m_adfLUTOutputs{};
    1635             : 
    1636             :     double GetAdjustedNoDataValue() const;
    1637             : 
    1638             :     template <class WorkingDT>
    1639             :     CPLErr
    1640             :     RasterIOInternal(GDALRasterBand *poSourceBand,
    1641             :                      GDALDataType eVRTBandDataType, int nReqXOff, int nReqYOff,
    1642             :                      int nReqXSize, int nReqYSize, void *pData, int nOutXSize,
    1643             :                      int nOutYSize, GDALDataType eBufType, GSpacing nPixelSpace,
    1644             :                      GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg,
    1645             :                      GDALDataType eWrkDataType, WorkingState &oWorkingState);
    1646             : 
    1647             :     template <class SourceDT, GDALDataType eSourceType>
    1648             :     CPLErr RasterIOProcessNoData(GDALRasterBand *poSourceBand,
    1649             :                                  GDALDataType eVRTBandDataType, int nReqXOff,
    1650             :                                  int nReqYOff, int nReqXSize, int nReqYSize,
    1651             :                                  void *pData, int nOutXSize, int nOutYSize,
    1652             :                                  GDALDataType eBufType, GSpacing nPixelSpace,
    1653             :                                  GSpacing nLineSpace,
    1654             :                                  GDALRasterIOExtraArg *psExtraArg,
    1655             :                                  WorkingState &oWorkingState);
    1656             : 
    1657             :   public:
    1658         464 :     VRTComplexSource() = default;
    1659             :     VRTComplexSource(const VRTComplexSource *poSrcSource, double dfXDstRatio,
    1660             :                      double dfYDstRatio);
    1661             : 
    1662             :     virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
    1663             :                             int nXSize, int nYSize, void *pData, int nBufXSize,
    1664             :                             int nBufYSize, GDALDataType eBufType,
    1665             :                             GSpacing nPixelSpace, GSpacing nLineSpace,
    1666             :                             GDALRasterIOExtraArg *psExtraArgIn,
    1667             :                             WorkingState &oWorkingState) override;
    1668             : 
    1669             :     virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
    1670             :     virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
    1671             :     virtual CPLErr GetHistogram(int nXSize, int nYSize, double dfMin,
    1672             :                                 double dfMax, int nBuckets,
    1673             :                                 GUIntBig *panHistogram, int bIncludeOutOfRange,
    1674             :                                 int bApproxOK, GDALProgressFunc pfnProgress,
    1675             :                                 void *pProgressData) override;
    1676             : 
    1677             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
    1678             :     virtual CPLErr XMLInit(const CPLXMLNode *, const char *,
    1679             :                            VRTMapSharedResources &) override;
    1680             : 
    1681             :     /** Returns the same value as GetType() called on objects that are exactly
    1682             :      * instances of VRTComplexSource.
    1683             :      */
    1684             :     static const char *GetTypeStatic();
    1685             : 
    1686             :     const char *GetType() const override;
    1687             : 
    1688             :     bool AreValuesUnchanged() const;
    1689             : 
    1690             :     double LookupValue(double dfInput);
    1691             : 
    1692             :     void SetNoDataValue(double dfNoDataValue);
    1693             : 
    1694          54 :     void SetUseMaskBand(bool bUseMaskBand)
    1695             :     {
    1696          54 :         if (bUseMaskBand)
    1697          54 :             m_nProcessingFlags |= PROCESSING_FLAG_USE_MASK_BAND;
    1698             :         else
    1699           0 :             m_nProcessingFlags &= ~PROCESSING_FLAG_USE_MASK_BAND;
    1700          54 :     }
    1701             : 
    1702             :     void SetLinearScaling(double dfOffset, double dfScale);
    1703             :     void SetPowerScaling(double dfExponent, double dfSrcMin, double dfSrcMax,
    1704             :                          double dfDstMin, double dfDstMax);
    1705             :     void SetColorTableComponent(int nComponent);
    1706             : };
    1707             : 
    1708             : /************************************************************************/
    1709             : /*                           VRTFilteredSource                          */
    1710             : /************************************************************************/
    1711             : 
    1712             : class VRTFilteredSource CPL_NON_FINAL : public VRTComplexSource
    1713             : {
    1714             :   private:
    1715             :     int IsTypeSupported(GDALDataType eTestType) const;
    1716             : 
    1717             :     CPL_DISALLOW_COPY_ASSIGN(VRTFilteredSource)
    1718             : 
    1719             :   protected:
    1720             :     int m_nSupportedTypesCount;
    1721             :     GDALDataType m_aeSupportedTypes[20];
    1722             : 
    1723             :     int m_nExtraEdgePixels;
    1724             : 
    1725             :   public:
    1726             :     VRTFilteredSource();
    1727             :     virtual ~VRTFilteredSource();
    1728             : 
    1729             :     const char *GetType() const override = 0;
    1730             : 
    1731             :     void SetExtraEdgePixels(int);
    1732             :     void SetFilteringDataTypesSupported(int, GDALDataType *);
    1733             : 
    1734             :     virtual CPLErr FilterData(int nXSize, int nYSize, GDALDataType eType,
    1735             :                               GByte *pabySrcData, GByte *pabyDstData) = 0;
    1736             : 
    1737             :     virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
    1738             :                             int nXSize, int nYSize, void *pData, int nBufXSize,
    1739             :                             int nBufYSize, GDALDataType eBufType,
    1740             :                             GSpacing nPixelSpace, GSpacing nLineSpace,
    1741             :                             GDALRasterIOExtraArg *psExtraArg,
    1742             :                             WorkingState &oWorkingState) override;
    1743             : };
    1744             : 
    1745             : /************************************************************************/
    1746             : /*                       VRTKernelFilteredSource                        */
    1747             : /************************************************************************/
    1748             : 
    1749             : class VRTKernelFilteredSource CPL_NON_FINAL : public VRTFilteredSource
    1750             : {
    1751             :     CPL_DISALLOW_COPY_ASSIGN(VRTKernelFilteredSource)
    1752             : 
    1753             :   protected:
    1754             :     int m_nKernelSize = 0;
    1755             :     bool m_bSeparable = false;
    1756             :     // m_nKernelSize elements if m_bSeparable, m_nKernelSize * m_nKernelSize otherwise
    1757             :     std::vector<double> m_adfKernelCoefs{};
    1758             :     bool m_bNormalized = false;
    1759             : 
    1760             :   public:
    1761             :     VRTKernelFilteredSource();
    1762             : 
    1763             :     const char *GetType() const override;
    1764             : 
    1765             :     virtual CPLErr XMLInit(const CPLXMLNode *psTree, const char *,
    1766             :                            VRTMapSharedResources &) override;
    1767             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
    1768             : 
    1769             :     virtual CPLErr FilterData(int nXSize, int nYSize, GDALDataType eType,
    1770             :                               GByte *pabySrcData, GByte *pabyDstData) override;
    1771             : 
    1772             :     CPLErr SetKernel(int nKernelSize, bool bSeparable,
    1773             :                      const std::vector<double> &adfNewCoefs);
    1774             :     void SetNormalized(bool);
    1775             : };
    1776             : 
    1777             : /************************************************************************/
    1778             : /*                       VRTAverageFilteredSource                       */
    1779             : /************************************************************************/
    1780             : 
    1781             : class VRTAverageFilteredSource final : public VRTKernelFilteredSource
    1782             : {
    1783             :     CPL_DISALLOW_COPY_ASSIGN(VRTAverageFilteredSource)
    1784             : 
    1785             :   public:
    1786             :     explicit VRTAverageFilteredSource(int nKernelSize);
    1787             :     virtual ~VRTAverageFilteredSource();
    1788             : 
    1789             :     const char *GetType() const override;
    1790             : 
    1791             :     virtual CPLErr XMLInit(const CPLXMLNode *psTree, const char *,
    1792             :                            VRTMapSharedResources &) override;
    1793             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
    1794             : };
    1795             : 
    1796             : /************************************************************************/
    1797             : /*                            VRTFuncSource                             */
    1798             : /************************************************************************/
    1799             : class VRTFuncSource final : public VRTSource
    1800             : {
    1801             :     CPL_DISALLOW_COPY_ASSIGN(VRTFuncSource)
    1802             : 
    1803             :   public:
    1804             :     VRTFuncSource();
    1805             :     virtual ~VRTFuncSource();
    1806             : 
    1807           0 :     virtual CPLErr XMLInit(const CPLXMLNode *, const char *,
    1808             :                            VRTMapSharedResources &) override
    1809             :     {
    1810           0 :         return CE_Failure;
    1811             :     }
    1812             : 
    1813             :     virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
    1814             : 
    1815             :     virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
    1816             :                             int nXSize, int nYSize, void *pData, int nBufXSize,
    1817             :                             int nBufYSize, GDALDataType eBufType,
    1818             :                             GSpacing nPixelSpace, GSpacing nLineSpace,
    1819             :                             GDALRasterIOExtraArg *psExtraArg,
    1820             :                             WorkingState &oWorkingState) override;
    1821             : 
    1822             :     virtual double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
    1823             :     virtual double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
    1824             :     virtual CPLErr GetHistogram(int nXSize, int nYSize, double dfMin,
    1825             :                                 double dfMax, int nBuckets,
    1826             :                                 GUIntBig *panHistogram, int bIncludeOutOfRange,
    1827             :                                 int bApproxOK, GDALProgressFunc pfnProgress,
    1828             :                                 void *pProgressData) override;
    1829             : 
    1830             :     const char *GetType() const override;
    1831             : 
    1832             :     VRTImageReadFunc pfnReadFunc;
    1833             :     void *pCBData;
    1834             :     GDALDataType eType;
    1835             : 
    1836             :     float fNoDataValue;
    1837             : };
    1838             : 
    1839             : /************************************************************************/
    1840             : /*                              VRTGroup                                */
    1841             : /************************************************************************/
    1842             : 
    1843             : #ifdef TMPEXPORT
    1844             : #define TMP_CPL_DLL CPL_DLL
    1845             : #else
    1846             : #define TMP_CPL_DLL
    1847             : #endif
    1848             : 
    1849             : class VRTMDArray;
    1850             : class VRTAttribute;
    1851             : class VRTDimension;
    1852             : 
    1853             : class VRTGroup final : public GDALGroup
    1854             : {
    1855             :   public:
    1856             :     struct Ref
    1857             :     {
    1858             :         VRTGroup *m_ptr;
    1859             : 
    1860         847 :         explicit Ref(VRTGroup *ptr) : m_ptr(ptr)
    1861             :         {
    1862         847 :         }
    1863             : 
    1864             :         Ref(const Ref &) = delete;
    1865             :         Ref &operator=(const Ref &) = delete;
    1866             :     };
    1867             : 
    1868             :   private:
    1869             :     std::shared_ptr<Ref> m_poSharedRefRootGroup{};
    1870             :     std::weak_ptr<Ref> m_poWeakRefRootGroup{};
    1871             :     std::shared_ptr<Ref> m_poRefSelf{};
    1872             : 
    1873             :     std::string m_osFilename{};
    1874             :     mutable bool m_bDirty = false;
    1875             :     std::string m_osVRTPath{};
    1876             :     std::map<std::string, std::shared_ptr<VRTGroup>> m_oMapGroups{};
    1877             :     std::map<std::string, std::shared_ptr<VRTMDArray>> m_oMapMDArrays{};
    1878             :     std::map<std::string, std::shared_ptr<VRTAttribute>> m_oMapAttributes{};
    1879             :     std::map<std::string, std::shared_ptr<VRTDimension>> m_oMapDimensions{};
    1880             : 
    1881             :     std::shared_ptr<VRTGroup>
    1882             :     OpenGroupInternal(const std::string &osName) const;
    1883             :     void SetRootGroupRef(const std::weak_ptr<Ref> &rgRef);
    1884             :     std::weak_ptr<Ref> GetRootGroupRef() const;
    1885             : 
    1886             :   protected:
    1887             :     friend class VRTMDArray;
    1888             :     friend std::shared_ptr<GDALMDArray>
    1889             :     VRTDerivedArrayCreate(const char *pszVRTPath, const CPLXMLNode *psTree);
    1890             : 
    1891             :     explicit VRTGroup(const char *pszVRTPath);
    1892             :     VRTGroup(const std::string &osParentName, const std::string &osName);
    1893             : 
    1894             :   public:
    1895         531 :     static std::shared_ptr<VRTGroup> Create(const std::string &osParentName,
    1896             :                                             const std::string &osName)
    1897             :     {
    1898             :         auto poGroup =
    1899         531 :             std::shared_ptr<VRTGroup>(new VRTGroup(osParentName, osName));
    1900         531 :         poGroup->SetSelf(poGroup);
    1901         531 :         return poGroup;
    1902             :     }
    1903             : 
    1904             :     ~VRTGroup();
    1905             : 
    1906             :     bool XMLInit(const std::shared_ptr<VRTGroup> &poRoot,
    1907             :                  const std::shared_ptr<VRTGroup> &poThisGroup,
    1908             :                  const CPLXMLNode *psNode, const char *pszVRTPath);
    1909             : 
    1910             :     std::vector<std::string>
    1911             :     GetMDArrayNames(CSLConstList papszOptions) const override;
    1912             :     std::shared_ptr<GDALMDArray>
    1913             :     OpenMDArray(const std::string &osName,
    1914             :                 CSLConstList papszOptions = nullptr) const override;
    1915             : 
    1916             :     std::vector<std::string>
    1917             :     GetGroupNames(CSLConstList papszOptions) const override;
    1918             : 
    1919          24 :     std::shared_ptr<GDALGroup> OpenGroup(const std::string &osName,
    1920             :                                          CSLConstList) const override
    1921             :     {
    1922          24 :         return OpenGroupInternal(osName);
    1923             :     }
    1924             : 
    1925             :     std::vector<std::shared_ptr<GDALDimension>>
    1926             :         GetDimensions(CSLConstList) const override;
    1927             : 
    1928             :     std::vector<std::shared_ptr<GDALAttribute>>
    1929             :         GetAttributes(CSLConstList) const override;
    1930             : 
    1931        1646 :     std::shared_ptr<VRTDimension> GetDimension(const std::string &name) const
    1932             :     {
    1933        1646 :         auto oIter = m_oMapDimensions.find(name);
    1934        3292 :         return oIter == m_oMapDimensions.end() ? nullptr : oIter->second;
    1935             :     }
    1936             : 
    1937             :     std::shared_ptr<VRTDimension>
    1938             :     GetDimensionFromFullName(const std::string &name, bool bEmitError) const;
    1939             : 
    1940             :     std::shared_ptr<GDALGroup>
    1941             :     CreateGroup(const std::string &osName,
    1942             :                 CSLConstList papszOptions = nullptr) override;
    1943             : 
    1944             :     std::shared_ptr<GDALDimension>
    1945             :     CreateDimension(const std::string &osName, const std::string &osType,
    1946             :                     const std::string &osDirection, GUInt64 nSize,
    1947             :                     CSLConstList papszOptions = nullptr) override;
    1948             : 
    1949             :     std::shared_ptr<GDALAttribute>
    1950             :     CreateAttribute(const std::string &osName,
    1951             :                     const std::vector<GUInt64> &anDimensions,
    1952             :                     const GDALExtendedDataType &oDataType,
    1953             :                     CSLConstList papszOptions = nullptr) override;
    1954             : 
    1955             :     std::shared_ptr<GDALMDArray> CreateMDArray(
    1956             :         const std::string &osName,
    1957             :         const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
    1958             :         const GDALExtendedDataType &oDataType,
    1959             :         CSLConstList papszOptions) override;
    1960             : 
    1961             :     void SetIsRootGroup();
    1962             : 
    1963        1591 :     const std::shared_ptr<Ref> &GetRef() const
    1964             :     {
    1965        1591 :         return m_poRefSelf;
    1966             :     }
    1967             : 
    1968             :     VRTGroup *GetRootGroup() const;
    1969             :     std::shared_ptr<GDALGroup> GetRootGroupSharedPtr() const;
    1970             : 
    1971         979 :     const std::string &GetVRTPath() const
    1972             :     {
    1973         979 :         return m_osVRTPath;
    1974             :     }
    1975             : 
    1976             :     void SetDirty();
    1977             : 
    1978         172 :     void SetFilename(const std::string &osFilename)
    1979             :     {
    1980         172 :         m_osFilename = osFilename;
    1981         172 :     }
    1982             : 
    1983         979 :     const std::string &GetFilename() const
    1984             :     {
    1985         979 :         return m_osFilename;
    1986             :     }
    1987             : 
    1988             :     bool Serialize() const;
    1989             :     CPLXMLNode *SerializeToXML(const char *pszVRTPathIn) const;
    1990             :     void Serialize(CPLXMLNode *psParent, const char *pszVRTPathIn) const;
    1991             : };
    1992             : 
    1993             : /************************************************************************/
    1994             : /*                            VRTDimension                              */
    1995             : /************************************************************************/
    1996             : 
    1997             : class VRTDimension final : public GDALDimension
    1998             : {
    1999             :     std::weak_ptr<VRTGroup::Ref> m_poGroupRef;
    2000             :     std::string m_osIndexingVariableName;
    2001             : 
    2002             :   public:
    2003         612 :     VRTDimension(const std::shared_ptr<VRTGroup::Ref> &poGroupRef,
    2004             :                  const std::string &osParentName, const std::string &osName,
    2005             :                  const std::string &osType, const std::string &osDirection,
    2006             :                  GUInt64 nSize, const std::string &osIndexingVariableName)
    2007         612 :         : GDALDimension(osParentName, osName, osType, osDirection, nSize),
    2008             :           m_poGroupRef(poGroupRef),
    2009         612 :           m_osIndexingVariableName(osIndexingVariableName)
    2010             :     {
    2011         612 :     }
    2012             : 
    2013             :     VRTGroup *GetGroup() const;
    2014             : 
    2015             :     static std::shared_ptr<VRTDimension>
    2016             :     Create(const std::shared_ptr<VRTGroup> &poThisGroup,
    2017             :            const std::string &osParentName, const CPLXMLNode *psNode);
    2018             : 
    2019             :     std::shared_ptr<GDALMDArray> GetIndexingVariable() const override;
    2020             : 
    2021             :     bool SetIndexingVariable(
    2022             :         std::shared_ptr<GDALMDArray> poIndexingVariable) override;
    2023             : 
    2024             :     void Serialize(CPLXMLNode *psParent) const;
    2025             : };
    2026             : 
    2027             : /************************************************************************/
    2028             : /*                            VRTAttribute                              */
    2029             : /************************************************************************/
    2030             : 
    2031             : class VRTAttribute final : public GDALAttribute
    2032             : {
    2033             :     GDALExtendedDataType m_dt;
    2034             :     std::vector<std::string> m_aosList{};
    2035             :     std::vector<std::shared_ptr<GDALDimension>> m_dims{};
    2036             : 
    2037             :   protected:
    2038             :     bool IRead(const GUInt64 *arrayStartIdx, const size_t *count,
    2039             :                const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
    2040             :                const GDALExtendedDataType &bufferDataType,
    2041             :                void *pDstBuffer) const override;
    2042             : 
    2043             :     bool IWrite(const GUInt64 *arrayStartIdx, const size_t *count,
    2044             :                 const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
    2045             :                 const GDALExtendedDataType &bufferDataType,
    2046             :                 const void *pSrcBuffer) override;
    2047             : 
    2048             :   public:
    2049         150 :     VRTAttribute(const std::string &osParentName, const std::string &osName,
    2050             :                  const GDALExtendedDataType &dt,
    2051             :                  std::vector<std::string> &&aosList)
    2052         150 :         : GDALAbstractMDArray(osParentName, osName),
    2053             :           GDALAttribute(osParentName, osName), m_dt(dt),
    2054         150 :           m_aosList(std::move(aosList))
    2055             :     {
    2056         150 :         if (m_aosList.size() > 1)
    2057             :         {
    2058           2 :             m_dims.emplace_back(std::make_shared<GDALDimension>(
    2059           2 :                 std::string(), "dim", std::string(), std::string(),
    2060           3 :                 m_aosList.size()));
    2061             :         }
    2062         150 :     }
    2063             : 
    2064          60 :     VRTAttribute(const std::string &osParentName, const std::string &osName,
    2065             :                  GUInt64 nDim, const GDALExtendedDataType &dt)
    2066          60 :         : GDALAbstractMDArray(osParentName, osName),
    2067          60 :           GDALAttribute(osParentName, osName), m_dt(dt)
    2068             :     {
    2069          60 :         if (nDim != 0)
    2070             :         {
    2071           8 :             m_dims.emplace_back(std::make_shared<GDALDimension>(
    2072          12 :                 std::string(), "dim", std::string(), std::string(), nDim));
    2073             :         }
    2074          60 :     }
    2075             : 
    2076             :     static bool CreationCommonChecks(
    2077             :         const std::string &osName, const std::vector<GUInt64> &anDimensions,
    2078             :         const std::map<std::string, std::shared_ptr<VRTAttribute>>
    2079             :             &oMapAttributes);
    2080             : 
    2081             :     static std::shared_ptr<VRTAttribute> Create(const std::string &osParentName,
    2082             :                                                 const CPLXMLNode *psNode);
    2083             : 
    2084             :     const std::vector<std::shared_ptr<GDALDimension>> &
    2085         305 :     GetDimensions() const override
    2086             :     {
    2087         305 :         return m_dims;
    2088             :     }
    2089             : 
    2090         208 :     const GDALExtendedDataType &GetDataType() const override
    2091             :     {
    2092         208 :         return m_dt;
    2093             :     }
    2094             : 
    2095             :     void Serialize(CPLXMLNode *psParent) const;
    2096             : };
    2097             : 
    2098             : /************************************************************************/
    2099             : /*                          VRTMDArraySource                            */
    2100             : /************************************************************************/
    2101             : 
    2102             : class VRTMDArraySource
    2103             : {
    2104             :   public:
    2105         962 :     virtual ~VRTMDArraySource() = default;
    2106             : 
    2107             :     virtual bool Read(const GUInt64 *arrayStartIdx, const size_t *count,
    2108             :                       const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
    2109             :                       const GDALExtendedDataType &bufferDataType,
    2110             :                       void *pDstBuffer) const = 0;
    2111             : 
    2112             :     virtual void Serialize(CPLXMLNode *psParent,
    2113             :                            const char *pszVRTPath) const = 0;
    2114             : };
    2115             : 
    2116             : /************************************************************************/
    2117             : /*                            VRTMDArray                                */
    2118             : /************************************************************************/
    2119             : 
    2120             : class VRTMDArray final : public GDALMDArray
    2121             : {
    2122             :   protected:
    2123             :     friend class VRTGroup;  // for access to SetSelf()
    2124             : 
    2125             :     std::weak_ptr<VRTGroup::Ref> m_poGroupRef;
    2126             :     std::string m_osVRTPath{};
    2127             :     std::shared_ptr<VRTGroup> m_poDummyOwningGroup{};
    2128             : 
    2129             :     GDALExtendedDataType m_dt;
    2130             :     std::vector<std::shared_ptr<GDALDimension>> m_dims;
    2131             :     std::map<std::string, std::shared_ptr<VRTAttribute>> m_oMapAttributes{};
    2132             :     std::vector<std::unique_ptr<VRTMDArraySource>> m_sources{};
    2133             :     std::shared_ptr<OGRSpatialReference> m_poSRS{};
    2134             :     std::vector<GByte> m_abyNoData{};
    2135             :     std::string m_osUnit{};
    2136             :     double m_dfScale = 1.0;
    2137             :     double m_dfOffset = 0.0;
    2138             :     bool m_bHasScale = false;
    2139             :     bool m_bHasOffset = false;
    2140             :     std::string m_osFilename{};
    2141             : 
    2142             :     bool IRead(const GUInt64 *arrayStartIdx, const size_t *count,
    2143             :                const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
    2144             :                const GDALExtendedDataType &bufferDataType,
    2145             :                void *pDstBuffer) const override;
    2146             : 
    2147             :     void SetDirty();
    2148             : 
    2149             :   public:
    2150         873 :     VRTMDArray(
    2151             :         const std::shared_ptr<VRTGroup::Ref> &poGroupRef,
    2152             :         const std::string &osParentName, const std::string &osName,
    2153             :         const GDALExtendedDataType &dt,
    2154             :         std::vector<std::shared_ptr<GDALDimension>> &&dims,
    2155             :         std::map<std::string, std::shared_ptr<VRTAttribute>> &&oMapAttributes)
    2156         873 :         : GDALAbstractMDArray(osParentName, osName),
    2157             :           GDALMDArray(osParentName, osName), m_poGroupRef(poGroupRef),
    2158         873 :           m_osVRTPath(poGroupRef->m_ptr->GetVRTPath()), m_dt(dt),
    2159        1746 :           m_dims(std::move(dims)), m_oMapAttributes(std::move(oMapAttributes)),
    2160        1746 :           m_osFilename(poGroupRef->m_ptr->GetFilename())
    2161             :     {
    2162         873 :     }
    2163             : 
    2164         106 :     VRTMDArray(const std::shared_ptr<VRTGroup::Ref> &poGroupRef,
    2165             :                const std::string &osParentName, const std::string &osName,
    2166             :                const std::vector<std::shared_ptr<GDALDimension>> &dims,
    2167             :                const GDALExtendedDataType &dt)
    2168         106 :         : GDALAbstractMDArray(osParentName, osName),
    2169             :           GDALMDArray(osParentName, osName), m_poGroupRef(poGroupRef),
    2170         106 :           m_osVRTPath(poGroupRef->m_ptr->GetVRTPath()), m_dt(dt), m_dims(dims),
    2171         212 :           m_osFilename(poGroupRef->m_ptr->GetFilename())
    2172             :     {
    2173         106 :     }
    2174             : 
    2175           3 :     bool IsWritable() const override
    2176             :     {
    2177           3 :         return false;
    2178             :     }
    2179             : 
    2180         139 :     const std::string &GetFilename() const override
    2181             :     {
    2182         139 :         return m_osFilename;
    2183             :     }
    2184             : 
    2185             :     static std::shared_ptr<VRTMDArray> Create(const char *pszVRTPath,
    2186             :                                               const CPLXMLNode *psNode);
    2187             : 
    2188             :     static std::shared_ptr<VRTMDArray>
    2189             :     Create(const std::shared_ptr<VRTGroup> &poThisGroup,
    2190             :            const std::string &osParentName, const CPLXMLNode *psNode);
    2191             : 
    2192             :     const std::vector<std::shared_ptr<GDALDimension>> &
    2193        3596 :     GetDimensions() const override
    2194             :     {
    2195        3596 :         return m_dims;
    2196             :     }
    2197             : 
    2198             :     std::vector<std::shared_ptr<GDALAttribute>>
    2199             :         GetAttributes(CSLConstList) const override;
    2200             : 
    2201        2087 :     const GDALExtendedDataType &GetDataType() const override
    2202             :     {
    2203        2087 :         return m_dt;
    2204             :     }
    2205             : 
    2206             :     bool SetSpatialRef(const OGRSpatialReference *poSRS) override;
    2207             : 
    2208         158 :     std::shared_ptr<OGRSpatialReference> GetSpatialRef() const override
    2209             :     {
    2210         158 :         return m_poSRS;
    2211             :     }
    2212             : 
    2213             :     const void *GetRawNoDataValue() const override;
    2214             : 
    2215             :     bool SetRawNoDataValue(const void *pRawNoData) override;
    2216             : 
    2217         177 :     const std::string &GetUnit() const override
    2218             :     {
    2219         177 :         return m_osUnit;
    2220             :     }
    2221             : 
    2222           8 :     bool SetUnit(const std::string &osUnit) override
    2223             :     {
    2224           8 :         m_osUnit = osUnit;
    2225           8 :         return true;
    2226             :     }
    2227             : 
    2228         160 :     double GetOffset(bool *pbHasOffset,
    2229             :                      GDALDataType *peStorageType) const override
    2230             :     {
    2231         160 :         if (pbHasOffset)
    2232         160 :             *pbHasOffset = m_bHasOffset;
    2233         160 :         if (peStorageType)
    2234         109 :             *peStorageType = GDT_Unknown;
    2235         160 :         return m_dfOffset;
    2236             :     }
    2237             : 
    2238         160 :     double GetScale(bool *pbHasScale,
    2239             :                     GDALDataType *peStorageType) const override
    2240             :     {
    2241         160 :         if (pbHasScale)
    2242         160 :             *pbHasScale = m_bHasScale;
    2243         160 :         if (peStorageType)
    2244         109 :             *peStorageType = GDT_Unknown;
    2245         160 :         return m_dfScale;
    2246             :     }
    2247             : 
    2248           3 :     bool SetOffset(double dfOffset,
    2249             :                    GDALDataType /* eStorageType */ = GDT_Unknown) override
    2250             :     {
    2251           3 :         SetDirty();
    2252           3 :         m_bHasOffset = true;
    2253           3 :         m_dfOffset = dfOffset;
    2254           3 :         return true;
    2255             :     }
    2256             : 
    2257           3 :     bool SetScale(double dfScale,
    2258             :                   GDALDataType /* eStorageType */ = GDT_Unknown) override
    2259             :     {
    2260           3 :         SetDirty();
    2261           3 :         m_bHasScale = true;
    2262           3 :         m_dfScale = dfScale;
    2263           3 :         return true;
    2264             :     }
    2265             : 
    2266             :     void AddSource(std::unique_ptr<VRTMDArraySource> &&poSource);
    2267             : 
    2268             :     std::shared_ptr<GDALAttribute>
    2269             :     CreateAttribute(const std::string &osName,
    2270             :                     const std::vector<GUInt64> &anDimensions,
    2271             :                     const GDALExtendedDataType &oDataType,
    2272             :                     CSLConstList papszOptions = nullptr) override;
    2273             : 
    2274             :     bool CopyFrom(GDALDataset *poSrcDS, const GDALMDArray *poSrcArray,
    2275             :                   bool bStrict, GUInt64 &nCurCost, const GUInt64 nTotalCost,
    2276             :                   GDALProgressFunc pfnProgress, void *pProgressData) override;
    2277             : 
    2278             :     void Serialize(CPLXMLNode *psParent, const char *pszVRTPathIn) const;
    2279             : 
    2280             :     VRTGroup *GetGroup() const;
    2281             : 
    2282           1 :     const std::string &GetVRTPath() const
    2283             :     {
    2284           1 :         return m_osVRTPath;
    2285             :     }
    2286             : 
    2287           0 :     std::shared_ptr<GDALGroup> GetRootGroup() const override
    2288             :     {
    2289           0 :         auto poGroup = m_poGroupRef.lock();
    2290           0 :         if (poGroup)
    2291           0 :             return poGroup->m_ptr->GetRootGroupSharedPtr();
    2292           0 :         return nullptr;
    2293             :     }
    2294             : };
    2295             : 
    2296             : /************************************************************************/
    2297             : /*                       VRTMDArraySourceInlinedValues                  */
    2298             : /************************************************************************/
    2299             : 
    2300             : class VRTMDArraySourceInlinedValues final : public VRTMDArraySource
    2301             : {
    2302             :     const VRTMDArray *m_poDstArray = nullptr;
    2303             :     bool m_bIsConstantValue;
    2304             :     std::vector<GUInt64> m_anOffset{};
    2305             :     std::vector<size_t> m_anCount{};
    2306             :     std::vector<GByte> m_abyValues{};
    2307             :     std::vector<size_t> m_anInlinedArrayStrideInBytes{};
    2308             :     GDALExtendedDataType m_dt;
    2309             : 
    2310             :     VRTMDArraySourceInlinedValues(const VRTMDArraySourceInlinedValues &) =
    2311             :         delete;
    2312             :     VRTMDArraySourceInlinedValues &
    2313             :     operator=(const VRTMDArraySourceInlinedValues &) = delete;
    2314             : 
    2315             :   public:
    2316         538 :     VRTMDArraySourceInlinedValues(const VRTMDArray *poDstArray,
    2317             :                                   bool bIsConstantValue,
    2318             :                                   std::vector<GUInt64> &&anOffset,
    2319             :                                   std::vector<size_t> &&anCount,
    2320             :                                   std::vector<GByte> &&abyValues)
    2321         538 :         : m_poDstArray(poDstArray), m_bIsConstantValue(bIsConstantValue),
    2322        1076 :           m_anOffset(std::move(anOffset)), m_anCount(std::move(anCount)),
    2323         538 :           m_abyValues(std::move(abyValues)), m_dt(poDstArray->GetDataType())
    2324             :     {
    2325         538 :         const auto nDims(poDstArray->GetDimensionCount());
    2326         538 :         m_anInlinedArrayStrideInBytes.resize(nDims);
    2327         538 :         if (!bIsConstantValue && nDims > 0)
    2328             :         {
    2329         216 :             m_anInlinedArrayStrideInBytes.back() =
    2330         216 :                 poDstArray->GetDataType().GetSize();
    2331         221 :             for (size_t i = nDims - 1; i > 0;)
    2332             :             {
    2333           5 :                 --i;
    2334           5 :                 m_anInlinedArrayStrideInBytes[i] =
    2335           5 :                     m_anInlinedArrayStrideInBytes[i + 1] * m_anCount[i + 1];
    2336             :             }
    2337             :         }
    2338         538 :     }
    2339             : 
    2340             :     ~VRTMDArraySourceInlinedValues();
    2341             : 
    2342             :     static std::unique_ptr<VRTMDArraySourceInlinedValues>
    2343             :     Create(const VRTMDArray *poDstArray, const CPLXMLNode *psNode);
    2344             : 
    2345             :     bool Read(const GUInt64 *arrayStartIdx, const size_t *count,
    2346             :               const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
    2347             :               const GDALExtendedDataType &bufferDataType,
    2348             :               void *pDstBuffer) const override;
    2349             : 
    2350             :     void Serialize(CPLXMLNode *psParent, const char *pszVRTPath) const override;
    2351             : };
    2352             : 
    2353             : /************************************************************************/
    2354             : /*                     VRTMDArraySourceRegularlySpaced                  */
    2355             : /************************************************************************/
    2356             : 
    2357             : class VRTMDArraySourceRegularlySpaced final : public VRTMDArraySource
    2358             : {
    2359             :     double m_dfStart;
    2360             :     double m_dfIncrement;
    2361             : 
    2362             :   public:
    2363         220 :     VRTMDArraySourceRegularlySpaced(double dfStart, double dfIncrement)
    2364         220 :         : m_dfStart(dfStart), m_dfIncrement(dfIncrement)
    2365             :     {
    2366         220 :     }
    2367             : 
    2368             :     bool Read(const GUInt64 *arrayStartIdx, const size_t *count,
    2369             :               const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
    2370             :               const GDALExtendedDataType &bufferDataType,
    2371             :               void *pDstBuffer) const override;
    2372             : 
    2373             :     void Serialize(CPLXMLNode *psParent, const char *pszVRTPath) const override;
    2374             : };
    2375             : 
    2376             : /************************************************************************/
    2377             : /*                       VRTMDArraySourceFromArray                      */
    2378             : /************************************************************************/
    2379             : 
    2380             : class VRTMDArraySourceFromArray final : public VRTMDArraySource
    2381             : {
    2382             :     const VRTMDArray *m_poDstArray = nullptr;
    2383             :     bool m_bRelativeToVRTSet = false;
    2384             :     bool m_bRelativeToVRT = false;
    2385             :     std::string m_osFilename{};
    2386             :     std::string m_osArray{};
    2387             :     std::string m_osBand{};
    2388             :     std::vector<int> m_anTransposedAxis{};
    2389             :     std::string m_osViewExpr{};
    2390             :     std::vector<GUInt64> m_anSrcOffset{};
    2391             :     mutable std::vector<GUInt64> m_anCount{};
    2392             :     std::vector<GUInt64> m_anStep{};
    2393             :     std::vector<GUInt64> m_anDstOffset{};
    2394             : 
    2395             :     VRTMDArraySourceFromArray(const VRTMDArraySourceFromArray &) = delete;
    2396             :     VRTMDArraySourceFromArray &
    2397             :     operator=(const VRTMDArraySourceFromArray &) = delete;
    2398             : 
    2399             :   public:
    2400         204 :     VRTMDArraySourceFromArray(
    2401             :         const VRTMDArray *poDstArray, bool bRelativeToVRTSet,
    2402             :         bool bRelativeToVRT, const std::string &osFilename,
    2403             :         const std::string &osArray, const std::string &osBand,
    2404             :         std::vector<int> &&anTransposedAxis, const std::string &osViewExpr,
    2405             :         std::vector<GUInt64> &&anSrcOffset, std::vector<GUInt64> &&anCount,
    2406             :         std::vector<GUInt64> &&anStep, std::vector<GUInt64> &&anDstOffset)
    2407         204 :         : m_poDstArray(poDstArray), m_bRelativeToVRTSet(bRelativeToVRTSet),
    2408             :           m_bRelativeToVRT(bRelativeToVRT), m_osFilename(osFilename),
    2409             :           m_osArray(osArray), m_osBand(osBand),
    2410         204 :           m_anTransposedAxis(std::move(anTransposedAxis)),
    2411         204 :           m_osViewExpr(osViewExpr), m_anSrcOffset(std::move(anSrcOffset)),
    2412         408 :           m_anCount(std::move(anCount)), m_anStep(std::move(anStep)),
    2413         204 :           m_anDstOffset(std::move(anDstOffset))
    2414             :     {
    2415         204 :     }
    2416             : 
    2417             :     ~VRTMDArraySourceFromArray() override;
    2418             : 
    2419             :     static std::unique_ptr<VRTMDArraySourceFromArray>
    2420             :     Create(const VRTMDArray *poDstArray, const CPLXMLNode *psNode);
    2421             : 
    2422             :     bool Read(const GUInt64 *arrayStartIdx, const size_t *count,
    2423             :               const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
    2424             :               const GDALExtendedDataType &bufferDataType,
    2425             :               void *pDstBuffer) const override;
    2426             : 
    2427             :     void Serialize(CPLXMLNode *psParent, const char *pszVRTPath) const override;
    2428             : };
    2429             : 
    2430             : #endif /* #ifndef DOXYGEN_SKIP */
    2431             : 
    2432             : #endif /* ndef VIRTUALDATASET_H_INCLUDED */

Generated by: LCOV version 1.14