Page 1 of 1

useful new feature of cjpeg

Posted: 2011-05-20T10:44:42-07:00
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.

Re: useful new feature of cjpeg

Posted: 2011-05-22T14:06:58-07:00
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.

Re: useful new feature of cjpeg

Posted: 2011-05-23T17:12:06-07:00
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.

Re: useful new feature of cjpeg

Posted: 2011-05-23T17:53:41-07:00
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?

Re: useful new feature of cjpeg

Posted: 2011-05-26T06:30:49-07:00
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.)

Re: useful new feature of cjpeg

Posted: 2011-05-26T08:54:56-07:00
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.

Re: useful new feature of cjpeg

Posted: 2011-06-02T09:49:02-07:00
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.

Re: useful new feature of cjpeg

Posted: 2011-06-02T10:32:45-07:00
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;

Re: useful new feature of cjpeg

Posted: 2011-06-02T11:55:58-07:00
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.