Index: trunk/dvoTools/src/Makefile.am
===================================================================
--- trunk/dvoTools/src/Makefile.am	(revision 11805)
+++ trunk/dvoTools/src/Makefile.am	(revision 11862)
@@ -24,4 +24,5 @@
 	dvoApplyCorrParseCamera.c \
 	dvoApplyCorrLoop.c \
+	dvoApplyCorrReadout.c \
 	dvoApplyCorrCleanup.c \
 	dvoApplyCorrOptions.c \
Index: trunk/dvoTools/src/dvoApplyCorr.h
===================================================================
--- trunk/dvoTools/src/dvoApplyCorr.h	(revision 11805)
+++ trunk/dvoTools/src/dvoApplyCorr.h	(revision 11862)
@@ -31,4 +31,7 @@
 bool dvoApplyCorrLoop(pmConfig *config, dvoApplyCorrOptions *options);
 
+// apply the correction factor pixel-by-pixel
+bool dvoApplyCorrReadout (pmConfig *config, pmFPAview *view, char *inName, char *corrName);
+
 // free memory, check for leaks
 void dvoApplyCorrCleanup (pmConfig *config, dvoApplyCorrOptions *options);
Index: trunk/dvoTools/src/dvoApplyCorrArguments.c
===================================================================
--- trunk/dvoTools/src/dvoApplyCorrArguments.c	(revision 11805)
+++ trunk/dvoTools/src/dvoApplyCorrArguments.c	(revision 11862)
@@ -6,5 +6,5 @@
 
 static void usage (void) {
-    fprintf(stderr, "USAGE: dvoApplyCorr MOSAIC.fits OUTPUT\n\n");
+    fprintf(stderr, "USAGE: dvoApplyCorr -file INPUT.fits OUTPUT\n\n");
     exit (2);
 }
@@ -50,6 +50,4 @@
     }
 
-    if (argc != 2) usage ();
-
     // the input file is a required argument; if not found, we will exit
     bool status = pmConfigFileSetsMD (config->arguments, config, "INPUT", "-file", "-list");
@@ -58,4 +56,8 @@
     }
 
+    pmConfigFileSetsMD (config->arguments, config, "CORR", "-corr", "-corrlist");
+
+    if (argc != 2) usage ();
+
     // Add the output image (which remain on the command-line) to the arguments list
     psMetadataAddStr(config->arguments, PS_LIST_TAIL, "OUTPUT", 0, "Name of the output image", argv[1]);
Index: trunk/dvoTools/src/dvoApplyCorrLoop.c
===================================================================
--- trunk/dvoTools/src/dvoApplyCorrLoop.c	(revision 11805)
+++ trunk/dvoTools/src/dvoApplyCorrLoop.c	(revision 11862)
@@ -14,5 +14,5 @@
     // psMetadata *recipe = psMetadataLookupMetadata(&status, config->recipes, RECIPE_NAME);
 
