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.10 2002/04/16 13:11:48 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.10  2002/04/16 13:11:48  warmerda
    00030  * updated
    00030  *
    00031  * Revision 1.23  2001/12/15 15:47:54  warmerda
    00032  * don't replace existing descriptions
    00033  *
    00034  * Revision 1.22  2001/12/15 15:42:27  warmerda
    00035  * *** empty log message ***
    00036  *
    00037  * Revision 1.21  2001/10/05 20:35:26  warmerda
    00038  * CreateCopy() won't try to write default geotransform
    00039  *
    00040  * Revision 1.20  2001/09/24 15:58:27  warmerda
    00041  * improved progress reporting in createcopy
    00042  *
    00043  * Revision 1.19  2001/07/18 04:04:30  warmerda
    00044  * added CPL_CVSID
    00045  *
    00046  * Revision 1.18  2001/02/15 16:30:34  warmerda
    00047  * added create debug message
    00048  *
    00049  * Revision 1.17  2000/10/06 15:26:49  warmerda
    00050  * make buffer size for copying image data the exact size, fixing bug with complex data
    00051  *
    00052  * Revision 1.16  2000/07/13 17:34:11  warmerda
    00053  * Set description for CopyCreate() method.
    00054  *
    00055  * Revision 1.15  2000/07/13 17:27:48  warmerda
    00056  * added SetDescription after create
    00057  *
    00058  * Revision 1.14  2000/06/27 16:47:28  warmerda
    00059  * added cancel support for CopyCreate progress func
    00060  *
    00061  * Revision 1.13  2000/06/26 18:47:14  warmerda
    00062  * Ensure pszHelpTopic is initialized
    00063  *
    00064  * Revision 1.12  2000/04/30 23:22:16  warmerda
    00065  * added CreateCopy support
    00066  *
    00067  * Revision 1.11  2000/03/06 02:21:15  warmerda
    00068  * Added help topic C function
    00069  *
    00070  * Revision 1.10  2000/01/31 16:24:01  warmerda
    00071  * use failure, not fatal
    00072  *
    00073  * Revision 1.9  2000/01/31 15:00:25  warmerda
    00074  * added some documentation
    00075  *
    00076  * Revision 1.8  2000/01/31 14:24:36  warmerda
    00077  * implemented dataset delete
    00078  *
    00079  * Revision 1.7  2000/01/13 04:13:10  pgs
    00080  * added initialization of pfnCreate = NULL to prevent run-time crash when format doesn't support creating a file
    00081  *
    00082  * Revision 1.6  1999/12/08 14:40:50  warmerda
    00083  * Fixed error message.
    00084  *
    00085  * Revision 1.5  1999/10/21 13:22:10  warmerda
    00086  * Added GDALGetDriverShort/LongName().
    00087  *
    00088  * Revision 1.4  1999/01/11 15:36:50  warmerda
    00089  * Added GDALCreate()
    00090  *
    00091  * Revision 1.3  1998/12/31 18:54:53  warmerda
    00092  * Flesh out create method.
    00093  *
    00094  * Revision 1.2  1998/12/06 22:17:32  warmerda
    00095  * Add stub Create() method
    00096  *
    00097  * Revision 1.1  1998/12/03 18:32:01  warmerda
    00098  * New
    00099  *
    00100  */
    00101
    00102 #include "gdal_priv.h"
    00103
    00104 CPL_CVSID("$Id: gdaldriver_cpp-source.html,v 1.10 2002/04/16 13:11:48 warmerda Exp $");
    00105
    00106 /************************************************************************/
    00107 /*                             GDALDriver()                             */
    00108 /************************************************************************/
    00109
    00110 GDALDriver::GDALDriver()
    00111
    00112 {
    00113     pszShortName = NULL;
    00114     pszLongName = NULL;
    00115     pszHelpTopic = NULL;
    00116
    00117     pfnOpen = NULL;
    00118     pfnCreate = NULL;
    00119     pfnDelete = NULL;
    00120     pfnCreateCopy = NULL;
    00121 }
    00122
    00123 /************************************************************************/
    00124 /*                            ~GDALDriver()                             */
    00125 /************************************************************************/
    00126
    00127 GDALDriver::~GDALDriver()
    00128
    00129 {
    00130 }
    00131
    00132 /************************************************************************/
    00133 /*                               Create()                               */
    00134 /************************************************************************/
    00135
    00154 GDALDataset * GDALDriver::Create( const char * pszFilename,
    00155                                   int nXSize, int nYSize, int nBands,
    00156                                   GDALDataType eType, char ** papszParmList )
    00157
    00158 {
    00159     /* notdef: should add a bunch of error checking here */
    00160
    00161     if( pfnCreate == NULL )
    00162     {
    00163         CPLError( CE_Failure, CPLE_NotSupported,
    00164                   "GDALDriver::Create() ... no create method implemented"
    00165                   " for this format.\n" );
    00166
    00167         return NULL;
    00168     }
    00169     else
    00170     {
    00171         GDALDataset *poDS;
    00172
    00173         CPLDebug( "GDAL", "GDALDriver::Create(%s,%s,%d,%d,%d,%s,%p)",
    00174                   pszShortName, pszFilename, nXSize, nYSize, nBands,
    00175                   GDALGetDataTypeName( eType ),
    00176                   papszParmList );
    00177
    00178         poDS = pfnCreate( pszFilename, nXSize, nYSize, nBands, eType,
    00179                           papszParmList );
    00180
    00181         if( poDS != NULL )
    00182         {
    00183             if( poDS->GetDescription() == NULL
    00184                 || strlen(poDS->GetDescription()) > 0 )
    00185                 poDS->SetDescription( pszFilename );
    00186
    00187             if( poDS->poDriver == NULL )
    00188                 poDS->poDriver = this;
    00189         }
    00190
    00191         return poDS;
    00192     }
    00193 }
    00194
    00195 /************************************************************************/
    00196 /*                             GDALCreate()                             */
    00197 /************************************************************************/
    00198
    00199 GDALDatasetH CPL_DLL GDALCreate( GDALDriverH hDriver,
    00200                                  const char * pszFilename,
    00201                                  int nXSize, int nYSize, int nBands,
    00202                                  GDALDataType eBandType,
    00203                                  char ** papszOptions )
    00204
    00205 {
    00206     return( ((GDALDriver *) hDriver)->Create( pszFilename,
    00207                                               nXSize, nYSize, nBands,
    00208                                               eBandType, papszOptions ) );
    00209 }
    00210
    00211 /************************************************************************/
    00212 /*                             CreateCopy()                             */
    00213 /************************************************************************/
    00214
    00248 GDALDataset *GDALDriver::CreateCopy( const char * pszFilename,
    00249                                      GDALDataset * poSrcDS,
    00250                                      int bStrict, char ** papszOptions,
    00251                                      GDALProgressFunc pfnProgress,
    00252                                      void * pProgressData )
    00253
    00254 {
    00255     if( pfnProgress == NULL )
    00256         pfnProgress = GDALDummyProgress;
    00257
    00258 /* -------------------------------------------------------------------- */
    00259 /*      If the format provides a CreateCopy() method use that,          */
    00260 /*      otherwise fallback to the internal implementation using the     */
    00261 /*      Create() method.                                                */
    00262 /* -------------------------------------------------------------------- */
    00263     if( pfnCreateCopy != NULL )
    00264     {
    00265         GDALDataset *poDstDS;
    00266
    00267         poDstDS = pfnCreateCopy( pszFilename, poSrcDS, bStrict, papszOptions,
    00268                                  pfnProgress, pProgressData );
    00269         if( poDstDS != NULL )
    00270         {
    00271             if( poDstDS->GetDescription() == NULL
    00272                 || strlen(poDstDS->GetDescription()) > 0 )
    00273                 poDstDS->SetDescription( pszFilename );
    00274
    00275             if( poDstDS->poDriver == NULL )
    00276                 poDstDS->poDriver = this;
    00277         }
    00278
    00279         return poDstDS;
    00280     }
    00281
    00282 /* -------------------------------------------------------------------- */
    00283 /*      Create destination dataset.                                     */
    00284 /* -------------------------------------------------------------------- */
    00285     GDALDataset  *poDstDS;
    00286     int          nXSize = poSrcDS->GetRasterXSize();
    00287     int          nYSize = poSrcDS->GetRasterYSize();
    00288     GDALDataType eType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
    00289     CPLErr       eErr;
    00290
    00291     CPLDebug( "GDAL", "Using default GDALDriver::CreateCopy implementation." );
    00292
    00293     if( !pfnProgress( 0.0, NULL, pProgressData ) )
    00294     {
    00295         CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
    00296         return NULL;
    00297     }
    00298
    00299     poDstDS = Create( pszFilename, nXSize, nYSize,
    00300                       poSrcDS->GetRasterCount(), eType, papszOptions );
    00301
    00302     if( poDstDS == NULL )
    00303         return NULL;
    00304
    00305 /* -------------------------------------------------------------------- */
    00306 /*      Try setting the projection and geotransform if it seems         */
    00307 /*      suitable.  For now we don't try and copy GCPs, though I         */
    00308 /*      suppose we should.                                              */
    00309 /* -------------------------------------------------------------------- */
    00310     double      adfGeoTransform[6];
    00311
    00312     if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None
    00313         && (adfGeoTransform[0] != 0.0
    00314             || adfGeoTransform[1] != 1.0
    00315             || adfGeoTransform[2] != 0.0
    00316             || adfGeoTransform[3] != 0.0
    00317             || adfGeoTransform[4] != 0.0
    00318             || adfGeoTransform[5] != 1.0) )
    00319     {
    00320         poDstDS->SetGeoTransform( adfGeoTransform );
    00321     }
    00322
    00323     if( poSrcDS->GetProjectionRef() != NULL
    00324         && strlen(poSrcDS->GetProjectionRef()) > 0 )
    00325     {
    00326         poDstDS->SetProjection( poSrcDS->GetProjectionRef() );
    00327     }
    00328
    00329 /* -------------------------------------------------------------------- */
    00330 /*      Loop copying bands.                                             */
    00331 /* -------------------------------------------------------------------- */
    00332     for( int iBand = 0; iBand < poSrcDS->GetRasterCount(); iBand++ )
    00333     {
    00334         GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( iBand+1 );
    00335         GDALRasterBand *poDstBand = poDstDS->GetRasterBand( iBand+1 );
    00336
    00337         void           *pData;
    00338
    00339         pData = CPLMalloc(nXSize * GDALGetDataTypeSize(eType) / 8);
    00340
    00341         for( int iLine = 0; iLine < nYSize; iLine++ )
    00342         {
    00343             eErr = poSrcBand->RasterIO( GF_Read, 0, iLine, nXSize, 1,
    00344                                         pData, nXSize, 1, eType, 0, 0 );
    00345             if( eErr != CE_None )
    00346             {
    00347                 return NULL;
    00348             }
    00349
    00350             eErr = poDstBand->RasterIO( GF_Write, 0, iLine, nXSize, 1,
    00351                                         pData, nXSize, 1, eType, 0, 0 );
    00352
    00353             if( eErr != CE_None )
    00354             {
    00355                 return NULL;
    00356             }
    00357
    00358             if( !pfnProgress( (iBand + (iLine+1) / (double) nYSize)
    00359                               / (double) poSrcDS->GetRasterCount(),
    00360                               NULL, pProgressData ) )
    00361             {
    00362                 CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
    00363                 delete poDstDS;
    00364                 Delete( pszFilename );
    00365                 return NULL;
    00366             }
    00367         }
    00368
    00369         CPLFree( pData );
    00370     }
    00371
    00372     return poDstDS;
    00373 }
    00374
    00375 /************************************************************************/
    00376 /*                           GDALCreateCopy()                           */
    00377 /************************************************************************/
    00378
    00379 GDALDatasetH GDALCreateCopy( GDALDriverH hDriver,
    00380                              const char * pszFilename,
    00381                              GDALDatasetH hSrcDS,
    00382                              int bStrict, char ** papszOptions,
    00383                              GDALProgressFunc pfnProgress,
    00384                              void * pProgressData )
    00385
    00386 {
    00387     return (GDALDatasetH) ((GDALDriver *) hDriver)->
    00388         CreateCopy( pszFilename, (GDALDataset *) hSrcDS, bStrict, papszOptions,
    00389                     pfnProgress, pProgressData );
    00390 }
    00391
    00392 /************************************************************************/
    00393 /*                               Delete()                               */
    00394 /************************************************************************/
    00395
    00415 CPLErr GDALDriver::Delete( const char * pszFilename )
    00416
    00417 {
    00418     if( pfnDelete != NULL )
    00419         return pfnDelete( pszFilename );
    00420     else
    00421     {
    00422         VSIStatBuf      sStat;
    00423
    00424         if( VSIStat( pszFilename, &sStat ) == 0 && VSI_ISREG( sStat.st_mode ) )
    00425         {
    00426             if( VSIUnlink( pszFilename ) == 0 )
    00427                 return CE_None;
    00428             else
    00429             {
    00430                 CPLError( CE_Failure, CPLE_AppDefined,
    00431                           "%s: Attempt to unlink %s failed.\n",
    00432                           pszShortName, pszFilename );
    00433                 return CE_Failure;
    00434             }
    00435         }
    00436         else
    00437         {
    00438             CPLError( CE_Failure, CPLE_AppDefined,
    00439                       "%s: Unable to delete %s, not a file.\n",
    00440                       pszShortName, pszFilename );
    00441             return CE_Failure;
    00442         }
    00443     }
    00444 }
    00445
    00446 /************************************************************************/
    00447 /*                             GDALDelete()                             */
    00448 /************************************************************************/
    00449
    00450 CPLErr GDALDeleteDataset( GDALDriverH hDriver, const char * pszFilename )
    00451
    00452 {
    00453     return ((GDALDriver *) hDriver)->Delete( pszFilename );
    00454 }
    00455
    00456 /************************************************************************/
    00457 /*                       GDALGetDriverShortName()                       */
    00458 /************************************************************************/
    00459
    00460 const char * GDALGetDriverShortName( GDALDriverH hDriver )
    00461
    00462 {
    00463     if( hDriver == NULL )
    00464         return NULL;
    00465     else
    00466         return ((GDALDriver *) hDriver)->pszShortName;
    00467 }
    00468
    00469 /************************************************************************/
    00470 /*                       GDALGetDriverLongName()                        */
    00471 /************************************************************************/
    00472
    00473 const char * GDALGetDriverLongName( GDALDriverH hDriver )
    00474
    00475 {
    00476     if( hDriver == NULL )
    00477         return NULL;
    00478     else
    00479         return ((GDALDriver *) hDriver)->pszLongName;
    00480 }
    00481
    00482 /************************************************************************/
    00483 /*                       GDALGetDriverHelpTopic()                       */
    00484 /************************************************************************/
    00485
    00486 const char * GDALGetDriverHelpTopic( GDALDriverH hDriver )
    00487
    00488 {
    00489     if( hDriver == NULL )
    00490         return NULL;
    00491     else
    00492         return ((GDALDriver *) hDriver)->pszHelpTopic;
    00493 }
    00494