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