LCOV - code coverage report
Current view: top level - autotest/cpp - testcopywords.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 847 856 98.9 %
Date: 2025-02-20 10:14:44 Functions: 519 627 82.8 %

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

Generated by: LCOV version 1.14