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