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