Index: trunk/ppImage/src/ppImageDetrendPedestal.c
===================================================================
--- trunk/ppImage/src/ppImageDetrendPedestal.c	(revision 5857)
+++ trunk/ppImage/src/ppImageDetrendPedestal.c	(revision 5858)
@@ -1,9 +1,15 @@
 # include "ppImage.h"
 
-psImage *ppDetrendPedestal (pmCell *input, psImage *bias, psImage *dark, ppRecipe *options) {
+// XXX check on image overlaps, as well as image sizes
+// XXX what constraints do we put on the detrend images?
+// XXX this function is much easier if we can assume all detrend images
+//     should have the same size and represent the same pixels...
 
-    psImage *pedestal = NULL;       // Pedestal image (bias + scaled dark)
+pmReadout *ppDetrendPedestal (pmReadout *pedestal, pmCell *input, pmReadout *bias, pmReadout *dark, float darkTime, ppOptions *options) {
 
 #ifdef PRODUCTION
+    static float lastExptime = 0.0;
+    bool reusePedestal = true;
+
     if (options->doDark) {
 	// Dark time for input image
@@ -14,23 +20,55 @@
 	    exit(EXIT_FAILURE);
 	}
-	pedestal = (psImage*)psBinaryOp(NULL, dark, "*", psScalarAlloc(inputTime * darkTime, PS_TYPE_F32));
+
+	if (inputTime != lastExptime) {
+	    // this will create a new pedestal if the input one is NULL
+	    // XXX EAM : this function had darkTime * inputTime, which is wrong, yes?
+	    if (pedestal == NULL) {
+		pedestal = pmReadoutAlloc (NULL);
+	    }
+	    pedestal->col0    = dark->col0;
+	    pedestal->row0    = dark->row0;
+	    pedestal->colBins = dark->colBins;
+	    pedestal->rowBins = dark->rowBins;
+
+	    pedestal->image   = (psImage *) psBinaryOp(pedestal->image, dark->image, "*", psScalarAlloc(inputTime / darkTime, PS_TYPE_F32));
+	    reusePedestal = false;
+	    lastExptime = inputTime
+	}
     }
-    if (options->doBias) {
-	if (pedestal) {
-	    if (bias->numRows != dark->numRows ||
-		bias->numCols != dark->numCols) {
-		psError(PS_ERR_IO, true, "Bias and dark images have different dimensions: "
-			"%dx%d vs %dx%d\n", bias->numCols, bias->numRows,
-			dark->numCols, dark->numRows);
-		exit(EXIT_FAILURE);
-	    }
-	    (void)psBinaryOp(pedestal, pedestal, "+", bias);
-	} else {
+
+    // no bias image, return dark pedestal or NULL
+    if (!options->doBias) {
+	return pedestal;
+    }
+
+    // no dark image, return bias pedestal, or reuse
+    if (!options->doDark) {
+	if (!pedestal) {
 	    pedestal = psMemIncrRefCounter(bias);
 	}
+	return pedestal;
     }
+
+    if (reusePedestal) {
+	return pedestal;
+    }
+
+    if (bias->image->numRows != dark->image->numRows ||
+	bias->image->numCols != dark->image->numCols) {
+	psError(PS_ERR_IO, true, "Bias and dark images have different dimensions: %dx%d vs %dx%d\n", 
+		bias->image->numCols, bias->image->numRows,
+		dark->image->numCols, dark->image->numRows);
+	exit(EXIT_FAILURE);
+    }
+
+    psBinaryOp(pedestal->image, pedestal->image, "+", bias->image);
+    return pedestal;
+#else
+    return NULL;
 #endif
-
-    return pedestal;
 }
 
+// creates a new pedestal image for this readout
+// if the current exptime is the same as the last exptime, 
+// reuses the supplied pedestal
