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