/src/gdal/alg/gdalwarper.h
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * $Id$ |
3 | | * |
4 | | * Project: GDAL High Performance Warper |
5 | | * Purpose: Prototypes, and definitions for warping related work. |
6 | | * Author: Frank Warmerdam, warmerdam@pobox.com |
7 | | * |
8 | | ****************************************************************************** |
9 | | * Copyright (c) 2003, Frank Warmerdam |
10 | | * Copyright (c) 2009-2012, Even Rouault <even dot rouault at spatialys.com> |
11 | | * |
12 | | * SPDX-License-Identifier: MIT |
13 | | ****************************************************************************/ |
14 | | |
15 | | #ifndef GDALWARPER_H_INCLUDED |
16 | | #define GDALWARPER_H_INCLUDED |
17 | | |
18 | | /** |
19 | | * \file gdalwarper.h |
20 | | * |
21 | | * GDAL warper related entry points and definitions. Eventually it is |
22 | | * expected that this file will be mostly private to the implementation, |
23 | | * and the public C entry points will be available in gdal_alg.h. |
24 | | */ |
25 | | |
26 | | #include "gdal_alg.h" |
27 | | #include "cpl_minixml.h" |
28 | | #include "cpl_multiproc.h" |
29 | | |
30 | | CPL_C_START |
31 | | |
32 | | /* Note: values are selected to be consistent with GDALRIOResampleAlg of |
33 | | * gcore/gdal.h */ |
34 | | /*! Warp Resampling Algorithm */ |
35 | | typedef enum |
36 | | { |
37 | | /*! Nearest neighbour (select on one input pixel) */ GRA_NearestNeighbour = |
38 | | 0, |
39 | | /*! Bilinear (2x2 kernel) */ GRA_Bilinear = 1, |
40 | | /*! Cubic Convolution Approximation (4x4 kernel) */ GRA_Cubic = 2, |
41 | | /*! Cubic B-Spline Approximation (4x4 kernel) */ GRA_CubicSpline = 3, |
42 | | /*! Lanczos windowed sinc interpolation (6x6 kernel) */ GRA_Lanczos = 4, |
43 | | /*! Average (computes the weighted average of all non-NODATA contributing |
44 | | pixels) */ |
45 | | GRA_Average = 5, |
46 | | /*! Mode (selects the value which appears most often of all the sampled |
47 | | points) */ |
48 | | GRA_Mode = 6, |
49 | | /* GRA_Gauss=7 reserved. */ |
50 | | /*! Max (selects maximum of all non-NODATA contributing pixels) */ GRA_Max = |
51 | | 8, |
52 | | /*! Min (selects minimum of all non-NODATA contributing pixels) */ GRA_Min = |
53 | | 9, |
54 | | /*! Med (selects median of all non-NODATA contributing pixels) */ GRA_Med = |
55 | | 10, |
56 | | /*! Q1 (selects first quartile of all non-NODATA contributing pixels) */ |
57 | | GRA_Q1 = 11, |
58 | | /*! Q3 (selects third quartile of all non-NODATA contributing pixels) */ |
59 | | GRA_Q3 = 12, |
60 | | /*! Sum (weighed sum of all non-NODATA contributing pixels). Added in |
61 | | GDAL 3.1 */ |
62 | | GRA_Sum = 13, |
63 | | /*! RMS (weighted root mean square (quadratic mean) of all non-NODATA |
64 | | contributing pixels) */ |
65 | | GRA_RMS = 14, |
66 | | /*! @cond Doxygen_Suppress */ |
67 | | GRA_LAST_VALUE = GRA_RMS |
68 | | /*! @endcond */ |
69 | | } GDALResampleAlg; |
70 | | |
71 | | /*! GWKAverageOrMode Algorithm */ |
72 | | typedef enum |
73 | | { |
74 | | /*! Average */ GWKAOM_Average = 1, |
75 | | /*! Mode */ GWKAOM_Fmode = 2, |
76 | | /*! Mode of GDT_Byte, GDT_UInt16, or GDT_Int16 */ GWKAOM_Imode = 3, |
77 | | /*! Maximum */ GWKAOM_Max = 4, |
78 | | /*! Minimum */ GWKAOM_Min = 5, |
79 | | /*! Quantile */ GWKAOM_Quant = 6, |
80 | | /*! Sum */ GWKAOM_Sum = 7, |
81 | | /*! RMS */ GWKAOM_RMS = 8 |
82 | | } GWKAverageOrModeAlg; |
83 | | |
84 | | /*! @cond Doxygen_Suppress */ |
85 | | typedef int (*GDALMaskFunc)(void *pMaskFuncArg, int nBandCount, |
86 | | GDALDataType eType, int nXOff, int nYOff, |
87 | | int nXSize, int nYSize, GByte **papabyImageData, |
88 | | int bMaskIsFloat, void *pMask); |
89 | | |
90 | | CPLErr CPL_DLL GDALWarpNoDataMasker(void *pMaskFuncArg, int nBandCount, |
91 | | GDALDataType eType, int nXOff, int nYOff, |
92 | | int nXSize, int nYSize, |
93 | | GByte **papabyImageData, int bMaskIsFloat, |
94 | | void *pValidityMask, int *pbOutAllValid); |
95 | | |
96 | | CPLErr CPL_DLL GDALWarpDstAlphaMasker(void *pMaskFuncArg, int nBandCount, |
97 | | GDALDataType eType, int nXOff, int nYOff, |
98 | | int nXSize, int nYSize, |
99 | | GByte ** /*ppImageData */, |
100 | | int bMaskIsFloat, void *pValidityMask); |
101 | | CPLErr CPL_DLL GDALWarpSrcAlphaMasker(void *pMaskFuncArg, int nBandCount, |
102 | | GDALDataType eType, int nXOff, int nYOff, |
103 | | int nXSize, int nYSize, |
104 | | GByte ** /*ppImageData */, |
105 | | int bMaskIsFloat, void *pValidityMask, |
106 | | int *pbOutAllOpaque); |
107 | | |
108 | | CPLErr CPL_DLL GDALWarpSrcMaskMasker(void *pMaskFuncArg, int nBandCount, |
109 | | GDALDataType eType, int nXOff, int nYOff, |
110 | | int nXSize, int nYSize, |
111 | | GByte ** /*ppImageData */, |
112 | | int bMaskIsFloat, void *pValidityMask); |
113 | | |
114 | | CPLErr CPL_DLL GDALWarpCutlineMasker(void *pMaskFuncArg, int nBandCount, |
115 | | GDALDataType eType, int nXOff, int nYOff, |
116 | | int nXSize, int nYSize, |
117 | | GByte ** /* ppImageData */, |
118 | | int bMaskIsFloat, void *pValidityMask); |
119 | | |
120 | | /* GCMVF stands for GDALWARP_CUTLINE_MASKER_VALIDITY_FLAG */ |
121 | 0 | #define GCMVF_PARTIAL_INTERSECTION 0 |
122 | 0 | #define GCMVF_NO_INTERSECTION 1 |
123 | 0 | #define GCMVF_CHUNK_FULLY_WITHIN_CUTLINE 2 |
124 | | CPLErr CPL_DLL GDALWarpCutlineMaskerEx(void *pMaskFuncArg, int nBandCount, |
125 | | GDALDataType eType, int nXOff, int nYOff, |
126 | | int nXSize, int nYSize, |
127 | | GByte ** /* ppImageData */, |
128 | | int bMaskIsFloat, void *pValidityMask, |
129 | | int *pnValidityFlag); |
130 | | |
131 | | /*! @endcond */ |
132 | | |
133 | | /*! GWKMode tie-breaking strategy */ |
134 | | typedef enum |
135 | | { |
136 | | /* Choose the first value encountered */ GWKTS_First = 1, |
137 | | /* Choose the minimal value */ GWKTS_Min = 2, |
138 | | /* Choose the maximum value */ GWKTS_Max = 3, |
139 | | } GWKTieStrategy; |
140 | | |
141 | | /************************************************************************/ |
142 | | /* GDALWarpOptions */ |
143 | | /************************************************************************/ |
144 | | |
145 | | /** Warp control options for use with GDALWarpOperation::Initialize() */ |
146 | | typedef struct |
147 | | { |
148 | | |
149 | | char **papszWarpOptions; |
150 | | |
151 | | /*! In bytes, 0.0 for internal default */ |
152 | | double dfWarpMemoryLimit; |
153 | | |
154 | | /*! Resampling algorithm to use */ |
155 | | GDALResampleAlg eResampleAlg; |
156 | | |
157 | | /*! data type to use during warp operation, GDT_Unknown lets the algorithm |
158 | | select the type */ |
159 | | GDALDataType eWorkingDataType; |
160 | | |
161 | | /*! Source image dataset. */ |
162 | | GDALDatasetH hSrcDS; |
163 | | |
164 | | /*! Destination image dataset - may be NULL if only using |
165 | | * GDALWarpOperation::WarpRegionToBuffer(). */ |
166 | | GDALDatasetH hDstDS; |
167 | | |
168 | | /*! Number of bands to process, may be 0 to select all bands. */ |
169 | | int nBandCount; |
170 | | |
171 | | /*! The band numbers for the source bands to process (1 based) */ |
172 | | int *panSrcBands; |
173 | | |
174 | | /*! The band numbers for the destination bands to process (1 based) */ |
175 | | int *panDstBands; |
176 | | |
177 | | /*! The source band so use as an alpha (transparency) value, 0=disabled */ |
178 | | int nSrcAlphaBand; |
179 | | |
180 | | /*! The dest. band so use as an alpha (transparency) value, 0=disabled */ |
181 | | int nDstAlphaBand; |
182 | | |
183 | | /*! The "nodata" value real component for each input band, if NULL there |
184 | | * isn't one */ |
185 | | double *padfSrcNoDataReal; |
186 | | /*! The "nodata" value imaginary component - may be NULL even if real |
187 | | component is provided. This value is not used to flag invalid values. |
188 | | Only the real component is used. */ |
189 | | double *padfSrcNoDataImag; |
190 | | |
191 | | /*! The "nodata" value real component for each output band, if NULL there |
192 | | * isn't one */ |
193 | | double *padfDstNoDataReal; |
194 | | /*! The "nodata" value imaginary component - may be NULL even if real |
195 | | component is provided. Note that warp operations only use real component |
196 | | for flagging invalid data.*/ |
197 | | double *padfDstNoDataImag; |
198 | | |
199 | | /*! GDALProgressFunc() compatible progress reporting function, or NULL |
200 | | if there isn't one. */ |
201 | | GDALProgressFunc pfnProgress; |
202 | | |
203 | | /*! Callback argument to be passed to pfnProgress. */ |
204 | | void *pProgressArg; |
205 | | |
206 | | /*! Type of spatial point transformer function */ |
207 | | GDALTransformerFunc pfnTransformer; |
208 | | |
209 | | /*! Handle to image transformer setup structure */ |
210 | | void *pTransformerArg; |
211 | | |
212 | | /** Unused. Must be NULL */ |
213 | | GDALMaskFunc *papfnSrcPerBandValidityMaskFunc; |
214 | | /** Unused. Must be NULL */ |
215 | | void **papSrcPerBandValidityMaskFuncArg; |
216 | | |
217 | | /** Unused. Must be NULL */ |
218 | | GDALMaskFunc pfnSrcValidityMaskFunc; |
219 | | /** Unused. Must be NULL */ |
220 | | void *pSrcValidityMaskFuncArg; |
221 | | |
222 | | /** Unused. Must be NULL */ |
223 | | GDALMaskFunc pfnSrcDensityMaskFunc; |
224 | | /** Unused. Must be NULL */ |
225 | | void *pSrcDensityMaskFuncArg; |
226 | | |
227 | | /** Unused. Must be NULL */ |
228 | | GDALMaskFunc pfnDstDensityMaskFunc; |
229 | | /** Unused. Must be NULL */ |
230 | | void *pDstDensityMaskFuncArg; |
231 | | |
232 | | /** Unused. Must be NULL */ |
233 | | GDALMaskFunc pfnDstValidityMaskFunc; |
234 | | /** Unused. Must be NULL */ |
235 | | void *pDstValidityMaskFuncArg; |
236 | | |
237 | | /** Unused. Must be NULL */ |
238 | | CPLErr (*pfnPreWarpChunkProcessor)(void *pKern, void *pArg); |
239 | | /** Unused. Must be NULL */ |
240 | | void *pPreWarpProcessorArg; |
241 | | |
242 | | /** Unused. Must be NULL */ |
243 | | CPLErr (*pfnPostWarpChunkProcessor)(void *pKern, void *pArg); |
244 | | /** Unused. Must be NULL */ |
245 | | void *pPostWarpProcessorArg; |
246 | | |
247 | | /*! Optional OGRPolygonH for a masking cutline. */ |
248 | | void *hCutline; |
249 | | |
250 | | /*! Optional blending distance to apply across cutline in pixels, default is |
251 | | * zero. */ |
252 | | double dfCutlineBlendDist; |
253 | | |
254 | | /** Tie-breaking method */ |
255 | | GWKTieStrategy eTieStrategy; |
256 | | } GDALWarpOptions; |
257 | | |
258 | | const char CPL_DLL *GDALWarpGetOptionList(void); |
259 | | |
260 | | GDALWarpOptions CPL_DLL *CPL_STDCALL GDALCreateWarpOptions(void); |
261 | | void CPL_DLL CPL_STDCALL GDALDestroyWarpOptions(GDALWarpOptions *); |
262 | | GDALWarpOptions CPL_DLL *CPL_STDCALL |
263 | | GDALCloneWarpOptions(const GDALWarpOptions *); |
264 | | |
265 | | void CPL_DLL CPL_STDCALL GDALWarpInitDstNoDataReal(GDALWarpOptions *, |
266 | | double dNoDataReal); |
267 | | |
268 | | void CPL_DLL CPL_STDCALL GDALWarpInitSrcNoDataReal(GDALWarpOptions *, |
269 | | double dNoDataReal); |
270 | | |
271 | | void CPL_DLL CPL_STDCALL GDALWarpInitNoDataReal(GDALWarpOptions *, |
272 | | double dNoDataReal); |
273 | | |
274 | | void CPL_DLL CPL_STDCALL GDALWarpInitDstNoDataImag(GDALWarpOptions *, |
275 | | double dNoDataImag); |
276 | | |
277 | | void CPL_DLL CPL_STDCALL GDALWarpInitSrcNoDataImag(GDALWarpOptions *, |
278 | | double dNoDataImag); |
279 | | |
280 | | void CPL_DLL CPL_STDCALL GDALWarpResolveWorkingDataType(GDALWarpOptions *); |
281 | | |
282 | | void CPL_DLL CPL_STDCALL GDALWarpInitDefaultBandMapping(GDALWarpOptions *, |
283 | | int nBandCount); |
284 | | |
285 | | /*! @cond Doxygen_Suppress */ |
286 | | CPLXMLNode CPL_DLL *CPL_STDCALL |
287 | | GDALSerializeWarpOptions(const GDALWarpOptions *); |
288 | | GDALWarpOptions CPL_DLL *CPL_STDCALL GDALDeserializeWarpOptions(CPLXMLNode *); |
289 | | /*! @endcond */ |
290 | | |
291 | | /************************************************************************/ |
292 | | /* GDALReprojectImage() */ |
293 | | /************************************************************************/ |
294 | | |
295 | | CPLErr CPL_DLL CPL_STDCALL GDALReprojectImage( |
296 | | GDALDatasetH hSrcDS, const char *pszSrcWKT, GDALDatasetH hDstDS, |
297 | | const char *pszDstWKT, GDALResampleAlg eResampleAlg, |
298 | | double dfWarpMemoryLimit, double dfMaxError, GDALProgressFunc pfnProgress, |
299 | | void *pProgressArg, GDALWarpOptions *psOptions); |
300 | | |
301 | | CPLErr CPL_DLL CPL_STDCALL GDALCreateAndReprojectImage( |
302 | | GDALDatasetH hSrcDS, const char *pszSrcWKT, const char *pszDstFilename, |
303 | | const char *pszDstWKT, GDALDriverH hDstDriver, char **papszCreateOptions, |
304 | | GDALResampleAlg eResampleAlg, double dfWarpMemoryLimit, double dfMaxError, |
305 | | GDALProgressFunc pfnProgress, void *pProgressArg, |
306 | | GDALWarpOptions *psOptions); |
307 | | |
308 | | /************************************************************************/ |
309 | | /* VRTWarpedDataset */ |
310 | | /************************************************************************/ |
311 | | |
312 | | GDALDatasetH CPL_DLL CPL_STDCALL |
313 | | GDALAutoCreateWarpedVRT(GDALDatasetH hSrcDS, const char *pszSrcWKT, |
314 | | const char *pszDstWKT, GDALResampleAlg eResampleAlg, |
315 | | double dfMaxError, const GDALWarpOptions *psOptions); |
316 | | |
317 | | GDALDatasetH CPL_DLL CPL_STDCALL GDALAutoCreateWarpedVRTEx( |
318 | | GDALDatasetH hSrcDS, const char *pszSrcWKT, const char *pszDstWKT, |
319 | | GDALResampleAlg eResampleAlg, double dfMaxError, |
320 | | const GDALWarpOptions *psOptions, CSLConstList papszTransformerOptions); |
321 | | |
322 | | GDALDatasetH CPL_DLL CPL_STDCALL |
323 | | GDALCreateWarpedVRT(GDALDatasetH hSrcDS, int nPixels, int nLines, |
324 | | double *padfGeoTransform, GDALWarpOptions *psOptions); |
325 | | |
326 | | CPLErr CPL_DLL CPL_STDCALL GDALInitializeWarpedVRT(GDALDatasetH hDS, |
327 | | GDALWarpOptions *psWO); |
328 | | |
329 | | CPL_C_END |
330 | | |
331 | | #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS) |
332 | | |
333 | | #include <vector> |
334 | | #include <utility> |
335 | | |
336 | | bool GDALGetWarpResampleAlg(const char *pszResampling, |
337 | | GDALResampleAlg &eResampleAlg, bool bThrow = false); |
338 | | |
339 | | /************************************************************************/ |
340 | | /* GDALWarpKernel */ |
341 | | /* */ |
342 | | |
343 | | /** This is the number of dummy pixels that must be reserved in source arrays |
344 | | * in order to satisfy assumptions made in GWKResample(), and more specifically |
345 | | * by GWKGetPixelRow() that always read a even number of pixels. So if we are |
346 | | * in the situation to read the last pixel of the source array, we need 1 extra |
347 | | * dummy pixel to avoid reading out of bounds. */ |
348 | 0 | #define WARP_EXTRA_ELTS 1 |
349 | | |
350 | | /** This class represents the lowest level of abstraction of warping. |
351 | | * |
352 | | * It holds the imagery for one "chunk" of a warp, and the |
353 | | * pre-prepared masks. All IO is done before and after its |
354 | | * operation. This class is not normally used by the |
355 | | * application. |
356 | | */ |
357 | | class CPL_DLL GDALWarpKernel |
358 | | { |
359 | | CPL_DISALLOW_COPY_ASSIGN(GDALWarpKernel) |
360 | | |
361 | | public: |
362 | | /** Warp options */ |
363 | | char **papszWarpOptions; |
364 | | |
365 | | /** Resample algorithm */ |
366 | | GDALResampleAlg eResample; |
367 | | /** Working data type */ |
368 | | GDALDataType eWorkingDataType; |
369 | | /** Number of input and output bands (excluding alpha bands) */ |
370 | | int nBands; |
371 | | |
372 | | /** Width of the source image */ |
373 | | int nSrcXSize; |
374 | | /** Height of the source image */ |
375 | | int nSrcYSize; |
376 | | /** Extra pixels (included in nSrcXSize) reserved for filter window. Should |
377 | | * be ignored in scale computation */ |
378 | | double dfSrcXExtraSize; |
379 | | /** Extra pixels (included in nSrcYSize) reserved for filter window. Should |
380 | | * be ignored in scale computation */ |
381 | | double dfSrcYExtraSize; |
382 | | /** Array of nBands source images of size nSrcXSize * nSrcYSize. Each |
383 | | * subarray must have WARP_EXTRA_ELTS at the end */ |
384 | | GByte **papabySrcImage; |
385 | | |
386 | | /** Array of nBands validity mask of size (nSrcXSize * nSrcYSize + |
387 | | * WARP_EXTRA_ELTS) / 8 */ |
388 | | GUInt32 **papanBandSrcValid; |
389 | | /** Unified validity mask of size (nSrcXSize * nSrcYSize + WARP_EXTRA_ELTS) |
390 | | * / 8 */ |
391 | | GUInt32 *panUnifiedSrcValid; |
392 | | /** Unified source density of size nSrcXSize * nSrcYSize + WARP_EXTRA_ELTS |
393 | | */ |
394 | | float *pafUnifiedSrcDensity; |
395 | | |
396 | | /** Width of the destination image */ |
397 | | int nDstXSize; |
398 | | /** Height of the destination image */ |
399 | | int nDstYSize; |
400 | | /** Array of nBands destination images of size nDstXSize * nDstYSize */ |
401 | | GByte **papabyDstImage; |
402 | | /** Validify mask of size (nDstXSize * nDstYSize) / 8 */ |
403 | | GUInt32 *panDstValid; |
404 | | /** Destination density of size nDstXSize * nDstYSize */ |
405 | | float *pafDstDensity; |
406 | | |
407 | | /** X resampling scale, i.e. nDstXSize / nSrcXSize */ |
408 | | double dfXScale; |
409 | | /** Y resampling scale, i.e. nDstYSize / nSrcYSize */ |
410 | | double dfYScale; |
411 | | /** X size of filter kernel */ |
412 | | double dfXFilter; |
413 | | /** Y size of filter kernel */ |
414 | | double dfYFilter; |
415 | | /** X size of window to filter */ |
416 | | int nXRadius; |
417 | | /** Y size of window to filter */ |
418 | | int nYRadius; |
419 | | /** X filtering offset */ |
420 | | int nFiltInitX; |
421 | | /** Y filtering offset */ |
422 | | int nFiltInitY; |
423 | | |
424 | | /** X offset of the source buffer regarding the top-left corner of the image |
425 | | */ |
426 | | int nSrcXOff; |
427 | | /** Y offset of the source buffer regarding the top-left corner of the image |
428 | | */ |
429 | | int nSrcYOff; |
430 | | |
431 | | /** X offset of the destination buffer regarding the top-left corner of the |
432 | | * image */ |
433 | | int nDstXOff; |
434 | | /** Y offset of the destination buffer regarding the top-left corner of the |
435 | | * image */ |
436 | | int nDstYOff; |
437 | | |
438 | | /** Pixel transformation function */ |
439 | | GDALTransformerFunc pfnTransformer; |
440 | | /** User data provided to pfnTransformer */ |
441 | | void *pTransformerArg; |
442 | | |
443 | | /** Progress function */ |
444 | | GDALProgressFunc pfnProgress; |
445 | | /** User data provided to pfnProgress */ |
446 | | void *pProgress; |
447 | | |
448 | | /** Base/offset value for progress computation */ |
449 | | double dfProgressBase; |
450 | | /** Scale value for progress computation */ |
451 | | double dfProgressScale; |
452 | | |
453 | | /** Array of nBands value for destination nodata */ |
454 | | double *padfDstNoDataReal; |
455 | | |
456 | | /*! @cond Doxygen_Suppress */ |
457 | | /** Per-thread data. Internally set */ |
458 | | void *psThreadData; |
459 | | |
460 | | bool bApplyVerticalShift = false; |
461 | | |
462 | | double dfMultFactorVerticalShift = 1.0; |
463 | | |
464 | | // Tuples of values (e.g. "<R>,<G>,<B>" or "(<R1>,<G1>,<B1>),(<R2>,<G2>,<B2>)") that must |
465 | | // be ignored as contributing source pixels during resampling. Only taken into account by |
466 | | // Average currently |
467 | | std::vector<std::vector<double>> m_aadfExcludedValues{}; |
468 | | |
469 | | GWKTieStrategy eTieStrategy; |
470 | | |
471 | | bool bWarnedAboutDstNoDataReplacement = false; |
472 | | |
473 | | /*! @endcond */ |
474 | | |
475 | | GDALWarpKernel(); |
476 | | virtual ~GDALWarpKernel(); |
477 | | |
478 | | CPLErr Validate(); |
479 | | CPLErr PerformWarp(); |
480 | | }; |
481 | | |
482 | | /*! @cond Doxygen_Suppress */ |
483 | | void *GWKThreadsCreate(char **papszWarpOptions, |
484 | | GDALTransformerFunc pfnTransformer, |
485 | | void *pTransformerArg); |
486 | | void GWKThreadsEnd(void *psThreadDataIn); |
487 | | /*! @endcond */ |
488 | | |
489 | | /************************************************************************/ |
490 | | /* GDALWarpOperation() */ |
491 | | /* */ |
492 | | /* This object is application created, or created by a higher */ |
493 | | /* level convenience function. It is responsible for */ |
494 | | /* subdividing the operation into chunks, loading and saving */ |
495 | | /* imagery, and establishing the varios validity and density */ |
496 | | /* masks. Actual resampling is done by the GDALWarpKernel. */ |
497 | | /************************************************************************/ |
498 | | |
499 | | /*! @cond Doxygen_Suppress */ |
500 | | typedef struct _GDALWarpChunk GDALWarpChunk; |
501 | | |
502 | | struct GDALTransformerUniquePtrReleaser |
503 | | { |
504 | | void operator()(void *p) |
505 | 0 | { |
506 | 0 | GDALDestroyTransformer(p); |
507 | 0 | } |
508 | | }; |
509 | | |
510 | | /*! @endcond */ |
511 | | |
512 | | /** Unique pointer for the argument of a GDALTransformerFunc */ |
513 | | using GDALTransformerArgUniquePtr = |
514 | | std::unique_ptr<void, GDALTransformerUniquePtrReleaser>; |
515 | | |
516 | | class CPL_DLL GDALWarpOperation final |
517 | | { |
518 | | |
519 | | CPL_DISALLOW_COPY_ASSIGN(GDALWarpOperation) |
520 | | |
521 | | private: |
522 | | GDALWarpOptions *psOptions = nullptr; |
523 | | GDALTransformerArgUniquePtr m_psOwnedTransformerArg{nullptr}; |
524 | | |
525 | | void WipeOptions(); |
526 | | int ValidateOptions(); |
527 | | |
528 | | bool ComputeSourceWindowTransformPoints( |
529 | | int nDstXOff, int nDstYOff, int nDstXSize, int nDstYSize, bool bUseGrid, |
530 | | bool bAll, int nStepCount, bool bTryWithCheckWithInvertProj, |
531 | | double &dfMinXOut, double &dfMinYOut, double &dfMaxXOut, |
532 | | double &dfMaxYOut, int &nSamplePoints, int &nFailedCount); |
533 | | |
534 | | void ComputeSourceWindowStartingFromSource(int nDstXOff, int nDstYOff, |
535 | | int nDstXSize, int nDstYSize, |
536 | | double *padfSrcMinX, |
537 | | double *padfSrcMinY, |
538 | | double *padfSrcMaxX, |
539 | | double *padfSrcMaxY); |
540 | | |
541 | | static CPLErr CreateKernelMask(GDALWarpKernel *, int iBand, |
542 | | const char *pszType); |
543 | | |
544 | | CPLMutex *hIOMutex = nullptr; |
545 | | CPLMutex *hWarpMutex = nullptr; |
546 | | |
547 | | int nChunkListCount = 0; |
548 | | int nChunkListMax = 0; |
549 | | GDALWarpChunk *pasChunkList = nullptr; |
550 | | |
551 | | bool bReportTimings = false; |
552 | | unsigned long nLastTimeReported = 0; |
553 | | |
554 | | void *psThreadData = nullptr; |
555 | | |
556 | | // Coordinates a few special points in target image space, to determine |
557 | | // if ComputeSourceWindow() must use a grid based sampling. |
558 | | std::vector<std::pair<double, double>> aDstXYSpecialPoints{}; |
559 | | |
560 | | bool m_bIsTranslationOnPixelBoundaries = false; |
561 | | |
562 | | void WipeChunkList(); |
563 | | CPLErr CollectChunkListInternal(int nDstXOff, int nDstYOff, int nDstXSize, |
564 | | int nDstYSize); |
565 | | void CollectChunkList(int nDstXOff, int nDstYOff, int nDstXSize, |
566 | | int nDstYSize); |
567 | | void ReportTiming(const char *); |
568 | | |
569 | | public: |
570 | | GDALWarpOperation(); |
571 | | ~GDALWarpOperation(); |
572 | | |
573 | | CPLErr Initialize(const GDALWarpOptions *psNewOptions, |
574 | | GDALTransformerFunc pfnTransformer = nullptr, |
575 | | GDALTransformerArgUniquePtr psOwnedTransformerArg = |
576 | | GDALTransformerArgUniquePtr{nullptr}); |
577 | | void *CreateDestinationBuffer(int nDstXSize, int nDstYSize, |
578 | | int *pbWasInitialized = nullptr); |
579 | | CPLErr InitializeDestinationBuffer(void *pDstBuffer, int nDstXSize, |
580 | | int nDstYSize, |
581 | | int *pbWasInitialized = nullptr) const; |
582 | | static void DestroyDestinationBuffer(void *pDstBuffer); |
583 | | |
584 | | const GDALWarpOptions *GetOptions(); |
585 | | |
586 | | CPLErr ChunkAndWarpImage(int nDstXOff, int nDstYOff, int nDstXSize, |
587 | | int nDstYSize); |
588 | | CPLErr ChunkAndWarpMulti(int nDstXOff, int nDstYOff, int nDstXSize, |
589 | | int nDstYSize); |
590 | | CPLErr WarpRegion(int nDstXOff, int nDstYOff, int nDstXSize, int nDstYSize, |
591 | | int nSrcXOff = 0, int nSrcYOff = 0, int nSrcXSize = 0, |
592 | | int nSrcYSize = 0, double dfProgressBase = 0.0, |
593 | | double dfProgressScale = 1.0); |
594 | | CPLErr WarpRegion(int nDstXOff, int nDstYOff, int nDstXSize, int nDstYSize, |
595 | | int nSrcXOff, int nSrcYOff, int nSrcXSize, int nSrcYSize, |
596 | | double dfSrcXExtraSize, double dfSrcYExtraSize, |
597 | | double dfProgressBase, double dfProgressScale); |
598 | | CPLErr WarpRegionToBuffer(int nDstXOff, int nDstYOff, int nDstXSize, |
599 | | int nDstYSize, void *pDataBuf, |
600 | | GDALDataType eBufDataType, int nSrcXOff = 0, |
601 | | int nSrcYOff = 0, int nSrcXSize = 0, |
602 | | int nSrcYSize = 0, double dfProgressBase = 0.0, |
603 | | double dfProgressScale = 1.0); |
604 | | CPLErr WarpRegionToBuffer(int nDstXOff, int nDstYOff, int nDstXSize, |
605 | | int nDstYSize, void *pDataBuf, |
606 | | GDALDataType eBufDataType, int nSrcXOff, |
607 | | int nSrcYOff, int nSrcXSize, int nSrcYSize, |
608 | | double dfSrcXExtraSize, double dfSrcYExtraSize, |
609 | | double dfProgressBase, double dfProgressScale); |
610 | | |
611 | | protected: |
612 | | friend class VRTWarpedDataset; |
613 | | CPLErr ComputeSourceWindow(int nDstXOff, int nDstYOff, int nDstXSize, |
614 | | int nDstYSize, int *pnSrcXOff, int *pnSrcYOff, |
615 | | int *pnSrcXSize, int *pnSrcYSize, |
616 | | double *pdfSrcXExtraSize, |
617 | | double *pdfSrcYExtraSize, |
618 | | double *pdfSrcFillRatio); |
619 | | |
620 | | double GetWorkingMemoryForWindow(int nSrcXSize, int nSrcYSize, |
621 | | int nDstXSize, int nDstYSize) const; |
622 | | }; |
623 | | |
624 | | #endif /* def __cplusplus */ |
625 | | |
626 | | CPL_C_START |
627 | | |
628 | | /** Opaque type representing a GDALWarpOperation object */ |
629 | | typedef void *GDALWarpOperationH; |
630 | | |
631 | | GDALWarpOperationH CPL_DLL GDALCreateWarpOperation(const GDALWarpOptions *); |
632 | | void CPL_DLL GDALDestroyWarpOperation(GDALWarpOperationH); |
633 | | CPLErr CPL_DLL GDALChunkAndWarpImage(GDALWarpOperationH, int, int, int, int); |
634 | | CPLErr CPL_DLL GDALChunkAndWarpMulti(GDALWarpOperationH, int, int, int, int); |
635 | | CPLErr CPL_DLL GDALWarpRegion(GDALWarpOperationH, int, int, int, int, int, int, |
636 | | int, int); |
637 | | CPLErr CPL_DLL GDALWarpRegionToBuffer(GDALWarpOperationH, int, int, int, int, |
638 | | void *, GDALDataType, int, int, int, int); |
639 | | |
640 | | /************************************************************************/ |
641 | | /* Warping kernel functions */ |
642 | | /************************************************************************/ |
643 | | |
644 | | /*! @cond Doxygen_Suppress */ |
645 | | int GWKGetFilterRadius(GDALResampleAlg eResampleAlg); |
646 | | |
647 | | typedef double (*FilterFuncType)(double dfX); |
648 | | FilterFuncType GWKGetFilterFunc(GDALResampleAlg eResampleAlg); |
649 | | |
650 | | // TODO(schwehr): Can padfVals be a const pointer? |
651 | | typedef double (*FilterFunc4ValuesType)(double *padfVals); |
652 | | FilterFunc4ValuesType GWKGetFilterFunc4Values(GDALResampleAlg eResampleAlg); |
653 | | /*! @endcond */ |
654 | | |
655 | | CPL_C_END |
656 | | |
657 | | #endif /* ndef GDAL_ALG_H_INCLUDED */ |