March 24, 2011

Using Google's WebP Image Format with Open Tools on Linux

Google's WebM project, the free and open video codec based on VP8, offers tantalizing benefits for fans of Linux and open source: better quality, plus full support in the browser and other applications, thanks to the lack of royalty-demanding patent holders. Often overlooked in the WebM story is the other media format unveiled by Google at the same time: WebP, a lossy still-image format said to provide better-than-JPEG quality at substantially slimmer file sizes. Is WebP poised to displace the stodgy old photo format? Let's take a look at the free tools available for writing, converting, and displaying WebP files to find out.

Image is Everything

For starters, we need to understand what WebP is. The format is lossy, like standard JPEG, meaning that it uses compression to remove bytes in a way that (hopefully) the eye will not notice. JPEG files typically split the image into 8-by-8 blocks, then perform a discrete cosine transform (DCT) on each block, and toss out some of the least-significant-digit data in the resulting high frequencies. That's where most of the size savings come from; our eyes aren't as sensitive to that high-frequency data, so JPEGs sweep them under the carpet.

There are actually quite a few options defined by the JPEG codec standard (including lossless compression), which is what gives rise to the JPEG "quality" setting — as you crank the quality down when you export an image, the algorithm adapts to toss out more and more information. But the gist remains the same.

Example JPEG and WebP conversion - this WebP image is 39.3% smaller.WebP compression is essentially an adaption of a single frame of WebM video. It, too, breaks the image into blocks (although 4-by-4 in size, rather than 8-by-8), but in place of JPEG's DCT and high-frequency bit-chopping step, it uses the intra-frame coding algorithm from WebM. Intra-frame coding is the coding down within a single frame, as opposed to between two consecutive frames, and WebM's method involved constructing a prediction for each block based on the blocks adjacent to it. The encoder saves the predictions and the differences between the predictions and the real input blocks in the output file — if prediction is going well, as it should for most continuous-tone images like photos, the output is smaller than the raw input — and the result compressed with lossless techniques.

The fun part is that WebM's block prediction algorithm can use several different techniques, which can generate better results than JPEG's one-size-fits-all approach. On the other hand, the codec is substantially more complex mathematically, so encoding takes longer. It is possible to parallelize decoding of WebP images, however, so at least the viewer won't have to invest noticeably more time.

The Google Toolkit

Google provides a "reference implementation" toolkit called libwebp for download on Google Code. The bundle is currently at version number 0.1, and includes two command-line tools, a static library, and C header files for use with other applications. All are licensed under the BSD-style terms used by the WebM project as a whole. Binary packages are provided for 32-bit and 64-bit Linux, as well as Mac OS X and Windows, and a source code archive is available, too.

To get started with the Linux bundle, you'll need to unpack the archive, moving the cwebp and dwebp binaries into the directory of your choice and making sure that you have execute permission. They are linked against libjpeg and libpng, but there is no installer script included in the bundle, so there is no checking enabled to ensure that you have both libraries installed. They're fundamental fare these days, though, so you almost certainly do.

The WebP library is named libwebp.a and can be used to add WebP encoding and decoding support to an application. The accompanying README file describes the encoding and decoding APIs, including several encoding functions for different RGB data types, plus pseudocode. The necessary headers are provided in the "include" directory. For a developer needing to implement WebP, this is a good starting point, but to experiment with the format, the CLI tools are a quicker way to begin.

Encoding WebP

The cwebp tool takes a PNG or JPEG image as input, and converts it to WebP format. The dwebp tool takes a WebP image and converts it to a lossless PNG. This allows you to view the affects of your WebP conversion experiments even without a WebP-supporting client app (of which there are few at the moment).

Cwebp exposes several levels of algorithmic adjustments you can play around with to tweak your compression results or to investigate the various parameters of the format. The simplest option is the -quality NN.nn flag, which takes a floating point number in the range 0 to 100. 100 represents the highest-quality output and thus the largest file size. For reference, the default quality setting is 75. Thus the most basic usage of cwebp would be cwebp filename.png, which would produce a 75-quality WebP output image, and name it filename.webp.

The next step up in complexity is to use cwebp's built-in presets, each of which supplies a full array of encoder settings in one fell swoop. The presets are photo, picture, drawing, icon, and text, and you use them by supplying the preset you want after the -preset command-line option, as in cwebp -preset drawing filename.png. Using -preset overrides any other command-line switches you supply as arguments.

