Coverage Report

Created: 2025-06-13 06:18

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