Index: trunk/psLib/src/image/psImage.c
===================================================================
--- trunk/psLib/src/image/psImage.c	(revision 3442)
+++ trunk/psLib/src/image/psImage.c	(revision 3446)
@@ -9,6 +9,6 @@
  *  @author Ross Harman, MHPCC
  *
- *  @version $Revision: 1.60 $ $Name: not supported by cvs2svn $
- *  @date $Date: 2005-03-17 19:02:01 $
+ *  @version $Revision: 1.61 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2005-03-18 02:35:14 $
  *
  *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -26,4 +26,8 @@
 
 #include "psImageErrors.h"
+
+#define SQUARE(x) ((x)*(x))
+#define MIN(x,y) (((x) > (y)) ? (y) : (x))
+#define MAX(x,y) (((x) > (y)) ? (x) : (y))
 
 static void imageFree(psImage* image)
@@ -116,6 +120,4 @@
 }
 
-
-
 psRegion* psRegionFromString(char* region)
 {
@@ -165,5 +167,4 @@
     return psStringCopy(tmpText);
 }
-
 
 psImage* psImageRecycle(psImage* old,
@@ -428,5 +429,5 @@
     }
 
-    #define PSIMAGE_PIXEL_INTERPOLATE_CASE(TYPE)                     \
+    #define PSIMAGE_PIXEL_INTERPOLATE_CASE(TYPE)                             \
 case PS_TYPE_##TYPE:                                                 \
     switch (mode) {                                                  \
@@ -449,4 +450,13 @@
                 unexposedValue);                                     \
         break;                                                       \
+    case PS_INTERPOLATE_BILINEAR_VARIANCE:                           \
+        return p_psImagePixelInterpolateBILINEAR_VARIANCE_##TYPE(    \
+                input,                                               \
+                x,                                                   \
+                y,                                                   \
+                mask,                                                \
+                maskVal,                                             \
+                unexposedValue);                                     \
+        break;                                                       \
     default:                                                         \
         psError(PS_ERR_BAD_PARAMETER_VALUE,true,                     \
@@ -454,5 +464,5 @@
                 mode);                                               \
     }                                                                \
-    break
+    break;
 
     switch (input->type.type) {
@@ -481,11 +491,12 @@
 }
 
-#define PSIMAGE_PIXEL_INTERPOLATE_FLAT(TYPE) \
-inline psF64 p_psImagePixelInterpolateFLAT_##TYPE(const psImage* input, \
+#define PSIMAGE_PIXEL_INTERPOLATE_FLAT(TYPE,RETURNTYPE) \
+inline RETURNTYPE p_psImagePixelInterpolateFLAT_##TYPE( \
+        const psImage* input, \
         float x, \
         float y, \
         const psImage* mask, \
         psU32 maskVal, \
-        psF64 unexposedValue) \
+        RETURNTYPE unexposedValue) \
 { \
     psS32 intX = (psS32) round((psF64)(x) - 0.5 + FLT_EPSILON); \
@@ -506,49 +517,25 @@
 }
 
