Index: /trunk/psLib/src/astronomy/psMetadata.c
===================================================================
--- /trunk/psLib/src/astronomy/psMetadata.c	(revision 1652)
+++ /trunk/psLib/src/astronomy/psMetadata.c	(revision 1653)
@@ -12,6 +12,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.25 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2004-08-25 20:21:25 $
+*  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-08-28 01:18:28 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -482,5 +482,4 @@
     entry = (psMetadataItem* ) psHashLookup(mdTable, key);
     if (entry == NULL) {
-        psError(__func__, "Could not find metadata item. Key: %s", key);
         return NULL;
     }
@@ -567,9 +566,4 @@
     }
 
-    // Match not found
-    if (entry == NULL) {
-        psError(__func__, "Couldn't find metadata item");
-    }
-
     return entry;
 }
@@ -605,9 +599,4 @@
             return psListGetPrevious(mdList);
         }
-    }
-
-    // Match not found
-    if (entry == NULL) {
-        psError(__func__, "Couldn't find metadata item", match);
     }
 
Index: /trunk/psLib/src/collections/psMetadata.c
===================================================================
--- /trunk/psLib/src/collections/psMetadata.c	(revision 1652)
+++ /trunk/psLib/src/collections/psMetadata.c	(revision 1653)
@@ -12,6 +12,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.25 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2004-08-25 20:21:25 $
+*  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-08-28 01:18:28 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -482,5 +482,4 @@
     entry = (psMetadataItem* ) psHashLookup(mdTable, key);
     if (entry == NULL) {
-        psError(__func__, "Could not find metadata item. Key: %s", key);
         return NULL;
     }
@@ -567,9 +566,4 @@
     }
 
-    // Match not found
-    if (entry == NULL) {
-        psError(__func__, "Couldn't find metadata item");
-    }
-
     return entry;
 }
@@ -605,9 +599,4 @@
             return psListGetPrevious(mdList);
         }
-    }
-
-    // Match not found
-    if (entry == NULL) {
-        psError(__func__, "Couldn't find metadata item", match);
     }
 
Index: /trunk/psLib/src/image/Makefile
===================================================================
--- /trunk/psLib/src/image/Makefile	(revision 1652)
+++ /trunk/psLib/src/image/Makefile	(revision 1653)
@@ -3,6 +3,6 @@
 ##  Makefile:   collections
 ##
-##  $Revision: 1.3 $  $Name: not supported by cvs2svn $
-##  $Date: 2004-08-25 21:10:08 $
+##  $Revision: 1.4 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-08-28 01:18:28 $
 ##
 ##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -35,5 +35,6 @@
            psImageManip.o \
            psImageStats.o \
-           psImageFFT.o
+           psImageFFT.o \
+           psImageConvolve.o 
 
 OBJS = $(addprefix makedir/,$(SRC_OBJS))
Index: /trunk/psLib/src/image/psImage.c
===================================================================
--- /trunk/psLib/src/image/psImage.c	(revision 1652)
+++ /trunk/psLib/src/image/psImage.c	(revision 1653)
@@ -10,6 +10,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.41 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-08-27 19:05:40 $
+ *  @version $Revision: 1.42 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-28 01:18:28 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -17,10 +17,4 @@
  *  That is the routine used to generate matrices.
  */
-
-/******************************************************************************/
-
-/*  INCLUDE FILES                                                             */
-
-/******************************************************************************/
 
 #include <string.h>
@@ -33,10 +27,4 @@
 
 static void imageFree(psImage* image);
-
-/*****************************************************************************/
-
-/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
-
-/*****************************************************************************/
 
 psImage* psImageAlloc(unsigned int numCols,
@@ -52,5 +40,7 @@
     if (area < 1) {
         psError(__func__,
-                "Invalid value for number of rows or columns " "(numRows=%d, numCols=%d).", numRows, numCols);
+                "Invalid value for number of rows or columns "
+                "(numRows=%d, numCols=%d).",
+                numRows, numCols);
         return NULL;
     }
