LCOV - code coverage report
Current view: top level - gcore - gdal_priv.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 427 445 96.0 %
Date: 2025-09-17 18:03:44 Functions: 220 236 93.2 %

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

Generated by: LCOV version 1.14