Index: trunk/psLib/src/imageops/psImageConvolve.c
===================================================================
--- trunk/psLib/src/imageops/psImageConvolve.c	(revision 1863)
+++ trunk/psLib/src/imageops/psImageConvolve.c	(revision 1936)
@@ -5,6 +5,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-09-23 18:30:57 $
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-30 21:01:09 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -15,4 +15,5 @@
 #include "psImageConvolve.h"
 #include "psImageFFT.h"
+#include "psImageExtraction.h"
 #include "psMatrixVectorArithmetic.h"
 #include "psMemory.h"
@@ -21,4 +22,6 @@
 
 #include "psImageErrors.h"
+
+#define FOURIER_PADDING 32 /* padding amount in every side of the image for fourier convolution */
 
 static void freeKernel(psKernel* ptr);
@@ -32,22 +35,22 @@
     // following is explicitly spelled out in the SDRS as a requirement
     if (yMin > yMax) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "Specified yMin, %d, was greater than yMax, %d.  Values swapped.",
+                 yMin, yMax);
+
         int temp = yMin;
         yMin = yMax;
         yMax = temp;
-
-        psLogMsg(__func__, PS_LOG_WARN,
-                 "Found yMin > yMax (%d > %d).  Values swapped.",
-                 yMin, yMax);
     }
 
     // following is explicitly spelled out in the SDRS as a requirement
     if (xMin > xMax) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "Specified xMin, %d, was greater than xMax, %d.  Values swapped.",
+                 xMin, xMax);
+
         int temp = xMin;
         xMin = xMax;
         xMax = temp;
-
-        psLogMsg(__func__, PS_LOG_WARN,
-                 "Found xMin > xMax (%d > %d).  Values swapped.",
-                 xMin, xMax);
     }
 
@@ -295,11 +298,12 @@
     } else {
         // fourier convolution
+        int paddedCols = numCols+2*FOURIER_PADDING;
+        int paddedRows = numRows+2*FOURIER_PADDING;
+
+        // check to see if kernel is smaller, otherwise padding it up will fail.
         int kRows = kernel->image->numRows;
         int kCols = kernel->image->numCols;
-        int x0 = (numCols - kCols) / 2;
-        int y0 = (numRows - kRows) / 2;
-        psImage* paddedKernel;
-
-        // check to see if kernel is smaller, otherwise padding it up will fail.
+        int x0 = (paddedCols - kCols) / 2;
+        int y0 = (paddedRows - kRows) / 2;
         if (x0 < 0 || y0 < 0) {
             psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConvolve",
@@ -312,7 +316,30 @@
         }
 
-        // pad the kernel to the same size of image
-        paddedKernel = psImageAlloc(numCols,numRows,PS_TYPE_KERNEL);
-        memset(paddedKernel->data.V,0,sizeof(psKernelType)*numCols*numRows); // zeroize image
+        // pad the image
+        psImage* paddedImage = psImageAlloc(paddedCols,paddedRows,in->type.type);
+        int elementSize = PSELEMTYPE_SIZEOF(in->type.type);
+
+        // zero out padded area on top and bottom
+        memset(paddedImage->data.U8[0],0,FOURIER_PADDING*paddedCols*elementSize);
+        memset(paddedImage->data.U8[FOURIER_PADDING+numRows-1],0,FOURIER_PADDING*paddedCols*elementSize);
+
+        // fill in the image-containing rows.
+        int sidePaddingSize = FOURIER_PADDING*elementSize;
+        int imageRowSize = numCols*elementSize;
+        psU8* paddedData = paddedImage->data.U8[FOURIER_PADDING];
+        for (int row=0;row<numRows;row++) {
+            // zero out padded area on left edge.
+            memset(paddedData,0,sidePaddingSize);
+            paddedData += sidePaddingSize;
+            memcpy(paddedData,in->data.U8[row],imageRowSize);
+            paddedData += imageRowSize;
+            // zero out padded area on right edge.
+            memset(paddedData,0,sidePaddingSize);
+            paddedData += sidePaddingSize;
+        }
+
+        // pad the kernel to the same size of paddedImage
+        psImage* paddedKernel = psImageAlloc(paddedCols,paddedRows,PS_TYPE_KERNEL);
+        memset(paddedKernel->data.U8[0],0,sizeof(psKernelType)*numCols*numRows); // zero-out image
         for (int row=0;row<kRows;row++) {
             psKernelType* padRow = paddedKernel->data.PS_TYPE_KERNEL_DATA[row+y0];
@@ -332,6 +359,5 @@
         }
 
-
-        psImage* inFourier = psImageFFT(NULL, in, PS_FFT_FORWARD);
+        psImage* inFourier = psImageFFT(NULL, paddedImage, PS_FFT_FORWARD);
         if (inFourier == NULL) {
             psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConvolve",
@@ -343,5 +369,5 @@
 
         // convolution in fourier domain is just a pixel-wise multiplication
-        psImage* outFourier = psImageAlloc(numCols,numRows,inFourier->type.type);
+        psImage* outFourier = psImageAlloc(paddedCols,paddedRows,inFourier->type.type);
         psBinaryOp(outFourier,inFourier,"*",kernelFourier);
 
@@ -355,10 +381,16 @@
         }
 
-        // since our image was real to start, the result is real
-        out = psImageReal(out,complexOut);
-
-        psFree(complexOut);
+        // subset out the padded area now.
+        psImage* complexOutSansPad = psImageSubset(complexOut,
+                                     FOURIER_PADDING,FOURIER_PADDING,
+                                     FOURIER_PADDING+numCols,FOURIER_PADDING+numRows);
+
+        // since our image was real, the result is to be real as well
+        out = psImageReal(out,complexOutSansPad);
+
+        psFree(complexOut); // frees complexOutSansPad, as it is a child.
         psFree(kernelFourier);
         psFree(inFourier);
+        psFree(paddedImage);
         psFree(paddedKernel);
 
