Main Page Class Hierarchy Compound List File List Compound Members File Members Related Pages

# gdaldriver.cpp

    00001 /******************************************************************************
    00002  * $Id: gdaldriver_cpp-source.html,v 1.8 2001/07/05 13:24:08 warmerda Exp $
    00003  *
    00004  * Project:  GDAL Core
    00005  * Purpose:  Implementation of GDALDriver class (and C wrappers)
    00006  * Author:   Frank Warmerdam, warmerda@home.com
    00007  *
    00008  ******************************************************************************
    00009  * Copyright (c) 1998, 2000, Frank Warmerdam
    00010  *
    00011  * Permission is hereby granted, free of charge, to any person obtaining a
    00012  * copy of this software and associated documentation files (the "Software"),
    00013  * to deal in the Software without restriction, including without limitation
    00014  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    00015  * and/or sell copies of the Software, and to permit persons to whom the
    00016  * Software is furnished to do so, subject to the following conditions:
    00017  *
    00018  * The above copyright notice and this permission notice shall be included
    00019  * in all copies or substantial portions of the Software.
    00020  *
    00021  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    00022  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    00023  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    00024  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    00025  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    00026  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    00027  * DEALINGS IN THE SOFTWARE.
    00028  ******************************************************************************
    00029  *
    00030  * $Log: gdaldriver_cpp-source.html,v $
    00030  * Revision 1.8  2001/07/05 13:24:08  warmerda
    00030  * *** empty log message ***
    00030  *
    00031  * Revision 1.18  2001/02/15 16:30:34  warmerda
    00032  * added create debug message
    00033  *
    00034  * Revision 1.17  2000/10/06 15:26:49  warmerda
    00035  * make buffer size for copying image data the exact size, fixing bug with complex data
    00036  *
    00037  * Revision 1.16  2000/07/13 17:34:11  warmerda
    00038  * Set description for CopyCreate() method.
    00039  *
    00040  * Revision 1.15  2000/07/13 17:27:48  warmerda
    00041  * added SetDescription after create
    00042  *
    00043  * Revision 1.14  2000/06/27 16:47:28  warmerda
    00044  * added cancel support for CopyCreate progress func
    00045  *
    00046  * Revision 1.13  2000/06/26 18:47:14  warmerda
    00047  * Ensure pszHelpTopic is initialized
    00048  *
    00049  * Revision 1.12  2000/04/30 23:22:16  warmerda
    00050  * added CreateCopy support
    00051  *
    00052  * Revision 1.11  2000/03/06 02:21:15  warmerda
    00053  * Added help topic C function
    00054  *
    00055  * Revision 1.10  2000/01/31 16:24:01  warmerda
    00056  * use failure, not fatal
    00057  *
    00058  * Revision 1.9  2000/01/31 15:00:25  warmerda
    00059  * added some documentation
    00060  *
    00061  * Revision 1.8  2000/01/31 14:24:36  warmerda
    00062  * implemented dataset delete
    00063  *
    00064  * Revision 1.7  2000/01/13 04:13:10  pgs
    00065  * added initialization of pfnCreate = NULL to prevent run-time crash when format doesn't support creating a file
    00066  *
    00067  * Revision 1.6  1999/12/08 14:40:50  warmerda
    00068  * Fixed error message.
    00069  *
    00070  * Revision 1.5  1999/10/21 13:22:10  warmerda
    00071  * Added GDALGetDriverShort/LongName().
    00072  *
    00073  * Revision 1.4  1999/01/11 15:36:50  warmerda
    00074  * Added GDALCreate()
    00075  *
    00076  * Revision 1.3  1998/12/31 18:54:53  warmerda
    00077  * Flesh out create method.
    00078  *
    00079  * Revision 1.2  1998/12/06 22:17:32  warmerda
    00080  * Add stub Create() method
    00081  *
    00082  * Revision 1.1  1998/12/03 18:32:01  warmerda
    00083  * New
    00084  *
    00085  */
    00086
    00087 #include "gdal_priv.h"
    00088
    00089 /************************************************************************/
    00090 /*                             GDALDriver()                             */
    00091 /************************************************************************/
    00092
    00093 GDALDriver::GDALDriver()
    00094
    00095 {
    00096     pszShortName = NULL;
    00097     pszLongName = NULL;
    00098     pszHelpTopic = NULL;
    00099
    00100     pfnOpen = NULL;
    00101     pfnCreate = NULL;
    00102     pfnDelete = NULL;
    00103     pfnCreateCopy = NULL;
    00104 }
    00105
    00106 /************************************************************************/
    00107 /*                            ~GDALDriver()                             */
    00108 /************************************************************************/
    00109
    00110 GDALDriver::~GDALDriver()
    00111
    00112 {
    00113 }
    00114
    00115 /************************************************************************/
    00116 /*                               Create()                               */
    00117 /************************************************************************/
    00118
    00137 GDALDataset * GDALDriver::Create( const char * pszFilename,
    00138                                   int nXSize, int nYSize, int nBands,
    00139                                   GDALDataType eType, char ** papszParmList )
    00140
    00141 {
    00142     /* notdef: should add a bunch of error checking here */
    00143
    00144     if( pfnCreate == NULL )
    00145     {
    00146         CPLError( CE_Failure, CPLE_NotSupported,
    00147                   "GDALDriver::Create() ... no create method implemented"
    00148                   " for this format.\n" );
    00149
    00150         return NULL;
    00151     }
    00152     else
    00153     {
    00154         GDALDataset *poDS;
    00155
    00156         CPLDebug( "GDAL", "GDALDriver::Create(%s,%s,%d,%d,%d,%s,%p)",
    00157                   pszShortName, pszFilename, nXSize, nYSize, nBands,
    00158                   GDALGetDataTypeName( eType ),
    00159                   papszParmList );
    00160
    00161         poDS = pfnCreate( pszFilename, nXSize, nYSize, nBands, eType,
    00162                           papszParmList );
    00163
    00164         if( poDS != NULL )
    00165             poDS->SetDescription( pszFilename );
    00166
    00167         return poDS;
    00168     }
    00169 }
    00170
    00171 /************************************************************************/
    00172 /*                             GDALCreate()                             */
    00173 /************************************************************************/
    00174
    00175 GDALDatasetH CPL_DLL GDALCreate( GDALDriverH hDriver,
    00176                                  const char * pszFilename,
    00177                                  int nXSize, int nYSize, int nBands,
    00178                                  GDALDataType eBandType,
    00179                                  char ** papszOptions )
    00180
    00181 {
    00182     return( ((GDALDriver *) hDriver)->Create( pszFilename,
    00183                                               nXSize, nYSize, nBands,
    00184                                               eBandType, papszOptions ) );
    00185 }
    00186
    00187 /************************************************************************/
    00188 /*                             CreateCopy()                             */
    00189 /************************************************************************/
    00190
    00224 GDALDataset *GDALDriver::CreateCopy( const char * pszFilename,
    00225                                      GDALDataset * poSrcDS,
    00226                                      int bStrict, char ** papszOptions,
    00227                                      GDALProgressFunc pfnProgress,
    00228                                      void * pProgressData )
    00229
    00230 {
    00231     if( pfnProgress == NULL )
    00232         pfnProgress = GDALDummyProgress;
    00233
    00234 /* -------------------------------------------------------------------- */
    00235 /*      If the format provides a CreateCopy() method use that,          */
    00236 /*      otherwise fallback to the internal implementation using the     */
    00237 /*      Create() method.                                                */
    00238 /* -------------------------------------------------------------------- */
    00239     if( pfnCreateCopy != NULL )
    00240     {
    00241         GDALDataset *poDstDS;
    00242
    00243         poDstDS = pfnCreateCopy( pszFilename, poSrcDS, bStrict, papszOptions,
    00244                                  pfnProgress, pProgressData );
    00245         if( poDstDS != NULL )
    00246         {
    00247             if( poDstDS->GetDescription() == NULL
    00248                 || strlen(poDstDS->GetDescription()) > 0 )
    00249                 poDstDS->SetDescription( pszFilename );
    00250         }
    00251
    00252         return poDstDS;
    00253     }
    00254
    00255 /* -------------------------------------------------------------------- */
    00256 /*      Create destination dataset.                                     */
    00257 /* -------------------------------------------------------------------- */
    00258     GDALDataset  *poDstDS;
    00259     int          nXSize = poSrcDS->GetRasterXSize();
    00260     int          nYSize = poSrcDS->GetRasterYSize();
    00261     GDALDataType eType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
    00262     CPLErr       eErr;
    00263
    00264     CPLDebug( "GDAL", "Using default GDALDriver::CreateCopy implementation." );
    00265
    00266     if( !pfnProgress( 0.0, NULL, pProgressData ) )
    00267     {
    00268         CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
    00269         return NULL;
    00270     }
    00271
    00272     poDstDS = Create( pszFilename, nXSize, nYSize,
    00273                       poSrcDS->GetRasterCount(), eType, papszOptions );
    00274
    00275     if( poDstDS == NULL )
    00276         return NULL;
    00277
    00278 /* -------------------------------------------------------------------- */
    00279 /*      Try setting the projection and geotransform if it seems         */
    00280 /*      suitable.  For now we don't try and copy GCPs, though I         */
    00281 /*      suppose we should.                                              */
    00282 /* -------------------------------------------------------------------- */
    00283     double      adfGeoTransform[6];
    00284
    00285     if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None )
    00286     {
    00287         poDstDS->SetGeoTransform( adfGeoTransform );
    00288     }
    00289
    00290     if( poSrcDS->GetProjectionRef() != NULL
    00291         && strlen(poSrcDS->GetProjectionRef()) > 0 )
    00292     {
    00293         poDstDS->SetProjection( poSrcDS->GetProjectionRef() );
    00294     }
    00295
    00296 /* -------------------------------------------------------------------- */
    00297 /*      Loop copying bands.                                             */
    00298 /* -------------------------------------------------------------------- */
    00299     for( int iBand = 0; iBand < poSrcDS->GetRasterCount(); iBand++ )
    00300     {
    00301         GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( iBand+1 );
    00302         GDALRasterBand *poDstBand = poDstDS->GetRasterBand( iBand+1 );
    00303
    00304         void           *pData;
    00305
    00306         pData = CPLMalloc(nXSize * GDALGetDataTypeSize(eType) / 8);
    00307
    00308         for( int iLine = 0; iLine < nYSize; iLine++ )
    00309         {
    00310             eErr = poSrcBand->RasterIO( GF_Read, 0, iLine, nXSize, 1,
    00311                                         pData, nXSize, 1, eType, 0, 0 );
    00312             if( eErr != CE_None )
    00313             {
    00314                 return NULL;
    00315             }
    00316
    00317             eErr = poDstBand->RasterIO( GF_Write, 0, iLine, nXSize, 1,
    00318                                         pData, nXSize, 1, eType, 0, 0 );
    00319
    00320             if( eErr != CE_None )
    00321             {
    00322                 return NULL;
    00323             }
    00324
    00325             if( !pfnProgress( (iBand + iLine / (double) nYSize)
    00326                               / (double) poSrcDS->GetRasterCount(),
    00327                               NULL, pProgressData ) )
    00328             {
    00329                 CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
    00330                 delete poDstDS;
    00331                 Delete( pszFilename );
    00332                 return NULL;
    00333             }
    00334         }
    00335
    00336         CPLFree( pData );
    00337     }
    00338
    00339     return poDstDS;
    00340 }
    00341
    00342 /************************************************************************/
    00343 /*                           GDALCreateCopy()                           */
    00344 /************************************************************************/
    00345
    00346 GDALDatasetH GDALCreateCopy( GDALDriverH hDriver,
    00347                              const char * pszFilename,
    00348                              GDALDatasetH hSrcDS,
    00349                              int bStrict, char ** papszOptions,
    00350                              GDALProgressFunc pfnProgress,
    00351                              void * pProgressData )
    00352
    00353 {
    00354     return (GDALDatasetH) ((GDALDriver *) hDriver)->
    00355         CreateCopy( pszFilename, (GDALDataset *) hSrcDS, bStrict, papszOptions,
    00356                     pfnProgress, pProgressData );
    00357 }
    00358
    00359 /************************************************************************/
    00360 /*                               Delete()                               */
    00361 /************************************************************************/
    00362
    00382 CPLErr GDALDriver::Delete( const char * pszFilename )
    00383
    00384 {
    00385     if( pfnDelete != NULL )
    00386         return pfnDelete( pszFilename );
    00387     else
    00388     {
    00389         VSIStatBuf      sStat;
    00390
    00391         if( VSIStat( pszFilename, &sStat ) == 0 && VSI_ISREG( sStat.st_mode ) )
    00392         {
    00393             if( VSIUnlink( pszFilename ) == 0 )
    00394                 return CE_None;
    00395             else
    00396             {
    00397                 CPLError( CE_Failure, CPLE_AppDefined,
    00398                           "%s: Attempt to unlink %s failed.\n",
    00399                           pszShortName, pszFilename );
    00400                 return CE_Failure;
    00401             }
    00402         }
    00403         else
    00404         {
    00405             CPLError( CE_Failure, CPLE_AppDefined,
    00406                       "%s: Unable to delete %s, not a file.\n",
    00407                       pszShortName, pszFilename );
    00408             return CE_Failure;
    00409         }
    00410     }
    00411 }
    00412
    00413 /************************************************************************/
    00414 /*                             GDALDelete()                             */
    00415 /************************************************************************/
    00416
    00417 CPLErr GDALDeleteDataset( GDALDriverH hDriver, const char * pszFilename )
    00418
    00419 {
    00420     return ((GDALDriver *) hDriver)->Delete( pszFilename );
    00421 }
    00422
    00423 /************************************************************************/
    00424 /*                       GDALGetDriverShortName()                       */
    00425 /************************************************************************/
    00426
    00427 const char * GDALGetDriverShortName( GDALDriverH hDriver )
    00428
    00429 {
    00430     if( hDriver == NULL )
    00431         return NULL;
    00432     else
    00433         return ((GDALDriver *) hDriver)->pszShortName;
    00434 }
    00435
    00436 /************************************************************************/
    00437 /*                       GDALGetDriverLongName()                        */
    00438 /************************************************************************/
    00439
    00440 const char * GDALGetDriverLongName( GDALDriverH hDriver )
    00441
    00442 {
    00443     if( hDriver == NULL )
    00444         return NULL;
    00445     else
    00446         return ((GDALDriver *) hDriver)->pszLongName;
    00447 }
    00448
    00449 /************************************************************************/
    00450 /*                       GDALGetDriverHelpTopic()                       */
    00451 /************************************************************************/
    00452
    00453 const char * GDALGetDriverHelpTopic( GDALDriverH hDriver )
    00454
    00455 {
    00456     if( hDriver == NULL )
    00457         return NULL;
    00458     else
    00459         return ((GDALDriver *) hDriver)->pszHelpTopic;
    00460 }
    00461