Index: trunk/psModules/test/imsubtract/tst_pmSubtractBias.c
===================================================================
--- trunk/psModules/test/imsubtract/tst_pmSubtractBias.c	(revision 5188)
+++ trunk/psModules/test/imsubtract/tst_pmSubtractBias.c	(revision 5516)
@@ -3,12 +3,21 @@
  *  @brief Contains the tests for pmSubtractBias.c:
  *
- * test00: This code will subtract full bias frames from the input image.
- * test01: Multiple overscan regions, calculate a scalar statistic for
- *  each, then subtract from the input image.
- * test02: Calculate a column overscan vector and subtract it from each
- *  column in the input image.
- * test03: Calculate a row overscan vector and subtract it from each
+ * test00a: This code will subtract full bias frames from the input image.
+ * XXX: Must test:
+ *  Various image offsets.
+ *  Various image size combinations.
+ *  Various data types for the bias and input images.
+ *  Ensure code works when CELL.TRIMSEC is not set.
+ * test00b: This code will subtract full dark frames from the input image.
+ * XXX: Must test:
+ *  Various image offsets.
+ *  Various image size combinations.
+ *  Various data types for the bias and input images.
+ *  Code properly determines CELL.DARKTIME from cell metadata.
+ *  Ensure code works when CELL.DARKTIME is not set.
+ *  Ensure code works when CELL.TRIMSEC is not set.
+ *  test03: Calculate a row overscan vector and subtract it from each
  *  row in the input image.
- * test04: 
+ * test05: 
  *
  *  @author GLG, MHPCC
@@ -16,6 +25,6 @@
  *  XXX: Memory leaks are not being detected.
  *
- *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-09-29 21:57:31 $
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-11-15 20:09:03 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -25,17 +34,19 @@
 #include "pslib.h"
 #include "pmSubtractBias.h"
-static int test00(void);
-static int test01(void);
-static int test02(void);
-static int test03(void);
-static int test04(void);
-static int testX(void);
+static int test00a(void);
+static int test00b(void);
+//static int test01(void);
+//static int test02(void);
+//static int test03(void);
+//static int test04(void);
+static int test05(void);
 testDescription tests[] = {
-                              {test00, 000, "pmSubtractBias", 0, true},
-                              {test01, 000, "pmSubtractBias", 0, true},
-                              {test02, 000, "pmSubtractBias", 0, true},
-                              {test03, 000, "pmSubtractBias", 0, false},
-                              {test04, 000, "pmSubtractBias", 0, true},
-                              {testX,  000, "pmSubtractBias", 0, true},
+                              {test00a, 000, "doSubtractBiasFullFrame", 0, false},
+                              {test00b, 000, "doSubtractDarkFullFrame", 0, false},
+                              //                              {test01, 000, "pmSubtractBias", 0, true},
+                              //                              {test02, 000, "pmSubtractBias", 0, true},
+                              //                              {test03, 000, "pmSubtractBias", 0, false},
+                              //                              {test04, 000, "pmSubtractBias", 0, true},
+                              {test05, 000, "pmSubtractBias", 0, false},
                               {NULL}
                           };
@@ -45,4 +56,16 @@
 {
     psLogSetFormat("HLNM");
+
+    psTraceSetLevel(".", 0);
+    psTraceSetLevel("spline1DFree", 0);
+    psTraceSetLevel("calculateSecondDerivs", 0);
+    psTraceSetLevel("vectorBinDisectF32", 0);
+    psTraceSetLevel("vectorBinDisectF64", 0);
+    psTraceSetLevel("p_psVectorBinDisect", 0);
+    psTraceSetLevel("psSpline1DAlloc", 0);
+    psTraceSetLevel("psVectorFitSpline1D", 0);
+    psTraceSetLevel("psSpline1DEval", 0);
+    psTraceSetLevel("psSpline1DEvalVector", 0);
+
     return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
 }
@@ -50,4 +73,7 @@
 #define NUM_ROWS 8
 #define NUM_COLS 8
+#define MAX_HEADER_MSG_LENGTH 1000
+#define POLYNOMIAL_FIT_ORDER 2
+#define NUM_OVERSCANS 2
 /******************************************************************************
 doSubtractBiasFullFrame(): a sample pmReadout as well as a bias image are
@@ -63,6 +89,4 @@
     psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
     psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    //    pmReadout *myReadout = pmReadoutAlloc(numCols, numRows, tmpImage1);
-    //    pmReadout *myBias = pmReadoutAlloc(numCols, numRows, tmpImage2);
     pmReadout *myReadout = pmReadoutAlloc(NULL);
     pmReadout *myBias = pmReadoutAlloc(NULL);
@@ -70,6 +94,7 @@
     myBias->image = tmpImage2;
 
-
-    printPositiveTestHeader(stdout, "pmSubtractBias", "doSubtractBiasFullFrame");
+    char *HeaderMessageStr = (char *) psAlloc(MAX_HEADER_MSG_LENGTH);
+    sprintf(HeaderMessageStr, "doSubtractBiasFullFrame(%d, %d)", numRows, numCols);
+    printPositiveTestHeader(stdout, "pmSubtractBias", HeaderMessageStr);
     for (i=0;i<numRows;i++) {
         for (j=0;j<numCols;j++) {
@@ -79,6 +104,6 @@
     }
 
-    myReadout = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_NONE, NULL,
-                               0, PM_FIT_NONE, myBias);
+    myReadout = pmSubtractBias(myReadout, NULL, PM_FIT_NONE, false,
+                               NULL, 0, myBias, NULL);
 
     for (i=0;i<numRows;i++) {
@@ -96,10 +121,11 @@
     psFree(myReadout);
     psFree(myBias);
-    printFooter(stdout, "pmSubtractBias", "doSubtractBiasFullFrame", true);
+    printFooter(stdout, "pmSubtractBias", HeaderMessageStr, true);
+    psFree(HeaderMessageStr);
     return(testStatus);
 }
 
 
-int test00( void )
+int test00a( void )
 {
     int testStatus = 0;
@@ -112,10 +138,10 @@
 }
 
+
 /******************************************************************************
-doSubtractFullOverscans(): a sample pmReadout as well as several overscan
-images of the same size are created.  The overscan images are then subtracted
-from the pmReadout.
+doSubtractDarkFullFrame(): a sample pmReadout as well as a dark image are
+created and the dark image is subtracted from the pmReadout.
  *****************************************************************************/
