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