[Pixman] [PATCH v14 12/22] pixman-filter: fix subsample_bits == 0
soren.sandmann at gmail.com
Sat Apr 9 20:13:19 UTC 2016
On Sat, Apr 9, 2016 at 3:45 PM, Bill Spitzak <spitzak at gmail.com> wrote:
> On 04/03/2016 11:17 AM, Søren Sandmann wrote:
>> I don't believe this patch is correct.
>> As an example, consider an image with an identity transformation and a
>> cubic filter (which has width 4) with subsample_bits = 0. The current
>> code will compute a matrix
>> [ cubic(-2), cubic(-1), cubic(0), cubic(1) ]
>> Now suppose we are filtering a pixel located at x = 17.5. The code in
>> bits_image_fetch_pixel_separable_convolution() will eventually end up
>> convolving with the pixels at locations 15.5, 16.5, 17.5 and 18.5, which
>> is the correct result since cubic(-2) = 0 .
>> With your code, the matrix computed would be
>> [ cubic(-1.5), cubic(-0.5), cubic(0.5), cubic(1) ]
>> which would not be correct no matter what: With an identity
>> transformation, the pixel at 17.5 should be multiplied with cubic(0).
>> There is a detailed explanation of these issues in the file
> 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.
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
subsample set to 0,
reconstruct set to 'Cubic',
sample set to 'Impulse'
scale factor set to 1.0,
it prints out this:
cubic(1.500000) = -0.034722
cubic(0.500000) = 0.534722
cubic(-0.500000) = 0.534722
cubic(-1.500000) = -0.034722
[ -0.035, 0.535, 0.535, -0.035, ]
which is not the correct result. The first value should be cubic(-2) = 0.
And if you toggle back and forth between subsamples = 0 and 1, you can see
the image shift slightly.
(The *gnuplot* graph looks correct, but that's because the gnuplot function
is also generating the wrong coordinates).
diff --git a/pixman/pixman-filter.c b/pixman/pixman-filter.c
index 2bf289a..52b7834 100644
@@ -134,7 +134,9 @@ cubic_kernel (double x)
* (0.0, 0.5) would give us the Catmull-Rom spline,
* but that one seems to be indistinguishable from Lanczos2.
- return general_cubic (x, 1/3.0, 1/3.0);
+ double v = general_cubic (x, 1/3.0, 1/3.0);
+ printf ("cubic(%f) = %f\n", x, v);
+ return v;
static const filter_info_t filters =
@@ -297,6 +299,11 @@ create_1d_filter (int width,
+ printf ("[ ");
+ for (x = 0; x < width; ++x)
+ printf ("%.3f, ", pixman_fixed_to_double (p[x]));
+ printf ("]\n");
p += width;
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Pixman