LCOV - code coverage report
Current view: top level - frmts/vrt - vrtdataset.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 237 255 92.9 %
Date: 2026-07-04 09:03:09 Functions: 80 88 90.9 %

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

Generated by: LCOV version 1.14