Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL
4 : * Purpose: Implementation of a set of GDALDerivedPixelFunc(s) to be used
5 : * with source raster band of virtual GDAL datasets.
6 : * Author: Antonio Valentino <antonio.valentino@tiscali.it>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2008-2014,2022 Antonio Valentino <antonio.valentino@tiscali.it>
10 : *
11 : * SPDX-License-Identifier: MIT
12 : *****************************************************************************/
13 :
14 : #include <cmath>
15 : #include "gdal.h"
16 : #include "vrtdataset.h"
17 :
18 : #include <limits>
19 :
20 : template <typename T>
21 88487 : inline double GetSrcVal(const void *pSource, GDALDataType eSrcType, T ii)
22 : {
23 88487 : switch (eSrcType)
24 : {
25 0 : case GDT_Unknown:
26 0 : return 0;
27 32950 : case GDT_Byte:
28 32950 : return static_cast<const GByte *>(pSource)[ii];
29 0 : case GDT_Int8:
30 0 : return static_cast<const GInt8 *>(pSource)[ii];
31 0 : case GDT_UInt16:
32 0 : return static_cast<const GUInt16 *>(pSource)[ii];
33 0 : case GDT_Int16:
34 0 : return static_cast<const GInt16 *>(pSource)[ii];
35 0 : case GDT_UInt32:
36 0 : return static_cast<const GUInt32 *>(pSource)[ii];
37 400 : case GDT_Int32:
38 400 : return static_cast<const GInt32 *>(pSource)[ii];
39 : // Precision loss currently for int64/uint64
40 0 : case GDT_UInt64:
41 : return static_cast<double>(
42 0 : static_cast<const uint64_t *>(pSource)[ii]);
43 0 : case GDT_Int64:
44 : return static_cast<double>(
45 0 : static_cast<const int64_t *>(pSource)[ii]);
46 8636 : case GDT_Float32:
47 8636 : return static_cast<const float *>(pSource)[ii];
48 8231 : case GDT_Float64:
49 8231 : return static_cast<const double *>(pSource)[ii];
50 360 : case GDT_CInt16:
51 360 : return static_cast<const GInt16 *>(pSource)[2 * ii];
52 0 : case GDT_CInt32:
53 0 : return static_cast<const GInt32 *>(pSource)[2 * ii];
54 4660 : case GDT_CFloat32:
55 4660 : return static_cast<const float *>(pSource)[2 * ii];
56 33250 : case GDT_CFloat64:
57 33250 : return static_cast<const double *>(pSource)[2 * ii];
58 0 : case GDT_TypeCount:
59 0 : break;
60 : }
61 0 : return 0;
62 : }
63 :
64 57 : static CPLErr FetchDoubleArg(CSLConstList papszArgs, const char *pszName,
65 : double *pdfX, double *pdfDefault = nullptr)
66 : {
67 57 : const char *pszVal = CSLFetchNameValue(papszArgs, pszName);
68 :
69 57 : if (pszVal == nullptr)
70 : {
71 15 : if (pdfDefault == nullptr)
72 : {
73 0 : CPLError(CE_Failure, CPLE_AppDefined,
74 : "Missing pixel function argument: %s", pszName);
75 0 : return CE_Failure;
76 : }
77 : else
78 : {
79 15 : *pdfX = *pdfDefault;
80 15 : return CE_None;
81 : }
82 : }
83 :
84 42 : char *pszEnd = nullptr;
85 42 : *pdfX = std::strtod(pszVal, &pszEnd);
86 42 : if (pszEnd == pszVal)
87 : {
88 0 : CPLError(CE_Failure, CPLE_AppDefined,
89 : "Failed to parse pixel function argument: %s", pszName);
90 0 : return CE_Failure;
91 : }
92 :
93 42 : return CE_None;
94 : }
95 :
96 6 : static CPLErr RealPixelFunc(void **papoSources, int nSources, void *pData,
97 : int nXSize, int nYSize, GDALDataType eSrcType,
98 : GDALDataType eBufType, int nPixelSpace,
99 : int nLineSpace)
100 : {
101 : /* ---- Init ---- */
102 6 : if (nSources != 1)
103 1 : return CE_Failure;
104 :
105 5 : const int nPixelSpaceSrc = GDALGetDataTypeSizeBytes(eSrcType);
106 5 : const size_t nLineSpaceSrc = static_cast<size_t>(nPixelSpaceSrc) * nXSize;
107 :
108 : /* ---- Set pixels ---- */
109 77 : for (int iLine = 0; iLine < nYSize; ++iLine)
110 : {
111 72 : GDALCopyWords(static_cast<GByte *>(papoSources[0]) +
112 72 : nLineSpaceSrc * iLine,
113 : eSrcType, nPixelSpaceSrc,
114 : static_cast<GByte *>(pData) +
115 72 : static_cast<GSpacing>(nLineSpace) * iLine,
116 : eBufType, nPixelSpace, nXSize);
117 : }
118 :
119 : /* ---- Return success ---- */
120 5 : return CE_None;
121 : } // RealPixelFunc
122 :
123 8 : static CPLErr ImagPixelFunc(void **papoSources, int nSources, void *pData,
124 : int nXSize, int nYSize, GDALDataType eSrcType,
125 : GDALDataType eBufType, int nPixelSpace,
126 : int nLineSpace)
127 : {
128 : /* ---- Init ---- */
129 8 : if (nSources != 1)
130 1 : return CE_Failure;
131 :
132 7 : if (GDALDataTypeIsComplex(eSrcType))
133 : {
134 6 : const GDALDataType eSrcBaseType = GDALGetNonComplexDataType(eSrcType);
135 6 : const int nPixelSpaceSrc = GDALGetDataTypeSizeBytes(eSrcType);
136 6 : const size_t nLineSpaceSrc =
137 6 : static_cast<size_t>(nPixelSpaceSrc) * nXSize;
138 :
139 6 : const void *const pImag = static_cast<GByte *>(papoSources[0]) +
140 6 : GDALGetDataTypeSizeBytes(eSrcType) / 2;
141 :
142 : /* ---- Set pixels ---- */
143 56 : for (int iLine = 0; iLine < nYSize; ++iLine)
144 : {
145 50 : GDALCopyWords(static_cast<const GByte *>(pImag) +
146 50 : nLineSpaceSrc * iLine,
147 : eSrcBaseType, nPixelSpaceSrc,
148 : static_cast<GByte *>(pData) +
149 50 : static_cast<GSpacing>(nLineSpace) * iLine,
150 : eBufType, nPixelSpace, nXSize);
151 : }
152 : }
153 : else
154 : {
155 1 : const double dfImag = 0;
156 :
157 : /* ---- Set pixels ---- */
158 21 : for (int iLine = 0; iLine < nYSize; ++iLine)
159 : {
160 : // Always copy from the same location.
161 20 : GDALCopyWords(&dfImag, eSrcType, 0,
162 : static_cast<GByte *>(pData) +
163 20 : static_cast<GSpacing>(nLineSpace) * iLine,
164 : eBufType, nPixelSpace, nXSize);
165 : }
166 : }
167 :
168 : /* ---- Return success ---- */
169 7 : return CE_None;
170 : } // ImagPixelFunc
171 :
172 6 : static CPLErr ComplexPixelFunc(void **papoSources, int nSources, void *pData,
173 : int nXSize, int nYSize, GDALDataType eSrcType,
174 : GDALDataType eBufType, int nPixelSpace,
175 : int nLineSpace)
176 : {
177 : /* ---- Init ---- */
178 6 : if (nSources != 2)
179 1 : return CE_Failure;
180 :
181 5 : const void *const pReal = papoSources[0];
182 5 : const void *const pImag = papoSources[1];
183 :
184 : /* ---- Set pixels ---- */
185 5 : size_t ii = 0;
186 281 : for (int iLine = 0; iLine < nYSize; ++iLine)
187 : {
188 17060 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
189 : {
190 : // Source raster pixels may be obtained with GetSrcVal macro.
191 : const double adfPixVal[2] = {
192 16784 : GetSrcVal(pReal, eSrcType, ii), // re
193 16784 : GetSrcVal(pImag, eSrcType, ii) // im
194 16784 : };
195 :
196 16784 : GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
197 : static_cast<GByte *>(pData) +
198 16784 : static_cast<GSpacing>(nLineSpace) * iLine +
199 16784 : iCol * nPixelSpace,
200 : eBufType, nPixelSpace, 1);
201 : }
202 : }
203 :
204 : /* ---- Return success ---- */
205 5 : return CE_None;
206 : } // ComplexPixelFunc
207 :
208 : typedef enum
209 : {
210 : GAT_amplitude,
211 : GAT_intensity,
212 : GAT_dB
213 : } PolarAmplitudeType;
214 :
215 : static const char pszPolarPixelFuncMetadata[] =
216 : "<PixelFunctionArgumentsList>"
217 : " <Argument name='amplitude_type' description='Amplitude Type' "
218 : "type='string-select' default='AMPLITUDE'>"
219 : " <Value>INTENSITY</Value>"
220 : " <Value>dB</Value>"
221 : " <Value>AMPLITUDE</Value>"
222 : " </Argument>"
223 : "</PixelFunctionArgumentsList>";
224 :
225 4 : static CPLErr PolarPixelFunc(void **papoSources, int nSources, void *pData,
226 : int nXSize, int nYSize, GDALDataType eSrcType,
227 : GDALDataType eBufType, int nPixelSpace,
228 : int nLineSpace, CSLConstList papszArgs)
229 : {
230 : /* ---- Init ---- */
231 4 : if (nSources != 2)
232 0 : return CE_Failure;
233 :
234 4 : const char pszName[] = "amplitude_type";
235 4 : const char *pszVal = CSLFetchNameValue(papszArgs, pszName);
236 4 : PolarAmplitudeType amplitudeType = GAT_amplitude;
237 4 : if (pszVal != nullptr)
238 : {
239 3 : if (strcmp(pszVal, "INTENSITY") == 0)
240 1 : amplitudeType = GAT_intensity;
241 2 : else if (strcmp(pszVal, "dB") == 0)
242 1 : amplitudeType = GAT_dB;
243 1 : else if (strcmp(pszVal, "AMPLITUDE") != 0)
244 : {
245 0 : CPLError(CE_Failure, CPLE_AppDefined,
246 : "Invalid value for pixel function argument '%s': %s",
247 : pszName, pszVal);
248 0 : return CE_Failure;
249 : }
250 : }
251 :
252 4 : const void *const pAmp = papoSources[0];
253 4 : const void *const pPhase = papoSources[1];
254 :
255 : /* ---- Set pixels ---- */
256 4 : size_t ii = 0;
257 84 : for (int iLine = 0; iLine < nYSize; ++iLine)
258 : {
259 1680 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
260 : {
261 : // Source raster pixels may be obtained with GetSrcVal macro.
262 1600 : double dfAmp = GetSrcVal(pAmp, eSrcType, ii);
263 1600 : switch (amplitudeType)
264 : {
265 400 : case GAT_intensity:
266 : // clip to zero
267 400 : dfAmp = dfAmp <= 0 ? 0 : std::sqrt(dfAmp);
268 400 : break;
269 400 : case GAT_dB:
270 400 : dfAmp = dfAmp <= 0
271 400 : ? -std::numeric_limits<double>::infinity()
272 400 : : pow(10, dfAmp / 20.);
273 400 : break;
274 800 : case GAT_amplitude:
275 800 : break;
276 : }
277 1600 : const double dfPhase = GetSrcVal(pPhase, eSrcType, ii);
278 : const double adfPixVal[2] = {
279 1600 : dfAmp * std::cos(dfPhase), // re
280 1600 : dfAmp * std::sin(dfPhase) // im
281 1600 : };
282 :
283 1600 : GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
284 : static_cast<GByte *>(pData) +
285 1600 : static_cast<GSpacing>(nLineSpace) * iLine +
286 1600 : iCol * nPixelSpace,
287 : eBufType, nPixelSpace, 1);
288 : }
289 : }
290 :
291 : /* ---- Return success ---- */
292 4 : return CE_None;
293 : } // PolarPixelFunc
294 :
295 4 : static CPLErr ModulePixelFunc(void **papoSources, int nSources, void *pData,
296 : int nXSize, int nYSize, GDALDataType eSrcType,
297 : GDALDataType eBufType, int nPixelSpace,
298 : int nLineSpace)
299 : {
300 : /* ---- Init ---- */
301 4 : if (nSources != 1)
302 1 : return CE_Failure;
303 :
304 3 : if (GDALDataTypeIsComplex(eSrcType))
305 : {
306 2 : const void *pReal = papoSources[0];
307 2 : const void *pImag = static_cast<GByte *>(papoSources[0]) +
308 2 : GDALGetDataTypeSizeBytes(eSrcType) / 2;
309 :
310 : /* ---- Set pixels ---- */
311 2 : size_t ii = 0;
312 14 : for (int iLine = 0; iLine < nYSize; ++iLine)
313 : {
314 72 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
315 : {
316 : // Source raster pixels may be obtained with GetSrcVal macro.
317 60 : const double dfReal = GetSrcVal(pReal, eSrcType, ii);
318 60 : const double dfImag = GetSrcVal(pImag, eSrcType, ii);
319 :
320 60 : const double dfPixVal = sqrt(dfReal * dfReal + dfImag * dfImag);
321 :
322 60 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
323 : static_cast<GByte *>(pData) +
324 60 : static_cast<GSpacing>(nLineSpace) * iLine +
325 60 : iCol * nPixelSpace,
326 : eBufType, nPixelSpace, 1);
327 : }
328 : }
329 : }
330 : else
331 : {
332 : /* ---- Set pixels ---- */
333 1 : size_t ii = 0;
334 21 : for (int iLine = 0; iLine < nYSize; ++iLine)
335 : {
336 420 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
337 : {
338 : // Source raster pixels may be obtained with GetSrcVal macro.
339 : const double dfPixVal =
340 400 : fabs(GetSrcVal(papoSources[0], eSrcType, ii));
341 :
342 400 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
343 : static_cast<GByte *>(pData) +
344 400 : static_cast<GSpacing>(nLineSpace) * iLine +
345 400 : iCol * nPixelSpace,
346 : eBufType, nPixelSpace, 1);
347 : }
348 : }
349 : }
350 :
351 : /* ---- Return success ---- */
352 3 : return CE_None;
353 : } // ModulePixelFunc
354 :
355 5 : static CPLErr PhasePixelFunc(void **papoSources, int nSources, void *pData,
356 : int nXSize, int nYSize, GDALDataType eSrcType,
357 : GDALDataType eBufType, int nPixelSpace,
358 : int nLineSpace)
359 : {
360 : /* ---- Init ---- */
361 5 : if (nSources != 1)
362 1 : return CE_Failure;
363 :
364 4 : if (GDALDataTypeIsComplex(eSrcType))
365 : {
366 2 : const void *const pReal = papoSources[0];
367 2 : const void *const pImag = static_cast<GByte *>(papoSources[0]) +
368 2 : GDALGetDataTypeSizeBytes(eSrcType) / 2;
369 :
370 : /* ---- Set pixels ---- */
371 2 : size_t ii = 0;
372 14 : for (int iLine = 0; iLine < nYSize; ++iLine)
373 : {
374 72 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
375 : {
376 : // Source raster pixels may be obtained with GetSrcVal macro.
377 60 : const double dfReal = GetSrcVal(pReal, eSrcType, ii);
378 60 : const double dfImag = GetSrcVal(pImag, eSrcType, ii);
379 :
380 60 : const double dfPixVal = atan2(dfImag, dfReal);
381 :
382 60 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
383 : static_cast<GByte *>(pData) +
384 60 : static_cast<GSpacing>(nLineSpace) * iLine +
385 60 : iCol * nPixelSpace,
386 : eBufType, nPixelSpace, 1);
387 : }
388 : }
389 : }
390 2 : else if (GDALDataTypeIsInteger(eSrcType) && !GDALDataTypeIsSigned(eSrcType))
391 : {
392 1 : constexpr double dfZero = 0;
393 7 : for (int iLine = 0; iLine < nYSize; ++iLine)
394 : {
395 6 : GDALCopyWords(&dfZero, GDT_Float64, 0,
396 : static_cast<GByte *>(pData) +
397 6 : static_cast<GSpacing>(nLineSpace) * iLine,
398 : eBufType, nPixelSpace, nXSize);
399 : }
400 : }
401 : else
402 : {
403 : /* ---- Set pixels ---- */
404 1 : size_t ii = 0;
405 7 : for (int iLine = 0; iLine < nYSize; ++iLine)
406 : {
407 36 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
408 : {
409 30 : const void *const pReal = papoSources[0];
410 :
411 : // Source raster pixels may be obtained with GetSrcVal macro.
412 30 : const double dfReal = GetSrcVal(pReal, eSrcType, ii);
413 30 : const double dfPixVal = (dfReal < 0) ? M_PI : 0.0;
414 :
415 30 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
416 : static_cast<GByte *>(pData) +
417 30 : static_cast<GSpacing>(nLineSpace) * iLine +
418 30 : iCol * nPixelSpace,
419 : eBufType, nPixelSpace, 1);
420 : }
421 : }
422 : }
423 :
424 : /* ---- Return success ---- */
425 4 : return CE_None;
426 : } // PhasePixelFunc
427 :
428 4 : static CPLErr ConjPixelFunc(void **papoSources, int nSources, void *pData,
429 : int nXSize, int nYSize, GDALDataType eSrcType,
430 : GDALDataType eBufType, int nPixelSpace,
431 : int nLineSpace)
432 : {
433 : /* ---- Init ---- */
434 4 : if (nSources != 1)
435 1 : return CE_Failure;
436 :
437 3 : if (GDALDataTypeIsComplex(eSrcType) && GDALDataTypeIsComplex(eBufType))
438 : {
439 2 : const int nOffset = GDALGetDataTypeSizeBytes(eSrcType) / 2;
440 2 : const void *const pReal = papoSources[0];
441 2 : const void *const pImag =
442 2 : static_cast<GByte *>(papoSources[0]) + nOffset;
443 :
444 : /* ---- Set pixels ---- */
445 2 : size_t ii = 0;
446 14 : for (int iLine = 0; iLine < nYSize; ++iLine)
447 : {
448 72 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
449 : {
450 : // Source raster pixels may be obtained with GetSrcVal macro.
451 : const double adfPixVal[2] = {
452 60 : +GetSrcVal(pReal, eSrcType, ii), // re
453 120 : -GetSrcVal(pImag, eSrcType, ii) // im
454 60 : };
455 :
456 60 : GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
457 : static_cast<GByte *>(pData) +
458 60 : static_cast<GSpacing>(nLineSpace) * iLine +
459 60 : iCol * nPixelSpace,
460 : eBufType, nPixelSpace, 1);
461 : }
462 : }
463 : }
464 : else
465 : {
466 : // No complex data type.
467 1 : return RealPixelFunc(papoSources, nSources, pData, nXSize, nYSize,
468 1 : eSrcType, eBufType, nPixelSpace, nLineSpace);
469 : }
470 :
471 : /* ---- Return success ---- */
472 2 : return CE_None;
473 : } // ConjPixelFunc
474 :
475 : static const char pszSumPixelFuncMetadata[] =
476 : "<PixelFunctionArgumentsList>"
477 : " <Argument name='k' description='Optional constant term' type='double' "
478 : "default='0.0' />"
479 : "</PixelFunctionArgumentsList>";
480 :
481 4 : static CPLErr SumPixelFunc(void **papoSources, int nSources, void *pData,
482 : int nXSize, int nYSize, GDALDataType eSrcType,
483 : GDALDataType eBufType, int nPixelSpace,
484 : int nLineSpace, CSLConstList papszArgs)
485 : {
486 : /* ---- Init ---- */
487 4 : if (nSources < 2)
488 1 : return CE_Failure;
489 :
490 3 : double dfK = 0.0;
491 3 : if (FetchDoubleArg(papszArgs, "k", &dfK, &dfK) != CE_None)
492 0 : return CE_Failure;
493 :
494 : /* ---- Set pixels ---- */
495 3 : if (GDALDataTypeIsComplex(eSrcType))
496 : {
497 1 : const int nOffset = GDALGetDataTypeSizeBytes(eSrcType) / 2;
498 :
499 : /* ---- Set pixels ---- */
500 1 : size_t ii = 0;
501 7 : for (int iLine = 0; iLine < nYSize; ++iLine)
502 : {
503 36 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
504 : {
505 30 : double adfSum[2] = {dfK, 0.0};
506 :
507 120 : for (int iSrc = 0; iSrc < nSources; ++iSrc)
508 : {
509 90 : const void *const pReal = papoSources[iSrc];
510 90 : const void *const pImag =
511 90 : static_cast<const GByte *>(pReal) + nOffset;
512 :
513 : // Source raster pixels may be obtained with GetSrcVal
514 : // macro.
515 90 : adfSum[0] += GetSrcVal(pReal, eSrcType, ii);
516 90 : adfSum[1] += GetSrcVal(pImag, eSrcType, ii);
517 : }
518 :
519 30 : GDALCopyWords(adfSum, GDT_CFloat64, 0,
520 : static_cast<GByte *>(pData) +
521 30 : static_cast<GSpacing>(nLineSpace) * iLine +
522 30 : iCol * nPixelSpace,
523 : eBufType, nPixelSpace, 1);
524 : }
525 : }
526 : }
527 : else
528 : {
529 : /* ---- Set pixels ---- */
530 2 : size_t ii = 0;
531 42 : for (int iLine = 0; iLine < nYSize; ++iLine)
532 : {
533 840 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
534 : {
535 800 : double dfSum = dfK; // Not complex.
536 :
537 3200 : for (int iSrc = 0; iSrc < nSources; ++iSrc)
538 : {
539 : // Source raster pixels may be obtained with GetSrcVal
540 : // macro.
541 2400 : dfSum += GetSrcVal(papoSources[iSrc], eSrcType, ii);
542 : }
543 :
544 800 : GDALCopyWords(&dfSum, GDT_Float64, 0,
545 : static_cast<GByte *>(pData) +
546 800 : static_cast<GSpacing>(nLineSpace) * iLine +
547 800 : iCol * nPixelSpace,
548 : eBufType, nPixelSpace, 1);
549 : }
550 : }
551 : }
552 :
553 : /* ---- Return success ---- */
554 3 : return CE_None;
555 : } /* SumPixelFunc */
556 :
557 3 : static CPLErr DiffPixelFunc(void **papoSources, int nSources, void *pData,
558 : int nXSize, int nYSize, GDALDataType eSrcType,
559 : GDALDataType eBufType, int nPixelSpace,
560 : int nLineSpace)
561 : {
562 : /* ---- Init ---- */
563 3 : if (nSources != 2)
564 1 : return CE_Failure;
565 :
566 2 : if (GDALDataTypeIsComplex(eSrcType))
567 : {
568 1 : const int nOffset = GDALGetDataTypeSizeBytes(eSrcType) / 2;
569 1 : const void *const pReal0 = papoSources[0];
570 1 : const void *const pImag0 =
571 1 : static_cast<GByte *>(papoSources[0]) + nOffset;
572 1 : const void *const pReal1 = papoSources[1];
573 1 : const void *const pImag1 =
574 1 : static_cast<GByte *>(papoSources[1]) + nOffset;
575 :
576 : /* ---- Set pixels ---- */
577 1 : size_t ii = 0;
578 7 : for (int iLine = 0; iLine < nYSize; ++iLine)
579 : {
580 36 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
581 : {
582 : // Source raster pixels may be obtained with GetSrcVal macro.
583 30 : double adfPixVal[2] = {GetSrcVal(pReal0, eSrcType, ii) -
584 30 : GetSrcVal(pReal1, eSrcType, ii),
585 60 : GetSrcVal(pImag0, eSrcType, ii) -
586 30 : GetSrcVal(pImag1, eSrcType, ii)};
587 :
588 30 : GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
589 : static_cast<GByte *>(pData) +
590 30 : static_cast<GSpacing>(nLineSpace) * iLine +
591 30 : iCol * nPixelSpace,
592 : eBufType, nPixelSpace, 1);
593 : }
594 : }
595 : }
596 : else
597 : {
598 : /* ---- Set pixels ---- */
599 1 : size_t ii = 0;
600 7 : for (int iLine = 0; iLine < nYSize; ++iLine)
601 : {
602 36 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
603 : {
604 : // Source raster pixels may be obtained with GetSrcVal macro.
605 : // Not complex.
606 : const double dfPixVal =
607 30 : GetSrcVal(papoSources[0], eSrcType, ii) -
608 30 : GetSrcVal(papoSources[1], eSrcType, ii);
609 :
610 30 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
611 : static_cast<GByte *>(pData) +
612 30 : static_cast<GSpacing>(nLineSpace) * iLine +
613 30 : iCol * nPixelSpace,
614 : eBufType, nPixelSpace, 1);
615 : }
616 : }
617 : }
618 :
619 : /* ---- Return success ---- */
620 2 : return CE_None;
621 : } // DiffPixelFunc
622 :
623 : static const char pszMulPixelFuncMetadata[] =
624 : "<PixelFunctionArgumentsList>"
625 : " <Argument name='k' description='Optional constant factor' "
626 : "type='double' default='1.0' />"
627 : "</PixelFunctionArgumentsList>";
628 :
629 4 : static CPLErr MulPixelFunc(void **papoSources, int nSources, void *pData,
630 : int nXSize, int nYSize, GDALDataType eSrcType,
631 : GDALDataType eBufType, int nPixelSpace,
632 : int nLineSpace, CSLConstList papszArgs)
633 : {
634 : /* ---- Init ---- */
635 4 : if (nSources < 2)
636 1 : return CE_Failure;
637 :
638 3 : double dfK = 1.0;
639 3 : if (FetchDoubleArg(papszArgs, "k", &dfK, &dfK) != CE_None)
640 0 : return CE_Failure;
641 :
642 : /* ---- Set pixels ---- */
643 3 : if (GDALDataTypeIsComplex(eSrcType))
644 : {
645 1 : const int nOffset = GDALGetDataTypeSizeBytes(eSrcType) / 2;
646 :
647 : /* ---- Set pixels ---- */
648 1 : size_t ii = 0;
649 7 : for (int iLine = 0; iLine < nYSize; ++iLine)
650 : {
651 36 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
652 : {
653 30 : double adfPixVal[2] = {dfK, 0.0};
654 :
655 90 : for (int iSrc = 0; iSrc < nSources; ++iSrc)
656 : {
657 60 : const void *const pReal = papoSources[iSrc];
658 60 : const void *const pImag =
659 60 : static_cast<const GByte *>(pReal) + nOffset;
660 :
661 60 : const double dfOldR = adfPixVal[0];
662 60 : const double dfOldI = adfPixVal[1];
663 :
664 : // Source raster pixels may be obtained with GetSrcVal
665 : // macro.
666 60 : const double dfNewR = GetSrcVal(pReal, eSrcType, ii);
667 60 : const double dfNewI = GetSrcVal(pImag, eSrcType, ii);
668 :
669 60 : adfPixVal[0] = dfOldR * dfNewR - dfOldI * dfNewI;
670 60 : adfPixVal[1] = dfOldR * dfNewI + dfOldI * dfNewR;
671 : }
672 :
673 30 : GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
674 : static_cast<GByte *>(pData) +
675 30 : static_cast<GSpacing>(nLineSpace) * iLine +
676 30 : iCol * nPixelSpace,
677 : eBufType, nPixelSpace, 1);
678 : }
679 : }
680 : }
681 : else
682 : {
683 : /* ---- Set pixels ---- */
684 2 : size_t ii = 0;
685 42 : for (int iLine = 0; iLine < nYSize; ++iLine)
686 : {
687 840 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
688 : {
689 800 : double dfPixVal = dfK; // Not complex.
690 :
691 3200 : for (int iSrc = 0; iSrc < nSources; ++iSrc)
692 : {
693 : // Source raster pixels may be obtained with GetSrcVal
694 : // macro.
695 2400 : dfPixVal *= GetSrcVal(papoSources[iSrc], eSrcType, ii);
696 : }
697 :
698 800 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
699 : static_cast<GByte *>(pData) +
700 800 : static_cast<GSpacing>(nLineSpace) * iLine +
701 800 : iCol * nPixelSpace,
702 : eBufType, nPixelSpace, 1);
703 : }
704 : }
705 : }
706 :
707 : /* ---- Return success ---- */
708 3 : return CE_None;
709 : } // MulPixelFunc
710 :
711 2 : static CPLErr DivPixelFunc(void **papoSources, int nSources, void *pData,
712 : int nXSize, int nYSize, GDALDataType eSrcType,
713 : GDALDataType eBufType, int nPixelSpace,
714 : int nLineSpace)
715 : {
716 : /* ---- Init ---- */
717 2 : if (nSources != 2)
718 0 : return CE_Failure;
719 :
720 : /* ---- Set pixels ---- */
721 2 : if (GDALDataTypeIsComplex(eSrcType))
722 : {
723 1 : const int nOffset = GDALGetDataTypeSizeBytes(eSrcType) / 2;
724 1 : const void *const pReal0 = papoSources[0];
725 1 : const void *const pImag0 =
726 1 : static_cast<GByte *>(papoSources[0]) + nOffset;
727 1 : const void *const pReal1 = papoSources[1];
728 1 : const void *const pImag1 =
729 1 : static_cast<GByte *>(papoSources[1]) + nOffset;
730 :
731 : /* ---- Set pixels ---- */
732 1 : size_t ii = 0;
733 7 : for (int iLine = 0; iLine < nYSize; ++iLine)
734 : {
735 36 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
736 : {
737 : // Source raster pixels may be obtained with GetSrcVal macro.
738 30 : const double dfReal0 = GetSrcVal(pReal0, eSrcType, ii);
739 30 : const double dfReal1 = GetSrcVal(pReal1, eSrcType, ii);
740 30 : const double dfImag0 = GetSrcVal(pImag0, eSrcType, ii);
741 30 : const double dfImag1 = GetSrcVal(pImag1, eSrcType, ii);
742 30 : const double dfAux = dfReal1 * dfReal1 + dfImag1 * dfImag1;
743 :
744 : const double adfPixVal[2] = {
745 : dfAux == 0
746 30 : ? std::numeric_limits<double>::infinity()
747 30 : : dfReal0 * dfReal1 / dfAux + dfImag0 * dfImag1 / dfAux,
748 0 : dfAux == 0 ? std::numeric_limits<double>::infinity()
749 30 : : dfReal1 / dfAux * dfImag0 -
750 30 : dfReal0 * dfImag1 / dfAux};
751 :
752 30 : GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
753 : static_cast<GByte *>(pData) +
754 30 : static_cast<GSpacing>(nLineSpace) * iLine +
755 30 : iCol * nPixelSpace,
756 : eBufType, nPixelSpace, 1);
757 : }
758 : }
759 : }
760 : else
761 : {
762 : /* ---- Set pixels ---- */
763 1 : size_t ii = 0;
764 7 : for (int iLine = 0; iLine < nYSize; ++iLine)
765 : {
766 36 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
767 : {
768 30 : const double dfVal = GetSrcVal(papoSources[1], eSrcType, ii);
769 : double dfPixVal =
770 : dfVal == 0
771 60 : ? std::numeric_limits<double>::infinity()
772 30 : : GetSrcVal(papoSources[0], eSrcType, ii) / dfVal;
773 :
774 30 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
775 : static_cast<GByte *>(pData) +
776 30 : static_cast<GSpacing>(nLineSpace) * iLine +
777 30 : iCol * nPixelSpace,
778 : eBufType, nPixelSpace, 1);
779 : }
780 : }
781 : }
782 :
783 : /* ---- Return success ---- */
784 2 : return CE_None;
785 : } // DivPixelFunc
786 :
787 3 : static CPLErr CMulPixelFunc(void **papoSources, int nSources, void *pData,
788 : int nXSize, int nYSize, GDALDataType eSrcType,
789 : GDALDataType eBufType, int nPixelSpace,
790 : int nLineSpace)
791 : {
792 : /* ---- Init ---- */
793 3 : if (nSources != 2)
794 1 : return CE_Failure;
795 :
796 : /* ---- Set pixels ---- */
797 2 : if (GDALDataTypeIsComplex(eSrcType))
798 : {
799 1 : const int nOffset = GDALGetDataTypeSizeBytes(eSrcType) / 2;
800 1 : const void *const pReal0 = papoSources[0];
801 1 : const void *const pImag0 =
802 1 : static_cast<GByte *>(papoSources[0]) + nOffset;
803 1 : const void *const pReal1 = papoSources[1];
804 1 : const void *const pImag1 =
805 1 : static_cast<GByte *>(papoSources[1]) + nOffset;
806 :
807 1 : size_t ii = 0;
808 7 : for (int iLine = 0; iLine < nYSize; ++iLine)
809 : {
810 36 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
811 : {
812 : // Source raster pixels may be obtained with GetSrcVal macro.
813 30 : const double dfReal0 = GetSrcVal(pReal0, eSrcType, ii);
814 30 : const double dfReal1 = GetSrcVal(pReal1, eSrcType, ii);
815 30 : const double dfImag0 = GetSrcVal(pImag0, eSrcType, ii);
816 30 : const double dfImag1 = GetSrcVal(pImag1, eSrcType, ii);
817 : const double adfPixVal[2] = {
818 30 : dfReal0 * dfReal1 + dfImag0 * dfImag1,
819 30 : dfReal1 * dfImag0 - dfReal0 * dfImag1};
820 :
821 30 : GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
822 : static_cast<GByte *>(pData) +
823 30 : static_cast<GSpacing>(nLineSpace) * iLine +
824 30 : iCol * nPixelSpace,
825 : eBufType, nPixelSpace, 1);
826 : }
827 : }
828 : }
829 : else
830 : {
831 1 : size_t ii = 0;
832 21 : for (int iLine = 0; iLine < nYSize; ++iLine)
833 : {
834 420 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
835 : {
836 : // Source raster pixels may be obtained with GetSrcVal macro.
837 : // Not complex.
838 400 : const double adfPixVal[2] = {
839 400 : GetSrcVal(papoSources[0], eSrcType, ii) *
840 400 : GetSrcVal(papoSources[1], eSrcType, ii),
841 400 : 0.0};
842 :
843 400 : GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
844 : static_cast<GByte *>(pData) +
845 400 : static_cast<GSpacing>(nLineSpace) * iLine +
846 400 : iCol * nPixelSpace,
847 : eBufType, nPixelSpace, 1);
848 : }
849 : }
850 : }
851 :
852 : /* ---- Return success ---- */
853 2 : return CE_None;
854 : } // CMulPixelFunc
855 :
856 : static const char pszInvPixelFuncMetadata[] =
857 : "<PixelFunctionArgumentsList>"
858 : " <Argument name='k' description='Optional constant factor' "
859 : "type='double' default='1.0' />"
860 : "</PixelFunctionArgumentsList>";
861 :
862 6 : static CPLErr InvPixelFunc(void **papoSources, int nSources, void *pData,
863 : int nXSize, int nYSize, GDALDataType eSrcType,
864 : GDALDataType eBufType, int nPixelSpace,
865 : int nLineSpace, CSLConstList papszArgs)
866 : {
867 : /* ---- Init ---- */
868 6 : if (nSources != 1)
869 1 : return CE_Failure;
870 :
871 5 : double dfK = 1.0;
872 5 : if (FetchDoubleArg(papszArgs, "k", &dfK, &dfK) != CE_None)
873 0 : return CE_Failure;
874 :
875 : /* ---- Set pixels ---- */
876 5 : if (GDALDataTypeIsComplex(eSrcType))
877 : {
878 2 : const int nOffset = GDALGetDataTypeSizeBytes(eSrcType) / 2;
879 2 : const void *const pReal = papoSources[0];
880 2 : const void *const pImag =
881 2 : static_cast<GByte *>(papoSources[0]) + nOffset;
882 :
883 2 : size_t ii = 0;
884 9 : for (int iLine = 0; iLine < nYSize; ++iLine)
885 : {
886 38 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
887 : {
888 : // Source raster pixels may be obtained with GetSrcVal macro.
889 31 : const double dfReal = GetSrcVal(pReal, eSrcType, ii);
890 31 : const double dfImag = GetSrcVal(pImag, eSrcType, ii);
891 31 : const double dfAux = dfReal * dfReal + dfImag * dfImag;
892 : const double adfPixVal[2] = {
893 31 : dfAux == 0 ? std::numeric_limits<double>::infinity()
894 30 : : dfK * dfReal / dfAux,
895 1 : dfAux == 0 ? std::numeric_limits<double>::infinity()
896 31 : : -dfK * dfImag / dfAux};
897 :
898 31 : GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
899 : static_cast<GByte *>(pData) +
900 31 : static_cast<GSpacing>(nLineSpace) * iLine +
901 31 : iCol * nPixelSpace,
902 : eBufType, nPixelSpace, 1);
903 : }
904 : }
905 : }
906 : else
907 : {
908 : /* ---- Set pixels ---- */
909 3 : size_t ii = 0;
910 44 : for (int iLine = 0; iLine < nYSize; ++iLine)
911 : {
912 842 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
913 : {
914 : // Source raster pixels may be obtained with GetSrcVal macro.
915 : // Not complex.
916 801 : const double dfVal = GetSrcVal(papoSources[0], eSrcType, ii);
917 : const double dfPixVal =
918 801 : dfVal == 0 ? std::numeric_limits<double>::infinity()
919 800 : : dfK / dfVal;
920 :
921 801 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
922 : static_cast<GByte *>(pData) +
923 801 : static_cast<GSpacing>(nLineSpace) * iLine +
924 801 : iCol * nPixelSpace,
925 : eBufType, nPixelSpace, 1);
926 : }
927 : }
928 : }
929 :
930 : /* ---- Return success ---- */
931 5 : return CE_None;
932 : } // InvPixelFunc
933 :
934 4 : static CPLErr IntensityPixelFunc(void **papoSources, int nSources, void *pData,
935 : int nXSize, int nYSize, GDALDataType eSrcType,
936 : GDALDataType eBufType, int nPixelSpace,
937 : int nLineSpace)
938 : {
939 : /* ---- Init ---- */
940 4 : if (nSources != 1)
941 1 : return CE_Failure;
942 :
943 3 : if (GDALDataTypeIsComplex(eSrcType))
944 : {
945 2 : const int nOffset = GDALGetDataTypeSizeBytes(eSrcType) / 2;
946 2 : const void *const pReal = papoSources[0];
947 2 : const void *const pImag =
948 2 : static_cast<GByte *>(papoSources[0]) + nOffset;
949 :
950 : /* ---- Set pixels ---- */
951 2 : size_t ii = 0;
952 14 : for (int iLine = 0; iLine < nYSize; ++iLine)
953 : {
954 72 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
955 : {
956 : // Source raster pixels may be obtained with GetSrcVal macro.
957 60 : const double dfReal = GetSrcVal(pReal, eSrcType, ii);
958 60 : const double dfImag = GetSrcVal(pImag, eSrcType, ii);
959 :
960 60 : const double dfPixVal = dfReal * dfReal + dfImag * dfImag;
961 :
962 60 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
963 : static_cast<GByte *>(pData) +
964 60 : static_cast<GSpacing>(nLineSpace) * iLine +
965 60 : iCol * nPixelSpace,
966 : eBufType, nPixelSpace, 1);
967 : }
968 : }
969 : }
970 : else
971 : {
972 : /* ---- Set pixels ---- */
973 1 : size_t ii = 0;
974 21 : for (int iLine = 0; iLine < nYSize; ++iLine)
975 : {
976 420 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
977 : {
978 : // Source raster pixels may be obtained with GetSrcVal macro.
979 400 : double dfPixVal = GetSrcVal(papoSources[0], eSrcType, ii);
980 400 : dfPixVal *= dfPixVal;
981 :
982 400 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
983 : static_cast<GByte *>(pData) +
984 400 : static_cast<GSpacing>(nLineSpace) * iLine +
985 400 : iCol * nPixelSpace,
986 : eBufType, nPixelSpace, 1);
987 : }
988 : }
989 : }
990 :
991 : /* ---- Return success ---- */
992 3 : return CE_None;
993 : } // IntensityPixelFunc
994 :
995 2 : static CPLErr SqrtPixelFunc(void **papoSources, int nSources, void *pData,
996 : int nXSize, int nYSize, GDALDataType eSrcType,
997 : GDALDataType eBufType, int nPixelSpace,
998 : int nLineSpace)
999 : {
1000 : /* ---- Init ---- */
1001 2 : if (nSources != 1)
1002 1 : return CE_Failure;
1003 1 : if (GDALDataTypeIsComplex(eSrcType))
1004 0 : return CE_Failure;
1005 :
1006 : /* ---- Set pixels ---- */
1007 1 : size_t ii = 0;
1008 21 : for (int iLine = 0; iLine < nYSize; ++iLine)
1009 : {
1010 420 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
1011 : {
1012 : // Source raster pixels may be obtained with GetSrcVal macro.
1013 : const double dfPixVal =
1014 400 : sqrt(GetSrcVal(papoSources[0], eSrcType, ii));
1015 :
1016 400 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
1017 : static_cast<GByte *>(pData) +
1018 400 : static_cast<GSpacing>(nLineSpace) * iLine +
1019 400 : iCol * nPixelSpace,
1020 : eBufType, nPixelSpace, 1);
1021 : }
1022 : }
1023 :
1024 : /* ---- Return success ---- */
1025 1 : return CE_None;
1026 : } // SqrtPixelFunc
1027 :
1028 11 : static CPLErr Log10PixelFuncHelper(void **papoSources, int nSources,
1029 : void *pData, int nXSize, int nYSize,
1030 : GDALDataType eSrcType, GDALDataType eBufType,
1031 : int nPixelSpace, int nLineSpace, double fact)
1032 : {
1033 : /* ---- Init ---- */
1034 11 : if (nSources != 1)
1035 2 : return CE_Failure;
1036 :
1037 9 : if (GDALDataTypeIsComplex(eSrcType))
1038 : {
1039 : // Complex input datatype.
1040 5 : const int nOffset = GDALGetDataTypeSizeBytes(eSrcType) / 2;
1041 5 : const void *const pReal = papoSources[0];
1042 5 : const void *const pImag =
1043 5 : static_cast<GByte *>(papoSources[0]) + nOffset;
1044 :
1045 : /* We should compute fact * log10( sqrt( dfReal * dfReal + dfImag *
1046 : * dfImag ) ) */
1047 : /* Given that log10(sqrt(x)) = 0.5 * log10(x) */
1048 : /* we can remove the sqrt() by multiplying fact by 0.5 */
1049 5 : fact *= 0.5;
1050 :
1051 : /* ---- Set pixels ---- */
1052 5 : size_t ii = 0;
1053 35 : for (int iLine = 0; iLine < nYSize; ++iLine)
1054 : {
1055 180 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
1056 : {
1057 : // Source raster pixels may be obtained with GetSrcVal macro.
1058 150 : const double dfReal = GetSrcVal(pReal, eSrcType, ii);
1059 150 : const double dfImag = GetSrcVal(pImag, eSrcType, ii);
1060 :
1061 : const double dfPixVal =
1062 150 : fact * log10(dfReal * dfReal + dfImag * dfImag);
1063 :
1064 150 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
1065 : static_cast<GByte *>(pData) +
1066 150 : static_cast<GSpacing>(nLineSpace) * iLine +
1067 150 : iCol * nPixelSpace,
1068 : eBufType, nPixelSpace, 1);
1069 : }
1070 : }
1071 : }
1072 : else
1073 : {
1074 : /* ---- Set pixels ---- */
1075 4 : size_t ii = 0;
1076 84 : for (int iLine = 0; iLine < nYSize; ++iLine)
1077 : {
1078 1680 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
1079 : {
1080 : // Source raster pixels may be obtained with GetSrcVal macro.
1081 : const double dfPixVal =
1082 1600 : fact * log10(fabs(GetSrcVal(papoSources[0], eSrcType, ii)));
1083 :
1084 1600 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
1085 : static_cast<GByte *>(pData) +
1086 1600 : static_cast<GSpacing>(nLineSpace) * iLine +
1087 1600 : iCol * nPixelSpace,
1088 : eBufType, nPixelSpace, 1);
1089 : }
1090 : }
1091 : }
1092 :
1093 : /* ---- Return success ---- */
1094 9 : return CE_None;
1095 : } // Log10PixelFuncHelper
1096 :
1097 4 : static CPLErr Log10PixelFunc(void **papoSources, int nSources, void *pData,
1098 : int nXSize, int nYSize, GDALDataType eSrcType,
1099 : GDALDataType eBufType, int nPixelSpace,
1100 : int nLineSpace)
1101 : {
1102 4 : return Log10PixelFuncHelper(papoSources, nSources, pData, nXSize, nYSize,
1103 : eSrcType, eBufType, nPixelSpace, nLineSpace,
1104 4 : 1.0);
1105 : } // Log10PixelFunc
1106 :
1107 : static const char pszDBPixelFuncMetadata[] =
1108 : "<PixelFunctionArgumentsList>"
1109 : " <Argument name='fact' description='Factor' type='double' "
1110 : "default='20.0' />"
1111 : "</PixelFunctionArgumentsList>";
1112 :
1113 7 : static CPLErr DBPixelFunc(void **papoSources, int nSources, void *pData,
1114 : int nXSize, int nYSize, GDALDataType eSrcType,
1115 : GDALDataType eBufType, int nPixelSpace,
1116 : int nLineSpace, CSLConstList papszArgs)
1117 : {
1118 7 : double dfFact = 20.;
1119 7 : if (FetchDoubleArg(papszArgs, "fact", &dfFact, &dfFact) != CE_None)
1120 0 : return CE_Failure;
1121 :
1122 7 : return Log10PixelFuncHelper(papoSources, nSources, pData, nXSize, nYSize,
1123 : eSrcType, eBufType, nPixelSpace, nLineSpace,
1124 7 : dfFact);
1125 : } // DBPixelFunc
1126 :
1127 7 : static CPLErr ExpPixelFuncHelper(void **papoSources, int nSources, void *pData,
1128 : int nXSize, int nYSize, GDALDataType eSrcType,
1129 : GDALDataType eBufType, int nPixelSpace,
1130 : int nLineSpace, double base, double fact)
1131 : {
1132 : /* ---- Init ---- */
1133 7 : if (nSources != 1)
1134 2 : return CE_Failure;
1135 5 : if (GDALDataTypeIsComplex(eSrcType))
1136 0 : return CE_Failure;
1137 :
1138 : /* ---- Set pixels ---- */
1139 5 : size_t ii = 0;
1140 105 : for (int iLine = 0; iLine < nYSize; ++iLine)
1141 : {
1142 2100 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
1143 : {
1144 : // Source raster pixels may be obtained with GetSrcVal macro.
1145 : const double dfPixVal =
1146 2000 : pow(base, GetSrcVal(papoSources[0], eSrcType, ii) * fact);
1147 :
1148 2000 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
1149 : static_cast<GByte *>(pData) +
1150 2000 : static_cast<GSpacing>(nLineSpace) * iLine +
1151 2000 : iCol * nPixelSpace,
1152 : eBufType, nPixelSpace, 1);
1153 : }
1154 : }
1155 :
1156 : /* ---- Return success ---- */
1157 5 : return CE_None;
1158 : } // ExpPixelFuncHelper
1159 :
1160 : static const char pszExpPixelFuncMetadata[] =
1161 : "<PixelFunctionArgumentsList>"
1162 : " <Argument name='base' description='Base' type='double' "
1163 : "default='2.7182818284590452353602874713526624' />"
1164 : " <Argument name='fact' description='Factor' type='double' default='1' />"
1165 : "</PixelFunctionArgumentsList>";
1166 :
1167 3 : static CPLErr ExpPixelFunc(void **papoSources, int nSources, void *pData,
1168 : int nXSize, int nYSize, GDALDataType eSrcType,
1169 : GDALDataType eBufType, int nPixelSpace,
1170 : int nLineSpace, CSLConstList papszArgs)
1171 : {
1172 3 : double dfBase = 2.7182818284590452353602874713526624;
1173 3 : double dfFact = 1.;
1174 :
1175 3 : if (FetchDoubleArg(papszArgs, "base", &dfBase, &dfBase) != CE_None)
1176 0 : return CE_Failure;
1177 :
1178 3 : if (FetchDoubleArg(papszArgs, "fact", &dfFact, &dfFact) != CE_None)
1179 0 : return CE_Failure;
1180 :
1181 3 : return ExpPixelFuncHelper(papoSources, nSources, pData, nXSize, nYSize,
1182 : eSrcType, eBufType, nPixelSpace, nLineSpace,
1183 3 : dfBase, dfFact);
1184 : } // ExpPixelFunc
1185 :
1186 2 : static CPLErr dB2AmpPixelFunc(void **papoSources, int nSources, void *pData,
1187 : int nXSize, int nYSize, GDALDataType eSrcType,
1188 : GDALDataType eBufType, int nPixelSpace,
1189 : int nLineSpace)
1190 : {
1191 2 : return ExpPixelFuncHelper(papoSources, nSources, pData, nXSize, nYSize,
1192 : eSrcType, eBufType, nPixelSpace, nLineSpace, 10.0,
1193 2 : 1. / 20);
1194 : } // dB2AmpPixelFunc
1195 :
1196 2 : static CPLErr dB2PowPixelFunc(void **papoSources, int nSources, void *pData,
1197 : int nXSize, int nYSize, GDALDataType eSrcType,
1198 : GDALDataType eBufType, int nPixelSpace,
1199 : int nLineSpace)
1200 : {
1201 2 : return ExpPixelFuncHelper(papoSources, nSources, pData, nXSize, nYSize,
1202 : eSrcType, eBufType, nPixelSpace, nLineSpace, 10.0,
1203 2 : 1. / 10);
1204 : } // dB2PowPixelFunc
1205 :
1206 : static const char pszPowPixelFuncMetadata[] =
1207 : "<PixelFunctionArgumentsList>"
1208 : " <Argument name='power' description='Exponent' type='double' "
1209 : "mandatory='1' />"
1210 : "</PixelFunctionArgumentsList>";
1211 :
1212 1 : static CPLErr PowPixelFunc(void **papoSources, int nSources, void *pData,
1213 : int nXSize, int nYSize, GDALDataType eSrcType,
1214 : GDALDataType eBufType, int nPixelSpace,
1215 : int nLineSpace, CSLConstList papszArgs)
1216 : {
1217 : /* ---- Init ---- */
1218 1 : if (nSources != 1)
1219 0 : return CE_Failure;
1220 1 : if (GDALDataTypeIsComplex(eSrcType))
1221 0 : return CE_Failure;
1222 :
1223 : double power;
1224 1 : if (FetchDoubleArg(papszArgs, "power", &power) != CE_None)
1225 0 : return CE_Failure;
1226 :
1227 : /* ---- Set pixels ---- */
1228 1 : size_t ii = 0;
1229 21 : for (int iLine = 0; iLine < nYSize; ++iLine)
1230 : {
1231 420 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
1232 : {
1233 : const double dfPixVal =
1234 400 : std::pow(GetSrcVal(papoSources[0], eSrcType, ii), power);
1235 :
1236 400 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
1237 : static_cast<GByte *>(pData) +
1238 400 : static_cast<GSpacing>(nLineSpace) * iLine +
1239 400 : iCol * nPixelSpace,
1240 : eBufType, nPixelSpace, 1);
1241 : }
1242 : }
1243 :
1244 : /* ---- Return success ---- */
1245 1 : return CE_None;
1246 : }
1247 :
1248 : // Given nt intervals spaced by dt and beginning at t0, return the index of
1249 : // the lower bound of the interval that should be used to
1250 : // interpolate/extrapolate a value for t.
1251 7 : static std::size_t intervalLeft(double t0, double dt, std::size_t nt, double t)
1252 : {
1253 7 : if (t < t0)
1254 : {
1255 2 : return 0;
1256 : }
1257 :
1258 5 : std::size_t n = static_cast<std::size_t>((t - t0) / dt);
1259 :
1260 5 : if (n >= nt - 1)
1261 : {
1262 3 : return nt - 2;
1263 : }
1264 :
1265 2 : return n;
1266 : }
1267 :
1268 16 : static double InterpolateLinear(double dfX0, double dfX1, double dfY0,
1269 : double dfY1, double dfX)
1270 : {
1271 16 : return dfY0 + (dfX - dfX0) * (dfY1 - dfY0) / (dfX1 - dfX0);
1272 : }
1273 :
1274 12 : static double InterpolateExponential(double dfX0, double dfX1, double dfY0,
1275 : double dfY1, double dfX)
1276 : {
1277 12 : const double r = std::log(dfY1 / dfY0) / (dfX1 - dfX0);
1278 12 : return dfY0 * std::exp(r * (dfX - dfX0));
1279 : }
1280 :
1281 : static const char pszInterpolatePixelFuncMetadata[] =
1282 : "<PixelFunctionArgumentsList>"
1283 : " <Argument name='t0' description='t0' type='double' mandatory='1' />"
1284 : " <Argument name='dt' description='dt' type='double' mandatory='1' />"
1285 : " <Argument name='t' description='t' type='double' mandatory='1' />"
1286 : "</PixelFunctionArgumentsList>";
1287 :
1288 : template <decltype(InterpolateLinear) InterpolationFunction>
1289 7 : CPLErr InterpolatePixelFunc(void **papoSources, int nSources, void *pData,
1290 : int nXSize, int nYSize, GDALDataType eSrcType,
1291 : GDALDataType eBufType, int nPixelSpace,
1292 : int nLineSpace, CSLConstList papszArgs)
1293 : {
1294 : /* ---- Init ---- */
1295 7 : if (GDALDataTypeIsComplex(eSrcType))
1296 0 : return CE_Failure;
1297 :
1298 : double dfT0;
1299 7 : if (FetchDoubleArg(papszArgs, "t0", &dfT0) == CE_Failure)
1300 0 : return CE_Failure;
1301 :
1302 : double dfT;
1303 7 : if (FetchDoubleArg(papszArgs, "t", &dfT) == CE_Failure)
1304 0 : return CE_Failure;
1305 :
1306 : double dfDt;
1307 7 : if (FetchDoubleArg(papszArgs, "dt", &dfDt) == CE_Failure)
1308 0 : return CE_Failure;
1309 :
1310 7 : if (nSources < 2)
1311 : {
1312 0 : CPLError(CE_Failure, CPLE_AppDefined,
1313 : "At least two sources required for interpolation.");
1314 0 : return CE_Failure;
1315 : }
1316 :
1317 7 : if (dfT == 0 || !std::isfinite(dfT))
1318 : {
1319 0 : CPLError(CE_Failure, CPLE_AppDefined, "dt must be finite and non-zero");
1320 0 : return CE_Failure;
1321 : }
1322 :
1323 7 : const auto i0 = intervalLeft(dfT0, dfDt, nSources, dfT);
1324 7 : const auto i1 = i0 + 1;
1325 7 : dfT0 = dfT0 + static_cast<double>(i0) * dfDt;
1326 7 : double dfX1 = dfT0 + dfDt;
1327 :
1328 : /* ---- Set pixels ---- */
1329 7 : size_t ii = 0;
1330 21 : for (int iLine = 0; iLine < nYSize; ++iLine)
1331 : {
1332 42 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
1333 : {
1334 28 : const double dfY0 = GetSrcVal(papoSources[i0], eSrcType, ii);
1335 28 : const double dfY1 = GetSrcVal(papoSources[i1], eSrcType, ii);
1336 :
1337 28 : const double dfPixVal =
1338 28 : InterpolationFunction(dfT0, dfX1, dfY0, dfY1, dfT);
1339 :
1340 28 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
1341 : static_cast<GByte *>(pData) +
1342 28 : static_cast<GSpacing>(nLineSpace) * iLine +
1343 28 : iCol * nPixelSpace,
1344 : eBufType, nPixelSpace, 1);
1345 : }
1346 : }
1347 :
1348 : /* ---- Return success ---- */
1349 7 : return CE_None;
1350 : }
1351 :
1352 : static const char pszReplaceNoDataPixelFuncMetadata[] =
1353 : "<PixelFunctionArgumentsList>"
1354 : " <Argument type='builtin' value='NoData' />"
1355 : " <Argument name='to' type='double' description='New NoData value to be "
1356 : "replaced' default='nan' />"
1357 : "</PixelFunctionArgumentsList>";
1358 :
1359 2 : static CPLErr ReplaceNoDataPixelFunc(void **papoSources, int nSources,
1360 : void *pData, int nXSize, int nYSize,
1361 : GDALDataType eSrcType,
1362 : GDALDataType eBufType, int nPixelSpace,
1363 : int nLineSpace, CSLConstList papszArgs)
1364 : {
1365 : /* ---- Init ---- */
1366 2 : if (nSources != 1)
1367 0 : return CE_Failure;
1368 2 : if (GDALDataTypeIsComplex(eSrcType))
1369 : {
1370 0 : CPLError(CE_Failure, CPLE_AppDefined,
1371 : "replace_nodata cannot convert complex data types");
1372 0 : return CE_Failure;
1373 : }
1374 :
1375 2 : double dfOldNoData, dfNewNoData = NAN;
1376 2 : if (FetchDoubleArg(papszArgs, "NoData", &dfOldNoData) != CE_None)
1377 0 : return CE_Failure;
1378 2 : if (FetchDoubleArg(papszArgs, "to", &dfNewNoData, &dfNewNoData) != CE_None)
1379 0 : return CE_Failure;
1380 :
1381 2 : if (!GDALDataTypeIsFloating(eBufType) && std::isnan(dfNewNoData))
1382 : {
1383 0 : CPLError(CE_Failure, CPLE_AppDefined,
1384 : "Using nan requires a floating point type output buffer");
1385 0 : return CE_Failure;
1386 : }
1387 :
1388 : /* ---- Set pixels ---- */
1389 2 : size_t ii = 0;
1390 102 : for (int iLine = 0; iLine < nYSize; ++iLine)
1391 : {
1392 5100 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
1393 : {
1394 5000 : double dfPixVal = GetSrcVal(papoSources[0], eSrcType, ii);
1395 5000 : if (dfPixVal == dfOldNoData || std::isnan(dfPixVal))
1396 3200 : dfPixVal = dfNewNoData;
1397 :
1398 5000 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
1399 : static_cast<GByte *>(pData) +
1400 5000 : static_cast<GSpacing>(nLineSpace) * iLine +
1401 5000 : iCol * nPixelSpace,
1402 : eBufType, nPixelSpace, 1);
1403 : }
1404 : }
1405 :
1406 : /* ---- Return success ---- */
1407 2 : return CE_None;
1408 : }
1409 :
1410 : static const char pszScalePixelFuncMetadata[] =
1411 : "<PixelFunctionArgumentsList>"
1412 : " <Argument type='builtin' value='offset' />"
1413 : " <Argument type='builtin' value='scale' />"
1414 : "</PixelFunctionArgumentsList>";
1415 :
1416 1 : static CPLErr ScalePixelFunc(void **papoSources, int nSources, void *pData,
1417 : int nXSize, int nYSize, GDALDataType eSrcType,
1418 : GDALDataType eBufType, int nPixelSpace,
1419 : int nLineSpace, CSLConstList papszArgs)
1420 : {
1421 : /* ---- Init ---- */
1422 1 : if (nSources != 1)
1423 0 : return CE_Failure;
1424 1 : if (GDALDataTypeIsComplex(eSrcType))
1425 : {
1426 0 : CPLError(CE_Failure, CPLE_AppDefined,
1427 : "scale cannot by applied to complex data types");
1428 0 : return CE_Failure;
1429 : }
1430 :
1431 : double dfScale, dfOffset;
1432 1 : if (FetchDoubleArg(papszArgs, "scale", &dfScale) != CE_None)
1433 0 : return CE_Failure;
1434 1 : if (FetchDoubleArg(papszArgs, "offset", &dfOffset) != CE_None)
1435 0 : return CE_Failure;
1436 :
1437 : /* ---- Set pixels ---- */
1438 1 : size_t ii = 0;
1439 21 : for (int iLine = 0; iLine < nYSize; ++iLine)
1440 : {
1441 420 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
1442 : {
1443 : const double dfPixVal =
1444 400 : GetSrcVal(papoSources[0], eSrcType, ii) * dfScale + dfOffset;
1445 :
1446 400 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
1447 : static_cast<GByte *>(pData) +
1448 400 : static_cast<GSpacing>(nLineSpace) * iLine +
1449 400 : iCol * nPixelSpace,
1450 : eBufType, nPixelSpace, 1);
1451 : }
1452 : }
1453 :
1454 : /* ---- Return success ---- */
1455 1 : return CE_None;
1456 : }
1457 :
1458 1 : static CPLErr NormDiffPixelFunc(void **papoSources, int nSources, void *pData,
1459 : int nXSize, int nYSize, GDALDataType eSrcType,
1460 : GDALDataType eBufType, int nPixelSpace,
1461 : int nLineSpace)
1462 : {
1463 : /* ---- Init ---- */
1464 1 : if (nSources != 2)
1465 0 : return CE_Failure;
1466 :
1467 1 : if (GDALDataTypeIsComplex(eSrcType))
1468 : {
1469 0 : CPLError(CE_Failure, CPLE_AppDefined,
1470 : "norm_diff cannot by applied to complex data types");
1471 0 : return CE_Failure;
1472 : }
1473 :
1474 : /* ---- Set pixels ---- */
1475 1 : size_t ii = 0;
1476 7 : for (int iLine = 0; iLine < nYSize; ++iLine)
1477 : {
1478 36 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
1479 : {
1480 30 : const double dfLeftVal = GetSrcVal(papoSources[0], eSrcType, ii);
1481 30 : const double dfRightVal = GetSrcVal(papoSources[1], eSrcType, ii);
1482 :
1483 30 : const double dfDenom = (dfLeftVal + dfRightVal);
1484 :
1485 : const double dfPixVal =
1486 30 : dfDenom == 0 ? std::numeric_limits<double>::infinity()
1487 30 : : (dfLeftVal - dfRightVal) / dfDenom;
1488 :
1489 30 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
1490 : static_cast<GByte *>(pData) +
1491 30 : static_cast<GSpacing>(nLineSpace) * iLine +
1492 30 : iCol * nPixelSpace,
1493 : eBufType, nPixelSpace, 1);
1494 : }
1495 : }
1496 :
1497 : /* ---- Return success ---- */
1498 1 : return CE_None;
1499 : } // NormDiffPixelFunc
1500 :
1501 : /************************************************************************/
1502 : /* pszMinMaxFuncMetadataNodata */
1503 : /************************************************************************/
1504 :
1505 : static const char pszMinMaxFuncMetadataNodata[] =
1506 : "<PixelFunctionArgumentsList>"
1507 : " <Argument type='builtin' value='NoData' optional='true' />"
1508 : " <Argument name='propagateNoData' description='Whether the output value "
1509 : "should be NoData as as soon as one source is NoData' type='boolean' "
1510 : "default='false' />"
1511 : "</PixelFunctionArgumentsList>";
1512 :
1513 : template <class Comparator>
1514 5 : static CPLErr MinOrMaxPixelFunc(void **papoSources, int nSources, void *pData,
1515 : int nXSize, int nYSize, GDALDataType eSrcType,
1516 : GDALDataType eBufType, int nPixelSpace,
1517 : int nLineSpace, CSLConstList papszArgs)
1518 : {
1519 : /* ---- Init ---- */
1520 5 : if (nSources < 2)
1521 0 : return CE_Failure;
1522 :
1523 5 : if (GDALDataTypeIsComplex(eSrcType))
1524 : {
1525 0 : CPLError(CE_Failure, CPLE_AppDefined,
1526 : "Complex data type not supported for min/max().");
1527 0 : return CE_Failure;
1528 : }
1529 :
1530 5 : double dfNoData = std::numeric_limits<double>::quiet_NaN();
1531 5 : if (FetchDoubleArg(papszArgs, "NoData", &dfNoData, &dfNoData) != CE_None)
1532 0 : return CE_Failure;
1533 5 : const bool bPropagateNoData = CPLTestBool(
1534 : CSLFetchNameValueDef(papszArgs, "propagateNoData", "false"));
1535 :
1536 : /* ---- Set pixels ---- */
1537 5 : size_t ii = 0;
1538 255 : for (int iLine = 0; iLine < nYSize; ++iLine)
1539 : {
1540 12750 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
1541 : {
1542 12500 : double dfRes = std::numeric_limits<double>::quiet_NaN();
1543 :
1544 43400 : for (int iSrc = 0; iSrc < nSources; ++iSrc)
1545 : {
1546 32950 : const double dfVal = GetSrcVal(papoSources[iSrc], eSrcType, ii);
1547 :
1548 32950 : if (std::isnan(dfVal) || dfVal == dfNoData)
1549 : {
1550 14350 : if (bPropagateNoData)
1551 : {
1552 2050 : dfRes = dfNoData;
1553 2050 : break;
1554 : }
1555 : }
1556 18600 : else if (Comparator::compare(dfVal, dfRes))
1557 : {
1558 9950 : dfRes = dfVal;
1559 : }
1560 : }
1561 :
1562 12500 : if (!bPropagateNoData && std::isnan(dfRes))
1563 : {
1564 3200 : dfRes = dfNoData;
1565 : }
1566 :
1567 12500 : GDALCopyWords(&dfRes, GDT_Float64, 0,
1568 : static_cast<GByte *>(pData) +
1569 12500 : static_cast<GSpacing>(nLineSpace) * iLine +
1570 12500 : iCol * nPixelSpace,
1571 : eBufType, nPixelSpace, 1);
1572 : }
1573 : }
1574 :
1575 : /* ---- Return success ---- */
1576 5 : return CE_None;
1577 : } /* MinOrMaxPixelFunc */
1578 :
1579 2 : static CPLErr MinPixelFunc(void **papoSources, int nSources, void *pData,
1580 : int nXSize, int nYSize, GDALDataType eSrcType,
1581 : GDALDataType eBufType, int nPixelSpace,
1582 : int nLineSpace, CSLConstList papszArgs)
1583 : {
1584 : struct Comparator
1585 : {
1586 2700 : static bool compare(double x, double resVal)
1587 : {
1588 : // Written this way to deal with resVal being NaN
1589 2700 : return !(x >= resVal);
1590 : }
1591 : };
1592 :
1593 2 : return MinOrMaxPixelFunc<Comparator>(papoSources, nSources, pData, nXSize,
1594 : nYSize, eSrcType, eBufType,
1595 2 : nPixelSpace, nLineSpace, papszArgs);
1596 : }
1597 :
1598 3 : static CPLErr MaxPixelFunc(void **papoSources, int nSources, void *pData,
1599 : int nXSize, int nYSize, GDALDataType eSrcType,
1600 : GDALDataType eBufType, int nPixelSpace,
1601 : int nLineSpace, CSLConstList papszArgs)
1602 : {
1603 : struct Comparator
1604 : {
1605 15900 : static bool compare(double x, double resVal)
1606 : {
1607 : // Written this way to deal with resVal being NaN
1608 15900 : return !(x <= resVal);
1609 : }
1610 : };
1611 :
1612 3 : return MinOrMaxPixelFunc<Comparator>(papoSources, nSources, pData, nXSize,
1613 : nYSize, eSrcType, eBufType,
1614 3 : nPixelSpace, nLineSpace, papszArgs);
1615 : }
1616 :
1617 : /************************************************************************/
1618 : /* GDALRegisterDefaultPixelFunc() */
1619 : /************************************************************************/
1620 :
1621 : /**
1622 : * This adds a default set of pixel functions to the global list of
1623 : * available pixel functions for derived bands:
1624 : *
1625 : * - "real": extract real part from a single raster band (just a copy if the
1626 : * input is non-complex)
1627 : * - "imag": extract imaginary part from a single raster band (0 for
1628 : * non-complex)
1629 : * - "complex": make a complex band merging two bands used as real and
1630 : * imag values
1631 : * - "polar": make a complex band using input bands for amplitude and
1632 : * phase values (b1 * exp( j * b2 ))
1633 : * - "mod": extract module from a single raster band (real or complex)
1634 : * - "phase": extract phase from a single raster band [-PI,PI] (0 or PI for
1635 : non-complex)
1636 : * - "conj": computes the complex conjugate of a single raster band (just a
1637 : * copy if the input is non-complex)
1638 : * - "sum": sum 2 or more raster bands
1639 : * - "diff": computes the difference between 2 raster bands (b1 - b2)
1640 : * - "mul": multiply 2 or more raster bands
1641 : * - "div": divide one raster band by another (b1 / b2).
1642 : * - "min": minimum value of 2 or more raster bands
1643 : * - "max": maximum value of 2 or more raster bands
1644 : * - "norm_diff": computes the normalized difference between two raster bands:
1645 : * ``(b1 - b2)/(b1 + b2)``.
1646 : * - "cmul": multiply the first band for the complex conjugate of the second
1647 : * - "inv": inverse (1./x).
1648 : * - "intensity": computes the intensity Re(x*conj(x)) of a single raster band
1649 : * (real or complex)
1650 : * - "sqrt": perform the square root of a single raster band (real only)
1651 : * - "log10": compute the logarithm (base 10) of the abs of a single raster
1652 : * band (real or complex): log10( abs( x ) )
1653 : * - "dB": perform conversion to dB of the abs of a single raster
1654 : * band (real or complex): 20. * log10( abs( x ) ).
1655 : * Note: the optional fact parameter can be set to 10. to get the
1656 : * alternative formula: 10. * log10( abs( x ) )
1657 : * - "exp": computes the exponential of each element in the input band ``x``
1658 : * (of real values): ``e ^ x``.
1659 : * The function also accepts two optional parameters: ``base`` and
1660 : ``fact``
1661 : * that allow to compute the generalized formula: ``base ^ ( fact *
1662 : x)``.
1663 : * Note: this function is the recommended one to perform conversion
1664 : * form logarithmic scale (dB): `` 10. ^ (x / 20.)``, in this case
1665 : * ``base = 10.`` and ``fact = 1./20``
1666 : * - "dB2amp": perform scale conversion from logarithmic to linear
1667 : * (amplitude) (i.e. 10 ^ ( x / 20 ) ) of a single raster
1668 : * band (real only).
1669 : * Deprecated in GDAL v3.5. Please use the ``exp`` pixel function
1670 : with
1671 : * ``base = 10.`` and ``fact = 0.05`` i.e. ``1./20``
1672 : * - "dB2pow": perform scale conversion from logarithmic to linear
1673 : * (power) (i.e. 10 ^ ( x / 10 ) ) of a single raster
1674 : * band (real only)
1675 : * Deprecated in GDAL v3.5. Please use the ``exp`` pixel function
1676 : with
1677 : * ``base = 10.`` and ``fact = 0.1`` i.e. ``1./10``
1678 : * - "pow": raise a single raster band to a constant power
1679 : * - "interpolate_linear": interpolate values between two raster bands
1680 : * using linear interpolation
1681 : * - "interpolate_exp": interpolate values between two raster bands using
1682 : * exponential interpolation
1683 : * - "scale": Apply the RasterBand metadata values of "offset" and "scale"
1684 : * - "nan": Convert incoming NoData values to IEEE 754 nan
1685 : *
1686 : * @see GDALAddDerivedBandPixelFunc
1687 : *
1688 : * @return CE_None
1689 : */
1690 1292 : CPLErr GDALRegisterDefaultPixelFunc()
1691 : {
1692 1292 : GDALAddDerivedBandPixelFunc("real", RealPixelFunc);
1693 1292 : GDALAddDerivedBandPixelFunc("imag", ImagPixelFunc);
1694 1292 : GDALAddDerivedBandPixelFunc("complex", ComplexPixelFunc);
1695 1292 : GDALAddDerivedBandPixelFuncWithArgs("polar", PolarPixelFunc,
1696 : pszPolarPixelFuncMetadata);
1697 1292 : GDALAddDerivedBandPixelFunc("mod", ModulePixelFunc);
1698 1292 : GDALAddDerivedBandPixelFunc("phase", PhasePixelFunc);
1699 1292 : GDALAddDerivedBandPixelFunc("conj", ConjPixelFunc);
1700 1292 : GDALAddDerivedBandPixelFuncWithArgs("sum", SumPixelFunc,
1701 : pszSumPixelFuncMetadata);
1702 1292 : GDALAddDerivedBandPixelFunc("diff", DiffPixelFunc);
1703 1292 : GDALAddDerivedBandPixelFuncWithArgs("mul", MulPixelFunc,
1704 : pszMulPixelFuncMetadata);
1705 1292 : GDALAddDerivedBandPixelFunc("div", DivPixelFunc);
1706 1292 : GDALAddDerivedBandPixelFunc("cmul", CMulPixelFunc);
1707 1292 : GDALAddDerivedBandPixelFuncWithArgs("inv", InvPixelFunc,
1708 : pszInvPixelFuncMetadata);
1709 1292 : GDALAddDerivedBandPixelFunc("intensity", IntensityPixelFunc);
1710 1292 : GDALAddDerivedBandPixelFunc("sqrt", SqrtPixelFunc);
1711 1292 : GDALAddDerivedBandPixelFunc("log10", Log10PixelFunc);
1712 1292 : GDALAddDerivedBandPixelFuncWithArgs("dB", DBPixelFunc,
1713 : pszDBPixelFuncMetadata);
1714 1292 : GDALAddDerivedBandPixelFuncWithArgs("exp", ExpPixelFunc,
1715 : pszExpPixelFuncMetadata);
1716 1292 : GDALAddDerivedBandPixelFunc("dB2amp",
1717 : dB2AmpPixelFunc); // deprecated in v3.5
1718 1292 : GDALAddDerivedBandPixelFunc("dB2pow",
1719 : dB2PowPixelFunc); // deprecated in v3.5
1720 1292 : GDALAddDerivedBandPixelFuncWithArgs("pow", PowPixelFunc,
1721 : pszPowPixelFuncMetadata);
1722 1292 : GDALAddDerivedBandPixelFuncWithArgs("interpolate_linear",
1723 : InterpolatePixelFunc<InterpolateLinear>,
1724 : pszInterpolatePixelFuncMetadata);
1725 1292 : GDALAddDerivedBandPixelFuncWithArgs(
1726 : "interpolate_exp", InterpolatePixelFunc<InterpolateExponential>,
1727 : pszInterpolatePixelFuncMetadata);
1728 1292 : GDALAddDerivedBandPixelFuncWithArgs("replace_nodata",
1729 : ReplaceNoDataPixelFunc,
1730 : pszReplaceNoDataPixelFuncMetadata);
1731 1292 : GDALAddDerivedBandPixelFuncWithArgs("scale", ScalePixelFunc,
1732 : pszScalePixelFuncMetadata);
1733 1292 : GDALAddDerivedBandPixelFunc("norm_diff", NormDiffPixelFunc);
1734 1292 : GDALAddDerivedBandPixelFuncWithArgs("min", MinPixelFunc,
1735 : pszMinMaxFuncMetadataNodata);
1736 1292 : GDALAddDerivedBandPixelFuncWithArgs("max", MaxPixelFunc,
1737 : pszMinMaxFuncMetadataNodata);
1738 1292 : return CE_None;
1739 : }
|