LCOV - code coverage report
Current view: top level - autotest/cpp - test_gdal_pixelfn.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 78 88 88.6 %
Date: 2024-11-21 22:18:42 Functions: 17 17 100.0 %

          Line data    Source code
       1             : ///////////////////////////////////////////////////////////////////////////////
       2             : //
       3             : // Project:  C++ Test Suite for GDAL/OGR
       4             : // Purpose:  Test constant and builtin arguments for C++ pixel functions
       5             : // Author:   Momtchil Momtchev <momtchil@momtchev.com>
       6             : //
       7             : ///////////////////////////////////////////////////////////////////////////////
       8             : // Copyright (c) 2022, Momtchil Momtchev <momtchil@momtchev.com>
       9             : /*
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "gdal_unit_test.h"
      14             : 
      15             : #include "cpl_string.h"
      16             : #include "gdal_alg.h"
      17             : #include "gdal_priv.h"
      18             : #include "gdal.h"
      19             : #include "../../frmts/vrt/vrtdataset.h"
      20             : 
      21             : #include <vector>
      22             : 
      23             : #include "gtest_include.h"
      24             : 
      25             : CPLErr CustomPixelFuncWithMetadata(void **papoSources, int nSources,
      26             :                                    void *pData, int nXSize, int nYSize,
      27             :                                    GDALDataType eSrcType, GDALDataType eBufType,
      28             :                                    int nPixelSpace, int nLineSpace,
      29             :                                    CSLConstList papszArgs);
      30             : CPLErr CustomPixelFunc(void **papoSources, int nSources, void *pData,
      31             :                        int nXSize, int nYSize, GDALDataType eSrcType,
      32             :                        GDALDataType eBufType, int nPixelSpace, int nLineSpace,
      33             :                        CSLConstList papszArgs);
      34             : CPLErr CustomPixelFuncNoArgs(void **papoSources, int nSources, void *pData,
      35             :                              int nXSize, int nYSize, GDALDataType eSrcType,
      36             :                              GDALDataType eBufType, int nPixelSpace,
      37             :                              int nLineSpace);
      38             : 
      39           1 : CPLErr CustomPixelFuncWithMetadata(void **papoSources, int nSources,
      40             :                                    void *pData, int nXSize, int nYSize,
      41             :                                    GDALDataType eSrcType, GDALDataType eBufType,
      42             :                                    int nPixelSpace, int nLineSpace,
      43             :                                    CSLConstList papszArgs)
      44             : {
      45             : 
      46             :     /* ---- Init ---- */
      47           1 :     if (nSources != 1)
      48           0 :         return CE_Failure;
      49           1 :     const char *pszConstant = CSLFetchNameValue(papszArgs, "customConstant");
      50           1 :     if (pszConstant == nullptr)
      51           0 :         return CE_Failure;
      52           1 :     if (strncmp(pszConstant, "something", strlen("something")))
      53           0 :         return CE_Failure;
      54           1 :     const char *pszScale = CSLFetchNameValue(papszArgs, "scale");
      55           1 :     if (pszScale == nullptr)
      56           0 :         return CE_Failure;
      57             : 
      58             :     /* ---- Set pixels ---- */
      59           1 :     size_t ii = 0;
      60          21 :     for (int iLine = 0; iLine < nYSize; ++iLine)
      61             :     {
      62         420 :         for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
      63             :         {
      64         400 :             const double dfPixVal = SRCVAL(papoSources[0], eSrcType, ii) * 2;
      65         400 :             GDALCopyWords(&dfPixVal, GDT_Float64, 0,
      66             :                           static_cast<GByte *>(pData) +
      67         400 :                               static_cast<GSpacing>(nLineSpace) * iLine +
      68         400 :                               iCol * nPixelSpace,
      69             :                           eBufType, nPixelSpace, 1);
      70             :         }
      71             :     }
      72             : 
      73             :     /* ---- Return success ---- */
      74           1 :     return CE_None;
      75             : }
      76             : 
      77           1 : CPLErr CustomPixelFunc(void **papoSources, int nSources, void *pData,
      78             :                        int nXSize, int nYSize, GDALDataType eSrcType,
      79             :                        GDALDataType eBufType, int nPixelSpace, int nLineSpace,
      80             :                        CSLConstList papszArgs)
      81             : {
      82             : 
      83             :     /* ---- Init ---- */
      84           1 :     if (nSources != 1)
      85           0 :         return CE_Failure;
      86             : 
      87             :     (void)papszArgs;
      88             : 
      89             :     /* ---- Set pixels ---- */
      90           1 :     size_t ii = 0;
      91          21 :     for (int iLine = 0; iLine < nYSize; ++iLine)
      92             :     {
      93         420 :         for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
      94             :         {
      95         400 :             const double dfPixVal = SRCVAL(papoSources[0], eSrcType, ii) * 3;
      96         400 :             GDALCopyWords(&dfPixVal, GDT_Float64, 0,
      97             :                           static_cast<GByte *>(pData) +
      98         400 :                               static_cast<GSpacing>(nLineSpace) * iLine +
      99         400 :                               iCol * nPixelSpace,
     100             :                           eBufType, nPixelSpace, 1);
     101             :         }
     102             :     }
     103             : 
     104             :     /* ---- Return success ---- */
     105           1 :     return CE_None;
     106             : }
     107             : 
     108           1 : CPLErr CustomPixelFuncNoArgs(void **papoSources, int nSources, void *pData,
     109             :                              int nXSize, int nYSize, GDALDataType eSrcType,
     110             :                              GDALDataType eBufType, int nPixelSpace,
     111             :                              int nLineSpace)
     112             : {
     113             : 
     114             :     /* ---- Init ---- */
     115           1 :     if (nSources != 1)
     116           0 :         return CE_Failure;
     117             : 
     118             :     /* ---- Set pixels ---- */
     119           1 :     size_t ii = 0;
     120          21 :     for (int iLine = 0; iLine < nYSize; ++iLine)
     121             :     {
     122         420 :         for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
     123             :         {
     124         400 :             const double dfPixVal = SRCVAL(papoSources[0], eSrcType, ii) * 4;
     125         400 :             GDALCopyWords(&dfPixVal, GDT_Float64, 0,
     126             :                           static_cast<GByte *>(pData) +
     127         400 :                               static_cast<GSpacing>(nLineSpace) * iLine +
     128         400 :                               iCol * nPixelSpace,
     129             :                           eBufType, nPixelSpace, 1);
     130             :         }
     131             :     }
     132             : 
     133             :     /* ---- Return success ---- */
     134           1 :     return CE_None;
     135             : }
     136             : 
     137             : namespace
     138             : {
     139             : const char pszFuncMetadata[] =
     140             :     "<PixelFunctionArgumentsList>"
     141             :     "   <Argument name='customConstant' type='constant' value='something'>"
     142             :     "   </Argument>"
     143             :     "   <Argument type='builtin' value='scale'>"
     144             :     "   </Argument>"
     145             :     "</PixelFunctionArgumentsList>";
     146             : 
     147             : struct test_gdal_pixelfn : public ::testing::Test
     148             : {
     149             :     std::string src_;
     150             : 
     151           3 :     test_gdal_pixelfn()
     152           3 :     {
     153           3 :         src_ = tut::common::data_basedir;
     154           3 :         src_ += SEP;
     155           3 :         src_ += "pixelfn.vrt";
     156           3 :     }
     157             : 
     158           3 :     void SetUp() override
     159             :     {
     160           3 :         if (GDALGetMetadataItem(GDALGetDriverByName("VRT"),
     161           3 :                                 GDAL_DMD_OPENOPTIONLIST, nullptr) == nullptr)
     162             :         {
     163           0 :             GTEST_SKIP() << "VRT driver Open() missing";
     164             :         }
     165             :     }
     166             : };
     167             : 
     168             : // Test constant parameters in a custom pixel function
     169           4 : TEST_F(test_gdal_pixelfn, custom_pixel_fn_constant_parameters)
     170             : {
     171           1 :     if (!GDALGetDriverByName("GTiff"))
     172             :     {
     173           0 :         GTEST_SKIP() << "GTiff driver missing";
     174             :     }
     175             : 
     176           1 :     GDALAddDerivedBandPixelFuncWithArgs("custom", CustomPixelFuncWithMetadata,
     177             :                                         pszFuncMetadata);
     178           1 :     GDALDatasetH ds = GDALOpen(src_.c_str(), GA_ReadOnly);
     179           1 :     ASSERT_TRUE(nullptr != ds);
     180             : 
     181           1 :     GDALRasterBandH band = GDALGetRasterBand(ds, 1);
     182           1 :     ASSERT_TRUE(nullptr != band);
     183             : 
     184             :     float buf[20 * 20];
     185           1 :     CPL_IGNORE_RET_VAL(GDALRasterIO(band, GF_Read, 0, 0, 20, 20, buf, 20, 20,
     186             :                                     GDT_Float32, 0, 0));
     187             : 
     188           1 :     EXPECT_EQ(buf[0], 107 * 2);
     189             : 
     190           1 :     GDALClose(ds);
     191             : }
     192             : 
     193             : // Test registering of a custom pixel function without metadata
     194           4 : TEST_F(test_gdal_pixelfn, custom_pixel_fn_without_metadata)
     195             : {
     196           1 :     if (!GDALGetDriverByName("GTiff"))
     197             :     {
     198           0 :         GTEST_SKIP() << "GTiff driver missing";
     199             :     }
     200             : 
     201           1 :     GDALAddDerivedBandPixelFuncWithArgs("custom2", CustomPixelFunc, nullptr);
     202           1 :     GDALDatasetH ds = GDALOpen(src_.c_str(), GA_ReadOnly);
     203           1 :     ASSERT_TRUE(nullptr != ds);
     204             : 
     205           1 :     GDALRasterBandH band = GDALGetRasterBand(ds, 1);
     206           1 :     ASSERT_TRUE(nullptr != band);
     207             : 
     208             :     VRTDerivedRasterBand *derived = reinterpret_cast<VRTDerivedRasterBand *>(
     209           1 :         GDALRasterBand::FromHandle(band));
     210           1 :     derived->SetPixelFunctionName("custom2");
     211             : 
     212             :     float buf[20 * 20];
     213           1 :     CPL_IGNORE_RET_VAL(GDALRasterIO(band, GF_Read, 0, 0, 20, 20, buf, 20, 20,
     214             :                                     GDT_Float32, 0, 0));
     215             : 
     216           1 :     EXPECT_EQ(buf[0], 107 * 3);
     217             : 
     218           1 :     GDALClose(ds);
     219             : }
     220             : 
     221             : // Test the registering of a custom pixel function without args
     222           4 : TEST_F(test_gdal_pixelfn, custom_pixel_fn_without_args)
     223             : {
     224           1 :     if (!GDALGetDriverByName("GTiff"))
     225             :     {
     226           0 :         GTEST_SKIP() << "GTiff driver missing";
     227             :     }
     228             : 
     229           1 :     GDALAddDerivedBandPixelFunc("custom3", CustomPixelFuncNoArgs);
     230           1 :     GDALDatasetH ds = GDALOpen(src_.c_str(), GA_ReadOnly);
     231           1 :     ASSERT_TRUE(nullptr != ds);
     232             : 
     233           1 :     GDALRasterBandH band = GDALGetRasterBand(ds, 1);
     234           1 :     ASSERT_TRUE(nullptr != band);
     235             : 
     236             :     VRTDerivedRasterBand *derived = reinterpret_cast<VRTDerivedRasterBand *>(
     237           1 :         GDALRasterBand::FromHandle(band));
     238           1 :     derived->SetPixelFunctionName("custom3");
     239             : 
     240             :     float buf[20 * 20];
     241           1 :     CPL_IGNORE_RET_VAL(GDALRasterIO(band, GF_Read, 0, 0, 20, 20, buf, 20, 20,
     242             :                                     GDT_Float32, 0, 0));
     243             : 
     244           1 :     EXPECT_EQ(buf[0], 107 * 4);
     245             : 
     246           1 :     GDALClose(ds);
     247             : }
     248             : 
     249             : }  // namespace

Generated by: LCOV version 1.14