Index: gcore/gdal_priv.h
===================================================================
--- gcore/gdal_priv.h	(révision 23068)
+++ gcore/gdal_priv.h	(copie de travail)
@@ -359,6 +359,8 @@
 
     CPLErr BuildOverviews( const char *, int, int *,
                            int, int *, GDALProgressFunc, void * );
+
+    void ReportError(CPLErr eErrClass, int err_no, const char *fmt, ...)  CPL_PRINT_FUNC_FORMAT (4, 5);
 };
 
 /* ******************************************************************** */
@@ -601,6 +603,8 @@
     virtual GDALRasterBand *GetMaskBand();
     virtual int             GetMaskFlags();
     virtual CPLErr          CreateMaskBand( int nFlags );
+
+    void ReportError(CPLErr eErrClass, int err_no, const char *fmt, ...)  CPL_PRINT_FUNC_FORMAT (4, 5);
 };
 
 /* ******************************************************************** */
Index: gcore/gdalrasterband.cpp
===================================================================
--- gcore/gdalrasterband.cpp	(révision 23068)
+++ gcore/gdalrasterband.cpp	(copie de travail)
@@ -187,7 +187,7 @@
 
     if( NULL == pData )
     {
-        CPLError( CE_Failure, CPLE_AppDefined, 
+        ReportError( CE_Failure, CPLE_AppDefined,
                   "The buffer into which the data should be read is null" );
             return CE_Failure;
     }
@@ -210,7 +210,7 @@
 
     if( eRWFlag == GF_Write && eFlushBlockErr != CE_None )
     {
-        CPLError(eFlushBlockErr, CPLE_AppDefined,
+        ReportError(eFlushBlockErr, CPLE_AppDefined,
                  "An error occured while writing a dirty block");
         CPLErr eErr = eFlushBlockErr;
         eFlushBlockErr = CE_None;
@@ -228,7 +228,7 @@
     {
         if (nPixelSpace > INT_MAX / nBufXSize)
         {
-            CPLError( CE_Failure, CPLE_AppDefined, 
+            ReportError( CE_Failure, CPLE_AppDefined,
                       "Int overflow : %d x %d", nPixelSpace, nBufXSize );
             return CE_Failure;
         }
@@ -241,7 +241,7 @@
     if( nXOff < 0 || nXOff > INT_MAX - nXSize || nXOff + nXSize > nRasterXSize
         || nYOff < 0 || nYOff > INT_MAX - nYSize || nYOff + nYSize > nRasterYSize )
     {
-        CPLError( CE_Failure, CPLE_IllegalArg,
+        ReportError( CE_Failure, CPLE_IllegalArg,
                   "Access window out of range in RasterIO().  Requested\n"
                   "(%d,%d) of size %dx%d on raster of %dx%d.",
                   nXOff, nYOff, nXSize, nYSize, nRasterXSize, nRasterYSize );
@@ -250,7 +250,7 @@
 
     if( eRWFlag != GF_Read && eRWFlag != GF_Write )
     {
-        CPLError( CE_Failure, CPLE_IllegalArg,
+        ReportError( CE_Failure, CPLE_IllegalArg,
                   "eRWFlag = %d, only GF_Read (0) and GF_Write (1) are legal.",
                   eRWFlag );
         return CE_Failure;
@@ -397,7 +397,7 @@
         
     if( nXBlockOff < 0 || nXBlockOff >= nBlocksPerRow )
     {
-        CPLError( CE_Failure, CPLE_IllegalArg,
+        ReportError( CE_Failure, CPLE_IllegalArg,
                   "Illegal nXBlockOff value (%d) in "
                         "GDALRasterBand::ReadBlock()\n",
                   nXBlockOff );
@@ -407,7 +407,7 @@
 
     if( nYBlockOff < 0 || nYBlockOff >= nBlocksPerColumn )
     {
-        CPLError( CE_Failure, CPLE_IllegalArg,
+        ReportError( CE_Failure, CPLE_IllegalArg,
                   "Illegal nYBlockOff value (%d) in "
                         "GDALRasterBand::ReadBlock()\n",
                   nYBlockOff );
@@ -452,7 +452,7 @@
 
 {
     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
-        CPLError( CE_Failure, CPLE_NotSupported,
+        ReportError( CE_Failure, CPLE_NotSupported,
                   "WriteBlock() not supported for this dataset." );
     
     return( CE_Failure );
@@ -500,7 +500,7 @@
 
     if( nXBlockOff < 0 || nXBlockOff >= nBlocksPerRow )
     {
-        CPLError( CE_Failure, CPLE_IllegalArg,
+        ReportError( CE_Failure, CPLE_IllegalArg,
                   "Illegal nXBlockOff value (%d) in "
                         "GDALRasterBand::WriteBlock()\n",
                   nXBlockOff );
@@ -510,7 +510,7 @@
 
     if( nYBlockOff < 0 || nYBlockOff >= nBlocksPerColumn )
     {
-        CPLError( CE_Failure, CPLE_IllegalArg,
+        ReportError( CE_Failure, CPLE_IllegalArg,
                   "Illegal nYBlockOff value (%d) in "
                         "GDALRasterBand::WriteBlock()\n",
                   nYBlockOff );
@@ -520,7 +520,7 @@
 
     if( eAccess == GA_ReadOnly )
     {
-        CPLError( CE_Failure, CPLE_NoWriteAccess,
+        ReportError( CE_Failure, CPLE_NoWriteAccess,
                   "Attempt to write to read only dataset in"
                   "GDALRasterBand::WriteBlock().\n" );
 
@@ -529,7 +529,7 @@
 
     if( eFlushBlockErr != CE_None )
     {
-        CPLError(eFlushBlockErr, CPLE_AppDefined,
+        ReportError(eFlushBlockErr, CPLE_AppDefined,
                  "An error occured while writing a dirty block");
         CPLErr eErr = eFlushBlockErr;
         eFlushBlockErr = CE_None;
@@ -628,7 +628,7 @@
 {
     if( nBlockXSize <= 0 || nBlockYSize <= 0 )
     {
-        CPLError( CE_Failure, CPLE_AppDefined, "Invalid block dimension : %d * %d",
+        ReportError( CE_Failure, CPLE_AppDefined, "Invalid block dimension : %d * %d",
                  nBlockXSize, nBlockYSize );
         if( pnXSize != NULL )
             *pnXSize = 0;
@@ -678,14 +678,14 @@
     /* would have neglected to do it itself */
     if( nBlockXSize <= 0 || nBlockYSize <= 0 )
     {
-        CPLError( CE_Failure, CPLE_AppDefined, "Invalid block dimension : %d * %d",
+        ReportError( CE_Failure, CPLE_AppDefined, "Invalid block dimension : %d * %d",
                   nBlockXSize, nBlockYSize );
         return FALSE;
     }
 
     if( nRasterXSize <= 0 || nRasterYSize <= 0 )
     {
-        CPLError( CE_Failure, CPLE_AppDefined, "Invalid raster dimension : %d * %d",
+        ReportError( CE_Failure, CPLE_AppDefined, "Invalid raster dimension : %d * %d",
                   nRasterXSize, nRasterYSize );
         return FALSE;
     }
@@ -702,7 +702,7 @@
         GIntBig nBigSizeInBytes = (GIntBig)nBlockXSize * nBlockYSize * (GDALGetDataTypeSize(eDataType) / 8);
         if ((GIntBig)nSizeInBytes != nBigSizeInBytes)
         {
-            CPLError( CE_Failure, CPLE_NotSupported, "Too big block : %d * %d",
+            ReportError( CE_Failure, CPLE_NotSupported, "Too big block : %d * %d",
                         nBlockXSize, nBlockYSize );
             return FALSE;
         }
@@ -711,14 +711,14 @@
     /* Check for overflows in computation of nBlocksPerRow and nBlocksPerColumn */
     if (nRasterXSize > INT_MAX - (nBlockXSize-1))
     {
-        CPLError( CE_Failure, CPLE_NotSupported, "Inappropriate raster width (%d) for block width (%d)",
+        ReportError( CE_Failure, CPLE_NotSupported, "Inappropriate raster width (%d) for block width (%d)",
                     nRasterXSize, nBlockXSize );
         return FALSE;
     }
 
     if (nRasterYSize > INT_MAX - (nBlockYSize-1))
     {
-        CPLError( CE_Failure, CPLE_NotSupported, "Inappropriate raster height (%d) for block height (%d)",
+        ReportError( CE_Failure, CPLE_NotSupported, "Inappropriate raster height (%d) for block height (%d)",
                     nRasterYSize, nBlockYSize );
         return FALSE;
     }
@@ -737,7 +737,7 @@
         }
         else
         {
-            CPLError( CE_Failure, CPLE_NotSupported, "Too many blocks : %d x %d",
+            ReportError( CE_Failure, CPLE_NotSupported, "Too many blocks : %d x %d",
                      nBlocksPerRow, nBlocksPerColumn );
             return FALSE;
         }
@@ -747,14 +747,14 @@
         /* Check for overflows in computation of nSubBlocksPerRow and nSubBlocksPerColumn */
         if (nBlocksPerRow > INT_MAX - (SUBBLOCK_SIZE+1))
         {
-            CPLError( CE_Failure, CPLE_NotSupported, "Inappropriate raster width (%d) for block width (%d)",
+            ReportError( CE_Failure, CPLE_NotSupported, "Inappropriate raster width (%d) for block width (%d)",
                         nRasterXSize, nBlockXSize );
             return FALSE;
         }
 
         if (nBlocksPerColumn > INT_MAX - (SUBBLOCK_SIZE+1))
         {
-            CPLError( CE_Failure, CPLE_NotSupported, "Inappropriate raster height (%d) for block height (%d)",
+            ReportError( CE_Failure, CPLE_NotSupported, "Inappropriate raster height (%d) for block height (%d)",
                         nRasterYSize, nBlockYSize );
             return FALSE;
         }
@@ -771,7 +771,7 @@
         }
         else
         {
-            CPLError( CE_Failure, CPLE_NotSupported, "Too many subblocks : %d x %d",
+            ReportError( CE_Failure, CPLE_NotSupported, "Too many subblocks : %d x %d",
                       nSubBlocksPerRow, nSubBlocksPerColumn );
             return FALSE;
         }
@@ -779,7 +779,7 @@
 
     if( papoBlocks == NULL )
     {
-        CPLError( CE_Failure, CPLE_OutOfMemory,
+        ReportError( CE_Failure, CPLE_OutOfMemory,
                   "Out of memory in InitBlockInfo()." );
         return FALSE;
     }
@@ -840,7 +840,7 @@
         papoBlocks[nSubBlock] = (GDALRasterBlock *) VSIMalloc(nSubGridSize);
         if( papoBlocks[nSubBlock] == NULL )
         {
-            CPLError( CE_Failure, CPLE_OutOfMemory,
+            ReportError( CE_Failure, CPLE_OutOfMemory,
                       "Out of memory in AdoptBlock()." );
             return CE_Failure;
         }
@@ -891,7 +891,7 @@
 
     if (eFlushBlockErr != CE_None)
     {
-        CPLError(eFlushBlockErr, CPLE_AppDefined,
+        ReportError(eFlushBlockErr, CPLE_AppDefined,
                  "An error occured while writing a dirty block");
         eFlushBlockErr = CE_None;
     }
@@ -1008,7 +1008,7 @@
 /* -------------------------------------------------------------------- */
     if( nXBlockOff < 0 || nXBlockOff >= nBlocksPerRow )
     {
-        CPLError( CE_Failure, CPLE_IllegalArg,
+        ReportError( CE_Failure, CPLE_IllegalArg,
                   "Illegal nBlockXOff value (%d) in "
                         "GDALRasterBand::FlushBlock()\n",
                   nXBlockOff );
@@ -1018,7 +1018,7 @@
 
     if( nYBlockOff < 0 || nYBlockOff >= nBlocksPerColumn )
     {
-        CPLError( CE_Failure, CPLE_IllegalArg,
+        ReportError( CE_Failure, CPLE_IllegalArg,
                   "Illegal nBlockYOff value (%d) in "
                         "GDALRasterBand::FlushBlock()\n",
                   nYBlockOff );
@@ -1125,7 +1125,7 @@
 /* -------------------------------------------------------------------- */
     if( nXBlockOff < 0 || nXBlockOff >= nBlocksPerRow )
     {
-        CPLError( CE_Failure, CPLE_IllegalArg,
+        ReportError( CE_Failure, CPLE_IllegalArg,
                   "Illegal nBlockXOff value (%d) in "
                         "GDALRasterBand::TryGetLockedBlockRef()\n",
                   nXBlockOff );
@@ -1135,7 +1135,7 @@
 
     if( nYBlockOff < 0 || nYBlockOff >= nBlocksPerColumn )
     {
-        CPLError( CE_Failure, CPLE_IllegalArg,
+        ReportError( CE_Failure, CPLE_IllegalArg,
                   "Illegal nBlockYOff value (%d) in "
                         "GDALRasterBand::TryGetLockedBlockRef()\n",
                   nYBlockOff );
@@ -1239,7 +1239,7 @@
     /* -------------------------------------------------------------------- */
         if( nXBlockOff < 0 || nXBlockOff >= nBlocksPerRow )
         {
-            CPLError( CE_Failure, CPLE_IllegalArg,
+            ReportError( CE_Failure, CPLE_IllegalArg,
                       "Illegal nBlockXOff value (%d) in "
                       "GDALRasterBand::GetLockedBlockRef()\n",
                       nXBlockOff );
@@ -1249,7 +1249,7 @@
 
         if( nYBlockOff < 0 || nYBlockOff >= nBlocksPerColumn )
         {
-            CPLError( CE_Failure, CPLE_IllegalArg,
+            ReportError( CE_Failure, CPLE_IllegalArg,
                       "Illegal nBlockYOff value (%d) in "
                       "GDALRasterBand::GetLockedBlockRef()\n",
                       nYBlockOff );
@@ -1281,10 +1281,10 @@
         {
             poBlock->DropLock();
             FlushBlock( nXBlockOff, nYBlockOff );
-            CPLError( CE_Failure, CPLE_AppDefined,
-		      "IReadBlock failed at X offset %d, Y offset %d",
-		      nXBlockOff, nYBlockOff );
-	    return( NULL );
+            ReportError( CE_Failure, CPLE_AppDefined,
+                "IReadBlock failed at X offset %d, Y offset %d",
+                nXBlockOff, nYBlockOff );
+            return( NULL );
         }
 
         if( !bJustInitialize )
@@ -1335,7 +1335,7 @@
 
     // Check we can write to the file
     if( eAccess == GA_ReadOnly ) {
-        CPLError(CE_Failure, CPLE_NoWriteAccess,
+        ReportError(CE_Failure, CPLE_NoWriteAccess,
                  "Attempt to write to read only dataset in"
                  "GDALRasterBand::Fill().\n" );
         return CE_Failure;
@@ -1351,7 +1351,7 @@
     int blockByteSize = blockSize * elementSize;
     unsigned char* srcBlock = (unsigned char*) VSIMalloc(blockByteSize);
     if (srcBlock == NULL) {
-	CPLError(CE_Failure, CPLE_OutOfMemory,
+        ReportError(CE_Failure, CPLE_OutOfMemory,
                  "GDALRasterBand::Fill(): Out of memory "
 		 "allocating %d bytes.\n", blockByteSize);
         return CE_Failure;
@@ -1372,7 +1372,7 @@
 	for (int i = 0; i < nBlocksPerRow; ++i) {
 	    GDALRasterBlock* destBlock = GetLockedBlockRef(i, j, TRUE);
 	    if (destBlock == NULL) {
-		CPLError(CE_Failure, CPLE_OutOfMemory,
+            ReportError(CE_Failure, CPLE_OutOfMemory,
 			 "GDALRasterBand::Fill(): Error "
 			 "while retrieving cache block.\n");
                 VSIFree(srcBlock);
@@ -1519,7 +1519,7 @@
 
 {
     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
-        CPLError( CE_Failure, CPLE_NotSupported,
+        ReportError( CE_Failure, CPLE_NotSupported,
                   "SetCategoryNames() not supported for this dataset." );
     
     return CE_Failure;
@@ -1617,7 +1617,7 @@
 
 {
     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
-        CPLError( CE_Failure, CPLE_NotSupported,
+        ReportError( CE_Failure, CPLE_NotSupported,
                   "SetNoDataValue() not supported for this dataset." );
 
     return CE_Failure;
@@ -1882,7 +1882,7 @@
 {
     (void) eColorInterp;
     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
-        CPLError( CE_Failure, CPLE_NotSupported,
+        ReportError( CE_Failure, CPLE_NotSupported,
                   "SetColorInterpretation() not supported for this dataset." );
     return CE_Failure;
 }
@@ -1974,7 +1974,7 @@
 {
     (void) poCT;
     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
-        CPLError( CE_Failure, CPLE_NotSupported,
+        ReportError( CE_Failure, CPLE_NotSupported,
                   "SetColorTable() not supported for this dataset." );
     return CE_Failure;
 }
@@ -2237,7 +2237,7 @@
     (void) pfnProgress;
     (void) pProgressData;
 
-    CPLError( CE_Failure, CPLE_NotSupported,
+    ReportError( CE_Failure, CPLE_NotSupported,
               "BuildOverviews() not supported for this dataset." );
     
     return( CE_Failure );
@@ -2315,7 +2315,7 @@
 
 {
     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
-        CPLError( CE_Failure, CPLE_NotSupported,
+        ReportError( CE_Failure, CPLE_NotSupported,
                   "SetOffset() not supported on this raster band." );
     
     return CE_Failure;
@@ -2413,7 +2413,7 @@
 
 {
     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
-        CPLError( CE_Failure, CPLE_NotSupported,
+        ReportError( CE_Failure, CPLE_NotSupported,
                   "SetScale() not supported on this raster band." );
     
     return CE_Failure;
@@ -2504,7 +2504,7 @@
 
 {
     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
-        CPLError( CE_Failure, CPLE_NotSupported, 
+        ReportError( CE_Failure, CPLE_NotSupported,
                   "SetUnitType() not supported on this raster band." );
     return CE_Failure;
 }
@@ -2765,7 +2765,7 @@
 
     if( !pfnProgress( 0.0, "Compute Histogram", pProgressData ) )
     {
-        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
+        ReportError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
         return CE_Failure;
     }
 
@@ -3205,7 +3205,7 @@
     *ppanHistogram = (int *) VSICalloc(sizeof(int), nBuckets);
     if( *ppanHistogram == NULL )
     {
-        CPLError( CE_Failure, CPLE_OutOfMemory,
+        ReportError( CE_Failure, CPLE_OutOfMemory,
                   "Out of memory in InitBlockInfo()." );
         return CE_Failure;
     }
@@ -3516,7 +3516,7 @@
 
     if( !pfnProgress( 0.0, "Compute Statistics", pProgressData ) )
     {
-        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
+        ReportError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
         return CE_Failure;
     }
 
@@ -3787,7 +3787,7 @@
                               / ((double)(nBlocksPerRow*nBlocksPerColumn)),
                               "Compute Statistics", pProgressData) )
             {
-                CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
+                ReportError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
                 return CE_Failure;
             }
         }
@@ -3795,7 +3795,7 @@
 
     if( !pfnProgress( 1.0, "Compute Statistics", pProgressData ) )
     {
-        CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
+        ReportError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
         return CE_Failure;
     }
 
@@ -3826,7 +3826,7 @@
         return CE_None;
     else
     {
-        CPLError( CE_Failure, CPLE_AppDefined,
+        ReportError( CE_Failure, CPLE_AppDefined,
         "Failed to compute statistics, no valid pixels found in sampling." );
         return CE_Failure;
     }
@@ -4256,7 +4256,7 @@
 
     if (bFirstValue)
     {
-        CPLError( CE_Failure, CPLE_AppDefined,
+        ReportError( CE_Failure, CPLE_AppDefined,
             "Failed to compute min/max, no valid pixels found in sampling." );
         return CE_Failure;
     }
@@ -4300,7 +4300,7 @@
 
 {
     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
-        CPLError( CE_Failure, CPLE_NotSupported,
+        ReportError( CE_Failure, CPLE_NotSupported,
                   "SetDefaultHistogram() not implemented for this format." );
 
     return CE_Failure;
@@ -4387,7 +4387,7 @@
 
 {
     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
-        CPLError( CE_Failure, CPLE_NotSupported,
+        ReportError( CE_Failure, CPLE_NotSupported,
                   "SetDefaultRAT() not implemented for this format." );
 
     return CE_Failure;
@@ -4510,13 +4510,13 @@
                 }
                 else
                 {
-                    CPLError(CE_Warning, CPLE_AppDefined,
+                    ReportError(CE_Warning, CPLE_AppDefined,
                             "All bands should have the same type in order the NODATA_VALUES metadata item to be used as a mask.");
                 }
             }
             else
             {
-                CPLError(CE_Warning, CPLE_AppDefined,
+                ReportError(CE_Warning, CPLE_AppDefined,
                         "NODATA_VALUES metadata item doesn't have the same number of values as the number of bands.\n"
                         "Ignoring it for mask.");
             }
@@ -4717,7 +4717,7 @@
         return CE_None;
     }
 
-    CPLError( CE_Failure, CPLE_NotSupported,
+    ReportError( CE_Failure, CPLE_NotSupported,
               "CreateMaskBand() not supported for this band." );
     
     return CE_Failure;
@@ -4899,3 +4899,46 @@
 {
     eFlushBlockErr = eErr;
 }
+
+/************************************************************************/
+/*                            ReportError()                             */
+/************************************************************************/
+
+/**
+ * \brief Emits an error related to a raster band.
+ *
+ * This function is a wrapper for regular CPLError(). The only difference
+ * with CPLError() is that it prepends the error message with the dataset
+ * name and the band number.
+ *
+ * @param eErrClass one of CE_Warning, CE_Failure or CE_Fatal.
+ * @param err_no the error number (CPLE_*) from cpl_error.h.
+ * @param fmt a printf() style format string.  Any additional arguments
+ * will be treated as arguments to fill in this format in a manner
+ * similar to printf().
+ *
+ * @since GDAL 1.9.0
+ */
+
+void GDALRasterBand::ReportError(CPLErr eErrClass, int err_no, const char *fmt, ...)
+{
+    va_list args;
+
+    va_start(args, fmt);
+
+    char szNewFmt[256];
+    const char* pszDSName = poDS ? poDS->GetDescription() : "";
+    if (strlen(fmt) + strlen(pszDSName) + 20 >= sizeof(szNewFmt) - 1)
+        pszDSName = CPLGetFilename(pszDSName);
+    if (strlen(fmt) + strlen(pszDSName) + 20 < sizeof(szNewFmt) - 1)
+    {
+        snprintf(szNewFmt, sizeof(szNewFmt), "%s, band %d: %s",
+                 pszDSName, GetBand(), fmt);
+        CPLErrorV( eErrClass, err_no, szNewFmt, args );
+    }
+    else
+    {
+        CPLErrorV( eErrClass, err_no, fmt, args );
+    }
+    va_end(args);
+}
Index: gcore/gdaldataset.cpp
===================================================================
--- gcore/gdaldataset.cpp	(révision 23068)
+++ gcore/gdaldataset.cpp	(copie de travail)
@@ -475,7 +475,7 @@
     (void) eType;
     (void) papszOptions;
 
-    CPLError( CE_Failure, CPLE_NotSupported, 
+    ReportError( CE_Failure, CPLE_NotSupported,
               "Dataset does not support the AddBand() method." );
 
     return CE_Failure;
@@ -526,7 +526,7 @@
                            MAX(nNewBand,nBands));
         if (papoNewBands == NULL)
         {
-            CPLError(CE_Failure, CPLE_OutOfMemory,
+            ReportError(CE_Failure, CPLE_OutOfMemory,
                      "Cannot allocate band array");
             return;
         }
@@ -543,7 +543,7 @@
 /* -------------------------------------------------------------------- */
     if( papoBands[nNewBand-1] != NULL )
     {
-        CPLError(CE_Failure, CPLE_NotSupported,
+        ReportError(CE_Failure, CPLE_NotSupported,
                  "Cannot set band %d as it is already set", nNewBand);
         return;
     }
@@ -663,7 +663,7 @@
     {
         if( nBandId < 1 || nBandId > nBands )
         {
-            CPLError( CE_Failure, CPLE_IllegalArg,
+            ReportError( CE_Failure, CPLE_IllegalArg,
                       "GDALDataset::GetRasterBand(%d) - Illegal band #\n",
                       nBandId );
             return NULL;
@@ -796,7 +796,7 @@
 
 {
     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
-        CPLError( CE_Failure, CPLE_NotSupported, 
+        ReportError( CE_Failure, CPLE_NotSupported,
                   "Dataset does not support the SetProjection() method." );
     return CE_Failure;
 }
@@ -912,7 +912,7 @@
 
 {
     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
-        CPLError( CE_Failure, CPLE_NotSupported,
+        ReportError( CE_Failure, CPLE_NotSupported,
                   "SetGeoTransform() not supported for this dataset." );
     
     return( CE_Failure );
@@ -1138,7 +1138,7 @@
     if(CPLHashSetLookup(phSharedDatasetSet, psStruct) != NULL)
     {
         CPLFree(psStruct);
-        CPLError(CE_Failure, CPLE_AppDefined,
+        ReportError(CE_Failure, CPLE_AppDefined,
                  "An existing shared dataset has already this description. This should not happen");
     }
     else
@@ -1304,7 +1304,7 @@
     (void) pszGCPProjection;
 
     if( !(GetMOFlags() & GMO_IGNORE_UNIMPLEMENTED) )
-        CPLError( CE_Failure, CPLE_NotSupported, 
+        ReportError( CE_Failure, CPLE_NotSupported,
                   "Dataset does not support the SetGCPs() method." );
 
     return CE_Failure;
@@ -1445,7 +1445,7 @@
                                           pfnProgress, pProgressData );
     else
     {
-        CPLError( CE_Failure, CPLE_NotSupported,
+        ReportError( CE_Failure, CPLE_NotSupported,
                   "BuildOverviews() not supported for this dataset." );
         
         return( CE_Failure );
@@ -1598,7 +1598,7 @@
 
     if( NULL == pData )
     {
-        CPLError( CE_Failure, CPLE_AppDefined, 
+        ReportError( CE_Failure, CPLE_AppDefined,
                   "The buffer into which the data should be read is null" );
             return CE_Failure;
     }
@@ -1630,7 +1630,7 @@
     {
         if (nPixelSpace > INT_MAX / nBufXSize)
         {
-            CPLError( CE_Failure, CPLE_AppDefined, 
+            ReportError( CE_Failure, CPLE_AppDefined,
                       "Int overflow : %d x %d", nPixelSpace, nBufXSize );
             return CE_Failure;
         }
@@ -1644,7 +1644,7 @@
     {
         if (nLineSpace > INT_MAX / nBufYSize)
         {
-            CPLError( CE_Failure, CPLE_AppDefined, 
+            ReportError( CE_Failure, CPLE_AppDefined,
                       "Int overflow : %d x %d", nLineSpace, nBufYSize );
             return CE_Failure;
         }
@@ -1655,7 +1655,7 @@
     {
         if (nBandCount > GetRasterCount())
         {
-            CPLError( CE_Failure, CPLE_IllegalArg, 
+            ReportError( CE_Failure, CPLE_IllegalArg,
                       "nBandCount cannot be greater than %d",
                       GetRasterCount() );
             return CE_Failure;
@@ -1663,7 +1663,7 @@
         panBandMap = (int *) VSIMalloc2(sizeof(int), nBandCount);
         if (panBandMap == NULL)
         {
-            CPLError( CE_Failure, CPLE_OutOfMemory, 
+            ReportError( CE_Failure, CPLE_OutOfMemory,
                       "Out of memory while allocating band map array" );
             return CE_Failure;
         }
@@ -1679,7 +1679,7 @@
     if( nXOff < 0 || nXOff > INT_MAX - nXSize || nXOff + nXSize > nRasterXSize
         || nYOff < 0 || nYOff > INT_MAX - nYSize || nYOff + nYSize > nRasterYSize )
     {
-        CPLError( CE_Failure, CPLE_IllegalArg,
+        ReportError( CE_Failure, CPLE_IllegalArg,
                   "Access window out of range in RasterIO().  Requested\n"
                   "(%d,%d) of size %dx%d on raster of %dx%d.",
                   nXOff, nYOff, nXSize, nYSize, nRasterXSize, nRasterYSize );
@@ -1688,7 +1688,7 @@
 
     if( eRWFlag != GF_Read && eRWFlag != GF_Write )
     {
-        CPLError( CE_Failure, CPLE_IllegalArg,
+        ReportError( CE_Failure, CPLE_IllegalArg,
                   "eRWFlag = %d, only GF_Read (0) and GF_Write (1) are legal.",
                   eRWFlag );
         eErr = CE_Failure;
@@ -1698,7 +1698,7 @@
     {
         if( panBandMap[i] < 1 || panBandMap[i] > GetRasterCount() )
         {
-            CPLError( CE_Failure, CPLE_IllegalArg, 
+            ReportError( CE_Failure, CPLE_IllegalArg,
                       "panBandMap[%d] = %d, this band does not exist on dataset.",
                       i, panBandMap[i] );
             eErr = CE_Failure;
@@ -1706,7 +1706,7 @@
 
         if( eErr == CE_None && GetRasterBand( panBandMap[i] ) == NULL )
         {
-            CPLError( CE_Failure, CPLE_IllegalArg, 
+            ReportError( CE_Failure, CPLE_IllegalArg,
                       "panBandMap[%d]=%d, this band should exist but is NULL!",
                       i, panBandMap[i] );
             eErr = CE_Failure;
@@ -2129,7 +2129,7 @@
         return CE_None;
     }
 
-    CPLError( CE_Failure, CPLE_NotSupported,
+    ReportError( CE_Failure, CPLE_NotSupported,
               "CreateMaskBand() not supported for this dataset." );
     
     return( CE_Failure );
@@ -2695,3 +2695,46 @@
 {
     return oOvManager.CloseDependentDatasets();
 }
+
+/************************************************************************/
+/*                            ReportError()                             */
+/************************************************************************/
+
+/**
+ * \brief Emits an error related to a dataset.
+ *
+ * This function is a wrapper for regular CPLError(). The only difference
+ * with CPLError() is that it prepends the error message with the dataset
+ * name.
+ *
+ * @param eErrClass one of CE_Warning, CE_Failure or CE_Fatal.
+ * @param err_no the error number (CPLE_*) from cpl_error.h.
+ * @param fmt a printf() style format string.  Any additional arguments
+ * will be treated as arguments to fill in this format in a manner
+ * similar to printf().
+ *
+ * @since GDAL 1.9.0
+ */
+
+void GDALDataset::ReportError(CPLErr eErrClass, int err_no, const char *fmt, ...)
+{
+    va_list args;
+
+    va_start(args, fmt);
+
+    char szNewFmt[256];
+    const char* pszDSName = GetDescription();
+    if (strlen(fmt) + strlen(pszDSName) + 3 >= sizeof(szNewFmt) - 1)
+        pszDSName = CPLGetFilename(pszDSName);
+    if (strlen(fmt) + strlen(pszDSName) + 3 < sizeof(szNewFmt) - 1)
+    {
+        snprintf(szNewFmt, sizeof(szNewFmt), "%s: %s",
+                 pszDSName, fmt);
+        CPLErrorV( eErrClass, err_no, szNewFmt, args );
+    }
+    else
+    {
+        CPLErrorV( eErrClass, err_no, fmt, args );
+    }
+    va_end(args);
+}
