Coverage Report

Created: 2025-06-13 06:18

/src/gdal/alg/gdal_alg_priv.h
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 * $Id$
3
 *
4
 * Project:  GDAL Image Processing Algorithms
5
 * Purpose:  Prototypes and definitions for various GDAL based algorithms:
6
 *           private declarations.
7
 * Author:   Andrey Kiselev, dron@ak4719.spb.edu
8
 *
9
 ******************************************************************************
10
 * Copyright (c) 2008, Andrey Kiselev <dron@ak4719.spb.edu>
11
 * Copyright (c) 2010-2013, Even Rouault <even dot rouault at spatialys.com>
12
 *
13
 * SPDX-License-Identifier: MIT
14
 ****************************************************************************/
15
16
#ifndef GDAL_ALG_PRIV_H_INCLUDED
17
#define GDAL_ALG_PRIV_H_INCLUDED
18
19
#ifndef DOXYGEN_SKIP
20
21
#include <cstdint>
22
23
#include <set>
24
25
#include "gdal_alg.h"
26
#include "ogr_spatialref.h"
27
28
CPL_C_START
29
30
/** Source of the burn value */
31
typedef enum
32
{
33
    /*! Use value from padfBurnValue */ GBV_UserBurnValue = 0,
34
    /*! Use value from the Z coordinate */ GBV_Z = 1,
35
    /*! Use value form the M value */ GBV_M = 2
36
} GDALBurnValueSrc;
37
38
typedef enum
39
{
40
    GRMA_Replace = 0,
41
    GRMA_Add = 1,
42
} GDALRasterMergeAlg;
43
44
typedef struct
45
{
46
    unsigned char *pabyChunkBuf;
47
    int nXSize;
48
    int nYSize;
49
    int nBands;
50
    GDALDataType eType;
51
    int nPixelSpace;
52
    GSpacing nLineSpace;
53
    GSpacing nBandSpace;
54
    GDALDataType eBurnValueType;
55
56
    union
57
    {
58
        const std::int64_t *int64_values;
59
        const double *double_values;
60
    } burnValues;
61
62
    GDALBurnValueSrc eBurnValueSource;
63
    GDALRasterMergeAlg eMergeAlg;
64
    bool bFillSetVisitedPoints;
65
    std::set<uint64_t> *poSetVisitedPoints;
66
} GDALRasterizeInfo;
67
68
typedef enum
69
{
70
    GRO_Raster = 0,
71
    GRO_Vector = 1,
72
    GRO_Auto = 2,
73
} GDALRasterizeOptim;
74
75
/************************************************************************/
76
/*      Low level rasterizer API.                                       */
77
/************************************************************************/
78
79
typedef void (*llScanlineFunc)(GDALRasterizeInfo *, int, int, int, double);
80
typedef void (*llPointFunc)(GDALRasterizeInfo *, int, int, double);
81
82
void GDALdllImagePoint(int nRasterXSize, int nRasterYSize, int nPartCount,
83
                       const int *panPartSize, const double *padfX,
84
                       const double *padfY, const double *padfVariant,
85
                       llPointFunc pfnPointFunc, GDALRasterizeInfo *pCBData);
86
87
void GDALdllImageLine(int nRasterXSize, int nRasterYSize, int nPartCount,
88
                      const int *panPartSize, const double *padfX,
89
                      const double *padfY, const double *padfVariant,
90
                      llPointFunc pfnPointFunc, GDALRasterizeInfo *pCBData);
91
92
void GDALdllImageLineAllTouched(
93
    int nRasterXSize, int nRasterYSize, int nPartCount, const int *panPartSize,
94
    const double *padfX, const double *padfY, const double *padfVariant,
95
    llPointFunc pfnPointFunc, GDALRasterizeInfo *pCBData,
96
    bool bAvoidBurningSamePoints, bool bIntersectOnly);
97
98
void GDALdllImageFilledPolygon(int nRasterXSize, int nRasterYSize,
99
                               int nPartCount, const int *panPartSize,
100
                               const double *padfX, const double *padfY,
101
                               const double *padfVariant,
102
                               llScanlineFunc pfnScanlineFunc,
103
                               GDALRasterizeInfo *pCBData,
104
                               bool bAvoidBurningSamePoints);
105
106
CPL_C_END
107
108
/************************************************************************/
109
/*                          Polygon Enumerator                          */
110
/************************************************************************/
111
112
#define GP_NODATA_MARKER -51502112
113
114
template <class DataType, class EqualityTest> class GDALRasterPolygonEnumeratorT
115
116
{
117
  private:
118
    void MergePolygon(int nSrcId, int nDstId);
119
    int NewPolygon(DataType nValue);
120
121
    CPL_DISALLOW_COPY_ASSIGN(GDALRasterPolygonEnumeratorT)
122
123
  public:  // these are intended to be readonly.
124
    GInt32 *panPolyIdMap = nullptr;
125
    DataType *panPolyValue = nullptr;
126
127
    int nNextPolygonId = 0;
128
    int nPolyAlloc = 0;
129
130
    int nConnectedness = 0;
131
132
  public:
133
    explicit GDALRasterPolygonEnumeratorT(int nConnectedness = 4);
134
    ~GDALRasterPolygonEnumeratorT();
135
136
    bool ProcessLine(DataType *panLastLineVal, DataType *panThisLineVal,
137
                     GInt32 *panLastLineId, GInt32 *panThisLineId, int nXSize);
138
139
    void CompleteMerges();
140
141
    void Clear();
142
};
143
144
struct IntEqualityTest
145
{
146
    bool operator()(std::int64_t a, std::int64_t b) const
147
0
    {
148
0
        return a == b;
149
0
    }
150
};
151
152
typedef GDALRasterPolygonEnumeratorT<std::int64_t, IntEqualityTest>
153
    GDALRasterPolygonEnumerator;
154
155
constexpr const char *GDAL_APPROX_TRANSFORMER_CLASS_NAME =
156
    "GDALApproxTransformer";
157
constexpr const char *GDAL_GEN_IMG_TRANSFORMER_CLASS_NAME =
158
    "GDALGenImgProjTransformer";
159
constexpr const char *GDAL_RPC_TRANSFORMER_CLASS_NAME = "GDALRPCTransformer";
160
constexpr const char *GDAL_REPROJECTION_TRANSFORMER_CLASS_NAME =
161
    "GDALReprojectionTransformer";
162
163
bool GDALIsTransformer(void *hTransformerArg, const char *pszClassName);
164
165
typedef void *(*GDALTransformDeserializeFunc)(CPLXMLNode *psTree);
166
167
void CPL_DLL *GDALRegisterTransformDeserializer(
168
    const char *pszTransformName, GDALTransformerFunc pfnTransformerFunc,
169
    GDALTransformDeserializeFunc pfnDeserializeFunc);
170
void CPL_DLL GDALUnregisterTransformDeserializer(void *pData);
171
172
void GDALCleanupTransformDeserializerMutex();
173
174
/* Transformer cloning */
175
176
void *GDALCreateTPSTransformerInt(int nGCPCount, const GDAL_GCP *pasGCPList,
177
                                  int bReversed, CSLConstList papszOptions);
178
179
void CPL_DLL *GDALCloneTransformer(void *pTransformerArg);
180
181
void GDALRefreshGenImgProjTransformer(void *hTransformArg);
182
void GDALRefreshApproxTransformer(void *hTransformArg);
183
184
int GDALTransformLonLatToDestGenImgProjTransformer(void *hTransformArg,
185
                                                   double *pdfX, double *pdfY);
186
int GDALTransformLonLatToDestApproxTransformer(void *hTransformArg,
187
                                               double *pdfX, double *pdfY);
188
189
bool GDALTransformIsTranslationOnPixelBoundaries(
190
    GDALTransformerFunc pfnTransformer, void *pTransformerArg);
191
192
bool GDALTransformIsAffineNoRotation(GDALTransformerFunc pfnTransformer,
193
                                     void *pTransformerArg);
