Jpeg 2000

Published January 17, 2007
Advertisement
No, i didn't forget Shadowing part II. But as i have a lot to say, i need to block an hour or more in order to write the "article" :)

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.
Previous Entry Shadowing part I
Next Entry Fast Perlin noise
0 likes 12 comments

Comments

jollyjeffers
Interesting write-up - thanks for sharing [smile]

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
January 17, 2007 03:23 PM
Jotaf
Looks like Enigma here is working on a Jpeg2000 loader, and even at a very early stage he claims it's quite fast. I wouldn't be surprised, the libraries you mentioned are full of bloat :)

Here's the link, in case you don't read his journal already:

http://www.gamedev.net/community/forums/mod/journal/journal.asp?jn=410678&reply_id=2875235
January 17, 2007 06:28 PM
Ysaneya
Quote:Original post by Jotaf
Looks like Enigma here is working on a Jpeg2000 loader, and even at a very early stage he claims it's quite fast. I wouldn't be surprised, the libraries you mentioned are full of bloat :)


Pretty cool :)

I don't think it's faster than J2K. He mentions 1.5 seconds to load a 2048x2048 image. J2K loads a 1024x1024 image in 253 ms. Assuming linear scaling, a 2048x2048 would take about 1 second to load in J2K.
January 18, 2007 03:41 AM
Poo Bear
We use j2k codec and it's been really great, although obviously our texture sizes are much smaller than yours. Some info here if you scroll down to 'download size'

http://www.moonpod.com/board/viewtopic.php?p=13609#13609


On another project we were using Jasper and had to decompress everything at install time. That's still an option if using jpeg2000 on load is slow.
January 18, 2007 03:56 AM
Jason Z
Isn't the compression / decompression times content based as well? For example, a repeating texture is likely to be more quickly compressed than a very high frequency texture, meaning that there is a potential for better performance - or is this a totally different compression scheme?
January 18, 2007 05:22 AM
Ysaneya
Some news:

The comparisons were flawed since all the files were recently cached by the hard drive, making I/O non-significant.

In other word, my results only compare CPU work, and not I/O + CPU work.

I re-tested by making sure the files weren't in the hard drive cache yet, and the new results are:
TGA: 102 ms ( vs 14.3 ms when cached )
JPG: 151 ms ( vs 71 ms when cached )
JP2: 218 ms ( vs 180 ms when cached )

This lessens the performance hit between loading JPG and JP2 files.

Loading TGA files is still a bit more than 2 times faster, but i think i can live with that.
January 18, 2007 08:02 AM
tamat
IMHO decompressing algorythms for JPG2 will be faster with time as has happened with all other algorythms, when your game is finished probably the Jasper lib will go faster or there would be another one to replace it.

And about using JPG or JPG2, well, nobody could stand the JPG artifacts, and going straight to the kind of game you are coding, textures wont come all together at the very same moment, they probably will be loaded one every few seconds or more (at events like a ship entering your area), so I dont think its a problem to have a separate thread loading and decompressing if you can save memory/bandwich and keep a nice quality.

But as I say, thats just my humbre opinion.
January 18, 2007 11:10 AM
Enigma
Quote:Original post by Ysaneya
Quote:Original post by Jotaf
Looks like Enigma here is working on a Jpeg2000 loader, and even at a very early stage he claims it's quite fast. I wouldn't be surprised, the libraries you mentioned are full of bloat :)
Pretty cool :)

I don't think it's faster than J2K. He mentions 1.5 seconds to load a 2048x2048 image. J2K loads a 1024x1024 image in 253 ms. Assuming linear scaling, a 2048x2048 would take about 1 second to load in J2K.
I don't expect to be faster than J2K-Codec yet, but then I have a list of optimisations still to implement. Eventually I expect/hope to be pretty competative speed-wise with J2K-Codec, with the following advantages/disadvantages:
  • Advantages
    • Free (as in beer)
    • Free (as in speech)
    • Portable static linking

  • Disadvantages
    • Not a complete Jpeg2000 implementation
    • No technical support
    • Naff name
    Also, I don't see anywhere that mentions whether or not J2K-Codec offers a multi-threaded soultion, but the Jpeg2000 decoding algorithm should be heavily parallelizable and I hope to take advantage of that.

    Anyway, keep up the good work on Infinity and the interesting journal entries,

    Σnigma
    January 18, 2007 01:01 PM
    glitchz
    As AP mention ealier, I don't understand why you are not using DDS. You might have a good reason, but if loading performance is the problem you are trying to solve, DDS is the way to go. The DDS file format is natively supported by graphics card. You save loading time, and memory. It also support alpha.

    But my guess I that you know about all that and you have other motives to use JPEG2000 (I see one : why not ? ;p)

    My 2 cents,

    ps: amazing work btw
    January 19, 2007 02:22 AM
    tamat
    Well, just check the compresion algorythms of DDS... the colors are totally wasted, if you have gradients then the result will be horrible. Maybe there is a latest DDS internal format I havent check...

    In the other hand, as Ysaneya said in previous post, he wants to create the mipmaps by hardware (I guess using shaders and renderToTexture, make a post when you can about that) so he dont want to store mipmaps.

    January 19, 2007 04:46 AM
    You must log in to join the conversation.
    Don't have a GameDev.net account? Sign up!
    Profile
    Author
    Advertisement
    Advertisement