1 /******************************************************************************
2  * $Id: gdal_priv.h 4837705836841b794f4d30bf30430f11a1496956 2021-07-12 14:16:37 +0200 Even Rouault $
3  *
4  * Name:     gdal_priv.h
5  * Project:  GDAL Core
6  * Purpose:  GDAL Core C++/Private declarations.
7  * Author:   Frank Warmerdam, warmerdam@pobox.com
8  *
9  ******************************************************************************
10  * Copyright (c) 1998, Frank Warmerdam
11  * Copyright (c) 2007-2014, Even Rouault <even dot rouault at spatialys.com>
12  *
13  * Permission is hereby granted, free of charge, to any person obtaining a
14  * copy of this software and associated documentation files (the "Software"),
15  * to deal in the Software without restriction, including without limitation
16  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17  * and/or sell copies of the Software, and to permit persons to whom the
18  * Software is furnished to do so, subject to the following conditions:
19  *
20  * The above copyright notice and this permission notice shall be included
21  * in all copies or substantial portions of the Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29  * DEALINGS IN THE SOFTWARE.
30  ****************************************************************************/
31 
32 #ifndef GDAL_PRIV_H_INCLUDED
33 #define GDAL_PRIV_H_INCLUDED
34 
35 /**
36  * \file gdal_priv.h
37  *
38  * C++ GDAL entry points.
39  */
40 
41 /* -------------------------------------------------------------------- */
42 /*      Predeclare various classes before pulling in gdal.h, the        */
43 /*      public declarations.                                            */
44 /* -------------------------------------------------------------------- */
45 class GDALMajorObject;
46 class GDALDataset;
47 class GDALRasterBand;
48 class GDALDriver;
49 class GDALRasterAttributeTable;
50 class GDALProxyDataset;
51 class GDALProxyRasterBand;
52 class GDALAsyncReader;
53 
54 /* -------------------------------------------------------------------- */
55 /*      Pull in the public declarations.  This gets the C apis, and     */
56 /*      also various constants.  However, we will still get to          */
57 /*      provide the real class definitions for the GDAL classes.        */
58 /* -------------------------------------------------------------------- */
59 
60 #include "gdal.h"
61 #include "gdal_frmts.h"
62 #include "cpl_vsi.h"
63 #include "cpl_conv.h"
64 #include "cpl_string.h"
65 #include "cpl_minixml.h"
66 #include "cpl_multiproc.h"
67 #include "cpl_atomic_ops.h"
68 
69 #include <stdarg.h>
70 
71 #include <cmath>
72 #include <cstdint>
73 #include <iterator>
74 #include <limits>
75 #include <map>
76 #include <memory>
77 #include <vector>
78 
79 #include "ogr_core.h"
80 #include "ogr_feature.h"
81 
82 //! @cond Doxygen_Suppress
83 #define GMO_VALID                0x0001
84 #define GMO_IGNORE_UNIMPLEMENTED 0x0002
85 #define GMO_SUPPORT_MD           0x0004
86 #define GMO_SUPPORT_MDMD         0x0008
87 #define GMO_MD_DIRTY             0x0010
88 #define GMO_PAM_CLASS            0x0020
89 //! @endcond
90 
91 /************************************************************************/
92 /*                       GDALMultiDomainMetadata                        */
93 /************************************************************************/
94 
95 //! @cond Doxygen_Suppress
96 class CPL_DLL GDALMultiDomainMetadata
97 {
98 private:
99     char **papszDomainList;
100     CPLStringList **papoMetadataLists;
101 
102 public:
103     GDALMultiDomainMetadata();
104     ~GDALMultiDomainMetadata();
105 
106     int         XMLInit( CPLXMLNode *psMetadata, int bMerge );
107     CPLXMLNode  *Serialize();
108 
109     char      **GetDomainList() { return papszDomainList; }
110 
111     char      **GetMetadata( const char * pszDomain = "" );
112     CPLErr      SetMetadata( char ** papszMetadata,
113                              const char * pszDomain = "" );
114     const char *GetMetadataItem( const char * pszName,
115                                  const char * pszDomain = "" );
116     CPLErr      SetMetadataItem( const char * pszName,
117                                  const char * pszValue,
118                                  const char * pszDomain = "" );
119 
120     void        Clear();
121 
122   private:
123     CPL_DISALLOW_COPY_ASSIGN(GDALMultiDomainMetadata)
124 };
125 //! @endcond
126 
127 /* ******************************************************************** */
128 /*                           GDALMajorObject                            */
129 /*                                                                      */
130 /*      Base class providing metadata, description and other            */
131 /*      services shared by major objects.                               */
132 /* ******************************************************************** */
133 
134 /** Object with metadata. */
135 class CPL_DLL GDALMajorObject
136 {
137   protected:
138 //! @cond Doxygen_Suppress
139     int                 nFlags; // GMO_* flags.
140     CPLString           sDescription{};
141     GDALMultiDomainMetadata oMDMD{};
142 
143 //! @endcond
144 
145     char               **BuildMetadataDomainList( char** papszList,
146                                                   int bCheckNonEmpty, ... ) CPL_NULL_TERMINATED;
147   public:
148                         GDALMajorObject();
149     virtual            ~GDALMajorObject();
150 
151     int                 GetMOFlags() const;
152     void                SetMOFlags( int nFlagsIn );
153 
154     virtual const char *GetDescription() const;
155     virtual void        SetDescription( const char * );
156 
157     virtual char      **GetMetadataDomainList();
158 
159     virtual char      **GetMetadata( const char * pszDomain = "" );
160     virtual CPLErr      SetMetadata( char ** papszMetadata,
161                                      const char * pszDomain = "" );
162     virtual const char *GetMetadataItem( const char * pszName,
163                                          const char * pszDomain = "" );
164     virtual CPLErr      SetMetadataItem( const char * pszName,
165                                          const char * pszValue,
166                                          const char * pszDomain = "" );
167 
168     /** Convert a GDALMajorObject* to a GDALMajorObjectH.
169      * @since GDAL 2.3
170      */
171     static inline GDALMajorObjectH ToHandle(GDALMajorObject* poMajorObject)
172         { return static_cast<GDALMajorObjectH>(poMajorObject); }
173 
174     /** Convert a GDALMajorObjectH to a GDALMajorObject*.
175      * @since GDAL 2.3
176      */
177     static inline GDALMajorObject* FromHandle(GDALMajorObjectH hMajorObject)
178         { return static_cast<GDALMajorObject*>(hMajorObject); }
179 };
180 
181 /* ******************************************************************** */
182 /*                         GDALDefaultOverviews                         */
183 /* ******************************************************************** */
184 
185 //! @cond Doxygen_Suppress
186 class CPL_DLL GDALDefaultOverviews
187 {
188     friend class GDALDataset;
189 
190     GDALDataset *poDS;
191     GDALDataset *poODS;
192 
193     CPLString   osOvrFilename{};
194 
195     bool        bOvrIsAux;
196 
197     bool        bCheckedForMask;
198     bool        bOwnMaskDS;
199     GDALDataset *poMaskDS;
200 
201     // For "overview datasets" we record base level info so we can
202     // find our way back to get overview masks.
203     GDALDataset *poBaseDS;
204 
205     // Stuff for deferred initialize/overviewscans.
206     bool        bCheckedForOverviews;
207     void        OverviewScan();
208     char       *pszInitName;
209     bool        bInitNameIsOVR;
210     char      **papszInitSiblingFiles;
211 
212   public:
213                GDALDefaultOverviews();
214                ~GDALDefaultOverviews();
215 
216     void       Initialize( GDALDataset *poDSIn, const char *pszName = nullptr,
217                            char **papszSiblingFiles = nullptr,
218                            int bNameIsOVR = FALSE );
219 
220     void       TransferSiblingFiles( char** papszSiblingFiles );
MarkPamDirty()221 
222     int        IsInitialized();
GetPamFlags()223 
224     int        CloseDependentDatasets();
225 
226     // Overview Related
227 
228     int        GetOverviewCount( int nBand );
229     GDALRasterBand *GetOverview( int nBand, int iOverview );
230 
231     CPLErr     BuildOverviews( const char * pszBasename,
232                                const char * pszResampling,
233                                int nOverviews, int * panOverviewList,
234                                int nBands, int * panBandList,
235                                GDALProgressFunc pfnProgress,
236                                void *pProgressData );
237 
238     CPLErr     BuildOverviewsSubDataset( const char * pszPhysicalFile,
239                                          const char * pszResampling,
240                                          int nOverviews, int * panOverviewList,
241                                          int nBands, int * panBandList,
242                                          GDALProgressFunc pfnProgress,
243                                          void *pProgressData );
244 
245     CPLErr     CleanOverviews();
246 
247     // Mask Related
248 
249     CPLErr     CreateMaskBand( int nFlags, int nBand = -1 );
250     GDALRasterBand *GetMaskBand( int nBand );
251     int        GetMaskFlags( int nBand );
252 
253     int        HaveMaskFile( char **papszSiblings = nullptr,
254                              const char *pszBasename = nullptr );
255 
256     char**     GetSiblingFiles() { return papszInitSiblingFiles; }
257 
258   private:
259     CPL_DISALLOW_COPY_ASSIGN(GDALDefaultOverviews)
260 };
261 //! @endcond
262 
263 /* ******************************************************************** */
264 /*                             GDALOpenInfo                             */
265 /* ******************************************************************** */
266 
267 /** Class for dataset open functions. */
268 class CPL_DLL GDALOpenInfo
269 {
270     bool        bHasGotSiblingFiles;
271     char        **papszSiblingFiles;
272     int         nHeaderBytesTried;
273 
274   public:
275                 GDALOpenInfo( const char * pszFile, int nOpenFlagsIn,
276                               const char * const * papszSiblingFiles = nullptr );
277                 ~GDALOpenInfo( void );
278 
279     /** Filename */
280     char        *pszFilename;
281     /** Open options */
282     char**      papszOpenOptions;
283 
284     /** Access flag */
285     GDALAccess  eAccess;
286     /** Open flags */
287     int         nOpenFlags;
288 
289     /** Whether stat()'ing the file was successful */
290     int         bStatOK;
291     /** Whether the file is a directory */
292     int         bIsDirectory;
293 
294     /** Pointer to the file */
295     VSILFILE   *fpL;
296 
297     /** Number of bytes in pabyHeader */
298     int         nHeaderBytes;
299     /** Buffer with first bytes of the file */
300     GByte       *pabyHeader;
301 
302     /** Allowed drivers (NULL for all) */
303     const char* const* papszAllowedDrivers;
304 
305     int         TryToIngest(int nBytes);
306     char      **GetSiblingFiles();
307     char      **StealSiblingFiles();
308     bool        AreSiblingFilesLoaded() const;
309 
310   private:
311     CPL_DISALLOW_COPY_ASSIGN(GDALOpenInfo)
312 };
313 
314 /* ******************************************************************** */
315 /*                             GDALDataset                              */
316 /* ******************************************************************** */
317 
318 class OGRLayer;
319 class OGRGeometry;
320 class OGRSpatialReference;
321 class OGRStyleTable;
322 class swq_select;
323 class swq_select_parse_options;
324 class GDALGroup;
325 
326 //! @cond Doxygen_Suppress
327 typedef struct GDALSQLParseInfo GDALSQLParseInfo;
328 //! @endcond
329 
330 //! @cond Doxygen_Suppress
331 #ifdef GDAL_COMPILATION
332 #define OPTIONAL_OUTSIDE_GDAL(val)
333 #else
334 #define OPTIONAL_OUTSIDE_GDAL(val) = val
335 #endif
336 //! @endcond
337 
338 /** A set of associated raster bands, usually from one file. */
339 class CPL_DLL GDALDataset : public GDALMajorObject
340 {
341     friend GDALDatasetH CPL_STDCALL GDALOpenEx( const char* pszFilename,
342                                  unsigned int nOpenFlags,
343                                  const char* const* papszAllowedDrivers,
344                                  const char* const* papszOpenOptions,
345                                  const char* const* papszSiblingFiles );
346     friend void CPL_STDCALL GDALClose( GDALDatasetH hDS );
347 
348     friend class GDALDriver;
GetPamInfo()349     friend class GDALDefaultOverviews;
350     friend class GDALProxyDataset;
351     friend class GDALDriverManager;
352 
353     CPL_INTERNAL void AddToDatasetOpenList();
354 
355     CPL_INTERNAL static void ReportErrorV(
356                                      const char* pszDSName,
357                                      CPLErr eErrClass, CPLErrorNum err_no,
358                                      const char *fmt, va_list args);
359   protected:
360 //! @cond Doxygen_Suppress
361     GDALDriver  *poDriver = nullptr;
362     GDALAccess  eAccess = GA_ReadOnly;
363 
364     // Stored raster information.
365     int         nRasterXSize = 512;
366     int         nRasterYSize = 512;
367     int         nBands = 0;
368     GDALRasterBand **papoBands = nullptr;
369 
370     int         nOpenFlags = 0;
371 
372     int         nRefCount = 1;
373     bool        bForceCachedIO = false;
374     bool        bShared = false;
375     bool        bIsInternal = true;
376     bool        bSuppressOnClose = false;
377 
378     mutable std::map<std::string, std::unique_ptr<OGRFieldDomain>> m_oMapFieldDomains{};
379 
380                 GDALDataset(void);
381     explicit    GDALDataset(int bForceCachedIO);
382 
383     void        RasterInitialize( int, int );
384     void        SetBand( int, GDALRasterBand * );
385 
386     GDALDefaultOverviews oOvManager{};
387 
388     virtual CPLErr IBuildOverviews( const char *, int, int *,
389                                     int, int *, GDALProgressFunc, void * );
390 
391     virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
392                               void *, int, int, GDALDataType,
393                               int, int *, GSpacing, GSpacing, GSpacing,
394                               GDALRasterIOExtraArg* psExtraArg ) CPL_WARN_UNUSED_RESULT;
395 
396     CPLErr BlockBasedRasterIO( GDALRWFlag, int, int, int, int,
397                                void *, int, int, GDALDataType,
398                                int, int *, GSpacing, GSpacing, GSpacing,
399                                GDALRasterIOExtraArg* psExtraArg ) CPL_WARN_UNUSED_RESULT;
400     void   BlockBasedFlushCache();
401 
402     CPLErr BandBasedRasterIO( GDALRWFlag eRWFlag,
403                                int nXOff, int nYOff, int nXSize, int nYSize,
404                                void * pData, int nBufXSize, int nBufYSize,
405                                GDALDataType eBufType,
406                                int nBandCount, int *panBandMap,
407                                GSpacing nPixelSpace, GSpacing nLineSpace,
408                                GSpacing nBandSpace,
409                                GDALRasterIOExtraArg* psExtraArg ) CPL_WARN_UNUSED_RESULT;
410 
411     CPLErr RasterIOResampled( GDALRWFlag eRWFlag,
412                                int nXOff, int nYOff, int nXSize, int nYSize,
413                                void * pData, int nBufXSize, int nBufYSize,
414                                GDALDataType eBufType,
415                                int nBandCount, int *panBandMap,
416                                GSpacing nPixelSpace, GSpacing nLineSpace,
417                                GSpacing nBandSpace,
418                                GDALRasterIOExtraArg* psExtraArg ) CPL_WARN_UNUSED_RESULT;
419 
420     CPLErr ValidateRasterIOOrAdviseReadParameters(
421                                const char* pszCallingFunc,
422                                int* pbStopProcessingOnCENone,
423                                int nXOff, int nYOff, int nXSize, int nYSize,
424                                int nBufXSize, int nBufYSize,
425                                int nBandCount, int *panBandMap);
426 
427     CPLErr TryOverviewRasterIO( GDALRWFlag eRWFlag,
428                                 int nXOff, int nYOff, int nXSize, int nYSize,
429                                 void * pData, int nBufXSize, int nBufYSize,
430                                 GDALDataType eBufType,
431                                 int nBandCount, int *panBandMap,
432                                 GSpacing nPixelSpace, GSpacing nLineSpace,
433                                 GSpacing nBandSpace,
434                                 GDALRasterIOExtraArg* psExtraArg,
435                                 int* pbTried);
436 
437     void  ShareLockWithParentDataset(GDALDataset* poParentDataset);
438 
439 //! @endcond
440     virtual int         CloseDependentDatasets();
441 //! @cond Doxygen_Suppress
442     int                 ValidateLayerCreationOptions( const char* const* papszLCO );
443 
444     char            **papszOpenOptions = nullptr;
445 
446     friend class GDALRasterBand;
447 
448     // The below methods related to read write mutex are fragile logic, and
449     // should not be used by out-of-tree code if possible.
450     int                 EnterReadWrite(GDALRWFlag eRWFlag);
451     void                LeaveReadWrite();
452     void                InitRWLock();
453 
454     void                TemporarilyDropReadWriteLock();
455     void                ReacquireReadWriteLock();
456 
457     void                DisableReadWriteMutex();
458 
459     int          AcquireMutex();
460     void         ReleaseMutex();
461 //! @endcond
462 
463   public:
464      ~GDALDataset() override;
465 
466     int GetRasterXSize();
467     int GetRasterYSize();
468     int GetRasterCount();
469     GDALRasterBand *GetRasterBand( int );
470 
471     /** Class returned by GetBands() that act as a container for raster bands. */
472     class CPL_DLL Bands
473     {
474       private:
475 
476         friend class GDALDataset;
477         GDALDataset* m_poSelf;
478         CPL_INTERNAL explicit Bands(GDALDataset* poSelf): m_poSelf(poSelf) {}
479 
480         class CPL_DLL Iterator
481         {
482                 struct Private;
483                 std::unique_ptr<Private> m_poPrivate;
484             public:
485                 Iterator(GDALDataset* poDS, bool bStart);
486                 Iterator(const Iterator& oOther); // declared but not defined. Needed for gcc 5.4 at least
487                 Iterator(Iterator&& oOther) noexcept; // declared but not defined. Needed for gcc 5.4 at least
488                 ~Iterator();
489                 GDALRasterBand* operator*();
490                 Iterator& operator++();
491                 bool operator!=(const Iterator& it) const;
492         };
493 
494       public:
495 
496         const Iterator begin() const;
497 
498         const Iterator end() const;
499 
500         size_t size() const;
501 
502         GDALRasterBand* operator[](int iBand);
503         GDALRasterBand* operator[](size_t iBand);
504     };
505 
506     Bands              GetBands();
507 
508     virtual void FlushCache(void);
509 
510     virtual const OGRSpatialReference* GetSpatialRef() const;
511     virtual CPLErr SetSpatialRef(const OGRSpatialReference* poSRS);
512 
513     // Compatibility layer
514     const char *GetProjectionRef(void) const;
515     CPLErr SetProjection( const char * pszProjection );
516 
517     virtual CPLErr GetGeoTransform( double * padfTransform );
518     virtual CPLErr SetGeoTransform( double * padfTransform );
519 
520     virtual CPLErr        AddBand( GDALDataType eType,
521                                    char **papszOptions=nullptr );
522 
523     virtual void *GetInternalHandle( const char * pszHandleName );
524     virtual GDALDriver *GetDriver(void);
525     virtual char      **GetFileList(void);
526 
527     virtual     const char* GetDriverName();
528 
529     virtual const OGRSpatialReference* GetGCPSpatialRef() const;
530     virtual int    GetGCPCount();
531     virtual const GDAL_GCP *GetGCPs();
532     virtual CPLErr SetGCPs( int nGCPCount, const GDAL_GCP *pasGCPList,
533                             const OGRSpatialReference * poGCP_SRS );
534 
535     // Compatibility layer
536     const char *GetGCPProjection();
537     CPLErr SetGCPs( int nGCPCount, const GDAL_GCP *pasGCPList,
538                     const char *pszGCPProjection );
539 
540     virtual CPLErr AdviseRead( int nXOff, int nYOff, int nXSize, int nYSize,
541                                int nBufXSize, int nBufYSize,
542                                GDALDataType eDT,
543                                int nBandCount, int *panBandList,
544                                char **papszOptions );
545 
546     virtual CPLErr          CreateMaskBand( int nFlagsIn );
547 
548     virtual GDALAsyncReader*
549         BeginAsyncReader(int nXOff, int nYOff, int nXSize, int nYSize,
550                          void *pBuf, int nBufXSize, int nBufYSize,
551                          GDALDataType eBufType,
552                          int nBandCount, int* panBandMap,
553                          int nPixelSpace, int nLineSpace, int nBandSpace,
554                          char **papszOptions);
555     virtual void EndAsyncReader(GDALAsyncReader *);
556 
557 //! @cond Doxygen_Suppress
558     struct RawBinaryLayout
559     {
560         enum class Interleaving
561         {
562             UNKNOWN,
563             BIP,
564             BIL,
565             BSQ
566         };
567         std::string         osRawFilename{};
568         Interleaving        eInterleaving = Interleaving::UNKNOWN;
569         GDALDataType        eDataType = GDT_Unknown;
570         bool                bLittleEndianOrder = false;
571 
572         vsi_l_offset        nImageOffset = 0;
573         GIntBig             nPixelOffset = 0;
574         GIntBig             nLineOffset = 0;
575         GIntBig             nBandOffset = 0;
576     };
577 
578     virtual bool GetRawBinaryLayout(RawBinaryLayout&);
579 //! @endcond
580 
581     CPLErr      RasterIO( GDALRWFlag, int, int, int, int,
582                           void *, int, int, GDALDataType,
583                           int, int *, GSpacing, GSpacing, GSpacing,
584                           GDALRasterIOExtraArg* psExtraArg
585 #ifndef DOXYGEN_SKIP
586                           OPTIONAL_OUTSIDE_GDAL(nullptr)
587 #endif
588                           ) CPL_WARN_UNUSED_RESULT;
589 
590     int           Reference();
591     int           Dereference();
592     int           ReleaseRef();
593 
594     /** Return access mode.
595      * @return access mode.
596      */
597     GDALAccess    GetAccess() const { return eAccess; }
598 
599     int           GetShared() const;
600     void          MarkAsShared();
601 
602     /** Set that the dataset must be deleted on close. */
603     void          MarkSuppressOnClose() { bSuppressOnClose = true; }
604 
605     /** Return open options.
606      * @return open options.
607      */
608     char        **GetOpenOptions() { return papszOpenOptions; }
609 
610     static GDALDataset **GetOpenDatasets( int *pnDatasetCount );
611 
612     CPLErr BuildOverviews( const char *, int, int *,
613                            int, int *, GDALProgressFunc, void * );
614 
615 #ifndef DOXYGEN_XML
616     void ReportError(CPLErr eErrClass, CPLErrorNum err_no, const char *fmt, ...)  CPL_PRINT_FUNC_FORMAT (4, 5);
617 
618     static void ReportError(const char* pszDSName,
619                             CPLErr eErrClass, CPLErrorNum err_no,
620                             const char *fmt, ...)  CPL_PRINT_FUNC_FORMAT (4, 5);
621 #endif
622 
623     char ** GetMetadata(const char * pszDomain = "") override;
624 
625 // Only defined when Doxygen enabled
626 #ifdef DOXYGEN_SKIP
627     CPLErr      SetMetadata( char ** papszMetadata,
628                              const char * pszDomain ) override;
629     CPLErr      SetMetadataItem( const char * pszName,
630                                  const char * pszValue,
631                                  const char * pszDomain ) override;
632 #endif
633 
634     char **GetMetadataDomainList() override;
635 
636     virtual void ClearStatistics();
637 
638     /** Convert a GDALDataset* to a GDALDatasetH.
639      * @since GDAL 2.3
640      */
641     static inline GDALDatasetH ToHandle(GDALDataset* poDS)
642         { return static_cast<GDALDatasetH>(poDS); }
643 
644     /** Convert a GDALDatasetH to a GDALDataset*.
645      * @since GDAL 2.3
646      */
647     static inline GDALDataset* FromHandle(GDALDatasetH hDS)
648         { return static_cast<GDALDataset*>(hDS); }
649 
650     /** @see GDALOpenEx().
651      * @since GDAL 2.3
652      */
653     static GDALDataset* Open( const char* pszFilename,
654                               unsigned int nOpenFlags = 0,
655                               const char* const* papszAllowedDrivers = nullptr,
656                               const char* const* papszOpenOptions = nullptr,
657                               const char* const* papszSiblingFiles = nullptr )
658     {
659         return FromHandle(GDALOpenEx(pszFilename, nOpenFlags,
660                                       papszAllowedDrivers,
661                                       papszOpenOptions,
662                                       papszSiblingFiles));
663     }
664 
665     /** Object returned by GetFeatures() iterators */
666     struct FeatureLayerPair
667     {
668         /** Unique pointer to a OGRFeature. */
669         OGRFeatureUniquePtr feature{};
670 
671         /** Layer to which the feature belongs to. */
672         OGRLayer* layer = nullptr;
673     };
674 
675 //! @cond Doxygen_Suppress
676     // SetEnableOverviews() only to be used by GDALOverviewDataset
677     void SetEnableOverviews(bool bEnable);
678 
679     // Only to be used by driver's GetOverviewCount() method.
680     bool AreOverviewsEnabled() const;
681 //! @endcond
682 
683 private:
684     class Private;
685     Private *m_poPrivate;
686 
687     CPL_INTERNAL OGRLayer*       BuildLayerFromSelectInfo(swq_select* psSelectInfo,
688                                              OGRGeometry *poSpatialFilter,
689                                              const char *pszDialect,
690                                              swq_select_parse_options* poSelectParseOptions);
691     CPLStringList oDerivedMetadataList{};
692 
693   public:
694 
695     virtual int         GetLayerCount();
696     virtual OGRLayer    *GetLayer(int iLayer);
697 
698     /** Class returned by GetLayers() that acts as a range of layers.
699      * @since GDAL 2.3
700      */
701     class CPL_DLL Layers
702     {
703       private:
704 
705         friend class GDALDataset;
706         GDALDataset* m_poSelf;
707         CPL_INTERNAL explicit Layers(GDALDataset* poSelf): m_poSelf(poSelf) {}
708 
709       public:
710 
711         /** Layer iterator.
712          * @since GDAL 2.3
713          */
714         class CPL_DLL Iterator
715         {
716                 struct Private;
717                 std::unique_ptr<Private> m_poPrivate;
718             public:
719 
720                 using value_type = OGRLayer*; /**< value_type */
721                 using reference = OGRLayer*; /**< reference */
722                 using difference_type = void; /**< difference_type */
723                 using pointer = void; /**< pointer */
724                 using iterator_category = std::input_iterator_tag; /**< iterator_category */
725 
726                 Iterator(); /**< Default constructor */
727                 Iterator(GDALDataset* poDS, bool bStart);  /**< Constructor */
728                 Iterator(const Iterator& oOther);  /**< Copy constructor */
729                 Iterator(Iterator&& oOther) noexcept;  /**< Move constructor */
730                 ~Iterator(); /**< Destructor */
731 
732                 Iterator& operator=(const Iterator& oOther);  /**< Assignment operator */
733                 Iterator& operator=(Iterator&& oOther) noexcept; /**< Move assignment operator */
734 
735                 OGRLayer* operator*() const; /**< Dereference operator */
736                 Iterator& operator++(); /**< Pre-increment operator */
737                 Iterator operator++(int); /**< Post-increment operator */
738                 bool operator!=(const Iterator& it) const; /**< Difference comparison operator */
739         };
740 
741         Iterator begin() const;
742         Iterator end() const;
743 
744         size_t size() const;
745 
746         OGRLayer* operator[](int iLayer);
747         OGRLayer* operator[](size_t iLayer);
748         OGRLayer* operator[](const char* pszLayername);
749     };
750 
751     Layers              GetLayers();
752 
753     virtual OGRLayer    *GetLayerByName(const char *);
754     virtual OGRErr      DeleteLayer(int iLayer);
755 
756     virtual void        ResetReading();
757     virtual OGRFeature* GetNextFeature( OGRLayer** ppoBelongingLayer,
758                                         double* pdfProgressPct,
759                                         GDALProgressFunc pfnProgress,
760                                         void* pProgressData );
761 
762 
763     /** Class returned by GetFeatures() that act as a container for vector features. */
764     class CPL_DLL Features
765     {
766       private:
767 
768         friend class GDALDataset;
769         GDALDataset* m_poSelf;
770         CPL_INTERNAL explicit Features(GDALDataset* poSelf): m_poSelf(poSelf) {}
771 
772         class CPL_DLL Iterator
773         {
774                 struct Private;
775                 std::unique_ptr<Private> m_poPrivate;
776             public:
777                 Iterator(GDALDataset* poDS, bool bStart);
778                 Iterator(const Iterator& oOther); // declared but not defined. Needed for gcc 5.4 at least
779                 Iterator(Iterator&& oOther) noexcept; // declared but not defined. Needed for gcc 5.4 at least
780                 ~Iterator();
781                 const FeatureLayerPair& operator*() const;
782                 Iterator& operator++();
783                 bool operator!=(const Iterator& it) const;
784         };
785 
786       public:
787 
788         const Iterator begin() const;
789 
790         const Iterator end() const;
791     };
792 
793     Features            GetFeatures();
794 
795     virtual int         TestCapability( const char * );
796 
797     virtual const OGRFieldDomain* GetFieldDomain(const std::string& name) const;
798 
799     virtual bool        AddFieldDomain(std::unique_ptr<OGRFieldDomain>&& domain,
800                                        std::string& failureReason);
801 
802     virtual OGRLayer   *CreateLayer( const char *pszName,
803                                      OGRSpatialReference *poSpatialRef = nullptr,
804                                      OGRwkbGeometryType eGType = wkbUnknown,
805                                      char ** papszOptions = nullptr );
806     virtual OGRLayer   *CopyLayer( OGRLayer *poSrcLayer,
807                                    const char *pszNewName,
808                                    char **papszOptions = nullptr );
809 
810     virtual OGRStyleTable *GetStyleTable();
811     virtual void        SetStyleTableDirectly( OGRStyleTable *poStyleTable );
812 
813     virtual void        SetStyleTable(OGRStyleTable *poStyleTable);
814 
815     virtual OGRLayer *  ExecuteSQL( const char *pszStatement,
816                                     OGRGeometry *poSpatialFilter,
817                                     const char *pszDialect );
818     virtual void        ReleaseResultSet( OGRLayer * poResultsSet );
819     virtual OGRErr      AbortSQL( );
820 
821     int                 GetRefCount() const;
822     int                 GetSummaryRefCount() const;
823     OGRErr              Release();
824 
825     virtual OGRErr      StartTransaction(int bForce=FALSE);
826     virtual OGRErr      CommitTransaction();
827     virtual OGRErr      RollbackTransaction();
828 
829     virtual std::shared_ptr<GDALGroup> GetRootGroup() const;
830 
831 //! @cond Doxygen_Suppress
832     static int          IsGenericSQLDialect(const char* pszDialect);
833 
834     // Semi-public methods. Only to be used by in-tree drivers.
835     GDALSQLParseInfo*   BuildParseInfo(swq_select* psSelectInfo,
836                                        swq_select_parse_options* poSelectParseOptions);
837     static void         DestroyParseInfo(GDALSQLParseInfo* psParseInfo );
838     OGRLayer *          ExecuteSQL( const char *pszStatement,
839                                     OGRGeometry *poSpatialFilter,
840                                     const char *pszDialect,
841                                     swq_select_parse_options* poSelectParseOptions);
842 //! @endcond
843 
844   protected:
845     virtual OGRLayer   *ICreateLayer( const char *pszName,
846                                      OGRSpatialReference *poSpatialRef = nullptr,
847                                      OGRwkbGeometryType eGType = wkbUnknown,
848                                      char ** papszOptions = nullptr );
849 
850 //! @cond Doxygen_Suppress
851     OGRErr              ProcessSQLCreateIndex( const char * );
852     OGRErr              ProcessSQLDropIndex( const char * );
853     OGRErr              ProcessSQLDropTable( const char * );
854     OGRErr              ProcessSQLAlterTableAddColumn( const char * );
855     OGRErr              ProcessSQLAlterTableDropColumn( const char * );
856     OGRErr              ProcessSQLAlterTableAlterColumn( const char * );
857     OGRErr              ProcessSQLAlterTableRenameColumn( const char * );
858 
859     OGRStyleTable      *m_poStyleTable = nullptr;
860 
861     // Compatibility layers
862     const OGRSpatialReference* GetSpatialRefFromOldGetProjectionRef() const;
863     CPLErr OldSetProjectionFromSetSpatialRef(const OGRSpatialReference* poSRS);
864     const OGRSpatialReference* GetGCPSpatialRefFromOldGetGCPProjection() const;
865     CPLErr OldSetGCPsFromNew( int nGCPCount, const GDAL_GCP *pasGCPList,
866                               const OGRSpatialReference * poGCP_SRS );
867 
868     friend class GDALProxyPoolDataset;
869     virtual const char *_GetProjectionRef();
870     const char *GetProjectionRefFromSpatialRef(const OGRSpatialReference*) const;
871     virtual const char *_GetGCPProjection();
872     const char *GetGCPProjectionFromSpatialRef(const OGRSpatialReference* poSRS) const;
873     virtual CPLErr _SetProjection( const char * pszProjection );
874     virtual CPLErr _SetGCPs( int nGCPCount, const GDAL_GCP *pasGCPList,
875                     const char *pszGCPProjection );
876 //! @endcond
877 
878   private:
879     CPL_DISALLOW_COPY_ASSIGN(GDALDataset)
880 };
881 
882 //! @cond Doxygen_Suppress
883 struct CPL_DLL GDALDatasetUniquePtrDeleter
884 {
885     void operator()(GDALDataset* poDataset) const
886         { GDALClose(poDataset); }
887 };
888 //! @endcond
889 
890 /** Unique pointer type for GDALDataset.
891  * Appropriate for use on datasets open in non-shared mode and onto which
892  * reference counter has not been manually modified.
893  * @since GDAL 2.3
894  */
895 using GDALDatasetUniquePtr = std::unique_ptr<GDALDataset, GDALDatasetUniquePtrDeleter>;
896 
897 /* ******************************************************************** */
898 /*                           GDALRasterBlock                            */
899 /* ******************************************************************** */
900 
901 /** A single raster block in the block cache.
902  *
903  * And the global block manager that manages a least-recently-used list of
904  * blocks from various datasets/bands */
905 class CPL_DLL GDALRasterBlock
906 {
907     friend class GDALAbstractBandBlockCache;
908 
909     GDALDataType        eType;
910 
911     bool                bDirty;
912     volatile int        nLockCount;
913 
914     int                 nXOff;
915     int                 nYOff;
916 
917     int                 nXSize;
918     int                 nYSize;
919 
920     void                *pData;
921 
922     GDALRasterBand      *poBand;
923 
924     GDALRasterBlock     *poNext;
925     GDALRasterBlock     *poPrevious;
926 
927     bool                 bMustDetach;
928 
929     CPL_INTERNAL void        Detach_unlocked( void );
930     CPL_INTERNAL void        Touch_unlocked( void );
931 
932     CPL_INTERNAL void        RecycleFor( int nXOffIn, int nYOffIn );
933 
934   public:
935                 GDALRasterBlock( GDALRasterBand *, int, int );
936                 GDALRasterBlock( int nXOffIn, int nYOffIn ); /* only for lookup purpose */
937     virtual     ~GDALRasterBlock();
938 
939     CPLErr      Internalize( void );
940     void        Touch( void );
941     void        MarkDirty( void );
942     void        MarkClean( void );
943     /** Increment the lock count */
944     int         AddLock( void ) { return CPLAtomicInc(&nLockCount); }
945     /** Decrement the lock count */
946     int         DropLock( void ) { return CPLAtomicDec(&nLockCount); }
947     void        Detach();
948 
949     CPLErr      Write();
950 
951     /** Return the data type
952      * @return data type
953      */
954     GDALDataType GetDataType() const { return eType; }
955     /** Return the x offset of the top-left corner of the block
956      * @return x offset
957      */
958     int         GetXOff() const { return nXOff; }
959     /** Return the y offset of the top-left corner of the block
960      * @return y offset
961      */
962     int         GetYOff() const { return nYOff; }
963     /** Return the width of the block
964      * @return width
965      */
966     int         GetXSize() const { return nXSize; }
967     /** Return the height of the block
968      * @return height
969      */
970     int         GetYSize() const { return nYSize; }
971     /** Return the dirty flag
972      * @return dirty flag
973      */
974     int         GetDirty() const { return bDirty; }
975     /** Return the data buffer
976      * @return data buffer
977      */
978     void        *GetDataRef( void ) { return pData; }
979     /** Return the block size in bytes
980      * @return block size.
981      */
982     GPtrDiff_t   GetBlockSize() const {
983         return static_cast<GPtrDiff_t>(nXSize) * nYSize * GDALGetDataTypeSizeBytes(eType); }
984 
985     int          TakeLock();
986     int          DropLockForRemovalFromStorage();
987 
988     /// @brief Accessor to source GDALRasterBand object.
989     /// @return source raster band of the raster block.
990     GDALRasterBand *GetBand() { return poBand; }
991 
992     static void FlushDirtyBlocks();
993     static int  FlushCacheBlock(int bDirtyBlocksOnly = FALSE);
994     static void Verify();
995 
996     static void EnterDisableDirtyBlockFlush();
997     static void LeaveDisableDirtyBlockFlush();
998 
999 #ifdef notdef
1000     static void CheckNonOrphanedBlocks(GDALRasterBand* poBand);
1001     void        DumpBlock();
1002     static void DumpAll();
1003 #endif
1004 
1005     /* Should only be called by GDALDestroyDriverManager() */
1006 //! @cond Doxygen_Suppress
1007     CPL_INTERNAL static void DestroyRBMutex();
1008 //! @endcond
1009 
1010   private:
1011     CPL_DISALLOW_COPY_ASSIGN(GDALRasterBlock)
1012 };
1013 
1014 /* ******************************************************************** */
1015 /*                             GDALColorTable                           */
1016 /* ******************************************************************** */
1017 
1018 /** A color table / palette. */
1019 
1020 class CPL_DLL GDALColorTable
1021 {
1022     GDALPaletteInterp eInterp;
1023 
1024     std::vector<GDALColorEntry> aoEntries{};
1025 
1026 public:
1027     explicit     GDALColorTable( GDALPaletteInterp = GPI_RGB );
1028                 ~GDALColorTable();
1029 
1030     GDALColorTable *Clone() const;
1031     int             IsSame(const GDALColorTable* poOtherCT) const;
1032 
1033     GDALPaletteInterp GetPaletteInterpretation() const;
1034 
1035     int           GetColorEntryCount() const;
1036     const GDALColorEntry *GetColorEntry( int ) const;
1037     int           GetColorEntryAsRGB( int, GDALColorEntry * ) const;
1038     void          SetColorEntry( int, const GDALColorEntry * );
1039     int           CreateColorRamp( int, const GDALColorEntry * ,
1040                                    int, const GDALColorEntry * );
1041 
1042     /** Convert a GDALColorTable* to a GDALRasterBandH.
1043      * @since GDAL 2.3
1044      */
1045     static inline GDALColorTableH ToHandle(GDALColorTable* poCT)
1046         { return static_cast<GDALColorTableH>(poCT); }
1047 
1048     /** Convert a GDALColorTableH to a GDALColorTable*.
1049      * @since GDAL 2.3
1050      */
1051     static inline GDALColorTable* FromHandle(GDALColorTableH hCT)
1052         { return static_cast<GDALColorTable*>(hCT); }
1053 
1054 };
1055 
1056 /* ******************************************************************** */
1057 /*                       GDALAbstractBandBlockCache                     */
1058 /* ******************************************************************** */
1059 
1060  //! @cond Doxygen_Suppress
1061 
1062 //! This manages how a raster band store its cached block.
1063 // only used by GDALRasterBand implementation.
1064 
1065 class GDALAbstractBandBlockCache
1066 {
1067         // List of blocks that can be freed or recycled, and its lock
1068         CPLLock          *hSpinLock = nullptr;
1069         GDALRasterBlock  *psListBlocksToFree = nullptr;
1070 
1071         // Band keep alive counter, and its lock & condition
1072         CPLCond          *hCond = nullptr;
1073         CPLMutex         *hCondMutex = nullptr;
1074         volatile int      nKeepAliveCounter = 0;
1075 
1076         volatile int      m_nDirtyBlocks = 0;
1077 
1078         CPL_DISALLOW_COPY_ASSIGN(GDALAbstractBandBlockCache)
1079 
1080     protected:
1081         GDALRasterBand   *poBand;
1082 
1083         int               m_nInitialDirtyBlocksInFlushCache = 0;
1084         int               m_nLastTick = -1;
1085 
1086         void              FreeDanglingBlocks();
1087         void              UnreferenceBlockBase();
1088 
1089         void              StartDirtyBlockFlushingLog();
1090         void              UpdateDirtyBlockFlushingLog();
1091         void              EndDirtyBlockFlushingLog();
1092 
1093     public:
1094             explicit GDALAbstractBandBlockCache(GDALRasterBand* poBand);
1095             virtual ~GDALAbstractBandBlockCache();
1096 
1097             GDALRasterBlock* CreateBlock(int nXBlockOff, int nYBlockOff);
1098             void             AddBlockToFreeList( GDALRasterBlock * );
1099             void             IncDirtyBlocks(int nInc);
1100             void             WaitCompletionPendingTasks();
1101 
1102             virtual bool             Init() = 0;
1103             virtual bool             IsInitOK() = 0;
1104             virtual CPLErr           FlushCache() = 0;
1105             virtual CPLErr           AdoptBlock( GDALRasterBlock* poBlock ) = 0;
1106             virtual GDALRasterBlock *TryGetLockedBlockRef( int nXBlockOff,
1107                                                            int nYBlockYOff ) = 0;
1108             virtual CPLErr           UnreferenceBlock( GDALRasterBlock* poBlock ) = 0;
1109             virtual CPLErr           FlushBlock( int nXBlockOff, int nYBlockOff,
1110                                                  int bWriteDirtyBlock ) = 0;
1111 };
1112 
1113 GDALAbstractBandBlockCache* GDALArrayBandBlockCacheCreate(GDALRasterBand* poBand);
1114 GDALAbstractBandBlockCache* GDALHashSetBandBlockCacheCreate(GDALRasterBand* poBand);
1115 
1116 //! @endcond
1117 
1118 /* ******************************************************************** */
1119 /*                            GDALRasterBand                            */
1120 /* ******************************************************************** */
1121 
1122 class GDALMDArray;
1123 
1124 /** A single raster band (or channel). */
1125 
1126 class CPL_DLL GDALRasterBand : public GDALMajorObject
1127 {
1128   private:
1129     friend class GDALArrayBandBlockCache;
1130     friend class GDALHashSetBandBlockCache;
1131     friend class GDALRasterBlock;
1132     friend class GDALDataset;
1133 
1134     CPLErr eFlushBlockErr = CE_None;
1135     GDALAbstractBandBlockCache* poBandBlockCache = nullptr;
1136 
1137     CPL_INTERNAL void           SetFlushBlockErr( CPLErr eErr );
1138     CPL_INTERNAL CPLErr         UnreferenceBlock( GDALRasterBlock* poBlock );
1139     CPL_INTERNAL void           SetValidPercent( GUIntBig nSampleCount, GUIntBig nValidCount );
1140     CPL_INTERNAL void           IncDirtyBlocks(int nInc);
1141 
1142   protected:
1143 //! @cond Doxygen_Suppress
1144     GDALDataset *poDS = nullptr;
1145     int         nBand = 0; /* 1 based */
1146 
1147     int         nRasterXSize = 0;
1148     int         nRasterYSize = 0;
1149 
1150     GDALDataType eDataType = GDT_Byte;
1151     GDALAccess  eAccess = GA_ReadOnly;
1152 
1153     /* stuff related to blocking, and raster cache */
1154     int         nBlockXSize = -1;
1155     int         nBlockYSize = -1;
1156     int         nBlocksPerRow = 0;
1157     int         nBlocksPerColumn = 0;
1158 
1159     int         nBlockReads = 0;
1160     int         bForceCachedIO = 0;
1161 
1162     GDALRasterBand *poMask = nullptr;
1163     bool        bOwnMask = false;
1164     int         nMaskFlags = 0;
1165 
1166     void        InvalidateMaskBand();
1167 
1168     friend class GDALProxyRasterBand;
1169     friend class GDALDefaultOverviews;
1170 
1171     CPLErr RasterIOResampled( GDALRWFlag, int, int, int, int,
1172                               void *, int, int, GDALDataType,
1173                               GSpacing, GSpacing, GDALRasterIOExtraArg* psExtraArg ) CPL_WARN_UNUSED_RESULT;
1174 
1175     int          EnterReadWrite(GDALRWFlag eRWFlag);
1176     void         LeaveReadWrite();
1177     void         InitRWLock();
1178 //! @endcond
1179 
1180   protected:
1181     virtual CPLErr IReadBlock( int nBlockXOff, int nBlockYOff, void * pData ) = 0;
1182     virtual CPLErr IWriteBlock( int nBlockXOff, int nBlockYOff, void * pData );
1183 
1184     virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
1185                               void *, int, int, GDALDataType,
1186                               GSpacing, GSpacing, GDALRasterIOExtraArg* psExtraArg ) CPL_WARN_UNUSED_RESULT;
1187 
1188     virtual int IGetDataCoverageStatus( int nXOff, int nYOff,
1189                                         int nXSize, int nYSize,
1190                                         int nMaskFlagStop,
1191                                         double* pdfDataPct);
1192 //! @cond Doxygen_Suppress
1193     CPLErr         OverviewRasterIO( GDALRWFlag, int, int, int, int,
1194                                      void *, int, int, GDALDataType,
1195                                      GSpacing, GSpacing, GDALRasterIOExtraArg* psExtraArg ) CPL_WARN_UNUSED_RESULT;
1196 
1197     CPLErr TryOverviewRasterIO( GDALRWFlag eRWFlag,
1198                                 int nXOff, int nYOff, int nXSize, int nYSize,
1199                                 void * pData, int nBufXSize, int nBufYSize,
1200                                 GDALDataType eBufType,
1201                                 GSpacing nPixelSpace, GSpacing nLineSpace,
1202                                 GDALRasterIOExtraArg* psExtraArg,
1203                                 int* pbTried );
1204 
1205     int            InitBlockInfo();
1206 
1207     void           AddBlockToFreeList( GDALRasterBlock * );
1208 //! @endcond
1209 
1210     GDALRasterBlock *TryGetLockedBlockRef( int nXBlockOff, int nYBlockYOff );
1211 
1212   public:
1213                 GDALRasterBand();
1214     explicit    GDALRasterBand(int bForceCachedIO);
1215 
1216     ~GDALRasterBand() override;
1217 
1218     int         GetXSize();
1219     int         GetYSize();
1220     int         GetBand();
1221     GDALDataset*GetDataset();
1222 
1223     GDALDataType GetRasterDataType( void );
1224     void        GetBlockSize( int *, int * );
1225     CPLErr      GetActualBlockSize ( int, int, int *, int * );
1226     GDALAccess  GetAccess();
1227 
1228     CPLErr      RasterIO( GDALRWFlag, int, int, int, int,
1229                           void *, int, int, GDALDataType,
1230                           GSpacing, GSpacing, GDALRasterIOExtraArg* psExtraArg
1231 #ifndef DOXYGEN_SKIP
1232                           OPTIONAL_OUTSIDE_GDAL(nullptr)
1233 #endif
1234                           ) CPL_WARN_UNUSED_RESULT;
1235     CPLErr      ReadBlock( int, int, void * ) CPL_WARN_UNUSED_RESULT;
1236 
1237     CPLErr      WriteBlock( int, int, void * ) CPL_WARN_UNUSED_RESULT;
1238 
1239     GDALRasterBlock *GetLockedBlockRef( int nXBlockOff, int nYBlockOff,
1240                                         int bJustInitialize = FALSE ) CPL_WARN_UNUSED_RESULT;
1241     CPLErr      FlushBlock( int, int, int bWriteDirtyBlock = TRUE );
1242 
1243     unsigned char*  GetIndexColorTranslationTo(/* const */ GDALRasterBand* poReferenceBand,
1244                                                unsigned char* pTranslationTable = nullptr,
1245                                                int* pApproximateMatching = nullptr);
1246 
1247     // New OpengIS CV_SampleDimension stuff.
1248 
1249     virtual CPLErr FlushCache();
1250     virtual char **GetCategoryNames();
1251     virtual double GetNoDataValue( int *pbSuccess = nullptr );
1252     virtual double GetMinimum( int *pbSuccess = nullptr );
1253     virtual double GetMaximum(int *pbSuccess = nullptr );
1254     virtual double GetOffset( int *pbSuccess = nullptr );
1255     virtual double GetScale( int *pbSuccess = nullptr );
1256     virtual const char *GetUnitType();
1257     virtual GDALColorInterp GetColorInterpretation();
1258     virtual GDALColorTable *GetColorTable();
1259     virtual CPLErr Fill(double dfRealValue, double dfImaginaryValue = 0);
1260 
1261     virtual CPLErr SetCategoryNames( char ** papszNames );
1262     virtual CPLErr SetNoDataValue( double dfNoData );
1263     virtual CPLErr DeleteNoDataValue();
1264     virtual CPLErr SetColorTable( GDALColorTable * poCT );
1265     virtual CPLErr SetColorInterpretation( GDALColorInterp eColorInterp );
1266     virtual CPLErr SetOffset( double dfNewOffset );
1267     virtual CPLErr SetScale( double dfNewScale );
1268     virtual CPLErr SetUnitType( const char * pszNewValue );
1269 
1270     virtual CPLErr GetStatistics( int bApproxOK, int bForce,
1271                                   double *pdfMin, double *pdfMax,
1272                                   double *pdfMean, double *padfStdDev );
1273     virtual CPLErr ComputeStatistics( int bApproxOK,
1274                                       double *pdfMin, double *pdfMax,
1275                                       double *pdfMean, double *pdfStdDev,
1276                                       GDALProgressFunc, void *pProgressData );
1277     virtual CPLErr SetStatistics( double dfMin, double dfMax,
1278                                   double dfMean, double dfStdDev );
1279     virtual CPLErr ComputeRasterMinMax( int, double* );
1280 
1281 // Only defined when Doxygen enabled
1282 #ifdef DOXYGEN_SKIP
1283     CPLErr      SetMetadata( char ** papszMetadata,
1284                              const char * pszDomain ) override;
1285     CPLErr      SetMetadataItem( const char * pszName,
1286                                  const char * pszValue,
1287                                  const char * pszDomain ) override;
1288 #endif
1289 
1290     virtual int HasArbitraryOverviews();
1291     virtual int GetOverviewCount();
1292     virtual GDALRasterBand *GetOverview(int);
1293     virtual GDALRasterBand *GetRasterSampleOverview( GUIntBig );
1294     virtual CPLErr BuildOverviews( const char * pszResampling,
1295                                    int nOverviews,
1296                                    int * panOverviewList,
1297                                    GDALProgressFunc pfnProgress,
1298                                    void * pProgressData );
1299 
1300     virtual CPLErr AdviseRead( int nXOff, int nYOff, int nXSize, int nYSize,
1301                                int nBufXSize, int nBufYSize,
1302                                GDALDataType eBufType, char **papszOptions );
1303 
1304     virtual CPLErr  GetHistogram( double dfMin, double dfMax,
1305                           int nBuckets, GUIntBig * panHistogram,
1306                           int bIncludeOutOfRange, int bApproxOK,
1307                           GDALProgressFunc, void *pProgressData );
1308 
1309     virtual CPLErr GetDefaultHistogram( double *pdfMin, double *pdfMax,
1310                                         int *pnBuckets, GUIntBig ** ppanHistogram,
1311                                         int bForce,
1312                                         GDALProgressFunc, void *pProgressData);
1313     virtual CPLErr SetDefaultHistogram( double dfMin, double dfMax,
1314                                         int nBuckets, GUIntBig *panHistogram );
1315 
1316     virtual GDALRasterAttributeTable *GetDefaultRAT();
1317     virtual CPLErr SetDefaultRAT( const GDALRasterAttributeTable * poRAT );
1318 
1319     virtual GDALRasterBand *GetMaskBand();
1320     virtual int             GetMaskFlags();
1321     virtual CPLErr          CreateMaskBand( int nFlagsIn );
1322 
1323     virtual CPLVirtualMem  *GetVirtualMemAuto( GDALRWFlag eRWFlag,
1324                                                int *pnPixelSpace,
1325                                                GIntBig *pnLineSpace,
1326                                                char **papszOptions ) CPL_WARN_UNUSED_RESULT;
1327 
1328     int GetDataCoverageStatus( int nXOff, int nYOff,
1329                                int nXSize, int nYSize,
1330                                int nMaskFlagStop = 0,
1331                                double* pdfDataPct = nullptr );
1332 
1333     std::shared_ptr<GDALMDArray> AsMDArray() const;
1334 
1335 #ifndef DOXYGEN_XML
1336     void ReportError(CPLErr eErrClass, CPLErrorNum err_no, const char *fmt, ...)  CPL_PRINT_FUNC_FORMAT (4, 5);
1337 #endif
1338 
1339     /** Convert a GDALRasterBand* to a GDALRasterBandH.
1340      * @since GDAL 2.3
1341      */
1342     static inline GDALRasterBandH ToHandle(GDALRasterBand* poBand)
1343         { return static_cast<GDALRasterBandH>(poBand); }
1344 
1345     /** Convert a GDALRasterBandH to a GDALRasterBand*.
1346      * @since GDAL 2.3
1347      */
1348     static inline GDALRasterBand* FromHandle(GDALRasterBandH hBand)
1349         { return static_cast<GDALRasterBand*>(hBand); }
1350 
1351 private:
1352     CPL_DISALLOW_COPY_ASSIGN(GDALRasterBand)
1353 };
1354 
1355 //! @cond Doxygen_Suppress
1356 /* ******************************************************************** */
1357 /*                         GDALAllValidMaskBand                         */
1358 /* ******************************************************************** */
1359 
1360 class CPL_DLL GDALAllValidMaskBand : public GDALRasterBand
1361 {
1362   protected:
1363     CPLErr IReadBlock( int, int, void * ) override;
1364 
1365     CPL_DISALLOW_COPY_ASSIGN(GDALAllValidMaskBand)
1366 
1367   public:
1368     explicit     GDALAllValidMaskBand( GDALRasterBand * );
1369     ~GDALAllValidMaskBand() override;
1370 
1371     GDALRasterBand *GetMaskBand() override;
1372     int             GetMaskFlags() override;
1373 
1374     CPLErr ComputeStatistics( int bApproxOK,
1375                             double *pdfMin, double *pdfMax,
1376                             double *pdfMean, double *pdfStdDev,
1377                             GDALProgressFunc, void *pProgressData ) override;
1378 
1379 };
1380 
1381 /* ******************************************************************** */
1382 /*                         GDALNoDataMaskBand                           */
1383 /* ******************************************************************** */
1384 
1385 class CPL_DLL GDALNoDataMaskBand : public GDALRasterBand
1386 {
1387     double          dfNoDataValue;
1388     GDALRasterBand *poParent;
1389 
1390     CPL_DISALLOW_COPY_ASSIGN(GDALNoDataMaskBand)
1391 
1392   protected:
1393     CPLErr IReadBlock( int, int, void * ) override;
1394     CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
1395                       void *, int, int, GDALDataType,
1396                       GSpacing, GSpacing, GDALRasterIOExtraArg* psExtraArg ) override;
1397 
1398   public:
1399     explicit GDALNoDataMaskBand( GDALRasterBand * );
1400     ~GDALNoDataMaskBand() override;
1401 
1402     static bool IsNoDataInRange(double dfNoDataValue,
1403                                 GDALDataType eDataType);
1404 };
1405 
1406 /* ******************************************************************** */
1407 /*                  GDALNoDataValuesMaskBand                            */
1408 /* ******************************************************************** */
1409 
1410 class CPL_DLL GDALNoDataValuesMaskBand : public GDALRasterBand
1411 {
1412     double      *padfNodataValues;
1413 
1414     CPL_DISALLOW_COPY_ASSIGN(GDALNoDataValuesMaskBand)
1415 
1416   protected:
1417     CPLErr IReadBlock( int, int, void * ) override;
1418 
1419   public:
1420     explicit     GDALNoDataValuesMaskBand( GDALDataset * );
1421     ~GDALNoDataValuesMaskBand() override;
1422 };
1423 
1424 /* ******************************************************************** */
1425 /*                         GDALRescaledAlphaBand                        */
1426 /* ******************************************************************** */
1427 
1428 class GDALRescaledAlphaBand : public GDALRasterBand
1429 {
1430     GDALRasterBand *poParent;
1431     void           *pTemp;
1432 
1433     CPL_DISALLOW_COPY_ASSIGN(GDALRescaledAlphaBand)
1434 
1435   protected:
1436     CPLErr IReadBlock( int, int, void * ) override;
1437     CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
1438                       void *, int, int, GDALDataType,
1439                       GSpacing, GSpacing,
1440                       GDALRasterIOExtraArg* psExtraArg ) override;
1441 
1442   public:
1443     explicit GDALRescaledAlphaBand( GDALRasterBand * );
1444     ~GDALRescaledAlphaBand() override;
1445 };
1446 //! @endcond
1447 
1448 /* ******************************************************************** */
1449 /*                          GDALIdentifyEnum                            */
1450 /* ******************************************************************** */
1451 
1452 /**
1453  * Enumeration used by GDALDriver::pfnIdentify().
1454  *
1455  * @since GDAL 2.1
1456  */
1457 typedef enum
1458 {
1459     /** Identify could not determine if the file is recognized or not by the probed driver. */
1460     GDAL_IDENTIFY_UNKNOWN = -1,
1461     /** Identify determined the file is not recognized by the probed driver. */
1462     GDAL_IDENTIFY_FALSE = 0,
1463     /** Identify determined the file is recognized by the probed driver. */
1464     GDAL_IDENTIFY_TRUE = 1
1465 } GDALIdentifyEnum;
1466 
1467 /* ******************************************************************** */
1468 /*                              GDALDriver                              */
1469 /* ******************************************************************** */
1470 
1471 /**
1472  * \brief Format specific driver.
1473  *
1474  * An instance of this class is created for each supported format, and
1475  * manages information about the format.
1476  *
1477  * This roughly corresponds to a file format, though some
1478  * drivers may be gateways to many formats through a secondary
1479  * multi-library.
1480  */
1481 
1482 class CPL_DLL GDALDriver : public GDALMajorObject
1483 {
1484   public:
1485     GDALDriver();
1486     ~GDALDriver() override;
1487 
1488     CPLErr      SetMetadataItem( const char * pszName,
1489                                  const char * pszValue,
1490                                  const char * pszDomain = "" ) override;
1491 
1492 /* -------------------------------------------------------------------- */
1493 /*      Public C++ methods.                                             */
1494 /* -------------------------------------------------------------------- */
1495     GDALDataset         *Create( const char * pszName,
1496                                  int nXSize, int nYSize, int nBands,
1497                                  GDALDataType eType, char ** papszOptions ) CPL_WARN_UNUSED_RESULT;
1498 
1499     GDALDataset         *CreateMultiDimensional( const char * pszName,
1500                                                  CSLConstList papszRootGroupOptions,
1501                                                  CSLConstList papszOptions ) CPL_WARN_UNUSED_RESULT;
1502 
1503     CPLErr              Delete( const char * pszName );
1504     CPLErr              Rename( const char * pszNewName,
1505                                 const char * pszOldName );
1506     CPLErr              CopyFiles( const char * pszNewName,
1507                                    const char * pszOldName );
1508 
1509     GDALDataset         *CreateCopy( const char *, GDALDataset *,
1510                                      int, char **,
1511                                      GDALProgressFunc pfnProgress,
1512                                      void * pProgressData ) CPL_WARN_UNUSED_RESULT;
1513 
1514 /* -------------------------------------------------------------------- */
1515 /*      The following are semiprivate, not intended to be accessed      */
1516 /*      by anyone but the formats instantiating and populating the      */
1517 /*      drivers.                                                        */
1518 /* -------------------------------------------------------------------- */
1519 //! @cond Doxygen_Suppress
1520     GDALDataset         *(*pfnOpen)( GDALOpenInfo * );
1521 
1522     GDALDataset         *(*pfnCreate)( const char * pszName,
1523                                        int nXSize, int nYSize, int nBands,
1524                                        GDALDataType eType,
1525                                        char ** papszOptions );
1526 
1527     GDALDataset         *(*pfnCreateEx)( GDALDriver*, const char * pszName,
1528                                        int nXSize, int nYSize, int nBands,
1529                                        GDALDataType eType,
1530                                        char ** papszOptions );
1531 
1532     GDALDataset         *(*pfnCreateMultiDimensional)( const char * pszName,
1533                                                        CSLConstList papszRootGroupOptions,
1534                                                        CSLConstList papszOptions );
1535 
1536     CPLErr              (*pfnDelete)( const char * pszName );
1537 
1538     GDALDataset         *(*pfnCreateCopy)( const char *, GDALDataset *,
1539                                            int, char **,
1540                                            GDALProgressFunc pfnProgress,
1541                                            void * pProgressData );
1542 
1543     void                *pDriverData;
1544 
1545     void                (*pfnUnloadDriver)(GDALDriver *);
1546 
1547     /** Identify() if the file is recognized or not by the driver.
1548 
1549        Return GDAL_IDENTIFY_TRUE (1) if the passed file is certainly recognized by the driver.
1550        Return GDAL_IDENTIFY_FALSE (0) if the passed file is certainly NOT recognized by the driver.
1551        Return GDAL_IDENTIFY_UNKNOWN (-1) if the passed file may be or may not be recognized by the driver,
1552        and that a potentially costly test must be done with pfnOpen.
1553     */
1554     int                 (*pfnIdentify)( GDALOpenInfo * );
1555     int                 (*pfnIdentifyEx)( GDALDriver*, GDALOpenInfo * );
1556 
1557     CPLErr              (*pfnRename)( const char * pszNewName,
1558                                       const char * pszOldName );
1559     CPLErr              (*pfnCopyFiles)( const char * pszNewName,
1560                                          const char * pszOldName );
1561 
1562     // Used for legacy OGR drivers, and Python drivers
1563     GDALDataset         *(*pfnOpenWithDriverArg)( GDALDriver*, GDALOpenInfo * );
1564 
1565     /* For legacy OGR drivers */
1566     GDALDataset         *(*pfnCreateVectorOnly)( GDALDriver*,
1567                                                  const char * pszName,
1568                                                  char ** papszOptions );
1569     CPLErr              (*pfnDeleteDataSource)( GDALDriver*,
1570                                                  const char * pszName );
1571 //! @endcond
1572 
1573 /* -------------------------------------------------------------------- */
1574 /*      Helper methods.                                                 */
1575 /* -------------------------------------------------------------------- */
1576 //! @cond Doxygen_Suppress
1577     GDALDataset         *DefaultCreateCopy( const char *, GDALDataset *,
1578                                             int, char **,
1579                                             GDALProgressFunc pfnProgress,
1580                                             void * pProgressData ) CPL_WARN_UNUSED_RESULT;
1581 
1582     static CPLErr        DefaultCreateCopyMultiDimensional(
1583                                      GDALDataset *poSrcDS,
1584                                      GDALDataset *poDstDS,
1585                                      bool bStrict,
1586                                      CSLConstList /*papszOptions*/,
1587                                      GDALProgressFunc pfnProgress,
1588                                      void * pProgressData );
1589 
1590     static CPLErr        DefaultCopyMasks( GDALDataset *poSrcDS,
1591                                            GDALDataset *poDstDS,
1592                                            int bStrict );
1593     static CPLErr        DefaultCopyMasks( GDALDataset *poSrcDS,
1594                                            GDALDataset *poDstDS,
1595                                            int bStrict,
1596                                            CSLConstList papszOptions,
1597                                            GDALProgressFunc pfnProgress,
1598                                            void * pProgressData );
1599 //! @endcond
1600     static CPLErr       QuietDelete( const char * pszName,
1601                                      const char *const *papszAllowedDrivers = nullptr);
1602 
1603 //! @cond Doxygen_Suppress
1604     static CPLErr       DefaultRename( const char * pszNewName,
1605                                        const char * pszOldName );
1606     static CPLErr       DefaultCopyFiles( const char * pszNewName,
1607                                           const char * pszOldName );
1608 //! @endcond
1609 
1610     /** Convert a GDALDriver* to a GDALDriverH.
1611      * @since GDAL 2.3
1612      */
1613     static inline GDALDriverH ToHandle(GDALDriver* poDriver)
1614         { return static_cast<GDALDriverH>(poDriver); }
1615 
1616     /** Convert a GDALDriverH to a GDALDriver*.
1617      * @since GDAL 2.3
1618      */
1619     static inline GDALDriver* FromHandle(GDALDriverH hDriver)
1620         { return static_cast<GDALDriver*>(hDriver); }
1621 
1622 private:
1623     CPL_DISALLOW_COPY_ASSIGN(GDALDriver)
1624 };
1625 
1626 /* ******************************************************************** */
1627 /*                          GDALDriverManager                           */
1628 /* ******************************************************************** */
1629 
1630 /**
1631  * Class for managing the registration of file format drivers.
1632  *
1633  * Use GetGDALDriverManager() to fetch the global singleton instance of
1634  * this class.
1635  */
1636 
1637 class CPL_DLL GDALDriverManager : public GDALMajorObject
1638 {
1639     int         nDrivers = 0;
1640     GDALDriver  **papoDrivers = nullptr;
1641     std::map<CPLString, GDALDriver*> oMapNameToDrivers{};
1642 
1643     GDALDriver  *GetDriver_unlocked( int iDriver )
1644             { return (iDriver >= 0 && iDriver < nDrivers) ?
1645                   papoDrivers[iDriver] : nullptr; }
1646 
1647     GDALDriver  *GetDriverByName_unlocked( const char * pszName )
1648             { return oMapNameToDrivers[CPLString(pszName).toupper()]; }
1649 
1650     static char** GetSearchPaths(const char* pszGDAL_DRIVER_PATH);
1651 
1652     static void   CleanupPythonDrivers();
1653 
1654     CPL_DISALLOW_COPY_ASSIGN(GDALDriverManager)
1655 
1656  public:
1657                 GDALDriverManager();
1658                 ~GDALDriverManager();
1659 
1660     int         GetDriverCount( void ) const;
1661     GDALDriver  *GetDriver( int );
1662     GDALDriver  *GetDriverByName( const char * );
1663 
1664     int         RegisterDriver( GDALDriver * );
1665     void        DeregisterDriver( GDALDriver * );
1666 
1667     // AutoLoadDrivers is a no-op if compiled with GDAL_NO_AUTOLOAD defined.
1668     static void        AutoLoadDrivers();
1669     void        AutoSkipDrivers();
1670 
1671     static void        AutoLoadPythonDrivers();
1672 };
1673 
1674 CPL_C_START
1675 GDALDriverManager CPL_DLL * GetGDALDriverManager( void );
1676 CPL_C_END
1677 
1678 /* ******************************************************************** */
1679 /*                          GDALAsyncReader                             */
1680 /* ******************************************************************** */
1681 
1682 /**
1683  * Class used as a session object for asynchronous requests.  They are
1684  * created with GDALDataset::BeginAsyncReader(), and destroyed with
1685  * GDALDataset::EndAsyncReader().
1686  */
1687 class CPL_DLL GDALAsyncReader
1688 {
1689 
1690     CPL_DISALLOW_COPY_ASSIGN(GDALAsyncReader)
1691 
1692   protected:
1693 //! @cond Doxygen_Suppress
1694     GDALDataset* poDS;
1695     int          nXOff;
1696     int          nYOff;
1697     int          nXSize;
1698     int          nYSize;
1699     void *       pBuf;
1700     int          nBufXSize;
1701     int          nBufYSize;
1702     GDALDataType eBufType;
1703     int          nBandCount;
1704     int*         panBandMap;
1705     int          nPixelSpace;
1706     int          nLineSpace;
1707     int          nBandSpace;
1708 //! @endcond
1709 
1710   public:
1711     GDALAsyncReader();
1712     virtual ~GDALAsyncReader();
1713 
1714     /** Return dataset.
1715      * @return dataset
1716      */
1717     GDALDataset* GetGDALDataset() {return poDS;}
1718     /** Return x offset.
1719      * @return x offset.
1720      */
1721     int GetXOffset() const { return nXOff; }
1722     /** Return y offset.
1723      * @return y offset.
1724      */
1725     int GetYOffset() const { return nYOff; }
1726     /** Return width.
1727      * @return width
1728      */
1729     int GetXSize() const { return nXSize; }
1730     /** Return height.
1731      * @return height
1732      */
1733     int GetYSize() const { return nYSize; }
1734     /** Return buffer.
1735      * @return buffer
1736      */
1737     void * GetBuffer() {return pBuf;}
1738     /** Return buffer width.
1739      * @return buffer width.
1740      */
1741     int GetBufferXSize() const { return nBufXSize; }
1742     /** Return buffer height.
1743      * @return buffer height.
1744      */
1745     int GetBufferYSize() const { return nBufYSize; }
1746     /** Return buffer data type.
1747      * @return buffer data type.
1748      */
1749     GDALDataType GetBufferType() const { return eBufType; }
1750     /** Return band count.
1751      * @return band count
1752      */
1753     int GetBandCount() const { return nBandCount; }
1754     /** Return band map.
1755      * @return band map.
1756      */
1757     int* GetBandMap() { return panBandMap; }
1758     /** Return pixel spacing.
1759      * @return pixel spacing.
1760      */
1761     int GetPixelSpace() const { return nPixelSpace; }
1762     /** Return line spacing.
1763      * @return line spacing.
1764      */
1765     int GetLineSpace() const { return nLineSpace; }
1766     /** Return band spacing.
1767      * @return band spacing.
1768      */
1769     int GetBandSpace() const { return nBandSpace; }
1770 
1771     virtual GDALAsyncStatusType
1772         GetNextUpdatedRegion(double dfTimeout,
1773                              int* pnBufXOff, int* pnBufYOff,
1774                              int* pnBufXSize, int* pnBufYSize) = 0;
1775     virtual int LockBuffer( double dfTimeout = -1.0 );
1776     virtual void UnlockBuffer();
1777 };
1778 
1779 /* ******************************************************************** */
1780 /*                       Multidimensional array API                     */
1781 /* ******************************************************************** */
1782 
1783 class GDALMDArray;
1784 class GDALAttribute;
1785 class GDALDimension;
1786 class GDALEDTComponent;
1787 
1788 /* ******************************************************************** */
1789 /*                         GDALExtendedDataType                         */
1790 /* ******************************************************************** */
1791 
1792 /**
1793  * Class used to represent potentially complex data types.
1794  * Several classes of data types are supported: numeric (based on GDALDataType),
1795  * compound or string.
1796  *
1797  * @since GDAL 3.1
1798  */
1799 class CPL_DLL GDALExtendedDataType
1800 {
1801 public:
1802     ~GDALExtendedDataType();
1803 
1804     GDALExtendedDataType(const GDALExtendedDataType&);
1805 
1806     GDALExtendedDataType& operator= (GDALExtendedDataType&&);
1807 
1808     static GDALExtendedDataType Create(GDALDataType eType);
1809     static GDALExtendedDataType Create(const std::string& osName,
1810                                        size_t nTotalSize,
1811                                        std::vector<std::unique_ptr<GDALEDTComponent>>&& components);
1812     static GDALExtendedDataType CreateString(size_t nMaxStringLength = 0);
1813 
1814     bool operator== (const GDALExtendedDataType& ) const;
1815     /** Non-equality operator */
1816     bool operator!= (const GDALExtendedDataType& other) const { return !(operator==(other)); }
1817 
1818     /** Return type name.
1819      *
1820      * This is the same as the C function GDALExtendedDataTypeGetName()
1821      */
1822     const std::string&        GetName() const { return m_osName; }
1823 
1824     /** Return type class.
1825      *
1826      * This is the same as the C function GDALExtendedDataTypeGetClass()
1827      */
1828     GDALExtendedDataTypeClass GetClass() const { return m_eClass; }
1829 
1830     /** Return numeric data type (only valid when GetClass() == GEDTC_NUMERIC)
1831      *
1832      * This is the same as the C function GDALExtendedDataTypeGetNumericDataType()
1833      */
1834     GDALDataType              GetNumericDataType() const { return m_eNumericDT;  }
1835 
1836     /** Return the components of the data type (only valid when GetClass() == GEDTC_COMPOUND)
1837      *
1838      * This is the same as the C function GDALExtendedDataTypeGetComponents()
1839      */
1840     const std::vector<std::unique_ptr<GDALEDTComponent>>& GetComponents() const { return m_aoComponents; }
1841 
1842     /** Return data type size in bytes.
1843      *
1844      * For a string, this will be size of a char* pointer.
1845      *
1846      * This is the same as the C function GDALExtendedDataTypeGetSize()
1847      */
1848     size_t                    GetSize() const { return m_nSize; }
1849 
1850     /** Return the maximum length of a string in bytes.
1851      *
1852      * 0 indicates unknown/unlimited string.
1853      */
1854     size_t                    GetMaxStringLength() const { return m_nMaxStringLength; }
1855 
1856     bool CanConvertTo(const GDALExtendedDataType& other) const;
1857 
1858     bool NeedsFreeDynamicMemory() const;
1859 
1860     void FreeDynamicMemory(void* pBuffer) const;
1861 
1862     static
1863     bool CopyValue(const void* pSrc, const GDALExtendedDataType& srcType,
1864                      void* pDst, const GDALExtendedDataType& dstType);
1865 
1866 private:
1867     explicit GDALExtendedDataType(size_t nMaxStringLength = 0);
1868     explicit  GDALExtendedDataType(GDALDataType eType);
1869     GDALExtendedDataType(const std::string& osName,
1870                          size_t nTotalSize,
1871                          std::vector<std::unique_ptr<GDALEDTComponent>>&& components);
1872 
1873     std::string m_osName{};
1874     GDALExtendedDataTypeClass m_eClass = GEDTC_NUMERIC;
1875     GDALDataType m_eNumericDT = GDT_Unknown;
1876     std::vector<std::unique_ptr<GDALEDTComponent>> m_aoComponents{};
1877     size_t m_nSize = 0;
1878     size_t m_nMaxStringLength = 0;
1879 };
1880 
1881 /* ******************************************************************** */
1882 /*                            GDALEDTComponent                          */
1883 /* ******************************************************************** */
1884 
1885 /**
1886  * Class for a component of a compound extended data type.
1887  *
1888  * @since GDAL 3.1
1889  */
1890 class CPL_DLL GDALEDTComponent
1891 {
1892 public:
1893     ~GDALEDTComponent();
1894     GDALEDTComponent(const std::string& name, size_t offset, const GDALExtendedDataType& type);
1895     GDALEDTComponent(const GDALEDTComponent&);
1896 
1897     bool operator== (const GDALEDTComponent& ) const;
1898 
1899     /** Return the name.
1900      *
1901      * This is the same as the C function GDALEDTComponentGetName().
1902      */
1903     const std::string&   GetName() const { return m_osName; }
1904 
1905     /** Return the offset (in bytes) of the component in the compound data type.
1906      *
1907      * This is the same as the C function GDALEDTComponentGetOffset().
1908      */
1909     size_t               GetOffset() const { return m_nOffset; }
1910 
1911     /** Return the data type of the component.
1912      *
1913      * This is the same as the C function GDALEDTComponentGetType().
1914      */
1915     const GDALExtendedDataType& GetType() const { return m_oType; }
1916 
1917 private:
1918     std::string          m_osName;
1919     size_t               m_nOffset;
1920     GDALExtendedDataType m_oType;
1921 };
1922 
1923 /* ******************************************************************** */
1924 /*                            GDALIHasAttribute                         */
1925 /* ******************************************************************** */
1926 
1927 /**
1928  * Interface used to get a single GDALAttribute or a set of GDALAttribute
1929  *
1930  * @since GDAL 3.1
1931  */
1932 class CPL_DLL GDALIHasAttribute
1933 {
1934 protected:
1935     std::shared_ptr<GDALAttribute> GetAttributeFromAttributes(const std::string& osName) const;
1936 
1937 public:
1938     virtual ~GDALIHasAttribute();
1939 
1940     virtual std::shared_ptr<GDALAttribute> GetAttribute(const std::string& osName) const;
1941 
1942     virtual std::vector<std::shared_ptr<GDALAttribute>> GetAttributes(CSLConstList papszOptions = nullptr) const;
1943 
1944     virtual std::shared_ptr<GDALAttribute> CreateAttribute(
1945         const std::string& osName,
1946         const std::vector<GUInt64>& anDimensions,
1947         const GDALExtendedDataType& oDataType,
1948         CSLConstList papszOptions = nullptr);
1949 };
1950 
1951 /* ******************************************************************** */
1952 /*                               GDALGroup                              */
1953 /* ******************************************************************** */
1954 
1955 /**
1956  * Class modeling a named container of GDALAttribute, GDALMDArray or other
1957  * GDALGroup. Hence GDALGroup can describe a hierarchy of objects.
1958  *
1959  * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_group">HDF5 group concept</a>
1960  *
1961  * @since GDAL 3.1
1962  */
1963 class CPL_DLL GDALGroup: public GDALIHasAttribute
1964 {
1965 protected:
1966 //! @cond Doxygen_Suppress
1967     std::string m_osName{};
1968     std::string m_osFullName{};
1969 
1970     GDALGroup(const std::string& osParentName, const std::string& osName);
1971 
1972     const GDALGroup* GetInnerMostGroup(const std::string& osPathOrArrayOrDim,
1973                                        std::shared_ptr<GDALGroup>& curGroupHolder,
1974                                        std::string& osLastPart) const;
1975 //! @endcond
1976 
1977 public:
1978     virtual ~GDALGroup();
1979 
1980     /** Return the name of the group.
1981      *
1982      * This is the same as the C function GDALGroupGetName().
1983      */
1984     const std::string& GetName() const { return m_osName; }
1985 
1986     /** Return the full name of the group.
1987      *
1988      * This is the same as the C function GDALGroupGetFullName().
1989      */
1990     const std::string& GetFullName() const { return m_osFullName; }
1991 
1992     virtual std::vector<std::string> GetMDArrayNames(CSLConstList papszOptions = nullptr) const;
1993     virtual std::shared_ptr<GDALMDArray> OpenMDArray(const std::string& osName,
1994                                                      CSLConstList papszOptions = nullptr) const;
1995 
1996     virtual std::vector<std::string> GetGroupNames(CSLConstList papszOptions = nullptr) const;
1997     virtual std::shared_ptr<GDALGroup> OpenGroup(const std::string& osName,
1998                                                  CSLConstList papszOptions = nullptr) const;
1999 
2000     virtual std::vector<std::shared_ptr<GDALDimension>> GetDimensions(CSLConstList papszOptions = nullptr) const;
2001 
2002     virtual std::shared_ptr<GDALGroup> CreateGroup(const std::string& osName,
2003                                                    CSLConstList papszOptions = nullptr);
2004 
2005     virtual std::shared_ptr<GDALDimension> CreateDimension(const std::string& osName,
2006                                                            const std::string& osType,
2007                                                            const std::string& osDirection,
2008                                                            GUInt64 nSize,
2009                                                            CSLConstList papszOptions = nullptr);
2010 
2011     virtual std::shared_ptr<GDALMDArray> CreateMDArray(const std::string& osName,
2012                                                        const std::vector<std::shared_ptr<GDALDimension>>& aoDimensions,
2013                                                        const GDALExtendedDataType& oDataType,
2014                                                        CSLConstList papszOptions = nullptr);
2015 
2016     GUInt64 GetTotalCopyCost() const;
2017 
2018     virtual bool CopyFrom(const std::shared_ptr<GDALGroup>& poDstRootGroup,
2019                           GDALDataset* poSrcDS,
2020                           const std::shared_ptr<GDALGroup>& poSrcGroup,
2021                           bool bStrict,
2022                           GUInt64& nCurCost,
2023                           const GUInt64 nTotalCost,
2024                           GDALProgressFunc pfnProgress,
2025                           void * pProgressData,
2026                           CSLConstList papszOptions = nullptr);
2027 
2028     virtual CSLConstList GetStructuralInfo() const;
2029 
2030     std::shared_ptr<GDALMDArray> OpenMDArrayFromFullname(
2031                                         const std::string& osFullName,
2032                                         CSLConstList papszOptions = nullptr) const;
2033 
2034     std::shared_ptr<GDALMDArray> ResolveMDArray(const std::string& osName,
2035                                                 const std::string& osStartingPath,
2036                                                 CSLConstList papszOptions = nullptr) const;
2037 
2038     std::shared_ptr<GDALGroup> OpenGroupFromFullname(
2039                                         const std::string& osFullName,
2040                                         CSLConstList papszOptions = nullptr) const;
2041 
2042     std::shared_ptr<GDALDimension> OpenDimensionFromFullname(
2043                                         const std::string& osFullName) const;
2044 
2045 //! @cond Doxygen_Suppress
2046     static constexpr GUInt64 COPY_COST = 1000;
2047 //! @endcond
2048 };
2049 
2050 /* ******************************************************************** */
2051 /*                          GDALAbstractMDArray                         */
2052 /* ******************************************************************** */
2053 
2054 /**
2055  * Abstract class, implemented by GDALAttribute and GDALMDArray.
2056  *
2057  * @since GDAL 3.1
2058  */
2059 class CPL_DLL GDALAbstractMDArray
2060 {
2061 protected:
2062 //! @cond Doxygen_Suppress
2063     std::string m_osName{};
2064     std::string m_osFullName{};
2065     std::weak_ptr<GDALAbstractMDArray> m_pSelf{};
2066 
2067     GDALAbstractMDArray(const std::string& osParentName, const std::string& osName);
2068 
2069     void SetSelf(std::weak_ptr<GDALAbstractMDArray> self) { m_pSelf = self; }
2070 
2071     bool CheckReadWriteParams(const GUInt64* arrayStartIdx,
2072                               const size_t* count,
2073                               const GInt64*& arrayStep,
2074                               const GPtrDiff_t*& bufferStride,
2075                               const GDALExtendedDataType& bufferDataType,
2076                               const void* buffer,
2077                               const void* buffer_alloc_start,
2078                               size_t buffer_alloc_size,
2079                               std::vector<GInt64>& tmp_arrayStep,
2080                               std::vector<GPtrDiff_t>& tmp_bufferStride) const;
2081 
2082     virtual bool IRead(const GUInt64* arrayStartIdx,     // array of size GetDimensionCount()
2083                       const size_t* count,                 // array of size GetDimensionCount()
2084                       const GInt64* arrayStep,        // step in elements
2085                       const GPtrDiff_t* bufferStride, // stride in elements
2086                       const GDALExtendedDataType& bufferDataType,
2087                       void* pDstBuffer) const = 0;
2088 
2089     virtual bool IWrite(const GUInt64* arrayStartIdx,     // array of size GetDimensionCount()
2090                       const size_t* count,                 // array of size GetDimensionCount()
2091                       const GInt64* arrayStep,        // step in elements
2092                       const GPtrDiff_t* bufferStride, // stride in elements
2093                       const GDALExtendedDataType& bufferDataType,
2094                       const void* pSrcBuffer);
2095 //! @endcond
2096 
2097 public:
2098     virtual ~GDALAbstractMDArray();
2099 
2100     /** Return the name of an array or attribute.
2101      *
2102      * This is the same as the C function GDALMDArrayGetName() or GDALAttributeGetName().
2103      */
2104     const std::string& GetName() const{ return m_osName; }
2105 
2106     /** Return the name of an array or attribute.
2107      *
2108      * This is the same as the C function GDALMDArrayGetFullName() or GDALAttributeGetFullName().
2109      */
2110     const std::string& GetFullName() const{ return m_osFullName; }
2111 
2112     GUInt64 GetTotalElementsCount() const;
2113 
2114     virtual size_t GetDimensionCount() const;
2115 
2116     virtual const std::vector<std::shared_ptr<GDALDimension>>& GetDimensions() const = 0;
2117 
2118     virtual const GDALExtendedDataType &GetDataType() const = 0;
2119 
2120     virtual std::vector<GUInt64> GetBlockSize() const;
2121 
2122     virtual std::vector<size_t> GetProcessingChunkSize(size_t nMaxChunkMemory) const;
2123 
2124     /** Type of pfnFunc argument of ProcessPerChunk().
2125      * @param array Array on which ProcessPerChunk was called.
2126      * @param chunkArrayStartIdx Values representing the starting index to use
2127      *                           in each dimension (in [0, aoDims[i].GetSize()-1] range)
2128      *                           for the current chunk.
2129      *                           Will be nullptr for a zero-dimensional array.
2130      * @param chunkCount         Values representing the number of values to use in
2131      *                           each dimension for the current chunk.
2132      *                           Will be nullptr for a zero-dimensional array.
2133      * @param iCurChunk          Number of current chunk being processed.
2134      *                           In [1, nChunkCount] range.
2135      * @param nChunkCount        Total number of chunks to process.
2136      * @param pUserData          User data.
2137      * @return return true in case of success.
2138      */
2139     typedef bool (*FuncProcessPerChunkType)(
2140                                 GDALAbstractMDArray* array,
2141                                 const GUInt64* chunkArrayStartIdx,
2142                                 const size_t* chunkCount,
2143                                 GUInt64 iCurChunk,
2144                                 GUInt64 nChunkCount,
2145                                 void* pUserData);
2146 
2147     virtual bool ProcessPerChunk(const GUInt64* arrayStartIdx,
2148                                  const GUInt64* count,
2149                                  const size_t* chunkSize,
2150                                  FuncProcessPerChunkType pfnFunc,
2151                                  void* pUserData);
2152 
2153     bool Read(const GUInt64* arrayStartIdx,     // array of size GetDimensionCount()
2154                       const size_t* count,                 // array of size GetDimensionCount()
2155                       const GInt64* arrayStep,        // step in elements
2156                       const GPtrDiff_t* bufferStride, // stride in elements
2157                       const GDALExtendedDataType& bufferDataType,
2158                       void* pDstBuffer,
2159                       const void* pDstBufferAllocStart = nullptr,
2160                       size_t nDstBufferAllocSize = 0) const;
2161 
2162     bool Write(const GUInt64* arrayStartIdx,     // array of size GetDimensionCount()
2163                       const size_t* count,                 // array of size GetDimensionCount()
2164                       const GInt64* arrayStep,        // step in elements
2165                       const GPtrDiff_t* bufferStride, // stride in elements
2166                       const GDALExtendedDataType& bufferDataType,
2167                       const void* pSrcBuffer,
2168                       const void* pSrcBufferAllocStart = nullptr,
2169                       size_t nSrcBufferAllocSize = 0);
2170 };
2171 
2172 /* ******************************************************************** */
2173 /*                              GDALRawResult                           */
2174 /* ******************************************************************** */
2175 
2176 /**
2177  * Store the raw result of an attribute value, which might contain dynamically
2178  * allocated structures (like pointer to strings).
2179  *
2180  * @since GDAL 3.1
2181  */
2182 class CPL_DLL GDALRawResult
2183 {
2184 private:
2185     GDALExtendedDataType m_dt;
2186     size_t m_nEltCount;
2187     size_t m_nSize;
2188     GByte* m_raw;
2189 
2190     void FreeMe();
2191 
2192     GDALRawResult(const GDALRawResult&) = delete;
2193     GDALRawResult& operator=(const GDALRawResult&) = delete;
2194 
2195 protected:
2196     friend class GDALAttribute;
2197 //! @cond Doxygen_Suppress
2198     GDALRawResult(GByte* raw,
2199                   const GDALExtendedDataType& dt,
2200                   size_t nEltCount);
2201 //! @endcond
2202 
2203 public:
2204     ~GDALRawResult();
2205     GDALRawResult(GDALRawResult&&);
2206     GDALRawResult& operator=(GDALRawResult&&);
2207 
2208     /** Return byte at specified index. */
2209     const GByte& operator[](size_t idx) const { return m_raw[idx]; }
2210     /** Return pointer to the start of data. */
2211     const GByte* data() const { return m_raw; }
2212     /** Return the size in bytes of the raw result. */
2213     size_t size() const { return m_nSize; }
2214 
2215 //! @cond Doxygen_Suppress
2216     GByte* StealData();
2217 //! @endcond
2218 };
2219 
2220 
2221 /* ******************************************************************** */
2222 /*                              GDALAttribute                           */
2223 /* ******************************************************************** */
2224 
2225 /**
2226  * Class modeling an attribute that has a name, a value and a type, and is
2227  * typically used to describe a metadata item. The value can be (for the
2228  * HDF5 format) in the general case a multidimensional array of "any" type
2229  * (in most cases, this will be a single value of string or numeric type)
2230  *
2231  * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_attribute">HDF5 attribute concept</a>
2232  *
2233  * @since GDAL 3.1
2234  */
2235 class CPL_DLL GDALAttribute: virtual public GDALAbstractMDArray
2236 {
2237     mutable std::string m_osCachedVal{};
2238 
2239 protected:
2240 //! @cond Doxygen_Suppress
2241     GDALAttribute(const std::string& osParentName, const std::string& osName);
2242 //! @endcond
2243 
2244 public:
2245 
2246     std::vector<GUInt64> GetDimensionsSize() const;
2247 
2248     GDALRawResult ReadAsRaw() const;
2249     const char* ReadAsString() const;
2250     int ReadAsInt() const;
2251     double ReadAsDouble() const;
2252     CPLStringList ReadAsStringArray() const;
2253     std::vector<int> ReadAsIntArray() const;
2254     std::vector<double> ReadAsDoubleArray() const;
2255 
2256     using GDALAbstractMDArray::Write;
2257     bool Write(const void* pabyValue, size_t nLen);
2258     bool Write(const char*);
2259     bool WriteInt(int);
2260     bool Write(double);
2261     bool Write(CSLConstList);
2262     bool Write(const double*, size_t);
2263 
2264 //! @cond Doxygen_Suppress
2265     static constexpr GUInt64 COPY_COST = 100;
2266 //! @endcond
2267 
2268 };
2269 
2270 /************************************************************************/
2271 /*                            GDALAttributeString                       */
2272 /************************************************************************/
2273 
2274 //! @cond Doxygen_Suppress
2275 class CPL_DLL GDALAttributeString final: public GDALAttribute
2276 {
2277     std::vector<std::shared_ptr<GDALDimension>> m_dims{};
2278     GDALExtendedDataType m_dt = GDALExtendedDataType::CreateString();
2279     std::string m_osValue;
2280 
2281 protected:
2282 
2283     bool IRead(const GUInt64* ,
2284                const size_t* ,
2285                const GInt64* ,
2286                const GPtrDiff_t* ,
2287                const GDALExtendedDataType& bufferDataType,
2288                void* pDstBuffer) const override;
2289 
2290 public:
2291     GDALAttributeString(const std::string& osParentName,
2292                   const std::string& osName,
2293                   const std::string& osValue);
2294 
2295     const std::vector<std::shared_ptr<GDALDimension>>& GetDimensions() const override;
2296 
2297     const GDALExtendedDataType &GetDataType() const override;
2298 };
2299 //! @endcond
2300 
2301 /************************************************************************/
2302 /*                           GDALAttributeNumeric                       */
2303 /************************************************************************/
2304 
2305 //! @cond Doxygen_Suppress
2306 class CPL_DLL GDALAttributeNumeric final: public GDALAttribute
2307 {
2308     std::vector<std::shared_ptr<GDALDimension>> m_dims{};
2309     GDALExtendedDataType m_dt;
2310     int m_nValue = 0;
2311     double m_dfValue = 0;
2312     std::vector<GUInt32> m_anValuesUInt32{};
2313 
2314 protected:
2315 
2316     bool IRead(const GUInt64* ,
2317                const size_t* ,
2318                const GInt64* ,
2319                const GPtrDiff_t* ,
2320                const GDALExtendedDataType& bufferDataType,
2321                void* pDstBuffer) const override;
2322 
2323 public:
2324     GDALAttributeNumeric(const std::string& osParentName,
2325                   const std::string& osName,
2326                   double dfValue);
2327     GDALAttributeNumeric(const std::string& osParentName,
2328                   const std::string& osName,
2329                   int nValue);
2330     GDALAttributeNumeric(const std::string& osParentName,
2331                   const std::string& osName,
2332                   const std::vector<GUInt32>& anValues);
2333 
2334     const std::vector<std::shared_ptr<GDALDimension>>& GetDimensions() const override;
2335 
2336     const GDALExtendedDataType &GetDataType() const override;
2337 };
2338 //! @endcond
2339 
2340 /* ******************************************************************** */
2341 /*                              GDALMDArray                             */
2342 /* ******************************************************************** */
2343 
2344 /**
2345  * Class modeling a multi-dimensional array. It has a name, values organized
2346  * as an array and a list of GDALAttribute.
2347  *
2348  * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_dataset">HDF5 dataset concept</a>
2349  *
2350  * @since GDAL 3.1
2351  */
2352 class CPL_DLL GDALMDArray: virtual public GDALAbstractMDArray, public GDALIHasAttribute
2353 {
2354     std::shared_ptr<GDALMDArray> GetView(const std::vector<GUInt64>& indices) const;
2355 
2356     inline std::shared_ptr<GDALMDArray> atInternal(std::vector<GUInt64>& indices) const
2357     {
2358         return GetView(indices);
2359     }
2360 
2361     template<typename... GUInt64VarArg>
2362     // cppcheck-suppress functionStatic
2363     inline std::shared_ptr<GDALMDArray> atInternal(std::vector<GUInt64>& indices,
2364                                             GUInt64 idx, GUInt64VarArg... tail) const
2365     {
2366         indices.push_back(idx);
2367         return atInternal(indices, tail...);
2368     }
2369 
2370     bool SetStatistics( GDALDataset* poDS,
2371                         bool bApproxStats,
2372                         double dfMin, double dfMax,
2373                         double dfMean, double dfStdDev,
2374                         GUInt64 nValidCount );
2375 
2376 protected:
2377 //! @cond Doxygen_Suppress
2378     GDALMDArray(const std::string& osParentName, const std::string& osName);
2379 
2380     virtual bool IAdviseRead(const GUInt64* arrayStartIdx,
2381                              const size_t* count) const;
2382 
2383 //! @endcond
2384 
2385 public:
2386 
2387     GUInt64 GetTotalCopyCost() const;
2388 
2389     virtual bool CopyFrom(GDALDataset* poSrcDS,
2390                           const GDALMDArray* poSrcArray,
2391                           bool bStrict,
2392                           GUInt64& nCurCost,
2393                           const GUInt64 nTotalCost,
2394                           GDALProgressFunc pfnProgress,
2395                           void * pProgressData);
2396 
2397     /** Return whether an array is writable; */
2398     virtual bool IsWritable() const = 0;
2399 
2400     virtual CSLConstList GetStructuralInfo() const;
2401 
2402     virtual const std::string& GetUnit() const;
2403 
2404     virtual bool SetUnit(const std::string& osUnit);
2405 
2406     virtual bool SetSpatialRef(const OGRSpatialReference* poSRS);
2407 
2408     virtual std::shared_ptr<OGRSpatialReference> GetSpatialRef() const;
2409 
2410     virtual const void* GetRawNoDataValue() const;
2411 
2412     double GetNoDataValueAsDouble(bool* pbHasNoData = nullptr) const;
2413 
2414     virtual bool SetRawNoDataValue(const void* pRawNoData);
2415 
2416     bool SetNoDataValue(double dfNoData);
2417 
2418     virtual double GetOffset(bool* pbHasOffset = nullptr, GDALDataType* peStorageType = nullptr) const;
2419 
2420     virtual double GetScale(bool* pbHasScale = nullptr, GDALDataType* peStorageType = nullptr) const;
2421 
2422     virtual bool SetOffset(double dfOffset, GDALDataType eStorageType = GDT_Unknown);
2423 
2424     virtual bool SetScale(double dfScale, GDALDataType eStorageType = GDT_Unknown);
2425 
2426     std::shared_ptr<GDALMDArray> GetView(const std::string& viewExpr) const;
2427 
2428     std::shared_ptr<GDALMDArray> operator[](const std::string& fieldName) const;
2429 
2430     /** Return a view of the array using integer indexing.
2431     *
2432     * Equivalent of GetView("[indices_0,indices_1,.....,indices_last]")
2433     *
2434     * Example:
2435     * \code
2436     * ar->at(0,3,2)
2437     * \endcode
2438     */
2439     // sphinx 4.1.0 / breathe 4.30.0 don't like typename...
2440 //! @cond Doxygen_Suppress
2441     template<typename... GUInt64VarArg>
2442 //! @endcond
2443     // cppcheck-suppress functionStatic
2444     std::shared_ptr<GDALMDArray> at(GUInt64 idx, GUInt64VarArg... tail) const
2445     {
2446         std::vector<GUInt64> indices;
2447         indices.push_back(idx);
2448         return atInternal(indices, tail...);
2449     }
2450 
2451     virtual std::shared_ptr<GDALMDArray> Transpose(const std::vector<int>& anMapNewAxisToOldAxis) const;
2452 
2453     std::shared_ptr<GDALMDArray> GetUnscaled() const;
2454 
2455     virtual std::shared_ptr<GDALMDArray> GetMask(CSLConstList papszOptions) const;
2456 
2457     virtual GDALDataset* AsClassicDataset(size_t iXDim, size_t iYDim) const;
2458 
2459     virtual CPLErr GetStatistics( GDALDataset* poDS,
2460                                   bool bApproxOK, bool bForce,
2461                                   double *pdfMin, double *pdfMax,
2462                                   double *pdfMean, double *padfStdDev,
2463                                   GUInt64* pnValidCount,
2464                                   GDALProgressFunc pfnProgress, void *pProgressData );
2465 
2466     virtual bool ComputeStatistics( GDALDataset* poDS,
2467                                     bool bApproxOK,
2468                                     double *pdfMin, double *pdfMax,
2469                                     double *pdfMean, double *pdfStdDev,
2470                                     GUInt64* pnValidCount,
2471                                     GDALProgressFunc, void *pProgressData );
2472 
2473     bool AdviseRead(const GUInt64* arrayStartIdx,
2474                     const size_t* count) const;
2475 
2476 //! @cond Doxygen_Suppress
2477     static constexpr GUInt64 COPY_COST = 1000;
2478 
2479     bool CopyFromAllExceptValues(const GDALMDArray* poSrcArray,
2480                                           bool bStrict,
2481                                           GUInt64& nCurCost,
2482                                           const GUInt64 nTotalCost,
2483                                           GDALProgressFunc pfnProgress,
2484                                           void * pProgressData);
2485     struct Range
2486     {
2487         GUInt64 m_nStartIdx;
2488         GInt64  m_nIncr;
2489         Range(GUInt64 nStartIdx = 0, GInt64 nIncr = 0):
2490             m_nStartIdx(nStartIdx), m_nIncr(nIncr) {}
2491     };
2492 
2493     struct ViewSpec
2494     {
2495         std::string m_osFieldName{};
2496 
2497         // or
2498 
2499         std::vector<size_t> m_mapDimIdxToParentDimIdx{}; // of size m_dims.size()
2500         std::vector<Range> m_parentRanges{} ; // of size m_poParent->GetDimensionCount()
2501     };
2502 
2503     virtual std::shared_ptr<GDALMDArray> GetView(const std::string& viewExpr,
2504                                                  bool bRenameDimensions,
2505                                                  std::vector<ViewSpec>& viewSpecs) const;
2506 //! @endcond
2507 };
2508 
2509 
2510 /************************************************************************/
2511 /*                     GDALMDArrayRegularlySpaced                       */
2512 /************************************************************************/
2513 
2514 //! @cond Doxygen_Suppress
2515 class CPL_DLL GDALMDArrayRegularlySpaced: public GDALMDArray
2516 {
2517     double m_dfStart;
2518     double m_dfIncrement;
2519     double m_dfOffsetInIncrement;
2520     GDALExtendedDataType m_dt = GDALExtendedDataType::Create(GDT_Float64);
2521     std::vector<std::shared_ptr<GDALDimension>> m_dims;
2522     std::vector<std::shared_ptr<GDALAttribute>> m_attributes{};
2523 
2524 protected:
2525 
2526     bool IRead(const GUInt64* ,
2527                const size_t* ,
2528                const GInt64* ,
2529                const GPtrDiff_t* ,
2530                const GDALExtendedDataType& bufferDataType,
2531                void* pDstBuffer) const override;
2532 
2533 public:
2534     GDALMDArrayRegularlySpaced(
2535                 const std::string& osParentName,
2536                 const std::string& osName,
2537                 const std::shared_ptr<GDALDimension>& poDim,
2538                 double dfStart, double dfIncrement,
2539                 double dfOffsetInIncrement);
2540 
2541     bool IsWritable() const override { return false; }
2542 
2543     const std::vector<std::shared_ptr<GDALDimension>>& GetDimensions() const override;
2544 
2545     const GDALExtendedDataType &GetDataType() const override;
2546 
2547     std::vector<std::shared_ptr<GDALAttribute>> GetAttributes(CSLConstList) const override;
2548 
2549     void AddAttribute(const std::shared_ptr<GDALAttribute>& poAttr);
2550 };
2551 //! @endcond
2552 
2553 /* ******************************************************************** */
2554 /*                            GDALDimension                             */
2555 /* ******************************************************************** */
2556 
2557 /**
2558  * Class modeling a a dimension / axis used to index multidimensional arrays.
2559  * It has a name, a size (that is the number of values that can be indexed along
2560  * the dimension), a type (see GDALDimension::GetType()), a direction
2561  * (see GDALDimension::GetDirection()), a unit and can optionally point to a GDALMDArray variable,
2562  * typically one-dimensional, describing the values taken by the dimension.
2563  * For a georeferenced GDALMDArray and its X dimension, this will be typically
2564  * the values of the easting/longitude for each grid point.
2565  *
2566  * @since GDAL 3.1
2567  */
2568 class CPL_DLL GDALDimension
2569 {
2570 public:
2571 //! @cond Doxygen_Suppress
2572     GDALDimension(const std::string& osParentName,
2573                   const std::string& osName,
2574                   const std::string& osType,
2575                   const std::string& osDirection,
2576                   GUInt64 nSize);
2577 //! @endcond
2578 
2579     virtual ~GDALDimension();
2580 
2581     /** Return the name.
2582      *
2583      * This is the same as the C function GDALDimensionGetName()
2584      */
2585     const std::string& GetName() const { return m_osName; }
2586 
2587     /** Return the full name.
2588      *
2589      * This is the same as the C function GDALDimensionGetFullName()
2590      */
2591     const std::string& GetFullName() const { return m_osFullName; }
2592 
2593     /** Return the axis type.
2594      *
2595      * Predefined values are:
2596      * HORIZONTAL_X, HORIZONTAL_Y, VERTICAL, TEMPORAL, PARAMETRIC
2597      * Other values might be returned. Empty value means unknown.
2598      *
2599      * This is the same as the C function GDALDimensionGetType()
2600      */
2601     const std::string& GetType() const { return m_osType; }
2602 
2603     /** Return the axis direction.
2604      *
2605      * Predefined values are:
2606      * EAST, WEST, SOUTH, NORTH, UP, DOWN, FUTURE, PAST
2607      * Other values might be returned. Empty value means unknown.
2608      *
2609      * This is the same as the C function GDALDimensionGetDirection()
2610      */
2611     const std::string& GetDirection() const { return m_osDirection; }
2612 
2613     /** Return the size, that is the number of values along the dimension.
2614      *
2615      * This is the same as the C function GDALDimensionGetSize()
2616      */
2617     GUInt64 GetSize() const { return m_nSize; }
2618 
2619     virtual std::shared_ptr<GDALMDArray> GetIndexingVariable() const;
2620 
2621     virtual bool SetIndexingVariable(std::shared_ptr<GDALMDArray> poIndexingVariable);
2622 
2623 protected:
2624 //! @cond Doxygen_Suppress
2625     std::string m_osName;
2626     std::string m_osFullName;
2627     std::string m_osType;
2628     std::string m_osDirection;
2629     GUInt64 m_nSize;
2630 //! @endcond
2631 };
2632 
2633 
2634 /************************************************************************/
2635 /*                   GDALDimensionWeakIndexingVar()                     */
2636 /************************************************************************/
2637 
2638 //! @cond Doxygen_Suppress
2639 class CPL_DLL GDALDimensionWeakIndexingVar: public GDALDimension
2640 {
2641     std::weak_ptr<GDALMDArray> m_poIndexingVariable{};
2642 
2643 public:
2644     GDALDimensionWeakIndexingVar(const std::string& osParentName,
2645                   const std::string& osName,
2646                   const std::string& osType,
2647                   const std::string& osDirection,
2648                   GUInt64 nSize);
2649 
2650     std::shared_ptr<GDALMDArray> GetIndexingVariable() const override;
2651 
2652     bool SetIndexingVariable(std::shared_ptr<GDALMDArray> poIndexingVariable) override;
2653 };
2654 //! @endcond
2655 
2656 /* ==================================================================== */
2657 /*      An assortment of overview related stuff.                        */
2658 /* ==================================================================== */
2659 
2660 //! @cond Doxygen_Suppress
2661 /* Only exported for drivers as plugin. Signature may change */
2662 CPLErr CPL_DLL
2663 GDALRegenerateOverviewsMultiBand(int nBands, GDALRasterBand** papoSrcBands,
2664                                  int nOverviews,
2665                                  GDALRasterBand*** papapoOverviewBands,
2666                                  const char * pszResampling,
2667                                  GDALProgressFunc pfnProgress, void * pProgressData );
2668 
2669 typedef CPLErr (*GDALResampleFunction)
2670                       ( double dfXRatioDstToSrc,
2671                         double dfYRatioDstToSrc,
2672                         double dfSrcXDelta,
2673                         double dfSrcYDelta,
2674                         GDALDataType eWrkDataType,
2675                         const void * pChunk,
2676                         const GByte * pabyChunkNodataMask,
2677                         int nChunkXOff, int nChunkXSize,
2678                         int nChunkYOff, int nChunkYSize,
2679                         int nDstXOff, int nDstXOff2,
2680                         int nDstYOff, int nDstYOff2,
2681                         GDALRasterBand * poOverview,
2682                         void** ppDstBuffer,
2683                         GDALDataType* peDstBufferDataType,
2684                         const char * pszResampling,
2685                         int bHasNoData, float fNoDataValue,
2686                         GDALColorTable* poColorTable,
2687                         GDALDataType eSrcDataType,
2688                         bool bPropagateNoData );
2689 
2690 GDALResampleFunction GDALGetResampleFunction(const char* pszResampling,
2691                                                  int* pnRadius);
2692 
2693 GDALDataType GDALGetOvrWorkDataType(const char* pszResampling,
2694                                         GDALDataType eSrcDataType);
2695 
2696 CPL_C_START
2697 
2698 CPLErr CPL_DLL
2699 HFAAuxBuildOverviews( const char *pszOvrFilename, GDALDataset *poParentDS,
2700                       GDALDataset **ppoDS,
2701                       int nBands, int *panBandList,
2702                       int nNewOverviews, int *panNewOverviewList,
2703                       const char *pszResampling,
2704                       GDALProgressFunc pfnProgress,
2705                       void *pProgressData );
2706 
2707 CPLErr CPL_DLL
2708 GTIFFBuildOverviews( const char * pszFilename,
2709                      int nBands, GDALRasterBand **papoBandList,
2710                      int nOverviews, int * panOverviewList,
2711                      const char * pszResampling,
2712                      GDALProgressFunc pfnProgress, void * pProgressData );
2713 
2714 int CPL_DLL GDALBandGetBestOverviewLevel(GDALRasterBand* poBand,
2715                                          int &nXOff, int &nYOff,
2716                                          int &nXSize, int &nYSize,
2717                                          int nBufXSize, int nBufYSize) CPL_WARN_DEPRECATED("Use GDALBandGetBestOverviewLevel2 instead");
2718 int CPL_DLL GDALBandGetBestOverviewLevel2(GDALRasterBand* poBand,
2719                                          int &nXOff, int &nYOff,
2720                                          int &nXSize, int &nYSize,
2721                                          int nBufXSize, int nBufYSize,
2722                                          GDALRasterIOExtraArg* psExtraArg);
2723 
2724 int CPL_DLL GDALOvLevelAdjust( int nOvLevel, int nXSize ) CPL_WARN_DEPRECATED("Use GDALOvLevelAdjust2 instead");
2725 int CPL_DLL GDALOvLevelAdjust2( int nOvLevel, int nXSize, int nYSize );
2726 int CPL_DLL GDALComputeOvFactor( int nOvrXSize, int nRasterXSize,
2727                                  int nOvrYSize, int nRasterYSize );
2728 
2729 GDALDataset CPL_DLL *
2730 GDALFindAssociatedAuxFile( const char *pszBasefile, GDALAccess eAccess,
2731                            GDALDataset *poDependentDS );
2732 
2733 /* ==================================================================== */
2734 /*  Infrastructure to check that dataset characteristics are valid      */
2735 /* ==================================================================== */
2736 
2737 int CPL_DLL GDALCheckDatasetDimensions( int nXSize, int nYSize );
2738 int CPL_DLL GDALCheckBandCount( int nBands, int bIsZeroAllowed );
2739 
2740 /* Internal use only */
2741 
2742 /* CPL_DLL exported, but only for in-tree drivers that can be built as plugins */
2743 int CPL_DLL GDALReadWorldFile2( const char *pszBaseFilename, const char *pszExtension,
2744                                 double *padfGeoTransform, char** papszSiblingFiles,
2745                                 char** ppszWorldFileNameOut);
2746 int GDALReadTabFile2( const char * pszBaseFilename,
2747                       double *padfGeoTransform, char **ppszWKT,
2748                       int *pnGCPCount, GDAL_GCP **ppasGCPs,
2749                       char** papszSiblingFiles, char** ppszTabFileNameOut );
2750 
2751 void CPL_DLL GDALCopyRasterIOExtraArg(GDALRasterIOExtraArg* psDestArg,
2752                                       GDALRasterIOExtraArg* psSrcArg);
2753 
2754 CPL_C_END
2755 
2756 void GDALNullifyOpenDatasetsList();
2757 CPLMutex** GDALGetphDMMutex();
2758 CPLMutex** GDALGetphDLMutex();
2759 void GDALNullifyProxyPoolSingleton();
2760 void GDALSetResponsiblePIDForCurrentThread(GIntBig responsiblePID);
2761 GIntBig GDALGetResponsiblePIDForCurrentThread();
2762 
2763 CPLString GDALFindAssociatedFile( const char *pszBasename, const char *pszExt,
2764                                   CSLConstList papszSiblingFiles, int nFlags );
2765 
2766 CPLErr CPL_DLL EXIFExtractMetadata(char**& papszMetadata,
2767                            void *fpL, int nOffset,
2768                            int bSwabflag, int nTIFFHEADER,
2769                            int& nExifOffset, int& nInterOffset, int& nGPSOffset);
2770 
2771 int GDALValidateOpenOptions( GDALDriverH hDriver,
2772                              const char* const* papszOptionOptions);
2773 int GDALValidateOptions( const char* pszOptionList,
2774                          const char* const* papszOptionsToValidate,
2775                          const char* pszErrorMessageOptionType,
2776                          const char* pszErrorMessageContainerName);
2777 
2778 GDALRIOResampleAlg GDALRasterIOGetResampleAlg(const char* pszResampling);
2779 const char* GDALRasterIOGetResampleAlg(GDALRIOResampleAlg eResampleAlg);
2780 
2781 void GDALRasterIOExtraArgSetResampleAlg(GDALRasterIOExtraArg* psExtraArg,
2782                                         int nXSize, int nYSize,
2783                                         int nBufXSize, int nBufYSize);
2784 
2785 
2786 GDALDataset* GDALCreateOverviewDataset(GDALDataset* poDS, int nOvrLevel,
2787                                        int bThisLevelOnly);
2788 
2789 // Should cover particular cases of #3573, #4183, #4506, #6578
2790 // Behavior is undefined if fVal1 or fVal2 are NaN (should be tested before
2791 // calling this function)
2792 template<class T> inline bool ARE_REAL_EQUAL(T fVal1, T fVal2, int ulp = 2)
2793 {
2794     return fVal1 == fVal2 || /* Should cover infinity */
2795            std::abs(fVal1 - fVal2) < std::numeric_limits<float>::epsilon() * std::abs(fVal1+fVal2) * ulp;
2796 }
2797 
2798 double GDALAdjustNoDataCloseToFloatMax(double dfVal);
2799 
2800 #define DIV_ROUND_UP(a, b) ( ((a) % (b)) == 0 ? ((a) / (b)) : (((a) / (b)) + 1) )
2801 
2802 // Number of data samples that will be used to compute approximate statistics
2803 // (minimum value, maximum value, etc.)
2804 #define GDALSTAT_APPROX_NUMSAMPLES 2500
2805 
2806 void GDALSerializeGCPListToXML( CPLXMLNode* psParentNode,
2807                                 GDAL_GCP* pasGCPList,
2808                                 int nGCPCount,
2809                                 const OGRSpatialReference* poGCP_SRS );
2810 void GDALDeserializeGCPListFromXML( CPLXMLNode* psGCPList,
2811                                     GDAL_GCP** ppasGCPList,
2812                                     int* pnGCPCount,
2813                                     OGRSpatialReference** ppoGCP_SRS );
2814 
2815 void GDALSerializeOpenOptionsToXML( CPLXMLNode* psParentNode, char** papszOpenOptions);
2816 char** GDALDeserializeOpenOptionsFromXML( CPLXMLNode* psParentNode );
2817 
2818 int GDALCanFileAcceptSidecarFile(const char* pszFilename);
2819 
2820 bool GDALCanReliablyUseSiblingFileList(const char* pszFilename);
2821 
2822 bool CPL_DLL GDALIsDriverDeprecatedForGDAL35StillEnabled(const char* pszDriverName, const char* pszExtraMsg = "");
2823 
2824 //! @endcond
2825 
2826 #endif /* ndef GDAL_PRIV_H_INCLUDED */
2827