Index: trunk/psModules/src/camera/pmFPAMosaic.c
===================================================================
--- trunk/psModules/src/camera/pmFPAMosaic.c	(revision 11786)
+++ trunk/psModules/src/camera/pmFPAMosaic.c	(revision 12589)
@@ -382,104 +382,7 @@
 }
 
-// Mosaic multiple images, with flips, binning and offsets
-static psImage *imageMosaic(const psArray *source, // Images to splice in
-                            const psVector *xFlip, const psVector *yFlip, // Need to flip x and y?
-                            const psVector *xBinSource, // Binning in x of source images
-                            const psVector *yBinSource, // Binning in y of source images
-                            int xBinTarget, int yBinTarget, // Binning in x and y of target images
-                            const psVector *x0, const psVector *y0 // Offsets for source images on target
-                           )
-{
-    assert(source);
-    assert(xFlip && xFlip->type.type == PS_TYPE_U8);
-    assert(yFlip && yFlip->type.type == PS_TYPE_U8);
-    assert(xBinSource && xBinSource->type.type == PS_TYPE_S32);
-    assert(yBinSource && yBinSource->type.type == PS_TYPE_S32);
-    assert(x0 && x0->type.type == PS_TYPE_S32);
-    assert(y0 && y0->type.type == PS_TYPE_S32);
-    assert(xFlip->n == source->n);
-    assert(yFlip->n == source->n);
-    assert(xBinSource->n == source->n);
-    assert(yBinSource->n == source->n);
-    assert(x0->n == source->n);
-    assert(y0->n == source->n);
-
-    if (source->n == 0) {
-        return NULL;
-    }
-
-    // Get the maximum extent of the mosaic image
-    int xMin = INT_MAX;
-    int xMax = - INT_MAX;
-    int yMin = INT_MAX;
-    int yMax = - INT_MAX;
-    psElemType type = 0;
-    int numImages = 0;                  // Number of images
-    psTrace("psModules.camera", 3, "Mosaicking %ld cells.\n", source->n);
-    for (int i = 0; i < source->n; i++) {
-        psImage *image = source->data[i]; // The image of interest
-        if (!image) {
-            continue;
-        }
-        numImages++;
-
-        // Only implemented for F32 and U8 images so far.
-        assert(image->type.type == PS_TYPE_F32 || image->type.type == PS_TYPE_U8);
-        // All input types must be the same
-        if (type == 0) {
-            type = image->type.type;
-        }
-        assert(type == image->type.type);
-
-        // Size of cell in x and y
-        int xParity = xFlip->data.U8[i] ? -1 : 1;
-        int yParity = yFlip->data.U8[i] ? -1 : 1;
-        psTrace("psModules.camera", 5, "Extent of cell %d: %d -> %d , %d -> %d\n", i, x0->data.S32[i],
-                x0->data.S32[i] + xParity * xBinSource->data.S32[i] * image->numCols, y0->data.S32[i],
-                y0->data.S32[i] + yParity * yBinSource->data.S32[i] * image->numRows);
-
-        COMPARE(x0->data.S32[i], xMin, xMax);
-        COMPARE(y0->data.S32[i], yMin, yMax);
-        // Subtract the parity to get the inclusive limit (not exclusive)
-        COMPARE(x0->data.S32[i] + xParity * xBinSource->data.S32[i] * image->numCols - xParity, xMin, xMax);
-        COMPARE(y0->data.S32[i] + yParity * yBinSource->data.S32[i] * image->numRows - yParity, yMin, yMax);
-    }
-    if (numImages == 0) {
-        return NULL;
-    }
-
-    // Set up the image
-    // Since both upper and lower values are inclusive, we need to add one to the size
-    float xSize = (float)(xMax - xMin + 1) / (float)xBinTarget;
-    if (xSize - (int)xSize > 0) {
-        xSize += 1;
-    }
-    float ySize = (float)(yMax - yMin + 1) / (float)yBinTarget;
-    if (ySize - (int)ySize > 0) {
-        ySize += 1;
-    }
-
-    psTrace("psModules.camera", 3, "Spliced image will be %dx%d\n", (int)xSize, (int)ySize);
-    psImage *mosaic = psImageAlloc((int)xSize, (int)ySize, type); // The mosaic image
-    psImageInit(mosaic, 0);
-
-    // Next pass through the images to do the mosaicking
-    for (int i = 0; i < source->n; i++) {
-        psImage *image = source->data[i]; // The image of interest
-        if (!image) {
-            continue;
-        }
-        int xParity = xFlip->data.U8[i] ? -1 : 1; // Parity difference, in x
-        int yParity = yFlip->data.U8[i] ? -1 : 1; // Parity difference, in y
-        int xTargetBase = (x0->data.S32[i] - xMin) / xBinTarget; // The base x position in the target frame
-        int yTargetBase = (y0->data.S32[i] - yMin) / yBinTarget; // The base y position in the target frame
-        if (xBinSource->data.S32[i] == xBinTarget && yBinSource->data.S32[i] == yBinTarget &&
-                xFlip->data.U8[i] == 0 && yFlip->data.U8[i] == 0) {
-            // Let someone else do the hard work
-            psImageOverlaySection(mosaic, image, xTargetBase, yTargetBase, "+");
-        } else if (xBinSource->data.S32[i] == xBinTarget && yBinSource->data.S32[i] == yBinTarget) {
-            // There's a difference with the parities, but we don't have to worry about binning
-
-            #define COPY_WITH_PARITY_DIFFERENCE(TYPE) \
+// supporting macros used by imageMosaic()
+// copy pixels without binning
+#define COPY_WITH_PARITY_DIFFERENCE(TYPE) \
         case PS_TYPE_##TYPE: { \
                 for (int y = 0; y < image->numRows; y++) { \
@@ -493,17 +396,8 @@
             break;
 
-            switch (type) {
-                COPY_WITH_PARITY_DIFFERENCE(F32);
-                COPY_WITH_PARITY_DIFFERENCE(U8);
-            default:
-                psAbort("Should never get here.\n");
-            }
-
-        } else {
-            // We have to do all of the hard work ourself
-
-            // In case the original image is binned but the mosaic is not, we need to fill in the
-            // values in the mosaic.
-            #define FILL_IN(TYPE) \
+// In case the original image is binned but the mosaic is not, we need to fill in the values in
+// the mosaic.  this operation should be replaced with a call to one of the functions defined
+// in psImageBinning
+#define FILL_IN(TYPE) \
         case PS_TYPE_##TYPE: \
             for (int y = 0; y < image->numRows; y++) { \
@@ -522,17 +416,132 @@
             break;
 
+// Mosaic multiple images, with flips, binning and offsets
+static psImage *imageMosaic(const psArray *source, // Images to splice in
+                            const psVector *xFlip, const psVector *yFlip, // Need to flip x and y?
+                            const psVector *xBinSource, // Binning in x of source images
+                            const psVector *yBinSource, // Binning in y of source images
+                            int xBinTarget, int yBinTarget, // Binning in x and y of target images
+                            const psVector *x0, const psVector *y0 // Offsets for source images on target
+                           )
+{
+    assert(source);
+    assert(xFlip && xFlip->type.type == PS_TYPE_U8);
+    assert(yFlip && yFlip->type.type == PS_TYPE_U8);
+    assert(xBinSource && xBinSource->type.type == PS_TYPE_S32);
+    assert(yBinSource && yBinSource->type.type == PS_TYPE_S32);
+    assert(x0 && x0->type.type == PS_TYPE_S32);
+    assert(y0 && y0->type.type == PS_TYPE_S32);
+    assert(xFlip->n == source->n);
+    assert(yFlip->n == source->n);
+    assert(xBinSource->n == source->n);
+    assert(yBinSource->n == source->n);
+    assert(x0->n == source->n);
+    assert(y0->n == source->n);
+
+    if (source->n == 0) {
+        return NULL;
+    }
+
+    // Get the maximum extent of the mosaic image
+    int xMin = INT_MAX;
+    int xMax = - INT_MAX;
+    int yMin = INT_MAX;
+    int yMax = - INT_MAX;
+    psElemType type = 0;
+    int numImages = 0;                  // Number of images
+    psTrace("psModules.camera", 3, "Mosaicking %ld cells.\n", source->n);
+    for (int i = 0; i < source->n; i++) {
+        psImage *image = source->data[i]; // The image of interest
+        if (!image) {
+            continue;
+        }
+        numImages++;
+
+        // Only implemented for F32 and U8 images so far.
+        assert(image->type.type == PS_TYPE_F32 || image->type.type == PS_TYPE_U8);
+        // All input types must be the same
+        if (type == 0) {
+            type = image->type.type;
+        }
+        assert(type == image->type.type);
+
+        // Size of cell in x and y
+        int xParity = xFlip->data.U8[i] ? -1 : 1;
+        int yParity = yFlip->data.U8[i] ? -1 : 1;
+        psTrace("psModules.camera", 5, "Extent of cell %d: %d -> %d , %d -> %d\n", i, x0->data.S32[i],
+                x0->data.S32[i] + xParity * xBinSource->data.S32[i] * image->numCols, y0->data.S32[i],
+                y0->data.S32[i] + yParity * yBinSource->data.S32[i] * image->numRows);
+
+        COMPARE(x0->data.S32[i], xMin, xMax);
+        COMPARE(y0->data.S32[i], yMin, yMax);
+        // Subtract the parity to get the inclusive limit (not exclusive)
+        COMPARE(x0->data.S32[i] + xParity * xBinSource->data.S32[i] * image->numCols - xParity, xMin, xMax);
+        COMPARE(y0->data.S32[i] + yParity * yBinSource->data.S32[i] * image->numRows - yParity, yMin, yMax);
+    }
+    if (numImages == 0) {
+        return NULL;
+    }
+
+    // Set up the image
+    // Since both upper and lower values are inclusive, we need to add one to the size
+    float xSize = (float)(xMax - xMin + 1) / (float)xBinTarget;
+    if (xSize - (int)xSize > 0) {
+        xSize += 1;
+    }
+    float ySize = (float)(yMax - yMin + 1) / (float)yBinTarget;
+    if (ySize - (int)ySize > 0) {
+        ySize += 1;
+    }
+
+    psTrace("psModules.camera", 3, "Spliced image will be %dx%d\n", (int)xSize, (int)ySize);
+    psImage *mosaic = psImageAlloc((int)xSize, (int)ySize, type); // The mosaic image
+    psImageInit(mosaic, 0);
+
+    // Next pass through the images to do the mosaicking
+    // XXX this function uses summing for the output: is this the right choice?
+    for (int i = 0; i < source->n; i++) {
+        psImage *image = source->data[i]; // The image of interest
+        if (!image) {
+            continue;
+        }
+        int xParity = xFlip->data.U8[i] ? -1 : 1; // Parity difference, in x
+        int yParity = yFlip->data.U8[i] ? -1 : 1; // Parity difference, in y
+        int xTargetBase = (x0->data.S32[i] - xMin) / xBinTarget; // The base x position in the target frame
+        int yTargetBase = (y0->data.S32[i] - yMin) / yBinTarget; // The base y position in the target frame
+
+	// in the first case, we are just copy a section pixel-by-pixel
+        if ((xBinSource->data.S32[i] == xBinTarget) && 
+	    (yBinSource->data.S32[i] == yBinTarget) && 
+	    (xFlip->data.U8[i] == 0) && 
+	    (yFlip->data.U8[i] == 0)) {
+            // Let someone else do the hard work
+            psImageOverlaySection(mosaic, image, xTargetBase, yTargetBase, "+");
+	    continue;
+        } 
+	
+	// in the second case, there's a difference with the parities, but we don't have to
+	// worry about binning
+	if (xBinSource->data.S32[i] == xBinTarget && yBinSource->data.S32[i] == yBinTarget) {
             switch (type) {
-                FILL_IN(F32);
-                FILL_IN(U8);
-            default:
+                COPY_WITH_PARITY_DIFFERENCE(F32);
+                COPY_WITH_PARITY_DIFFERENCE(U8);
+	      default:
                 psAbort("Should never get here.\n");
             }
-
-        } // Various difficulty levels
+	    continue;
+        } 
+	
+	// In the third case, the images are flipped and have different binnnig.
+	// We have to do all of the hard work ourselves
+	switch (type) {
+	    FILL_IN(F32);
+	    FILL_IN(U8);
+	  default:
+	    psAbort("Should never get here.\n");
+	}
     } // Iterating over images
 
     return mosaic;
 }
-
 
 // Add a cell and its various properties to the arrays
