#!/bin/sh # make-png-google-logo 0.1.0 (2004-Feb-12-Thu) # http://www.nicemice.net/amc/utils/#ppmuncomposite # Adam M. Costello # http://www.nicemice.net/amc/ # This script constructs an unofficial Google logo sticker as a PNG # file with a full alpha channel (so that it can be composited against # any background). The constructed image is derived algorithmically # from two of the official GIF image files that are pre-composited # against black and white backgrounds. Those files, Logo_60blk.gif and # Logo_60wht.gif, are fetched from the web if they don't already exist # in the current directory. The PNG stream is written to Logo_60any.png # in the current working directory, which must not already exist. # # WARNING: While Google has given everyone permission to use their # official logo sticker images in certain ways, they have *not* given # permission to display or distribute modified images, such as the image # produced by this script. See http://www.google.com/stickers.html. # This script is not blessed by Google in any way. # # The primary purpose of this script is not to generate a Google logo # image per se, but to demonstrate the technique of reverse-engineering # an uncomposited transparent image from two pre-composited images. # # NOTE: The PNG file produced by this script does a very good job of # approximating the official logo images when properly composited # against white and black backgrounds. Mozilla Firefox 0.8 (and # earlier) does the compositing improperly--it neglects to undo # the gamma encoding before compositing and redo it afterward, as # recommended and demonstrated in the PNG spec, which states that the # alpha channel indicates how to mix intensity samples, not how to # mix gamma-encoded samples. I don't know about other browsers. The # ImageMagick 5.5.7.9 command "composite -compose over" has the same # bug. # # This script depends on another script, ppmuncomposite, which must # either be in $PATH or be in the same directory as this script. This # script also depends on wget, some of the netpbm utilities, pngcrush, # and some customary Unix commands. tmpdir=/tmp/make-png-google-logo-$$ onblack_gif=Logo_60blk.gif onwhite_gif=Logo_60wht.gif gif_web_dir=http://www.google.com/logos/ width=176 height=77 outfile=Logo_60any.png cleanup() { cd / rm -rf $tmpdir } warn() { echo "$*" >&2 } fail() { warn "$*" cleanup exit 1 } # Make sure the output file doesn't already exist. [ ! -f "$outfile" ] || fail "$outfile already exists" # Create a temporary directory and copy the source GIF images into it. mkdir $tmpdir || fail "cannot mkdir $tmpdir" [ ! -f "$onblack_gif" ] || cp "$onblack_gif" $tmpdir [ ! -f "$onwhite_gif" ] || cp "$onwhite_gif" $tmpdir onblack_uri=$gif_web_dir$onblack_gif onwhite_uri=$gif_web_dir$onwhite_gif ( cd $tmpdir || fail "cannot cd $tmpdir" [ -f "$onblack_gif" ] || wget "$onblack_uri" || fail "cannot wget $onblack_uri" [ -f "$onwhite_gif" ] || wget "$onwhite_uri" || fail "cannot wget $onwhite_uri" read black_sum black_length junk << EOF `cksum "$onblack_gif"` EOF [ "$black_sum $black_length" = "3336891779 3455" ] || fail "unexpected checksum/length for $onblack_gif" read white_sum white_length junk << EOF `cksum "$onwhite_gif"` EOF [ "$white_sum $white_length" = "3221466317 5614" ] || fail "unexpected checksum/length for $onwhite_gif" # The GIF images contain some (completely) transparent pixels. Replace # them with black or white pixels (as appropriate) so that we have # simple opaque images to start from. # # In this case it's okay to use pnmcomp on gamma-encoded samples, even # though it does no gamma decoding before compositing, because all the # alpha values are 0 or 1 (GIF supports only binary transparency), and # therefore there is no mixing of pixels. giftopnm -alphaout=black-mask.pgm < "$onblack_gif" > black-fore.ppm giftopnm -alphaout=white-mask.pgm < "$onwhite_gif" > white-fore.ppm pbmmake -black $width $height | pnmcomp -alpha=black-mask.pgm black-fore.ppm > onblack.ppm pbmmake -white $width $height | pnmcomp -alpha=white-mask.pgm white-fore.ppm > onwhite.ppm # Align the images. Oddly, the black and white logos are not quite # aligned with each other. We need to shift the black image 1 pixel # to the left. (Actually, I think it wants to be shifted a little # more than 1 pixel to the left, and a little more than 0 pixels # upward. That could be accomplished by scaling up, then shifting, # then subsampling, but I doubt that the benefit of sub-pixel alignment # would outweigh the distortion introduced by resampling, and I doubt my # ability to determine the proper alignment so precisely, because the # two images are simply different in various ways when you look closely. # If we did do resampling, we'd first need to do gamma decoding, and # we'd want to convert to 16-bit samples before doing that, to avoid # losing precision.) mv onblack.ppm onblack-unshifted.ppm pnmcut -pad -left 1 -width $width < onblack-unshifted.ppm > onblack.ppm # pnmcut's -pad option conveniently pads with black pixels. If we had # been shifting the white image, we would have needed to use pnmpad. # Pop back out of the temporary directory so we can find ppmuncomposite. ) # Uncomposite. if type ppmuncomposite > /dev/null 2>&1; then ppmuncomposite=ppmuncomposite else ppmuncomposite=`dirname "$0"`/ppmuncomposite [ -x "$ppmuncomposite" ] || fail 'cannot find ppmuncomposite' fi "$ppmuncomposite" $tmpdir/onblack.ppm $tmpdir/onwhite.ppm \ $tmpdir/uncomp.ppm $tmpdir/alpha.pgm # Convert to PNG. pnmtopng -alpha $tmpdir/alpha.pgm < $tmpdir/uncomp.ppm > $tmpdir/tmp.png # Add sRGB and tEXt chunks to the PNG image (and compress it better). pngcrush -srgb 1 \ -text b Title 'unofficial Google logo sticker, 60% scale, any background' \ -text b Description ' Full-alpha image derived (without permission) algorithmically from two Google-supplied images pre-composited onto black and white backgrounds: http://www.google.com/logos/Logo_60blk.gif http://www.google.com/logos/Logo_60wht.gif The conversion script was written on 2004-Jan-21-Wed by Adam M. Costello http://www.nicemice.net/amc/ ' $tmpdir/tmp.png "$outfile" # Clean up. cleanup