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.1 2000/09/25 20:50:11 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.1  2000/09/25 20:50:11  warmerda
00030  * New
00030  *
00031  * Revision 1.16  2000/07/13 17:34:11  warmerda
00032  * Set description for CopyCreate() method.
00033  *
00034  * Revision 1.15  2000/07/13 17:27:48  warmerda
00035  * added SetDescription after create
00036  *
00037  * Revision 1.14  2000/06/27 16:47:28  warmerda
00038  * added cancel support for CopyCreate progress func
00039  *
00040  * Revision 1.13  2000/06/26 18:47:14  warmerda
00041  * Ensure pszHelpTopic is initialized
00042  *
00043  * Revision 1.12  2000/04/30 23:22:16  warmerda
00044  * added CreateCopy support
00045  *
00046  * Revision 1.11  2000/03/06 02:21:15  warmerda
00047  * Added help topic C function
00048  *
00049  * Revision 1.10  2000/01/31 16:24:01  warmerda
00050  * use failure, not fatal
00051  *
00052  * Revision 1.9  2000/01/31 15:00:25  warmerda
00053  * added some documentation
00054  *
00055  * Revision 1.8  2000/01/31 14:24:36  warmerda
00056  * implemented dataset delete
00057  *
00058  * Revision 1.7  2000/01/13 04:13:10  pgs
00059  * added initialization of pfnCreate = NULL to prevent run-time crash when format doesn't support creating a file
00060  *
00061  * Revision 1.6  1999/12/08 14:40:50  warmerda
00062  * Fixed error message.
00063  *
00064  * Revision 1.5  1999/10/21 13:22:10  warmerda
00065  * Added GDALGetDriverShort/LongName().
00066  *
00067  * Revision 1.4  1999/01/11 15:36:50  warmerda
00068  * Added GDALCreate()
00069  *
00070  * Revision 1.3  1998/12/31 18:54:53  warmerda
00071  * Flesh out create method.
00072  *
00073  * Revision 1.2  1998/12/06 22:17:32  warmerda
00074  * Add stub Create() method
00075  *
00076  * Revision 1.1  1998/12/03 18:32:01  warmerda
00077  * New
00078  *
00079  */
00080 
00081 #include "gdal_priv.h"
00082 
00083 /************************************************************************/
00084 /*                             GDALDriver()                             */
00085 /************************************************************************/
00086 
00087 GDALDriver::GDALDriver()
00088 
00089 {
00090     pszShortName = NULL;
00091     pszLongName = NULL;
00092     pszHelpTopic = NULL;
00093 
00094     pfnOpen = NULL;
00095     pfnCreate = NULL;
00096     pfnDelete = NULL;
00097     pfnCreateCopy = NULL;
00098 }
00099 
00100 /************************************************************************/
00101 /*                            ~GDALDriver()                             */
00102 /************************************************************************/
00103 
00104 GDALDriver::~GDALDriver()
00105 
00106 {
00107 }
00108 
00109 /************************************************************************/
00110 /*                               Create()                               */
00111 /************************************************************************/
00112 
00131 GDALDataset * GDALDriver::Create( const char * pszFilename,
00132                                   int nXSize, int nYSize, int nBands,
00133                                   GDALDataType eType, char ** papszParmList )
00134 
00135 {
00136     /* notdef: should add a bunch of error checking here */
00137 
00138     if( pfnCreate == NULL )
00139     {
00140         CPLError( CE_Failure, CPLE_NotSupported,
00141                   "GDALDriver::Create() ... no create method implemented"
00142                   " for this format.\n" );
00143 
00144         return NULL;
00145     }
00146     else
00147     {
00148         GDALDataset *poDS;
00149 
00150         poDS = pfnCreate( pszFilename, nXSize, nYSize, nBands, eType,
00151                           papszParmList );
00152 
00153         if( poDS != NULL )
00154             poDS->SetDescription( pszFilename );
00155 
00156         return poDS;
00157     }
00158 }
00159 
00160 /************************************************************************/
00161 /*                             GDALCreate()                             */
00162 /************************************************************************/
00163 
00164 GDALDatasetH CPL_DLL GDALCreate( GDALDriverH hDriver,
00165                                  const char * pszFilename,
00166                                  int nXSize, int nYSize, int nBands,
00167                                  GDALDataType eBandType,
00168                                  char ** papszOptions )
00169 
00170 {
00171     return( ((GDALDriver *) hDriver)->Create( pszFilename,
00172                                               nXSize, nYSize, nBands,
00173                                               eBandType, papszOptions ) );
00174 }
00175 
00176 /************************************************************************/
00177 /*                             CreateCopy()                             */
00178 /************************************************************************/
00179 
00213 GDALDataset *GDALDriver::CreateCopy( const char * pszFilename, 
00214                                      GDALDataset * poSrcDS, 
00215                                      int bStrict, char ** papszOptions,
00216                                      GDALProgressFunc pfnProgress,
00217                                      void * pProgressData )
00218 
00219 {
00220     if( pfnProgress == NULL )
00221         pfnProgress = GDALDummyProgress;
00222 
00223 /* -------------------------------------------------------------------- */
00224 /*      If the format provides a CreateCopy() method use that,          */
00225 /*      otherwise fallback to the internal implementation using the     */
00226 /*      Create() method.                                                */
00227 /* -------------------------------------------------------------------- */
00228     if( pfnCreateCopy != NULL )
00229     {
00230         GDALDataset *poDstDS;
00231 
00232         poDstDS = pfnCreateCopy( pszFilename, poSrcDS, bStrict, papszOptions,
00233                                  pfnProgress, pProgressData );
00234         if( poDstDS != NULL )
00235         {
00236             if( poDstDS->GetDescription() == NULL 
00237                 || strlen(poDstDS->GetDescription()) > 0 )
00238                 poDstDS->SetDescription( pszFilename );
00239         }
00240 
00241         return poDstDS;
00242     }
00243     
00244 /* -------------------------------------------------------------------- */
00245 /*      Create destination dataset.                                     */
00246 /* -------------------------------------------------------------------- */
00247     GDALDataset  *poDstDS;
00248     int          nXSize = poSrcDS->GetRasterXSize();
00249     int          nYSize = poSrcDS->GetRasterYSize();
00250     GDALDataType eType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
00251     CPLErr       eErr;
00252 
00253     CPLDebug( "GDAL", "Using default GDALDriver::CreateCopy implementation." );
00254 
00255     if( !pfnProgress( 0.0, NULL, pProgressData ) )
00256     {
00257         CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
00258         return NULL;
00259     }
00260 
00261     poDstDS = Create( pszFilename, nXSize, nYSize, 
00262                       poSrcDS->GetRasterCount(), eType, papszOptions );
00263 
00264     if( poDstDS == NULL )
00265         return NULL;
00266 
00267 /* -------------------------------------------------------------------- */
00268 /*      Try setting the projection and geotransform if it seems         */
00269 /*      suitable.  For now we don't try and copy GCPs, though I         */
00270 /*      suppose we should.                                              */
00271 /* -------------------------------------------------------------------- */
00272     double      adfGeoTransform[6];
00273 
00274     if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None )
00275     {
00276         poDstDS->SetGeoTransform( adfGeoTransform );
00277     }
00278 
00279     if( poSrcDS->GetProjectionRef() != NULL
00280         && strlen(poSrcDS->GetProjectionRef()) > 0 )
00281     {
00282         poDstDS->SetProjection( poSrcDS->GetProjectionRef() );
00283     }
00284 
00285 /* -------------------------------------------------------------------- */
00286 /*      Loop copying bands.                                             */
00287 /* -------------------------------------------------------------------- */
00288     for( int iBand = 0; iBand < poSrcDS->GetRasterCount(); iBand++ )
00289     {
00290         GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( iBand+1 );
00291         GDALRasterBand *poDstBand = poDstDS->GetRasterBand( iBand+1 );
00292 
00293         void           *pData;
00294 
00295         pData = CPLMalloc(nXSize * 8);
00296 
00297         for( int iLine = 0; iLine < nYSize; iLine++ )
00298         {
00299             eErr = poSrcBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, 
00300                                         pData, nXSize, 1, eType, 0, 0 );
00301             if( eErr != CE_None )
00302             {
00303                 return NULL;
00304             }
00305             
00306             eErr = poDstBand->RasterIO( GF_Write, 0, iLine, nXSize, 1, 
00307                                         pData, nXSize, 1, eType, 0, 0 );
00308 
00309             if( eErr != CE_None )
00310             {
00311                 return NULL;
00312             }
00313 
00314             if( !pfnProgress( (iBand + iLine / (double) nYSize)
00315                               / (double) poSrcDS->GetRasterCount(), 
00316                               NULL, pProgressData ) )
00317             {
00318                 CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
00319                 delete poDstDS;
00320                 Delete( pszFilename );
00321                 return NULL;
00322             }
00323         }
00324 
00325         CPLFree( pData );
00326     }
00327 
00328     return poDstDS;
00329 }
00330 
00331 /************************************************************************/
00332 /*                           GDALCreateCopy()                           */
00333 /************************************************************************/
00334 
00335 GDALDatasetH GDALCreateCopy( GDALDriverH hDriver, 
00336                              const char * pszFilename, 
00337                              GDALDatasetH hSrcDS, 
00338                              int bStrict, char ** papszOptions,
00339                              GDALProgressFunc pfnProgress,
00340                              void * pProgressData )
00341 
00342 {
00343     return (GDALDatasetH) ((GDALDriver *) hDriver)->
00344         CreateCopy( pszFilename, (GDALDataset *) hSrcDS, bStrict, papszOptions,
00345                     pfnProgress, pProgressData );
00346 }
00347 
00348 /************************************************************************/
00349 /*                               Delete()                               */
00350 /************************************************************************/
00351 
00371 CPLErr GDALDriver::Delete( const char * pszFilename )
00372 
00373 {
00374     if( pfnDelete != NULL )
00375         return pfnDelete( pszFilename );
00376     else
00377     {
00378         VSIStatBuf      sStat;
00379 
00380         if( VSIStat( pszFilename, &sStat ) == 0 && VSI_ISREG( sStat.st_mode ) )
00381         {
00382             if( VSIUnlink( pszFilename ) == 0 )
00383                 return CE_None;
00384             else
00385             {
00386                 CPLError( CE_Failure, CPLE_AppDefined,
00387                           "%s: Attempt to unlink %s failed.\n",
00388                           pszShortName, pszFilename );
00389                 return CE_Failure;
00390             }
00391         }
00392         else
00393         {
00394             CPLError( CE_Failure, CPLE_AppDefined,
00395                       "%s: Unable to delete %s, not a file.\n",
00396                       pszShortName, pszFilename );
00397             return CE_Failure;
00398         }
00399     }
00400 }
00401 
00402 /************************************************************************/
00403 /*                             GDALDelete()                             */
00404 /************************************************************************/
00405 
00406 CPLErr GDALDeleteDataset( GDALDriverH hDriver, const char * pszFilename )
00407 
00408 {
00409     return ((GDALDriver *) hDriver)->Delete( pszFilename );
00410 }
00411 
00412 /************************************************************************/
00413 /*                       GDALGetDriverShortName()                       */
00414 /************************************************************************/
00415 
00416 const char * GDALGetDriverShortName( GDALDriverH hDriver )
00417 
00418 {
00419     if( hDriver == NULL )
00420         return NULL;
00421     else
00422         return ((GDALDriver *) hDriver)->pszShortName;
00423 }
00424 
00425 /************************************************************************/
00426 /*                       GDALGetDriverLongName()                        */
00427 /************************************************************************/
00428 
00429 const char * GDALGetDriverLongName( GDALDriverH hDriver )
00430 
00431 {
00432     if( hDriver == NULL )
00433         return NULL;
00434     else
00435         return ((GDALDriver *) hDriver)->pszLongName;
00436 }
00437 
00438 /************************************************************************/
00439 /*                       GDALGetDriverHelpTopic()                       */
00440 /************************************************************************/
00441 
00442 const char * GDALGetDriverHelpTopic( GDALDriverH hDriver )
00443 
00444 {
00445     if( hDriver == NULL )
00446         return NULL;
00447     else
00448         return ((GDALDriver *) hDriver)->pszHelpTopic;
00449 }
00450 

doxygen1.2.2 Dimitri van Heesch, © 1997-2000