<div dir="ltr"><div><div><div>This is forcing the filter to be normalized (sum to 1.0) despite any math errors.<br><br></div>p is a post-increment pointer used to store the filter values, so it now points after the last filter value. The filter is summed and the difference from 1.0 is then added to the middle pixel with this code.<br><br></div>If the width is an odd number such as 5, the filter is stored in f[0]..f[4], and p points at f[5]. The old code would add the extra error value to f[3], which is not the center sample. The new code adds it to f[2]. (If the width is even such as 4, then both the old and new code add the error to the f[2] which is the pixel to the right of the center.)<br><br></div><div>The mistake was only visible in the width==1 case. Some combinations of filters produced a sample of 0, and then calculated the error as 1.0. The old code would put the error on f[1] (past the end). The new code puts it on f[0], thus producing a value of 1.0.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 22, 2015 at 2:41 AM, Oded Gabbay <span dir="ltr"><<a href="mailto:oded.gabbay@gmail.com" target="_blank">oded.gabbay@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Sat, Dec 12, 2015 at 8:06 PM, <<a href="mailto:spitzak@gmail.com">spitzak@gmail.com</a>> wrote:<br>
> From: Bill Spitzak <<a href="mailto:spitzak@gmail.com">spitzak@gmail.com</a>><br>
><br>
> Any error in filter normalization is placed on the center of odd-sized filters,<br>
> rather than 1 pixel to the right.<br>
><br>
> In particular this fixes the 1-wide filters produced by impulse sampling<br>
> so they are 1.0 rather than 0.0.<br>
> ---<br>
> pixman/pixman-filter.c | 2 +-<br>
> 1 file changed, 1 insertion(+), 1 deletion(-)<br>
><br>
> diff --git a/pixman/pixman-filter.c b/pixman/pixman-filter.c<br>
> index 0cd4a68..fbc657d 100644<br>
> --- a/pixman/pixman-filter.c<br>
> +++ b/pixman/pixman-filter.c<br>
> @@ -299,7 +299,7 @@ create_1d_filter (int width,<br>
> }<br>
><br>
> if (new_total != pixman_fixed_1)<br>
> - *(p - width / 2) += (pixman_fixed_1 - new_total);<br>
> + *(p - (width + 1) / 2) += (pixman_fixed_1 - new_total);<br>
> }<br>
> }<br>
><br>
> --<br>
> 1.9.1<br>
><br>
</div></div>> _______________________________________________<br>
> Pixman mailing list<br>
> <a href="mailto:Pixman@lists.freedesktop.org">Pixman@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/pixman" rel="noreferrer" target="_blank">http://lists.freedesktop.org/mailman/listinfo/pixman</a><br>
<br>
<br>
I see that the result is indeed better (in the scale demo), but do you<br>
mind explaining a bit more about the underlying of this patch ?<br>
I indeed see that the width is 1, so without your patch, the new value<br>
is written to *p and with your patch, it is written to *(p-1). But I<br>
have no idea what that means :(<br>
<span class="HOEnZb"><font color="#888888"><br>
Oded<br>
</font></span></blockquote></div><br></div>