Index: trunk/psModules/src/camera/pmFPAMaskWeight.c
===================================================================
--- trunk/psModules/src/camera/pmFPAMaskWeight.c	(revision 19155)
+++ trunk/psModules/src/camera/pmFPAMaskWeight.c	(revision 19163)
@@ -12,4 +12,6 @@
 #include "pmHDUGenerate.h"
 #include "pmFPAMaskWeight.h"
+
+#define PIXELS_BUFFER 100               // Size of buffer for allocating pixel lists
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -431,2 +433,81 @@
     return true;
 }
+
+
+bool pmReadoutInterpolateBadPixels(pmReadout *readout, psMaskType maskVal, psImageInterpolateMode mode,
+                                   float poorFrac, psMaskType maskPoor, psMaskType maskBad)
+{
+    PM_ASSERT_READOUT_NON_NULL(readout, false);
+    PM_ASSERT_READOUT_IMAGE(readout, false);
+    PM_ASSERT_READOUT_MASK(readout, false);
+    if (!maskVal) {
+        return true;
+    }
+
+    psImage *image = readout->image;    // Image
+    psImage *mask = readout->mask;      // Mask
+    psImage *weight = readout->weight;  // Weight map
+
+    psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(mode, image, weight, mask, maskVal,
+                                                                       NAN, NAN, maskBad, maskPoor, poorFrac);
+    interp->shifting = false;           // Turn off "exact shifts" so we get proper interpolation
+
+    int numCols = mask->numCols, numRows = mask->numRows; // Size of image
+
+    psPixels *pixels = psPixelsAllocEmpty(PIXELS_BUFFER); // Pixels that have been interpolated
+    psVector *imagePix = psVectorAllocEmpty(PIXELS_BUFFER, PS_TYPE_F32); // Corresponding values for image
+    psVector *weightPix = psVectorAllocEmpty(PIXELS_BUFFER, PS_TYPE_F32); // Corresponding values for weight
+    psVector *maskPix = psVectorAllocEmpty(PIXELS_BUFFER, PS_TYPE_MASK); // Corresponding values for mask
+
+    long numBad = 0;                    // Number of bad pixels interpolated
+    for (int y = 0; y < numRows; y++) {
+        for (int x = 0; x < numCols; x++) {
+            if (mask->data.PS_TYPE_MASK_DATA[y][x] & maskVal) {
+                double imageValue, weightValue; // Image and weight value from interpolation
+                psMaskType maskValue = 0; // Mask value from interpolation
+                psImageInterpolateStatus status = psImageInterpolate(&imageValue, &weightValue, &maskValue,
+                                                                     x, y, interp);
+                if (status == PS_INTERPOLATE_STATUS_ERROR || status == PS_INTERPOLATE_STATUS_OFF) {
+                    psError(PS_ERR_UNKNOWN, false, "Unable to interpolate readout at %d,%d", x, y);
+                    psFree(interp);
+                    psFree(pixels);
+                    psFree(imagePix);
+                    psFree(weightPix);
+                    psFree(maskPix);
+                    return false;
+                }
+                if (status == PS_INTERPOLATE_STATUS_BAD) {
+                    // It's still bad: couldn't interpolate enough
+                    continue;
+                }
+
+                pixels = psPixelsAdd(pixels, PIXELS_BUFFER, x, y);
+                imagePix = psVectorExtend(imagePix, PIXELS_BUFFER, 1);
+                weightPix = psVectorExtend(weightPix, PIXELS_BUFFER, 1);
+                maskPix = psVectorExtend(maskPix, PIXELS_BUFFER, 1);
+                imagePix->data.F32[numBad] = imageValue;
+                weightPix->data.F32[numBad] = weightValue;
+                maskPix->data.PS_TYPE_MASK_DATA[numBad] = maskValue;
+                numBad++;
+            }
+        }
+    }
+
+    psFree(interp);
+
+    for (long i = 0; i < numBad; i++) {
+        int x = pixels->data[i].x, y = pixels->data[i].y; // Coordinates of pixel
+        image->data.F32[y][x] = imagePix->data.F32[i];
+        weight->data.F32[y][x] = weightPix->data.F32[i];
+        mask->data.PS_TYPE_MASK_DATA[y][x] = maskPix->data.PS_TYPE_MASK_DATA[i];
+    }
+
+    psFree(pixels);
+    psFree(imagePix);
+    psFree(weightPix);
+    psFree(maskPix);
+
+    psLogMsg("psModules.camera", PS_LOG_INFO, "Interpolated over %ld pixels", numBad);
+
+    return true;
+}
Index: trunk/psModules/src/camera/pmFPAMaskWeight.h
===================================================================
--- trunk/psModules/src/camera/pmFPAMaskWeight.h	(revision 19155)
+++ trunk/psModules/src/camera/pmFPAMaskWeight.h	(revision 19163)
@@ -5,6 +5,6 @@
  * @author Eugene Magnier, IfA
  *
- * @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
- * @date $Date: 2008-07-15 20:25:00 $
+ * @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ * @date $Date: 2008-08-22 22:25:22 $
  * Copyright 2005-2006 Institute for Astronomy, University of Hawaii
  */
@@ -123,4 +123,14 @@
     );
 
+/// Interpolate over bad pixels
+///
+/// Scan the mask image for bad pixels, and interpolate over them using the nominated options
+bool pmReadoutInterpolateBadPixels(pmReadout *readout, ///< Readout to work on
+                                   psMaskType maskVal, ///< Value to mask
+                                   psImageInterpolateMode mode, ///< Interpolation mode
+                                   float poorFrac, ///< Maximum bad fraction of kernel for "poor" status
+                                   psMaskType maskPoor, ///< Mask value to give poor pixels
+                                   psMaskType maskBad ///< Mask value to give bad pixels
+    );
 
 /// @}
