I did quite a bit more hacking on largeimagelib over the last few days. First of all, I converted the core to use tiles and not stripes, which helps the performance a lot when the viewport is smaller than the scaled image (but which may hurt a bit when downsampling images). A double-buffer was also added to reduce flicker — so now one can scroll around huge images at small zoom factors very smoothly. This wasn't quite enough when scaling huge images down a lot, however, as rescaling down 100 million pixels can take some time. So I implemented support for time limits for painting (rescaling is lazy, and hence done when painting, of course only for drawn regions). When the drawing code runs over the time limit, it stops doing expensive processing, and only shows tiles that can be fetched from the pixmap for the rest of the region, using black rectangles as a filler. It then generates a deferred update event for the still-unpainted range, using the same mechanism as in progressive loading. The end result is that if the image can't be scaled quickly, the app remains responsive, and the user can see it being scaled piecewise; and the application does not need to worry too much about it, either (I had to add one parameter to the draw call in the test kpart — that's it). This works very well — I can open a 13,000x13,000 JPEG of Mars, and scale it, scroll it, etc., however I want, without annoying "stuck" states. The only problem is that sometimes the timeout seems to trigger on smaller images, causing some flashing, so I may need to tweak it or to make the logic a bit more complicated.
I also implemented much of a progressive PNG loader, using libPNG, in a few hours this evening. It seems to work on all images I tried it with, although PNG supports a lot more types than are commonly in use; the code also needs testing on big-endian machines. The big missing piece is support for interlaced images. This needs some core tweaking in order to let the loader pull out partial scanlines from the image to merge in the updates. This is actually pretty easy, but it involves the tile locking code, and I try not to touch incremental algorithms late in the evening. Maybe I'll add it tomorrow or over the weekend.