LCOV - code coverage report
Current view: top level - gcore - gdal_priv.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 326 344 94.8 %
Date: 2025-05-31 00:00:17 Functions: 160 174 92.0 %

          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 */

Generated by: LCOV version 1.14