• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OSGeo / gdal / 15885686134

25 Jun 2025 07:44PM UTC coverage: 71.084%. Remained the same
15885686134

push

github

rouault
gdal_priv.h: fix C++11 compatibility

573814 of 807237 relevant lines covered (71.08%)

250621.56 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.85
/gcore/gdal_priv.h
1
/******************************************************************************
2
 *
3
 * Name:     gdal_priv.h
4
 * Project:  GDAL Core
5
 * Purpose:  GDAL Core C++/Private declarations.
6
 * Author:   Frank Warmerdam, warmerdam@pobox.com
7
 *
8
 ******************************************************************************
9
 * Copyright (c) 1998, Frank Warmerdam
10
 * Copyright (c) 2007-2014, Even Rouault <even dot rouault at spatialys.com>
11
 *
12
 * SPDX-License-Identifier: MIT
13
 ****************************************************************************/
14

15
#ifndef GDAL_PRIV_H_INCLUDED
16
#define GDAL_PRIV_H_INCLUDED
17

18
/**
19
 * \file gdal_priv.h
20
 *
21
 * C++ GDAL entry points.
22
 */
23

24
/* -------------------------------------------------------------------- */
25
/*      Predeclare various classes before pulling in gdal.h, the        */
26
/*      public declarations.                                            */
27
/* -------------------------------------------------------------------- */
28
class GDALMajorObject;
29
class GDALDataset;
30
class GDALRasterBand;
31
class GDALDriver;
32
class GDALRasterAttributeTable;
33
class GDALProxyDataset;
34
class GDALProxyRasterBand;
35
class GDALAsyncReader;
36
class GDALRelationship;
37
class GDALAlgorithm;
38

39
/* -------------------------------------------------------------------- */
40
/*      Pull in the public declarations.  This gets the C apis, and     */
41
/*      also various constants.  However, we will still get to          */
42
/*      provide the real class definitions for the GDAL classes.        */
43
/* -------------------------------------------------------------------- */
44

45
#include "gdal.h"
46
#include "gdal_frmts.h"
47
#include "gdalsubdatasetinfo.h"
48
#include "cpl_vsi.h"
49
#include "cpl_conv.h"
50
#include "cpl_string.h"
51
#include "cpl_minixml.h"
52
#include "cpl_multiproc.h"
53
#include "cpl_atomic_ops.h"
54

55
#include <stdarg.h>
56

57
#include <algorithm>
58
#include <cmath>
59
#include <complex>
60
#include <cstdint>
61
#include <iterator>
62
#include <limits>
63
#include <map>
64
#include <memory>
65
#include <set>
66
#if __cplusplus >= 202002L
67
#include <span>
68
#endif
69
#include <type_traits>
70
#include <vector>
71

72
#include "ogr_core.h"
73
#include "ogr_feature.h"
74

75
//! @cond Doxygen_Suppress
76
#define GMO_VALID 0x0001
77
#define GMO_IGNORE_UNIMPLEMENTED 0x0002
78
#define GMO_SUPPORT_MD 0x0004
79
#define GMO_SUPPORT_MDMD 0x0008
80
#define GMO_MD_DIRTY 0x0010
81
#define GMO_PAM_CLASS 0x0020
82

83
//! @endcond
84

85
/************************************************************************/
86
/*                       GDALMultiDomainMetadata                        */
87
/************************************************************************/
88

89
//! @cond Doxygen_Suppress
90
class CPL_DLL GDALMultiDomainMetadata
7,011,688✔
91
{
92
  private:
93
    CPLStringList aosDomainList{};
94

95
    struct Comparator
96
    {
97
        bool operator()(const char *a, const char *b) const
31,833,000✔
98
        {
99
            return STRCASECMP(a, b) < 0;
31,833,000✔
100
        }
101
    };
102

103
    std::map<const char *, CPLStringList, Comparator> oMetadata{};
104

105
  public:
106
    GDALMultiDomainMetadata();
107

108
    /** Copy constructor */
109
    GDALMultiDomainMetadata(const GDALMultiDomainMetadata &) = default;
110

111
    /** Copy assignment operator */
112
    GDALMultiDomainMetadata &
113
    operator=(const GDALMultiDomainMetadata &) = default;
114

115
    /** Move constructor */
116
    GDALMultiDomainMetadata(GDALMultiDomainMetadata &&) = default;
117

118
    /** Move assignment operator */
119
    GDALMultiDomainMetadata &operator=(GDALMultiDomainMetadata &&) = default;
120

121
    ~GDALMultiDomainMetadata();
122

123
    int XMLInit(const CPLXMLNode *psMetadata, int bMerge);
124
    CPLXMLNode *Serialize() const;
125

126
    CSLConstList GetDomainList() const
711,409✔
127
    {
128
        return aosDomainList.List();
711,409✔
129
    }
130

131
    char **GetMetadata(const char *pszDomain = "");
132
    CPLErr SetMetadata(CSLConstList papszMetadata, const char *pszDomain = "");
133
    const char *GetMetadataItem(const char *pszName,
134
                                const char *pszDomain = "");
135
    CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
136
                           const char *pszDomain = "");
137

138
    void Clear();
139

140
    inline void clear()
141
    {
142
        Clear();
143
    }
144
};
145

146
//! @endcond
147

148
/* ******************************************************************** */
149
/*                           GDALMajorObject                            */
150
/*                                                                      */
151
/*      Base class providing metadata, description and other            */
152
/*      services shared by major objects.                               */
153
/* ******************************************************************** */
154

155
/** Object with metadata. */
156
class CPL_DLL GDALMajorObject
157
{
158
  protected:
159
    //! @cond Doxygen_Suppress
160
    int nFlags;  // GMO_* flags.
161
    CPLString sDescription{};
162
    GDALMultiDomainMetadata oMDMD{};
163

164
    //! @endcond
165

166
    char **BuildMetadataDomainList(char **papszList, int bCheckNonEmpty,
167
                                   ...) CPL_NULL_TERMINATED;
168

169
    /** Copy constructor */
170
    GDALMajorObject(const GDALMajorObject &) = default;
171

172
    /** Copy assignment operator */
173
    GDALMajorObject &operator=(const GDALMajorObject &) = default;
174

175
    /** Move constructor */
176
    GDALMajorObject(GDALMajorObject &&) = default;
177

178
    /** Move assignment operator */
179
    GDALMajorObject &operator=(GDALMajorObject &&) = default;
180

181
  public:
182
    GDALMajorObject();
183
    virtual ~GDALMajorObject();
184

185
    int GetMOFlags() const;
186
    void SetMOFlags(int nFlagsIn);
187

188
    virtual const char *GetDescription() const;
189
    virtual void SetDescription(const char *);
190

191
    virtual char **GetMetadataDomainList();
192

193
    virtual char **GetMetadata(const char *pszDomain = "");
194
    virtual CPLErr SetMetadata(char **papszMetadata,
195
                               const char *pszDomain = "");
196
    virtual const char *GetMetadataItem(const char *pszName,
197
                                        const char *pszDomain = "");
198
    virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
199
                                   const char *pszDomain = "");
200

201
    /** Convert a GDALMajorObject* to a GDALMajorObjectH.
202
     * @since GDAL 2.3
203
     */
204
    static inline GDALMajorObjectH ToHandle(GDALMajorObject *poMajorObject)
248✔
205
    {
206
        return static_cast<GDALMajorObjectH>(poMajorObject);
248✔
207
    }
208

209
    /** Convert a GDALMajorObjectH to a GDALMajorObject*.
210
     * @since GDAL 2.3
211
     */
212
    static inline GDALMajorObject *FromHandle(GDALMajorObjectH hMajorObject)
294,538✔
213
    {
214
        return static_cast<GDALMajorObject *>(hMajorObject);
294,538✔
215
    }
216
};
217

218
/* ******************************************************************** */
219
/*                         GDALDefaultOverviews                         */
220
/* ******************************************************************** */
221

222
//! @cond Doxygen_Suppress
223
class GDALOpenInfo;
224

225
class CPL_DLL GDALDefaultOverviews
226
{
227
    friend class GDALDataset;
228

229
    GDALDataset *poDS;
230
    GDALDataset *poODS;
231

232
    CPLString osOvrFilename{};
233

234
    bool bOvrIsAux;
235

236
    bool bCheckedForMask;
237
    bool bOwnMaskDS;
238
    GDALDataset *poMaskDS;
239

240
    // For "overview datasets" we record base level info so we can
241
    // find our way back to get overview masks.
242
    GDALDataset *poBaseDS;
243

244
    // Stuff for deferred initialize/overviewscans.
245
    bool bCheckedForOverviews;
246
    void OverviewScan();
247
    char *pszInitName;
248
    bool bInitNameIsOVR;
249
    char **papszInitSiblingFiles;
250

251
  public:
252
    GDALDefaultOverviews();
253
    ~GDALDefaultOverviews();
254

255
    void Initialize(GDALDataset *poDSIn, const char *pszName = nullptr,
256
                    CSLConstList papszSiblingFiles = nullptr,
257
                    bool bNameIsOVR = false);
258

259
    void Initialize(GDALDataset *poDSIn, GDALOpenInfo *poOpenInfo,
260
                    const char *pszName = nullptr,
261
                    bool bTransferSiblingFilesIfLoaded = true);
262

263
    void TransferSiblingFiles(char **papszSiblingFiles);
264

265
    int IsInitialized();
266

267
    int CloseDependentDatasets();
268

269
    // Overview Related
270

271
    int GetOverviewCount(int nBand);
272
    GDALRasterBand *GetOverview(int nBand, int iOverview);
273

274
    CPLErr BuildOverviews(const char *pszBasename, const char *pszResampling,
275
                          int nOverviews, const int *panOverviewList,
276
                          int nBands, const int *panBandList,
277
                          GDALProgressFunc pfnProgress, void *pProgressData,
278
                          CSLConstList papszOptions);
279

280
    CPLErr BuildOverviewsSubDataset(const char *pszPhysicalFile,
281
                                    const char *pszResampling, int nOverviews,
282
                                    const int *panOverviewList, int nBands,
283
                                    const int *panBandList,
284
                                    GDALProgressFunc pfnProgress,
285
                                    void *pProgressData,
286
                                    CSLConstList papszOptions);
287

288
    CPLErr BuildOverviewsMask(const char *pszResampling, int nOverviews,
289
                              const int *panOverviewList,
290
                              GDALProgressFunc pfnProgress, void *pProgressData,
291
                              CSLConstList papszOptions);
292

293
    CPLErr CleanOverviews();
294

295
    // Mask Related
296

297
    CPLErr CreateMaskBand(int nFlags, int nBand = -1);
298
    GDALRasterBand *GetMaskBand(int nBand);
299
    int GetMaskFlags(int nBand);
300

301
    int HaveMaskFile(char **papszSiblings = nullptr,
302
                     const char *pszBasename = nullptr);
303

304
    char **GetSiblingFiles()
58,716✔
305
    {
306
        return papszInitSiblingFiles;
58,716✔
307
    }
308

309
  private:
310
    CPL_DISALLOW_COPY_ASSIGN(GDALDefaultOverviews)
311
};
312

313
//! @endcond
314

315
/* ******************************************************************** */
316
/*                             GDALOpenInfo                             */
317
/* ******************************************************************** */
318

319
/** Class for dataset open functions. */
320
class CPL_DLL GDALOpenInfo
321
{
322
    bool bHasGotSiblingFiles = false;
323
    char **papszSiblingFiles = nullptr;
324
    int nHeaderBytesTried = 0;
325

326
  public:
327
    GDALOpenInfo(const char *pszFile, int nOpenFlagsIn,
328
                 const char *const *papszSiblingFiles = nullptr);
329
    ~GDALOpenInfo(void);
330

331
    /** Filename */
332
    char *pszFilename = nullptr;
333

334
    /** Result of CPLGetExtension(pszFilename); */
335
    std::string osExtension{};
336

337
    /** Open options */
338
    char **papszOpenOptions = nullptr;
339

340
    /** Access flag */
341
    GDALAccess eAccess = GA_ReadOnly;
342
    /** Open flags */
343
    int nOpenFlags = 0;
344

345
    /** Whether stat()'ing the file was successful */
346
    bool bStatOK = false;
347
    /** Whether the file is a directory */
348
    bool bIsDirectory = false;
349

350
    /** Pointer to the file */
351
    VSILFILE *fpL = nullptr;
352

353
    /** Number of bytes in pabyHeader */
354
    int nHeaderBytes = 0;
355
    /** Buffer with first bytes of the file */
356
    GByte *pabyHeader = nullptr;
357

358
    /** Allowed drivers (NULL for all) */
359
    const char *const *papszAllowedDrivers = nullptr;
360

361
    int TryToIngest(int nBytes);
362
    char **GetSiblingFiles();
363
    char **StealSiblingFiles();
364
    bool AreSiblingFilesLoaded() const;
365

366
    bool IsSingleAllowedDriver(const char *pszDriverName) const;
367

368
    /** Return whether the extension of the file is equal to pszExt, using
369
     * case-insensitive comparison.
370
     * @since 3.11 */
371
    inline bool IsExtensionEqualToCI(const char *pszExt) const
882,380✔
372
    {
373
        return EQUAL(osExtension.c_str(), pszExt);
882,380✔
374
    }
375

376
  private:
377
    CPL_DISALLOW_COPY_ASSIGN(GDALOpenInfo)
378
};
379

380
/* ******************************************************************** */
381
/*                             gdal::GCP                                */
382
/* ******************************************************************** */
383

384
namespace gdal
385
{
386
/** C++ wrapper over the C GDAL_GCP structure.
387
 *
388
 * It has the same binary layout, and thus a gdal::GCP pointer can be cast as a
389
 * GDAL_GCP pointer.
390
 *
391
 * @since 3.9
392
 */
393
class CPL_DLL GCP
394
{
395
  public:
396
    explicit GCP(const char *pszId = "", const char *pszInfo = "",
397
                 double dfPixel = 0, double dfLine = 0, double dfX = 0,
398
                 double dfY = 0, double dfZ = 0);
399
    ~GCP();
400
    GCP(const GCP &);
401
    explicit GCP(const GDAL_GCP &other);
402
    GCP &operator=(const GCP &);
403
    GCP(GCP &&);
404
    GCP &operator=(GCP &&);
405

406
    /** Returns the "id" member. */
407
    inline const char *Id() const
21,898✔
408
    {
409
        return gcp.pszId;
21,898✔
410
    }
411

412
    void SetId(const char *pszId);
413

414
    /** Returns the "info" member. */
415
    inline const char *Info() const
43,778✔
416
    {
417
        return gcp.pszInfo;
43,778✔
418
    }
419

420
    void SetInfo(const char *pszInfo);
421

422
    /** Returns the "pixel" member. */
423
    inline double Pixel() const
21,917✔
424
    {
425
        return gcp.dfGCPPixel;
21,917✔
426
    }
427

428
    /** Returns a reference to the "pixel" member. */
429
    inline double &Pixel()
24,725✔
430
    {
431
        return gcp.dfGCPPixel;
24,725✔
432
    }
433

434
    /** Returns the "line" member. */
435
    inline double Line() const
21,917✔
436
    {
437
        return gcp.dfGCPLine;
21,917✔
438
    }
439

440
    /** Returns a reference to the "line" member. */
441
    inline double &Line()
24,725✔
442
    {
443
        return gcp.dfGCPLine;
24,725✔
444
    }
445

446
    /** Returns the "X" member. */
447
    inline double X() const
21,917✔
448
    {
449
        return gcp.dfGCPX;
21,917✔
450
    }
451

452
    /** Returns a reference to the "X" member. */
453
    inline double &X()
24,651✔
454
    {
455
        return gcp.dfGCPX;
24,651✔
456
    }
457

458
    /** Returns the "Y" member. */
459
    inline double Y() const
21,917✔
460
    {
461
        return gcp.dfGCPY;
21,917✔
462
    }
463

464
    /** Returns a reference to the "Y" member. */
465
    inline double &Y()
24,651✔
466
    {
467
        return gcp.dfGCPY;
24,651✔
468
    }
469

470
    /** Returns the "Z" member. */
471
    inline double Z() const
43,745✔
472
    {
473
        return gcp.dfGCPZ;
43,745✔
474
    }
475

476
    /** Returns a reference to the "Z" member. */
477
    inline double &Z()
24,532✔
478
    {
479
        return gcp.dfGCPZ;
24,532✔
480
    }
481

482
    /** Casts as a C GDAL_GCP pointer */
483
    inline const GDAL_GCP *c_ptr() const
449✔
484
    {
485
        return &gcp;
449✔
486
    }
487

488
    static const GDAL_GCP *c_ptr(const std::vector<GCP> &asGCPs);
489

490
    static std::vector<GCP> fromC(const GDAL_GCP *pasGCPList, int nGCPCount);
491

492
  private:
493
    GDAL_GCP gcp;
494
};
495

496
} /* namespace gdal */
497

498
/* ******************************************************************** */
499
/*                             GDALGeoTransform                         */
500
/* ******************************************************************** */
501

502
/** Class that encapsulates a geotransform matrix.
503
 *
504
 * It contains 6 coefficients expressing an affine transformation from
505
 * (column, line) raster space to (X, Y) georeferenced space, such that
506
 *
507
 * \code{.c}
508
 *  X = xorig + column * xscale + line * xrot;
509
 *  Y = yorig + column * yrot   + line * yscale;
510
 * \endcode
511
 *
512
 * The default value is the identity transformation.
513
 *
514
 * @since 3.12
515
 */
516
struct GDALGeoTransform
517
{
518
    // NOTE to GDAL developers: do not reorder those coefficients!
519

520
    /** X value of the origin of the raster */
521
    double xorig = 0;
522

523
    /** X scale factor */
524
    double xscale = 1;
525

526
    /** X rotation factor */
527
    double xrot = 0;
528

529
    /** Y value of the origin of the raster */
530
    double yorig = 0;
531

532
    /** Y rotation factor */
533
    double yrot = 0;
534

535
    /** Y scale factor */
536
    double yscale = 1;
537

538
    /** Default constructor for an identity geotransformation matrix. */
539
    inline GDALGeoTransform() = default;
184,850✔
540

541
    /** Constructor from a array of 6 double */
542
    inline explicit GDALGeoTransform(const double coeffs[6])
93✔
543
    {
93✔
544
        static_assert(sizeof(GDALGeoTransform) == 6 * sizeof(double),
545
                      "Wrong size for GDALGeoTransform");
546
        xorig = coeffs[0];
93✔
547
        xscale = coeffs[1];
93✔
548
        xrot = coeffs[2];
93✔
549
        yorig = coeffs[3];
93✔
550
        yrot = coeffs[4];
93✔
551
        yscale = coeffs[5];
93✔
552
    }
93✔
553

554
    /** Constructor from 6 double values */
555
    inline GDALGeoTransform(double xorigIn, double xscaleIn, double xrotIn,
5,845✔
556
                            double yorigIn, double yrotIn, double yscaleIn)
557
    {
5,845✔
558
        xorig = xorigIn;
5,845✔
559
        xscale = xscaleIn;
5,845✔
560
        xrot = xrotIn;
5,845✔
561
        yorig = yorigIn;
5,845✔
562
        yrot = yrotIn;
5,845✔
563
        yscale = yscaleIn;
5,845✔
564
    }
5,845✔
565

566
    /** Element accessor. idx must be in [0,5] range */
567
    template <typename T> inline double operator[](T idx) const
13,533✔
568
    {
569
        return *(&xorig + idx);
13,533✔
570
    }
571

572
    /** Element accessor. idx must be in [0,5] range */
573
    template <typename T> inline double &operator[](T idx)
81,839,775✔
574
    {
575
        return *(&xorig + idx);
81,839,775✔
576
    }
577

578
    /** Equality test operator */
579
    inline bool operator==(const GDALGeoTransform &other) const
3,942✔
580
    {
581
        return xorig == other.xorig && xscale == other.xscale &&
2,894✔
582
               xrot == other.xrot && yorig == other.yorig &&
2,870✔
583
               yrot == other.yrot && yscale == other.yscale;
6,836✔
584
    }
585

586
    /** Inequality test operator */
587
    inline bool operator!=(const GDALGeoTransform &other) const
3,879✔
588
    {
589
        return !(operator==(other));
3,879✔
590
    }
591

592
    /** Cast to const double* */
593
    inline const double *data() const
641✔
594
    {
595
        return &xorig;
641✔
596
    }
597

598
    /** Cast to double* */
599
    inline double *data()
25,334✔
600
    {
601
        return &xorig;
25,334✔
602
    }
603

604
    /**
605
     * Apply GeoTransform to x/y coordinate.
606
     *
607
     * Applies the following computation, converting a (pixel, line) coordinate
608
     * into a georeferenced (geo_x, geo_y) location.
609
     * \code{.c}
610
     *  *pdfGeoX = padfGeoTransform[0] + dfPixel * padfGeoTransform[1]
611
     *                                 + dfLine  * padfGeoTransform[2];
612
     *  *pdfGeoY = padfGeoTransform[3] + dfPixel * padfGeoTransform[4]
613
     *                                 + dfLine  * padfGeoTransform[5];
614
     * \endcode
615
     *
616
     * @param dfPixel Input pixel position.
617
     * @param dfLine Input line position.
618
     * @param pdfGeoX output location where geo_x (easting/longitude)
619
     * location is placed.
620
     * @param pdfGeoY output location where geo_y (northing/latitude)
621
     * location is placed.
622
     */
623

624
    inline void Apply(double dfPixel, double dfLine, double *pdfGeoX,
480✔
625
                      double *pdfGeoY) const
626
    {
627
        GDALApplyGeoTransform(data(), dfPixel, dfLine, pdfGeoX, pdfGeoY);
480✔
628
    }
480✔
629

630
    /**
631
     * Invert Geotransform.
632
     *
633
     * This function will invert a standard 3x2 set of GeoTransform coefficients.
634
     * This converts the equation from being pixel to geo to being geo to pixel.
635
     *
636
     * @param[out] inverse Output geotransform
637
     *
638
     * @return true on success or false if the equation is uninvertable.
639
     */
640
    inline bool GetInverse(GDALGeoTransform &inverse) const
161✔
641
    {
642
        return GDALInvGeoTransform(data(), inverse.data()) == TRUE;
161✔
643
    }
644

645
    /** Rescale a geotransform by multiplying its scale and rotation terms by
646
     * the provided ratios.
647
     *
648
     * This is typically used to compute the geotransform matrix of an overview
649
     * dataset from the full resolution dataset, where the ratios are the size
650
     * of the full resolution dataset divided by the size of the overview.
651
     */
652
    inline void Rescale(double dfXRatio, double dfYRatio)
1,780✔
653
    {
654
        xscale *= dfXRatio;
1,780✔
655
        xrot *= dfYRatio;
1,780✔
656
        yrot *= dfXRatio;
1,780✔
657
        yscale *= dfYRatio;
1,780✔
658
    }
1,780✔
659
};
660

661
/* ******************************************************************** */
662
/*                             GDALDataset                              */
663
/* ******************************************************************** */
664

665
class OGRLayer;
666
class OGRGeometry;
667
class OGRSpatialReference;
668
class OGRStyleTable;
669
class swq_select;
670
class swq_select_parse_options;
671
class GDALGroup;
672

673
//! @cond Doxygen_Suppress
674
typedef struct GDALSQLParseInfo GDALSQLParseInfo;
675
//! @endcond
676

677
//! @cond Doxygen_Suppress
678
#ifdef GDAL_COMPILATION
679
#define OPTIONAL_OUTSIDE_GDAL(val)
680
#else
681
#define OPTIONAL_OUTSIDE_GDAL(val) = val
682
#endif
683
//! @endcond
684

685
//! @cond Doxygen_Suppress
686
// This macro can be defined to check that GDALDataset::IRasterIO()
687
// implementations do not alter the passed panBandList. It is not defined
688
// by default (and should not!), hence int* is used.
689
#if defined(GDAL_BANDMAP_TYPE_CONST_SAFE)
690
#define BANDMAP_TYPE const int *
691
#else
692
#define BANDMAP_TYPE int *
693
#endif
694
//! @endcond
695

