Index: trunk/ppImage/src/ppImageParseCamera.c
===================================================================
--- trunk/ppImage/src/ppImageParseCamera.c	(revision 12821)
+++ trunk/ppImage/src/ppImageParseCamera.c	(revision 12824)
@@ -5,6 +5,6 @@
 # include "ppImage.h"
 
-ppImageOptions *ppImageParseCamera (pmConfig *config) {
-
+ppImageOptions *ppImageParseCamera(pmConfig *config)
+{
     bool status = false;
 
@@ -15,9 +15,22 @@
         return NULL;
     }
+    if (input->type != PM_FPA_FILE_IMAGE) {
+        psError(PS_ERR_IO, true, "PPIMAGE.INPUT is not of type IMAGE");
+        return NULL;
+    }
 
     // if MASK or WEIGHT was supplied on command line, bind files to 'input'
     // the mask and weight will be mosaicked with the image
-    pmFPAfileBindFromArgs (NULL, input, config, "PPIMAGE.INPUT.MASK",   "MASK");
-    pmFPAfileBindFromArgs (NULL, input, config, "PPIMAGE.INPUT.WEIGHT", "WEIGHT");
+    pmFPAfile *inputMask = pmFPAfileBindFromArgs(NULL, input, config, "PPIMAGE.INPUT.MASK", "INPUT.MASK");
+    if (inputMask && inputMask->type != PM_FPA_FILE_MASK) {
+        psError(PS_ERR_IO, true, "PPIMAGE.INPUT.MASK is not of type MASK");
+        return NULL;
+    }
+
+    pmFPAfile *inputWeight = pmFPAfileBindFromArgs(NULL, input, config, "PPIMAGE.INPUT.WEIGHT", "INPUT.WEIGHT");
+    if (inputWeight && inputWeight->type != PM_FPA_FILE_WEIGHT) {
+        psError(PS_ERR_IO, true, "PPIMAGE.INPUT.WEIGHT is not of type WEIGHT");
+        return NULL;
+    }
 
     // add recipe options supplied on command line
@@ -35,6 +48,13 @@
         pmFPAfileDefineFromConf  (&status, config, "PPIMAGE.BIAS");
         pmFPAfileDefineFromDetDB (&status, config, "PPIMAGE.BIAS", input->fpa, PM_DETREND_TYPE_BIAS);
-        if (!status) {
-            psError (PS_ERR_IO, false, "can't find a bias image source");
+        pmFPAfile *bias = psMetadataLookupPtr(NULL, config->files, "PPIMAGE.BIAS");
+        if (!status || !bias) {
+            psError (PS_ERR_IO, false, "Can't find a bias image source");
+            psFree(options);
+            return NULL;
+        }
+        if (bias->type != PM_FPA_FILE_IMAGE) {
+            psError(PS_ERR_IO, true, "PPIMAGE.BIAS is not of type IMAGE");
+            psFree(options);
             return NULL;
         }
@@ -45,6 +65,13 @@
         pmFPAfileDefineFromConf  (&status, config, "PPIMAGE.DARK");
         pmFPAfileDefineFromDetDB (&status, config, "PPIMAGE.DARK", input->fpa, PM_DETREND_TYPE_DARK);
-        if (!status) {
-            psError (PS_ERR_IO, false, "can't find a dark image source");
+        pmFPAfile *dark = psMetadataLookupPtr(NULL, config->files, "PPIMAGE.DARK");
+        if (!status || !dark) {
+            psError (PS_ERR_IO, false, "Can't find a dark image source");
+            psFree(options);
+            return NULL;
+        }
+        if (dark->type != PM_FPA_FILE_IMAGE) {
+            psError(PS_ERR_IO, true, "PPIMAGE.DARK is not of type IMAGE");
+            psFree(options);
             return NULL;
         }
@@ -55,6 +82,13 @@
         pmFPAfileDefineFromConf  (&status, config, "PPIMAGE.MASK");
         pmFPAfileDefineFromDetDB (&status, config, "PPIMAGE.MASK", input->fpa, PM_DETREND_TYPE_MASK);
-        if (!status) {
-            psError (PS_ERR_IO, false, "can't find a mask image source");
+        pmFPAfile *mask = psMetadataLookupPtr(NULL, config->files, "PPIMAGE.MASK");
+        if (!status || !mask) {
+            psError (PS_ERR_IO, false, "Can't find a mask image source");
+            psFree(options);
+            return NULL;
+        }
+        if (mask->type != PM_FPA_FILE_MASK) {
+            psError(PS_ERR_IO, true, "PPIMAGE.MASK is not of type MASK");
+            psFree(options);
             return NULL;
         }
@@ -65,6 +99,13 @@
         pmFPAfileDefineFromConf  (&status, config, "PPIMAGE.SHUTTER");
         pmFPAfileDefineFromDetDB (&status, config, "PPIMAGE.SHUTTER", input->fpa, PM_DETREND_TYPE_SHUTTER);
-        if (!status) {
-            psError (PS_ERR_IO, false, "can't find a shutter image source");
+        pmFPAfile *shutter = psMetadataLookupPtr(NULL, config->files, "PPIMAGE.SHUTTER");
+        if (!status || !shutter) {
+            psError (PS_ERR_IO, false, "Can't find a shutter image source");
+            psFree(options);
+            return NULL;
+        }
+        if (shutter->type != PM_FPA_FILE_IMAGE) {
+            psError(PS_ERR_IO, true, "PPIMAGE.SHUTTER is not of type IMAGE");
+            psFree(options);
             return NULL;
         }
@@ -81,6 +122,13 @@
         psErrorClear();
         pmFPAfileDefineFromDetDB (&status, config, "PPIMAGE.FLAT", input->fpa, PM_DETREND_TYPE_FLAT);
-        if (!status) {
-            psError (PS_ERR_IO, false, "can't find a flat image source");
+        pmFPAfile *flat = psMetadataLookupPtr(NULL, config->files, "PPIMAGE.FLAT");
+        if (!status || !flat) {
+            psError (PS_ERR_IO, false, "Can't find a flat image source");
+            psFree(options);
+            return NULL;
+        }
+        if (flat->type != PM_FPA_FILE_IMAGE) {
+            psError(PS_ERR_IO, true, "PPIMAGE.FLAT is not of type IMAGE");
+            psFree(options);
             return NULL;
         }
@@ -95,4 +143,5 @@
         if (!status || !filter || strlen(filter) == 0) {
             psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find FPA.FILTER.\n");
+            psFree(options);
             return NULL;
         }
@@ -114,5 +163,8 @@
             filters = psMemIncrRefCounter(mdi->data.list);
         } else {
-            psAbort("invalid type for FRINGE.FILTERS");
+            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                    "FRINGE.FILTERS in recipe %s is not of type METADATA", RECIPE_NAME);
+            psFree(options);
+            return NULL;
         }
 
@@ -135,6 +187,13 @@
         pmFPAfileDefineFromConf  (&status, config, "PPIMAGE.FRINGE");
         pmFPAfileDefineFromDetDB (&status, config, "PPIMAGE.FRINGE", input->fpa, PM_DETREND_TYPE_FRINGE_IMAGE);
-        if (!status) {
-            psError (PS_ERR_IO, false, "can't find a fringe image source");
+        pmFPAfile *fringe = psMetadataLookupPtr(NULL, config->files, "PPIMAGE.FRINGE");
+        if (!status || !fringe) {
+            psError (PS_ERR_IO, false, "Can't find a fringe image source");
+            psFree(options);
+            return NULL;
+        }
+        if (fringe->type != PM_FPA_FILE_FRINGE) {
+            psError(PS_ERR_IO, true, "PPIMAGE.FRINGE is not of type FRINGE");
+            psFree(options);
             return NULL;
         }
@@ -148,4 +207,9 @@
         return NULL;
     }
+    if (output->type != PM_FPA_FILE_IMAGE) {
+        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT is not of type IMAGE");
+        psFree(options);
+        return NULL;
+    }
     pmFPAfile *outMask = pmFPAfileDefineOutput(config, input->fpa, "PPIMAGE.OUTPUT.MASK");
     if (!outMask) {
@@ -154,4 +218,9 @@
         return NULL;
     }
+    if (outMask->type != PM_FPA_FILE_MASK) {
+        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.MASK is not of type MASK");
+        psFree(options);
+        return NULL;
+    }
     pmFPAfile *outWeight = pmFPAfileDefineOutput(config, input->fpa, "PPIMAGE.OUTPUT.WEIGHT");
     if (!outWeight) {
@@ -160,4 +229,10 @@
         return NULL;
     }
+    if (outWeight->type != PM_FPA_FILE_WEIGHT) {
+        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.WEIGHT is not of type WEIGHT");
+        psFree(options);
+        return NULL;
+    }
+
     // XXX should these be bound explicitly to the output->fpa rather than the input->fpa?
     pmFPAfile *byChip = pmFPAfileDefineChipMosaic(config, input->fpa, "PPIMAGE.OUTPUT.CHIP");
@@ -167,4 +242,9 @@
         return NULL;
     }
+    if (byChip->type != PM_FPA_FILE_IMAGE) {
+        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.CHIP is not of type IMAGE");
+        psFree(options);
+        return NULL;
+    }
     pmFPAfile *byFPA1 = pmFPAfileDefineFPAMosaic(config, input->fpa, "PPIMAGE.OUTPUT.FPA1");
     if (!byFPA1) {
@@ -173,4 +253,9 @@
         return NULL;
     }
+    if (byFPA1->type != PM_FPA_FILE_IMAGE) {
+        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.FPA1 is not of type IMAGE");
+        psFree(options);
+        return NULL;
+    }
     pmFPAfile *byFPA2 = pmFPAfileDefineFPAMosaic(config, input->fpa, "PPIMAGE.OUTPUT.FPA2");
     if (!byFPA2) {
@@ -179,41 +264,46 @@
         return NULL;
     }
+    if (byFPA2->type != PM_FPA_FILE_IMAGE) {
+        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.FPA2 is not of type IMAGE");
+        psFree(options);
+        return NULL;
+    }
 
     // For photometry, we operate on the chip-mosaicked image
     // we create a copy of the mosaicked image for psphot so we can write out a clean image
     if (options->doPhotom) {
-	pmFPAfile *psphotInput = pmFPAfileDefineFromFPA (config, byChip->fpa, 1, 1, "PSPHOT.INPUT");
-	PS_ASSERT (psphotInput, false);
-
-	// this file is just used as a carrier; 
-	// actual output files (eg, PSPHOT.RESID) are defined below
-	psphotInput->save = false; 
-
-	// define associated psphot input/output files
-	if (!psphotDefineFiles (config, psphotInput)) {
-	    psError(PSPHOT_ERR_CONFIG, false, "Trouble defining the additional input/output files for psphot");
-	    return false;
-	}
+        pmFPAfile *psphotInput = pmFPAfileDefineFromFPA (config, byChip->fpa, 1, 1, "PSPHOT.INPUT");
+        PS_ASSERT (psphotInput, false);
+
+        // this file is just used as a carrier;
+        // actual output files (eg, PSPHOT.RESID) are defined below
+        psphotInput->save = false;
+
+        // define associated psphot input/output files
+        if (!psphotDefineFiles (config, psphotInput)) {
+            psError(PSPHOT_ERR_CONFIG, false, "Trouble defining the additional input/output files for psphot");
+            return false;
+        }
     }
 
     // For photometry, we operate on the chip-mosaicked image
     if (options->doAstromChip || options->doAstromMosaic) {
-	if (!options->doPhotom) {
-	    psError (PSASTRO_ERR_CONFIG, false, "photometry mode is not selected; it is required for astrometry");
-	    return false;
-	}
-
-	pmFPAfile *psphotOutput = psMetadataLookupPtr (&status, config->files, "PSPHOT.OUTPUT");
-	PS_ASSERT (psphotOutput, false);
-
-	pmFPAfile *psastroInput = pmFPAfileDefineInput (config, psphotOutput->fpa, "PSASTRO.INPUT");
-	PS_ASSERT (psastroInput, false);
-	psastroInput->mode = PM_FPA_MODE_REFERENCE;
-
-	// define associated psphot input/output files
-	if (!psastroDefineFiles (config, psastroInput)) {
-	    psError(PSPHOT_ERR_CONFIG, false, "Trouble defining the additional input/output files for psastro");
-	    return false;
-	}
+        if (!options->doPhotom) {
+            psError (PSASTRO_ERR_CONFIG, false, "photometry mode is not selected; it is required for astrometry");
+            return false;
+        }
+
+        pmFPAfile *psphotOutput = psMetadataLookupPtr (&status, config->files, "PSPHOT.OUTPUT");
+        PS_ASSERT (psphotOutput, false);
+
+        pmFPAfile *psastroInput = pmFPAfileDefineInput (config, psphotOutput->fpa, "PSASTRO.INPUT");
+        PS_ASSERT (psastroInput, false);
+        psastroInput->mode = PM_FPA_MODE_REFERENCE;
+
+        // define associated psphot input/output files
+        if (!psastroDefineFiles (config, psastroInput)) {
+            psError(PSPHOT_ERR_CONFIG, false, "Trouble defining the additional input/output files for psastro");
+            return false;
+        }
     }
 
@@ -234,4 +324,9 @@
         return NULL;
     }
+    if (bin1->type != PM_FPA_FILE_IMAGE) {
+        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.BIN1 is not of type IMAGE");
+        psFree(options);
+        return NULL;
+    }
 
     pmFPAfile *bin2 = pmFPAfileDefineFromFPA (config, byChip->fpa, options->xBin2, options->yBin2, "PPIMAGE.BIN2");
@@ -241,4 +336,9 @@
         return NULL;
     }
+    if (bin2->type != PM_FPA_FILE_IMAGE) {
+        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.BIN2 is not of type IMAGE");
+        psFree(options);
+        return NULL;
+    }
 
     // bin1 and bin2 are used as carriers: input for byFPA1, byFPA2
@@ -252,7 +352,17 @@
         return NULL;
     }
