[cairo] [PATCH] pixman: high qualtiy downscaling

Soeren Sandmann sandmann at daimi.au.dk
Fri Nov 27 04:18:13 PST 2009


Carlos Garcia Campos <carlosgc at gnome.org> writes:

> What's the status of this? any chance of getting this fixed in
> pixman soon? Poppler has been affected by this bug[1] for a long
> time, and it's the main reason why we still allow building
> poppler-glib frontend with the splash backend. If there's anything I
> can do to help, please let me know.

My opinion on the subject is basically still here:

    http://lists.cairographics.org/archives/cairo/2009-June/017498.html

A quite general solution would be to add the ability to resample at a
user-specified rate with a user-specified filter kernel. A first
implementation of this could offer just a box filter.

In practical terms, this would mean changing the fetching in
pixman-bits-image.c to fetch subpixels and average them together
instead of fetching whole pixels.

A new function

     pixman_image_set_resample_rate (image, rate_x, rate_y)

would be added, where rate_x and rate_y both default to 1. If they are
set to something other than 1, then a different fetch function is
installed that fetches rate_x times rate_y subpixels per pixel, then
averages them together. I don't think this would be a huge amount of
work to do.

To get approximately GdkPixbuf level of quality, you could then do:

     if downscaling in the X direction, then
     	rate_x = 1 / scale_ratio_x
     else
	rate_x = 1;

     if downscaling in the Y direction, then
        rate_y = 1 / scale_ratio_y
     else
        rate_x = 1;

     if (rate_x == 1 || rate_y == 1)
     	filter = PIXMAN_FILTER_BILINEAR;
     else
        filter = PIXMAN_FILTER_NEAREST;

     pixman_image_set_filter (image, filter);
     pixman_image_set_resample_rate (image, rate_x, rate_y);

Though, there could be aliasing issues resulting from the combination
of nearest interpolation with super sampling where some source pixels
may get disproportionately overrepresented. BILINEAR could be used in
all cases if this is a problem.


- Cairo API -

Corresponding cairo API would have to be added. Below are some
thoughts on that. They should not be taken as fully formed proposal.

The direct translation of the pixman API would be:

      cairo_pattern_set_resampling_rate (pattern, rate_x, rate_y)
      cairo_pattern_set_resampling_filter (pattern, filter).

and that would enough for a sufficiently motivated developer to get
reasonable rescaling, but you have to write basically the code above,
so there likely should be some simplified API to let users say "please
just make it look reasonable".

Maybe that is CAIRO_FILTER_GOOD, but that would conflate interpolatino
and sampling, which would bug me. Another possibility is that cairo
simply offers

      CAIRO_RESAMPLE_FAST
      CAIRO_RESAMPLE_GOOD
      CAIRO_RESAMPLE_BEST

defaulting to GOOD, where GOOD then would mean "make it look good". 

Another issue is how/whether to configure resampling of masks.  Having
this ability is interesting because it gives us these features:

     - resampling with a gaussian kernel gives us blurring of both
       images and geometry

     - using a better kernel than the current box filter could
       potentially give higher quality antialiasing.

     - setting the sampling rate to something other than 17x15 gives a
       user-settable tradeoff between speed and quality geometry
       rendering.


Thanks,
Soren


More information about the cairo mailing list