696
/** A set of associated raster bands, usually from one file. */
697
class CPL_DLL GDALDataset : public GDALMajorObject
698
{
699
    friend GDALDatasetH CPL_STDCALL
700
    GDALOpenEx(const char *pszFilename, unsigned int nOpenFlags,
701
               const char *const *papszAllowedDrivers,
702
               const char *const *papszOpenOptions,
703
               const char *const *papszSiblingFiles);
704
    friend CPLErr CPL_STDCALL GDALClose(GDALDatasetH hDS);
705

706
    friend class GDALDriver;
707
    friend class GDALDefaultOverviews;
708
    friend class GDALProxyDataset;
709
    friend class GDALDriverManager;
710

711
    CPL_INTERNAL void AddToDatasetOpenList();
712

713
    CPL_INTERNAL void UnregisterFromSharedDataset();
714

715
    CPL_INTERNAL static void ReportErrorV(const char *pszDSName,
716
                                          CPLErr eErrClass, CPLErrorNum err_no,
717
                                          const char *fmt, va_list args);
718

719
  protected:
720
    //! @cond Doxygen_Suppress
721
    GDALDriver *poDriver = nullptr;
722
    GDALAccess eAccess = GA_ReadOnly;
723

724
    // Stored raster information.
725
    int nRasterXSize = 512;
726
    int nRasterYSize = 512;
727
    int nBands = 0;
728
    GDALRasterBand **papoBands = nullptr;
729

730
    static constexpr int OPEN_FLAGS_CLOSED = -1;
731
    int nOpenFlags =
732
        0;  // set to OPEN_FLAGS_CLOSED after Close() has been called
733

734
    int nRefCount = 1;
735
    bool bForceCachedIO = false;
736
    bool bShared = false;
737
    bool bIsInternal = true;
738
    bool bSuppressOnClose = false;
739

740
    mutable std::map<std::string, std::unique_ptr<OGRFieldDomain>>
741
        m_oMapFieldDomains{};
742

743
    GDALDataset(void);
744
    explicit GDALDataset(int bForceCachedIO);
745

746
    void RasterInitialize(int, int);
747
    void SetBand(int nNewBand, GDALRasterBand *poBand);
748
    void SetBand(int nNewBand, std::unique_ptr<GDALRasterBand> poBand);
749

750
    GDALDefaultOverviews oOvManager{};
751

752
    virtual CPLErr IBuildOverviews(const char *pszResampling, int nOverviews,
753
                                   const int *panOverviewList, int nListBands,
754
                                   const int *panBandList,
755
                                   GDALProgressFunc pfnProgress,
756
                                   void *pProgressData,
757
                                   CSLConstList papszOptions);
758

759
    virtual CPLErr
760
    IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize,
761
              void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType,
762
              int nBandCount, BANDMAP_TYPE panBandMap, GSpacing nPixelSpace,
763
              GSpacing nLineSpace, GSpacing nBandSpace,
764
              GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
765

766
    /* This method should only be be overloaded by GDALProxyDataset */
767
    virtual CPLErr
768
    BlockBasedRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
769
                       int nYSize, void *pData, int nBufXSize, int nBufYSize,
770
                       GDALDataType eBufType, int nBandCount,
771
                       const int *panBandMap, GSpacing nPixelSpace,
772
                       GSpacing nLineSpace, GSpacing nBandSpace,
773
                       GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
774
    CPLErr BlockBasedFlushCache(bool bAtClosing);
775

776
    CPLErr
777
    BandBasedRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
778
                      int nYSize, void *pData, int nBufXSize, int nBufYSize,
779
                      GDALDataType eBufType, int nBandCount,
780
                      const int *panBandMap, GSpacing nPixelSpace,
781
                      GSpacing nLineSpace, GSpacing nBandSpace,
782
                      GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
783

784
    CPLErr
785
    RasterIOResampled(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
786
                      int nYSize, void *pData, int nBufXSize, int nBufYSize,
787
                      GDALDataType eBufType, int nBandCount,
788
                      const int *panBandMap, GSpacing nPixelSpace,
789
                      GSpacing nLineSpace, GSpacing nBandSpace,
790
                      GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
791

792
    CPLErr ValidateRasterIOOrAdviseReadParameters(
793
        const char *pszCallingFunc, int *pbStopProcessingOnCENone, int nXOff,
794
        int nYOff, int nXSize, int nYSize, int nBufXSize, int nBufYSize,
795
        int nBandCount, const int *panBandMap);
796

797
    CPLErr TryOverviewRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
798
                               int nXSize, int nYSize, void *pData,
799
                               int nBufXSize, int nBufYSize,
800
                               GDALDataType eBufType, int nBandCount,
801
                               const int *panBandMap, GSpacing nPixelSpace,
802
                               GSpacing nLineSpace, GSpacing nBandSpace,
803
                               GDALRasterIOExtraArg *psExtraArg, int *pbTried);
804

805
    void ShareLockWithParentDataset(GDALDataset *poParentDataset);
806

807
    bool m_bCanBeReopened = false;
808

809
    virtual bool CanBeCloned(int nScopeFlags, bool bCanShareState) const;
810

811
    friend class GDALThreadSafeDataset;
812
    friend class MEMDataset;
813
    virtual std::unique_ptr<GDALDataset> Clone(int nScopeFlags,
814
                                               bool bCanShareState) const;
815

816
    //! @endcond
817

818
    void CleanupPostFileClosing();
819

820
    virtual int CloseDependentDatasets();
821
    //! @cond Doxygen_Suppress
822
    int ValidateLayerCreationOptions(const char *const *papszLCO);
823

824
    char **papszOpenOptions = nullptr;
825

826
    friend class GDALRasterBand;
827

828
    // The below methods related to read write mutex are fragile logic, and
829
    // should not be used by out-of-tree code if possible.
830
    int EnterReadWrite(GDALRWFlag eRWFlag);
831
    void LeaveReadWrite();
832
    void InitRWLock();
833

834
    void TemporarilyDropReadWriteLock();
835
    void ReacquireReadWriteLock();
836

837
    void DisableReadWriteMutex();
838

839
    int AcquireMutex();
840
    void ReleaseMutex();
841

842
    bool IsAllBands(int nBandCount, const int *panBandList) const;
843
    //! @endcond
844

845
  public:
846
    ~GDALDataset() override;
847

848
    virtual CPLErr Close();
849

850
    int GetRasterXSize() const;
851
    int GetRasterYSize() const;
852
    int GetRasterCount() const;
853
    GDALRasterBand *GetRasterBand(int);
854
    const GDALRasterBand *GetRasterBand(int) const;
855

856
    /**
857
     * @brief SetQueryLoggerFunc
858
     * @param pfnQueryLoggerFuncIn query logger function callback
859
     * @param poQueryLoggerArgIn arguments passed to the query logger function
860
     * @return true on success
861
     */
862
    virtual bool SetQueryLoggerFunc(GDALQueryLoggerFunc pfnQueryLoggerFuncIn,
863
                                    void *poQueryLoggerArgIn);
864

865
    /** Class returned by GetBands() that act as a container for raster bands.
866
     */
867
    class CPL_DLL Bands
868
    {
869
      private:
870
        friend class GDALDataset;
871
        GDALDataset *m_poSelf;
872

873
        CPL_INTERNAL explicit Bands(GDALDataset *poSelf) : m_poSelf(poSelf)
7✔
874
        {
875
        }
7✔
876

877
        class CPL_DLL Iterator
6✔
878
        {
879
            struct Private;
880
            std::unique_ptr<Private> m_poPrivate;
881

882
          public:
883
            Iterator(GDALDataset *poDS, bool bStart);
884
            Iterator(const Iterator &oOther);  // declared but not defined.
885
                                               // Needed for gcc 5.4 at least
886
            Iterator(Iterator &&oOther) noexcept;  // declared but not defined.
887
                // Needed for gcc 5.4 at least
888
            ~Iterator();
889
            GDALRasterBand *operator*();
890
            Iterator &operator++();
891
            bool operator!=(const Iterator &it) const;
892
        };
893

894
      public:
895
        const Iterator begin() const;
896

897
        const Iterator end() const;
898

899
        size_t size() const;
900

901
        GDALRasterBand *operator[](int iBand);
902
        GDALRasterBand *operator[](size_t iBand);
903
    };
904

905
    Bands GetBands();
906

907
    virtual CPLErr FlushCache(bool bAtClosing = false);
908
    virtual CPLErr DropCache();
909

910
    virtual GIntBig GetEstimatedRAMUsage();
911

912
    virtual const OGRSpatialReference *GetSpatialRef() const;
913
    virtual CPLErr SetSpatialRef(const OGRSpatialReference *poSRS);
914

915
    // Compatibility layer
916
    const char *GetProjectionRef(void) const;
917
    CPLErr SetProjection(const char *pszProjection);
918

919
    virtual CPLErr GetGeoTransform(GDALGeoTransform &gt) const;
920
    virtual CPLErr SetGeoTransform(const GDALGeoTransform &gt);
921

922
    CPLErr GetGeoTransform(double *padfGeoTransform) const
923
#if defined(GDAL_COMPILATION) && !defined(DOXYGEN_XML)
924
        CPL_WARN_DEPRECATED("Use GetGeoTransform(GDALGeoTransform&) instead")
925
#endif
926
            ;
927

928
    CPLErr SetGeoTransform(const double *padfGeoTransform)
929
#if defined(GDAL_COMPILATION) && !defined(DOXYGEN_XML)
930
        CPL_WARN_DEPRECATED(
931
            "Use SetGeoTransform(const GDALGeoTransform&) instead")
932
#endif
933
            ;
934

935
    virtual CPLErr GetExtent(OGREnvelope *psExtent,
936
                             const OGRSpatialReference *poCRS = nullptr) const;
937
    virtual CPLErr GetExtentWGS84LongLat(OGREnvelope *psExtent) const;
938

939
    CPLErr GeolocationToPixelLine(
940
        double dfGeolocX, double dfGeolocY, const OGRSpatialReference *poSRS,
941
        double *pdfPixel, double *pdfLine,
942
        CSLConstList papszTransformerOptions = nullptr) const;
943

944
    virtual CPLErr AddBand(GDALDataType eType, char **papszOptions = nullptr);
945

946
    virtual void *GetInternalHandle(const char *pszHandleName);
947
    virtual GDALDriver *GetDriver(void);
948
    virtual char **GetFileList(void);
949

950
    virtual const char *GetDriverName();
951

952
    virtual const OGRSpatialReference *GetGCPSpatialRef() const;
953
    virtual int GetGCPCount();
954
    virtual const GDAL_GCP *GetGCPs();
955
    virtual CPLErr SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList,
956
                           const OGRSpatialReference *poGCP_SRS);
957

958
    // Compatibility layer
959
    const char *GetGCPProjection();
960
    CPLErr SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList,
961
                   const char *pszGCPProjection);
962

963
    virtual CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize,
964
                              int nBufXSize, int nBufYSize, GDALDataType eDT,
965
                              int nBandCount, int *panBandList,
966
                              char **papszOptions);
967

968
    virtual CPLErr CreateMaskBand(int nFlagsIn);
969

970
    virtual GDALAsyncReader *
971
    BeginAsyncReader(int nXOff, int nYOff, int nXSize, int nYSize, void *pBuf,
972
                     int nBufXSize, int nBufYSize, GDALDataType eBufType,
973
                     int nBandCount, int *panBandMap, int nPixelSpace,
974
                     int nLineSpace, int nBandSpace, char **papszOptions);
975
    virtual void EndAsyncReader(GDALAsyncReader *poARIO);
976

977
    //! @cond Doxygen_Suppress
978
    struct RawBinaryLayout
979
    {
980
        enum class Interleaving
981
        {
982
            UNKNOWN,
983
            BIP,
984
            BIL,
985
            BSQ
986
        };
987
        std::string osRawFilename{};
988
        Interleaving eInterleaving = Interleaving::UNKNOWN;
989
        GDALDataType eDataType = GDT_Unknown;
990
        bool bLittleEndianOrder = false;
991

992
        vsi_l_offset nImageOffset = 0;
993
        GIntBig nPixelOffset = 0;
994
        GIntBig nLineOffset = 0;
995
        GIntBig nBandOffset = 0;
996
    };
997

998
    virtual bool GetRawBinaryLayout(RawBinaryLayout &);
999
    //! @endcond
1000

1001
#ifndef DOXYGEN_SKIP
1002
    CPLErr RasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1003
                    int nYSize, void *pData, int nBufXSize, int nBufYSize,
1004
                    GDALDataType eBufType, int nBandCount,
1005
                    const int *panBandMap, GSpacing nPixelSpace,
1006
                    GSpacing nLineSpace, GSpacing nBandSpace,
1007
                    GDALRasterIOExtraArg *psExtraArg
1008
                        OPTIONAL_OUTSIDE_GDAL(nullptr)) CPL_WARN_UNUSED_RESULT;
1009
#else
1010
    CPLErr RasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1011
                    int nYSize, void *pData, int nBufXSize, int nBufYSize,
1012
                    GDALDataType eBufType, int nBandCount,
1013
                    const int *panBandMap, GSpacing nPixelSpace,
1014
                    GSpacing nLineSpace, GSpacing nBandSpace,
1015
                    GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
1016
#endif
1017

1018
    virtual CPLStringList GetCompressionFormats(int nXOff, int nYOff,
1019
                                                int nXSize, int nYSize,
1020
                                                int nBandCount,
1021
                                                const int *panBandList);
1022
    virtual CPLErr ReadCompressedData(const char *pszFormat, int nXOff,
1023
                                      int nYOff, int nXSize, int nYSize,
1024
                                      int nBands, const int *panBandList,
1025
                                      void **ppBuffer, size_t *pnBufferSize,
1026
                                      char **ppszDetailedFormat);
1027

1028
    int Reference();
1029
    int Dereference();
1030
    int ReleaseRef();
1031

1032
    /** Return access mode.
1033
     * @return access mode.
1034
     */
1035
    GDALAccess GetAccess() const
190,294✔
1036
    {
1037
        return eAccess;
190,294✔
1038
    }
1039

1040
    int GetShared() const;
1041
    void MarkAsShared();
1042

1043
    void MarkSuppressOnClose();
1044
    void UnMarkSuppressOnClose();
1045

1046
    /** Return MarkSuppressOnClose flag.
1047
    * @return MarkSuppressOnClose flag.
1048
    */
1049
    bool IsMarkedSuppressOnClose() const
5,757,518✔
1050
    {
1051
        return bSuppressOnClose;
5,757,518✔
1052
    }
1053

1054
    /** Return open options.
1055
     * @return open options.
1056
     */
1057
    char **GetOpenOptions()
142,710✔
1058
    {
1059
        return papszOpenOptions;
142,710✔
1060
    }
1061

1062
    bool IsThreadSafe(int nScopeFlags) const;
1063

1064
#ifndef DOXYGEN_SKIP
1065
    /** Return open options.
1066
     * @return open options.
1067
     */
1068
    CSLConstList GetOpenOptions() const
7✔
1069
    {
1070
        return papszOpenOptions;
7✔
1071
    }
1072
#endif
1073

1074
    static GDALDataset **GetOpenDatasets(int *pnDatasetCount);
1075

1076
#ifndef DOXYGEN_SKIP
1077
    CPLErr
1078
    BuildOverviews(const char *pszResampling, int nOverviews,
1079
                   const int *panOverviewList, int nListBands,
1080
                   const int *panBandList, GDALProgressFunc pfnProgress,
1081
                   void *pProgressData,
1082
                   CSLConstList papszOptions OPTIONAL_OUTSIDE_GDAL(nullptr));
1083
#else
1084
    CPLErr BuildOverviews(const char *pszResampling, int nOverviews,
1085
                          const int *panOverviewList, int nListBands,
1086
                          const int *panBandList, GDALProgressFunc pfnProgress,
1087
                          void *pProgressData, CSLConstList papszOptions);
1088
#endif
1089

1090
#ifndef DOXYGEN_XML
1091
    void ReportError(CPLErr eErrClass, CPLErrorNum err_no, const char *fmt,
1092
                     ...) const CPL_PRINT_FUNC_FORMAT(4, 5);
1093

1094
    static void ReportError(const char *pszDSName, CPLErr eErrClass,
1095
                            CPLErrorNum err_no, const char *fmt, ...)
1096
        CPL_PRINT_FUNC_FORMAT(4, 5);
1097
#endif
1098

1099
    char **GetMetadata(const char *pszDomain = "") override;
1100

1101
// Only defined when Doxygen enabled
1102
#ifdef DOXYGEN_SKIP
1103
    CPLErr SetMetadata(char **papszMetadata, const char *pszDomain) override;
1104
    CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
1105
                           const char *pszDomain) override;
1106
#endif
1107

1108
    char **GetMetadataDomainList() override;
1109

1110
    virtual void ClearStatistics();
1111

1112
    /** Convert a GDALDataset* to a GDALDatasetH.
1113
     * @since GDAL 2.3
1114
     */
1115
    static inline GDALDatasetH ToHandle(GDALDataset *poDS)
30,160✔
1116
    {
1117
        return static_cast<GDALDatasetH>(poDS);
30,160✔
1118
    }
1119

1120
    /** Convert a GDALDatasetH to a GDALDataset*.
1121
     * @since GDAL 2.3
1122
     */
1123
    static inline GDALDataset *FromHandle(GDALDatasetH hDS)
1,498,736✔
1124
    {
1125
        return static_cast<GDALDataset *>(hDS);
1,498,736✔
1126
    }
1127

1128
    /** @see GDALOpenEx().
1129
     * @since GDAL 2.3
1130
     */
1131
    static GDALDataset *Open(const char *pszFilename,
29,128✔
1132
                             unsigned int nOpenFlags = 0,
1133
                             const char *const *papszAllowedDrivers = nullptr,
1134
                             const char *const *papszOpenOptions = nullptr,
1135
                             const char *const *papszSiblingFiles = nullptr)
1136
    {
1137
        return FromHandle(GDALOpenEx(pszFilename, nOpenFlags,
29,128✔
1138
                                     papszAllowedDrivers, papszOpenOptions,
1139
                                     papszSiblingFiles));
29,117✔
1140
    }
1141

1142
    /** Object returned by GetFeatures() iterators */
1143
    struct FeatureLayerPair
1144
    {
1145
        /** Unique pointer to a OGRFeature. */
1146
        OGRFeatureUniquePtr feature{};
1147

1148
        /** Layer to which the feature belongs to. */
1149
        OGRLayer *layer = nullptr;
1150
    };
1151

1152
    //! @cond Doxygen_Suppress
1153
    // SetEnableOverviews() only to be used by GDALOverviewDataset
1154
    void SetEnableOverviews(bool bEnable);
1155

1156
    // Only to be used by driver's GetOverviewCount() method.
1157
    bool AreOverviewsEnabled() const;
1158

1159
    static void ReportUpdateNotSupportedByDriver(const char *pszDriverName);
1160
    //! @endcond
1161

1162
  private:
1163
    class Private;
1164
    Private *m_poPrivate;
1165

1166
    CPL_INTERNAL OGRLayer *BuildLayerFromSelectInfo(
1167
        swq_select *psSelectInfo, OGRGeometry *poSpatialFilter,
1168
        const char *pszDialect, swq_select_parse_options *poSelectParseOptions);
1169
    CPLStringList oDerivedMetadataList{};
1170

1171
  public:
1172
    virtual int GetLayerCount();
1173
    virtual OGRLayer *GetLayer(int iLayer);
1174

1175
    virtual bool IsLayerPrivate(int iLayer) const;
1176

1177
    /** Class returned by GetLayers() that acts as a range of layers.
1178
     * @since GDAL 2.3
1179
     */
1180
    class CPL_DLL Layers
1181
    {
1182
      private:
1183
        friend class GDALDataset;
1184
        GDALDataset *m_poSelf;
1185

1186
        CPL_INTERNAL explicit Layers(GDALDataset *poSelf) : m_poSelf(poSelf)
208✔
1187
        {
1188
        }
208✔
1189

1190
      public:
1191
        /** Layer iterator.
1192
         * @since GDAL 2.3
1193
         */
1194
        class CPL_DLL Iterator
426✔
1195
        {
1196
            struct Private;
1197
            std::unique_ptr<Private> m_poPrivate;
1198

1199
          public:
1200
            using value_type = OGRLayer *; /**< value_type */
1201
            using reference = OGRLayer *;  /**< reference */
1202
            using difference_type = void;  /**< difference_type */
1203
            using pointer = void;          /**< pointer */
1204
            using iterator_category =
1205
                std::input_iterator_tag; /**< iterator_category */
1206

1207
            Iterator(); /**< Default constructor */
1208
            Iterator(GDALDataset *poDS, bool bStart); /**< Constructor */
1209
            Iterator(const Iterator &oOther);         /**< Copy constructor */
1210
            Iterator(Iterator &&oOther) noexcept;     /**< Move constructor */
1211
            ~Iterator();                              /**< Destructor */
1212

1213
            Iterator &
1214
            operator=(const Iterator &oOther); /**< Assignment operator */
1215
            Iterator &operator=(
1216
                Iterator &&oOther) noexcept; /**< Move assignment operator */
1217

1218
            OGRLayer *operator*() const; /**< Dereference operator */
1219
            Iterator &operator++();      /**< Pre-increment operator */
1220
            Iterator operator++(int);    /**< Post-increment operator */
1221
            bool operator!=(const Iterator &it)
1222
                const; /**< Difference comparison operator */
1223
        };
1224

1225
        Iterator begin() const;
1226
        Iterator end() const;
1227

1228
        size_t size() const;
1229

1230
        OGRLayer *operator[](int iLayer);
1231
        OGRLayer *operator[](size_t iLayer);
1232
        OGRLayer *operator[](const char *pszLayername);
1233
    };
1234

1235
    Layers GetLayers();
1236

1237
    virtual OGRLayer *GetLayerByName(const char *);
1238

1239
    int GetLayerIndex(const char *pszName);
1240

1241
    virtual OGRErr DeleteLayer(int iLayer);
1242

1243
    virtual void ResetReading();
1244
    virtual OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer,
1245
                                       double *pdfProgressPct,
1246
                                       GDALProgressFunc pfnProgress,
1247
                                       void *pProgressData);
1248

1249
    /** Class returned by GetFeatures() that act as a container for vector
1250
     * features. */
1251
    class CPL_DLL Features
1252
    {
1253
      private:
1254
        friend class GDALDataset;
1255
        GDALDataset *m_poSelf;
1256

1257
        CPL_INTERNAL explicit Features(GDALDataset *poSelf) : m_poSelf(poSelf)
2✔
1258
        {
1259
        }
2✔
1260

1261
        class CPL_DLL Iterator
4✔
1262
        {
1263
            struct Private;
1264
            std::unique_ptr<Private> m_poPrivate;
1265

1266
          public:
1267
            Iterator(GDALDataset *poDS, bool bStart);
1268
            Iterator(const Iterator &oOther);  // declared but not defined.
1269
                                               // Needed for gcc 5.4 at least
1270
            Iterator(Iterator &&oOther) noexcept;  // declared but not defined.
1271
                // Needed for gcc 5.4 at least
1272
            ~Iterator();
1273
            const FeatureLayerPair &operator*() const;
1274
            Iterator &operator++();
1275
            bool operator!=(const Iterator &it) const;
1276
        };
1277

1278
      public:
1279
        const Iterator begin() const;
1280

1281
        const Iterator end() const;
1282
    };
1283

1284
    Features GetFeatures();
1285

1286
    virtual int TestCapability(const char *);
1287

1288
    virtual std::vector<std::string>
1289
    GetFieldDomainNames(CSLConstList papszOptions = nullptr) const;
1290

1291
    virtual const OGRFieldDomain *GetFieldDomain(const std::string &name) const;
1292

1293
    virtual bool AddFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
1294
                                std::string &failureReason);
1295

1296
    virtual bool DeleteFieldDomain(const std::string &name,
1297
                                   std::string &failureReason);
1298

1299
    virtual bool UpdateFieldDomain(std::unique_ptr<OGRFieldDomain> &&domain,
1300
                                   std::string &failureReason);
1301

1302
    virtual std::vector<std::string>
1303
    GetRelationshipNames(CSLConstList papszOptions = nullptr) const;
1304

1305
    virtual const GDALRelationship *
1306
    GetRelationship(const std::string &name) const;
1307

1308
    virtual bool
1309
    AddRelationship(std::unique_ptr<GDALRelationship> &&relationship,
1310
                    std::string &failureReason);
1311

1312
    virtual bool DeleteRelationship(const std::string &name,
1313
                                    std::string &failureReason);
1314

1315
    virtual bool
1316
    UpdateRelationship(std::unique_ptr<GDALRelationship> &&relationship,
1317
                       std::string &failureReason);
1318

1319
    //! @cond Doxygen_Suppress
1320
    OGRLayer *CreateLayer(const char *pszName);
1321

1322
    OGRLayer *CreateLayer(const char *pszName, std::nullptr_t);
1323
    //! @endcond
1324

1325
    OGRLayer *CreateLayer(const char *pszName,
1326
                          const OGRSpatialReference *poSpatialRef,
1327
                          OGRwkbGeometryType eGType = wkbUnknown,
1328
                          CSLConstList papszOptions = nullptr);
1329

1330
    OGRLayer *CreateLayer(const char *pszName,
1331
                          const OGRGeomFieldDefn *poGeomFieldDefn,
1332
                          CSLConstList papszOptions = nullptr);
1333

1334
    virtual OGRLayer *CopyLayer(OGRLayer *poSrcLayer, const char *pszNewName,
1335
                                char **papszOptions = nullptr);
1336

1337
    virtual OGRStyleTable *GetStyleTable();
1338
    virtual void SetStyleTableDirectly(OGRStyleTable *poStyleTable);
1339

1340
    virtual void SetStyleTable(OGRStyleTable *poStyleTable);
1341

1342
    virtual OGRLayer *ExecuteSQL(const char *pszStatement,
1343
                                 OGRGeometry *poSpatialFilter,
1344
                                 const char *pszDialect);
1345
    virtual void ReleaseResultSet(OGRLayer *poResultsSet);
1346
    virtual OGRErr AbortSQL();
1347

1348
    int GetRefCount() const;
1349
    int GetSummaryRefCount() const;
1350
    OGRErr Release();
1351

1352
    virtual OGRErr StartTransaction(int bForce = FALSE);
1353
    virtual OGRErr CommitTransaction();
1354
    virtual OGRErr RollbackTransaction();
1355

1356
    virtual std::shared_ptr<GDALGroup> GetRootGroup() const;
1357

1358
    static std::string BuildFilename(const char *pszFilename,
1359
                                     const char *pszReferencePath,
1360
                                     bool bRelativeToReferencePath);
1361

1362
    //! @cond Doxygen_Suppress
1363
    static int IsGenericSQLDialect(const char *pszDialect);
1364

1365
    // Semi-public methods. Only to be used by in-tree drivers.
1366
    GDALSQLParseInfo *
1367
    BuildParseInfo(swq_select *psSelectInfo,
1368
                   swq_select_parse_options *poSelectParseOptions);
1369
    static void DestroyParseInfo(GDALSQLParseInfo *psParseInfo);
1370
    OGRLayer *ExecuteSQL(const char *pszStatement, OGRGeometry *poSpatialFilter,
1371
                         const char *pszDialect,
1372
                         swq_select_parse_options *poSelectParseOptions);
1373

1374
    static constexpr const char *const apszSpecialSubDatasetSyntax[] = {
1375
        "NITF_IM:{ANY}:{FILENAME}", "PDF:{ANY}:{FILENAME}",
1376
        "RASTERLITE:{FILENAME},{ANY}", "TILEDB:\"{FILENAME}\":{ANY}",
1377
        "TILEDB:{FILENAME}:{ANY}"};
1378

1379
    //! @endcond
1380

1381
  protected:
1382
    virtual OGRLayer *ICreateLayer(const char *pszName,
1383
                                   const OGRGeomFieldDefn *poGeomFieldDefn,
1384
                                   CSLConstList papszOptions);
1385

1386
    //! @cond Doxygen_Suppress
1387
    OGRErr ProcessSQLCreateIndex(const char *);
1388
    OGRErr ProcessSQLDropIndex(const char *);
1389
    OGRErr ProcessSQLDropTable(const char *);
1390
    OGRErr ProcessSQLAlterTableAddColumn(const char *);
1391
    OGRErr ProcessSQLAlterTableDropColumn(const char *);
1392
    OGRErr ProcessSQLAlterTableAlterColumn(const char *);
1393
    OGRErr ProcessSQLAlterTableRenameColumn(const char *);
1394

1395
    OGRStyleTable *m_poStyleTable = nullptr;
1396

1397
    friend class GDALProxyPoolDataset;
1398
    //! @endcond
1399

1400
  private:
1401
    CPL_DISALLOW_COPY_ASSIGN(GDALDataset)
1402
};
1403

1404
//! @cond Doxygen_Suppress
1405
struct CPL_DLL GDALDatasetUniquePtrDeleter
1406
{
1407
    void operator()(GDALDataset *poDataset) const
74✔
1408
    {
1409
        GDALClose(poDataset);
74✔
1410
    }
74✔
1411
};
1412

1413
//! @endcond
1414

1415
//! @cond Doxygen_Suppress
1416
struct CPL_DLL GDALDatasetUniquePtrReleaser
1417
{
1418
    void operator()(GDALDataset *poDataset) const
1,599✔
1419
    {
1420
        if (poDataset)
1,599✔
1421
            poDataset->Release();
1,596✔
1422
    }
1,599✔
1423
};
1424

1425
//! @endcond
1426

1427
/** Unique pointer type for GDALDataset.
1428
 * Appropriate for use on datasets open in non-shared mode and onto which
1429
 * reference counter has not been manually modified.
1430
 * @since GDAL 2.3
1431
 */
1432
using GDALDatasetUniquePtr =
1433
    std::unique_ptr<GDALDataset, GDALDatasetUniquePtrDeleter>;
1434

1435
/* ******************************************************************** */
1436
/*                           GDALRasterBlock                            */
1437
/* ******************************************************************** */
1438

1439
/** A single raster block in the block cache.
1440
 *
1441
 * And the global block manager that manages a least-recently-used list of
1442
 * blocks from various datasets/bands */
