Coverage Report

Created: 2025-08-28 06:57

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