Coverage Report

Created: 2025-12-31 06:48

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
    int GetSrcDstWindow(double, double, double, double, int, int,
1484
                        GDALRIOResampleAlg eResampleAlg, double *pdfReqXOff,
1485
                        double *pdfReqYOff, double *pdfReqXSize,
1486
                        double *pdfReqYSize, int *, int *, int *, int *, int *,
1487
                        int *, int *, int *, bool &bErrorOut);
1488
1489
    virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
1490
                            int nXSize, int nYSize, void *pData, int nBufXSize,
1491
                            int nBufYSize, GDALDataType eBufType,
1492
                            GSpacing nPixelSpace, GSpacing nLineSpace,
1493
                            GDALRasterIOExtraArg *psExtraArgIn,
1494
                            WorkingState &oWorkingState) override;
1495
1496
    double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
1497
    double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
1498
    CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax,
1499
                        int nBuckets, GUIntBig *panHistogram,
1500
                        int bIncludeOutOfRange, int bApproxOK,
1501
                        GDALProgressFunc pfnProgress,
1502
                        void *pProgressData) override;
1503
1504
    void DstToSrc(double dfX, double dfY, double &dfXOut, double &dfYOut) const;
1505
    void SrcToDst(double dfX, double dfY, double &dfXOut, double &dfYOut) const;
1506
1507
    virtual void GetFileList(char ***ppapszFileList, int *pnSize,
1508
                             int *pnMaxSize, CPLHashSet *hSetFiles) override;
1509
1510
    bool IsSimpleSource() const override
1511
0
    {
1512
0
        return true;
1513
0
    }
1514
1515
    /** Returns the same value as GetType() called on objects that are exactly
1516
     * instances of VRTSimpleSource.
1517
     */
1518
    static const char *GetTypeStatic();
1519
1520
    const char *GetType() const override;
1521
1522
    CPLErr FlushCache(bool bAtClosing) override;
1523
1524
    GDALRasterBand *GetRasterBand() const;
1525
    GDALRasterBand *GetMaskBandMainBand();
1526
    bool IsSameExceptBandNumber(const VRTSimpleSource *poOtherSource) const;
1527
    CPLErr DatasetRasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
1528
                           int nXSize, int nYSize, void *pData, int nBufXSize,
1529
                           int nBufYSize, GDALDataType eBufType, int nBandCount,
1530
                           const int *panBandMap, GSpacing nPixelSpace,
1531
                           GSpacing nLineSpace, GSpacing nBandSpace,
1532
                           GDALRasterIOExtraArg *psExtraArg);
1533
1534
    void UnsetPreservedRelativeFilenames();
1535
1536
    void SetMaxValue(int nVal)
1537
0
    {
1538
0
        m_nMaxValue = nVal;
1539
0
    }
1540
};
1541
1542
/************************************************************************/
1543
/*                          VRTAveragedSource                           */
1544
/************************************************************************/
1545
1546
class VRTAveragedSource final : public VRTSimpleSource
1547
{
1548
    CPL_DISALLOW_COPY_ASSIGN(VRTAveragedSource)
1549
1550
    int m_bNoDataSet = false;
1551
    double m_dfNoDataValue = VRT_NODATA_UNSET;
1552
1553
  public:
1554
    VRTAveragedSource();
1555
    virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
1556
                            int nXSize, int nYSize, void *pData, int nBufXSize,
1557
                            int nBufYSize, GDALDataType eBufType,
1558
                            GSpacing nPixelSpace, GSpacing nLineSpace,
1559
                            GDALRasterIOExtraArg *psExtraArgIn,
1560
                            WorkingState &oWorkingState) override;
1561
1562
    double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
1563
    double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
1564
    CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax,
1565
                        int nBuckets, GUIntBig *panHistogram,
1566
                        int bIncludeOutOfRange, int bApproxOK,
1567
                        GDALProgressFunc pfnProgress,
1568
                        void *pProgressData) override;
1569
1570
    void SetNoDataValue(double dfNoDataValue);
1571
1572
    CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
1573
1574
    /** Returns the same value as GetType() called on objects that are exactly
1575
     * instances of VRTAveragedSource.
1576
     */
1577
    static const char *GetTypeStatic();
1578
1579
    const char *GetType() const override;
1580
};
1581
1582
/************************************************************************/
1583
/*                       VRTNoDataFromMaskSource                        */
1584
/************************************************************************/
1585
1586
class VRTNoDataFromMaskSource final : public VRTSimpleSource
1587
{
1588
    CPL_DISALLOW_COPY_ASSIGN(VRTNoDataFromMaskSource)
1589
1590
    bool m_bNoDataSet = false;
1591
    double m_dfNoDataValue = 0;
1592
    double m_dfMaskValueThreshold = 0;
1593
    bool m_bHasRemappedValue = false;
1594
    double m_dfRemappedValue = 0;
1595
1596
  public:
1597
    VRTNoDataFromMaskSource();
1598
    virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
1599
                            int nXSize, int nYSize, void *pData, int nBufXSize,
1600
                            int nBufYSize, GDALDataType eBufType,
1601
                            GSpacing nPixelSpace, GSpacing nLineSpace,
1602
                            GDALRasterIOExtraArg *psExtraArgIn,
1603
                            WorkingState &oWorkingState) override;
1604
1605
    double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
1606
    double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
1607
    CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax,
1608
                        int nBuckets, GUIntBig *panHistogram,
1609
                        int bIncludeOutOfRange, int bApproxOK,
1610
                        GDALProgressFunc pfnProgress,
1611
                        void *pProgressData) override;
1612
1613
    void SetParameters(double dfNoDataValue, double dfMaskValueThreshold);
1614
    void SetParameters(double dfNoDataValue, double dfMaskValueThreshold,
1615
                       double dfRemappedValue);
