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