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
|