Because scaling operations are prohibitively expensive in my current rendering stack, I have to pre-render my images in all desired sizes and cache the result on disk. At the moment, I do this by dumping one PNG file per image size. However, this gets fairly large quickly and I'd like to know whether there is a possibility to take advantage of the fact that all these images are basically showing the same content.
However, this gets fairly large quickly and I'd like to know whether there is a possibility to take advantage of the fact that all these images are basically showing the same content.
There is. It's called... scaling the largest mipmap to produce the smaller ones. That's essentially what's happening when you generate mipmaps directly: you are "compressing" the lower mipmaps by taking advantage of the fact that all these images are algorithmically built from the largest mipmap. Since you only store the largest mipmap, the other mipmaps take up zero bytes. Then you "decompress" them by scaling them as they are loaded.
The principle cost of CPU scaling is not the computation of the lower-mipmap level itself. It's the memory bandwidth costs of reading from the higher mipmap and writing to the lower one. It doesn't really matter what your algorithm for computing the lower one is; if it requires reading every pixel of the higher mipmap, it's basically going to cost the same thing.
If you've got access to a GPU, you ought to be able to scale it there with rendering operations or even just linearly-interpolated blitting operations.
You could look into wavelet image compression, which effectively stores a mip pyramid "top down" with each level storing only the diffs from the next-smaller level. This would effectively let you reconstruct whichever mip level you wanted from the same file at load time, with the file being the same overall size as only the base mip. However, it is likely more expensive to decompress than PNG for the same reason.
The JPEG2000 format implements a wavelet compression method (as well as quantization and bitstream coding like other JPEG formats). I'm not sure if there are JPEG2000 libraries that support efficiently reconstructing multiple resolutions of the image while loading though.