Leopold's Shareware:

pnmleoscale is a replacement for the pnmscale program provided with the pbmplus graphical exchange package. It uses optimal sample reconstruction, which yields as little loss of information as possible.

Image Degradation with Multiple Scalings

Let's take a picture of size, say, 100 x 100 pixels, like this one:

Now, let's scale it several times, little at a time, to see, how the image degrades. Let's do the same test with the original pnmscale and pnmleoscale.

Multiple scaling example, pnmscale vs pnmleoscale
Generation Size Original pnmscaled pnmleoscaled
0 100 x 100
1 103 x 101
2 107 x 105
3 111 x 121
4 110 x 119
5 108 x 113
6 110 x 110
7 108 x 108
8 112 x 112
9 100 x 100

How about that!?


And there's more. If you wish to scale a small picture to a much greater size, you have probably noticed that all (?) of the current scaling programs give you jaggies, or pixels the size of your toenails. This is, too, totally avoided with pnmleoscale. See for youself!

The image scaled to quadruple size with pnmscale:

The image scaled to quadruple size with pnmleoscale:

Just look at those ears and eyes! Are you now ready to buy pnmleoscale?

Speed and Quality Tradeoffs

Here comes the sad part:
pnmleoscale is quite cpu intensive. It typically uses 2..40 times as much time for a scaling operation compared to pnmscale. Because of the slowness, it is possible for the user to control it's quality and the speed of the scale operation.

The cat shown before will look like the following (and take as much time as shown) after the 9 generations when converted using the different quality values:
9 generations of scaling with pnmleoscale
Quality Time Original Converted Comments
pnmscale 1 Awful.

The image has lost all detail because of the simple weighted average scheme that has been used to scale it.

0 1.5 The image looks quite a bit better than the one converted with pnmscale did. However, it is easy to see that the white colour in the belly has turned to gray.
1 2 A definitive improvement over the previous one. The belly still isn't white, but it's much nearer the original colour. Some other artifacts have diminished, too.
2 2.5 This already bears a striking resemblence to the original picture.
3 3 This is the default quality value of pnmleoscale. Usually, even after nine generations, it gives images indistinguishable from the original. However, this is not always the case.
4 4 From now on the differences are almost too hard to find.
5 6
6 9
7 13
8 20
9 40 The best, and very CPU-intensive quality setting. Very high quality.

Examples with an Artificial Test Image

Here is an example of shrinking an image. This is the original picture.

This picture has been downscaled to 40% with pnmscale:

This picture has been downscaled to 40% with pnmleoscale:

As you can see, pnmleoscale low-pass filters the image before downscaling. Thus, there is no visible aliasing.

Here is an example of enlarging an image. This is the original picture.

This picture has been upscaled to 400% with pnmscale:

This picture has been upscaled to 400% with pnmleoscale:

Here is an example of an image, that has first been downscaled to 25%, and then upscaled back to the original size. This is the original picture.

This picture has been treated with pnmscale.

This picture has been treated with pnmleoscale.

When to Use pnmleoscale?

In my opinion, pnmleoscale is useful almost always. The only times it isn't useful is when the original picture has very little colours or grayshades, or it is heavily dithered.

How to Use pnmleoscale?

Just have a look at the man-page of pnmscale. There is only one addition to it:

Anywhere on a line, you may have a "-q n", where n is a digit between 0 and 9, and defines the quality of the conversion. 0 is worst, 9 is best, and 3 is the default.

How to download pnmleoscale?

Here, have it! Just download it, uudecode it, and compile it. Makefiles are provided both for Unix and Amiga's SAS-C.
If you don't know how to open this file, don't ask me. You ought to know. If you are using MS-DOS: forget about it. This program needs binary standard input/output.