Ah, excellent. I was hoping to integrate JPEG XL into a future C project and was facing the prospect of reimplementing it/translating the standard implementation.
Seriously though, this is going to be HUGE for image editors. A format that finally supports both layers and animation.
I think the exact code for features in that diagram does fit in 5K lines of code. More specifically an entropy coder is less than 1K LoC, the modular mode and transform is probably 1.5K LoC, the entirety of VarDCT is probably 2K LoC. The problem is that JPEG XL has a lot of other features to make it viable as a long-term format, and I greatly underestimated that complexity at the beginning.
JPEG XL format internals are beautiful -- control structures are self-similar and the image coding itself is used to code substructures, similar to WebP lossless.
libjxl C++ implementation is modern high-performance multi-threaded SIMD code, with layering, animation, streaming and progressive features, it can look scary. With some less emphasis on performance it could be written rather elegantly.
Indeed, I think writing a JPEG decoder is not really difficult, yet still challenging enough to be interesting, and something I believe everyone should try sometime. (I've written one before too.) The official standard itself (ITU T.81) is not hard to follow either, and contains a lot of useful flowcharts showing the decoding and encoding process.
It was surprising to me how few unique implementations there are of JPEG at all. Dig deep enough into most open source image libraries for almost any language, and eventually you'll find IJG libjpeg or one of its descendants.
Anyone interested in doing an independent implementation can use this specification (or a recent draft of the upcoming 2nd edition).
Alternatively, you can look at the source code of one of the three JPEG XL implementations currently available: libjxl, J40, and jxlatte. These are all open-source, and in a way that's an executable specification.
JPEG is actually ~12 bits deep, it's just that all the decoders decode it to 8 bit YCbCr, and on top of that cause extra loss by 8-bit YCbCr->RGB conversion. It's possible to compile libjpeg with a 16-bit color pipeline, but it's a hassle, so nobody does that.
You can probably learn something from what is available on jpeg.org and jpegxl.info, as well as looking at the libjxl or j40 implementations. Is there anything in particular you would like to know?
BTW, the old JPEG is a ~12-bit format. It's widely assumed to be an 8-bit format, because libjpeg by default gives you output truncated to 8 bits. Unfortunately, libjpeg made higher depth outputs an either-or compile-time option that breaks the ABI, so nobody enables that mode.
A Wasm implementation of JPEG XL is 174 kB, and a minimal implementation (reflecting the libjxl-tiny encoder) can be done in somewhere around 25-50 kB. Wasm is rather performant and can render both normal and HDR JPEG XL's in browsers.
A Wasm implementation of JPEG XL is 174 kB, and a minimal implementation (reflecting the libjxl-tiny encoder) can be done in somewhere around 25-50 kB. Wasm is rather performant and can render both normal and HDR JPEG XL's in browsers.
QOI is confusing simple with primitive. It's worsening compression only due to trauma of using dependencies in C.
I strongly disagree with characterization that JPEG is overcomplicated, especially in a controlled situation where you only need to support files you encode yourself (as is the case with QOI), and not edge cases like Adobe's CMYK extension.
JPEG's design is brilliant for the level of compression it's capable of. libjpeg API is crufty, and C dependencies are a pain, but you can use other implementations and languages.
Why write another article on JPEG when there are already hundreds of articles on the internet? Well, normally when you read articles on JPEG, the author just gives you details about what the format looks like. You don’t implement any code to do the actual decompression and decoding. Even if you do write code, it is in C/C++ and not accessible to a wide group of people. I tried to change that through this article. I give you a guided tour of JPEG encoding/decoding process and show you how it can be implemented in Python3.
I mainly focus on decoding baseline encoded JPEG images.
reply