194
195
bool GDALTransformHasFastClone(void *pTransformerArg);
196
197
typedef struct _CPLQuadTree CPLQuadTree;
198
199
typedef struct
200
{
201
    GDALTransformerInfo sTI;
202
203
    bool bReversed;
204
    double dfOversampleFactor;
205
206
    // Map from target georef coordinates back to geolocation array
207
    // pixel line coordinates.  Built only if needed.
208
    int nBackMapWidth;
209
    int nBackMapHeight;
210
    double adfBackMapGeoTransform[6];  // Maps georef to pixel/line.
211
212
    bool bUseArray;
213
    void *pAccessors;
214
215
    // Geolocation bands.
216
    GDALDatasetH hDS_X;
217
    GDALRasterBandH hBand_X;
218
    GDALDatasetH hDS_Y;
219
    GDALRasterBandH hBand_Y;
220
    int bSwapXY;
221
222
    // Located geolocation data.
223
    int nGeoLocXSize;
224
    int nGeoLocYSize;
225
    double dfMinX;
226
    double dfYAtMinX;
227
    double dfMinY;
228
    double dfXAtMinY;
229
    double dfMaxX;
230
    double dfYAtMaxX;
231
    double dfMaxY;
232
    double dfXAtMaxY;
233
234
    int bHasNoData;
235
    double dfNoDataX;
236
237
    // Geolocation <-> base image mapping.
238
    double dfPIXEL_OFFSET;
239
    double dfPIXEL_STEP;
240
    double dfLINE_OFFSET;
241
    double dfLINE_STEP;
242
243
    bool bOriginIsTopLeftCorner;
244
    bool bGeographicSRSWithMinus180Plus180LongRange;
245
    CPLQuadTree *hQuadTree;
246
247
    char **papszGeolocationInfo;
248
249
} GDALGeoLocTransformInfo;
250
251
/************************************************************************/
252
/* ==================================================================== */
253
/*                       GDALReprojectionTransformer                    */
254
/* ==================================================================== */
255
/************************************************************************/
256
257
struct GDALReprojectionTransformInfo
258
{
259
    GDALTransformerInfo sTI;
260
    char **papszOptions = nullptr;
261
    double dfTime = 0.0;
262
263
    OGRCoordinateTransformation *poForwardTransform = nullptr;
264
    OGRCoordinateTransformation *poReverseTransform = nullptr;
265
266
0
    GDALReprojectionTransformInfo() : sTI()
267
0
    {
268
0
        memset(&sTI, 0, sizeof(sTI));
269
0
    }
270
271
    GDALReprojectionTransformInfo(const GDALReprojectionTransformInfo &) =
272
        delete;
273
    GDALReprojectionTransformInfo &
274
    operator=(const GDALReprojectionTransformInfo &) = delete;
275
};
276
277
/************************************************************************/
278
/* ==================================================================== */
279
/*      Approximate transformer.                                        */
280
/* ==================================================================== */
281
/************************************************************************/
282
283
struct GDALApproxTransformInfo
284
{
285
    GDALTransformerInfo sTI;
286
287
    GDALTransformerFunc pfnBaseTransformer = nullptr;
288
    void *pBaseCBData = nullptr;
289
    double dfMaxErrorForward = 0;
290
    double dfMaxErrorReverse = 0;
291
292
    int bOwnSubtransformer = 0;
293
294
0
    GDALApproxTransformInfo() : sTI()
295
0
    {
296
0
        memset(&sTI, 0, sizeof(sTI));
297
0
    }
298
299
    GDALApproxTransformInfo(const GDALApproxTransformInfo &) = delete;
300
    GDALApproxTransformInfo &
301
    operator=(const GDALApproxTransformInfo &) = delete;
302
};
303
304
/************************************************************************/
305
/* ==================================================================== */
306
/*                       GDALGenImgProjTransformer                      */
307
/* ==================================================================== */
308
/************************************************************************/
309
310
struct GDALGenImgProjTransformPart
311
{
312
    double adfGeoTransform[6];
313
    double adfInvGeoTransform[6];
314
315
    void *pTransformArg;
316
    GDALTransformerFunc pTransformer;
317
};
318
319
typedef struct
320
{
321
322
    GDALTransformerInfo sTI;
323
324
    GDALGenImgProjTransformPart sSrcParams;
325
326
    void *pReprojectArg;
327
    GDALTransformerFunc pReproject;
328
329
    GDALGenImgProjTransformPart sDstParams;
330
331
    // Memorize the value of the CHECK_WITH_INVERT_PROJ at the time we
332
    // instantiated the object, to be able to decide if
333
    // GDALRefreshGenImgProjTransformer() must do something or not.
334
    bool bCheckWithInvertPROJ;
335
336
    // Set to TRUE when the transformation pipline is a custom one.
337
    bool bHasCustomTransformationPipeline;
338
339
} GDALGenImgProjTransformInfo;
340
341
/************************************************************************/
342
/*      Color table related                                             */
343
/************************************************************************/
344
345
// Definitions exists for T = GUInt32 and T = GUIntBig.
346
template <class T>
347
int GDALComputeMedianCutPCTInternal(
348
    GDALRasterBandH hRed, GDALRasterBandH hGreen, GDALRasterBandH hBlue,
349
    GByte *pabyRedBand, GByte *pabyGreenBand, GByte *pabyBlueBand,
350
    int (*pfnIncludePixel)(int, int, void *), int nColors, int nBits,
351
    T *panHistogram, GDALColorTableH hColorTable, GDALProgressFunc pfnProgress,
352
    void *pProgressArg);
