Image scaling

My latest project on the RISC OS platform is writing some image scaling routines that resample the input image rather than just using a dumb algorithm like nearest-neighbour. Selecting an appropriate filter kernel based upon the scaled factor can help achieve better image quality across a large range of shrinks and zooms.

The code is implemented as a library with a very simple API which can be used to plot a scaled rectangular portion of an image to either memory or the screen. In the latter case, the rendering will use DMA on hardware that supports it in order to achieve better performance by overlapping the filter arithmetic with the screen writes.

Currently it has been included in Geminus because this provides an easy route to implementing filtered scaling for the majority of applications such as !NetSurf, !Paint, !Avalanche that all call either OS_SpriteOp or Tinct_Plot(Scaled) SWIs to render their 32bpp sprites.

Below is a screenshot of the NetSurf home page being rendered using a filtered implementation of Tinct_PlotScaled. Geminus must be set to perform sprite plotting for those application(s) that wish to benefit from filtered scaling, so the first option is ticked for NetSurf in the applications list.

As a side-by-side comparison of the effect of the current filtering code, I've loaded that screen grab into two copies of !Paint, one using the normal OS code - note the pixellation when zoomed in and the aliasing in the thumbnail view - and one using the new filtering code in Geminus - giving a much smoother image when zoomed in and a much clearer thumbnail representation.

And here's what it does on a real JPEG photograph when zoomed in to 300%.

The filter kernels are currently:

Copyright (C) Adrian Lees 2006