1443
class CPL_DLL GDALRasterBlock
1444
{
1445
    friend class GDALAbstractBandBlockCache;
1446

1447
    GDALDataType eType;
1448

1449
    bool bDirty;
1450
    volatile int nLockCount;
1451

1452
    int nXOff;
1453
    int nYOff;
1454

1455
    int nXSize;
1456
    int nYSize;
1457

1458
    void *pData;
1459

1460
    GDALRasterBand *poBand;
1461

1462
    GDALRasterBlock *poNext;
1463
    GDALRasterBlock *poPrevious;
1464

1465
    bool bMustDetach;
1466

1467
    CPL_INTERNAL void Detach_unlocked(void);
1468
    CPL_INTERNAL void Touch_unlocked(void);
1469

1470
    CPL_INTERNAL void RecycleFor(int nXOffIn, int nYOffIn);
1471

1472
  public:
1473
    GDALRasterBlock(GDALRasterBand *, int, int);
1474
    GDALRasterBlock(int nXOffIn, int nYOffIn); /* only for lookup purpose */
1475
    virtual ~GDALRasterBlock();
1476

1477
    CPLErr Internalize(void);
1478
    void Touch(void);
1479
    void MarkDirty(void);
1480
    void MarkClean(void);
1481

1482
    /** Increment the lock count */
1483
    int AddLock(void)
10,508,400✔
1484
    {
1485
        return CPLAtomicInc(&nLockCount);
10,508,400✔
1486
    }
1487

1488
    /** Decrement the lock count */
1489
    int DropLock(void)
10,509,173✔
1490
    {
1491
        return CPLAtomicDec(&nLockCount);
10,509,173✔
1492
    }
1493

1494
    void Detach();
1495

1496
    CPLErr Write();
1497

1498
    /** Return the data type
1499
     * @return data type
1500
     */
1501
    GDALDataType GetDataType() const
19,542✔
1502
    {
1503
        return eType;
19,542✔
1504
    }
1505

1506
    /** Return the x offset of the top-left corner of the block
1507
     * @return x offset
1508
     */
1509
    int GetXOff() const
12,324,900✔
1510
    {
1511
        return nXOff;
12,324,900✔
1512
    }
1513

1514
    /** Return the y offset of the top-left corner of the block
1515
     * @return y offset
1516
     */
1517
    int GetYOff() const
483,163,000✔
1518
    {
1519
        return nYOff;
483,163,000✔
1520
    }
1521

1522
    /** Return the width of the block
1523
     * @return width
1524
     */
1525
    int GetXSize() const
1526
    {
1527
        return nXSize;
1528
    }
1529

1530
    /** Return the height of the block
1531
     * @return height
1532
     */
1533
    int GetYSize() const
1534
    {
1535
        return nYSize;
1536
    }
1537

1538
    /** Return the dirty flag
1539
     * @return dirty flag
1540
     */
1541
    int GetDirty() const
3,957,150✔
1542
    {
1543
        return bDirty;
3,957,150✔
1544
    }
1545

1546
    /** Return the data buffer
1547
     * @return data buffer
1548
     */
1549
    void *GetDataRef(void)
13,894,919✔
1550
    {
1551
        return pData;
13,894,919✔
1552
    }
1553

1554
    /** Return the block size in bytes
1555
     * @return block size.
1556
     */
1557
    GPtrDiff_t GetBlockSize() const
6,747,720✔
1558
    {
1559
        return static_cast<GPtrDiff_t>(nXSize) * nYSize *
6,747,720✔
1560
               GDALGetDataTypeSizeBytes(eType);
6,747,720✔
1561
    }
1562

1563
    int TakeLock();
1564
    int DropLockForRemovalFromStorage();
1565

1566
    /// @brief Accessor to source GDALRasterBand object.
1567
    /// @return source raster band of the raster block.
1568
    GDALRasterBand *GetBand()
59,306✔
1569
    {
1570
        return poBand;
59,306✔
1571
    }
1572

1573
    static void FlushDirtyBlocks();
1574
    static int FlushCacheBlock(int bDirtyBlocksOnly = FALSE);
1575
    static void Verify();
1576

1577
    static void EnterDisableDirtyBlockFlush();
1578
    static void LeaveDisableDirtyBlockFlush();
1579

1580
#ifdef notdef
1581
    static void CheckNonOrphanedBlocks(GDALRasterBand *poBand);
1582
    void DumpBlock();
1583
    static void DumpAll();
1584
#endif
1585

1586
    /* Should only be called by GDALDestroyDriverManager() */
1587
    //! @cond Doxygen_Suppress
1588
    CPL_INTERNAL static void DestroyRBMutex();
1589
    //! @endcond
1590

1591
  private:
1592
    CPL_DISALLOW_COPY_ASSIGN(GDALRasterBlock)
1593
};
1594

1595
/* ******************************************************************** */
1596
/*                             GDALColorTable                           */
1597
/* ******************************************************************** */
1598

1599
/** A color table / palette. */
1600

1601
class CPL_DLL GDALColorTable
2,117✔
1602
{
1603
    GDALPaletteInterp eInterp;
1604

1605
    std::vector<GDALColorEntry> aoEntries{};
1606

1607
  public:
1608
    explicit GDALColorTable(GDALPaletteInterp = GPI_RGB);
1609

1610
    /** Copy constructor */
1611
    GDALColorTable(const GDALColorTable &) = default;
285✔
1612

1613
    /** Copy assignment operator */
1614
    GDALColorTable &operator=(const GDALColorTable &) = default;
1615

1616
    /** Move constructor */
1617
    GDALColorTable(GDALColorTable &&) = default;
1618

1619
    /** Move assignment operator */
1620
    GDALColorTable &operator=(GDALColorTable &&) = default;
1621

1622
    ~GDALColorTable();
1623

1624
    GDALColorTable *Clone() const;
1625
    int IsSame(const GDALColorTable *poOtherCT) const;
1626

1627
    GDALPaletteInterp GetPaletteInterpretation() const;
1628

1629
    int GetColorEntryCount() const;
1630
    const GDALColorEntry *GetColorEntry(int i) const;
1631
    int GetColorEntryAsRGB(int i, GDALColorEntry *poEntry) const;
1632
    void SetColorEntry(int i, const GDALColorEntry *poEntry);
1633
    int CreateColorRamp(int nStartIndex, const GDALColorEntry *psStartColor,
1634
                        int nEndIndex, const GDALColorEntry *psEndColor);
1635
    bool IsIdentity() const;
1636

1637
    static std::unique_ptr<GDALColorTable>
1638
    LoadFromFile(const char *pszFilename);
1639

1640
    /** Convert a GDALColorTable* to a GDALRasterBandH.
1641
     * @since GDAL 2.3
1642
     */
1643
    static inline GDALColorTableH ToHandle(GDALColorTable *poCT)
1,981✔
1644
    {
1645
        return static_cast<GDALColorTableH>(poCT);
1,981✔
1646
    }
1647

1648
    /** Convert a GDALColorTableH to a GDALColorTable*.
1649
     * @since GDAL 2.3
1650
     */
1651
    static inline GDALColorTable *FromHandle(GDALColorTableH hCT)
22,075✔
1652
    {
1653
        return static_cast<GDALColorTable *>(hCT);
22,075✔
1654
    }
1655
};
1656

1657
/* ******************************************************************** */
1658
/*                       GDALAbstractBandBlockCache                     */
1659
/* ******************************************************************** */
1660

1661
//! @cond Doxygen_Suppress
1662

1663
//! This manages how a raster band store its cached block.
1664
// only used by GDALRasterBand implementation.
1665

1666
class GDALAbstractBandBlockCache
1667
{
1668
    // List of blocks that can be freed or recycled, and its lock
1669
    CPLLock *hSpinLock = nullptr;
1670
    GDALRasterBlock *psListBlocksToFree = nullptr;
1671

1672
    // Band keep alive counter, and its lock & condition
1673
    CPLCond *hCond = nullptr;
1674
    CPLMutex *hCondMutex = nullptr;
1675
    volatile int nKeepAliveCounter = 0;
1676

1677
    volatile int m_nDirtyBlocks = 0;
1678

1679
    CPL_DISALLOW_COPY_ASSIGN(GDALAbstractBandBlockCache)
1680

1681
  protected:
1682
    GDALRasterBand *poBand;
1683

1684
    int m_nInitialDirtyBlocksInFlushCache = 0;
1685
    int m_nLastTick = -1;
1686
    size_t m_nWriteDirtyBlocksDisabled = 0;
1687

1688
    void FreeDanglingBlocks();
1689
    void UnreferenceBlockBase();
1690

1691
    void StartDirtyBlockFlushingLog();
1692
    void UpdateDirtyBlockFlushingLog();
1693
    void EndDirtyBlockFlushingLog();
1694

1695
  public:
1696
    explicit GDALAbstractBandBlockCache(GDALRasterBand *poBand);
1697
    virtual ~GDALAbstractBandBlockCache();
1698

1699
    GDALRasterBlock *CreateBlock(int nXBlockOff, int nYBlockOff);
1700
    void AddBlockToFreeList(GDALRasterBlock *poBlock);
1701
    void IncDirtyBlocks(int nInc);
1702
    void WaitCompletionPendingTasks();
1703

1704
    void EnableDirtyBlockWriting()
1✔
1705
    {
1706
        --m_nWriteDirtyBlocksDisabled;
1✔
1707
    }
1✔
1708

1709
    void DisableDirtyBlockWriting()
2,973✔
1710
    {
1711
        ++m_nWriteDirtyBlocksDisabled;
2,973✔
1712
    }
2,973✔
1713

1714
    bool HasDirtyBlocks() const
×
1715
    {
1716
        return m_nDirtyBlocks > 0;
×
1717
    }
1718

1719
    virtual bool Init() = 0;
1720
    virtual bool IsInitOK() = 0;
1721
    virtual CPLErr FlushCache() = 0;
1722
    virtual CPLErr AdoptBlock(GDALRasterBlock *poBlock) = 0;
1723
    virtual GDALRasterBlock *TryGetLockedBlockRef(int nXBlockOff,
1724
                                                  int nYBlockYOff) = 0;
1725
    virtual CPLErr UnreferenceBlock(GDALRasterBlock *poBlock) = 0;
1726
    virtual CPLErr FlushBlock(int nXBlockOff, int nYBlockOff,
1727
                              int bWriteDirtyBlock) = 0;
1728
};
1729

1730
GDALAbstractBandBlockCache *
1731
GDALArrayBandBlockCacheCreate(GDALRasterBand *poBand);
1732
GDALAbstractBandBlockCache *
1733
GDALHashSetBandBlockCacheCreate(GDALRasterBand *poBand);
1734

1735
//! @endcond
1736

1737
/* ******************************************************************** */
1738
/*                            GDALRasterBand                            */
1739
/* ******************************************************************** */
1740

1741
class GDALMDArray;
1742
class GDALDoublePointsCache;
1743

1744
/** Range of values found in a mask band */
1745
typedef enum
1746
{
1747
    GMVR_UNKNOWN, /*! Unknown (can also be used for any values between 0 and 255
1748
                     for a Byte band) */
1749
    GMVR_0_AND_1_ONLY,   /*! Only 0 and 1 */
1750
    GMVR_0_AND_255_ONLY, /*! Only 0 and 255 */
1751
} GDALMaskValueRange;
1752

1753
/** Suggested/most efficient access pattern to blocks. */
1754
typedef int GDALSuggestedBlockAccessPattern;
1755

1756
/** Unknown, or no particular read order is suggested. */
1757
constexpr GDALSuggestedBlockAccessPattern GSBAP_UNKNOWN = 0;
1758

1759
/** Random access to blocks is efficient. */
1760
constexpr GDALSuggestedBlockAccessPattern GSBAP_RANDOM = 1;
1761

1762
/** Reading by strips from top to bottom is the most efficient. */
1763
constexpr GDALSuggestedBlockAccessPattern GSBAP_TOP_TO_BOTTOM = 2;
1764

1765
/** Reading by strips from bottom to top is the most efficient. */
1766
constexpr GDALSuggestedBlockAccessPattern GSBAP_BOTTOM_TO_TOP = 3;
1767

1768
/** Reading the largest chunk from the raster is the most efficient (can be
1769
 * combined with above values). */
1770
constexpr GDALSuggestedBlockAccessPattern GSBAP_LARGEST_CHUNK_POSSIBLE = 0x100;
1771

1772
class GDALComputedRasterBand;
1773

1774
/** A single raster band (or channel). */
1775

1776
class CPL_DLL GDALRasterBand : public GDALMajorObject
1777
{
1778
  private:
1779
    friend class GDALArrayBandBlockCache;
1780
    friend class GDALHashSetBandBlockCache;
1781
    friend class GDALRasterBlock;
1782
    friend class GDALDataset;
1783

1784
    CPLErr eFlushBlockErr = CE_None;
1785
    GDALAbstractBandBlockCache *poBandBlockCache = nullptr;
1786

1787
    CPL_INTERNAL void SetFlushBlockErr(CPLErr eErr);
1788
    CPL_INTERNAL CPLErr UnreferenceBlock(GDALRasterBlock *poBlock);
1789
    CPL_INTERNAL void IncDirtyBlocks(int nInc);
1790

1791
    CPL_INTERNAL CPLErr RasterIOInternal(
1792
        GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize,
1793
        void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType,
1794
        GSpacing nPixelSpace, GSpacing nLineSpace,
1795
        GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
1796

1797
  protected:
1798
    //! @cond Doxygen_Suppress
1799
    GDALDataset *poDS = nullptr;
1800
    int nBand = 0; /* 1 based */
1801

1802
    int nRasterXSize = 0;
1803
    int nRasterYSize = 0;
1804

1805
    GDALDataType eDataType = GDT_Byte;
1806
    GDALAccess eAccess = GA_ReadOnly;
1807

1808
    /* stuff related to blocking, and raster cache */
1809
    int nBlockXSize = -1;
1810
    int nBlockYSize = -1;
1811
    int nBlocksPerRow = 0;
1812
    int nBlocksPerColumn = 0;
1813

1814
    int nBlockReads = 0;
1815
    int bForceCachedIO = 0;
1816

1817
    friend class GDALComputedRasterBand;
1818
    friend class GDALComputedDataset;
1819

1820
    class GDALRasterBandOwnedOrNot
1821
    {
1822
      public:
1823
        GDALRasterBandOwnedOrNot() = default;
1,909,820✔
1824

1825
        GDALRasterBandOwnedOrNot(GDALRasterBandOwnedOrNot &&) = default;
1826

1827
        void reset()
1,910,000✔
1828
        {
1829
            m_poBandOwned.reset();
1,910,000✔
1830
            m_poBandRef = nullptr;
1,909,980✔
1831
        }
1,909,980✔
1832

1833
        void resetNotOwned(GDALRasterBand *poBand)
1,811✔
1834
        {
1835
            m_poBandOwned.reset();
1,811✔
1836
            m_poBandRef = poBand;
1,811✔
1837
        }
1,811✔
1838

1839
        void reset(std::unique_ptr<GDALRasterBand> poBand)
161,034✔
1840
        {
1841
            m_poBandOwned = std::move(poBand);
161,034✔
1842
            m_poBandRef = nullptr;
161,033✔
1843
        }
161,033✔
1844

1845
        const GDALRasterBand *get() const
2✔
1846
        {
1847
            return static_cast<const GDALRasterBand *>(*this);
2✔
1848
        }
1849

1850
        GDALRasterBand *get()
1,413,980✔
1851
        {
1852
            return static_cast<GDALRasterBand *>(*this);
1,413,980✔
1853
        }
1854

1855
        bool IsOwned() const
696,577✔
1856
        {
1857
            return m_poBandOwned != nullptr;
696,577✔
1858
        }
1859

1860
        operator const GDALRasterBand *() const
2✔
1861
        {
1862
            return m_poBandOwned ? m_poBandOwned.get() : m_poBandRef;
2✔
1863
        }
1864

1865
        operator GDALRasterBand *()
3,013,850✔
1866
        {
1867
            return m_poBandOwned ? m_poBandOwned.get() : m_poBandRef;
3,013,850✔
1868
        }
1869

1870
      private:
1871
        CPL_DISALLOW_COPY_ASSIGN(GDALRasterBandOwnedOrNot)
1872
        std::unique_ptr<GDALRasterBand> m_poBandOwned{};
1873
        GDALRasterBand *m_poBandRef = nullptr;
1874
    };
1875

1876
    GDALRasterBandOwnedOrNot poMask{};
1877
    bool m_bEnablePixelTypeSignedByteWarning =
1878
        true;  // Remove me in GDAL 4.0. See GetMetadataItem() implementation
1879
    int nMaskFlags = 0;
1880

1881
    void InvalidateMaskBand();
1882

1883
    friend class GDALProxyRasterBand;
1884
    friend class GDALDefaultOverviews;
1885

1886
    CPLErr
1887
    RasterIOResampled(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1888
                      int nYSize, void *pData, int nBufXSize, int nBufYSize,
1889
                      GDALDataType eBufType, GSpacing nPixelSpace,
1890
                      GSpacing nLineSpace,
1891
                      GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
1892

1893
    int EnterReadWrite(GDALRWFlag eRWFlag);
1894
    void LeaveReadWrite();
1895
    void InitRWLock();
1896
    void SetValidPercent(GUIntBig nSampleCount, GUIntBig nValidCount);
1897

1898
    mutable GDALDoublePointsCache *m_poPointsCache = nullptr;
1899

1900
    //! @endcond
1901

1902
  protected:
1903
    virtual CPLErr IReadBlock(int nBlockXOff, int nBlockYOff, void *pData) = 0;
1904
    virtual CPLErr IWriteBlock(int nBlockXOff, int nBlockYOff, void *pData);
1905

1906
    virtual CPLErr
1907
    IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize,
1908
              void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType,
1909
              GSpacing nPixelSpace, GSpacing nLineSpace,
1910
              GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
1911

1912
    virtual int IGetDataCoverageStatus(int nXOff, int nYOff, int nXSize,
1913
                                       int nYSize, int nMaskFlagStop,
1914
                                       double *pdfDataPct);
1915

1916
    virtual bool
1917
    EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const;
1918

1919
    //! @cond Doxygen_Suppress
1920
    CPLErr
1921
    OverviewRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1922
                     int nYSize, void *pData, int nBufXSize, int nBufYSize,
1923
                     GDALDataType eBufType, GSpacing nPixelSpace,
1924
                     GSpacing nLineSpace,
1925
                     GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
1926

1927
    CPLErr TryOverviewRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff,
1928
                               int nXSize, int nYSize, void *pData,
1929
                               int nBufXSize, int nBufYSize,
1930
                               GDALDataType eBufType, GSpacing nPixelSpace,
1931
                               GSpacing nLineSpace,
1932
                               GDALRasterIOExtraArg *psExtraArg, int *pbTried);
1933

1934
    CPLErr SplitRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1935
                         int nYSize, void *pData, int nBufXSize, int nBufYSize,
1936
                         GDALDataType eBufType, GSpacing nPixelSpace,
1937
                         GSpacing nLineSpace, GDALRasterIOExtraArg *psExtraArg)
1938
        CPL_WARN_UNUSED_RESULT;
1939

1940
    int InitBlockInfo();
1941

1942
    void AddBlockToFreeList(GDALRasterBlock *);
1943

1944
    bool HasBlockCache() const
2,296,640✔
1945
    {
1946
        return poBandBlockCache != nullptr;
2,296,640✔
1947
    }
1948

1949
    bool HasDirtyBlocks() const
17✔
1950
    {
1951
        return poBandBlockCache && poBandBlockCache->HasDirtyBlocks();
17✔
1952
    }
1953

1954
    //! @endcond
1955

1956
  public:
1957
    GDALRasterBand();
1958
    explicit GDALRasterBand(int bForceCachedIO);
1959

1960
    //! @cond Doxygen_Suppress
1961
    GDALRasterBand(GDALRasterBand &&) = default;
1962
    //! @endcond
1963

1964
    ~GDALRasterBand() override;
1965

1966
    int GetXSize() const;
1967
    int GetYSize() const;
1968
    int GetBand() const;
1969
    GDALDataset *GetDataset() const;
1970

1971
    GDALDataType GetRasterDataType(void) const;
1972
    void GetBlockSize(int *pnXSize, int *pnYSize) const;
1973
    CPLErr GetActualBlockSize(int nXBlockOff, int nYBlockOff, int *pnXValid,
1974
                              int *pnYValid) const;
1975

1976
    virtual GDALSuggestedBlockAccessPattern
1977
    GetSuggestedBlockAccessPattern() const;
1978

1979
    GDALAccess GetAccess();
1980

1981
#ifndef DOXYGEN_SKIP
1982
    CPLErr RasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1983
                    int nYSize, void *pData, int nBufXSize, int nBufYSize,
1984
                    GDALDataType eBufType, GSpacing nPixelSpace,
1985
                    GSpacing nLineSpace,
1986
                    GDALRasterIOExtraArg *psExtraArg
1987
                        OPTIONAL_OUTSIDE_GDAL(nullptr)) CPL_WARN_UNUSED_RESULT;
1988
#else
1989
    CPLErr RasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
1990
                    int nYSize, void *pData, int nBufXSize, int nBufYSize,
1991
                    GDALDataType eBufType, GSpacing nPixelSpace,
1992
                    GSpacing nLineSpace,
1993
                    GDALRasterIOExtraArg *psExtraArg) CPL_WARN_UNUSED_RESULT;
1994
#endif
1995

1996
    template <class T>
1997
    CPLErr ReadRaster(T *pData, size_t nArrayEltCount = 0, double dfXOff = 0,
1998
                      double dfYOff = 0, double dfXSize = 0, double dfYSize = 0,
1999
                      size_t nBufXSize = 0, size_t nBufYSize = 0,
2000
                      GDALRIOResampleAlg eResampleAlg = GRIORA_NearestNeighbour,
2001
                      GDALProgressFunc pfnProgress = nullptr,
2002
                      void *pProgressData = nullptr) const;
2003

2004
    template <class T>
2005
    CPLErr ReadRaster(std::vector<T> &vData, double dfXOff = 0,
2006
                      double dfYOff = 0, double dfXSize = 0, double dfYSize = 0,
2007
                      size_t nBufXSize = 0, size_t nBufYSize = 0,
2008
                      GDALRIOResampleAlg eResampleAlg = GRIORA_NearestNeighbour,
2009
                      GDALProgressFunc pfnProgress = nullptr,
2010
                      void *pProgressData = nullptr) const;
2011

2012
#if __cplusplus >= 202002L
2013
    //! @cond Doxygen_Suppress
2014
    template <class T>
2015
    inline CPLErr
2016
    ReadRaster(std::span<T> pData, double dfXOff = 0, double dfYOff = 0,
2017
               double dfXSize = 0, double dfYSize = 0, size_t nBufXSize = 0,
2018
               size_t nBufYSize = 0,
2019
               GDALRIOResampleAlg eResampleAlg = GRIORA_NearestNeighbour,
2020
               GDALProgressFunc pfnProgress = nullptr,
2021
               void *pProgressData = nullptr) const
2022
    {
2023
        return ReadRaster(pData.data(), pData.size(), dfXOff, dfYOff, dfXSize,
2024
                          dfYSize, nBufXSize, nBufYSize, eResampleAlg,
2025
                          pfnProgress, pProgressData);
2026
    }
2027

2028
    //! @endcond
2029
#endif
2030

2031
    GDALComputedRasterBand
2032
    operator+(const GDALRasterBand &other) const CPL_WARN_UNUSED_RESULT;
2033
    GDALComputedRasterBand operator+(double cst) const CPL_WARN_UNUSED_RESULT;
2034
    friend GDALComputedRasterBand CPL_DLL
2035
    operator+(double cst, const GDALRasterBand &other) CPL_WARN_UNUSED_RESULT;
2036

2037
    GDALComputedRasterBand
2038
    operator-(const GDALRasterBand &other) const CPL_WARN_UNUSED_RESULT;
2039
    GDALComputedRasterBand operator-(double cst) const CPL_WARN_UNUSED_RESULT;
2040
    friend GDALComputedRasterBand CPL_DLL
2041
    operator-(double cst, const GDALRasterBand &other) CPL_WARN_UNUSED_RESULT;
2042

2043
    GDALComputedRasterBand
2044
    operator*(const GDALRasterBand &other) const CPL_WARN_UNUSED_RESULT;
2045
    GDALComputedRasterBand operator*(double cst) const CPL_WARN_UNUSED_RESULT;
2046
    friend GDALComputedRasterBand CPL_DLL
2047
    operator*(double cst, const GDALRasterBand &other) CPL_WARN_UNUSED_RESULT;
2048

2049
    GDALComputedRasterBand
2050
    operator/(const GDALRasterBand &other) const CPL_WARN_UNUSED_RESULT;
2051
    GDALComputedRasterBand operator/(double cst) const CPL_WARN_UNUSED_RESULT;
2052
    friend GDALComputedRasterBand CPL_DLL
2053
    operator/(double cst, const GDALRasterBand &other) CPL_WARN_UNUSED_RESULT;
2054

2055
    GDALComputedRasterBand
2056
    operator>(const GDALRasterBand &other) const CPL_WARN_UNUSED_RESULT;
2057
    GDALComputedRasterBand operator>(double cst) const CPL_WARN_UNUSED_RESULT;
2058
    friend GDALComputedRasterBand CPL_DLL
2059
    operator>(double cst, const GDALRasterBand &other) CPL_WARN_UNUSED_RESULT;
2060

2061
    GDALComputedRasterBand
2062
    operator>=(const GDALRasterBand &other) const CPL_WARN_UNUSED_RESULT;
2063
    GDALComputedRasterBand operator>=(double cst) const CPL_WARN_UNUSED_RESULT;
2064
    friend GDALComputedRasterBand CPL_DLL
2065
    operator>=(double cst, const GDALRasterBand &other) CPL_WARN_UNUSED_RESULT;
2066

2067
    GDALComputedRasterBand
2068
    operator<(const GDALRasterBand &other) const CPL_WARN_UNUSED_RESULT;
2069
    GDALComputedRasterBand operator<(double cst) const CPL_WARN_UNUSED_RESULT;
2070
    friend GDALComputedRasterBand CPL_DLL
2071
    operator<(double cst, const GDALRasterBand &other) CPL_WARN_UNUSED_RESULT;
2072

2073
    GDALComputedRasterBand
2074
    operator<=(const GDALRasterBand &other) const CPL_WARN_UNUSED_RESULT;
2075
    GDALComputedRasterBand operator<=(double cst) const CPL_WARN_UNUSED_RESULT;
2076
    friend GDALComputedRasterBand CPL_DLL
2077
    operator<=(double cst, const GDALRasterBand &other) CPL_WARN_UNUSED_RESULT;
2078

2079
    GDALComputedRasterBand
2080
    operator==(const GDALRasterBand &other) const CPL_WARN_UNUSED_RESULT;
2081
    GDALComputedRasterBand operator==(double cst) const CPL_WARN_UNUSED_RESULT;
2082
    friend GDALComputedRasterBand CPL_DLL
2083
    operator==(double cst, const GDALRasterBand &other) CPL_WARN_UNUSED_RESULT;
2084

2085
    GDALComputedRasterBand
2086
    operator!=(const GDALRasterBand &other) const CPL_WARN_UNUSED_RESULT;
2087
    GDALComputedRasterBand operator!=(double cst) const CPL_WARN_UNUSED_RESULT;
2088
    friend GDALComputedRasterBand CPL_DLL
2089
    operator!=(double cst, const GDALRasterBand &other) CPL_WARN_UNUSED_RESULT;
2090

2091
#if defined(__GNUC__)
2092
#pragma GCC diagnostic push
2093
#pragma GCC diagnostic ignored "-Weffc++"
2094
#endif
2095

2096
    GDALComputedRasterBand
2097
    operator&&(const GDALRasterBand &other) const CPL_WARN_UNUSED_RESULT;
2098
    GDALComputedRasterBand operator&&(bool cst) const CPL_WARN_UNUSED_RESULT;
2099
    friend GDALComputedRasterBand CPL_DLL
