LCOV - code coverage report
Current view: directory - gcore - gdaldriver.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 473 367 77.6 %
Date: 2013-03-30 Functions: 27 23 85.2 %

       1                 : /******************************************************************************
       2                 :  * $Id: gdaldriver.cpp 25606 2013-02-06 19:22:07Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL Core
       5                 :  * Purpose:  Implementation of GDALDriver class (and C wrappers)
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1998, 2000, 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 "gdal_priv.h"
      31                 : 
      32                 : CPL_CVSID("$Id: gdaldriver.cpp 25606 2013-02-06 19:22:07Z rouault $");
      33                 : 
      34                 : CPL_C_START
      35                 : const char* GDALClientDatasetGetFilename(const char* pszFilename);
      36                 : CPL_C_END
      37                 : 
      38                 : /************************************************************************/
      39                 : /*                             GDALDriver()                             */
      40                 : /************************************************************************/
      41                 : 
      42           76429 : GDALDriver::GDALDriver()
      43                 : 
      44                 : {
      45           76429 :     pfnOpen = NULL;
      46           76429 :     pfnCreate = NULL;
      47           76429 :     pfnDelete = NULL;
      48           76429 :     pfnCreateCopy = NULL;
      49           76429 :     pfnUnloadDriver = NULL;
      50           76429 :     pDriverData = NULL;
      51           76429 :     pfnIdentify = NULL;
      52           76429 :     pfnRename = NULL;
      53           76429 :     pfnCopyFiles = NULL;
      54           76429 : }
      55                 : 
      56                 : /************************************************************************/
      57                 : /*                            ~GDALDriver()                             */
      58                 : /************************************************************************/
      59                 : 
      60           71521 : GDALDriver::~GDALDriver()
      61                 : 
      62                 : {
      63           71521 :     if( pfnUnloadDriver != NULL )
      64            4400 :         pfnUnloadDriver( this );
      65           71521 : }
      66                 : 
      67                 : /************************************************************************/
      68                 : /*                         GDALDestroyDriver()                          */
      69                 : /************************************************************************/
      70                 : 
      71                 : /**
      72                 :  * \brief Destroy a GDALDriver.
      73                 :  * 
      74                 :  * This is roughly equivelent to deleting the driver, but is guaranteed
      75                 :  * to take place in the GDAL heap.  It is important this that function
      76                 :  * not be called on a driver that is registered with the GDALDriverManager.
      77                 :  * 
      78                 :  * @param hDriver the driver to destroy.
      79                 :  */
      80                 : 
      81               0 : void CPL_STDCALL GDALDestroyDriver( GDALDriverH hDriver )
      82                 : 
      83                 : {
      84               0 :     VALIDATE_POINTER0( hDriver, "GDALDestroyDriver" );
      85                 : 
      86               0 :     delete ((GDALDriver *) hDriver);
      87                 : }
      88                 : 
      89                 : /************************************************************************/
      90                 : /*                               Create()                               */
      91                 : /************************************************************************/
      92                 : 
      93                 : /**
      94                 :  * \brief Create a new dataset with this driver.
      95                 :  *
      96                 :  * What argument values are legal for particular drivers is driver specific,
      97                 :  * and there is no way to query in advance to establish legal values.
      98                 :  *
      99                 :  * That function will try to validate the creation option list passed to the driver
     100                 :  * with the GDALValidateCreationOptions() method. This check can be disabled
     101                 :  * by defining the configuration option GDAL_VALIDATE_CREATION_OPTIONS=NO.
     102                 :  *
     103                 :  * After you have finished working with the returned dataset, it is <b>required</b>
     104                 :  * to close it with GDALClose(). This does not only close the file handle, but
     105                 :  * also ensures that all the data and metadata has been written to the dataset
     106                 :  * (GDALFlushCache() is not sufficient for that purpose).
     107                 :  *
     108                 :  * In some situations, the new dataset can be created in another process through the
     109                 :  * \ref gdal_api_proxy mechanism.
     110                 :  *
     111                 :  * Equivelent of the C function GDALCreate().
     112                 :  * 
     113                 :  * @param pszFilename the name of the dataset to create.  UTF-8 encoded.
     114                 :  * @param nXSize width of created raster in pixels.
     115                 :  * @param nYSize height of created raster in pixels.
     116                 :  * @param nBands number of bands.
     117                 :  * @param eType type of raster.
     118                 :  * @param papszOptions list of driver specific control parameters.
     119                 :  *
     120                 :  * @return NULL on failure, or a new GDALDataset.
     121                 :  */
     122                 : 
     123            8091 : GDALDataset * GDALDriver::Create( const char * pszFilename,
     124                 :                                   int nXSize, int nYSize, int nBands,
     125                 :                                   GDALDataType eType, char ** papszOptions )
     126                 : 
     127                 : {
     128            8091 :     CPLLocaleC  oLocaleForcer;
     129                 : 
     130                 : /* -------------------------------------------------------------------- */
     131                 : /*      Does this format support creation.                              */
     132                 : /* -------------------------------------------------------------------- */
     133            8091 :     if( pfnCreate == NULL )
     134                 :     {
     135                 :         CPLError( CE_Failure, CPLE_NotSupported,
     136                 :                   "GDALDriver::Create() ... no create method implemented"
     137               0 :                   " for this format.\n" );
     138                 : 
     139               0 :         return NULL;
     140                 :     }
     141                 : /* -------------------------------------------------------------------- */
     142                 : /*      Do some rudimentary argument checking.                          */
     143                 : /* -------------------------------------------------------------------- */
     144            8091 :     if (nBands < 0)
     145                 :     {
     146                 :         CPLError( CE_Failure, CPLE_AppDefined,
     147                 :                   "Attempt to create dataset with %d bands is illegal,"
     148                 :                   "Must be >= 0.",
     149               1 :                   nBands );
     150               1 :         return NULL;
     151                 :     }
     152                 : 
     153            8090 :     if( nXSize < 1 || nYSize < 1 )
     154                 :     {
     155                 :         CPLError( CE_Failure, CPLE_AppDefined,
     156                 :                   "Attempt to create %dx%d dataset is illegal,"
     157                 :                   "sizes must be larger than zero.",
     158               1 :                   nXSize, nYSize );
     159               1 :         return NULL;
     160                 :     }
     161                 : 
     162            8089 :     const char* pszClientFilename = GDALClientDatasetGetFilename(pszFilename);
     163            8092 :     if( pszClientFilename != NULL && !EQUAL(GetDescription(), "MEM") &&
     164               3 :         !EQUAL(GetDescription(), "VRT")  )
     165                 :     {
     166               3 :         GDALDriver* poAPIPROXYDriver = GDALGetAPIPROXYDriver();
     167               3 :         if( poAPIPROXYDriver != this )
     168                 :         {
     169               3 :             if( poAPIPROXYDriver == NULL || poAPIPROXYDriver->pfnCreate == NULL )
     170               0 :                 return NULL;
     171               3 :             char** papszOptionsDup = CSLDuplicate(papszOptions);
     172                 :             papszOptionsDup = CSLAddNameValue(papszOptionsDup, "SERVER_DRIVER",
     173               3 :                                                GetDescription());
     174                 :             GDALDataset* poDstDS = poAPIPROXYDriver->pfnCreate(
     175                 :                 pszClientFilename, nXSize, nYSize, nBands,
     176               3 :                 eType, papszOptionsDup);
     177                 : 
     178               3 :             CSLDestroy(papszOptionsDup);
     179                 : 
     180               3 :             if( poDstDS != NULL )
     181                 :             {
     182               6 :                 if( poDstDS->GetDescription() == NULL 
     183               3 :                     || strlen(poDstDS->GetDescription()) == 0 )
     184               0 :                     poDstDS->SetDescription( pszFilename );
     185                 : 
     186               3 :                 if( poDstDS->poDriver == NULL )
     187               0 :                     poDstDS->poDriver = poAPIPROXYDriver;
     188                 :             }
     189                 : 
     190               3 :             return poDstDS;
     191                 :         }
     192                 :     }
     193                 : 
     194                 : /* -------------------------------------------------------------------- */
     195                 : /*      Make sure we cleanup if there is an existing dataset of this    */
     196                 : /*      name.  But even if that seems to fail we will continue since    */
     197                 : /*      it might just be a corrupt file or something.                   */
     198                 : /* -------------------------------------------------------------------- */
     199            8086 :     if( !CSLFetchBoolean(papszOptions, "APPEND_SUBDATASET", FALSE) )
     200            8086 :         QuietDelete( pszFilename );
     201                 : 
     202                 : /* -------------------------------------------------------------------- */
     203                 : /*      Validate creation options.                                      */
     204                 : /* -------------------------------------------------------------------- */
     205            8086 :     if (CSLTestBoolean(CPLGetConfigOption("GDAL_VALIDATE_CREATION_OPTIONS", "YES")))
     206            8086 :         GDALValidateCreationOptions( this, papszOptions );
     207                 : 
     208                 : /* -------------------------------------------------------------------- */
     209                 : /*      Proceed with creation.                                          */
     210                 : /* -------------------------------------------------------------------- */
     211                 :     GDALDataset *poDS;
     212                 : 
     213                 :     CPLDebug( "GDAL", "GDALDriver::Create(%s,%s,%d,%d,%d,%s,%p)",
     214            8086 :               GetDescription(), pszFilename, nXSize, nYSize, nBands, 
     215                 :               GDALGetDataTypeName( eType ), 
     216           16172 :               papszOptions );
     217                 :     
     218                 :     poDS = pfnCreate( pszFilename, nXSize, nYSize, nBands, eType,
     219            8086 :                       papszOptions );
     220                 : 
     221            8086 :     if( poDS != NULL )
     222                 :     {
     223           14380 :         if( poDS->GetDescription() == NULL
     224            7190 :             || strlen(poDS->GetDescription()) == 0 )
     225            6461 :             poDS->SetDescription( pszFilename );
     226                 :         
     227            7190 :         if( poDS->poDriver == NULL )
     228            6593 :             poDS->poDriver = this;
     229                 :     }
     230                 : 
     231            8086 :     return poDS;
     232                 : }
     233                 : 
     234                 : /************************************************************************/
     235                 : /*                             GDALCreate()                             */
     236                 : /************************************************************************/
     237                 : 
     238                 : /**
     239                 :  * \brief Create a new dataset with this driver.
     240                 :  *
     241                 :  * @see GDALDriver::Create()
     242                 :  */
     243                 : 
     244                 : GDALDatasetH CPL_DLL CPL_STDCALL 
     245            7438 : GDALCreate( GDALDriverH hDriver, const char * pszFilename,
     246                 :             int nXSize, int nYSize, int nBands, GDALDataType eBandType,
     247                 :             char ** papszOptions )
     248                 : 
     249                 : {
     250            7438 :     VALIDATE_POINTER1( hDriver, "GDALCreate", NULL );
     251                 : 
     252                 :     return( ((GDALDriver *) hDriver)->Create( pszFilename,
     253                 :                                               nXSize, nYSize, nBands,
     254            7438 :                                               eBandType, papszOptions ) );
     255                 : }
     256                 : 
     257                 : /************************************************************************/
     258                 : /*                          DefaultCopyMasks()                          */
     259                 : /************************************************************************/
     260                 : 
     261             804 : CPLErr GDALDriver::DefaultCopyMasks( GDALDataset *poSrcDS,
     262                 :                                      GDALDataset *poDstDS,
     263                 :                                      int bStrict )
     264                 : 
     265                 : {
     266             804 :     CPLErr eErr = CE_None;  
     267                 : 
     268             804 :     int nBands = poSrcDS->GetRasterCount();
     269             804 :     if (nBands == 0)
     270               1 :         return CE_None;
     271                 : 
     272             803 :     const char* papszOptions[2] = { "COMPRESSED=YES", NULL };
     273                 : 
     274                 : /* -------------------------------------------------------------------- */
     275                 : /*      Try to copy mask if it seems appropriate.                       */
     276                 : /* -------------------------------------------------------------------- */
     277            2075 :     for( int iBand = 0; 
     278                 :          eErr == CE_None && iBand < nBands; 
     279                 :          iBand++ )
     280                 :     {
     281            1272 :         GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( iBand+1 );
     282                 : 
     283            1272 :         int nMaskFlags = poSrcBand->GetMaskFlags();
     284            1272 :         if( eErr == CE_None
     285                 :             && !(nMaskFlags & (GMF_ALL_VALID|GMF_PER_DATASET|GMF_ALPHA|GMF_NODATA) ) )
     286                 :         {
     287               0 :             GDALRasterBand *poDstBand = poDstDS->GetRasterBand( iBand+1 );
     288               0 :             if (poDstBand != NULL)
     289                 :             {
     290               0 :                 eErr = poDstBand->CreateMaskBand( nMaskFlags );
     291               0 :                 if( eErr == CE_None )
     292                 :                 {
     293                 :                     eErr = GDALRasterBandCopyWholeRaster(
     294               0 :                         poSrcBand->GetMaskBand(),
     295               0 :                         poDstBand->GetMaskBand(),
     296                 :                         (char**)papszOptions,
     297               0 :                         GDALDummyProgress, NULL);
     298                 :                 }
     299               0 :                 else if( !bStrict )
     300               0 :                     eErr = CE_None;
     301                 :             }
     302                 :         }
     303                 :     }
     304                 : 
     305                 : /* -------------------------------------------------------------------- */
     306                 : /*      Try to copy a per-dataset mask if we have one.                  */
     307                 : /* -------------------------------------------------------------------- */
     308             803 :     int nMaskFlags = poSrcDS->GetRasterBand(1)->GetMaskFlags();
     309             803 :     if( eErr == CE_None
     310                 :         && !(nMaskFlags & (GMF_ALL_VALID|GMF_ALPHA|GMF_NODATA) ) 
     311                 :         && (nMaskFlags & GMF_PER_DATASET) )
     312                 :     {
     313               1 :         eErr = poDstDS->CreateMaskBand( nMaskFlags );
     314               1 :         if( eErr == CE_None )
     315                 :         {
     316                 :             eErr = GDALRasterBandCopyWholeRaster(
     317               1 :                 poSrcDS->GetRasterBand(1)->GetMaskBand(),
     318               1 :                 poDstDS->GetRasterBand(1)->GetMaskBand(),
     319                 :                 (char**)papszOptions,
     320               3 :                 GDALDummyProgress, NULL);
     321                 :         }
     322               0 :         else if( !bStrict )
     323               0 :             eErr = CE_None;
     324                 :     }
     325                 : 
     326             803 :     return eErr;
     327                 : }
     328                 : 
     329                 : /************************************************************************/
     330                 : /*                         DefaultCreateCopy()                          */
     331                 : /************************************************************************/
     332                 : 
     333             613 : GDALDataset *GDALDriver::DefaultCreateCopy( const char * pszFilename, 
     334                 :                                             GDALDataset * poSrcDS, 
     335                 :                                             int bStrict, char ** papszOptions,
     336                 :                                             GDALProgressFunc pfnProgress,
     337                 :                                             void * pProgressData )
     338                 : 
     339                 : {
     340             613 :     if( pfnProgress == NULL )
     341               0 :         pfnProgress = GDALDummyProgress;
     342                 :     
     343             613 :     CPLErrorReset();
     344                 : 
     345             613 :     if( !pfnProgress( 0.0, NULL, pProgressData ) )
     346                 :     {
     347               0 :         CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
     348               0 :         return NULL;
     349                 :     }
     350                 : 
     351                 : /* -------------------------------------------------------------------- */
     352                 : /*      Validate that we can create the output as requested.            */
     353                 : /* -------------------------------------------------------------------- */
     354             613 :     int          nXSize = poSrcDS->GetRasterXSize();
     355             613 :     int          nYSize = poSrcDS->GetRasterYSize();
     356             613 :     int          nBands = poSrcDS->GetRasterCount();
     357                 : 
     358             613 :     CPLDebug( "GDAL", "Using default GDALDriver::CreateCopy implementation." );
     359                 : 
     360             613 :     if (nBands == 0)
     361                 :     {
     362                 :         CPLError( CE_Failure, CPLE_NotSupported,
     363              22 :                   "GDALDriver::DefaultCreateCopy does not support zero band" );
     364              22 :         return NULL;
     365                 :     }
     366                 : 
     367                 : /* -------------------------------------------------------------------- */
     368                 : /*      Propogate some specific structural metadata as options if it    */
     369                 : /*      appears to be supported by the target driver and the caller     */
     370                 : /*      didn't provide values.                                          */
     371                 : /* -------------------------------------------------------------------- */
     372             591 :     char **papszCreateOptions = CSLDuplicate( papszOptions );
     373                 :     int  iOptItem;
     374                 :     static const char *apszOptItems[] = {
     375                 :         "NBITS", "IMAGE_STRUCTURE",
     376                 :         "PIXELTYPE", "IMAGE_STRUCTURE", 
     377                 :         NULL };
     378                 : 
     379            1773 :     for( iOptItem = 0; apszOptItems[iOptItem] != NULL; iOptItem += 2 )
     380                 :     {
     381                 :         // does the source have this metadata item on the first band?
     382                 :         const char *pszValue = 
     383                 :             poSrcDS->GetRasterBand(1)->GetMetadataItem( 
     384            1182 :                 apszOptItems[iOptItem], apszOptItems[iOptItem+1] );
     385                 : 
     386            1182 :         if( pszValue == NULL )
     387            1180 :             continue;
     388                 : 
     389                 :         // do not override provided value.
     390               2 :         if( CSLFetchNameValue( papszCreateOptions, pszValue ) != NULL )
     391               0 :             continue;
     392                 : 
     393                 :         // Does this appear to be a supported creation option on this driver?
     394                 :         const char *pszOptionList =
     395               2 :             GetMetadataItem( GDAL_DMD_CREATIONDATATYPES );
     396                 : 
     397               2 :         if( pszOptionList == NULL 
     398                 :             || strstr(pszOptionList,apszOptItems[iOptItem]) != NULL )
     399               0 :             continue;
     400                 : 
     401                 :         papszCreateOptions = CSLSetNameValue( papszCreateOptions,
     402                 :                                               apszOptItems[iOptItem], 
     403               2 :                                               pszValue );
     404                 :     }
     405                 :     
     406                 : /* -------------------------------------------------------------------- */
     407                 : /*      Create destination dataset.                                     */
     408                 : /* -------------------------------------------------------------------- */
     409                 :     GDALDataset  *poDstDS;
     410                 :     GDALDataType eType;
     411             591 :     CPLErr       eErr = CE_None;
     412                 : 
     413             591 :     eType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
     414                 :     poDstDS = Create( pszFilename, nXSize, nYSize, 
     415             591 :                       nBands, eType, papszCreateOptions );
     416                 :                       
     417             591 :     CSLDestroy(papszCreateOptions);
     418                 : 
     419             591 :     if( poDstDS == NULL )
     420             371 :         return NULL;
     421                 : 
     422                 : /* -------------------------------------------------------------------- */
     423                 : /*      Try setting the projection and geotransform if it seems         */
     424                 : /*      suitable.                                                       */
     425                 : /* -------------------------------------------------------------------- */
     426                 :     double      adfGeoTransform[6];
     427                 : 
     428             654 :     if( eErr == CE_None
     429             220 :         && poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None 
     430             214 :         && (adfGeoTransform[0] != 0.0 
     431               0 :             || adfGeoTransform[1] != 1.0
     432               0 :             || adfGeoTransform[2] != 0.0
     433               0 :             || adfGeoTransform[3] != 0.0
     434               0 :             || adfGeoTransform[4] != 0.0
     435               0 :             || adfGeoTransform[5] != 1.0) )
     436                 :     {
     437             214 :         eErr = poDstDS->SetGeoTransform( adfGeoTransform );
     438             214 :         if( !bStrict )
     439              42 :             eErr = CE_None;
     440                 :     }
     441                 : 
     442             660 :     if( eErr == CE_None 
     443             220 :         && poSrcDS->GetProjectionRef() != NULL
     444             220 :         && strlen(poSrcDS->GetProjectionRef()) > 0 )
     445                 :     {
     446             210 :         eErr = poDstDS->SetProjection( poSrcDS->GetProjectionRef() );
     447             210 :         if( !bStrict )
     448              41 :             eErr = CE_None;
     449                 :     }
     450                 : 
     451                 : /* -------------------------------------------------------------------- */
     452                 : /*      Copy GCPs.                                                      */
     453                 : /* -------------------------------------------------------------------- */
     454             220 :     if( poSrcDS->GetGCPCount() > 0 && eErr == CE_None )
     455                 :     {
     456               1 :         eErr = poDstDS->SetGCPs( poSrcDS->GetGCPCount(),
     457               1 :                                  poSrcDS->GetGCPs(), 
     458               3 :                                  poSrcDS->GetGCPProjection() );
     459               1 :         if( !bStrict )
     460               0 :             eErr = CE_None;
     461                 :     }
     462                 : 
     463                 : /* -------------------------------------------------------------------- */
     464                 : /*      Copy metadata.                                                  */
     465                 : /* -------------------------------------------------------------------- */
     466             220 :     if( poSrcDS->GetMetadata() != NULL )
     467             204 :         poDstDS->SetMetadata( poSrcDS->GetMetadata() );
     468                 : 
     469                 : /* -------------------------------------------------------------------- */
     470                 : /*      Copy transportable special domain metadata (RPCs).  It would    */
     471                 : /*      be nice to copy geolocation, but is is pretty fragile.          */
     472                 : /* -------------------------------------------------------------------- */
     473             220 :     char **papszMD = poSrcDS->GetMetadata( "RPC" );
     474             220 :     if( papszMD )
     475               1 :         poDstDS->SetMetadata( papszMD, "RPC" );
     476                 : 
     477                 : /* -------------------------------------------------------------------- */
     478                 : /*      Loop copying bands.                                             */
     479                 : /* -------------------------------------------------------------------- */
     480             597 :     for( int iBand = 0; 
     481                 :          eErr == CE_None && iBand < nBands; 
     482                 :          iBand++ )
     483                 :     {
     484             377 :         GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( iBand+1 );
     485             377 :         GDALRasterBand *poDstBand = poDstDS->GetRasterBand( iBand+1 );
     486                 : 
     487                 : /* -------------------------------------------------------------------- */
     488                 : /*      Do we need to copy a colortable.                                */
     489                 : /* -------------------------------------------------------------------- */
     490                 :         GDALColorTable *poCT;
     491                 :         int bSuccess;
     492                 :         double dfValue;
     493                 : 
     494             377 :         poCT = poSrcBand->GetColorTable();
     495             377 :         if( poCT != NULL )
     496               4 :             poDstBand->SetColorTable( poCT );
     497                 : 
     498                 : /* -------------------------------------------------------------------- */
     499                 : /*      Do we need to copy other metadata?  Most of this is             */
     500                 : /*      non-critical, so lets not bother folks if it fails are we       */
     501                 : /*      are not in strict mode.                                         */
     502                 : /* -------------------------------------------------------------------- */
     503             377 :         if( !bStrict )
     504              51 :             CPLPushErrorHandler( CPLQuietErrorHandler );
     505                 : 
     506             377 :         if( strlen(poSrcBand->GetDescription()) > 0 )
     507              12 :             poDstBand->SetDescription( poSrcBand->GetDescription() );
     508                 : 
     509             377 :         if( CSLCount(poSrcBand->GetMetadata()) > 0 )
     510              72 :             poDstBand->SetMetadata( poSrcBand->GetMetadata() );
     511                 : 
     512             377 :         dfValue = poSrcBand->GetOffset( &bSuccess );
     513             377 :         if( bSuccess && dfValue != 0.0 )
     514               0 :             poDstBand->SetOffset( dfValue );
     515                 : 
     516             377 :         dfValue = poSrcBand->GetScale( &bSuccess );
     517             377 :         if( bSuccess && dfValue != 1.0 )
     518               1 :             poDstBand->SetScale( dfValue );
     519                 : 
     520             377 :         dfValue = poSrcBand->GetNoDataValue( &bSuccess );
     521             377 :         if( bSuccess )
     522              10 :             poDstBand->SetNoDataValue( dfValue );
     523                 : 
     524             967 :         if( poSrcBand->GetColorInterpretation() != GCI_Undefined 
     525             295 :             && poSrcBand->GetColorInterpretation()
     526             295 :             != poDstBand->GetColorInterpretation() )
     527                 :             poDstBand->SetColorInterpretation( 
     528             220 :                 poSrcBand->GetColorInterpretation() );
     529                 : 
     530                 :         char** papszCatNames;
     531             377 :         papszCatNames = poSrcBand->GetCategoryNames();
     532             377 :         if (0 != papszCatNames)
     533               1 :             poDstBand->SetCategoryNames( papszCatNames );
     534                 : 
     535             377 :         if( !bStrict )
     536                 :         {
     537              51 :             CPLPopErrorHandler();
     538              51 :             CPLErrorReset();
     539                 :         }
     540                 :         else 
     541             326 :             eErr = CPLGetLastErrorType();
     542                 :     }
     543                 : 
     544                 : /* -------------------------------------------------------------------- */
     545                 : /*      Copy image data.                                                */
     546                 : /* -------------------------------------------------------------------- */
     547             220 :     if( eErr == CE_None )
     548                 :         eErr = GDALDatasetCopyWholeRaster( (GDALDatasetH) poSrcDS, 
     549                 :                                            (GDALDatasetH) poDstDS, 
     550             219 :                                            NULL, pfnProgress, pProgressData );
     551                 : 
     552                 : /* -------------------------------------------------------------------- */
     553                 : /*      Should we copy some masks over?                                 */
     554                 : /* -------------------------------------------------------------------- */
     555             220 :     if( eErr == CE_None )
     556             201 :         eErr = DefaultCopyMasks( poSrcDS, poDstDS, eErr );
     557                 : 
     558                 : /* -------------------------------------------------------------------- */
     559                 : /*      Try to cleanup the output dataset if the translation failed.    */
     560                 : /* -------------------------------------------------------------------- */
     561             220 :     if( eErr != CE_None )
     562                 :     {
     563              19 :         delete poDstDS;
     564              19 :         Delete( pszFilename );
     565              19 :         return NULL;
     566                 :     }
     567                 :     else
     568             201 :         CPLErrorReset();
     569                 : 
     570             201 :     return poDstDS;
     571                 : }
     572                 : 
     573                 : /************************************************************************/
     574                 : /*                             CreateCopy()                             */
     575                 : /************************************************************************/
     576                 : 
     577                 : /**
     578                 :  * \brief Create a copy of a dataset.
     579                 :  *
     580                 :  * This method will attempt to create a copy of a raster dataset with the
     581                 :  * indicated filename, and in this drivers format.  Band number, size, 
     582                 :  * type, projection, geotransform and so forth are all to be copied from
     583                 :  * the provided template dataset.  
     584                 :  *
     585                 :  * Note that many sequential write once formats (such as JPEG and PNG) don't
     586                 :  * implement the Create() method but do implement this CreateCopy() method.
     587                 :  * If the driver doesn't implement CreateCopy(), but does implement Create()
     588                 :  * then the default CreateCopy() mechanism built on calling Create() will
     589                 :  * be used.                                                             
     590                 :  *
     591                 :  * It is intended that CreateCopy() will often be used with a source dataset
     592                 :  * which is a virtual dataset allowing configuration of band types, and
     593                 :  * other information without actually duplicating raster data (see the VRT driver).
     594                 :  * This is what is done by the gdal_translate utility for example.
     595                 :  *
     596                 :  * That function will try to validate the creation option list passed to the driver
     597                 :  * with the GDALValidateCreationOptions() method. This check can be disabled
     598                 :  * by defining the configuration option GDAL_VALIDATE_CREATION_OPTIONS=NO.
     599                 :  *
     600                 :  * After you have finished working with the returned dataset, it is <b>required</b>
     601                 :  * to close it with GDALClose(). This does not only close the file handle, but
     602                 :  * also ensures that all the data and metadata has been written to the dataset
     603                 :  * (GDALFlushCache() is not sufficient for that purpose).
     604                 :  *
     605                 :  * In some situations, the new dataset can be created in another process through the
     606                 :  * \ref gdal_api_proxy mechanism.
     607                 :  *
     608                 :  * @param pszFilename the name for the new dataset.  UTF-8 encoded.
     609                 :  * @param poSrcDS the dataset being duplicated. 
     610                 :  * @param bStrict TRUE if the copy must be strictly equivelent, or more
     611                 :  * normally FALSE indicating that the copy may adapt as needed for the 
     612                 :  * output format. 
     613                 :  * @param papszOptions additional format dependent options controlling 
     614                 :  * creation of the output file. 
     615                 :  * @param pfnProgress a function to be used to report progress of the copy.
     616                 :  * @param pProgressData application data passed into progress function.
     617                 :  *
     618                 :  * @return a pointer to the newly created dataset (may be read-only access).
     619                 :  */
     620                 : 
     621            2270 : GDALDataset *GDALDriver::CreateCopy( const char * pszFilename, 
     622                 :                                      GDALDataset * poSrcDS, 
     623                 :                                      int bStrict, char ** papszOptions,
     624                 :                                      GDALProgressFunc pfnProgress,
     625                 :                                      void * pProgressData )
     626                 : 
     627                 : {
     628            2270 :     CPLLocaleC  oLocaleForcer;
     629                 : 
     630            2270 :     if( pfnProgress == NULL )
     631            1755 :         pfnProgress = GDALDummyProgress;
     632                 : 
     633            2270 :     const char* pszClientFilename = GDALClientDatasetGetFilename(pszFilename);
     634            2273 :     if( pszClientFilename != NULL && !EQUAL(GetDescription(), "MEM") &&
     635               3 :         !EQUAL(GetDescription(), "VRT") )
     636                 :     {
     637               3 :         GDALDriver* poAPIPROXYDriver = GDALGetAPIPROXYDriver();
     638               3 :         if( poAPIPROXYDriver != this )
     639                 :         {
     640               3 :             if( poAPIPROXYDriver->pfnCreateCopy == NULL )
     641               0 :                 return NULL;
     642               3 :             char** papszOptionsDup = CSLDuplicate(papszOptions);
     643                 :             papszOptionsDup = CSLAddNameValue(papszOptionsDup, "SERVER_DRIVER",
     644               3 :                                                GetDescription());
     645                 :             GDALDataset* poDstDS = poAPIPROXYDriver->pfnCreateCopy(
     646                 :                 pszClientFilename, poSrcDS, bStrict, papszOptionsDup,
     647               3 :                 pfnProgress, pProgressData);
     648               3 :             if( poDstDS != NULL )
     649                 :             {
     650               6 :                 if( poDstDS->GetDescription() == NULL 
     651               3 :                     || strlen(poDstDS->GetDescription()) == 0 )
     652               0 :                     poDstDS->SetDescription( pszFilename );
     653                 : 
     654               3 :                 if( poDstDS->poDriver == NULL )
     655               0 :                     poDstDS->poDriver = poAPIPROXYDriver;
     656                 :             }
     657                 : 
     658               3 :             CSLDestroy(papszOptionsDup);
     659               3 :             return poDstDS;
     660                 :         }
     661                 :     }
     662                 : 
     663                 : /* -------------------------------------------------------------------- */
     664                 : /*      Make sure we cleanup if there is an existing dataset of this    */
     665                 : /*      name.  But even if that seems to fail we will continue since    */
     666                 : /*      it might just be a corrupt file or something.                   */
     667                 : /* -------------------------------------------------------------------- */
     668            2267 :     if( !CSLFetchBoolean(papszOptions, "APPEND_SUBDATASET", FALSE) )
     669            2267 :         QuietDelete( pszFilename );
     670                 : 
     671                 : /* -------------------------------------------------------------------- */
     672                 : /*      Validate creation options.                                      */
     673                 : /* -------------------------------------------------------------------- */
     674            2267 :     if (CSLTestBoolean(CPLGetConfigOption("GDAL_VALIDATE_CREATION_OPTIONS", "YES")))
     675            2267 :         GDALValidateCreationOptions( this, papszOptions);
     676                 : 
     677                 : /* -------------------------------------------------------------------- */
     678                 : /*      If the format provides a CreateCopy() method use that,          */
     679                 : /*      otherwise fallback to the internal implementation using the     */
     680                 : /*      Create() method.                                                */
     681                 : /* -------------------------------------------------------------------- */
     682            2267 :     if( pfnCreateCopy != NULL )
     683                 :     {
     684                 :         GDALDataset *poDstDS;
     685                 : 
     686                 :         poDstDS = pfnCreateCopy( pszFilename, poSrcDS, bStrict, papszOptions,
     687            1688 :                                  pfnProgress, pProgressData );
     688            1688 :         if( poDstDS != NULL )
     689                 :         {
     690            1940 :             if( poDstDS->GetDescription() == NULL 
     691             970 :                 || strlen(poDstDS->GetDescription()) == 0 )
     692              21 :                 poDstDS->SetDescription( pszFilename );
     693                 : 
     694             970 :             if( poDstDS->poDriver == NULL )
     695             350 :                 poDstDS->poDriver = this;
     696                 :         }
     697                 : 
     698            1688 :         return poDstDS;
     699                 :     }
     700                 :     else
     701                 :         return DefaultCreateCopy( pszFilename, poSrcDS, bStrict, 
     702             579 :                                   papszOptions, pfnProgress, pProgressData );
     703                 : }
     704                 : 
     705                 : /************************************************************************/
     706                 : /*                           GDALCreateCopy()                           */
     707                 : /************************************************************************/
     708                 : 
     709                 : /**
     710                 :  * \brief Create a copy of a dataset.
     711                 :  *
     712                 :  * @see GDALDriver::CreateCopy()
     713                 :  */
     714                 : 
     715            2227 : GDALDatasetH CPL_STDCALL GDALCreateCopy( GDALDriverH hDriver, 
     716                 :                              const char * pszFilename, 
     717                 :                              GDALDatasetH hSrcDS, 
     718                 :                              int bStrict, char ** papszOptions,
     719                 :                              GDALProgressFunc pfnProgress,
     720                 :                              void * pProgressData )
     721                 : 
     722                 : {
     723            2227 :     VALIDATE_POINTER1( hDriver, "GDALCreateCopy", NULL );
     724            2227 :     VALIDATE_POINTER1( hSrcDS, "GDALCreateCopy", NULL );
     725                 :     
     726                 :     return (GDALDatasetH) ((GDALDriver *) hDriver)->
     727                 :         CreateCopy( pszFilename, (GDALDataset *) hSrcDS, bStrict, papszOptions,
     728            2227 :                     pfnProgress, pProgressData );
     729                 : }
     730                 : 
     731                 : /************************************************************************/
     732                 : /*                            QuietDelete()                             */
     733                 : /************************************************************************/
     734                 : 
     735                 : /**
     736                 :  * \brief Delete dataset if found.
     737                 :  *
     738                 :  * This is a helper method primarily used by Create() and
     739                 :  * CreateCopy() to predelete any dataset of the name soon to be
     740                 :  * created.  It will attempt to delete the named dataset if
     741                 :  * one is found, otherwise it does nothing.  An error is only
     742                 :  * returned if the dataset is found but the delete fails.
     743                 :  *
     744                 :  * This is a static method and it doesn't matter what driver instance
     745                 :  * it is invoked on.  It will attempt to discover the correct driver
     746                 :  * using Identify().
     747                 :  *
     748                 :  * @param pszName the dataset name to try and delete.
     749                 :  * @return CE_None if the dataset does not exist, or is deleted without issues.
     750                 :  */
     751                 : 
     752           10357 : CPLErr GDALDriver::QuietDelete( const char *pszName )
     753                 : 
     754                 : {
     755           10357 :     GDALDriver *poDriver = (GDALDriver*) GDALIdentifyDriver( pszName, NULL );
     756                 : 
     757           10357 :     if( poDriver == NULL )
     758           10099 :         return CE_None;
     759                 : 
     760             258 :     CPLDebug( "GDAL", "QuietDelete(%s) invoking Delete()", pszName );
     761                 : 
     762             258 :     return poDriver->Delete( pszName );
     763                 : }
     764                 : 
     765                 : /************************************************************************/
     766                 : /*                               Delete()                               */
     767                 : /************************************************************************/
     768                 : 
     769                 : /**
     770                 :  * \brief Delete named dataset.
     771                 :  *
     772                 :  * The driver will attempt to delete the named dataset in a driver specific
     773                 :  * fashion.  Full featured drivers will delete all associated files,
     774                 :  * database objects, or whatever is appropriate.  The default behaviour when
     775                 :  * no driver specific behaviour is provided is to attempt to delete the
     776                 :  * passed name as a single file.
     777                 :  *
     778                 :  * It is unwise to have open dataset handles on this dataset when it is
     779                 :  * deleted.
     780                 :  *
     781                 :  * Equivelent of the C function GDALDeleteDataset().
     782                 :  *
     783                 :  * @param pszFilename name of dataset to delete.
     784                 :  *
     785                 :  * @return CE_None on success, or CE_Failure if the operation fails.
     786                 :  */
     787                 : 
     788            1611 : CPLErr GDALDriver::Delete( const char * pszFilename )
     789                 : 
     790                 : {
     791            1611 :     if( pfnDelete != NULL )
     792             169 :         return pfnDelete( pszFilename );
     793                 : 
     794                 : /* -------------------------------------------------------------------- */
     795                 : /*      Collect file list.                                              */
     796                 : /* -------------------------------------------------------------------- */
     797            1442 :     GDALDatasetH hDS = (GDALDataset *) GDALOpen(pszFilename,GA_ReadOnly);
     798                 :         
     799            1442 :     if( hDS == NULL )
     800                 :     {
     801               8 :         if( CPLGetLastErrorNo() == 0 )
     802                 :             CPLError( CE_Failure, CPLE_OpenFailed, 
     803               0 :                       "Unable to open %s to obtain file list.", pszFilename );
     804                 : 
     805               8 :         return CE_Failure;
     806                 :     }
     807                 : 
     808            1434 :     char **papszFileList = GDALGetFileList( hDS );
     809                 :         
     810            1434 :     GDALClose( hDS );
     811                 : 
     812            1434 :     if( CSLCount( papszFileList ) == 0 )
     813                 :     {
     814                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     815                 :                   "Unable to determine files associated with %s,\n"
     816               0 :                   "delete fails.", pszFilename );
     817                 : 
     818               0 :         return CE_Failure;
     819                 :     }
     820                 : 
     821                 : /* -------------------------------------------------------------------- */
     822                 : /*      Delete all files.                                               */
     823                 : /* -------------------------------------------------------------------- */
     824                 :     int i;
     825                 : 
     826            3245 :     for( i = 0; papszFileList[i] != NULL; i++ )
     827                 :     {
     828            1811 :         if( VSIUnlink( papszFileList[i] ) != 0 )
     829                 :         {
     830                 :             CPLError( CE_Failure, CPLE_AppDefined,
     831                 :                       "Deleting %s failed:\n%s",
     832                 :                       papszFileList[i],
     833               0 :                       VSIStrerror(errno) );
     834               0 :             CSLDestroy( papszFileList );
     835               0 :             return CE_Failure;
     836                 :         }
     837                 :     }
     838                 : 
     839            1434 :     CSLDestroy( papszFileList );
     840                 : 
     841            1434 :     return CE_None;
     842                 : }
     843                 : 
     844                 : /************************************************************************/
     845                 : /*                         GDALDeleteDataset()                          */
     846                 : /************************************************************************/
     847                 : 
     848                 : /**
     849                 :  * \brief Delete named dataset.
     850                 :  *
     851                 :  * @see GDALDriver::Delete()
     852                 :  */
     853                 : 
     854            1328 : CPLErr CPL_STDCALL GDALDeleteDataset( GDALDriverH hDriver, const char * pszFilename )
     855                 : 
     856                 : {
     857            1328 :     if( hDriver == NULL )
     858               0 :         hDriver = GDALIdentifyDriver( pszFilename, NULL );
     859                 : 
     860            1328 :     if( hDriver == NULL )
     861                 :     {
     862                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     863                 :                   "No identifiable driver for %s.",
     864               0 :                   pszFilename );
     865               0 :         return CE_Failure;
     866                 :     }
     867                 : 
     868            1328 :     return ((GDALDriver *) hDriver)->Delete( pszFilename );
     869                 : }
     870                 : 
     871                 : /************************************************************************/
     872                 : /*                           DefaultRename()                            */
     873                 : /*                                                                      */
     874                 : /*      The generic implementation based on the file list used when     */
     875                 : /*      there is no format specific implementation.                     */
     876                 : /************************************************************************/
     877                 : 
     878               1 : CPLErr GDALDriver::DefaultRename( const char * pszNewName, 
     879                 :                                   const char *pszOldName )
     880                 : 
     881                 : {
     882                 : /* -------------------------------------------------------------------- */
     883                 : /*      Collect file list.                                              */
     884                 : /* -------------------------------------------------------------------- */
     885               1 :     GDALDatasetH hDS = (GDALDataset *) GDALOpen(pszOldName,GA_ReadOnly);
     886                 :         
     887               1 :     if( hDS == NULL )
     888                 :     {
     889               0 :         if( CPLGetLastErrorNo() == 0 )
     890                 :             CPLError( CE_Failure, CPLE_OpenFailed, 
     891               0 :                       "Unable to open %s to obtain file list.", pszOldName );
     892                 : 
     893               0 :         return CE_Failure;
     894                 :     }
     895                 : 
     896               1 :     char **papszFileList = GDALGetFileList( hDS );
     897                 :         
     898               1 :     GDALClose( hDS );
     899                 : 
     900               1 :     if( CSLCount( papszFileList ) == 0 )
     901                 :     {
     902                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     903                 :                   "Unable to determine files associated with %s,\n"
     904               0 :                   "rename fails.", pszOldName );
     905                 : 
     906               0 :         return CE_Failure;
     907                 :     }
     908                 : 
     909                 : /* -------------------------------------------------------------------- */
     910                 : /*      Produce a list of new filenames that correspond to the old      */
     911                 : /*      names.                                                          */
     912                 : /* -------------------------------------------------------------------- */
     913               1 :     CPLErr eErr = CE_None;
     914                 :     int i;
     915                 :     char **papszNewFileList = 
     916               1 :         CPLCorrespondingPaths( pszOldName, pszNewName, papszFileList );
     917                 : 
     918               1 :     if( papszNewFileList == NULL )
     919               0 :         return CE_Failure;
     920                 : 
     921               5 :     for( i = 0; papszFileList[i] != NULL; i++ )
     922                 :     {
     923               4 :         if( CPLMoveFile( papszNewFileList[i], papszFileList[i] ) != 0 )
     924                 :         {
     925               0 :             eErr = CE_Failure;
     926                 :             // Try to put the ones we moved back. 
     927               0 :             for( --i; i >= 0; i-- )
     928               0 :                 CPLMoveFile( papszFileList[i], papszNewFileList[i] );
     929               0 :             break;
     930                 :         }
     931                 :     }
     932                 : 
     933               1 :     CSLDestroy( papszNewFileList );
     934               1 :     CSLDestroy( papszFileList );
     935                 : 
     936               1 :     return eErr;
     937                 : }
     938                 : 
     939                 : /************************************************************************/
     940                 : /*                               Rename()                               */
     941                 : /************************************************************************/
     942                 : 
     943                 : /**
     944                 :  * \brief Rename a dataset.
     945                 :  *
     946                 :  * Rename a dataset. This may including moving the dataset to a new directory
     947                 :  * or even a new filesystem.  
     948                 :  *
     949                 :  * It is unwise to have open dataset handles on this dataset when it is
     950                 :  * being renamed. 
     951                 :  *
     952                 :  * Equivelent of the C function GDALRenameDataset().
     953                 :  *
     954                 :  * @param pszNewName new name for the dataset.
     955                 :  * @param pszOldName old name for the dataset.
     956                 :  *
     957                 :  * @return CE_None on success, or CE_Failure if the operation fails.
     958                 :  */
     959                 : 
     960               1 : CPLErr GDALDriver::Rename( const char * pszNewName, const char *pszOldName )
     961                 : 
     962                 : {
     963               1 :     if( pfnRename != NULL )
     964               1 :         return pfnRename( pszNewName, pszOldName );
     965                 :     else
     966               0 :         return DefaultRename( pszNewName, pszOldName );
     967                 : }
     968                 : 
     969                 : /************************************************************************/
     970                 : /*                         GDALRenameDataset()                          */
     971                 : /************************************************************************/
     972                 : 
     973                 : /**
     974                 :  * \brief Rename a dataset.
     975                 :  *
     976                 :  * @see GDALDriver::Rename()
     977                 :  */
     978                 : 
     979               1 : CPLErr CPL_STDCALL GDALRenameDataset( GDALDriverH hDriver, 
     980                 :                                       const char * pszNewName,
     981                 :                                       const char * pszOldName )
     982                 : 
     983                 : {
     984               1 :     if( hDriver == NULL )
     985               0 :         hDriver = GDALIdentifyDriver( pszOldName, NULL );
     986                 :     
     987               1 :     if( hDriver == NULL )
     988                 :     {
     989                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     990                 :                   "No identifiable driver for %s.",
     991               0 :                   pszOldName );
     992               0 :         return CE_Failure;
     993                 :     }
     994                 : 
     995               1 :     return ((GDALDriver *) hDriver)->Rename( pszNewName, pszOldName );
     996                 : }
     997                 : 
     998                 : /************************************************************************/
     999                 : /*                          DefaultCopyFiles()                          */
    1000                 : /*                                                                      */
    1001                 : /*      The default implementation based on file lists used when        */
    1002                 : /*      there is no format specific implementation.                     */
    1003                 : /************************************************************************/
    1004                 : 
    1005               1 : CPLErr GDALDriver::DefaultCopyFiles( const char * pszNewName, 
    1006                 :                                      const char *pszOldName )
    1007                 : 
    1008                 : {
    1009                 : /* -------------------------------------------------------------------- */
    1010                 : /*      Collect file list.                                              */
    1011                 : /* -------------------------------------------------------------------- */
    1012               1 :     GDALDatasetH hDS = (GDALDataset *) GDALOpen(pszOldName,GA_ReadOnly);
    1013                 :         
    1014               1 :     if( hDS == NULL )
    1015                 :     {
    1016               0 :         if( CPLGetLastErrorNo() == 0 )
    1017                 :             CPLError( CE_Failure, CPLE_OpenFailed, 
    1018               0 :                       "Unable to open %s to obtain file list.", pszOldName );
    1019                 : 
    1020               0 :         return CE_Failure;
    1021                 :     }
    1022                 : 
    1023               1 :     char **papszFileList = GDALGetFileList( hDS );
    1024                 :         
    1025               1 :     GDALClose( hDS );
    1026                 : 
    1027               1 :     if( CSLCount( papszFileList ) == 0 )
    1028                 :     {
    1029                 :         CPLError( CE_Failure, CPLE_NotSupported, 
    1030                 :                   "Unable to determine files associated with %s,\n"
    1031               0 :                   "rename fails.", pszOldName );
    1032                 : 
    1033               0 :         return CE_Failure;
    1034                 :     }
    1035                 : 
    1036                 : /* -------------------------------------------------------------------- */
    1037                 : /*      Produce a list of new filenames that correspond to the old      */
    1038                 : /*      names.                                                          */
    1039                 : /* -------------------------------------------------------------------- */
    1040               1 :     CPLErr eErr = CE_None;
    1041                 :     int i;
    1042                 :     char **papszNewFileList = 
    1043               1 :         CPLCorrespondingPaths( pszOldName, pszNewName, papszFileList );
    1044                 : 
    1045               1 :     if( papszNewFileList == NULL )
    1046               0 :         return CE_Failure;
    1047                 : 
    1048               5 :     for( i = 0; papszFileList[i] != NULL; i++ )
    1049                 :     {
    1050               4 :         if( CPLCopyFile( papszNewFileList[i], papszFileList[i] ) != 0 )
    1051                 :         {
    1052               0 :             eErr = CE_Failure;
    1053                 :             // Try to put the ones we moved back. 
    1054               0 :             for( --i; i >= 0; i-- )
    1055               0 :                 VSIUnlink( papszNewFileList[i] );
    1056               0 :             break;
    1057                 :         }
    1058                 :     }
    1059                 : 
    1060               1 :     CSLDestroy( papszNewFileList );
    1061               1 :     CSLDestroy( papszFileList );
    1062                 : 
    1063               1 :     return eErr;
    1064                 : }
    1065                 : 
    1066                 : /************************************************************************/
    1067                 : /*                             CopyFiles()                              */
    1068                 : /************************************************************************/
    1069                 : 
    1070                 : /**
    1071                 :  * \brief Copy the files of a dataset.
    1072                 :  *
    1073                 :  * Copy all the files associated with a dataset.
    1074                 :  *
    1075                 :  * Equivelent of the C function GDALCopyDatasetFiles().
    1076                 :  *
    1077                 :  * @param pszNewName new name for the dataset.
    1078                 :  * @param pszOldName old name for the dataset.
    1079                 :  *
    1080                 :  * @return CE_None on success, or CE_Failure if the operation fails.
    1081                 :  */
    1082                 : 
    1083               1 : CPLErr GDALDriver::CopyFiles( const char * pszNewName, const char *pszOldName )
    1084                 : 
    1085                 : {
    1086               1 :     if( pfnCopyFiles != NULL )
    1087               1 :         return pfnCopyFiles( pszNewName, pszOldName );
    1088                 :     else
    1089               0 :         return DefaultCopyFiles( pszNewName, pszOldName );
    1090                 : }
    1091                 : 
    1092                 : /************************************************************************/
    1093                 : /*                        GDALCopyDatasetFiles()                        */
    1094                 : /************************************************************************/
    1095                 : 
    1096                 : /**
    1097                 :  * \brief Copy the files of a dataset.
    1098                 :  *
    1099                 :  * @see GDALDriver::CopyFiles()
    1100                 :  */
    1101                 : 
    1102               1 : CPLErr CPL_STDCALL GDALCopyDatasetFiles( GDALDriverH hDriver, 
    1103                 :                                          const char * pszNewName,
    1104                 :                                          const char * pszOldName )
    1105                 : 
    1106                 : {
    1107               1 :     if( hDriver == NULL )
    1108               0 :         hDriver = GDALIdentifyDriver( pszOldName, NULL );
    1109                 :     
    1110               1 :     if( hDriver == NULL )
    1111                 :     {
    1112                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1113                 :                   "No identifiable driver for %s.",
    1114               0 :                   pszOldName );
    1115               0 :         return CE_Failure;
    1116                 :     }
    1117                 : 
    1118               1 :     return ((GDALDriver *) hDriver)->CopyFiles( pszNewName, pszOldName );
    1119                 : }
    1120                 : 
    1121                 : /************************************************************************/
    1122                 : /*                       GDALGetDriverShortName()                       */
    1123                 : /************************************************************************/
    1124                 : 
    1125                 : /**
    1126                 :  * \brief Return the short name of a driver
    1127                 :  *
    1128                 :  * This is the string that can be
    1129                 :  * passed to the GDALGetDriverByName() function.
    1130                 :  *
    1131                 :  * For the GeoTIFF driver, this is "GTiff"
    1132                 :  *
    1133                 :  * @param hDriver the handle of the driver
    1134                 :  * @return the short name of the driver. The
    1135                 :  *         returned string should not be freed and is owned by the driver.
    1136                 :  */
    1137                 : 
    1138           26505 : const char * CPL_STDCALL GDALGetDriverShortName( GDALDriverH hDriver )
    1139                 : 
    1140                 : {
    1141           26505 :     VALIDATE_POINTER1( hDriver, "GDALGetDriverShortName", NULL );
    1142                 : 
    1143           26505 :     return ((GDALDriver *) hDriver)->GetDescription();
    1144                 : }
    1145                 : 
    1146                 : /************************************************************************/
    1147                 : /*                       GDALGetDriverLongName()                        */
    1148                 : /************************************************************************/
    1149                 : 
    1150                 : /**
    1151                 :  * \brief Return the long name of a driver
    1152                 :  *
    1153                 :  * For the GeoTIFF driver, this is "GeoTIFF"
    1154                 :  *
    1155                 :  * @param hDriver the handle of the driver
    1156                 :  * @return the long name of the driver or empty string. The
    1157                 :  *         returned string should not be freed and is owned by the driver.
    1158                 :  */
    1159                 : 
    1160             169 : const char * CPL_STDCALL GDALGetDriverLongName( GDALDriverH hDriver )
    1161                 : 
    1162                 : {
    1163             169 :     VALIDATE_POINTER1( hDriver, "GDALGetDriverLongName", NULL );
    1164                 : 
    1165                 :     const char *pszLongName = 
    1166             169 :         ((GDALDriver *) hDriver)->GetMetadataItem( GDAL_DMD_LONGNAME );
    1167                 : 
    1168             169 :     if( pszLongName == NULL )
    1169               0 :         return "";
    1170                 :     else
    1171             169 :         return pszLongName;
    1172                 : }
    1173                 : 
    1174                 : /************************************************************************/
    1175                 : /*                       GDALGetDriverHelpTopic()                       */
    1176                 : /************************************************************************/
    1177                 : 
    1178                 : /**
    1179                 :  * \brief Return the URL to the help that describes the driver
    1180                 :  *
    1181                 :  * That URL is relative to the GDAL documentation directory.
    1182                 :  *
    1183                 :  * For the GeoTIFF driver, this is "frmt_gtiff.html"
    1184                 :  *
    1185                 :  * @param hDriver the handle of the driver
    1186                 :  * @return the URL to the help that describes the driver or NULL. The
    1187                 :  *         returned string should not be freed and is owned by the driver.
    1188                 :  */
    1189                 : 
    1190               0 : const char * CPL_STDCALL GDALGetDriverHelpTopic( GDALDriverH hDriver )
    1191                 : 
    1192                 : {
    1193               0 :     VALIDATE_POINTER1( hDriver, "GDALGetDriverHelpTopic", NULL );
    1194                 : 
    1195               0 :     return ((GDALDriver *) hDriver)->GetMetadataItem( GDAL_DMD_HELPTOPIC );
    1196                 : }
    1197                 : 
    1198                 : /************************************************************************/
    1199                 : /*                   GDALGetDriverCreationOptionList()                  */
    1200                 : /************************************************************************/
    1201                 : 
    1202                 : /**
    1203                 :  * \brief Return the list of creation options of the driver
    1204                 :  *
    1205                 :  * Return the list of creation options of the driver used by Create() and
    1206                 :  * CreateCopy() as an XML string
    1207                 :  *
    1208                 :  * @param hDriver the handle of the driver
    1209                 :  * @return an XML string that describes the list of creation options or
    1210                 :  *         empty string. The returned string should not be freed and is
    1211                 :  *         owned by the driver.
    1212                 :  */
    1213                 : 
    1214               0 : const char * CPL_STDCALL GDALGetDriverCreationOptionList( GDALDriverH hDriver )
    1215                 : 
    1216                 : {
    1217               0 :     VALIDATE_POINTER1( hDriver, "GDALGetDriverCreationOptionList", NULL );
    1218                 : 
    1219                 :     const char *pszOptionList = 
    1220               0 :         ((GDALDriver *) hDriver)->GetMetadataItem( GDAL_DMD_CREATIONOPTIONLIST );
    1221                 : 
    1222               0 :     if( pszOptionList == NULL )
    1223               0 :         return "";
    1224                 :     else
    1225               0 :         return pszOptionList;
    1226                 : }
    1227                 : 
    1228                 : /************************************************************************/
    1229                 : /*                   GDALValidateCreationOptions()                      */
    1230                 : /************************************************************************/
    1231                 : 
    1232                 : /**
    1233                 :  * \brief Validate the list of creation options that are handled by a driver
    1234                 :  *
    1235                 :  * This is a helper method primarily used by Create() and
    1236                 :  * CreateCopy() to validate that the passed in list of creation options
    1237                 :  * is compatible with the GDAL_DMD_CREATIONOPTIONLIST metadata item defined
    1238                 :  * by some drivers. @see GDALGetDriverCreationOptionList()
    1239                 :  *
    1240                 :  * If the GDAL_DMD_CREATIONOPTIONLIST metadata item is not defined, this
    1241                 :  * function will return TRUE. Otherwise it will check that the keys and values
    1242                 :  * in the list of creation options are compatible with the capabilities declared
    1243                 :  * by the GDAL_DMD_CREATIONOPTIONLIST metadata item. In case of incompatibility
    1244                 :  * a (non fatal) warning will be emited and FALSE will be returned.
    1245                 :  *
    1246                 :  * @param hDriver the handle of the driver with whom the lists of creation option
    1247                 :  *                must be validated
    1248                 :  * @param papszCreationOptions the list of creation options. An array of strings,
    1249                 :  *                             whose last element is a NULL pointer
    1250                 :  * @return TRUE if the list of creation options is compatible with the Create()
    1251                 :  *         and CreateCopy() method of the driver, FALSE otherwise.
    1252                 :  */
    1253                 : 
    1254           10355 : int CPL_STDCALL GDALValidateCreationOptions( GDALDriverH hDriver,
    1255                 :                                              char** papszCreationOptions)
    1256                 : {
    1257           10355 :     int bRet = TRUE;
    1258           10355 :     VALIDATE_POINTER1( hDriver, "GDALValidateCreationOptions", FALSE );
    1259                 : 
    1260                 :     const char *pszOptionList = 
    1261           10355 :         ((GDALDriver *) hDriver)->GetMetadataItem( GDAL_DMD_CREATIONOPTIONLIST );
    1262                 : 
    1263           10355 :     if( papszCreationOptions == NULL || *papszCreationOptions == NULL)
    1264            9844 :         return TRUE;
    1265             511 :     if( pszOptionList == NULL )
    1266              23 :         return TRUE;
    1267                 :     
    1268             488 :     CPLXMLNode* psNode = CPLParseXMLString(pszOptionList);
    1269             488 :     if (psNode == NULL)
    1270                 :     {
    1271                 :         CPLError(CE_Warning, CPLE_AppDefined,
    1272                 :                  "Could not parse creation option list of driver %s. Assuming creation options are valid.",
    1273               0 :                  ((GDALDriver *) hDriver)->GetDescription());
    1274               0 :         return TRUE;
    1275                 :     }
    1276                 : 
    1277            1753 :     while(*papszCreationOptions)
    1278                 :     {
    1279             777 :         char* pszKey = NULL;
    1280             777 :         const char* pszValue = CPLParseNameValue(*papszCreationOptions, &pszKey);
    1281             777 :         if (pszKey == NULL)
    1282                 :         {
    1283                 :             CPLError(CE_Warning, CPLE_NotSupported,
    1284                 :                      "Creation option '%s' is not formatted with the key=value format",
    1285               0 :                      *papszCreationOptions);
    1286               0 :             bRet = FALSE;
    1287                 : 
    1288               0 :             papszCreationOptions ++;
    1289               0 :             continue;
    1290                 :         }
    1291                 : 
    1292             777 :         CPLXMLNode* psChildNode = psNode->psChild;
    1293            8348 :         while(psChildNode)
    1294                 :         {
    1295            7566 :             if (EQUAL(psChildNode->pszValue, "OPTION"))
    1296                 :             {
    1297            7566 :                 const char* pszOptionName = CPLGetXMLValue(psChildNode, "name", "");
    1298                 :                 /* For option names terminated by wildcard (NITF BLOCKA option names for example) */
    1299           15132 :                 if (strlen(pszOptionName) > 0 &&
    1300            7566 :                     pszOptionName[strlen(pszOptionName) - 1] == '*' &&
    1301                 :                     EQUALN(pszOptionName, pszKey, strlen(pszOptionName) - 1))
    1302                 :                 {
    1303               7 :                     break;
    1304                 :                 }
    1305                 : 
    1306            7559 :                 if (EQUAL(pszOptionName, pszKey) ||
    1307                 :                     EQUAL(CPLGetXMLValue(psChildNode, "alias", ""), pszKey))
    1308                 :                 {
    1309             765 :                     break;
    1310                 :                 }
    1311                 :             }
    1312            6794 :             psChildNode = psChildNode->psNext;
    1313                 :         }
    1314             777 :         if (psChildNode == NULL)
    1315                 :         {
    1316                 :             CPLError(CE_Warning, CPLE_NotSupported,
    1317                 :                      "Driver %s does not support %s creation option",
    1318               5 :                      ((GDALDriver *) hDriver)->GetDescription(),
    1319              10 :                      pszKey);
    1320               5 :             CPLFree(pszKey);
    1321               5 :             bRet = FALSE;
    1322                 : 
    1323               5 :             papszCreationOptions ++;
    1324               5 :             continue;
    1325                 :         }
    1326             772 :         const char* pszType = CPLGetXMLValue(psChildNode, "type", NULL);
    1327             772 :         if (pszType != NULL)
    1328                 :         {
    1329            1046 :             if (EQUAL(pszType, "INT") || EQUAL(pszType, "INTEGER"))
    1330                 :             {
    1331             274 :                 const char* pszValueIter = pszValue;
    1332             971 :                 while (*pszValueIter)
    1333                 :                 {
    1334             423 :                     if (!((*pszValueIter >= '0' && *pszValueIter <= '9') ||
    1335                 :                            *pszValueIter == '+' || *pszValueIter == '-'))
    1336                 :                     {
    1337                 :                         CPLError(CE_Warning, CPLE_NotSupported,
    1338                 :                              "'%s' is an unexpected value for %s creation option of type int.",
    1339               0 :                              pszValue, pszKey);
    1340               0 :                         bRet = FALSE;
    1341               0 :                         break;
    1342                 :                     }
    1343             423 :                     pszValueIter++;
    1344                 :                 }
    1345                 :             }
    1346             498 :             else if (EQUAL(pszType, "UNSIGNED INT"))
    1347                 :             {
    1348               0 :                 const char* pszValueIter = pszValue;
    1349               0 :                 while (*pszValueIter)
    1350                 :                 {
    1351               0 :                     if (!((*pszValueIter >= '0' && *pszValueIter <= '9') ||
    1352                 :                            *pszValueIter == '+'))
    1353                 :                     {
    1354                 :                         CPLError(CE_Warning, CPLE_NotSupported,
    1355                 :                              "'%s' is an unexpected value for %s creation option of type unsigned int.",
    1356               0 :                              pszValue, pszKey);
    1357               0 :                         bRet = FALSE;
    1358               0 :                         break;
    1359                 :                     }
    1360               0 :                     pszValueIter++;
    1361                 :                 }
    1362                 :             }
    1363             498 :             else if (EQUAL(pszType, "FLOAT"))
    1364                 :             {
    1365              23 :                 char* endPtr = NULL;
    1366              23 :                 CPLStrtod(pszValue, &endPtr);
    1367              23 :                 if ( !(endPtr == NULL || *endPtr == '\0') )
    1368                 :                 {
    1369                 :                     CPLError(CE_Warning, CPLE_NotSupported,
    1370                 :                              "'%s' is an unexpected value for %s creation option of type float.",
    1371               0 :                              pszValue, pszKey);
    1372               0 :                     bRet = FALSE;
    1373                 :                 }
    1374                 :             }
    1375             475 :             else if (EQUAL(pszType, "BOOLEAN"))
    1376                 :             {
    1377             120 :                 if (!(EQUAL(pszValue, "ON") || EQUAL(pszValue, "TRUE") || EQUAL(pszValue, "YES") ||
    1378                 :                       EQUAL(pszValue, "OFF") || EQUAL(pszValue, "FALSE") || EQUAL(pszValue, "NO")))
    1379                 :                 {
    1380                 :                     CPLError(CE_Warning, CPLE_NotSupported,
    1381                 :                              "'%s' is an unexpected value for %s creation option of type boolean.",
    1382               0 :                              pszValue, pszKey);
    1383               0 :                     bRet = FALSE;
    1384                 :                 }
    1385                 :             }
    1386             355 :             else if (EQUAL(pszType, "STRING-SELECT"))
    1387                 :             {
    1388             253 :                 int bMatchFound = FALSE;
    1389             253 :                 CPLXMLNode* psStringSelect = psChildNode->psChild;
    1390            1813 :                 while(psStringSelect)
    1391                 :                 {
    1392            1559 :                     if (psStringSelect->eType == CXT_Element &&
    1393                 :                         EQUAL(psStringSelect->pszValue, "Value"))
    1394                 :                     {
    1395             866 :                         CPLXMLNode* psOptionNode = psStringSelect->psChild;
    1396            2347 :                         while(psOptionNode)
    1397                 :                         {
    1398             867 :                             if (psOptionNode->eType == CXT_Text &&
    1399                 :                                 EQUAL(psOptionNode->pszValue, pszValue))
    1400                 :                             {
    1401             252 :                                 bMatchFound = TRUE;
    1402             252 :                                 break;
    1403                 :                             }
    1404             615 :                             psOptionNode = psOptionNode->psNext;
    1405                 :                         }
    1406             866 :                         if (bMatchFound)
    1407             252 :                             break;
    1408                 :                     }
    1409            1307 :                     psStringSelect = psStringSelect->psNext;
    1410                 :                 }
    1411             253 :                 if (!bMatchFound)
    1412                 :                 {
    1413                 :                     CPLError(CE_Warning, CPLE_NotSupported,
    1414                 :                              "'%s' is an unexpected value for %s creation option of type string-select.",
    1415               1 :                              pszValue, pszKey);
    1416               1 :                     bRet = FALSE;
    1417                 :                 }
    1418                 :             }
    1419             102 :             else if (EQUAL(pszType, "STRING"))
    1420                 :             {
    1421             102 :                 const char* pszMaxSize = CPLGetXMLValue(psChildNode, "maxsize", NULL);
    1422             102 :                 if (pszMaxSize != NULL)
    1423                 :                 {
    1424               8 :                     if ((int)strlen(pszValue) > atoi(pszMaxSize))
    1425                 :                     {
    1426                 :                         CPLError(CE_Warning, CPLE_NotSupported,
    1427                 :                              "'%s' is of size %d, whereas maximum size for %s creation option is %d.",
    1428               1 :                              pszValue, (int)strlen(pszValue), pszKey, atoi(pszMaxSize));
    1429               1 :                         bRet = FALSE;
    1430                 :                     }
    1431                 :                 }
    1432                 :             }
    1433                 :             else
    1434                 :             {
    1435                 :                 /* Driver error */
    1436                 :                 CPLError(CE_Warning, CPLE_NotSupported,
    1437                 :                      "Driver %s : type '%s' for %s creation option is not recognized.",
    1438               0 :                      ((GDALDriver *) hDriver)->GetDescription(),
    1439                 :                      pszType,
    1440               0 :                      pszKey);
    1441                 :             }
    1442                 :         }
    1443                 :         else
    1444                 :         {
    1445                 :             /* Driver error */
    1446                 :             CPLError(CE_Warning, CPLE_NotSupported,
    1447                 :                      "Driver %s : no type for %s creation option.",
    1448               0 :                      ((GDALDriver *) hDriver)->GetDescription(),
    1449               0 :                      pszKey);
    1450                 :         }
    1451             772 :         CPLFree(pszKey);
    1452             772 :         papszCreationOptions++;
    1453                 :     }
    1454                 : 
    1455             488 :     CPLDestroyXMLNode(psNode);
    1456             488 :     return bRet;
    1457                 : }
    1458                 : 
    1459                 : /************************************************************************/
    1460                 : /*                         GDALIdentifyDriver()                         */
    1461                 : /************************************************************************/
    1462                 : 
    1463                 : /**
    1464                 :  * \brief Identify the driver that can open a raster file.
    1465                 :  *
    1466                 :  * This function will try to identify the driver that can open the passed file
    1467                 :  * name by invoking the Identify method of each registered GDALDriver in turn. 
    1468                 :  * The first driver that successful identifies the file name will be returned.
    1469                 :  * If all drivers fail then NULL is returned.
    1470                 :  *
    1471                 :  * In order to reduce the need for such searches touch the operating system
    1472                 :  * file system machinery, it is possible to give an optional list of files.
    1473                 :  * This is the list of all files at the same level in the file system as the
    1474                 :  * target file, including the target file. The filenames will not include any
    1475                 :  * path components, are an essentially just the output of CPLReadDir() on the
    1476                 :  * parent directory. If the target object does not have filesystem semantics
    1477                 :  * then the file list should be NULL.
    1478                 :  *
    1479                 :  * @param pszFilename the name of the file to access.  In the case of
    1480                 :  * exotic drivers this may not refer to a physical file, but instead contain
    1481                 :  * information for the driver on how to access a dataset.
    1482                 :  *
    1483                 :  * @param papszFileList an array of strings, whose last element is the NULL pointer.
    1484                 :  * These strings are filenames that are auxiliary to the main filename. The passed
    1485                 :  * value may be NULL.
    1486                 :  *
    1487                 :  * @return A GDALDriverH handle or NULL on failure.  For C++ applications
    1488                 :  * this handle can be cast to a GDALDriver *. 
    1489                 :  */
    1490                 : 
    1491                 : 
    1492                 : GDALDriverH CPL_STDCALL 
    1493           10388 : GDALIdentifyDriver( const char * pszFilename, 
    1494                 :                     char **papszFileList )
    1495                 : 
    1496                 : {
    1497                 :     int           iDriver;
    1498           10388 :     GDALDriverManager  *poDM = GetGDALDriverManager();
    1499           10388 :     GDALOpenInfo        oOpenInfo( pszFilename, GA_ReadOnly, papszFileList );
    1500           10388 :     CPLLocaleC          oLocaleForcer;
    1501                 : 
    1502           10388 :     CPLErrorReset();
    1503           10388 :     CPLAssert( NULL != poDM );
    1504                 :     
    1505         1339566 :     for( iDriver = -1; iDriver < poDM->GetDriverCount(); iDriver++ )
    1506                 :     {
    1507                 :         GDALDriver      *poDriver;
    1508                 :         GDALDataset     *poDS;
    1509                 : 
    1510         1329464 :         if( iDriver < 0 )
    1511           10388 :             poDriver = GDALGetAPIPROXYDriver();
    1512                 :         else
    1513         1319076 :             poDriver = poDM->GetDriver( iDriver );
    1514                 : 
    1515         1329464 :         VALIDATE_POINTER1( poDriver, "GDALIdentifyDriver", NULL );
    1516                 : 
    1517         1329464 :         if( poDriver->pfnIdentify != NULL )
    1518                 :         {
    1519          802159 :             if( poDriver->pfnIdentify( &oOpenInfo ) )
    1520             268 :                 return (GDALDriverH) poDriver;
    1521                 :         }
    1522          527305 :         else if( poDriver->pfnOpen != NULL )
    1523                 :         {
    1524          517050 :             poDS = poDriver->pfnOpen( &oOpenInfo );
    1525          517050 :             if( poDS != NULL )
    1526                 :             {
    1527              18 :                 delete poDS;
    1528              18 :                 return (GDALDriverH) poDriver;
    1529                 :             }
    1530                 : 
    1531          517032 :             if( CPLGetLastErrorNo() != 0 )
    1532               0 :                 return NULL;
    1533                 :         }
    1534                 :     }
    1535                 : 
    1536           10102 :     return NULL;
    1537                 : }

Generated by: LCOV version 1.7