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