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.
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.
Splash bresenham left, Splash bilinear mid, Cairo right
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.