Coverage Report

Created: 2026-02-14 09:00

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
55.6k
    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
11.1M
            {
150
                // do nothing
151
11.1M
            }
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
1.79M
    {
336
1.79M
        m_bNeedsFlush = true;
337
1.79M
    }
338
339
    CPLErr FlushCache(bool bAtClosing) override;
340
341
    void SetWritable(int bWritableIn)
342
119
    {
343
119
        m_bWritable = CPL_TO_BOOL(bWritableIn);
344
119
    }
345
346
    CPLErr CreateMaskBand(int nFlags) override;
347
    void SetMaskBand(std::unique_ptr<VRTRasterBand> poMaskBand);
348
349
    const OGRSpatialReference *GetSpatialRef() const override
350
26.2k
    {
351
26.2k
        return m_poSRS.get();
352
26.2k
    }
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(CSLConstList papszMetadata,
360
                       const char *pszDomain = "") override;
361
    CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
362
                           const char *pszDomain = "") override;
363
364
    CSLConstList 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
1.57k
    {
372
1.57k
        return m_poGCP_SRS.get();
373
1.57k
    }
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
                           CSLConstList 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
                      CSLConstList 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
179k
    {
425
179k
        m_nCompatibleForDatasetIO = -1;
426
179k
    }
427
428
    /* Used by PDF driver for example */
429
    GDALDataset *GetSingleSimpleSource();
430
    void BuildVirtualOverviews();
431
432
    void UnsetPreservedRelativeFilenames();
433
434
    bool IsBlockSizeSpecified() const
435
48.5k
    {
436
48.5k
        return m_bBlockSizeSpecified;
437
48.5k
    }
438
439
    int GetBlockXSize() const
440
48.5k
    {
441
48.5k
        return m_nBlockXSize;
442
48.5k
    }
443
444
    int GetBlockYSize() const
445
48.5k
    {
446
48.5k
        return m_nBlockYSize;
447
48.5k
    }
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
                               CSLConstList 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
                           CSLConstList 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
                           CSLConstList 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(CSLConstList papszMD,
878
                       const char *pszDomain = "") override;
879
    CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
880
                           const char *pszDomain = "") override;
881
882
    double GetOffset(int *pbSuccess = nullptr) override;
883
    CPLErr SetOffset(double) override;
884
    double GetScale(int *pbSuccess = nullptr) override;
885
    CPLErr SetScale(double) override;
886
887
    int GetOverviewCount() override;
888
    GDALRasterBand *GetOverview(int) override;
889
890
    CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets,
891
                        GUIntBig *panHistogram, int bIncludeOutOfRange,
892
                        int bApproxOK, GDALProgressFunc,
893
                        void *pProgressData) override;
894
895
    CPLErr GetDefaultHistogram(double *pdfMin, double *pdfMax, int *pnBuckets,
896
                               GUIntBig **ppanHistogram, int bForce,
897
                               GDALProgressFunc, void *pProgressData) override;
898
899
    virtual CPLErr SetDefaultHistogram(double dfMin, double dfMax, int nBuckets,
900
                                       GUIntBig *panHistogram) override;
901
902
    CPLErr CopyCommonInfoFrom(GDALRasterBand *);
903
904
    virtual void GetFileList(char ***ppapszFileList, int *pnSize,
905
                             int *pnMaxSize, CPLHashSet *hSetFiles);
906
907
    void SetDescription(const char *) override;
908
909
    GDALRasterBand *GetMaskBand() override;
910
    int GetMaskFlags() override;
911
912
    CPLErr CreateMaskBand(int nFlagsIn) override;
913
914
    void SetMaskBand(std::unique_ptr<VRTRasterBand> poMaskBand);
915
916
    void SetIsMaskBand();
917
918
    bool IsMaskBand() const override;
919
920
    CPLErr UnsetNoDataValue();
921
922
    virtual int CloseDependentDatasets();
923
924
    virtual bool IsSourcedRasterBand()
925
29
    {
926
29
        return false;
927
29
    }
928
929
    virtual bool IsPansharpenRasterBand()
930
0
    {
931
0
        return false;
932
0
    }
933
};
934
935
/************************************************************************/
936
/*                         VRTSourcedRasterBand                         */
937
/************************************************************************/
938
939
class VRTSimpleSource;
940
941
class CPL_DLL VRTSourcedRasterBand CPL_NON_FINAL : public VRTRasterBand
942
{
943
  private:
944
    CPLString m_osLastLocationInfo{};
945
    CPLStringList m_aosSourceList{};
946
    int m_nSkipBufferInitialization = -1;
947
948
    bool CanUseSourcesMinMaxImplementations();
949
950
    bool IsMosaicOfNonOverlappingSimpleSourcesOfFullRasterNoResAndTypeChange(
951
        bool bAllowMaxValAdjustment) const;
952
953
    CPL_DISALLOW_COPY_ASSIGN(VRTSourcedRasterBand)
954
955
  protected:
956
    bool SkipBufferInitialization();
957
958
    void InitializeOutputBuffer(void *pData, int nBufXSize, int nBufYSize,
959
                                GDALDataType eBufType, GSpacing nPixelSpace,
960
                                GSpacing nLineSpace) const;
961
962
  public:
963
    std::vector<std::unique_ptr<VRTSource>> m_papoSources{};
964
965
    VRTSourcedRasterBand(GDALDataset *poDS, int nBand);
966
    VRTSourcedRasterBand(GDALDataType eType, int nXSize, int nYSize);
967
    VRTSourcedRasterBand(GDALDataset *poDS, int nBand, GDALDataType eType,
968
                         int nXSize, int nYSize);
969
    VRTSourcedRasterBand(GDALDataset *poDS, int nBand, GDALDataType eType,
970
                         int nXSize, int nYSize, int nBlockXSizeIn,
971
                         int nBlockYSizeIn);
972
    ~VRTSourcedRasterBand() override;
973
974
    CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
975
                     GDALDataType, GSpacing nPixelSpace, GSpacing nLineSpace,
976
                     GDALRasterIOExtraArg *psExtraArg) override;
977
978
    bool MayMultiBlockReadingBeMultiThreaded() const override;
979
980
    virtual int IGetDataCoverageStatus(int nXOff, int nYOff, int nXSize,
981
                                       int nYSize, int nMaskFlagStop,
982
                                       double *pdfDataPct) override;
983
984
    char **GetMetadataDomainList() override;
985
    virtual const char *GetMetadataItem(const char *pszName,
986
                                        const char *pszDomain = "") override;
987
    CSLConstList GetMetadata(const char *pszDomain = "") override;
988
    CPLErr SetMetadata(CSLConstList papszMetadata,
989
                       const char *pszDomain = "") override;
990
    CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
991
                           const char *pszDomain = "") override;
992
993
    virtual CPLErr XMLInit(const CPLXMLNode *, const char *,
994
                           VRTMapSharedResources &) override;
995
    virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath,
996
                                       bool &bHasWarnedAboutRAMUsage,
997
                                       size_t &nAccRAMUsage) override;
998
999
    double GetMinimum(int *pbSuccess = nullptr) override;
1000
    double GetMaximum(int *pbSuccess = nullptr) override;
1001
    virtual CPLErr ComputeRasterMinMax(int bApproxOK,
1002
                                       double *adfMinMax) override;
1003
    virtual CPLErr ComputeStatistics(int bApproxOK, double *pdfMin,
1004
                                     double *pdfMax, double *pdfMean,
1005
                                     double *pdfStdDev,
1006
                                     GDALProgressFunc pfnProgress,
1007
                                     void *pProgressData) override;
1008
    CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets,
1009
                        GUIntBig *panHistogram, int bIncludeOutOfRange,
1010
                        int bApproxOK, GDALProgressFunc pfnProgress,
1011
                        void *pProgressData) override;
1012
1013
    CPLErr AddSource(std::unique_ptr<VRTSource>);
1014
1015
    CPLErr AddSource(VRTSource *);
1016
1017
    CPLErr AddSimpleSource(const char *pszFilename, int nBand,
1018
                           double dfSrcXOff = -1, double dfSrcYOff = -1,
1019
                           double dfSrcXSize = -1, double dfSrcYSize = -1,
1020
                           double dfDstXOff = -1, double dfDstYOff = -1,
1021
                           double dfDstXSize = -1, double dfDstYSize = -1,
1022
                           const char *pszResampling = "near",
1023
                           double dfNoDataValue = VRT_NODATA_UNSET);
1024
1025
    CPLErr AddSimpleSource(GDALRasterBand *poSrcBand, double dfSrcXOff = -1,
1026
                           double dfSrcYOff = -1, double dfSrcXSize = -1,
1027
                           double dfSrcYSize = -1, double dfDstXOff = -1,
1028
                           double dfDstYOff = -1, double dfDstXSize = -1,
1029
                           double dfDstYSize = -1,
1030
                           const char *pszResampling = "near",
1031
                           double dfNoDataValue = VRT_NODATA_UNSET);
1032
1033
    CPLErr AddComplexSource(const char *pszFilename, int nBand,
1034
                            double dfSrcXOff = -1, double dfSrcYOff = -1,
1035
                            double dfSrcXSize = -1, double dfSrcYSize = -1,
1036
                            double dfDstXOff = -1, double dfDstYOff = -1,
1037
                            double dfDstXSize = -1, double dfDstYSize = -1,
1038
                            double dfScaleOff = 0.0, double dfScaleRatio = 1.0,
1039
                            double dfNoDataValue = VRT_NODATA_UNSET,
1040
                            int nColorTableComponent = 0);
