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