Skip to content

Splash: Enhance bilinear scaling for downsampling

This is a proposal to fix #950. It's only one of many approaches, but probably the lowest hanging fruit.

Splash bilinear scaling was originally limited to upsampling. With small enhancements we can now use it for downsampling too. Our Bresenham box-like scaling produced jagged edges when downsampling, esp. notable when scaling down raster images containing text. Bilinear filtering improves quality but is a bit slower.

Should not be used for downsampling below 0.5, because bilinear interpolation starts being lossy there.

Visual quality: Generated text

Here's a side-by-side comparison of an image containing glyphs, scaled down to 75%. From left to right: Splash Bresenham (box like filter), Splash new bilinear downsampling, Glib/Cairo/Pixman.

text_images_bresenham_bilinear_glib_0_75

Note how Bresenham (left) produced jagged edges, and note how the bilinear filter (middle) improves the quality. Maybe still not as good as Cairo (right), but close.

Visual quality: Embedded images from a test PDF

Splash bresenham left, Splash bilinear mid, Cairo right

Scale 0.9: splash-bresen_splash-bilinear_cairo_09

Scale 0.8: splash-bresen_splash-bilinear_cairo_08

Scale 0.7: splash-bresen_splash-bilinear_cairo_07

Scale 0.6: splash-bresen_splash-bilinear_cairo_06

Scale 0.5: splash-bresen_splash-bilinear_cairo_05

Performance

cpu_time_bresenham_bilinear_cairo

Bilinear scaling is ~ 1.25 .. 1.5x slower then Bresenham. Unrelated, but interesting, we see how Cairo/Pixman automatically changes filter at 75%.

Measured by putting a std::chrono::steady_clock::now() at the beginning and the end of Gfx::doImage. Test environment was

model name      : Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz
cpu MHz         : 1880.459
cache size      : 8192 KB
cpu cores       : 4

Measurement: SSIM using Lanczos3 as reference

Scaled down a zone plate test image using our algorithms, scaled it down the same with Lanczos3 (top quality filter for reference), and calculated SSIM between ours and the reference. The higher the value the better.

ssim_bresenham_bilinear_cairo

Edited by Tobias Deiminger

Merge request reports