LCOV - code coverage report
Current view: top level - apps - gdalalg_raster_overview_add.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 54 54 100.0 %
Date: 2025-05-15 18:21:54 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  gdal "raster overview add" subcommand
       5             :  * Author:   Even Rouault <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2025, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "gdalalg_raster_overview_add.h"
      14             : 
      15             : #include "cpl_string.h"
      16             : #include "gdal_priv.h"
      17             : 
      18             : //! @cond Doxygen_Suppress
      19             : 
      20             : #ifndef _
      21             : #define _(x) (x)
      22             : #endif
      23             : 
      24             : /************************************************************************/
      25             : /*                    GDALRasterOverviewAlgorithmAdd()                  */
      26             : /************************************************************************/
      27             : 
      28          15 : GDALRasterOverviewAlgorithmAdd::GDALRasterOverviewAlgorithmAdd()
      29          15 :     : GDALAlgorithm(NAME, DESCRIPTION, HELP_URL)
      30             : {
      31          15 :     AddProgressArg();
      32          15 :     AddOpenOptionsArg(&m_openOptions);
      33             :     AddArg("dataset", 0,
      34             :            _("Dataset (to be updated in-place, unless --external)"), &m_dataset,
      35          30 :            GDAL_OF_RASTER | GDAL_OF_UPDATE)
      36          15 :         .SetPositional()
      37          15 :         .SetRequired();
      38          30 :     AddArg("external", 0, _("Add external overviews"), &m_readOnly)
      39          30 :         .AddHiddenAlias("ro")
      40          15 :         .AddHiddenAlias(GDAL_ARG_NAME_READ_ONLY);
      41             : 
      42          30 :     AddArg("resampling", 'r', _("Resampling method"), &m_resampling)
      43             :         .SetChoices("nearest", "average", "cubic", "cubicspline", "lanczos",
      44          15 :                     "bilinear", "gauss", "average_magphase", "rms", "mode")
      45          15 :         .SetHiddenChoices("near", "none");
      46             : 
      47          30 :     AddArg("levels", 0, _("Levels / decimation factors"), &m_levels)
      48          15 :         .SetMinValueIncluded(2);
      49             :     AddArg("min-size", 0,
      50             :            _("Maximum width or height of the smallest overview level."),
      51          30 :            &m_minSize)
      52          15 :         .SetMinValueIncluded(1);
      53          15 : }
      54             : 
      55             : /************************************************************************/
      56             : /*                GDALRasterOverviewAlgorithmAdd::RunImpl()             */
      57             : /************************************************************************/
      58             : 
      59           8 : bool GDALRasterOverviewAlgorithmAdd::RunImpl(GDALProgressFunc pfnProgress,
      60             :                                              void *pProgressData)
      61             : {
      62           8 :     auto poDS = m_dataset.GetDatasetRef();
      63           8 :     CPLAssert(poDS);
      64             : 
      65          16 :     std::string resampling = m_resampling;
      66           8 :     if (resampling.empty() && poDS->GetRasterCount() > 0)
      67             :     {
      68           5 :         auto poBand = poDS->GetRasterBand(1);
      69           5 :         if (poBand->GetOverviewCount() > 0)
      70             :         {
      71             :             const char *pszResampling =
      72           1 :                 poBand->GetOverview(0)->GetMetadataItem("RESAMPLING");
      73           1 :             if (pszResampling)
      74             :             {
      75           1 :                 resampling = pszResampling;
      76           1 :                 CPLDebug("GDAL",
      77             :                          "Reusing resampling method %s from existing "
      78             :                          "overview",
      79             :                          pszResampling);
      80             :             }
      81             :         }
      82             :     }
      83           8 :     if (resampling.empty())
      84           4 :         resampling = "nearest";
      85             : 
      86           8 :     std::vector<int> levels = m_levels;
      87             : 
      88             :     // If no levels are specified, reuse the potentially existing ones.
      89           8 :     if (levels.empty() && poDS->GetRasterCount() > 0)
      90             :     {
      91           5 :         auto poBand = poDS->GetRasterBand(1);
      92           5 :         const int nExistingCount = poBand->GetOverviewCount();
      93           5 :         if (nExistingCount > 0)
      94             :         {
      95           2 :             for (int iOvr = 0; iOvr < nExistingCount; ++iOvr)
      96             :             {
      97           1 :                 auto poOverview = poBand->GetOverview(iOvr);
      98           1 :                 if (poOverview)
      99             :                 {
     100           1 :                     const int nOvFactor = GDALComputeOvFactor(
     101             :                         poOverview->GetXSize(), poBand->GetXSize(),
     102           1 :                         poOverview->GetYSize(), poBand->GetYSize());
     103           1 :                     levels.push_back(nOvFactor);
     104             :                 }
     105             :             }
     106             :         }
     107             :     }
     108             : 
     109           8 :     if (levels.empty())
     110             :     {
     111           4 :         const int nXSize = poDS->GetRasterXSize();
     112           4 :         const int nYSize = poDS->GetRasterYSize();
     113           4 :         int nOvrFactor = 1;
     114           9 :         while (DIV_ROUND_UP(nXSize, nOvrFactor) > m_minSize ||
     115           4 :                DIV_ROUND_UP(nYSize, nOvrFactor) > m_minSize)
     116             :         {
     117           5 :             nOvrFactor *= 2;
     118           5 :             levels.push_back(nOvrFactor);
     119             :         }
     120             :     }
     121             : 
     122          16 :     return levels.empty() ||
     123           8 :            GDALBuildOverviews(GDALDataset::ToHandle(poDS), resampling.c_str(),
     124           8 :                               static_cast<int>(levels.size()), levels.data(), 0,
     125          16 :                               nullptr, pfnProgress, pProgressData) == CE_None;
     126             : }
     127             : 
     128             : //! @endcond

Generated by: LCOV version 1.14