LCOV - code coverage report
Current view: top level - apps - gdalalg_raster_nodata_to_alpha.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 60 60 100.0 %
Date: 2025-06-19 12:30:01 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  "nodata-to-alpha" 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_nodata_to_alpha.h"
      14             : 
      15             : #include "gdal_priv.h"
      16             : #include "gdal_utils.h"
      17             : 
      18             : //! @cond Doxygen_Suppress
      19             : 
      20             : #ifndef _
      21             : #define _(x) (x)
      22             : #endif
      23             : 
      24             : /************************************************************************/
      25             : /* GDALRasterNoDataToAlphaAlgorithm::GDALRasterNoDataToAlphaAlgorithm() */
      26             : /************************************************************************/
      27             : 
      28          27 : GDALRasterNoDataToAlphaAlgorithm::GDALRasterNoDataToAlphaAlgorithm(
      29          27 :     bool standaloneStep)
      30             :     : GDALRasterPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
      31          27 :                                       standaloneStep)
      32             : {
      33             :     AddArg("nodata", 0,
      34             :            _("Override nodata value of input band(s) "
      35             :              "(numeric value, 'nan', 'inf', '-inf')"),
      36          27 :            &m_nodata);
      37          27 : }
      38             : 
      39             : /************************************************************************/
      40             : /*              GDALRasterNoDataToAlphaAlgorithm::RunStep()             */
      41             : /************************************************************************/
      42             : 
      43           5 : bool GDALRasterNoDataToAlphaAlgorithm::RunStep(GDALPipelineStepRunContext &)
      44             : {
      45           5 :     GDALDataset *poSrcDS = m_inputDataset[0].GetDatasetRef();
      46           5 :     CPLAssert(poSrcDS);
      47           5 :     CPLAssert(m_outputDataset.GetName().empty());
      48           5 :     CPLAssert(!m_outputDataset.GetDatasetRef());
      49             : 
      50           5 :     if (!m_nodata.empty())
      51             :     {
      52           3 :         CPLStringList aosOptions;
      53           3 :         aosOptions.AddString("-of");
      54           3 :         aosOptions.AddString("VRT");
      55             : 
      56           3 :         if (m_nodata.size() == 1)
      57             :         {
      58           1 :             aosOptions.AddString("-a_nodata");
      59           1 :             aosOptions.AddString(CPLSPrintf("%.17g", m_nodata[0]));
      60             :         }
      61             :         else
      62             :         {
      63           2 :             if (m_nodata.size() !=
      64           2 :                 static_cast<size_t>(poSrcDS->GetRasterCount()))
      65             :             {
      66           1 :                 ReportError(CE_Failure, CPLE_IllegalArg,
      67             :                             "There should be %d nodata values given the input "
      68             :                             "dataset has %d bands",
      69             :                             poSrcDS->GetRasterCount(),
      70             :                             poSrcDS->GetRasterCount());
      71           1 :                 return false;
      72             :             }
      73           1 :             aosOptions.AddString("-mo");
      74           2 :             std::string nodataValues("NODATA_VALUES=");
      75           4 :             for (size_t i = 0; i < m_nodata.size(); ++i)
      76             :             {
      77           3 :                 if (i > 0)
      78           2 :                     nodataValues += ' ';
      79           3 :                 nodataValues += CPLSPrintf("%.17g", m_nodata[i]);
      80             :             }
      81           1 :             aosOptions.AddString(nodataValues.c_str());
      82             :         }
      83             : 
      84             :         GDALTranslateOptions *psOptions =
      85           2 :             GDALTranslateOptionsNew(aosOptions.List(), nullptr);
      86           2 :         if (psOptions)
      87             :         {
      88           2 :             m_tempDS.reset(GDALDataset::FromHandle(GDALTranslate(
      89             :                 "", GDALDataset::ToHandle(poSrcDS), psOptions, nullptr)));
      90           2 :             GDALTranslateOptionsFree(psOptions);
      91             :         }
      92           2 :         poSrcDS = m_tempDS.get();
      93             :     }
      94             : 
      95           4 :     bool bRet = poSrcDS != nullptr;
      96           4 :     if (poSrcDS)
      97             :     {
      98           8 :         CPLStringList aosOptions;
      99           4 :         aosOptions.AddString("-of");
     100           4 :         aosOptions.AddString("VRT");
     101             : 
     102           4 :         if (poSrcDS->GetRasterCount() > 0 &&
     103           7 :             poSrcDS->GetRasterBand(1)->GetMaskFlags() != GMF_ALL_VALID &&
     104           3 :             poSrcDS->GetRasterBand(1)->GetMaskFlags() !=
     105             :                 (GMF_ALPHA | GMF_PER_DATASET))
     106             :         {
     107           3 :             aosOptions.AddString("-a_nodata");
     108           3 :             aosOptions.AddString("none");
     109             : 
     110           8 :             for (int i = 1; i <= poSrcDS->GetRasterCount(); ++i)
     111             :             {
     112           5 :                 aosOptions.AddString("-b");
     113           5 :                 aosOptions.AddString(CPLSPrintf("%d", i));
     114             :             }
     115           3 :             aosOptions.AddString("-b");
     116           3 :             aosOptions.AddString("mask");
     117             : 
     118             :             aosOptions.AddString(
     119           3 :                 CPLSPrintf("-colorinterp_%d", poSrcDS->GetRasterCount() + 1));
     120           3 :             aosOptions.AddString("alpha");
     121             :         }
     122             : 
     123           4 :         std::unique_ptr<GDALDataset> poOutDS;
     124             :         GDALTranslateOptions *psOptions =
     125           4 :             GDALTranslateOptionsNew(aosOptions.List(), nullptr);
     126           4 :         if (psOptions)
     127             :         {
     128           4 :             poOutDS.reset(GDALDataset::FromHandle(GDALTranslate(
     129             :                 "", GDALDataset::ToHandle(poSrcDS), psOptions, nullptr)));
     130           4 :             GDALTranslateOptionsFree(psOptions);
     131             : 
     132           4 :             poOutDS->GetRasterBand(1)->GetMaskFlags();
     133             :         }
     134           4 :         bRet = poOutDS != nullptr;
     135           4 :         if (poOutDS)
     136             :         {
     137           4 :             m_outputDataset.Set(std::move(poOutDS));
     138             :         }
     139             :     }
     140             : 
     141           4 :     return bRet;
     142             : }
     143             : 
     144             : GDALRasterNoDataToAlphaAlgorithmStandalone::
     145             :     ~GDALRasterNoDataToAlphaAlgorithmStandalone() = default;
     146             : 
     147             : //! @endcond

Generated by: LCOV version 1.14