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 

Generated at Thu Mar 28 09:47:30 2002 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000