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 : * Permission is hereby granted, free of charge, to any person obtaining a
11 : * copy of this software and associated documentation files (the "Software"),
12 : * to deal in the Software without restriction, including without limitation
13 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 : * and/or sell copies of the Software, and to permit persons to whom the
15 : * Software is furnished to do so, subject to the following conditions:
16 : *
17 : * The above copyright notice and this permission notice shall be included
18 : * in all copies or substantial portions of the Software.
19 : *
20 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 : * DEALINGS IN THE SOFTWARE.
27 : ****************************************************************************/
28 :
29 : #include "gdal_unit_test.h"
30 :
31 : #include "cpl_string.h"
32 : #include "gdal_alg.h"
33 : #include "gdal_priv.h"
34 : #include "gdal.h"
35 : #include "../../frmts/vrt/vrtdataset.h"
36 :
37 : #include <vector>
38 :
39 : #include "gtest_include.h"
40 :
41 : CPLErr CustomPixelFuncWithMetadata(void **papoSources, int nSources,
42 : void *pData, int nXSize, int nYSize,
43 : GDALDataType eSrcType, GDALDataType eBufType,
44 : int nPixelSpace, int nLineSpace,
45 : CSLConstList papszArgs);
46 : CPLErr CustomPixelFunc(void **papoSources, int nSources, void *pData,
47 : int nXSize, int nYSize, GDALDataType eSrcType,
48 : GDALDataType eBufType, int nPixelSpace, int nLineSpace,
49 : CSLConstList papszArgs);
50 : CPLErr CustomPixelFuncNoArgs(void **papoSources, int nSources, void *pData,
51 : int nXSize, int nYSize, GDALDataType eSrcType,
52 : GDALDataType eBufType, int nPixelSpace,
53 : int nLineSpace);
54 :
55 1 : CPLErr CustomPixelFuncWithMetadata(void **papoSources, int nSources,
56 : void *pData, int nXSize, int nYSize,
57 : GDALDataType eSrcType, GDALDataType eBufType,
58 : int nPixelSpace, int nLineSpace,
59 : CSLConstList papszArgs)
60 : {
61 :
62 : /* ---- Init ---- */
63 1 : if (nSources != 1)
64 0 : return CE_Failure;
65 1 : const char *pszConstant = CSLFetchNameValue(papszArgs, "customConstant");
66 1 : if (pszConstant == nullptr)
67 0 : return CE_Failure;
68 1 : if (strncmp(pszConstant, "something", strlen("something")))
69 0 : return CE_Failure;
70 1 : const char *pszScale = CSLFetchNameValue(papszArgs, "scale");
71 1 : if (pszScale == nullptr)
72 0 : return CE_Failure;
73 :
74 : /* ---- Set pixels ---- */
75 1 : size_t ii = 0;
76 21 : for (int iLine = 0; iLine < nYSize; ++iLine)
77 : {
78 420 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
79 : {
80 400 : const double dfPixVal = SRCVAL(papoSources[0], eSrcType, ii) * 2;
81 400 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
82 : static_cast<GByte *>(pData) +
83 400 : static_cast<GSpacing>(nLineSpace) * iLine +
84 400 : iCol * nPixelSpace,
85 : eBufType, nPixelSpace, 1);
86 : }
87 : }
88 :
89 : /* ---- Return success ---- */
90 1 : return CE_None;
91 : }
92 :
93 1 : CPLErr CustomPixelFunc(void **papoSources, int nSources, void *pData,
94 : int nXSize, int nYSize, GDALDataType eSrcType,
95 : GDALDataType eBufType, int nPixelSpace, int nLineSpace,
96 : CSLConstList papszArgs)
97 : {
98 :
99 : /* ---- Init ---- */
100 1 : if (nSources != 1)
101 0 : return CE_Failure;
102 :
103 : (void)papszArgs;
104 :
105 : /* ---- Set pixels ---- */
106 1 : size_t ii = 0;
107 21 : for (int iLine = 0; iLine < nYSize; ++iLine)
108 : {
109 420 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
110 : {
111 400 : const double dfPixVal = SRCVAL(papoSources[0], eSrcType, ii) * 3;
112 400 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
113 : static_cast<GByte *>(pData) +
114 400 : static_cast<GSpacing>(nLineSpace) * iLine +
115 400 : iCol * nPixelSpace,
116 : eBufType, nPixelSpace, 1);
117 : }
118 : }
119 :
120 : /* ---- Return success ---- */
121 1 : return CE_None;
122 : }
123 :
124 1 : CPLErr CustomPixelFuncNoArgs(void **papoSources, int nSources, void *pData,
125 : int nXSize, int nYSize, GDALDataType eSrcType,
126 : GDALDataType eBufType, int nPixelSpace,
127 : int nLineSpace)
128 : {
129 :
130 : /* ---- Init ---- */
131 1 : if (nSources != 1)
132 0 : return CE_Failure;
133 :
134 : /* ---- Set pixels ---- */
135 1 : size_t ii = 0;
136 21 : for (int iLine = 0; iLine < nYSize; ++iLine)
137 : {
138 420 : for (int iCol = 0; iCol < nXSize; ++iCol, ++ii)
139 : {
140 400 : const double dfPixVal = SRCVAL(papoSources[0], eSrcType, ii) * 4;
141 400 : GDALCopyWords(&dfPixVal, GDT_Float64, 0,
142 : static_cast<GByte *>(pData) +
143 400 : static_cast<GSpacing>(nLineSpace) * iLine +
144 400 : iCol * nPixelSpace,
145 : eBufType, nPixelSpace, 1);
146 : }
147 : }
148 :
149 : /* ---- Return success ---- */
150 1 : return CE_None;
151 : }
152 :
153 : namespace
154 : {
155 : const char pszFuncMetadata[] =
156 : "<PixelFunctionArgumentsList>"
157 : " <Argument name='customConstant' type='constant' value='something'>"
158 : " </Argument>"
159 : " <Argument type='builtin' value='scale'>"
160 : " </Argument>"
161 : "</PixelFunctionArgumentsList>";
162 :
163 : struct test_gdal_pixelfn : public ::testing::Test
164 : {
165 : std::string src_;
166 :
167 3 : test_gdal_pixelfn()
168 3 : {
169 3 : src_ = tut::common::data_basedir;
170 3 : src_ += SEP;
171 3 : src_ += "pixelfn.vrt";
172 3 : }
173 : };
174 :
175 : // Test constant parameters in a custom pixel function
176 4 : TEST_F(test_gdal_pixelfn, custom_pixel_fn_constant_parameters)
177 : {
178 1 : GDALAddDerivedBandPixelFuncWithArgs("custom", CustomPixelFuncWithMetadata,
179 : pszFuncMetadata);
180 1 : GDALDatasetH ds = GDALOpen(src_.c_str(), GA_ReadOnly);
181 1 : ASSERT_TRUE(nullptr != ds);
182 :
183 1 : GDALRasterBandH band = GDALGetRasterBand(ds, 1);
184 1 : ASSERT_TRUE(nullptr != band);
185 :
186 : float buf[20 * 20];
187 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(band, GF_Read, 0, 0, 20, 20, buf, 20, 20,
188 : GDT_Float32, 0, 0));
189 :
190 1 : EXPECT_EQ(buf[0], 107 * 2);
191 :
192 1 : GDALClose(ds);
193 : }
194 :
195 : // Test registering of a custom pixel function without metadata
196 4 : TEST_F(test_gdal_pixelfn, custom_pixel_fn_without_metadata)
197 : {
198 1 : GDALAddDerivedBandPixelFuncWithArgs("custom2", CustomPixelFunc, nullptr);
199 1 : GDALDatasetH ds = GDALOpen(src_.c_str(), GA_ReadOnly);
200 1 : ASSERT_TRUE(nullptr != ds);
201 :
202 1 : GDALRasterBandH band = GDALGetRasterBand(ds, 1);
203 1 : ASSERT_TRUE(nullptr != band);
204 :
205 : VRTDerivedRasterBand *derived = reinterpret_cast<VRTDerivedRasterBand *>(
206 1 : GDALRasterBand::FromHandle(band));
207 1 : derived->SetPixelFunctionName("custom2");
208 :
209 : float buf[20 * 20];
210 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(band, GF_Read, 0, 0, 20, 20, buf, 20, 20,
211 : GDT_Float32, 0, 0));
212 :
213 1 : EXPECT_EQ(buf[0], 107 * 3);
214 :
215 1 : GDALClose(ds);
216 : }
217 :
218 : // Test the registering of a custom pixel function without args
219 4 : TEST_F(test_gdal_pixelfn, custom_pixel_fn_without_args)
220 : {
221 1 : GDALAddDerivedBandPixelFunc("custom3", CustomPixelFuncNoArgs);
222 1 : GDALDatasetH ds = GDALOpen(src_.c_str(), GA_ReadOnly);
223 1 : ASSERT_TRUE(nullptr != ds);
224 :
225 1 : GDALRasterBandH band = GDALGetRasterBand(ds, 1);
226 1 : ASSERT_TRUE(nullptr != band);
227 :
228 : VRTDerivedRasterBand *derived = reinterpret_cast<VRTDerivedRasterBand *>(
229 1 : GDALRasterBand::FromHandle(band));
230 1 : derived->SetPixelFunctionName("custom3");
231 :
232 : float buf[20 * 20];
233 1 : CPL_IGNORE_RET_VAL(GDALRasterIO(band, GF_Read, 0, 0, 20, 20, buf, 20, 20,
234 : GDT_Float32, 0, 0));
235 :
236 1 : EXPECT_EQ(buf[0], 107 * 4);
237 :
238 1 : GDALClose(ds);
239 : }
240 :
241 : } // namespace
|