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