2100
    operator&&(bool cst, const GDALRasterBand &other) CPL_WARN_UNUSED_RESULT;
2101

2102
    GDALComputedRasterBand
2103
    operator||(const GDALRasterBand &other) const CPL_WARN_UNUSED_RESULT;
2104
    GDALComputedRasterBand operator||(bool cst) const CPL_WARN_UNUSED_RESULT;
2105
    friend GDALComputedRasterBand CPL_DLL
2106
    operator||(bool cst, const GDALRasterBand &other) CPL_WARN_UNUSED_RESULT;
2107

2108
#if defined(__GNUC__)
2109
#pragma GCC diagnostic pop
2110
#endif
2111

2112
    GDALComputedRasterBand operator!() const CPL_WARN_UNUSED_RESULT;
2113

2114
    GDALComputedRasterBand AsType(GDALDataType) const CPL_WARN_UNUSED_RESULT;
2115

2116
    CPLErr ReadBlock(int nXBlockOff, int nYBlockOff,
2117
                     void *pImage) CPL_WARN_UNUSED_RESULT;
2118

2119
    CPLErr WriteBlock(int nXBlockOff, int nYBlockOff,
2120
                      void *pImage) CPL_WARN_UNUSED_RESULT;
2121

2122
    // This method should only be overloaded by GDALProxyRasterBand
2123
    virtual GDALRasterBlock *
2124
    GetLockedBlockRef(int nXBlockOff, int nYBlockOff,
2125
                      int bJustInitialize = FALSE) CPL_WARN_UNUSED_RESULT;
2126

2127
    // This method should only be overloaded by GDALProxyRasterBand
2128
    virtual GDALRasterBlock *
2129
    TryGetLockedBlockRef(int nXBlockOff,
2130
                         int nYBlockYOff) CPL_WARN_UNUSED_RESULT;
2131

2132
    // This method should only be overloaded by GDALProxyRasterBand
2133
    virtual CPLErr FlushBlock(int nXBlockOff, int nYBlockOff,
2134
                              int bWriteDirtyBlock = TRUE);
2135

2136
    unsigned char *
2137
    GetIndexColorTranslationTo(/* const */ GDALRasterBand *poReferenceBand,
2138
                               unsigned char *pTranslationTable = nullptr,
2139
                               int *pApproximateMatching = nullptr);
2140

2141
    // New OpengIS CV_SampleDimension stuff.
2142

2143
    virtual CPLErr FlushCache(bool bAtClosing = false);
2144
    virtual CPLErr DropCache();
2145
    virtual char **GetCategoryNames();
2146
    virtual double GetNoDataValue(int *pbSuccess = nullptr);
2147
    virtual int64_t GetNoDataValueAsInt64(int *pbSuccess = nullptr);
2148
    virtual uint64_t GetNoDataValueAsUInt64(int *pbSuccess = nullptr);
2149
    virtual double GetMinimum(int *pbSuccess = nullptr);
2150
    virtual double GetMaximum(int *pbSuccess = nullptr);
2151
    virtual double GetOffset(int *pbSuccess = nullptr);
2152
    virtual double GetScale(int *pbSuccess = nullptr);
2153
    virtual const char *GetUnitType();
2154
    virtual GDALColorInterp GetColorInterpretation();
2155
    virtual GDALColorTable *GetColorTable();
2156
    virtual CPLErr Fill(double dfRealValue, double dfImaginaryValue = 0);
2157

2158
    virtual CPLErr SetCategoryNames(char **papszNames);
2159
    virtual CPLErr SetNoDataValue(double dfNoData);
2160
    virtual CPLErr SetNoDataValueAsInt64(int64_t nNoData);
2161
    virtual CPLErr SetNoDataValueAsUInt64(uint64_t nNoData);
2162
    CPLErr SetNoDataValueAsString(const char *pszNoData,
2163
                                  bool *pbCannotBeExactlyRepresented = nullptr);
2164
    virtual CPLErr DeleteNoDataValue();
2165
    virtual CPLErr SetColorTable(GDALColorTable *poCT);
2166
    virtual CPLErr SetColorInterpretation(GDALColorInterp eColorInterp);
2167
    virtual CPLErr SetOffset(double dfNewOffset);
2168
    virtual CPLErr SetScale(double dfNewScale);
2169
    virtual CPLErr SetUnitType(const char *pszNewValue);
2170

2171
    virtual CPLErr GetStatistics(int bApproxOK, int bForce, double *pdfMin,
2172
                                 double *pdfMax, double *pdfMean,
2173
                                 double *padfStdDev);
2174
    virtual CPLErr ComputeStatistics(int bApproxOK, double *pdfMin,
2175
                                     double *pdfMax, double *pdfMean,
2176
                                     double *pdfStdDev, GDALProgressFunc,
2177
                                     void *pProgressData);
2178
    virtual CPLErr SetStatistics(double dfMin, double dfMax, double dfMean,
2179
                                 double dfStdDev);
2180
    virtual CPLErr ComputeRasterMinMax(int bApproxOK, double *adfMinMax);
2181
    virtual CPLErr ComputeRasterMinMaxLocation(double *pdfMin, double *pdfMax,
2182
                                               int *pnMinX, int *pnMinY,
2183
                                               int *pnMaxX, int *pnMaxY);
2184

2185
// Only defined when Doxygen enabled
2186
#ifdef DOXYGEN_SKIP
2187
    CPLErr SetMetadata(char **papszMetadata, const char *pszDomain) override;
2188
    CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
2189
                           const char *pszDomain) override;
2190
#endif
2191
    virtual const char *GetMetadataItem(const char *pszName,
2192
                                        const char *pszDomain = "") override;
2193

2194
    virtual int HasArbitraryOverviews();
2195
    virtual int GetOverviewCount();
2196
    virtual GDALRasterBand *GetOverview(int i);
2197
    virtual GDALRasterBand *GetRasterSampleOverview(GUIntBig);
2198
    virtual CPLErr BuildOverviews(const char *pszResampling, int nOverviews,
2199
                                  const int *panOverviewList,
2200
                                  GDALProgressFunc pfnProgress,
2201
                                  void *pProgressData,
2202
                                  CSLConstList papszOptions);
2203

2204
    virtual CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize,
2205
                              int nBufXSize, int nBufYSize,
2206
                              GDALDataType eBufType, char **papszOptions);
2207

2208
    virtual CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets,
2209
                                GUIntBig *panHistogram, int bIncludeOutOfRange,
2210
                                int bApproxOK, GDALProgressFunc,
2211
                                void *pProgressData);
2212

2213
    virtual CPLErr GetDefaultHistogram(double *pdfMin, double *pdfMax,
2214
                                       int *pnBuckets, GUIntBig **ppanHistogram,
2215
                                       int bForce, GDALProgressFunc,
2216
                                       void *pProgressData);
2217
    virtual CPLErr SetDefaultHistogram(double dfMin, double dfMax, int nBuckets,
2218
                                       GUIntBig *panHistogram);
2219

2220
    virtual GDALRasterAttributeTable *GetDefaultRAT();
2221
    virtual CPLErr SetDefaultRAT(const GDALRasterAttributeTable *poRAT);
2222

2223
    virtual GDALRasterBand *GetMaskBand();
2224
    virtual int GetMaskFlags();
2225
    virtual CPLErr CreateMaskBand(int nFlagsIn);
2226
    virtual bool IsMaskBand() const;
2227
    virtual GDALMaskValueRange GetMaskValueRange() const;
2228

2229
    virtual CPLVirtualMem *
2230
    GetVirtualMemAuto(GDALRWFlag eRWFlag, int *pnPixelSpace,
2231
                      GIntBig *pnLineSpace,
2232
                      char **papszOptions) CPL_WARN_UNUSED_RESULT;
2233

2234
    int GetDataCoverageStatus(int nXOff, int nYOff, int nXSize, int nYSize,
2235
                              int nMaskFlagStop = 0,
2236
                              double *pdfDataPct = nullptr);
2237

2238
    std::shared_ptr<GDALMDArray> AsMDArray() const;
2239

2240
    CPLErr InterpolateAtGeolocation(
2241
        double dfGeolocX, double dfGeolocY, const OGRSpatialReference *poSRS,
2242
        GDALRIOResampleAlg eInterpolation, double *pdfRealValue,
2243
        double *pdfImagValue = nullptr,
2244
        CSLConstList papszTransformerOptions = nullptr) const;
2245

2246
    virtual CPLErr InterpolateAtPoint(double dfPixel, double dfLine,
2247
                                      GDALRIOResampleAlg eInterpolation,
2248
                                      double *pdfRealValue,
2249
                                      double *pdfImagValue = nullptr) const;
2250

2251
#ifndef DOXYGEN_XML
2252
    void ReportError(CPLErr eErrClass, CPLErrorNum err_no, const char *fmt,
2253
                     ...) const CPL_PRINT_FUNC_FORMAT(4, 5);
2254
#endif
2255

2256
    //! @cond Doxygen_Suppress
2257
    static void ThrowIfNotSameDimensions(const GDALRasterBand &first,
2258
                                         const GDALRasterBand &second);
2259

2260
    //! @endcond
2261

2262
    /** Convert a GDALRasterBand* to a GDALRasterBandH.
2263
     * @since GDAL 2.3
2264
     */
2265
    static inline GDALRasterBandH ToHandle(GDALRasterBand *poBand)
421,011✔
2266
    {
2267
        return static_cast<GDALRasterBandH>(poBand);
421,011✔
2268
    }
2269

2270
    /** Convert a GDALRasterBandH to a GDALRasterBand*.
2271
     * @since GDAL 2.3
2272
     */
2273
    static inline GDALRasterBand *FromHandle(GDALRasterBandH hBand)
5,254,646✔
2274
    {
2275
        return static_cast<GDALRasterBand *>(hBand);
5,254,646✔
2276
    }
2277

2278
    //! @cond Doxygen_Suppress
2279
    // Remove me in GDAL 4.0. See GetMetadataItem() implementation
2280
    // Internal use in GDAL only !
2281
    virtual void EnablePixelTypeSignedByteWarning(bool b)
2282
#ifndef GDAL_COMPILATION
2283
        CPL_WARN_DEPRECATED("Do not use that method outside of GDAL!")
2284
#endif
2285
            ;
2286

2287
    //! @endcond
2288

2289
  private:
2290
    CPL_DISALLOW_COPY_ASSIGN(GDALRasterBand)
2291
};
2292

2293
//! @cond Doxygen_Suppress
2294
#define GDAL_EXTERN_TEMPLATE_READ_RASTER(T)                                    \
2295
    extern template CPLErr GDALRasterBand::ReadRaster<T>(                      \
2296
        T * pData, size_t nArrayEltCount, double dfXOff, double dfYOff,        \
2297
        double dfXSize, double dfYSize, size_t nBufXSize, size_t nBufYSize,    \
2298
        GDALRIOResampleAlg eResampleAlg, GDALProgressFunc pfnProgress,         \
2299
        void *pProgressData) const;
2300

2301
GDAL_EXTERN_TEMPLATE_READ_RASTER(uint8_t)
2302
GDAL_EXTERN_TEMPLATE_READ_RASTER(int8_t)
2303
GDAL_EXTERN_TEMPLATE_READ_RASTER(uint16_t)
2304
GDAL_EXTERN_TEMPLATE_READ_RASTER(int16_t)
2305
GDAL_EXTERN_TEMPLATE_READ_RASTER(uint32_t)
2306
GDAL_EXTERN_TEMPLATE_READ_RASTER(int32_t)
2307
GDAL_EXTERN_TEMPLATE_READ_RASTER(uint64_t)
2308
GDAL_EXTERN_TEMPLATE_READ_RASTER(int64_t)
2309
#ifdef CPL_FLOAT_H_INCLUDED
2310
GDAL_EXTERN_TEMPLATE_READ_RASTER(GFloat16)
2311
#endif
2312
GDAL_EXTERN_TEMPLATE_READ_RASTER(float)
2313
GDAL_EXTERN_TEMPLATE_READ_RASTER(double)
2314
// Not allowed by C++ standard
2315
// GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<int16_t>)
2316
// GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<int32_t>)
2317
GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<float>)
2318
GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<double>)
2319

2320
#define GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(T)                             \
2321
    extern template CPLErr GDALRasterBand::ReadRaster<T>(                      \
2322
        std::vector<T> & vData, double dfXOff, double dfYOff, double dfXSize,  \
2323
        double dfYSize, size_t nBufXSize, size_t nBufYSize,                    \
2324
        GDALRIOResampleAlg eResampleAlg, GDALProgressFunc pfnProgress,         \
2325
        void *pProgressData) const;
2326

2327
GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint8_t)
2328
GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int8_t)
2329
GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint16_t)
2330
GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int16_t)
2331
GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint32_t)
2332
GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int32_t)
2333
GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint64_t)
2334
GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int64_t)
2335
#ifdef CPL_FLOAT_H_INCLUDED
2336
GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(GFloat16)
2337
#endif
2338
GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(float)
2339
GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(double)
2340
// Not allowed by C++ standard
2341
// GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<int16_t>)
2342
// GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<int32_t>)
2343
GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<float>)
2344
GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<double>)
2345

2346
//! @endcond
2347

2348
/* ******************************************************************** */
2349
/*                       GDALComputedRasterBand                         */
2350
/* ******************************************************************** */
2351

2352
/** Class represented the result of an operation on one or two input bands.
2353
 *
2354
 * Such class is instantiated only by operators on GDALRasterBand.
2355
 * The resulting band is lazy evaluated.
2356
 *
2357
 * @since 3.12
2358
 */
2359
class CPL_DLL GDALComputedRasterBand final : public GDALRasterBand
2360
{
2361
  public:
2362
    /** Destructor */
2363
    ~GDALComputedRasterBand() override;
2364

2365
    //! @cond Doxygen_Suppress
2366
    enum class Operation
2367
    {
2368
        OP_ADD,
2369
        OP_SUBTRACT,
2370
        OP_MULTIPLY,
2371
        OP_DIVIDE,
2372
        OP_MIN,
2373
        OP_MAX,
2374
        OP_MEAN,
2375
        OP_GT,
2376
        OP_GE,
2377
        OP_LT,
2378
        OP_LE,
2379
        OP_EQ,
2380
        OP_NE,
2381
        OP_LOGICAL_AND,
2382
        OP_LOGICAL_OR,
2383
        OP_CAST,
2384
        OP_TERNARY,
2385
    };
2386

2387
    GDALComputedRasterBand(
2388
        Operation op, const std::vector<const GDALRasterBand *> &bands,
2389
        double constant = std::numeric_limits<double>::quiet_NaN());
2390
    GDALComputedRasterBand(Operation op, double constant,
2391
                           const GDALRasterBand &band);
2392
    GDALComputedRasterBand(Operation op, const GDALRasterBand &band,
2393
                           double constant);
2394
    GDALComputedRasterBand(Operation op, const GDALRasterBand &band,
2395
                           GDALDataType dt);
2396

2397
    // Semi-public for gdal::min(), gdal::max()
2398
    GDALComputedRasterBand(Operation op, const GDALRasterBand &firstBand,
2399
                           const GDALRasterBand &secondBand);
2400

2401
    GDALComputedRasterBand(GDALComputedRasterBand &&) = default;
2402

2403
    //! @endcond
2404

2405
    double GetNoDataValue(int *pbSuccess = nullptr) override;
2406

2407
    /** Convert a GDALComputedRasterBand* to a GDALComputedRasterBandH.
2408
     */
2409
    static inline GDALComputedRasterBandH
2410
    ToHandle(GDALComputedRasterBand *poBand)
2411
    {
2412
        return static_cast<GDALComputedRasterBandH>(poBand);
2413
    }
2414

2415
    /** Convert a GDALComputedRasterBandH to a GDALComputedRasterBand*.
2416
     */
2417
    static inline GDALComputedRasterBand *
2418
    FromHandle(GDALComputedRasterBandH hBand)
156✔
2419
    {
2420
        return static_cast<GDALComputedRasterBand *>(hBand);
156✔
2421
    }
2422

2423
  protected:
2424
    friend class GDALRasterBand;
2425

2426
    CPLErr IReadBlock(int, int, void *) override;
2427

2428
    CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
2429
                     int nYSize, void *pData, int nBufXSize, int nBufYSize,
2430
                     GDALDataType eBufType, GSpacing nPixelSpace,
2431
                     GSpacing nLineSpace,
2432
                     GDALRasterIOExtraArg *psExtraArg) override;
2433

2434
  private:
2435
    friend class GDALComputedDataset;
2436
    std::unique_ptr<GDALDataset, GDALDatasetUniquePtrReleaser> m_poOwningDS{};
2437
    bool m_bHasNoData{false};
2438
    double m_dfNoDataValue{0};
2439

2440
    GDALComputedRasterBand(const GDALComputedRasterBand &, bool);
2441
    GDALComputedRasterBand(const GDALComputedRasterBand &) = delete;
2442
    GDALComputedRasterBand &operator=(const GDALComputedRasterBand &) = delete;
2443
    GDALComputedRasterBand &operator=(GDALComputedRasterBand &&) = delete;
2444
};
2445

2446
namespace gdal
2447
{
2448

2449
GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
2450
                                          const GDALRasterBand &thenBand,
2451
                                          const GDALRasterBand &elseBand);
2452

2453
//! @cond Doxygen_Suppress
2454

2455
GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
2456
                                          double thenValue,
2457
                                          const GDALRasterBand &elseBand);
2458

2459
GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
2460
                                          const GDALRasterBand &thenBand,
2461
                                          double elseValue);
2462

2463
GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
2464
                                          double thenValue, double elseValue);
2465

2466
//! @endcond
2467

2468
using std::max;
2469
using std::min;
2470

2471
GDALComputedRasterBand CPL_DLL min(const GDALRasterBand &first,
2472
                                   const GDALRasterBand &second);
2473

2474
//! @cond Doxygen_Suppress
2475

2476
namespace detail
2477
{
2478

2479
template <typename U, typename Enable> struct minDealFirstArg;
2480

2481
template <typename U>
2482
struct minDealFirstArg<
2483
    U, typename std::enable_if<std::is_arithmetic<U>::value>::type>
2484
{
2485
    inline static void process(std::vector<const GDALRasterBand *> &,
2✔
2486
                               double &constant, const U &first)
2487
    {
2488
        if (std::isnan(constant) || static_cast<double>(first) < constant)
2✔
2489
            constant = static_cast<double>(first);
2✔
2490
    }
2✔
2491
};
2492

2493
template <typename U>
2494
struct minDealFirstArg<
2495
    U, typename std::enable_if<!std::is_arithmetic<U>::value>::type>
2496
{
2497
    inline static void process(std::vector<const GDALRasterBand *> &bands,
16✔
2498
                               double &, const U &first)
2499
    {
2500
        if (!bands.empty())
16✔
2501
            GDALRasterBand::ThrowIfNotSameDimensions(first, *(bands.front()));
10✔
2502
        bands.push_back(&first);
14✔
2503
    }
14✔
2504
};
2505

2506
inline static GDALComputedRasterBand
2507
minInternal(std::vector<const GDALRasterBand *> &bands, double constant)
4✔
2508
{
2509
    return GDALComputedRasterBand(GDALComputedRasterBand::Operation::OP_MIN,
2510
                                  bands, constant);
4✔
2511
}
2512

2513
template <typename U, typename... V>
2514
GDALComputedRasterBand minInternal(std::vector<const GDALRasterBand *> &bands,
18✔
2515
                                   double constant, const U &first, V &&...rest)
2516
{
2517
    minDealFirstArg<U, void>::process(bands, constant, first);
18✔
2518
    return minInternal(bands, constant, std::forward<V>(rest)...);
16✔
2519
}
2520

2521
}  // namespace detail
2522

2523
template <typename U, typename... V>
2524
inline GDALComputedRasterBand min(const U &first, V &&...rest)
6✔
2525
{
2526
    std::vector<const GDALRasterBand *> bands;
12✔
2527
    return detail::minInternal(bands, std::numeric_limits<double>::quiet_NaN(),
2528
                               first, std::forward<V>(rest)...);
10✔
2529
}
2530

2531
//! @endcond
2532

2533
GDALComputedRasterBand CPL_DLL max(const GDALRasterBand &first,
2534
                                   const GDALRasterBand &second);
2535

2536
//! @cond Doxygen_Suppress
2537

2538
namespace detail
2539
{
2540

2541
template <typename U, typename Enable> struct maxDealFirstArg;
2542

2543
template <typename U>
2544
struct maxDealFirstArg<
2545
    U, typename std::enable_if<std::is_arithmetic<U>::value>::type>
2546
{
2547
    inline static void process(std::vector<const GDALRasterBand *> &,
2✔
2548
                               double &constant, const U &first)
2549
    {
2550
        if (std::isnan(constant) || static_cast<double>(first) > constant)
2✔
2551
            constant = static_cast<double>(first);
2✔
2552
    }
2✔
2553
};
2554

2555
template <typename U>
2556
struct maxDealFirstArg<
2557
    U, typename std::enable_if<!std::is_arithmetic<U>::value>::type>
2558
{
2559
    inline static void process(std::vector<const GDALRasterBand *> &bands,
14✔
2560
                               double &, const U &first)
2561
    {
2562
        if (!bands.empty())
14✔
2563
            GDALRasterBand::ThrowIfNotSameDimensions(first, *(bands.front()));
9✔
2564
        bands.push_back(&first);
12✔
2565
    }
12✔
2566
};
2567

2568
inline static GDALComputedRasterBand
2569
maxInternal(std::vector<const GDALRasterBand *> &bands, double constant)
3✔
2570
{
2571
    return GDALComputedRasterBand(GDALComputedRasterBand::Operation::OP_MAX,
2572
                                  bands, constant);
3✔
2573
}
2574

2575
template <typename U, typename... V>
2576
GDALComputedRasterBand maxInternal(std::vector<const GDALRasterBand *> &bands,
16✔
2577
                                   double constant, const U &first, V &&...rest)
2578
{
2579
    maxDealFirstArg<U, void>::process(bands, constant, first);
16✔
2580
    return maxInternal(bands, constant, std::forward<V>(rest)...);
14✔
2581
}
2582

2583
}  // namespace detail
2584

2585
template <typename U, typename... V>
2586
inline GDALComputedRasterBand max(const U &first, V &&...rest)
5✔
2587
{
2588
    std::vector<const GDALRasterBand *> bands;
10✔
2589
    return detail::maxInternal(bands, std::numeric_limits<double>::quiet_NaN(),
2590
                               first, std::forward<V>(rest)...);
8✔
2591
}
2592

2593
//! @endcond
2594

2595
GDALComputedRasterBand CPL_DLL mean(const GDALRasterBand &first,
2596
                                    const GDALRasterBand &second);
2597

2598
//! @cond Doxygen_Suppress
2599
inline GDALComputedRasterBand
2600
meanInternal(std::vector<const GDALRasterBand *> &bands)
1✔
2601
{
2602
    return GDALComputedRasterBand(GDALComputedRasterBand::Operation::OP_MEAN,
2603
                                  bands);
1✔
2604
}
2605

2606
template <typename U, typename... V>
2607
inline GDALComputedRasterBand
2608
meanInternal(std::vector<const GDALRasterBand *> &bands, const U &first,
8✔
2609
             V &&...rest)
2610
{
2611
    if (!bands.empty())
8✔
2612
        GDALRasterBand::ThrowIfNotSameDimensions(first, *(bands.front()));
5✔
2613
    bands.push_back(&first);
6✔
2614
    return meanInternal(bands, std::forward<V>(rest)...);
6✔
2615
}
2616

2617
template <typename... Args> inline GDALComputedRasterBand mean(Args &&...args)
3✔
2618
{
2619
    std::vector<const GDALRasterBand *> bands;
6✔
2620
    return meanInternal(bands, std::forward<Args>(args)...);
4✔
2621
}
2622

2623
//! @endcond
2624

2625
}  // namespace gdal
2626

2627
//! @cond Doxygen_Suppress
2628
/* ******************************************************************** */
2629
/*                         GDALAllValidMaskBand                         */
2630
/* ******************************************************************** */
2631

2632
class CPL_DLL GDALAllValidMaskBand : public GDALRasterBand
318,900✔
2633
{
2634
  protected:
2635
    CPLErr IReadBlock(int, int, void *) override;
2636

2637
    CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
2638
                     int nYSize, void *pData, int nBufXSize, int nBufYSize,
2639
                     GDALDataType eBufType, GSpacing nPixelSpace,
2640
                     GSpacing nLineSpace,
2641
                     GDALRasterIOExtraArg *psExtraArg) override;
2642

2643
    bool
2644
    EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2645

2646
    CPL_DISALLOW_COPY_ASSIGN(GDALAllValidMaskBand)
2647

2648
  public:
2649
    explicit GDALAllValidMaskBand(GDALRasterBand *);
2650
    ~GDALAllValidMaskBand() override;
2651

2652
    GDALRasterBand *GetMaskBand() override;
2653
    int GetMaskFlags() override;
2654

2655
    bool IsMaskBand() const override
1✔
2656
    {
2657
        return true;
1✔
2658
    }
2659

2660
    GDALMaskValueRange GetMaskValueRange() const override
×
2661
    {
2662
        return GMVR_0_AND_255_ONLY;
×
2663
    }
2664

2665
    CPLErr ComputeStatistics(int bApproxOK, double *pdfMin, double *pdfMax,
2666
                             double *pdfMean, double *pdfStdDev,
2667
                             GDALProgressFunc, void *pProgressData) override;
2668
};
2669

2670
/* ******************************************************************** */
2671
/*                         GDALNoDataMaskBand                           */
2672
/* ******************************************************************** */
2673

2674
class CPL_DLL GDALNoDataMaskBand : public GDALRasterBand
2,128✔
2675
{
2676
    friend class GDALRasterBand;
2677
    double m_dfNoDataValue = 0;
2678
    int64_t m_nNoDataValueInt64 = 0;
2679
    uint64_t m_nNoDataValueUInt64 = 0;
2680
    GDALRasterBand *m_poParent = nullptr;
2681

2682
    CPL_DISALLOW_COPY_ASSIGN(GDALNoDataMaskBand)
2683

2684
  protected:
2685
    CPLErr IReadBlock(int, int, void *) override;
2686
    CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
2687
                     GDALDataType, GSpacing, GSpacing,
2688
                     GDALRasterIOExtraArg *psExtraArg) override;
2689

2690
    bool
2691
    EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2692

2693
  public:
2694
    explicit GDALNoDataMaskBand(GDALRasterBand *);
2695
    explicit GDALNoDataMaskBand(GDALRasterBand *, double dfNoDataValue);
2696
    ~GDALNoDataMaskBand() override;
2697

2698
    bool IsMaskBand() const override
1✔
2699
    {
2700
        return true;
1✔
2701
    }
2702

2703
    GDALMaskValueRange GetMaskValueRange() const override
×
2704
    {
2705
        return GMVR_0_AND_255_ONLY;
×
2706
    }
2707

2708
    static bool IsNoDataInRange(double dfNoDataValue, GDALDataType eDataType);
2709
};
2710

2711
/* ******************************************************************** */
2712
/*                  GDALNoDataValuesMaskBand                            */
2713
/* ******************************************************************** */
2714

