Index: trunk/psModules/src/imcombine/pmSubtraction.c
===================================================================
--- trunk/psModules/src/imcombine/pmSubtraction.c	(revision 15319)
+++ trunk/psModules/src/imcombine/pmSubtraction.c	(revision 15325)
@@ -4,6 +4,6 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.64 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2007-10-16 21:38:24 $
+ *  @version $Revision: 1.65 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-10-17 02:45:40 $
  *
  *  Copyright 2004-2007 Institute for Astronomy, University of Hawaii
@@ -459,5 +459,5 @@
 
 psImage *pmSubtractionMask(const psImage *refMask, const psImage *inMask, psMaskType maskVal,
-                           int size, int footprint, float badFrac)
+                           int size, int footprint, float badFrac, bool useFFT)
 {
     PS_ASSERT_IMAGE_NON_NULL(refMask, NULL);
@@ -540,55 +540,62 @@
     // skycell isn't overlapped by a large fraction by the observation), so that convolving around every bad
     // pixel is wasting time.  As a first cut, I've put in a check on the fraction of bad pixels, but we could
-    // imagine looking for the edge of big regions and convolving just at the edge.
-
-    // Mask the bad pixels, and around them
+    // imagine looking for the edge of big regions and convolving just at the edge.  As a second cut, allow
+    // use of FFT convolution.
+
     for (int y = 0; y < numRows; y++) {
         for (int x = 0; x < numCols; x++) {
             if (inData && inData[y][x] & maskVal) {
                 maskData[y][x] |= PM_SUBTRACTION_MASK_INPUT;
-                // Block out the entire stamp footprint around this pixel
-                for (int v = PS_MAX(y - footprint, 0); v <= PS_MIN(y + footprint, numRows - 1); v++) {
-                    for (int u = PS_MAX(x - footprint, 0); u <= PS_MIN(x + footprint, numCols - 1); u++) {
-                        maskData[v][u] |= PM_SUBTRACTION_MASK_FOOTPRINT;
-                    }
-                }
             }
             if (refData[y][x] & maskVal) {
                 maskData[y][x] |= PM_SUBTRACTION_MASK_REF;
-
-                // We want to block out with the CONVOLVE mask anything that would be bad if we convolved with
-                // this bad pixel (within 'size').  Then we want to block out with the FOOTPRINT mask
-                // everything within a footprint's distance of those (within 'footprint').
-
-                // Bottom stripe
-                for (int v = PS_MAX(y - footprint - size, 0); v < y - size; v++) {
-                    for (int u = PS_MAX(x - footprint - size, 0);
-                         u <= PS_MIN(x + footprint + size, numCols - 1); u++) {
-                        maskData[v][u] |= PM_SUBTRACTION_MASK_FOOTPRINT;
-                    }
-                }
-                // Middle
-                for (int v = PS_MAX(y - size, 0); v <= PS_MIN(y + size, numRows - 1); v++) {
-                    // Left side
-                    for (int u = PS_MAX(x - footprint - size, 0); u < x - size; u++) {
-                        maskData[v][u] |= PM_SUBTRACTION_MASK_FOOTPRINT;
-                    }
-                    // Centre
-                    for (int u = PS_MAX(x - size, 0); u <= PS_MIN(x + size, numCols - 1); u++) {
-                        maskData[v][u] |= PM_SUBTRACTION_MASK_FOOTPRINT | PM_SUBTRACTION_MASK_CONVOLVE;
-                    }
-                    // Right side
-                    for (int u = x + size + 1; u <= PS_MIN(x + footprint + size, numCols - 1); u++) {
-                        maskData[v][u] |= PM_SUBTRACTION_MASK_FOOTPRINT;
-                    }
-                }
-                // Top stripe
-                for (int v = y + size + 1; v <= PS_MIN(y + footprint + size, numRows - 1); v++) {
-                    for (int u = PS_MAX(x - footprint - size, 0);
-                         u <= PS_MIN(x + footprint + size, numCols - 1); u++) {
-                        maskData[v][u] |= PM_SUBTRACTION_MASK_FOOTPRINT;
-                    }
-                }
-            }
+            }
+        }
+    }
+
+    // Block out the entire stamp footprint around bad input pixels.
+
+    // We want to block out with the CONVOLVE mask anything that would be bad if we convolved with a bad
+    // reference pixel (within 'size').  Then we want to block out with the FOOTPRINT mask everything within a
+    // footprint's distance of those (within 'footprint').
+
+    if (useFFT) {
+        if (!psImageConvolveMaskFFT(mask, mask, PM_SUBTRACTION_MASK_INPUT, PM_SUBTRACTION_MASK_FOOTPRINT,
+                                    -footprint, footprint, -footprint, footprint, 0.5)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to convolve bad input pixels.");
+            psFree(mask);
+            return NULL;
+        }
+        if (!psImageConvolveMaskFFT(mask, mask, PM_SUBTRACTION_MASK_REF, PM_SUBTRACTION_MASK_CONVOLVE,
+                                    -size, size, -size, size, 0.5)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to convolve bad reference pixels.");
+            psFree(mask);
+            return NULL;
+        }
+        if (!psImageConvolveMaskFFT(mask, mask, PM_SUBTRACTION_MASK_CONVOLVE, PM_SUBTRACTION_MASK_FOOTPRINT,
+                                    -footprint, footprint, -footprint, footprint, 0.5)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to reconvolve bad reference pixels.");
+            psFree(mask);
+            return NULL;
+        }
+    } else {
+        if (!psImageConvolveMaskDirect(mask, mask, PM_SUBTRACTION_MASK_INPUT, PM_SUBTRACTION_MASK_FOOTPRINT,
+                                       -footprint, footprint, -footprint, footprint)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to convolve bad input pixels.");
+            psFree(mask);
+            return NULL;
+        }
+        if (!psImageConvolveMaskDirect(mask, mask, PM_SUBTRACTION_MASK_REF, PM_SUBTRACTION_MASK_CONVOLVE,
+                                   -size, size, -size, size)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to convolve bad reference pixels.");
+            psFree(mask);
+            return NULL;
+        }
+        if (!psImageConvolveMaskDirect(mask, mask, PM_SUBTRACTION_MASK_CONVOLVE,
+                                       PM_SUBTRACTION_MASK_FOOTPRINT,
+                                       -footprint, footprint, -footprint, footprint)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to reconvolve bad reference pixels.");
+            psFree(mask);
+            return NULL;
         }
     }