1616
1617
    virtual CPLErr XMLInit(const CPLXMLNode *psTree, const char *,
1618
                           VRTMapSharedResources &) override;
1619
    CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
1620
1621
    /** Returns the same value as GetType() called on objects that are exactly
1622
     * instances of VRTNoDataFromMaskSource.
1623
     */
1624
    static const char *GetTypeStatic();
1625
1626
    const char *GetType() const override;
1627
};
1628
1629
/************************************************************************/
1630
/*                           VRTComplexSource                           */
1631
/************************************************************************/
1632
1633
class CPL_DLL VRTComplexSource CPL_NON_FINAL : public VRTSimpleSource
1634
{
1635
    CPL_DISALLOW_COPY_ASSIGN(VRTComplexSource)
1636
1637
  protected:
1638
    static constexpr int PROCESSING_FLAG_NODATA = 1 << 0;
1639
    static constexpr int PROCESSING_FLAG_USE_MASK_BAND =
1640
        1 << 1;  // Mutually exclusive with NODATA
1641
    static constexpr int PROCESSING_FLAG_SCALING_LINEAR = 1 << 2;
1642
    static constexpr int PROCESSING_FLAG_SCALING_EXPONENTIAL =
1643
        1 << 3;  // Mutually exclusive with SCALING_LINEAR
1644
    static constexpr int PROCESSING_FLAG_COLOR_TABLE_EXPANSION = 1 << 4;
1645
    static constexpr int PROCESSING_FLAG_LUT = 1 << 5;
1646
1647
    int m_nProcessingFlags = 0;
1648
1649
    // adjusted value should be read with GetAdjustedNoDataValue()
1650
    double m_dfNoDataValue = VRT_NODATA_UNSET;
1651
    std::string
1652
        m_osNoDataValueOri{};  // string value read in XML deserialization
1653
1654
    double m_dfScaleOff = 0;    // For linear scaling.
1655
    double m_dfScaleRatio = 1;  // For linear scaling.
1656
1657
    // For non-linear scaling with a power function.
1658
    bool m_bSrcMinMaxDefined = false;
1659
    double m_dfSrcMin = 0;
1660
    double m_dfSrcMax = 0;
1661
    double m_dfDstMin = 0;
1662
    double m_dfDstMax = 0;
1663
    double m_dfExponent = 1;
1664
    bool m_bClip = true;  // Only taken into account for non-linear scaling
1665
1666
    int m_nColorTableComponent = 0;
1667
1668
    std::vector<double> m_adfLUTInputs{};
1669
    std::vector<double> m_adfLUTOutputs{};
1670
1671
    double GetAdjustedNoDataValue() const;
1672
1673
    template <class WorkingDT>
1674
    CPLErr
1675
    RasterIOInternal(GDALRasterBand *poSourceBand,
1676
                     GDALDataType eVRTBandDataType, int nReqXOff, int nReqYOff,
1677
                     int nReqXSize, int nReqYSize, void *pData, int nOutXSize,
1678
                     int nOutYSize, GDALDataType eBufType, GSpacing nPixelSpace,
1679
                     GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg,
1680
                     GDALDataType eWrkDataType, WorkingState &oWorkingState);
1681
1682
    template <class SourceDT, GDALDataType eSourceType>
1683
    CPLErr RasterIOProcessNoData(GDALRasterBand *poSourceBand,
1684
                                 GDALDataType eVRTBandDataType, int nReqXOff,
1685
                                 int nReqYOff, int nReqXSize, int nReqYSize,
1686
                                 void *pData, int nOutXSize, int nOutYSize,
1687
                                 GDALDataType eBufType, GSpacing nPixelSpace,
1688
                                 GSpacing nLineSpace,
1689
                                 GDALRasterIOExtraArg *psExtraArg,
1690
                                 WorkingState &oWorkingState);
1691
1692
  public:
1693
0
    VRTComplexSource() = default;
1694
    VRTComplexSource(const VRTComplexSource *poSrcSource, double dfXDstRatio,
1695
                     double dfYDstRatio);
1696
1697
    virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
1698
                            int nXSize, int nYSize, void *pData, int nBufXSize,
1699
                            int nBufYSize, GDALDataType eBufType,
1700
                            GSpacing nPixelSpace, GSpacing nLineSpace,
1701
                            GDALRasterIOExtraArg *psExtraArgIn,
1702
                            WorkingState &oWorkingState) override;
1703
1704
    double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
1705
    double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
1706
    CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax,
1707
                        int nBuckets, GUIntBig *panHistogram,
1708
                        int bIncludeOutOfRange, int bApproxOK,
1709
                        GDALProgressFunc pfnProgress,
1710
                        void *pProgressData) override;
1711
1712
    CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
1713
    virtual CPLErr XMLInit(const CPLXMLNode *, const char *,
1714
                           VRTMapSharedResources &) override;
1715
1716
    /** Returns the same value as GetType() called on objects that are exactly
1717
     * instances of VRTComplexSource.
1718
     */
1719
    static const char *GetTypeStatic();
1720
1721
    const char *GetType() const override;
1722
1723
    bool AreValuesUnchanged() const;
1724
1725
    double LookupValue(double dfInput);
1726
1727
    void SetNoDataValue(double dfNoDataValue);
1728
1729
    void SetUseMaskBand(bool bUseMaskBand)
1730
0
    {
1731
0
        if (bUseMaskBand)
1732
0
            m_nProcessingFlags |= PROCESSING_FLAG_USE_MASK_BAND;
1733
0
        else
1734
0
            m_nProcessingFlags &= ~PROCESSING_FLAG_USE_MASK_BAND;
1735
0
    }
1736
1737
    void SetLinearScaling(double dfOffset, double dfScale);
1738
    void SetPowerScaling(double dfExponent, double dfSrcMin, double dfSrcMax,
1739
                         double dfDstMin, double dfDstMax, bool bClip = true);
