Index: trunk/psModules/src/pmReadoutCombine.c
===================================================================
--- trunk/psModules/src/pmReadoutCombine.c	(revision 2282)
+++ trunk/psModules/src/pmReadoutCombine.c	(revision 2286)
@@ -5,6 +5,6 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-11-04 20:52:17 $
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-05 02:45:42 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -55,10 +55,8 @@
     PS_PTR_CHECK_NULL(inputs, NULL);
     PS_PTR_CHECK_NULL(params, NULL);
-    //    unsigned int maskVal = params->maskVal;
+    unsigned int maskVal = params->maskVal;
     psStats *stats = params->stats;
     int i;
     int j;
-    int numInputCols = -1;
-    int numInputRows = -1;
     int maxInputCols = 0;
     int maxInputRows = 0;
@@ -69,4 +67,5 @@
     psReadout *tmpReadout;
     float tmpF;
+
 
     //
@@ -92,22 +91,50 @@
         minInputRows = PS_MIN(minInputRows,
                               (tmpReadout->row0 + tmpReadout->image->row0));
+        tmpF = tmpReadout->row0 +
+               tmpReadout->image->row0 +
+               tmpReadout->image->numRows;
+        maxInputRows = PS_MAX(maxInputRows, tmpF);
+
+        minInputCols = PS_MIN(minInputCols,
+                              (tmpReadout->col0 + tmpReadout->image->col0));
         tmpF = tmpReadout->col0 +
                tmpReadout->image->col0 +
                tmpReadout->image->numCols;
         maxInputCols = PS_MAX(maxInputCols, tmpF);
-
-        minInputCols = PS_MIN(minInputCols,
-                              (tmpReadout->col0 + tmpReadout->image->col0));
-        tmpF = tmpReadout->row0 +
-               tmpReadout->image->row0 +
-               tmpReadout->image->numRows;
-        maxInputRows = PS_MAX(maxInputRows, tmpF);
         tmpInput = tmpInput->next;
         numInputs++;
     }
 
