diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000000..599e63a78a14
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+*.pyc
+*.o
+*.so
+*~
diff --git a/autotest/gdrivers/data/cfloat64.tif b/autotest/gdrivers/data/cfloat64.tif
new file mode 100644
index 000000000000..0e75cb9919ab
Binary files /dev/null and b/autotest/gdrivers/data/cfloat64.tif differ
diff --git a/autotest/gdrivers/data/cint_sar.tif b/autotest/gdrivers/data/cint_sar.tif
new file mode 100644
index 000000000000..45e7c29907d2
Binary files /dev/null and b/autotest/gdrivers/data/cint_sar.tif differ
diff --git a/autotest/gdrivers/data/pixfun_cmul_c.vrt b/autotest/gdrivers/data/pixfun_cmul_c.vrt
new file mode 100644
index 000000000000..ea7a30b5451d
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_cmul_c.vrt
@@ -0,0 +1,18 @@
+
+
+ Product with complex conjugate
+ cmul
+
+ cint_sar.tif
+ 1
+
+
+
+
+ cint_sar.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_cmul_r.vrt b/autotest/gdrivers/data/pixfun_cmul_r.vrt
new file mode 100644
index 000000000000..be1ffe198c7a
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_cmul_r.vrt
@@ -0,0 +1,18 @@
+
+
+ Product with complex conjugate
+ cmul
+
+ uint16.tif
+ 1
+
+
+
+
+ int32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_complex.vrt b/autotest/gdrivers/data/pixfun_complex.vrt
new file mode 100644
index 000000000000..c26c08cfada1
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_complex.vrt
@@ -0,0 +1,19 @@
+
+
+ Make complex
+ complex
+ CFloat32
+
+ int32.tif
+ 1
+
+
+
+
+ int32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_conj_c.vrt b/autotest/gdrivers/data/pixfun_conj_c.vrt
new file mode 100644
index 000000000000..41e6ac20d769
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_conj_c.vrt
@@ -0,0 +1,13 @@
+
+
+ conjugate
+ conj
+ CInt16
+
+ cint_sar.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_conj_r.vrt b/autotest/gdrivers/data/pixfun_conj_r.vrt
new file mode 100644
index 000000000000..a91219bf5aee
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_conj_r.vrt
@@ -0,0 +1,13 @@
+
+
+ conjugate
+ conj
+ Int32
+
+ int32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_dB2amp.vrt b/autotest/gdrivers/data/pixfun_dB2amp.vrt
new file mode 100644
index 000000000000..0db48ef93863
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_dB2amp.vrt
@@ -0,0 +1,13 @@
+
+
+ db to amplitude
+ dB2amp
+ Float64
+
+ float32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_dB2pow.vrt b/autotest/gdrivers/data/pixfun_dB2pow.vrt
new file mode 100644
index 000000000000..ca295795adbc
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_dB2pow.vrt
@@ -0,0 +1,13 @@
+
+
+ dB to power
+ dB2pow
+ Float64
+
+ float32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_diff_c.vrt b/autotest/gdrivers/data/pixfun_diff_c.vrt
new file mode 100644
index 000000000000..c2f6cf0d1bb7
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_diff_c.vrt
@@ -0,0 +1,18 @@
+
+
+ Difference
+ diff
+
+ cint_sar.tif
+ 1
+
+
+
+
+ cfloat64.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_diff_r.vrt b/autotest/gdrivers/data/pixfun_diff_r.vrt
new file mode 100644
index 000000000000..3937e1de7d2e
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_diff_r.vrt
@@ -0,0 +1,18 @@
+
+
+ Difference
+ diff
+
+ int32.tif
+ 1
+
+
+
+
+ float32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_imag_c.vrt b/autotest/gdrivers/data/pixfun_imag_c.vrt
new file mode 100644
index 000000000000..41c3bd452e61
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_imag_c.vrt
@@ -0,0 +1,13 @@
+
+
+ Imaginary part
+ imag
+ CFloat64
+
+ cint_sar.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_imag_r.vrt b/autotest/gdrivers/data/pixfun_imag_r.vrt
new file mode 100644
index 000000000000..f0c147ed37bd
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_imag_r.vrt
@@ -0,0 +1,13 @@
+
+
+ Imaginary part
+ imag
+ Float32
+
+ float32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_intensity_c.vrt b/autotest/gdrivers/data/pixfun_intensity_c.vrt
new file mode 100644
index 000000000000..559d1f84e5ab
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_intensity_c.vrt
@@ -0,0 +1,13 @@
+
+
+ Intensity
+ intensity
+ CFloat64
+
+ cint_sar.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_intensity_r.vrt b/autotest/gdrivers/data/pixfun_intensity_r.vrt
new file mode 100644
index 000000000000..bdaafde8b363
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_intensity_r.vrt
@@ -0,0 +1,13 @@
+
+
+ Intensity
+ intensity
+ Float32
+
+ float32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_inv_c.vrt b/autotest/gdrivers/data/pixfun_inv_c.vrt
new file mode 100644
index 000000000000..50d88b1766d6
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_inv_c.vrt
@@ -0,0 +1,13 @@
+
+
+ Inverse
+ inv
+ CFloat64
+
+ cint_sar.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_inv_r.vrt b/autotest/gdrivers/data/pixfun_inv_r.vrt
new file mode 100644
index 000000000000..7726ebd45925
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_inv_r.vrt
@@ -0,0 +1,13 @@
+
+
+ Inverse
+ inv
+ Float64
+
+ float32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_log10.vrt b/autotest/gdrivers/data/pixfun_log10.vrt
new file mode 100644
index 000000000000..fc9cbbc919be
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_log10.vrt
@@ -0,0 +1,13 @@
+
+
+ Log10
+ log10
+ Float32
+
+ float32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_mod_c.vrt b/autotest/gdrivers/data/pixfun_mod_c.vrt
new file mode 100644
index 000000000000..a97668465a6b
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_mod_c.vrt
@@ -0,0 +1,13 @@
+
+
+ Magnitude
+ mod
+ CFloat64
+
+ cint_sar.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_mod_r.vrt b/autotest/gdrivers/data/pixfun_mod_r.vrt
new file mode 100644
index 000000000000..844cc14f1c68
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_mod_r.vrt
@@ -0,0 +1,13 @@
+
+
+ Magnitude
+ mod
+ Int32
+
+ int32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_mul_c.vrt b/autotest/gdrivers/data/pixfun_mul_c.vrt
new file mode 100644
index 000000000000..5c05266f9e20
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_mul_c.vrt
@@ -0,0 +1,18 @@
+
+
+ Product
+ mul
+
+ cint_sar.tif
+ 1
+
+
+
+
+ cint_sar.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_mul_r.vrt b/autotest/gdrivers/data/pixfun_mul_r.vrt
new file mode 100644
index 000000000000..0a3c246674b2
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_mul_r.vrt
@@ -0,0 +1,24 @@
+
+
+ Product
+ mul
+
+ uint16.tif
+ 1
+
+
+
+
+ int32.tif
+ 1
+
+
+
+
+ float32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_phase_c.vrt b/autotest/gdrivers/data/pixfun_phase_c.vrt
new file mode 100644
index 000000000000..f332b118f22c
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_phase_c.vrt
@@ -0,0 +1,13 @@
+
+
+ Phase
+ phase
+ CFloat64
+
+ cint_sar.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_phase_r.vrt b/autotest/gdrivers/data/pixfun_phase_r.vrt
new file mode 100644
index 000000000000..2f5c12bf84e2
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_phase_r.vrt
@@ -0,0 +1,13 @@
+
+
+ Phase
+ phase
+ Float64
+
+ pixfun_imag_c.vrt
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_real_c.vrt b/autotest/gdrivers/data/pixfun_real_c.vrt
new file mode 100644
index 000000000000..471a7d2ff037
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_real_c.vrt
@@ -0,0 +1,13 @@
+
+
+ Real part
+ real
+ CFloat64
+
+ cint_sar.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_real_r.vrt b/autotest/gdrivers/data/pixfun_real_r.vrt
new file mode 100644
index 000000000000..41dbd5439ac8
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_real_r.vrt
@@ -0,0 +1,13 @@
+
+
+ Real part
+ real
+ CFloat64
+
+ int32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_sqrt.vrt b/autotest/gdrivers/data/pixfun_sqrt.vrt
new file mode 100644
index 000000000000..c22fa3e8237e
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_sqrt.vrt
@@ -0,0 +1,13 @@
+
+
+ Square root
+ sqrt
+ Float32
+
+ float32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_sum_c.vrt b/autotest/gdrivers/data/pixfun_sum_c.vrt
new file mode 100644
index 000000000000..6c976dd32a67
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_sum_c.vrt
@@ -0,0 +1,24 @@
+
+
+ Sum
+ sum
+
+ uint16.tif
+ 1
+
+
+
+
+ cint_sar.tif
+ 1
+
+
+
+
+ cfloat64.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/pixfun_sum_r.vrt b/autotest/gdrivers/data/pixfun_sum_r.vrt
new file mode 100644
index 000000000000..24e253cc9d26
--- /dev/null
+++ b/autotest/gdrivers/data/pixfun_sum_r.vrt
@@ -0,0 +1,24 @@
+
+
+ Sum
+ sum
+
+ uint16.tif
+ 1
+
+
+
+
+ int32.tif
+ 1
+
+
+
+
+ float32.tif
+ 1
+
+
+
+
+
diff --git a/autotest/gdrivers/data/uint16.tif b/autotest/gdrivers/data/uint16.tif
new file mode 100644
index 000000000000..73fced68e554
Binary files /dev/null and b/autotest/gdrivers/data/uint16.tif differ
diff --git a/autotest/gdrivers/pixfun.py b/autotest/gdrivers/pixfun.py
new file mode 100644
index 000000000000..9450085372ac
--- /dev/null
+++ b/autotest/gdrivers/pixfun.py
@@ -0,0 +1,791 @@
+#!/usr/bin/env python
+###############################################################################
+# $Id$
+#
+# Project: GDAL/OGR Test Suite
+# Purpose: Test pixel functions support.
+# Author: Antonio Valentino
+#
+###############################################################################
+# Copyright (c) 2010-2014, Antonio Valentino
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+###############################################################################
+
+import sys
+
+try:
+ import numpy
+ numpy_available = True
+except ImportError:
+ numpy_available = False
+
+from osgeo import gdal
+
+sys.path.append('../pymod')
+
+import gdaltest
+
+###############################################################################
+# Verify real part extraction from a complex dataset.
+
+def pixfun_real_c():
+
+ filename = 'data/pixfun_real_c.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/cint_sar.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == refdata.real):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify real part extraction from a complex dataset.
+
+def pixfun_real_r():
+
+ filename = 'data/pixfun_real_r.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/int32.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == refdata.real):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify imaginary part extraction from a complex dataset.
+
+def pixfun_imag_c():
+
+ filename = 'data/pixfun_imag_c.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/cint_sar.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == refdata.imag):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify imaginary part extraction from a real dataset.
+
+def pixfun_imag_r():
+
+ filename = 'data/pixfun_imag_r.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == 0):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify imaginary part extraction from a real dataset.
+
+def pixfun_complex():
+
+ filename = 'data/pixfun_complex.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/int32.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.allclose(data, refdata + 1j * refdata):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify modulus extraction from a complex (float) dataset.
+
+def pixfun_mod_c():
+
+ filename = 'data/pixfun_mod_c.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/cint_sar.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == numpy.abs(refdata)):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify modulus extraction from a real (integer type) dataset.
+
+def pixfun_mod_r():
+
+ filename = 'data/pixfun_mod_r.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/int32.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == numpy.abs(refdata)):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify phase extraction from a complex dataset.
+
+def pixfun_phase_c():
+
+ filename = 'data/pixfun_phase_c.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/cint_sar.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+ refdata = refdata.astype('complex128')
+
+ #if not numpy.allclose(data, numpy.arctan2(refdata.imag, refdata.real)):
+ if numpy_available and not numpy.alltrue(data == numpy.arctan2(refdata.imag, refdata.real)):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify phase extraction from a real dataset.
+
+def pixfun_phase_r():
+
+ filename = 'data/pixfun_phase_r.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/pixfun_imag_c.vrt'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == numpy.arctan2(0, refdata)):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify cmplex conjugare computation on a complex dataset.
+
+def pixfun_conj_c():
+
+ filename = 'data/pixfun_conj_c.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/cint_sar.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == numpy.conj(refdata)):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify cmplex conjugare computation on a real dataset.
+
+def pixfun_conj_r():
+
+ filename = 'data/pixfun_conj_r.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/int32.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == numpy.conj(refdata)):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify the sum of 3 (real) datasets.
+
+def pixfun_sum_r():
+
+ filename = 'data/pixfun_sum_r.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available:
+ refdata = numpy.zeros(data.shape, 'float')
+ for reffilename in ('data/uint16.tif', 'data/int32.tif',
+ 'data/float32.tif'):
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata += refds.GetRasterBand(1).ReadAsArray()
+
+ if not numpy.alltrue(data == refdata):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify the sum of 3 (two complex and one real) datasets.
+
+def pixfun_sum_c():
+
+ filename = 'data/pixfun_sum_c.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available:
+ refdata = numpy.zeros(data.shape, 'complex')
+ for reffilename in ('data/uint16.tif', 'data/cint_sar.tif',
+ 'data/cfloat64.tif'):
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata += refds.GetRasterBand(1).ReadAsArray(0, 0, 5, 6)
+
+ if not numpy.alltrue(data == refdata):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify the difference of 2 (real) datasets.
+
+def pixfun_diff_r():
+
+ filename = 'data/pixfun_diff_r.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/int32.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata1 = refds.GetRasterBand(1).ReadAsArray(0, 0, 5, 6)
+
+ reffilename = 'data/float32.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata2 = refds.GetRasterBand(1).ReadAsArray(10, 10, 5, 6)
+
+ if numpy_available and not numpy.alltrue(data == refdata1-refdata2):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify the difference of 2 (complex) datasets.
+
+def pixfun_diff_c():
+
+ filename = 'data/pixfun_diff_c.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/cint_sar.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata1 = refds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/cfloat64.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata2 = refds.GetRasterBand(1).ReadAsArray(0, 0, 5, 6)
+
+ if numpy_available and not numpy.alltrue(data == refdata1-refdata2):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify the product of 3 (real) datasets.
+
+def pixfun_mul_r():
+
+ filename = 'data/pixfun_mul_r.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available:
+ refdata = numpy.ones(data.shape, 'float')
+ for reffilename in ('data/uint16.tif', 'data/int32.tif',
+ 'data/float32.tif'):
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata *= refds.GetRasterBand(1).ReadAsArray()
+
+ if not numpy.alltrue(data == refdata):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify the product of 2 (complex) datasets.
+
+def pixfun_mul_c():
+
+ filename = 'data/pixfun_mul_c.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/cint_sar.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == refdata*refdata):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify the product with complex conjugate of a complex datasets.
+
+def pixfun_cmul_c():
+
+ filename = 'data/pixfun_cmul_c.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/cint_sar.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == refdata*refdata.conj()):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify the product with complex conjugate of two real datasets.
+
+def pixfun_cmul_r():
+
+ filename = 'data/pixfun_cmul_r.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/uint16.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata1 = refds.GetRasterBand(1).ReadAsArray()
+ refdata1 = refdata1.astype('float64')
+
+ reffilename = 'data/int32.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata2 = refds.GetRasterBand(1).ReadAsArray()
+ refdata2 = refdata2.astype('float64')
+
+ if numpy_available and not numpy.alltrue(data == refdata1 * refdata2.conj()):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify computation of the inverse of a real datasets.
+
+def pixfun_inv_r():
+
+ filename = 'data/pixfun_inv_r.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/uint16.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+ refdata = refdata.astype('float64')
+
+ if numpy_available and not numpy.alltrue(data == 1./refdata):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify computation of the inverse of a complex datasets.
+
+def pixfun_inv_c():
+
+ filename = 'data/pixfun_inv_c.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/cint_sar.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+ refdata = refdata.astype('complex')
+ delta = data - 1./refdata
+
+ if numpy_available and not numpy.alltrue(abs(delta.real) < 1e-13):
+ return 'fail'
+ if numpy_available and not numpy.alltrue(abs(delta.imag) < 1e-13):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify intensity computation of a complex dataset.
+
+def pixfun_intensity_c():
+
+ filename = 'data/pixfun_intensity_c.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/cint_sar.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == (refdata*refdata.conj()).real):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify intensity computation of real dataset.
+
+def pixfun_intensity_r():
+
+ filename = 'data/pixfun_intensity_r.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/float32.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == (refdata*refdata.conj()).real):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify square root computation.
+
+def pixfun_sqrt():
+
+ filename = 'data/pixfun_sqrt.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/float32.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == numpy.sqrt(refdata)):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify logarithm computation.
+
+def pixfun_log10():
+
+ filename = 'data/pixfun_log10.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/float32.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ if numpy_available and not numpy.alltrue(data == numpy.log10(refdata)):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify conversion from dB to amplitude.
+
+def pixfun_dB2amp():
+
+ filename = 'data/pixfun_dB2amp.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/float32.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+
+ #if not numpy.alltrue(data == 10.**(refdata/20.)):
+ if numpy_available and not numpy.allclose(data, 10.**(refdata/20.)):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+# Verify conversion from dB to power.
+
+def pixfun_dB2pow():
+
+ filename = 'data/pixfun_dB2pow.vrt'
+ ds = gdal.OpenShared(filename, gdal.GA_ReadOnly)
+ if ds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % filename)
+ return 'fail'
+ data = ds.GetRasterBand(1).ReadAsArray()
+
+ reffilename = 'data/float32.tif'
+ refds = gdal.Open(reffilename)
+ if refds is None:
+ gdaltest.post_reason('Unable to open "%s" dataset.' % reffilename)
+ return 'fail'
+ refdata = refds.GetRasterBand(1).ReadAsArray()
+ refdata = refdata.astype('float64')
+
+ #if not numpy.allclose(data, 10.**(refdata/10.)):
+ if numpy_available and not numpy.alltrue(data == 10.**(refdata/10.)):
+ return 'fail'
+
+ return 'success'
+
+
+###############################################################################
+
+gdaltest_list = [
+ pixfun_real_c,
+ pixfun_real_r,
+ pixfun_imag_c,
+ pixfun_imag_r,
+ pixfun_complex,
+ pixfun_mod_c,
+ pixfun_mod_r,
+ pixfun_phase_c,
+ pixfun_phase_r,
+ pixfun_conj_c,
+ pixfun_conj_r,
+ pixfun_sum_r,
+ pixfun_sum_c,
+ pixfun_diff_r,
+ pixfun_diff_c,
+ pixfun_mul_r,
+ pixfun_mul_c,
+ pixfun_cmul_c,
+ pixfun_cmul_r,
+ pixfun_inv_r,
+ pixfun_inv_c,
+ pixfun_intensity_c,
+ pixfun_intensity_r,
+ pixfun_sqrt,
+ pixfun_log10,
+ pixfun_dB2amp,
+ pixfun_dB2pow,
+]
+
+
+if __name__ == '__main__':
+ gdaltest.setup_run('pixfun')
+ gdaltest.run_tests(gdaltest_list)
+ gdaltest.summarize()
diff --git a/gdal/frmts/vrt/GNUmakefile b/gdal/frmts/vrt/GNUmakefile
index b4e3d2427e16..2340fc25f7c1 100644
--- a/gdal/frmts/vrt/GNUmakefile
+++ b/gdal/frmts/vrt/GNUmakefile
@@ -3,6 +3,7 @@ include ../../GDALmake.opt
OBJ := vrtdataset.o vrtrasterband.o vrtdriver.o vrtsources.o
OBJ += vrtfilters.o vrtsourcedrasterband.o vrtrawrasterband.o
OBJ += vrtwarped.o vrtderivedrasterband.o vrtpansharpened.o
+OBJ += pixelfunctions.o
CPPFLAGS := -I../raw $(CPPFLAGS)
diff --git a/gdal/frmts/vrt/gdal_vrt.h b/gdal/frmts/vrt/gdal_vrt.h
index ca8971547619..642280a55614 100644
--- a/gdal/frmts/vrt/gdal_vrt.h
+++ b/gdal/frmts/vrt/gdal_vrt.h
@@ -46,6 +46,8 @@
CPL_C_START
void GDALRegister_VRT();
+CPLErr CPL_STDCALL GDALRegisterDefaultPixelFunc(void);
+
typedef CPLErr
(*VRTImageReadFunc)( void *hCBData,
int nXOff, int nYOff, int nXSize, int nYSize,
diff --git a/gdal/frmts/vrt/makefile.vc b/gdal/frmts/vrt/makefile.vc
index 442da649bb30..99a83150afd6 100644
--- a/gdal/frmts/vrt/makefile.vc
+++ b/gdal/frmts/vrt/makefile.vc
@@ -2,7 +2,7 @@
OBJ = vrtdataset.obj vrtrasterband.obj vrtdriver.obj \
vrtsources.obj vrtfilters.obj vrtsourcedrasterband.obj \
vrtrawrasterband.obj vrtderivedrasterband.obj vrtwarped.obj \
- vrtpansharpened.obj
+ vrtpansharpened.obj pixelfunctions.obj
GDAL_ROOT = ..\..
diff --git a/gdal/frmts/vrt/pixelfunctions.c b/gdal/frmts/vrt/pixelfunctions.c
new file mode 100644
index 000000000000..677cd95694c0
--- /dev/null
+++ b/gdal/frmts/vrt/pixelfunctions.c
@@ -0,0 +1,940 @@
+/******************************************************************************
+ *
+ * Project: GDAL
+ * Purpose: Implementation of a set of GDALDerivedPixelFunc(s) to be used
+ * with source raster band of virtual GDAL datasets.
+ * Author: Antonio Valentino
+ *
+ ******************************************************************************
+ * Copyright (c) 2008-2014 Antonio Valentino
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *****************************************************************************/
+
+#include
+#include
+#include "gdal_vrt.h"
+
+static CPLErr RealPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr ImagPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr ComplexPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr ModulePixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr PhasePixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr ConjPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr SumPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr DiffPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr MulPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr CMulPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr InvPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr IntensityPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr SqrtPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr Log10PixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr dB2AmpPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr dB2PowPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace);
+
+static CPLErr PowPixelFuncHelper(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace,
+ double base, double fact);
+
+static CPLErr RealPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ int iLine, nPixelSpaceSrc, nLineSpaceSrc;
+
+ /* ---- Init ---- */
+ if (nSources != 1) return CE_Failure;
+
+ nPixelSpaceSrc = GDALGetDataTypeSize( eSrcType ) / 8;
+ nLineSpaceSrc = nPixelSpaceSrc * nXSize;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0; iLine < nYSize; ++iLine ) {
+ GDALCopyWords(((GByte *)papoSources[0]) + nLineSpaceSrc * iLine,
+ eSrcType, nPixelSpaceSrc,
+ ((GByte *)pData) + nLineSpace * iLine,
+ eBufType, nPixelSpace, nXSize);
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* RealPixelFunc */
+
+
+static CPLErr ImagPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ int iLine;
+
+ /* ---- Init ---- */
+ if (nSources != 1) return CE_Failure;
+
+ if (GDALDataTypeIsComplex( eSrcType ))
+ {
+ int nPixelSpaceSrc = GDALGetDataTypeSize( eSrcType ) / 8;
+ int nLineSpaceSrc = nPixelSpaceSrc * nXSize;
+
+ void* pImag = ((GByte *)papoSources[0])
+ + GDALGetDataTypeSize( eSrcType ) / 8 / 2;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0; iLine < nYSize; ++iLine ) {
+ GDALCopyWords(((GByte *)pImag) + nLineSpaceSrc * iLine,
+ eSrcType, nPixelSpaceSrc,
+ ((GByte *)pData) + nLineSpace * iLine,
+ eBufType, nPixelSpace, nXSize);
+ }
+ } else {
+ double dfImag = 0;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0; iLine < nYSize; ++iLine ) {
+ /* always copy from the same location */
+ GDALCopyWords(&dfImag, eSrcType, 0,
+ ((GByte *)pData) + nLineSpace * iLine,
+ eBufType, nPixelSpace, nXSize);
+ }
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* ImagPixelFunc */
+
+
+static CPLErr ComplexPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ int ii, iLine, iCol;
+ double adfPixVal[2];
+
+ void *pReal = papoSources[0];
+ void *pImag = papoSources[1];
+
+ /* ---- Init ---- */
+ if (nSources != 2) return CE_Failure;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ adfPixVal[0] = SRCVAL(pReal, eSrcType, ii); /* re */
+ adfPixVal[1] = SRCVAL(pImag, eSrcType, ii); /* im */
+
+ GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* MakeComplexPixelFunc */
+
+
+static CPLErr ModulePixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ int ii, iLine, iCol;
+ double dfPixVal;
+
+ /* ---- Init ---- */
+ if (nSources != 1) return CE_Failure;
+
+ if (GDALDataTypeIsComplex( eSrcType ))
+ {
+ double dfReal, dfImag;
+ void *pReal = papoSources[0];
+ void *pImag = ((GByte *)papoSources[0])
+ + GDALGetDataTypeSize( eSrcType ) / 8 / 2;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii = 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfReal = SRCVAL(pReal, eSrcType, ii);
+ dfImag = SRCVAL(pImag, eSrcType, ii);
+
+ dfPixVal = sqrt( dfReal * dfReal + dfImag * dfImag );
+
+ GDALCopyWords(&dfPixVal, GDT_Float64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ } else {
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii = 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfPixVal = fabs(SRCVAL(papoSources[0], eSrcType, ii));
+
+ GDALCopyWords(&dfPixVal, GDT_Float64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* ModulePixelFunc */
+
+
+static CPLErr PhasePixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ int ii, iLine, iCol;
+ double dfPixVal, dfReal;
+
+ /* ---- Init ---- */
+ if (nSources != 1) return CE_Failure;
+
+ if (GDALDataTypeIsComplex( eSrcType ))
+ {
+ double dfImag;
+ void *pReal = papoSources[0];
+ void *pImag = ((GByte *)papoSources[0])
+ + GDALGetDataTypeSize( eSrcType ) / 8 / 2;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfReal = SRCVAL(pReal, eSrcType, ii);
+ dfImag = SRCVAL(pImag, eSrcType, ii);
+
+ dfPixVal = atan2(dfImag, dfReal);
+
+ GDALCopyWords(&dfPixVal, GDT_Float64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ } else {
+ /* ---- Set pixels ---- */
+ /*
+ for( iLine = 0; iLine < nYSize; ++iLine ) {
+ / * always copy from the same location * /
+ GDALCopyWords(&dfImag, eSrcType, 0,
+ ((GByte *)pData) + nLineSpace * iLine,
+ eBufType, nPixelSpace, nXSize);
+ }
+ */
+ /* ---- Set pixels ---- */
+ double pi = atan2(0, -1);
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ void *pReal = papoSources[0];
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfReal = SRCVAL(pReal, eSrcType, ii);
+ dfPixVal = (dfReal < 0) ? pi : 0;
+
+ GDALCopyWords(&dfPixVal, GDT_Float64, dfPixVal,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* PhasePixelFunc */
+
+
+static CPLErr ConjPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ /* ---- Init ---- */
+ if (nSources != 1) return CE_Failure;
+
+ if (GDALDataTypeIsComplex( eSrcType ) && GDALDataTypeIsComplex( eBufType ))
+ {
+ int iLine, iCol, ii;
+ double adfPixVal[2];
+ int nOffset = GDALGetDataTypeSize( eSrcType ) / 8 / 2;
+ void *pReal = papoSources[0];
+ void *pImag = ((GByte *)papoSources[0]) + nOffset;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ adfPixVal[0] = +SRCVAL(pReal, eSrcType, ii); /* re */
+ adfPixVal[1] = -SRCVAL(pImag, eSrcType, ii); /* im */
+
+ GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ } else {
+ /* no complex data type */
+ return RealPixelFunc(papoSources, nSources, pData, nXSize, nYSize,
+ eSrcType, eBufType, nPixelSpace, nLineSpace);
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* ConjPixelFunc */
+
+
+static CPLErr SumPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ int iLine, iCol, ii, iSrc;
+
+ /* ---- Init ---- */
+ if (nSources < 2) return CE_Failure;
+
+ /* ---- Set pixels ---- */
+ if (GDALDataTypeIsComplex( eSrcType ))
+ {
+ double adfSum[2];
+ void *pReal, *pImag;
+ int nOffset = GDALGetDataTypeSize( eSrcType ) / 8 / 2;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+ adfSum[0] = 0;
+ adfSum[1] = 0;
+
+ for( iSrc = 0; iSrc < nSources; ++iSrc ) {
+ pReal = papoSources[iSrc];
+ pImag = ((GByte *)pReal) + nOffset;
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ adfSum[0] += SRCVAL(pReal, eSrcType, ii);
+ adfSum[1] += SRCVAL(pImag, eSrcType, ii);
+ }
+
+ GDALCopyWords(adfSum, GDT_CFloat64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ } else {
+ /* non complex */
+ double dfSum;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+ dfSum = 0;
+
+ for( iSrc = 0; iSrc < nSources; ++iSrc ) {
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfSum += SRCVAL(papoSources[iSrc], eSrcType, ii);
+ }
+
+ GDALCopyWords(&dfSum, GDT_Float64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* SumPixelFunc */
+
+
+static CPLErr DiffPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ int ii, iLine, iCol;
+
+ /* ---- Init ---- */
+ if (nSources != 2) return CE_Failure;
+
+ if (GDALDataTypeIsComplex( eSrcType ))
+ {
+
+ double adfPixVal[2];
+ int nOffset = GDALGetDataTypeSize( eSrcType ) / 8 / 2;
+ void *pReal0 = papoSources[0];
+ void *pImag0 = ((GByte *)papoSources[0]) + nOffset;
+ void *pReal1 = papoSources[1];
+ void *pImag1 = ((GByte *)papoSources[1]) + nOffset;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ adfPixVal[0] = SRCVAL(pReal0, eSrcType, ii)
+ - SRCVAL(pReal1, eSrcType, ii);
+ adfPixVal[1] = SRCVAL(pImag0, eSrcType, ii)
+ - SRCVAL(pImag1, eSrcType, ii);
+
+ GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ } else {
+ /* non complex */
+ double dfPixVal;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfPixVal = SRCVAL(papoSources[0], eSrcType, ii)
+ - SRCVAL(papoSources[1], eSrcType, ii);
+
+ GDALCopyWords(&dfPixVal, GDT_Float64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* DiffPixelFunc */
+
+
+static CPLErr MulPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ int iLine, iCol, ii, iSrc;
+
+ /* ---- Init ---- */
+ if (nSources < 2) return CE_Failure;
+
+ /* ---- Set pixels ---- */
+ if (GDALDataTypeIsComplex( eSrcType ))
+ {
+ double adfPixVal[2], dfOldR, dfOldI, dfNewR, dfNewI;
+ void *pReal, *pImag;
+ int nOffset = GDALGetDataTypeSize( eSrcType ) / 8 / 2;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+ adfPixVal[0] = 1.;
+ adfPixVal[1] = 0.;
+
+ for( iSrc = 0; iSrc < nSources; ++iSrc ) {
+ pReal = papoSources[iSrc];
+ pImag = ((GByte *)pReal) + nOffset;
+
+ dfOldR = adfPixVal[0];
+ dfOldI = adfPixVal[1];
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfNewR = SRCVAL(pReal, eSrcType, ii);
+ dfNewI = SRCVAL(pImag, eSrcType, ii);
+
+ adfPixVal[0] = dfOldR * dfNewR - dfOldI * dfNewI;
+ adfPixVal[1] = dfOldR * dfNewI + dfOldI * dfNewR;
+ }
+
+ GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ } else {
+ /* non complex */
+ double dfPixVal;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+ dfPixVal = 1;
+
+ for( iSrc = 0; iSrc < nSources; ++iSrc ) {
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfPixVal *= SRCVAL(papoSources[iSrc], eSrcType, ii);
+ }
+
+ GDALCopyWords(&dfPixVal, GDT_Float64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* MulPixelFunc */
+
+
+static CPLErr CMulPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ int ii, iLine, iCol;
+
+ /* ---- Init ---- */
+ if (nSources != 2) return CE_Failure;
+
+ /* ---- Set pixels ---- */
+ if (GDALDataTypeIsComplex( eSrcType ))
+ {
+ double adfPixVal[2], dfReal0, dfImag0, dfReal1, dfImag1;
+
+ int nOffset = GDALGetDataTypeSize( eSrcType ) / 8 / 2;
+ void *pReal0 = papoSources[0];
+ void *pImag0 = ((GByte *)papoSources[0]) + nOffset;
+ void *pReal1 = papoSources[1];
+ void *pImag1 = ((GByte *)papoSources[1]) + nOffset;
+
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfReal0 = SRCVAL(pReal0, eSrcType, ii);
+ dfReal1 = SRCVAL(pReal1, eSrcType, ii);
+ dfImag0 = SRCVAL(pImag0, eSrcType, ii);
+ dfImag1 = SRCVAL(pImag1, eSrcType, ii);
+ adfPixVal[0] = dfReal0 * dfReal1 + dfImag0 * dfImag1;
+ adfPixVal[1] = dfReal1 * dfImag0 - dfReal0 * dfImag1;
+
+ GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ } else {
+ /* non complex */
+ double adfPixVal[2] = {0, 0};
+
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ adfPixVal[0] = SRCVAL(papoSources[0], eSrcType, ii)
+ * SRCVAL(papoSources[1], eSrcType, ii);
+
+ GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* CMulPixelFunc */
+
+
+static CPLErr InvPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ int iLine, iCol, ii;
+
+ /* ---- Init ---- */
+ if (nSources != 1) return CE_Failure;
+
+ /* ---- Set pixels ---- */
+ if (GDALDataTypeIsComplex( eSrcType ))
+ {
+ double adfPixVal[2], dfReal, dfImag, dfAux;
+
+ int nOffset = GDALGetDataTypeSize( eSrcType ) / 8 / 2;
+ void *pReal = papoSources[0];
+ void *pImag = ((GByte *)papoSources[0]) + nOffset;
+
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfReal = SRCVAL(pReal, eSrcType, ii);
+ dfImag = SRCVAL(pImag, eSrcType, ii);
+ dfAux = dfReal * dfReal + dfImag * dfImag;
+ adfPixVal[0] = +dfReal / dfAux;
+ adfPixVal[1] = -dfImag / dfAux;
+
+ GDALCopyWords(adfPixVal, GDT_CFloat64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ } else {
+ /* non complex */
+ double dfPixVal;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfPixVal = 1. / SRCVAL(papoSources[0], eSrcType, ii);
+
+ GDALCopyWords(&dfPixVal, GDT_Float64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* InvPixelFunc */
+
+
+static CPLErr IntensityPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ int ii, iLine, iCol;
+ double dfPixVal;
+
+ /* ---- Init ---- */
+ if (nSources != 1) return CE_Failure;
+
+ if (GDALDataTypeIsComplex( eSrcType ))
+ {
+ double dfReal, dfImag;
+ int nOffset = GDALGetDataTypeSize( eSrcType ) / 8 / 2;
+ void *pReal = papoSources[0];
+ void *pImag = ((GByte *)papoSources[0]) + nOffset;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii = 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfReal = SRCVAL(pReal, eSrcType, ii);
+ dfImag = SRCVAL(pImag, eSrcType, ii);
+
+ dfPixVal = dfReal * dfReal + dfImag * dfImag;
+
+ GDALCopyWords(&dfPixVal, GDT_Float64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ } else {
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii = 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfPixVal = SRCVAL(papoSources[0], eSrcType, ii);
+ dfPixVal *= dfPixVal;
+
+ GDALCopyWords(&dfPixVal, GDT_Float64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* IntensityPixelFunc */
+
+
+static CPLErr SqrtPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ int iLine, iCol, ii;
+ double dfPixVal;
+
+ /* ---- Init ---- */
+ if (nSources != 1) return CE_Failure;
+ if (GDALDataTypeIsComplex( eSrcType )) return CE_Failure;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */;
+ dfPixVal = sqrt( SRCVAL(papoSources[0], eSrcType, ii) );
+
+ GDALCopyWords(&dfPixVal, GDT_Float64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* SqrtPixelFunc */
+
+
+static CPLErr Log10PixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ int ii, iLine, iCol;
+
+ /* ---- Init ---- */
+ if (nSources != 1) return CE_Failure;
+
+ if (GDALDataTypeIsComplex( eSrcType ))
+ {
+ /* complex input datatype */
+ double dfReal, dfImag, dfPixVal;
+ int nOffset = GDALGetDataTypeSize( eSrcType ) / 8 / 2;
+ void *pReal = papoSources[0];
+ void *pImag = ((GByte *)papoSources[0]) + nOffset;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii = 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfReal = SRCVAL(pReal, eSrcType, ii);
+ dfImag = SRCVAL(pImag, eSrcType, ii);
+
+ dfPixVal = log10( dfReal * dfReal + dfImag * dfImag );
+
+ GDALCopyWords(&dfPixVal, GDT_Float64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ } else {
+ double dfPixVal;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii = 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfPixVal = SRCVAL(papoSources[0], eSrcType, ii);
+ dfPixVal = log10( fabs( dfPixVal ) );
+
+ GDALCopyWords(&dfPixVal, GDT_Float64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* Log10PixelFunc */
+
+
+static CPLErr PowPixelFuncHelper(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace,
+ double base, double fact)
+{
+ int iLine, iCol, ii;
+ double dfPixVal;
+
+ /* ---- Init ---- */
+ if (nSources != 1) return CE_Failure;
+ if (GDALDataTypeIsComplex( eSrcType )) return CE_Failure;
+
+ /* ---- Set pixels ---- */
+ for( iLine = 0, ii= 0; iLine < nYSize; ++iLine ) {
+ for( iCol = 0; iCol < nXSize; ++iCol, ++ii ) {
+
+ /* Source raster pixels may be obtained with SRCVAL macro */
+ dfPixVal = SRCVAL(papoSources[0], eSrcType, ii);
+ dfPixVal = pow(base, dfPixVal / fact);
+
+ GDALCopyWords(&dfPixVal, GDT_Float64, 0,
+ ((GByte *)pData) + nLineSpace * iLine +
+ iCol * nPixelSpace, eBufType, nPixelSpace, 1);
+ }
+ }
+
+ /* ---- Return success ---- */
+ return CE_None;
+} /* PowPixelFuncHelper */
+
+static CPLErr dB2AmpPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ return PowPixelFuncHelper(papoSources, nSources, pData,
+ nXSize, nYSize, eSrcType, eBufType,
+ nPixelSpace, nLineSpace, 10., 20.);
+} /* dB2AmpPixelFunc */
+
+
+static CPLErr dB2PowPixelFunc(void **papoSources, int nSources, void *pData,
+ int nXSize, int nYSize,
+ GDALDataType eSrcType, GDALDataType eBufType,
+ int nPixelSpace, int nLineSpace)
+{
+ return PowPixelFuncHelper(papoSources, nSources, pData,
+ nXSize, nYSize, eSrcType, eBufType,
+ nPixelSpace, nLineSpace, 10., 10.);
+} /* dB2PowPixelFunc */
+
+
+/************************************************************************/
+/* GDALRegisterDefaultPixelFunc() */
+/************************************************************************/
+
+/**
+ * This adds a default set of pixel functions to the global list of
+ * available pixel functions for derived bands:
+ *
+ * - "real": extract real part from a single raster band (just a copy if the
+ * input is non-complex)
+ * - "imag": extract imaginary part from a single raster band (0 for
+ * non-complex)
+ * - "complex": make a complex band merging two bands used as real and
+ * imag values
+ * - "mod": extract module from a single raster band (real or complex)
+ * - "phase": extract phase from a single raster band (0 for non-complex)
+ * - "conj": computes the complex conjugate of a single raster band (just a
+ * copy if the input is non-complex)
+ * - "sum": sum 2 or more raster bands
+ * - "diff": computes the difference between 2 raster bands (b1 - b2)
+ * - "mul": multilpy 2 or more raster bands
+ * - "cmul": multiply the first band for the complex conjugate of the second
+ * - "inv": inverse (1./x). Note: no check is performed on zero division
+ * - "intensity": computes the intensity Re(x*conj(x)) of a single raster band
+ * (real or complex)
+ * - "sqrt": perform the square root of a single raster band (real only)
+ * - "log10": compute the logarithm (base 10) of the abs of a single raster
+ * band (real or complex): log10( abs( x ) )
+ * - "dB2amp": perform scale conversion from logarithmic to linear
+ * (amplitude) (i.e. 10 ^ ( x / 20 ) ) of a single raster
+ * band (real only)
+ * - "dB2pow": perform scale conversion from logarithmic to linear
+ * (power) (i.e. 10 ^ ( x / 10 ) ) of a single raster
+ * band (real only)
+ *
+ * @see GDALAddDerivedBandPixelFunc
+ *
+ * @return CE_None, invalid (NULL) parameters are currently ignored.
+ */
+CPLErr CPL_STDCALL GDALRegisterDefaultPixelFunc(void)
+{
+ GDALAddDerivedBandPixelFunc("real", RealPixelFunc);
+ GDALAddDerivedBandPixelFunc("imag", ImagPixelFunc);
+ GDALAddDerivedBandPixelFunc("complex", ComplexPixelFunc);
+ GDALAddDerivedBandPixelFunc("mod", ModulePixelFunc);
+ GDALAddDerivedBandPixelFunc("phase", PhasePixelFunc);
+ GDALAddDerivedBandPixelFunc("conj", ConjPixelFunc);
+ GDALAddDerivedBandPixelFunc("sum", SumPixelFunc);
+ GDALAddDerivedBandPixelFunc("diff", DiffPixelFunc);
+ GDALAddDerivedBandPixelFunc("mul", MulPixelFunc);
+ GDALAddDerivedBandPixelFunc("cmul", CMulPixelFunc);
+ GDALAddDerivedBandPixelFunc("inv", InvPixelFunc);
+ GDALAddDerivedBandPixelFunc("intensity", IntensityPixelFunc);
+ GDALAddDerivedBandPixelFunc("sqrt", SqrtPixelFunc);
+ GDALAddDerivedBandPixelFunc("log10", Log10PixelFunc);
+ GDALAddDerivedBandPixelFunc("dB2amp", dB2AmpPixelFunc);
+ GDALAddDerivedBandPixelFunc("dB2pow", dB2PowPixelFunc);
+
+ return CE_None;
+}
diff --git a/gdal/frmts/vrt/vrt_tutorial.dox b/gdal/frmts/vrt/vrt_tutorial.dox
index 5c294651feb6..d8dbc58da396 100644
--- a/gdal/frmts/vrt/vrt_tutorial.dox
+++ b/gdal/frmts/vrt/vrt_tutorial.dox
@@ -806,6 +806,30 @@ calling the pixel function, and the imaginary portion would be lost.
...
\endcode
+ Default Pixel Functions
+
+GDAL provides a set of default pixel functions that can be used without writing new code:
+
+
+- "real": extract real part from a single raster band (just a copy if the input is non-complex)
+
- "imag":
+ extract imaginary part from a single raster band (0 for non-complex)
+
- "complex": make a complex band merging two bands used as real and imag values
+
- "mod": extract module from a single raster band (real or complex)
+
- "phase": extract phase from a single raster band (0 for non-complex)
+
- "conj": computes the complex conjugate of a single raster band (just a copy if the input is non-complex)
+
- "sum": sum 2 or more raster bands
+
- "diff": computes the difference between 2 raster bands (b1 - b2)
+
- "mul": multiply 2 or more raster bands
+
- "cmul": multiply the first band for the complex conjugate of the second
+
- "inv": inverse (1./x). Note: no check is performed on zero division
+
- "intensity": computes the intensity Re(x*conj(x)) of a single raster band (real or complex)
+
- "sqrt": perform the square root of a single raster band (real only)
+
- "log10": compute the logarithm (base 10) of the abs of a single raster band (real or complex): log10( abs( x ) )
+
- "dB2amp": perform scale conversion from logarithmic to linear (amplitude) (i.e. 10 ^ ( x / 20 ) ) of a single raster band (real only)
+
- "dB2pow": perform scale conversion from logarithmic to linear (power) (i.e. 10 ^ ( x / 10 ) ) of a single raster band (real only)
+
+
Writing Pixel Functions
To register this function with GDAL (prior to accessing any VRT datasets
diff --git a/gdal/frmts/vrt/vrtdriver.cpp b/gdal/frmts/vrt/vrtdriver.cpp
index 82eee925e45f..2045dc78f817 100644
--- a/gdal/frmts/vrt/vrtdriver.cpp
+++ b/gdal/frmts/vrt/vrtdriver.cpp
@@ -37,6 +37,7 @@
CPL_CVSID("$Id$");
+
/************************************************************************/
/* VRTDriver() */
/************************************************************************/
@@ -356,6 +357,9 @@ VRTCreateCopy( const char * pszFilename,
void GDALRegister_VRT()
{
+ // First register the pixel functions
+ GDALRegisterDefaultPixelFunc();
+
if( GDALGetDriverByName( "VRT" ) != NULL )
return;