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

doxygen1.2.3-20001105 Dimitri van Heesch, © 1997-2000