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