Index: trunk/psModules/src/camera/pmFPARead.c
===================================================================
--- trunk/psModules/src/camera/pmFPARead.c	(revision 7017)
+++ trunk/psModules/src/camera/pmFPARead.c	(revision 7168)
@@ -5,5 +5,4 @@
 
 #include "pmFPA.h"
-#include "pmFPARead.h"
 #include "pmHDU.h"
 #include "pmHDUUtils.h"
@@ -11,4 +10,6 @@
 #include "psRegionIsBad.h"
 #include "pmFPAHeader.h"
+
+#include "pmFPARead.h"
 
 #define MAX(x,y) ((x) > (y) ? (x) : (y))
@@ -74,4 +75,61 @@
 }
 
+// Read a component of a readout
+psImage *readoutReadComponent(psFits *fits, // FITS file from which to read
+                              const psRegion *region, // Region to read
+                              int readdir, // Read direction (1=rows, 2=cols)
+                              int min,  // Minimum row/col number to read
+                              int max,   // Maximum row/col number to read
+                              int z,     // Image plane to read
+                              float bad // Bad value
+                             )
+{
+    bool resize = false;                // Do we need to resize the image once read?
+    psRegion toRead = psRegionSet(region->x0, region->x1, region->y0, region->y1); // Region to read
+    psRegion fullSize = toRead;         // Full sized region
+    if (readdir == 1) {
+        if (toRead.y0 <= min) {
+            toRead.y0 = min;
+        } else {
+            fullSize.y0 = min;
+            resize = true;
+        }
+        if (toRead.y1 >= max) {
+            toRead.y1 = max;
+        } else {
+            fullSize.y1 = max;
+            resize = false;
+        }
+    } else if (readdir == 2) {
+        if (toRead.x0 <= min) {
+            toRead.x0 = min;
+        } else {
+            fullSize.x0 = min;
+            resize = true;
+        }
+        if (toRead.x1 >= max) {
+            toRead.x1 = max;
+        } else {
+            fullSize.x1 = max;
+            resize = false;
+        }
+    } else {
+        psAbort(__func__, "Read direction can only be 1 (rows) or 2 (cols).\n");
+    }
+
+    psImage *image = psFitsReadImage(fits, toRead, z); // Desired pixels
+
+    if (resize) {
+        // For some reason, the region of interest is smaller than the number of pixels we want.
+        psImage *temp = psImageAlloc(fullSize.x1 - fullSize.x0, fullSize.y1 - fullSize.y0, image->type.type);
+        psImageInit(temp, bad);
+        psImageOverlaySection(temp, image, toRead.x0, toRead.y0, "=");
+        psFree(image);
+        image = temp;
+    }
+
+    return image;
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
 // Public functions
@@ -79,4 +137,7 @@
 
 // Read the next readout; return true if we read pixels in.
+//
+// Note that this doesn't put pixels in the HDU.  It is therefore NOT COMPATIBLE with pmCellWrite,
+// pmChipWrite, and pmFPAWrite.  Use pmReadoutWriteNext to write the data that's read by this function.
 bool pmReadoutReadNext(pmReadout *readout, // Readout into which to read
                        psFits *fits,    // FITS file from which to read
@@ -98,5 +159,6 @@
 
     // Make sure we have the information we need
-    pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER, false, NULL);
+    pmConceptsReadCell(cell, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS,
+                       false, NULL);
 
     // Get the trim and bias sections
@@ -113,7 +175,12 @@
     }
     int readdir = psMetadataLookupS32(&mdok, cell->concepts, "CELL.READDIR"); // Read direction
-    if (!mdok || readdir == 0 || (readdir != -1 && readdir != 1)) {
+    if (!mdok || readdir == 0 || (readdir != 1 && readdir != 2)) {
         psError(PS_ERR_IO, true, "CELL.READDIR is not set to -1 or +1.\n");
         return false;
+    }
+    float bad = psMetadataLookupF32(&mdok, cell->concepts, "CELL.BAD"); // Bad level
+    if (!mdok) {
+        psLogMsg(__func__, PS_LOG_WARN, "CELL.BAD is not set --- assuming zero.\n");
+        bad = 0.0;
     }
 
@@ -159,48 +226,44 @@
 
     // Read the FITS image
-    int offset = readout->row0;         // The row number to read
+    int offset = 0;                     // The offset from the start of the image to where we are now
     if (readout->image) {
-        if (readdir > 0) {
+        if (readdir == 1) {
             // Reading rows
-            offset += readout->image->numRows;
+            readout->row0 += readout->image->numRows;
+            offset = readout->row0;
         } else {
             // Reading columns
-            offset += readout->image->numCols;
-        }
-    }
-    if ((readdir > 0 && offset >= naxis2) || (readdir < 0 && offset > naxis1)) {
+            readout->col0 += readout->image->numCols;
+            offset = readout->col0;
+        }
+    }
+    if ((readdir == 1 && offset >= naxis2) || (readdir == 2 && offset > naxis1)) {
         // We've read everything there is
         return false;
     }
     int upper = offset + numScans;      // The upper limit for the pixel read
-    if (readdir > 0 && upper > naxis2) {
+    if (readdir == 1 && upper > naxis2) {
         upper = naxis2;
-    } else if (readdir < 0 && upper > naxis1) {
+    } else if (readdir == 2 && upper > naxis1) {
         upper = naxis1;
     }
-    psRegion region = {0, 0, 0, 0};     // Region to be read
-    if (readdir > 0) {
-        region = psRegionSet(0, naxis1, offset, upper); // Read rows
-    } else {
-        region = psRegionSet(offset, upper, 0, naxis2); // Read columns
-    }
-    psImage *image = psFitsReadImage(fits, region, z); // The image
-
-    // Stick the image into the HDU and the readout
-    if (!hdu->images) {
-        hdu->images = psArrayAlloc(naxis3);
-        hdu->images->n = naxis3;
-    }
-    if (hdu->images->nalloc != naxis3) {
-        hdu->images = psArrayRealloc(hdu->images, naxis3);
-        hdu->images->n = naxis3;
-    }
-    if (hdu->images->data[z]) {
-        psFree(hdu->images->data[z]);
-    }
-    hdu->images->data[z] = image;
-    readout->row0 = region.y0;
-    readout->col0 = region.x0;
-    readoutCarve(readout, image, trimsec, biassecs);
+
+    // Blow away existing data
+    psFree(readout->image);
+    while (readout->bias->n > 0) {
+        psListRemove(readout->bias, PS_LIST_HEAD);
+    }
+
+    // Get the new the trim section
+    readout->image = readoutReadComponent(fits, trimsec, readdir, offset, upper, z, bad); // The image
+
+    // Get the new bias sections
+    psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, false); // Iterator for BIASSEC
+    psRegion *biassec = NULL;           // Bias section from iteration
+    while ((biassec = psListGetAndIncrement(biassecsIter))) {
+        psImage *bias = readoutReadComponent(fits, biassec, readdir, offset, upper, z, bad); // The bias
+        psListAdd(readout->bias, PS_LIST_TAIL, bias);
+    }
+    psFree(biassecsIter);
 
     return true;
