Index: trunk/psLib/src/image/psImage.c
===================================================================
--- trunk/psLib/src/image/psImage.c	(revision 1918)
+++ trunk/psLib/src/image/psImage.c	(revision 1920)
@@ -10,6 +10,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.46 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-09-25 02:06:12 $
+ *  @version $Revision: 1.47 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-28 23:26:48 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -68,5 +68,4 @@
     *(psElemType* ) & image->type.type = type;
     image->parent = NULL;
-    image->nChildren = 0;
     image->children = NULL;
 
@@ -81,6 +80,5 @@
 
     if (image->type.type == PS_TYPE_PTR) {
-        // 2-D array of pointers -- must
-        // dereference
+        // 2-D array of pointers -- must dereference elements
         unsigned int oldNumRows = image->numRows;
         unsigned int oldNumCols = image->numCols;
@@ -95,9 +93,13 @@
     }
 
+    if (image->parent != NULL) {
+        psArrayRemove(image->parent->children,image);
+        image->parent = NULL;
+    }
+
     psImageFreeChildren(image);
 
     psFree(image->rawDataBuffer);
     psFree(image->data.V);
-    image->data.V = NULL;
 }
 
@@ -164,7 +166,4 @@
 int psImageFreeChildren(psImage* image)
 {
-    int i = 0;
-    int nChildren = 0;
-    psImage* *children = NULL;
     int numFreed = 0;
 
@@ -173,17 +172,17 @@
     }
 
-    nChildren = image->nChildren;
-    children = image->children;
-
-    for (i = 0; i < nChildren; i++) {
-        if (children[i] != NULL) {
-            numFreed++;
-            psFree(children[i]);
+    if (image->children != NULL) {
+        psImage** children = (psImage**)image->children->data;
+        numFreed = image->children->n;
+
+        // orphan the children first
+        // (so psFree doesn't try to modify the parent's children array while I'm using it)
+        for (int i=0;i<numFreed;i++) {
+            children[i]->parent = NULL;
         }
-    }
-    psFree(children);
-
-    image->nChildren = 0;
-    image->children = NULL;
+
+        psFree(image->children);
+        image->children = NULL;
+    }
 
     return numFreed;
Index: trunk/psLib/src/image/psImage.h
===================================================================
--- trunk/psLib/src/image/psImage.h	(revision 1918)
+++ trunk/psLib/src/image/psImage.h	(revision 1920)
@@ -11,6 +11,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.37 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-09-25 02:06:12 $
+ *  @version $Revision: 1.38 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-28 23:26:48 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -22,4 +22,5 @@
 
 #include "psType.h"
+#include "psArray.h"
 
 /// @addtogroup Image
@@ -67,6 +68,5 @@
     } data;                            ///< Union for data types.
     const struct psImage* parent;      ///< Parent, if a subimage.
-    int nChildren;                     ///< Number of subimages.
-    struct psImage* *children;         ///< Children of this region.
+    psArray* children;                 ///< Children of this region.
 
     void* rawDataBuffer;
Index: trunk/psLib/src/image/psImageExtraction.c
===================================================================
--- trunk/psLib/src/image/psImageExtraction.c	(revision 1918)
+++ trunk/psLib/src/image/psImageExtraction.c	(revision 1920)
@@ -1,19 +1,18 @@
-
 /** @file  psImageExtraction.c
-*
-*  @brief Contains basic image extraction operations, as specified in the 
-*         PSLIB SDRS sections "Image Pixel Extractions" and "Image Structure
-*         Manipulation".
-*
-*  @ingroup Image
-*
-*  @author Robert DeSonia, MHPCC
-*
-*  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2004-09-28 02:27:58 $
-*
-*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
-*
-*/
+ *
+ *  @brief Contains basic image extraction operations, as specified in the 
+ *         PSLIB SDRS sections "Image Pixel Extractions" and "Image Structure
+ *         Manipulation".
+ *
+ *  @ingroup Image
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-28 23:26:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
 
 #include <string.h>
@@ -25,11 +24,12 @@
 #include "psImageErrors.h"
 
-psImage* psImageSubset(psImage* image,
-                       int col0,
-                       int row0,
-                       int col1,
-                       int row1)
+
+psImage* imageSubset(psImage* out,
+                     psImage* image,
+                     int col0,
+                     int row0,
+                     int col1,
+                     int row1)
 {
-    psImage* out;
     unsigned int elementSize;          // size of image element in bytes
     unsigned int inputColOffset;       // offset in bytes to first subset pixel in input row
@@ -70,9 +70,33 @@
     }
     int numRows = row1-row0;
-    int numCols = col1-row0;
+    int numCols = col1-col0;
 
     elementSize = PSELEMTYPE_SIZEOF(image->type.type);
 
-    out = psAlloc(sizeof(psImage));
+    if (image->parent != NULL) { // if this is a child, we need to start working with parent.
+        col0 += image->col0;
+        col1 += image->col0;
+        row0 += image->row0;
+        row1 += image->row0;
+        image = (psImage*)image->parent;
+    }
+
+    // increment the raw data buffer before freeing anything in the 'out'
+    void* rawData = psMemIncrRefCounter(image->rawDataBuffer);
+
+    if (out != NULL) {
+        // if a child, need to orphan (disassociate from parent) first
+        if (out->parent != NULL) {
+            psArrayRemove(out->parent->children,out); // remove from parent's knowledge
+            out->parent = NULL; // break link to parent
+        }
+
+        psFree(out->rawDataBuffer); // free the previous data reference
+    } else {
+        out = psAlloc(sizeof(psImage));
+        out->data.V = NULL;
+    }
+
+    out->data.V = psRealloc(out->data.V,sizeof(void*)*numRows); // resize row pointer array
     *(psType*)&out->type = image->type;
     *(unsigned int*)&out->numCols = numCols;
