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 59991 : void AssertRes(GDALDataType intype, CT1 inval, GDALDataType outtype,
32 : CT2 expected_outval, OutType outval, int numLine)
33 : {
34 62729 : 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 59991 : }
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 1024 : void Test(GDALDataType intype, ConstantType inval, ConstantType invali,
75 : GDALDataType outtype, ConstantType outval, ConstantType outvali,
76 : int numLine)
77 : {
78 1024 : memset(pIn, 0xff, 1024);
79 1024 : memset(pOut, 0xff, 1024);
80 :
81 1024 : *(InType *)(pIn) = (InType)inval;
82 1024 : *(InType *)(pIn + 32) = (InType)inval;
83 1024 : 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 1024 : GDALCopyWords(pIn, intype, 32, pOut, outtype, 32, 2);
91 :
92 : /* Test negative offsets */
93 1024 : GDALCopyWords(pIn + 32, intype, -32, pOut + 1024 - 16, outtype, -32, 2);
94 :
95 1024 : MY_EXPECT(intype, inval, outtype, outval, *(OutType *)(pOut));
96 1024 : MY_EXPECT(intype, inval, outtype, outval, *(OutType *)(pOut + 32));
97 1024 : MY_EXPECT(intype, inval, outtype, outval,
98 : *(OutType *)(pOut + 1024 - 16));
99 1024 : MY_EXPECT(intype, inval, outtype, outval,
100 : *(OutType *)(pOut + 1024 - 16 - 32));
101 :
102 1024 : 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 720 : constexpr int N = 32 + 31;
116 46080 : for (int i = 0; i < N; ++i)
117 : {
118 45360 : *(InType *)(pIn + i * GDALGetDataTypeSizeBytes(intype)) =
119 8694 : (InType)inval;
120 : }
121 :
122 : /* Test packed offsets */
123 720 : GDALCopyWords(pIn, intype, GDALGetDataTypeSizeBytes(intype), pOut,
124 : outtype, GDALGetDataTypeSizeBytes(outtype), N);
125 :
126 46080 : for (int i = 0; i < N; ++i)
127 : {
128 45360 : MY_EXPECT(
129 : intype, inval, outtype, outval,
130 : *(OutType *)(pOut + i * GDALGetDataTypeSizeBytes(outtype)));
131 : }
132 : }
133 1024 : }
134 :
135 : template <class InType, class ConstantType>
136 1024 : void FromR_2(GDALDataType intype, ConstantType inval, ConstantType invali,
137 : GDALDataType outtype, ConstantType outval,
138 : ConstantType outvali, int numLine)
139 : {
140 1024 : if (outtype == GDT_Byte)
141 77 : Test<InType, GByte, ConstantType>(intype, inval, invali, outtype,
142 : outval, outvali, numLine);
143 947 : else if (outtype == GDT_Int8)
144 61 : Test<InType, GInt8, ConstantType>(intype, inval, invali, outtype,
145 : outval, outvali, numLine);
146 886 : else if (outtype == GDT_Int16)
147 92 : Test<InType, GInt16, ConstantType>(intype, inval, invali, outtype,
148 : outval, outvali, numLine);
149 794 : else if (outtype == GDT_UInt16)
150 71 : Test<InType, GUInt16, ConstantType>(intype, inval, invali, outtype,
151 : outval, outvali, numLine);
152 723 : else if (outtype == GDT_Int32)
153 87 : Test<InType, GInt32, ConstantType>(intype, inval, invali, outtype,
154 : outval, outvali, numLine);
155 636 : else if (outtype == GDT_UInt32)
156 66 : Test<InType, GUInt32, ConstantType>(intype, inval, invali, outtype,
157 : outval, outvali, numLine);
158 570 : else if (outtype == GDT_Int64)
159 71 : Test<InType, std::int64_t, ConstantType>(
160 : intype, inval, invali, outtype, outval, outvali, numLine);
161 499 : else if (outtype == GDT_UInt64)
162 50 : Test<InType, std::uint64_t, ConstantType>(
163 : intype, inval, invali, outtype, outval, outvali, numLine);
164 449 : else if (outtype == GDT_Float16)
165 34 : 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 1024 : }
189 :
190 : template <class ConstantType>
191 1024 : void FromR(GDALDataType intype, ConstantType inval, ConstantType invali,
192 : GDALDataType outtype, ConstantType outval, ConstantType outvali,
193 : int numLine)
194 : {
195 1024 : if (intype == GDT_Byte)
196 47 : FromR_2<GByte, ConstantType>(intype, inval, invali, outtype, outval,
197 : outvali, numLine);
198 977 : else if (intype == GDT_Int8)
199 46 : FromR_2<GInt8, ConstantType>(intype, inval, invali, outtype, outval,
200 : outvali, numLine);
201 931 : else if (intype == GDT_Int16)
202 42 : FromR_2<GInt16, ConstantType>(intype, inval, invali, outtype,
203 : outval, outvali, numLine);
204 889 : else if (intype == GDT_UInt16)
205 45 : FromR_2<GUInt16, ConstantType>(intype, inval, invali, outtype,
206 : outval, outvali, numLine);
207 844 : else if (intype == GDT_Int32)
208 45 : FromR_2<GInt32, ConstantType>(intype, inval, invali, outtype,
209 : outval, outvali, numLine);
210 799 : else if (intype == GDT_UInt32)
211 45 : FromR_2<GUInt32, ConstantType>(intype, inval, invali, outtype,
212 : outval, outvali, numLine);
213 754 : else if (intype == GDT_Int64)
214 39 : FromR_2<std::int64_t, ConstantType>(intype, inval, invali, outtype,
215 : outval, outvali, numLine);
216 715 : else if (intype == GDT_UInt64)
217 45 : FromR_2<std::uint64_t, ConstantType>(intype, inval, invali, outtype,
218 : outval, outvali, numLine);
219 670 : else if (intype == GDT_Float16)
220 135 : FromR_2<GFloat16, ConstantType>(intype, inval, invali, outtype,
221 : outval, outvali, numLine);
222 535 : else if (intype == GDT_Float32)
223 141 : 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 1024 : }
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>::max(), GDT_Float16,
603 : std::numeric_limits<double>::infinity());
604 1 : FROM_R_F(GDT_Float32, -std::numeric_limits<float>::max(), GDT_Float16,
605 : -std::numeric_limits<double>::infinity());
606 1 : FROM_R_F(GDT_Float32, std::numeric_limits<float>::quiet_NaN(), GDT_Float16,
607 : std::numeric_limits<double>::quiet_NaN());
608 :
609 1 : FROM_R_F(GDT_Float64, std::numeric_limits<double>::max(), GDT_Float16,
610 : std::numeric_limits<double>::infinity());
611 1 : FROM_R_F(GDT_Float64, -std::numeric_limits<double>::max(), GDT_Float16,
612 : -std::numeric_limits<double>::infinity());
613 1 : FROM_R_F(GDT_Float64, std::numeric_limits<double>::quiet_NaN(), GDT_Float16,
614 : std::numeric_limits<double>::quiet_NaN());
615 :
616 : // Float16 to Int64
617 : {
618 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::quiet_NaN();
619 1 : int64_t out_value = 0;
620 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_Int64, 0, 1);
621 1 : EXPECT_EQ(out_value, 0);
622 : }
623 :
624 : {
625 1 : GFloat16 in_value = -cpl::NumericLimits<GFloat16>::infinity();
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, INT64_MIN);
629 : }
630 :
631 : {
632 1 : GFloat16 in_value = -cpl::NumericLimits<GFloat16>::max();
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, -65504);
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>::infinity();
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, INT64_MAX);
650 : }
651 :
652 : // Float16 to UInt64
653 : {
654 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::quiet_NaN();
655 1 : uint64_t out_value = 0;
656 1 : GDALCopyWords(&in_value, GDT_Float16, 0, &out_value, GDT_UInt64, 0, 1);
657 1 : EXPECT_EQ(out_value, 0);
658 : }
659 :
660 : {
661 1 : GFloat16 in_value = -cpl::NumericLimits<GFloat16>::infinity();
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>::max();
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, 65504);
679 : }
680 :
681 : {
682 1 : GFloat16 in_value = cpl::NumericLimits<GFloat16>::infinity();
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, UINT64_MAX);
686 : }
687 1 : }
688 :
689 4 : TEST_F(TestCopyWords, GDT_Float32and64)
690 : {
691 : /* GDT_Float32 and GDT_Float64 */
692 3 : for (int i = 0; i < 2; i++)
693 : {
694 2 : GDALDataType intype = (i == 0) ? GDT_Float32 : GDT_Float64;
695 34 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
696 32 : outtype = (GDALDataType)(outtype + 1))
697 : {
698 32 : if (IS_FLOAT(outtype))
699 : {
700 12 : FROM_R_F(intype, 127.1, outtype, 127.1);
701 12 : FROM_R_F(intype, -127.1, outtype, -127.1);
702 : }
703 : else
704 : {
705 20 : FROM_R_F(intype, 125.1, outtype, 125);
706 20 : FROM_R_F(intype, 125.9, outtype, 126);
707 :
708 20 : FROM_R_F(intype, 0.4, outtype, 0);
709 20 : FROM_R_F(intype, 0.5, outtype,
710 : 1); /* We could argue how to do this rounding */
711 20 : FROM_R_F(intype, 0.6, outtype, 1);
712 20 : FROM_R_F(intype, 126.5, outtype,
713 : 127); /* We could argue how to do this rounding */
714 :
715 20 : if (!IS_UNSIGNED(outtype))
716 : {
717 12 : FROM_R_F(intype, -125.9, outtype, -126);
718 12 : FROM_R_F(intype, -127.1, outtype, -127);
719 :
720 12 : FROM_R_F(intype, -0.4, outtype, 0);
721 12 : FROM_R_F(intype, -0.5, outtype,
722 : -1); /* We could argue how to do this rounding */
723 12 : FROM_R_F(intype, -0.6, outtype, -1);
724 12 : FROM_R_F(intype, -127.5, outtype,
725 : -128); /* We could argue how to do this rounding */
726 : }
727 : }
728 : }
729 2 : FROM_R(intype, -CST_3000000000, GDT_Byte, 0);
730 2 : FROM_R(intype, -32768, GDT_Byte, 0);
731 2 : FROM_R(intype, -1, GDT_Byte, 0);
732 2 : FROM_R(intype, 256, GDT_Byte, 255);
733 2 : FROM_R(intype, 65536, GDT_Byte, 255);
734 2 : FROM_R(intype, CST_3000000000, GDT_Byte, 255);
735 2 : FROM_R(intype, -CST_3000000000, GDT_Int16, -32768);
736 2 : FROM_R(intype, -33000, GDT_Int16, -32768);
737 2 : FROM_R(intype, 33000, GDT_Int16, 32767);
738 2 : FROM_R(intype, CST_3000000000, GDT_Int16, 32767);
739 2 : FROM_R(intype, -CST_3000000000, GDT_UInt16, 0);
740 2 : FROM_R(intype, -1, GDT_UInt16, 0);
741 2 : FROM_R(intype, 66000, GDT_UInt16, 65535);
742 2 : FROM_R(intype, CST_3000000000, GDT_UInt16, 65535);
743 2 : FROM_R(intype, -CST_3000000000, GDT_Int32, INT_MIN);
744 2 : FROM_R(intype, CST_3000000000, GDT_Int32, 2147483647);
745 2 : FROM_R(intype, -1, GDT_UInt32, 0);
746 2 : FROM_R(intype, CST_5000000000, GDT_UInt32, 4294967295UL);
747 2 : FROM_R(intype, CST_5000000000, GDT_Float32, CST_5000000000);
748 2 : FROM_R(intype, -CST_5000000000, GDT_Float32, -CST_5000000000);
749 2 : FROM_R(intype, CST_5000000000, GDT_Float64, CST_5000000000);
750 2 : FROM_R(intype, -CST_5000000000, GDT_Float64, -CST_5000000000);
751 2 : FROM_R(intype, -33000, GDT_CInt16, -32768);
752 2 : FROM_R(intype, 33000, GDT_CInt16, 32767);
753 2 : FROM_R(intype, -CST_3000000000, GDT_CInt32, INT_MIN);
754 2 : FROM_R(intype, CST_3000000000, GDT_CInt32, 2147483647);
755 2 : FROM_R(intype, CST_5000000000, GDT_CFloat32, CST_5000000000);
756 2 : FROM_R(intype, -CST_5000000000, GDT_CFloat32, -CST_5000000000);
757 2 : FROM_R(intype, CST_5000000000, GDT_CFloat64, CST_5000000000);
758 2 : FROM_R(intype, -CST_5000000000, GDT_CFloat64, -CST_5000000000);
759 : }
760 :
761 : // Float32 to Int64
762 : {
763 1 : float in_value = cpl::NumericLimits<float>::quiet_NaN();
764 1 : int64_t out_value = 0;
765 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_Int64, 0, 1);
766 1 : EXPECT_EQ(out_value, 0);
767 : }
768 :
769 : {
770 1 : float in_value = -cpl::NumericLimits<float>::infinity();
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, INT64_MIN);
774 : }
775 :
776 : {
777 1 : float in_value = -cpl::NumericLimits<float>::max();
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_MAX);
788 : }
789 :
790 : {
791 1 : float in_value = cpl::NumericLimits<float>::infinity();
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 : // Float64 to Int64
798 : {
799 1 : double in_value = cpl::NumericLimits<double>::quiet_NaN();
800 1 : int64_t out_value = 0;
801 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_Int64, 0, 1);
802 1 : EXPECT_EQ(out_value, 0);
803 : }
804 :
805 : {
806 1 : double in_value = -cpl::NumericLimits<double>::infinity();
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, INT64_MIN);
810 : }
811 :
812 : {
813 1 : double in_value = -cpl::NumericLimits<double>::max();
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_MAX);
824 : }
825 :
826 : {
827 1 : double in_value = cpl::NumericLimits<double>::infinity();
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 : // Float32 to UInt64
834 : {
835 1 : float in_value = cpl::NumericLimits<float>::quiet_NaN();
836 1 : uint64_t out_value = 0;
837 1 : GDALCopyWords(&in_value, GDT_Float32, 0, &out_value, GDT_UInt64, 0, 1);
838 1 : EXPECT_EQ(out_value, 0);
839 : }
840 :
841 : {
842 1 : float in_value = -cpl::NumericLimits<float>::infinity();
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>::max();
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, UINT64_MAX);
860 : }
861 :
862 : {
863 1 : float in_value = cpl::NumericLimits<float>::infinity();
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 : // Float64 to UInt64
870 : {
871 1 : double in_value = -cpl::NumericLimits<double>::quiet_NaN();
872 1 : uint64_t out_value = 0;
873 1 : GDALCopyWords(&in_value, GDT_Float64, 0, &out_value, GDT_UInt64, 0, 1);
874 1 : EXPECT_EQ(out_value, 0);
875 : }
876 :
877 : {
878 1 : double in_value = -cpl::NumericLimits<double>::infinity();
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>::max();
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, UINT64_MAX);
896 : }
897 :
898 : {
899 1 : double in_value = cpl::NumericLimits<double>::infinity();
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 1 : }
905 :
906 4 : TEST_F(TestCopyWords, GDT_CInt16)
907 : {
908 : /* GDT_CInt16 */
909 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Byte, 0, 0); /* clamp */
910 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Int16, -32000, 0);
911 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_UInt16, 0, 0); /* clamp */
912 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Int32, -32000, 0);
913 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_UInt32, 0, 0); /* clamp */
914 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Float32, -32000, 0);
915 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_Float64, -32000, 0);
916 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_CInt16, -32000, -32500);
917 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_CInt32, -32000, -32500);
918 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_CFloat32, -32000, -32500);
919 1 : FROM_C(GDT_CInt16, -32000, -32500, GDT_CFloat64, -32000, -32500);
920 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
921 16 : outtype = (GDALDataType)(outtype + 1))
922 : {
923 16 : FROM_C(GDT_CInt16, 127, 128, outtype, 127, 128);
924 : }
925 :
926 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Byte, 255, 0); /* clamp */
927 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Int16, 32000, 0);
928 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_UInt16, 32000, 0);
929 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Int32, 32000, 0);
930 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_UInt32, 32000, 0);
931 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Float32, 32000, 0);
932 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_Float64, 32000, 0);
933 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_CInt16, 32000, 32500);
934 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_CInt32, 32000, 32500);
935 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_CFloat32, 32000, 32500);
936 1 : FROM_C(GDT_CInt16, 32000, 32500, GDT_CFloat64, 32000, 32500);
937 1 : }
938 :
939 4 : TEST_F(TestCopyWords, GDT_CInt32)
940 : {
941 : /* GDT_CInt32 */
942 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Byte, 0, 0); /* clamp */
943 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Int16, -32768, 0); /* clamp */
944 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_UInt16, 0, 0); /* clamp */
945 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Int32, -33000, 0);
946 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_UInt32, 0, 0); /* clamp */
947 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Float32, -33000, 0);
948 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_Float64, -33000, 0);
949 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_CInt16, -32768, -32768); /* clamp */
950 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_CInt32, -33000, -33500);
951 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_CFloat32, -33000, -33500);
952 1 : FROM_C(GDT_CInt32, -33000, -33500, GDT_CFloat64, -33000, -33500);
953 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
954 16 : outtype = (GDALDataType)(outtype + 1))
955 : {
956 16 : FROM_C(GDT_CInt32, 127, 128, outtype, 127, 128);
957 : }
958 :
959 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Byte, 255, 0); /* clamp */
960 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Int16, 32767, 0); /* clamp */
961 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_UInt16, 65535, 0); /* clamp */
962 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Int32, 67000, 0);
963 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_UInt32, 67000, 0);
964 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Float32, 67000, 0);
965 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_Float64, 67000, 0);
966 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_CInt16, 32767, 32767); /* clamp */
967 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_CInt32, 67000, 67500);
968 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_CFloat32, 67000, 67500);
969 1 : FROM_C(GDT_CInt32, 67000, 67500, GDT_CFloat64, 67000, 67500);
970 1 : }
971 :
972 4 : TEST_F(TestCopyWords, GDT_CFloat32and64)
973 : {
974 : /* GDT_CFloat32 and GDT_CFloat64 */
975 3 : for (int i = 0; i < 2; i++)
976 : {
977 2 : GDALDataType intype = (i == 0) ? GDT_CFloat32 : GDT_CFloat64;
978 34 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
979 32 : outtype = (GDALDataType)(outtype + 1))
980 : {
981 32 : if (IS_FLOAT(outtype))
982 : {
983 12 : FROM_C_F(intype, 127.1, 127.9, outtype, 127.1, 127.9);
984 12 : FROM_C_F(intype, -127.1, -127.9, outtype, -127.1, -127.9);
985 : }
986 : else
987 : {
988 20 : FROM_C_F(intype, 126.1, 150.9, outtype, 126, 151);
989 20 : FROM_C_F(intype, 126.9, 150.1, outtype, 127, 150);
990 20 : if (!IS_UNSIGNED(outtype))
991 : {
992 12 : FROM_C_F(intype, -125.9, -127.1, outtype, -126, -127);
993 : }
994 : }
995 : }
996 2 : FROM_C(intype, -1, 256, GDT_Byte, 0, 0);
997 2 : FROM_C(intype, 256, -1, GDT_Byte, 255, 0);
998 2 : FROM_C(intype, -33000, 33000, GDT_Int16, -32768, 0);
999 2 : FROM_C(intype, 33000, -33000, GDT_Int16, 32767, 0);
1000 2 : FROM_C(intype, -1, 66000, GDT_UInt16, 0, 0);
1001 2 : FROM_C(intype, 66000, -1, GDT_UInt16, 65535, 0);
1002 2 : FROM_C(intype, -CST_3000000000, -CST_3000000000, GDT_Int32, INT_MIN, 0);
1003 2 : FROM_C(intype, CST_3000000000, CST_3000000000, GDT_Int32, 2147483647,
1004 : 0);
1005 2 : FROM_C(intype, -1, CST_5000000000, GDT_UInt32, 0, 0);
1006 2 : FROM_C(intype, CST_5000000000, -1, GDT_UInt32, 4294967295UL, 0);
1007 2 : FROM_C(intype, CST_5000000000, -1, GDT_Float32, CST_5000000000, 0);
1008 2 : FROM_C(intype, CST_5000000000, -1, GDT_Float64, CST_5000000000, 0);
1009 2 : FROM_C(intype, -CST_5000000000, -1, GDT_Float32, -CST_5000000000, 0);
1010 2 : FROM_C(intype, -CST_5000000000, -1, GDT_Float64, -CST_5000000000, 0);
1011 2 : FROM_C(intype, -33000, 33000, GDT_CInt16, -32768, 32767);
1012 2 : FROM_C(intype, 33000, -33000, GDT_CInt16, 32767, -32768);
1013 2 : FROM_C(intype, -CST_3000000000, -CST_3000000000, GDT_CInt32, INT_MIN,
1014 : INT_MIN);
1015 2 : FROM_C(intype, CST_3000000000, CST_3000000000, GDT_CInt32, 2147483647,
1016 : 2147483647);
1017 2 : FROM_C(intype, CST_5000000000, -CST_5000000000, GDT_CFloat32,
1018 : CST_5000000000, -CST_5000000000);
1019 2 : FROM_C(intype, CST_5000000000, -CST_5000000000, GDT_CFloat64,
1020 : CST_5000000000, -CST_5000000000);
1021 : }
1022 1 : }
1023 :
1024 4 : TEST_F(TestCopyWords, GDT_CFloat16only)
1025 : {
1026 1 : GDALDataType intype = GDT_CFloat16;
1027 17 : for (GDALDataType outtype = GDT_Byte; outtype < GDT_TypeCount;
1028 16 : outtype = (GDALDataType)(outtype + 1))
1029 : {
1030 16 : if (IS_FLOAT(outtype))
1031 : {
1032 6 : FROM_C_F(intype, 127.1, 127.9, outtype, 127.1, 127.9);
1033 6 : FROM_C_F(intype, -127.1, -127.9, outtype, -127.1, -127.9);
1034 : }
1035 : else
1036 : {
1037 10 : FROM_C_F(intype, 126.1, 150.9, outtype, 126, 151);
1038 10 : FROM_C_F(intype, 126.9, 150.1, outtype, 127, 150);
1039 10 : if (!IS_UNSIGNED(outtype))
1040 : {
1041 6 : FROM_C_F(intype, -125.9, -127.1, outtype, -126, -127);
1042 : }
1043 : }
1044 : }
1045 1 : FROM_C(intype, -1, 256, GDT_Byte, 0, 0);
1046 1 : FROM_C(intype, 256, -1, GDT_Byte, 255, 0);
1047 1 : FROM_C(intype, -33000, 33000, GDT_Int16, -32768, 0);
1048 1 : FROM_C(intype, 33000, -33000, GDT_Int16, 32767, 0);
1049 1 : FROM_C(intype, -1, 66000, GDT_UInt16, 0, 0);
1050 1 : FROM_C(intype, 66000, -1, GDT_UInt16, 65535, 0);
1051 1 : FROM_C(intype, -33000, -33000, GDT_Int32, -32992, 0);
1052 1 : FROM_C(intype, 33000, 33000, GDT_Int32, 32992, 0);
1053 1 : FROM_C(intype, -1, 33000, GDT_UInt32, 0, 0);
1054 1 : FROM_C(intype, 33000, -1, GDT_UInt32, 32992, 0);
1055 1 : FROM_C(intype, 33000, -1, GDT_Float32, 32992, 0);
1056 1 : FROM_C(intype, 33000, -1, GDT_Float64, 32992, 0);
1057 1 : FROM_C(intype, -33000, -1, GDT_Float32, -32992, 0);
1058 1 : FROM_C(intype, -33000, -1, GDT_Float64, -32992, 0);
1059 1 : FROM_C(intype, -33000, 33000, GDT_CInt16, -32768, 32767);
1060 1 : FROM_C(intype, 33000, -33000, GDT_CInt16, 32767, -32768);
1061 1 : FROM_C(intype, -33000, -33000, GDT_CInt32, -32992, -32992);
1062 1 : FROM_C(intype, 33000, 33000, GDT_CInt32, 32992, 32992);
1063 1 : FROM_C(intype, 33000, -33000, GDT_CFloat32, 32992, -32992);
1064 1 : FROM_C(intype, 33000, -33000, GDT_CFloat64, 32992, -32992);
1065 1 : }
1066 :
1067 : template <class Tin, class Tout>
1068 121 : void CheckPackedGeneric(GDALDataType eIn, GDALDataType eOut)
1069 : {
1070 121 : const int N = 64 + 7;
1071 792 : Tin arrayIn[N];
1072 792 : Tout arrayOut[N];
1073 8712 : for (int i = 0; i < N; i++)
1074 : {
1075 : if constexpr (!std::is_integral_v<Tin> && std::is_integral_v<Tout>)
1076 : {
1077 : // Test correct rounding
1078 852 : if (i == 0 && std::is_unsigned_v<Tout>)
1079 12 : arrayIn[i] = cpl::NumericLimits<Tin>::quiet_NaN();
1080 1692 : else if ((i % 2) != 0)
1081 840 : arrayIn[i] = static_cast<Tin>(i + 0.4);
1082 : else
1083 852 : arrayIn[i] = static_cast<Tin>(i + 0.6);
1084 : }
1085 : else
1086 : {
1087 6887 : arrayIn[i] = static_cast<Tin>(i + 1);
1088 : }
1089 8591 : arrayOut[i] = 0;
1090 : }
1091 121 : GDALCopyWords(arrayIn, eIn, GDALGetDataTypeSizeBytes(eIn), arrayOut, eOut,
1092 : GDALGetDataTypeSizeBytes(eOut), N);
1093 121 : int numLine = 0;
1094 8712 : for (int i = 0; i < N; i++)
1095 : {
1096 : if constexpr (!std::is_integral_v<Tin> && std::is_integral_v<Tout>)
1097 : {
1098 852 : if (i == 0 && std::is_unsigned_v<Tout>)
1099 : {
1100 12 : MY_EXPECT(eIn, cpl::NumericLimits<Tin>::quiet_NaN(), eOut, 0,
1101 : arrayOut[i]);
1102 : }
1103 1692 : else if ((i % 2) != 0)
1104 : {
1105 840 : MY_EXPECT(eIn, i + 0.4, eOut, i, arrayOut[i]);
1106 : }
1107 : else
1108 : {
1109 852 : MY_EXPECT(eIn, i + 0.6, eOut, i + 1, arrayOut[i]);
1110 : }
1111 : }
1112 : else
1113 : {
1114 6887 : MY_EXPECT(eIn, i + 1, eOut, i + 1, arrayOut[i]);
1115 : }
1116 : }
1117 121 : }
1118 :
1119 : template <class Tin, class Tout>
1120 119 : void CheckPacked(GDALDataType eIn, GDALDataType eOut)
1121 : {
1122 119 : CheckPackedGeneric<Tin, Tout>(eIn, eOut);
1123 119 : }
1124 :
1125 : template <>
1126 1 : void CheckPacked<GUInt16, GByte>(GDALDataType eIn, GDALDataType eOut)
1127 : {
1128 1 : CheckPackedGeneric<GUInt16, GByte>(eIn, eOut);
1129 :
1130 1 : const int N = 64 + 7;
1131 1 : GUInt16 arrayIn[N] = {0};
1132 1 : GByte arrayOut[N] = {0};
1133 72 : for (int i = 0; i < N; i++)
1134 : {
1135 130 : arrayIn[i] = (i % 6) == 0 ? 254
1136 59 : : (i % 6) == 1 ? 255
1137 47 : : (i % 4) == 2 ? 256
1138 35 : : (i % 6) == 3 ? 32767
1139 23 : : (i % 6) == 4 ? 32768
1140 : : 65535;
1141 : }
1142 1 : GDALCopyWords(arrayIn, eIn, GDALGetDataTypeSizeBytes(eIn), arrayOut, eOut,
1143 : GDALGetDataTypeSizeBytes(eOut), N);
1144 1 : int numLine = 0;
1145 72 : for (int i = 0; i < N; i++)
1146 : {
1147 71 : MY_EXPECT(eIn, (int)arrayIn[i], eOut, (i % 6) == 0 ? 254 : 255,
1148 : arrayOut[i]);
1149 : }
1150 1 : }
1151 :
1152 : template <>
1153 1 : void CheckPacked<GUInt16, GInt16>(GDALDataType eIn, GDALDataType eOut)
1154 : {
1155 1 : CheckPackedGeneric<GUInt16, GInt16>(eIn, eOut);
1156 :
1157 1 : const int N = 64 + 7;
1158 1 : GUInt16 arrayIn[N] = {0};
1159 1 : GInt16 arrayOut[N] = {0};
1160 72 : for (int i = 0; i < N; i++)
1161 : {
1162 71 : arrayIn[i] = 32766 + (i % 4);
1163 : }
1164 1 : GDALCopyWords(arrayIn, eIn, GDALGetDataTypeSizeBytes(eIn), arrayOut, eOut,
1165 : GDALGetDataTypeSizeBytes(eOut), N);
1166 1 : int numLine = 0;
1167 72 : for (int i = 0; i < N; i++)
1168 : {
1169 71 : MY_EXPECT(eIn, (int)arrayIn[i], eOut, (i % 4) == 0 ? 32766 : 32767,
1170 : arrayOut[i]);
1171 : }
1172 1 : }
1173 :
1174 121 : template <class Tin> void CheckPacked(GDALDataType eIn, GDALDataType eOut)
1175 : {
1176 121 : switch (eOut)
1177 : {
1178 11 : case GDT_Byte:
1179 11 : CheckPacked<Tin, GByte>(eIn, eOut);
1180 11 : break;
1181 11 : case GDT_Int8:
1182 11 : CheckPacked<Tin, GInt8>(eIn, eOut);
1183 11 : break;
1184 11 : case GDT_UInt16:
1185 11 : CheckPacked<Tin, GUInt16>(eIn, eOut);
1186 11 : break;
1187 11 : case GDT_Int16:
1188 11 : CheckPacked<Tin, GInt16>(eIn, eOut);
1189 11 : break;
1190 11 : case GDT_UInt32:
1191 11 : CheckPacked<Tin, GUInt32>(eIn, eOut);
1192 11 : break;
1193 11 : case GDT_Int32:
1194 11 : CheckPacked<Tin, GInt32>(eIn, eOut);
1195 11 : break;
1196 11 : case GDT_UInt64:
1197 11 : CheckPacked<Tin, std::uint64_t>(eIn, eOut);
1198 11 : break;
1199 11 : case GDT_Int64:
1200 11 : CheckPacked<Tin, std::int64_t>(eIn, eOut);
1201 11 : break;
1202 11 : case GDT_Float16:
1203 11 : CheckPacked<Tin, GFloat16>(eIn, eOut);
1204 11 : break;
1205 11 : case GDT_Float32:
1206 11 : CheckPacked<Tin, float>(eIn, eOut);
1207 11 : break;
1208 11 : case GDT_Float64:
1209 11 : CheckPacked<Tin, double>(eIn, eOut);
1210 11 : break;
1211 0 : default:
1212 0 : CPLAssert(false);
1213 : }
1214 121 : }
1215 :
1216 121 : static void CheckPacked(GDALDataType eIn, GDALDataType eOut)
1217 : {
1218 121 : switch (eIn)
1219 : {
1220 11 : case GDT_Byte:
1221 11 : CheckPacked<GByte>(eIn, eOut);
1222 11 : break;
1223 11 : case GDT_Int8:
1224 11 : CheckPacked<GInt8>(eIn, eOut);
1225 11 : break;
1226 11 : case GDT_UInt16:
1227 11 : CheckPacked<GUInt16>(eIn, eOut);
1228 11 : break;
1229 11 : case GDT_Int16:
1230 11 : CheckPacked<GInt16>(eIn, eOut);
1231 11 : break;
1232 11 : case GDT_UInt32:
1233 11 : CheckPacked<GUInt32>(eIn, eOut);
1234 11 : break;
1235 11 : case GDT_Int32:
1236 11 : CheckPacked<GInt32>(eIn, eOut);
1237 11 : break;
1238 11 : case GDT_UInt64:
1239 11 : CheckPacked<std::uint64_t>(eIn, eOut);
1240 11 : break;
1241 11 : case GDT_Int64:
1242 11 : CheckPacked<std::int64_t>(eIn, eOut);
1243 11 : break;
1244 11 : case GDT_Float16:
1245 11 : CheckPacked<GFloat16>(eIn, eOut);
1246 11 : break;
1247 11 : case GDT_Float32:
1248 11 : CheckPacked<float>(eIn, eOut);
1249 11 : break;
1250 11 : case GDT_Float64:
1251 11 : CheckPacked<double>(eIn, eOut);
1252 11 : break;
1253 0 : default:
1254 0 : CPLAssert(false);
1255 : }
1256 121 : }
1257 :
1258 : class TestCopyWordsCheckPackedFixture
1259 : : public TestCopyWords,
1260 : public ::testing::WithParamInterface<
1261 : std::tuple<GDALDataType, GDALDataType>>
1262 : {
1263 : };
1264 :
1265 243 : TEST_P(TestCopyWordsCheckPackedFixture, CheckPacked)
1266 : {
1267 121 : GDALDataType eIn = std::get<0>(GetParam());
1268 121 : GDALDataType eOut = std::get<1>(GetParam());
1269 121 : CheckPacked(eIn, eOut);
1270 121 : }
1271 :
1272 : static std::vector<std::tuple<GDALDataType, GDALDataType>>
1273 1 : GetGDALDataTypeTupleValues()
1274 : {
1275 1 : std::vector<std::tuple<GDALDataType, GDALDataType>> ret;
1276 17 : for (GDALDataType eIn = GDT_Byte; eIn < GDT_TypeCount;
1277 16 : eIn = static_cast<GDALDataType>(eIn + 1))
1278 : {
1279 16 : if (GDALDataTypeIsComplex(eIn))
1280 5 : continue;
1281 187 : for (GDALDataType eOut = GDT_Byte; eOut < GDT_TypeCount;
1282 176 : eOut = static_cast<GDALDataType>(eOut + 1))
1283 : {
1284 176 : if (GDALDataTypeIsComplex(eOut))
1285 55 : continue;
1286 121 : ret.emplace_back(std::make_tuple(eIn, eOut));
1287 : }
1288 : }
1289 1 : return ret;
1290 : }
1291 :
1292 365 : INSTANTIATE_TEST_SUITE_P(
1293 : TestCopyWords, TestCopyWordsCheckPackedFixture,
1294 : ::testing::ValuesIn(GetGDALDataTypeTupleValues()),
1295 : [](const ::testing::TestParamInfo<
1296 : TestCopyWordsCheckPackedFixture::ParamType> &l_info)
1297 : {
1298 : GDALDataType eIn = std::get<0>(l_info.param);
1299 : GDALDataType eOut = std::get<1>(l_info.param);
1300 : return std::string(GDALGetDataTypeName(eIn)) + "_" +
1301 : GDALGetDataTypeName(eOut);
1302 : });
1303 :
1304 4 : TEST_F(TestCopyWords, ByteToByte)
1305 : {
1306 3 : for (int k = 0; k < 2; k++)
1307 : {
1308 2 : if (k == 1)
1309 1 : CPLSetConfigOption("GDAL_USE_SSSE3", "NO");
1310 :
1311 8 : for (int spacing = 2; spacing <= 4; spacing++)
1312 : {
1313 6 : memset(pIn, 0xff, 256);
1314 108 : for (int i = 0; i < 17; i++)
1315 : {
1316 102 : pIn[spacing * i] = (GByte)(17 - i);
1317 : }
1318 6 : memset(pOut, 0xff, 256);
1319 6 : GDALCopyWords(pIn, GDT_Byte, spacing, pOut, GDT_Byte, 1, 17);
1320 108 : for (int i = 0; i < 17; i++)
1321 : {
1322 102 : AssertRes(GDT_Byte, 17 - i, GDT_Byte, 17 - i, pOut[i],
1323 : __LINE__);
1324 : }
1325 :
1326 6 : memset(pIn, 0xff, 256);
1327 6 : memset(pOut, 0xff, 256);
1328 108 : for (int i = 0; i < 17; i++)
1329 : {
1330 102 : pIn[i] = (GByte)(17 - i);
1331 : }
1332 6 : GDALCopyWords(pIn, GDT_Byte, 1, pOut, GDT_Byte, spacing, 17);
1333 108 : for (int i = 0; i < 17; i++)
1334 : {
1335 102 : AssertRes(GDT_Byte, 17 - i, GDT_Byte, 17 - i, pOut[i * spacing],
1336 : __LINE__);
1337 306 : for (int j = 1; j < spacing; j++)
1338 : {
1339 204 : AssertRes(GDT_Byte, 0xff, GDT_Byte, 0xff,
1340 204 : pOut[i * spacing + j], __LINE__);
1341 : }
1342 : }
1343 : }
1344 : }
1345 1 : CPLSetConfigOption("GDAL_USE_SSSE3", nullptr);
1346 1 : }
1347 :
1348 4 : TEST_F(TestCopyWords, Int16ToInt16)
1349 : {
1350 1 : memset(pIn, 0xff, 256);
1351 1 : GInt16 *pInShort = (GInt16 *)pIn;
1352 1 : GInt16 *pOutShort = (GInt16 *)pOut;
1353 10 : for (int i = 0; i < 9; i++)
1354 : {
1355 9 : pInShort[2 * i + 0] = 0x1234;
1356 9 : pInShort[2 * i + 1] = 0x5678;
1357 : }
1358 5 : for (int iSpacing = 0; iSpacing < 4; iSpacing++)
1359 : {
1360 4 : memset(pOut, 0xff, 256);
1361 4 : GDALCopyWords(pInShort, GDT_Int16, sizeof(short), pOutShort, GDT_Int16,
1362 4 : (iSpacing + 1) * sizeof(short), 18);
1363 40 : for (int i = 0; i < 9; i++)
1364 : {
1365 36 : AssertRes(GDT_Int16, pInShort[2 * i + 0], GDT_Int16,
1366 36 : pInShort[2 * i + 0],
1367 36 : pOutShort[(iSpacing + 1) * (2 * i + 0)], __LINE__);
1368 36 : AssertRes(GDT_Int16, pInShort[2 * i + 1], GDT_Int16,
1369 36 : pInShort[2 * i + 1],
1370 36 : pOutShort[(iSpacing + 1) * (2 * i + 1)], __LINE__);
1371 : }
1372 : }
1373 5 : for (int iSpacing = 0; iSpacing < 4; iSpacing++)
1374 : {
1375 4 : memset(pIn, 0xff, 256);
1376 4 : memset(pOut, 0xff, 256);
1377 40 : for (int i = 0; i < 9; i++)
1378 : {
1379 36 : pInShort[(iSpacing + 1) * (2 * i + 0)] = 0x1234;
1380 36 : pInShort[(iSpacing + 1) * (2 * i + 1)] = 0x5678;
1381 : }
1382 4 : GDALCopyWords(pInShort, GDT_Int16, (iSpacing + 1) * sizeof(short),
1383 : pOutShort, GDT_Int16, sizeof(short), 18);
1384 40 : for (int i = 0; i < 9; i++)
1385 : {
1386 36 : AssertRes(GDT_Int16, pInShort[(iSpacing + 1) * (2 * i + 0)],
1387 36 : GDT_Int16, pInShort[(iSpacing + 1) * (2 * i + 0)],
1388 36 : pOutShort[2 * i + 0], __LINE__);
1389 36 : AssertRes(GDT_Int16, pInShort[(iSpacing + 1) * (2 * i + 1)],
1390 36 : GDT_Int16, pInShort[(iSpacing + 1) * (2 * i + 1)],
1391 36 : pOutShort[2 * i + 1], __LINE__);
1392 : }
1393 : }
1394 1 : }
1395 :
1396 : } // namespace
|