LCOV - code coverage report
Current view: directory - gcore - gdaldriver.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 441 290 65.8 %
Date: 2010-01-09 Functions: 24 17 70.8 %

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

Generated by: LCOV version 1.7