LCOV - code coverage report
Current view: directory - apps - gdal_translate.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 451 295 65.4 %
Date: 2010-01-09 Functions: 5 3 60.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: gdal_translate.cpp 18419 2009-12-31 20:38:45Z warmerdam $
       3                 :  *
       4                 :  * Project:  GDAL Utilities
       5                 :  * Purpose:  GDAL Image Translator Program
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1998, 2002, Frank Warmerdam
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "cpl_vsi.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : #include "gdal_priv.h"
      34                 : #include "ogr_spatialref.h"
      35                 : #include "vrt/vrtdataset.h"
      36                 : 
      37                 : CPL_CVSID("$Id: gdal_translate.cpp 18419 2009-12-31 20:38:45Z warmerdam $");
      38                 : 
      39                 : static int ArgIsNumeric( const char * );
      40                 : static void AttachMetadata( GDALDatasetH, char ** );
      41                 : static int bSubCall = FALSE;
      42                 : 
      43                 : /*  ******************************************************************* */
      44                 : /*                               Usage()                                */
      45                 : /* ******************************************************************** */
      46                 : 
      47               0 : static void Usage()
      48                 : 
      49                 : {
      50                 :     int iDr;
      51                 :         
      52                 :     printf( "Usage: gdal_translate [--help-general]\n"
      53                 :             "       [-ot {Byte/Int16/UInt16/UInt32/Int32/Float32/Float64/\n"
      54                 :             "             CInt16/CInt32/CFloat32/CFloat64}] [-strict]\n"
      55                 :             "       [-of format] [-b band] [-expand {gray|rgb|rgba}]\n"
      56                 :             "       [-outsize xsize[%%] ysize[%%]]\n"
      57                 :             "       [-unscale] [-scale [src_min src_max [dst_min dst_max]]]\n"
      58                 :             "       [-srcwin xoff yoff xsize ysize] [-projwin ulx uly lrx lry]\n"
      59                 :             "       [-a_srs srs_def] [-a_ullr ulx uly lrx lry] [-a_nodata value]\n"
      60                 :             "       [-gcp pixel line easting northing [elevation]]*\n" 
      61                 :             "       [-mo \"META-TAG=VALUE\"]* [-q] [-sds]\n"
      62                 :             "       [-co \"NAME=VALUE\"]*\n"
      63               0 :             "       src_dataset dst_dataset\n\n" );
      64                 : 
      65               0 :     printf( "%s\n\n", GDALVersionInfo( "--version" ) );
      66               0 :     printf( "The following format drivers are configured and support output:\n" );
      67               0 :     for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ )
      68                 :     {
      69               0 :         GDALDriverH hDriver = GDALGetDriver(iDr);
      70                 :         
      71               0 :         if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL
      72                 :             || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY,
      73                 :                                     NULL ) != NULL )
      74                 :         {
      75                 :             printf( "  %s: %s\n",
      76                 :                     GDALGetDriverShortName( hDriver ),
      77               0 :                     GDALGetDriverLongName( hDriver ) );
      78                 :         }
      79                 :     }
      80               0 : }
      81                 : 
      82                 : /************************************************************************/
      83                 : /*                             ProxyMain()                              */
      84                 : /************************************************************************/
      85                 : 
      86              24 : static int ProxyMain( int argc, char ** argv )
      87                 : 
      88                 : {
      89                 :     GDALDatasetH  hDataset, hOutDS;
      90                 :     int     i;
      91                 :     int     nRasterXSize, nRasterYSize;
      92              24 :     const char    *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff";
      93                 :     GDALDriverH   hDriver;
      94              24 :     int     *panBandList = NULL, nBandCount = 0, bDefBands = TRUE;
      95                 :     double    adfGeoTransform[6];
      96              24 :     GDALDataType  eOutputType = GDT_Unknown;
      97              24 :     int     nOXSize = 0, nOYSize = 0;
      98              24 :     char    *pszOXSize=NULL, *pszOYSize=NULL;
      99              24 :     char                **papszCreateOptions = NULL;
     100              24 :     int                 anSrcWin[4], bStrict = FALSE;
     101                 :     const char          *pszProjection;
     102              24 :     int                 bScale = FALSE, bHaveScaleSrc = FALSE, bUnscale=FALSE;
     103              24 :     double          dfScaleSrcMin=0.0, dfScaleSrcMax=255.0;
     104              24 :     double              dfScaleDstMin=0.0, dfScaleDstMax=255.0;
     105                 :     double              dfULX, dfULY, dfLRX, dfLRY;
     106              24 :     char                **papszMetadataOptions = NULL;
     107              24 :     char                *pszOutputSRS = NULL;
     108              24 :     int                 bQuiet = FALSE, bGotBounds = FALSE;
     109              24 :     GDALProgressFunc    pfnProgress = GDALTermProgress;
     110              24 :     int                 nGCPCount = 0;
     111              24 :     GDAL_GCP            *pasGCPs = NULL;
     112              24 :     int                 iSrcFileArg = -1, iDstFileArg = -1;
     113              24 :     int                 bCopySubDatasets = FALSE;
     114              24 :     double              adfULLR[4] = { 0,0,0,0 };
     115              24 :     int                 bSetNoData = FALSE;
     116              24 :     double    dfNoDataReal = 0.0;
     117              24 :     int                 nRGBExpand = 0;
     118                 : 
     119                 : 
     120              24 :     anSrcWin[0] = 0;
     121              24 :     anSrcWin[1] = 0;
     122              24 :     anSrcWin[2] = 0;
     123              24 :     anSrcWin[3] = 0;
     124                 : 
     125              24 :     dfULX = dfULY = dfLRX = dfLRY = 0.0;
     126                 :     
     127                 :     /* Check strict compilation and runtime library version as we use C++ API */
     128              24 :     if (! GDAL_CHECK_VERSION(argv[0]))
     129               0 :         exit(1);
     130                 : 
     131                 : /* -------------------------------------------------------------------- */
     132                 : /*      Register standard GDAL drivers, and process generic GDAL        */
     133                 : /*      command options.                                                */
     134                 : /* -------------------------------------------------------------------- */
     135              24 :     GDALAllRegister();
     136              24 :     argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
     137              24 :     if( argc < 1 )
     138               0 :         exit( -argc );
     139                 : 
     140                 : /* -------------------------------------------------------------------- */
     141                 : /*      Handle command line arguments.                                  */
     142                 : /* -------------------------------------------------------------------- */
     143             103 :     for( i = 1; i < argc; i++ )
     144                 :     {
     145              80 :         if( EQUAL(argv[i], "--utility_version") )
     146                 :         {
     147                 :             printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
     148               1 :                    argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
     149               1 :             return 0;
     150                 :         }
     151              84 :         else if( EQUAL(argv[i],"-of") && i < argc-1 )
     152               5 :             pszFormat = argv[++i];
     153                 : 
     154              74 :         else if( EQUAL(argv[i],"-q") || EQUAL(argv[i],"-quiet") )
     155                 :         {
     156               0 :             bQuiet = TRUE;
     157               0 :             pfnProgress = GDALDummyProgress;
     158                 :         }
     159                 : 
     160              76 :         else if( EQUAL(argv[i],"-ot") && i < argc-1 )
     161                 :         {
     162                 :             int iType;
     163                 :             
     164              24 :             for( iType = 1; iType < GDT_TypeCount; iType++ )
     165                 :             {
     166              44 :                 if( GDALGetDataTypeName((GDALDataType)iType) != NULL
     167              22 :                     && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
     168                 :                              argv[i+1]) )
     169                 :                 {
     170               2 :                     eOutputType = (GDALDataType) iType;
     171                 :                 }
     172                 :             }
     173                 : 
     174               2 :             if( eOutputType == GDT_Unknown )
     175                 :             {
     176               0 :                 printf( "Unknown output pixel type: %s\n", argv[i+1] );
     177               0 :                 Usage();
     178               0 :                 GDALDestroyDriverManager();
     179               0 :                 exit( 2 );
     180                 :             }
     181               2 :             i++;
     182                 :         }
     183              75 :         else if( EQUAL(argv[i],"-b") && i < argc-1 )
     184                 :         {
     185               3 :             if( atoi(argv[i+1]) < 1 )
     186                 :             {
     187               0 :                 printf( "Unrecognizable band number (%s).\n", argv[i+1] );
     188               0 :                 Usage();
     189               0 :                 GDALDestroyDriverManager();
     190               0 :                 exit( 2 );
     191                 :             }
     192                 : 
     193               3 :             nBandCount++;
     194                 :             panBandList = (int *) 
     195               3 :                 CPLRealloc(panBandList, sizeof(int) * nBandCount);
     196               3 :             panBandList[nBandCount-1] = atoi(argv[++i]);
     197                 : 
     198               3 :             if( panBandList[nBandCount-1] != nBandCount )
     199               2 :                 bDefBands = FALSE;
     200                 :         }
     201              69 :         else if( EQUAL(argv[i],"-not_strict")  )
     202               0 :             bStrict = FALSE;
     203                 :             
     204              69 :         else if( EQUAL(argv[i],"-strict")  )
     205               0 :             bStrict = TRUE;
     206                 :             
     207              69 :         else if( EQUAL(argv[i],"-sds")  )
     208               2 :             bCopySubDatasets = TRUE;
     209                 :             
     210              75 :         else if( EQUAL(argv[i],"-gcp") && i < argc - 4 )
     211                 :         {
     212               8 :             char* endptr = NULL;
     213                 :             /* -gcp pixel line easting northing [elev] */
     214                 : 
     215               8 :             nGCPCount++;
     216                 :             pasGCPs = (GDAL_GCP *) 
     217               8 :                 CPLRealloc( pasGCPs, sizeof(GDAL_GCP) * nGCPCount );
     218               8 :             GDALInitGCPs( 1, pasGCPs + nGCPCount - 1 );
     219                 : 
     220               8 :             pasGCPs[nGCPCount-1].dfGCPPixel = atof(argv[++i]);
     221               8 :             pasGCPs[nGCPCount-1].dfGCPLine = atof(argv[++i]);
     222               8 :             pasGCPs[nGCPCount-1].dfGCPX = atof(argv[++i]);
     223               8 :             pasGCPs[nGCPCount-1].dfGCPY = atof(argv[++i]);
     224              24 :             if( argv[i+1] != NULL 
     225              16 :                 && (CPLStrtod(argv[i+1], &endptr) != 0.0 || argv[i+1][0] == '0') )
     226                 :             {
     227                 :                 /* Check that last argument is really a number and not a filename */
     228                 :                 /* looking like a number (see ticket #863) */
     229               2 :                 if (endptr && *endptr == 0)
     230               2 :                     pasGCPs[nGCPCount-1].dfGCPZ = atof(argv[++i]);
     231                 :             }
     232                 : 
     233                 :             /* should set id and info? */
     234                 :         }   
     235                 : 
     236              60 :         else if( EQUAL(argv[i],"-a_nodata") && i < argc - 1 )
     237                 :         {
     238               1 :             bSetNoData = TRUE;
     239               1 :             dfNoDataReal = atof(argv[i+1]);
     240               1 :             i += 1;
     241                 :         }   
     242                 : 
     243              59 :         else if( EQUAL(argv[i],"-a_ullr") && i < argc - 4 )
     244                 :         {
     245               1 :             adfULLR[0] = atof(argv[i+1]);
     246               1 :             adfULLR[1] = atof(argv[i+2]);
     247               1 :             adfULLR[2] = atof(argv[i+3]);
     248               1 :             adfULLR[3] = atof(argv[i+4]);
     249                 : 
     250               1 :             bGotBounds = TRUE;
     251                 :             
     252               1 :             i += 4;
     253                 :         }   
     254                 : 
     255              58 :         else if( EQUAL(argv[i],"-co") && i < argc-1 )
     256                 :         {
     257               1 :             papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] );
     258                 :         }   
     259                 : 
     260              56 :         else if( EQUAL(argv[i],"-scale") )
     261                 :         {
     262               0 :             bScale = TRUE;
     263               0 :             if( i < argc-2 && ArgIsNumeric(argv[i+1]) )
     264                 :             {
     265               0 :                 bHaveScaleSrc = TRUE;
     266               0 :                 dfScaleSrcMin = atof(argv[i+1]);
     267               0 :                 dfScaleSrcMax = atof(argv[i+2]);
     268               0 :                 i += 2;
     269                 :             }
     270               0 :             if( i < argc-2 && bHaveScaleSrc && ArgIsNumeric(argv[i+1]) )
     271                 :             {
     272               0 :                 dfScaleDstMin = atof(argv[i+1]);
     273               0 :                 dfScaleDstMax = atof(argv[i+2]);
     274               0 :                 i += 2;
     275                 :             }
     276                 :             else
     277                 :             {
     278               0 :                 dfScaleDstMin = 0.0;
     279               0 :                 dfScaleDstMax = 255.999;
     280                 :             }
     281                 :         }   
     282                 : 
     283              56 :         else if( EQUAL(argv[i], "-unscale") )
     284                 :         {
     285               0 :             bUnscale = TRUE;
     286                 :         }
     287                 : 
     288              57 :         else if( EQUAL(argv[i],"-mo") && i < argc-1 )
     289                 :         {
     290                 :             papszMetadataOptions = CSLAddString( papszMetadataOptions,
     291               1 :                                                  argv[++i] );
     292                 :         }
     293                 : 
     294              57 :         else if( EQUAL(argv[i],"-outsize") && i < argc-2 )
     295                 :         {
     296               2 :             pszOXSize = argv[++i];
     297               2 :             pszOYSize = argv[++i];
     298                 :         }   
     299                 : 
     300              54 :         else if( EQUAL(argv[i],"-srcwin") && i < argc-4 )
     301                 :         {
     302               1 :             anSrcWin[0] = atoi(argv[++i]);
     303               1 :             anSrcWin[1] = atoi(argv[++i]);
     304               1 :             anSrcWin[2] = atoi(argv[++i]);
     305               1 :             anSrcWin[3] = atoi(argv[++i]);
     306                 :         }   
     307                 : 
     308              53 :         else if( EQUAL(argv[i],"-projwin") && i < argc-4 )
     309                 :         {
     310               1 :             dfULX = atof(argv[++i]);
     311               1 :             dfULY = atof(argv[++i]);
     312               1 :             dfLRX = atof(argv[++i]);
     313               1 :             dfLRY = atof(argv[++i]);
     314                 :         }   
     315                 : 
     316              53 :         else if( EQUAL(argv[i],"-a_srs") && i < argc-1 )
     317                 :         {
     318               2 :             OGRSpatialReference oOutputSRS;
     319                 : 
     320               2 :             if( oOutputSRS.SetFromUserInput( argv[i+1] ) != OGRERR_NONE )
     321                 :             {
     322                 :                 fprintf( stderr, "Failed to process SRS definition: %s\n", 
     323               0 :                          argv[i+1] );
     324               0 :                 GDALDestroyDriverManager();
     325               0 :                 exit( 1 );
     326                 :             }
     327                 : 
     328               2 :             oOutputSRS.exportToWkt( &pszOutputSRS );
     329               2 :             i++;
     330                 :         }   
     331                 : 
     332              52 :         else if( EQUAL(argv[i],"-expand") && i < argc-1 )
     333                 :         {
     334               3 :             if (EQUAL(argv[i+1], "gray"))
     335               0 :                 nRGBExpand = 1;
     336               3 :             else if (EQUAL(argv[i+1], "rgb"))
     337               2 :                 nRGBExpand = 3;
     338               1 :             else if (EQUAL(argv[i+1], "rgba"))
     339               1 :                 nRGBExpand = 4;
     340                 :             else
     341                 :             {
     342                 :                 printf( "Value %s unsupported. Only gray, rgb or rgba are supported.\n\n", 
     343               0 :                     argv[i] );
     344               0 :                 Usage();
     345               0 :                 GDALDestroyDriverManager();
     346               0 :                 exit( 2 );
     347                 :             }
     348               3 :             i++;
     349                 :         }
     350                 : 
     351              46 :         else if( argv[i][0] == '-' )
     352                 :         {
     353                 :             printf( "Option %s incomplete, or not recognised.\n\n", 
     354               0 :                     argv[i] );
     355               0 :             Usage();
     356               0 :             GDALDestroyDriverManager();
     357               0 :             exit( 2 );
     358                 :         }
     359              46 :         else if( pszSource == NULL )
     360                 :         {
     361              23 :             iSrcFileArg = i;
     362              23 :             pszSource = argv[i];
     363                 :         }
     364              23 :         else if( pszDest == NULL )
     365                 :         {
     366              23 :             pszDest = argv[i];
     367              23 :             iDstFileArg = i;
     368                 :         }
     369                 : 
     370                 :         else
     371                 :         {
     372               0 :             printf( "Too many command options.\n\n" );
     373               0 :             Usage();
     374               0 :             GDALDestroyDriverManager();
     375               0 :             exit( 2 );
     376                 :         }
     377                 :     }
     378                 : 
     379              23 :     if( pszDest == NULL )
     380                 :     {
     381               0 :         Usage();
     382               0 :         GDALDestroyDriverManager();
     383               0 :         exit( 10 );
     384                 :     }
     385                 : 
     386              23 :     if ( strcmp(pszSource, pszDest) == 0)
     387                 :     {
     388               0 :         fprintf(stderr, "Source and destination datasets must be different.\n");
     389               0 :         GDALDestroyDriverManager();
     390               0 :         exit( 1 );
     391                 :     }
     392                 : 
     393                 : /* -------------------------------------------------------------------- */
     394                 : /*      Attempt to open source file.                                    */
     395                 : /* -------------------------------------------------------------------- */
     396                 : 
     397              23 :     hDataset = GDALOpenShared( pszSource, GA_ReadOnly );
     398                 :     
     399              23 :     if( hDataset == NULL )
     400                 :     {
     401                 :         fprintf( stderr,
     402                 :                  "GDALOpen failed - %d\n%s\n",
     403               0 :                  CPLGetLastErrorNo(), CPLGetLastErrorMsg() );
     404               0 :         GDALDestroyDriverManager();
     405               0 :         exit( 1 );
     406                 :     }
     407                 : 
     408                 : /* -------------------------------------------------------------------- */
     409                 : /*      Handle subdatasets.                                             */
     410                 : /* -------------------------------------------------------------------- */
     411              23 :     if( !bCopySubDatasets 
     412                 :         && CSLCount(GDALGetMetadata( hDataset, "SUBDATASETS" )) > 0 
     413                 :         && GDALGetRasterCount(hDataset) == 0 )
     414                 :     {
     415                 :         fprintf( stderr,
     416               0 :                  "Input file contains subdatasets. Please, select one of them for reading.\n" );
     417               0 :         GDALClose( hDataset );
     418               0 :         GDALDestroyDriverManager();
     419               0 :         exit( 1 );
     420                 :     }
     421                 : 
     422              23 :     if( CSLCount(GDALGetMetadata( hDataset, "SUBDATASETS" )) > 0 
     423                 :         && bCopySubDatasets )
     424                 :     {
     425               1 :         char **papszSubdatasets = GDALGetMetadata(hDataset,"SUBDATASETS");
     426               1 :         char *pszSubDest = (char *) CPLMalloc(strlen(pszDest)+32);
     427                 :         int i;
     428               1 :         int bOldSubCall = bSubCall;
     429                 :         
     430               1 :         argv[iDstFileArg] = pszSubDest;
     431               1 :         bSubCall = TRUE;
     432               2 :         for( i = 0; papszSubdatasets[i] != NULL; i += 2 )
     433                 :         {
     434               1 :             argv[iSrcFileArg] = strstr(papszSubdatasets[i],"=")+1;
     435               1 :             sprintf( pszSubDest, "%s%d", pszDest, i/2 + 1 );
     436               1 :             if( ProxyMain( argc, argv ) != 0 )
     437               0 :                 break;
     438                 :         }
     439                 :         
     440               1 :         bSubCall = bOldSubCall;
     441               1 :         CPLFree( pszSubDest );
     442                 : 
     443               1 :         GDALClose( hDataset );
     444                 : 
     445               1 :         if( !bSubCall )
     446                 :         {
     447               1 :             GDALDumpOpenDatasets( stderr );
     448               1 :             GDALDestroyDriverManager();
     449                 :         }
     450               1 :         return 1;
     451                 :     }
     452                 : 
     453                 : /* -------------------------------------------------------------------- */
     454                 : /*      Collect some information from the source file.                  */
     455                 : /* -------------------------------------------------------------------- */
     456              22 :     nRasterXSize = GDALGetRasterXSize( hDataset );
     457              22 :     nRasterYSize = GDALGetRasterYSize( hDataset );
     458                 : 
     459              22 :     if( !bQuiet )
     460              22 :         printf( "Input file size is %d, %d\n", nRasterXSize, nRasterYSize );
     461                 : 
     462              22 :     if( anSrcWin[2] == 0 && anSrcWin[3] == 0 )
     463                 :     {
     464              21 :         anSrcWin[2] = nRasterXSize;
     465              21 :         anSrcWin[3] = nRasterYSize;
     466                 :     }
     467                 : 
     468                 : /* -------------------------------------------------------------------- */
     469                 : /*  Build band list to translate          */
     470                 : /* -------------------------------------------------------------------- */
     471              22 :     if( nBandCount == 0 )
     472                 :     {
     473              21 :         nBandCount = GDALGetRasterCount( hDataset );
     474              21 :         if( nBandCount == 0 )
     475                 :         {
     476               0 :             fprintf( stderr, "Input file has no bands, and so cannot be translated.\n" );
     477               0 :             GDALDestroyDriverManager();
     478               0 :             exit(1 );
     479                 :         }
     480                 : 
     481              21 :         panBandList = (int *) CPLMalloc(sizeof(int)*nBandCount);
     482              44 :         for( i = 0; i < nBandCount; i++ )
     483              23 :             panBandList[i] = i+1;
     484                 :     }
     485                 :     else
     486                 :     {
     487               4 :         for( i = 0; i < nBandCount; i++ )
     488                 :         {
     489               3 :             if( panBandList[i] < 1 || panBandList[i] > GDALGetRasterCount(hDataset) )
     490                 :             {
     491                 :                 fprintf( stderr, 
     492                 :                          "Band %d requested, but only bands 1 to %d available.\n",
     493               0 :                          panBandList[i], GDALGetRasterCount(hDataset) );
     494               0 :                 GDALDestroyDriverManager();
     495               0 :                 exit( 2 );
     496                 :             }
     497                 :         }
     498                 : 
     499               1 :         if( nBandCount != GDALGetRasterCount( hDataset ) )
     500               0 :             bDefBands = FALSE;
     501                 :     }
     502                 : 
     503                 : /* -------------------------------------------------------------------- */
     504                 : /*      Compute the source window from the projected source window      */
     505                 : /*      if the projected coordinates were provided.  Note that the      */
     506                 : /*      projected coordinates are in ulx, uly, lrx, lry format,         */
     507                 : /*      while the anSrcWin is xoff, yoff, xsize, ysize with the         */
     508                 : /*      xoff,yoff being the ulx, uly in pixel/line.                     */
     509                 : /* -------------------------------------------------------------------- */
     510              22 :     if( dfULX != 0.0 || dfULY != 0.0 
     511                 :         || dfLRX != 0.0 || dfLRY != 0.0 )
     512                 :     {
     513                 :         double  adfGeoTransform[6];
     514                 : 
     515               1 :         GDALGetGeoTransform( hDataset, adfGeoTransform );
     516                 : 
     517               1 :         if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 )
     518                 :         {
     519                 :             fprintf( stderr, 
     520                 :                      "The -projwin option was used, but the geotransform is\n"
     521               0 :                      "rotated.  This configuration is not supported.\n" );
     522               0 :             GDALClose( hDataset );
     523               0 :             CPLFree( panBandList );
     524               0 :             GDALDestroyDriverManager();
     525               0 :             exit( 1 );
     526                 :         }
     527                 : 
     528                 :         anSrcWin[0] = (int) 
     529               1 :             ((dfULX - adfGeoTransform[0]) / adfGeoTransform[1] + 0.001);
     530                 :         anSrcWin[1] = (int) 
     531               1 :             ((dfULY - adfGeoTransform[3]) / adfGeoTransform[5] + 0.001);
     532                 : 
     533               1 :         anSrcWin[2] = (int) ((dfLRX - dfULX) / adfGeoTransform[1] + 0.5);
     534               1 :         anSrcWin[3] = (int) ((dfLRY - dfULY) / adfGeoTransform[5] + 0.5);
     535                 : 
     536               1 :         if( !bQuiet )
     537                 :             fprintf( stdout, 
     538                 :                      "Computed -srcwin %d %d %d %d from projected window.\n",
     539                 :                      anSrcWin[0], 
     540                 :                      anSrcWin[1], 
     541                 :                      anSrcWin[2], 
     542               1 :                      anSrcWin[3] );
     543                 :         
     544               3 :         if( anSrcWin[0] < 0 || anSrcWin[1] < 0 
     545               1 :             || anSrcWin[0] + anSrcWin[2] > GDALGetRasterXSize(hDataset) 
     546               1 :             || anSrcWin[1] + anSrcWin[3] > GDALGetRasterYSize(hDataset) )
     547                 :         {
     548                 :             fprintf( stderr, 
     549                 :                      "Computed -srcwin falls outside raster size of %dx%d.\n",
     550                 :                      GDALGetRasterXSize(hDataset), 
     551               0 :                      GDALGetRasterYSize(hDataset) );
     552               0 :             exit( 1 );
     553                 :         }
     554                 :     }
     555                 : 
     556                 : /* -------------------------------------------------------------------- */
     557                 : /*      Verify source window.                                           */
     558                 : /* -------------------------------------------------------------------- */
     559             110 :     if( anSrcWin[0] < 0 || anSrcWin[1] < 0 
     560              44 :         || anSrcWin[2] <= 0 || anSrcWin[3] <= 0
     561              22 :         || anSrcWin[0] + anSrcWin[2] > GDALGetRasterXSize(hDataset) 
     562              22 :         || anSrcWin[1] + anSrcWin[3] > GDALGetRasterYSize(hDataset) )
     563                 :     {
     564                 :         fprintf( stderr, 
     565                 :                  "-srcwin %d %d %d %d falls outside raster size of %dx%d\n"
     566                 :                  "or is otherwise illegal.\n",
     567                 :                  anSrcWin[0],
     568                 :                  anSrcWin[1],
     569                 :                  anSrcWin[2],
     570                 :                  anSrcWin[3],
     571                 :                  GDALGetRasterXSize(hDataset), 
     572               0 :                  GDALGetRasterYSize(hDataset) );
     573               0 :         exit( 1 );
     574                 :     }
     575                 : 
     576                 : /* -------------------------------------------------------------------- */
     577                 : /*      Find the output driver.                                         */
     578                 : /* -------------------------------------------------------------------- */
     579              22 :     hDriver = GDALGetDriverByName( pszFormat );
     580              22 :     if( hDriver == NULL )
     581                 :     {
     582                 :         int iDr;
     583                 :         
     584               0 :         printf( "Output driver `%s' not recognised.\n", pszFormat );
     585               0 :         printf( "The following format drivers are configured and support output:\n" );
     586               0 :         for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ )
     587                 :         {
     588               0 :             GDALDriverH hDriver = GDALGetDriver(iDr);
     589                 : 
     590               0 :             if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL
     591                 :                 || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY,
     592                 :                                         NULL ) != NULL )
     593                 :             {
     594                 :                 printf( "  %s: %s\n",
     595                 :                         GDALGetDriverShortName( hDriver  ),
     596               0 :                         GDALGetDriverLongName( hDriver ) );
     597                 :             }
     598                 :         }
     599               0 :         printf( "\n" );
     600               0 :         Usage();
     601                 :         
     602               0 :         GDALClose( hDataset );
     603               0 :         CPLFree( panBandList );
     604               0 :         GDALDestroyDriverManager();
     605               0 :         CSLDestroy( argv );
     606               0 :         CSLDestroy( papszCreateOptions );
     607               0 :         exit( 1 );
     608                 :     }
     609                 : 
     610                 : /* -------------------------------------------------------------------- */
     611                 : /*      The short form is to CreateCopy().  We use this if the input    */
     612                 : /*      matches the whole dataset.  Eventually we should rewrite        */
     613                 : /*      this entire program to use virtual datasets to construct a      */
     614                 : /*      virtual input source to copy from.                              */
     615                 : /* -------------------------------------------------------------------- */
     616              93 :     if( eOutputType == GDT_Unknown 
     617                 :         && !bScale && !bUnscale
     618                 :         && CSLCount(papszMetadataOptions) == 0 && bDefBands 
     619              36 :         && anSrcWin[0] == 0 && anSrcWin[1] == 0 
     620              18 :         && anSrcWin[2] == GDALGetRasterXSize(hDataset)
     621              17 :         && anSrcWin[3] == GDALGetRasterYSize(hDataset) 
     622                 :         && pszOXSize == NULL && pszOYSize == NULL 
     623                 :         && nGCPCount == 0 && !bGotBounds
     624                 :         && pszOutputSRS == NULL && !bSetNoData
     625                 :         && nRGBExpand == 0)
     626                 :     {
     627                 :         
     628                 :         hOutDS = GDALCreateCopy( hDriver, pszDest, hDataset, 
     629                 :                                  bStrict, papszCreateOptions, 
     630               8 :                                  pfnProgress, NULL );
     631                 : 
     632               8 :         if( hOutDS != NULL )
     633               8 :             GDALClose( hOutDS );
     634                 :         
     635               8 :         GDALClose( hDataset );
     636                 : 
     637               8 :         CPLFree( panBandList );
     638                 : 
     639               8 :         if( !bSubCall )
     640                 :         {
     641               7 :             GDALDumpOpenDatasets( stderr );
     642               7 :             GDALDestroyDriverManager();
     643                 :         }
     644                 : 
     645               8 :         CSLDestroy( argv );
     646               8 :         CSLDestroy( papszCreateOptions );
     647                 : 
     648               8 :         return hOutDS == NULL;
     649                 :     }
     650                 : 
     651                 : /* -------------------------------------------------------------------- */
     652                 : /*      Establish some parameters.                                      */
     653                 : /* -------------------------------------------------------------------- */
     654              14 :     if( pszOXSize == NULL )
     655                 :     {
     656              12 :         nOXSize = anSrcWin[2];
     657              12 :         nOYSize = anSrcWin[3];
     658                 :     }
     659                 :     else
     660                 :     {
     661               2 :         nOXSize = (int) ((pszOXSize[strlen(pszOXSize)-1]=='%' 
     662               4 :                           ? atof(pszOXSize)/100*anSrcWin[2] : atoi(pszOXSize)));
     663               2 :         nOYSize = (int) ((pszOYSize[strlen(pszOYSize)-1]=='%' 
     664               4 :                           ? atof(pszOYSize)/100*anSrcWin[3] : atoi(pszOYSize)));
     665                 :     }
     666                 :     
     667                 : /* ==================================================================== */
     668                 : /*      Create a virtual dataset.                                       */
     669                 : /* ==================================================================== */
     670                 :     VRTDataset *poVDS;
     671                 :         
     672                 : /* -------------------------------------------------------------------- */
     673                 : /*      Make a virtual clone.                                           */
     674                 : /* -------------------------------------------------------------------- */
     675              14 :     poVDS = (VRTDataset *) VRTCreate( nOXSize, nOYSize );
     676                 : 
     677              14 :     if( nGCPCount == 0 )
     678                 :     {
     679              12 :         if( pszOutputSRS != NULL )
     680                 :         {
     681               0 :             poVDS->SetProjection( pszOutputSRS );
     682                 :         }
     683                 :         else
     684                 :         {
     685              12 :             pszProjection = GDALGetProjectionRef( hDataset );
     686              12 :             if( pszProjection != NULL && strlen(pszProjection) > 0 )
     687               9 :                 poVDS->SetProjection( pszProjection );
     688                 :         }
     689                 :     }
     690                 : 
     691              14 :     if( bGotBounds )
     692                 :     {
     693               1 :         adfGeoTransform[0] = adfULLR[0];
     694               1 :         adfGeoTransform[1] = (adfULLR[2] - adfULLR[0]) / nOXSize;
     695               1 :         adfGeoTransform[2] = 0.0;
     696               1 :         adfGeoTransform[3] = adfULLR[1];
     697               1 :         adfGeoTransform[4] = 0.0;
     698               1 :         adfGeoTransform[5] = (adfULLR[3] - adfULLR[1]) / nOYSize;
     699                 : 
     700               1 :         poVDS->SetGeoTransform( adfGeoTransform );
     701                 :     }
     702                 : 
     703              13 :     else if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None 
     704                 :         && nGCPCount == 0 )
     705                 :     {
     706              18 :         adfGeoTransform[0] += anSrcWin[0] * adfGeoTransform[1]
     707              27 :             + anSrcWin[1] * adfGeoTransform[2];
     708              18 :         adfGeoTransform[3] += anSrcWin[0] * adfGeoTransform[4]
     709              27 :             + anSrcWin[1] * adfGeoTransform[5];
     710                 :         
     711               9 :         adfGeoTransform[1] *= anSrcWin[2] / (double) nOXSize;
     712               9 :         adfGeoTransform[2] *= anSrcWin[3] / (double) nOYSize;
     713               9 :         adfGeoTransform[4] *= anSrcWin[2] / (double) nOXSize;
     714               9 :         adfGeoTransform[5] *= anSrcWin[3] / (double) nOYSize;
     715                 :         
     716               9 :         poVDS->SetGeoTransform( adfGeoTransform );
     717                 :     }
     718                 : 
     719              14 :     if( nGCPCount != 0 )
     720                 :     {
     721               2 :         const char *pszGCPProjection = pszOutputSRS;
     722                 : 
     723               2 :         if( pszGCPProjection == NULL )
     724               0 :             pszGCPProjection = GDALGetGCPProjection( hDataset );
     725               2 :         if( pszGCPProjection == NULL )
     726               0 :             pszGCPProjection = "";
     727                 : 
     728               2 :         poVDS->SetGCPs( nGCPCount, pasGCPs, pszGCPProjection );
     729                 : 
     730               2 :         GDALDeinitGCPs( nGCPCount, pasGCPs );
     731               2 :         CPLFree( pasGCPs );
     732                 :     }
     733                 : 
     734              12 :     else if( GDALGetGCPCount( hDataset ) > 0 )
     735                 :     {
     736                 :         GDAL_GCP *pasGCPs;
     737               0 :         int       nGCPs = GDALGetGCPCount( hDataset );
     738                 : 
     739               0 :         pasGCPs = GDALDuplicateGCPs( nGCPs, GDALGetGCPs( hDataset ) );
     740                 : 
     741               0 :         for( i = 0; i < nGCPs; i++ )
     742                 :         {
     743               0 :             pasGCPs[i].dfGCPPixel -= anSrcWin[0];
     744               0 :             pasGCPs[i].dfGCPLine  -= anSrcWin[1];
     745               0 :             pasGCPs[i].dfGCPPixel *= (nOXSize / (double) anSrcWin[2] );
     746               0 :             pasGCPs[i].dfGCPLine  *= (nOYSize / (double) anSrcWin[3] );
     747                 :         }
     748                 :             
     749                 :         poVDS->SetGCPs( nGCPs, pasGCPs,
     750               0 :                         GDALGetGCPProjection( hDataset ) );
     751                 : 
     752               0 :         GDALDeinitGCPs( nGCPs, pasGCPs );
     753               0 :         CPLFree( pasGCPs );
     754                 :     }
     755                 : 
     756                 : /* -------------------------------------------------------------------- */
     757                 : /*      Transfer generally applicable metadata.                         */
     758                 : /* -------------------------------------------------------------------- */
     759              14 :     poVDS->SetMetadata( ((GDALDataset*)hDataset)->GetMetadata() );
     760              14 :     AttachMetadata( (GDALDatasetH) poVDS, papszMetadataOptions );
     761                 : 
     762                 : /* -------------------------------------------------------------------- */
     763                 : /*      Transfer metadata that remains valid if the spatial             */
     764                 : /*      arrangement of the data is unaltered.                           */
     765                 : /* -------------------------------------------------------------------- */
     766              41 :     if( anSrcWin[0] == 0 && anSrcWin[1] == 0 
     767              14 :         && anSrcWin[2] == GDALGetRasterXSize(hDataset)
     768              13 :         && anSrcWin[3] == GDALGetRasterYSize(hDataset) 
     769                 :         && pszOXSize == NULL && pszOYSize == NULL )
     770                 :     {
     771                 :         char **papszMD;
     772                 : 
     773              11 :         papszMD = ((GDALDataset*)hDataset)->GetMetadata("RPC");
     774              11 :         if( papszMD != NULL )
     775               0 :             poVDS->SetMetadata( papszMD, "RPC" );
     776                 :     }
     777                 : 
     778              14 :     if (nRGBExpand != 0)
     779               3 :         nBandCount += nRGBExpand - 1;
     780                 : 
     781                 : /* ==================================================================== */
     782                 : /*      Process all bands.                                              */
     783                 : /* ==================================================================== */
     784              37 :     for( i = 0; i < nBandCount; i++ )
     785                 :     {
     786                 :         VRTSourcedRasterBand   *poVRTBand;
     787                 :         GDALRasterBand  *poSrcBand;
     788                 :         GDALDataType    eBandType;
     789                 : 
     790              33 :         if (nRGBExpand != 0 && i < nRGBExpand)
     791                 :         {
     792                 :             poSrcBand = ((GDALDataset *) 
     793              10 :                      hDataset)->GetRasterBand(panBandList[0]);
     794              10 :             GDALColorTable* poColorTable = poSrcBand->GetColorTable();
     795              10 :             if (poColorTable == NULL)
     796                 :             {
     797               0 :                 fprintf(stderr, "Error : band %d has no color table\n", panBandList[0]);
     798               0 :                 GDALClose( hDataset );
     799               0 :                 CPLFree( panBandList );
     800               0 :                 GDALDestroyDriverManager();
     801               0 :                 CSLDestroy( argv );
     802               0 :                 CSLDestroy( papszCreateOptions );
     803               0 :                 exit( 1 );
     804                 :             }
     805                 :             
     806                 :             /* Check that the color table only contains gray levels */
     807                 :             /* when using -expand gray */
     808              10 :             if (nRGBExpand == 1)
     809                 :             {
     810               0 :                 int nColorCount = poColorTable->GetColorEntryCount();
     811                 :                 int nColor;
     812               0 :                 for( nColor = 0; nColor < nColorCount; nColor++ )
     813                 :                 {
     814               0 :                     const GDALColorEntry* poEntry = poColorTable->GetColorEntry(nColor);
     815               0 :                     if (poEntry->c1 != poEntry->c2 || poEntry->c1 != poEntry->c2)
     816                 :                     {
     817               0 :                         fprintf(stderr, "Warning : color table contains non gray levels colors\n");
     818               0 :                         break;
     819                 :                     }
     820                 :                 }
     821                 :             }
     822                 :         }
     823                 :         else
     824                 :             poSrcBand = ((GDALDataset *) 
     825              13 :                         hDataset)->GetRasterBand(panBandList[i]);
     826                 : 
     827                 : /* -------------------------------------------------------------------- */
     828                 : /*      Select output data type to match source.                        */
     829                 : /* -------------------------------------------------------------------- */
     830              23 :         if( eOutputType == GDT_Unknown )
     831              21 :             eBandType = poSrcBand->GetRasterDataType();
     832                 :         else
     833               2 :             eBandType = eOutputType;
     834                 : 
     835                 : /* -------------------------------------------------------------------- */
     836                 : /*      Create this band.                                               */
     837                 : /* -------------------------------------------------------------------- */
     838              23 :         poVDS->AddBand( eBandType, NULL );
     839              23 :         poVRTBand = (VRTSourcedRasterBand *) poVDS->GetRasterBand( i+1 );
     840                 :             
     841                 : /* -------------------------------------------------------------------- */
     842                 : /*      Do we need to collect scaling information?                      */
     843                 : /* -------------------------------------------------------------------- */
     844              23 :         double dfScale=1.0, dfOffset=0.0;
     845                 : 
     846              23 :         if( bScale && !bHaveScaleSrc )
     847                 :         {
     848                 :             double  adfCMinMax[2];
     849               0 :             GDALComputeRasterMinMax( poSrcBand, TRUE, adfCMinMax );
     850               0 :             dfScaleSrcMin = adfCMinMax[0];
     851               0 :             dfScaleSrcMax = adfCMinMax[1];
     852                 :         }
     853                 : 
     854              23 :         if( bScale )
     855                 :         {
     856               0 :             if( dfScaleSrcMax == dfScaleSrcMin )
     857               0 :                 dfScaleSrcMax += 0.1;
     858               0 :             if( dfScaleDstMax == dfScaleDstMin )
     859               0 :                 dfScaleDstMax += 0.1;
     860                 : 
     861                 :             dfScale = (dfScaleDstMax - dfScaleDstMin) 
     862               0 :                 / (dfScaleSrcMax - dfScaleSrcMin);
     863               0 :             dfOffset = -1 * dfScaleSrcMin * dfScale + dfScaleDstMin;
     864                 :         }
     865                 : 
     866              23 :         if( bUnscale )
     867                 :         {
     868               0 :             dfScale = poSrcBand->GetScale();
     869               0 :             dfOffset = poSrcBand->GetOffset();
     870                 :         }
     871                 : 
     872                 : /* -------------------------------------------------------------------- */
     873                 : /*      Create a simple or complex data source depending on the         */
     874                 : /*      translation type required.                                      */
     875                 : /* -------------------------------------------------------------------- */
     876              33 :         if( bUnscale || bScale || (nRGBExpand != 0 && i < nRGBExpand) )
     877                 :         {
     878                 :             poVRTBand->AddComplexSource( poSrcBand,
     879                 :                                          anSrcWin[0], anSrcWin[1], 
     880                 :                                          anSrcWin[2], anSrcWin[3], 
     881                 :                                          0, 0, nOXSize, nOYSize,
     882                 :                                          dfOffset, dfScale,
     883                 :                                          VRT_NODATA_UNSET,
     884              10 :                                          (nRGBExpand != 0 && i < nRGBExpand) ? i + 1 : 0 );
     885                 :         }
     886                 :         else
     887                 :             poVRTBand->AddSimpleSource( poSrcBand,
     888                 :                                         anSrcWin[0], anSrcWin[1], 
     889                 :                                         anSrcWin[2], anSrcWin[3], 
     890              13 :                                         0, 0, nOXSize, nOYSize );
     891                 : 
     892                 : /* -------------------------------------------------------------------- */
     893                 : /*      In case of color table translate, we only set the color         */
     894                 : /*      interpretation other info copied by CopyCommonInfoFrom are      */
     895                 : /*      not relevant in RGB expansion.                                  */
     896                 : /* -------------------------------------------------------------------- */
     897              23 :         if (nRGBExpand == 1)
     898                 :         {
     899               0 :             poVRTBand->SetColorInterpretation( GCI_GrayIndex );
     900                 :         }
     901              33 :         else if (nRGBExpand != 0 && i < nRGBExpand)
     902                 :         {
     903              10 :             poVRTBand->SetColorInterpretation( (GDALColorInterp) (GCI_RedBand + i) );
     904                 :         }
     905                 : 
     906                 : /* -------------------------------------------------------------------- */
     907                 : /*      copy over some other information of interest.                   */
     908                 : /* -------------------------------------------------------------------- */
     909                 :         else
     910                 :         {
     911              13 :             poVRTBand->CopyCommonInfoFrom( poSrcBand );
     912                 : 
     913              13 :             if( bUnscale )
     914                 :             {
     915               0 :                 poVRTBand->SetOffset( 0.0 );
     916               0 :                 poVRTBand->SetScale( 1.0 );
     917                 :             }
     918                 :         }
     919                 : 
     920                 : /* -------------------------------------------------------------------- */
     921                 : /*      Set a forcable nodata value?                                    */
     922                 : /* -------------------------------------------------------------------- */
     923              23 :         if( bSetNoData )
     924                 :         {
     925               1 :             double dfVal = dfNoDataReal;
     926               1 :             int bClamped = FALSE, bRounded = FALSE;
     927                 : 
     928                 : #define CLAMP(val,type,minval,maxval) \
     929                 :     do { if (val < minval) { bClamped = TRUE; val = minval; } \
     930                 :     else if (val > maxval) { bClamped = TRUE; val = maxval; } \
     931                 :     else if (val != (type)val) { bRounded = TRUE; val = (type)(val + 0.5); } } \
     932                 :     while(0)
     933                 : 
     934               1 :             switch(eBandType)
     935                 :             {
     936                 :                 case GDT_Byte:
     937               1 :                     CLAMP(dfVal, GByte, 0.0, 255.0);
     938               1 :                     break;
     939                 :                 case GDT_Int16:
     940               0 :                     CLAMP(dfVal, GInt16, -32768.0, 32767.0);
     941               0 :                     break;
     942                 :                 case GDT_UInt16:
     943               0 :                     CLAMP(dfVal, GUInt16, 0.0, 65535.0);
     944               0 :                     break;
     945                 :                 case GDT_Int32:
     946               0 :                     CLAMP(dfVal, GInt32, -2147483648.0, 2147483647.0);
     947               0 :                     break;
     948                 :                 case GDT_UInt32:
     949               0 :                     CLAMP(dfVal, GUInt32, 0.0, 4294967295.0);
     950                 :                     break;
     951                 :                 default:
     952                 :                     break;
     953                 :             }
     954                 :                 
     955               1 :             if (bClamped)
     956                 :             {
     957                 :                 printf( "for band %d, nodata value has been clamped "
     958                 :                        "to %.0f, the original value being out of range.\n",
     959               0 :                        i + 1, dfVal);
     960                 :             }
     961               1 :             else if(bRounded)
     962                 :             {
     963                 :                 printf("for band %d, nodata value has been rounded "
     964                 :                        "to %.0f, %s being an integer datatype.\n",
     965                 :                        i + 1, dfVal,
     966               0 :                        GDALGetDataTypeName(eBandType));
     967                 :             }
     968                 :             
     969               1 :             poVRTBand->SetNoDataValue( dfVal );
     970                 :         }
     971                 :     }
     972                 : 
     973                 : /* -------------------------------------------------------------------- */
     974                 : /*      Write to the output file using CopyCreate().                    */
     975                 : /* -------------------------------------------------------------------- */
     976                 :     hOutDS = GDALCreateCopy( hDriver, pszDest, (GDALDatasetH) poVDS,
     977                 :                              bStrict, papszCreateOptions, 
     978              14 :                              pfnProgress, NULL );
     979              14 :     if( hOutDS != NULL )
     980                 :     {
     981              14 :         GDALClose( hOutDS );
     982                 :     }
     983                 :     
     984              14 :     GDALClose( (GDALDatasetH) poVDS );
     985                 :         
     986              14 :     GDALClose( hDataset );
     987                 : 
     988              14 :     CPLFree( panBandList );
     989                 :     
     990              14 :     CPLFree( pszOutputSRS );
     991                 : 
     992              14 :     if( !bSubCall )
     993                 :     {
     994              14 :         GDALDumpOpenDatasets( stderr );
     995              14 :         GDALDestroyDriverManager();
     996                 :     }
     997                 : 
     998              14 :     CSLDestroy( argv );
     999              14 :     CSLDestroy( papszCreateOptions );
    1000                 :     
    1001              14 :     return hOutDS == NULL;
    1002                 : }
    1003                 : 
    1004                 : 
    1005                 : /************************************************************************/
    1006                 : /*                            ArgIsNumeric()                            */
    1007                 : /************************************************************************/
    1008                 : 
    1009               0 : int ArgIsNumeric( const char *pszArg )
    1010                 : 
    1011                 : {
    1012               0 :     if( pszArg[0] == '-' )
    1013               0 :         pszArg++;
    1014                 : 
    1015               0 :     if( *pszArg == '\0' )
    1016               0 :         return FALSE;
    1017                 : 
    1018               0 :     while( *pszArg != '\0' )
    1019                 :     {
    1020               0 :         if( (*pszArg < '0' || *pszArg > '9') && *pszArg != '.' )
    1021               0 :             return FALSE;
    1022               0 :         pszArg++;
    1023                 :     }
    1024                 :         
    1025               0 :     return TRUE;
    1026                 : }
    1027                 : 
    1028                 : /************************************************************************/
    1029                 : /*                           AttachMetadata()                           */
    1030                 : /************************************************************************/
    1031                 : 
    1032              14 : static void AttachMetadata( GDALDatasetH hDS, char **papszMetadataOptions )
    1033                 : 
    1034                 : {
    1035              14 :     int nCount = CSLCount(papszMetadataOptions);
    1036                 :     int i;
    1037                 : 
    1038              15 :     for( i = 0; i < nCount; i++ )
    1039                 :     {
    1040               1 :         char    *pszKey = NULL;
    1041                 :         const char *pszValue;
    1042                 :         
    1043               1 :         pszValue = CPLParseNameValue( papszMetadataOptions[i], &pszKey );
    1044               1 :         GDALSetMetadataItem(hDS,pszKey,pszValue,NULL);
    1045               1 :         CPLFree( pszKey );
    1046                 :     }
    1047                 : 
    1048              14 :     CSLDestroy( papszMetadataOptions );
    1049              14 : }
    1050                 : 
    1051                 : /************************************************************************/
    1052                 : /*                                main()                                */
    1053                 : /************************************************************************/
    1054                 : 
    1055              23 : int main( int argc, char ** argv )
    1056                 : 
    1057                 : {
    1058              23 :     return ProxyMain( argc, argv );
    1059                 : }
    1060                 : 
    1061                 : 

Generated by: LCOV version 1.7