[Pixman] [PATCH v8 06/14] pixman-filter: Correct Simpsons integration

spitzak at gmail.com spitzak at gmail.com
Mon Jan 4 21:48:53 PST 2016


From: Bill Spitzak <spitzak at gmail.com>

Simpsons uses cubic curve fitting, with 3 samples defining each cubic. This
makes the weights of the samples be in a pattern of 1,4,2,4,2...4,1, and then
dividing the result by 3.

The previous code was using weights of 1,2,6,6...6,2,1. Since it divided by
3 this produced about 2x the desired value (the normalization fixed this).
Also this is effectively a linear interpolation, not Simpsons integration.

With this fix the integration is accurate enough that the number of samples
could be reduced a lot. Likely even 16 samples is too many.

v7: Merged with patch to reduce from 128 samples to 16

Signed-off-by: Bill Spitzak <spitzak at gmail.com>
---
 pixman/pixman-filter.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/pixman/pixman-filter.c b/pixman/pixman-filter.c
index 55073c4..8d65e76 100644
--- a/pixman/pixman-filter.c
+++ b/pixman/pixman-filter.c
@@ -189,8 +189,10 @@ integral (pixman_kernel_t reconstruct, double x1,
     }
     else
     {
-	/* Integration via Simpson's rule */
-#define N_SEGMENTS 128
+	/* Integration via Simpson's rule
+	 * See http://www.intmath.com/integration/6-simpsons-rule.php
+	 */
+#define N_SEGMENTS 16
 #define SAMPLE(a1, a2)							\
 	(filters[reconstruct].func ((a1)) * filters[sample].func ((a2) / scale))
 	
@@ -204,11 +206,14 @@ integral (pixman_kernel_t reconstruct, double x1,
 	{
 	    double a1 = x1 + h * i;
 	    double a2 = x2 + h * i;
+	    s += 4 * SAMPLE(a1, a2);
+	}
 
-	    s += 2 * SAMPLE (a1, a2);
-
-	    if (i >= 2 && i < N_SEGMENTS - 1)
-		s += 4 * SAMPLE (a1, a2);
+	for (i = 2; i < N_SEGMENTS; i += 2)
+	{
+	    double a1 = x1 + h * i;
+	    double a2 = x2 + h * i;
+	    s += 2 * SAMPLE(a1, a2);
 	}
 
 	s += SAMPLE (x1 + width, x2 + width);
-- 
1.9.1



More information about the Pixman mailing list