Index: trunk/psLib/src/imageops/psImageConvolve.c
===================================================================
--- trunk/psLib/src/imageops/psImageConvolve.c	(revision 4608)
+++ trunk/psLib/src/imageops/psImageConvolve.c	(revision 4815)
@@ -5,6 +5,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.22 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-07-12 19:33:49 $
+ *  @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-08-18 21:44:40 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -12,5 +12,5 @@
 
 #include <string.h>
-
+#include <math.h>
 #include "psImageConvolve.h"
 #include "psImageFFT.h"
@@ -279,5 +279,8 @@
 }
 
-psImage* psImageConvolve(psImage* out, const psImage* in, const psKernel* kernel, bool direct)
+psImage* psImageConvolve(psImage* out,
+                         const psImage* in,
+                         const psKernel* kernel,
+                         bool direct)
 {
     if (in == NULL) {
@@ -476,2 +479,74 @@
     return out;
 }
+
+void psImageSmooth (psImage *image,
+                    float sigma,
+                    float Nsigma)
+{
+
+    int Nx, Ny, Npixel, Nrange;
+    float factor, g, s;
+    psVector *temp;
+
+    // relevant terms
+    Nrange = sigma*Nsigma + 0.5;
+    Npixel = 2*Nrange + 1;
+    factor = -0.5/(sigma*sigma);
+
+    Nx = image->numCols;
+    Ny = image->numRows;
+
+    // generate gaussian
+    psVector *gaussnorm = psVectorAlloc (Npixel, PS_TYPE_F32);
+    for (int i = -Nrange; i < Nrange + 1; i++) {
+        gaussnorm->data.F32[i+Nrange] = exp (factor*i*i);
+    }
+    psF32 *gauss = &gaussnorm->data.F32[Nrange];
+
+    // smooth in X direction
+    temp = psVectorAlloc (Nx, PS_TYPE_F32);
+    for (int j = 0; j < Ny; j++) {
+        psF32 *vi = image->data.F32[j];
+        psF32 *vo = temp->data.F32;
+        for (int i = 0; i < Nx; i++) {
+            g = s = 0;
+            for (int n = -Nrange; n < Nrange + 1; n++) {
+                if (i+n < 0)
+                    continue;
+                if (i+n >= Nx)
+                    continue;
+                s += gauss[n]*vi[i+n];
+                g += gauss[n];
+            }
+            vo[i] = s / g;
+        }
+        memcpy (image->data.F32[j], temp->data.F32, Nx*sizeof(psF32));
+    }
+    psFree (temp);
+
+    // smooth in Y direction
+    temp = psVectorAlloc (image->numRows, PS_TYPE_F32);
+    for (int i = 0; i < Nx; i++) {
+        psF32  *vo = temp->data.F32;
+        psF32 **vi = image->data.F32;
+        for (int j = 0; j < Ny; j++) {
+            g = s = 0;
+            for (int n = -Nrange; n < Nrange + 1; n++) {
+                if (j+n < 0)
+                    continue;
+                if (j+n >= Ny)
+                    continue;
+                s += gauss[n]*vi[j+n][i];
+                g += gauss[n];
+            }
+            vo[j] = s / g;
+        }
+        // replace temp in image
+        for (int j = 0; j < Ny; j++) {
+            vi[j][i] = vo[j];
+        }
+    }
+    psFree (temp);
+    psFree (gaussnorm);
+}
+
Index: trunk/psLib/src/imageops/psImageConvolve.h
===================================================================
--- trunk/psLib/src/imageops/psImageConvolve.h	(revision 4608)
+++ trunk/psLib/src/imageops/psImageConvolve.h	(revision 4815)
@@ -7,6 +7,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-07-12 19:12:01 $
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-08-18 21:44:40 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -126,3 +126,15 @@
 );
 
+/** Smooths an image by parts using 1D Gaussian independently in x and y.
+ *
+ *  Applies a circularly symmetric Gaussian smoothing first in x and then in y
+ *  directions with just a vector.  This process is 2N faster than 2D convolutions (in general).
+ */
+void psImageSmooth(
+    psImage *image,                    ///< the image to be smoothed
+    float sigma,                       ///< the width of the smoothing kernel in pixels
+    float Nsigma                       ///< the size of the smoothing box in sigmas
+);
+
+
 #endif // #ifndef PS_IMAGE_CONVOLVE_H
Index: trunk/psLib/src/imageops/psImagePixelManip.c
===================================================================
--- trunk/psLib/src/imageops/psImagePixelManip.c	(revision 4608)
+++ trunk/psLib/src/imageops/psImagePixelManip.c	(revision 4815)
@@ -10,6 +10,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-07-21 01:40:10 $
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-08-18 21:44:40 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -396,2 +396,118 @@
 }
 
