[cairo] Image resampling [PATCH 0/6]

Bill Spitzak spitzak at gmail.com
Mon Nov 26 18:44:21 PST 2012

Søren Sandmann wrote:
> Hi,
> Reviewing the supersampling patch here:
>    http://cgit.freedesktop.org/~ajohnson/pixman/log/?h=supersampling
> I wasn't happy with either the performance and image quality, and I
> realized that the whole supersampling approach just isn't going to
> fly. Since I told people to do it that way, I apologize for that. The
> approach advocated by Bill Spitzak in the various downsampling threads
> of computing a convolution kernel up front, is the much better way to
> go. To make up for being misleading, the following patches implement
> comprehensive support for high-quality image scaling filters.

This is great news!

> -=- Adding support to cairo and further work
> Once these patches have landed in Pixman, support will have to be
> added to cairo to make use of them. How to do that exactly requires
> figuring out what new API to offer, and how the tradeoffs between
> performance and quality should be made. This is not something that I
> personally plan to work on anytime soon, except to make three notes:

Cairo may want to pre-scale the source surface by an integer factor 
using a box filter so that the sampling filters are not so large. It 
would then have to keep this scaled image around until either the source 
image is dirtied or a transform requiring a different scale is used. I 
would think this could speed up repeated drawing of a much-scaled-down 
image considerably. It does seem to me that such a step should be done 
by cairo rather than pixman. The alternative is for client programs to 
do this with extra Cairo surfaces for the scaled images, but that seems 
to not be keeping with the easy-to-use api intentions of Cairo.

The scale would be chosen so the intermediate image is no smaller than 
2x the final result. This seems to hide any problems with the box 
filter. It kind of makes sense because we are reusing the sampling 
filter at intervals that are less than 1/2 which is below the nyquist 
frequency for the sync.

>   - While transformations that are not pure scalings will not
>     generally result in a separable filter, OK-looking results for
>     non-scalings can be achieved by using scaling factors based on the
>     bounding box of a transformation

Having recently wasted some time on this, I discovered that in fact 
these sampling filters *rely* on the separable property. The lancos and 
sync filters do not work if when they are centered on a pixel the 
neighboring pixels are not at the zeros in the filter. The only way to 
do this is for the filter to be a product of 2 1-D filters that are 
aligned with the source pixel grid. If they were at an angle, the zeros 
would be at an angle and thus could not all hit pixel centers. Trying to 
make it circular (as I was doing) also fails for the same reason. An 
obvious error is that the identity transformation results in ringing and 
sharpening being added to the picture. With aligned separable filters 
and a filter that is zero at all integers other than 0 the result is an 
identity, which is much more likely what users want.

Therefore it looks like you have already gotten most of what is needed.

The two sizes are fairly easy to figure out from the inverse 
transformation matrix (ie the inverse of the matrix a Cairo user sets, 
but the one needed to find the source image pixel given an output 
position) (WARNING: I may have b/c swapped from what Cairo/pixman code 

	[ a b 0 ]   [ X ]
   inxy=	[ c d 0 ] * [ Y ]
	[ x y 1 ]   [ 1 ]

The horizontal size is hypot(a,b) and the vertical size is hypot(c,d).

This is the width/height of the bounding box of the ellipse you get if a 
.5-radius circle is transformed by this matrix.

More information about the cairo mailing list