LCOV - code coverage report
Current view: directory - gcore - gdaldriver.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 435 335 77.0 %
Date: 2012-12-26 Functions: 27 23 85.2 %

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

Generated by: LCOV version 1.7