--- gdalgeoloc.cpp-trunk	2008-08-07 09:47:56.942138420 +0100
+++ gdalgeoloc.cpp	2008-08-07 10:31:29.483985249 +0100
@@ -143,6 +143,7 @@
 {
     int nXSize = GDALGetRasterXSize( psTransform->hDS_X );
     int nYSize = GDALGetRasterYSize( psTransform->hDS_X );
+	int iMaxIter = 3;
 
 /* -------------------------------------------------------------------- */
 /*      Scan forward map for lat/long extents.                          */
@@ -228,6 +229,8 @@
 /* -------------------------------------------------------------------- */
 /*      Run through the whole geoloc array forward projecting and       */
 /*      pushing into the backmap.                                       */
+/*      Initialise to the iMaxIter+1 value so we can spot genuinely     */
+/*      valid pixels in the hole-filling loop.                          */
 /* -------------------------------------------------------------------- */
     int iBMX, iBMY;
     int iX, iY;
@@ -253,7 +256,7 @@
             psTransform->pafBackMapY[iBMX + iBMY * nBMXSize] = 
                 (float)(iY * psTransform->dfLINE_STEP + psTransform->dfLINE_OFFSET);
 
-            pabyValidFlag[iBMX + iBMY * nBMXSize] = 1;
+            pabyValidFlag[iBMX + iBMY * nBMXSize] = iMaxIter+1;
 
         }
     }
@@ -264,55 +267,98 @@
 /* -------------------------------------------------------------------- */
     int iIter;
 
-    for( iIter = 0; iIter < 3; iIter++ )
+	int iNumValid, iExpectedValid;
+
+    for( iIter = 0; iIter < iMaxIter; iIter++ )
     {
+		iNumValid = 0;
+		iExpectedValid = (nBMYSize - 2) * (nBMXSize - 2);
         for( iBMY = 1; iBMY < nBMYSize-1; iBMY++ )
         {
             for( iBMX = 1; iBMX < nBMXSize-1; iBMX++ )
             {
                 // if this point is already set, ignore it. 
                 if( pabyValidFlag[iBMX + iBMY*nBMXSize] )
+				{
+					iNumValid++;
                     continue;
+				}
 
                 int nCount = 0;
                 double dfXSum = 0.0, dfYSum = 0.0;
+				int iMarkedAsGood = iMaxIter - iIter;
 
                 // left?
-                if( iBMX > 0 && pabyValidFlag[iBMX-1+iBMY*nBMXSize] )
+                if( (iBMX > 0) && (pabyValidFlag[iBMX-1+iBMY*nBMXSize] > iMarkedAsGood) )
                 {
                     dfXSum += psTransform->pafBackMapX[iBMX-1+iBMY*nBMXSize];
                     dfYSum += psTransform->pafBackMapY[iBMX-1+iBMY*nBMXSize];
                     nCount++;
                 }
                 // right?
-                if( iBMX < nBMXSize-1 && pabyValidFlag[iBMX+1+iBMY*nBMXSize] )
+                if( (iBMX < nBMXSize-1) && (pabyValidFlag[iBMX+1+iBMY*nBMXSize] > iMarkedAsGood) )
                 {
                     dfXSum += psTransform->pafBackMapX[iBMX+1+iBMY*nBMXSize];
                     dfYSum += psTransform->pafBackMapY[iBMX+1+iBMY*nBMXSize];
                     nCount++;
                 }
                 // top?
-                if( iBMY > 0 && pabyValidFlag[iBMX+(iBMY-1)*nBMXSize] )
+                if( (iBMY > 0) && (pabyValidFlag[iBMX+(iBMY-1)*nBMXSize] > iMarkedAsGood) )
                 {
                     dfXSum += psTransform->pafBackMapX[iBMX+(iBMY-1)*nBMXSize];
                     dfYSum += psTransform->pafBackMapY[iBMX+(iBMY-1)*nBMXSize];
                     nCount++;
                 }
                 // bottom?
-                if( iBMY < nBMYSize-1 && pabyValidFlag[iBMX+(iBMY+1)*nBMXSize] )
+                if( (iBMY < nBMYSize-1) && (pabyValidFlag[iBMX+(iBMY+1)*nBMXSize] > iMarkedAsGood) )
                 {
                     dfXSum += psTransform->pafBackMapX[iBMX+(iBMY+1)*nBMXSize];
                     dfYSum += psTransform->pafBackMapY[iBMX+(iBMY+1)*nBMXSize];
                     nCount++;
                 }
+				// top-left?
+                if( (iBMX > 0) && (iBMY > 0) && (pabyValidFlag[iBMX-1+(iBMY-1)*nBMXSize] > iMarkedAsGood) )
+				{
+                    dfXSum += psTransform->pafBackMapX[iBMX-1+(iBMY-1)*nBMXSize];
+                    dfYSum += psTransform->pafBackMapY[iBMX-1+(iBMY-1)*nBMXSize];
+                    nCount++;
+				}
+				// top-right?
+                if( (iBMX < nBMXSize-1) && (pabyValidFlag[iBMX+1+(iBMY-1)*nBMXSize] > iMarkedAsGood) )
+				{
+                    dfXSum += psTransform->pafBackMapX[iBMX+1+(iBMY-1)*nBMXSize];
+                    dfYSum += psTransform->pafBackMapY[iBMX+1+(iBMY-1)*nBMXSize];
+                    nCount++;
+				}
+				// bottom-left?
+                if( (iBMY < nBMYSize-1) && (iBMX > 0) && (pabyValidFlag[iBMX-1+(iBMY+1)*nBMXSize] > iMarkedAsGood) )
+				{
+                    dfXSum += psTransform->pafBackMapX[iBMX-1+(iBMY+1)*nBMXSize];
+                    dfYSum += psTransform->pafBackMapY[iBMX-1+(iBMY+1)*nBMXSize];
+                    nCount++;
+				}
+				// bottom-right?
+                if( (iBMY < nBMYSize-1) && (iBMX < nBMXSize-1) && (pabyValidFlag[iBMX+1+(iBMY+1)*nBMXSize] > iMarkedAsGood) )
+				{
+                    dfXSum += psTransform->pafBackMapX[iBMX+1+(iBMY+1)*nBMXSize];
+                    dfYSum += psTransform->pafBackMapY[iBMX+1+(iBMY+1)*nBMXSize];
+                    nCount++;
+				}
 
                 if( nCount > 0 )
                 {
                     psTransform->pafBackMapX[iBMX + iBMY * nBMXSize] = (float)(dfXSum/nCount);
                     psTransform->pafBackMapY[iBMX + iBMY * nBMXSize] = (float)(dfYSum/nCount);
+					// genuinely valid points will have value iMaxIter+1
+					// On each iteration mark newly valid points with a
+					// descending value so that it will not be used on the
+					// current iteration only on subsequent ones.
+					pabyValidFlag[iBMX+iBMY*nBMXSize] = iMaxIter - iIter;
                 }
             }
         }
+		if (iNumValid == iExpectedValid)
+			break;
     }
 
 #ifdef notdef

