1 /******************************************************************************
2  * $Id: vrtdataset.h 8c8864a6008b3f523a8e96017e87482904fa665b 2020-12-18 18:51:04 +0100 Even Rouault $
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 <map>
45 #include <memory>
46 #include <vector>
47 
48 int VRTApplyMetadata( CPLXMLNode *, GDALMajorObject * );
49 CPLXMLNode *VRTSerializeMetadata( GDALMajorObject * );
50 CPLErr GDALRegisterDefaultPixelFunc();
51 CPLString VRTSerializeNoData(double dfVal, GDALDataType eDataType, int nPrecision);
52 #if 0
53 int VRTWarpedOverviewTransform( void *pTransformArg, int bDstToSrc,
54                                 int nPointCount,
55                                 double *padfX, double *padfY, double *padfZ,
56                                 int *panSuccess );
57 void* VRTDeserializeWarpedOverviewTransformer( CPLXMLNode *psTree );
58 #endif
59 
60 /************************************************************************/
61 /*                          VRTOverviewInfo()                           */
62 /************************************************************************/
63 class VRTOverviewInfo
64 {
CPL_DISALLOW_COPY_ASSIGN(VRTOverviewInfo)65     CPL_DISALLOW_COPY_ASSIGN(VRTOverviewInfo)
66 
67 public:
68     CPLString       osFilename{};
69     int             nBand = 0;
70     GDALRasterBand *poBand = nullptr;
71     int             bTriedToOpen = FALSE;
72 
73     VRTOverviewInfo() = default;
VRTOverviewInfo(VRTOverviewInfo && oOther)74     VRTOverviewInfo(VRTOverviewInfo&& oOther) noexcept:
75         osFilename(std::move(oOther.osFilename)),
76         nBand(oOther.nBand),
77         poBand(oOther.poBand),
78         bTriedToOpen(oOther.bTriedToOpen)
79     {
80         oOther.poBand = nullptr;
81     }
82 
~VRTOverviewInfo()83     ~VRTOverviewInfo() {
84         CloseDataset();
85     }
86 
CloseDataset()87     bool CloseDataset()
88     {
89         if( poBand == nullptr )
90             return false;
91 
92         GDALDataset* poDS = poBand->GetDataset();
93         // Nullify now, to prevent recursion in some cases !
94         poBand = nullptr;
95         if( poDS->GetShared() )
96             GDALClose( /* (GDALDatasetH) */ poDS );
97         else
98             poDS->Dereference();
99 
100         return true;
101     }
102 };
103 
104 /************************************************************************/
105 /*                              VRTSource                               */
106 /************************************************************************/
107 
108 class CPL_DLL VRTSource
109 {
110 public:
111     virtual ~VRTSource();
112 
113     virtual CPLErr  RasterIO( GDALDataType eBandDataType,
114                               int nXOff, int nYOff, int nXSize, int nYSize,
115                               void *pData, int nBufXSize, int nBufYSize,
116                               GDALDataType eBufType,
117                               GSpacing nPixelSpace, GSpacing nLineSpace,
118                               GDALRasterIOExtraArg* psExtraArg ) = 0;
119 
120     virtual double GetMinimum( int nXSize, int nYSize, int *pbSuccess ) = 0;
121     virtual double GetMaximum( int nXSize, int nYSize, int *pbSuccess ) = 0;
122     virtual CPLErr ComputeRasterMinMax( int nXSize, int nYSize, int bApproxOK,
123                                         double* adfMinMax ) = 0;
124     virtual CPLErr ComputeStatistics( int nXSize, int nYSize,
125                                       int bApproxOK,
126                                       double *pdfMin, double *pdfMax,
127                                       double *pdfMean, double *pdfStdDev,
128                                       GDALProgressFunc pfnProgress,
129                                       void *pProgressData ) = 0;
130     virtual CPLErr  GetHistogram( int nXSize, int nYSize,
131                                   double dfMin, double dfMax,
132                                   int nBuckets, GUIntBig * panHistogram,
133                                   int bIncludeOutOfRange, int bApproxOK,
134                                   GDALProgressFunc pfnProgress,
135                                   void *pProgressData ) = 0;
136 
137     virtual CPLErr  XMLInit( CPLXMLNode *psTree, const char *, void*,
138                              std::map<CPLString, GDALDataset*>& ) = 0;
139     virtual CPLXMLNode *SerializeToXML( const char *pszVRTPath ) = 0;
140 
141     virtual void   GetFileList(char*** ppapszFileList, int *pnSize,
142                                int *pnMaxSize, CPLHashSet* hSetFiles);
143 
IsSimpleSource()144     virtual int    IsSimpleSource() { return FALSE; }
FlushCache()145     virtual CPLErr FlushCache() { return CE_None; }
146 };
147 
148 typedef VRTSource *(*VRTSourceParser)(CPLXMLNode *, const char *, void* pUniqueHandle,
149                                       std::map<CPLString, GDALDataset*>& oMapSharedSources);
150 
151 VRTSource *VRTParseCoreSources( CPLXMLNode *psTree, const char *, void* pUniqueHandle,
152                                 std::map<CPLString, GDALDataset*>& oMapSharedSources);
153 VRTSource *VRTParseFilterSources( CPLXMLNode *psTree, const char *, void* pUniqueHandle,
154                                   std::map<CPLString, GDALDataset*>& oMapSharedSources );
155 
156 /************************************************************************/
157 /*                              VRTDataset                              */
158 /************************************************************************/
159 
160 class VRTRasterBand;
161 
162 template<class T> struct VRTFlushCacheStruct
163 {
164     static void FlushCache(T& obj);
165 };
166 
167 class VRTWarpedDataset;
168 class VRTPansharpenedDataset;
169 class VRTGroup;
170 
171 class CPL_DLL VRTDataset CPL_NON_FINAL: public GDALDataset
172 {
173     friend class VRTRasterBand;
174     friend struct VRTFlushCacheStruct<VRTDataset>;
175     friend struct VRTFlushCacheStruct<VRTWarpedDataset>;
176     friend struct VRTFlushCacheStruct<VRTPansharpenedDataset>;
177     friend class VRTSourcedRasterBand;
178     friend VRTDatasetH CPL_STDCALL VRTCreate(int nXSize, int nYSize);
179 
180     OGRSpatialReference* m_poSRS = nullptr;
181 
182     int            m_bGeoTransformSet = false;
183     double         m_adfGeoTransform[6];
184 
185     int            m_nGCPCount = 0;
186     GDAL_GCP      *m_pasGCPList = nullptr;
187     OGRSpatialReference *m_poGCP_SRS = nullptr;
188 
189     bool           m_bNeedsFlush = false;
190     bool           m_bWritable = true;
191     bool           m_bCanTakeRef = true;
192 
193     char          *m_pszVRTPath = nullptr;
194 
195     VRTRasterBand *m_poMaskBand = nullptr;
196 
197     int            m_bCompatibleForDatasetIO = -1;
198     int            CheckCompatibleForDatasetIO();
199     void           ExpandProxyBands();
200 
201     // Virtual (ie not materialized) overviews, created either implicitly
202     // when it is cheap to do it, or explicitly.
203     std::vector<GDALDataset*> m_apoOverviews{};
204     std::vector<GDALDataset*> m_apoOverviewsBak{};
205     CPLString           m_osOverviewResampling{};
206     std::vector<int>    m_anOverviewFactors{};
207 
208     char         **m_papszXMLVRTMetadata = nullptr;
209 
210     std::map<CPLString, GDALDataset*> m_oMapSharedSources{};
211     std::shared_ptr<VRTGroup> m_poRootGroup{};
212 
213     int            m_nRecursionCounter = 0;
214 
215     VRTRasterBand*      InitBand(const char* pszSubclass, int nBand,
216                                  bool bAllowPansharpened);
217     static GDALDataset *OpenVRTProtocol( const char* pszSpec );
218     bool                AddVirtualOverview(int nOvFactor,
219                                            const char* pszResampling);
220 
221     CPL_DISALLOW_COPY_ASSIGN(VRTDataset)
222 
223   protected:
224     virtual int         CloseDependentDatasets() override;
225 
226   public:
227                  VRTDataset(int nXSize, int nYSize);
228     virtual ~VRTDataset();
229 
230     void          SetNeedsFlush() { m_bNeedsFlush = true; }
231     virtual void  FlushCache() override;
232 
233     void SetWritable(int bWritableIn) { m_bWritable = CPL_TO_BOOL(bWritableIn); }
234 
235     virtual CPLErr          CreateMaskBand( int nFlags ) override;
236     void SetMaskBand(VRTRasterBand* poMaskBand);
237 
238     const OGRSpatialReference* GetSpatialRef() const override { return m_poSRS; }
239     CPLErr SetSpatialRef(const OGRSpatialReference* poSRS) override;
240 
241     virtual CPLErr GetGeoTransform( double * ) override;
242     virtual CPLErr SetGeoTransform( double * ) override;
243 
244     virtual CPLErr SetMetadata( char **papszMetadata,
245                                 const char *pszDomain = "" ) override;
246     virtual CPLErr SetMetadataItem( const char *pszName, const char *pszValue,
247                                     const char *pszDomain = "" ) override;
248 
249     virtual char** GetMetadata( const char *pszDomain = "" ) override;
250 
251     virtual int    GetGCPCount() override;
252     const OGRSpatialReference* GetGCPSpatialRef() const override { return m_poGCP_SRS; }
253     virtual const GDAL_GCP *GetGCPs() override;
254     using GDALDataset::SetGCPs;
255     CPLErr SetGCPs( int nGCPCount, const GDAL_GCP *pasGCPList,
256                     const OGRSpatialReference* poSRS ) override;
257 
258     virtual CPLErr AddBand( GDALDataType eType,
259                             char **papszOptions=nullptr ) override;
260 
261     virtual char      **GetFileList() override;
262 
263     virtual CPLErr  IRasterIO( GDALRWFlag eRWFlag,
264                                int nXOff, int nYOff, int nXSize, int nYSize,
265                                void * pData, int nBufXSize, int nBufYSize,
266                                GDALDataType eBufType,
267                                int nBandCount, int *panBandMap,
268                                GSpacing nPixelSpace, GSpacing nLineSpace,
269                                GSpacing nBandSpace,
270                                GDALRasterIOExtraArg* psExtraArg) override;
271 
272     virtual CPLErr AdviseRead( int nXOff, int nYOff, int nXSize, int nYSize,
273                                int nBufXSize, int nBufYSize,
274                                GDALDataType eDT,
275                                int nBandCount, int *panBandList,
276                                char **papszOptions ) override;
277 
278     virtual CPLXMLNode *SerializeToXML( const char *pszVRTPath);
279     virtual CPLErr      XMLInit( CPLXMLNode *, const char * );
280 
281     virtual CPLErr IBuildOverviews( const char *, int, int *,
282                                     int, int *, GDALProgressFunc, void * ) override;
283 
284     std::shared_ptr<GDALGroup> GetRootGroup() const override;
285 
286     /* Used by PDF driver for example */
287     GDALDataset*        GetSingleSimpleSource();
288     void                BuildVirtualOverviews();
289 
290     void                UnsetPreservedRelativeFilenames();
291 
292     static int          Identify( GDALOpenInfo * );
293     static GDALDataset *Open( GDALOpenInfo * );
294     static GDALDataset *OpenXML( const char *, const char * = nullptr,
295                                  GDALAccess eAccess = GA_ReadOnly );
296     static GDALDataset *Create( const char * pszName,
297                                 int nXSize, int nYSize, int nBands,
298                                 GDALDataType eType, char ** papszOptions );
299     static GDALDataset *CreateMultiDimensional( const char * pszFilename,
300                                                 CSLConstList papszRootGroupOptions,
301                                                 CSLConstList papszOptions );
302     static CPLErr       Delete( const char * pszFilename );
303 };
304 
305 /************************************************************************/
306 /*                           VRTWarpedDataset                           */
307 /************************************************************************/
308 
309 class GDALWarpOperation;
310 class VRTWarpedRasterBand;
311 
312 class CPL_DLL VRTWarpedDataset final: public VRTDataset
313 {
314     int               m_nBlockXSize;
315     int               m_nBlockYSize;
316     GDALWarpOperation *m_poWarper;
317 
318     int               m_nOverviewCount;
319     VRTWarpedDataset **m_papoOverviews;
320     int               m_nSrcOvrLevel;
321 
322     void              CreateImplicitOverviews();
323 
324     struct VerticalShiftGrid
325     {
326         CPLString osVGrids{};
327         int       bInverse = false;
328         double    dfToMeterSrc = 0.0;
329         double    dfToMeterDest = 0.0;
330         CPLStringList aosOptions{};
331     };
332     std::vector<VerticalShiftGrid> m_aoVerticalShiftGrids{};
333 
334     friend class VRTWarpedRasterBand;
335 
336     CPL_DISALLOW_COPY_ASSIGN(VRTWarpedDataset)
337 
338   protected:
339     virtual int         CloseDependentDatasets() override;
340 
341 public:
342                       VRTWarpedDataset( int nXSize, int nYSize );
343     virtual ~VRTWarpedDataset();
344 
345     virtual void  FlushCache() override;
346 
347     CPLErr            Initialize( /* GDALWarpOptions */ void * );
348 
349     virtual CPLErr IBuildOverviews( const char *, int, int *,
350                                     int, int *, GDALProgressFunc, void * ) override;
351 
352     virtual CPLErr SetMetadataItem( const char *pszName, const char *pszValue,
353                                     const char *pszDomain = "" ) override;
354 
355     virtual CPLXMLNode *SerializeToXML( const char *pszVRTPath ) override;
356     virtual CPLErr    XMLInit( CPLXMLNode *, const char * ) override;
357 
358     virtual CPLErr AddBand( GDALDataType eType,
359                             char **papszOptions=nullptr ) override;
360 
361     virtual char      **GetFileList() override;
362 
363     CPLErr            ProcessBlock( int iBlockX, int iBlockY );
364 
365     void              GetBlockSize( int *, int * ) const;
366 
367     void              SetApplyVerticalShiftGrid(const char* pszVGrids,
368                                              int bInverse,
369                                              double dfToMeterSrc,
370                                              double dfToMeterDest,
371                                              char** papszOptions );
372 };
373 
374 /************************************************************************/
375 /*                        VRTPansharpenedDataset                        */
376 /************************************************************************/
377 
378 class GDALPansharpenOperation;
379 
380 typedef enum
381 {
382     GTAdjust_Union,
383     GTAdjust_Intersection,
384     GTAdjust_None,
385     GTAdjust_NoneWithoutWarning
386 } GTAdjustment;
387 
388 class VRTPansharpenedDataset final: public VRTDataset
389 {
390     friend class      VRTPansharpenedRasterBand;
391 
392     int               m_nBlockXSize;
393     int               m_nBlockYSize;
394     GDALPansharpenOperation* m_poPansharpener;
395     VRTPansharpenedDataset* m_poMainDataset;
396     std::vector<VRTPansharpenedDataset*> m_apoOverviewDatasets{};
397     // Map from absolute to relative.
398     std::map<CPLString,CPLString> m_oMapToRelativeFilenames{};
399 
400     int               m_bLoadingOtherBands;
401 
402     GByte            *m_pabyLastBufferBandRasterIO;
403     int               m_nLastBandRasterIOXOff;
404     int               m_nLastBandRasterIOYOff;
405     int               m_nLastBandRasterIOXSize;
406     int               m_nLastBandRasterIOYSize;
407     GDALDataType      m_eLastBandRasterIODataType;
408 
409     GTAdjustment      m_eGTAdjustment;
410     int               m_bNoDataDisabled;
411 
412     std::vector<GDALDataset*> m_apoDatasetsToClose{};
413 
414     CPL_DISALLOW_COPY_ASSIGN(VRTPansharpenedDataset)
415 
416   protected:
417     virtual int         CloseDependentDatasets() override;
418 
419 public:
420                       VRTPansharpenedDataset( int nXSize, int nYSize );
421     virtual ~VRTPansharpenedDataset();
422 
423     virtual void  FlushCache() override;
424 
425     virtual CPLErr    XMLInit( CPLXMLNode *, const char * ) override;
426     virtual CPLXMLNode *   SerializeToXML( const char *pszVRTPath ) override;
427 
428     CPLErr            XMLInit( CPLXMLNode *psTree, const char *pszVRTPath,
429                                GDALRasterBandH hPanchroBandIn,
430                                int nInputSpectralBandsIn,
431                                GDALRasterBandH* pahInputSpectralBandsIn );
432 
433     virtual CPLErr AddBand( GDALDataType eType,
434                             char **papszOptions=nullptr ) override;
435 
436     virtual char      **GetFileList() override;
437 
438     virtual CPLErr  IRasterIO( GDALRWFlag eRWFlag,
439                                int nXOff, int nYOff, int nXSize, int nYSize,
440                                void * pData, int nBufXSize, int nBufYSize,
441                                GDALDataType eBufType,
442                                int nBandCount, int *panBandMap,
443                                GSpacing nPixelSpace, GSpacing nLineSpace,
444                                GSpacing nBandSpace,
445                                GDALRasterIOExtraArg* psExtraArg) override;
446 
447     void              GetBlockSize( int *, int * ) const;
448 
449     GDALPansharpenOperation* GetPansharpener() { return m_poPansharpener; }
450 };
451 
452 /************************************************************************/
453 /*                            VRTRasterBand                             */
454 /*                                                                      */
455 /*      Provides support for all the various kinds of metadata but      */
456 /*      no raster access.  That is handled by derived classes.          */
457 /************************************************************************/
458 
459 class CPL_DLL VRTRasterBand CPL_NON_FINAL: public GDALRasterBand
460 {
461   protected:
462     friend class VRTDataset;
463 
464     int            m_bIsMaskBand;
465 
466     int            m_bNoDataValueSet;
467     // If set to true, will not report the existence of nodata.
468     int            m_bHideNoDataValue;
469     double         m_dfNoDataValue;
470 
471     std::unique_ptr<GDALColorTable> m_poColorTable{};
472 
473     GDALColorInterp m_eColorInterp;
474 
475     char           *m_pszUnitType;
476     char           **m_papszCategoryNames;
477 
478     double         m_dfOffset;
479     double         m_dfScale;
480 
481     CPLXMLNode    *m_psSavedHistograms;
482 
483     void           Initialize( int nXSize, int nYSize );
484 
485     std::vector<VRTOverviewInfo> m_aoOverviewInfos{};
486 
487     VRTRasterBand *m_poMaskBand;
488 
489     std::unique_ptr<GDALRasterAttributeTable> m_poRAT{};
490 
491     CPL_DISALLOW_COPY_ASSIGN(VRTRasterBand)
492 
493   public:
494 
495                     VRTRasterBand();
496     virtual        ~VRTRasterBand();
497 
498     virtual CPLErr         XMLInit( CPLXMLNode *, const char *, void*,
499                                     std::map<CPLString, GDALDataset*>& );
500     virtual CPLXMLNode *   SerializeToXML( const char *pszVRTPath );
501 
502     virtual CPLErr SetNoDataValue( double ) override;
503     virtual double GetNoDataValue( int *pbSuccess = nullptr ) override;
504     virtual CPLErr DeleteNoDataValue() override;
505 
506     virtual CPLErr SetColorTable( GDALColorTable * ) override;
507     virtual GDALColorTable *GetColorTable() override;
508 
509     virtual GDALRasterAttributeTable *GetDefaultRAT() override;
510     virtual CPLErr SetDefaultRAT( const GDALRasterAttributeTable * poRAT ) override;
511 
512     virtual CPLErr SetColorInterpretation( GDALColorInterp ) override;
513     virtual GDALColorInterp GetColorInterpretation() override;
514 
515     virtual const char *GetUnitType() override;
516     CPLErr SetUnitType( const char * ) override;
517 
518     virtual char **GetCategoryNames() override;
519     virtual CPLErr SetCategoryNames( char ** ) override;
520 
521     virtual CPLErr SetMetadata( char **papszMD, const char *pszDomain = "" ) override;
522     virtual CPLErr SetMetadataItem( const char *pszName, const char *pszValue,
523                                     const char *pszDomain = "" ) override;
524 
525     virtual double GetOffset( int *pbSuccess = nullptr ) override;
526     CPLErr SetOffset( double ) override;
527     virtual double GetScale( int *pbSuccess = nullptr ) override;
528     CPLErr SetScale( double ) override;
529 
530     virtual int GetOverviewCount() override;
531     virtual GDALRasterBand *GetOverview(int) override;
532 
533     virtual CPLErr  GetHistogram( double dfMin, double dfMax,
534                                   int nBuckets, GUIntBig * panHistogram,
535                                   int bIncludeOutOfRange, int bApproxOK,
536                                   GDALProgressFunc, void *pProgressData ) override;
537 
538     virtual CPLErr GetDefaultHistogram( double *pdfMin, double *pdfMax,
539                                         int *pnBuckets, GUIntBig ** ppanHistogram,
540                                         int bForce,
541                                         GDALProgressFunc, void *pProgressData) override;
542 
543     virtual CPLErr SetDefaultHistogram( double dfMin, double dfMax,
544                                         int nBuckets, GUIntBig *panHistogram ) override;
545 
546     CPLErr         CopyCommonInfoFrom( GDALRasterBand * );
547 
548     virtual void   GetFileList(char*** ppapszFileList, int *pnSize,
549                                int *pnMaxSize, CPLHashSet* hSetFiles);
550 
551     virtual void   SetDescription( const char * ) override;
552 
553     virtual GDALRasterBand *GetMaskBand() override;
554     virtual int             GetMaskFlags() override;
555 
556     virtual CPLErr          CreateMaskBand( int nFlagsIn ) override;
557 
558     void SetMaskBand(VRTRasterBand* poMaskBand);
559 
560     void SetIsMaskBand();
561 
562     CPLErr UnsetNoDataValue();
563 
564     virtual int         CloseDependentDatasets();
565 
566     virtual int         IsSourcedRasterBand() { return FALSE; }
567     virtual int         IsPansharpenRasterBand() { return FALSE; }
568 };
569 
570 /************************************************************************/
571 /*                         VRTSourcedRasterBand                         */
572 /************************************************************************/
573 
574 class VRTSimpleSource;
575 
576 class CPL_DLL VRTSourcedRasterBand CPL_NON_FINAL: public VRTRasterBand
577 {
578   private:
579     int            m_nRecursionCounter;
580     CPLString      m_osLastLocationInfo{};
581     char         **m_papszSourceList;
582 
583     bool           CanUseSourcesMinMaxImplementations();
584     void           CheckSource( VRTSimpleSource *poSS );
585 
586     CPL_DISALLOW_COPY_ASSIGN(VRTSourcedRasterBand)
587 
588   public:
589     int            nSources;
590     VRTSource    **papoSources;
591     int            bSkipBufferInitialization;
592 
593                    VRTSourcedRasterBand( GDALDataset *poDS, int nBand );
594                    VRTSourcedRasterBand( GDALDataType eType,
595                                          int nXSize, int nYSize );
596                    VRTSourcedRasterBand( GDALDataset *poDS, int nBand,
597                                          GDALDataType eType,
598                                          int nXSize, int nYSize );
599                    VRTSourcedRasterBand( GDALDataset *poDS, int nBand,
600                                          GDALDataType eType,
601                                          int nXSize, int nYSize,
602                                          int nBlockXSizeIn, int nBlockYSizeIn );
603     virtual        ~VRTSourcedRasterBand();
604 
605     virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
606                               void *, int, int, GDALDataType,
607                               GSpacing nPixelSpace, GSpacing nLineSpace,
608                               GDALRasterIOExtraArg* psExtraArg) override;
609 
610     virtual int IGetDataCoverageStatus( int nXOff, int nYOff,
611                                         int nXSize, int nYSize,
612                                         int nMaskFlagStop,
613                                         double* pdfDataPct) override;
614 
615     virtual char      **GetMetadataDomainList() override;
616     virtual const char *GetMetadataItem( const char * pszName,
617                                          const char * pszDomain = "" ) override;
618     virtual char      **GetMetadata( const char * pszDomain = "" ) override;
619     virtual CPLErr      SetMetadata( char ** papszMetadata,
620                                      const char * pszDomain = "" ) override;
621     virtual CPLErr      SetMetadataItem( const char * pszName,
622                                          const char * pszValue,
623                                          const char * pszDomain = "" ) override;
624 
625     virtual CPLErr         XMLInit( CPLXMLNode *, const char *, void*,
626                                     std::map<CPLString, GDALDataset*>& ) override;
627     virtual CPLXMLNode *   SerializeToXML( const char *pszVRTPath ) override;
628 
629     virtual double GetMinimum( int *pbSuccess = nullptr ) override;
630     virtual double GetMaximum(int *pbSuccess = nullptr ) override;
631     virtual CPLErr ComputeRasterMinMax( int bApproxOK, double* adfMinMax ) override;
632     virtual CPLErr ComputeStatistics( int bApproxOK,
633                                       double *pdfMin, double *pdfMax,
634                                       double *pdfMean, double *pdfStdDev,
635                                       GDALProgressFunc pfnProgress,
636                                       void *pProgressData ) override;
637     virtual CPLErr  GetHistogram( double dfMin, double dfMax,
638                                   int nBuckets, GUIntBig * panHistogram,
639                                   int bIncludeOutOfRange, int bApproxOK,
640                                   GDALProgressFunc pfnProgress,
641                                   void *pProgressData ) override;
642 
643     CPLErr         AddSource( VRTSource * );
644     CPLErr         AddSimpleSource( GDALRasterBand *poSrcBand,
645                                     double dfSrcXOff=-1, double dfSrcYOff=-1,
646                                     double dfSrcXSize=-1, double dfSrcYSize=-1,
647                                     double dfDstXOff=-1, double dfDstYOff=-1,
648                                     double dfDstXSize=-1, double dfDstYSize=-1,
649                                     const char *pszResampling = "near",
650                                     double dfNoDataValue = VRT_NODATA_UNSET);
651     CPLErr         AddComplexSource( GDALRasterBand *poSrcBand,
652                                      double dfSrcXOff=-1, double dfSrcYOff=-1,
653                                      double dfSrcXSize=-1, double dfSrcYSize=-1,
654                                      double dfDstXOff=-1, double dfDstYOff=-1,
655                                      double dfDstXSize=-1, double dfDstYSize=-1,
656                                      double dfScaleOff=0.0,
657                                      double dfScaleRatio=1.0,
658                                      double dfNoDataValue = VRT_NODATA_UNSET,
659                                      int nColorTableComponent = 0);
660 
661     CPLErr         AddMaskBandSource( GDALRasterBand *poSrcBand,
662                                       double dfSrcXOff=-1, double dfSrcYOff=-1,
663                                       double dfSrcXSize=-1,
664                                       double dfSrcYSize=-1,
665                                       double dfDstXOff=-1, double dfDstYOff=-1,
666                                       double dfDstXSize=-1,
667                                       double dfDstYSize=-1 );
668 
669     CPLErr         AddFuncSource( VRTImageReadFunc pfnReadFunc, void *hCBData,
670                                   double dfNoDataValue = VRT_NODATA_UNSET );
671 
672     void           ConfigureSource(VRTSimpleSource *poSimpleSource,
673                                    GDALRasterBand *poSrcBand,
674                                    int bAddAsMaskBand,
675                                    double dfSrcXOff, double dfSrcYOff,
676                                    double dfSrcXSize, double dfSrcYSize,
677                                    double dfDstXOff, double dfDstYOff,
678                                    double dfDstXSize, double dfDstYSize );
679 
680     virtual CPLErr IReadBlock( int, int, void * ) override;
681 
682     virtual void   GetFileList(char*** ppapszFileList, int *pnSize,
683                                int *pnMaxSize, CPLHashSet* hSetFiles) override;
684 
685     virtual int         CloseDependentDatasets() override;
686 
687     virtual int         IsSourcedRasterBand() override { return TRUE; }
688 
689     virtual CPLErr      FlushCache() override;
690 };
691 
692 /************************************************************************/
693 /*                         VRTWarpedRasterBand                          */
694 /************************************************************************/
695 
696 class CPL_DLL VRTWarpedRasterBand final: public VRTRasterBand
697 {
698   public:
699                    VRTWarpedRasterBand( GDALDataset *poDS, int nBand,
700                                         GDALDataType eType = GDT_Unknown );
701     virtual        ~VRTWarpedRasterBand();
702 
703     virtual CPLXMLNode *   SerializeToXML( const char *pszVRTPath ) override;
704 
705     virtual CPLErr IReadBlock( int, int, void * ) override;
706     virtual CPLErr IWriteBlock( int, int, void * ) override;
707 
708     virtual int GetOverviewCount() override;
709     virtual GDALRasterBand *GetOverview(int) override;
710 };
711 /************************************************************************/
712 /*                        VRTPansharpenedRasterBand                     */
713 /************************************************************************/
714 
715 class VRTPansharpenedRasterBand final: public VRTRasterBand
716 {
717     int               m_nIndexAsPansharpenedBand;
718 
719   public:
720                    VRTPansharpenedRasterBand(
721                        GDALDataset *poDS, int nBand,
722                        GDALDataType eDataType = GDT_Unknown );
723     virtual        ~VRTPansharpenedRasterBand();
724 
725     virtual CPLXMLNode *   SerializeToXML( const char *pszVRTPath ) override;
726 
727     virtual CPLErr IReadBlock( int, int, void * ) override;
728 
729     virtual CPLErr  IRasterIO( GDALRWFlag eRWFlag,
730                                int nXOff, int nYOff, int nXSize, int nYSize,
731                                void * pData, int nBufXSize, int nBufYSize,
732                                GDALDataType eBufType,
733                                GSpacing nPixelSpace, GSpacing nLineSpace,
734                                GDALRasterIOExtraArg* psExtraArg) override;
735 
736     virtual int GetOverviewCount() override;
737     virtual GDALRasterBand *GetOverview(int) override;
738 
739     virtual int         IsPansharpenRasterBand() override { return TRUE; }
740 
741     void                SetIndexAsPansharpenedBand( int nIdx )
742         { m_nIndexAsPansharpenedBand = nIdx; }
743     int                 GetIndexAsPansharpenedBand() const
744         { return m_nIndexAsPansharpenedBand; }
745 };
746 
747 /************************************************************************/
748 /*                         VRTDerivedRasterBand                         */
749 /************************************************************************/
750 
751 class VRTDerivedRasterBandPrivateData;
752 
753 class CPL_DLL VRTDerivedRasterBand CPL_NON_FINAL: public VRTSourcedRasterBand
754 {
755     VRTDerivedRasterBandPrivateData* m_poPrivate;
756     bool InitializePython();
757 
758     CPL_DISALLOW_COPY_ASSIGN(VRTDerivedRasterBand)
759 
760  public:
761     char *pszFuncName;
762     GDALDataType eSourceTransferType;
763 
764     VRTDerivedRasterBand( GDALDataset *poDS, int nBand );
765     VRTDerivedRasterBand( GDALDataset *poDS, int nBand,
766                           GDALDataType eType, int nXSize, int nYSize );
767     virtual        ~VRTDerivedRasterBand();
768 
769     virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
770                               void *, int, int, GDALDataType,
771                               GSpacing nPixelSpace, GSpacing nLineSpace,
772                               GDALRasterIOExtraArg* psExtraArg ) override;
773 
774     virtual int IGetDataCoverageStatus( int nXOff, int nYOff,
775                                         int nXSize, int nYSize,
776                                         int nMaskFlagStop,
777                                         double* pdfDataPct) override;
778 
779     static CPLErr AddPixelFunction( const char *pszFuncName,
780                                     GDALDerivedPixelFunc pfnPixelFunc );
781     static GDALDerivedPixelFunc GetPixelFunction( const char *pszFuncName );
782 
783     void SetPixelFunctionName( const char *pszFuncName );
784     void SetSourceTransferType( GDALDataType eDataType );
785     void SetPixelFunctionLanguage( const char* pszLanguage );
786 
787     virtual CPLErr         XMLInit( CPLXMLNode *, const char *, void*,
788                                     std::map<CPLString, GDALDataset*>& ) override;
789     virtual CPLXMLNode *   SerializeToXML( const char *pszVRTPath ) override;
790 
791     virtual double GetMinimum( int *pbSuccess = nullptr ) override;
792     virtual double GetMaximum(int *pbSuccess = nullptr ) override;
793     virtual CPLErr ComputeRasterMinMax( int bApproxOK, double* adfMinMax ) override;
794     virtual CPLErr ComputeStatistics( int bApproxOK,
795                                       double *pdfMin, double *pdfMax,
796                                       double *pdfMean, double *pdfStdDev,
797                                       GDALProgressFunc pfnProgress,
798                                       void *pProgressData ) override;
799     virtual CPLErr  GetHistogram( double dfMin, double dfMax,
800                                   int nBuckets, GUIntBig * panHistogram,
801                                   int bIncludeOutOfRange, int bApproxOK,
802                                   GDALProgressFunc pfnProgress,
803                                   void *pProgressData ) override;
804 
805     static void Cleanup();
806 };
807 
808 /************************************************************************/
809 /*                           VRTRawRasterBand                           */
810 /************************************************************************/
811 
812 class RawRasterBand;
813 
814 class CPL_DLL VRTRawRasterBand CPL_NON_FINAL: public VRTRasterBand
815 {
816     RawRasterBand  *m_poRawRaster;
817 
818     char           *m_pszSourceFilename;
819     int            m_bRelativeToVRT;
820 
821     CPL_DISALLOW_COPY_ASSIGN(VRTRawRasterBand)
822 
823   public:
824                    VRTRawRasterBand( GDALDataset *poDS, int nBand,
825                                      GDALDataType eType = GDT_Unknown );
826     virtual        ~VRTRawRasterBand();
827 
828     virtual CPLErr         XMLInit( CPLXMLNode *, const char *, void*,
829                                     std::map<CPLString, GDALDataset*>& ) override;
830     virtual CPLXMLNode *   SerializeToXML( const char *pszVRTPath ) override;
831 
832     virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
833                               void *, int, int, GDALDataType,
834                               GSpacing nPixelSpace, GSpacing nLineSpace,
835                               GDALRasterIOExtraArg* psExtraArg ) override;
836 
837     virtual CPLErr IReadBlock( int, int, void * ) override;
838     virtual CPLErr IWriteBlock( int, int, void * ) override;
839 
840     CPLErr         SetRawLink( const char *pszFilename,
841                                const char *pszVRTPath,
842                                int bRelativeToVRT,
843                                vsi_l_offset nImageOffset,
844                                int nPixelOffset, int nLineOffset,
845                                const char *pszByteOrder );
846 
847     void           ClearRawLink();
848 
849     CPLVirtualMem *GetVirtualMemAuto( GDALRWFlag eRWFlag,
850                                       int *pnPixelSpace,
851                                       GIntBig *pnLineSpace,
852                                       char **papszOptions ) override;
853 
854     virtual void   GetFileList( char*** ppapszFileList, int *pnSize,
855                                 int *pnMaxSize, CPLHashSet* hSetFiles ) override;
856 };
857 
858 /************************************************************************/
859 /*                              VRTDriver                               */
860 /************************************************************************/
861 
862 class VRTDriver final: public GDALDriver
863 {
864     CPL_DISALLOW_COPY_ASSIGN(VRTDriver)
865 
866   public:
867                  VRTDriver();
868     virtual ~VRTDriver();
869 
870     char         **papszSourceParsers;
871 
872     virtual char      **GetMetadataDomainList() override;
873     virtual char      **GetMetadata( const char * pszDomain = "" ) override;
874     virtual CPLErr      SetMetadata( char ** papszMetadata,
875                                      const char * pszDomain = "" ) override;
876 
877     VRTSource   *ParseSource( CPLXMLNode *psSrc, const char *pszVRTPath,
878                               void* pUniqueHandle,
879                               std::map<CPLString, GDALDataset*>& oMapSharedSources );
880     void         AddSourceParser( const char *pszElementName,
881                                   VRTSourceParser pfnParser );
882 };
883 
884 /************************************************************************/
885 /*                           VRTSimpleSource                            */
886 /************************************************************************/
887 
888 class CPL_DLL VRTSimpleSource CPL_NON_FINAL: public VRTSource
889 {
890     CPL_DISALLOW_COPY_ASSIGN(VRTSimpleSource)
891 
892 protected:
893     friend class VRTSourcedRasterBand;
894     friend class VRTDataset;
895 
896     GDALRasterBand      *m_poRasterBand;
897 
898     // When poRasterBand is a mask band, poMaskBandMainBand is the band
899     // from which the mask band is taken.
900     GDALRasterBand      *m_poMaskBandMainBand;
901 
902     double              m_dfSrcXOff;
903     double              m_dfSrcYOff;
904     double              m_dfSrcXSize;
905     double              m_dfSrcYSize;
906 
907     double              m_dfDstXOff;
908     double              m_dfDstYOff;
909     double              m_dfDstXSize;
910     double              m_dfDstYSize;
911 
912     int                 m_bNoDataSet;       // should really be a member of VRTComplexSource as only taken into account by it
913     double              m_dfNoDataValue;    // same as above
914     CPLString           m_osResampling{};
915 
916     int                 m_nMaxValue;
917 
918     int                 m_bRelativeToVRTOri;
919     CPLString           m_osSourceFileNameOri{};
920     int                 m_nExplicitSharedStatus; // -1 unknown, 0 = unshared, 1 = shared
921 
922     bool                m_bDropRefOnSrcBand;
923 
924     int                 NeedMaxValAdjustment() const;
925 
926 public:
927             VRTSimpleSource();
928             VRTSimpleSource( const VRTSimpleSource* poSrcSource,
929                              double dfXDstRatio, double dfYDstRatio );
930     virtual ~VRTSimpleSource();
931 
932     virtual CPLErr  XMLInit( CPLXMLNode *psTree, const char *, void*,
933                              std::map<CPLString, GDALDataset*>& ) override;
934     virtual CPLXMLNode *SerializeToXML( const char *pszVRTPath ) override;
935 
936     void           SetSrcBand( GDALRasterBand * );
937     void           SetSrcMaskBand( GDALRasterBand * );
938     void           SetSrcWindow( double, double, double, double );
939     void           SetDstWindow( double, double, double, double );
940     void           SetNoDataValue( double dfNoDataValue );  // should really be a member of VRTComplexSource
941     const CPLString& GetResampling() const { return m_osResampling; }
942     void           SetResampling( const char* pszResampling );
943 
944     int            GetSrcDstWindow( int, int, int, int, int, int,
945                                     double *pdfReqXOff, double *pdfReqYOff,
946                                     double *pdfReqXSize, double *pdfReqYSize,
947                                     int *, int *, int *, int *,
948                                     int *, int *, int *, int * );
949 
950     virtual CPLErr  RasterIO( GDALDataType eBandDataType,
951                               int nXOff, int nYOff, int nXSize, int nYSize,
952                               void *pData, int nBufXSize, int nBufYSize,
953                               GDALDataType eBufType,
954                               GSpacing nPixelSpace, GSpacing nLineSpace,
955                               GDALRasterIOExtraArg* psExtraArgIn ) override;
956 
957     virtual double GetMinimum( int nXSize, int nYSize, int *pbSuccess ) override;
958     virtual double GetMaximum( int nXSize, int nYSize, int *pbSuccess ) override;
959     virtual CPLErr ComputeRasterMinMax( int nXSize, int nYSize, int bApproxOK,
960                                         double* adfMinMax ) override;
961     virtual CPLErr ComputeStatistics( int nXSize, int nYSize,
962                                       int bApproxOK,
963                                       double *pdfMin, double *pdfMax,
964                                       double *pdfMean, double *pdfStdDev,
965                                       GDALProgressFunc pfnProgress,
966                                       void *pProgressData ) override;
967     virtual CPLErr  GetHistogram( int nXSize, int nYSize,
968                                   double dfMin, double dfMax,
969                                   int nBuckets, GUIntBig * panHistogram,
970                                   int bIncludeOutOfRange, int bApproxOK,
971                                   GDALProgressFunc pfnProgress,
972                                   void *pProgressData ) override;
973 
974     void            DstToSrc( double dfX, double dfY,
975                               double &dfXOut, double &dfYOut ) const;
976     void            SrcToDst( double dfX, double dfY,
977                               double &dfXOut, double &dfYOut ) const;
978 
979     virtual void   GetFileList( char*** ppapszFileList, int *pnSize,
980                                 int *pnMaxSize, CPLHashSet* hSetFiles ) override;
981 
982     virtual int    IsSimpleSource() override { return TRUE; }
983     virtual const char* GetType() { return "SimpleSource"; }
984     virtual CPLErr FlushCache() override;
985 
986     GDALRasterBand* GetBand();
987     GDALRasterBand* GetMaskBandMainBand() { return m_poMaskBandMainBand; }
988     int             IsSameExceptBandNumber( VRTSimpleSource* poOtherSource );
989     CPLErr          DatasetRasterIO(
990                                GDALDataType eBandDataType,
991                                int nXOff, int nYOff, int nXSize, int nYSize,
992                                void * pData, int nBufXSize, int nBufYSize,
993                                GDALDataType eBufType,
994                                int nBandCount, int *panBandMap,
995                                GSpacing nPixelSpace, GSpacing nLineSpace,
996                                GSpacing nBandSpace,
997                                GDALRasterIOExtraArg* psExtraArg );
998 
999     void             UnsetPreservedRelativeFilenames();
1000 
1001     void             SetMaxValue( int nVal ) { m_nMaxValue = nVal; }
1002 };
1003 
1004 /************************************************************************/
1005 /*                          VRTAveragedSource                           */
1006 /************************************************************************/
1007 
1008 class VRTAveragedSource final: public VRTSimpleSource
1009 {
1010     CPL_DISALLOW_COPY_ASSIGN(VRTAveragedSource)
1011 
1012 public:
1013                     VRTAveragedSource();
1014     virtual CPLErr  RasterIO( GDALDataType eBandDataType,
1015                               int nXOff, int nYOff, int nXSize, int nYSize,
1016                               void *pData, int nBufXSize, int nBufYSize,
1017                               GDALDataType eBufType,
1018                               GSpacing nPixelSpace, GSpacing nLineSpace,
1019                               GDALRasterIOExtraArg* psExtraArgIn ) override;
1020 
1021     virtual double GetMinimum( int nXSize, int nYSize, int *pbSuccess ) override;
1022     virtual double GetMaximum( int nXSize, int nYSize, int *pbSuccess ) override;
1023     virtual CPLErr ComputeRasterMinMax( int nXSize, int nYSize, int bApproxOK,
1024                                         double* adfMinMax ) override;
1025     virtual CPLErr ComputeStatistics( int nXSize, int nYSize,
1026                                       int bApproxOK,
1027                                       double *pdfMin, double *pdfMax,
1028                                       double *pdfMean, double *pdfStdDev,
1029                                       GDALProgressFunc pfnProgress,
1030                                       void *pProgressData ) override;
1031     virtual CPLErr  GetHistogram( int nXSize, int nYSize,
1032                                   double dfMin, double dfMax,
1033                                   int nBuckets, GUIntBig * panHistogram,
1034                                   int bIncludeOutOfRange, int bApproxOK,
1035                                   GDALProgressFunc pfnProgress,
1036                                   void *pProgressData ) override;
1037 
1038     virtual CPLXMLNode *SerializeToXML( const char *pszVRTPath ) override;
1039     virtual const char* GetType() override { return "AveragedSource"; }
1040 };
1041 
1042 /************************************************************************/
1043 /*                           VRTComplexSource                           */
1044 /************************************************************************/
1045 
1046 typedef enum
1047 {
1048     VRT_SCALING_NONE,
1049     VRT_SCALING_LINEAR,
1050     VRT_SCALING_EXPONENTIAL,
1051 } VRTComplexSourceScaling;
1052 
1053 class CPL_DLL VRTComplexSource CPL_NON_FINAL: public VRTSimpleSource
1054 {
1055     CPL_DISALLOW_COPY_ASSIGN(VRTComplexSource)
1056     bool           AreValuesUnchanged() const;
1057 
1058 protected:
1059     VRTComplexSourceScaling m_eScalingType;
1060     double         m_dfScaleOff;  // For linear scaling.
1061     double         m_dfScaleRatio;  // For linear scaling.
1062 
1063     // For non-linear scaling with a power function.
1064     int            m_bSrcMinMaxDefined;
1065     double         m_dfSrcMin;
1066     double         m_dfSrcMax;
1067     double         m_dfDstMin;
1068     double         m_dfDstMax;
1069     double         m_dfExponent;
1070 
1071     int            m_nColorTableComponent;
1072 
1073     bool           m_bUseMaskBand = false;
1074 
1075     template <class WorkingDT>
1076     CPLErr          RasterIOInternal( int nReqXOff, int nReqYOff,
1077                                       int nReqXSize, int nReqYSize,
1078                                       void *pData, int nOutXSize, int nOutYSize,
1079                                       GDALDataType eBufType,
1080                                       GSpacing nPixelSpace, GSpacing nLineSpace,
1081                                       GDALRasterIOExtraArg* psExtraArg,
1082                                       GDALDataType eWrkDataType );
1083 
1084 public:
1085                    VRTComplexSource();
1086                    VRTComplexSource(const VRTComplexSource* poSrcSource,
1087                                     double dfXDstRatio, double dfYDstRatio);
1088     virtual        ~VRTComplexSource();
1089 
1090     virtual CPLErr RasterIO( GDALDataType eBandDataType,
1091                              int nXOff, int nYOff, int nXSize, int nYSize,
1092                              void *pData, int nBufXSize, int nBufYSize,
1093                              GDALDataType eBufType,
1094                              GSpacing nPixelSpace, GSpacing nLineSpace,
1095                              GDALRasterIOExtraArg* psExtraArgIn ) override;
1096 
1097     virtual double GetMinimum( int nXSize, int nYSize, int *pbSuccess ) override;
1098     virtual double GetMaximum( int nXSize, int nYSize, int *pbSuccess ) override;
1099     virtual CPLErr ComputeRasterMinMax( int nXSize, int nYSize, int bApproxOK,
1100                                         double* adfMinMax ) override;
1101     virtual CPLErr ComputeStatistics( int nXSize, int nYSize,
1102                                       int bApproxOK,
1103                                       double *pdfMin, double *pdfMax,
1104                                       double *pdfMean, double *pdfStdDev,
1105                                       GDALProgressFunc pfnProgress,
1106                                       void *pProgressData ) override;
1107     virtual CPLErr  GetHistogram( int nXSize, int nYSize,
1108                                   double dfMin, double dfMax,
1109                                   int nBuckets, GUIntBig * panHistogram,
1110                                   int bIncludeOutOfRange, int bApproxOK,
1111                                   GDALProgressFunc pfnProgress,
1112                                   void *pProgressData ) override;
1113 
1114     virtual CPLXMLNode *SerializeToXML( const char *pszVRTPath ) override;
1115     virtual CPLErr XMLInit( CPLXMLNode *, const char *, void*,
1116                             std::map<CPLString, GDALDataset*>& ) override;
1117     virtual const char* GetType() override { return "ComplexSource"; }
1118 
1119     double  LookupValue( double dfInput );
1120 
1121     void    SetUseMaskBand(bool bUseMaskBand) { m_bUseMaskBand = bUseMaskBand; }
1122 
1123     void    SetLinearScaling( double dfOffset, double dfScale );
1124     void    SetPowerScaling( double dfExponent,
1125                              double dfSrcMin,
1126                              double dfSrcMax,
1127                              double dfDstMin,
1128                              double dfDstMax );
1129     void    SetColorTableComponent( int nComponent );
1130 
1131     double         *m_padfLUTInputs;
1132     double         *m_padfLUTOutputs;
1133     int            m_nLUTItemCount;
1134 };
1135 
1136 /************************************************************************/
1137 /*                           VRTFilteredSource                          */
1138 /************************************************************************/
1139 
1140 class VRTFilteredSource CPL_NON_FINAL: public VRTComplexSource
1141 {
1142 private:
1143     int          IsTypeSupported( GDALDataType eTestType ) const;
1144 
1145     CPL_DISALLOW_COPY_ASSIGN(VRTFilteredSource)
1146 
1147 protected:
1148     int          m_nSupportedTypesCount;
1149     GDALDataType m_aeSupportedTypes[20];
1150 
1151     int          m_nExtraEdgePixels;
1152 
1153 public:
1154             VRTFilteredSource();
1155     virtual ~VRTFilteredSource();
1156 
1157     void    SetExtraEdgePixels( int );
1158     void    SetFilteringDataTypesSupported( int, GDALDataType * );
1159 
1160     virtual CPLErr  FilterData( int nXSize, int nYSize, GDALDataType eType,
1161                                 GByte *pabySrcData, GByte *pabyDstData ) = 0;
1162 
1163     virtual CPLErr  RasterIO( GDALDataType eBandDataType,
1164                               int nXOff, int nYOff, int nXSize, int nYSize,
1165                               void *pData, int nBufXSize, int nBufYSize,
1166                               GDALDataType eBufType,
1167                               GSpacing nPixelSpace, GSpacing nLineSpace,
1168                               GDALRasterIOExtraArg* psExtraArg ) override;
1169 };
1170 
1171 /************************************************************************/
1172 /*                       VRTKernelFilteredSource                        */
1173 /************************************************************************/
1174 
1175 class VRTKernelFilteredSource CPL_NON_FINAL: public VRTFilteredSource
1176 {
1177     CPL_DISALLOW_COPY_ASSIGN(VRTKernelFilteredSource)
1178 
1179 protected:
1180     int     m_nKernelSize;
1181 
1182     bool    m_bSeparable;
1183 
1184     double  *m_padfKernelCoefs;
1185 
1186     int     m_bNormalized;
1187 
1188 public:
1189             VRTKernelFilteredSource();
1190     virtual ~VRTKernelFilteredSource();
1191 
1192     virtual CPLErr  XMLInit( CPLXMLNode *psTree, const char *, void*,
1193                              std::map<CPLString, GDALDataset*>& ) override;
1194     virtual CPLXMLNode *SerializeToXML( const char *pszVRTPath ) override;
1195 
1196     virtual CPLErr  FilterData( int nXSize, int nYSize, GDALDataType eType,
1197                                 GByte *pabySrcData, GByte *pabyDstData ) override;
1198 
1199     CPLErr          SetKernel( int nKernelSize, bool bSeparable, double *padfCoefs );
1200     void            SetNormalized( int );
1201 };
1202 
1203 /************************************************************************/
1204 /*                       VRTAverageFilteredSource                       */
1205 /************************************************************************/
1206 
1207 class VRTAverageFilteredSource final: public VRTKernelFilteredSource
1208 {
1209     CPL_DISALLOW_COPY_ASSIGN(VRTAverageFilteredSource)
1210 
1211 public:
1212             explicit VRTAverageFilteredSource( int nKernelSize );
1213     virtual ~VRTAverageFilteredSource();
1214 
1215     virtual CPLErr  XMLInit( CPLXMLNode *psTree, const char *, void*,
1216                              std::map<CPLString, GDALDataset*>& ) override;
1217     virtual CPLXMLNode *SerializeToXML( const char *pszVRTPath ) override;
1218 };
1219 
1220 /************************************************************************/
1221 /*                            VRTFuncSource                             */
1222 /************************************************************************/
1223 class VRTFuncSource final: public VRTSource
1224 {
1225     CPL_DISALLOW_COPY_ASSIGN(VRTFuncSource)
1226 
1227 public:
1228             VRTFuncSource();
1229     virtual ~VRTFuncSource();
1230 
1231     virtual CPLErr  XMLInit( CPLXMLNode *, const char *, void*,
1232                              std::map<CPLString, GDALDataset*>& ) override { return CE_Failure; }
1233     virtual CPLXMLNode *SerializeToXML( const char *pszVRTPath ) override;
1234 
1235     virtual CPLErr  RasterIO( GDALDataType eBandDataType,
1236                               int nXOff, int nYOff, int nXSize, int nYSize,
1237                               void *pData, int nBufXSize, int nBufYSize,
1238                               GDALDataType eBufType,
1239                               GSpacing nPixelSpace, GSpacing nLineSpace,
1240                               GDALRasterIOExtraArg* psExtraArg ) override;
1241 
1242     virtual double GetMinimum( int nXSize, int nYSize, int *pbSuccess ) override;
1243     virtual double GetMaximum( int nXSize, int nYSize, int *pbSuccess ) override;
1244     virtual CPLErr ComputeRasterMinMax( int nXSize, int nYSize, int bApproxOK,
1245                                         double* adfMinMax ) override;
1246     virtual CPLErr ComputeStatistics( int nXSize, int nYSize,
1247                                       int bApproxOK,
1248                                       double *pdfMin, double *pdfMax,
1249                                       double *pdfMean, double *pdfStdDev,
1250                                       GDALProgressFunc pfnProgress,
1251                                       void *pProgressData ) override;
1252     virtual CPLErr  GetHistogram( int nXSize, int nYSize,
1253                                   double dfMin, double dfMax,
1254                                   int nBuckets, GUIntBig * panHistogram,
1255                                   int bIncludeOutOfRange, int bApproxOK,
1256                                   GDALProgressFunc pfnProgress,
1257                                   void *pProgressData ) override;
1258 
1259     VRTImageReadFunc    pfnReadFunc;
1260     void               *pCBData;
1261     GDALDataType        eType;
1262 
1263     float               fNoDataValue;
1264 };
1265 
1266 /************************************************************************/
1267 /*                              VRTGroup                                */
1268 /************************************************************************/
1269 
1270 #ifdef TMPEXPORT
1271 #define TMP_CPL_DLL CPL_DLL
1272 #else
1273 #define TMP_CPL_DLL
1274 #endif
1275 
1276 class VRTMDArray;
1277 class VRTAttribute;
1278 class VRTDimension;
1279 
1280 class VRTGroup final: public GDALGroup
1281 {
1282 public:
1283     struct Ref
1284     {
1285         VRTGroup* m_ptr;
1286         explicit Ref(VRTGroup* ptr): m_ptr(ptr) {}
1287         Ref(const Ref&) = delete;
1288         Ref& operator=(const Ref&) = delete;
1289     };
1290 
1291 private:
1292     std::shared_ptr<Ref> m_poSharedRefRootGroup{};
1293     std::weak_ptr<Ref> m_poWeakRefRootGroup{};
1294     std::shared_ptr<Ref> m_poRefSelf{};
1295 
1296     std::string m_osFilename{};
1297     mutable bool m_bDirty = false;
1298     std::string m_osVRTPath{};
1299     std::map<std::string, std::shared_ptr<VRTGroup>> m_oMapGroups{};
1300     std::map<std::string, std::shared_ptr<VRTMDArray>> m_oMapMDArrays{};
1301     std::map<std::string, std::shared_ptr<VRTAttribute>> m_oMapAttributes{};
1302     std::map<std::string, std::shared_ptr<VRTDimension>> m_oMapDimensions{};
1303 
1304     std::shared_ptr<VRTGroup> OpenGroupInternal(const std::string& osName) const;
1305     void SetRootGroupRef(const std::weak_ptr<Ref>& rgRef);
1306     std::weak_ptr<Ref> GetRootGroupRef() const;
1307 
1308 public:
1309 
1310     VRTGroup(const std::string& osParentName, const std::string& osName);
1311     ~VRTGroup();
1312 
1313     bool XMLInit(const std::shared_ptr<VRTGroup>& poRoot,
1314                  const std::shared_ptr<VRTGroup>& poThisGroup,
1315                  const CPLXMLNode* psNode,
1316                  const char* pszVRTPath);
1317 
1318     std::vector<std::string> GetMDArrayNames(CSLConstList papszOptions) const override;
1319     std::shared_ptr<GDALMDArray> OpenMDArray(const std::string& osName,
1320                                              CSLConstList papszOptions = nullptr) const override;
1321 
1322     std::vector<std::string> GetGroupNames(CSLConstList papszOptions) const override;
1323     std::shared_ptr<GDALGroup> OpenGroup(const std::string& osName,
1324                                          CSLConstList) const override
1325     {
1326         return OpenGroupInternal(osName);
1327     }
1328 
1329     std::vector<std::shared_ptr<GDALDimension>> GetDimensions(CSLConstList) const override;
1330 
1331     std::vector<std::shared_ptr<GDALAttribute>> GetAttributes(CSLConstList) const override;
1332 
1333     std::shared_ptr<VRTDimension> GetDimension(const std::string& name) const {
1334         auto oIter = m_oMapDimensions.find(name);
1335         return oIter == m_oMapDimensions.end() ? nullptr : oIter->second;
1336     }
1337     std::shared_ptr<VRTDimension> GetDimensionFromFullName(const std::string& name,
1338                                                            bool bEmitError) const;
1339 
1340     std::shared_ptr<GDALGroup> CreateGroup(const std::string& osName,
1341                                            CSLConstList papszOptions = nullptr) override;
1342 
1343     std::shared_ptr<GDALDimension> CreateDimension(const std::string& osName,
1344                                                            const std::string& osType,
1345                                                            const std::string& osDirection,
1346                                                            GUInt64 nSize,
1347                                                            CSLConstList papszOptions = nullptr) override;
1348 
1349     std::shared_ptr<GDALAttribute> CreateAttribute(
1350         const std::string& osName,
1351         const std::vector<GUInt64>& anDimensions,
1352         const GDALExtendedDataType& oDataType,
1353         CSLConstList papszOptions = nullptr) override;
1354 
1355     std::shared_ptr<GDALMDArray> CreateMDArray(const std::string& osName,
1356                                                        const std::vector<std::shared_ptr<GDALDimension>>& aoDimensions,
1357                                                        const GDALExtendedDataType& oDataType,
1358                                                        CSLConstList papszOptions) override;
1359 
1360     void SetIsRootGroup();
1361 
1362     const std::shared_ptr<Ref>& GetRef() const { return m_poRefSelf; }
1363     VRTGroup* GetRootGroup() const;
1364 
1365     const std::string& GetVRTPath() const { return m_osVRTPath; }
1366     void SetDirty();
1367     void SetFilename(const std::string& osFilename) { m_osFilename = osFilename; }
1368     void Serialize() const;
1369     CPLXMLNode* SerializeToXML( const char *pszVRTPathIn ) const;
1370     void Serialize(CPLXMLNode* psParent, const char *pszVRTPathIn) const;
1371 };
1372 
1373 /************************************************************************/
1374 /*                            VRTDimension                              */
1375 /************************************************************************/
1376 
1377 class VRTDimension final: public GDALDimension
1378 {
1379     std::weak_ptr<VRTGroup::Ref> m_poGroupRef;
1380     std::string m_osIndexingVariableName;
1381 
1382 public:
1383     VRTDimension(const std::shared_ptr<VRTGroup::Ref>& poGroupRef,
1384                   const std::string& osParentName,
1385                   const std::string& osName,
1386                   const std::string& osType,
1387                   const std::string& osDirection,
1388                   GUInt64 nSize,
1389                   const std::string& osIndexingVariableName):
1390         GDALDimension(osParentName, osName, osType, osDirection, nSize),
1391         m_poGroupRef(poGroupRef),
1392         m_osIndexingVariableName(osIndexingVariableName)
1393     {}
1394 
1395     VRTGroup* GetGroup() const;
1396 
1397     static std::shared_ptr<VRTDimension> Create(const std::shared_ptr<VRTGroup>& poThisGroup,
1398                                                 const std::string& osParentName,
1399                                                 const CPLXMLNode* psNode);
1400 
1401     std::shared_ptr<GDALMDArray> GetIndexingVariable() const override;
1402 
1403     bool SetIndexingVariable(std::shared_ptr<GDALMDArray> poIndexingVariable) override;
1404 
1405     void Serialize(CPLXMLNode* psParent) const;
1406 };
1407 
1408 /************************************************************************/
1409 /*                            VRTAttribute                              */
1410 /************************************************************************/
1411 
1412 class VRTAttribute final: public GDALAttribute
1413 {
1414     GDALExtendedDataType m_dt;
1415     std::vector<std::string> m_aosList{};
1416     std::vector<std::shared_ptr<GDALDimension>> m_dims{};
1417 
1418 protected:
1419 
1420     bool IRead(const GUInt64* arrayStartIdx,
1421                       const size_t* count,
1422                       const GInt64* arrayStep,
1423                       const GPtrDiff_t* bufferStride,
1424                       const GDALExtendedDataType& bufferDataType,
1425                       void* pDstBuffer) const override;
1426 
1427     bool IWrite(const GUInt64* arrayStartIdx,
1428                       const size_t* count,
1429                       const GInt64* arrayStep,
1430                       const GPtrDiff_t* bufferStride,
1431                       const GDALExtendedDataType& bufferDataType,
1432                       const void* pSrcBuffer) override;
1433 
1434 
1435 public:
1436     VRTAttribute(const std::string& osParentName,
1437                  const std::string& osName,
1438                  const GDALExtendedDataType& dt,
1439                  std::vector<std::string>&& aosList):
1440         GDALAbstractMDArray(osParentName, osName),
1441         GDALAttribute(osParentName, osName),
1442         m_dt(dt),
1443         m_aosList(std::move(aosList))
1444     {
1445         if( m_aosList.size() > 1 )
1446         {
1447             m_dims.emplace_back(std::make_shared<GDALDimension>(
1448                 std::string(), "dim",
1449                 std::string(), std::string(), m_aosList.size()));
1450         }
1451     }
1452 
1453     VRTAttribute(const std::string& osParentName,
1454                  const std::string& osName,
1455                  GUInt64 nDim,
1456                  const GDALExtendedDataType& dt):
1457         GDALAbstractMDArray(osParentName, osName),
1458         GDALAttribute(osParentName, osName),
1459         m_dt(dt)
1460     {
1461         if( nDim != 0 )
1462         {
1463             m_dims.emplace_back(std::make_shared<GDALDimension>(
1464                 std::string(), "dim",
1465                 std::string(), std::string(), nDim));
1466         }
1467     }
1468 
1469     static bool CreationCommonChecks(const std::string& osName,
1470                                      const std::vector<GUInt64>& anDimensions,
1471                                      const std::map<std::string, std::shared_ptr<VRTAttribute>>& oMapAttributes);
1472 
1473     static std::shared_ptr<VRTAttribute> Create(const std::string& osParentName,
1474                                                 const CPLXMLNode* psNode);
1475 
1476     const std::vector<std::shared_ptr<GDALDimension>>& GetDimensions() const override { return m_dims; }
1477 
1478     const GDALExtendedDataType &GetDataType() const override { return m_dt; }
1479 
1480     void Serialize(CPLXMLNode* psParent) const;
1481 };
1482 
1483 /************************************************************************/
1484 /*                          VRTMDArraySource                            */
1485 /************************************************************************/
1486 
1487 class VRTMDArraySource
1488 {
1489 public:
1490     virtual ~VRTMDArraySource() = default;
1491 
1492     virtual bool Read(const GUInt64* arrayStartIdx,
1493                       const size_t* count,
1494                       const GInt64* arrayStep,
1495                       const GPtrDiff_t* bufferStride,
1496                       const GDALExtendedDataType& bufferDataType,
1497                       void* pDstBuffer) const = 0;
1498 
1499     virtual void Serialize(CPLXMLNode* psParent, const char* pszVRTPath) const = 0;
1500 };
1501 
1502 /************************************************************************/
1503 /*                            VRTMDArray                                */
1504 /************************************************************************/
1505 
1506 class VRTMDArray final: public GDALMDArray
1507 {
1508 protected:
1509     friend class VRTGroup; // for access to SetSelf()
1510 
1511     std::weak_ptr<VRTGroup::Ref> m_poGroupRef;
1512     std::string m_osVRTPath{};
1513 
1514     GDALExtendedDataType m_dt;
1515     std::vector<std::shared_ptr<GDALDimension>> m_dims;
1516     std::map<std::string, std::shared_ptr<VRTAttribute>> m_oMapAttributes{};
1517     std::vector<std::unique_ptr<VRTMDArraySource>> m_sources{};
1518     std::shared_ptr<OGRSpatialReference> m_poSRS{};
1519     std::vector<GByte> m_abyNoData{};
1520     std::string m_osUnit{};
1521     double m_dfScale = 1.0;
1522     double m_dfOffset = 0.0;
1523     bool m_bHasScale = false;
1524     bool m_bHasOffset = false;
1525 
1526     bool IRead(const GUInt64* arrayStartIdx,
1527                       const size_t* count,
1528                       const GInt64* arrayStep,
1529                       const GPtrDiff_t* bufferStride,
1530                       const GDALExtendedDataType& bufferDataType,
1531                       void* pDstBuffer) const override;
1532 
1533     void SetDirty();
1534 
1535 public:
1536     VRTMDArray(const std::shared_ptr<VRTGroup::Ref>& poGroupRef,
1537                const std::string& osParentName,
1538                const std::string& osName,
1539                const GDALExtendedDataType& dt,
1540                std::vector<std::shared_ptr<GDALDimension>>&& dims,
1541                std::map<std::string, std::shared_ptr<VRTAttribute>>&& oMapAttributes) :
1542         GDALAbstractMDArray(osParentName, osName),
1543         GDALMDArray(osParentName, osName),
1544         m_poGroupRef(poGroupRef),
1545         m_osVRTPath(poGroupRef->m_ptr->GetVRTPath()),
1546         m_dt(dt),
1547         m_dims(std::move(dims)),
1548         m_oMapAttributes(std::move(oMapAttributes))
1549     {
1550     }
1551 
1552     VRTMDArray(const std::shared_ptr<VRTGroup::Ref>& poGroupRef,
1553                const std::string& osParentName,
1554                const std::string& osName,
1555                const std::vector<std::shared_ptr<GDALDimension>>& dims,
1556                const GDALExtendedDataType& dt) :
1557         GDALAbstractMDArray(osParentName, osName),
1558         GDALMDArray(osParentName, osName),
1559         m_poGroupRef(poGroupRef),
1560         m_osVRTPath(poGroupRef->m_ptr->GetVRTPath()),
1561         m_dt(dt),
1562         m_dims(dims)
1563     {
1564     }
1565 
1566     bool IsWritable() const override { return false; }
1567 
1568     static std::shared_ptr<VRTMDArray> Create(const std::shared_ptr<VRTGroup>& poThisGroup,
1569                                               const std::string& osParentName,
1570                                               const CPLXMLNode* psNode);
1571 
1572     const std::vector<std::shared_ptr<GDALDimension>>& GetDimensions() const override { return m_dims; }
1573 
1574     std::vector<std::shared_ptr<GDALAttribute>> GetAttributes(CSLConstList) const override;
1575 
1576     const GDALExtendedDataType &GetDataType() const override { return m_dt; }
1577 
1578     bool SetSpatialRef(const OGRSpatialReference* poSRS) override;
1579 
1580     std::shared_ptr<OGRSpatialReference> GetSpatialRef() const override { return m_poSRS; }
1581 
1582     const void* GetRawNoDataValue() const override;
1583 
1584     bool SetRawNoDataValue(const void* pRawNoData) override;
1585 
1586     const std::string& GetUnit() const override { return m_osUnit; }
1587 
1588     bool SetUnit(const std::string& osUnit) override {
1589         m_osUnit = osUnit; return true; }
1590 
1591     double GetOffset(bool* pbHasOffset, GDALDataType* peStorageType) const override
1592     {
1593         if( pbHasOffset) *pbHasOffset = m_bHasOffset;
1594         if( peStorageType ) *peStorageType = GDT_Unknown;
1595         return m_dfOffset;
1596     }
1597 
1598     double GetScale(bool* pbHasScale, GDALDataType* peStorageType) const override
1599     {
1600         if( pbHasScale) *pbHasScale = m_bHasScale;
1601         if( peStorageType ) *peStorageType = GDT_Unknown;
1602         return m_dfScale;
1603     }
1604 
1605     bool SetOffset(double dfOffset, GDALDataType /* eStorageType */ = GDT_Unknown) override
1606     { SetDirty(); m_bHasOffset = true; m_dfOffset = dfOffset; return true; }
1607 
1608     bool SetScale(double dfScale, GDALDataType /* eStorageType */ = GDT_Unknown) override
1609     { SetDirty(); m_bHasScale = true; m_dfScale = dfScale; return true; }
1610 
1611     void AddSource(std::unique_ptr<VRTMDArraySource>&& poSource);
1612 
1613     std::shared_ptr<GDALAttribute> CreateAttribute(
1614         const std::string& osName,
1615         const std::vector<GUInt64>& anDimensions,
1616         const GDALExtendedDataType& oDataType,
1617         CSLConstList papszOptions = nullptr) override;
1618 
1619     bool CopyFrom(GDALDataset* poSrcDS,
1620                           const GDALMDArray* poSrcArray,
1621                           bool bStrict,
1622                           GUInt64& nCurCost,
1623                           const GUInt64 nTotalCost,
1624                           GDALProgressFunc pfnProgress,
1625                           void * pProgressData) override;
1626 
1627     void Serialize(CPLXMLNode* psParent, const char *pszVRTPathIn ) const;
1628 
1629     VRTGroup* GetGroup() const;
1630 
1631     const std::string& GetVRTPath() const { return m_osVRTPath; }
1632 };
1633 
1634 /************************************************************************/
1635 /*                       VRTMDArraySourceInlinedValues                  */
1636 /************************************************************************/
1637 
1638 class VRTMDArraySourceInlinedValues final: public VRTMDArraySource
1639 {
1640     const VRTMDArray* m_poDstArray = nullptr;
1641     bool m_bIsConstantValue;
1642     std::vector<GUInt64> m_anOffset{};
1643     std::vector<size_t> m_anCount{};
1644     std::vector<GByte> m_abyValues{};
1645     std::vector<size_t> m_anInlinedArrayStrideInBytes{};
1646     GDALExtendedDataType m_dt;
1647 
1648     VRTMDArraySourceInlinedValues(const VRTMDArraySourceInlinedValues&) = delete;
1649     VRTMDArraySourceInlinedValues& operator=(const VRTMDArraySourceInlinedValues&) = delete;
1650 
1651 public:
1652     VRTMDArraySourceInlinedValues(const VRTMDArray* poDstArray,
1653                                   bool bIsConstantValue,
1654                                   std::vector<GUInt64>&& anOffset,
1655                                   std::vector<size_t>&& anCount,
1656                                   std::vector<GByte>&& abyValues):
1657         m_poDstArray(poDstArray),
1658         m_bIsConstantValue(bIsConstantValue),
1659         m_anOffset(std::move(anOffset)),
1660         m_anCount(std::move(anCount)),
1661         m_abyValues(std::move(abyValues)),
1662         m_dt(poDstArray->GetDataType())
1663     {
1664         const auto nDims(poDstArray->GetDimensionCount());
1665         m_anInlinedArrayStrideInBytes.resize(nDims);
1666         if( !bIsConstantValue && nDims > 0 )
1667         {
1668             m_anInlinedArrayStrideInBytes.back() = poDstArray->GetDataType().GetSize();
1669             for(size_t i = nDims - 1; i > 0; )
1670             {
1671                 --i;
1672                 m_anInlinedArrayStrideInBytes[i] =
1673                     m_anInlinedArrayStrideInBytes[i+1] * m_anCount[i+1];
1674             }
1675         }
1676     }
1677 
1678     ~VRTMDArraySourceInlinedValues();
1679 
1680     static std::unique_ptr<VRTMDArraySourceInlinedValues> Create(
1681                                                 const VRTMDArray* poDstArray,
1682                                                 const CPLXMLNode* psNode);
1683 
1684     bool Read(const GUInt64* arrayStartIdx,
1685                       const size_t* count,
1686                       const GInt64* arrayStep,
1687                       const GPtrDiff_t* bufferStride,
1688                       const GDALExtendedDataType& bufferDataType,
1689                       void* pDstBuffer) const override;
1690 
1691     void Serialize(CPLXMLNode* psParent, const char* pszVRTPath) const override;
1692 };
1693 
1694 /************************************************************************/
1695 /*                     VRTMDArraySourceRegularlySpaced                  */
1696 /************************************************************************/
1697 
1698 class VRTMDArraySourceRegularlySpaced final: public VRTMDArraySource
1699 {
1700     double m_dfStart;
1701     double m_dfIncrement;
1702 
1703 public:
1704     VRTMDArraySourceRegularlySpaced(
1705                  double dfStart, double dfIncrement):
1706         m_dfStart(dfStart),
1707         m_dfIncrement(dfIncrement)
1708     {
1709     }
1710 
1711     bool Read(const GUInt64* arrayStartIdx,
1712                       const size_t* count,
1713                       const GInt64* arrayStep,
1714                       const GPtrDiff_t* bufferStride,
1715                       const GDALExtendedDataType& bufferDataType,
1716                       void* pDstBuffer) const override;
1717 
1718     void Serialize(CPLXMLNode* psParent, const char* pszVRTPath) const override;
1719 };
1720 
1721 /************************************************************************/
1722 /*                       VRTMDArraySourceFromArray                      */
1723 /************************************************************************/
1724 
1725 class VRTMDArraySourceFromArray final: public VRTMDArraySource
1726 {
1727     const VRTMDArray* m_poDstArray = nullptr;
1728     bool m_bRelativeToVRTSet = false;
1729     bool m_bRelativeToVRT = false;
1730     std::string m_osFilename{};
1731     std::string m_osArray{};
1732     std::string m_osBand{};
1733     std::vector<int> m_anTransposedAxis{};
1734     std::string m_osViewExpr{};
1735     std::vector<GUInt64> m_anSrcOffset{};
1736     mutable std::vector<GUInt64> m_anCount{};
1737     std::vector<GUInt64> m_anStep{};
1738     std::vector<GUInt64> m_anDstOffset{};
1739 
1740     VRTMDArraySourceFromArray(const VRTMDArraySourceFromArray&) = delete;
1741     VRTMDArraySourceFromArray& operator=(const VRTMDArraySourceFromArray&) = delete;
1742 
1743 public:
1744     VRTMDArraySourceFromArray(const VRTMDArray* poDstArray,
1745                               bool bRelativeToVRTSet,
1746                               bool bRelativeToVRT,
1747                               const std::string& osFilename,
1748                               const std::string& osArray,
1749                               const std::string& osBand,
1750                               std::vector<int>&& anTransposedAxis,
1751                               const std::string& osViewExpr,
1752                               std::vector<GUInt64>&& anSrcOffset,
1753                               std::vector<GUInt64>&& anCount,
1754                               std::vector<GUInt64>&& anStep,
1755                               std::vector<GUInt64>&& anDstOffset):
1756         m_poDstArray(poDstArray),
1757         m_bRelativeToVRTSet(bRelativeToVRTSet),
1758         m_bRelativeToVRT(bRelativeToVRT),
1759         m_osFilename(osFilename),
1760         m_osArray(osArray),
1761         m_osBand(osBand),
1762         m_anTransposedAxis(std::move(anTransposedAxis)),
1763         m_osViewExpr(osViewExpr),
1764         m_anSrcOffset(std::move(anSrcOffset)),
1765         m_anCount(std::move(anCount)),
1766         m_anStep(std::move(anStep)),
1767         m_anDstOffset(std::move(anDstOffset))
1768     {
1769     }
1770 
1771     ~VRTMDArraySourceFromArray() override;
1772 
1773     static std::unique_ptr<VRTMDArraySourceFromArray> Create(
1774                                                 const VRTMDArray* poDstArray,
1775                                                 const CPLXMLNode* psNode);
1776 
1777     bool Read(const GUInt64* arrayStartIdx,
1778                       const size_t* count,
1779                       const GInt64* arrayStep,
1780                       const GPtrDiff_t* bufferStride,
1781                       const GDALExtendedDataType& bufferDataType,
1782                       void* pDstBuffer) const override;
1783 
1784     void Serialize(CPLXMLNode* psParent, const char* pszVRTPath) const override;
1785 };
1786 
1787 #endif /* #ifndef DOXYGEN_SKIP */
1788 
1789 #endif /* ndef VIRTUALDATASET_H_INCLUDED */
1790