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: 2025-05-15 13:16:46 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          29 : GDALRasterScaleAlgorithm::GDALRasterScaleAlgorithm(bool standaloneStep)
      31             :     : GDALRasterPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
      32          29 :                                       standaloneStep)
      33             : {
      34          29 :     AddOutputDataTypeArg(&m_type);
      35             :     AddBandArg(&m_band,
      36          29 :                _("Select band to restrict the scaling (1-based index)"));
      37          29 :     AddArg("src-min", 0, _("Minimum value of the source range"), &m_srcMin);
      38          29 :     AddArg("src-max", 0, _("Maximum value of the source range"), &m_srcMax);
      39             :     AddArg("dst-min", 0, _("Minimum value of the destination range"),
      40          29 :            &m_dstMin);
      41             :     AddArg("dst-max", 0, _("Maximum value of the destination range"),
      42          29 :            &m_dstMax);
      43             :     AddArg("exponent", 0,
      44             :            _("Exponent to apply non-linear scaling with a power function"),
      45          29 :            &m_exponent);
      46             :     AddArg("no-clip", 0, _("Do not clip input values to [srcmin, srcmax]"),
      47          29 :            &m_noClip);
      48          29 : }
      49             : 
      50             : /************************************************************************/
      51             : /*               GDALRasterScaleAlgorithm::RunStep()                    */
      52             : /************************************************************************/
      53             : 
      54          21 : bool GDALRasterScaleAlgorithm::RunStep(GDALProgressFunc, void *)
      55             : {
      56          21 :     CPLAssert(m_inputDataset.GetDatasetRef());
      57          21 :     CPLAssert(m_outputDataset.GetName().empty());
      58          21 :     CPLAssert(!m_outputDataset.GetDatasetRef());
      59             : 
      60          42 :     CPLStringList aosOptions;
      61          21 :     aosOptions.AddString("-of");
      62          21 :     aosOptions.AddString("VRT");
      63          21 :     if (!m_type.empty())
      64             :     {
      65           1 :         aosOptions.AddString("-ot");
      66           1 :         aosOptions.AddString(m_type.c_str());
      67             :     }
      68           2 :     aosOptions.AddString(m_band > 0 ? CPLSPrintf("-scale_%d", m_band)
      69          23 :                                     : "-scale");
      70          21 :     if (!std::isnan(m_srcMin))
      71             :     {
      72           9 :         if (std::isnan(m_srcMax))
      73             :         {
      74           1 :             ReportError(CE_Failure, CPLE_AppDefined,
      75             :                         "src-max must be specified when src-min is specified");
      76           1 :             return false;
      77             :         }
      78           8 :         aosOptions.AddString(CPLSPrintf("%.17g", m_srcMin));
      79           8 :         aosOptions.AddString(CPLSPrintf("%.17g", m_srcMax));
      80             :     }
      81          12 :     else if (!std::isnan(m_srcMax))
      82             :     {
      83           1 :         ReportError(CE_Failure, CPLE_AppDefined,
      84             :                     "src-min must be specified when src-max is specified");
      85           1 :         return false;
      86             :     }
      87             : 
      88          19 :     if (!std::isnan(m_dstMin))
      89             :     {
      90           9 :         if (std::isnan(m_dstMax))
      91             :         {
      92           1 :             ReportError(CE_Failure, CPLE_AppDefined,
      93             :                         "dst-max must be specified when dst-min is specified");
      94           1 :             return false;
      95             :         }
      96           8 :         if (std::isnan(m_srcMin))
      97             :         {
      98           1 :             aosOptions.AddString("NaN");
      99           1 :             aosOptions.AddString("NaN");
     100             :         }
     101           8 :         aosOptions.AddString(CPLSPrintf("%.17g", m_dstMin));
     102           8 :         aosOptions.AddString(CPLSPrintf("%.17g", m_dstMax));
     103             :     }
     104          10 :     else if (!std::isnan(m_dstMax))
     105             :     {
     106           1 :         ReportError(CE_Failure, CPLE_AppDefined,
     107             :                     "dst-min must be specified when dst-max is specified");
     108           1 :         return false;
     109             :     }
     110             : 
     111          17 :     if (!std::isnan(m_exponent))
     112             :     {
     113           1 :         aosOptions.AddString(m_band > 0 ? CPLSPrintf("-exponent_%d", m_band)
     114           4 :                                         : "-exponent");
     115           3 :         aosOptions.AddString(CPLSPrintf("%.17g", m_exponent));
     116             :     }
     117          14 :     else if (!m_noClip)
     118             :     {
     119           1 :         aosOptions.AddString(m_band > 0 ? CPLSPrintf("-exponent_%d", m_band)
     120          14 :                                         : "-exponent");
     121          13 :         aosOptions.AddString("1");
     122             :     }
     123             : 
     124          17 :     if (m_noClip)
     125             :     {
     126           2 :         aosOptions.AddString("--no-clip");
     127             :     }
     128             : 
     129             :     GDALTranslateOptions *psOptions =
     130          17 :         GDALTranslateOptionsNew(aosOptions.List(), nullptr);
     131             : 
     132             :     auto poOutDS = std::unique_ptr<GDALDataset>(GDALDataset::FromHandle(
     133             :         GDALTranslate("", GDALDataset::ToHandle(m_inputDataset.GetDatasetRef()),
     134          17 :                       psOptions, nullptr)));
     135          17 :     GDALTranslateOptionsFree(psOptions);
     136          17 :     const bool bRet = poOutDS != nullptr;
     137          17 :     if (poOutDS)
     138             :     {
     139          17 :         m_outputDataset.Set(std::move(poOutDS));
     140             :     }
     141             : 
     142          17 :     return bRet;
     143             : }
     144             : 
     145             : //! @endcond

Generated by: LCOV version 1.14