<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 18, 2016 at 6: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><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></div></div></blockquote><div><br></div><div>Yes I believe you are right. Looks like my mistake there, and you can see the other line that this replaces is in the correct direction so I'm not sure how I managed to do this. This incorrect version still hid the artifact in the filter (a small dip/spike in the middle of large ones for sync filters), so I guess I concluded I got it right.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><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></div></div></div></div></blockquote><div><br></div><div>That will not distribute the error evenly. I could just add error*(x+1)/width-error*x/width and avoid the temporary entirely, though I guess there has to be a warning comment that doing the obvious-looking optimization will make it not work. </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>Another possibility is to do error diffusion in the /* Normalize */ loop. <br></div></div></div></div></blockquote><div><br></div><div>I don't think that will work because it needs to take into account the rounding to pixman_fixed_t after the division. </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div></div><span class="HOEnZb"><font color="#888888"><div><br><br></div><div>Søren<br></div></font></span></div></div></div>
</blockquote></div><br></div></div>