Index: trunk/psLib/src/imageops/psImageStats.c
===================================================================
--- trunk/psLib/src/imageops/psImageStats.c	(revision 12431)
+++ trunk/psLib/src/imageops/psImageStats.c	(revision 21183)
@@ -9,6 +9,6 @@
  *  @author GLG, MHPCC
  *
- *  @version $Revision: 1.106 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2007-03-14 00:39:50 $
+ *  @version $Revision: 1.107 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2009-01-27 06:39:37 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -53,5 +53,5 @@
                       const psImage* in,
                       const psImage* mask,
-                      psMaskType maskVal)
+                      psImageMaskType maskVal)
 {
     psVector *junkData = NULL;
@@ -62,7 +62,70 @@
     PS_ASSERT_IMAGE_NON_NULL(in, false)
     if (mask != NULL) {
-        PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_U8, false);
+        PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_IMAGE_MASK, false);
         PS_ASSERT_IMAGES_SIZE_EQUAL(in, mask, false);
     }
+
+    if (in->parent == NULL) {
+        // stuff the image data into a psVector struct.
+	// XXX this is a bit hackish: does it save much time? (avoids a Nx*Ny alloc)
+        junkData = (psVector *) psAlloc(sizeof(psVector));
+        junkData->type = in->type;
+        P_PSVECTOR_SET_NALLOC(junkData,in->numRows * in->numCols);
+        junkData->n = junkData->nalloc;
+        junkData->data.U8 = in->data.V[0];      // since psImage data is contiguous...
+    } else {
+        // image not necessarily contiguous
+        int numRows = in->numRows;
+        int numCols = in->numCols;
+        int rowSize = numCols * (PSELEMTYPE_SIZEOF(in->type.type));
+
+        junkData = psVectorAlloc(numRows*numCols, in->type.type);
+
+        psU8* data = junkData->data.U8;
+        for (int row = 0; row < numRows; row++) {
+            memcpy(data, in->data.V[row], rowSize);
+            data += rowSize;
+        }
+    }
+
+    if (mask != NULL) {
+	// image not necessarily contiguous, generate a temp vector to hold the full image
+	int numRows = mask->numRows;
+	int numCols = mask->numCols;
+
+	junkMask = psVectorAlloc(numRows*numCols, PS_TYPE_VECTOR_MASK);
+
+	psVectorMaskType *data = junkMask->data.PS_TYPE_VECTOR_MASK_DATA;
+	for (int row = 0, nVect = 0; row < numRows; row++) {
+	    for (int col = 0; col < numCols; col++, nVect++) {
+		data[nVect] = (mask->data.PS_TYPE_IMAGE_MASK_DATA[row][col] & maskVal);
+	    }
+	}
+    }
+
+    psVectorStats(stats, junkData, NULL, junkMask, 0xff);
+
+    psFree(junkMask);
+    psFree(junkData);
+    return true;
+}
+
+/*****************************************************************************
+NOTE: We assume that the psHistogram structure out has already been allocated
+and initialized.
+ *****************************************************************************/
+bool psImageHistogram(psHistogram* out,
+                              const psImage* in,
+                              const psImage* mask,
+                              psImageMaskType maskVal)
+{
+    PS_ASSERT_PTR_NON_NULL(out, false);
+    PS_ASSERT_PTR_NON_NULL(in, false);
+    if (mask != NULL) {
+        PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_IMAGE_MASK, false);
+        PS_ASSERT_IMAGES_SIZE_EQUAL(in, mask, false);
+    }
+    psVector* junkData = NULL;
+    psVector* junkMask = NULL;
 
     if (in->parent == NULL) {
@@ -89,96 +152,16 @@
 
     if (mask != NULL) {
-        if (mask->parent == NULL) {
-            // stuff the mask data into a psVector struct.
-            junkMask = psAlloc(sizeof(psVector));
-            junkMask->type = mask->type;
-            P_PSVECTOR_SET_NALLOC(junkMask,mask->numRows * mask->numCols);
-            junkMask->n = junkMask->nalloc;
-            junkMask->data.U8 = mask->data.V[0];
-        } else {
-            // image not necessarily contiguous
-            int numRows = mask->numRows;
-            int numCols = mask->numCols;
-            int rowSize = numCols * (PSELEMTYPE_SIZEOF(mask->type.type));
-
-            junkMask = psVectorAlloc(numRows*numCols, mask->type.type);
-
-            psU8* data = junkMask->data.U8;
-            for (int row = 0; row < numRows; row++) {
-                memcpy(data, mask->data.V[row], rowSize);
-                data += rowSize;
-            }
-        }
-    }
-
-    psVectorStats(stats, junkData, NULL, junkMask, maskVal);
-
-    psFree(junkMask);
-    psFree(junkData);
-    return true;
-}
-
-/*****************************************************************************
-NOTE: We assume that the psHistogram structure out has already been allocated
-and initialized.
- *****************************************************************************/
-bool psImageHistogram(psHistogram* out,
-                              const psImage* in,
-                              const psImage* mask,
-                              psMaskType maskVal)
-{
-    PS_ASSERT_PTR_NON_NULL(out, false);
-    PS_ASSERT_PTR_NON_NULL(in, false);
-    if (mask != NULL) {
-        PS_ASSERT_IMAGE_TYPE(mask, PS_TYPE_U8, false);
-        PS_ASSERT_IMAGES_SIZE_EQUAL(in, mask, false);
-    }
-    psVector* junkData = NULL;
-    psVector* junkMask = NULL;
-
-    if (in->parent == NULL) {
-        // stuff the image data into a psVector struct.
-        junkData = (psVector *) psAlloc(sizeof(psVector));
-        junkData->type = in->type;
-        P_PSVECTOR_SET_NALLOC(junkData,in->numRows * in->numCols);
-        junkData->n = junkData->nalloc;
-        junkData->data.U8 = in->data.V[0];      // since psImage data is contiguous...
-    } else {
-        // image not necessarily contiguous
-        int numRows = in->numRows;
-        int numCols = in->numCols;
-        int rowSize = numCols * (PSELEMTYPE_SIZEOF(in->type.type));
-
-        junkData = psVectorAlloc(numRows*numCols, in->type.type);
-
-        psU8* data = junkData->data.U8;
-        for (int row = 0; row < numRows; row++) {
-            memcpy(data, in->data.V[row], rowSize);
-            data += rowSize;
-        }
-    }
-
-    if (mask != NULL) {
-        if (mask->parent == NULL) {
-            // stuff the mask data into a psVector struct.
-            junkMask = psAlloc(sizeof(psVector));
-            junkMask->type = mask->type;
-            P_PSVECTOR_SET_NALLOC(junkMask,mask->numRows * mask->numCols);
-            junkMask->n = junkMask->nalloc;
-            junkMask->data.U8 = mask->data.V[0];
-        } else {
-            // image not necessarily contiguous
-            int numRows = mask->numRows;
-            int numCols = mask->numCols;
-            int rowSize = numCols * (PSELEMTYPE_SIZEOF(mask->type.type));
-
-            junkMask = psVectorAlloc(numRows*numCols, mask->type.type);
-
-            psU8* data = junkMask->data.U8;
-            for (int row = 0; row < numRows; row++) {
-                memcpy(data, mask->data.V[row], rowSize);
-                data += rowSize;
-            }
-        }
+	// image not necessarily contiguous; vector & image mask types do not match
+	int numRows = mask->numRows;
+	int numCols = mask->numCols;
+
+	junkMask = psVectorAlloc(numRows*numCols, PS_TYPE_VECTOR_MASK);
+
+	psVectorMaskType *data = junkMask->data.PS_TYPE_VECTOR_MASK_DATA;
+	for (int row = 0, nVect = 0; row < numRows; row++) {
+	    for (int col = 0; col < numCols; col++, nVect++) {
+		data[nVect] = (mask->data.PS_TYPE_IMAGE_MASK_DATA[row][col] & maskVal);
+	    }
+	}
     }
 
@@ -472,5 +455,5 @@
 long psImageCountPixelMask (psImage *mask,
                             psRegion region,
-                            psMaskType value)
+                            psImageMaskType value)
 {
     long Npixels = 0;
@@ -479,5 +462,4 @@
     int x1 = 0;
     int y1 = 0;
-    psElemType type;
 
     // this is not a valid error: a psRegion with ranges outside the valid pixels
@@ -608,34 +590,30 @@
     y1 = row1;
 
-    type = mask->type.type;
-    if (type != PS_TYPE_MASK) {
-        psError(PS_ERR_BAD_PARAMETER_TYPE, true,
-                "psImage type does not match the specified psMaskType!\n");
-        return -1;
-    }
-
+# define PS_IMAGE_COUNT_PIXEL_MASK(NAME,TYPE) \
+    case PS_TYPE_##NAME: \
+        for (long j = y0; j < y1; j++) { \
+            for (long i = x0; i < x1; i++) { \
+                if (mask->data.TYPE[j][i] & value) { \
+                    Npixels ++; \
+                } \
+            } \
+        } \
+        break;
+
+    psElemType type = mask->type.type;
     switch (type) {
-    case PS_TYPE_U8:
-    case PS_TYPE_U16:
-        for (long j = y0; j < y1; j++) {
-            for (long i = x0; i < x1; i++) {
-                if (mask->data.PS_TYPE_MASK_DATA[j][i] & value) {
-                    Npixels ++;
-                }
-            }
-        }
-        break;
-    case PS_TYPE_S8:
-    case PS_TYPE_S16:
-    case PS_TYPE_S32:
-    case PS_TYPE_S64:
-    case PS_TYPE_U32:
-    case PS_TYPE_U64:
-    case PS_TYPE_F32:
-    case PS_TYPE_F64:
+	PS_IMAGE_COUNT_PIXEL_MASK(U8, U8);
+	PS_IMAGE_COUNT_PIXEL_MASK(U16,U16);
+	PS_IMAGE_COUNT_PIXEL_MASK(U32,U32);
+	PS_IMAGE_COUNT_PIXEL_MASK(U64,U64);
+	PS_IMAGE_COUNT_PIXEL_MASK(S8, S8);
+	PS_IMAGE_COUNT_PIXEL_MASK(S16,S16);
+	PS_IMAGE_COUNT_PIXEL_MASK(S32,S32);
+	PS_IMAGE_COUNT_PIXEL_MASK(S64,S64);
+
     default:
         // XXX this should include the mask type (as a string)
         psError(PS_ERR_BAD_PARAMETER_TYPE, true,
-                _("Input psImage mask type is not a supported mask datatype"));
+                _("Input psImage is an unsupported datatype"));
 
         return -1;
