/src/gdal/alg/gdal_interpolateatpoint.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * $Id$ |
3 | | * |
4 | | * Project: GDAL DEM Interpolation |
5 | | * Purpose: Interpolation algorithms with cache |
6 | | * Author: Frank Warmerdam, warmerdam@pobox.com |
7 | | * |
8 | | ****************************************************************************** |
9 | | * Copyright (c) 2001, Frank Warmerdam |
10 | | * Copyright (c) 2008-2012, Even Rouault <even dot rouault at spatialys.com> |
11 | | * Copyright (c) 2024, Javier Jimenez Shaw |
12 | | * |
13 | | * SPDX-License-Identifier: MIT |
14 | | ****************************************************************************/ |
15 | | |
16 | | #include "gdal_interpolateatpoint.h" |
17 | | |
18 | | #include "gdalresamplingkernels.h" |
19 | | |
20 | | #include "gdal_vectorx.h" |
21 | | |
22 | | #include <algorithm> |
23 | | #include <complex> |
24 | | |
25 | | template <typename T> bool areEqualReal(double dfNoDataValue, T dfOut); |
26 | | |
27 | | template <> bool areEqualReal(double dfNoDataValue, double dfOut) |
28 | 0 | { |
29 | 0 | return ARE_REAL_EQUAL(dfNoDataValue, dfOut); |
30 | 0 | } |
31 | | |
32 | | template <> bool areEqualReal(double dfNoDataValue, std::complex<double> dfOut) |
33 | 0 | { |
34 | 0 | return ARE_REAL_EQUAL(dfNoDataValue, dfOut.real()); |
35 | 0 | } |
36 | | |
37 | | // Only valid for T = double or std::complex<double> |
38 | | template <typename T> |
39 | | bool GDALInterpExtractValuesWindow(GDALRasterBand *pBand, |
40 | | std::unique_ptr<DoublePointsCache> &cache, |
41 | | gdal::Vector2i point, |
42 | | gdal::Vector2i dimensions, T *padfOut) |
43 | 0 | { |
44 | 0 | constexpr int BLOCK_SIZE = 64; |
45 | |
|
46 | 0 | const int nX = point.x(); |
47 | 0 | const int nY = point.y(); |
48 | 0 | const int nWidth = dimensions.x(); |
49 | 0 | const int nHeight = dimensions.y(); |
50 | | |
51 | | // Request the DEM by blocks of BLOCK_SIZE * BLOCK_SIZE and put them |
52 | | // in cache |
53 | 0 | if (!cache) |
54 | 0 | cache.reset(new DoublePointsCache{}); |
55 | |
|
56 | 0 | const int nXIters = (nX + nWidth - 1) / BLOCK_SIZE - nX / BLOCK_SIZE + 1; |
57 | 0 | const int nYIters = (nY + nHeight - 1) / BLOCK_SIZE - nY / BLOCK_SIZE + 1; |
58 | 0 | const int nRasterXSize = pBand->GetXSize(); |
59 | 0 | const int nRasterYSize = pBand->GetYSize(); |
60 | 0 | const bool bIsComplex = |
61 | 0 | CPL_TO_BOOL(GDALDataTypeIsComplex(pBand->GetRasterDataType())); |
62 | |
|
63 | 0 | for (int iY = 0; iY < nYIters; iY++) |
64 | 0 | { |
65 | 0 | const int nBlockY = nY / BLOCK_SIZE + iY; |
66 | 0 | const int nReqYSize = |
67 | 0 | std::min(nRasterYSize - nBlockY * BLOCK_SIZE, BLOCK_SIZE); |
68 | 0 | const int nFirstLineInCachedBlock = (iY == 0) ? nY % BLOCK_SIZE : 0; |
69 | 0 | const int nFirstLineInOutput = |
70 | 0 | (iY == 0) ? 0 |
71 | 0 | : BLOCK_SIZE - (nY % BLOCK_SIZE) + (iY - 1) * BLOCK_SIZE; |
72 | 0 | const int nLinesToCopy = (nYIters == 1) ? nHeight |
73 | 0 | : (iY == 0) ? BLOCK_SIZE - (nY % BLOCK_SIZE) |
74 | 0 | : (iY == nYIters - 1) |
75 | 0 | ? 1 + (nY + nHeight - 1) % BLOCK_SIZE |
76 | 0 | : BLOCK_SIZE; |
77 | 0 | for (int iX = 0; iX < nXIters; iX++) |
78 | 0 | { |
79 | 0 | const int nBlockX = nX / BLOCK_SIZE + iX; |
80 | 0 | const int nReqXSize = |
81 | 0 | std::min(nRasterXSize - nBlockX * BLOCK_SIZE, BLOCK_SIZE); |
82 | 0 | const uint64_t nKey = |
83 | 0 | (static_cast<uint64_t>(nBlockY) << 32) | nBlockX; |
84 | 0 | const int nFirstColInCachedBlock = (iX == 0) ? nX % BLOCK_SIZE : 0; |
85 | 0 | const int nFirstColInOutput = |
86 | 0 | (iX == 0) |
87 | 0 | ? 0 |
88 | 0 | : BLOCK_SIZE - (nX % BLOCK_SIZE) + (iX - 1) * BLOCK_SIZE; |
89 | 0 | const int nColsToCopy = (nXIters == 1) ? nWidth |
90 | 0 | : (iX == 0) ? BLOCK_SIZE - (nX % BLOCK_SIZE) |
91 | 0 | : (iX == nXIters - 1) |
92 | 0 | ? 1 + (nX + nWidth - 1) % BLOCK_SIZE |
93 | 0 | : BLOCK_SIZE; |
94 | |
|
95 | | #if 0 |
96 | | CPLDebug("RPC", "nY=%d nX=%d nBlockY=%d nBlockX=%d " |
97 | | "nFirstLineInCachedBlock=%d nFirstLineInOutput=%d nLinesToCopy=%d " |
98 | | "nFirstColInCachedBlock=%d nFirstColInOutput=%d nColsToCopy=%d", |
99 | | nY, nX, nBlockY, nBlockX, nFirstLineInCachedBlock, nFirstLineInOutput, nLinesToCopy, |
100 | | nFirstColInCachedBlock, nFirstColInOutput, nColsToCopy); |
101 | | #endif |
102 | |
|
103 | 0 | constexpr int nTypeFactor = sizeof(T) / sizeof(double); |
104 | 0 | std::shared_ptr<std::vector<double>> poValue; |
105 | 0 | if (!cache->tryGet(nKey, poValue)) |
106 | 0 | { |
107 | 0 | const GDALDataType eDataType = |
108 | 0 | bIsComplex ? GDT_CFloat64 : GDT_Float64; |
109 | 0 | const size_t nVectorSize = |
110 | 0 | size_t(nReqXSize) * nReqYSize * nTypeFactor; |
111 | 0 | poValue = std::make_shared<std::vector<double>>(nVectorSize); |
112 | 0 | CPLErr eErr = pBand->RasterIO( |
113 | 0 | GF_Read, nBlockX * BLOCK_SIZE, nBlockY * BLOCK_SIZE, |
114 | 0 | nReqXSize, nReqYSize, poValue->data(), nReqXSize, nReqYSize, |
115 | 0 | eDataType, 0, 0, nullptr); |
116 | 0 | if (eErr != CE_None) |
117 | 0 | { |
118 | 0 | return false; |
119 | 0 | } |
120 | 0 | cache->insert(nKey, poValue); |
121 | 0 | } |
122 | | |
123 | 0 | double *padfAsDouble = reinterpret_cast<double *>(padfOut); |
124 | | // Compose the cached block to the final buffer |
125 | 0 | for (int j = 0; j < nLinesToCopy; j++) |
126 | 0 | { |
127 | 0 | const size_t dstOffset = |
128 | 0 | (static_cast<size_t>(nFirstLineInOutput + j) * nWidth + |
129 | 0 | nFirstColInOutput) * |
130 | 0 | nTypeFactor; |
131 | 0 | const size_t srcOffset = |
132 | 0 | (static_cast<size_t>(nFirstLineInCachedBlock + j) * |
133 | 0 | nReqXSize + |
134 | 0 | nFirstColInCachedBlock) * |
135 | 0 | nTypeFactor; |
136 | 0 | if (srcOffset + nColsToCopy * nTypeFactor > poValue->size()) |
137 | 0 | { |
138 | 0 | return false; |
139 | 0 | } |
140 | 0 | memcpy(padfAsDouble + dstOffset, poValue->data() + srcOffset, |
141 | 0 | nColsToCopy * sizeof(T)); |
142 | 0 | } |
143 | 0 | } |
144 | 0 | } |
145 | | |
146 | | #if 0 |
147 | | CPLDebug("RPC_DEM", "DEM for %d,%d,%d,%d", nX, nY, nWidth, nHeight); |
148 | | for(int j = 0; j < nHeight; j++) |
149 | | { |
150 | | std::string osLine; |
151 | | for(int i = 0; i < nWidth; ++i ) |
152 | | { |
153 | | if( !osLine.empty() ) |
154 | | osLine += ", "; |
155 | | osLine += std::to_string(padfOut[j * nWidth + i]); |
156 | | } |
157 | | CPLDebug("RPC_DEM", "%s", osLine.c_str()); |
158 | | } |
159 | | #endif |
160 | | |
161 | 0 | return true; |
162 | 0 | } Unexecuted instantiation: bool GDALInterpExtractValuesWindow<std::__1::complex<double> >(GDALRasterBand*, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, gdal::VectorX<int, 2ul>, gdal::VectorX<int, 2ul>, std::__1::complex<double>*) Unexecuted instantiation: bool GDALInterpExtractValuesWindow<double>(GDALRasterBand*, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, gdal::VectorX<int, 2ul>, gdal::VectorX<int, 2ul>, double*) |
163 | | |
164 | | template <typename T> |
165 | | bool GDALInterpolateAtPointImpl(GDALRasterBand *pBand, |
166 | | GDALRIOResampleAlg eResampleAlg, |
167 | | std::unique_ptr<DoublePointsCache> &cache, |
168 | | double dfXIn, double dfYIn, T &out) |
169 | 0 | { |
170 | 0 | const gdal::Vector2i rasterSize{pBand->GetXSize(), pBand->GetYSize()}; |
171 | |
|
172 | 0 | if (eResampleAlg == GRIORA_NearestNeighbour) |
173 | 0 | { |
174 | | // Allow input coordinates right at the bottom or right edge |
175 | | // with GRIORA_NearestNeighbour. |
176 | | // "introduce" them in the pixel of the image. |
177 | 0 | if (dfXIn >= rasterSize.x() && dfXIn <= rasterSize.x() + 1e-5) |
178 | 0 | dfXIn -= 0.25; |
179 | 0 | if (dfYIn >= rasterSize.y() && dfYIn <= rasterSize.y() + 1e-5) |
180 | 0 | dfYIn -= 0.25; |
181 | 0 | } |
182 | 0 | const gdal::Vector2d inLoc{dfXIn, dfYIn}; |
183 | |
|
184 | 0 | int bGotNoDataValue = FALSE; |
185 | 0 | const double dfNoDataValue = pBand->GetNoDataValue(&bGotNoDataValue); |
186 | |
|
187 | 0 | if (inLoc.x() < 0 || inLoc.x() > rasterSize.x() || inLoc.y() < 0 || |
188 | 0 | inLoc.y() > rasterSize.y()) |
189 | 0 | { |
190 | 0 | return FALSE; |
191 | 0 | } |
192 | | |
193 | | // Downgrade the interpolation algorithm if the image is too small |
194 | 0 | if ((rasterSize.x() < 4 || rasterSize.y() < 4) && |
195 | 0 | (eResampleAlg == GRIORA_CubicSpline || eResampleAlg == GRIORA_Cubic)) |
196 | 0 | { |
197 | 0 | eResampleAlg = GRIORA_Bilinear; |
198 | 0 | } |
199 | 0 | if ((rasterSize.x() < 2 || rasterSize.y() < 2) && |
200 | 0 | eResampleAlg == GRIORA_Bilinear) |
201 | 0 | { |
202 | 0 | eResampleAlg = GRIORA_NearestNeighbour; |
203 | 0 | } |
204 | |
|
205 | 0 | auto outOfBorderCorrectionSimple = |
206 | 0 | [](int dNew, int nRasterSize, int nKernelsize) |
207 | 0 | { |
208 | 0 | int dOutOfBorder = 0; |
209 | 0 | if (dNew < 0) |
210 | 0 | { |
211 | 0 | dOutOfBorder = dNew; |
212 | 0 | } |
213 | 0 | if (dNew + nKernelsize >= nRasterSize) |
214 | 0 | { |
215 | 0 | dOutOfBorder = dNew + nKernelsize - nRasterSize; |
216 | 0 | } |
217 | 0 | return dOutOfBorder; |
218 | 0 | }; Unexecuted instantiation: GDALInterpolateAtPointImpl<std::__1::complex<double> >(GDALRasterBand*, GDALRIOResampleAlg, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, double, double, std::__1::complex<double>&)::{lambda(int, int, int)#1}::operator()(int, int, int) const Unexecuted instantiation: GDALInterpolateAtPointImpl<double>(GDALRasterBand*, GDALRIOResampleAlg, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, double, double, double&)::{lambda(int, int, int)#1}::operator()(int, int, int) const |
219 | |
|
220 | 0 | auto outOfBorderCorrection = |
221 | 0 | [&outOfBorderCorrectionSimple, |
222 | 0 | &rasterSize](gdal::Vector2i input, int nKernelsize) -> gdal::Vector2i |
223 | 0 | { |
224 | 0 | return { |
225 | 0 | outOfBorderCorrectionSimple(input.x(), rasterSize.x(), nKernelsize), |
226 | 0 | outOfBorderCorrectionSimple(input.y(), rasterSize.y(), |
227 | 0 | nKernelsize)}; |
228 | 0 | }; Unexecuted instantiation: GDALInterpolateAtPointImpl<std::__1::complex<double> >(GDALRasterBand*, GDALRIOResampleAlg, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, double, double, std::__1::complex<double>&)::{lambda(gdal::VectorX<int, 2ul>, int)#1}::operator()(gdal::VectorX<int, 2ul>, int) const Unexecuted instantiation: GDALInterpolateAtPointImpl<double>(GDALRasterBand*, GDALRIOResampleAlg, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, double, double, double&)::{lambda(gdal::VectorX<int, 2ul>, int)#1}::operator()(gdal::VectorX<int, 2ul>, int) const |
229 | |
|
230 | 0 | auto dragReadDataInBorderSimple = |
231 | 0 | [](T *adfElevData, int dOutOfBorder, int nKernelSize, bool bIsX) |
232 | 0 | { |
233 | 0 | while (dOutOfBorder < 0) |
234 | 0 | { |
235 | 0 | for (int j = 0; j < nKernelSize; j++) |
236 | 0 | for (int ii = 0; ii < nKernelSize - 1; ii++) |
237 | 0 | { |
238 | 0 | const int i = nKernelSize - ii - 2; // iterate in reverse |
239 | 0 | const int row_src = bIsX ? j : i; |
240 | 0 | const int row_dst = bIsX ? j : i + 1; |
241 | 0 | const int col_src = bIsX ? i : j; |
242 | 0 | const int col_dst = bIsX ? i + 1 : j; |
243 | 0 | adfElevData[nKernelSize * row_dst + col_dst] = |
244 | 0 | adfElevData[nKernelSize * row_src + col_src]; |
245 | 0 | } |
246 | 0 | dOutOfBorder++; |
247 | 0 | } |
248 | 0 | while (dOutOfBorder > 0) |
249 | 0 | { |
250 | 0 | for (int j = 0; j < nKernelSize; j++) |
251 | 0 | for (int i = 0; i < nKernelSize - 1; i++) |
252 | 0 | { |
253 | 0 | const int row_src = bIsX ? j : i + 1; |
254 | 0 | const int row_dst = bIsX ? j : i; |
255 | 0 | const int col_src = bIsX ? i + 1 : j; |
256 | 0 | const int col_dst = bIsX ? i : j; |
257 | 0 | adfElevData[nKernelSize * row_dst + col_dst] = |
258 | 0 | adfElevData[nKernelSize * row_src + col_src]; |
259 | 0 | } |
260 | 0 | dOutOfBorder--; |
261 | 0 | } |
262 | 0 | }; Unexecuted instantiation: GDALInterpolateAtPointImpl<std::__1::complex<double> >(GDALRasterBand*, GDALRIOResampleAlg, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, double, double, std::__1::complex<double>&)::{lambda(std::__1::complex<double>*, int, int, bool)#1}::operator()(std::__1::complex<double>*, int, int, bool) const Unexecuted instantiation: GDALInterpolateAtPointImpl<double>(GDALRasterBand*, GDALRIOResampleAlg, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, double, double, double&)::{lambda(double*, int, int, bool)#1}::operator()(double*, int, int, bool) const |
263 | 0 | auto dragReadDataInBorder = [&dragReadDataInBorderSimple]( |
264 | 0 | T *adfElevData, gdal::Vector2i dOutOfBorder, |
265 | 0 | int nKernelSize) -> void |
266 | 0 | { |
267 | 0 | dragReadDataInBorderSimple(adfElevData, dOutOfBorder.x(), nKernelSize, |
268 | 0 | true); |
269 | 0 | dragReadDataInBorderSimple(adfElevData, dOutOfBorder.y(), nKernelSize, |
270 | 0 | false); |
271 | 0 | }; Unexecuted instantiation: GDALInterpolateAtPointImpl<std::__1::complex<double> >(GDALRasterBand*, GDALRIOResampleAlg, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, double, double, std::__1::complex<double>&)::{lambda(std::__1::complex<double>*, gdal::VectorX<int, 2ul>, int)#1}::operator()(std::__1::complex<double>*, gdal::VectorX<int, 2ul>, int) const Unexecuted instantiation: GDALInterpolateAtPointImpl<double>(GDALRasterBand*, GDALRIOResampleAlg, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, double, double, double&)::{lambda(double*, gdal::VectorX<int, 2ul>, int)#1}::operator()(double*, gdal::VectorX<int, 2ul>, int) const |
272 | |
|
273 | 0 | auto applyBilinearKernel = [&](gdal::Vector2d dfDelta, T *adfValues, |
274 | 0 | T &pdfRes) -> bool |
275 | 0 | { |
276 | 0 | if (bGotNoDataValue) |
277 | 0 | { |
278 | | // TODO: We could perhaps use a valid sample if there's one. |
279 | 0 | bool bFoundNoDataElev = false; |
280 | 0 | for (int k_i = 0; k_i < 4; k_i++) |
281 | 0 | { |
282 | 0 | if (areEqualReal(dfNoDataValue, adfValues[k_i])) |
283 | 0 | bFoundNoDataElev = true; |
284 | 0 | } |
285 | 0 | if (bFoundNoDataElev) |
286 | 0 | { |
287 | 0 | return FALSE; |
288 | 0 | } |
289 | 0 | } |
290 | 0 | const gdal::Vector2d dfDelta1 = 1.0 - dfDelta; |
291 | |
|
292 | 0 | const T dfXZ1 = |
293 | 0 | adfValues[0] * dfDelta1.x() + adfValues[1] * dfDelta.x(); |
294 | 0 | const T dfXZ2 = |
295 | 0 | adfValues[2] * dfDelta1.x() + adfValues[3] * dfDelta.x(); |
296 | 0 | const T dfYZ = dfXZ1 * dfDelta1.y() + dfXZ2 * dfDelta.y(); |
297 | |
|
298 | 0 | pdfRes = dfYZ; |
299 | 0 | return TRUE; |
300 | 0 | }; Unexecuted instantiation: GDALInterpolateAtPointImpl<std::__1::complex<double> >(GDALRasterBand*, GDALRIOResampleAlg, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, double, double, std::__1::complex<double>&)::{lambda(gdal::VectorX<double, 2ul>, std::__1::complex<double>*, std::__1::complex<double>&)#1}::operator()(gdal::VectorX<double, 2ul>, std::__1::complex<double>*, std::__1::complex<double>&) const Unexecuted instantiation: GDALInterpolateAtPointImpl<double>(GDALRasterBand*, GDALRIOResampleAlg, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, double, double, double&)::{lambda(gdal::VectorX<double, 2ul>, double*, double&)#1}::operator()(gdal::VectorX<double, 2ul>, double*, double&) const |
301 | |
|
302 | 0 | auto apply4x4Kernel = [&](gdal::Vector2d dfDelta, T *adfValues, |
303 | 0 | T &pdfRes) -> bool |
304 | 0 | { |
305 | 0 | T dfSumH = 0.0; |
306 | 0 | T dfSumWeight = 0.0; |
307 | 0 | for (int k_i = 0; k_i < 4; k_i++) |
308 | 0 | { |
309 | | // Loop across the X axis. |
310 | 0 | for (int k_j = 0; k_j < 4; k_j++) |
311 | 0 | { |
312 | | // Calculate the weight for the specified pixel according |
313 | | // to the bicubic b-spline kernel we're using for |
314 | | // interpolation. |
315 | 0 | const gdal::Vector2i dKernInd = {k_j - 1, k_i - 1}; |
316 | 0 | const gdal::Vector2d fPoint = dKernInd.cast<double>() - dfDelta; |
317 | 0 | const double dfPixelWeight = |
318 | 0 | eResampleAlg == GDALRIOResampleAlg::GRIORA_CubicSpline |
319 | 0 | ? CubicSplineKernel(fPoint.x()) * |
320 | 0 | CubicSplineKernel(fPoint.y()) |
321 | 0 | : CubicKernel(fPoint.x()) * CubicKernel(fPoint.y()); |
322 | | |
323 | | // Create a sum of all values |
324 | | // adjusted for the pixel's calculated weight. |
325 | 0 | const T dfElev = adfValues[k_j + k_i * 4]; |
326 | 0 | if (bGotNoDataValue && areEqualReal(dfNoDataValue, dfElev)) |
327 | 0 | continue; |
328 | | |
329 | 0 | dfSumH += dfElev * dfPixelWeight; |
330 | 0 | dfSumWeight += dfPixelWeight; |
331 | 0 | } |
332 | 0 | } |
333 | 0 | if (dfSumWeight == 0.0) |
334 | 0 | { |
335 | 0 | return FALSE; |
336 | 0 | } |
337 | | |
338 | 0 | pdfRes = dfSumH / dfSumWeight; |
339 | |
|
340 | 0 | return TRUE; |
341 | 0 | }; Unexecuted instantiation: GDALInterpolateAtPointImpl<std::__1::complex<double> >(GDALRasterBand*, GDALRIOResampleAlg, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, double, double, std::__1::complex<double>&)::{lambda(gdal::VectorX<double, 2ul>, std::__1::complex<double>*, std::__1::complex<double>&)#2}::operator()(gdal::VectorX<double, 2ul>, std::__1::complex<double>*, std::__1::complex<double>&) const Unexecuted instantiation: GDALInterpolateAtPointImpl<double>(GDALRasterBand*, GDALRIOResampleAlg, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, double, double, double&)::{lambda(gdal::VectorX<double, 2ul>, double*, double&)#2}::operator()(gdal::VectorX<double, 2ul>, double*, double&) const |
342 | |
|
343 | 0 | if (eResampleAlg == GDALRIOResampleAlg::GRIORA_CubicSpline || |
344 | 0 | eResampleAlg == GDALRIOResampleAlg::GRIORA_Cubic) |
345 | 0 | { |
346 | | // Convert from upper left corner of pixel coordinates to center of |
347 | | // pixel coordinates: |
348 | 0 | const gdal::Vector2d df = inLoc - 0.5; |
349 | 0 | const gdal::Vector2i d = df.floor().template cast<int>(); |
350 | 0 | const gdal::Vector2d delta = df - d.cast<double>(); |
351 | 0 | const gdal::Vector2i dNew = d - 1; |
352 | 0 | const int nKernelSize = 4; |
353 | 0 | const gdal::Vector2i dOutOfBorder = |
354 | 0 | outOfBorderCorrection(dNew, nKernelSize); |
355 | | |
356 | | // CubicSpline interpolation. |
357 | 0 | T adfReadData[16] = {0.0}; |
358 | 0 | if (!GDALInterpExtractValuesWindow(pBand, cache, dNew - dOutOfBorder, |
359 | 0 | {nKernelSize, nKernelSize}, |
360 | 0 | adfReadData)) |
361 | 0 | { |
362 | 0 | return FALSE; |
363 | 0 | } |
364 | 0 | dragReadDataInBorder(adfReadData, dOutOfBorder, nKernelSize); |
365 | 0 | if (!apply4x4Kernel(delta, adfReadData, out)) |
366 | 0 | return FALSE; |
367 | | |
368 | 0 | return TRUE; |
369 | 0 | } |
370 | 0 | else if (eResampleAlg == GDALRIOResampleAlg::GRIORA_Bilinear) |
371 | 0 | { |
372 | | // Convert from upper left corner of pixel coordinates to center of |
373 | | // pixel coordinates: |
374 | 0 | const gdal::Vector2d df = inLoc - 0.5; |
375 | 0 | const gdal::Vector2i d = df.floor().template cast<int>(); |
376 | 0 | const gdal::Vector2d delta = df - d.cast<double>(); |
377 | 0 | const int nKernelSize = 2; |
378 | 0 | const gdal::Vector2i dOutOfBorder = |
379 | 0 | outOfBorderCorrection(d, nKernelSize); |
380 | | |
381 | | // Bilinear interpolation. |
382 | 0 | T adfReadData[4] = {0.0}; |
383 | 0 | if (!GDALInterpExtractValuesWindow(pBand, cache, d - dOutOfBorder, |
384 | 0 | {nKernelSize, nKernelSize}, |
385 | 0 | adfReadData)) |
386 | 0 | { |
387 | 0 | return FALSE; |
388 | 0 | } |
389 | 0 | dragReadDataInBorder(adfReadData, dOutOfBorder, nKernelSize); |
390 | 0 | if (!applyBilinearKernel(delta, adfReadData, out)) |
391 | 0 | return FALSE; |
392 | | |
393 | 0 | return TRUE; |
394 | 0 | } |
395 | 0 | else |
396 | 0 | { |
397 | 0 | const gdal::Vector2i d = inLoc.cast<int>(); |
398 | 0 | T adfOut[1] = {}; |
399 | 0 | if (!GDALInterpExtractValuesWindow(pBand, cache, d, {1, 1}, adfOut) || |
400 | 0 | (bGotNoDataValue && areEqualReal(dfNoDataValue, adfOut[0]))) |
401 | 0 | { |
402 | 0 | return FALSE; |
403 | 0 | } |
404 | | |
405 | 0 | out = adfOut[0]; |
406 | |
|
407 | 0 | return TRUE; |
408 | 0 | } |
409 | 0 | } Unexecuted instantiation: bool GDALInterpolateAtPointImpl<std::__1::complex<double> >(GDALRasterBand*, GDALRIOResampleAlg, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, double, double, std::__1::complex<double>&) Unexecuted instantiation: bool GDALInterpolateAtPointImpl<double>(GDALRasterBand*, GDALRIOResampleAlg, std::__1::unique_ptr<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > >, std::__1::default_delete<lru11::Cache<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > >, lru11::NullLock, std::__1::unordered_map<unsigned long, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*>, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::__list_iterator<lru11::KeyValuePair<unsigned long, std::__1::shared_ptr<std::__1::vector<double, std::__1::allocator<double> > > >, void*> > > > > > >&, double, double, double&) |
410 | | |
411 | | /************************************************************************/ |
412 | | /* GDALInterpolateAtPoint() */ |
413 | | /************************************************************************/ |
414 | | |
415 | | bool GDALInterpolateAtPoint(GDALRasterBand *pBand, |
416 | | GDALRIOResampleAlg eResampleAlg, |
417 | | std::unique_ptr<DoublePointsCache> &cache, |
418 | | const double dfXIn, const double dfYIn, |
419 | | double *pdfOutputReal, double *pdfOutputImag) |
420 | 0 | { |
421 | 0 | const bool bIsComplex = |
422 | 0 | CPL_TO_BOOL(GDALDataTypeIsComplex(pBand->GetRasterDataType())); |
423 | 0 | bool res = TRUE; |
424 | 0 | if (bIsComplex) |
425 | 0 | { |
426 | 0 | std::complex<double> out{}; |
427 | 0 | res = GDALInterpolateAtPointImpl(pBand, eResampleAlg, cache, dfXIn, |
428 | 0 | dfYIn, out); |
429 | 0 | *pdfOutputReal = out.real(); |
430 | 0 | if (pdfOutputImag) |
431 | 0 | *pdfOutputImag = out.imag(); |
432 | 0 | } |
433 | 0 | else |
434 | 0 | { |
435 | 0 | double out{}; |
436 | 0 | res = GDALInterpolateAtPointImpl(pBand, eResampleAlg, cache, dfXIn, |
437 | 0 | dfYIn, out); |
438 | 0 | *pdfOutputReal = out; |
439 | 0 | if (pdfOutputImag) |
440 | 0 | *pdfOutputImag = 0; |
441 | 0 | } |
442 | 0 | return res; |
443 | 0 | } |