Coverage Report

Created: 2025-11-16 06:25

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