2715
class CPL_DLL GDALNoDataValuesMaskBand : public GDALRasterBand
2716
{
2717
    double *padfNodataValues;
2718

2719
    CPL_DISALLOW_COPY_ASSIGN(GDALNoDataValuesMaskBand)
2720

2721
  protected:
2722
    CPLErr IReadBlock(int, int, void *) override;
2723

2724
    bool
2725
    EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2726

2727
  public:
2728
    explicit GDALNoDataValuesMaskBand(GDALDataset *);
2729
    ~GDALNoDataValuesMaskBand() override;
2730

2731
    bool IsMaskBand() const override
×
2732
    {
2733
        return true;
×
2734
    }
2735

2736
    GDALMaskValueRange GetMaskValueRange() const override
×
2737
    {
2738
        return GMVR_0_AND_255_ONLY;
×
2739
    }
2740
};
2741

2742
/* ******************************************************************** */
2743
/*                         GDALRescaledAlphaBand                        */
2744
/* ******************************************************************** */
2745

2746
class GDALRescaledAlphaBand : public GDALRasterBand
2747
{
2748
    GDALRasterBand *poParent;
2749
    void *pTemp;
2750

2751
    CPL_DISALLOW_COPY_ASSIGN(GDALRescaledAlphaBand)
2752

2753
  protected:
2754
    CPLErr IReadBlock(int, int, void *) override;
2755
    CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
2756
                     GDALDataType, GSpacing, GSpacing,
2757
                     GDALRasterIOExtraArg *psExtraArg) override;
2758

2759
    bool
2760
    EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2761

2762
  public:
2763
    explicit GDALRescaledAlphaBand(GDALRasterBand *);
2764
    ~GDALRescaledAlphaBand() override;
2765

2766
    bool IsMaskBand() const override
×
2767
    {
2768
        return true;
×
2769
    }
2770
};
2771

2772
//! @endcond
2773

2774
/* ******************************************************************** */
2775
/*                          GDALIdentifyEnum                            */
2776
/* ******************************************************************** */
2777

2778
/**
2779
 * Enumeration used by GDALDriver::pfnIdentify().
2780
 *
2781
 * @since GDAL 2.1
2782
 */
2783
typedef enum
2784
{
2785
    /** Identify could not determine if the file is recognized or not by the
2786
       probed driver. */
2787
    GDAL_IDENTIFY_UNKNOWN = -1,
2788
    /** Identify determined the file is not recognized by the probed driver. */
2789
    GDAL_IDENTIFY_FALSE = 0,
2790
    /** Identify determined the file is recognized by the probed driver. */
2791
    GDAL_IDENTIFY_TRUE = 1
2792
} GDALIdentifyEnum;
2793

2794
/* ******************************************************************** */
2795
/*                              GDALDriver                              */
2796
/* ******************************************************************** */
2797

2798
/**
2799
 * \brief Format specific driver.
2800
 *
2801
 * An instance of this class is created for each supported format, and
2802
 * manages information about the format.
2803
 *
2804
 * This roughly corresponds to a file format, though some
2805
 * drivers may be gateways to many formats through a secondary
2806
 * multi-library.
2807
 */
2808

2809
class CPL_DLL GDALDriver : public GDALMajorObject
361,066✔
2810
{
2811
  public:
2812
    GDALDriver();
2813
    ~GDALDriver() override;
2814

2815
    CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
2816
                           const char *pszDomain = "") override;
2817

2818
    /* -------------------------------------------------------------------- */
2819
    /*      Public C++ methods.                                             */
2820
    /* -------------------------------------------------------------------- */
2821
    GDALDataset *Create(const char *pszName, int nXSize, int nYSize, int nBands,
2822
                        GDALDataType eType,
2823
                        CSLConstList papszOptions) CPL_WARN_UNUSED_RESULT;
2824

2825
    GDALDataset *
2826
    CreateMultiDimensional(const char *pszName,
2827
                           CSLConstList papszRootGroupOptions,
2828
                           CSLConstList papszOptions) CPL_WARN_UNUSED_RESULT;
2829

2830
    CPLErr Delete(const char *pszName);
2831
    CPLErr Rename(const char *pszNewName, const char *pszOldName);
2832
    CPLErr CopyFiles(const char *pszNewName, const char *pszOldName);
2833

2834
    GDALDataset *CreateCopy(const char *, GDALDataset *, int,
2835
                            CSLConstList papszOptions,
2836
                            GDALProgressFunc pfnProgress,
2837
                            void *pProgressData) CPL_WARN_UNUSED_RESULT;
2838

2839
    bool CanVectorTranslateFrom(const char *pszDestName,
2840
                                GDALDataset *poSourceDS,
2841
                                CSLConstList papszVectorTranslateArguments,
2842
                                char ***ppapszFailureReasons);
2843

2844
    /**
2845
     * \brief Returns TRUE if the given open option is supported by the driver.
2846
     * @param pszOpenOptionName name of the open option to be checked
2847
     * @return TRUE if the driver supports the open option
2848
     * @since GDAL 3.11
2849
     */
2850
    bool HasOpenOption(const char *pszOpenOptionName) const;
2851

2852
    GDALDataset *
2853
    VectorTranslateFrom(const char *pszDestName, GDALDataset *poSourceDS,
2854
                        CSLConstList papszVectorTranslateArguments,
2855
                        GDALProgressFunc pfnProgress,
2856
                        void *pProgressData) CPL_WARN_UNUSED_RESULT;
2857

2858
    /* -------------------------------------------------------------------- */
2859
    /*      The following are semiprivate, not intended to be accessed      */
2860
    /*      by anyone but the formats instantiating and populating the      */
2861
    /*      drivers.                                                        */
2862
    /* -------------------------------------------------------------------- */
2863
    //! @cond Doxygen_Suppress
2864

2865
    // Not aimed at being used outside of GDAL. Use GDALDataset::Open() instead
2866
    GDALDataset *Open(GDALOpenInfo *poOpenInfo, bool bSetOpenOptions);
2867

2868
    typedef GDALDataset *(*OpenCallback)(GDALOpenInfo *);
2869

2870
    OpenCallback pfnOpen = nullptr;
2871

2872
    virtual OpenCallback GetOpenCallback()
435,578✔
2873
    {
2874
        return pfnOpen;
435,578✔
2875
    }
2876

2877
    typedef GDALDataset *(*CreateCallback)(const char *pszName, int nXSize,
2878
                                           int nYSize, int nBands,
2879
                                           GDALDataType eType,
2880
                                           char **papszOptions);
2881

2882
    CreateCallback pfnCreate = nullptr;
2883

2884
    virtual CreateCallback GetCreateCallback()
22,058✔
2885
    {
2886
        return pfnCreate;
22,058✔
2887
    }
2888

2889
    GDALDataset *(*pfnCreateEx)(GDALDriver *, const char *pszName, int nXSize,
2890
                                int nYSize, int nBands, GDALDataType eType,
2891
                                char **papszOptions) = nullptr;
2892

2893
    typedef GDALDataset *(*CreateMultiDimensionalCallback)(
2894
        const char *pszName, CSLConstList papszRootGroupOptions,
2895
        CSLConstList papszOptions);
2896

2897
    CreateMultiDimensionalCallback pfnCreateMultiDimensional = nullptr;
2898

2899
    virtual CreateMultiDimensionalCallback GetCreateMultiDimensionalCallback()
465✔
2900
    {
2901
        return pfnCreateMultiDimensional;
465✔
2902
    }
2903

2904
    typedef CPLErr (*DeleteCallback)(const char *pszName);
2905
    DeleteCallback pfnDelete = nullptr;
2906

2907
    virtual DeleteCallback GetDeleteCallback()
5,449✔
2908
    {
2909
        return pfnDelete;
5,449✔
2910
    }
2911

2912
    typedef GDALDataset *(*CreateCopyCallback)(const char *, GDALDataset *, int,
2913
                                               char **,
2914
                                               GDALProgressFunc pfnProgress,
2915
                                               void *pProgressData);
2916

2917
    CreateCopyCallback pfnCreateCopy = nullptr;
2918

2919
    virtual CreateCopyCallback GetCreateCopyCallback()
11,073✔
2920
    {
2921
        return pfnCreateCopy;
11,073✔
2922
    }
2923

2924
    void *pDriverData = nullptr;
2925

2926
    void (*pfnUnloadDriver)(GDALDriver *) = nullptr;
2927

2928
    /** Identify() if the file is recognized or not by the driver.
2929

2930
       Return GDAL_IDENTIFY_TRUE (1) if the passed file is certainly recognized
2931
       by the driver. Return GDAL_IDENTIFY_FALSE (0) if the passed file is
2932
       certainly NOT recognized by the driver. Return GDAL_IDENTIFY_UNKNOWN (-1)
2933
       if the passed file may be or may not be recognized by the driver, and
2934
       that a potentially costly test must be done with pfnOpen.
2935
    */
2936
    int (*pfnIdentify)(GDALOpenInfo *) = nullptr;
2937
    int (*pfnIdentifyEx)(GDALDriver *, GDALOpenInfo *) = nullptr;
2938

2939
    typedef CPLErr (*RenameCallback)(const char *pszNewName,
2940
                                     const char *pszOldName);
2941
    RenameCallback pfnRename = nullptr;
2942

2943
    virtual RenameCallback GetRenameCallback()
175✔
2944
    {
2945
        return pfnRename;
175✔
2946
    }
2947

2948
    typedef CPLErr (*CopyFilesCallback)(const char *pszNewName,
2949
                                        const char *pszOldName);
2950
    CopyFilesCallback pfnCopyFiles = nullptr;
2951

2952
    virtual CopyFilesCallback GetCopyFilesCallback()
12✔
2953
    {
2954
        return pfnCopyFiles;
12✔
2955
    }
2956

2957
    // Used for legacy OGR drivers, and Python drivers
2958
    GDALDataset *(*pfnOpenWithDriverArg)(GDALDriver *,
2959
                                         GDALOpenInfo *) = nullptr;
2960

2961
    /* For legacy OGR drivers */
2962
    GDALDataset *(*pfnCreateVectorOnly)(GDALDriver *, const char *pszName,
2963
                                        char **papszOptions) = nullptr;
2964
    CPLErr (*pfnDeleteDataSource)(GDALDriver *, const char *pszName) = nullptr;
2965

2966
    /** Whether pfnVectorTranslateFrom() can be run given the source dataset
2967
     * and the non-positional arguments of GDALVectorTranslate() stored
2968
     * in papszVectorTranslateArguments.
2969
     */
2970
    bool (*pfnCanVectorTranslateFrom)(
2971
        const char *pszDestName, GDALDataset *poSourceDS,
2972
        CSLConstList papszVectorTranslateArguments,
2973
        char ***ppapszFailureReasons) = nullptr;
2974

2975
    /** Creates a copy from the specified source dataset, using the
2976
     * non-positional arguments of GDALVectorTranslate() stored
2977
     * in papszVectorTranslateArguments.
2978
     */
2979
    GDALDataset *(*pfnVectorTranslateFrom)(
2980
        const char *pszDestName, GDALDataset *poSourceDS,
2981
        CSLConstList papszVectorTranslateArguments,
2982
        GDALProgressFunc pfnProgress, void *pProgressData) = nullptr;
2983

2984
    /**
2985
     * Returns a (possibly null) pointer to the Subdataset informational function
2986
     * from the subdataset file name.
2987
     */
2988
    GDALSubdatasetInfo *(*pfnGetSubdatasetInfoFunc)(const char *pszFileName) =
2989
        nullptr;
2990

2991
    typedef GDALAlgorithm *(*InstantiateAlgorithmCallback)(
2992
        const std::vector<std::string> &aosPath);
2993
    InstantiateAlgorithmCallback pfnInstantiateAlgorithm = nullptr;
2994

2995
    virtual InstantiateAlgorithmCallback GetInstantiateAlgorithmCallback()
56✔
2996
    {
2997
        return pfnInstantiateAlgorithm;
56✔
2998
    }
2999

3000
    /** Instantiate an algorithm by its full path (omitting leading "gdal").
3001
     * For example {"driver", "pdf", "list-layers"}
3002
     */
3003
    GDALAlgorithm *
3004
    InstantiateAlgorithm(const std::vector<std::string> &aosPath);
3005

3006
    /** Declare an algorithm by its full path (omitting leading "gdal").
3007
     * For example {"driver", "pdf", "list-layers"}
3008
     */
3009
    void DeclareAlgorithm(const std::vector<std::string> &aosPath);
3010

3011
    //! @endcond
3012

3013
    /* -------------------------------------------------------------------- */
3014
    /*      Helper methods.                                                 */
3015
    /* -------------------------------------------------------------------- */
3016
    //! @cond Doxygen_Suppress
3017
    GDALDataset *DefaultCreateCopy(const char *, GDALDataset *, int,
3018
                                   CSLConstList papszOptions,
3019
                                   GDALProgressFunc pfnProgress,
3020
                                   void *pProgressData) CPL_WARN_UNUSED_RESULT;
3021

3022
    static CPLErr DefaultCreateCopyMultiDimensional(
3023
        GDALDataset *poSrcDS, GDALDataset *poDstDS, bool bStrict,
3024
        CSLConstList /*papszOptions*/, GDALProgressFunc pfnProgress,
3025
        void *pProgressData);
3026

3027
    static CPLErr DefaultCopyMasks(GDALDataset *poSrcDS, GDALDataset *poDstDS,
3028
                                   int bStrict);
3029
    static CPLErr DefaultCopyMasks(GDALDataset *poSrcDS, GDALDataset *poDstDS,
3030
                                   int bStrict, CSLConstList papszOptions,
3031
                                   GDALProgressFunc pfnProgress,
3032
                                   void *pProgressData);
3033

3034
    CPLErr QuietDeleteForCreateCopy(const char *pszFilename,
3035
                                    GDALDataset *poSrcDS);
3036

3037
    //! @endcond
3038
    static CPLErr QuietDelete(const char *pszName,
3039
                              CSLConstList papszAllowedDrivers = nullptr);
3040

3041
    //! @cond Doxygen_Suppress
3042
    static CPLErr DefaultRename(const char *pszNewName, const char *pszOldName);
3043
    static CPLErr DefaultCopyFiles(const char *pszNewName,
3044
                                   const char *pszOldName);
3045
    static void DefaultCopyMetadata(GDALDataset *poSrcDS, GDALDataset *poDstDS,
3046
                                    CSLConstList papszOptions,
3047
                                    CSLConstList papszExcludedDomains);
3048

3049
    //! @endcond
3050

3051
    /** Convert a GDALDriver* to a GDALDriverH.
3052
     * @since GDAL 2.3
3053
     */
3054
    static inline GDALDriverH ToHandle(GDALDriver *poDriver)
166,884✔
3055
    {
3056
        return static_cast<GDALDriverH>(poDriver);
166,884✔
3057
    }
3058

3059
    /** Convert a GDALDriverH to a GDALDriver*.
3060
     * @since GDAL 2.3
3061
     */
3062
    static inline GDALDriver *FromHandle(GDALDriverH hDriver)
3,782,617✔
3063
    {
3064
        return static_cast<GDALDriver *>(hDriver);
3,782,617✔
3065
    }
3066

3067
  private:
3068
    CPL_DISALLOW_COPY_ASSIGN(GDALDriver)
3069
};
3070

3071
/************************************************************************/
3072
/*                       GDALPluginDriverProxy                          */
3073
/************************************************************************/
3074

3075
// clang-format off
3076
/** Proxy for a plugin driver.
3077
 *
3078
 * Such proxy must be registered with
3079
 * GDALDriverManager::DeclareDeferredPluginDriver().
3080
 *
3081
 * If the real driver defines any of the following metadata items, the
3082
 * proxy driver should also define them with the same value:
3083
 * <ul>
3084
 * <li>GDAL_DMD_LONGNAME</li>
3085
 * <li>GDAL_DMD_EXTENSIONS</li>
3086
 * <li>GDAL_DMD_EXTENSION</li>
3087
 * <li>GDAL_DMD_OPENOPTIONLIST</li>
3088
 * <li>GDAL_DMD_SUBDATASETS</li>
3089
 * <li>GDAL_DMD_CONNECTION_PREFIX</li>
3090
 * <li>GDAL_DCAP_RASTER</li>
3091
 * <li>GDAL_DCAP_MULTIDIM_RASTER</li>
3092
 * <li>GDAL_DCAP_VECTOR</li>
3093
 * <li>GDAL_DCAP_GNM</li>
3094
 * <li>GDAL_DCAP_MULTIPLE_VECTOR_LAYERS</li>
3095
 * <li>GDAL_DCAP_NONSPATIAL</li>
3096
 * <li>GDAL_DCAP_VECTOR_TRANSLATE_FROM</li>
3097
 * </ul>
3098
 *
3099
 * The pfnIdentify and pfnGetSubdatasetInfoFunc callbacks, if they are
3100
 * defined in the real driver, should also be set on the proxy driver.
3101
 *
3102
 * Furthermore, the following metadata items must be defined if the real
3103
 * driver sets the corresponding callback:
3104
 * <ul>
3105
 * <li>GDAL_DCAP_OPEN: must be set to YES if the real driver defines pfnOpen</li>
3106
 * <li>GDAL_DCAP_CREATE: must be set to YES if the real driver defines pfnCreate</li>
3107
 * <li>GDAL_DCAP_CREATE_MULTIDIMENSIONAL: must be set to YES if the real driver defines pfnCreateMultiDimensional</li>
3108
 * <li>GDAL_DCAP_CREATECOPY: must be set to YES if the real driver defines pfnCreateCopy</li>
3109
 * </ul>
3110
 *
3111
 * @since 3.9
3112
 */
3113
// clang-format on
3114

3115
class GDALPluginDriverProxy : public GDALDriver
3116
{
3117
    const std::string m_osPluginFileName;
3118
    std::string m_osPluginFullPath{};
3119
    std::unique_ptr<GDALDriver> m_poRealDriver{};
3120
    std::set<std::string> m_oSetMetadataItems{};
3121

3122
    GDALDriver *GetRealDriver();
3123

3124
    CPL_DISALLOW_COPY_ASSIGN(GDALPluginDriverProxy)
3125

3126
  protected:
3127
    friend class GDALDriverManager;
3128

3129
    //! @cond Doxygen_Suppress
3130
    void SetPluginFullPath(const std::string &osFullPath)
71,676✔
3131
    {
3132
        m_osPluginFullPath = osFullPath;
71,676✔
3133
    }
71,676✔
3134

3135
    //! @endcond
3136

3137
  public:
3138
    explicit GDALPluginDriverProxy(const std::string &osPluginFileName);
3139

3140
    /** Return the plugin file name (not a full path) */
3141
    const std::string &GetPluginFileName() const
71,676✔
3142
    {
3143
        return m_osPluginFileName;
71,676✔
3144
    }
3145

3146
    //! @cond Doxygen_Suppress
3147
    OpenCallback GetOpenCallback() override;
3148

3149
    CreateCallback GetCreateCallback() override;
3150

3151
    CreateMultiDimensionalCallback GetCreateMultiDimensionalCallback() override;
3152

3153
    CreateCopyCallback GetCreateCopyCallback() override;
3154

3155
    DeleteCallback GetDeleteCallback() override;
3156

3157
    RenameCallback GetRenameCallback() override;
3158

3159
    CopyFilesCallback GetCopyFilesCallback() override;
3160

3161
    InstantiateAlgorithmCallback GetInstantiateAlgorithmCallback() override;
3162
    //! @endcond
3163

3164
    CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
3165
                           const char *pszDomain = "") override;
3166

3167
    char **GetMetadata(const char *pszDomain) override;
3168

3169
    const char *GetMetadataItem(const char *pszName,
3170
                                const char *pszDomain = "") override;
3171
};
3172

3173
/* ******************************************************************** */
3174
/*                          GDALDriverManager                           */
3175
/* ******************************************************************** */
3176

3177
/**
3178
 * Class for managing the registration of file format drivers.
3179
 *
3180
 * Use GetGDALDriverManager() to fetch the global singleton instance of
3181
 * this class.
3182
 */
3183

3184
class CPL_DLL GDALDriverManager : public GDALMajorObject
3185
{
3186
    int nDrivers = 0;
3187
    GDALDriver **papoDrivers = nullptr;
3188
    std::map<CPLString, GDALDriver *> oMapNameToDrivers{};
3189
    std::string m_osPluginPath{};
3190
    std::string m_osDriversIniPath{};
3191
    mutable std::string m_osLastTriedDirectory{};
3192
    std::set<std::string> m_oSetPluginFileNames{};
3193
    bool m_bInDeferredDriverLoading = false;
3194
    std::map<std::string, std::unique_ptr<GDALDriver>> m_oMapRealDrivers{};
3195
    std::vector<std::unique_ptr<GDALDriver>> m_aoHiddenDrivers{};
3196

3197
    GDALDriver *GetDriver_unlocked(int iDriver)
19,614,700✔
3198
    {
3199
        return (iDriver >= 0 && iDriver < nDrivers) ? papoDrivers[iDriver]
19,614,700✔
3200
                                                    : nullptr;
19,614,700✔
3201
    }
3202

3203
    GDALDriver *GetDriverByName_unlocked(const char *pszName) const;
3204

3205
    static void CleanupPythonDrivers();
3206

3207
    std::string GetPluginFullPath(const char *pszFilename) const;
3208

3209
    int RegisterDriver(GDALDriver *, bool bHidden);
3210

3211
    CPL_DISALLOW_COPY_ASSIGN(GDALDriverManager)
3212

3213
  protected:
3214
    friend class GDALPluginDriverProxy;
3215
    friend GDALDatasetH CPL_STDCALL
3216
    GDALOpenEx(const char *pszFilename, unsigned int nOpenFlags,
3217
               const char *const *papszAllowedDrivers,
3218
               const char *const *papszOpenOptions,
3219
               const char *const *papszSiblingFiles);
3220

3221
    //! @cond Doxygen_Suppress
3222
    static char **GetSearchPaths(const char *pszGDAL_DRIVER_PATH);
3223
    //! @endcond
3224

3225
  public:
3226
    GDALDriverManager();
3227
    ~GDALDriverManager();
3228

3229
    int GetDriverCount(void) const;
3230
    GDALDriver *GetDriver(int);
3231
    GDALDriver *GetDriverByName(const char *);
3232

3233
    int RegisterDriver(GDALDriver *);
3234
    void DeregisterDriver(GDALDriver *);
3235

3236
    // AutoLoadDrivers is a no-op if compiled with GDAL_NO_AUTOLOAD defined.
3237
    void AutoLoadDrivers();
3238
    void AutoSkipDrivers();
3239
    void ReorderDrivers();
3240
    static CPLErr LoadPlugin(const char *name);
3241

3242
    static void AutoLoadPythonDrivers();
3243

3244
    void DeclareDeferredPluginDriver(GDALPluginDriverProxy *poProxyDriver);
3245

3246
    //! @cond Doxygen_Suppress
3247
    int GetDriverCount(bool bIncludeHidden) const;
3248
    GDALDriver *GetDriver(int iDriver, bool bIncludeHidden);
3249
    bool IsKnownDriver(const char *pszDriverName) const;
3250
    GDALDriver *GetHiddenDriverByName(const char *pszName);
3251
    //! @endcond
3252
};
3253

3254
CPL_C_START
3255
GDALDriverManager CPL_DLL *GetGDALDriverManager(void);
3256
CPL_C_END
3257

3258
/* ******************************************************************** */
3259
/*                          GDALAsyncReader                             */
3260
/* ******************************************************************** */
3261

3262
/**
3263
 * Class used as a session object for asynchronous requests.  They are
3264
 * created with GDALDataset::BeginAsyncReader(), and destroyed with
3265
 * GDALDataset::EndAsyncReader().
3266
 */
3267
class CPL_DLL GDALAsyncReader
1✔
3268
{
3269

3270
    CPL_DISALLOW_COPY_ASSIGN(GDALAsyncReader)
3271

3272
  protected:
3273
    //! @cond Doxygen_Suppress
3274
    GDALDataset *poDS;
3275
    int nXOff;
3276
    int nYOff;
3277
    int nXSize;
3278
    int nYSize;
3279
    void *pBuf;
3280
    int nBufXSize;
3281
    int nBufYSize;
3282
    GDALDataType eBufType;
3283
    int nBandCount;
3284
    int *panBandMap;
3285
    int nPixelSpace;
3286
    int nLineSpace;
3287
    int nBandSpace;
3288
    //! @endcond
3289

3290
  public:
3291
    GDALAsyncReader();
3292
    virtual ~GDALAsyncReader();
3293

3294
    /** Return dataset.
3295
     * @return dataset
3296
     */
3297
    GDALDataset *GetGDALDataset()
3298
    {
3299
        return poDS;
3300
    }
3301

3302
    /** Return x offset.
3303
     * @return x offset.
3304
     */
3305
    int GetXOffset() const
3306
    {
3307
        return nXOff;
3308
    }
3309

3310
    /** Return y offset.
3311
     * @return y offset.
3312
     */
3313
    int GetYOffset() const
3314
    {
3315
        return nYOff;
3316
    }
3317

3318
    /** Return width.
3319
     * @return width
3320
     */
3321
    int GetXSize() const
3322
    {
3323
        return nXSize;
3324
    }
3325

3326
    /** Return height.
3327
     * @return height
3328
     */
3329
    int GetYSize() const
3330
    {
3331
        return nYSize;
3332
    }
3333

3334
    /** Return buffer.
3335
     * @return buffer
3336
     */
3337
    void *GetBuffer()
3338
    {
3339
        return pBuf;
3340
    }
3341

3342
    /** Return buffer width.
3343
     * @return buffer width.
3344
     */
3345
    int GetBufferXSize() const
3346
    {
3347
        return nBufXSize;
3348
    }
3349

3350
    /** Return buffer height.
3351
     * @return buffer height.
3352
     */
3353
    int GetBufferYSize() const
3354
    {
3355
        return nBufYSize;
3356
    }
3357

3358
    /** Return buffer data type.
3359
     * @return buffer data type.
3360
     */
3361
    GDALDataType GetBufferType() const
3362
    {
3363
        return eBufType;
3364
    }
3365

3366
    /** Return band count.
3367
     * @return band count
3368
     */
3369
    int GetBandCount() const
3370
    {
3371
        return nBandCount;
3372
    }
3373

3374
    /** Return band map.
3375
     * @return band map.
3376
     */
3377
    int *GetBandMap()
3378
    {
3379
        return panBandMap;
3380
    }
3381

3382
    /** Return pixel spacing.
3383
     * @return pixel spacing.
3384
     */
3385
    int GetPixelSpace() const
3386
    {
3387
        return nPixelSpace;
3388
    }
3389

3390
    /** Return line spacing.
3391
     * @return line spacing.
3392
     */
3393
    int GetLineSpace() const
3394
    {
3395
        return nLineSpace;
3396
    }
3397

3398
    /** Return band spacing.
3399
     * @return band spacing.
3400
     */
3401
    int GetBandSpace() const
3402
    {
3403
        return nBandSpace;
3404
    }
3405

3406
    virtual GDALAsyncStatusType
3407
    GetNextUpdatedRegion(double dfTimeout, int *pnBufXOff, int *pnBufYOff,
3408
                         int *pnBufXSize, int *pnBufYSize) = 0;
3409
    virtual int LockBuffer(double dfTimeout = -1.0);
3410
    virtual void UnlockBuffer();
3411
};
3412

3413
/* ******************************************************************** */
3414
/*                       Multidimensional array API                     */
3415
/* ******************************************************************** */
3416

3417
class GDALMDArray;
3418
class GDALAttribute;
3419
class GDALDimension;
3420
class GDALEDTComponent;
3421

3422
/* ******************************************************************** */
3423
/*                         GDALExtendedDataType                         */
3424
/* ******************************************************************** */
3425