+    // We ensure that the zero vector is of the proper size.
+    if (zero != NULL) {
+        PS_VECTOR_CHECK_TYPE(zero, PS_TYPE_F32, NULL);
+        if (numInputs > zero->n) {
+            // XXX: ERROR: the zero vector does not have enough elements.
+            return(NULL);
+        } else if (numInputs < zero->n) {
+            // XXX: WARNING: the zero vector too many elements.
+        }
+    }
+
+    // We ensure that the scale vector is of the proper size.
+    if (scale != NULL) {
+        PS_VECTOR_CHECK_TYPE(scale, PS_TYPE_F32, NULL);
+        if (numInputs > scale->n) {
+            // XXX: ERROR: the scale vector does not have enough elements.
+            return(NULL);
+        } else if (numInputs < scale->n) {
+            // XXX: WARNING: the scale vector too many elements.
+        }
+    }
+
+    // At this point, the following variables have been computed:
+    // maxInputRows: the largest input row value, in output image space.
+    // maxInputCols: the largest input column value, in output image space.
+    // minInputRows: the smallest input row value, in output image space.
+    // minInputCols: the smallest input column value, in output image space.
+    //
     if (output == NULL) {
-        output = psImageAlloc(numInputCols-minInputCols,
-                              numInputRows-minInputRows, PS_TYPE_F32);
+        output = psImageAlloc(1+maxInputCols-minInputCols,
+                              1+maxInputRows-minInputRows, PS_TYPE_F32);
         *(int *) &(output->col0) = minInputCols;
         *(int *) &(output->row0) = minInputRows;
@@ -115,5 +142,5 @@
         if (((output->col0 + output->numCols) < maxInputCols) ||
                 ((output->row0 + output->numRows) < maxInputRows)) {
-            //XXX            psError(__func__, "Output image (%d, %d) is too small to hold combined images.\n",
+            //XXX ERROR: "Output image (%d, %d) is too small to hold combined images.\n",
             //                    output->row0 + output->numRows,
             //                    output->col0 + output->numCols);
@@ -121,7 +148,6 @@
         }
 
-        if ((output->col0 > minInputCols) ||
-                (output->row0 > minInputRows)) {
-            //XXX            psError(__func__, "Output image offset is larger then input image offset.\n");
+        if ((output->col0 > minInputCols) || (output->row0 > minInputRows)) {
+            //XXX ERROR "Output image offset is larger then input image offset.\n");
             return(NULL);
         }
@@ -136,19 +162,58 @@
     psVector *tmpPixelMask = psVectorAlloc(numInputs, PS_TYPE_U8);
     psVector *tmpPixelMaskNKeep = psVectorAlloc(numInputs, PS_TYPE_U8);
+    psVector *outRowLower = psVectorAlloc(numInputs, PS_TYPE_U32);
+    psVector *outRowUpper = psVectorAlloc(numInputs, PS_TYPE_U32);
+    psVector *outColLower = psVectorAlloc(numInputs, PS_TYPE_U32);
+    psVector *outColUpper = psVectorAlloc(numInputs, PS_TYPE_U32);
     psReadout **tmpReadouts = (psReadout **) psAlloc(numInputs * sizeof(psReadout *));
+
+
+    // For each input readout, we create a pointer to that readout in
+    // "tmpReadouts[]", and we store the min/max pixel indices for that
+    // readout, in putput image coordinates, in the psVectors
+    // (outRowLower, outColLower, outRowUpper, outColUpper).
     i = 0;
     while (NULL != tmpInput) {
         tmpReadouts[i] = (psReadout *) tmpInput->data;
+        outRowLower->data.U32[i] = tmpReadouts[i]->row0 + tmpReadout->image->row0;
+        outColLower->data.U32[i] = tmpReadouts[i]->col0 + tmpReadout->image->col0;
+        outRowUpper->data.U32[i] = tmpReadouts[i]->row0 +
+                                   tmpReadouts[i]->image->row0 +
+                                   tmpReadouts[i]->image->numRows;
+        outColUpper->data.U32[i] = tmpReadouts[i]->col0 +
+                                   tmpReadouts[i]->image->col0 +
+                                   tmpReadouts[i]->image->numCols;
+
         tmpInput = tmpInput->next;
         i++;
-    }
-
-    for (i = 0; i < output->numRows ; i++) {
-        for (j = 0; j < output->numCols ; j++) {
+
+    }
+
+    // We loop through each pixel in the output image.  We loop through each
+    // input readout.  We determine if that output pixel is contained in the
+    // image from that readout.  If so, we save it in psVector tmpPixels.
+    // If not, we set a mask for that element in tmpPixels.  Then, we mask off
+    // pixels not between fracLow and fracHigh.  Then we call the vector
+    // stats routine on those pixels/mask.  Then we set the output pixel value
+    // to the result of the stats call.
+    for (i = output->row0; i < output->numRows ; i++) {
+        for (j = output->col0; j < output->numCols ; j++) {
             for (int r = 0; r < numInputs ; r++) {
-                //                if (i,j are valid for this readout) {
-                if (0) {
-                    //                     tmpPixels->data.F32[r] = WHATEVER;
-                    tmpPixelMask->data.U8[r] = 0;
+                if ((outRowLower->data.U32[r] <= i) &&
+                        (outColLower->data.U32[r] <= j) &&
+                        (outRowUpper->data.U32[r] > i) &&
+                        (outColUpper->data.U32[r] > j)) {
+
+                    int imageRow = i - (tmpReadouts[r]->row0 +
+                                        tmpReadouts[i]->image->row0);
+                    int imageCol = j - (tmpReadouts[r]->col0 +
+                                        tmpReadouts[r]->image->col0);
+                    if (!(maskVal && tmpReadouts[i]->mask->data.U8[imageRow][imageCol])) {
+                        tmpPixels->data.F32[r] = tmpReadouts[i]->image->data.F32[imageRow][imageCol];
+                        tmpPixelMask->data.U8[r] = 0;
+                    } else {
+                        tmpPixels->data.F32[r] = 0.0;
+                        tmpPixelMask->data.U8[r] = 1;
+                    }
                 } else {
                     tmpPixels->data.F32[r] = 0.0;
@@ -156,4 +221,6 @@
                 }
             }
+            // At this point, we have scanned all input readouts for this
+            // one output pixel.
 
             // Determine how many pixels lie between fracLow and fracHigh.
@@ -184,4 +251,34 @@
             }
 
+            // XXX: Is this correct?
+            // We add the zero vector, if non-NULL.
+            if (zero != NULL) {
+                for (int r = 0; r < numInputs ; r++) {
+                    tmpPixels->data.F32[r]+= zero->data.F32[r];
+                }
+            }
+
+            // XXX: Is this correct?
+            // We scale the pixels by the scale vector, if not-NULL.
+            if (scale != NULL) {
+                for (int r = 0; r < numInputs ; r++) {
+                    tmpPixels->data.F32[r]*= scale->data.F32[r];
+                }
+            }
+
+            // XXX: Is this correct?
+            if (gain > 0.0) {
+                for (int r = 0; r < numInputs ; r++) {
+                    tmpPixels->data.F32[r]*= gain;
+                }
+            }
+
+            // XXX: Is this correct?
+            if (!(readnoise < 0.0)) {
+                for (int r = 0; r < numInputs ; r++) {
+                    tmpPixels->data.F32[r]+= readnoise;
+                }
+            }
+
             // Calculate the specified statistic on the stack of pixels.
             stats = psVectorStats(stats,
@@ -193,8 +290,8 @@
             double statValue;
             if (!p_psGetStatValue(stats, &statValue)) {
-                psError(PS_ERR_UNKNOWN,true, "Could not determine stats value.\n");
+                //XXX ERROR: "Could not determine stats value.\n"
                 return(NULL);
             } else {
-                output->data.F32[i][j] = (float) statValue;
+                output->data.F32[i-output->row0][j-output->col0] = (float) statValue;
             }
         }
@@ -205,4 +302,8 @@
     psFree(tmpPixelMask);
     psFree(tmpPixelMaskNKeep);
+    psFree(outRowLower);
+    psFree(outRowUpper);
+    psFree(outColLower);
+    psFree(outColUpper);
     psFree(tmpReadouts);
 
