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