-int doSubtractFullOverscans(int numCols, int numRows)
+int doSubtractDarkFullFrame(int numCols, int numRows)
 {
     int i;
@@ -126,33 +152,25 @@
     psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
     psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    psImage *tmpImage3 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    psImage *tmpImage4 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    //    pmReadout *myReadout = pmReadoutAlloc(numCols, numRows, tmpImage1);
     pmReadout *myReadout = pmReadoutAlloc(NULL);
+    pmReadout *myDark = pmReadoutAlloc(NULL);
     myReadout->image = tmpImage1;
-
-
-    printPositiveTestHeader(stdout, "pmSubtractBias", "doSubtractFullOverscans");
-    psList *list;
-    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
-
+    myDark->image = tmpImage2;
+
+    char *HeaderMessageStr = (char *) psAlloc(MAX_HEADER_MSG_LENGTH);
+    sprintf(HeaderMessageStr, "doSubtractDarkFullFrame(%d, %d)", numRows, numCols);
+    printPositiveTestHeader(stdout, "pmSubtractBias", HeaderMessageStr);
     for (i=0;i<numRows;i++) {
         for (j=0;j<numCols;j++) {
             myReadout->image->data.F32[i][j] = (float) (i + j);
-            tmpImage2->data.F32[i][j] = 3.0;
-            tmpImage3->data.F32[i][j] = 4.0;
-            tmpImage4->data.F32[i][j] = 5.0;
-        }
-    }
-    list = psListAlloc(tmpImage2);
-    psListAdd(list, PS_LIST_HEAD, tmpImage3);
-    psListAdd(list, PS_LIST_HEAD, tmpImage4);
-
-    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_ALL, stat,
-                               0, PM_FIT_NONE, NULL);
+            myDark->image->data.F32[i][j] = 1.0;
+        }
+    }
+
+    myReadout = pmSubtractBias(myReadout, NULL, PM_FIT_NONE, false,
+                               NULL, 0, NULL, myDark);
 
     for (i=0;i<numRows;i++) {
         for (j=0;j<numCols;j++) {
-            expect = ((float) (i + j)) - 12.0;
+            expect = ((float) (i + j)) - 1.0;
             actual = myReadout->image->data.F32[i][j];
             if (FLT_EPSILON < fabs(expect - actual)) {
@@ -165,385 +183,24 @@
 
     psFree(myReadout);
-    psFree(tmpImage2);
-    psFree(tmpImage3);
-    psFree(tmpImage4);
-    psFree(stat);
-    psFree(list);
-
-    printFooter(stdout, "pmSubtractBias", "doSubtractFullOverscans", true);
+    psFree(myDark);
+    printFooter(stdout, "pmSubtractBias", HeaderMessageStr, true);
+    psFree(HeaderMessageStr);
     return(testStatus);
 }
 
-int test01( void )
+
+int test00b( void )
 {
     int testStatus = 0;
 
-    testStatus |= doSubtractFullOverscans(1, 1);
-    testStatus |= doSubtractFullOverscans(1, NUM_ROWS);
-    testStatus |= doSubtractFullOverscans(NUM_COLS, 1);
-    testStatus |= doSubtractFullOverscans(NUM_COLS, NUM_ROWS);
-
+    testStatus |= doSubtractDarkFullFrame(1, 1);
+    testStatus |= doSubtractDarkFullFrame(NUM_COLS, 1);
+    testStatus |= doSubtractDarkFullFrame(1, NUM_ROWS);
+    testStatus |= doSubtractDarkFullFrame(NUM_COLS, NUM_ROWS);
     return(testStatus);
 }
 
-/******************************************************************************
-doSubtractFullOverscans(): a sample pmReadout as well as several overscan
-images of the same size are created.  The overscan images are collected
-pixel-by-pixel then subtracted column-wise from the pmReadout.
- *****************************************************************************/
-int doSubtractFullOverscanColumns(int numCols, int numRows)
-{
-    int i;
-    int j;
-    float actual;
-    float expect;
-    int testStatus = 0;
-    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    psImage *tmpImage3 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    psImage *tmpImage4 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    pmReadout *myReadout = pmReadoutAlloc(NULL);
-    myReadout->image = tmpImage1;
-    psList *list;
-    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
-
-    for (i=0;i<numRows;i++) {
-        for (j=0;j<numCols;j++) {
-            myReadout->image->data.F32[i][j] = (float) (i + j);
-            tmpImage2->data.F32[i][j] = 3.0;
-            tmpImage3->data.F32[i][j] = 4.0;
-            tmpImage4->data.F32[i][j] = 5.0;
-        }
-    }
-    list = psListAlloc(tmpImage2);
-    psListAdd(list, PS_LIST_HEAD, tmpImage3);
-    psListAdd(list, PS_LIST_HEAD, tmpImage4);
-
-    printPositiveTestHeader(stdout, "pmSubtractBias", "Column Overscans");
-
-    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_COLUMNS, stat,
-                               0, PM_FIT_NONE, NULL);
-
-    for (i=0;i<numRows;i++) {
-        for (j=0;j<numCols;j++) {
-            expect = ((float) (i + j)) - 12.0;
-            actual = myReadout->image->data.F32[i][j];
-            if (FLT_EPSILON < fabs(expect - actual)) {
-                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
-                testStatus = 1;
-            }
-        }
-    }
-
-
-    psFree(myReadout);
-    psFree(tmpImage2);
-    psFree(tmpImage3);
-    psFree(tmpImage4);
-    psFree(stat);
-    psFree(list);
-
-    printFooter(stdout, "pmSubtractBias", "Column Overscans", true);
-    return(testStatus);
-}
-/******************************************************************************
-doSubtractFullOverscans(): a sample pmReadout as well as several overscan
-images of the same size are created.  The overscan images are collected
-pixel-by-pixel then subtracted column-wise from the pmReadout.
- *****************************************************************************/
-int doSubtractFullOverscanColumnsPoly(int numCols, int numRows)
-{
-    int i;
-    int j;
-    float actual;
-    float expect;
-    int testStatus = 0;
-    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    psImage *tmpImage3 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    psImage *tmpImage4 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    pmReadout *myReadout = pmReadoutAlloc(NULL);
-    myReadout->image = tmpImage1;
-    psList *list;
-    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
-    psPolynomial1D *myPoly = psPolynomial1DAlloc(1, PS_POLYNOMIAL_ORD);
-
-    for (i=0;i<numRows;i++) {
-        for (j=0;j<numCols;j++) {
-            myReadout->image->data.F32[i][j] = (float) (i + j);
-            tmpImage2->data.F32[i][j] = 3.0;
-            tmpImage3->data.F32[i][j] = 4.0;
-            tmpImage4->data.F32[i][j] = 5.0;
-        }
-    }
-    list = psListAlloc(tmpImage2);
-    psListAdd(list, PS_LIST_HEAD, tmpImage3);
-    psListAdd(list, PS_LIST_HEAD, tmpImage4);
-
-    printPositiveTestHeader(stdout, "pmSubtractBias", "Column Overscans");
-
-    myReadout = pmSubtractBias(myReadout, myPoly, list, PM_OVERSCAN_COLUMNS, stat,
-                               0, PM_FIT_POLYNOMIAL, NULL);
-
-    for (i=0;i<numRows;i++) {
-        for (j=0;j<numCols;j++) {
-            expect = ((float) (i + j)) - 12.0;
-            actual = myReadout->image->data.F32[i][j];
-            if (FLT_EPSILON < fabs(expect - actual)) {
-                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
-                testStatus = 1;
-            }
-        }
-    }
-
-
-    psFree(myReadout);
-    psFree(tmpImage2);
-    psFree(tmpImage3);
-    psFree(tmpImage4);
-    psFree(stat);
-    psFree(list);
-    psFree(myPoly);
-
-    printFooter(stdout, "pmSubtractBias", "Column Overscans", true);
-    return(testStatus);
-}
-/******************************************************************************
-doSubtractFullOverscansSmall(): a sample pmReadout as well as several overscan
-images of smaller size are created.  The overscan images are collected
-pixel-by-pixel then subtracted column-wise from the pmReadout.
- *****************************************************************************/
-int doSubtractFullOverscanColumnsSmall(int numCols, int numRows)
-{
-    int i;
-    int j;
-    float actual;
-    float expect;
-    int testStatus = 0;
-    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    pmReadout *myReadout = pmReadoutAlloc(NULL);
-    myReadout->image = tmpImage1;
-    psImage *tmpImage2 = psImageAlloc(numCols/2, numRows/2, PS_TYPE_F32);
-    psImage *tmpImage3 = psImageAlloc(numCols/2, numRows/2, PS_TYPE_F32);
-    psImage *tmpImage4 = psImageAlloc(numCols/2, numRows/2, PS_TYPE_F32);
-    psList *list;
-    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
-
-    for (i=0;i<numRows;i++) {
-        for (j=0;j<numCols;j++) {
-            myReadout->image->data.F32[i][j] = (float) (i + j);
-        }
-    }
-    for (i=0;i<numRows/2;i++) {
-        for (j=0;j<numCols/2;j++) {
-            tmpImage2->data.F32[i][j] = 3.0;
-            tmpImage3->data.F32[i][j] = 4.0;
-            tmpImage4->data.F32[i][j] = 5.0;
-        }
-    }
-    list = psListAlloc(tmpImage2);
-    psListAdd(list, PS_LIST_HEAD, tmpImage3);
-    psListAdd(list, PS_LIST_HEAD, tmpImage4);
-
-    printPositiveTestHeader(stdout, "pmSubtractBias", "Column Overscans");
-
-    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_COLUMNS, stat,
-                               0, PM_FIT_POLYNOMIAL, NULL);
-
-    for (i=0;i<numRows;i++) {
-        for (j=0;j<numCols;j++) {
-            expect = ((float) (i + j)) - 12.0;
-            actual = myReadout->image->data.F32[i][j];
-            if (FLT_EPSILON < fabs(expect - actual)) {
-                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
-                testStatus = 1;
-            }
-        }
-    }
-
-
-    psFree(myReadout);
-    psFree(tmpImage2);
-    psFree(tmpImage3);
-    psFree(tmpImage4);
-    psFree(stat);
-    psFree(list);
-
-    printFooter(stdout, "pmSubtractBias", "Column Overscans", true);
-    return(testStatus);
-}
-
-int test02( void )
-{
-    int testStatus = 0;
-
-    testStatus |= doSubtractFullOverscanColumns(1, 1);
-    testStatus |= doSubtractFullOverscanColumns(1, NUM_ROWS);
-    testStatus |= doSubtractFullOverscanColumns(NUM_COLS, 1);
-    testStatus |= doSubtractFullOverscanColumns(NUM_COLS, NUM_ROWS);
-    /* These tests do not make sense until the SDRS is clarified.
-        testStatus |= doSubtractFullOverscanColumnsSmall(1, 1);
-        testStatus |= doSubtractFullOverscanColumnsSmall(1, NUM_ROWS);
-        testStatus |= doSubtractFullOverscanColumnsSmall(NUM_COLS, 1);
-        testStatus |= doSubtractFullOverscanColumnsSmall(NUM_COLS, NUM_ROWS);
-    */
-
-    return(testStatus);
-}
-
-/******************************************************************************
-doSubtractFullOverscans(): a sample pmReadout as well as several overscan
-images of the same size are created.  The overscan images are collected
-pixel-by-pixel then subtracted row-wise from the pmReadout.
- *****************************************************************************/
-int doSubtractFullOverscanRows(int numCols, int numRows)
-{
-    int i;
-    int j;
-    float actual;
-    float expect;
-    int testStatus = 0;
-    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    psImage *tmpImage3 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    psImage *tmpImage4 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    pmReadout *myReadout = pmReadoutAlloc(NULL);
-    myReadout->image = tmpImage1;
-    psList *list;
-    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
-
-    for (i=0;i<numRows;i++) {
-        for (j=0;j<numCols;j++) {
-            myReadout->image->data.F32[i][j] = (float) (i + j);
-            tmpImage2->data.F32[i][j] = 3.0;
-            tmpImage3->data.F32[i][j] = 4.0;
-            tmpImage4->data.F32[i][j] = 5.0;
-        }
-    }
-    list = psListAlloc(tmpImage2);
-    psListAdd(list, PS_LIST_HEAD, tmpImage3);
-    psListAdd(list, PS_LIST_HEAD, tmpImage4);
-
-    printPositiveTestHeader(stdout, "pmSubtractBias", "Row Overscans");
-
-    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_ROWS, stat,
-                               0, PM_FIT_NONE, NULL);
-
-    for (i=0;i<numRows;i++) {
-        for (j=0;j<numCols;j++) {
-            expect = ((float) (i + j)) - 12.0;
-            actual = myReadout->image->data.F32[i][j];
-            if (FLT_EPSILON < fabs(expect - actual)) {
-                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
-                testStatus = 1;
-            }
-        }
-    }
-
-
-    psFree(myReadout);
-    psFree(tmpImage2);
-    psFree(tmpImage3);
-    psFree(tmpImage4);
-    psFree(stat);
-    psFree(list);
-
-    printFooter(stdout, "pmSubtractBias", "Row Overscans", true);
-    return(testStatus);
-}
-
-/******************************************************************************
-doSubtractFullOverscansSmall(): a sample pmReadout as well as several overscan
-images of smaller size are created.  The overscan images are collected
-pixel-by-pixel then subtracted row-wise from the pmReadout.
- *****************************************************************************/
-int doSubtractFullOverscanRowsSmall(int numCols, int numRows)
-{
-    int i;
-    int j;
-    float actual;
-    float expect;
-    int testStatus = 0;
-    psS32 OSnumRows = numRows-1;
-    if (OSnumRows == 0) {
-        OSnumRows = 1;
-    }
-    psS32 OSnumCols = numCols-1;
-    if (OSnumCols == 0) {
-        OSnumCols = 1;
-    }
-    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
-    psImage *tmpImage2 = psImageAlloc(OSnumCols, OSnumRows, PS_TYPE_F32);
-    psImage *tmpImage3 = psImageAlloc(OSnumCols, OSnumRows, PS_TYPE_F32);
-    psImage *tmpImage4 = psImageAlloc(OSnumCols, OSnumRows, PS_TYPE_F32);
-    pmReadout *myReadout = pmReadoutAlloc(NULL);
-    myReadout->image = tmpImage1;
-    psList *list;
-    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
-
-    for (i=0;i<numRows;i++) {
-        for (j=0;j<numCols;j++) {
-            myReadout->image->data.F32[i][j] = (float) (i + j);
-        }
-    }
-    for (i=0;i<OSnumRows;i++) {
-        for (j=0;j<OSnumCols;j++) {
-            tmpImage2->data.F32[i][j] = 3.0;
-            tmpImage3->data.F32[i][j] = 4.0;
-            tmpImage4->data.F32[i][j] = 5.0;
-        }
-    }
-    list = psListAlloc(tmpImage2);
-    psListAdd(list, PS_LIST_HEAD, tmpImage3);
-    psListAdd(list, PS_LIST_HEAD, tmpImage4);
-
-    printPositiveTestHeader(stdout, "pmSubtractBias", "Row Overscans");
-
-    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_ROWS, stat,
-                               0, PM_FIT_SPLINE, NULL);
-
-    for (i=0;i<numRows;i++) {
-        for (j=0;j<numCols;j++) {
-            expect = ((float) (i + j)) - 12.0;
-            actual = myReadout->image->data.F32[i][j];
-            if (FLT_EPSILON < fabs(expect - actual)) {
-                printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
-                testStatus = 1;
-            }
-        }
-    }
-
-
-    psFree(myReadout);
-    psFree(tmpImage2);
-    psFree(tmpImage3);
-    psFree(tmpImage4);
-    psFree(stat);
-    psFree(list);
-
-    printFooter(stdout, "pmSubtractBias", "Row Overscans", true);
-    return(testStatus);
-}
-
-
-// XXX: HEY
-int test03( void )
-{
-    int testStatus = 0;
-
-    //    testStatus |= doSubtractFullOverscanRows(1, 1);
-    //    testStatus |= doSubtractFullOverscanRows(1, NUM_ROWS);
-    //    testStatus |= doSubtractFullOverscanRows(NUM_COLS, 1);
-    //    testStatus |= doSubtractFullOverscanRows(NUM_COLS, NUM_ROWS);
-    //    testStatus |= doSubtractFullOverscanRowsSmall(1, 1);
-    //    testStatus |= doSubtractFullOverscanRowsSmall(1, NUM_ROWS);
-    //    testStatus |= doSubtractFullOverscanRowsSmall(NUM_COLS, 1);
-    testStatus |= doSubtractFullOverscanRowsSmall(NUM_COLS, NUM_ROWS);
-
-    return(testStatus);
-}
-
-
-
+
+/*
 int doSubtractOverscansTestInputCases(int numCols, int numRows)
 {
@@ -568,5 +225,5 @@
     myBias->image = tmpImage5;
     printPositiveTestHeader(stdout, "pmSubtractBias", "Testing input parameter error conditions");
-
+ 
     psImage *tmpImage5ShortRows = psImageAlloc(numCols, numRows-1, PS_TYPE_F32);
     pmReadout *myBiasShortRows = pmReadoutAlloc(NULL);
@@ -575,5 +232,5 @@
     pmReadout *myBiasShortCols = pmReadoutAlloc(NULL);
     myBiasShortCols->image = tmpImage5ShortCols;
-
+ 
     for (i=0;i<numRows;i++) {
         for (j=0;j<numCols;j++) {
@@ -588,5 +245,5 @@
     psListAdd(list, PS_LIST_HEAD, tmpImage3);
     psListAdd(list, PS_LIST_HEAD, tmpImage4);
-
+ 
     for (i=0;i<numRows-1;i++) {
         for (j=0;j<numCols-1;j++) {
@@ -609,6 +266,6 @@
         }
     }
-
-
+ 
+ 
     printf("------------------------------------------------------------------\n");
     printf("Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_ALL.  Should generate error.\n");
@@ -618,5 +275,5 @@
         testStatus = false;
     }
-
+ 
     printf("------------------------------------------------------------------\n");
     printf("Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_ROWS.  Should generate error.\n");
@@ -627,5 +284,5 @@
         psFree(rc);
     }
-
+ 
     printf("------------------------------------------------------------------\n");
     printf("Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_COLUMNS.  Should generate error.\n");
@@ -636,9 +293,9 @@
         psFree(rc);
     }
-
+ 
     printf("------------------------------------------------------------------\n");
     printf("Calling pmSubtractBias() with non-NULL overscan list and PM_OVERSCAN_NONE.  Should generate warning.\n");
     rc = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_NONE, stat, 0, PM_FIT_NONE, myBias);
-
+ 
     for (i=0;i<numRows;i++) {
         for (j=0;j<numCols;j++) {
@@ -649,11 +306,12 @@
                 testStatus = 1;
             }
-
+ 
             // Restore myReadout for next test.
             myReadout->image->data.F32[i][j] = (float) (i + j);
         }
     }
-
-    /* XXX: This does not seem to be a requirement.
+ 
+    // XXX: This does not seem to be a requirement.
+    if (0) {
         printf("------------------------------------------------------------------\n");
         printf("Calling pmSubtractBias() with NULL overscan list and PM_OVERSCAN_NONE.  Should generate warning.\n");
@@ -674,6 +332,6 @@
             }
         }
-    */
-
+    }
+ 
     printf("------------------------------------------------------------------\n");
     printf("Calling pmSubtractBias() with PM_OVERSCAN_NONE and PM_FIT_POLYNOMIAL.  Should generate Warning.\n");