@@ -129,13 +119,6 @@
                         const psElemType type)
 {
-    int elementSize = PSELEMTYPE_SIZEOF(type);  // element
-
-    // size in
-    // bytes
-    int rowSize = numCols * elementSize;        // row
-
-    // size
-
-    // in bytes.
+    int elementSize = PSELEMTYPE_SIZEOF(type);  // element size in bytes
+    int rowSize = numCols * elementSize;        // row size in bytes.
 
     if (old == NULL) {
@@ -145,5 +128,6 @@
 
     if (old->type.dimen != PS_DIMEN_IMAGE) {
-        psError(__func__, "Can not realloc image because input is not an image.");
+        psError(__func__,
+                "Can not realloc image because input is not an image.");
         return NULL;
     }
@@ -166,9 +150,11 @@
 
     /* image already the right size/type? */
-    if (numCols == old->numCols && numRows == old->numRows && type == old->type.type) {
+    if (numCols == old->numCols && numRows == old->numRows &&
+            type == old->type.type) {
         return old;
     }
     // Resize the image buffer
-    old->rawDataBuffer = psRealloc(old->data.V[0], numCols * numRows * elementSize);
+    old->rawDataBuffer = psRealloc(old->data.V[0],
+                                   numCols * numRows * elementSize);
     old->data.V = (void **)psRealloc(old->data.V, numRows * sizeof(void *));
 
Index: /trunk/psLib/src/image/psImageConvolve.c
===================================================================
--- /trunk/psLib/src/image/psImageConvolve.c	(revision 1653)
+++ /trunk/psLib/src/image/psImageConvolve.c	(revision 1653)
@@ -0,0 +1,172 @@
+/*  @file  psImageConvolve.c
+ *
+ *  @brief Contains FFT transform related functions for psImage.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-28 01:18:28 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "psImageConvolve.h"
+#include "psImageFFT.h"
+#include "psMemory.h"
+#include "psLogMsg.h"
+#include "psError.h"
+
+static void freeKernel(psKernel* ptr);
+
+psKernel* psKernelAlloc(int xMin, int xMax, int yMin, int yMax)
+{
+    psKernel* result;
+    int numRows;
+    int numCols;
+
+    if (yMin > yMax) {
+        int temp = yMin;
+        yMin = yMax;
+        yMax = temp;
+
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "Found yMin > yMax (%d > %d).  Values swapped.",
+                 yMin, yMax);
+    }
+
+    if (xMin > xMax) {
+        int temp = xMin;
+        xMin = xMax;
+        xMax = temp;
+
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "Found xMin > xMax (%d > %d).  Values swapped.",
+                 xMin, xMax);
+    }
+
+    numRows = yMax - yMin + 1;
+    numCols = xMax - xMin + 1;
+
+    result = psAlloc(sizeof(psKernel));
+    result->xMin = xMin;
+    result->xMax = xMax;
+    result->yMin = yMin;
+    result->yMax = yMax;
+    result->p_data = psImageAlloc(numCols,numRows,PS_TYPE_F32);
+    result->p_kernelRows = psAlloc(sizeof(psF32*)*numRows);
+
+    psF32** kernelRows = result->p_kernelRows;
+    psF32** imageRows = result->p_data->data.F32;
+    for (int i = 0; i < numRows; i++) {
+        kernelRows[i] = imageRows[i] - xMin;
+    }
+    result->kernel = kernelRows - yMin;
+
+    p_psMemSetDeallocator(result,(psFreeFcn)freeKernel);
+
+    return result;
+}
+
+void freeKernel(psKernel* ptr)
+{
+    if (ptr != NULL) {
+        psFree(ptr->p_data);
+        psFree(ptr->p_kernelRows);
+    }
+}
+
+psKernel *psKernelGenerate(const psVector *xShifts, const psVector *yShifts)
+{
+    int x = 0;
+    int y = 0;
+    int xMin = 0;
+    int xMax = 0;
+    int yMin = 0;
+    int yMax = 0;
+    int length = 0;
+    psF32 relativeTime = 1.0f;            // fraction of total time for each shift clock
+    psKernel* result = NULL;
+    psF32** kernel = NULL;
+
+    // got non-NULL vectors?
+    if (xShifts == NULL || yShifts == NULL) {
+        psError(__func__,"Shift vectors can not be NULL.");
+        return NULL;
+    }
+
+    if (xShifts->type.type != yShifts->type.type) {
+        psError(__func__,"Shift vectors can not be different data types.");
+        return NULL;
+    }
+
+    // determine the usable length of the shift vector
+    if (xShifts->n != yShifts->n) {
+        psLogMsg(__func__,PS_LOG_WARN,"Shift vectors found to be different sizes.");
+        length = xShifts->n;
+        if (yShifts->n < length) {
+            length = yShifts->n;
+        }
+    } else {
+        length = xShifts->n;
+    }
+    relativeTime = 1 / (1+length); // 1+length 'cause we count origin before shift
+    // e.g., 1 time unit at origin + a time unit for each shift clock
+
+    #define KERNEL_GENERATE_CASE(TYPE) \
+case PS_TYPE_##TYPE: { \
+        ps##TYPE *xShiftData = xShifts->data.TYPE; \
+        ps##TYPE *yShiftData = yShifts->data.TYPE; \
+        for (int lcv = 0; lcv < length; lcv++) { \
+            x += xShiftData[lcv]; \
+            y += yShiftData[lcv]; \
+            if (x < xMin) { \
+                xMin = x; \
+            } else if (x > xMax) { \
+                xMax = x; \
+            } \
+            if (y < yMin) { \
+                yMin = y; \
+            } else if (y > yMax) { \
+                yMax = y; \
+            } \
+        } \
+        result = psKernelAlloc(xMin,xMax,yMin,yMax); \
+        kernel = result->kernel; \
+        \
+        kernel[0][0]+=relativeTime;    /* mark the original point as one exposure. */ \
+        \
+        x = 0; \
+        y = 0; \
+        for (int i = 0; i < length; i++) { \
+            x += xShiftData[i]; \
+            y += yShiftData[i]; \
+            kernel[y][x]+=relativeTime; \
+        } \
+    }
+
+    switch (xShifts->type.type) {
+        KERNEL_GENERATE_CASE(U8);
+        KERNEL_GENERATE_CASE(U16);
+        KERNEL_GENERATE_CASE(U32);
+        KERNEL_GENERATE_CASE(U64);
+        KERNEL_GENERATE_CASE(S8);
+        KERNEL_GENERATE_CASE(S16);
+        KERNEL_GENERATE_CASE(S32);
+        KERNEL_GENERATE_CASE(S64);
+        KERNEL_GENERATE_CASE(F32);
+        KERNEL_GENERATE_CASE(F64);
+        KERNEL_GENERATE_CASE(C32);
+        KERNEL_GENERATE_CASE(C64);
+    default:
+        psError(__func__,"Shift vector datatype not supported.");
+    }
+
+    return result;
+}
+
+psImage* psImageConvolve(psImage* out, const psImage* in, const psKernel* kernel, bool direct)
+{
+
+
+    return NULL;
+}
Index: /trunk/psLib/src/image/psImageConvolve.h
===================================================================
--- /trunk/psLib/src/image/psImageConvolve.h	(revision 1653)
+++ /trunk/psLib/src/image/psImageConvolve.h	(revision 1653)
@@ -0,0 +1,114 @@
+/** @file  psImageConvolve.h
+ *
+ *  @brief image convolution functionality
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-28 01:18:28 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_IMAGE_FFT_H
+#define PS_IMAGE_FFT_H
+
+#include<stdbool.h>
+
+#include "psImage.h"
+#include "psVector.h"
+
+/** A convolution kernel */
+typedef struct
+{
+    int xMin;                          ///< Most negative x index
+    int yMin;                          ///< Most negative y index
+    int xMax;                          ///< Most positive x index
+    int yMax;                          ///< Most positive y index
+    psF32** kernel;                    ///< Pointer to the kernel data
+    psF32** p_kernelRows;              ///< Pointer to the rows of the kernel data
+    psImage* p_data;                   ///< Kernel data, in the form of an image
+}
+psKernel;
+
+/** Allocates a convolution kernel of the given range
+ *
+ *  In order to perform a convolution, we need to define the convolution 
+ *  kernel. We need a more general object than a psImage so that we can 
+ *  incorporate the offset from the (0, 0) pixel to the (0, 0) value of the 
+ *  kernel. It might be convenient to allow both positive and negative 
+ *  indices to convey the positive and negative shifts. One might consider 
+ *  setting the x0 and y0 members of a psImage to the appropriate offsets, 
+ *  but this is not the purpose of these members, and doing so may affect the 
+ *  behavior of other psImage operations.
+ *
+ *  This construction allows the kernel member to use negative indices, while 
+ *  preserving the location of psMemBlocks relative to allocated memory.
+ *
+ *  The maximum extent of the kernel shifts shall be defined by the xMin, 
+ *  xMax, yMin and yMax members. Note that xMin and yMin, under normal 
+ *  circumstances, should be negative numbers. That is, 
+ *  myKernel->kernel[-3][-2] may be defined if yMin and xMin are equal to or 
+ *  more negative than -3 and -2, respectively.
+ *
+ *  In the event that one of the minimum values is greater than the 
+ *  corresponding maximum value, the function shall generate a warning, and 
+ *  the offending values shall be exchanged.
+ *
+ *  @return psKernel*          A new kernel object
+ */
+psKernel* psKernelAlloc(
+    int xMin,                          ///< Most negative x index
+    int xMax,                          ///< Most negative y index
+    int yMin,                          ///< Most positive x index
+    int yMax                           ///< Most positive y index
+);
+
+/** Generates a kernel given a list of shift values
+ *
+ *  Given a list of values (e.g., shifts made in the course of OT guiding), 
+ *  psKernelGenerate shall return the appropriate kernel.  The vectors xShifts 
+ *  and yShifts, which are a list of shifts relative to some starting point, 
+ *  will be supplied by the user. The elements of the vectors should be of an 
+ *  integer type; otherwise the values shall be truncated to integers. The 
+ *  output kernel shall be normalized such that the sum over the kernel is 
+ *  unity. 
+ *
+ *  If the vectors are not of the same number of elements, then the function 
+ *  shall generate a warning shall be generated, following which, the longer 
+ *  vector trimmed to the length of the shorter, and the function shall continue.
+ *
+ *  @return psKernel*    new Kernel object
+ */
+psKernel* psKernelGenerate(
+    const psVector* xShifts,           ///< list of shifts relative to a reference point
+    const psVector* yShifts            ///< list of shifts relative to a reference point
+);
+
+/** convolve an image with a kernel
+ *
+ *  Given an input image and the convolution kernel, psImageConvolve shall 
+ *  convolve the input image, in, with the kernel, kernel and return the 
+ *  convolved image, out.
+ * 
+ *  Two methods shall be available for the convolution: if direct is true, 
+ *  then the convolution shall be performed in real space (appropriate for 
+ *  small kernels); otherwise, the convolution shall be performed using Fast 
+ *  Fourier Transforms (FFTs; appropriate for larger kernels). The latter 
+ *  option involves padding the input image, copying the kernel into an image 
+ *  of the same size as the padded input image, performing an FFT on each, 
+ *  multiplying the FFTs, and performing an inverse FFT before trimming the 
+ *  image back to the original size.
+ *
+ *  @return psImage*  resulting image 
+ */
+psImage* psImageConvolve(
+    psImage* out,                      ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* in,                 ///< the psImage to convolve
+    const psKernel* kernel,            ///< kernel to colvolve with
+    bool direct                        ///< specifies method, true=direct convolution, false=fourier
+);
+
+#endif
Index: /trunk/psLib/src/imageops/psImageConvolve.c
===================================================================
--- /trunk/psLib/src/imageops/psImageConvolve.c	(revision 1653)
+++ /trunk/psLib/src/imageops/psImageConvolve.c	(revision 1653)
@@ -0,0 +1,172 @@
+/*  @file  psImageConvolve.c
+ *
+ *  @brief Contains FFT transform related functions for psImage.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-28 01:18:28 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "psImageConvolve.h"
+#include "psImageFFT.h"
+#include "psMemory.h"
+#include "psLogMsg.h"
+#include "psError.h"
+
+static void freeKernel(psKernel* ptr);
+
+psKernel* psKernelAlloc(int xMin, int xMax, int yMin, int yMax)
+{
+    psKernel* result;
+    int numRows;
+    int numCols;
+
+    if (yMin > yMax) {
+        int temp = yMin;
+        yMin = yMax;
+        yMax = temp;
+
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "Found yMin > yMax (%d > %d).  Values swapped.",
+                 yMin, yMax);
+    }
+
+    if (xMin > xMax) {
+        int temp = xMin;
+        xMin = xMax;
+        xMax = temp;
+
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "Found xMin > xMax (%d > %d).  Values swapped.",
+                 xMin, xMax);
+    }
+
+    numRows = yMax - yMin + 1;
+    numCols = xMax - xMin + 1;
+
+    result = psAlloc(sizeof(psKernel));
+    result->xMin = xMin;
+    result->xMax = xMax;
+    result->yMin = yMin;
+    result->yMax = yMax;
+    result->p_data = psImageAlloc(numCols,numRows,PS_TYPE_F32);
+    result->p_kernelRows = psAlloc(sizeof(psF32*)*numRows);
+
+    psF32** kernelRows = result->p_kernelRows;
+    psF32** imageRows = result->p_data->data.F32;
+    for (int i = 0; i < numRows; i++) {
+        kernelRows[i] = imageRows[i] - xMin;
+    }
+    result->kernel = kernelRows - yMin;
+
+    p_psMemSetDeallocator(result,(psFreeFcn)freeKernel);
+
+    return result;
+}
+
+void freeKernel(psKernel* ptr)
+{
+    if (ptr != NULL) {
+        psFree(ptr->p_data);
+        psFree(ptr->p_kernelRows);
+    }
+}
+
+psKernel *psKernelGenerate(const psVector *xShifts, const psVector *yShifts)
+{
+    int x = 0;
+    int y = 0;
+    int xMin = 0;
+    int xMax = 0;
+    int yMin = 0;
+    int yMax = 0;
+    int length = 0;
+    psF32 relativeTime = 1.0f;            // fraction of total time for each shift clock
+    psKernel* result = NULL;
+    psF32** kernel = NULL;
+
+    // got non-NULL vectors?
+    if (xShifts == NULL || yShifts == NULL) {
+        psError(__func__,"Shift vectors can not be NULL.");
+        return NULL;
+    }
+
+    if (xShifts->type.type != yShifts->type.type) {
+        psError(__func__,"Shift vectors can not be different data types.");
+        return NULL;
+    }
+
+    // determine the usable length of the shift vector
+    if (xShifts->n != yShifts->n) {
+        psLogMsg(__func__,PS_LOG_WARN,"Shift vectors found to be different sizes.");
+        length = xShifts->n;
+        if (yShifts->n < length) {
+            length = yShifts->n;
+        }
+    } else {
+        length = xShifts->n;
+    }
+    relativeTime = 1 / (1+length); // 1+length 'cause we count origin before shift
+    // e.g., 1 time unit at origin + a time unit for each shift clock
+
+    #define KERNEL_GENERATE_CASE(TYPE) \
+case PS_TYPE_##TYPE: { \
+        ps##TYPE *xShiftData = xShifts->data.TYPE; \
+        ps##TYPE *yShiftData = yShifts->data.TYPE; \
+        for (int lcv = 0; lcv < length; lcv++) { \
+            x += xShiftData[lcv]; \
+            y += yShiftData[lcv]; \
+            if (x < xMin) { \
+                xMin = x; \
+            } else if (x > xMax) { \
+                xMax = x; \
+            } \
+            if (y < yMin) { \
+                yMin = y; \
+            } else if (y > yMax) { \
+                yMax = y; \
+            } \
+        } \
+        result = psKernelAlloc(xMin,xMax,yMin,yMax); \
+        kernel = result->kernel; \
+        \
+        kernel[0][0]+=relativeTime;    /* mark the original point as one exposure. */ \
+        \
+        x = 0; \
+        y = 0; \
+        for (int i = 0; i < length; i++) { \
+            x += xShiftData[i]; \
+            y += yShiftData[i]; \
+            kernel[y][x]+=relativeTime; \
+        } \
+    }
+
+    switch (xShifts->type.type) {
+        KERNEL_GENERATE_CASE(U8);
+        KERNEL_GENERATE_CASE(U16);
+        KERNEL_GENERATE_CASE(U32);
+        KERNEL_GENERATE_CASE(U64);
+        KERNEL_GENERATE_CASE(S8);
+        KERNEL_GENERATE_CASE(S16);
+        KERNEL_GENERATE_CASE(S32);
+        KERNEL_GENERATE_CASE(S64);
+        KERNEL_GENERATE_CASE(F32);
+        KERNEL_GENERATE_CASE(F64);
+        KERNEL_GENERATE_CASE(C32);
+        KERNEL_GENERATE_CASE(C64);
+    default:
+        psError(__func__,"Shift vector datatype not supported.");
+    }
+
+    return result;
+}
+
+psImage* psImageConvolve(psImage* out, const psImage* in, const psKernel* kernel, bool direct)
+{
+
+
+    return NULL;
+}
Index: /trunk/psLib/src/imageops/psImageConvolve.h
===================================================================
--- /trunk/psLib/src/imageops/psImageConvolve.h	(revision 1653)
+++ /trunk/psLib/src/imageops/psImageConvolve.h	(revision 1653)
@@ -0,0 +1,114 @@
+/** @file  psImageConvolve.h
+ *
+ *  @brief image convolution functionality
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-28 01:18:28 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_IMAGE_FFT_H
+#define PS_IMAGE_FFT_H
+
+#include<stdbool.h>
+
+#include "psImage.h"
+#include "psVector.h"
+
+/** A convolution kernel */
+typedef struct
+{
+    int xMin;                          ///< Most negative x index
+    int yMin;                          ///< Most negative y index
+    int xMax;                          ///< Most positive x index
+    int yMax;                          ///< Most positive y index
+    psF32** kernel;                    ///< Pointer to the kernel data
+    psF32** p_kernelRows;              ///< Pointer to the rows of the kernel data
+    psImage* p_data;                   ///< Kernel data, in the form of an image
+}
+psKernel;
+
+/** Allocates a convolution kernel of the given range
+ *
+ *  In order to perform a convolution, we need to define the convolution 
+ *  kernel. We need a more general object than a psImage so that we can 
+ *  incorporate the offset from the (0, 0) pixel to the (0, 0) value of the 
+ *  kernel. It might be convenient to allow both positive and negative 
+ *  indices to convey the positive and negative shifts. One might consider 
+ *  setting the x0 and y0 members of a psImage to the appropriate offsets, 
+ *  but this is not the purpose of these members, and doing so may affect the 
+ *  behavior of other psImage operations.
+ *
+ *  This construction allows the kernel member to use negative indices, while 
+ *  preserving the location of psMemBlocks relative to allocated memory.
+ *
+ *  The maximum extent of the kernel shifts shall be defined by the xMin, 
+ *  xMax, yMin and yMax members. Note that xMin and yMin, under normal 
+ *  circumstances, should be negative numbers. That is, 
+ *  myKernel->kernel[-3][-2] may be defined if yMin and xMin are equal to or 
+ *  more negative than -3 and -2, respectively.
+ *
+ *  In the event that one of the minimum values is greater than the 
+ *  corresponding maximum value, the function shall generate a warning, and 
+ *  the offending values shall be exchanged.
+ *
+ *  @return psKernel*          A new kernel object
+ */
+psKernel* psKernelAlloc(
+    int xMin,                          ///< Most negative x index
+    int xMax,                          ///< Most negative y index
+    int yMin,                          ///< Most positive x index
+    int yMax                           ///< Most positive y index
+);
+
+/** Generates a kernel given a list of shift values
+ *
+ *  Given a list of values (e.g., shifts made in the course of OT guiding), 
+ *  psKernelGenerate shall return the appropriate kernel.  The vectors xShifts 
+ *  and yShifts, which are a list of shifts relative to some starting point, 
+ *  will be supplied by the user. The elements of the vectors should be of an 
+ *  integer type; otherwise the values shall be truncated to integers. The 
+ *  output kernel shall be normalized such that the sum over the kernel is 
+ *  unity. 
+ *
+ *  If the vectors are not of the same number of elements, then the function 
+ *  shall generate a warning shall be generated, following which, the longer 
+ *  vector trimmed to the length of the shorter, and the function shall continue.
+ *
+ *  @return psKernel*    new Kernel object
+ */
+psKernel* psKernelGenerate(
+    const psVector* xShifts,           ///< list of shifts relative to a reference point
+    const psVector* yShifts            ///< list of shifts relative to a reference point
+);
+
+/** convolve an image with a kernel
+ *
+ *  Given an input image and the convolution kernel, psImageConvolve shall 
+ *  convolve the input image, in, with the kernel, kernel and return the 
+ *  convolved image, out.
+ * 
+ *  Two methods shall be available for the convolution: if direct is true, 
+ *  then the convolution shall be performed in real space (appropriate for 
+ *  small kernels); otherwise, the convolution shall be performed using Fast 
+ *  Fourier Transforms (FFTs; appropriate for larger kernels). The latter 
+ *  option involves padding the input image, copying the kernel into an image 
+ *  of the same size as the padded input image, performing an FFT on each, 
+ *  multiplying the FFTs, and performing an inverse FFT before trimming the 
+ *  image back to the original size.
+ *
+ *  @return psImage*  resulting image 
+ */
+psImage* psImageConvolve(
+    psImage* out,                      ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* in,                 ///< the psImage to convolve
+    const psKernel* kernel,            ///< kernel to colvolve with
+    bool direct                        ///< specifies method, true=direct convolution, false=fourier
+);
+
+#endif
Index: /trunk/psLib/src/mathtypes/psImage.c
===================================================================
--- /trunk/psLib/src/mathtypes/psImage.c	(revision 1652)
+++ /trunk/psLib/src/mathtypes/psImage.c	(revision 1653)
@@ -10,6 +10,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.41 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-08-27 19:05:40 $
+ *  @version $Revision: 1.42 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-28 01:18:28 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -17,10 +17,4 @@
  *  That is the routine used to generate matrices.
  */
