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

Generated by: LCOV version 1.14