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 121 : GDALRasterInfoAlgorithm::GDALRasterInfoAlgorithm(bool standaloneStep,
30 121 : bool openForMixedRasterVector)
31 : : GDALRasterPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
32 0 : ConstructorOptions()
33 121 : .SetStandaloneStep(standaloneStep)
34 121 : .SetInputDatasetMaxCount(1)
35 121 : .SetAddDefaultArguments(false)
36 242 : .SetInputDatasetAlias("dataset"))
37 : {
38 121 : AddRasterInputArgs(openForMixedRasterVector, !standaloneStep);
39 :
40 121 : AddOutputFormatArg(&m_format).SetChoices("json", "text");
41 242 : AddArg("min-max", 0, _("Compute minimum and maximum value"), &m_minMax)
42 121 : .AddAlias("mm");
43 : AddArg("stats", 0, _("Retrieve or compute statistics, using all pixels"),
44 242 : &m_stats)
45 121 : .SetMutualExclusionGroup("stats");
46 : AddArg("approx-stats", 0,
47 : _("Retrieve or compute statistics, using a subset of pixels"),
48 242 : &m_approxStats)
49 121 : .SetMutualExclusionGroup("stats");
50 121 : AddArg("hist", 0, _("Retrieve or compute histogram"), &m_hist);
51 :
52 : AddArg("no-gcp", 0, _("Suppress ground control points list printing"),
53 242 : &m_noGCP)
54 121 : .SetCategory(GAAC_ADVANCED);
55 242 : AddArg("no-md", 0, _("Suppress metadata printing"), &m_noMD)
56 121 : .SetCategory(GAAC_ADVANCED);
57 242 : AddArg("no-ct", 0, _("Suppress color table printing"), &m_noCT)
58 121 : .SetCategory(GAAC_ADVANCED);
59 242 : AddArg("no-fl", 0, _("Suppress file list printing"), &m_noFL)
60 121 : .SetCategory(GAAC_ADVANCED);
61 242 : AddArg("checksum", 0, _("Compute pixel checksum"), &m_checksum)
62 121 : .SetCategory(GAAC_ADVANCED);
63 : AddArg("list-mdd", 0,
64 242 : _("List all metadata domains available for the dataset"), &m_listMDD)
65 242 : .AddAlias("list-metadata-domains")
66 121 : .SetCategory(GAAC_ADVANCED);
67 : AddArg("metadata-domain", 0,
68 : _("Report metadata for the specified domain. 'all' can be used to "
69 : "report metadata in all domains"),
70 242 : &m_mdd)
71 242 : .AddAlias("mdd")
72 121 : .SetCategory(GAAC_ADVANCED);
73 :
74 242 : AddArg("no-nodata", 0, _("Suppress retrieving nodata value"), &m_noNodata)
75 121 : .SetCategory(GAAC_ESOTERIC);
76 242 : AddArg("no-mask", 0, _("Suppress mask band information"), &m_noMask)
77 121 : .SetCategory(GAAC_ESOTERIC);
78 : AddArg("subdataset", 0,
79 : _("Use subdataset of specified index (starting at 1), instead of "
80 : "the source dataset itself"),
81 242 : &m_subDS)
82 242 : .SetCategory(GAAC_ESOTERIC)
83 121 : .SetMinValueIncluded(1);
84 :
85 121 : AddOutputStringArg(&m_output);
86 : AddArg("stdout", 0,
87 : _("Directly output on stdout (format=text mode only). If enabled, "
88 : "output-string will be empty"),
89 242 : &m_stdout)
90 121 : .SetHiddenForCLI();
91 121 : }
92 :
93 : /************************************************************************/
94 : /* GDALRasterInfoAlgorithm::RunStep() */
95 : /************************************************************************/
96 :
97 27 : bool GDALRasterInfoAlgorithm::RunStep(GDALPipelineStepRunContext &)
98 : {
99 27 : CPLAssert(m_inputDataset.size() == 1);
100 27 : auto poSrcDS = m_inputDataset[0].GetDatasetRef();
101 27 : CPLAssert(poSrcDS);
102 :
103 27 : if (m_format.empty())
104 22 : m_format = IsCalledFromCommandLine() ? "text" : "json";
105 :
106 54 : CPLStringList aosOptions;
107 27 : if (m_format == "json")
108 19 : aosOptions.AddString("-json");
109 27 : if (m_minMax)
110 1 : aosOptions.AddString("-mm");
111 27 : if (m_stats)
112 1 : aosOptions.AddString("-stats");
113 27 : if (m_approxStats)
114 1 : aosOptions.AddString("-approx_stats");
115 27 : if (m_hist)
116 1 : aosOptions.AddString("-hist");
117 27 : if (m_noGCP)
118 1 : aosOptions.AddString("-nogcp");
119 27 : if (m_noMD)
120 1 : aosOptions.AddString("-nomd");
121 27 : if (m_noCT)
122 1 : aosOptions.AddString("-noct");
123 27 : if (m_noFL)
124 1 : aosOptions.AddString("-nofl");
125 27 : if (m_noMask)
126 1 : aosOptions.AddString("-nomask");
127 27 : if (m_noNodata)
128 1 : aosOptions.AddString("-nonodata");
129 27 : if (m_checksum)
130 2 : aosOptions.AddString("-checksum");
131 27 : if (m_listMDD)
132 1 : aosOptions.AddString("-listmdd");
133 27 : if (!m_mdd.empty())
134 : {
135 1 : aosOptions.AddString("-mdd");
136 1 : aosOptions.AddString(m_mdd.c_str());
137 : }
138 :
139 27 : GDALDatasetH hDS = GDALDataset::ToHandle(poSrcDS);
140 27 : std::unique_ptr<GDALDataset> poSubDataset;
141 :
142 27 : if (m_subDS > 0)
143 : {
144 3 : char **papszSubdatasets = GDALGetMetadata(hDS, "SUBDATASETS");
145 3 : const int nSubdatasets = CSLCount(papszSubdatasets) / 2;
146 3 : if (m_subDS > nSubdatasets)
147 : {
148 1 : CPLError(CE_Failure, CPLE_AppDefined,
149 : "Invalid value for 'subdataset' argument. Should be "
150 : "between 1 and %d",
151 : nSubdatasets);
152 2 : return false;
153 : }
154 :
155 : char szKeyName[64];
156 2 : snprintf(szKeyName, sizeof(szKeyName), "SUBDATASET_%d_NAME", m_subDS);
157 : const std::string osSubDSName =
158 2 : CSLFetchNameValueDef(papszSubdatasets, szKeyName, "");
159 :
160 2 : poSubDataset.reset(GDALDataset::Open(
161 : osSubDSName.c_str(), GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR,
162 : nullptr, nullptr, nullptr));
163 2 : if (!poSubDataset)
164 1 : return false;
165 1 : hDS = GDALDataset::ToHandle(poSubDataset.get());
166 : }
167 :
168 25 : if (m_stdout)
169 : {
170 5 : aosOptions.AddString("-stdout");
171 : }
172 :
173 25 : GDALInfoOptions *psOptions = GDALInfoOptionsNew(aosOptions.List(), nullptr);
174 25 : char *ret = GDALInfo(hDS, psOptions);
175 25 : GDALInfoOptionsFree(psOptions);
176 25 : const bool bOK = ret != nullptr;
177 25 : if (ret)
178 : {
179 25 : m_output = ret;
180 : }
181 25 : CPLFree(ret);
182 :
183 25 : return bOK;
184 : }
185 :
186 : GDALRasterInfoAlgorithmStandalone::~GDALRasterInfoAlgorithmStandalone() =
187 : default;
188 :
189 : //! @endcond
|