LCOV - code coverage report
Current view: top level - apps - gdalalg_raster_overview_add.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 66 69 95.7 %
Date: 2025-07-09 17:50:03 Functions: 2 3 66.7 %

          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.h"
      14             : #include "gdalalg_raster_overview_add.h"
      15             : 
      16             : #include "cpl_string.h"
      17             : #include "gdal_priv.h"
      18             : 
      19             : //! @cond Doxygen_Suppress
      20             : 
      21             : #ifndef _
      22             : #define _(x) (x)
      23             : #endif
      24             : 
      25           0 : bool GDALRasterOverviewAlgorithm::RunImpl(GDALProgressFunc, void *)
      26             : {
      27           0 :     CPLError(CE_Failure, CPLE_AppDefined,
      28             :              "The Run() method should not be called directly on the \"gdal "
      29             :              "raster overview\" program.");
      30           0 :     return false;
      31             : }
      32             : 
      33             : /************************************************************************/
      34             : /*                    GDALRasterOverviewAlgorithmAdd()                  */
      35             : /************************************************************************/
      36             : 
      37          29 : GDALRasterOverviewAlgorithmAdd::GDALRasterOverviewAlgorithmAdd()
      38          29 :     : GDALAlgorithm(NAME, DESCRIPTION, HELP_URL)
      39             : {
      40          29 :     AddProgressArg();
      41          29 :     AddOpenOptionsArg(&m_openOptions);
      42             :     AddArg("dataset", 0,
      43             :            _("Dataset (to be updated in-place, unless --external)"), &m_dataset,
      44          58 :            GDAL_OF_RASTER | GDAL_OF_UPDATE)
      45          29 :         .SetPositional()
      46          29 :         .SetRequired();
      47             : 
      48          29 :     constexpr const char *OVERVIEW_SRC_LEVELS_MUTEX = "overview-src-levels";
      49             : 
      50             :     auto &overviewSrcArg =
      51             :         AddArg("overview-src", 0, _("Source overview dataset"),
      52          58 :                &m_overviewSources, GDAL_OF_RASTER)
      53          29 :             .SetMutualExclusionGroup(OVERVIEW_SRC_LEVELS_MUTEX);
      54          29 :     SetAutoCompleteFunctionForFilename(overviewSrcArg, GDAL_OF_RASTER);
      55             : 
      56          58 :     AddArg("external", 0, _("Add external overviews"), &m_readOnly)
      57          58 :         .AddHiddenAlias("ro")
      58          29 :         .AddHiddenAlias(GDAL_ARG_NAME_READ_ONLY);
      59             : 
      60          58 :     AddArg("resampling", 'r', _("Resampling method"), &m_resampling)
      61             :         .SetChoices("nearest", "average", "cubic", "cubicspline", "lanczos",
      62          29 :                     "bilinear", "gauss", "average_magphase", "rms", "mode")
      63          29 :         .SetHiddenChoices("near", "none");
      64             : 
      65          58 :     AddArg("levels", 0, _("Levels / decimation factors"), &m_levels)
      66          29 :         .SetMinValueIncluded(2)
      67          29 :         .SetMutualExclusionGroup(OVERVIEW_SRC_LEVELS_MUTEX);
      68             :     AddArg("min-size", 0,
      69             :            _("Maximum width or height of the smallest overview level."),
      70          58 :            &m_minSize)
      71          29 :         .SetMinValueIncluded(1);
      72          29 : }
      73             : 
      74             : /************************************************************************/
      75             : /*                GDALRasterOverviewAlgorithmAdd::RunImpl()             */
      76             : /************************************************************************/
      77             : 
      78          22 : bool GDALRasterOverviewAlgorithmAdd::RunImpl(GDALProgressFunc pfnProgress,
      79             :                                              void *pProgressData)
      80             : {
      81          22 :     auto poDS = m_dataset.GetDatasetRef();
      82          22 :     CPLAssert(poDS);
      83             : 
      84          44 :     std::string resampling = m_resampling;
      85          22 :     if (resampling.empty() && poDS->GetRasterCount() > 0)
      86             :     {
      87          19 :         auto poBand = poDS->GetRasterBand(1);
      88          19 :         if (poBand->GetOverviewCount() > 0)
      89             :         {
      90             :             const char *pszResampling =
      91           5 :                 poBand->GetOverview(0)->GetMetadataItem("RESAMPLING");
      92           5 :             if (pszResampling)
      93             :             {
      94           1 :                 resampling = pszResampling;
      95           1 :                 CPLDebug("GDAL",
      96             :                          "Reusing resampling method %s from existing "
      97             :                          "overview",
      98             :                          pszResampling);
      99             :             }
     100             :         }
     101             :     }
     102          22 :     if (resampling.empty())
     103          18 :         resampling = "nearest";
     104             : 
     105          22 :     if (!m_overviewSources.empty())
     106             :     {
     107          14 :         std::vector<GDALDataset *> apoDS;
     108          28 :         for (auto &val : m_overviewSources)
     109             :         {
     110          14 :             CPLAssert(val.GetDatasetRef());
     111          14 :             apoDS.push_back(val.GetDatasetRef());
     112             :         }
     113          14 :         return poDS->AddOverviews(apoDS, pfnProgress, pProgressData, nullptr) ==
     114          14 :                CE_None;
     115             :     }
     116             : 
     117           8 :     std::vector<int> levels = m_levels;
     118             : 
     119             :     // If no levels are specified, reuse the potentially existing ones.
     120           8 :     if (levels.empty() && poDS->GetRasterCount() > 0)
     121             :     {
     122           5 :         auto poBand = poDS->GetRasterBand(1);
     123           5 :         const int nExistingCount = poBand->GetOverviewCount();
     124           5 :         if (nExistingCount > 0)
     125             :         {
     126           2 :             for (int iOvr = 0; iOvr < nExistingCount; ++iOvr)
     127             :             {
     128           1 :                 auto poOverview = poBand->GetOverview(iOvr);
     129           1 :                 if (poOverview)
     130             :                 {
     131           1 :                     const int nOvFactor = GDALComputeOvFactor(
     132             :                         poOverview->GetXSize(), poBand->GetXSize(),
     133           1 :                         poOverview->GetYSize(), poBand->GetYSize());
     134           1 :                     levels.push_back(nOvFactor);
     135             :                 }
     136             :             }
     137             :         }
     138             :     }
     139             : 
     140           8 :     if (levels.empty())
     141             :     {
     142           4 :         const int nXSize = poDS->GetRasterXSize();
     143           4 :         const int nYSize = poDS->GetRasterYSize();
     144           4 :         int nOvrFactor = 1;
     145           9 :         while (DIV_ROUND_UP(nXSize, nOvrFactor) > m_minSize ||
     146           4 :                DIV_ROUND_UP(nYSize, nOvrFactor) > m_minSize)
     147             :         {
     148           5 :             nOvrFactor *= 2;
     149           5 :             levels.push_back(nOvrFactor);
     150             :         }
     151             :     }
     152             : 
     153          16 :     return levels.empty() ||
     154           8 :            GDALBuildOverviews(GDALDataset::ToHandle(poDS), resampling.c_str(),
     155           8 :                               static_cast<int>(levels.size()), levels.data(), 0,
     156           8 :                               nullptr, pfnProgress, pProgressData) == CE_None;
     157             : }
     158             : 
     159             : //! @endcond

Generated by: LCOV version 1.14