LCOV - code coverage report
Current view: top level - alg - gdalgeoloc_carray_accessor.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 104 112 92.9 %
Date: 2024-05-04 12:52:34 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  C-Array storage of geolocation array and backmap
       5             :  * Author:   Even Rouault, <even.rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2022, Planet Labs
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : /*! @cond Doxygen_Suppress */
      30             : 
      31             : /************************************************************************/
      32             : /*                        GDALGeoLocCArrayAccessors                     */
      33             : /************************************************************************/
      34             : 
      35             : class GDALGeoLocCArrayAccessors
      36             : {
      37             :     typedef class GDALGeoLocCArrayAccessors AccessorType;
      38             : 
      39             :     GDALGeoLocTransformInfo *m_psTransform;
      40             :     double *m_padfGeoLocX = nullptr;
      41             :     double *m_padfGeoLocY = nullptr;
      42             :     float *m_pafBackMapX = nullptr;
      43             :     float *m_pafBackMapY = nullptr;
      44             :     float *m_wgtsBackMap = nullptr;
      45             : 
      46             :     bool LoadGeoloc(bool bIsRegularGrid);
      47             : 
      48             :   public:
      49             :     template <class Type> struct CArrayAccessor
      50             :     {
      51             :         Type *m_array;
      52             :         size_t m_nXSize;
      53             : 
      54         230 :         CArrayAccessor(Type *array, size_t nXSize)
      55         230 :             : m_array(array), m_nXSize(nXSize)
      56             :         {
      57         230 :         }
      58             : 
      59    23309440 :         inline Type Get(int nX, int nY, bool *pbSuccess = nullptr)
      60             :         {
      61    23309440 :             if (pbSuccess)
      62           0 :                 *pbSuccess = true;
      63    23309440 :             return m_array[nY * m_nXSize + nX];
      64             :         }
      65             : 
      66     1930990 :         inline bool Set(int nX, int nY, Type val)
      67             :         {
      68     1930990 :             m_array[nY * m_nXSize + nX] = val;
      69     1930990 :             return true;
      70             :         }
      71             :     };
      72             : 
      73             :     CArrayAccessor<double> geolocXAccessor;
      74             :     CArrayAccessor<double> geolocYAccessor;
      75             :     CArrayAccessor<float> backMapXAccessor;
      76             :     CArrayAccessor<float> backMapYAccessor;
      77             :     CArrayAccessor<float> backMapWeightAccessor;
      78             : 
      79          46 :     explicit GDALGeoLocCArrayAccessors(GDALGeoLocTransformInfo *psTransform)
      80          46 :         : m_psTransform(psTransform), geolocXAccessor(nullptr, 0),
      81             :           geolocYAccessor(nullptr, 0), backMapXAccessor(nullptr, 0),
      82          46 :           backMapYAccessor(nullptr, 0), backMapWeightAccessor(nullptr, 0)
      83             :     {
      84          46 :     }
      85             : 
      86          46 :     ~GDALGeoLocCArrayAccessors()
      87          46 :     {
      88          46 :         VSIFree(m_pafBackMapX);
      89          46 :         VSIFree(m_pafBackMapY);
      90          46 :         VSIFree(m_padfGeoLocX);
      91          46 :         VSIFree(m_padfGeoLocY);
      92          46 :         VSIFree(m_wgtsBackMap);
      93          46 :     }
      94             : 
      95             :     GDALGeoLocCArrayAccessors(const GDALGeoLocCArrayAccessors &) = delete;
      96             :     GDALGeoLocCArrayAccessors &
      97             :     operator=(const GDALGeoLocCArrayAccessors &) = delete;
      98             : 
      99             :     bool Load(bool bIsRegularGrid, bool bUseQuadtree);
     100             : 
     101             :     bool AllocateBackMap();
     102             : 
     103             :     GDALDataset *GetBackmapDataset();
     104             : 
     105          42 :     static void FlushBackmapCaches()
     106             :     {
     107          42 :     }
     108             : 
     109          42 :     static void ReleaseBackmapDataset(GDALDataset *poDS)
     110             :     {
     111          42 :         delete poDS;
     112          42 :     }
     113             : 
     114             :     void FreeWghtsBackMap();
     115             : };
     116             : 
     117             : /************************************************************************/
     118             : /*                         AllocateBackMap()                            */
     119             : /************************************************************************/
     120             : 
     121          42 : bool GDALGeoLocCArrayAccessors::AllocateBackMap()
     122             : {
     123          42 :     m_pafBackMapX = static_cast<float *>(
     124          42 :         VSI_MALLOC3_VERBOSE(m_psTransform->nBackMapWidth,
     125             :                             m_psTransform->nBackMapHeight, sizeof(float)));
     126          42 :     m_pafBackMapY = static_cast<float *>(
     127          42 :         VSI_MALLOC3_VERBOSE(m_psTransform->nBackMapWidth,
     128             :                             m_psTransform->nBackMapHeight, sizeof(float)));
     129             : 
     130          42 :     m_wgtsBackMap = static_cast<float *>(
     131          42 :         VSI_MALLOC3_VERBOSE(m_psTransform->nBackMapWidth,
     132             :                             m_psTransform->nBackMapHeight, sizeof(float)));
     133             : 
     134          42 :     if (m_pafBackMapX == nullptr || m_pafBackMapY == nullptr ||
     135          42 :         m_wgtsBackMap == nullptr)
     136             :     {
     137           0 :         return false;
     138             :     }
     139             : 
     140          42 :     const size_t nBMXYCount =
     141          42 :         static_cast<size_t>(m_psTransform->nBackMapWidth) *
     142          42 :         m_psTransform->nBackMapHeight;
     143      186014 :     for (size_t i = 0; i < nBMXYCount; i++)
     144             :     {
     145      185972 :         m_pafBackMapX[i] = 0;
     146      185972 :         m_pafBackMapY[i] = 0;
     147      185972 :         m_wgtsBackMap[i] = 0.0;
     148             :     }
     149             : 
     150          42 :     backMapXAccessor.m_array = m_pafBackMapX;
     151          42 :     backMapXAccessor.m_nXSize = m_psTransform->nBackMapWidth;
     152             : 
     153          42 :     backMapYAccessor.m_array = m_pafBackMapY;
     154          42 :     backMapYAccessor.m_nXSize = m_psTransform->nBackMapWidth;
     155             : 
     156          42 :     backMapWeightAccessor.m_array = m_wgtsBackMap;
     157          42 :     backMapWeightAccessor.m_nXSize = m_psTransform->nBackMapWidth;
     158             : 
     159          42 :     return true;
     160             : }
     161             : 
     162             : /************************************************************************/
     163             : /*                         FreeWghtsBackMap()                           */
     164             : /************************************************************************/
     165             : 
     166          42 : void GDALGeoLocCArrayAccessors::FreeWghtsBackMap()
     167             : {
     168          42 :     VSIFree(m_wgtsBackMap);
     169          42 :     m_wgtsBackMap = nullptr;
     170          42 :     backMapWeightAccessor.m_array = nullptr;
     171          42 :     backMapWeightAccessor.m_nXSize = 0;
     172          42 : }
     173             : 
     174             : /************************************************************************/
     175             : /*                        GetBackmapDataset()                           */
     176             : /************************************************************************/
     177             : 
     178          42 : GDALDataset *GDALGeoLocCArrayAccessors::GetBackmapDataset()
     179             : {
     180          84 :     auto poMEMDS = MEMDataset::Create("", m_psTransform->nBackMapWidth,
     181          42 :                                       m_psTransform->nBackMapHeight, 0,
     182             :                                       GDT_Float32, nullptr);
     183             : 
     184         126 :     for (int i = 1; i <= 2; i++)
     185             :     {
     186          84 :         void *ptr = (i == 1) ? m_pafBackMapX : m_pafBackMapY;
     187          84 :         GDALRasterBandH hMEMBand = MEMCreateRasterBandEx(
     188             :             poMEMDS, i, static_cast<GByte *>(ptr), GDT_Float32, 0, 0, false);
     189          84 :         poMEMDS->AddMEMBand(hMEMBand);
     190          84 :         poMEMDS->GetRasterBand(i)->SetNoDataValue(INVALID_BMXY);
     191             :     }
     192          42 :     return poMEMDS;
     193             : }
     194             : 
     195             : /************************************************************************/
     196             : /*                             Load()                                   */
     197             : /************************************************************************/
     198             : 
     199          46 : bool GDALGeoLocCArrayAccessors::Load(bool bIsRegularGrid, bool bUseQuadtree)
     200             : {
     201          92 :     return LoadGeoloc(bIsRegularGrid) &&
     202           4 :            ((bUseQuadtree && GDALGeoLocBuildQuadTree(m_psTransform)) ||
     203          42 :             (!bUseQuadtree &&
     204          88 :              GDALGeoLoc<AccessorType>::GenerateBackMap(m_psTransform)));
     205             : }
     206             : 
     207             : /************************************************************************/
     208             : /*                          LoadGeoloc()                                */
     209             : /************************************************************************/
     210             : 
     211          46 : bool GDALGeoLocCArrayAccessors::LoadGeoloc(bool bIsRegularGrid)
     212             : 
     213             : {
     214          46 :     const int nXSize = m_psTransform->nGeoLocXSize;
     215          46 :     const int nYSize = m_psTransform->nGeoLocYSize;
     216             : 
     217          46 :     m_padfGeoLocY = static_cast<double *>(
     218          46 :         VSI_MALLOC3_VERBOSE(sizeof(double), nXSize, nYSize));
     219          46 :     m_padfGeoLocX = static_cast<double *>(
     220          46 :         VSI_MALLOC3_VERBOSE(sizeof(double), nXSize, nYSize));
     221             : 
     222          46 :     if (m_padfGeoLocX == nullptr || m_padfGeoLocY == nullptr)
     223             :     {
     224           0 :         return false;
     225             :     }
     226             : 
     227          46 :     if (bIsRegularGrid)
     228             :     {
     229             :         // Case of regular grid.
     230             :         // The XBAND contains the x coordinates for all lines.
     231             :         // The YBAND contains the y coordinates for all columns.
     232             : 
     233             :         double *padfTempX =
     234          14 :             static_cast<double *>(VSI_MALLOC2_VERBOSE(nXSize, sizeof(double)));
     235             :         double *padfTempY =
     236          14 :             static_cast<double *>(VSI_MALLOC2_VERBOSE(nYSize, sizeof(double)));
     237          14 :         if (padfTempX == nullptr || padfTempY == nullptr)
     238             :         {
     239           0 :             CPLFree(padfTempX);
     240           0 :             CPLFree(padfTempY);
     241           0 :             return false;
     242             :         }
     243             : 
     244             :         CPLErr eErr =
     245          14 :             GDALRasterIO(m_psTransform->hBand_X, GF_Read, 0, 0, nXSize, 1,
     246             :                          padfTempX, nXSize, 1, GDT_Float64, 0, 0);
     247             : 
     248         262 :         for (size_t j = 0; j < static_cast<size_t>(nYSize); j++)
     249             :         {
     250         248 :             memcpy(m_padfGeoLocX + j * nXSize, padfTempX,
     251         248 :                    nXSize * sizeof(double));
     252             :         }
     253             : 
     254          14 :         if (eErr == CE_None)
     255             :         {
     256          14 :             eErr = GDALRasterIO(m_psTransform->hBand_Y, GF_Read, 0, 0, nYSize,
     257             :                                 1, padfTempY, nYSize, 1, GDT_Float64, 0, 0);
     258             : 
     259         262 :             for (size_t j = 0; j < static_cast<size_t>(nYSize); j++)
     260             :             {
     261       31480 :                 for (size_t i = 0; i < static_cast<size_t>(nXSize); i++)
     262             :                 {
     263       31232 :                     m_padfGeoLocY[j * nXSize + i] = padfTempY[j];
     264             :                 }
     265             :             }
     266             :         }
     267             : 
     268          14 :         CPLFree(padfTempX);
     269          14 :         CPLFree(padfTempY);
     270             : 
     271          14 :         if (eErr != CE_None)
     272           0 :             return false;
     273             :     }
     274             :     else
     275             :     {
     276          96 :         if (GDALRasterIO(m_psTransform->hBand_X, GF_Read, 0, 0, nXSize, nYSize,
     277          32 :                          m_padfGeoLocX, nXSize, nYSize, GDT_Float64, 0,
     278          64 :                          0) != CE_None ||
     279          32 :             GDALRasterIO(m_psTransform->hBand_Y, GF_Read, 0, 0, nXSize, nYSize,
     280          32 :                          m_padfGeoLocY, nXSize, nYSize, GDT_Float64, 0,
     281             :                          0) != CE_None)
     282           0 :             return false;
     283             :     }
     284             : 
     285          46 :     geolocXAccessor.m_array = m_padfGeoLocX;
     286          46 :     geolocXAccessor.m_nXSize = m_psTransform->nGeoLocXSize;
     287             : 
     288          46 :     geolocYAccessor.m_array = m_padfGeoLocY;
     289          46 :     geolocYAccessor.m_nXSize = m_psTransform->nGeoLocXSize;
     290             : 
     291          46 :     GDALGeoLoc<GDALGeoLocCArrayAccessors>::LoadGeolocFinish(m_psTransform);
     292          46 :     return true;
     293             : }
     294             : 
     295             : /*! @endcond */

Generated by: LCOV version 1.14