Index: trunk/psLib/src/imageops/psImageStructManip.c
===================================================================
--- trunk/psLib/src/imageops/psImageStructManip.c	(revision 14885)
+++ trunk/psLib/src/imageops/psImageStructManip.c	(revision 14921)
@@ -8,6 +8,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2007-08-16 02:51:09 $
+ *  @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-09-20 23:48:47 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -23,7 +23,8 @@
 
 #include "psMemory.h"
+#include "psError.h"
+#include "psAbort.h"
+
 #include "psImageStructManip.h"
-#include "psError.h"
-
 
 // col0,row0 are the starting pixel in the input image coordinate frame
@@ -98,10 +99,17 @@
     if (out != NULL) {
         // if a child, need to orphan (disassociate from parent) first
-        if (out->parent != NULL) {
-            psArrayRemoveData(out->parent->children,psMemIncrRefCounter(out));
-            // remove from parent's knowledge without triggering a free
-            out->parent = NULL; // break link to parent
+	psImage *parent = (psImage *) out->parent;
+        if (parent != NULL) {
+	    // break the back-pointer first so we don't loop
+	    out->parent = NULL;
+
+	    // drop my entry on my parent's array of children
+            psArrayRemoveDataNoFree (out->parent->children, out);
+
+	    // drop my reference to my old parent
+	    psFree (parent);
         }
 
+	// we recycle out->data.V
         psFree(out->p_rawDataBuffer); // free the previous data reference
     } else {
@@ -117,5 +125,5 @@
     P_PSIMAGE_SET_ROW0(out, row0);
 
-    out->parent = image;
+    out->parent = psMemIncrRefCounter(image); // track references to parents
     out->children = NULL;
     out->p_rawDataBuffer = rawData;
@@ -133,6 +141,6 @@
 
     // add output image as a child of the input image.
-    image->children = psArrayAdd(image->children,16,out);
-    psMemDecrRefCounter(out); // don't count the reference held by parent as a true reference
+    image->children = psArrayAdd (image->children, 16, out);
+    psFree (out); // the image->children array is an array of views only
 
     return (out);
@@ -307,4 +315,8 @@
                 _("Can not operate on a NULL psImage."));
         return NULL;
+    }
+
+    if ((image->children != NULL) && (image->children->n > 0)) {
+	psAbort ("cannot trim an image with outstanding children");
     }
 
@@ -345,6 +357,4 @@
     }
 
-    psImageFreeChildren(image);
-
     psU32 elementSize = PSELEMTYPE_SIZEOF(image->type.type);
     psU32 numCols = col1-col0;
Index: trunk/psLib/src/mathtypes/psImage.c
===================================================================
--- trunk/psLib/src/mathtypes/psImage.c	(revision 14885)
+++ trunk/psLib/src/mathtypes/psImage.c	(revision 14921)
@@ -9,6 +9,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.129 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2007-04-12 18:52:57 $
+ *  @version $Revision: 1.130 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2007-09-20 23:48:30 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -28,4 +28,6 @@
 #include "psError.h"
 #include "psAssert.h"
+#include "psAbort.h"
+
 #include "psImage.h"
 #include "psString.h"
@@ -38,16 +40,31 @@
     }
 
-    if (image->parent != NULL) {
-        psMemBlock* ptr = ((psMemBlock*)image)-1;
-        int ref = ptr->refCounter;
-        ptr->refCounter = 2;  // make sure psFree is not retriggered
-        psArrayRemoveData(image->parent->children,image);
-        ptr->refCounter = ref; // restore previous count (not assuming zero, but should be)
-
-        image->parent = NULL;
-    }
-
-    psImageFreeChildren(image);
-
+    psImage *parent = (psImage *) image->parent;
+
+    // if I am a child, remove me from my parent's array of children
+    if (parent != NULL) {
+	// sanity check : a child cannot also be a parent
+	if ((image->children != NULL) && (image->children->n > 0)) {
+	    psAbort ("psImage cannot be both child and parent!");
+	}
+
+	// break the back-pointer first so we don't loop
+        image->parent = NULL; 
+
+	// drop my entry on my parent's array of children
+	psArrayRemoveDataNoFree (parent->children, image); 
+	
+	// drop my reference to my parent
+	psFree (parent);
+    }
+    
+    // sanity check: this function should never be reached if an image still has live children;
+    // they should each be holding a pointer to the image, forcing the number of references to
+    // be > 1.
+    if (image->children && (image->children->n > 0)) {
+	psAbort ("psImage memory management programming error : imageFree called on image with live children");
+    }
+
+    psFree(image->children);
     psFree(image->p_rawDataBuffer);
     psFree(image->data.V);
@@ -524,30 +541,4 @@
 }
 
-
-int psImageFreeChildren(psImage* image)
-{
-    psS32 numFreed = 0;
-
-    if (image == NULL) {
-        return numFreed;
-    }
-
-    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 (psS32 i=0;i<numFreed;i++) {
-            children[i]->parent = NULL;
-        }
-
-        psFree(image->children);
-        image->children = NULL;
-    }
-
-    return numFreed;
-}
-
 bool p_psImagePrint (int fd,
                      psImage *a,
