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 63606 : void AssertRes(GDALDataType intype, CT1 inval, GDALDataType outtype,
32 : CT2 expected_outval, OutType outval, int numLine)
33 : {
34 66344 : 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 63606 : }
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 1085 : void Test(GDALDataType intype, ConstantType inval, ConstantType invali,
75 : GDALDataType outtype, ConstantType outval, ConstantType outvali,
76 : int numLine)
77 : {
78 1085 : memset(pIn, 0xff, 1024);
79 1085 : memset(pOut, 0xff, 1024);
80 :
81 1085 : *(InType *)(pIn) = (InType)inval;
82 1085 : *(InType *)(pIn + 32) = (InType)inval;
83 1085 : 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 1085 : GDALCopyWords(pIn, intype, 32, pOut, outtype, 32, 2);
91 :
92 : /* Test negative offsets */
93 1085 : GDALCopyWords(pIn + 32, intype, -32, pOut + 1024 - 16, outtype, -32, 2);
94 :
95 1085 : MY_EXPECT(intype, inval, outtype, outval, *(OutType *)(pOut));
96 1085 : MY_EXPECT(intype, inval, outtype, outval, *(OutType *)(pOut + 32));
97 1085 : MY_EXPECT(intype, inval, outtype, outval,
98 : *(OutType *)(pOut + 1024 - 16));
99 1085 : MY_EXPECT(intype, inval, outtype, outval,
100 : *(OutType *)(pOut + 1024 - 16 - 32));
101 :
102 1085 : if (GDALDataTypeIsComplex(outtype))
103 : {
104 312 : MY_EXPECT(intype, invali, outtype, outvali, ((OutType *)(pOut))[1]);
105 312 : MY_EXPECT(intype, invali, outtype, outvali,
106 : ((OutType *)(pOut + 32))[1]);
107 :
108 312 : MY_EXPECT(intype, invali, outtype, outvali,
109 : ((OutType *)(pOut + 1024 - 16))[1]);
110 312 : MY_EXPECT(intype, invali, outtype, outvali,
111 : ((OutType *)(pOut + 1024 - 16 - 32))[1]);
112 : }
113 : else
114 : {
115 773 : constexpr int N = 32 + 31;
116 49472 : for (int i = 0; i < N; ++i)
117 : {
118 48699 : *(InType *)(pIn + i * GDALGetDataTypeSizeBytes(intype)) =
119 10017 : (InType)inval;
120 : }
121 :
122 : /* Test packed offsets */
123 773 : GDALCopyWords(pIn, intype, GDALGetDataTypeSizeBytes(intype), pOut,
124 : outtype, GDALGetDataTypeSizeBytes(outtype), N);
125 :
126 49472 : for (int i = 0; i < N; ++i)
127 : {
128 48699 : MY_EXPECT(
129 : intype, inval, outtype, outval,
130 : *(OutType *)(pOut + i * GDALGetDataTypeSizeBytes(outtype)));
131 : }
132 : }
133 1085 : }
134 :
135 : template <class InType, class ConstantType>
136 1085 : void FromR_2(GDALDataType intype, ConstantType inval, ConstantType invali,
137 : GDALDataType outtype, ConstantType outval,
138 : ConstantType outvali, int numLine)
139 : {
140 1085 : if (outtype == GDT_Byte)
141 81 : Test<InType, GByte, ConstantType>(intype, inval, invali, outtype,
142 : outval, outvali, numLine);
143 1004 : else if (outtype == GDT_Int8)
144 65 : Test<InType, GInt8, ConstantType>(intype, inval, invali, outtype,
145 : outval, outvali, numLine);
146 939 : else if (outtype == GDT_Int16)
147 96 : Test<InType, GInt16, ConstantType>(intype, inval, invali, outtype,
148 : outval, outvali, numLine);
149 843 : else if (outtype == GDT_UInt16)
150 75 : Test<InType, GUInt16, ConstantType>(intype, inval, invali, outtype,
151 : outval, outvali, numLine);
152 768 : else if (outtype == GDT_Int32)
153 101 : Test<InType, GInt32, ConstantType>(intype, inval, invali, outtype,
154 : outval, outvali, numLine);
155 667 : else if (outtype == GDT_UInt32)
156 76 : Test<InType, GUInt32, ConstantType>(intype, inval, invali, outtype,
157 : outval, outvali, numLine);
158 591 : else if (outtype == GDT_Int64)
159 75 : Test<InType, std::int64_t, ConstantType>(
160 : intype, inval, invali, outtype, outval, outvali, numLine);
161 516 : else if (outtype == GDT_UInt64)
162 54 : Test<InType, std::uint64_t, ConstantType>(
163 : intype, inval, invali, outtype, outval, outvali, numLine);
164 462 : else if (outtype == GDT_Float16)
165 39 : Test<InType, GFloat16, ConstantType>(intype, inval, invali, outtype,
166 : outval, outvali, numLine);
167 423 : else if (outtype == GDT_Float32)
168 57 : Test<InType, float, ConstantType>(intype, inval, invali, outtype,
169 : outval, outvali, numLine);
170 366 : else if (outtype == GDT_Float64)
171 54 : Test<InType, double, ConstantType>(intype, inval, invali, outtype,
172 : outval, outvali, numLine);
173 312 : else if (outtype == GDT_CInt16)
174 91 : Test<InType, GInt16, ConstantType>(intype, inval, invali, outtype,
175 : outval, outvali, numLine);
176 221 : else if (outtype == GDT_CInt32)
177 91 : 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 1085 : }
189 :
190 : template <class ConstantType>
191 1085 : void FromR(GDALDataType intype, ConstantType inval, ConstantType invali,
192 : GDALDataType outtype, ConstantType outval, ConstantType outvali,
193 : int numLine)
194 : {
195 1085 : if (intype == GDT_Byte)
196 47 : FromR_2<GByte, ConstantType>(intype, inval, invali, outtype, outval,
197 : outvali, numLine);
198 1038 : else if (intype == GDT_Int8)
199 46 : FromR_2<GInt8, ConstantType>(intype, inval, invali, outtype, outval,
200 : outvali, numLine);
201 992 : else if (intype == GDT_Int16)
202 42 : FromR_2<GInt16, ConstantType>(intype, inval, invali, outtype,
203 : outval, outvali, numLine);
204 950 : else if (intype == GDT_UInt16)
205 45 : FromR_2<GUInt16, ConstantType>(intype, inval, invali, outtype,
206 : outval, outvali, numLine);
207 905 : else if (intype == GDT_Int32)
208 57 : FromR_2<GInt32, ConstantType>(intype, inval, invali, outtype,
209 : outval, outvali, numLine);
210 848 : else if (intype == GDT_UInt32)
211 49 : FromR_2<GUInt32, ConstantType>(intype, inval, invali, outtype,
212 : outval, outvali, numLine);
213 799 : else if (intype == GDT_Int64)
214 39 : FromR_2<std::int64_t, ConstantType>(intype, inval, invali, outtype,
215 : outval, outvali, numLine);
216 760 : else if (intype == GDT_UInt64)
217 45 : FromR_2<std::uint64_t, ConstantType>(intype, inval, invali, outtype,
218 : outval, outvali, numLine);
219 715 : else if (intype == GDT_Float16)
220 135 : FromR_2<GFloat16, ConstantType>(intype, inval, invali, outtype,
221 : outval, outvali, numLine);
222 580 : else if (intype == GDT_Float32)
223 166 : FromR_2<float, ConstantType>(intype, inval, invali, outtype, outval,
224 : outvali, numLine);
225 414 : else if (intype == GDT_Float64)
226 164 : 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 1085 : }
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 :
436 1 : FROM_R(GDT_Int32, INT_MIN, GDT_Int32, INT_MIN);
437 1 : FROM_R(GDT_Int32, INT_MIN + 1, GDT_Int32, INT_MIN + 1);
438 1 : FROM_R(GDT_Int32, -1, GDT_Int32, -1);
439 1 : FROM_R(GDT_Int32, 1, GDT_Int32, 1);
440 1 : FROM_R(GDT_Int32, INT_MAX - 1, GDT_Int32, INT_MAX - 1);
441 1 : FROM_R(GDT_Int32, INT_MAX, GDT_Int32, INT_MAX);
442 :
443 1 : FROM_R(GDT_Int32, INT_MIN, GDT_UInt32, 0);
444 1 : FROM_R(GDT_Int32, INT_MIN + 1, GDT_UInt32, 0);
445 1 : FROM_R(GDT_Int32, -1, GDT_UInt32, 0);
446 1 : FROM_R(GDT_Int32, 1, GDT_UInt32, 1);
447 1 : FROM_R(GDT_Int32, INT_MAX - 1, GDT_UInt32, INT_MAX - 1);
448 1 : FROM_R(GDT_Int32, INT_MAX, GDT_UInt32, INT_MAX);
449 1 : }
450 :
451 4 : TEST_F(TestCopyWords, GDT_UInt32)
452 : {
453 : /* GDT_UInt32 */
454 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
455 16 : outtype = (GDALDataType)(outtype + 1))
456 : {
457 16 : FROM_R(GDT_UInt32, 0, outtype, 0);
458 16 : FROM_R(GDT_UInt32, 127, outtype, 127);
459 : }
460 :
461 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_Byte, 255); /* clamp */
462 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_Int16, 32767); /* clamp */
463 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_UInt16, 65535); /* clamp */
464 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_Int32, INT_MAX); /* clamp */
465 1 : FROM_R(GDT_UInt32, INT_MAX - 1, GDT_Int32, INT_MAX - 1);
466 1 : FROM_R(GDT_UInt32, INT_MAX, GDT_Int32, INT_MAX);
467 1 : FROM_R(GDT_UInt32, 1U << 31U, GDT_Int32, INT_MAX); /* clamp */
468 1 : FROM_R(GDT_UInt32, UINT32_MAX, GDT_Int32, INT_MAX); /* clamp */
469 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_UInt32, 3000000000U);
470 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_Int64, 3000000000U);
471 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_UInt64, 3000000000U);
472 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_Float32, 3000000000U);
473 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_Float64, 3000000000U);
474 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_CInt16, 32767); /* clamp */
475 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_CInt32, INT_MAX); /* clamp */
476 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_CFloat32, 3000000000U);
477 1 : FROM_R(GDT_UInt32, 3000000000U, GDT_CFloat64, 3000000000U);
478 1 : }
479 :
480 4 : TEST_F(TestCopyWords, check_GDT_Int64)
481 : {
482 : /* GDT_Int64 */
483 1 : FROM_R(GDT_Int64, -33000, GDT_Byte, 0); /* clamp */
484 1 : FROM_R(GDT_Int64, -33000, GDT_Int16, -32768); /* clamp */
485 1 : FROM_R(GDT_Int64, -33000, GDT_UInt16, 0); /* clamp */
486 1 : FROM_R(GDT_Int64, -33000, GDT_Int32, -33000);
487 1 : FROM_R(GDT_Int64, -33000, GDT_UInt32, 0); /* clamp */
488 1 : FROM_R(GDT_Int64, -33000, GDT_Int64, -33000);
489 1 : FROM_R(GDT_Int64, -33000, GDT_UInt64, 0); /* clamp */
490 1 : FROM_R(GDT_Int64, -33000, GDT_Float32, -33000);
491 1 : FROM_R(GDT_Int64, -33000, GDT_Float64, -33000);
492 1 : FROM_R(GDT_Int64, -33000, GDT_CInt16, -32768); /* clamp */
493 1 : FROM_R(GDT_Int64, -33000, GDT_CInt32, -33000);
494 1 : FROM_R(GDT_Int64, -33000, GDT_CFloat32, -33000);
495 1 : FROM_R(GDT_Int64, -33000, GDT_CFloat64, -33000);
496 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
497 16 : outtype = (GDALDataType)(outtype + 1))
498 : {
499 16 : FROM_R(GDT_Int64, 127, outtype, 127);
500 : }
501 :
502 1 : FROM_R(GDT_Int64, 67000, GDT_Byte, 255); /* clamp */
503 1 : FROM_R(GDT_Int64, 67000, GDT_Int16, 32767); /* clamp */
504 1 : FROM_R(GDT_Int32, 67000, GDT_UInt16, 65535); /* clamp */
505 1 : FROM_R(GDT_Int32, 67000, GDT_Int32, 67000);
506 1 : FROM_R(GDT_Int64, 67000, GDT_UInt32, 67000);
507 1 : FROM_R(GDT_Int32, 67000, GDT_Int64, 67000);
508 1 : FROM_R(GDT_Int64, 67000, GDT_UInt64, 67000);
509 1 : FROM_R(GDT_Int64, 67000, GDT_Float32, 67000);
510 1 : FROM_R(GDT_Int64, 67000, GDT_Float64, 67000);
511 1 : FROM_R(GDT_Int64, 67000, GDT_CInt16, 32767); /* clamp */
512 1 : FROM_R(GDT_Int64, 67000, GDT_CInt32, 67000);
513 1 : FROM_R(GDT_Int64, 67000, GDT_CFloat32, 67000);
514 1 : FROM_R(GDT_Int64, 67000, GDT_CFloat64, 67000);
515 1 : }
516 :
517 4 : TEST_F(TestCopyWords, GDT_UInt64)
518 : {
519 : /* GDT_UInt64 */
520 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
521 16 : outtype = (GDALDataType)(outtype + 1))
522 : {
523 16 : FROM_R(GDT_UInt64, 0, outtype, 0);
524 16 : FROM_R(GDT_UInt64, 127, outtype, 127);
525 : }
526 :
527 1 : std::uint64_t nVal = static_cast<std::uint64_t>(3000000000) * 1000;
528 1 : FROM_R(GDT_UInt64, nVal, GDT_Byte, 255); /* clamp */
529 1 : FROM_R(GDT_UInt64, nVal, GDT_Int16, 32767); /* clamp */
530 1 : FROM_R(GDT_UInt64, nVal, GDT_UInt16, 65535); /* clamp */
531 1 : FROM_R(GDT_UInt64, nVal, GDT_Int32, 2147483647); /* clamp */
532 1 : FROM_R(GDT_UInt64, nVal, GDT_UInt32, 4294967295U); /* clamp */
533 1 : FROM_R(GDT_UInt64, nVal, GDT_Int64, nVal);
534 1 : FROM_R(GDT_UInt64, nVal, GDT_UInt64, nVal);
535 1 : FROM_R(GDT_UInt64, nVal, GDT_Float32,
536 : static_cast<uint64_t>(static_cast<float>(nVal)));
537 1 : FROM_R(GDT_UInt64, nVal, GDT_Float64, nVal);
538 1 : FROM_R(GDT_UInt64, nVal, GDT_CInt16, 32767); /* clamp */
539 1 : FROM_R(GDT_UInt64, nVal, GDT_CInt32, 2147483647); /* clamp */
540 1 : FROM_R(GDT_UInt64, nVal, GDT_CFloat32,
541 : static_cast<uint64_t>(static_cast<float>(nVal)));
542 1 : FROM_R(GDT_UInt64, nVal, GDT_CFloat64, nVal);
543 1 : }
544 :
545 4 : TEST_F(TestCopyWords, GDT_Float64)
546 : {
547 1 : FROM_R_F(GDT_Float64, std::numeric_limits<double>::max(), GDT_Float32,
548 : std::numeric_limits<double>::infinity());
549 1 : FROM_R_F(GDT_Float64, -std::numeric_limits<double>::max(), GDT_Float32,
550 : -std::numeric_limits<double>::infinity());
551 1 : FROM_R_F(GDT_Float64, std::numeric_limits<double>::quiet_NaN(), GDT_Float32,
552 : std::numeric_limits<double>::quiet_NaN());
553 1 : }
554 :
555 4 : TEST_F(TestCopyWords, GDT_Float16only)
556 : {
557 1 : GDALDataType intype = GDT_Float16;
558 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
559 16 : outtype = (GDALDataType)(outtype + 1))
560 : {
561 16 : if (IS_FLOAT(outtype))
562 : {
563 6 : FROM_R_F(intype, 127.1, outtype, 127.1);
564 6 : FROM_R_F(intype, -127.1, outtype, -127.1);
565 : }
566 : else
567 : {
568 10 : FROM_R_F(intype, 125.1, outtype, 125);
569 10 : FROM_R_F(intype, 125.9, outtype, 126);
570 :
571 10 : FROM_R_F(intype, 0.4, outtype, 0);
572 10 : FROM_R_F(intype, 0.5, outtype,
573 : 1); /* We could argue how to do this rounding */
574 10 : FROM_R_F(intype, 0.6, outtype, 1);
575 10 : FROM_R_F(intype, 126.5, outtype,
576 : 127); /* We could argue how to do this rounding */
577 :
578 10 : if (!IS_UNSIGNED(outtype))
579 : {
580 6 : FROM_R_F(intype, -125.9, outtype, -126);
581 6 : FROM_R_F(intype, -127.1, outtype, -127);
582 :
583 6 : FROM_R_F(intype, -0.4, outtype, 0);
584 6 : FROM_R_F(intype, -0.5, outtype,
585 : -1); /* We could argue how to do this rounding */
586 6 : FROM_R_F(intype, -0.6, outtype, -1);
587 6 : FROM_R_F(intype, -127.5, outtype,
588 : -128); /* We could argue how to do this rounding */
589 : }
590 : }
591 : }
592 1 : FROM_R(intype, -30000, GDT_Byte, 0);
593 1 : FROM_R(intype, -32768, GDT_Byte, 0);
594 1 : FROM_R(intype, -1, GDT_Byte, 0);
595 1 : FROM_R(intype, 256, GDT_Byte, 255);
596 1 : FROM_R(intype, 30000, GDT_Byte, 255);
597 1 : FROM_R(intype, -330000, GDT_Int16, -32768);
598 1 : FROM_R(intype, -33000, GDT_Int16, -32768);
599 1 : FROM_R(intype, 33000, GDT_Int16, 32767);
600 1 : FROM_R(intype, -33000, GDT_UInt16, 0);
601 1 : FROM_R(intype, -1, GDT_UInt16, 0);
602 1 : FROM_R(intype, 60000, GDT_UInt16, 60000);
603 1 : FROM_R(intype, -33000, GDT_Int32, -32992);
604 1 : FROM_R(intype, 33000, GDT_Int32, 32992);
605 1 : FROM_R(intype, -1, GDT_UInt32, 0);
606 1 : FROM_R(intype, 60000, GDT_UInt32, 60000U);
607 1 : FROM_R(intype, 33000, GDT_Float32, 32992);
608 1 : FROM_R(intype, -33000, GDT_Float32, -32992);
609 1 : FROM_R(intype, 33000, GDT_Float64, 32992);
610 1 : FROM_R(intype, -33000, GDT_Float64, -32992);
611 1 : FROM_R(intype, -33000, GDT_CInt16, -32768);
612 1 : FROM_R(intype, 33000, GDT_CInt16, 32767);
613 1 : FROM_R(intype, -33000, GDT_CInt32, -32992);
614 1 : FROM_R(intype, 33000, GDT_CInt32, 32992);
615 1 : FROM_R(intype, 33000, GDT_CFloat32, 32992);
616 1 : FROM_R(intype, -33000, GDT_CFloat32, -32992);
617 1 : FROM_R(intype, 33000, GDT_CFloat64, 32992);
618 1 : FROM_R(intype, -33000, GDT_CFloat64, -32992);
619 :
620 1 : FROM_R_F(GDT_Float32, std::numeric_limits<float>::min(), GDT_Float16, 0);
621 1 : FROM_R_F(GDT_Float32, -std::numeric_limits<float>::min(), GDT_Float16, 0);
622 : // smallest positive subnormal float16 number
623 1 : FROM_R_F(GDT_Float32, 0.000000059604645f, GDT_Float16, 0.000000059604645f);
624 1 : FROM_R_F(GDT_Float32, 65504.0f, GDT_Float16, 65504.0f);
625 1 : FROM_R_F(GDT_Float32, 65535.0f, GDT_Float16,
626 : std::numeric_limits<double>::infinity());
627 1 : FROM_R_F(GDT_Float32, std::numeric_limits<float>::max(), GDT_Float16,
628 : std::numeric_limits<double>::infinity());
629 1 : FROM_R_F(GDT_Float32, -std::numeric_limits<float>::max(), GDT_Float16,
630 : -std::numeric_limits<double>::infinity());
631 1 : FROM_R_F(GDT_Float32, std::numeric_limits<float>::quiet_NaN(), GDT_Float16,
632 : std::numeric_limits<double>::quiet_NaN());
633 :
634 1 : FROM_R_F(GDT_Float64, std::numeric_limits<double>::max(), GDT_Float16,
635 : std::numeric_limits<double>::infinity());
636 1 : FROM_R_F(GDT_Float64, -std::numeric_limits<double>::max(), GDT_Float16,
637 : -std::numeric_limits<double>::infinity());
638 1 : FROM_R_F(GDT_Float64, std::numeric_limits<double>::quiet_NaN(), GDT_Float16,
639 : std::numeric_limits<double>::quiet_NaN());
640 :
641 : // Float16 to Int64
642 : {
643 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::quiet_NaN();
644 1 : int64_t out_value = 0;
645 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_Int64, 0, 1);
646 1 : EXPECT_EQ(out_value, 0);
647 : }
648 :
649 : {
650 1 : GFloat16 in_value = -cpl::NumericLimits<GFloat16>::infinity();
651 1 : int64_t out_value = 0;
652 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_Int64, 0, 1);
653 1 : EXPECT_EQ(out_value, INT64_MIN);
654 : }
655 :
656 : {
657 1 : GFloat16 in_value = -cpl::NumericLimits<GFloat16>::max();
658 1 : int64_t out_value = 0;
659 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_Int64, 0, 1);
660 1 : EXPECT_EQ(out_value, -65504);
661 : }
662 :
663 : {
664 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::max();
665 1 : int64_t out_value = 0;
666 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_Int64, 0, 1);
667 1 : EXPECT_EQ(out_value, 65504);
668 : }
669 :
670 : {
671 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::infinity();
672 1 : int64_t out_value = 0;
673 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_Int64, 0, 1);
674 1 : EXPECT_EQ(out_value, INT64_MAX);
675 : }
676 :
677 : // Float16 to UInt64
678 : {
679 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::quiet_NaN();
680 1 : uint64_t out_value = 0;
681 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_UInt64, 0, 1);
682 1 : EXPECT_EQ(out_value, 0);
683 : }
684 :
685 : {
686 1 : GFloat16 in_value = -cpl::NumericLimits<GFloat16>::infinity();
687 1 : uint64_t out_value = 0;
688 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_UInt64, 0, 1);
689 1 : EXPECT_EQ(out_value, 0);
690 : }
691 :
692 : {
693 1 : GFloat16 in_value = -cpl::NumericLimits<GFloat16>::max();
694 1 : uint64_t out_value = 0;
695 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_UInt64, 0, 1);
696 1 : EXPECT_EQ(out_value, 0);
697 : }
698 :
699 : {
700 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::max();
701 1 : uint64_t out_value = 0;
702 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_UInt64, 0, 1);
703 1 : EXPECT_EQ(out_value, 65504);
704 : }
705 :
706 : {
707 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::infinity();
708 1 : uint64_t out_value = 0;
709 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_UInt64, 0, 1);
710 1 : EXPECT_EQ(out_value, UINT64_MAX);
711 : }
712 1 : }
713 :
714 4 : TEST_F(TestCopyWords, GDT_Float32and64)
715 : {
716 : /* GDT_Float32 and GDT_Float64 */
717 3 : for (int i = 0; i < 2; i++)
718 : {
719 2 : const GDALDataType intype = (i == 0) ? GDT_Float32 : GDT_Float64;
720 34 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
721 32 : outtype = (GDALDataType)(outtype + 1))
722 : {
723 32 : if (IS_FLOAT(outtype))
724 : {
725 12 : FROM_R_F(intype, 127.1, outtype, 127.1);
726 12 : FROM_R_F(intype, -127.1, outtype, -127.1);
727 : }
728 : else
729 : {
730 20 : FROM_R_F(intype, 125.1, outtype, 125);
731 20 : FROM_R_F(intype, 125.9, outtype, 126);
732 :
733 20 : FROM_R_F(intype, 0.4, outtype, 0);
734 20 : FROM_R_F(intype, 0.5, outtype,
735 : 1); /* We could argue how to do this rounding */
736 20 : FROM_R_F(intype, 0.6, outtype, 1);
737 20 : FROM_R_F(intype, 126.5, outtype,
738 : 127); /* We could argue how to do this rounding */
739 :
740 20 : if (!IS_UNSIGNED(outtype))
741 : {
742 12 : FROM_R_F(intype, -125.9, outtype, -126);
743 12 : FROM_R_F(intype, -127.1, outtype, -127);
744 :
745 12 : FROM_R_F(intype, -0.4, outtype, 0);
746 12 : FROM_R_F(intype, -0.5, outtype,
747 : -1); /* We could argue how to do this rounding */
748 12 : FROM_R_F(intype, -0.6, outtype, -1);
749 12 : FROM_R_F(intype, -127.5, outtype,
750 : -128); /* We could argue how to do this rounding */
751 : }
752 :
753 20 : FROM_R_F(intype, std::numeric_limits<float>::quiet_NaN(),
754 : outtype, 0);
755 :
756 20 : constexpr double NEGATIVE_ZERO =
757 : -1.0f / std::numeric_limits<float>::infinity();
758 20 : FROM_R_F(intype, NEGATIVE_ZERO, outtype, 0);
759 : }
760 : }
761 2 : FROM_R(intype, -CST_3000000000, GDT_Byte, 0);
762 2 : FROM_R(intype, -32768, GDT_Byte, 0);
763 2 : FROM_R(intype, -1, GDT_Byte, 0);
764 2 : FROM_R(intype, 256, GDT_Byte, 255);
765 2 : FROM_R(intype, 65536, GDT_Byte, 255);
766 2 : FROM_R(intype, CST_3000000000, GDT_Byte, 255);
767 2 : FROM_R(intype, -CST_3000000000, GDT_Int16, -32768);
768 2 : FROM_R(intype, -33000, GDT_Int16, -32768);
769 2 : FROM_R(intype, 33000, GDT_Int16, 32767);
770 2 : FROM_R(intype, CST_3000000000, GDT_Int16, 32767);
771 2 : FROM_R(intype, -CST_3000000000, GDT_UInt16, 0);
772 2 : FROM_R(intype, -1, GDT_UInt16, 0);
773 2 : FROM_R(intype, 66000, GDT_UInt16, 65535);
774 2 : FROM_R(intype, CST_3000000000, GDT_UInt16, 65535);
775 2 : FROM_R(intype, -CST_3000000000, GDT_Int32, INT_MIN);
776 2 : FROM_R(intype, CST_3000000000, GDT_Int32, 2147483647);
777 2 : FROM_R(intype, -1, GDT_UInt32, 0);
778 2 : FROM_R(intype, CST_5000000000, GDT_UInt32, 4294967295UL);
779 2 : FROM_R(intype, CST_5000000000, GDT_Float32, CST_5000000000);
780 2 : FROM_R(intype, -CST_5000000000, GDT_Float32, -CST_5000000000);
781 2 : FROM_R(intype, CST_5000000000, GDT_Float64, CST_5000000000);
782 2 : FROM_R(intype, -CST_5000000000, GDT_Float64, -CST_5000000000);
783 2 : FROM_R(intype, -33000, GDT_CInt16, -32768);
784 2 : FROM_R(intype, 33000, GDT_CInt16, 32767);
785 2 : FROM_R(intype, -CST_3000000000, GDT_CInt32, INT_MIN);
786 2 : FROM_R(intype, CST_3000000000, GDT_CInt32, 2147483647);
787 2 : FROM_R(intype, CST_5000000000, GDT_CFloat32, CST_5000000000);
788 2 : FROM_R(intype, -CST_5000000000, GDT_CFloat32, -CST_5000000000);
789 2 : FROM_R(intype, CST_5000000000, GDT_CFloat64, CST_5000000000);
790 2 : FROM_R(intype, -CST_5000000000, GDT_CFloat64, -CST_5000000000);
791 : }
792 :
793 : // Float32 to Int64
794 : {
795 1 : float in_value = cpl::NumericLimits<float>::quiet_NaN();
796 1 : int64_t out_value = 0;
797 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_Int64, 0, 1);
798 1 : EXPECT_EQ(out_value, 0);
799 : }
800 :
801 : {
802 1 : float in_value = -cpl::NumericLimits<float>::infinity();
803 1 : int64_t out_value = 0;
804 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_Int64, 0, 1);
805 1 : EXPECT_EQ(out_value, INT64_MIN);
806 : }
807 :
808 : {
809 1 : float in_value = -cpl::NumericLimits<float>::max();
810 1 : int64_t out_value = 0;
811 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_Int64, 0, 1);
812 1 : EXPECT_EQ(out_value, INT64_MIN);
813 : }
814 :
815 : {
816 1 : float in_value = cpl::NumericLimits<float>::max();
817 1 : int64_t out_value = 0;
818 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_Int64, 0, 1);
819 1 : EXPECT_EQ(out_value, INT64_MAX);
820 : }
821 :
822 : {
823 1 : float in_value = cpl::NumericLimits<float>::infinity();
824 1 : int64_t out_value = 0;
825 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_Int64, 0, 1);
826 1 : EXPECT_EQ(out_value, INT64_MAX);
827 : }
828 :
829 : // Float64 to Int64
830 : {
831 1 : double in_value = cpl::NumericLimits<double>::quiet_NaN();
832 1 : int64_t out_value = 0;
833 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_Int64, 0, 1);
834 1 : EXPECT_EQ(out_value, 0);
835 : }
836 :
837 : {
838 1 : double in_value = -cpl::NumericLimits<double>::infinity();
839 1 : int64_t out_value = 0;
840 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_Int64, 0, 1);
841 1 : EXPECT_EQ(out_value, INT64_MIN);
842 : }
843 :
844 : {
845 1 : double in_value = -cpl::NumericLimits<double>::max();
846 1 : int64_t out_value = 0;
847 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_Int64, 0, 1);
848 1 : EXPECT_EQ(out_value, INT64_MIN);
849 : }
850 :
851 : {
852 1 : double in_value = cpl::NumericLimits<double>::max();
853 1 : int64_t out_value = 0;
854 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_Int64, 0, 1);
855 1 : EXPECT_EQ(out_value, INT64_MAX);
856 : }
857 :
858 : {
859 1 : double in_value = cpl::NumericLimits<double>::infinity();
860 1 : int64_t out_value = 0;
861 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_Int64, 0, 1);
862 1 : EXPECT_EQ(out_value, INT64_MAX);
863 : }
864 :
865 : // Float32 to UInt64
866 : {
867 1 : float in_value = cpl::NumericLimits<float>::quiet_NaN();
868 1 : uint64_t out_value = 0;
869 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_UInt64, 0, 1);
870 1 : EXPECT_EQ(out_value, 0);
871 : }
872 :
873 : {
874 1 : float in_value = -cpl::NumericLimits<float>::infinity();
875 1 : uint64_t out_value = 0;
876 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_UInt64, 0, 1);
877 1 : EXPECT_EQ(out_value, 0);
878 : }
879 :
880 : {
881 1 : float in_value = -cpl::NumericLimits<float>::max();
882 1 : uint64_t out_value = 0;
883 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_UInt64, 0, 1);
884 1 : EXPECT_EQ(out_value, 0);
885 : }
886 :
887 : {
888 1 : float in_value = cpl::NumericLimits<float>::max();
889 1 : uint64_t out_value = 0;
890 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_UInt64, 0, 1);
891 1 : EXPECT_EQ(out_value, UINT64_MAX);
892 : }
893 :
894 : {
895 1 : float in_value = cpl::NumericLimits<float>::infinity();
896 1 : uint64_t out_value = 0;
897 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_UInt64, 0, 1);
898 1 : EXPECT_EQ(out_value, UINT64_MAX);
899 : }
900 :
901 : // Float64 to UInt64
902 : {
903 1 : double in_value = -cpl::NumericLimits<double>::quiet_NaN();
904 1 : uint64_t out_value = 0;
905 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_UInt64, 0, 1);
906 1 : EXPECT_EQ(out_value, 0);
907 : }
908 :
909 : {
910 1 : double in_value = -cpl::NumericLimits<double>::infinity();
911 1 : uint64_t out_value = 0;
912 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_UInt64, 0, 1);
913 1 : EXPECT_EQ(out_value, 0);
914 : }
915 :
916 : {
917 1 : double in_value = -cpl::NumericLimits<double>::max();
918 1 : uint64_t out_value = 0;
919 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_UInt64, 0, 1);
920 1 : EXPECT_EQ(out_value, 0);
921 : }
922 :
923 : {
924 1 : double in_value = cpl::NumericLimits<double>::max();
925 1 : uint64_t out_value = 0;
926 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_UInt64, 0, 1);
927 1 : EXPECT_EQ(out_value, UINT64_MAX);
928 : }
929 :
930 : {
931 1 : double in_value = cpl::NumericLimits<double>::infinity();
932 1 : uint64_t out_value = 0;
933 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_UInt64, 0, 1);
934 1 : EXPECT_EQ(out_value, UINT64_MAX);
935 : }
936 1 : }
937 :
938 4 : TEST_F(TestCopyWords, GDT_CInt16)
939 : {
940 : /* GDT_CInt16 */
941 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Byte, 0, 0); /* clamp */
942 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Int16, -32000, 0);
943 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_UInt16, 0, 0); /* clamp */
944 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Int32, -32000, 0);
945 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_UInt32, 0, 0); /* clamp */
946 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Float32, -32000, 0);
947 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Float64, -32000, 0);
948 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_CInt16, -32000, -32500);
949 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_CInt32, -32000, -32500);
950 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_CFloat32, -32000, -32500);
951 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_CFloat64, -32000, -32500);
952 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
953 16 : outtype = (GDALDataType)(outtype + 1))
954 : {
955 16 : FROM_C(GDT_CInt16, 127, 128, outtype, 127, 128);
956 : }
957 :
958 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Byte, 255, 0); /* clamp */
959 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Int16, 32000, 0);
960 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_UInt16, 32000, 0);
961 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Int32, 32000, 0);
962 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_UInt32, 32000, 0);
963 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Float32, 32000, 0);
964 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Float64, 32000, 0);
965 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_CInt16, 32000, 32500);
966 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_CInt32, 32000, 32500);
967 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_CFloat32, 32000, 32500);
968 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_CFloat64, 32000, 32500);
969 1 : }
970 :
971 4 : TEST_F(TestCopyWords, GDT_CInt32)
972 : {
973 : /* GDT_CInt32 */
974 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Byte, 0, 0); /* clamp */
975 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Int16, -32768, 0); /* clamp */
976 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_UInt16, 0, 0); /* clamp */
977 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Int32, -33000, 0);
978 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_UInt32, 0, 0); /* clamp */
979 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Float32, -33000, 0);
980 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Float64, -33000, 0);
981 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_CInt16, -32768, -32768); /* clamp */
982 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_CInt32, -33000, -33500);
983 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_CFloat32, -33000, -33500);
984 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_CFloat64, -33000, -33500);
985 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
986 16 : outtype = (GDALDataType)(outtype + 1))
987 : {
988 16 : FROM_C(GDT_CInt32, 127, 128, outtype, 127, 128);
989 : }
990 :
991 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Byte, 255, 0); /* clamp */
992 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Int16, 32767, 0); /* clamp */
993 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_UInt16, 65535, 0); /* clamp */
994 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Int32, 67000, 0);
995 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_UInt32, 67000, 0);
996 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Float32, 67000, 0);
997 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Float64, 67000, 0);
998 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_CInt16, 32767, 32767); /* clamp */
999 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_CInt32, 67000, 67500);
1000 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_CFloat32, 67000, 67500);
1001 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_CFloat64, 67000, 67500);
1002 1 : }
1003 :
1004 4 : TEST_F(TestCopyWords, GDT_CFloat32and64)
1005 : {
1006 : /* GDT_CFloat32 and GDT_CFloat64 */
1007 3 : for (int i = 0; i < 2; i++)
1008 : {
1009 2 : GDALDataType intype = (i == 0) ? GDT_CFloat32 : GDT_CFloat64;
1010 34 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
1011 32 : outtype = (GDALDataType)(outtype + 1))
1012 : {
1013 32 : if (IS_FLOAT(outtype))
1014 : {
1015 12 : FROM_C_F(intype, 127.1, 127.9, outtype, 127.1, 127.9);
1016 12 : FROM_C_F(intype, -127.1, -127.9, outtype, -127.1, -127.9);
1017 : }
1018 : else
1019 : {
1020 20 : FROM_C_F(intype, 126.1, 150.9, outtype, 126, 151);
1021 20 : FROM_C_F(intype, 126.9, 150.1, outtype, 127, 150);
1022 20 : if (!IS_UNSIGNED(outtype))
1023 : {
1024 12 : FROM_C_F(intype, -125.9, -127.1, outtype, -126, -127);
1025 : }
1026 : }
1027 : }
1028 2 : FROM_C(intype, -1, 256, GDT_Byte, 0, 0);
1029 2 : FROM_C(intype, 256, -1, GDT_Byte, 255, 0);
1030 2 : FROM_C(intype, -33000, 33000, GDT_Int16, -32768, 0);
1031 2 : FROM_C(intype, 33000, -33000, GDT_Int16, 32767, 0);
1032 2 : FROM_C(intype, -1, 66000, GDT_UInt16, 0, 0);
1033 2 : FROM_C(intype, 66000, -1, GDT_UInt16, 65535, 0);
1034 2 : FROM_C(intype, -CST_3000000000, -CST_3000000000, GDT_Int32, INT_MIN, 0);
1035 2 : FROM_C(intype, CST_3000000000, CST_3000000000, GDT_Int32, 2147483647,
1036 : 0);
1037 2 : FROM_C(intype, -1, CST_5000000000, GDT_UInt32, 0, 0);
1038 2 : FROM_C(intype, CST_5000000000, -1, GDT_UInt32, 4294967295UL, 0);
1039 2 : FROM_C(intype, CST_5000000000, -1, GDT_Float32, CST_5000000000, 0);
1040 2 : FROM_C(intype, CST_5000000000, -1, GDT_Float64, CST_5000000000, 0);
1041 2 : FROM_C(intype, -CST_5000000000, -1, GDT_Float32, -CST_5000000000, 0);
1042 2 : FROM_C(intype, -CST_5000000000, -1, GDT_Float64, -CST_5000000000, 0);
1043 2 : FROM_C(intype, -33000, 33000, GDT_CInt16, -32768, 32767);
1044 2 : FROM_C(intype, 33000, -33000, GDT_CInt16, 32767, -32768);
1045 2 : FROM_C(intype, -CST_3000000000, -CST_3000000000, GDT_CInt32, INT_MIN,
1046 : INT_MIN);
1047 2 : FROM_C(intype, CST_3000000000, CST_3000000000, GDT_CInt32, 2147483647,
1048 : 2147483647);
1049 2 : FROM_C(intype, CST_5000000000, -CST_5000000000, GDT_CFloat32,
1050 : CST_5000000000, -CST_5000000000);
1051 2 : FROM_C(intype, CST_5000000000, -CST_5000000000, GDT_CFloat64,
1052 : CST_5000000000, -CST_5000000000);
1053 : }
1054 1 : }
1055 :
1056 4 : TEST_F(TestCopyWords, GDT_CFloat16only)
1057 : {
1058 1 : GDALDataType intype = GDT_CFloat16;
1059 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
1060 16 : outtype = (GDALDataType)(outtype + 1))
1061 : {
1062 16 : if (IS_FLOAT(outtype))
1063 : {
1064 6 : FROM_C_F(intype, 127.1, 127.9, outtype, 127.1, 127.9);
1065 6 : FROM_C_F(intype, -127.1, -127.9, outtype, -127.1, -127.9);
1066 : }
1067 : else
1068 : {
1069 10 : FROM_C_F(intype, 126.1, 150.9, outtype, 126, 151);
1070 10 : FROM_C_F(intype, 126.9, 150.1, outtype, 127, 150);
1071 10 : if (!IS_UNSIGNED(outtype))
1072 : {
1073 6 : FROM_C_F(intype, -125.9, -127.1, outtype, -126, -127);
1074 : }
1075 : }
1076 : }
1077 1 : FROM_C(intype, -1, 256, GDT_Byte, 0, 0);
1078 1 : FROM_C(intype, 256, -1, GDT_Byte, 255, 0);
1079 1 : FROM_C(intype, -33000, 33000, GDT_Int16, -32768, 0);
1080 1 : FROM_C(intype, 33000, -33000, GDT_Int16, 32767, 0);
1081 1 : FROM_C(intype, -1, 66000, GDT_UInt16, 0, 0);
1082 1 : FROM_C(intype, 66000, -1, GDT_UInt16, 65535, 0);
1083 1 : FROM_C(intype, -33000, -33000, GDT_Int32, -32992, 0);
1084 1 : FROM_C(intype, 33000, 33000, GDT_Int32, 32992, 0);
1085 1 : FROM_C(intype, -1, 33000, GDT_UInt32, 0, 0);
1086 1 : FROM_C(intype, 33000, -1, GDT_UInt32, 32992, 0);
1087 1 : FROM_C(intype, 33000, -1, GDT_Float32, 32992, 0);
1088 1 : FROM_C(intype, 33000, -1, GDT_Float64, 32992, 0);
1089 1 : FROM_C(intype, -33000, -1, GDT_Float32, -32992, 0);
1090 1 : FROM_C(intype, -33000, -1, GDT_Float64, -32992, 0);
1091 1 : FROM_C(intype, -33000, 33000, GDT_CInt16, -32768, 32767);
1092 1 : FROM_C(intype, 33000, -33000, GDT_CInt16, 32767, -32768);
1093 1 : FROM_C(intype, -33000, -33000, GDT_CInt32, -32992, -32992);
1094 1 : FROM_C(intype, 33000, 33000, GDT_CInt32, 32992, 32992);
1095 1 : FROM_C(intype, 33000, -33000, GDT_CFloat32, 32992, -32992);
1096 1 : FROM_C(intype, 33000, -33000, GDT_CFloat64, 32992, -32992);
1097 1 : }
1098 :
1099 : template <class Tin, class Tout>
1100 121 : void CheckPackedGeneric(GDALDataType eIn, GDALDataType eOut)
1101 : {
1102 121 : const int N = 64 + 7;
1103 792 : Tin arrayIn[N];
1104 792 : Tout arrayOut[N];
1105 8712 : for (int i = 0; i < N; i++)
1106 : {
1107 : if constexpr (!std::is_integral_v<Tin> && std::is_integral_v<Tout>)
1108 : {
1109 : // Test correct rounding
1110 852 : if (i == 0 && std::is_unsigned_v<Tout>)
1111 12 : arrayIn[i] = cpl::NumericLimits<Tin>::quiet_NaN();
1112 1692 : else if ((i % 2) != 0)
1113 840 : arrayIn[i] = static_cast<Tin>(i + 0.4);
1114 : else
1115 852 : arrayIn[i] = static_cast<Tin>(i + 0.6);
1116 : }
1117 : else
1118 : {
1119 6887 : arrayIn[i] = static_cast<Tin>(i + 1);
1120 : }
1121 8591 : arrayOut[i] = 0;
1122 : }
1123 121 : GDALCopyWords(arrayIn, eIn, GDALGetDataTypeSizeBytes(eIn), arrayOut, eOut,
1124 : GDALGetDataTypeSizeBytes(eOut), N);
1125 121 : int numLine = 0;
1126 8712 : for (int i = 0; i < N; i++)
1127 : {
1128 : if constexpr (!std::is_integral_v<Tin> && std::is_integral_v<Tout>)
1129 : {
1130 852 : if (i == 0 && std::is_unsigned_v<Tout>)
1131 : {
1132 12 : MY_EXPECT(eIn, cpl::NumericLimits<Tin>::quiet_NaN(), eOut, 0,
1133 : arrayOut[i]);
1134 : }
1135 1692 : else if ((i % 2) != 0)
1136 : {
1137 840 : MY_EXPECT(eIn, i + 0.4, eOut, i, arrayOut[i]);
1138 : }
1139 : else
1140 : {
1141 852 : MY_EXPECT(eIn, i + 0.6, eOut, i + 1, arrayOut[i]);
1142 : }
1143 : }
1144 : else
1145 : {
1146 6887 : MY_EXPECT(eIn, i + 1, eOut, i + 1, arrayOut[i]);
1147 : }
1148 : }
1149 121 : }
1150 :
1151 : template <class Tin, class Tout>
1152 119 : void CheckPacked(GDALDataType eIn, GDALDataType eOut)
1153 : {
1154 119 : CheckPackedGeneric<Tin, Tout>(eIn, eOut);
1155 119 : }
1156 :
1157 : template <>
1158 1 : void CheckPacked<GUInt16, GByte>(GDALDataType eIn, GDALDataType eOut)
1159 : {
1160 1 : CheckPackedGeneric<GUInt16, GByte>(eIn, eOut);
1161 :
1162 1 : const int N = 64 + 7;
1163 1 : GUInt16 arrayIn[N] = {0};
1164 1 : GByte arrayOut[N] = {0};
1165 72 : for (int i = 0; i < N; i++)
1166 : {
1167 130 : arrayIn[i] = (i % 6) == 0 ? 254
1168 59 : : (i % 6) == 1 ? 255
1169 47 : : (i % 4) == 2 ? 256
1170 35 : : (i % 6) == 3 ? 32767
1171 23 : : (i % 6) == 4 ? 32768
1172 : : 65535;
1173 : }
1174 1 : GDALCopyWords(arrayIn, eIn, GDALGetDataTypeSizeBytes(eIn), arrayOut, eOut,
1175 : GDALGetDataTypeSizeBytes(eOut), N);
1176 1 : int numLine = 0;
1177 72 : for (int i = 0; i < N; i++)
1178 : {
1179 71 : MY_EXPECT(eIn, (int)arrayIn[i], eOut, (i % 6) == 0 ? 254 : 255,
1180 : arrayOut[i]);
1181 : }
1182 1 : }
1183 :
1184 : template <>
1185 1 : void CheckPacked<GUInt16, GInt16>(GDALDataType eIn, GDALDataType eOut)
1186 : {
1187 1 : CheckPackedGeneric<GUInt16, GInt16>(eIn, eOut);
1188 :
1189 1 : const int N = 64 + 7;
1190 1 : GUInt16 arrayIn[N] = {0};
1191 1 : GInt16 arrayOut[N] = {0};
1192 72 : for (int i = 0; i < N; i++)
1193 : {
1194 71 : arrayIn[i] = 32766 + (i % 4);
1195 : }
1196 1 : GDALCopyWords(arrayIn, eIn, GDALGetDataTypeSizeBytes(eIn), arrayOut, eOut,
1197 : GDALGetDataTypeSizeBytes(eOut), N);
1198 1 : int numLine = 0;
1199 72 : for (int i = 0; i < N; i++)
1200 : {
1201 71 : MY_EXPECT(eIn, (int)arrayIn[i], eOut, (i % 4) == 0 ? 32766 : 32767,
1202 : arrayOut[i]);
1203 : }
1204 1 : }
1205 :
1206 121 : template <class Tin> void CheckPacked(GDALDataType eIn, GDALDataType eOut)
1207 : {
1208 121 : switch (eOut)
1209 : {
1210 11 : case GDT_Byte:
1211 11 : CheckPacked<Tin, GByte>(eIn, eOut);
1212 11 : break;
1213 11 : case GDT_Int8:
1214 11 : CheckPacked<Tin, GInt8>(eIn, eOut);
1215 11 : break;
1216 11 : case GDT_UInt16:
1217 11 : CheckPacked<Tin, GUInt16>(eIn, eOut);
1218 11 : break;
1219 11 : case GDT_Int16:
1220 11 : CheckPacked<Tin, GInt16>(eIn, eOut);
1221 11 : break;
1222 11 : case GDT_UInt32:
1223 11 : CheckPacked<Tin, GUInt32>(eIn, eOut);
1224 11 : break;
1225 11 : case GDT_Int32:
1226 11 : CheckPacked<Tin, GInt32>(eIn, eOut);
1227 11 : break;
1228 11 : case GDT_UInt64:
1229 11 : CheckPacked<Tin, std::uint64_t>(eIn, eOut);
1230 11 : break;
1231 11 : case GDT_Int64:
1232 11 : CheckPacked<Tin, std::int64_t>(eIn, eOut);
1233 11 : break;
1234 11 : case GDT_Float16:
1235 11 : CheckPacked<Tin, GFloat16>(eIn, eOut);
1236 11 : break;
1237 11 : case GDT_Float32:
1238 11 : CheckPacked<Tin, float>(eIn, eOut);
1239 11 : break;
1240 11 : case GDT_Float64:
1241 11 : CheckPacked<Tin, double>(eIn, eOut);
1242 11 : break;
1243 0 : default:
1244 0 : CPLAssert(false);
1245 : }
1246 121 : }
1247 :
1248 121 : static void CheckPacked(GDALDataType eIn, GDALDataType eOut)
1249 : {
1250 121 : switch (eIn)
1251 : {
1252 11 : case GDT_Byte:
1253 11 : CheckPacked<GByte>(eIn, eOut);
1254 11 : break;
1255 11 : case GDT_Int8:
1256 11 : CheckPacked<GInt8>(eIn, eOut);
1257 11 : break;
1258 11 : case GDT_UInt16:
1259 11 : CheckPacked<GUInt16>(eIn, eOut);
1260 11 : break;
1261 11 : case GDT_Int16:
1262 11 : CheckPacked<GInt16>(eIn, eOut);
1263 11 : break;
1264 11 : case GDT_UInt32:
1265 11 : CheckPacked<GUInt32>(eIn, eOut);
1266 11 : break;
1267 11 : case GDT_Int32:
1268 11 : CheckPacked<GInt32>(eIn, eOut);
1269 11 : break;
1270 11 : case GDT_UInt64:
1271 11 : CheckPacked<std::uint64_t>(eIn, eOut);
1272 11 : break;
1273 11 : case GDT_Int64:
1274 11 : CheckPacked<std::int64_t>(eIn, eOut);
1275 11 : break;
1276 11 : case GDT_Float16:
1277 11 : CheckPacked<GFloat16>(eIn, eOut);
1278 11 : break;
1279 11 : case GDT_Float32:
1280 11 : CheckPacked<float>(eIn, eOut);
1281 11 : break;
1282 11 : case GDT_Float64:
1283 11 : CheckPacked<double>(eIn, eOut);
1284 11 : break;
1285 0 : default:
1286 0 : CPLAssert(false);
1287 : }
1288 121 : }
1289 :
1290 : class TestCopyWordsCheckPackedFixture
1291 : : public TestCopyWords,
1292 : public ::testing::WithParamInterface<
1293 : std::tuple<GDALDataType, GDALDataType>>
1294 : {
1295 : };
1296 :
1297 243 : TEST_P(TestCopyWordsCheckPackedFixture, CheckPacked)
1298 : {
1299 121 : GDALDataType eIn = std::get<0>(GetParam());
1300 121 : GDALDataType eOut = std::get<1>(GetParam());
1301 121 : CheckPacked(eIn, eOut);
1302 121 : }
1303 :
1304 : static std::vector<std::tuple<GDALDataType, GDALDataType>>
1305 1 : GetGDALDataTypeTupleValues()
1306 : {
1307 1 : std::vector<std::tuple<GDALDataType, GDALDataType>> ret;
1308 17 : for (GDALDataType eIn = GDT_Byte; eIn < GDT_TypeCount;
1309 16 : eIn = static_cast<GDALDataType>(eIn + 1))
1310 : {
1311 16 : if (GDALDataTypeIsComplex(eIn))
1312 5 : continue;
1313 187 : for (GDALDataType eOut = GDT_Byte; eOut < GDT_TypeCount;
1314 176 : eOut = static_cast<GDALDataType>(eOut + 1))
1315 : {
1316 176 : if (GDALDataTypeIsComplex(eOut))
1317 55 : continue;
1318 121 : ret.emplace_back(std::make_tuple(eIn, eOut));
1319 : }
1320 : }
1321 1 : return ret;
1322 : }
1323 :
1324 365 : INSTANTIATE_TEST_SUITE_P(
1325 : TestCopyWords, TestCopyWordsCheckPackedFixture,
1326 : ::testing::ValuesIn(GetGDALDataTypeTupleValues()),
1327 : [](const ::testing::TestParamInfo<
1328 : TestCopyWordsCheckPackedFixture::ParamType> &l_info)
1329 : {
1330 : GDALDataType eIn = std::get<0>(l_info.param);
1331 : GDALDataType eOut = std::get<1>(l_info.param);
1332 : return std::string(GDALGetDataTypeName(eIn)) + "_" +
1333 : GDALGetDataTypeName(eOut);
1334 : });
1335 :
1336 4 : TEST_F(TestCopyWords, ByteToByte)
1337 : {
1338 3 : for (int k = 0; k < 2; k++)
1339 : {
1340 2 : if (k == 1)
1341 1 : CPLSetConfigOption("GDAL_USE_SSSE3", "NO");
1342 :
1343 8 : for (int spacing = 2; spacing <= 4; spacing++)
1344 : {
1345 6 : memset(pIn, 0xff, 256);
1346 108 : for (int i = 0; i < 17; i++)
1347 : {
1348 102 : pIn[spacing * i] = (GByte)(17 - i);
1349 : }
1350 6 : memset(pOut, 0xff, 256);
1351 6 : GDALCopyWords(pIn, GDT_Byte, spacing, pOut, GDT_Byte, 1, 17);
1352 108 : for (int i = 0; i < 17; i++)
1353 : {
1354 102 : AssertRes(GDT_Byte, 17 - i, GDT_Byte, 17 - i, pOut[i],
1355 : __LINE__);
1356 : }
1357 :
1358 6 : memset(pIn, 0xff, 256);
1359 6 : memset(pOut, 0xff, 256);
1360 108 : for (int i = 0; i < 17; i++)
1361 : {
1362 102 : pIn[i] = (GByte)(17 - i);
1363 : }
1364 6 : GDALCopyWords(pIn, GDT_Byte, 1, pOut, GDT_Byte, spacing, 17);
1365 108 : for (int i = 0; i < 17; i++)
1366 : {
1367 102 : AssertRes(GDT_Byte, 17 - i, GDT_Byte, 17 - i, pOut[i * spacing],
1368 : __LINE__);
1369 306 : for (int j = 1; j < spacing; j++)
1370 : {
1371 204 : AssertRes(GDT_Byte, 0xff, GDT_Byte, 0xff,
1372 204 : pOut[i * spacing + j], __LINE__);
1373 : }
1374 : }
1375 : }
1376 : }
1377 1 : CPLSetConfigOption("GDAL_USE_SSSE3", nullptr);
1378 1 : }
1379 :
1380 4 : TEST_F(TestCopyWords, Int16ToInt16)
1381 : {
1382 1 : memset(pIn, 0xff, 256);
1383 1 : GInt16 *pInShort = (GInt16 *)pIn;
1384 1 : GInt16 *pOutShort = (GInt16 *)pOut;
1385 10 : for (int i = 0; i < 9; i++)
1386 : {
1387 9 : pInShort[2 * i + 0] = 0x1234;
1388 9 : pInShort[2 * i + 1] = 0x5678;
1389 : }
1390 5 : for (int iSpacing = 0; iSpacing < 4; iSpacing++)
1391 : {
1392 4 : memset(pOut, 0xff, 256);
1393 4 : GDALCopyWords(pInShort, GDT_Int16, sizeof(short), pOutShort, GDT_Int16,
1394 4 : (iSpacing + 1) * sizeof(short), 18);
1395 40 : for (int i = 0; i < 9; i++)
1396 : {
1397 36 : AssertRes(GDT_Int16, pInShort[2 * i + 0], GDT_Int16,
1398 36 : pInShort[2 * i + 0],
1399 36 : pOutShort[(iSpacing + 1) * (2 * i + 0)], __LINE__);
1400 36 : AssertRes(GDT_Int16, pInShort[2 * i + 1], GDT_Int16,
1401 36 : pInShort[2 * i + 1],
1402 36 : pOutShort[(iSpacing + 1) * (2 * i + 1)], __LINE__);
1403 : }
1404 : }
1405 5 : for (int iSpacing = 0; iSpacing < 4; iSpacing++)
1406 : {
1407 4 : memset(pIn, 0xff, 256);
1408 4 : memset(pOut, 0xff, 256);
1409 40 : for (int i = 0; i < 9; i++)
1410 : {
1411 36 : pInShort[(iSpacing + 1) * (2 * i + 0)] = 0x1234;
1412 36 : pInShort[(iSpacing + 1) * (2 * i + 1)] = 0x5678;
1413 : }
1414 4 : GDALCopyWords(pInShort, GDT_Int16, (iSpacing + 1) * sizeof(short),
1415 : pOutShort, GDT_Int16, sizeof(short), 18);
1416 40 : for (int i = 0; i < 9; i++)
1417 : {
1418 36 : AssertRes(GDT_Int16, pInShort[(iSpacing + 1) * (2 * i + 0)],
1419 36 : GDT_Int16, pInShort[(iSpacing + 1) * (2 * i + 0)],
1420 36 : pOutShort[2 * i + 0], __LINE__);
1421 36 : AssertRes(GDT_Int16, pInShort[(iSpacing + 1) * (2 * i + 1)],
1422 36 : GDT_Int16, pInShort[(iSpacing + 1) * (2 * i + 1)],
1423 36 : pOutShort[2 * i + 1], __LINE__);
1424 : }
1425 : }
1426 1 : }
1427 :
1428 : } // namespace
|