Index: /trunk/psLib/src/image/psImage.c
===================================================================
--- /trunk/psLib/src/image/psImage.c	(revision 691)
+++ /trunk/psLib/src/image/psImage.c	(revision 692)
@@ -7,6 +7,6 @@
  *  @author Ross Harman, MHPCC
  *   
- *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-05-13 20:03:35 $
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-05-14 22:39:58 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -18,36 +18,7 @@
 #include "psMemory.h"
 #include "psError.h"
-#include "psVector.h"
 #include "psImage.h"
 
-/******************************************************************************/
-/*  DEFINE STATEMENTS                                                         */
-/******************************************************************************/
-
-// None
-
-/******************************************************************************/
-/*  TYPE DEFINITIONS                                                          */
-/******************************************************************************/
-
-// None
-
-/*****************************************************************************/
-/*  GLOBAL VARIABLES                                                         */
-/*****************************************************************************/
-
-// None
-
-/*****************************************************************************/
-/*  FILE STATIC VARIABLES                                                    */
-/*****************************************************************************/
-
-// None
-
-/*****************************************************************************/
-/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
-/*****************************************************************************/
-
-// None
+#include <string.h>
 
 /*****************************************************************************/
@@ -55,39 +26,30 @@
 /*****************************************************************************/
 
-psImage *psImageAlloc(unsigned int numCols, unsigned int numRows, psType type)
+psImage *psImageAlloc(unsigned int numCols, unsigned int numRows, const psElemType type)
 {
     int area = 0;
-    psElemType imageType = 0;
-    psDimen imageDim = 0;
-    int elementSize = PSELEMTYPE_SIZEOF(type.type); // element size in bytes
+    int elementSize = PSELEMTYPE_SIZEOF(type); // element size in bytes
     int rowSize = numCols*elementSize;  // row size in bytes.
 
-    imageType = type.type;
-    imageDim =  type.dimen;
     area = numCols*numRows;
-
-    if(imageDim != PS_DIMEN_IMAGE) {
-        psError(__func__, " : Image dimensionality not PS_DIMEN_IMAGE (3). Dimensionality: %d\n",
-                imageDim);
-        return NULL;
-    } else if(area <= 0) {
-        psError(__func__, " : Invalid value for number of rows or columns. numRows: %d numCols: %d\n",
-                numRows, numCols);
-        return NULL;
-    }
 
     psImage *image = (psImage *)psAlloc(sizeof(psImage));
 
-    image->data.v[0] = psAlloc(area*elementSize);
+    if(area < 1) {
+        image->data.v[0] = NULL;
+    } else {
+        image->data.v[0] = psAlloc(area*elementSize);
 
-    for(int i = 1; i < numRows; i++) {
-        image->data.v[i] = (void*)((int8_t*)image->data.v[i-1]+rowSize);
+        for(int i = 1; i < numRows; i++) {
+            image->data.v[i] = (void*)((int8_t*)image->data.v[i-1]+rowSize);
+        }
     }
 
-    image->col0 = 0;
-    image->row0 = 0;
-    image->numCols = numCols;
-    image->numRows = numRows;
-    image->type = type;
+    *(int*)&image->col0 = 0;
+    *(int*)&image->row0 = 0;
+    *(unsigned int*)&image->numCols = numCols;
+    *(unsigned int*)&image->numRows = numRows;
+    *(psDimen*)&image->type.dimen = PS_DIMEN_IMAGE;
+    *(psElemType*)&image->type.type = type;
     image->parent = NULL;
     image->nChildren = 0;
@@ -101,18 +63,74 @@
     int i = 0;
     int nChildren = 0;
-    psElemType imageType = 0;
-    psImage *children = NULL;
+    psImage **children = NULL;
 
     if(image != NULL) {
-        imageType = image->type.type;
         nChildren = image->nChildren;
         children = image->children;
+
+        for(i=0; i<nChildren; i++) {
+            psImageFree(children[i]);
+        }
 
         psFree(image->data.v[0]);
         psFree(image->data.v);
 
-        for(i=0; i<nChildren; i++) {
-            psImageFree(&children[i]);
-        }
     }
 }
+
+psImage *psImageSubset(psImage *out,psImage *image,unsigned int numCols,
+                       unsigned int numRows, unsigned int col0, unsigned int row0)
+{
+    psElemType type;
+    unsigned int elementSize;           // size of image element in bytes
+    unsigned int outputRowSize;         // output row size in bytes
+    unsigned int inputColOffset;        // offset in bytes to first subset pixel in input row
+
+    if (image == NULL) {
+        psError(__func__,"Can not subset image because input image is NULL.");
+        return NULL;
+    }
+
+    if (image->type.dimen != PS_DIMEN_IMAGE) {
+        psError(__func__,"Can not subset image because input image is not an image.");
+        return NULL;
+    }
+
+    /* validate subimage size */
+    if (col0+numCols >= image->numCols || row0+numRows >= image->numRows) {
+        psError(__func__,"Can not subset image outside of image boundaries (size=%dx%d, "
+                "subset=[%d:%d,%d:%d]).",image->numCols,image->numRows,image->col0,
+                image->col0+numCols, image->row0, image->row0+numRows);
+        return NULL;
+    }
+
+    type = image->type.type;
+    elementSize = PSELEMTYPE_SIZEOF(type);
+
+    if (out == NULL) {
+        out = psImageAlloc(numCols,numRows,image->type.type);
+    } else if (out->numCols != numCols || out->numRows != numRows || out->type.type != type) {
+        // sizes/type different, can't reuse the given image buffer
+        psImageFree(out);
+        out = psImageAlloc(numCols,numRows,image->type.type);
+    }
+
+    // set the parent information into the child output image
+    *(int*)&out->row0 = row0;
+    *(int*)&out->col0 = col0;
+    *(psImage**)&out->parent = (psImage*)image;
+
+    // add output image as a child of the input image.
+    image->nChildren++;
+    image->children = (psImage **) psRealloc(image->children,image->nChildren*sizeof(psImage *));
+    image->children[image->nChildren-1] = out;
+
+    inputColOffset = elementSize*col0;
+    outputRowSize = elementSize*numCols;
+
+    for (int row = 0; row < numRows; row++) {
+        memcpy(out->data.v[row],image->data.i8[row0+row] + inputColOffset,outputRowSize);
+    }
+
+    return (out);
+}
Index: /trunk/psLib/src/image/psImage.h
===================================================================
--- /trunk/psLib/src/image/psImage.h	(revision 691)
+++ /trunk/psLib/src/image/psImage.h	(revision 692)
@@ -7,6 +7,6 @@
  *  @author Ross Harman, MHPCC
  *   
- *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-05-13 20:03:35 $
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-05-14 22:39:58 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -16,4 +16,6 @@
 
 #include <complex.h>
+
+#include "psType.h"
 
 /******************************************************************************/
@@ -35,21 +37,25 @@
 typedef struct psImage
 {
-    psType type;                        ///< Image data type and dimension.
-    unsigned int numCols;               ///< Number of rows in image
-    unsigned int numRows;               ///< Number of columns in image.
-    int col0;                           ///< Row position relative to parent.
-    int row0;                           ///< Column position relative to parent.
+    const psType type;                  ///< Image data type and dimension.
+    const unsigned int numCols;         ///< Number of columns in image
+    const unsigned int numRows;         ///< Number of rows in image.
+    const int col0;                     ///< Column position relative to parent.
+    const int row0;                     ///< Row position relative to parent.
 
     union {
-        void    **v;                    ///< void pointer to data
-        uint8_t **ui8;                  ///< Pointers to char integer data.
-        int16_t **i16;                  ///< Pointers to short integer data.
-        int32_t **i32;                  ///< Pointers to integer data.
-        float **f32;                    ///< Pointers to floating point data.
-        complex float **c32;            ///< Pointers to complex floating point data.
+        uint8_t **ui8;                  ///< unsigned 8-bit integer data.
+        uint16_t **ui16;                ///< unsigned 16-bit integer data.
+        uint32_t **ui32;                ///< unsigned 32-bit integer data.
+        int8_t **i8;                    ///< signed 8-bit integer data.
+        int16_t **i16;                  ///< signed 16-bit integer data.
+        int32_t **i32;                  ///< signed 32-bit integer data.
+        float **f32;                    ///< single-precision float data.
+        double **f64;                   ///< double-precision float data.
+        complex float **c32;            ///< single-precision complex data.
+        void    **v;                    ///< void pointers to data
     } data;                             ///< Union for data types.
-    struct psImage *parent;             ///< Parent, if a subimage.
+    const struct psImage *parent;       ///< Parent, if a subimage.
     int nChildren;                      ///< Number of subimages.
-    struct psImage *children;           ///< Children of this region.
+    struct psImage** children;          ///< Children of this region.
 }
 psImage;
@@ -70,5 +76,5 @@
     unsigned int numCols,               ///< Number of rows in image.
     unsigned int numRows,               ///< Number of columns in image.
-    psType type                         ///< Type of data for image.
+    const psElemType type               ///< Type of data for image.
 );
 
