[Pixman] [PATCH v9 06/15] pixman-filter: Correct Simpsons integration

Oded Gabbay oded.gabbay at gmail.com
Mon Feb 1 06:34:48 PST 2016

```On Fri, Jan 22, 2016 at 11:42 AM,  <spitzak at gmail.com> wrote:
> 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. Multiples of 12 seem to work best.
>
> v9: Changed samples from 16 to 12
> v7: Merged with patch to reduce from 128 samples to 16
>
> Signed-off-by: Bill Spitzak <spitzak at gmail.com>
> ---
>  pixman/pixman-filter.c | 29 +++++++++++++++++++----------
>  1 file changed, 19 insertions(+), 10 deletions(-)
>
> diff --git a/pixman/pixman-filter.c b/pixman/pixman-filter.c
> index 55073c4..718649a 100644
> --- a/pixman/pixman-filter.c
> +++ b/pixman/pixman-filter.c
> @@ -189,13 +189,19 @@ integral (pixman_kernel_t reconstruct, double x1,
>      }
>      else
>      {
> -       /* Integration via Simpson's rule */
> -#define N_SEGMENTS 128
> -#define SAMPLE(a1, a2)                                                 \
> -       (filters[reconstruct].func ((a1)) * filters[sample].func ((a2) / scale))
> -
> +       /* Integration via Simpson's rule
> +        * See http://www.intmath.com/integration/6-simpsons-rule.php
> +        * 12 segments (6 cubic approximations) seems to produce best
> +        * result for lanczos3.linear, which was the combination that
> +        * showed the most errors.  This makes sense as the lanczos3
> +        * filter is 6 wide.
> +        */
> +#define N_SEGMENTS 12
> +#define SAMPLE(a)                                                      \
> +       (filters[reconstruct].func ((a)) * filters[sample].func (((a) - pos) / scale))
> +
You changed the SAMPLE macro to get 1 parameter, but in all the calls
you send 2 parameters, which make the compilation fail.

Please fix this and resend the patch.

Oded

>         double s = 0.0;
> -       double h = width / (double)N_SEGMENTS;
> +       double h = width / N_SEGMENTS;
>         int i;
>
>         s = SAMPLE (x1, x2);
> @@ -204,11 +210,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
>
> _______________________________________________
> Pixman mailing list
> Pixman at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/pixman
```