But how to get textures in DXT format? Traditionally in games the textures are often pre-generated in DXT. This works fine in many cases, but for web apps may not be optimal, especially if the web app needs to load many such textures over a potentially slow internet connection. This is because DXT is designed to be fast to decode in hardware but is not as compressed as it could be. DXT1 for example takes 4 bits per pixel ("4bpp") while JPG, a very common image format on the web, can achieve lower bpp at equivalent quality. When optimizing for speed of loading images and textures, every bit counts. Ideally there would be a way to send a highly compressed texture over the wire and then quickly transcode it into DXT for use with WebGL.
The decode_test.html puts it all together. It loads crn-O2.js as a regular script, fetches a test .CRN file, calls functions from the generated crn-O2.js file to decode the .CRN file, uploads the resulting DXT compressed texture to WebGL, displays it using some code in renderer.js, and keeps some timing stats for display in a little table. The results are pretty impressive (to me, at least): I see ~50 megatexels/second on my setup (Chrome 19 on a nice linux box). For comparison, at this speed a 256x256 image would take a couple milliseconds to transcode, which is much better than the 16ms for transcoding JPG into DXT.
UPDATE: I added some code in dxt-to-rgb565.js to transcode from DXT into RGB565 so the texture can be displayed even if there is no DXT support. This transcoding would also be useful in real world applications that only want to serve one copy of the data. The transcoding from DXT into RGB565 seems to be about 5x as fast as the decode from CRN to DXT. Optimizing it was fun :)
Thanks to Rich Geldreich for developing Crunch and helping me with this little project. He was very responsive whenever I had questions, he provided the test .CRN files used here, and he ported the encoder to linux.
Also thanks to Colt McAnlis who first told me about Crunch and connected me with Rich.
Thanks to Travis Heppe for helping with the C++ code in crn.cpp (I am quite rusty at C++!).