+// mask the area contained by the region
+// the region is defined wrt the parent image
+void psImageMaskRegion(psImage *image,
+                       psRegion *region,
+                       bool logical_and,
+                       int maskValue)
+{
+
+    for (int iy = 0; iy < image->numRows; iy++) {
+        for (int ix = 0; ix < image->numCols; ix++) {
+            if (ix + image->col0 <  region->x0)
+                continue;
+            if (ix + image->col0 >= region->x1)
+                continue;
+            if (iy + image->row0 <  region->y0)
+                continue;
+            if (iy + image->row0 >= region->y1)
+                continue;
+            if (logical_and) {
+                image->data.U8[iy][ix] &= maskValue;
+            } else {
+                image->data.U8[iy][ix] |= maskValue;
+            }
+        }
+    }
+}
+
+// mask the area not contained by the region
+// the region is defined wrt the parent image
+void psImageKeepRegion(psImage *image,
+                       psRegion *region,
+                       bool logical_and,
+                       int maskValue)
+{
+
+    for (int iy = 0; iy < image->numRows; iy++) {
+        for (int ix = 0; ix < image->numCols; ix++) {
+            if (ix + image->col0 <  region->x0)
+                goto maskit;
+            if (ix + image->col0 >= region->x1)
+                goto maskit;
+            if (iy + image->row0 <  region->y0)
+                goto maskit;
+            if (iy + image->row0 >= region->y1)
+                goto maskit;
+            continue;
+maskit:
+            if (logical_and) {
+                image->data.U8[iy][ix] &= maskValue;
+            } else {
+                image->data.U8[iy][ix] |= maskValue;
+            }
+        }
+    }
+}
+
+// mask the area contained by the region
+// the region is defined wrt the parent image
+void psImageMaskCircle(psImage *image,
+                       double x,
+                       double y,
+                       double radius,
+                       bool logical_and,
+                       int maskValue)
+{
+
+    double dx, dy, r2, R2;
+
+    R2 = PS_SQR(radius);
+
+    for (int iy = 0; iy < image->numRows; iy++) {
+        for (int ix = 0; ix < image->numCols; ix++) {
+            dx = ix + image->col0 - x;
+            dy = iy + image->row0 - y;
+            r2 = PS_SQR(dx) + PS_SQR(dy);
+            if (r2 > R2)
+                continue;
+            if (logical_and) {
+                image->data.U8[iy][ix] &= maskValue;
+            } else {
+                image->data.U8[iy][ix] |= maskValue;
+            }
+        }
+    }
+}
+
+// mask the area contained by the region
+// the region is defined wrt the parent image
+void psImageKeepCircle(psImage *image,
+                       double x,
+                       double y,
+                       double radius,
+                       bool logical_and,
+                       int maskValue)
+{
+
+    double dx, dy, r2, R2;
+
+    R2 = PS_SQR(radius);
+
+    for (int iy = 0; iy < image->numRows; iy++) {
+        for (int ix = 0; ix < image->numCols; ix++) {
+            dx = ix + image->col0 - x;
+            dy = iy + image->row0 - y;
+            r2 = PS_SQR(dx) + PS_SQR(dy);
+            if (r2 < R2)
+                continue;
+            if (logical_and) {
+                image->data.U8[iy][ix] &= maskValue;
+            } else {
+                image->data.U8[iy][ix] |= maskValue;
+            }
+        }
+    }
+}
+
Index: trunk/psLib/src/imageops/psImagePixelManip.h
===================================================================
--- trunk/psLib/src/imageops/psImagePixelManip.h	(revision 4608)
+++ trunk/psLib/src/imageops/psImagePixelManip.h	(revision 4815)
@@ -8,6 +8,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-07-21 01:40:10 $
+ *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-08-18 21:44:40 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -87,4 +87,55 @@
     const char *op                     ///< the operation to perform for overlay
 );
+/** Sets the bits inside the region, ignoring pixels outside.
+ *
+ *  The pixels are set by combining the existing pixel value and the given maskValue
+ *  with a logical operation.  The allowed operations are =, AND, OR, and XOR.
+ */
+void psImageMaskRegion(
+    psImage *image,                    ///< the image to set
+    psRegion *region,                  ///< the specified region
+    bool logical_and,                  ///< the logical operation
+    int maskValue                      ///< the specified bits
+);
+
+/** Sets the bits outside the region, ignoring pixels inside.
+ *
+ *  The pixels are set by combining the existing pixel value and the given maskValue
+ *  with a logical operation.  The allowed operations are =, AND, OR, and XOR.
+ */
+void psImageKeepRegion(
+    psImage *image,                    ///< the image to set
+    psRegion *region,                  ///< the specified region
+    bool logical_and,                  ///< the logical operation
+    int maskValue                      ///< the specified bits
+);
+
+/** Sets the bits inside the circle, ignoring the pixels outside.
+ *
+ *  The pixel values are set by combining the existing pixel value and the given maskValue
+ *  with a logical operation.  The allowed operations are =, AND, OR, and XOR.
+ */
+void psImageMaskCircle(
+    psImage *image,                    ///< the image to set
+    double x,                          ///< the x coordinate of the circle's center
+    double y,                          ///< the y coordinate of the circle's center
+    double radius,                     ///< the radius of the specified circle
+    bool logical_and,                  ///< the logical operation
+    int maskValue                      ///< the specified bits
+);
+
+/** Sets the bits outside the circle, ignoring the pixels inside.
+ *
+ *  The pixel values are set by combining the existing pixel value and the given maskValue
+ *  with a logical operation.  The allowed operations are =, AND, OR, and XOR.
+ */
+void psImageKeepCircle(
+    psImage *image,                    ///< the image to set
+    double x,                          ///< the x coordinate of the circle's center
+    double y,                          ///< the y coordinate of the circle's center
+    double radius,                     ///< the radius of the specified circle
+    bool logical_and,                  ///< the logical operation
+    int maskValue                      ///< the specified bits
+);
 
 #endif // #ifndef PS_IMAGE_PIXEL_MANIP_H
