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