@@ -81,8 +105,6 @@
     *(int*)&out->col0 = col0;
     out->parent = image;
-    out->nChildren = 0;
     out->children = NULL;
-    out->rawDataBuffer = psMemIncrRefCounter(image->rawDataBuffer);
-    out->data.V = psAlloc(sizeof(void*)*numRows);
+    out->rawDataBuffer = rawData;
 
     // set the new psImage's deallocator to the same as the input image
@@ -94,11 +116,29 @@
     }
 
-    // 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;
+    // add output image as a child of the input image.
+    int n = 0;
+    psArray* children = image->children;
+    if (children == NULL) {
+        children = psArrayAlloc(16); // start with a reasonable size for growth
+    } else if (children->nalloc == children->n) { // full?
+        n = children->n;
+        children = psArrayRealloc(children,n*2); // double the array size
+    } else {
+        n = children->n;
+    }
+    children->data[n] = out;
+    children->n = n+1;
+    image->children = children; // push back any change (esp. if children==NULL before)
 
     return (out);
+}
+
+psImage* psImageSubset(psImage* image,
+                       int col0,
+                       int row0,
+                       int col1,
+                       int row1)
+{
+    return imageSubset(NULL,image,col0,row0,col1,row1);
 }
 
@@ -126,8 +166,8 @@
         return NULL;
     }
-    return psImageSubset(image,x1,y1,x2,y2);
+    return imageSubset(NULL,image,x1,y1,x2,y2);
 }
 
-psImage* psImageTrim(psImage* image, int x0, int x1, int y0, int y1)
+psImage* psImageTrim(psImage* image, int x0, int y0, int x1, int y1)
 {
     if (image == NULL || image->data.V == NULL) {
@@ -139,8 +179,10 @@
 
     if (image->parent != NULL) {
-        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageTrim",
-                   PS_ERR_BAD_PARAMETER_NULL, true,
-                   PS_ERRORTEXT_psImage_NOT_PARENT);
-        return NULL;
+        return imageSubset(image,
+                           (psImage*)image->parent,
+                           x0+image->col0,
+                           y0+image->row0,
+                           x1+image->col0,
+                           y1+image->row0);
     }
 
@@ -904,7 +946,7 @@
                     int n = buffer[r]->n;
                     if (n == buffer[r]->nalloc) { // in case buffers already full, expand
-                        buffer[r] = psVectorRealloc(n*2, buffer[r]);
+                        buffer[r] = psVectorRealloc(buffer[r], n*2);
                         if (bufferMask[r] != NULL) {
-                            bufferMask[r] = psVectorRealloc(n*2, bufferMask[r]);
+                            bufferMask[r] = psVectorRealloc(bufferMask[r], n*2);
                         }
                     }
Index: trunk/psLib/src/image/psImageExtraction.h
===================================================================
--- trunk/psLib/src/image/psImageExtraction.h	(revision 1918)
+++ trunk/psLib/src/image/psImageExtraction.h	(revision 1920)
@@ -10,6 +10,6 @@
 *  @author Robert DeSonia, MHPCC
 *
-*  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2004-09-28 02:27:58 $
+*  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-09-28 23:26:48 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -76,9 +76,15 @@
  *
  *  Trim the specified image in-place, which involves shuffling the pixels 
- *  around in memory.  The pixels in the region [x0:x1,y0:y1] (inclusive)
- *  shall consist the output image.
- *
- *  N.b., An image that has a parent image will be orphaned from the parent 
- *  upon trimming.  Any children of the trimmed image will also be obliterated, 
+ *  around in memory.  The pixels in the region [col0:col1,row0:row1] shall consist
+ *  the output image.  The column col1 and row row1 are NOT included in the range.
+ *  In the event that x1 or y1 are non-positive, they shall be interpreted as
+ *  being relative to the size of the parent image in that dimension.
+ *
+ *  If the entire specified subimage is not contained within the parent 
+ *  image, an error results and the return value will be NULL.
+ *
+ *  N.B. If the input psImage is a child of another psImage, no pixel data 
+ *  will be trimmed, rather it equivalent to calling psImageSubset.  If the input 
+ *  psImage is, however, a parent psImage, any children will be obliterated,
  *  i.e., freed from memory.
  *
@@ -87,8 +93,8 @@
 psImage* psImageTrim(
     psImage* image,                    ///< image to trim
-    int x0,                            ///< column of trim region's left boundary
-    int x1,                            ///< column of trim region's right boundary
-    int y0,                            ///< row of trim region's lower boundary
-    int y1                             ///< row of trim region's upper boundary
+    int col0,                          ///< column of trim region's left boundary
+    int row0,                          ///< row of trim region's lower boundary
+    int col1,                          ///< column of trim region's right boundary
+    int row1                           ///< row of trim region's upper boundary
 );
 
