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.
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.
No, a jpeg pixel is not "the summation of 64 8 bit coefficients." I've written jpeg codecs (and many other image formats). It works just as I explained above.
Or simply read the libjpeg source.
Don't like that, read this [1]: "JPEG images are always recorded with 8-bit depth. This means the files can record 256 (28) levels of red, green and blue."
Don't like that, here [2] is the JPEG ISO standard, section 4.11, baseline jpeg, "Source image: 8-bit samples within each component".
A DCT takes an 8x8 pixel input, 8 bits per channel, and transforms them into an 8x8 output. It matters not what these are - the information theory content is nothing more than what was put into it. There is not suddenly magically more information content.
More simply, appending zeroes to a number does not mean you can represent more numbers. You simply can represent the exact same numbers, just wasting more space.
None of what you wrote adds more resolution at the output. It simply isn't there.
If I give you 5 possible inputs to a function, then you have 5 possible outputs, not matter how many digits you finagle into representing the output.
Jpeg has 8 bits of resolution per channel. End of story. That is why professional photos are taken and edited in raw - you get more bits of resolution per channel.
I'm not sure why you're still arguing this. It's a longstanding, well known issue, and I explained it all again very simply.
If you think it isn't true, encode one of your magic jepgs with more than 256 levels of gray and post it here. Good luck :)
If you cannot do that, then maybe you should consider that you're wrong.
JPEG's technically limited to 64x64k dimensions per the spec (65500 pixels with libjpeg and libturbojpeg), so if you want arbitrary software to be able to open images in that format, you'd be limited to that...
> The way jpegli handles XYB color in a JPEG image is by applying an ICC color profile that maps the existing JPEG color channels to XYB. This actually has the potential to increase the bit depth of the image, which could allow 10 bit JPEGs in the future. I'm excited to see XYB JPEG continue to improve via jpegli, but for now we're just going going to use libjxl's included cjpegli binary to test some photographic images.
Actually the coefficients are 12 bit in JPEG, before quantization. In principle you can make pretty accurate 10-bit HDR JPEG files, and with an accurate JPEG decoder, it would work well enough.
The most common JPEG decoders though (in particular libjpeg-turbo) are using a cheap but not super precise iDCT that has 8-bit YCbCr as output, which then gets chroma-upsampled if needed and converted to 8-bit RGB. That causes the effective precision in reds and blues to be only 7-bit. But in principle you could have about 10 bits of effective RGB precision, it just requires a sufficiently precise JPEG decoder.
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.
I'm not aware of any photo editing software that can export 12bit JPEG (although to be fair I don't know many), I am aware though that JPEG 2000 supports 12bit color and that JPEG XT supports up to 16bit color, perhaps that's whats causing the confusion?
What you have described is usually called a 24 bit rgb image--not a 8 bit image. An 8 bit image can have only 256 distinct levels, whereas a jpeg can have ~16 million or 2^24 values for each pixel. 8 bit images are used often for medical imaging, but they are crude compared to 24 bit rgb images. One can argue that 24 bit rgb images are too crude, but they should not, IMHO, be called 8 bit images. But that is often what people say about jpegs. Typical jpegs with 8 bit coefficients have much more information than 8 bit images. Perhaps typical imprecise terminology?
[1] https://en.wikipedia.org/wiki/Color_depth#True_color_(24-bit...
[2] https://www.quora.com/How-many-colors-does-a-JPEG-contain
[3] https://en.wikipedia.org/wiki/JPEG#JPEG_codec_example << They walk thru the steps.
A jpeg pixel is not 64 eight-bit coefficients. Jpeg compresses an 8x8 pixel block at a time by taking a DCT (which mathematically is lossless, but in practice is not due to rounding and quantization at this stage), which turns those original 8x8 values into another set of 8x8 values, then some of these are thrown away and/or quantized for lossy compression.
Decompression is the reverse: take these 8x8 quantized DCT coefficients, perform an inverse 8x8 DCT top get pixel values.
The 11-bit dynamic range part you claim is merely from a color profile, which takes the resulting 8 bits per channel (i.e., 256 possible values) and spreads them over a gamma curve to an 11-bit range. But there are still only 256 possible levels per channel, too few for quality image editing.
Think of it as squaring: taking [0,255] as your input and squaring every value gives you a range of 0 to 255^2 = 65025, but that does not allow you to store any value in that range. It only allows you the 256 values that are squares.
So the dynamic range is 11 stops, but the number of representable levels per channel is still 8 bit: 256 levels. This makes gradients band no matter how you do them in JPEG.
It's why photo processing software wants RAW, not JPEG. JPEG, besides being lossy, does not allow enough steps.
One example: given a so-so RAW, at 11 bits, you can pull out dark things or darken bright things smoothly. This is not possible once you go to jpeg, for any implementation of jpeg.
Also good to know that Jpegli (a traditional jpeg codec within libjxl) allows for 16 bit input and output for '8-bit jpegs' and can deliver about ~12 bits of dynamics for the slowest gradients and ~10.5 bits for the usual photographs.
Jpegli improves existing jpeg images by about 8 % by doing decoding more precisely.
Jpegli allows for encoding jpeg images 30 % more efficiently by using JPEG XL adaptive quantization (by borrowing guetzli's variable dead zone trick), and the XYB colorspace from JPEG XL.
Together, you get about 35 % savings by using jpegli from the decoding + encoding improvements. Also, you get traditional JPEG that works with HDR.
Jpegli is predicted to be production ready in April or so, but can be benchmarked already.
This is really impressive even compared to WebP. And unlike WebP, it's backwards compatible.
I have forever associated Webp with macroblocky, poor colors, and a general ungraceful degradation that doesn't really happen the same way even with old JPEG.
I am gonna go look at the complexity of the JXL decoder vs WebP. Curious if it's even practical to decode on embedded. JPEG is easily decodable, and you can do it in small pieces at a time to work within memory constraints.
This isn't the default jpeg library. That's libjpeg. In this case, the `jpeg` bit isn't as interesting as the `-turbo` bit. Keeping up with the fastest way to implement JPEG on new architectures and CPUs is worthwhile.
JPEG has been growing on me lately. In addition to all of the clever information theory magic, it is also practically the fastest way to compress an image by miles.
I've got implementations on top of libjpegturbo that can encode with latency low enough to support interactive frame rates at modern resolutions. We are talking 1920x1080@4:4:4 in under 10 milliseconds.
This is of intense interest to me - I had no idea you could do this with an existing jpeg. 20% would be a world-changing difference for an application I am working on right now, assuming the added encoding/decoding stages do not add substantial latency to the process.
Is there some variant of libjpeg-turbo that works for XL?
reply