1041
1042
    CPLErr AddComplexSource(GDALRasterBand *poSrcBand, double dfSrcXOff = -1,
1043
                            double dfSrcYOff = -1, double dfSrcXSize = -1,
1044
                            double dfSrcYSize = -1, double dfDstXOff = -1,
1045
                            double dfDstYOff = -1, double dfDstXSize = -1,
1046
                            double dfDstYSize = -1, double dfScaleOff = 0.0,
1047
                            double dfScaleRatio = 1.0,
1048
                            double dfNoDataValue = VRT_NODATA_UNSET,
1049
                            int nColorTableComponent = 0);
1050
1051
    CPLErr AddMaskBandSource(GDALRasterBand *poSrcBand, double dfSrcXOff = -1,
1052
                             double dfSrcYOff = -1, double dfSrcXSize = -1,
1053
                             double dfSrcYSize = -1, double dfDstXOff = -1,
1054
                             double dfDstYOff = -1, double dfDstXSize = -1,
1055
                             double dfDstYSize = -1);
1056
1057
    CPLErr AddFuncSource(VRTImageReadFunc pfnReadFunc, void *hCBData,
1058
                         double dfNoDataValue = VRT_NODATA_UNSET);
1059
1060
    void ConfigureSource(VRTSimpleSource *poSimpleSource,
1061
                         GDALRasterBand *poSrcBand, int bAddAsMaskBand,
1062
                         double dfSrcXOff, double dfSrcYOff, double dfSrcXSize,
1063
                         double dfSrcYSize, double dfDstXOff, double dfDstYOff,
1064
                         double dfDstXSize, double dfDstYSize);
1065
1066
    void RemoveCoveredSources(CSLConstList papszOptions = nullptr);
1067
1068
    bool CanIRasterIOBeForwardedToEachSource(
1069
        GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize,
1070
        int nBufXSize, int nBufYSize,
1071
        const GDALRasterIOExtraArg *psExtraArg) const;
1072
1073
    bool CanMultiThreadRasterIO(double dfXOff, double dfYOff, double dfXSize,
1074
                                double dfYSize,
1075
                                int &nContributingSources) const;
1076
1077
    CPLErr IReadBlock(int, int, void *) override;
1078
1079
    virtual void GetFileList(char ***ppapszFileList, int *pnSize,
1080
                             int *pnMaxSize, CPLHashSet *hSetFiles) override;
1081
1082
    int CloseDependentDatasets() override;
1083
1084
    bool IsSourcedRasterBand() override
1085
269k
    {
1086
269k
        return true;
1087
269k
    }
1088
1089
    CPLErr FlushCache(bool bAtClosing) override;
1090
};
1091
1092
/************************************************************************/
1093
/*                         VRTWarpedRasterBand                          */
1094
/************************************************************************/
1095
1096
class CPL_DLL VRTWarpedRasterBand final : public VRTRasterBand
1097
{
1098
  public:
1099
    VRTWarpedRasterBand(GDALDataset *poDS, int nBand,
1100
                        GDALDataType eType = GDT_Unknown);
1101
    ~VRTWarpedRasterBand() override;
1102
1103
    virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath,
1104
                                       bool &bHasWarnedAboutRAMUsage,
1105
                                       size_t &nAccRAMUsage) override;
1106
1107
    CPLErr IReadBlock(int, int, void *) override;
1108
    CPLErr IWriteBlock(int, int, void *) override;
1109
1110
    CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1111
                     int nYSize, void *pData, int nBufXSize, int nBufYSize,
1112
                     GDALDataType eBufType, GSpacing nPixelSpace,
1113
                     GSpacing nLineSpace,
1114
                     GDALRasterIOExtraArg *psExtraArg) override;
1115
1116
    int GetOverviewCount() override;
1117
    GDALRasterBand *GetOverview(int) override;
1118
1119
    bool
1120
    EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
1121
1122
  private:
1123
    int m_nIRasterIOCounter =
1124
        0;  //! Protects against infinite recursion inside IRasterIO()
1125
1126
    int GetBestOverviewLevel(int &nXOff, int &nYOff, int &nXSize, int &nYSize,
1127
                             int nBufXSize, int nBufYSize,
1128
                             GDALRasterIOExtraArg *psExtraArg) const;
1129
};
1130
1131
/************************************************************************/
1132
/*                      VRTPansharpenedRasterBand                       */
1133
/************************************************************************/
1134
1135
class VRTPansharpenedRasterBand final : public VRTRasterBand
1136
{
1137
    int m_nIndexAsPansharpenedBand;
1138
1139
  public:
1140
    VRTPansharpenedRasterBand(GDALDataset *poDS, int nBand,
1141
                              GDALDataType eDataType = GDT_Unknown);
1142
    ~VRTPansharpenedRasterBand() override;
1143
1144
    virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath,
1145
                                       bool &bHasWarnedAboutRAMUsage,
1146
                                       size_t &nAccRAMUsage) override;
1147
1148
    CPLErr IReadBlock(int, int, void *) override;
1149
1150
    CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1151
                     int nYSize, void *pData, int nBufXSize, int nBufYSize,
1152
                     GDALDataType eBufType, GSpacing nPixelSpace,
1153
                     GSpacing nLineSpace,
1154
                     GDALRasterIOExtraArg *psExtraArg) override;
1155
1156
    int GetOverviewCount() override;
1157
    GDALRasterBand *GetOverview(int) override;
1158
1159
    bool IsPansharpenRasterBand() override
1160
0
    {
1161
0
        return true;
1162
0
    }
1163
1164
    void SetIndexAsPansharpenedBand(int nIdx)
1165
0
    {
1166
0
        m_nIndexAsPansharpenedBand = nIdx;
1167
0
    }
1168
1169
    int GetIndexAsPansharpenedBand() const
1170
0
    {
1171
0
        return m_nIndexAsPansharpenedBand;
1172
0
    }
1173
};
1174
1175
/************************************************************************/
1176
/*                        VRTProcessedRasterBand                        */
1177
/************************************************************************/
1178
1179
class VRTProcessedRasterBand final : public VRTRasterBand
1180
{
1181
  public:
1182
    VRTProcessedRasterBand(VRTProcessedDataset *poDS, int nBand,
1183
                           GDALDataType eDataType = GDT_Unknown);
1184
1185
    CPLErr IReadBlock(int, int, void *) override;
1186
1187
    int GetOverviewCount() override;
1188
    GDALRasterBand *GetOverview(int) override;
1189
1190
    virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath,
1191
                                       bool &bHasWarnedAboutRAMUsage,
1192
                                       size_t &nAccRAMUsage) override;
1193
};
1194
1195
/************************************************************************/
1196
/*                         VRTDerivedRasterBand                         */
1197
/************************************************************************/
1198
1199
class VRTDerivedRasterBandPrivateData;
1200
1201
class CPL_DLL VRTDerivedRasterBand CPL_NON_FINAL : public VRTSourcedRasterBand
1202
{
1203
    VRTDerivedRasterBandPrivateData *m_poPrivate;
1204
    bool InitializePython();
1205
    CPLErr GetPixelFunctionArguments(
1206
        const CPLString &, const std::vector<int> &anMapBufferIdxToSourceIdx,
1207
        int nXOff, int nYOff, std::vector<std::pair<CPLString, CPLString>> &);
1208
1209
    CPL_DISALLOW_COPY_ASSIGN(VRTDerivedRasterBand)
1210
1211
  public:
1212
    CPLString osFuncName{};
1213
    GDALDataType eSourceTransferType;
1214
1215
    using PixelFunc =
1216
        std::function<CPLErr(void **, int, void *, int, int, GDALDataType,
1217
                             GDALDataType, int, int, CSLConstList)>;
1218
1219
    VRTDerivedRasterBand(GDALDataset *poDS, int nBand);
1220
    VRTDerivedRasterBand(GDALDataset *poDS, int nBand, GDALDataType eType,
1221
                         int nXSize, int nYSize, int nBlockXSizeIn = 0,
1222
                         int nBlockYSizeIn = 0);
1223
    ~VRTDerivedRasterBand() override;
1224
1225
    CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
1226
                     GDALDataType, GSpacing nPixelSpace, GSpacing nLineSpace,
1227
                     GDALRasterIOExtraArg *psExtraArg) override;
1228
1229
    virtual int IGetDataCoverageStatus(int nXOff, int nYOff, int nXSize,
1230
                                       int nYSize, int nMaskFlagStop,
1231
                                       double *pdfDataPct) override;
1232
1233
    static CPLErr AddPixelFunction(const char *pszFuncNameIn,
1234
                                   GDALDerivedPixelFunc pfnPixelFunc);
1235
    static CPLErr AddPixelFunction(const char *pszFuncNameIn,
1236
                                   GDALDerivedPixelFuncWithArgs pfnPixelFunc,
1237
                                   const char *pszMetadata);
1238
1239
    static const std::pair<PixelFunc, std::string> *
1240
    GetPixelFunction(const char *pszFuncNameIn);
1241
1242
    static std::vector<std::string> GetPixelFunctionNames();
1243
1244
    void SetPixelFunctionName(const char *pszFuncNameIn);
1245
    void AddPixelFunctionArgument(const char *pszArg, const char *pszValue);
1246
    void SetSkipNonContributingSources(bool bSkip);
1247
    void SetSourceTransferType(GDALDataType eDataType);
1248
    void SetPixelFunctionLanguage(const char *pszLanguage);
1249
1250
    virtual CPLErr XMLInit(const CPLXMLNode *, const char *,
1251
                           VRTMapSharedResources &) override;
1252
    virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath,
1253
                                       bool &bHasWarnedAboutRAMUsage,
1254
                                       size_t &nAccRAMUsage) override;
