Coverage Report

Created: 2026-04-01 06:20

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