Index: trunk/psLib/src/dataIO/psFits.c
===================================================================
--- trunk/psLib/src/dataIO/psFits.c	(revision 3025)
+++ trunk/psLib/src/dataIO/psFits.c	(revision 3028)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-01-17 20:58:21 $
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-01-18 03:15:03 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -19,4 +19,5 @@
 #include "psError.h"
 #include "psFileUtilsErrors.h"
+#include "psImageExtraction.h"
 #include "psMemory.h"
 #include "psString.h"
@@ -795,4 +796,11 @@
                             datatype);
 
+    if (output == NULL)
+    {
+        psError(PS_ERR_UNKNOWN, false,
+                "Failed to allocate a properly sized image.");
+        return false;
+    }
+
     // n.b., this assumes contiguous image buffer
     if (fits_read_subset(fits->p_fd, fitsDatatype, firstPixel, lastPixel, increment,
@@ -814,5 +822,6 @@
                       const psMetadata* header,
                       const psImage* input,
-                      int numZPlanes)
+                      int numZPlanes,
+                      char* extname)
 {
 
@@ -853,4 +862,8 @@
 
     fits_create_img(fits->p_fd, bitPix, naxis, naxes, &status);
+
+    if (extname != NULL) {
+        fits_update_key_str(fits->p_fd, "EXTNAME", (char*)extname, NULL, &status);
+    }
 
     if (bZero != 0) {        // set the bscale/bzero
@@ -896,4 +909,142 @@
     return true;
 
+}
+
+bool psFitsUpdateImage(psFits* fits,
+                       const psImage* input,
+                       psRegion region,
+                       int z)
+{
+    int status = 0;
+
+    if (fits == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_NULL);
+        return false;
+    }
+
+    if (input == NULL) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                PS_ERRORTEXT_psFits_IMAGE_NULL);
+        return false;
+    }
+
+    // check to see if we are positioned on an image HDU
+    int hdutype;
+    if ( fits_get_hdu_type(fits->p_fd,&hdutype, &status) != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_GET_HDU_TYPE_FAILED,
+                fitsErr);
+        return NULL;
+    }
+    if (hdutype != IMAGE_HDU) {
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_NOT_IMAGE_TYPE);
+        return NULL;
+    }
+
+    int numCols = input->numCols;
+    int numRows = input->numRows;
+
+    // determine the FITS-equivalent parameters
+    int bitPix;
+    double bZero;
+    int dataType;
+    if (! convertPsTypeToFits(input->type.type, &bitPix, &bZero, &dataType) ) {
+        return false;
+    }
+
+    //check to see if the HDU has the same datatype
+    int fileBitpix;
+    int naxis;
+    long nAxes[3];
+    nAxes[2] = 1;
+    fits_get_img_param(fits->p_fd, 3, &fileBitpix, &naxis, nAxes, &status);
+
+    //check to see if the HDU has the same datatype
+    if (bitPix != fileBitpix) {
+        char* fitsTypeStr;
+        char* imageTypeStr;
+        PS_TYPE_NAME(fitsTypeStr,fileBitpix);
+        PS_TYPE_NAME(imageTypeStr,input->type.type);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_IMAGE_UPDATE_TYPE_MISMATCH,
+                fitsTypeStr, imageTypeStr);
+        return false;
+    }
+
+    //check if the HDU has the z-plane requested
+    if (z >= nAxes[2]) {
+        psError(PS_ERR_BAD_PARAMETER_SIZE, true,
+                PS_ERRORTEXT_psFits_FITS_Z_SMALL,
+                nAxes[2],z);
+        return false;
+    }
+
+    // determine the region in the FITS file domain
+    long firstPixel[3];
+    long lastPixel[3];
+
+    firstPixel[0] = region.x0 + 1;
+    firstPixel[1] = region.y0 + 1;
+    firstPixel[2] = z + 1;
+
+    if (region.x1 > 0) {
+        lastPixel[0] = region.x1;
+    } else {
+        lastPixel[0] = nAxes[0] + region.x1; // n.b., region.x1 < 0
+    }
+    if (region.y1 > 0) {
+        lastPixel[1] = region.y1;
+    } else {
+        lastPixel[1] = nAxes[1] + region.y1; // n.b., region.y1 < 0
+    }
+    lastPixel[2] = z + 1;
+
+    if (firstPixel[0] < 1 || firstPixel[0] > nAxes[0] ||
+            firstPixel[1] < 1 || firstPixel[1] > nAxes[1] ||
+            lastPixel[0] < 1 || lastPixel[0] > nAxes[0] ||
+            lastPixel[1] < 1 || lastPixel[1] > nAxes[1]) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "Specified region [%d:%d,%d:%d], is not valid given the %dx%d FITS image.",
+                region.y0,region.y1-1,region.x0,region.x1-1);
+        return false;
+
+    }
+
+    int dx = lastPixel[0] - firstPixel[0];
+    int dy = lastPixel[1] - firstPixel[1];
+    if (dx > numCols ||
+            dy > numRows) {
+        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
+                "The region [%d:%d,%d:%d], is not valid given the input %dx%d image.",
+                firstPixel[1]-1,lastPixel[1]-1,
+                firstPixel[0]-1,lastPixel[0]-1,
+                numCols, numRows);
+        return false;
+    }
+
+    psImage* subset;
+    if (dx != numCols || dy != numRows) {
+        // the input image needs to be subsetted
+        subset = psImageSubset((psImage*)input,0,0,dx+1,dy+1);
+    } else {
+        subset = psMemIncrRefCounter((psImage*)input);
+    }
+
+    fits_write_subset(fits->p_fd, dataType, firstPixel, lastPixel, subset->data.V[0], &status);
+
+    if ( status != 0) {
+        char fitsErr[MAX_STRING_LENGTH];
+        (void)fits_get_errstatus(status, fitsErr);
+        psError(PS_ERR_IO, true,
+                PS_ERRORTEXT_psFits_WRITE_FAILED,
+                fits->filename, fitsErr);
+        return false;
+    }
+
+    return true;
 }
 