@@ -687,11 +345,11 @@
                 testStatus = 1;
             }
-
+ 
             // Restore myReadout for next test.
             myReadout->image->data.F32[i][j] = (float) (i + j);
         }
     }
-
-
+ 
+ 
     printf("------------------------------------------------------------------\n");
     printf("Calling pmSubtractBias() with PM_OVERSCAN_ALL and PM_FIT_SPLINE.  Should generate Warning.\n");
@@ -702,5 +360,5 @@
         psFree(rc);
     }
-
+ 
     for (i=0;i<numRows;i++) {
         for (j=0;j<numCols;j++) {
@@ -711,11 +369,11 @@
                 testStatus = 1;
             }
-
+ 
             // Restore myReadout for next test.
             myReadout->image->data.F32[i][j] = (float) (i + j);
         }
     }
-
-
+ 
+ 
     printf("------------------------------------------------------------------\n");
     printf("Calling pmSubtractBias() with multiple stats->options.  Should generate Warning.\n");
@@ -734,10 +392,10 @@
     }
     stat->options = PS_STAT_SAMPLE_MEAN;
-
+ 
     printf("------------------------------------------------------------------\n");
     printf("Calling pmSubtractBias() undersize overscans (PM_OVERSCAN_ROWS).  Should generate Warning.\n");
     rc = pmSubtractBias(myReadout, NULL, listShort, PM_OVERSCAN_ROWS, stat,
                         0, PM_FIT_NONE, NULL);
