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 7046386 : class CPL_DLL GDALMultiDomainMetadata
92 : {
93 : private:
94 : CPLStringList aosDomainList{};
95 :
96 : struct Comparator
97 : {
98 33452800 : bool operator()(const char *a, const char *b) const
99 : {
100 33452800 : 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 711690 : CSLConstList GetDomainList() const
128 : {
129 711690 : 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 262 : static inline GDALMajorObjectH ToHandle(GDALMajorObject *poMajorObject)
206 : {
207 262 : return static_cast<GDALMajorObjectH>(poMajorObject);
208 : }
209 :
210 : /** Convert a GDALMajorObjectH to a GDALMajorObject*.
211 : * @since GDAL 2.3
212 : */
213 298260 : static inline GDALMajorObject *FromHandle(GDALMajorObjectH hMajorObject)
214 : {
215 298260 : 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 58536 : char **GetSiblingFiles()
315 : {
316 58536 : 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 885237 : inline bool IsExtensionEqualToCI(const char *pszExt) const
385 : {
386 885237 : return EQUAL(osExtension.c_str(), pszExt);
387 : }
388 :
389 : private:
390 : CPL_DISALLOW_COPY_ASSIGN(GDALOpenInfo)
391 : };
392 :
393 : /* ******************************************************************** */
394 : /* gdal::GCP */
395 : /* ******************************************************************** */
396 :
397 : namespace gdal
398 : {
399 : /** C++ wrapper over the C GDAL_GCP structure.
400 : *
401 : * It has the same binary layout, and thus a gdal::GCP pointer can be cast as a
402 : * GDAL_GCP pointer.
403 : *
404 : * @since 3.9
405 : */
406 : class CPL_DLL GCP
407 : {
408 : public:
409 : explicit GCP(const char *pszId = "", const char *pszInfo = "",
410 : double dfPixel = 0, double dfLine = 0, double dfX = 0,
411 : double dfY = 0, double dfZ = 0);
412 : ~GCP();
413 : GCP(const GCP &);
414 : explicit GCP(const GDAL_GCP &other);
415 : GCP &operator=(const GCP &);
416 : GCP(GCP &&);
417 : GCP &operator=(GCP &&);
418 :
419 : /** Returns the "id" member. */
420 21898 : inline const char *Id() const
421 : {
422 21898 : return gcp.pszId;
423 : }
424 :
425 : void SetId(const char *pszId);
426 :
427 : /** Returns the "info" member. */
428 43778 : inline const char *Info() const
429 : {
430 43778 : return gcp.pszInfo;
431 : }
432 :
433 : void SetInfo(const char *pszInfo);
434 :
435 : /** Returns the "pixel" member. */
436 21917 : inline double Pixel() const
437 : {
438 21917 : return gcp.dfGCPPixel;
439 : }
440 :
441 : /** Returns a reference to the "pixel" member. */
442 24725 : inline double &Pixel()
443 : {
444 24725 : return gcp.dfGCPPixel;
445 : }
446 :
447 : /** Returns the "line" member. */
448 21917 : inline double Line() const
449 : {
450 21917 : return gcp.dfGCPLine;
451 : }
452 :
453 : /** Returns a reference to the "line" member. */
454 24725 : inline double &Line()
455 : {
456 24725 : return gcp.dfGCPLine;
457 : }
458 :
459 : /** Returns the "X" member. */
460 21917 : inline double X() const
461 : {
462 21917 : return gcp.dfGCPX;
463 : }
464 :
465 : /** Returns a reference to the "X" member. */
466 24651 : inline double &X()
467 : {
468 24651 : return gcp.dfGCPX;
469 : }
470 :
471 : /** Returns the "Y" member. */
472 21917 : inline double Y() const
473 : {
474 21917 : return gcp.dfGCPY;
475 : }
476 :
477 : /** Returns a reference to the "Y" member. */
478 24651 : inline double &Y()
479 : {
480 24651 : return gcp.dfGCPY;
481 : }
482 :
483 : /** Returns the "Z" member. */
484 43745 : inline double Z() const
485 : {
486 43745 : return gcp.dfGCPZ;
487 : }
488 :
489 : /** Returns a reference to the "Z" member. */
490 24532 : inline double &Z()
491 : {
492 24532 : return gcp.dfGCPZ;
493 : }
494 :
495 : /** Casts as a C GDAL_GCP pointer */
496 449 : inline const GDAL_GCP *c_ptr() const
497 : {
498 449 : return &gcp;
499 : }
500 :
501 : static const GDAL_GCP *c_ptr(const std::vector<GCP> &asGCPs);
502 :
503 : static std::vector<GCP> fromC(const GDAL_GCP *pasGCPList, int nGCPCount);
504 :
505 : private:
506 : GDAL_GCP gcp;
507 : };
508 :
509 : } /* namespace gdal */
510 :
511 : /* ******************************************************************** */
512 : /* GDALGeoTransform */
513 : /* ******************************************************************** */
514 :
515 : /** Class that encapsulates a geotransform matrix.
516 : *
517 : * It contains 6 coefficients expressing an affine transformation from
518 : * (column, line) raster space to (X, Y) georeferenced space, such that
519 : *
520 : * \code{.c}
521 : * X = xorig + column * xscale + line * xrot;
522 : * Y = yorig + column * yrot + line * yscale;
523 : * \endcode
524 : *
525 : * The default value is the identity transformation.
526 : *
527 : * @since 3.12
528 : */
529 : 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 186407 : 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 6085 : inline GDALGeoTransform(double xorigIn, double xscaleIn, double xrotIn,
570 : double yorigIn, double yrotIn, double yscaleIn)
571 6085 : {
572 6085 : xorig = xorigIn;
573 6085 : xscale = xscaleIn;
574 6085 : xrot = xrotIn;
575 6085 : yorig = yorigIn;
576 6085 : yrot = yrotIn;
577 6085 : yscale = yscaleIn;
578 6085 : }
579 :
580 : /** Element accessor. idx must be in [0,5] range */
581 13616 : template <typename T> inline double operator[](T idx) const
582 : {
583 13616 : return *(&xorig + idx);
584 : }
585 :
586 : /** Element accessor. idx must be in [0,5] range */
587 81878621 : template <typename T> inline double &operator[](T idx)
588 : {
589 81878621 : return *(&xorig + idx);
590 : }
591 :
592 : /** Equality test operator */
593 3999 : inline bool operator==(const GDALGeoTransform &other) const
594 : {
595 2945 : return xorig == other.xorig && xscale == other.xscale &&
596 2921 : xrot == other.xrot && yorig == other.yorig &&
597 6944 : yrot == other.yrot && yscale == other.yscale;
598 : }
599 :
600 : /** Inequality test operator */
601 3936 : inline bool operator!=(const GDALGeoTransform &other) const
602 : {
603 3936 : return !(operator==(other));
604 : }
605 :
606 : /** Cast to const double* */
607 677 : inline const double *data() const
608 : {
609 677 : return &xorig;
610 : }
611 :
612 : /** Cast to double* */
613 24895 : inline double *data()
614 : {
615 24895 : 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 516 : inline void Apply(double dfPixel, double dfLine, double *pdfGeoX,
639 : double *pdfGeoY) const
640 : {
641 516 : GDALApplyGeoTransform(data(), dfPixel, dfLine, pdfGeoX, pdfGeoY);
642 516 : }
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 1821 : inline void Rescale(double dfXRatio, double dfYRatio)
667 : {
668 1821 : xscale *= dfXRatio;
669 1821 : xrot *= dfYRatio;
670 1821 : yrot *= dfXRatio;
671 1821 : yscale *= dfYRatio;
672 1821 : }
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 190856 : GDALAccess GetAccess() const
1050 : {
1051 190856 : 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 5797703 : bool IsMarkedSuppressOnClose() const
1064 : {
1065 5797703 : return bSuppressOnClose;
1066 : }
1067 :
1068 : /** Return open options.
1069 : * @return open options.
1070 : */
1071 143898 : char **GetOpenOptions()
1072 : {
1073 143898 : 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 30492 : static inline GDALDatasetH ToHandle(GDALDataset *poDS)
1134 : {
1135 30492 : return static_cast<GDALDatasetH>(poDS);
1136 : }
1137 :
1138 : /** Convert a GDALDatasetH to a GDALDataset*.
1139 : * @since GDAL 2.3
1140 : */
1141 1507208 : static inline GDALDataset *FromHandle(GDALDatasetH hDS)
1142 : {
1143 1507208 : return static_cast<GDALDataset *>(hDS);
1144 : }
1145 :
1146 : /** @see GDALOpenEx().
1147 : * @since GDAL 2.3
1148 : */
1149 30361 : 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 30361 : return FromHandle(GDALOpenEx(pszFilename, nOpenFlags,
1156 : papszAllowedDrivers, papszOpenOptions,
1157 30360 : 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 251 : CPL_INTERNAL explicit Layers(GDALDataset *poSelf) : m_poSelf(poSelf)
1205 : {
1206 251 : }
1207 :
1208 : public:
1209 : /** Layer iterator.
1210 : * @since GDAL 2.3
1211 : */
1212 512 : 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 2272 : void operator()(GDALDataset *poDataset) const
1437 : {
1438 2272 : if (poDataset)
1439 2269 : poDataset->Release();
1440 2272 : }
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 10533900 : int AddLock(void)
1502 : {
1503 10533900 : return CPLAtomicInc(&nLockCount);
1504 : }
1505 :
1506 : /** Decrement the lock count */
1507 10534384 : int DropLock(void)
1508 : {
1509 10534384 : 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 12355100 : int GetXOff() const
1528 : {
1529 12355100 : return nXOff;
1530 : }
1531 :
1532 : /** Return the y offset of the top-left corner of the block
1533 : * @return y offset
1534 : */
1535 483194000 : int GetYOff() const
1536 : {
1537 483194000 : 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 4044020 : int GetDirty() const
1560 : {
1561 4044020 : return bDirty;
1562 : }
1563 :
1564 : /** Return the data buffer
1565 : * @return data buffer
1566 : */
1567 13940927 : void *GetDataRef(void)
1568 : {
1569 13940927 : return pData;
1570 : }
1571 :
1572 : /** Return the block size in bytes
1573 : * @return block size.
1574 : */
1575 6807960 : GPtrDiff_t GetBlockSize() const
1576 : {
1577 6807960 : return static_cast<GPtrDiff_t>(nXSize) * nYSize *
1578 6807960 : 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 59640 : GDALRasterBand *GetBand()
1587 : {
1588 59640 : 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 2121 : 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 287 : 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 1990 : static inline GDALColorTableH ToHandle(GDALColorTable *poCT)
1662 : {
1663 1990 : return static_cast<GDALColorTableH>(poCT);
1664 : }
1665 :
1666 : /** Convert a GDALColorTableH to a GDALColorTable*.
1667 : * @since GDAL 2.3
1668 : */
1669 22076 : static inline GDALColorTable *FromHandle(GDALColorTableH hCT)
1670 : {
1671 22076 : 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 3382 : void DisableDirtyBlockWriting()
1728 : {
1729 3382 : ++m_nWriteDirtyBlocksDisabled;
1730 3382 : }
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 1911390 : GDALRasterBandOwnedOrNot() = default;
1859 :
1860 : GDALRasterBandOwnedOrNot(GDALRasterBandOwnedOrNot &&) = default;
1861 :
1862 1911550 : void reset()
1863 : {
1864 1911550 : m_poBandOwned.reset();
1865 1911550 : m_poBandRef = nullptr;
1866 1911550 : }
1867 :
1868 1718 : void resetNotOwned(GDALRasterBand *poBand)
1869 : {
1870 1718 : m_poBandOwned.reset();
1871 1716 : m_poBandRef = poBand;
1872 1716 : }
1873 :
1874 160748 : void reset(std::unique_ptr<GDALRasterBand> poBand)
1875 : {
1876 160748 : m_poBandOwned = std::move(poBand);
1877 160749 : m_poBandRef = nullptr;
1878 160749 : }
1879 :
1880 2 : const GDALRasterBand *get() const
1881 : {
1882 2 : return static_cast<const GDALRasterBand *>(*this);
1883 : }
1884 :
1885 1434780 : GDALRasterBand *get()
1886 : {
1887 1434780 : return static_cast<GDALRasterBand *>(*this);
1888 : }
1889 :
1890 705790 : bool IsOwned() const
1891 : {
1892 705790 : 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 3091530 : operator GDALRasterBand *()
1901 : {
1902 3091530 : 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 2296520 : bool HasBlockCache() const
1980 : {
1981 2296520 : 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 operator-() const CPL_WARN_UNUSED_RESULT;
2150 :
2151 : GDALComputedRasterBand AsType(GDALDataType) const CPL_WARN_UNUSED_RESULT;
2152 :
2153 : CPLErr ReadBlock(int nXBlockOff, int nYBlockOff,
2154 : void *pImage) CPL_WARN_UNUSED_RESULT;
2155 :
2156 : CPLErr WriteBlock(int nXBlockOff, int nYBlockOff,
2157 : void *pImage) CPL_WARN_UNUSED_RESULT;
2158 :
2159 : // This method should only be overloaded by GDALProxyRasterBand
2160 : virtual GDALRasterBlock *
2161 : GetLockedBlockRef(int nXBlockOff, int nYBlockOff,
2162 : int bJustInitialize = FALSE) CPL_WARN_UNUSED_RESULT;
2163 :
2164 : // This method should only be overloaded by GDALProxyRasterBand
2165 : virtual GDALRasterBlock *
2166 : TryGetLockedBlockRef(int nXBlockOff,
2167 : int nYBlockYOff) CPL_WARN_UNUSED_RESULT;
2168 :
2169 : // This method should only be overloaded by GDALProxyRasterBand
2170 : virtual CPLErr FlushBlock(int nXBlockOff, int nYBlockOff,
2171 : int bWriteDirtyBlock = TRUE);
2172 :
2173 : unsigned char *
2174 : GetIndexColorTranslationTo(/* const */ GDALRasterBand *poReferenceBand,
2175 : unsigned char *pTranslationTable = nullptr,
2176 : int *pApproximateMatching = nullptr);
2177 :
2178 : // New OpengIS CV_SampleDimension stuff.
2179 :
2180 : virtual CPLErr FlushCache(bool bAtClosing = false);
2181 : virtual CPLErr DropCache();
2182 : virtual char **GetCategoryNames();
2183 : virtual double GetNoDataValue(int *pbSuccess = nullptr);
2184 : virtual int64_t GetNoDataValueAsInt64(int *pbSuccess = nullptr);
2185 : virtual uint64_t GetNoDataValueAsUInt64(int *pbSuccess = nullptr);
2186 : virtual double GetMinimum(int *pbSuccess = nullptr);
2187 : virtual double GetMaximum(int *pbSuccess = nullptr);
2188 : virtual double GetOffset(int *pbSuccess = nullptr);
2189 : virtual double GetScale(int *pbSuccess = nullptr);
2190 : virtual const char *GetUnitType();
2191 : virtual GDALColorInterp GetColorInterpretation();
2192 : virtual GDALColorTable *GetColorTable();
2193 : virtual CPLErr Fill(double dfRealValue, double dfImaginaryValue = 0);
2194 :
2195 : virtual CPLErr SetCategoryNames(char **papszNames);
2196 : virtual CPLErr SetNoDataValue(double dfNoData);
2197 : virtual CPLErr SetNoDataValueAsInt64(int64_t nNoData);
2198 : virtual CPLErr SetNoDataValueAsUInt64(uint64_t nNoData);
2199 : CPLErr SetNoDataValueAsString(const char *pszNoData,
2200 : bool *pbCannotBeExactlyRepresented = nullptr);
2201 : virtual CPLErr DeleteNoDataValue();
2202 : virtual CPLErr SetColorTable(GDALColorTable *poCT);
2203 : virtual CPLErr SetColorInterpretation(GDALColorInterp eColorInterp);
2204 : virtual CPLErr SetOffset(double dfNewOffset);
2205 : virtual CPLErr SetScale(double dfNewScale);
2206 : virtual CPLErr SetUnitType(const char *pszNewValue);
2207 :
2208 : virtual CPLErr GetStatistics(int bApproxOK, int bForce, double *pdfMin,
2209 : double *pdfMax, double *pdfMean,
2210 : double *padfStdDev);
2211 : virtual CPLErr ComputeStatistics(int bApproxOK, double *pdfMin,
2212 : double *pdfMax, double *pdfMean,
2213 : double *pdfStdDev, GDALProgressFunc,
2214 : void *pProgressData);
2215 : virtual CPLErr SetStatistics(double dfMin, double dfMax, double dfMean,
2216 : double dfStdDev);
2217 : virtual CPLErr ComputeRasterMinMax(int bApproxOK, double *adfMinMax);
2218 : virtual CPLErr ComputeRasterMinMaxLocation(double *pdfMin, double *pdfMax,
2219 : int *pnMinX, int *pnMinY,
2220 : int *pnMaxX, int *pnMaxY);
2221 :
2222 : // Only defined when Doxygen enabled
2223 : #ifdef DOXYGEN_SKIP
2224 : CPLErr SetMetadata(char **papszMetadata, const char *pszDomain) override;
2225 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
2226 : const char *pszDomain) override;
2227 : #endif
2228 : virtual const char *GetMetadataItem(const char *pszName,
2229 : const char *pszDomain = "") override;
2230 :
2231 : virtual int HasArbitraryOverviews();
2232 : virtual int GetOverviewCount();
2233 : virtual GDALRasterBand *GetOverview(int i);
2234 : virtual GDALRasterBand *GetRasterSampleOverview(GUIntBig);
2235 : virtual CPLErr BuildOverviews(const char *pszResampling, int nOverviews,
2236 : const int *panOverviewList,
2237 : GDALProgressFunc pfnProgress,
2238 : void *pProgressData,
2239 : CSLConstList papszOptions);
2240 :
2241 : virtual CPLErr AdviseRead(int nXOff, int nYOff, int nXSize, int nYSize,
2242 : int nBufXSize, int nBufYSize,
2243 : GDALDataType eBufType, char **papszOptions);
2244 :
2245 : virtual CPLErr GetHistogram(double dfMin, double dfMax, int nBuckets,
2246 : GUIntBig *panHistogram, int bIncludeOutOfRange,
2247 : int bApproxOK, GDALProgressFunc,
2248 : void *pProgressData);
2249 :
2250 : virtual CPLErr GetDefaultHistogram(double *pdfMin, double *pdfMax,
2251 : int *pnBuckets, GUIntBig **ppanHistogram,
2252 : int bForce, GDALProgressFunc,
2253 : void *pProgressData);
2254 : virtual CPLErr SetDefaultHistogram(double dfMin, double dfMax, int nBuckets,
2255 : GUIntBig *panHistogram);
2256 :
2257 : virtual GDALRasterAttributeTable *GetDefaultRAT();
2258 : virtual CPLErr SetDefaultRAT(const GDALRasterAttributeTable *poRAT);
2259 :
2260 : virtual GDALRasterBand *GetMaskBand();
2261 : virtual int GetMaskFlags();
2262 : virtual CPLErr CreateMaskBand(int nFlagsIn);
2263 : virtual bool IsMaskBand() const;
2264 : virtual GDALMaskValueRange GetMaskValueRange() const;
2265 :
2266 : virtual CPLVirtualMem *
2267 : GetVirtualMemAuto(GDALRWFlag eRWFlag, int *pnPixelSpace,
2268 : GIntBig *pnLineSpace,
2269 : char **papszOptions) CPL_WARN_UNUSED_RESULT;
2270 :
2271 : int GetDataCoverageStatus(int nXOff, int nYOff, int nXSize, int nYSize,
2272 : int nMaskFlagStop = 0,
2273 : double *pdfDataPct = nullptr);
2274 :
2275 : std::shared_ptr<GDALMDArray> AsMDArray() const;
2276 :
2277 : CPLErr InterpolateAtGeolocation(
2278 : double dfGeolocX, double dfGeolocY, const OGRSpatialReference *poSRS,
2279 : GDALRIOResampleAlg eInterpolation, double *pdfRealValue,
2280 : double *pdfImagValue = nullptr,
2281 : CSLConstList papszTransformerOptions = nullptr) const;
2282 :
2283 : virtual CPLErr InterpolateAtPoint(double dfPixel, double dfLine,
2284 : GDALRIOResampleAlg eInterpolation,
2285 : double *pdfRealValue,
2286 : double *pdfImagValue = nullptr) const;
2287 :
2288 : //! @cond Doxygen_Suppress
2289 : class CPL_DLL WindowIterator
2290 : {
2291 : public:
2292 : using iterator_category = std::input_iterator_tag;
2293 : using difference_type = std::ptrdiff_t;
2294 :
2295 : using value_type = GDALRasterWindow;
2296 : using pointer = value_type *;
2297 : using reference = value_type &;
2298 :
2299 : WindowIterator(int nRasterXSize, int nRasterYSize, int nBlockXSize,
2300 : int nBlockYSize, int nRow, int nCol);
2301 :
2302 : bool operator==(const WindowIterator &other) const;
2303 :
2304 : bool operator!=(const WindowIterator &other) const;
2305 :
2306 : value_type operator*() const;
2307 :
2308 : WindowIterator &operator++();
2309 :
2310 : private:
2311 : const int m_nRasterXSize;
2312 : const int m_nRasterYSize;
2313 : const int m_nBlockXSize;
2314 : const int m_nBlockYSize;
2315 : int m_row;
2316 : int m_col;
2317 : };
2318 :
2319 : class CPL_DLL WindowIteratorWrapper
2320 : {
2321 : public:
2322 : explicit WindowIteratorWrapper(const GDALRasterBand &band);
2323 :
2324 : WindowIterator begin() const;
2325 :
2326 : WindowIterator end() const;
2327 :
2328 : private:
2329 : const int m_nRasterXSize;
2330 : const int m_nRasterYSize;
2331 : int m_nBlockXSize;
2332 : int m_nBlockYSize;
2333 : };
2334 :
2335 : //! @endcond
2336 :
2337 : WindowIteratorWrapper IterateWindows() const;
2338 :
2339 : #ifndef DOXYGEN_XML
2340 : void ReportError(CPLErr eErrClass, CPLErrorNum err_no, const char *fmt,
2341 : ...) const CPL_PRINT_FUNC_FORMAT(4, 5);
2342 : #endif
2343 :
2344 : //! @cond Doxygen_Suppress
2345 : static void ThrowIfNotSameDimensions(const GDALRasterBand &first,
2346 : const GDALRasterBand &second);
2347 :
2348 : //! @endcond
2349 :
2350 : /** Convert a GDALRasterBand* to a GDALRasterBandH.
2351 : * @since GDAL 2.3
2352 : */
2353 422642 : static inline GDALRasterBandH ToHandle(GDALRasterBand *poBand)
2354 : {
2355 422642 : return static_cast<GDALRasterBandH>(poBand);
2356 : }
2357 :
2358 : /** Convert a GDALRasterBandH to a GDALRasterBand*.
2359 : * @since GDAL 2.3
2360 : */
2361 5274346 : static inline GDALRasterBand *FromHandle(GDALRasterBandH hBand)
2362 : {
2363 5274346 : return static_cast<GDALRasterBand *>(hBand);
2364 : }
2365 :
2366 : //! @cond Doxygen_Suppress
2367 : // Remove me in GDAL 4.0. See GetMetadataItem() implementation
2368 : // Internal use in GDAL only !
2369 : virtual void EnablePixelTypeSignedByteWarning(bool b)
2370 : #ifndef GDAL_COMPILATION
2371 : CPL_WARN_DEPRECATED("Do not use that method outside of GDAL!")
2372 : #endif
2373 : ;
2374 :
2375 : //! @endcond
2376 :
2377 : private:
2378 : CPL_DISALLOW_COPY_ASSIGN(GDALRasterBand)
2379 : };
2380 :
2381 : //! @cond Doxygen_Suppress
2382 : #define GDAL_EXTERN_TEMPLATE_READ_RASTER(T) \
2383 : extern template CPLErr GDALRasterBand::ReadRaster<T>( \
2384 : T * pData, size_t nArrayEltCount, double dfXOff, double dfYOff, \
2385 : double dfXSize, double dfYSize, size_t nBufXSize, size_t nBufYSize, \
2386 : GDALRIOResampleAlg eResampleAlg, GDALProgressFunc pfnProgress, \
2387 : void *pProgressData) const;
2388 :
2389 : GDAL_EXTERN_TEMPLATE_READ_RASTER(uint8_t)
2390 : GDAL_EXTERN_TEMPLATE_READ_RASTER(int8_t)
2391 : GDAL_EXTERN_TEMPLATE_READ_RASTER(uint16_t)
2392 : GDAL_EXTERN_TEMPLATE_READ_RASTER(int16_t)
2393 : GDAL_EXTERN_TEMPLATE_READ_RASTER(uint32_t)
2394 : GDAL_EXTERN_TEMPLATE_READ_RASTER(int32_t)
2395 : GDAL_EXTERN_TEMPLATE_READ_RASTER(uint64_t)
2396 : GDAL_EXTERN_TEMPLATE_READ_RASTER(int64_t)
2397 : #ifdef CPL_FLOAT_H_INCLUDED
2398 : GDAL_EXTERN_TEMPLATE_READ_RASTER(GFloat16)
2399 : #endif
2400 : GDAL_EXTERN_TEMPLATE_READ_RASTER(float)
2401 : GDAL_EXTERN_TEMPLATE_READ_RASTER(double)
2402 : // Not allowed by C++ standard
2403 : // GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<int16_t>)
2404 : // GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<int32_t>)
2405 : GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<float>)
2406 : GDAL_EXTERN_TEMPLATE_READ_RASTER(std::complex<double>)
2407 :
2408 : #define GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(T) \
2409 : extern template CPLErr GDALRasterBand::ReadRaster<T>( \
2410 : std::vector<T> & vData, double dfXOff, double dfYOff, double dfXSize, \
2411 : double dfYSize, size_t nBufXSize, size_t nBufYSize, \
2412 : GDALRIOResampleAlg eResampleAlg, GDALProgressFunc pfnProgress, \
2413 : void *pProgressData) const;
2414 :
2415 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint8_t)
2416 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int8_t)
2417 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint16_t)
2418 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int16_t)
2419 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint32_t)
2420 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int32_t)
2421 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(uint64_t)
2422 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(int64_t)
2423 : #ifdef CPL_FLOAT_H_INCLUDED
2424 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(GFloat16)
2425 : #endif
2426 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(float)
2427 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(double)
2428 : // Not allowed by C++ standard
2429 : // GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<int16_t>)
2430 : // GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<int32_t>)
2431 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<float>)
2432 : GDAL_EXTERN_TEMPLATE_READ_RASTER_VECTOR(std::complex<double>)
2433 :
2434 : //! @endcond
2435 :
2436 : /* ******************************************************************** */
2437 : /* GDALComputedRasterBand */
2438 : /* ******************************************************************** */
2439 :
2440 : /** Class represented the result of an operation on one or two input bands.
2441 : *
2442 : * Such class is instantiated only by operators on GDALRasterBand.
2443 : * The resulting band is lazy evaluated.
2444 : *
2445 : * @since 3.12
2446 : */
2447 : class CPL_DLL GDALComputedRasterBand final : public GDALRasterBand
2448 : {
2449 : public:
2450 : /** Destructor */
2451 : ~GDALComputedRasterBand() override;
2452 :
2453 : //! @cond Doxygen_Suppress
2454 : enum class Operation
2455 : {
2456 : OP_ADD,
2457 : OP_SUBTRACT,
2458 : OP_MULTIPLY,
2459 : OP_DIVIDE,
2460 : OP_MIN,
2461 : OP_MAX,
2462 : OP_MEAN,
2463 : OP_GT,
2464 : OP_GE,
2465 : OP_LT,
2466 : OP_LE,
2467 : OP_EQ,
2468 : OP_NE,
2469 : OP_LOGICAL_AND,
2470 : OP_LOGICAL_OR,
2471 : OP_CAST,
2472 : OP_TERNARY,
2473 : OP_ABS,
2474 : OP_SQRT,
2475 : OP_LOG,
2476 : OP_LOG10,
2477 : OP_POW,
2478 : };
2479 :
2480 : GDALComputedRasterBand(
2481 : Operation op, const std::vector<const GDALRasterBand *> &bands,
2482 : double constant = std::numeric_limits<double>::quiet_NaN());
2483 : GDALComputedRasterBand(Operation op, const GDALRasterBand &band);
2484 : GDALComputedRasterBand(Operation op, double constant,
2485 : const GDALRasterBand &band);
2486 : GDALComputedRasterBand(Operation op, const GDALRasterBand &band,
2487 : double constant);
2488 : GDALComputedRasterBand(Operation op, const GDALRasterBand &band,
2489 : GDALDataType dt);
2490 :
2491 : // Semi-public for gdal::min(), gdal::max()
2492 : GDALComputedRasterBand(Operation op, const GDALRasterBand &firstBand,
2493 : const GDALRasterBand &secondBand);
2494 :
2495 : GDALComputedRasterBand(GDALComputedRasterBand &&) = default;
2496 :
2497 : //! @endcond
2498 :
2499 : double GetNoDataValue(int *pbSuccess = nullptr) override;
2500 :
2501 : /** Convert a GDALComputedRasterBand* to a GDALComputedRasterBandH.
2502 : */
2503 : static inline GDALComputedRasterBandH
2504 : ToHandle(GDALComputedRasterBand *poBand)
2505 : {
2506 : return static_cast<GDALComputedRasterBandH>(poBand);
2507 : }
2508 :
2509 : /** Convert a GDALComputedRasterBandH to a GDALComputedRasterBand*.
2510 : */
2511 : static inline GDALComputedRasterBand *
2512 163 : FromHandle(GDALComputedRasterBandH hBand)
2513 : {
2514 163 : return static_cast<GDALComputedRasterBand *>(hBand);
2515 : }
2516 :
2517 : protected:
2518 : friend class GDALRasterBand;
2519 :
2520 : CPLErr IReadBlock(int, int, void *) override;
2521 :
2522 : CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
2523 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
2524 : GDALDataType eBufType, GSpacing nPixelSpace,
2525 : GSpacing nLineSpace,
2526 : GDALRasterIOExtraArg *psExtraArg) override;
2527 :
2528 : private:
2529 : friend class GDALComputedDataset;
2530 : std::unique_ptr<GDALDataset, GDALDatasetUniquePtrReleaser> m_poOwningDS{};
2531 : bool m_bHasNoData{false};
2532 : double m_dfNoDataValue{0};
2533 :
2534 : GDALComputedRasterBand(const GDALComputedRasterBand &, bool);
2535 : GDALComputedRasterBand(const GDALComputedRasterBand &) = delete;
2536 : GDALComputedRasterBand &operator=(const GDALComputedRasterBand &) = delete;
2537 : GDALComputedRasterBand &operator=(GDALComputedRasterBand &&) = delete;
2538 : };
2539 :
2540 : namespace gdal
2541 : {
2542 : using std::abs;
2543 : GDALComputedRasterBand CPL_DLL abs(const GDALRasterBand &band);
2544 :
2545 : using std::fabs;
2546 : GDALComputedRasterBand CPL_DLL fabs(const GDALRasterBand &band);
2547 :
2548 : using std::sqrt;
2549 : GDALComputedRasterBand CPL_DLL sqrt(const GDALRasterBand &band);
2550 :
2551 : using std::log;
2552 : GDALComputedRasterBand CPL_DLL log(const GDALRasterBand &band);
2553 :
2554 : using std::log10;
2555 : GDALComputedRasterBand CPL_DLL log10(const GDALRasterBand &band);
2556 :
2557 : using std::pow;
2558 : GDALComputedRasterBand CPL_DLL pow(const GDALRasterBand &band, double constant);
2559 : #ifndef DOXYGEN_SKIP
2560 : GDALComputedRasterBand CPL_DLL pow(double constant, const GDALRasterBand &band);
2561 : GDALComputedRasterBand CPL_DLL pow(const GDALRasterBand &band1,
2562 : const GDALRasterBand &band2);
2563 : #endif
2564 :
2565 : GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
2566 : const GDALRasterBand &thenBand,
2567 : const GDALRasterBand &elseBand);
2568 :
2569 : //! @cond Doxygen_Suppress
2570 :
2571 : GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
2572 : double thenValue,
2573 : const GDALRasterBand &elseBand);
2574 :
2575 : GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
2576 : const GDALRasterBand &thenBand,
2577 : double elseValue);
2578 :
2579 : GDALComputedRasterBand CPL_DLL IfThenElse(const GDALRasterBand &condBand,
2580 : double thenValue, double elseValue);
2581 :
2582 : //! @endcond
2583 :
2584 : using std::max;
2585 : using std::min;
2586 :
2587 : GDALComputedRasterBand CPL_DLL min(const GDALRasterBand &first,
2588 : const GDALRasterBand &second);
2589 :
2590 : //! @cond Doxygen_Suppress
2591 :
2592 : namespace detail
2593 : {
2594 :
2595 : template <typename U, typename Enable> struct minDealFirstArg;
2596 :
2597 : template <typename U>
2598 : struct minDealFirstArg<
2599 : U, typename std::enable_if<std::is_arithmetic<U>::value>::type>
2600 : {
2601 2 : inline static void process(std::vector<const GDALRasterBand *> &,
2602 : double &constant, const U &first)
2603 : {
2604 2 : if (std::isnan(constant) || static_cast<double>(first) < constant)
2605 2 : constant = static_cast<double>(first);
2606 2 : }
2607 : };
2608 :
2609 : template <typename U>
2610 : struct minDealFirstArg<
2611 : U, typename std::enable_if<!std::is_arithmetic<U>::value>::type>
2612 : {
2613 16 : inline static void process(std::vector<const GDALRasterBand *> &bands,
2614 : double &, const U &first)
2615 : {
2616 16 : if (!bands.empty())
2617 10 : GDALRasterBand::ThrowIfNotSameDimensions(first, *(bands.front()));
2618 14 : bands.push_back(&first);
2619 14 : }
2620 : };
2621 :
2622 : inline static GDALComputedRasterBand
2623 4 : minInternal(std::vector<const GDALRasterBand *> &bands, double constant)
2624 : {
2625 : return GDALComputedRasterBand(GDALComputedRasterBand::Operation::OP_MIN,
2626 4 : bands, constant);
2627 : }
2628 :
2629 : template <typename U, typename... V>
2630 18 : GDALComputedRasterBand minInternal(std::vector<const GDALRasterBand *> &bands,
2631 : double constant, const U &first, V &&...rest)
2632 : {
2633 18 : minDealFirstArg<U, void>::process(bands, constant, first);
2634 16 : return minInternal(bands, constant, std::forward<V>(rest)...);
2635 : }
2636 :
2637 : } // namespace detail
2638 :
2639 : template <typename U, typename... V>
2640 6 : inline GDALComputedRasterBand min(const U &first, V &&...rest)
2641 : {
2642 12 : std::vector<const GDALRasterBand *> bands;
2643 : return detail::minInternal(bands, std::numeric_limits<double>::quiet_NaN(),
2644 10 : first, std::forward<V>(rest)...);
2645 : }
2646 :
2647 : //! @endcond
2648 :
2649 : GDALComputedRasterBand CPL_DLL max(const GDALRasterBand &first,
2650 : const GDALRasterBand &second);
2651 :
2652 : //! @cond Doxygen_Suppress
2653 :
2654 : namespace detail
2655 : {
2656 :
2657 : template <typename U, typename Enable> struct maxDealFirstArg;
2658 :
2659 : template <typename U>
2660 : struct maxDealFirstArg<
2661 : U, typename std::enable_if<std::is_arithmetic<U>::value>::type>
2662 : {
2663 2 : inline static void process(std::vector<const GDALRasterBand *> &,
2664 : double &constant, const U &first)
2665 : {
2666 2 : if (std::isnan(constant) || static_cast<double>(first) > constant)
2667 2 : constant = static_cast<double>(first);
2668 2 : }
2669 : };
2670 :
2671 : template <typename U>
2672 : struct maxDealFirstArg<
2673 : U, typename std::enable_if<!std::is_arithmetic<U>::value>::type>
2674 : {
2675 14 : inline static void process(std::vector<const GDALRasterBand *> &bands,
2676 : double &, const U &first)
2677 : {
2678 14 : if (!bands.empty())
2679 9 : GDALRasterBand::ThrowIfNotSameDimensions(first, *(bands.front()));
2680 12 : bands.push_back(&first);
2681 12 : }
2682 : };
2683 :
2684 : inline static GDALComputedRasterBand
2685 3 : maxInternal(std::vector<const GDALRasterBand *> &bands, double constant)
2686 : {
2687 : return GDALComputedRasterBand(GDALComputedRasterBand::Operation::OP_MAX,
2688 3 : bands, constant);
2689 : }
2690 :
2691 : template <typename U, typename... V>
2692 16 : GDALComputedRasterBand maxInternal(std::vector<const GDALRasterBand *> &bands,
2693 : double constant, const U &first, V &&...rest)
2694 : {
2695 16 : maxDealFirstArg<U, void>::process(bands, constant, first);
2696 14 : return maxInternal(bands, constant, std::forward<V>(rest)...);
2697 : }
2698 :
2699 : } // namespace detail
2700 :
2701 : template <typename U, typename... V>
2702 5 : inline GDALComputedRasterBand max(const U &first, V &&...rest)
2703 : {
2704 10 : std::vector<const GDALRasterBand *> bands;
2705 : return detail::maxInternal(bands, std::numeric_limits<double>::quiet_NaN(),
2706 8 : first, std::forward<V>(rest)...);
2707 : }
2708 :
2709 : //! @endcond
2710 :
2711 : GDALComputedRasterBand CPL_DLL mean(const GDALRasterBand &first,
2712 : const GDALRasterBand &second);
2713 :
2714 : //! @cond Doxygen_Suppress
2715 : inline GDALComputedRasterBand
2716 1 : meanInternal(std::vector<const GDALRasterBand *> &bands)
2717 : {
2718 : return GDALComputedRasterBand(GDALComputedRasterBand::Operation::OP_MEAN,
2719 1 : bands);
2720 : }
2721 :
2722 : template <typename U, typename... V>
2723 : inline GDALComputedRasterBand
2724 8 : meanInternal(std::vector<const GDALRasterBand *> &bands, const U &first,
2725 : V &&...rest)
2726 : {
2727 8 : if (!bands.empty())
2728 5 : GDALRasterBand::ThrowIfNotSameDimensions(first, *(bands.front()));
2729 6 : bands.push_back(&first);
2730 6 : return meanInternal(bands, std::forward<V>(rest)...);
2731 : }
2732 :
2733 3 : template <typename... Args> inline GDALComputedRasterBand mean(Args &&...args)
2734 : {
2735 6 : std::vector<const GDALRasterBand *> bands;
2736 4 : return meanInternal(bands, std::forward<Args>(args)...);
2737 : }
2738 :
2739 : //! @endcond
2740 :
2741 : } // namespace gdal
2742 :
2743 : //! @cond Doxygen_Suppress
2744 : /* ******************************************************************** */
2745 : /* GDALAllValidMaskBand */
2746 : /* ******************************************************************** */
2747 :
2748 318276 : class CPL_DLL GDALAllValidMaskBand : public GDALRasterBand
2749 : {
2750 : protected:
2751 : CPLErr IReadBlock(int, int, void *) override;
2752 :
2753 : CPLErr IRasterIO(GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize,
2754 : int nYSize, void *pData, int nBufXSize, int nBufYSize,
2755 : GDALDataType eBufType, GSpacing nPixelSpace,
2756 : GSpacing nLineSpace,
2757 : GDALRasterIOExtraArg *psExtraArg) override;
2758 :
2759 : bool
2760 : EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2761 :
2762 : CPL_DISALLOW_COPY_ASSIGN(GDALAllValidMaskBand)
2763 :
2764 : public:
2765 : explicit GDALAllValidMaskBand(GDALRasterBand *);
2766 : ~GDALAllValidMaskBand() override;
2767 :
2768 : GDALRasterBand *GetMaskBand() override;
2769 : int GetMaskFlags() override;
2770 :
2771 1 : bool IsMaskBand() const override
2772 : {
2773 1 : return true;
2774 : }
2775 :
2776 0 : GDALMaskValueRange GetMaskValueRange() const override
2777 : {
2778 0 : return GMVR_0_AND_255_ONLY;
2779 : }
2780 :
2781 : CPLErr ComputeStatistics(int bApproxOK, double *pdfMin, double *pdfMax,
2782 : double *pdfMean, double *pdfStdDev,
2783 : GDALProgressFunc, void *pProgressData) override;
2784 : };
2785 :
2786 : /* ******************************************************************** */
2787 : /* GDALNoDataMaskBand */
2788 : /* ******************************************************************** */
2789 :
2790 2174 : class CPL_DLL GDALNoDataMaskBand : public GDALRasterBand
2791 : {
2792 : friend class GDALRasterBand;
2793 : double m_dfNoDataValue = 0;
2794 : int64_t m_nNoDataValueInt64 = 0;
2795 : uint64_t m_nNoDataValueUInt64 = 0;
2796 : GDALRasterBand *m_poParent = nullptr;
2797 :
2798 : CPL_DISALLOW_COPY_ASSIGN(GDALNoDataMaskBand)
2799 :
2800 : protected:
2801 : CPLErr IReadBlock(int, int, void *) override;
2802 : CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
2803 : GDALDataType, GSpacing, GSpacing,
2804 : GDALRasterIOExtraArg *psExtraArg) override;
2805 :
2806 : bool
2807 : EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2808 :
2809 : public:
2810 : explicit GDALNoDataMaskBand(GDALRasterBand *);
2811 : explicit GDALNoDataMaskBand(GDALRasterBand *, double dfNoDataValue);
2812 : ~GDALNoDataMaskBand() override;
2813 :
2814 1 : bool IsMaskBand() const override
2815 : {
2816 1 : return true;
2817 : }
2818 :
2819 0 : GDALMaskValueRange GetMaskValueRange() const override
2820 : {
2821 0 : return GMVR_0_AND_255_ONLY;
2822 : }
2823 :
2824 : static bool IsNoDataInRange(double dfNoDataValue, GDALDataType eDataType);
2825 : };
2826 :
2827 : /* ******************************************************************** */
2828 : /* GDALNoDataValuesMaskBand */
2829 : /* ******************************************************************** */
2830 :
2831 : class CPL_DLL GDALNoDataValuesMaskBand : public GDALRasterBand
2832 : {
2833 : double *padfNodataValues;
2834 :
2835 : CPL_DISALLOW_COPY_ASSIGN(GDALNoDataValuesMaskBand)
2836 :
2837 : protected:
2838 : CPLErr IReadBlock(int, int, void *) override;
2839 :
2840 : bool
2841 : EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2842 :
2843 : public:
2844 : explicit GDALNoDataValuesMaskBand(GDALDataset *);
2845 : ~GDALNoDataValuesMaskBand() override;
2846 :
2847 0 : bool IsMaskBand() const override
2848 : {
2849 0 : return true;
2850 : }
2851 :
2852 0 : GDALMaskValueRange GetMaskValueRange() const override
2853 : {
2854 0 : return GMVR_0_AND_255_ONLY;
2855 : }
2856 : };
2857 :
2858 : /* ******************************************************************** */
2859 : /* GDALRescaledAlphaBand */
2860 : /* ******************************************************************** */
2861 :
2862 : class GDALRescaledAlphaBand : public GDALRasterBand
2863 : {
2864 : GDALRasterBand *poParent;
2865 : void *pTemp;
2866 :
2867 : CPL_DISALLOW_COPY_ASSIGN(GDALRescaledAlphaBand)
2868 :
2869 : protected:
2870 : CPLErr IReadBlock(int, int, void *) override;
2871 : CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
2872 : GDALDataType, GSpacing, GSpacing,
2873 : GDALRasterIOExtraArg *psExtraArg) override;
2874 :
2875 : bool
2876 : EmitErrorMessageIfWriteNotSupported(const char *pszCaller) const override;
2877 :
2878 : public:
2879 : explicit GDALRescaledAlphaBand(GDALRasterBand *);
2880 : ~GDALRescaledAlphaBand() override;
2881 :
2882 0 : bool IsMaskBand() const override
2883 : {
2884 0 : return true;
2885 : }
2886 : };
2887 :
2888 : //! @endcond
2889 :
2890 : /* ******************************************************************** */
2891 : /* GDALIdentifyEnum */
2892 : /* ******************************************************************** */
2893 :
2894 : /**
2895 : * Enumeration used by GDALDriver::pfnIdentify().
2896 : *
2897 : * @since GDAL 2.1
2898 : */
2899 : typedef enum
2900 : {
2901 : /** Identify could not determine if the file is recognized or not by the
2902 : probed driver. */
2903 : GDAL_IDENTIFY_UNKNOWN = -1,
2904 : /** Identify determined the file is not recognized by the probed driver. */
2905 : GDAL_IDENTIFY_FALSE = 0,
2906 : /** Identify determined the file is recognized by the probed driver. */
2907 : GDAL_IDENTIFY_TRUE = 1
2908 : } GDALIdentifyEnum;
2909 :
2910 : /* ******************************************************************** */
2911 : /* GDALDriver */
2912 : /* ******************************************************************** */
2913 :
2914 : /**
2915 : * \brief Format specific driver.
2916 : *
2917 : * An instance of this class is created for each supported format, and
2918 : * manages information about the format.
2919 : *
2920 : * This roughly corresponds to a file format, though some
2921 : * drivers may be gateways to many formats through a secondary
2922 : * multi-library.
2923 : */
2924 :
2925 380035 : class CPL_DLL GDALDriver : public GDALMajorObject
2926 : {
2927 : public:
2928 : GDALDriver();
2929 : ~GDALDriver() override;
2930 :
2931 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
2932 : const char *pszDomain = "") override;
2933 :
2934 : /* -------------------------------------------------------------------- */
2935 : /* Public C++ methods. */
2936 : /* -------------------------------------------------------------------- */
2937 : GDALDataset *Create(const char *pszName, int nXSize, int nYSize, int nBands,
2938 : GDALDataType eType,
2939 : CSLConstList papszOptions) CPL_WARN_UNUSED_RESULT;
2940 :
2941 : GDALDataset *
2942 : CreateMultiDimensional(const char *pszName,
2943 : CSLConstList papszRootGroupOptions,
2944 : CSLConstList papszOptions) CPL_WARN_UNUSED_RESULT;
2945 :
2946 : CPLErr Delete(const char *pszName);
2947 : CPLErr Rename(const char *pszNewName, const char *pszOldName);
2948 : CPLErr CopyFiles(const char *pszNewName, const char *pszOldName);
2949 :
2950 : GDALDataset *CreateCopy(const char *, GDALDataset *, int,
2951 : CSLConstList papszOptions,
2952 : GDALProgressFunc pfnProgress,
2953 : void *pProgressData) CPL_WARN_UNUSED_RESULT;
2954 :
2955 : bool CanVectorTranslateFrom(const char *pszDestName,
2956 : GDALDataset *poSourceDS,
2957 : CSLConstList papszVectorTranslateArguments,
2958 : char ***ppapszFailureReasons);
2959 :
2960 : /**
2961 : * \brief Returns TRUE if the given open option is supported by the driver.
2962 : * @param pszOpenOptionName name of the open option to be checked
2963 : * @return TRUE if the driver supports the open option
2964 : * @since GDAL 3.11
2965 : */
2966 : bool HasOpenOption(const char *pszOpenOptionName) const;
2967 :
2968 : GDALDataset *
2969 : VectorTranslateFrom(const char *pszDestName, GDALDataset *poSourceDS,
2970 : CSLConstList papszVectorTranslateArguments,
2971 : GDALProgressFunc pfnProgress,
2972 : void *pProgressData) CPL_WARN_UNUSED_RESULT;
2973 :
2974 : /* -------------------------------------------------------------------- */
2975 : /* The following are semiprivate, not intended to be accessed */
2976 : /* by anyone but the formats instantiating and populating the */
2977 : /* drivers. */
2978 : /* -------------------------------------------------------------------- */
2979 : //! @cond Doxygen_Suppress
2980 :
2981 : // Not aimed at being used outside of GDAL. Use GDALDataset::Open() instead
2982 : GDALDataset *Open(GDALOpenInfo *poOpenInfo, bool bSetOpenOptions);
2983 :
2984 : typedef GDALDataset *(*OpenCallback)(GDALOpenInfo *);
2985 :
2986 : OpenCallback pfnOpen = nullptr;
2987 :
2988 437733 : virtual OpenCallback GetOpenCallback()
2989 : {
2990 437733 : return pfnOpen;
2991 : }
2992 :
2993 : typedef GDALDataset *(*CreateCallback)(const char *pszName, int nXSize,
2994 : int nYSize, int nBands,
2995 : GDALDataType eType,
2996 : char **papszOptions);
2997 :
2998 : CreateCallback pfnCreate = nullptr;
2999 :
3000 22287 : virtual CreateCallback GetCreateCallback()
3001 : {
3002 22287 : return pfnCreate;
3003 : }
3004 :
3005 : GDALDataset *(*pfnCreateEx)(GDALDriver *, const char *pszName, int nXSize,
3006 : int nYSize, int nBands, GDALDataType eType,
3007 : char **papszOptions) = nullptr;
3008 :
3009 : typedef GDALDataset *(*CreateMultiDimensionalCallback)(
3010 : const char *pszName, CSLConstList papszRootGroupOptions,
3011 : CSLConstList papszOptions);
3012 :
3013 : CreateMultiDimensionalCallback pfnCreateMultiDimensional = nullptr;
3014 :
3015 472 : virtual CreateMultiDimensionalCallback GetCreateMultiDimensionalCallback()
3016 : {
3017 472 : return pfnCreateMultiDimensional;
3018 : }
3019 :
3020 : typedef CPLErr (*DeleteCallback)(const char *pszName);
3021 : DeleteCallback pfnDelete = nullptr;
3022 :
3023 5428 : virtual DeleteCallback GetDeleteCallback()
3024 : {
3025 5428 : return pfnDelete;
3026 : }
3027 :
3028 : typedef GDALDataset *(*CreateCopyCallback)(const char *, GDALDataset *, int,
3029 : char **,
3030 : GDALProgressFunc pfnProgress,
3031 : void *pProgressData);
3032 :
3033 : CreateCopyCallback pfnCreateCopy = nullptr;
3034 :
3035 10992 : virtual CreateCopyCallback GetCreateCopyCallback()
3036 : {
3037 10992 : return pfnCreateCopy;
3038 : }
3039 :
3040 : void *pDriverData = nullptr;
3041 :
3042 : void (*pfnUnloadDriver)(GDALDriver *) = nullptr;
3043 :
3044 : /** Identify() if the file is recognized or not by the driver.
3045 :
3046 : Return GDAL_IDENTIFY_TRUE (1) if the passed file is certainly recognized
3047 : by the driver. Return GDAL_IDENTIFY_FALSE (0) if the passed file is
3048 : certainly NOT recognized by the driver. Return GDAL_IDENTIFY_UNKNOWN (-1)
3049 : if the passed file may be or may not be recognized by the driver, and
3050 : that a potentially costly test must be done with pfnOpen.
3051 : */
3052 : int (*pfnIdentify)(GDALOpenInfo *) = nullptr;
3053 : int (*pfnIdentifyEx)(GDALDriver *, GDALOpenInfo *) = nullptr;
3054 :
3055 : typedef CPLErr (*RenameCallback)(const char *pszNewName,
3056 : const char *pszOldName);
3057 : RenameCallback pfnRename = nullptr;
3058 :
3059 175 : virtual RenameCallback GetRenameCallback()
3060 : {
3061 175 : return pfnRename;
3062 : }
3063 :
3064 : typedef CPLErr (*CopyFilesCallback)(const char *pszNewName,
3065 : const char *pszOldName);
3066 : CopyFilesCallback pfnCopyFiles = nullptr;
3067 :
3068 12 : virtual CopyFilesCallback GetCopyFilesCallback()
3069 : {
3070 12 : return pfnCopyFiles;
3071 : }
3072 :
3073 : // Used for legacy OGR drivers, and Python drivers
3074 : GDALDataset *(*pfnOpenWithDriverArg)(GDALDriver *,
3075 : GDALOpenInfo *) = nullptr;
3076 :
3077 : /* For legacy OGR drivers */
3078 : GDALDataset *(*pfnCreateVectorOnly)(GDALDriver *, const char *pszName,
3079 : char **papszOptions) = nullptr;
3080 : CPLErr (*pfnDeleteDataSource)(GDALDriver *, const char *pszName) = nullptr;
3081 :
3082 : /** Whether pfnVectorTranslateFrom() can be run given the source dataset
3083 : * and the non-positional arguments of GDALVectorTranslate() stored
3084 : * in papszVectorTranslateArguments.
3085 : */
3086 : bool (*pfnCanVectorTranslateFrom)(
3087 : const char *pszDestName, GDALDataset *poSourceDS,
3088 : CSLConstList papszVectorTranslateArguments,
3089 : char ***ppapszFailureReasons) = nullptr;
3090 :
3091 : /** Creates a copy from the specified source dataset, using the
3092 : * non-positional arguments of GDALVectorTranslate() stored
3093 : * in papszVectorTranslateArguments.
3094 : */
3095 : GDALDataset *(*pfnVectorTranslateFrom)(
3096 : const char *pszDestName, GDALDataset *poSourceDS,
3097 : CSLConstList papszVectorTranslateArguments,
3098 : GDALProgressFunc pfnProgress, void *pProgressData) = nullptr;
3099 :
3100 : /**
3101 : * Returns a (possibly null) pointer to the Subdataset informational function
3102 : * from the subdataset file name.
3103 : */
3104 : GDALSubdatasetInfo *(*pfnGetSubdatasetInfoFunc)(const char *pszFileName) =
3105 : nullptr;
3106 :
3107 : typedef GDALAlgorithm *(*InstantiateAlgorithmCallback)(
3108 : const std::vector<std::string> &aosPath);
3109 : InstantiateAlgorithmCallback pfnInstantiateAlgorithm = nullptr;
3110 :
3111 56 : virtual InstantiateAlgorithmCallback GetInstantiateAlgorithmCallback()
3112 : {
3113 56 : return pfnInstantiateAlgorithm;
3114 : }
3115 :
3116 : /** Instantiate an algorithm by its full path (omitting leading "gdal").
3117 : * For example {"driver", "pdf", "list-layers"}
3118 : */
3119 : GDALAlgorithm *
3120 : InstantiateAlgorithm(const std::vector<std::string> &aosPath);
3121 :
3122 : /** Declare an algorithm by its full path (omitting leading "gdal").
3123 : * For example {"driver", "pdf", "list-layers"}
3124 : */
3125 : void DeclareAlgorithm(const std::vector<std::string> &aosPath);
3126 :
3127 : //! @endcond
3128 :
3129 : /* -------------------------------------------------------------------- */
3130 : /* Helper methods. */
3131 : /* -------------------------------------------------------------------- */
3132 : //! @cond Doxygen_Suppress
3133 : GDALDataset *DefaultCreateCopy(const char *, GDALDataset *, int,
3134 : CSLConstList papszOptions,
3135 : GDALProgressFunc pfnProgress,
3136 : void *pProgressData) CPL_WARN_UNUSED_RESULT;
3137 :
3138 : static CPLErr DefaultCreateCopyMultiDimensional(
3139 : GDALDataset *poSrcDS, GDALDataset *poDstDS, bool bStrict,
3140 : CSLConstList /*papszOptions*/, GDALProgressFunc pfnProgress,
3141 : void *pProgressData);
3142 :
3143 : static CPLErr DefaultCopyMasks(GDALDataset *poSrcDS, GDALDataset *poDstDS,
3144 : int bStrict);
3145 : static CPLErr DefaultCopyMasks(GDALDataset *poSrcDS, GDALDataset *poDstDS,
3146 : int bStrict, CSLConstList papszOptions,
3147 : GDALProgressFunc pfnProgress,
3148 : void *pProgressData);
3149 :
3150 : CPLErr QuietDeleteForCreateCopy(const char *pszFilename,
3151 : GDALDataset *poSrcDS);
3152 :
3153 : //! @endcond
3154 : static CPLErr QuietDelete(const char *pszName,
3155 : CSLConstList papszAllowedDrivers = nullptr);
3156 :
3157 : //! @cond Doxygen_Suppress
3158 : static CPLErr DefaultRename(const char *pszNewName, const char *pszOldName);
3159 : static CPLErr DefaultCopyFiles(const char *pszNewName,
3160 : const char *pszOldName);
3161 : static void DefaultCopyMetadata(GDALDataset *poSrcDS, GDALDataset *poDstDS,
3162 : CSLConstList papszOptions,
3163 : CSLConstList papszExcludedDomains);
3164 :
3165 : //! @endcond
3166 :
3167 : /** Convert a GDALDriver* to a GDALDriverH.
3168 : * @since GDAL 2.3
3169 : */
3170 169666 : static inline GDALDriverH ToHandle(GDALDriver *poDriver)
3171 : {
3172 169666 : return static_cast<GDALDriverH>(poDriver);
3173 : }
3174 :
3175 : /** Convert a GDALDriverH to a GDALDriver*.
3176 : * @since GDAL 2.3
3177 : */
3178 3859771 : static inline GDALDriver *FromHandle(GDALDriverH hDriver)
3179 : {
3180 3859771 : return static_cast<GDALDriver *>(hDriver);
3181 : }
3182 :
3183 : private:
3184 : CPL_DISALLOW_COPY_ASSIGN(GDALDriver)
3185 : };
3186 :
3187 : /************************************************************************/
3188 : /* GDALPluginDriverProxy */
3189 : /************************************************************************/
3190 :
3191 : // clang-format off
3192 : /** Proxy for a plugin driver.
3193 : *
3194 : * Such proxy must be registered with
3195 : * GDALDriverManager::DeclareDeferredPluginDriver().
3196 : *
3197 : * If the real driver defines any of the following metadata items, the
3198 : * proxy driver should also define them with the same value:
3199 : * <ul>
3200 : * <li>GDAL_DMD_LONGNAME</li>
3201 : * <li>GDAL_DMD_EXTENSIONS</li>
3202 : * <li>GDAL_DMD_EXTENSION</li>
3203 : * <li>GDAL_DMD_OPENOPTIONLIST</li>
3204 : * <li>GDAL_DMD_SUBDATASETS</li>
3205 : * <li>GDAL_DMD_CONNECTION_PREFIX</li>
3206 : * <li>GDAL_DCAP_RASTER</li>
3207 : * <li>GDAL_DCAP_MULTIDIM_RASTER</li>
3208 : * <li>GDAL_DCAP_VECTOR</li>
3209 : * <li>GDAL_DCAP_GNM</li>
3210 : * <li>GDAL_DCAP_MULTIPLE_VECTOR_LAYERS</li>
3211 : * <li>GDAL_DCAP_NONSPATIAL</li>
3212 : * <li>GDAL_DCAP_VECTOR_TRANSLATE_FROM</li>
3213 : * </ul>
3214 : *
3215 : * The pfnIdentify and pfnGetSubdatasetInfoFunc callbacks, if they are
3216 : * defined in the real driver, should also be set on the proxy driver.
3217 : *
3218 : * Furthermore, the following metadata items must be defined if the real
3219 : * driver sets the corresponding callback:
3220 : * <ul>
3221 : * <li>GDAL_DCAP_OPEN: must be set to YES if the real driver defines pfnOpen</li>
3222 : * <li>GDAL_DCAP_CREATE: must be set to YES if the real driver defines pfnCreate</li>
3223 : * <li>GDAL_DCAP_CREATE_MULTIDIMENSIONAL: must be set to YES if the real driver defines pfnCreateMultiDimensional</li>
3224 : * <li>GDAL_DCAP_CREATECOPY: must be set to YES if the real driver defines pfnCreateCopy</li>
3225 : * </ul>
3226 : *
3227 : * @since 3.9
3228 : */
3229 : // clang-format on
3230 :
3231 : class GDALPluginDriverProxy : public GDALDriver
3232 : {
3233 : const std::string m_osPluginFileName;
3234 : std::string m_osPluginFullPath{};
3235 : std::unique_ptr<GDALDriver> m_poRealDriver{};
3236 : std::set<std::string> m_oSetMetadataItems{};
3237 :
3238 : GDALDriver *GetRealDriver();
3239 :
3240 : CPL_DISALLOW_COPY_ASSIGN(GDALPluginDriverProxy)
3241 :
3242 : protected:
3243 : friend class GDALDriverManager;
3244 :
3245 : //! @cond Doxygen_Suppress
3246 73964 : void SetPluginFullPath(const std::string &osFullPath)
3247 : {
3248 73964 : m_osPluginFullPath = osFullPath;
3249 73964 : }
3250 :
3251 : //! @endcond
3252 :
3253 : public:
3254 : explicit GDALPluginDriverProxy(const std::string &osPluginFileName);
3255 :
3256 : /** Return the plugin file name (not a full path) */
3257 73964 : const std::string &GetPluginFileName() const
3258 : {
3259 73964 : return m_osPluginFileName;
3260 : }
3261 :
3262 : //! @cond Doxygen_Suppress
3263 : OpenCallback GetOpenCallback() override;
3264 :
3265 : CreateCallback GetCreateCallback() override;
3266 :
3267 : CreateMultiDimensionalCallback GetCreateMultiDimensionalCallback() override;
3268 :
3269 : CreateCopyCallback GetCreateCopyCallback() override;
3270 :
3271 : DeleteCallback GetDeleteCallback() override;
3272 :
3273 : RenameCallback GetRenameCallback() override;
3274 :
3275 : CopyFilesCallback GetCopyFilesCallback() override;
3276 :
3277 : InstantiateAlgorithmCallback GetInstantiateAlgorithmCallback() override;
3278 : //! @endcond
3279 :
3280 : CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
3281 : const char *pszDomain = "") override;
3282 :
3283 : char **GetMetadata(const char *pszDomain) override;
3284 :
3285 : const char *GetMetadataItem(const char *pszName,
3286 : const char *pszDomain = "") override;
3287 : };
3288 :
3289 : /* ******************************************************************** */
3290 : /* GDALDriverManager */
3291 : /* ******************************************************************** */
3292 :
3293 : /**
3294 : * Class for managing the registration of file format drivers.
3295 : *
3296 : * Use GetGDALDriverManager() to fetch the global singleton instance of
3297 : * this class.
3298 : */
3299 :
3300 : class CPL_DLL GDALDriverManager : public GDALMajorObject
3301 : {
3302 : int nDrivers = 0;
3303 : GDALDriver **papoDrivers = nullptr;
3304 : std::map<CPLString, GDALDriver *> oMapNameToDrivers{};
3305 : std::string m_osPluginPath{};
3306 : std::string m_osDriversIniPath{};
3307 : mutable std::string m_osLastTriedDirectory{};
3308 : std::set<std::string> m_oSetPluginFileNames{};
3309 : bool m_bInDeferredDriverLoading = false;
3310 : std::map<std::string, std::unique_ptr<GDALDriver>> m_oMapRealDrivers{};
3311 : std::vector<std::unique_ptr<GDALDriver>> m_aoHiddenDrivers{};
3312 :
3313 19814900 : GDALDriver *GetDriver_unlocked(int iDriver)
3314 : {
3315 19814900 : return (iDriver >= 0 && iDriver < nDrivers) ? papoDrivers[iDriver]
3316 19814900 : : nullptr;
3317 : }
3318 :
3319 : GDALDriver *GetDriverByName_unlocked(const char *pszName) const;
3320 :
3321 : static void CleanupPythonDrivers();
3322 :
3323 : std::string GetPluginFullPath(const char *pszFilename) const;
3324 :
3325 : int RegisterDriver(GDALDriver *, bool bHidden);
3326 :
3327 : CPL_DISALLOW_COPY_ASSIGN(GDALDriverManager)
3328 :
3329 : protected:
3330 : friend class GDALPluginDriverProxy;
3331 : friend GDALDatasetH CPL_STDCALL
3332 : GDALOpenEx(const char *pszFilename, unsigned int nOpenFlags,
3333 : const char *const *papszAllowedDrivers,
3334 : const char *const *papszOpenOptions,
3335 : const char *const *papszSiblingFiles);
3336 :
3337 : //! @cond Doxygen_Suppress
3338 : static char **GetSearchPaths(const char *pszGDAL_DRIVER_PATH);
3339 : //! @endcond
3340 :
3341 : public:
3342 : GDALDriverManager();
3343 : ~GDALDriverManager();
3344 :
3345 : int GetDriverCount(void) const;
3346 : GDALDriver *GetDriver(int);
3347 : GDALDriver *GetDriverByName(const char *);
3348 :
3349 : int RegisterDriver(GDALDriver *);
3350 : void DeregisterDriver(GDALDriver *);
3351 :
3352 : // AutoLoadDrivers is a no-op if compiled with GDAL_NO_AUTOLOAD defined.
3353 : void AutoLoadDrivers();
3354 : void AutoSkipDrivers();
3355 : void ReorderDrivers();
3356 : static CPLErr LoadPlugin(const char *name);
3357 :
3358 : static void AutoLoadPythonDrivers();
3359 :
3360 : void DeclareDeferredPluginDriver(GDALPluginDriverProxy *poProxyDriver);
3361 :
3362 : //! @cond Doxygen_Suppress
3363 : int GetDriverCount(bool bIncludeHidden) const;
3364 : GDALDriver *GetDriver(int iDriver, bool bIncludeHidden);
3365 : bool IsKnownDriver(const char *pszDriverName) const;
3366 : GDALDriver *GetHiddenDriverByName(const char *pszName);
3367 : //! @endcond
3368 : };
3369 :
3370 : CPL_C_START
3371 : GDALDriverManager CPL_DLL *GetGDALDriverManager(void);
3372 : CPL_C_END
3373 :
3374 : /* ******************************************************************** */
3375 : /* GDALAsyncReader */
3376 : /* ******************************************************************** */
3377 :
3378 : /**
3379 : * Class used as a session object for asynchronous requests. They are
3380 : * created with GDALDataset::BeginAsyncReader(), and destroyed with
3381 : * GDALDataset::EndAsyncReader().
3382 : */
3383 1 : class CPL_DLL GDALAsyncReader
3384 : {
3385 :
3386 : CPL_DISALLOW_COPY_ASSIGN(GDALAsyncReader)
3387 :
3388 : protected:
3389 : //! @cond Doxygen_Suppress
3390 : GDALDataset *poDS;
3391 : int nXOff;
3392 : int nYOff;
3393 : int nXSize;
3394 : int nYSize;
3395 : void *pBuf;
3396 : int nBufXSize;
3397 : int nBufYSize;
3398 : GDALDataType eBufType;
3399 : int nBandCount;
3400 : int *panBandMap;
3401 : int nPixelSpace;
3402 : int nLineSpace;
3403 : int nBandSpace;
3404 : //! @endcond
3405 :
3406 : public:
3407 : GDALAsyncReader();
3408 : virtual ~GDALAsyncReader();
3409 :
3410 : /** Return dataset.
3411 : * @return dataset
3412 : */
3413 : GDALDataset *GetGDALDataset()
3414 : {
3415 : return poDS;
3416 : }
3417 :
3418 : /** Return x offset.
3419 : * @return x offset.
3420 : */
3421 : int GetXOffset() const
3422 : {
3423 : return nXOff;
3424 : }
3425 :
3426 : /** Return y offset.
3427 : * @return y offset.
3428 : */
3429 : int GetYOffset() const
3430 : {
3431 : return nYOff;
3432 : }
3433 :
3434 : /** Return width.
3435 : * @return width
3436 : */
3437 : int GetXSize() const
3438 : {
3439 : return nXSize;
3440 : }
3441 :
3442 : /** Return height.
3443 : * @return height
3444 : */
3445 : int GetYSize() const
3446 : {
3447 : return nYSize;
3448 : }
3449 :
3450 : /** Return buffer.
3451 : * @return buffer
3452 : */
3453 : void *GetBuffer()
3454 : {
3455 : return pBuf;
3456 : }
3457 :
3458 : /** Return buffer width.
3459 : * @return buffer width.
3460 : */
3461 : int GetBufferXSize() const
3462 : {
3463 : return nBufXSize;
3464 : }
3465 :
3466 : /** Return buffer height.
3467 : * @return buffer height.
3468 : */
3469 : int GetBufferYSize() const
3470 : {
3471 : return nBufYSize;
3472 : }
3473 :
3474 : /** Return buffer data type.
3475 : * @return buffer data type.
3476 : */
3477 : GDALDataType GetBufferType() const
3478 : {
3479 : return eBufType;
3480 : }
3481 :
3482 : /** Return band count.
3483 : * @return band count
3484 : */
3485 : int GetBandCount() const
3486 : {
3487 : return nBandCount;
3488 : }
3489 :
3490 : /** Return band map.
3491 : * @return band map.
3492 : */
3493 : int *GetBandMap()
3494 : {
3495 : return panBandMap;
3496 : }
3497 :
3498 : /** Return pixel spacing.
3499 : * @return pixel spacing.
3500 : */
3501 : int GetPixelSpace() const
3502 : {
3503 : return nPixelSpace;
3504 : }
3505 :
3506 : /** Return line spacing.
3507 : * @return line spacing.
3508 : */
3509 : int GetLineSpace() const
3510 : {
3511 : return nLineSpace;
3512 : }
3513 :
3514 : /** Return band spacing.
3515 : * @return band spacing.
3516 : */
3517 : int GetBandSpace() const
3518 : {
3519 : return nBandSpace;
3520 : }
3521 :
3522 : virtual GDALAsyncStatusType
3523 : GetNextUpdatedRegion(double dfTimeout, int *pnBufXOff, int *pnBufYOff,
3524 : int *pnBufXSize, int *pnBufYSize) = 0;
3525 : virtual int LockBuffer(double dfTimeout = -1.0);
3526 : virtual void UnlockBuffer();
3527 : };
3528 :
3529 : /* ******************************************************************** */
3530 : /* Multidimensional array API */
3531 : /* ******************************************************************** */
3532 :
3533 : class GDALMDArray;
3534 : class GDALAttribute;
3535 : class GDALDimension;
3536 : class GDALEDTComponent;
3537 :
3538 : /* ******************************************************************** */
3539 : /* GDALExtendedDataType */
3540 : /* ******************************************************************** */
3541 :
3542 : /**
3543 : * Class used to represent potentially complex data types.
3544 : * Several classes of data types are supported: numeric (based on GDALDataType),
3545 : * compound or string.
3546 : *
3547 : * @since GDAL 3.1
3548 : */
3549 81922 : class CPL_DLL GDALExtendedDataType
3550 : {
3551 : public:
3552 : ~GDALExtendedDataType();
3553 :
3554 : GDALExtendedDataType(GDALExtendedDataType &&);
3555 : GDALExtendedDataType(const GDALExtendedDataType &);
3556 :
3557 : GDALExtendedDataType &operator=(const GDALExtendedDataType &);
3558 : GDALExtendedDataType &operator=(GDALExtendedDataType &&);
3559 :
3560 : static GDALExtendedDataType Create(GDALDataType eType);
3561 : static GDALExtendedDataType
3562 : Create(const std::string &osName, GDALDataType eBaseType,
3563 : std::unique_ptr<GDALRasterAttributeTable>);
3564 : static GDALExtendedDataType
3565 : Create(const std::string &osName, size_t nTotalSize,
3566 : std::vector<std::unique_ptr<GDALEDTComponent>> &&components);
3567 : static GDALExtendedDataType
3568 : CreateString(size_t nMaxStringLength = 0,
3569 : GDALExtendedDataTypeSubType eSubType = GEDTST_NONE);
3570 :
3571 : bool operator==(const GDALExtendedDataType &) const;
3572 :
3573 : /** Non-equality operator */
3574 1102 : bool operator!=(const GDALExtendedDataType &other) const
3575 : {
3576 1102 : return !(operator==(other));
3577 : }
3578 :
3579 : /** Return type name.
3580 : *
3581 : * This is the same as the C function GDALExtendedDataTypeGetName()
3582 : */
3583 21 : const std::string &GetName() const
3584 : {
3585 21 : return m_osName;
3586 : }
3587 :
3588 : /** Return type class.
3589 : *
3590 : * This is the same as the C function GDALExtendedDataTypeGetClass()
3591 : */
3592 306264 : GDALExtendedDataTypeClass GetClass() const
3593 : {
3594 306264 : return m_eClass;
3595 : }
3596 :
3597 : /** Return numeric data type (only valid when GetClass() == GEDTC_NUMERIC)
3598 : *
3599 : * This is the same as the C function
3600 : * GDALExtendedDataTypeGetNumericDataType()
3601 : */
3602 1958494 : GDALDataType GetNumericDataType() const
3603 : {
3604 1958494 : return m_eNumericDT;
3605 : }
3606 :
3607 : /** Return subtype.
3608 : *
3609 : * This is the same as the C function GDALExtendedDataTypeGetSubType()
3610 : *
3611 : * @since 3.4
3612 : */
3613 503 : GDALExtendedDataTypeSubType GetSubType() const
3614 : {
3615 503 : return m_eSubType;
3616 : }
3617 :
3618 : /** Return the components of the data type (only valid when GetClass() ==
3619 : * GEDTC_COMPOUND)
3620 : *
3621 : * This is the same as the C function GDALExtendedDataTypeGetComponents()
3622 : */
3623 1231 : const std::vector<std::unique_ptr<GDALEDTComponent>> &GetComponents() const
3624 : {
3625 1231 : return m_aoComponents;
3626 : }
3627 :
3628 : /** Return data type size in bytes.
3629 : *
3630 : * For a string, this will be size of a char* pointer.
3631 : *
3632 : * This is the same as the C function GDALExtendedDataTypeGetSize()
3633 : */
3634 53362 : size_t GetSize() const
3635 : {
3636 53362 : return m_nSize;
3637 : }
3638 :
3639 : /** Return the maximum length of a string in bytes.
3640 : *
3641 : * 0 indicates unknown/unlimited string.
3642 : */
3643 21 : size_t GetMaxStringLength() const
3644 : {
3645 21 : return m_nMaxStringLength;
3646 : }
3647 :
3648 : /** Return associated raster attribute table, when there is one.
3649 : *
3650 : * For the netCDF driver, the RAT will capture enumerated types, with
3651 : * a "value" column with an integer value and a "name" column with the
3652 : * associated name.
3653 : *
3654 : * This is the same as the C function GDALExtendedDataTypeGetRAT()
3655 : *
3656 : * @since 3.12
3657 : */
3658 430 : const GDALRasterAttributeTable *GetRAT() const
3659 : {
3660 430 : return m_poRAT.get();
3661 : }
3662 :
3663 : bool CanConvertTo(const GDALExtendedDataType &other) const;
3664 :
3665 : bool NeedsFreeDynamicMemory() const;
3666 :
3667 : void FreeDynamicMemory(void *pBuffer) const;
3668 :
3669 : static bool CopyValue(const void *pSrc, const GDALExtendedDataType &srcType,
3670 : void *pDst, const GDALExtendedDataType &dstType);
3671 :
3672 : static bool CopyValues(const void *pSrc,
3673 : const GDALExtendedDataType &srcType,
3674 : GPtrDiff_t nSrcStrideInElts, void *pDst,
3675 : const GDALExtendedDataType &dstType,
3676 : GPtrDiff_t nDstStrideInElts, size_t nValues);
3677 :
3678 : private:
3679 : GDALExtendedDataType(size_t nMaxStringLength,
3680 : GDALExtendedDataTypeSubType eSubType);
3681 : explicit GDALExtendedDataType(GDALDataType eType);
3682 : GDALExtendedDataType(const std::string &osName, GDALDataType eBaseType,
3683 : std::unique_ptr<GDALRasterAttributeTable>);
3684 : GDALExtendedDataType(
3685 : const std::string &osName, size_t nTotalSize,
3686 : std::vector<std::unique_ptr<GDALEDTComponent>> &&components);
3687 :
3688 : std::string m_osName{};
3689 : GDALExtendedDataTypeClass m_eClass = GEDTC_NUMERIC;
3690 : GDALExtendedDataTypeSubType m_eSubType = GEDTST_NONE;
3691 : GDALDataType m_eNumericDT = GDT_Unknown;
3692 : std::vector<std::unique_ptr<GDALEDTComponent>> m_aoComponents{};
3693 : size_t m_nSize = 0;
3694 : size_t m_nMaxStringLength = 0;
3695 : std::unique_ptr<GDALRasterAttributeTable> m_poRAT{};
3696 : };
3697 :
3698 : /* ******************************************************************** */
3699 : /* GDALEDTComponent */
3700 : /* ******************************************************************** */
3701 :
3702 : /**
3703 : * Class for a component of a compound extended data type.
3704 : *
3705 : * @since GDAL 3.1
3706 : */
3707 4116 : class CPL_DLL GDALEDTComponent
3708 : {
3709 : public:
3710 : ~GDALEDTComponent();
3711 : GDALEDTComponent(const std::string &name, size_t offset,
3712 : const GDALExtendedDataType &type);
3713 : GDALEDTComponent(const GDALEDTComponent &);
3714 :
3715 : bool operator==(const GDALEDTComponent &) const;
3716 :
3717 : /** Return the name.
3718 : *
3719 : * This is the same as the C function GDALEDTComponentGetName().
3720 : */
3721 3641 : const std::string &GetName() const
3722 : {
3723 3641 : return m_osName;
3724 : }
3725 :
3726 : /** Return the offset (in bytes) of the component in the compound data type.
3727 : *
3728 : * This is the same as the C function GDALEDTComponentGetOffset().
3729 : */
3730 8809 : size_t GetOffset() const
3731 : {
3732 8809 : return m_nOffset;
3733 : }
3734 :
3735 : /** Return the data type of the component.
3736 : *
3737 : * This is the same as the C function GDALEDTComponentGetType().
3738 : */
3739 8049 : const GDALExtendedDataType &GetType() const
3740 : {
3741 8049 : return m_oType;
3742 : }
3743 :
3744 : private:
3745 : std::string m_osName;
3746 : size_t m_nOffset;
3747 : GDALExtendedDataType m_oType;
3748 : };
3749 :
3750 : /* ******************************************************************** */
3751 : /* GDALIHasAttribute */
3752 : /* ******************************************************************** */
3753 :
3754 : /**
3755 : * Interface used to get a single GDALAttribute or a set of GDALAttribute
3756 : *
3757 : * @since GDAL 3.1
3758 : */
3759 13554 : class CPL_DLL GDALIHasAttribute
3760 : {
3761 : protected:
3762 : std::shared_ptr<GDALAttribute>
3763 : GetAttributeFromAttributes(const std::string &osName) const;
3764 :
3765 : public:
3766 : virtual ~GDALIHasAttribute();
3767 :
3768 : virtual std::shared_ptr<GDALAttribute>
3769 : GetAttribute(const std::string &osName) const;
3770 :
3771 : virtual std::vector<std::shared_ptr<GDALAttribute>>
3772 : GetAttributes(CSLConstList papszOptions = nullptr) const;
3773 :
3774 : virtual std::shared_ptr<GDALAttribute>
3775 : CreateAttribute(const std::string &osName,
3776 : const std::vector<GUInt64> &anDimensions,
3777 : const GDALExtendedDataType &oDataType,
3778 : CSLConstList papszOptions = nullptr);
3779 :
3780 : virtual bool DeleteAttribute(const std::string &osName,
3781 : CSLConstList papszOptions = nullptr);
3782 : };
3783 :
3784 : /* ******************************************************************** */
3785 : /* GDALGroup */
3786 : /* ******************************************************************** */
3787 :
3788 : /* clang-format off */
3789 : /**
3790 : * Class modeling a named container of GDALAttribute, GDALMDArray, OGRLayer or
3791 : * other GDALGroup. Hence GDALGroup can describe a hierarchy of objects.
3792 : *
3793 : * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_group">HDF5 group
3794 : * concept</a>
3795 : *
3796 : * @since GDAL 3.1
3797 : */
3798 : /* clang-format on */
3799 :
3800 6959 : class CPL_DLL GDALGroup : public GDALIHasAttribute
3801 : {
3802 : protected:
3803 : //! @cond Doxygen_Suppress
3804 : std::string m_osName{};
3805 :
3806 : // This is actually a path of the form "/parent_path/{m_osName}"
3807 : std::string m_osFullName{};
3808 :
3809 : // Used for example by GDALSubsetGroup to distinguish a derived group
3810 : //from its original, without altering its name
3811 : const std::string m_osContext{};
3812 :
3813 : // List of types owned by the group.
3814 : std::vector<std::shared_ptr<GDALExtendedDataType>> m_apoTypes{};
3815 :
3816 : //! Weak pointer to this
3817 : std::weak_ptr<GDALGroup> m_pSelf{};
3818 :
3819 : //! Can be set to false by the owing group, when deleting this object
3820 : bool m_bValid = true;
3821 :
3822 : GDALGroup(const std::string &osParentName, const std::string &osName,
3823 : const std::string &osContext = std::string());
3824 :
3825 : const GDALGroup *
3826 : GetInnerMostGroup(const std::string &osPathOrArrayOrDim,
3827 : std::shared_ptr<GDALGroup> &curGroupHolder,
3828 : std::string &osLastPart) const;
3829 :
3830 : void BaseRename(const std::string &osNewName);
3831 :
3832 : bool CheckValidAndErrorOutIfNot() const;
3833 :
3834 6092 : void SetSelf(const std::shared_ptr<GDALGroup> &self)
3835 : {
3836 6092 : m_pSelf = self;
3837 6092 : }
3838 :
3839 0 : virtual void NotifyChildrenOfRenaming()
3840 : {
3841 0 : }
3842 :
3843 0 : virtual void NotifyChildrenOfDeletion()
3844 : {
3845 0 : }
3846 :
3847 : //! @endcond
3848 :
3849 : public:
3850 : virtual ~GDALGroup();
3851 :
3852 : /** Return the name of the group.
3853 : *
3854 : * This is the same as the C function GDALGroupGetName().
3855 : */
3856 1069 : const std::string &GetName() const
3857 : {
3858 1069 : return m_osName;
3859 : }
3860 :
3861 : /** Return the full name of the group.
3862 : *
3863 : * This is the same as the C function GDALGroupGetFullName().
3864 : */
3865 24339 : const std::string &GetFullName() const
3866 : {
3867 24339 : return m_osFullName;
3868 : }
3869 :
3870 : /** Return data types associated with the group (typically enumerations)
3871 : *
3872 : * This is the same as the C function GDALGroupGetDataTypeCount() and GDALGroupGetDataType()
3873 : *
3874 : * @since 3.12
3875 : */
3876 : const std::vector<std::shared_ptr<GDALExtendedDataType>> &
3877 57 : GetDataTypes() const
3878 : {
3879 57 : return m_apoTypes;
3880 : }
3881 :
3882 : virtual std::vector<std::string>
3883 : GetMDArrayNames(CSLConstList papszOptions = nullptr) const;
3884 : virtual std::shared_ptr<GDALMDArray>
3885 : OpenMDArray(const std::string &osName,
3886 : CSLConstList papszOptions = nullptr) const;
3887 :
3888 : std::vector<std::string> GetMDArrayFullNamesRecursive(
3889 : CSLConstList papszGroupOptions = nullptr,
3890 : CSLConstList papszArrayOptions = nullptr) const;
3891 :
3892 : virtual std::vector<std::string>
3893 : GetGroupNames(CSLConstList papszOptions = nullptr) const;
3894 : virtual std::shared_ptr<GDALGroup>
3895 : OpenGroup(const std::string &osName,
3896 : CSLConstList papszOptions = nullptr) const;
3897 :
3898 : virtual std::vector<std::string>
3899 : GetVectorLayerNames(CSLConstList papszOptions = nullptr) const;
3900 : virtual OGRLayer *
3901 : OpenVectorLayer(const std::string &osName,
3902 : CSLConstList papszOptions = nullptr) const;
3903 :
3904 : virtual std::vector<std::shared_ptr<GDALDimension>>
3905 : GetDimensions(CSLConstList papszOptions = nullptr) const;
3906 :
3907 : virtual std::shared_ptr<GDALGroup>
3908 : CreateGroup(const std::string &osName, CSLConstList papszOptions = nullptr);
3909 :
3910 : virtual bool DeleteGroup(const std::string &osName,
3911 : CSLConstList papszOptions = nullptr);
3912 :
3913 : virtual std::shared_ptr<GDALDimension>
3914 : CreateDimension(const std::string &osName, const std::string &osType,
3915 : const std::string &osDirection, GUInt64 nSize,
3916 : CSLConstList papszOptions = nullptr);
3917 :
3918 : virtual std::shared_ptr<GDALMDArray> CreateMDArray(
3919 : const std::string &osName,
3920 : const std::vector<std::shared_ptr<GDALDimension>> &aoDimensions,
3921 : const GDALExtendedDataType &oDataType,
3922 : CSLConstList papszOptions = nullptr);
3923 :
3924 : virtual bool DeleteMDArray(const std::string &osName,
3925 : CSLConstList papszOptions = nullptr);
3926 :
3927 : GUInt64 GetTotalCopyCost() const;
3928 :
3929 : virtual bool CopyFrom(const std::shared_ptr<GDALGroup> &poDstRootGroup,
3930 : GDALDataset *poSrcDS,
3931 : const std::shared_ptr<GDALGroup> &poSrcGroup,
3932 : bool bStrict, GUInt64 &nCurCost,
3933 : const GUInt64 nTotalCost,
3934 : GDALProgressFunc pfnProgress, void *pProgressData,
3935 : CSLConstList papszOptions = nullptr);
3936 :
3937 : virtual CSLConstList GetStructuralInfo() const;
3938 :
3939 : std::shared_ptr<GDALMDArray>
3940 : OpenMDArrayFromFullname(const std::string &osFullName,
3941 : CSLConstList papszOptions = nullptr) const;
3942 :
3943 : std::shared_ptr<GDALAttribute>
3944 : OpenAttributeFromFullname(const std::string &osFullName,
3945 : CSLConstList papszOptions = nullptr) const;
3946 :
3947 : std::shared_ptr<GDALMDArray>
3948 : ResolveMDArray(const std::string &osName, const std::string &osStartingPath,
3949 : CSLConstList papszOptions = nullptr) const;
3950 :
3951 : std::shared_ptr<GDALGroup>
3952 : OpenGroupFromFullname(const std::string &osFullName,
3953 : CSLConstList papszOptions = nullptr) const;
3954 :
3955 : std::shared_ptr<GDALDimension>
3956 : OpenDimensionFromFullname(const std::string &osFullName) const;
3957 :
3958 : virtual void ClearStatistics();
3959 :
3960 : virtual bool Rename(const std::string &osNewName);
3961 :
3962 : std::shared_ptr<GDALGroup>
3963 : SubsetDimensionFromSelection(const std::string &osSelection) const;
3964 :
3965 : //! @cond Doxygen_Suppress
3966 : virtual void ParentRenamed(const std::string &osNewParentFullName);
3967 :
3968 : virtual void Deleted();
3969 :
3970 : virtual void ParentDeleted();
3971 :
3972 23 : const std::string &GetContext() const
3973 : {
3974 23 : return m_osContext;
3975 : }
3976 :
3977 : //! @endcond
3978 :
3979 : //! @cond Doxygen_Suppress
3980 : static constexpr GUInt64 COPY_COST = 1000;
3981 : //! @endcond
3982 : };
3983 :
3984 : /* ******************************************************************** */
3985 : /* GDALAbstractMDArray */
3986 : /* ******************************************************************** */
3987 :
3988 : /**
3989 : * Abstract class, implemented by GDALAttribute and GDALMDArray.
3990 : *
3991 : * @since GDAL 3.1
3992 : */
3993 21054 : class CPL_DLL GDALAbstractMDArray
3994 : {
3995 : protected:
3996 : //! @cond Doxygen_Suppress
3997 : std::string m_osName{};
3998 :
3999 : // This is actually a path of the form "/parent_path/{m_osName}"
4000 : std::string m_osFullName{};
4001 : std::weak_ptr<GDALAbstractMDArray> m_pSelf{};
4002 :
4003 : //! Can be set to false by the owing object, when deleting this object
4004 : bool m_bValid = true;
4005 :
4006 : GDALAbstractMDArray(const std::string &osParentName,
4007 : const std::string &osName);
4008 :
4009 8428 : void SetSelf(const std::shared_ptr<GDALAbstractMDArray> &self)
4010 : {
4011 8428 : m_pSelf = self;
4012 8428 : }
4013 :
4014 : bool CheckValidAndErrorOutIfNot() const;
4015 :
4016 : bool CheckReadWriteParams(const GUInt64 *arrayStartIdx, const size_t *count,
4017 : const GInt64 *&arrayStep,
4018 : const GPtrDiff_t *&bufferStride,
4019 : const GDALExtendedDataType &bufferDataType,
4020 : const void *buffer,
4021 : const void *buffer_alloc_start,
4022 : size_t buffer_alloc_size,
4023 : std::vector<GInt64> &tmp_arrayStep,
4024 : std::vector<GPtrDiff_t> &tmp_bufferStride) const;
4025 :
4026 : virtual bool
4027 : IRead(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
4028 : const size_t *count, // array of size GetDimensionCount()
4029 : const GInt64 *arrayStep, // step in elements
4030 : const GPtrDiff_t *bufferStride, // stride in elements
4031 : const GDALExtendedDataType &bufferDataType,
4032 : void *pDstBuffer) const = 0;
4033 :
4034 : virtual bool
4035 : IWrite(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
4036 : const size_t *count, // array of size GetDimensionCount()
4037 : const GInt64 *arrayStep, // step in elements
4038 : const GPtrDiff_t *bufferStride, // stride in elements
4039 : const GDALExtendedDataType &bufferDataType, const void *pSrcBuffer);
4040 :
4041 : void BaseRename(const std::string &osNewName);
4042 :
4043 47 : virtual void NotifyChildrenOfRenaming()
4044 : {
4045 47 : }
4046 :
4047 42 : virtual void NotifyChildrenOfDeletion()
4048 : {
4049 42 : }
4050 :
4051 : //! @endcond
4052 :
4053 : public:
4054 : virtual ~GDALAbstractMDArray();
4055 :
4056 : /** Return the name of an array or attribute.
4057 : *
4058 : * This is the same as the C function GDALMDArrayGetName() or
4059 : * GDALAttributeGetName().
4060 : */
4061 19914 : const std::string &GetName() const
4062 : {
4063 19914 : return m_osName;
4064 : }
4065 :
4066 : /** Return the name of an array or attribute.
4067 : *
4068 : * This is the same as the C function GDALMDArrayGetFullName() or
4069 : * GDALAttributeGetFullName().
4070 : */
4071 12829 : const std::string &GetFullName() const
4072 : {
4073 12829 : return m_osFullName;
4074 : }
4075 :
4076 : GUInt64 GetTotalElementsCount() const;
4077 :
4078 : virtual size_t GetDimensionCount() const;
4079 :
4080 : virtual const std::vector<std::shared_ptr<GDALDimension>> &
4081 : GetDimensions() const = 0;
4082 :
4083 : virtual const GDALExtendedDataType &GetDataType() const = 0;
4084 :
4085 : virtual std::vector<GUInt64> GetBlockSize() const;
4086 :
4087 : virtual std::vector<size_t>
4088 : GetProcessingChunkSize(size_t nMaxChunkMemory) const;
4089 :
4090 : /* clang-format off */
4091 : /** Type of pfnFunc argument of ProcessPerChunk().
4092 : * @param array Array on which ProcessPerChunk was called.
4093 : * @param chunkArrayStartIdx Values representing the starting index to use
4094 : * in each dimension (in [0, aoDims[i].GetSize()-1] range)
4095 : * for the current chunk.
4096 : * Will be nullptr for a zero-dimensional array.
4097 : * @param chunkCount Values representing the number of values to use in
4098 : * each dimension for the current chunk.
4099 : * Will be nullptr for a zero-dimensional array.
4100 : * @param iCurChunk Number of current chunk being processed.
4101 : * In [1, nChunkCount] range.
4102 : * @param nChunkCount Total number of chunks to process.
4103 : * @param pUserData User data.
4104 : * @return return true in case of success.
4105 : */
4106 : typedef bool (*FuncProcessPerChunkType)(
4107 : GDALAbstractMDArray *array,
4108 : const GUInt64 *chunkArrayStartIdx,
4109 : const size_t *chunkCount,
4110 : GUInt64 iCurChunk,
4111 : GUInt64 nChunkCount,
4112 : void *pUserData);
4113 : /* clang-format on */
4114 :
4115 : virtual bool ProcessPerChunk(const GUInt64 *arrayStartIdx,
4116 : const GUInt64 *count, const size_t *chunkSize,
4117 : FuncProcessPerChunkType pfnFunc,
4118 : void *pUserData);
4119 :
4120 : virtual bool
4121 : Read(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
4122 : const size_t *count, // array of size GetDimensionCount()
4123 : const GInt64 *arrayStep, // step in elements
4124 : const GPtrDiff_t *bufferStride, // stride in elements
4125 : const GDALExtendedDataType &bufferDataType, void *pDstBuffer,
4126 : const void *pDstBufferAllocStart = nullptr,
4127 : size_t nDstBufferAllocSize = 0) const;
4128 :
4129 : bool
4130 : Write(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
4131 : const size_t *count, // array of size GetDimensionCount()
4132 : const GInt64 *arrayStep, // step in elements
4133 : const GPtrDiff_t *bufferStride, // stride in elements
4134 : const GDALExtendedDataType &bufferDataType, const void *pSrcBuffer,
4135 : const void *pSrcBufferAllocStart = nullptr,
4136 : size_t nSrcBufferAllocSize = 0);
4137 :
4138 : virtual bool Rename(const std::string &osNewName);
4139 :
4140 : //! @cond Doxygen_Suppress
4141 : virtual void Deleted();
4142 :
4143 : virtual void ParentDeleted();
4144 :
4145 : virtual void ParentRenamed(const std::string &osNewParentFullName);
4146 : //! @endcond
4147 : };
4148 :
4149 : /* ******************************************************************** */
4150 : /* GDALRawResult */
4151 : /* ******************************************************************** */
4152 :
4153 : /**
4154 : * Store the raw result of an attribute value, which might contain dynamically
4155 : * allocated structures (like pointer to strings).
4156 : *
4157 : * @since GDAL 3.1
4158 : */
4159 : class CPL_DLL GDALRawResult
4160 : {
4161 : private:
4162 : GDALExtendedDataType m_dt;
4163 : size_t m_nEltCount;
4164 : size_t m_nSize;
4165 : GByte *m_raw;
4166 :
4167 : void FreeMe();
4168 :
4169 : GDALRawResult(const GDALRawResult &) = delete;
4170 : GDALRawResult &operator=(const GDALRawResult &) = delete;
4171 :
4172 : protected:
4173 : friend class GDALAttribute;
4174 : //! @cond Doxygen_Suppress
4175 : GDALRawResult(GByte *raw, const GDALExtendedDataType &dt, size_t nEltCount);
4176 : //! @endcond
4177 :
4178 : public:
4179 : ~GDALRawResult();
4180 : GDALRawResult(GDALRawResult &&);
4181 : GDALRawResult &operator=(GDALRawResult &&);
4182 :
4183 : /** Return byte at specified index. */
4184 : const GByte &operator[](size_t idx) const
4185 : {
4186 : return m_raw[idx];
4187 : }
4188 :
4189 : /** Return pointer to the start of data. */
4190 354 : const GByte *data() const
4191 : {
4192 354 : return m_raw;
4193 : }
4194 :
4195 : /** Return the size in bytes of the raw result. */
4196 135 : size_t size() const
4197 : {
4198 135 : return m_nSize;
4199 : }
4200 :
4201 : //! @cond Doxygen_Suppress
4202 : GByte *StealData();
4203 : //! @endcond
4204 : };
4205 :
4206 : /* ******************************************************************** */
4207 : /* GDALAttribute */
4208 : /* ******************************************************************** */
4209 :
4210 : /* clang-format off */
4211 : /**
4212 : * Class modeling an attribute that has a name, a value and a type, and is
4213 : * typically used to describe a metadata item. The value can be (for the
4214 : * HDF5 format) in the general case a multidimensional array of "any" type
4215 : * (in most cases, this will be a single value of string or numeric type)
4216 : *
4217 : * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_attribute">HDF5
4218 : * attribute concept</a>
4219 : *
4220 : * @since GDAL 3.1
4221 : */
4222 : /* clang-format on */
4223 :
4224 14459 : class CPL_DLL GDALAttribute : virtual public GDALAbstractMDArray
4225 : {
4226 : mutable std::string m_osCachedVal{};
4227 :
4228 : protected:
4229 : //! @cond Doxygen_Suppress
4230 : GDALAttribute(const std::string &osParentName, const std::string &osName);
4231 : //! @endcond
4232 :
4233 : public:
4234 : //! @cond Doxygen_Suppress
4235 : ~GDALAttribute();
4236 : //! @endcond
4237 :
4238 : std::vector<GUInt64> GetDimensionsSize() const;
4239 :
4240 : GDALRawResult ReadAsRaw() const;
4241 : const char *ReadAsString() const;
4242 : int ReadAsInt() const;
4243 : int64_t ReadAsInt64() const;
4244 : double ReadAsDouble() const;
4245 : CPLStringList ReadAsStringArray() const;
4246 : std::vector<int> ReadAsIntArray() const;
4247 : std::vector<int64_t> ReadAsInt64Array() const;
4248 : std::vector<double> ReadAsDoubleArray() const;
4249 :
4250 : using GDALAbstractMDArray::Write;
4251 : bool Write(const void *pabyValue, size_t nLen);
4252 : bool Write(const char *);
4253 : bool WriteInt(int);
4254 : bool WriteInt64(int64_t);
4255 : bool Write(double);
4256 : bool Write(CSLConstList);
4257 : bool Write(const int *, size_t);
4258 : bool Write(const int64_t *, size_t);
4259 : bool Write(const double *, size_t);
4260 :
4261 : //! @cond Doxygen_Suppress
4262 : static constexpr GUInt64 COPY_COST = 100;
4263 : //! @endcond
4264 : };
4265 :
4266 : /************************************************************************/
4267 : /* GDALAttributeString */
4268 : /************************************************************************/
4269 :
4270 : //! @cond Doxygen_Suppress
4271 : class CPL_DLL GDALAttributeString final : public GDALAttribute
4272 : {
4273 : std::vector<std::shared_ptr<GDALDimension>> m_dims{};
4274 : GDALExtendedDataType m_dt = GDALExtendedDataType::CreateString();
4275 : std::string m_osValue;
4276 :
4277 : protected:
4278 : bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
4279 : const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
4280 : void *pDstBuffer) const override;
4281 :
4282 : public:
4283 : GDALAttributeString(const std::string &osParentName,
4284 : const std::string &osName, const std::string &osValue,
4285 : GDALExtendedDataTypeSubType eSubType = GEDTST_NONE);
4286 :
4287 : const std::vector<std::shared_ptr<GDALDimension>> &
4288 : GetDimensions() const override;
4289 :
4290 : const GDALExtendedDataType &GetDataType() const override;
4291 : };
4292 :
4293 : //! @endcond
4294 :
4295 : /************************************************************************/
4296 : /* GDALAttributeNumeric */
4297 : /************************************************************************/
4298 :
4299 : //! @cond Doxygen_Suppress
4300 : class CPL_DLL GDALAttributeNumeric final : public GDALAttribute
4301 : {
4302 : std::vector<std::shared_ptr<GDALDimension>> m_dims{};
4303 : GDALExtendedDataType m_dt;
4304 : int m_nValue = 0;
4305 : double m_dfValue = 0;
4306 : std::vector<GUInt32> m_anValuesUInt32{};
4307 :
4308 : protected:
4309 : bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
4310 : const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
4311 : void *pDstBuffer) const override;
4312 :
4313 : public:
4314 : GDALAttributeNumeric(const std::string &osParentName,
4315 : const std::string &osName, double dfValue);
4316 : GDALAttributeNumeric(const std::string &osParentName,
4317 : const std::string &osName, int nValue);
4318 : GDALAttributeNumeric(const std::string &osParentName,
4319 : const std::string &osName,
4320 : const std::vector<GUInt32> &anValues);
4321 :
4322 : const std::vector<std::shared_ptr<GDALDimension>> &
4323 : GetDimensions() const override;
4324 :
4325 : const GDALExtendedDataType &GetDataType() const override;
4326 : };
4327 :
4328 : //! @endcond
4329 :
4330 : /* ******************************************************************** */
4331 : /* GDALMDArray */
4332 : /* ******************************************************************** */
4333 :
4334 : /* clang-format off */
4335 : /**
4336 : * Class modeling a multi-dimensional array. It has a name, values organized
4337 : * as an array and a list of GDALAttribute.
4338 : *
4339 : * This is based on the <a href="https://portal.opengeospatial.org/files/81716#_hdf5_dataset">HDF5
4340 : * dataset concept</a>
4341 : *
4342 : * @since GDAL 3.1
4343 : */
4344 : /* clang-format on */
4345 :
4346 : class CPL_DLL GDALMDArray : virtual public GDALAbstractMDArray,
4347 : public GDALIHasAttribute
4348 : {
4349 : friend class GDALMDArrayResampled;
4350 : std::shared_ptr<GDALMDArray>
4351 : GetView(const std::vector<GUInt64> &indices) const;
4352 :
4353 : inline std::shared_ptr<GDALMDArray>
4354 19 : atInternal(const std::vector<GUInt64> &indices) const
4355 : {
4356 19 : return GetView(indices);
4357 : }
4358 :
4359 : template <typename... GUInt64VarArg>
4360 : // cppcheck-suppress functionStatic
4361 : inline std::shared_ptr<GDALMDArray>
4362 7 : atInternal(std::vector<GUInt64> &indices, GUInt64 idx,
4363 : GUInt64VarArg... tail) const
4364 : {
4365 7 : indices.push_back(idx);
4366 7 : return atInternal(indices, tail...);
4367 : }
4368 :
4369 : // Used for example by GDALSubsetGroup to distinguish a derived group
4370 : //from its original, without altering its name
4371 : const std::string m_osContext{};
4372 :
4373 : mutable bool m_bHasTriedCachedArray = false;
4374 : mutable std::shared_ptr<GDALMDArray> m_poCachedArray{};
4375 :
4376 : protected:
4377 : //! @cond Doxygen_Suppress
4378 : GDALMDArray(const std::string &osParentName, const std::string &osName,
4379 : const std::string &osContext = std::string());
4380 :
4381 : virtual bool IAdviseRead(const GUInt64 *arrayStartIdx, const size_t *count,
4382 : CSLConstList papszOptions) const;
4383 :
4384 1755 : virtual bool IsCacheable() const
4385 : {
4386 1755 : return true;
4387 : }
4388 :
4389 : virtual bool SetStatistics(bool bApproxStats, double dfMin, double dfMax,
4390 : double dfMean, double dfStdDev,
4391 : GUInt64 nValidCount, CSLConstList papszOptions);
4392 :
4393 : static std::string MassageName(const std::string &inputName);
4394 :
4395 : std::shared_ptr<GDALGroup>
4396 : GetCacheRootGroup(bool bCanCreate, std::string &osCacheFilenameOut) const;
4397 :
4398 : // Returns if bufferStride values express a transposed view of the array
4399 : bool IsTransposedRequest(const size_t *count,
4400 : const GPtrDiff_t *bufferStride) const;
4401 :
4402 : // Should only be called if IsTransposedRequest() returns true
4403 : bool ReadForTransposedRequest(const GUInt64 *arrayStartIdx,
4404 : const size_t *count, const GInt64 *arrayStep,
4405 : const GPtrDiff_t *bufferStride,
4406 : const GDALExtendedDataType &bufferDataType,
4407 : void *pDstBuffer) const;
4408 :
4409 : bool IsStepOneContiguousRowMajorOrderedSameDataType(
4410 : const size_t *count, const GInt64 *arrayStep,
4411 : const GPtrDiff_t *bufferStride,
4412 : const GDALExtendedDataType &bufferDataType) const;
4413 :
4414 : // Should only be called if IsStepOneContiguousRowMajorOrderedSameDataType()
4415 : // returns false
4416 : bool ReadUsingContiguousIRead(const GUInt64 *arrayStartIdx,
4417 : const size_t *count, const GInt64 *arrayStep,
4418 : const GPtrDiff_t *bufferStride,
4419 : const GDALExtendedDataType &bufferDataType,
4420 : void *pDstBuffer) const;
4421 :
4422 : static std::shared_ptr<GDALMDArray> CreateGLTOrthorectified(
4423 : const std::shared_ptr<GDALMDArray> &poParent,
4424 : const std::shared_ptr<GDALGroup> &poRootGroup,
4425 : const std::shared_ptr<GDALMDArray> &poGLTX,
4426 : const std::shared_ptr<GDALMDArray> &poGLTY, int nGLTIndexOffset,
4427 : const std::vector<double> &adfGeoTransform, CSLConstList papszOptions);
4428 :
4429 : //! @endcond
4430 :
4431 : public:
4432 : GUInt64 GetTotalCopyCost() const;
4433 :
4434 : virtual bool CopyFrom(GDALDataset *poSrcDS, const GDALMDArray *poSrcArray,
4435 : bool bStrict, GUInt64 &nCurCost,
4436 : const GUInt64 nTotalCost,
4437 : GDALProgressFunc pfnProgress, void *pProgressData);
4438 :
4439 : /** Return whether an array is writable. */
4440 : virtual bool IsWritable() const = 0;
4441 :
4442 : /** Return the filename that contains that array.
4443 : *
4444 : * This is used in particular for caching.
4445 : *
4446 : * Might be empty if the array is not linked to a file.
4447 : *
4448 : * @since GDAL 3.4
4449 : */
4450 : virtual const std::string &GetFilename() const = 0;
4451 :
4452 : virtual CSLConstList GetStructuralInfo() const;
4453 :
4454 : virtual const std::string &GetUnit() const;
4455 :
4456 : virtual bool SetUnit(const std::string &osUnit);
4457 :
4458 : virtual bool SetSpatialRef(const OGRSpatialReference *poSRS);
4459 :
4460 : virtual std::shared_ptr<OGRSpatialReference> GetSpatialRef() const;
4461 :
4462 : virtual const void *GetRawNoDataValue() const;
4463 :
4464 : double GetNoDataValueAsDouble(bool *pbHasNoData = nullptr) const;
4465 :
4466 : int64_t GetNoDataValueAsInt64(bool *pbHasNoData = nullptr) const;
4467 :
4468 : uint64_t GetNoDataValueAsUInt64(bool *pbHasNoData = nullptr) const;
4469 :
4470 : virtual bool SetRawNoDataValue(const void *pRawNoData);
4471 :
4472 : //! @cond Doxygen_Suppress
4473 2 : bool SetNoDataValue(int nNoData)
4474 : {
4475 2 : return SetNoDataValue(static_cast<int64_t>(nNoData));
4476 : }
4477 :
4478 : //! @endcond
4479 :
4480 : bool SetNoDataValue(double dfNoData);
4481 :
4482 : bool SetNoDataValue(int64_t nNoData);
4483 :
4484 : bool SetNoDataValue(uint64_t nNoData);
4485 :
4486 : virtual bool Resize(const std::vector<GUInt64> &anNewDimSizes,
4487 : CSLConstList papszOptions);
4488 :
4489 : virtual double GetOffset(bool *pbHasOffset = nullptr,
4490 : GDALDataType *peStorageType = nullptr) const;
4491 :
4492 : virtual double GetScale(bool *pbHasScale = nullptr,
4493 : GDALDataType *peStorageType = nullptr) const;
4494 :
4495 : virtual bool SetOffset(double dfOffset,
4496 : GDALDataType eStorageType = GDT_Unknown);
4497 :
4498 : virtual bool SetScale(double dfScale,
4499 : GDALDataType eStorageType = GDT_Unknown);
4500 :
4501 : std::shared_ptr<GDALMDArray> GetView(const std::string &viewExpr) const;
4502 :
4503 : std::shared_ptr<GDALMDArray> operator[](const std::string &fieldName) const;
4504 :
4505 : /** Return a view of the array using integer indexing.
4506 : *
4507 : * Equivalent of GetView("[indices_0,indices_1,.....,indices_last]")
4508 : *
4509 : * Example:
4510 : * \code
4511 : * ar->at(0,3,2)
4512 : * \endcode
4513 : */
4514 : // sphinx 4.1.0 / breathe 4.30.0 don't like typename...
4515 : //! @cond Doxygen_Suppress
4516 : template <typename... GUInt64VarArg>
4517 : //! @endcond
4518 : // cppcheck-suppress functionStatic
4519 19 : std::shared_ptr<GDALMDArray> at(GUInt64 idx, GUInt64VarArg... tail) const
4520 : {
4521 38 : std::vector<GUInt64> indices;
4522 19 : indices.push_back(idx);
4523 38 : return atInternal(indices, tail...);
4524 : }
4525 :
4526 : virtual std::shared_ptr<GDALMDArray>
4527 : Transpose(const std::vector<int> &anMapNewAxisToOldAxis) const;
4528 :
4529 : std::shared_ptr<GDALMDArray> GetUnscaled(
4530 : double dfOverriddenScale = std::numeric_limits<double>::quiet_NaN(),
4531 : double dfOverriddenOffset = std::numeric_limits<double>::quiet_NaN(),
4532 : double dfOverriddenDstNodata =
4533 : std::numeric_limits<double>::quiet_NaN()) const;
4534 :
4535 : virtual std::shared_ptr<GDALMDArray>
4536 : GetMask(CSLConstList papszOptions) const;
4537 :
4538 : virtual std::shared_ptr<GDALMDArray>
4539 : GetResampled(const std::vector<std::shared_ptr<GDALDimension>> &apoNewDims,
4540 : GDALRIOResampleAlg resampleAlg,
4541 : const OGRSpatialReference *poTargetSRS,
4542 : CSLConstList papszOptions) const;
4543 :
4544 : std::shared_ptr<GDALMDArray>
4545 : GetGridded(const std::string &osGridOptions,
4546 : const std::shared_ptr<GDALMDArray> &poXArray = nullptr,
4547 : const std::shared_ptr<GDALMDArray> &poYArray = nullptr,
4548 : CSLConstList papszOptions = nullptr) const;
4549 :
4550 : static std::vector<std::shared_ptr<GDALMDArray>>
4551 : GetMeshGrid(const std::vector<std::shared_ptr<GDALMDArray>> &apoArrays,
4552 : CSLConstList papszOptions = nullptr);
4553 :
4554 : virtual GDALDataset *
4555 : AsClassicDataset(size_t iXDim, size_t iYDim,
4556 : const std::shared_ptr<GDALGroup> &poRootGroup = nullptr,
4557 : CSLConstList papszOptions = nullptr) const;
4558 :
4559 : virtual CPLErr GetStatistics(bool bApproxOK, bool bForce, double *pdfMin,
4560 : double *pdfMax, double *pdfMean,
4561 : double *padfStdDev, GUInt64 *pnValidCount,
4562 : GDALProgressFunc pfnProgress,
4563 : void *pProgressData);
4564 :
4565 : virtual bool ComputeStatistics(bool bApproxOK, double *pdfMin,
4566 : double *pdfMax, double *pdfMean,
4567 : double *pdfStdDev, GUInt64 *pnValidCount,
4568 : GDALProgressFunc, void *pProgressData,
4569 : CSLConstList papszOptions);
4570 :
4571 : virtual void ClearStatistics();
4572 :
4573 : virtual std::vector<std::shared_ptr<GDALMDArray>>
4574 : GetCoordinateVariables() const;
4575 :
4576 : bool AdviseRead(const GUInt64 *arrayStartIdx, const size_t *count,
4577 : CSLConstList papszOptions = nullptr) const;
4578 :
4579 : bool IsRegularlySpaced(double &dfStart, double &dfIncrement) const;
4580 :
4581 : bool GuessGeoTransform(size_t nDimX, size_t nDimY, bool bPixelIsPoint,
4582 : GDALGeoTransform >) const;
4583 :
4584 : bool GuessGeoTransform(size_t nDimX, size_t nDimY, bool bPixelIsPoint,
4585 : double adfGeoTransform[6]) const;
4586 :
4587 : bool Cache(CSLConstList papszOptions = nullptr) const;
4588 :
4589 : bool
4590 : Read(const GUInt64 *arrayStartIdx, // array of size GetDimensionCount()
4591 : const size_t *count, // array of size GetDimensionCount()
4592 : const GInt64 *arrayStep, // step in elements
4593 : const GPtrDiff_t *bufferStride, // stride in elements
4594 : const GDALExtendedDataType &bufferDataType, void *pDstBuffer,
4595 : const void *pDstBufferAllocStart = nullptr,
4596 : size_t nDstBufferAllocSize = 0) const override final;
4597 :
4598 : virtual std::shared_ptr<GDALGroup> GetRootGroup() const;
4599 :
4600 : //! @cond Doxygen_Suppress
4601 : static constexpr GUInt64 COPY_COST = 1000;
4602 :
4603 : bool CopyFromAllExceptValues(const GDALMDArray *poSrcArray, bool bStrict,
4604 : GUInt64 &nCurCost, const GUInt64 nTotalCost,
4605 : GDALProgressFunc pfnProgress,
4606 : void *pProgressData);
4607 :
4608 : struct Range
4609 : {
4610 : GUInt64 m_nStartIdx;
4611 : GInt64 m_nIncr;
4612 :
4613 1332 : explicit Range(GUInt64 nStartIdx = 0, GInt64 nIncr = 0)
4614 1332 : : m_nStartIdx(nStartIdx), m_nIncr(nIncr)
4615 : {
4616 1332 : }
4617 : };
4618 :
4619 : struct ViewSpec
4620 : {
4621 : std::string m_osFieldName{};
4622 :
4623 : // or
4624 :
4625 : std::vector<size_t>
4626 : m_mapDimIdxToParentDimIdx{}; // of size m_dims.size()
4627 : std::vector<Range>
4628 : m_parentRanges{}; // of size m_poParent->GetDimensionCount()
4629 : };
4630 :
4631 : virtual std::shared_ptr<GDALMDArray>
4632 : GetView(const std::string &viewExpr, bool bRenameDimensions,
4633 : std::vector<ViewSpec> &viewSpecs) const;
4634 :
4635 1083 : const std::string &GetContext() const
4636 : {
4637 1083 : return m_osContext;
4638 : }
4639 :
4640 : //! @endcond
4641 : };
4642 :
4643 : //! @cond Doxygen_Suppress
4644 : bool GDALMDRasterIOFromBand(GDALRasterBand *poBand, GDALRWFlag eRWFlag,
4645 : size_t iDimX, size_t iDimY,
4646 : const GUInt64 *arrayStartIdx, const size_t *count,
4647 : const GInt64 *arrayStep,
4648 : const GPtrDiff_t *bufferStride,
4649 : const GDALExtendedDataType &bufferDataType,
4650 : void *pBuffer);
4651 :
4652 : //! @endcond
4653 :
4654 : /************************************************************************/
4655 : /* GDALMDArrayRegularlySpaced */
4656 : /************************************************************************/
4657 :
4658 : //! @cond Doxygen_Suppress
4659 : class CPL_DLL GDALMDArrayRegularlySpaced : public GDALMDArray
4660 : {
4661 : double m_dfStart;
4662 : double m_dfIncrement;
4663 : double m_dfOffsetInIncrement;
4664 : GDALExtendedDataType m_dt = GDALExtendedDataType::Create(GDT_Float64);
4665 : std::vector<std::shared_ptr<GDALDimension>> m_dims;
4666 : std::vector<std::shared_ptr<GDALAttribute>> m_attributes{};
4667 : std::string m_osEmptyFilename{};
4668 :
4669 : protected:
4670 : bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
4671 : const GPtrDiff_t *, const GDALExtendedDataType &bufferDataType,
4672 : void *pDstBuffer) const override;
4673 :
4674 : public:
4675 : GDALMDArrayRegularlySpaced(const std::string &osParentName,
4676 : const std::string &osName,
4677 : const std::shared_ptr<GDALDimension> &poDim,
4678 : double dfStart, double dfIncrement,
4679 : double dfOffsetInIncrement);
4680 :
4681 : static std::shared_ptr<GDALMDArrayRegularlySpaced>
4682 : Create(const std::string &osParentName, const std::string &osName,
4683 : const std::shared_ptr<GDALDimension> &poDim, double dfStart,
4684 : double dfIncrement, double dfOffsetInIncrement);
4685 :
4686 0 : bool IsWritable() const override
4687 : {
4688 0 : return false;
4689 : }
4690 :
4691 104 : const std::string &GetFilename() const override
4692 : {
4693 104 : return m_osEmptyFilename;
4694 : }
4695 :
4696 : const std::vector<std::shared_ptr<GDALDimension>> &
4697 : GetDimensions() const override;
4698 :
4699 : const GDALExtendedDataType &GetDataType() const override;
4700 :
4701 : std::vector<std::shared_ptr<GDALAttribute>>
4702 : GetAttributes(CSLConstList) const override;
4703 :
4704 : void AddAttribute(const std::shared_ptr<GDALAttribute> &poAttr);
4705 : };
4706 :
4707 : //! @endcond
4708 :
4709 : /* ******************************************************************** */
4710 : /* GDALDimension */
4711 : /* ******************************************************************** */
4712 :
4713 : /**
4714 : * Class modeling a a dimension / axis used to index multidimensional arrays.
4715 : * It has a name, a size (that is the number of values that can be indexed along
4716 : * the dimension), a type (see GDALDimension::GetType()), a direction
4717 : * (see GDALDimension::GetDirection()), a unit and can optionally point to a
4718 : * GDALMDArray variable, typically one-dimensional, describing the values taken
4719 : * by the dimension. For a georeferenced GDALMDArray and its X dimension, this
4720 : * will be typically the values of the easting/longitude for each grid point.
4721 : *
4722 : * @since GDAL 3.1
4723 : */
4724 8520 : class CPL_DLL GDALDimension
4725 : {
4726 : public:
4727 : //! @cond Doxygen_Suppress
4728 : GDALDimension(const std::string &osParentName, const std::string &osName,
4729 : const std::string &osType, const std::string &osDirection,
4730 : GUInt64 nSize);
4731 : //! @endcond
4732 :
4733 : virtual ~GDALDimension();
4734 :
4735 : /** Return the name.
4736 : *
4737 : * This is the same as the C function GDALDimensionGetName()
4738 : */
4739 10229 : const std::string &GetName() const
4740 : {
4741 10229 : return m_osName;
4742 : }
4743 :
4744 : /** Return the full name.
4745 : *
4746 : * This is the same as the C function GDALDimensionGetFullName()
4747 : */
4748 1563 : const std::string &GetFullName() const
4749 : {
4750 1563 : return m_osFullName;
4751 : }
4752 :
4753 : /** Return the axis type.
4754 : *
4755 : * Predefined values are:
4756 : * HORIZONTAL_X, HORIZONTAL_Y, VERTICAL, TEMPORAL, PARAMETRIC
4757 : * Other values might be returned. Empty value means unknown.
4758 : *
4759 : * This is the same as the C function GDALDimensionGetType()
4760 : */
4761 1832 : const std::string &GetType() const
4762 : {
4763 1832 : return m_osType;
4764 : }
4765 :
4766 : /** Return the axis direction.
4767 : *
4768 : * Predefined values are:
4769 : * EAST, WEST, SOUTH, NORTH, UP, DOWN, FUTURE, PAST
4770 : * Other values might be returned. Empty value means unknown.
4771 : *
4772 : * This is the same as the C function GDALDimensionGetDirection()
4773 : */
4774 884 : const std::string &GetDirection() const
4775 : {
4776 884 : return m_osDirection;
4777 : }
4778 :
4779 : /** Return the size, that is the number of values along the dimension.
4780 : *
4781 : * This is the same as the C function GDALDimensionGetSize()
4782 : */
4783 82384 : GUInt64 GetSize() const
4784 : {
4785 82384 : return m_nSize;
4786 : }
4787 :
4788 : virtual std::shared_ptr<GDALMDArray> GetIndexingVariable() const;
4789 :
4790 : virtual bool
4791 : SetIndexingVariable(std::shared_ptr<GDALMDArray> poIndexingVariable);
4792 :
4793 : virtual bool Rename(const std::string &osNewName);
4794 :
4795 : //! @cond Doxygen_Suppress
4796 : virtual void ParentRenamed(const std::string &osNewParentFullName);
4797 :
4798 : virtual void ParentDeleted();
4799 : //! @endcond
4800 :
4801 : protected:
4802 : //! @cond Doxygen_Suppress
4803 : std::string m_osName;
4804 : std::string m_osFullName;
4805 : std::string m_osType;
4806 : std::string m_osDirection;
4807 : GUInt64 m_nSize;
4808 :
4809 : void BaseRename(const std::string &osNewName);
4810 :
4811 : //! @endcond
4812 : };
4813 :
4814 : /************************************************************************/
4815 : /* GDALDimensionWeakIndexingVar() */
4816 : /************************************************************************/
4817 :
4818 : //! @cond Doxygen_Suppress
4819 : class CPL_DLL GDALDimensionWeakIndexingVar : public GDALDimension
4820 : {
4821 : std::weak_ptr<GDALMDArray> m_poIndexingVariable{};
4822 :
4823 : public:
4824 : GDALDimensionWeakIndexingVar(const std::string &osParentName,
4825 : const std::string &osName,
4826 : const std::string &osType,
4827 : const std::string &osDirection, GUInt64 nSize);
4828 :
4829 : std::shared_ptr<GDALMDArray> GetIndexingVariable() const override;
4830 :
4831 : bool SetIndexingVariable(
4832 : std::shared_ptr<GDALMDArray> poIndexingVariable) override;
4833 :
4834 : void SetSize(GUInt64 nNewSize);
4835 : };
4836 : //! @endcond
4837 :
4838 : /************************************************************************/
4839 : /* GDALAntiRecursionGuard */
4840 : /************************************************************************/
4841 :
4842 : //! @cond Doxygen_Suppress
4843 : struct GDALAntiRecursionStruct;
4844 :
4845 : class GDALAntiRecursionGuard
4846 : {
4847 : GDALAntiRecursionStruct *m_psAntiRecursionStruct;
4848 : std::string m_osIdentifier;
4849 : int m_nDepth;
4850 :
4851 : GDALAntiRecursionGuard(const GDALAntiRecursionGuard &) = delete;
4852 : GDALAntiRecursionGuard &operator=(const GDALAntiRecursionGuard &) = delete;
4853 :
4854 : public:
4855 : explicit GDALAntiRecursionGuard(const std::string &osIdentifier);
4856 : GDALAntiRecursionGuard(const GDALAntiRecursionGuard &other,
4857 : const std::string &osIdentifier);
4858 : ~GDALAntiRecursionGuard();
4859 :
4860 519664 : int GetCallDepth() const
4861 : {
4862 519664 : return m_nDepth;
4863 : }
4864 : };
4865 :
4866 : //! @endcond
4867 :
4868 : /************************************************************************/
4869 : /* Relationships */
4870 : /************************************************************************/
4871 :
4872 : /**
4873 : * Definition of a table relationship.
4874 : *
4875 : * GDALRelationship describes the relationship between two tables, including
4876 : * properties such as the cardinality of the relationship and the participating
4877 : * tables.
4878 : *
4879 : * Not all relationship properties are supported by all data formats.
4880 : *
4881 : * @since GDAL 3.6
4882 : */
4883 : class CPL_DLL GDALRelationship
4884 : {
4885 : protected:
4886 : /*! @cond Doxygen_Suppress */
4887 : std::string m_osName{};
4888 : std::string m_osLeftTableName{};
4889 : std::string m_osRightTableName{};
4890 : GDALRelationshipCardinality m_eCardinality =
4891 : GDALRelationshipCardinality::GRC_ONE_TO_MANY;
4892 : std::string m_osMappingTableName{};
4893 : std::vector<std::string> m_osListLeftTableFields{};
4894 : std::vector<std::string> m_osListRightTableFields{};
4895 : std::vector<std::string> m_osListLeftMappingTableFields{};
4896 : std::vector<std::string> m_osListRightMappingTableFields{};
4897 : GDALRelationshipType m_eType = GDALRelationshipType::GRT_ASSOCIATION;
4898 : std::string m_osForwardPathLabel{};
4899 : std::string m_osBackwardPathLabel{};
4900 : std::string m_osRelatedTableType{};
4901 :
4902 : /*! @endcond */
4903 :
4904 : public:
4905 : /**
4906 : * Constructor for a relationship between two tables.
4907 : * @param osName relationship name
4908 : * @param osLeftTableName left table name
4909 : * @param osRightTableName right table name
4910 : * @param eCardinality cardinality of relationship
4911 : */
4912 349 : GDALRelationship(const std::string &osName,
4913 : const std::string &osLeftTableName,
4914 : const std::string &osRightTableName,
4915 : GDALRelationshipCardinality eCardinality =
4916 : GDALRelationshipCardinality::GRC_ONE_TO_MANY)
4917 349 : : m_osName(osName), m_osLeftTableName(osLeftTableName),
4918 349 : m_osRightTableName(osRightTableName), m_eCardinality(eCardinality)
4919 : {
4920 349 : }
4921 :
4922 : /** Get the name of the relationship */
4923 393 : const std::string &GetName() const
4924 : {
4925 393 : return m_osName;
4926 : }
4927 :
4928 : /** Get the cardinality of the relationship */
4929 247 : GDALRelationshipCardinality GetCardinality() const
4930 : {
4931 247 : return m_eCardinality;
4932 : }
4933 :
4934 : /** Get the name of the left (or base/origin) table in the relationship.
4935 : *
4936 : * @see GetRightTableName()
4937 : */
4938 202 : const std::string &GetLeftTableName() const
4939 : {
4940 202 : return m_osLeftTableName;
4941 : }
4942 :
4943 : /** Get the name of the right (or related/destination) table in the
4944 : * relationship */
4945 197 : const std::string &GetRightTableName() const
4946 : {
4947 197 : return m_osRightTableName;
4948 : }
4949 :
4950 : /** Get the name of the mapping table for many-to-many relationships.
4951 : *
4952 : * @see SetMappingTableName()
4953 : */
4954 160 : const std::string &GetMappingTableName() const
4955 : {
4956 160 : return m_osMappingTableName;
4957 : }
4958 :
4959 : /** Sets the name of the mapping table for many-to-many relationships.
4960 : *
4961 : * @see GetMappingTableName()
4962 : */
4963 113 : void SetMappingTableName(const std::string &osName)
4964 : {
4965 113 : m_osMappingTableName = osName;
4966 113 : }
4967 :
4968 : /** Get the names of the participating fields from the left table in the
4969 : * relationship.
4970 : *
4971 : * @see GetRightTableFields()
4972 : * @see SetLeftTableFields()
4973 : */
4974 157 : const std::vector<std::string> &GetLeftTableFields() const
4975 : {
4976 157 : return m_osListLeftTableFields;
4977 : }
4978 :
4979 : /** Get the names of the participating fields from the right table in the
4980 : * relationship.
4981 : *
4982 : * @see GetLeftTableFields()
4983 : * @see SetRightTableFields()
4984 : */
4985 151 : const std::vector<std::string> &GetRightTableFields() const
4986 : {
4987 151 : return m_osListRightTableFields;
4988 : }
4989 :
4990 : /** Sets the names of the participating fields from the left table in the
4991 : * relationship.
4992 : *
4993 : * @see GetLeftTableFields()
4994 : * @see SetRightTableFields()
4995 : */
4996 362 : void SetLeftTableFields(const std::vector<std::string> &osListFields)
4997 : {
4998 362 : m_osListLeftTableFields = osListFields;
4999 362 : }
5000 :
5001 : /** Sets the names of the participating fields from the right table in the
5002 : * relationship.
5003 : *
5004 : * @see GetRightTableFields()
5005 : * @see SetLeftTableFields()
5006 : */
5007 363 : void SetRightTableFields(const std::vector<std::string> &osListFields)
5008 : {
5009 363 : m_osListRightTableFields = osListFields;
5010 363 : }
5011 :
5012 : /** Get the names of the mapping table fields which correspond to the
5013 : * participating fields from the left table in the relationship.
5014 : *
5015 : * @see GetRightMappingTableFields()
5016 : * @see SetLeftMappingTableFields()
5017 : */
5018 61 : const std::vector<std::string> &GetLeftMappingTableFields() const
5019 : {
5020 61 : return m_osListLeftMappingTableFields;
5021 : }
5022 :
5023 : /** Get the names of the mapping table fields which correspond to the
5024 : * participating fields from the right table in the relationship.
5025 : *
5026 : * @see GetLeftMappingTableFields()
5027 : * @see SetRightMappingTableFields()
5028 : */
5029 61 : const std::vector<std::string> &GetRightMappingTableFields() const
5030 : {
5031 61 : return m_osListRightMappingTableFields;
5032 : }
5033 :
5034 : /** Sets the names of the mapping table fields which correspond to the
5035 : * participating fields from the left table in the relationship.
5036 : *
5037 : * @see GetLeftMappingTableFields()
5038 : * @see SetRightMappingTableFields()
5039 : */
5040 313 : void SetLeftMappingTableFields(const std::vector<std::string> &osListFields)
5041 : {
5042 313 : m_osListLeftMappingTableFields = osListFields;
5043 313 : }
5044 :
5045 : /** Sets the names of the mapping table fields which correspond to the
5046 : * participating fields from the right table in the relationship.
5047 : *
5048 : * @see GetRightMappingTableFields()
5049 : * @see SetLeftMappingTableFields()
5050 : */
5051 : void
5052 313 : SetRightMappingTableFields(const std::vector<std::string> &osListFields)
5053 : {
5054 313 : m_osListRightMappingTableFields = osListFields;
5055 313 : }
5056 :
5057 : /** Get the type of the relationship.
5058 : *
5059 : * @see SetType()
5060 : */
5061 111 : GDALRelationshipType GetType() const
5062 : {
5063 111 : return m_eType;
5064 : }
5065 :
5066 : /** Sets the type of the relationship.
5067 : *
5068 : * @see GetType()
5069 : */
5070 263 : void SetType(GDALRelationshipType eType)
5071 : {
5072 263 : m_eType = eType;
5073 263 : }
5074 :
5075 : /** Get the label of the forward path for the relationship.
5076 : *
5077 : * The forward and backward path labels are free-form, user-friendly strings
5078 : * which can be used to generate descriptions of the relationship between
5079 : * features from the right and left tables.
5080 : *
5081 : * E.g. when the left table contains buildings and the right table contains
5082 : * furniture, the forward path label could be "contains" and the backward
5083 : * path label could be "is located within". A client could then generate a
5084 : * user friendly description string such as "fire hose 1234 is located
5085 : * within building 15a".
5086 : *
5087 : * @see SetForwardPathLabel()
5088 : * @see GetBackwardPathLabel()
5089 : */
5090 53 : const std::string &GetForwardPathLabel() const
5091 : {
5092 53 : return m_osForwardPathLabel;
5093 : }
5094 :
5095 : /** Sets the label of the forward path for the relationship.
5096 : *
5097 : * The forward and backward path labels are free-form, user-friendly strings
5098 : * which can be used to generate descriptions of the relationship between
5099 : * features from the right and left tables.
5100 : *
5101 : * E.g. when the left table contains buildings and the right table contains
5102 : * furniture, the forward path label could be "contains" and the backward
5103 : * path label could be "is located within". A client could then generate a
5104 : * user friendly description string such as "fire hose 1234 is located
5105 : * within building 15a".
5106 : *
5107 : * @see GetForwardPathLabel()
5108 : * @see SetBackwardPathLabel()
5109 : */
5110 260 : void SetForwardPathLabel(const std::string &osLabel)
5111 : {
5112 260 : m_osForwardPathLabel = osLabel;
5113 260 : }
5114 :
5115 : /** Get the label of the backward path for the relationship.
5116 : *
5117 : * The forward and backward path labels are free-form, user-friendly strings
5118 : * which can be used to generate descriptions of the relationship between
5119 : * features from the right and left tables.
5120 : *
5121 : * E.g. when the left table contains buildings and the right table contains
5122 : * furniture, the forward path label could be "contains" and the backward
5123 : * path label could be "is located within". A client could then generate a
5124 : * user friendly description string such as "fire hose 1234 is located
5125 : * within building 15a".
5126 : *
5127 : * @see SetBackwardPathLabel()
5128 : * @see GetForwardPathLabel()
5129 : */
5130 53 : const std::string &GetBackwardPathLabel() const
5131 : {
5132 53 : return m_osBackwardPathLabel;
5133 : }
5134 :
5135 : /** Sets the label of the backward path for the relationship.
5136 : *
5137 : * The forward and backward path labels are free-form, user-friendly strings
5138 : * which can be used to generate descriptions of the relationship between
5139 : * features from the right and left tables.
5140 : *
5141 : * E.g. when the left table contains buildings and the right table contains
5142 : * furniture, the forward path label could be "contains" and the backward
5143 : * path label could be "is located within". A client could then generate a
5144 : * user friendly description string such as "fire hose 1234 is located
5145 : * within building 15a".
5146 : *
5147 : * @see GetBackwardPathLabel()
5148 : * @see SetForwardPathLabel()
5149 : */
5150 260 : void SetBackwardPathLabel(const std::string &osLabel)
5151 : {
5152 260 : m_osBackwardPathLabel = osLabel;
5153 260 : }
5154 :
5155 : /** Get the type string of the related table.
5156 : *
5157 : * This a free-form string representing the type of related features, where
5158 : * the exact interpretation is format dependent. For instance, table types
5159 : * from GeoPackage relationships will directly reflect the categories from
5160 : * the GeoPackage related tables extension (i.e. "media", "simple
5161 : * attributes", "features", "attributes" and "tiles").
5162 : *
5163 : * @see SetRelatedTableType()
5164 : */
5165 144 : const std::string &GetRelatedTableType() const
5166 : {
5167 144 : return m_osRelatedTableType;
5168 : }
5169 :
5170 : /** Sets the type string of the related table.
5171 : *
5172 : * This a free-form string representing the type of related features, where
5173 : * the exact interpretation is format dependent. For instance, table types
5174 : * from GeoPackage relationships will directly reflect the categories from
5175 : * the GeoPackage related tables extension (i.e. "media", "simple
5176 : * attributes", "features", "attributes" and "tiles").
5177 : *
5178 : * @see GetRelatedTableType()
5179 : */
5180 340 : void SetRelatedTableType(const std::string &osType)
5181 : {
5182 340 : m_osRelatedTableType = osType;
5183 340 : }
5184 :
5185 : /** Convert a GDALRelationship* to a GDALRelationshipH.
5186 : */
5187 81 : static inline GDALRelationshipH ToHandle(GDALRelationship *poRelationship)
5188 : {
5189 81 : return static_cast<GDALRelationshipH>(poRelationship);
5190 : }
5191 :
5192 : /** Convert a GDALRelationshipH to a GDALRelationship*.
5193 : */
5194 706 : static inline GDALRelationship *FromHandle(GDALRelationshipH hRelationship)
5195 : {
5196 706 : return static_cast<GDALRelationship *>(hRelationship);
5197 : }
5198 : };
5199 :
5200 : /* ==================================================================== */
5201 : /* An assortment of overview related stuff. */
5202 : /* ==================================================================== */
5203 :
5204 : //! @cond Doxygen_Suppress
5205 : /* Only exported for drivers as plugin. Signature may change */
5206 : CPLErr CPL_DLL GDALRegenerateOverviewsMultiBand(
5207 : int nBands, GDALRasterBand *const *papoSrcBands, int nOverviews,
5208 : GDALRasterBand *const *const *papapoOverviewBands,
5209 : const char *pszResampling, GDALProgressFunc pfnProgress,
5210 : void *pProgressData, CSLConstList papszOptions);
5211 :
5212 : CPLErr CPL_DLL GDALRegenerateOverviewsMultiBand(
5213 : const std::vector<GDALRasterBand *> &apoSrcBands,
5214 : // First level of array is indexed by band (thus aapoOverviewBands.size() must be equal to apoSrcBands.size())
5215 : // Second level is indexed by overview
5216 : const std::vector<std::vector<GDALRasterBand *>> &aapoOverviewBands,
5217 : const char *pszResampling, GDALProgressFunc pfnProgress,
5218 : void *pProgressData, CSLConstList papszOptions);
5219 :
5220 : /************************************************************************/
5221 : /* GDALOverviewResampleArgs */
5222 : /************************************************************************/
5223 :
5224 : /** Arguments for overview resampling function. */
5225 : // Should not contain any dataset/rasterband object, as this might be
5226 : // read in a worker thread.
5227 : struct GDALOverviewResampleArgs
5228 : {
5229 : //! Datatype of the source band argument
5230 : GDALDataType eSrcDataType = GDT_Unknown;
5231 : //! Datatype of the destination/overview band
5232 : GDALDataType eOvrDataType = GDT_Unknown;
5233 : //! Width in pixel of the destination/overview band
5234 : int nOvrXSize = 0;
5235 : //! Height in pixel of the destination/overview band
5236 : int nOvrYSize = 0;
5237 : //! NBITS value of the destination/overview band (or 0 if not set)
5238 : int nOvrNBITS = 0;
5239 : //! Factor to convert from destination X to source X
5240 : // (source width divided by destination width)
5241 : double dfXRatioDstToSrc = 0;
5242 : //! Factor to convert from destination Y to source Y
5243 : // (source height divided by destination height)
5244 : double dfYRatioDstToSrc = 0;
5245 : //! Sub-pixel delta to add to get source X
5246 : double dfSrcXDelta = 0;
5247 : //! Sub-pixel delta to add to get source Y
5248 : double dfSrcYDelta = 0;
5249 : //! Working data type (data type of the pChunk argument)
5250 : GDALDataType eWrkDataType = GDT_Unknown;
5251 : //! Array of nChunkXSize * nChunkYSize values of mask, or nullptr
5252 : const GByte *pabyChunkNodataMask = nullptr;
5253 : //! X offset of the source chunk in the source band
5254 : int nChunkXOff = 0;
5255 : //! Width in pixel of the source chunk in the source band
5256 : int nChunkXSize = 0;
5257 : //! Y offset of the source chunk in the source band
5258 : int nChunkYOff = 0;
5259 : //! Height in pixel of the source chunk in the source band
5260 : int nChunkYSize = 0;
5261 : //! X Offset of the destination chunk in the destination band
5262 : int nDstXOff = 0;
5263 : //! X Offset of the end (not included) of the destination chunk in the destination band
5264 : int nDstXOff2 = 0;
5265 : //! Y Offset of the destination chunk in the destination band
5266 : int nDstYOff = 0;
5267 : //! Y Offset of the end (not included) of the destination chunk in the destination band
5268 : int nDstYOff2 = 0;
5269 : //! Resampling method
5270 : const char *pszResampling = nullptr;
5271 : //! Whether the source band has a nodata value
5272 : bool bHasNoData = false;
5273 : //! Source band nodata value
5274 : double dfNoDataValue = 0;
5275 : //! Source color table
5276 : const GDALColorTable *poColorTable = nullptr;
5277 : //! Whether a single contributing source pixel at nodata should result
5278 : // in the target pixel to be at nodata too (only taken into account by
5279 : // average resampling)
5280 : bool bPropagateNoData = false;
5281 : };
5282 :
5283 : typedef CPLErr (*GDALResampleFunction)(const GDALOverviewResampleArgs &args,
5284 : const void *pChunk, void **ppDstBuffer,
5285 : GDALDataType *peDstBufferDataType);
5286 :
5287 : GDALResampleFunction GDALGetResampleFunction(const char *pszResampling,
5288 : int *pnRadius);
5289 :
5290 : std::string CPL_DLL GDALGetNormalizedOvrResampling(const char *pszResampling);
5291 :
5292 : GDALDataType GDALGetOvrWorkDataType(const char *pszResampling,
5293 : GDALDataType eSrcDataType);
5294 :
5295 : CPL_C_START
5296 :
5297 : CPLErr CPL_DLL
5298 : HFAAuxBuildOverviews(const char *pszOvrFilename, GDALDataset *poParentDS,
5299 : GDALDataset **ppoDS, int nBands, const int *panBandList,
5300 : int nNewOverviews, const int *panNewOverviewList,
5301 : const char *pszResampling, GDALProgressFunc pfnProgress,
5302 : void *pProgressData, CSLConstList papszOptions);
5303 :
5304 : CPLErr CPL_DLL GTIFFBuildOverviews(const char *pszFilename, int nBands,
5305 : GDALRasterBand *const *papoBandList,
5306 : int nOverviews, const int *panOverviewList,
5307 : const char *pszResampling,
5308 : GDALProgressFunc pfnProgress,
5309 : void *pProgressData,
5310 : CSLConstList papszOptions);
5311 :
5312 : CPLErr CPL_DLL GTIFFBuildOverviewsEx(const char *pszFilename, int nBands,
5313 : GDALRasterBand *const *papoBandList,
5314 : int nOverviews, const int *panOverviewList,
5315 : const std::pair<int, int> *pasOverviewSize,
5316 : const char *pszResampling,
5317 : const char *const *papszOptions,
5318 : GDALProgressFunc pfnProgress,
5319 : void *pProgressData);
5320 :
5321 : int CPL_DLL GDALBandGetBestOverviewLevel(GDALRasterBand *poBand, int &nXOff,
5322 : int &nYOff, int &nXSize, int &nYSize,
5323 : int nBufXSize, int nBufYSize)
5324 : CPL_WARN_DEPRECATED("Use GDALBandGetBestOverviewLevel2 instead");
5325 : int CPL_DLL GDALBandGetBestOverviewLevel2(GDALRasterBand *poBand, int &nXOff,
5326 : int &nYOff, int &nXSize, int &nYSize,
5327 : int nBufXSize, int nBufYSize,
5328 : GDALRasterIOExtraArg *psExtraArg);
5329 :
5330 : int CPL_DLL GDALOvLevelAdjust(int nOvLevel, int nXSize)
5331 : CPL_WARN_DEPRECATED("Use GDALOvLevelAdjust2 instead");
5332 : int CPL_DLL GDALOvLevelAdjust2(int nOvLevel, int nXSize, int nYSize);
5333 : int CPL_DLL GDALComputeOvFactor(int nOvrXSize, int nRasterXSize, int nOvrYSize,
5334 : int nRasterYSize);
5335 :
5336 : GDALDataset CPL_DLL *GDALFindAssociatedAuxFile(const char *pszBasefile,
5337 : GDALAccess eAccess,
5338 : GDALDataset *poDependentDS);
5339 :
5340 : /* ==================================================================== */
5341 : /* Infrastructure to check that dataset characteristics are valid */
5342 : /* ==================================================================== */
5343 :
5344 : int CPL_DLL GDALCheckDatasetDimensions(int nXSize, int nYSize);
5345 : int CPL_DLL GDALCheckBandCount(int nBands, int bIsZeroAllowed);
5346 :
5347 : /* Internal use only */
5348 :
5349 : /* CPL_DLL exported, but only for in-tree drivers that can be built as plugins
5350 : */
5351 : int CPL_DLL GDALReadWorldFile2(const char *pszBaseFilename,
5352 : const char *pszExtension,
5353 : double *padfGeoTransform,
5354 : CSLConstList papszSiblingFiles,
5355 : char **ppszWorldFileNameOut);
5356 : int CPL_DLL GDALReadTabFile2(const char *pszBaseFilename,
5357 : double *padfGeoTransform, char **ppszWKT,
5358 : int *pnGCPCount, GDAL_GCP **ppasGCPs,
5359 : CSLConstList papszSiblingFiles,
5360 : char **ppszTabFileNameOut);
5361 :
5362 : void CPL_DLL GDALCopyRasterIOExtraArg(GDALRasterIOExtraArg *psDestArg,
5363 : GDALRasterIOExtraArg *psSrcArg);
5364 :
5365 : void CPL_DLL GDALExpandPackedBitsToByteAt0Or1(
5366 : const GByte *CPL_RESTRICT pabyInput, GByte *CPL_RESTRICT pabyOutput,
5367 : size_t nInputBits);
5368 :
5369 : void CPL_DLL GDALExpandPackedBitsToByteAt0Or255(
5370 : const GByte *CPL_RESTRICT pabyInput, GByte *CPL_RESTRICT pabyOutput,
5371 : size_t nInputBits);
5372 :
5373 : CPL_C_END
5374 :
5375 : int CPL_DLL GDALReadWorldFile2(const char *pszBaseFilename,
5376 : const char *pszExtension, GDALGeoTransform >,
5377 : CSLConstList papszSiblingFiles,
5378 : char **ppszWorldFileNameOut);
5379 :
5380 : std::unique_ptr<GDALDataset> CPL_DLL
5381 : GDALGetThreadSafeDataset(std::unique_ptr<GDALDataset> poDS, int nScopeFlags);
5382 :
5383 : GDALDataset CPL_DLL *GDALGetThreadSafeDataset(GDALDataset *poDS,
5384 : int nScopeFlags);
5385 :
5386 : void GDALNullifyOpenDatasetsList();
5387 : CPLMutex **GDALGetphDMMutex();
5388 : CPLMutex **GDALGetphDLMutex();
5389 : void GDALNullifyProxyPoolSingleton();
5390 : void GDALSetResponsiblePIDForCurrentThread(GIntBig responsiblePID);
5391 : GIntBig GDALGetResponsiblePIDForCurrentThread();
5392 :
5393 : CPLString GDALFindAssociatedFile(const char *pszBasename, const char *pszExt,
5394 : CSLConstList papszSiblingFiles, int nFlags);
5395 :
5396 : CPLErr CPL_DLL EXIFExtractMetadata(char **&papszMetadata, void *fpL,
5397 : int nOffset, int bSwabflag, int nTIFFHEADER,
5398 : int &nExifOffset, int &nInterOffset,
5399 : int &nGPSOffset);
5400 :
5401 : int GDALValidateOpenOptions(GDALDriverH hDriver,
5402 : const char *const *papszOptionOptions);
5403 : int GDALValidateOptions(const char *pszOptionList,
5404 : const char *const *papszOptionsToValidate,
5405 : const char *pszErrorMessageOptionType,
5406 : const char *pszErrorMessageContainerName);
5407 :
5408 : GDALRIOResampleAlg CPL_DLL
5409 : GDALRasterIOGetResampleAlg(const char *pszResampling);
5410 : const char *GDALRasterIOGetResampleAlg(GDALRIOResampleAlg eResampleAlg);
5411 :
5412 : void GDALRasterIOExtraArgSetResampleAlg(GDALRasterIOExtraArg *psExtraArg,
5413 : int nXSize, int nYSize, int nBufXSize,
5414 : int nBufYSize);
5415 :
5416 : GDALDataset *GDALCreateOverviewDataset(GDALDataset *poDS, int nOvrLevel,
5417 : bool bThisLevelOnly);
5418 :
5419 : // Should cover particular cases of #3573, #4183, #4506, #6578
5420 : // Behavior is undefined if fVal1 or fVal2 are NaN (should be tested before
5421 : // calling this function)
5422 :
5423 : // TODO: The expression `abs(fVal1 + fVal2)` looks strange; is this a bug?
5424 : // Should this be `abs(fVal1) + abs(fVal2)` instead?
5425 :
5426 29053113 : inline bool ARE_REAL_EQUAL(float fVal1, float fVal2, int ulp = 2)
5427 : {
5428 : using std::abs;
5429 57039718 : return fVal1 == fVal2 || /* Should cover infinity */
5430 27986605 : abs(fVal1 - fVal2) <
5431 57039718 : std::numeric_limits<float>::epsilon() * abs(fVal1 + fVal2) * ulp;
5432 : }
5433 :
5434 : // We are using `std::numeric_limits<float>::epsilon()` for backward
5435 : // compatibility
5436 3949759 : inline bool ARE_REAL_EQUAL(double dfVal1, double dfVal2, int ulp = 2)
5437 : {
5438 : using std::abs;
5439 4551885 : return dfVal1 == dfVal2 || /* Should cover infinity */
5440 602130 : abs(dfVal1 - dfVal2) < std::numeric_limits<float>::epsilon() *
5441 4551885 : abs(dfVal1 + dfVal2) * ulp;
5442 : }
5443 :
5444 : double GDALAdjustNoDataCloseToFloatMax(double dfVal);
5445 :
5446 : #define DIV_ROUND_UP(a, b) (((a) % (b)) == 0 ? ((a) / (b)) : (((a) / (b)) + 1))
5447 :
5448 : // Number of data samples that will be used to compute approximate statistics
5449 : // (minimum value, maximum value, etc.)
5450 : #define GDALSTAT_APPROX_NUMSAMPLES 2500
5451 :
5452 : void GDALSerializeGCPListToXML(CPLXMLNode *psParentNode,
5453 : const std::vector<gdal::GCP> &asGCPs,
5454 : const OGRSpatialReference *poGCP_SRS);
5455 : void GDALDeserializeGCPListFromXML(const CPLXMLNode *psGCPList,
5456 : std::vector<gdal::GCP> &asGCPs,
5457 : OGRSpatialReference **ppoGCP_SRS);
5458 :
5459 : void GDALSerializeOpenOptionsToXML(CPLXMLNode *psParentNode,
5460 : CSLConstList papszOpenOptions);
5461 : char CPL_DLL **
5462 : GDALDeserializeOpenOptionsFromXML(const CPLXMLNode *psParentNode);
5463 :
5464 : int GDALCanFileAcceptSidecarFile(const char *pszFilename);
5465 :
5466 : bool GDALCanReliablyUseSiblingFileList(const char *pszFilename);
5467 :
5468 : typedef enum
5469 : {
5470 : GSF_UNSIGNED_INT,
5471 : GSF_SIGNED_INT,
5472 : GSF_FLOATING_POINT,
5473 : } GDALBufferSampleFormat;
5474 :
5475 : bool CPL_DLL GDALBufferHasOnlyNoData(const void *pBuffer, double dfNoDataValue,
5476 : size_t nWidth, size_t nHeight,
5477 : size_t nLineStride, size_t nComponents,
5478 : int nBitsPerSample,
5479 : GDALBufferSampleFormat nSampleFormat);
5480 :
5481 : bool CPL_DLL GDALCopyNoDataValue(GDALRasterBand *poDstBand,
5482 : GDALRasterBand *poSrcBand,
5483 : bool *pbCannotBeExactlyRepresented = nullptr);
5484 :
5485 : double CPL_DLL GDALGetNoDataValueCastToDouble(int64_t nVal);
5486 : double CPL_DLL GDALGetNoDataValueCastToDouble(uint64_t nVal);
5487 :
5488 : // Remove me in GDAL 4.0. See GetMetadataItem() implementation
5489 : // Internal use in GDAL only !
5490 : // Declaration copied in swig/include/gdal.i
5491 : void CPL_DLL GDALEnablePixelTypeSignedByteWarning(GDALRasterBandH hBand,
5492 : bool b);
5493 :
5494 : std::string CPL_DLL GDALGetCompressionFormatForJPEG(VSILFILE *fp);
5495 : std::string CPL_DLL GDALGetCompressionFormatForJPEG(const void *pBuffer,
5496 : size_t nBufferSize);
5497 :
5498 : GDALRasterAttributeTable CPL_DLL *GDALCreateRasterAttributeTableFromMDArrays(
5499 : GDALRATTableType eTableType,
5500 : const std::vector<std::shared_ptr<GDALMDArray>> &apoArrays,
5501 : const std::vector<GDALRATFieldUsage> &aeUsages);
5502 :
5503 : GDALColorInterp CPL_DLL
5504 : GDALGetColorInterpFromSTACCommonName(const char *pszName);
5505 : const char CPL_DLL *
5506 : GDALGetSTACCommonNameFromColorInterp(GDALColorInterp eInterp);
5507 :
5508 : std::string CPL_DLL GDALGetCacheDirectory();
5509 :
5510 : bool GDALDoesFileOrDatasetExist(const char *pszName,
5511 : const char **ppszType = nullptr,
5512 : GDALDriver **ppDriver = nullptr);
5513 :
5514 : std::string CPL_DLL
5515 : GDALGetMessageAboutMissingPluginDriver(GDALDriver *poMissingPluginDriver);
5516 :
5517 : std::string GDALPrintDriverList(int nOptions, bool bJSON);
5518 :
5519 : struct GDALColorAssociation
5520 : {
5521 : double dfVal;
5522 : int nR;
5523 : int nG;
5524 : int nB;
5525 : int nA;
5526 : };
5527 :
5528 : std::vector<GDALColorAssociation> GDALLoadTextColorMap(const char *pszFilename,
5529 : GDALRasterBand *poBand);
5530 :
5531 : // Macro used so that Identify and driver metadata methods in drivers built
5532 : // as plugin can be duplicated in libgdal core and in the driver under different
5533 : // names
5534 : #ifdef PLUGIN_FILENAME
5535 : #define PLUGIN_SYMBOL_NAME(x) GDAL_core_##x
5536 : #else
5537 : #define PLUGIN_SYMBOL_NAME(x) GDAL_driver_##x
5538 : #endif
5539 :
5540 : //! @endcond
5541 :
5542 : #endif /* ndef GDAL_PRIV_H_INCLUDED */
|