353
354
int GDALDitherRGB2PCTInternal(GDALRasterBandH hRed, GDALRasterBandH hGreen,
355
                              GDALRasterBandH hBlue, GDALRasterBandH hTarget,
356
                              GDALColorTableH hColorTable, int nBits,
357
                              GInt16 *pasDynamicColorMap, int bDither,
358
                              GDALProgressFunc pfnProgress, void *pProgressArg);
359
360
#define PRIME_FOR_65536 98317
361
362
// See HashHistogram structure in gdalmediancut.cpp and ColorIndex structure in
363
// gdaldither.cpp 6 * sizeof(int) should be the size of the largest of both
364
// structures.
365
#define MEDIAN_CUT_AND_DITHER_BUFFER_SIZE_65536                                \
366
    (6 * sizeof(int) * PRIME_FOR_65536)
367
368
/************************************************************************/
369
/*      Float comparison function.                                      */
370
/************************************************************************/
371
372
/**
373
 * Units in the Last Place. This specifies how big an error we are willing to
374
 * accept in terms of the value of the least significant digit of the floating
375
 * point number’s representation. MAX_ULPS can also be interpreted in terms of
376
 * how many representable floats we are willing to accept between A and B.
377
 */
378
#define MAX_ULPS 10
379
380
GBool GDALFloatEquals(float A, float B);
381
382
struct FloatEqualityTest
383
{
384
    bool operator()(float a, float b)
385
0
    {
386
0
        return GDALFloatEquals(a, b) == TRUE;
387
0
    }
388
};
389
390
bool GDALComputeAreaOfInterest(OGRSpatialReference *poSRS, double adfGT[6],
391
                               int nXSize, int nYSize,
392
                               double &dfWestLongitudeDeg,
393
                               double &dfSouthLatitudeDeg,
394
                               double &dfEastLongitudeDeg,
395
                               double &dfNorthLatitudeDeg);
396
397
bool GDALComputeAreaOfInterest(OGRSpatialReference *poSRS, double dfX1,
398
                               double dfY1, double dfX2, double dfY2,
399
                               double &dfWestLongitudeDeg,
400
                               double &dfSouthLatitudeDeg,
401
                               double &dfEastLongitudeDeg,
402
                               double &dfNorthLatitudeDeg);
403
404
CPLStringList GDALCreateGeolocationMetadata(GDALDatasetH hBaseDS,
405
                                            const char *pszGeolocationDataset,
406
                                            bool bIsSource);
407
408
void *GDALCreateGeoLocTransformerEx(GDALDatasetH hBaseDS,
409
                                    CSLConstList papszGeolocationInfo,
410
                                    int bReversed, const char *pszSourceDataset,
411
                                    CSLConstList papszTransformOptions);
412
413
#endif /* #ifndef DOXYGEN_SKIP */
414
415
#endif /* ndef GDAL_ALG_PRIV_H_INCLUDED */