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