Querying lossless mode during decompression with libjpeg API

19 views
Skip to first unread message

kevle

unread,
Jan 21, 2024, 7:59:11 AM1/21/24
to libjpeg-turbo User Discussion/Support
Hello everyone,

I have been trying to find out if I can determine whether a jpeg file is lossless or lossy when decompressing it using the libjpeg API.
From what I can tell, it might be possible that the internal state in "master->lossless" is setup after a call to "jpeg_read_header".
However, I have not seen a way to access that property by using the public API.

In TurboJPEG API 3, there is "tj3Get" and "TJPARAM_LOSSLESS" that can probably be used for the same purpose.

The question is, can I also access the "lossless" property using the public libjpeg API or is there an indirect way of deriving that information with public API calls?

Best regards,
Kevin

DRC

unread,
Jan 21, 2024, 12:21:10 PM1/21/24
to libjpeg-t...@googlegroups.com

The lossless JPEG feature was originally implemented by Ken Murchison as a patch against libjpeg v6b in 1999.  (The patch was never adopted into libjpeg, probably because Tom Lane was already moving away from the project at that point.)  As implemented, Ken's patch introduced new fields into the public jpeg_compress_struct/jpeg_decompress_struct structures that allowed lossless mode to be enabled (compression) and queried (decompression.)  However, that broke backward API/ABI compatibility, which is a non-starter for libjpeg-turbo.  Thus, in the process of integrating Ken's patch, I heavily restructured it and moved the new lossless parameters into the private jpeg_comp_master/jpeg_decomp_master structures.  (Refer to https://github.com/libjpeg-turbo/ijg/commits/6b_lossless to see how this all played out prior to the feature being merged into libjpeg-turbo.)

The lack of an intuitive way to query lossless mode in the public decompressor API was an oversight on my part.  However, the good news is that you can still do it.  It's just really subtle and requires digging through wizard.txt to figure it out.  In a lossless JPEG image, Ss will always be non-zero and Se will always be 0.  That's because Ss in a lossless JPEG image is the predictor selection value, which must be between 1 and 7 (inclusive), and Se is specified to be 0.  That combination of scan parameters is illegal for a lossy JPEG image, in which Se must be greater than or equal to Ss.  Thus, if any scan has Ss != 0 and Se == 0, then the JPEG image is lossless.  The compressor takes advantage of that fact to automatically enable lossless mode if a scan script specifies a scan with Ss != 0 and Se == 0:

https://github.com/libjpeg-turbo/libjpeg-turbo/blob/335ed793f92370edbb425d56fe9c07aab5a93d9a/jcmaster.c#L184-L193

Thus, lossless mode can implicitly be enabled through a scan script without explicitly calling jpeg_enable_lossless(), just like progressive mode can implicitly be enabled through a scan script without explicitly calling jpeg_simple_progression().

To make this more intuitive, I would probably need to introduce the get/set API that I implemented for mozjpeg, which extends the public libjpeg API to allow getting and setting the value of arbitrary parameters (including those that are stored in the opaque master structures.)  That would not break backward API/ABI compatibility, but it would break forward API/ABI compatibility (meaning that applications that took advantage of the new functions would not work with prior versions of libjpeg-turbo.)  Thus, I would have to be really careful when integrating the feature, and it would probably have to land in a major new release rather than a bug-fix release.

Since the decompressor automatically handles lossless vs. lossy mode, it isn't functionally critical for applications to have that information.  Thus, since there is already a non-intuitive but still straightforward and reliable way to obtain that information, my inclination is not to introduce a major new feature solely for that purpose.

--
You received this message because you are subscribed to the Google Groups "libjpeg-turbo User Discussion/Support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to libjpeg-turbo-u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/libjpeg-turbo-users/1ddcbe50-7118-4aa6-a6ec-99e99b91627bn%40googlegroups.com.

kevle

unread,
Jan 22, 2024, 1:45:49 PM1/22/24
to libjpeg-turbo User Discussion/Support
Thanks a lot! That is exactly what I needed to know.
The additional context makes all the difference.


>> Since the decompressor automatically handles lossless vs. lossy mode, it isn't functionally critical for applications to have that information.
A brief description of the motivation for having lossless vs. lossy mode information available:
From what I can gather, the DCMTK library bundles an adapted libjpeg v6b version with Ken's patch applied and some additional fixes.
When it comes to color space conversion, there is a flag that allows color space conversion only when the file has been stored lossy:


Upon looking into the possibility of replacing the bundled libjpeg version with libjpeg-turbo, knowing when the code is dealing with decompressing a lossless image was one of the roadblocks.

Thanks again!

Best regards,
Kevin

DRC

unread,
Jan 22, 2024, 1:48:49 PM1/22/24
to libjpeg-t...@googlegroups.com

Glad I could help.  It's good to see uptake of the new lossless feature in downstream software.

Reply all
Reply to author
Forward
0 new messages