# [Pixman] [PATCH v14 12/22] pixman-filter: fix subsample_bits == 0

Søren Sandmann 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 [1].
>>
>> 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
>> pixman/rounding.txt.
>>
>
> 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).

Søren

diff --git a/pixman/pixman-filter.c b/pixman/pixman-filter.c
index 2bf289a..52b7834 100644
--- a/pixman/pixman-filter.c
+++ b/pixman/pixman-filter.c
@@ -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...
URL: <https://lists.freedesktop.org/archives/pixman/attachments/20160409/8294e73f/attachment.html>
```