3426
/**
3427
 * Class used to represent potentially complex data types.
3428
 * Several classes of data types are supported: numeric (based on GDALDataType),
3429
 * compound or string.
3430
 *
3431
 * @since GDAL 3.1
3432
 */
3433
class CPL_DLL GDALExtendedDataType
64,942✔
3434
{
3435
  public:
3436
    ~GDALExtendedDataType();
3437

3438
    GDALExtendedDataType(const GDALExtendedDataType &);
3439

3440
    GDALExtendedDataType &operator=(const GDALExtendedDataType &);
3441
    GDALExtendedDataType &operator=(GDALExtendedDataType &&);
3442

3443
    static GDALExtendedDataType Create(GDALDataType eType);
3444
    static GDALExtendedDataType
3445
    Create(const std::string &osName, GDALDataType eBaseType,
3446
           std::unique_ptr<GDALRasterAttributeTable>);
3447
    static GDALExtendedDataType
3448
    Create(const std::string &osName, size_t nTotalSize,
3449
           std::vector<std::unique_ptr<GDALEDTComponent>> &&components);
3450
    static GDALExtendedDataType
3451
    CreateString(size_t nMaxStringLength = 0,
3452
                 GDALExtendedDataTypeSubType eSubType = GEDTST_NONE);
3453

3454
    bool operator==(const GDALExtendedDataType &) const;
3455

3456
    /** Non-equality operator */
3457
    bool operator!=(const GDALExtendedDataType &other) const
1,058✔
3458
    {
3459
        return !(operator==(other));
1,058✔
3460
    }
3461

3462
    /** Return type name.
3463
     *
3464
     * This is the same as the C function GDALExtendedDataTypeGetName()
3465
     */
3466
    const std::string &GetName() const
21✔
3467
    {
3468
        return m_osName;
21✔
3469
    }
3470

3471
    /** Return type class.
3472
     *
3473
     * This is the same as the C function GDALExtendedDataTypeGetClass()
3474
     */
3475
    GDALExtendedDataTypeClass GetClass() const
305,028✔
3476
    {
3477
        return m_eClass;
305,028✔
3478
    }
3479

3480
    /** Return numeric data type (only valid when GetClass() == GEDTC_NUMERIC)
3481
     *
3482
     * This is the same as the C function
3483
     * GDALExtendedDataTypeGetNumericDataType()
3484
     */
3485
    GDALDataType GetNumericDataType() const
1,958,069✔
3486
    {
3487
        return m_eNumericDT;
1,958,069✔
3488
    }
3489

3490
    /** Return subtype.
3491
     *
3492
     * This is the same as the C function GDALExtendedDataTypeGetSubType()
3493
     *
3494
     * @since 3.4
3495
     */
3496
    GDALExtendedDataTypeSubType GetSubType() const
360✔
3497
    {
3498
        return m_eSubType;
360✔
3499
    }
3500

3501
    /** Return the components of the data type (only valid when GetClass() ==
3502
     * GEDTC_COMPOUND)
3503
     *
3504
     * This is the same as the C function GDALExtendedDataTypeGetComponents()
3505
     */
3506
    const std::vector<std::unique_ptr<GDALEDTComponent>> &GetComponents() const
1,215✔
3507
    {
3508
        return m_aoComponents;
1,215✔
3509
    }
3510

3511
    /** Return data type size in bytes.
3512
     *
3513
     * For a string, this will be size of a char* pointer.
3514
     *
3515
     * This is the same as the C function GDALExtendedDataTypeGetSize()
3516
     */
3517
    size_t GetSize() const
52,882✔
3518
    {
3519
        return m_nSize;
52,882✔
3520
    }
3521

3522
    /** Return the maximum length of a string in bytes.
3523
     *
3524
     * 0 indicates unknown/unlimited string.
3525
     */
3526
    size_t GetMaxStringLength() const
21✔
3527
    {
3528
        return m_nMaxStringLength;
21✔
3529
    }
3530

3531
    /** Return associated raster attribute table, when there is one.
3532
     *
3533
     * For the netCDF driver, the RAT will capture enumerated types, with
3534
     * a "value" column with an integer value and a "name" column with the
3535
     * associated name.
3536
     *
3537
     * This is the same as the C function GDALExtendedDataTypeGetRAT()
3538
     *
3539
     * @since 3.12
3540
     */
3541
    const GDALRasterAttributeTable *GetRAT() const
425✔
3542
    {
3543
        return m_poRAT.get();
425✔
3544
    }
3545

3546
    bool CanConvertTo(const GDALExtendedDataType &other) const;
3547

3548
    bool NeedsFreeDynamicMemory() const;
3549

3550
    void FreeDynamicMemory(void *pBuffer) const;
3551

3552
    static bool CopyValue(const void *pSrc, const GDALExtendedDataType &srcType,
3553
                          void *pDst, const GDALExtendedDataType &dstType);
3554

3555
    static bool CopyValues(const void *pSrc,
3556
                           const GDALExtendedDataType &srcType,
3557
                           GPtrDiff_t nSrcStrideInElts, void *pDst,
3558
                           const GDALExtendedDataType &dstType,
3559
                           GPtrDiff_t nDstStrideInElts, size_t nValues);
3560

3561
  private:
3562
    GDALExtendedDataType(size_t nMaxStringLength,
3563
                         GDALExtendedDataTypeSubType eSubType);
3564
    explicit GDALExtendedDataType(GDALDataType eType);
3565
    GDALExtendedDataType(const std::string &osName, GDALDataType eBaseType,
3566
                         std::unique_ptr<GDALRasterAttributeTable>);
3567
    GDALExtendedDataType(
3568
        const std::string &osName, size_t nTotalSize,
3569
        std::vector<std::unique_ptr<GDALEDTComponent>> &&components);
3570

3571
    std::string m_osName{};
3572
    GDALExtendedDataTypeClass m_eClass = GEDTC_NUMERIC;
3573
    GDALExtendedDataTypeSubType m_eSubType = GEDTST_NONE;
3574
    GDALDataType m_eNumericDT = GDT_Unknown;
3575
    std::vector<std::unique_ptr<GDALEDTComponent>> m_aoComponents{};
3576
    size_t m_nSize = 0;
3577
    size_t m_nMaxStringLength = 0;
3578
    std::unique_ptr<GDALRasterAttributeTable> m_poRAT{};
3579
};
3580

3581
/* ******************************************************************** */
3582
/*                            GDALEDTComponent                          */
3583
/* ******************************************************************** */
3584

3585
/**
3586
 * Class for a component of a compound extended data type.
3587
 *
3588
 * @since GDAL 3.1
3589
 */
3590
class CPL_DLL GDALEDTComponent
4,168✔
3591
{
3592
  public:
3593
    ~GDALEDTComponent();
3594
    GDALEDTComponent(const std::string &name, size_t offset,
3595
                     const GDALExtendedDataType &type);
3596
    GDALEDTComponent(const GDALEDTComponent &);
3597

3598
    bool operator==(const GDALEDTComponent &) const;
3599

3600
    /** Return the name.
3601
     *
3602
     * This is the same as the C function GDALEDTComponentGetName().
3603
     */
3604
    const std::string &GetName() const
3,607✔
3605
    {
3606
        return m_osName;
3,607✔
3607
    }
3608

3609
    /** Return the offset (in bytes) of the component in the compound data type.
3610
     *
3611
     * This is the same as the C function GDALEDTComponentGetOffset().
3612
     */
3613
    size_t GetOffset() const
8,793✔
3614
    {
3615
        return m_nOffset;
8,793✔
3616
    }
3617

3618
    /** Return the data type of the component.
3619
     *
3620
     * This is the same as the C function GDALEDTComponentGetType().
3621
     */
3622
    const GDALExtendedDataType &GetType() const
8,015✔
3623
    {
3624
        return m_oType;
8,015✔
3625
    }
3626

3627
  private:
3628
    std::string m_osName;
3629
    size_t m_nOffset;
3630
    GDALExtendedDataType m_oType;
3631
};
3632

3633
/* ******************************************************************** */
3634
/*                            GDALIHasAttribute                         */
3635
/* ******************************************************************** */
3636

3637
/**
3638
 * Interface used to get a single GDALAttribute or a set of GDALAttribute
3639
 *
3640
 * @since GDAL 3.1
3641
 */
3642
class CPL_DLL GDALIHasAttribute
13,481✔
3643
{
3644
  protected:
3645
    std::shared_ptr<GDALAttribute>
3646
    GetAttributeFromAttributes(const std::string &osName) const;
3647

3648
  public:
3649
    virtual ~GDALIHasAttribute();
3650

3651
    virtual std::shared_ptr<GDALAttribute>
3652
    GetAttribute(const std::string &osName) const;
3653

3654
    virtual std::vector<std::shared_ptr<GDALAttribute>>
3655
    GetAttributes(CSLConstList papszOptions = nullptr) const;
3656

3657
    virtual std::shared_ptr<GDALAttribute>
3658
    CreateAttribute(const std::string &osName,
3659
                    const std::vector<GUInt64> &anDimensions,
3660
                    const GDALExtendedDataType &oDataType,
3661
                    CSLConstList papszOptions = nullptr);
3662

3663
    virtual bool DeleteAttribute(const std::string &osName,
3664
                                 CSLConstList papszOptions = nullptr);
3665
};
3666

3667
/* ******************************************************************** */
3668
/*                               GDALGroup                              */
3669
/* ******************************************************************** */
3670

3671
/* clang-format off */
3672
/**
3673
 * Class modeling a named container of GDALAttribute, GDALMDArray, OGRLayer or
3674
 * other GDALGroup. Hence GDALGroup can describe a hierarchy of objects.
3675
 *
3676
 * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_group">HDF5 group
3677
 * concept</a>
3678
 *
3679
 * @since GDAL 3.1
3680
 */
3681
/* clang-format on */
3682

3683
class CPL_DLL GDALGroup : public GDALIHasAttribute
6,915✔
3684
{
3685
  protected:
3686
    //! @cond Doxygen_Suppress
3687
    std::string m_osName{};
3688

3689
    // This is actually a path of the form "/parent_path/{m_osName}"
3690
    std::string m_osFullName{};
3691

3692
    // Used for example by GDALSubsetGroup to distinguish a derived group
3693
    //from its original, without altering its name
3694
    const std::string m_osContext{};
3695

3696
    // List of types owned by the group.
3697
    std::vector<std::shared_ptr<GDALExtendedDataType>> m_apoTypes{};
3698

3699
    //! Weak pointer to this
3700
    std::weak_ptr<GDALGroup> m_pSelf{};
3701

3702
    //! Can be set to false by the owing group, when deleting this object
3703
    bool m_bValid = true;
3704

3705
    GDALGroup(const std::string &osParentName, const std::string &osName,
3706
              const std::string &osContext = std::string());
3707

3708
    const GDALGroup *
3709
    GetInnerMostGroup(const std::string &osPathOrArrayOrDim,
3710
                      std::shared_ptr<GDALGroup> &curGroupHolder,
3711
                      std::string &osLastPart) const;
3712

3713
    void BaseRename(const std::string &osNewName);
3714

3715
    bool CheckValidAndErrorOutIfNot() const;
3716

3717
    void SetSelf(const std::shared_ptr<GDALGroup> &self)
6,049✔
3718
    {
3719
        m_pSelf = self;
6,049✔
3720
    }
6,049✔
3721

3722
    virtual void NotifyChildrenOfRenaming()
×
3723
    {
3724
    }
×
3725

3726
    virtual void NotifyChildrenOfDeletion()
×
3727
    {
3728
    }
×
3729

3730
    //! @endcond
3731

3732
  public:
3733
    virtual ~GDALGroup();
3734

3735
    /** Return the name of the group.
3736
     *
3737
     * This is the same as the C function GDALGroupGetName().
3738
     */
3739
    const std::string &GetName() const
1,052✔
3740
    {
3741
        return m_osName;
1,052✔
3742
    }
3743

3744
    /** Return the full name of the group.
3745
     *
3746
     * This is the same as the C function GDALGroupGetFullName().
3747
     */
3748
    const std::string &GetFullName() const
24,283✔
3749
    {
3750
        return m_osFullName;
24,283✔
3751
    }
3752

3753
    /** Return data types associated with the group (typically enumerations)
3754
     *
3755
     * This is the same as the C function GDALGroupGetDataTypeCount() and GDALGroupGetDataType()
3756
     *
3757
     * @since 3.12
3758
     */
3759
    const std::vector<std::shared_ptr<GDALExtendedDataType>> &
3760
    GetDataTypes() const
55✔
3761
    {
3762
        return m_apoTypes;
55✔
3763
    }
3764

3765
    virtual std::vector<std::string>
3766
    GetMDArrayNames(CSLConstList papszOptions = nullptr) const;
3767
    virtual std::shared_ptr<GDALMDArray>
3768
    OpenMDArray(const std::string &osName,
3769
                CSLConstList papszOptions = nullptr) const;
3770

3771
    std::vector<std::string> GetMDArrayFullNamesRecursive(
3772
        CSLConstList papszGroupOptions = nullptr,
3773
        CSLConstList papszArrayOptions = nullptr) const;
3774

3775
    virtual std::vector<std::string>
3776
    GetGroupNames(CSLConstList papszOptions = nullptr) const;
3777
    virtual std::shared_ptr<GDALGroup>
3778
    OpenGroup(const std::string &osName,
3779
              CSLConstList papszOptions = nullptr) const;
3780

3781
    virtual std::vector<std::string>
3782
    GetVectorLayerNames(CSLConstList papszOptions = nullptr) const;
3783
    virtual OGRLayer *
3784
    OpenVectorLayer(const std::string &osName,
3785
                    CSLConstList papszOptions = nullptr) const;
3786

3787
    virtual std::vector<std::shared_ptr<GDALDimension>>
3788
    GetDimensions(CSLConstList papszOptions = nullptr) const;
3789

3790
    virtual std::shared_ptr<GDALGroup>
3791
    CreateGroup(const std::string &osName, CSLConstList papszOptions = nullptr);
3792

3793
    virtual bool DeleteGroup(const std::string &osName,
3794
                             CSLConstList papszOptions = nullptr);
3795

3796
    virtual std::shared_ptr<GDALDimension>
3797
    CreateDimension(const std::string &osName, const std::string &osType,
3798
                    const std::string &osDirection, GUInt64 nSize,
3799
                    CSLConstList papszOptions = nullptr);
3800

3801
    virtual std::shared_ptr<GDALMDArray> CreateMDArray(
3802
        const std::string &osName,
3803
        const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
3804
        const GDALExtendedDataType &oDataType,
3805
        CSLConstList papszOptions = nullptr);
3806

3807
    virtual bool DeleteMDArray(const std::string &osName,
3808
                               CSLConstList papszOptions = nullptr);
3809

3810
    GUInt64 GetTotalCopyCost() const;
3811

3812
    virtual bool CopyFrom(const std::shared_ptr<GDALGroup> &poDstRootGroup,
3813
                          GDALDataset *poSrcDS,
3814
                          const std::shared_ptr<GDALGroup> &poSrcGroup,
3815
                          bool bStrict, GUInt64 &nCurCost,
3816
                          const GUInt64 nTotalCost,
3817
                          GDALProgressFunc pfnProgress, void *pProgressData,
3818
                          CSLConstList papszOptions = nullptr);
3819

3820
    virtual CSLConstList GetStructuralInfo() const;
3821

3822
    std::shared_ptr<GDALMDArray>
3823
    OpenMDArrayFromFullname(const std::string &osFullName,
3824
                            CSLConstList papszOptions = nullptr) const;
3825

3826
    std::shared_ptr<GDALAttribute>
3827
    OpenAttributeFromFullname(const std::string &osFullName,
3828
                              CSLConstList papszOptions = nullptr) const;
3829

3830
    std::shared_ptr<GDALMDArray>
3831
    ResolveMDArray(const std::string &osName, const std::string &osStartingPath,
3832
                   CSLConstList papszOptions = nullptr) const;
3833

3834
    std::shared_ptr<GDALGroup>
3835
    OpenGroupFromFullname(const std::string &osFullName,
3836
                          CSLConstList papszOptions = nullptr) const;
3837

3838
    std::shared_ptr<GDALDimension>
3839
    OpenDimensionFromFullname(const std::string &osFullName) const;
3840

3841
    virtual void ClearStatistics();
3842

3843
    virtual bool Rename(const std::string &osNewName);
3844

3845
    std::shared_ptr<GDALGroup>
3846
    SubsetDimensionFromSelection(const std::string &osSelection) const;
3847

3848
    //! @cond Doxygen_Suppress
3849
    virtual void ParentRenamed(const std::string &osNewParentFullName);
3850

3851
    virtual void Deleted();
3852

3853
    virtual void ParentDeleted();
3854

3855
    const std::string &GetContext() const
23✔
3856
    {
3857
        return m_osContext;
23✔
3858
    }
3859

3860
    //! @endcond
3861

3862
    //! @cond Doxygen_Suppress
3863
    static constexpr GUInt64 COPY_COST = 1000;
3864
    //! @endcond
3865
};
3866

3867
/* ******************************************************************** */
3868
/*                          GDALAbstractMDArray                         */
3869
/* ******************************************************************** */
3870

3871
/**
3872
 * Abstract class, implemented by GDALAttribute and GDALMDArray.
3873
 *
3874
 * @since GDAL 3.1
3875
 */
3876
class CPL_DLL GDALAbstractMDArray
20,965✔
3877
{
3878
  protected:
3879
    //! @cond Doxygen_Suppress
3880
    std::string m_osName{};
3881

3882
    // This is actually a path of the form "/parent_path/{m_osName}"
3883
    std::string m_osFullName{};
3884
    std::weak_ptr<GDALAbstractMDArray> m_pSelf{};
3885

3886
    //! Can be set to false by the owing object, when deleting this object
3887
    bool m_bValid = true;
3888

3889
    GDALAbstractMDArray(const std::string &osParentName,
3890
                        const std::string &osName);
3891

3892
    void SetSelf(const std::shared_ptr<GDALAbstractMDArray> &self)
8,344✔
3893
    {
3894
        m_pSelf = self;
8,344✔
3895
    }
8,344✔
3896

3897
    bool CheckValidAndErrorOutIfNot() const;
3898

3899
    bool CheckReadWriteParams(const GUInt64 *arrayStartIdx, const size_t *count,
3900
                              const GInt64 *&arrayStep,
3901
                              const GPtrDiff_t *&bufferStride,
3902
                              const GDALExtendedDataType &bufferDataType,
3903
                              const void *buffer,
3904
                              const void *buffer_alloc_start,
3905
                              size_t buffer_alloc_size,
3906
                              std::vector<GInt64> &tmp_arrayStep,
3907
                              std::vector<GPtrDiff_t> &tmp_bufferStride) const;
3908

3909
    virtual bool
3910
    IRead(const GUInt64 *arrayStartIdx,    // array of size GetDimensionCount()
3911
          const size_t *count,             // array of size GetDimensionCount()
3912
          const GInt64 *arrayStep,         // step in elements
3913
          const GPtrDiff_t *bufferStride,  // stride in elements
3914
          const GDALExtendedDataType &bufferDataType,
3915
          void *pDstBuffer) const = 0;
3916

3917
    virtual bool
3918
    IWrite(const GUInt64 *arrayStartIdx,    // array of size GetDimensionCount()
3919
           const size_t *count,             // array of size GetDimensionCount()
3920
           const GInt64 *arrayStep,         // step in elements
3921
           const GPtrDiff_t *bufferStride,  // stride in elements
3922
           const GDALExtendedDataType &bufferDataType, const void *pSrcBuffer);
3923

3924
    void BaseRename(const std::string &osNewName);
3925

3926
    virtual void NotifyChildrenOfRenaming()
47✔
3927
    {
3928
    }
47✔
3929

3930
    virtual void NotifyChildrenOfDeletion()
42✔
3931
    {
3932
    }
42✔
3933

3934
    //! @endcond
3935

3936
  public:
3937
    virtual ~GDALAbstractMDArray();
3938

3939
    /** Return the name of an array or attribute.
3940
     *
3941
     * This is the same as the C function GDALMDArrayGetName() or
3942
     * GDALAttributeGetName().
3943
     */
3944
    const std::string &GetName() const
19,408✔
3945
    {
3946
        return m_osName;
19,408✔
3947
    }
3948

3949
    /** Return the name of an array or attribute.
3950
     *
3951
     * This is the same as the C function GDALMDArrayGetFullName() or
3952
     * GDALAttributeGetFullName().
3953
     */
3954
    const std::string &GetFullName() const
12,813✔
3955
    {
3956
        return m_osFullName;
12,813✔
3957
    }
3958

3959
    GUInt64 GetTotalElementsCount() const;
3960

3961
    virtual size_t GetDimensionCount() const;
3962

3963
    virtual const std::vector<std::shared_ptr<GDALDimension>> &
3964
    GetDimensions() const = 0;
3965

3966
    virtual const GDALExtendedDataType &GetDataType() const = 0;
3967

3968
    virtual std::vector<GUInt64> GetBlockSize() const;
3969

3970
    virtual std::vector<size_t>
3971
    GetProcessingChunkSize(size_t nMaxChunkMemory) const;
3972

3973
    /* clang-format off */
3974
    /** Type of pfnFunc argument of ProcessPerChunk().
3975
     * @param array Array on which ProcessPerChunk was called.
3976
     * @param chunkArrayStartIdx Values representing the starting index to use
3977
     *                           in each dimension (in [0, aoDims[i].GetSize()-1] range)
3978
     *                           for the current chunk.
3979
     *                           Will be nullptr for a zero-dimensional array.
3980
     * @param chunkCount         Values representing the number of values to use in
3981
     *                           each dimension for the current chunk.
3982
     *                           Will be nullptr for a zero-dimensional array.
3983
     * @param iCurChunk          Number of current chunk being processed.
3984
     *                           In [1, nChunkCount] range.
3985
     * @param nChunkCount        Total number of chunks to process.
3986
     * @param pUserData          User data.
3987
     * @return return true in case of success.
3988
     */
3989
    typedef bool (*FuncProcessPerChunkType)(
3990
                        GDALAbstractMDArray *array,
3991
                        const GUInt64 *chunkArrayStartIdx,
3992
                        const size_t *chunkCount,
3993
                        GUInt64 iCurChunk,
3994
                        GUInt64 nChunkCount,
3995
                        void *pUserData);
3996
    /* clang-format on */
3997

3998
    virtual bool ProcessPerChunk(const GUInt64 *arrayStartIdx,
3999
                                 const GUInt64 *count, const size_t *chunkSize,
4000
                                 FuncProcessPerChunkType pfnFunc,
4001
                                 void *pUserData);
4002

4003
    virtual bool
4004
    Read(const GUInt64 *arrayStartIdx,    // array of size GetDimensionCount()
4005
         const size_t *count,             // array of size GetDimensionCount()
4006
         const GInt64 *arrayStep,         // step in elements
4007
         const GPtrDiff_t *bufferStride,  // stride in elements
4008
         const GDALExtendedDataType &bufferDataType, void *pDstBuffer,
4009
         const void *pDstBufferAllocStart = nullptr,
4010
         size_t nDstBufferAllocSize = 0) const;
4011

4012
    bool
4013
    Write(const GUInt64 *arrayStartIdx,    // array of size GetDimensionCount()
4014
          const size_t *count,             // array of size GetDimensionCount()
4015
          const GInt64 *arrayStep,         // step in elements
4016
          const GPtrDiff_t *bufferStride,  // stride in elements
4017
          const GDALExtendedDataType &bufferDataType, const void *pSrcBuffer,
4018
          const void *pSrcBufferAllocStart = nullptr,
4019
          size_t nSrcBufferAllocSize = 0);
4020

4021
    virtual bool Rename(const std::string &osNewName);
4022

4023
    //! @cond Doxygen_Suppress
4024
    virtual void Deleted();
4025

4026
    virtual void ParentDeleted();
4027

4028
    virtual void ParentRenamed(const std::string &osNewParentFullName);
4029
    //! @endcond
4030
};
4031

4032
/* ******************************************************************** */
4033
/*                              GDALRawResult                           */
4034
/* ******************************************************************** */
4035

4036
/**
4037
 * Store the raw result of an attribute value, which might contain dynamically
4038
 * allocated structures (like pointer to strings).
4039
 *
4040
 * @since GDAL 3.1
4041
 */
4042
class CPL_DLL GDALRawResult
4043
{
4044
  private:
4045
    GDALExtendedDataType m_dt;
4046
    size_t m_nEltCount;
4047
    size_t m_nSize;
4048
    GByte *m_raw;
4049

4050
    void FreeMe();
4051

4052
    GDALRawResult(const GDALRawResult &) = delete;
4053
    GDALRawResult &operator=(const GDALRawResult &) = delete;
4054

4055
  protected:
4056
    friend class GDALAttribute;
4057
    //! @cond Doxygen_Suppress
4058
    GDALRawResult(GByte *raw, const GDALExtendedDataType &dt, size_t nEltCount);
4059
    //! @endcond
4060

4061
  public:
4062
    ~GDALRawResult();
4063
    GDALRawResult(GDALRawResult &&);
4064
    GDALRawResult &operator=(GDALRawResult &&);
4065

4066
    /** Return byte at specified index. */
4067
    const GByte &operator[](size_t idx) const
4068
    {
4069
        return m_raw[idx];
4070
    }
4071

4072
    /** Return pointer to the start of data. */
4073
    const GByte *data() const
343✔
4074
    {
4075
        return m_raw;
343✔
4076
    }
4077

4078
    /** Return the size in bytes of the raw result. */
4079
    size_t size() const
125✔
4080
    {
4081
        return m_nSize;
125✔
4082
    }
4083

4084
    //! @cond Doxygen_Suppress
4085
    GByte *StealData();
4086
    //! @endcond
4087
};
4088

4089
/* ******************************************************************** */
4090
/*                              GDALAttribute                           */
4091
/* ******************************************************************** */
4092

4093
/* clang-format off */
4094
/**
4095
 * Class modeling an attribute that has a name, a value and a type, and is
4096
 * typically used to describe a metadata item. The value can be (for the
4097
 * HDF5 format) in the general case a multidimensional array of "any" type
4098
 * (in most cases, this will be a single value of string or numeric type)
4099
 *
4100
 * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_attribute">HDF5
4101
 * attribute concept</a>
4102
 *
4103
 * @since GDAL 3.1
4104
 */
4105
/* clang-format on */
4106

4107
class CPL_DLL GDALAttribute : virtual public GDALAbstractMDArray
14,399✔
4108
{
4109
    mutable std::string m_osCachedVal{};
4110

4111
  protected:
4112
    //! @cond Doxygen_Suppress
4113
    GDALAttribute(const std::string &osParentName, const std::string &osName);
4114
    //! @endcond
4115

4116
  public:
4117
    //! @cond Doxygen_Suppress
4118
    ~GDALAttribute();
4119
    //! @endcond
4120

4121
    std::vector<GUInt64> GetDimensionsSize() const;
4122

4123
    GDALRawResult ReadAsRaw() const;
4124
    const char *ReadAsString() const;
4125
    int ReadAsInt() const;
4126
    int64_t ReadAsInt64() const;
4127
    double ReadAsDouble() const;
4128
    CPLStringList ReadAsStringArray() const;
4129
    std::vector<int> ReadAsIntArray() const;
4130
    std::vector<int64_t> ReadAsInt64Array() const;
4131
    std::vector<double> ReadAsDoubleArray() const;
4132

4133
    using GDALAbstractMDArray::Write;
4134
    bool Write(const void *pabyValue, size_t nLen);
4135
    bool Write(const char *);
4136
    bool WriteInt(int);
4137
    bool WriteInt64(int64_t);
4138
    bool Write(double);
4139
    bool Write(CSLConstList);
4140
    bool Write(const int *, size_t);
4141
    bool Write(const int64_t *, size_t);
4142
    bool Write(const double *, size_t);
4143

4144
    //! @cond Doxygen_Suppress
4145
    static constexpr GUInt64 COPY_COST = 100;
4146
    //! @endcond
4147
};
4148

