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 : * Permission is hereby granted, free of charge, to any person obtaining a
11 : * copy of this software and associated documentation files (the "Software"),
12 : * to deal in the Software without restriction, including without limitation
13 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 : * and/or sell copies of the Software, and to permit persons to whom the
15 : * Software is furnished to do so, subject to the following conditions:
16 : *
17 : * The above copyright notice and this permission notice shall be included
18 : * in all copies or substantial portions of the Software.
19 : *
20 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 : * DEALINGS IN THE SOFTWARE.
27 : ****************************************************************************/
28 :
29 : #include "gdal_unit_test.h"
30 :
31 : #include "gdal_alg.h"
32 : #include "gdal_priv.h"
33 : #include "gdal_utils.h"
34 : #include "gdal_priv_templates.hpp"
35 : #include "gdal.h"
36 : #include "tilematrixset.hpp"
37 : #include "gdalcachedpixelaccessor.h"
38 :
39 : #include <limits>
40 : #include <string>
41 :
42 : #include "test_data.h"
43 :
44 : #include "gtest_include.h"
45 :
46 : namespace
47 : {
48 : // Common fixture with test data
49 : struct test_gdal : public ::testing::Test
50 : {
51 : };
52 :
53 : // Test GDAL driver manager access
54 4 : TEST_F(test_gdal, driver_manager)
55 : {
56 1 : GDALDriverManager *drv_mgr = nullptr;
57 1 : drv_mgr = GetGDALDriverManager();
58 1 : ASSERT_TRUE(nullptr != drv_mgr);
59 : }
60 :
61 : // Test that GDALRegisterPlugins can be called
62 4 : TEST_F(test_gdal, register_plugins)
63 : {
64 1 : GDALRegisterPlugins();
65 1 : }
66 :
67 : // Test that GDALRegisterPlugin can be called and returns an error for a non
68 : // existing plugin name
69 4 : TEST_F(test_gdal, register_plugin)
70 : {
71 1 : ASSERT_EQ(GDALRegisterPlugin("rtbreg_non_existing_plugin"), CE_Failure);
72 : }
73 :
74 : // Test number of registered GDAL drivers
75 4 : TEST_F(test_gdal, number_of_registered_drivers)
76 : {
77 : #ifdef WIN32CE
78 : ASSERT_EQ(GDALGetDriverCount(), drv_count_);
79 : #endif
80 1 : }
81 :
82 : // Test if AAIGrid driver is registered
83 4 : TEST_F(test_gdal, aaigrid_is_registered)
84 : {
85 1 : GDALDriverH drv = GDALGetDriverByName("AAIGrid");
86 :
87 : #ifdef FRMT_aaigrid
88 : ASSERT_TRUE(NULL != drv);
89 : #else
90 : (void)drv;
91 : #endif
92 1 : }
93 :
94 : // Test if DTED driver is registered
95 4 : TEST_F(test_gdal, dted_is_registered)
96 : {
97 1 : GDALDriverH drv = GDALGetDriverByName("DTED");
98 :
99 : #ifdef FRMT_dted
100 : ASSERT_TRUE(NULL != drv);
101 : #else
102 : (void)drv;
103 : #endif
104 1 : }
105 :
106 : // Test if GeoTIFF driver is registered
107 4 : TEST_F(test_gdal, gtiff_is_registered)
108 : {
109 1 : GDALDriverH drv = GDALGetDriverByName("GTiff");
110 :
111 : #ifdef FRMT_gtiff
112 : ASSERT_TRUE(NULL != drv);
113 : #else
114 : (void)drv;
115 : #endif
116 1 : }
117 :
118 : class DataTypeTupleFixture : public test_gdal,
119 : public ::testing::WithParamInterface<
120 : std::tuple<GDALDataType, GDALDataType>>
121 : {
122 : public:
123 1 : static std::vector<std::tuple<GDALDataType, GDALDataType>> GetTupleValues()
124 : {
125 1 : std::vector<std::tuple<GDALDataType, GDALDataType>> ret;
126 15 : for (GDALDataType eIn = GDT_Byte; eIn < GDT_TypeCount;
127 14 : eIn = static_cast<GDALDataType>(eIn + 1))
128 : {
129 210 : for (GDALDataType eOut = GDT_Byte; eOut < GDT_TypeCount;
130 196 : eOut = static_cast<GDALDataType>(eOut + 1))
131 : {
132 196 : ret.emplace_back(std::make_tuple(eIn, eOut));
133 : }
134 : }
135 1 : return ret;
136 : }
137 : };
138 :
139 : // Test GDALDataTypeUnion() on all (GDALDataType, GDALDataType) combinations
140 393 : TEST_P(DataTypeTupleFixture, GDALDataTypeUnion_generic)
141 : {
142 196 : GDALDataType eDT1 = std::get<0>(GetParam());
143 196 : GDALDataType eDT2 = std::get<1>(GetParam());
144 196 : GDALDataType eDT = GDALDataTypeUnion(eDT1, eDT2);
145 196 : EXPECT_EQ(eDT, GDALDataTypeUnion(eDT2, eDT1));
146 196 : EXPECT_GE(GDALGetDataTypeSize(eDT), GDALGetDataTypeSize(eDT1));
147 196 : EXPECT_GE(GDALGetDataTypeSize(eDT), GDALGetDataTypeSize(eDT2));
148 196 : EXPECT_TRUE((GDALDataTypeIsComplex(eDT) && (GDALDataTypeIsComplex(eDT1) ||
149 : GDALDataTypeIsComplex(eDT2))) ||
150 : (!GDALDataTypeIsComplex(eDT) && !GDALDataTypeIsComplex(eDT1) &&
151 : !GDALDataTypeIsComplex(eDT2)));
152 :
153 196 : EXPECT_TRUE(
154 : !(GDALDataTypeIsFloating(eDT1) || GDALDataTypeIsFloating(eDT2)) ||
155 : GDALDataTypeIsFloating(eDT));
156 196 : EXPECT_TRUE(!(GDALDataTypeIsSigned(eDT1) || GDALDataTypeIsSigned(eDT2)) ||
157 : GDALDataTypeIsSigned(eDT));
158 196 : }
159 :
160 590 : INSTANTIATE_TEST_SUITE_P(
161 : test_gdal, DataTypeTupleFixture,
162 : ::testing::ValuesIn(DataTypeTupleFixture::GetTupleValues()),
163 : [](const ::testing::TestParamInfo<DataTypeTupleFixture::ParamType> &l_info)
164 : {
165 : GDALDataType eDT1 = std::get<0>(l_info.param);
166 : GDALDataType eDT2 = std::get<1>(l_info.param);
167 : return std::string(GDALGetDataTypeName(eDT1)) + "_" +
168 : GDALGetDataTypeName(eDT2);
169 : });
170 :
171 : // Test GDALDataTypeUnion()
172 4 : TEST_F(test_gdal, GDALDataTypeUnion_special_cases)
173 : {
174 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Int16, GDT_UInt16), GDT_Int32);
175 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Int16, GDT_UInt32), GDT_Int64);
176 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_UInt32, GDT_Int16), GDT_Int64);
177 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Int64, GDT_UInt64), GDT_Float64);
178 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Int64, GDT_Float32), GDT_Float64);
179 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_Int64, GDT_Float64), 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_Float32, GDT_CInt32), GDT_CFloat64);
184 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt16, GDT_UInt32), GDT_CFloat64);
185 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt16, GDT_CFloat32), GDT_CFloat32);
186 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_Byte), GDT_CInt32);
187 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_UInt16), GDT_CInt32);
188 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_Int16), GDT_CInt32);
189 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_UInt32), GDT_CFloat64);
190 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_Int32), GDT_CInt32);
191 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_Float32), GDT_CFloat64);
192 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_CInt16), GDT_CInt32);
193 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CInt32, GDT_CFloat32), GDT_CFloat64);
194 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_Byte), GDT_CFloat32);
195 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_UInt16), GDT_CFloat32);
196 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_Int16), GDT_CFloat32);
197 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_UInt32), GDT_CFloat64);
198 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_Int32), GDT_CFloat64);
199 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_Float32), GDT_CFloat32);
200 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_CInt16), GDT_CFloat32);
201 1 : EXPECT_EQ(GDALDataTypeUnion(GDT_CFloat32, GDT_CInt32), GDT_CFloat64);
202 :
203 1 : EXPECT_EQ(GDALFindDataType(0, false /* signed */, false /* floating */,
204 : false /* complex */),
205 : GDT_Byte);
206 1 : EXPECT_EQ(GDALFindDataType(0, true /* signed */, false /* floating */,
207 : false /* complex */),
208 : GDT_Int8);
209 1 : EXPECT_EQ(GDALFindDataType(0, false /* signed */, false /* floating */,
210 : true /* complex */),
211 : GDT_CInt32);
212 1 : EXPECT_EQ(GDALFindDataType(0, true /* signed */, false /* floating */,
213 : true /* complex */),
214 : GDT_CInt16);
215 1 : EXPECT_EQ(GDALFindDataType(0, false /* signed */, true /* floating */,
216 : false /* complex */),
217 : GDT_Float32);
218 1 : EXPECT_EQ(GDALFindDataType(0, true /* signed */, true /* floating */,
219 : false /* complex */),
220 : GDT_Float32);
221 1 : EXPECT_EQ(GDALFindDataType(0, false /* signed */, true /* floating */,
222 : true /* complex */),
223 : GDT_CFloat32);
224 1 : EXPECT_EQ(GDALFindDataType(0, true /* signed */, true /* floating */,
225 : true /* complex */),
226 : GDT_CFloat32);
227 :
228 1 : EXPECT_EQ(GDALFindDataType(8, false /* signed */, false /* floating */,
229 : false /* complex */),
230 : GDT_Byte);
231 1 : EXPECT_EQ(GDALFindDataType(8, true /* signed */, false /* floating */,
232 : false /* complex */),
233 : GDT_Int8);
234 :
235 1 : EXPECT_EQ(GDALFindDataType(16, false /* signed */, false /* floating */,
236 : false /* complex */),
237 : GDT_UInt16);
238 1 : EXPECT_EQ(GDALFindDataType(16, true /* signed */, false /* floating */,
239 : false /* complex */),
240 : GDT_Int16);
241 :
242 1 : EXPECT_EQ(GDALFindDataType(32, false /* signed */, false /* floating */,
243 : false /* complex */),
244 : GDT_UInt32);
245 1 : EXPECT_EQ(GDALFindDataType(32, true /* signed */, false /* floating */,
246 : false /* complex */),
247 : GDT_Int32);
248 :
249 1 : EXPECT_EQ(GDALFindDataType(64, false /* signed */, true /* floating */,
250 : false /* complex */),
251 : GDT_Float64);
252 1 : EXPECT_EQ(GDALFindDataType(64, false /* signed */, true /* floating */,
253 : true /* complex */),
254 : GDT_CFloat64);
255 :
256 1 : EXPECT_EQ(GDALFindDataType(64, false /* signed */, false /* floating */,
257 : false /* complex */),
258 : GDT_UInt64);
259 1 : EXPECT_EQ(GDALFindDataType(64, true /* signed */, false /* floating */,
260 : false /* complex */),
261 : GDT_Int64);
262 :
263 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Byte, -128, 0), GDT_Int16);
264 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Byte, -32768, 0), GDT_Int16);
265 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Byte, -32769, 0), GDT_Int32);
266 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Float32, -99999, 0), GDT_Float32);
267 1 : EXPECT_EQ(GDALDataTypeUnionWithValue(GDT_Float32, -99999.9876, 0),
268 : GDT_Float64);
269 1 : }
270 :
271 : // Test GDALAdjustValueToDataType()
272 4 : TEST_F(test_gdal, GDALAdjustValueToDataType)
273 : {
274 : int bClamped, bRounded;
275 :
276 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Byte, 255.0, nullptr, nullptr) ==
277 : 255.0);
278 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Byte, 255.0, &bClamped,
279 : &bRounded) == 255.0 &&
280 : !bClamped && !bRounded);
281 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Byte, 254.4, &bClamped,
282 : &bRounded) == 254.0 &&
283 : !bClamped && bRounded);
284 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Byte, -1, &bClamped, &bRounded) ==
285 : 0.0 &&
286 : bClamped && !bRounded);
287 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Byte, 256.0, &bClamped,
288 : &bRounded) == 255.0 &&
289 : bClamped && !bRounded);
290 :
291 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int8, -128.0, &bClamped,
292 : &bRounded) == -128.0 &&
293 : !bClamped && !bRounded);
294 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int8, 127.0, &bClamped,
295 : &bRounded) == 127.0 &&
296 : !bClamped && !bRounded);
297 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int8, -127.4, &bClamped,
298 : &bRounded) == -127.0 &&
299 : !bClamped && bRounded);
300 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int8, 126.4, &bClamped,
301 : &bRounded) == 126.0 &&
302 : !bClamped && bRounded);
303 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int8, -129.0, &bClamped,
304 : &bRounded) == -128.0 &&
305 : bClamped && !bRounded);
306 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int8, 128.0, &bClamped,
307 : &bRounded) == 127.0 &&
308 : bClamped && !bRounded);
309 :
310 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt16, 65535.0, &bClamped,
311 : &bRounded) == 65535.0 &&
312 : !bClamped && !bRounded);
313 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt16, 65534.4, &bClamped,
314 : &bRounded) == 65534.0 &&
315 : !bClamped && bRounded);
316 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt16, -1, &bClamped,
317 : &bRounded) == 0.0 &&
318 : bClamped && !bRounded);
319 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt16, 65536.0, &bClamped,
320 : &bRounded) == 65535.0 &&
321 : bClamped && !bRounded);
322 :
323 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int16, -32768.0, &bClamped,
324 : &bRounded) == -32768.0 &&
325 : !bClamped && !bRounded);
326 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int16, 32767.0, &bClamped,
327 : &bRounded) == 32767.0 &&
328 : !bClamped && !bRounded);
329 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int16, -32767.4, &bClamped,
330 : &bRounded) == -32767.0 &&
331 : !bClamped && bRounded);
332 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int16, 32766.4, &bClamped,
333 : &bRounded) == 32766.0 &&
334 : !bClamped && bRounded);
335 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int16, -32769.0, &bClamped,
336 : &bRounded) == -32768.0 &&
337 : bClamped && !bRounded);
338 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int16, 32768.0, &bClamped,
339 : &bRounded) == 32767.0 &&
340 : bClamped && !bRounded);
341 :
342 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt32, 10000000.0, &bClamped,
343 : &bRounded) == 10000000.0 &&
344 : !bClamped && !bRounded);
345 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt32, 10000000.4, &bClamped,
346 : &bRounded) == 10000000.0 &&
347 : !bClamped && bRounded);
348 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt32, -1, &bClamped,
349 : &bRounded) == 0.0 &&
350 : bClamped && !bRounded);
351 :
352 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int32, -10000000.0, &bClamped,
353 : &bRounded) == -10000000.0 &&
354 : !bClamped && !bRounded);
355 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int32, 10000000.0, &bClamped,
356 : &bRounded) == 10000000.0 &&
357 : !bClamped && !bRounded);
358 :
359 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt64, 10000000000.0, &bClamped,
360 : &bRounded) == 10000000000.0 &&
361 : !bClamped && !bRounded);
362 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt64, 10000000000.4, &bClamped,
363 : &bRounded) == 10000000000.0 &&
364 : !bClamped && bRounded);
365 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_UInt64, -1, &bClamped,
366 : &bRounded) == 0.0 &&
367 : bClamped && !bRounded);
368 :
369 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int64, -10000000000.0, &bClamped,
370 : &bRounded) == -10000000000.0 &&
371 : !bClamped && !bRounded);
372 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Int64, 10000000000.0, &bClamped,
373 : &bRounded) == 10000000000.0 &&
374 : !bClamped && !bRounded);
375 :
376 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float32, 0.0, &bClamped,
377 : &bRounded) == 0.0 &&
378 : !bClamped && !bRounded);
379 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float32, 1e-50, &bClamped,
380 : &bRounded) == 0.0 &&
381 : !bClamped && !bRounded);
382 1 : EXPECT_TRUE(
383 : GDALAdjustValueToDataType(GDT_Float32, 1.23, &bClamped, &bRounded) ==
384 : static_cast<double>(1.23f) &&
385 : !bClamped && !bRounded);
386 1 : EXPECT_TRUE(
387 : GDALAdjustValueToDataType(GDT_Float32, -1e300, &bClamped, &bRounded) ==
388 : -std::numeric_limits<float>::max() &&
389 : bClamped && !bRounded);
390 1 : EXPECT_TRUE(
391 : GDALAdjustValueToDataType(GDT_Float32, 1e300, &bClamped, &bRounded) ==
392 : std::numeric_limits<float>::max() &&
393 : bClamped && !bRounded);
394 1 : EXPECT_TRUE(GDALAdjustValueToDataType(
395 : GDT_Float32, std::numeric_limits<float>::infinity(),
396 : &bClamped,
397 : &bRounded) == std::numeric_limits<float>::infinity() &&
398 : !bClamped && !bRounded);
399 1 : EXPECT_TRUE(GDALAdjustValueToDataType(
400 : GDT_Float32, -std::numeric_limits<float>::infinity(),
401 : &bClamped,
402 : &bRounded) == -std::numeric_limits<float>::infinity() &&
403 : !bClamped && !bRounded);
404 : {
405 1 : double dfNan = std::numeric_limits<double>::quiet_NaN();
406 : double dfGot =
407 1 : GDALAdjustValueToDataType(GDT_Float32, dfNan, &bClamped, &bRounded);
408 1 : EXPECT_TRUE(memcmp(&dfNan, &dfGot, sizeof(double)) == 0 && !bClamped &&
409 : !bRounded);
410 : }
411 :
412 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float64, 0.0, &bClamped,
413 : &bRounded) == 0.0 &&
414 : !bClamped && !bRounded);
415 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float64, 1e-50, &bClamped,
416 : &bRounded) == 1e-50 &&
417 : !bClamped && !bRounded);
418 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float64, -1e40, &bClamped,
419 : &bRounded) == -1e40 &&
420 : !bClamped && !bRounded);
421 1 : EXPECT_TRUE(GDALAdjustValueToDataType(GDT_Float64, 1e40, &bClamped,
422 : &bRounded) == 1e40 &&
423 : !bClamped && !bRounded);
424 1 : EXPECT_TRUE(GDALAdjustValueToDataType(
425 : GDT_Float64, std::numeric_limits<float>::infinity(),
426 : &bClamped,
427 : &bRounded) == std::numeric_limits<float>::infinity() &&
428 : !bClamped && !bRounded);
429 1 : EXPECT_TRUE(GDALAdjustValueToDataType(
430 : GDT_Float64, -std::numeric_limits<float>::infinity(),
431 : &bClamped,
432 : &bRounded) == -std::numeric_limits<float>::infinity() &&
433 : !bClamped && !bRounded);
434 : {
435 1 : double dfNan = std::numeric_limits<double>::quiet_NaN();
436 : double dfGot =
437 1 : GDALAdjustValueToDataType(GDT_Float64, dfNan, &bClamped, &bRounded);
438 1 : EXPECT_TRUE(memcmp(&dfNan, &dfGot, sizeof(double)) == 0 && !bClamped &&
439 : !bRounded);
440 : }
441 1 : }
442 :
443 : class FakeBand : public GDALRasterBand
444 : {
445 : protected:
446 0 : virtual CPLErr IReadBlock(int, int, void *) override
447 : {
448 0 : return CE_None;
449 : }
450 :
451 1 : virtual CPLErr IWriteBlock(int, int, void *) override
452 : {
453 1 : return CE_None;
454 : }
455 :
456 : public:
457 1 : FakeBand(int nXSize, int nYSize)
458 1 : {
459 1 : nBlockXSize = nXSize;
460 1 : nBlockYSize = nYSize;
461 1 : }
462 : };
463 :
464 : class DatasetWithErrorInFlushCache : public GDALDataset
465 : {
466 : bool bHasFlushCache;
467 :
468 : public:
469 2 : DatasetWithErrorInFlushCache() : bHasFlushCache(false)
470 : {
471 2 : }
472 :
473 4 : ~DatasetWithErrorInFlushCache()
474 2 : {
475 2 : FlushCache(true);
476 4 : }
477 :
478 4 : virtual CPLErr FlushCache(bool bAtClosing) override
479 : {
480 4 : CPLErr eErr = CE_None;
481 4 : if (!bHasFlushCache)
482 : {
483 2 : CPLError(CE_Failure, CPLE_AppDefined, "some error");
484 2 : eErr = CE_Failure;
485 : }
486 4 : if (GDALDataset::FlushCache(bAtClosing) != CE_None)
487 0 : eErr = CE_Failure;
488 4 : bHasFlushCache = true;
489 4 : return eErr;
490 : }
491 :
492 1 : CPLErr SetSpatialRef(const OGRSpatialReference *) override
493 : {
494 1 : return CE_None;
495 : }
496 :
497 1 : virtual CPLErr SetGeoTransform(double *) override
498 : {
499 1 : return CE_None;
500 : }
501 :
502 1 : static GDALDataset *CreateCopy(const char *, GDALDataset *, int, char **,
503 : GDALProgressFunc, void *)
504 : {
505 1 : return new DatasetWithErrorInFlushCache();
506 : }
507 :
508 1 : static GDALDataset *Create(const char *, int nXSize, int nYSize, int,
509 : GDALDataType, char **)
510 : {
511 1 : DatasetWithErrorInFlushCache *poDS = new DatasetWithErrorInFlushCache();
512 1 : poDS->eAccess = GA_Update;
513 1 : poDS->nRasterXSize = nXSize;
514 1 : poDS->nRasterYSize = nYSize;
515 1 : poDS->SetBand(1, new FakeBand(nXSize, nYSize));
516 1 : return poDS;
517 : }
518 : };
519 :
520 : // Test that GDALTranslate() detects error in flush cache
521 4 : TEST_F(test_gdal, GDALTranslate_error_flush_cache)
522 : {
523 1 : GDALDriver *poDriver = new GDALDriver();
524 1 : poDriver->SetDescription("DatasetWithErrorInFlushCache");
525 1 : poDriver->pfnCreateCopy = DatasetWithErrorInFlushCache::CreateCopy;
526 1 : GetGDALDriverManager()->RegisterDriver(poDriver);
527 1 : const char *args[] = {"-of", "DatasetWithErrorInFlushCache", nullptr};
528 : GDALTranslateOptions *psOptions =
529 1 : GDALTranslateOptionsNew((char **)args, nullptr);
530 1 : GDALDatasetH hSrcDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
531 1 : CPLErrorReset();
532 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
533 1 : GDALDatasetH hOutDS = GDALTranslate("", hSrcDS, psOptions, nullptr);
534 1 : CPLPopErrorHandler();
535 1 : GDALClose(hSrcDS);
536 1 : GDALTranslateOptionsFree(psOptions);
537 1 : EXPECT_TRUE(hOutDS == nullptr);
538 1 : EXPECT_TRUE(CPLGetLastErrorType() != CE_None);
539 1 : GetGDALDriverManager()->DeregisterDriver(poDriver);
540 1 : delete poDriver;
541 1 : }
542 :
543 : // Test that GDALWarp() detects error in flush cache
544 4 : TEST_F(test_gdal, GDALWarp_error_flush_cache)
545 : {
546 1 : GDALDriver *poDriver = new GDALDriver();
547 1 : poDriver->SetDescription("DatasetWithErrorInFlushCache");
548 1 : poDriver->pfnCreate = DatasetWithErrorInFlushCache::Create;
549 1 : GetGDALDriverManager()->RegisterDriver(poDriver);
550 1 : const char *args[] = {"-of", "DatasetWithErrorInFlushCache", nullptr};
551 : GDALWarpAppOptions *psOptions =
552 1 : GDALWarpAppOptionsNew((char **)args, nullptr);
553 1 : GDALDatasetH hSrcDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
554 1 : CPLErrorReset();
555 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
556 : GDALDatasetH hOutDS =
557 1 : GDALWarp("/", nullptr, 1, &hSrcDS, psOptions, nullptr);
558 1 : CPLPopErrorHandler();
559 1 : GDALClose(hSrcDS);
560 1 : GDALWarpAppOptionsFree(psOptions);
561 1 : EXPECT_TRUE(hOutDS == nullptr);
562 1 : EXPECT_TRUE(CPLGetLastErrorType() != CE_None);
563 1 : GetGDALDriverManager()->DeregisterDriver(poDriver);
564 1 : delete poDriver;
565 1 : }
566 :
567 : // Test GDALWarp() to VRT and that we can call GDALReleaseDataset() on the
568 : // source dataset when we want.
569 4 : TEST_F(test_gdal, GDALWarp_VRT)
570 : {
571 1 : const char *args[] = {"-of", "VRT", nullptr};
572 : GDALWarpAppOptions *psOptions =
573 1 : GDALWarpAppOptionsNew((char **)args, nullptr);
574 1 : GDALDatasetH hSrcDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
575 1 : GDALDatasetH hOutDS = GDALWarp("", nullptr, 1, &hSrcDS, psOptions, nullptr);
576 1 : GDALWarpAppOptionsFree(psOptions);
577 1 : GDALReleaseDataset(hSrcDS);
578 1 : EXPECT_EQ(GDALChecksumImage(GDALGetRasterBand(hOutDS, 1), 0, 0, 20, 20),
579 : 4672);
580 1 : GDALReleaseDataset(hOutDS);
581 1 : }
582 :
583 : // Test GDALTranslate() to VRT and that we can call GDALReleaseDataset() on the
584 : // source dataset when we want.
585 4 : TEST_F(test_gdal, GDALTranslate_VRT)
586 : {
587 1 : const char *args[] = {"-of", "VRT", nullptr};
588 : GDALTranslateOptions *psOptions =
589 1 : GDALTranslateOptionsNew((char **)args, nullptr);
590 1 : GDALDatasetH hSrcDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
591 1 : GDALDatasetH hOutDS = GDALTranslate("", hSrcDS, psOptions, nullptr);
592 1 : GDALTranslateOptionsFree(psOptions);
593 1 : GDALReleaseDataset(hSrcDS);
594 1 : EXPECT_EQ(GDALChecksumImage(GDALGetRasterBand(hOutDS, 1), 0, 0, 20, 20),
595 : 4672);
596 1 : GDALReleaseDataset(hOutDS);
597 1 : }
598 :
599 : // Test GDALBuildVRT() and that we can call GDALReleaseDataset() on the
600 : // source dataset when we want.
601 4 : TEST_F(test_gdal, GDALBuildVRT)
602 : {
603 1 : GDALDatasetH hSrcDS = GDALOpen(GCORE_DATA_DIR "byte.tif", GA_ReadOnly);
604 : GDALDatasetH hOutDS =
605 1 : GDALBuildVRT("", 1, &hSrcDS, nullptr, nullptr, nullptr);
606 1 : GDALReleaseDataset(hSrcDS);
607 1 : EXPECT_EQ(GDALChecksumImage(GDALGetRasterBand(hOutDS, 1), 0, 0, 20, 20),
608 : 4672);
609 1 : GDALReleaseDataset(hOutDS);
610 1 : }
611 :
612 : // Test that GDALSwapWords() with unaligned buffers
613 4 : TEST_F(test_gdal, GDALSwapWords_unaligned_buffers)
614 : {
615 1 : GByte abyBuffer[8 * 2 + 1] = {0, 1, 2, 3, 4, 5, 6, 7, 255,
616 : 7, 6, 5, 4, 3, 2, 1, 0};
617 1 : GDALSwapWords(abyBuffer, 4, 2, 9);
618 1 : EXPECT_EQ(abyBuffer[0], 3);
619 1 : EXPECT_EQ(abyBuffer[1], 2);
620 1 : EXPECT_EQ(abyBuffer[2], 1);
621 1 : EXPECT_EQ(abyBuffer[3], 0);
622 :
623 1 : EXPECT_EQ(abyBuffer[9], 4);
624 1 : EXPECT_EQ(abyBuffer[10], 5);
625 1 : EXPECT_EQ(abyBuffer[11], 6);
626 1 : EXPECT_EQ(abyBuffer[12], 7);
627 1 : GDALSwapWords(abyBuffer, 4, 2, 9);
628 :
629 1 : GDALSwapWords(abyBuffer, 8, 2, 9);
630 1 : EXPECT_EQ(abyBuffer[0], 7);
631 1 : EXPECT_EQ(abyBuffer[1], 6);
632 1 : EXPECT_EQ(abyBuffer[2], 5);
633 1 : EXPECT_EQ(abyBuffer[3], 4);
634 1 : EXPECT_EQ(abyBuffer[4], 3);
635 1 : EXPECT_EQ(abyBuffer[5], 2);
636 1 : EXPECT_EQ(abyBuffer[6], 1);
637 1 : EXPECT_EQ(abyBuffer[7], 0);
638 :
639 1 : EXPECT_EQ(abyBuffer[9], 0);
640 1 : EXPECT_EQ(abyBuffer[10], 1);
641 1 : EXPECT_EQ(abyBuffer[11], 2);
642 1 : EXPECT_EQ(abyBuffer[12], 3);
643 1 : EXPECT_EQ(abyBuffer[13], 4);
644 1 : EXPECT_EQ(abyBuffer[14], 5);
645 1 : EXPECT_EQ(abyBuffer[15], 6);
646 1 : EXPECT_EQ(abyBuffer[16], 7);
647 1 : GDALSwapWords(abyBuffer, 4, 2, 9);
648 1 : }
649 :
650 : // Test ARE_REAL_EQUAL()
651 4 : TEST_F(test_gdal, ARE_REAL_EQUAL)
652 : {
653 1 : EXPECT_TRUE(ARE_REAL_EQUAL(0.0, 0.0));
654 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(0.0, 0.1));
655 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(0.1, 0.0));
656 1 : EXPECT_TRUE(ARE_REAL_EQUAL(1.0, 1.0));
657 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(1.0, 0.99));
658 1 : EXPECT_TRUE(ARE_REAL_EQUAL(-std::numeric_limits<double>::min(),
659 : -std::numeric_limits<double>::min()));
660 1 : EXPECT_TRUE(ARE_REAL_EQUAL(std::numeric_limits<double>::min(),
661 : std::numeric_limits<double>::min()));
662 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(std::numeric_limits<double>::min(), 0.0));
663 1 : EXPECT_TRUE(ARE_REAL_EQUAL(-std::numeric_limits<double>::max(),
664 : -std::numeric_limits<double>::max()));
665 1 : EXPECT_TRUE(ARE_REAL_EQUAL(std::numeric_limits<double>::max(),
666 : std::numeric_limits<double>::max()));
667 1 : EXPECT_TRUE(ARE_REAL_EQUAL(-std::numeric_limits<double>::infinity(),
668 : -std::numeric_limits<double>::infinity()));
669 1 : EXPECT_TRUE(ARE_REAL_EQUAL(std::numeric_limits<double>::infinity(),
670 : std::numeric_limits<double>::infinity()));
671 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(std::numeric_limits<double>::infinity(),
672 : std::numeric_limits<double>::max()));
673 1 : EXPECT_TRUE(ARE_REAL_EQUAL(-std::numeric_limits<double>::min(),
674 : -std::numeric_limits<double>::min()));
675 :
676 1 : EXPECT_TRUE(ARE_REAL_EQUAL(0.0f, 0.0f));
677 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(0.0f, 0.1f));
678 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(0.1f, 0.0f));
679 1 : EXPECT_TRUE(ARE_REAL_EQUAL(1.0f, 1.0f));
680 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(1.0f, 0.99f));
681 1 : EXPECT_TRUE(ARE_REAL_EQUAL(-std::numeric_limits<float>::min(),
682 : -std::numeric_limits<float>::min()));
683 1 : EXPECT_TRUE(ARE_REAL_EQUAL(std::numeric_limits<float>::min(),
684 : std::numeric_limits<float>::min()));
685 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(std::numeric_limits<float>::min(), 0.0f));
686 1 : EXPECT_TRUE(ARE_REAL_EQUAL(-std::numeric_limits<float>::max(),
687 : -std::numeric_limits<float>::max()));
688 1 : EXPECT_TRUE(ARE_REAL_EQUAL(std::numeric_limits<float>::max(),
689 : std::numeric_limits<float>::max()));
690 1 : EXPECT_TRUE(ARE_REAL_EQUAL(-std::numeric_limits<float>::infinity(),
691 : -std::numeric_limits<float>::infinity()));
692 1 : EXPECT_TRUE(ARE_REAL_EQUAL(std::numeric_limits<float>::infinity(),
693 : std::numeric_limits<float>::infinity()));
694 1 : EXPECT_TRUE(!ARE_REAL_EQUAL(std::numeric_limits<float>::infinity(),
695 : std::numeric_limits<float>::max()));
696 1 : }
697 :
698 : // Test GDALIsValueInRange()
699 4 : TEST_F(test_gdal, GDALIsValueInRange)
700 : {
701 1 : EXPECT_TRUE(GDALIsValueInRange<GByte>(0));
702 1 : EXPECT_TRUE(GDALIsValueInRange<GByte>(255));
703 1 : EXPECT_TRUE(!GDALIsValueInRange<GByte>(-1));
704 1 : EXPECT_TRUE(!GDALIsValueInRange<GByte>(256));
705 1 : EXPECT_TRUE(GDALIsValueInRange<GInt8>(-128));
706 1 : EXPECT_TRUE(GDALIsValueInRange<GInt8>(127));
707 1 : EXPECT_TRUE(!GDALIsValueInRange<GInt8>(-129));
708 1 : EXPECT_TRUE(!GDALIsValueInRange<GInt8>(128));
709 1 : EXPECT_TRUE(GDALIsValueInRange<float>(std::numeric_limits<float>::max()));
710 1 : EXPECT_TRUE(
711 : GDALIsValueInRange<float>(std::numeric_limits<float>::infinity()));
712 1 : EXPECT_TRUE(!GDALIsValueInRange<float>(std::numeric_limits<double>::max()));
713 1 : EXPECT_TRUE(
714 : GDALIsValueInRange<double>(std::numeric_limits<double>::infinity()));
715 1 : EXPECT_TRUE(!GDALIsValueInRange<double>(CPLAtof("nan")));
716 1 : EXPECT_TRUE(!GDALIsValueInRange<float>(CPLAtof("nan")));
717 1 : EXPECT_TRUE(!GDALIsValueInRange<GByte>(CPLAtof("nan")));
718 1 : }
719 :
720 : // Test GDALDataTypeIsInteger()
721 4 : TEST_F(test_gdal, GDALDataTypeIsInteger)
722 : {
723 1 : EXPECT_TRUE(!GDALDataTypeIsInteger(GDT_Unknown));
724 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_Byte), TRUE);
725 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_Int8), TRUE);
726 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_UInt16), TRUE);
727 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_Int16), TRUE);
728 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_UInt32), TRUE);
729 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_Int32), TRUE);
730 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_UInt64), TRUE);
731 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_Int64), TRUE);
732 1 : EXPECT_TRUE(!GDALDataTypeIsInteger(GDT_Float32));
733 1 : EXPECT_TRUE(!GDALDataTypeIsInteger(GDT_Float64));
734 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_CInt16), TRUE);
735 1 : EXPECT_EQ(GDALDataTypeIsInteger(GDT_CInt32), TRUE);
736 1 : EXPECT_TRUE(!GDALDataTypeIsInteger(GDT_CFloat32));
737 1 : EXPECT_TRUE(!GDALDataTypeIsInteger(GDT_CFloat64));
738 1 : }
739 :
740 : // Test GDALDataTypeIsFloating()
741 4 : TEST_F(test_gdal, GDALDataTypeIsFloating)
742 : {
743 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_Unknown));
744 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_Byte));
745 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_Int8));
746 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_UInt16));
747 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_Int16));
748 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_UInt32));
749 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_Int32));
750 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_UInt64));
751 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_Int64));
752 1 : EXPECT_EQ(GDALDataTypeIsFloating(GDT_Float32), TRUE);
753 1 : EXPECT_EQ(GDALDataTypeIsFloating(GDT_Float64), TRUE);
754 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_CInt16));
755 1 : EXPECT_TRUE(!GDALDataTypeIsFloating(GDT_CInt32));
756 1 : EXPECT_EQ(GDALDataTypeIsFloating(GDT_CFloat32), TRUE);
757 1 : EXPECT_EQ(GDALDataTypeIsFloating(GDT_CFloat64), TRUE);
758 1 : }
759 :
760 : // Test GDALDataTypeIsComplex()
761 4 : TEST_F(test_gdal, GDALDataTypeIsComplex)
762 : {
763 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Unknown));
764 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Byte));
765 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Int8));
766 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_UInt16));
767 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Int16));
768 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_UInt32));
769 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Int32));
770 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_UInt64));
771 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Int64));
772 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Float32));
773 1 : EXPECT_TRUE(!GDALDataTypeIsComplex(GDT_Float64));
774 1 : EXPECT_EQ(GDALDataTypeIsComplex(GDT_CInt16), TRUE);
775 1 : EXPECT_EQ(GDALDataTypeIsComplex(GDT_CInt32), TRUE);
776 1 : EXPECT_EQ(GDALDataTypeIsComplex(GDT_CFloat32), TRUE);
777 1 : EXPECT_EQ(GDALDataTypeIsComplex(GDT_CFloat64), TRUE);
778 1 : }
779 :
780 : // Test GDALDataTypeIsConversionLossy()
781 4 : TEST_F(test_gdal, GDALDataTypeIsConversionLossy)
782 : {
783 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_Byte));
784 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Byte, GDT_Int8));
785 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_UInt16));
786 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_Int16));
787 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_UInt32));
788 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_Int32));
789 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_UInt64));
790 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_Int64));
791 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_Float32));
792 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_Float64));
793 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_CInt16));
794 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_CInt32));
795 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_CFloat32));
796 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Byte, GDT_CFloat64));
797 :
798 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int8, GDT_Byte));
799 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_Int8));
800 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int8, GDT_UInt16));
801 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_Int16));
802 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int8, GDT_UInt32));
803 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_Int32));
804 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int8, GDT_UInt64));
805 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_Int64));
806 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_Float32));
807 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_Float64));
808 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_CInt16));
809 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_CInt32));
810 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_CFloat32));
811 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int8, GDT_CFloat64));
812 :
813 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_Byte));
814 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_Int8));
815 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_UInt16));
816 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_Int16));
817 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_UInt32));
818 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_Int32));
819 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_UInt64));
820 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_Int64));
821 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_Float32));
822 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_Float64));
823 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_CInt16));
824 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_CInt32));
825 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_CFloat32));
826 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt16, GDT_CFloat64));
827 :
828 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int16, GDT_Byte));
829 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int16, GDT_Int8));
830 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int16, GDT_UInt16));
831 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_Int16));
832 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int16, GDT_UInt32));
833 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_Int32));
834 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int16, GDT_UInt64));
835 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_Int64));
836 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_Float32));
837 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_Float64));
838 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_CInt16));
839 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_CInt32));
840 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_CFloat32));
841 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int16, GDT_CFloat64));
842 :
843 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_Byte));
844 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_UInt16));
845 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_Int16));
846 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_UInt32));
847 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_Int32));
848 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_UInt64));
849 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_Int64));
850 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_Float32));
851 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_Float64));
852 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_CInt16));
853 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_CInt32));
854 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_CFloat32));
855 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt32, GDT_CFloat64));
856 :
857 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_Byte));
858 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_UInt16));
859 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_Int16));
860 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_UInt32));
861 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int32, GDT_Int32));
862 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_UInt64));
863 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int32, GDT_Int64));
864 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_Float32));
865 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int32, GDT_Float64));
866 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_CInt16));
867 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int32, GDT_CInt32));
868 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int32, GDT_CFloat32));
869 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int32, GDT_CFloat64));
870 :
871 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_Byte));
872 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_UInt16));
873 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_Int16));
874 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_UInt32));
875 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_Int32));
876 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_UInt64));
877 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_Int64));
878 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_Float32));
879 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_Float64));
880 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_CInt16));
881 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_CInt32));
882 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_CFloat32));
883 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_UInt64, GDT_CFloat64));
884 :
885 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_Byte));
886 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_UInt16));
887 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_Int16));
888 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_UInt32));
889 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_Int32));
890 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_UInt64));
891 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Int64, GDT_Int64));
892 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_Float32));
893 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_Float64));
894 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_CInt16));
895 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_CInt32));
896 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_CFloat32));
897 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Int64, GDT_CFloat64));
898 :
899 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_Byte));
900 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_UInt16));
901 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_Int16));
902 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_UInt32));
903 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_Int32));
904 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_UInt64));
905 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_Int64));
906 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Float32, GDT_Float32));
907 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Float32, GDT_Float64));
908 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_CInt16));
909 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float32, GDT_CInt32));
910 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Float32, GDT_CFloat32));
911 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Float32, GDT_CFloat64));
912 :
913 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_Byte));
914 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_UInt16));
915 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_Int16));
916 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_UInt32));
917 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_Int32));
918 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_UInt64));
919 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_Int64));
920 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_Float32));
921 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Float64, GDT_Float64));
922 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_CInt16));
923 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_CInt32));
924 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_Float64, GDT_CFloat32));
925 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_Float64, GDT_CFloat64));
926 :
927 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_Byte));
928 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_UInt16));
929 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_Int16));
930 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_UInt32));
931 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_Int32));
932 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_UInt64));
933 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_Int64));
934 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_Float32));
935 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_Float64));
936 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_CInt16));
937 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_CInt32));
938 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_CFloat32));
939 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CInt16, GDT_CFloat64));
940 :
941 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_Byte));
942 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_UInt16));
943 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_Int16));
944 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_UInt32));
945 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_Int32));
946 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_UInt64));
947 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_Int64));
948 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_Float32));
949 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_Float64));
950 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_CInt16));
951 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_CInt32));
952 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_CFloat32));
953 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CInt32, GDT_CFloat64));
954 :
955 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_Byte));
956 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_UInt16));
957 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_Int16));
958 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_UInt32));
959 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_Int32));
960 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_UInt64));
961 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_Int64));
962 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_Float32));
963 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_Float64));
964 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_CInt16));
965 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_CInt32));
966 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_CFloat32));
967 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CFloat32, GDT_CFloat64));
968 :
969 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_Byte));
970 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_UInt16));
971 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_Int16));
972 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_UInt32));
973 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_Int32));
974 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_UInt64));
975 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_Int64));
976 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_Float32));
977 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_Float64));
978 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_CInt16));
979 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_CInt32));
980 1 : EXPECT_TRUE(GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_CFloat32));
981 1 : EXPECT_TRUE(!GDALDataTypeIsConversionLossy(GDT_CFloat64, GDT_CFloat64));
982 1 : }
983 :
984 : // Test GDALDataset::GetBands()
985 4 : TEST_F(test_gdal, GDALDataset_GetBands)
986 : {
987 : GDALDatasetUniquePtr poDS(GDALDriver::FromHandle(GDALGetDriverByName("MEM"))
988 1 : ->Create("", 1, 1, 3, GDT_Byte, nullptr));
989 1 : int nExpectedNumber = 1;
990 4 : for (auto &&poBand : poDS->GetBands())
991 : {
992 3 : EXPECT_EQ(poBand->GetBand(), nExpectedNumber);
993 3 : nExpectedNumber++;
994 : }
995 1 : ASSERT_EQ(nExpectedNumber, 3 + 1);
996 :
997 1 : ASSERT_EQ(poDS->GetBands().size(), 3U);
998 1 : EXPECT_EQ(poDS->GetBands()[0], poDS->GetRasterBand(1));
999 1 : EXPECT_EQ(poDS->GetBands()[static_cast<size_t>(0)], poDS->GetRasterBand(1));
1000 : }
1001 :
1002 4 : TEST_F(test_gdal, GDALExtendedDataType)
1003 : {
1004 : // non-null string to string
1005 : {
1006 1 : const char *srcPtr = "foo";
1007 1 : char *dstPtr = nullptr;
1008 1 : GDALExtendedDataType::CopyValue(
1009 2 : &srcPtr, GDALExtendedDataType::CreateString(), &dstPtr,
1010 2 : GDALExtendedDataType::CreateString());
1011 1 : EXPECT_TRUE(dstPtr != nullptr);
1012 : // Coverity isn't smart enough to figure out that GetClass() of
1013 : // CreateString() is GEDTC_STRING and then takes the wrong path
1014 : // in CopyValue() and makes wrong assumptions.
1015 : // coverity[string_null]
1016 1 : EXPECT_STREQ(dstPtr, srcPtr);
1017 : // coverity[incorrect_free]
1018 1 : CPLFree(dstPtr);
1019 : }
1020 : // null string to string
1021 : {
1022 1 : const char *srcPtr = nullptr;
1023 1 : char *dstPtr = nullptr;
1024 1 : GDALExtendedDataType::CopyValue(
1025 2 : &srcPtr, GDALExtendedDataType::CreateString(), &dstPtr,
1026 2 : GDALExtendedDataType::CreateString());
1027 1 : EXPECT_TRUE(dstPtr == nullptr);
1028 : }
1029 : // non-null string to Int32
1030 : {
1031 1 : const char *srcPtr = "2";
1032 1 : int32_t nVal = 1;
1033 1 : GDALExtendedDataType::CopyValue(
1034 2 : &srcPtr, GDALExtendedDataType::CreateString(), &nVal,
1035 2 : GDALExtendedDataType::Create(GDT_Int32));
1036 1 : EXPECT_EQ(nVal, 2);
1037 : }
1038 : // null string to Int32
1039 : {
1040 1 : const char *srcPtr = nullptr;
1041 1 : int32_t nVal = 1;
1042 1 : GDALExtendedDataType::CopyValue(
1043 2 : &srcPtr, GDALExtendedDataType::CreateString(), &nVal,
1044 2 : GDALExtendedDataType::Create(GDT_Int32));
1045 1 : EXPECT_EQ(nVal, 0);
1046 : }
1047 : // non-null string to Int64
1048 : {
1049 1 : const char *srcPtr = "2";
1050 1 : int64_t nVal = 1;
1051 1 : GDALExtendedDataType::CopyValue(
1052 2 : &srcPtr, GDALExtendedDataType::CreateString(), &nVal,
1053 2 : GDALExtendedDataType::Create(GDT_Int64));
1054 1 : EXPECT_EQ(nVal, 2);
1055 : }
1056 : // null string to Int64
1057 : {
1058 1 : const char *srcPtr = nullptr;
1059 1 : int64_t nVal = 1;
1060 1 : GDALExtendedDataType::CopyValue(
1061 2 : &srcPtr, GDALExtendedDataType::CreateString(), &nVal,
1062 2 : GDALExtendedDataType::Create(GDT_Int64));
1063 1 : EXPECT_EQ(nVal, 0);
1064 : }
1065 : // non-null string to UInt64
1066 : {
1067 1 : char *srcPtr = nullptr;
1068 1 : uint64_t nVal = 1;
1069 1 : GDALExtendedDataType::CopyValue(
1070 2 : &srcPtr, GDALExtendedDataType::CreateString(), &nVal,
1071 2 : GDALExtendedDataType::Create(GDT_UInt64));
1072 1 : EXPECT_EQ(nVal, 0U);
1073 : }
1074 : // non-null string to Int64
1075 : {
1076 1 : const char *srcPtr = "2";
1077 1 : uint64_t nVal = 1;
1078 1 : GDALExtendedDataType::CopyValue(
1079 2 : &srcPtr, GDALExtendedDataType::CreateString(), &nVal,
1080 2 : GDALExtendedDataType::Create(GDT_UInt64));
1081 1 : EXPECT_EQ(nVal, 2U);
1082 : }
1083 :
1084 : class myArray : public GDALMDArray
1085 : {
1086 : GDALExtendedDataType m_dt;
1087 : std::vector<std::shared_ptr<GDALDimension>> m_dims;
1088 : std::vector<GUInt64> m_blockSize;
1089 : const std::string m_osEmptyFilename{};
1090 :
1091 : static std::vector<std::shared_ptr<GDALDimension>>
1092 9 : BuildDims(const std::vector<GUInt64> &sizes)
1093 : {
1094 9 : std::vector<std::shared_ptr<GDALDimension>> dims;
1095 33 : for (const auto sz : sizes)
1096 : {
1097 : dims.emplace_back(
1098 24 : std::make_shared<GDALDimension>("", "", "", "", sz));
1099 : }
1100 9 : return dims;
1101 : }
1102 :
1103 : protected:
1104 0 : bool IRead(const GUInt64 *, const size_t *, const GInt64 *,
1105 : const GPtrDiff_t *, const GDALExtendedDataType &,
1106 : void *) const override
1107 : {
1108 0 : return false;
1109 : }
1110 :
1111 : public:
1112 8 : myArray(GDALDataType eDT, const std::vector<GUInt64> &sizes,
1113 : const std::vector<GUInt64> &blocksizes)
1114 8 : : GDALAbstractMDArray("", "array"), GDALMDArray("", "array"),
1115 : m_dt(GDALExtendedDataType::Create(eDT)), m_dims(BuildDims(sizes)),
1116 8 : m_blockSize(blocksizes)
1117 : {
1118 8 : }
1119 :
1120 1 : myArray(const GDALExtendedDataType &dt,
1121 : const std::vector<GUInt64> &sizes,
1122 : const std::vector<GUInt64> &blocksizes)
1123 1 : : GDALAbstractMDArray("", "array"), GDALMDArray("", "array"),
1124 1 : m_dt(dt), m_dims(BuildDims(sizes)), m_blockSize(blocksizes)
1125 : {
1126 1 : }
1127 :
1128 0 : bool IsWritable() const override
1129 : {
1130 0 : return true;
1131 : }
1132 :
1133 0 : const std::string &GetFilename() const override
1134 : {
1135 0 : return m_osEmptyFilename;
1136 : }
1137 :
1138 : static std::shared_ptr<myArray>
1139 1 : Create(GDALDataType eDT, const std::vector<GUInt64> &sizes,
1140 : const std::vector<GUInt64> &blocksizes)
1141 : {
1142 : auto ar(
1143 1 : std::shared_ptr<myArray>(new myArray(eDT, sizes, blocksizes)));
1144 1 : ar->SetSelf(ar);
1145 1 : return ar;
1146 : }
1147 :
1148 : static std::shared_ptr<myArray>
1149 1 : Create(const GDALExtendedDataType &dt,
1150 : const std::vector<GUInt64> &sizes,
1151 : const std::vector<GUInt64> &blocksizes)
1152 : {
1153 : auto ar(
1154 1 : std::shared_ptr<myArray>(new myArray(dt, sizes, blocksizes)));
1155 1 : ar->SetSelf(ar);
1156 1 : return ar;
1157 : }
1158 :
1159 : const std::vector<std::shared_ptr<GDALDimension>> &
1160 74 : GetDimensions() const override
1161 : {
1162 74 : return m_dims;
1163 : }
1164 :
1165 14 : const GDALExtendedDataType &GetDataType() const override
1166 : {
1167 14 : return m_dt;
1168 : }
1169 :
1170 10 : std::vector<GUInt64> GetBlockSize() const override
1171 : {
1172 10 : return m_blockSize;
1173 : }
1174 : };
1175 :
1176 : {
1177 3 : auto ar(myArray::Create(GDT_UInt16, {3000, 1000, 2000}, {32, 64, 128}));
1178 1 : EXPECT_EQ(ar->at(0)->GetDimensionCount(), 2U);
1179 1 : EXPECT_EQ(ar->at(2999, 999, 1999)->GetDimensionCount(), 0U);
1180 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1181 1 : EXPECT_TRUE(ar->at(3000, 0, 0) == nullptr);
1182 1 : EXPECT_TRUE(ar->at(0, 0, 0, 0) == nullptr);
1183 1 : EXPECT_TRUE((*ar)["foo"] == nullptr);
1184 1 : CPLPopErrorHandler();
1185 : }
1186 :
1187 : {
1188 2 : std::vector<std::unique_ptr<GDALEDTComponent>> comps;
1189 : comps.emplace_back(
1190 4 : std::unique_ptr<GDALEDTComponent>(new GDALEDTComponent(
1191 3 : "f\\o\"o", 0, GDALExtendedDataType::Create(GDT_Int32))));
1192 3 : auto dt(GDALExtendedDataType::Create("", 4, std::move(comps)));
1193 3 : auto ar(myArray::Create(dt, {3000, 1000, 2000}, {32, 64, 128}));
1194 1 : EXPECT_TRUE((*ar)["f\\o\"o"] != nullptr);
1195 : }
1196 :
1197 : {
1198 3 : myArray ar(GDT_UInt16, {}, {});
1199 :
1200 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1201 1 : EXPECT_TRUE(ar.GetView("[...]") == nullptr);
1202 1 : CPLPopErrorHandler();
1203 :
1204 2 : auto cs = ar.GetProcessingChunkSize(0);
1205 1 : EXPECT_EQ(cs.size(), 0U);
1206 :
1207 : struct TmpStructNoDim
1208 : {
1209 1 : static bool func(GDALAbstractMDArray *p_ar,
1210 : const GUInt64 *chunk_array_start_idx,
1211 : const size_t *chunk_count, GUInt64 iCurChunk,
1212 : GUInt64 nChunkCount, void *user_data)
1213 : {
1214 1 : EXPECT_TRUE(p_ar->GetName() == "array");
1215 1 : EXPECT_TRUE(chunk_array_start_idx == nullptr);
1216 1 : EXPECT_TRUE(chunk_count == nullptr);
1217 1 : EXPECT_EQ(iCurChunk, 1U);
1218 1 : EXPECT_EQ(nChunkCount, 1U);
1219 1 : *static_cast<bool *>(user_data) = true;
1220 1 : return true;
1221 : }
1222 : };
1223 :
1224 1 : bool b = false;
1225 1 : ar.ProcessPerChunk(nullptr, nullptr, nullptr, TmpStructNoDim::func, &b);
1226 1 : EXPECT_TRUE(b);
1227 : }
1228 :
1229 : struct ChunkDef
1230 : {
1231 : std::vector<GUInt64> array_start_idx;
1232 : std::vector<GUInt64> count;
1233 : };
1234 :
1235 : struct TmpStruct
1236 : {
1237 16 : static bool func(GDALAbstractMDArray *p_ar,
1238 : const GUInt64 *chunk_array_start_idx,
1239 : const size_t *chunk_count, GUInt64 iCurChunk,
1240 : GUInt64 nChunkCount, void *user_data)
1241 : {
1242 16 : EXPECT_EQ(p_ar->GetName(), "array");
1243 16 : std::vector<ChunkDef> *p_chunkDefs =
1244 : static_cast<std::vector<ChunkDef> *>(user_data);
1245 32 : std::vector<GUInt64> v_chunk_array_start_idx;
1246 : v_chunk_array_start_idx.insert(
1247 0 : v_chunk_array_start_idx.end(), chunk_array_start_idx,
1248 16 : chunk_array_start_idx + p_ar->GetDimensionCount());
1249 32 : std::vector<GUInt64> v_chunk_count;
1250 0 : v_chunk_count.insert(v_chunk_count.end(), chunk_count,
1251 16 : chunk_count + p_ar->GetDimensionCount());
1252 16 : ChunkDef chunkDef;
1253 16 : chunkDef.array_start_idx = std::move(v_chunk_array_start_idx);
1254 16 : chunkDef.count = std::move(v_chunk_count);
1255 16 : p_chunkDefs->emplace_back(std::move(chunkDef));
1256 16 : EXPECT_EQ(p_chunkDefs->size(), iCurChunk);
1257 16 : EXPECT_TRUE(iCurChunk > 0);
1258 16 : EXPECT_TRUE(iCurChunk <= nChunkCount);
1259 32 : return true;
1260 : }
1261 : };
1262 :
1263 : {
1264 3 : myArray ar(GDT_UInt16, {3000, 1000, 2000}, {32, 64, 128});
1265 : {
1266 2 : auto cs = ar.GetProcessingChunkSize(0);
1267 1 : EXPECT_EQ(cs.size(), 3U);
1268 1 : EXPECT_EQ(cs[0], 32U);
1269 1 : EXPECT_EQ(cs[1], 64U);
1270 1 : EXPECT_EQ(cs[2], 128U);
1271 : }
1272 : {
1273 2 : auto cs = ar.GetProcessingChunkSize(40 * 1000 * 1000);
1274 1 : EXPECT_EQ(cs.size(), 3U);
1275 1 : EXPECT_EQ(cs[0], 32U);
1276 1 : EXPECT_EQ(cs[1], 256U);
1277 1 : EXPECT_EQ(cs[2], 2000U);
1278 :
1279 2 : std::vector<ChunkDef> chunkDefs;
1280 :
1281 : // Error cases of input parameters of ProcessPerChunk()
1282 : {
1283 : // array_start_idx[0] + count[0] > 3000
1284 2 : std::vector<GUInt64> array_start_idx{1, 0, 0};
1285 2 : std::vector<GUInt64> count{3000, 1000, 2000};
1286 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1287 1 : EXPECT_TRUE(!ar.ProcessPerChunk(array_start_idx.data(),
1288 : count.data(), cs.data(),
1289 : TmpStruct::func, &chunkDefs));
1290 1 : CPLPopErrorHandler();
1291 : }
1292 : {
1293 : // array_start_idx[0] >= 3000
1294 2 : std::vector<GUInt64> array_start_idx{3000, 0, 0};
1295 2 : std::vector<GUInt64> count{1, 1000, 2000};
1296 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1297 1 : EXPECT_TRUE(!ar.ProcessPerChunk(array_start_idx.data(),
1298 : count.data(), cs.data(),
1299 : TmpStruct::func, &chunkDefs));
1300 1 : CPLPopErrorHandler();
1301 : }
1302 : {
1303 : // count[0] > 3000
1304 2 : std::vector<GUInt64> array_start_idx{0, 0, 0};
1305 2 : std::vector<GUInt64> count{3001, 1000, 2000};
1306 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1307 1 : EXPECT_TRUE(!ar.ProcessPerChunk(array_start_idx.data(),
1308 : count.data(), cs.data(),
1309 : TmpStruct::func, &chunkDefs));
1310 1 : CPLPopErrorHandler();
1311 : }
1312 : {
1313 : // count[0] == 0
1314 2 : std::vector<GUInt64> array_start_idx{0, 0, 0};
1315 2 : std::vector<GUInt64> count{0, 1000, 2000};
1316 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1317 1 : EXPECT_TRUE(!ar.ProcessPerChunk(array_start_idx.data(),
1318 : count.data(), cs.data(),
1319 : TmpStruct::func, &chunkDefs));
1320 1 : CPLPopErrorHandler();
1321 : }
1322 : {
1323 : // myCustomChunkSize[0] == 0
1324 2 : std::vector<GUInt64> array_start_idx{0, 0, 0};
1325 2 : std::vector<GUInt64> count{3000, 1000, 2000};
1326 2 : std::vector<size_t> myCustomChunkSize{0, 1000, 2000};
1327 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1328 1 : EXPECT_TRUE(!ar.ProcessPerChunk(
1329 : array_start_idx.data(), count.data(),
1330 : myCustomChunkSize.data(), TmpStruct::func, &chunkDefs));
1331 1 : CPLPopErrorHandler();
1332 : }
1333 : {
1334 : // myCustomChunkSize[0] > 3000
1335 2 : std::vector<GUInt64> array_start_idx{0, 0, 0};
1336 2 : std::vector<GUInt64> count{3000, 1000, 2000};
1337 2 : std::vector<size_t> myCustomChunkSize{3001, 1000, 2000};
1338 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1339 1 : EXPECT_TRUE(!ar.ProcessPerChunk(
1340 : array_start_idx.data(), count.data(),
1341 : myCustomChunkSize.data(), TmpStruct::func, &chunkDefs));
1342 1 : CPLPopErrorHandler();
1343 : }
1344 :
1345 2 : std::vector<GUInt64> array_start_idx{1500, 256, 0};
1346 2 : std::vector<GUInt64> count{99, 512, 2000};
1347 1 : EXPECT_TRUE(ar.ProcessPerChunk(array_start_idx.data(), count.data(),
1348 : cs.data(), TmpStruct::func,
1349 : &chunkDefs));
1350 :
1351 1 : size_t nExpectedChunks = 1;
1352 4 : for (size_t i = 0; i < ar.GetDimensionCount(); i++)
1353 : {
1354 3 : nExpectedChunks *= static_cast<size_t>(
1355 3 : 1 + ((array_start_idx[i] + count[i] - 1) / cs[i]) -
1356 3 : (array_start_idx[i] / cs[i]));
1357 : }
1358 1 : EXPECT_EQ(chunkDefs.size(), nExpectedChunks);
1359 :
1360 2 : CPLString osChunks;
1361 9 : for (const auto &chunkDef : chunkDefs)
1362 : {
1363 : osChunks += CPLSPrintf("{%u, %u, %u}, {%u, %u, %u}\n",
1364 8 : (unsigned)chunkDef.array_start_idx[0],
1365 8 : (unsigned)chunkDef.array_start_idx[1],
1366 8 : (unsigned)chunkDef.array_start_idx[2],
1367 8 : (unsigned)chunkDef.count[0],
1368 8 : (unsigned)chunkDef.count[1],
1369 8 : (unsigned)chunkDef.count[2]);
1370 : }
1371 1 : EXPECT_EQ(osChunks, "{1500, 256, 0}, {4, 256, 2000}\n"
1372 : "{1500, 512, 0}, {4, 256, 2000}\n"
1373 : "{1504, 256, 0}, {32, 256, 2000}\n"
1374 : "{1504, 512, 0}, {32, 256, 2000}\n"
1375 : "{1536, 256, 0}, {32, 256, 2000}\n"
1376 : "{1536, 512, 0}, {32, 256, 2000}\n"
1377 : "{1568, 256, 0}, {31, 256, 2000}\n"
1378 : "{1568, 512, 0}, {31, 256, 2000}\n");
1379 : }
1380 : }
1381 :
1382 : // Another error case of ProcessPerChunk
1383 : {
1384 1 : const auto M64 = std::numeric_limits<GUInt64>::max();
1385 1 : const auto Msize_t = std::numeric_limits<size_t>::max();
1386 3 : myArray ar(GDT_UInt16, {M64, M64, M64}, {32, 256, 128});
1387 :
1388 : // Product of myCustomChunkSize[] > Msize_t
1389 2 : std::vector<GUInt64> array_start_idx{0, 0, 0};
1390 2 : std::vector<GUInt64> count{3000, 1000, 2000};
1391 2 : std::vector<size_t> myCustomChunkSize{Msize_t, Msize_t, Msize_t};
1392 2 : std::vector<ChunkDef> chunkDefs;
1393 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1394 1 : EXPECT_TRUE(!ar.ProcessPerChunk(array_start_idx.data(), count.data(),
1395 : myCustomChunkSize.data(),
1396 : TmpStruct::func, &chunkDefs));
1397 1 : CPLPopErrorHandler();
1398 : }
1399 :
1400 : {
1401 1 : const auto BIG = GUInt64(5000) * 1000 * 1000;
1402 : myArray ar(GDT_UInt16, {BIG + 3000, BIG + 1000, BIG + 2000},
1403 3 : {32, 256, 128});
1404 2 : std::vector<GUInt64> array_start_idx{BIG + 1500, BIG + 256, BIG + 0};
1405 2 : std::vector<GUInt64> count{99, 512, 2000};
1406 2 : std::vector<ChunkDef> chunkDefs;
1407 2 : auto cs = ar.GetProcessingChunkSize(40 * 1000 * 1000);
1408 1 : EXPECT_TRUE(ar.ProcessPerChunk(array_start_idx.data(), count.data(),
1409 : cs.data(), TmpStruct::func, &chunkDefs));
1410 :
1411 1 : size_t nExpectedChunks = 1;
1412 4 : for (size_t i = 0; i < ar.GetDimensionCount(); i++)
1413 : {
1414 3 : nExpectedChunks *= static_cast<size_t>(
1415 3 : 1 + ((array_start_idx[i] + count[i] - 1) / cs[i]) -
1416 3 : (array_start_idx[i] / cs[i]));
1417 : }
1418 1 : EXPECT_EQ(chunkDefs.size(), nExpectedChunks);
1419 :
1420 2 : CPLString osChunks;
1421 9 : for (const auto &chunkDef : chunkDefs)
1422 : {
1423 : osChunks += CPLSPrintf("{" CPL_FRMT_GUIB ", " CPL_FRMT_GUIB
1424 : ", " CPL_FRMT_GUIB "}, {%u, %u, %u}\n",
1425 8 : (GUIntBig)chunkDef.array_start_idx[0],
1426 8 : (GUIntBig)chunkDef.array_start_idx[1],
1427 8 : (GUIntBig)chunkDef.array_start_idx[2],
1428 8 : (unsigned)chunkDef.count[0],
1429 8 : (unsigned)chunkDef.count[1],
1430 8 : (unsigned)chunkDef.count[2]);
1431 : }
1432 1 : EXPECT_EQ(osChunks,
1433 : "{5000001500, 5000000256, 5000000000}, {4, 256, 2000}\n"
1434 : "{5000001500, 5000000512, 5000000000}, {4, 256, 2000}\n"
1435 : "{5000001504, 5000000256, 5000000000}, {32, 256, 2000}\n"
1436 : "{5000001504, 5000000512, 5000000000}, {32, 256, 2000}\n"
1437 : "{5000001536, 5000000256, 5000000000}, {32, 256, 2000}\n"
1438 : "{5000001536, 5000000512, 5000000000}, {32, 256, 2000}\n"
1439 : "{5000001568, 5000000256, 5000000000}, {31, 256, 2000}\n"
1440 : "{5000001568, 5000000512, 5000000000}, {31, 256, 2000}\n");
1441 : }
1442 :
1443 : {
1444 : // Test with 0 in GetBlockSize()
1445 3 : myArray ar(GDT_UInt16, {500, 1000, 2000}, {0, 0, 128});
1446 : {
1447 2 : auto cs = ar.GetProcessingChunkSize(300 * 2);
1448 1 : EXPECT_EQ(cs.size(), 3U);
1449 1 : EXPECT_EQ(cs[0], 1U);
1450 1 : EXPECT_EQ(cs[1], 1U);
1451 1 : EXPECT_EQ(cs[2], 256U);
1452 : }
1453 : {
1454 2 : auto cs = ar.GetProcessingChunkSize(40 * 1000 * 1000);
1455 1 : EXPECT_EQ(cs.size(), 3U);
1456 1 : EXPECT_EQ(cs[0], 10U);
1457 1 : EXPECT_EQ(cs[1], 1000U);
1458 1 : EXPECT_EQ(cs[2], 2000U);
1459 : }
1460 : {
1461 2 : auto cs = ar.GetProcessingChunkSize(500U * 1000 * 2000 * 2);
1462 1 : EXPECT_EQ(cs.size(), 3U);
1463 1 : EXPECT_EQ(cs[0], 500U);
1464 1 : EXPECT_EQ(cs[1], 1000U);
1465 1 : EXPECT_EQ(cs[2], 2000U);
1466 : }
1467 : {
1468 2 : auto cs = ar.GetProcessingChunkSize(500U * 1000 * 2000 * 2 - 1);
1469 1 : EXPECT_EQ(cs.size(), 3U);
1470 1 : EXPECT_EQ(cs[0], 499U);
1471 1 : EXPECT_EQ(cs[1], 1000U);
1472 1 : EXPECT_EQ(cs[2], 2000U);
1473 : }
1474 : }
1475 : {
1476 1 : const auto M = std::numeric_limits<GUInt64>::max();
1477 3 : myArray ar(GDT_UInt16, {M, M, M}, {M, M, M / 2});
1478 : {
1479 2 : auto cs = ar.GetProcessingChunkSize(0);
1480 1 : EXPECT_EQ(cs.size(), 3U);
1481 1 : EXPECT_EQ(cs[0], 1U);
1482 1 : EXPECT_EQ(cs[1], 1U);
1483 : #if SIZEOF_VOIDP == 8
1484 1 : EXPECT_EQ(cs[2], static_cast<size_t>(M / 2));
1485 : #else
1486 : EXPECT_EQ(cs[2], 1U);
1487 : #endif
1488 : }
1489 : }
1490 : #if SIZEOF_VOIDP == 8
1491 : {
1492 1 : const auto M = std::numeric_limits<GUInt64>::max();
1493 3 : myArray ar(GDT_UInt16, {M, M, M}, {M, M, M / 4});
1494 : {
1495 : auto cs =
1496 2 : ar.GetProcessingChunkSize(std::numeric_limits<size_t>::max());
1497 1 : EXPECT_EQ(cs.size(), 3U);
1498 1 : EXPECT_EQ(cs[0], 1U);
1499 1 : EXPECT_EQ(cs[1], 1U);
1500 1 : EXPECT_EQ(cs[2], (std::numeric_limits<size_t>::max() / 4) * 2);
1501 : }
1502 : }
1503 : #endif
1504 1 : }
1505 :
1506 : // Test GDALDataset::GetRawBinaryLayout() implementations
1507 4 : TEST_F(test_gdal, GetRawBinaryLayout_ENVI)
1508 : {
1509 1 : if (GDALGetDriverByName("ENVI") == nullptr)
1510 : {
1511 0 : GTEST_SKIP() << "ENVI driver missing";
1512 : }
1513 :
1514 : {
1515 : GDALDatasetUniquePtr poDS(
1516 2 : GDALDataset::Open(GDRIVERS_DATA_DIR "envi/envi_rgbsmall_bip.img"));
1517 1 : EXPECT_TRUE(poDS != nullptr);
1518 2 : GDALDataset::RawBinaryLayout sLayout;
1519 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1520 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1521 1 : EXPECT_EQ(
1522 : static_cast<int>(sLayout.eInterleaving),
1523 : static_cast<int>(GDALDataset::RawBinaryLayout::Interleaving::BIP));
1524 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1525 1 : EXPECT_TRUE(sLayout.bLittleEndianOrder);
1526 1 : EXPECT_EQ(sLayout.nImageOffset, 0U);
1527 1 : EXPECT_EQ(sLayout.nPixelOffset, 3);
1528 1 : EXPECT_EQ(sLayout.nLineOffset, 3 * 50);
1529 1 : EXPECT_EQ(sLayout.nBandOffset, 1);
1530 : }
1531 :
1532 : {
1533 : GDALDatasetUniquePtr poDS(
1534 2 : GDALDataset::Open(GDRIVERS_DATA_DIR "envi/envi_rgbsmall_bil.img"));
1535 1 : EXPECT_TRUE(poDS != nullptr);
1536 2 : GDALDataset::RawBinaryLayout sLayout;
1537 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1538 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1539 1 : EXPECT_EQ(
1540 : static_cast<int>(sLayout.eInterleaving),
1541 : static_cast<int>(GDALDataset::RawBinaryLayout::Interleaving::BIL));
1542 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1543 1 : EXPECT_TRUE(sLayout.bLittleEndianOrder);
1544 1 : EXPECT_EQ(sLayout.nImageOffset, 0U);
1545 1 : EXPECT_EQ(sLayout.nPixelOffset, 1);
1546 1 : EXPECT_EQ(sLayout.nLineOffset, 3 * 50);
1547 1 : EXPECT_EQ(sLayout.nBandOffset, 50);
1548 : }
1549 :
1550 : {
1551 : GDALDatasetUniquePtr poDS(
1552 2 : GDALDataset::Open(GDRIVERS_DATA_DIR "envi/envi_rgbsmall_bsq.img"));
1553 1 : EXPECT_TRUE(poDS != nullptr);
1554 2 : GDALDataset::RawBinaryLayout sLayout;
1555 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1556 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1557 1 : EXPECT_EQ(
1558 : static_cast<int>(sLayout.eInterleaving),
1559 : static_cast<int>(GDALDataset::RawBinaryLayout::Interleaving::BSQ));
1560 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1561 1 : EXPECT_TRUE(sLayout.bLittleEndianOrder);
1562 1 : EXPECT_EQ(sLayout.nImageOffset, 0U);
1563 1 : EXPECT_EQ(sLayout.nPixelOffset, 1);
1564 1 : EXPECT_EQ(sLayout.nLineOffset, 50);
1565 1 : EXPECT_EQ(sLayout.nBandOffset, 50 * 49);
1566 : }
1567 : }
1568 :
1569 : // Test GDALDataset::GetRawBinaryLayout() implementations
1570 4 : TEST_F(test_gdal, GetRawBinaryLayout_GTIFF)
1571 : {
1572 1 : if (GDALGetDriverByName("GTIFF") == nullptr)
1573 : {
1574 0 : GTEST_SKIP() << "GTIFF driver missing";
1575 : }
1576 :
1577 : {
1578 : GDALDatasetUniquePtr poDS(
1579 2 : GDALDataset::Open(GCORE_DATA_DIR "uint16.tif"));
1580 1 : EXPECT_TRUE(poDS != nullptr);
1581 2 : GDALDataset::RawBinaryLayout sLayout;
1582 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1583 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1584 1 : EXPECT_EQ(static_cast<int>(sLayout.eInterleaving),
1585 : static_cast<int>(
1586 : GDALDataset::RawBinaryLayout::Interleaving::UNKNOWN));
1587 1 : EXPECT_EQ(sLayout.eDataType, GDT_UInt16);
1588 1 : EXPECT_TRUE(sLayout.bLittleEndianOrder);
1589 1 : EXPECT_EQ(sLayout.nImageOffset, 8U);
1590 1 : EXPECT_EQ(sLayout.nPixelOffset, 2);
1591 1 : EXPECT_EQ(sLayout.nLineOffset, 40);
1592 1 : EXPECT_EQ(sLayout.nBandOffset, 0);
1593 : }
1594 :
1595 : {
1596 : GDALDatasetUniquePtr poDS(
1597 2 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif"));
1598 1 : EXPECT_TRUE(poDS != nullptr);
1599 2 : GDALDataset::RawBinaryLayout sLayout;
1600 : // Compressed
1601 1 : EXPECT_TRUE(!poDS->GetRawBinaryLayout(sLayout));
1602 : }
1603 :
1604 : {
1605 : GDALDatasetUniquePtr poDS(
1606 2 : GDALDataset::Open(GCORE_DATA_DIR "stefan_full_rgba.tif"));
1607 1 : EXPECT_TRUE(poDS != nullptr);
1608 2 : GDALDataset::RawBinaryLayout sLayout;
1609 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1610 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1611 1 : EXPECT_EQ(
1612 : static_cast<int>(sLayout.eInterleaving),
1613 : static_cast<int>(GDALDataset::RawBinaryLayout::Interleaving::BIP));
1614 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1615 1 : EXPECT_EQ(sLayout.nImageOffset, 278U);
1616 1 : EXPECT_EQ(sLayout.nPixelOffset, 4);
1617 1 : EXPECT_EQ(sLayout.nLineOffset, 162 * 4);
1618 1 : EXPECT_EQ(sLayout.nBandOffset, 1);
1619 : }
1620 :
1621 : {
1622 : GDALDatasetUniquePtr poSrcDS(
1623 2 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif"));
1624 1 : EXPECT_TRUE(poSrcDS != nullptr);
1625 1 : auto tmpFilename = "/vsimem/tmp.tif";
1626 1 : auto poDrv = GDALDriver::FromHandle(GDALGetDriverByName("GTiff"));
1627 1 : const char *options[] = {"INTERLEAVE=BAND", nullptr};
1628 : auto poDS(GDALDatasetUniquePtr(
1629 : poDrv->CreateCopy(tmpFilename, poSrcDS.get(), false,
1630 2 : const_cast<char **>(options), nullptr, nullptr)));
1631 1 : EXPECT_TRUE(poDS != nullptr);
1632 2 : GDALDataset::RawBinaryLayout sLayout;
1633 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1634 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1635 1 : EXPECT_EQ(
1636 : static_cast<int>(sLayout.eInterleaving),
1637 : static_cast<int>(GDALDataset::RawBinaryLayout::Interleaving::BSQ));
1638 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1639 1 : EXPECT_TRUE(sLayout.nImageOffset >= 396U);
1640 1 : EXPECT_EQ(sLayout.nPixelOffset, 1);
1641 1 : EXPECT_EQ(sLayout.nLineOffset, 50);
1642 1 : EXPECT_EQ(sLayout.nBandOffset, 50 * 50);
1643 1 : poDS.reset();
1644 1 : VSIUnlink(tmpFilename);
1645 : }
1646 :
1647 : {
1648 : GDALDatasetUniquePtr poSrcDS(
1649 2 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif"));
1650 1 : EXPECT_TRUE(poSrcDS != nullptr);
1651 1 : auto tmpFilename = "/vsimem/tmp.tif";
1652 1 : const char *options[] = {"-srcwin",
1653 : "0",
1654 : "0",
1655 : "48",
1656 : "32",
1657 : "-co",
1658 : "INTERLEAVE=PIXEL",
1659 : "-co",
1660 : "TILED=YES",
1661 : "-co",
1662 : "BLOCKXSIZE=48",
1663 : "-co",
1664 : "BLOCKYSIZE=32",
1665 : nullptr};
1666 : auto psOptions =
1667 1 : GDALTranslateOptionsNew(const_cast<char **>(options), nullptr);
1668 : auto poDS(GDALDatasetUniquePtr(GDALDataset::FromHandle(
1669 : GDALTranslate(tmpFilename, GDALDataset::ToHandle(poSrcDS.get()),
1670 2 : psOptions, nullptr))));
1671 1 : GDALTranslateOptionsFree(psOptions);
1672 1 : EXPECT_TRUE(poDS != nullptr);
1673 2 : GDALDataset::RawBinaryLayout sLayout;
1674 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1675 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1676 1 : EXPECT_EQ(
1677 : static_cast<int>(sLayout.eInterleaving),
1678 : static_cast<int>(GDALDataset::RawBinaryLayout::Interleaving::BIP));
1679 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1680 1 : EXPECT_TRUE(sLayout.nImageOffset >= 390U);
1681 1 : EXPECT_EQ(sLayout.nPixelOffset, 3);
1682 1 : EXPECT_EQ(sLayout.nLineOffset, 48 * 3);
1683 1 : EXPECT_EQ(sLayout.nBandOffset, 1);
1684 1 : poDS.reset();
1685 1 : VSIUnlink(tmpFilename);
1686 : }
1687 :
1688 : {
1689 : GDALDatasetUniquePtr poSrcDS(
1690 2 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif"));
1691 1 : EXPECT_TRUE(poSrcDS != nullptr);
1692 1 : auto tmpFilename = "/vsimem/tmp.tif";
1693 1 : const char *options[] = {"-srcwin",
1694 : "0",
1695 : "0",
1696 : "48",
1697 : "32",
1698 : "-ot",
1699 : "UInt16",
1700 : "-co",
1701 : "TILED=YES",
1702 : "-co",
1703 : "BLOCKXSIZE=48",
1704 : "-co",
1705 : "BLOCKYSIZE=32",
1706 : "-co",
1707 : "INTERLEAVE=BAND",
1708 : "-co",
1709 : "ENDIANNESS=BIG",
1710 : nullptr};
1711 : auto psOptions =
1712 1 : GDALTranslateOptionsNew(const_cast<char **>(options), nullptr);
1713 : auto poDS(GDALDatasetUniquePtr(GDALDataset::FromHandle(
1714 : GDALTranslate(tmpFilename, GDALDataset::ToHandle(poSrcDS.get()),
1715 2 : psOptions, nullptr))));
1716 1 : GDALTranslateOptionsFree(psOptions);
1717 1 : EXPECT_TRUE(poDS != nullptr);
1718 2 : GDALDataset::RawBinaryLayout sLayout;
1719 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1720 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1721 1 : EXPECT_EQ(
1722 : static_cast<int>(sLayout.eInterleaving),
1723 : static_cast<int>(GDALDataset::RawBinaryLayout::Interleaving::BSQ));
1724 1 : EXPECT_EQ(sLayout.eDataType, GDT_UInt16);
1725 1 : EXPECT_TRUE(!sLayout.bLittleEndianOrder);
1726 1 : EXPECT_TRUE(sLayout.nImageOffset >= 408U);
1727 1 : EXPECT_EQ(sLayout.nPixelOffset, 2);
1728 1 : EXPECT_EQ(sLayout.nLineOffset, 2 * 48);
1729 1 : EXPECT_EQ(sLayout.nBandOffset, 2 * 48 * 32);
1730 1 : poDS.reset();
1731 1 : VSIUnlink(tmpFilename);
1732 : }
1733 : }
1734 :
1735 : // Test GDALDataset::GetRawBinaryLayout() implementations
1736 4 : TEST_F(test_gdal, GetRawBinaryLayout_ISIS3)
1737 : {
1738 1 : if (GDALGetDriverByName("ISIS3") == nullptr)
1739 : {
1740 0 : GTEST_SKIP() << "ISIS3 driver missing";
1741 : }
1742 :
1743 : {
1744 : GDALDatasetUniquePtr poDS(
1745 2 : GDALDataset::Open(GDRIVERS_DATA_DIR "isis3/isis3_detached.lbl"));
1746 1 : EXPECT_TRUE(poDS != nullptr);
1747 2 : GDALDataset::RawBinaryLayout sLayout;
1748 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1749 1 : EXPECT_TRUE(sLayout.osRawFilename.find("isis3_detached.cub") !=
1750 : std::string::npos);
1751 1 : EXPECT_EQ(static_cast<int>(sLayout.eInterleaving),
1752 : static_cast<int>(
1753 : GDALDataset::RawBinaryLayout::Interleaving::UNKNOWN));
1754 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1755 1 : EXPECT_TRUE(sLayout.bLittleEndianOrder);
1756 1 : EXPECT_EQ(sLayout.nImageOffset, 0U);
1757 1 : EXPECT_EQ(sLayout.nPixelOffset, 1);
1758 1 : EXPECT_EQ(sLayout.nLineOffset, 317);
1759 : // EXPECT_EQ( sLayout.nBandOffset, 9510 ); // doesn't matter on single
1760 : // band
1761 : }
1762 : }
1763 :
1764 : // Test GDALDataset::GetRawBinaryLayout() implementations
1765 4 : TEST_F(test_gdal, GetRawBinaryLayout_VICAR)
1766 : {
1767 1 : if (GDALGetDriverByName("VICAR") == nullptr)
1768 : {
1769 0 : GTEST_SKIP() << "VICAR driver missing";
1770 : }
1771 :
1772 : {
1773 : GDALDatasetUniquePtr poDS(GDALDataset::Open(
1774 2 : GDRIVERS_DATA_DIR "vicar/test_vicar_truncated.bin"));
1775 1 : EXPECT_TRUE(poDS != nullptr);
1776 2 : GDALDataset::RawBinaryLayout sLayout;
1777 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1778 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1779 1 : EXPECT_EQ(static_cast<int>(sLayout.eInterleaving),
1780 : static_cast<int>(
1781 : GDALDataset::RawBinaryLayout::Interleaving::UNKNOWN));
1782 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1783 1 : EXPECT_TRUE(sLayout.bLittleEndianOrder);
1784 1 : EXPECT_EQ(sLayout.nImageOffset, 9680U);
1785 1 : EXPECT_EQ(sLayout.nPixelOffset, 1);
1786 1 : EXPECT_EQ(sLayout.nLineOffset, 400);
1787 1 : EXPECT_EQ(sLayout.nBandOffset, 0); // doesn't matter on single band
1788 : }
1789 : }
1790 :
1791 : // Test GDALDataset::GetRawBinaryLayout() implementations
1792 4 : TEST_F(test_gdal, GetRawBinaryLayout_FITS)
1793 : {
1794 1 : if (GDALGetDriverByName("FITS") == nullptr)
1795 : {
1796 0 : GTEST_SKIP() << "FITS driver missing";
1797 : }
1798 :
1799 : {
1800 : GDALDatasetUniquePtr poSrcDS(
1801 2 : GDALDataset::Open(GCORE_DATA_DIR "int16.tif"));
1802 1 : EXPECT_TRUE(poSrcDS != nullptr);
1803 2 : CPLString tmpFilename(CPLGenerateTempFilename(nullptr));
1804 1 : tmpFilename += ".fits";
1805 1 : auto poDrv = GDALDriver::FromHandle(GDALGetDriverByName("FITS"));
1806 1 : if (poDrv)
1807 : {
1808 : auto poDS(GDALDatasetUniquePtr(poDrv->CreateCopy(
1809 2 : tmpFilename, poSrcDS.get(), false, nullptr, nullptr, nullptr)));
1810 1 : EXPECT_TRUE(poDS != nullptr);
1811 1 : poDS.reset();
1812 1 : poDS.reset(GDALDataset::Open(tmpFilename));
1813 1 : EXPECT_TRUE(poDS != nullptr);
1814 2 : GDALDataset::RawBinaryLayout sLayout;
1815 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1816 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1817 1 : EXPECT_EQ(static_cast<int>(sLayout.eInterleaving),
1818 : static_cast<int>(
1819 : GDALDataset::RawBinaryLayout::Interleaving::UNKNOWN));
1820 1 : EXPECT_EQ(sLayout.eDataType, GDT_Int16);
1821 1 : EXPECT_TRUE(!sLayout.bLittleEndianOrder);
1822 1 : EXPECT_EQ(sLayout.nImageOffset, 2880U);
1823 1 : EXPECT_EQ(sLayout.nPixelOffset, 2);
1824 1 : EXPECT_EQ(sLayout.nLineOffset, 2 * 20);
1825 1 : EXPECT_EQ(sLayout.nBandOffset, 2 * 20 * 20);
1826 1 : poDS.reset();
1827 1 : VSIUnlink(tmpFilename);
1828 : }
1829 : }
1830 : }
1831 :
1832 : // Test GDALDataset::GetRawBinaryLayout() implementations
1833 4 : TEST_F(test_gdal, GetRawBinaryLayout_PDS)
1834 : {
1835 1 : if (GDALGetDriverByName("PDS") == nullptr)
1836 : {
1837 0 : GTEST_SKIP() << "PDS driver missing";
1838 : }
1839 :
1840 : {
1841 : GDALDatasetUniquePtr poDS(
1842 2 : GDALDataset::Open(GDRIVERS_DATA_DIR "pds/mc02_truncated.img"));
1843 1 : EXPECT_TRUE(poDS != nullptr);
1844 2 : GDALDataset::RawBinaryLayout sLayout;
1845 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1846 1 : EXPECT_EQ(sLayout.osRawFilename, poDS->GetDescription());
1847 1 : EXPECT_EQ(static_cast<int>(sLayout.eInterleaving),
1848 : static_cast<int>(
1849 : GDALDataset::RawBinaryLayout::Interleaving::UNKNOWN));
1850 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1851 1 : EXPECT_TRUE(sLayout.bLittleEndianOrder);
1852 1 : EXPECT_EQ(sLayout.nImageOffset, 3840U);
1853 1 : EXPECT_EQ(sLayout.nPixelOffset, 1);
1854 1 : EXPECT_EQ(sLayout.nLineOffset, 3840);
1855 1 : EXPECT_EQ(sLayout.nBandOffset, 0); // doesn't matter on single band
1856 : }
1857 : }
1858 :
1859 : // Test GDALDataset::GetRawBinaryLayout() implementations
1860 4 : TEST_F(test_gdal, GetRawBinaryLayout_PDS4)
1861 : {
1862 1 : if (GDALGetDriverByName("PDS4") == nullptr)
1863 : {
1864 0 : GTEST_SKIP() << "PDS4 driver missing";
1865 : }
1866 :
1867 : {
1868 : GDALDatasetUniquePtr poDS(GDALDataset::Open(
1869 2 : GDRIVERS_DATA_DIR "pds4/byte_pds4_cart_1700.xml"));
1870 1 : EXPECT_TRUE(poDS != nullptr);
1871 2 : GDALDataset::RawBinaryLayout sLayout;
1872 1 : EXPECT_TRUE(poDS->GetRawBinaryLayout(sLayout));
1873 1 : EXPECT_TRUE(sLayout.osRawFilename.find("byte_pds4_cart_1700.img") !=
1874 : std::string::npos);
1875 1 : EXPECT_EQ(static_cast<int>(sLayout.eInterleaving),
1876 : static_cast<int>(
1877 : GDALDataset::RawBinaryLayout::Interleaving::UNKNOWN));
1878 1 : EXPECT_EQ(sLayout.eDataType, GDT_Byte);
1879 1 : EXPECT_TRUE(!sLayout.bLittleEndianOrder);
1880 1 : EXPECT_EQ(sLayout.nImageOffset, 0U);
1881 1 : EXPECT_EQ(sLayout.nPixelOffset, 1);
1882 1 : EXPECT_EQ(sLayout.nLineOffset, 20);
1883 1 : EXPECT_EQ(sLayout.nBandOffset, 0); // doesn't matter on single band
1884 : }
1885 : }
1886 :
1887 : // Test TileMatrixSet
1888 4 : TEST_F(test_gdal, TileMatrixSet)
1889 : {
1890 1 : if (getenv("SKIP_TILEMATRIXSET_TEST") != nullptr)
1891 0 : GTEST_SKIP() << "Test skipped due to SKIP_TILEMATRIXSET_TEST being set";
1892 :
1893 : {
1894 2 : auto l = gdal::TileMatrixSet::listPredefinedTileMatrixSets();
1895 1 : EXPECT_TRUE(l.find("GoogleMapsCompatible") != l.end());
1896 1 : EXPECT_TRUE(l.find("NZTM2000") != l.end());
1897 : }
1898 :
1899 : {
1900 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1901 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse("i_dont_exist") == nullptr);
1902 1 : CPLPopErrorHandler();
1903 : }
1904 :
1905 : {
1906 1 : CPLErrorReset();
1907 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1908 : // Invalid JSON
1909 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse(
1910 : "http://127.0.0.1:32767/example.json") == nullptr);
1911 1 : CPLPopErrorHandler();
1912 1 : EXPECT_TRUE(CPLGetLastErrorType() != 0);
1913 : }
1914 :
1915 : {
1916 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1917 : // Invalid JSON
1918 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse(
1919 : "{\"type\": \"TileMatrixSetType\" invalid") == nullptr);
1920 1 : CPLPopErrorHandler();
1921 : }
1922 :
1923 : {
1924 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1925 : // No tileMatrix
1926 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse(
1927 : "{\"type\": \"TileMatrixSetType\" }") == nullptr);
1928 1 : CPLPopErrorHandler();
1929 : }
1930 :
1931 : {
1932 2 : auto poTMS = gdal::TileMatrixSet::parse("LINZAntarticaMapTileGrid");
1933 1 : EXPECT_TRUE(poTMS != nullptr);
1934 1 : if (poTMS)
1935 : {
1936 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTopLeft());
1937 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTileSize());
1938 1 : EXPECT_TRUE(poTMS->hasOnlyPowerOfTwoVaryingScales());
1939 1 : EXPECT_TRUE(!poTMS->hasVariableMatrixWidth());
1940 : }
1941 : }
1942 :
1943 : {
1944 2 : auto poTMS = gdal::TileMatrixSet::parse("NZTM2000");
1945 1 : EXPECT_TRUE(poTMS != nullptr);
1946 1 : if (poTMS)
1947 : {
1948 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTopLeft());
1949 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTileSize());
1950 1 : EXPECT_TRUE(!poTMS->hasOnlyPowerOfTwoVaryingScales());
1951 1 : EXPECT_TRUE(!poTMS->hasVariableMatrixWidth());
1952 : }
1953 : }
1954 :
1955 : // Inline JSON with minimal structure
1956 : {
1957 : auto poTMS = gdal::TileMatrixSet::parse(
1958 : "{\"type\": \"TileMatrixSetType\", \"supportedCRS\": "
1959 : "\"http://www.opengis.net/def/crs/OGC/1.3/CRS84\", \"tileMatrix\": "
1960 2 : "[{ \"topLeftCorner\": [-180, 90],\"scaleDenominator\":1.0}] }");
1961 1 : EXPECT_TRUE(poTMS != nullptr);
1962 1 : if (poTMS)
1963 : {
1964 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTopLeft());
1965 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTileSize());
1966 1 : EXPECT_TRUE(poTMS->hasOnlyPowerOfTwoVaryingScales());
1967 1 : EXPECT_TRUE(!poTMS->hasVariableMatrixWidth());
1968 : }
1969 : }
1970 :
1971 : // Invalid scaleDenominator
1972 : {
1973 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
1974 1 : EXPECT_TRUE(gdal::TileMatrixSet::parse(
1975 : "{\"type\": \"TileMatrixSetType\", \"supportedCRS\": "
1976 : "\"http://www.opengis.net/def/crs/OGC/1.3/CRS84\", "
1977 : "\"tileMatrix\": [{ \"topLeftCorner\": [-180, "
1978 : "90],\"scaleDenominator\":0.0}] }") == nullptr);
1979 1 : CPLPopErrorHandler();
1980 : }
1981 :
1982 : {
1983 1 : const char *pszJSON = "{"
1984 : " \"type\": \"TileMatrixSetType\","
1985 : " \"title\": \"CRS84 for the World\","
1986 : " \"identifier\": \"WorldCRS84Quad\","
1987 : " \"abstract\": \"my abstract\","
1988 : " \"boundingBox\":"
1989 : " {"
1990 : " \"type\": \"BoundingBoxType\","
1991 : " \"crs\": "
1992 : "\"http://www.opengis.net/def/crs/OGC/1.X/"
1993 : "CRS84\"," // 1.3 modified to 1.X to test
1994 : // difference with supportedCRS
1995 : " \"lowerCorner\": [-180, -90],"
1996 : " \"upperCorner\": [180, 90]"
1997 : " },"
1998 : " \"supportedCRS\": "
1999 : "\"http://www.opengis.net/def/crs/OGC/1.3/"
2000 : "CRS84\","
2001 : " \"wellKnownScaleSet\": "
2002 : "\"http://www.opengis.net/def/wkss/OGC/1.0/"
2003 : "GoogleCRS84Quad\","
2004 : " \"tileMatrix\":"
2005 : " ["
2006 : " {"
2007 : " \"type\": \"TileMatrixType\","
2008 : " \"identifier\": \"0\","
2009 : " \"scaleDenominator\": "
2010 : "279541132.014358,"
2011 : " \"topLeftCorner\": [-180, 90],"
2012 : " \"tileWidth\": 256,"
2013 : " \"tileHeight\": 256,"
2014 : " \"matrixWidth\": 2,"
2015 : " \"matrixHeight\": 1"
2016 : " },"
2017 : " {"
2018 : " \"type\": \"TileMatrixType\","
2019 : " \"identifier\": \"1\","
2020 : " \"scaleDenominator\": "
2021 : "139770566.007179,"
2022 : " \"topLeftCorner\": [-180, 90],"
2023 : " \"tileWidth\": 256,"
2024 : " \"tileHeight\": 256,"
2025 : " \"matrixWidth\": 4,"
2026 : " \"matrixHeight\": 2"
2027 : " }"
2028 : " ]"
2029 : "}";
2030 1 : VSIFCloseL(VSIFileFromMemBuffer(
2031 : "/vsimem/tmp.json",
2032 : reinterpret_cast<GByte *>(const_cast<char *>(pszJSON)),
2033 1 : strlen(pszJSON), false));
2034 1 : auto poTMS = gdal::TileMatrixSet::parse("/vsimem/tmp.json");
2035 1 : VSIUnlink("/vsimem/tmp.json");
2036 :
2037 1 : EXPECT_TRUE(poTMS != nullptr);
2038 1 : if (poTMS)
2039 : {
2040 1 : EXPECT_EQ(poTMS->title(), "CRS84 for the World");
2041 1 : EXPECT_EQ(poTMS->identifier(), "WorldCRS84Quad");
2042 1 : EXPECT_EQ(poTMS->abstract(), "my abstract");
2043 1 : EXPECT_EQ(poTMS->crs(),
2044 : "http://www.opengis.net/def/crs/OGC/1.3/CRS84");
2045 1 : EXPECT_EQ(
2046 : poTMS->wellKnownScaleSet(),
2047 : "http://www.opengis.net/def/wkss/OGC/1.0/GoogleCRS84Quad");
2048 1 : EXPECT_EQ(poTMS->bbox().mCrs,
2049 : "http://www.opengis.net/def/crs/OGC/1.X/CRS84");
2050 1 : EXPECT_EQ(poTMS->bbox().mLowerCornerX, -180.0);
2051 1 : EXPECT_EQ(poTMS->bbox().mLowerCornerY, -90.0);
2052 1 : EXPECT_EQ(poTMS->bbox().mUpperCornerX, 180.0);
2053 1 : EXPECT_EQ(poTMS->bbox().mUpperCornerY, 90.0);
2054 1 : ASSERT_EQ(poTMS->tileMatrixList().size(), 2U);
2055 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTopLeft());
2056 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTileSize());
2057 1 : EXPECT_TRUE(poTMS->hasOnlyPowerOfTwoVaryingScales());
2058 1 : EXPECT_TRUE(!poTMS->hasVariableMatrixWidth());
2059 1 : const auto &tm = poTMS->tileMatrixList()[0];
2060 1 : EXPECT_EQ(tm.mId, "0");
2061 1 : EXPECT_EQ(tm.mScaleDenominator, 279541132.014358);
2062 1 : EXPECT_TRUE(fabs(tm.mResX - tm.mScaleDenominator * 0.28e-3 /
2063 : (6378137. * M_PI / 180)) < 1e-10);
2064 1 : EXPECT_TRUE(fabs(tm.mResX - 180. / 256) < 1e-10);
2065 1 : EXPECT_EQ(tm.mResY, tm.mResX);
2066 1 : EXPECT_EQ(tm.mTopLeftX, -180.0);
2067 1 : EXPECT_EQ(tm.mTopLeftY, 90.0);
2068 1 : EXPECT_EQ(tm.mTileWidth, 256);
2069 1 : EXPECT_EQ(tm.mTileHeight, 256);
2070 1 : EXPECT_EQ(tm.mMatrixWidth, 2);
2071 1 : EXPECT_EQ(tm.mMatrixHeight, 1);
2072 : }
2073 : }
2074 :
2075 : {
2076 : auto poTMS = gdal::TileMatrixSet::parse(
2077 : "{"
2078 : " \"type\": \"TileMatrixSetType\","
2079 : " \"title\": \"CRS84 for the World\","
2080 : " \"identifier\": \"WorldCRS84Quad\","
2081 : " \"boundingBox\":"
2082 : " {"
2083 : " \"type\": \"BoundingBoxType\","
2084 : " \"crs\": "
2085 : "\"http://www.opengis.net/def/crs/OGC/1.X/"
2086 : "CRS84\"," // 1.3 modified to 1.X to test
2087 : // difference with supportedCRS
2088 : " \"lowerCorner\": [-180, -90],"
2089 : " \"upperCorner\": [180, 90]"
2090 : " },"
2091 : " \"supportedCRS\": "
2092 : "\"http://www.opengis.net/def/crs/OGC/1.3/"
2093 : "CRS84\","
2094 : " \"wellKnownScaleSet\": "
2095 : "\"http://www.opengis.net/def/wkss/OGC/1.0/"
2096 : "GoogleCRS84Quad\","
2097 : " \"tileMatrix\":"
2098 : " ["
2099 : " {"
2100 : " \"type\": \"TileMatrixType\","
2101 : " \"identifier\": \"0\","
2102 : " \"scaleDenominator\": "
2103 : "279541132.014358,"
2104 : " \"topLeftCorner\": [-180, 90],"
2105 : " \"tileWidth\": 256,"
2106 : " \"tileHeight\": 256,"
2107 : " \"matrixWidth\": 2,"
2108 : " \"matrixHeight\": 1"
2109 : " },"
2110 : " {"
2111 : " \"type\": \"TileMatrixType\","
2112 : " \"identifier\": \"1\","
2113 : " \"scaleDenominator\": 100000000,"
2114 : " \"topLeftCorner\": [-123, 90],"
2115 : " \"tileWidth\": 128,"
2116 : " \"tileHeight\": 256,"
2117 : " \"matrixWidth\": 4,"
2118 : " \"matrixHeight\": 2,"
2119 : " \"variableMatrixWidth\": [{"
2120 : " \"type\": "
2121 : "\"VariableMatrixWidthType\","
2122 : " \"coalesce\" : 2,"
2123 : " \"minTileRow\": 0,"
2124 : " \"maxTileRow\": 1"
2125 : " }]"
2126 : " }"
2127 : " ]"
2128 1 : "}");
2129 1 : EXPECT_TRUE(poTMS != nullptr);
2130 1 : if (poTMS)
2131 : {
2132 1 : ASSERT_EQ(poTMS->tileMatrixList().size(), 2U);
2133 1 : EXPECT_TRUE(!poTMS->haveAllLevelsSameTopLeft());
2134 1 : EXPECT_TRUE(!poTMS->haveAllLevelsSameTileSize());
2135 1 : EXPECT_TRUE(!poTMS->hasOnlyPowerOfTwoVaryingScales());
2136 1 : EXPECT_TRUE(poTMS->hasVariableMatrixWidth());
2137 1 : const auto &tm = poTMS->tileMatrixList()[1];
2138 1 : EXPECT_EQ(tm.mVariableMatrixWidthList.size(), 1U);
2139 1 : const auto &vmw = tm.mVariableMatrixWidthList[0];
2140 1 : EXPECT_EQ(vmw.mCoalesce, 2);
2141 1 : EXPECT_EQ(vmw.mMinTileRow, 0);
2142 1 : EXPECT_EQ(vmw.mMaxTileRow, 1);
2143 : }
2144 : }
2145 :
2146 : {
2147 : auto poTMS = gdal::TileMatrixSet::parse(
2148 : "{"
2149 : " \"identifier\" : \"CDBGlobalGrid\","
2150 : " \"title\" : \"CDBGlobalGrid\","
2151 : " \"boundingBox\" : {"
2152 : " \"crs\" : \"http://www.opengis.net/def/crs/EPSG/0/4326\","
2153 : " \"lowerCorner\" : ["
2154 : " -90,"
2155 : " -180"
2156 : " ],"
2157 : " \"upperCorner\" : ["
2158 : " 90,"
2159 : " 180"
2160 : " ]"
2161 : " },"
2162 : " \"supportedCRS\" : "
2163 : "\"http://www.opengis.net/def/crs/EPSG/0/4326\","
2164 : " \"wellKnownScaleSet\" : "
2165 : "\"http://www.opengis.net/def/wkss/OGC/1.0/CDBGlobalGrid\","
2166 : " \"tileMatrix\" : ["
2167 : " {"
2168 : " \"identifier\" : \"-10\","
2169 : " \"scaleDenominator\" : 397569609.975977063179,"
2170 : " \"matrixWidth\" : 360,"
2171 : " \"matrixHeight\" : 180,"
2172 : " \"tileWidth\" : 1,"
2173 : " \"tileHeight\" : 1,"
2174 : " \"topLeftCorner\" : ["
2175 : " 90,"
2176 : " -180"
2177 : " ],"
2178 : " \"variableMatrixWidth\" : ["
2179 : " {"
2180 : " \"coalesce\" : 12,"
2181 : " \"minTileRow\" : 0,"
2182 : " \"maxTileRow\" : 0"
2183 : " },"
2184 : " {"
2185 : " \"coalesce\" : 12,"
2186 : " \"minTileRow\" : 179,"
2187 : " \"maxTileRow\" : 179"
2188 : " }"
2189 : " ]"
2190 : " }"
2191 : " ]"
2192 1 : "}");
2193 1 : EXPECT_TRUE(poTMS != nullptr);
2194 1 : if (poTMS)
2195 : {
2196 1 : ASSERT_EQ(poTMS->tileMatrixList().size(), 1U);
2197 1 : const auto &tm = poTMS->tileMatrixList()[0];
2198 1 : EXPECT_EQ(tm.mVariableMatrixWidthList.size(), 2U);
2199 1 : const auto &vmw = tm.mVariableMatrixWidthList[0];
2200 1 : EXPECT_EQ(vmw.mCoalesce, 12);
2201 1 : EXPECT_EQ(vmw.mMinTileRow, 0);
2202 1 : EXPECT_EQ(vmw.mMaxTileRow, 0);
2203 : }
2204 : }
2205 :
2206 : // TMS v2 (truncated version of https://maps.gnosis.earth/ogcapi/tileMatrixSets/GNOSISGlobalGrid?f=json)
2207 : {
2208 : auto poTMS = gdal::TileMatrixSet::parse(
2209 : "{"
2210 : " \"id\" : \"GNOSISGlobalGrid\","
2211 : " \"title\" : \"GNOSISGlobalGrid\","
2212 : " \"uri\" : "
2213 : "\"http://www.opengis.net/def/tilematrixset/OGC/1.0/"
2214 : "GNOSISGlobalGrid\","
2215 : " \"description\": \"added for testing\","
2216 : " \"crs\" : \"http://www.opengis.net/def/crs/EPSG/0/4326\","
2217 : " \"orderedAxes\" : ["
2218 : " \"Lat\","
2219 : " \"Lon\""
2220 : " ],"
2221 : " \"wellKnownScaleSet\" : "
2222 : "\"http://www.opengis.net/def/wkss/OGC/1.0/GoogleCRS84Quad\","
2223 : " \"tileMatrices\" : ["
2224 : " {"
2225 : " \"id\" : \"0\","
2226 : " \"scaleDenominator\" : 139770566.0071794390678,"
2227 : " \"cellSize\" : 0.3515625,"
2228 : " \"cornerOfOrigin\" : \"topLeft\","
2229 : " \"pointOfOrigin\" : [ 90, -180 ],"
2230 : " \"matrixWidth\" : 4,"
2231 : " \"matrixHeight\" : 2,"
2232 : " \"tileWidth\" : 256,"
2233 : " \"tileHeight\" : 256"
2234 : " },"
2235 : " {"
2236 : " \"id\" : \"1\","
2237 : " \"scaleDenominator\" : 69885283.0035897195339,"
2238 : " \"cellSize\" : 0.17578125,"
2239 : " \"cornerOfOrigin\" : \"topLeft\","
2240 : " \"pointOfOrigin\" : [ 90, -180 ],"
2241 : " \"matrixWidth\" : 8,"
2242 : " \"matrixHeight\" : 4,"
2243 : " \"tileWidth\" : 256,"
2244 : " \"tileHeight\" : 256,"
2245 : " \"variableMatrixWidths\" : ["
2246 : " { \"coalesce\" : 2, \"minTileRow\" : 0, "
2247 : "\"maxTileRow\" : 0 },"
2248 : " { \"coalesce\" : 2, \"minTileRow\" : 3, "
2249 : "\"maxTileRow\" : 3 }"
2250 : " ]"
2251 : " }"
2252 : " ]"
2253 1 : "}");
2254 1 : EXPECT_TRUE(poTMS != nullptr);
2255 1 : if (poTMS)
2256 : {
2257 1 : EXPECT_EQ(poTMS->title(), "GNOSISGlobalGrid");
2258 1 : EXPECT_EQ(poTMS->identifier(), "GNOSISGlobalGrid");
2259 1 : EXPECT_EQ(poTMS->abstract(), "added for testing");
2260 1 : EXPECT_EQ(poTMS->crs(),
2261 : "http://www.opengis.net/def/crs/EPSG/0/4326");
2262 1 : EXPECT_EQ(
2263 : poTMS->wellKnownScaleSet(),
2264 : "http://www.opengis.net/def/wkss/OGC/1.0/GoogleCRS84Quad");
2265 1 : ASSERT_EQ(poTMS->tileMatrixList().size(), 2U);
2266 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTopLeft());
2267 1 : EXPECT_TRUE(poTMS->haveAllLevelsSameTileSize());
2268 1 : EXPECT_TRUE(poTMS->hasOnlyPowerOfTwoVaryingScales());
2269 : {
2270 1 : const auto &tm = poTMS->tileMatrixList()[0];
2271 1 : EXPECT_EQ(tm.mId, "0");
2272 1 : EXPECT_EQ(tm.mScaleDenominator, 139770566.0071794390678);
2273 1 : EXPECT_TRUE(fabs(tm.mResX - tm.mScaleDenominator * 0.28e-3 /
2274 : (6378137. * M_PI / 180)) <
2275 : 1e-10);
2276 1 : EXPECT_EQ(tm.mResY, tm.mResX);
2277 1 : EXPECT_EQ(tm.mTopLeftX, 90.0);
2278 1 : EXPECT_EQ(tm.mTopLeftY, -180.0);
2279 1 : EXPECT_EQ(tm.mTileWidth, 256);
2280 1 : EXPECT_EQ(tm.mTileHeight, 256);
2281 1 : EXPECT_EQ(tm.mMatrixWidth, 4);
2282 1 : EXPECT_EQ(tm.mMatrixHeight, 2);
2283 : }
2284 :
2285 1 : EXPECT_TRUE(poTMS->hasVariableMatrixWidth());
2286 : {
2287 1 : const auto &tm = poTMS->tileMatrixList()[1];
2288 1 : EXPECT_EQ(tm.mVariableMatrixWidthList.size(), 2U);
2289 1 : const auto &vmw = tm.mVariableMatrixWidthList[1];
2290 1 : EXPECT_EQ(vmw.mCoalesce, 2);
2291 1 : EXPECT_EQ(vmw.mMinTileRow, 3);
2292 1 : EXPECT_EQ(vmw.mMaxTileRow, 3);
2293 : }
2294 : }
2295 : }
2296 : }
2297 :
2298 : // Test that PCIDSK GetMetadataItem() return is stable
2299 4 : TEST_F(test_gdal, PCIDSK_GetMetadataItem)
2300 : {
2301 1 : auto poDrv = GDALDriver::FromHandle(GDALGetDriverByName("PCIDSK"));
2302 1 : if (poDrv == nullptr)
2303 0 : GTEST_SKIP() << "PCIDSK driver missing";
2304 :
2305 : GDALDatasetUniquePtr poDS(
2306 2 : poDrv->Create("/vsimem/tmp.pix", 1, 1, 1, GDT_Byte, nullptr));
2307 1 : EXPECT_TRUE(poDS != nullptr);
2308 1 : poDS->SetMetadataItem("FOO", "BAR");
2309 1 : poDS->SetMetadataItem("BAR", "BAZ");
2310 1 : poDS->GetRasterBand(1)->SetMetadataItem("FOO", "BAR");
2311 1 : poDS->GetRasterBand(1)->SetMetadataItem("BAR", "BAZ");
2312 :
2313 : {
2314 1 : const char *psz1 = poDS->GetMetadataItem("FOO");
2315 1 : const char *psz2 = poDS->GetMetadataItem("BAR");
2316 1 : const char *pszNull = poDS->GetMetadataItem("I_DONT_EXIST");
2317 1 : const char *psz3 = poDS->GetMetadataItem("FOO");
2318 1 : const char *pszNull2 = poDS->GetMetadataItem("I_DONT_EXIST");
2319 1 : const char *psz4 = poDS->GetMetadataItem("BAR");
2320 1 : EXPECT_TRUE(psz1 != nullptr);
2321 1 : EXPECT_TRUE(psz2 != nullptr);
2322 1 : EXPECT_TRUE(psz3 != nullptr);
2323 1 : EXPECT_TRUE(psz4 != nullptr);
2324 1 : EXPECT_TRUE(pszNull == nullptr);
2325 1 : EXPECT_TRUE(pszNull2 == nullptr);
2326 1 : EXPECT_EQ(psz1, psz3);
2327 1 : EXPECT_TRUE(psz1 != psz2);
2328 1 : EXPECT_EQ(psz2, psz4);
2329 1 : EXPECT_STREQ(psz1, "BAR");
2330 1 : EXPECT_STREQ(psz2, "BAZ");
2331 : }
2332 :
2333 : {
2334 1 : auto poBand = poDS->GetRasterBand(1);
2335 1 : const char *psz1 = poBand->GetMetadataItem("FOO");
2336 1 : const char *psz2 = poBand->GetMetadataItem("BAR");
2337 1 : const char *pszNull = poBand->GetMetadataItem("I_DONT_EXIST");
2338 1 : const char *psz3 = poBand->GetMetadataItem("FOO");
2339 1 : const char *pszNull2 = poBand->GetMetadataItem("I_DONT_EXIST");
2340 1 : const char *psz4 = poBand->GetMetadataItem("BAR");
2341 1 : EXPECT_TRUE(psz1 != nullptr);
2342 1 : EXPECT_TRUE(psz2 != nullptr);
2343 1 : EXPECT_TRUE(psz3 != nullptr);
2344 1 : EXPECT_TRUE(psz4 != nullptr);
2345 1 : EXPECT_TRUE(pszNull == nullptr);
2346 1 : EXPECT_TRUE(pszNull2 == nullptr);
2347 1 : EXPECT_EQ(psz1, psz3);
2348 1 : EXPECT_TRUE(psz1 != psz2);
2349 1 : EXPECT_EQ(psz2, psz4);
2350 1 : EXPECT_STREQ(psz1, "BAR");
2351 1 : EXPECT_STREQ(psz2, "BAZ");
2352 : }
2353 :
2354 1 : poDS.reset();
2355 1 : VSIUnlink("/vsimem/tmp.pix");
2356 : }
2357 :
2358 : // Test GDALBufferHasOnlyNoData()
2359 4 : TEST_F(test_gdal, GDALBufferHasOnlyNoData)
2360 : {
2361 : /* bool CPL_DLL GDALBufferHasOnlyNoData(const void* pBuffer,
2362 : double dfNoDataValue,
2363 : size_t nWidth, size_t nHeight,
2364 : size_t nLineStride,
2365 : size_t nComponents,
2366 : int nBitsPerSample,
2367 : GDALBufferSampleFormat nSampleFormat);
2368 : */
2369 1 : EXPECT_TRUE(
2370 : GDALBufferHasOnlyNoData("\x00", 0.0, 1, 1, 1, 1, 8, GSF_UNSIGNED_INT));
2371 1 : EXPECT_TRUE(
2372 : !GDALBufferHasOnlyNoData("\x01", 0.0, 1, 1, 1, 1, 8, GSF_UNSIGNED_INT));
2373 1 : EXPECT_TRUE(
2374 : GDALBufferHasOnlyNoData("\x00", 0.0, 1, 1, 1, 1, 1, GSF_UNSIGNED_INT));
2375 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData("\x00\x00", 0.0, 1, 1, 1, 1, 16,
2376 : GSF_UNSIGNED_INT));
2377 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData("\x00\x01", 0.0, 1, 1, 1, 1, 16,
2378 : GSF_UNSIGNED_INT));
2379 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData("\x00\x01", 0.0, 1, 2, 2, 1, 8,
2380 : GSF_UNSIGNED_INT));
2381 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(
2382 : "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0.0, 14, 1,
2383 : 14, 1, 8, GSF_UNSIGNED_INT));
2384 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(
2385 : "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 0.0, 14, 1,
2386 : 14, 1, 8, GSF_UNSIGNED_INT));
2387 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(
2388 : "\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00", 0.0, 14, 1,
2389 : 14, 1, 8, GSF_UNSIGNED_INT));
2390 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(
2391 : "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 0.0, 14, 1,
2392 : 14, 1, 8, GSF_UNSIGNED_INT));
2393 :
2394 1 : uint8_t uint8val = 1;
2395 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&uint8val, 1.0, 1, 1, 1, 1, 8,
2396 : GSF_UNSIGNED_INT));
2397 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&uint8val, 0.0, 1, 1, 1, 1, 8,
2398 : GSF_UNSIGNED_INT));
2399 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&uint8val, 128 + 1, 1, 1, 1, 1, 8,
2400 : GSF_UNSIGNED_INT));
2401 :
2402 1 : int8_t int8val = -1;
2403 1 : EXPECT_TRUE(
2404 : GDALBufferHasOnlyNoData(&int8val, -1.0, 1, 1, 1, 1, 8, GSF_SIGNED_INT));
2405 1 : EXPECT_TRUE(
2406 : !GDALBufferHasOnlyNoData(&int8val, 0.0, 1, 1, 1, 1, 8, GSF_SIGNED_INT));
2407 1 : EXPECT_TRUE(
2408 : !GDALBufferHasOnlyNoData(&int8val, 256, 1, 1, 1, 1, 8, GSF_SIGNED_INT));
2409 :
2410 1 : uint16_t uint16val = 1;
2411 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&uint16val, 1.0, 1, 1, 1, 1, 16,
2412 : GSF_UNSIGNED_INT));
2413 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&uint16val, 0.0, 1, 1, 1, 1, 16,
2414 : GSF_UNSIGNED_INT));
2415 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&uint16val, 65536 + 1, 1, 1, 1, 1, 16,
2416 : GSF_UNSIGNED_INT));
2417 :
2418 1 : int16_t int16val = -1;
2419 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&int16val, -1.0, 1, 1, 1, 1, 16,
2420 : GSF_SIGNED_INT));
2421 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&int16val, 0.0, 1, 1, 1, 1, 16,
2422 : GSF_SIGNED_INT));
2423 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&int16val, 32768, 1, 1, 1, 1, 16,
2424 : GSF_SIGNED_INT));
2425 :
2426 1 : uint32_t uint32val = 1;
2427 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&uint32val, 1.0, 1, 1, 1, 1, 32,
2428 : GSF_UNSIGNED_INT));
2429 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&uint32val, 0.0, 1, 1, 1, 1, 32,
2430 : GSF_UNSIGNED_INT));
2431 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&uint32val,
2432 : static_cast<double>(0x100000000LL + 1),
2433 : 1, 1, 1, 1, 32, GSF_UNSIGNED_INT));
2434 :
2435 1 : int32_t int32val = -1;
2436 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&int32val, -1.0, 1, 1, 1, 1, 32,
2437 : GSF_SIGNED_INT));
2438 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&int32val, 0.0, 1, 1, 1, 1, 32,
2439 : GSF_SIGNED_INT));
2440 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&int32val, 0x80000000, 1, 1, 1, 1, 32,
2441 : GSF_SIGNED_INT));
2442 :
2443 1 : float float32val = -1;
2444 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&float32val, -1.0, 1, 1, 1, 1, 32,
2445 : GSF_FLOATING_POINT));
2446 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&float32val, 0.0, 1, 1, 1, 1, 32,
2447 : GSF_FLOATING_POINT));
2448 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&float32val, 1e50, 1, 1, 1, 1, 32,
2449 : GSF_FLOATING_POINT));
2450 :
2451 1 : float float32nan = std::numeric_limits<float>::quiet_NaN();
2452 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&float32nan, float32nan, 1, 1, 1, 1, 32,
2453 : GSF_FLOATING_POINT));
2454 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&float32nan, 0.0, 1, 1, 1, 1, 32,
2455 : GSF_FLOATING_POINT));
2456 :
2457 1 : double float64val = -1;
2458 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&float64val, -1.0, 1, 1, 1, 1, 64,
2459 : GSF_FLOATING_POINT));
2460 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&float64val, 0.0, 1, 1, 1, 1, 64,
2461 : GSF_FLOATING_POINT));
2462 :
2463 1 : double float64nan = std::numeric_limits<double>::quiet_NaN();
2464 1 : EXPECT_TRUE(GDALBufferHasOnlyNoData(&float64nan, float64nan, 1, 1, 1, 1, 64,
2465 : GSF_FLOATING_POINT));
2466 1 : EXPECT_TRUE(!GDALBufferHasOnlyNoData(&float64nan, 0.0, 1, 1, 1, 1, 64,
2467 : GSF_FLOATING_POINT));
2468 1 : }
2469 :
2470 : // Test GetRasterNoDataReplacementValue()
2471 4 : TEST_F(test_gdal, GetRasterNoDataReplacementValue)
2472 : {
2473 : // Test GDT_Byte
2474 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2475 : GDT_Byte, std::numeric_limits<double>::lowest()),
2476 : 0);
2477 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Byte,
2478 : std::numeric_limits<double>::max()),
2479 : 0);
2480 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2481 : GDT_Byte, std::numeric_limits<uint8_t>::lowest()),
2482 : std::numeric_limits<uint8_t>::lowest() + 1);
2483 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2484 : GDT_Byte, std::numeric_limits<uint8_t>::max()),
2485 : std::numeric_limits<uint8_t>::max() - 1);
2486 :
2487 : // Test GDT_Int8
2488 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2489 : GDT_Int8, std::numeric_limits<double>::lowest()),
2490 : 0);
2491 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Int8,
2492 : std::numeric_limits<double>::max()),
2493 : 0);
2494 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2495 : GDT_Int8, std::numeric_limits<int8_t>::lowest()),
2496 : std::numeric_limits<int8_t>::lowest() + 1);
2497 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Int8,
2498 : std::numeric_limits<int8_t>::max()),
2499 : std::numeric_limits<int8_t>::max() - 1);
2500 :
2501 : // Test GDT_UInt16
2502 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2503 : GDT_UInt16, std::numeric_limits<double>::lowest()),
2504 : 0);
2505 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_UInt16,
2506 : std::numeric_limits<double>::max()),
2507 : 0);
2508 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2509 : GDT_UInt16, std::numeric_limits<uint16_t>::lowest()),
2510 : std::numeric_limits<uint16_t>::lowest() + 1);
2511 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2512 : GDT_UInt16, std::numeric_limits<uint16_t>::max()),
2513 : std::numeric_limits<uint16_t>::max() - 1);
2514 :
2515 : // Test GDT_Int16
2516 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2517 : GDT_Int16, std::numeric_limits<double>::lowest()),
2518 : 0);
2519 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Int16,
2520 : std::numeric_limits<double>::max()),
2521 : 0);
2522 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2523 : GDT_Int16, std::numeric_limits<int16_t>::lowest()),
2524 : std::numeric_limits<int16_t>::lowest() + 1);
2525 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2526 : GDT_Int16, std::numeric_limits<int16_t>::max()),
2527 : std::numeric_limits<int16_t>::max() - 1);
2528 :
2529 : // Test GDT_UInt32
2530 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2531 : GDT_UInt32, std::numeric_limits<double>::lowest()),
2532 : 0);
2533 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_UInt32,
2534 : std::numeric_limits<double>::max()),
2535 : 0);
2536 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2537 : GDT_UInt32, std::numeric_limits<uint32_t>::lowest()),
2538 : std::numeric_limits<uint32_t>::lowest() + 1);
2539 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2540 : GDT_UInt32, std::numeric_limits<uint32_t>::max()),
2541 : std::numeric_limits<uint32_t>::max() - 1);
2542 :
2543 : // Test GDT_Int32
2544 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2545 : GDT_Int32, std::numeric_limits<double>::lowest()),
2546 : 0);
2547 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Int32,
2548 : std::numeric_limits<double>::max()),
2549 : 0);
2550 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2551 : GDT_Int32, std::numeric_limits<int32_t>::lowest()),
2552 : std::numeric_limits<int32_t>::lowest() + 1);
2553 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2554 : GDT_Int32, std::numeric_limits<int32_t>::max()),
2555 : std::numeric_limits<int32_t>::max() - 1);
2556 :
2557 : // Test GDT_UInt64
2558 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2559 : GDT_UInt64, std::numeric_limits<double>::lowest()),
2560 : 0);
2561 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_UInt64,
2562 : std::numeric_limits<double>::max()),
2563 : 0);
2564 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2565 : GDT_UInt64,
2566 : static_cast<double>(std::numeric_limits<uint64_t>::lowest())),
2567 : static_cast<double>(std::numeric_limits<uint64_t>::lowest()) + 1);
2568 : // uin64_t max is not representable in double so we expect the next value to be returned
2569 1 : EXPECT_EQ(
2570 : GDALGetNoDataReplacementValue(
2571 : GDT_UInt64,
2572 : static_cast<double>(std::numeric_limits<uint64_t>::max())),
2573 : std::nextafter(
2574 : static_cast<double>(std::numeric_limits<uint64_t>::max()), 0) -
2575 : 1);
2576 :
2577 : // Test GDT_Int64
2578 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2579 : GDT_Int64, std::numeric_limits<double>::lowest()),
2580 : 0);
2581 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Int64,
2582 : std::numeric_limits<double>::max()),
2583 : 0);
2584 : // in64_t max is not representable in double so we expect the next value to be returned
2585 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2586 : GDT_Int64,
2587 : static_cast<double>(std::numeric_limits<int64_t>::lowest())),
2588 : static_cast<double>(std::numeric_limits<int64_t>::lowest()) + 1);
2589 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2590 : GDT_Int64,
2591 : static_cast<double>(std::numeric_limits<int64_t>::max())),
2592 : std::nextafter(
2593 : static_cast<double>(std::numeric_limits<int64_t>::max()), 0) -
2594 : 1);
2595 :
2596 : // Test floating point types
2597 :
2598 : // out of range for float32
2599 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2600 : GDT_Float32, std::numeric_limits<double>::lowest()),
2601 : 0.0);
2602 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Float32,
2603 : std::numeric_limits<double>::max()),
2604 : 0.0);
2605 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2606 : GDT_Float32, std::numeric_limits<double>::infinity()),
2607 : 0.0);
2608 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2609 : GDT_Float32, -std::numeric_limits<double>::infinity()),
2610 : 0.0);
2611 :
2612 : // in range for float 32
2613 1 : EXPECT_EQ(
2614 : static_cast<float>(GDALGetNoDataReplacementValue(GDT_Float32, -1.0)),
2615 : std::nextafter(float(-1.0), 0.0f));
2616 1 : EXPECT_EQ(
2617 : static_cast<float>(GDALGetNoDataReplacementValue(GDT_Float32, 1.1)),
2618 : std::nextafter(float(1.1), 2.0f));
2619 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2620 : GDT_Float32, std::numeric_limits<float>::lowest()),
2621 : std::nextafter(std::numeric_limits<float>::lowest(), 0.0f));
2622 :
2623 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Float32,
2624 : std::numeric_limits<float>::max()),
2625 : static_cast<double>(
2626 : std::nextafter(std::numeric_limits<float>::max(), 0.0f)));
2627 :
2628 : // in range for float64
2629 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2630 : GDT_Float64, std::numeric_limits<double>::lowest()),
2631 : std::nextafter(std::numeric_limits<double>::lowest(), 0.0));
2632 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Float64,
2633 : std::numeric_limits<double>::max()),
2634 : std::nextafter(std::numeric_limits<double>::max(), 0.0));
2635 :
2636 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2637 : GDT_Float64, std::numeric_limits<double>::lowest()),
2638 : std::nextafter(std::numeric_limits<double>::lowest(), 0.0));
2639 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Float64,
2640 : std::numeric_limits<double>::max()),
2641 : std::nextafter(std::numeric_limits<double>::max(), 0.0));
2642 :
2643 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Float64, double(-1.0)),
2644 : std::nextafter(double(-1.0), 0.0));
2645 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(GDT_Float64, double(1.1)),
2646 : std::nextafter(double(1.1), 2.0));
2647 :
2648 : // test infinity
2649 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2650 : GDT_Float64, std::numeric_limits<double>::infinity()),
2651 : 0.0);
2652 1 : EXPECT_EQ(GDALGetNoDataReplacementValue(
2653 : GDT_Float64, -std::numeric_limits<double>::infinity()),
2654 : 0.0);
2655 1 : }
2656 :
2657 : // Test GDALRasterBand::GetIndexColorTranslationTo()
2658 4 : TEST_F(test_gdal, GetIndexColorTranslationTo)
2659 : {
2660 : GDALDatasetUniquePtr poSrcDS(
2661 : GDALDriver::FromHandle(GDALGetDriverByName("MEM"))
2662 2 : ->Create("", 1, 1, 1, GDT_Byte, nullptr));
2663 : {
2664 2 : GDALColorTable oCT;
2665 : {
2666 : GDALColorEntry e;
2667 1 : e.c1 = 0;
2668 1 : e.c2 = 0;
2669 1 : e.c3 = 0;
2670 1 : e.c4 = 255;
2671 1 : oCT.SetColorEntry(0, &e);
2672 : }
2673 : {
2674 : GDALColorEntry e;
2675 1 : e.c1 = 1;
2676 1 : e.c2 = 0;
2677 1 : e.c3 = 0;
2678 1 : e.c4 = 255;
2679 1 : oCT.SetColorEntry(1, &e);
2680 : }
2681 : {
2682 : GDALColorEntry e;
2683 1 : e.c1 = 255;
2684 1 : e.c2 = 255;
2685 1 : e.c3 = 255;
2686 1 : e.c4 = 255;
2687 1 : oCT.SetColorEntry(2, &e);
2688 : }
2689 : {
2690 : GDALColorEntry e;
2691 1 : e.c1 = 125;
2692 1 : e.c2 = 126;
2693 1 : e.c3 = 127;
2694 1 : e.c4 = 0;
2695 1 : oCT.SetColorEntry(3, &e);
2696 1 : poSrcDS->GetRasterBand(1)->SetNoDataValue(3);
2697 : }
2698 1 : poSrcDS->GetRasterBand(1)->SetColorTable(&oCT);
2699 : }
2700 :
2701 : GDALDatasetUniquePtr poDstDS(
2702 : GDALDriver::FromHandle(GDALGetDriverByName("MEM"))
2703 2 : ->Create("", 1, 1, 1, GDT_Byte, nullptr));
2704 : {
2705 2 : GDALColorTable oCT;
2706 : {
2707 : GDALColorEntry e;
2708 1 : e.c1 = 255;
2709 1 : e.c2 = 255;
2710 1 : e.c3 = 255;
2711 1 : e.c4 = 255;
2712 1 : oCT.SetColorEntry(0, &e);
2713 : }
2714 : {
2715 : GDALColorEntry e;
2716 1 : e.c1 = 0;
2717 1 : e.c2 = 0;
2718 1 : e.c3 = 1;
2719 1 : e.c4 = 255;
2720 1 : oCT.SetColorEntry(1, &e);
2721 : }
2722 : {
2723 : GDALColorEntry e;
2724 1 : e.c1 = 12;
2725 1 : e.c2 = 13;
2726 1 : e.c3 = 14;
2727 1 : e.c4 = 0;
2728 1 : oCT.SetColorEntry(2, &e);
2729 1 : poSrcDS->GetRasterBand(1)->SetNoDataValue(2);
2730 : }
2731 1 : poDstDS->GetRasterBand(1)->SetColorTable(&oCT);
2732 : }
2733 :
2734 : unsigned char *panTranslationTable =
2735 1 : poSrcDS->GetRasterBand(1)->GetIndexColorTranslationTo(
2736 : poDstDS->GetRasterBand(1));
2737 1 : EXPECT_EQ(static_cast<int>(panTranslationTable[0]), 1);
2738 1 : EXPECT_EQ(static_cast<int>(panTranslationTable[1]), 1);
2739 1 : EXPECT_EQ(static_cast<int>(panTranslationTable[2]), 0);
2740 1 : EXPECT_EQ(static_cast<int>(panTranslationTable[3]),
2741 : 2); // special nodata mapping
2742 1 : CPLFree(panTranslationTable);
2743 1 : }
2744 :
2745 : // Test effect of MarkSuppressOnClose() with the final FlushCache() at dataset
2746 : // destruction
2747 4 : TEST_F(test_gdal, MarkSuppressOnClose)
2748 : {
2749 1 : const char *pszFilename = "/vsimem/out.tif";
2750 1 : const char *const apszOptions[] = {"PROFILE=BASELINE", nullptr};
2751 : {
2752 : GDALDatasetUniquePtr poDstDS(
2753 : GDALDriver::FromHandle(GDALGetDriverByName("GTiff"))
2754 2 : ->Create(pszFilename, 1, 1, 1, GDT_Byte, apszOptions));
2755 1 : poDstDS->SetMetadataItem("FOO", "BAR");
2756 1 : poDstDS->MarkSuppressOnClose();
2757 1 : poDstDS->GetRasterBand(1)->Fill(255);
2758 1 : poDstDS->FlushCache(true);
2759 : // All buffers have been flushed, but our dirty block should not have
2760 : // been written hence the checksum will be 0
2761 1 : EXPECT_EQ(GDALChecksumImage(
2762 : GDALRasterBand::FromHandle(poDstDS->GetRasterBand(1)), 0,
2763 : 0, 1, 1),
2764 : 0);
2765 : }
2766 : {
2767 : VSIStatBufL sStat;
2768 1 : EXPECT_TRUE(VSIStatL(CPLSPrintf("%s.aux.xml", pszFilename), &sStat) !=
2769 : 0);
2770 : }
2771 1 : }
2772 :
2773 : // Test effect of UnMarkSuppressOnClose()
2774 4 : TEST_F(test_gdal, UnMarkSuppressOnClose)
2775 : {
2776 1 : const char *pszFilename = "/vsimem/out.tif";
2777 1 : const char *const apszOptions[] = {"PROFILE=BASELINE", nullptr};
2778 : {
2779 : GDALDatasetUniquePtr poDstDS(
2780 : GDALDriver::FromHandle(GDALGetDriverByName("GTiff"))
2781 2 : ->Create(pszFilename, 1, 1, 1, GDT_Byte, apszOptions));
2782 1 : poDstDS->MarkSuppressOnClose();
2783 1 : poDstDS->GetRasterBand(1)->Fill(255);
2784 1 : if (poDstDS->IsMarkedSuppressOnClose())
2785 1 : poDstDS->UnMarkSuppressOnClose();
2786 1 : poDstDS->FlushCache(true);
2787 : // All buffers have been flushed, and our dirty block should have
2788 : // been written hence the checksum will not be 0
2789 1 : EXPECT_NE(GDALChecksumImage(
2790 : GDALRasterBand::FromHandle(poDstDS->GetRasterBand(1)), 0,
2791 : 0, 1, 1),
2792 : 0);
2793 : VSIStatBufL sStat;
2794 1 : EXPECT_TRUE(VSIStatL(pszFilename, &sStat) == 0);
2795 1 : VSIUnlink(pszFilename);
2796 : }
2797 1 : }
2798 :
2799 11 : template <class T> void TestCachedPixelAccessor()
2800 : {
2801 11 : constexpr auto eType = GDALCachedPixelAccessorGetDataType<T>::DataType;
2802 22 : auto poDS = std::unique_ptr<GDALDataset>(
2803 : GDALDriver::FromHandle(GDALGetDriverByName("MEM"))
2804 : ->Create("", 11, 23, 1, eType, nullptr));
2805 11 : auto poBand = poDS->GetRasterBand(1);
2806 22 : GDALCachedPixelAccessor<T, 4> accessor(poBand);
2807 264 : for (int iY = 0; iY < poBand->GetYSize(); iY++)
2808 : {
2809 3036 : for (int iX = 0; iX < poBand->GetXSize(); iX++)
2810 : {
2811 2783 : accessor.Set(iX, iY, static_cast<T>(iY * poBand->GetXSize() + iX));
2812 : }
2813 : }
2814 264 : for (int iY = 0; iY < poBand->GetYSize(); iY++)
2815 : {
2816 3036 : for (int iX = 0; iX < poBand->GetXSize(); iX++)
2817 : {
2818 2783 : EXPECT_EQ(accessor.Get(iX, iY),
2819 : static_cast<T>(iY * poBand->GetXSize() + iX));
2820 : }
2821 : }
2822 :
2823 22 : std::vector<T> values(static_cast<size_t>(poBand->GetYSize()) *
2824 11 : poBand->GetXSize());
2825 11 : accessor.FlushCache();
2826 11 : EXPECT_EQ(poBand->RasterIO(GF_Read, 0, 0, poBand->GetXSize(),
2827 : poBand->GetYSize(), values.data(),
2828 : poBand->GetXSize(), poBand->GetYSize(), eType, 0,
2829 : 0, nullptr),
2830 : CE_None);
2831 264 : for (int iY = 0; iY < poBand->GetYSize(); iY++)
2832 : {
2833 3036 : for (int iX = 0; iX < poBand->GetXSize(); iX++)
2834 : {
2835 2783 : EXPECT_EQ(values[iY * poBand->GetXSize() + iX],
2836 : static_cast<T>(iY * poBand->GetXSize() + iX));
2837 : }
2838 : }
2839 11 : }
2840 :
2841 : // Test GDALCachedPixelAccessor
2842 4 : TEST_F(test_gdal, GDALCachedPixelAccessor)
2843 : {
2844 1 : TestCachedPixelAccessor<GByte>();
2845 1 : TestCachedPixelAccessor<GUInt16>();
2846 1 : TestCachedPixelAccessor<GInt16>();
2847 1 : TestCachedPixelAccessor<GUInt32>();
2848 1 : TestCachedPixelAccessor<GInt32>();
2849 1 : TestCachedPixelAccessor<GUInt64>();
2850 1 : TestCachedPixelAccessor<GInt64>();
2851 1 : TestCachedPixelAccessor<uint64_t>();
2852 1 : TestCachedPixelAccessor<int64_t>();
2853 1 : TestCachedPixelAccessor<float>();
2854 1 : TestCachedPixelAccessor<double>();
2855 1 : }
2856 :
2857 : // Test VRT and caching of sources w.r.t open options
2858 : // (https://github.com/OSGeo/gdal/issues/5989)
2859 4 : TEST_F(test_gdal, VRTCachingOpenOptions)
2860 : {
2861 : class TestRasterBand : public GDALRasterBand
2862 : {
2863 : protected:
2864 3 : CPLErr IReadBlock(int, int, void *pImage) override
2865 : {
2866 3 : static_cast<GByte *>(pImage)[0] = 0;
2867 3 : return CE_None;
2868 : }
2869 :
2870 : public:
2871 3 : TestRasterBand()
2872 3 : {
2873 3 : nBlockXSize = 1;
2874 3 : nBlockYSize = 1;
2875 3 : eDataType = GDT_Byte;
2876 3 : }
2877 : };
2878 :
2879 : static int nCountZeroOpenOptions = 0;
2880 : static int nCountWithOneOpenOptions = 0;
2881 :
2882 : class TestDataset : public GDALDataset
2883 : {
2884 : public:
2885 3 : TestDataset()
2886 3 : {
2887 3 : nRasterXSize = 1;
2888 3 : nRasterYSize = 1;
2889 3 : SetBand(1, new TestRasterBand());
2890 3 : }
2891 :
2892 3 : static GDALDataset *TestOpen(GDALOpenInfo *poOpenInfo)
2893 : {
2894 3 : if (strcmp(poOpenInfo->pszFilename, ":::DUMMY:::") != 0)
2895 0 : return nullptr;
2896 3 : if (poOpenInfo->papszOpenOptions == nullptr)
2897 1 : nCountZeroOpenOptions++;
2898 : else
2899 2 : nCountWithOneOpenOptions++;
2900 3 : return new TestDataset();
2901 : }
2902 : };
2903 :
2904 2 : std::unique_ptr<GDALDriver> driver(new GDALDriver());
2905 1 : driver->SetDescription("TEST_VRT_SOURCE_OPEN_OPTION");
2906 1 : driver->pfnOpen = TestDataset::TestOpen;
2907 1 : GetGDALDriverManager()->RegisterDriver(driver.get());
2908 :
2909 1 : const char *pszVRT = R"(
2910 : <VRTDataset rasterXSize="1" rasterYSize="1">
2911 : <VRTRasterBand dataType="Byte" band="1" subClass="VRTSourcedRasterBand">
2912 : <SimpleSource>
2913 : <SourceFilename relativeToVRT="0">:::DUMMY:::</SourceFilename>
2914 : </SimpleSource>
2915 : <SimpleSource>
2916 : <SourceFilename relativeToVRT="0">:::DUMMY:::</SourceFilename>
2917 : </SimpleSource>
2918 : <SimpleSource>
2919 : <SourceFilename relativeToVRT="0">:::DUMMY:::</SourceFilename>
2920 : <OpenOptions>
2921 : <OOI key="TESTARG">present</OOI>
2922 : </OpenOptions>
2923 : </SimpleSource>
2924 : <SimpleSource>
2925 : <SourceFilename relativeToVRT="0">:::DUMMY:::</SourceFilename>
2926 : <OpenOptions>
2927 : <OOI key="TESTARG">present</OOI>
2928 : </OpenOptions>
2929 : </SimpleSource>
2930 : <SimpleSource>
2931 : <SourceFilename relativeToVRT="0">:::DUMMY:::</SourceFilename>
2932 : <OpenOptions>
2933 : <OOI key="TESTARG">another_one</OOI>
2934 : </OpenOptions>
2935 : </SimpleSource>
2936 : </VRTRasterBand>
2937 : </VRTDataset>)";
2938 2 : auto ds = std::unique_ptr<GDALDataset>(GDALDataset::Open(pszVRT));
2939 :
2940 : // Trigger reading data, which triggers opening of source datasets
2941 1 : auto rb = ds->GetRasterBand(1);
2942 : double minmax[2];
2943 1 : GDALComputeRasterMinMax(GDALRasterBand::ToHandle(rb), TRUE, minmax);
2944 :
2945 1 : ds.reset();
2946 1 : GetGDALDriverManager()->DeregisterDriver(driver.get());
2947 :
2948 1 : EXPECT_EQ(nCountZeroOpenOptions, 1);
2949 1 : EXPECT_EQ(nCountWithOneOpenOptions, 2);
2950 1 : }
2951 :
2952 : // Test GDALDeinterleave 3 components Byte()
2953 4 : TEST_F(test_gdal, GDALDeinterleave3ComponentsByte)
2954 : {
2955 1 : GByte *pabySrc = static_cast<GByte *>(CPLMalloc(3 * 4 * 15));
2956 181 : for (int i = 0; i < 3 * 4 * 15; i++)
2957 180 : pabySrc[i] = static_cast<GByte>(i);
2958 1 : GByte *pabyDest0 = static_cast<GByte *>(CPLMalloc(4 * 15));
2959 1 : GByte *pabyDest1 = static_cast<GByte *>(CPLMalloc(4 * 15));
2960 1 : GByte *pabyDest2 = static_cast<GByte *>(CPLMalloc(4 * 15));
2961 1 : void *ppabyDest[] = {pabyDest0, pabyDest1, pabyDest2};
2962 3 : for (int nIters : {1, 4 * 15})
2963 : {
2964 2 : GDALDeinterleave(pabySrc, GDT_Byte, 3, ppabyDest, GDT_Byte, nIters);
2965 63 : for (int i = 0; i < nIters; i++)
2966 : {
2967 61 : EXPECT_EQ(pabyDest0[i], 3 * i);
2968 61 : EXPECT_EQ(pabyDest1[i], 3 * i + 1);
2969 61 : EXPECT_EQ(pabyDest2[i], 3 * i + 2);
2970 : }
2971 : }
2972 1 : VSIFree(pabySrc);
2973 1 : VSIFree(pabyDest0);
2974 1 : VSIFree(pabyDest1);
2975 1 : VSIFree(pabyDest2);
2976 1 : }
2977 :
2978 : // Test GDALDeinterleave 3 components Byte() without SSSE3
2979 4 : TEST_F(test_gdal, GDALDeinterleave3ComponentsByte_NOSSE3)
2980 : {
2981 1 : GByte *pabySrc = static_cast<GByte *>(CPLMalloc(3 * 4 * 15));
2982 181 : for (int i = 0; i < 3 * 4 * 15; i++)
2983 180 : pabySrc[i] = static_cast<GByte>(i);
2984 1 : GByte *pabyDest0 = static_cast<GByte *>(CPLMalloc(4 * 15));
2985 1 : GByte *pabyDest1 = static_cast<GByte *>(CPLMalloc(4 * 15));
2986 1 : GByte *pabyDest2 = static_cast<GByte *>(CPLMalloc(4 * 15));
2987 1 : void *ppabyDest[] = {pabyDest0, pabyDest1, pabyDest2};
2988 3 : for (int nIters : {1, 4 * 15})
2989 : {
2990 2 : CPLSetConfigOption("GDAL_USE_SSSE3", "NO");
2991 2 : GDALDeinterleave(pabySrc, GDT_Byte, 3, ppabyDest, GDT_Byte, nIters);
2992 2 : CPLSetConfigOption("GDAL_USE_SSSE3", nullptr);
2993 63 : for (int i = 0; i < nIters; i++)
2994 : {
2995 61 : EXPECT_EQ(pabyDest0[i], 3 * i);
2996 61 : EXPECT_EQ(pabyDest1[i], 3 * i + 1);
2997 61 : EXPECT_EQ(pabyDest2[i], 3 * i + 2);
2998 : }
2999 : }
3000 1 : VSIFree(pabySrc);
3001 1 : VSIFree(pabyDest0);
3002 1 : VSIFree(pabyDest1);
3003 1 : VSIFree(pabyDest2);
3004 1 : }
3005 :
3006 : // Test GDALDeinterleave 4 components Byte()
3007 4 : TEST_F(test_gdal, GDALDeinterleave4ComponentsByte)
3008 : {
3009 1 : GByte *pabySrc = static_cast<GByte *>(CPLMalloc(3 * 4 * 15));
3010 181 : for (int i = 0; i < 3 * 4 * 15; i++)
3011 180 : pabySrc[i] = static_cast<GByte>(i);
3012 1 : GByte *pabyDest0 = static_cast<GByte *>(CPLMalloc(3 * 15));
3013 1 : GByte *pabyDest1 = static_cast<GByte *>(CPLMalloc(3 * 15));
3014 1 : GByte *pabyDest2 = static_cast<GByte *>(CPLMalloc(3 * 15));
3015 1 : GByte *pabyDest3 = static_cast<GByte *>(CPLMalloc(3 * 15));
3016 1 : void *ppabyDest[] = {pabyDest0, pabyDest1, pabyDest2, pabyDest3};
3017 3 : for (int nIters : {1, 3 * 15})
3018 : {
3019 2 : GDALDeinterleave(pabySrc, GDT_Byte, 4, ppabyDest, GDT_Byte, nIters);
3020 48 : for (int i = 0; i < nIters; i++)
3021 : {
3022 46 : EXPECT_EQ(pabyDest0[i], 4 * i);
3023 46 : EXPECT_EQ(pabyDest1[i], 4 * i + 1);
3024 46 : EXPECT_EQ(pabyDest2[i], 4 * i + 2);
3025 46 : EXPECT_EQ(pabyDest3[i], 4 * i + 3);
3026 : }
3027 : }
3028 1 : VSIFree(pabySrc);
3029 1 : VSIFree(pabyDest0);
3030 1 : VSIFree(pabyDest1);
3031 1 : VSIFree(pabyDest2);
3032 1 : VSIFree(pabyDest3);
3033 1 : }
3034 :
3035 : // Test GDALDeinterleave 4 components Byte without SSSE3
3036 4 : TEST_F(test_gdal, GDALDeinterleave4ComponentsByte_NOSSE3)
3037 : {
3038 1 : GByte *pabySrc = static_cast<GByte *>(CPLMalloc(3 * 4 * 15));
3039 181 : for (int i = 0; i < 3 * 4 * 15; i++)
3040 180 : pabySrc[i] = static_cast<GByte>(i);
3041 1 : GByte *pabyDest0 = static_cast<GByte *>(CPLMalloc(3 * 15));
3042 1 : GByte *pabyDest1 = static_cast<GByte *>(CPLMalloc(3 * 15));
3043 1 : GByte *pabyDest2 = static_cast<GByte *>(CPLMalloc(3 * 15));
3044 1 : GByte *pabyDest3 = static_cast<GByte *>(CPLMalloc(3 * 15));
3045 1 : void *ppabyDest[] = {pabyDest0, pabyDest1, pabyDest2, pabyDest3};
3046 3 : for (int nIters : {1, 3 * 15})
3047 : {
3048 2 : CPLSetConfigOption("GDAL_USE_SSSE3", "NO");
3049 2 : GDALDeinterleave(pabySrc, GDT_Byte, 4, ppabyDest, GDT_Byte, nIters);
3050 2 : CPLSetConfigOption("GDAL_USE_SSSE3", nullptr);
3051 48 : for (int i = 0; i < nIters; i++)
3052 : {
3053 46 : EXPECT_EQ(pabyDest0[i], 4 * i);
3054 46 : EXPECT_EQ(pabyDest1[i], 4 * i + 1);
3055 46 : EXPECT_EQ(pabyDest2[i], 4 * i + 2);
3056 46 : EXPECT_EQ(pabyDest3[i], 4 * i + 3);
3057 : }
3058 : }
3059 1 : VSIFree(pabySrc);
3060 1 : VSIFree(pabyDest0);
3061 1 : VSIFree(pabyDest1);
3062 1 : VSIFree(pabyDest2);
3063 1 : VSIFree(pabyDest3);
3064 1 : }
3065 :
3066 : // Test GDALDeinterleave general case
3067 4 : TEST_F(test_gdal, GDALDeinterleaveGeneralCase)
3068 : {
3069 1 : GByte *pabySrc = static_cast<GByte *>(CPLMalloc(3 * 2));
3070 7 : for (int i = 0; i < 3 * 2; i++)
3071 6 : pabySrc[i] = static_cast<GByte>(i);
3072 1 : GUInt16 *panDest0 = static_cast<GUInt16 *>(CPLMalloc(3 * sizeof(uint16_t)));
3073 1 : GUInt16 *panDest1 = static_cast<GUInt16 *>(CPLMalloc(3 * sizeof(uint16_t)));
3074 1 : void *ppanDest[] = {panDest0, panDest1};
3075 1 : GDALDeinterleave(pabySrc, GDT_Byte, 2, ppanDest, GDT_UInt16, 3);
3076 4 : for (int i = 0; i < 3; i++)
3077 : {
3078 3 : EXPECT_EQ(panDest0[i], 2 * i);
3079 3 : EXPECT_EQ(panDest1[i], 2 * i + 1);
3080 : }
3081 1 : VSIFree(pabySrc);
3082 1 : VSIFree(panDest0);
3083 1 : VSIFree(panDest1);
3084 1 : }
3085 :
3086 : // Test GDALDeinterleave 3 components UInt16()
3087 4 : TEST_F(test_gdal, GDALDeinterleave3ComponentsUInt16)
3088 : {
3089 : GUInt16 *panSrc =
3090 1 : static_cast<GUInt16 *>(CPLMalloc(3 * 4 * 15 * sizeof(GUInt16)));
3091 181 : for (int i = 0; i < 3 * 4 * 15; i++)
3092 180 : panSrc[i] = static_cast<GUInt16>(i + 32767);
3093 : GUInt16 *panDest0 =
3094 1 : static_cast<GUInt16 *>(CPLMalloc(4 * 15 * sizeof(GUInt16)));
3095 : GUInt16 *panDest1 =
3096 1 : static_cast<GUInt16 *>(CPLMalloc(4 * 15 * sizeof(GUInt16)));
3097 : GUInt16 *panDest2 =
3098 1 : static_cast<GUInt16 *>(CPLMalloc(4 * 15 * sizeof(GUInt16)));
3099 1 : void *ppanDest[] = {panDest0, panDest1, panDest2};
3100 3 : for (int nIters : {1, 4 * 15})
3101 : {
3102 2 : GDALDeinterleave(panSrc, GDT_UInt16, 3, ppanDest, GDT_UInt16, nIters);
3103 63 : for (int i = 0; i < nIters; i++)
3104 : {
3105 61 : EXPECT_EQ(panDest0[i], 3 * i + 32767);
3106 61 : EXPECT_EQ(panDest1[i], 3 * i + 1 + 32767);
3107 61 : EXPECT_EQ(panDest2[i], 3 * i + 2 + 32767);
3108 : }
3109 : }
3110 1 : VSIFree(panSrc);
3111 1 : VSIFree(panDest0);
3112 1 : VSIFree(panDest1);
3113 1 : VSIFree(panDest2);
3114 1 : }
3115 :
3116 : // Test GDALDeinterleave 4 components UInt16()
3117 4 : TEST_F(test_gdal, GDALDeinterleave4ComponentsUInt16)
3118 : {
3119 : GUInt16 *panSrc =
3120 1 : static_cast<GUInt16 *>(CPLMalloc(3 * 4 * 15 * sizeof(GUInt16)));
3121 181 : for (int i = 0; i < 3 * 4 * 15; i++)
3122 180 : panSrc[i] = static_cast<GUInt16>(i + 32767);
3123 : GUInt16 *panDest0 =
3124 1 : static_cast<GUInt16 *>(CPLMalloc(4 * 15 * sizeof(GUInt16)));
3125 : GUInt16 *panDest1 =
3126 1 : static_cast<GUInt16 *>(CPLMalloc(4 * 15 * sizeof(GUInt16)));
3127 : GUInt16 *panDest2 =
3128 1 : static_cast<GUInt16 *>(CPLMalloc(4 * 15 * sizeof(GUInt16)));
3129 : GUInt16 *panDest3 =
3130 1 : static_cast<GUInt16 *>(CPLMalloc(4 * 15 * sizeof(GUInt16)));
3131 1 : void *ppanDest[] = {panDest0, panDest1, panDest2, panDest3};
3132 3 : for (int nIters : {1, 3 * 15})
3133 : {
3134 2 : GDALDeinterleave(panSrc, GDT_UInt16, 4, ppanDest, GDT_UInt16, nIters);
3135 48 : for (int i = 0; i < nIters; i++)
3136 : {
3137 46 : EXPECT_EQ(panDest0[i], 4 * i + 32767);
3138 46 : EXPECT_EQ(panDest1[i], 4 * i + 1 + 32767);
3139 46 : EXPECT_EQ(panDest2[i], 4 * i + 2 + 32767);
3140 46 : EXPECT_EQ(panDest3[i], 4 * i + 3 + 32767);
3141 : }
3142 : }
3143 1 : VSIFree(panSrc);
3144 1 : VSIFree(panDest0);
3145 1 : VSIFree(panDest1);
3146 1 : VSIFree(panDest2);
3147 1 : VSIFree(panDest3);
3148 1 : }
3149 :
3150 : // Test GDALDataset::ReportError()
3151 4 : TEST_F(test_gdal, GDALDatasetReportError)
3152 : {
3153 : GDALDatasetUniquePtr poSrcDS(
3154 : GDALDriver::FromHandle(GDALGetDriverByName("MEM"))
3155 2 : ->Create("", 1, 1, 1, GDT_Byte, nullptr));
3156 :
3157 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
3158 1 : poSrcDS->ReportError("foo", CE_Warning, CPLE_AppDefined, "bar");
3159 1 : CPLPopErrorHandler();
3160 1 : EXPECT_STREQ(CPLGetLastErrorMsg(), "foo: bar");
3161 :
3162 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
3163 1 : poSrcDS->ReportError("%foo", CE_Warning, CPLE_AppDefined, "bar");
3164 1 : CPLPopErrorHandler();
3165 1 : EXPECT_STREQ(CPLGetLastErrorMsg(), "%foo: bar");
3166 :
3167 1 : CPLPushErrorHandler(CPLQuietErrorHandler);
3168 1 : poSrcDS->ReportError(
3169 : "this_is_"
3170 : "wayyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3171 : "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3172 : "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3173 : "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3174 : "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3175 : "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3176 : "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3177 : "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
3178 : "yyyyyyy_too_long/foo",
3179 1 : CE_Warning, CPLE_AppDefined, "bar");
3180 1 : CPLPopErrorHandler();
3181 1 : EXPECT_STREQ(CPLGetLastErrorMsg(), "foo: bar");
3182 1 : }
3183 :
3184 : // Test GDALDataset::GetCompressionFormats() and ReadCompressedData()
3185 4 : TEST_F(test_gdal, gtiff_ReadCompressedData)
3186 : {
3187 1 : if (GDALGetDriverByName("JPEG") == nullptr)
3188 : {
3189 0 : GTEST_SKIP() << "JPEG support missing";
3190 : }
3191 :
3192 : GDALDatasetUniquePtr poSrcDS(GDALDataset::FromHandle(
3193 1 : GDALDataset::Open((tut::common::data_basedir +
3194 : "/../../gcore/data/byte_jpg_unusual_jpegtable.tif")
3195 1 : .c_str())));
3196 1 : ASSERT_TRUE(poSrcDS);
3197 :
3198 : const CPLStringList aosRet(GDALDatasetGetCompressionFormats(
3199 1 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0, 20, 20, 1, nullptr));
3200 1 : EXPECT_EQ(aosRet.size(), 1);
3201 1 : if (aosRet.size() == 1)
3202 : {
3203 1 : EXPECT_STREQ(aosRet[0], "JPEG");
3204 : }
3205 :
3206 : {
3207 1 : int nBand = 1;
3208 1 : EXPECT_EQ(CPLStringList(GDALDatasetGetCompressionFormats(
3209 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0,
3210 : 20, 20, 1, &nBand))
3211 : .size(),
3212 : 1);
3213 : }
3214 :
3215 : // nBandCout > nBands
3216 1 : EXPECT_EQ(CPLStringList(GDALDatasetGetCompressionFormats(
3217 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0, 20,
3218 : 20, 2, nullptr))
3219 : .size(),
3220 : 0);
3221 :
3222 : // Cannot subset just one pixel
3223 1 : EXPECT_EQ(CPLStringList(GDALDatasetGetCompressionFormats(
3224 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0, 1,
3225 : 1, 1, nullptr))
3226 : .size(),
3227 : 0);
3228 :
3229 : // Wrong band number
3230 : {
3231 1 : int nBand = 2;
3232 1 : EXPECT_EQ(CPLStringList(GDALDatasetGetCompressionFormats(
3233 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0,
3234 : 20, 20, 1, &nBand))
3235 : .size(),
3236 : 0);
3237 : }
3238 :
3239 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3240 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 20, 20, 1,
3241 : nullptr, nullptr, nullptr, nullptr),
3242 : CE_None);
3243 :
3244 : size_t nNeededSize;
3245 : {
3246 1 : char *pszDetailedFormat = nullptr;
3247 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3248 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 20,
3249 : 20, 1, nullptr, nullptr, &nNeededSize,
3250 : &pszDetailedFormat),
3251 : CE_None);
3252 1 : EXPECT_EQ(nNeededSize, 476);
3253 1 : EXPECT_TRUE(pszDetailedFormat != nullptr);
3254 1 : if (pszDetailedFormat)
3255 : {
3256 1 : ASSERT_STREQ(pszDetailedFormat, "JPEG");
3257 1 : VSIFree(pszDetailedFormat);
3258 : }
3259 : }
3260 :
3261 : {
3262 1 : const GByte abyCanary[] = {0xDE, 0xAD, 0xBE, 0xEF};
3263 1 : std::vector<GByte> abyBuffer(nNeededSize + sizeof(abyCanary));
3264 1 : memcpy(&abyBuffer[nNeededSize], abyCanary, sizeof(abyCanary));
3265 1 : void *pabyBuffer = abyBuffer.data();
3266 1 : void **ppabyBuffer = &pabyBuffer;
3267 1 : size_t nProvidedSize = nNeededSize;
3268 1 : char *pszDetailedFormat = nullptr;
3269 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3270 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 20,
3271 : 20, 1, nullptr, ppabyBuffer, &nProvidedSize,
3272 : &pszDetailedFormat),
3273 : CE_None);
3274 1 : ASSERT_EQ(nProvidedSize, nNeededSize);
3275 1 : ASSERT_TRUE(*ppabyBuffer == pabyBuffer);
3276 1 : EXPECT_TRUE(pszDetailedFormat != nullptr);
3277 1 : if (pszDetailedFormat)
3278 : {
3279 1 : ASSERT_STREQ(pszDetailedFormat,
3280 : "JPEG;frame_type=SOF0_baseline;bit_depth=8;num_"
3281 : "components=1;colorspace=unknown");
3282 1 : VSIFree(pszDetailedFormat);
3283 : }
3284 1 : EXPECT_TRUE(
3285 : memcmp(&abyBuffer[nNeededSize], abyCanary, sizeof(abyCanary)) == 0);
3286 1 : EXPECT_EQ(abyBuffer[0], 0xFF);
3287 1 : EXPECT_EQ(abyBuffer[1], 0xD8);
3288 1 : EXPECT_EQ(abyBuffer[nNeededSize - 2], 0xFF);
3289 1 : EXPECT_EQ(abyBuffer[nNeededSize - 1], 0xD9);
3290 :
3291 : // Buffer larger than needed: OK
3292 1 : nProvidedSize = nNeededSize + 1;
3293 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3294 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 20,
3295 : 20, 1, nullptr, ppabyBuffer, &nProvidedSize, nullptr),
3296 : CE_None);
3297 :
3298 : // Too small buffer
3299 1 : nProvidedSize = nNeededSize - 1;
3300 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3301 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 20,
3302 : 20, 1, nullptr, ppabyBuffer, &nProvidedSize, nullptr),
3303 : CE_Failure);
3304 :
3305 : // Missing pointer to size
3306 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3307 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 20,
3308 : 20, 1, nullptr, ppabyBuffer, nullptr, nullptr),
3309 : CE_Failure);
3310 : }
3311 :
3312 : // Let GDAL allocate buffer
3313 : {
3314 1 : void *pBuffer = nullptr;
3315 1 : size_t nGotSize = 0;
3316 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3317 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 20,
3318 : 20, 1, nullptr, &pBuffer, &nGotSize, nullptr),
3319 : CE_None);
3320 1 : EXPECT_EQ(nGotSize, nNeededSize);
3321 1 : EXPECT_NE(pBuffer, nullptr);
3322 1 : if (pBuffer != nullptr && nGotSize == nNeededSize)
3323 : {
3324 1 : const GByte *pabyBuffer = static_cast<GByte *>(pBuffer);
3325 1 : EXPECT_EQ(pabyBuffer[0], 0xFF);
3326 1 : EXPECT_EQ(pabyBuffer[1], 0xD8);
3327 1 : EXPECT_EQ(pabyBuffer[nNeededSize - 2], 0xFF);
3328 1 : EXPECT_EQ(pabyBuffer[nNeededSize - 1], 0xD9);
3329 : }
3330 1 : VSIFree(pBuffer);
3331 : }
3332 :
3333 : // Cannot subset just one pixel
3334 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3335 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 1, 1, 1,
3336 : nullptr, nullptr, nullptr, nullptr),
3337 : CE_Failure);
3338 :
3339 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3340 : GDALDataset::ToHandle(poSrcDS.get()), "wrong_format", 0, 0,
3341 : 20, 20, 1, nullptr, nullptr, nullptr, nullptr),
3342 : CE_Failure);
3343 : }
3344 :
3345 : // Test GDALDataset::GetCompressionFormats() and ReadCompressedData()
3346 4 : TEST_F(test_gdal, gtiff_ReadCompressedData_jpeg_rgba)
3347 : {
3348 1 : if (GDALGetDriverByName("JPEG") == nullptr)
3349 : {
3350 0 : GTEST_SKIP() << "JPEG support missing";
3351 : }
3352 :
3353 : GDALDatasetUniquePtr poSrcDS(GDALDataset::FromHandle(
3354 1 : GDALDataset::Open((tut::common::data_basedir +
3355 : "/../../gcore/data/stefan_full_rgba_jpeg_contig.tif")
3356 1 : .c_str())));
3357 1 : ASSERT_TRUE(poSrcDS);
3358 :
3359 : const CPLStringList aosRet(GDALDatasetGetCompressionFormats(
3360 1 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0, 162, 16, 4, nullptr));
3361 1 : EXPECT_EQ(aosRet.size(), 1);
3362 1 : if (aosRet.size() == 1)
3363 : {
3364 1 : EXPECT_STREQ(aosRet[0], "JPEG;colorspace=RGBA");
3365 : }
3366 :
3367 : // Let GDAL allocate buffer
3368 : {
3369 1 : void *pBuffer = nullptr;
3370 1 : size_t nGotSize = 0;
3371 1 : char *pszDetailedFormat = nullptr;
3372 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3373 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 162,
3374 : 16, 4, nullptr, &pBuffer, &nGotSize, &pszDetailedFormat),
3375 : CE_None);
3376 1 : if (pszDetailedFormat)
3377 : {
3378 1 : ASSERT_STREQ(pszDetailedFormat,
3379 : "JPEG;frame_type=SOF0_baseline;bit_depth=8;num_"
3380 : "components=4;colorspace=RGBA");
3381 1 : VSIFree(pszDetailedFormat);
3382 : }
3383 1 : VSIFree(pBuffer);
3384 : }
3385 : }
3386 :
3387 : // Test GDALDataset::GetCompressionFormats() and ReadCompressedData()
3388 4 : TEST_F(test_gdal, jpeg_ReadCompressedData)
3389 : {
3390 1 : if (GDALGetDriverByName("JPEG") == nullptr)
3391 : {
3392 0 : GTEST_SKIP() << "JPEG support missing";
3393 : }
3394 :
3395 1 : GDALDatasetUniquePtr poSrcDS(GDALDataset::FromHandle(GDALDataset::Open(
3396 1 : (tut::common::data_basedir + "/../../gdrivers/data/jpeg/albania.jpg")
3397 1 : .c_str())));
3398 1 : ASSERT_TRUE(poSrcDS);
3399 :
3400 : const CPLStringList aosRet(GDALDatasetGetCompressionFormats(
3401 1 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0, 361, 260, 3, nullptr));
3402 1 : EXPECT_EQ(aosRet.size(), 1);
3403 1 : if (aosRet.size() == 1)
3404 : {
3405 1 : EXPECT_STREQ(aosRet[0],
3406 : "JPEG;frame_type=SOF0_baseline;bit_depth=8;num_components="
3407 : "3;subsampling=4:2:0;colorspace=YCbCr");
3408 : }
3409 :
3410 : size_t nUpperBoundSize;
3411 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3412 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 361, 260,
3413 : 3, nullptr, nullptr, &nUpperBoundSize, nullptr),
3414 : CE_None);
3415 1 : EXPECT_EQ(nUpperBoundSize, 12574);
3416 :
3417 : {
3418 1 : std::vector<GByte> abyBuffer(nUpperBoundSize);
3419 1 : void *pabyBuffer = abyBuffer.data();
3420 1 : void **ppabyBuffer = &pabyBuffer;
3421 1 : size_t nSize = nUpperBoundSize;
3422 1 : char *pszDetailedFormat = nullptr;
3423 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3424 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 361,
3425 : 260, 3, nullptr, ppabyBuffer, &nSize, &pszDetailedFormat),
3426 : CE_None);
3427 1 : ASSERT_LT(nSize, nUpperBoundSize);
3428 1 : ASSERT_TRUE(*ppabyBuffer == pabyBuffer);
3429 1 : EXPECT_TRUE(pszDetailedFormat != nullptr);
3430 1 : if (pszDetailedFormat)
3431 : {
3432 1 : ASSERT_STREQ(pszDetailedFormat,
3433 : "JPEG;frame_type=SOF0_baseline;bit_depth=8;num_"
3434 : "components=3;subsampling=4:2:0;colorspace=YCbCr");
3435 1 : VSIFree(pszDetailedFormat);
3436 : }
3437 1 : EXPECT_EQ(abyBuffer[0], 0xFF);
3438 1 : EXPECT_EQ(abyBuffer[1], 0xD8);
3439 1 : EXPECT_EQ(abyBuffer[nSize - 2], 0xFF);
3440 1 : EXPECT_EQ(abyBuffer[nSize - 1], 0xD9);
3441 :
3442 : // Buffer larger than needed: OK
3443 1 : nSize = nUpperBoundSize + 1;
3444 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3445 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 361,
3446 : 260, 3, nullptr, ppabyBuffer, &nSize, nullptr),
3447 : CE_None);
3448 :
3449 : // Too small buffer
3450 1 : nSize = nUpperBoundSize - 1;
3451 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3452 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 361,
3453 : 260, 3, nullptr, ppabyBuffer, &nSize, nullptr),
3454 : CE_Failure);
3455 :
3456 : // Missing pointer to size
3457 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3458 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 361,
3459 : 260, 3, nullptr, ppabyBuffer, nullptr, nullptr),
3460 : CE_Failure);
3461 : }
3462 :
3463 : // Let GDAL allocate buffer
3464 : {
3465 1 : void *pBuffer = nullptr;
3466 1 : size_t nSize = nUpperBoundSize;
3467 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3468 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 361,
3469 : 260, 3, nullptr, &pBuffer, &nSize, nullptr),
3470 : CE_None);
3471 1 : EXPECT_GT(nSize, 4);
3472 1 : EXPECT_LT(nSize, nUpperBoundSize);
3473 1 : EXPECT_NE(pBuffer, nullptr);
3474 1 : if (pBuffer != nullptr && nSize >= 4 && nSize <= nUpperBoundSize)
3475 : {
3476 1 : const GByte *pabyBuffer = static_cast<GByte *>(pBuffer);
3477 1 : EXPECT_EQ(pabyBuffer[0], 0xFF);
3478 1 : EXPECT_EQ(pabyBuffer[1], 0xD8);
3479 1 : EXPECT_EQ(pabyBuffer[nSize - 2], 0xFF);
3480 1 : EXPECT_EQ(pabyBuffer[nSize - 1], 0xD9);
3481 : }
3482 1 : VSIFree(pBuffer);
3483 : }
3484 : }
3485 :
3486 : // Test GDALDataset::GetCompressionFormats() and ReadCompressedData()
3487 4 : TEST_F(test_gdal, jpegxl_ReadCompressedData)
3488 : {
3489 1 : if (GDALGetDriverByName("JPEGXL") == nullptr)
3490 : {
3491 0 : GTEST_SKIP() << "JPEGXL support missing";
3492 : }
3493 :
3494 1 : GDALDatasetUniquePtr poSrcDS(GDALDataset::FromHandle(GDALDataset::Open(
3495 1 : (tut::common::data_basedir + "/../../gdrivers/data/jpegxl/byte.jxl")
3496 1 : .c_str())));
3497 1 : ASSERT_TRUE(poSrcDS);
3498 :
3499 : const CPLStringList aosRet(GDALDatasetGetCompressionFormats(
3500 1 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0, 20, 20, 1, nullptr));
3501 1 : EXPECT_EQ(aosRet.size(), 1);
3502 1 : if (aosRet.size() == 1)
3503 : {
3504 1 : EXPECT_STREQ(aosRet[0], "JXL");
3505 : }
3506 :
3507 : size_t nUpperBoundSize;
3508 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3509 : GDALDataset::ToHandle(poSrcDS.get()), "JXL", 0, 0, 20, 20, 1,
3510 : nullptr, nullptr, &nUpperBoundSize, nullptr),
3511 : CE_None);
3512 1 : EXPECT_EQ(nUpperBoundSize, 719);
3513 :
3514 : {
3515 1 : std::vector<GByte> abyBuffer(nUpperBoundSize);
3516 1 : void *pabyBuffer = abyBuffer.data();
3517 1 : void **ppabyBuffer = &pabyBuffer;
3518 1 : size_t nSize = nUpperBoundSize;
3519 1 : char *pszDetailedFormat = nullptr;
3520 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3521 : GDALDataset::ToHandle(poSrcDS.get()), "JXL", 0, 0, 20, 20,
3522 : 1, nullptr, ppabyBuffer, &nSize, &pszDetailedFormat),
3523 : CE_None);
3524 1 : ASSERT_LT(nSize, nUpperBoundSize);
3525 1 : ASSERT_TRUE(*ppabyBuffer == pabyBuffer);
3526 1 : EXPECT_TRUE(pszDetailedFormat != nullptr);
3527 1 : if (pszDetailedFormat)
3528 : {
3529 1 : ASSERT_STREQ(pszDetailedFormat, "JXL");
3530 1 : VSIFree(pszDetailedFormat);
3531 : }
3532 1 : EXPECT_EQ(abyBuffer[0], 0x00);
3533 1 : EXPECT_EQ(abyBuffer[1], 0x00);
3534 1 : EXPECT_EQ(abyBuffer[2], 0x00);
3535 1 : EXPECT_EQ(abyBuffer[3], 0x0C);
3536 1 : EXPECT_EQ(abyBuffer[nSize - 2], 0x4C);
3537 1 : EXPECT_EQ(abyBuffer[nSize - 1], 0x01);
3538 :
3539 : // Buffer larger than needed: OK
3540 1 : nSize = nUpperBoundSize + 1;
3541 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3542 : GDALDataset::ToHandle(poSrcDS.get()), "JXL", 0, 0, 20, 20,
3543 : 1, nullptr, ppabyBuffer, &nSize, nullptr),
3544 : CE_None);
3545 :
3546 : // Too small buffer
3547 1 : nSize = nUpperBoundSize - 1;
3548 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3549 : GDALDataset::ToHandle(poSrcDS.get()), "JXL", 0, 0, 20, 20,
3550 : 1, nullptr, ppabyBuffer, &nSize, nullptr),
3551 : CE_Failure);
3552 :
3553 : // Missing pointer to size
3554 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3555 : GDALDataset::ToHandle(poSrcDS.get()), "JXL", 0, 0, 20, 20,
3556 : 1, nullptr, ppabyBuffer, nullptr, nullptr),
3557 : CE_Failure);
3558 : }
3559 :
3560 : // Let GDAL allocate buffer
3561 : {
3562 1 : void *pBuffer = nullptr;
3563 1 : size_t nSize = nUpperBoundSize;
3564 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3565 : GDALDataset::ToHandle(poSrcDS.get()), "JXL", 0, 0, 20, 20,
3566 : 1, nullptr, &pBuffer, &nSize, nullptr),
3567 : CE_None);
3568 1 : EXPECT_GT(nSize, 6);
3569 1 : EXPECT_LT(nSize, nUpperBoundSize);
3570 1 : EXPECT_NE(pBuffer, nullptr);
3571 1 : if (pBuffer != nullptr && nSize >= 6 && nSize <= nUpperBoundSize)
3572 : {
3573 1 : const GByte *pabyBuffer = static_cast<GByte *>(pBuffer);
3574 1 : EXPECT_EQ(pabyBuffer[0], 0x00);
3575 1 : EXPECT_EQ(pabyBuffer[1], 0x00);
3576 1 : EXPECT_EQ(pabyBuffer[2], 0x00);
3577 1 : EXPECT_EQ(pabyBuffer[3], 0x0C);
3578 1 : EXPECT_EQ(pabyBuffer[nSize - 2], 0x4C);
3579 1 : EXPECT_EQ(pabyBuffer[nSize - 1], 0x01);
3580 : }
3581 1 : VSIFree(pBuffer);
3582 : }
3583 : }
3584 :
3585 : // Test GDALDataset::GetCompressionFormats() and ReadCompressedData()
3586 4 : TEST_F(test_gdal, jpegxl_jpeg_compatible_ReadCompressedData)
3587 : {
3588 1 : auto poDrv = GDALDriver::FromHandle(GDALGetDriverByName("JPEGXL"));
3589 1 : if (poDrv == nullptr)
3590 : {
3591 0 : GTEST_SKIP() << "JPEGXL support missing";
3592 : }
3593 :
3594 1 : GDALDatasetUniquePtr poSrcDS(GDALDataset::FromHandle(GDALDataset::Open(
3595 1 : (tut::common::data_basedir +
3596 : "/../../gdrivers/data/jpegxl/exif_orientation/F1.jxl")
3597 1 : .c_str())));
3598 1 : ASSERT_TRUE(poSrcDS);
3599 :
3600 : const CPLStringList aosRet(GDALDatasetGetCompressionFormats(
3601 1 : GDALDataset::ToHandle(poSrcDS.get()), 0, 0, 3, 5, 1, nullptr));
3602 1 : EXPECT_EQ(aosRet.size(), 2);
3603 1 : if (aosRet.size() == 2)
3604 : {
3605 1 : EXPECT_STREQ(aosRet[0], "JXL");
3606 1 : EXPECT_STREQ(aosRet[1], "JPEG");
3607 : }
3608 :
3609 : size_t nUpperBoundSize;
3610 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3611 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 3, 5, 1,
3612 : nullptr, nullptr, &nUpperBoundSize, nullptr),
3613 : CE_None);
3614 1 : EXPECT_EQ(nUpperBoundSize, 235);
3615 :
3616 : {
3617 1 : std::vector<GByte> abyBuffer(nUpperBoundSize);
3618 1 : void *pabyBuffer = abyBuffer.data();
3619 1 : void **ppabyBuffer = &pabyBuffer;
3620 1 : size_t nSize = nUpperBoundSize;
3621 1 : char *pszDetailedFormat = nullptr;
3622 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3623 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 3, 5,
3624 : 1, nullptr, ppabyBuffer, &nSize, &pszDetailedFormat),
3625 : CE_None);
3626 1 : ASSERT_LE(nSize, nUpperBoundSize);
3627 1 : ASSERT_TRUE(*ppabyBuffer == pabyBuffer);
3628 1 : EXPECT_TRUE(pszDetailedFormat != nullptr);
3629 1 : if (pszDetailedFormat)
3630 : {
3631 1 : ASSERT_STREQ(pszDetailedFormat,
3632 : "JPEG;frame_type=SOF0_baseline;bit_depth=8;num_"
3633 : "components=1;colorspace=unknown");
3634 1 : VSIFree(pszDetailedFormat);
3635 : }
3636 1 : EXPECT_EQ(abyBuffer[0], 0xFF);
3637 1 : EXPECT_EQ(abyBuffer[1], 0xD8);
3638 1 : EXPECT_EQ(abyBuffer[nSize - 2], 0xFF);
3639 1 : EXPECT_EQ(abyBuffer[nSize - 1], 0xD9);
3640 :
3641 : // Buffer larger than needed: OK
3642 1 : nSize = nUpperBoundSize + 1;
3643 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3644 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 3, 5,
3645 : 1, nullptr, ppabyBuffer, &nSize, nullptr),
3646 : CE_None);
3647 :
3648 : // Too small buffer
3649 1 : nSize = nUpperBoundSize - 1;
3650 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3651 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 3, 5,
3652 : 1, nullptr, ppabyBuffer, &nSize, nullptr),
3653 : CE_Failure);
3654 :
3655 : // Missing pointer to size
3656 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3657 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 3, 5,
3658 : 1, nullptr, ppabyBuffer, nullptr, nullptr),
3659 : CE_Failure);
3660 : }
3661 :
3662 : // Let GDAL allocate buffer
3663 : {
3664 1 : void *pBuffer = nullptr;
3665 1 : size_t nSize = nUpperBoundSize;
3666 1 : EXPECT_EQ(GDALDatasetReadCompressedData(
3667 : GDALDataset::ToHandle(poSrcDS.get()), "JPEG", 0, 0, 3, 5,
3668 : 1, nullptr, &pBuffer, &nSize, nullptr),
3669 : CE_None);
3670 1 : EXPECT_GT(nSize, 4);
3671 1 : EXPECT_LE(nSize, nUpperBoundSize);
3672 1 : EXPECT_NE(pBuffer, nullptr);
3673 1 : if (pBuffer != nullptr && nSize >= 4 && nSize <= nUpperBoundSize)
3674 : {
3675 1 : const GByte *pabyBuffer = static_cast<GByte *>(pBuffer);
3676 1 : EXPECT_EQ(pabyBuffer[0], 0xFF);
3677 1 : EXPECT_EQ(pabyBuffer[1], 0xD8);
3678 1 : EXPECT_EQ(pabyBuffer[nSize - 2], 0xFF);
3679 1 : EXPECT_EQ(pabyBuffer[nSize - 1], 0xD9);
3680 : }
3681 1 : VSIFree(pBuffer);
3682 : }
3683 : }
3684 :
3685 : // Test GDAL_OF_SHARED flag and open options
3686 4 : TEST_F(test_gdal, open_shared_open_options)
3687 : {
3688 1 : CPLErrorReset();
3689 1 : const char *const apszOpenOptions[] = {"OVERVIEW_LEVEL=NONE", nullptr};
3690 : {
3691 : GDALDataset *poDS1 =
3692 1 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
3693 1 : nullptr, apszOpenOptions);
3694 : GDALDataset *poDS2 =
3695 1 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
3696 1 : nullptr, apszOpenOptions);
3697 1 : EXPECT_EQ(CPLGetLastErrorType(), CE_None);
3698 1 : EXPECT_NE(poDS1, nullptr);
3699 1 : EXPECT_NE(poDS2, nullptr);
3700 1 : EXPECT_EQ(poDS1, poDS2);
3701 1 : GDALClose(poDS1);
3702 1 : GDALClose(poDS2);
3703 : }
3704 : {
3705 : GDALDataset *poDS1 =
3706 1 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
3707 1 : nullptr, apszOpenOptions);
3708 1 : GDALDataset *poDS2 = GDALDataset::Open(
3709 1 : GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED, nullptr, nullptr);
3710 : GDALDataset *poDS3 =
3711 1 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
3712 1 : nullptr, apszOpenOptions);
3713 1 : EXPECT_EQ(CPLGetLastErrorType(), CE_None);
3714 1 : EXPECT_NE(poDS1, nullptr);
3715 1 : EXPECT_NE(poDS2, nullptr);
3716 1 : EXPECT_NE(poDS3, nullptr);
3717 1 : EXPECT_NE(poDS1, poDS2);
3718 1 : EXPECT_EQ(poDS1, poDS3);
3719 1 : GDALClose(poDS1);
3720 1 : GDALClose(poDS2);
3721 1 : GDALClose(poDS3);
3722 : }
3723 : {
3724 1 : GDALDataset *poDS1 = GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif",
3725 : GDAL_OF_SHARED | GDAL_OF_UPDATE,
3726 1 : nullptr, apszOpenOptions);
3727 : // We allow to re-use a shared dataset in update mode when requesting it in read-only
3728 : GDALDataset *poDS2 =
3729 1 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
3730 1 : nullptr, apszOpenOptions);
3731 1 : EXPECT_EQ(CPLGetLastErrorType(), CE_None);
3732 1 : EXPECT_NE(poDS1, nullptr);
3733 1 : EXPECT_NE(poDS2, nullptr);
3734 1 : EXPECT_EQ(poDS1, poDS2);
3735 1 : GDALClose(poDS1);
3736 1 : GDALClose(poDS2);
3737 : }
3738 : {
3739 1 : GDALDataset *poDS1 = GDALDataset::Open(
3740 1 : GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED, nullptr, nullptr);
3741 : GDALDataset *poDS2 =
3742 1 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
3743 1 : nullptr, apszOpenOptions);
3744 : GDALDataset *poDS3 =
3745 1 : GDALDataset::Open(GCORE_DATA_DIR "rgbsmall.tif", GDAL_OF_SHARED,
3746 1 : nullptr, apszOpenOptions);
3747 1 : EXPECT_EQ(CPLGetLastErrorType(), CE_None);
3748 1 : EXPECT_NE(poDS1, nullptr);
3749 1 : EXPECT_NE(poDS2, nullptr);
3750 1 : EXPECT_NE(poDS3, nullptr);
3751 1 : EXPECT_NE(poDS1, poDS2);
3752 1 : EXPECT_EQ(poDS2, poDS3);
3753 1 : GDALClose(poDS1);
3754 1 : GDALClose(poDS2);
3755 1 : GDALClose(poDS3);
3756 : }
3757 1 : }
3758 :
3759 : // Test DropCache() to check that no data is saved on disk
3760 4 : TEST_F(test_gdal, drop_cache)
3761 : {
3762 1 : CPLErrorReset();
3763 : {
3764 1 : GDALDriverManager *gdalDriverManager = GetGDALDriverManager();
3765 1 : if (!gdalDriverManager)
3766 0 : return;
3767 1 : GDALDriver *enviDriver = gdalDriverManager->GetDriverByName("ENVI");
3768 1 : if (!enviDriver)
3769 0 : return;
3770 1 : const char *enviOptions[] = {"SUFFIX=ADD", "INTERLEAVE=BIL", nullptr};
3771 :
3772 1 : const char *filename = GCORE_DATA_DIR "test_drop_cache.bil";
3773 :
3774 : auto poDS = std::unique_ptr<GDALDataset>(enviDriver->Create(
3775 1 : filename, 1, 1, 1, GDALDataType::GDT_Float32, enviOptions));
3776 1 : if (!poDS)
3777 0 : return;
3778 1 : poDS->GetRasterBand(1)->Fill(1);
3779 1 : poDS->DropCache();
3780 1 : poDS.reset();
3781 :
3782 1 : poDS.reset(
3783 : GDALDataset::Open(filename, GDAL_OF_SHARED, nullptr, nullptr));
3784 1 : if (!poDS)
3785 0 : return;
3786 :
3787 1 : EXPECT_EQ(GDALChecksumImage(poDS->GetRasterBand(1), 0, 0, 1, 1), 0);
3788 1 : poDS->MarkSuppressOnClose();
3789 1 : poDS.reset();
3790 : }
3791 : }
3792 :
3793 : // Test gdal::gcp class
3794 4 : TEST_F(test_gdal, gdal_gcp_class)
3795 : {
3796 : {
3797 2 : gdal::GCP gcp;
3798 1 : EXPECT_STREQ(gcp.Id(), "");
3799 1 : EXPECT_STREQ(gcp.Info(), "");
3800 1 : EXPECT_EQ(gcp.Pixel(), 0.0);
3801 1 : EXPECT_EQ(gcp.Line(), 0.0);
3802 1 : EXPECT_EQ(gcp.X(), 0.0);
3803 1 : EXPECT_EQ(gcp.Y(), 0.0);
3804 1 : EXPECT_EQ(gcp.Z(), 0.0);
3805 : }
3806 : {
3807 2 : gdal::GCP gcp("id", "info", 1.5, 2.5, 3.5, 4.5, 5.5);
3808 1 : EXPECT_STREQ(gcp.Id(), "id");
3809 1 : EXPECT_STREQ(gcp.Info(), "info");
3810 1 : EXPECT_EQ(gcp.Pixel(), 1.5);
3811 1 : EXPECT_EQ(gcp.Line(), 2.5);
3812 1 : EXPECT_EQ(gcp.X(), 3.5);
3813 1 : EXPECT_EQ(gcp.Y(), 4.5);
3814 1 : EXPECT_EQ(gcp.Z(), 5.5);
3815 :
3816 1 : gcp.SetId("id2");
3817 1 : gcp.SetInfo("info2");
3818 1 : gcp.Pixel() = -1.5;
3819 1 : gcp.Line() = -2.5;
3820 1 : gcp.X() = -3.5;
3821 1 : gcp.Y() = -4.5;
3822 1 : gcp.Z() = -5.5;
3823 1 : EXPECT_STREQ(gcp.Id(), "id2");
3824 1 : EXPECT_STREQ(gcp.Info(), "info2");
3825 1 : EXPECT_EQ(gcp.Pixel(), -1.5);
3826 1 : EXPECT_EQ(gcp.Line(), -2.5);
3827 1 : EXPECT_EQ(gcp.X(), -3.5);
3828 1 : EXPECT_EQ(gcp.Y(), -4.5);
3829 1 : EXPECT_EQ(gcp.Z(), -5.5);
3830 :
3831 : {
3832 2 : gdal::GCP gcp_copy(gcp);
3833 1 : EXPECT_STREQ(gcp_copy.Id(), "id2");
3834 1 : EXPECT_STREQ(gcp_copy.Info(), "info2");
3835 1 : EXPECT_EQ(gcp_copy.Pixel(), -1.5);
3836 1 : EXPECT_EQ(gcp_copy.Line(), -2.5);
3837 1 : EXPECT_EQ(gcp_copy.X(), -3.5);
3838 1 : EXPECT_EQ(gcp_copy.Y(), -4.5);
3839 1 : EXPECT_EQ(gcp_copy.Z(), -5.5);
3840 : }
3841 :
3842 : {
3843 2 : gdal::GCP gcp_copy;
3844 1 : gcp_copy = gcp;
3845 1 : EXPECT_STREQ(gcp_copy.Id(), "id2");
3846 1 : EXPECT_STREQ(gcp_copy.Info(), "info2");
3847 1 : EXPECT_EQ(gcp_copy.Pixel(), -1.5);
3848 1 : EXPECT_EQ(gcp_copy.Line(), -2.5);
3849 1 : EXPECT_EQ(gcp_copy.X(), -3.5);
3850 1 : EXPECT_EQ(gcp_copy.Y(), -4.5);
3851 1 : EXPECT_EQ(gcp_copy.Z(), -5.5);
3852 : }
3853 :
3854 : {
3855 2 : gdal::GCP gcp_copy(gcp);
3856 2 : gdal::GCP gcp_from_moved(std::move(gcp_copy));
3857 1 : EXPECT_STREQ(gcp_from_moved.Id(), "id2");
3858 1 : EXPECT_STREQ(gcp_from_moved.Info(), "info2");
3859 1 : EXPECT_EQ(gcp_from_moved.Pixel(), -1.5);
3860 1 : EXPECT_EQ(gcp_from_moved.Line(), -2.5);
3861 1 : EXPECT_EQ(gcp_from_moved.X(), -3.5);
3862 1 : EXPECT_EQ(gcp_from_moved.Y(), -4.5);
3863 1 : EXPECT_EQ(gcp_from_moved.Z(), -5.5);
3864 : }
3865 :
3866 : {
3867 2 : gdal::GCP gcp_copy(gcp);
3868 2 : gdal::GCP gcp_from_moved;
3869 1 : gcp_from_moved = std::move(gcp_copy);
3870 1 : EXPECT_STREQ(gcp_from_moved.Id(), "id2");
3871 1 : EXPECT_STREQ(gcp_from_moved.Info(), "info2");
3872 1 : EXPECT_EQ(gcp_from_moved.Pixel(), -1.5);
3873 1 : EXPECT_EQ(gcp_from_moved.Line(), -2.5);
3874 1 : EXPECT_EQ(gcp_from_moved.X(), -3.5);
3875 1 : EXPECT_EQ(gcp_from_moved.Y(), -4.5);
3876 1 : EXPECT_EQ(gcp_from_moved.Z(), -5.5);
3877 : }
3878 :
3879 : {
3880 1 : const GDAL_GCP *c_gcp = gcp.c_ptr();
3881 1 : EXPECT_STREQ(c_gcp->pszId, "id2");
3882 1 : EXPECT_STREQ(c_gcp->pszInfo, "info2");
3883 1 : EXPECT_EQ(c_gcp->dfGCPPixel, -1.5);
3884 1 : EXPECT_EQ(c_gcp->dfGCPLine, -2.5);
3885 1 : EXPECT_EQ(c_gcp->dfGCPX, -3.5);
3886 1 : EXPECT_EQ(c_gcp->dfGCPY, -4.5);
3887 1 : EXPECT_EQ(c_gcp->dfGCPZ, -5.5);
3888 :
3889 2 : const gdal::GCP gcp_from_c(*c_gcp);
3890 1 : EXPECT_STREQ(gcp_from_c.Id(), "id2");
3891 1 : EXPECT_STREQ(gcp_from_c.Info(), "info2");
3892 1 : EXPECT_EQ(gcp_from_c.Pixel(), -1.5);
3893 1 : EXPECT_EQ(gcp_from_c.Line(), -2.5);
3894 1 : EXPECT_EQ(gcp_from_c.X(), -3.5);
3895 1 : EXPECT_EQ(gcp_from_c.Y(), -4.5);
3896 1 : EXPECT_EQ(gcp_from_c.Z(), -5.5);
3897 : }
3898 : }
3899 :
3900 : {
3901 : const std::vector<gdal::GCP> gcps{
3902 : gdal::GCP{nullptr, nullptr, 0, 0, 0, 0, 0},
3903 4 : gdal::GCP{"id", "info", 1.5, 2.5, 3.5, 4.5, 5.5}};
3904 :
3905 1 : const GDAL_GCP *c_gcps = gdal::GCP::c_ptr(gcps);
3906 1 : EXPECT_STREQ(c_gcps[1].pszId, "id");
3907 1 : EXPECT_STREQ(c_gcps[1].pszInfo, "info");
3908 1 : EXPECT_EQ(c_gcps[1].dfGCPPixel, 1.5);
3909 1 : EXPECT_EQ(c_gcps[1].dfGCPLine, 2.5);
3910 1 : EXPECT_EQ(c_gcps[1].dfGCPX, 3.5);
3911 1 : EXPECT_EQ(c_gcps[1].dfGCPY, 4.5);
3912 1 : EXPECT_EQ(c_gcps[1].dfGCPZ, 5.5);
3913 :
3914 : const auto gcps_from_c =
3915 1 : gdal::GCP::fromC(c_gcps, static_cast<int>(gcps.size()));
3916 1 : ASSERT_EQ(gcps_from_c.size(), gcps.size());
3917 3 : for (size_t i = 0; i < gcps.size(); ++i)
3918 : {
3919 2 : EXPECT_STREQ(gcps_from_c[i].Id(), gcps[i].Id());
3920 2 : EXPECT_STREQ(gcps_from_c[i].Info(), gcps[i].Info());
3921 2 : EXPECT_EQ(gcps_from_c[i].Pixel(), gcps[i].Pixel());
3922 2 : EXPECT_EQ(gcps_from_c[i].Line(), gcps[i].Line());
3923 2 : EXPECT_EQ(gcps_from_c[i].X(), gcps[i].X());
3924 2 : EXPECT_EQ(gcps_from_c[i].Y(), gcps[i].Y());
3925 2 : EXPECT_EQ(gcps_from_c[i].Z(), gcps[i].Z());
3926 : }
3927 : }
3928 : }
3929 :
3930 : } // namespace
|