Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL Core
4 : * Purpose: Test GDALCopyWords().
5 : * Author: Even Rouault, <even dot rouault at spatialys.com>
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2009-2011, Even Rouault <even dot rouault at spatialys.com>
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #include "cpl_conv.h"
14 : #include "cpl_float.h"
15 : #include "gdal.h"
16 :
17 : #include <cmath>
18 : #include <cstdint>
19 : #include <iostream>
20 : #include <limits>
21 : #include <type_traits>
22 :
23 : #include "gtest_include.h"
24 :
25 : namespace
26 : {
27 :
28 : // ---------------------------------------------------------------------------
29 :
30 : template <class OutType, class CT1, class CT2>
31 60326 : void AssertRes(GDALDataType intype, CT1 inval, GDALDataType outtype,
32 : CT2 expected_outval, OutType outval, int numLine)
33 : {
34 63064 : if (static_cast<double>(expected_outval) == static_cast<double>(outval) ||
35 2738 : (std::isnan(static_cast<double>(expected_outval)) &&
36 201 : std::isnan(static_cast<double>(outval))))
37 : {
38 : // ok
39 : }
40 : else
41 : {
42 2336 : EXPECT_NEAR((double)outval, (double)expected_outval, 1.0)
43 0 : << "Test failed at line " << numLine
44 0 : << " (intype=" << GDALGetDataTypeName(intype)
45 0 : << ",inval=" << (double)inval
46 0 : << ",outtype=" << GDALGetDataTypeName(outtype) << ",got "
47 0 : << (double)outval << " expected " << expected_outval;
48 : }
49 60326 : }
50 :
51 : #define MY_EXPECT(intype, inval, outtype, expected_outval, outval) \
52 : AssertRes(intype, inval, outtype, expected_outval, outval, numLine)
53 :
54 : class TestCopyWords : public ::testing::Test
55 : {
56 : protected:
57 138 : void SetUp() override
58 : {
59 138 : pIn = (GByte *)malloc(2048);
60 138 : pOut = (GByte *)malloc(2048);
61 138 : }
62 :
63 138 : void TearDown() override
64 : {
65 :
66 138 : free(pIn);
67 138 : free(pOut);
68 138 : }
69 :
70 : GByte *pIn;
71 : GByte *pOut;
72 :
73 : template <class InType, class OutType, class ConstantType>
74 1029 : void Test(GDALDataType intype, ConstantType inval, ConstantType invali,
75 : GDALDataType outtype, ConstantType outval, ConstantType outvali,
76 : int numLine)
77 : {
78 1029 : memset(pIn, 0xff, 1024);
79 1029 : memset(pOut, 0xff, 1024);
80 :
81 1029 : *(InType *)(pIn) = (InType)inval;
82 1029 : *(InType *)(pIn + 32) = (InType)inval;
83 1029 : if (GDALDataTypeIsComplex(intype))
84 : {
85 250 : ((InType *)(pIn))[1] = (InType)invali;
86 250 : ((InType *)(pIn + 32))[1] = (InType)invali;
87 : }
88 :
89 : /* Test positive offsets */
90 1029 : GDALCopyWords(pIn, intype, 32, pOut, outtype, 32, 2);
91 :
92 : /* Test negative offsets */
93 1029 : GDALCopyWords(pIn + 32, intype, -32, pOut + 1024 - 16, outtype, -32, 2);
94 :
95 1029 : MY_EXPECT(intype, inval, outtype, outval, *(OutType *)(pOut));
96 1029 : MY_EXPECT(intype, inval, outtype, outval, *(OutType *)(pOut + 32));
97 1029 : MY_EXPECT(intype, inval, outtype, outval,
98 : *(OutType *)(pOut + 1024 - 16));
99 1029 : MY_EXPECT(intype, inval, outtype, outval,
100 : *(OutType *)(pOut + 1024 - 16 - 32));
101 :
102 1029 : if (GDALDataTypeIsComplex(outtype))
103 : {
104 304 : MY_EXPECT(intype, invali, outtype, outvali, ((OutType *)(pOut))[1]);
105 304 : MY_EXPECT(intype, invali, outtype, outvali,
106 : ((OutType *)(pOut + 32))[1]);
107 :
108 304 : MY_EXPECT(intype, invali, outtype, outvali,
109 : ((OutType *)(pOut + 1024 - 16))[1]);
110 304 : MY_EXPECT(intype, invali, outtype, outvali,
111 : ((OutType *)(pOut + 1024 - 16 - 32))[1]);
112 : }
113 : else
114 : {
115 725 : constexpr int N = 32 + 31;
116 46400 : for (int i = 0; i < N; ++i)
117 : {
118 45675 : *(InType *)(pIn + i * GDALGetDataTypeSizeBytes(intype)) =
119 9009 : (InType)inval;
120 : }
121 :
122 : /* Test packed offsets */
123 725 : GDALCopyWords(pIn, intype, GDALGetDataTypeSizeBytes(intype), pOut,
124 : outtype, GDALGetDataTypeSizeBytes(outtype), N);
125 :
126 46400 : for (int i = 0; i < N; ++i)
127 : {
128 45675 : MY_EXPECT(
129 : intype, inval, outtype, outval,
130 : *(OutType *)(pOut + i * GDALGetDataTypeSizeBytes(outtype)));
131 : }
132 : }
133 1029 : }
134 :
135 : template <class InType, class ConstantType>
136 1029 : void FromR_2(GDALDataType intype, ConstantType inval, ConstantType invali,
137 : GDALDataType outtype, ConstantType outval,
138 : ConstantType outvali, int numLine)
139 : {
140 1029 : if (outtype == GDT_Byte)
141 77 : Test<InType, GByte, ConstantType>(intype, inval, invali, outtype,
142 : outval, outvali, numLine);
143 952 : else if (outtype == GDT_Int8)
144 61 : Test<InType, GInt8, ConstantType>(intype, inval, invali, outtype,
145 : outval, outvali, numLine);
146 891 : else if (outtype == GDT_Int16)
147 92 : Test<InType, GInt16, ConstantType>(intype, inval, invali, outtype,
148 : outval, outvali, numLine);
149 799 : else if (outtype == GDT_UInt16)
150 71 : Test<InType, GUInt16, ConstantType>(intype, inval, invali, outtype,
151 : outval, outvali, numLine);
152 728 : else if (outtype == GDT_Int32)
153 87 : Test<InType, GInt32, ConstantType>(intype, inval, invali, outtype,
154 : outval, outvali, numLine);
155 641 : else if (outtype == GDT_UInt32)
156 66 : Test<InType, GUInt32, ConstantType>(intype, inval, invali, outtype,
157 : outval, outvali, numLine);
158 575 : else if (outtype == GDT_Int64)
159 71 : Test<InType, std::int64_t, ConstantType>(
160 : intype, inval, invali, outtype, outval, outvali, numLine);
161 504 : else if (outtype == GDT_UInt64)
162 50 : Test<InType, std::uint64_t, ConstantType>(
163 : intype, inval, invali, outtype, outval, outvali, numLine);
164 454 : else if (outtype == GDT_Float16)
165 39 : Test<InType, GFloat16, ConstantType>(intype, inval, invali, outtype,
166 : outval, outvali, numLine);
167 415 : else if (outtype == GDT_Float32)
168 57 : Test<InType, float, ConstantType>(intype, inval, invali, outtype,
169 : outval, outvali, numLine);
170 358 : else if (outtype == GDT_Float64)
171 54 : Test<InType, double, ConstantType>(intype, inval, invali, outtype,
172 : outval, outvali, numLine);
173 304 : else if (outtype == GDT_CInt16)
174 87 : Test<InType, GInt16, ConstantType>(intype, inval, invali, outtype,
175 : outval, outvali, numLine);
176 217 : else if (outtype == GDT_CInt32)
177 87 : Test<InType, GInt32, ConstantType>(intype, inval, invali, outtype,
178 : outval, outvali, numLine);
179 130 : else if (outtype == GDT_CFloat16)
180 28 : Test<InType, GFloat16, ConstantType>(intype, inval, invali, outtype,
181 : outval, outvali, numLine);
182 102 : else if (outtype == GDT_CFloat32)
183 51 : Test<InType, float, ConstantType>(intype, inval, invali, outtype,
184 : outval, outvali, numLine);
185 51 : else if (outtype == GDT_CFloat64)
186 51 : Test<InType, double, ConstantType>(intype, inval, invali, outtype,
187 : outval, outvali, numLine);
188 1029 : }
189 :
190 : template <class ConstantType>
191 1029 : void FromR(GDALDataType intype, ConstantType inval, ConstantType invali,
192 : GDALDataType outtype, ConstantType outval, ConstantType outvali,
193 : int numLine)
194 : {
195 1029 : if (intype == GDT_Byte)
196 47 : FromR_2<GByte, ConstantType>(intype, inval, invali, outtype, outval,
197 : outvali, numLine);
198 982 : else if (intype == GDT_Int8)
199 46 : FromR_2<GInt8, ConstantType>(intype, inval, invali, outtype, outval,
200 : outvali, numLine);
201 936 : else if (intype == GDT_Int16)
202 42 : FromR_2<GInt16, ConstantType>(intype, inval, invali, outtype,
203 : outval, outvali, numLine);
204 894 : else if (intype == GDT_UInt16)
205 45 : FromR_2<GUInt16, ConstantType>(intype, inval, invali, outtype,
206 : outval, outvali, numLine);
207 849 : else if (intype == GDT_Int32)
208 45 : FromR_2<GInt32, ConstantType>(intype, inval, invali, outtype,
209 : outval, outvali, numLine);
210 804 : else if (intype == GDT_UInt32)
211 45 : FromR_2<GUInt32, ConstantType>(intype, inval, invali, outtype,
212 : outval, outvali, numLine);
213 759 : else if (intype == GDT_Int64)
214 39 : FromR_2<std::int64_t, ConstantType>(intype, inval, invali, outtype,
215 : outval, outvali, numLine);
216 720 : else if (intype == GDT_UInt64)
217 45 : FromR_2<std::uint64_t, ConstantType>(intype, inval, invali, outtype,
218 : outval, outvali, numLine);
219 675 : else if (intype == GDT_Float16)
220 135 : FromR_2<GFloat16, ConstantType>(intype, inval, invali, outtype,
221 : outval, outvali, numLine);
222 540 : else if (intype == GDT_Float32)
223 146 : FromR_2<float, ConstantType>(intype, inval, invali, outtype, outval,
224 : outvali, numLine);
225 394 : else if (intype == GDT_Float64)
226 144 : FromR_2<double, ConstantType>(intype, inval, invali, outtype,
227 : outval, outvali, numLine);
228 250 : else if (intype == GDT_CInt16)
229 38 : FromR_2<GInt16, ConstantType>(intype, inval, invali, outtype,
230 : outval, outvali, numLine);
231 212 : else if (intype == GDT_CInt32)
232 38 : FromR_2<GInt32, ConstantType>(intype, inval, invali, outtype,
233 : outval, outvali, numLine);
234 174 : else if (intype == GDT_CFloat16)
235 58 : FromR_2<GFloat16, ConstantType>(intype, inval, invali, outtype,
236 : outval, outvali, numLine);
237 116 : else if (intype == GDT_CFloat32)
238 58 : FromR_2<float, ConstantType>(intype, inval, invali, outtype, outval,
239 : outvali, numLine);
240 58 : else if (intype == GDT_CFloat64)
241 58 : FromR_2<double, ConstantType>(intype, inval, invali, outtype,
242 : outval, outvali, numLine);
243 1029 : }
244 : };
245 :
246 : #define FROM_R(intype, inval, outtype, outval) \
247 : FromR<GIntBig>(intype, inval, 0, outtype, outval, 0, __LINE__)
248 : #define FROM_R_F(intype, inval, outtype, outval) \
249 : FromR<double>(intype, inval, 0, outtype, outval, 0, __LINE__)
250 :
251 : #define FROM_C(intype, inval, invali, outtype, outval, outvali) \
252 : FromR<GIntBig>(intype, inval, invali, outtype, outval, outvali, __LINE__)
253 : #define FROM_C_F(intype, inval, invali, outtype, outval, outvali) \
254 : FromR<double>(intype, inval, invali, outtype, outval, outvali, __LINE__)
255 :
256 : #define IS_UNSIGNED(x) \
257 : (x == GDT_Byte || x == GDT_UInt16 || x == GDT_UInt32 || x == GDT_UInt64)
258 : #define IS_FLOAT(x) \
259 : (x == GDT_Float16 || x == GDT_Float32 || x == GDT_Float64 || \
260 : x == GDT_CFloat16 || x == GDT_CFloat32 || x == GDT_CFloat64)
261 :
262 : #define CST_3000000000 (((GIntBig)3000) * 1000 * 1000)
263 : #define CST_5000000000 (((GIntBig)5000) * 1000 * 1000)
264 :
265 4 : TEST_F(TestCopyWords, GDT_Byte)
266 : {
267 : /* GDT_Byte */
268 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
269 16 : outtype = (GDALDataType)(outtype + 1))
270 : {
271 16 : FROM_R(GDT_Byte, 0, outtype, 0);
272 16 : FROM_R(GDT_Byte, 127, outtype, 127);
273 16 : if (outtype != GDT_Int8)
274 15 : FROM_R(GDT_Byte, 255, outtype, 255);
275 : }
276 :
277 18 : for (int i = 0; i < 17; i++)
278 : {
279 17 : pIn[i] = (GByte)i;
280 : }
281 :
282 1 : memset(pOut, 0xff, 128);
283 1 : GDALCopyWords(pIn, GDT_Byte, 1, pOut, GDT_Int32, 4, 17);
284 18 : for (int i = 0; i < 17; i++)
285 : {
286 17 : AssertRes(GDT_Byte, i, GDT_Int32, i, ((int *)pOut)[i], __LINE__);
287 : }
288 :
289 1 : memset(pOut, 0xff, 128);
290 1 : GDALCopyWords(pIn, GDT_Byte, 1, pOut, GDT_Float32, 4, 17);
291 18 : for (int i = 0; i < 17; i++)
292 : {
293 17 : AssertRes(GDT_Byte, i, GDT_Float32, i, ((float *)pOut)[i], __LINE__);
294 : }
295 1 : }
296 :
297 4 : TEST_F(TestCopyWords, GDT_Int8)
298 : {
299 : /* GDT_Int8 */
300 1 : FROM_R(GDT_Int8, -128, GDT_Byte, 0); /* clamp */
301 1 : FROM_R(GDT_Int8, -128, GDT_Int8, -128); /* clamp */
302 1 : FROM_R(GDT_Int8, -128, GDT_Int16, -128);
303 1 : FROM_R(GDT_Int8, -128, GDT_UInt16, 0); /* clamp */
304 1 : FROM_R(GDT_Int8, -128, GDT_Int32, -128);
305 1 : FROM_R(GDT_Int8, -128, GDT_UInt32, 0); /* clamp */
306 1 : FROM_R(GDT_Int8, -128, GDT_Int64, -128);
307 1 : FROM_R(GDT_Int8, -128, GDT_UInt64, 0); /* clamp */
308 1 : FROM_R(GDT_Int8, -128, GDT_Float16, -128);
309 1 : FROM_R(GDT_Int8, -128, GDT_Float32, -128);
310 1 : FROM_R(GDT_Int8, -128, GDT_Float64, -128);
311 1 : FROM_R(GDT_Int8, -128, GDT_CInt16, -128);
312 1 : FROM_R(GDT_Int8, -128, GDT_CInt32, -128);
313 1 : FROM_R(GDT_Int8, -128, GDT_CFloat16, -128);
314 1 : FROM_R(GDT_Int8, -128, GDT_CFloat32, -128);
315 1 : FROM_R(GDT_Int8, -128, GDT_CFloat64, -128);
316 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
317 16 : outtype = (GDALDataType)(outtype + 1))
318 : {
319 16 : FROM_R(GDT_Int8, 127, outtype, 127);
320 : }
321 :
322 1 : FROM_R(GDT_Int8, 127, GDT_Byte, 127);
323 1 : FROM_R(GDT_Int8, 127, GDT_Int8, 127);
324 1 : FROM_R(GDT_Int8, 127, GDT_Int16, 127);
325 1 : FROM_R(GDT_Int8, 127, GDT_UInt16, 127);
326 1 : FROM_R(GDT_Int8, 127, GDT_Int32, 127);
327 1 : FROM_R(GDT_Int8, 127, GDT_UInt32, 127);
328 1 : FROM_R(GDT_Int8, 127, GDT_Int64, 127);
329 1 : FROM_R(GDT_Int8, 127, GDT_UInt64, 127);
330 1 : FROM_R(GDT_Int8, 127, GDT_Float32, 127);
331 1 : FROM_R(GDT_Int8, 127, GDT_Float64, 127);
332 1 : FROM_R(GDT_Int8, 127, GDT_CInt16, 127);
333 1 : FROM_R(GDT_Int8, 127, GDT_CInt32, 127);
334 1 : FROM_R(GDT_Int8, 127, GDT_CFloat32, 127);
335 1 : FROM_R(GDT_Int8, 127, GDT_CFloat64, 127);
336 1 : }
337 :
338 4 : TEST_F(TestCopyWords, GDT_Int16)
339 : {
340 : /* GDT_Int16 */
341 1 : FROM_R(GDT_Int16, -32000, GDT_Byte, 0); /* clamp */
342 1 : FROM_R(GDT_Int16, -32000, GDT_Int16, -32000);
343 1 : FROM_R(GDT_Int16, -32000, GDT_UInt16, 0); /* clamp */
344 1 : FROM_R(GDT_Int16, -32000, GDT_Int32, -32000);
345 1 : FROM_R(GDT_Int16, -32000, GDT_UInt32, 0); /* clamp */
346 1 : FROM_R(GDT_Int16, -32000, GDT_Int64, -32000);
347 1 : FROM_R(GDT_Int16, -32000, GDT_UInt64, 0); /* clamp */
348 1 : FROM_R(GDT_Int16, -32000, GDT_Float32, -32000);
349 1 : FROM_R(GDT_Int16, -32000, GDT_Float64, -32000);
350 1 : FROM_R(GDT_Int16, -32000, GDT_CInt16, -32000);
351 1 : FROM_R(GDT_Int16, -32000, GDT_CInt32, -32000);
352 1 : FROM_R(GDT_Int16, -32000, GDT_CFloat32, -32000);
353 1 : FROM_R(GDT_Int16, -32000, GDT_CFloat64, -32000);
354 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
355 16 : outtype = (GDALDataType)(outtype + 1))
356 : {
357 16 : FROM_R(GDT_Int16, 127, outtype, 127);
358 : }
359 :
360 1 : FROM_R(GDT_Int16, 32000, GDT_Byte, 255); /* clamp */
361 1 : FROM_R(GDT_Int16, 32000, GDT_Int16, 32000);
362 1 : FROM_R(GDT_Int16, 32000, GDT_UInt16, 32000);
363 1 : FROM_R(GDT_Int16, 32000, GDT_Int32, 32000);
364 1 : FROM_R(GDT_Int16, 32000, GDT_UInt32, 32000);
365 1 : FROM_R(GDT_Int16, 32000, GDT_Int64, 32000);
366 1 : FROM_R(GDT_Int16, 32000, GDT_UInt64, 32000);
367 1 : FROM_R(GDT_Int16, 32000, GDT_Float32, 32000);
368 1 : FROM_R(GDT_Int16, 32000, GDT_Float64, 32000);
369 1 : FROM_R(GDT_Int16, 32000, GDT_CInt16, 32000);
370 1 : FROM_R(GDT_Int16, 32000, GDT_CInt32, 32000);
371 1 : FROM_R(GDT_Int16, 32000, GDT_CFloat32, 32000);
372 1 : FROM_R(GDT_Int16, 32000, GDT_CFloat64, 32000);
373 1 : }
374 :
375 4 : TEST_F(TestCopyWords, GDT_UInt16)
376 : {
377 : /* GDT_UInt16 */
378 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
379 16 : outtype = (GDALDataType)(outtype + 1))
380 : {
381 16 : FROM_R(GDT_UInt16, 0, outtype, 0);
382 16 : FROM_R(GDT_UInt16, 127, outtype, 127);
383 : }
384 :
385 1 : FROM_R(GDT_UInt16, 65000, GDT_Byte, 255); /* clamp */
386 1 : FROM_R(GDT_UInt16, 65000, GDT_Int16, 32767); /* clamp */
387 1 : FROM_R(GDT_UInt16, 65000, GDT_UInt16, 65000);
388 1 : FROM_R(GDT_UInt16, 65000, GDT_Int32, 65000);
389 1 : FROM_R(GDT_UInt16, 65000, GDT_UInt32, 65000);
390 1 : FROM_R(GDT_UInt16, 65000, GDT_Int64, 65000);
391 1 : FROM_R(GDT_UInt16, 65000, GDT_UInt64, 65000);
392 1 : FROM_R(GDT_UInt16, 65000, GDT_Float32, 65000);
393 1 : FROM_R(GDT_UInt16, 65000, GDT_Float64, 65000);
394 1 : FROM_R(GDT_UInt16, 65000, GDT_CInt16, 32767); /* clamp */
395 1 : FROM_R(GDT_UInt16, 65000, GDT_CInt32, 65000);
396 1 : FROM_R(GDT_UInt16, 65000, GDT_CFloat32, 65000);
397 1 : FROM_R(GDT_UInt16, 65000, GDT_CFloat64, 65000);
398 1 : }
399 :
400 4 : TEST_F(TestCopyWords, GDT_Int32)
401 : {
402 : /* GDT_Int32 */
403 1 : FROM_R(GDT_Int32, -33000, GDT_Byte, 0); /* clamp */
404 1 : FROM_R(GDT_Int32, -33000, GDT_Int16, -32768); /* clamp */
405 1 : FROM_R(GDT_Int32, -33000, GDT_UInt16, 0); /* clamp */
406 1 : FROM_R(GDT_Int32, -33000, GDT_Int32, -33000);
407 1 : FROM_R(GDT_Int32, -33000, GDT_UInt32, 0); /* clamp */
408 1 : FROM_R(GDT_Int32, -33000, GDT_Int64, -33000);
409 1 : FROM_R(GDT_Int32, -33000, GDT_UInt64, 0); /* clamp */
410 1 : FROM_R(GDT_Int32, -33000, GDT_Float32, -33000);
411 1 : FROM_R(GDT_Int32, -33000, GDT_Float64, -33000);
412 1 : FROM_R(GDT_Int32, -33000, GDT_CInt16, -32768); /* clamp */
413 1 : FROM_R(GDT_Int32, -33000, GDT_CInt32, -33000);
414 1 : FROM_R(GDT_Int32, -33000, GDT_CFloat32, -33000);
415 1 : FROM_R(GDT_Int32, -33000, GDT_CFloat64, -33000);
416 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
417 16 : outtype = (GDALDataType)(outtype + 1))
418 : {
419 16 : FROM_R(GDT_Int32, 127, outtype, 127);
420 : }
421 :
422 1 : FROM_R(GDT_Int32, 67000, GDT_Byte, 255); /* clamp */
423 1 : FROM_R(GDT_Int32, 67000, GDT_Int16, 32767); /* clamp */
424 1 : FROM_R(GDT_Int32, 67000, GDT_UInt16, 65535); /* clamp */
425 1 : FROM_R(GDT_Int32, 67000, GDT_Int32, 67000);
426 1 : FROM_R(GDT_Int32, 67000, GDT_UInt32, 67000);
427 1 : FROM_R(GDT_Int32, 67000, GDT_Int64, 67000);
428 1 : FROM_R(GDT_Int32, 67000, GDT_UInt64, 67000);
429 1 : FROM_R(GDT_Int32, 67000, GDT_Float32, 67000);
430 1 : FROM_R(GDT_Int32, 67000, GDT_Float64, 67000);
431 1 : FROM_R(GDT_Int32, 67000, GDT_CInt16, 32767); /* clamp */
432 1 : FROM_R(GDT_Int32, 67000, GDT_CInt32, 67000);
433 1 : FROM_R(GDT_Int32, 67000, GDT_CFloat32, 67000);
434 1 : FROM_R(GDT_Int32, 67000, GDT_CFloat64, 67000);
435 1 : }
436 :
437 4 : TEST_F(TestCopyWords, GDT_UInt32)
438 : {
439 : /* GDT_UInt32 */
440 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
441 16 : outtype = (GDALDataType)(outtype + 1))
442 : {
443 16 : FROM_R(GDT_UInt32, 0, outtype, 0);
444 16 : FROM_R(GDT_UInt32, 127, outtype, 127);
445 : }
446 :
447 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_Byte, 255); /* clamp */
448 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_Int16, 32767); /* clamp */
449 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_UInt16, 65535); /* clamp */
450 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_Int32, 2147483647); /* clamp */
451 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_UInt32, 3000000000U);
452 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_Int64, 3000000000U);
453 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_UInt64, 3000000000U);
454 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_Float32, 3000000000U);
455 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_Float64, 3000000000U);
456 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_CInt16, 32767); /* clamp */
457 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_CInt32, 2147483647); /* clamp */
458 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_CFloat32, 3000000000U);
459 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_CFloat64, 3000000000U);
460 1 : }
461 :
462 4 : TEST_F(TestCopyWords, check_GDT_Int64)
463 : {
464 : /* GDT_Int64 */
465 1 : FROM_R(GDT_Int64, -33000, GDT_Byte, 0); /* clamp */
466 1 : FROM_R(GDT_Int64, -33000, GDT_Int16, -32768); /* clamp */
467 1 : FROM_R(GDT_Int64, -33000, GDT_UInt16, 0); /* clamp */
468 1 : FROM_R(GDT_Int64, -33000, GDT_Int32, -33000);
469 1 : FROM_R(GDT_Int64, -33000, GDT_UInt32, 0); /* clamp */
470 1 : FROM_R(GDT_Int64, -33000, GDT_Int64, -33000);
471 1 : FROM_R(GDT_Int64, -33000, GDT_UInt64, 0); /* clamp */
472 1 : FROM_R(GDT_Int64, -33000, GDT_Float32, -33000);
473 1 : FROM_R(GDT_Int64, -33000, GDT_Float64, -33000);
474 1 : FROM_R(GDT_Int64, -33000, GDT_CInt16, -32768); /* clamp */
475 1 : FROM_R(GDT_Int64, -33000, GDT_CInt32, -33000);
476 1 : FROM_R(GDT_Int64, -33000, GDT_CFloat32, -33000);
477 1 : FROM_R(GDT_Int64, -33000, GDT_CFloat64, -33000);
478 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
479 16 : outtype = (GDALDataType)(outtype + 1))
480 : {
481 16 : FROM_R(GDT_Int64, 127, outtype, 127);
482 : }
483 :
484 1 : FROM_R(GDT_Int64, 67000, GDT_Byte, 255); /* clamp */
485 1 : FROM_R(GDT_Int64, 67000, GDT_Int16, 32767); /* clamp */
486 1 : FROM_R(GDT_Int32, 67000, GDT_UInt16, 65535); /* clamp */
487 1 : FROM_R(GDT_Int32, 67000, GDT_Int32, 67000);
488 1 : FROM_R(GDT_Int64, 67000, GDT_UInt32, 67000);
489 1 : FROM_R(GDT_Int32, 67000, GDT_Int64, 67000);
490 1 : FROM_R(GDT_Int64, 67000, GDT_UInt64, 67000);
491 1 : FROM_R(GDT_Int64, 67000, GDT_Float32, 67000);
492 1 : FROM_R(GDT_Int64, 67000, GDT_Float64, 67000);
493 1 : FROM_R(GDT_Int64, 67000, GDT_CInt16, 32767); /* clamp */
494 1 : FROM_R(GDT_Int64, 67000, GDT_CInt32, 67000);
495 1 : FROM_R(GDT_Int64, 67000, GDT_CFloat32, 67000);
496 1 : FROM_R(GDT_Int64, 67000, GDT_CFloat64, 67000);
497 1 : }
498 :
499 4 : TEST_F(TestCopyWords, GDT_UInt64)
500 : {
501 : /* GDT_UInt64 */
502 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
503 16 : outtype = (GDALDataType)(outtype + 1))
504 : {
505 16 : FROM_R(GDT_UInt64, 0, outtype, 0);
506 16 : FROM_R(GDT_UInt64, 127, outtype, 127);
507 : }
508 :
509 1 : std::uint64_t nVal = static_cast<std::uint64_t>(3000000000) * 1000;
510 1 : FROM_R(GDT_UInt64, nVal, GDT_Byte, 255); /* clamp */
511 1 : FROM_R(GDT_UInt64, nVal, GDT_Int16, 32767); /* clamp */
512 1 : FROM_R(GDT_UInt64, nVal, GDT_UInt16, 65535); /* clamp */
513 1 : FROM_R(GDT_UInt64, nVal, GDT_Int32, 2147483647); /* clamp */
514 1 : FROM_R(GDT_UInt64, nVal, GDT_UInt32, 4294967295U); /* clamp */
515 1 : FROM_R(GDT_UInt64, nVal, GDT_Int64, nVal);
516 1 : FROM_R(GDT_UInt64, nVal, GDT_UInt64, nVal);
517 1 : FROM_R(GDT_UInt64, nVal, GDT_Float32,
518 : static_cast<uint64_t>(static_cast<float>(nVal)));
519 1 : FROM_R(GDT_UInt64, nVal, GDT_Float64, nVal);
520 1 : FROM_R(GDT_UInt64, nVal, GDT_CInt16, 32767); /* clamp */
521 1 : FROM_R(GDT_UInt64, nVal, GDT_CInt32, 2147483647); /* clamp */
522 1 : FROM_R(GDT_UInt64, nVal, GDT_CFloat32,
523 : static_cast<uint64_t>(static_cast<float>(nVal)));
524 1 : FROM_R(GDT_UInt64, nVal, GDT_CFloat64, nVal);
525 1 : }
526 :
527 4 : TEST_F(TestCopyWords, GDT_Float64)
528 : {
529 1 : FROM_R_F(GDT_Float64, std::numeric_limits<double>::max(), GDT_Float32,
530 : std::numeric_limits<double>::infinity());
531 1 : FROM_R_F(GDT_Float64, -std::numeric_limits<double>::max(), GDT_Float32,
532 : -std::numeric_limits<double>::infinity());
533 1 : FROM_R_F(GDT_Float64, std::numeric_limits<double>::quiet_NaN(), GDT_Float32,
534 : std::numeric_limits<double>::quiet_NaN());
535 1 : }
536 :
537 4 : TEST_F(TestCopyWords, GDT_Float16only)
538 : {
539 1 : GDALDataType intype = GDT_Float16;
540 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
541 16 : outtype = (GDALDataType)(outtype + 1))
542 : {
543 16 : if (IS_FLOAT(outtype))
544 : {
545 6 : FROM_R_F(intype, 127.1, outtype, 127.1);
546 6 : FROM_R_F(intype, -127.1, outtype, -127.1);
547 : }
548 : else
549 : {
550 10 : FROM_R_F(intype, 125.1, outtype, 125);
551 10 : FROM_R_F(intype, 125.9, outtype, 126);
552 :
553 10 : FROM_R_F(intype, 0.4, outtype, 0);
554 10 : FROM_R_F(intype, 0.5, outtype,
555 : 1); /* We could argue how to do this rounding */
556 10 : FROM_R_F(intype, 0.6, outtype, 1);
557 10 : FROM_R_F(intype, 126.5, outtype,
558 : 127); /* We could argue how to do this rounding */
559 :
560 10 : if (!IS_UNSIGNED(outtype))
561 : {
562 6 : FROM_R_F(intype, -125.9, outtype, -126);
563 6 : FROM_R_F(intype, -127.1, outtype, -127);
564 :
565 6 : FROM_R_F(intype, -0.4, outtype, 0);
566 6 : FROM_R_F(intype, -0.5, outtype,
567 : -1); /* We could argue how to do this rounding */
568 6 : FROM_R_F(intype, -0.6, outtype, -1);
569 6 : FROM_R_F(intype, -127.5, outtype,
570 : -128); /* We could argue how to do this rounding */
571 : }
572 : }
573 : }
574 1 : FROM_R(intype, -30000, GDT_Byte, 0);
575 1 : FROM_R(intype, -32768, GDT_Byte, 0);
576 1 : FROM_R(intype, -1, GDT_Byte, 0);
577 1 : FROM_R(intype, 256, GDT_Byte, 255);
578 1 : FROM_R(intype, 30000, GDT_Byte, 255);
579 1 : FROM_R(intype, -330000, GDT_Int16, -32768);
580 1 : FROM_R(intype, -33000, GDT_Int16, -32768);
581 1 : FROM_R(intype, 33000, GDT_Int16, 32767);
582 1 : FROM_R(intype, -33000, GDT_UInt16, 0);
583 1 : FROM_R(intype, -1, GDT_UInt16, 0);
584 1 : FROM_R(intype, 60000, GDT_UInt16, 60000);
585 1 : FROM_R(intype, -33000, GDT_Int32, -32992);
586 1 : FROM_R(intype, 33000, GDT_Int32, 32992);
587 1 : FROM_R(intype, -1, GDT_UInt32, 0);
588 1 : FROM_R(intype, 60000, GDT_UInt32, 60000U);
589 1 : FROM_R(intype, 33000, GDT_Float32, 32992);
590 1 : FROM_R(intype, -33000, GDT_Float32, -32992);
591 1 : FROM_R(intype, 33000, GDT_Float64, 32992);
592 1 : FROM_R(intype, -33000, GDT_Float64, -32992);
593 1 : FROM_R(intype, -33000, GDT_CInt16, -32768);
594 1 : FROM_R(intype, 33000, GDT_CInt16, 32767);
595 1 : FROM_R(intype, -33000, GDT_CInt32, -32992);
596 1 : FROM_R(intype, 33000, GDT_CInt32, 32992);
597 1 : FROM_R(intype, 33000, GDT_CFloat32, 32992);
598 1 : FROM_R(intype, -33000, GDT_CFloat32, -32992);
599 1 : FROM_R(intype, 33000, GDT_CFloat64, 32992);
600 1 : FROM_R(intype, -33000, GDT_CFloat64, -32992);
601 :
602 1 : FROM_R_F(GDT_Float32, std::numeric_limits<float>::min(), GDT_Float16, 0);
603 1 : FROM_R_F(GDT_Float32, -std::numeric_limits<float>::min(), GDT_Float16, 0);
604 : // smallest positive subnormal float16 number
605 1 : FROM_R_F(GDT_Float32, 0.000000059604645f, GDT_Float16, 0.000000059604645f);
606 1 : FROM_R_F(GDT_Float32, 65504.0f, GDT_Float16, 65504.0f);
607 1 : FROM_R_F(GDT_Float32, 65535.0f, GDT_Float16,
608 : std::numeric_limits<double>::infinity());
609 1 : FROM_R_F(GDT_Float32, std::numeric_limits<float>::max(), GDT_Float16,
610 : std::numeric_limits<double>::infinity());
611 1 : FROM_R_F(GDT_Float32, -std::numeric_limits<float>::max(), GDT_Float16,
612 : -std::numeric_limits<double>::infinity());
613 1 : FROM_R_F(GDT_Float32, std::numeric_limits<float>::quiet_NaN(), GDT_Float16,
614 : std::numeric_limits<double>::quiet_NaN());
615 :
616 1 : FROM_R_F(GDT_Float64, std::numeric_limits<double>::max(), GDT_Float16,
617 : std::numeric_limits<double>::infinity());
618 1 : FROM_R_F(GDT_Float64, -std::numeric_limits<double>::max(), GDT_Float16,
619 : -std::numeric_limits<double>::infinity());
620 1 : FROM_R_F(GDT_Float64, std::numeric_limits<double>::quiet_NaN(), GDT_Float16,
621 : std::numeric_limits<double>::quiet_NaN());
622 :
623 : // Float16 to Int64
624 : {
625 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::quiet_NaN();
626 1 : int64_t out_value = 0;
627 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_Int64, 0, 1);
628 1 : EXPECT_EQ(out_value, 0);
629 : }
630 :
631 : {
632 1 : GFloat16 in_value = -cpl::NumericLimits<GFloat16>::infinity();
633 1 : int64_t out_value = 0;
634 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_Int64, 0, 1);
635 1 : EXPECT_EQ(out_value, INT64_MIN);
636 : }
637 :
638 : {
639 1 : GFloat16 in_value = -cpl::NumericLimits<GFloat16>::max();
640 1 : int64_t out_value = 0;
641 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_Int64, 0, 1);
642 1 : EXPECT_EQ(out_value, -65504);
643 : }
644 :
645 : {
646 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::max();
647 1 : int64_t out_value = 0;
648 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_Int64, 0, 1);
649 1 : EXPECT_EQ(out_value, 65504);
650 : }
651 :
652 : {
653 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::infinity();
654 1 : int64_t out_value = 0;
655 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_Int64, 0, 1);
656 1 : EXPECT_EQ(out_value, INT64_MAX);
657 : }
658 :
659 : // Float16 to UInt64
660 : {
661 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::quiet_NaN();
662 1 : uint64_t out_value = 0;
663 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_UInt64, 0, 1);
664 1 : EXPECT_EQ(out_value, 0);
665 : }
666 :
667 : {
668 1 : GFloat16 in_value = -cpl::NumericLimits<GFloat16>::infinity();
669 1 : uint64_t out_value = 0;
670 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_UInt64, 0, 1);
671 1 : EXPECT_EQ(out_value, 0);
672 : }
673 :
674 : {
675 1 : GFloat16 in_value = -cpl::NumericLimits<GFloat16>::max();
676 1 : uint64_t out_value = 0;
677 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_UInt64, 0, 1);
678 1 : EXPECT_EQ(out_value, 0);
679 : }
680 :
681 : {
682 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::max();
683 1 : uint64_t out_value = 0;
684 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_UInt64, 0, 1);
685 1 : EXPECT_EQ(out_value, 65504);
686 : }
687 :
688 : {
689 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::infinity();
690 1 : uint64_t out_value = 0;
691 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_UInt64, 0, 1);
692 1 : EXPECT_EQ(out_value, UINT64_MAX);
693 : }
694 1 : }
695 :
696 4 : TEST_F(TestCopyWords, GDT_Float32and64)
697 : {
698 : /* GDT_Float32 and GDT_Float64 */
699 3 : for (int i = 0; i < 2; i++)
700 : {
701 2 : GDALDataType intype = (i == 0) ? GDT_Float32 : GDT_Float64;
702 34 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
703 32 : outtype = (GDALDataType)(outtype + 1))
704 : {
705 32 : if (IS_FLOAT(outtype))
706 : {
707 12 : FROM_R_F(intype, 127.1, outtype, 127.1);
708 12 : FROM_R_F(intype, -127.1, outtype, -127.1);
709 : }
710 : else
711 : {
712 20 : FROM_R_F(intype, 125.1, outtype, 125);
713 20 : FROM_R_F(intype, 125.9, outtype, 126);
714 :
715 20 : FROM_R_F(intype, 0.4, outtype, 0);
716 20 : FROM_R_F(intype, 0.5, outtype,
717 : 1); /* We could argue how to do this rounding */
718 20 : FROM_R_F(intype, 0.6, outtype, 1);
719 20 : FROM_R_F(intype, 126.5, outtype,
720 : 127); /* We could argue how to do this rounding */
721 :
722 20 : if (!IS_UNSIGNED(outtype))
723 : {
724 12 : FROM_R_F(intype, -125.9, outtype, -126);
725 12 : FROM_R_F(intype, -127.1, outtype, -127);
726 :
727 12 : FROM_R_F(intype, -0.4, outtype, 0);
728 12 : FROM_R_F(intype, -0.5, outtype,
729 : -1); /* We could argue how to do this rounding */
730 12 : FROM_R_F(intype, -0.6, outtype, -1);
731 12 : FROM_R_F(intype, -127.5, outtype,
732 : -128); /* We could argue how to do this rounding */
733 : }
734 : }
735 : }
736 2 : FROM_R(intype, -CST_3000000000, GDT_Byte, 0);
737 2 : FROM_R(intype, -32768, GDT_Byte, 0);
738 2 : FROM_R(intype, -1, GDT_Byte, 0);
739 2 : FROM_R(intype, 256, GDT_Byte, 255);
740 2 : FROM_R(intype, 65536, GDT_Byte, 255);
741 2 : FROM_R(intype, CST_3000000000, GDT_Byte, 255);
742 2 : FROM_R(intype, -CST_3000000000, GDT_Int16, -32768);
743 2 : FROM_R(intype, -33000, GDT_Int16, -32768);
744 2 : FROM_R(intype, 33000, GDT_Int16, 32767);
745 2 : FROM_R(intype, CST_3000000000, GDT_Int16, 32767);
746 2 : FROM_R(intype, -CST_3000000000, GDT_UInt16, 0);
747 2 : FROM_R(intype, -1, GDT_UInt16, 0);
748 2 : FROM_R(intype, 66000, GDT_UInt16, 65535);
749 2 : FROM_R(intype, CST_3000000000, GDT_UInt16, 65535);
750 2 : FROM_R(intype, -CST_3000000000, GDT_Int32, INT_MIN);
751 2 : FROM_R(intype, CST_3000000000, GDT_Int32, 2147483647);
752 2 : FROM_R(intype, -1, GDT_UInt32, 0);
753 2 : FROM_R(intype, CST_5000000000, GDT_UInt32, 4294967295UL);
754 2 : FROM_R(intype, CST_5000000000, GDT_Float32, CST_5000000000);
755 2 : FROM_R(intype, -CST_5000000000, GDT_Float32, -CST_5000000000);
756 2 : FROM_R(intype, CST_5000000000, GDT_Float64, CST_5000000000);
757 2 : FROM_R(intype, -CST_5000000000, GDT_Float64, -CST_5000000000);
758 2 : FROM_R(intype, -33000, GDT_CInt16, -32768);
759 2 : FROM_R(intype, 33000, GDT_CInt16, 32767);
760 2 : FROM_R(intype, -CST_3000000000, GDT_CInt32, INT_MIN);
761 2 : FROM_R(intype, CST_3000000000, GDT_CInt32, 2147483647);
762 2 : FROM_R(intype, CST_5000000000, GDT_CFloat32, CST_5000000000);
763 2 : FROM_R(intype, -CST_5000000000, GDT_CFloat32, -CST_5000000000);
764 2 : FROM_R(intype, CST_5000000000, GDT_CFloat64, CST_5000000000);
765 2 : FROM_R(intype, -CST_5000000000, GDT_CFloat64, -CST_5000000000);
766 : }
767 :
768 : // Float32 to Int64
769 : {
770 1 : float in_value = cpl::NumericLimits<float>::quiet_NaN();
771 1 : int64_t out_value = 0;
772 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_Int64, 0, 1);
773 1 : EXPECT_EQ(out_value, 0);
774 : }
775 :
776 : {
777 1 : float in_value = -cpl::NumericLimits<float>::infinity();
778 1 : int64_t out_value = 0;
779 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_Int64, 0, 1);
780 1 : EXPECT_EQ(out_value, INT64_MIN);
781 : }
782 :
783 : {
784 1 : float in_value = -cpl::NumericLimits<float>::max();
785 1 : int64_t out_value = 0;
786 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_Int64, 0, 1);
787 1 : EXPECT_EQ(out_value, INT64_MIN);
788 : }
789 :
790 : {
791 1 : float in_value = cpl::NumericLimits<float>::max();
792 1 : int64_t out_value = 0;
793 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_Int64, 0, 1);
794 1 : EXPECT_EQ(out_value, INT64_MAX);
795 : }
796 :
797 : {
798 1 : float in_value = cpl::NumericLimits<float>::infinity();
799 1 : int64_t out_value = 0;
800 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_Int64, 0, 1);
801 1 : EXPECT_EQ(out_value, INT64_MAX);
802 : }
803 :
804 : // Float64 to Int64
805 : {
806 1 : double in_value = cpl::NumericLimits<double>::quiet_NaN();
807 1 : int64_t out_value = 0;
808 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_Int64, 0, 1);
809 1 : EXPECT_EQ(out_value, 0);
810 : }
811 :
812 : {
813 1 : double in_value = -cpl::NumericLimits<double>::infinity();
814 1 : int64_t out_value = 0;
815 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_Int64, 0, 1);
816 1 : EXPECT_EQ(out_value, INT64_MIN);
817 : }
818 :
819 : {
820 1 : double in_value = -cpl::NumericLimits<double>::max();
821 1 : int64_t out_value = 0;
822 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_Int64, 0, 1);
823 1 : EXPECT_EQ(out_value, INT64_MIN);
824 : }
825 :
826 : {
827 1 : double in_value = cpl::NumericLimits<double>::max();
828 1 : int64_t out_value = 0;
829 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_Int64, 0, 1);
830 1 : EXPECT_EQ(out_value, INT64_MAX);
831 : }
832 :
833 : {
834 1 : double in_value = cpl::NumericLimits<double>::infinity();
835 1 : int64_t out_value = 0;
836 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_Int64, 0, 1);
837 1 : EXPECT_EQ(out_value, INT64_MAX);
838 : }
839 :
840 : // Float32 to UInt64
841 : {
842 1 : float in_value = cpl::NumericLimits<float>::quiet_NaN();
843 1 : uint64_t out_value = 0;
844 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_UInt64, 0, 1);
845 1 : EXPECT_EQ(out_value, 0);
846 : }
847 :
848 : {
849 1 : float in_value = -cpl::NumericLimits<float>::infinity();
850 1 : uint64_t out_value = 0;
851 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_UInt64, 0, 1);
852 1 : EXPECT_EQ(out_value, 0);
853 : }
854 :
855 : {
856 1 : float in_value = -cpl::NumericLimits<float>::max();
857 1 : uint64_t out_value = 0;
858 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_UInt64, 0, 1);
859 1 : EXPECT_EQ(out_value, 0);
860 : }
861 :
862 : {
863 1 : float in_value = cpl::NumericLimits<float>::max();
864 1 : uint64_t out_value = 0;
865 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_UInt64, 0, 1);
866 1 : EXPECT_EQ(out_value, UINT64_MAX);
867 : }
868 :
869 : {
870 1 : float in_value = cpl::NumericLimits<float>::infinity();
871 1 : uint64_t out_value = 0;
872 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_UInt64, 0, 1);
873 1 : EXPECT_EQ(out_value, UINT64_MAX);
874 : }
875 :
876 : // Float64 to UInt64
877 : {
878 1 : double in_value = -cpl::NumericLimits<double>::quiet_NaN();
879 1 : uint64_t out_value = 0;
880 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_UInt64, 0, 1);
881 1 : EXPECT_EQ(out_value, 0);
882 : }
883 :
884 : {
885 1 : double in_value = -cpl::NumericLimits<double>::infinity();
886 1 : uint64_t out_value = 0;
887 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_UInt64, 0, 1);
888 1 : EXPECT_EQ(out_value, 0);
889 : }
890 :
891 : {
892 1 : double in_value = -cpl::NumericLimits<double>::max();
893 1 : uint64_t out_value = 0;
894 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_UInt64, 0, 1);
895 1 : EXPECT_EQ(out_value, 0);
896 : }
897 :
898 : {
899 1 : double in_value = cpl::NumericLimits<double>::max();
900 1 : uint64_t out_value = 0;
901 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_UInt64, 0, 1);
902 1 : EXPECT_EQ(out_value, UINT64_MAX);
903 : }
904 :
905 : {
906 1 : double in_value = cpl::NumericLimits<double>::infinity();
907 1 : uint64_t out_value = 0;
908 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_UInt64, 0, 1);
909 1 : EXPECT_EQ(out_value, UINT64_MAX);
910 : }
911 1 : }
912 :
913 4 : TEST_F(TestCopyWords, GDT_CInt16)
914 : {
915 : /* GDT_CInt16 */
916 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Byte, 0, 0); /* clamp */
917 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Int16, -32000, 0);
918 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_UInt16, 0, 0); /* clamp */
919 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Int32, -32000, 0);
920 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_UInt32, 0, 0); /* clamp */
921 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Float32, -32000, 0);
922 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Float64, -32000, 0);
923 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_CInt16, -32000, -32500);
924 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_CInt32, -32000, -32500);
925 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_CFloat32, -32000, -32500);
926 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_CFloat64, -32000, -32500);
927 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
928 16 : outtype = (GDALDataType)(outtype + 1))
929 : {
930 16 : FROM_C(GDT_CInt16, 127, 128, outtype, 127, 128);
931 : }
932 :
933 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Byte, 255, 0); /* clamp */
934 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Int16, 32000, 0);
935 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_UInt16, 32000, 0);
936 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Int32, 32000, 0);
937 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_UInt32, 32000, 0);
938 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Float32, 32000, 0);
939 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Float64, 32000, 0);
940 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_CInt16, 32000, 32500);
941 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_CInt32, 32000, 32500);
942 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_CFloat32, 32000, 32500);
943 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_CFloat64, 32000, 32500);
944 1 : }
945 :
946 4 : TEST_F(TestCopyWords, GDT_CInt32)
947 : {
948 : /* GDT_CInt32 */
949 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Byte, 0, 0); /* clamp */
950 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Int16, -32768, 0); /* clamp */
951 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_UInt16, 0, 0); /* clamp */
952 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Int32, -33000, 0);
953 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_UInt32, 0, 0); /* clamp */
954 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Float32, -33000, 0);
955 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Float64, -33000, 0);
956 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_CInt16, -32768, -32768); /* clamp */
957 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_CInt32, -33000, -33500);
958 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_CFloat32, -33000, -33500);
959 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_CFloat64, -33000, -33500);
960 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
961 16 : outtype = (GDALDataType)(outtype + 1))
962 : {
963 16 : FROM_C(GDT_CInt32, 127, 128, outtype, 127, 128);
964 : }
965 :
966 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Byte, 255, 0); /* clamp */
967 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Int16, 32767, 0); /* clamp */
968 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_UInt16, 65535, 0); /* clamp */
969 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Int32, 67000, 0);
970 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_UInt32, 67000, 0);
971 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Float32, 67000, 0);
972 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Float64, 67000, 0);
973 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_CInt16, 32767, 32767); /* clamp */
974 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_CInt32, 67000, 67500);
975 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_CFloat32, 67000, 67500);
976 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_CFloat64, 67000, 67500);
977 1 : }
978 :
979 4 : TEST_F(TestCopyWords, GDT_CFloat32and64)
980 : {
981 : /* GDT_CFloat32 and GDT_CFloat64 */
982 3 : for (int i = 0; i < 2; i++)
983 : {
984 2 : GDALDataType intype = (i == 0) ? GDT_CFloat32 : GDT_CFloat64;
985 34 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
986 32 : outtype = (GDALDataType)(outtype + 1))
987 : {
988 32 : if (IS_FLOAT(outtype))
989 : {
990 12 : FROM_C_F(intype, 127.1, 127.9, outtype, 127.1, 127.9);
991 12 : FROM_C_F(intype, -127.1, -127.9, outtype, -127.1, -127.9);
992 : }
993 : else
994 : {
995 20 : FROM_C_F(intype, 126.1, 150.9, outtype, 126, 151);
996 20 : FROM_C_F(intype, 126.9, 150.1, outtype, 127, 150);
997 20 : if (!IS_UNSIGNED(outtype))
998 : {
999 12 : FROM_C_F(intype, -125.9, -127.1, outtype, -126, -127);
1000 : }
1001 : }
1002 : }
1003 2 : FROM_C(intype, -1, 256, GDT_Byte, 0, 0);
1004 2 : FROM_C(intype, 256, -1, GDT_Byte, 255, 0);
1005 2 : FROM_C(intype, -33000, 33000, GDT_Int16, -32768, 0);
1006 2 : FROM_C(intype, 33000, -33000, GDT_Int16, 32767, 0);
1007 2 : FROM_C(intype, -1, 66000, GDT_UInt16, 0, 0);
1008 2 : FROM_C(intype, 66000, -1, GDT_UInt16, 65535, 0);
1009 2 : FROM_C(intype, -CST_3000000000, -CST_3000000000, GDT_Int32, INT_MIN, 0);
1010 2 : FROM_C(intype, CST_3000000000, CST_3000000000, GDT_Int32, 2147483647,
1011 : 0);
1012 2 : FROM_C(intype, -1, CST_5000000000, GDT_UInt32, 0, 0);
1013 2 : FROM_C(intype, CST_5000000000, -1, GDT_UInt32, 4294967295UL, 0);
1014 2 : FROM_C(intype, CST_5000000000, -1, GDT_Float32, CST_5000000000, 0);
1015 2 : FROM_C(intype, CST_5000000000, -1, GDT_Float64, CST_5000000000, 0);
1016 2 : FROM_C(intype, -CST_5000000000, -1, GDT_Float32, -CST_5000000000, 0);
1017 2 : FROM_C(intype, -CST_5000000000, -1, GDT_Float64, -CST_5000000000, 0);
1018 2 : FROM_C(intype, -33000, 33000, GDT_CInt16, -32768, 32767);
1019 2 : FROM_C(intype, 33000, -33000, GDT_CInt16, 32767, -32768);
1020 2 : FROM_C(intype, -CST_3000000000, -CST_3000000000, GDT_CInt32, INT_MIN,
1021 : INT_MIN);
1022 2 : FROM_C(intype, CST_3000000000, CST_3000000000, GDT_CInt32, 2147483647,
1023 : 2147483647);
1024 2 : FROM_C(intype, CST_5000000000, -CST_5000000000, GDT_CFloat32,
1025 : CST_5000000000, -CST_5000000000);
1026 2 : FROM_C(intype, CST_5000000000, -CST_5000000000, GDT_CFloat64,
1027 : CST_5000000000, -CST_5000000000);
1028 : }
1029 1 : }
1030 :
1031 4 : TEST_F(TestCopyWords, GDT_CFloat16only)
1032 : {
1033 1 : GDALDataType intype = GDT_CFloat16;
1034 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
1035 16 : outtype = (GDALDataType)(outtype + 1))
1036 : {
1037 16 : if (IS_FLOAT(outtype))
1038 : {
1039 6 : FROM_C_F(intype, 127.1, 127.9, outtype, 127.1, 127.9);
1040 6 : FROM_C_F(intype, -127.1, -127.9, outtype, -127.1, -127.9);
1041 : }
1042 : else
1043 : {
1044 10 : FROM_C_F(intype, 126.1, 150.9, outtype, 126, 151);
1045 10 : FROM_C_F(intype, 126.9, 150.1, outtype, 127, 150);
1046 10 : if (!IS_UNSIGNED(outtype))
1047 : {
1048 6 : FROM_C_F(intype, -125.9, -127.1, outtype, -126, -127);
1049 : }
1050 : }
1051 : }
1052 1 : FROM_C(intype, -1, 256, GDT_Byte, 0, 0);
1053 1 : FROM_C(intype, 256, -1, GDT_Byte, 255, 0);
1054 1 : FROM_C(intype, -33000, 33000, GDT_Int16, -32768, 0);
1055 1 : FROM_C(intype, 33000, -33000, GDT_Int16, 32767, 0);
1056 1 : FROM_C(intype, -1, 66000, GDT_UInt16, 0, 0);
1057 1 : FROM_C(intype, 66000, -1, GDT_UInt16, 65535, 0);
1058 1 : FROM_C(intype, -33000, -33000, GDT_Int32, -32992, 0);
1059 1 : FROM_C(intype, 33000, 33000, GDT_Int32, 32992, 0);
1060 1 : FROM_C(intype, -1, 33000, GDT_UInt32, 0, 0);
1061 1 : FROM_C(intype, 33000, -1, GDT_UInt32, 32992, 0);
1062 1 : FROM_C(intype, 33000, -1, GDT_Float32, 32992, 0);
1063 1 : FROM_C(intype, 33000, -1, GDT_Float64, 32992, 0);
1064 1 : FROM_C(intype, -33000, -1, GDT_Float32, -32992, 0);
1065 1 : FROM_C(intype, -33000, -1, GDT_Float64, -32992, 0);
1066 1 : FROM_C(intype, -33000, 33000, GDT_CInt16, -32768, 32767);
1067 1 : FROM_C(intype, 33000, -33000, GDT_CInt16, 32767, -32768);
1068 1 : FROM_C(intype, -33000, -33000, GDT_CInt32, -32992, -32992);
1069 1 : FROM_C(intype, 33000, 33000, GDT_CInt32, 32992, 32992);
1070 1 : FROM_C(intype, 33000, -33000, GDT_CFloat32, 32992, -32992);
1071 1 : FROM_C(intype, 33000, -33000, GDT_CFloat64, 32992, -32992);
1072 1 : }
1073 :
1074 : template <class Tin, class Tout>
1075 121 : void CheckPackedGeneric(GDALDataType eIn, GDALDataType eOut)
1076 : {
1077 121 : const int N = 64 + 7;
1078 792 : Tin arrayIn[N];
1079 792 : Tout arrayOut[N];
1080 8712 : for (int i = 0; i < N; i++)
1081 : {
1082 : if constexpr (!std::is_integral_v<Tin> && std::is_integral_v<Tout>)
1083 : {
1084 : // Test correct rounding
1085 852 : if (i == 0 && std::is_unsigned_v<Tout>)
1086 12 : arrayIn[i] = cpl::NumericLimits<Tin>::quiet_NaN();
1087 1692 : else if ((i % 2) != 0)
1088 840 : arrayIn[i] = static_cast<Tin>(i + 0.4);
1089 : else
1090 852 : arrayIn[i] = static_cast<Tin>(i + 0.6);
1091 : }
1092 : else
1093 : {
1094 6887 : arrayIn[i] = static_cast<Tin>(i + 1);
1095 : }
1096 8591 : arrayOut[i] = 0;
1097 : }
1098 121 : GDALCopyWords(arrayIn, eIn, GDALGetDataTypeSizeBytes(eIn), arrayOut, eOut,
1099 : GDALGetDataTypeSizeBytes(eOut), N);
1100 121 : int numLine = 0;
1101 8712 : for (int i = 0; i < N; i++)
1102 : {
1103 : if constexpr (!std::is_integral_v<Tin> && std::is_integral_v<Tout>)
1104 : {
1105 852 : if (i == 0 && std::is_unsigned_v<Tout>)
1106 : {
1107 12 : MY_EXPECT(eIn, cpl::NumericLimits<Tin>::quiet_NaN(), eOut, 0,
1108 : arrayOut[i]);
1109 : }
1110 1692 : else if ((i % 2) != 0)
1111 : {
1112 840 : MY_EXPECT(eIn, i + 0.4, eOut, i, arrayOut[i]);
1113 : }
1114 : else
1115 : {
1116 852 : MY_EXPECT(eIn, i + 0.6, eOut, i + 1, arrayOut[i]);
1117 : }
1118 : }
1119 : else
1120 : {
1121 6887 : MY_EXPECT(eIn, i + 1, eOut, i + 1, arrayOut[i]);
1122 : }
1123 : }
1124 121 : }
1125 :
1126 : template <class Tin, class Tout>
1127 119 : void CheckPacked(GDALDataType eIn, GDALDataType eOut)
1128 : {
1129 119 : CheckPackedGeneric<Tin, Tout>(eIn, eOut);
1130 119 : }
1131 :
1132 : template <>
1133 1 : void CheckPacked<GUInt16, GByte>(GDALDataType eIn, GDALDataType eOut)
1134 : {
1135 1 : CheckPackedGeneric<GUInt16, GByte>(eIn, eOut);
1136 :
1137 1 : const int N = 64 + 7;
1138 1 : GUInt16 arrayIn[N] = {0};
1139 1 : GByte arrayOut[N] = {0};
1140 72 : for (int i = 0; i < N; i++)
1141 : {
1142 130 : arrayIn[i] = (i % 6) == 0 ? 254
1143 59 : : (i % 6) == 1 ? 255
1144 47 : : (i % 4) == 2 ? 256
1145 35 : : (i % 6) == 3 ? 32767
1146 23 : : (i % 6) == 4 ? 32768
1147 : : 65535;
1148 : }
1149 1 : GDALCopyWords(arrayIn, eIn, GDALGetDataTypeSizeBytes(eIn), arrayOut, eOut,
1150 : GDALGetDataTypeSizeBytes(eOut), N);
1151 1 : int numLine = 0;
1152 72 : for (int i = 0; i < N; i++)
1153 : {
1154 71 : MY_EXPECT(eIn, (int)arrayIn[i], eOut, (i % 6) == 0 ? 254 : 255,
1155 : arrayOut[i]);
1156 : }
1157 1 : }
1158 :
1159 : template <>
1160 1 : void CheckPacked<GUInt16, GInt16>(GDALDataType eIn, GDALDataType eOut)
1161 : {
1162 1 : CheckPackedGeneric<GUInt16, GInt16>(eIn, eOut);
1163 :
1164 1 : const int N = 64 + 7;
1165 1 : GUInt16 arrayIn[N] = {0};
1166 1 : GInt16 arrayOut[N] = {0};
1167 72 : for (int i = 0; i < N; i++)
1168 : {
1169 71 : arrayIn[i] = 32766 + (i % 4);
1170 : }
1171 1 : GDALCopyWords(arrayIn, eIn, GDALGetDataTypeSizeBytes(eIn), arrayOut, eOut,
1172 : GDALGetDataTypeSizeBytes(eOut), N);
1173 1 : int numLine = 0;
1174 72 : for (int i = 0; i < N; i++)
1175 : {
1176 71 : MY_EXPECT(eIn, (int)arrayIn[i], eOut, (i % 4) == 0 ? 32766 : 32767,
1177 : arrayOut[i]);
1178 : }
1179 1 : }
1180 :
1181 121 : template <class Tin> void CheckPacked(GDALDataType eIn, GDALDataType eOut)
1182 : {
1183 121 : switch (eOut)
1184 : {
1185 11 : case GDT_Byte:
1186 11 : CheckPacked<Tin, GByte>(eIn, eOut);
1187 11 : break;
1188 11 : case GDT_Int8:
1189 11 : CheckPacked<Tin, GInt8>(eIn, eOut);
1190 11 : break;
1191 11 : case GDT_UInt16:
1192 11 : CheckPacked<Tin, GUInt16>(eIn, eOut);
1193 11 : break;
1194 11 : case GDT_Int16:
1195 11 : CheckPacked<Tin, GInt16>(eIn, eOut);
1196 11 : break;
1197 11 : case GDT_UInt32:
1198 11 : CheckPacked<Tin, GUInt32>(eIn, eOut);
1199 11 : break;
1200 11 : case GDT_Int32:
1201 11 : CheckPacked<Tin, GInt32>(eIn, eOut);
1202 11 : break;
1203 11 : case GDT_UInt64:
1204 11 : CheckPacked<Tin, std::uint64_t>(eIn, eOut);
1205 11 : break;
1206 11 : case GDT_Int64:
1207 11 : CheckPacked<Tin, std::int64_t>(eIn, eOut);
1208 11 : break;
1209 11 : case GDT_Float16:
1210 11 : CheckPacked<Tin, GFloat16>(eIn, eOut);
1211 11 : break;
1212 11 : case GDT_Float32:
1213 11 : CheckPacked<Tin, float>(eIn, eOut);
1214 11 : break;
1215 11 : case GDT_Float64:
1216 11 : CheckPacked<Tin, double>(eIn, eOut);
1217 11 : break;
1218 0 : default:
1219 0 : CPLAssert(false);
1220 : }
1221 121 : }
1222 :
1223 121 : static void CheckPacked(GDALDataType eIn, GDALDataType eOut)
1224 : {
1225 121 : switch (eIn)
1226 : {
1227 11 : case GDT_Byte:
1228 11 : CheckPacked<GByte>(eIn, eOut);
1229 11 : break;
1230 11 : case GDT_Int8:
1231 11 : CheckPacked<GInt8>(eIn, eOut);
1232 11 : break;
1233 11 : case GDT_UInt16:
1234 11 : CheckPacked<GUInt16>(eIn, eOut);
1235 11 : break;
1236 11 : case GDT_Int16:
1237 11 : CheckPacked<GInt16>(eIn, eOut);
1238 11 : break;
1239 11 : case GDT_UInt32:
1240 11 : CheckPacked<GUInt32>(eIn, eOut);
1241 11 : break;
1242 11 : case GDT_Int32:
1243 11 : CheckPacked<GInt32>(eIn, eOut);
1244 11 : break;
1245 11 : case GDT_UInt64:
1246 11 : CheckPacked<std::uint64_t>(eIn, eOut);
1247 11 : break;
1248 11 : case GDT_Int64:
1249 11 : CheckPacked<std::int64_t>(eIn, eOut);
1250 11 : break;
1251 11 : case GDT_Float16:
1252 11 : CheckPacked<GFloat16>(eIn, eOut);
1253 11 : break;
1254 11 : case GDT_Float32:
1255 11 : CheckPacked<float>(eIn, eOut);
1256 11 : break;
1257 11 : case GDT_Float64:
1258 11 : CheckPacked<double>(eIn, eOut);
1259 11 : break;
1260 0 : default:
1261 0 : CPLAssert(false);
1262 : }
1263 121 : }
1264 :
1265 : class TestCopyWordsCheckPackedFixture
1266 : : public TestCopyWords,
1267 : public ::testing::WithParamInterface<
1268 : std::tuple<GDALDataType, GDALDataType>>
1269 : {
1270 : };
1271 :
1272 243 : TEST_P(TestCopyWordsCheckPackedFixture, CheckPacked)
1273 : {
1274 121 : GDALDataType eIn = std::get<0>(GetParam());
1275 121 : GDALDataType eOut = std::get<1>(GetParam());
1276 121 : CheckPacked(eIn, eOut);
1277 121 : }
1278 :
1279 : static std::vector<std::tuple<GDALDataType, GDALDataType>>
1280 1 : GetGDALDataTypeTupleValues()
1281 : {
1282 1 : std::vector<std::tuple<GDALDataType, GDALDataType>> ret;
1283 17 : for (GDALDataType eIn = GDT_Byte; eIn < GDT_TypeCount;
1284 16 : eIn = static_cast<GDALDataType>(eIn + 1))
1285 : {
1286 16 : if (GDALDataTypeIsComplex(eIn))
1287 5 : continue;
1288 187 : for (GDALDataType eOut = GDT_Byte; eOut < GDT_TypeCount;
1289 176 : eOut = static_cast<GDALDataType>(eOut + 1))
1290 : {
1291 176 : if (GDALDataTypeIsComplex(eOut))
1292 55 : continue;
1293 121 : ret.emplace_back(std::make_tuple(eIn, eOut));
1294 : }
1295 : }
1296 1 : return ret;
1297 : }
1298 :
1299 365 : INSTANTIATE_TEST_SUITE_P(
1300 : TestCopyWords, TestCopyWordsCheckPackedFixture,
1301 : ::testing::ValuesIn(GetGDALDataTypeTupleValues()),
1302 : [](const ::testing::TestParamInfo<
1303 : TestCopyWordsCheckPackedFixture::ParamType> &l_info)
1304 : {
1305 : GDALDataType eIn = std::get<0>(l_info.param);
1306 : GDALDataType eOut = std::get<1>(l_info.param);
1307 : return std::string(GDALGetDataTypeName(eIn)) + "_" +
1308 : GDALGetDataTypeName(eOut);
1309 : });
1310 :
1311 4 : TEST_F(TestCopyWords, ByteToByte)
1312 : {
1313 3 : for (int k = 0; k < 2; k++)
1314 : {
1315 2 : if (k == 1)
1316 1 : CPLSetConfigOption("GDAL_USE_SSSE3", "NO");
1317 :
1318 8 : for (int spacing = 2; spacing <= 4; spacing++)
1319 : {
1320 6 : memset(pIn, 0xff, 256);
1321 108 : for (int i = 0; i < 17; i++)
1322 : {
1323 102 : pIn[spacing * i] = (GByte)(17 - i);
1324 : }
1325 6 : memset(pOut, 0xff, 256);
1326 6 : GDALCopyWords(pIn, GDT_Byte, spacing, pOut, GDT_Byte, 1, 17);
1327 108 : for (int i = 0; i < 17; i++)
1328 : {
1329 102 : AssertRes(GDT_Byte, 17 - i, GDT_Byte, 17 - i, pOut[i],
1330 : __LINE__);
1331 : }
1332 :
1333 6 : memset(pIn, 0xff, 256);
1334 6 : memset(pOut, 0xff, 256);
1335 108 : for (int i = 0; i < 17; i++)
1336 : {
1337 102 : pIn[i] = (GByte)(17 - i);
1338 : }
1339 6 : GDALCopyWords(pIn, GDT_Byte, 1, pOut, GDT_Byte, spacing, 17);
1340 108 : for (int i = 0; i < 17; i++)
1341 : {
1342 102 : AssertRes(GDT_Byte, 17 - i, GDT_Byte, 17 - i, pOut[i * spacing],
1343 : __LINE__);
1344 306 : for (int j = 1; j < spacing; j++)
1345 : {
1346 204 : AssertRes(GDT_Byte, 0xff, GDT_Byte, 0xff,
1347 204 : pOut[i * spacing + j], __LINE__);
1348 : }
1349 : }
1350 : }
1351 : }
1352 1 : CPLSetConfigOption("GDAL_USE_SSSE3", nullptr);
1353 1 : }
1354 :
1355 4 : TEST_F(TestCopyWords, Int16ToInt16)
1356 : {
1357 1 : memset(pIn, 0xff, 256);
1358 1 : GInt16 *pInShort = (GInt16 *)pIn;
1359 1 : GInt16 *pOutShort = (GInt16 *)pOut;
1360 10 : for (int i = 0; i < 9; i++)
1361 : {
1362 9 : pInShort[2 * i + 0] = 0x1234;
1363 9 : pInShort[2 * i + 1] = 0x5678;
1364 : }
1365 5 : for (int iSpacing = 0; iSpacing < 4; iSpacing++)
1366 : {
1367 4 : memset(pOut, 0xff, 256);
1368 4 : GDALCopyWords(pInShort, GDT_Int16, sizeof(short), pOutShort, GDT_Int16,
1369 4 : (iSpacing + 1) * sizeof(short), 18);
1370 40 : for (int i = 0; i < 9; i++)
1371 : {
1372 36 : AssertRes(GDT_Int16, pInShort[2 * i + 0], GDT_Int16,
1373 36 : pInShort[2 * i + 0],
1374 36 : pOutShort[(iSpacing + 1) * (2 * i + 0)], __LINE__);
1375 36 : AssertRes(GDT_Int16, pInShort[2 * i + 1], GDT_Int16,
1376 36 : pInShort[2 * i + 1],
1377 36 : pOutShort[(iSpacing + 1) * (2 * i + 1)], __LINE__);
1378 : }
1379 : }
1380 5 : for (int iSpacing = 0; iSpacing < 4; iSpacing++)
1381 : {
1382 4 : memset(pIn, 0xff, 256);
1383 4 : memset(pOut, 0xff, 256);
1384 40 : for (int i = 0; i < 9; i++)
1385 : {
1386 36 : pInShort[(iSpacing + 1) * (2 * i + 0)] = 0x1234;
1387 36 : pInShort[(iSpacing + 1) * (2 * i + 1)] = 0x5678;
1388 : }
1389 4 : GDALCopyWords(pInShort, GDT_Int16, (iSpacing + 1) * sizeof(short),
1390 : pOutShort, GDT_Int16, sizeof(short), 18);
1391 40 : for (int i = 0; i < 9; i++)
1392 : {
1393 36 : AssertRes(GDT_Int16, pInShort[(iSpacing + 1) * (2 * i + 0)],
1394 36 : GDT_Int16, pInShort[(iSpacing + 1) * (2 * i + 0)],
1395 36 : pOutShort[2 * i + 0], __LINE__);
1396 36 : AssertRes(GDT_Int16, pInShort[(iSpacing + 1) * (2 * i + 1)],
1397 36 : GDT_Int16, pInShort[(iSpacing + 1) * (2 * i + 1)],
1398 36 : pOutShort[2 * i + 1], __LINE__);
1399 : }
1400 : }
1401 1 : }
1402 :
1403 : } // namespace
|