-
-/******************************************************************************/
-
-/*  INCLUDE FILES                                                             */
-
-/******************************************************************************/
 
 #include <string.h>
@@ -33,10 +27,4 @@
 
 static void imageFree(psImage* image);
-
-/*****************************************************************************/
-
-/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
-
-/*****************************************************************************/
 
 psImage* psImageAlloc(unsigned int numCols,
@@ -52,5 +40,7 @@
     if (area < 1) {
         psError(__func__,
-                "Invalid value for number of rows or columns " "(numRows=%d, numCols=%d).", numRows, numCols);
+                "Invalid value for number of rows or columns "
+                "(numRows=%d, numCols=%d).",
+                numRows, numCols);
         return NULL;
     }
@@ -129,13 +119,6 @@
                         const psElemType type)
 {
-    int elementSize = PSELEMTYPE_SIZEOF(type);  // element
-
-    // size in
-    // bytes
-    int rowSize = numCols * elementSize;        // row
-
-    // size
-
-    // in bytes.
+    int elementSize = PSELEMTYPE_SIZEOF(type);  // element size in bytes
+    int rowSize = numCols * elementSize;        // row size in bytes.
 
     if (old == NULL) {
@@ -145,5 +128,6 @@
 
     if (old->type.dimen != PS_DIMEN_IMAGE) {
-        psError(__func__, "Can not realloc image because input is not an image.");
+        psError(__func__,
+                "Can not realloc image because input is not an image.");
         return NULL;
     }
@@ -166,9 +150,11 @@
 
     /* image already the right size/type? */
-    if (numCols == old->numCols && numRows == old->numRows && type == old->type.type) {
+    if (numCols == old->numCols && numRows == old->numRows &&
+            type == old->type.type) {
         return old;
     }
     // Resize the image buffer
-    old->rawDataBuffer = psRealloc(old->data.V[0], numCols * numRows * elementSize);
+    old->rawDataBuffer = psRealloc(old->data.V[0],
+                                   numCols * numRows * elementSize);
     old->data.V = (void **)psRealloc(old->data.V, numRows * sizeof(void *));
 
Index: /trunk/psLib/src/types/psMetadata.c
===================================================================
--- /trunk/psLib/src/types/psMetadata.c	(revision 1652)
+++ /trunk/psLib/src/types/psMetadata.c	(revision 1653)
@@ -12,6 +12,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.25 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2004-08-25 20:21:25 $
+*  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-08-28 01:18:28 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -482,5 +482,4 @@
     entry = (psMetadataItem* ) psHashLookup(mdTable, key);
     if (entry == NULL) {
-        psError(__func__, "Could not find metadata item. Key: %s", key);
         return NULL;
     }
@@ -567,9 +566,4 @@
     }
 
-    // Match not found
-    if (entry == NULL) {
-        psError(__func__, "Couldn't find metadata item");
-    }
-
     return entry;
 }
@@ -605,9 +599,4 @@
             return psListGetPrevious(mdList);
         }
-    }
-
-    // Match not found
-    if (entry == NULL) {
-        psError(__func__, "Couldn't find metadata item", match);
     }
 