1255
1256
    double GetMinimum(int *pbSuccess = nullptr) override;
1257
    double GetMaximum(int *pbSuccess = nullptr) override;
1258
    virtual CPLErr ComputeRasterMinMax(int bApproxOK,
1259
                                       double *adfMinMax) override;
1260
    virtual CPLErr ComputeStatistics(int bApproxOK, double *pdfMin,
1261
                                     double *pdfMax, double *pdfMean,
1262
                                     double *pdfStdDev,
1263
                                     GDALProgressFunc pfnProgress,
1264
                                     void *pProgressData) override;
1265
    CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets,
1266
                        GUIntBig *panHistogram, int bIncludeOutOfRange,
1267
                        int bApproxOK, GDALProgressFunc pfnProgress,
1268
                        void *pProgressData) override;
1269
1270
    static void Cleanup();
1271
};
1272
1273
#ifndef GDAL_VRT_DISABLE_RAWRASTERBAND
1274
/************************************************************************/
1275
/*                           VRTRawRasterBand                           */
1276
/************************************************************************/
1277
1278
class RawRasterBand;
1279
1280
class CPL_DLL VRTRawRasterBand CPL_NON_FINAL : public VRTRasterBand
1281
{
1282
    RawRasterBand *m_poRawRaster;
1283
1284
    char *m_pszSourceFilename;
1285
    int m_bRelativeToVRT;
1286
1287
    CPL_DISALLOW_COPY_ASSIGN(VRTRawRasterBand)
1288
1289
  public:
1290
    VRTRawRasterBand(GDALDataset *poDS, int nBand,
1291
                     GDALDataType eType = GDT_Unknown);
1292
    ~VRTRawRasterBand() override;
1293
1294
    virtual CPLErr XMLInit(const CPLXMLNode *, const char *,
1295
                           VRTMapSharedResources &) override;
1296
    virtual CPLXMLNode *SerializeToXML(const char *pszVRTPath,
1297
                                       bool &bHasWarnedAboutRAMUsage,
1298
                                       size_t &nAccRAMUsage) override;
1299
1300
    CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
1301
                     GDALDataType, GSpacing nPixelSpace, GSpacing nLineSpace,
1302
                     GDALRasterIOExtraArg *psExtraArg) override;
1303
1304
    CPLErr IReadBlock(int, int, void *) override;
1305
    CPLErr IWriteBlock(int, int, void *) override;
1306
1307
    CPLErr SetRawLink(const char *pszFilename, const char *pszVRTPath,
1308
                      int bRelativeToVRT, vsi_l_offset nImageOffset,
1309
                      int nPixelOffset, int nLineOffset,
1310
                      const char *pszByteOrder);
1311
1312
    void ClearRawLink();
1313
1314
    CPLVirtualMem *GetVirtualMemAuto(GDALRWFlag eRWFlag, int *pnPixelSpace,
1315
                                     GIntBig *pnLineSpace,
1316
                                     CSLConstList papszOptions) override;
1317
1318
    virtual void GetFileList(char ***ppapszFileList, int *pnSize,
1319
                             int *pnMaxSize, CPLHashSet *hSetFiles) override;
1320
};
1321
#endif
1322
1323
/************************************************************************/
1324
/*                              VRTDriver                               */
1325
/************************************************************************/
1326
1327
class VRTDriver final : public GDALDriver
1328
{
1329
    CPL_DISALLOW_COPY_ASSIGN(VRTDriver)
1330
1331
    std::mutex m_oMutex{};
1332
    std::map<std::string, VRTSourceParser> m_oMapSourceParser{};
1333
1334
  public:
1335
    VRTDriver();
1336
    ~VRTDriver() override;
1337
1338
    char **papszSourceParsers;
1339
1340
    char **GetMetadataDomainList() override;
1341
    CSLConstList GetMetadata(const char *pszDomain = "") override;
1342
    CPLErr SetMetadata(CSLConstList papszMetadata,
1343
                       const char *pszDomain = "") override;
1344
1345
    VRTSource *ParseSource(const CPLXMLNode *psSrc, const char *pszVRTPath,
1346
                           VRTMapSharedResources &oMapSharedSources);
1347
    void AddSourceParser(const char *pszElementName, VRTSourceParser pfnParser);
1348
};
1349
1350
/************************************************************************/
1351
/*                           VRTSimpleSource                            */
1352
/************************************************************************/
1353
1354
class CPL_DLL VRTSimpleSource CPL_NON_FINAL : public VRTSource
1355
{
1356
    CPL_DISALLOW_COPY_ASSIGN(VRTSimpleSource)
1357
1358
  private:
1359
    // Owned by the VRTDataset
1360
    VRTMapSharedResources *m_poMapSharedSources = nullptr;
1361
1362
    mutable GDALRasterBand *m_poRasterBand = nullptr;
1363
1364
    // When poRasterBand is a mask band, poMaskBandMainBand is the band
1365
    // from which the mask band is taken.
1366
    mutable GDALRasterBand *m_poMaskBandMainBand = nullptr;
1367
1368
    CPLStringList m_aosOpenOptionsOri{};  // as read in the original source XML
1369
    CPLStringList
1370
        m_aosOpenOptions{};  // same as above, but potentially augmented with ROOT_PATH
1371
    bool m_bSrcDSNameFromVRT =
1372
        false;  // whereas content in m_osSrcDSName is a <VRTDataset> XML node
1373
1374
    void OpenSource() const;
1375
1376
    GDALDataset *GetSourceDataset() const;
1377
1378
  protected:
1379
    friend class VRTSourcedRasterBand;
1380
    friend class VRTDerivedRasterBand;
1381
    friend class VRTDataset;
1382
    friend class GDALTileIndexDataset;
1383
    friend class GDALTileIndexBand;
1384
1385
    int m_nBand = 0;
1386
    bool m_bGetMaskBand = false;
1387
1388
    /* Value for uninitialized source or destination window. It is chosen such
1389
     * that SrcToDst() and DstToSrc() are no-ops if both source and destination
1390
     * windows are unset.
1391
     */
1392
    static constexpr double UNINIT_WINDOW = -1.0;
1393
1394
    double m_dfSrcXOff = UNINIT_WINDOW;
1395
    double m_dfSrcYOff = UNINIT_WINDOW;
1396
    double m_dfSrcXSize = UNINIT_WINDOW;
1397
    double m_dfSrcYSize = UNINIT_WINDOW;
1398
1399
    double m_dfDstXOff = UNINIT_WINDOW;
1400
    double m_dfDstYOff = UNINIT_WINDOW;
1401
    double m_dfDstXSize = UNINIT_WINDOW;
1402
    double m_dfDstYSize = UNINIT_WINDOW;
1403
1404
    CPLString m_osResampling{};
1405
1406
    int m_nMaxValue = 0;
1407
1408
    int m_bRelativeToVRTOri = -1;
1409
    CPLString m_osSourceFileNameOri{};
1410
    int m_nExplicitSharedStatus = -1;  // -1 unknown, 0 = unshared, 1 = shared
1411
    CPLString m_osSrcDSName{};
1412
1413
    bool m_bDropRefOnSrcBand = true;
1414
1415
    int NeedMaxValAdjustment() const;
1416
1417
    GDALRasterBand *GetRasterBandNoOpen() const
1418
0
    {
1419
0
        return m_poRasterBand;
1420
0
    }
1421
1422
    void SetRasterBand(GDALRasterBand *poBand, bool bDropRef)
1423
0
    {
1424
0
        m_poRasterBand = poBand;
1425
0
        m_bDropRefOnSrcBand = bDropRef;
1426
0
    }
1427
1428
    virtual bool ValidateOpenedBand(GDALRasterBand * /*poBand*/) const
1429
3.96k
    {
1430
3.96k
        return true;
1431
3.96k
    }
1432
1433
    /** Returns whether the source window is set */
1434
    bool IsSrcWinSet() const
1435
53.5k
    {
1436
53.5k
        return m_dfSrcXOff != UNINIT_WINDOW || m_dfSrcYOff != UNINIT_WINDOW ||
1437
0
               m_dfSrcXSize != UNINIT_WINDOW || m_dfSrcYSize != UNINIT_WINDOW;
1438
53.5k
    }
1439
1440
    /** Returns whether the destination window is set */
1441
    bool IsDstWinSet() const
1442
666k
    {
1443
666k
        return m_dfDstXOff != UNINIT_WINDOW || m_dfDstYOff != UNINIT_WINDOW ||
1444
3.14k
               m_dfDstXSize != UNINIT_WINDOW || m_dfDstYSize != UNINIT_WINDOW;
1445
666k
    }
1446
1447
    void AddSourceFilenameNode(const char *pszVRTPath, CPLXMLNode *psSrc);
1448
1449
  public:
1450
    VRTSimpleSource();
1451
    VRTSimpleSource(const VRTSimpleSource *poSrcSource, double dfXDstRatio,
1452
                    double dfYDstRatio);
1453
    ~VRTSimpleSource() override;
1454
1455
    virtual CPLErr XMLInit(const CPLXMLNode *psTree, const char *,
1456
                           VRTMapSharedResources &) override;
1457
    CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
1458
1459
    CPLErr ParseSrcRectAndDstRect(const CPLXMLNode *psSrc);
1460
1461
    void SetSrcBand(const char *pszFilename, int nBand);
1462
    void SetSrcBand(GDALRasterBand *);
1463
    void SetSrcMaskBand(GDALRasterBand *);
1464
    void SetSrcWindow(double, double, double, double);
1465
    void SetDstWindow(double, double, double, double);
1466
    void GetDstWindow(double &, double &, double &, double &) const;
1467
    bool DstWindowIntersects(double dfXOff, double dfYOff, double dfXSize,
1468
                             double dfYSize) const;
1469
1470
    const std::string &GetSourceDatasetName() const
1471
0
    {
1472
0
        return m_osSrcDSName;
1473
0
    }
1474
1475
    // Must be called after SetSrcBand()
1476
    void SetSourceDatasetName(const char *pszFilename, bool bRelativeToVRT);
1477
1478
    const CPLString &GetResampling() const
1479
350
    {
1480
350
        return m_osResampling;
1481
350
    }
1482
1483
    void SetResampling(const char *pszResampling);
1484
1485
    int GetSrcDstWindow(double, double, double, double, int, int,
1486
                        double *pdfReqXOff, double *pdfReqYOff,
1487
                        double *pdfReqXSize, double *pdfReqYSize, int *, int *,
1488
                        int *, int *, int *, int *, int *, int *,
1489
                        bool &bErrorOut);
1490
1491
    int GetSrcDstWindow(double, double, double, double, int, int,
1492
                        GDALRIOResampleAlg eResampleAlg, double *pdfReqXOff,
1493
                        double *pdfReqYOff, double *pdfReqXSize,
1494
                        double *pdfReqYSize, int *, int *, int *, int *, int *,
1495
                        int *, int *, int *, bool &bErrorOut);
1496
1497
    virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
1498
                            int nXSize, int nYSize, void *pData, int nBufXSize,
1499
                            int nBufYSize, GDALDataType eBufType,
1500
                            GSpacing nPixelSpace, GSpacing nLineSpace,
1501
                            GDALRasterIOExtraArg *psExtraArgIn,
1502
                            WorkingState &oWorkingState) override;
