Line data Source code
1 : /******************************************************************************
2 : *
3 : * Name: gdal_priv.h
4 : * Project: GDAL Core
5 : * Purpose: GDAL Core C++/Private declarations.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1998, Frank Warmerdam
10 : * Copyright (c) 2007-2014, Even Rouault <even dot rouault at spatialys.com>
11 : *
12 : * SPDX-License-Identifier: MIT
13 : ****************************************************************************/
14 :
15 : #ifndef GDAL_PRIV_H_INCLUDED
16 : #define GDAL_PRIV_H_INCLUDED
17 :
18 : /**
19 : * \file gdal_priv.h
20 : *
21 : * C++ GDAL entry points.
22 : */
23 :
24 : /* -------------------------------------------------------------------- */
25 : /* Predeclare various classes before pulling in gdal.h, the */
26 : /* public declarations. */
27 : /* -------------------------------------------------------------------- */
28 : class GDALMajorObject;
29 : class GDALDataset;
30 : class GDALRasterBand;
31 : class GDALDriver;
32 : class GDALRasterAttributeTable;
33 : class GDALProxyDataset;
34 : class GDALProxyRasterBand;
35 : class GDALAsyncReader;
36 : class GDALRelationship;
37 :
38 : /* -------------------------------------------------------------------- */
39 : /* Pull in the public declarations. This gets the C apis, and */
40 : /* also various constants. However, we will still get to */
41 : /* provide the real class definitions for the GDAL classes. */
42 : /* -------------------------------------------------------------------- */
43 :
44 : #include "gdal.h"
45 : #include "gdal_frmts.h"
46 : #include "gdalsubdatasetinfo.h"
47 : #include "cpl_vsi.h"
48 : #include "cpl_conv.h"
49 : #include "cpl_float.h"
50 : #include "cpl_string.h"
51 : #include "cpl_minixml.h"
52 : #include "cpl_multiproc.h"
53 : #include "cpl_atomic_ops.h"
54 :
55 : #include <stdarg.h>
56 :
57 : #include <cmath>
58 : #include <complex>
59 : #include <cstdint>
60 : #include <iterator>
61 : #include <limits>
62 : #include <map>
63 : #include <memory>
64 : #include <set>
65 : #if __cplusplus >= 202002L
66 : #include <span>
67 : #endif
68 : #include <vector>
69 :
70 : #include "ogr_core.h"
71 : #include "ogr_feature.h"
72 :
73 : //! @cond Doxygen_Suppress
74 : #define GMO_VALID 0x0001
75 : #define GMO_IGNORE_UNIMPLEMENTED 0x0002
76 : #define GMO_SUPPORT_MD 0x0004
77 : #define GMO_SUPPORT_MDMD 0x0008
78 : #define GMO_MD_DIRTY 0x0010
79 : #define GMO_PAM_CLASS 0x0020
80 :
81 : //! @endcond
82 :
83 : /************************************************************************/
84 : /* GDALMultiDomainMetadata */
85 : /************************************************************************/
86 :
87 : //! @cond Doxygen_Suppress
88 4768210 : class CPL_DLL GDALMultiDomainMetadata
89 : {
90 : private:
91 : CPLStringList aosDomainList{};
92 :
93 : struct Comparator
94 : {
95 28649100 : bool operator()(const char *a, const char *b) const
96 : {
97 28649100 : return STRCASECMP(a, b) < 0;
98 : }
99 : };
100 :
101 : std::map<const char *, CPLStringList, Comparator> oMetadata{};
102 :
103 : public:
104 : GDALMultiDomainMetadata();
105 : ~GDALMultiDomainMetadata();
106 :
107 : int XMLInit(const CPLXMLNode *psMetadata, int bMerge);
108 : CPLXMLNode *Serialize() const;
109 :
110 437317 : CSLConstList GetDomainList() const
111 : {
112 437317 : return aosDomainList.List();
113 : }
114 :
115 : char **GetMetadata(const char *pszDomain = "");
116 : CPLErr SetMetadata(CSLConstList papszMetadata, const char *pszDomain = "");
117 : const char *GetMetadataItem(const char *pszName,
118 : const char *pszDomain = "");
119 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
120 : const char *pszDomain = "");
121 :
122 : void Clear();
123 :
124 : inline void clear()
125 : {
126 : Clear();
127 : }
128 : };
129 :
130 : //! @endcond
131 :
132 : /* ******************************************************************** */
133 : /* GDALMajorObject */
134 : /* */
135 : /* Base class providing metadata, description and other */
136 : /* services shared by major objects. */
137 : /* ******************************************************************** */
138 :
139 : /** Object with metadata. */
140 : class CPL_DLL GDALMajorObject
141 : {
142 : protected:
143 : //! @cond Doxygen_Suppress
144 : int nFlags; // GMO_* flags.
145 : CPLString sDescription{};
146 : GDALMultiDomainMetadata oMDMD{};
147 :
148 : //! @endcond
149 :
150 : char **BuildMetadataDomainList(char **papszList, int bCheckNonEmpty,
151 : ...) CPL_NULL_TERMINATED;
152 :
153 : public:
154 : GDALMajorObject();
155 : virtual ~GDALMajorObject();
156 :
157 : int GetMOFlags() const;
158 : void SetMOFlags(int nFlagsIn);
159 :
160 : virtual const char *GetDescription() const;
161 : virtual void SetDescription(const char *);
162 :
163 : virtual char **GetMetadataDomainList();
164 :
165 : virtual char **GetMetadata(const char *pszDomain = "");
166 : virtual CPLErr SetMetadata(char **papszMetadata,
167 : const char *pszDomain = "");
168 : virtual const char *GetMetadataItem(const char *pszName,
169 : const char *pszDomain = "");
170 : virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
171 : const char *pszDomain = "");
172 :
173 : /** Convert a GDALMajorObject* to a GDALMajorObjectH.
174 : * @since GDAL 2.3
175 : */
176 245 : static inline GDALMajorObjectH ToHandle(GDALMajorObject *poMajorObject)
177 : {
178 245 : return static_cast<GDALMajorObjectH>(poMajorObject);
179 : }
180 :
181 : /** Convert a GDALMajorObjectH to a GDALMajorObject*.
182 : * @since GDAL 2.3
183 : */
184 1901040 : static inline GDALMajorObject *FromHandle(GDALMajorObjectH hMajorObject)
185 : {
186 1901040 : return static_cast<GDALMajorObject *>(hMajorObject);
187 : }
188 : };
189 :
190 : /* ******************************************************************** */
191 : /* GDALDefaultOverviews */
192 : /* ******************************************************************** */
193 :
194 : //! @cond Doxygen_Suppress
195 : class GDALOpenInfo;
196 :
197 : class CPL_DLL GDALDefaultOverviews
198 : {
199 : friend class GDALDataset;
200 :
201 : GDALDataset *poDS;
202 : GDALDataset *poODS;
203 :
204 : CPLString osOvrFilename{};
205 :
206 : bool bOvrIsAux;
207 :
208 : bool bCheckedForMask;
209 : bool bOwnMaskDS;
210 : GDALDataset *poMaskDS;
211 :
212 : // For "overview datasets" we record base level info so we can
213 : // find our way back to get overview masks.
214 : GDALDataset *poBaseDS;
215 :
216 : // Stuff for deferred initialize/overviewscans.
217 : bool bCheckedForOverviews;
218 : void OverviewScan();
219 : char *pszInitName;
220 : bool bInitNameIsOVR;
221 : char **papszInitSiblingFiles;
222 :
223 : public:
224 : GDALDefaultOverviews();
225 : ~GDALDefaultOverviews();
226 :
227 : void Initialize(GDALDataset *poDSIn, const char *pszName = nullptr,
228 : CSLConstList papszSiblingFiles = nullptr,
229 : bool bNameIsOVR = false);
230 :
231 : void Initialize(GDALDataset *poDSIn, GDALOpenInfo *poOpenInfo,
232 : const char *pszName = nullptr,
233 : bool bTransferSiblingFilesIfLoaded = true);
234 :
235 : void TransferSiblingFiles(char **papszSiblingFiles);
236 :
237 : int IsInitialized();
238 :
239 : int CloseDependentDatasets();
240 :
241 : // Overview Related
242 :
243 : int GetOverviewCount(int nBand);
244 : GDALRasterBand *GetOverview(int nBand, int iOverview);
245 :
246 : CPLErr BuildOverviews(const char *pszBasename, const char *pszResampling,
247 : int nOverviews, const int *panOverviewList,
248 : int nBands, const int *panBandList,
249 : GDALProgressFunc pfnProgress, void *pProgressData,
250 : CSLConstList papszOptions);
251 :
252 : CPLErr BuildOverviewsSubDataset(const char *pszPhysicalFile,
253 : const char *pszResampling, int nOverviews,
254 : const int *panOverviewList, int nBands,
255 : const int *panBandList,
256 : GDALProgressFunc pfnProgress,
257 : void *pProgressData,
258 : CSLConstList papszOptions);
259 :
260 : CPLErr BuildOverviewsMask(const char *pszResampling, int nOverviews,
261 : const int *panOverviewList,
262 : GDALProgressFunc pfnProgress, void *pProgressData,
263 : CSLConstList papszOptions);
264 :
265 : CPLErr CleanOverviews();
266 :
267 : // Mask Related
268 :
269 : CPLErr CreateMaskBand(int nFlags, int nBand = -1);
270 : GDALRasterBand *GetMaskBand(int nBand);
271 : int GetMaskFlags(int nBand);
272 :
273 : int HaveMaskFile(char **papszSiblings = nullptr,
274 : const char *pszBasename = nullptr);
275 :
276 47587 : char **GetSiblingFiles()
277 : {
278 47587 : return papszInitSiblingFiles;
279 : }
280 :
281 : private:
282 : CPL_DISALLOW_COPY_ASSIGN(GDALDefaultOverviews)
283 : };
284 :
285 : //! @endcond
286 :
287 : /* ******************************************************************** */
288 : /* GDALOpenInfo */
289 : /* ******************************************************************** */
290 :
291 : /** Class for dataset open functions. */
292 : class CPL_DLL GDALOpenInfo
293 : {
294 : bool bHasGotSiblingFiles = false;
295 : char **papszSiblingFiles = nullptr;
296 : int nHeaderBytesTried = 0;
297 :
298 : public:
299 : GDALOpenInfo(const char *pszFile, int nOpenFlagsIn,
300 : const char *const *papszSiblingFiles = nullptr);
301 : ~GDALOpenInfo(void);
302 :
303 : /** Filename */
304 : char *pszFilename = nullptr;
305 :
306 : /** Result of CPLGetExtension(pszFilename); */
307 : std::string osExtension{};
308 :
309 : /** Open options */
310 : char **papszOpenOptions = nullptr;
311 :
312 : /** Access flag */
313 : GDALAccess eAccess = GA_ReadOnly;
314 : /** Open flags */
315 : int nOpenFlags = 0;
316 :
317 : /** Whether stat()'ing the file was successful */
318 : bool bStatOK = false;
319 : /** Whether the file is a directory */
320 : bool bIsDirectory = false;
321 :
322 : /** Pointer to the file */
323 : VSILFILE *fpL = nullptr;
324 :
325 : /** Number of bytes in pabyHeader */
326 : int nHeaderBytes = 0;
327 : /** Buffer with first bytes of the file */
328 : GByte *pabyHeader = nullptr;
329 :
330 : /** Allowed drivers (NULL for all) */
331 : const char *const *papszAllowedDrivers = nullptr;
332 :
333 : int TryToIngest(int nBytes);
334 : char **GetSiblingFiles();
335 : char **StealSiblingFiles();
336 : bool AreSiblingFilesLoaded() const;
337 :
338 : bool IsSingleAllowedDriver(const char *pszDriverName) const;
339 :
340 : /** Return whether the extension of the file is equal to pszExt, using
341 : * case-insensitive comparison.
342 : * @since 3.11 */
343 752218 : inline bool IsExtensionEqualToCI(const char *pszExt) const
344 : {
345 752218 : return EQUAL(osExtension.c_str(), pszExt);
346 : }
347 :
348 : private:
349 : CPL_DISALLOW_COPY_ASSIGN(GDALOpenInfo)
350 : };
351 :
352 : /* ******************************************************************** */
353 : /* gdal::GCP */
354 : /* ******************************************************************** */
355 :
356 : namespace gdal
357 : {
358 : /** C++ wrapper over the C GDAL_GCP structure.
359 : *
360 : * It has the same binary layout, and thus a gdal::GCP pointer can be cast as a
361 : * GDAL_GCP pointer.
362 : *
363 : * @since 3.9
364 : */
365 : class CPL_DLL GCP
366 : {
367 : public:
368 : explicit GCP(const char *pszId = "", const char *pszInfo = "",
369 : double dfPixel = 0, double dfLine = 0, double dfX = 0,
370 : double dfY = 0, double dfZ = 0);
371 : ~GCP();
372 : GCP(const GCP &);
373 : explicit GCP(const GDAL_GCP &other);
374 : GCP &operator=(const GCP &);
375 : GCP(GCP &&);
376 : GCP &operator=(GCP &&);
377 :
378 : /** Returns the "id" member. */
379 21898 : inline const char *Id() const
380 : {
381 21898 : return gcp.pszId;
382 : }
383 :
384 : void SetId(const char *pszId);
385 :
386 : /** Returns the "info" member. */
387 43778 : inline const char *Info() const
388 : {
389 43778 : return gcp.pszInfo;
390 : }
391 :
392 : void SetInfo(const char *pszInfo);
393 :
394 : /** Returns the "pixel" member. */
395 21917 : inline double Pixel() const
396 : {
397 21917 : return gcp.dfGCPPixel;
398 : }
399 :
400 : /** Returns a reference to the "pixel" member. */
401 24690 : inline double &Pixel()
402 : {
403 24690 : return gcp.dfGCPPixel;
404 : }
405 :
406 : /** Returns the "line" member. */
407 21917 : inline double Line() const
408 : {
409 21917 : return gcp.dfGCPLine;
410 : }
411 :
412 : /** Returns a reference to the "line" member. */
413 24690 : inline double &Line()
414 : {
415 24690 : return gcp.dfGCPLine;
416 : }
417 :
418 : /** Returns the "X" member. */
419 21917 : inline double X() const
420 : {
421 21917 : return gcp.dfGCPX;
422 : }
423 :
424 : /** Returns a reference to the "X" member. */
425 24616 : inline double &X()
426 : {
427 24616 : return gcp.dfGCPX;
428 : }
429 :
430 : /** Returns the "Y" member. */
431 21917 : inline double Y() const
432 : {
433 21917 : return gcp.dfGCPY;
434 : }
435 :
436 : /** Returns a reference to the "Y" member. */
437 24616 : inline double &Y()
438 : {
439 24616 : return gcp.dfGCPY;
440 : }
441 :
442 : /** Returns the "Z" member. */
443 43745 : inline double Z() const
444 : {
445 43745 : return gcp.dfGCPZ;
446 : }
447 :
448 : /** Returns a reference to the "Z" member. */
449 24516 : inline double &Z()
450 : {
451 24516 : return gcp.dfGCPZ;
452 : }
453 :
454 : /** Casts as a C GDAL_GCP pointer */
455 409 : inline const GDAL_GCP *c_ptr() const
456 : {
457 409 : return &gcp;
458 : }
459 :
460 : static const GDAL_GCP *c_ptr(const std::vector<GCP> &asGCPs);
461 :
462 : static std::vector<GCP> fromC(const GDAL_GCP *pasGCPList, int nGCPCount);
463 :
464 : private:
465 : GDAL_GCP gcp;
466 : };
467 :
468 : } /* namespace gdal */
469 :
470 : /* ******************************************************************** */
471 : /* GDALDataset */
472 : /* ******************************************************************** */
473 :
474 : class OGRLayer;
475 : class OGRGeometry;
476 : class OGRSpatialReference;
477 : class OGRStyleTable;
478 : class swq_select;
479 : class swq_select_parse_options;
480 : class GDALGroup;
481 :
482 : //! @cond Doxygen_Suppress
483 : typedef struct GDALSQLParseInfo GDALSQLParseInfo;
484 : //! @endcond
485 :
486 : //! @cond Doxygen_Suppress
487 : #ifdef GDAL_COMPILATION
488 : #define OPTIONAL_OUTSIDE_GDAL(val)
489 : #else
490 : #define OPTIONAL_OUTSIDE_GDAL(val) = val
491 : #endif
492 : //! @endcond
493 :
494 : //! @cond Doxygen_Suppress
495 : // This macro can be defined to check that GDALDataset::IRasterIO()
496 : // implementations do not alter the passed panBandList. It is not defined
497 : // by default (and should not!), hence int* is used.
498 : #if defined(GDAL_BANDMAP_TYPE_CONST_SAFE)
499 : #define BANDMAP_TYPE const int *
500 : #else
501 : #define BANDMAP_TYPE int *
502 : #endif
503 : //! @endcond
504 :
505 : /** A set of associated raster bands, usually from one file. */
506 : class CPL_DLL GDALDataset : public GDALMajorObject
507 : {
508 : friend GDALDatasetH CPL_STDCALL
509 : GDALOpenEx(const char *pszFilename, unsigned int nOpenFlags,
510 : const char *const *papszAllowedDrivers,
511 : const char *const *papszOpenOptions,
512 : const char *const *papszSiblingFiles);
513 : friend CPLErr CPL_STDCALL GDALClose(GDALDatasetH hDS);
514 :
515 : friend class GDALDriver;
516 : friend class GDALDefaultOverviews;
517 : friend class GDALProxyDataset;
518 : friend class GDALDriverManager;
519 :
520 : CPL_INTERNAL void AddToDatasetOpenList();
521 :
522 : CPL_INTERNAL void UnregisterFromSharedDataset();
523 :
524 : CPL_INTERNAL static void ReportErrorV(const char *pszDSName,
525 : CPLErr eErrClass, CPLErrorNum err_no,
526 : const char *fmt, va_list args);
527 :
528 : protected:
529 : //! @cond Doxygen_Suppress
530 : GDALDriver *poDriver = nullptr;
531 : GDALAccess eAccess = GA_ReadOnly;
532 :
533 : // Stored raster information.
534 : int nRasterXSize = 512;
535 : int nRasterYSize = 512;
536 : int nBands = 0;
537 : GDALRasterBand **papoBands = nullptr;
538 :
539 : static constexpr int OPEN_FLAGS_CLOSED = -1;
540 : int nOpenFlags =
541 : 0; // set to OPEN_FLAGS_CLOSED after Close() has been called
542 :
543 : int nRefCount = 1;
544 : bool bForceCachedIO = false;
545 : bool bShared = false;
546 : bool bIsInternal = true;
547 : bool bSuppressOnClose = false;
548 :
549 : mutable std::map<std::string, std::unique_ptr<OGRFieldDomain>>
550 : m_oMapFieldDomains{};
551 :
552 : GDALDataset(void);
553 : explicit GDALDataset(int bForceCachedIO);
554 :
555 : void RasterInitialize(int, int);
556 : void SetBand(int nNewBand, GDALRasterBand *poBand);
557 : void SetBand(int nNewBand, std::unique_ptr<GDALRasterBand> poBand);
558 :
559 : GDALDefaultOverviews oOvManager{};
560 :
561 : virtual CPLErr IBuildOverviews(const char *pszResampling, int nOverviews,
562 : const int *panOverviewList, int nListBands,
563 : const int *panBandList,
564 : GDALProgressFunc pfnProgress,
565 : void *pProgressData,
566 : CSLConstList papszOptions);
567 :
568 : virtual CPLErr
569 : IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize,
570 : void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType,
571 : int nBandCount, BANDMAP_TYPE panBandMap, GSpacing nPixelSpace,
572 : GSpacing nLineSpace, GSpacing nBandSpace,
573 : GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
574 :
575 : /* This method should only be be overloaded by GDALProxyDataset */
576 : virtual CPLErr
577 : BlockBasedRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
578 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
579 : GDALDataType eBufType, int nBandCount,
580 : const int *panBandMap, GSpacing nPixelSpace,
581 : GSpacing nLineSpace, GSpacing nBandSpace,
582 : GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
583 : CPLErr BlockBasedFlushCache(bool bAtClosing);
584 :
585 : CPLErr
586 : BandBasedRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
587 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
588 : GDALDataType eBufType, int nBandCount,
589 : const int *panBandMap, GSpacing nPixelSpace,
590 : GSpacing nLineSpace, GSpacing nBandSpace,
591 : GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
592 :
593 : CPLErr
594 : RasterIOResampled(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
595 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
596 : GDALDataType eBufType, int nBandCount,
597 : const int *panBandMap, GSpacing nPixelSpace,
598 : GSpacing nLineSpace, GSpacing nBandSpace,
599 : GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
600 :
601 : CPLErr ValidateRasterIOOrAdviseReadParameters(
602 : const char *pszCallingFunc, int *pbStopProcessingOnCENone, int nXOff,
603 : int nYOff, int nXSize, int nYSize, int nBufXSize, int nBufYSize,
604 : int nBandCount, const int *panBandMap);
605 :
606 : CPLErr TryOverviewRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
607 : int nXSize, int nYSize, void *pData,
608 : int nBufXSize, int nBufYSize,
609 : GDALDataType eBufType, int nBandCount,
610 : const int *panBandMap, GSpacing nPixelSpace,
611 : GSpacing nLineSpace, GSpacing nBandSpace,
612 : GDALRasterIOExtraArg *psExtraArg, int *pbTried);
613 :
614 : void ShareLockWithParentDataset(GDALDataset *poParentDataset);
615 :
616 : bool m_bCanBeReopened = false;
617 :
618 : virtual bool CanBeCloned(int nScopeFlags, bool bCanShareState) const;
619 :
620 : friend class GDALThreadSafeDataset;
621 : friend class MEMDataset;
622 : virtual std::unique_ptr<GDALDataset> Clone(int nScopeFlags,
623 : bool bCanShareState) const;
624 :
625 : //! @endcond
626 :
627 : void CleanupPostFileClosing();
628 :
629 : virtual int CloseDependentDatasets();
630 : //! @cond Doxygen_Suppress
631 : int ValidateLayerCreationOptions(const char *const *papszLCO);
632 :
633 : char **papszOpenOptions = nullptr;
634 :
635 : friend class GDALRasterBand;
636 :
637 : // The below methods related to read write mutex are fragile logic, and
638 : // should not be used by out-of-tree code if possible.
639 : int EnterReadWrite(GDALRWFlag eRWFlag);
640 : void LeaveReadWrite();
641 : void InitRWLock();
642 :
643 : void TemporarilyDropReadWriteLock();
644 : void ReacquireReadWriteLock();
645 :
646 : void DisableReadWriteMutex();
647 :
648 : int AcquireMutex();
649 : void ReleaseMutex();
650 :
651 : bool IsAllBands(int nBandCount, const int *panBandList) const;
652 : //! @endcond
653 :
654 : public:
655 : ~GDALDataset() override;
656 :
657 : virtual CPLErr Close();
658 :
659 : int GetRasterXSize() const;
660 : int GetRasterYSize() const;
661 : int GetRasterCount() const;
662 : GDALRasterBand *GetRasterBand(int);
663 : const GDALRasterBand *GetRasterBand(int) const;
664 :
665 : /**
666 : * @brief SetQueryLoggerFunc
667 : * @param pfnQueryLoggerFuncIn query logger function callback
668 : * @param poQueryLoggerArgIn arguments passed to the query logger function
669 : * @return true on success
670 : */
671 : virtual bool SetQueryLoggerFunc(GDALQueryLoggerFunc pfnQueryLoggerFuncIn,
672 : void *poQueryLoggerArgIn);
673 :
674 : /** Class returned by GetBands() that act as a container for raster bands.
675 : */
676 : class CPL_DLL Bands
677 : {
678 : private:
679 : friend class GDALDataset;
680 : GDALDataset *m_poSelf;
681 :
682 7 : CPL_INTERNAL explicit Bands(GDALDataset *poSelf) : m_poSelf(poSelf)
683 : {
684 7 : }
685 :
686 6 : class CPL_DLL Iterator
687 : {
688 : struct Private;
689 : std::unique_ptr<Private> m_poPrivate;
690 :
691 : public:
692 : Iterator(GDALDataset *poDS, bool bStart);
693 : Iterator(const Iterator &oOther); // declared but not defined.
694 : // Needed for gcc 5.4 at least
695 : Iterator(Iterator &&oOther) noexcept; // declared but not defined.
696 : // Needed for gcc 5.4 at least
697 : ~Iterator();
698 : GDALRasterBand *operator*();
699 : Iterator &operator++();
700 : bool operator!=(const Iterator &it) const;
701 : };
702 :
703 : public:
704 : const Iterator begin() const;
705 :
706 : const Iterator end() const;
707 :
708 : size_t size() const;
709 :
710 : GDALRasterBand *operator[](int iBand);
711 : GDALRasterBand *operator[](size_t iBand);
712 : };
713 :
714 : Bands GetBands();
715 :
716 : virtual CPLErr FlushCache(bool bAtClosing = false);
717 : virtual CPLErr DropCache();
718 :
719 : virtual GIntBig GetEstimatedRAMUsage();
720 :
721 : virtual const OGRSpatialReference *GetSpatialRef() const;
722 : virtual CPLErr SetSpatialRef(const OGRSpatialReference *poSRS);
723 :
724 : // Compatibility layer
725 : const char *GetProjectionRef(void) const;
726 : CPLErr SetProjection(const char *pszProjection);
727 :
728 : virtual CPLErr GetGeoTransform(double *padfTransform);
729 : virtual CPLErr SetGeoTransform(double *padfTransform);
730 :
731 : CPLErr GeolocationToPixelLine(
732 : double dfGeolocX, double dfGeolocY, const OGRSpatialReference *poSRS,
733 : double *pdfPixel, double *pdfLine,
734 : CSLConstList papszTransformerOptions = nullptr) const;
735 :
736 : virtual CPLErr AddBand(GDALDataType eType, char **papszOptions = nullptr);
737 :
738 : virtual void *GetInternalHandle(const char *pszHandleName);
739 : virtual GDALDriver *GetDriver(void);
740 : virtual char **GetFileList(void);
741 :
742 : virtual const char *GetDriverName();
743 :
744 : virtual const OGRSpatialReference *GetGCPSpatialRef() const;
745 : virtual int GetGCPCount();
746 : virtual const GDAL_GCP *GetGCPs();
747 : virtual CPLErr SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList,
748 : const OGRSpatialReference *poGCP_SRS);
749 :
750 : // Compatibility layer
751 : const char *GetGCPProjection();
752 : CPLErr SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList,
753 : const char *pszGCPProjection);
754 :
755 : virtual CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize,
756 : int nBufXSize, int nBufYSize, GDALDataType eDT,
757 : int nBandCount, int *panBandList,
758 : char **papszOptions);
759 :
760 : virtual CPLErr CreateMaskBand(int nFlagsIn);
761 :
762 : virtual GDALAsyncReader *
763 : BeginAsyncReader(int nXOff, int nYOff, int nXSize, int nYSize, void *pBuf,
764 : int nBufXSize, int nBufYSize, GDALDataType eBufType,
765 : int nBandCount, int *panBandMap, int nPixelSpace,
766 : int nLineSpace, int nBandSpace, char **papszOptions);
767 : virtual void EndAsyncReader(GDALAsyncReader *poARIO);
768 :
769 : //! @cond Doxygen_Suppress
770 : struct RawBinaryLayout
771 : {
772 : enum class Interleaving
773 : {
774 : UNKNOWN,
775 : BIP,
776 : BIL,
777 : BSQ
778 : };
779 : std::string osRawFilename{};
780 : Interleaving eInterleaving = Interleaving::UNKNOWN;
781 : GDALDataType eDataType = GDT_Unknown;
782 : bool bLittleEndianOrder = false;
783 :
784 : vsi_l_offset nImageOffset = 0;
785 : GIntBig nPixelOffset = 0;
786 : GIntBig nLineOffset = 0;
787 : GIntBig nBandOffset = 0;
788 : };
789 :
790 : virtual bool GetRawBinaryLayout(RawBinaryLayout &);
791 : //! @endcond
792 :
793 : #ifndef DOXYGEN_SKIP
794 : CPLErr RasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
795 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
796 : GDALDataType eBufType, int nBandCount,
797 : const int *panBandMap, GSpacing nPixelSpace,
798 : GSpacing nLineSpace, GSpacing nBandSpace,
799 : GDALRasterIOExtraArg *psExtraArg
800 : OPTIONAL_OUTSIDE_GDAL(nullptr)) CPL_WARN_UNUSED_RESULT;
801 : #else
802 : CPLErr RasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
803 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
804 : GDALDataType eBufType, int nBandCount,
805 : const int *panBandMap, GSpacing nPixelSpace,
806 : GSpacing nLineSpace, GSpacing nBandSpace,
807 : GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
808 : #endif
809 :
810 : virtual CPLStringList GetCompressionFormats(int nXOff, int nYOff,
811 : int nXSize, int nYSize,
812 : int nBandCount,
813 : const int *panBandList);
814 : virtual CPLErr ReadCompressedData(const char *pszFormat, int nXOff,
815 : int nYOff, int nXSize, int nYSize,
816 : int nBands, const int *panBandList,
817 : void **ppBuffer, size_t *pnBufferSize,
818 : char **ppszDetailedFormat);
819 :
820 : int Reference();
821 : int Dereference();
822 : int ReleaseRef();
823 :
824 : /** Return access mode.
825 : * @return access mode.
826 : */
827 113257 : GDALAccess GetAccess() const
828 : {
829 113257 : return eAccess;
830 : }
831 :
832 : int GetShared() const;
833 : void MarkAsShared();
834 :
835 : void MarkSuppressOnClose();
836 : void UnMarkSuppressOnClose();
837 :
838 : /** Return MarkSuppressOnClose flag.
839 : * @return MarkSuppressOnClose flag.
840 : */
841 3579352 : bool IsMarkedSuppressOnClose() const
842 : {
843 3579352 : return bSuppressOnClose;
844 : }
845 :
846 : /** Return open options.
847 : * @return open options.
848 : */
849 10388 : char **GetOpenOptions()
850 : {
851 10388 : return papszOpenOptions;
852 : }
853 :
854 : bool IsThreadSafe(int nScopeFlags) const;
855 :
856 : #ifndef DOXYGEN_SKIP
857 : /** Return open options.
858 : * @return open options.
859 : */
860 7 : CSLConstList GetOpenOptions() const
861 : {
862 7 : return papszOpenOptions;
863 : }
864 : #endif
865 :
866 : static GDALDataset **GetOpenDatasets(int *pnDatasetCount);
867 :
868 : #ifndef DOXYGEN_SKIP
869 : CPLErr
870 : BuildOverviews(const char *pszResampling, int nOverviews,
871 : const int *panOverviewList, int nListBands,
872 : const int *panBandList, GDALProgressFunc pfnProgress,
873 : void *pProgressData,
874 : CSLConstList papszOptions OPTIONAL_OUTSIDE_GDAL(nullptr));
875 : #else
876 : CPLErr BuildOverviews(const char *pszResampling, int nOverviews,
877 : const int *panOverviewList, int nListBands,
878 : const int *panBandList, GDALProgressFunc pfnProgress,
879 : void *pProgressData, CSLConstList papszOptions);
880 : #endif
881 :
882 : #ifndef DOXYGEN_XML
883 : void ReportError(CPLErr eErrClass, CPLErrorNum err_no, const char *fmt,
884 : ...) const CPL_PRINT_FUNC_FORMAT(4, 5);
885 :
886 : static void ReportError(const char *pszDSName, CPLErr eErrClass,
887 : CPLErrorNum err_no, const char *fmt, ...)
888 : CPL_PRINT_FUNC_FORMAT(4, 5);
889 : #endif
890 :
891 : char **GetMetadata(const char *pszDomain = "") override;
892 :
893 : // Only defined when Doxygen enabled
894 : #ifdef DOXYGEN_SKIP
895 : CPLErr SetMetadata(char **papszMetadata, const char *pszDomain) override;
896 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
897 : const char *pszDomain) override;
898 : #endif
899 :
900 : char **GetMetadataDomainList() override;
901 :
902 : virtual void ClearStatistics();
903 :
904 : /** Convert a GDALDataset* to a GDALDatasetH.
905 : * @since GDAL 2.3
906 : */
907 25282 : static inline GDALDatasetH ToHandle(GDALDataset *poDS)
908 : {
909 25282 : return static_cast<GDALDatasetH>(poDS);
910 : }
911 :
912 : /** Convert a GDALDatasetH to a GDALDataset*.
913 : * @since GDAL 2.3
914 : */
915 1357429 : static inline GDALDataset *FromHandle(GDALDatasetH hDS)
916 : {
917 1357429 : return static_cast<GDALDataset *>(hDS);
918 : }
919 :
920 : /** @see GDALOpenEx().
921 : * @since GDAL 2.3
922 : */
923 24879 : static GDALDataset *Open(const char *pszFilename,
924 : unsigned int nOpenFlags = 0,
925 : const char *const *papszAllowedDrivers = nullptr,
926 : const char *const *papszOpenOptions = nullptr,
927 : const char *const *papszSiblingFiles = nullptr)
928 : {
929 24879 : return FromHandle(GDALOpenEx(pszFilename, nOpenFlags,
930 : papszAllowedDrivers, papszOpenOptions,
931 24865 : papszSiblingFiles));
932 : }
933 :
934 : /** Object returned by GetFeatures() iterators */
935 : struct FeatureLayerPair
936 : {
937 : /** Unique pointer to a OGRFeature. */
938 : OGRFeatureUniquePtr feature{};
939 :
940 : /** Layer to which the feature belongs to. */
941 : OGRLayer *layer = nullptr;
942 : };
943 :
944 : //! @cond Doxygen_Suppress
945 : // SetEnableOverviews() only to be used by GDALOverviewDataset
946 : void SetEnableOverviews(bool bEnable);
947 :
948 : // Only to be used by driver's GetOverviewCount() method.
949 : bool AreOverviewsEnabled() const;
950 :
951 : static void ReportUpdateNotSupportedByDriver(const char *pszDriverName);
952 : //! @endcond
953 :
954 : private:
955 : class Private;
956 : Private *m_poPrivate;
957 :
958 : CPL_INTERNAL OGRLayer *BuildLayerFromSelectInfo(
959 : swq_select *psSelectInfo, OGRGeometry *poSpatialFilter,
960 : const char *pszDialect, swq_select_parse_options *poSelectParseOptions);
961 : CPLStringList oDerivedMetadataList{};
962 :
963 : public:
964 : virtual int GetLayerCount();
965 : virtual OGRLayer *GetLayer(int iLayer);
966 :
967 : virtual bool IsLayerPrivate(int iLayer) const;
968 :
969 : /** Class returned by GetLayers() that acts as a range of layers.
970 : * @since GDAL 2.3
971 : */
972 : class CPL_DLL Layers
973 : {
974 : private:
975 : friend class GDALDataset;
976 : GDALDataset *m_poSelf;
977 :
978 26 : CPL_INTERNAL explicit Layers(GDALDataset *poSelf) : m_poSelf(poSelf)
979 : {
980 26 : }
981 :
982 : public:
983 : /** Layer iterator.
984 : * @since GDAL 2.3
985 : */
986 60 : class CPL_DLL Iterator
987 : {
988 : struct Private;
989 : std::unique_ptr<Private> m_poPrivate;
990 :
991 : public:
992 : using value_type = OGRLayer *; /**< value_type */
993 : using reference = OGRLayer *; /**< reference */
994 : using difference_type = void; /**< difference_type */
995 : using pointer = void; /**< pointer */
996 : using iterator_category =
997 : std::input_iterator_tag; /**< iterator_category */
998 :
999 : Iterator(); /**< Default constructor */
1000 : Iterator(GDALDataset *poDS, bool bStart); /**< Constructor */
1001 : Iterator(const Iterator &oOther); /**< Copy constructor */
1002 : Iterator(Iterator &&oOther) noexcept; /**< Move constructor */
1003 : ~Iterator(); /**< Destructor */
1004 :
1005 : Iterator &
1006 : operator=(const Iterator &oOther); /**< Assignment operator */
1007 : Iterator &operator=(
1008 : Iterator &&oOther) noexcept; /**< Move assignment operator */
1009 :
1010 : OGRLayer *operator*() const; /**< Dereference operator */
1011 : Iterator &operator++(); /**< Pre-increment operator */
1012 : Iterator operator++(int); /**< Post-increment operator */
1013 : bool operator!=(const Iterator &it)
1014 : const; /**< Difference comparison operator */
1015 : };
1016 :
1017 : Iterator begin() const;
1018 : Iterator end() const;
1019 :
1020 : size_t size() const;
1021 :
1022 : OGRLayer *operator[](int iLayer);
1023 : OGRLayer *operator[](size_t iLayer);
1024 : OGRLayer *operator[](const char *pszLayername);
1025 : };
1026 :
1027 : Layers GetLayers();
1028 :
1029 : virtual OGRLayer *GetLayerByName(const char *);
1030 : virtual OGRErr DeleteLayer(int iLayer);
1031 :
1032 : virtual void ResetReading();
1033 : virtual OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer,
1034 : double *pdfProgressPct,
1035 : GDALProgressFunc pfnProgress,
1036 : void *pProgressData);
1037 :
1038 : /** Class returned by GetFeatures() that act as a container for vector
1039 : * features. */
1040 : class CPL_DLL Features
1041 : {
1042 : private:
1043 : friend class GDALDataset;
1044 : GDALDataset *m_poSelf;
1045 :
1046 2 : CPL_INTERNAL explicit Features(GDALDataset *poSelf) : m_poSelf(poSelf)
1047 : {
1048 2 : }
1049 :
1050 4 : class CPL_DLL Iterator
1051 : {
1052 : struct Private;
1053 : std::unique_ptr<Private> m_poPrivate;
1054 :
1055 : public:
1056 : Iterator(GDALDataset *poDS, bool bStart);
1057 : Iterator(const Iterator &oOther); // declared but not defined.
1058 : // Needed for gcc 5.4 at least
1059 : Iterator(Iterator &&oOther) noexcept; // declared but not defined.
1060 : // Needed for gcc 5.4 at least
1061 : ~Iterator();
1062 : const FeatureLayerPair &operator*() const;
1063 : Iterator &operator++();
1064 : bool operator!=(const Iterator &it) const;
1065 : };
1066 :
1067 : public:
1068 : const Iterator begin() const;
1069 :
1070 : const Iterator end() const;
1071 : };
1072 :
1073 : Features GetFeatures();
1074 :
1075 : virtual int TestCapability(const char *);
1076 :
1077 : virtual std::vector<std::string>
1078 : GetFieldDomainNames(CSLConstList papszOptions = nullptr) const;
1079 :
1080 : virtual const OGRFieldDomain *GetFieldDomain(const std::string &name) const;
1081 :
1082 : virtual bool AddFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
1083 : std::string &failureReason);
1084 :
1085 : virtual bool DeleteFieldDomain(const std::string &name,
1086 : std::string &failureReason);
1087 :
1088 : virtual bool UpdateFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
1089 : std::string &failureReason);
1090 :
1091 : virtual std::vector<std::string>
1092 : GetRelationshipNames(CSLConstList papszOptions = nullptr) const;
1093 :
1094 : virtual const GDALRelationship *
1095 : GetRelationship(const std::string &name) const;
1096 :
1097 : virtual bool
1098 : AddRelationship(std::unique_ptr<GDALRelationship> &&relationship,
1099 : std::string &failureReason);
1100 :
1101 : virtual bool DeleteRelationship(const std::string &name,
1102 : std::string &failureReason);
1103 :
1104 : virtual bool
1105 : UpdateRelationship(std::unique_ptr<GDALRelationship> &&relationship,
1106 : std::string &failureReason);
1107 :
1108 : //! @cond Doxygen_Suppress
1109 : OGRLayer *CreateLayer(const char *pszName);
1110 :
1111 : OGRLayer *CreateLayer(const char *pszName, std::nullptr_t);
1112 : //! @endcond
1113 :
1114 : OGRLayer *CreateLayer(const char *pszName,
1115 : const OGRSpatialReference *poSpatialRef,
1116 : OGRwkbGeometryType eGType = wkbUnknown,
1117 : CSLConstList papszOptions = nullptr);
1118 :
1119 : OGRLayer *CreateLayer(const char *pszName,
1120 : const OGRGeomFieldDefn *poGeomFieldDefn,
1121 : CSLConstList papszOptions = nullptr);
1122 :
1123 : virtual OGRLayer *CopyLayer(OGRLayer *poSrcLayer, const char *pszNewName,
1124 : char **papszOptions = nullptr);
1125 :
1126 : virtual OGRStyleTable *GetStyleTable();
1127 : virtual void SetStyleTableDirectly(OGRStyleTable *poStyleTable);
1128 :
1129 : virtual void SetStyleTable(OGRStyleTable *poStyleTable);
1130 :
1131 : virtual OGRLayer *ExecuteSQL(const char *pszStatement,
1132 : OGRGeometry *poSpatialFilter,
1133 : const char *pszDialect);
1134 : virtual void ReleaseResultSet(OGRLayer *poResultsSet);
1135 : virtual OGRErr AbortSQL();
1136 :
1137 : int GetRefCount() const;
1138 : int GetSummaryRefCount() const;
1139 : OGRErr Release();
1140 :
1141 : virtual OGRErr StartTransaction(int bForce = FALSE);
1142 : virtual OGRErr CommitTransaction();
1143 : virtual OGRErr RollbackTransaction();
1144 :
1145 : virtual std::shared_ptr<GDALGroup> GetRootGroup() const;
1146 :
1147 : static std::string BuildFilename(const char *pszFilename,
1148 : const char *pszReferencePath,
1149 : bool bRelativeToReferencePath);
1150 :
1151 : //! @cond Doxygen_Suppress
1152 : static int IsGenericSQLDialect(const char *pszDialect);
1153 :
1154 : // Semi-public methods. Only to be used by in-tree drivers.
1155 : GDALSQLParseInfo *
1156 : BuildParseInfo(swq_select *psSelectInfo,
1157 : swq_select_parse_options *poSelectParseOptions);
1158 : static void DestroyParseInfo(GDALSQLParseInfo *psParseInfo);
1159 : OGRLayer *ExecuteSQL(const char *pszStatement, OGRGeometry *poSpatialFilter,
1160 : const char *pszDialect,
1161 : swq_select_parse_options *poSelectParseOptions);
1162 :
1163 : static constexpr const char *const apszSpecialSubDatasetSyntax[] = {
1164 : "NITF_IM:{ANY}:{FILENAME}", "PDF:{ANY}:{FILENAME}",
1165 : "RASTERLITE:{FILENAME},{ANY}", "TILEDB:\"{FILENAME}\":{ANY}",
1166 : "TILEDB:{FILENAME}:{ANY}"};
1167 :
1168 : //! @endcond
1169 :
1170 : protected:
1171 : virtual OGRLayer *ICreateLayer(const char *pszName,
1172 : const OGRGeomFieldDefn *poGeomFieldDefn,
1173 : CSLConstList papszOptions);
1174 :
1175 : //! @cond Doxygen_Suppress
1176 : OGRErr ProcessSQLCreateIndex(const char *);
1177 : OGRErr ProcessSQLDropIndex(const char *);
1178 : OGRErr ProcessSQLDropTable(const char *);
1179 : OGRErr ProcessSQLAlterTableAddColumn(const char *);
1180 : OGRErr ProcessSQLAlterTableDropColumn(const char *);
1181 : OGRErr ProcessSQLAlterTableAlterColumn(const char *);
1182 : OGRErr ProcessSQLAlterTableRenameColumn(const char *);
1183 :
1184 : OGRStyleTable *m_poStyleTable = nullptr;
1185 :
1186 : friend class GDALProxyPoolDataset;
1187 : //! @endcond
1188 :
1189 : private:
1190 : CPL_DISALLOW_COPY_ASSIGN(GDALDataset)
1191 : };
1192 :
1193 : //! @cond Doxygen_Suppress
1194 : struct CPL_DLL GDALDatasetUniquePtrDeleter
1195 : {
1196 74 : void operator()(GDALDataset *poDataset) const
1197 : {
1198 74 : GDALClose(poDataset);
1199 74 : }
1200 : };
1201 :
1202 : //! @endcond
1203 :
1204 : //! @cond Doxygen_Suppress
1205 : struct CPL_DLL GDALDatasetUniquePtrReleaser
1206 : {
1207 516 : void operator()(GDALDataset *poDataset) const
1208 : {
1209 516 : if (poDataset)
1210 513 : poDataset->Release();
1211 516 : }
1212 : };
1213 :
1214 : //! @endcond
1215 :
1216 : /** Unique pointer type for GDALDataset.
1217 : * Appropriate for use on datasets open in non-shared mode and onto which
1218 : * reference counter has not been manually modified.
1219 : * @since GDAL 2.3
1220 : */
1221 : using GDALDatasetUniquePtr =
1222 : std::unique_ptr<GDALDataset, GDALDatasetUniquePtrDeleter>;
1223 :
1224 : /* ******************************************************************** */
1225 : /* GDALRasterBlock */
1226 : /* ******************************************************************** */
1227 :
1228 : /** A single raster block in the block cache.
1229 : *
1230 : * And the global block manager that manages a least-recently-used list of
1231 : * blocks from various datasets/bands */
1232 : class CPL_DLL GDALRasterBlock
1233 : {
1234 : friend class GDALAbstractBandBlockCache;
1235 :
1236 : GDALDataType eType;
1237 :
1238 : bool bDirty;
1239 : volatile int nLockCount;
1240 :
1241 : int nXOff;
1242 : int nYOff;
1243 :
1244 : int nXSize;
1245 : int nYSize;
1246 :
1247 : void *pData;
1248 :
1249 : GDALRasterBand *poBand;
1250 :
1251 : GDALRasterBlock *poNext;
1252 : GDALRasterBlock *poPrevious;
1253 :
1254 : bool bMustDetach;
1255 :
1256 : CPL_INTERNAL void Detach_unlocked(void);
1257 : CPL_INTERNAL void Touch_unlocked(void);
1258 :
1259 : CPL_INTERNAL void RecycleFor(int nXOffIn, int nYOffIn);
1260 :
1261 : public:
1262 : GDALRasterBlock(GDALRasterBand *, int, int);
1263 : GDALRasterBlock(int nXOffIn, int nYOffIn); /* only for lookup purpose */
1264 : virtual ~GDALRasterBlock();
1265 :
1266 : CPLErr Internalize(void);
1267 : void Touch(void);
1268 : void MarkDirty(void);
1269 : void MarkClean(void);
1270 :
1271 : /** Increment the lock count */
1272 9814710 : int AddLock(void)
1273 : {
1274 9814710 : return CPLAtomicInc(&nLockCount);
1275 : }
1276 :
1277 : /** Decrement the lock count */
1278 9817835 : int DropLock(void)
1279 : {
1280 9817835 : return CPLAtomicDec(&nLockCount);
1281 : }
1282 :
1283 : void Detach();
1284 :
1285 : CPLErr Write();
1286 :
1287 : /** Return the data type
1288 : * @return data type
1289 : */
1290 19504 : GDALDataType GetDataType() const
1291 : {
1292 19504 : return eType;
1293 : }
1294 :
1295 : /** Return the x offset of the top-left corner of the block
1296 : * @return x offset
1297 : */
1298 12102500 : int GetXOff() const
1299 : {
1300 12102500 : return nXOff;
1301 : }
1302 :
1303 : /** Return the y offset of the top-left corner of the block
1304 : * @return y offset
1305 : */
1306 482941000 : int GetYOff() const
1307 : {
1308 482941000 : return nYOff;
1309 : }
1310 :
1311 : /** Return the width of the block
1312 : * @return width
1313 : */
1314 : int GetXSize() const
1315 : {
1316 : return nXSize;
1317 : }
1318 :
1319 : /** Return the height of the block
1320 : * @return height
1321 : */
1322 : int GetYSize() const
1323 : {
1324 : return nYSize;
1325 : }
1326 :
1327 : /** Return the dirty flag
1328 : * @return dirty flag
1329 : */
1330 3650260 : int GetDirty() const
1331 : {
1332 3650260 : return bDirty;
1333 : }
1334 :
1335 : /** Return the data buffer
1336 : * @return data buffer
1337 : */
1338 12985858 : void *GetDataRef(void)
1339 : {
1340 12985858 : return pData;
1341 : }
1342 :
1343 : /** Return the block size in bytes
1344 : * @return block size.
1345 : */
1346 6303030 : GPtrDiff_t GetBlockSize() const
1347 : {
1348 6303030 : return static_cast<GPtrDiff_t>(nXSize) * nYSize *
1349 6303030 : GDALGetDataTypeSizeBytes(eType);
1350 : }
1351 :
1352 : int TakeLock();
1353 : int DropLockForRemovalFromStorage();
1354 :
1355 : /// @brief Accessor to source GDALRasterBand object.
1356 : /// @return source raster band of the raster block.
1357 59240 : GDALRasterBand *GetBand()
1358 : {
1359 59240 : return poBand;
1360 : }
1361 :
1362 : static void FlushDirtyBlocks();
1363 : static int FlushCacheBlock(int bDirtyBlocksOnly = FALSE);
1364 : static void Verify();
1365 :
1366 : static void EnterDisableDirtyBlockFlush();
1367 : static void LeaveDisableDirtyBlockFlush();
1368 :
1369 : #ifdef notdef
1370 : static void CheckNonOrphanedBlocks(GDALRasterBand *poBand);
1371 : void DumpBlock();
1372 : static void DumpAll();
1373 : #endif
1374 :
1375 : /* Should only be called by GDALDestroyDriverManager() */
1376 : //! @cond Doxygen_Suppress
1377 : CPL_INTERNAL static void DestroyRBMutex();
1378 : //! @endcond
1379 :
1380 : private:
1381 : CPL_DISALLOW_COPY_ASSIGN(GDALRasterBlock)
1382 : };
1383 :
1384 : /* ******************************************************************** */
1385 : /* GDALColorTable */
1386 : /* ******************************************************************** */
1387 :
1388 : /** A color table / palette. */
1389 :
1390 2042 : class CPL_DLL GDALColorTable
1391 : {
1392 : GDALPaletteInterp eInterp;
1393 :
1394 : std::vector<GDALColorEntry> aoEntries{};
1395 :
1396 : public:
1397 : explicit GDALColorTable(GDALPaletteInterp = GPI_RGB);
1398 : ~GDALColorTable();
1399 :
1400 : GDALColorTable *Clone() const;
1401 : int IsSame(const GDALColorTable *poOtherCT) const;
1402 :
1403 : GDALPaletteInterp GetPaletteInterpretation() const;
1404 :
1405 : int GetColorEntryCount() const;
1406 : const GDALColorEntry *GetColorEntry(int i) const;
1407 : int GetColorEntryAsRGB(int i, GDALColorEntry *poEntry) const;
1408 : void SetColorEntry(int i, const GDALColorEntry *poEntry);
1409 : int CreateColorRamp(int nStartIndex, const GDALColorEntry *psStartColor,
1410 : int nEndIndex, const GDALColorEntry *psEndColor);
1411 : bool IsIdentity() const;
1412 :
1413 : /** Convert a GDALColorTable* to a GDALRasterBandH.
1414 : * @since GDAL 2.3
1415 : */
1416 1882 : static inline GDALColorTableH ToHandle(GDALColorTable *poCT)
1417 : {
1418 1882 : return static_cast<GDALColorTableH>(poCT);
1419 : }
1420 :
1421 : /** Convert a GDALColorTableH to a GDALColorTable*.
1422 : * @since GDAL 2.3
1423 : */
1424 14485 : static inline GDALColorTable *FromHandle(GDALColorTableH hCT)
1425 : {
1426 14485 : return static_cast<GDALColorTable *>(hCT);
1427 : }
1428 : };
1429 :
1430 : /* ******************************************************************** */
1431 : /* GDALAbstractBandBlockCache */
1432 : /* ******************************************************************** */
1433 :
1434 : //! @cond Doxygen_Suppress
1435 :
1436 : //! This manages how a raster band store its cached block.
1437 : // only used by GDALRasterBand implementation.
1438 :
1439 : class GDALAbstractBandBlockCache
1440 : {
1441 : // List of blocks that can be freed or recycled, and its lock
1442 : CPLLock *hSpinLock = nullptr;
1443 : GDALRasterBlock *psListBlocksToFree = nullptr;
1444 :
1445 : // Band keep alive counter, and its lock & condition
1446 : CPLCond *hCond = nullptr;
1447 : CPLMutex *hCondMutex = nullptr;
1448 : volatile int nKeepAliveCounter = 0;
1449 :
1450 : volatile int m_nDirtyBlocks = 0;
1451 :
1452 : CPL_DISALLOW_COPY_ASSIGN(GDALAbstractBandBlockCache)
1453 :
1454 : protected:
1455 : GDALRasterBand *poBand;
1456 :
1457 : int m_nInitialDirtyBlocksInFlushCache = 0;
1458 : int m_nLastTick = -1;
1459 : size_t m_nWriteDirtyBlocksDisabled = 0;
1460 :
1461 : void FreeDanglingBlocks();
1462 : void UnreferenceBlockBase();
1463 :
1464 : void StartDirtyBlockFlushingLog();
1465 : void UpdateDirtyBlockFlushingLog();
1466 : void EndDirtyBlockFlushingLog();
1467 :
1468 : public:
1469 : explicit GDALAbstractBandBlockCache(GDALRasterBand *poBand);
1470 : virtual ~GDALAbstractBandBlockCache();
1471 :
1472 : GDALRasterBlock *CreateBlock(int nXBlockOff, int nYBlockOff);
1473 : void AddBlockToFreeList(GDALRasterBlock *poBlock);
1474 : void IncDirtyBlocks(int nInc);
1475 : void WaitCompletionPendingTasks();
1476 :
1477 1 : void EnableDirtyBlockWriting()
1478 : {
1479 1 : --m_nWriteDirtyBlocksDisabled;
1480 1 : }
1481 :
1482 2550 : void DisableDirtyBlockWriting()
1483 : {
1484 2550 : ++m_nWriteDirtyBlocksDisabled;
1485 2550 : }
1486 :
1487 0 : bool HasDirtyBlocks() const
1488 : {
1489 0 : return m_nDirtyBlocks > 0;
1490 : }
1491 :
1492 : virtual bool Init() = 0;
1493 : virtual bool IsInitOK() = 0;
1494 : virtual CPLErr FlushCache() = 0;
1495 : virtual CPLErr AdoptBlock(GDALRasterBlock *poBlock) = 0;
1496 : virtual GDALRasterBlock *TryGetLockedBlockRef(int nXBlockOff,
1497 : int nYBlockYOff) = 0;
1498 : virtual CPLErr UnreferenceBlock(GDALRasterBlock *poBlock) = 0;
1499 : virtual CPLErr FlushBlock(int nXBlockOff, int nYBlockOff,
1500 : int bWriteDirtyBlock) = 0;
1501 : };
1502 :
1503 : GDALAbstractBandBlockCache *
1504 : GDALArrayBandBlockCacheCreate(GDALRasterBand *poBand);
1505 : GDALAbstractBandBlockCache *
1506 : GDALHashSetBandBlockCacheCreate(GDALRasterBand *poBand);
1507 :
1508 : //! @endcond
1509 :
1510 : /* ******************************************************************** */
1511 : /* GDALRasterBand */
1512 : /* ******************************************************************** */
1513 :
1514 : class GDALMDArray;
1515 : class GDALDoublePointsCache;
1516 :
1517 : /** Range of values found in a mask band */
1518 : typedef enum
1519 : {
1520 : GMVR_UNKNOWN, /*! Unknown (can also be used for any values between 0 and 255
1521 : for a Byte band) */
1522 : GMVR_0_AND_1_ONLY, /*! Only 0 and 1 */
1523 : GMVR_0_AND_255_ONLY, /*! Only 0 and 255 */
1524 : } GDALMaskValueRange;
1525 :
1526 : /** Suggested/most efficient access pattern to blocks. */
1527 : typedef int GDALSuggestedBlockAccessPattern;
1528 :
1529 : /** Unknown, or no particular read order is suggested. */
1530 : constexpr GDALSuggestedBlockAccessPattern GSBAP_UNKNOWN = 0;
1531 :
1532 : /** Random access to blocks is efficient. */
1533 : constexpr GDALSuggestedBlockAccessPattern GSBAP_RANDOM = 1;
1534 :
1535 : /** Reading by strips from top to bottom is the most efficient. */
1536 : constexpr GDALSuggestedBlockAccessPattern GSBAP_TOP_TO_BOTTOM = 2;
1537 :
1538 : /** Reading by strips from bottom to top is the most efficient. */
1539 : constexpr GDALSuggestedBlockAccessPattern GSBAP_BOTTOM_TO_TOP = 3;
1540 :
1541 : /** Reading the largest chunk from the raster is the most efficient (can be
1542 : * combined with above values). */
1543 : constexpr GDALSuggestedBlockAccessPattern GSBAP_LARGEST_CHUNK_POSSIBLE = 0x100;
1544 :
1545 : /** A single raster band (or channel). */
1546 :
1547 : class CPL_DLL GDALRasterBand : public GDALMajorObject
1548 : {
1549 : private:
1550 : friend class GDALArrayBandBlockCache;
1551 : friend class GDALHashSetBandBlockCache;
1552 : friend class GDALRasterBlock;
1553 : friend class GDALDataset;
1554 :
1555 : CPLErr eFlushBlockErr = CE_None;
1556 : GDALAbstractBandBlockCache *poBandBlockCache = nullptr;
1557 :
1558 : CPL_INTERNAL void SetFlushBlockErr(CPLErr eErr);
1559 : CPL_INTERNAL CPLErr UnreferenceBlock(GDALRasterBlock *poBlock);
1560 : CPL_INTERNAL void IncDirtyBlocks(int nInc);
1561 :
1562 : protected:
1563 : //! @cond Doxygen_Suppress
1564 : GDALDataset *poDS = nullptr;
1565 : int nBand = 0; /* 1 based */
1566 :
1567 : int nRasterXSize = 0;
1568 : int nRasterYSize = 0;
1569 :
1570 : GDALDataType eDataType = GDT_Byte;
1571 : GDALAccess eAccess = GA_ReadOnly;
1572 :
1573 : /* stuff related to blocking, and raster cache */
1574 : int nBlockXSize = -1;
1575 : int nBlockYSize = -1;
1576 : int nBlocksPerRow = 0;
1577 : int nBlocksPerColumn = 0;
1578 :
1579 : int nBlockReads = 0;
1580 : int bForceCachedIO = 0;
1581 :
1582 : class GDALRasterBandOwnedOrNot
1583 : {
1584 : public:
1585 1200720 : GDALRasterBandOwnedOrNot()
1586 1200720 : {
1587 1200630 : }
1588 :
1589 : GDALRasterBandOwnedOrNot(GDALRasterBand *poBand, bool bOwned)
1590 : : m_poBandOwned(bOwned ? poBand : nullptr),
1591 : m_poBandRef(bOwned ? nullptr : poBand)
1592 : {
1593 : }
1594 :
1595 1200880 : void reset()
1596 : {
1597 1200880 : m_poBandOwned.reset();
1598 1200870 : m_poBandRef = nullptr;
1599 1200870 : }
1600 :
1601 28359 : void reset(GDALRasterBand *poBand, bool bOwned)
1602 : {
1603 28359 : m_poBandOwned.reset(bOwned ? poBand : nullptr);
1604 28358 : m_poBandRef = bOwned ? nullptr : poBand;
1605 28358 : }
1606 :
1607 66847 : void reset(std::unique_ptr<GDALRasterBand> poBand)
1608 : {
1609 66847 : m_poBandOwned = std::move(poBand);
1610 66847 : m_poBandRef = nullptr;
1611 66847 : }
1612 :
1613 2 : const GDALRasterBand *get() const
1614 : {
1615 2 : return static_cast<const GDALRasterBand *>(*this);
1616 : }
1617 :
1618 1338210 : GDALRasterBand *get()
1619 : {
1620 1338210 : return static_cast<GDALRasterBand *>(*this);
1621 : }
1622 :
1623 665213 : bool IsOwned() const
1624 : {
1625 665213 : return m_poBandOwned != nullptr;
1626 : }
1627 :
1628 2 : operator const GDALRasterBand *() const
1629 : {
1630 2 : return m_poBandOwned ? m_poBandOwned.get() : m_poBandRef;
1631 : }
1632 :
1633 2845770 : operator GDALRasterBand *()
1634 : {
1635 2845770 : return m_poBandOwned ? m_poBandOwned.get() : m_poBandRef;
1636 : }
1637 :
1638 : private:
1639 : CPL_DISALLOW_COPY_ASSIGN(GDALRasterBandOwnedOrNot)
1640 : std::unique_ptr<GDALRasterBand> m_poBandOwned{};
1641 : GDALRasterBand *m_poBandRef = nullptr;
1642 : };
1643 :
1644 : GDALRasterBandOwnedOrNot poMask{};
1645 : bool m_bEnablePixelTypeSignedByteWarning =
1646 : true; // Remove me in GDAL 4.0. See GetMetadataItem() implementation
1647 : int nMaskFlags = 0;
1648 :
1649 : void InvalidateMaskBand();
1650 :
1651 : friend class GDALProxyRasterBand;
1652 : friend class GDALDefaultOverviews;
1653 :
1654 : CPLErr
1655 : RasterIOResampled(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1656 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
1657 : GDALDataType eBufType, GSpacing nPixelSpace,
1658 : GSpacing nLineSpace,
1659 : GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
1660 :
1661 : int EnterReadWrite(GDALRWFlag eRWFlag);
1662 : void LeaveReadWrite();
1663 : void InitRWLock();
1664 : void SetValidPercent(GUIntBig nSampleCount, GUIntBig nValidCount);
1665 :
1666 : mutable GDALDoublePointsCache *m_poPointsCache = nullptr;
1667 :
1668 : //! @endcond
1669 :
1670 : protected:
1671 : virtual CPLErr IReadBlock(int nBlockXOff, int nBlockYOff, void *pData) = 0;
1672 : virtual CPLErr IWriteBlock(int nBlockXOff, int nBlockYOff, void *pData);
1673 :
1674 : virtual CPLErr
1675 : IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize,
1676 : void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType,
1677 : GSpacing nPixelSpace, GSpacing nLineSpace,
1678 : GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
1679 :
1680 : virtual int IGetDataCoverageStatus(int nXOff, int nYOff, int nXSize,
1681 : int nYSize, int nMaskFlagStop,
1682 : double *pdfDataPct);
1683 :
1684 : virtual bool
1685 : EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const;
1686 :
1687 : //! @cond Doxygen_Suppress
1688 : CPLErr
1689 : OverviewRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1690 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
1691 : GDALDataType eBufType, GSpacing nPixelSpace,
1692 : GSpacing nLineSpace,
1693 : GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
1694 :
1695 : CPLErr TryOverviewRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
1696 : int nXSize, int nYSize, void *pData,
1697 : int nBufXSize, int nBufYSize,
1698 : GDALDataType eBufType, GSpacing nPixelSpace,
1699 : GSpacing nLineSpace,
1700 : GDALRasterIOExtraArg *psExtraArg, int *pbTried);
1701 :
1702 : int InitBlockInfo();
1703 :
1704 : void AddBlockToFreeList(GDALRasterBlock *);
1705 :
1706 2100690 : bool HasBlockCache() const
1707 : {
1708 2100690 : return poBandBlockCache != nullptr;
1709 : }
1710 :
1711 17 : bool HasDirtyBlocks() const
1712 : {
1713 17 : return poBandBlockCache && poBandBlockCache->HasDirtyBlocks();
1714 : }
1715 :
1716 : //! @endcond
1717 :
1718 : public:
1719 : GDALRasterBand();
1720 : explicit GDALRasterBand(int bForceCachedIO);
1721 :
1722 : ~GDALRasterBand() override;
1723 :
1724 : int GetXSize() const;
1725 : int GetYSize() const;
1726 : int GetBand() const;
1727 : GDALDataset *GetDataset() const;
1728 :
1729 : GDALDataType GetRasterDataType(void) const;
1730 : void GetBlockSize(int *pnXSize, int *pnYSize) const;
1731 : CPLErr GetActualBlockSize(int nXBlockOff, int nYBlockOff, int *pnXValid,
1732 : int *pnYValid) const;
1733 :
1734 : virtual GDALSuggestedBlockAccessPattern
1735 : GetSuggestedBlockAccessPattern() const;
1736 :
1737 : GDALAccess GetAccess();
1738 :
1739 : #ifndef DOXYGEN_SKIP
1740 : CPLErr RasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1741 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
1742 : GDALDataType eBufType, GSpacing nPixelSpace,
1743 : GSpacing nLineSpace,
1744 : GDALRasterIOExtraArg *psExtraArg
1745 : OPTIONAL_OUTSIDE_GDAL(nullptr)) CPL_WARN_UNUSED_RESULT;
1746 : #else
1747 : CPLErr RasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1748 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
1749 : GDALDataType eBufType, GSpacing nPixelSpace,
1750 : GSpacing nLineSpace,
1751 : GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
1752 : #endif
1753 :
1754 : template <class T>
1755 : CPLErr ReadRaster(T *pData, size_t nArrayEltCount = 0, double dfXOff = 0,
1756 : double dfYOff = 0, double dfXSize = 0, double dfYSize = 0,
1757 : size_t nBufXSize = 0, size_t nBufYSize = 0,
1758 : GDALRIOResampleAlg eResampleAlg = GRIORA_NearestNeighbour,
1759 : GDALProgressFunc pfnProgress = nullptr,
1760 : void *pProgressData = nullptr) const;
1761 :
1762 : template <class T>
1763 : CPLErr ReadRaster(std::vector<T> &vData, double dfXOff = 0,
1764 : double dfYOff = 0, double dfXSize = 0, double dfYSize = 0,
1765 : size_t nBufXSize = 0, size_t nBufYSize = 0,
1766 : GDALRIOResampleAlg eResampleAlg = GRIORA_NearestNeighbour,
1767 : GDALProgressFunc pfnProgress = nullptr,
1768 : void *pProgressData = nullptr) const;
1769 :
1770 : #if __cplusplus >= 202002L
1771 : //! @cond Doxygen_Suppress
1772 : template <class T>
1773 : inline CPLErr
1774 : ReadRaster(std::span<T> pData, double dfXOff = 0, double dfYOff = 0,
1775 : double dfXSize = 0, double dfYSize = 0, size_t nBufXSize = 0,
1776 : size_t nBufYSize = 0,
1777 : GDALRIOResampleAlg eResampleAlg = GRIORA_NearestNeighbour,
1778 : GDALProgressFunc pfnProgress = nullptr,
1779 : void *pProgressData = nullptr) const
1780 : {
1781 : return ReadRaster(pData.data(), pData.size(), dfXOff, dfYOff, dfXSize,
1782 : dfYSize, nBufXSize, nBufYSize, eResampleAlg,
1783 : pfnProgress, pProgressData);
1784 : }
1785 :
1786 : //! @endcond
1787 : #endif
1788 :
1789 : CPLErr ReadBlock(int nXBlockOff, int nYBlockOff,
1790 : void *pImage) CPL_WARN_UNUSED_RESULT;
1791 :
1792 : CPLErr WriteBlock(int nXBlockOff, int nYBlockOff,
1793 : void *pImage) CPL_WARN_UNUSED_RESULT;
1794 :
1795 : // This method should only be overloaded by GDALProxyRasterBand
1796 : virtual GDALRasterBlock *
1797 : GetLockedBlockRef(int nXBlockOff, int nYBlockOff,
1798 : int bJustInitialize = FALSE) CPL_WARN_UNUSED_RESULT;
1799 :
1800 : // This method should only be overloaded by GDALProxyRasterBand
1801 : virtual GDALRasterBlock *
1802 : TryGetLockedBlockRef(int nXBlockOff,
1803 : int nYBlockYOff) CPL_WARN_UNUSED_RESULT;
1804 :
1805 : // This method should only be overloaded by GDALProxyRasterBand
1806 : virtual CPLErr FlushBlock(int nXBlockOff, int nYBlockOff,
1807 : int bWriteDirtyBlock = TRUE);
1808 :
1809 : unsigned char *
1810 : GetIndexColorTranslationTo(/* const */ GDALRasterBand *poReferenceBand,
1811 : unsigned char *pTranslationTable = nullptr,
1812 : int *pApproximateMatching = nullptr);
1813 :
1814 : // New OpengIS CV_SampleDimension stuff.
1815 :
1816 : virtual CPLErr FlushCache(bool bAtClosing = false);
1817 : virtual CPLErr DropCache();
1818 : virtual char **GetCategoryNames();
1819 : virtual double GetNoDataValue(int *pbSuccess = nullptr);
1820 : virtual int64_t GetNoDataValueAsInt64(int *pbSuccess = nullptr);
1821 : virtual uint64_t GetNoDataValueAsUInt64(int *pbSuccess = nullptr);
1822 : virtual double GetMinimum(int *pbSuccess = nullptr);
1823 : virtual double GetMaximum(int *pbSuccess = nullptr);
1824 : virtual double GetOffset(int *pbSuccess = nullptr);
1825 : virtual double GetScale(int *pbSuccess = nullptr);
1826 : virtual const char *GetUnitType();
1827 : virtual GDALColorInterp GetColorInterpretation();
1828 : virtual GDALColorTable *GetColorTable();
1829 : virtual CPLErr Fill(double dfRealValue, double dfImaginaryValue = 0);
1830 :
1831 : virtual CPLErr SetCategoryNames(char **papszNames);
1832 : virtual CPLErr SetNoDataValue(double dfNoData);
1833 : virtual CPLErr SetNoDataValueAsInt64(int64_t nNoData);
1834 : virtual CPLErr SetNoDataValueAsUInt64(uint64_t nNoData);
1835 : virtual CPLErr DeleteNoDataValue();
1836 : virtual CPLErr SetColorTable(GDALColorTable *poCT);
1837 : virtual CPLErr SetColorInterpretation(GDALColorInterp eColorInterp);
1838 : virtual CPLErr SetOffset(double dfNewOffset);
1839 : virtual CPLErr SetScale(double dfNewScale);
1840 : virtual CPLErr SetUnitType(const char *pszNewValue);
1841 :
1842 : virtual CPLErr GetStatistics(int bApproxOK, int bForce, double *pdfMin,
1843 : double *pdfMax, double *pdfMean,
1844 : double *padfStdDev);
1845 : virtual CPLErr ComputeStatistics(int bApproxOK, double *pdfMin,
1846 : double *pdfMax, double *pdfMean,
1847 : double *pdfStdDev, GDALProgressFunc,
1848 : void *pProgressData);
1849 : virtual CPLErr SetStatistics(double dfMin, double dfMax, double dfMean,
1850 : double dfStdDev);
1851 : virtual CPLErr ComputeRasterMinMax(int bApproxOK, double *adfMinMax);
1852 : virtual CPLErr ComputeRasterMinMaxLocation(double *pdfMin, double *pdfMax,
1853 : int *pnMinX, int *pnMinY,
1854 : int *pnMaxX, int *pnMaxY);
1855 :
1856 : // Only defined when Doxygen enabled
1857 : #ifdef DOXYGEN_SKIP
1858 : CPLErr SetMetadata(char **papszMetadata, const char *pszDomain) override;
1859 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
1860 : const char *pszDomain) override;
1861 : #endif
1862 : virtual const char *GetMetadataItem(const char *pszName,
1863 : const char *pszDomain = "") override;
1864 :
1865 : virtual int HasArbitraryOverviews();
1866 : virtual int GetOverviewCount();
1867 : virtual GDALRasterBand *GetOverview(int i);
1868 : virtual GDALRasterBand *GetRasterSampleOverview(GUIntBig);
1869 : virtual CPLErr BuildOverviews(const char *pszResampling, int nOverviews,
1870 : const int *panOverviewList,
1871 : GDALProgressFunc pfnProgress,
1872 : void *pProgressData,
1873 : CSLConstList papszOptions);
1874 :
1875 : virtual CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize,
1876 : int nBufXSize, int nBufYSize,
1877 : GDALDataType eBufType, char **papszOptions);
1878 :
1879 : virtual CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets,
1880 : GUIntBig *panHistogram, int bIncludeOutOfRange,
1881 : int bApproxOK, GDALProgressFunc,
1882 : void *pProgressData);
1883 :
1884 : virtual CPLErr GetDefaultHistogram(double *pdfMin, double *pdfMax,
1885 : int *pnBuckets, GUIntBig **ppanHistogram,
1886 : int bForce, GDALProgressFunc,
1887 : void *pProgressData);
1888 : virtual CPLErr SetDefaultHistogram(double dfMin, double dfMax, int nBuckets,
1889 : GUIntBig *panHistogram);
1890 :
1891 : virtual GDALRasterAttributeTable *GetDefaultRAT();
1892 : virtual CPLErr SetDefaultRAT(const GDALRasterAttributeTable *poRAT);
1893 :
1894 : virtual GDALRasterBand *GetMaskBand();
1895 : virtual int GetMaskFlags();
1896 : virtual CPLErr CreateMaskBand(int nFlagsIn);
1897 : virtual bool IsMaskBand() const;
1898 : virtual GDALMaskValueRange GetMaskValueRange() const;
1899 :
1900 : virtual CPLVirtualMem *
1901 : GetVirtualMemAuto(GDALRWFlag eRWFlag, int *pnPixelSpace,
1902 : GIntBig *pnLineSpace,
1903 : char **papszOptions) CPL_WARN_UNUSED_RESULT;
1904 :
1905 : int GetDataCoverageStatus(int nXOff, int nYOff, int nXSize, int nYSize,
1906 : int nMaskFlagStop = 0,
1907 : double *pdfDataPct = nullptr);
1908 :
1909 : std::shared_ptr<GDALMDArray> AsMDArray() const;
1910 :
1911 : CPLErr InterpolateAtGeolocation(
1912 : double dfGeolocX, double dfGeolocY, const OGRSpatialReference *poSRS,
1913 : GDALRIOResampleAlg eInterpolation, double *pdfRealValue,
1914 : double *pdfImagValue = nullptr,
1915 : CSLConstList papszTransformerOptions = nullptr) const;
1916 :
1917 : virtual CPLErr InterpolateAtPoint(double dfPixel, double dfLine,
1918 : GDALRIOResampleAlg eInterpolation,
1919 : double *pdfRealValue,
1920 : double *pdfImagValue = nullptr) const;
1921 :
1922 : #ifndef DOXYGEN_XML
1923 : void ReportError(CPLErr eErrClass, CPLErrorNum err_no, const char *fmt,
1924 : ...) const CPL_PRINT_FUNC_FORMAT(4, 5);
1925 : #endif
1926 :
1927 : /** Convert a GDALRasterBand* to a GDALRasterBandH.
1928 : * @since GDAL 2.3
1929 : */
1930 314085 : static inline GDALRasterBandH ToHandle(GDALRasterBand *poBand)
1931 : {
1932 314085 : return static_cast<GDALRasterBandH>(poBand);
1933 : }
1934 :
1935 : /** Convert a GDALRasterBandH to a GDALRasterBand*.
1936 : * @since GDAL 2.3
1937 : */
1938 5190928 : static inline GDALRasterBand *FromHandle(GDALRasterBandH hBand)
1939 : {
1940 5190928 : return static_cast<GDALRasterBand *>(hBand);
1941 : }
1942 :
1943 : //! @cond Doxygen_Suppress
1944 : // Remove me in GDAL 4.0. See GetMetadataItem() implementation
1945 : // Internal use in GDAL only !
1946 : virtual void EnablePixelTypeSignedByteWarning(bool b)
1947 : #ifndef GDAL_COMPILATION
1948 : CPL_WARN_DEPRECATED("Do not use that method outside of GDAL!")
1949 : #endif
1950 : ;
1951 :
1952 : //! @endcond
1953 :
1954 : private:
1955 : CPL_DISALLOW_COPY_ASSIGN(GDALRasterBand)
1956 : };
1957 :
1958 : //! @cond Doxygen_Suppress
1959 : #define GDAL_EXTERN_TEMPLATE_READ_RASTER(T) \
1960 : extern template CPLErr GDALRasterBand::ReadRaster<T>( \
1961 : T * pData, size_t nArrayEltCount, double dfXOff, double dfYOff, \
1962 : double dfXSize, double dfYSize, size_t nBufXSize, size_t nBufYSize, \
1963 : GDALRIOResampleAlg eResampleAlg, GDALProgressFunc pfnProgress, \
1964 : void *pProgressData) const;
1965 :
1966 : GDAL_EXTERN_TEMPLATE_READ_RASTER(uint8_t)
1967 : GDAL_EXTERN_TEMPLATE_READ_RASTER(int8_t)
1968 : GDAL_EXTERN_TEMPLATE_READ_RASTER(uint16_t)
1969 : GDAL_EXTERN_TEMPLATE_READ_RASTER(int16_t)
1970 : GDAL_EXTERN_TEMPLATE_READ_RASTER(uint32_t)
1971 : GDAL_EXTERN_TEMPLATE_READ_RASTER(int32_t)
1972 : GDAL_EXTERN_TEMPLATE_READ_RASTER(uint64_t)
1973 : GDAL_EXTERN_TEMPLATE_READ_RASTER(int64_t)
1974 : GDAL_EXTERN_TEMPLATE_READ_RASTER(float)
1975 : GDAL_EXTERN_TEMPLATE_READ_RASTER(double)
1976 : // Not allowed by C++ standard
1977 : // GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<int16_t>)
1978 : // GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<int32_t>)
1979 : GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<float>)
1980 : GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<double>)
1981 :
1982 : #define GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(T) \
1983 : extern template CPLErr GDALRasterBand::ReadRaster<T>( \
1984 : std::vector<T> & vData, double dfXOff, double dfYOff, double dfXSize, \
1985 : double dfYSize, size_t nBufXSize, size_t nBufYSize, \
1986 : GDALRIOResampleAlg eResampleAlg, GDALProgressFunc pfnProgress, \
1987 : void *pProgressData) const;
1988 :
1989 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint8_t)
1990 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int8_t)
1991 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint16_t)
1992 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int16_t)
1993 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint32_t)
1994 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int32_t)
1995 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint64_t)
1996 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int64_t)
1997 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(float)
1998 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(double)
1999 : // Not allowed by C++ standard
2000 : // GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<int16_t>)
2001 : // GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<int32_t>)
2002 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<float>)
2003 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<double>)
2004 :
2005 : //! @endcond
2006 :
2007 : //! @cond Doxygen_Suppress
2008 : /* ******************************************************************** */
2009 : /* GDALAllValidMaskBand */
2010 : /* ******************************************************************** */
2011 :
2012 184784 : class CPL_DLL GDALAllValidMaskBand : public GDALRasterBand
2013 : {
2014 : protected:
2015 : CPLErr IReadBlock(int, int, void *) override;
2016 :
2017 : CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
2018 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
2019 : GDALDataType eBufType, GSpacing nPixelSpace,
2020 : GSpacing nLineSpace,
2021 : GDALRasterIOExtraArg *psExtraArg) override;
2022 :
2023 : bool
2024 : EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2025 :
2026 : CPL_DISALLOW_COPY_ASSIGN(GDALAllValidMaskBand)
2027 :
2028 : public:
2029 : explicit GDALAllValidMaskBand(GDALRasterBand *);
2030 : ~GDALAllValidMaskBand() override;
2031 :
2032 : GDALRasterBand *GetMaskBand() override;
2033 : int GetMaskFlags() override;
2034 :
2035 1 : bool IsMaskBand() const override
2036 : {
2037 1 : return true;
2038 : }
2039 :
2040 0 : GDALMaskValueRange GetMaskValueRange() const override
2041 : {
2042 0 : return GMVR_0_AND_255_ONLY;
2043 : }
2044 :
2045 : CPLErr ComputeStatistics(int bApproxOK, double *pdfMin, double *pdfMax,
2046 : double *pdfMean, double *pdfStdDev,
2047 : GDALProgressFunc, void *pProgressData) override;
2048 : };
2049 :
2050 : /* ******************************************************************** */
2051 : /* GDALNoDataMaskBand */
2052 : /* ******************************************************************** */
2053 :
2054 1692 : class CPL_DLL GDALNoDataMaskBand : public GDALRasterBand
2055 : {
2056 : friend class GDALRasterBand;
2057 : double m_dfNoDataValue = 0;
2058 : int64_t m_nNoDataValueInt64 = 0;
2059 : uint64_t m_nNoDataValueUInt64 = 0;
2060 : GDALRasterBand *m_poParent = nullptr;
2061 :
2062 : CPL_DISALLOW_COPY_ASSIGN(GDALNoDataMaskBand)
2063 :
2064 : protected:
2065 : CPLErr IReadBlock(int, int, void *) override;
2066 : CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
2067 : GDALDataType, GSpacing, GSpacing,
2068 : GDALRasterIOExtraArg *psExtraArg) override;
2069 :
2070 : bool
2071 : EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2072 :
2073 : public:
2074 : explicit GDALNoDataMaskBand(GDALRasterBand *);
2075 : explicit GDALNoDataMaskBand(GDALRasterBand *, double dfNoDataValue);
2076 : ~GDALNoDataMaskBand() override;
2077 :
2078 1 : bool IsMaskBand() const override
2079 : {
2080 1 : return true;
2081 : }
2082 :
2083 0 : GDALMaskValueRange GetMaskValueRange() const override
2084 : {
2085 0 : return GMVR_0_AND_255_ONLY;
2086 : }
2087 :
2088 : static bool IsNoDataInRange(double dfNoDataValue, GDALDataType eDataType);
2089 : };
2090 :
2091 : /* ******************************************************************** */
2092 : /* GDALNoDataValuesMaskBand */
2093 : /* ******************************************************************** */
2094 :
2095 : class CPL_DLL GDALNoDataValuesMaskBand : public GDALRasterBand
2096 : {
2097 : double *padfNodataValues;
2098 :
2099 : CPL_DISALLOW_COPY_ASSIGN(GDALNoDataValuesMaskBand)
2100 :
2101 : protected:
2102 : CPLErr IReadBlock(int, int, void *) override;
2103 :
2104 : bool
2105 : EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2106 :
2107 : public:
2108 : explicit GDALNoDataValuesMaskBand(GDALDataset *);
2109 : ~GDALNoDataValuesMaskBand() override;
2110 :
2111 0 : bool IsMaskBand() const override
2112 : {
2113 0 : return true;
2114 : }
2115 :
2116 0 : GDALMaskValueRange GetMaskValueRange() const override
2117 : {
2118 0 : return GMVR_0_AND_255_ONLY;
2119 : }
2120 : };
2121 :
2122 : /* ******************************************************************** */
2123 : /* GDALRescaledAlphaBand */
2124 : /* ******************************************************************** */
2125 :
2126 : class GDALRescaledAlphaBand : public GDALRasterBand
2127 : {
2128 : GDALRasterBand *poParent;
2129 : void *pTemp;
2130 :
2131 : CPL_DISALLOW_COPY_ASSIGN(GDALRescaledAlphaBand)
2132 :
2133 : protected:
2134 : CPLErr IReadBlock(int, int, void *) override;
2135 : CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
2136 : GDALDataType, GSpacing, GSpacing,
2137 : GDALRasterIOExtraArg *psExtraArg) override;
2138 :
2139 : bool
2140 : EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2141 :
2142 : public:
2143 : explicit GDALRescaledAlphaBand(GDALRasterBand *);
2144 : ~GDALRescaledAlphaBand() override;
2145 :
2146 0 : bool IsMaskBand() const override
2147 : {
2148 0 : return true;
2149 : }
2150 : };
2151 :
2152 : //! @endcond
2153 :
2154 : /* ******************************************************************** */
2155 : /* GDALIdentifyEnum */
2156 : /* ******************************************************************** */
2157 :
2158 : /**
2159 : * Enumeration used by GDALDriver::pfnIdentify().
2160 : *
2161 : * @since GDAL 2.1
2162 : */
2163 : typedef enum
2164 : {
2165 : /** Identify could not determine if the file is recognized or not by the
2166 : probed driver. */
2167 : GDAL_IDENTIFY_UNKNOWN = -1,
2168 : /** Identify determined the file is not recognized by the probed driver. */
2169 : GDAL_IDENTIFY_FALSE = 0,
2170 : /** Identify determined the file is recognized by the probed driver. */
2171 : GDAL_IDENTIFY_TRUE = 1
2172 : } GDALIdentifyEnum;
2173 :
2174 : /* ******************************************************************** */
2175 : /* GDALDriver */
2176 : /* ******************************************************************** */
2177 :
2178 : /**
2179 : * \brief Format specific driver.
2180 : *
2181 : * An instance of this class is created for each supported format, and
2182 : * manages information about the format.
2183 : *
2184 : * This roughly corresponds to a file format, though some
2185 : * drivers may be gateways to many formats through a secondary
2186 : * multi-library.
2187 : */
2188 :
2189 301294 : class CPL_DLL GDALDriver : public GDALMajorObject
2190 : {
2191 : public:
2192 : GDALDriver();
2193 : ~GDALDriver() override;
2194 :
2195 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
2196 : const char *pszDomain = "") override;
2197 :
2198 : /* -------------------------------------------------------------------- */
2199 : /* Public C++ methods. */
2200 : /* -------------------------------------------------------------------- */
2201 : GDALDataset *Create(const char *pszName, int nXSize, int nYSize, int nBands,
2202 : GDALDataType eType,
2203 : CSLConstList papszOptions) CPL_WARN_UNUSED_RESULT;
2204 :
2205 : GDALDataset *
2206 : CreateMultiDimensional(const char *pszName,
2207 : CSLConstList papszRootGroupOptions,
2208 : CSLConstList papszOptions) CPL_WARN_UNUSED_RESULT;
2209 :
2210 : CPLErr Delete(const char *pszName);
2211 : CPLErr Rename(const char *pszNewName, const char *pszOldName);
2212 : CPLErr CopyFiles(const char *pszNewName, const char *pszOldName);
2213 :
2214 : GDALDataset *CreateCopy(const char *, GDALDataset *, int,
2215 : CSLConstList papszOptions,
2216 : GDALProgressFunc pfnProgress,
2217 : void *pProgressData) CPL_WARN_UNUSED_RESULT;
2218 :
2219 : bool CanVectorTranslateFrom(const char *pszDestName,
2220 : GDALDataset *poSourceDS,
2221 : CSLConstList papszVectorTranslateArguments,
2222 : char ***ppapszFailureReasons);
2223 :
2224 : /**
2225 : * \brief Returns TRUE if the given open option is supported by the driver.
2226 : * @param pszOpenOptionName name of the open option to be checked
2227 : * @return TRUE if the driver supports the open option
2228 : * @since GDAL 3.11
2229 : */
2230 : bool HasOpenOption(const char *pszOpenOptionName) const;
2231 :
2232 : GDALDataset *
2233 : VectorTranslateFrom(const char *pszDestName, GDALDataset *poSourceDS,
2234 : CSLConstList papszVectorTranslateArguments,
2235 : GDALProgressFunc pfnProgress,
2236 : void *pProgressData) CPL_WARN_UNUSED_RESULT;
2237 :
2238 : /* -------------------------------------------------------------------- */
2239 : /* The following are semiprivate, not intended to be accessed */
2240 : /* by anyone but the formats instantiating and populating the */
2241 : /* drivers. */
2242 : /* -------------------------------------------------------------------- */
2243 : //! @cond Doxygen_Suppress
2244 :
2245 : // Not aimed at being used outside of GDAL. Use GDALDataset::Open() instead
2246 : GDALDataset *Open(GDALOpenInfo *poOpenInfo, bool bSetOpenOptions);
2247 :
2248 : typedef GDALDataset *(*OpenCallback)(GDALOpenInfo *);
2249 :
2250 : OpenCallback pfnOpen = nullptr;
2251 :
2252 432259 : virtual OpenCallback GetOpenCallback()
2253 : {
2254 432259 : return pfnOpen;
2255 : }
2256 :
2257 : typedef GDALDataset *(*CreateCallback)(const char *pszName, int nXSize,
2258 : int nYSize, int nBands,
2259 : GDALDataType eType,
2260 : char **papszOptions);
2261 :
2262 : CreateCallback pfnCreate = nullptr;
2263 :
2264 19636 : virtual CreateCallback GetCreateCallback()
2265 : {
2266 19636 : return pfnCreate;
2267 : }
2268 :
2269 : GDALDataset *(*pfnCreateEx)(GDALDriver *, const char *pszName, int nXSize,
2270 : int nYSize, int nBands, GDALDataType eType,
2271 : char **papszOptions) = nullptr;
2272 :
2273 : typedef GDALDataset *(*CreateMultiDimensionalCallback)(
2274 : const char *pszName, CSLConstList papszRootGroupOptions,
2275 : CSLConstList papszOptions);
2276 :
2277 : CreateMultiDimensionalCallback pfnCreateMultiDimensional = nullptr;
2278 :
2279 467 : virtual CreateMultiDimensionalCallback GetCreateMultiDimensionalCallback()
2280 : {
2281 467 : return pfnCreateMultiDimensional;
2282 : }
2283 :
2284 : typedef CPLErr (*DeleteCallback)(const char *pszName);
2285 : DeleteCallback pfnDelete = nullptr;
2286 :
2287 5395 : virtual DeleteCallback GetDeleteCallback()
2288 : {
2289 5395 : return pfnDelete;
2290 : }
2291 :
2292 : typedef GDALDataset *(*CreateCopyCallback)(const char *, GDALDataset *, int,
2293 : char **,
2294 : GDALProgressFunc pfnProgress,
2295 : void *pProgressData);
2296 :
2297 : CreateCopyCallback pfnCreateCopy = nullptr;
2298 :
2299 10417 : virtual CreateCopyCallback GetCreateCopyCallback()
2300 : {
2301 10417 : return pfnCreateCopy;
2302 : }
2303 :
2304 : void *pDriverData = nullptr;
2305 :
2306 : void (*pfnUnloadDriver)(GDALDriver *) = nullptr;
2307 :
2308 : /** Identify() if the file is recognized or not by the driver.
2309 :
2310 : Return GDAL_IDENTIFY_TRUE (1) if the passed file is certainly recognized
2311 : by the driver. Return GDAL_IDENTIFY_FALSE (0) if the passed file is
2312 : certainly NOT recognized by the driver. Return GDAL_IDENTIFY_UNKNOWN (-1)
2313 : if the passed file may be or may not be recognized by the driver, and
2314 : that a potentially costly test must be done with pfnOpen.
2315 : */
2316 : int (*pfnIdentify)(GDALOpenInfo *) = nullptr;
2317 : int (*pfnIdentifyEx)(GDALDriver *, GDALOpenInfo *) = nullptr;
2318 :
2319 : typedef CPLErr (*RenameCallback)(const char *pszNewName,
2320 : const char *pszOldName);
2321 : RenameCallback pfnRename = nullptr;
2322 :
2323 174 : virtual RenameCallback GetRenameCallback()
2324 : {
2325 174 : return pfnRename;
2326 : }
2327 :
2328 : typedef CPLErr (*CopyFilesCallback)(const char *pszNewName,
2329 : const char *pszOldName);
2330 : CopyFilesCallback pfnCopyFiles = nullptr;
2331 :
2332 9 : virtual CopyFilesCallback GetCopyFilesCallback()
2333 : {
2334 9 : return pfnCopyFiles;
2335 : }
2336 :
2337 : // Used for legacy OGR drivers, and Python drivers
2338 : GDALDataset *(*pfnOpenWithDriverArg)(GDALDriver *,
2339 : GDALOpenInfo *) = nullptr;
2340 :
2341 : /* For legacy OGR drivers */
2342 : GDALDataset *(*pfnCreateVectorOnly)(GDALDriver *, const char *pszName,
2343 : char **papszOptions) = nullptr;
2344 : CPLErr (*pfnDeleteDataSource)(GDALDriver *, const char *pszName) = nullptr;
2345 :
2346 : /** Whether pfnVectorTranslateFrom() can be run given the source dataset
2347 : * and the non-positional arguments of GDALVectorTranslate() stored
2348 : * in papszVectorTranslateArguments.
2349 : */
2350 : bool (*pfnCanVectorTranslateFrom)(
2351 : const char *pszDestName, GDALDataset *poSourceDS,
2352 : CSLConstList papszVectorTranslateArguments,
2353 : char ***ppapszFailureReasons) = nullptr;
2354 :
2355 : /** Creates a copy from the specified source dataset, using the
2356 : * non-positional arguments of GDALVectorTranslate() stored
2357 : * in papszVectorTranslateArguments.
2358 : */
2359 : GDALDataset *(*pfnVectorTranslateFrom)(
2360 : const char *pszDestName, GDALDataset *poSourceDS,
2361 : CSLConstList papszVectorTranslateArguments,
2362 : GDALProgressFunc pfnProgress, void *pProgressData) = nullptr;
2363 :
2364 : /**
2365 : * Returns a (possibly null) pointer to the Subdataset informational function
2366 : * from the subdataset file name.
2367 : */
2368 : GDALSubdatasetInfo *(*pfnGetSubdatasetInfoFunc)(const char *pszFileName) =
2369 : nullptr;
2370 :
2371 : //! @endcond
2372 :
2373 : /* -------------------------------------------------------------------- */
2374 : /* Helper methods. */
2375 : /* -------------------------------------------------------------------- */
2376 : //! @cond Doxygen_Suppress
2377 : GDALDataset *DefaultCreateCopy(const char *, GDALDataset *, int,
2378 : CSLConstList papszOptions,
2379 : GDALProgressFunc pfnProgress,
2380 : void *pProgressData) CPL_WARN_UNUSED_RESULT;
2381 :
2382 : static CPLErr DefaultCreateCopyMultiDimensional(
2383 : GDALDataset *poSrcDS, GDALDataset *poDstDS, bool bStrict,
2384 : CSLConstList /*papszOptions*/, GDALProgressFunc pfnProgress,
2385 : void *pProgressData);
2386 :
2387 : static CPLErr DefaultCopyMasks(GDALDataset *poSrcDS, GDALDataset *poDstDS,
2388 : int bStrict);
2389 : static CPLErr DefaultCopyMasks(GDALDataset *poSrcDS, GDALDataset *poDstDS,
2390 : int bStrict, CSLConstList papszOptions,
2391 : GDALProgressFunc pfnProgress,
2392 : void *pProgressData);
2393 :
2394 : CPLErr QuietDeleteForCreateCopy(const char *pszFilename,
2395 : GDALDataset *poSrcDS);
2396 :
2397 : //! @endcond
2398 : static CPLErr QuietDelete(const char *pszName,
2399 : CSLConstList papszAllowedDrivers = nullptr);
2400 :
2401 : //! @cond Doxygen_Suppress
2402 : static CPLErr DefaultRename(const char *pszNewName, const char *pszOldName);
2403 : static CPLErr DefaultCopyFiles(const char *pszNewName,
2404 : const char *pszOldName);
2405 : static void DefaultCopyMetadata(GDALDataset *poSrcDS, GDALDataset *poDstDS,
2406 : CSLConstList papszOptions,
2407 : CSLConstList papszExcludedDomains);
2408 :
2409 : //! @endcond
2410 :
2411 : /** Convert a GDALDriver* to a GDALDriverH.
2412 : * @since GDAL 2.3
2413 : */
2414 47 : static inline GDALDriverH ToHandle(GDALDriver *poDriver)
2415 : {
2416 47 : return static_cast<GDALDriverH>(poDriver);
2417 : }
2418 :
2419 : /** Convert a GDALDriverH to a GDALDriver*.
2420 : * @since GDAL 2.3
2421 : */
2422 3531682 : static inline GDALDriver *FromHandle(GDALDriverH hDriver)
2423 : {
2424 3531682 : return static_cast<GDALDriver *>(hDriver);
2425 : }
2426 :
2427 : private:
2428 : CPL_DISALLOW_COPY_ASSIGN(GDALDriver)
2429 : };
2430 :
2431 : /************************************************************************/
2432 : /* GDALPluginDriverProxy */
2433 : /************************************************************************/
2434 :
2435 : // clang-format off
2436 : /** Proxy for a plugin driver.
2437 : *
2438 : * Such proxy must be registered with
2439 : * GDALDriverManager::DeclareDeferredPluginDriver().
2440 : *
2441 : * If the real driver defines any of the following metadata items, the
2442 : * proxy driver should also define them with the same value:
2443 : * <ul>
2444 : * <li>GDAL_DMD_LONGNAME</li>
2445 : * <li>GDAL_DMD_EXTENSIONS</li>
2446 : * <li>GDAL_DMD_EXTENSION</li>
2447 : * <li>GDAL_DMD_OPENOPTIONLIST</li>
2448 : * <li>GDAL_DMD_SUBDATASETS</li>
2449 : * <li>GDAL_DMD_CONNECTION_PREFIX</li>
2450 : * <li>GDAL_DCAP_RASTER</li>
2451 : * <li>GDAL_DCAP_MULTIDIM_RASTER</li>
2452 : * <li>GDAL_DCAP_VECTOR</li>
2453 : * <li>GDAL_DCAP_GNM</li>
2454 : * <li>GDAL_DCAP_MULTIPLE_VECTOR_LAYERS</li>
2455 : * <li>GDAL_DCAP_NONSPATIAL</li>
2456 : * <li>GDAL_DCAP_VECTOR_TRANSLATE_FROM</li>
2457 : * </ul>
2458 : *
2459 : * The pfnIdentify and pfnGetSubdatasetInfoFunc callbacks, if they are
2460 : * defined in the real driver, should also be set on the proxy driver.
2461 : *
2462 : * Furthermore, the following metadata items must be defined if the real
2463 : * driver sets the corresponding callback:
2464 : * <ul>
2465 : * <li>GDAL_DCAP_OPEN: must be set to YES if the real driver defines pfnOpen</li>
2466 : * <li>GDAL_DCAP_CREATE: must be set to YES if the real driver defines pfnCreate</li>
2467 : * <li>GDAL_DCAP_CREATE_MULTIDIMENSIONAL: must be set to YES if the real driver defines pfnCreateMultiDimensional</li>
2468 : * <li>GDAL_DCAP_CREATECOPY: must be set to YES if the real driver defines pfnCreateCopy</li>
2469 : * </ul>
2470 : *
2471 : * @since 3.9
2472 : */
2473 : // clang-format on
2474 :
2475 : class GDALPluginDriverProxy : public GDALDriver
2476 : {
2477 : const std::string m_osPluginFileName;
2478 : std::string m_osPluginFullPath{};
2479 : std::unique_ptr<GDALDriver> m_poRealDriver{};
2480 : std::set<std::string> m_oSetMetadataItems{};
2481 :
2482 : GDALDriver *GetRealDriver();
2483 :
2484 : CPL_DISALLOW_COPY_ASSIGN(GDALPluginDriverProxy)
2485 :
2486 : protected:
2487 : friend class GDALDriverManager;
2488 :
2489 : //! @cond Doxygen_Suppress
2490 60060 : void SetPluginFullPath(const std::string &osFullPath)
2491 : {
2492 60060 : m_osPluginFullPath = osFullPath;
2493 60060 : }
2494 :
2495 : //! @endcond
2496 :
2497 : public:
2498 : explicit GDALPluginDriverProxy(const std::string &osPluginFileName);
2499 :
2500 : /** Return the plugin file name (not a full path) */
2501 60060 : const std::string &GetPluginFileName() const
2502 : {
2503 60060 : return m_osPluginFileName;
2504 : }
2505 :
2506 : //! @cond Doxygen_Suppress
2507 : OpenCallback GetOpenCallback() override;
2508 :
2509 : CreateCallback GetCreateCallback() override;
2510 :
2511 : CreateMultiDimensionalCallback GetCreateMultiDimensionalCallback() override;
2512 :
2513 : CreateCopyCallback GetCreateCopyCallback() override;
2514 :
2515 : DeleteCallback GetDeleteCallback() override;
2516 :
2517 : RenameCallback GetRenameCallback() override;
2518 :
2519 : CopyFilesCallback GetCopyFilesCallback() override;
2520 : //! @endcond
2521 :
2522 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
2523 : const char *pszDomain = "") override;
2524 :
2525 : char **GetMetadata(const char *pszDomain) override;
2526 :
2527 : const char *GetMetadataItem(const char *pszName,
2528 : const char *pszDomain = "") override;
2529 : };
2530 :
2531 : /* ******************************************************************** */
2532 : /* GDALDriverManager */
2533 : /* ******************************************************************** */
2534 :
2535 : /**
2536 : * Class for managing the registration of file format drivers.
2537 : *
2538 : * Use GetGDALDriverManager() to fetch the global singleton instance of
2539 : * this class.
2540 : */
2541 :
2542 : class CPL_DLL GDALDriverManager : public GDALMajorObject
2543 : {
2544 : int nDrivers = 0;
2545 : GDALDriver **papoDrivers = nullptr;
2546 : std::map<CPLString, GDALDriver *> oMapNameToDrivers{};
2547 : std::string m_osPluginPath{};
2548 : std::string m_osDriversIniPath{};
2549 : mutable std::string m_osLastTriedDirectory{};
2550 : std::set<std::string> m_oSetPluginFileNames{};
2551 : bool m_bInDeferredDriverLoading = false;
2552 : std::map<std::string, std::unique_ptr<GDALDriver>> m_oMapRealDrivers{};
2553 : std::vector<std::unique_ptr<GDALDriver>> m_aoHiddenDrivers{};
2554 :
2555 17505400 : GDALDriver *GetDriver_unlocked(int iDriver)
2556 : {
2557 17505400 : return (iDriver >= 0 && iDriver < nDrivers) ? papoDrivers[iDriver]
2558 17505400 : : nullptr;
2559 : }
2560 :
2561 756375 : GDALDriver *GetDriverByName_unlocked(const char *pszName) const
2562 : {
2563 756375 : auto oIter = oMapNameToDrivers.find(CPLString(pszName).toupper());
2564 756375 : return oIter == oMapNameToDrivers.end() ? nullptr : oIter->second;
2565 : }
2566 :
2567 : static void CleanupPythonDrivers();
2568 :
2569 : std::string GetPluginFullPath(const char *pszFilename) const;
2570 :
2571 : int RegisterDriver(GDALDriver *, bool bHidden);
2572 :
2573 : CPL_DISALLOW_COPY_ASSIGN(GDALDriverManager)
2574 :
2575 : protected:
2576 : friend class GDALPluginDriverProxy;
2577 : friend GDALDatasetH CPL_STDCALL
2578 : GDALOpenEx(const char *pszFilename, unsigned int nOpenFlags,
2579 : const char *const *papszAllowedDrivers,
2580 : const char *const *papszOpenOptions,
2581 : const char *const *papszSiblingFiles);
2582 :
2583 : //! @cond Doxygen_Suppress
2584 : static char **GetSearchPaths(const char *pszGDAL_DRIVER_PATH);
2585 : //! @endcond
2586 :
2587 : public:
2588 : GDALDriverManager();
2589 : ~GDALDriverManager();
2590 :
2591 : int GetDriverCount(void) const;
2592 : GDALDriver *GetDriver(int);
2593 : GDALDriver *GetDriverByName(const char *);
2594 :
2595 : int RegisterDriver(GDALDriver *);
2596 : void DeregisterDriver(GDALDriver *);
2597 :
2598 : // AutoLoadDrivers is a no-op if compiled with GDAL_NO_AUTOLOAD defined.
2599 : void AutoLoadDrivers();
2600 : void AutoSkipDrivers();
2601 : void ReorderDrivers();
2602 : static CPLErr LoadPlugin(const char *name);
2603 :
2604 : static void AutoLoadPythonDrivers();
2605 :
2606 : void DeclareDeferredPluginDriver(GDALPluginDriverProxy *poProxyDriver);
2607 :
2608 : //! @cond Doxygen_Suppress
2609 : int GetDriverCount(bool bIncludeHidden) const;
2610 : GDALDriver *GetDriver(int iDriver, bool bIncludeHidden);
2611 : bool IsKnownDriver(const char *pszDriverName) const;
2612 : //! @endcond
2613 : };
2614 :
2615 : CPL_C_START
2616 : GDALDriverManager CPL_DLL *GetGDALDriverManager(void);
2617 : CPL_C_END
2618 :
2619 : /* ******************************************************************** */
2620 : /* GDALAsyncReader */
2621 : /* ******************************************************************** */
2622 :
2623 : /**
2624 : * Class used as a session object for asynchronous requests. They are
2625 : * created with GDALDataset::BeginAsyncReader(), and destroyed with
2626 : * GDALDataset::EndAsyncReader().
2627 : */
2628 1 : class CPL_DLL GDALAsyncReader
2629 : {
2630 :
2631 : CPL_DISALLOW_COPY_ASSIGN(GDALAsyncReader)
2632 :
2633 : protected:
2634 : //! @cond Doxygen_Suppress
2635 : GDALDataset *poDS;
2636 : int nXOff;
2637 : int nYOff;
2638 : int nXSize;
2639 : int nYSize;
2640 : void *pBuf;
2641 : int nBufXSize;
2642 : int nBufYSize;
2643 : GDALDataType eBufType;
2644 : int nBandCount;
2645 : int *panBandMap;
2646 : int nPixelSpace;
2647 : int nLineSpace;
2648 : int nBandSpace;
2649 : //! @endcond
2650 :
2651 : public:
2652 : GDALAsyncReader();
2653 : virtual ~GDALAsyncReader();
2654 :
2655 : /** Return dataset.
2656 : * @return dataset
2657 : */
2658 : GDALDataset *GetGDALDataset()
2659 : {
2660 : return poDS;
2661 : }
2662 :
2663 : /** Return x offset.
2664 : * @return x offset.
2665 : */
2666 : int GetXOffset() const
2667 : {
2668 : return nXOff;
2669 : }
2670 :
2671 : /** Return y offset.
2672 : * @return y offset.
2673 : */
2674 : int GetYOffset() const
2675 : {
2676 : return nYOff;
2677 : }
2678 :
2679 : /** Return width.
2680 : * @return width
2681 : */
2682 : int GetXSize() const
2683 : {
2684 : return nXSize;
2685 : }
2686 :
2687 : /** Return height.
2688 : * @return height
2689 : */
2690 : int GetYSize() const
2691 : {
2692 : return nYSize;
2693 : }
2694 :
2695 : /** Return buffer.
2696 : * @return buffer
2697 : */
2698 : void *GetBuffer()
2699 : {
2700 : return pBuf;
2701 : }
2702 :
2703 : /** Return buffer width.
2704 : * @return buffer width.
2705 : */
2706 : int GetBufferXSize() const
2707 : {
2708 : return nBufXSize;
2709 : }
2710 :
2711 : /** Return buffer height.
2712 : * @return buffer height.
2713 : */
2714 : int GetBufferYSize() const
2715 : {
2716 : return nBufYSize;
2717 : }
2718 :
2719 : /** Return buffer data type.
2720 : * @return buffer data type.
2721 : */
2722 : GDALDataType GetBufferType() const
2723 : {
2724 : return eBufType;
2725 : }
2726 :
2727 : /** Return band count.
2728 : * @return band count
2729 : */
2730 : int GetBandCount() const
2731 : {
2732 : return nBandCount;
2733 : }
2734 :
2735 : /** Return band map.
2736 : * @return band map.
2737 : */
2738 : int *GetBandMap()
2739 : {
2740 : return panBandMap;
2741 : }
2742 :
2743 : /** Return pixel spacing.
2744 : * @return pixel spacing.
2745 : */
2746 : int GetPixelSpace() const
2747 : {
2748 : return nPixelSpace;
2749 : }
2750 :
2751 : /** Return line spacing.
2752 : * @return line spacing.
2753 : */
2754 : int GetLineSpace() const
2755 : {
2756 : return nLineSpace;
2757 : }
2758 :
2759 : /** Return band spacing.
2760 : * @return band spacing.
2761 : */
2762 : int GetBandSpace() const
2763 : {
2764 : return nBandSpace;
2765 : }
2766 :
2767 : virtual GDALAsyncStatusType
2768 : GetNextUpdatedRegion(double dfTimeout, int *pnBufXOff, int *pnBufYOff,
2769 : int *pnBufXSize, int *pnBufYSize) = 0;
2770 : virtual int LockBuffer(double dfTimeout = -1.0);
2771 : virtual void UnlockBuffer();
2772 : };
2773 :
2774 : /* ******************************************************************** */
2775 : /* Multidimensional array API */
2776 : /* ******************************************************************** */
2777 :
2778 : class GDALMDArray;
2779 : class GDALAttribute;
2780 : class GDALDimension;
2781 : class GDALEDTComponent;
2782 :
2783 : /* ******************************************************************** */
2784 : /* GDALExtendedDataType */
2785 : /* ******************************************************************** */
2786 :
2787 : /**
2788 : * Class used to represent potentially complex data types.
2789 : * Several classes of data types are supported: numeric (based on GDALDataType),
2790 : * compound or string.
2791 : *
2792 : * @since GDAL 3.1
2793 : */
2794 60622 : class CPL_DLL GDALExtendedDataType
2795 : {
2796 : public:
2797 : ~GDALExtendedDataType();
2798 :
2799 : GDALExtendedDataType(const GDALExtendedDataType &);
2800 :
2801 : GDALExtendedDataType &operator=(const GDALExtendedDataType &);
2802 : GDALExtendedDataType &operator=(GDALExtendedDataType &&);
2803 :
2804 : static GDALExtendedDataType Create(GDALDataType eType);
2805 : static GDALExtendedDataType
2806 : Create(const std::string &osName, size_t nTotalSize,
2807 : std::vector<std::unique_ptr<GDALEDTComponent>> &&components);
2808 : static GDALExtendedDataType
2809 : CreateString(size_t nMaxStringLength = 0,
2810 : GDALExtendedDataTypeSubType eSubType = GEDTST_NONE);
2811 :
2812 : bool operator==(const GDALExtendedDataType &) const;
2813 :
2814 : /** Non-equality operator */
2815 963 : bool operator!=(const GDALExtendedDataType &other) const
2816 : {
2817 963 : return !(operator==(other));
2818 : }
2819 :
2820 : /** Return type name.
2821 : *
2822 : * This is the same as the C function GDALExtendedDataTypeGetName()
2823 : */
2824 18 : const std::string &GetName() const
2825 : {
2826 18 : return m_osName;
2827 : }
2828 :
2829 : /** Return type class.
2830 : *
2831 : * This is the same as the C function GDALExtendedDataTypeGetClass()
2832 : */
2833 296477 : GDALExtendedDataTypeClass GetClass() const
2834 : {
2835 296477 : return m_eClass;
2836 : }
2837 :
2838 : /** Return numeric data type (only valid when GetClass() == GEDTC_NUMERIC)
2839 : *
2840 : * This is the same as the C function
2841 : * GDALExtendedDataTypeGetNumericDataType()
2842 : */
2843 1954165 : GDALDataType GetNumericDataType() const
2844 : {
2845 1954165 : return m_eNumericDT;
2846 : }
2847 :
2848 : /** Return subtype.
2849 : *
2850 : * This is the same as the C function GDALExtendedDataTypeGetSubType()
2851 : *
2852 : * @since 3.4
2853 : */
2854 311 : GDALExtendedDataTypeSubType GetSubType() const
2855 : {
2856 311 : return m_eSubType;
2857 : }
2858 :
2859 : /** Return the components of the data type (only valid when GetClass() ==
2860 : * GEDTC_COMPOUND)
2861 : *
2862 : * This is the same as the C function GDALExtendedDataTypeGetComponents()
2863 : */
2864 904 : const std::vector<std::unique_ptr<GDALEDTComponent>> &GetComponents() const
2865 : {
2866 904 : return m_aoComponents;
2867 : }
2868 :
2869 : /** Return data type size in bytes.
2870 : *
2871 : * For a string, this will be size of a char* pointer.
2872 : *
2873 : * This is the same as the C function GDALExtendedDataTypeGetSize()
2874 : */
2875 50214 : size_t GetSize() const
2876 : {
2877 50214 : return m_nSize;
2878 : }
2879 :
2880 : /** Return the maximum length of a string in bytes.
2881 : *
2882 : * 0 indicates unknown/unlimited string.
2883 : */
2884 21 : size_t GetMaxStringLength() const
2885 : {
2886 21 : return m_nMaxStringLength;
2887 : }
2888 :
2889 : bool CanConvertTo(const GDALExtendedDataType &other) const;
2890 :
2891 : bool NeedsFreeDynamicMemory() const;
2892 :
2893 : void FreeDynamicMemory(void *pBuffer) const;
2894 :
2895 : static bool CopyValue(const void *pSrc, const GDALExtendedDataType &srcType,
2896 : void *pDst, const GDALExtendedDataType &dstType);
2897 :
2898 : static bool CopyValues(const void *pSrc,
2899 : const GDALExtendedDataType &srcType,
2900 : GPtrDiff_t nSrcStrideInElts, void *pDst,
2901 : const GDALExtendedDataType &dstType,
2902 : GPtrDiff_t nDstStrideInElts, size_t nValues);
2903 :
2904 : private:
2905 : GDALExtendedDataType(size_t nMaxStringLength,
2906 : GDALExtendedDataTypeSubType eSubType);
2907 : explicit GDALExtendedDataType(GDALDataType eType);
2908 : GDALExtendedDataType(
2909 : const std::string &osName, size_t nTotalSize,
2910 : std::vector<std::unique_ptr<GDALEDTComponent>> &&components);
2911 :
2912 : std::string m_osName{};
2913 : GDALExtendedDataTypeClass m_eClass = GEDTC_NUMERIC;
2914 : GDALExtendedDataTypeSubType m_eSubType = GEDTST_NONE;
2915 : GDALDataType m_eNumericDT = GDT_Unknown;
2916 : std::vector<std::unique_ptr<GDALEDTComponent>> m_aoComponents{};
2917 : size_t m_nSize = 0;
2918 : size_t m_nMaxStringLength = 0;
2919 : };
2920 :
2921 : /* ******************************************************************** */
2922 : /* GDALEDTComponent */
2923 : /* ******************************************************************** */
2924 :
2925 : /**
2926 : * Class for a component of a compound extended data type.
2927 : *
2928 : * @since GDAL 3.1
2929 : */
2930 3344 : class CPL_DLL GDALEDTComponent
2931 : {
2932 : public:
2933 : ~GDALEDTComponent();
2934 : GDALEDTComponent(const std::string &name, size_t offset,
2935 : const GDALExtendedDataType &type);
2936 : GDALEDTComponent(const GDALEDTComponent &);
2937 :
2938 : bool operator==(const GDALEDTComponent &) const;
2939 :
2940 : /** Return the name.
2941 : *
2942 : * This is the same as the C function GDALEDTComponentGetName().
2943 : */
2944 2492 : const std::string &GetName() const
2945 : {
2946 2492 : return m_osName;
2947 : }
2948 :
2949 : /** Return the offset (in bytes) of the component in the compound data type.
2950 : *
2951 : * This is the same as the C function GDALEDTComponentGetOffset().
2952 : */
2953 6707 : size_t GetOffset() const
2954 : {
2955 6707 : return m_nOffset;
2956 : }
2957 :
2958 : /** Return the data type of the component.
2959 : *
2960 : * This is the same as the C function GDALEDTComponentGetType().
2961 : */
2962 6446 : const GDALExtendedDataType &GetType() const
2963 : {
2964 6446 : return m_oType;
2965 : }
2966 :
2967 : private:
2968 : std::string m_osName;
2969 : size_t m_nOffset;
2970 : GDALExtendedDataType m_oType;
2971 : };
2972 :
2973 : /* ******************************************************************** */
2974 : /* GDALIHasAttribute */
2975 : /* ******************************************************************** */
2976 :
2977 : /**
2978 : * Interface used to get a single GDALAttribute or a set of GDALAttribute
2979 : *
2980 : * @since GDAL 3.1
2981 : */
2982 12921 : class CPL_DLL GDALIHasAttribute
2983 : {
2984 : protected:
2985 : std::shared_ptr<GDALAttribute>
2986 : GetAttributeFromAttributes(const std::string &osName) const;
2987 :
2988 : public:
2989 : virtual ~GDALIHasAttribute();
2990 :
2991 : virtual std::shared_ptr<GDALAttribute>
2992 : GetAttribute(const std::string &osName) const;
2993 :
2994 : virtual std::vector<std::shared_ptr<GDALAttribute>>
2995 : GetAttributes(CSLConstList papszOptions = nullptr) const;
2996 :
2997 : virtual std::shared_ptr<GDALAttribute>
2998 : CreateAttribute(const std::string &osName,
2999 : const std::vector<GUInt64> &anDimensions,
3000 : const GDALExtendedDataType &oDataType,
3001 : CSLConstList papszOptions = nullptr);
3002 :
3003 : virtual bool DeleteAttribute(const std::string &osName,
3004 : CSLConstList papszOptions = nullptr);
3005 : };
3006 :
3007 : /* ******************************************************************** */
3008 : /* GDALGroup */
3009 : /* ******************************************************************** */
3010 :
3011 : /* clang-format off */
3012 : /**
3013 : * Class modeling a named container of GDALAttribute, GDALMDArray, OGRLayer or
3014 : * other GDALGroup. Hence GDALGroup can describe a hierarchy of objects.
3015 : *
3016 : * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_group">HDF5 group
3017 : * concept</a>
3018 : *
3019 : * @since GDAL 3.1
3020 : */
3021 : /* clang-format on */
3022 :
3023 6676 : class CPL_DLL GDALGroup : public GDALIHasAttribute
3024 : {
3025 : protected:
3026 : //! @cond Doxygen_Suppress
3027 : std::string m_osName{};
3028 :
3029 : // This is actually a path of the form "/parent_path/{m_osName}"
3030 : std::string m_osFullName{};
3031 :
3032 : // Used for example by GDALSubsetGroup to distinguish a derived group
3033 : //from its original, without altering its name
3034 : const std::string m_osContext{};
3035 :
3036 : std::weak_ptr<GDALGroup> m_pSelf{};
3037 :
3038 : //! Can be set to false by the owing group, when deleting this object
3039 : bool m_bValid = true;
3040 :
3041 : GDALGroup(const std::string &osParentName, const std::string &osName,
3042 : const std::string &osContext = std::string());
3043 :
3044 : const GDALGroup *
3045 : GetInnerMostGroup(const std::string &osPathOrArrayOrDim,
3046 : std::shared_ptr<GDALGroup> &curGroupHolder,
3047 : std::string &osLastPart) const;
3048 :
3049 : void BaseRename(const std::string &osNewName);
3050 :
3051 : bool CheckValidAndErrorOutIfNot() const;
3052 :
3053 5815 : void SetSelf(const std::shared_ptr<GDALGroup> &self)
3054 : {
3055 5815 : m_pSelf = self;
3056 5815 : }
3057 :
3058 0 : virtual void NotifyChildrenOfRenaming()
3059 : {
3060 0 : }
3061 :
3062 0 : virtual void NotifyChildrenOfDeletion()
3063 : {
3064 0 : }
3065 :
3066 : //! @endcond
3067 :
3068 : public:
3069 : virtual ~GDALGroup();
3070 :
3071 : /** Return the name of the group.
3072 : *
3073 : * This is the same as the C function GDALGroupGetName().
3074 : */
3075 1017 : const std::string &GetName() const
3076 : {
3077 1017 : return m_osName;
3078 : }
3079 :
3080 : /** Return the full name of the group.
3081 : *
3082 : * This is the same as the C function GDALGroupGetFullName().
3083 : */
3084 23418 : const std::string &GetFullName() const
3085 : {
3086 23418 : return m_osFullName;
3087 : }
3088 :
3089 : virtual std::vector<std::string>
3090 : GetMDArrayNames(CSLConstList papszOptions = nullptr) const;
3091 : virtual std::shared_ptr<GDALMDArray>
3092 : OpenMDArray(const std::string &osName,
3093 : CSLConstList papszOptions = nullptr) const;
3094 :
3095 : virtual std::vector<std::string>
3096 : GetGroupNames(CSLConstList papszOptions = nullptr) const;
3097 : virtual std::shared_ptr<GDALGroup>
3098 : OpenGroup(const std::string &osName,
3099 : CSLConstList papszOptions = nullptr) const;
3100 :
3101 : virtual std::vector<std::string>
3102 : GetVectorLayerNames(CSLConstList papszOptions = nullptr) const;
3103 : virtual OGRLayer *
3104 : OpenVectorLayer(const std::string &osName,
3105 : CSLConstList papszOptions = nullptr) const;
3106 :
3107 : virtual std::vector<std::shared_ptr<GDALDimension>>
3108 : GetDimensions(CSLConstList papszOptions = nullptr) const;
3109 :
3110 : virtual std::shared_ptr<GDALGroup>
3111 : CreateGroup(const std::string &osName, CSLConstList papszOptions = nullptr);
3112 :
3113 : virtual bool DeleteGroup(const std::string &osName,
3114 : CSLConstList papszOptions = nullptr);
3115 :
3116 : virtual std::shared_ptr<GDALDimension>
3117 : CreateDimension(const std::string &osName, const std::string &osType,
3118 : const std::string &osDirection, GUInt64 nSize,
3119 : CSLConstList papszOptions = nullptr);
3120 :
3121 : virtual std::shared_ptr<GDALMDArray> CreateMDArray(
3122 : const std::string &osName,
3123 : const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
3124 : const GDALExtendedDataType &oDataType,
3125 : CSLConstList papszOptions = nullptr);
3126 :
3127 : virtual bool DeleteMDArray(const std::string &osName,
3128 : CSLConstList papszOptions = nullptr);
3129 :
3130 : GUInt64 GetTotalCopyCost() const;
3131 :
3132 : virtual bool CopyFrom(const std::shared_ptr<GDALGroup> &poDstRootGroup,
3133 : GDALDataset *poSrcDS,
3134 : const std::shared_ptr<GDALGroup> &poSrcGroup,
3135 : bool bStrict, GUInt64 &nCurCost,
3136 : const GUInt64 nTotalCost,
3137 : GDALProgressFunc pfnProgress, void *pProgressData,
3138 : CSLConstList papszOptions = nullptr);
3139 :
3140 : virtual CSLConstList GetStructuralInfo() const;
3141 :
3142 : std::shared_ptr<GDALMDArray>
3143 : OpenMDArrayFromFullname(const std::string &osFullName,
3144 : CSLConstList papszOptions = nullptr) const;
3145 :
3146 : std::shared_ptr<GDALMDArray>
3147 : ResolveMDArray(const std::string &osName, const std::string &osStartingPath,
3148 : CSLConstList papszOptions = nullptr) const;
3149 :
3150 : std::shared_ptr<GDALGroup>
3151 : OpenGroupFromFullname(const std::string &osFullName,
3152 : CSLConstList papszOptions = nullptr) const;
3153 :
3154 : std::shared_ptr<GDALDimension>
3155 : OpenDimensionFromFullname(const std::string &osFullName) const;
3156 :
3157 : virtual void ClearStatistics();
3158 :
3159 : virtual bool Rename(const std::string &osNewName);
3160 :
3161 : std::shared_ptr<GDALGroup>
3162 : SubsetDimensionFromSelection(const std::string &osSelection) const;
3163 :
3164 : //! @cond Doxygen_Suppress
3165 : virtual void ParentRenamed(const std::string &osNewParentFullName);
3166 :
3167 : virtual void Deleted();
3168 :
3169 : virtual void ParentDeleted();
3170 :
3171 23 : const std::string &GetContext() const
3172 : {
3173 23 : return m_osContext;
3174 : }
3175 :
3176 : //! @endcond
3177 :
3178 : //! @cond Doxygen_Suppress
3179 : static constexpr GUInt64 COPY_COST = 1000;
3180 : //! @endcond
3181 : };
3182 :
3183 : /* ******************************************************************** */
3184 : /* GDALAbstractMDArray */
3185 : /* ******************************************************************** */
3186 :
3187 : /**
3188 : * Abstract class, implemented by GDALAttribute and GDALMDArray.
3189 : *
3190 : * @since GDAL 3.1
3191 : */
3192 20250 : class CPL_DLL GDALAbstractMDArray
3193 : {
3194 : protected:
3195 : //! @cond Doxygen_Suppress
3196 : std::string m_osName{};
3197 :
3198 : // This is actually a path of the form "/parent_path/{m_osName}"
3199 : std::string m_osFullName{};
3200 : std::weak_ptr<GDALAbstractMDArray> m_pSelf{};
3201 :
3202 : //! Can be set to false by the owing object, when deleting this object
3203 : bool m_bValid = true;
3204 :
3205 : GDALAbstractMDArray(const std::string &osParentName,
3206 : const std::string &osName);
3207 :
3208 7945 : void SetSelf(const std::shared_ptr<GDALAbstractMDArray> &self)
3209 : {
3210 7945 : m_pSelf = self;
3211 7945 : }
3212 :
3213 : bool CheckValidAndErrorOutIfNot() const;
3214 :
3215 : bool CheckReadWriteParams(const GUInt64 *arrayStartIdx, const size_t *count,
3216 : const GInt64 *&arrayStep,
3217 : const GPtrDiff_t *&bufferStride,
3218 : const GDALExtendedDataType &bufferDataType,
3219 : const void *buffer,
3220 : const void *buffer_alloc_start,
3221 : size_t buffer_alloc_size,
3222 : std::vector<GInt64> &tmp_arrayStep,
3223 : std::vector<GPtrDiff_t> &tmp_bufferStride) const;
3224 :
3225 : virtual bool
3226 : IRead(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
3227 : const size_t *count, // array of size GetDimensionCount()
3228 : const GInt64 *arrayStep, // step in elements
3229 : const GPtrDiff_t *bufferStride, // stride in elements
3230 : const GDALExtendedDataType &bufferDataType,
3231 : void *pDstBuffer) const = 0;
3232 :
3233 : virtual bool
3234 : IWrite(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
3235 : const size_t *count, // array of size GetDimensionCount()
3236 : const GInt64 *arrayStep, // step in elements
3237 : const GPtrDiff_t *bufferStride, // stride in elements
3238 : const GDALExtendedDataType &bufferDataType, const void *pSrcBuffer);
3239 :
3240 : void BaseRename(const std::string &osNewName);
3241 :
3242 47 : virtual void NotifyChildrenOfRenaming()
3243 : {
3244 47 : }
3245 :
3246 42 : virtual void NotifyChildrenOfDeletion()
3247 : {
3248 42 : }
3249 :
3250 : //! @endcond
3251 :
3252 : public:
3253 : virtual ~GDALAbstractMDArray();
3254 :
3255 : /** Return the name of an array or attribute.
3256 : *
3257 : * This is the same as the C function GDALMDArrayGetName() or
3258 : * GDALAttributeGetName().
3259 : */
3260 18262 : const std::string &GetName() const
3261 : {
3262 18262 : return m_osName;
3263 : }
3264 :
3265 : /** Return the name of an array or attribute.
3266 : *
3267 : * This is the same as the C function GDALMDArrayGetFullName() or
3268 : * GDALAttributeGetFullName().
3269 : */
3270 12241 : const std::string &GetFullName() const
3271 : {
3272 12241 : return m_osFullName;
3273 : }
3274 :
3275 : GUInt64 GetTotalElementsCount() const;
3276 :
3277 : virtual size_t GetDimensionCount() const;
3278 :
3279 : virtual const std::vector<std::shared_ptr<GDALDimension>> &
3280 : GetDimensions() const = 0;
3281 :
3282 : virtual const GDALExtendedDataType &GetDataType() const = 0;
3283 :
3284 : virtual std::vector<GUInt64> GetBlockSize() const;
3285 :
3286 : virtual std::vector<size_t>
3287 : GetProcessingChunkSize(size_t nMaxChunkMemory) const;
3288 :
3289 : /* clang-format off */
3290 : /** Type of pfnFunc argument of ProcessPerChunk().
3291 : * @param array Array on which ProcessPerChunk was called.
3292 : * @param chunkArrayStartIdx Values representing the starting index to use
3293 : * in each dimension (in [0, aoDims[i].GetSize()-1] range)
3294 : * for the current chunk.
3295 : * Will be nullptr for a zero-dimensional array.
3296 : * @param chunkCount Values representing the number of values to use in
3297 : * each dimension for the current chunk.
3298 : * Will be nullptr for a zero-dimensional array.
3299 : * @param iCurChunk Number of current chunk being processed.
3300 : * In [1, nChunkCount] range.
3301 : * @param nChunkCount Total number of chunks to process.
3302 : * @param pUserData User data.
3303 : * @return return true in case of success.
3304 : */
3305 : typedef bool (*FuncProcessPerChunkType)(
3306 : GDALAbstractMDArray *array,
3307 : const GUInt64 *chunkArrayStartIdx,
3308 : const size_t *chunkCount,
3309 : GUInt64 iCurChunk,
3310 : GUInt64 nChunkCount,
3311 : void *pUserData);
3312 : /* clang-format on */
3313 :
3314 : virtual bool ProcessPerChunk(const GUInt64 *arrayStartIdx,
3315 : const GUInt64 *count, const size_t *chunkSize,
3316 : FuncProcessPerChunkType pfnFunc,
3317 : void *pUserData);
3318 :
3319 : virtual bool
3320 : Read(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
3321 : const size_t *count, // array of size GetDimensionCount()
3322 : const GInt64 *arrayStep, // step in elements
3323 : const GPtrDiff_t *bufferStride, // stride in elements
3324 : const GDALExtendedDataType &bufferDataType, void *pDstBuffer,
3325 : const void *pDstBufferAllocStart = nullptr,
3326 : size_t nDstBufferAllocSize = 0) const;
3327 :
3328 : bool
3329 : Write(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
3330 : const size_t *count, // array of size GetDimensionCount()
3331 : const GInt64 *arrayStep, // step in elements
3332 : const GPtrDiff_t *bufferStride, // stride in elements
3333 : const GDALExtendedDataType &bufferDataType, const void *pSrcBuffer,
3334 : const void *pSrcBufferAllocStart = nullptr,
3335 : size_t nSrcBufferAllocSize = 0);
3336 :
3337 : virtual bool Rename(const std::string &osNewName);
3338 :
3339 : //! @cond Doxygen_Suppress
3340 : virtual void Deleted();
3341 :
3342 : virtual void ParentDeleted();
3343 :
3344 : virtual void ParentRenamed(const std::string &osNewParentFullName);
3345 : //! @endcond
3346 : };
3347 :
3348 : /* ******************************************************************** */
3349 : /* GDALRawResult */
3350 : /* ******************************************************************** */
3351 :
3352 : /**
3353 : * Store the raw result of an attribute value, which might contain dynamically
3354 : * allocated structures (like pointer to strings).
3355 : *
3356 : * @since GDAL 3.1
3357 : */
3358 : class CPL_DLL GDALRawResult
3359 : {
3360 : private:
3361 : GDALExtendedDataType m_dt;
3362 : size_t m_nEltCount;
3363 : size_t m_nSize;
3364 : GByte *m_raw;
3365 :
3366 : void FreeMe();
3367 :
3368 : GDALRawResult(const GDALRawResult &) = delete;
3369 : GDALRawResult &operator=(const GDALRawResult &) = delete;
3370 :
3371 : protected:
3372 : friend class GDALAttribute;
3373 : //! @cond Doxygen_Suppress
3374 : GDALRawResult(GByte *raw, const GDALExtendedDataType &dt, size_t nEltCount);
3375 : //! @endcond
3376 :
3377 : public:
3378 : ~GDALRawResult();
3379 : GDALRawResult(GDALRawResult &&);
3380 : GDALRawResult &operator=(GDALRawResult &&);
3381 :
3382 : /** Return byte at specified index. */
3383 : const GByte &operator[](size_t idx) const
3384 : {
3385 : return m_raw[idx];
3386 : }
3387 :
3388 : /** Return pointer to the start of data. */
3389 337 : const GByte *data() const
3390 : {
3391 337 : return m_raw;
3392 : }
3393 :
3394 : /** Return the size in bytes of the raw result. */
3395 122 : size_t size() const
3396 : {
3397 122 : return m_nSize;
3398 : }
3399 :
3400 : //! @cond Doxygen_Suppress
3401 : GByte *StealData();
3402 : //! @endcond
3403 : };
3404 :
3405 : /* ******************************************************************** */
3406 : /* GDALAttribute */
3407 : /* ******************************************************************** */
3408 :
3409 : /* clang-format off */
3410 : /**
3411 : * Class modeling an attribute that has a name, a value and a type, and is
3412 : * typically used to describe a metadata item. The value can be (for the
3413 : * HDF5 format) in the general case a multidimensional array of "any" type
3414 : * (in most cases, this will be a single value of string or numeric type)
3415 : *
3416 : * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_attribute">HDF5
3417 : * attribute concept</a>
3418 : *
3419 : * @since GDAL 3.1
3420 : */
3421 : /* clang-format on */
3422 :
3423 : class CPL_DLL GDALAttribute : virtual public GDALAbstractMDArray
3424 : {
3425 : mutable std::string m_osCachedVal{};
3426 :
3427 : protected:
3428 : //! @cond Doxygen_Suppress
3429 : GDALAttribute(const std::string &osParentName, const std::string &osName);
3430 : //! @endcond
3431 :
3432 : public:
3433 : std::vector<GUInt64> GetDimensionsSize() const;
3434 :
3435 : GDALRawResult ReadAsRaw() const;
3436 : const char *ReadAsString() const;
3437 : int ReadAsInt() const;
3438 : int64_t ReadAsInt64() const;
3439 : double ReadAsDouble() const;
3440 : CPLStringList ReadAsStringArray() const;
3441 : std::vector<int> ReadAsIntArray() const;
3442 : std::vector<int64_t> ReadAsInt64Array() const;
3443 : std::vector<double> ReadAsDoubleArray() const;
3444 :
3445 : using GDALAbstractMDArray::Write;
3446 : bool Write(const void *pabyValue, size_t nLen);
3447 : bool Write(const char *);
3448 : bool WriteInt(int);
3449 : bool WriteInt64(int64_t);
3450 : bool Write(double);
3451 : bool Write(CSLConstList);
3452 : bool Write(const int *, size_t);
3453 : bool Write(const int64_t *, size_t);
3454 : bool Write(const double *, size_t);
3455 :
3456 : //! @cond Doxygen_Suppress
3457 : static constexpr GUInt64 COPY_COST = 100;
3458 : //! @endcond
3459 : };
3460 :
3461 : /************************************************************************/
3462 : /* GDALAttributeString */
3463 : /************************************************************************/
3464 :
3465 : //! @cond Doxygen_Suppress
3466 : class CPL_DLL GDALAttributeString final : public GDALAttribute
3467 : {
3468 : std::vector<std::shared_ptr<GDALDimension>> m_dims{};
3469 : GDALExtendedDataType m_dt = GDALExtendedDataType::CreateString();
3470 : std::string m_osValue;
3471 :
3472 : protected:
3473 : bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
3474 : const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
3475 : void *pDstBuffer) const override;
3476 :
3477 : public:
3478 : GDALAttributeString(const std::string &osParentName,
3479 : const std::string &osName, const std::string &osValue,
3480 : GDALExtendedDataTypeSubType eSubType = GEDTST_NONE);
3481 :
3482 : const std::vector<std::shared_ptr<GDALDimension>> &
3483 : GetDimensions() const override;
3484 :
3485 : const GDALExtendedDataType &GetDataType() const override;
3486 : };
3487 :
3488 : //! @endcond
3489 :
3490 : /************************************************************************/
3491 : /* GDALAttributeNumeric */
3492 : /************************************************************************/
3493 :
3494 : //! @cond Doxygen_Suppress
3495 : class CPL_DLL GDALAttributeNumeric final : public GDALAttribute
3496 : {
3497 : std::vector<std::shared_ptr<GDALDimension>> m_dims{};
3498 : GDALExtendedDataType m_dt;
3499 : int m_nValue = 0;
3500 : double m_dfValue = 0;
3501 : std::vector<GUInt32> m_anValuesUInt32{};
3502 :
3503 : protected:
3504 : bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
3505 : const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
3506 : void *pDstBuffer) const override;
3507 :
3508 : public:
3509 : GDALAttributeNumeric(const std::string &osParentName,
3510 : const std::string &osName, double dfValue);
3511 : GDALAttributeNumeric(const std::string &osParentName,
3512 : const std::string &osName, int nValue);
3513 : GDALAttributeNumeric(const std::string &osParentName,
3514 : const std::string &osName,
3515 : const std::vector<GUInt32> &anValues);
3516 :
3517 : const std::vector<std::shared_ptr<GDALDimension>> &
3518 : GetDimensions() const override;
3519 :
3520 : const GDALExtendedDataType &GetDataType() const override;
3521 : };
3522 :
3523 : //! @endcond
3524 :
3525 : /* ******************************************************************** */
3526 : /* GDALMDArray */
3527 : /* ******************************************************************** */
3528 :
3529 : /* clang-format off */
3530 : /**
3531 : * Class modeling a multi-dimensional array. It has a name, values organized
3532 : * as an array and a list of GDALAttribute.
3533 : *
3534 : * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_dataset">HDF5
3535 : * dataset concept</a>
3536 : *
3537 : * @since GDAL 3.1
3538 : */
3539 : /* clang-format on */
3540 :
3541 : class CPL_DLL GDALMDArray : virtual public GDALAbstractMDArray,
3542 : public GDALIHasAttribute
3543 : {
3544 : friend class GDALMDArrayResampled;
3545 : std::shared_ptr<GDALMDArray>
3546 : GetView(const std::vector<GUInt64> &indices) const;
3547 :
3548 : inline std::shared_ptr<GDALMDArray>
3549 19 : atInternal(const std::vector<GUInt64> &indices) const
3550 : {
3551 19 : return GetView(indices);
3552 : }
3553 :
3554 : template <typename... GUInt64VarArg>
3555 : // cppcheck-suppress functionStatic
3556 : inline std::shared_ptr<GDALMDArray>
3557 7 : atInternal(std::vector<GUInt64> &indices, GUInt64 idx,
3558 : GUInt64VarArg... tail) const
3559 : {
3560 7 : indices.push_back(idx);
3561 7 : return atInternal(indices, tail...);
3562 : }
3563 :
3564 : // Used for example by GDALSubsetGroup to distinguish a derived group
3565 : //from its original, without altering its name
3566 : const std::string m_osContext{};
3567 :
3568 : mutable bool m_bHasTriedCachedArray = false;
3569 : mutable std::shared_ptr<GDALMDArray> m_poCachedArray{};
3570 :
3571 : protected:
3572 : //! @cond Doxygen_Suppress
3573 : GDALMDArray(const std::string &osParentName, const std::string &osName,
3574 : const std::string &osContext = std::string());
3575 :
3576 : virtual bool IAdviseRead(const GUInt64 *arrayStartIdx, const size_t *count,
3577 : CSLConstList papszOptions) const;
3578 :
3579 1649 : virtual bool IsCacheable() const
3580 : {
3581 1649 : return true;
3582 : }
3583 :
3584 : virtual bool SetStatistics(bool bApproxStats, double dfMin, double dfMax,
3585 : double dfMean, double dfStdDev,
3586 : GUInt64 nValidCount, CSLConstList papszOptions);
3587 :
3588 : static std::string MassageName(const std::string &inputName);
3589 :
3590 : std::shared_ptr<GDALGroup>
3591 : GetCacheRootGroup(bool bCanCreate, std::string &osCacheFilenameOut) const;
3592 :
3593 : // Returns if bufferStride values express a transposed view of the array
3594 : bool IsTransposedRequest(const size_t *count,
3595 : const GPtrDiff_t *bufferStride) const;
3596 :
3597 : // Should only be called if IsTransposedRequest() returns true
3598 : bool ReadForTransposedRequest(const GUInt64 *arrayStartIdx,
3599 : const size_t *count, const GInt64 *arrayStep,
3600 : const GPtrDiff_t *bufferStride,
3601 : const GDALExtendedDataType &bufferDataType,
3602 : void *pDstBuffer) const;
3603 :
3604 : bool IsStepOneContiguousRowMajorOrderedSameDataType(
3605 : const size_t *count, const GInt64 *arrayStep,
3606 : const GPtrDiff_t *bufferStride,
3607 : const GDALExtendedDataType &bufferDataType) const;
3608 :
3609 : // Should only be called if IsStepOneContiguousRowMajorOrderedSameDataType()
3610 : // returns false
3611 : bool ReadUsingContiguousIRead(const GUInt64 *arrayStartIdx,
3612 : const size_t *count, const GInt64 *arrayStep,
3613 : const GPtrDiff_t *bufferStride,
3614 : const GDALExtendedDataType &bufferDataType,
3615 : void *pDstBuffer) const;
3616 :
3617 : static std::shared_ptr<GDALMDArray> CreateGLTOrthorectified(
3618 : const std::shared_ptr<GDALMDArray> &poParent,
3619 : const std::shared_ptr<GDALGroup> &poRootGroup,
3620 : const std::shared_ptr<GDALMDArray> &poGLTX,
3621 : const std::shared_ptr<GDALMDArray> &poGLTY, int nGLTIndexOffset,
3622 : const std::vector<double> &adfGeoTransform, CSLConstList papszOptions);
3623 :
3624 : //! @endcond
3625 :
3626 : public:
3627 : GUInt64 GetTotalCopyCost() const;
3628 :
3629 : virtual bool CopyFrom(GDALDataset *poSrcDS, const GDALMDArray *poSrcArray,
3630 : bool bStrict, GUInt64 &nCurCost,
3631 : const GUInt64 nTotalCost,
3632 : GDALProgressFunc pfnProgress, void *pProgressData);
3633 :
3634 : /** Return whether an array is writable. */
3635 : virtual bool IsWritable() const = 0;
3636 :
3637 : /** Return the filename that contains that array.
3638 : *
3639 : * This is used in particular for caching.
3640 : *
3641 : * Might be empty if the array is not linked to a file.
3642 : *
3643 : * @since GDAL 3.4
3644 : */
3645 : virtual const std::string &GetFilename() const = 0;
3646 :
3647 : virtual CSLConstList GetStructuralInfo() const;
3648 :
3649 : virtual const std::string &GetUnit() const;
3650 :
3651 : virtual bool SetUnit(const std::string &osUnit);
3652 :
3653 : virtual bool SetSpatialRef(const OGRSpatialReference *poSRS);
3654 :
3655 : virtual std::shared_ptr<OGRSpatialReference> GetSpatialRef() const;
3656 :
3657 : virtual const void *GetRawNoDataValue() const;
3658 :
3659 : double GetNoDataValueAsDouble(bool *pbHasNoData = nullptr) const;
3660 :
3661 : int64_t GetNoDataValueAsInt64(bool *pbHasNoData = nullptr) const;
3662 :
3663 : uint64_t GetNoDataValueAsUInt64(bool *pbHasNoData = nullptr) const;
3664 :
3665 : virtual bool SetRawNoDataValue(const void *pRawNoData);
3666 :
3667 : //! @cond Doxygen_Suppress
3668 2 : bool SetNoDataValue(int nNoData)
3669 : {
3670 2 : return SetNoDataValue(static_cast<int64_t>(nNoData));
3671 : }
3672 :
3673 : //! @endcond
3674 :
3675 : bool SetNoDataValue(double dfNoData);
3676 :
3677 : bool SetNoDataValue(int64_t nNoData);
3678 :
3679 : bool SetNoDataValue(uint64_t nNoData);
3680 :
3681 : virtual bool Resize(const std::vector<GUInt64> &anNewDimSizes,
3682 : CSLConstList papszOptions);
3683 :
3684 : virtual double GetOffset(bool *pbHasOffset = nullptr,
3685 : GDALDataType *peStorageType = nullptr) const;
3686 :
3687 : virtual double GetScale(bool *pbHasScale = nullptr,
3688 : GDALDataType *peStorageType = nullptr) const;
3689 :
3690 : virtual bool SetOffset(double dfOffset,
3691 : GDALDataType eStorageType = GDT_Unknown);
3692 :
3693 : virtual bool SetScale(double dfScale,
3694 : GDALDataType eStorageType = GDT_Unknown);
3695 :
3696 : std::shared_ptr<GDALMDArray> GetView(const std::string &viewExpr) const;
3697 :
3698 : std::shared_ptr<GDALMDArray> operator[](const std::string &fieldName) const;
3699 :
3700 : /** Return a view of the array using integer indexing.
3701 : *
3702 : * Equivalent of GetView("[indices_0,indices_1,.....,indices_last]")
3703 : *
3704 : * Example:
3705 : * \code
3706 : * ar->at(0,3,2)
3707 : * \endcode
3708 : */
3709 : // sphinx 4.1.0 / breathe 4.30.0 don't like typename...
3710 : //! @cond Doxygen_Suppress
3711 : template <typename... GUInt64VarArg>
3712 : //! @endcond
3713 : // cppcheck-suppress functionStatic
3714 19 : std::shared_ptr<GDALMDArray> at(GUInt64 idx, GUInt64VarArg... tail) const
3715 : {
3716 38 : std::vector<GUInt64> indices;
3717 19 : indices.push_back(idx);
3718 38 : return atInternal(indices, tail...);
3719 : }
3720 :
3721 : virtual std::shared_ptr<GDALMDArray>
3722 : Transpose(const std::vector<int> &anMapNewAxisToOldAxis) const;
3723 :
3724 : std::shared_ptr<GDALMDArray> GetUnscaled(
3725 : double dfOverriddenScale = cpl::NumericLimits<double>::quiet_NaN(),
3726 : double dfOverriddenOffset = cpl::NumericLimits<double>::quiet_NaN(),
3727 : double dfOverriddenDstNodata =
3728 : cpl::NumericLimits<double>::quiet_NaN()) const;
3729 :
3730 : virtual std::shared_ptr<GDALMDArray>
3731 : GetMask(CSLConstList papszOptions) const;
3732 :
3733 : virtual std::shared_ptr<GDALMDArray>
3734 : GetResampled(const std::vector<std::shared_ptr<GDALDimension>> &apoNewDims,
3735 : GDALRIOResampleAlg resampleAlg,
3736 : const OGRSpatialReference *poTargetSRS,
3737 : CSLConstList papszOptions) const;
3738 :
3739 : std::shared_ptr<GDALMDArray>
3740 : GetGridded(const std::string &osGridOptions,
3741 : const std::shared_ptr<GDALMDArray> &poXArray = nullptr,
3742 : const std::shared_ptr<GDALMDArray> &poYArray = nullptr,
3743 : CSLConstList papszOptions = nullptr) const;
3744 :
3745 : static std::vector<std::shared_ptr<GDALMDArray>>
3746 : GetMeshGrid(const std::vector<std::shared_ptr<GDALMDArray>> &apoArrays,
3747 : CSLConstList papszOptions = nullptr);
3748 :
3749 : virtual GDALDataset *
3750 : AsClassicDataset(size_t iXDim, size_t iYDim,
3751 : const std::shared_ptr<GDALGroup> &poRootGroup = nullptr,
3752 : CSLConstList papszOptions = nullptr) const;
3753 :
3754 : virtual CPLErr GetStatistics(bool bApproxOK, bool bForce, double *pdfMin,
3755 : double *pdfMax, double *pdfMean,
3756 : double *padfStdDev, GUInt64 *pnValidCount,
3757 : GDALProgressFunc pfnProgress,
3758 : void *pProgressData);
3759 :
3760 : virtual bool ComputeStatistics(bool bApproxOK, double *pdfMin,
3761 : double *pdfMax, double *pdfMean,
3762 : double *pdfStdDev, GUInt64 *pnValidCount,
3763 : GDALProgressFunc, void *pProgressData,
3764 : CSLConstList papszOptions);
3765 :
3766 : virtual void ClearStatistics();
3767 :
3768 : virtual std::vector<std::shared_ptr<GDALMDArray>>
3769 : GetCoordinateVariables() const;
3770 :
3771 : bool AdviseRead(const GUInt64 *arrayStartIdx, const size_t *count,
3772 : CSLConstList papszOptions = nullptr) const;
3773 :
3774 : bool IsRegularlySpaced(double &dfStart, double &dfIncrement) const;
3775 :
3776 : bool GuessGeoTransform(size_t nDimX, size_t nDimY, bool bPixelIsPoint,
3777 : double adfGeoTransform[6]) const;
3778 :
3779 : bool Cache(CSLConstList papszOptions = nullptr) const;
3780 :
3781 : bool
3782 : Read(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
3783 : const size_t *count, // array of size GetDimensionCount()
3784 : const GInt64 *arrayStep, // step in elements
3785 : const GPtrDiff_t *bufferStride, // stride in elements
3786 : const GDALExtendedDataType &bufferDataType, void *pDstBuffer,
3787 : const void *pDstBufferAllocStart = nullptr,
3788 : size_t nDstBufferAllocSize = 0) const override final;
3789 :
3790 : virtual std::shared_ptr<GDALGroup> GetRootGroup() const;
3791 :
3792 : //! @cond Doxygen_Suppress
3793 : static constexpr GUInt64 COPY_COST = 1000;
3794 :
3795 : bool CopyFromAllExceptValues(const GDALMDArray *poSrcArray, bool bStrict,
3796 : GUInt64 &nCurCost, const GUInt64 nTotalCost,
3797 : GDALProgressFunc pfnProgress,
3798 : void *pProgressData);
3799 :
3800 : struct Range
3801 : {
3802 : GUInt64 m_nStartIdx;
3803 : GInt64 m_nIncr;
3804 :
3805 1308 : explicit Range(GUInt64 nStartIdx = 0, GInt64 nIncr = 0)
3806 1308 : : m_nStartIdx(nStartIdx), m_nIncr(nIncr)
3807 : {
3808 1308 : }
3809 : };
3810 :
3811 : struct ViewSpec
3812 : {
3813 : std::string m_osFieldName{};
3814 :
3815 : // or
3816 :
3817 : std::vector<size_t>
3818 : m_mapDimIdxToParentDimIdx{}; // of size m_dims.size()
3819 : std::vector<Range>
3820 : m_parentRanges{}; // of size m_poParent->GetDimensionCount()
3821 : };
3822 :
3823 : virtual std::shared_ptr<GDALMDArray>
3824 : GetView(const std::string &viewExpr, bool bRenameDimensions,
3825 : std::vector<ViewSpec> &viewSpecs) const;
3826 :
3827 1033 : const std::string &GetContext() const
3828 : {
3829 1033 : return m_osContext;
3830 : }
3831 :
3832 : //! @endcond
3833 : };
3834 :
3835 : //! @cond Doxygen_Suppress
3836 : bool GDALMDRasterIOFromBand(GDALRasterBand *poBand, GDALRWFlag eRWFlag,
3837 : size_t iDimX, size_t iDimY,
3838 : const GUInt64 *arrayStartIdx, const size_t *count,
3839 : const GInt64 *arrayStep,
3840 : const GPtrDiff_t *bufferStride,
3841 : const GDALExtendedDataType &bufferDataType,
3842 : void *pBuffer);
3843 :
3844 : //! @endcond
3845 :
3846 : /************************************************************************/
3847 : /* GDALMDArrayRegularlySpaced */
3848 : /************************************************************************/
3849 :
3850 : //! @cond Doxygen_Suppress
3851 : class CPL_DLL GDALMDArrayRegularlySpaced : public GDALMDArray
3852 : {
3853 : double m_dfStart;
3854 : double m_dfIncrement;
3855 : double m_dfOffsetInIncrement;
3856 : GDALExtendedDataType m_dt = GDALExtendedDataType::Create(GDT_Float64);
3857 : std::vector<std::shared_ptr<GDALDimension>> m_dims;
3858 : std::vector<std::shared_ptr<GDALAttribute>> m_attributes{};
3859 : std::string m_osEmptyFilename{};
3860 :
3861 : protected:
3862 : bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
3863 : const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
3864 : void *pDstBuffer) const override;
3865 :
3866 : public:
3867 : GDALMDArrayRegularlySpaced(const std::string &osParentName,
3868 : const std::string &osName,
3869 : const std::shared_ptr<GDALDimension> &poDim,
3870 : double dfStart, double dfIncrement,
3871 : double dfOffsetInIncrement);
3872 :
3873 : static std::shared_ptr<GDALMDArrayRegularlySpaced>
3874 : Create(const std::string &osParentName, const std::string &osName,
3875 : const std::shared_ptr<GDALDimension> &poDim, double dfStart,
3876 : double dfIncrement, double dfOffsetInIncrement);
3877 :
3878 0 : bool IsWritable() const override
3879 : {
3880 0 : return false;
3881 : }
3882 :
3883 104 : const std::string &GetFilename() const override
3884 : {
3885 104 : return m_osEmptyFilename;
3886 : }
3887 :
3888 : const std::vector<std::shared_ptr<GDALDimension>> &
3889 : GetDimensions() const override;
3890 :
3891 : const GDALExtendedDataType &GetDataType() const override;
3892 :
3893 : std::vector<std::shared_ptr<GDALAttribute>>
3894 : GetAttributes(CSLConstList) const override;
3895 :
3896 : void AddAttribute(const std::shared_ptr<GDALAttribute> &poAttr);
3897 : };
3898 :
3899 : //! @endcond
3900 :
3901 : /* ******************************************************************** */
3902 : /* GDALDimension */
3903 : /* ******************************************************************** */
3904 :
3905 : /**
3906 : * Class modeling a a dimension / axis used to index multidimensional arrays.
3907 : * It has a name, a size (that is the number of values that can be indexed along
3908 : * the dimension), a type (see GDALDimension::GetType()), a direction
3909 : * (see GDALDimension::GetDirection()), a unit and can optionally point to a
3910 : * GDALMDArray variable, typically one-dimensional, describing the values taken
3911 : * by the dimension. For a georeferenced GDALMDArray and its X dimension, this
3912 : * will be typically the values of the easting/longitude for each grid point.
3913 : *
3914 : * @since GDAL 3.1
3915 : */
3916 8165 : class CPL_DLL GDALDimension
3917 : {
3918 : public:
3919 : //! @cond Doxygen_Suppress
3920 : GDALDimension(const std::string &osParentName, const std::string &osName,
3921 : const std::string &osType, const std::string &osDirection,
3922 : GUInt64 nSize);
3923 : //! @endcond
3924 :
3925 : virtual ~GDALDimension();
3926 :
3927 : /** Return the name.
3928 : *
3929 : * This is the same as the C function GDALDimensionGetName()
3930 : */
3931 7885 : const std::string &GetName() const
3932 : {
3933 7885 : return m_osName;
3934 : }
3935 :
3936 : /** Return the full name.
3937 : *
3938 : * This is the same as the C function GDALDimensionGetFullName()
3939 : */
3940 1226 : const std::string &GetFullName() const
3941 : {
3942 1226 : return m_osFullName;
3943 : }
3944 :
3945 : /** Return the axis type.
3946 : *
3947 : * Predefined values are:
3948 : * HORIZONTAL_X, HORIZONTAL_Y, VERTICAL, TEMPORAL, PARAMETRIC
3949 : * Other values might be returned. Empty value means unknown.
3950 : *
3951 : * This is the same as the C function GDALDimensionGetType()
3952 : */
3953 1703 : const std::string &GetType() const
3954 : {
3955 1703 : return m_osType;
3956 : }
3957 :
3958 : /** Return the axis direction.
3959 : *
3960 : * Predefined values are:
3961 : * EAST, WEST, SOUTH, NORTH, UP, DOWN, FUTURE, PAST
3962 : * Other values might be returned. Empty value means unknown.
3963 : *
3964 : * This is the same as the C function GDALDimensionGetDirection()
3965 : */
3966 833 : const std::string &GetDirection() const
3967 : {
3968 833 : return m_osDirection;
3969 : }
3970 :
3971 : /** Return the size, that is the number of values along the dimension.
3972 : *
3973 : * This is the same as the C function GDALDimensionGetSize()
3974 : */
3975 80312 : GUInt64 GetSize() const
3976 : {
3977 80312 : return m_nSize;
3978 : }
3979 :
3980 : virtual std::shared_ptr<GDALMDArray> GetIndexingVariable() const;
3981 :
3982 : virtual bool
3983 : SetIndexingVariable(std::shared_ptr<GDALMDArray> poIndexingVariable);
3984 :
3985 : virtual bool Rename(const std::string &osNewName);
3986 :
3987 : //! @cond Doxygen_Suppress
3988 : virtual void ParentRenamed(const std::string &osNewParentFullName);
3989 :
3990 : virtual void ParentDeleted();
3991 : //! @endcond
3992 :
3993 : protected:
3994 : //! @cond Doxygen_Suppress
3995 : std::string m_osName;
3996 : std::string m_osFullName;
3997 : std::string m_osType;
3998 : std::string m_osDirection;
3999 : GUInt64 m_nSize;
4000 :
4001 : void BaseRename(const std::string &osNewName);
4002 :
4003 : //! @endcond
4004 : };
4005 :
4006 : /************************************************************************/
4007 : /* GDALDimensionWeakIndexingVar() */
4008 : /************************************************************************/
4009 :
4010 : //! @cond Doxygen_Suppress
4011 : class CPL_DLL GDALDimensionWeakIndexingVar : public GDALDimension
4012 : {
4013 : std::weak_ptr<GDALMDArray> m_poIndexingVariable{};
4014 :
4015 : public:
4016 : GDALDimensionWeakIndexingVar(const std::string &osParentName,
4017 : const std::string &osName,
4018 : const std::string &osType,
4019 : const std::string &osDirection, GUInt64 nSize);
4020 :
4021 : std::shared_ptr<GDALMDArray> GetIndexingVariable() const override;
4022 :
4023 : bool SetIndexingVariable(
4024 : std::shared_ptr<GDALMDArray> poIndexingVariable) override;
4025 :
4026 : void SetSize(GUInt64 nNewSize);
4027 : };
4028 : //! @endcond
4029 :
4030 : /************************************************************************/
4031 : /* GDALAntiRecursionGuard */
4032 : /************************************************************************/
4033 :
4034 : //! @cond Doxygen_Suppress
4035 : struct GDALAntiRecursionStruct;
4036 :
4037 : class GDALAntiRecursionGuard
4038 : {
4039 : GDALAntiRecursionStruct *m_psAntiRecursionStruct;
4040 : std::string m_osIdentifier;
4041 : int m_nDepth;
4042 :
4043 : GDALAntiRecursionGuard(const GDALAntiRecursionGuard &) = delete;
4044 : GDALAntiRecursionGuard &operator=(const GDALAntiRecursionGuard &) = delete;
4045 :
4046 : public:
4047 : explicit GDALAntiRecursionGuard(const std::string &osIdentifier);
4048 : GDALAntiRecursionGuard(const GDALAntiRecursionGuard &other,
4049 : const std::string &osIdentifier);
4050 : ~GDALAntiRecursionGuard();
4051 :
4052 109002 : int GetCallDepth() const
4053 : {
4054 109002 : return m_nDepth;
4055 : }
4056 : };
4057 :
4058 : //! @endcond
4059 :
4060 : /************************************************************************/
4061 : /* Relationships */
4062 : /************************************************************************/
4063 :
4064 : /**
4065 : * Definition of a table relationship.
4066 : *
4067 : * GDALRelationship describes the relationship between two tables, including
4068 : * properties such as the cardinality of the relationship and the participating
4069 : * tables.
4070 : *
4071 : * Not all relationship properties are supported by all data formats.
4072 : *
4073 : * @since GDAL 3.6
4074 : */
4075 : class CPL_DLL GDALRelationship
4076 : {
4077 : protected:
4078 : /*! @cond Doxygen_Suppress */
4079 : std::string m_osName{};
4080 : std::string m_osLeftTableName{};
4081 : std::string m_osRightTableName{};
4082 : GDALRelationshipCardinality m_eCardinality =
4083 : GDALRelationshipCardinality::GRC_ONE_TO_MANY;
4084 : std::string m_osMappingTableName{};
4085 : std::vector<std::string> m_osListLeftTableFields{};
4086 : std::vector<std::string> m_osListRightTableFields{};
4087 : std::vector<std::string> m_osListLeftMappingTableFields{};
4088 : std::vector<std::string> m_osListRightMappingTableFields{};
4089 : GDALRelationshipType m_eType = GDALRelationshipType::GRT_ASSOCIATION;
4090 : std::string m_osForwardPathLabel{};
4091 : std::string m_osBackwardPathLabel{};
4092 : std::string m_osRelatedTableType{};
4093 :
4094 : /*! @endcond */
4095 :
4096 : public:
4097 : /**
4098 : * Constructor for a relationship between two tables.
4099 : * @param osName relationship name
4100 : * @param osLeftTableName left table name
4101 : * @param osRightTableName right table name
4102 : * @param eCardinality cardinality of relationship
4103 : */
4104 349 : GDALRelationship(const std::string &osName,
4105 : const std::string &osLeftTableName,
4106 : const std::string &osRightTableName,
4107 : GDALRelationshipCardinality eCardinality =
4108 : GDALRelationshipCardinality::GRC_ONE_TO_MANY)
4109 349 : : m_osName(osName), m_osLeftTableName(osLeftTableName),
4110 349 : m_osRightTableName(osRightTableName), m_eCardinality(eCardinality)
4111 : {
4112 349 : }
4113 :
4114 : /** Get the name of the relationship */
4115 393 : const std::string &GetName() const
4116 : {
4117 393 : return m_osName;
4118 : }
4119 :
4120 : /** Get the cardinality of the relationship */
4121 247 : GDALRelationshipCardinality GetCardinality() const
4122 : {
4123 247 : return m_eCardinality;
4124 : }
4125 :
4126 : /** Get the name of the left (or base/origin) table in the relationship.
4127 : *
4128 : * @see GetRightTableName()
4129 : */
4130 202 : const std::string &GetLeftTableName() const
4131 : {
4132 202 : return m_osLeftTableName;
4133 : }
4134 :
4135 : /** Get the name of the right (or related/destination) table in the
4136 : * relationship */
4137 197 : const std::string &GetRightTableName() const
4138 : {
4139 197 : return m_osRightTableName;
4140 : }
4141 :
4142 : /** Get the name of the mapping table for many-to-many relationships.
4143 : *
4144 : * @see SetMappingTableName()
4145 : */
4146 160 : const std::string &GetMappingTableName() const
4147 : {
4148 160 : return m_osMappingTableName;
4149 : }
4150 :
4151 : /** Sets the name of the mapping table for many-to-many relationships.
4152 : *
4153 : * @see GetMappingTableName()
4154 : */
4155 113 : void SetMappingTableName(const std::string &osName)
4156 : {
4157 113 : m_osMappingTableName = osName;
4158 113 : }
4159 :
4160 : /** Get the names of the participating fields from the left table in the
4161 : * relationship.
4162 : *
4163 : * @see GetRightTableFields()
4164 : * @see SetLeftTableFields()
4165 : */
4166 157 : const std::vector<std::string> &GetLeftTableFields() const
4167 : {
4168 157 : return m_osListLeftTableFields;
4169 : }
4170 :
4171 : /** Get the names of the participating fields from the right table in the
4172 : * relationship.
4173 : *
4174 : * @see GetLeftTableFields()
4175 : * @see SetRightTableFields()
4176 : */
4177 151 : const std::vector<std::string> &GetRightTableFields() const
4178 : {
4179 151 : return m_osListRightTableFields;
4180 : }
4181 :
4182 : /** Sets the names of the participating fields from the left table in the
4183 : * relationship.
4184 : *
4185 : * @see GetLeftTableFields()
4186 : * @see SetRightTableFields()
4187 : */
4188 362 : void SetLeftTableFields(const std::vector<std::string> &osListFields)
4189 : {
4190 362 : m_osListLeftTableFields = osListFields;
4191 362 : }
4192 :
4193 : /** Sets the names of the participating fields from the right table in the
4194 : * relationship.
4195 : *
4196 : * @see GetRightTableFields()
4197 : * @see SetLeftTableFields()
4198 : */
4199 363 : void SetRightTableFields(const std::vector<std::string> &osListFields)
4200 : {
4201 363 : m_osListRightTableFields = osListFields;
4202 363 : }
4203 :
4204 : /** Get the names of the mapping table fields which correspond to the
4205 : * participating fields from the left table in the relationship.
4206 : *
4207 : * @see GetRightMappingTableFields()
4208 : * @see SetLeftMappingTableFields()
4209 : */
4210 61 : const std::vector<std::string> &GetLeftMappingTableFields() const
4211 : {
4212 61 : return m_osListLeftMappingTableFields;
4213 : }
4214 :
4215 : /** Get the names of the mapping table fields which correspond to the
4216 : * participating fields from the right table in the relationship.
4217 : *
4218 : * @see GetLeftMappingTableFields()
4219 : * @see SetRightMappingTableFields()
4220 : */
4221 61 : const std::vector<std::string> &GetRightMappingTableFields() const
4222 : {
4223 61 : return m_osListRightMappingTableFields;
4224 : }
4225 :
4226 : /** Sets the names of the mapping table fields which correspond to the
4227 : * participating fields from the left table in the relationship.
4228 : *
4229 : * @see GetLeftMappingTableFields()
4230 : * @see SetRightMappingTableFields()
4231 : */
4232 313 : void SetLeftMappingTableFields(const std::vector<std::string> &osListFields)
4233 : {
4234 313 : m_osListLeftMappingTableFields = osListFields;
4235 313 : }
4236 :
4237 : /** Sets the names of the mapping table fields which correspond to the
4238 : * participating fields from the right table in the relationship.
4239 : *
4240 : * @see GetRightMappingTableFields()
4241 : * @see SetLeftMappingTableFields()
4242 : */
4243 : void
4244 313 : SetRightMappingTableFields(const std::vector<std::string> &osListFields)
4245 : {
4246 313 : m_osListRightMappingTableFields = osListFields;
4247 313 : }
4248 :
4249 : /** Get the type of the relationship.
4250 : *
4251 : * @see SetType()
4252 : */
4253 111 : GDALRelationshipType GetType() const
4254 : {
4255 111 : return m_eType;
4256 : }
4257 :
4258 : /** Sets the type of the relationship.
4259 : *
4260 : * @see GetType()
4261 : */
4262 263 : void SetType(GDALRelationshipType eType)
4263 : {
4264 263 : m_eType = eType;
4265 263 : }
4266 :
4267 : /** Get the label of the forward path for the relationship.
4268 : *
4269 : * The forward and backward path labels are free-form, user-friendly strings
4270 : * which can be used to generate descriptions of the relationship between
4271 : * features from the right and left tables.
4272 : *
4273 : * E.g. when the left table contains buildings and the right table contains
4274 : * furniture, the forward path label could be "contains" and the backward
4275 : * path label could be "is located within". A client could then generate a
4276 : * user friendly description string such as "fire hose 1234 is located
4277 : * within building 15a".
4278 : *
4279 : * @see SetForwardPathLabel()
4280 : * @see GetBackwardPathLabel()
4281 : */
4282 53 : const std::string &GetForwardPathLabel() const
4283 : {
4284 53 : return m_osForwardPathLabel;
4285 : }
4286 :
4287 : /** Sets the label of the forward path for the relationship.
4288 : *
4289 : * The forward and backward path labels are free-form, user-friendly strings
4290 : * which can be used to generate descriptions of the relationship between
4291 : * features from the right and left tables.
4292 : *
4293 : * E.g. when the left table contains buildings and the right table contains
4294 : * furniture, the forward path label could be "contains" and the backward
4295 : * path label could be "is located within". A client could then generate a
4296 : * user friendly description string such as "fire hose 1234 is located
4297 : * within building 15a".
4298 : *
4299 : * @see GetForwardPathLabel()
4300 : * @see SetBackwardPathLabel()
4301 : */
4302 260 : void SetForwardPathLabel(const std::string &osLabel)
4303 : {
4304 260 : m_osForwardPathLabel = osLabel;
4305 260 : }
4306 :
4307 : /** Get the label of the backward path for the relationship.
4308 : *
4309 : * The forward and backward path labels are free-form, user-friendly strings
4310 : * which can be used to generate descriptions of the relationship between
4311 : * features from the right and left tables.
4312 : *
4313 : * E.g. when the left table contains buildings and the right table contains
4314 : * furniture, the forward path label could be "contains" and the backward
4315 : * path label could be "is located within". A client could then generate a
4316 : * user friendly description string such as "fire hose 1234 is located
4317 : * within building 15a".
4318 : *
4319 : * @see SetBackwardPathLabel()
4320 : * @see GetForwardPathLabel()
4321 : */
4322 53 : const std::string &GetBackwardPathLabel() const
4323 : {
4324 53 : return m_osBackwardPathLabel;
4325 : }
4326 :
4327 : /** Sets the label of the backward path for the relationship.
4328 : *
4329 : * The forward and backward path labels are free-form, user-friendly strings
4330 : * which can be used to generate descriptions of the relationship between
4331 : * features from the right and left tables.
4332 : *
4333 : * E.g. when the left table contains buildings and the right table contains
4334 : * furniture, the forward path label could be "contains" and the backward
4335 : * path label could be "is located within". A client could then generate a
4336 : * user friendly description string such as "fire hose 1234 is located
4337 : * within building 15a".
4338 : *
4339 : * @see GetBackwardPathLabel()
4340 : * @see SetForwardPathLabel()
4341 : */
4342 260 : void SetBackwardPathLabel(const std::string &osLabel)
4343 : {
4344 260 : m_osBackwardPathLabel = osLabel;
4345 260 : }
4346 :
4347 : /** Get the type string of the related table.
4348 : *
4349 : * This a free-form string representing the type of related features, where
4350 : * the exact interpretation is format dependent. For instance, table types
4351 : * from GeoPackage relationships will directly reflect the categories from
4352 : * the GeoPackage related tables extension (i.e. "media", "simple
4353 : * attributes", "features", "attributes" and "tiles").
4354 : *
4355 : * @see SetRelatedTableType()
4356 : */
4357 144 : const std::string &GetRelatedTableType() const
4358 : {
4359 144 : return m_osRelatedTableType;
4360 : }
4361 :
4362 : /** Sets the type string of the related table.
4363 : *
4364 : * This a free-form string representing the type of related features, where
4365 : * the exact interpretation is format dependent. For instance, table types
4366 : * from GeoPackage relationships will directly reflect the categories from
4367 : * the GeoPackage related tables extension (i.e. "media", "simple
4368 : * attributes", "features", "attributes" and "tiles").
4369 : *
4370 : * @see GetRelatedTableType()
4371 : */
4372 340 : void SetRelatedTableType(const std::string &osType)
4373 : {
4374 340 : m_osRelatedTableType = osType;
4375 340 : }
4376 :
4377 : /** Convert a GDALRelationship* to a GDALRelationshipH.
4378 : */
4379 81 : static inline GDALRelationshipH ToHandle(GDALRelationship *poRelationship)
4380 : {
4381 81 : return static_cast<GDALRelationshipH>(poRelationship);
4382 : }
4383 :
4384 : /** Convert a GDALRelationshipH to a GDALRelationship*.
4385 : */
4386 706 : static inline GDALRelationship *FromHandle(GDALRelationshipH hRelationship)
4387 : {
4388 706 : return static_cast<GDALRelationship *>(hRelationship);
4389 : }
4390 : };
4391 :
4392 : /* ==================================================================== */
4393 : /* An assortment of overview related stuff. */
4394 : /* ==================================================================== */
4395 :
4396 : //! @cond Doxygen_Suppress
4397 : /* Only exported for drivers as plugin. Signature may change */
4398 : CPLErr CPL_DLL GDALRegenerateOverviewsMultiBand(
4399 : int nBands, GDALRasterBand *const *papoSrcBands, int nOverviews,
4400 : GDALRasterBand *const *const *papapoOverviewBands,
4401 : const char *pszResampling, GDALProgressFunc pfnProgress,
4402 : void *pProgressData, CSLConstList papszOptions);
4403 :
4404 : CPLErr CPL_DLL GDALRegenerateOverviewsMultiBand(
4405 : const std::vector<GDALRasterBand *> &apoSrcBands,
4406 : // First level of array is indexed by band (thus aapoOverviewBands.size() must be equal to apoSrcBands.size())
4407 : // Second level is indexed by overview
4408 : const std::vector<std::vector<GDALRasterBand *>> &aapoOverviewBands,
4409 : const char *pszResampling, GDALProgressFunc pfnProgress,
4410 : void *pProgressData, CSLConstList papszOptions);
4411 :
4412 : /************************************************************************/
4413 : /* GDALOverviewResampleArgs */
4414 : /************************************************************************/
4415 :
4416 : /** Arguments for overview resampling function. */
4417 : // Should not contain any dataset/rasterband object, as this might be
4418 : // read in a worker thread.
4419 : struct GDALOverviewResampleArgs
4420 : {
4421 : //! Datatype of the source band argument
4422 : GDALDataType eSrcDataType = GDT_Unknown;
4423 : //! Datatype of the destination/overview band
4424 : GDALDataType eOvrDataType = GDT_Unknown;
4425 : //! Width in pixel of the destination/overview band
4426 : int nOvrXSize = 0;
4427 : //! Height in pixel of the destination/overview band
4428 : int nOvrYSize = 0;
4429 : //! NBITS value of the destination/overview band (or 0 if not set)
4430 : int nOvrNBITS = 0;
4431 : //! Factor to convert from destination X to source X
4432 : // (source width divided by destination width)
4433 : double dfXRatioDstToSrc = 0;
4434 : //! Factor to convert from destination Y to source Y
4435 : // (source height divided by destination height)
4436 : double dfYRatioDstToSrc = 0;
4437 : //! Sub-pixel delta to add to get source X
4438 : double dfSrcXDelta = 0;
4439 : //! Sub-pixel delta to add to get source Y
4440 : double dfSrcYDelta = 0;
4441 : //! Working data type (data type of the pChunk argument)
4442 : GDALDataType eWrkDataType = GDT_Unknown;
4443 : //! Array of nChunkXSize * nChunkYSize values of mask, or nullptr
4444 : const GByte *pabyChunkNodataMask = nullptr;
4445 : //! X offset of the source chunk in the source band
4446 : int nChunkXOff = 0;
4447 : //! Width in pixel of the source chunk in the source band
4448 : int nChunkXSize = 0;
4449 : //! Y offset of the source chunk in the source band
4450 : int nChunkYOff = 0;
4451 : //! Height in pixel of the source chunk in the source band
4452 : int nChunkYSize = 0;
4453 : //! X Offset of the destination chunk in the destination band
4454 : int nDstXOff = 0;
4455 : //! X Offset of the end (not included) of the destination chunk in the destination band
4456 : int nDstXOff2 = 0;
4457 : //! Y Offset of the destination chunk in the destination band
4458 : int nDstYOff = 0;
4459 : //! Y Offset of the end (not included) of the destination chunk in the destination band
4460 : int nDstYOff2 = 0;
4461 : //! Resampling method
4462 : const char *pszResampling = nullptr;
4463 : //! Whether the source band has a nodata value
4464 : bool bHasNoData = false;
4465 : //! Source band nodata value
4466 : double dfNoDataValue = 0;
4467 : //! Source color table
4468 : const GDALColorTable *poColorTable = nullptr;
4469 : //! Whether a single contributing source pixel at nodata should result
4470 : // in the target pixel to be at nodata too (only taken into account by
4471 : // average resampling)
4472 : bool bPropagateNoData = false;
4473 : };
4474 :
4475 : typedef CPLErr (*GDALResampleFunction)(const GDALOverviewResampleArgs &args,
4476 : const void *pChunk, void **ppDstBuffer,
4477 : GDALDataType *peDstBufferDataType);
4478 :
4479 : GDALResampleFunction GDALGetResampleFunction(const char *pszResampling,
4480 : int *pnRadius);
4481 :
4482 : std::string CPL_DLL GDALGetNormalizedOvrResampling(const char *pszResampling);
4483 :
4484 : GDALDataType GDALGetOvrWorkDataType(const char *pszResampling,
4485 : GDALDataType eSrcDataType);
4486 :
4487 : CPL_C_START
4488 :
4489 : CPLErr CPL_DLL
4490 : HFAAuxBuildOverviews(const char *pszOvrFilename, GDALDataset *poParentDS,
4491 : GDALDataset **ppoDS, int nBands, const int *panBandList,
4492 : int nNewOverviews, const int *panNewOverviewList,
4493 : const char *pszResampling, GDALProgressFunc pfnProgress,
4494 : void *pProgressData, CSLConstList papszOptions);
4495 :
4496 : CPLErr CPL_DLL GTIFFBuildOverviews(const char *pszFilename, int nBands,
4497 : GDALRasterBand *const *papoBandList,
4498 : int nOverviews, const int *panOverviewList,
4499 : const char *pszResampling,
4500 : GDALProgressFunc pfnProgress,
4501 : void *pProgressData,
4502 : CSLConstList papszOptions);
4503 :
4504 : int CPL_DLL GDALBandGetBestOverviewLevel(GDALRasterBand *poBand, int &nXOff,
4505 : int &nYOff, int &nXSize, int &nYSize,
4506 : int nBufXSize, int nBufYSize)
4507 : CPL_WARN_DEPRECATED("Use GDALBandGetBestOverviewLevel2 instead");
4508 : int CPL_DLL GDALBandGetBestOverviewLevel2(GDALRasterBand *poBand, int &nXOff,
4509 : int &nYOff, int &nXSize, int &nYSize,
4510 : int nBufXSize, int nBufYSize,
4511 : GDALRasterIOExtraArg *psExtraArg);
4512 :
4513 : int CPL_DLL GDALOvLevelAdjust(int nOvLevel, int nXSize)
4514 : CPL_WARN_DEPRECATED("Use GDALOvLevelAdjust2 instead");
4515 : int CPL_DLL GDALOvLevelAdjust2(int nOvLevel, int nXSize, int nYSize);
4516 : int CPL_DLL GDALComputeOvFactor(int nOvrXSize, int nRasterXSize, int nOvrYSize,
4517 : int nRasterYSize);
4518 :
4519 : GDALDataset CPL_DLL *GDALFindAssociatedAuxFile(const char *pszBasefile,
4520 : GDALAccess eAccess,
4521 : GDALDataset *poDependentDS);
4522 :
4523 : /* ==================================================================== */
4524 : /* Infrastructure to check that dataset characteristics are valid */
4525 : /* ==================================================================== */
4526 :
4527 : int CPL_DLL GDALCheckDatasetDimensions(int nXSize, int nYSize);
4528 : int CPL_DLL GDALCheckBandCount(int nBands, int bIsZeroAllowed);
4529 :
4530 : /* Internal use only */
4531 :
4532 : /* CPL_DLL exported, but only for in-tree drivers that can be built as plugins
4533 : */
4534 : int CPL_DLL GDALReadWorldFile2(const char *pszBaseFilename,
4535 : const char *pszExtension,
4536 : double *padfGeoTransform,
4537 : CSLConstList papszSiblingFiles,
4538 : char **ppszWorldFileNameOut);
4539 : int CPL_DLL GDALReadTabFile2(const char *pszBaseFilename,
4540 : double *padfGeoTransform, char **ppszWKT,
4541 : int *pnGCPCount, GDAL_GCP **ppasGCPs,
4542 : CSLConstList papszSiblingFiles,
4543 : char **ppszTabFileNameOut);
4544 :
4545 : void CPL_DLL GDALCopyRasterIOExtraArg(GDALRasterIOExtraArg *psDestArg,
4546 : GDALRasterIOExtraArg *psSrcArg);
4547 :
4548 : void CPL_DLL GDALExpandPackedBitsToByteAt0Or1(
4549 : const GByte *CPL_RESTRICT pabyInput, GByte *CPL_RESTRICT pabyOutput,
4550 : size_t nInputBits);
4551 :
4552 : void CPL_DLL GDALExpandPackedBitsToByteAt0Or255(
4553 : const GByte *CPL_RESTRICT pabyInput, GByte *CPL_RESTRICT pabyOutput,
4554 : size_t nInputBits);
4555 :
4556 : CPL_C_END
4557 :
4558 : std::unique_ptr<GDALDataset> CPL_DLL
4559 : GDALGetThreadSafeDataset(std::unique_ptr<GDALDataset> poDS, int nScopeFlags);
4560 :
4561 : GDALDataset CPL_DLL *GDALGetThreadSafeDataset(GDALDataset *poDS,
4562 : int nScopeFlags);
4563 :
4564 : void GDALNullifyOpenDatasetsList();
4565 : CPLMutex **GDALGetphDMMutex();
4566 : CPLMutex **GDALGetphDLMutex();
4567 : void GDALNullifyProxyPoolSingleton();
4568 : void GDALSetResponsiblePIDForCurrentThread(GIntBig responsiblePID);
4569 : GIntBig GDALGetResponsiblePIDForCurrentThread();
4570 :
4571 : CPLString GDALFindAssociatedFile(const char *pszBasename, const char *pszExt,
4572 : CSLConstList papszSiblingFiles, int nFlags);
4573 :
4574 : CPLErr CPL_DLL EXIFExtractMetadata(char **&papszMetadata, void *fpL,
4575 : int nOffset, int bSwabflag, int nTIFFHEADER,
4576 : int &nExifOffset, int &nInterOffset,
4577 : int &nGPSOffset);
4578 :
4579 : int GDALValidateOpenOptions(GDALDriverH hDriver,
4580 : const char *const *papszOptionOptions);
4581 : int GDALValidateOptions(const char *pszOptionList,
4582 : const char *const *papszOptionsToValidate,
4583 : const char *pszErrorMessageOptionType,
4584 : const char *pszErrorMessageContainerName);
4585 :
4586 : GDALRIOResampleAlg CPL_DLL
4587 : GDALRasterIOGetResampleAlg(const char *pszResampling);
4588 : const char *GDALRasterIOGetResampleAlg(GDALRIOResampleAlg eResampleAlg);
4589 :
4590 : void GDALRasterIOExtraArgSetResampleAlg(GDALRasterIOExtraArg *psExtraArg,
4591 : int nXSize, int nYSize, int nBufXSize,
4592 : int nBufYSize);
4593 :
4594 : GDALDataset *GDALCreateOverviewDataset(GDALDataset *poDS, int nOvrLevel,
4595 : bool bThisLevelOnly);
4596 :
4597 : // Should cover particular cases of #3573, #4183, #4506, #6578
4598 : // Behavior is undefined if fVal1 or fVal2 are NaN (should be tested before
4599 : // calling this function)
4600 :
4601 : // TODO: The expression `abs(fVal1 + fVal2)` looks strange; is this a bug?
4602 : // Should this be `abs(fVal1) + abs(fVal2)` instead?
4603 :
4604 0 : inline bool ARE_REAL_EQUAL(GFloat16 dfVal1, GFloat16 dfVal2, int ulp = 2)
4605 : {
4606 : using std::abs;
4607 0 : return dfVal1 == dfVal2 || /* Should cover infinity */
4608 0 : abs(dfVal1 - dfVal2) < cpl::NumericLimits<GFloat16>::epsilon() *
4609 0 : abs(dfVal1 + dfVal2) * ulp;
4610 : }
4611 :
4612 15638313 : inline bool ARE_REAL_EQUAL(float fVal1, float fVal2, int ulp = 2)
4613 : {
4614 : using std::abs;
4615 30270118 : return fVal1 == fVal2 || /* Should cover infinity */
4616 14631805 : abs(fVal1 - fVal2) <
4617 30270118 : cpl::NumericLimits<float>::epsilon() * abs(fVal1 + fVal2) * ulp;
4618 : }
4619 :
4620 : // We are using `cpl::NumericLimits<float>::epsilon()` for backward
4621 : // compatibility
4622 3948184 : inline bool ARE_REAL_EQUAL(double dfVal1, double dfVal2, int ulp = 2)
4623 : {
4624 : using std::abs;
4625 4548789 : return dfVal1 == dfVal2 || /* Should cover infinity */
4626 600610 : abs(dfVal1 - dfVal2) < cpl::NumericLimits<float>::epsilon() *
4627 4548789 : abs(dfVal1 + dfVal2) * ulp;
4628 : }
4629 :
4630 : double GDALAdjustNoDataCloseToFloatMax(double dfVal);
4631 :
4632 : #define DIV_ROUND_UP(a, b) (((a) % (b)) == 0 ? ((a) / (b)) : (((a) / (b)) + 1))
4633 :
4634 : // Number of data samples that will be used to compute approximate statistics
4635 : // (minimum value, maximum value, etc.)
4636 : #define GDALSTAT_APPROX_NUMSAMPLES 2500
4637 :
4638 : void GDALSerializeGCPListToXML(CPLXMLNode *psParentNode,
4639 : const std::vector<gdal::GCP> &asGCPs,
4640 : const OGRSpatialReference *poGCP_SRS);
4641 : void GDALDeserializeGCPListFromXML(const CPLXMLNode *psGCPList,
4642 : std::vector<gdal::GCP> &asGCPs,
4643 : OGRSpatialReference **ppoGCP_SRS);
4644 :
4645 : void GDALSerializeOpenOptionsToXML(CPLXMLNode *psParentNode,
4646 : CSLConstList papszOpenOptions);
4647 : char CPL_DLL **
4648 : GDALDeserializeOpenOptionsFromXML(const CPLXMLNode *psParentNode);
4649 :
4650 : int GDALCanFileAcceptSidecarFile(const char *pszFilename);
4651 :
4652 : bool GDALCanReliablyUseSiblingFileList(const char *pszFilename);
4653 :
4654 : typedef enum
4655 : {
4656 : GSF_UNSIGNED_INT,
4657 : GSF_SIGNED_INT,
4658 : GSF_FLOATING_POINT,
4659 : } GDALBufferSampleFormat;
4660 :
4661 : bool CPL_DLL GDALBufferHasOnlyNoData(const void *pBuffer, double dfNoDataValue,
4662 : size_t nWidth, size_t nHeight,
4663 : size_t nLineStride, size_t nComponents,
4664 : int nBitsPerSample,
4665 : GDALBufferSampleFormat nSampleFormat);
4666 :
4667 : void CPL_DLL GDALCopyNoDataValue(GDALRasterBand *poDstBand,
4668 : GDALRasterBand *poSrcBand);
4669 :
4670 : double CPL_DLL GDALGetNoDataValueCastToDouble(int64_t nVal);
4671 : double CPL_DLL GDALGetNoDataValueCastToDouble(uint64_t nVal);
4672 :
4673 : // Remove me in GDAL 4.0. See GetMetadataItem() implementation
4674 : // Internal use in GDAL only !
4675 : // Declaration copied in swig/include/gdal.i
4676 : void CPL_DLL GDALEnablePixelTypeSignedByteWarning(GDALRasterBandH hBand,
4677 : bool b);
4678 :
4679 : std::string CPL_DLL GDALGetCompressionFormatForJPEG(VSILFILE *fp);
4680 : std::string CPL_DLL GDALGetCompressionFormatForJPEG(const void *pBuffer,
4681 : size_t nBufferSize);
4682 :
4683 : GDALRasterAttributeTable CPL_DLL *GDALCreateRasterAttributeTableFromMDArrays(
4684 : GDALRATTableType eTableType,
4685 : const std::vector<std::shared_ptr<GDALMDArray>> &apoArrays,
4686 : const std::vector<GDALRATFieldUsage> &aeUsages);
4687 :
4688 : GDALColorInterp CPL_DLL
4689 : GDALGetColorInterpFromSTACCommonName(const char *pszName);
4690 : const char CPL_DLL *
4691 : GDALGetSTACCommonNameFromColorInterp(GDALColorInterp eInterp);
4692 :
4693 : // Macro used so that Identify and driver metadata methods in drivers built
4694 : // as plugin can be duplicated in libgdal core and in the driver under different
4695 : // names
4696 : #ifdef PLUGIN_FILENAME
4697 : #define PLUGIN_SYMBOL_NAME(x) GDAL_core_##x
4698 : #else
4699 : #define PLUGIN_SYMBOL_NAME(x) GDAL_driver_##x
4700 : #endif
4701 :
4702 : //! @endcond
4703 :
4704 : #endif /* ndef GDAL_PRIV_H_INCLUDED */
|