useful new feature of cjpeg

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
Post Reply
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

useful new feature of cjpeg

Post by NicolasRobidoux »

If I understand correctly, ImageMagick relies on the JPEG club's delegate programs to produce jpegs.

There is a useful new feature which I think would be very easy to implement:
-quality N[,...] Compression quality (0..100; 5-95 is useful range)
...
The -quality option has been extended for support of separate quality settings for luminance and chrominance (or in general, for every provided quantization table slot). This feature is useful for high-quality applications which cannot accept the damage of color data by coarse subsampling settings. You can now easily reduce the color data amount more smoothly with finer control without separate subsampling. The resulting file is fully compliant with standard JPEG decoders.
(from http://jpegclub.org/)

If this could make it in IM, I'd start using it immediately.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: useful new feature of cjpeg

Post by NicolasRobidoux »

There is another advantage to this: Chroma with less quality that works with sprite mosaics of images which are multiples of 8, but not 16, in size.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: useful new feature of cjpeg

Post by NicolasRobidoux »

Is there any objection to adding this to IM? If there are none, one of my grad students will (try to) do it.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: useful new feature of cjpeg

Post by magick »

Its would take just a few minutes to support multiple qualities with the command parser (we already support multiple sampling factors). Our question is how is it set with the JPEG delegate library. We currently call
  • jpeg_set_quality(&jpeg_info,(int) image->quality,MagickTrue);
What method do we use to set separate compression qualities?
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: useful new feature of cjpeg

Post by NicolasRobidoux »

Magick:

My student Adam Turcotte is finding that most linux distros use an older version of libjpeg which does not support different quality settings for luma and chroma. (*buntu 11.04 does have libjpeg8 as the default, however, so it appears that everything would be fine with it.)

It would appear to me that this would cause some grief for people installing IM within many current distros (Linux Mint 10, for example).

Does it make sense to you that he document what he figured for later reference, but that we leave IM alone for now?

Or did I miss something?

(We don't need the feature to be added to IM for our purposes anymore because we're using cjpeg (and then exiftool) directly on png/ppm ImageMagick output.)
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: useful new feature of cjpeg

Post by magick »

We can conditionally compile the quality setting so that new and older versions of libjpeg are supported. All we need is the new method to use to support different quality settings for luma and chroma and we'll create a patch for IM.
avant
Posts: 2
Joined: 2011-05-23T18:44:35-07:00
Authentication code: 8675308

Re: useful new feature of cjpeg

Post by avant »

It seems difficult to get libjpeg8 and libjpeg62 to coexist peacefully, so I haven't been able to directly test anything, but here is my understanding of how the quality setting needs to work:

As you mentioned, we currently call
  • jpeg_set_quality(&jpeg_info,(int) image->quality,MagickTrue);
where jpeg_info is an ImageInfo pointer, in this case (elsewhere it's a jpeg_compress_struct). According to http://jpegclub.org/cjpeg/ there are new q_scale_factor[] fields in jpeg_compress_struct, so I assume that ImageInfo will have to be updated to reflect this (not entirely sure).

Anyway, looking at the code for jpeg_set_quality(), it simply does the following:
  • quality = jpeg_quality_scaling(image->quality);
    jpeg_set_linear_quality(&jpeg_info, quality, MagickTrue);
So we need to call jpeg_quality_scaling for luminance and chrominance separately. Following the example at http://jpegclub.org/cjpeg/ where we want to set luminance to 90% and chrominance to 70% (cjpeg -quality 90,70), we have
  • jpeg_set_defaults(&jpeg_info);
    jpeg_info.q_scale_factor[0] = jpeg_quality_scaling(90);
    jpeg_info.q_scale_factor[1] = jpeg_quality_scaling(70);
    jpeg_default_qtables(&jpeg_info, MagickTrue);
    jpeg_info.comp_info[0].v_samp_factor = 1;
    jpeg_info.comp_info[0].h_samp_factor = 1;
It seems like this would be an easy modification to implement, but libjpeg8 is giving me trouble.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: useful new feature of cjpeg

Post by NicolasRobidoux »

From the cjpeg documentation, you need to have (the equivalent of) -sampling-factor 1x1 for multiple quality settings to work, hence

Code: Select all

jpeg_info.comp_info[0].v_samp_factor = 1;
jpeg_info.comp_info[0].h_samp_factor = 1;
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: useful new feature of cjpeg

Post by magick »

Since -quality does not support multiple fields, we'll need to use a define (e.g. -define jpeg:linear-quality=90,70). We'll get a patch into ImageMagick soon.
Post Reply