4149
/************************************************************************/
4150
/*                            GDALAttributeString                       */
4151
/************************************************************************/
4152

4153
//! @cond Doxygen_Suppress
4154
class CPL_DLL GDALAttributeString final : public GDALAttribute
4155
{
4156
    std::vector<std::shared_ptr<GDALDimension>> m_dims{};
4157
    GDALExtendedDataType m_dt = GDALExtendedDataType::CreateString();
4158
    std::string m_osValue;
4159

4160
  protected:
4161
    bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
4162
               const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
4163
               void *pDstBuffer) const override;
4164

4165
  public:
4166
    GDALAttributeString(const std::string &osParentName,
4167
                        const std::string &osName, const std::string &osValue,
4168
                        GDALExtendedDataTypeSubType eSubType = GEDTST_NONE);
4169

4170
    const std::vector<std::shared_ptr<GDALDimension>> &
4171
    GetDimensions() const override;
4172

4173
    const GDALExtendedDataType &GetDataType() const override;
4174
};
4175

4176
//! @endcond
4177

4178
/************************************************************************/
4179
/*                           GDALAttributeNumeric                       */
4180
/************************************************************************/
4181

4182
//! @cond Doxygen_Suppress
4183
class CPL_DLL GDALAttributeNumeric final : public GDALAttribute
4184
{
4185
    std::vector<std::shared_ptr<GDALDimension>> m_dims{};
4186
    GDALExtendedDataType m_dt;
4187
    int m_nValue = 0;
4188
    double m_dfValue = 0;
4189
    std::vector<GUInt32> m_anValuesUInt32{};
4190

4191
  protected:
4192
    bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
4193
               const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
4194
               void *pDstBuffer) const override;
4195

4196
  public:
4197
    GDALAttributeNumeric(const std::string &osParentName,
4198
                         const std::string &osName, double dfValue);
4199
    GDALAttributeNumeric(const std::string &osParentName,
4200
                         const std::string &osName, int nValue);
4201
    GDALAttributeNumeric(const std::string &osParentName,
4202
                         const std::string &osName,
4203
                         const std::vector<GUInt32> &anValues);
4204

4205
    const std::vector<std::shared_ptr<GDALDimension>> &
4206
    GetDimensions() const override;
4207

4208
    const GDALExtendedDataType &GetDataType() const override;
4209
};
4210

4211
//! @endcond
4212

4213
/* ******************************************************************** */
4214
/*                              GDALMDArray                             */
4215
/* ******************************************************************** */
4216

4217
/* clang-format off */
4218
/**
4219
 * Class modeling a multi-dimensional array. It has a name, values organized
4220
 * as an array and a list of GDALAttribute.
4221
 *
4222
 * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_dataset">HDF5
4223
 * dataset concept</a>
4224
 *
4225
 * @since GDAL 3.1
4226
 */
4227
/* clang-format on */
4228

4229
class CPL_DLL GDALMDArray : virtual public GDALAbstractMDArray,
4230
                            public GDALIHasAttribute
4231
{
4232
    friend class GDALMDArrayResampled;
4233
    std::shared_ptr<GDALMDArray>
4234
    GetView(const std::vector<GUInt64> &indices) const;
4235

4236
    inline std::shared_ptr<GDALMDArray>
4237
    atInternal(const std::vector<GUInt64> &indices) const
19✔
4238
    {
4239
        return GetView(indices);
19✔
4240
    }
4241

4242
    template <typename... GUInt64VarArg>
4243
    // cppcheck-suppress functionStatic
4244
    inline std::shared_ptr<GDALMDArray>
4245
    atInternal(std::vector<GUInt64> &indices, GUInt64 idx,
7✔
4246
               GUInt64VarArg... tail) const
4247
    {
4248
        indices.push_back(idx);
7✔
4249
        return atInternal(indices, tail...);
7✔
4250
    }
4251

4252
    // Used for example by GDALSubsetGroup to distinguish a derived group
4253
    //from its original, without altering its name
4254
    const std::string m_osContext{};
4255

4256
    mutable bool m_bHasTriedCachedArray = false;
4257
    mutable std::shared_ptr<GDALMDArray> m_poCachedArray{};
4258

4259
  protected:
4260
    //! @cond Doxygen_Suppress
4261
    GDALMDArray(const std::string &osParentName, const std::string &osName,
4262
                const std::string &osContext = std::string());
4263

4264
    virtual bool IAdviseRead(const GUInt64 *arrayStartIdx, const size_t *count,
4265
                             CSLConstList papszOptions) const;
4266

4267
    virtual bool IsCacheable() const
1,748✔
4268
    {
4269
        return true;
1,748✔
4270
    }
4271

4272
    virtual bool SetStatistics(bool bApproxStats, double dfMin, double dfMax,
4273
                               double dfMean, double dfStdDev,
4274
                               GUInt64 nValidCount, CSLConstList papszOptions);
4275

4276
    static std::string MassageName(const std::string &inputName);
4277

4278
    std::shared_ptr<GDALGroup>
4279
    GetCacheRootGroup(bool bCanCreate, std::string &osCacheFilenameOut) const;
4280

4281
    // Returns if bufferStride values express a transposed view of the array
4282
    bool IsTransposedRequest(const size_t *count,
4283
                             const GPtrDiff_t *bufferStride) const;
4284

4285
    // Should only be called if IsTransposedRequest() returns true
4286
    bool ReadForTransposedRequest(const GUInt64 *arrayStartIdx,
4287
                                  const size_t *count, const GInt64 *arrayStep,
4288
                                  const GPtrDiff_t *bufferStride,
4289
                                  const GDALExtendedDataType &bufferDataType,
4290
                                  void *pDstBuffer) const;
4291

4292
    bool IsStepOneContiguousRowMajorOrderedSameDataType(
4293
        const size_t *count, const GInt64 *arrayStep,
4294
        const GPtrDiff_t *bufferStride,
4295
        const GDALExtendedDataType &bufferDataType) const;
4296

4297
    // Should only be called if IsStepOneContiguousRowMajorOrderedSameDataType()
4298
    // returns false
4299
    bool ReadUsingContiguousIRead(const GUInt64 *arrayStartIdx,
4300
                                  const size_t *count, const GInt64 *arrayStep,
4301
                                  const GPtrDiff_t *bufferStride,
4302
                                  const GDALExtendedDataType &bufferDataType,
4303
                                  void *pDstBuffer) const;
4304

4305
    static std::shared_ptr<GDALMDArray> CreateGLTOrthorectified(
4306
        const std::shared_ptr<GDALMDArray> &poParent,
4307
        const std::shared_ptr<GDALGroup> &poRootGroup,
4308
        const std::shared_ptr<GDALMDArray> &poGLTX,
4309
        const std::shared_ptr<GDALMDArray> &poGLTY, int nGLTIndexOffset,
4310
        const std::vector<double> &adfGeoTransform, CSLConstList papszOptions);
4311

4312
    //! @endcond
4313

4314
  public:
4315
    GUInt64 GetTotalCopyCost() const;
4316

4317
    virtual bool CopyFrom(GDALDataset *poSrcDS, const GDALMDArray *poSrcArray,
4318
                          bool bStrict, GUInt64 &nCurCost,
4319
                          const GUInt64 nTotalCost,
4320
                          GDALProgressFunc pfnProgress, void *pProgressData);
4321

4322
    /** Return whether an array is writable. */
4323
    virtual bool IsWritable() const = 0;
4324

4325
    /** Return the filename that contains that array.
4326
     *
4327
     * This is used in particular for caching.
4328
     *
4329
     * Might be empty if the array is not linked to a file.
4330
     *
4331
     * @since GDAL 3.4
4332
     */
4333
    virtual const std::string &GetFilename() const = 0;
4334

4335
    virtual CSLConstList GetStructuralInfo() const;
4336

4337
    virtual const std::string &GetUnit() const;
4338

4339
    virtual bool SetUnit(const std::string &osUnit);
4340

4341
    virtual bool SetSpatialRef(const OGRSpatialReference *poSRS);
4342

4343
    virtual std::shared_ptr<OGRSpatialReference> GetSpatialRef() const;
4344

4345
    virtual const void *GetRawNoDataValue() const;
4346

4347
    double GetNoDataValueAsDouble(bool *pbHasNoData = nullptr) const;
4348

4349
    int64_t GetNoDataValueAsInt64(bool *pbHasNoData = nullptr) const;
4350

4351
    uint64_t GetNoDataValueAsUInt64(bool *pbHasNoData = nullptr) const;
4352

4353
    virtual bool SetRawNoDataValue(const void *pRawNoData);
4354

4355
    //! @cond Doxygen_Suppress
4356
    bool SetNoDataValue(int nNoData)
2✔
4357
    {
4358
        return SetNoDataValue(static_cast<int64_t>(nNoData));
2✔
4359
    }
4360

4361
    //! @endcond
4362

4363
    bool SetNoDataValue(double dfNoData);
4364

4365
    bool SetNoDataValue(int64_t nNoData);
4366

4367
    bool SetNoDataValue(uint64_t nNoData);
4368

4369
    virtual bool Resize(const std::vector<GUInt64> &anNewDimSizes,
4370
                        CSLConstList papszOptions);
4371

4372
    virtual double GetOffset(bool *pbHasOffset = nullptr,
4373
                             GDALDataType *peStorageType = nullptr) const;
4374

4375
    virtual double GetScale(bool *pbHasScale = nullptr,
4376
                            GDALDataType *peStorageType = nullptr) const;
4377

4378
    virtual bool SetOffset(double dfOffset,
4379
                           GDALDataType eStorageType = GDT_Unknown);
4380

4381
    virtual bool SetScale(double dfScale,
4382
                          GDALDataType eStorageType = GDT_Unknown);
4383

4384
    std::shared_ptr<GDALMDArray> GetView(const std::string &viewExpr) const;
4385

4386
    std::shared_ptr<GDALMDArray> operator[](const std::string &fieldName) const;
4387

4388
    /** Return a view of the array using integer indexing.
4389
     *
4390
     * Equivalent of GetView("[indices_0,indices_1,.....,indices_last]")
4391
     *
4392
     * Example:
4393
     * \code
4394
     * ar->at(0,3,2)
4395
     * \endcode
4396
     */
4397
    // sphinx 4.1.0 / breathe 4.30.0 don't like typename...
4398
    //! @cond Doxygen_Suppress
4399
    template <typename... GUInt64VarArg>
4400
    //! @endcond
4401
    // cppcheck-suppress functionStatic
4402
    std::shared_ptr<GDALMDArray> at(GUInt64 idx, GUInt64VarArg... tail) const
19✔
4403
    {
4404
        std::vector<GUInt64> indices;
38✔
4405
        indices.push_back(idx);
19✔
4406
        return atInternal(indices, tail...);
38✔
4407
    }
4408

4409
    virtual std::shared_ptr<GDALMDArray>
4410
    Transpose(const std::vector<int> &anMapNewAxisToOldAxis) const;
4411

4412
    std::shared_ptr<GDALMDArray> GetUnscaled(
4413
        double dfOverriddenScale = std::numeric_limits<double>::quiet_NaN(),
4414
        double dfOverriddenOffset = std::numeric_limits<double>::quiet_NaN(),
4415
        double dfOverriddenDstNodata =
4416
            std::numeric_limits<double>::quiet_NaN()) const;
4417

4418
    virtual std::shared_ptr<GDALMDArray>
4419
    GetMask(CSLConstList papszOptions) const;
4420

4421
    virtual std::shared_ptr<GDALMDArray>
4422
    GetResampled(const std::vector<std::shared_ptr<GDALDimension>> &apoNewDims,
4423
                 GDALRIOResampleAlg resampleAlg,
4424
                 const OGRSpatialReference *poTargetSRS,
4425
                 CSLConstList papszOptions) const;
4426

4427
    std::shared_ptr<GDALMDArray>
4428
    GetGridded(const std::string &osGridOptions,
4429
               const std::shared_ptr<GDALMDArray> &poXArray = nullptr,
4430
               const std::shared_ptr<GDALMDArray> &poYArray = nullptr,
4431
               CSLConstList papszOptions = nullptr) const;
4432

4433
    static std::vector<std::shared_ptr<GDALMDArray>>
4434
    GetMeshGrid(const std::vector<std::shared_ptr<GDALMDArray>> &apoArrays,
4435
                CSLConstList papszOptions = nullptr);
4436

4437
    virtual GDALDataset *
4438
    AsClassicDataset(size_t iXDim, size_t iYDim,
4439
                     const std::shared_ptr<GDALGroup> &poRootGroup = nullptr,
4440
                     CSLConstList papszOptions = nullptr) const;
4441

4442
    virtual CPLErr GetStatistics(bool bApproxOK, bool bForce, double *pdfMin,
4443
                                 double *pdfMax, double *pdfMean,
4444
                                 double *padfStdDev, GUInt64 *pnValidCount,
4445
                                 GDALProgressFunc pfnProgress,
4446
                                 void *pProgressData);
4447

4448
    virtual bool ComputeStatistics(bool bApproxOK, double *pdfMin,
4449
                                   double *pdfMax, double *pdfMean,
4450
                                   double *pdfStdDev, GUInt64 *pnValidCount,
4451
                                   GDALProgressFunc, void *pProgressData,
4452
                                   CSLConstList papszOptions);
4453

4454
    virtual void ClearStatistics();
4455

4456
    virtual std::vector<std::shared_ptr<GDALMDArray>>
4457
    GetCoordinateVariables() const;
4458

4459
    bool AdviseRead(const GUInt64 *arrayStartIdx, const size_t *count,
4460
                    CSLConstList papszOptions = nullptr) const;
4461

4462
    bool IsRegularlySpaced(double &dfStart, double &dfIncrement) const;
4463

4464
    bool GuessGeoTransform(size_t nDimX, size_t nDimY, bool bPixelIsPoint,
4465
                           GDALGeoTransform &gt) const;
4466

4467
    bool GuessGeoTransform(size_t nDimX, size_t nDimY, bool bPixelIsPoint,
4468
                           double adfGeoTransform[6]) const;
4469

4470
    bool Cache(CSLConstList papszOptions = nullptr) const;
4471

4472
    bool
4473
    Read(const GUInt64 *arrayStartIdx,    // array of size GetDimensionCount()
4474
         const size_t *count,             // array of size GetDimensionCount()
4475
         const GInt64 *arrayStep,         // step in elements
4476
         const GPtrDiff_t *bufferStride,  // stride in elements
4477
         const GDALExtendedDataType &bufferDataType, void *pDstBuffer,
4478
         const void *pDstBufferAllocStart = nullptr,
4479
         size_t nDstBufferAllocSize = 0) const override final;
4480

4481
    virtual std::shared_ptr<GDALGroup> GetRootGroup() const;
4482

4483
    //! @cond Doxygen_Suppress
4484
    static constexpr GUInt64 COPY_COST = 1000;
4485

4486
    bool CopyFromAllExceptValues(const GDALMDArray *poSrcArray, bool bStrict,
4487
                                 GUInt64 &nCurCost, const GUInt64 nTotalCost,
4488
                                 GDALProgressFunc pfnProgress,
4489
                                 void *pProgressData);
4490

4491
    struct Range
4492
    {
4493
        GUInt64 m_nStartIdx;
4494
        GInt64 m_nIncr;
4495

4496
        explicit Range(GUInt64 nStartIdx = 0, GInt64 nIncr = 0)
1,331✔
4497
            : m_nStartIdx(nStartIdx), m_nIncr(nIncr)
1,331✔
4498
        {
4499
        }
1,331✔
4500
    };
4501

4502
    struct ViewSpec
4503
    {
4504
        std::string m_osFieldName{};
4505

4506
        // or
4507

4508
        std::vector<size_t>
4509
            m_mapDimIdxToParentDimIdx{};  // of size m_dims.size()
4510
        std::vector<Range>
4511
            m_parentRanges{};  // of size m_poParent->GetDimensionCount()
4512
    };
4513

4514
    virtual std::shared_ptr<GDALMDArray>
4515
    GetView(const std::string &viewExpr, bool bRenameDimensions,
4516
            std::vector<ViewSpec> &viewSpecs) const;
4517

4518
    const std::string &GetContext() const
1,081✔
4519
    {
4520
        return m_osContext;
1,081✔
4521
    }
4522

4523
    //! @endcond
4524
};
4525

4526
//! @cond Doxygen_Suppress
4527
bool GDALMDRasterIOFromBand(GDALRasterBand *poBand, GDALRWFlag eRWFlag,
4528
                            size_t iDimX, size_t iDimY,
4529
                            const GUInt64 *arrayStartIdx, const size_t *count,
4530
                            const GInt64 *arrayStep,
4531
                            const GPtrDiff_t *bufferStride,
4532
                            const GDALExtendedDataType &bufferDataType,
4533
                            void *pBuffer);
4534

4535
//! @endcond
4536

4537
/************************************************************************/
4538
/*                     GDALMDArrayRegularlySpaced                       */
4539
/************************************************************************/
4540

4541
//! @cond Doxygen_Suppress
4542
class CPL_DLL GDALMDArrayRegularlySpaced : public GDALMDArray
4543
{
4544
    double m_dfStart;
4545
    double m_dfIncrement;
4546
    double m_dfOffsetInIncrement;
4547
    GDALExtendedDataType m_dt = GDALExtendedDataType::Create(GDT_Float64);
4548
    std::vector<std::shared_ptr<GDALDimension>> m_dims;
4549
    std::vector<std::shared_ptr<GDALAttribute>> m_attributes{};
4550
    std::string m_osEmptyFilename{};
4551

4552
  protected:
4553
    bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
4554
               const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
4555
               void *pDstBuffer) const override;
4556

4557
  public:
4558
    GDALMDArrayRegularlySpaced(const std::string &osParentName,
4559
                               const std::string &osName,
4560
                               const std::shared_ptr<GDALDimension> &poDim,
4561
                               double dfStart, double dfIncrement,
4562
                               double dfOffsetInIncrement);
4563

4564
    static std::shared_ptr<GDALMDArrayRegularlySpaced>
4565
    Create(const std::string &osParentName, const std::string &osName,
4566
           const std::shared_ptr<GDALDimension> &poDim, double dfStart,
4567
           double dfIncrement, double dfOffsetInIncrement);
4568

4569
    bool IsWritable() const override
×
4570
    {
4571
        return false;
×
4572
    }
4573

4574
    const std::string &GetFilename() const override
104✔
4575
    {
4576
        return m_osEmptyFilename;
104✔
4577
    }
4578

4579
    const std::vector<std::shared_ptr<GDALDimension>> &
4580
    GetDimensions() const override;
4581

4582
    const GDALExtendedDataType &GetDataType() const override;
4583

4584
    std::vector<std::shared_ptr<GDALAttribute>>
4585
        GetAttributes(CSLConstList) const override;
4586

4587
    void AddAttribute(const std::shared_ptr<GDALAttribute> &poAttr);
4588
};
4589

4590
//! @endcond
4591

4592
/* ******************************************************************** */
4593
/*                            GDALDimension                             */
4594
/* ******************************************************************** */
4595

4596
/**
4597
 * Class modeling a a dimension / axis used to index multidimensional arrays.
4598
 * It has a name, a size (that is the number of values that can be indexed along
4599
 * the dimension), a type (see GDALDimension::GetType()), a direction
4600
 * (see GDALDimension::GetDirection()), a unit and can optionally point to a
4601
 * GDALMDArray variable, typically one-dimensional, describing the values taken
4602
 * by the dimension. For a georeferenced GDALMDArray and its X dimension, this
4603
 * will be typically the values of the easting/longitude for each grid point.
4604
 *
4605
 * @since GDAL 3.1
4606
 */
4607
class CPL_DLL GDALDimension
8,492✔
4608
{
4609
  public:
4610
    //! @cond Doxygen_Suppress
4611
    GDALDimension(const std::string &osParentName, const std::string &osName,
4612
                  const std::string &osType, const std::string &osDirection,
4613
                  GUInt64 nSize);
4614
    //! @endcond
4615

4616
    virtual ~GDALDimension();
4617

4618
    /** Return the name.
4619
     *
4620
     * This is the same as the C function GDALDimensionGetName()
4621
     */
4622
    const std::string &GetName() const
8,337✔
4623
    {
4624
        return m_osName;
8,337✔
4625
    }
4626

4627
    /** Return the full name.
4628
     *
4629
     * This is the same as the C function GDALDimensionGetFullName()
4630
     */
4631
    const std::string &GetFullName() const
1,551✔
4632
    {
4633
        return m_osFullName;
1,551✔
4634
    }
4635

4636
    /** Return the axis type.
4637
     *
4638
     * Predefined values are:
4639
     * HORIZONTAL_X, HORIZONTAL_Y, VERTICAL, TEMPORAL, PARAMETRIC
4640
     * Other values might be returned. Empty value means unknown.
4641
     *
4642
     * This is the same as the C function GDALDimensionGetType()
4643
     */
4644
    const std::string &GetType() const
1,804✔
4645
    {
4646
        return m_osType;
1,804✔
4647
    }
4648

4649
    /** Return the axis direction.
4650
     *
4651
     * Predefined values are:
4652
     * EAST, WEST, SOUTH, NORTH, UP, DOWN, FUTURE, PAST
4653
     * Other values might be returned. Empty value means unknown.
4654
     *
4655
     * This is the same as the C function GDALDimensionGetDirection()
4656
     */
4657
    const std::string &GetDirection() const
880✔
4658
    {
4659
        return m_osDirection;
880✔
4660
    }
4661

4662
    /** Return the size, that is the number of values along the dimension.
4663
     *
4664
     * This is the same as the C function GDALDimensionGetSize()
4665
     */
4666
    GUInt64 GetSize() const
82,022✔
4667
    {
4668
        return m_nSize;
82,022✔
4669
    }
4670

4671
    virtual std::shared_ptr<GDALMDArray> GetIndexingVariable() const;
4672

4673
    virtual bool
4674
    SetIndexingVariable(std::shared_ptr<GDALMDArray> poIndexingVariable);
4675

4676
    virtual bool Rename(const std::string &osNewName);
4677

4678
    //! @cond Doxygen_Suppress
4679
    virtual void ParentRenamed(const std::string &osNewParentFullName);
4680

4681
    virtual void ParentDeleted();
4682
    //! @endcond
4683

4684
  protected:
4685
    //! @cond Doxygen_Suppress
4686
    std::string m_osName;
4687
    std::string m_osFullName;
4688
    std::string m_osType;
4689
    std::string m_osDirection;
4690
    GUInt64 m_nSize;
4691

4692
    void BaseRename(const std::string &osNewName);
4693

4694
    //! @endcond
4695
};
4696

4697
/************************************************************************/
4698
/*                   GDALDimensionWeakIndexingVar()                     */
4699
/************************************************************************/
4700

4701
//! @cond Doxygen_Suppress
4702
class CPL_DLL GDALDimensionWeakIndexingVar : public GDALDimension
4703
{
4704
    std::weak_ptr<GDALMDArray> m_poIndexingVariable{};
4705

4706
  public:
4707
    GDALDimensionWeakIndexingVar(const std::string &osParentName,
4708
                                 const std::string &osName,
4709
                                 const std::string &osType,
4710
                                 const std::string &osDirection, GUInt64 nSize);
4711

4712
    std::shared_ptr<GDALMDArray> GetIndexingVariable() const override;
4713

4714
    bool SetIndexingVariable(
4715
        std::shared_ptr<GDALMDArray> poIndexingVariable) override;
4716

4717
    void SetSize(GUInt64 nNewSize);
4718
};
4719
//! @endcond
4720

4721
/************************************************************************/
4722
/*                       GDALAntiRecursionGuard                         */
4723
/************************************************************************/
4724

4725
//! @cond Doxygen_Suppress
4726
struct GDALAntiRecursionStruct;
4727

4728
class GDALAntiRecursionGuard
4729
{
4730
    GDALAntiRecursionStruct *m_psAntiRecursionStruct;
4731
    std::string m_osIdentifier;
4732
    int m_nDepth;
4733

4734
    GDALAntiRecursionGuard(const GDALAntiRecursionGuard &) = delete;
4735
    GDALAntiRecursionGuard &operator=(const GDALAntiRecursionGuard &) = delete;
4736

4737
  public:
4738
    explicit GDALAntiRecursionGuard(const std::string &osIdentifier);
4739
    GDALAntiRecursionGuard(const GDALAntiRecursionGuard &other,
4740
                           const std::string &osIdentifier);
4741
    ~GDALAntiRecursionGuard();
4742

4743
    int GetCallDepth() const
519,618✔
4744
    {
4745
        return m_nDepth;
519,618✔
4746
    }
4747
};
4748

4749
//! @endcond
4750

4751
/************************************************************************/
4752
/*                           Relationships                              */
4753
/************************************************************************/
4754

4755
/**
4756
 * Definition of a table relationship.
4757
 *
4758
 * GDALRelationship describes the relationship between two tables, including
4759
 * properties such as the cardinality of the relationship and the participating
4760
 * tables.
4761
 *
4762
 * Not all relationship properties are supported by all data formats.
4763
 *
4764
 * @since GDAL 3.6
4765
 */
