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