Index: trunk/psLib/src/fft/psImageFFT.c
===================================================================
--- trunk/psLib/src/fft/psImageFFT.c	(revision 17377)
+++ trunk/psLib/src/fft/psImageFFT.c	(revision 19058)
@@ -6,6 +6,6 @@
 /// @author Robert DeSonia, MHPCC
 ///
-/// @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
-/// @date $Date: 2008-04-08 01:25:42 $
+/// @version $Revision: 1.27 $ $Name: not supported by cvs2svn $
+/// @date $Date: 2008-08-14 03:23:13 $
 ///
 /// Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -20,4 +20,5 @@
 #include <complex.h>
 #include <fftw3.h>
+#include <pthread.h>
 
 #include "psAssert.h"
@@ -28,6 +29,18 @@
 #include "psImageStructManip.h"
 #include "psImageConvolve.h"
+#include "psThread.h"
+#include "psFFT.h"
 #include "psImageFFT.h"
 
+// Lock FFTW access
+#define FFTW_LOCK \
+if (threaded) { \
+    psFFTLock(); \
+}
+// Unlock FFTW access
+#define FFTW_UNLOCK \
+if (threaded) { \
+    psFFTUnlock(); \
+}
 
 #define FFTW_PLAN_RIGOR FFTW_ESTIMATE   // How rigorous the FFTW planning is
@@ -42,9 +55,13 @@
     PS_ASSERT_PTR_NON_NULL(imag, false);
 
+    bool threaded = psThreadPoolSize(); // Are we running threaded?
+
     // Make sure the system-level wisdom information is imported.
+    FFTW_LOCK;
     if (!fftwWisdomImported) {
         fftwf_import_system_wisdom();
         fftwWisdomImported = true;
     }
+    FFTW_UNLOCK;
 
     int numCols = in->numCols;          // Number of columns
@@ -64,8 +81,16 @@
 
     // Do the FFT
+
+    FFTW_LOCK;
     fftwf_complex *out = fftwf_malloc((numCols/2 + 1) * numRows * sizeof(fftwf_complex)); // Output data
     fftwf_plan plan = fftwf_plan_dft_r2c_2d(numRows, numCols, input, out, FFTW_PLAN_RIGOR);
+    FFTW_UNLOCK;
+
     fftwf_execute(plan);
+
+    FFTW_LOCK;
     fftwf_destroy_plan(plan);
+    FFTW_UNLOCK;
+
     psFree(input);
 
@@ -87,5 +112,8 @@
         }
     }
+
+    FFTW_LOCK;
     fftwf_free(out);
+    FFTW_UNLOCK;
 
     return true;
@@ -101,4 +129,6 @@
     PS_ASSERT_PTR_NON_NULL(out, false);
 
+    bool threaded = psThreadPoolSize(); // Are we running threaded?
+
     int numCols = real->numCols;        // Number of columns
     int numRows = real->numRows;        // Number of rows
@@ -120,14 +150,17 @@
     }
 
-
     // Make sure the system-level wisdom information is imported.
+    FFTW_LOCK;
     if (!fftwWisdomImported) {
         fftwf_import_system_wisdom();
         fftwWisdomImported = true;
     }
+    FFTW_UNLOCK;
 
     // Stuff the real and imaginary parts in
     psF32 *target = psAlloc(2 * numCols * numRows * PSELEMTYPE_SIZEOF(PS_TYPE_F32)); // Target for FFTW
+    FFTW_LOCK;
     fftwf_complex *in = fftwf_malloc(numCols * numRows * sizeof(fftwf_complex)); // Input data
+    FFTW_UNLOCK;
 
     for (int y = 0, index = 0; y < numRows; y++) {
@@ -145,8 +178,14 @@
 
     // Do the FFT
+    FFTW_LOCK;
     fftwf_plan plan = fftwf_plan_dft_c2r_2d(numRows, origCols, in, target, FFTW_PLAN_RIGOR);
+    FFTW_UNLOCK;
+
     fftwf_execute(plan);
+
+    FFTW_LOCK;
     fftwf_destroy_plan(plan);
     fftwf_free(in);
+    FFTW_UNLOCK;
 
     // Copy the target pixels into the output
@@ -288,4 +327,6 @@
     }
 
+    bool threaded = psThreadPoolSize(); // Are we running threaded?
+
     int numCols = in->numCols, numRows = in->numRows; // Size of image
     int xMin = kernel->xMin, xMax = kernel->xMax, yMin = kernel->yMin, yMax = kernel->yMax; // Kernel sizes
@@ -304,5 +345,7 @@
 
     // Create data array containing the padded image and padded kernel
+    FFTW_LOCK;
     psF32 *data = fftwf_malloc(2 * numPadded * PSELEMTYPE_SIZEOF(PS_TYPE_F32)); // Data for FFTW
+    FFTW_UNLOCK;
     psF32 *dataPtr = data;              // Pointer into FFTW data
     psF32 **imageData = in->data.F32;   // Pointer into image data
@@ -317,5 +360,5 @@
     memset(dataPtr, 0, (paddedRows - numRows) * paddedCols * PSELEMTYPE_SIZEOF(PS_TYPE_F32));
 
-#if 1
+#if 0
     {
         // Use this for inspecting the result of copying the image
@@ -379,5 +422,5 @@
     }
 
-#if 1
+#if 0
     {
         // Use this for inspecting the result of copying the kernel
@@ -409,12 +452,21 @@
     // Do the forward FFT
     // Note that the FFT images have different size from the input
+    FFTW_LOCK;
     fftwf_complex *fft = fftwf_malloc(2 * (paddedCols/2 + 1) * paddedRows * sizeof(fftwf_complex)); // FFT
+    FFTW_UNLOCK;
     int size[] = { paddedRows, paddedCols }; // Size of transforms
     int fftCols = paddedCols/2 + 1, fftRows = paddedRows; // Size of FFT images
     int fftPixels = fftCols * fftRows;  // Number of pixels in FFT image
+
+    FFTW_LOCK;
     fftwf_plan forward = fftwf_plan_many_dft_r2c(2, size, 2, data, NULL, 1, paddedCols * paddedRows,
                                                  fft, NULL, 1, fftPixels, FFTW_PLAN_RIGOR);
+    FFTW_UNLOCK;
+
     fftwf_execute(forward);
+
+    FFTW_LOCK;
     fftwf_destroy_plan(forward);
+    FFTW_UNLOCK;
 
     // Multiply the two transforms
@@ -434,8 +486,14 @@
 
     // Do the backward FFT
+    FFTW_LOCK;
     fftwf_plan backward = fftwf_plan_dft_c2r_2d(paddedRows, paddedCols, fft, data, FFTW_PLAN_RIGOR);
+    FFTW_UNLOCK;
+
     fftwf_execute(backward);
+
+    FFTW_LOCK;
     fftwf_destroy_plan(backward);
     fftwf_free(fft);
+    FFTW_UNLOCK;
 
     // Copy into the target, without the padding
@@ -446,5 +504,8 @@
         memcpy(*outData, dataPtr, goodBytes);
     }
+
+    FFTW_LOCK;
     fftwf_free(data);
+    FFTW_UNLOCK;
 
     return out;