1740
    void SetColorTableComponent(int nComponent);
1741
};
1742
1743
/************************************************************************/
1744
/*                           VRTFilteredSource                          */
1745
/************************************************************************/
1746
1747
class VRTFilteredSource CPL_NON_FINAL : public VRTComplexSource
1748
{
1749
  private:
1750
    int IsTypeSupported(GDALDataType eTestType) const;
1751
1752
    CPL_DISALLOW_COPY_ASSIGN(VRTFilteredSource)
1753
1754
  protected:
1755
    int m_nSupportedTypesCount;
1756
    GDALDataType m_aeSupportedTypes[20];
1757
1758
    int m_nExtraEdgePixels;
1759
1760
  public:
1761
    VRTFilteredSource();
1762
    ~VRTFilteredSource() override;
1763
1764
    const char *GetType() const override = 0;
1765
1766
    void SetExtraEdgePixels(int);
1767
    void SetFilteringDataTypesSupported(int, GDALDataType *);
1768
1769
    virtual CPLErr FilterData(int nXSize, int nYSize, GDALDataType eType,
1770
                              GByte *pabySrcData, GByte *pabyDstData) = 0;
1771
1772
    virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
1773
                            int nXSize, int nYSize, void *pData, int nBufXSize,
1774
                            int nBufYSize, GDALDataType eBufType,
1775
                            GSpacing nPixelSpace, GSpacing nLineSpace,
1776
                            GDALRasterIOExtraArg *psExtraArg,
1777
                            WorkingState &oWorkingState) override;
1778
};
1779
1780
/************************************************************************/
1781
/*                       VRTKernelFilteredSource                        */
1782
/************************************************************************/
1783
1784
class VRTKernelFilteredSource CPL_NON_FINAL : public VRTFilteredSource
1785
{
1786
    CPL_DISALLOW_COPY_ASSIGN(VRTKernelFilteredSource)
1787
1788
  protected:
1789
    int m_nKernelSize = 0;
1790
    bool m_bSeparable = false;
1791
    // m_nKernelSize elements if m_bSeparable, m_nKernelSize * m_nKernelSize otherwise
1792
    std::vector<double> m_adfKernelCoefs{};
1793
    bool m_bNormalized = false;
1794
    std::string m_function{};
1795
1796
  public:
1797
    VRTKernelFilteredSource();
1798
1799
    const char *GetType() const override;
1800
1801
    virtual CPLErr XMLInit(const CPLXMLNode *psTree, const char *,
1802
                           VRTMapSharedResources &) override;
1803
    CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
1804
1805
    virtual CPLErr FilterData(int nXSize, int nYSize, GDALDataType eType,
1806
                              GByte *pabySrcData, GByte *pabyDstData) override;
1807
1808
    CPLErr SetKernel(int nKernelSize, bool bSeparable,
1809
                     const std::vector<double> &adfNewCoefs);
1810
    void SetNormalized(bool);
1811
1812
    void SetFunction(const std::string &s)
1813
0
    {
1814
0
        m_function = s;
1815
0
    }
1816
};
1817
1818
/************************************************************************/
1819
/*                       VRTAverageFilteredSource                       */
1820
/************************************************************************/
1821
1822
class VRTAverageFilteredSource final : public VRTKernelFilteredSource
1823
{
1824
    CPL_DISALLOW_COPY_ASSIGN(VRTAverageFilteredSource)
1825
1826
  public:
1827
    explicit VRTAverageFilteredSource(int nKernelSize);
1828
    ~VRTAverageFilteredSource() override;
1829
1830
    const char *GetType() const override;
1831
1832
    virtual CPLErr XMLInit(const CPLXMLNode *psTree, const char *,
1833
                           VRTMapSharedResources &) override;
1834
    CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
1835
};
1836
1837
/************************************************************************/
1838
/*                            VRTFuncSource                             */
1839
/************************************************************************/
1840
class VRTFuncSource final : public VRTSource
1841
{
1842
    CPL_DISALLOW_COPY_ASSIGN(VRTFuncSource)
1843
1844
  public:
1845
    VRTFuncSource();
1846
    ~VRTFuncSource() override;
1847
1848
    virtual CPLErr XMLInit(const CPLXMLNode *, const char *,
1849
                           VRTMapSharedResources &) override
1850
0
    {
1851
0
        return CE_Failure;
1852
0
    }
1853
1854
    CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
1855
1856
    virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
1857
                            int nXSize, int nYSize, void *pData, int nBufXSize,
1858
                            int nBufYSize, GDALDataType eBufType,
1859
                            GSpacing nPixelSpace, GSpacing nLineSpace,
1860
                            GDALRasterIOExtraArg *psExtraArg,
1861
                            WorkingState &oWorkingState) override;
1862
1863
    double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
1864
    double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
1865
    CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax,
1866
                        int nBuckets, GUIntBig *panHistogram,
1867
                        int bIncludeOutOfRange, int bApproxOK,
1868
                        GDALProgressFunc pfnProgress,
1869
                        void *pProgressData) override;
1870
1871
    const char *GetType() const override;
1872
1873
    VRTImageReadFunc pfnReadFunc;
1874
    void *pCBData;
1875
    GDALDataType eType;
1876
1877
    float fNoDataValue;
