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