+    if (jpg1->type != PM_FPA_FILE_JPEG) {
+        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.JPEG1 is not of type JPEG");
+        psFree(options);
+        return NULL;
+    }
     pmFPAfile *jpg2 = pmFPAfileDefineOutput (config, byFPA2->fpa, "PPIMAGE.JPEG2");
     if (!jpg2) {
         psError(PS_ERR_IO, false, _("Unable to generate new file from PPIMAGE.JPEG2"));
+        psFree(options);
+        return NULL;
+    }
+    if (jpg2->type != PM_FPA_FILE_JPEG) {
+        psError(PS_ERR_IO, true, "PPIMAGE.OUTPUT.JPEG2 is not of type JPEG");
         psFree(options);
         return NULL;
@@ -274,4 +384,5 @@
             if (! pmFPASelectChip(input->fpa, chipNum, false)) {
                 psError(PS_ERR_IO, false, "Chip number %d doesn't exist in camera.\n", chipNum);
+                psFree(options);
                 return false;
             }
@@ -293,15 +404,15 @@
 
     if (psTraceGetLevel("ppImage.config") > 0) {
-	// Get a look inside all the files.
-	psMetadataIterator *filesIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD, NULL); // Iterator
-	psMetadataItem *item;               // Item from iteration
-	fprintf(stderr, "Files:\n");
-	while ((item = psMetadataGetAndIncrement(filesIter))) {
-	    pmFPAfile *file = item->data.V; // File of interest
-	    fprintf(stderr, "%s: %p %p %p (%p) %p\n", file->name,
-		    file->src, file->fpa,
-		    file->camera, file->fpa->camera, file->format);
-	}
-	psFree(filesIter);
+        // Get a look inside all the files.
+        psMetadataIterator *filesIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD, NULL); // Iterator
+        psMetadataItem *item;               // Item from iteration
+        fprintf(stderr, "Files:\n");
+        while ((item = psMetadataGetAndIncrement(filesIter))) {
+            pmFPAfile *file = item->data.V; // File of interest
+            fprintf(stderr, "%s: %p %p %p (%p) %p\n", file->name,
+                    file->src, file->fpa,
+                    file->camera, file->fpa->camera, file->format);
+        }
+        psFree(filesIter);
     }
 
