Line data Source code
1 : ///////////////////////////////////////////////////////////////////////////////
2 : //
3 : // Project: C++ Test Suite for GDAL/OGR
4 : // Purpose: Test general GDAL features.
5 : // Author: Mateusz Loskot <mateusz@loskot.net>
6 : //
7 : ///////////////////////////////////////////////////////////////////////////////
8 : // Copyright (c) 2006, Mateusz Loskot <mateusz@loskot.net>
9 : /*
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #include "gdal_unit_test.h"
14 :
15 : #include "gdal_alg.h"
16 : #include "gdal_priv.h"
17 : #include "gdal_utils.h"
18 : #include "gdal_priv_templates.hpp"
19 : #include "gdal.h"
20 : #include "tilematrixset.hpp"
21 : #include "gdalcachedpixelaccessor.h"
22 : #include "memdataset.h"
23 :
24 : #include <algorithm>
25 : #include <array>
26 : #include <limits>
27 : #include <string>
28 :
29 : #include "test_data.h"
30 :
31 : #include "gtest_include.h"
32 :
33 : namespace
34 : {
35 : // Common fixture with test data
36 : struct test_gdal : public ::testing::Test
37 : {
38 : };
39 :
40 : // Test GDAL driver manager access
41 4 : TEST_F(test_gdal, driver_manager)
42 : {
43 1 : GDALDriverManager *drv_mgr = nullptr;
44 1 : drv_mgr = GetGDALDriverManager();
45 1 : ASSERT_TRUE(nullptr != drv_mgr);
46 : }
47 :
48 : // Test that GDALRegisterPlugins can be called
49 4 : TEST_F(test_gdal, register_plugins)
50 : {
51 1 : GDALRegisterPlugins();
52 1 : }
53 :
54 : // Test that GDALRegisterPlugin can be called and returns an error for a non
55 : // existing plugin name
56 4 : TEST_F(test_gdal, register_plugin)
57 : {
58 1 : ASSERT_EQ(GDALRegisterPlugin("rtbreg_non_existing_plugin"), CE_Failure);
59 : }
60 :
61 : // Test number of registered GDAL drivers
62 4 : TEST_F(test_gdal, number_of_registered_drivers)
63 : {
64 : #ifdef WIN32CE
65 : ASSERT_EQ(GDALGetDriverCount(), drv_count_);
66 : #endif
67 1 : }
68 :
69 : // Test if AAIGrid driver is registered
70 4 : TEST_F(test_gdal, aaigrid_is_registered)
71 : {
72 1 : GDALDriverH drv = GDALGetDriverByName("AAIGrid");
73 :
74 : #ifdef FRMT_aaigrid
75 : ASSERT_TRUE(NULL != drv);
76 : #else
77 : (void)drv;
78 : #endif
79 1 : }
80 :
81 : // Test if DTED driver is registered
82 4 : TEST_F(test_gdal, dted_is_registered)
83 : {
84 1 : GDALDriverH drv = GDALGetDriverByName("DTED");
85 :
86 : #ifdef FRMT_dted
87 : ASSERT_TRUE(NULL != drv);
88 : #else
89 : (void)drv;
90 : #endif
91 1 : }
92 :
93 : // Test if GeoTIFF driver is registered
94 4 : TEST_F(test_gdal, gtiff_is_registered)
95 : {
96 1 : GDALDriverH drv = GDALGetDriverByName("GTiff");
97 :
98 : #ifdef FRMT_gtiff
99 : ASSERT_TRUE(NULL != drv);
100 : #else
101 : (void)drv;
102 : #endif
103 1 : }
104 :
105 : class DataTypeTupleFixture : public test_gdal,
106 : public ::testing::WithParamInterface<
107 : std::tuple<GDALDataType, GDALDataType>>
108 : {
109 : public:
110 1 : static std::vector<std::tuple<GDALDataType, GDALDataType>> GetTupleValues()
111 : {
112 1 : std::vector<std::tuple<GDALDataType, GDALDataType>> ret;
113 17 : for (GDALDataType eIn = GDT_Byte; eIn < GDT_TypeCount;
114 16 : eIn = static_cast<GDALDataType>(eIn + 1))
115 : {
116 272 : for (GDALDataType eOut = GDT_Byte; eOut < GDT_TypeCount;
117 256 : eOut = static_cast<GDALDataType>(eOut + 1))
118 : {
119 256 : ret.emplace_back(std::make_tuple(eIn, eOut));
120 : }
121 : }
122 1 : return ret;
123 : }
124 : };
125 :
126 : // Test GDALDataTypeUnion() on all (GDALDataType, GDALDataType) combinations
127 513 : TEST_P(DataTypeTupleFixture, GDALDataTypeUnion_generic)
128 : {
129 256 : GDALDataType eDT1 = std::get<0>(GetParam());
130 256 : GDALDataType eDT2 = std::get<1>(GetParam());
131 256 : GDALDataType eDT = GDALDataTypeUnion(eDT1, eDT2);
132 256 : EXPECT_EQ(eDT, GDALDataTypeUnion(eDT2, eDT1));
133 256 : EXPECT_GE(GDALGetDataTypeSize(eDT), GDALGetDataTypeSize(eDT1));
134 256 : EXPECT_GE(GDALGetDataTypeSize(eDT), GDALGetDataTypeSize(eDT2));
135 256 : EXPECT_TRUE((GDALDataTypeIsComplex(eDT) && (GDALDataTypeIsComplex(eDT1) ||
136 : GDALDataTypeIsComplex(eDT2))) ||
137 : (!GDALDataTypeIsComplex(eDT) && !GDALDataTypeIsComplex(eDT1) &&
138 : !GDALDataTypeIsComplex(eDT2)));
139 :
140 256 : EXPECT_TRUE(
141 : !(GDALDataTypeIsFloating(eDT1) || GDALDataTypeIsFloating(eDT2)) ||
142 : GDALDataTypeIsFloating(eDT));
143 256 : EXPECT_TRUE(!(GDALDataTypeIsSigned(eDT1) || GDALDataTypeIsSigned(eDT2)) ||
144 : GDALDataTypeIsSigned(eDT));
145 256 : }
146 :
147 770 : INSTANTIATE_TEST_SUITE_P(
148 : test_gdal, DataTypeTupleFixture,
149 : ::testing::ValuesIn(DataTypeTupleFixture::GetTupleValues()),
150 : [](const ::testing::TestParamInfo<DataTypeTupleFixture::ParamType> &l_info)
151 : {
152 : GDALDataType eDT1 = std::get<0>(l_info.param);
153 : GDALDataType eDT2 = std::get<1>(l_info.param);
154 : return std::string(GDALGetDataTypeName(eDT1)) + "_" +
155 : GDALGetDataTypeName(eDT2);
156 : });
157 :
158 : // Test GDALDataTypeUnion()
159 4 : TEST_F(test_gdal, GDALDataTypeUnion_special_cases)
160 : {
161 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Byte, GDT_CInt16), GDT_CInt16);
162 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Byte, GDT_CInt32), GDT_CInt32);
163 : // special case (should be GDT_CFloat16)
164 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Byte, GDT_CFloat16), GDT_CFloat32);
165 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Byte, GDT_CFloat32), GDT_CFloat32);
166 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Byte, GDT_CFloat64), GDT_CFloat64);
167 :
168 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_UInt16, GDT_CInt16), GDT_CInt32);
169 :
170 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Int16, GDT_UInt16), GDT_Int32);
171 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Int16, GDT_UInt32), GDT_Int64);
172 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_UInt32, GDT_Int16), GDT_Int64);
173 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Int64, GDT_UInt64), GDT_Float64);
174 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Int64, GDT_Float16), GDT_Float64);
175 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Int64, GDT_Float32), GDT_Float64);
176 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Int64, GDT_Float64), GDT_Float64);
177 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_UInt64, GDT_Float16), GDT_Float64);
178 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_UInt64, GDT_Float32), GDT_Float64);
179 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_UInt64, GDT_Float64), GDT_Float64);
180 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_UInt32, GDT_CInt16), GDT_CFloat64);
181 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Float16, GDT_CInt32), GDT_CFloat64);
182 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Float32, GDT_CInt32), GDT_CFloat64);
183 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt16, GDT_UInt32), GDT_CFloat64);
184 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt16, GDT_CFloat16), GDT_CFloat32);
185 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt16, GDT_CFloat32), GDT_CFloat32);
186 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_Byte), GDT_CInt32);
187 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_UInt16), GDT_CInt32);
188 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_Int16), GDT_CInt32);
189 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_UInt32), GDT_CFloat64);
190 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_Int32), GDT_CInt32);
191 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_Float32), GDT_CFloat64);
192 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_CInt16), GDT_CInt32);
193 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_CFloat32), GDT_CFloat64);
194 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat16, GDT_Byte), GDT_CFloat32);
195 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat16, GDT_UInt16), GDT_CFloat32);
196 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat16, GDT_Int16), GDT_CFloat32);
197 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat16, GDT_UInt32), GDT_CFloat64);
198 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat16, GDT_Int32), GDT_CFloat64);
199 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat16, GDT_Float32), GDT_CFloat32);
200 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat16, GDT_CInt16), GDT_CFloat32);
201 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat16, GDT_CInt32), GDT_CFloat64);
202 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_Byte), GDT_CFloat32);
203 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_UInt16), GDT_CFloat32);
204 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_Int16), GDT_CFloat32);
205 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_UInt32), GDT_CFloat64);
206 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_Int32), GDT_CFloat64);
207 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_Float32), GDT_CFloat32);
208 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_CInt16), GDT_CFloat32);
209 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_CInt32), GDT_CFloat64);
210 :
211 : // Define brief abbreviations to make calls to `GDALFindDataType`
212 : // more legible
213 1 : const bool u = false, s = true; // signed
214 1 : const bool i = false, f = true; // floating
215 1 : const bool r = false, c = true; // complex
216 :
217 1 : EXPECT_EQ(GDALFindDataType(0, u, i, r), GDT_Byte);
218 1 : EXPECT_EQ(GDALFindDataType(0, s, i, r), GDT_Int8);
219 1 : EXPECT_EQ(GDALFindDataType(0, u, i, c), GDT_CInt32);
220 1 : EXPECT_EQ(GDALFindDataType(0, s, i, c), GDT_CInt16);
221 1 : EXPECT_EQ(GDALFindDataType(0, u, f, r), GDT_Float32);
222 1 : EXPECT_EQ(GDALFindDataType(0, s, f, r), GDT_Float32);
223 1 : EXPECT_EQ(GDALFindDataType(0, u, f, c), GDT_CFloat32);
224 1 : EXPECT_EQ(GDALFindDataType(0, s, f, c), GDT_CFloat32);
225 :
226 1 : EXPECT_EQ(GDALFindDataType(8, u, i, r), GDT_Byte);
227 1 : EXPECT_EQ(GDALFindDataType(8, s, i, r), GDT_Int8);
228 :
229 1 : EXPECT_EQ(GDALFindDataType(16, u, f, r), GDT_Float32);
230 1 : EXPECT_EQ(GDALFindDataType(16, u, f, c), GDT_CFloat32);
231 :
232 1 : EXPECT_EQ(GDALFindDataType(16, u, i, r), GDT_UInt16);
233 1 : EXPECT_EQ(GDALFindDataType(16, s, i, r), GDT_Int16);
234 :
235 1 : EXPECT_EQ(GDALFindDataType(32, u, f, r), GDT_Float32);
236 1 : EXPECT_EQ(GDALFindDataType(32, u, f, c), GDT_CFloat32);
237 :
238 1 : EXPECT_EQ(GDALFindDataType(32, u, i, r), GDT_UInt32);
239 1 : EXPECT_EQ(GDALFindDataType(32, s, i, r), GDT_Int32);
240 :
241 1 : EXPECT_EQ(GDALFindDataType(64, u, f, r), GDT_Float64);
242 1 : EXPECT_EQ(GDALFindDataType(64, u, f, c), GDT_CFloat64);
243 :
244 1 : EXPECT_EQ(GDALFindDataType(64, u, i, r), GDT_UInt64);
245 1 : EXPECT_EQ(GDALFindDataType(64, s, i, r), GDT_Int64);
246 :
247 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Byte, -128, false), GDT_Int16);
248 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Byte, -32768, false), GDT_Int16);
249 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Byte, -32769, false), GDT_Int32);
250 :
251 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Int8, 127, false), GDT_Int8);
252 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Int8, 128, false), GDT_Int16);
253 :
254 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Int16, 32767, false), GDT_Int16);
255 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Int16, 32768, false), GDT_Int32);
256 :
257 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_UInt16, 65535, false), GDT_UInt16);
258 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_UInt16, 65536, false), GDT_UInt32);
259 :
260 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Int32, INT32_MAX, false),
261 : GDT_Int32);
262 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Int32, INT32_MAX + 1.0, false),
263 : GDT_Int64);
264 :
265 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_UInt32, UINT32_MAX, false),
266 : GDT_UInt32);
267 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_UInt32, UINT32_MAX + 1.0, false),
268 : GDT_UInt64);
269 :
270 : // (1 << 63) - 1024
271 1 : EXPECT_EQ(
272 : GDALDataTypeUnionWithValue(GDT_Int64, 9223372036854774784.0, false),
273 : GDT_Int64);
274 : // (1 << 63) - 512
275 1 : EXPECT_EQ(
276 : GDALDataTypeUnionWithValue(GDT_Int64, 9223372036854775296.0, false),
277 : GDT_Float64);
278 :
279 : // (1 << 64) - 2048
280 1 : EXPECT_EQ(
281 : GDALDataTypeUnionWithValue(GDT_UInt64, 18446744073709549568.0, false),
282 : GDT_UInt64);
283 : // (1 << 64) + 4096
284 1 : EXPECT_EQ(
285 : GDALDataTypeUnionWithValue(GDT_UInt64, 18446744073709555712.0, false),
286 : GDT_Float64);
287 :
288 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Float16, -999, false),
289 : GDT_Float32);
290 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Float16, -99999, false),
291 : GDT_Float32);
292 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Float16, -99999.9876, false),
293 : GDT_Float64);
294 :
295 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Float32, -99999, false),
296 : GDT_Float32);
297 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Float32, -99999.9876, false),
298 : GDT_Float64);
299 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(
300 : GDT_Float32, cpl::NumericLimits<double>::quiet_NaN(), false),
301 : GDT_Float32);
302 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(
303 : GDT_Float32, -cpl::NumericLimits<double>::infinity(), false),
304 : GDT_Float32);
305 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(
306 : GDT_Float32, -cpl::NumericLimits<double>::infinity(), false),
307 : GDT_Float32);
308 :
309 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Float64, -99999.9876, false),
310 : GDT_Float64);
311 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(
312 : GDT_Float64, cpl::NumericLimits<double>::quiet_NaN(), false),
313 : GDT_Float64);
314 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(
315 : GDT_Float64, -cpl::NumericLimits<double>::infinity(), false),
316 : GDT_Float64);
317 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(
318 : GDT_Float64, -cpl::NumericLimits<double>::infinity(), false),
319 : GDT_Float64);
320 :
321 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Unknown, 0, false), GDT_Byte);
322 1 : }
323 :
324 : // Test GDALAdjustValueToDataType()
325 4 : TEST_F(test_gdal, GDALAdjustValueToDataType)
326 : {
327 : int bClamped, bRounded;
328 :
329 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Byte, 255.0, nullptr, nullptr) ==
330 : 255.0);
331 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Byte, 255.0, &bClamped,
332 : &bRounded) == 255.0 &&
333 : !bClamped && !bRounded);
334 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Byte, 254.4, &bClamped,
335 : &bRounded) == 254.0 &&
336 : !bClamped && bRounded);
337 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Byte, -1, &bClamped, &bRounded) ==
338 : 0.0 &&
339 : bClamped && !bRounded);
340 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Byte, 256.0, &bClamped,
341 : &bRounded) == 255.0 &&
342 : bClamped && !bRounded);
343 :
344 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int8, -128.0, &bClamped,
345 : &bRounded) == -128.0 &&
346 : !bClamped && !bRounded);
347 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int8, 127.0, &bClamped,
348 : &bRounded) == 127.0 &&
349 : !bClamped && !bRounded);
350 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int8, -127.4, &bClamped,
351 : &bRounded) == -127.0 &&
352 : !bClamped && bRounded);
353 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int8, 126.4, &bClamped,
354 : &bRounded) == 126.0 &&
355 : !bClamped && bRounded);
356 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int8, -129.0, &bClamped,
357 : &bRounded) == -128.0 &&
358 : bClamped && !bRounded);
359 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int8, 128.0, &bClamped,
360 : &bRounded) == 127.0 &&
361 : bClamped && !bRounded);
362 :
363 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt16, 65535.0, &bClamped,
364 : &bRounded) == 65535.0 &&
365 : !bClamped && !bRounded);
366 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt16, 65534.4, &bClamped,
367 : &bRounded) == 65534.0 &&
368 : !bClamped && bRounded);
369 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt16, -1, &bClamped,
370 : &bRounded) == 0.0 &&
371 : bClamped && !bRounded);
372 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt16, 65536.0, &bClamped,
373 : &bRounded) == 65535.0 &&
374 : bClamped && !bRounded);
375 :
376 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int16, -32768.0, &bClamped,
377 : &bRounded) == -32768.0 &&
378 : !bClamped && !bRounded);
379 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int16, 32767.0, &bClamped,
380 : &bRounded) == 32767.0 &&
381 : !bClamped && !bRounded);
382 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int16, -32767.4, &bClamped,
383 : &bRounded) == -32767.0 &&
384 : !bClamped && bRounded);
385 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int16, 32766.4, &bClamped,
386 : &bRounded) == 32766.0 &&
387 : !bClamped && bRounded);
388 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int16, -32769.0, &bClamped,
389 : &bRounded) == -32768.0 &&
390 : bClamped && !bRounded);
391 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int16, 32768.0, &bClamped,
392 : &bRounded) == 32767.0 &&
393 : bClamped && !bRounded);
394 :
395 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt32, 10000000.0, &bClamped,
396 : &bRounded) == 10000000.0 &&
397 : !bClamped && !bRounded);
398 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt32, 10000000.4, &bClamped,
399 : &bRounded) == 10000000.0 &&
400 : !bClamped && bRounded);
401 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt32, -1, &bClamped,
402 : &bRounded) == 0.0 &&
403 : bClamped && !bRounded);
404 :
405 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int32, -10000000.0, &bClamped,
406 : &bRounded) == -10000000.0 &&
407 : !bClamped && !bRounded);
408 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int32, 10000000.0, &bClamped,
409 : &bRounded) == 10000000.0 &&
410 : !bClamped && !bRounded);
411 :
412 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt64, 10000000000.0, &bClamped,
413 : &bRounded) == 10000000000.0 &&
414 : !bClamped && !bRounded);
415 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt64, 10000000000.4, &bClamped,
416 : &bRounded) == 10000000000.0 &&
417 : !bClamped && bRounded);
418 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt64, -1, &bClamped,
419 : &bRounded) == 0.0 &&
420 : bClamped && !bRounded);
421 :
422 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int64, -10000000000.0, &bClamped,
423 : &bRounded) == -10000000000.0 &&
424 : !bClamped && !bRounded);
425 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int64, 10000000000.0, &bClamped,
426 : &bRounded) == 10000000000.0 &&
427 : !bClamped && !bRounded);
428 :
429 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float16, 0.0, &bClamped,
430 : &bRounded) == 0.0 &&
431 : !bClamped && !bRounded);
432 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float16, 1e-10, &bClamped,
433 : &bRounded) == 0.0 &&
434 : !bClamped && !bRounded);
435 1 : EXPECT_TRUE(
436 : GDALAdjustValueToDataType(GDT_Float16, 1.23, &bClamped, &bRounded) ==
437 : static_cast<double>(static_cast<GFloat16>(1.23f)) &&
438 : !bClamped && !bRounded);
439 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float16, -1e300, &bClamped,
440 : &bRounded) == -65504 &&
441 : bClamped && !bRounded);
442 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float16, 1e30, &bClamped,
443 : &bRounded) == 65504 &&
444 : bClamped && !bRounded);
445 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float16,
446 : cpl::NumericLimits<float>::infinity(),
447 : &bClamped, &bRounded) ==
448 : cpl::NumericLimits<float>::infinity() &&
449 : !bClamped && !bRounded);
450 1 : EXPECT_TRUE(GDALAdjustValueToDataType(
451 : GDT_Float16, -cpl::NumericLimits<float>::infinity(),
452 : &bClamped,
453 : &bRounded) == -cpl::NumericLimits<float>::infinity() &&
454 : !bClamped && !bRounded);
455 : {
456 1 : double dfNan = cpl::NumericLimits<double>::quiet_NaN();
457 : double dfGot =
458 1 : GDALAdjustValueToDataType(GDT_Float16, dfNan, &bClamped, &bRounded);
459 1 : EXPECT_TRUE(memcmp(&dfNan, &dfGot, sizeof(double)) == 0 && !bClamped &&
460 : !bRounded);
461 : }
462 :
463 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float32, 0.0, &bClamped,
464 : &bRounded) == 0.0 &&
465 : !bClamped && !bRounded);
466 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float32, 1e-50, &bClamped,
467 : &bRounded) == 0.0 &&
468 : !bClamped && !bRounded);
469 1 : EXPECT_TRUE(
470 : GDALAdjustValueToDataType(GDT_Float32, 1.23, &bClamped, &bRounded) ==
471 : static_cast<double>(1.23f) &&
472 : !bClamped && !bRounded);
473 1 : EXPECT_TRUE(
474 : GDALAdjustValueToDataType(GDT_Float32, -1e300, &bClamped, &bRounded) ==
475 : -cpl::NumericLimits<float>::max() &&
476 : bClamped && !bRounded);
477 1 : EXPECT_TRUE(
478 : GDALAdjustValueToDataType(GDT_Float32, 1e300, &bClamped, &bRounded) ==
479 : cpl::NumericLimits<float>::max() &&
480 : bClamped && !bRounded);
481 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float32,
482 : cpl::NumericLimits<float>::infinity(),
483 : &bClamped, &bRounded) ==
484 : cpl::NumericLimits<float>::infinity() &&
485 : !bClamped && !bRounded);
486 1 : EXPECT_TRUE(GDALAdjustValueToDataType(
487 : GDT_Float32, -cpl::NumericLimits<float>::infinity(),
488 : &bClamped,
489 : &bRounded) == -cpl::NumericLimits<float>::infinity() &&
490 : !bClamped && !bRounded);
491 : {
492 1 : double dfNan = cpl::NumericLimits<double>::quiet_NaN();
493 : double dfGot =
494 1 : GDALAdjustValueToDataType(GDT_Float32, dfNan, &bClamped, &bRounded);
495 1 : EXPECT_TRUE(memcmp(&dfNan, &dfGot, sizeof(double)) == 0 && !bClamped &&
496 : !bRounded);
497 : }
498 :
499 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float64, 0.0, &bClamped,
500 : &bRounded) == 0.0 &&
501 : !bClamped && !bRounded);
502 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float64, 1e-50, &bClamped,
503 : &bRounded) == 1e-50 &&
504 : !bClamped && !bRounded);
505 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float64, -1e40, &bClamped,
506 : &bRounded) == -1e40 &&
507 : !bClamped && !bRounded);
508 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float64, 1e40, &bClamped,
509 : &bRounded) == 1e40 &&
510 : !bClamped && !bRounded);
511 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float64,
512 : cpl::NumericLimits<float>::infinity(),
513 : &bClamped, &bRounded) ==
514 : cpl::NumericLimits<float>::infinity() &&
515 : !bClamped && !bRounded);
516 1 : EXPECT_TRUE(GDALAdjustValueToDataType(
517 : GDT_Float64, -cpl::NumericLimits<float>::infinity(),
518 : &bClamped,
519 : &bRounded) == -cpl::NumericLimits<float>::infinity() &&
520 : !bClamped && !bRounded);
521 : {
522 1 : double dfNan = cpl::NumericLimits<double>::quiet_NaN();
523 : double dfGot =
524 1 : GDALAdjustValueToDataType(GDT_Float64, dfNan, &bClamped, &bRounded);
525 1 : EXPECT_TRUE(memcmp(&dfNan, &dfGot, sizeof(double)) == 0 && !bClamped &&
526 : !bRounded);
527 : }
528 1 : }
529 :
530 : class FakeBand : public GDALRasterBand
531 : {
532 : protected:
533 0 : virtual CPLErr IReadBlock(int, int, void *) override
534 : {
535 0 : return CE_None;
536 : }
537 :
538 1 : virtual CPLErr IWriteBlock(int, int, void *) override
539 : {
540 1 : return CE_None;
541 : }
542 :
543 : public:
544 1 : FakeBand(int nXSize, int nYSize)
545 1 : {
546 1 : nBlockXSize = nXSize;
547 1 : nBlockYSize = nYSize;
548 1 : }
549 : };
550 :
551 : class DatasetWithErrorInFlushCache : public GDALDataset
552 : {
553 : bool bHasFlushCache;
554 :
555 : public:
556 2 : DatasetWithErrorInFlushCache() : bHasFlushCache(false)
557 : {
558 2 : }
559 :
560 4 : ~DatasetWithErrorInFlushCache()
561 2 : {
562 2 : FlushCache(true);
563 4 : }
564 :
565 4 : virtual CPLErr FlushCache(bool bAtClosing) override
566 : {
567 4 : CPLErr eErr = CE_None;
568 4 : if (!bHasFlushCache)
569 : {
570 2 : CPLError(CE_Failure, CPLE_AppDefined, "some error");
571 2 : eErr = CE_Failure;
572 : }
573 4 : if (GDALDataset::FlushCache(bAtClosing) != CE_None)
574 0 : eErr = CE_Failure;
575 4 : bHasFlushCache = true;
576 4 : return eErr;
577 : }
578 :
579 1 : CPLErr SetSpatialRef(const OGRSpatialReference *) override
580 : {
581 1 : return CE_None;
582 : }
583 :
584 1 : virtual CPLErr SetGeoTransform(const GDALGeoTransform &) override
585 : {
586 1 : return CE_None;
587 : }
588 :
589 1 : static GDALDataset *CreateCopy(const char *, GDALDataset *, int, char **,
590 : GDALProgressFunc, void *)
591 : {
592 1 : return new DatasetWithErrorInFlushCache();
593 : }
594 :
595 1 : static GDALDataset *Create(const char *, int nXSize, int nYSize, int,
596 : GDALDataType, char **)
597 : {
598 1 : DatasetWithErrorInFlushCache *poDS = new DatasetWithErrorInFlushCache();
599 1 : poDS->eAccess = GA_Update;
600 1 : poDS->nRasterXSize = nXSize;
601 1 : poDS->nRasterYSize = nYSize;
602 1 : poDS->SetBand(1, new FakeBand(nXSize, nYSize));
603 1 : return poDS;
604 : }
605 : };
606 :
607 : // Test that GDALTranslate() detects error in flush cache
608 4 : TEST_F(test_gdal, GDALTranslate_error_flush_cache)
609 : {
610 1 : GDALDriver *poDriver = new GDALDriver();
611 1 : poDriver->SetDescription("DatasetWithErrorInFlushCache");
612 1 : poDriver->pfnCreateCopy = DatasetWithErrorInFlushCache::CreateCopy;
613 1 : GetGDALDriverManager()->RegisterDriver(poDriver);
614 1 : const char *args[] = {"-of", "DatasetWithErrorInFlushCache", nullptr};
615 : GDALTranslateOptions *psOptions =
616 1 : GDALTranslateOptionsNew((char **)args, nullptr);
617 1 : GDALDatasetH hSrcDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
618 1 : CPLErrorReset();
619 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
620 1 : GDALDatasetH hOutDS = GDALTranslate("", hSrcDS, psOptions, nullptr);
621 1 : CPLPopErrorHandler();
622 1 : GDALClose(hSrcDS);
623 1 : GDALTranslateOptionsFree(psOptions);
624 1 : EXPECT_TRUE(hOutDS == nullptr);
625 1 : EXPECT_TRUE(CPLGetLastErrorType() != CE_None);
626 1 : GetGDALDriverManager()->DeregisterDriver(poDriver);
627 1 : delete poDriver;
628 1 : }
629 :
630 : // Test that GDALWarp() detects error in flush cache
631 4 : TEST_F(test_gdal, GDALWarp_error_flush_cache)
632 : {
633 1 : GDALDriver *poDriver = new GDALDriver();
634 1 : poDriver->SetDescription("DatasetWithErrorInFlushCache");
635 1 : poDriver->pfnCreate = DatasetWithErrorInFlushCache::Create;
636 1 : GetGDALDriverManager()->RegisterDriver(poDriver);
637 1 : const char *args[] = {"-of", "DatasetWithErrorInFlushCache", nullptr};
638 : GDALWarpAppOptions *psOptions =
639 1 : GDALWarpAppOptionsNew((char **)args, nullptr);
640 1 : GDALDatasetH hSrcDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
641 1 : CPLErrorReset();
642 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
643 : GDALDatasetH hOutDS =
644 1 : GDALWarp("/", nullptr, 1, &hSrcDS, psOptions, nullptr);
645 1 : CPLPopErrorHandler();
646 1 : GDALClose(hSrcDS);
647 1 : GDALWarpAppOptionsFree(psOptions);
648 1 : EXPECT_TRUE(hOutDS == nullptr);
649 1 : EXPECT_TRUE(CPLGetLastErrorType() != CE_None);
650 1 : GetGDALDriverManager()->DeregisterDriver(poDriver);
651 1 : delete poDriver;
652 1 : }
653 :
654 : // Test GDALWarp() to VRT and that we can call GDALReleaseDataset() on the
655 : // source dataset when we want.
656 4 : TEST_F(test_gdal, GDALWarp_VRT)
657 : {
658 1 : auto hDrv = GDALGetDriverByName("GTiff");
659 1 : if (!hDrv)
660 : {
661 0 : GTEST_SKIP() << "GTiff driver missing";
662 : }
663 1 : const char *args[] = {"-of", "VRT", nullptr};
664 : GDALWarpAppOptions *psOptions =
665 1 : GDALWarpAppOptionsNew((char **)args, nullptr);
666 1 : GDALDatasetH hSrcDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
667 1 : GDALDatasetH hOutDS = GDALWarp("", nullptr, 1, &hSrcDS, psOptions, nullptr);
668 1 : GDALWarpAppOptionsFree(psOptions);
669 1 : GDALReleaseDataset(hSrcDS);
670 1 : EXPECT_EQ(GDALChecksumImage(GDALGetRasterBand(hOutDS, 1), 0, 0, 20, 20),
671 : 4672);
672 1 : GDALReleaseDataset(hOutDS);
673 : }
674 :
675 : // Test GDALTranslate() to VRT and that we can call GDALReleaseDataset() on the
676 : // source dataset when we want.
677 4 : TEST_F(test_gdal, GDALTranslate_VRT)
678 : {
679 1 : auto hDrv = GDALGetDriverByName("GTiff");
680 1 : if (!hDrv)
681 : {
682 0 : GTEST_SKIP() << "GTiff driver missing";
683 : }
684 1 : const char *args[] = {"-of", "VRT", nullptr};
685 : GDALTranslateOptions *psOptions =
686 1 : GDALTranslateOptionsNew((char **)args, nullptr);
687 1 : GDALDatasetH hSrcDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
688 1 : GDALDatasetH hOutDS = GDALTranslate("", hSrcDS, psOptions, nullptr);
689 1 : GDALTranslateOptionsFree(psOptions);
690 1 : GDALReleaseDataset(hSrcDS);
691 1 : EXPECT_EQ(GDALChecksumImage(GDALGetRasterBand(hOutDS, 1), 0, 0, 20, 20),
692 : 4672);
693 1 : GDALReleaseDataset(hOutDS);
694 : }
695 :
696 : // Test GDALBuildVRT() and that we can call GDALReleaseDataset() on the
697 : // source dataset when we want.
698 4 : TEST_F(test_gdal, GDALBuildVRT)
699 : {
700 1 : auto hDrv = GDALGetDriverByName("GTiff");
701 1 : if (!hDrv)
702 : {
703 0 : GTEST_SKIP() << "GTiff driver missing";
704 : }
705 1 : GDALDatasetH hSrcDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
706 : GDALDatasetH hOutDS =
707 1 : GDALBuildVRT("", 1, &hSrcDS, nullptr, nullptr, nullptr);
708 1 : GDALReleaseDataset(hSrcDS);
709 1 : EXPECT_EQ(GDALChecksumImage(GDALGetRasterBand(hOutDS, 1), 0, 0, 20, 20),
710 : 4672);
711 1 : GDALReleaseDataset(hOutDS);
712 : }
713 :
714 : // Test that GDALSwapWords() with unaligned buffers
715 4 : TEST_F(test_gdal, GDALSwapWords_unaligned_buffers)
716 : {
717 1 : GByte abyBuffer[8 * 2 + 1] = {0, 1, 2, 3, 4, 5, 6, 7, 255,
718 : 7, 6, 5, 4, 3, 2, 1, 0};
719 1 : GDALSwapWords(abyBuffer, 4, 2, 9);
720 1 : EXPECT_EQ(abyBuffer[0], 3);
721 1 : EXPECT_EQ(abyBuffer[1], 2);
722 1 : EXPECT_EQ(abyBuffer[2], 1);
723 1 : EXPECT_EQ(abyBuffer[3], 0);
724 :
725 1 : EXPECT_EQ(abyBuffer[9], 4);
726 1 : EXPECT_EQ(abyBuffer[10], 5);
727 1 : EXPECT_EQ(abyBuffer[11], 6);
728 1 : EXPECT_EQ(abyBuffer[12], 7);
729 1 : GDALSwapWords(abyBuffer, 4, 2, 9);
730 :
731 1 : GDALSwapWords(abyBuffer, 8, 2, 9);
732 1 : EXPECT_EQ(abyBuffer[0], 7);
733 1 : EXPECT_EQ(abyBuffer[1], 6);
734 1 : EXPECT_EQ(abyBuffer[2], 5);
735 1 : EXPECT_EQ(abyBuffer[3], 4);
736 1 : EXPECT_EQ(abyBuffer[4], 3);
737 1 : EXPECT_EQ(abyBuffer[5], 2);
738 1 : EXPECT_EQ(abyBuffer[6], 1);
739 1 : EXPECT_EQ(abyBuffer[7], 0);
740 :
741 1 : EXPECT_EQ(abyBuffer[9], 0);
742 1 : EXPECT_EQ(abyBuffer[10], 1);
743 1 : EXPECT_EQ(abyBuffer[11], 2);
744 1 : EXPECT_EQ(abyBuffer[12], 3);
745 1 : EXPECT_EQ(abyBuffer[13], 4);
746 1 : EXPECT_EQ(abyBuffer[14], 5);
747 1 : EXPECT_EQ(abyBuffer[15], 6);
748 1 : EXPECT_EQ(abyBuffer[16], 7);
749 1 : GDALSwapWords(abyBuffer, 4, 2, 9);
750 1 : }
751 :
752 : // Test ARE_REAL_EQUAL()
753 4 : TEST_F(test_gdal, ARE_REAL_EQUAL)
754 : {
755 1 : EXPECT_TRUE(ARE_REAL_EQUAL(0.0, 0.0));
756 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(0.0, 0.1));
757 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(0.1, 0.0));
758 1 : EXPECT_TRUE(ARE_REAL_EQUAL(1.0, 1.0));
759 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(1.0, 0.99));
760 1 : EXPECT_TRUE(ARE_REAL_EQUAL(-cpl::NumericLimits<double>::min(),
761 : -cpl::NumericLimits<double>::min()));
762 1 : EXPECT_TRUE(ARE_REAL_EQUAL(cpl::NumericLimits<double>::min(),
763 : cpl::NumericLimits<double>::min()));
764 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(cpl::NumericLimits<double>::min(), 0.0));
765 1 : EXPECT_TRUE(ARE_REAL_EQUAL(-cpl::NumericLimits<double>::max(),
766 : -cpl::NumericLimits<double>::max()));
767 1 : EXPECT_TRUE(ARE_REAL_EQUAL(cpl::NumericLimits<double>::max(),
768 : cpl::NumericLimits<double>::max()));
769 1 : EXPECT_TRUE(ARE_REAL_EQUAL(-cpl::NumericLimits<double>::infinity(),
770 : -cpl::NumericLimits<double>::infinity()));
771 1 : EXPECT_TRUE(ARE_REAL_EQUAL(cpl::NumericLimits<double>::infinity(),
772 : cpl::NumericLimits<double>::infinity()));
773 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(cpl::NumericLimits<double>::infinity(),
774 : cpl::NumericLimits<double>::max()));
775 1 : EXPECT_TRUE(ARE_REAL_EQUAL(-cpl::NumericLimits<double>::min(),
776 : -cpl::NumericLimits<double>::min()));
777 :
778 1 : EXPECT_TRUE(ARE_REAL_EQUAL(0.0f, 0.0f));
779 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(0.0f, 0.1f));
780 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(0.1f, 0.0f));
781 1 : EXPECT_TRUE(ARE_REAL_EQUAL(1.0f, 1.0f));
782 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(1.0f, 0.99f));
783 1 : EXPECT_TRUE(ARE_REAL_EQUAL(-cpl::NumericLimits<float>::min(),
784 : -cpl::NumericLimits<float>::min()));
785 1 : EXPECT_TRUE(ARE_REAL_EQUAL(cpl::NumericLimits<float>::min(),
786 : cpl::NumericLimits<float>::min()));
787 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(cpl::NumericLimits<float>::min(), 0.0f));
788 1 : EXPECT_TRUE(ARE_REAL_EQUAL(-cpl::NumericLimits<float>::max(),
789 : -cpl::NumericLimits<float>::max()));
790 1 : EXPECT_TRUE(ARE_REAL_EQUAL(cpl::NumericLimits<float>::max(),
791 : cpl::NumericLimits<float>::max()));
792 1 : EXPECT_TRUE(ARE_REAL_EQUAL(-cpl::NumericLimits<float>::infinity(),
793 : -cpl::NumericLimits<float>::infinity()));
794 1 : EXPECT_TRUE(ARE_REAL_EQUAL(cpl::NumericLimits<float>::infinity(),
795 : cpl::NumericLimits<float>::infinity()));
796 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(cpl::NumericLimits<float>::infinity(),
797 : cpl::NumericLimits<float>::max()));
798 1 : }
799 :
800 : // Test GDALIsValueInRange()
801 4 : TEST_F(test_gdal, GDALIsValueInRange)
802 : {
803 1 : EXPECT_TRUE(GDALIsValueInRange<GByte>(0));
804 1 : EXPECT_TRUE(GDALIsValueInRange<GByte>(255));
805 1 : EXPECT_TRUE(!GDALIsValueInRange<GByte>(-1));
806 1 : EXPECT_TRUE(!GDALIsValueInRange<GByte>(256));
807 1 : EXPECT_TRUE(
808 : !GDALIsValueInRange<GByte>(cpl::NumericLimits<double>::quiet_NaN()));
809 :
810 1 : EXPECT_TRUE(GDALIsValueInRange<GInt8>(-128));
811 1 : EXPECT_TRUE(GDALIsValueInRange<GInt8>(127));
812 1 : EXPECT_TRUE(!GDALIsValueInRange<GInt8>(-129));
813 1 : EXPECT_TRUE(!GDALIsValueInRange<GInt8>(128));
814 :
815 : // -(1 << 63)
816 1 : EXPECT_TRUE(GDALIsValueInRange<int64_t>(-9223372036854775808.0));
817 : // (1 << 63) - 1024
818 1 : EXPECT_TRUE(GDALIsValueInRange<int64_t>(9223372036854774784.0));
819 1 : EXPECT_TRUE(GDALIsValueInRange<int64_t>(0.5));
820 : // (1 << 63) - 512
821 1 : EXPECT_TRUE(!GDALIsValueInRange<int64_t>(9223372036854775296.0));
822 :
823 1 : EXPECT_TRUE(GDALIsValueInRange<uint64_t>(0.0));
824 1 : EXPECT_TRUE(GDALIsValueInRange<uint64_t>(0.5));
825 : // (1 << 64) - 2048
826 1 : EXPECT_TRUE(GDALIsValueInRange<uint64_t>(18446744073709549568.0));
827 : // (1 << 64)
828 1 : EXPECT_TRUE(!GDALIsValueInRange<uint64_t>(18446744073709551616.0));
829 1 : EXPECT_TRUE(!GDALIsValueInRange<uint64_t>(-0.5));
830 :
831 1 : EXPECT_TRUE(GDALIsValueInRange<float>(-cpl::NumericLimits<float>::max()));
832 1 : EXPECT_TRUE(GDALIsValueInRange<float>(cpl::NumericLimits<float>::max()));
833 1 : EXPECT_TRUE(
834 : GDALIsValueInRange<float>(-cpl::NumericLimits<float>::infinity()));
835 1 : EXPECT_TRUE(
836 : GDALIsValueInRange<float>(cpl::NumericLimits<float>::infinity()));
837 1 : EXPECT_TRUE(
838 : !GDALIsValueInRange<float>(cpl::NumericLimits<double>::quiet_NaN()));
839 1 : EXPECT_TRUE(!GDALIsValueInRange<float>(-cpl::NumericLimits<double>::max()));
840 1 : EXPECT_TRUE(!GDALIsValueInRange<float>(cpl::NumericLimits<double>::max()));
841 :
842 1 : EXPECT_TRUE(
843 : GDALIsValueInRange<double>(-cpl::NumericLimits<double>::infinity()));
844 1 : EXPECT_TRUE(
845 : GDALIsValueInRange<double>(cpl::NumericLimits<double>::infinity()));
846 1 : EXPECT_TRUE(GDALIsValueInRange<double>(-cpl::NumericLimits<double>::max()));
847 1 : EXPECT_TRUE(GDALIsValueInRange<double>(cpl::NumericLimits<double>::max()));
848 1 : EXPECT_TRUE(
849 : !GDALIsValueInRange<double>(cpl::NumericLimits<double>::quiet_NaN()));
850 1 : }
851 :
852 4 : TEST_F(test_gdal, GDALIsValueInRangeOf)
853 : {
854 18 : for (int eDT = GDT_Byte; eDT <= GDT_TypeCount; ++eDT)
855 : {
856 17 : EXPECT_TRUE(GDALIsValueInRangeOf(0, static_cast<GDALDataType>(eDT)));
857 : }
858 1 : EXPECT_FALSE(GDALIsValueInRangeOf(-1, GDT_Byte));
859 1 : }
860 :
861 : #ifdef _MSC_VER
862 : #pragma warning(push)
863 : // overflow in constant arithmetic
864 : #pragma warning(disable : 4756)
865 : #endif
866 :
867 : // Test GDALIsValueExactAs()
868 4 : TEST_F(test_gdal, GDALIsValueExactAs)
869 : {
870 1 : EXPECT_TRUE(GDALIsValueExactAs<GByte>(0));
871 1 : EXPECT_TRUE(GDALIsValueExactAs<GByte>(255));
872 1 : EXPECT_TRUE(!GDALIsValueExactAs<GByte>(0.5));
873 1 : EXPECT_TRUE(!GDALIsValueExactAs<GByte>(-1));
874 1 : EXPECT_TRUE(!GDALIsValueExactAs<GByte>(-0.5));
875 1 : EXPECT_TRUE(!GDALIsValueExactAs<GByte>(255.5));
876 1 : EXPECT_TRUE(!GDALIsValueExactAs<GByte>(256));
877 1 : EXPECT_TRUE(
878 : !GDALIsValueExactAs<GByte>(cpl::NumericLimits<double>::quiet_NaN()));
879 :
880 : // -(1 << 63)
881 1 : EXPECT_TRUE(GDALIsValueExactAs<int64_t>(-9223372036854775808.0));
882 : // (1 << 63) - 1024
883 1 : EXPECT_TRUE(GDALIsValueExactAs<int64_t>(9223372036854774784.0));
884 1 : EXPECT_TRUE(!GDALIsValueExactAs<int64_t>(0.5));
885 : // (1 << 63) - 512
886 1 : EXPECT_TRUE(!GDALIsValueExactAs<int64_t>(9223372036854775296.0));
887 :
888 1 : EXPECT_TRUE(GDALIsValueExactAs<uint64_t>(0.0));
889 1 : EXPECT_TRUE(!GDALIsValueExactAs<uint64_t>(0.5));
890 : // (1 << 64) - 2048
891 1 : EXPECT_TRUE(GDALIsValueExactAs<uint64_t>(18446744073709549568.0));
892 : // (1 << 64)
893 1 : EXPECT_TRUE(!GDALIsValueExactAs<uint64_t>(18446744073709551616.0));
894 1 : EXPECT_TRUE(!GDALIsValueExactAs<uint64_t>(-0.5));
895 :
896 1 : EXPECT_TRUE(GDALIsValueExactAs<float>(-cpl::NumericLimits<float>::max()));
897 1 : EXPECT_TRUE(GDALIsValueExactAs<float>(cpl::NumericLimits<float>::max()));
898 1 : EXPECT_TRUE(
899 : GDALIsValueExactAs<float>(-cpl::NumericLimits<float>::infinity()));
900 1 : EXPECT_TRUE(
901 : GDALIsValueExactAs<float>(cpl::NumericLimits<float>::infinity()));
902 1 : EXPECT_TRUE(
903 : GDALIsValueExactAs<float>(cpl::NumericLimits<double>::quiet_NaN()));
904 1 : EXPECT_TRUE(!GDALIsValueExactAs<float>(-cpl::NumericLimits<double>::max()));
905 1 : EXPECT_TRUE(!GDALIsValueExactAs<float>(cpl::NumericLimits<double>::max()));
906 :
907 1 : EXPECT_TRUE(
908 : GDALIsValueExactAs<double>(-cpl::NumericLimits<double>::infinity()));
909 1 : EXPECT_TRUE(
910 : GDALIsValueExactAs<double>(cpl::NumericLimits<double>::infinity()));
911 1 : EXPECT_TRUE(GDALIsValueExactAs<double>(-cpl::NumericLimits<double>::max()));
912 1 : EXPECT_TRUE(GDALIsValueExactAs<double>(cpl::NumericLimits<double>::max()));
913 1 : EXPECT_TRUE(
914 : GDALIsValueExactAs<double>(cpl::NumericLimits<double>::quiet_NaN()));
915 1 : }
916 :
917 : // Test GDALIsValueExactAs()
918 4 : TEST_F(test_gdal, GDALIsValueExactAs_C_func)
919 : {
920 1 : EXPECT_TRUE(GDALIsValueExactAs(0, GDT_Byte));
921 1 : EXPECT_TRUE(GDALIsValueExactAs(255, GDT_Byte));
922 1 : EXPECT_FALSE(GDALIsValueExactAs(-1, GDT_Byte));
923 1 : EXPECT_FALSE(GDALIsValueExactAs(256, GDT_Byte));
924 1 : EXPECT_FALSE(GDALIsValueExactAs(0.5, GDT_Byte));
925 :
926 1 : EXPECT_TRUE(GDALIsValueExactAs(-128, GDT_Int8));
927 1 : EXPECT_TRUE(GDALIsValueExactAs(127, GDT_Int8));
928 1 : EXPECT_FALSE(GDALIsValueExactAs(-129, GDT_Int8));
929 1 : EXPECT_FALSE(GDALIsValueExactAs(128, GDT_Int8));
930 1 : EXPECT_FALSE(GDALIsValueExactAs(0.5, GDT_Int8));
931 :
932 1 : EXPECT_TRUE(GDALIsValueExactAs(0, GDT_UInt16));
933 1 : EXPECT_TRUE(GDALIsValueExactAs(65535, GDT_UInt16));
934 1 : EXPECT_FALSE(GDALIsValueExactAs(-1, GDT_UInt16));
935 1 : EXPECT_FALSE(GDALIsValueExactAs(65536, GDT_UInt16));
936 1 : EXPECT_FALSE(GDALIsValueExactAs(0.5, GDT_UInt16));
937 :
938 1 : EXPECT_TRUE(GDALIsValueExactAs(-32768, GDT_Int16));
939 1 : EXPECT_TRUE(GDALIsValueExactAs(32767, GDT_Int16));
940 1 : EXPECT_FALSE(GDALIsValueExactAs(-32769, GDT_Int16));
941 1 : EXPECT_FALSE(GDALIsValueExactAs(32768, GDT_Int16));
942 1 : EXPECT_FALSE(GDALIsValueExactAs(0.5, GDT_Int16));
943 :
944 1 : EXPECT_TRUE(
945 : GDALIsValueExactAs(cpl::NumericLimits<uint32_t>::lowest(), GDT_UInt32));
946 1 : EXPECT_TRUE(
947 : GDALIsValueExactAs(cpl::NumericLimits<uint32_t>::max(), GDT_UInt32));
948 1 : EXPECT_FALSE(GDALIsValueExactAs(
949 : cpl::NumericLimits<uint32_t>::lowest() - 1.0, GDT_UInt32));
950 1 : EXPECT_FALSE(GDALIsValueExactAs(cpl::NumericLimits<uint32_t>::max() + 1.0,
951 : GDT_UInt32));
952 1 : EXPECT_FALSE(GDALIsValueExactAs(0.5, GDT_UInt32));
953 :
954 1 : EXPECT_TRUE(
955 : GDALIsValueExactAs(cpl::NumericLimits<int32_t>::lowest(), GDT_Int32));
956 1 : EXPECT_TRUE(
957 : GDALIsValueExactAs(cpl::NumericLimits<int32_t>::max(), GDT_Int32));
958 1 : EXPECT_FALSE(GDALIsValueExactAs(cpl::NumericLimits<int32_t>::lowest() - 1.0,
959 : GDT_Int32));
960 1 : EXPECT_FALSE(GDALIsValueExactAs(cpl::NumericLimits<int32_t>::max() + 1.0,
961 : GDT_Int32));
962 1 : EXPECT_FALSE(GDALIsValueExactAs(0.5, GDT_Int32));
963 :
964 1 : EXPECT_TRUE(GDALIsValueExactAs(
965 : static_cast<double>(cpl::NumericLimits<uint64_t>::lowest()),
966 : GDT_UInt64));
967 : // (1 << 64) - 2048
968 1 : EXPECT_TRUE(GDALIsValueExactAs(18446744073709549568.0, GDT_UInt64));
969 1 : EXPECT_FALSE(GDALIsValueExactAs(
970 : static_cast<double>(cpl::NumericLimits<uint64_t>::lowest()) - 1.0,
971 : GDT_UInt64));
972 : // (1 << 64)
973 1 : EXPECT_FALSE(GDALIsValueExactAs(18446744073709551616.0, GDT_UInt64));
974 1 : EXPECT_FALSE(GDALIsValueExactAs(0.5, GDT_UInt64));
975 :
976 1 : EXPECT_TRUE(GDALIsValueExactAs(
977 : static_cast<double>(cpl::NumericLimits<int64_t>::lowest()), GDT_Int64));
978 : // (1 << 63) - 1024
979 1 : EXPECT_TRUE(GDALIsValueExactAs(9223372036854774784.0, GDT_Int64));
980 1 : EXPECT_FALSE(GDALIsValueExactAs(
981 : static_cast<double>(cpl::NumericLimits<int64_t>::lowest()) - 2048.0,
982 : GDT_Int64));
983 : // (1 << 63) - 512
984 1 : EXPECT_FALSE(GDALIsValueExactAs(9223372036854775296.0, GDT_Int64));
985 1 : EXPECT_FALSE(GDALIsValueExactAs(0.5, GDT_Int64));
986 :
987 1 : EXPECT_TRUE(
988 : GDALIsValueExactAs(-cpl::NumericLimits<float>::max(), GDT_Float32));
989 1 : EXPECT_TRUE(
990 : GDALIsValueExactAs(cpl::NumericLimits<float>::max(), GDT_Float32));
991 1 : EXPECT_TRUE(GDALIsValueExactAs(-cpl::NumericLimits<float>::infinity(),
992 : GDT_Float32));
993 1 : EXPECT_TRUE(
994 : GDALIsValueExactAs(cpl::NumericLimits<float>::infinity(), GDT_Float32));
995 1 : EXPECT_TRUE(GDALIsValueExactAs(cpl::NumericLimits<double>::quiet_NaN(),
996 : GDT_Float32));
997 1 : EXPECT_TRUE(
998 : !GDALIsValueExactAs(-cpl::NumericLimits<double>::max(), GDT_Float32));
999 1 : EXPECT_TRUE(
1000 : !GDALIsValueExactAs(cpl::NumericLimits<double>::max(), GDT_Float32));
1001 :
1002 1 : EXPECT_TRUE(GDALIsValueExactAs(-cpl::NumericLimits<double>::infinity(),
1003 : GDT_Float64));
1004 1 : EXPECT_TRUE(GDALIsValueExactAs(cpl::NumericLimits<double>::infinity(),
1005 : GDT_Float64));
1006 1 : EXPECT_TRUE(
1007 : GDALIsValueExactAs(-cpl::NumericLimits<double>::max(), GDT_Float64));
1008 1 : EXPECT_TRUE(
1009 : GDALIsValueExactAs(cpl::NumericLimits<double>::max(), GDT_Float64));
1010 1 : EXPECT_TRUE(GDALIsValueExactAs(cpl::NumericLimits<double>::quiet_NaN(),
1011 : GDT_Float64));
1012 :
1013 1 : EXPECT_TRUE(GDALIsValueExactAs(0, GDT_CInt16));
1014 1 : }
1015 :
1016 : #ifdef _MSC_VER
1017 : #pragma warning(pop)
1018 : #endif
1019 :
1020 : // Test GDALDataTypeIsInteger()
1021 4 : TEST_F(test_gdal, GDALDataTypeIsInteger)
1022 : {
1023 1 : EXPECT_TRUE(!GDALDataTypeIsInteger(GDT_Unknown));
1024 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_Byte), TRUE);
1025 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_Int8), TRUE);
1026 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_UInt16), TRUE);
1027 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_Int16), TRUE);
1028 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_UInt32), TRUE);
1029 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_Int32), TRUE);
1030 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_UInt64), TRUE);
1031 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_Int64), TRUE);
1032 1 : EXPECT_TRUE(!GDALDataTypeIsInteger(GDT_Float32));
1033 1 : EXPECT_TRUE(!GDALDataTypeIsInteger(GDT_Float64));
1034 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_CInt16), TRUE);
1035 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_CInt32), TRUE);
1036 1 : EXPECT_TRUE(!GDALDataTypeIsInteger(GDT_CFloat32));
1037 1 : EXPECT_TRUE(!GDALDataTypeIsInteger(GDT_CFloat64));
1038 1 : }
1039 :
1040 : // Test GDALDataTypeIsFloating()
1041 4 : TEST_F(test_gdal, GDALDataTypeIsFloating)
1042 : {
1043 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_Unknown));
1044 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_Byte));
1045 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_Int8));
1046 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_UInt16));
1047 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_Int16));
1048 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_UInt32));
1049 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_Int32));
1050 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_UInt64));
1051 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_Int64));
1052 1 : EXPECT_EQ(GDALDataTypeIsFloating(GDT_Float32), TRUE);
1053 1 : EXPECT_EQ(GDALDataTypeIsFloating(GDT_Float64), TRUE);
1054 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_CInt16));
1055 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_CInt32));
1056 1 : EXPECT_EQ(GDALDataTypeIsFloating(GDT_CFloat32), TRUE);
1057 1 : EXPECT_EQ(GDALDataTypeIsFloating(GDT_CFloat64), TRUE);
1058 1 : }
1059 :
1060 : // Test GDALDataTypeIsComplex()
1061 4 : TEST_F(test_gdal, GDALDataTypeIsComplex)
1062 : {
1063 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Unknown));
1064 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Byte));
1065 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Int8));
1066 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_UInt16));
1067 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Int16));
1068 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_UInt32));
1069 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Int32));
1070 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_UInt64));
1071 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Int64));
1072 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Float32));
1073 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Float64));
1074 1 : EXPECT_EQ(GDALDataTypeIsComplex(GDT_CInt16), TRUE);
1075 1 : EXPECT_EQ(GDALDataTypeIsComplex(GDT_CInt32), TRUE);
1076 1 : EXPECT_EQ(GDALDataTypeIsComplex(GDT_CFloat32), TRUE);
1077 1 : EXPECT_EQ(GDALDataTypeIsComplex(GDT_CFloat64), TRUE);
1078 1 : }
1079 :
1080 : // Test GDALDataTypeIsConversionLossy()
1081 4 : TEST_F(test_gdal, GDALDataTypeIsConversionLossy)
1082 : {
1083 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_Byte));
1084 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Byte, GDT_Int8));
1085 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_UInt16));
1086 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_Int16));
1087 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_UInt32));
1088 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_Int32));
1089 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_UInt64));
1090 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_Int64));
1091 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_Float32));
1092 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_Float64));
1093 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_CInt16));
1094 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_CInt32));
1095 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_CFloat32));
1096 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_CFloat64));
1097 :
1098 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int8, GDT_Byte));
1099 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_Int8));
1100 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int8, GDT_UInt16));
1101 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_Int16));
1102 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int8, GDT_UInt32));
1103 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_Int32));
1104 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int8, GDT_UInt64));
1105 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_Int64));
1106 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_Float32));
1107 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_Float64));
1108 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_CInt16));
1109 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_CInt32));
1110 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_CFloat32));
1111 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_CFloat64));
1112 :
1113 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_Byte));
1114 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_Int8));
1115 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_UInt16));
1116 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_Int16));
1117 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_UInt32));
1118 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_Int32));
1119 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_UInt64));
1120 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_Int64));
1121 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_Float32));
1122 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_Float64));
1123 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_CInt16));
1124 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_CInt32));
1125 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_CFloat32));
1126 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_CFloat64));
1127 :
1128 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int16, GDT_Byte));
1129 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int16, GDT_Int8));
1130 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int16, GDT_UInt16));
1131 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_Int16));
1132 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int16, GDT_UInt32));
1133 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_Int32));
1134 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int16, GDT_UInt64));
1135 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_Int64));
1136 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_Float32));
1137 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_Float64));
1138 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_CInt16));
1139 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_CInt32));
1140 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_CFloat32));
1141 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_CFloat64));
1142 :
1143 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_Byte));
1144 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_UInt16));
1145 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_Int16));
1146 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_UInt32));
1147 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_Int32));
1148 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_UInt64));
1149 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_Int64));
1150 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_Float32));
1151 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_Float64));
1152 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_CInt16));
1153 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_CInt32));
1154 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_CFloat32));
1155 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_CFloat64));
1156 :
1157 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_Byte));
1158 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_UInt16));
1159 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_Int16));
1160 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_UInt32));
1161 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int32, GDT_Int32));
1162 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_UInt64));
1163 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int32, GDT_Int64));
1164 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_Float32));
1165 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int32, GDT_Float64));
1166 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_CInt16));
1167 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int32, GDT_CInt32));
1168 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_CFloat32));
1169 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int32, GDT_CFloat64));
1170 :
1171 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_Byte));
1172 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_UInt16));
1173 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_Int16));
1174 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_UInt32));
1175 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_Int32));
1176 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_UInt64));
1177 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_Int64));
1178 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_Float32));
1179 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_Float64));
1180 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_CInt16));
1181 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_CInt32));
1182 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_CFloat32));
1183 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_CFloat64));
1184 :
1185 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_Byte));
1186 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_UInt16));
1187 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_Int16));
1188 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_UInt32));
1189 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_Int32));
1190 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_UInt64));
1191 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int64, GDT_Int64));
1192 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_Float32));
1193 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_Float64));
1194 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_CInt16));
1195 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_CInt32));
1196 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_CFloat32));
1197 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_CFloat64));
1198 :
1199 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_Byte));
1200 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_UInt16));
1201 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_Int16));
1202 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_UInt32));
1203 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_Int32));
1204 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_UInt64));
1205 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_Int64));
1206 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Float32, GDT_Float32));
1207 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Float32, GDT_Float64));
1208 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_CInt16));
1209 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_CInt32));
1210 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Float32, GDT_CFloat32));
1211 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Float32, GDT_CFloat64));
1212 :
1213 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_Byte));
1214 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_UInt16));
1215 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_Int16));
1216 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_UInt32));
1217 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_Int32));
1218 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_UInt64));
1219 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_Int64));
1220 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_Float32));
1221 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Float64, GDT_Float64));
1222 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_CInt16));
1223 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_CInt32));
1224 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_CFloat32));
1225 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Float64, GDT_CFloat64));
1226 :
1227 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_Byte));
1228 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_UInt16));
1229 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_Int16));
1230 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_UInt32));
1231 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_Int32));
1232 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_UInt64));
1233 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_Int64));
1234 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_Float32));
1235 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_Float64));
1236 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_CInt16));
1237 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_CInt32));
1238 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_CFloat32));
1239 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_CFloat64));
1240 :
1241 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_Byte));
1242 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_UInt16));
1243 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_Int16));
1244 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_UInt32));
1245 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_Int32));
1246 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_UInt64));
1247 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_Int64));
1248 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_Float32));
1249 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_Float64));
1250 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_CInt16));
1251 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_CInt32));
1252 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_CFloat32));
1253 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_CFloat64));
1254 :
1255 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_Byte));
1256 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_UInt16));
1257 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_Int16));
1258 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_UInt32));
1259 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_Int32));
1260 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_UInt64));
1261 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_Int64));
1262 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_Float32));
1263 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_Float64));
1264 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_CInt16));
1265 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_CInt32));
1266 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_CFloat32));
1267 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_CFloat64));
1268 :
1269 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_Byte));
1270 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_UInt16));
1271 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_Int16));
1272 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_UInt32));
1273 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_Int32));
1274 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_UInt64));
1275 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_Int64));
1276 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_Float32));
1277 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_Float64));
1278 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_CInt16));
1279 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_CInt32));
1280 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_CFloat32));
1281 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_CFloat64));
1282 1 : }
1283 :
1284 : // Test GDALDataset::GetBands()
1285 4 : TEST_F(test_gdal, GDALDataset_GetBands)
1286 : {
1287 : GDALDatasetUniquePtr poDS(
1288 1 : MEMDataset::Create("", 1, 1, 3, GDT_Byte, nullptr));
1289 1 : int nExpectedNumber = 1;
1290 4 : for (auto &&poBand : poDS->GetBands())
1291 : {
1292 3 : EXPECT_EQ(poBand->GetBand(), nExpectedNumber);
1293 3 : nExpectedNumber++;
1294 : }
1295 1 : ASSERT_EQ(nExpectedNumber, 3 + 1);
1296 :
1297 1 : ASSERT_EQ(poDS->GetBands().size(), 3U);
1298 1 : EXPECT_EQ(poDS->GetBands()[0], poDS->GetRasterBand(1));
1299 1 : EXPECT_EQ(poDS->GetBands()[static_cast<size_t>(0)], poDS->GetRasterBand(1));
1300 : }
1301 :
1302 4 : TEST_F(test_gdal, GDALExtendedDataType)
1303 : {
1304 : #ifndef __COVERITY__
1305 : // non-null string to string
1306 : {
1307 1 : const char *srcPtr = "foo";
1308 1 : char *dstPtr = nullptr;
1309 1 : GDALExtendedDataType::CopyValue(
1310 2 : &srcPtr, GDALExtendedDataType::CreateString(), &dstPtr,
1311 2 : GDALExtendedDataType::CreateString());
1312 1 : EXPECT_TRUE(dstPtr != nullptr);
1313 : // Coverity isn't smart enough to figure out that GetClass() of
1314 : // CreateString() is GEDTC_STRING and then takes the wrong path
1315 : // in CopyValue() and makes wrong assumptions.
1316 1 : EXPECT_STREQ(dstPtr, srcPtr);
1317 1 : CPLFree(dstPtr);
1318 : }
1319 : #endif
1320 :
1321 : // null string to string
1322 : {
1323 1 : const char *srcPtr = nullptr;
1324 1 : char *dstPtr = nullptr;
1325 1 : GDALExtendedDataType::CopyValue(
1326 2 : &srcPtr, GDALExtendedDataType::CreateString(), &dstPtr,
1327 2 : GDALExtendedDataType::CreateString());
1328 1 : EXPECT_TRUE(dstPtr == nullptr);
1329 : }
1330 : // non-null string to Int32
1331 : {
1332 1 : const char *srcPtr = "2";
1333 1 : int32_t nVal = 1;
1334 1 : GDALExtendedDataType::CopyValue(
1335 2 : &srcPtr, GDALExtendedDataType::CreateString(), &nVal,
1336 2 : GDALExtendedDataType::Create(GDT_Int32));
1337 1 : EXPECT_EQ(nVal, 2);
1338 : }
1339 : // null string to Int32
1340 : {
1341 1 : const char *srcPtr = nullptr;
1342 1 : int32_t nVal = 1;
1343 1 : GDALExtendedDataType::CopyValue(
1344 2 : &srcPtr, GDALExtendedDataType::CreateString(), &nVal,
1345 2 : GDALExtendedDataType::Create(GDT_Int32));
1346 1 : EXPECT_EQ(nVal, 0);
1347 : }
1348 : // non-null string to Int64
1349 : {
1350 1 : const char *srcPtr = "2";
1351 1 : int64_t nVal = 1;
1352 1 : GDALExtendedDataType::CopyValue(
1353 2 : &srcPtr, GDALExtendedDataType::CreateString(), &nVal,
1354 2 : GDALExtendedDataType::Create(GDT_Int64));
1355 1 : EXPECT_EQ(nVal, 2);
1356 : }
1357 : // null string to Int64
1358 : {
1359 1 : const char *srcPtr = nullptr;
1360 1 : int64_t nVal = 1;
1361 1 : GDALExtendedDataType::CopyValue(
1362 2 : &srcPtr, GDALExtendedDataType::CreateString(), &nVal,
1363 2 : GDALExtendedDataType::Create(GDT_Int64));
1364 1 : EXPECT_EQ(nVal, 0);
1365 : }
1366 : // non-null string to UInt64
1367 : {
1368 1 : char *srcPtr = nullptr;
1369 1 : uint64_t nVal = 1;
1370 1 : GDALExtendedDataType::CopyValue(
1371 2 : &srcPtr, GDALExtendedDataType::CreateString(), &nVal,
1372 2 : GDALExtendedDataType::Create(GDT_UInt64));
1373 1 : EXPECT_EQ(nVal, 0U);
1374 : }
1375 : // non-null string to Int64
1376 : {
1377 1 : const char *srcPtr = "2";
1378 1 : uint64_t nVal = 1;
1379 1 : GDALExtendedDataType::CopyValue(
1380 2 : &srcPtr, GDALExtendedDataType::CreateString(), &nVal,
1381 2 : GDALExtendedDataType::Create(GDT_UInt64));
1382 1 : EXPECT_EQ(nVal, 2U);
1383 : }
1384 :
1385 : class myArray : public GDALMDArray
1386 : {
1387 : GDALExtendedDataType m_dt;
1388 : std::vector<std::shared_ptr<GDALDimension>> m_dims;
1389 : std::vector<GUInt64> m_blockSize;
1390 : const std::string m_osEmptyFilename{};
1391 :
1392 : static std::vector<std::shared_ptr<GDALDimension>>
1393 9 : BuildDims(const std::vector<GUInt64> &sizes)
1394 : {
1395 9 : std::vector<std::shared_ptr<GDALDimension>> dims;
1396 33 : for (const auto sz : sizes)
1397 : {
1398 : dims.emplace_back(
1399 24 : std::make_shared<GDALDimension>("", "", "", "", sz));
1400 : }
1401 9 : return dims;
1402 : }
1403 :
1404 : protected:
1405 0 : bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
1406 : const GPtrDiff_t *, const GDALExtendedDataType &,
1407 : void *) const override
1408 : {
1409 0 : return false;
1410 : }
1411 :
1412 : public:
1413 8 : myArray(GDALDataType eDT, const std::vector<GUInt64> &sizes,
1414 : const std::vector<GUInt64> &blocksizes)
1415 8 : : GDALAbstractMDArray("", "array"), GDALMDArray("", "array"),
1416 : m_dt(GDALExtendedDataType::Create(eDT)), m_dims(BuildDims(sizes)),
1417 8 : m_blockSize(blocksizes)
1418 : {
1419 8 : }
1420 :
1421 1 : myArray(const GDALExtendedDataType &dt,
1422 : const std::vector<GUInt64> &sizes,
1423 : const std::vector<GUInt64> &blocksizes)
1424 1 : : GDALAbstractMDArray("", "array"), GDALMDArray("", "array"),
1425 1 : m_dt(dt), m_dims(BuildDims(sizes)), m_blockSize(blocksizes)
1426 : {
1427 1 : }
1428 :
1429 0 : bool IsWritable() const override
1430 : {
1431 0 : return true;
1432 : }
1433 :
1434 0 : const std::string &GetFilename() const override
1435 : {
1436 0 : return m_osEmptyFilename;
1437 : }
1438 :
1439 : static std::shared_ptr<myArray>
1440 1 : Create(GDALDataType eDT, const std::vector<GUInt64> &sizes,
1441 : const std::vector<GUInt64> &blocksizes)
1442 : {
1443 : auto ar(
1444 1 : std::shared_ptr<myArray>(new myArray(eDT, sizes, blocksizes)));
1445 1 : ar->SetSelf(ar);
1446 1 : return ar;
1447 : }
1448 :
1449 : static std::shared_ptr<myArray>
1450 1 : Create(const GDALExtendedDataType &dt,
1451 : const std::vector<GUInt64> &sizes,
1452 : const std::vector<GUInt64> &blocksizes)
1453 : {
1454 : auto ar(
1455 1 : std::shared_ptr<myArray>(new myArray(dt, sizes, blocksizes)));
1456 1 : ar->SetSelf(ar);
1457 1 : return ar;
1458 : }
1459 :
1460 : const std::vector<std::shared_ptr<GDALDimension>> &
1461 74 : GetDimensions() const override
1462 : {
1463 74 : return m_dims;
1464 : }
1465 :
1466 14 : const GDALExtendedDataType &GetDataType() const override
1467 : {
1468 14 : return m_dt;
1469 : }
1470 :
1471 10 : std::vector<GUInt64> GetBlockSize() const override
1472 : {
1473 10 : return m_blockSize;
1474 : }
1475 : };
1476 :
1477 : {
1478 3 : auto ar(myArray::Create(GDT_UInt16, {3000, 1000, 2000}, {32, 64, 128}));
1479 1 : EXPECT_EQ(ar->at(0)->GetDimensionCount(), 2U);
1480 1 : EXPECT_EQ(ar->at(2999, 999, 1999)->GetDimensionCount(), 0U);
1481 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1482 1 : EXPECT_TRUE(ar->at(3000, 0, 0) == nullptr);
1483 1 : EXPECT_TRUE(ar->at(0, 0, 0, 0) == nullptr);
1484 1 : EXPECT_TRUE((*ar)["foo"] == nullptr);
1485 1 : CPLPopErrorHandler();
1486 : }
1487 :
1488 : {
1489 2 : std::vector<std::unique_ptr<GDALEDTComponent>> comps;
1490 : comps.emplace_back(
1491 4 : std::unique_ptr<GDALEDTComponent>(new GDALEDTComponent(
1492 3 : "f\\o\"o", 0, GDALExtendedDataType::Create(GDT_Int32))));
1493 3 : auto dt(GDALExtendedDataType::Create("", 4, std::move(comps)));
1494 3 : auto ar(myArray::Create(dt, {3000, 1000, 2000}, {32, 64, 128}));
1495 1 : EXPECT_TRUE((*ar)["f\\o\"o"] != nullptr);
1496 : }
1497 :
1498 : {
1499 3 : myArray ar(GDT_UInt16, {}, {});
1500 :
1501 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1502 1 : EXPECT_TRUE(ar.GetView("[...]") == nullptr);
1503 1 : CPLPopErrorHandler();
1504 :
1505 2 : auto cs = ar.GetProcessingChunkSize(0);
1506 1 : EXPECT_EQ(cs.size(), 0U);
1507 :
1508 : struct TmpStructNoDim
1509 : {
1510 1 : static bool func(GDALAbstractMDArray *p_ar,
1511 : const GUInt64 *chunk_array_start_idx,
1512 : const size_t *chunk_count, GUInt64 iCurChunk,
1513 : GUInt64 nChunkCount, void *user_data)
1514 : {
1515 1 : EXPECT_TRUE(p_ar->GetName() == "array");
1516 1 : EXPECT_TRUE(chunk_array_start_idx == nullptr);
1517 1 : EXPECT_TRUE(chunk_count == nullptr);
1518 1 : EXPECT_EQ(iCurChunk, 1U);
1519 1 : EXPECT_EQ(nChunkCount, 1U);
1520 1 : *static_cast<bool *>(user_data) = true;
1521 1 : return true;
1522 : }
1523 : };
1524 :
1525 1 : bool b = false;
1526 1 : ar.ProcessPerChunk(nullptr, nullptr, nullptr, TmpStructNoDim::func, &b);
1527 1 : EXPECT_TRUE(b);
1528 : }
1529 :
1530 : struct ChunkDef
1531 : {
1532 : std::vector<GUInt64> array_start_idx;
1533 : std::vector<GUInt64> count;
1534 : };
1535 :
1536 : struct TmpStruct
1537 : {
1538 16 : static bool func(GDALAbstractMDArray *p_ar,
1539 : const GUInt64 *chunk_array_start_idx,
1540 : const size_t *chunk_count, GUInt64 iCurChunk,
1541 : GUInt64 nChunkCount, void *user_data)
1542 : {
1543 16 : EXPECT_EQ(p_ar->GetName(), "array");
1544 16 : std::vector<ChunkDef> *p_chunkDefs =
1545 : static_cast<std::vector<ChunkDef> *>(user_data);
1546 32 : std::vector<GUInt64> v_chunk_array_start_idx;
1547 : v_chunk_array_start_idx.insert(
1548 0 : v_chunk_array_start_idx.end(), chunk_array_start_idx,
1549 16 : chunk_array_start_idx + p_ar->GetDimensionCount());
1550 32 : std::vector<GUInt64> v_chunk_count;
1551 0 : v_chunk_count.insert(v_chunk_count.end(), chunk_count,
1552 16 : chunk_count + p_ar->GetDimensionCount());
1553 16 : ChunkDef chunkDef;
1554 16 : chunkDef.array_start_idx = std::move(v_chunk_array_start_idx);
1555 16 : chunkDef.count = std::move(v_chunk_count);
1556 16 : p_chunkDefs->emplace_back(std::move(chunkDef));
1557 16 : EXPECT_EQ(p_chunkDefs->size(), iCurChunk);
1558 16 : EXPECT_TRUE(iCurChunk > 0);
1559 16 : EXPECT_TRUE(iCurChunk <= nChunkCount);
1560 32 : return true;
1561 : }
1562 : };
1563 :
1564 : {
1565 3 : myArray ar(GDT_UInt16, {3000, 1000, 2000}, {32, 64, 128});
1566 : {
1567 2 : auto cs = ar.GetProcessingChunkSize(0);
1568 1 : EXPECT_EQ(cs.size(), 3U);
1569 1 : EXPECT_EQ(cs[0], 32U);
1570 1 : EXPECT_EQ(cs[1], 64U);
1571 1 : EXPECT_EQ(cs[2], 128U);
1572 : }
1573 : {
1574 2 : auto cs = ar.GetProcessingChunkSize(40 * 1000 * 1000);
1575 1 : EXPECT_EQ(cs.size(), 3U);
1576 1 : EXPECT_EQ(cs[0], 32U);
1577 1 : EXPECT_EQ(cs[1], 256U);
1578 1 : EXPECT_EQ(cs[2], 2000U);
1579 :
1580 2 : std::vector<ChunkDef> chunkDefs;
1581 :
1582 : // Error cases of input parameters of ProcessPerChunk()
1583 : {
1584 : // array_start_idx[0] + count[0] > 3000
1585 2 : std::vector<GUInt64> array_start_idx{1, 0, 0};
1586 2 : std::vector<GUInt64> count{3000, 1000, 2000};
1587 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1588 1 : EXPECT_TRUE(!ar.ProcessPerChunk(array_start_idx.data(),
1589 : count.data(), cs.data(),
1590 : TmpStruct::func, &chunkDefs));
1591 1 : CPLPopErrorHandler();
1592 : }
1593 : {
1594 : // array_start_idx[0] >= 3000
1595 2 : std::vector<GUInt64> array_start_idx{3000, 0, 0};
1596 2 : std::vector<GUInt64> count{1, 1000, 2000};
1597 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1598 1 : EXPECT_TRUE(!ar.ProcessPerChunk(array_start_idx.data(),
1599 : count.data(), cs.data(),
1600 : TmpStruct::func, &chunkDefs));
1601 1 : CPLPopErrorHandler();
1602 : }
1603 : {
1604 : // count[0] > 3000
1605 2 : std::vector<GUInt64> array_start_idx{0, 0, 0};
1606 2 : std::vector<GUInt64> count{3001, 1000, 2000};
1607 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1608 1 : EXPECT_TRUE(!ar.ProcessPerChunk(array_start_idx.data(),
1609 : count.data(), cs.data(),
1610 : TmpStruct::func, &chunkDefs));
1611 1 : CPLPopErrorHandler();
1612 : }
1613 : {
1614 : // count[0] == 0
1615 2 : std::vector<GUInt64> array_start_idx{0, 0, 0};
1616 2 : std::vector<GUInt64> count{0, 1000, 2000};
1617 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1618 1 : EXPECT_TRUE(!ar.ProcessPerChunk(array_start_idx.data(),
1619 : count.data(), cs.data(),
1620 : TmpStruct::func, &chunkDefs));
1621 1 : CPLPopErrorHandler();
1622 : }
1623 : {
1624 : // myCustomChunkSize[0] == 0
1625 2 : std::vector<GUInt64> array_start_idx{0, 0, 0};
1626 2 : std::vector<GUInt64> count{3000, 1000, 2000};
1627 2 : std::vector<size_t> myCustomChunkSize{0, 1000, 2000};
1628 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1629 1 : EXPECT_TRUE(!ar.ProcessPerChunk(
1630 : array_start_idx.data(), count.data(),
1631 : myCustomChunkSize.data(), TmpStruct::func, &chunkDefs));
1632 1 : CPLPopErrorHandler();
1633 : }
1634 : {
1635 : // myCustomChunkSize[0] > 3000
1636 2 : std::vector<GUInt64> array_start_idx{0, 0, 0};
1637 2 : std::vector<GUInt64> count{3000, 1000, 2000};
1638 2 : std::vector<size_t> myCustomChunkSize{3001, 1000, 2000};
1639 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1640 1 : EXPECT_TRUE(!ar.ProcessPerChunk(
1641 : array_start_idx.data(), count.data(),
1642 : myCustomChunkSize.data(), TmpStruct::func, &chunkDefs));
1643 1 : CPLPopErrorHandler();
1644 : }
1645 :
1646 2 : std::vector<GUInt64> array_start_idx{1500, 256, 0};
1647 2 : std::vector<GUInt64> count{99, 512, 2000};
1648 1 : EXPECT_TRUE(ar.ProcessPerChunk(array_start_idx.data(), count.data(),
1649 : cs.data(), TmpStruct::func,
1650 : &chunkDefs));
1651 :
1652 1 : size_t nExpectedChunks = 1;
1653 4 : for (size_t i = 0; i < ar.GetDimensionCount(); i++)
1654 : {
1655 3 : nExpectedChunks *= static_cast<size_t>(
1656 3 : 1 + ((array_start_idx[i] + count[i] - 1) / cs[i]) -
1657 3 : (array_start_idx[i] / cs[i]));
1658 : }
1659 1 : EXPECT_EQ(chunkDefs.size(), nExpectedChunks);
1660 :
1661 2 : CPLString osChunks;
1662 9 : for (const auto &chunkDef : chunkDefs)
1663 : {
1664 : osChunks += CPLSPrintf("{%u, %u, %u}, {%u, %u, %u}\n",
1665 8 : (unsigned)chunkDef.array_start_idx[0],
1666 8 : (unsigned)chunkDef.array_start_idx[1],
1667 8 : (unsigned)chunkDef.array_start_idx[2],
1668 8 : (unsigned)chunkDef.count[0],
1669 8 : (unsigned)chunkDef.count[1],
1670 8 : (unsigned)chunkDef.count[2]);
1671 : }
1672 1 : EXPECT_EQ(osChunks, "{1500, 256, 0}, {4, 256, 2000}\n"
1673 : "{1500, 512, 0}, {4, 256, 2000}\n"
1674 : "{1504, 256, 0}, {32, 256, 2000}\n"
1675 : "{1504, 512, 0}, {32, 256, 2000}\n"
1676 : "{1536, 256, 0}, {32, 256, 2000}\n"
1677 : "{1536, 512, 0}, {32, 256, 2000}\n"
1678 : "{1568, 256, 0}, {31, 256, 2000}\n"
1679 : "{1568, 512, 0}, {31, 256, 2000}\n");
1680 : }
1681 : }
1682 :
1683 : // Another error case of ProcessPerChunk
1684 : {
1685 1 : const auto M64 = cpl::NumericLimits<GUInt64>::max();
1686 1 : const auto Msize_t = cpl::NumericLimits<size_t>::max();
1687 3 : myArray ar(GDT_UInt16, {M64, M64, M64}, {32, 256, 128});
1688 :
1689 : // Product of myCustomChunkSize[] > Msize_t
1690 2 : std::vector<GUInt64> array_start_idx{0, 0, 0};
1691 2 : std::vector<GUInt64> count{3000, 1000, 2000};
1692 2 : std::vector<size_t> myCustomChunkSize{Msize_t, Msize_t, Msize_t};
1693 2 : std::vector<ChunkDef> chunkDefs;
1694 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1695 1 : EXPECT_TRUE(!ar.ProcessPerChunk(array_start_idx.data(), count.data(),
1696 : myCustomChunkSize.data(),
1697 : TmpStruct::func, &chunkDefs));
1698 1 : CPLPopErrorHandler();
1699 : }
1700 :
1701 : {
1702 1 : const auto BIG = GUInt64(5000) * 1000 * 1000;
1703 : myArray ar(GDT_UInt16, {BIG + 3000, BIG + 1000, BIG + 2000},
1704 3 : {32, 256, 128});
1705 2 : std::vector<GUInt64> array_start_idx{BIG + 1500, BIG + 256, BIG + 0};
1706 2 : std::vector<GUInt64> count{99, 512, 2000};
1707 2 : std::vector<ChunkDef> chunkDefs;
1708 2 : auto cs = ar.GetProcessingChunkSize(40 * 1000 * 1000);
1709 1 : EXPECT_TRUE(ar.ProcessPerChunk(array_start_idx.data(), count.data(),
1710 : cs.data(), TmpStruct::func, &chunkDefs));
1711 :
1712 1 : size_t nExpectedChunks = 1;
1713 4 : for (size_t i = 0; i < ar.GetDimensionCount(); i++)
1714 : {
1715 3 : nExpectedChunks *= static_cast<size_t>(
1716 3 : 1 + ((array_start_idx[i] + count[i] - 1) / cs[i]) -
1717 3 : (array_start_idx[i] / cs[i]));
1718 : }
1719 1 : EXPECT_EQ(chunkDefs.size(), nExpectedChunks);
1720 :
1721 2 : CPLString osChunks;
1722 9 : for (const auto &chunkDef : chunkDefs)
1723 : {
1724 : osChunks += CPLSPrintf("{" CPL_FRMT_GUIB ", " CPL_FRMT_GUIB
1725 : ", " CPL_FRMT_GUIB "}, {%u, %u, %u}\n",
1726 8 : (GUIntBig)chunkDef.array_start_idx[0],
1727 8 : (GUIntBig)chunkDef.array_start_idx[1],
1728 8 : (GUIntBig)chunkDef.array_start_idx[2],
1729 8 : (unsigned)chunkDef.count[0],
1730 8 : (unsigned)chunkDef.count[1],
1731 8 : (unsigned)chunkDef.count[2]);
1732 : }
1733 1 : EXPECT_EQ(osChunks,
1734 : "{5000001500, 5000000256, 5000000000}, {4, 256, 2000}\n"
1735 : "{5000001500, 5000000512, 5000000000}, {4, 256, 2000}\n"
1736 : "{5000001504, 5000000256, 5000000000}, {32, 256, 2000}\n"
1737 : "{5000001504, 5000000512, 5000000000}, {32, 256, 2000}\n"
1738 : "{5000001536, 5000000256, 5000000000}, {32, 256, 2000}\n"
1739 : "{5000001536, 5000000512, 5000000000}, {32, 256, 2000}\n"
1740 : "{5000001568, 5000000256, 5000000000}, {31, 256, 2000}\n"
1741 : "{5000001568, 5000000512, 5000000000}, {31, 256, 2000}\n");
1742 : }
1743 :
1744 : {
1745 : // Test with 0 in GetBlockSize()
1746 3 : myArray ar(GDT_UInt16, {500, 1000, 2000}, {0, 0, 128});
1747 : {
1748 2 : auto cs = ar.GetProcessingChunkSize(300 * 2);
1749 1 : EXPECT_EQ(cs.size(), 3U);
1750 1 : EXPECT_EQ(cs[0], 1U);
1751 1 : EXPECT_EQ(cs[1], 1U);
1752 1 : EXPECT_EQ(cs[2], 256U);
1753 : }
1754 : {
1755 2 : auto cs = ar.GetProcessingChunkSize(40 * 1000 * 1000);
1756 1 : EXPECT_EQ(cs.size(), 3U);
1757 1 : EXPECT_EQ(cs[0], 10U);
1758 1 : EXPECT_EQ(cs[1], 1000U);
1759 1 : EXPECT_EQ(cs[2], 2000U);
1760 : }
1761 : {
1762 2 : auto cs = ar.GetProcessingChunkSize(500U * 1000 * 2000 * 2);
1763 1 : EXPECT_EQ(cs.size(), 3U);
1764 1 : EXPECT_EQ(cs[0], 500U);
1765 1 : EXPECT_EQ(cs[1], 1000U);
1766 1 : EXPECT_EQ(cs[2], 2000U);
1767 : }
1768 : {
1769 2 : auto cs = ar.GetProcessingChunkSize(500U * 1000 * 2000 * 2 - 1);
1770 1 : EXPECT_EQ(cs.size(), 3U);
1771 1 : EXPECT_EQ(cs[0], 499U);
1772 1 : EXPECT_EQ(cs[1], 1000U);
1773 1 : EXPECT_EQ(cs[2], 2000U);
1774 : }
1775 : }
1776 : {
1777 1 : const auto M = cpl::NumericLimits<GUInt64>::max();
1778 3 : myArray ar(GDT_UInt16, {M, M, M}, {M, M, M / 2});
1779 : {
1780 2 : auto cs = ar.GetProcessingChunkSize(0);
1781 1 : EXPECT_EQ(cs.size(), 3U);
1782 1 : EXPECT_EQ(cs[0], 1U);
1783 1 : EXPECT_EQ(cs[1], 1U);
1784 : #if SIZEOF_VOIDP == 8
1785 1 : EXPECT_EQ(cs[2], static_cast<size_t>(M / 2));
1786 : #else
1787 : EXPECT_EQ(cs[2], 1U);
1788 : #endif
1789 : }
1790 : }
1791 : #if SIZEOF_VOIDP == 8
1792 : {
1793 1 : const auto M = cpl::NumericLimits<GUInt64>::max();
1794 3 : myArray ar(GDT_UInt16, {M, M, M}, {M, M, M / 4});
1795 : {
1796 : auto cs =
1797 2 : ar.GetProcessingChunkSize(cpl::NumericLimits<size_t>::max());
1798 1 : EXPECT_EQ(cs.size(), 3U);
1799 1 : EXPECT_EQ(cs[0], 1U);
1800 1 : EXPECT_EQ(cs[1], 1U);
1801 1 : EXPECT_EQ(cs[2], (cpl::NumericLimits<size_t>::max() / 4) * 2);
1802 : }
1803 : }
1804 : #endif
1805 1 : }
1806 :
1807 : // Test GDALDataset::GetRawBinaryLayout() implementations
1808 4 : TEST_F(test_gdal, GetRawBinaryLayout_ENVI)
1809 : {
1810 1 : if (GDALGetDriverByName("ENVI") == nullptr)
1811 : {
1812 0 : GTEST_SKIP() << "ENVI driver missing";
1813 : }
1814 :
1815 : {
1816 : GDALDatasetUniquePtr poDS(
1817 2 : GDALDataset::Open(GDRIVERS_DATA_DIR "envi/envi_rgbsmall_bip.img"));
1818 1 : EXPECT_TRUE(poDS != nullptr);
1819 2 : GDALDataset::RawBinaryLayout sLayout;
1820 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1821 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1822 1 : EXPECT_EQ(
1823 : static_cast<int>(sLayout.eInterleaving),
1824 : static_cast<int>(GDALDataset::RawBinaryLayout::Interleaving::BIP));
1825 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1826 1 : EXPECT_TRUE(sLayout.bLittleEndianOrder);
1827 1 : EXPECT_EQ(sLayout.nImageOffset, 0U);
1828 1 : EXPECT_EQ(sLayout.nPixelOffset, 3);
1829 1 : EXPECT_EQ(sLayout.nLineOffset, 3 * 50);
1830 1 : EXPECT_EQ(sLayout.nBandOffset, 1);
1831 : }
1832 :
1833 : {
1834 : GDALDatasetUniquePtr poDS(
1835 2 : GDALDataset::Open(GDRIVERS_DATA_DIR "envi/envi_rgbsmall_bil.img"));
1836 1 : EXPECT_TRUE(poDS != nullptr);
1837 2 : GDALDataset::RawBinaryLayout sLayout;
1838 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1839 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1840 1 : EXPECT_EQ(
1841 : static_cast<int>(sLayout.eInterleaving),
1842 : static_cast<int>(GDALDataset::RawBinaryLayout::Interleaving::BIL));
1843 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1844 1 : EXPECT_TRUE(sLayout.bLittleEndianOrder);
1845 1 : EXPECT_EQ(sLayout.nImageOffset, 0U);
1846 1 : EXPECT_EQ(sLayout.nPixelOffset, 1);
1847 1 : EXPECT_EQ(sLayout.nLineOffset, 3 * 50);
1848 1 : EXPECT_EQ(sLayout.nBandOffset, 50);
1849 : }
1850 :
1851 : {
1852 : GDALDatasetUniquePtr poDS(
1853 2 : GDALDataset::Open(GDRIVERS_DATA_DIR "envi/envi_rgbsmall_bsq.img"));
1854 1 : EXPECT_TRUE(poDS != nullptr);
1855 2 : GDALDataset::RawBinaryLayout sLayout;
1856 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1857 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1858 1 : EXPECT_EQ(
1859 : static_cast<int>(sLayout.eInterleaving),
1860 : static_cast<int>(GDALDataset::RawBinaryLayout::Interleaving::BSQ));
1861 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1862 1 : EXPECT_TRUE(sLayout.bLittleEndianOrder);
1863 1 : EXPECT_EQ(sLayout.nImageOffset, 0U);
1864 1 : EXPECT_EQ(sLayout.nPixelOffset, 1);
1865 1 : EXPECT_EQ(sLayout.nLineOffset, 50);
1866 1 : EXPECT_EQ(sLayout.nBandOffset, 50 * 49);
1867 : }
1868 : }
1869 :
1870 : // Test GDALDataset::GetRawBinaryLayout() implementations
1871 4 : TEST_F(test_gdal, GetRawBinaryLayout_GTIFF)
1872 : {
1873 1 : if (GDALGetDriverByName("GTIFF") == nullptr)
1874 : {
1875 0 : GTEST_SKIP() << "GTIFF driver missing";
1876 : }
1877 :
1878 : {
1879 : GDALDatasetUniquePtr poDS(
1880 2 : GDALDataset::Open(GCORE_DATA_DIR "uint16.tif"));
1881 1 : EXPECT_TRUE(poDS != nullptr);
1882 2 : GDALDataset::RawBinaryLayout sLayout;
1883 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1884 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1885 1 : EXPECT_EQ(static_cast<int>(sLayout.eInterleaving),
1886 : static_cast<int>(
1887 : GDALDataset::RawBinaryLayout::Interleaving::UNKNOWN));
1888 1 : EXPECT_EQ(sLayout.eDataType, GDT_UInt16);
1889 1 : EXPECT_TRUE(sLayout.bLittleEndianOrder);
1890 1 : EXPECT_EQ(sLayout.nImageOffset, 8U);
1891 1 : EXPECT_EQ(sLayout.nPixelOffset, 2);
1892 1 : EXPECT_EQ(sLayout.nLineOffset, 40);
1893 1 : EXPECT_EQ(sLayout.nBandOffset, 0);
1894 : }
1895 :
1896 : {
1897 : GDALDatasetUniquePtr poDS(
1898 2 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif"));
1899 1 : EXPECT_TRUE(poDS != nullptr);
1900 2 : GDALDataset::RawBinaryLayout sLayout;
1901 : // Compressed
1902 1 : EXPECT_TRUE(!poDS->GetRawBinaryLayout(sLayout));
1903 : }
1904 :
1905 : {
1906 : GDALDatasetUniquePtr poDS(
1907 2 : GDALDataset::Open(GCORE_DATA_DIR "stefan_full_rgba.tif"));
1908 1 : EXPECT_TRUE(poDS != nullptr);
1909 2 : GDALDataset::RawBinaryLayout sLayout;
1910 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1911 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1912 1 : EXPECT_EQ(
1913 : static_cast<int>(sLayout.eInterleaving),
1914 : static_cast<int>(GDALDataset::RawBinaryLayout::Interleaving::BIP));
1915 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1916 1 : EXPECT_EQ(sLayout.nImageOffset, 278U);
1917 1 : EXPECT_EQ(sLayout.nPixelOffset, 4);
1918 1 : EXPECT_EQ(sLayout.nLineOffset, 162 * 4);
1919 1 : EXPECT_EQ(sLayout.nBandOffset, 1);
1920 : }
1921 :
1922 : {
1923 : GDALDatasetUniquePtr poSrcDS(
1924 2 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif"));
1925 1 : EXPECT_TRUE(poSrcDS != nullptr);
1926 1 : auto tmpFilename = "/vsimem/tmp.tif";
1927 1 : auto poDrv = GDALDriver::FromHandle(GDALGetDriverByName("GTiff"));
1928 1 : const char *options[] = {"INTERLEAVE=BAND", nullptr};
1929 : auto poDS(GDALDatasetUniquePtr(
1930 : poDrv->CreateCopy(tmpFilename, poSrcDS.get(), false,
1931 2 : const_cast<char **>(options), nullptr, nullptr)));
1932 1 : EXPECT_TRUE(poDS != nullptr);
1933 2 : GDALDataset::RawBinaryLayout sLayout;
1934 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1935 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1936 1 : EXPECT_EQ(
1937 : static_cast<int>(sLayout.eInterleaving),
1938 : static_cast<int>(GDALDataset::RawBinaryLayout::Interleaving::BSQ));
1939 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1940 1 : EXPECT_TRUE(sLayout.nImageOffset >= 396U);
1941 1 : EXPECT_EQ(sLayout.nPixelOffset, 1);
1942 1 : EXPECT_EQ(sLayout.nLineOffset, 50);
1943 1 : EXPECT_EQ(sLayout.nBandOffset, 50 * 50);
1944 1 : poDS.reset();
1945 1 : VSIUnlink(tmpFilename);
1946 : }
1947 :
1948 : {
1949 : GDALDatasetUniquePtr poSrcDS(
1950 2 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif"));
1951 1 : EXPECT_TRUE(poSrcDS != nullptr);
1952 1 : auto tmpFilename = "/vsimem/tmp.tif";
1953 1 : const char *options[] = {"-srcwin",
1954 : "0",
1955 : "0",
1956 : "48",
1957 : "32",
1958 : "-co",
1959 : "INTERLEAVE=PIXEL",
1960 : "-co",
1961 : "TILED=YES",
1962 : "-co",
1963 : "BLOCKXSIZE=48",
1964 : "-co",
1965 : "BLOCKYSIZE=32",
1966 : nullptr};
1967 : auto psOptions =
1968 1 : GDALTranslateOptionsNew(const_cast<char **>(options), nullptr);
1969 : auto poDS(GDALDatasetUniquePtr(GDALDataset::FromHandle(
1970 : GDALTranslate(tmpFilename, GDALDataset::ToHandle(poSrcDS.get()),
1971 2 : psOptions, nullptr))));
1972 1 : GDALTranslateOptionsFree(psOptions);
1973 1 : EXPECT_TRUE(poDS != nullptr);
1974 2 : GDALDataset::RawBinaryLayout sLayout;
1975 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1976 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1977 1 : EXPECT_EQ(
1978 : static_cast<int>(sLayout.eInterleaving),
1979 : static_cast<int>(GDALDataset::RawBinaryLayout::Interleaving::BIP));
1980 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1981 1 : EXPECT_TRUE(sLayout.nImageOffset >= 390U);
1982 1 : EXPECT_EQ(sLayout.nPixelOffset, 3);
1983 1 : EXPECT_EQ(sLayout.nLineOffset, 48 * 3);
1984 1 : EXPECT_EQ(sLayout.nBandOffset, 1);
1985 1 : poDS.reset();
1986 1 : VSIUnlink(tmpFilename);
1987 : }
1988 :
1989 : {
1990 : GDALDatasetUniquePtr poSrcDS(
1991 2 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif"));
1992 1 : EXPECT_TRUE(poSrcDS != nullptr);
1993 1 : auto tmpFilename = "/vsimem/tmp.tif";
1994 1 : const char *options[] = {"-srcwin",
1995 : "0",
1996 : "0",
1997 : "48",
1998 : "32",
1999 : "-ot",
2000 : "UInt16",
2001 : "-co",
2002 : "TILED=YES",
2003 : "-co",
2004 : "BLOCKXSIZE=48",
2005 : "-co",
2006 : "BLOCKYSIZE=32",
2007 : "-co",
2008 : "INTERLEAVE=BAND",
2009 : "-co",
2010 : "ENDIANNESS=BIG",
2011 : nullptr};
2012 : auto psOptions =
2013 1 : GDALTranslateOptionsNew(const_cast<char **>(options), nullptr);
2014 : auto poDS(GDALDatasetUniquePtr(GDALDataset::FromHandle(
2015 : GDALTranslate(tmpFilename, GDALDataset::ToHandle(poSrcDS.get()),
2016 2 : psOptions, nullptr))));
2017 1 : GDALTranslateOptionsFree(psOptions);
2018 1 : EXPECT_TRUE(poDS != nullptr);
2019 2 : GDALDataset::RawBinaryLayout sLayout;
2020 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
2021 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
2022 1 : EXPECT_EQ(
2023 : static_cast<int>(sLayout.eInterleaving),
2024 : static_cast<int>(GDALDataset::RawBinaryLayout::Interleaving::BSQ));
2025 1 : EXPECT_EQ(sLayout.eDataType, GDT_UInt16);
2026 1 : EXPECT_TRUE(!sLayout.bLittleEndianOrder);
2027 1 : EXPECT_TRUE(sLayout.nImageOffset >= 408U);
2028 1 : EXPECT_EQ(sLayout.nPixelOffset, 2);
2029 1 : EXPECT_EQ(sLayout.nLineOffset, 2 * 48);
2030 1 : EXPECT_EQ(sLayout.nBandOffset, 2 * 48 * 32);
2031 1 : poDS.reset();
2032 1 : VSIUnlink(tmpFilename);
2033 : }
2034 : }
2035 :
2036 : // Test GDALDataset::GetRawBinaryLayout() implementations
2037 4 : TEST_F(test_gdal, GetRawBinaryLayout_ISIS3)
2038 : {
2039 1 : if (GDALGetDriverByName("ISIS3") == nullptr)
2040 : {
2041 0 : GTEST_SKIP() << "ISIS3 driver missing";
2042 : }
2043 :
2044 : {
2045 : GDALDatasetUniquePtr poDS(
2046 2 : GDALDataset::Open(GDRIVERS_DATA_DIR "isis3/isis3_detached.lbl"));
2047 1 : EXPECT_TRUE(poDS != nullptr);
2048 2 : GDALDataset::RawBinaryLayout sLayout;
2049 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
2050 1 : EXPECT_TRUE(sLayout.osRawFilename.find("isis3_detached.cub") !=
2051 : std::string::npos);
2052 1 : EXPECT_EQ(static_cast<int>(sLayout.eInterleaving),
2053 : static_cast<int>(
2054 : GDALDataset::RawBinaryLayout::Interleaving::UNKNOWN));
2055 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
2056 1 : EXPECT_TRUE(sLayout.bLittleEndianOrder);
2057 1 : EXPECT_EQ(sLayout.nImageOffset, 0U);
2058 1 : EXPECT_EQ(sLayout.nPixelOffset, 1);
2059 1 : EXPECT_EQ(sLayout.nLineOffset, 317);
2060 : // EXPECT_EQ( sLayout.nBandOffset, 9510 ); // doesn't matter on single
2061 : // band
2062 : }
2063 : }
2064 :
2065 : // Test GDALDataset::GetRawBinaryLayout() implementations
2066 4 : TEST_F(test_gdal, GetRawBinaryLayout_VICAR)
2067 : {
2068 1 : if (GDALGetDriverByName("VICAR") == nullptr)
2069 : {
2070 0 : GTEST_SKIP() << "VICAR driver missing";
2071 : }
2072 :
2073 : {
2074 : GDALDatasetUniquePtr poDS(GDALDataset::Open(
2075 2 : GDRIVERS_DATA_DIR "vicar/test_vicar_truncated.bin"));
2076 1 : EXPECT_TRUE(poDS != nullptr);
2077 2 : GDALDataset::RawBinaryLayout sLayout;
2078 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
2079 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
2080 1 : EXPECT_EQ(static_cast<int>(sLayout.eInterleaving),
2081 : static_cast<int>(
2082 : GDALDataset::RawBinaryLayout::Interleaving::UNKNOWN));
2083 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
2084 1 : EXPECT_TRUE(sLayout.bLittleEndianOrder);
2085 1 : EXPECT_EQ(sLayout.nImageOffset, 9680U);
2086 1 : EXPECT_EQ(sLayout.nPixelOffset, 1);
2087 1 : EXPECT_EQ(sLayout.nLineOffset, 400);
2088 1 : EXPECT_EQ(sLayout.nBandOffset, 0); // doesn't matter on single band
2089 : }
2090 : }
2091 :
2092 : // Test GDALDataset::GetRawBinaryLayout() implementations
2093 4 : TEST_F(test_gdal, GetRawBinaryLayout_FITS)
2094 : {
2095 1 : if (GDALGetDriverByName("FITS") == nullptr)
2096 : {
2097 0 : GTEST_SKIP() << "FITS driver missing";
2098 : }
2099 :
2100 : {
2101 : GDALDatasetUniquePtr poSrcDS(
2102 2 : GDALDataset::Open(GCORE_DATA_DIR "int16.tif"));
2103 1 : EXPECT_TRUE(poSrcDS != nullptr);
2104 2 : CPLString tmpFilename(CPLGenerateTempFilename(nullptr));
2105 1 : tmpFilename += ".fits";
2106 1 : auto poDrv = GDALDriver::FromHandle(GDALGetDriverByName("FITS"));
2107 1 : if (poDrv)
2108 : {
2109 : auto poDS(GDALDatasetUniquePtr(poDrv->CreateCopy(
2110 2 : tmpFilename, poSrcDS.get(), false, nullptr, nullptr, nullptr)));
2111 1 : EXPECT_TRUE(poDS != nullptr);
2112 1 : poDS.reset();
2113 1 : poDS.reset(GDALDataset::Open(tmpFilename));
2114 1 : EXPECT_TRUE(poDS != nullptr);
2115 2 : GDALDataset::RawBinaryLayout sLayout;
2116 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
2117 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
2118 1 : EXPECT_EQ(static_cast<int>(sLayout.eInterleaving),
2119 : static_cast<int>(
2120 : GDALDataset::RawBinaryLayout::Interleaving::UNKNOWN));
2121 1 : EXPECT_EQ(sLayout.eDataType, GDT_Int16);
2122 1 : EXPECT_TRUE(!sLayout.bLittleEndianOrder);
2123 1 : EXPECT_EQ(sLayout.nImageOffset, 2880U);
2124 1 : EXPECT_EQ(sLayout.nPixelOffset, 2);
2125 1 : EXPECT_EQ(sLayout.nLineOffset, 2 * 20);
2126 1 : EXPECT_EQ(sLayout.nBandOffset, 2 * 20 * 20);
2127 1 : poDS.reset();
2128 1 : VSIUnlink(tmpFilename);
2129 : }
2130 : }
2131 : }
2132 :
2133 : // Test GDALDataset::GetRawBinaryLayout() implementations
2134 4 : TEST_F(test_gdal, GetRawBinaryLayout_PDS)
2135 : {
2136 1 : if (GDALGetDriverByName("PDS") == nullptr)
2137 : {
2138 0 : GTEST_SKIP() << "PDS driver missing";
2139 : }
2140 :
2141 : {
2142 : GDALDatasetUniquePtr poDS(
2143 2 : GDALDataset::Open(GDRIVERS_DATA_DIR "pds/mc02_truncated.img"));
2144 1 : EXPECT_TRUE(poDS != nullptr);
2145 2 : GDALDataset::RawBinaryLayout sLayout;
2146 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
2147 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
2148 1 : EXPECT_EQ(static_cast<int>(sLayout.eInterleaving),
2149 : static_cast<int>(
2150 : GDALDataset::RawBinaryLayout::Interleaving::UNKNOWN));
2151 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
2152 1 : EXPECT_TRUE(sLayout.bLittleEndianOrder);
2153 1 : EXPECT_EQ(sLayout.nImageOffset, 3840U);
2154 1 : EXPECT_EQ(sLayout.nPixelOffset, 1);
2155 1 : EXPECT_EQ(sLayout.nLineOffset, 3840);
2156 1 : EXPECT_EQ(sLayout.nBandOffset, 0); // doesn't matter on single band
2157 : }
2158 : }
2159 :
2160 : // Test GDALDataset::GetRawBinaryLayout() implementations
2161 4 : TEST_F(test_gdal, GetRawBinaryLayout_PDS4)
2162 : {
2163 1 : if (GDALGetDriverByName("PDS4") == nullptr)
2164 : {
2165 0 : GTEST_SKIP() << "PDS4 driver missing";
2166 : }
2167 :
2168 : {
2169 : GDALDatasetUniquePtr poDS(GDALDataset::Open(
2170 2 : GDRIVERS_DATA_DIR "pds4/byte_pds4_cart_1700.xml"));
2171 1 : EXPECT_TRUE(poDS != nullptr);
2172 2 : GDALDataset::RawBinaryLayout sLayout;
2173 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
2174 1 : EXPECT_TRUE(sLayout.osRawFilename.find("byte_pds4_cart_1700.img") !=
2175 : std::string::npos);
2176 1 : EXPECT_EQ(static_cast<int>(sLayout.eInterleaving),
2177 : static_cast<int>(
2178 : GDALDataset::RawBinaryLayout::Interleaving::UNKNOWN));
2179 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
2180 1 : EXPECT_TRUE(!sLayout.bLittleEndianOrder);
2181 1 : EXPECT_EQ(sLayout.nImageOffset, 0U);
2182 1 : EXPECT_EQ(sLayout.nPixelOffset, 1);
2183 1 : EXPECT_EQ(sLayout.nLineOffset, 20);
2184 1 : EXPECT_EQ(sLayout.nBandOffset, 0); // doesn't matter on single band
2185 : }
2186 : }
2187 :
2188 : // Test TileMatrixSet
2189 4 : TEST_F(test_gdal, TileMatrixSet)
2190 : {
2191 1 : if (getenv("SKIP_TILEMATRIXSET_TEST") != nullptr)
2192 0 : GTEST_SKIP() << "Test skipped due to SKIP_TILEMATRIXSET_TEST being set";
2193 :
2194 : {
2195 2 : auto l = gdal::TileMatrixSet::listPredefinedTileMatrixSets();
2196 1 : EXPECT_TRUE(std::find(l.begin(), l.end(), "GoogleMapsCompatible") !=
2197 : l.end());
2198 1 : EXPECT_TRUE(std::find(l.begin(), l.end(), "NZTM2000") != l.end());
2199 : }
2200 :
2201 : {
2202 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
2203 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse("i_dont_exist") == nullptr);
2204 1 : CPLPopErrorHandler();
2205 : }
2206 :
2207 : {
2208 1 : CPLErrorReset();
2209 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
2210 : // Invalid JSON
2211 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse(
2212 : "http://127.0.0.1:32767/example.json") == nullptr);
2213 1 : CPLPopErrorHandler();
2214 1 : EXPECT_TRUE(CPLGetLastErrorType() != 0);
2215 : }
2216 :
2217 : {
2218 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
2219 : // Invalid JSON
2220 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse(
2221 : "{\"type\": \"TileMatrixSetType\" invalid") == nullptr);
2222 1 : CPLPopErrorHandler();
2223 : }
2224 :
2225 : {
2226 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
2227 : // No tileMatrix
2228 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse(
2229 : "{\"type\": \"TileMatrixSetType\" }") == nullptr);
2230 1 : CPLPopErrorHandler();
2231 : }
2232 :
2233 : {
2234 2 : auto poTMS = gdal::TileMatrixSet::parse("LINZAntarticaMapTileGrid");
2235 1 : EXPECT_TRUE(poTMS != nullptr);
2236 1 : if (poTMS)
2237 : {
2238 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTopLeft());
2239 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTileSize());
2240 1 : EXPECT_TRUE(poTMS->hasOnlyPowerOfTwoVaryingScales());
2241 1 : EXPECT_TRUE(!poTMS->hasVariableMatrixWidth());
2242 : }
2243 : }
2244 :
2245 : {
2246 2 : auto poTMS = gdal::TileMatrixSet::parse("NZTM2000");
2247 1 : EXPECT_TRUE(poTMS != nullptr);
2248 1 : if (poTMS)
2249 : {
2250 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTopLeft());
2251 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTileSize());
2252 1 : EXPECT_TRUE(!poTMS->hasOnlyPowerOfTwoVaryingScales());
2253 1 : EXPECT_TRUE(!poTMS->hasVariableMatrixWidth());
2254 : }
2255 : }
2256 :
2257 : // Inline JSON with minimal structure
2258 : {
2259 : auto poTMS = gdal::TileMatrixSet::parse(
2260 : "{\"type\": \"TileMatrixSetType\", \"supportedCRS\": "
2261 : "\"http://www.opengis.net/def/crs/OGC/1.3/CRS84\", \"tileMatrix\": "
2262 : "[{ \"topLeftCorner\": [-180, "
2263 : "90],\"scaleDenominator\":1.0,\"tileWidth\": 1,"
2264 : "\"tileHeight\": 1,"
2265 : "\"matrixWidth\": 1,"
2266 2 : "\"matrixHeight\": 1}] }");
2267 1 : EXPECT_TRUE(poTMS != nullptr);
2268 1 : if (poTMS)
2269 : {
2270 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTopLeft());
2271 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTileSize());
2272 1 : EXPECT_TRUE(poTMS->hasOnlyPowerOfTwoVaryingScales());
2273 1 : EXPECT_TRUE(!poTMS->hasVariableMatrixWidth());
2274 : }
2275 : }
2276 :
2277 : {
2278 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
2279 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse(
2280 : "{\"type\": \"TileMatrixSetType\", \"supportedCRS\": "
2281 : "\"http://www.opengis.net/def/crs/OGC/1.3/CRS84\", "
2282 : "\"tileMatrix\": [{ \"topLeftCorner\": [-180, "
2283 : "90],\"scaleDenominator\":0.0,\"tileWidth\": 1,"
2284 : "\"tileHeight\": 1,"
2285 : "\"matrixWidth\": 1,"
2286 : "\"matrixHeight\": 1}] }") == nullptr);
2287 1 : EXPECT_STREQ(CPLGetLastErrorMsg(),
2288 : "Invalid scale denominator or non-decreasing series of "
2289 : "scale denominators");
2290 1 : CPLPopErrorHandler();
2291 : }
2292 :
2293 : {
2294 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
2295 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse(
2296 : "{\"type\": \"TileMatrixSetType\", \"supportedCRS\": "
2297 : "\"http://www.opengis.net/def/crs/OGC/1.3/CRS84\", "
2298 : "\"tileMatrix\": [{ \"topLeftCorner\": [-180, "
2299 : "90],\"scaleDenominator\":1.0,\"tileWidth\": 0,"
2300 : "\"tileHeight\": 1,"
2301 : "\"matrixWidth\": 1,"
2302 : "\"matrixHeight\": 1}] }") == nullptr);
2303 1 : EXPECT_STREQ(CPLGetLastErrorMsg(), "Invalid tileWidth: 0");
2304 1 : CPLPopErrorHandler();
2305 : }
2306 :
2307 : {
2308 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
2309 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse(
2310 : "{\"type\": \"TileMatrixSetType\", \"supportedCRS\": "
2311 : "\"http://www.opengis.net/def/crs/OGC/1.3/CRS84\", "
2312 : "\"tileMatrix\": [{ \"topLeftCorner\": [-180, "
2313 : "90],\"scaleDenominator\":1.0,\"tileWidth\": 1,"
2314 : "\"tileHeight\": 0,"
2315 : "\"matrixWidth\": 1,"
2316 : "\"matrixHeight\": 1}] }") == nullptr);
2317 1 : EXPECT_STREQ(CPLGetLastErrorMsg(), "Invalid tileHeight: 0");
2318 1 : CPLPopErrorHandler();
2319 : }
2320 :
2321 : {
2322 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
2323 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse(
2324 : "{\"type\": \"TileMatrixSetType\", \"supportedCRS\": "
2325 : "\"http://www.opengis.net/def/crs/OGC/1.3/CRS84\", "
2326 : "\"tileMatrix\": [{ \"topLeftCorner\": [-180, "
2327 : "90],\"scaleDenominator\":1.0,\"tileWidth\": 100000,"
2328 : "\"tileHeight\": 100000,"
2329 : "\"matrixWidth\": 1,"
2330 : "\"matrixHeight\": 1}] }") == nullptr);
2331 1 : EXPECT_STREQ(
2332 : CPLGetLastErrorMsg(),
2333 : "tileWidth(100000) x tileHeight(100000) larger than INT_MAX");
2334 1 : CPLPopErrorHandler();
2335 : }
2336 :
2337 : {
2338 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
2339 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse(
2340 : "{\"type\": \"TileMatrixSetType\", \"supportedCRS\": "
2341 : "\"http://www.opengis.net/def/crs/OGC/1.3/CRS84\", "
2342 : "\"tileMatrix\": [{ \"topLeftCorner\": [-180, "
2343 : "90],\"scaleDenominator\":1.0,\"tileWidth\": 1,"
2344 : "\"tileHeight\": 1,"
2345 : "\"matrixWidth\": 0,"
2346 : "\"matrixHeight\": 1}] }") == nullptr);
2347 1 : EXPECT_STREQ(CPLGetLastErrorMsg(), "Invalid matrixWidth: 0");
2348 1 : CPLPopErrorHandler();
2349 : }
2350 :
2351 : {
2352 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
2353 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse(
2354 : "{\"type\": \"TileMatrixSetType\", \"supportedCRS\": "
2355 : "\"http://www.opengis.net/def/crs/OGC/1.3/CRS84\", "
2356 : "\"tileMatrix\": [{ \"topLeftCorner\": [-180, "
2357 : "90],\"scaleDenominator\":1.0,\"tileWidth\": 1,"
2358 : "\"tileHeight\": 1,"
2359 : "\"matrixWidth\": 1,"
2360 : "\"matrixHeight\": 0}] }") == nullptr);
2361 1 : EXPECT_STREQ(CPLGetLastErrorMsg(), "Invalid matrixHeight: 0");
2362 1 : CPLPopErrorHandler();
2363 : }
2364 :
2365 : {
2366 1 : const char *pszJSON = "{"
2367 : " \"type\": \"TileMatrixSetType\","
2368 : " \"title\": \"CRS84 for the World\","
2369 : " \"identifier\": \"WorldCRS84Quad\","
2370 : " \"abstract\": \"my abstract\","
2371 : " \"boundingBox\":"
2372 : " {"
2373 : " \"type\": \"BoundingBoxType\","
2374 : " \"crs\": "
2375 : "\"http://www.opengis.net/def/crs/OGC/1.X/"
2376 : "CRS84\"," // 1.3 modified to 1.X to test
2377 : // difference with supportedCRS
2378 : " \"lowerCorner\": [-180, -90],"
2379 : " \"upperCorner\": [180, 90]"
2380 : " },"
2381 : " \"supportedCRS\": "
2382 : "\"http://www.opengis.net/def/crs/OGC/1.3/"
2383 : "CRS84\","
2384 : " \"wellKnownScaleSet\": "
2385 : "\"http://www.opengis.net/def/wkss/OGC/1.0/"
2386 : "GoogleCRS84Quad\","
2387 : " \"tileMatrix\":"
2388 : " ["
2389 : " {"
2390 : " \"type\": \"TileMatrixType\","
2391 : " \"identifier\": \"0\","
2392 : " \"scaleDenominator\": "
2393 : "279541132.014358,"
2394 : " \"topLeftCorner\": [-180, 90],"
2395 : " \"tileWidth\": 256,"
2396 : " \"tileHeight\": 256,"
2397 : " \"matrixWidth\": 2,"
2398 : " \"matrixHeight\": 1"
2399 : " },"
2400 : " {"
2401 : " \"type\": \"TileMatrixType\","
2402 : " \"identifier\": \"1\","
2403 : " \"scaleDenominator\": "
2404 : "139770566.007179,"
2405 : " \"topLeftCorner\": [-180, 90],"
2406 : " \"tileWidth\": 256,"
2407 : " \"tileHeight\": 256,"
2408 : " \"matrixWidth\": 4,"
2409 : " \"matrixHeight\": 2"
2410 : " }"
2411 : " ]"
2412 : "}";
2413 1 : VSIFCloseL(VSIFileFromMemBuffer(
2414 : "/vsimem/tmp.json",
2415 : reinterpret_cast<GByte *>(const_cast<char *>(pszJSON)),
2416 1 : strlen(pszJSON), false));
2417 1 : auto poTMS = gdal::TileMatrixSet::parse("/vsimem/tmp.json");
2418 1 : VSIUnlink("/vsimem/tmp.json");
2419 :
2420 1 : EXPECT_TRUE(poTMS != nullptr);
2421 1 : if (poTMS)
2422 : {
2423 1 : EXPECT_EQ(poTMS->title(), "CRS84 for the World");
2424 1 : EXPECT_EQ(poTMS->identifier(), "WorldCRS84Quad");
2425 1 : EXPECT_EQ(poTMS->abstract(), "my abstract");
2426 1 : EXPECT_EQ(poTMS->crs(),
2427 : "http://www.opengis.net/def/crs/OGC/1.3/CRS84");
2428 1 : EXPECT_EQ(
2429 : poTMS->wellKnownScaleSet(),
2430 : "http://www.opengis.net/def/wkss/OGC/1.0/GoogleCRS84Quad");
2431 1 : EXPECT_EQ(poTMS->bbox().mCrs,
2432 : "http://www.opengis.net/def/crs/OGC/1.X/CRS84");
2433 1 : EXPECT_EQ(poTMS->bbox().mLowerCornerX, -180.0);
2434 1 : EXPECT_EQ(poTMS->bbox().mLowerCornerY, -90.0);
2435 1 : EXPECT_EQ(poTMS->bbox().mUpperCornerX, 180.0);
2436 1 : EXPECT_EQ(poTMS->bbox().mUpperCornerY, 90.0);
2437 1 : ASSERT_EQ(poTMS->tileMatrixList().size(), 2U);
2438 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTopLeft());
2439 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTileSize());
2440 1 : EXPECT_TRUE(poTMS->hasOnlyPowerOfTwoVaryingScales());
2441 1 : EXPECT_TRUE(!poTMS->hasVariableMatrixWidth());
2442 1 : const auto &tm = poTMS->tileMatrixList()[0];
2443 1 : EXPECT_EQ(tm.mId, "0");
2444 1 : EXPECT_EQ(tm.mScaleDenominator, 279541132.014358);
2445 1 : EXPECT_TRUE(fabs(tm.mResX - tm.mScaleDenominator * 0.28e-3 /
2446 : (6378137. * M_PI / 180)) < 1e-10);
2447 1 : EXPECT_TRUE(fabs(tm.mResX - 180. / 256) < 1e-10);
2448 1 : EXPECT_EQ(tm.mResY, tm.mResX);
2449 1 : EXPECT_EQ(tm.mTopLeftX, -180.0);
2450 1 : EXPECT_EQ(tm.mTopLeftY, 90.0);
2451 1 : EXPECT_EQ(tm.mTileWidth, 256);
2452 1 : EXPECT_EQ(tm.mTileHeight, 256);
2453 1 : EXPECT_EQ(tm.mMatrixWidth, 2);
2454 1 : EXPECT_EQ(tm.mMatrixHeight, 1);
2455 : }
2456 : }
2457 :
2458 : {
2459 1 : const char *pszJSON =
2460 : "{\n"
2461 : " \"type\":\"TileMatrixSetType\",\n"
2462 : " \"title\":\"CRS84 for the World\",\n"
2463 : " \"identifier\":\"WorldCRS84Quad\",\n"
2464 : " \"boundingBox\":{\n"
2465 : " \"type\":\"BoundingBoxType\",\n"
2466 : // 1.3 modified to 1.X to test difference with supportedCRS
2467 : " \"crs\":\"http://www.opengis.net/def/crs/OGC/1.X/CRS84\",\n"
2468 : " \"lowerCorner\":[\n"
2469 : " -180.0,\n"
2470 : " -90.0\n"
2471 : " ],\n"
2472 : " \"upperCorner\":[\n"
2473 : " 180.0,\n"
2474 : " 90.0\n"
2475 : " ]\n"
2476 : " },\n"
2477 : " "
2478 : "\"supportedCRS\":\"http://www.opengis.net/def/crs/OGC/1.3/"
2479 : "CRS84\",\n"
2480 : " "
2481 : "\"wellKnownScaleSet\":\"http://www.opengis.net/def/wkss/OGC/1.0/"
2482 : "GoogleCRS84Quad\",\n"
2483 : " \"tileMatrix\":[\n"
2484 : " {\n"
2485 : " \"type\":\"TileMatrixType\",\n"
2486 : " \"identifier\":\"0\",\n"
2487 : " \"scaleDenominator\":279541132.01435798,\n"
2488 : " \"topLeftCorner\":[\n"
2489 : " -180.0,\n"
2490 : " 90.0\n"
2491 : " ],\n"
2492 : " \"tileWidth\":256,\n"
2493 : " \"tileHeight\":256,\n"
2494 : " \"matrixWidth\":2,\n"
2495 : " \"matrixHeight\":1\n"
2496 : " },\n"
2497 : " {\n"
2498 : " \"type\":\"TileMatrixType\",\n"
2499 : " \"identifier\":\"1\",\n"
2500 : " \"scaleDenominator\":100000000.0,\n"
2501 : " \"topLeftCorner\":[\n"
2502 : " -123.0,\n"
2503 : " 90.0\n"
2504 : " ],\n"
2505 : " \"tileWidth\":128,\n"
2506 : " \"tileHeight\":256,\n"
2507 : " \"matrixWidth\":4,\n"
2508 : " \"matrixHeight\":2,\n"
2509 : " \"variableMatrixWidth\":[\n"
2510 : " {\n"
2511 : " \"coalesce\":2,\n"
2512 : " \"minTileRow\":0,\n"
2513 : " \"maxTileRow\":1\n"
2514 : " }\n"
2515 : " ]\n"
2516 : " }\n"
2517 : " ]\n"
2518 : "}";
2519 1 : auto poTMS = gdal::TileMatrixSet::parse(pszJSON);
2520 1 : EXPECT_TRUE(poTMS != nullptr);
2521 1 : if (poTMS)
2522 : {
2523 1 : ASSERT_EQ(poTMS->tileMatrixList().size(), 2U);
2524 1 : EXPECT_TRUE(!poTMS->haveAllLevelsSameTopLeft());
2525 1 : EXPECT_TRUE(!poTMS->haveAllLevelsSameTileSize());
2526 1 : EXPECT_TRUE(!poTMS->hasOnlyPowerOfTwoVaryingScales());
2527 1 : EXPECT_TRUE(poTMS->hasVariableMatrixWidth());
2528 1 : const auto &tm = poTMS->tileMatrixList()[1];
2529 1 : EXPECT_EQ(tm.mVariableMatrixWidthList.size(), 1U);
2530 1 : const auto &vmw = tm.mVariableMatrixWidthList[0];
2531 1 : EXPECT_EQ(vmw.mCoalesce, 2);
2532 1 : EXPECT_EQ(vmw.mMinTileRow, 0);
2533 1 : EXPECT_EQ(vmw.mMaxTileRow, 1);
2534 :
2535 2 : EXPECT_STREQ(poTMS->exportToTMSJsonV1().c_str(), pszJSON);
2536 : }
2537 : }
2538 :
2539 : {
2540 : auto poTMS = gdal::TileMatrixSet::parse(
2541 : "{"
2542 : " \"identifier\" : \"CDBGlobalGrid\","
2543 : " \"title\" : \"CDBGlobalGrid\","
2544 : " \"boundingBox\" : {"
2545 : " \"crs\" : \"http://www.opengis.net/def/crs/EPSG/0/4326\","
2546 : " \"lowerCorner\" : ["
2547 : " -90,"
2548 : " -180"
2549 : " ],"
2550 : " \"upperCorner\" : ["
2551 : " 90,"
2552 : " 180"
2553 : " ]"
2554 : " },"
2555 : " \"supportedCRS\" : "
2556 : "\"http://www.opengis.net/def/crs/EPSG/0/4326\","
2557 : " \"wellKnownScaleSet\" : "
2558 : "\"http://www.opengis.net/def/wkss/OGC/1.0/CDBGlobalGrid\","
2559 : " \"tileMatrix\" : ["
2560 : " {"
2561 : " \"identifier\" : \"-10\","
2562 : " \"scaleDenominator\" : 397569609.975977063179,"
2563 : " \"matrixWidth\" : 360,"
2564 : " \"matrixHeight\" : 180,"
2565 : " \"tileWidth\" : 1,"
2566 : " \"tileHeight\" : 1,"
2567 : " \"topLeftCorner\" : ["
2568 : " 90,"
2569 : " -180"
2570 : " ],"
2571 : " \"variableMatrixWidth\" : ["
2572 : " {"
2573 : " \"coalesce\" : 12,"
2574 : " \"minTileRow\" : 0,"
2575 : " \"maxTileRow\" : 0"
2576 : " },"
2577 : " {"
2578 : " \"coalesce\" : 12,"
2579 : " \"minTileRow\" : 179,"
2580 : " \"maxTileRow\" : 179"
2581 : " }"
2582 : " ]"
2583 : " }"
2584 : " ]"
2585 1 : "}");
2586 1 : EXPECT_TRUE(poTMS != nullptr);
2587 1 : if (poTMS)
2588 : {
2589 1 : ASSERT_EQ(poTMS->tileMatrixList().size(), 1U);
2590 1 : const auto &tm = poTMS->tileMatrixList()[0];
2591 1 : EXPECT_EQ(tm.mVariableMatrixWidthList.size(), 2U);
2592 1 : const auto &vmw = tm.mVariableMatrixWidthList[0];
2593 1 : EXPECT_EQ(vmw.mCoalesce, 12);
2594 1 : EXPECT_EQ(vmw.mMinTileRow, 0);
2595 1 : EXPECT_EQ(vmw.mMaxTileRow, 0);
2596 : }
2597 : }
2598 :
2599 : // TMS v2 (truncated version of https://maps.gnosis.earth/ogcapi/tileMatrixSets/GNOSISGlobalGrid?f=json)
2600 : {
2601 : auto poTMS = gdal::TileMatrixSet::parse(
2602 : "{"
2603 : " \"id\" : \"GNOSISGlobalGrid\","
2604 : " \"title\" : \"GNOSISGlobalGrid\","
2605 : " \"uri\" : "
2606 : "\"http://www.opengis.net/def/tilematrixset/OGC/1.0/"
2607 : "GNOSISGlobalGrid\","
2608 : " \"description\": \"added for testing\","
2609 : " \"crs\" : \"http://www.opengis.net/def/crs/EPSG/0/4326\","
2610 : " \"orderedAxes\" : ["
2611 : " \"Lat\","
2612 : " \"Lon\""
2613 : " ],"
2614 : " \"wellKnownScaleSet\" : "
2615 : "\"http://www.opengis.net/def/wkss/OGC/1.0/GoogleCRS84Quad\","
2616 : " \"tileMatrices\" : ["
2617 : " {"
2618 : " \"id\" : \"0\","
2619 : " \"scaleDenominator\" : 139770566.0071794390678,"
2620 : " \"cellSize\" : 0.3515625,"
2621 : " \"cornerOfOrigin\" : \"topLeft\","
2622 : " \"pointOfOrigin\" : [ 90, -180 ],"
2623 : " \"matrixWidth\" : 4,"
2624 : " \"matrixHeight\" : 2,"
2625 : " \"tileWidth\" : 256,"
2626 : " \"tileHeight\" : 256"
2627 : " },"
2628 : " {"
2629 : " \"id\" : \"1\","
2630 : " \"scaleDenominator\" : 69885283.0035897195339,"
2631 : " \"cellSize\" : 0.17578125,"
2632 : " \"cornerOfOrigin\" : \"topLeft\","
2633 : " \"pointOfOrigin\" : [ 90, -180 ],"
2634 : " \"matrixWidth\" : 8,"
2635 : " \"matrixHeight\" : 4,"
2636 : " \"tileWidth\" : 256,"
2637 : " \"tileHeight\" : 256,"
2638 : " \"variableMatrixWidths\" : ["
2639 : " { \"coalesce\" : 2, \"minTileRow\" : 0, "
2640 : "\"maxTileRow\" : 0 },"
2641 : " { \"coalesce\" : 2, \"minTileRow\" : 3, "
2642 : "\"maxTileRow\" : 3 }"
2643 : " ]"
2644 : " }"
2645 : " ]"
2646 1 : "}");
2647 1 : EXPECT_TRUE(poTMS != nullptr);
2648 1 : if (poTMS)
2649 : {
2650 1 : EXPECT_EQ(poTMS->title(), "GNOSISGlobalGrid");
2651 1 : EXPECT_EQ(poTMS->identifier(), "GNOSISGlobalGrid");
2652 1 : EXPECT_EQ(poTMS->abstract(), "added for testing");
2653 1 : EXPECT_EQ(poTMS->crs(),
2654 : "http://www.opengis.net/def/crs/EPSG/0/4326");
2655 1 : EXPECT_EQ(
2656 : poTMS->wellKnownScaleSet(),
2657 : "http://www.opengis.net/def/wkss/OGC/1.0/GoogleCRS84Quad");
2658 1 : ASSERT_EQ(poTMS->tileMatrixList().size(), 2U);
2659 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTopLeft());
2660 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTileSize());
2661 1 : EXPECT_TRUE(poTMS->hasOnlyPowerOfTwoVaryingScales());
2662 : {
2663 1 : const auto &tm = poTMS->tileMatrixList()[0];
2664 1 : EXPECT_EQ(tm.mId, "0");
2665 1 : EXPECT_EQ(tm.mScaleDenominator, 139770566.0071794390678);
2666 1 : EXPECT_TRUE(fabs(tm.mResX - tm.mScaleDenominator * 0.28e-3 /
2667 : (6378137. * M_PI / 180)) <
2668 : 1e-10);
2669 1 : EXPECT_EQ(tm.mResY, tm.mResX);
2670 1 : EXPECT_EQ(tm.mTopLeftX, 90.0);
2671 1 : EXPECT_EQ(tm.mTopLeftY, -180.0);
2672 1 : EXPECT_EQ(tm.mTileWidth, 256);
2673 1 : EXPECT_EQ(tm.mTileHeight, 256);
2674 1 : EXPECT_EQ(tm.mMatrixWidth, 4);
2675 1 : EXPECT_EQ(tm.mMatrixHeight, 2);
2676 : }
2677 :
2678 1 : EXPECT_TRUE(poTMS->hasVariableMatrixWidth());
2679 : {
2680 1 : const auto &tm = poTMS->tileMatrixList()[1];
2681 1 : EXPECT_EQ(tm.mVariableMatrixWidthList.size(), 2U);
2682 1 : const auto &vmw = tm.mVariableMatrixWidthList[1];
2683 1 : EXPECT_EQ(vmw.mCoalesce, 2);
2684 1 : EXPECT_EQ(vmw.mMinTileRow, 3);
2685 1 : EXPECT_EQ(vmw.mMaxTileRow, 3);
2686 : }
2687 : }
2688 : }
2689 :
2690 : // TMS v2 with crs.uri
2691 : {
2692 : auto poTMS = gdal::TileMatrixSet::parse(
2693 : "{"
2694 : " \"id\" : \"test\","
2695 : " \"title\" : \"test\","
2696 : " \"uri\" : "
2697 : "\"http://www.opengis.net/def/tilematrixset/OGC/1.0/test\","
2698 : " \"crs\" : {\"uri\": "
2699 : "\"http://www.opengis.net/def/crs/EPSG/0/4326\"},"
2700 : " \"orderedAxes\" : ["
2701 : " \"Lat\","
2702 : " \"Lon\""
2703 : " ],"
2704 : " \"wellKnownScaleSet\" : "
2705 : "\"http://www.opengis.net/def/wkss/OGC/1.0/GoogleCRS84Quad\","
2706 : " \"tileMatrices\" : ["
2707 : " {"
2708 : " \"id\" : \"0\","
2709 : " \"scaleDenominator\" : 139770566.0071794390678,"
2710 : " \"cellSize\" : 0.3515625,"
2711 : " \"cornerOfOrigin\" : \"topLeft\","
2712 : " \"pointOfOrigin\" : [ 90, -180 ],"
2713 : " \"matrixWidth\" : 4,"
2714 : " \"matrixHeight\" : 2,"
2715 : " \"tileWidth\" : 256,"
2716 : " \"tileHeight\" : 256"
2717 : " }"
2718 : " ]"
2719 2 : "}");
2720 1 : EXPECT_TRUE(poTMS != nullptr);
2721 1 : if (poTMS)
2722 : {
2723 1 : EXPECT_EQ(poTMS->crs(),
2724 : "http://www.opengis.net/def/crs/EPSG/0/4326");
2725 : }
2726 : }
2727 :
2728 : // TMS v2 with crs.wkt
2729 : {
2730 : auto poTMS = gdal::TileMatrixSet::parse(
2731 : "{"
2732 : " \"id\" : \"test\","
2733 : " \"title\" : \"test\","
2734 : " \"uri\" : "
2735 : "\"http://www.opengis.net/def/tilematrixset/OGC/1.0/test\","
2736 : " \"crs\" : {\"wkt\": \"GEOGCRS[\\\"WGS 84\\\","
2737 : "ENSEMBLE[\\\"World Geodetic System 1984 ensemble\\\","
2738 : "MEMBER[\\\"World Geodetic System 1984 (Transit)\\\"],"
2739 : "MEMBER[\\\"World Geodetic System 1984 (G730)\\\"],"
2740 : "MEMBER[\\\"World Geodetic System 1984 (G873)\\\"],"
2741 : "MEMBER[\\\"World Geodetic System 1984 (G1150)\\\"],"
2742 : "MEMBER[\\\"World Geodetic System 1984 (G1674)\\\"],"
2743 : "MEMBER[\\\"World Geodetic System 1984 (G1762)\\\"],"
2744 : "MEMBER[\\\"World Geodetic System 1984 (G2139)\\\"],"
2745 : "MEMBER[\\\"World Geodetic System 1984 (G2296)\\\"],"
2746 : "ELLIPSOID[\\\"WGS 84\\\",6378137,298.257223563,"
2747 : "LENGTHUNIT[\\\"metre\\\",1]],"
2748 : "ENSEMBLEACCURACY[2.0]],"
2749 : "PRIMEM[\\\"Greenwich\\\",0,"
2750 : "ANGLEUNIT[\\\"degree\\\",0.0174532925199433]],"
2751 : "CS[ellipsoidal,2],"
2752 : "AXIS[\\\"geodetic latitude (Lat)\\\",north,"
2753 : "ORDER[1],"
2754 : "ANGLEUNIT[\\\"degree\\\",0.0174532925199433]],"
2755 : "AXIS[\\\"geodetic longitude (Lon)\\\",east,"
2756 : "ORDER[2],"
2757 : "ANGLEUNIT[\\\"degree\\\",0.0174532925199433]],"
2758 : "USAGE["
2759 : "SCOPE[\\\"Horizontal component of 3D system.\\\"],"
2760 : "AREA[\\\"World.\\\"],"
2761 : "BBOX[-90,-180,90,180]],"
2762 : "ID[\\\"EPSG\\\",4326]]\" },"
2763 : " \"orderedAxes\" : ["
2764 : " \"Lat\","
2765 : " \"Lon\""
2766 : " ],"
2767 : " \"wellKnownScaleSet\" : "
2768 : "\"http://www.opengis.net/def/wkss/OGC/1.0/GoogleCRS84Quad\","
2769 : " \"tileMatrices\" : ["
2770 : " {"
2771 : " \"id\" : \"0\","
2772 : " \"scaleDenominator\" : 139770566.0071794390678,"
2773 : " \"cellSize\" : 0.3515625,"
2774 : " \"cornerOfOrigin\" : \"topLeft\","
2775 : " \"pointOfOrigin\" : [ 90, -180 ],"
2776 : " \"matrixWidth\" : 4,"
2777 : " \"matrixHeight\" : 2,"
2778 : " \"tileWidth\" : 256,"
2779 : " \"tileHeight\" : 256"
2780 : " }"
2781 : " ]"
2782 2 : "}");
2783 1 : EXPECT_TRUE(poTMS != nullptr);
2784 1 : if (poTMS)
2785 : {
2786 1 : EXPECT_TRUE(
2787 : STARTS_WITH(poTMS->crs().c_str(), "GEOGCRS[\"WGS 84\""));
2788 : }
2789 : }
2790 :
2791 : // TMS v2 with crs.wkt with JSON content
2792 : {
2793 : auto poTMS = gdal::TileMatrixSet::parse(
2794 : "{"
2795 : " \"id\" : \"test\","
2796 : " \"title\" : \"test\","
2797 : " \"uri\" : "
2798 : "\"http://www.opengis.net/def/tilematrixset/OGC/1.0/test\","
2799 : " \"crs\" : {\"wkt\": "
2800 : "{"
2801 : " \"type\": \"GeographicCRS\","
2802 : " \"name\": \"WGS 84\","
2803 : " \"datum_ensemble\": {"
2804 : " \"name\": \"World Geodetic System 1984 ensemble\","
2805 : " \"members\": ["
2806 : " {"
2807 : " \"name\": \"World Geodetic System 1984 (Transit)\","
2808 : " \"id\": {"
2809 : " \"authority\": \"EPSG\","
2810 : " \"code\": 1166"
2811 : " }"
2812 : " },"
2813 : " {"
2814 : " \"name\": \"World Geodetic System 1984 (G730)\","
2815 : " \"id\": {"
2816 : " \"authority\": \"EPSG\","
2817 : " \"code\": 1152"
2818 : " }"
2819 : " },"
2820 : " {"
2821 : " \"name\": \"World Geodetic System 1984 (G873)\","
2822 : " \"id\": {"
2823 : " \"authority\": \"EPSG\","
2824 : " \"code\": 1153"
2825 : " }"
2826 : " },"
2827 : " {"
2828 : " \"name\": \"World Geodetic System 1984 (G1150)\","
2829 : " \"id\": {"
2830 : " \"authority\": \"EPSG\","
2831 : " \"code\": 1154"
2832 : " }"
2833 : " },"
2834 : " {"
2835 : " \"name\": \"World Geodetic System 1984 (G1674)\","
2836 : " \"id\": {"
2837 : " \"authority\": \"EPSG\","
2838 : " \"code\": 1155"
2839 : " }"
2840 : " },"
2841 : " {"
2842 : " \"name\": \"World Geodetic System 1984 (G1762)\","
2843 : " \"id\": {"
2844 : " \"authority\": \"EPSG\","
2845 : " \"code\": 1156"
2846 : " }"
2847 : " },"
2848 : " {"
2849 : " \"name\": \"World Geodetic System 1984 (G2139)\","
2850 : " \"id\": {"
2851 : " \"authority\": \"EPSG\","
2852 : " \"code\": 1309"
2853 : " }"
2854 : " },"
2855 : " {"
2856 : " \"name\": \"World Geodetic System 1984 (G2296)\","
2857 : " \"id\": {"
2858 : " \"authority\": \"EPSG\","
2859 : " \"code\": 1383"
2860 : " }"
2861 : " }"
2862 : " ],"
2863 : " \"ellipsoid\": {"
2864 : " \"name\": \"WGS 84\","
2865 : " \"semi_major_axis\": 6378137,"
2866 : " \"inverse_flattening\": 298.257223563"
2867 : " },"
2868 : " \"accuracy\": \"2.0\","
2869 : " \"id\": {"
2870 : " \"authority\": \"EPSG\","
2871 : " \"code\": 6326"
2872 : " }"
2873 : " },"
2874 : " \"coordinate_system\": {"
2875 : " \"subtype\": \"ellipsoidal\","
2876 : " \"axis\": ["
2877 : " {"
2878 : " \"name\": \"Geodetic latitude\","
2879 : " \"abbreviation\": \"Lat\","
2880 : " \"direction\": \"north\","
2881 : " \"unit\": \"degree\""
2882 : " },"
2883 : " {"
2884 : " \"name\": \"Geodetic longitude\","
2885 : " \"abbreviation\": \"Lon\","
2886 : " \"direction\": \"east\","
2887 : " \"unit\": \"degree\""
2888 : " }"
2889 : " ]"
2890 : " },"
2891 : " \"scope\": \"Horizontal component of 3D system.\","
2892 : " \"area\": \"World.\","
2893 : " \"bbox\": {"
2894 : " \"south_latitude\": -90,"
2895 : " \"west_longitude\": -180,"
2896 : " \"north_latitude\": 90,"
2897 : " \"east_longitude\": 180"
2898 : " },"
2899 : " \"id\": {"
2900 : " \"authority\": \"EPSG\","
2901 : " \"code\": 4326"
2902 : " }"
2903 : "}"
2904 : "},"
2905 : " \"orderedAxes\" : ["
2906 : " \"Lat\","
2907 : " \"Lon\""
2908 : " ],"
2909 : " \"wellKnownScaleSet\" : "
2910 : "\"http://www.opengis.net/def/wkss/OGC/1.0/GoogleCRS84Quad\","
2911 : " \"tileMatrices\" : ["
2912 : " {"
2913 : " \"id\" : \"0\","
2914 : " \"scaleDenominator\" : 139770566.0071794390678,"
2915 : " \"cellSize\" : 0.3515625,"
2916 : " \"cornerOfOrigin\" : \"topLeft\","
2917 : " \"pointOfOrigin\" : [ 90, -180 ],"
2918 : " \"matrixWidth\" : 4,"
2919 : " \"matrixHeight\" : 2,"
2920 : " \"tileWidth\" : 256,"
2921 : " \"tileHeight\" : 256"
2922 : " }"
2923 : " ]"
2924 2 : "}");
2925 1 : EXPECT_TRUE(poTMS != nullptr);
2926 1 : if (poTMS)
2927 : {
2928 1 : EXPECT_TRUE(STARTS_WITH(poTMS->crs().c_str(),
2929 : "{ \"type\": \"GeographicCRS\""));
2930 : }
2931 : }
2932 : }
2933 :
2934 : // Test that PCIDSK GetMetadataItem() return is stable
2935 4 : TEST_F(test_gdal, PCIDSK_GetMetadataItem)
2936 : {
2937 1 : auto poDrv = GDALDriver::FromHandle(GDALGetDriverByName("PCIDSK"));
2938 1 : if (poDrv == nullptr)
2939 0 : GTEST_SKIP() << "PCIDSK driver missing";
2940 :
2941 : GDALDatasetUniquePtr poDS(
2942 2 : poDrv->Create("/vsimem/tmp.pix", 1, 1, 1, GDT_Byte, nullptr));
2943 1 : EXPECT_TRUE(poDS != nullptr);
2944 1 : poDS->SetMetadataItem("FOO", "BAR");
2945 1 : poDS->SetMetadataItem("BAR", "BAZ");
2946 1 : poDS->GetRasterBand(1)->SetMetadataItem("FOO", "BAR");
2947 1 : poDS->GetRasterBand(1)->SetMetadataItem("BAR", "BAZ");
2948 :
2949 : {
2950 1 : const char *psz1 = poDS->GetMetadataItem("FOO");
2951 1 : const char *psz2 = poDS->GetMetadataItem("BAR");
2952 1 : const char *pszNull = poDS->GetMetadataItem("I_DONT_EXIST");
2953 1 : const char *psz3 = poDS->GetMetadataItem("FOO");
2954 1 : const char *pszNull2 = poDS->GetMetadataItem("I_DONT_EXIST");
2955 1 : const char *psz4 = poDS->GetMetadataItem("BAR");
2956 1 : EXPECT_TRUE(psz1 != nullptr);
2957 1 : EXPECT_TRUE(psz2 != nullptr);
2958 1 : EXPECT_TRUE(psz3 != nullptr);
2959 1 : EXPECT_TRUE(psz4 != nullptr);
2960 1 : EXPECT_TRUE(pszNull == nullptr);
2961 1 : EXPECT_TRUE(pszNull2 == nullptr);
2962 1 : EXPECT_EQ(psz1, psz3);
2963 1 : EXPECT_TRUE(psz1 != psz2);
2964 1 : EXPECT_EQ(psz2, psz4);
2965 1 : EXPECT_STREQ(psz1, "BAR");
2966 1 : EXPECT_STREQ(psz2, "BAZ");
2967 : }
2968 :
2969 : {
2970 1 : auto poBand = poDS->GetRasterBand(1);
2971 1 : const char *psz1 = poBand->GetMetadataItem("FOO");
2972 1 : const char *psz2 = poBand->GetMetadataItem("BAR");
2973 1 : const char *pszNull = poBand->GetMetadataItem("I_DONT_EXIST");
2974 1 : const char *psz3 = poBand->GetMetadataItem("FOO");
2975 1 : const char *pszNull2 = poBand->GetMetadataItem("I_DONT_EXIST");
2976 1 : const char *psz4 = poBand->GetMetadataItem("BAR");
2977 1 : EXPECT_TRUE(psz1 != nullptr);
2978 1 : EXPECT_TRUE(psz2 != nullptr);
2979 1 : EXPECT_TRUE(psz3 != nullptr);
2980 1 : EXPECT_TRUE(psz4 != nullptr);
2981 1 : EXPECT_TRUE(pszNull == nullptr);
2982 1 : EXPECT_TRUE(pszNull2 == nullptr);
2983 1 : EXPECT_EQ(psz1, psz3);
2984 1 : EXPECT_TRUE(psz1 != psz2);
2985 1 : EXPECT_EQ(psz2, psz4);
2986 1 : EXPECT_STREQ(psz1, "BAR");
2987 1 : EXPECT_STREQ(psz2, "BAZ");
2988 : }
2989 :
2990 1 : poDS.reset();
2991 1 : VSIUnlink("/vsimem/tmp.pix");
2992 : }
2993 :
2994 : // Test GDALBufferHasOnlyNoData()
2995 4 : TEST_F(test_gdal, GDALBufferHasOnlyNoData)
2996 : {
2997 : /* bool CPL_DLL GDALBufferHasOnlyNoData(const void* pBuffer,
2998 : double dfNoDataValue,
2999 : size_t nWidth, size_t nHeight,
3000 : size_t nLineStride,
3001 : size_t nComponents,
3002 : int nBitsPerSample,
3003 : GDALBufferSampleFormat nSampleFormat);
3004 : */
3005 1 : EXPECT_TRUE(
3006 : GDALBufferHasOnlyNoData("\x00", 0.0, 1, 1, 1, 1, 8, GSF_UNSIGNED_INT));
3007 1 : EXPECT_TRUE(
3008 : !GDALBufferHasOnlyNoData("\x01", 0.0, 1, 1, 1, 1, 8, GSF_UNSIGNED_INT));
3009 1 : EXPECT_TRUE(
3010 : GDALBufferHasOnlyNoData("\x00", 0.0, 1, 1, 1, 1, 1, GSF_UNSIGNED_INT));
3011 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData("\x00\x00", 0.0, 1, 1, 1, 1, 16,
3012 : GSF_UNSIGNED_INT));
3013 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData("\x00\x01", 0.0, 1, 1, 1, 1, 16,
3014 : GSF_UNSIGNED_INT));
3015 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData("\x00\x01", 0.0, 1, 2, 2, 1, 8,
3016 : GSF_UNSIGNED_INT));
3017 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(
3018 : "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0.0, 14, 1,
3019 : 14, 1, 8, GSF_UNSIGNED_INT));
3020 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(
3021 : "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0.0, 14, 1,
3022 : 14, 1, 8, GSF_UNSIGNED_INT));
3023 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(
3024 : "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", 0.0, 14, 1,
3025 : 14, 1, 8, GSF_UNSIGNED_INT));
3026 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(
3027 : "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 0.0, 14, 1,
3028 : 14, 1, 8, GSF_UNSIGNED_INT));
3029 :
3030 1 : uint8_t uint8val = 1;
3031 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&uint8val, 1.0, 1, 1, 1, 1, 8,
3032 : GSF_UNSIGNED_INT));
3033 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&uint8val, 0.0, 1, 1, 1, 1, 8,
3034 : GSF_UNSIGNED_INT));
3035 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&uint8val, 128 + 1, 1, 1, 1, 1, 8,
3036 : GSF_UNSIGNED_INT));
3037 :
3038 1 : int8_t int8val = -1;
3039 1 : EXPECT_TRUE(
3040 : GDALBufferHasOnlyNoData(&int8val, -1.0, 1, 1, 1, 1, 8, GSF_SIGNED_INT));
3041 1 : EXPECT_TRUE(
3042 : !GDALBufferHasOnlyNoData(&int8val, 0.0, 1, 1, 1, 1, 8, GSF_SIGNED_INT));
3043 1 : EXPECT_TRUE(
3044 : !GDALBufferHasOnlyNoData(&int8val, 256, 1, 1, 1, 1, 8, GSF_SIGNED_INT));
3045 :
3046 1 : uint16_t uint16val = 1;
3047 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&uint16val, 1.0, 1, 1, 1, 1, 16,
3048 : GSF_UNSIGNED_INT));
3049 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&uint16val, 0.0, 1, 1, 1, 1, 16,
3050 : GSF_UNSIGNED_INT));
3051 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&uint16val, 65536 + 1, 1, 1, 1, 1, 16,
3052 : GSF_UNSIGNED_INT));
3053 :
3054 1 : int16_t int16val = -1;
3055 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&int16val, -1.0, 1, 1, 1, 1, 16,
3056 : GSF_SIGNED_INT));
3057 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&int16val, 0.0, 1, 1, 1, 1, 16,
3058 : GSF_SIGNED_INT));
3059 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&int16val, 32768, 1, 1, 1, 1, 16,
3060 : GSF_SIGNED_INT));
3061 :
3062 1 : uint32_t uint32val = 1;
3063 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&uint32val, 1.0, 1, 1, 1, 1, 32,
3064 : GSF_UNSIGNED_INT));
3065 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&uint32val, 0.0, 1, 1, 1, 1, 32,
3066 : GSF_UNSIGNED_INT));
3067 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&uint32val,
3068 : static_cast<double>(0x100000000LL + 1),
3069 : 1, 1, 1, 1, 32, GSF_UNSIGNED_INT));
3070 :
3071 1 : int32_t int32val = -1;
3072 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&int32val, -1.0, 1, 1, 1, 1, 32,
3073 : GSF_SIGNED_INT));
3074 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&int32val, 0.0, 1, 1, 1, 1, 32,
3075 : GSF_SIGNED_INT));
3076 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&int32val, 0x80000000, 1, 1, 1, 1, 32,
3077 : GSF_SIGNED_INT));
3078 :
3079 1 : float float32val = -1;
3080 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&float32val, -1.0, 1, 1, 1, 1, 32,
3081 : GSF_FLOATING_POINT));
3082 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&float32val, 0.0, 1, 1, 1, 1, 32,
3083 : GSF_FLOATING_POINT));
3084 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&float32val, 1e50, 1, 1, 1, 1, 32,
3085 : GSF_FLOATING_POINT));
3086 :
3087 1 : float float32nan = cpl::NumericLimits<float>::quiet_NaN();
3088 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&float32nan, float32nan, 1, 1, 1, 1, 32,
3089 : GSF_FLOATING_POINT));
3090 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&float32nan, 0.0, 1, 1, 1, 1, 32,
3091 : GSF_FLOATING_POINT));
3092 :
3093 1 : double float64val = -1;
3094 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&float64val, -1.0, 1, 1, 1, 1, 64,
3095 : GSF_FLOATING_POINT));
3096 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&float64val, 0.0, 1, 1, 1, 1, 64,
3097 : GSF_FLOATING_POINT));
3098 :
3099 1 : double float64nan = cpl::NumericLimits<double>::quiet_NaN();
3100 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&float64nan, float64nan, 1, 1, 1, 1, 64,
3101 : GSF_FLOATING_POINT));
3102 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&float64nan, 0.0, 1, 1, 1, 1, 64,
3103 : GSF_FLOATING_POINT));
3104 1 : }
3105 :
3106 : // Test GetRasterNoDataReplacementValue()
3107 4 : TEST_F(test_gdal, GetRasterNoDataReplacementValue)
3108 : {
3109 : // Test GDT_Byte
3110 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3111 : GDT_Byte, cpl::NumericLimits<double>::lowest()),
3112 : 0);
3113 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Byte,
3114 : cpl::NumericLimits<double>::max()),
3115 : 0);
3116 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3117 : GDT_Byte, cpl::NumericLimits<uint8_t>::lowest()),
3118 : cpl::NumericLimits<uint8_t>::lowest() + 1);
3119 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Byte,
3120 : cpl::NumericLimits<uint8_t>::max()),
3121 : cpl::NumericLimits<uint8_t>::max() - 1);
3122 :
3123 : // Test GDT_Int8
3124 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3125 : GDT_Int8, cpl::NumericLimits<double>::lowest()),
3126 : 0);
3127 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Int8,
3128 : cpl::NumericLimits<double>::max()),
3129 : 0);
3130 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3131 : GDT_Int8, cpl::NumericLimits<int8_t>::lowest()),
3132 : cpl::NumericLimits<int8_t>::lowest() + 1);
3133 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Int8,
3134 : cpl::NumericLimits<int8_t>::max()),
3135 : cpl::NumericLimits<int8_t>::max() - 1);
3136 :
3137 : // Test GDT_UInt16
3138 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3139 : GDT_UInt16, cpl::NumericLimits<double>::lowest()),
3140 : 0);
3141 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_UInt16,
3142 : cpl::NumericLimits<double>::max()),
3143 : 0);
3144 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3145 : GDT_UInt16, cpl::NumericLimits<uint16_t>::lowest()),
3146 : cpl::NumericLimits<uint16_t>::lowest() + 1);
3147 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3148 : GDT_UInt16, cpl::NumericLimits<uint16_t>::max()),
3149 : cpl::NumericLimits<uint16_t>::max() - 1);
3150 :
3151 : // Test GDT_Int16
3152 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3153 : GDT_Int16, cpl::NumericLimits<double>::lowest()),
3154 : 0);
3155 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Int16,
3156 : cpl::NumericLimits<double>::max()),
3157 : 0);
3158 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3159 : GDT_Int16, cpl::NumericLimits<int16_t>::lowest()),
3160 : cpl::NumericLimits<int16_t>::lowest() + 1);
3161 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Int16,
3162 : cpl::NumericLimits<int16_t>::max()),
3163 : cpl::NumericLimits<int16_t>::max() - 1);
3164 :
3165 : // Test GDT_UInt32
3166 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3167 : GDT_UInt32, cpl::NumericLimits<double>::lowest()),
3168 : 0);
3169 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_UInt32,
3170 : cpl::NumericLimits<double>::max()),
3171 : 0);
3172 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3173 : GDT_UInt32, cpl::NumericLimits<uint32_t>::lowest()),
3174 : cpl::NumericLimits<uint32_t>::lowest() + 1);
3175 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3176 : GDT_UInt32, cpl::NumericLimits<uint32_t>::max()),
3177 : cpl::NumericLimits<uint32_t>::max() - 1);
3178 :
3179 : // Test GDT_Int32
3180 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3181 : GDT_Int32, cpl::NumericLimits<double>::lowest()),
3182 : 0);
3183 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Int32,
3184 : cpl::NumericLimits<double>::max()),
3185 : 0);
3186 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3187 : GDT_Int32, cpl::NumericLimits<int32_t>::lowest()),
3188 : cpl::NumericLimits<int32_t>::lowest() + 1);
3189 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Int32,
3190 : cpl::NumericLimits<int32_t>::max()),
3191 : cpl::NumericLimits<int32_t>::max() - 1);
3192 :
3193 : // Test GDT_UInt64
3194 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3195 : GDT_UInt64, cpl::NumericLimits<double>::lowest()),
3196 : 0);
3197 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_UInt64,
3198 : cpl::NumericLimits<double>::max()),
3199 : 0);
3200 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3201 : GDT_UInt64,
3202 : static_cast<double>(cpl::NumericLimits<uint64_t>::lowest())),
3203 : static_cast<double>(cpl::NumericLimits<uint64_t>::lowest()) + 1);
3204 : // uin64_t max is not representable in double so we expect the next value to be returned
3205 : using std::nextafter;
3206 1 : EXPECT_EQ(
3207 : GDALGetNoDataReplacementValue(
3208 : GDT_UInt64,
3209 : static_cast<double>(cpl::NumericLimits<uint64_t>::max())),
3210 : nextafter(static_cast<double>(cpl::NumericLimits<uint64_t>::max()), 0) -
3211 : 1);
3212 :
3213 : // Test GDT_Int64
3214 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3215 : GDT_Int64, cpl::NumericLimits<double>::lowest()),
3216 : 0);
3217 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Int64,
3218 : cpl::NumericLimits<double>::max()),
3219 : 0);
3220 : // in64_t max is not representable in double so we expect the next value to be returned
3221 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3222 : GDT_Int64,
3223 : static_cast<double>(cpl::NumericLimits<int64_t>::lowest())),
3224 : static_cast<double>(cpl::NumericLimits<int64_t>::lowest()) + 1);
3225 1 : EXPECT_EQ(
3226 : GDALGetNoDataReplacementValue(
3227 : GDT_Int64, static_cast<double>(cpl::NumericLimits<int64_t>::max())),
3228 : nextafter(static_cast<double>(cpl::NumericLimits<int64_t>::max()), 0) -
3229 : 1);
3230 :
3231 : // Test floating point types
3232 :
3233 : // NOTE: Google Test's output for GFloat16 values is very wrong.
3234 : // It seems to round GFloat16 values to integers before outputting
3235 : // them. Do not trust the screen output when there is an error.
3236 : // However, the tests themselves are reliable.
3237 :
3238 : // out of range for float16
3239 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3240 : GDT_Float16, cpl::NumericLimits<double>::lowest()),
3241 : 0.0);
3242 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Float16,
3243 : cpl::NumericLimits<double>::max()),
3244 : 0.0);
3245 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3246 : GDT_Float16, cpl::NumericLimits<double>::infinity()),
3247 : 0.0);
3248 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3249 : GDT_Float16, -cpl::NumericLimits<double>::infinity()),
3250 : 0.0);
3251 :
3252 : // in range for float 16
3253 1 : EXPECT_EQ(
3254 : static_cast<GFloat16>(GDALGetNoDataReplacementValue(GDT_Float16, -1.0)),
3255 : nextafter(GFloat16(-1.0), GFloat16(0.0f)));
3256 1 : EXPECT_EQ(
3257 : static_cast<GFloat16>(GDALGetNoDataReplacementValue(GDT_Float16, 1.1)),
3258 : nextafter(GFloat16(1.1), GFloat16(2.0f)));
3259 1 : EXPECT_EQ(
3260 : GDALGetNoDataReplacementValue(GDT_Float16,
3261 : cpl::NumericLimits<GFloat16>::lowest()),
3262 : nextafter(cpl::NumericLimits<GFloat16>::lowest(), GFloat16(0.0f)));
3263 :
3264 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3265 : GDT_Float16, cpl::NumericLimits<GFloat16>::max()),
3266 : static_cast<double>(nextafter(cpl::NumericLimits<GFloat16>::max(),
3267 : GFloat16(0.0f))));
3268 :
3269 : // out of range for float32
3270 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3271 : GDT_Float32, cpl::NumericLimits<double>::lowest()),
3272 : 0.0);
3273 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Float32,
3274 : cpl::NumericLimits<double>::max()),
3275 : 0.0);
3276 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3277 : GDT_Float32, cpl::NumericLimits<double>::infinity()),
3278 : 0.0);
3279 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3280 : GDT_Float32, -cpl::NumericLimits<double>::infinity()),
3281 : 0.0);
3282 :
3283 : // in range for float 32
3284 1 : EXPECT_EQ(
3285 : static_cast<float>(GDALGetNoDataReplacementValue(GDT_Float32, -1.0)),
3286 : nextafter(float(-1.0), 0.0f));
3287 1 : EXPECT_EQ(
3288 : static_cast<float>(GDALGetNoDataReplacementValue(GDT_Float32, 1.1)),
3289 : nextafter(float(1.1), 2.0f));
3290 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3291 : GDT_Float32, cpl::NumericLimits<float>::lowest()),
3292 : nextafter(cpl::NumericLimits<float>::lowest(), 0.0f));
3293 :
3294 1 : EXPECT_EQ(
3295 : GDALGetNoDataReplacementValue(GDT_Float32,
3296 : cpl::NumericLimits<float>::max()),
3297 : static_cast<double>(nextafter(cpl::NumericLimits<float>::max(), 0.0f)));
3298 :
3299 : // in range for float64
3300 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3301 : GDT_Float64, cpl::NumericLimits<double>::lowest()),
3302 : nextafter(cpl::NumericLimits<double>::lowest(), 0.0));
3303 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Float64,
3304 : cpl::NumericLimits<double>::max()),
3305 : nextafter(cpl::NumericLimits<double>::max(), 0.0));
3306 :
3307 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3308 : GDT_Float64, cpl::NumericLimits<double>::lowest()),
3309 : nextafter(cpl::NumericLimits<double>::lowest(), 0.0));
3310 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Float64,
3311 : cpl::NumericLimits<double>::max()),
3312 : nextafter(cpl::NumericLimits<double>::max(), 0.0));
3313 :
3314 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Float64, double(-1.0)),
3315 : nextafter(double(-1.0), 0.0));
3316 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Float64, double(1.1)),
3317 : nextafter(double(1.1), 2.0));
3318 :
3319 : // test infinity
3320 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3321 : GDT_Float64, cpl::NumericLimits<double>::infinity()),
3322 : 0.0);
3323 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
3324 : GDT_Float64, -cpl::NumericLimits<double>::infinity()),
3325 : 0.0);
3326 1 : }
3327 :
3328 : // Test GDALRasterBand::GetIndexColorTranslationTo()
3329 4 : TEST_F(test_gdal, GetIndexColorTranslationTo)
3330 : {
3331 : GDALDatasetUniquePtr poSrcDS(
3332 2 : MEMDataset::Create("", 1, 1, 1, GDT_Byte, nullptr));
3333 : {
3334 2 : GDALColorTable oCT;
3335 : {
3336 : GDALColorEntry e;
3337 1 : e.c1 = 0;
3338 1 : e.c2 = 0;
3339 1 : e.c3 = 0;
3340 1 : e.c4 = 255;
3341 1 : oCT.SetColorEntry(0, &e);
3342 : }
3343 : {
3344 : GDALColorEntry e;
3345 1 : e.c1 = 1;
3346 1 : e.c2 = 0;
3347 1 : e.c3 = 0;
3348 1 : e.c4 = 255;
3349 1 : oCT.SetColorEntry(1, &e);
3350 : }
3351 : {
3352 : GDALColorEntry e;
3353 1 : e.c1 = 255;
3354 1 : e.c2 = 255;
3355 1 : e.c3 = 255;
3356 1 : e.c4 = 255;
3357 1 : oCT.SetColorEntry(2, &e);
3358 : }
3359 : {
3360 : GDALColorEntry e;
3361 1 : e.c1 = 125;
3362 1 : e.c2 = 126;
3363 1 : e.c3 = 127;
3364 1 : e.c4 = 0;
3365 1 : oCT.SetColorEntry(3, &e);
3366 1 : poSrcDS->GetRasterBand(1)->SetNoDataValue(3);
3367 : }
3368 1 : poSrcDS->GetRasterBand(1)->SetColorTable(&oCT);
3369 : }
3370 :
3371 : GDALDatasetUniquePtr poDstDS(
3372 2 : MEMDataset::Create("", 1, 1, 1, GDT_Byte, nullptr));
3373 : {
3374 2 : GDALColorTable oCT;
3375 : {
3376 : GDALColorEntry e;
3377 1 : e.c1 = 255;
3378 1 : e.c2 = 255;
3379 1 : e.c3 = 255;
3380 1 : e.c4 = 255;
3381 1 : oCT.SetColorEntry(0, &e);
3382 : }
3383 : {
3384 : GDALColorEntry e;
3385 1 : e.c1 = 0;
3386 1 : e.c2 = 0;
3387 1 : e.c3 = 1;
3388 1 : e.c4 = 255;
3389 1 : oCT.SetColorEntry(1, &e);
3390 : }
3391 : {
3392 : GDALColorEntry e;
3393 1 : e.c1 = 12;
3394 1 : e.c2 = 13;
3395 1 : e.c3 = 14;
3396 1 : e.c4 = 0;
3397 1 : oCT.SetColorEntry(2, &e);
3398 1 : poSrcDS->GetRasterBand(1)->SetNoDataValue(2);
3399 : }
3400 1 : poDstDS->GetRasterBand(1)->SetColorTable(&oCT);
3401 : }
3402 :
3403 : unsigned char *panTranslationTable =
3404 1 : poSrcDS->GetRasterBand(1)->GetIndexColorTranslationTo(
3405 : poDstDS->GetRasterBand(1));
3406 1 : EXPECT_EQ(static_cast<int>(panTranslationTable[0]), 1);
3407 1 : EXPECT_EQ(static_cast<int>(panTranslationTable[1]), 1);
3408 1 : EXPECT_EQ(static_cast<int>(panTranslationTable[2]), 0);
3409 1 : EXPECT_EQ(static_cast<int>(panTranslationTable[3]),
3410 : 2); // special nodata mapping
3411 1 : CPLFree(panTranslationTable);
3412 1 : }
3413 :
3414 : // Test effect of MarkSuppressOnClose() with the final FlushCache() at dataset
3415 : // destruction
3416 4 : TEST_F(test_gdal, MarkSuppressOnClose)
3417 : {
3418 1 : const char *pszFilename = "/vsimem/out.tif";
3419 1 : const char *const apszOptions[] = {"PROFILE=BASELINE", nullptr};
3420 1 : auto hDrv = GDALGetDriverByName("GTiff");
3421 1 : if (!hDrv)
3422 : {
3423 0 : GTEST_SKIP() << "GTiff driver missing";
3424 : }
3425 : else
3426 : {
3427 : GDALDatasetUniquePtr poDstDS(GDALDriver::FromHandle(hDrv)->Create(
3428 2 : pszFilename, 1, 1, 1, GDT_Byte, apszOptions));
3429 1 : poDstDS->SetMetadataItem("FOO", "BAR");
3430 1 : poDstDS->MarkSuppressOnClose();
3431 1 : poDstDS->GetRasterBand(1)->Fill(255);
3432 1 : poDstDS->FlushCache(true);
3433 : // All buffers have been flushed, but our dirty block should not have
3434 : // been written hence the checksum will be 0
3435 1 : EXPECT_EQ(GDALChecksumImage(
3436 : GDALRasterBand::FromHandle(poDstDS->GetRasterBand(1)), 0,
3437 : 0, 1, 1),
3438 : 0);
3439 : }
3440 : {
3441 : VSIStatBufL sStat;
3442 1 : EXPECT_TRUE(VSIStatL(CPLSPrintf("%s.aux.xml", pszFilename), &sStat) !=
3443 : 0);
3444 : }
3445 : }
3446 :
3447 : // Test effect of UnMarkSuppressOnClose()
3448 4 : TEST_F(test_gdal, UnMarkSuppressOnClose)
3449 : {
3450 1 : const char *pszFilename = "/vsimem/out.tif";
3451 1 : const char *const apszOptions[] = {"PROFILE=BASELINE", nullptr};
3452 1 : auto hDrv = GDALGetDriverByName("GTiff");
3453 1 : if (!hDrv)
3454 : {
3455 0 : GTEST_SKIP() << "GTiff driver missing";
3456 : }
3457 : else
3458 : {
3459 : GDALDatasetUniquePtr poDstDS(GDALDriver::FromHandle(hDrv)->Create(
3460 2 : pszFilename, 1, 1, 1, GDT_Byte, apszOptions));
3461 1 : poDstDS->MarkSuppressOnClose();
3462 1 : poDstDS->GetRasterBand(1)->Fill(255);
3463 1 : if (poDstDS->IsMarkedSuppressOnClose())
3464 1 : poDstDS->UnMarkSuppressOnClose();
3465 1 : poDstDS->FlushCache(true);
3466 : // All buffers have been flushed, and our dirty block should have
3467 : // been written hence the checksum will not be 0
3468 1 : EXPECT_NE(GDALChecksumImage(
3469 : GDALRasterBand::FromHandle(poDstDS->GetRasterBand(1)), 0,
3470 : 0, 1, 1),
3471 : 0);
3472 : VSIStatBufL sStat;
3473 1 : EXPECT_TRUE(VSIStatL(pszFilename, &sStat) == 0);
3474 1 : VSIUnlink(pszFilename);
3475 : }
3476 : }
3477 :
3478 11 : template <class T> void TestCachedPixelAccessor()
3479 : {
3480 11 : constexpr auto eType = GDALCachedPixelAccessorGetDataType<T>::DataType;
3481 11 : auto poDS = std::unique_ptr<GDALDataset>(
3482 11 : MEMDataset::Create("", 11, 23, 1, eType, nullptr));
3483 11 : auto poBand = poDS->GetRasterBand(1);
3484 22 : GDALCachedPixelAccessor<T, 4> accessor(poBand);
3485 264 : for (int iY = 0; iY < poBand->GetYSize(); iY++)
3486 : {
3487 3036 : for (int iX = 0; iX < poBand->GetXSize(); iX++)
3488 : {
3489 2783 : accessor.Set(iX, iY, static_cast<T>(iY * poBand->GetXSize() + iX));
3490 : }
3491 : }
3492 264 : for (int iY = 0; iY < poBand->GetYSize(); iY++)
3493 : {
3494 3036 : for (int iX = 0; iX < poBand->GetXSize(); iX++)
3495 : {
3496 2783 : EXPECT_EQ(accessor.Get(iX, iY),
3497 : static_cast<T>(iY * poBand->GetXSize() + iX));
3498 : }
3499 : }
3500 :
3501 22 : std::vector<T> values(static_cast<size_t>(poBand->GetYSize()) *
3502 11 : poBand->GetXSize());
3503 11 : accessor.FlushCache();
3504 11 : EXPECT_EQ(poBand->RasterIO(GF_Read, 0, 0, poBand->GetXSize(),
3505 : poBand->GetYSize(), values.data(),
3506 : poBand->GetXSize(), poBand->GetYSize(), eType, 0,
3507 : 0, nullptr),
3508 : CE_None);
3509 264 : for (int iY = 0; iY < poBand->GetYSize(); iY++)
3510 : {
3511 3036 : for (int iX = 0; iX < poBand->GetXSize(); iX++)
3512 : {
3513 2783 : EXPECT_EQ(values[iY * poBand->GetXSize() + iX],
3514 : static_cast<T>(iY * poBand->GetXSize() + iX));
3515 : }
3516 : }
3517 11 : }
3518 :
3519 : // Test GDALCachedPixelAccessor
3520 4 : TEST_F(test_gdal, GDALCachedPixelAccessor)
3521 : {
3522 1 : TestCachedPixelAccessor<GByte>();
3523 1 : TestCachedPixelAccessor<GUInt16>();
3524 1 : TestCachedPixelAccessor<GInt16>();
3525 1 : TestCachedPixelAccessor<GUInt32>();
3526 1 : TestCachedPixelAccessor<GInt32>();
3527 1 : TestCachedPixelAccessor<GUInt64>();
3528 1 : TestCachedPixelAccessor<GInt64>();
3529 1 : TestCachedPixelAccessor<uint64_t>();
3530 1 : TestCachedPixelAccessor<int64_t>();
3531 1 : TestCachedPixelAccessor<float>();
3532 1 : TestCachedPixelAccessor<double>();
3533 1 : }
3534 :
3535 : // Test VRT and caching of sources w.r.t open options
3536 : // (https://github.com/OSGeo/gdal/issues/5989)
3537 4 : TEST_F(test_gdal, VRTCachingOpenOptions)
3538 : {
3539 1 : if (GDALGetMetadataItem(GDALGetDriverByName("VRT"), GDAL_DMD_OPENOPTIONLIST,
3540 1 : nullptr) == nullptr)
3541 : {
3542 0 : GTEST_SKIP() << "VRT driver Open() missing";
3543 : }
3544 :
3545 : class TestRasterBand : public GDALRasterBand
3546 : {
3547 : protected:
3548 3 : CPLErr IReadBlock(int, int, void *pImage) override
3549 : {
3550 3 : static_cast<GByte *>(pImage)[0] = 0;
3551 3 : return CE_None;
3552 : }
3553 :
3554 : public:
3555 3 : TestRasterBand()
3556 3 : {
3557 3 : nBlockXSize = 1;
3558 3 : nBlockYSize = 1;
3559 3 : eDataType = GDT_Byte;
3560 3 : }
3561 : };
3562 :
3563 : static int nCountZeroOpenOptions = 0;
3564 : static int nCountWithOneOpenOptions = 0;
3565 :
3566 : class TestDataset : public GDALDataset
3567 : {
3568 : public:
3569 3 : TestDataset()
3570 3 : {
3571 3 : nRasterXSize = 1;
3572 3 : nRasterYSize = 1;
3573 3 : SetBand(1, new TestRasterBand());
3574 3 : }
3575 :
3576 3 : static GDALDataset *TestOpen(GDALOpenInfo *poOpenInfo)
3577 : {
3578 3 : if (strcmp(poOpenInfo->pszFilename, ":::DUMMY:::") != 0)
3579 0 : return nullptr;
3580 3 : if (poOpenInfo->papszOpenOptions == nullptr)
3581 1 : nCountZeroOpenOptions++;
3582 : else
3583 2 : nCountWithOneOpenOptions++;
3584 3 : return new TestDataset();
3585 : }
3586 : };
3587 :
3588 2 : std::unique_ptr<GDALDriver> driver(new GDALDriver());
3589 1 : driver->SetDescription("TEST_VRT_SOURCE_OPEN_OPTION");
3590 1 : driver->pfnOpen = TestDataset::TestOpen;
3591 1 : GetGDALDriverManager()->RegisterDriver(driver.get());
3592 :
3593 1 : const char *pszVRT = R"(
3594 : <VRTDataset rasterXSize="1" rasterYSize="1">
3595 : <VRTRasterBand dataType="Byte" band="1" subClass="VRTSourcedRasterBand">
3596 : <SimpleSource>
3597 : <SourceFilename relativeToVRT="0">:::DUMMY:::</SourceFilename>
3598 : </SimpleSource>
3599 : <SimpleSource>
3600 : <SourceFilename relativeToVRT="0">:::DUMMY:::</SourceFilename>
3601 : </SimpleSource>
3602 : <SimpleSource>
3603 : <SourceFilename relativeToVRT="0">:::DUMMY:::</SourceFilename>
3604 : <OpenOptions>
3605 : <OOI key="TESTARG">present</OOI>
3606 : </OpenOptions>
3607 : </SimpleSource>
3608 : <SimpleSource>
3609 : <SourceFilename relativeToVRT="0">:::DUMMY:::</SourceFilename>
3610 : <OpenOptions>
3611 : <OOI key="TESTARG">present</OOI>
3612 : </OpenOptions>
3613 : </SimpleSource>
3614 : <SimpleSource>
3615 : <SourceFilename relativeToVRT="0">:::DUMMY:::</SourceFilename>
3616 : <OpenOptions>
3617 : <OOI key="TESTARG">another_one</OOI>
3618 : </OpenOptions>
3619 : </SimpleSource>
3620 : </VRTRasterBand>
3621 : </VRTDataset>)";
3622 2 : auto ds = std::unique_ptr<GDALDataset>(GDALDataset::Open(pszVRT));
3623 :
3624 : // Trigger reading data, which triggers opening of source datasets
3625 1 : auto rb = ds->GetRasterBand(1);
3626 : double minmax[2];
3627 1 : GDALComputeRasterMinMax(GDALRasterBand::ToHandle(rb), TRUE, minmax);
3628 :
3629 1 : ds.reset();
3630 1 : GetGDALDriverManager()->DeregisterDriver(driver.get());
3631 :
3632 1 : EXPECT_EQ(nCountZeroOpenOptions, 1);
3633 1 : EXPECT_EQ(nCountWithOneOpenOptions, 2);
3634 : }
3635 :
3636 : // Test GDALDeinterleave 3 components Byte()
3637 4 : TEST_F(test_gdal, GDALDeinterleave3ComponentsByte)
3638 : {
3639 1 : GByte *pabySrc = static_cast<GByte *>(CPLMalloc(3 * 4 * 15));
3640 181 : for (int i = 0; i < 3 * 4 * 15; i++)
3641 180 : pabySrc[i] = static_cast<GByte>(i);
3642 1 : GByte *pabyDest0 = static_cast<GByte *>(CPLMalloc(4 * 15));
3643 1 : GByte *pabyDest1 = static_cast<GByte *>(CPLMalloc(4 * 15));
3644 1 : GByte *pabyDest2 = static_cast<GByte *>(CPLMalloc(4 * 15));
3645 1 : void *ppabyDest[] = {pabyDest0, pabyDest1, pabyDest2};
3646 3 : for (int nIters : {1, 4 * 15})
3647 : {
3648 2 : GDALDeinterleave(pabySrc, GDT_Byte, 3, ppabyDest, GDT_Byte, nIters);
3649 63 : for (int i = 0; i < nIters; i++)
3650 : {
3651 61 : EXPECT_EQ(pabyDest0[i], 3 * i);
3652 61 : EXPECT_EQ(pabyDest1[i], 3 * i + 1);
3653 61 : EXPECT_EQ(pabyDest2[i], 3 * i + 2);
3654 : }
3655 : }
3656 1 : VSIFree(pabySrc);
3657 1 : VSIFree(pabyDest0);
3658 1 : VSIFree(pabyDest1);
3659 1 : VSIFree(pabyDest2);
3660 1 : }
3661 :
3662 : // Test GDALDeinterleave 3 components Byte() without SSSE3
3663 4 : TEST_F(test_gdal, GDALDeinterleave3ComponentsByte_NOSSE3)
3664 : {
3665 1 : GByte *pabySrc = static_cast<GByte *>(CPLMalloc(3 * 4 * 15));
3666 181 : for (int i = 0; i < 3 * 4 * 15; i++)
3667 180 : pabySrc[i] = static_cast<GByte>(i);
3668 1 : GByte *pabyDest0 = static_cast<GByte *>(CPLMalloc(4 * 15));
3669 1 : GByte *pabyDest1 = static_cast<GByte *>(CPLMalloc(4 * 15));
3670 1 : GByte *pabyDest2 = static_cast<GByte *>(CPLMalloc(4 * 15));
3671 1 : void *ppabyDest[] = {pabyDest0, pabyDest1, pabyDest2};
3672 3 : for (int nIters : {1, 4 * 15})
3673 : {
3674 2 : CPLSetConfigOption("GDAL_USE_SSSE3", "NO");
3675 2 : GDALDeinterleave(pabySrc, GDT_Byte, 3, ppabyDest, GDT_Byte, nIters);
3676 2 : CPLSetConfigOption("GDAL_USE_SSSE3", nullptr);
3677 63 : for (int i = 0; i < nIters; i++)
3678 : {
3679 61 : EXPECT_EQ(pabyDest0[i], 3 * i);
3680 61 : EXPECT_EQ(pabyDest1[i], 3 * i + 1);
3681 61 : EXPECT_EQ(pabyDest2[i], 3 * i + 2);
3682 : }
3683 : }
3684 1 : VSIFree(pabySrc);
3685 1 : VSIFree(pabyDest0);
3686 1 : VSIFree(pabyDest1);
3687 1 : VSIFree(pabyDest2);
3688 1 : }
3689 :
3690 : // Test GDALDeinterleave 4 components Byte()
3691 4 : TEST_F(test_gdal, GDALDeinterleave4ComponentsByte)
3692 : {
3693 1 : GByte *pabySrc = static_cast<GByte *>(CPLMalloc(3 * 4 * 15));
3694 181 : for (int i = 0; i < 3 * 4 * 15; i++)
3695 180 : pabySrc[i] = static_cast<GByte>(i);
3696 1 : GByte *pabyDest0 = static_cast<GByte *>(CPLMalloc(3 * 15));
3697 1 : GByte *pabyDest1 = static_cast<GByte *>(CPLMalloc(3 * 15));
3698 1 : GByte *pabyDest2 = static_cast<GByte *>(CPLMalloc(3 * 15));
3699 1 : GByte *pabyDest3 = static_cast<GByte *>(CPLMalloc(3 * 15));
3700 1 : void *ppabyDest[] = {pabyDest0, pabyDest1, pabyDest2, pabyDest3};
3701 3 : for (int nIters : {1, 3 * 15})
3702 : {
3703 2 : GDALDeinterleave(pabySrc, GDT_Byte, 4, ppabyDest, GDT_Byte, nIters);
3704 48 : for (int i = 0; i < nIters; i++)
3705 : {
3706 46 : EXPECT_EQ(pabyDest0[i], 4 * i);
3707 46 : EXPECT_EQ(pabyDest1[i], 4 * i + 1);
3708 46 : EXPECT_EQ(pabyDest2[i], 4 * i + 2);
3709 46 : EXPECT_EQ(pabyDest3[i], 4 * i + 3);
3710 : }
3711 : }
3712 1 : VSIFree(pabySrc);
3713 1 : VSIFree(pabyDest0);
3714 1 : VSIFree(pabyDest1);
3715 1 : VSIFree(pabyDest2);
3716 1 : VSIFree(pabyDest3);
3717 1 : }
3718 :
3719 : // Test GDALDeinterleave 4 components Byte without SSSE3
3720 4 : TEST_F(test_gdal, GDALDeinterleave4ComponentsByte_NOSSE3)
3721 : {
3722 1 : GByte *pabySrc = static_cast<GByte *>(CPLMalloc(3 * 4 * 15));
3723 181 : for (int i = 0; i < 3 * 4 * 15; i++)
3724 180 : pabySrc[i] = static_cast<GByte>(i);
3725 1 : GByte *pabyDest0 = static_cast<GByte *>(CPLMalloc(3 * 15));
3726 1 : GByte *pabyDest1 = static_cast<GByte *>(CPLMalloc(3 * 15));
3727 1 : GByte *pabyDest2 = static_cast<GByte *>(CPLMalloc(3 * 15));
3728 1 : GByte *pabyDest3 = static_cast<GByte *>(CPLMalloc(3 * 15));
3729 1 : void *ppabyDest[] = {pabyDest0, pabyDest1, pabyDest2, pabyDest3};
3730 3 : for (int nIters : {1, 3 * 15})
3731 : {
3732 2 : CPLSetConfigOption("GDAL_USE_SSSE3", "NO");
3733 2 : GDALDeinterleave(pabySrc, GDT_Byte, 4, ppabyDest, GDT_Byte, nIters);
3734 2 : CPLSetConfigOption("GDAL_USE_SSSE3", nullptr);
3735 48 : for (int i = 0; i < nIters; i++)
3736 : {
3737 46 : EXPECT_EQ(pabyDest0[i], 4 * i);
3738 46 : EXPECT_EQ(pabyDest1[i], 4 * i + 1);
3739 46 : EXPECT_EQ(pabyDest2[i], 4 * i + 2);
3740 46 : EXPECT_EQ(pabyDest3[i], 4 * i + 3);
3741 : }
3742 : }
3743 1 : VSIFree(pabySrc);
3744 1 : VSIFree(pabyDest0);
3745 1 : VSIFree(pabyDest1);
3746 1 : VSIFree(pabyDest2);
3747 1 : VSIFree(pabyDest3);
3748 1 : }
3749 :
3750 : // Test GDALDeinterleave general case
3751 4 : TEST_F(test_gdal, GDALDeinterleaveGeneralCase)
3752 : {
3753 1 : GByte *pabySrc = static_cast<GByte *>(CPLMalloc(3 * 2));
3754 7 : for (int i = 0; i < 3 * 2; i++)
3755 6 : pabySrc[i] = static_cast<GByte>(i);
3756 1 : GUInt16 *panDest0 = static_cast<GUInt16 *>(CPLMalloc(3 * sizeof(uint16_t)));
3757 1 : GUInt16 *panDest1 = static_cast<GUInt16 *>(CPLMalloc(3 * sizeof(uint16_t)));
3758 1 : void *ppanDest[] = {panDest0, panDest1};
3759 1 : GDALDeinterleave(pabySrc, GDT_Byte, 2, ppanDest, GDT_UInt16, 3);
3760 4 : for (int i = 0; i < 3; i++)
3761 : {
3762 3 : EXPECT_EQ(panDest0[i], 2 * i);
3763 3 : EXPECT_EQ(panDest1[i], 2 * i + 1);
3764 : }
3765 1 : VSIFree(pabySrc);
3766 1 : VSIFree(panDest0);
3767 1 : VSIFree(panDest1);
3768 1 : }
3769 :
3770 : // Test GDALDeinterleave 3 components UInt16()
3771 4 : TEST_F(test_gdal, GDALDeinterleave3ComponentsUInt16)
3772 : {
3773 : GUInt16 *panSrc =
3774 1 : static_cast<GUInt16 *>(CPLMalloc(3 * 4 * 15 * sizeof(GUInt16)));
3775 181 : for (int i = 0; i < 3 * 4 * 15; i++)
3776 180 : panSrc[i] = static_cast<GUInt16>(i + 32767);
3777 : GUInt16 *panDest0 =
3778 1 : static_cast<GUInt16 *>(CPLMalloc(4 * 15 * sizeof(GUInt16)));
3779 : GUInt16 *panDest1 =
3780 1 : static_cast<GUInt16 *>(CPLMalloc(4 * 15 * sizeof(GUInt16)));
3781 : GUInt16 *panDest2 =
3782 1 : static_cast<GUInt16 *>(CPLMalloc(4 * 15 * sizeof(GUInt16)));
3783 1 : void *ppanDest[] = {panDest0, panDest1, panDest2};
3784 3 : for (int nIters : {1, 4 * 15})
3785 : {
3786 2 : GDALDeinterleave(panSrc, GDT_UInt16, 3, ppanDest, GDT_UInt16, nIters);
3787 63 : for (int i = 0; i < nIters; i++)
3788 : {
3789 61 : EXPECT_EQ(panDest0[i], 3 * i + 32767);
3790 61 : EXPECT_EQ(panDest1[i], 3 * i + 1 + 32767);
3791 61 : EXPECT_EQ(panDest2[i], 3 * i + 2 + 32767);
3792 : }
3793 : }
3794 1 : VSIFree(panSrc);
3795 1 : VSIFree(panDest0);
3796 1 : VSIFree(panDest1);
3797 1 : VSIFree(panDest2);
3798 1 : }
3799 :
3800 : // Test GDALDeinterleave 4 components UInt16()
3801 4 : TEST_F(test_gdal, GDALDeinterleave4ComponentsUInt16)
3802 : {
3803 : GUInt16 *panSrc =
3804 1 : static_cast<GUInt16 *>(CPLMalloc(3 * 4 * 15 * sizeof(GUInt16)));
3805 181 : for (int i = 0; i < 3 * 4 * 15; i++)
3806 180 : panSrc[i] = static_cast<GUInt16>(i + 32767);
3807 : GUInt16 *panDest0 =
3808 1 : static_cast<GUInt16 *>(CPLMalloc(4 * 15 * sizeof(GUInt16)));
3809 : GUInt16 *panDest1 =
3810 1 : static_cast<GUInt16 *>(CPLMalloc(4 * 15 * sizeof(GUInt16)));
3811 : GUInt16 *panDest2 =
3812 1 : static_cast<GUInt16 *>(CPLMalloc(4 * 15 * sizeof(GUInt16)));
3813 : GUInt16 *panDest3 =
3814 1 : static_cast<GUInt16 *>(CPLMalloc(4 * 15 * sizeof(GUInt16)));
3815 1 : void *ppanDest[] = {panDest0, panDest1, panDest2, panDest3};
3816 3 : for (int nIters : {1, 3 * 15})
3817 : {
3818 2 : GDALDeinterleave(panSrc, GDT_UInt16, 4, ppanDest, GDT_UInt16, nIters);
3819 48 : for (int i = 0; i < nIters; i++)
3820 : {
3821 46 : EXPECT_EQ(panDest0[i], 4 * i + 32767);
3822 46 : EXPECT_EQ(panDest1[i], 4 * i + 1 + 32767);
3823 46 : EXPECT_EQ(panDest2[i], 4 * i + 2 + 32767);
3824 46 : EXPECT_EQ(panDest3[i], 4 * i + 3 + 32767);
3825 : }
3826 : }
3827 1 : VSIFree(panSrc);
3828 1 : VSIFree(panDest0);
3829 1 : VSIFree(panDest1);
3830 1 : VSIFree(panDest2);
3831 1 : VSIFree(panDest3);
3832 1 : }
3833 :
3834 : // Test GDALDataset::ReportError()
3835 4 : TEST_F(test_gdal, GDALDatasetReportError)
3836 : {
3837 : GDALDatasetUniquePtr poSrcDS(
3838 2 : MEMDataset::Create("", 1, 1, 1, GDT_Byte, nullptr));
3839 :
3840 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
3841 1 : poSrcDS->ReportError("foo", CE_Warning, CPLE_AppDefined, "bar");
3842 1 : CPLPopErrorHandler();
3843 1 : EXPECT_STREQ(CPLGetLastErrorMsg(), "foo: bar");
3844 :
3845 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
3846 1 : poSrcDS->ReportError("%foo", CE_Warning, CPLE_AppDefined, "bar");
3847 1 : CPLPopErrorHandler();
3848 1 : EXPECT_STREQ(CPLGetLastErrorMsg(), "%foo: bar");
3849 :
3850 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
3851 1 : poSrcDS->ReportError(
3852 : "this_is_"
3853 : "wayyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3854 : "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3855 : "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3856 : "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3857 : "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3858 : "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3859 : "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3860 : "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3861 : "yyyyyyy_too_long/foo",
3862 1 : CE_Warning, CPLE_AppDefined, "bar");
3863 1 : CPLPopErrorHandler();
3864 1 : EXPECT_STREQ(CPLGetLastErrorMsg(), "foo: bar");
3865 1 : }
3866 :
3867 : // Test GDALDataset::GetCompressionFormats() and ReadCompressedData()
3868 4 : TEST_F(test_gdal, gtiff_ReadCompressedData)
3869 : {
3870 1 : if (!GDALGetDriverByName("GTiff"))
3871 : {
3872 0 : GTEST_SKIP() << "GTiff driver missing";
3873 : }
3874 1 : if (GDALGetDriverByName("JPEG") == nullptr)
3875 : {
3876 0 : GTEST_SKIP() << "JPEG support missing";
3877 : }
3878 :
3879 : GDALDatasetUniquePtr poSrcDS(GDALDataset::FromHandle(
3880 1 : GDALDataset::Open((tut::common::data_basedir +
3881 : "/../../gcore/data/byte_jpg_unusual_jpegtable.tif")
3882 1 : .c_str())));
3883 1 : ASSERT_TRUE(poSrcDS);
3884 :
3885 : const CPLStringList aosRet(GDALDatasetGetCompressionFormats(
3886 1 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0, 20, 20, 1, nullptr));
3887 1 : EXPECT_EQ(aosRet.size(), 1);
3888 1 : if (aosRet.size() == 1)
3889 : {
3890 1 : EXPECT_STREQ(aosRet[0], "JPEG");
3891 : }
3892 :
3893 : {
3894 1 : int nBand = 1;
3895 1 : EXPECT_EQ(CPLStringList(GDALDatasetGetCompressionFormats(
3896 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0,
3897 : 20, 20, 1, &nBand))
3898 : .size(),
3899 : 1);
3900 : }
3901 :
3902 : // nBandCout > nBands
3903 1 : EXPECT_EQ(CPLStringList(GDALDatasetGetCompressionFormats(
3904 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0, 20,
3905 : 20, 2, nullptr))
3906 : .size(),
3907 : 0);
3908 :
3909 : // Cannot subset just one pixel
3910 1 : EXPECT_EQ(CPLStringList(GDALDatasetGetCompressionFormats(
3911 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0, 1,
3912 : 1, 1, nullptr))
3913 : .size(),
3914 : 0);
3915 :
3916 : // Wrong band number
3917 : {
3918 1 : int nBand = 2;
3919 1 : EXPECT_EQ(CPLStringList(GDALDatasetGetCompressionFormats(
3920 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0,
3921 : 20, 20, 1, &nBand))
3922 : .size(),
3923 : 0);
3924 : }
3925 :
3926 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3927 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 20, 20, 1,
3928 : nullptr, nullptr, nullptr, nullptr),
3929 : CE_None);
3930 :
3931 : size_t nNeededSize;
3932 : {
3933 1 : char *pszDetailedFormat = nullptr;
3934 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3935 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 20,
3936 : 20, 1, nullptr, nullptr, &nNeededSize,
3937 : &pszDetailedFormat),
3938 : CE_None);
3939 1 : EXPECT_EQ(nNeededSize, 476);
3940 1 : EXPECT_TRUE(pszDetailedFormat != nullptr);
3941 1 : if (pszDetailedFormat)
3942 : {
3943 1 : ASSERT_STREQ(pszDetailedFormat, "JPEG");
3944 1 : VSIFree(pszDetailedFormat);
3945 : }
3946 : }
3947 :
3948 : {
3949 1 : const GByte abyCanary[] = {0xDE, 0xAD, 0xBE, 0xEF};
3950 1 : std::vector<GByte> abyBuffer(nNeededSize + sizeof(abyCanary));
3951 1 : memcpy(&abyBuffer[nNeededSize], abyCanary, sizeof(abyCanary));
3952 1 : void *pabyBuffer = abyBuffer.data();
3953 1 : void **ppabyBuffer = &pabyBuffer;
3954 1 : size_t nProvidedSize = nNeededSize;
3955 1 : char *pszDetailedFormat = nullptr;
3956 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3957 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 20,
3958 : 20, 1, nullptr, ppabyBuffer, &nProvidedSize,
3959 : &pszDetailedFormat),
3960 : CE_None);
3961 1 : ASSERT_EQ(nProvidedSize, nNeededSize);
3962 1 : ASSERT_TRUE(*ppabyBuffer == pabyBuffer);
3963 1 : EXPECT_TRUE(pszDetailedFormat != nullptr);
3964 1 : if (pszDetailedFormat)
3965 : {
3966 1 : ASSERT_STREQ(pszDetailedFormat,
3967 : "JPEG;frame_type=SOF0_baseline;bit_depth=8;num_"
3968 : "components=1;colorspace=unknown");
3969 1 : VSIFree(pszDetailedFormat);
3970 : }
3971 1 : EXPECT_TRUE(
3972 : memcmp(&abyBuffer[nNeededSize], abyCanary, sizeof(abyCanary)) == 0);
3973 1 : EXPECT_EQ(abyBuffer[0], 0xFF);
3974 1 : EXPECT_EQ(abyBuffer[1], 0xD8);
3975 1 : EXPECT_EQ(abyBuffer[nNeededSize - 2], 0xFF);
3976 1 : EXPECT_EQ(abyBuffer[nNeededSize - 1], 0xD9);
3977 :
3978 : // Buffer larger than needed: OK
3979 1 : nProvidedSize = nNeededSize + 1;
3980 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3981 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 20,
3982 : 20, 1, nullptr, ppabyBuffer, &nProvidedSize, nullptr),
3983 : CE_None);
3984 :
3985 : // Too small buffer
3986 1 : nProvidedSize = nNeededSize - 1;
3987 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3988 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 20,
3989 : 20, 1, nullptr, ppabyBuffer, &nProvidedSize, nullptr),
3990 : CE_Failure);
3991 :
3992 : // Missing pointer to size
3993 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3994 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 20,
3995 : 20, 1, nullptr, ppabyBuffer, nullptr, nullptr),
3996 : CE_Failure);
3997 : }
3998 :
3999 : // Let GDAL allocate buffer
4000 : {
4001 1 : void *pBuffer = nullptr;
4002 1 : size_t nGotSize = 0;
4003 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4004 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 20,
4005 : 20, 1, nullptr, &pBuffer, &nGotSize, nullptr),
4006 : CE_None);
4007 1 : EXPECT_EQ(nGotSize, nNeededSize);
4008 1 : EXPECT_NE(pBuffer, nullptr);
4009 1 : if (pBuffer != nullptr && nGotSize == nNeededSize && nNeededSize >= 2)
4010 : {
4011 1 : const GByte *pabyBuffer = static_cast<GByte *>(pBuffer);
4012 1 : EXPECT_EQ(pabyBuffer[0], 0xFF);
4013 1 : EXPECT_EQ(pabyBuffer[1], 0xD8);
4014 1 : EXPECT_EQ(pabyBuffer[nNeededSize - 2], 0xFF);
4015 1 : EXPECT_EQ(pabyBuffer[nNeededSize - 1], 0xD9);
4016 : }
4017 1 : VSIFree(pBuffer);
4018 : }
4019 :
4020 : // Cannot subset just one pixel
4021 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4022 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 1, 1, 1,
4023 : nullptr, nullptr, nullptr, nullptr),
4024 : CE_Failure);
4025 :
4026 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4027 : GDALDataset::ToHandle(poSrcDS.get()), "wrong_format", 0, 0,
4028 : 20, 20, 1, nullptr, nullptr, nullptr, nullptr),
4029 : CE_Failure);
4030 : }
4031 :
4032 : // Test GDALDataset::GetCompressionFormats() and ReadCompressedData()
4033 4 : TEST_F(test_gdal, gtiff_ReadCompressedData_jpeg_rgba)
4034 : {
4035 1 : if (!GDALGetDriverByName("GTiff"))
4036 : {
4037 0 : GTEST_SKIP() << "GTiff driver missing";
4038 : }
4039 1 : if (GDALGetDriverByName("JPEG") == nullptr)
4040 : {
4041 0 : GTEST_SKIP() << "JPEG support missing";
4042 : }
4043 :
4044 : GDALDatasetUniquePtr poSrcDS(GDALDataset::FromHandle(
4045 1 : GDALDataset::Open((tut::common::data_basedir +
4046 : "/../../gcore/data/stefan_full_rgba_jpeg_contig.tif")
4047 1 : .c_str())));
4048 1 : ASSERT_TRUE(poSrcDS);
4049 :
4050 : const CPLStringList aosRet(GDALDatasetGetCompressionFormats(
4051 1 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0, 162, 16, 4, nullptr));
4052 1 : EXPECT_EQ(aosRet.size(), 1);
4053 1 : if (aosRet.size() == 1)
4054 : {
4055 1 : EXPECT_STREQ(aosRet[0], "JPEG;colorspace=RGBA");
4056 : }
4057 :
4058 : // Let GDAL allocate buffer
4059 : {
4060 1 : void *pBuffer = nullptr;
4061 1 : size_t nGotSize = 0;
4062 1 : char *pszDetailedFormat = nullptr;
4063 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4064 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 162,
4065 : 16, 4, nullptr, &pBuffer, &nGotSize, &pszDetailedFormat),
4066 : CE_None);
4067 1 : if (pszDetailedFormat)
4068 : {
4069 1 : ASSERT_STREQ(pszDetailedFormat,
4070 : "JPEG;frame_type=SOF0_baseline;bit_depth=8;num_"
4071 : "components=4;colorspace=RGBA");
4072 1 : VSIFree(pszDetailedFormat);
4073 : }
4074 1 : VSIFree(pBuffer);
4075 : }
4076 : }
4077 :
4078 : // Test GDALDataset::GetCompressionFormats() and ReadCompressedData()
4079 4 : TEST_F(test_gdal, jpeg_ReadCompressedData)
4080 : {
4081 1 : if (GDALGetDriverByName("JPEG") == nullptr)
4082 : {
4083 0 : GTEST_SKIP() << "JPEG support missing";
4084 : }
4085 :
4086 1 : GDALDatasetUniquePtr poSrcDS(GDALDataset::FromHandle(GDALDataset::Open(
4087 1 : (tut::common::data_basedir + "/../../gdrivers/data/jpeg/albania.jpg")
4088 1 : .c_str())));
4089 1 : ASSERT_TRUE(poSrcDS);
4090 :
4091 : const CPLStringList aosRet(GDALDatasetGetCompressionFormats(
4092 1 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0, 361, 260, 3, nullptr));
4093 1 : EXPECT_EQ(aosRet.size(), 1);
4094 1 : if (aosRet.size() == 1)
4095 : {
4096 1 : EXPECT_STREQ(aosRet[0],
4097 : "JPEG;frame_type=SOF0_baseline;bit_depth=8;num_components="
4098 : "3;subsampling=4:2:0;colorspace=YCbCr");
4099 : }
4100 :
4101 : size_t nUpperBoundSize;
4102 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4103 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 361, 260,
4104 : 3, nullptr, nullptr, &nUpperBoundSize, nullptr),
4105 : CE_None);
4106 1 : EXPECT_EQ(nUpperBoundSize, 12574);
4107 :
4108 : {
4109 1 : std::vector<GByte> abyBuffer(nUpperBoundSize);
4110 1 : void *pabyBuffer = abyBuffer.data();
4111 1 : void **ppabyBuffer = &pabyBuffer;
4112 1 : size_t nSize = nUpperBoundSize;
4113 1 : char *pszDetailedFormat = nullptr;
4114 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4115 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 361,
4116 : 260, 3, nullptr, ppabyBuffer, &nSize, &pszDetailedFormat),
4117 : CE_None);
4118 1 : ASSERT_LT(nSize, nUpperBoundSize);
4119 1 : ASSERT_TRUE(*ppabyBuffer == pabyBuffer);
4120 1 : EXPECT_TRUE(pszDetailedFormat != nullptr);
4121 1 : if (pszDetailedFormat)
4122 : {
4123 1 : ASSERT_STREQ(pszDetailedFormat,
4124 : "JPEG;frame_type=SOF0_baseline;bit_depth=8;num_"
4125 : "components=3;subsampling=4:2:0;colorspace=YCbCr");
4126 1 : VSIFree(pszDetailedFormat);
4127 : }
4128 1 : EXPECT_EQ(abyBuffer[0], 0xFF);
4129 1 : EXPECT_EQ(abyBuffer[1], 0xD8);
4130 1 : EXPECT_EQ(abyBuffer[nSize - 2], 0xFF);
4131 1 : EXPECT_EQ(abyBuffer[nSize - 1], 0xD9);
4132 :
4133 : // Buffer larger than needed: OK
4134 1 : nSize = nUpperBoundSize + 1;
4135 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4136 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 361,
4137 : 260, 3, nullptr, ppabyBuffer, &nSize, nullptr),
4138 : CE_None);
4139 :
4140 : // Too small buffer
4141 1 : nSize = nUpperBoundSize - 1;
4142 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4143 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 361,
4144 : 260, 3, nullptr, ppabyBuffer, &nSize, nullptr),
4145 : CE_Failure);
4146 :
4147 : // Missing pointer to size
4148 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4149 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 361,
4150 : 260, 3, nullptr, ppabyBuffer, nullptr, nullptr),
4151 : CE_Failure);
4152 : }
4153 :
4154 : // Let GDAL allocate buffer
4155 : {
4156 1 : void *pBuffer = nullptr;
4157 1 : size_t nSize = nUpperBoundSize;
4158 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4159 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 361,
4160 : 260, 3, nullptr, &pBuffer, &nSize, nullptr),
4161 : CE_None);
4162 1 : EXPECT_GT(nSize, 4);
4163 1 : EXPECT_LT(nSize, nUpperBoundSize);
4164 1 : EXPECT_NE(pBuffer, nullptr);
4165 1 : if (pBuffer != nullptr && nSize >= 4 && nSize <= nUpperBoundSize)
4166 : {
4167 1 : const GByte *pabyBuffer = static_cast<GByte *>(pBuffer);
4168 1 : EXPECT_EQ(pabyBuffer[0], 0xFF);
4169 1 : EXPECT_EQ(pabyBuffer[1], 0xD8);
4170 1 : EXPECT_EQ(pabyBuffer[nSize - 2], 0xFF);
4171 1 : EXPECT_EQ(pabyBuffer[nSize - 1], 0xD9);
4172 : }
4173 1 : VSIFree(pBuffer);
4174 : }
4175 : }
4176 :
4177 : // Test GDALDataset::GetCompressionFormats() and ReadCompressedData()
4178 4 : TEST_F(test_gdal, jpegxl_ReadCompressedData)
4179 : {
4180 1 : if (GDALGetDriverByName("JPEGXL") == nullptr)
4181 : {
4182 0 : GTEST_SKIP() << "JPEGXL support missing";
4183 : }
4184 :
4185 1 : GDALDatasetUniquePtr poSrcDS(GDALDataset::FromHandle(GDALDataset::Open(
4186 1 : (tut::common::data_basedir + "/../../gdrivers/data/jpegxl/byte.jxl")
4187 1 : .c_str())));
4188 1 : ASSERT_TRUE(poSrcDS);
4189 :
4190 : const CPLStringList aosRet(GDALDatasetGetCompressionFormats(
4191 1 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0, 20, 20, 1, nullptr));
4192 1 : EXPECT_EQ(aosRet.size(), 1);
4193 1 : if (aosRet.size() == 1)
4194 : {
4195 1 : EXPECT_STREQ(aosRet[0], "JXL");
4196 : }
4197 :
4198 : size_t nUpperBoundSize;
4199 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4200 : GDALDataset::ToHandle(poSrcDS.get()), "JXL", 0, 0, 20, 20, 1,
4201 : nullptr, nullptr, &nUpperBoundSize, nullptr),
4202 : CE_None);
4203 1 : EXPECT_EQ(nUpperBoundSize, 719);
4204 :
4205 : {
4206 1 : std::vector<GByte> abyBuffer(nUpperBoundSize);
4207 1 : void *pabyBuffer = abyBuffer.data();
4208 1 : void **ppabyBuffer = &pabyBuffer;
4209 1 : size_t nSize = nUpperBoundSize;
4210 1 : char *pszDetailedFormat = nullptr;
4211 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4212 : GDALDataset::ToHandle(poSrcDS.get()), "JXL", 0, 0, 20, 20,
4213 : 1, nullptr, ppabyBuffer, &nSize, &pszDetailedFormat),
4214 : CE_None);
4215 1 : ASSERT_LT(nSize, nUpperBoundSize);
4216 1 : ASSERT_TRUE(*ppabyBuffer == pabyBuffer);
4217 1 : EXPECT_TRUE(pszDetailedFormat != nullptr);
4218 1 : if (pszDetailedFormat)
4219 : {
4220 1 : ASSERT_STREQ(pszDetailedFormat, "JXL");
4221 1 : VSIFree(pszDetailedFormat);
4222 : }
4223 1 : EXPECT_EQ(abyBuffer[0], 0x00);
4224 1 : EXPECT_EQ(abyBuffer[1], 0x00);
4225 1 : EXPECT_EQ(abyBuffer[2], 0x00);
4226 1 : EXPECT_EQ(abyBuffer[3], 0x0C);
4227 1 : EXPECT_EQ(abyBuffer[nSize - 2], 0x4C);
4228 1 : EXPECT_EQ(abyBuffer[nSize - 1], 0x01);
4229 :
4230 : // Buffer larger than needed: OK
4231 1 : nSize = nUpperBoundSize + 1;
4232 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4233 : GDALDataset::ToHandle(poSrcDS.get()), "JXL", 0, 0, 20, 20,
4234 : 1, nullptr, ppabyBuffer, &nSize, nullptr),
4235 : CE_None);
4236 :
4237 : // Too small buffer
4238 1 : nSize = nUpperBoundSize - 1;
4239 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4240 : GDALDataset::ToHandle(poSrcDS.get()), "JXL", 0, 0, 20, 20,
4241 : 1, nullptr, ppabyBuffer, &nSize, nullptr),
4242 : CE_Failure);
4243 :
4244 : // Missing pointer to size
4245 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4246 : GDALDataset::ToHandle(poSrcDS.get()), "JXL", 0, 0, 20, 20,
4247 : 1, nullptr, ppabyBuffer, nullptr, nullptr),
4248 : CE_Failure);
4249 : }
4250 :
4251 : // Let GDAL allocate buffer
4252 : {
4253 1 : void *pBuffer = nullptr;
4254 1 : size_t nSize = nUpperBoundSize;
4255 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4256 : GDALDataset::ToHandle(poSrcDS.get()), "JXL", 0, 0, 20, 20,
4257 : 1, nullptr, &pBuffer, &nSize, nullptr),
4258 : CE_None);
4259 1 : EXPECT_GT(nSize, 6);
4260 1 : EXPECT_LT(nSize, nUpperBoundSize);
4261 1 : EXPECT_NE(pBuffer, nullptr);
4262 1 : if (pBuffer != nullptr && nSize >= 6 && nSize <= nUpperBoundSize)
4263 : {
4264 1 : const GByte *pabyBuffer = static_cast<GByte *>(pBuffer);
4265 1 : EXPECT_EQ(pabyBuffer[0], 0x00);
4266 1 : EXPECT_EQ(pabyBuffer[1], 0x00);
4267 1 : EXPECT_EQ(pabyBuffer[2], 0x00);
4268 1 : EXPECT_EQ(pabyBuffer[3], 0x0C);
4269 1 : EXPECT_EQ(pabyBuffer[nSize - 2], 0x4C);
4270 1 : EXPECT_EQ(pabyBuffer[nSize - 1], 0x01);
4271 : }
4272 1 : VSIFree(pBuffer);
4273 : }
4274 : }
4275 :
4276 : // Test GDALDataset::GetCompressionFormats() and ReadCompressedData()
4277 4 : TEST_F(test_gdal, jpegxl_jpeg_compatible_ReadCompressedData)
4278 : {
4279 1 : auto poDrv = GDALDriver::FromHandle(GDALGetDriverByName("JPEGXL"));
4280 1 : if (poDrv == nullptr)
4281 : {
4282 0 : GTEST_SKIP() << "JPEGXL support missing";
4283 : }
4284 :
4285 1 : GDALDatasetUniquePtr poSrcDS(GDALDataset::FromHandle(GDALDataset::Open(
4286 1 : (tut::common::data_basedir +
4287 : "/../../gdrivers/data/jpegxl/exif_orientation/F1.jxl")
4288 1 : .c_str())));
4289 1 : ASSERT_TRUE(poSrcDS);
4290 :
4291 : const CPLStringList aosRet(GDALDatasetGetCompressionFormats(
4292 1 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0, 3, 5, 1, nullptr));
4293 1 : EXPECT_EQ(aosRet.size(), 2);
4294 1 : if (aosRet.size() == 2)
4295 : {
4296 1 : EXPECT_STREQ(aosRet[0], "JXL");
4297 1 : EXPECT_STREQ(aosRet[1], "JPEG");
4298 : }
4299 :
4300 : size_t nUpperBoundSize;
4301 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4302 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 3, 5, 1,
4303 : nullptr, nullptr, &nUpperBoundSize, nullptr),
4304 : CE_None);
4305 1 : EXPECT_EQ(nUpperBoundSize, 235);
4306 :
4307 : {
4308 1 : std::vector<GByte> abyBuffer(nUpperBoundSize);
4309 1 : void *pabyBuffer = abyBuffer.data();
4310 1 : void **ppabyBuffer = &pabyBuffer;
4311 1 : size_t nSize = nUpperBoundSize;
4312 1 : char *pszDetailedFormat = nullptr;
4313 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4314 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 3, 5,
4315 : 1, nullptr, ppabyBuffer, &nSize, &pszDetailedFormat),
4316 : CE_None);
4317 1 : ASSERT_LE(nSize, nUpperBoundSize);
4318 1 : ASSERT_TRUE(*ppabyBuffer == pabyBuffer);
4319 1 : EXPECT_TRUE(pszDetailedFormat != nullptr);
4320 1 : if (pszDetailedFormat)
4321 : {
4322 1 : ASSERT_STREQ(pszDetailedFormat,
4323 : "JPEG;frame_type=SOF0_baseline;bit_depth=8;num_"
4324 : "components=1;colorspace=unknown");
4325 1 : VSIFree(pszDetailedFormat);
4326 : }
4327 1 : EXPECT_EQ(abyBuffer[0], 0xFF);
4328 1 : EXPECT_EQ(abyBuffer[1], 0xD8);
4329 1 : EXPECT_EQ(abyBuffer[nSize - 2], 0xFF);
4330 1 : EXPECT_EQ(abyBuffer[nSize - 1], 0xD9);
4331 :
4332 : // Buffer larger than needed: OK
4333 1 : nSize = nUpperBoundSize + 1;
4334 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4335 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 3, 5,
4336 : 1, nullptr, ppabyBuffer, &nSize, nullptr),
4337 : CE_None);
4338 :
4339 : // Too small buffer
4340 1 : nSize = nUpperBoundSize - 1;
4341 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4342 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 3, 5,
4343 : 1, nullptr, ppabyBuffer, &nSize, nullptr),
4344 : CE_Failure);
4345 :
4346 : // Missing pointer to size
4347 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4348 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 3, 5,
4349 : 1, nullptr, ppabyBuffer, nullptr, nullptr),
4350 : CE_Failure);
4351 : }
4352 :
4353 : // Let GDAL allocate buffer
4354 : {
4355 1 : void *pBuffer = nullptr;
4356 1 : size_t nSize = nUpperBoundSize;
4357 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
4358 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 3, 5,
4359 : 1, nullptr, &pBuffer, &nSize, nullptr),
4360 : CE_None);
4361 1 : EXPECT_GT(nSize, 4);
4362 1 : EXPECT_LE(nSize, nUpperBoundSize);
4363 1 : EXPECT_NE(pBuffer, nullptr);
4364 1 : if (pBuffer != nullptr && nSize >= 4 && nSize <= nUpperBoundSize)
4365 : {
4366 1 : const GByte *pabyBuffer = static_cast<GByte *>(pBuffer);
4367 1 : EXPECT_EQ(pabyBuffer[0], 0xFF);
4368 1 : EXPECT_EQ(pabyBuffer[1], 0xD8);
4369 1 : EXPECT_EQ(pabyBuffer[nSize - 2], 0xFF);
4370 1 : EXPECT_EQ(pabyBuffer[nSize - 1], 0xD9);
4371 : }
4372 1 : VSIFree(pBuffer);
4373 : }
4374 : }
4375 :
4376 : // Test GDAL_OF_SHARED flag and open options
4377 4 : TEST_F(test_gdal, open_shared_open_options)
4378 : {
4379 1 : if (!GDALGetDriverByName("GTiff"))
4380 : {
4381 0 : GTEST_SKIP() << "GTiff driver missing";
4382 : }
4383 :
4384 1 : CPLErrorReset();
4385 1 : const char *const apszOpenOptions[] = {"OVERVIEW_LEVEL=NONE", nullptr};
4386 : {
4387 : GDALDataset *poDS1 =
4388 1 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
4389 1 : nullptr, apszOpenOptions);
4390 : GDALDataset *poDS2 =
4391 1 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
4392 1 : nullptr, apszOpenOptions);
4393 1 : EXPECT_EQ(CPLGetLastErrorType(), CE_None);
4394 1 : EXPECT_NE(poDS1, nullptr);
4395 1 : EXPECT_NE(poDS2, nullptr);
4396 1 : EXPECT_EQ(poDS1, poDS2);
4397 1 : GDALClose(poDS1);
4398 1 : GDALClose(poDS2);
4399 : }
4400 : {
4401 : GDALDataset *poDS1 =
4402 1 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
4403 1 : nullptr, apszOpenOptions);
4404 1 : GDALDataset *poDS2 = GDALDataset::Open(
4405 1 : GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED, nullptr, nullptr);
4406 : GDALDataset *poDS3 =
4407 1 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
4408 1 : nullptr, apszOpenOptions);
4409 1 : EXPECT_EQ(CPLGetLastErrorType(), CE_None);
4410 1 : EXPECT_NE(poDS1, nullptr);
4411 1 : EXPECT_NE(poDS2, nullptr);
4412 1 : EXPECT_NE(poDS3, nullptr);
4413 1 : EXPECT_NE(poDS1, poDS2);
4414 1 : EXPECT_EQ(poDS1, poDS3);
4415 1 : GDALClose(poDS1);
4416 1 : GDALClose(poDS2);
4417 1 : GDALClose(poDS3);
4418 : }
4419 : {
4420 1 : GDALDataset *poDS1 = GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif",
4421 : GDAL_OF_SHARED | GDAL_OF_UPDATE,
4422 1 : nullptr, apszOpenOptions);
4423 : // We allow to re-use a shared dataset in update mode when requesting it in read-only
4424 : GDALDataset *poDS2 =
4425 1 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
4426 1 : nullptr, apszOpenOptions);
4427 1 : EXPECT_EQ(CPLGetLastErrorType(), CE_None);
4428 1 : EXPECT_NE(poDS1, nullptr);
4429 1 : EXPECT_NE(poDS2, nullptr);
4430 1 : EXPECT_EQ(poDS1, poDS2);
4431 1 : GDALClose(poDS1);
4432 1 : GDALClose(poDS2);
4433 : }
4434 : {
4435 1 : GDALDataset *poDS1 = GDALDataset::Open(
4436 1 : GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED, nullptr, nullptr);
4437 : GDALDataset *poDS2 =
4438 1 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
4439 1 : nullptr, apszOpenOptions);
4440 : GDALDataset *poDS3 =
4441 1 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
4442 1 : nullptr, apszOpenOptions);
4443 1 : EXPECT_EQ(CPLGetLastErrorType(), CE_None);
4444 1 : EXPECT_NE(poDS1, nullptr);
4445 1 : EXPECT_NE(poDS2, nullptr);
4446 1 : EXPECT_NE(poDS3, nullptr);
4447 1 : EXPECT_NE(poDS1, poDS2);
4448 1 : EXPECT_EQ(poDS2, poDS3);
4449 1 : GDALClose(poDS1);
4450 1 : GDALClose(poDS2);
4451 1 : GDALClose(poDS3);
4452 : }
4453 : }
4454 :
4455 : // Test DropCache() to check that no data is saved on disk
4456 4 : TEST_F(test_gdal, drop_cache)
4457 : {
4458 1 : CPLErrorReset();
4459 : {
4460 1 : GDALDriverManager *gdalDriverManager = GetGDALDriverManager();
4461 1 : if (!gdalDriverManager)
4462 0 : return;
4463 1 : GDALDriver *enviDriver = gdalDriverManager->GetDriverByName("ENVI");
4464 1 : if (!enviDriver)
4465 0 : return;
4466 1 : const char *enviOptions[] = {"SUFFIX=ADD", "INTERLEAVE=BIL", nullptr};
4467 :
4468 1 : const char *filename = GCORE_DATA_DIR "test_drop_cache.bil";
4469 :
4470 : auto poDS = std::unique_ptr<GDALDataset>(enviDriver->Create(
4471 1 : filename, 1, 1, 1, GDALDataType::GDT_Float32, enviOptions));
4472 1 : if (!poDS)
4473 0 : return;
4474 1 : poDS->GetRasterBand(1)->Fill(1);
4475 1 : poDS->DropCache();
4476 1 : poDS.reset();
4477 :
4478 1 : poDS.reset(
4479 : GDALDataset::Open(filename, GDAL_OF_SHARED, nullptr, nullptr));
4480 1 : if (!poDS)
4481 0 : return;
4482 :
4483 1 : EXPECT_EQ(GDALChecksumImage(poDS->GetRasterBand(1), 0, 0, 1, 1), 0);
4484 1 : poDS->MarkSuppressOnClose();
4485 1 : poDS.reset();
4486 : }
4487 : }
4488 :
4489 : // Test gdal::gcp class
4490 4 : TEST_F(test_gdal, gdal_gcp_class)
4491 : {
4492 : {
4493 2 : gdal::GCP gcp;
4494 1 : EXPECT_STREQ(gcp.Id(), "");
4495 1 : EXPECT_STREQ(gcp.Info(), "");
4496 1 : EXPECT_EQ(gcp.Pixel(), 0.0);
4497 1 : EXPECT_EQ(gcp.Line(), 0.0);
4498 1 : EXPECT_EQ(gcp.X(), 0.0);
4499 1 : EXPECT_EQ(gcp.Y(), 0.0);
4500 1 : EXPECT_EQ(gcp.Z(), 0.0);
4501 : }
4502 : {
4503 2 : gdal::GCP gcp("id", "info", 1.5, 2.5, 3.5, 4.5, 5.5);
4504 1 : EXPECT_STREQ(gcp.Id(), "id");
4505 1 : EXPECT_STREQ(gcp.Info(), "info");
4506 1 : EXPECT_EQ(gcp.Pixel(), 1.5);
4507 1 : EXPECT_EQ(gcp.Line(), 2.5);
4508 1 : EXPECT_EQ(gcp.X(), 3.5);
4509 1 : EXPECT_EQ(gcp.Y(), 4.5);
4510 1 : EXPECT_EQ(gcp.Z(), 5.5);
4511 :
4512 1 : gcp.SetId("id2");
4513 1 : gcp.SetInfo("info2");
4514 1 : gcp.Pixel() = -1.5;
4515 1 : gcp.Line() = -2.5;
4516 1 : gcp.X() = -3.5;
4517 1 : gcp.Y() = -4.5;
4518 1 : gcp.Z() = -5.5;
4519 1 : EXPECT_STREQ(gcp.Id(), "id2");
4520 1 : EXPECT_STREQ(gcp.Info(), "info2");
4521 1 : EXPECT_EQ(gcp.Pixel(), -1.5);
4522 1 : EXPECT_EQ(gcp.Line(), -2.5);
4523 1 : EXPECT_EQ(gcp.X(), -3.5);
4524 1 : EXPECT_EQ(gcp.Y(), -4.5);
4525 1 : EXPECT_EQ(gcp.Z(), -5.5);
4526 :
4527 : {
4528 2 : gdal::GCP gcp_copy(gcp);
4529 1 : EXPECT_STREQ(gcp_copy.Id(), "id2");
4530 1 : EXPECT_STREQ(gcp_copy.Info(), "info2");
4531 1 : EXPECT_EQ(gcp_copy.Pixel(), -1.5);
4532 1 : EXPECT_EQ(gcp_copy.Line(), -2.5);
4533 1 : EXPECT_EQ(gcp_copy.X(), -3.5);
4534 1 : EXPECT_EQ(gcp_copy.Y(), -4.5);
4535 1 : EXPECT_EQ(gcp_copy.Z(), -5.5);
4536 : }
4537 :
4538 : {
4539 2 : gdal::GCP gcp_copy;
4540 1 : gcp_copy = gcp;
4541 1 : EXPECT_STREQ(gcp_copy.Id(), "id2");
4542 1 : EXPECT_STREQ(gcp_copy.Info(), "info2");
4543 1 : EXPECT_EQ(gcp_copy.Pixel(), -1.5);
4544 1 : EXPECT_EQ(gcp_copy.Line(), -2.5);
4545 1 : EXPECT_EQ(gcp_copy.X(), -3.5);
4546 1 : EXPECT_EQ(gcp_copy.Y(), -4.5);
4547 1 : EXPECT_EQ(gcp_copy.Z(), -5.5);
4548 : }
4549 :
4550 : {
4551 2 : gdal::GCP gcp_copy(gcp);
4552 2 : gdal::GCP gcp_from_moved(std::move(gcp_copy));
4553 1 : EXPECT_STREQ(gcp_from_moved.Id(), "id2");
4554 1 : EXPECT_STREQ(gcp_from_moved.Info(), "info2");
4555 1 : EXPECT_EQ(gcp_from_moved.Pixel(), -1.5);
4556 1 : EXPECT_EQ(gcp_from_moved.Line(), -2.5);
4557 1 : EXPECT_EQ(gcp_from_moved.X(), -3.5);
4558 1 : EXPECT_EQ(gcp_from_moved.Y(), -4.5);
4559 1 : EXPECT_EQ(gcp_from_moved.Z(), -5.5);
4560 : }
4561 :
4562 : {
4563 2 : gdal::GCP gcp_copy(gcp);
4564 2 : gdal::GCP gcp_from_moved;
4565 1 : gcp_from_moved = std::move(gcp_copy);
4566 1 : EXPECT_STREQ(gcp_from_moved.Id(), "id2");
4567 1 : EXPECT_STREQ(gcp_from_moved.Info(), "info2");
4568 1 : EXPECT_EQ(gcp_from_moved.Pixel(), -1.5);
4569 1 : EXPECT_EQ(gcp_from_moved.Line(), -2.5);
4570 1 : EXPECT_EQ(gcp_from_moved.X(), -3.5);
4571 1 : EXPECT_EQ(gcp_from_moved.Y(), -4.5);
4572 1 : EXPECT_EQ(gcp_from_moved.Z(), -5.5);
4573 : }
4574 :
4575 : {
4576 1 : const GDAL_GCP *c_gcp = gcp.c_ptr();
4577 1 : EXPECT_STREQ(c_gcp->pszId, "id2");
4578 1 : EXPECT_STREQ(c_gcp->pszInfo, "info2");
4579 1 : EXPECT_EQ(c_gcp->dfGCPPixel, -1.5);
4580 1 : EXPECT_EQ(c_gcp->dfGCPLine, -2.5);
4581 1 : EXPECT_EQ(c_gcp->dfGCPX, -3.5);
4582 1 : EXPECT_EQ(c_gcp->dfGCPY, -4.5);
4583 1 : EXPECT_EQ(c_gcp->dfGCPZ, -5.5);
4584 :
4585 2 : const gdal::GCP gcp_from_c(*c_gcp);
4586 1 : EXPECT_STREQ(gcp_from_c.Id(), "id2");
4587 1 : EXPECT_STREQ(gcp_from_c.Info(), "info2");
4588 1 : EXPECT_EQ(gcp_from_c.Pixel(), -1.5);
4589 1 : EXPECT_EQ(gcp_from_c.Line(), -2.5);
4590 1 : EXPECT_EQ(gcp_from_c.X(), -3.5);
4591 1 : EXPECT_EQ(gcp_from_c.Y(), -4.5);
4592 1 : EXPECT_EQ(gcp_from_c.Z(), -5.5);
4593 : }
4594 : }
4595 :
4596 : {
4597 : const std::vector<gdal::GCP> gcps{
4598 : gdal::GCP{nullptr, nullptr, 0, 0, 0, 0, 0},
4599 4 : gdal::GCP{"id", "info", 1.5, 2.5, 3.5, 4.5, 5.5}};
4600 :
4601 1 : const GDAL_GCP *c_gcps = gdal::GCP::c_ptr(gcps);
4602 1 : EXPECT_STREQ(c_gcps[1].pszId, "id");
4603 1 : EXPECT_STREQ(c_gcps[1].pszInfo, "info");
4604 1 : EXPECT_EQ(c_gcps[1].dfGCPPixel, 1.5);
4605 1 : EXPECT_EQ(c_gcps[1].dfGCPLine, 2.5);
4606 1 : EXPECT_EQ(c_gcps[1].dfGCPX, 3.5);
4607 1 : EXPECT_EQ(c_gcps[1].dfGCPY, 4.5);
4608 1 : EXPECT_EQ(c_gcps[1].dfGCPZ, 5.5);
4609 :
4610 : const auto gcps_from_c =
4611 1 : gdal::GCP::fromC(c_gcps, static_cast<int>(gcps.size()));
4612 1 : ASSERT_EQ(gcps_from_c.size(), gcps.size());
4613 3 : for (size_t i = 0; i < gcps.size(); ++i)
4614 : {
4615 2 : EXPECT_STREQ(gcps_from_c[i].Id(), gcps[i].Id());
4616 2 : EXPECT_STREQ(gcps_from_c[i].Info(), gcps[i].Info());
4617 2 : EXPECT_EQ(gcps_from_c[i].Pixel(), gcps[i].Pixel());
4618 2 : EXPECT_EQ(gcps_from_c[i].Line(), gcps[i].Line());
4619 2 : EXPECT_EQ(gcps_from_c[i].X(), gcps[i].X());
4620 2 : EXPECT_EQ(gcps_from_c[i].Y(), gcps[i].Y());
4621 2 : EXPECT_EQ(gcps_from_c[i].Z(), gcps[i].Z());
4622 : }
4623 : }
4624 : }
4625 :
4626 4 : TEST_F(test_gdal, RasterIO_gdt_unknown)
4627 : {
4628 : GDALDatasetUniquePtr poDS(
4629 2 : MEMDataset::Create("", 1, 1, 1, GDT_Float64, nullptr));
4630 2 : CPLErrorHandlerPusher oErrorHandler(CPLQuietErrorHandler);
4631 1 : GByte b = 0;
4632 : GDALRasterIOExtraArg sExtraArg;
4633 1 : INIT_RASTERIO_EXTRA_ARG(sExtraArg);
4634 1 : EXPECT_EQ(poDS->RasterIO(GF_Read, 0, 0, 1, 1, &b, 1, 1, GDT_Unknown, 1,
4635 : nullptr, 0, 0, 0, &sExtraArg),
4636 : CE_Failure);
4637 1 : EXPECT_EQ(poDS->RasterIO(GF_Read, 0, 0, 1, 1, &b, 1, 1, GDT_TypeCount, 1,
4638 : nullptr, 0, 0, 0, &sExtraArg),
4639 : CE_Failure);
4640 1 : EXPECT_EQ(poDS->GetRasterBand(1)->RasterIO(GF_Read, 0, 0, 1, 1, &b, 1, 1,
4641 : GDT_Unknown, 0, 0, &sExtraArg),
4642 : CE_Failure);
4643 1 : EXPECT_EQ(poDS->GetRasterBand(1)->RasterIO(GF_Read, 0, 0, 1, 1, &b, 1, 1,
4644 : GDT_TypeCount, 0, 0, &sExtraArg),
4645 : CE_Failure);
4646 1 : }
4647 :
4648 4 : TEST_F(test_gdal, CopyWords_gdt_unknown)
4649 : {
4650 2 : CPLErrorHandlerPusher oErrorHandler(CPLQuietErrorHandler);
4651 1 : GByte b = 0;
4652 1 : GByte b2 = 0;
4653 1 : CPLErrorReset();
4654 1 : GDALCopyWords(&b, GDT_Byte, 0, &b2, GDT_Unknown, 0, 1);
4655 1 : EXPECT_EQ(CPLGetLastErrorType(), CE_Failure);
4656 1 : CPLErrorReset();
4657 1 : GDALCopyWords(&b, GDT_Unknown, 0, &b2, GDT_Byte, 0, 1);
4658 1 : EXPECT_EQ(CPLGetLastErrorType(), CE_Failure);
4659 1 : }
4660 :
4661 : // Test GDALRasterBand::ReadRaster
4662 4 : TEST_F(test_gdal, ReadRaster)
4663 : {
4664 : GDALDatasetUniquePtr poDS(
4665 1 : MEMDataset::Create("", 2, 3, 1, GDT_Float64, nullptr));
4666 1 : std::array<double, 6> buffer = {
4667 : -1e300, -1, //////////////////////////////////////////////
4668 : 1, 128, //////////////////////////////////////////////
4669 : 32768, 1e300, //////////////////////////////////////////////
4670 : };
4671 : GDALRasterIOExtraArg sExtraArg;
4672 1 : INIT_RASTERIO_EXTRA_ARG(sExtraArg);
4673 1 : EXPECT_EQ(poDS->GetRasterBand(1)->RasterIO(
4674 : GF_Write, 0, 0, 2, 3, buffer.data(), 2, 3, GDT_Float64,
4675 : sizeof(double), 2 * sizeof(double), &sExtraArg),
4676 : CE_None);
4677 :
4678 : {
4679 2 : std::vector<uint8_t> res;
4680 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4681 2 : const auto expected_res = std::vector<uint8_t>{0, 0, 1, 128, 255, 255};
4682 1 : EXPECT_EQ(res, expected_res);
4683 :
4684 1 : std::fill(res.begin(), res.end(), 0);
4685 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res, 0, 0, 2, 3, 2, 3),
4686 : CE_None);
4687 1 : EXPECT_EQ(res, expected_res);
4688 :
4689 1 : std::fill(res.begin(), res.end(), 0);
4690 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res, 0, 0, 2, 3), CE_None);
4691 1 : EXPECT_EQ(res, expected_res);
4692 :
4693 : #if __cplusplus >= 202002L
4694 : std::fill(res.begin(), res.end(), 0);
4695 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(std::span<uint8_t>(res)),
4696 : CE_None);
4697 : EXPECT_EQ(res, expected_res);
4698 : #endif
4699 :
4700 1 : std::fill(res.begin(), res.end(), 0);
4701 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4702 1 : EXPECT_EQ(res, expected_res);
4703 :
4704 1 : std::fill(res.begin(), res.end(), 0);
4705 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data(), res.size()),
4706 : CE_None);
4707 1 : EXPECT_EQ(res, expected_res);
4708 :
4709 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
4710 : // Too small buffer size
4711 1 : EXPECT_EQ(
4712 : poDS->GetRasterBand(1)->ReadRaster(res.data(), res.size() - 1),
4713 : CE_Failure);
4714 1 : CPLPopErrorHandler();
4715 :
4716 1 : std::fill(res.begin(), res.end(), 0);
4717 1 : EXPECT_EQ(
4718 : poDS->GetRasterBand(1)->ReadRaster(res.data(), 0, 0, 0, 2, 3, 2, 3),
4719 : CE_None);
4720 1 : EXPECT_EQ(res, expected_res);
4721 :
4722 1 : std::fill(res.begin(), res.end(), 0);
4723 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data(), 0, 0, 0, 2, 3),
4724 : CE_None);
4725 1 : EXPECT_EQ(res, expected_res);
4726 : }
4727 :
4728 : {
4729 2 : std::vector<double> res;
4730 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
4731 : // Too large nBufXSize
4732 1 : EXPECT_EQ(
4733 : poDS->GetRasterBand(1)->ReadRaster(res, 0, 0, 1, 1, UINT32_MAX, 1),
4734 : CE_Failure);
4735 :
4736 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data(), UINT32_MAX, 0,
4737 : 0, 1, 1, UINT32_MAX, 1),
4738 : CE_Failure);
4739 :
4740 : // Too large nBufYSize
4741 1 : EXPECT_EQ(
4742 : poDS->GetRasterBand(1)->ReadRaster(res, 0, 0, 1, 1, 1, UINT32_MAX),
4743 : CE_Failure);
4744 :
4745 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data(), UINT32_MAX, 0,
4746 : 0, 1, 1, 1, UINT32_MAX),
4747 : CE_Failure);
4748 :
4749 1 : CPLPopErrorHandler();
4750 : }
4751 :
4752 : {
4753 2 : std::vector<double> res;
4754 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
4755 : // Huge nBufXSize x nBufYSize
4756 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res, 0, 0, 1, 1, INT32_MAX,
4757 : INT32_MAX),
4758 : CE_Failure);
4759 1 : CPLPopErrorHandler();
4760 : }
4761 :
4762 : {
4763 2 : std::vector<double> res;
4764 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res, 1, 2, 1, 1), CE_None);
4765 2 : const auto expected_res = std::vector<double>{1e300};
4766 1 : EXPECT_EQ(res, expected_res);
4767 : }
4768 :
4769 : {
4770 2 : std::vector<double> res;
4771 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
4772 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res, 1.1, 2.1, 0.9, 0.9),
4773 : CE_Failure);
4774 1 : CPLPopErrorHandler();
4775 :
4776 1 : EXPECT_EQ(
4777 : poDS->GetRasterBand(1)->ReadRaster(res, 1.1, 2.1, 0.9, 0.9, 1, 1),
4778 : CE_None);
4779 2 : const auto expected_res = std::vector<double>{1e300};
4780 1 : EXPECT_EQ(res, expected_res);
4781 : }
4782 :
4783 : {
4784 1 : std::vector<double> res;
4785 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res, 0.4, 0.5, 1.4, 1.5, 1,
4786 : 1, GRIORA_Bilinear),
4787 : CE_None);
4788 1 : ASSERT_EQ(res.size(), 1U);
4789 1 : const double expected_res = -8.64198e+298;
4790 1 : EXPECT_NEAR(res[0], expected_res, std::fabs(expected_res) * 1e-6);
4791 : }
4792 :
4793 : // Test int8_t
4794 : {
4795 2 : std::vector<int8_t> res;
4796 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4797 : const auto expected_res =
4798 2 : std::vector<int8_t>{-128, -1, 1, 127, 127, 127};
4799 1 : EXPECT_EQ(res, expected_res);
4800 :
4801 1 : std::fill(res.begin(), res.end(), 0);
4802 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4803 1 : EXPECT_EQ(res, expected_res);
4804 : }
4805 :
4806 : // Test uint16_t
4807 : {
4808 2 : std::vector<uint16_t> res;
4809 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4810 : const auto expected_res =
4811 2 : std::vector<uint16_t>{0, 0, 1, 128, 32768, 65535};
4812 1 : EXPECT_EQ(res, expected_res);
4813 :
4814 1 : std::fill(res.begin(), res.end(), 0);
4815 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4816 1 : EXPECT_EQ(res, expected_res);
4817 :
4818 1 : std::fill(res.begin(), res.end(), 0);
4819 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data(), res.size()),
4820 : CE_None);
4821 1 : EXPECT_EQ(res, expected_res);
4822 : }
4823 :
4824 : // Test int16_t
4825 : {
4826 2 : std::vector<int16_t> res;
4827 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4828 : const auto expected_res =
4829 2 : std::vector<int16_t>{-32768, -1, 1, 128, 32767, 32767};
4830 1 : EXPECT_EQ(res, expected_res);
4831 :
4832 1 : std::fill(res.begin(), res.end(), 0);
4833 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4834 1 : EXPECT_EQ(res, expected_res);
4835 : }
4836 :
4837 : #if 0
4838 : // Not allowed by C++ standard
4839 : // Test complex<int16_t>
4840 : {
4841 : std::vector<std::complex<int16_t>> res;
4842 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4843 : const auto expected_res = std::vector<std::complex<int16_t>>{
4844 : -32768, -1, 1, 128, 32767, 32767};
4845 : EXPECT_EQ(res, expected_res);
4846 :
4847 : std::fill(res.begin(), res.end(), 0);
4848 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4849 : EXPECT_EQ(res, expected_res);
4850 : }
4851 : #endif
4852 :
4853 : // Test uint32_t
4854 : {
4855 2 : std::vector<uint32_t> res;
4856 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4857 : const auto expected_res =
4858 2 : std::vector<uint32_t>{0, 0, 1, 128, 32768, UINT32_MAX};
4859 1 : EXPECT_EQ(res, expected_res);
4860 :
4861 1 : std::fill(res.begin(), res.end(), 0);
4862 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4863 1 : EXPECT_EQ(res, expected_res);
4864 : }
4865 :
4866 : // Test int32_t
4867 : {
4868 2 : std::vector<int32_t> res;
4869 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4870 : const auto expected_res =
4871 2 : std::vector<int32_t>{INT32_MIN, -1, 1, 128, 32768, INT32_MAX};
4872 1 : EXPECT_EQ(res, expected_res);
4873 :
4874 1 : std::fill(res.begin(), res.end(), 0);
4875 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4876 1 : EXPECT_EQ(res, expected_res);
4877 : }
4878 :
4879 : #if 0
4880 : // Not allowed by C++ standard
4881 : // Test complex<int32_t>
4882 : {
4883 : std::vector<std::complex<int32_t>> res;
4884 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4885 : const auto expected_res = std::vector<std::complex<int32_t>>{
4886 : INT32_MIN, -1, 1, 128, 32768, INT32_MAX};
4887 : EXPECT_EQ(res, expected_res);
4888 :
4889 : std::fill(res.begin(), res.end(), 0);
4890 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4891 : EXPECT_EQ(res, expected_res);
4892 : }
4893 : #endif
4894 :
4895 : // Test uint64_t
4896 : {
4897 2 : std::vector<uint64_t> res;
4898 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4899 : const auto expected_res =
4900 2 : std::vector<uint64_t>{0, 0, 1, 128, 32768, UINT64_MAX};
4901 1 : EXPECT_EQ(res, expected_res);
4902 :
4903 1 : std::fill(res.begin(), res.end(), 0);
4904 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4905 1 : EXPECT_EQ(res, expected_res);
4906 : }
4907 :
4908 : // Test int64_t
4909 : {
4910 2 : std::vector<int64_t> res;
4911 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4912 : const auto expected_res =
4913 2 : std::vector<int64_t>{INT64_MIN, -1, 1, 128, 32768, INT64_MAX};
4914 1 : EXPECT_EQ(res, expected_res);
4915 :
4916 1 : std::fill(res.begin(), res.end(), 0);
4917 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4918 1 : EXPECT_EQ(res, expected_res);
4919 : }
4920 :
4921 : // Test GFloat16
4922 : {
4923 2 : std::vector<GFloat16> res;
4924 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4925 : const auto expected_res =
4926 1 : std::vector<GFloat16>{-cpl::NumericLimits<GFloat16>::infinity(),
4927 : static_cast<GFloat16>(-1.0f),
4928 : static_cast<GFloat16>(1.0f),
4929 : static_cast<GFloat16>(128.0f),
4930 : static_cast<GFloat16>(32768.0f),
4931 2 : cpl::NumericLimits<GFloat16>::infinity()};
4932 1 : EXPECT_EQ(res, expected_res);
4933 :
4934 1 : std::fill(res.begin(), res.end(), static_cast<GFloat16>(0.0f));
4935 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4936 1 : EXPECT_EQ(res, expected_res);
4937 : }
4938 :
4939 : // Test float
4940 : {
4941 2 : std::vector<float> res;
4942 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4943 : const auto expected_res =
4944 : std::vector<float>{-cpl::NumericLimits<float>::infinity(),
4945 : -1.0f,
4946 : 1.0f,
4947 : 128.0f,
4948 : 32768.0f,
4949 2 : cpl::NumericLimits<float>::infinity()};
4950 1 : EXPECT_EQ(res, expected_res);
4951 :
4952 1 : std::fill(res.begin(), res.end(), 0.0f);
4953 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4954 1 : EXPECT_EQ(res, expected_res);
4955 : }
4956 :
4957 : // Test complex<float>
4958 : {
4959 2 : std::vector<std::complex<float>> res;
4960 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4961 : const auto expected_res = std::vector<std::complex<float>>{
4962 : -cpl::NumericLimits<float>::infinity(),
4963 : -1.0f,
4964 : 1.0f,
4965 : 128.0f,
4966 : 32768.0f,
4967 2 : cpl::NumericLimits<float>::infinity()};
4968 1 : EXPECT_EQ(res, expected_res);
4969 :
4970 1 : std::fill(res.begin(), res.end(), 0.0f);
4971 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4972 1 : EXPECT_EQ(res, expected_res);
4973 : }
4974 :
4975 : // Test double
4976 : {
4977 2 : std::vector<double> res;
4978 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4979 : const auto expected_res =
4980 2 : std::vector<double>{-1e300, -1, 1, 128, 32768, 1e300};
4981 1 : EXPECT_EQ(res, expected_res);
4982 :
4983 1 : std::fill(res.begin(), res.end(), 0);
4984 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4985 1 : EXPECT_EQ(res, expected_res);
4986 : }
4987 :
4988 : // Test complex<double>
4989 : {
4990 2 : std::vector<std::complex<double>> res;
4991 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res), CE_None);
4992 : const auto expected_res =
4993 2 : std::vector<std::complex<double>>{-1e300, -1, 1, 128, 32768, 1e300};
4994 1 : EXPECT_EQ(res, expected_res);
4995 :
4996 1 : std::fill(res.begin(), res.end(), 0);
4997 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ReadRaster(res.data()), CE_None);
4998 1 : EXPECT_EQ(res, expected_res);
4999 : }
5000 : }
5001 :
5002 : // Test GDALComputeRasterMinMaxLocation
5003 4 : TEST_F(test_gdal, GDALComputeRasterMinMaxLocation)
5004 : {
5005 1 : GDALDatasetH hDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
5006 1 : ASSERT_NE(hDS, nullptr);
5007 1 : GDALRasterBandH hBand = GDALGetRasterBand(hDS, 1);
5008 : {
5009 1 : double dfMin = 0;
5010 1 : double dfMax = 0;
5011 1 : int nMinX = -1;
5012 1 : int nMinY = -1;
5013 1 : int nMaxX = -1;
5014 1 : int nMaxY = -1;
5015 1 : EXPECT_EQ(GDALComputeRasterMinMaxLocation(hBand, &dfMin, &dfMax, &nMinX,
5016 : &nMinY, &nMaxX, &nMaxY),
5017 : CE_None);
5018 1 : EXPECT_EQ(dfMin, 74.0);
5019 1 : EXPECT_EQ(dfMax, 255.0);
5020 1 : EXPECT_EQ(nMinX, 9);
5021 1 : EXPECT_EQ(nMinY, 17);
5022 1 : EXPECT_EQ(nMaxX, 2);
5023 1 : EXPECT_EQ(nMaxY, 18);
5024 1 : GByte val = 0;
5025 1 : EXPECT_EQ(GDALRasterIO(hBand, GF_Read, nMinX, nMinY, 1, 1, &val, 1, 1,
5026 : GDT_Byte, 0, 0),
5027 : CE_None);
5028 1 : EXPECT_EQ(val, 74);
5029 1 : EXPECT_EQ(GDALRasterIO(hBand, GF_Read, nMaxX, nMaxY, 1, 1, &val, 1, 1,
5030 : GDT_Byte, 0, 0),
5031 : CE_None);
5032 1 : EXPECT_EQ(val, 255);
5033 : }
5034 : {
5035 1 : int nMinX = -1;
5036 1 : int nMinY = -1;
5037 1 : EXPECT_EQ(GDALComputeRasterMinMaxLocation(hBand, nullptr, nullptr,
5038 : &nMinX, &nMinY, nullptr,
5039 : nullptr),
5040 : CE_None);
5041 1 : EXPECT_EQ(nMinX, 9);
5042 1 : EXPECT_EQ(nMinY, 17);
5043 : }
5044 : {
5045 1 : int nMaxX = -1;
5046 1 : int nMaxY = -1;
5047 1 : EXPECT_EQ(GDALComputeRasterMinMaxLocation(hBand, nullptr, nullptr,
5048 : nullptr, nullptr, &nMaxX,
5049 : &nMaxY),
5050 : CE_None);
5051 1 : EXPECT_EQ(nMaxX, 2);
5052 1 : EXPECT_EQ(nMaxY, 18);
5053 : }
5054 : {
5055 1 : EXPECT_EQ(GDALComputeRasterMinMaxLocation(hBand, nullptr, nullptr,
5056 : nullptr, nullptr, nullptr,
5057 : nullptr),
5058 : CE_None);
5059 : }
5060 1 : GDALClose(hDS);
5061 : }
5062 :
5063 : // Test GDALComputeRasterMinMaxLocation
5064 4 : TEST_F(test_gdal, GDALComputeRasterMinMaxLocation_byte_min_max_optim)
5065 : {
5066 : GDALDatasetUniquePtr poDS(
5067 2 : MEMDataset::Create("", 1, 4, 1, GDT_Byte, nullptr));
5068 1 : std::array<uint8_t, 4> buffer = {
5069 : 1, //////////////////////////////////////////////////////////
5070 : 0, //////////////////////////////////////////////////////////
5071 : 255, //////////////////////////////////////////////////////////
5072 : 1, //////////////////////////////////////////////////////////
5073 : };
5074 : GDALRasterIOExtraArg sExtraArg;
5075 1 : INIT_RASTERIO_EXTRA_ARG(sExtraArg);
5076 1 : EXPECT_EQ(poDS->GetRasterBand(1)->RasterIO(
5077 : GF_Write, 0, 0, 1, 4, buffer.data(), 1, 4, GDT_Byte,
5078 : sizeof(uint8_t), 1 * sizeof(uint8_t), &sExtraArg),
5079 : CE_None);
5080 :
5081 1 : double dfMin = 0;
5082 1 : double dfMax = 0;
5083 1 : int nMinX = -1;
5084 1 : int nMinY = -1;
5085 1 : int nMaxX = -1;
5086 1 : int nMaxY = -1;
5087 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ComputeRasterMinMaxLocation(
5088 : &dfMin, &dfMax, &nMinX, &nMinY, &nMaxX, &nMaxY),
5089 : CE_None);
5090 1 : EXPECT_EQ(dfMin, 0);
5091 1 : EXPECT_EQ(dfMax, 255);
5092 1 : EXPECT_EQ(nMinX, 0);
5093 1 : EXPECT_EQ(nMinY, 1);
5094 1 : EXPECT_EQ(nMaxX, 0);
5095 1 : EXPECT_EQ(nMaxY, 2);
5096 1 : }
5097 :
5098 : // Test GDALComputeRasterMinMaxLocation
5099 4 : TEST_F(test_gdal, GDALComputeRasterMinMaxLocation_with_mask)
5100 : {
5101 : GDALDatasetUniquePtr poDS(
5102 2 : MEMDataset::Create("", 2, 2, 1, GDT_Byte, nullptr));
5103 1 : std::array<uint8_t, 6> buffer = {
5104 : 2, 10, //////////////////////////////////////////////////////////
5105 : 4, 20, //////////////////////////////////////////////////////////
5106 : };
5107 : GDALRasterIOExtraArg sExtraArg;
5108 1 : INIT_RASTERIO_EXTRA_ARG(sExtraArg);
5109 1 : EXPECT_EQ(poDS->GetRasterBand(1)->RasterIO(
5110 : GF_Write, 0, 0, 2, 2, buffer.data(), 2, 2, GDT_Byte,
5111 : sizeof(uint8_t), 2 * sizeof(uint8_t), &sExtraArg),
5112 : CE_None);
5113 :
5114 1 : poDS->GetRasterBand(1)->CreateMaskBand(0);
5115 1 : std::array<uint8_t, 6> buffer_mask = {
5116 : 0, 255, //////////////////////////////////////////////////////////
5117 : 255, 0, //////////////////////////////////////////////////////////
5118 : };
5119 1 : EXPECT_EQ(poDS->GetRasterBand(1)->GetMaskBand()->RasterIO(
5120 : GF_Write, 0, 0, 2, 2, buffer_mask.data(), 2, 2, GDT_Byte,
5121 : sizeof(uint8_t), 2 * sizeof(uint8_t), &sExtraArg),
5122 : CE_None);
5123 :
5124 1 : double dfMin = 0;
5125 1 : double dfMax = 0;
5126 1 : int nMinX = -1;
5127 1 : int nMinY = -1;
5128 1 : int nMaxX = -1;
5129 1 : int nMaxY = -1;
5130 1 : EXPECT_EQ(poDS->GetRasterBand(1)->ComputeRasterMinMaxLocation(
5131 : &dfMin, &dfMax, &nMinX, &nMinY, &nMaxX, &nMaxY),
5132 : CE_None);
5133 1 : EXPECT_EQ(dfMin, 4);
5134 1 : EXPECT_EQ(dfMax, 10);
5135 1 : EXPECT_EQ(nMinX, 0);
5136 1 : EXPECT_EQ(nMinY, 1);
5137 1 : EXPECT_EQ(nMaxX, 1);
5138 1 : EXPECT_EQ(nMaxY, 0);
5139 1 : }
5140 :
5141 4 : TEST_F(test_gdal, GDALTranspose2D)
5142 : {
5143 1 : constexpr int COUNT = 6;
5144 1 : const GByte abyData[] = {1, 2, 3, 4, 5, 6};
5145 : GByte abySrcData[COUNT * 2 * sizeof(double)];
5146 : GByte abyDstData[COUNT * 2 * sizeof(double)];
5147 : GByte abyDstAsByteData[COUNT * 2 * sizeof(double)];
5148 17 : for (int eSrcDTInt = GDT_Byte; eSrcDTInt < GDT_TypeCount; ++eSrcDTInt)
5149 : {
5150 16 : const auto eSrcDT = static_cast<GDALDataType>(eSrcDTInt);
5151 16 : GDALCopyWords(abyData, GDT_Byte, 1, abySrcData, eSrcDT,
5152 : GDALGetDataTypeSizeBytes(eSrcDT), COUNT);
5153 272 : for (int eDstDTInt = GDT_Byte; eDstDTInt < GDT_TypeCount; ++eDstDTInt)
5154 : {
5155 256 : const auto eDstDT = static_cast<GDALDataType>(eDstDTInt);
5156 256 : memset(abyDstData, 0, sizeof(abyDstData));
5157 256 : GDALTranspose2D(abySrcData, eSrcDT, abyDstData, eDstDT, 3, 2);
5158 :
5159 256 : memset(abyDstAsByteData, 0, sizeof(abyDstAsByteData));
5160 256 : GDALCopyWords(abyDstData, eDstDT, GDALGetDataTypeSizeBytes(eDstDT),
5161 : abyDstAsByteData, GDT_Byte, 1, COUNT);
5162 :
5163 256 : EXPECT_EQ(abyDstAsByteData[0], 1)
5164 0 : << "eSrcDT=" << eSrcDT << ", eDstDT=" << eDstDT;
5165 256 : EXPECT_EQ(abyDstAsByteData[1], 4)
5166 0 : << "eSrcDT=" << eSrcDT << ", eDstDT=" << eDstDT;
5167 256 : EXPECT_EQ(abyDstAsByteData[2], 2)
5168 0 : << "eSrcDT=" << eSrcDT << ", eDstDT=" << eDstDT;
5169 256 : EXPECT_EQ(abyDstAsByteData[3], 5)
5170 0 : << "eSrcDT=" << eSrcDT << ", eDstDT=" << eDstDT;
5171 256 : EXPECT_EQ(abyDstAsByteData[4], 3)
5172 0 : << "eSrcDT=" << eSrcDT << ", eDstDT=" << eDstDT;
5173 256 : EXPECT_EQ(abyDstAsByteData[5], 6)
5174 0 : << "eSrcDT=" << eSrcDT << ", eDstDT=" << eDstDT;
5175 : }
5176 : }
5177 1 : }
5178 :
5179 4 : TEST_F(test_gdal, GDALTranspose2D_Byte_optims)
5180 : {
5181 2 : std::vector<GByte> in;
5182 324 : for (int i = 0; i < 19 * 17; ++i)
5183 323 : in.push_back(static_cast<GByte>(i % 256));
5184 :
5185 2 : std::vector<GByte> out(in.size());
5186 :
5187 : // SSSE3 optim (16x16) blocks
5188 : {
5189 1 : constexpr int W = 19;
5190 1 : constexpr int H = 17;
5191 1 : GDALTranspose2D(in.data(), GDT_Byte, out.data(), GDT_Byte, W, H);
5192 18 : for (int y = 0; y < H; ++y)
5193 : {
5194 340 : for (int x = 0; x < W; ++x)
5195 : {
5196 323 : EXPECT_EQ(out[x * H + y], in[y * W + x]);
5197 : }
5198 : }
5199 : }
5200 :
5201 : // Optim H = 2 with W < 16
5202 : {
5203 1 : constexpr int W = 15;
5204 1 : constexpr int H = 2;
5205 1 : GDALTranspose2D(in.data(), GDT_Byte, out.data(), GDT_Byte, W, H);
5206 3 : for (int y = 0; y < H; ++y)
5207 : {
5208 32 : for (int x = 0; x < W; ++x)
5209 : {
5210 30 : EXPECT_EQ(out[x * H + y], in[y * W + x]);
5211 : }
5212 : }
5213 : }
5214 :
5215 : // Optim H = 2 with W >= 16
5216 : {
5217 1 : constexpr int W = 19;
5218 1 : constexpr int H = 2;
5219 1 : GDALTranspose2D(in.data(), GDT_Byte, out.data(), GDT_Byte, W, H);
5220 3 : for (int y = 0; y < H; ++y)
5221 : {
5222 40 : for (int x = 0; x < W; ++x)
5223 : {
5224 38 : EXPECT_EQ(out[x * H + y], in[y * W + x]);
5225 : }
5226 : }
5227 : }
5228 :
5229 : // SSSE3 optim H = 3 with W < 16
5230 : {
5231 1 : constexpr int W = 15;
5232 1 : constexpr int H = 3;
5233 1 : GDALTranspose2D(in.data(), GDT_Byte, out.data(), GDT_Byte, W, H);
5234 4 : for (int y = 0; y < H; ++y)
5235 : {
5236 48 : for (int x = 0; x < W; ++x)
5237 : {
5238 45 : EXPECT_EQ(out[x * H + y], in[y * W + x]);
5239 : }
5240 : }
5241 : }
5242 :
5243 : // SSSE3 optim H = 3 with W >= 16
5244 : {
5245 1 : constexpr int W = 19;
5246 1 : constexpr int H = 3;
5247 1 : GDALTranspose2D(in.data(), GDT_Byte, out.data(), GDT_Byte, W, H);
5248 4 : for (int y = 0; y < H; ++y)
5249 : {
5250 60 : for (int x = 0; x < W; ++x)
5251 : {
5252 57 : EXPECT_EQ(out[x * H + y], in[y * W + x]);
5253 : }
5254 : }
5255 : }
5256 :
5257 : // Optim H = 4 with H < 16
5258 : {
5259 1 : constexpr int W = 15;
5260 1 : constexpr int H = 4;
5261 1 : GDALTranspose2D(in.data(), GDT_Byte, out.data(), GDT_Byte, W, H);
5262 5 : for (int y = 0; y < H; ++y)
5263 : {
5264 64 : for (int x = 0; x < W; ++x)
5265 : {
5266 60 : EXPECT_EQ(out[x * H + y], in[y * W + x]);
5267 : }
5268 : }
5269 : }
5270 :
5271 : // Optim H = 4 with H >= 16
5272 : {
5273 1 : constexpr int W = 19;
5274 1 : constexpr int H = 4;
5275 1 : GDALTranspose2D(in.data(), GDT_Byte, out.data(), GDT_Byte, W, H);
5276 5 : for (int y = 0; y < H; ++y)
5277 : {
5278 80 : for (int x = 0; x < W; ++x)
5279 : {
5280 76 : EXPECT_EQ(out[x * H + y], in[y * W + x]);
5281 : }
5282 : }
5283 : }
5284 :
5285 : // SSSE3 optim H = 5 with W < 16
5286 : {
5287 1 : constexpr int W = 15;
5288 1 : constexpr int H = 5;
5289 1 : GDALTranspose2D(in.data(), GDT_Byte, out.data(), GDT_Byte, W, H);
5290 6 : for (int y = 0; y < H; ++y)
5291 : {
5292 80 : for (int x = 0; x < W; ++x)
5293 : {
5294 75 : EXPECT_EQ(out[x * H + y], in[y * W + x]);
5295 : }
5296 : }
5297 : }
5298 :
5299 : // SSSE3 optim H = 5 with W >= 16
5300 : {
5301 1 : constexpr int W = 19;
5302 1 : constexpr int H = 5;
5303 1 : GDALTranspose2D(in.data(), GDT_Byte, out.data(), GDT_Byte, W, H);
5304 6 : for (int y = 0; y < H; ++y)
5305 : {
5306 100 : for (int x = 0; x < W; ++x)
5307 : {
5308 95 : EXPECT_EQ(out[x * H + y], in[y * W + x]);
5309 : }
5310 : }
5311 : }
5312 1 : }
5313 :
5314 4 : TEST_F(test_gdal, GDALExpandPackedBitsToByteAt0Or1)
5315 : {
5316 1 : unsigned next = 1;
5317 141 : const auto badRand = [&next]()
5318 : {
5319 141 : next = static_cast<unsigned>(static_cast<uint64_t>(next) * 1103515245 +
5320 : 12345);
5321 141 : return next;
5322 1 : };
5323 :
5324 1 : constexpr int BITS_PER_BYTE = 8;
5325 1 : constexpr int SSE_REGISTER_SIZE_IN_BYTES = 16;
5326 1 : constexpr int LESS_THAN_8BITS = 5;
5327 : std::vector<GByte> expectedOut(SSE_REGISTER_SIZE_IN_BYTES * BITS_PER_BYTE +
5328 2 : BITS_PER_BYTE + LESS_THAN_8BITS);
5329 1 : std::vector<GByte> in((expectedOut.size() + BITS_PER_BYTE - 1) /
5330 3 : BITS_PER_BYTE);
5331 142 : for (int i = 0; i < static_cast<int>(expectedOut.size()); ++i)
5332 : {
5333 141 : expectedOut[i] = (badRand() % 2) == 0 ? 0 : 1;
5334 141 : if (expectedOut[i])
5335 : {
5336 70 : in[i / BITS_PER_BYTE] = static_cast<GByte>(
5337 70 : in[i / BITS_PER_BYTE] |
5338 70 : (1 << (BITS_PER_BYTE - 1 - (i % BITS_PER_BYTE))));
5339 : }
5340 : }
5341 :
5342 2 : std::vector<GByte> out(expectedOut.size());
5343 1 : GDALExpandPackedBitsToByteAt0Or1(in.data(), out.data(), out.size());
5344 :
5345 1 : EXPECT_EQ(out, expectedOut);
5346 1 : }
5347 :
5348 4 : TEST_F(test_gdal, GDALExpandPackedBitsToByteAt0Or255)
5349 : {
5350 1 : unsigned next = 1;
5351 141 : const auto badRand = [&next]()
5352 : {
5353 141 : next = static_cast<unsigned>(static_cast<uint64_t>(next) * 1103515245 +
5354 : 12345);
5355 141 : return next;
5356 1 : };
5357 :
5358 1 : constexpr int BITS_PER_BYTE = 8;
5359 1 : constexpr int SSE_REGISTER_SIZE_IN_BYTES = 16;
5360 1 : constexpr int LESS_THAN_8BITS = 5;
5361 : std::vector<GByte> expectedOut(SSE_REGISTER_SIZE_IN_BYTES * BITS_PER_BYTE +
5362 2 : BITS_PER_BYTE + LESS_THAN_8BITS);
5363 1 : std::vector<GByte> in((expectedOut.size() + BITS_PER_BYTE - 1) /
5364 3 : BITS_PER_BYTE);
5365 142 : for (int i = 0; i < static_cast<int>(expectedOut.size()); ++i)
5366 : {
5367 141 : expectedOut[i] = (badRand() % 2) == 0 ? 0 : 255;
5368 141 : if (expectedOut[i])
5369 : {
5370 70 : in[i / BITS_PER_BYTE] = static_cast<GByte>(
5371 70 : in[i / BITS_PER_BYTE] |
5372 70 : (1 << (BITS_PER_BYTE - 1 - (i % BITS_PER_BYTE))));
5373 : }
5374 : }
5375 :
5376 2 : std::vector<GByte> out(expectedOut.size());
5377 1 : GDALExpandPackedBitsToByteAt0Or255(in.data(), out.data(), out.size());
5378 :
5379 1 : EXPECT_EQ(out, expectedOut);
5380 1 : }
5381 :
5382 4 : TEST_F(test_gdal, GDALComputeOvFactor)
5383 : {
5384 1 : EXPECT_EQ(GDALComputeOvFactor((1000 + 16 - 1) / 16, 1000, 1, 1), 16);
5385 1 : EXPECT_EQ(GDALComputeOvFactor(1, 1, (1000 + 16 - 1) / 16, 1000), 16);
5386 1 : EXPECT_EQ(GDALComputeOvFactor((1000 + 32 - 1) / 32, 1000,
5387 : (1000 + 32 - 1) / 32, 1000),
5388 : 32);
5389 1 : EXPECT_EQ(GDALComputeOvFactor((1000 + 64 - 1) / 64, 1000,
5390 : (1000 + 64 - 1) / 64, 1000),
5391 : 64);
5392 1 : EXPECT_EQ(GDALComputeOvFactor((1000 + 128 - 1) / 128, 1000,
5393 : (1000 + 128 - 1) / 128, 1000),
5394 : 128);
5395 1 : EXPECT_EQ(GDALComputeOvFactor((1000 + 256 - 1) / 256, 1000,
5396 : (1000 + 256 - 1) / 256, 1000),
5397 : 256);
5398 1 : EXPECT_EQ(GDALComputeOvFactor((1000 + 25 - 1) / 25, 1000, 1, 1), 25);
5399 1 : EXPECT_EQ(GDALComputeOvFactor(1, 1, (1000 + 25 - 1) / 25, 1000), 25);
5400 1 : }
5401 :
5402 4 : TEST_F(test_gdal, GDALRegenerateOverviewsMultiBand_very_large_block_size)
5403 : {
5404 : class MyBand final : public GDALRasterBand
5405 : {
5406 : public:
5407 2 : explicit MyBand(int nSize)
5408 2 : {
5409 2 : nRasterXSize = nSize;
5410 2 : nRasterYSize = nSize;
5411 2 : nBlockXSize = std::max(1, nSize / 2);
5412 2 : nBlockYSize = std::max(1, nSize / 2);
5413 2 : eDataType = GDT_Float64;
5414 2 : }
5415 :
5416 2 : CPLErr IReadBlock(int, int, void *) override
5417 : {
5418 2 : return CE_Failure;
5419 : }
5420 :
5421 2 : CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
5422 : GDALDataType, GSpacing, GSpacing,
5423 : GDALRasterIOExtraArg *) override
5424 : {
5425 2 : IReadBlock(0, 0, nullptr);
5426 2 : return CE_Failure;
5427 : }
5428 : };
5429 :
5430 : class MyDataset : public GDALDataset
5431 : {
5432 : public:
5433 1 : MyDataset()
5434 1 : {
5435 1 : nRasterXSize = INT_MAX;
5436 1 : nRasterYSize = INT_MAX;
5437 1 : SetBand(1, std::make_unique<MyBand>(INT_MAX));
5438 1 : }
5439 : };
5440 :
5441 2 : MyDataset ds;
5442 1 : GDALRasterBand *poSrcBand = ds.GetRasterBand(1);
5443 1 : GDALRasterBand **ppoSrcBand = &poSrcBand;
5444 1 : GDALRasterBandH hSrcBand = GDALRasterBand::ToHandle(poSrcBand);
5445 :
5446 2 : MyBand overBand1x1(1);
5447 1 : GDALRasterBand *poOvrBand = &overBand1x1;
5448 1 : GDALRasterBand **ppoOvrBand = &poOvrBand;
5449 1 : GDALRasterBandH hOverBand1x1 = GDALRasterBand::ToHandle(poOvrBand);
5450 :
5451 2 : CPLErrorStateBackuper oBackuper(CPLQuietErrorHandler);
5452 1 : EXPECT_EQ(GDALRegenerateOverviewsMultiBand(1, &poSrcBand, 1, &ppoSrcBand,
5453 : "AVERAGE", nullptr, nullptr,
5454 : nullptr),
5455 : CE_Failure);
5456 :
5457 1 : EXPECT_EQ(GDALRegenerateOverviewsMultiBand(1, &poSrcBand, 1, &ppoOvrBand,
5458 : "AVERAGE", nullptr, nullptr,
5459 : nullptr),
5460 : CE_Failure);
5461 :
5462 1 : EXPECT_EQ(GDALRegenerateOverviewsEx(hSrcBand, 1, &hSrcBand, "AVERAGE",
5463 : nullptr, nullptr, nullptr),
5464 : CE_Failure);
5465 :
5466 1 : EXPECT_EQ(GDALRegenerateOverviewsEx(hSrcBand, 1, &hOverBand1x1, "AVERAGE",
5467 : nullptr, nullptr, nullptr),
5468 : CE_Failure);
5469 1 : }
5470 :
5471 4 : TEST_F(test_gdal, GDALColorTable_from_qml_paletted)
5472 : {
5473 : {
5474 2 : CPLErrorStateBackuper oBackuper(CPLQuietErrorHandler);
5475 1 : CPLErrorReset();
5476 : auto poCT =
5477 2 : GDALColorTable::LoadFromFile(GCORE_DATA_DIR "i_do_not_exist.txt");
5478 1 : EXPECT_EQ(poCT, nullptr);
5479 1 : EXPECT_EQ(CPLGetLastErrorType(), CE_Failure);
5480 : }
5481 :
5482 : {
5483 : auto poCT = GDALColorTable::LoadFromFile(GCORE_DATA_DIR
5484 1 : "qgis_qml_paletted.qml");
5485 1 : ASSERT_NE(poCT, nullptr);
5486 1 : EXPECT_EQ(poCT->GetColorEntryCount(), 256);
5487 1 : const GDALColorEntry *psEntry = poCT->GetColorEntry(74);
5488 1 : EXPECT_NE(psEntry, nullptr);
5489 1 : EXPECT_EQ(psEntry->c1, 67);
5490 1 : EXPECT_EQ(psEntry->c2, 27);
5491 1 : EXPECT_EQ(psEntry->c3, 225);
5492 1 : EXPECT_EQ(psEntry->c4, 255);
5493 : }
5494 :
5495 : {
5496 : auto poCT = GDALColorTable::LoadFromFile(
5497 1 : GCORE_DATA_DIR "qgis_qml_singlebandpseudocolor.qml");
5498 1 : ASSERT_NE(poCT, nullptr);
5499 1 : EXPECT_EQ(poCT->GetColorEntryCount(), 256);
5500 1 : const GDALColorEntry *psEntry = poCT->GetColorEntry(74);
5501 1 : EXPECT_NE(psEntry, nullptr);
5502 1 : EXPECT_EQ(psEntry->c1, 255);
5503 1 : EXPECT_EQ(psEntry->c2, 255);
5504 1 : EXPECT_EQ(psEntry->c3, 204);
5505 1 : EXPECT_EQ(psEntry->c4, 255);
5506 : }
5507 :
5508 : {
5509 : auto poCT = GDALColorTable::LoadFromFile(
5510 1 : UTILITIES_DATA_DIR "color_paletted_red_green_0-255.txt");
5511 1 : ASSERT_NE(poCT, nullptr);
5512 1 : EXPECT_EQ(poCT->GetColorEntryCount(), 256);
5513 : {
5514 1 : const GDALColorEntry *psEntry = poCT->GetColorEntry(0);
5515 1 : EXPECT_NE(psEntry, nullptr);
5516 1 : EXPECT_EQ(psEntry->c1, 255);
5517 1 : EXPECT_EQ(psEntry->c2, 255);
5518 1 : EXPECT_EQ(psEntry->c3, 255);
5519 1 : EXPECT_EQ(psEntry->c4, 0);
5520 : }
5521 : {
5522 1 : const GDALColorEntry *psEntry = poCT->GetColorEntry(1);
5523 1 : EXPECT_NE(psEntry, nullptr);
5524 1 : EXPECT_EQ(psEntry->c1, 128);
5525 1 : EXPECT_EQ(psEntry->c2, 128);
5526 1 : EXPECT_EQ(psEntry->c3, 128);
5527 1 : EXPECT_EQ(psEntry->c4, 255);
5528 : }
5529 : {
5530 1 : const GDALColorEntry *psEntry = poCT->GetColorEntry(2);
5531 1 : EXPECT_NE(psEntry, nullptr);
5532 1 : EXPECT_EQ(psEntry->c1, 255);
5533 1 : EXPECT_EQ(psEntry->c2, 0);
5534 1 : EXPECT_EQ(psEntry->c3, 0);
5535 1 : EXPECT_EQ(psEntry->c4, 255);
5536 : }
5537 : }
5538 : }
5539 :
5540 4 : TEST_F(test_gdal, GDALRasterBand_arithmetic_operators)
5541 : {
5542 1 : constexpr int WIDTH = 1;
5543 1 : constexpr int HEIGHT = 2;
5544 : auto poDS = std::unique_ptr<GDALDataset, GDALDatasetUniquePtrReleaser>(
5545 2 : MEMDataset::Create("", WIDTH, HEIGHT, 3, GDT_Float64, nullptr));
5546 1 : std::array<double, 6> adfGT = {1, 2, 3, 4, 5, 6};
5547 1 : poDS->SetGeoTransform(adfGT.data());
5548 1 : OGRSpatialReference *poSRS = new OGRSpatialReference();
5549 1 : poSRS->SetFromUserInput("WGS84");
5550 1 : poDS->SetSpatialRef(poSRS);
5551 1 : poSRS->Release();
5552 1 : auto &firstBand = *(poDS->GetRasterBand(1));
5553 1 : auto &secondBand = *(poDS->GetRasterBand(2));
5554 1 : auto &thirdBand = *(poDS->GetRasterBand(3));
5555 1 : constexpr double FIRST = 1.5;
5556 1 : firstBand.Fill(FIRST);
5557 1 : constexpr double SECOND = 2.5;
5558 1 : secondBand.Fill(SECOND);
5559 1 : constexpr double THIRD = 3.5;
5560 1 : thirdBand.Fill(THIRD);
5561 :
5562 : {
5563 : auto poOtherDS =
5564 : std::unique_ptr<GDALDataset, GDALDatasetUniquePtrReleaser>(
5565 2 : MEMDataset::Create("", 1, 1, 1, GDT_Byte, nullptr));
5566 2 : EXPECT_THROW(
5567 : CPL_IGNORE_RET_VAL(firstBand + (*poOtherDS->GetRasterBand(1))),
5568 : std::runtime_error);
5569 2 : EXPECT_THROW(CPL_IGNORE_RET_VAL(
5570 : gdal::min(firstBand, (*poOtherDS->GetRasterBand(1)))),
5571 : std::runtime_error);
5572 2 : EXPECT_THROW(CPL_IGNORE_RET_VAL(gdal::min(
5573 : firstBand, firstBand, (*poOtherDS->GetRasterBand(1)))),
5574 : std::runtime_error);
5575 2 : EXPECT_THROW(CPL_IGNORE_RET_VAL(
5576 : gdal::max(firstBand, (*poOtherDS->GetRasterBand(1)))),
5577 : std::runtime_error);
5578 2 : EXPECT_THROW(CPL_IGNORE_RET_VAL(gdal::max(
5579 : firstBand, firstBand, (*poOtherDS->GetRasterBand(1)))),
5580 : std::runtime_error);
5581 2 : EXPECT_THROW(CPL_IGNORE_RET_VAL(
5582 : gdal::mean(firstBand, (*poOtherDS->GetRasterBand(1)))),
5583 : std::runtime_error);
5584 2 : EXPECT_THROW(CPL_IGNORE_RET_VAL(gdal::mean(
5585 : firstBand, firstBand, (*poOtherDS->GetRasterBand(1)))),
5586 : std::runtime_error);
5587 : #ifdef HAVE_MUPARSER
5588 2 : EXPECT_THROW(
5589 : CPL_IGNORE_RET_VAL(firstBand > (*poOtherDS->GetRasterBand(1))),
5590 : std::runtime_error);
5591 2 : EXPECT_THROW(
5592 : CPL_IGNORE_RET_VAL(firstBand >= (*poOtherDS->GetRasterBand(1))),
5593 : std::runtime_error);
5594 2 : EXPECT_THROW(
5595 : CPL_IGNORE_RET_VAL(firstBand < (*poOtherDS->GetRasterBand(1))),
5596 : std::runtime_error);
5597 2 : EXPECT_THROW(
5598 : CPL_IGNORE_RET_VAL(firstBand <= (*poOtherDS->GetRasterBand(1))),
5599 : std::runtime_error);
5600 2 : EXPECT_THROW(
5601 : CPL_IGNORE_RET_VAL(firstBand == (*poOtherDS->GetRasterBand(1))),
5602 : std::runtime_error);
5603 2 : EXPECT_THROW(
5604 : CPL_IGNORE_RET_VAL(firstBand != (*poOtherDS->GetRasterBand(1))),
5605 : std::runtime_error);
5606 2 : EXPECT_THROW(
5607 : CPL_IGNORE_RET_VAL(firstBand && (*poOtherDS->GetRasterBand(1))),
5608 : std::runtime_error);
5609 2 : EXPECT_THROW(
5610 : CPL_IGNORE_RET_VAL(firstBand || (*poOtherDS->GetRasterBand(1))),
5611 : std::runtime_error);
5612 2 : EXPECT_THROW(CPL_IGNORE_RET_VAL(gdal::IfThenElse(
5613 : firstBand, firstBand, (*poOtherDS->GetRasterBand(1)))),
5614 : std::runtime_error);
5615 2 : EXPECT_THROW(CPL_IGNORE_RET_VAL(gdal::IfThenElse(
5616 : firstBand, (*poOtherDS->GetRasterBand(1)), firstBand)),
5617 : std::runtime_error);
5618 2 : EXPECT_THROW(CPL_IGNORE_RET_VAL(
5619 : gdal::pow(firstBand, (*poOtherDS->GetRasterBand(1)))),
5620 : std::runtime_error);
5621 : #endif
5622 : }
5623 :
5624 : {
5625 1 : const auto Calc = [](const auto &a, const auto &b, const auto &c)
5626 : {
5627 : return (0.5 + 2 / gdal::min(c, gdal::max(a, b)) + 3 * a * 2 -
5628 : a * (1 - b) / c - 2 * a - 3 + 4) /
5629 : gdal::pow(3.0, a) * gdal::pow(b, 2.0) +
5630 : gdal::abs(-a) + gdal::fabs(-a) + gdal::sqrt(a) +
5631 : gdal::log10(a)
5632 : #ifdef HAVE_MUPARSER
5633 1 : + gdal::log(a) + gdal::pow(a, b)
5634 : #endif
5635 : ;
5636 : };
5637 :
5638 2 : auto formula = Calc(firstBand, secondBand, thirdBand);
5639 1 : const double expectedVal = Calc(FIRST, SECOND, THIRD);
5640 :
5641 1 : EXPECT_EQ(formula.GetXSize(), WIDTH);
5642 1 : EXPECT_EQ(formula.GetYSize(), HEIGHT);
5643 1 : EXPECT_EQ(formula.GetRasterDataType(), GDT_Float64);
5644 :
5645 : std::array<double, 6> gotGT;
5646 1 : EXPECT_EQ(formula.GetDataset()->GetGeoTransform(gotGT.data()), CE_None);
5647 1 : EXPECT_TRUE(gotGT == adfGT);
5648 :
5649 : const OGRSpatialReference *poGotSRS =
5650 1 : formula.GetDataset()->GetSpatialRef();
5651 1 : EXPECT_NE(poGotSRS, nullptr);
5652 1 : EXPECT_TRUE(poGotSRS->IsSame(poDS->GetSpatialRef()));
5653 :
5654 1 : EXPECT_NE(formula.GetDataset()->GetInternalHandle("VRT_DATASET"),
5655 : nullptr);
5656 1 : EXPECT_EQ(formula.GetDataset()->GetInternalHandle("invalid"), nullptr);
5657 :
5658 1 : EXPECT_EQ(formula.GetDataset()->GetMetadataItem("foo"), nullptr);
5659 1 : EXPECT_NE(formula.GetDataset()->GetMetadata("xml:VRT"), nullptr);
5660 :
5661 2 : std::vector<double> adfResults(WIDTH);
5662 1 : EXPECT_EQ(formula.ReadBlock(0, 0, adfResults.data()), CE_None);
5663 1 : EXPECT_NEAR(adfResults[0], expectedVal, 1e-14);
5664 :
5665 1 : double adfMinMax[2] = {0};
5666 1 : EXPECT_EQ(formula.ComputeRasterMinMax(false, adfMinMax), CE_None);
5667 1 : EXPECT_NEAR(adfMinMax[0], expectedVal, 1e-14);
5668 1 : EXPECT_NEAR(adfMinMax[1], expectedVal, 1e-14);
5669 :
5670 1 : EXPECT_EQ(gdal::min(thirdBand, firstBand, secondBand)
5671 : .ComputeRasterMinMax(false, adfMinMax),
5672 : CE_None);
5673 1 : EXPECT_NEAR(adfMinMax[0], std::min(FIRST, std::min(SECOND, THIRD)),
5674 : 1e-14);
5675 :
5676 1 : EXPECT_EQ(gdal::min(thirdBand, firstBand, 2, secondBand)
5677 : .ComputeRasterMinMax(false, adfMinMax),
5678 : CE_None);
5679 1 : EXPECT_NEAR(adfMinMax[0], std::min(FIRST, std::min(SECOND, THIRD)),
5680 : 1e-14);
5681 :
5682 1 : EXPECT_EQ(gdal::min(thirdBand, firstBand, -1, secondBand)
5683 : .ComputeRasterMinMax(false, adfMinMax),
5684 : CE_None);
5685 1 : EXPECT_EQ(adfMinMax[0], -1);
5686 :
5687 1 : EXPECT_EQ(gdal::max(firstBand, thirdBand, secondBand)
5688 : .ComputeRasterMinMax(false, adfMinMax),
5689 : CE_None);
5690 1 : EXPECT_NEAR(adfMinMax[0], std::max(FIRST, std::max(SECOND, THIRD)),
5691 : 1e-14);
5692 :
5693 1 : EXPECT_EQ(gdal::max(firstBand, thirdBand, -1, secondBand)
5694 : .ComputeRasterMinMax(false, adfMinMax),
5695 : CE_None);
5696 1 : EXPECT_NEAR(adfMinMax[0], std::max(FIRST, std::max(SECOND, THIRD)),
5697 : 1e-14);
5698 :
5699 1 : EXPECT_EQ(gdal::max(thirdBand, firstBand, 100, secondBand)
5700 : .ComputeRasterMinMax(false, adfMinMax),
5701 : CE_None);
5702 1 : EXPECT_EQ(adfMinMax[0], 100);
5703 :
5704 1 : EXPECT_EQ(gdal::mean(firstBand, thirdBand, secondBand)
5705 : .ComputeRasterMinMax(false, adfMinMax),
5706 : CE_None);
5707 1 : EXPECT_NEAR(adfMinMax[0], (FIRST + SECOND + THIRD) / 3, 1e-14);
5708 :
5709 : #ifdef HAVE_MUPARSER
5710 1 : EXPECT_EQ((firstBand > 1.4).GetRasterDataType(), GDT_Byte);
5711 1 : EXPECT_EQ((firstBand > 1.4).ComputeRasterMinMax(false, adfMinMax),
5712 : CE_None);
5713 1 : EXPECT_EQ(adfMinMax[0], 1);
5714 1 : EXPECT_EQ((firstBand > 1.5).ComputeRasterMinMax(false, adfMinMax),
5715 : CE_None);
5716 1 : EXPECT_EQ(adfMinMax[0], 0);
5717 1 : EXPECT_EQ((1.5 > firstBand).ComputeRasterMinMax(false, adfMinMax),
5718 : CE_None);
5719 1 : EXPECT_EQ(adfMinMax[0], 0);
5720 1 : EXPECT_EQ((1.6 > firstBand).ComputeRasterMinMax(false, adfMinMax),
5721 : CE_None);
5722 1 : EXPECT_EQ(adfMinMax[0], 1);
5723 1 : EXPECT_EQ((firstBand > firstBand).ComputeRasterMinMax(false, adfMinMax),
5724 : CE_None);
5725 1 : EXPECT_EQ(adfMinMax[0], 0);
5726 1 : EXPECT_EQ(
5727 : (secondBand > firstBand).ComputeRasterMinMax(false, adfMinMax),
5728 : CE_None);
5729 1 : EXPECT_EQ(adfMinMax[0], 1);
5730 :
5731 1 : EXPECT_EQ((firstBand >= 1.5).GetRasterDataType(), GDT_Byte);
5732 1 : EXPECT_EQ((firstBand >= 1.5).ComputeRasterMinMax(false, adfMinMax),
5733 : CE_None);
5734 1 : EXPECT_EQ(adfMinMax[0], 1);
5735 1 : EXPECT_EQ((firstBand >= 1.6).ComputeRasterMinMax(false, adfMinMax),
5736 : CE_None);
5737 1 : EXPECT_EQ(adfMinMax[0], 0);
5738 1 : EXPECT_EQ((1.4 >= firstBand).ComputeRasterMinMax(false, adfMinMax),
5739 : CE_None);
5740 1 : EXPECT_EQ(adfMinMax[0], 0);
5741 1 : EXPECT_EQ((1.5 >= firstBand).ComputeRasterMinMax(false, adfMinMax),
5742 : CE_None);
5743 1 : EXPECT_EQ(adfMinMax[0], 1);
5744 1 : EXPECT_EQ(
5745 : (firstBand >= firstBand).ComputeRasterMinMax(false, adfMinMax),
5746 : CE_None);
5747 1 : EXPECT_EQ(adfMinMax[0], 1);
5748 1 : EXPECT_EQ(
5749 : (secondBand >= firstBand).ComputeRasterMinMax(false, adfMinMax),
5750 : CE_None);
5751 1 : EXPECT_EQ(adfMinMax[0], 1);
5752 1 : EXPECT_EQ(
5753 : (firstBand >= secondBand).ComputeRasterMinMax(false, adfMinMax),
5754 : CE_None);
5755 1 : EXPECT_EQ(adfMinMax[0], 0);
5756 :
5757 1 : EXPECT_EQ((firstBand < 1.5).GetRasterDataType(), GDT_Byte);
5758 1 : EXPECT_EQ((firstBand < 1.5).ComputeRasterMinMax(false, adfMinMax),
5759 : CE_None);
5760 1 : EXPECT_EQ(adfMinMax[0], 0);
5761 1 : EXPECT_EQ((firstBand < 1.6).ComputeRasterMinMax(false, adfMinMax),
5762 : CE_None);
5763 1 : EXPECT_EQ(adfMinMax[0], 1);
5764 1 : EXPECT_EQ((1.5 < firstBand).ComputeRasterMinMax(false, adfMinMax),
5765 : CE_None);
5766 1 : EXPECT_EQ(adfMinMax[0], 0);
5767 1 : EXPECT_EQ((1.4 < firstBand).ComputeRasterMinMax(false, adfMinMax),
5768 : CE_None);
5769 1 : EXPECT_EQ(adfMinMax[0], 1);
5770 1 : EXPECT_EQ((firstBand < firstBand).ComputeRasterMinMax(false, adfMinMax),
5771 : CE_None);
5772 1 : EXPECT_EQ(adfMinMax[0], 0);
5773 1 : EXPECT_EQ(
5774 : (firstBand < secondBand).ComputeRasterMinMax(false, adfMinMax),
5775 : CE_None);
5776 1 : EXPECT_EQ(adfMinMax[0], 1);
5777 :
5778 1 : EXPECT_EQ((firstBand <= 1.5).GetRasterDataType(), GDT_Byte);
5779 1 : EXPECT_EQ((firstBand <= 1.5).ComputeRasterMinMax(false, adfMinMax),
5780 : CE_None);
5781 1 : EXPECT_EQ(adfMinMax[0], 1);
5782 1 : EXPECT_EQ((firstBand <= 1.4).ComputeRasterMinMax(false, adfMinMax),
5783 : CE_None);
5784 1 : EXPECT_EQ(adfMinMax[0], 0);
5785 1 : EXPECT_EQ((1.5 <= firstBand).ComputeRasterMinMax(false, adfMinMax),
5786 : CE_None);
5787 1 : EXPECT_EQ(adfMinMax[0], 1);
5788 1 : EXPECT_EQ((1.6 <= firstBand).ComputeRasterMinMax(false, adfMinMax),
5789 : CE_None);
5790 1 : EXPECT_EQ(adfMinMax[0], 0);
5791 1 : EXPECT_EQ(
5792 : (firstBand <= firstBand).ComputeRasterMinMax(false, adfMinMax),
5793 : CE_None);
5794 1 : EXPECT_EQ(adfMinMax[0], 1);
5795 1 : EXPECT_EQ(
5796 : (secondBand <= firstBand).ComputeRasterMinMax(false, adfMinMax),
5797 : CE_None);
5798 1 : EXPECT_EQ(adfMinMax[0], 0);
5799 1 : EXPECT_EQ(
5800 : (firstBand <= secondBand).ComputeRasterMinMax(false, adfMinMax),
5801 : CE_None);
5802 1 : EXPECT_EQ(adfMinMax[0], 1);
5803 :
5804 1 : EXPECT_EQ((firstBand == 1.5).GetRasterDataType(), GDT_Byte);
5805 1 : EXPECT_EQ((firstBand == 1.5).ComputeRasterMinMax(false, adfMinMax),
5806 : CE_None);
5807 1 : EXPECT_EQ(adfMinMax[0], 1);
5808 1 : EXPECT_EQ((firstBand == 1.6).ComputeRasterMinMax(false, adfMinMax),
5809 : CE_None);
5810 1 : EXPECT_EQ(adfMinMax[0], 0);
5811 1 : EXPECT_EQ((1.5 == firstBand).ComputeRasterMinMax(false, adfMinMax),
5812 : CE_None);
5813 1 : EXPECT_EQ(adfMinMax[0], 1);
5814 1 : EXPECT_EQ((1.4 == firstBand).ComputeRasterMinMax(false, adfMinMax),
5815 : CE_None);
5816 1 : EXPECT_EQ(adfMinMax[0], 0);
5817 1 : EXPECT_EQ(
5818 : (firstBand == firstBand).ComputeRasterMinMax(false, adfMinMax),
5819 : CE_None);
5820 1 : EXPECT_EQ(adfMinMax[0], 1);
5821 1 : EXPECT_EQ(
5822 : (firstBand == secondBand).ComputeRasterMinMax(false, adfMinMax),
5823 : CE_None);
5824 1 : EXPECT_EQ(adfMinMax[0], 0);
5825 :
5826 1 : EXPECT_EQ((firstBand != 1.5).GetRasterDataType(), GDT_Byte);
5827 1 : EXPECT_EQ((firstBand != 1.5).ComputeRasterMinMax(false, adfMinMax),
5828 : CE_None);
5829 1 : EXPECT_EQ(adfMinMax[0], 0);
5830 1 : EXPECT_EQ((firstBand != 1.6).ComputeRasterMinMax(false, adfMinMax),
5831 : CE_None);
5832 1 : EXPECT_EQ(adfMinMax[0], 1);
5833 1 : EXPECT_EQ((1.5 != firstBand).ComputeRasterMinMax(false, adfMinMax),
5834 : CE_None);
5835 1 : EXPECT_EQ(adfMinMax[0], 0);
5836 1 : EXPECT_EQ((1.4 != firstBand).ComputeRasterMinMax(false, adfMinMax),
5837 : CE_None);
5838 1 : EXPECT_EQ(adfMinMax[0], 1);
5839 1 : EXPECT_EQ(
5840 : (firstBand != firstBand).ComputeRasterMinMax(false, adfMinMax),
5841 : CE_None);
5842 1 : EXPECT_EQ(adfMinMax[0], 0);
5843 1 : EXPECT_EQ(
5844 : (firstBand != secondBand).ComputeRasterMinMax(false, adfMinMax),
5845 : CE_None);
5846 1 : EXPECT_EQ(adfMinMax[0], 1);
5847 :
5848 1 : EXPECT_EQ(gdal::IfThenElse(firstBand == 1.5, secondBand, thirdBand)
5849 : .ComputeRasterMinMax(false, adfMinMax),
5850 : CE_None);
5851 1 : EXPECT_EQ(adfMinMax[0], SECOND);
5852 1 : EXPECT_EQ(gdal::IfThenElse(firstBand == 1.5, secondBand, thirdBand)
5853 : .GetRasterDataType(),
5854 : GDALDataTypeUnion(secondBand.GetRasterDataType(),
5855 : thirdBand.GetRasterDataType()));
5856 :
5857 1 : EXPECT_EQ(gdal::IfThenElse(firstBand == 1.5, SECOND, THIRD)
5858 : .ComputeRasterMinMax(false, adfMinMax),
5859 : CE_None);
5860 1 : EXPECT_EQ(adfMinMax[0], SECOND);
5861 1 : EXPECT_EQ(gdal::IfThenElse(firstBand == 1.5, SECOND, THIRD)
5862 : .GetRasterDataType(),
5863 : GDT_Float32);
5864 :
5865 1 : EXPECT_EQ(gdal::IfThenElse(firstBand == 1.5, SECOND, thirdBand)
5866 : .ComputeRasterMinMax(false, adfMinMax),
5867 : CE_None);
5868 1 : EXPECT_EQ(adfMinMax[0], SECOND);
5869 :
5870 1 : EXPECT_EQ(gdal::IfThenElse(firstBand != 1.5, secondBand, thirdBand)
5871 : .ComputeRasterMinMax(false, adfMinMax),
5872 : CE_None);
5873 1 : EXPECT_EQ(adfMinMax[0], THIRD);
5874 :
5875 1 : EXPECT_EQ(gdal::IfThenElse(firstBand != 1.5, secondBand, THIRD)
5876 : .ComputeRasterMinMax(false, adfMinMax),
5877 : CE_None);
5878 1 : EXPECT_EQ(adfMinMax[0], THIRD);
5879 :
5880 1 : EXPECT_EQ(gdal::IfThenElse(firstBand != 1.5, SECOND, THIRD)
5881 : .ComputeRasterMinMax(false, adfMinMax),
5882 : CE_None);
5883 1 : EXPECT_EQ(adfMinMax[0], THIRD);
5884 : #endif
5885 : }
5886 :
5887 : #ifdef HAVE_MUPARSER
5888 : {
5889 : auto poLogicalDS =
5890 : std::unique_ptr<GDALDataset, GDALDatasetUniquePtrReleaser>(
5891 2 : MEMDataset::Create("", WIDTH, HEIGHT, 2, GDT_Byte, nullptr));
5892 1 : auto &trueBand = *(poLogicalDS->GetRasterBand(1));
5893 1 : auto &falseBand = *(poLogicalDS->GetRasterBand(2));
5894 1 : trueBand.Fill(true);
5895 1 : falseBand.Fill(false);
5896 :
5897 : double adfMinMax[2];
5898 :
5899 : // And
5900 1 : EXPECT_EQ((trueBand && falseBand).ComputeRasterMinMax(false, adfMinMax),
5901 : CE_None);
5902 1 : EXPECT_EQ(adfMinMax[0], false);
5903 :
5904 1 : EXPECT_EQ((trueBand && trueBand).ComputeRasterMinMax(false, adfMinMax),
5905 : CE_None);
5906 1 : EXPECT_EQ(adfMinMax[0], true);
5907 :
5908 1 : EXPECT_EQ((trueBand && true).ComputeRasterMinMax(false, adfMinMax),
5909 : CE_None);
5910 1 : EXPECT_EQ(adfMinMax[0], true);
5911 :
5912 1 : EXPECT_EQ((trueBand && false).ComputeRasterMinMax(false, adfMinMax),
5913 : CE_None);
5914 1 : EXPECT_EQ(adfMinMax[0], false);
5915 :
5916 1 : EXPECT_EQ((true && trueBand).ComputeRasterMinMax(false, adfMinMax),
5917 : CE_None);
5918 1 : EXPECT_EQ(adfMinMax[0], true);
5919 :
5920 1 : EXPECT_EQ((false && trueBand).ComputeRasterMinMax(false, adfMinMax),
5921 : CE_None);
5922 1 : EXPECT_EQ(adfMinMax[0], false);
5923 :
5924 : // Or
5925 1 : EXPECT_EQ((trueBand || falseBand).ComputeRasterMinMax(false, adfMinMax),
5926 : CE_None);
5927 1 : EXPECT_EQ(adfMinMax[0], true);
5928 :
5929 1 : EXPECT_EQ((trueBand || trueBand).ComputeRasterMinMax(false, adfMinMax),
5930 : CE_None);
5931 1 : EXPECT_EQ(adfMinMax[0], true);
5932 :
5933 1 : EXPECT_EQ(
5934 : (falseBand || falseBand).ComputeRasterMinMax(false, adfMinMax),
5935 : CE_None);
5936 1 : EXPECT_EQ(adfMinMax[0], false);
5937 :
5938 1 : EXPECT_EQ((trueBand || true).ComputeRasterMinMax(false, adfMinMax),
5939 : CE_None);
5940 1 : EXPECT_EQ(adfMinMax[0], true);
5941 :
5942 1 : EXPECT_EQ((trueBand || false).ComputeRasterMinMax(false, adfMinMax),
5943 : CE_None);
5944 1 : EXPECT_EQ(adfMinMax[0], true);
5945 :
5946 1 : EXPECT_EQ((falseBand || true).ComputeRasterMinMax(false, adfMinMax),
5947 : CE_None);
5948 1 : EXPECT_EQ(adfMinMax[0], true);
5949 :
5950 1 : EXPECT_EQ((falseBand || false).ComputeRasterMinMax(false, adfMinMax),
5951 : CE_None);
5952 1 : EXPECT_EQ(adfMinMax[0], false);
5953 :
5954 1 : EXPECT_EQ((true || trueBand).ComputeRasterMinMax(false, adfMinMax),
5955 : CE_None);
5956 1 : EXPECT_EQ(adfMinMax[0], true);
5957 :
5958 1 : EXPECT_EQ((false || trueBand).ComputeRasterMinMax(false, adfMinMax),
5959 : CE_None);
5960 1 : EXPECT_EQ(adfMinMax[0], true);
5961 :
5962 1 : EXPECT_EQ((true || falseBand).ComputeRasterMinMax(false, adfMinMax),
5963 : CE_None);
5964 1 : EXPECT_EQ(adfMinMax[0], true);
5965 :
5966 1 : EXPECT_EQ((false || falseBand).ComputeRasterMinMax(false, adfMinMax),
5967 : CE_None);
5968 1 : EXPECT_EQ(adfMinMax[0], false);
5969 :
5970 : // Not
5971 1 : EXPECT_EQ((!trueBand).ComputeRasterMinMax(false, adfMinMax), CE_None);
5972 1 : EXPECT_EQ(adfMinMax[0], false);
5973 :
5974 1 : EXPECT_EQ((!falseBand).ComputeRasterMinMax(false, adfMinMax), CE_None);
5975 1 : EXPECT_EQ(adfMinMax[0], true);
5976 : }
5977 : #endif
5978 :
5979 1 : EXPECT_EQ(firstBand.AsType(GDT_Byte).GetRasterDataType(), GDT_Byte);
5980 2 : EXPECT_THROW(
5981 : CPL_IGNORE_RET_VAL(firstBand.AsType(GDT_Unknown).GetRasterDataType()),
5982 : std::runtime_error);
5983 1 : }
5984 :
5985 4 : TEST_F(test_gdal, GDALRasterBand_window_iterator)
5986 : {
5987 1 : GDALDriver *poDrv = GetGDALDriverManager()->GetDriverByName("GTiff");
5988 1 : if (!poDrv)
5989 : {
5990 0 : GTEST_SKIP() << "GTiff driver missing";
5991 : }
5992 :
5993 1 : std::string tmpFilename = VSIMemGenerateHiddenFilename("tmp.tif");
5994 :
5995 1 : CPLStringList aosOptions;
5996 1 : aosOptions.AddNameValue("TILED", "TRUE");
5997 1 : aosOptions.AddNameValue("BLOCKXSIZE", "512");
5998 1 : aosOptions.AddNameValue("BLOCKYSIZE", "256");
5999 :
6000 : std::unique_ptr<GDALDataset> poDS(poDrv->Create(
6001 1 : tmpFilename.c_str(), 1050, 600, 1, GDT_Byte, aosOptions.List()));
6002 1 : GDALRasterBand *poBand = poDS->GetRasterBand(1);
6003 1 : std::vector<GDALRasterWindow> windows(poBand->IterateWindows().begin(),
6004 2 : poBand->IterateWindows().end());
6005 1 : poDS->MarkSuppressOnClose();
6006 :
6007 1 : ASSERT_EQ(windows.size(), 9);
6008 :
6009 : // top-left
6010 1 : EXPECT_EQ(windows[0].nXOff, 0);
6011 1 : EXPECT_EQ(windows[0].nYOff, 0);
6012 1 : EXPECT_EQ(windows[0].nXSize, 512);
6013 1 : EXPECT_EQ(windows[0].nYSize, 256);
6014 :
6015 : // top-middle
6016 1 : EXPECT_EQ(windows[1].nXOff, 512);
6017 1 : EXPECT_EQ(windows[1].nYOff, 0);
6018 1 : EXPECT_EQ(windows[1].nXSize, 512);
6019 1 : EXPECT_EQ(windows[1].nYSize, 256);
6020 :
6021 : // top-right
6022 1 : EXPECT_EQ(windows[2].nXOff, 1024);
6023 1 : EXPECT_EQ(windows[2].nYOff, 0);
6024 1 : EXPECT_EQ(windows[2].nXSize, 1050 - 1024);
6025 1 : EXPECT_EQ(windows[2].nYSize, 256);
6026 :
6027 : // middle-left
6028 1 : EXPECT_EQ(windows[3].nXOff, 0);
6029 1 : EXPECT_EQ(windows[3].nYOff, 256);
6030 1 : EXPECT_EQ(windows[3].nXSize, 512);
6031 1 : EXPECT_EQ(windows[3].nYSize, 256);
6032 :
6033 : // middle-middle
6034 1 : EXPECT_EQ(windows[4].nXOff, 512);
6035 1 : EXPECT_EQ(windows[4].nYOff, 256);
6036 1 : EXPECT_EQ(windows[4].nXSize, 512);
6037 1 : EXPECT_EQ(windows[4].nYSize, 256);
6038 :
6039 : // middle-right
6040 1 : EXPECT_EQ(windows[5].nXOff, 1024);
6041 1 : EXPECT_EQ(windows[5].nYOff, 256);
6042 1 : EXPECT_EQ(windows[5].nXSize, 1050 - 1024);
6043 1 : EXPECT_EQ(windows[5].nYSize, 256);
6044 :
6045 : // bottom-left
6046 1 : EXPECT_EQ(windows[6].nXOff, 0);
6047 1 : EXPECT_EQ(windows[6].nYOff, 512);
6048 1 : EXPECT_EQ(windows[6].nXSize, 512);
6049 1 : EXPECT_EQ(windows[6].nYSize, 600 - 512);
6050 :
6051 : // bottom-middle
6052 1 : EXPECT_EQ(windows[7].nXOff, 512);
6053 1 : EXPECT_EQ(windows[7].nYOff, 512);
6054 1 : EXPECT_EQ(windows[7].nXSize, 512);
6055 1 : EXPECT_EQ(windows[7].nYSize, 600 - 512);
6056 :
6057 : // bottom-right
6058 1 : EXPECT_EQ(windows[8].nXOff, 1024);
6059 1 : EXPECT_EQ(windows[8].nYOff, 512);
6060 1 : EXPECT_EQ(windows[8].nXSize, 1050 - 1024);
6061 1 : EXPECT_EQ(windows[8].nYSize, 600 - 512);
6062 : }
6063 :
6064 : } // namespace
|