Index: trunk/psLib/src/image/psImage.c
===================================================================
--- trunk/psLib/src/image/psImage.c	(revision 664)
+++ 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);
+}
