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