#include "ogr_srs_api.h"
#include "cpl_multiproc.h"
#include "commonutils.h"
CPL_CVSID("$Id: gdalinfo.c 27044 2014-03-16 23:41:27Z rouault $");
static int
OGRCoordinateTransformationH hTransform,
const char * corner_name,
double x, double y );
void Usage(const char* pszErrorMsg)
{
printf( "Usage: gdalinfo [--help-general] [-mm] [-stats] [-hist] [-nogcp] [-nomd]\n"
" [-norat] [-noct] [-nofl] [-checksum] [-proj4]\n"
" [-listmdd] [-mdd domain|`all`]*\n"
" [-sd subdataset] datasetname\n" );
if( pszErrorMsg != NULL )
fprintf(stderr, "\nFAILURE: %s\n", pszErrorMsg);
exit( 1 );
}
#define CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(nExtraArg) \
do { if (i + nExtraArg >= argc) \
Usage(CPLSPrintf("%s option requires %d argument(s)", argv[i], nExtraArg)); } while(0)
int main( int argc, char ** argv )
{
int i, iBand;
double adfGeoTransform[6];
char **papszMetadata;
int bComputeMinMax = FALSE, bSample = FALSE;
int bShowGCPs = TRUE, bShowMetadata = TRUE, bShowRAT=TRUE;
int bStats = FALSE, bApproxStats = TRUE, iMDD;
int bShowColorTable = TRUE, bComputeChecksum = FALSE;
int bReportHistograms = FALSE;
int bReportProj4 = FALSE;
int nSubdataset = -1;
const char *pszFilename = NULL;
char **papszExtraMDDomains = NULL, **papszFileList;
int bListMDD = FALSE;
const char *pszProjection = NULL;
OGRCoordinateTransformationH hTransform = NULL;
int bShowFileList = TRUE;
{
fprintf(stderr, "At least, GDAL >= 1.5.0 is required for this version of %s, "
"which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME);
exit(1);
}
EarlySetConfigOptions(argc, argv);
if( argc < 1 )
exit( -argc );
for( i = 1; i < argc; i++ )
{
if( EQUAL(argv[i], "--utility_version") )
{
printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
return 0;
}
else if( EQUAL(argv[i],"--help") )
Usage(NULL);
else if( EQUAL(argv[i], "-mm") )
bComputeMinMax = TRUE;
else if( EQUAL(argv[i], "-hist") )
bReportHistograms = TRUE;
else if( EQUAL(argv[i], "-proj4") )
bReportProj4 = TRUE;
else if( EQUAL(argv[i], "-stats") )
{
bStats = TRUE;
bApproxStats = FALSE;
}
else if( EQUAL(argv[i], "-approx_stats") )
{
bStats = TRUE;
bApproxStats = TRUE;
}
else if( EQUAL(argv[i], "-sample") )
bSample = TRUE;
else if( EQUAL(argv[i], "-checksum") )
bComputeChecksum = TRUE;
else if( EQUAL(argv[i], "-nogcp") )
bShowGCPs = FALSE;
else if( EQUAL(argv[i], "-nomd") )
bShowMetadata = FALSE;
else if( EQUAL(argv[i], "-norat") )
bShowRAT = FALSE;
else if( EQUAL(argv[i], "-noct") )
bShowColorTable = FALSE;
else if( EQUAL(argv[i], "-listmdd") )
bListMDD = TRUE;
else if( EQUAL(argv[i], "-mdd") )
{
CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
papszExtraMDDomains = CSLAddString( papszExtraMDDomains,
argv[++i] );
}
else if( EQUAL(argv[i], "-nofl") )
bShowFileList = FALSE;
else if( EQUAL(argv[i], "-sd") )
{
CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
nSubdataset = atoi(argv[++i]);
}
else if( argv[i][0] == '-' )
Usage(CPLSPrintf("Unknown option name '%s'", argv[i]));
else if( pszFilename == NULL )
pszFilename = argv[i];
else
Usage("Too many command options.");
}
if( pszFilename == NULL )
Usage("No datasource specified.");
if( hDataset == NULL )
{
fprintf( stderr,
"gdalinfo failed - unable to open '%s'.\n",
pszFilename );
if ( strncmp( pszFilename, "/vsizip/", 8 ) == 0 ||
strncmp( pszFilename, "/vsitar/", 8 ) == 0 )
{
if ( papszFileList )
{
fprintf( stdout,
"Unable to open source `%s' directly.\n"
"The archive contains %d files:\n",
pszFilename, nCount );
for ( i = 0; i < nCount; i++ )
{
fprintf( stdout, " %s/%s\n", pszFilename, papszFileList[i] );
}
papszFileList = NULL;
}
}
exit( 1 );
}
if ( nSubdataset > 0 )
{
int nSubdatasets =
CSLCount( papszSubdatasets );
if ( nSubdatasets > 0 && nSubdataset <= nSubdatasets )
{
char szKeyName[1024];
char *pszSubdatasetName;
snprintf( szKeyName, sizeof(szKeyName),
"SUBDATASET_%d_NAME", nSubdataset );
szKeyName[sizeof(szKeyName) - 1] = '\0';
pszSubdatasetName =
CPLStrdup( CSLFetchNameValue( papszSubdatasets, szKeyName ) );
CPLFree( pszSubdatasetName );
}
else
{
fprintf( stderr,
"gdalinfo warning: subdataset %d of %d requested. "
"Reading the main dataset.\n",
nSubdataset, nSubdatasets );
}
}
printf( "Driver: %s/%s\n",
{
printf( "Files: none associated\n" );
}
else
{
printf( "Files: %s\n", papszFileList[0] );
if( bShowFileList )
{
for( i = 1; papszFileList[i] != NULL; i++ )
printf( " %s\n", papszFileList[i] );
}
}
printf( "Size is %d, %d\n",
{
OGRSpatialReferenceH hSRS;
char *pszProjection;
hSRS = OSRNewSpatialReference(NULL);
if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None )
{
char *pszPrettyWkt = NULL;
OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE );
printf( "Coordinate System is:\n%s\n", pszPrettyWkt );
CPLFree( pszPrettyWkt );
}
else
printf( "Coordinate System is `%s'\n",
if ( bReportProj4 )
{
char *pszProj4 = NULL;
OSRExportToProj4( hSRS, &pszProj4 );
printf("PROJ.4 string is:\n\'%s\'\n",pszProj4);
CPLFree( pszProj4 );
}
OSRDestroySpatialReference( hSRS );
}
{
if( adfGeoTransform[2] == 0.0 && adfGeoTransform[4] == 0.0 )
{
printf( "Origin = (%.15f,%.15f)\n",
adfGeoTransform[0], adfGeoTransform[3] );
printf( "Pixel Size = (%.15f,%.15f)\n",
adfGeoTransform[1], adfGeoTransform[5] );
}
else
printf( "GeoTransform =\n"
" %.16g, %.16g, %.16g\n"
" %.16g, %.16g, %.16g\n",
adfGeoTransform[0],
adfGeoTransform[1],
adfGeoTransform[2],
adfGeoTransform[3],
adfGeoTransform[4],
adfGeoTransform[5] );
}
{
{
OGRSpatialReferenceH hSRS;
char *pszProjection;
hSRS = OSRNewSpatialReference(NULL);
if( OSRImportFromWkt( hSRS, &pszProjection ) == CE_None )
{
char *pszPrettyWkt = NULL;
OSRExportToPrettyWkt( hSRS, &pszPrettyWkt, FALSE );
printf( "GCP Projection = \n%s\n", pszPrettyWkt );
CPLFree( pszPrettyWkt );
}
else
printf( "GCP Projection = %s\n",
OSRDestroySpatialReference( hSRS );
}
{
printf( "GCP[%3d]: Id=%s, Info=%s\n"
" (%.15g,%.15g) -> (%.15g,%.15g,%.15g)\n",
}
}
if( bListMDD )
{
char** papszIter = papszMDDList;
if( papszMDDList != NULL )
printf( "Metadata domains:\n" );
while( papszIter != NULL && *papszIter != NULL )
{
if( EQUAL(*papszIter, "") )
printf( " (default)\n");
else
printf( " %s\n", *papszIter );
papszIter ++;
}
}
papszMetadata = (bShowMetadata) ?
GDALGetMetadata( hDataset, NULL ) : NULL;
if( bShowMetadata &&
CSLCount(papszMetadata) > 0 )
{
printf( "Metadata:\n" );
for( i = 0; papszMetadata[i] != NULL; i++ )
{
printf( " %s\n", papszMetadata[i] );
}
}
if( papszExtraMDDomains != NULL && EQUAL(papszExtraMDDomains[0], "all") &&
papszExtraMDDomains[1] == NULL )
{
char** papszIter = papszMDDList;
papszExtraMDDomains = NULL;
while( papszIter != NULL && *papszIter != NULL )
{
if( !EQUAL(*papszIter, "") &&
!EQUAL(*papszIter, "IMAGE_STRUCTURE") &&
!EQUAL(*papszIter, "SUBDATASETS") &&
!EQUAL(*papszIter, "GEOLOCATION") &&
!EQUAL(*papszIter, "RPC") )
{
papszExtraMDDomains = CSLAddString(papszExtraMDDomains, *papszIter);
}
papszIter ++;
}
}
for( iMDD = 0; bShowMetadata && iMDD <
CSLCount(papszExtraMDDomains); iMDD++ )
{
{
printf( "Metadata (%s):\n", papszExtraMDDomains[iMDD]);
for( i = 0; papszMetadata[i] != NULL; i++ )
{
if (EQUALN(papszExtraMDDomains[iMDD], "xml:", 4))
printf( "%s\n", papszMetadata[i] );
else
printf( " %s\n", papszMetadata[i] );
}
}
}
papszMetadata = (bShowMetadata) ?
GDALGetMetadata( hDataset,
"IMAGE_STRUCTURE" ) : NULL;
if( bShowMetadata &&
CSLCount(papszMetadata) > 0 )
{
printf( "Image Structure Metadata:\n" );
for( i = 0; papszMetadata[i] != NULL; i++ )
{
printf( " %s\n", papszMetadata[i] );
}
}
{
printf( "Subdatasets:\n" );
for( i = 0; papszMetadata[i] != NULL; i++ )
{
printf( " %s\n", papszMetadata[i] );
}
}
papszMetadata = (bShowMetadata) ?
GDALGetMetadata( hDataset,
"GEOLOCATION" ) : NULL;
if( bShowMetadata &&
CSLCount(papszMetadata) > 0 )
{
printf( "Geolocation:\n" );
for( i = 0; papszMetadata[i] != NULL; i++ )
{
printf( " %s\n", papszMetadata[i] );
}
}
papszMetadata = (bShowMetadata) ?
GDALGetMetadata( hDataset,
"RPC" ) : NULL;
if( bShowMetadata &&
CSLCount(papszMetadata) > 0 )
{
printf( "RPC Metadata:\n" );
for( i = 0; papszMetadata[i] != NULL; i++ )
{
printf( " %s\n", papszMetadata[i] );
}
}
if( pszProjection != NULL && strlen(pszProjection) > 0 )
{
OGRSpatialReferenceH hProj, hLatLong = NULL;
hProj = OSRNewSpatialReference( pszProjection );
if( hProj != NULL )
hLatLong = OSRCloneGeogCS( hProj );
if( hLatLong != NULL )
{
hTransform = OCTNewCoordinateTransformation( hProj, hLatLong );
OSRDestroySpatialReference( hLatLong );
}
if( hProj != NULL )
OSRDestroySpatialReference( hProj );
}
printf( "Corner Coordinates:\n" );
GDALInfoReportCorner( hDataset, hTransform, "Upper Left",
0.0, 0.0 );
GDALInfoReportCorner( hDataset, hTransform, "Lower Left",
GDALInfoReportCorner( hDataset, hTransform, "Upper Right",
GDALInfoReportCorner( hDataset, hTransform, "Lower Right",
GDALInfoReportCorner( hDataset, hTransform, "Center",
if( hTransform != NULL )
{
OCTDestroyCoordinateTransformation( hTransform );
hTransform = NULL;
}
{
double dfMin, dfMax, adfCMinMax[2], dfNoData;
int bGotMin, bGotMax, bGotNodata, bSuccess;
int nBlockXSize, nBlockYSize, nMaskFlags;
double dfMean, dfStdDev;
CPLErr eErr;
if( bSample )
{
float afSample[10000];
int nCount;
nCount = GDALGetRandomRasterSample( hBand, 10000, afSample );
printf( "Got %d samples.\n", nCount );
}
printf( "Band %d Block=%dx%d Type=%s, ColorInterp=%s\n", iBand+1,
nBlockXSize, nBlockYSize,
if( bGotMin || bGotMax || bComputeMinMax )
{
printf( " " );
if( bGotMin )
printf( "Min=%.3f ", dfMin );
if( bGotMax )
printf( "Max=%.3f ", dfMax );
if( bComputeMinMax )
{
{
printf( " Computed Min/Max=%.3f,%.3f",
adfCMinMax[0], adfCMinMax[1] );
}
}
printf( "\n" );
}
&dfMin, &dfMax, &dfMean, &dfStdDev );
if( eErr == CE_None )
{
printf( " Minimum=%.3f, Maximum=%.3f, Mean=%.3f, StdDev=%.3f\n",
dfMin, dfMax, dfMean, dfStdDev );
}
if( bReportHistograms )
{
int nBucketCount, *panHistogram = NULL;
&nBucketCount, &panHistogram,
TRUE, GDALTermProgress, NULL );
if( eErr == CE_None )
{
int iBucket;
printf( " %d buckets from %g to %g:\n ",
nBucketCount, dfMin, dfMax );
for( iBucket = 0; iBucket < nBucketCount; iBucket++ )
printf( "%d ", panHistogram[iBucket] );
printf( "\n" );
CPLFree( panHistogram );
}
}
if ( bComputeChecksum)
{
printf( " Checksum=%d\n",
}
if( bGotNodata )
{
if (CPLIsNan(dfNoData))
printf( " NoData Value=nan\n" );
else
printf( " NoData Value=%.18g\n", dfNoData );
}
{
int iOverview;
printf( " Overviews: " );
for( iOverview = 0;
iOverview++ )
{
const char *pszResampling = NULL;
if( iOverview != 0 )
printf( ", " );
if (hOverview != NULL)
{
printf( "%dx%d",
pszResampling =
if( pszResampling != NULL
&& EQUALN(pszResampling,"AVERAGE_BIT2",12) )
printf( "*" );
}
else
printf( "(null)" );
}
printf( "\n" );
if ( bComputeChecksum)
{
printf( " Overviews checksum: " );
for( iOverview = 0;
iOverview++ )
{
if( iOverview != 0 )
printf( ", " );
if (hOverview)
printf( "%d",
else
printf( "(null)" );
}
printf( "\n" );
}
}
{
printf( " Overviews: arbitrary\n" );
}
if( (nMaskFlags & (GMF_NODATA|GMF_ALL_VALID)) == 0 )
{
printf( " Mask Flags: " );
if( nMaskFlags & GMF_PER_DATASET )
printf( "PER_DATASET " );
if( nMaskFlags & GMF_ALPHA )
printf( "ALPHA " );
if( nMaskFlags & GMF_NODATA )
printf( "NODATA " );
if( nMaskFlags & GMF_ALL_VALID )
printf( "ALL_VALID " );
printf( "\n" );
if( hMaskBand != NULL &&
{
int iOverview;
printf( " Overviews of mask band: " );
for( iOverview = 0;
iOverview++ )
{
if( iOverview != 0 )
printf( ", " );
printf( "%dx%d",
}
printf( "\n" );
}
}
{
}
{
int i;
printf( " Categories:\n" );
for( i = 0; papszCategories[i] != NULL; i++ )
printf( " %3d: %s\n", i, papszCategories[i] );
}
printf( " Offset: %.15g, Scale:%.15g\n",
if( bListMDD )
{
char** papszIter = papszMDDList;
if( papszMDDList != NULL )
printf( " Metadata domains:\n" );
while( papszIter != NULL && *papszIter != NULL )
{
if( EQUAL(*papszIter, "") )
printf( " (default)\n");
else
printf( " %s\n", *papszIter );
papszIter ++;
}
}
if( bShowMetadata &&
CSLCount(papszMetadata) > 0 )
{
printf( " Metadata:\n" );
for( i = 0; papszMetadata[i] != NULL; i++ )
{
printf( " %s\n", papszMetadata[i] );
}
}
papszMetadata = (bShowMetadata) ?
GDALGetMetadata( hBand,
"IMAGE_STRUCTURE" ) : NULL;
if( bShowMetadata &&
CSLCount(papszMetadata) > 0 )
{
printf( " Image Structure Metadata:\n" );
for( i = 0; papszMetadata[i] != NULL; i++ )
{
printf( " %s\n", papszMetadata[i] );
}
}
{
int i;
printf( " Color Table (%s with %d entries)\n",
if (bShowColorTable)
{
{
printf( " %3d: %d,%d,%d,%d\n",
i,
}
}
}
{
}
}
CPLCleanupTLS();
exit( 0 );
}
static int
OGRCoordinateTransformationH hTransform,
const char * corner_name,
double x, double y )
{
double dfGeoX, dfGeoY;
double adfGeoTransform[6];
printf( "%-11s ", corner_name );
{
dfGeoX = adfGeoTransform[0] + adfGeoTransform[1] * x
+ adfGeoTransform[2] * y;
dfGeoY = adfGeoTransform[3] + adfGeoTransform[4] * x
+ adfGeoTransform[5] * y;
}
else
{
printf( "(%7.1f,%7.1f)\n", x, y );
return FALSE;
}
if( ABS(dfGeoX) < 181 && ABS(dfGeoY) < 91 )
{
printf( "(%12.7f,%12.7f) ", dfGeoX, dfGeoY );
}
else
{
printf( "(%12.3f,%12.3f) ", dfGeoX, dfGeoY );
}
if( hTransform != NULL
&& OCTTransform(hTransform,1,&dfGeoX,&dfGeoY,NULL) )
{
printf( "(%s,", GDALDecToDMS( dfGeoX, "Long", 2 ) );
printf( "%s)", GDALDecToDMS( dfGeoY, "Lat", 2 ) );
}
printf( "\n" );
return TRUE;
}