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