panolib.c: Use something similar to Lanczos resampling for sharper images.
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Mon, 20 Aug 2007 10:21:08 +0000 (12:21 +0200)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Mon, 20 Aug 2007 10:21:08 +0000 (12:21 +0200)
src/panolib.c

index 6d503d6..58948d3 100644 (file)
@@ -68,6 +68,29 @@ static void set_transformation_matrix (double m[3][3],
        matrix_matrix_mult( dummy, my, m);
 } /* void SetMatrix */
 
+#if 0
+static double lanczos (double x)
+{
+       static double table[257];
+
+       assert ((x >= 0.0) && (x <= 1.0));
+
+       if (table[0] != 1.0)
+       {
+               int i;
+
+               table[0] = 1.0;
+               for (i = 1; i <= 256; i++)
+               {
+                       double t = ((double) i) / 256.0;
+                       table[i] = 2 * sin (M_PI * t) * sin (M_PI_2 * t) / (M_PI * M_PI * t * t);
+               }
+       }
+
+       return (table[(int) (0.5 + 256.0 * x)]);
+} /* double lanczos */
+#endif
+
 static int copy_pixel (ui_image_t *dest, const ui_image_t *src,
                int x_dest, int y_dest,
                double x_src_fp, double y_src_fp,
@@ -76,7 +99,9 @@ static int copy_pixel (ui_image_t *dest, const ui_image_t *src,
        uint32_t pixel_dest = (y_dest * dest->width) + x_dest;
 
        assert (x_src_fp >= 0.0);
-       assert (y_src_fp >= 0.0);
+
+       if (y_src_fp < 0.0)
+               y_src_fp = 0.0;
 
        if (interp == BILINEAR)
        {
@@ -101,6 +126,20 @@ static int copy_pixel (ui_image_t *dest, const ui_image_t *src,
                x_right_frac = x_src_fp - x_src_left;
                y_bottom_frac = y_src_fp - y_src_top;
 
+               /*
+                * The polynomial function
+                *   2x^3 - 3x^2 + 1
+                * is similar to the Lanczos function, but much easier to compute. It's
+                * applied here to improve sharpness. 
+                */
+               {
+                       double t = x_src_fp - x_src_left;
+                       x_right_frac = -2.0 * t * t * t + 3.0 * t * t;
+
+                       t = y_src_fp - y_src_top;
+                       y_bottom_frac = -2.0 * t * t * t + 3.0 * t * t;
+               }
+
                assert ((x_right_frac >= 0.0) && (x_right_frac <= 1.0));
                assert ((y_bottom_frac >= 0.0) && (y_bottom_frac <= 1.0));