Web Performance Calendar

The speed geek's favorite time of year
2014 Edition

MozJPEG 3.0

by Kornel Lesiński
Kornel Lesiński photo

(@pornelski). Web developer since “best viewed in AWeb in 640×256.” Creator of ImageOptim. London Standardista.

Mozilla has done a study of image formats and concluded that WebP and JPEG XR are not a big-enough improvement over well-optimized JPEG. In the study only HEVC (H.265) was significantly better, but it’s a patent-encumbered format, so it can’t be used freely (shhhh!)

It seems that Mozilla has a short-term and a long-term plan for image compression. They’re sponsoring development of the Daala codec, which is technically very interesting, but not production-ready yet.

For the short term Mozilla has developed MozJPEG — a modernized JPEG encoder that offers better compression while remaining fully standard-compliant, so it’s compatible with all browsers, operating systems and native apps, and you can use it today without waiting for the whole world to upgrade (BTW: if you need the same for images with alpha channel, try lossy PNG).

MozJPEG features

Advanced compression

In addition to all standard libjpeg optimizations MozJPEG performs progressive scan optimization—a trick from the jpegcrush/jpegrescan tool. Parameters of progressive JPEG passes influence compression, so it’s possible to make smaller files by tuning them just right. It’s like having ImageOptim built-in.

MozJPEG also brings to JPEG a technique from modern video codecs called trellis quantization. Simple JPEG encoders discard a fixed amount of detail according to quality set, but MozJPEG looks how many bits it would cost to write each detail and discards details that compress the least. This makes files much smaller, but also tends to make images look softer (which, depending on an image, may be a good or a bad thing).

Cleaner black-on-white text and lines

JPEG is known for being terrible for compression of text and cartoons. Well, I’ve fixed that (partially): now MozJPEG won’t create ugly gray halos around high-contrast edges on a white background.

libjpeg 6b (6.2KB)
cjpeg -sample 1x1 -quality 16
Deringing disabled (6KB)
cjpeg -noovershoot ...
cjpeg -sample 1x1 -quality 35.5

BTW: In this case JPEG’s file size is about the same as 32-color PNG’s! Image by xkcd.

Smoother high-DPI “compressive” images

JPEG files have quantization tables that allow fine-tuning of quality for various levels of detail. It’s like an audio equalizer with 64 knobs—e.g. you can choose whether you want sharper edges or less blocky gradients).

Modification of quantization tables used to be a hidden option reserved for the most advanced users. MozJPEG made it more accessible by adding a few good presets. It’s especially useful for high-resolution images. Standard JPEG tables have been tuned for low-DPI displays, and for compressive images tend to put too much emphasis on tiny details over accurate color reproduction.

ImageMagick (20.8KB)
convert -quality 18
MozJPEG (20.6KB)
cjpeg -quant-table 2 -quality 29.4

To be fair, technically you can get a decent result from ImageMagick, but it takes a few obscure options and an XML file.

libjpeg and libjpeg-turbo compatibility

MozJPEG is binary-compatible with both libjpeg-turbo and the classic libjpeg. This makes it possible to use MozJPEG as a drop-in replacement for libjpeg, and even install it as a system-wide replacement.

The latest release has been made with help of libjpeg-turbo maintainer. MozJPEG and libjpeg-turbo adopted a common future-proof API that allows programs to be compatible with both libraries and still take advantage of each library’s specific features.

How can I use it?

Ask makers of your favorite graphics programs to integrate MozJPEG! No, really. MozJPEG is a library for developers, and on its own is not useful to people who don’t like compiling C programs.

I’ve quickly hacked a web interface for you.

If you want to run MozJPEG on your own machine, then you’ll need to use an ugly command-line program. I’ve built a binary for OS X, but on other systems you may need to compile it yourself:

  1. Get the latest mozjpeg release.
  2. Run ./configure && make in mozjpeg source directory (you’ll need a compiler installed.)
  3. Hope you don’t get a million compilation errors.
  4. If it succeeds, you’ll be able to run ./cjpeg in this directory (the ./ prefix is important, otherwise you may invoke an old version bundled with your system.)
  5. You can run sudo make install if you want cjpeg (and other mozjpeg libraries/tools) installed system-wide.

And then:

./cjpeg -quality 70 -outfile compressed-image.jpg source-image.png
  • The -quality option accepts fractional numbers (necessary if you want to make a fair benchmark) and two numbers separated by commas to set quality of brightness and color separately, e.g. -quality 60,70.
  • -sample 1x1 enables full-resolution color (e.g. red lines won’t be smudged as badly), but it makes files larger.
  • -quant-table 2 (mentioned earlier) makes images softer and reduces posterization in low qualities.
  • -notrellis makes images sharper, but increases file size.
  • -outfile defines path where result is (over)written to.
  • And the last argument is the source image. It can be a PNG, a very high-quality JPEG or Targa.

You can combine cjpeg with ImageMagick like this:

 convert -resize 50% source-image.png TGA:- | 
  ./cjpeg -outfile compressed-image.jpg -targa

The TGA:- | bit tells ImageMagick to quickly and cheaply pipe uncompressed data to cjpeg, so you don’t waste CPU on generating a temporary PNG file.

Happy compressing

Xiph.org’s researcher Tim Terriberry calls JPEG an “alien technology from the future”. JPEG, designed over 20 years ago, has got so many details right that it still remains competitive today, despite being much simpler and faster to decode than newer formats trying to dethrone it. And MozJPEG isn’t done yet!