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