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);
                         }
                     }
