Coverage Report

Created: 2026-04-10 07:04

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