-    /*
+    if (0) {
         for (i=0;i<numRows;i++) {
             for (j=0;j<numCols;j++) {
@@ -750,11 +408,11 @@
             }
         }
-    */
-
+    }
+ 
     printf("------------------------------------------------------------------\n");
     printf("Calling pmSubtractBias() undersize overscans (PM_OVERSCAN_COLUMNS).  Should generate Warning.\n");
     rc = pmSubtractBias(myReadout, NULL, listShort, PM_OVERSCAN_COLUMNS, stat,
                         0, PM_FIT_NONE, NULL);
-    /*
+    if (0) {
         for (i=0;i<numRows;i++) {
             for (j=0;j<numCols;j++) {
@@ -767,6 +425,6 @@
             }
         }
-    */
-
+    }
+ 
     printf("------------------------------------------------------------------\n");
     printf("Calling pmSubtractBias() undersize bias image (short rows).  Should generate Error.\n");
@@ -778,6 +436,6 @@
         psFree(rc);
     }
-
-
+ 
+ 
     printf("------------------------------------------------------------------\n");
     printf("Calling pmSubtractBias() undersize bias image (short columns).  Should generate Error.\n");
@@ -789,5 +447,5 @@
         psFree(rc);
     }
-
+ 
     printf("------------------------------------------------------------------\n");
     printf("Calling pmSubtractBias() with bogus PM_FIT.  Should generate Error.\n");
