Today's theme is Jpeg2000. I have spent a bit of time investigating exactly what is the status of Jpeg2000 and if it's usable in Infinity.
Jpeg2000 is a much, much improved version of the old Jpeg standard. It supports alpha channels. It can be lossy or lossless. It supports 16 bits per component. It allows one to decompress an image of a lower resolution directly into memory ( without having to decompress to the original resolution and shrink it ). And best of all, at equivalent disk space usage ( imp.: to Jpeg ), it has a much higher quality. Often when Jpeg is very compressed, you can notice small artifacts: blocks of 8x8 pixels. This is no longer the case with Jpeg2000. Of course, higher compressions still mean loss of details, and the image gets blurry - but the artifacts are no longer visible..
All of those are excellent reasons to switch to Jpeg2000 in Infinity. But there's one thing to be careful about: that's performance. Jpeg2000 has a price..
So today i evaluated two Jpeg2000 libraries: J2K-codec ( http://j2k-codec.com/ ) and Jasper ( http://www.ece.uvic.ca/~mdadams/jasper/ ). I must add that i'm mostly interested in the decoding ( loading ) performance.
Jasper is considered to be pretty slow, but it's open source. J2K has a free trial but costs a small fee to be used in commercial project ( nothing to stop me if it's good ). J2K claims to be up to 54 times faster than Jasper. So i had to make a few benchmarks to see if it's true, and if the performance is usable.
The results are as follows:
A. The reference is loading a TGA image of 1024x1024 RGB, weighting 3 MB, uncompressed. When the hard drive cache is warmed up, it takes 14 ms on my Pentium D 830 @ 3 Ghz with a standard hard drive. I'm not sure how to disable the hard drive cache, so the result is flawed, as it's mostly a bandwidth operation rather than an I/O operation. It would probably be 3 or 4 times slower if the file was read for the first time.
B. Loading a JPEG version of the image, compressed to 171 KB, using the OpenIL image library. Takes 71 ms. That'll be another good point of reference: if loading a Jpeg2000 image is much slower than that, it won't be good.
C. Loading a JP2 version of the image, compressed to 154 KB, using J2K: 180 ms.
D. Loading a JP2 version of the image, compressed to 154 KB, using Jasper: 1390 ms ( ouch ! ).
Here we got a speed up of 7.7 times when using J2K over Jasper. That's nice, but the problem is that even in J2K, it is still 2.5 times slower than reading an equivalent Jpeg...
Next, i decided to vary a bit the compression ratio ( the lowest, the more compressed it becomes, and the less disk space it takes ):
J2K:
385 ms at 80%
253 ms at 10%
180 ms at 5%
150 ms at 3%
135 ms at 2%
117 ms at 1%
Jasper:
1670 ms at 80%
1472 ms at 10%
1390 ms at 5%
1345 ms at 3%
1320 ms at 2%
1310 ms at 1%
The interesting thing is to notice how J2K speeds up with higher compressions. A file compressed at 1% of its original size is loading 2.1 times faster than one compressed at 10%. This effect doesn't happen in Jasper: a 1% file loads 1.12 times faster than a 10% one..
Finally, let's see how it scales with resolution:
J2K at 10%:
253 ms at 1024x1024
64 ms at 512x512
17 ms at 256x256
Jasper at 10%:
1472 ms at 1024x1024
325 ms at 512x512
180 ms at 256x256
Infinity uses high resolution textures: 1024x1024 and 2048x2048. At those resolutions, J2K is between 5 to 10 times faster than Jasper, but it's still 3 times slower than Jpeg... it's a bit disapointing. I'm still wondering wether to use Jpeg2000 or not.
Could you not consider some sort of threaded/delayed loading of resources to mask the performance? I've not tried it much, but the D3DX10 'thread pump' architecture looks quite capable and fairly straight-forward to borrow - I've read stories of other people having great success with similar techniques.
Jack