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