@@ -799,5 +457,5 @@
         psFree(rc);
     }
-
+ 
     printf("------------------------------------------------------------------\n");
     printf("Calling pmSubtractBias() with bogus overScanAxis.  Should generate Error.\n");
@@ -809,6 +467,6 @@
         psFree(rc);
     }
-
-    /*
+ 
+    if (0) {
         for (i=0;i<numRows;i++) {
             for (j=0;j<numCols;j++) {
@@ -821,6 +479,6 @@
             }
         }
-    */
-
+    }
+ 
     printf("------------------------------------------------------------------\n");
     psFree(myReadout);
@@ -837,29 +495,32 @@
     psFree(list);
     psFree(listShort);
-
+ 
     printFooter(stdout, "pmSubtractBias", "Testing input parameter error conditions", true);
     return(testStatus);
 }
-
+ 
 int test04( void )
 {
     int testStatus = 0;
-
+ 
     testStatus |= doSubtractOverscansTestInputCases(NUM_COLS, NUM_ROWS);
     return(testStatus);
 }
+*/
 
 /******************************************************************************
-doSubtractFullOverscansSmall(): a sample pmReadout as well as several overscan
-images of smaller size are created.  The overscan images are collected
-pixel-by-pixel then subtracted column-wise from the pmReadout.
+doSubtractFullOverscanColumnsGeneric(): This is a general version of the
+bias subtraction tests which allows the various parameters to be specified
+as arguments.
  *****************************************************************************/
