<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>