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 : class GDALAlgorithm;
38 :
39 : /* -------------------------------------------------------------------- */
40 : /* Pull in the public declarations. This gets the C apis, and */
41 : /* also various constants. However, we will still get to */
42 : /* provide the real class definitions for the GDAL classes. */
43 : /* -------------------------------------------------------------------- */
44 :
45 : #include "gdal.h"
46 : #include "gdal_frmts.h"
47 : #include "gdalsubdatasetinfo.h"
48 : #include "cpl_vsi.h"
49 : #include "cpl_conv.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 6008640 : class CPL_DLL GDALMultiDomainMetadata
89 : {
90 : private:
91 : CPLStringList aosDomainList{};
92 :
93 : struct Comparator
94 : {
95 31637500 : bool operator()(const char *a, const char *b) const
96 : {
97 31637500 : 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 513222 : CSLConstList GetDomainList() const
111 : {
112 513222 : 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 246 : static inline GDALMajorObjectH ToHandle(GDALMajorObject *poMajorObject)
177 : {
178 246 : return static_cast<GDALMajorObjectH>(poMajorObject);
179 : }
180 :
181 : /** Convert a GDALMajorObjectH to a GDALMajorObject*.
182 : * @since GDAL 2.3
183 : */
184 293592 : static inline GDALMajorObject *FromHandle(GDALMajorObjectH hMajorObject)
185 : {
186 293592 : 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 57727 : char **GetSiblingFiles()
277 : {
278 57727 : 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 859587 : inline bool IsExtensionEqualToCI(const char *pszExt) const
344 : {
345 859587 : 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 24695 : inline double &Pixel()
402 : {
403 24695 : 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 24695 : inline double &Line()
414 : {
415 24695 : 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 24621 : inline double &X()
426 : {
427 24621 : 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 24621 : inline double &Y()
438 : {
439 24621 : 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 24519 : inline double &Z()
450 : {
451 24519 : return gcp.dfGCPZ;
452 : }
453 :
454 : /** Casts as a C GDAL_GCP pointer */
455 438 : inline const GDAL_GCP *c_ptr() const
456 : {
457 438 : 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 189535 : GDALAccess GetAccess() const
828 : {
829 189535 : 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 4762447 : bool IsMarkedSuppressOnClose() const
842 : {
843 4762447 : return bSuppressOnClose;
844 : }
845 :
846 : /** Return open options.
847 : * @return open options.
848 : */
849 141935 : char **GetOpenOptions()
850 : {
851 141935 : 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 29856 : static inline GDALDatasetH ToHandle(GDALDataset *poDS)
908 : {
909 29856 : return static_cast<GDALDatasetH>(poDS);
910 : }
911 :
912 : /** Convert a GDALDatasetH to a GDALDataset*.
913 : * @since GDAL 2.3
914 : */
915 1397606 : static inline GDALDataset *FromHandle(GDALDatasetH hDS)
916 : {
917 1397606 : return static_cast<GDALDataset *>(hDS);
918 : }
919 :
920 : /** @see GDALOpenEx().
921 : * @since GDAL 2.3
922 : */
923 28723 : 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 28723 : return FromHandle(GDALOpenEx(pszFilename, nOpenFlags,
930 : papszAllowedDrivers, papszOpenOptions,
931 28723 : 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 200 : CPL_INTERNAL explicit Layers(GDALDataset *poSelf) : m_poSelf(poSelf)
979 : {
980 200 : }
981 :
982 : public:
983 : /** Layer iterator.
984 : * @since GDAL 2.3
985 : */
986 408 : 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 :
1031 : int GetLayerIndex(const char *pszName);
1032 :
1033 : virtual OGRErr DeleteLayer(int iLayer);
1034 :
1035 : virtual void ResetReading();
1036 : virtual OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer,
1037 : double *pdfProgressPct,
1038 : GDALProgressFunc pfnProgress,
1039 : void *pProgressData);
1040 :
1041 : /** Class returned by GetFeatures() that act as a container for vector
1042 : * features. */
1043 : class CPL_DLL Features
1044 : {
1045 : private:
1046 : friend class GDALDataset;
1047 : GDALDataset *m_poSelf;
1048 :
1049 2 : CPL_INTERNAL explicit Features(GDALDataset *poSelf) : m_poSelf(poSelf)
1050 : {
1051 2 : }
1052 :
1053 4 : class CPL_DLL Iterator
1054 : {
1055 : struct Private;
1056 : std::unique_ptr<Private> m_poPrivate;
1057 :
1058 : public:
1059 : Iterator(GDALDataset *poDS, bool bStart);
1060 : Iterator(const Iterator &oOther); // declared but not defined.
1061 : // Needed for gcc 5.4 at least
1062 : Iterator(Iterator &&oOther) noexcept; // declared but not defined.
1063 : // Needed for gcc 5.4 at least
1064 : ~Iterator();
1065 : const FeatureLayerPair &operator*() const;
1066 : Iterator &operator++();
1067 : bool operator!=(const Iterator &it) const;
1068 : };
1069 :
1070 : public:
1071 : const Iterator begin() const;
1072 :
1073 : const Iterator end() const;
1074 : };
1075 :
1076 : Features GetFeatures();
1077 :
1078 : virtual int TestCapability(const char *);
1079 :
1080 : virtual std::vector<std::string>
1081 : GetFieldDomainNames(CSLConstList papszOptions = nullptr) const;
1082 :
1083 : virtual const OGRFieldDomain *GetFieldDomain(const std::string &name) const;
1084 :
1085 : virtual bool AddFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
1086 : std::string &failureReason);
1087 :
1088 : virtual bool DeleteFieldDomain(const std::string &name,
1089 : std::string &failureReason);
1090 :
1091 : virtual bool UpdateFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
1092 : std::string &failureReason);
1093 :
1094 : virtual std::vector<std::string>
1095 : GetRelationshipNames(CSLConstList papszOptions = nullptr) const;
1096 :
1097 : virtual const GDALRelationship *
1098 : GetRelationship(const std::string &name) const;
1099 :
1100 : virtual bool
1101 : AddRelationship(std::unique_ptr<GDALRelationship> &&relationship,
1102 : std::string &failureReason);
1103 :
1104 : virtual bool DeleteRelationship(const std::string &name,
1105 : std::string &failureReason);
1106 :
1107 : virtual bool
1108 : UpdateRelationship(std::unique_ptr<GDALRelationship> &&relationship,
1109 : std::string &failureReason);
1110 :
1111 : //! @cond Doxygen_Suppress
1112 : OGRLayer *CreateLayer(const char *pszName);
1113 :
1114 : OGRLayer *CreateLayer(const char *pszName, std::nullptr_t);
1115 : //! @endcond
1116 :
1117 : OGRLayer *CreateLayer(const char *pszName,
1118 : const OGRSpatialReference *poSpatialRef,
1119 : OGRwkbGeometryType eGType = wkbUnknown,
1120 : CSLConstList papszOptions = nullptr);
1121 :
1122 : OGRLayer *CreateLayer(const char *pszName,
1123 : const OGRGeomFieldDefn *poGeomFieldDefn,
1124 : CSLConstList papszOptions = nullptr);
1125 :
1126 : virtual OGRLayer *CopyLayer(OGRLayer *poSrcLayer, const char *pszNewName,
1127 : char **papszOptions = nullptr);
1128 :
1129 : virtual OGRStyleTable *GetStyleTable();
1130 : virtual void SetStyleTableDirectly(OGRStyleTable *poStyleTable);
1131 :
1132 : virtual void SetStyleTable(OGRStyleTable *poStyleTable);
1133 :
1134 : virtual OGRLayer *ExecuteSQL(const char *pszStatement,
1135 : OGRGeometry *poSpatialFilter,
1136 : const char *pszDialect);
1137 : virtual void ReleaseResultSet(OGRLayer *poResultsSet);
1138 : virtual OGRErr AbortSQL();
1139 :
1140 : int GetRefCount() const;
1141 : int GetSummaryRefCount() const;
1142 : OGRErr Release();
1143 :
1144 : virtual OGRErr StartTransaction(int bForce = FALSE);
1145 : virtual OGRErr CommitTransaction();
1146 : virtual OGRErr RollbackTransaction();
1147 :
1148 : virtual std::shared_ptr<GDALGroup> GetRootGroup() const;
1149 :
1150 : static std::string BuildFilename(const char *pszFilename,
1151 : const char *pszReferencePath,
1152 : bool bRelativeToReferencePath);
1153 :
1154 : //! @cond Doxygen_Suppress
1155 : static int IsGenericSQLDialect(const char *pszDialect);
1156 :
1157 : // Semi-public methods. Only to be used by in-tree drivers.
1158 : GDALSQLParseInfo *
1159 : BuildParseInfo(swq_select *psSelectInfo,
1160 : swq_select_parse_options *poSelectParseOptions);
1161 : static void DestroyParseInfo(GDALSQLParseInfo *psParseInfo);
1162 : OGRLayer *ExecuteSQL(const char *pszStatement, OGRGeometry *poSpatialFilter,
1163 : const char *pszDialect,
1164 : swq_select_parse_options *poSelectParseOptions);
1165 :
1166 : static constexpr const char *const apszSpecialSubDatasetSyntax[] = {
1167 : "NITF_IM:{ANY}:{FILENAME}", "PDF:{ANY}:{FILENAME}",
1168 : "RASTERLITE:{FILENAME},{ANY}", "TILEDB:\"{FILENAME}\":{ANY}",
1169 : "TILEDB:{FILENAME}:{ANY}"};
1170 :
1171 : //! @endcond
1172 :
1173 : protected:
1174 : virtual OGRLayer *ICreateLayer(const char *pszName,
1175 : const OGRGeomFieldDefn *poGeomFieldDefn,
1176 : CSLConstList papszOptions);
1177 :
1178 : //! @cond Doxygen_Suppress
1179 : OGRErr ProcessSQLCreateIndex(const char *);
1180 : OGRErr ProcessSQLDropIndex(const char *);
1181 : OGRErr ProcessSQLDropTable(const char *);
1182 : OGRErr ProcessSQLAlterTableAddColumn(const char *);
1183 : OGRErr ProcessSQLAlterTableDropColumn(const char *);
1184 : OGRErr ProcessSQLAlterTableAlterColumn(const char *);
1185 : OGRErr ProcessSQLAlterTableRenameColumn(const char *);
1186 :
1187 : OGRStyleTable *m_poStyleTable = nullptr;
1188 :
1189 : friend class GDALProxyPoolDataset;
1190 : //! @endcond
1191 :
1192 : private:
1193 : CPL_DISALLOW_COPY_ASSIGN(GDALDataset)
1194 : };
1195 :
1196 : //! @cond Doxygen_Suppress
1197 : struct CPL_DLL GDALDatasetUniquePtrDeleter
1198 : {
1199 74 : void operator()(GDALDataset *poDataset) const
1200 : {
1201 74 : GDALClose(poDataset);
1202 74 : }
1203 : };
1204 :
1205 : //! @endcond
1206 :
1207 : //! @cond Doxygen_Suppress
1208 : struct CPL_DLL GDALDatasetUniquePtrReleaser
1209 : {
1210 1032 : void operator()(GDALDataset *poDataset) const
1211 : {
1212 1032 : if (poDataset)
1213 1029 : poDataset->Release();
1214 1032 : }
1215 : };
1216 :
1217 : //! @endcond
1218 :
1219 : /** Unique pointer type for GDALDataset.
1220 : * Appropriate for use on datasets open in non-shared mode and onto which
1221 : * reference counter has not been manually modified.
1222 : * @since GDAL 2.3
1223 : */
1224 : using GDALDatasetUniquePtr =
1225 : std::unique_ptr<GDALDataset, GDALDatasetUniquePtrDeleter>;
1226 :
1227 : /* ******************************************************************** */
1228 : /* GDALRasterBlock */
1229 : /* ******************************************************************** */
1230 :
1231 : /** A single raster block in the block cache.
1232 : *
1233 : * And the global block manager that manages a least-recently-used list of
1234 : * blocks from various datasets/bands */
1235 : class CPL_DLL GDALRasterBlock
1236 : {
1237 : friend class GDALAbstractBandBlockCache;
1238 :
1239 : GDALDataType eType;
1240 :
1241 : bool bDirty;
1242 : volatile int nLockCount;
1243 :
1244 : int nXOff;
1245 : int nYOff;
1246 :
1247 : int nXSize;
1248 : int nYSize;
1249 :
1250 : void *pData;
1251 :
1252 : GDALRasterBand *poBand;
1253 :
1254 : GDALRasterBlock *poNext;
1255 : GDALRasterBlock *poPrevious;
1256 :
1257 : bool bMustDetach;
1258 :
1259 : CPL_INTERNAL void Detach_unlocked(void);
1260 : CPL_INTERNAL void Touch_unlocked(void);
1261 :
1262 : CPL_INTERNAL void RecycleFor(int nXOffIn, int nYOffIn);
1263 :
1264 : public:
1265 : GDALRasterBlock(GDALRasterBand *, int, int);
1266 : GDALRasterBlock(int nXOffIn, int nYOffIn); /* only for lookup purpose */
1267 : virtual ~GDALRasterBlock();
1268 :
1269 : CPLErr Internalize(void);
1270 : void Touch(void);
1271 : void MarkDirty(void);
1272 : void MarkClean(void);
1273 :
1274 : /** Increment the lock count */
1275 10210400 : int AddLock(void)
1276 : {
1277 10210400 : return CPLAtomicInc(&nLockCount);
1278 : }
1279 :
1280 : /** Decrement the lock count */
1281 10210376 : int DropLock(void)
1282 : {
1283 10210376 : return CPLAtomicDec(&nLockCount);
1284 : }
1285 :
1286 : void Detach();
1287 :
1288 : CPLErr Write();
1289 :
1290 : /** Return the data type
1291 : * @return data type
1292 : */
1293 19542 : GDALDataType GetDataType() const
1294 : {
1295 19542 : return eType;
1296 : }
1297 :
1298 : /** Return the x offset of the top-left corner of the block
1299 : * @return x offset
1300 : */
1301 12126800 : int GetXOff() const
1302 : {
1303 12126800 : return nXOff;
1304 : }
1305 :
1306 : /** Return the y offset of the top-left corner of the block
1307 : * @return y offset
1308 : */
1309 482965000 : int GetYOff() const
1310 : {
1311 482965000 : return nYOff;
1312 : }
1313 :
1314 : /** Return the width of the block
1315 : * @return width
1316 : */
1317 : int GetXSize() const
1318 : {
1319 : return nXSize;
1320 : }
1321 :
1322 : /** Return the height of the block
1323 : * @return height
1324 : */
1325 : int GetYSize() const
1326 : {
1327 : return nYSize;
1328 : }
1329 :
1330 : /** Return the dirty flag
1331 : * @return dirty flag
1332 : */
1333 3675950 : int GetDirty() const
1334 : {
1335 3675950 : return bDirty;
1336 : }
1337 :
1338 : /** Return the data buffer
1339 : * @return data buffer
1340 : */
1341 13497010 : void *GetDataRef(void)
1342 : {
1343 13497010 : return pData;
1344 : }
1345 :
1346 : /** Return the block size in bytes
1347 : * @return block size.
1348 : */
1349 6351550 : GPtrDiff_t GetBlockSize() const
1350 : {
1351 6351550 : return static_cast<GPtrDiff_t>(nXSize) * nYSize *
1352 6351550 : GDALGetDataTypeSizeBytes(eType);
1353 : }
1354 :
1355 : int TakeLock();
1356 : int DropLockForRemovalFromStorage();
1357 :
1358 : /// @brief Accessor to source GDALRasterBand object.
1359 : /// @return source raster band of the raster block.
1360 59248 : GDALRasterBand *GetBand()
1361 : {
1362 59248 : return poBand;
1363 : }
1364 :
1365 : static void FlushDirtyBlocks();
1366 : static int FlushCacheBlock(int bDirtyBlocksOnly = FALSE);
1367 : static void Verify();
1368 :
1369 : static void EnterDisableDirtyBlockFlush();
1370 : static void LeaveDisableDirtyBlockFlush();
1371 :
1372 : #ifdef notdef
1373 : static void CheckNonOrphanedBlocks(GDALRasterBand *poBand);
1374 : void DumpBlock();
1375 : static void DumpAll();
1376 : #endif
1377 :
1378 : /* Should only be called by GDALDestroyDriverManager() */
1379 : //! @cond Doxygen_Suppress
1380 : CPL_INTERNAL static void DestroyRBMutex();
1381 : //! @endcond
1382 :
1383 : private:
1384 : CPL_DISALLOW_COPY_ASSIGN(GDALRasterBlock)
1385 : };
1386 :
1387 : /* ******************************************************************** */
1388 : /* GDALColorTable */
1389 : /* ******************************************************************** */
1390 :
1391 : /** A color table / palette. */
1392 :
1393 2114 : class CPL_DLL GDALColorTable
1394 : {
1395 : GDALPaletteInterp eInterp;
1396 :
1397 : std::vector<GDALColorEntry> aoEntries{};
1398 :
1399 : public:
1400 : explicit GDALColorTable(GDALPaletteInterp = GPI_RGB);
1401 : ~GDALColorTable();
1402 :
1403 : GDALColorTable *Clone() const;
1404 : int IsSame(const GDALColorTable *poOtherCT) const;
1405 :
1406 : GDALPaletteInterp GetPaletteInterpretation() const;
1407 :
1408 : int GetColorEntryCount() const;
1409 : const GDALColorEntry *GetColorEntry(int i) const;
1410 : int GetColorEntryAsRGB(int i, GDALColorEntry *poEntry) const;
1411 : void SetColorEntry(int i, const GDALColorEntry *poEntry);
1412 : int CreateColorRamp(int nStartIndex, const GDALColorEntry *psStartColor,
1413 : int nEndIndex, const GDALColorEntry *psEndColor);
1414 : bool IsIdentity() const;
1415 :
1416 : static std::unique_ptr<GDALColorTable>
1417 : LoadFromFile(const char *pszFilename);
1418 :
1419 : /** Convert a GDALColorTable* to a GDALRasterBandH.
1420 : * @since GDAL 2.3
1421 : */
1422 1979 : static inline GDALColorTableH ToHandle(GDALColorTable *poCT)
1423 : {
1424 1979 : return static_cast<GDALColorTableH>(poCT);
1425 : }
1426 :
1427 : /** Convert a GDALColorTableH to a GDALColorTable*.
1428 : * @since GDAL 2.3
1429 : */
1430 20666 : static inline GDALColorTable *FromHandle(GDALColorTableH hCT)
1431 : {
1432 20666 : return static_cast<GDALColorTable *>(hCT);
1433 : }
1434 : };
1435 :
1436 : /* ******************************************************************** */
1437 : /* GDALAbstractBandBlockCache */
1438 : /* ******************************************************************** */
1439 :
1440 : //! @cond Doxygen_Suppress
1441 :
1442 : //! This manages how a raster band store its cached block.
1443 : // only used by GDALRasterBand implementation.
1444 :
1445 : class GDALAbstractBandBlockCache
1446 : {
1447 : // List of blocks that can be freed or recycled, and its lock
1448 : CPLLock *hSpinLock = nullptr;
1449 : GDALRasterBlock *psListBlocksToFree = nullptr;
1450 :
1451 : // Band keep alive counter, and its lock & condition
1452 : CPLCond *hCond = nullptr;
1453 : CPLMutex *hCondMutex = nullptr;
1454 : volatile int nKeepAliveCounter = 0;
1455 :
1456 : volatile int m_nDirtyBlocks = 0;
1457 :
1458 : CPL_DISALLOW_COPY_ASSIGN(GDALAbstractBandBlockCache)
1459 :
1460 : protected:
1461 : GDALRasterBand *poBand;
1462 :
1463 : int m_nInitialDirtyBlocksInFlushCache = 0;
1464 : int m_nLastTick = -1;
1465 : size_t m_nWriteDirtyBlocksDisabled = 0;
1466 :
1467 : void FreeDanglingBlocks();
1468 : void UnreferenceBlockBase();
1469 :
1470 : void StartDirtyBlockFlushingLog();
1471 : void UpdateDirtyBlockFlushingLog();
1472 : void EndDirtyBlockFlushingLog();
1473 :
1474 : public:
1475 : explicit GDALAbstractBandBlockCache(GDALRasterBand *poBand);
1476 : virtual ~GDALAbstractBandBlockCache();
1477 :
1478 : GDALRasterBlock *CreateBlock(int nXBlockOff, int nYBlockOff);
1479 : void AddBlockToFreeList(GDALRasterBlock *poBlock);
1480 : void IncDirtyBlocks(int nInc);
1481 : void WaitCompletionPendingTasks();
1482 :
1483 1 : void EnableDirtyBlockWriting()
1484 : {
1485 1 : --m_nWriteDirtyBlocksDisabled;
1486 1 : }
1487 :
1488 2899 : void DisableDirtyBlockWriting()
1489 : {
1490 2899 : ++m_nWriteDirtyBlocksDisabled;
1491 2899 : }
1492 :
1493 0 : bool HasDirtyBlocks() const
1494 : {
1495 0 : return m_nDirtyBlocks > 0;
1496 : }
1497 :
1498 : virtual bool Init() = 0;
1499 : virtual bool IsInitOK() = 0;
1500 : virtual CPLErr FlushCache() = 0;
1501 : virtual CPLErr AdoptBlock(GDALRasterBlock *poBlock) = 0;
1502 : virtual GDALRasterBlock *TryGetLockedBlockRef(int nXBlockOff,
1503 : int nYBlockYOff) = 0;
1504 : virtual CPLErr UnreferenceBlock(GDALRasterBlock *poBlock) = 0;
1505 : virtual CPLErr FlushBlock(int nXBlockOff, int nYBlockOff,
1506 : int bWriteDirtyBlock) = 0;
1507 : };
1508 :
1509 : GDALAbstractBandBlockCache *
1510 : GDALArrayBandBlockCacheCreate(GDALRasterBand *poBand);
1511 : GDALAbstractBandBlockCache *
1512 : GDALHashSetBandBlockCacheCreate(GDALRasterBand *poBand);
1513 :
1514 : //! @endcond
1515 :
1516 : /* ******************************************************************** */
1517 : /* GDALRasterBand */
1518 : /* ******************************************************************** */
1519 :
1520 : class GDALMDArray;
1521 : class GDALDoublePointsCache;
1522 :
1523 : /** Range of values found in a mask band */
1524 : typedef enum
1525 : {
1526 : GMVR_UNKNOWN, /*! Unknown (can also be used for any values between 0 and 255
1527 : for a Byte band) */
1528 : GMVR_0_AND_1_ONLY, /*! Only 0 and 1 */
1529 : GMVR_0_AND_255_ONLY, /*! Only 0 and 255 */
1530 : } GDALMaskValueRange;
1531 :
1532 : /** Suggested/most efficient access pattern to blocks. */
1533 : typedef int GDALSuggestedBlockAccessPattern;
1534 :
1535 : /** Unknown, or no particular read order is suggested. */
1536 : constexpr GDALSuggestedBlockAccessPattern GSBAP_UNKNOWN = 0;
1537 :
1538 : /** Random access to blocks is efficient. */
1539 : constexpr GDALSuggestedBlockAccessPattern GSBAP_RANDOM = 1;
1540 :
1541 : /** Reading by strips from top to bottom is the most efficient. */
1542 : constexpr GDALSuggestedBlockAccessPattern GSBAP_TOP_TO_BOTTOM = 2;
1543 :
1544 : /** Reading by strips from bottom to top is the most efficient. */
1545 : constexpr GDALSuggestedBlockAccessPattern GSBAP_BOTTOM_TO_TOP = 3;
1546 :
1547 : /** Reading the largest chunk from the raster is the most efficient (can be
1548 : * combined with above values). */
1549 : constexpr GDALSuggestedBlockAccessPattern GSBAP_LARGEST_CHUNK_POSSIBLE = 0x100;
1550 :
1551 : /** A single raster band (or channel). */
1552 :
1553 : class CPL_DLL GDALRasterBand : public GDALMajorObject
1554 : {
1555 : private:
1556 : friend class GDALArrayBandBlockCache;
1557 : friend class GDALHashSetBandBlockCache;
1558 : friend class GDALRasterBlock;
1559 : friend class GDALDataset;
1560 :
1561 : CPLErr eFlushBlockErr = CE_None;
1562 : GDALAbstractBandBlockCache *poBandBlockCache = nullptr;
1563 :
1564 : CPL_INTERNAL void SetFlushBlockErr(CPLErr eErr);
1565 : CPL_INTERNAL CPLErr UnreferenceBlock(GDALRasterBlock *poBlock);
1566 : CPL_INTERNAL void IncDirtyBlocks(int nInc);
1567 :
1568 : protected:
1569 : //! @cond Doxygen_Suppress
1570 : GDALDataset *poDS = nullptr;
1571 : int nBand = 0; /* 1 based */
1572 :
1573 : int nRasterXSize = 0;
1574 : int nRasterYSize = 0;
1575 :
1576 : GDALDataType eDataType = GDT_Byte;
1577 : GDALAccess eAccess = GA_ReadOnly;
1578 :
1579 : /* stuff related to blocking, and raster cache */
1580 : int nBlockXSize = -1;
1581 : int nBlockYSize = -1;
1582 : int nBlocksPerRow = 0;
1583 : int nBlocksPerColumn = 0;
1584 :
1585 : int nBlockReads = 0;
1586 : int bForceCachedIO = 0;
1587 :
1588 : class GDALRasterBandOwnedOrNot
1589 : {
1590 : public:
1591 1611440 : GDALRasterBandOwnedOrNot()
1592 1611440 : {
1593 1611290 : }
1594 :
1595 : GDALRasterBandOwnedOrNot(GDALRasterBand *poBand, bool bOwned)
1596 : : m_poBandOwned(bOwned ? poBand : nullptr),
1597 : m_poBandRef(bOwned ? nullptr : poBand)
1598 : {
1599 : }
1600 :
1601 1611610 : void reset()
1602 : {
1603 1611610 : m_poBandOwned.reset();
1604 1611610 : m_poBandRef = nullptr;
1605 1611610 : }
1606 :
1607 95762 : void reset(GDALRasterBand *poBand, bool bOwned)
1608 : {
1609 95762 : m_poBandOwned.reset(bOwned ? poBand : nullptr);
1610 95761 : m_poBandRef = bOwned ? nullptr : poBand;
1611 95761 : }
1612 :
1613 66847 : void reset(std::unique_ptr<GDALRasterBand> poBand)
1614 : {
1615 66847 : m_poBandOwned = std::move(poBand);
1616 66847 : m_poBandRef = nullptr;
1617 66847 : }
1618 :
1619 2 : const GDALRasterBand *get() const
1620 : {
1621 2 : return static_cast<const GDALRasterBand *>(*this);
1622 : }
1623 :
1624 1436680 : GDALRasterBand *get()
1625 : {
1626 1436680 : return static_cast<GDALRasterBand *>(*this);
1627 : }
1628 :
1629 709099 : bool IsOwned() const
1630 : {
1631 709099 : return m_poBandOwned != nullptr;
1632 : }
1633 :
1634 2 : operator const GDALRasterBand *() const
1635 : {
1636 2 : return m_poBandOwned ? m_poBandOwned.get() : m_poBandRef;
1637 : }
1638 :
1639 3096000 : operator GDALRasterBand *()
1640 : {
1641 3096000 : return m_poBandOwned ? m_poBandOwned.get() : m_poBandRef;
1642 : }
1643 :
1644 : private:
1645 : CPL_DISALLOW_COPY_ASSIGN(GDALRasterBandOwnedOrNot)
1646 : std::unique_ptr<GDALRasterBand> m_poBandOwned{};
1647 : GDALRasterBand *m_poBandRef = nullptr;
1648 : };
1649 :
1650 : GDALRasterBandOwnedOrNot poMask{};
1651 : bool m_bEnablePixelTypeSignedByteWarning =
1652 : true; // Remove me in GDAL 4.0. See GetMetadataItem() implementation
1653 : int nMaskFlags = 0;
1654 :
1655 : void InvalidateMaskBand();
1656 :
1657 : friend class GDALProxyRasterBand;
1658 : friend class GDALDefaultOverviews;
1659 :
1660 : CPLErr
1661 : RasterIOResampled(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1662 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
1663 : GDALDataType eBufType, GSpacing nPixelSpace,
1664 : GSpacing nLineSpace,
1665 : GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
1666 :
1667 : int EnterReadWrite(GDALRWFlag eRWFlag);
1668 : void LeaveReadWrite();
1669 : void InitRWLock();
1670 : void SetValidPercent(GUIntBig nSampleCount, GUIntBig nValidCount);
1671 :
1672 : mutable GDALDoublePointsCache *m_poPointsCache = nullptr;
1673 :
1674 : //! @endcond
1675 :
1676 : protected:
1677 : virtual CPLErr IReadBlock(int nBlockXOff, int nBlockYOff, void *pData) = 0;
1678 : virtual CPLErr IWriteBlock(int nBlockXOff, int nBlockYOff, void *pData);
1679 :
1680 : virtual CPLErr
1681 : IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize,
1682 : void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType,
1683 : GSpacing nPixelSpace, GSpacing nLineSpace,
1684 : GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
1685 :
1686 : virtual int IGetDataCoverageStatus(int nXOff, int nYOff, int nXSize,
1687 : int nYSize, int nMaskFlagStop,
1688 : double *pdfDataPct);
1689 :
1690 : virtual bool
1691 : EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const;
1692 :
1693 : //! @cond Doxygen_Suppress
1694 : CPLErr
1695 : OverviewRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1696 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
1697 : GDALDataType eBufType, GSpacing nPixelSpace,
1698 : GSpacing nLineSpace,
1699 : GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
1700 :
1701 : CPLErr TryOverviewRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
1702 : int nXSize, int nYSize, void *pData,
1703 : int nBufXSize, int nBufYSize,
1704 : GDALDataType eBufType, GSpacing nPixelSpace,
1705 : GSpacing nLineSpace,
1706 : GDALRasterIOExtraArg *psExtraArg, int *pbTried);
1707 :
1708 : int InitBlockInfo();
1709 :
1710 : void AddBlockToFreeList(GDALRasterBlock *);
1711 :
1712 2296810 : bool HasBlockCache() const
1713 : {
1714 2296810 : return poBandBlockCache != nullptr;
1715 : }
1716 :
1717 17 : bool HasDirtyBlocks() const
1718 : {
1719 17 : return poBandBlockCache && poBandBlockCache->HasDirtyBlocks();
1720 : }
1721 :
1722 : //! @endcond
1723 :
1724 : public:
1725 : GDALRasterBand();
1726 : explicit GDALRasterBand(int bForceCachedIO);
1727 :
1728 : ~GDALRasterBand() override;
1729 :
1730 : int GetXSize() const;
1731 : int GetYSize() const;
1732 : int GetBand() const;
1733 : GDALDataset *GetDataset() const;
1734 :
1735 : GDALDataType GetRasterDataType(void) const;
1736 : void GetBlockSize(int *pnXSize, int *pnYSize) const;
1737 : CPLErr GetActualBlockSize(int nXBlockOff, int nYBlockOff, int *pnXValid,
1738 : int *pnYValid) const;
1739 :
1740 : virtual GDALSuggestedBlockAccessPattern
1741 : GetSuggestedBlockAccessPattern() const;
1742 :
1743 : GDALAccess GetAccess();
1744 :
1745 : #ifndef DOXYGEN_SKIP
1746 : CPLErr RasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1747 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
1748 : GDALDataType eBufType, GSpacing nPixelSpace,
1749 : GSpacing nLineSpace,
1750 : GDALRasterIOExtraArg *psExtraArg
1751 : OPTIONAL_OUTSIDE_GDAL(nullptr)) CPL_WARN_UNUSED_RESULT;
1752 : #else
1753 : CPLErr RasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1754 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
1755 : GDALDataType eBufType, GSpacing nPixelSpace,
1756 : GSpacing nLineSpace,
1757 : GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
1758 : #endif
1759 :
1760 : template <class T>
1761 : CPLErr ReadRaster(T *pData, size_t nArrayEltCount = 0, double dfXOff = 0,
1762 : double dfYOff = 0, double dfXSize = 0, double dfYSize = 0,
1763 : size_t nBufXSize = 0, size_t nBufYSize = 0,
1764 : GDALRIOResampleAlg eResampleAlg = GRIORA_NearestNeighbour,
1765 : GDALProgressFunc pfnProgress = nullptr,
1766 : void *pProgressData = nullptr) const;
1767 :
1768 : template <class T>
1769 : CPLErr ReadRaster(std::vector<T> &vData, double dfXOff = 0,
1770 : double dfYOff = 0, double dfXSize = 0, double dfYSize = 0,
1771 : size_t nBufXSize = 0, size_t nBufYSize = 0,
1772 : GDALRIOResampleAlg eResampleAlg = GRIORA_NearestNeighbour,
1773 : GDALProgressFunc pfnProgress = nullptr,
1774 : void *pProgressData = nullptr) const;
1775 :
1776 : #if __cplusplus >= 202002L
1777 : //! @cond Doxygen_Suppress
1778 : template <class T>
1779 : inline CPLErr
1780 : ReadRaster(std::span<T> pData, double dfXOff = 0, double dfYOff = 0,
1781 : double dfXSize = 0, double dfYSize = 0, size_t nBufXSize = 0,
1782 : size_t nBufYSize = 0,
1783 : GDALRIOResampleAlg eResampleAlg = GRIORA_NearestNeighbour,
1784 : GDALProgressFunc pfnProgress = nullptr,
1785 : void *pProgressData = nullptr) const
1786 : {
1787 : return ReadRaster(pData.data(), pData.size(), dfXOff, dfYOff, dfXSize,
1788 : dfYSize, nBufXSize, nBufYSize, eResampleAlg,
1789 : pfnProgress, pProgressData);
1790 : }
1791 :
1792 : //! @endcond
1793 : #endif
1794 :
1795 : CPLErr ReadBlock(int nXBlockOff, int nYBlockOff,
1796 : void *pImage) CPL_WARN_UNUSED_RESULT;
1797 :
1798 : CPLErr WriteBlock(int nXBlockOff, int nYBlockOff,
1799 : void *pImage) CPL_WARN_UNUSED_RESULT;
1800 :
1801 : // This method should only be overloaded by GDALProxyRasterBand
1802 : virtual GDALRasterBlock *
1803 : GetLockedBlockRef(int nXBlockOff, int nYBlockOff,
1804 : int bJustInitialize = FALSE) CPL_WARN_UNUSED_RESULT;
1805 :
1806 : // This method should only be overloaded by GDALProxyRasterBand
1807 : virtual GDALRasterBlock *
1808 : TryGetLockedBlockRef(int nXBlockOff,
1809 : int nYBlockYOff) CPL_WARN_UNUSED_RESULT;
1810 :
1811 : // This method should only be overloaded by GDALProxyRasterBand
1812 : virtual CPLErr FlushBlock(int nXBlockOff, int nYBlockOff,
1813 : int bWriteDirtyBlock = TRUE);
1814 :
1815 : unsigned char *
1816 : GetIndexColorTranslationTo(/* const */ GDALRasterBand *poReferenceBand,
1817 : unsigned char *pTranslationTable = nullptr,
1818 : int *pApproximateMatching = nullptr);
1819 :
1820 : // New OpengIS CV_SampleDimension stuff.
1821 :
1822 : virtual CPLErr FlushCache(bool bAtClosing = false);
1823 : virtual CPLErr DropCache();
1824 : virtual char **GetCategoryNames();
1825 : virtual double GetNoDataValue(int *pbSuccess = nullptr);
1826 : virtual int64_t GetNoDataValueAsInt64(int *pbSuccess = nullptr);
1827 : virtual uint64_t GetNoDataValueAsUInt64(int *pbSuccess = nullptr);
1828 : virtual double GetMinimum(int *pbSuccess = nullptr);
1829 : virtual double GetMaximum(int *pbSuccess = nullptr);
1830 : virtual double GetOffset(int *pbSuccess = nullptr);
1831 : virtual double GetScale(int *pbSuccess = nullptr);
1832 : virtual const char *GetUnitType();
1833 : virtual GDALColorInterp GetColorInterpretation();
1834 : virtual GDALColorTable *GetColorTable();
1835 : virtual CPLErr Fill(double dfRealValue, double dfImaginaryValue = 0);
1836 :
1837 : virtual CPLErr SetCategoryNames(char **papszNames);
1838 : virtual CPLErr SetNoDataValue(double dfNoData);
1839 : virtual CPLErr SetNoDataValueAsInt64(int64_t nNoData);
1840 : virtual CPLErr SetNoDataValueAsUInt64(uint64_t nNoData);
1841 : CPLErr SetNoDataValueAsString(const char *pszNoData,
1842 : bool *pbCannotBeExactlyRepresented = nullptr);
1843 : virtual CPLErr DeleteNoDataValue();
1844 : virtual CPLErr SetColorTable(GDALColorTable *poCT);
1845 : virtual CPLErr SetColorInterpretation(GDALColorInterp eColorInterp);
1846 : virtual CPLErr SetOffset(double dfNewOffset);
1847 : virtual CPLErr SetScale(double dfNewScale);
1848 : virtual CPLErr SetUnitType(const char *pszNewValue);
1849 :
1850 : virtual CPLErr GetStatistics(int bApproxOK, int bForce, double *pdfMin,
1851 : double *pdfMax, double *pdfMean,
1852 : double *padfStdDev);
1853 : virtual CPLErr ComputeStatistics(int bApproxOK, double *pdfMin,
1854 : double *pdfMax, double *pdfMean,
1855 : double *pdfStdDev, GDALProgressFunc,
1856 : void *pProgressData);
1857 : virtual CPLErr SetStatistics(double dfMin, double dfMax, double dfMean,
1858 : double dfStdDev);
1859 : virtual CPLErr ComputeRasterMinMax(int bApproxOK, double *adfMinMax);
1860 : virtual CPLErr ComputeRasterMinMaxLocation(double *pdfMin, double *pdfMax,
1861 : int *pnMinX, int *pnMinY,
1862 : int *pnMaxX, int *pnMaxY);
1863 :
1864 : // Only defined when Doxygen enabled
1865 : #ifdef DOXYGEN_SKIP
1866 : CPLErr SetMetadata(char **papszMetadata, const char *pszDomain) override;
1867 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
1868 : const char *pszDomain) override;
1869 : #endif
1870 : virtual const char *GetMetadataItem(const char *pszName,
1871 : const char *pszDomain = "") override;
1872 :
1873 : virtual int HasArbitraryOverviews();
1874 : virtual int GetOverviewCount();
1875 : virtual GDALRasterBand *GetOverview(int i);
1876 : virtual GDALRasterBand *GetRasterSampleOverview(GUIntBig);
1877 : virtual CPLErr BuildOverviews(const char *pszResampling, int nOverviews,
1878 : const int *panOverviewList,
1879 : GDALProgressFunc pfnProgress,
1880 : void *pProgressData,
1881 : CSLConstList papszOptions);
1882 :
1883 : virtual CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize,
1884 : int nBufXSize, int nBufYSize,
1885 : GDALDataType eBufType, char **papszOptions);
1886 :
1887 : virtual CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets,
1888 : GUIntBig *panHistogram, int bIncludeOutOfRange,
1889 : int bApproxOK, GDALProgressFunc,
1890 : void *pProgressData);
1891 :
1892 : virtual CPLErr GetDefaultHistogram(double *pdfMin, double *pdfMax,
1893 : int *pnBuckets, GUIntBig **ppanHistogram,
1894 : int bForce, GDALProgressFunc,
1895 : void *pProgressData);
1896 : virtual CPLErr SetDefaultHistogram(double dfMin, double dfMax, int nBuckets,
1897 : GUIntBig *panHistogram);
1898 :
1899 : virtual GDALRasterAttributeTable *GetDefaultRAT();
1900 : virtual CPLErr SetDefaultRAT(const GDALRasterAttributeTable *poRAT);
1901 :
1902 : virtual GDALRasterBand *GetMaskBand();
1903 : virtual int GetMaskFlags();
1904 : virtual CPLErr CreateMaskBand(int nFlagsIn);
1905 : virtual bool IsMaskBand() const;
1906 : virtual GDALMaskValueRange GetMaskValueRange() const;
1907 :
1908 : virtual CPLVirtualMem *
1909 : GetVirtualMemAuto(GDALRWFlag eRWFlag, int *pnPixelSpace,
1910 : GIntBig *pnLineSpace,
1911 : char **papszOptions) CPL_WARN_UNUSED_RESULT;
1912 :
1913 : int GetDataCoverageStatus(int nXOff, int nYOff, int nXSize, int nYSize,
1914 : int nMaskFlagStop = 0,
1915 : double *pdfDataPct = nullptr);
1916 :
1917 : std::shared_ptr<GDALMDArray> AsMDArray() const;
1918 :
1919 : CPLErr InterpolateAtGeolocation(
1920 : double dfGeolocX, double dfGeolocY, const OGRSpatialReference *poSRS,
1921 : GDALRIOResampleAlg eInterpolation, double *pdfRealValue,
1922 : double *pdfImagValue = nullptr,
1923 : CSLConstList papszTransformerOptions = nullptr) const;
1924 :
1925 : virtual CPLErr InterpolateAtPoint(double dfPixel, double dfLine,
1926 : GDALRIOResampleAlg eInterpolation,
1927 : double *pdfRealValue,
1928 : double *pdfImagValue = nullptr) const;
1929 :
1930 : #ifndef DOXYGEN_XML
1931 : void ReportError(CPLErr eErrClass, CPLErrorNum err_no, const char *fmt,
1932 : ...) const CPL_PRINT_FUNC_FORMAT(4, 5);
1933 : #endif
1934 :
1935 : /** Convert a GDALRasterBand* to a GDALRasterBandH.
1936 : * @since GDAL 2.3
1937 : */
1938 321987 : static inline GDALRasterBandH ToHandle(GDALRasterBand *poBand)
1939 : {
1940 321987 : return static_cast<GDALRasterBandH>(poBand);
1941 : }
1942 :
1943 : /** Convert a GDALRasterBandH to a GDALRasterBand*.
1944 : * @since GDAL 2.3
1945 : */
1946 5159786 : static inline GDALRasterBand *FromHandle(GDALRasterBandH hBand)
1947 : {
1948 5159786 : return static_cast<GDALRasterBand *>(hBand);
1949 : }
1950 :
1951 : //! @cond Doxygen_Suppress
1952 : // Remove me in GDAL 4.0. See GetMetadataItem() implementation
1953 : // Internal use in GDAL only !
1954 : virtual void EnablePixelTypeSignedByteWarning(bool b)
1955 : #ifndef GDAL_COMPILATION
1956 : CPL_WARN_DEPRECATED("Do not use that method outside of GDAL!")
1957 : #endif
1958 : ;
1959 :
1960 : //! @endcond
1961 :
1962 : private:
1963 : CPL_DISALLOW_COPY_ASSIGN(GDALRasterBand)
1964 : };
1965 :
1966 : //! @cond Doxygen_Suppress
1967 : #define GDAL_EXTERN_TEMPLATE_READ_RASTER(T) \
1968 : extern template CPLErr GDALRasterBand::ReadRaster<T>( \
1969 : T * pData, size_t nArrayEltCount, double dfXOff, double dfYOff, \
1970 : double dfXSize, double dfYSize, size_t nBufXSize, size_t nBufYSize, \
1971 : GDALRIOResampleAlg eResampleAlg, GDALProgressFunc pfnProgress, \
1972 : void *pProgressData) const;
1973 :
1974 : GDAL_EXTERN_TEMPLATE_READ_RASTER(uint8_t)
1975 : GDAL_EXTERN_TEMPLATE_READ_RASTER(int8_t)
1976 : GDAL_EXTERN_TEMPLATE_READ_RASTER(uint16_t)
1977 : GDAL_EXTERN_TEMPLATE_READ_RASTER(int16_t)
1978 : GDAL_EXTERN_TEMPLATE_READ_RASTER(uint32_t)
1979 : GDAL_EXTERN_TEMPLATE_READ_RASTER(int32_t)
1980 : GDAL_EXTERN_TEMPLATE_READ_RASTER(uint64_t)
1981 : GDAL_EXTERN_TEMPLATE_READ_RASTER(int64_t)
1982 : GDAL_EXTERN_TEMPLATE_READ_RASTER(float)
1983 : GDAL_EXTERN_TEMPLATE_READ_RASTER(double)
1984 : // Not allowed by C++ standard
1985 : // GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<int16_t>)
1986 : // GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<int32_t>)
1987 : GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<float>)
1988 : GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<double>)
1989 :
1990 : #define GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(T) \
1991 : extern template CPLErr GDALRasterBand::ReadRaster<T>( \
1992 : std::vector<T> & vData, double dfXOff, double dfYOff, double dfXSize, \
1993 : double dfYSize, size_t nBufXSize, size_t nBufYSize, \
1994 : GDALRIOResampleAlg eResampleAlg, GDALProgressFunc pfnProgress, \
1995 : void *pProgressData) const;
1996 :
1997 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint8_t)
1998 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int8_t)
1999 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint16_t)
2000 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int16_t)
2001 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint32_t)
2002 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int32_t)
2003 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint64_t)
2004 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int64_t)
2005 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(float)
2006 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(double)
2007 : // Not allowed by C++ standard
2008 : // GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<int16_t>)
2009 : // GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<int32_t>)
2010 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<float>)
2011 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<double>)
2012 :
2013 : //! @endcond
2014 :
2015 : //! @cond Doxygen_Suppress
2016 : /* ******************************************************************** */
2017 : /* GDALAllValidMaskBand */
2018 : /* ******************************************************************** */
2019 :
2020 318462 : class CPL_DLL GDALAllValidMaskBand : public GDALRasterBand
2021 : {
2022 : protected:
2023 : CPLErr IReadBlock(int, int, void *) override;
2024 :
2025 : CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
2026 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
2027 : GDALDataType eBufType, GSpacing nPixelSpace,
2028 : GSpacing nLineSpace,
2029 : GDALRasterIOExtraArg *psExtraArg) override;
2030 :
2031 : bool
2032 : EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2033 :
2034 : CPL_DISALLOW_COPY_ASSIGN(GDALAllValidMaskBand)
2035 :
2036 : public:
2037 : explicit GDALAllValidMaskBand(GDALRasterBand *);
2038 : ~GDALAllValidMaskBand() override;
2039 :
2040 : GDALRasterBand *GetMaskBand() override;
2041 : int GetMaskFlags() override;
2042 :
2043 1 : bool IsMaskBand() const override
2044 : {
2045 1 : return true;
2046 : }
2047 :
2048 0 : GDALMaskValueRange GetMaskValueRange() const override
2049 : {
2050 0 : return GMVR_0_AND_255_ONLY;
2051 : }
2052 :
2053 : CPLErr ComputeStatistics(int bApproxOK, double *pdfMin, double *pdfMax,
2054 : double *pdfMean, double *pdfStdDev,
2055 : GDALProgressFunc, void *pProgressData) override;
2056 : };
2057 :
2058 : /* ******************************************************************** */
2059 : /* GDALNoDataMaskBand */
2060 : /* ******************************************************************** */
2061 :
2062 2116 : class CPL_DLL GDALNoDataMaskBand : public GDALRasterBand
2063 : {
2064 : friend class GDALRasterBand;
2065 : double m_dfNoDataValue = 0;
2066 : int64_t m_nNoDataValueInt64 = 0;
2067 : uint64_t m_nNoDataValueUInt64 = 0;
2068 : GDALRasterBand *m_poParent = nullptr;
2069 :
2070 : CPL_DISALLOW_COPY_ASSIGN(GDALNoDataMaskBand)
2071 :
2072 : protected:
2073 : CPLErr IReadBlock(int, int, void *) override;
2074 : CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
2075 : GDALDataType, GSpacing, GSpacing,
2076 : GDALRasterIOExtraArg *psExtraArg) override;
2077 :
2078 : bool
2079 : EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2080 :
2081 : public:
2082 : explicit GDALNoDataMaskBand(GDALRasterBand *);
2083 : explicit GDALNoDataMaskBand(GDALRasterBand *, double dfNoDataValue);
2084 : ~GDALNoDataMaskBand() override;
2085 :
2086 1 : bool IsMaskBand() const override
2087 : {
2088 1 : return true;
2089 : }
2090 :
2091 0 : GDALMaskValueRange GetMaskValueRange() const override
2092 : {
2093 0 : return GMVR_0_AND_255_ONLY;
2094 : }
2095 :
2096 : static bool IsNoDataInRange(double dfNoDataValue, GDALDataType eDataType);
2097 : };
2098 :
2099 : /* ******************************************************************** */
2100 : /* GDALNoDataValuesMaskBand */
2101 : /* ******************************************************************** */
2102 :
2103 : class CPL_DLL GDALNoDataValuesMaskBand : public GDALRasterBand
2104 : {
2105 : double *padfNodataValues;
2106 :
2107 : CPL_DISALLOW_COPY_ASSIGN(GDALNoDataValuesMaskBand)
2108 :
2109 : protected:
2110 : CPLErr IReadBlock(int, int, void *) override;
2111 :
2112 : bool
2113 : EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2114 :
2115 : public:
2116 : explicit GDALNoDataValuesMaskBand(GDALDataset *);
2117 : ~GDALNoDataValuesMaskBand() override;
2118 :
2119 0 : bool IsMaskBand() const override
2120 : {
2121 0 : return true;
2122 : }
2123 :
2124 0 : GDALMaskValueRange GetMaskValueRange() const override
2125 : {
2126 0 : return GMVR_0_AND_255_ONLY;
2127 : }
2128 : };
2129 :
2130 : /* ******************************************************************** */
2131 : /* GDALRescaledAlphaBand */
2132 : /* ******************************************************************** */
2133 :
2134 : class GDALRescaledAlphaBand : public GDALRasterBand
2135 : {
2136 : GDALRasterBand *poParent;
2137 : void *pTemp;
2138 :
2139 : CPL_DISALLOW_COPY_ASSIGN(GDALRescaledAlphaBand)
2140 :
2141 : protected:
2142 : CPLErr IReadBlock(int, int, void *) override;
2143 : CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
2144 : GDALDataType, GSpacing, GSpacing,
2145 : GDALRasterIOExtraArg *psExtraArg) override;
2146 :
2147 : bool
2148 : EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2149 :
2150 : public:
2151 : explicit GDALRescaledAlphaBand(GDALRasterBand *);
2152 : ~GDALRescaledAlphaBand() override;
2153 :
2154 0 : bool IsMaskBand() const override
2155 : {
2156 0 : return true;
2157 : }
2158 : };
2159 :
2160 : //! @endcond
2161 :
2162 : /* ******************************************************************** */
2163 : /* GDALIdentifyEnum */
2164 : /* ******************************************************************** */
2165 :
2166 : /**
2167 : * Enumeration used by GDALDriver::pfnIdentify().
2168 : *
2169 : * @since GDAL 2.1
2170 : */
2171 : typedef enum
2172 : {
2173 : /** Identify could not determine if the file is recognized or not by the
2174 : probed driver. */
2175 : GDAL_IDENTIFY_UNKNOWN = -1,
2176 : /** Identify determined the file is not recognized by the probed driver. */
2177 : GDAL_IDENTIFY_FALSE = 0,
2178 : /** Identify determined the file is recognized by the probed driver. */
2179 : GDAL_IDENTIFY_TRUE = 1
2180 : } GDALIdentifyEnum;
2181 :
2182 : /* ******************************************************************** */
2183 : /* GDALDriver */
2184 : /* ******************************************************************** */
2185 :
2186 : /**
2187 : * \brief Format specific driver.
2188 : *
2189 : * An instance of this class is created for each supported format, and
2190 : * manages information about the format.
2191 : *
2192 : * This roughly corresponds to a file format, though some
2193 : * drivers may be gateways to many formats through a secondary
2194 : * multi-library.
2195 : */
2196 :
2197 356203 : class CPL_DLL GDALDriver : public GDALMajorObject
2198 : {
2199 : public:
2200 : GDALDriver();
2201 : ~GDALDriver() override;
2202 :
2203 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
2204 : const char *pszDomain = "") override;
2205 :
2206 : /* -------------------------------------------------------------------- */
2207 : /* Public C++ methods. */
2208 : /* -------------------------------------------------------------------- */
2209 : GDALDataset *Create(const char *pszName, int nXSize, int nYSize, int nBands,
2210 : GDALDataType eType,
2211 : CSLConstList papszOptions) CPL_WARN_UNUSED_RESULT;
2212 :
2213 : GDALDataset *
2214 : CreateMultiDimensional(const char *pszName,
2215 : CSLConstList papszRootGroupOptions,
2216 : CSLConstList papszOptions) CPL_WARN_UNUSED_RESULT;
2217 :
2218 : CPLErr Delete(const char *pszName);
2219 : CPLErr Rename(const char *pszNewName, const char *pszOldName);
2220 : CPLErr CopyFiles(const char *pszNewName, const char *pszOldName);
2221 :
2222 : GDALDataset *CreateCopy(const char *, GDALDataset *, int,
2223 : CSLConstList papszOptions,
2224 : GDALProgressFunc pfnProgress,
2225 : void *pProgressData) CPL_WARN_UNUSED_RESULT;
2226 :
2227 : bool CanVectorTranslateFrom(const char *pszDestName,
2228 : GDALDataset *poSourceDS,
2229 : CSLConstList papszVectorTranslateArguments,
2230 : char ***ppapszFailureReasons);
2231 :
2232 : /**
2233 : * \brief Returns TRUE if the given open option is supported by the driver.
2234 : * @param pszOpenOptionName name of the open option to be checked
2235 : * @return TRUE if the driver supports the open option
2236 : * @since GDAL 3.11
2237 : */
2238 : bool HasOpenOption(const char *pszOpenOptionName) const;
2239 :
2240 : GDALDataset *
2241 : VectorTranslateFrom(const char *pszDestName, GDALDataset *poSourceDS,
2242 : CSLConstList papszVectorTranslateArguments,
2243 : GDALProgressFunc pfnProgress,
2244 : void *pProgressData) CPL_WARN_UNUSED_RESULT;
2245 :
2246 : /* -------------------------------------------------------------------- */
2247 : /* The following are semiprivate, not intended to be accessed */
2248 : /* by anyone but the formats instantiating and populating the */
2249 : /* drivers. */
2250 : /* -------------------------------------------------------------------- */
2251 : //! @cond Doxygen_Suppress
2252 :
2253 : // Not aimed at being used outside of GDAL. Use GDALDataset::Open() instead
2254 : GDALDataset *Open(GDALOpenInfo *poOpenInfo, bool bSetOpenOptions);
2255 :
2256 : typedef GDALDataset *(*OpenCallback)(GDALOpenInfo *);
2257 :
2258 : OpenCallback pfnOpen = nullptr;
2259 :
2260 434276 : virtual OpenCallback GetOpenCallback()
2261 : {
2262 434276 : return pfnOpen;
2263 : }
2264 :
2265 : typedef GDALDataset *(*CreateCallback)(const char *pszName, int nXSize,
2266 : int nYSize, int nBands,
2267 : GDALDataType eType,
2268 : char **papszOptions);
2269 :
2270 : CreateCallback pfnCreate = nullptr;
2271 :
2272 21862 : virtual CreateCallback GetCreateCallback()
2273 : {
2274 21862 : return pfnCreate;
2275 : }
2276 :
2277 : GDALDataset *(*pfnCreateEx)(GDALDriver *, const char *pszName, int nXSize,
2278 : int nYSize, int nBands, GDALDataType eType,
2279 : char **papszOptions) = nullptr;
2280 :
2281 : typedef GDALDataset *(*CreateMultiDimensionalCallback)(
2282 : const char *pszName, CSLConstList papszRootGroupOptions,
2283 : CSLConstList papszOptions);
2284 :
2285 : CreateMultiDimensionalCallback pfnCreateMultiDimensional = nullptr;
2286 :
2287 465 : virtual CreateMultiDimensionalCallback GetCreateMultiDimensionalCallback()
2288 : {
2289 465 : return pfnCreateMultiDimensional;
2290 : }
2291 :
2292 : typedef CPLErr (*DeleteCallback)(const char *pszName);
2293 : DeleteCallback pfnDelete = nullptr;
2294 :
2295 5446 : virtual DeleteCallback GetDeleteCallback()
2296 : {
2297 5446 : return pfnDelete;
2298 : }
2299 :
2300 : typedef GDALDataset *(*CreateCopyCallback)(const char *, GDALDataset *, int,
2301 : char **,
2302 : GDALProgressFunc pfnProgress,
2303 : void *pProgressData);
2304 :
2305 : CreateCopyCallback pfnCreateCopy = nullptr;
2306 :
2307 11051 : virtual CreateCopyCallback GetCreateCopyCallback()
2308 : {
2309 11051 : return pfnCreateCopy;
2310 : }
2311 :
2312 : void *pDriverData = nullptr;
2313 :
2314 : void (*pfnUnloadDriver)(GDALDriver *) = nullptr;
2315 :
2316 : /** Identify() if the file is recognized or not by the driver.
2317 :
2318 : Return GDAL_IDENTIFY_TRUE (1) if the passed file is certainly recognized
2319 : by the driver. Return GDAL_IDENTIFY_FALSE (0) if the passed file is
2320 : certainly NOT recognized by the driver. Return GDAL_IDENTIFY_UNKNOWN (-1)
2321 : if the passed file may be or may not be recognized by the driver, and
2322 : that a potentially costly test must be done with pfnOpen.
2323 : */
2324 : int (*pfnIdentify)(GDALOpenInfo *) = nullptr;
2325 : int (*pfnIdentifyEx)(GDALDriver *, GDALOpenInfo *) = nullptr;
2326 :
2327 : typedef CPLErr (*RenameCallback)(const char *pszNewName,
2328 : const char *pszOldName);
2329 : RenameCallback pfnRename = nullptr;
2330 :
2331 175 : virtual RenameCallback GetRenameCallback()
2332 : {
2333 175 : return pfnRename;
2334 : }
2335 :
2336 : typedef CPLErr (*CopyFilesCallback)(const char *pszNewName,
2337 : const char *pszOldName);
2338 : CopyFilesCallback pfnCopyFiles = nullptr;
2339 :
2340 12 : virtual CopyFilesCallback GetCopyFilesCallback()
2341 : {
2342 12 : return pfnCopyFiles;
2343 : }
2344 :
2345 : // Used for legacy OGR drivers, and Python drivers
2346 : GDALDataset *(*pfnOpenWithDriverArg)(GDALDriver *,
2347 : GDALOpenInfo *) = nullptr;
2348 :
2349 : /* For legacy OGR drivers */
2350 : GDALDataset *(*pfnCreateVectorOnly)(GDALDriver *, const char *pszName,
2351 : char **papszOptions) = nullptr;
2352 : CPLErr (*pfnDeleteDataSource)(GDALDriver *, const char *pszName) = nullptr;
2353 :
2354 : /** Whether pfnVectorTranslateFrom() can be run given the source dataset
2355 : * and the non-positional arguments of GDALVectorTranslate() stored
2356 : * in papszVectorTranslateArguments.
2357 : */
2358 : bool (*pfnCanVectorTranslateFrom)(
2359 : const char *pszDestName, GDALDataset *poSourceDS,
2360 : CSLConstList papszVectorTranslateArguments,
2361 : char ***ppapszFailureReasons) = nullptr;
2362 :
2363 : /** Creates a copy from the specified source dataset, using the
2364 : * non-positional arguments of GDALVectorTranslate() stored
2365 : * in papszVectorTranslateArguments.
2366 : */
2367 : GDALDataset *(*pfnVectorTranslateFrom)(
2368 : const char *pszDestName, GDALDataset *poSourceDS,
2369 : CSLConstList papszVectorTranslateArguments,
2370 : GDALProgressFunc pfnProgress, void *pProgressData) = nullptr;
2371 :
2372 : /**
2373 : * Returns a (possibly null) pointer to the Subdataset informational function
2374 : * from the subdataset file name.
2375 : */
2376 : GDALSubdatasetInfo *(*pfnGetSubdatasetInfoFunc)(const char *pszFileName) =
2377 : nullptr;
2378 :
2379 : typedef GDALAlgorithm *(*InstantiateAlgorithmCallback)(
2380 : const std::vector<std::string> &aosPath);
2381 : InstantiateAlgorithmCallback pfnInstantiateAlgorithm = nullptr;
2382 :
2383 56 : virtual InstantiateAlgorithmCallback GetInstantiateAlgorithmCallback()
2384 : {
2385 56 : return pfnInstantiateAlgorithm;
2386 : }
2387 :
2388 : /** Instantiate an algorithm by its full path (omitting leading "gdal").
2389 : * For example {"driver", "pdf", "list-layers"}
2390 : */
2391 : GDALAlgorithm *
2392 : InstantiateAlgorithm(const std::vector<std::string> &aosPath);
2393 :
2394 : /** Declare an algorithm by its full path (omitting leading "gdal").
2395 : * For example {"driver", "pdf", "list-layers"}
2396 : */
2397 : void DeclareAlgorithm(const std::vector<std::string> &aosPath);
2398 :
2399 : //! @endcond
2400 :
2401 : /* -------------------------------------------------------------------- */
2402 : /* Helper methods. */
2403 : /* -------------------------------------------------------------------- */
2404 : //! @cond Doxygen_Suppress
2405 : GDALDataset *DefaultCreateCopy(const char *, GDALDataset *, int,
2406 : CSLConstList papszOptions,
2407 : GDALProgressFunc pfnProgress,
2408 : void *pProgressData) CPL_WARN_UNUSED_RESULT;
2409 :
2410 : static CPLErr DefaultCreateCopyMultiDimensional(
2411 : GDALDataset *poSrcDS, GDALDataset *poDstDS, bool bStrict,
2412 : CSLConstList /*papszOptions*/, GDALProgressFunc pfnProgress,
2413 : void *pProgressData);
2414 :
2415 : static CPLErr DefaultCopyMasks(GDALDataset *poSrcDS, GDALDataset *poDstDS,
2416 : int bStrict);
2417 : static CPLErr DefaultCopyMasks(GDALDataset *poSrcDS, GDALDataset *poDstDS,
2418 : int bStrict, CSLConstList papszOptions,
2419 : GDALProgressFunc pfnProgress,
2420 : void *pProgressData);
2421 :
2422 : CPLErr QuietDeleteForCreateCopy(const char *pszFilename,
2423 : GDALDataset *poSrcDS);
2424 :
2425 : //! @endcond
2426 : static CPLErr QuietDelete(const char *pszName,
2427 : CSLConstList papszAllowedDrivers = nullptr);
2428 :
2429 : //! @cond Doxygen_Suppress
2430 : static CPLErr DefaultRename(const char *pszNewName, const char *pszOldName);
2431 : static CPLErr DefaultCopyFiles(const char *pszNewName,
2432 : const char *pszOldName);
2433 : static void DefaultCopyMetadata(GDALDataset *poSrcDS, GDALDataset *poDstDS,
2434 : CSLConstList papszOptions,
2435 : CSLConstList papszExcludedDomains);
2436 :
2437 : //! @endcond
2438 :
2439 : /** Convert a GDALDriver* to a GDALDriverH.
2440 : * @since GDAL 2.3
2441 : */
2442 166198 : static inline GDALDriverH ToHandle(GDALDriver *poDriver)
2443 : {
2444 166198 : return static_cast<GDALDriverH>(poDriver);
2445 : }
2446 :
2447 : /** Convert a GDALDriverH to a GDALDriver*.
2448 : * @since GDAL 2.3
2449 : */
2450 3768684 : static inline GDALDriver *FromHandle(GDALDriverH hDriver)
2451 : {
2452 3768684 : return static_cast<GDALDriver *>(hDriver);
2453 : }
2454 :
2455 : private:
2456 : CPL_DISALLOW_COPY_ASSIGN(GDALDriver)
2457 : };
2458 :
2459 : /************************************************************************/
2460 : /* GDALPluginDriverProxy */
2461 : /************************************************************************/
2462 :
2463 : // clang-format off
2464 : /** Proxy for a plugin driver.
2465 : *
2466 : * Such proxy must be registered with
2467 : * GDALDriverManager::DeclareDeferredPluginDriver().
2468 : *
2469 : * If the real driver defines any of the following metadata items, the
2470 : * proxy driver should also define them with the same value:
2471 : * <ul>
2472 : * <li>GDAL_DMD_LONGNAME</li>
2473 : * <li>GDAL_DMD_EXTENSIONS</li>
2474 : * <li>GDAL_DMD_EXTENSION</li>
2475 : * <li>GDAL_DMD_OPENOPTIONLIST</li>
2476 : * <li>GDAL_DMD_SUBDATASETS</li>
2477 : * <li>GDAL_DMD_CONNECTION_PREFIX</li>
2478 : * <li>GDAL_DCAP_RASTER</li>
2479 : * <li>GDAL_DCAP_MULTIDIM_RASTER</li>
2480 : * <li>GDAL_DCAP_VECTOR</li>
2481 : * <li>GDAL_DCAP_GNM</li>
2482 : * <li>GDAL_DCAP_MULTIPLE_VECTOR_LAYERS</li>
2483 : * <li>GDAL_DCAP_NONSPATIAL</li>
2484 : * <li>GDAL_DCAP_VECTOR_TRANSLATE_FROM</li>
2485 : * </ul>
2486 : *
2487 : * The pfnIdentify and pfnGetSubdatasetInfoFunc callbacks, if they are
2488 : * defined in the real driver, should also be set on the proxy driver.
2489 : *
2490 : * Furthermore, the following metadata items must be defined if the real
2491 : * driver sets the corresponding callback:
2492 : * <ul>
2493 : * <li>GDAL_DCAP_OPEN: must be set to YES if the real driver defines pfnOpen</li>
2494 : * <li>GDAL_DCAP_CREATE: must be set to YES if the real driver defines pfnCreate</li>
2495 : * <li>GDAL_DCAP_CREATE_MULTIDIMENSIONAL: must be set to YES if the real driver defines pfnCreateMultiDimensional</li>
2496 : * <li>GDAL_DCAP_CREATECOPY: must be set to YES if the real driver defines pfnCreateCopy</li>
2497 : * </ul>
2498 : *
2499 : * @since 3.9
2500 : */
2501 : // clang-format on
2502 :
2503 : class GDALPluginDriverProxy : public GDALDriver
2504 : {
2505 : const std::string m_osPluginFileName;
2506 : std::string m_osPluginFullPath{};
2507 : std::unique_ptr<GDALDriver> m_poRealDriver{};
2508 : std::set<std::string> m_oSetMetadataItems{};
2509 :
2510 : GDALDriver *GetRealDriver();
2511 :
2512 : CPL_DISALLOW_COPY_ASSIGN(GDALPluginDriverProxy)
2513 :
2514 : protected:
2515 : friend class GDALDriverManager;
2516 :
2517 : //! @cond Doxygen_Suppress
2518 70708 : void SetPluginFullPath(const std::string &osFullPath)
2519 : {
2520 70708 : m_osPluginFullPath = osFullPath;
2521 70708 : }
2522 :
2523 : //! @endcond
2524 :
2525 : public:
2526 : explicit GDALPluginDriverProxy(const std::string &osPluginFileName);
2527 :
2528 : /** Return the plugin file name (not a full path) */
2529 70708 : const std::string &GetPluginFileName() const
2530 : {
2531 70708 : return m_osPluginFileName;
2532 : }
2533 :
2534 : //! @cond Doxygen_Suppress
2535 : OpenCallback GetOpenCallback() override;
2536 :
2537 : CreateCallback GetCreateCallback() override;
2538 :
2539 : CreateMultiDimensionalCallback GetCreateMultiDimensionalCallback() override;
2540 :
2541 : CreateCopyCallback GetCreateCopyCallback() override;
2542 :
2543 : DeleteCallback GetDeleteCallback() override;
2544 :
2545 : RenameCallback GetRenameCallback() override;
2546 :
2547 : CopyFilesCallback GetCopyFilesCallback() override;
2548 :
2549 : InstantiateAlgorithmCallback GetInstantiateAlgorithmCallback() override;
2550 : //! @endcond
2551 :
2552 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
2553 : const char *pszDomain = "") override;
2554 :
2555 : char **GetMetadata(const char *pszDomain) override;
2556 :
2557 : const char *GetMetadataItem(const char *pszName,
2558 : const char *pszDomain = "") override;
2559 : };
2560 :
2561 : /* ******************************************************************** */
2562 : /* GDALDriverManager */
2563 : /* ******************************************************************** */
2564 :
2565 : /**
2566 : * Class for managing the registration of file format drivers.
2567 : *
2568 : * Use GetGDALDriverManager() to fetch the global singleton instance of
2569 : * this class.
2570 : */
2571 :
2572 : class CPL_DLL GDALDriverManager : public GDALMajorObject
2573 : {
2574 : int nDrivers = 0;
2575 : GDALDriver **papoDrivers = nullptr;
2576 : std::map<CPLString, GDALDriver *> oMapNameToDrivers{};
2577 : std::string m_osPluginPath{};
2578 : std::string m_osDriversIniPath{};
2579 : mutable std::string m_osLastTriedDirectory{};
2580 : std::set<std::string> m_oSetPluginFileNames{};
2581 : bool m_bInDeferredDriverLoading = false;
2582 : std::map<std::string, std::unique_ptr<GDALDriver>> m_oMapRealDrivers{};
2583 : std::vector<std::unique_ptr<GDALDriver>> m_aoHiddenDrivers{};
2584 :
2585 19512300 : GDALDriver *GetDriver_unlocked(int iDriver)
2586 : {
2587 19512300 : return (iDriver >= 0 && iDriver < nDrivers) ? papoDrivers[iDriver]
2588 19512300 : : nullptr;
2589 : }
2590 :
2591 : GDALDriver *GetDriverByName_unlocked(const char *pszName) const;
2592 :
2593 : static void CleanupPythonDrivers();
2594 :
2595 : std::string GetPluginFullPath(const char *pszFilename) const;
2596 :
2597 : int RegisterDriver(GDALDriver *, bool bHidden);
2598 :
2599 : CPL_DISALLOW_COPY_ASSIGN(GDALDriverManager)
2600 :
2601 : protected:
2602 : friend class GDALPluginDriverProxy;
2603 : friend GDALDatasetH CPL_STDCALL
2604 : GDALOpenEx(const char *pszFilename, unsigned int nOpenFlags,
2605 : const char *const *papszAllowedDrivers,
2606 : const char *const *papszOpenOptions,
2607 : const char *const *papszSiblingFiles);
2608 :
2609 : //! @cond Doxygen_Suppress
2610 : static char **GetSearchPaths(const char *pszGDAL_DRIVER_PATH);
2611 : //! @endcond
2612 :
2613 : public:
2614 : GDALDriverManager();
2615 : ~GDALDriverManager();
2616 :
2617 : int GetDriverCount(void) const;
2618 : GDALDriver *GetDriver(int);
2619 : GDALDriver *GetDriverByName(const char *);
2620 :
2621 : int RegisterDriver(GDALDriver *);
2622 : void DeregisterDriver(GDALDriver *);
2623 :
2624 : // AutoLoadDrivers is a no-op if compiled with GDAL_NO_AUTOLOAD defined.
2625 : void AutoLoadDrivers();
2626 : void AutoSkipDrivers();
2627 : void ReorderDrivers();
2628 : static CPLErr LoadPlugin(const char *name);
2629 :
2630 : static void AutoLoadPythonDrivers();
2631 :
2632 : void DeclareDeferredPluginDriver(GDALPluginDriverProxy *poProxyDriver);
2633 :
2634 : //! @cond Doxygen_Suppress
2635 : int GetDriverCount(bool bIncludeHidden) const;
2636 : GDALDriver *GetDriver(int iDriver, bool bIncludeHidden);
2637 : bool IsKnownDriver(const char *pszDriverName) const;
2638 : GDALDriver *GetHiddenDriverByName(const char *pszName);
2639 : //! @endcond
2640 : };
2641 :
2642 : CPL_C_START
2643 : GDALDriverManager CPL_DLL *GetGDALDriverManager(void);
2644 : CPL_C_END
2645 :
2646 : /* ******************************************************************** */
2647 : /* GDALAsyncReader */
2648 : /* ******************************************************************** */
2649 :
2650 : /**
2651 : * Class used as a session object for asynchronous requests. They are
2652 : * created with GDALDataset::BeginAsyncReader(), and destroyed with
2653 : * GDALDataset::EndAsyncReader().
2654 : */
2655 1 : class CPL_DLL GDALAsyncReader
2656 : {
2657 :
2658 : CPL_DISALLOW_COPY_ASSIGN(GDALAsyncReader)
2659 :
2660 : protected:
2661 : //! @cond Doxygen_Suppress
2662 : GDALDataset *poDS;
2663 : int nXOff;
2664 : int nYOff;
2665 : int nXSize;
2666 : int nYSize;
2667 : void *pBuf;
2668 : int nBufXSize;
2669 : int nBufYSize;
2670 : GDALDataType eBufType;
2671 : int nBandCount;
2672 : int *panBandMap;
2673 : int nPixelSpace;
2674 : int nLineSpace;
2675 : int nBandSpace;
2676 : //! @endcond
2677 :
2678 : public:
2679 : GDALAsyncReader();
2680 : virtual ~GDALAsyncReader();
2681 :
2682 : /** Return dataset.
2683 : * @return dataset
2684 : */
2685 : GDALDataset *GetGDALDataset()
2686 : {
2687 : return poDS;
2688 : }
2689 :
2690 : /** Return x offset.
2691 : * @return x offset.
2692 : */
2693 : int GetXOffset() const
2694 : {
2695 : return nXOff;
2696 : }
2697 :
2698 : /** Return y offset.
2699 : * @return y offset.
2700 : */
2701 : int GetYOffset() const
2702 : {
2703 : return nYOff;
2704 : }
2705 :
2706 : /** Return width.
2707 : * @return width
2708 : */
2709 : int GetXSize() const
2710 : {
2711 : return nXSize;
2712 : }
2713 :
2714 : /** Return height.
2715 : * @return height
2716 : */
2717 : int GetYSize() const
2718 : {
2719 : return nYSize;
2720 : }
2721 :
2722 : /** Return buffer.
2723 : * @return buffer
2724 : */
2725 : void *GetBuffer()
2726 : {
2727 : return pBuf;
2728 : }
2729 :
2730 : /** Return buffer width.
2731 : * @return buffer width.
2732 : */
2733 : int GetBufferXSize() const
2734 : {
2735 : return nBufXSize;
2736 : }
2737 :
2738 : /** Return buffer height.
2739 : * @return buffer height.
2740 : */
2741 : int GetBufferYSize() const
2742 : {
2743 : return nBufYSize;
2744 : }
2745 :
2746 : /** Return buffer data type.
2747 : * @return buffer data type.
2748 : */
2749 : GDALDataType GetBufferType() const
2750 : {
2751 : return eBufType;
2752 : }
2753 :
2754 : /** Return band count.
2755 : * @return band count
2756 : */
2757 : int GetBandCount() const
2758 : {
2759 : return nBandCount;
2760 : }
2761 :
2762 : /** Return band map.
2763 : * @return band map.
2764 : */
2765 : int *GetBandMap()
2766 : {
2767 : return panBandMap;
2768 : }
2769 :
2770 : /** Return pixel spacing.
2771 : * @return pixel spacing.
2772 : */
2773 : int GetPixelSpace() const
2774 : {
2775 : return nPixelSpace;
2776 : }
2777 :
2778 : /** Return line spacing.
2779 : * @return line spacing.
2780 : */
2781 : int GetLineSpace() const
2782 : {
2783 : return nLineSpace;
2784 : }
2785 :
2786 : /** Return band spacing.
2787 : * @return band spacing.
2788 : */
2789 : int GetBandSpace() const
2790 : {
2791 : return nBandSpace;
2792 : }
2793 :
2794 : virtual GDALAsyncStatusType
2795 : GetNextUpdatedRegion(double dfTimeout, int *pnBufXOff, int *pnBufYOff,
2796 : int *pnBufXSize, int *pnBufYSize) = 0;
2797 : virtual int LockBuffer(double dfTimeout = -1.0);
2798 : virtual void UnlockBuffer();
2799 : };
2800 :
2801 : /* ******************************************************************** */
2802 : /* Multidimensional array API */
2803 : /* ******************************************************************** */
2804 :
2805 : class GDALMDArray;
2806 : class GDALAttribute;
2807 : class GDALDimension;
2808 : class GDALEDTComponent;
2809 :
2810 : /* ******************************************************************** */
2811 : /* GDALExtendedDataType */
2812 : /* ******************************************************************** */
2813 :
2814 : /**
2815 : * Class used to represent potentially complex data types.
2816 : * Several classes of data types are supported: numeric (based on GDALDataType),
2817 : * compound or string.
2818 : *
2819 : * @since GDAL 3.1
2820 : */
2821 64893 : class CPL_DLL GDALExtendedDataType
2822 : {
2823 : public:
2824 : ~GDALExtendedDataType();
2825 :
2826 : GDALExtendedDataType(const GDALExtendedDataType &);
2827 :
2828 : GDALExtendedDataType &operator=(const GDALExtendedDataType &);
2829 : GDALExtendedDataType &operator=(GDALExtendedDataType &&);
2830 :
2831 : static GDALExtendedDataType Create(GDALDataType eType);
2832 : static GDALExtendedDataType
2833 : Create(const std::string &osName, GDALDataType eBaseType,
2834 : std::unique_ptr<GDALRasterAttributeTable>);
2835 : static GDALExtendedDataType
2836 : Create(const std::string &osName, size_t nTotalSize,
2837 : std::vector<std::unique_ptr<GDALEDTComponent>> &&components);
2838 : static GDALExtendedDataType
2839 : CreateString(size_t nMaxStringLength = 0,
2840 : GDALExtendedDataTypeSubType eSubType = GEDTST_NONE);
2841 :
2842 : bool operator==(const GDALExtendedDataType &) const;
2843 :
2844 : /** Non-equality operator */
2845 1058 : bool operator!=(const GDALExtendedDataType &other) const
2846 : {
2847 1058 : return !(operator==(other));
2848 : }
2849 :
2850 : /** Return type name.
2851 : *
2852 : * This is the same as the C function GDALExtendedDataTypeGetName()
2853 : */
2854 21 : const std::string &GetName() const
2855 : {
2856 21 : return m_osName;
2857 : }
2858 :
2859 : /** Return type class.
2860 : *
2861 : * This is the same as the C function GDALExtendedDataTypeGetClass()
2862 : */
2863 303863 : GDALExtendedDataTypeClass GetClass() const
2864 : {
2865 303863 : return m_eClass;
2866 : }
2867 :
2868 : /** Return numeric data type (only valid when GetClass() == GEDTC_NUMERIC)
2869 : *
2870 : * This is the same as the C function
2871 : * GDALExtendedDataTypeGetNumericDataType()
2872 : */
2873 1957799 : GDALDataType GetNumericDataType() const
2874 : {
2875 1957799 : return m_eNumericDT;
2876 : }
2877 :
2878 : /** Return subtype.
2879 : *
2880 : * This is the same as the C function GDALExtendedDataTypeGetSubType()
2881 : *
2882 : * @since 3.4
2883 : */
2884 360 : GDALExtendedDataTypeSubType GetSubType() const
2885 : {
2886 360 : return m_eSubType;
2887 : }
2888 :
2889 : /** Return the components of the data type (only valid when GetClass() ==
2890 : * GEDTC_COMPOUND)
2891 : *
2892 : * This is the same as the C function GDALExtendedDataTypeGetComponents()
2893 : */
2894 1215 : const std::vector<std::unique_ptr<GDALEDTComponent>> &GetComponents() const
2895 : {
2896 1215 : return m_aoComponents;
2897 : }
2898 :
2899 : /** Return data type size in bytes.
2900 : *
2901 : * For a string, this will be size of a char* pointer.
2902 : *
2903 : * This is the same as the C function GDALExtendedDataTypeGetSize()
2904 : */
2905 52828 : size_t GetSize() const
2906 : {
2907 52828 : return m_nSize;
2908 : }
2909 :
2910 : /** Return the maximum length of a string in bytes.
2911 : *
2912 : * 0 indicates unknown/unlimited string.
2913 : */
2914 21 : size_t GetMaxStringLength() const
2915 : {
2916 21 : return m_nMaxStringLength;
2917 : }
2918 :
2919 : /** Return associated raster attribute table, when there is one.
2920 : *
2921 : * For the netCDF driver, the RAT will capture enumerated types, with
2922 : * a "value" column with an integer value and a "name" column with the
2923 : * associated name.
2924 : *
2925 : * This is the same as the C function GDALExtendedDataTypeGetRAT()
2926 : *
2927 : * @since 3.12
2928 : */
2929 425 : const GDALRasterAttributeTable *GetRAT() const
2930 : {
2931 425 : return m_poRAT.get();
2932 : }
2933 :
2934 : bool CanConvertTo(const GDALExtendedDataType &other) const;
2935 :
2936 : bool NeedsFreeDynamicMemory() const;
2937 :
2938 : void FreeDynamicMemory(void *pBuffer) const;
2939 :
2940 : static bool CopyValue(const void *pSrc, const GDALExtendedDataType &srcType,
2941 : void *pDst, const GDALExtendedDataType &dstType);
2942 :
2943 : static bool CopyValues(const void *pSrc,
2944 : const GDALExtendedDataType &srcType,
2945 : GPtrDiff_t nSrcStrideInElts, void *pDst,
2946 : const GDALExtendedDataType &dstType,
2947 : GPtrDiff_t nDstStrideInElts, size_t nValues);
2948 :
2949 : private:
2950 : GDALExtendedDataType(size_t nMaxStringLength,
2951 : GDALExtendedDataTypeSubType eSubType);
2952 : explicit GDALExtendedDataType(GDALDataType eType);
2953 : GDALExtendedDataType(const std::string &osName, GDALDataType eBaseType,
2954 : std::unique_ptr<GDALRasterAttributeTable>);
2955 : GDALExtendedDataType(
2956 : const std::string &osName, size_t nTotalSize,
2957 : std::vector<std::unique_ptr<GDALEDTComponent>> &&components);
2958 :
2959 : std::string m_osName{};
2960 : GDALExtendedDataTypeClass m_eClass = GEDTC_NUMERIC;
2961 : GDALExtendedDataTypeSubType m_eSubType = GEDTST_NONE;
2962 : GDALDataType m_eNumericDT = GDT_Unknown;
2963 : std::vector<std::unique_ptr<GDALEDTComponent>> m_aoComponents{};
2964 : size_t m_nSize = 0;
2965 : size_t m_nMaxStringLength = 0;
2966 : std::unique_ptr<GDALRasterAttributeTable> m_poRAT{};
2967 : };
2968 :
2969 : /* ******************************************************************** */
2970 : /* GDALEDTComponent */
2971 : /* ******************************************************************** */
2972 :
2973 : /**
2974 : * Class for a component of a compound extended data type.
2975 : *
2976 : * @since GDAL 3.1
2977 : */
2978 4168 : class CPL_DLL GDALEDTComponent
2979 : {
2980 : public:
2981 : ~GDALEDTComponent();
2982 : GDALEDTComponent(const std::string &name, size_t offset,
2983 : const GDALExtendedDataType &type);
2984 : GDALEDTComponent(const GDALEDTComponent &);
2985 :
2986 : bool operator==(const GDALEDTComponent &) const;
2987 :
2988 : /** Return the name.
2989 : *
2990 : * This is the same as the C function GDALEDTComponentGetName().
2991 : */
2992 3607 : const std::string &GetName() const
2993 : {
2994 3607 : return m_osName;
2995 : }
2996 :
2997 : /** Return the offset (in bytes) of the component in the compound data type.
2998 : *
2999 : * This is the same as the C function GDALEDTComponentGetOffset().
3000 : */
3001 8793 : size_t GetOffset() const
3002 : {
3003 8793 : return m_nOffset;
3004 : }
3005 :
3006 : /** Return the data type of the component.
3007 : *
3008 : * This is the same as the C function GDALEDTComponentGetType().
3009 : */
3010 8015 : const GDALExtendedDataType &GetType() const
3011 : {
3012 8015 : return m_oType;
3013 : }
3014 :
3015 : private:
3016 : std::string m_osName;
3017 : size_t m_nOffset;
3018 : GDALExtendedDataType m_oType;
3019 : };
3020 :
3021 : /* ******************************************************************** */
3022 : /* GDALIHasAttribute */
3023 : /* ******************************************************************** */
3024 :
3025 : /**
3026 : * Interface used to get a single GDALAttribute or a set of GDALAttribute
3027 : *
3028 : * @since GDAL 3.1
3029 : */
3030 13476 : class CPL_DLL GDALIHasAttribute
3031 : {
3032 : protected:
3033 : std::shared_ptr<GDALAttribute>
3034 : GetAttributeFromAttributes(const std::string &osName) const;
3035 :
3036 : public:
3037 : virtual ~GDALIHasAttribute();
3038 :
3039 : virtual std::shared_ptr<GDALAttribute>
3040 : GetAttribute(const std::string &osName) const;
3041 :
3042 : virtual std::vector<std::shared_ptr<GDALAttribute>>
3043 : GetAttributes(CSLConstList papszOptions = nullptr) const;
3044 :
3045 : virtual std::shared_ptr<GDALAttribute>
3046 : CreateAttribute(const std::string &osName,
3047 : const std::vector<GUInt64> &anDimensions,
3048 : const GDALExtendedDataType &oDataType,
3049 : CSLConstList papszOptions = nullptr);
3050 :
3051 : virtual bool DeleteAttribute(const std::string &osName,
3052 : CSLConstList papszOptions = nullptr);
3053 : };
3054 :
3055 : /* ******************************************************************** */
3056 : /* GDALGroup */
3057 : /* ******************************************************************** */
3058 :
3059 : /* clang-format off */
3060 : /**
3061 : * Class modeling a named container of GDALAttribute, GDALMDArray, OGRLayer or
3062 : * other GDALGroup. Hence GDALGroup can describe a hierarchy of objects.
3063 : *
3064 : * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_group">HDF5 group
3065 : * concept</a>
3066 : *
3067 : * @since GDAL 3.1
3068 : */
3069 : /* clang-format on */
3070 :
3071 6912 : class CPL_DLL GDALGroup : public GDALIHasAttribute
3072 : {
3073 : protected:
3074 : //! @cond Doxygen_Suppress
3075 : std::string m_osName{};
3076 :
3077 : // This is actually a path of the form "/parent_path/{m_osName}"
3078 : std::string m_osFullName{};
3079 :
3080 : // Used for example by GDALSubsetGroup to distinguish a derived group
3081 : //from its original, without altering its name
3082 : const std::string m_osContext{};
3083 :
3084 : // List of types owned by the group.
3085 : std::vector<std::shared_ptr<GDALExtendedDataType>> m_apoTypes{};
3086 :
3087 : //! Weak pointer to this
3088 : std::weak_ptr<GDALGroup> m_pSelf{};
3089 :
3090 : //! Can be set to false by the owing group, when deleting this object
3091 : bool m_bValid = true;
3092 :
3093 : GDALGroup(const std::string &osParentName, const std::string &osName,
3094 : const std::string &osContext = std::string());
3095 :
3096 : const GDALGroup *
3097 : GetInnerMostGroup(const std::string &osPathOrArrayOrDim,
3098 : std::shared_ptr<GDALGroup> &curGroupHolder,
3099 : std::string &osLastPart) const;
3100 :
3101 : void BaseRename(const std::string &osNewName);
3102 :
3103 : bool CheckValidAndErrorOutIfNot() const;
3104 :
3105 6048 : void SetSelf(const std::shared_ptr<GDALGroup> &self)
3106 : {
3107 6048 : m_pSelf = self;
3108 6048 : }
3109 :
3110 0 : virtual void NotifyChildrenOfRenaming()
3111 : {
3112 0 : }
3113 :
3114 0 : virtual void NotifyChildrenOfDeletion()
3115 : {
3116 0 : }
3117 :
3118 : //! @endcond
3119 :
3120 : public:
3121 : virtual ~GDALGroup();
3122 :
3123 : /** Return the name of the group.
3124 : *
3125 : * This is the same as the C function GDALGroupGetName().
3126 : */
3127 1050 : const std::string &GetName() const
3128 : {
3129 1050 : return m_osName;
3130 : }
3131 :
3132 : /** Return the full name of the group.
3133 : *
3134 : * This is the same as the C function GDALGroupGetFullName().
3135 : */
3136 24275 : const std::string &GetFullName() const
3137 : {
3138 24275 : return m_osFullName;
3139 : }
3140 :
3141 : /** Return data types associated with the group (typically enumerations)
3142 : *
3143 : * This is the same as the C function GDALGroupGetDataTypeCount() and GDALGroupGetDataType()
3144 : *
3145 : * @since 3.12
3146 : */
3147 : const std::vector<std::shared_ptr<GDALExtendedDataType>> &
3148 55 : GetDataTypes() const
3149 : {
3150 55 : return m_apoTypes;
3151 : }
3152 :
3153 : virtual std::vector<std::string>
3154 : GetMDArrayNames(CSLConstList papszOptions = nullptr) const;
3155 : virtual std::shared_ptr<GDALMDArray>
3156 : OpenMDArray(const std::string &osName,
3157 : CSLConstList papszOptions = nullptr) const;
3158 :
3159 : std::vector<std::string> GetMDArrayFullNamesRecursive(
3160 : CSLConstList papszGroupOptions = nullptr,
3161 : CSLConstList papszArrayOptions = nullptr) const;
3162 :
3163 : virtual std::vector<std::string>
3164 : GetGroupNames(CSLConstList papszOptions = nullptr) const;
3165 : virtual std::shared_ptr<GDALGroup>
3166 : OpenGroup(const std::string &osName,
3167 : CSLConstList papszOptions = nullptr) const;
3168 :
3169 : virtual std::vector<std::string>
3170 : GetVectorLayerNames(CSLConstList papszOptions = nullptr) const;
3171 : virtual OGRLayer *
3172 : OpenVectorLayer(const std::string &osName,
3173 : CSLConstList papszOptions = nullptr) const;
3174 :
3175 : virtual std::vector<std::shared_ptr<GDALDimension>>
3176 : GetDimensions(CSLConstList papszOptions = nullptr) const;
3177 :
3178 : virtual std::shared_ptr<GDALGroup>
3179 : CreateGroup(const std::string &osName, CSLConstList papszOptions = nullptr);
3180 :
3181 : virtual bool DeleteGroup(const std::string &osName,
3182 : CSLConstList papszOptions = nullptr);
3183 :
3184 : virtual std::shared_ptr<GDALDimension>
3185 : CreateDimension(const std::string &osName, const std::string &osType,
3186 : const std::string &osDirection, GUInt64 nSize,
3187 : CSLConstList papszOptions = nullptr);
3188 :
3189 : virtual std::shared_ptr<GDALMDArray> CreateMDArray(
3190 : const std::string &osName,
3191 : const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
3192 : const GDALExtendedDataType &oDataType,
3193 : CSLConstList papszOptions = nullptr);
3194 :
3195 : virtual bool DeleteMDArray(const std::string &osName,
3196 : CSLConstList papszOptions = nullptr);
3197 :
3198 : GUInt64 GetTotalCopyCost() const;
3199 :
3200 : virtual bool CopyFrom(const std::shared_ptr<GDALGroup> &poDstRootGroup,
3201 : GDALDataset *poSrcDS,
3202 : const std::shared_ptr<GDALGroup> &poSrcGroup,
3203 : bool bStrict, GUInt64 &nCurCost,
3204 : const GUInt64 nTotalCost,
3205 : GDALProgressFunc pfnProgress, void *pProgressData,
3206 : CSLConstList papszOptions = nullptr);
3207 :
3208 : virtual CSLConstList GetStructuralInfo() const;
3209 :
3210 : std::shared_ptr<GDALMDArray>
3211 : OpenMDArrayFromFullname(const std::string &osFullName,
3212 : CSLConstList papszOptions = nullptr) const;
3213 :
3214 : std::shared_ptr<GDALMDArray>
3215 : ResolveMDArray(const std::string &osName, const std::string &osStartingPath,
3216 : CSLConstList papszOptions = nullptr) const;
3217 :
3218 : std::shared_ptr<GDALGroup>
3219 : OpenGroupFromFullname(const std::string &osFullName,
3220 : CSLConstList papszOptions = nullptr) const;
3221 :
3222 : std::shared_ptr<GDALDimension>
3223 : OpenDimensionFromFullname(const std::string &osFullName) const;
3224 :
3225 : virtual void ClearStatistics();
3226 :
3227 : virtual bool Rename(const std::string &osNewName);
3228 :
3229 : std::shared_ptr<GDALGroup>
3230 : SubsetDimensionFromSelection(const std::string &osSelection) const;
3231 :
3232 : //! @cond Doxygen_Suppress
3233 : virtual void ParentRenamed(const std::string &osNewParentFullName);
3234 :
3235 : virtual void Deleted();
3236 :
3237 : virtual void ParentDeleted();
3238 :
3239 23 : const std::string &GetContext() const
3240 : {
3241 23 : return m_osContext;
3242 : }
3243 :
3244 : //! @endcond
3245 :
3246 : //! @cond Doxygen_Suppress
3247 : static constexpr GUInt64 COPY_COST = 1000;
3248 : //! @endcond
3249 : };
3250 :
3251 : /* ******************************************************************** */
3252 : /* GDALAbstractMDArray */
3253 : /* ******************************************************************** */
3254 :
3255 : /**
3256 : * Abstract class, implemented by GDALAttribute and GDALMDArray.
3257 : *
3258 : * @since GDAL 3.1
3259 : */
3260 20951 : class CPL_DLL GDALAbstractMDArray
3261 : {
3262 : protected:
3263 : //! @cond Doxygen_Suppress
3264 : std::string m_osName{};
3265 :
3266 : // This is actually a path of the form "/parent_path/{m_osName}"
3267 : std::string m_osFullName{};
3268 : std::weak_ptr<GDALAbstractMDArray> m_pSelf{};
3269 :
3270 : //! Can be set to false by the owing object, when deleting this object
3271 : bool m_bValid = true;
3272 :
3273 : GDALAbstractMDArray(const std::string &osParentName,
3274 : const std::string &osName);
3275 :
3276 8330 : void SetSelf(const std::shared_ptr<GDALAbstractMDArray> &self)
3277 : {
3278 8330 : m_pSelf = self;
3279 8330 : }
3280 :
3281 : bool CheckValidAndErrorOutIfNot() const;
3282 :
3283 : bool CheckReadWriteParams(const GUInt64 *arrayStartIdx, const size_t *count,
3284 : const GInt64 *&arrayStep,
3285 : const GPtrDiff_t *&bufferStride,
3286 : const GDALExtendedDataType &bufferDataType,
3287 : const void *buffer,
3288 : const void *buffer_alloc_start,
3289 : size_t buffer_alloc_size,
3290 : std::vector<GInt64> &tmp_arrayStep,
3291 : std::vector<GPtrDiff_t> &tmp_bufferStride) const;
3292 :
3293 : virtual bool
3294 : IRead(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
3295 : const size_t *count, // array of size GetDimensionCount()
3296 : const GInt64 *arrayStep, // step in elements
3297 : const GPtrDiff_t *bufferStride, // stride in elements
3298 : const GDALExtendedDataType &bufferDataType,
3299 : void *pDstBuffer) const = 0;
3300 :
3301 : virtual bool
3302 : IWrite(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
3303 : const size_t *count, // array of size GetDimensionCount()
3304 : const GInt64 *arrayStep, // step in elements
3305 : const GPtrDiff_t *bufferStride, // stride in elements
3306 : const GDALExtendedDataType &bufferDataType, const void *pSrcBuffer);
3307 :
3308 : void BaseRename(const std::string &osNewName);
3309 :
3310 47 : virtual void NotifyChildrenOfRenaming()
3311 : {
3312 47 : }
3313 :
3314 42 : virtual void NotifyChildrenOfDeletion()
3315 : {
3316 42 : }
3317 :
3318 : //! @endcond
3319 :
3320 : public:
3321 : virtual ~GDALAbstractMDArray();
3322 :
3323 : /** Return the name of an array or attribute.
3324 : *
3325 : * This is the same as the C function GDALMDArrayGetName() or
3326 : * GDALAttributeGetName().
3327 : */
3328 19390 : const std::string &GetName() const
3329 : {
3330 19390 : return m_osName;
3331 : }
3332 :
3333 : /** Return the name of an array or attribute.
3334 : *
3335 : * This is the same as the C function GDALMDArrayGetFullName() or
3336 : * GDALAttributeGetFullName().
3337 : */
3338 12799 : const std::string &GetFullName() const
3339 : {
3340 12799 : return m_osFullName;
3341 : }
3342 :
3343 : GUInt64 GetTotalElementsCount() const;
3344 :
3345 : virtual size_t GetDimensionCount() const;
3346 :
3347 : virtual const std::vector<std::shared_ptr<GDALDimension>> &
3348 : GetDimensions() const = 0;
3349 :
3350 : virtual const GDALExtendedDataType &GetDataType() const = 0;
3351 :
3352 : virtual std::vector<GUInt64> GetBlockSize() const;
3353 :
3354 : virtual std::vector<size_t>
3355 : GetProcessingChunkSize(size_t nMaxChunkMemory) const;
3356 :
3357 : /* clang-format off */
3358 : /** Type of pfnFunc argument of ProcessPerChunk().
3359 : * @param array Array on which ProcessPerChunk was called.
3360 : * @param chunkArrayStartIdx Values representing the starting index to use
3361 : * in each dimension (in [0, aoDims[i].GetSize()-1] range)
3362 : * for the current chunk.
3363 : * Will be nullptr for a zero-dimensional array.
3364 : * @param chunkCount Values representing the number of values to use in
3365 : * each dimension for the current chunk.
3366 : * Will be nullptr for a zero-dimensional array.
3367 : * @param iCurChunk Number of current chunk being processed.
3368 : * In [1, nChunkCount] range.
3369 : * @param nChunkCount Total number of chunks to process.
3370 : * @param pUserData User data.
3371 : * @return return true in case of success.
3372 : */
3373 : typedef bool (*FuncProcessPerChunkType)(
3374 : GDALAbstractMDArray *array,
3375 : const GUInt64 *chunkArrayStartIdx,
3376 : const size_t *chunkCount,
3377 : GUInt64 iCurChunk,
3378 : GUInt64 nChunkCount,
3379 : void *pUserData);
3380 : /* clang-format on */
3381 :
3382 : virtual bool ProcessPerChunk(const GUInt64 *arrayStartIdx,
3383 : const GUInt64 *count, const size_t *chunkSize,
3384 : FuncProcessPerChunkType pfnFunc,
3385 : void *pUserData);
3386 :
3387 : virtual bool
3388 : Read(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
3389 : const size_t *count, // array of size GetDimensionCount()
3390 : const GInt64 *arrayStep, // step in elements
3391 : const GPtrDiff_t *bufferStride, // stride in elements
3392 : const GDALExtendedDataType &bufferDataType, void *pDstBuffer,
3393 : const void *pDstBufferAllocStart = nullptr,
3394 : size_t nDstBufferAllocSize = 0) const;
3395 :
3396 : bool
3397 : Write(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
3398 : const size_t *count, // array of size GetDimensionCount()
3399 : const GInt64 *arrayStep, // step in elements
3400 : const GPtrDiff_t *bufferStride, // stride in elements
3401 : const GDALExtendedDataType &bufferDataType, const void *pSrcBuffer,
3402 : const void *pSrcBufferAllocStart = nullptr,
3403 : size_t nSrcBufferAllocSize = 0);
3404 :
3405 : virtual bool Rename(const std::string &osNewName);
3406 :
3407 : //! @cond Doxygen_Suppress
3408 : virtual void Deleted();
3409 :
3410 : virtual void ParentDeleted();
3411 :
3412 : virtual void ParentRenamed(const std::string &osNewParentFullName);
3413 : //! @endcond
3414 : };
3415 :
3416 : /* ******************************************************************** */
3417 : /* GDALRawResult */
3418 : /* ******************************************************************** */
3419 :
3420 : /**
3421 : * Store the raw result of an attribute value, which might contain dynamically
3422 : * allocated structures (like pointer to strings).
3423 : *
3424 : * @since GDAL 3.1
3425 : */
3426 : class CPL_DLL GDALRawResult
3427 : {
3428 : private:
3429 : GDALExtendedDataType m_dt;
3430 : size_t m_nEltCount;
3431 : size_t m_nSize;
3432 : GByte *m_raw;
3433 :
3434 : void FreeMe();
3435 :
3436 : GDALRawResult(const GDALRawResult &) = delete;
3437 : GDALRawResult &operator=(const GDALRawResult &) = delete;
3438 :
3439 : protected:
3440 : friend class GDALAttribute;
3441 : //! @cond Doxygen_Suppress
3442 : GDALRawResult(GByte *raw, const GDALExtendedDataType &dt, size_t nEltCount);
3443 : //! @endcond
3444 :
3445 : public:
3446 : ~GDALRawResult();
3447 : GDALRawResult(GDALRawResult &&);
3448 : GDALRawResult &operator=(GDALRawResult &&);
3449 :
3450 : /** Return byte at specified index. */
3451 : const GByte &operator[](size_t idx) const
3452 : {
3453 : return m_raw[idx];
3454 : }
3455 :
3456 : /** Return pointer to the start of data. */
3457 343 : const GByte *data() const
3458 : {
3459 343 : return m_raw;
3460 : }
3461 :
3462 : /** Return the size in bytes of the raw result. */
3463 125 : size_t size() const
3464 : {
3465 125 : return m_nSize;
3466 : }
3467 :
3468 : //! @cond Doxygen_Suppress
3469 : GByte *StealData();
3470 : //! @endcond
3471 : };
3472 :
3473 : /* ******************************************************************** */
3474 : /* GDALAttribute */
3475 : /* ******************************************************************** */
3476 :
3477 : /* clang-format off */
3478 : /**
3479 : * Class modeling an attribute that has a name, a value and a type, and is
3480 : * typically used to describe a metadata item. The value can be (for the
3481 : * HDF5 format) in the general case a multidimensional array of "any" type
3482 : * (in most cases, this will be a single value of string or numeric type)
3483 : *
3484 : * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_attribute">HDF5
3485 : * attribute concept</a>
3486 : *
3487 : * @since GDAL 3.1
3488 : */
3489 : /* clang-format on */
3490 :
3491 : class CPL_DLL GDALAttribute : virtual public GDALAbstractMDArray
3492 : {
3493 : mutable std::string m_osCachedVal{};
3494 :
3495 : protected:
3496 : //! @cond Doxygen_Suppress
3497 : GDALAttribute(const std::string &osParentName, const std::string &osName);
3498 : //! @endcond
3499 :
3500 : public:
3501 : std::vector<GUInt64> GetDimensionsSize() const;
3502 :
3503 : GDALRawResult ReadAsRaw() const;
3504 : const char *ReadAsString() const;
3505 : int ReadAsInt() const;
3506 : int64_t ReadAsInt64() const;
3507 : double ReadAsDouble() const;
3508 : CPLStringList ReadAsStringArray() const;
3509 : std::vector<int> ReadAsIntArray() const;
3510 : std::vector<int64_t> ReadAsInt64Array() const;
3511 : std::vector<double> ReadAsDoubleArray() const;
3512 :
3513 : using GDALAbstractMDArray::Write;
3514 : bool Write(const void *pabyValue, size_t nLen);
3515 : bool Write(const char *);
3516 : bool WriteInt(int);
3517 : bool WriteInt64(int64_t);
3518 : bool Write(double);
3519 : bool Write(CSLConstList);
3520 : bool Write(const int *, size_t);
3521 : bool Write(const int64_t *, size_t);
3522 : bool Write(const double *, size_t);
3523 :
3524 : //! @cond Doxygen_Suppress
3525 : static constexpr GUInt64 COPY_COST = 100;
3526 : //! @endcond
3527 : };
3528 :
3529 : /************************************************************************/
3530 : /* GDALAttributeString */
3531 : /************************************************************************/
3532 :
3533 : //! @cond Doxygen_Suppress
3534 : class CPL_DLL GDALAttributeString final : public GDALAttribute
3535 : {
3536 : std::vector<std::shared_ptr<GDALDimension>> m_dims{};
3537 : GDALExtendedDataType m_dt = GDALExtendedDataType::CreateString();
3538 : std::string m_osValue;
3539 :
3540 : protected:
3541 : bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
3542 : const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
3543 : void *pDstBuffer) const override;
3544 :
3545 : public:
3546 : GDALAttributeString(const std::string &osParentName,
3547 : const std::string &osName, const std::string &osValue,
3548 : GDALExtendedDataTypeSubType eSubType = GEDTST_NONE);
3549 :
3550 : const std::vector<std::shared_ptr<GDALDimension>> &
3551 : GetDimensions() const override;
3552 :
3553 : const GDALExtendedDataType &GetDataType() const override;
3554 : };
3555 :
3556 : //! @endcond
3557 :
3558 : /************************************************************************/
3559 : /* GDALAttributeNumeric */
3560 : /************************************************************************/
3561 :
3562 : //! @cond Doxygen_Suppress
3563 : class CPL_DLL GDALAttributeNumeric final : public GDALAttribute
3564 : {
3565 : std::vector<std::shared_ptr<GDALDimension>> m_dims{};
3566 : GDALExtendedDataType m_dt;
3567 : int m_nValue = 0;
3568 : double m_dfValue = 0;
3569 : std::vector<GUInt32> m_anValuesUInt32{};
3570 :
3571 : protected:
3572 : bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
3573 : const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
3574 : void *pDstBuffer) const override;
3575 :
3576 : public:
3577 : GDALAttributeNumeric(const std::string &osParentName,
3578 : const std::string &osName, double dfValue);
3579 : GDALAttributeNumeric(const std::string &osParentName,
3580 : const std::string &osName, int nValue);
3581 : GDALAttributeNumeric(const std::string &osParentName,
3582 : const std::string &osName,
3583 : const std::vector<GUInt32> &anValues);
3584 :
3585 : const std::vector<std::shared_ptr<GDALDimension>> &
3586 : GetDimensions() const override;
3587 :
3588 : const GDALExtendedDataType &GetDataType() const override;
3589 : };
3590 :
3591 : //! @endcond
3592 :
3593 : /* ******************************************************************** */
3594 : /* GDALMDArray */
3595 : /* ******************************************************************** */
3596 :
3597 : /* clang-format off */
3598 : /**
3599 : * Class modeling a multi-dimensional array. It has a name, values organized
3600 : * as an array and a list of GDALAttribute.
3601 : *
3602 : * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_dataset">HDF5
3603 : * dataset concept</a>
3604 : *
3605 : * @since GDAL 3.1
3606 : */
3607 : /* clang-format on */
3608 :
3609 : class CPL_DLL GDALMDArray : virtual public GDALAbstractMDArray,
3610 : public GDALIHasAttribute
3611 : {
3612 : friend class GDALMDArrayResampled;
3613 : std::shared_ptr<GDALMDArray>
3614 : GetView(const std::vector<GUInt64> &indices) const;
3615 :
3616 : inline std::shared_ptr<GDALMDArray>
3617 19 : atInternal(const std::vector<GUInt64> &indices) const
3618 : {
3619 19 : return GetView(indices);
3620 : }
3621 :
3622 : template <typename... GUInt64VarArg>
3623 : // cppcheck-suppress functionStatic
3624 : inline std::shared_ptr<GDALMDArray>
3625 7 : atInternal(std::vector<GUInt64> &indices, GUInt64 idx,
3626 : GUInt64VarArg... tail) const
3627 : {
3628 7 : indices.push_back(idx);
3629 7 : return atInternal(indices, tail...);
3630 : }
3631 :
3632 : // Used for example by GDALSubsetGroup to distinguish a derived group
3633 : //from its original, without altering its name
3634 : const std::string m_osContext{};
3635 :
3636 : mutable bool m_bHasTriedCachedArray = false;
3637 : mutable std::shared_ptr<GDALMDArray> m_poCachedArray{};
3638 :
3639 : protected:
3640 : //! @cond Doxygen_Suppress
3641 : GDALMDArray(const std::string &osParentName, const std::string &osName,
3642 : const std::string &osContext = std::string());
3643 :
3644 : virtual bool IAdviseRead(const GUInt64 *arrayStartIdx, const size_t *count,
3645 : CSLConstList papszOptions) const;
3646 :
3647 1748 : virtual bool IsCacheable() const
3648 : {
3649 1748 : return true;
3650 : }
3651 :
3652 : virtual bool SetStatistics(bool bApproxStats, double dfMin, double dfMax,
3653 : double dfMean, double dfStdDev,
3654 : GUInt64 nValidCount, CSLConstList papszOptions);
3655 :
3656 : static std::string MassageName(const std::string &inputName);
3657 :
3658 : std::shared_ptr<GDALGroup>
3659 : GetCacheRootGroup(bool bCanCreate, std::string &osCacheFilenameOut) const;
3660 :
3661 : // Returns if bufferStride values express a transposed view of the array
3662 : bool IsTransposedRequest(const size_t *count,
3663 : const GPtrDiff_t *bufferStride) const;
3664 :
3665 : // Should only be called if IsTransposedRequest() returns true
3666 : bool ReadForTransposedRequest(const GUInt64 *arrayStartIdx,
3667 : const size_t *count, const GInt64 *arrayStep,
3668 : const GPtrDiff_t *bufferStride,
3669 : const GDALExtendedDataType &bufferDataType,
3670 : void *pDstBuffer) const;
3671 :
3672 : bool IsStepOneContiguousRowMajorOrderedSameDataType(
3673 : const size_t *count, const GInt64 *arrayStep,
3674 : const GPtrDiff_t *bufferStride,
3675 : const GDALExtendedDataType &bufferDataType) const;
3676 :
3677 : // Should only be called if IsStepOneContiguousRowMajorOrderedSameDataType()
3678 : // returns false
3679 : bool ReadUsingContiguousIRead(const GUInt64 *arrayStartIdx,
3680 : const size_t *count, const GInt64 *arrayStep,
3681 : const GPtrDiff_t *bufferStride,
3682 : const GDALExtendedDataType &bufferDataType,
3683 : void *pDstBuffer) const;
3684 :
3685 : static std::shared_ptr<GDALMDArray> CreateGLTOrthorectified(
3686 : const std::shared_ptr<GDALMDArray> &poParent,
3687 : const std::shared_ptr<GDALGroup> &poRootGroup,
3688 : const std::shared_ptr<GDALMDArray> &poGLTX,
3689 : const std::shared_ptr<GDALMDArray> &poGLTY, int nGLTIndexOffset,
3690 : const std::vector<double> &adfGeoTransform, CSLConstList papszOptions);
3691 :
3692 : //! @endcond
3693 :
3694 : public:
3695 : GUInt64 GetTotalCopyCost() const;
3696 :
3697 : virtual bool CopyFrom(GDALDataset *poSrcDS, const GDALMDArray *poSrcArray,
3698 : bool bStrict, GUInt64 &nCurCost,
3699 : const GUInt64 nTotalCost,
3700 : GDALProgressFunc pfnProgress, void *pProgressData);
3701 :
3702 : /** Return whether an array is writable. */
3703 : virtual bool IsWritable() const = 0;
3704 :
3705 : /** Return the filename that contains that array.
3706 : *
3707 : * This is used in particular for caching.
3708 : *
3709 : * Might be empty if the array is not linked to a file.
3710 : *
3711 : * @since GDAL 3.4
3712 : */
3713 : virtual const std::string &GetFilename() const = 0;
3714 :
3715 : virtual CSLConstList GetStructuralInfo() const;
3716 :
3717 : virtual const std::string &GetUnit() const;
3718 :
3719 : virtual bool SetUnit(const std::string &osUnit);
3720 :
3721 : virtual bool SetSpatialRef(const OGRSpatialReference *poSRS);
3722 :
3723 : virtual std::shared_ptr<OGRSpatialReference> GetSpatialRef() const;
3724 :
3725 : virtual const void *GetRawNoDataValue() const;
3726 :
3727 : double GetNoDataValueAsDouble(bool *pbHasNoData = nullptr) const;
3728 :
3729 : int64_t GetNoDataValueAsInt64(bool *pbHasNoData = nullptr) const;
3730 :
3731 : uint64_t GetNoDataValueAsUInt64(bool *pbHasNoData = nullptr) const;
3732 :
3733 : virtual bool SetRawNoDataValue(const void *pRawNoData);
3734 :
3735 : //! @cond Doxygen_Suppress
3736 2 : bool SetNoDataValue(int nNoData)
3737 : {
3738 2 : return SetNoDataValue(static_cast<int64_t>(nNoData));
3739 : }
3740 :
3741 : //! @endcond
3742 :
3743 : bool SetNoDataValue(double dfNoData);
3744 :
3745 : bool SetNoDataValue(int64_t nNoData);
3746 :
3747 : bool SetNoDataValue(uint64_t nNoData);
3748 :
3749 : virtual bool Resize(const std::vector<GUInt64> &anNewDimSizes,
3750 : CSLConstList papszOptions);
3751 :
3752 : virtual double GetOffset(bool *pbHasOffset = nullptr,
3753 : GDALDataType *peStorageType = nullptr) const;
3754 :
3755 : virtual double GetScale(bool *pbHasScale = nullptr,
3756 : GDALDataType *peStorageType = nullptr) const;
3757 :
3758 : virtual bool SetOffset(double dfOffset,
3759 : GDALDataType eStorageType = GDT_Unknown);
3760 :
3761 : virtual bool SetScale(double dfScale,
3762 : GDALDataType eStorageType = GDT_Unknown);
3763 :
3764 : std::shared_ptr<GDALMDArray> GetView(const std::string &viewExpr) const;
3765 :
3766 : std::shared_ptr<GDALMDArray> operator[](const std::string &fieldName) const;
3767 :
3768 : /** Return a view of the array using integer indexing.
3769 : *
3770 : * Equivalent of GetView("[indices_0,indices_1,.....,indices_last]")
3771 : *
3772 : * Example:
3773 : * \code
3774 : * ar->at(0,3,2)
3775 : * \endcode
3776 : */
3777 : // sphinx 4.1.0 / breathe 4.30.0 don't like typename...
3778 : //! @cond Doxygen_Suppress
3779 : template <typename... GUInt64VarArg>
3780 : //! @endcond
3781 : // cppcheck-suppress functionStatic
3782 19 : std::shared_ptr<GDALMDArray> at(GUInt64 idx, GUInt64VarArg... tail) const
3783 : {
3784 38 : std::vector<GUInt64> indices;
3785 19 : indices.push_back(idx);
3786 38 : return atInternal(indices, tail...);
3787 : }
3788 :
3789 : virtual std::shared_ptr<GDALMDArray>
3790 : Transpose(const std::vector<int> &anMapNewAxisToOldAxis) const;
3791 :
3792 : std::shared_ptr<GDALMDArray> GetUnscaled(
3793 : double dfOverriddenScale = std::numeric_limits<double>::quiet_NaN(),
3794 : double dfOverriddenOffset = std::numeric_limits<double>::quiet_NaN(),
3795 : double dfOverriddenDstNodata =
3796 : std::numeric_limits<double>::quiet_NaN()) const;
3797 :
3798 : virtual std::shared_ptr<GDALMDArray>
3799 : GetMask(CSLConstList papszOptions) const;
3800 :
3801 : virtual std::shared_ptr<GDALMDArray>
3802 : GetResampled(const std::vector<std::shared_ptr<GDALDimension>> &apoNewDims,
3803 : GDALRIOResampleAlg resampleAlg,
3804 : const OGRSpatialReference *poTargetSRS,
3805 : CSLConstList papszOptions) const;
3806 :
3807 : std::shared_ptr<GDALMDArray>
3808 : GetGridded(const std::string &osGridOptions,
3809 : const std::shared_ptr<GDALMDArray> &poXArray = nullptr,
3810 : const std::shared_ptr<GDALMDArray> &poYArray = nullptr,
3811 : CSLConstList papszOptions = nullptr) const;
3812 :
3813 : static std::vector<std::shared_ptr<GDALMDArray>>
3814 : GetMeshGrid(const std::vector<std::shared_ptr<GDALMDArray>> &apoArrays,
3815 : CSLConstList papszOptions = nullptr);
3816 :
3817 : virtual GDALDataset *
3818 : AsClassicDataset(size_t iXDim, size_t iYDim,
3819 : const std::shared_ptr<GDALGroup> &poRootGroup = nullptr,
3820 : CSLConstList papszOptions = nullptr) const;
3821 :
3822 : virtual CPLErr GetStatistics(bool bApproxOK, bool bForce, double *pdfMin,
3823 : double *pdfMax, double *pdfMean,
3824 : double *padfStdDev, GUInt64 *pnValidCount,
3825 : GDALProgressFunc pfnProgress,
3826 : void *pProgressData);
3827 :
3828 : virtual bool ComputeStatistics(bool bApproxOK, double *pdfMin,
3829 : double *pdfMax, double *pdfMean,
3830 : double *pdfStdDev, GUInt64 *pnValidCount,
3831 : GDALProgressFunc, void *pProgressData,
3832 : CSLConstList papszOptions);
3833 :
3834 : virtual void ClearStatistics();
3835 :
3836 : virtual std::vector<std::shared_ptr<GDALMDArray>>
3837 : GetCoordinateVariables() const;
3838 :
3839 : bool AdviseRead(const GUInt64 *arrayStartIdx, const size_t *count,
3840 : CSLConstList papszOptions = nullptr) const;
3841 :
3842 : bool IsRegularlySpaced(double &dfStart, double &dfIncrement) const;
3843 :
3844 : bool GuessGeoTransform(size_t nDimX, size_t nDimY, bool bPixelIsPoint,
3845 : double adfGeoTransform[6]) const;
3846 :
3847 : bool Cache(CSLConstList papszOptions = nullptr) const;
3848 :
3849 : bool
3850 : Read(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
3851 : const size_t *count, // array of size GetDimensionCount()
3852 : const GInt64 *arrayStep, // step in elements
3853 : const GPtrDiff_t *bufferStride, // stride in elements
3854 : const GDALExtendedDataType &bufferDataType, void *pDstBuffer,
3855 : const void *pDstBufferAllocStart = nullptr,
3856 : size_t nDstBufferAllocSize = 0) const override final;
3857 :
3858 : virtual std::shared_ptr<GDALGroup> GetRootGroup() const;
3859 :
3860 : //! @cond Doxygen_Suppress
3861 : static constexpr GUInt64 COPY_COST = 1000;
3862 :
3863 : bool CopyFromAllExceptValues(const GDALMDArray *poSrcArray, bool bStrict,
3864 : GUInt64 &nCurCost, const GUInt64 nTotalCost,
3865 : GDALProgressFunc pfnProgress,
3866 : void *pProgressData);
3867 :
3868 : struct Range
3869 : {
3870 : GUInt64 m_nStartIdx;
3871 : GInt64 m_nIncr;
3872 :
3873 1331 : explicit Range(GUInt64 nStartIdx = 0, GInt64 nIncr = 0)
3874 1331 : : m_nStartIdx(nStartIdx), m_nIncr(nIncr)
3875 : {
3876 1331 : }
3877 : };
3878 :
3879 : struct ViewSpec
3880 : {
3881 : std::string m_osFieldName{};
3882 :
3883 : // or
3884 :
3885 : std::vector<size_t>
3886 : m_mapDimIdxToParentDimIdx{}; // of size m_dims.size()
3887 : std::vector<Range>
3888 : m_parentRanges{}; // of size m_poParent->GetDimensionCount()
3889 : };
3890 :
3891 : virtual std::shared_ptr<GDALMDArray>
3892 : GetView(const std::string &viewExpr, bool bRenameDimensions,
3893 : std::vector<ViewSpec> &viewSpecs) const;
3894 :
3895 1081 : const std::string &GetContext() const
3896 : {
3897 1081 : return m_osContext;
3898 : }
3899 :
3900 : //! @endcond
3901 : };
3902 :
3903 : //! @cond Doxygen_Suppress
3904 : bool GDALMDRasterIOFromBand(GDALRasterBand *poBand, GDALRWFlag eRWFlag,
3905 : size_t iDimX, size_t iDimY,
3906 : const GUInt64 *arrayStartIdx, const size_t *count,
3907 : const GInt64 *arrayStep,
3908 : const GPtrDiff_t *bufferStride,
3909 : const GDALExtendedDataType &bufferDataType,
3910 : void *pBuffer);
3911 :
3912 : //! @endcond
3913 :
3914 : /************************************************************************/
3915 : /* GDALMDArrayRegularlySpaced */
3916 : /************************************************************************/
3917 :
3918 : //! @cond Doxygen_Suppress
3919 : class CPL_DLL GDALMDArrayRegularlySpaced : public GDALMDArray
3920 : {
3921 : double m_dfStart;
3922 : double m_dfIncrement;
3923 : double m_dfOffsetInIncrement;
3924 : GDALExtendedDataType m_dt = GDALExtendedDataType::Create(GDT_Float64);
3925 : std::vector<std::shared_ptr<GDALDimension>> m_dims;
3926 : std::vector<std::shared_ptr<GDALAttribute>> m_attributes{};
3927 : std::string m_osEmptyFilename{};
3928 :
3929 : protected:
3930 : bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
3931 : const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
3932 : void *pDstBuffer) const override;
3933 :
3934 : public:
3935 : GDALMDArrayRegularlySpaced(const std::string &osParentName,
3936 : const std::string &osName,
3937 : const std::shared_ptr<GDALDimension> &poDim,
3938 : double dfStart, double dfIncrement,
3939 : double dfOffsetInIncrement);
3940 :
3941 : static std::shared_ptr<GDALMDArrayRegularlySpaced>
3942 : Create(const std::string &osParentName, const std::string &osName,
3943 : const std::shared_ptr<GDALDimension> &poDim, double dfStart,
3944 : double dfIncrement, double dfOffsetInIncrement);
3945 :
3946 0 : bool IsWritable() const override
3947 : {
3948 0 : return false;
3949 : }
3950 :
3951 104 : const std::string &GetFilename() const override
3952 : {
3953 104 : return m_osEmptyFilename;
3954 : }
3955 :
3956 : const std::vector<std::shared_ptr<GDALDimension>> &
3957 : GetDimensions() const override;
3958 :
3959 : const GDALExtendedDataType &GetDataType() const override;
3960 :
3961 : std::vector<std::shared_ptr<GDALAttribute>>
3962 : GetAttributes(CSLConstList) const override;
3963 :
3964 : void AddAttribute(const std::shared_ptr<GDALAttribute> &poAttr);
3965 : };
3966 :
3967 : //! @endcond
3968 :
3969 : /* ******************************************************************** */
3970 : /* GDALDimension */
3971 : /* ******************************************************************** */
3972 :
3973 : /**
3974 : * Class modeling a a dimension / axis used to index multidimensional arrays.
3975 : * It has a name, a size (that is the number of values that can be indexed along
3976 : * the dimension), a type (see GDALDimension::GetType()), a direction
3977 : * (see GDALDimension::GetDirection()), a unit and can optionally point to a
3978 : * GDALMDArray variable, typically one-dimensional, describing the values taken
3979 : * by the dimension. For a georeferenced GDALMDArray and its X dimension, this
3980 : * will be typically the values of the easting/longitude for each grid point.
3981 : *
3982 : * @since GDAL 3.1
3983 : */
3984 8476 : class CPL_DLL GDALDimension
3985 : {
3986 : public:
3987 : //! @cond Doxygen_Suppress
3988 : GDALDimension(const std::string &osParentName, const std::string &osName,
3989 : const std::string &osType, const std::string &osDirection,
3990 : GUInt64 nSize);
3991 : //! @endcond
3992 :
3993 : virtual ~GDALDimension();
3994 :
3995 : /** Return the name.
3996 : *
3997 : * This is the same as the C function GDALDimensionGetName()
3998 : */
3999 8312 : const std::string &GetName() const
4000 : {
4001 8312 : return m_osName;
4002 : }
4003 :
4004 : /** Return the full name.
4005 : *
4006 : * This is the same as the C function GDALDimensionGetFullName()
4007 : */
4008 1551 : const std::string &GetFullName() const
4009 : {
4010 1551 : return m_osFullName;
4011 : }
4012 :
4013 : /** Return the axis type.
4014 : *
4015 : * Predefined values are:
4016 : * HORIZONTAL_X, HORIZONTAL_Y, VERTICAL, TEMPORAL, PARAMETRIC
4017 : * Other values might be returned. Empty value means unknown.
4018 : *
4019 : * This is the same as the C function GDALDimensionGetType()
4020 : */
4021 1804 : const std::string &GetType() const
4022 : {
4023 1804 : return m_osType;
4024 : }
4025 :
4026 : /** Return the axis direction.
4027 : *
4028 : * Predefined values are:
4029 : * EAST, WEST, SOUTH, NORTH, UP, DOWN, FUTURE, PAST
4030 : * Other values might be returned. Empty value means unknown.
4031 : *
4032 : * This is the same as the C function GDALDimensionGetDirection()
4033 : */
4034 880 : const std::string &GetDirection() const
4035 : {
4036 880 : return m_osDirection;
4037 : }
4038 :
4039 : /** Return the size, that is the number of values along the dimension.
4040 : *
4041 : * This is the same as the C function GDALDimensionGetSize()
4042 : */
4043 81856 : GUInt64 GetSize() const
4044 : {
4045 81856 : return m_nSize;
4046 : }
4047 :
4048 : virtual std::shared_ptr<GDALMDArray> GetIndexingVariable() const;
4049 :
4050 : virtual bool
4051 : SetIndexingVariable(std::shared_ptr<GDALMDArray> poIndexingVariable);
4052 :
4053 : virtual bool Rename(const std::string &osNewName);
4054 :
4055 : //! @cond Doxygen_Suppress
4056 : virtual void ParentRenamed(const std::string &osNewParentFullName);
4057 :
4058 : virtual void ParentDeleted();
4059 : //! @endcond
4060 :
4061 : protected:
4062 : //! @cond Doxygen_Suppress
4063 : std::string m_osName;
4064 : std::string m_osFullName;
4065 : std::string m_osType;
4066 : std::string m_osDirection;
4067 : GUInt64 m_nSize;
4068 :
4069 : void BaseRename(const std::string &osNewName);
4070 :
4071 : //! @endcond
4072 : };
4073 :
4074 : /************************************************************************/
4075 : /* GDALDimensionWeakIndexingVar() */
4076 : /************************************************************************/
4077 :
4078 : //! @cond Doxygen_Suppress
4079 : class CPL_DLL GDALDimensionWeakIndexingVar : public GDALDimension
4080 : {
4081 : std::weak_ptr<GDALMDArray> m_poIndexingVariable{};
4082 :
4083 : public:
4084 : GDALDimensionWeakIndexingVar(const std::string &osParentName,
4085 : const std::string &osName,
4086 : const std::string &osType,
4087 : const std::string &osDirection, GUInt64 nSize);
4088 :
4089 : std::shared_ptr<GDALMDArray> GetIndexingVariable() const override;
4090 :
4091 : bool SetIndexingVariable(
4092 : std::shared_ptr<GDALMDArray> poIndexingVariable) override;
4093 :
4094 : void SetSize(GUInt64 nNewSize);
4095 : };
4096 : //! @endcond
4097 :
4098 : /************************************************************************/
4099 : /* GDALAntiRecursionGuard */
4100 : /************************************************************************/
4101 :
4102 : //! @cond Doxygen_Suppress
4103 : struct GDALAntiRecursionStruct;
4104 :
4105 : class GDALAntiRecursionGuard
4106 : {
4107 : GDALAntiRecursionStruct *m_psAntiRecursionStruct;
4108 : std::string m_osIdentifier;
4109 : int m_nDepth;
4110 :
4111 : GDALAntiRecursionGuard(const GDALAntiRecursionGuard &) = delete;
4112 : GDALAntiRecursionGuard &operator=(const GDALAntiRecursionGuard &) = delete;
4113 :
4114 : public:
4115 : explicit GDALAntiRecursionGuard(const std::string &osIdentifier);
4116 : GDALAntiRecursionGuard(const GDALAntiRecursionGuard &other,
4117 : const std::string &osIdentifier);
4118 : ~GDALAntiRecursionGuard();
4119 :
4120 519488 : int GetCallDepth() const
4121 : {
4122 519488 : return m_nDepth;
4123 : }
4124 : };
4125 :
4126 : //! @endcond
4127 :
4128 : /************************************************************************/
4129 : /* Relationships */
4130 : /************************************************************************/
4131 :
4132 : /**
4133 : * Definition of a table relationship.
4134 : *
4135 : * GDALRelationship describes the relationship between two tables, including
4136 : * properties such as the cardinality of the relationship and the participating
4137 : * tables.
4138 : *
4139 : * Not all relationship properties are supported by all data formats.
4140 : *
4141 : * @since GDAL 3.6
4142 : */
4143 : class CPL_DLL GDALRelationship
4144 : {
4145 : protected:
4146 : /*! @cond Doxygen_Suppress */
4147 : std::string m_osName{};
4148 : std::string m_osLeftTableName{};
4149 : std::string m_osRightTableName{};
4150 : GDALRelationshipCardinality m_eCardinality =
4151 : GDALRelationshipCardinality::GRC_ONE_TO_MANY;
4152 : std::string m_osMappingTableName{};
4153 : std::vector<std::string> m_osListLeftTableFields{};
4154 : std::vector<std::string> m_osListRightTableFields{};
4155 : std::vector<std::string> m_osListLeftMappingTableFields{};
4156 : std::vector<std::string> m_osListRightMappingTableFields{};
4157 : GDALRelationshipType m_eType = GDALRelationshipType::GRT_ASSOCIATION;
4158 : std::string m_osForwardPathLabel{};
4159 : std::string m_osBackwardPathLabel{};
4160 : std::string m_osRelatedTableType{};
4161 :
4162 : /*! @endcond */
4163 :
4164 : public:
4165 : /**
4166 : * Constructor for a relationship between two tables.
4167 : * @param osName relationship name
4168 : * @param osLeftTableName left table name
4169 : * @param osRightTableName right table name
4170 : * @param eCardinality cardinality of relationship
4171 : */
4172 349 : GDALRelationship(const std::string &osName,
4173 : const std::string &osLeftTableName,
4174 : const std::string &osRightTableName,
4175 : GDALRelationshipCardinality eCardinality =
4176 : GDALRelationshipCardinality::GRC_ONE_TO_MANY)
4177 349 : : m_osName(osName), m_osLeftTableName(osLeftTableName),
4178 349 : m_osRightTableName(osRightTableName), m_eCardinality(eCardinality)
4179 : {
4180 349 : }
4181 :
4182 : /** Get the name of the relationship */
4183 393 : const std::string &GetName() const
4184 : {
4185 393 : return m_osName;
4186 : }
4187 :
4188 : /** Get the cardinality of the relationship */
4189 247 : GDALRelationshipCardinality GetCardinality() const
4190 : {
4191 247 : return m_eCardinality;
4192 : }
4193 :
4194 : /** Get the name of the left (or base/origin) table in the relationship.
4195 : *
4196 : * @see GetRightTableName()
4197 : */
4198 202 : const std::string &GetLeftTableName() const
4199 : {
4200 202 : return m_osLeftTableName;
4201 : }
4202 :
4203 : /** Get the name of the right (or related/destination) table in the
4204 : * relationship */
4205 197 : const std::string &GetRightTableName() const
4206 : {
4207 197 : return m_osRightTableName;
4208 : }
4209 :
4210 : /** Get the name of the mapping table for many-to-many relationships.
4211 : *
4212 : * @see SetMappingTableName()
4213 : */
4214 160 : const std::string &GetMappingTableName() const
4215 : {
4216 160 : return m_osMappingTableName;
4217 : }
4218 :
4219 : /** Sets the name of the mapping table for many-to-many relationships.
4220 : *
4221 : * @see GetMappingTableName()
4222 : */
4223 113 : void SetMappingTableName(const std::string &osName)
4224 : {
4225 113 : m_osMappingTableName = osName;
4226 113 : }
4227 :
4228 : /** Get the names of the participating fields from the left table in the
4229 : * relationship.
4230 : *
4231 : * @see GetRightTableFields()
4232 : * @see SetLeftTableFields()
4233 : */
4234 157 : const std::vector<std::string> &GetLeftTableFields() const
4235 : {
4236 157 : return m_osListLeftTableFields;
4237 : }
4238 :
4239 : /** Get the names of the participating fields from the right table in the
4240 : * relationship.
4241 : *
4242 : * @see GetLeftTableFields()
4243 : * @see SetRightTableFields()
4244 : */
4245 151 : const std::vector<std::string> &GetRightTableFields() const
4246 : {
4247 151 : return m_osListRightTableFields;
4248 : }
4249 :
4250 : /** Sets the names of the participating fields from the left table in the
4251 : * relationship.
4252 : *
4253 : * @see GetLeftTableFields()
4254 : * @see SetRightTableFields()
4255 : */
4256 362 : void SetLeftTableFields(const std::vector<std::string> &osListFields)
4257 : {
4258 362 : m_osListLeftTableFields = osListFields;
4259 362 : }
4260 :
4261 : /** Sets the names of the participating fields from the right table in the
4262 : * relationship.
4263 : *
4264 : * @see GetRightTableFields()
4265 : * @see SetLeftTableFields()
4266 : */
4267 363 : void SetRightTableFields(const std::vector<std::string> &osListFields)
4268 : {
4269 363 : m_osListRightTableFields = osListFields;
4270 363 : }
4271 :
4272 : /** Get the names of the mapping table fields which correspond to the
4273 : * participating fields from the left table in the relationship.
4274 : *
4275 : * @see GetRightMappingTableFields()
4276 : * @see SetLeftMappingTableFields()
4277 : */
4278 61 : const std::vector<std::string> &GetLeftMappingTableFields() const
4279 : {
4280 61 : return m_osListLeftMappingTableFields;
4281 : }
4282 :
4283 : /** Get the names of the mapping table fields which correspond to the
4284 : * participating fields from the right table in the relationship.
4285 : *
4286 : * @see GetLeftMappingTableFields()
4287 : * @see SetRightMappingTableFields()
4288 : */
4289 61 : const std::vector<std::string> &GetRightMappingTableFields() const
4290 : {
4291 61 : return m_osListRightMappingTableFields;
4292 : }
4293 :
4294 : /** Sets the names of the mapping table fields which correspond to the
4295 : * participating fields from the left table in the relationship.
4296 : *
4297 : * @see GetLeftMappingTableFields()
4298 : * @see SetRightMappingTableFields()
4299 : */
4300 313 : void SetLeftMappingTableFields(const std::vector<std::string> &osListFields)
4301 : {
4302 313 : m_osListLeftMappingTableFields = osListFields;
4303 313 : }
4304 :
4305 : /** Sets the names of the mapping table fields which correspond to the
4306 : * participating fields from the right table in the relationship.
4307 : *
4308 : * @see GetRightMappingTableFields()
4309 : * @see SetLeftMappingTableFields()
4310 : */
4311 : void
4312 313 : SetRightMappingTableFields(const std::vector<std::string> &osListFields)
4313 : {
4314 313 : m_osListRightMappingTableFields = osListFields;
4315 313 : }
4316 :
4317 : /** Get the type of the relationship.
4318 : *
4319 : * @see SetType()
4320 : */
4321 111 : GDALRelationshipType GetType() const
4322 : {
4323 111 : return m_eType;
4324 : }
4325 :
4326 : /** Sets the type of the relationship.
4327 : *
4328 : * @see GetType()
4329 : */
4330 263 : void SetType(GDALRelationshipType eType)
4331 : {
4332 263 : m_eType = eType;
4333 263 : }
4334 :
4335 : /** Get the label of the forward path for the relationship.
4336 : *
4337 : * The forward and backward path labels are free-form, user-friendly strings
4338 : * which can be used to generate descriptions of the relationship between
4339 : * features from the right and left tables.
4340 : *
4341 : * E.g. when the left table contains buildings and the right table contains
4342 : * furniture, the forward path label could be "contains" and the backward
4343 : * path label could be "is located within". A client could then generate a
4344 : * user friendly description string such as "fire hose 1234 is located
4345 : * within building 15a".
4346 : *
4347 : * @see SetForwardPathLabel()
4348 : * @see GetBackwardPathLabel()
4349 : */
4350 53 : const std::string &GetForwardPathLabel() const
4351 : {
4352 53 : return m_osForwardPathLabel;
4353 : }
4354 :
4355 : /** Sets the label of the forward path for the relationship.
4356 : *
4357 : * The forward and backward path labels are free-form, user-friendly strings
4358 : * which can be used to generate descriptions of the relationship between
4359 : * features from the right and left tables.
4360 : *
4361 : * E.g. when the left table contains buildings and the right table contains
4362 : * furniture, the forward path label could be "contains" and the backward
4363 : * path label could be "is located within". A client could then generate a
4364 : * user friendly description string such as "fire hose 1234 is located
4365 : * within building 15a".
4366 : *
4367 : * @see GetForwardPathLabel()
4368 : * @see SetBackwardPathLabel()
4369 : */
4370 260 : void SetForwardPathLabel(const std::string &osLabel)
4371 : {
4372 260 : m_osForwardPathLabel = osLabel;
4373 260 : }
4374 :
4375 : /** Get the label of the backward path for the relationship.
4376 : *
4377 : * The forward and backward path labels are free-form, user-friendly strings
4378 : * which can be used to generate descriptions of the relationship between
4379 : * features from the right and left tables.
4380 : *
4381 : * E.g. when the left table contains buildings and the right table contains
4382 : * furniture, the forward path label could be "contains" and the backward
4383 : * path label could be "is located within". A client could then generate a
4384 : * user friendly description string such as "fire hose 1234 is located
4385 : * within building 15a".
4386 : *
4387 : * @see SetBackwardPathLabel()
4388 : * @see GetForwardPathLabel()
4389 : */
4390 53 : const std::string &GetBackwardPathLabel() const
4391 : {
4392 53 : return m_osBackwardPathLabel;
4393 : }
4394 :
4395 : /** Sets the label of the backward path for the relationship.
4396 : *
4397 : * The forward and backward path labels are free-form, user-friendly strings
4398 : * which can be used to generate descriptions of the relationship between
4399 : * features from the right and left tables.
4400 : *
4401 : * E.g. when the left table contains buildings and the right table contains
4402 : * furniture, the forward path label could be "contains" and the backward
4403 : * path label could be "is located within". A client could then generate a
4404 : * user friendly description string such as "fire hose 1234 is located
4405 : * within building 15a".
4406 : *
4407 : * @see GetBackwardPathLabel()
4408 : * @see SetForwardPathLabel()
4409 : */
4410 260 : void SetBackwardPathLabel(const std::string &osLabel)
4411 : {
4412 260 : m_osBackwardPathLabel = osLabel;
4413 260 : }
4414 :
4415 : /** Get the type string of the related table.
4416 : *
4417 : * This a free-form string representing the type of related features, where
4418 : * the exact interpretation is format dependent. For instance, table types
4419 : * from GeoPackage relationships will directly reflect the categories from
4420 : * the GeoPackage related tables extension (i.e. "media", "simple
4421 : * attributes", "features", "attributes" and "tiles").
4422 : *
4423 : * @see SetRelatedTableType()
4424 : */
4425 144 : const std::string &GetRelatedTableType() const
4426 : {
4427 144 : return m_osRelatedTableType;
4428 : }
4429 :
4430 : /** Sets the type string of the related table.
4431 : *
4432 : * This a free-form string representing the type of related features, where
4433 : * the exact interpretation is format dependent. For instance, table types
4434 : * from GeoPackage relationships will directly reflect the categories from
4435 : * the GeoPackage related tables extension (i.e. "media", "simple
4436 : * attributes", "features", "attributes" and "tiles").
4437 : *
4438 : * @see GetRelatedTableType()
4439 : */
4440 340 : void SetRelatedTableType(const std::string &osType)
4441 : {
4442 340 : m_osRelatedTableType = osType;
4443 340 : }
4444 :
4445 : /** Convert a GDALRelationship* to a GDALRelationshipH.
4446 : */
4447 81 : static inline GDALRelationshipH ToHandle(GDALRelationship *poRelationship)
4448 : {
4449 81 : return static_cast<GDALRelationshipH>(poRelationship);
4450 : }
4451 :
4452 : /** Convert a GDALRelationshipH to a GDALRelationship*.
4453 : */
4454 706 : static inline GDALRelationship *FromHandle(GDALRelationshipH hRelationship)
4455 : {
4456 706 : return static_cast<GDALRelationship *>(hRelationship);
4457 : }
4458 : };
4459 :
4460 : /* ==================================================================== */
4461 : /* An assortment of overview related stuff. */
4462 : /* ==================================================================== */
4463 :
4464 : //! @cond Doxygen_Suppress
4465 : /* Only exported for drivers as plugin. Signature may change */
4466 : CPLErr CPL_DLL GDALRegenerateOverviewsMultiBand(
4467 : int nBands, GDALRasterBand *const *papoSrcBands, int nOverviews,
4468 : GDALRasterBand *const *const *papapoOverviewBands,
4469 : const char *pszResampling, GDALProgressFunc pfnProgress,
4470 : void *pProgressData, CSLConstList papszOptions);
4471 :
4472 : CPLErr CPL_DLL GDALRegenerateOverviewsMultiBand(
4473 : const std::vector<GDALRasterBand *> &apoSrcBands,
4474 : // First level of array is indexed by band (thus aapoOverviewBands.size() must be equal to apoSrcBands.size())
4475 : // Second level is indexed by overview
4476 : const std::vector<std::vector<GDALRasterBand *>> &aapoOverviewBands,
4477 : const char *pszResampling, GDALProgressFunc pfnProgress,
4478 : void *pProgressData, CSLConstList papszOptions);
4479 :
4480 : /************************************************************************/
4481 : /* GDALOverviewResampleArgs */
4482 : /************************************************************************/
4483 :
4484 : /** Arguments for overview resampling function. */
4485 : // Should not contain any dataset/rasterband object, as this might be
4486 : // read in a worker thread.
4487 : struct GDALOverviewResampleArgs
4488 : {
4489 : //! Datatype of the source band argument
4490 : GDALDataType eSrcDataType = GDT_Unknown;
4491 : //! Datatype of the destination/overview band
4492 : GDALDataType eOvrDataType = GDT_Unknown;
4493 : //! Width in pixel of the destination/overview band
4494 : int nOvrXSize = 0;
4495 : //! Height in pixel of the destination/overview band
4496 : int nOvrYSize = 0;
4497 : //! NBITS value of the destination/overview band (or 0 if not set)
4498 : int nOvrNBITS = 0;
4499 : //! Factor to convert from destination X to source X
4500 : // (source width divided by destination width)
4501 : double dfXRatioDstToSrc = 0;
4502 : //! Factor to convert from destination Y to source Y
4503 : // (source height divided by destination height)
4504 : double dfYRatioDstToSrc = 0;
4505 : //! Sub-pixel delta to add to get source X
4506 : double dfSrcXDelta = 0;
4507 : //! Sub-pixel delta to add to get source Y
4508 : double dfSrcYDelta = 0;
4509 : //! Working data type (data type of the pChunk argument)
4510 : GDALDataType eWrkDataType = GDT_Unknown;
4511 : //! Array of nChunkXSize * nChunkYSize values of mask, or nullptr
4512 : const GByte *pabyChunkNodataMask = nullptr;
4513 : //! X offset of the source chunk in the source band
4514 : int nChunkXOff = 0;
4515 : //! Width in pixel of the source chunk in the source band
4516 : int nChunkXSize = 0;
4517 : //! Y offset of the source chunk in the source band
4518 : int nChunkYOff = 0;
4519 : //! Height in pixel of the source chunk in the source band
4520 : int nChunkYSize = 0;
4521 : //! X Offset of the destination chunk in the destination band
4522 : int nDstXOff = 0;
4523 : //! X Offset of the end (not included) of the destination chunk in the destination band
4524 : int nDstXOff2 = 0;
4525 : //! Y Offset of the destination chunk in the destination band
4526 : int nDstYOff = 0;
4527 : //! Y Offset of the end (not included) of the destination chunk in the destination band
4528 : int nDstYOff2 = 0;
4529 : //! Resampling method
4530 : const char *pszResampling = nullptr;
4531 : //! Whether the source band has a nodata value
4532 : bool bHasNoData = false;
4533 : //! Source band nodata value
4534 : double dfNoDataValue = 0;
4535 : //! Source color table
4536 : const GDALColorTable *poColorTable = nullptr;
4537 : //! Whether a single contributing source pixel at nodata should result
4538 : // in the target pixel to be at nodata too (only taken into account by
4539 : // average resampling)
4540 : bool bPropagateNoData = false;
4541 : };
4542 :
4543 : typedef CPLErr (*GDALResampleFunction)(const GDALOverviewResampleArgs &args,
4544 : const void *pChunk, void **ppDstBuffer,
4545 : GDALDataType *peDstBufferDataType);
4546 :
4547 : GDALResampleFunction GDALGetResampleFunction(const char *pszResampling,
4548 : int *pnRadius);
4549 :
4550 : std::string CPL_DLL GDALGetNormalizedOvrResampling(const char *pszResampling);
4551 :
4552 : GDALDataType GDALGetOvrWorkDataType(const char *pszResampling,
4553 : GDALDataType eSrcDataType);
4554 :
4555 : CPL_C_START
4556 :
4557 : CPLErr CPL_DLL
4558 : HFAAuxBuildOverviews(const char *pszOvrFilename, GDALDataset *poParentDS,
4559 : GDALDataset **ppoDS, int nBands, const int *panBandList,
4560 : int nNewOverviews, const int *panNewOverviewList,
4561 : const char *pszResampling, GDALProgressFunc pfnProgress,
4562 : void *pProgressData, CSLConstList papszOptions);
4563 :
4564 : CPLErr CPL_DLL GTIFFBuildOverviews(const char *pszFilename, int nBands,
4565 : GDALRasterBand *const *papoBandList,
4566 : int nOverviews, const int *panOverviewList,
4567 : const char *pszResampling,
4568 : GDALProgressFunc pfnProgress,
4569 : void *pProgressData,
4570 : CSLConstList papszOptions);
4571 :
4572 : int CPL_DLL GDALBandGetBestOverviewLevel(GDALRasterBand *poBand, int &nXOff,
4573 : int &nYOff, int &nXSize, int &nYSize,
4574 : int nBufXSize, int nBufYSize)
4575 : CPL_WARN_DEPRECATED("Use GDALBandGetBestOverviewLevel2 instead");
4576 : int CPL_DLL GDALBandGetBestOverviewLevel2(GDALRasterBand *poBand, int &nXOff,
4577 : int &nYOff, int &nXSize, int &nYSize,
4578 : int nBufXSize, int nBufYSize,
4579 : GDALRasterIOExtraArg *psExtraArg);
4580 :
4581 : int CPL_DLL GDALOvLevelAdjust(int nOvLevel, int nXSize)
4582 : CPL_WARN_DEPRECATED("Use GDALOvLevelAdjust2 instead");
4583 : int CPL_DLL GDALOvLevelAdjust2(int nOvLevel, int nXSize, int nYSize);
4584 : int CPL_DLL GDALComputeOvFactor(int nOvrXSize, int nRasterXSize, int nOvrYSize,
4585 : int nRasterYSize);
4586 :
4587 : GDALDataset CPL_DLL *GDALFindAssociatedAuxFile(const char *pszBasefile,
4588 : GDALAccess eAccess,
4589 : GDALDataset *poDependentDS);
4590 :
4591 : /* ==================================================================== */
4592 : /* Infrastructure to check that dataset characteristics are valid */
4593 : /* ==================================================================== */
4594 :
4595 : int CPL_DLL GDALCheckDatasetDimensions(int nXSize, int nYSize);
4596 : int CPL_DLL GDALCheckBandCount(int nBands, int bIsZeroAllowed);
4597 :
4598 : /* Internal use only */
4599 :
4600 : /* CPL_DLL exported, but only for in-tree drivers that can be built as plugins
4601 : */
4602 : int CPL_DLL GDALReadWorldFile2(const char *pszBaseFilename,
4603 : const char *pszExtension,
4604 : double *padfGeoTransform,
4605 : CSLConstList papszSiblingFiles,
4606 : char **ppszWorldFileNameOut);
4607 : int CPL_DLL GDALReadTabFile2(const char *pszBaseFilename,
4608 : double *padfGeoTransform, char **ppszWKT,
4609 : int *pnGCPCount, GDAL_GCP **ppasGCPs,
4610 : CSLConstList papszSiblingFiles,
4611 : char **ppszTabFileNameOut);
4612 :
4613 : void CPL_DLL GDALCopyRasterIOExtraArg(GDALRasterIOExtraArg *psDestArg,
4614 : GDALRasterIOExtraArg *psSrcArg);
4615 :
4616 : void CPL_DLL GDALExpandPackedBitsToByteAt0Or1(
4617 : const GByte *CPL_RESTRICT pabyInput, GByte *CPL_RESTRICT pabyOutput,
4618 : size_t nInputBits);
4619 :
4620 : void CPL_DLL GDALExpandPackedBitsToByteAt0Or255(
4621 : const GByte *CPL_RESTRICT pabyInput, GByte *CPL_RESTRICT pabyOutput,
4622 : size_t nInputBits);
4623 :
4624 : CPL_C_END
4625 :
4626 : std::unique_ptr<GDALDataset> CPL_DLL
4627 : GDALGetThreadSafeDataset(std::unique_ptr<GDALDataset> poDS, int nScopeFlags);
4628 :
4629 : GDALDataset CPL_DLL *GDALGetThreadSafeDataset(GDALDataset *poDS,
4630 : int nScopeFlags);
4631 :
4632 : void GDALNullifyOpenDatasetsList();
4633 : CPLMutex **GDALGetphDMMutex();
4634 : CPLMutex **GDALGetphDLMutex();
4635 : void GDALNullifyProxyPoolSingleton();
4636 : void GDALSetResponsiblePIDForCurrentThread(GIntBig responsiblePID);
4637 : GIntBig GDALGetResponsiblePIDForCurrentThread();
4638 :
4639 : CPLString GDALFindAssociatedFile(const char *pszBasename, const char *pszExt,
4640 : CSLConstList papszSiblingFiles, int nFlags);
4641 :
4642 : CPLErr CPL_DLL EXIFExtractMetadata(char **&papszMetadata, void *fpL,
4643 : int nOffset, int bSwabflag, int nTIFFHEADER,
4644 : int &nExifOffset, int &nInterOffset,
4645 : int &nGPSOffset);
4646 :
4647 : int GDALValidateOpenOptions(GDALDriverH hDriver,
4648 : const char *const *papszOptionOptions);
4649 : int GDALValidateOptions(const char *pszOptionList,
4650 : const char *const *papszOptionsToValidate,
4651 : const char *pszErrorMessageOptionType,
4652 : const char *pszErrorMessageContainerName);
4653 :
4654 : GDALRIOResampleAlg CPL_DLL
4655 : GDALRasterIOGetResampleAlg(const char *pszResampling);
4656 : const char *GDALRasterIOGetResampleAlg(GDALRIOResampleAlg eResampleAlg);
4657 :
4658 : void GDALRasterIOExtraArgSetResampleAlg(GDALRasterIOExtraArg *psExtraArg,
4659 : int nXSize, int nYSize, int nBufXSize,
4660 : int nBufYSize);
4661 :
4662 : GDALDataset *GDALCreateOverviewDataset(GDALDataset *poDS, int nOvrLevel,
4663 : bool bThisLevelOnly);
4664 :
4665 : // Should cover particular cases of #3573, #4183, #4506, #6578
4666 : // Behavior is undefined if fVal1 or fVal2 are NaN (should be tested before
4667 : // calling this function)
4668 :
4669 : // TODO: The expression `abs(fVal1 + fVal2)` looks strange; is this a bug?
4670 : // Should this be `abs(fVal1) + abs(fVal2)` instead?
4671 :
4672 15878413 : inline bool ARE_REAL_EQUAL(float fVal1, float fVal2, int ulp = 2)
4673 : {
4674 : using std::abs;
4675 30690718 : return fVal1 == fVal2 || /* Should cover infinity */
4676 14812305 : abs(fVal1 - fVal2) <
4677 30690718 : std::numeric_limits<float>::epsilon() * abs(fVal1 + fVal2) * ulp;
4678 : }
4679 :
4680 : // We are using `std::numeric_limits<float>::epsilon()` for backward
4681 : // compatibility
4682 3948479 : inline bool ARE_REAL_EQUAL(double dfVal1, double dfVal2, int ulp = 2)
4683 : {
4684 : using std::abs;
4685 4549355 : return dfVal1 == dfVal2 || /* Should cover infinity */
4686 600877 : abs(dfVal1 - dfVal2) < std::numeric_limits<float>::epsilon() *
4687 4549355 : abs(dfVal1 + dfVal2) * ulp;
4688 : }
4689 :
4690 : double GDALAdjustNoDataCloseToFloatMax(double dfVal);
4691 :
4692 : #define DIV_ROUND_UP(a, b) (((a) % (b)) == 0 ? ((a) / (b)) : (((a) / (b)) + 1))
4693 :
4694 : // Number of data samples that will be used to compute approximate statistics
4695 : // (minimum value, maximum value, etc.)
4696 : #define GDALSTAT_APPROX_NUMSAMPLES 2500
4697 :
4698 : void GDALSerializeGCPListToXML(CPLXMLNode *psParentNode,
4699 : const std::vector<gdal::GCP> &asGCPs,
4700 : const OGRSpatialReference *poGCP_SRS);
4701 : void GDALDeserializeGCPListFromXML(const CPLXMLNode *psGCPList,
4702 : std::vector<gdal::GCP> &asGCPs,
4703 : OGRSpatialReference **ppoGCP_SRS);
4704 :
4705 : void GDALSerializeOpenOptionsToXML(CPLXMLNode *psParentNode,
4706 : CSLConstList papszOpenOptions);
4707 : char CPL_DLL **
4708 : GDALDeserializeOpenOptionsFromXML(const CPLXMLNode *psParentNode);
4709 :
4710 : int GDALCanFileAcceptSidecarFile(const char *pszFilename);
4711 :
4712 : bool GDALCanReliablyUseSiblingFileList(const char *pszFilename);
4713 :
4714 : typedef enum
4715 : {
4716 : GSF_UNSIGNED_INT,
4717 : GSF_SIGNED_INT,
4718 : GSF_FLOATING_POINT,
4719 : } GDALBufferSampleFormat;
4720 :
4721 : bool CPL_DLL GDALBufferHasOnlyNoData(const void *pBuffer, double dfNoDataValue,
4722 : size_t nWidth, size_t nHeight,
4723 : size_t nLineStride, size_t nComponents,
4724 : int nBitsPerSample,
4725 : GDALBufferSampleFormat nSampleFormat);
4726 :
4727 : bool CPL_DLL GDALCopyNoDataValue(GDALRasterBand *poDstBand,
4728 : GDALRasterBand *poSrcBand,
4729 : bool *pbCannotBeExactlyRepresented = nullptr);
4730 :
4731 : double CPL_DLL GDALGetNoDataValueCastToDouble(int64_t nVal);
4732 : double CPL_DLL GDALGetNoDataValueCastToDouble(uint64_t nVal);
4733 :
4734 : // Remove me in GDAL 4.0. See GetMetadataItem() implementation
4735 : // Internal use in GDAL only !
4736 : // Declaration copied in swig/include/gdal.i
4737 : void CPL_DLL GDALEnablePixelTypeSignedByteWarning(GDALRasterBandH hBand,
4738 : bool b);
4739 :
4740 : std::string CPL_DLL GDALGetCompressionFormatForJPEG(VSILFILE *fp);
4741 : std::string CPL_DLL GDALGetCompressionFormatForJPEG(const void *pBuffer,
4742 : size_t nBufferSize);
4743 :
4744 : GDALRasterAttributeTable CPL_DLL *GDALCreateRasterAttributeTableFromMDArrays(
4745 : GDALRATTableType eTableType,
4746 : const std::vector<std::shared_ptr<GDALMDArray>> &apoArrays,
4747 : const std::vector<GDALRATFieldUsage> &aeUsages);
4748 :
4749 : GDALColorInterp CPL_DLL
4750 : GDALGetColorInterpFromSTACCommonName(const char *pszName);
4751 : const char CPL_DLL *
4752 : GDALGetSTACCommonNameFromColorInterp(GDALColorInterp eInterp);
4753 :
4754 : std::string CPL_DLL GDALGetCacheDirectory();
4755 :
4756 : bool GDALDoesFileOrDatasetExist(const char *pszName,
4757 : const char **ppszType = nullptr,
4758 : GDALDriver **ppDriver = nullptr);
4759 :
4760 : std::string CPL_DLL
4761 : GDALGetMessageAboutMissingPluginDriver(GDALDriver *poMissingPluginDriver);
4762 :
4763 : std::string GDALPrintDriverList(int nOptions, bool bJSON);
4764 :
4765 : struct GDALColorAssociation
4766 : {
4767 : double dfVal;
4768 : int nR;
4769 : int nG;
4770 : int nB;
4771 : int nA;
4772 : };
4773 :
4774 : std::vector<GDALColorAssociation> GDALLoadTextColorMap(const char *pszFilename,
4775 : GDALRasterBand *poBand);
4776 :
4777 : void GDALRescaleGeoTransform(double adfGeoTransform[6], double dfXRatio,
4778 : double dfYRatio);
4779 :
4780 : // Macro used so that Identify and driver metadata methods in drivers built
4781 : // as plugin can be duplicated in libgdal core and in the driver under different
4782 : // names
4783 : #ifdef PLUGIN_FILENAME
4784 : #define PLUGIN_SYMBOL_NAME(x) GDAL_core_##x
4785 : #else
4786 : #define PLUGIN_SYMBOL_NAME(x) GDAL_driver_##x
4787 : #endif
4788 :
4789 : //! @endcond
4790 :
4791 : #endif /* ndef GDAL_PRIV_H_INCLUDED */
|