-int doSubtractFullOverscanColumnsGeneric(int imageNumCols,
-        int imageNumRows,
-        int overscanNumCols,
-        int overscanNumRows,
-        pmOverscanAxis overscanaxis,
-        pmFit fit,
-        psS32 nBin)
+int doSubtractFullOverscanColumnsGeneric(
+    int imageNumCols,
+    int imageNumRows,
+    int overscanNumCols,
+    int overscanNumRows,
+    int numOverscans,
+    pmOverscanAxis overscanaxis,
+    pmFit fit,
+    psS32 nBin)
 {
     int i;
@@ -869,73 +530,137 @@
     int testStatus = 0;
 
-    psImage *tmpImage1 = psImageAlloc(imageNumCols, imageNumRows, PS_TYPE_F32);
-    //    pmReadout *myReadout = pmReadoutAlloc(imageNumCols, imageNumRows, tmpImage1);
-    pmReadout *myReadout = pmReadoutAlloc(NULL);
-    myReadout->image = tmpImage1;
+    printPositiveTestHeader(stdout, "pmSubtractBias", "PUT COMMENT HERE");
+    printf("---- doSubtractFullOverscanColumnsGeneric() ----\n");
+    printf("    Image size: %d by %d\n", imageNumRows, imageNumCols);
+    printf("    Overscan size: %d by %d\n", overscanNumRows, overscanNumCols);
+    printf("    Total Overscans: %d\n", numOverscans);
+    printf("    Binning factor: %d\n", nBin);
+    if (overscanaxis == PM_OVERSCAN_ROWS)
+        printf("    Overscan axis: PM_OVERSCAN_ROWS\n");
+    if (overscanaxis == PM_OVERSCAN_COLUMNS)
+        printf("    Overscan axis: PM_OVERSCAN_COLUMNS\n");
+    if (overscanaxis == PM_OVERSCAN_ALL)
+        printf("    Overscan axis: PM_OVERSCAN_ALL\n");
+    if (overscanaxis == PM_OVERSCAN_NONE)
+        printf("    Overscan axis: PM_OVERSCAN_NONE\n");
+    if (fit == PM_FIT_NONE)
+        printf("    Fit type: PM_FIT_NONE\n");
+    if (fit == PM_FIT_POLYNOMIAL)
+        printf("    Fit type: PM_FIT_POLYNOMIAL\n");
+    if (fit == PM_FIT_SPLINE)
+        printf("    Fit type: PM_FIT_SPLINE\n");
+
+    //
+    // Create and initialize input image, FPA hierarchy.
+    //
+    const psMetadata *camera = psMetadataAlloc();
+    pmFPA* fpa = pmFPAAlloc(camera);
+
+    if (fpa == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR, "TEST ERROR: pmFPAAlloc returned a NULL.\n");
+        return 1;
+    }
+
+    pmChip *chip = pmChipAlloc(fpa, "ChipName");
+    if (chip == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR, "TEST ERROR: pmChipAlloc returned a NULL.\n");
+        return 2;
+    }
+
+    pmCell *cell = pmCellAlloc(chip, (psMetadata *) camera, "CellName");
+    if (cell == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR, "TEST ERROR: pmCellAlloc returned a NULL.\n");
+        return 3;
+    }
+
+    pmReadout *myReadout = pmReadoutAlloc(cell);
+    myReadout->image = psImageAlloc(imageNumCols, imageNumRows, PS_TYPE_F32);
+    for (i=0;i<myReadout->image->numRows;i++) {
+        for (j=0;j<myReadout->image->numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+    //
+    // Set overscan axis in the metadata.
+    //
+    psBool rc;
+    if (overscanaxis == PM_OVERSCAN_ROWS) {
+        rc = psMetadataAddS32(myReadout->parent->concepts, PS_LIST_HEAD, "CELL.READDIR", 0, NULL, 1);
+    } else if (overscanaxis == PM_OVERSCAN_COLUMNS) {
+        rc = psMetadataAddS32(myReadout->parent->concepts, PS_LIST_HEAD, "CELL.READDIR", 0, NULL, 2);
+    } else if (overscanaxis == PM_OVERSCAN_ALL) {
+        rc = psMetadataAddS32(myReadout->parent->concepts, PS_LIST_HEAD, "CELL.READDIR", 0, NULL, 3);
+    } else if (overscanaxis == PM_OVERSCAN_NONE) {
+        rc = psMetadataAddS32(myReadout->parent->concepts, PS_LIST_HEAD, "CELL.READDIR", 0, NULL, 0);
+    }
+    if (rc == false) {
+        printf("TEST ERROR: Could not set CELL.READDIR metadata.\n");
+        testStatus = 1;
+    }
+
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psPolynomial1D *myPoly = psPolynomial1DAlloc(POLYNOMIAL_FIT_ORDER, PS_POLYNOMIAL_ORD);
+    psSpline1D *mySpline = NULL;
+
+
+    if (0) {
+        if (overscanNumRows <= 0) {
+            overscanNumRows = 1;
+        }
+        if (overscanNumCols <= 0) {
+            overscanNumCols = 1;
+        }
+    }
+    psF32 oAverage = 0.0;
+    myReadout->bias = NULL;
+    for (psS32 i = 0 ; i < numOverscans ; i++) {
+        psImage *tmpImage = psImageAlloc(overscanNumCols, overscanNumRows, PS_TYPE_F32);
+        psF32 oValue = (float) (i + 3);
+        PS_IMAGE_SET_F32(tmpImage, oValue);
+        oAverage += oValue;
+        if (myReadout->bias == NULL) {
+            myReadout->bias = psListAlloc(tmpImage);
+        } else {
+            psListAdd(myReadout->bias, PS_LIST_HEAD, tmpImage);
+        }
+    }
+    oAverage/= (psF32) numOverscans;
+
+
+    if (fit == PM_FIT_NONE) {
+        myReadout = pmSubtractBias(myReadout, NULL, PM_FIT_NONE, overscanaxis,
+                                   stat, nBin, NULL, NULL);
+    } else if (fit == PM_FIT_POLYNOMIAL) {
+        myReadout = pmSubtractBias(myReadout, myPoly, PM_FIT_POLYNOMIAL, overscanaxis,
+                                   stat, nBin, NULL, NULL);
+    } else if (fit == PM_FIT_SPLINE) {
+        myReadout = pmSubtractBias(myReadout, mySpline, PM_FIT_SPLINE, overscanaxis,
+                                   stat, nBin, NULL, NULL);
+    }
+
     for (i=0;i<imageNumRows;i++) {
         for (j=0;j<imageNumCols;j++) {
-            myReadout->image->data.F32[i][j] = (float) (i + j);
-        }
-    }
-
-    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
-    psPolynomial1D *myPoly = psPolynomial1DAlloc(1, PS_POLYNOMIAL_ORD);
-    psSpline1D *mySpline = NULL;
-
-
-    /*
-        if (overscanNumRows <= 0) {
-            overscanNumRows = 1;
-        }
-        if (overscanNumCols <= 0) {
-            overscanNumCols = 1;
-        }
-    */
-    psImage *tmpImage2 = psImageAlloc(overscanNumCols, overscanNumRows, PS_TYPE_F32);
-    psImage *tmpImage3 = psImageAlloc(overscanNumCols, overscanNumRows, PS_TYPE_F32);
-    psImage *tmpImage4 = psImageAlloc(overscanNumCols, overscanNumRows, PS_TYPE_F32);
-    psList *list;
-    for (i=0;i<overscanNumRows;i++) {
-        for (j=0;j<overscanNumCols;j++) {
-            tmpImage2->data.F32[i][j] = 3.0;
-            tmpImage3->data.F32[i][j] = 4.0;
-            tmpImage4->data.F32[i][j] = 5.0;
-        }
-    }
-    list = psListAlloc(tmpImage2);
-    psListAdd(list, PS_LIST_HEAD, tmpImage3);
-    psListAdd(list, PS_LIST_HEAD, tmpImage4);
-
-    printPositiveTestHeader(stdout, "pmSubtractBias", "Column Overscans");
-
-    if (fit == PM_FIT_NONE) {
-        myReadout = pmSubtractBias(myReadout, NULL, list, overscanaxis, stat,
-                                   nBin, fit, NULL);
-    } else if (fit == PM_FIT_POLYNOMIAL) {
-        myReadout = pmSubtractBias(myReadout, myPoly, list, overscanaxis, stat,
-                                   nBin, fit, NULL);
-    } else if (fit == PM_FIT_SPLINE) {
-        myReadout = pmSubtractBias(myReadout, mySpline, list, overscanaxis, stat,
-                                   nBin, fit, NULL);
-    }
-
-    for (i=0;i<imageNumRows;i++) {
-        for (j=0;j<imageNumCols;j++) {
-            expect = ((float) (i + j)) - 12.0;
+            expect = ((float) (i + j)) - oAverage;
             actual = myReadout->image->data.F32[i][j];
             if (FLT_EPSILON < fabs(expect - actual)) {
                 printf("TEST ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
                 testStatus = 1;
+            } else {
+                //printf("COOL: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
             }
         }
     }
-
-
+    psFree(fpa);
+    psFree(chip);
+    psFree(cell);
+    psListElem *tmpElem = (psListElem *) myReadout->bias->head;
+    while (NULL != tmpElem) {
+        psFree((psImage *) tmpElem->data);
+        tmpElem = tmpElem->next;
+    }
     psFree(myReadout);
-    psFree(tmpImage2);
-    psFree(tmpImage3);
-    psFree(tmpImage4);
+    psFree(camera);
     psFree(stat);
-    psFree(list);
     psFree(myPoly);
     psFree(mySpline);
@@ -945,5 +670,47 @@
 }
 
-int testX( void )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+test05a() The following combinations are tested here:
+ Overscan images are same size, no fit, bin factor is 1.
+ Overscan images are same size, no fit, bin factor is 2.
+ *****************************************************************************/
+int test05a(
+    psS32 imageNumCols,
+    psS32 imageNumRows,
+    psS32 overscanNumCols,
+    psS32 overscanNumRows)
 {
     int testStatus = 0;
@@ -955,16 +722,16 @@
     // Overscan images are same size, no fit, bin factor is 1.
     //
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
                   PM_OVERSCAN_ALL,
                   PM_FIT_NONE, 1);
 
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
                   PM_OVERSCAN_COLUMNS,
                   PM_FIT_NONE, 1);
 
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
                   PM_OVERSCAN_ROWS,
                   PM_FIT_NONE, 1);
