[cairo] Re: fix pixel offsets in rotated image sources

Bill Spitzak spitzak at d2.com
Fri Sep 16 17:53:52 PDT 2005


Bertram Felgenhauer wrote:

> It does not. The filters implemented in pixman (and the Xserver, too)
> look like this right now for a single pixel:
> 
> Nearest:               Bilinear: 
>        ^                      ^
>        |                      |
>       1|----+               1 +
>        |    |                /|\
>        |    |               / | \
>        |    |              /  |  \
>        |    |             /   |   \
> --+----|----+----      --+----|----+--
>  -1    0    1           -1    0    1   
> 
> In a way, nearest filtering already samples at the center of the pixel,
> because it truncates the coordinates. Bilinear filtering needs an
> additional adjustment.

You are right, "nearest" is really doing a "floor" operation to figure 
out the pixel to sample. I thought it was rounding to the nearest 
integer, which would center the rectangle you drew around zero.

The matrix must still be manipulated as it still is assuming the 
integers in the output surface are in the centers of the pixels. I found 
that the following code adjusts the matrix correctly for the nearest filter:

   xtransform.matrix[0][2] +=
     (xtransform.matrix[0][0]+xtransform.matrix[0][1]/*-0x10000*/)>>1;
   xtransform.matrix[1][2] +=
     (xtransform.matrix[1][0]+xtransform.matrix[1][1]/*-0x10000*/)>>1;

This is the same except as for the filtered case except for a difference 
of .5 (the old offset is commented out here).

My opinion now is that this is definately a bug in XRender and the 
"nearest" algorithim should be fixed, as it does not match what anybody 
would expect "nearest" to do and makes the image shift as you change 
filters. It can be fixed by adding .5 to the input image coordinate just 
before you truncate it to an integer.

Since it is likely that this will break programs that are using the 
nearest filter, you might as well fix the other case as well and break 
everything at once. As you mention, it will actually fix programs that 
did not compensate for this, which may be the majority.

>>Unfortunately /2 rounds toward zero, which is equally broken.
> 
> Hmm. I'm not sure if it matters on the 1/65536 pixel/source pixel scale
> but yes, that's ugly.

It does matter when it truncates the result to the nearest integer. I 
have generally found that I can *never* use /2 in any GUI position 
calculations as it will always encounter negative numbers and result in 
very annoying wobbly movement or misalignment of things that should 
align, and always use >>1 for this.


More information about the cairo mailing list