Coverage Report

Created: 2025-08-28 06:57

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