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