-    pmFPAfile *input = psMetadataLookupPtr(&status, config->files, "DVOCORR.INPUT");
+    pmFPAfile *input = psMetadataLookupPtr(&status, config->files, "DVOFLAT.INPUT");
     if (!status) {
         psErrorStackPrint(stderr, "Can't find input data!\n");
@@ -58,5 +58,6 @@
 	    if (!readout->data_exists) continue;
 
-	    // XXX put the function here which unbins the input image
+	    // XXX put the function here which multiplies the input image and the correction image
+	    dvoApplyCorrReadout (config, view, "DVOFLAT.INPUT", "DVOFLAT.CORR");
 
 	    if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) {
Index: trunk/dvoTools/src/dvoApplyCorrParseCamera.c
===================================================================
--- trunk/dvoTools/src/dvoApplyCorrParseCamera.c	(revision 11805)
+++ trunk/dvoTools/src/dvoApplyCorrParseCamera.c	(revision 11862)
@@ -10,9 +10,7 @@
 
     // the input image defines the camera, and all recipes and options the follow
-    // XXX we need to change this: mosaic.fits is not in pmFPA format??
-    // - determine the camera from the header keywords
-    pmFPAfile *input = pmFPAfileDefineFromArgs (&status, config, "DVOCORR.INPUT", "INPUT");
-    if (!status || !input) {
-        psError(PS_ERR_IO, false, "Failed to build FPA from DVOCORR.INPUT");
+    pmFPAfile *input = pmFPAfileDefineFromArgs (NULL, config, "DVOFLAT.INPUT", "INPUT");
+    if (!input) {
+        psError(PS_ERR_IO, false, "Failed to build FPA from DVOFLAT.INPUT");
         return NULL;
     }
@@ -25,12 +23,25 @@
 
     // the following files are output targets
-    pmFPAfile *output = pmFPAfileDefineOutput(config, input->fpa, "DVOCORR.OUTPUT");
+    pmFPAfile *output = pmFPAfileDefineOutput(config, input->fpa, "DVOFLAT.OUTPUT");
     if (!output) {
-        psError(PS_ERR_IO, false, _("Unable to generate output file from DVOCORR.OUTPUT"));
+        psError(PS_ERR_IO, false, _("Unable to generate output file from DVOFLAT.OUTPUT"));
         psFree(options);
         return NULL;
     }
 
+    // find the flat-field correction image (from command-line, config file, or detrend db)
+    status = false;
+    pmFPAfileDefineFromArgs  (&status, config, "DVOFLAT.CORR", "CORR");
+    psErrorClear();
+    pmFPAfileDefineFromConf  (&status, config, "DVOFLAT.CORR");
+    psErrorClear();
+    pmFPAfileDefineFromDetDB (&status, config, "DVOFLAT.CORR", input->fpa, PM_DETREND_TYPE_FLAT_CORRECTION);
+    if (!status) {
+	psError (PS_ERR_IO, false, "can't find a flat-field correction image source");
+	return NULL;
+    }
+    
     // Chip selection: turn on only the chips specified (pass status to suppress missing-key log msg)
+    status = false;
     char *chipLine = psMetadataLookupStr(&status, config->arguments, "CHIP_SELECTIONS");
     psArray *chips = psStringSplitArray (chipLine, ",", false);
Index: trunk/dvoTools/src/dvoApplyCorrReadout.c
===================================================================
--- trunk/dvoTools/src/dvoApplyCorrReadout.c	(revision 11862)
+++ trunk/dvoTools/src/dvoApplyCorrReadout.c	(revision 11862)
@@ -0,0 +1,44 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "dvoApplyCorr.h"
+
+// this function is operating on each readout, assuming there is a correspondence between
+// readouts in the input (raw) flat-field image and the correction frame.  this is not really
+// true
+
+bool dvoApplyCorrReadout (pmConfig *config, pmFPAview *view, char *inName, char *corrName) {
+    
+    bool status;
+
+    pmFPAfile *inFile = psMetadataLookupPtr (&status, config->files, inName);
+    pmFPAfile *corrFile = psMetadataLookupPtr (&status, config->files, corrName);
+    assert (inFile);
+    assert (corrFile);
+
+    pmReadout *inData = pmFPAviewThisReadout (view, inFile->fpa);
+    pmReadout *corrData = pmFPAviewThisReadout (view, corrFile->fpa);
+    assert (inData);
+    assert (corrData);
+
+    // dimensions of input image:
+    assert (inData->image->numCols == corrData->image->numCols);
+    assert (inData->image->numRows == corrData->image->numRows);
+
+    // NOTE : the output pmFPA points at the same pixels as the input pmFPA
+
+    // the corr image is a multiplicative factor
+    for (int j = 0; j < inData->image->numRows; j++) {
+	for (int i = 0; i < inData->image->numCols; i++) {
+	    inData->image->data.F32[j][i] *= corrData->image->data.F32[j][i]; 
+	}
+    }
+
+    // psFits *fits = psFitsOpen ("tmp.fits", "w");
+    // psFitsWriteImage (fits, NULL, inData->image, 0, NULL);
+    // psFitsClose (fits);
+    // exit (0);
+
+    return true;
+}
