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