Index: /trunk/psLib/src/dataManip/Makefile
===================================================================
--- /trunk/psLib/src/dataManip/Makefile	(revision 1215)
+++ /trunk/psLib/src/dataManip/Makefile	(revision 1216)
@@ -16,5 +16,5 @@
            psMinimize.o \
            psImageManip.o
-
+           
 all: $(TARGET_STATIC)
 
Index: /trunk/psLib/src/image/psImageManip.c
===================================================================
--- /trunk/psLib/src/image/psImageManip.c	(revision 1215)
+++ /trunk/psLib/src/image/psImageManip.c	(revision 1216)
@@ -10,6 +10,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-07-09 21:48:07 $
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-07-14 23:22:49 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -17,9 +17,14 @@
 #include <math.h>                      // for isfinite(), etc.
 #include <stdlib.h>
+#include <stdbool.h>
 
 #include "psError.h"
 #include "psImage.h"
-
-int psImageClip(psImage* input,float min,float vmin,float max,float vmax)
+#include "psStats.h"
+#include "psMemory.h"
+
+bool getSpecifiedStatValue(const psStats* stats, double* value);
+
+int psImageClip(psImage* input, psF64 min, psF64 vmin, psF64 max, psF64 vmax)
 {
     int numClipped = 0;
@@ -41,6 +46,16 @@
     switch (input->type.type) {
 
-        #define psImageClipCase(type)\
+        #define psImageClipCase(type,typename) \
     case PS_TYPE_##type: { \
+            if (vmin < PS_MIN_##type || vmin > PS_MAX_##type) { \
+                psError(__func__, "Specified vmin (%g) is outside of image's " \
+                        typename " pixel range", \
+                        vmin); \
+            } \
+            if (vmax > PS_MAX_##type || vmax < PS_MIN_##type) { \
+                psError(__func__, "Specified vmax (%g) is outside of image's " \
+                        typename " pixel range", \
+                        vmax); \
+            } \
             ps##type minimum = (ps##type) min; \
             ps##type maximum = (ps##type) max; \
@@ -59,13 +74,24 @@
         } \
         break;
-        #define psImageClipCaseComplex(type)\
+
+        #define psImageClipCaseComplex(type,typename,absfcn)\
     case PS_TYPE_##type: { \
+            if (vmin < PS_MIN_##type || vmin > PS_MAX_##type) { \
+                psError(__func__, "Specified vmin (%g) is outside of image's " \
+                        typename " pixel range", \
+                        vmin); \
+            } \
+            if (vmax > PS_MAX_##type || vmax < PS_MIN_##type) { \
+                psError(__func__, "Specified vmax (%g) is outside of image's " \
+                        typename " pixel range", \
+                        vmax); \
+            } \
             for (unsigned int row = 0;row<numRows;row++) { \
                 ps##type* inputRow = input->data.type[row]; \
                 for (unsigned int col = 0; col < numCols; col++) { \
-                    if (cabsf(inputRow[col]) < min) { \
+                    if (absfcn(inputRow[col]) < min) { \
                         inputRow[col] = (ps##type)vmin; \
                         numClipped++; \
-                    } else if (cabsf(inputRow[col]) > max) { \
+                    } else if (absfcn(inputRow[col]) > max) { \
                         inputRow[col] = (ps##type)vmax; \
                         numClipped++; \
@@ -76,16 +102,16 @@
         break;
 
-        psImageClipCase(S8)
-        psImageClipCase(S16)
-        psImageClipCase(S32)
-        psImageClipCase(S64)
-        psImageClipCase(U8)
-        psImageClipCase(U16)
-        psImageClipCase(U32)
-        psImageClipCase(U64)
-        psImageClipCase(F32)
-        psImageClipCase(F64)
-        psImageClipCaseComplex(C32)
-        psImageClipCaseComplex(C64)
+        psImageClipCase(S8,"psS8")
+        psImageClipCase(S16,"psS16")
+        psImageClipCase(S32,"psS32")
+        psImageClipCase(S64,"psS64")
+        psImageClipCase(U8,"psU8")
+        psImageClipCase(U16,"psU16")
+        psImageClipCase(U32,"psU32")
+        psImageClipCase(U64,"psU64")
+        psImageClipCase(F32,"psF32")
+        psImageClipCase(F64,"psF64")
+        psImageClipCaseComplex(C32,"psC32",cabsf)
+        psImageClipCaseComplex(C64,"psC64",cabs)
 
     default:
@@ -97,5 +123,5 @@
 }
 
-int psImageClipNaN(psImage* input,float value)
+int psImageClipNaN(psImage* input,psF64 value)
 {
     int numClipped = 0;
@@ -240,2 +266,220 @@
     return 0;
 }
+
+int psImageClipComplexRegion(psImage* input, psC64 min, psC64 vmin, psC64 max, psC64 vmax)
+{
+    int numClipped = 0;
+    unsigned int numRows;
+    unsigned int numCols;
+    psF64 realMin = creal(min);
+    psF64 imagMin = cimag(min);
+    psF64 realMax = creal(max);
+    psF64 imagMax = cimag(max);
+
+    if (input == NULL) {
+        return 0;
+    }
+
+    if ( realMax < realMin ) {
+        psError(__func__,"psImageClipComplexRegion can not be invoked with "
+                "max < min in the real image space.");
+        return 0;
+    }
+    if ( imagMax < imagMin ) {
+        psError(__func__,"psImageClipComplexRegion can not be invoked with "
+                "max < min in the imaginary image space.");
+        return 0;
+    }
+
+    numRows = input->numRows;
+    numCols = input->numCols;
+
+    switch (input->type.type) {
+
+        #define psImageClipComplexRegionCase(type,typename,realfcn,imagfcn) \
+    case PS_TYPE_##type: { \
+            if (realfcn(vmin) < PS_MIN_##type || imagfcn(vmin) < PS_MIN_##type || \
+                    realfcn(vmin) > PS_MAX_##type || imagfcn(vmin) > PS_MAX_##type ) { \
+                psError(__func__, "Specified vmin (%g%+gi) is outside of image's " \
+                        typename " pixel range", \
+                        realfcn(vmin),imagfcn(vmin)); \
+            } \
+            if (realfcn(vmax) > PS_MAX_##type || imagfcn(vmax) > PS_MAX_##type || \
+                    realfcn(vmax) < PS_MIN_##type || imagfcn(vmax) < PS_MIN_##type ) { \
+                psError(__func__, "Specified vmax (%g%+gi) is outside of image's " \
+                        typename " pixel range", \
+                        realfcn(vmax),imagfcn(vmax)); \
+            } \
+            for (unsigned int row = 0;row<numRows;row++) { \
+                ps##type* inputRow = input->data.type[row]; \
+                for (unsigned int col = 0; col < numCols; col++) { \
+                    if ( (realfcn(inputRow[col]) > realMax) || (imagfcn(inputRow[col]) > imagMax) ) { \
+                        inputRow[col] = (ps##type)vmin; \
+                        numClipped++; \
+                    } else if ( (realfcn(inputRow[col]) < realMin) || (imagfcn(inputRow[col]) < imagMax) ){ \
+                        inputRow[col] = (ps##type)vmax; \
+                        numClipped++; \
+                    } \
+                } \
+            } \
+        } \
+        break;
+
+        psImageClipComplexRegionCase(C32,"psC32",crealf,cimagf)
+        psImageClipComplexRegionCase(C64,"psC64",creal,cimag)
+
+    default:
+        psError(__func__,"psImageClip does not support the given datatype (%d)",
+                input->type.type);
+    }
+
+    return numClipped;
+}
+
+bool getSpecifiedStatValue(const psStats* stats, double* value)
+{
+
+    switch (stats->options &
+            ! (PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE | PS_STAT_ROBUST_FOR_SAMPLE)) {
+    case PS_STAT_SAMPLE_MEAN:
+        *value = stats->sampleMean;
+        return true;
+
+    case PS_STAT_SAMPLE_MEDIAN:
+        *value = stats->sampleMedian;
+        return true;
+
+    case PS_STAT_SAMPLE_STDEV:
+        *value = stats->sampleStdev;
+        return true;
+
+    case PS_STAT_ROBUST_MEAN:
+        *value = stats->robustMean;
+        return true;
+
+    case PS_STAT_ROBUST_MEDIAN:
+        *value = stats->robustMedian;
+        return true;
+
+    case PS_STAT_ROBUST_MODE:
+        *value = stats->robustMode;
+        return true;
+
+    case PS_STAT_ROBUST_STDEV:
+        *value = stats->robustStdev;
+        return true;
+
+    case PS_STAT_CLIPPED_MEAN:
+        *value = stats->clippedMean;
+        return true;
+
+    case PS_STAT_CLIPPED_STDEV:
+        *value = stats->clippedStdev;
+        return true;
+
+    case PS_STAT_MAX:
+        *value = stats->max;
+        return true;
+
+    case PS_STAT_MIN:
+        *value = stats->min;
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+
+psImage* psImageRebin(psImage* out,const psImage* in,unsigned int scale,const psStats* stats)
+{
+    int inRows;
+    int inCols;
+    int outRows;
+    int outCols;
+    psVector* vec;            // vector to hold the values of a single bin.
+    psStats* myStats;
+    double statVal;
+
+    if (in == NULL) {
+        psError(__func__,"Input image is NULL.");
+        return NULL;
+    }
+
+    if (scale < 1) {
+        psError(__func__,"The scale must be positive.");
+        return NULL;
+    }
+
+    if (stats == NULL) {
+        psError(__func__,"The stats input can not be NULL.");
+        return NULL;
+    }
+
+    if (getSpecifiedStatValue(stats,&statVal) == false) {
+        psError(__func__,"The stat options didn't specify a single supported statistic type.");
+        return NULL;
+    }
+
+    myStats = psAlloc(sizeof(psStats));
+    *myStats = *stats;
+
+    vec = psVectorAlloc(scale*scale,in->type.type);
+
+    // create output image.
+    inRows = in->numRows;
+    inCols = in->numCols;
+    outRows = (inRows+scale-1) / scale;   // round-up for remainders
+    outCols = (inCols+scale-1) / scale;   // round-up for remainders
+    out = psImageRecycle(out,outCols,outRows,in->type.type);
+
+    #define PS_IMAGE_REBIN_CASE(type) \
+case PS_TYPE_##type: { \
+        ps##type* vecData = vec->data.type; \
+        for (int row = 0; row < outRows; row++) { \
+            ps##type* outRowData = out->data.type[row]; \
+            int inCurrentRow = row*scale; \
+            int inNextRow = (row+1)*scale; \
+            for (int col = 0; col < outCols; col++) { \
+                int inCurrentCol = col*scale; \
+                int inNextCol = (col+1)*scale; \
+                int n = 0; \
+                for (int inRow = inCurrentRow; inRow < inNextRow && inRow < inRows; inRow++) { \
+                    ps##type* inRowData = in->data.type[inRow]; \
+                    for (int inCol = inCurrentCol; inCol < inNextCol && inCol < inCols; inCol++) { \
+                        vecData[n++] = inRowData[inCol]; \
+                    } \
+                } \
+                vec->n = n; \
+                myStats = psVectorStats(myStats,vec,NULL,0); \
+                getSpecifiedStatValue(myStats,&statVal); \
+                outRowData[col] = (ps##type)statVal; \
+            } \
+        } \
+    } \
+    break;
+
+    switch (in->type.type) {
+        PS_IMAGE_REBIN_CASE(U8);
+        PS_IMAGE_REBIN_CASE(U16);
+        PS_IMAGE_REBIN_CASE(U32);
+        PS_IMAGE_REBIN_CASE(U64);
+        PS_IMAGE_REBIN_CASE(S8);
+        PS_IMAGE_REBIN_CASE(S16);
+        PS_IMAGE_REBIN_CASE(S32);
+        PS_IMAGE_REBIN_CASE(S64);
+        PS_IMAGE_REBIN_CASE(F32);
+        PS_IMAGE_REBIN_CASE(F64);
+        PS_IMAGE_REBIN_CASE(C32);
+        PS_IMAGE_REBIN_CASE(C64);
+    default:
+        psError(__func__,"Input image type not supported.");
+        psFree(out);
+        out = NULL;
+    }
+
+    psFree(vec);
+    psFree(myStats);
+
+    return out;
+}
Index: /trunk/psLib/src/image/psImageManip.d
===================================================================
--- /trunk/psLib/src/image/psImageManip.d	(revision 1216)
+++ /trunk/psLib/src/image/psImageManip.d	(revision 1216)
@@ -0,0 +1,3 @@
+psImageManip.o psImageManip.d : psImageManip.c ../sysUtils/psError.h \
+  ../collections/psImage.h ../collections/psType.h psStats.h \
+  ../collections/psVector.h ../sysUtils/psMemory.h
Index: /trunk/psLib/src/image/psImageManip.h
===================================================================
--- /trunk/psLib/src/image/psImageManip.h	(revision 1215)
+++ /trunk/psLib/src/image/psImageManip.h	(revision 1216)
@@ -10,11 +10,11 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-07-09 21:48:07 $
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-07-14 23:22:49 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
  */
-# ifndef PS_IMAGE_MANIP_H
-# define PS_IMAGE_MANIP_H
+#ifndef PS_IMAGE_MANIP_H
+#define PS_IMAGE_MANIP_H
 
 #include "psImage.h"
@@ -23,5 +23,5 @@
 /// @{
 
-/** Clip image values outside of tange to given values
+/** Clip image values outside of range to given values
  *
  *  All pixels with values less than min are set to the value vmin.  all pixels
@@ -33,8 +33,25 @@
 int psImageClip(
     psImage* input,                 ///< the image to clip
-    psF32 min,                      ///< the minimum image value allowed
-    psF32 vmin,                     ///< the value pixels < min are set to
-    psF32 max,                      ///< the maximum image value allowed
-    psF32 vmax                      ///< the value pixels > max are set to
+    psF64 min,                      ///< the minimum image value allowed
+    psF64 vmin,                     ///< the value pixels < min are set to
+    psF64 max,                      ///< the maximum image value allowed
+    psF64 vmax                      ///< the value pixels > max are set to
+);
+
+/** Clip image values outside of a specified complex region
+ *
+ *  All pixels outside of the rectangular region in complex space formed by
+ *  the min and max input parameters are set to the value vmax (if either
+ *  the real or imaginary portion exceeds the respective max values), or vmin. 
+ *  This function is defined for psC32, and psC64 imagery only.
+ *
+ *  @return int     The number of clipped pixels
+ */
+int psImageClipComplexRegion(
+    psImage* input,                 ///< the image to clip
+    psC64 min,                      ///< the minimum image value allowed
+    psC64 vmin,                     ///< the value pixels < min are set to
+    psC64 max,                      ///< the maximum image value allowed
+    psC64 vmax                      ///< the value pixels > max are set to
 );
 
@@ -48,5 +65,5 @@
 int psImageClipNaN(
     psImage* input,                 ///< the image to clip
-    psF32 value                     ///< the value to set all NaN/Inf values to
+    psF64 value                     ///< the value to set all NaN/Inf values to
 );
 
@@ -70,4 +87,21 @@
 );
 
+/** Rebin image to new scale.
+ *
+ *  A new image is constructed in which the dimensions are reduced by a factor of
+ *  1/scale.  The scale, always a positive number, is equal in each dimension and
+ *  specified the number of pixels used to define a new pixel in the output image.
+ *  The output image is generated from all input image pixels. This function is 
+ *  defined for psU8, psS8, psS16, psF32, psF64, psC32, and psC64.
+ *
+ *  @return psImage    new image formed by rebinning input image.
+ */
+psImage* psImageRebin(
+    psImage* out,                   ///< an psImage to recycle.  If NULL, a new image is created
+    const psImage* in,              ///< input image
+    unsigned int scale,             ///< the scale to rebin for each dimension
+    const psStats* stats            ///< the statistic to perform when rebinning.  Only one method should be set.
+);
 
 #endif
+
Index: /trunk/psLib/src/sys/psType.h
===================================================================
--- /trunk/psLib/src/sys/psType.h	(revision 1215)
+++ /trunk/psLib/src/sys/psType.h	(revision 1216)
@@ -10,6 +10,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-06-10 01:58:06 $
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-07-14 23:22:49 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -21,4 +21,5 @@
 #include <complex.h>
 #include <stdint.h>
+#include <float.h>
 
 /// @addtogroup DataContainer
@@ -69,4 +70,30 @@
 #define PS_TYPE_MASK PS_TYPE_U8         ///< the psElemType to use for mask image
 typedef psU8 psMaskType;                ///< the C datatype for a mask image
+
+#define PS_MIN_S8        INT8_MIN
+#define PS_MIN_S16       INT16_MIN
+#define PS_MIN_S32       INT32_MIN
+#define PS_MIN_S64       INT64_MIN
+#define PS_MIN_U8        0
+#define PS_MIN_U16       0
+#define PS_MIN_U32       0
+#define PS_MIN_U64       0
+#define PS_MIN_F32       FLT_MIN
+#define PS_MIN_F64       DBL_MIN
+#define PS_MIN_C32       FLT_MIN
+#define PS_MIN_C64       DBL_MIN
+
+#define PS_MAX_S8        INT8_MAX
+#define PS_MAX_S16       INT16_MAX
+#define PS_MAX_S32       INT32_MAX
+#define PS_MAX_S64       INT64_MAX
+#define PS_MAX_U8        UINT8_MAX
+#define PS_MAX_U16       UINT16_MAX
+#define PS_MAX_U32       UINT32_MAX
+#define PS_MAX_U64       UINT64_MAX
+#define PS_MAX_F32       FLT_MAX
+#define PS_MAX_F64       DBL_MAX
+#define PS_MAX_C32       FLT_MAX
+#define PS_MAX_C64       DBL_MAX
 
 /// Macro to get the bad pixel reason code (stored as part of mask value)
Index: /trunk/psLib/src/sysUtils/psType.h
===================================================================
--- /trunk/psLib/src/sysUtils/psType.h	(revision 1215)
+++ /trunk/psLib/src/sysUtils/psType.h	(revision 1216)
@@ -10,6 +10,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-06-10 01:58:06 $
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-07-14 23:22:49 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -21,4 +21,5 @@
 #include <complex.h>
 #include <stdint.h>
+#include <float.h>
 
 /// @addtogroup DataContainer
@@ -69,4 +70,30 @@
 #define PS_TYPE_MASK PS_TYPE_U8         ///< the psElemType to use for mask image
 typedef psU8 psMaskType;                ///< the C datatype for a mask image
+
+#define PS_MIN_S8        INT8_MIN
+#define PS_MIN_S16       INT16_MIN
+#define PS_MIN_S32       INT32_MIN
+#define PS_MIN_S64       INT64_MIN
+#define PS_MIN_U8        0
+#define PS_MIN_U16       0
+#define PS_MIN_U32       0
+#define PS_MIN_U64       0
+#define PS_MIN_F32       FLT_MIN
+#define PS_MIN_F64       DBL_MIN
+#define PS_MIN_C32       FLT_MIN
+#define PS_MIN_C64       DBL_MIN
+
+#define PS_MAX_S8        INT8_MAX
+#define PS_MAX_S16       INT16_MAX
+#define PS_MAX_S32       INT32_MAX
+#define PS_MAX_S64       INT64_MAX
+#define PS_MAX_U8        UINT8_MAX
+#define PS_MAX_U16       UINT16_MAX
+#define PS_MAX_U32       UINT32_MAX
+#define PS_MAX_U64       UINT64_MAX
+#define PS_MAX_F32       FLT_MAX
+#define PS_MAX_F64       DBL_MAX
+#define PS_MAX_C32       FLT_MAX
+#define PS_MAX_C64       DBL_MAX
 
 /// Macro to get the bad pixel reason code (stored as part of mask value)
