I think it's fantastic that you've managed to turn a long, hard optimisation slog into a real product win. Add me to the list of Australians willing to buy you a beer - but not back home, I live in SF at the moment :)
I'm curious about the low-quality preview you get when scrolling through all the shots. Are you storing low-quality data separately or do you also have a fast, low-qual JPEG decoder? (Is the Huffman encoding between blocks independent?)
Hey Andrew, would love to catch up over a beer. :-) Drop me a note via email: jpap {at} snappylabs.com
You've got a good eye: as part of the JPEG image compress, I also generate a low-resolution thumbnail that's embedded into each file as Exif metadata (along with geotagging, and other camera settings that define the shot, like exposure).
They are used as a "first-in" placeholder for an image.
The full image is then downsampled and decompressed simultaneously [1] exploiting the fact that the (Retina) screen resolution is often much lower than the full JPEG resolution.
As soon as you start zooming, the image is decompressed yet again at the full resolution and replaced in-place as quickly as possible so hopefully you won't see it. :-)
[1] As outlined in http://jpegclub.org/djpeg/ the technique relies on the fact that the top NxN DCT block of MxM coefficients, N < M, can be inverted to form a NxN pixel lower-resolution image of the original MxM block. When N is {1, 2, 4} a fast inverse DCT algorithm can be used with great success.
In fact, N == 1 is a trivial inversion and it might be tempting to use it as the low-resolution image instead of a thumbnail, but you still have to unpack all of the DCT coefficients to get to it, which can be expensive (Huffman).
I'm curious about the low-quality preview you get when scrolling through all the shots. Are you storing low-quality data separately or do you also have a fast, low-qual JPEG decoder? (Is the Huffman encoding between blocks independent?)