[cairo] Image resampling [PATCH 0/6]
spitzak at gmail.com
Mon Nov 26 18:44:21 PST 2012
Søren Sandmann wrote:
> Reviewing the supersampling patch here:
> 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