1503
1504
    double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
1505
    double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
1506
    CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax,
1507
                        int nBuckets, GUIntBig *panHistogram,
1508
                        int bIncludeOutOfRange, int bApproxOK,
1509
                        GDALProgressFunc pfnProgress,
1510
                        void *pProgressData) override;
1511
1512
    void DstToSrc(double dfX, double dfY, double &dfXOut, double &dfYOut) const;
1513
    void SrcToDst(double dfX, double dfY, double &dfXOut, double &dfYOut) const;
1514
1515
    virtual void GetFileList(char ***ppapszFileList, int *pnSize,
1516
                             int *pnMaxSize, CPLHashSet *hSetFiles) override;
1517
1518
    bool IsSimpleSource() const override
1519
577k
    {
1520
577k
        return true;
1521
577k
    }
1522
1523
    /** Returns the same value as GetType() called on objects that are exactly
1524
     * instances of VRTSimpleSource.
1525
     */
1526
    static const char *GetTypeStatic();
1527
1528
    const char *GetType() const override;
1529
1530
    CPLErr FlushCache(bool bAtClosing) override;
1531
1532
    GDALRasterBand *GetRasterBand() const;
1533
    GDALRasterBand *GetMaskBandMainBand();
1534
    bool IsSameExceptBandNumber(const VRTSimpleSource *poOtherSource) const;
1535
    CPLErr DatasetRasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
1536
                           int nXSize, int nYSize, void *pData, int nBufXSize,
1537
                           int nBufYSize, GDALDataType eBufType, int nBandCount,
1538
                           const int *panBandMap, GSpacing nPixelSpace,
1539
                           GSpacing nLineSpace, GSpacing nBandSpace,
1540
                           GDALRasterIOExtraArg *psExtraArg);
1541
1542
    void UnsetPreservedRelativeFilenames();
1543
1544
    void SetMaxValue(int nVal)
1545
6.76k
    {
1546
6.76k
        m_nMaxValue = nVal;
1547
6.76k
    }
1548
};
1549
1550
/************************************************************************/
1551
/*                          VRTAveragedSource                           */
1552
/************************************************************************/
1553
1554
class VRTAveragedSource final : public VRTSimpleSource
1555
{
1556
    CPL_DISALLOW_COPY_ASSIGN(VRTAveragedSource)
1557
1558
    int m_bNoDataSet = false;
1559
    double m_dfNoDataValue = VRT_NODATA_UNSET;
1560
1561
  public:
1562
    VRTAveragedSource();
1563
    virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
1564
                            int nXSize, int nYSize, void *pData, int nBufXSize,
1565
                            int nBufYSize, GDALDataType eBufType,
1566
                            GSpacing nPixelSpace, GSpacing nLineSpace,
1567
                            GDALRasterIOExtraArg *psExtraArgIn,
1568
                            WorkingState &oWorkingState) override;
1569
1570
    double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
1571
    double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
1572
    CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax,
1573
                        int nBuckets, GUIntBig *panHistogram,
1574
                        int bIncludeOutOfRange, int bApproxOK,
1575
                        GDALProgressFunc pfnProgress,
1576
                        void *pProgressData) override;
1577
1578
    void SetNoDataValue(double dfNoDataValue);
1579
1580
    CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
1581
1582
    /** Returns the same value as GetType() called on objects that are exactly
1583
     * instances of VRTAveragedSource.
1584
     */
1585
    static const char *GetTypeStatic();
1586
1587
    const char *GetType() const override;
1588
};
1589
1590
/************************************************************************/
1591
/*                       VRTNoDataFromMaskSource                        */
1592
/************************************************************************/
1593
1594
class VRTNoDataFromMaskSource final : public VRTSimpleSource
1595
{
1596
    CPL_DISALLOW_COPY_ASSIGN(VRTNoDataFromMaskSource)
1597
1598
    bool m_bNoDataSet = false;
1599
    double m_dfNoDataValue = 0;
1600
    double m_dfMaskValueThreshold = 0;
1601
    bool m_bHasRemappedValue = false;
1602
    double m_dfRemappedValue = 0;
1603
1604
  public:
1605
    VRTNoDataFromMaskSource();
1606
    virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
1607
                            int nXSize, int nYSize, void *pData, int nBufXSize,
1608
                            int nBufYSize, GDALDataType eBufType,
1609
                            GSpacing nPixelSpace, GSpacing nLineSpace,
1610
                            GDALRasterIOExtraArg *psExtraArgIn,
1611
                            WorkingState &oWorkingState) override;
1612
1613
    double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
1614
    double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
1615
    CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax,
1616
                        int nBuckets, GUIntBig *panHistogram,
1617
                        int bIncludeOutOfRange, int bApproxOK,
1618
                        GDALProgressFunc pfnProgress,
1619
                        void *pProgressData) override;
1620
1621
    void SetParameters(double dfNoDataValue, double dfMaskValueThreshold);
1622
    void SetParameters(double dfNoDataValue, double dfMaskValueThreshold,
1623
                       double dfRemappedValue);
1624
1625
    virtual CPLErr XMLInit(const CPLXMLNode *psTree, const char *,
1626
                           VRTMapSharedResources &) override;
1627
    CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
1628
1629
    /** Returns the same value as GetType() called on objects that are exactly
1630
     * instances of VRTNoDataFromMaskSource.
1631
     */
1632
    static const char *GetTypeStatic();
1633
1634
    const char *GetType() const override;
1635
};
1636
1637
/************************************************************************/
1638
/*                           VRTComplexSource                           */
1639
/************************************************************************/
1640
1641
class CPL_DLL VRTComplexSource CPL_NON_FINAL : public VRTSimpleSource
1642
{
1643
    CPL_DISALLOW_COPY_ASSIGN(VRTComplexSource)
1644
1645
  protected:
1646
    static constexpr int PROCESSING_FLAG_NODATA = 1 << 0;
1647
    static constexpr int PROCESSING_FLAG_USE_MASK_BAND =
1648
        1 << 1;  // Mutually exclusive with NODATA
1649
    static constexpr int PROCESSING_FLAG_SCALING_LINEAR = 1 << 2;
1650
    static constexpr int PROCESSING_FLAG_SCALING_EXPONENTIAL =
1651
        1 << 3;  // Mutually exclusive with SCALING_LINEAR
1652
    static constexpr int PROCESSING_FLAG_COLOR_TABLE_EXPANSION = 1 << 4;
1653
    static constexpr int PROCESSING_FLAG_LUT = 1 << 5;
1654
1655
    int m_nProcessingFlags = 0;
1656
1657
    // adjusted value should be read with GetAdjustedNoDataValue()
1658
    double m_dfNoDataValue = VRT_NODATA_UNSET;
1659
    std::string
1660
        m_osNoDataValueOri{};  // string value read in XML deserialization
1661
1662
    double m_dfScaleOff = 0;    // For linear scaling.
1663
    double m_dfScaleRatio = 1;  // For linear scaling.
1664
1665
    // For non-linear scaling with a power function.
1666
    bool m_bSrcMinMaxDefined = false;
1667
    double m_dfSrcMin = 0;
1668
    double m_dfSrcMax = 0;
1669
    double m_dfDstMin = 0;
1670
    double m_dfDstMax = 0;
1671
    double m_dfExponent = 1;
1672
    bool m_bClip = true;  // Only taken into account for non-linear scaling
1673
1674
    int m_nColorTableComponent = 0;
1675
1676
    std::vector<double> m_adfLUTInputs{};
1677
    std::vector<double> m_adfLUTOutputs{};
1678
1679
    double GetAdjustedNoDataValue() const;
1680
1681
    template <class WorkingDT>
1682
    CPLErr
1683
    RasterIOInternal(GDALRasterBand *poSourceBand,
1684
                     GDALDataType eVRTBandDataType, int nReqXOff, int nReqYOff,
1685
                     int nReqXSize, int nReqYSize, void *pData, int nOutXSize,
1686
                     int nOutYSize, GDALDataType eBufType, GSpacing nPixelSpace,
1687
                     GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg,
1688
                     GDALDataType eWrkDataType, WorkingState &oWorkingState);
1689
1690
    template <class SourceDT, GDALDataType eSourceType>
1691
    CPLErr RasterIOProcessNoData(GDALRasterBand *poSourceBand,
1692
                                 GDALDataType eVRTBandDataType, int nReqXOff,
1693
                                 int nReqYOff, int nReqXSize, int nReqYSize,
1694
                                 void *pData, int nOutXSize, int nOutYSize,
1695
                                 GDALDataType eBufType, GSpacing nPixelSpace,
1696
                                 GSpacing nLineSpace,
1697
                                 GDALRasterIOExtraArg *psExtraArg,
1698
                                 WorkingState &oWorkingState);
1699
1700
  public:
1701
35.8k
    VRTComplexSource() = default;
1702
    VRTComplexSource(const VRTComplexSource *poSrcSource, double dfXDstRatio,
1703
                     double dfYDstRatio);
1704
1705
    virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
1706
                            int nXSize, int nYSize, void *pData, int nBufXSize,
1707
                            int nBufYSize, GDALDataType eBufType,
1708
                            GSpacing nPixelSpace, GSpacing nLineSpace,
1709
                            GDALRasterIOExtraArg *psExtraArgIn,
1710
                            WorkingState &oWorkingState) override;
