LCOV - code coverage report
Current view: top level - autotest/cpp - testcopywords.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 709 718 98.7 %
Date: 2024-11-21 22:18:42 Functions: 435 529 82.2 %

          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

Generated by: LCOV version 1.14