Index: trunk/psLib/src/image/psImageConvolve.c
===================================================================
--- trunk/psLib/src/image/psImageConvolve.c	(revision 2273)
+++ trunk/psLib/src/image/psImageConvolve.c	(revision 2375)
@@ -5,6 +5,6 @@
  *  @author Robert DeSonia, MHPCC
  *
- *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2004-11-04 01:05:00 $
+ *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-11-16 20:00:21 $
  *
  *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
@@ -93,8 +93,10 @@
                            psBool relative)
 {
-    psS32 x = 0;
-    psS32 y = 0;
-    psS32 t = 0;
-    psS32 deltaT;
+    psS32 lastX;
+    psS32 lastY;
+    psS32 lastT;
+    psS32 x;
+    psS32 y;
+    psS32 t;
     psS32 oldX;
     psS32 oldY;
@@ -148,17 +150,11 @@
         ps##TYPE *xShiftData = xShifts->data.TYPE; \
         ps##TYPE *yShiftData = yShifts->data.TYPE; \
-        x = 0; \
-        y = 0; \
-        t = 0; \
-        for (psS32 lcv = 0; lcv < length; lcv++) { \
-            if (relative) { \
-                x += xShiftData[lcv]; \
-                y += yShiftData[lcv]; \
-                t += tShiftData[lcv]; \
-            } else { \
-                x = xShiftData[lcv]; \
-                y = yShiftData[lcv]; \
-                t = tShiftData[lcv]; \
-            } \
+        lastX =  xShiftData[length-1]; \
+        lastY =  yShiftData[length-1]; \
+        \
+        for (int lcv = 0; lcv < length; lcv++) { \
+            x = lastX - xShiftData[lcv]; \
+            y = lastY - yShiftData[lcv]; \
+            \
             if (x < xMin) { \
                 xMin = x; \
@@ -172,51 +168,108 @@
             } \
         } \
+        \
+        normalizeTime = 1.0 / (psKernelType)(lastT - tShiftData[0]); \
         result = psKernelAlloc(xMin,xMax,yMin,yMax); \
         kernel = result->kernel; \
         \
-        normalizeTime = 1.0 / (psKernelType)(t); \
+        lastT = 0; \
+        for (int i = 0; i < length; i++) { \
+            t = tShiftData[i] - lastT; \
+            x = lastX - xShiftData[i]; \
+            y = lastY - yShiftData[i]; \
+            \
+            kernel[y][x] += (psKernelType)t * normalizeTime; \
+            lastT = t; \
+        } \
+        break; \
+    }
+
+    #define RELATIVE_KERNEL_GENERATE_CASE(TYPE) \
+case PS_TYPE_##TYPE: { \
+        ps##TYPE *tShiftData = tShifts->data.TYPE; \
+        ps##TYPE *xShiftData = xShifts->data.TYPE; \
+        ps##TYPE *yShiftData = yShifts->data.TYPE; \
+        \
         x = 0; \
         y = 0; \
         t = 0; \
-        for (psS32 i = 0; i < length; i++) { \
-            deltaT = t; \
-            oldX = x; \
-            oldY = y; \
-            if (relative) { \
-                t += tShiftData[i]; \
-                x += xShiftData[i]; \
-                y += yShiftData[i]; \
-            } else { \
-                t = tShiftData[i]; \
-                x = xShiftData[i]; \
-                y = yShiftData[i]; \
+        \
+        for (int lcv = length-1; lcv >= 0; lcv--) { \
+            t += tShiftData[lcv]; \
+            \
+            if (x < xMin) { \
+                xMin = x; \
+            } else if (x > xMax) { \
+                xMax = x; \
             } \
-            deltaT = t - deltaT; \
+            if (y < yMin) { \
+                yMin = y; \
+            } else if (y > yMax) { \
+                yMax = y; \
+            } \
+            x += xShiftData[lcv]; \
+            y += yShiftData[lcv]; \
             \
-            kernel[oldY][oldX] += deltaT * normalizeTime; \
+        } \
+        result = psKernelAlloc(xMin,xMax,yMin,yMax); \
+        kernel = result->kernel; \
+        \
+        normalizeTime = 1.0 / (psKernelType)t; \
+        x = 0; \
+        y = 0; \
+        for (psS32 i = length-1; i >= 0; i--) { \
+            kernel[y][x] += (psKernelType)(tShiftData[i]) * normalizeTime; \
+            x += xShiftData[i]; \
+            y += yShiftData[i]; \
+            \
         } \
         break; \
     }
 
-    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: {
-            char* typeStr;
-            PS_TYPE_NAME(typeStr,xShifts->type.type);
-            psError(PS_ERR_BAD_PARAMETER_TYPE, true,
-                    PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
-                    typeStr);
+    if (relative) {
+        switch (xShifts->type.type) {
+            RELATIVE_KERNEL_GENERATE_CASE(U8);
+            RELATIVE_KERNEL_GENERATE_CASE(U16);
+            RELATIVE_KERNEL_GENERATE_CASE(U32);
+            RELATIVE_KERNEL_GENERATE_CASE(U64);
+            RELATIVE_KERNEL_GENERATE_CASE(S8);
+            RELATIVE_KERNEL_GENERATE_CASE(S16);
+            RELATIVE_KERNEL_GENERATE_CASE(S32);
+            RELATIVE_KERNEL_GENERATE_CASE(S64);
+            RELATIVE_KERNEL_GENERATE_CASE(F32);
+            RELATIVE_KERNEL_GENERATE_CASE(F64);
+            RELATIVE_KERNEL_GENERATE_CASE(C32);
+            RELATIVE_KERNEL_GENERATE_CASE(C64);
+
+        default: {
+                char* typeStr;
+                PS_TYPE_NAME(typeStr,xShifts->type.type);
+                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                        PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                        typeStr);
+            }
+        }
+    } else {
+        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: {
+                char* typeStr;
+                PS_TYPE_NAME(typeStr,xShifts->type.type);
+                psError(PS_ERR_BAD_PARAMETER_TYPE, true,
+                        PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                        typeStr);
+            }
         }
     }
