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