@@ -973,125 +740,351 @@
     // Overscan images are same size, no fit, bin factor is 2.
     //
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
                   PM_OVERSCAN_ALL,
                   PM_FIT_NONE, 2);
 
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
                   PM_OVERSCAN_COLUMNS,
                   PM_FIT_NONE, 2);
 
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
                   PM_OVERSCAN_ROWS,
                   PM_FIT_NONE, 2);
-    //
-    // Overscan images are too small, spline fit, bin factor is 1.
-    //
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS-1, NUM_ROWS-1,
-                  PM_OVERSCAN_ALL,
-                  PM_FIT_SPLINE, 1);
-
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS-1, NUM_ROWS-1,
-                  PM_OVERSCAN_COLUMNS,
-                  PM_FIT_SPLINE, 1);
-
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS-1, NUM_ROWS-1,
-                  PM_OVERSCAN_ROWS,
-                  PM_FIT_SPLINE, 1);
-
-    //
-    // Overscan images are too small, spline fit, bin factor is 2.
-    //
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS-1, NUM_ROWS-1,
-                  PM_OVERSCAN_ALL,
-                  PM_FIT_SPLINE, 2);
-
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS-1, NUM_ROWS-1,
-                  PM_OVERSCAN_COLUMNS,
-                  PM_FIT_SPLINE, 2);
-
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS-1, NUM_ROWS-1,
-                  PM_OVERSCAN_ROWS,
-                  PM_FIT_SPLINE, 2);
-
-    //
-    // Overscan images are same size, spline fit, bin factor is 1.
-    //
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
-                  PM_OVERSCAN_ALL,
-                  PM_FIT_SPLINE, 1);
-
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
-                  PM_OVERSCAN_COLUMNS,
-                  PM_FIT_SPLINE, 1);
-
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
-                  PM_OVERSCAN_ROWS,
-                  PM_FIT_SPLINE, 1);
-    //
-    // Overscan images are same size, spline fit, bin factor is 2.
-    //
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
-                  PM_OVERSCAN_ALL,
-                  PM_FIT_SPLINE, 2);
-
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
-                  PM_OVERSCAN_COLUMNS,
-                  PM_FIT_SPLINE, 2);
-
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
-                  PM_OVERSCAN_ROWS,
-                  PM_FIT_SPLINE, 2);
-
-    //
-    // Overscan images are same size, polynomial fit, bin factor is 1.
-    //
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
-                  PM_OVERSCAN_ALL,
-                  PM_FIT_POLYNOMIAL, 1);
-
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
-                  PM_OVERSCAN_COLUMNS,
-                  PM_FIT_POLYNOMIAL, 1);
-
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
-                  PM_OVERSCAN_ROWS,
-                  PM_FIT_POLYNOMIAL, 1);
-    //
-    // Overscan images are same size, polynomial fit, bin factor is 2.
-    //
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
-                  PM_OVERSCAN_ALL,
-                  PM_FIT_POLYNOMIAL, 2);
-
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
-                  PM_OVERSCAN_COLUMNS,
-                  PM_FIT_POLYNOMIAL, 2);
-
-    testStatus |= doSubtractFullOverscanColumnsGeneric(NUM_COLS, NUM_ROWS,
-                  NUM_COLS, NUM_ROWS,
-                  PM_OVERSCAN_ROWS,
-                  PM_FIT_POLYNOMIAL, 2);
 
     return(testStatus);
 }
 
