Index: /trunk/psModules/src/pmReadoutCombine.c
===================================================================
--- /trunk/psModules/src/pmReadoutCombine.c	(revision 2811)
+++ /trunk/psModules/src/pmReadoutCombine.c	(revision 2812)
@@ -5,6 +5,6 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-12-23 20:27:51 $
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-23 23:16:36 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -27,13 +27,16 @@
 psCombineParams;
 
-
-int p_psDetermineNumBits(unsigned int data)
+/******************************************************************************
+p_psDetermineNumBits(data): This routine takes an enum psStatsOptions as an
+argument and returns the number of non-zero bits.
+ *****************************************************************************/
+psStatsOptions p_psDetermineNumBits(psStatsOptions data)
 {
-    int i;
-    unsigned int tmpData = data;
-    int numBits = 0;
-
-    for (i=0;i<sizeof(unsigned int);i++) {
-        if (0x0001 && tmpData) {
+    psS32 i;
+    psU64 tmpData = data;
+    psS32 numBits = 0;
+
+    for (i=0;i<4 * sizeof(psStatsOptions);i++) {
+        if (0x0001 & tmpData) {
             numBits++;
         }
@@ -43,4 +46,5 @@
 }
 
+// XXX: Whats this?
 #define MAX_INT 10000
 psImage *pmReadoutCombine(psImage *output,
@@ -55,4 +59,17 @@
     PS_PTR_CHECK_NULL(inputs, NULL);
     PS_PTR_CHECK_NULL(params, NULL);
+    PS_PTR_CHECK_NULL(params->stats, NULL);
+    if (zero != NULL) {
+        PS_VECTOR_CHECK_TYPE(zero, PS_TYPE_F32, NULL);
+    }
+    if (scale != NULL) {
+        PS_VECTOR_CHECK_TYPE(scale, PS_TYPE_F32, NULL);
+    }
+    if ((zero != NULL) && (scale != NULL)) {
+        PS_VECTOR_CHECK_TYPE_EQUAL(zero, scale, NULL);
+        // XXX: Currently only type F32 is implemented.
+        // PS_VECTOR_CHECK_TYPE_S16_S32_F32(scale, NULL);
+    }
+
     psStats *stats = params->stats;
     int i;
@@ -66,4 +83,11 @@
     int numInputs = 0;
     int tmpI;
+    psElemType outputType = PS_TYPE_F32;
+
+    if (1 < p_psDetermineNumBits(params->stats->options)) {
+        psError(PS_ERR_UNKNOWN, true,
+                "Multiple statistical options have been requested.\n");
+        return(NULL);
+    }
 
     //
@@ -86,4 +110,5 @@
         PS_READOUT_CHECK_EMPTY(tmpReadout, output);
         PS_READOUT_CHECK_TYPE(tmpReadout, PS_TYPE_F32, output);
+        outputType = tmpReadout->image->type.type;
 
         minInputRows = PS_MIN(minInputRows,
@@ -105,11 +130,13 @@
 
     // 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.
+            psError(PS_ERR_UNKNOWN, true, "zero vector has incorrect size (%d)\n", zero->n);
             return(NULL);
         } else if (numInputs < zero->n) {
-            // XXX: WARNING: the zero vector too many elements.
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: the zero vector too many elements (%d)\n", zero->n);
         }
     }
@@ -119,8 +146,9 @@
         PS_VECTOR_CHECK_TYPE(scale, PS_TYPE_F32, NULL);
         if (numInputs > scale->n) {
-            // XXX: ERROR: the scale vector does not have enough elements.
+            psError(PS_ERR_UNKNOWN, true, "scale vector has incorrect size (%d)\n", scale->n);
             return(NULL);
         } else if (numInputs < scale->n) {
-            // XXX: WARNING: the scale vector too many elements.
+            psLogMsg(__func__, PS_LOG_WARN,
+                     "WARNING: the scale vector too many elements (%d)\n", scale->n);
         }
     }
@@ -134,5 +162,5 @@
     if (output == NULL) {
         output = psImageAlloc(maxInputCols-minInputCols,
-                              maxInputRows-minInputRows, PS_TYPE_F32);
+                              maxInputRows-minInputRows, outputType);
         *(int *) &(output->col0) = minInputCols;
         *(int *) &(output->row0) = minInputRows;
@@ -140,7 +168,8 @@
         if (((output->col0 + output->numCols) < maxInputCols) ||
                 ((output->row0 + output->numRows) < maxInputRows)) {
-            //XXX ERROR: "Output image (%d, %d) is too small to hold combined images.\n",
-            //                    output->row0 + output->numRows,
-            //                    output->col0 + output->numCols);
+            psError(PS_ERR_UNKNOWN, true,
+                    "Output image (%d, %d) is too small to hold combined images.\n",
+                    output->row0 + output->numRows,
+                    output->col0 + output->numCols);
             return(NULL);
         }
@@ -150,9 +179,4 @@
             return(NULL);
         }
-    }
-
-    if (1 < p_psDetermineNumBits(params->stats->options)) {
-        //XXX        psError(PS_ERR_UNKNOWN,true, "Multiple statistical options have been requested.\n");
-        return(NULL);
     }
 