@@ -82,9 +88,9 @@
 psImage *psImageSubset(
     psImage *out,                       ///< Subimage to return, or NULL.
-    const psImage *image,               ///< Parent image.
+    psImage *image,                     ///< Parent image.
     unsigned int numCols,               ///< Subimage width (<= image.nCols - col0).
     unsigned int numRows,               ///< Subimage height (<= image.nRows - row0).
-    int col0,                           ///< Subimage col-offset (0 <= col0 < nCol).
-    int row0                            ///< Subimage row-offset (0 <= row0 < nCol).
+    unsigned int col0,                  ///< Subimage col-offset (0 <= col0 < nCol).
+    unsigned int row0                   ///< Subimage row-offset (0 <= row0 < nCol).
 );
 
Index: /trunk/psLib/src/mathtypes/psImage.c
===================================================================
--- /trunk/psLib/src/mathtypes/psImage.c	(revision 691)
+++ /trunk/psLib/src/mathtypes/psImage.c	(revision 692)
@@ -7,6 +7,6 @@
  *  @author Ross Harman, MHPCC
  *   
- *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-05-13 20:03:35 $
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-05-14 22:39:58 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -18,36 +18,7 @@
 #include "psMemory.h"
 #include "psError.h"
-#include "psVector.h"
 #include "psImage.h"
 
