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