4766
class CPL_DLL GDALRelationship
4767
{
4768
  protected:
4769
    /*! @cond Doxygen_Suppress */
4770
    std::string m_osName{};
4771
    std::string m_osLeftTableName{};
4772
    std::string m_osRightTableName{};
4773
    GDALRelationshipCardinality m_eCardinality =
4774
        GDALRelationshipCardinality::GRC_ONE_TO_MANY;
4775
    std::string m_osMappingTableName{};
4776
    std::vector<std::string> m_osListLeftTableFields{};
4777
    std::vector<std::string> m_osListRightTableFields{};
4778
    std::vector<std::string> m_osListLeftMappingTableFields{};
4779
    std::vector<std::string> m_osListRightMappingTableFields{};
4780
    GDALRelationshipType m_eType = GDALRelationshipType::GRT_ASSOCIATION;
4781
    std::string m_osForwardPathLabel{};
4782
    std::string m_osBackwardPathLabel{};
4783
    std::string m_osRelatedTableType{};
4784

4785
    /*! @endcond */
4786

4787
  public:
4788
    /**
4789
     * Constructor for a relationship between two tables.
4790
     * @param osName relationship name
4791
     * @param osLeftTableName left table name
4792
     * @param osRightTableName right table name
4793
     * @param eCardinality cardinality of relationship
4794
     */
4795
    GDALRelationship(const std::string &osName,
349✔
4796
                     const std::string &osLeftTableName,
4797
                     const std::string &osRightTableName,
4798
                     GDALRelationshipCardinality eCardinality =
4799
                         GDALRelationshipCardinality::GRC_ONE_TO_MANY)
4800
        : m_osName(osName), m_osLeftTableName(osLeftTableName),
349✔
4801
          m_osRightTableName(osRightTableName), m_eCardinality(eCardinality)
349✔
4802
    {
4803
    }
349✔
4804

4805
    /** Get the name of the relationship */
4806
    const std::string &GetName() const
393✔
4807
    {
4808
        return m_osName;
393✔
4809
    }
4810

4811
    /** Get the cardinality of the relationship */
4812
    GDALRelationshipCardinality GetCardinality() const
247✔
4813
    {
4814
        return m_eCardinality;
247✔
4815
    }
4816

4817
    /** Get the name of the left (or base/origin) table in the relationship.
4818
     *
4819
     * @see GetRightTableName()
4820
     */
4821
    const std::string &GetLeftTableName() const
202✔
4822
    {
4823
        return m_osLeftTableName;
202✔
4824
    }
4825

4826
    /** Get the name of the right (or related/destination) table in the
4827
     * relationship */
4828
    const std::string &GetRightTableName() const
197✔
4829
    {
4830
        return m_osRightTableName;
197✔
4831
    }
4832

4833
    /** Get the name of the mapping table for many-to-many relationships.
4834
     *
4835
     * @see SetMappingTableName()
4836
     */
4837
    const std::string &GetMappingTableName() const
160✔
4838
    {
4839
        return m_osMappingTableName;
160✔
4840
    }
4841

4842
    /** Sets the name of the mapping table for many-to-many relationships.
4843
     *
4844
     * @see GetMappingTableName()
4845
     */
4846
    void SetMappingTableName(const std::string &osName)
113✔
4847
    {
4848
        m_osMappingTableName = osName;
113✔
4849
    }
113✔
4850

4851
    /** Get the names of the participating fields from the left table in the
4852
     * relationship.
4853
     *
4854
     * @see GetRightTableFields()
4855
     * @see SetLeftTableFields()
4856
     */
4857
    const std::vector<std::string> &GetLeftTableFields() const
157✔
4858
    {
4859
        return m_osListLeftTableFields;
157✔
4860
    }
4861

4862
    /** Get the names of the participating fields from the right table in the
4863
     * relationship.
4864
     *
4865
     * @see GetLeftTableFields()
4866
     * @see SetRightTableFields()
4867
     */
4868
    const std::vector<std::string> &GetRightTableFields() const
151✔
4869
    {
4870
        return m_osListRightTableFields;
151✔
4871
    }
4872

4873
    /** Sets the names of the participating fields from the left table in the
4874
     * relationship.
4875
     *
4876
     * @see GetLeftTableFields()
4877
     * @see SetRightTableFields()
4878
     */
4879
    void SetLeftTableFields(const std::vector<std::string> &osListFields)
362✔
4880
    {
4881
        m_osListLeftTableFields = osListFields;
362✔
4882
    }
362✔
4883

4884
    /** Sets the names of the participating fields from the right table in the
4885
     * relationship.
4886
     *
4887
     * @see GetRightTableFields()
4888
     * @see SetLeftTableFields()
4889
     */
4890
    void SetRightTableFields(const std::vector<std::string> &osListFields)
363✔
4891
    {
4892
        m_osListRightTableFields = osListFields;
363✔
4893
    }
363✔
4894

4895
    /** Get the names of the mapping table fields which correspond to the
4896
     * participating fields from the left table in the relationship.
4897
     *
4898
     * @see GetRightMappingTableFields()
4899
     * @see SetLeftMappingTableFields()
4900
     */
4901
    const std::vector<std::string> &GetLeftMappingTableFields() const
61✔
4902
    {
4903
        return m_osListLeftMappingTableFields;
61✔
4904
    }
4905

4906
    /** Get the names of the mapping table fields which correspond to the
4907
     * participating fields from the right table in the relationship.
4908
     *
4909
     * @see GetLeftMappingTableFields()
4910
     * @see SetRightMappingTableFields()
4911
     */
4912
    const std::vector<std::string> &GetRightMappingTableFields() const
61✔
4913
    {
4914
        return m_osListRightMappingTableFields;
61✔
4915
    }
4916

4917
    /** Sets the names of the mapping table fields which correspond to the
4918
     * participating fields from the left table in the relationship.
4919
     *
4920
     * @see GetLeftMappingTableFields()
4921
     * @see SetRightMappingTableFields()
4922
     */
4923
    void SetLeftMappingTableFields(const std::vector<std::string> &osListFields)
313✔
4924
    {
4925
        m_osListLeftMappingTableFields = osListFields;
313✔
4926
    }
313✔
4927

4928
    /** Sets the names of the mapping table fields which correspond to the
4929
     * participating fields from the right table in the relationship.
4930
     *
4931
     * @see GetRightMappingTableFields()
4932
     * @see SetLeftMappingTableFields()
4933
     */
4934
    void
4935
    SetRightMappingTableFields(const std::vector<std::string> &osListFields)
313✔
4936
    {
4937
        m_osListRightMappingTableFields = osListFields;
313✔
4938
    }
313✔
4939

4940
    /** Get the type of the relationship.
4941
     *
4942
     * @see SetType()
4943
     */
4944
    GDALRelationshipType GetType() const
111✔
4945
    {
4946
        return m_eType;
111✔
4947
    }
4948

4949
    /** Sets the type of the relationship.
4950
     *
4951
     * @see GetType()
4952
     */
4953
    void SetType(GDALRelationshipType eType)
263✔
4954
    {
4955
        m_eType = eType;
263✔
4956
    }
263✔
4957

4958
    /** Get the label of the forward path for the relationship.
4959
     *
4960
     * The forward and backward path labels are free-form, user-friendly strings
4961
     * which can be used to generate descriptions of the relationship between
4962
     * features from the right and left tables.
4963
     *
4964
     * E.g. when the left table contains buildings and the right table contains
4965
     * furniture, the forward path label could be "contains" and the backward
4966
     * path label could be "is located within". A client could then generate a
4967
     * user friendly description string such as "fire hose 1234 is located
4968
     * within building 15a".
4969
     *
4970
     * @see SetForwardPathLabel()
4971
     * @see GetBackwardPathLabel()
4972
     */
4973
    const std::string &GetForwardPathLabel() const
53✔
4974
    {
4975
        return m_osForwardPathLabel;
53✔
4976
    }
4977

4978
    /** Sets the label of the forward path for the relationship.
4979
     *
4980
     * The forward and backward path labels are free-form, user-friendly strings
4981
     * which can be used to generate descriptions of the relationship between
4982
     * features from the right and left tables.
4983
     *
4984
     * E.g. when the left table contains buildings and the right table contains
4985
     * furniture, the forward path label could be "contains" and the backward
4986
     * path label could be "is located within". A client could then generate a
4987
     * user friendly description string such as "fire hose 1234 is located
4988
     * within building 15a".
4989
     *
4990
     * @see GetForwardPathLabel()
4991
     * @see SetBackwardPathLabel()
4992
     */
4993
    void SetForwardPathLabel(const std::string &osLabel)
260✔
4994
    {
4995
        m_osForwardPathLabel = osLabel;
260✔
4996
    }
260✔
4997

4998
    /** Get the label of the backward path for the relationship.
4999
     *
5000
     * The forward and backward path labels are free-form, user-friendly strings
5001
     * which can be used to generate descriptions of the relationship between
5002
     * features from the right and left tables.
5003
     *
5004
     * E.g. when the left table contains buildings and the right table contains
5005
     * furniture, the forward path label could be "contains" and the backward
5006
     * path label could be "is located within". A client could then generate a
5007
     * user friendly description string such as "fire hose 1234 is located
5008
     * within building 15a".
5009
     *
5010
     * @see SetBackwardPathLabel()
5011
     * @see GetForwardPathLabel()
5012
     */
5013
    const std::string &GetBackwardPathLabel() const
53✔
5014
    {
5015
        return m_osBackwardPathLabel;
53✔
5016
    }
5017

5018
    /** Sets the label of the backward path for the relationship.
5019
     *
5020
     * The forward and backward path labels are free-form, user-friendly strings
5021
     * which can be used to generate descriptions of the relationship between
5022
     * features from the right and left tables.
5023
     *
5024
     * E.g. when the left table contains buildings and the right table contains
5025
     * furniture, the forward path label could be "contains" and the backward
5026
     * path label could be "is located within". A client could then generate a
5027
     * user friendly description string such as "fire hose 1234 is located
5028
     * within building 15a".
5029
     *
5030
     * @see GetBackwardPathLabel()
5031
     * @see SetForwardPathLabel()
5032
     */
5033
    void SetBackwardPathLabel(const std::string &osLabel)
260✔
5034
    {
5035
        m_osBackwardPathLabel = osLabel;
260✔
5036
    }
260✔
5037

5038
    /** Get the type string of the related table.
5039
     *
5040
     * This a free-form string representing the type of related features, where
5041
     * the exact interpretation is format dependent. For instance, table types
5042
     * from GeoPackage relationships will directly reflect the categories from
5043
     * the GeoPackage related tables extension (i.e. "media", "simple
5044
     * attributes", "features", "attributes" and "tiles").
5045
     *
5046
     * @see SetRelatedTableType()
5047
     */
5048
    const std::string &GetRelatedTableType() const
144✔
5049
    {
5050
        return m_osRelatedTableType;
144✔
5051
    }
5052

5053
    /** Sets the type string of the related table.
5054
     *
5055
     * This a free-form string representing the type of related features, where
5056
     * the exact interpretation is format dependent. For instance, table types
5057
     * from GeoPackage relationships will directly reflect the categories from
5058
     * the GeoPackage related tables extension (i.e. "media", "simple
5059
     * attributes", "features", "attributes" and "tiles").
5060
     *
5061
     * @see GetRelatedTableType()
5062
     */
5063
    void SetRelatedTableType(const std::string &osType)
340✔
5064
    {
5065
        m_osRelatedTableType = osType;
340✔
5066
    }
340✔
5067

5068
    /** Convert a GDALRelationship* to a GDALRelationshipH.
5069
     */
5070
    static inline GDALRelationshipH ToHandle(GDALRelationship *poRelationship)
81✔
5071
    {
5072
        return static_cast<GDALRelationshipH>(poRelationship);
81✔
5073
    }
5074

5075
    /** Convert a GDALRelationshipH to a GDALRelationship*.
5076
     */
5077
    static inline GDALRelationship *FromHandle(GDALRelationshipH hRelationship)
706✔
5078
    {
5079
        return static_cast<GDALRelationship *>(hRelationship);
706✔
5080
    }
5081
};
5082

5083
/* ==================================================================== */
5084
/*      An assortment of overview related stuff.                        */
5085
/* ==================================================================== */
5086

5087
//! @cond Doxygen_Suppress
5088
/* Only exported for drivers as plugin. Signature may change */
5089
CPLErr CPL_DLL GDALRegenerateOverviewsMultiBand(
5090
    int nBands, GDALRasterBand *const *papoSrcBands, int nOverviews,
5091
    GDALRasterBand *const *const *papapoOverviewBands,
5092
    const char *pszResampling, GDALProgressFunc pfnProgress,
5093
    void *pProgressData, CSLConstList papszOptions);
5094

5095
CPLErr CPL_DLL GDALRegenerateOverviewsMultiBand(
5096
    const std::vector<GDALRasterBand *> &apoSrcBands,
5097
    // First level of array is indexed by band (thus aapoOverviewBands.size() must be equal to apoSrcBands.size())
5098
    // Second level is indexed by overview
5099
    const std::vector<std::vector<GDALRasterBand *>> &aapoOverviewBands,
5100
    const char *pszResampling, GDALProgressFunc pfnProgress,
5101
    void *pProgressData, CSLConstList papszOptions);
5102

5103
/************************************************************************/
5104
/*                       GDALOverviewResampleArgs                       */
5105
/************************************************************************/
5106

5107
/** Arguments for overview resampling function. */
5108
// Should not contain any dataset/rasterband object, as this might be
5109
// read in a worker thread.
5110
struct GDALOverviewResampleArgs
5111
{
5112
    //! Datatype of the source band argument
5113
    GDALDataType eSrcDataType = GDT_Unknown;
5114
    //! Datatype of the destination/overview band
5115
    GDALDataType eOvrDataType = GDT_Unknown;
5116
    //! Width in pixel of the destination/overview band
5117
    int nOvrXSize = 0;
5118
    //! Height in pixel of the destination/overview band
5119
    int nOvrYSize = 0;
5120
    //! NBITS value of the destination/overview band (or 0 if not set)
5121
    int nOvrNBITS = 0;
5122
    //! Factor to convert from destination X to source X
5123
    // (source width divided by destination width)
5124
    double dfXRatioDstToSrc = 0;
5125
    //! Factor to convert from destination Y to source Y
5126
    // (source height divided by destination height)
5127
    double dfYRatioDstToSrc = 0;
5128
    //! Sub-pixel delta to add to get source X
5129
    double dfSrcXDelta = 0;
5130
    //! Sub-pixel delta to add to get source Y
5131
    double dfSrcYDelta = 0;
5132
    //! Working data type (data type of the pChunk argument)
5133
    GDALDataType eWrkDataType = GDT_Unknown;
5134
    //! Array of nChunkXSize * nChunkYSize values of mask, or nullptr
5135
    const GByte *pabyChunkNodataMask = nullptr;
5136
    //! X offset of the source chunk in the source band
5137
    int nChunkXOff = 0;
5138
    //! Width in pixel of the source chunk in the source band
5139
    int nChunkXSize = 0;
5140
    //! Y offset of the source chunk in the source band
5141
    int nChunkYOff = 0;
5142
    //! Height in pixel of the source chunk in the source band
5143
    int nChunkYSize = 0;
5144
    //! X Offset of the destination chunk in the destination band
5145
    int nDstXOff = 0;
5146
    //! X Offset of the end (not included) of the destination chunk in the destination band
5147
    int nDstXOff2 = 0;
5148
    //! Y Offset of the destination chunk in the destination band
5149
    int nDstYOff = 0;
5150
    //! Y Offset of the end (not included) of the destination chunk in the destination band
5151
    int nDstYOff2 = 0;
5152
    //! Resampling method
5153
    const char *pszResampling = nullptr;
5154
    //! Whether the source band has a nodata value
5155
    bool bHasNoData = false;
5156
    //! Source band nodata value
5157
    double dfNoDataValue = 0;
5158
    //! Source color table
5159
    const GDALColorTable *poColorTable = nullptr;
5160
    //! Whether a single contributing source pixel at nodata should result
5161
    // in the target pixel to be at nodata too (only taken into account by
5162
    // average resampling)
5163
    bool bPropagateNoData = false;
5164
};
5165

5166
typedef CPLErr (*GDALResampleFunction)(const GDALOverviewResampleArgs &args,
5167
                                       const void *pChunk, void **ppDstBuffer,
5168
                                       GDALDataType *peDstBufferDataType);
5169

5170
GDALResampleFunction GDALGetResampleFunction(const char *pszResampling,
5171
                                             int *pnRadius);
5172

5173
std::string CPL_DLL GDALGetNormalizedOvrResampling(const char *pszResampling);
5174

5175
GDALDataType GDALGetOvrWorkDataType(const char *pszResampling,
5176
                                    GDALDataType eSrcDataType);
5177

5178
CPL_C_START
5179

5180
CPLErr CPL_DLL
5181
HFAAuxBuildOverviews(const char *pszOvrFilename, GDALDataset *poParentDS,
5182
                     GDALDataset **ppoDS, int nBands, const int *panBandList,
5183
                     int nNewOverviews, const int *panNewOverviewList,
5184
                     const char *pszResampling, GDALProgressFunc pfnProgress,
5185
                     void *pProgressData, CSLConstList papszOptions);
5186

5187
CPLErr CPL_DLL GTIFFBuildOverviews(const char *pszFilename, int nBands,
5188
                                   GDALRasterBand *const *papoBandList,
5189
                                   int nOverviews, const int *panOverviewList,
5190
                                   const char *pszResampling,
5191
                                   GDALProgressFunc pfnProgress,
5192
                                   void *pProgressData,
5193
                                   CSLConstList papszOptions);
5194

5195
int CPL_DLL GDALBandGetBestOverviewLevel(GDALRasterBand *poBand, int &nXOff,
5196
                                         int &nYOff, int &nXSize, int &nYSize,
5197
                                         int nBufXSize, int nBufYSize)
5198
    CPL_WARN_DEPRECATED("Use GDALBandGetBestOverviewLevel2 instead");
5199
int CPL_DLL GDALBandGetBestOverviewLevel2(GDALRasterBand *poBand, int &nXOff,
5200
                                          int &nYOff, int &nXSize, int &nYSize,
5201
                                          int nBufXSize, int nBufYSize,
5202
                                          GDALRasterIOExtraArg *psExtraArg);
5203

5204
int CPL_DLL GDALOvLevelAdjust(int nOvLevel, int nXSize)
5205
    CPL_WARN_DEPRECATED("Use GDALOvLevelAdjust2 instead");
5206
int CPL_DLL GDALOvLevelAdjust2(int nOvLevel, int nXSize, int nYSize);
5207
int CPL_DLL GDALComputeOvFactor(int nOvrXSize, int nRasterXSize, int nOvrYSize,
5208
                                int nRasterYSize);
5209

5210
GDALDataset CPL_DLL *GDALFindAssociatedAuxFile(const char *pszBasefile,
5211
                                               GDALAccess eAccess,
5212
                                               GDALDataset *poDependentDS);
5213

5214
/* ==================================================================== */
5215
/*  Infrastructure to check that dataset characteristics are valid      */
5216
/* ==================================================================== */
5217

5218
int CPL_DLL GDALCheckDatasetDimensions(int nXSize, int nYSize);
5219
int CPL_DLL GDALCheckBandCount(int nBands, int bIsZeroAllowed);
5220

5221
/* Internal use only */
5222

5223
/* CPL_DLL exported, but only for in-tree drivers that can be built as plugins
5224
 */
5225
int CPL_DLL GDALReadWorldFile2(const char *pszBaseFilename,
5226
                               const char *pszExtension,
5227
                               double *padfGeoTransform,
5228
                               CSLConstList papszSiblingFiles,
5229
                               char **ppszWorldFileNameOut);
5230
int CPL_DLL GDALReadTabFile2(const char *pszBaseFilename,
5231
                             double *padfGeoTransform, char **ppszWKT,
5232
                             int *pnGCPCount, GDAL_GCP **ppasGCPs,
5233
                             CSLConstList papszSiblingFiles,
5234
                             char **ppszTabFileNameOut);
5235

5236
void CPL_DLL GDALCopyRasterIOExtraArg(GDALRasterIOExtraArg *psDestArg,
5237
                                      GDALRasterIOExtraArg *psSrcArg);
5238

5239
void CPL_DLL GDALExpandPackedBitsToByteAt0Or1(
5240
    const GByte *CPL_RESTRICT pabyInput, GByte *CPL_RESTRICT pabyOutput,
5241
    size_t nInputBits);
5242

5243
void CPL_DLL GDALExpandPackedBitsToByteAt0Or255(
5244
    const GByte *CPL_RESTRICT pabyInput, GByte *CPL_RESTRICT pabyOutput,
5245
    size_t nInputBits);
5246

5247
CPL_C_END
5248

5249
int CPL_DLL GDALReadWorldFile2(const char *pszBaseFilename,
5250
                               const char *pszExtension, GDALGeoTransform &gt,
5251
                               CSLConstList papszSiblingFiles,
5252
                               char **ppszWorldFileNameOut);
5253

5254
std::unique_ptr<GDALDataset> CPL_DLL
5255
GDALGetThreadSafeDataset(std::unique_ptr<GDALDataset> poDS, int nScopeFlags);
5256

5257
GDALDataset CPL_DLL *GDALGetThreadSafeDataset(GDALDataset *poDS,
5258
                                              int nScopeFlags);
5259

5260
void GDALNullifyOpenDatasetsList();
5261
CPLMutex **GDALGetphDMMutex();
5262
CPLMutex **GDALGetphDLMutex();
5263
void GDALNullifyProxyPoolSingleton();
5264
void GDALSetResponsiblePIDForCurrentThread(GIntBig responsiblePID);
5265
GIntBig GDALGetResponsiblePIDForCurrentThread();
5266

5267
CPLString GDALFindAssociatedFile(const char *pszBasename, const char *pszExt,
5268
                                 CSLConstList papszSiblingFiles, int nFlags);
5269

5270
CPLErr CPL_DLL EXIFExtractMetadata(char **&papszMetadata, void *fpL,
5271
                                   int nOffset, int bSwabflag, int nTIFFHEADER,
5272
                                   int &nExifOffset, int &nInterOffset,
5273
                                   int &nGPSOffset);
5274

5275
int GDALValidateOpenOptions(GDALDriverH hDriver,
5276
                            const char *const *papszOptionOptions);
5277
int GDALValidateOptions(const char *pszOptionList,
5278
                        const char *const *papszOptionsToValidate,
5279
                        const char *pszErrorMessageOptionType,
5280
                        const char *pszErrorMessageContainerName);
5281

5282
GDALRIOResampleAlg CPL_DLL
5283
GDALRasterIOGetResampleAlg(const char *pszResampling);
5284
const char *GDALRasterIOGetResampleAlg(GDALRIOResampleAlg eResampleAlg);
5285

5286
void GDALRasterIOExtraArgSetResampleAlg(GDALRasterIOExtraArg *psExtraArg,
5287
                                        int nXSize, int nYSize, int nBufXSize,
5288
                                        int nBufYSize);
5289

5290
GDALDataset *GDALCreateOverviewDataset(GDALDataset *poDS, int nOvrLevel,
5291
                                       bool bThisLevelOnly);
5292

5293
// Should cover particular cases of #3573, #4183, #4506, #6578
5294
// Behavior is undefined if fVal1 or fVal2 are NaN (should be tested before
5295
// calling this function)
5296

5297
// TODO: The expression `abs(fVal1 + fVal2)` looks strange; is this a bug?
5298
// Should this be `abs(fVal1) + abs(fVal2)` instead?
5299

5300
inline bool ARE_REAL_EQUAL(float fVal1, float fVal2, int ulp = 2)
15,878,513✔
5301
{
5302
    using std::abs;
5303
    return fVal1 == fVal2 || /* Should cover infinity */
30,690,718✔
5304
           abs(fVal1 - fVal2) <
14,812,305✔
5305
               std::numeric_limits<float>::epsilon() * abs(fVal1 + fVal2) * ulp;
30,690,718✔
5306
}
5307

5308
// We are using `std::numeric_limits<float>::epsilon()` for backward
5309
// compatibility
5310
inline bool ARE_REAL_EQUAL(double dfVal1, double dfVal2, int ulp = 2)
3,948,479✔
5311
{
5312
    using std::abs;
5313
    return dfVal1 == dfVal2 || /* Should cover infinity */
4,549,355✔
5314
           abs(dfVal1 - dfVal2) < std::numeric_limits<float>::epsilon() *
600,877✔
5315
                                      abs(dfVal1 + dfVal2) * ulp;
4,549,355✔
5316
}
5317

5318
double GDALAdjustNoDataCloseToFloatMax(double dfVal);
5319

5320
#define DIV_ROUND_UP(a, b) (((a) % (b)) == 0 ? ((a) / (b)) : (((a) / (b)) + 1))
5321

5322
// Number of data samples that will be used to compute approximate statistics
5323
// (minimum value, maximum value, etc.)
5324
#define GDALSTAT_APPROX_NUMSAMPLES 2500
5325

5326
void GDALSerializeGCPListToXML(CPLXMLNode *psParentNode,
5327
                               const std::vector<gdal::GCP> &asGCPs,
5328
                               const OGRSpatialReference *poGCP_SRS);
5329
void GDALDeserializeGCPListFromXML(const CPLXMLNode *psGCPList,
5330
                                   std::vector<gdal::GCP> &asGCPs,
5331
                                   OGRSpatialReference **ppoGCP_SRS);
5332

5333
void GDALSerializeOpenOptionsToXML(CPLXMLNode *psParentNode,
5334
                                   CSLConstList papszOpenOptions);
5335
char CPL_DLL **
5336
GDALDeserializeOpenOptionsFromXML(const CPLXMLNode *psParentNode);
5337

5338
int GDALCanFileAcceptSidecarFile(const char *pszFilename);
5339

5340
bool GDALCanReliablyUseSiblingFileList(const char *pszFilename);
5341

5342
typedef enum
5343
{
5344
    GSF_UNSIGNED_INT,
5345
    GSF_SIGNED_INT,
5346
    GSF_FLOATING_POINT,
5347
} GDALBufferSampleFormat;
5348

5349
bool CPL_DLL GDALBufferHasOnlyNoData(const void *pBuffer, double dfNoDataValue,
5350
                                     size_t nWidth, size_t nHeight,
5351
                                     size_t nLineStride, size_t nComponents,
5352
                                     int nBitsPerSample,
5353
                                     GDALBufferSampleFormat nSampleFormat);
5354

5355
bool CPL_DLL GDALCopyNoDataValue(GDALRasterBand *poDstBand,
5356
                                 GDALRasterBand *poSrcBand,
5357
                                 bool *pbCannotBeExactlyRepresented = nullptr);
5358

5359
double CPL_DLL GDALGetNoDataValueCastToDouble(int64_t nVal);
5360
double CPL_DLL GDALGetNoDataValueCastToDouble(uint64_t nVal);
5361

5362
// Remove me in GDAL 4.0. See GetMetadataItem() implementation
5363
// Internal use in GDAL only !
5364
// Declaration copied in swig/include/gdal.i
5365
void CPL_DLL GDALEnablePixelTypeSignedByteWarning(GDALRasterBandH hBand,
5366
                                                  bool b);
5367

5368
std::string CPL_DLL GDALGetCompressionFormatForJPEG(VSILFILE *fp);
5369
std::string CPL_DLL GDALGetCompressionFormatForJPEG(const void *pBuffer,
5370
                                                    size_t nBufferSize);
5371

5372
GDALRasterAttributeTable CPL_DLL *GDALCreateRasterAttributeTableFromMDArrays(
5373
    GDALRATTableType eTableType,
5374
    const std::vector<std::shared_ptr<GDALMDArray>> &apoArrays,
5375
    const std::vector<GDALRATFieldUsage> &aeUsages);
5376

5377
GDALColorInterp CPL_DLL
5378
GDALGetColorInterpFromSTACCommonName(const char *pszName);
5379
const char CPL_DLL *
5380
GDALGetSTACCommonNameFromColorInterp(GDALColorInterp eInterp);
5381

5382
std::string CPL_DLL GDALGetCacheDirectory();
5383

5384
bool GDALDoesFileOrDatasetExist(const char *pszName,
5385
                                const char **ppszType = nullptr,
5386
                                GDALDriver **ppDriver = nullptr);
5387

5388
std::string CPL_DLL
5389
GDALGetMessageAboutMissingPluginDriver(GDALDriver *poMissingPluginDriver);
5390

5391
std::string GDALPrintDriverList(int nOptions, bool bJSON);
5392

5393
struct GDALColorAssociation
5394
{
5395
    double dfVal;
5396
    int nR;
5397
    int nG;
5398
    int nB;
5399
    int nA;
5400
};
5401

5402
std::vector<GDALColorAssociation> GDALLoadTextColorMap(const char *pszFilename,
5403
                                                       GDALRasterBand *poBand);
5404

5405
// Macro used so that Identify and driver metadata methods in drivers built
5406
// as plugin can be duplicated in libgdal core and in the driver under different
5407
// names
5408
#ifdef PLUGIN_FILENAME
5409
#define PLUGIN_SYMBOL_NAME(x) GDAL_core_##x
5410
#else
5411
#define PLUGIN_SYMBOL_NAME(x) GDAL_driver_##x
5412
#endif
5413

5414
//! @endcond
5415

5416
#endif /* ndef GDAL_PRIV_H_INCLUDED */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc