gdal/autotest/cpp/test_gdal_pixelfn.cpp

241 строка
8.4 KiB
C++

///////////////////////////////////////////////////////////////////////////////
//
// Project: C++ Test Suite for GDAL/OGR
// Purpose: Test constant and builtin arguments for C++ pixel functions
// Author: Momtchil Momtchev <momtchil@momtchev.com>
//
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2022, Momtchil Momtchev <momtchil@momtchev.com>
/*
* 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 "gdal_unit_test.h"
#include "cpl_string.h"
#include "gdal_alg.h"
#include "gdal_priv.h"
#include "gdal.h"
#include "../../frmts/vrt/vrtdataset.h"
#include <vector>
#include "gtest_include.h"
CPLErr CustomPixelFuncWithMetadata(void **papoSources, int nSources,
void *pData, int nXSize, int nYSize,
GDALDataType eSrcType, GDALDataType eBufType,
int nPixelSpace, int nLineSpace,
CSLConstList papszArgs);
CPLErr CustomPixelFunc(void **papoSources, int nSources, void *pData,
int nXSize, int nYSize, GDALDataType eSrcType,
GDALDataType eBufType, int nPixelSpace, int nLineSpace,
CSLConstList papszArgs);
CPLErr CustomPixelFuncNoArgs(void **papoSources, int nSources, void *pData,
int nXSize, int nYSize, GDALDataType eSrcType,
GDALDataType eBufType, int nPixelSpace,
int nLineSpace);
CPLErr CustomPixelFuncWithMetadata(void **papoSources, int nSources,
void *pData, int nXSize, int nYSize,
GDALDataType eSrcType, GDALDataType eBufType,
int nPixelSpace, int nLineSpace,
CSLConstList papszArgs)
{
/* ---- Init ---- */
if (nSources != 1)
return CE_Failure;
const char *pszConstant = CSLFetchNameValue(papszArgs, "customConstant");
if (pszConstant == nullptr)
return CE_Failure;
if (strncmp(pszConstant, "something", strlen("something")))
return CE_Failure;
const char *pszScale = CSLFetchNameValue(papszArgs, "scale");
if (pszScale == nullptr)
return CE_Failure;
/* ---- Set pixels ---- */
size_t ii = 0;
for (int iLine = 0; iLine < nYSize; ++iLine)
{
for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
{
const double dfPixVal = SRCVAL(papoSources[0], eSrcType, ii) * 2;
GDALCopyWords(&dfPixVal, GDT_Float64, 0,
static_cast<GByte *>(pData) +
static_cast<GSpacing>(nLineSpace) * iLine +
iCol * nPixelSpace,
eBufType, nPixelSpace, 1);
}
}
/* ---- Return success ---- */
return CE_None;
}
CPLErr CustomPixelFunc(void **papoSources, int nSources, void *pData,
int nXSize, int nYSize, GDALDataType eSrcType,
GDALDataType eBufType, int nPixelSpace, int nLineSpace,
CSLConstList papszArgs)
{
/* ---- Init ---- */
if (nSources != 1)
return CE_Failure;
(void)papszArgs;
/* ---- Set pixels ---- */
size_t ii = 0;
for (int iLine = 0; iLine < nYSize; ++iLine)
{
for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
{
const double dfPixVal = SRCVAL(papoSources[0], eSrcType, ii) * 3;
GDALCopyWords(&dfPixVal, GDT_Float64, 0,
static_cast<GByte *>(pData) +
static_cast<GSpacing>(nLineSpace) * iLine +
iCol * nPixelSpace,
eBufType, nPixelSpace, 1);
}
}
/* ---- Return success ---- */
return CE_None;
}
CPLErr CustomPixelFuncNoArgs(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;
/* ---- Set pixels ---- */
size_t ii = 0;
for (int iLine = 0; iLine < nYSize; ++iLine)
{
for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
{
const double dfPixVal = SRCVAL(papoSources[0], eSrcType, ii) * 4;
GDALCopyWords(&dfPixVal, GDT_Float64, 0,
static_cast<GByte *>(pData) +
static_cast<GSpacing>(nLineSpace) * iLine +
iCol * nPixelSpace,
eBufType, nPixelSpace, 1);
}
}
/* ---- Return success ---- */
return CE_None;
}
namespace
{
const char pszFuncMetadata[] =
"<PixelFunctionArgumentsList>"
" <Argument name='customConstant' type='constant' value='something'>"
" </Argument>"
" <Argument type='builtin' value='scale'>"
" </Argument>"
"</PixelFunctionArgumentsList>";
struct test_gdal_pixelfn : public ::testing::Test
{
std::string src_;
test_gdal_pixelfn()
{
src_ = tut::common::data_basedir;
src_ += SEP;
src_ += "pixelfn.vrt";
}
};
// Test constant parameters in a custom pixel function
TEST_F(test_gdal_pixelfn, custom_pixel_fn_constant_parameters)
{
GDALAddDerivedBandPixelFuncWithArgs("custom", CustomPixelFuncWithMetadata,
pszFuncMetadata);
GDALDatasetH ds = GDALOpen(src_.c_str(), GA_ReadOnly);
ASSERT_TRUE(nullptr != ds);
GDALRasterBandH band = GDALGetRasterBand(ds, 1);
ASSERT_TRUE(nullptr != band);
float buf[20 * 20];
CPL_IGNORE_RET_VAL(GDALRasterIO(band, GF_Read, 0, 0, 20, 20, buf, 20, 20,
GDT_Float32, 0, 0));
EXPECT_EQ(buf[0], 107 * 2);
GDALClose(ds);
}
// Test registering of a custom pixel function without metadata
TEST_F(test_gdal_pixelfn, custom_pixel_fn_without_metadata)
{
GDALAddDerivedBandPixelFuncWithArgs("custom2", CustomPixelFunc, nullptr);
GDALDatasetH ds = GDALOpen(src_.c_str(), GA_ReadOnly);
ASSERT_TRUE(nullptr != ds);
GDALRasterBandH band = GDALGetRasterBand(ds, 1);
ASSERT_TRUE(nullptr != band);
VRTDerivedRasterBand *derived = reinterpret_cast<VRTDerivedRasterBand *>(
GDALRasterBand::FromHandle(band));
derived->SetPixelFunctionName("custom2");
float buf[20 * 20];
CPL_IGNORE_RET_VAL(GDALRasterIO(band, GF_Read, 0, 0, 20, 20, buf, 20, 20,
GDT_Float32, 0, 0));
EXPECT_EQ(buf[0], 107 * 3);
GDALClose(ds);
}
// Test the registering of a custom pixel function without args
TEST_F(test_gdal_pixelfn, custom_pixel_fn_without_args)
{
GDALAddDerivedBandPixelFunc("custom3", CustomPixelFuncNoArgs);
GDALDatasetH ds = GDALOpen(src_.c_str(), GA_ReadOnly);
ASSERT_TRUE(nullptr != ds);
GDALRasterBandH band = GDALGetRasterBand(ds, 1);
ASSERT_TRUE(nullptr != band);
VRTDerivedRasterBand *derived = reinterpret_cast<VRTDerivedRasterBand *>(
GDALRasterBand::FromHandle(band));
derived->SetPixelFunctionName("custom3");
float buf[20 * 20];
CPL_IGNORE_RET_VAL(GDALRasterIO(band, GF_Read, 0, 0, 20, 20, buf, 20, 20,
GDT_Float32, 0, 0));
EXPECT_EQ(buf[0], 107 * 4);
GDALClose(ds);
}
} // namespace