Index: /trunk/psLib/src/imageops/psImageGeomManip.c
===================================================================
--- /trunk/psLib/src/imageops/psImageGeomManip.c	(revision 9926)
+++ /trunk/psLib/src/imageops/psImageGeomManip.c	(revision 9927)
@@ -10,6 +10,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.31 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-11-06 02:02:59 $
+ *  @version $Revision: 1.32 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-11-09 20:20:27 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -594,4 +594,90 @@
 }
 
+// XXX this function seems to work (except for edge pixels and masked pixels
+// but the function below does not define the right 3x3 kernels.  look this
+// up
+psImage *p_psImageShiftKernel_F32(
+    psImage *out,
+    const psImage *input,
+    const psImage *kernel)
+{
+
+    PS_ASSERT_IMAGE_NON_NULL(input, NULL);
+    PS_ASSERT_IMAGE_NON_NULL(kernel, NULL);
+
+    if ((kernel->numCols % 2 == 0) || (kernel->numRows % 2 == 0)) {
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                _("kernel must have odd dimensions"));
+        return NULL;
+    }
+    int Xk = (kernel->numCols - 1) / 2;
+    int Yk = (kernel->numRows - 1) / 2;
+
+    int outRows = input->numRows;
+    int outCols = input->numCols;
+    out = psImageRecycle(out, outCols, outRows, input->type.type);
+    psImageInit (out, 0.0);
+
+    // need to handle the edge cases...
+    for (int row = 1; row < outRows-1; row++) {
+        psF32 *outRow = out->data.F32[row];
+        psF32 **inValue = input->data.F32;
+        for (int col = 1; col < outCols-1; col++) {
+            double value = 0;
+            double norm = 0;
+            psF32 **kernValue = kernel->data.F32;
+            for (int yi = -Yk; yi <= Yk; yi++) {
+                for (int xi = -Xk; xi <= Xk; xi++) {
+                    value += inValue[row+yi][col+xi]*kernValue[yi+Yk][xi+Xk];
+                    norm += kernValue[yi+Yk][xi+Xk];
+                }
+            }
+            // include the mask tests and divide-by-zero test
+            outRow[col] = value / norm;
+        }
+    }
+
+    return (out);
+}
+
+// XXX fix the definition of the interpolation kernels and add integer shifts
+psImage *psImageShiftKernel (
+    psImage *out,
+    const psImage *input,
+    float dx, float dy, psImageInterpolateMode mode)
+{
+
+    psImage *kernel = NULL;
+
+    switch (mode) {
+    case PS_INTERPOLATE_BICUBE:
+        kernel = psImageAlloc (3, 3, PS_TYPE_F32);
+        for (int iy = -1; iy <= +1; iy++) {
+            for (int ix = -1; ix <= +1; ix++) {
+                kernel->data.F32[iy+1][ix+1] = 5 - 3*PS_SQR(ix+dx) - 3*PS_SQR(iy+dy);
+            }
+        }
+        out = p_psImageShiftKernel_F32 (out, input, kernel);
+        break;
+
+    case PS_INTERPOLATE_GAUSS:
+        kernel = psImageAlloc (3, 3, PS_TYPE_F32);
+        for (int iy = -1; iy <= +1; iy++) {
+            for (int ix = -1; ix <= +1; ix++) {
+                kernel->data.F32[iy+1][ix+1] = exp(-0.5*PS_SQR(ix+dx) -0.5*PS_SQR(iy+dy));
+            }
+        }
+        out = p_psImageShiftKernel_F32 (out, input, kernel);
+        break;
+
+    default:
+        psError(PS_ERR_BAD_PARAMETER_NULL, true,
+                _("shift kernel for %d not defined"), mode);
+        return NULL;
+    }
+    psFree (kernel);
+    return (out);
+}
+
 psImage* psImageShift(psImage* out,
                       const psImage* input,
Index: /trunk/psLib/src/imageops/psImageGeomManip.h
===================================================================
--- /trunk/psLib/src/imageops/psImageGeomManip.h	(revision 9926)
+++ /trunk/psLib/src/imageops/psImageGeomManip.h	(revision 9927)
@@ -8,6 +8,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-06-07 03:22:06 $
+ *  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-11-09 20:20:27 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -100,4 +100,38 @@
     psImageInterpolateMode mode        ///< the interpolation mode to use
 );
+
+/** Shift image by an arbitrary number of pixels (dx,dy) in either direction.
+ *
+ *  If the shift values are fractional, the output pixel values should
+ *  interpolate between the input pixel values. The output image has the same
+ *  dimensions as the input image. Pixels which fall off the edge of the
+ *  output image are lost. Newly exposed pixels are set to the value given by
+ *  exposed. This function must be defined for the following types: psU8,
+ *  psU16, psS8, psS16, psF32, psF64, psC32, psC64.
+ *
+ *  This implementation uses a NxN kernel generated based on the interpolation method
+ *  the image is first shifted by a fractional amount with the kernel, then
+ *  shifted in place by an integer amount. 
+ *
+ *  XXX the integer shift portion is not implemented
+ *  XXX the exposed pixels are not properly replaced
+ *  XXX the algorithm can properly handle a mask, but the API does not include
+ *  it (and it is not implemented)
+ *
+ *  @return psImage*     the shifted image result.
+ */
+psImage* psImageShiftKernel(
+    psImage* out,                      ///< an psImage to recycle.  If NULL, a new image is created
+    const psImage* input,              ///< input image
+    float dx,                          ///< the shift in x direction.
+    float dy,                          ///< the shift in y direction.
+    psImageInterpolateMode mode        ///< the interpolation mode to use
+);
+
+// XXX should this be global private or local static?
+psImage *p_psImageShiftKernel_F32(
+    psImage *out,
+    const psImage *input,
+    const psImage *kernel);
 
 /** Roll image by an integer number of pixels in either direction.
@@ -151,6 +185,6 @@
     psRegion region,                   ///< the size of the transformed image
     const psPixels* pixels,            /**< if not NULL, consists of psPixelCoords and specifies
-                                                * which pixels in output image shall be transformed;
-                                                * otherwise, entire image generated*/
+                                                    * which pixels in output image shall be transformed;
+                                                    * otherwise, entire image generated*/
     psImageInterpolateMode mode,       ///< the interpolation scheme to be used
     double exposedValue                ///< Exposed value to which non-corresponding pixels are set
Index: /trunk/psLib/src/mathtypes/psImage.h
===================================================================
--- /trunk/psLib/src/mathtypes/psImage.h	(revision 9926)
+++ /trunk/psLib/src/mathtypes/psImage.h	(revision 9927)
@@ -11,6 +11,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.82 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2006-11-06 02:00:40 $
+ *  @version $Revision: 1.83 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2006-11-09 20:20:27 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -35,4 +35,5 @@
     PS_INTERPOLATE_BILINEAR,           ///< bi-linear interpolation
     PS_INTERPOLATE_BICUBE,             ///< bi-cubic interpolation with 3x3 region (EAM)
+    PS_INTERPOLATE_GAUSS,              ///< bi-cubic interpolation with 3x3 region (EAM)
     PS_INTERPOLATE_LANCZOS2,           ///< Sinc interpolation with 4x4 pixel kernel
     PS_INTERPOLATE_LANCZOS3,           ///< Sinc interpolation with 6x6 pixel kernel
