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