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