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