LCOV - code coverage report
Current view: top level - apps - gdalalg_raster_scale.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 61 61 100.0 %
Date: 2026-04-23 19:47:11 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  "scale" step of "raster pipeline"
       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_scale.h"
      14             : 
      15             : #include "gdal_priv.h"
      16             : #include "gdal_utils.h"
      17             : 
      18             : #include <cmath>
      19             : 
      20             : //! @cond Doxygen_Suppress
      21             : 
      22             : #ifndef _
      23             : #define _(x) (x)
      24             : #endif
      25             : 
      26             : /************************************************************************/
      27             : /*         GDALRasterScaleAlgorithm::GDALRasterScaleAlgorithm()         */
      28             : /************************************************************************/
      29             : 
      30         101 : GDALRasterScaleAlgorithm::GDALRasterScaleAlgorithm(bool standaloneStep)
      31             :     : GDALRasterPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
      32         101 :                                       standaloneStep)
      33             : {
      34         101 :     AddOutputDataTypeArg(&m_type);
      35             :     AddBandArg(&m_band,
      36         101 :                _("Select band to restrict the scaling (1-based index)"));
      37         202 :     AddArg("input-min", 0, _("Minimum value of the source range"), &m_srcMin)
      38         202 :         .SetMutualDependencyGroup("input-max-min")
      39         101 :         .AddHiddenAlias("src-min");
      40         202 :     AddArg("input-max", 0, _("Maximum value of the source range"), &m_srcMax)
      41         202 :         .SetMutualDependencyGroup("input-max-min")
      42         101 :         .AddHiddenAlias("src-max");
      43             :     AddArg("output-min", 0, _("Minimum value of the destination range"),
      44         202 :            &m_dstMin)
      45         202 :         .SetMutualDependencyGroup("output-max-min")
      46         101 :         .AddHiddenAlias("dst-min");
      47             :     AddArg("output-max", 0, _("Maximum value of the destination range"),
      48         202 :            &m_dstMax)
      49         202 :         .SetMutualDependencyGroup("output-max-min")
      50         101 :         .AddHiddenAlias("dst-max");
      51             :     AddArg("exponent", 0,
      52             :            _("Exponent to apply non-linear scaling with a power function"),
      53         101 :            &m_exponent);
      54             :     AddArg("no-clip", 0,
      55         101 :            _("Do not clip input values to [innput-min, input-max]"), &m_noClip);
      56         101 : }
      57             : 
      58             : /************************************************************************/
      59             : /*                 GDALRasterScaleAlgorithm::RunStep()                  */
      60             : /************************************************************************/
      61             : 
      62          17 : bool GDALRasterScaleAlgorithm::RunStep(GDALPipelineStepRunContext &)
      63             : {
      64          17 :     auto poSrcDS = m_inputDataset[0].GetDatasetRef();
      65          17 :     CPLAssert(poSrcDS);
      66          17 :     CPLAssert(m_outputDataset.GetName().empty());
      67          17 :     CPLAssert(!m_outputDataset.GetDatasetRef());
      68             : 
      69          34 :     CPLStringList aosOptions;
      70          17 :     aosOptions.AddString("-of");
      71          17 :     aosOptions.AddString("VRT");
      72          17 :     if (!m_type.empty())
      73             :     {
      74           1 :         aosOptions.AddString("-ot");
      75           1 :         aosOptions.AddString(m_type.c_str());
      76             :     }
      77           2 :     aosOptions.AddString(m_band > 0 ? CPLSPrintf("-scale_%d", m_band)
      78          19 :                                     : "-scale");
      79             : 
      80          17 :     CPLAssert((std::isnan(m_srcMax) && std::isnan(m_srcMin)) ||
      81             :               (!std::isnan(m_srcMax) && !std::isnan(m_srcMin)));
      82             : 
      83          17 :     if (!std::isnan(m_srcMin))
      84             :     {
      85           8 :         CPLAssert(!std::isnan(m_srcMax));
      86           8 :         aosOptions.AddString(CPLSPrintf("%.17g", m_srcMin));
      87           8 :         aosOptions.AddString(CPLSPrintf("%.17g", m_srcMax));
      88             :     }
      89             : 
      90          17 :     CPLAssert((std::isnan(m_dstMax) && std::isnan(m_dstMin)) ||
      91             :               (!std::isnan(m_dstMax) && !std::isnan(m_dstMin)));
      92          17 :     if (!std::isnan(m_dstMin))
      93             :     {
      94           8 :         if (std::isnan(m_srcMin))
      95             :         {
      96           1 :             aosOptions.AddString("NaN");
      97           1 :             aosOptions.AddString("NaN");
      98             :         }
      99           8 :         aosOptions.AddString(CPLSPrintf("%.17g", m_dstMin));
     100           8 :         aosOptions.AddString(CPLSPrintf("%.17g", m_dstMax));
     101             :     }
     102             : 
     103          17 :     if (!std::isnan(m_exponent))
     104             :     {
     105           1 :         aosOptions.AddString(m_band > 0 ? CPLSPrintf("-exponent_%d", m_band)
     106           4 :                                         : "-exponent");
     107           3 :         aosOptions.AddString(CPLSPrintf("%.17g", m_exponent));
     108             :     }
     109          14 :     else if (!m_noClip)
     110             :     {
     111           1 :         aosOptions.AddString(m_band > 0 ? CPLSPrintf("-exponent_%d", m_band)
     112          14 :                                         : "-exponent");
     113          13 :         aosOptions.AddString("1");
     114             :     }
     115             : 
     116          17 :     if (m_noClip)
     117             :     {
     118           2 :         aosOptions.AddString("--no-clip");
     119             :     }
     120             : 
     121             :     GDALTranslateOptions *psOptions =
     122          17 :         GDALTranslateOptionsNew(aosOptions.List(), nullptr);
     123             : 
     124             :     auto poOutDS = std::unique_ptr<GDALDataset>(GDALDataset::FromHandle(
     125          17 :         GDALTranslate("", GDALDataset::ToHandle(poSrcDS), psOptions, nullptr)));
     126          17 :     GDALTranslateOptionsFree(psOptions);
     127          17 :     const bool bRet = poOutDS != nullptr;
     128          17 :     if (poOutDS)
     129             :     {
     130          17 :         m_outputDataset.Set(std::move(poOutDS));
     131             :     }
     132             : 
     133          34 :     return bRet;
     134             : }
     135             : 
     136             : GDALRasterScaleAlgorithmStandalone::~GDALRasterScaleAlgorithmStandalone() =
     137             :     default;
     138             : 
     139             : //! @endcond

Generated by: LCOV version 1.14