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.13 2002/12/21 19:13:12 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.13  2002/12/21 19:13:12  warmerda
00030  * updated
00030  *
00031  * Revision 1.28  2002/09/11 14:17:23  warmerda
00032  * copy ct/metadata/description for bands in CreateCopy()
00033  *
00034  * Revision 1.27  2002/09/06 01:28:30  warmerda
00035  * fixed logic for setting descriptions in created files
00036  *
00037  * Revision 1.26  2002/09/04 06:52:05  warmerda
00038  * added unload driver support to GDALDriver
00039  *
00040  * Revision 1.25  2002/07/09 20:33:12  warmerda
00041  * expand tabs
00042  *
00043  * Revision 1.24  2002/06/12 21:13:27  warmerda
00044  * use metadata based driver info
00045  *
00046  * Revision 1.23  2001/12/15 15:47:54  warmerda
00047  * don't replace existing descriptions
00048  *
00049  * Revision 1.22  2001/12/15 15:42:27  warmerda
00050  * *** empty log message ***
00051  *
00052  * Revision 1.21  2001/10/05 20:35:26  warmerda
00053  * CreateCopy() won't try to write default geotransform
00054  *
00055  * Revision 1.20  2001/09/24 15:58:27  warmerda
00056  * improved progress reporting in createcopy
00057  *
00058  * Revision 1.19  2001/07/18 04:04:30  warmerda
00059  * added CPL_CVSID
00060  *
00061  * Revision 1.18  2001/02/15 16:30:34  warmerda
00062  * added create debug message
00063  *
00064  * Revision 1.17  2000/10/06 15:26:49  warmerda
00065  * make buffer size for copying image data the exact size, fixing bug with complex data
00066  *
00067  * Revision 1.16  2000/07/13 17:34:11  warmerda
00068  * Set description for CopyCreate() method.
00069  *
00070  * Revision 1.15  2000/07/13 17:27:48  warmerda
00071  * added SetDescription after create
00072  *
00073  * Revision 1.14  2000/06/27 16:47:28  warmerda
00074  * added cancel support for CopyCreate progress func
00075  *
00076  * Revision 1.13  2000/06/26 18:47:14  warmerda
00077  * Ensure pszHelpTopic is initialized
00078  *
00079  * Revision 1.12  2000/04/30 23:22:16  warmerda
00080  * added CreateCopy support
00081  *
00082  * Revision 1.11  2000/03/06 02:21:15  warmerda
00083  * Added help topic C function
00084  *
00085  * Revision 1.10  2000/01/31 16:24:01  warmerda
00086  * use failure, not fatal
00087  *
00088  * Revision 1.9  2000/01/31 15:00:25  warmerda
00089  * added some documentation
00090  *
00091  * Revision 1.8  2000/01/31 14:24:36  warmerda
00092  * implemented dataset delete
00093  *
00094  * Revision 1.7  2000/01/13 04:13:10  pgs
00095  * added initialization of pfnCreate = NULL to prevent run-time crash when format doesn't support creating a file
00096  *
00097  * Revision 1.6  1999/12/08 14:40:50  warmerda
00098  * Fixed error message.
00099  *
00100  * Revision 1.5  1999/10/21 13:22:10  warmerda
00101  * Added GDALGetDriverShort/LongName().
00102  *
00103  * Revision 1.4  1999/01/11 15:36:50  warmerda
00104  * Added GDALCreate()
00105  *
00106  * Revision 1.3  1998/12/31 18:54:53  warmerda
00107  * Flesh out create method.
00108  *
00109  * Revision 1.2  1998/12/06 22:17:32  warmerda
00110  * Add stub Create() method
00111  *
00112  * Revision 1.1  1998/12/03 18:32:01  warmerda
00113  * New
00114  *
00115  */
00116 
00117 #include "gdal_priv.h"
00118 
00119 CPL_CVSID("$Id: gdaldriver_cpp-source.html,v 1.13 2002/12/21 19:13:12 warmerda Exp $");
00120 
00121 /************************************************************************/
00122 /*                             GDALDriver()                             */
00123 /************************************************************************/
00124 
00125 GDALDriver::GDALDriver()
00126 
00127 {
00128     pfnOpen = NULL;
00129     pfnCreate = NULL;
00130     pfnDelete = NULL;
00131     pfnCreateCopy = NULL;
00132     pfnUnloadDriver = NULL;
00133     pDriverData = NULL;
00134 }
00135 
00136 /************************************************************************/
00137 /*                            ~GDALDriver()                             */
00138 /************************************************************************/
00139 
00140 GDALDriver::~GDALDriver()
00141 
00142 {
00143     if( pfnUnloadDriver != NULL )
00144         pfnUnloadDriver( this );
00145 }
00146 
00147 /************************************************************************/
00148 /*                               Create()                               */
00149 /************************************************************************/
00150 
00169 GDALDataset * GDALDriver::Create( const char * pszFilename,
00170                                   int nXSize, int nYSize, int nBands,
00171                                   GDALDataType eType, char ** papszParmList )
00172 
00173 {
00174     /* notdef: should add a bunch of error checking here */
00175 
00176     if( pfnCreate == NULL )
00177     {
00178         CPLError( CE_Failure, CPLE_NotSupported,
00179                   "GDALDriver::Create() ... no create method implemented"
00180                   " for this format.\n" );
00181 
00182         return NULL;
00183     }
00184     else
00185     {
00186         GDALDataset *poDS;
00187 
00188         CPLDebug( "GDAL", "GDALDriver::Create(%s,%s,%d,%d,%d,%s,%p)",
00189                   GetDescription(), pszFilename, nXSize, nYSize, nBands, 
00190                   GDALGetDataTypeName( eType ), 
00191                   papszParmList );
00192               
00193         poDS = pfnCreate( pszFilename, nXSize, nYSize, nBands, eType,
00194                           papszParmList );
00195 
00196         if( poDS != NULL )
00197         {
00198             if( poDS->GetDescription() == NULL
00199                 || strlen(poDS->GetDescription()) == 0 )
00200                 poDS->SetDescription( pszFilename );
00201 
00202             if( poDS->poDriver == NULL )
00203                 poDS->poDriver = this;
00204         }
00205 
00206         return poDS;
00207     }
00208 }
00209 
00210 /************************************************************************/
00211 /*                             GDALCreate()                             */
00212 /************************************************************************/
00213 
00214 GDALDatasetH CPL_DLL GDALCreate( GDALDriverH hDriver,
00215                                  const char * pszFilename,
00216                                  int nXSize, int nYSize, int nBands,
00217                                  GDALDataType eBandType,
00218                                  char ** papszOptions )
00219 
00220 {
00221     return( ((GDALDriver *) hDriver)->Create( pszFilename,
00222                                               nXSize, nYSize, nBands,
00223                                               eBandType, papszOptions ) );
00224 }
00225 
00226 /************************************************************************/
00227 /*                             CreateCopy()                             */
00228 /************************************************************************/
00229 
00263 GDALDataset *GDALDriver::CreateCopy( const char * pszFilename, 
00264                                      GDALDataset * poSrcDS, 
00265                                      int bStrict, char ** papszOptions,
00266                                      GDALProgressFunc pfnProgress,
00267                                      void * pProgressData )
00268 
00269 {
00270     if( pfnProgress == NULL )
00271         pfnProgress = GDALDummyProgress;
00272 
00273 /* -------------------------------------------------------------------- */
00274 /*      If the format provides a CreateCopy() method use that,          */
00275 /*      otherwise fallback to the internal implementation using the     */
00276 /*      Create() method.                                                */
00277 /* -------------------------------------------------------------------- */
00278     if( pfnCreateCopy != NULL )
00279     {
00280         GDALDataset *poDstDS;
00281 
00282         poDstDS = pfnCreateCopy( pszFilename, poSrcDS, bStrict, papszOptions,
00283                                  pfnProgress, pProgressData );
00284         if( poDstDS != NULL )
00285         {
00286             if( poDstDS->GetDescription() == NULL 
00287                 || strlen(poDstDS->GetDescription()) > 0 )
00288                 poDstDS->SetDescription( pszFilename );
00289 
00290             if( poDstDS->poDriver == NULL )
00291                 poDstDS->poDriver = this;
00292         }
00293 
00294         return poDstDS;
00295     }
00296     
00297 /* -------------------------------------------------------------------- */
00298 /*      Create destination dataset.                                     */
00299 /* -------------------------------------------------------------------- */
00300     GDALDataset  *poDstDS;
00301     int          nXSize = poSrcDS->GetRasterXSize();
00302     int          nYSize = poSrcDS->GetRasterYSize();
00303     GDALDataType eType = poSrcDS->GetRasterBand(1)->GetRasterDataType();
00304     CPLErr       eErr;
00305 
00306     CPLDebug( "GDAL", "Using default GDALDriver::CreateCopy implementation." );
00307 
00308     if( !pfnProgress( 0.0, NULL, pProgressData ) )
00309     {
00310         CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
00311         return NULL;
00312     }
00313 
00314     poDstDS = Create( pszFilename, nXSize, nYSize, 
00315                       poSrcDS->GetRasterCount(), eType, papszOptions );
00316 
00317     if( poDstDS == NULL )
00318         return NULL;
00319 
00320 /* -------------------------------------------------------------------- */
00321 /*      Try setting the projection and geotransform if it seems         */
00322 /*      suitable.  For now we don't try and copy GCPs, though I         */
00323 /*      suppose we should.                                              */
00324 /* -------------------------------------------------------------------- */
00325     double      adfGeoTransform[6];
00326 
00327     if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None 
00328         && (adfGeoTransform[0] != 0.0 
00329             || adfGeoTransform[1] != 1.0
00330             || adfGeoTransform[2] != 0.0
00331             || adfGeoTransform[3] != 0.0
00332             || adfGeoTransform[4] != 0.0
00333             || adfGeoTransform[5] != 1.0) )
00334     {
00335         poDstDS->SetGeoTransform( adfGeoTransform );
00336     }
00337 
00338     if( poSrcDS->GetProjectionRef() != NULL
00339         && strlen(poSrcDS->GetProjectionRef()) > 0 )
00340     {
00341         poDstDS->SetProjection( poSrcDS->GetProjectionRef() );
00342     }
00343 
00344 /* -------------------------------------------------------------------- */
00345 /*      Loop copying bands.                                             */
00346 /* -------------------------------------------------------------------- */
00347     for( int iBand = 0; iBand < poSrcDS->GetRasterCount(); iBand++ )
00348     {
00349         GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( iBand+1 );
00350         GDALRasterBand *poDstBand = poDstDS->GetRasterBand( iBand+1 );
00351 
00352 /* -------------------------------------------------------------------- */
00353 /*      Do we need to copy a colortable or other metadata?              */
00354 /* -------------------------------------------------------------------- */
00355         GDALColorTable *poCT;
00356 
00357         poCT = poSrcBand->GetColorTable();
00358         if( poCT != NULL )
00359             poDstBand->SetColorTable( poCT );
00360 
00361         if( strlen(poSrcBand->GetDescription()) > 0 )
00362             poDstBand->SetDescription( poSrcBand->GetDescription() );
00363 
00364         poDstBand->SetMetadata( poSrcBand->GetMetadata() );
00365 
00366 /* -------------------------------------------------------------------- */
00367 /*      Copy image data.                                                */
00368 /* -------------------------------------------------------------------- */
00369         void           *pData;
00370 
00371         pData = CPLMalloc(nXSize * GDALGetDataTypeSize(eType) / 8);
00372 
00373         for( int iLine = 0; iLine < nYSize; iLine++ )
00374         {
00375             eErr = poSrcBand->RasterIO( GF_Read, 0, iLine, nXSize, 1, 
00376                                         pData, nXSize, 1, eType, 0, 0 );
00377             if( eErr != CE_None )
00378             {
00379                 return NULL;
00380             }
00381             
00382             eErr = poDstBand->RasterIO( GF_Write, 0, iLine, nXSize, 1, 
00383                                         pData, nXSize, 1, eType, 0, 0 );
00384 
00385             if( eErr != CE_None )
00386             {
00387                 return NULL;
00388             }
00389 
00390             if( !pfnProgress( (iBand + (iLine+1) / (double) nYSize)
00391                               / (double) poSrcDS->GetRasterCount(), 
00392                               NULL, pProgressData ) )
00393             {
00394                 CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
00395                 delete poDstDS;
00396                 Delete( pszFilename );
00397                 return NULL;
00398             }
00399         }
00400 
00401         CPLFree( pData );
00402     }
00403 
00404     return poDstDS;
00405 }
00406 
00407 /************************************************************************/
00408 /*                           GDALCreateCopy()                           */
00409 /************************************************************************/
00410 
00411 GDALDatasetH GDALCreateCopy( GDALDriverH hDriver, 
00412                              const char * pszFilename, 
00413                              GDALDatasetH hSrcDS, 
00414                              int bStrict, char ** papszOptions,
00415                              GDALProgressFunc pfnProgress,
00416                              void * pProgressData )
00417 
00418 {
00419     return (GDALDatasetH) ((GDALDriver *) hDriver)->
00420         CreateCopy( pszFilename, (GDALDataset *) hSrcDS, bStrict, papszOptions,
00421                     pfnProgress, pProgressData );
00422 }
00423 
00424 /************************************************************************/
00425 /*                               Delete()                               */
00426 /************************************************************************/
00427 
00447 CPLErr GDALDriver::Delete( const char * pszFilename )
00448 
00449 {
00450     if( pfnDelete != NULL )
00451         return pfnDelete( pszFilename );
00452     else
00453     {
00454         VSIStatBuf      sStat;
00455 
00456         if( VSIStat( pszFilename, &sStat ) == 0 && VSI_ISREG( sStat.st_mode ) )
00457         {
00458             if( VSIUnlink( pszFilename ) == 0 )
00459                 return CE_None;
00460             else
00461             {
00462                 CPLError( CE_Failure, CPLE_AppDefined,
00463                           "%s: Attempt to unlink %s failed.\n",
00464                           GetDescription(), pszFilename );
00465                 return CE_Failure;
00466             }
00467         }
00468         else
00469         {
00470             CPLError( CE_Failure, CPLE_AppDefined,
00471                       "%s: Unable to delete %s, not a file.\n",
00472                       GetDescription(), pszFilename );
00473             return CE_Failure;
00474         }
00475     }
00476 }
00477 
00478 /************************************************************************/
00479 /*                             GDALDelete()                             */
00480 /************************************************************************/
00481 
00482 CPLErr GDALDeleteDataset( GDALDriverH hDriver, const char * pszFilename )
00483 
00484 {
00485     return ((GDALDriver *) hDriver)->Delete( pszFilename );
00486 }
00487 
00488 /************************************************************************/
00489 /*                       GDALGetDriverShortName()                       */
00490 /************************************************************************/
00491 
00492 const char * GDALGetDriverShortName( GDALDriverH hDriver )
00493 
00494 {
00495     if( hDriver == NULL )
00496         return NULL;
00497     else
00498         return ((GDALDriver *) hDriver)->GetDescription();
00499 }
00500 
00501 /************************************************************************/
00502 /*                       GDALGetDriverLongName()                        */
00503 /************************************************************************/
00504 
00505 const char * GDALGetDriverLongName( GDALDriverH hDriver )
00506 
00507 {
00508     if( hDriver == NULL )
00509         return NULL;
00510 
00511     const char *pszLongName = 
00512         ((GDALDriver *) hDriver)->GetMetadataItem( GDAL_DMD_LONGNAME );
00513 
00514     if( pszLongName == NULL )
00515         return "";
00516     else
00517         return pszLongName;
00518 }
00519 
00520 /************************************************************************/
00521 /*                       GDALGetDriverHelpTopic()                       */
00522 /************************************************************************/
00523 
00524 const char * GDALGetDriverHelpTopic( GDALDriverH hDriver )
00525 
00526 {
00527     if( hDriver == NULL )
00528         return NULL;
00529 
00530     return ((GDALDriver *) hDriver)->GetMetadataItem( GDAL_DMD_HELPTOPIC );
00531 }
00532 

Generated at Sat Dec 21 14:01:59 2002 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000