Index: trunk/psModules/src/camera/pmFPAfileFitsIO.c
===================================================================
--- trunk/psModules/src/camera/pmFPAfileFitsIO.c	(revision 10081)
+++ trunk/psModules/src/camera/pmFPAfileFitsIO.c	(revision 11255)
@@ -16,4 +16,78 @@
 #include "pmFPAfile.h"
 #include "pmFPAfileFitsIO.h"
+#include "pmFPACopy.h"
+
+pmFPA *pmFPAfileSuitableFPA(const pmFPAfile *file, const pmFPAview *view)
+{
+    PS_ASSERT_PTR_NON_NULL(file, NULL);
+    PS_ASSERT_PTR_NON_NULL(view, NULL);
+
+    if (!file->format) {
+        return psMemIncrRefCounter(file->fpa);
+    }
+
+    // Need to change format
+    pmFPA *fpa = pmFPAConstruct(file->camera);
+
+    pmFPAview *phuView = pmFPAviewAlloc(0); // View corresponding to the PHU
+    *phuView = *view;               // Copy contents
+    pmFPALevel phuLevel = pmFPAPHULevel(file->format); // Level for the PHU
+    switch (phuLevel) {
+    case PM_FPA_LEVEL_FPA:
+        phuView->chip = -1;
+        // Flow through
+    case PM_FPA_LEVEL_CHIP:
+        phuView->cell = -1;
+        // Flow through
+    case PM_FPA_LEVEL_CELL:
+        phuView->readout = -1;
+        break;
+    case PM_FPA_LEVEL_READOUT:
+    case PM_FPA_LEVEL_NONE:
+    default:
+        psAbort(PS_FILE_LINE, "Should never get here: bad phu level.\n");
+    }
+
+    if (!pmFPAAddSourceFromView(fpa, phuView, file->format)) {
+        psError(PS_ERR_UNKNOWN, false, "Unable to insert HDU into FPA for writing.\n");
+        psFree(fpa);
+        psFree(phuView);
+        return false;
+    }
+    psFree(phuView);
+
+
+    switch (phuLevel) {
+    case PM_FPA_LEVEL_FPA:
+        if (!pmFPACopy(fpa, file->fpa)) {
+            psError(PS_ERR_UNKNOWN, false, "Unable to copy FPA for format conversion.\n");
+            return NULL;
+        }
+        return fpa;
+    case PM_FPA_LEVEL_CHIP: {
+            pmChip *chip = pmFPAviewThisChip(view, fpa); // Chip of interest
+            pmChip *srcChip = pmFPAviewThisChip(view, file->fpa); // Source chip
+            if (!pmChipCopy(chip, srcChip)) {
+                psError(PS_ERR_UNKNOWN, false, "Unable to copy chip for format conversion.\n");
+                return false;
+            }
+            return fpa;
+        }
+    case PM_FPA_LEVEL_CELL: {
+            pmCell *cell = pmFPAviewThisCell(view, fpa); // Cell of interest
+            pmCell *srcCell = pmFPAviewThisCell(view, file->fpa); // Source cell
+            if (!pmCellCopy(cell, srcCell)) {
+                psError(PS_ERR_UNKNOWN, false, "Unable to copy cell for format conversion.\n");
+                return false;
+            }
+            return fpa;
+        }
+    case PM_FPA_LEVEL_READOUT:
+    case PM_FPA_LEVEL_NONE:
+    default:
+        psAbort(PS_FILE_LINE, "Should never get here: bad phu level.\n");
+    }
+    return NULL;
+}
 
 // given an already-opened fits file, read the table corresponding to the specified view
@@ -159,51 +233,53 @@
     assert(file);
 
-    pmFPA *fpa = file->fpa;             // FPA of interest
     psFits *fits = file->fits;          // FITS file
-
-    // pmFPAWrite takes care of all PHUs as needed
-    if (view->chip == -1) {
-        return fpaWriteFunc(fpa, fits, NULL, false, true);
-    }
-
-    if (view->chip >= fpa->chips->n) {
-        psError(PS_ERR_IO, true, "Requested chip == %d >= fpa->chips->n == %ld", view->chip, fpa->chips->n);
-        return false;
-    }
-    pmChip *chip = fpa->chips->data[view->chip]; // Chip of interest
-
-    if (view->cell == -1) {
-        return chipWriteFunc(chip, fits, NULL, false, true);
-    }
-
-    if (view->cell >= chip->cells->n) {
-        psError(PS_ERR_IO, true, "Requested cell == %d >= chip->cells->n == %ld", view->cell, chip->cells->n);
-        return false;
-    }
-    pmCell *cell = chip->cells->data[view->cell]; // Cell of interest
-
-    if (view->readout == -1) {
-        return cellWriteFunc(cell, fits, NULL, false);
-    }
-    psError(PS_ERR_UNKNOWN, true, "Bad view: %d,%d", view->chip, view->cell);
+    PS_ASSERT_PTR_NON_NULL(fits, false);
+
+    pmFPA *fpa = pmFPAfileSuitableFPA(file, view); // FPA to write
+
+    switch (pmFPAviewLevel(view)) {
+    case PM_FPA_LEVEL_FPA: {
+            bool success = fpaWriteFunc(fpa, fits, NULL, false, true);
+            psFree(fpa);
+            return success;
+        }
+    case PM_FPA_LEVEL_CHIP: {
+            pmChip *chip = pmFPAviewThisChip(view, fpa); // Chip of interest
+            bool success = chipWriteFunc(chip, fits, NULL, false, true);
+            psFree(fpa);
+            return success;
+        }
+    case PM_FPA_LEVEL_CELL: {
+            pmCell *cell = pmFPAviewThisCell(view, fpa); // Cell of interest
+            bool success = cellWriteFunc(cell, fits, NULL, false);
+            psFree(fpa);
+            return success;
+        }
+    case PM_FPA_LEVEL_READOUT:
+        #if 0 // XXX disable readout write for now
+
+        {
+            pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); // Readout of interest
+            if (changeFormat)
+        {
+            // No copy function defined for readouts!
+            psError(PS_ERR_UNKNOWN, false, "Unable to copy readout for format conversion on write.\n");
+                return false;
+            }
+            if (view->nRows == 0)
+        {
+            return pmReadoutWrite(readout, fits, NULL, NULL);
+            } else
+            {
+                return pmReadoutWriteSegment(readout, fits, view->nRows, view->iRows, NULL, NULL);
+            }
+        }
+        #endif
+    case PM_FPA_LEVEL_NONE:
+    default:
+        psAbort(PS_FILE_LINE, "Should never reach here: invalid file level.");
+    }
+
     return false;
-
-    // XXX disable readout write 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) {
-        pmReadoutWrite (readout, fits, NULL, NULL);
-    } else {
-        pmReadoutWriteSegment (readout, fits, view->nRows, view->iRows, NULL, NULL);
-    }
-    return true;
-    #endif
 }
 
