Come on Google, eat your own dog food!

This is the Google logo usually featured on the site.
Google logo
The file logo11w.png weights 14022 bytes.
Google used to provide good advices regarding image file optimizations to speed up web page download. I'm pretty sure that a former version of this page had much more valuable tips about PNG optimization a few years ago (before WebP inception), nevertheless lets follow its advice and try to optimize this file using OptiPNG.


OptiPNG run, unable to further optimize the file

Now that's interesting, OptiPNG could not further optimize this file, in fact it could not even reach the same file size (using the -force option would have produced a 14426 bytes file). The good news is that Google is putting optimized files online, but what did they use if it's not OptiPNG?


At first I thought Ken Silverman's PNGOUT had been used since it is one of the best PNG optimization tool (free but unfortunately closed source, binaries are available for Windows, OS X, GNU/Linux and FreeBSD).
PNGOUT run, using default and -f0 filter
The first trial did not produce a smaller file, since I noticed that the default PNG filter method (f5 automatic) was sensibly different from the one already in place (f0 no filtering) I enforced this dumb filtering and managed to produce a smaller file. Bingo! Without too much tweaking this file is now 7% smaller.
PNGOUT run, using -f0 filter and -n3 (three Deflate blocks)
Fiddling a bit with PNGOUT block splitting options can lead to even more gains (but you'll probably not play with these options at first hand).
Now the bad news is that the Google logo file could be 12% smaller and I did not find the tool used by Google, let's try something else.


Google Zopfli is an open source compression engine that produces Deflate compressed data (it takes much more time than Zlib but the result is often between 5 and 10% smaller). ZopfliPNG brings together the advanced compression provided by Zopfli and some other nice features like smarter filtering heuristics in a handy PNG optimization tool. ZopfliPNG comes with the current Zopfli code ("make zopflipng" to build it).
ZopfliPNG run, using -m
Not bad to start with! Pretty close to the best (hand tuned) PNGOUT result indeed. Well it looks like I'm not going to find the tool used by Google (based on the regularity of the Deflate block size it's very likely based on Zlib, perhaps an old PNGcrush version) but I am somewhat appalled to discover that Google does not use and foster its own PNG optimization tools.
Now could we push this file compression even further? The answer is yes. Two different tricks could be used to reduce this PNG file size: doing some advanced transparency cleaning or ressorting to color quantization to turn this 32-bit (RGB+Alpha) PNG into a similar 8-bit (Palette+tRNS) one.

I see dead pixels

You cannot see fully transparent pixels since they are by definition invisible. When a given pixel has its alpha chanel set to zero it becomes fully transparent the associated RGB components are no longer revelant but still take space in the file. Basic "dirty transparency cleaning" sets the value of RGB components of fully transparent pixels to zero (resulting in black), advanced "dirty transparency cleaning" tries to set them to something even easier to compress. Cryopng was quickly hacked together to prove that this idea could positively affect compression, the original release was accompanied by a small script that tried all the different PNG filters and ran PNGOUT on this output.
cryogen script run
Remarkably the file logo11w-paeth.png breaks the 12000 bytes barrier.
This is what the RGB components of this file look like, basic -black- "dirty transparency cleaning" below.
logo11w-paeth.png alpha stripped
logo11w-none.png alpha stripped
A few weeks ago, I would have recommended the bash script called cryogen2 (requires GNU readlink, zopflipng, cryopng and defluff) to produce a similar result (cryogen2 optimized Google logo weights 11860 bytes).
cryogen2 script run
But running a script like cryogen2 that writes a lot of temporary files has its drawbacks (it doesn't scale well when you try to optimize many files simultaneously using multi-core processors). Since zopflipng is open source and I wrote cryopng in the first place, I took the time to shoehorn the equivalent of cryopng inside zopflipng (this is preliminary work there are still a few issues I'd like to iron out but it does the trick most of the time).
ZopfliPNG run, using -m --alpha_cleaner=0124
The --alpha_cleaner option is specific to my custom version of zopflipng (it replaces --lossy_transparent) and performs the same kind of alpha cleaning as cryopng (hopefully I will trial other cleaning methods soon) methods 0 and 1 are usually the best ones, 3 is often the worst (discarded here).
By setting the --iterations option to a beefy 2000 the file size goes down to 11791 bytes (setting it to the insane level of 48000 saves a few bytes but takes hours to process). Even when avoiding the --iterations option optimizing large images this way will quickly become dog-slow, a different approach may prove more fruitful...

Smallest Google logo PNG-32 so far
Smallest PNG-32 so far (11783 bytes)
TweakPNG snapshot showing only 3 PNG chunks: IHDR, IDAT and IEND

One is better than four

Contrary to GIF files PNG files based on a palette (aka PNG-8) have access to subtle transparency. The tRNS chunk can be used to individually set a transparency level for each color in the palette, this feature is not well known for two main reasons: Adobe Photoshop Save For Web does not handle it (Adobe Fireworks did, go figure) and Internet Explorer 6 was unable to properly display this type of transparency. If you consider IE6 as a thing of the past you can safely use this kind of PNGs.
Representation of the bytes inside of PNG-8, PNG-24 and PNG-32 image body
PNG-24 and PNG-32 images are "direct color" ones this means that the information recorded in the image body (in the IDAT -Image DATa- PNG chunk) directly represents the pixel color, therefore 3 or 4 bytes are recorded for each pixel (deep color 16 bits per component PNGs would take 6 and 8 bytes, but for common Web usage this type of color precision is definitely overkill). PNG-8 images are "indexed color" ones this means that the image body only holds references to the actual color of each pixel (its index in the palette), the palette is a subset (up to 256 colors) taken out of the usual 16,777,216 different possible colors. To properly reconstruct the image the palette has to be recorded beside the image body (in the PLTE -PaLeTE- PNG chunk) each color in the palette is defined by a 3-byte RGB triplet. This is pretty similar to the older GIF image format, the latter PNG format allows to supplement the RGB triplet with a full fourth component which is dedicated to alpha transparency (in the tRNS -tRaNSparency- PNG chunk, the lowercase t is not a typo it states that this chunk is not critical and unfortunately is probably the source of poor support in IE6 and other decoders) and this is way more advanced than the basic transparency support found in GIF where only one color could become fully transparent.
Replacing 3 or 4 bytes by a single byte index produces a huge space win but choosing the right colors to compose the palette is not an easy task, pngquant 2.3.5 is by far the best tool to convert full-blown PNG-32 files into PNG-8 ones while preserving transparency. Of course this is a lossy operation, posterization or noise may appear especially on images having lots of color gradients since the palette is definitely limited to 256 colors, but quite often the naked eye will not perceive a significant difference.
Two pngquant run, with and without dithering
The --nofs option controls whether Floyd-Steinberg dithering is applied, no dithering usualy produces smaller files but the image will have more pronounced color banding, in the other hand dithering will add some grain. Visual inspection is therefore nearly mandatory to pick the best looking image. Since pngquant is based on libpng/zlib its output can be furter compressed using pngout or zopflipng.

Smallest Google logo PNG-8 so far
Smallest PNG-8 so far (8069 bytes)
TweakPNG snapshot showing 5 PNG chunks: IHDR, PLTE, tRNS, IDAT and IEND


I'll make uptodate binaries of pngquant and my custom version of zopflipng available here soon (you can get it from cryopng page for now, warning still a work in progress).