<div dir="ltr">On Sat, Apr 9, 2016 at 3:45 PM, Bill Spitzak <span dir="ltr"><<a href="mailto:spitzak@gmail.com" target="_blank">spitzak@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">On 04/03/2016 11:17 AM, Søren Sandmann wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
I don't believe this patch is correct.<br>
<br>
As an example, consider an image with an identity transformation and a<br>
cubic filter (which has width 4) with subsample_bits = 0. The current<br>
code will compute a matrix<br>
<br>
[ cubic(-2), cubic(-1), cubic(0), cubic(1) ]<br>
<br>
Now suppose we are filtering a pixel located at x = 17.5. The code in<br>
bits_image_fetch_pixel_separable_convolution() will eventually end up<br>
convolving with the pixels at locations 15.5, 16.5, 17.5 and 18.5, which<br>
is the correct result since cubic(-2) = 0 [1].<br>
<br>
With your code, the matrix computed would be<br>
<br>
[ cubic(-1.5), cubic(-0.5), cubic(0.5), cubic(1) ]<br>
<br>
which would not be correct no matter what: With an identity<br>
transformation, the pixel at 17.5 should be multiplied with cubic(0).<br>
<br>
There is a detailed explanation of these issues in the file<br>
pixman/rounding.txt.<br>
</blockquote>
<br></span>
I have finally checked this and it is producing the correct value in the above example. pos is not the left edge of the range to integrate, it is the center of it, due to the changes I made to the integrate function.<br></blockquote><div><br></div><div>No, it really doesn't produce the correct values. If you apply the patch below on top of your series and run demos/scale with<br><br> subsample set to 0,<br> reconstruct set to 'Cubic',<br></div><div> sample set to 'Impulse'<br></div><div> scale factor set to 1.0,<br><br></div><div>it prints out this:<br></div><div><br> cubic(1.500000) = -0.034722<br> cubic(0.500000) = 0.534722<br> cubic(-0.500000) = 0.534722<br> cubic(-1.500000) = -0.034722<br> [ -0.035, 0.535, 0.535, -0.035, ]<br><br></div><div>which is not the correct result. The first value should be cubic(-2) = 0.<br><br></div><div>And if you toggle back and forth between subsamples = 0 and 1, you can see the image shift slightly.<br></div><div><br></div><div>(The *gnuplot* graph looks correct, but that's because the gnuplot function is also generating the wrong coordinates).<br></div><br><div><br></div><div>Søren<br></div><div><br><br><br>diff --git a/pixman/pixman-filter.c b/pixman/pixman-filter.c<br>index 2bf289a..52b7834 100644<br>--- a/pixman/pixman-filter.c<br>+++ b/pixman/pixman-filter.c<br>@@ -134,7 +134,9 @@ cubic_kernel (double x)<br> * (0.0, 0.5) would give us the Catmull-Rom spline,<br> * but that one seems to be indistinguishable from Lanczos2.<br> */<br>- return general_cubic (x, 1/3.0, 1/3.0);<br>+ double v = general_cubic (x, 1/3.0, 1/3.0);<br>+ printf ("cubic(%f) = %f\n", x, v);<br>+ return v;<br> }<br> <br> static const filter_info_t filters[] =<br>@@ -297,6 +299,11 @@ create_1d_filter (int width,<br> }<br> }<br> <br>+ printf ("[ ");<br>+ for (x = 0; x < width; ++x)<br>+ printf ("%.3f, ", pixman_fixed_to_double (p[x]));<br>+ printf ("]\n");<br>+<br> p += width;<br> }<br> }<br><br></div></div></div></div>