Created
March 16, 2011 22:16
-
-
Save craigds/873438 to your computer and use it in GitHub Desktop.
backport gdal [20189] to 1.7.3. ticket: http://trac.osgeo.org/gdal/ticket/3708
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: gdal/apps/gdal_translate.cpp | |
=================================================================== | |
--- gdal/apps/gdal_translate.cpp (revision 21963) | |
+++ gdal/apps/gdal_translate.cpp (working copy) | |
@@ -991,7 +991,14 @@ | |
pfnProgress, NULL ); | |
if( hOutDS != NULL ) | |
{ | |
+ int bHasGotErr = FALSE; | |
+ CPLErrorReset(); | |
+ GDALFlushCache( hOutDS ); | |
+ if (CPLGetLastErrorType() != CE_None) | |
+ bHasGotErr = TRUE; | |
GDALClose( hOutDS ); | |
+ if (bHasGotErr) | |
+ hOutDS = NULL; | |
} | |
GDALClose( (GDALDatasetH) poVDS ); | |
Index: gdal/apps/gdalwarp.cpp | |
=================================================================== | |
--- gdal/apps/gdalwarp.cpp (revision 21963) | |
+++ gdal/apps/gdalwarp.cpp (working copy) | |
@@ -283,6 +283,7 @@ | |
char *pszCutlineDSName = NULL; | |
char *pszCLayer = NULL, *pszCWHERE = NULL, *pszCSQL = NULL; | |
void *hCutline = NULL; | |
+ int bHasGotErr = FALSE; | |
/* Check that we are running against at least GDAL 1.6 */ | |
/* Note to developers : if we use newer API, please change the requirement */ | |
@@ -1023,14 +1024,17 @@ | |
if( oWO.Initialize( psWO ) == CE_None ) | |
{ | |
+ CPLErr eErr; | |
if( bMulti ) | |
- oWO.ChunkAndWarpMulti( 0, 0, | |
+ eErr = oWO.ChunkAndWarpMulti( 0, 0, | |
GDALGetRasterXSize( hDstDS ), | |
GDALGetRasterYSize( hDstDS ) ); | |
else | |
- oWO.ChunkAndWarpImage( 0, 0, | |
+ eErr = oWO.ChunkAndWarpImage( 0, 0, | |
GDALGetRasterXSize( hDstDS ), | |
GDALGetRasterYSize( hDstDS ) ); | |
+ if (eErr != CE_None) | |
+ bHasGotErr = TRUE; | |
} | |
/* -------------------------------------------------------------------- */ | |
@@ -1050,6 +1054,10 @@ | |
/* -------------------------------------------------------------------- */ | |
/* Final Cleanup. */ | |
/* -------------------------------------------------------------------- */ | |
+ CPLErrorReset(); | |
+ GDALFlushCache( hDstDS ); | |
+ if( CPLGetLastErrorType() != CE_None ) | |
+ bHasGotErr = TRUE; | |
GDALClose( hDstDS ); | |
CPLFree( pszDstFilename ); | |
@@ -1068,7 +1076,7 @@ | |
OGRCleanupAll(); | |
#endif | |
- return 0; | |
+ return (bHasGotErr) ? 1 : 0; | |
} | |
/************************************************************************/ | |
Index: gdal/frmts/gtiff/geotiff.cpp | |
=================================================================== | |
--- gdal/frmts/gtiff/geotiff.cpp (revision 21963) | |
+++ gdal/frmts/gtiff/geotiff.cpp (working copy) | |
@@ -115,6 +115,7 @@ | |
CPLErr LoadBlockBuf( int nBlockId, int bReadFromDisk = TRUE ); | |
CPLErr FlushBlockBuf(); | |
+ int bWriteErrorInFlushBlockBuf; | |
char *pszProjection; | |
int bLookedForProjection; | |
@@ -751,6 +752,14 @@ | |
int nBlockId; | |
CPLErr eErr = CE_None; | |
+ if (poGDS->bWriteErrorInFlushBlockBuf) | |
+ { | |
+ /* Report as an error if a previously loaded block couldn't be */ | |
+ /* written correctly */ | |
+ poGDS->bWriteErrorInFlushBlockBuf = FALSE; | |
+ return CE_Failure; | |
+ } | |
+ | |
if (!poGDS->SetDirectory()) | |
return CE_Failure; | |
@@ -1632,6 +1641,14 @@ | |
int nBlockId; | |
CPLErr eErr = CE_None; | |
+ if (poGDS->bWriteErrorInFlushBlockBuf) | |
+ { | |
+ /* Report as an error if a previously loaded block couldn't be */ | |
+ /* written correctly */ | |
+ poGDS->bWriteErrorInFlushBlockBuf = FALSE; | |
+ return CE_Failure; | |
+ } | |
+ | |
if (!poGDS->SetDirectory()) | |
return CE_Failure; | |
@@ -2351,6 +2368,7 @@ | |
nLoadedBlock = -1; | |
bLoadedBlockDirty = FALSE; | |
pabyBlockBuf = NULL; | |
+ bWriteErrorInFlushBlockBuf = FALSE; | |
hTIFF = NULL; | |
bNeedsRewrite = FALSE; | |
bMetadataChanged = FALSE; | |
@@ -2660,6 +2678,7 @@ | |
{ | |
CPLError( CE_Failure, CPLE_AppDefined, | |
"WriteEncodedTile/Strip() failed." ); | |
+ bWriteErrorInFlushBlockBuf = TRUE; | |
} | |
return eErr; | |
Index: gdal/gcore/gdalrasterblock.cpp | |
=================================================================== | |
--- gdal/gcore/gdalrasterblock.cpp (revision 21963) | |
+++ gdal/gcore/gdalrasterblock.cpp (working copy) | |
@@ -217,7 +217,12 @@ | |
poBand = poTarget->GetBand(); | |
} | |
- poBand->FlushBlock( nXOff, nYOff ); | |
+ CPLErr eErr = poBand->FlushBlock( nXOff, nYOff ); | |
+ if (eErr != CE_None) | |
+ { | |
+ /* Save the error for later reporting */ | |
+ poBand->SetFlushBlockErr(eErr); | |
+ } | |
return TRUE; | |
} | |
Index: gdal/gcore/GNUmakefile | |
=================================================================== | |
--- gdal/gcore/GNUmakefile (revision 21963) | |
+++ gdal/gcore/GNUmakefile (working copy) | |
@@ -21,7 +21,7 @@ | |
default: $(OBJ:.o=.$(OBJ_EXT)) | |
clean: | |
- $(RM) *.o | |
+ $(RM) *.o $(O_OBJ) | |
docs: | |
(cd ..; $(MAKE) docs) | |
Index: gdal/gcore/gdal_priv.h | |
=================================================================== | |
--- gdal/gcore/gdal_priv.h (revision 21963) | |
+++ gdal/gcore/gdal_priv.h (working copy) | |
@@ -401,6 +401,13 @@ | |
class CPL_DLL GDALRasterBand : public GDALMajorObject | |
{ | |
+ private: | |
+ CPLErr eFlushBlockErr; | |
+ | |
+ void SetFlushBlockErr( CPLErr eErr ); | |
+ | |
+ friend class GDALRasterBlock; | |
+ | |
protected: | |
GDALDataset *poDS; | |
int nBand; /* 1 based */ | |
@@ -430,7 +437,6 @@ | |
int nMaskFlags; | |
friend class GDALDataset; | |
- friend class GDALRasterBlock; | |
friend class GDALProxyRasterBand; | |
protected: | |
Index: gdal/gcore/gdalrasterband.cpp | |
=================================================================== | |
--- gdal/gcore/gdalrasterband.cpp (revision 21963) | |
+++ gdal/gcore/gdalrasterband.cpp (working copy) | |
@@ -78,6 +78,8 @@ | |
nBlockReads = 0; | |
bForceCachedIO = CSLTestBoolean( | |
CPLGetConfigOption( "GDAL_FORCE_CACHING", "NO") ); | |
+ | |
+ eFlushBlockErr = CE_None; | |
} | |
/************************************************************************/ | |
@@ -212,6 +214,15 @@ | |
return CE_None; | |
} | |
+ if( eRWFlag == GF_Write && eFlushBlockErr != CE_None ) | |
+ { | |
+ CPLError(eFlushBlockErr, CPLE_AppDefined, | |
+ "An error occured while writing a dirty block"); | |
+ CPLErr eErr = eFlushBlockErr; | |
+ eFlushBlockErr = CE_None; | |
+ return eErr; | |
+ } | |
+ | |
/* -------------------------------------------------------------------- */ | |
/* If pixel and line spaceing are defaulted assign reasonable */ | |
/* value assuming a packed buffer. */ | |
@@ -522,6 +533,15 @@ | |
return( CE_Failure ); | |
} | |
+ if( eFlushBlockErr != CE_None ) | |
+ { | |
+ CPLError(eFlushBlockErr, CPLE_AppDefined, | |
+ "An error occured while writing a dirty block"); | |
+ CPLErr eErr = eFlushBlockErr; | |
+ eFlushBlockErr = CE_None; | |
+ return eErr; | |
+ } | |
+ | |
/* -------------------------------------------------------------------- */ | |
/* Invoke underlying implementation method. */ | |
/* -------------------------------------------------------------------- */ | |
@@ -873,8 +893,16 @@ | |
CPLErr GDALRasterBand::FlushCache() | |
{ | |
+ CPLErr eGlobalErr = eFlushBlockErr; | |
+ if (eFlushBlockErr != CE_None) | |
+ { | |
+ CPLError(eFlushBlockErr, CPLE_AppDefined, | |
+ "An error occured while writing a dirty block"); | |
+ eFlushBlockErr = CE_None; | |
+ } | |
+ | |
if (papoBlocks == NULL) | |
- return CE_None; | |
+ return eGlobalErr; | |
/* -------------------------------------------------------------------- */ | |
/* Flush all blocks in memory ... this case is without subblocking.*/ | |
@@ -4811,3 +4839,24 @@ | |
} | |
return NULL; | |
} | |
+ | |
+/************************************************************************/ | |
+/* SetFlushBlockErr() */ | |
+/************************************************************************/ | |
+ | |
+/** | |
+ * \brief Store that an error occured while writing a dirty block. | |
+ * | |
+ * This function stores the fact that an error occured while writing a dirty | |
+ * block from GDALRasterBlock::FlushCacheBlock(). Indeed when dirty blocks are | |
+ * flushed when the block cache get full, it is not convenient/possible to | |
+ * report that a dirty block could not be written correctly. This function | |
+ * remembers the error and re-issue it from GDALRasterBand::FlushCache(), | |
+ * GDALRasterBand::WriteBlock() and GDALRasterBand::RasterIO(), which are | |
+ * places where the user can easily match the error with the relevant dataset. | |
+ */ | |
+ | |
+void GDALRasterBand::SetFlushBlockErr( CPLErr eErr ) | |
+{ | |
+ eFlushBlockErr = eErr; | |
+} | |
Index: gdal/alg/gdalwarpoperation.cpp | |
=================================================================== | |
--- gdal/alg/gdalwarpoperation.cpp (revision 21963) | |
+++ gdal/alg/gdalwarpoperation.cpp (working copy) | |
@@ -1264,10 +1264,16 @@ | |
psOptions->nBandCount, | |
psOptions->panDstBands, | |
0, 0, 0 ); | |
- if( CSLFetchBoolean( psOptions->papszWarpOptions, "WRITE_FLUSH", | |
+ if( eErr == CE_None && | |
+ CSLFetchBoolean( psOptions->papszWarpOptions, "WRITE_FLUSH", | |
FALSE ) ) | |
{ | |
+ CPLErr eOldErr = CPLGetLastErrorType(); | |
+ CPLString osLastErrMsg = CPLGetLastErrorMsg(); | |
GDALFlushCache( psOptions->hDstDS ); | |
+ CPLErr eNewErr = CPLGetLastErrorType(); | |
+ if (eNewErr != eOldErr || osLastErrMsg.compare(CPLGetLastErrorMsg()) != 0) | |
+ eErr = CE_Failure; | |
} | |
ReportTiming( "Output buffer write" ); | |
} | |
Index: gdal/alg/GNUmakefile | |
=================================================================== | |
--- gdal/alg/GNUmakefile (revision 21963) | |
+++ gdal/alg/GNUmakefile (working copy) | |
@@ -21,7 +21,7 @@ | |
default: $(OBJ:.o=.$(OBJ_EXT)) | |
clean: | |
- $(RM) *.o | |
+ $(RM) *.o $(O_OBJ) | |
docs: | |
(cd ..; $(MAKE) docs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment