LCOV - code coverage report
Current view: top level - frmts/vrt - vrtdataset.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 212 226 93.8 %
Date: 2025-07-11 10:11:13 Functions: 70 75 93.3 %

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

Generated by: LCOV version 1.14