1711
1712
    double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
1713
    double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
1714
    CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax,
1715
                        int nBuckets, GUIntBig *panHistogram,
1716
                        int bIncludeOutOfRange, int bApproxOK,
1717
                        GDALProgressFunc pfnProgress,
1718
                        void *pProgressData) override;
1719
1720
    CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
1721
    virtual CPLErr XMLInit(const CPLXMLNode *, const char *,
1722
                           VRTMapSharedResources &) override;
1723
1724
    /** Returns the same value as GetType() called on objects that are exactly
1725
     * instances of VRTComplexSource.
1726
     */
1727
    static const char *GetTypeStatic();
1728
1729
    const char *GetType() const override;
1730
1731
    bool AreValuesUnchanged() const;
1732
1733
    double LookupValue(double dfInput);
1734
1735
    void SetNoDataValue(double dfNoDataValue);
1736
1737
    void SetUseMaskBand(bool bUseMaskBand)
1738
0
    {
1739
0
        if (bUseMaskBand)
1740
0
            m_nProcessingFlags |= PROCESSING_FLAG_USE_MASK_BAND;
1741
0
        else
1742
0
            m_nProcessingFlags &= ~PROCESSING_FLAG_USE_MASK_BAND;
1743
0
    }
1744
1745
    void SetLinearScaling(double dfOffset, double dfScale);
1746
    void SetPowerScaling(double dfExponent, double dfSrcMin, double dfSrcMax,
1747
                         double dfDstMin, double dfDstMax, bool bClip = true);
1748
    void SetColorTableComponent(int nComponent);
1749
1750
    void SetLUT(const std::vector<double> &adfLUTInputs,
1751
                const std::vector<double> &adfLUTOutputs);
1752
};
1753
1754
/************************************************************************/
1755
/*                          VRTFilteredSource                           */
1756
/************************************************************************/
1757
1758
class VRTFilteredSource CPL_NON_FINAL : public VRTComplexSource
1759
{
1760
  private:
1761
    int IsTypeSupported(GDALDataType eTestType) const;
1762
1763
    CPL_DISALLOW_COPY_ASSIGN(VRTFilteredSource)
1764
1765
  protected:
1766
    int m_nSupportedTypesCount;
1767
    GDALDataType m_aeSupportedTypes[20];
1768
1769
    int m_nExtraEdgePixels;
1770
1771
  public:
1772
    VRTFilteredSource();
1773
    ~VRTFilteredSource() override;
1774
1775
    const char *GetType() const override = 0;
1776
1777
    void SetExtraEdgePixels(int);
1778
    void SetFilteringDataTypesSupported(int, GDALDataType *);
1779
1780
    virtual CPLErr FilterData(int nXSize, int nYSize, GDALDataType eType,
1781
                              GByte *pabySrcData, GByte *pabyDstData) = 0;
1782
1783
    virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
1784
                            int nXSize, int nYSize, void *pData, int nBufXSize,
1785
                            int nBufYSize, GDALDataType eBufType,
1786
                            GSpacing nPixelSpace, GSpacing nLineSpace,
1787
                            GDALRasterIOExtraArg *psExtraArg,
1788
                            WorkingState &oWorkingState) override;