Unfortunately, neither the web-based or downloadable documentation goes into any detail about exactly what parameters each preset sets — and there are a lot of parameters available. For those seeking the most complex adjustments possible, cwebp includes eleven command-line switches to tweak individual encoding parameters. The full list is:

-f strength of deblocking filter, integer 0 to 100, default 20
-m thoroughness of compression method option examination, integer 0 to 6, default 4
-sns spatial noise-shaping, integer 0 to 100, default 80
-segments number of segments used by sns algorithms, integer 1 to 4, default 4
-sharpness filter sharpness, integer 0 to 7
-strong use "strong" filter rather than "simple," default off
-pass number of analysis passes, integer 1 to 10
-size target size in bytes
-psnr target peak signal-to-noise ratio in decibels.
-af auto-adjust filter strength, default off
-pre pre-processing filter, integer


Here again, the availability of the parameters is nice, but the documentation is sporadic at present. Google claims that 30-40% size reductions over JPEG with no discernible loss in quality is average, with even greater savings possible under certain circumstances. I have seen users claiming 80% reductions, although they do not have their full test data available. There is a gallery page on the WebP site that includes sample images and — more importantly — describes the cwebp settings used to create them.

Decoding WebP

Size savings are great, but unless you are a determined image archivist, there is no point to switching to a new format unless people can see the resulting files. For WebP viewing, there are several interesting options to consider.

First, the WebP toolkit includes the dwebp converter utility. Like cwebp, it is command-line only, and simply converts a WebP file into a lossless output file. The basic syntax is straightforward, dwebp filename.webp. You can specify an alternate filename with the -o outputfilename.png switch. By default dwebp produces PNGs, but you can also convert to PPM files with the -ppm flag or to PGM with the -pgm flag.

The fact that you can only convert to this small set of lossless file formats betrays the fact that dwebp is designed for experimentation only, so that you can compare cwebp encoding tests and contrast them with JPEG and other formats looking for artifacts. But can anyone in the real world decode WebP images? Surprisingly, yes.

Google has included WebP support in Chrome and Chromium since version 9, so you can view WebP content directly in either browser. It is therefore a good idea to look at the WebP gallery mentioned above in Chrome rather than another browser, since you can make direct quality comparisons rather than step through the convert-to-lossless process. It is also much faster to open your own images in Chrome than to re-convert them with dwebp. Opera added WebP support in its latest development snapshots, so support is right around the corner.

Firefox does not yet have support for WebP, even in the just-released Firefox 4, although there are patches targeting the next release cycle. Normally, adding Firefox support for a new media format would be provided by a browser plug-in, but in the case of WebP this is not necessary. That is because Firefox 4 includes built-in decoding of WebM video content and, as you recall, a WebP image is secretly just a single frame of WebM video.

Since WebM decoding is provided by the Gecko renderer and not by a plug-in, it can be leveraged by JavaScript. A small JavaScript script named Weppy is hosted at GitHub that can take a .webp <img> element and converts it into a single-frame WebM <video> element. So if you want to publish WebP content directly on the Web for enjoyment by Firefox users, you can do so by including weppy.js in your page — your visitors will never even know there difference. You can read more about Weppy's functionality and see example code at the author's blog.

If the viewing tools seem browser-centric, that's precisely because WebP is intended as a Web publishing format, not an archival format like TIFF or an image editing format like XCF or OpenRaster. But WebP support is slowly trickling out to other applications; there is a Photoshop plug-in, and support for open source applications is probably going to come through continued development of libwebp. It has not landed in a big way yet, but it is something to watch.

The million-pixel question remains Will WebP Replace A Significant Portion of JPEG's Share Among Web Images? It's too early to tell. There have been other JPEG-replacements in the past, including JPEG2000, and even among graphics professionals, few even remember them. But WebP does have one advantage most of the other solutions don't: it is free of royalty-bearing patents, like the original JPEG format.

Multimedia format wars — particularly as they relate to the Web — are an understandably hot topic for Linux and open source users, because they often involve thorny issues like software patents, royalties, and open standards. WebP's free and open status gives it a leg up, but not a free pass. Google claims that in spite of rapid growth of video on the Web, still photos continue to account for a significantly larger chunk of the browsing bandwidth used. I'm not sure that the size savings for any particular small site are a make-or-break determiner, but if a large image publishing warehouse like Flickr were to adopt WebP, the savings would be enormous, and the format an overnight success.