Index: trunk/psModules/src/imcombine/pmReadoutCombine.c
===================================================================
--- trunk/psModules/src/imcombine/pmReadoutCombine.c	(revision 13768)
+++ trunk/psModules/src/imcombine/pmReadoutCombine.c	(revision 13871)
@@ -13,4 +13,5 @@
 #include "pmFPAMaskWeight.h"
 #include "pmConceptsAverage.h"
+#include "pmReadoutStack.h"
 
 #include "pmReadoutCombine.h"
@@ -66,4 +67,12 @@
         return false;
     }
+    for (int i = 0; i < inputs->n; i++) {
+        pmReadout *readout = inputs->data[i]; // Readout of interest
+        if (params->weights && !readout->weight) {
+            psError(PS_ERR_UNEXPECTED_NULL, true,
+                    "Rejection based on weights requested, but no weights supplied for image %d.\n", i);
+            return false;
+        }
+    }
 
     bool first = !output->image;        // First pass through?
@@ -96,98 +105,14 @@
     }
 
-    // Step through each readout in the input image list to determine how big of an output image is needed to
-    // combine these input images.
-    int maxInputCols = 0;               // The largest input column value
-    int maxInputRows = 0;               // The largest input row value
-    int minInputCols = INT_MAX;         // The smallest input column value
-    int minInputRows = INT_MAX;         // The smallest input row value
-    int xSize = 0, ySize = 0;           // The size of the output image
-
-    int xMin = INT_MAX;
-    int yMin = INT_MAX;
-    int xMax = 0;
-    int yMax = 0;
-
-    bool valid = false;                 // Do we have a single valid input?
-    for (long i = 0; i < inputs->n; i++) {
-        pmReadout *readout = inputs->data[i]; // Readout of interest
-
-        if (!readout || !readout->image) {
-            psError(PS_ERR_UNEXPECTED_NULL, true, "Input readout %ld is NULL or has NULL image.\n", i);
-            return false;
-        }
-
-	// use the trimsec to define the max full range of the output pixels
-        pmCell *cell = readout->parent; // The parent cell
-        bool mdok = true;       // Status of MD lookup
-        psRegion *trimsec = psMetadataLookupPtr(&mdok, cell->concepts, "CELL.TRIMSEC"); // Trim section
-        if (!mdok || !trimsec || psRegionIsNaN(*trimsec)) {
-            psLogMsg(__func__, PS_LOG_WARN, "CELL.TRIMSEC is not set for readout %ld --- ignored.\n", i);
-        } else {
-            xSize = PS_MAX(xSize, trimsec->x1 - trimsec->x0);
-            ySize = PS_MAX(ySize, trimsec->y1 - trimsec->y0);
-	    xMin  = PS_MIN(xMin,  trimsec->x0);
-	    xMax  = PS_MAX(xMax,  trimsec->x1);
-	    yMin  = PS_MIN(yMin,  trimsec->y0);
-	    yMax  = PS_MAX(yMax,  trimsec->y1);
-        }
-
-        if (params->weights && !readout->weight) {
-            psError(PS_ERR_UNEXPECTED_NULL, true,
-                    "Rejection based on weights requested, but no weights supplied for image %ld.\n", i);
-            return false;
-        }
-
-        valid = true;
-
-        // Range of pixels on output image
-        minInputCols = PS_MAX (xMin, PS_MIN(minInputCols, readout->col0));
-        maxInputCols = PS_MIN (xMax, PS_MAX(maxInputCols, readout->col0 + readout->image->numCols));
-        minInputRows = PS_MAX (yMin, PS_MIN(minInputRows, readout->row0));
-        maxInputRows = PS_MIN (yMax, PS_MAX(maxInputRows, readout->row0 + readout->image->numRows));
-        psTrace("psModules.imcombine", 7, "Readout %ld: offset %d,%d; size %dx%d\n", i,
-                readout->col0, readout->row0, readout->image->numCols, readout->image->numRows);
-    }
-
-    if (!valid) {
-        psError(PS_ERR_IO, true, "No valid inputs.\n");
-        return NULL;
-    }
-
-    // Update the origin
-    // XXX EAM : use a macro (see psImage.h for PS_IMAGE_SET_ROW0, etc)
-    if (output->image) {
-        *(psS32 *) &(output->col0) = PS_MIN(minInputCols, output->col0);
-        *(psS32 *) &(output->row0) = PS_MIN(minInputRows, output->row0);
-    } else {
-        *(psS32 *) &(output->col0) = minInputCols;
-        *(psS32 *) &(output->row0) = minInputRows;
-    }
+    int minInputCols, maxInputCols, minInputRows, maxInputRows; // Smallest and largest values to combine
+    int xSize, ySize;                   // Size of the output image
+    if (!pmReadoutStackValidate(&minInputCols, &maxInputCols, &minInputRows, &maxInputRows, &xSize, &ySize,
+                                inputs)) {
+        psError(PS_ERR_UNKNOWN, false, "No valid input readouts.");
+        return false;
+    }
+
+    pmReadoutUpdateSize(output, minInputCols, minInputRows, xSize, ySize, true);
     psTrace("psModules.imcombine", 7, "Output minimum: %d,%d\n", output->col0, output->row0);
-
-    // Allocate the output products
-
-    if (!output->image) {
-        output->image = psImageAlloc(xSize, ySize, PS_TYPE_F32);
-    }
-    if (output->image->numCols < xSize || output->image->numRows < ySize) {
-        // Generate the new output image by extending the current one, or making a whole new one
-        psImage *newImage = psImageAlloc(xSize, ySize, PS_TYPE_F32);
-        psImageInit(newImage, 0.0);
-        psImageOverlaySection(newImage, output->image, output->col0, output->row0, "=");
-        psFree(output->image);
-        output->image = newImage;
-    }
-
-    if (!output->mask) {
-        output->mask = psImageAlloc(xSize, ySize, PS_TYPE_U8);
-    }
-    if (output->mask->numCols < xSize || output->mask->numRows < ySize) {
-        psImage *newMask = psImageAlloc(xSize, ySize, PS_TYPE_U8);
-        psImageInit(newMask, 0);
-        psImageOverlaySection(newMask, output->mask, output->col0, output->row0, "=");
-        psFree(output->mask);
-        output->mask = newMask;
-    }
 
     psStatsOptions combineStdev = 0; // Statistics option for weights
@@ -426,4 +351,8 @@
     psFree(inputCells);
 
+    output->data_exists = true;
+    output->parent->data_exists = true;
+    output->parent->parent->data_exists = true;
+
     return success;
 }
