summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <sandmann@redhat.com>2008-11-05 18:09:25 -0500
committerSøren Sandmann Pedersen <sandmann@redhat.com>2008-11-05 18:09:25 -0500
commita3fb811e96248bc0b9e0c323761d0abb1b594a76 (patch)
tree09e7ab8889f99ec367c01a798c5de2bf083516f2
parentcf760a1f37bb91435d252cd776f556081268932a (diff)
asdf
-rw-r--r--downscaling.c121
1 files changed, 85 insertions, 36 deletions
diff --git a/downscaling.c b/downscaling.c
index 2dadb09..dc16c2e 100644
--- a/downscaling.c
+++ b/downscaling.c
@@ -274,22 +274,95 @@ create_gaussian_kernel (int r, int *n_params)
return params;
}
+typedef double (* convolution_t) (int size, double x, double y);
+
static void
-set_gaussian (pixman_image_t *image, int w, int h, double scale)
+set_convolution (pixman_image_t *image, int w, int h,
+ int size, convolution_t convolution)
{
int n_params;
+ pixman_fixed_16_16_t *params;
+ double *dparams;
+ double sum;
+ int i, j;
+
+ n_params = size * size + 2;
+
+ dparams = g_malloc (n_params * sizeof (double));
+ params = g_malloc (n_params * sizeof (pixman_fixed_16_16_t));
+
+ sum = 0.0;
+ for (i = 0; i < size; ++i)
+ {
+ for (j = 0; j < size; ++j)
+ {
+ int idx = i * size + j + 2;
-#define RAD 5
+ dparams[idx] = convolution (size, i - size / 2, j - size / 2);
- pixman_fixed_16_16_t *params =
- create_gaussian_kernel (RAD, &n_params);
+ sum += dparams[idx];
+ }
+ }
- params[0] = (RAD * 2 + 1) << 16;
- params[1] = (RAD * 2 + 1) << 16;
+ g_print ("sum %f\n", sum);
+ for (i = 0; i < size; ++i)
+ {
+ for (j = 0; j < size; ++j)
+ {
+ int idx = i * size + j + 2;
+
+ params[idx] = _cairo_fixed_16_16_from_double (dparams[idx] / sum);
+
+ g_print ("%.4f ", dparams[idx] / sum);
+ }
+
+ g_print ("\n");
+ }
+
+ params[0] = size << 16;
+ params[1] = size << 16;
+
pixman_image_set_filter (image, PIXMAN_FILTER_CONVOLUTION, params, n_params);
+}
- g_free (params);
+static double
+gaussian (int size, double x, double y)
+{
+ double sigma = (size / 2.0) / 2.0;
+
+ return (1 / (2 * G_PI * sigma * sigma)) * exp (-(x * x + y * y) / (2 * sigma * sigma));
+}
+
+static void
+set_gaussian (pixman_image_t *image, int w, int h, double scale)
+{
+ set_convolution (image, w, h, 5 / scale, gaussian);
+}
+
+static double
+lanczos (int size, double x, double y)
+{
+ double a = size;
+ double d = sqrt (x * x + y * y);
+ double res;
+
+ if (fabs (d) < DBL_EPSILON)
+ {
+ res = 1.0;
+ }
+ else
+ {
+ res = (a * sin (G_PI * d) * sin ((G_PI * d)/ a)) / (G_PI * G_PI * d * d);
+ }
+
+ return res;
+}
+
+static void
+set_lanczos (pixman_image_t *image, int w, int h, double scale)
+{
+ set_convolution (image, w, h, 5 / scale, lanczos);
}
static void
@@ -304,10 +377,10 @@ set_nearest (pixman_image_t *image, int w, int h, double scale)
pixman_image_set_filter (image, PIXMAN_FILTER_NEAREST, NULL, 0);
}
-static void
-set_lanczos (pixman_image_t *image, int w, int h, double scale)
+static double
+box (int size, double x, double y)
{
- g_error ("Lanczos filter is not implemented yet");
+ return 1;
}
static void
@@ -315,35 +388,11 @@ set_box (pixman_image_t *image, int w, int h, double scale)
{
if (scale < 1.0)
{
- int size = (1.0 / scale + 0.5);
- int n_params = size * size + 2;
- pixman_fixed_16_16_t *params = g_malloc (n_params * sizeof (pixman_fixed_16_16_t));
- int i, j;
-
- params[0] = size << 16;
- params[1] = size << 16;
-
- g_print ("size of box: %d\n", size);
-
- for (i = 0; i < size; ++i)
- {
- for (j = 0; j < size; ++j)
- {
- int idx = i * size + j + 2;
-
- g_assert (idx < n_params);
-
- params[idx] = _cairo_fixed_16_16_from_double (1.0 / (size * size));
- }
- }
-
- pixman_image_set_filter (image, PIXMAN_FILTER_CONVOLUTION, params, n_params);
-
- g_free (params);
+ set_convolution (image, w, h, 1.0 / scale + 0.5, box);
}
else
{
- pixman_image_set_filter (image, PIXMAN_FILTER_NEAREST, NULL, 0);
+ pixman_image_set_filter (image, PIXMAN_FILTER_BILINEAR, NULL, 0);
}
}