Coverage Report

Created: 2025-06-22 06:59

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