LCOV - code coverage report
Current view: top level - apps - gdalalg_raster_info.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 113 116 97.4 %
Date: 2026-06-23 16:35:19 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  gdal "raster info" subcommand
       5             :  * Author:   Even Rouault <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "gdalalg_raster_info.h"
      14             : 
      15             : #include "cpl_conv.h"
      16             : #include "gdal_priv.h"
      17             : #include "gdal_utils.h"
      18             : 
      19             : //! @cond Doxygen_Suppress
      20             : 
      21             : #ifndef _
      22             : #define _(x) (x)
      23             : #endif
      24             : 
      25             : /************************************************************************/
      26             : /*          GDALRasterInfoAlgorithm::GDALRasterInfoAlgorithm()          */
      27             : /************************************************************************/
      28             : 
      29         239 : GDALRasterInfoAlgorithm::GDALRasterInfoAlgorithm(bool standaloneStep,
      30         239 :                                                  bool openForMixedRasterVector)
      31             :     : GDALRasterPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
      32           0 :                                       ConstructorOptions()
      33         239 :                                           .SetStandaloneStep(standaloneStep)
      34         239 :                                           .SetInputDatasetMaxCount(1)
      35         239 :                                           .SetAddDefaultArguments(false)
      36         478 :                                           .SetInputDatasetAlias("dataset"))
      37             : {
      38         239 :     if (standaloneStep)
      39             :     {
      40         163 :         AddRasterInputArgs(openForMixedRasterVector,
      41             :                            /* hiddenForCLI = */ false);
      42             :     }
      43             :     else
      44             :     {
      45          76 :         AddRasterHiddenInputDatasetArg();
      46             :     }
      47             : 
      48         239 :     AddOutputFormatArg(&m_format).SetChoices("json", "text");
      49         478 :     AddArg("min-max", 0, _("Compute minimum and maximum value"), &m_minMax)
      50         239 :         .AddAlias("mm");
      51             :     AddArg("stats", 0, _("Retrieve or compute statistics, using all pixels"),
      52         478 :            &m_stats)
      53         239 :         .SetMutualExclusionGroup("stats");
      54             :     AddArg("approx-stats", 0,
      55             :            _("Retrieve or compute statistics, using a subset of pixels"),
      56         478 :            &m_approxStats)
      57         239 :         .SetMutualExclusionGroup("stats");
      58         239 :     AddArg("hist", 0, _("Retrieve or compute histogram"), &m_hist);
      59             : 
      60             :     AddArg("no-gcp", 0, _("Suppress ground control points list printing"),
      61         478 :            &m_noGCP)
      62         239 :         .SetCategory(GAAC_ADVANCED);
      63         478 :     AddArg("no-md", 0, _("Suppress metadata printing"), &m_noMD)
      64         239 :         .SetCategory(GAAC_ADVANCED);
      65         478 :     AddArg("no-ct", 0, _("Suppress color table printing"), &m_noCT)
      66         239 :         .SetCategory(GAAC_ADVANCED);
      67         478 :     AddArg("no-fl", 0, _("Suppress file list printing"), &m_noFL)
      68         239 :         .SetCategory(GAAC_ADVANCED);
      69         478 :     AddArg("checksum", 0, _("Compute pixel checksum"), &m_checksum)
      70         239 :         .SetCategory(GAAC_ADVANCED);
      71             :     AddArg("list-mdd", 0,
      72         478 :            _("List all metadata domains available for the dataset"), &m_listMDD)
      73         478 :         .AddAlias("list-metadata-domains")
      74         239 :         .SetCategory(GAAC_ADVANCED);
      75             :     AddArg("metadata-domain", 0,
      76             :            _("Report metadata for the specified domain. 'all' can be used to "
      77             :              "report metadata in all domains"),
      78         478 :            &m_mdd)
      79         478 :         .AddAlias("mdd")
      80         239 :         .SetCategory(GAAC_ADVANCED);
      81             : 
      82         478 :     AddArg("no-nodata", 0, _("Suppress retrieving nodata value"), &m_noNodata)
      83         239 :         .SetCategory(GAAC_ESOTERIC);
      84         478 :     AddArg("no-mask", 0, _("Suppress mask band information"), &m_noMask)
      85         239 :         .SetCategory(GAAC_ESOTERIC);
      86             :     AddArg("subdataset", 0,
      87             :            _("Use subdataset of specified index (starting at 1), instead of "
      88             :              "the source dataset itself"),
      89         478 :            &m_subDS)
      90         478 :         .SetCategory(GAAC_ESOTERIC)
      91         239 :         .SetMinValueIncluded(1);
      92             :     AddArg("crs-format", 0, _("Which format to use to report CRS"),
      93         478 :            &m_crsFormat)
      94         239 :         .SetChoices("AUTO", "WKT2", "PROJJSON")
      95         239 :         .SetDefault(m_crsFormat)
      96         239 :         .SetCategory(GAAC_ESOTERIC);
      97             : 
      98         239 :     AddOutputStringArg(&m_output);
      99         239 :     AddStdoutArg(&m_stdout);
     100             : 
     101         239 :     AddValidationAction(
     102          75 :         [this]()
     103             :         {
     104          75 :             if (m_crsFormat != "AUTO" && m_format == "json")
     105             :             {
     106           0 :                 ReportError(CE_Failure, CPLE_AppDefined,
     107             :                             "'crs-format' cannot be set when 'format' is set "
     108             :                             "to 'json'");
     109           0 :                 return false;
     110             :             }
     111          75 :             return true;
     112             :         });
     113         239 : }
     114             : 
     115             : /************************************************************************/
     116             : /*                  GDALRasterInfoAlgorithm::RunStep()                  */
     117             : /************************************************************************/
     118             : 
     119          34 : bool GDALRasterInfoAlgorithm::RunStep(GDALPipelineStepRunContext &)
     120             : {
     121          34 :     CPLAssert(m_inputDataset.size() == 1);
     122          34 :     auto poSrcDS = m_inputDataset[0].GetDatasetRef();
     123          34 :     CPLAssert(poSrcDS);
     124             : 
     125          34 :     if (m_format.empty())
     126          28 :         m_format = IsCalledFromCommandLine() ? "text" : "json";
     127             : 
     128          68 :     CPLStringList aosOptions;
     129          34 :     aosOptions.AddString("--invoked-from=gdal-raster-info");
     130          34 :     aosOptions.AddString("--crs-format=" + m_crsFormat);
     131          34 :     if (m_format == "json")
     132          24 :         aosOptions.AddString("-json");
     133          34 :     if (m_minMax)
     134           1 :         aosOptions.AddString("-mm");
     135          34 :     if (m_stats)
     136           2 :         aosOptions.AddString("-stats");
     137          34 :     if (m_approxStats)
     138           1 :         aosOptions.AddString("-approx_stats");
     139          34 :     if (m_hist)
     140           1 :         aosOptions.AddString("-hist");
     141          34 :     if (m_noGCP)
     142           1 :         aosOptions.AddString("-nogcp");
     143          34 :     if (m_noMD)
     144           1 :         aosOptions.AddString("-nomd");
     145          34 :     if (m_noCT)
     146           1 :         aosOptions.AddString("-noct");
     147          34 :     if (m_noFL)
     148           1 :         aosOptions.AddString("-nofl");
     149          34 :     if (m_noMask)
     150           1 :         aosOptions.AddString("-nomask");
     151          34 :     if (m_noNodata)
     152           1 :         aosOptions.AddString("-nonodata");
     153          34 :     if (m_checksum)
     154           2 :         aosOptions.AddString("-checksum");
     155          34 :     if (m_listMDD)
     156           1 :         aosOptions.AddString("-listmdd");
     157          34 :     if (!m_mdd.empty())
     158             :     {
     159           1 :         aosOptions.AddString("-mdd");
     160           1 :         aosOptions.AddString(m_mdd.c_str());
     161             :     }
     162             : 
     163          34 :     GDALDatasetH hDS = GDALDataset::ToHandle(poSrcDS);
     164          34 :     std::unique_ptr<GDALDataset> poSubDataset;
     165             : 
     166          34 :     if (m_subDS > 0)
     167             :     {
     168             :         CSLConstList papszSubdatasets =
     169           3 :             GDALGetMetadata(hDS, GDAL_MDD_SUBDATASETS);
     170           3 :         const int nSubdatasets = CSLCount(papszSubdatasets) / 2;
     171           3 :         if (m_subDS > nSubdatasets)
     172             :         {
     173           1 :             CPLError(CE_Failure, CPLE_AppDefined,
     174             :                      "Invalid value for 'subdataset' argument. Should be "
     175             :                      "between 1 and %d",
     176             :                      nSubdatasets);
     177           2 :             return false;
     178             :         }
     179             : 
     180             :         char szKeyName[64];
     181           2 :         snprintf(szKeyName, sizeof(szKeyName), "SUBDATASET_%d_NAME", m_subDS);
     182             :         const std::string osSubDSName =
     183           2 :             CSLFetchNameValueDef(papszSubdatasets, szKeyName, "");
     184             : 
     185           2 :         poSubDataset.reset(GDALDataset::Open(
     186             :             osSubDSName.c_str(), GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR,
     187             :             nullptr, nullptr, nullptr));
     188           2 :         if (!poSubDataset)
     189           1 :             return false;
     190           1 :         hDS = GDALDataset::ToHandle(poSubDataset.get());
     191             :     }
     192             : 
     193          32 :     if (m_stdout)
     194             :     {
     195           7 :         aosOptions.AddString("-stdout");
     196             :     }
     197             : 
     198          32 :     GDALInfoOptions *psOptions = GDALInfoOptionsNew(aosOptions.List(), nullptr);
     199          32 :     char *ret = GDALInfo(hDS, psOptions);
     200          32 :     GDALInfoOptionsFree(psOptions);
     201          32 :     const bool bOK = ret != nullptr;
     202          32 :     if (ret)
     203             :     {
     204          32 :         m_output = ret;
     205             :     }
     206          32 :     CPLFree(ret);
     207             : 
     208          32 :     return bOK;
     209             : }
     210             : 
     211             : GDALRasterInfoAlgorithmStandalone::~GDALRasterInfoAlgorithmStandalone() =
     212             :     default;
     213             : 
     214             : //! @endcond

Generated by: LCOV version 1.14