LCOV - code coverage report
Current view: top level - frmts/vrt - vrtdataset.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 204 218 93.6 %
Date: 2024-05-07 17:03:27 Functions: 67 71 94.4 %

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

Generated by: LCOV version 1.14