-/******************************************************************************/
-/*  DEFINE STATEMENTS                                                         */
-/******************************************************************************/
-
-// None
-
-/******************************************************************************/
-/*  TYPE DEFINITIONS                                                          */
-/******************************************************************************/
-
-// None
-
-/*****************************************************************************/
-/*  GLOBAL VARIABLES                                                         */
-/*****************************************************************************/
-
-// None
-
-/*****************************************************************************/
-/*  FILE STATIC VARIABLES                                                    */
-/*****************************************************************************/
-
-// None
-
-/*****************************************************************************/
-/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
-/*****************************************************************************/
-
-// None
+#include <string.h>
 
 /*****************************************************************************/
@@ -55,39 +26,30 @@
 /*****************************************************************************/
 
-psImage *psImageAlloc(unsigned int numCols, unsigned int numRows, psType type)
+psImage *psImageAlloc(unsigned int numCols, unsigned int numRows, const psElemType type)
 {
     int area = 0;
-    psElemType imageType = 0;
-    psDimen imageDim = 0;
-    int elementSize = PSELEMTYPE_SIZEOF(type.type); // element size in bytes
+    int elementSize = PSELEMTYPE_SIZEOF(type); // element size in bytes
     int rowSize = numCols*elementSize;  // row size in bytes.
 
-    imageType = type.type;
-    imageDim =  type.dimen;
     area = numCols*numRows;
-
-    if(imageDim != PS_DIMEN_IMAGE) {
-        psError(__func__, " : Image dimensionality not PS_DIMEN_IMAGE (3). Dimensionality: %d\n",
-                imageDim);
-        return NULL;
-    } else if(area <= 0) {
-        psError(__func__, " : Invalid value for number of rows or columns. numRows: %d numCols: %d\n",
-                numRows, numCols);
-        return NULL;
-    }
 
     psImage *image = (psImage *)psAlloc(sizeof(psImage));
 
-    image->data.v[0] = psAlloc(area*elementSize);
+    if(area < 1) {
+        image->data.v[0] = NULL;
+    } else {
+        image->data.v[0] = psAlloc(area*elementSize);
 
-    for(int i = 1; i < numRows; i++) {
-        image->data.v[i] = (void*)((int8_t*)image->data.v[i-1]+rowSize);
+        for(int i = 1; i < numRows; i++) {
+            image->data.v[i] = (void*)((int8_t*)image->data.v[i-1]+rowSize);
+        }
     }
 
-    image->col0 = 0;
-    image->row0 = 0;
-    image->numCols = numCols;
-    image->numRows = numRows;
-    image->type = type;
+    *(int*)&image->col0 = 0;
+    *(int*)&image->row0 = 0;
+    *(unsigned int*)&image->numCols = numCols;
+    *(unsigned int*)&image->numRows = numRows;
+    *(psDimen*)&image->type.dimen = PS_DIMEN_IMAGE;
+    *(psElemType*)&image->type.type = type;
     image->parent = NULL;
     image->nChildren = 0;
@@ -101,18 +63,74 @@
     int i = 0;
     int nChildren = 0;
-    psElemType imageType = 0;
-    psImage *children = NULL;
+    psImage **children = NULL;
 
     if(image != NULL) {
-        imageType = image->type.type;
         nChildren = image->nChildren;
         children = image->children;
+
+        for(i=0; i<nChildren; i++) {
+            psImageFree(children[i]);
+        }
 
         psFree(image->data.v[0]);
         psFree(image->data.v);
 
-        for(i=0; i<nChildren; i++) {
-            psImageFree(&children[i]);
-        }
     }
 }
+
+psImage *psImageSubset(psImage *out,psImage *image,unsigned int numCols,
+                       unsigned int numRows, unsigned int col0, unsigned int row0)
+{
+    psElemType type;
+    unsigned int elementSize;           // size of image element in bytes
+    unsigned int outputRowSize;         // output row size in bytes
+    unsigned int inputColOffset;        // offset in bytes to first subset pixel in input row
+
+    if (image == NULL) {
+        psError(__func__,"Can not subset image because input image is NULL.");
+        return NULL;
+    }
+
+    if (image->type.dimen != PS_DIMEN_IMAGE) {
+        psError(__func__,"Can not subset image because input image is not an image.");
+        return NULL;
+    }
+
+    /* validate subimage size */
+    if (col0+numCols >= image->numCols || row0+numRows >= image->numRows) {
+        psError(__func__,"Can not subset image outside of image boundaries (size=%dx%d, "
+                "subset=[%d:%d,%d:%d]).",image->numCols,image->numRows,image->col0,
+                image->col0+numCols, image->row0, image->row0+numRows);
+        return NULL;
+    }
+
+    type = image->type.type;
+    elementSize = PSELEMTYPE_SIZEOF(type);
+
+    if (out == NULL) {
+        out = psImageAlloc(numCols,numRows,image->type.type);
+    } else if (out->numCols != numCols || out->numRows != numRows || out->type.type != type) {
+        // sizes/type different, can't reuse the given image buffer
+        psImageFree(out);
+        out = psImageAlloc(numCols,numRows,image->type.type);
+    }
+
+    // set the parent information into the child output image
+    *(int*)&out->row0 = row0;
+    *(int*)&out->col0 = col0;
+    *(psImage**)&out->parent = (psImage*)image;
+
+    // add output image as a child of the input image.
+    image->nChildren++;
+    image->children = (psImage **) psRealloc(image->children,image->nChildren*sizeof(psImage *));
+    image->children[image->nChildren-1] = out;
+
+    inputColOffset = elementSize*col0;
+    outputRowSize = elementSize*numCols;
+
+    for (int row = 0; row < numRows; row++) {
+        memcpy(out->data.v[row],image->data.i8[row0+row] + inputColOffset,outputRowSize);
+    }
+
+    return (out);
+}
Index: /trunk/psLib/src/mathtypes/psImage.h
===================================================================
--- /trunk/psLib/src/mathtypes/psImage.h	(revision 691)
+++ /trunk/psLib/src/mathtypes/psImage.h	(revision 692)
@@ -7,6 +7,6 @@
  *  @author Ross Harman, MHPCC
  *   
- *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-05-13 20:03:35 $
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-05-14 22:39:58 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -16,4 +16,6 @@
 
 #include <complex.h>
+
+#include "psType.h"
 
 /******************************************************************************/
@@ -35,21 +37,25 @@
 typedef struct psImage
 {
-    psType type;                        ///< Image data type and dimension.
-    unsigned int numCols;               ///< Number of rows in image
-    unsigned int numRows;               ///< Number of columns in image.
-    int col0;                           ///< Row position relative to parent.
-    int row0;                           ///< Column position relative to parent.
+    const psType type;                  ///< Image data type and dimension.
+    const unsigned int numCols;         ///< Number of columns in image
+    const unsigned int numRows;         ///< Number of rows in image.
+    const int col0;                     ///< Column position relative to parent.
+    const int row0;                     ///< Row position relative to parent.
 
     union {
-        void    **v;                    ///< void pointer to data
-        uint8_t **ui8;                  ///< Pointers to char integer data.
-        int16_t **i16;                  ///< Pointers to short integer data.
-        int32_t **i32;                  ///< Pointers to integer data.
-        float **f32;                    ///< Pointers to floating point data.
-        complex float **c32;            ///< Pointers to complex floating point data.
+        uint8_t **ui8;                  ///< unsigned 8-bit integer data.
+        uint16_t **ui16;                ///< unsigned 16-bit integer data.
+        uint32_t **ui32;                ///< unsigned 32-bit integer data.
+        int8_t **i8;                    ///< signed 8-bit integer data.
+        int16_t **i16;                  ///< signed 16-bit integer data.
+        int32_t **i32;                  ///< signed 32-bit integer data.
+        float **f32;                    ///< single-precision float data.
+        double **f64;                   ///< double-precision float data.
+        complex float **c32;            ///< single-precision complex data.
+        void    **v;                    ///< void pointers to data
     } data;                             ///< Union for data types.
-    struct psImage *parent;             ///< Parent, if a subimage.
+    const struct psImage *parent;       ///< Parent, if a subimage.
     int nChildren;                      ///< Number of subimages.
-    struct psImage *children;           ///< Children of this region.
+    struct psImage** children;          ///< Children of this region.
 }
 psImage;
@@ -70,5 +76,5 @@
     unsigned int numCols,               ///< Number of rows in image.
     unsigned int numRows,               ///< Number of columns in image.
-    psType type                         ///< Type of data for image.
+    const psElemType type               ///< Type of data for image.
 );
 
@@ -82,9 +88,9 @@
 psImage *psImageSubset(
     psImage *out,                       ///< Subimage to return, or NULL.
-    const psImage *image,               ///< Parent image.
+    psImage *image,                     ///< Parent image.
     unsigned int numCols,               ///< Subimage width (<= image.nCols - col0).
     unsigned int numRows,               ///< Subimage height (<= image.nRows - row0).
-    int col0,                           ///< Subimage col-offset (0 <= col0 < nCol).
-    int row0                            ///< Subimage row-offset (0 <= row0 < nCol).
+    unsigned int col0,                  ///< Subimage col-offset (0 <= col0 < nCol).
+    unsigned int row0                   ///< Subimage row-offset (0 <= row0 < nCol).
 );
 