-#define PSIMAGE_PIXEL_INTERPOLATE_FLAT_COMPLEX(TYPE) \
-inline psC64 p_psImagePixelInterpolateFLAT_##TYPE(const psImage* input, \
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(U8,psF64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(U16,psF64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(U32,psF64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(U64,psF64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(S8,psF64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(S16,psF64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(S32,psF64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(S64,psF64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(F32,psF64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(F64,psF64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(C32,psC64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(C64,psC64)
+
+#define PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(TYPE, RETURNTYPE, SUFFIX, FRACFUNC) \
+inline RETURNTYPE p_psImagePixelInterpolateBILINEAR_##SUFFIX( \
+        const psImage* input, \
         float x, \
         float y, \
         const psImage* mask, \
         psU32 maskVal, \
-        psC64 unexposedValue) \
-{ \
-    psS32 intX = (psS32) round((psF64)(x) - 0.5); \
-    psS32 intY = (psS32) round((psF64)(y) - 0.5); \
-    psS32 lastX = input->numCols - 1; \
-    psS32 lastY = input->numRows - 1; \
-    \
-    if ((intX < 0) || \
-            (intX > lastX) || \
-            (intY < 0) || \
-            (intY > lastY) || \
-            ( (mask!=NULL) && \
-              ((mask->data.PS_TYPE_MASK_DATA[intY][intX] & maskVal) != 0) ) ) { \
-        return unexposedValue; \
-    } \
-    \
-    return input->data.TYPE[intY][intX]; \
-}
-
-PSIMAGE_PIXEL_INTERPOLATE_FLAT(U8)
-PSIMAGE_PIXEL_INTERPOLATE_FLAT(U16)
-PSIMAGE_PIXEL_INTERPOLATE_FLAT(U32)
-PSIMAGE_PIXEL_INTERPOLATE_FLAT(U64)
-PSIMAGE_PIXEL_INTERPOLATE_FLAT(S8)
-PSIMAGE_PIXEL_INTERPOLATE_FLAT(S16)
-PSIMAGE_PIXEL_INTERPOLATE_FLAT(S32)
-PSIMAGE_PIXEL_INTERPOLATE_FLAT(S64)
-PSIMAGE_PIXEL_INTERPOLATE_FLAT(F32)
-PSIMAGE_PIXEL_INTERPOLATE_FLAT(F64)
-PSIMAGE_PIXEL_INTERPOLATE_FLAT_COMPLEX(C32)
-PSIMAGE_PIXEL_INTERPOLATE_FLAT_COMPLEX(C64)
-
-#define PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(TYPE) \
-inline psF64 p_psImagePixelInterpolateBILINEAR_##TYPE(const psImage* input, \
-        float x, \
-        float y, \
-        const psImage* mask, \
-        psU32 maskVal, \
-        psF64 unexposedValue) \
+        RETURNTYPE unexposedValue) \
 { \
     double floorX = floor((psF64)(x) - 0.5); \
@@ -597,14 +584,14 @@
     if (valid00 && valid10 && valid01 && valid11) { \
         /* formula from the ADD */ \
-        psF64 rx = V00 + (V10-V00)*fracX; \
-        return (rx + (V01 + (V11 - V01) * fracX - rx) * fracY); \
+        return V00*FRACFUNC((1.0-fracX)*(1.0-fracY)) + V10*FRACFUNC(fracX*(1.0-fracY)) + \
+               V01*FRACFUNC(fracY*(1.0-fracX)) + V11*FRACFUNC(fracX*fracY); \
     } \
     \
     /* OK, at least one pixel is not valid - need to do it piecemeal */ \
     \
-    psF64 V0 = 0.0; \
+    RETURNTYPE V0 = 0.0; \
     psBool valid0 = true; \
     if (valid00 && valid10) { \
-        V0 = V00*(1-fracX)+V10*fracX; \
+        V0 = V00*FRACFUNC(1-fracX)+V10*FRACFUNC(fracX); \
     } else if (valid00) { \
         V0 = V00; \
@@ -615,8 +602,8 @@
     } \
     \
-    psF64 V1 = 0.0; \
+    RETURNTYPE V1 = 0.0; \
     psBool valid1 = true; \
     if (valid01 && valid11) { \
-        V1 = V01*(1-fracX)+V11*fracX; \
+        V1 = V01*FRACFUNC(1-fracX)+V11*FRACFUNC(fracX); \
     } else if (valid01) { \
         V1 = V01; \
@@ -628,5 +615,5 @@
     \
     if (valid0 && valid1) { \
-        return ( V0*(1-fracY) + V1*fracY ); \
+        return V0*FRACFUNC(1-fracY) + V1*FRACFUNC(fracY); \
     } else if (valid0) { \
         return V0; \
@@ -638,108 +625,28 @@
 }
 
-#define PSIMAGE_PIXEL_INTERPOLATE_BILINEAR_COMPLEX(TYPE) \
-inline psC64 p_psImagePixelInterpolateBILINEAR_##TYPE(const psImage* input, \
-        float x, \
-        float y, \
-        const psImage* mask, \
-        psU32 maskVal, \
-        psC64 unexposedValue) \
-{ \
-    double floorX = floor((psF64)(x) - 0.5); \
-    double floorY = floor((psF64)(y) - 0.5); \
-    psF64 fracX = x - 0.5 - floorX; \
-    psF64 fracY = y - 0.5 - floorY; \
-    psS32 intFloorX = (psS32) floorX; \
-    psS32 intFloorY = (psS32) floorY; \
-    psS32 lastX = input->numCols - 1; \
-    psS32 lastY = input->numRows - 1; \
-    ps##TYPE V00 = 0; \
-    ps##TYPE V01 = 0; \
-    ps##TYPE V10 = 0; \
-    ps##TYPE V11 = 0; \
-    psBool valid00 = false; \
-    psBool valid01 = false; \
-    psBool valid10 = false; \
-    psBool valid11 = false; \
-    \
-    if (intFloorY >= 0 && intFloorY <= lastY) { \
-        if (intFloorX >= 0 && intFloorX <= lastX) { \
-            V00 = input->data.TYPE[intFloorY][intFloorX]; \
-            valid00 = (mask == NULL) || \
-                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY][intFloorX] & maskVal) == 0); \
-        } \
-        if (intFloorX >= -1 && intFloorX < lastX) { \
-            V10 = input->data.TYPE[intFloorY][intFloorX+1]; \
-            valid10 = (mask == NULL) || \
-                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY][intFloorX+1] & maskVal) == 0); \
-        } \
-    } \
-    if (intFloorY >= -1 && intFloorY < lastY) { \
-        if (intFloorX >= 0 && intFloorX <= lastX) { \
-            V01 = input->data.TYPE[intFloorY+1][intFloorX]; \
-            valid01 = (mask == NULL) || \
-                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY+1][intFloorX] & maskVal) == 0); \
-        } \
-        if (intFloorX >= -1 && intFloorX < lastX) { \
-            V11 = input->data.TYPE[intFloorY+1][intFloorX+1]; \
-            valid11 = (mask == NULL) || \
-                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY+1][intFloorX+1] & maskVal) == 0); \
-        } \
-    } \
-    \
-    /* cover likely case of all pixels being valid */  \
-    if (valid00 && valid10 && valid01 && valid11) { \
-        /* formula from the ADD */ \
-        psC64 rx = V00 + (V10-V00)*fracX; \
-        return (rx + (V01 + (V11 - V01) * fracX - rx) * fracY); \
-    } \
-    \
-    /* OK, at least one pixel is not valid - need to do it piecemeal */ \
-    \
-    psC64 V0 = 0; \
-    psBool valid0 = true; \
-    if (valid00 && valid10) { \
-        V0 = V00*(1-fracX)+V10*fracX; \
-    } else if (valid00) { \
-        V0 = V00; \
-    } else if (valid10) { \
-        V0 = V10; \
-    } else { \
-        valid0 = false; \
-    } \
-    \
-    psC64 V1 = 0; \
-    psBool valid1 = true; \
-    if (valid01 && valid11) { \
-        V0 = V01*(1-fracX)+V11*fracX; \
-    } else if (valid01) { \
-        V0 = V01; \
-    } else if (valid11) { \
-        V0 = V11; \
-    } else { \
-        valid1 = false; \
-    } \
-    \
-    if (valid0 && valid1) { \
-        return ( V0*(1-fracY) + V1*fracY ); \
-    } else if (valid0) { \
-        return V0; \
-    } else if (valid1) { \
-        return V1; \
-    } \
-    \
-    return unexposedValue; \
-}
-
-PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U8)
-PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U16)
-PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U32)
-PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U64)
-PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S8)
-PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S16)
-PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S32)
-PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S64)
-PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F32)
-PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F64)
-PSIMAGE_PIXEL_INTERPOLATE_BILINEAR_COMPLEX(C32)
-PSIMAGE_PIXEL_INTERPOLATE_BILINEAR_COMPLEX(C64)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U8,psF64,U8,)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U16,psF64,U16,)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U32,psF64,U32,)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U64,psF64,U64,)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S8,psF64,S8,)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S16,psF64,S16,)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S32,psF64,S32,)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S64,psF64,S64,)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F32,psF64,F32,)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F64,psF64,F64,)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(C32,psC64,C32,)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(C64,psC64,C64,)
+
+// Variance Version
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U8,psF64,VARIANCE_U8,SQUARE)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U16,psF64,VARIANCE_U16,SQUARE)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U32,psF64,VARIANCE_U32,SQUARE)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U64,psF64,VARIANCE_U64,SQUARE)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S8,psF64,VARIANCE_S8,SQUARE)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S16,psF64,VARIANCE_S16,SQUARE)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S32,psF64,VARIANCE_S32,SQUARE)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S64,psF64,VARIANCE_S64,SQUARE)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F32,psF64,VARIANCE_F32,SQUARE)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F64,psF64,VARIANCE_F64,SQUARE)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(C32,psC64,VARIANCE_C32,SQUARE)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(C64,psC64,VARIANCE_C64,SQUARE)
