Index: /branches/2dbias/ppImage/src/ppImageOptions.c
===================================================================
--- /branches/2dbias/ppImage/src/ppImageOptions.c	(revision 42664)
+++ /branches/2dbias/ppImage/src/ppImageOptions.c	(revision 42665)
@@ -187,21 +187,34 @@
     // XXX EAM : we should abort on invalid options. default options?
     if (psMetadataLookupBool(NULL, recipe, "OVERSCAN")) {
+	bool mdok;
+
         options->doOverscan = true;
 
-        // Do the overscan as a single value?
-        bool overscanSingle = psMetadataLookupBool(NULL, recipe, "OVERSCAN.SINGLE");
+        // Fill in the options
+        options->overscan = pmOverscanOptionsAlloc();
+
+	// these options apply to the overscan regardless of layout
+        options->overscan->single   = psMetadataLookupBool(NULL, recipe, "OVERSCAN.SINGLE");
+        options->overscan->constant = psMetadataLookupBool(NULL, recipe, "OVERSCAN.CONSTANT");
+        options->overscan->value    = psMetadataLookupF32(NULL, recipe, "OVERSCAN.VALUE");
+        options->overscan->minValid = psMetadataLookupF32(&mdok, recipe, "OVERSCAN.MIN.VALID");
+	if (!mdok) { options->overscan->minValid = 0.0; }
+        options->overscan->maxValid = psMetadataLookupF32(&mdok, recipe, "OVERSCAN.MAX.VALID");
+	if (!mdok) { options->overscan->maxValid = (float) 0x10000; }
+        options->overscan->maskVal  = 0x0001;
+
+        // statistics for the primary region
+        options->overscan->primary = pmOverscanStatOptionsAlloc();
 
         // How do we fit it?
-        pmFit overscanFit = PM_FIT_NONE; // Fit type for overscan
-        int overscanOrder = 0;          // Order for overscan fit
         psString fit = psMetadataLookupStr(NULL, recipe, "OVERSCAN.FIT");
         if (! strcasecmp(fit, "POLYNOMIAL")) {
-            overscanFit = PM_FIT_POLY_ORD;
-            overscanOrder = psMetadataLookupS32(NULL, recipe, "OVERSCAN.ORDER");
+	    options->overscan->primary->fitType = PM_FIT_POLY_ORD;
+            options->overscan->primary->order   = psMetadataLookupS32(NULL, recipe, "OVERSCAN.ORDER");
         } else if (! strcasecmp(fit, "CHEBYSHEV")) {
-            overscanFit = PM_FIT_POLY_CHEBY;
-            overscanOrder = psMetadataLookupS32(NULL, recipe, "OVERSCAN.ORDER");
+	    options->overscan->primary->fitType = PM_FIT_POLY_CHEBY;
+            options->overscan->primary->order   = psMetadataLookupS32(NULL, recipe, "OVERSCAN.ORDER");
         } else if (! strcasecmp(fit, "SPLINE")) {
-            overscanFit = PM_FIT_SPLINE;
+	    options->overscan->primary->fitType = PM_FIT_SPLINE;
         } else if (strcasecmp(fit, "NONE")) {
             psLogMsg(__func__, PS_LOG_WARN,
@@ -213,37 +226,56 @@
         // What method do we use to measure the overscan statistics?
         // XXX allow user to specify psStats types by name
-        psStats *overscanStats = NULL;  // Statistics for overscan
         psString stat = psMetadataLookupStr(NULL, recipe, "OVERSCAN.STAT");
         if (! strcasecmp(stat, "MEAN")) {
-            // overscanStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
-            overscanStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+            options->overscan->primary->stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
         } else if (! strcasecmp(stat, "MEDIAN")) {
-            overscanStats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN);
+            options->overscan->primary->stat = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN);
         } else {
-            psErrorStackPrint(stderr, "OVERSCAN.STAT (%s) in recipe %s is not one of MEAN or MEDIAN",
-                              stat, RECIPE_NAME);
+            psErrorStackPrint(stderr, "OVERSCAN.STAT (%s) in recipe %s is not one of MEAN or MEDIAN", stat, RECIPE_NAME);
             exit(EXIT_FAILURE);
         }
 
-	bool mdok;
-        int boxcar = psMetadataLookupS32(NULL, recipe, "OVERSCAN.BOXCAR");
-        float gauss = psMetadataLookupF32(NULL, recipe, "OVERSCAN.GAUSS");
-        float minValid = psMetadataLookupF32(&mdok, recipe, "OVERSCAN.MIN.VALID");
-	if (!mdok) { minValid = 0.0; }
-
-        float maxValid = psMetadataLookupF32(&mdok, recipe, "OVERSCAN.MAX.VALID");
-	if (!mdok) { maxValid = (float) 0x10000; }
-
-        // Fill in the options
-        options->overscan = pmOverscanOptionsAlloc(overscanSingle, overscanFit, overscanOrder,
-                                                   overscanStats, boxcar, gauss);
-
-        options->overscan->constant = psMetadataLookupBool(NULL, recipe, "OVERSCAN.CONSTANT");
-        options->overscan->value = psMetadataLookupF32(NULL, recipe, "OVERSCAN.VALUE");
-        options->overscan->minValid = minValid;
-        options->overscan->maxValid = maxValid;
-        options->overscan->maskVal  = 0x0001;
-
-        psFree(overscanStats);
+        options->overscan->primary->boxcar = psMetadataLookupS32(NULL, recipe, "OVERSCAN.BOXCAR");
+        options->overscan->primary->gauss  = psMetadataLookupF32(NULL, recipe, "OVERSCAN.GAUSS");
+
+        // Do the overscan as a single value?
+        options->overscan->TwoD = psMetadataLookupBool(NULL, recipe, "OVERSCAN.2D");
+	if (options->overscan->TwoD) {
+
+	    // statistics for the secondary region
+	    options->overscan->secondary = pmOverscanStatOptionsAlloc();
+
+	    // How do we fit it?
+	    psString fit = psMetadataLookupStr(NULL, recipe, "OVERSCAN.2D.FIT");
+	    if (! strcasecmp(fit, "POLYNOMIAL")) {
+		options->overscan->secondary->fitType = PM_FIT_POLY_ORD;
+		options->overscan->secondary->order   = psMetadataLookupS32(NULL, recipe, "OVERSCAN.2D.ORDER");
+	    } else if (! strcasecmp(fit, "CHEBYSHEV")) {
+		options->overscan->secondary->fitType = PM_FIT_POLY_CHEBY;
+		options->overscan->secondary->order   = psMetadataLookupS32(NULL, recipe, "OVERSCAN.2D.ORDER");
+	    } else if (! strcasecmp(fit, "SPLINE")) {
+		options->overscan->secondary->fitType = PM_FIT_SPLINE;
+	    } else if (strcasecmp(fit, "NONE")) {
+		psLogMsg(__func__, PS_LOG_WARN,
+			 "OVERSCAN.2D.FIT (%s) in recipe %s is not one of NONE, POLYNOMIAL, or SPLINE",
+			 fit, RECIPE_NAME);
+		exit(EXIT_FAILURE);
+	    }
+
+	    // What method do we use to measure the overscan statistics?
+	    // XXX allow user to specify psStats types by name
+	    psString stat = psMetadataLookupStr(NULL, recipe, "OVERSCAN.2D.STAT");
+	    if (! strcasecmp(stat, "MEAN")) {
+		options->overscan->secondary->stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+	    } else if (! strcasecmp(stat, "MEDIAN")) {
+		options->overscan->secondary->stat = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN);
+	    } else {
+		psErrorStackPrint(stderr, "OVERSCAN.2D.STAT (%s) in recipe %s is not one of MEAN or MEDIAN", stat, RECIPE_NAME);
+		exit(EXIT_FAILURE);
+	    }
+
+	    options->overscan->secondary->boxcar = psMetadataLookupS32(NULL, recipe, "OVERSCAN.2D.BOXCAR");
+	    options->overscan->secondary->gauss  = psMetadataLookupF32(NULL, recipe, "OVERSCAN.2D.GAUSS");
+	}
     }
 
