1 /******************************************************************************
2 *
3 * Project: GDAL Utilities
4 * Purpose: Command line utility to torture GDAL API on datasets
5 * Author: Even Rouault, <even dot rouault at spatialys.com>
6 *
7 ******************************************************************************
8 * Copyright (c) 2008-2011, Even Rouault <even dot rouault at spatialys.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 ****************************************************************************/
28
29 #include "gdal.h"
30 #include "cpl_string.h"
31 #include "cpl_conv.h"
32
33 #include <cassert>
34
35 CPL_CVSID("$Id: gdaltorture.cpp 355b41831cd2685c85d1aabe5b95665a2c6e99b7 2019-06-19 17:07:04 +0200 Even Rouault $")
36
37 /************************************************************************/
38 /* Usage() */
39 /************************************************************************/
40
Usage()41 static void Usage()
42
43 {
44 printf("Usage: gdaltorture [-r] [-u] [-rw] files*\n");
45 exit(1);
46 }
47
48 /************************************************************************/
49 /* TortureDS() */
50 /************************************************************************/
51
TortureBand(GDALRasterBandH hBand,int,int nRecurse)52 static void TortureBand( GDALRasterBandH hBand, int /* bReadWriteOperations */,
53 int nRecurse )
54 {
55 if( nRecurse > 5 )
56 return;
57
58 GDALGetRasterDataType(hBand);
59 int nBlockXSize;
60 int nBlockYSize;
61 GDALGetBlockSize(hBand, &nBlockXSize, &nBlockYSize);
62 // GDALRasterAdviseRead
63 // GDALRasterIO
64 // GDALReadBlock
65 // GDALWriteBlock
66 const int nRasterXSize = GDALGetRasterBandXSize(hBand);
67 assert(nRasterXSize >= 0);
68 const int nRasterYSize = GDALGetRasterBandYSize(hBand);
69 assert(nRasterYSize >= 0);
70 GDALGetRasterAccess(hBand);
71 GDALGetBandNumber(hBand);
72 GDALGetBandDataset(hBand);
73 GDALGetRasterColorInterpretation(hBand);
74 // GDALSetRasterColorInterpretation
75 GDALGetRasterColorTable(hBand);
76 // GDALSetRasterColorTable
77 GDALHasArbitraryOverviews (hBand);
78
79 const int nOverviewCount = GDALGetOverviewCount(hBand);
80 for(int iOverview=0;iOverview<nOverviewCount;iOverview++)
81 {
82 GDALRasterBandH hOverviewBand = GDALGetOverview(hBand, iOverview);
83 if( hOverviewBand )
84 TortureBand(hOverviewBand, false, nRecurse + 1);
85 }
86
87 int bHasNoData;
88 GDALGetRasterNoDataValue(hBand, &bHasNoData);
89 // GDALSetRasterNoDataValue
90 GDALGetRasterCategoryNames(hBand);
91 // GDALSetRasterCategoryNames
92 int bSuccess;
93 GDALGetRasterMinimum(hBand, &bSuccess);
94 GDALGetRasterMaximum(hBand, &bSuccess);
95 double dfMin, dfMax, dfMean, dfStdDev;
96 GDALGetRasterStatistics(hBand, TRUE, FALSE, &dfMin, &dfMax,
97 &dfMean, &dfStdDev);
98 // GDALComputeRasterStatistics
99 // GDALSetRasterStatistics
100 GDALGetRasterUnitType(hBand);
101 GDALGetRasterOffset(hBand, &bSuccess);
102 // GDALSetRasterOffset
103 GDALGetRasterScale(hBand, &bSuccess);
104 // GDALSetRasterScale
105 // double adfMinMax[2];
106 // GDALComputeRasterMinMax(hBand, TRUE, adfMinMax);
107 // GDALFlushRasterCache(hBand)
108 // GDALGetDefaultHistogram(
109 // GDALRasterBandH hBand, double *pdfMin, double *pdfMax,
110 // int *pnBuckets, int **ppanHistogram, int bForce,
111 // GDALProgressFunc pfnProgress, void *pProgressData);
112 // GDALSetDefaultHistogram(
113 // GDALRasterBandH hBand, double dfMin, double dfMax,
114 // int nBuckets, int *panHistogram);
115 float afSampleBuf;
116 GDALGetRandomRasterSample(hBand, 1, &afSampleBuf);
117 GDALGetRasterSampleOverview(hBand, 0); // returns a hBand
118 // GDALFillRaster
119 // GDALComputeBandStats
120 // GDALOverviewMagnitudeCorrection
121 GDALGetDefaultRAT(hBand);
122 // GDALSetDefaultRAT
123 // GDALAddDerivedBandPixelFunc
124 GDALRasterBandH hMaskBand = GDALGetMaskBand(hBand);
125 if( hMaskBand != hBand )
126 TortureBand(hMaskBand, false, nRecurse + 1);
127 GDALGetMaskFlags(hBand);
128 // GDALCreateMaskBand
129 }
130
131 /************************************************************************/
132 /* TortureDS() */
133 /************************************************************************/
134
TortureDS(const char * pszTarget,bool bReadWriteOperations)135 static void TortureDS( const char *pszTarget, bool bReadWriteOperations )
136 {
137 // hDS = GDALOpen(pszTarget, GA_Update);
138 // GDALClose(hDS);
139
140 GDALDatasetH hDS = GDALOpen(pszTarget, GA_ReadOnly);
141 if( hDS == nullptr )
142 return;
143
144 // GDALGetMetadata(GDALMajorObjectH, const char *);
145 // GDALSetMetadata(GDALMajorObjectH, char **, const char *);
146 // GDALGetMetadataItem(GDALMajorObjectH, const char *, const char *);
147 // GDALSetMetadataItem(GDALMajorObjectH, const char *, const char *,
148 // const char *);
149 GDALGetDescription(hDS);
150 //GDALSetDescription
151 GDALGetDatasetDriver(hDS);
152 char **papszFileList = GDALGetFileList(hDS);
153 CSLDestroy(papszFileList);
154 const int nXSize = GDALGetRasterXSize(hDS);
155 assert(nXSize >= 0);
156 const int nYSize = GDALGetRasterYSize(hDS);
157 assert(nYSize >= 0);
158 const int nBands = GDALGetRasterCount(hDS);
159 // GDALAddBand
160 // GDALDatasetRasterIO
161 GDALGetProjectionRef(hDS);
162 // GDALSetProjection
163 double adfGeotransform[6] = {};
164 GDALGetGeoTransform(hDS, adfGeotransform);
165 // GDALSetGeoTransform
166 GDALGetGCPCount(hDS);
167 GDALGetGCPProjection(hDS);
168 GDALGetGCPs(hDS);
169 // GDALSetGCPs
170 // GDALGetInternalHandle
171 GDALReferenceDataset(hDS);
172 GDALDereferenceDataset(hDS);
173 // GDALBuildOverviews
174 GDALGetAccess(hDS);
175 // GDALFlushCache
176 // GDALCreateDatasetMaskBand
177 // GDALDatasetCopyWholeRaster
178
179 for( int iBand = 0; iBand < nBands; iBand++ )
180 {
181 GDALRasterBandH hBand = GDALGetRasterBand(hDS, iBand + 1);
182 if( hBand == nullptr )
183 continue;
184
185 TortureBand(hBand, bReadWriteOperations, 0);
186 }
187
188 GDALClose(hDS);
189 }
190
191 /************************************************************************/
192 /* ProcessTortureTarget() */
193 /************************************************************************/
194
ProcessTortureTarget(const char * pszTarget,char ** papszSiblingList,bool bRecursive,bool bReportFailures,bool bReadWriteOperations)195 static void ProcessTortureTarget( const char *pszTarget,
196 char **papszSiblingList,
197 bool bRecursive, bool bReportFailures,
198 bool bReadWriteOperations )
199 {
200 GDALDriverH hDriver = GDALIdentifyDriver(pszTarget, papszSiblingList);
201
202 if( hDriver != nullptr )
203 {
204 printf("%s: %s\n", pszTarget, GDALGetDriverShortName(hDriver));
205 TortureDS(pszTarget, bReadWriteOperations);
206 }
207 else if( bReportFailures )
208 {
209 printf("%s: unrecognized\n", pszTarget);
210 }
211
212 if( !bRecursive || hDriver != nullptr )
213 return;
214
215 VSIStatBufL sStatBuf;
216 if( VSIStatL(pszTarget, &sStatBuf) != 0 ||
217 !VSI_ISDIR(sStatBuf.st_mode) )
218 return;
219
220 papszSiblingList = VSIReadDir(pszTarget);
221 for( int i = 0; papszSiblingList && papszSiblingList[i]; i++ )
222 {
223 if( EQUAL(papszSiblingList[i],"..") ||
224 EQUAL(papszSiblingList[i],".") )
225 continue;
226
227 const CPLString osSubTarget =
228 CPLFormFilename(pszTarget, papszSiblingList[i], nullptr);
229
230 ProcessTortureTarget(osSubTarget, papszSiblingList,
231 bRecursive, bReportFailures, bReadWriteOperations);
232 }
233 CSLDestroy(papszSiblingList);
234 }
235
236 /************************************************************************/
237 /* main() */
238 /************************************************************************/
239
main(int argc,char ** argv)240 int main( int argc, char **argv )
241 {
242 GDALAllRegister();
243
244 argc = GDALGeneralCmdLineProcessor(argc, &argv, 0);
245 if( argc < 1 )
246 exit(-argc);
247
248 if( argc < 2 )
249 Usage();
250
251 /* -------------------------------------------------------------------- */
252 /* Scan for command line switches */
253 /* -------------------------------------------------------------------- */
254 char** papszArgv = argv + 1;
255 argc--;
256
257 bool bRecursive = false;
258 bool bReportFailures = false;
259 bool bReadWriteOperations = false;
260
261 while( argc > 0 && papszArgv[0][0] == '-' )
262 {
263 if( EQUAL(papszArgv[0], "-r") )
264 bRecursive = true;
265 else if( EQUAL(papszArgv[0], "-u") )
266 bReportFailures = true;
267 else if( EQUAL(papszArgv[0], "-rw") )
268 bReadWriteOperations = true;
269 else
270 Usage();
271
272 papszArgv++;
273 argc--;
274 }
275
276 /* -------------------------------------------------------------------- */
277 /* Process given files. */
278 /* -------------------------------------------------------------------- */
279 while( argc > 0 )
280 {
281 ProcessTortureTarget(papszArgv[0], nullptr,
282 bRecursive, bReportFailures, bReadWriteOperations);
283 argc--;
284 papszArgv++;
285 }
286
287 /* -------------------------------------------------------------------- */
288 /* Cleanup */
289 /* -------------------------------------------------------------------- */
290 CSLDestroy(argv);
291 GDALDestroyDriverManager();
292
293 return 0;
294 }
295