diff --git a/README.txt b/README.txt index 449b7400357a..01a265765490 100644 --- a/README.txt +++ b/README.txt @@ -26,6 +26,8 @@ List of pixel functions :"imag": extract imaginary part from a single raster band (0 for non-complex) +:"makecomplex": + 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": diff --git a/autotest/gcore/data/pixfun_makecomplex.vrt b/autotest/gcore/data/pixfun_makecomplex.vrt new file mode 100644 index 000000000000..f276dca06481 --- /dev/null +++ b/autotest/gcore/data/pixfun_makecomplex.vrt @@ -0,0 +1,19 @@ + + + Make complex + makecomplex + CFloat32 + + int32.tif + 1 + + + + + int32.tif + 1 + + + + + \ No newline at end of file diff --git a/autotest/gcore/pixfun.py b/autotest/gcore/pixfun.py index 991f74c4f410..fcabeb2710d6 100644 --- a/autotest/gcore/pixfun.py +++ b/autotest/gcore/pixfun.py @@ -135,6 +135,31 @@ def pixfun_imag_r(): return 'success' +############################################################################### +# Verify imaginary part extraction from a real dataset. + +def pixfun_makecomplex(): + + filename = 'data/pixfun_makecomplex.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 not numpy.allclose(data, refdata + 1j * refdata): + return 'fail' + + return 'success' + + ############################################################################### # Verify modulus extraction from a complex (float) dataset. @@ -731,6 +756,7 @@ def pixfun_dB2pow(): pixfun_real_r, pixfun_imag_c, pixfun_imag_r, + pixfun_makecomplex, pixfun_mod_c, pixfun_mod_r, pixfun_phase_c, diff --git a/pixelfunctions.c b/pixelfunctions.c index 9ac7134e5c08..c39b2c760c9d 100644 --- a/pixelfunctions.c +++ b/pixelfunctions.c @@ -99,6 +99,39 @@ CPLErr ImagPixelFunc(void **papoSources, int nSources, void *pData, } /* ImagPixelFunc */ +CPLErr MakeComplexPixelFunc(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 */ + + CPLErr ModulePixelFunc(void **papoSources, int nSources, void *pData, int nXSize, int nYSize, GDALDataType eSrcType, GDALDataType eBufType, @@ -800,6 +833,7 @@ CPLErr CPL_STDCALL GDALRegisterDefaultPixelFunc() { GDALAddDerivedBandPixelFunc("real", RealPixelFunc); GDALAddDerivedBandPixelFunc("imag", ImagPixelFunc); + GDALAddDerivedBandPixelFunc("makecomplex", MakeComplexPixelFunc); GDALAddDerivedBandPixelFunc("mod", ModulePixelFunc); GDALAddDerivedBandPixelFunc("phase", PhasePixelFunc); GDALAddDerivedBandPixelFunc("conj", ConjPixelFunc);