Coverage Report

Created: 2025-06-13 06:29

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