Coverage Report

Created: 2026-07-25 06:50

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