<div dir="ltr">On Fri, Mar 18, 2016 at 9:54 PM, Søren Sandmann <span dir="ltr"><<a href="mailto:soren.sandmann@gmail.com" target="_blank">soren.sandmann@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div class="h5">On Sun, Mar 6, 2016 at 8:06 PM,  <span dir="ltr"><<a href="mailto:spitzak@gmail.com" target="_blank">spitzak@gmail.com</a>></span> wrote:<br></div></div><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Bill Spitzak <<a href="mailto:spitzak@gmail.com" target="_blank">spitzak@gmail.com</a>><br>
<br>
This removes a high-frequency spike in the middle of some filters that is<br>
caused by math errors all being in the same direction.<br>
<br>
Signed-off-by: Bill Spitzak <<a href="mailto:spitzak@gmail.com" target="_blank">spitzak@gmail.com</a>><br>
---<br>
 pixman/pixman-filter.c | 12 +++++++++++-<br>
 1 file changed, 11 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/pixman/pixman-filter.c b/pixman/pixman-filter.c<br>
index 36dd811..ab62e0a 100644<br>
--- a/pixman/pixman-filter.c<br>
+++ b/pixman/pixman-filter.c<br>
@@ -282,8 +282,18 @@ create_1d_filter (int              width,<br>
            p[x] = t;<br>
        }<br>
<br>
+       /* Distribute any remaining error over all samples */<br>
        if (new_total != pixman_fixed_1)<br>
-           p[width / 2] += (pixman_fixed_1 - new_total);<br>
+       {<br>
+           pixman_fixed_t delta = new_total - pixman_fixed_1;<br>
+           pixman_fixed_t t = 0;<br>
+           for (x = 0; x < width; ++x)<br>
+           {<br>
+               pixman_fixed_t new_t = delta * (x + 1) / width;<br>
+               p[x] += new_t - t;<br>
+               t = new_t;<br>
+           }<br>
+       }<br></blockquote><div><br></div></div></div><div>I think there is a sign error in this code: delta is new_total - 1, which is positive when new_total is bigger than 1. But this positive delta is then added to the samples, making the total even bigger.<br></div><div><br></div><div>Also, I would write the code like this:<br><br>        pixman_fixed_t error = pixman_fixed_1 - new_total;<span class=""><br>        for (x = 0; x < width; ++x)<br></span>        {<br>            pixman_fixed_t d = error * (x + 1) / width;<br>            p[x] += d;<br>            error -= d;<br>        }<br><br></div><div>to get rid of the temporary and to make it more obvious that there is an error that is being distributed.<br><br></div><div>Another possibility is to do error diffusion in the /* Normalize */ loop. <br></div></div></div></div></blockquote><div><br></div><div>Also, a test that generates a bunch of filters and verifies that all the phases sum to 1 would be useful.<br></div><br><br></div><div class="gmail_quote">Søren<br></div></div></div>