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