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