1789
};
1790
1791
/************************************************************************/
1792
/*                       VRTKernelFilteredSource                        */
1793
/************************************************************************/
1794
1795
class VRTKernelFilteredSource CPL_NON_FINAL : public VRTFilteredSource
1796
{
1797
    CPL_DISALLOW_COPY_ASSIGN(VRTKernelFilteredSource)
1798
1799
  protected:
1800
    int m_nKernelSize = 0;
1801
    bool m_bSeparable = false;
1802
    // m_nKernelSize elements if m_bSeparable, m_nKernelSize * m_nKernelSize otherwise
1803
    std::vector<double> m_adfKernelCoefs{};
1804
    bool m_bNormalized = false;
1805
    std::string m_function{};
1806
1807
  public:
1808
    VRTKernelFilteredSource();
1809
1810
    const char *GetType() const override;
1811
1812
    virtual CPLErr XMLInit(const CPLXMLNode *psTree, const char *,
1813
                           VRTMapSharedResources &) override;
1814
    CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
1815
1816
    virtual CPLErr FilterData(int nXSize, int nYSize, GDALDataType eType,
1817
                              GByte *pabySrcData, GByte *pabyDstData) override;
1818
1819
    CPLErr SetKernel(int nKernelSize, bool bSeparable,
1820
                     const std::vector<double> &adfNewCoefs);
1821
    void SetNormalized(bool);
1822
1823
    void SetFunction(const std::string &s)
1824
0
    {
1825
0
        m_function = s;
1826
0
    }
1827
};
1828
1829
/************************************************************************/
1830
/*                       VRTAverageFilteredSource                       */
1831
/************************************************************************/
1832
1833
class VRTAverageFilteredSource final : public VRTKernelFilteredSource
1834
{
1835
    CPL_DISALLOW_COPY_ASSIGN(VRTAverageFilteredSource)
1836
1837
  public:
1838
    explicit VRTAverageFilteredSource(int nKernelSize);
1839
    ~VRTAverageFilteredSource() override;
1840
1841
    const char *GetType() const override;
1842
1843
    virtual CPLErr XMLInit(const CPLXMLNode *psTree, const char *,
1844
                           VRTMapSharedResources &) override;
1845
    CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
1846
};
1847
1848
/************************************************************************/
1849
/*                            VRTFuncSource                             */
1850
/************************************************************************/
1851
class VRTFuncSource final : public VRTSource
1852
{
1853
    CPL_DISALLOW_COPY_ASSIGN(VRTFuncSource)
1854
1855
  public:
1856
    VRTFuncSource();
1857
    ~VRTFuncSource() override;
1858
1859
    virtual CPLErr XMLInit(const CPLXMLNode *, const char *,
1860
                           VRTMapSharedResources &) override
1861
0
    {
1862
0
        return CE_Failure;
1863
0
    }
1864
1865
    CPLXMLNode *SerializeToXML(const char *pszVRTPath) override;
1866
1867
    virtual CPLErr RasterIO(GDALDataType eVRTBandDataType, int nXOff, int nYOff,
1868
                            int nXSize, int nYSize, void *pData, int nBufXSize,
1869
                            int nBufYSize, GDALDataType eBufType,
1870
                            GSpacing nPixelSpace, GSpacing nLineSpace,
1871
                            GDALRasterIOExtraArg *psExtraArg,
1872
                            WorkingState &oWorkingState) override;
1873
1874
    double GetMinimum(int nXSize, int nYSize, int *pbSuccess) override;
1875
    double GetMaximum(int nXSize, int nYSize, int *pbSuccess) override;
1876
    CPLErr GetHistogram(int nXSize, int nYSize, double dfMin, double dfMax,
1877
                        int nBuckets, GUIntBig *panHistogram,
1878
                        int bIncludeOutOfRange, int bApproxOK,
1879
                        GDALProgressFunc pfnProgress,
1880
                        void *pProgressData) override;
1881
1882
    const char *GetType() const override;
1883
1884
    VRTImageReadFunc pfnReadFunc;
1885
    void *pCBData;
1886
    GDALDataType eType;
1887
1888
    float fNoDataValue;
1889
};
1890
1891
/************************************************************************/
1892
/*                               VRTGroup                               */
1893
/************************************************************************/
1894
1895
#ifdef TMPEXPORT
1896
#define TMP_CPL_DLL CPL_DLL
1897
#else
1898
#define TMP_CPL_DLL
1899
#endif
1900
1901
class VRTMDArray;
1902
class VRTAttribute;
1903
class VRTDimension;
1904
1905
class VRTGroup final : public GDALGroup
1906
{
1907
  public:
1908
    struct Ref
1909
    {
1910
        VRTGroup *m_ptr;
1911
1912
0
        explicit Ref(VRTGroup *ptr) : m_ptr(ptr)
1913
0
        {
1914
0
        }
1915
1916
        Ref(const Ref &) = delete;
1917
        Ref &operator=(const Ref &) = delete;
1918
    };
1919
1920
  private:
1921
    std::shared_ptr<Ref> m_poSharedRefRootGroup{};
1922
    std::weak_ptr<Ref> m_poWeakRefRootGroup{};
1923
    std::shared_ptr<Ref> m_poRefSelf{};
1924
1925
    std::string m_osFilename{};
1926
    mutable bool m_bDirty = false;
1927
    std::string m_osVRTPath{};
1928
    std::vector<std::string> m_aosGroupNames{};
1929
    std::map<std::string, std::shared_ptr<VRTGroup>> m_oMapGroups{};
1930
    std::vector<std::string> m_aosMDArrayNames{};
1931
    std::map<std::string, std::shared_ptr<VRTMDArray>> m_oMapMDArrays{};
1932
    std::map<std::string, std::shared_ptr<VRTAttribute>> m_oMapAttributes{};
1933
    std::map<std::string, std::shared_ptr<VRTDimension>> m_oMapDimensions{};
1934
1935
    std::shared_ptr<VRTGroup>
1936
    OpenGroupInternal(const std::string &osName) const;
1937
    void SetRootGroupRef(const std::weak_ptr<Ref> &rgRef);
1938
    std::weak_ptr<Ref> GetRootGroupRef() const;
1939
1940
  protected:
1941
    friend class VRTMDArray;
1942
    friend std::shared_ptr<GDALMDArray>
1943
    VRTDerivedArrayCreate(const char *pszVRTPath, const CPLXMLNode *psTree);
1944
1945
    explicit VRTGroup(const char *pszVRTPath);
1946
    VRTGroup(const std::string &osParentName, const std::string &osName);
1947
1948
  public:
1949
    static std::shared_ptr<VRTGroup> Create(const std::string &osParentName,
1950
                                            const std::string &osName)
1951
0
    {
1952
0
        auto poGroup =
1953
0
            std::shared_ptr<VRTGroup>(new VRTGroup(osParentName, osName));
1954
0
        poGroup->SetSelf(poGroup);
1955
0
        return poGroup;
1956
0
    }
1957
1958
    ~VRTGroup() override;
1959
1960
    bool XMLInit(const std::shared_ptr<VRTGroup> &poRoot,
1961
                 const std::shared_ptr<VRTGroup> &poThisGroup,
1962
                 const CPLXMLNode *psNode, const char *pszVRTPath);
1963
1964
    std::vector<std::string>
1965
    GetMDArrayNames(CSLConstList papszOptions) const override;
1966
    std::shared_ptr<GDALMDArray>
1967
    OpenMDArray(const std::string &osName,
1968
                CSLConstList papszOptions = nullptr) const override;
1969
1970
    std::vector<std::string>
1971
    GetGroupNames(CSLConstList papszOptions) const override;
1972
1973
    std::shared_ptr<GDALGroup> OpenGroup(const std::string &osName,
1974
                                         CSLConstList) const override
1975
0
    {
1976
0
        return OpenGroupInternal(osName);
1977
0
    }
1978
1979
    std::vector<std::shared_ptr<GDALDimension>>
1980
        GetDimensions(CSLConstList) const override;
1981
1982
    std::vector<std::shared_ptr<GDALAttribute>>
1983
        GetAttributes(CSLConstList) const override;
1984
1985
    std::shared_ptr<VRTDimension> GetDimension(const std::string &name) const
1986
0
    {
1987
0
        auto oIter = m_oMapDimensions.find(name);
1988
0
        return oIter == m_oMapDimensions.end() ? nullptr : oIter->second;
1989
0
    }
1990
1991
    std::shared_ptr<VRTDimension>
1992
    GetDimensionFromFullName(const std::string &name, bool bEmitError) const;
1993
1994
    std::shared_ptr<GDALGroup>
1995
    CreateGroup(const std::string &osName,
1996
                CSLConstList papszOptions = nullptr) override;
1997
1998
    std::shared_ptr<VRTGroup>
1999
    CreateVRTGroup(const std::string &osName,
2000
                   CSLConstList papszOptions = nullptr);
2001
2002
    std::shared_ptr<GDALDimension>
2003
    CreateDimension(const std::string &osName, const std::string &osType,
2004
                    const std::string &osDirection, GUInt64 nSize,
2005
                    CSLConstList papszOptions = nullptr) override;
2006
2007
    std::shared_ptr<GDALAttribute>
2008
    CreateAttribute(const std::string &osName,
2009
                    const std::vector<GUInt64> &anDimensions,
2010
                    const GDALExtendedDataType &oDataType,
2011
                    CSLConstList papszOptions = nullptr) override;
2012
2013
    std::shared_ptr<GDALMDArray> CreateMDArray(
2014
        const std::string &osName,
2015
        const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
2016
        const GDALExtendedDataType &oDataType,
2017
        CSLConstList papszOptions = nullptr) override;
2018
2019
    std::shared_ptr<VRTMDArray> CreateVRTMDArray(
2020
        const std::string &osName,
2021
        const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
2022
        const GDALExtendedDataType &oDataType,
2023
        CSLConstList papszOptions = nullptr);
2024
2025
    void SetIsRootGroup();
2026
2027
    const std::shared_ptr<Ref> &GetRef() const
2028
0
    {
2029
0
        return m_poRefSelf;
2030
0
    }
2031
2032
    VRTGroup *GetRootGroup() const;
2033
    std::shared_ptr<VRTGroup> GetRootGroupSharedPtr() const;
2034
2035
    const std::string &GetVRTPath() const
2036
0
    {
2037
0
        return m_osVRTPath;
2038
0
    }
2039
2040
    void SetVRTPath(const std::string &osVRTPath)
2041
0
    {
2042
0
        m_osVRTPath = osVRTPath;
2043
0
    }
2044
2045
    void SetDirty();
2046
2047
    void SetFilename(const std::string &osFilename)
2048
0
    {
2049
0
        m_osFilename = osFilename;
2050
0
    }
2051
2052
    const std::string &GetFilename() const
2053
0
    {
2054
0
        return m_osFilename;
2055
0
    }
2056
2057
    bool Serialize() const;
2058
    CPLXMLNode *SerializeToXML(const char *pszVRTPathIn) const;
2059
    void Serialize(CPLXMLNode *psParent, const char *pszVRTPathIn) const;
2060
};
2061
2062
/************************************************************************/
2063
/*                             VRTDimension                             */
2064
/************************************************************************/
2065
2066
class VRTDimension final : public GDALDimension
2067
{
2068
    std::weak_ptr<VRTGroup::Ref> m_poGroupRef;
2069
    std::string m_osIndexingVariableName;
2070
2071
  public:
2072
    VRTDimension(const std::shared_ptr<VRTGroup::Ref> &poGroupRef,
2073
                 const std::string &osParentName, const std::string &osName,
2074
                 const std::string &osType, const std::string &osDirection,
2075
                 GUInt64 nSize, const std::string &osIndexingVariableName)
2076
0
        : GDALDimension(osParentName, osName, osType, osDirection, nSize),
2077
0
          m_poGroupRef(poGroupRef),
2078
0
          m_osIndexingVariableName(osIndexingVariableName)
2079
0
    {
2080
0
    }
2081
2082
    VRTGroup *GetGroup() const;
2083
2084
    static std::shared_ptr<VRTDimension>
2085
    Create(const std::shared_ptr<VRTGroup> &poThisGroup,
2086
           const std::string &osParentName, const CPLXMLNode *psNode);
2087
2088
    std::shared_ptr<GDALMDArray> GetIndexingVariable() const override;
2089
2090
    bool SetIndexingVariable(
2091
        std::shared_ptr<GDALMDArray> poIndexingVariable) override;
2092
2093
    void Serialize(CPLXMLNode *psParent) const;
2094
};
2095
2096
/************************************************************************/
2097
/*                             VRTAttribute                             */
2098
/************************************************************************/
2099
2100
class VRTAttribute final : public GDALAttribute
2101
{
2102
    GDALExtendedDataType m_dt;
2103
    std::vector<std::string> m_aosList{};
2104
    std::vector<std::shared_ptr<GDALDimension>> m_dims{};
2105
2106
  protected:
2107
    bool IRead(const GUInt64 *arrayStartIdx, const size_t *count,
2108
               const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
2109
               const GDALExtendedDataType &bufferDataType,
2110
               void *pDstBuffer) const override;
2111
2112
    bool IWrite(const GUInt64 *arrayStartIdx, const size_t *count,
2113
                const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
2114
                const GDALExtendedDataType &bufferDataType,
2115
                const void *pSrcBuffer) override;
2116
2117
  public:
2118
    VRTAttribute(const std::string &osParentName, const std::string &osName,
2119
                 const GDALExtendedDataType &dt,
2120
                 std::vector<std::string> &&aosList)
2121
0
        : GDALAbstractMDArray(osParentName, osName),
2122
0
          GDALAttribute(osParentName, osName), m_dt(dt),
2123
0
          m_aosList(std::move(aosList))
2124
0
    {
2125
0
        if (m_aosList.size() > 1)
2126
0
        {
2127
0
            m_dims.emplace_back(std::make_shared<GDALDimension>(
2128
0
                std::string(), "dim", std::string(), std::string(),
2129
0
                m_aosList.size()));
2130
0
        }
2131
0
    }
2132
2133
    VRTAttribute(const std::string &osParentName, const std::string &osName,
2134
                 GUInt64 nDim, const GDALExtendedDataType &dt)
2135
0
        : GDALAbstractMDArray(osParentName, osName),
2136
0
          GDALAttribute(osParentName, osName), m_dt(dt)
2137
0
    {
2138
0
        if (nDim != 0)
2139
0
        {
2140
0
            m_dims.emplace_back(std::make_shared<GDALDimension>(
2141
0
                std::string(), "dim", std::string(), std::string(), nDim));
2142
0
        }
2143
0
    }
2144
2145
    static bool CreationCommonChecks(
2146
        const std::string &osName, const std::vector<GUInt64> &anDimensions,
2147
        const std::map<std::string, std::shared_ptr<VRTAttribute>>
2148
            &oMapAttributes);
2149
2150
    static std::shared_ptr<VRTAttribute> Create(const std::string &osParentName,
2151
                                                const CPLXMLNode *psNode);
2152
2153
    const std::vector<std::shared_ptr<GDALDimension>> &
2154
    GetDimensions() const override
2155
0
    {
2156
0
        return m_dims;
2157
0
    }
2158
2159
    const GDALExtendedDataType &GetDataType() const override
2160
0
    {
2161
0
        return m_dt;
2162
0
    }
2163
2164
    void Serialize(CPLXMLNode *psParent) const;
2165
};
2166
2167
/************************************************************************/
2168
/*                           VRTMDArraySource                           */
2169
/************************************************************************/
2170
2171
class VRTMDArraySource
2172
{
2173
  public:
2174
    virtual ~VRTMDArraySource();
2175
2176
    enum class RelationShip
2177
    {
2178
        NO_INTERSECTION,
2179
        PARTIAL_INTERSECTION,
2180
        SOURCE_BLOCK_MATCH,
2181
    };
2182
2183
    virtual RelationShip GetRelationship(const uint64_t *arrayStartIdx,
2184
                                         const size_t *count) const = 0;
2185
2186
    virtual bool GetRawBlockInfo(const uint64_t *arrayStartIdx,
2187
                                 const size_t *count,
2188
                                 GDALMDArrayRawBlockInfo &info) const = 0;
2189
2190
    virtual bool Read(const GUInt64 *arrayStartIdx, const size_t *count,
2191
                      const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
2192
                      const GDALExtendedDataType &bufferDataType,
2193
                      void *pDstBuffer) const = 0;
2194
2195
    virtual void Serialize(CPLXMLNode *psParent,
2196
                           const char *pszVRTPath) const = 0;
2197
};
2198
2199
/************************************************************************/
2200
/*                              VRTMDArray                              */
2201
/************************************************************************/
2202
2203
class VRTMDArray final : public GDALMDArray
2204
{
2205
  protected:
2206
    friend class VRTGroup;  // for access to SetSelf()
2207
2208
    std::weak_ptr<VRTGroup::Ref> m_poGroupRef;
2209
    std::string m_osVRTPath{};
2210
    std::shared_ptr<VRTGroup> m_poDummyOwningGroup{};
2211
2212
    GDALExtendedDataType m_dt;
2213
    std::vector<std::shared_ptr<GDALDimension>> m_dims;
2214
    std::map<std::string, std::shared_ptr<VRTAttribute>> m_oMapAttributes{};
2215
    std::vector<std::unique_ptr<VRTMDArraySource>> m_sources{};
2216
    std::shared_ptr<OGRSpatialReference> m_poSRS{};
2217
    std::vector<GByte> m_abyNoData{};
2218
    std::string m_osUnit{};
2219
    double m_dfScale = 1.0;
2220
    double m_dfOffset = 0.0;
2221
    bool m_bHasScale = false;
2222
    bool m_bHasOffset = false;
2223
    std::string m_osFilename{};
2224
    std::vector<GUInt64> m_anBlockSize{};
2225
    std::vector<std::string> m_aosOverviewFullname{};
2226
    mutable std::vector<std::shared_ptr<GDALMDArray>> m_apoOverviews{};
2227
2228
    bool IRead(const GUInt64 *arrayStartIdx, const size_t *count,
2229
               const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
2230
               const GDALExtendedDataType &bufferDataType,
2231
               void *pDstBuffer) const override;
2232
2233
    void SetDirty();
2234
2235
  public:
2236
    VRTMDArray(
2237
        const std::shared_ptr<VRTGroup::Ref> &poGroupRef,
2238
        const std::string &osParentName, const std::string &osName,
2239
        const GDALExtendedDataType &dt,
2240
        std::vector<std::shared_ptr<GDALDimension>> &&dims,
2241
        std::map<std::string, std::shared_ptr<VRTAttribute>> &&oMapAttributes,
2242
        std::vector<GUInt64> &&anBlockSize)
2243
0
        : GDALAbstractMDArray(osParentName, osName),
2244
0
          GDALMDArray(osParentName, osName), m_poGroupRef(poGroupRef),
2245
0
          m_osVRTPath(poGroupRef->m_ptr->GetVRTPath()), m_dt(dt),
2246
0
          m_dims(std::move(dims)), m_oMapAttributes(std::move(oMapAttributes)),
2247
0
          m_osFilename(poGroupRef->m_ptr->GetFilename()),
2248
0
          m_anBlockSize(std::move(anBlockSize))
2249
0
    {
2250
0
    }
2251
2252
    VRTMDArray(const std::shared_ptr<VRTGroup::Ref> &poGroupRef,
2253
               const std::string &osParentName, const std::string &osName,
2254
               const std::vector<std::shared_ptr<GDALDimension>> &dims,
2255
               const GDALExtendedDataType &dt,
2256
               const std::vector<GUInt64> &anBlockSize)
2257
0
        : GDALAbstractMDArray(osParentName, osName),
2258
0
          GDALMDArray(osParentName, osName), m_poGroupRef(poGroupRef),
2259
0
          m_osVRTPath(poGroupRef->m_ptr->GetVRTPath()), m_dt(dt), m_dims(dims),
2260
0
          m_osFilename(poGroupRef->m_ptr->GetFilename()),
2261
0
          m_anBlockSize(anBlockSize)
2262
0
    {
2263
0
    }
2264
2265
    bool IsWritable() const override
2266
0
    {
2267
0
        return false;
2268
0
    }
2269
2270
    const std::string &GetFilename() const override
2271
0
    {
2272
0
        return m_osFilename;
2273
0
    }
2274
2275
    static std::shared_ptr<VRTMDArray> Create(const char *pszVRTPath,
2276
                                              const CPLXMLNode *psNode);
2277
2278
    static std::shared_ptr<VRTMDArray>
2279
    Create(const std::shared_ptr<VRTGroup> &poThisGroup,
2280
           const std::string &osParentName, const CPLXMLNode *psNode);
2281
2282
    const std::vector<std::shared_ptr<GDALDimension>> &
2283
    GetDimensions() const override
2284
0
    {
2285
0
        return m_dims;
2286
0
    }
2287
2288
    std::vector<std::shared_ptr<GDALAttribute>>
2289
        GetAttributes(CSLConstList) const override;
2290
2291
    const GDALExtendedDataType &GetDataType() const override
2292
0
    {
2293
0
        return m_dt;
2294
0
    }
2295
2296
    bool SetSpatialRef(const OGRSpatialReference *poSRS) override;
2297
2298
    std::shared_ptr<OGRSpatialReference> GetSpatialRef() const override
2299
0
    {
2300
0
        return m_poSRS;
2301
0
    }
2302
2303
    const void *GetRawNoDataValue() const override;
2304
2305
    bool SetRawNoDataValue(const void *pRawNoData) override;
2306
2307
    const std::string &GetUnit() const override
2308
0
    {
2309
0
        return m_osUnit;
2310
0
    }
2311
2312
    bool SetUnit(const std::string &osUnit) override
2313
0
    {
2314
0
        m_osUnit = osUnit;
2315
0
        return true;
2316
0
    }
2317
2318
    double GetOffset(bool *pbHasOffset,
2319
                     GDALDataType *peStorageType) const override
2320
0
    {
2321
0
        if (pbHasOffset)
2322
0
            *pbHasOffset = m_bHasOffset;
2323
0
        if (peStorageType)
2324
0
            *peStorageType = GDT_Unknown;
2325
0
        return m_dfOffset;
2326
0
    }
2327
2328
    double GetScale(bool *pbHasScale,
2329
                    GDALDataType *peStorageType) const override
2330
0
    {
2331
0
        if (pbHasScale)
2332
0
            *pbHasScale = m_bHasScale;
2333
0
        if (peStorageType)
2334
0
            *peStorageType = GDT_Unknown;
2335
0
        return m_dfScale;
2336
0
    }
2337
2338
    bool SetOffset(double dfOffset,
2339
                   GDALDataType /* eStorageType */ = GDT_Unknown) override
2340
0
    {
2341
0
        SetDirty();
2342
0
        m_bHasOffset = true;
2343
0
        m_dfOffset = dfOffset;
2344
0
        return true;
2345
0
    }
2346
2347
    bool SetScale(double dfScale,
2348
                  GDALDataType /* eStorageType */ = GDT_Unknown) override
2349
0
    {
2350
0
        SetDirty();
2351
0
        m_bHasScale = true;
2352
0
        m_dfScale = dfScale;
2353
0
        return true;
2354
0
    }
2355
2356
    void AddSource(std::unique_ptr<VRTMDArraySource> &&poSource);
2357
2358
    std::shared_ptr<GDALAttribute>
2359
    CreateAttribute(const std::string &osName,
2360
                    const std::vector<GUInt64> &anDimensions,
2361
                    const GDALExtendedDataType &oDataType,
2362
                    CSLConstList papszOptions = nullptr) override;
2363
2364
    bool CopyFrom(GDALDataset *poSrcDS, const GDALMDArray *poSrcArray,
2365
                  bool bStrict, GUInt64 &nCurCost, const GUInt64 nTotalCost,
2366
                  GDALProgressFunc pfnProgress, void *pProgressData) override;
2367
2368
    void Serialize(CPLXMLNode *psParent, const char *pszVRTPathIn) const;
2369
2370
    VRTGroup *GetGroup() const;
2371
2372
    const std::string &GetVRTPath() const
2373
0
    {
2374
0
        return m_osVRTPath;
2375
0
    }
2376
2377
    std::shared_ptr<VRTGroup> GetRootVRTGroup() const
2378
0
    {
2379
0
        auto poGroup = m_poGroupRef.lock();
2380
0
        if (poGroup)
2381
0
            return poGroup->m_ptr->GetRootGroupSharedPtr();
2382
0
        return nullptr;
2383
0
    }
2384
2385
    std::shared_ptr<GDALGroup> GetRootGroup() const override
2386
0
    {
2387
0
        return GetRootVRTGroup();
2388
0
    }
2389
2390
    std::vector<GUInt64> GetBlockSize() const override
2391
0
    {
2392
0
        return m_anBlockSize;
2393
0
    }
2394
2395
    bool GetRawBlockInfo(const uint64_t *panBlockCoordinates,
2396
                         GDALMDArrayRawBlockInfo &info) const override;
2397
2398
    int GetOverviewCount() const override;
2399
2400
    std::shared_ptr<GDALMDArray> GetOverview(int idx) const override;
2401
};
2402
2403
/************************************************************************/
2404
/*                    VRTMDArraySourceInlinedValues                     */
2405
/************************************************************************/
2406
2407
class VRTMDArraySourceInlinedValues final : public VRTMDArraySource
2408
{
2409
    const VRTMDArray *m_poDstArray = nullptr;
2410
    bool m_bIsConstantValue;
2411
    std::vector<GUInt64> m_anOffset{};
2412
    std::vector<size_t> m_anCount{};
2413
    std::vector<GByte> m_abyValues{};
2414
    std::vector<size_t> m_anInlinedArrayStrideInBytes{};
2415
    GDALExtendedDataType m_dt;
2416
2417
    VRTMDArraySourceInlinedValues(const VRTMDArraySourceInlinedValues &) =
2418
        delete;
2419
    VRTMDArraySourceInlinedValues &
2420
    operator=(const VRTMDArraySourceInlinedValues &) = delete;
2421
2422
  public:
2423
    VRTMDArraySourceInlinedValues(const VRTMDArray *poDstArray,
2424
                                  bool bIsConstantValue,
2425
                                  std::vector<GUInt64> &&anOffset,
2426
                                  std::vector<size_t> &&anCount,
2427
                                  std::vector<GByte> &&abyValues)
2428
0
        : m_poDstArray(poDstArray), m_bIsConstantValue(bIsConstantValue),
2429
0
          m_anOffset(std::move(anOffset)), m_anCount(std::move(anCount)),
2430
0
          m_abyValues(std::move(abyValues)), m_dt(poDstArray->GetDataType())
2431
0
    {
2432
0
        const auto nDims(poDstArray->GetDimensionCount());
2433
0
        m_anInlinedArrayStrideInBytes.resize(nDims);
2434
0
        if (!bIsConstantValue && nDims > 0)
2435
0
        {
2436
0
            m_anInlinedArrayStrideInBytes.back() =
2437
0
                poDstArray->GetDataType().GetSize();
2438
0
            for (size_t i = nDims - 1; i > 0;)
2439
0
            {
2440
0
                --i;
2441
0
                m_anInlinedArrayStrideInBytes[i] =
2442
0
                    m_anInlinedArrayStrideInBytes[i + 1] * m_anCount[i + 1];
2443
0
            }
2444
0
        }
2445
0
    }
2446
2447
    ~VRTMDArraySourceInlinedValues() override;
2448
2449
    static std::unique_ptr<VRTMDArraySourceInlinedValues>
2450
    Create(const VRTMDArray *poDstArray, const CPLXMLNode *psNode);
2451
2452
    RelationShip GetRelationship(const uint64_t * /*arrayStartIdx*/,
2453
                                 const size_t * /*count*/) const override
2454
0
    {
2455
0
        return RelationShip::PARTIAL_INTERSECTION;
2456
0
    }
2457
2458
    bool GetRawBlockInfo(const uint64_t * /*arrayStartIdx*/,
2459
                         const size_t * /*count*/,
2460
                         GDALMDArrayRawBlockInfo & /*info*/) const override
2461
0
    {
2462
0
        return false;
2463
0
    }
2464
2465
    bool Read(const GUInt64 *arrayStartIdx, const size_t *count,
2466
              const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
2467
              const GDALExtendedDataType &bufferDataType,
2468
              void *pDstBuffer) const override;
2469
2470
    void Serialize(CPLXMLNode *psParent, const char *pszVRTPath) const override;
2471
};
2472
2473
/************************************************************************/
2474
/*                   VRTMDArraySourceRegularlySpaced                    */
2475
/************************************************************************/
2476
2477
class VRTMDArraySourceRegularlySpaced final : public VRTMDArraySource
2478
{
2479
    double m_dfStart;
2480
    double m_dfIncrement;
2481
2482
  public:
2483
    VRTMDArraySourceRegularlySpaced(double dfStart, double dfIncrement)
2484
0
        : m_dfStart(dfStart), m_dfIncrement(dfIncrement)
2485
0
    {
2486
0
    }
2487
2488
    RelationShip GetRelationship(const uint64_t * /*arrayStartIdx*/,
2489
                                 const size_t * /*count*/) const override
2490
0
    {
2491
0
        return RelationShip::PARTIAL_INTERSECTION;
2492
0
    }
2493
2494
    bool GetRawBlockInfo(const uint64_t * /*arrayStartIdx*/,
2495
                         const size_t * /*count*/,
2496
                         GDALMDArrayRawBlockInfo & /*info*/) const override
2497
0
    {
2498
0
        return false;
2499
0
    }
2500
2501
    bool Read(const GUInt64 *arrayStartIdx, const size_t *count,
2502
              const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
2503
              const GDALExtendedDataType &bufferDataType,
2504
              void *pDstBuffer) const override;
2505
2506
    void Serialize(CPLXMLNode *psParent, const char *pszVRTPath) const override;
2507
};
2508
2509
/************************************************************************/
2510
/*                      VRTMDArraySourceFromArray                       */
2511
/************************************************************************/
2512
2513
struct VRTArrayDatasetWrapper;
2514
2515
class VRTMDArraySourceFromArray final : public VRTMDArraySource
2516
{
2517
    const VRTMDArray *m_poDstArray = nullptr;
2518
    bool m_bRelativeToVRTSet = false;
2519
    bool m_bRelativeToVRT = false;
2520
    std::string m_osFilename{};
2521
    std::string m_osArray{};
2522
    std::string m_osBand{};
2523
    std::vector<int> m_anTransposedAxis{};
2524
    std::string m_osViewExpr{};
2525
    std::vector<GUInt64> m_anSrcOffset{};
2526
    mutable std::vector<GUInt64> m_anCount{};
2527
    std::vector<GUInt64> m_anStep{};
2528
    std::vector<GUInt64> m_anDstOffset{};
2529
2530
    std::pair<std::shared_ptr<VRTArrayDatasetWrapper>,
2531
              std::shared_ptr<GDALMDArray>>
2532
    GetSourceArray() const;
2533
2534
    VRTMDArraySourceFromArray(const VRTMDArraySourceFromArray &) = delete;
2535
    VRTMDArraySourceFromArray &
2536
    operator=(const VRTMDArraySourceFromArray &) = delete;
2537
2538
  public:
2539
    VRTMDArraySourceFromArray(
2540
        const VRTMDArray *poDstArray, bool bRelativeToVRTSet,
2541
        bool bRelativeToVRT, const std::string &osFilename,
2542
        const std::string &osArray, const std::string &osBand,
2543
        std::vector<int> &&anTransposedAxis, const std::string &osViewExpr,
2544
        std::vector<GUInt64> &&anSrcOffset, std::vector<GUInt64> &&anCount,
2545
        std::vector<GUInt64> &&anStep, std::vector<GUInt64> &&anDstOffset)
2546
0
        : m_poDstArray(poDstArray), m_bRelativeToVRTSet(bRelativeToVRTSet),
2547
0
          m_bRelativeToVRT(bRelativeToVRT), m_osFilename(osFilename),
2548
0
          m_osArray(osArray), m_osBand(osBand),
2549
0
          m_anTransposedAxis(std::move(anTransposedAxis)),
2550
0
          m_osViewExpr(osViewExpr), m_anSrcOffset(std::move(anSrcOffset)),
2551
0
          m_anCount(std::move(anCount)), m_anStep(std::move(anStep)),
2552
0
          m_anDstOffset(std::move(anDstOffset))
2553
0
    {
2554
0
    }
2555
2556
    ~VRTMDArraySourceFromArray() override;
2557
2558
    static std::unique_ptr<VRTMDArraySourceFromArray>
2559
    Create(const VRTMDArray *poDstArray, const CPLXMLNode *psNode);
2560
2561
    RelationShip GetRelationship(const uint64_t *arrayStartIdx,
2562
                                 const size_t *count) const override;
2563
2564
    bool GetRawBlockInfo(const uint64_t *arrayStartIdx, const size_t *count,
2565
                         GDALMDArrayRawBlockInfo &info) const override;
2566
2567
    bool Read(const GUInt64 *arrayStartIdx, const size_t *count,
2568
              const GInt64 *arrayStep, const GPtrDiff_t *bufferStride,
2569
              const GDALExtendedDataType &bufferDataType,
2570
              void *pDstBuffer) const override;
2571
2572
    void Serialize(CPLXMLNode *psParent, const char *pszVRTPath) const override;
2573
};
2574
2575
#endif /* #ifndef DOXYGEN_SKIP */
2576
2577
#endif /* ndef VIRTUALDATASET_H_INCLUDED */