1878
};
1879
1880
/************************************************************************/
1881
/*                              VRTGroup                                */
1882
/************************************************************************/
1883
1884
#ifdef TMPEXPORT
1885
#define TMP_CPL_DLL CPL_DLL
1886
#else
1887
#define TMP_CPL_DLL
1888
#endif
1889
1890
class VRTMDArray;
1891
class VRTAttribute;
1892
class VRTDimension;
1893
1894
class VRTGroup final : public GDALGroup
1895
{
1896
  public:
1897
    struct Ref
1898
    {
1899
        VRTGroup *m_ptr;
1900
1901
0
        explicit Ref(VRTGroup *ptr) : m_ptr(ptr)
1902
0
        {
1903
0
        }
1904
1905
        Ref(const Ref &) = delete;
1906
        Ref &operator=(const Ref &) = delete;
1907
    };
1908
1909
  private:
1910
    std::shared_ptr<Ref> m_poSharedRefRootGroup{};
1911
    std::weak_ptr<Ref> m_poWeakRefRootGroup{};
1912
    std::shared_ptr<Ref> m_poRefSelf{};
1913
1914
    std::string m_osFilename{};
1915
    mutable bool m_bDirty = false;
1916
    std::string m_osVRTPath{};
1917
    std::vector<std::string> m_aosGroupNames{};
1918
    std::map<std::string, std::shared_ptr<VRTGroup>> m_oMapGroups{};
1919
    std::vector<std::string> m_aosMDArrayNames{};
1920
    std::map<std::string, std::shared_ptr<VRTMDArray>> m_oMapMDArrays{};
1921
    std::map<std::string, std::shared_ptr<VRTAttribute>> m_oMapAttributes{};
1922
    std::map<std::string, std::shared_ptr<VRTDimension>> m_oMapDimensions{};
1923
1924
    std::shared_ptr<VRTGroup>
1925
    OpenGroupInternal(const std::string &osName) const;
1926
    void SetRootGroupRef(const std::weak_ptr<Ref> &rgRef);
1927
    std::weak_ptr<Ref> GetRootGroupRef() const;
1928
1929
  protected:
1930
    friend class VRTMDArray;
1931
    friend std::shared_ptr<GDALMDArray>
1932
    VRTDerivedArrayCreate(const char *pszVRTPath, const CPLXMLNode *psTree);
1933
1934
    explicit VRTGroup(const char *pszVRTPath);
1935
    VRTGroup(const std::string &osParentName, const std::string &osName);
1936
1937
  public:
1938
    static std::shared_ptr<VRTGroup> Create(const std::string &osParentName,
1939
                                            const std::string &osName)
1940
0
    {
1941
0
        auto poGroup =
1942
0
            std::shared_ptr<VRTGroup>(new VRTGroup(osParentName, osName));
1943
0
        poGroup->SetSelf(poGroup);
1944
0
        return poGroup;
1945
0
    }
1946
1947
    ~VRTGroup() override;
1948
1949
    bool XMLInit(const std::shared_ptr<VRTGroup> &poRoot,
1950
                 const std::shared_ptr<VRTGroup> &poThisGroup,
1951
                 const CPLXMLNode *psNode, const char *pszVRTPath);
1952
1953
    std::vector<std::string>
1954
    GetMDArrayNames(CSLConstList papszOptions) const override;
1955
    std::shared_ptr<GDALMDArray>
1956
    OpenMDArray(const std::string &osName,
1957
                CSLConstList papszOptions = nullptr) const override;
1958
1959
    std::vector<std::string>
1960
    GetGroupNames(CSLConstList papszOptions) const override;
1961
1962
    std::shared_ptr<GDALGroup> OpenGroup(const std::string &osName,
1963
                                         CSLConstList) const override
1964
0
    {
1965
0
        return OpenGroupInternal(osName);
1966
0
    }
1967
1968
    std::vector<std::shared_ptr<GDALDimension>>
1969
        GetDimensions(CSLConstList) const override;
1970
1971
    std::vector<std::shared_ptr<GDALAttribute>>
1972
        GetAttributes(CSLConstList) const override;
1973
1974
    std::shared_ptr<VRTDimension> GetDimension(const std::string &name) const
1975
0
    {
1976
0
        auto oIter = m_oMapDimensions.find(name);
1977
0
        return oIter == m_oMapDimensions.end() ? nullptr : oIter->second;
1978
0
    }
1979
1980
    std::shared_ptr<VRTDimension>
1981
    GetDimensionFromFullName(const std::string &name, bool bEmitError) const;
1982
1983
    std::shared_ptr<GDALGroup>
1984
    CreateGroup(const std::string &osName,
1985
                CSLConstList papszOptions = nullptr) override;
1986
1987
    std::shared_ptr<VRTGroup>
1988
    CreateVRTGroup(const std::string &osName,
1989
                   CSLConstList papszOptions = nullptr);
1990
1991
    std::shared_ptr<GDALDimension>
1992
    CreateDimension(const std::string &osName, const std::string &osType,
1993
                    const std::string &osDirection, GUInt64 nSize,
1994
                    CSLConstList papszOptions = nullptr) override;
1995
1996
    std::shared_ptr<GDALAttribute>
1997
    CreateAttribute(const std::string &osName,
1998
                    const std::vector<GUInt64> &anDimensions,
1999
                    const GDALExtendedDataType &oDataType,
2000
                    CSLConstList papszOptions = nullptr) override;
2001
2002
    std::shared_ptr<GDALMDArray> CreateMDArray(
2003
        const std::string &osName,
2004
        const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
2005
        const GDALExtendedDataType &oDataType,
2006
        CSLConstList papszOptions = nullptr) override;
2007
2008
    std::shared_ptr<VRTMDArray> CreateVRTMDArray(
2009
        const std::string &osName,
2010
        const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
2011
        const GDALExtendedDataType &oDataType,
2012
        CSLConstList papszOptions = nullptr);
2013
2014
    void SetIsRootGroup();
2015
2016
    const std::shared_ptr<Ref> &GetRef() const
2017
0
    {
2018
0
        return m_poRefSelf;
2019
0
    }
2020
2021
    VRTGroup *GetRootGroup() const;
2022
    std::shared_ptr<VRTGroup> GetRootGroupSharedPtr() const;
2023
2024
    const std::string &GetVRTPath() const
2025
0
    {
2026
0
        return m_osVRTPath;
2027
0
    }
2028
2029
    void SetVRTPath(const std::string &osVRTPath)
2030
0
    {
2031
0
        m_osVRTPath = osVRTPath;
2032
0
    }
2033
2034
    void SetDirty();
2035
2036
    void SetFilename(const std::string &osFilename)
2037
0
    {
2038
0
        m_osFilename = osFilename;
2039
0
    }
2040
2041
    const std::string &GetFilename() const
2042
0
    {
2043
0
        return m_osFilename;
2044
0
    }
2045
2046
    bool Serialize() const;
2047
    CPLXMLNode *SerializeToXML(const char *pszVRTPathIn) const;
2048
    void Serialize(CPLXMLNode *psParent, const char *pszVRTPathIn) const;
2049
};
2050
2051
/************************************************************************/
2052
/*                            VRTDimension                              */
2053
/************************************************************************/
2054
2055
class VRTDimension final : public GDALDimension
2056
{
2057
    std::weak_ptr<VRTGroup::Ref> m_poGroupRef;
2058
    std::string m_osIndexingVariableName;
2059
2060
  public:
2061
    VRTDimension(const std::shared_ptr<VRTGroup::Ref> &poGroupRef,
2062
                 const std::string &osParentName, const std::string &osName,
2063
                 const std::string &osType, const std::string &osDirection,
2064
                 GUInt64 nSize, const std::string &osIndexingVariableName)
2065
0
        : GDALDimension(osParentName, osName, osType, osDirection, nSize),
2066
0
          m_poGroupRef(poGroupRef),
2067
0
          m_osIndexingVariableName(osIndexingVariableName)
2068
0
    {
2069
0
    }
2070
2071
    VRTGroup *GetGroup() const;
2072
2073
    static std::shared_ptr<VRTDimension>
2074
    Create(const std::shared_ptr<VRTGroup> &poThisGroup,
2075
           const std::string &osParentName, const CPLXMLNode *psNode);
2076
2077
    std::shared_ptr<GDALMDArray> GetIndexingVariable() const override;
2078
2079
    bool SetIndexingVariable(
2080
        std::shared_ptr<GDALMDArray> poIndexingVariable) override;
2081
2082
    void Serialize(CPLXMLNode *psParent) const;
2083
};
2084
2085
/************************************************************************/
2086
/*                            VRTAttribute                              */
2087
/************************************************************************/
2088
2089
class VRTAttribute final : public GDALAttribute
2090
{
2091
    GDALExtendedDataType m_dt;
2092
    std::vector<std::string> m_aosList{};
2093
    std::vector<std::shared_ptr<GDALDimension>> m_dims{};
2094
2095
  protected:
2096
    bool IRead(const GUInt64 *arrayStartIdx, const size_t *count,
2097
               const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
2098
               const GDALExtendedDataType &bufferDataType,
2099
               void *pDstBuffer) const override;
2100
2101
    bool IWrite(const GUInt64 *arrayStartIdx, const size_t *count,
2102
                const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
2103
                const GDALExtendedDataType &bufferDataType,
2104
                const void *pSrcBuffer) override;
2105
2106
  public:
2107
    VRTAttribute(const std::string &osParentName, const std::string &osName,
2108
                 const GDALExtendedDataType &dt,
2109
                 std::vector<std::string> &&aosList)
2110
0
        : GDALAbstractMDArray(osParentName, osName),
2111
0
          GDALAttribute(osParentName, osName), m_dt(dt),
2112
0
          m_aosList(std::move(aosList))
2113
0
    {
2114
0
        if (m_aosList.size() > 1)
2115
0
        {
2116
0
            m_dims.emplace_back(std::make_shared<GDALDimension>(
2117
0
                std::string(), "dim", std::string(), std::string(),
2118
0
                m_aosList.size()));
2119
0
        }
2120
0
    }
2121
2122
    VRTAttribute(const std::string &osParentName, const std::string &osName,
2123
                 GUInt64 nDim, const GDALExtendedDataType &dt)
2124
0
        : GDALAbstractMDArray(osParentName, osName),
2125
0
          GDALAttribute(osParentName, osName), m_dt(dt)
2126
0
    {
2127
0
        if (nDim != 0)
2128
0
        {
2129
0
            m_dims.emplace_back(std::make_shared<GDALDimension>(
2130
0
                std::string(), "dim", std::string(), std::string(), nDim));
2131
0
        }
2132
0
    }
2133
2134
    static bool CreationCommonChecks(
2135
        const std::string &osName, const std::vector<GUInt64> &anDimensions,
2136
        const std::map<std::string, std::shared_ptr<VRTAttribute>>
2137
            &oMapAttributes);
2138
2139
    static std::shared_ptr<VRTAttribute> Create(const std::string &osParentName,
2140
                                                const CPLXMLNode *psNode);
2141
2142
    const std::vector<std::shared_ptr<GDALDimension>> &
2143
    GetDimensions() const override
2144
0
    {
2145
0
        return m_dims;
2146
0
    }
2147
2148
    const GDALExtendedDataType &GetDataType() const override
2149
0
    {
2150
0
        return m_dt;
2151
0
    }
2152
2153
    void Serialize(CPLXMLNode *psParent) const;
2154
};
2155
2156
/************************************************************************/
2157
/*                          VRTMDArraySource                            */
2158
/************************************************************************/
2159
2160
class VRTMDArraySource
2161
{
2162
  public:
2163
    virtual ~VRTMDArraySource();
2164
2165
    enum class RelationShip
2166
    {
2167
        NO_INTERSECTION,
2168
        PARTIAL_INTERSECTION,
2169
        SOURCE_BLOCK_MATCH,
2170
    };
2171
2172
    virtual RelationShip GetRelationship(const uint64_t *arrayStartIdx,
2173
                                         const size_t *count) const = 0;
2174
2175
    virtual bool GetRawBlockInfo(const uint64_t *arrayStartIdx,
2176
                                 const size_t *count,
2177
                                 GDALMDArrayRawBlockInfo &info) const = 0;
2178
2179
    virtual bool Read(const GUInt64 *arrayStartIdx, const size_t *count,
2180
                      const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
2181
                      const GDALExtendedDataType &bufferDataType,
2182
                      void *pDstBuffer) const = 0;
2183
2184
    virtual void Serialize(CPLXMLNode *psParent,
2185
                           const char *pszVRTPath) const = 0;
2186
};
2187
2188
/************************************************************************/
2189
/*                            VRTMDArray                                */
2190
/************************************************************************/
2191
2192
class VRTMDArray final : public GDALMDArray
2193
{
2194
  protected:
2195
    friend class VRTGroup;  // for access to SetSelf()
2196
2197
    std::weak_ptr<VRTGroup::Ref> m_poGroupRef;
2198
    std::string m_osVRTPath{};
2199
    std::shared_ptr<VRTGroup> m_poDummyOwningGroup{};
2200
2201
    GDALExtendedDataType m_dt;
2202
    std::vector<std::shared_ptr<GDALDimension>> m_dims;
2203
    std::map<std::string, std::shared_ptr<VRTAttribute>> m_oMapAttributes{};
2204
    std::vector<std::unique_ptr<VRTMDArraySource>> m_sources{};
2205
    std::shared_ptr<OGRSpatialReference> m_poSRS{};
2206
    std::vector<GByte> m_abyNoData{};
2207
    std::string m_osUnit{};
2208
    double m_dfScale = 1.0;
2209
    double m_dfOffset = 0.0;
2210
    bool m_bHasScale = false;
2211
    bool m_bHasOffset = false;
2212
    std::string m_osFilename{};
2213
    std::vector<GUInt64> m_anBlockSize{};
2214
2215
    bool IRead(const GUInt64 *arrayStartIdx, const size_t *count,
2216
               const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
2217
               const GDALExtendedDataType &bufferDataType,
2218
               void *pDstBuffer) const override;
2219
2220
    void SetDirty();
2221
2222
  public:
2223
    VRTMDArray(
2224
        const std::shared_ptr<VRTGroup::Ref> &poGroupRef,
2225
        const std::string &osParentName, const std::string &osName,
2226
        const GDALExtendedDataType &dt,
2227
        std::vector<std::shared_ptr<GDALDimension>> &&dims,
2228
        std::map<std::string, std::shared_ptr<VRTAttribute>> &&oMapAttributes,
2229
        std::vector<GUInt64> &&anBlockSize)
2230
0
        : GDALAbstractMDArray(osParentName, osName),
2231
0
          GDALMDArray(osParentName, osName), m_poGroupRef(poGroupRef),
2232
0
          m_osVRTPath(poGroupRef->m_ptr->GetVRTPath()), m_dt(dt),
2233
0
          m_dims(std::move(dims)), m_oMapAttributes(std::move(oMapAttributes)),
2234
0
          m_osFilename(poGroupRef->m_ptr->GetFilename()),
2235
0
          m_anBlockSize(std::move(anBlockSize))
2236
0
    {
2237
0
    }
2238
2239
    VRTMDArray(const std::shared_ptr<VRTGroup::Ref> &poGroupRef,
2240
               const std::string &osParentName, const std::string &osName,
2241
               const std::vector<std::shared_ptr<GDALDimension>> &dims,
2242
               const GDALExtendedDataType &dt,
2243
               const std::vector<GUInt64> &anBlockSize)
2244
0
        : GDALAbstractMDArray(osParentName, osName),
2245
0
          GDALMDArray(osParentName, osName), m_poGroupRef(poGroupRef),
2246
0
          m_osVRTPath(poGroupRef->m_ptr->GetVRTPath()), m_dt(dt), m_dims(dims),
2247
0
          m_osFilename(poGroupRef->m_ptr->GetFilename()),
2248
0
          m_anBlockSize(anBlockSize)
2249
0
    {
2250
0
    }
2251
2252
    bool IsWritable() const override
2253
0
    {
2254
0
        return false;
2255
0
    }
2256
2257
    const std::string &GetFilename() const override
2258
0
    {
2259
0
        return m_osFilename;
2260
0
    }
2261
2262
    static std::shared_ptr<VRTMDArray> Create(const char *pszVRTPath,
2263
                                              const CPLXMLNode *psNode);
2264
2265
    static std::shared_ptr<VRTMDArray>
2266
    Create(const std::shared_ptr<VRTGroup> &poThisGroup,
2267
           const std::string &osParentName, const CPLXMLNode *psNode);
2268
2269
    const std::vector<std::shared_ptr<GDALDimension>> &
2270
    GetDimensions() const override
2271
0
    {
2272
0
        return m_dims;
2273
0
    }
2274
2275
    std::vector<std::shared_ptr<GDALAttribute>>
2276
        GetAttributes(CSLConstList) const override;
2277
2278
    const GDALExtendedDataType &GetDataType() const override
2279
0
    {
2280
0
        return m_dt;
2281
0
    }
2282
2283
    bool SetSpatialRef(const OGRSpatialReference *poSRS) override;
2284
2285
    std::shared_ptr<OGRSpatialReference> GetSpatialRef() const override
2286
0
    {
2287
0
        return m_poSRS;
2288
0
    }
2289
2290
    const void *GetRawNoDataValue() const override;
2291
2292
    bool SetRawNoDataValue(const void *pRawNoData) override;
2293
2294
    const std::string &GetUnit() const override
2295
0
    {
2296
0
        return m_osUnit;
2297
0
    }
2298
2299
    bool SetUnit(const std::string &osUnit) override
2300
0
    {
2301
0
        m_osUnit = osUnit;
2302
0
        return true;
2303
0
    }
2304
2305
    double GetOffset(bool *pbHasOffset,
2306
                     GDALDataType *peStorageType) const override
2307
0
    {
2308
0
        if (pbHasOffset)
2309
0
            *pbHasOffset = m_bHasOffset;
2310
0
        if (peStorageType)
2311
0
            *peStorageType = GDT_Unknown;
2312
0
        return m_dfOffset;
2313
0
    }
2314
2315
    double GetScale(bool *pbHasScale,
2316
                    GDALDataType *peStorageType) const override
2317
0
    {
2318
0
        if (pbHasScale)
2319
0
            *pbHasScale = m_bHasScale;
2320
0
        if (peStorageType)
2321
0
            *peStorageType = GDT_Unknown;
2322
0
        return m_dfScale;
2323
0
    }
2324
2325
    bool SetOffset(double dfOffset,
2326
                   GDALDataType /* eStorageType */ = GDT_Unknown) override
2327
0
    {
2328
0
        SetDirty();
2329
0
        m_bHasOffset = true;
2330
0
        m_dfOffset = dfOffset;
2331
0
        return true;
2332
0
    }
2333
2334
    bool SetScale(double dfScale,
2335
                  GDALDataType /* eStorageType */ = GDT_Unknown) override
2336
0
    {
2337
0
        SetDirty();
2338
0
        m_bHasScale = true;
2339
0
        m_dfScale = dfScale;
2340
0
        return true;
2341
0
    }
2342
2343
    void AddSource(std::unique_ptr<VRTMDArraySource> &&poSource);
2344
2345
    std::shared_ptr<GDALAttribute>
2346
    CreateAttribute(const std::string &osName,
2347
                    const std::vector<GUInt64> &anDimensions,
2348
                    const GDALExtendedDataType &oDataType,
2349
                    CSLConstList papszOptions = nullptr) override;
2350
2351
    bool CopyFrom(GDALDataset *poSrcDS, const GDALMDArray *poSrcArray,
2352
                  bool bStrict, GUInt64 &nCurCost, const GUInt64 nTotalCost,
2353
                  GDALProgressFunc pfnProgress, void *pProgressData) override;
2354
2355
    void Serialize(CPLXMLNode *psParent, const char *pszVRTPathIn) const;
2356
2357
    VRTGroup *GetGroup() const;
2358
2359
    const std::string &GetVRTPath() const
2360
0
    {
2361
0
        return m_osVRTPath;
2362
0
    }
2363
2364
    std::shared_ptr<VRTGroup> GetRootVRTGroup() const
2365
0
    {
2366
0
        auto poGroup = m_poGroupRef.lock();
2367
0
        if (poGroup)
2368
0
            return poGroup->m_ptr->GetRootGroupSharedPtr();
2369
0
        return nullptr;
2370
0
    }
2371
2372
    std::shared_ptr<GDALGroup> GetRootGroup() const override
2373
0
    {
2374
0
        return GetRootVRTGroup();
2375
0
    }
2376
2377
    std::vector<GUInt64> GetBlockSize() const override
2378
0
    {
2379
0
        return m_anBlockSize;
2380
0
    }
2381
2382
    bool GetRawBlockInfo(const uint64_t *panBlockCoordinates,
2383
                         GDALMDArrayRawBlockInfo &info) const override;
2384
};
2385
2386
/************************************************************************/
2387
/*                       VRTMDArraySourceInlinedValues                  */
2388
/************************************************************************/
2389
2390
class VRTMDArraySourceInlinedValues final : public VRTMDArraySource
2391
{
2392
    const VRTMDArray *m_poDstArray = nullptr;
2393
    bool m_bIsConstantValue;
2394
    std::vector<GUInt64> m_anOffset{};
2395
    std::vector<size_t> m_anCount{};
2396
    std::vector<GByte> m_abyValues{};
2397
    std::vector<size_t> m_anInlinedArrayStrideInBytes{};
2398
    GDALExtendedDataType m_dt;
2399
2400
    VRTMDArraySourceInlinedValues(const VRTMDArraySourceInlinedValues &) =
2401
        delete;
2402
    VRTMDArraySourceInlinedValues &
2403
    operator=(const VRTMDArraySourceInlinedValues &) = delete;
2404
2405
  public:
2406
    VRTMDArraySourceInlinedValues(const VRTMDArray *poDstArray,
2407
                                  bool bIsConstantValue,
2408
                                  std::vector<GUInt64> &&anOffset,
2409
                                  std::vector<size_t> &&anCount,
2410
                                  std::vector<GByte> &&abyValues)
2411
0
        : m_poDstArray(poDstArray), m_bIsConstantValue(bIsConstantValue),
2412
0
          m_anOffset(std::move(anOffset)), m_anCount(std::move(anCount)),
2413
0
          m_abyValues(std::move(abyValues)), m_dt(poDstArray->GetDataType())
2414
0
    {
2415
0
        const auto nDims(poDstArray->GetDimensionCount());
2416
0
        m_anInlinedArrayStrideInBytes.resize(nDims);
2417
0
        if (!bIsConstantValue && nDims > 0)
2418
0
        {
2419
0
            m_anInlinedArrayStrideInBytes.back() =
2420
0
                poDstArray->GetDataType().GetSize();
2421
0
            for (size_t i = nDims - 1; i > 0;)
2422
0
            {
2423
0
                --i;
2424
0
                m_anInlinedArrayStrideInBytes[i] =
2425
0
                    m_anInlinedArrayStrideInBytes[i + 1] * m_anCount[i + 1];
2426
0
            }
2427
0
        }
2428
0
    }
2429
2430
    ~VRTMDArraySourceInlinedValues() override;
2431
2432
    static std::unique_ptr<VRTMDArraySourceInlinedValues>
2433
    Create(const VRTMDArray *poDstArray, const CPLXMLNode *psNode);
2434
2435
    RelationShip GetRelationship(const uint64_t * /*arrayStartIdx*/,
2436
                                 const size_t * /*count*/) const override
2437
0
    {
2438
0
        return RelationShip::PARTIAL_INTERSECTION;
2439
0
    }
2440
2441
    bool GetRawBlockInfo(const uint64_t * /*arrayStartIdx*/,
2442
                         const size_t * /*count*/,
2443
                         GDALMDArrayRawBlockInfo & /*info*/) const override
2444
0
    {
2445
0
        return false;
2446
0
    }
2447
2448
    bool Read(const GUInt64 *arrayStartIdx, const size_t *count,
2449
              const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
2450
              const GDALExtendedDataType &bufferDataType,
2451
              void *pDstBuffer) const override;
2452
2453
    void Serialize(CPLXMLNode *psParent, const char *pszVRTPath) const override;
2454
};
2455
2456
/************************************************************************/
2457
/*                     VRTMDArraySourceRegularlySpaced                  */
2458
/************************************************************************/
2459
2460
class VRTMDArraySourceRegularlySpaced final : public VRTMDArraySource
2461
{
2462
    double m_dfStart;
2463
    double m_dfIncrement;
2464
2465
  public:
2466
    VRTMDArraySourceRegularlySpaced(double dfStart, double dfIncrement)
2467
0
        : m_dfStart(dfStart), m_dfIncrement(dfIncrement)
2468
0
    {
2469
0
    }
2470
2471
    RelationShip GetRelationship(const uint64_t * /*arrayStartIdx*/,
2472
                                 const size_t * /*count*/) const override
2473
0
    {
2474
0
        return RelationShip::PARTIAL_INTERSECTION;
2475
0
    }
2476
2477
    bool GetRawBlockInfo(const uint64_t * /*arrayStartIdx*/,
2478
                         const size_t * /*count*/,
2479
                         GDALMDArrayRawBlockInfo & /*info*/) const override
2480
0
    {
2481
0
        return false;
2482
0
    }
2483
2484
    bool Read(const GUInt64 *arrayStartIdx, const size_t *count,
2485
              const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
2486
              const GDALExtendedDataType &bufferDataType,
2487
              void *pDstBuffer) const override;
2488
2489
    void Serialize(CPLXMLNode *psParent, const char *pszVRTPath) const override;
2490
};
2491
2492
/************************************************************************/
2493
/*                       VRTMDArraySourceFromArray                      */
2494
/************************************************************************/
2495
2496
struct VRTArrayDatasetWrapper;
2497
2498
class VRTMDArraySourceFromArray final : public VRTMDArraySource
2499
{
2500
    const VRTMDArray *m_poDstArray = nullptr;
2501
    bool m_bRelativeToVRTSet = false;
2502
    bool m_bRelativeToVRT = false;
2503
    std::string m_osFilename{};
2504
    std::string m_osArray{};
2505
    std::string m_osBand{};
2506
    std::vector<int> m_anTransposedAxis{};
2507
    std::string m_osViewExpr{};
2508
    std::vector<GUInt64> m_anSrcOffset{};
2509
    mutable std::vector<GUInt64> m_anCount{};
2510
    std::vector<GUInt64> m_anStep{};
2511
    std::vector<GUInt64> m_anDstOffset{};
2512
2513
    std::pair<std::shared_ptr<VRTArrayDatasetWrapper>,
2514
              std::shared_ptr<GDALMDArray>>
2515
    GetSourceArray() const;
2516
2517
    VRTMDArraySourceFromArray(const VRTMDArraySourceFromArray &) = delete;
2518
    VRTMDArraySourceFromArray &
2519
    operator=(const VRTMDArraySourceFromArray &) = delete;
2520
2521
  public:
2522
    VRTMDArraySourceFromArray(
2523
        const VRTMDArray *poDstArray, bool bRelativeToVRTSet,
2524
        bool bRelativeToVRT, const std::string &osFilename,
2525
        const std::string &osArray, const std::string &osBand,
2526
        std::vector<int> &&anTransposedAxis, const std::string &osViewExpr,
2527
        std::vector<GUInt64> &&anSrcOffset, std::vector<GUInt64> &&anCount,
2528
        std::vector<GUInt64> &&anStep, std::vector<GUInt64> &&anDstOffset)
2529
0
        : m_poDstArray(poDstArray), m_bRelativeToVRTSet(bRelativeToVRTSet),
2530
0
          m_bRelativeToVRT(bRelativeToVRT), m_osFilename(osFilename),
2531
0
          m_osArray(osArray), m_osBand(osBand),
2532
0
          m_anTransposedAxis(std::move(anTransposedAxis)),
2533
0
          m_osViewExpr(osViewExpr), m_anSrcOffset(std::move(anSrcOffset)),
2534
0
          m_anCount(std::move(anCount)), m_anStep(std::move(anStep)),
2535
0
          m_anDstOffset(std::move(anDstOffset))
2536
0
    {
2537
0
    }
2538
2539
    ~VRTMDArraySourceFromArray() override;
2540
2541
    static std::unique_ptr<VRTMDArraySourceFromArray>
2542
    Create(const VRTMDArray *poDstArray, const CPLXMLNode *psNode);
2543
2544
    RelationShip GetRelationship(const uint64_t *arrayStartIdx,
2545
                                 const size_t *count) const override;
2546
2547
    bool GetRawBlockInfo(const uint64_t *arrayStartIdx, const size_t *count,
2548
                         GDALMDArrayRawBlockInfo &info) const override;
2549
2550
    bool Read(const GUInt64 *arrayStartIdx, const size_t *count,
2551
              const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
2552
              const GDALExtendedDataType &bufferDataType,
2553
              void *pDstBuffer) const override;
2554
2555
    void Serialize(CPLXMLNode *psParent, const char *pszVRTPath) const override;
2556
};
2557
2558
#endif /* #ifndef DOXYGEN_SKIP */
2559
2560
#endif /* ndef VIRTUALDATASET_H_INCLUDED */