@@ -254,4 +278,5 @@
             // XXX: Is this correct?
             // We add the zero vector, if non-NULL.
+
             if (zero != NULL) {
                 for (int r = 0; r < numInputs ; r++) {
Index: /trunk/psModules/src/pmSubtractSky.c
===================================================================
--- /trunk/psModules/src/pmSubtractSky.c	(revision 2811)
+++ /trunk/psModules/src/pmSubtractSky.c	(revision 2812)
@@ -6,9 +6,9 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-12-23 20:27:51 $
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-23 23:16:36 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
- *
+xd *
  */
 
@@ -20,15 +20,15 @@
 
 /******************************************************************************
-p_psDetermineNumBits(data): This routine takes an insigned int as an argument
-and returns the number of non-zero bits.
- *****************************************************************************/
-psS32 p_psDetermineNumBits(psU32 data)
+p_psDetermineNumBits(data): This routine takes an enum psStatsOptions as an
+argument and returns the number of non-zero bits.
+ *****************************************************************************/
+psStatsOptions p_psDetermineNumBits(psStatsOptions data)
 {
     psS32 i;
-    psU32 tmpData = data;
+    psU64 tmpData = data;
     psS32 numBits = 0;
 
-    for (i=0;i<sizeof(psU32);i++) {
-        if (0x0001 && tmpData) {
+    for (i=0;i<4 * sizeof(psStatsOptions);i++) {
+        if (0x0001 & tmpData) {
             numBits++;
         }
Index: /trunk/psModules/test/tst_pmReadoutCombine.c
===================================================================
--- /trunk/psModules/test/tst_pmReadoutCombine.c	(revision 2811)
+++ /trunk/psModules/test/tst_pmReadoutCombine.c	(revision 2812)
@@ -5,6 +5,6 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-12-01 22:08:32 $
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-12-23 23:16:36 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -15,6 +15,8 @@
 #include "pmReadoutCombine.h"
 static int test00(void);
+static int test01(void);
 testDescription tests[] = {
                               {test00, 000, "pmSubtractBias", 0, false},
+                              {test01, 000, "pmSubtractBias(): input parameter error conditions", 0, false},
                               {NULL}
                           };
@@ -34,4 +36,5 @@
 int doit()
 {
+    return(0);
     int i;
     int j;
@@ -238,2 +241,260 @@
     return(testStatus);
 }
+
+psS32 VerifyTheOutput(psImage *output)
+{
+    bool testStatus = true;
+
+    for (psS32 i = 0 ; i < output->numRows ; i++) {
+        for (psS32 j = 0 ; j < output->numCols ; j++) {
+            if (output->data.F32[i][j] != 45.0) {
+                printf("ERROR: output[%d][%d] is %.2f, should be 45.0\n", i, j, output->data.F32[i][j]);
+                testStatus = false;
+            }
+        }
+    }
+    return(testStatus);
+}
+
+
+int test01()
+{
+    int i;
+    int j;
+    int r;
+    psList *list = NULL;
+    int baseRowsReadout[NUM_READOUTS];
+    int baseColsReadout[NUM_READOUTS];
+    int baseRows[NUM_READOUTS];
+    int baseCols[NUM_READOUTS];
+    int numRows[NUM_READOUTS];
+    int numCols[NUM_READOUTS];
+    int minOutRow = 10000;
+    int minOutCol = 10000;
+    int maxOutRow = -1;
+    int maxOutCol = -1;
+    psImage *output = NULL;
+    psImage *rc = NULL;
+    psCombineParams *params = (psCombineParams *) psAlloc(sizeof(psCombineParams));
+    psVector *zero = psVectorAlloc(NUM_READOUTS, PS_TYPE_F32);
+    psVector *zeroHalf = psVectorAlloc(NUM_READOUTS/2, PS_TYPE_F32);
+    psVector *zeroBig = psVectorAlloc(NUM_READOUTS+1, PS_TYPE_F32);
+    psVector *zeroF64 = psVectorAlloc(NUM_READOUTS, PS_TYPE_F64);
+    psVector *scale = psVectorAlloc(NUM_READOUTS, PS_TYPE_F32);
+    psVector *scaleHalf = psVectorAlloc(NUM_READOUTS/2, PS_TYPE_F32);
+    psVector *scaleBig = psVectorAlloc(NUM_READOUTS*2, PS_TYPE_F32);
+    psVector *scaleF64 = psVectorAlloc(NUM_READOUTS, PS_TYPE_F64);
+    int testStatus = true;
+    for (i=0;i<NUM_READOUTS;i++) {
+        zero->data.F32[i] = 3.0;
+        zeroBig->data.F32[i] = 3.0;
+    }
+    for (i=0;i<NUM_READOUTS;i++) {
+        scale->data.F32[i] = 6.0;
+        scaleBig->data.F32[i] = 6.0;
+    }
+
+    params->stats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    params->maskVal = 1;
+    params->fracLow = 0.0;
+    params->fracHigh = 10000.0;
+    params->nKeep = 0;
+
+    for (r=0;r<NUM_READOUTS;r++) {
+        baseRowsReadout[r] = r + 40;
+        baseColsReadout[r] = r + 42;
+        baseRows[r] = r;
+        baseCols[r] = r+2;
+        numRows[r] = 4 + (2 * r);
+        numCols[r] = 8 + (2 * r);
+
+        baseRowsReadout[r] = 0;
+        baseColsReadout[r] = 0;
+        baseRows[r] = 0;
+        baseCols[r] = 0;
+        numRows[r] = 10;
+        numCols[r] = 10;
+
+        psImage *tmpImage = psImageAlloc(numCols[r], numRows[r], PS_TYPE_F32);
+        for (i=0;i<numRows[r];i++) {
+            for (j=0;j<numCols[r];j++) {
+                tmpImage->data.F32[i][j] = (float) (i + j);
+                tmpImage->data.F32[i][j] = 1.0;
+                tmpImage->data.F32[i][j] = (float) r;
+            }
+        }
+
+        *(int *) (& (tmpImage->row0)) = baseRows[r];
+        *(int *) (& (tmpImage->col0)) = baseCols[r];
+        psReadout *tmpReadout = psReadoutAlloc(baseColsReadout[r],
+                                               baseRowsReadout[r],
+                                               tmpImage);
+        minOutRow = PS_MIN(minOutRow, (baseRowsReadout[r] + baseRows[r]));
+        minOutCol = PS_MIN(minOutCol, (baseColsReadout[r] + baseCols[r]));
+        maxOutRow = PS_MAX(maxOutRow, (baseRowsReadout[r] + baseRows[r] + numRows[r]));
+        maxOutCol = PS_MAX(maxOutCol, (baseColsReadout[r] + baseCols[r] + numCols[r]));
+
+        if (r == 0) {
+            list = psListAlloc(tmpReadout);
+        } else {
+            psListAdd(list, PS_LIST_HEAD, tmpReadout);
+        }
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with NULL zero vector.\n");
+    rc = pmReadoutCombine(NULL, list, params, NULL, scale, true, 1.0, 0.0);
+    if (rc == NULL) {
+        //XXX: We should verify the output image here.
+        printf("ERROR: pmReadoutCombine() returned NULL\n");
+        testStatus = false;
+    }
+    if (rc->type.type != scale->type.type) {
+        printf("ERROR: output readout->image has incorrect type.\n");
+        testStatus = false;
+    }
+    psFree(rc);
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect length zero vector (too small).  Should generate error.\n");
+    rc = pmReadoutCombine(NULL, list, params, zeroHalf, scale, true, 1.0, 0.0);
+    if (rc != NULL) {
+        printf("ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect type zero vector.  Should generate error.\n");
+    rc = pmReadoutCombine(NULL, list, params, zeroF64, scale, true, 1.0, 0.0);
+    if (rc != NULL) {
+        printf("ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect length zero vector (too big).  Should generate warning.\n");
+    rc = pmReadoutCombine(output, list, params, zeroBig, scale, true, 1.0, 0.0);
+    if (rc != NULL) {
+        if (false == VerifyTheOutput(rc)) {
+            testStatus = false;
+        }
+        psFree(rc);
+        rc = NULL;
+    } else {
+        printf("ERROR: pmReadoutCombine() returned NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with NULL scale vector.\n");
+    rc = pmReadoutCombine(output, list, params, zero, NULL, true, 1.0, 0.0);
+    if (rc == NULL) {
+        //XXX: We should verify the output image here.
+        printf("ERROR: pmReadoutCombine() returned NULL\n");
+        testStatus = false;
+    }
+    psFree(rc);
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect length scale vector (too small).  Should generate error.\n");
+    rc = pmReadoutCombine(output, list, params, zero, scaleHalf, true, 1.0, 0.0);
+    if (rc != NULL) {
+        printf("ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect type scale vector.  Should generate error.\n");
+    rc = pmReadoutCombine(output, list, params, zero, scaleF64, true, 1.0, 0.0);
+    if (rc != NULL) {
+        printf("ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with incorrect length scale vector (too big).  Should generate warning.\n");
+    rc = pmReadoutCombine(output, list, params, zero, scaleBig, true, 1.0, 0.0);
+    if (rc != NULL) {
+        if (false == VerifyTheOutput(rc)) {
+            testStatus = false;
+        }
+        psFree(rc);
+        rc = NULL;
+    } else {
+        printf("ERROR: pmReadoutCombine() returned NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() insufficient size output image.  Should generate error, return NULL.\n");
+    output = psImageAlloc(1, 1, PS_TYPE_F32);
+    rc = pmReadoutCombine(output, list, params, zero, scale, true, 1.0, 0.0);
+    if (rc != NULL) {
+        printf("ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+    psFree(output);
+    output = NULL;
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with NULL input list.  Should generate error, return NULL.\n");
+    rc = pmReadoutCombine(output, NULL, params, zero, scale, true, 1.0, 0.0);
+    if (rc != NULL) {
+        printf("ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("Calling pmReadoutCombine() with NULL params.  Should generate error, return NULL.\n");
+    rc = pmReadoutCombine(output, list, NULL, zero, scale, true, 1.0, 0.0);
+    if (rc != NULL) {
+        printf("ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+
+    printf("----------------------------------------------------------------------------\n");
+    psStatsOptions oldStatsOpts = params->stats->options |= PS_STAT_MIN;
+    printf("Calling pmReadoutCombine() with multiple stats->options.  Should generate error, return NULL.\n");
+    rc = pmReadoutCombine(output, list, params, zero, scale, true, 1.0, 0.0);
+    if (rc != NULL) {
+        printf("ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+    params->stats->options = oldStatsOpts;
+
+    printf("----------------------------------------------------------------------------\n");
+    psStats *oldStats = params->stats;
+    printf("Calling pmReadoutCombine() with NULL param->stats.  Should generate error, return NULL.\n");
+    rc = pmReadoutCombine(output, list, params, zero, scale, true, 1.0, 0.0);
+    if (rc != NULL) {
+        printf("ERROR: pmReadoutCombine() did not return NULL\n");
+        testStatus = false;
+    }
+    params->stats = oldStats;
+
+    printf("----------------------------------------------------------------------------\n");
+    printf("============================================================================\n");
+
+    psFree(params->stats);
+    psFree(params);
+    //    psFree(output);
+    //    psFree(rc);
+    psFree(zero);
+    psFree(zeroHalf);
+    psFree(zeroBig);
+    psFree(zeroF64);
+    psFree(scale);
+    psFree(scaleHalf);
+    psFree(scaleBig);
+    psFree(scaleF64);
+    psListElem *tmpInput = (psListElem *) list->head;
+    while (NULL != tmpInput) {
+        psReadout *tmpReadout = (psReadout *) tmpInput->data;
+        psFree(tmpReadout);
+        tmpInput = tmpInput->next;
+    }
+    psFree(list);
+
+    return(!testStatus);
+}
+// This code will
