Index: /trunk/psLib/src/image/psImageIO.c
===================================================================
--- /trunk/psLib/src/image/psImageIO.c	(revision 817)
+++ /trunk/psLib/src/image/psImageIO.c	(revision 817)
@@ -0,0 +1,335 @@
+/** @file  psImageIO.c
+ *
+ *  @brief Contains image I/O routines.
+ *
+ *  This file defines the file input/output functions for the psImage structure.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-05-29 01:42:44 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <fitsio.h>
+#include <unistd.h>
+#include "psImageIO.h"
+#include "psError.h"
+
+psImage* psImageReadSection(psImage* output, int col, int row, int numCols,
+                            int numRows, int z, char* extname, int extnum, char* filename)
+{
+    fitsfile    *fptr=NULL;                 /*Pointer to the FITS file*/
+    int         status=0;                   /*CFITSIO file vars*/
+    int         nAxis=0;
+    int         anynull=0;
+    int         bitPix=0;                   /*Pixel type*/
+    long        nAxes[3];
+    long        firstPixel[3];              /* lower-left corner of image subset */
+    long        lastPixel[3];               /* upper-right corner of image subset */
+    long        increment[3];               /* increment for image subset */
+    char        fitsErr[80] = "";           /*CFITSIO error message string */
+    int         hduType = IMAGE_HDU;
+
+    /* Open the FITS file */
+    (void)fits_open_file(&fptr, filename, READONLY, &status);
+    if (fptr == NULL || status != 0) {
+        fits_get_errstatus(status,fitsErr);
+        psError(__func__,"Could not open file '%s'. FITS error:%s",
+                filename, fitsErr);
+        psImageFree(output);
+        return NULL;
+    }
+
+    /* find the specified extension */
+    if (extname != NULL) {
+        if (fits_movnam_hdu(fptr, hduType, extname, 0,&status) != 0) {
+            fits_get_errstatus(status, fitsErr);
+            status = 0;
+            (void)fits_close_file(fptr, &status);
+            psError(__func__,"Could not index to '%s' HDU for file %s. FITSIO ERROR:%s",
+                    extname, filename, fitsErr);
+            psImageFree(output);
+            return NULL;
+        }
+    } else {
+        if (fits_movabs_hdu(fptr, extnum+1, &hduType, &status) != 0) {
+            fits_get_errstatus(status, fitsErr);
+            status = 0;
+            (void)fits_close_file(fptr, &status);
+            psError(__func__,"Could not index to HDU #%d for file %s. FITSIO ERROR:%s",
+                    extnum, filename, fitsErr);
+            psImageFree(output);
+            return NULL;
+        }
+    }
+
+    /* Get the data type 'bitPix' from the FITS image */
+    if (fits_get_img_type(fptr, &bitPix, &status) != 0) {
+        fits_get_errstatus(status, fitsErr);
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psError("Could not determine image data type of '%s'. FITSIO ERROR:%s",
+                filename, fitsErr);
+        psImageFree(output);
+        return NULL;
+    }
+
+    /* Get the dimensions 'nAxis' from the FITS image */
+    if (fits_get_img_dim(fptr, &nAxis, &status) != 0) {
+        (void)fits_get_errstatus(status, fitsErr);
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psError("Could not determine dimensions of '%s'. FITSIO Error: %s",
+                filename,fitsErr);
+        psImageFree(output);
+        return NULL;
+    }
+
+    /* Validate the number of axis */
+    if ( (nAxis < 2) || (nAxis > 3) ) {
+        status=0;
+        (void)fits_close_file(fptr, &status);
+        psError("Dimensions of '%s' are not supported (NAXIS=%i).",
+                filename, nAxis);
+        psImageFree(output);
+        return NULL;
+    }
+
+    /* Get the Image size from the FITS file  */
+    if ( fits_get_img_size(fptr, nAxis, nAxes, &status) != 0) {
+        (void)fits_get_errstatus(status, fitsErr);
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psError("Could not determine image size of '%s'. FITSIO Error:%s",
+                filename,fitsErr);
+        psImageFree(output);
+        return NULL;
+    }
+
+    if (numCols < 1) {
+        numCols += nAxes[0];
+    }
+    if (numRows < 1) {
+        numRows += nAxes[1];
+    }
+
+    firstPixel[0] = col+1;
+    firstPixel[1] = row+1;
+    firstPixel[2] = z+1;
+
+    lastPixel[0] = firstPixel[0] + numCols - 1;
+    lastPixel[1] = firstPixel[1] + numRows - 1;
+    lastPixel[2] = z+1;
+
+    increment[0] = 1;
+    increment[1] = 1;
+    increment[2] = 1;
+
+    // turn off the BSCALE/BZERO processing in CFITSIO
+    (void)fits_set_bscale(fptr, 1.0,0.0,&status);
+
+    switch (bitPix) {
+    case BYTE_IMG:
+        psImageRecycle(output,numCols,numRows,PS_TYPE_U8);
+        (void)fits_read_subset(fptr, TBYTE, firstPixel, lastPixel, increment,
+                               NULL, output->data.v, &anynull, &status);
+        break;
+    case SHORT_IMG:
+        psImageRecycle(output,numCols,numRows,PS_TYPE_S16);
+        (void)fits_read_subset(fptr, TSHORT, firstPixel, lastPixel, increment,
+                               NULL, output->data.v, &anynull, &status);
+        break;
+    case LONG_IMG:
+        psImageRecycle(output,numCols,numRows,PS_TYPE_S32);
+        (void)fits_read_subset(fptr, TINT, firstPixel, lastPixel, increment,
+                               NULL, output->data.v, &anynull, &status);
+        break;
+    case FLOAT_IMG:
+        psImageRecycle(output,numCols,numRows,PS_TYPE_F32);
+        (void)fits_read_subset(fptr, TFLOAT, firstPixel, lastPixel, increment,
+                               NULL, output->data.v, &anynull, &status);
+        break;
+    case DOUBLE_IMG:
+        psImageRecycle(output,numCols,numRows,PS_TYPE_F64);
+        (void)fits_read_subset(fptr, TDOUBLE, firstPixel, lastPixel, increment,
+                               NULL, output->data.v, &anynull, &status);
+        break;
+    default:
+        psError(__func__,"Unsupported bitpix value (%d) in FITS file %s.",
+                bitPix,filename);
+        psImageFree(output);
+        return NULL;
+    }
+
+    return output;
+}
+
+
+int psImageWriteSection(psImage* input, int col0,int row0,int z,
+                        char* extname, int extnum, char* filename)
+{
+    int         numCols = 0;
+    int         numRows = 0;
+
+    int         status=0;               /* CFITSIO  status */
+    fitsfile    *fptr=NULL;             /* pointer to the FITS file */
+    long        nAxes[3];               /* Image axis vars */
+    long        firstPixel[3];          /* First Pixel to read */
+    long        lastPixel[3];           /* Last Pixel to read */
+    char        fitsErr[80];            /* FITSIO message string */
+    int         datatype = 0;           /* the datatype of the image */
+    int         bitPix = 0;             /* FITS bitPix value */
+    int         hduType = IMAGE_HDU;    /* the HDU type (image,table, etc.) */
+    double      bscale = 1.0;
+    double      bzero = 0.0;
+
+    /* need a valid image to write */
+    if(input==NULL) {
+        psError(__func__, "Can not write %s.  Input psImage is NULL.",
+                filename);
+        return 1;
+    }
+
+    numRows = input->numRows;
+    numCols = input->numCols;
+
+    switch (input->type.type) {
+    case PS_TYPE_U8:
+        bitPix = BYTE_IMG;
+        datatype = TBYTE;
+        break;
+    case PS_TYPE_S8:
+        bitPix = BYTE_IMG;
+        bzero = -128.0;
+        datatype = TSBYTE;
+        break;
+    case PS_TYPE_U16:
+        bitPix = SHORT_IMG;
+        bzero = 32768.0;
+        datatype = TUSHORT;
+        break;
+    case PS_TYPE_S16:
+        bitPix = SHORT_IMG;
+        datatype = TSHORT;
+        break;
+    case PS_TYPE_U32:
+        bitPix = LONG_IMG;
+        bzero = 2147483648.0;
+        datatype = TULONG;
+        break;
+    case PS_TYPE_S32:
+        bitPix = LONG_IMG;
+        datatype = TLONG;
+        break;
+    case PS_TYPE_F32:
+        bitPix = FLOAT_IMG;
+        datatype = TFLOAT;
+        break;
+    case PS_TYPE_F64:
+        bitPix = DOUBLE_IMG;
+        datatype = TDOUBLE;
+        break;
+    default:
+        psError(__func__, "psImage datatype (%d) not supported.  File %s not written.",
+                input->type.type,filename);
+        return 1;
+    }
+
+    /* Open the FITS file */
+    if (access(filename, F_OK) == 0) { // file exists
+        (void)fits_open_file(&fptr, filename, READWRITE, &status);
+        if (fptr == NULL || status != 0) {
+            fits_get_errstatus(status,fitsErr);
+            psError(__func__,"Could not open file '%s'. FITS error:%s",
+                    filename, fitsErr);
+            return 2;
+        }
+
+        /* find the specified extension */
+        if (extname != NULL) {
+            if (fits_movnam_hdu(fptr, hduType, extname, 0,&status) != 0) {
+                fits_get_errstatus(status, fitsErr);
+                status = 0;
+                (void)fits_close_file(fptr, &status);
+                psError(__func__,"Could not index to '%s' HDU for file %s. FITSIO ERROR:%s",
+                        extname, filename, fitsErr);
+                return 3;
+            }
+        } else {
+            if (fits_movabs_hdu(fptr, extnum+1, &hduType, &status) != 0) {
+                fits_get_errstatus(status, fitsErr);
+                status = 0;
+                (void)fits_close_file(fptr, &status);
+                psError(__func__,"Could not index to HDU #%d for file %s. FITSIO ERROR:%s",
+                        extnum, filename, fitsErr);
+                return 3;
+            }
+        }
+
+    } else { // file does not exist
+
+        if (col0 != 0 || row0 != 0 || z != 0) {
+            psError(__func__,"File %s does not exist and a non-zero indexing (%d,%d,%d) was specified.",
+                    filename,col0,row0,z);
+            return 4;
+        }
+        (void)fits_create_file(&fptr,filename,&status);
+        if (fptr == NULL || status != 0) {
+            fits_get_errstatus(status,fitsErr);
+            psError(__func__,"Could not create file '%s'. FITS error:%s",
+                    filename, fitsErr);
+            return 5;
+        }
+
+        /*  create the mandatory image keywords */
+        nAxes[0] = numCols;
+        nAxes[1] = numRows;
+        if (fits_create_img(fptr, bitPix, 2, nAxes, &status) != 0) {
+            (void)fits_get_errstatus(status, fitsErr);
+            status = 0;
+            (void)fits_close_file(fptr, &status);
+            psError(__func__,"Could not create image HDU in FITS file '%s'. %s",
+                    filename, fitsErr);
+            return 5;
+        }
+
+        // set the bscale/bzero
+        fits_write_key_dbl(fptr, "BZERO",bzero,5,"Pixel Value Offset",&status);
+        fits_write_key_dbl(fptr, "BSCALE",bscale,5,"Pixel Value Scale",&status);
+        fits_set_bscale(fptr,bscale,bzero,&status);
+
+        if (extname != NULL) {
+            /* create the extension for the Primary HDU */
+            if (fits_write_key_str(fptr, "EXTNAME", extname, "Extension Name", &status) != 0) {
+                (void)fits_get_errstatus(status, fitsErr);
+                status = 0;
+                (void)fits_close_file(fptr, &status);
+                psError(__func__,"Could not create EXTNAME keyword in FITS file '%s'. %s",
+                        filename, fitsErr);
+                return 5;
+            }
+        }
+    }
+
+    firstPixel[0] = col0+1;
+    firstPixel[1] = row0+1;
+    firstPixel[2] = z+1;
+
+    lastPixel[0] = firstPixel[0] + numCols - 1;
+    lastPixel[1] = firstPixel[1] + numRows - 1;
+    lastPixel[2] = z+1;
+
+
+    if ( fits_write_subset(fptr, datatype, firstPixel, lastPixel, input->data.v, &status) != 0) {
+        (void)fits_get_errstatus(status, fitsErr);
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psError(__func__, "Could not write image data to '%s'. FITS Error: %s",
+                filename, fitsErr);
+        return 6;
+    }
+
+    return 0;
+}
Index: /trunk/psLib/src/image/psImageIO.h
===================================================================
--- /trunk/psLib/src/image/psImageIO.h	(revision 817)
+++ /trunk/psLib/src/image/psImageIO.h	(revision 817)
@@ -0,0 +1,74 @@
+/** @file  psImageIO.h
+ *
+ *  @brief Contains image input/output routines
+ *
+ *  This file defines the file input/output functions for the psImage structure.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-05-29 01:42:44 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+# ifndef PS_IMAGEIO_H
+# define PS_IMAGEIO_H
+
+#include "psImage.h"
+
+/** Read an image or subimage from a FITS file specified by a filename.
+ *
+ *  return psImage*         The image read from the specified file.  NULL
+ *                          signifies that a problem had occured.
+ */
+psImage* psImageReadSection(
+    psImage* output,
+    /**< the output psImage to recycle, or NULL if new psImage desired */
+    int col0,
+    /**< the column index of the origin to start reading */
+    int row0,
+    /**< the row index of the origin to start reading */
+    int numCols,
+    /**< the number of desired columns to read */
+    int numRows,
+    /**< the number of desired rows to read */
+    int z,
+    /**< the z index to read if file is organized as a 3D image cube. */
+    char* extname,
+    /**< the image extension to read (this should match the EXTNAME keyword in
+     *   the extension If NULL, the extnum parameter is to be used instead
+     */
+    int extnum,
+    /**< the image extension to read (0=PHU, 1=first extension, etc.)  This is
+     *   only used if extname is NULL
+     */
+    char* filename
+    /**< the filename of the FITS image file to read */
+);
+
+/** Read an image or subimage from a FITS file specified by a filename.
+ *
+ *  return psImage*         NULL if an error, otherwise same as input psImage
+ */
+int psImageWriteSection(
+    psImage* input,
+    /**< the psImage to write */
+    int col0,
+    /**< the column index of the origin to start writing */
+    int row0,
+    /**< the row index of the origin to start writing */
+    int z,
+    /**< the z index to start writing */
+    char* extname,
+    /**< the image extension to write (this should match the EXTNAME keyword in
+     *   the extension If NULL, the extnum parameter is to be used instead
+     */
+    int extnum,
+    /**< the image extension to write (0=PHU, 1=first extension, etc.)  This is
+     *   only used if extname is NULL.
+     */
+    char* filename
+    /**< the filename of the FITS image file to write */
+);
+
+#endif
