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