Index: /trunk/psModules/src/camera/pmFPAfile.c
===================================================================
--- /trunk/psModules/src/camera/pmFPAfile.c	(revision 7479)
+++ /trunk/psModules/src/camera/pmFPAfile.c	(revision 7480)
@@ -289,5 +289,5 @@
 
     if (file->state & PM_FPA_STATE_INACTIVE) {
-        psTrace("pmFPAfile", 5, "skip open for %s, files is inactive", file->name);
+        psTrace("pmFPAfile", 6, "skip open for %s, files is inactive", file->name);
         return true;
     }
@@ -380,10 +380,10 @@
 
     if (file->state & PM_FPA_STATE_INACTIVE) {
-        psTrace("pmFPAfile", 5, "skip read for %s, files is inactive", file->name);
+        psTrace("pmFPAfile", 6, "skip read for %s, files is inactive", file->name);
         return true;
     }
 
     if (file->mode != PM_FPA_MODE_READ) {
-        psTrace("pmFPAfile", 5, "skip read for %s, mode is not READ", file->name);
+        psTrace("pmFPAfile", 6, "skip read for %s, mode is not READ", file->name);
         return true;
     }
@@ -402,5 +402,5 @@
     // do we need to read this file?
     if (depth != file->dataDepth) {
-        psTrace("pmFPAfile", 5, "skip reading of %s at this depth %s: dataDepth is %s",
+        psTrace("pmFPAfile", 6, "skip reading of %s at this depth %s: dataDepth is %s",
                 file->name, depthEnumToName(depth), depthEnumToName(file->dataDepth));
         return true;
@@ -441,5 +441,5 @@
 }
 
-bool pmFPAfileWrite(pmFPAfile *file, const pmFPAview *view)
+bool pmFPAfileFreeData(pmFPAfile *file, const pmFPAview *view)
 {
     PS_ASSERT_PTR_NON_NULL(file, false);
@@ -447,10 +447,5 @@
 
     if (file->state & PM_FPA_STATE_INACTIVE) {
-        psTrace("pmFPAfile", 5, "skip write for %s, files is inactive", file->name);
-        return true;
-    }
-
-    if (file->mode != PM_FPA_MODE_WRITE) {
-        psTrace("pmFPAfile", 5, "skip write for %s, mode is not WRITE", file->name);
+        psTrace("pmFPAfile", 6, "skip free for %s, files is inactive", file->name);
         return true;
     }
@@ -459,7 +454,63 @@
     pmFPAdepth depth = pmFPAviewDepth (view);
 
+    // do we need to read this file?
+    if (depth != file->dataDepth) {
+        psTrace("pmFPAfile", 6, "skip free of %s at this depth %s: dataDepth is %s",
+                file->name, depthEnumToName(depth), depthEnumToName(file->dataDepth));
+        return true;
+    }
+
+    switch (file->type) {
+    case PM_FPA_FILE_IMAGE:
+        if (pmFPAviewFreeFitsImage (view, file)) {
+            psTrace ("pmFPAfile", 5, "freed %s (type: %d)\n", file->filename, file->type);
+        } else {
+            psError(PS_ERR_UNKNOWN, false, "skipping %s (type: %d)\n", file->filename, file->type);
+            return false;
+        }
+        break;
+
+    case PM_FPA_FILE_SX:
+    case PM_FPA_FILE_RAW:
+    case PM_FPA_FILE_OBJ:
+    case PM_FPA_FILE_CMP:
+    case PM_FPA_FILE_CMF:
+        // pmFPAviewFreeObjects (view, file);
+        psTrace ("pmFPAfile", 5, "NOT freeing %s (type: %d)\n", file->filename, file->type);
+        break;
+
+        // XXX not certain what I need to free here
+    case PM_FPA_FILE_PSF:
+    case PM_FPA_FILE_JPEG:
+        break;
+
+    default:
+        psError(PS_ERR_IO, true, "warning: type mismatch; saw type %d", file->type);
+        return false;
+    }
+    return true;
+}
+
+bool pmFPAfileWrite(pmFPAfile *file, const pmFPAview *view)
+{
+    PS_ASSERT_PTR_NON_NULL(file, false);
+    PS_ASSERT_PTR_NON_NULL(view, false);
+
+    if (file->state & PM_FPA_STATE_INACTIVE) {
+        psTrace("pmFPAfile", 6, "skip write for %s, files is inactive", file->name);
+        return true;
+    }
+
+    if (file->mode != PM_FPA_MODE_WRITE) {
+        psTrace("pmFPAfile", 6, "skip write for %s, mode is not WRITE", file->name);
+        return true;
+    }
+
+    // get the current depth
+    pmFPAdepth depth = pmFPAviewDepth (view);
+
     // do we need to write this file?
     if (depth != file->dataDepth) {
-        psTrace("pmFPAfile", 5, "skip writing of %s at this depth %s: dataDepth is %s",
+        psTrace("pmFPAfile", 6, "skip writing of %s at this depth %s: dataDepth is %s",
                 file->name, depthEnumToName(depth), depthEnumToName(file->dataDepth));
         return true;
@@ -518,9 +569,9 @@
     // these are not error conditions; these are state tests
     if (file->state & PM_FPA_STATE_INACTIVE) {
-        psTrace("pmFPAfile", 5, "skip create for inactive file %s", file->name);
+        psTrace("pmFPAfile", 6, "skip create for inactive file %s", file->name);
         return true;
     }
     if (file->mode != PM_FPA_MODE_WRITE) {
-        psTrace("pmFPAfile", 5, "skip create for non-write file %s", file->name);
+        psTrace("pmFPAfile", 6, "skip create for non-write file %s", file->name);
         return true;
     }
@@ -531,5 +582,5 @@
     // don't create the file if the src FPA is not defined
     if (file->src == NULL) {
-        psTrace("pmFPAfile", 5, "skip create for FPA without src FPA for %s", file->name);
+        psTrace("pmFPAfile", 6, "skip create for FPA without src FPA for %s", file->name);
         return true;
     }
@@ -537,5 +588,5 @@
     // do we need to write this file?
     if (depth != file->dataDepth) {
-        psTrace("pmFPAfile", 5, "skip creation of %s at this depth %s: dataDepth is %s",
+        psTrace("pmFPAfile", 6, "skip creation of %s at this depth %s: dataDepth is %s",
                 file->name, depthEnumToName(depth), depthEnumToName(file->dataDepth));
         return true;
@@ -571,5 +622,5 @@
 
     if (file->state & PM_FPA_STATE_INACTIVE) {
-        psTrace("pmFPAfile", 5, "skip close for %s, files is inactive", file->name);
+        psTrace("pmFPAfile", 6, "skip close for %s, files is inactive", file->name);
         return true;
     }
@@ -581,5 +632,5 @@
     pmFPAdepth depth = pmFPAviewDepth (view);
     if (file->fileDepth != depth) {
-        psTrace("pmFPAfile", 5, "skip closing of %s at this depth %s: dataDepth is %s",
+        psTrace("pmFPAfile", 6, "skip closing of %s at this depth %s: dataDepth is %s",
                 file->name, depthEnumToName(depth), depthEnumToName(file->dataDepth));
         return true;
@@ -639,5 +690,5 @@
     pmFPAfile *file = psMetadataLookupPtr (&status, files, name);
     if (!status) {
-        psError(PS_ERR_IO, true, "Failed to look up file %s", name);
+        psTrace("pmFPAfile", 6, "%s is not a defined IO file", name);
         return false;
     }
@@ -654,5 +705,6 @@
 }
 
-// attempt open, read, write, or close pmFPAfiles in files
+// attempt create, read, write, close, or free pmFPAfiles available in files
+// files are automatically opened before they are read
 bool pmFPAfileIOChecks (psMetadata *files, const pmFPAview *view, pmFPAfilePlace place)
 {
@@ -660,5 +712,7 @@
     PS_ASSERT_PTR_NON_NULL(view, false);
 
-    // recipe override values (command-line options):
+    bool status = true;
+
+    // attempt to perform all create, read, write
     psMetadataItem *item = NULL;
     psMetadataIterator *iter = psMetadataIteratorAlloc (files, PS_LIST_HEAD, NULL);
@@ -670,11 +724,9 @@
             if (!pmFPAfileRead (file, view)) {
                 psError(PS_ERR_IO, false, "failed READ in FPA_BEFORE block for %s", file->name);
-                psFree(iter);
-                return false;
+                status = false;
             }
             if (!pmFPAfileCreate(file, view)) {
                 psError(PS_ERR_IO, false, "failed CREATE in FPA_BEFORE block for %s", file->name);
-                psFree(iter);
-                return false;
+                status = false;
             }
             break;
@@ -682,11 +734,9 @@
             if (!pmFPAfileWrite (file, view)) {
                 psError(PS_ERR_IO, false, "failed WRITE in FPA_AFTER block for %s", file->name);
-                psFree(iter);
-                return false;
+                status = false;
             }
             if (!pmFPAfileClose(file, view)) {
                 psError(PS_ERR_IO, false, "failed CLOSE in FPA_AFTER block for %s", file->name);
-                psFree(iter);
-                return false;
+                status = false;
             }
             break;
@@ -695,7 +745,25 @@
         }
     }
+
+    // attempt to free data that is no longer needed
+    psMetadataIteratorSet (iter, PS_LIST_HEAD);
+    while ((item = psMetadataGetAndIncrement (iter)) != NULL) {
+        pmFPAfile *file = item->data.V;
+
+        switch (place) {
+        case PM_FPA_BEFORE:
+            break;
+        case PM_FPA_AFTER:
+            if (!pmFPAfileFreeData(file, view)) {
+                psError(PS_ERR_IO, false, "failed FREE in FPA_AFTER block for %s", file->name);
+                status = false;
+            }
+            break;
+        default:
+            psAbort(PS_FILE_LINE, "You can't get here");
+        }
+    }
     psFree (iter);
-
-    return true;
+    return status;
 }
 
@@ -810,4 +878,67 @@
         status = pmCellRead (cell, fits, NULL);
         return status;
+    }
+    psError(PS_ERR_UNKNOWN, true, "Returning false");
+    return false;
+
+    // XXX pmReadoutRead, pmReadoutReadSegement disabled for now
+    #if 0
+
+    if (view->readout >= cell->readouts->n) {
+        psError(PS_ERR_IO, true, "Requested readout == %d >= cell->readouts->n == %d",
+                view->readout, cell->readouts->n);
+        return false;
+    }
+    pmReadout *readout = cell->readouts->data[view->readout];
+
+    if (view->nRows == 0) {
+        pmReadoutRead (readout, fits, NULL);
+    } else {
+        pmReadoutReadSegment (readout, fits, view->nRows, view->iRows, NULL, NULL);
+    }
+    return true;
+    #endif
+}
+
+// given an already-opened fits file, read the components corresponding
+// to the specified view
+bool pmFPAviewFreeFitsImage (const pmFPAview *view, pmFPAfile *file)
+{
+    PS_ASSERT_PTR_NON_NULL(view, false);
+    PS_ASSERT_PTR_NON_NULL(file, false);
+
+    pmFPA *fpa = file->fpa;
+
+    if (view->chip == -1) {
+        psTrace ("pmFPAfile", 5, "freeing fpa for %s\n", file->filename);
+        psFree (fpa);
+        file->fpa = NULL;
+        return true;
+    }
+
+    if (view->chip >= fpa->chips->n) {
+        psError(PS_ERR_IO, true, "Requested chip == %d >= fpa->chips->n == %d", view->chip, fpa->chips->n);
+        return false;
+    }
+    pmChip *chip = fpa->chips->data[view->chip];
+
+    if (view->cell == -1) {
+        psTrace ("pmFPAfile", 5, "freeing chip %d for %s\n", view->chip, file->filename);
+        psFree (chip);
+        fpa->chips->data[view->chip] = NULL;
+        return true;
+    }
+
+    if (view->cell >= chip->cells->n) {
+        psError(PS_ERR_IO, true, "Requested cell == %d >= chip->cells->n == %d", view->cell, chip->cells->n);
+        return false;
+    }
+    pmCell *cell = chip->cells->data[view->cell];
+
+    if (view->readout == -1) {
+        psTrace ("pmFPAfile", 5, "freeing cell %d for %s\n", view->cell, file->filename);
+        psFree (cell);
+        chip->cells->data[view->cell] = NULL;
+        return true;
     }
     psError(PS_ERR_UNKNOWN, true, "Returning false");
@@ -1251,5 +1382,5 @@
 
         if (file->mode == mode) {
-            psMetadataAddStr (file->names, PS_LIST_TAIL, name, 0, "", value);
+            psMetadataAddStr (file->names, PS_LIST_TAIL, name, PS_META_NO_REPLACE, "", value);
         }
     }
Index: /trunk/psModules/src/camera/pmFPAfile.h
===================================================================
--- /trunk/psModules/src/camera/pmFPAfile.h	(revision 7479)
+++ /trunk/psModules/src/camera/pmFPAfile.h	(revision 7480)
@@ -7,6 +7,6 @@
 *  @author EAM, IfA
 *
-*  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2006-05-01 01:55:43 $
+*  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2006-06-10 03:01:29 $
 *
 *  Copyright 2004-2005 Institute for Astronomy, University of Hawaii
@@ -43,4 +43,5 @@
     PM_FPA_MODE_WRITE,
     PM_FPA_MODE_INTERNAL,
+    PM_FPA_MODE_REFERENCE,
 } pmFPAfileMode;
 
@@ -112,4 +113,7 @@
 bool pmFPAfileClose (pmFPAfile *file, const pmFPAview *view);
 
+// free the data at this level
+bool pmFPAfileFreeData(pmFPAfile *file, const pmFPAview *view);
+
 // set the state of the specified pmFPAfile to active (state == true) or inactive
 // if name is NULL, set the state for all pmFPAfiles
@@ -139,4 +143,7 @@
 bool pmFPAviewWriteFitsImage (const pmFPAview *view, pmFPAfile *file);
 
+// free the appropriate image containers
+bool pmFPAviewFreeFitsImage (const pmFPAview *view, pmFPAfile *file);
+
 // look for the given argname on the argument list.  find the give filename from the file rules
 pmFPAfile *pmFPAfileFromArgs (bool *found, pmConfig *config, char *filename, char *argname);