+
+/******************************************************************************
+test05b() The following combinations are tested here:
+ Overscan images are too small, spline fit, bin factor is 1.
+ Overscan images are too small, spline fit, bin factor is 2.
+ Overscan images are same size, spline fit, bin factor is 1.
+ Overscan images are same size, spline fit, bin factor is 2.
+ Overscan images are too big,   spline fit, bin factor is 1.
+ Overscan images are too big,   spline fit, bin factor is 2.
+ A single overscan image of the same size, spline fit, bin factor is 1.
+ 
+ Overscan images are too small, polynomial fit, bin factor is 1.
+ Overscan images are too small, polynomial fit, bin factor is 2.
+ Overscan images are same size, polynomial fit, bin factor is 1.
+ Overscan images are same size, polynomial fit, bin factor is 2.
+ Overscan images are too big,   polynomial fit, bin factor is 1.
+ Overscan images are too big,   polynomial fit, bin factor is 2.
+ A single overscan image of the same size, polynomial fit, bin factor is 1.
+ 
+XXX: Must add M-by-N image size tests.
+ *****************************************************************************/
+int test05b(
+    psS32 imageNumCols,
+    psS32 imageNumRows,
+    psS32 overscanNumCols,
+    psS32 overscanNumRows)
+{
+    int testStatus = 0;
+
+    //
+    // Overscan images are too small, spline fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols-2, overscanNumRows-2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols-2, overscanNumRows-2, NUM_OVERSCANS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols-2, overscanNumRows-2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 1);
+
+    //
+    // Overscan images are too small, spline fit, bin factor is 2.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols-2, overscanNumRows-2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols-2, overscanNumRows-2, NUM_OVERSCANS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols-2, overscanNumRows-2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 2);
+
+
+    //
+    // Overscan images are same size, spline fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 1);
+
+    //
+    // Overscan images are same size, spline fit, bin factor is 2.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 2);
+
+    //
+    // Overscan images are too big, spline fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols+2, overscanNumRows+2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols+2, overscanNumRows+2, NUM_OVERSCANS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols+2, overscanNumRows+2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 1);
+
+    //
+    // Overscan images are too big, spline fit, bin factor is 2.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols+2, overscanNumRows+2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols+2, overscanNumRows+2, NUM_OVERSCANS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols+2, overscanNumRows+2 , NUM_OVERSCANS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 2);
+
+
+    //
+    // A single overscan image of the same size, spline fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, 1,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, 1,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_SPLINE, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, 1,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_SPLINE, 1);
+
+
+    //
+    // Overscan images are too small, polynomial fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols-2, overscanNumRows-2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols-2, overscanNumRows-2, NUM_OVERSCANS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols-2, overscanNumRows-2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    //
+    // Overscan images are too small, polynomial fit, bin factor is 2.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols-2, overscanNumRows-2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_POLYNOMIAL, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols-2, overscanNumRows-2, NUM_OVERSCANS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_POLYNOMIAL, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols-2, overscanNumRows-2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_POLYNOMIAL, 2);
+
+
+    //
+    // Overscan images are same size, polynomial fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    //
+    // Overscan images are same size, polynomial fit, bin factor is 2.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_POLYNOMIAL, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_POLYNOMIAL, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, NUM_OVERSCANS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_POLYNOMIAL, 2);
+
+    //
+    // Overscan images are too big, polynomial fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols+2, overscanNumRows+2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols+2, overscanNumRows+2, NUM_OVERSCANS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols+2, overscanNumRows+2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    //
+    // Overscan images are too big, polynomial fit, bin factor is 2.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols+2, overscanNumRows+2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_POLYNOMIAL, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols+2, overscanNumRows+2, NUM_OVERSCANS,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_POLYNOMIAL, 2);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols+2, overscanNumRows+2, NUM_OVERSCANS,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_POLYNOMIAL, 2);
+
+    //
+    // A single overscan image of the same size, polynomial fit, bin factor is 1.
+    //
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, 1,
+                  PM_OVERSCAN_ALL,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, 1,
+                  PM_OVERSCAN_COLUMNS,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    testStatus |= doSubtractFullOverscanColumnsGeneric(imageNumCols, imageNumRows,
+                  overscanNumCols, overscanNumRows, 1,
+                  PM_OVERSCAN_ROWS,
+                  PM_FIT_POLYNOMIAL, 1);
+
+    return(testStatus);
+}
+
+
+
+#define LOW_COLS 3
+#define LOW_ROWS 3
+
+/******************************************************************************
+test05(): See test05a() and test05b().
+ 
+We run the tests in test05b() starting with all possible combinations of
+sizes.
+ 
+XXX: Must add M-by-N image size tests.
+ *****************************************************************************/
+int test05()
+{
+    int testStatus = 0;
+    testStatus = test05a(NUM_COLS, NUM_ROWS, NUM_COLS, NUM_ROWS);
+
+    //    testStatus|= test05b(LOW_COLS, LOW_ROWS, LOW_COLS, LOW_ROWS);
+    //    testStatus|= test05b(LOW_COLS, LOW_ROWS, LOW_COLS, NUM_ROWS);
+    //    testStatus|= test05b(LOW_COLS, LOW_ROWS, NUM_COLS, LOW_ROWS);
+    //    testStatus|= test05b(LOW_COLS, LOW_ROWS, NUM_COLS, NUM_ROWS);
+
+    //    testStatus|= test05b(LOW_COLS, NUM_ROWS, LOW_COLS, LOW_ROWS);
+    //    testStatus|= test05b(LOW_COLS, NUM_ROWS, LOW_COLS, NUM_ROWS);
+    //    testStatus|= test05b(LOW_COLS, NUM_ROWS, NUM_COLS, LOW_ROWS);
+    //    testStatus|= test05b(LOW_COLS, NUM_ROWS, NUM_COLS, NUM_ROWS);
+
+    //    testStatus|= test05b(NUM_COLS, LOW_ROWS, LOW_COLS, LOW_ROWS);
+    //    testStatus|= test05b(NUM_COLS, LOW_ROWS, LOW_COLS, NUM_ROWS);
+    //    testStatus|= test05b(NUM_COLS, LOW_ROWS, NUM_COLS, LOW_ROWS);
+    //    testStatus|= test05b(NUM_COLS, LOW_ROWS, NUM_COLS, NUM_ROWS);
+
+    //    testStatus|= test05b(NUM_COLS, NUM_ROWS, LOW_COLS, LOW_ROWS);
+    //    testStatus|= test05b(NUM_COLS, NUM_ROWS, LOW_COLS, NUM_ROWS);
+    //    testStatus|= test05b(NUM_COLS, NUM_ROWS, NUM_COLS, LOW_ROWS);
+    testStatus|= test05b(NUM_COLS, NUM_ROWS, NUM_COLS, NUM_ROWS);
+
+
+    return(testStatus);
+}
+
+
