#!/usr/athena/bin/perl -w
## Make a gif "transparent"
##
## Jeffrey Friedl
## jfriedl@omrongw.wg.omron.co.jp
## 15 July 1994
## 2 Aug 1994 - added ability to select transparent color by RGB values.
## 940825.3 -- modified to work with possible future versions of the
##             GIF standard... just in case.
##
#$version = "940825.3";
##
## BLURB:
## Transforms a "normal" gif into a "transparent background" gif.
##
##>
##
## I wrote this because people ask for something like this all the time.
## I just learned the format of GIFs a week ago, so this will likely be
## lacking in many respects.
##
##
## Usage:
##      transgif [options] regular.gif > transparent.gif
##   or
##      cat regular.gif | transgif [options] transparent.gif
##
## The default is that whatever color happens to fall into the first colormap
## slot (often black) will be made transparent. This can be changed via the
## the options.
##
## The options are from:
##   -p              print the colormap (to STDERR).
##		     The new gif still goes to STDOUT.
##
##   -###            make colormap index-### transparent (default is -0)
##
##   -rgb ## ## ##   Take the three numbers as R G B values (in the range
##		     of 0..255 (or 0x00..0xff). The first colormap entry
##		     with those RGB values is made transparent.
##
##   -rgb name       Use the R G B values of the color 'name' if known
##		     by this program (data from X11's rgb.txt)
##
## COLORNUM is the index of the color entry to make transparent, and 
## defaults to zero. For those that like the looks of it, you can put
## a leading '-'.
##
##<

sub usage {
   die "@_\nUsage: $0 [-p] [-## | -rgb name | -rgb ## ## ##] [file]\n";
}

$trans_index = 0;
$print_color_map = 0;
$select_via_rgb = 0;

while (@ARGV && $ARGV[0] =~ m/^-/) {
    $arg = shift;
    if ($arg eq '-p') { 	     ## print color map
	$print_color_map = 1;

    } elsif ($arg =~ m/^-(\d+)$/) {  ## set color map index number
	$trans_index = $1;

    } elsif ($arg eq '-rgb') {	     ## set what color to make transparent

	## if next three args look numerical (## or 0x##), use as R B G.
	if (@ARGV >= 3 &&
	    $ARGV[0] =~ m/^(0x[\da-f]+|\d+)$/i &&
	    $ARGV[1] =~ m/^(0x[\da-f]+|\d+)$/i &&
	    $ARGV[2] =~ m/^(0x[\da-f]+|\d+)$/i)
	{
	    ($R, $G, $B) = splice(@ARGV, 0, 3);
	    $select_via_rgb = 1;
	    $R = eval($R); ## eval these to process any hex or octal values.
	    $G = eval($G); ## eval these to process any hex or octal values.
	    $B = eval($B); ## eval these to process any hex or octal values.

	## if next arg looks like a color name, use those R G B values.
	} elsif (@ARGV && (@RGB = &name2rgb($ARGV[0]), @RGB == 3)) {
	    shift; ## eat name;
	    ($R, $G, $B) = @RGB;
	    $select_via_rgb = 1;

	} else {
	   warn(qq/(don't understand "$ARGV[0]" as a color name)\n/) if @ARGV;
	   die qq/$0: expected color name or a numerical triplet for $arg\n/;
	}
    } else {
	&usage(qq/unknown arg "$arg".\n/);
    }
}

&usage('too many args.') if @ARGV > 1;

if (@ARGV == 0) {
    &giftrans(*STDIN, *STDOUT, $trans_index);
} else {
    open(INPUT,  $file =shift) || die "$0: couldn't open [$file] for input\n";
    &giftrans(*INPUT, *STDOUT, $trans_index);
    close(INPUT);
}
exit(0);



##
## Given indirect references to two filehandles, pass the file from
## one to the other, changing nothing unless it's a GIF that we know
## how to deal with, and if so do so.
##
## This is written rather verbosely for the sake of clarity... speed not
## much of an issue for something like this, and the difference is minimal
## anyway.
##
sub giftrans
{
    local(*IN, *OUT, $trans_index) = @_;
    $trans_index = 0 if !defined $trans_index;
    local($header, $color_table, $nextblock, $buffer) = ('') x 4;

    ## The header looks like:
    ##   byte 0 - 5:  "GIF89a" or "GIF87a"
    ##   byte 6, 7:   width  (low order first)
    ##   byte 8, 9:   height (low order first)
    ##   byte 10:     various flags
    ##   byte 11:     background color index
    ##   byte 12:     aspect ratio
    sysread(IN, $header, 13) || die "sysread header: $!";
    substr($header, 0, 6) = 'GIF89a' if substr($header,0,6) eq 'GIF87a';
    print OUT $header;

    if (substr($header, 0, 3) ne 'GIF') {
	print STDERR "don't know input filetype, passing unchanged\n";
    } else {
	##
	## Look at flags (8 bits): hi[MCCCSPPP]low
	##   M   = global colormap present?
	##   CCC = bits/color/colormapentry - 1
	##   S   = color map sorted by importance?
	##   PPP = bits/pixel - 1
	## therefore
	##   Bits/pixel = PPP+1
	##   Number of possible colors (entries in colormap): 2 ** (PPP+1)
	##                                                  : 1 << (PPP+1)
	##   Size (bytes) of colormap: 3 * Number of possible colors
	##                           : 3 * (1 << (PPP+1))
	##
	local($flags) = ord(substr($header, 10, 1));
	local($has_global_colormap) = $flags & 0x80;

	## Copy over the colormap if need be.
	if (!$has_global_colormap)
	{
	   die "$0: picture has no colormap, so -rgb arg invalid\n"
		if $select_via_rgb;
	   die "$0: no colormap, so any index except 0 or 1 makes no sense\n"
		if $trans_index > 1;
	} else {
	    local($bits_per_pixel) = 1 + ($flags & 0x07);
	    local($colormap_entries) = 1 << $bits_per_pixel;
	    local($color_tbl_size) = 3 * $colormap_entries;

	    sysread(IN, $color_table, $color_tbl_size) || die "sysread color";
	    print OUT $color_table;

	    if ($print_color_map || $select_via_rgb)
	    {
		## For each byte of each colormap's RGB triplit, we'll have
		## to mask off bits that aren't used when looking at the
		## color values.
		local($bits_color_byte) = 1 + (($flags >> 4) & 0x07);
		local($rgb_byte_mask) = (1 << $bits_color_byte) - 1;
		local($r,$g,$b);

		local($best_delta) = 1000; ## any big number ok
		local(@delta, @r, @b, @g);

		for ($i = 0; $i < $colormap_entries; $i++)
		{
		   ($r, $g, $b) = unpack("CCC", substr($color_table, $i*3, 3));
		   $r &= $rgb_byte_mask;
		   $g &= $rgb_byte_mask;
		   $b &= $rgb_byte_mask;

		   if ($select_via_rgb) {
			if ($r == $R && $g == $G && $b == $B) {
			    $select_via_rgb = 0;
			    $trans_index = $i;
			    print(STDERR "Found exact match (index #$i).\n");
			} else {
			    $delta = ($r < $R ? $R - $r : $r - $R) +
				     ($g < $G ? $G - $g : $g - $G) +
				     ($b < $B ? $B - $b : $b - $B);
			    if ($delta < $best_delta) {
				@delta = ($i);
				@r = $r; @g = $g; @b = $b;
				$best_delta = $delta;
			    } elsif ($delta == $best_delta) {
				push(@delta, $i);
				push(@r, $r); push(@g, $g); push(@b, $b);
			    }
			}
		   }

		   printf(STDERR "%03d: %3d %3d %3d (x%02x x%02x x%02x)\n", $i,
			$r, $g, $b, $r, $g, $b) if $print_color_map;
		}

		if ($select_via_rgb) {
		    ## Mmm, didn't find it. Use one of the close ones.
		    $trans_index = shift(delta);
		    $r = shift(@r);
		    $g = shift(@g);
		    $b = shift(@b);

		    printf(STDERR "requested color not found, using index ".
				  "#%d: %3d %3d %3d (x%02x x%02x x%02x)\n",
				  $trans_index,
				   $r, $g, $b, $r, $g, $b);
		    if (@delta)
		    {
			$count = @delta;
			print(STDERR
			    "note: %d other entrie%s seem equally close:\n",
				$count, $count == 1 ? "" : "s");
			while (@delta) {
			    $index = shift(delta);
			    $r = shift(@r);
			    $g = shift(@g);
			    $b = shift(@b);
		   	    printf(STDERR "  index %03d: %3d %3d %3d ".
					  "(x%02x x%02x x%02x)\n",
					  $index, $r, $g, $b, $r, $g, $b);
			}
		    }
		}
	    }
	}

	##
	## The next 8 bytes will either be an already-there graphic-extension
	## block, or something else that we'll not care about. In the latter
	## case, we'll add a graphic-extension block saying "color such-and-
	## such is transparent". If there's already one there, we'll just
	## ensure that it says that.
	##
	sysread(IN, $nextblock, 8) || die "sysread nextblock";
	local($extension, $label) = unpack('CC', $nextblock);
	## If extension is 0x21 and label is 0xf9, that's the magic tha means
	## there's already a graphic extension there.
	if ($extension == 0x21 && $label == 0xf9) {
	    substr($nextblock, 3, 1) = pack('C', 1|substr($nextblock, 3, 1));
	    substr($nextblock, 6, 1) = pack('C', $trans_index);
	} else {
	    print OUT pack('CCC CCCC C',
		0x21,  ## magic: "Extension Introducer"
		0xf9,  ## magic: "Graphic Control Label"
		   4,  ## bytes in block (between here and terminator)
		0x01,  ## indicates that 'transparet index' is given
		0, 0,  ## delay time.
                $trans_index, ## index number of colormap entry
		0x00); ## terminator.
	}
	print OUT $nextblock;
    }

    ## Now just pass the rest of the file over unchanged.

    print OUT $buffer while sysread(IN, $buffer, 4096);
    close(IN);
    close(OUT);
}

##
## Change a name to a triplet of RGB values.
## name and RGB data taken from the X11 lib/rgb.txt, with the
## name regexe-compressed by me.
##
sub name2rgb
{
    local($_) = @_;  ## name;
    study;
    %rgb = (
	'  0,  0,  0', 'black|gr[ae]y0',
	'  0,  0,128', 'navy([ \-]?blue)?',
	'  0,  0,139', 'blue4',
	'  0,  0,205', 'blue3|medium[ \-]?blue',
	'  0,  0,238', 'blue2',
	'  0,  0,255', 'blue1?',
	'  0,100,  0', 'dark[ \-]?green',
	'  0,104,139', 'deepskyblue4',
	'  0,134,139', 'turquoise4',
	'  0,139,  0', 'green4',
	'  0,139, 69', 'springgreen4',
	'  0,139,139', 'cyan4',
	'  0,154,205', 'deepskyblue3',
	'  0,178,238', 'deepskyblue2',
	'  0,191,255', 'deep( sky blue|-sky-blue|skyblue1?)',
	'  0,197,205', 'turquoise3',
	'  0,205,  0', 'green3',
	'  0,205,102', 'springgreen3',
	'  0,205,205', 'cyan3',
	'  0,206,209', 'dark[ \-]?turquoise',
	'  0,229,238', 'turquoise2',
	'  0,238,  0', 'green2',
	'  0,238,118', 'springgreen2',
	'  0,238,238', 'cyan2',
	'  0,245,255', 'turquoise1',
	'  0,250,154', 'medium[ \-]?spring[ \-]?green',
	'  0,255,  0', 'green1?',
	'  0,255,127', 'spring[ \-]?green1?',
	'  0,255,255', 'cyan1?',
	'  3,  3,  3', 'gr[ae]y1',
	'  5,  5,  5', 'gr[ae]y2',
	'  8,  8,  8', 'gr[ae]y3',
	' 10, 10, 10', 'gr[ae]y4',
	' 13, 13, 13', 'gr[ae]y5',
	' 15, 15, 15', 'gr[ae]y6',
	' 16, 78,139', 'dodgerblue4',
	' 18, 18, 18', 'gr[ae]y7',
	' 20, 20, 20', 'gr[ae]y8',
	' 23, 23, 23', 'gr[ae]y9',
	' 24,116,205', 'dodgerblue3',
	' 25, 25,112', 'midnight[ \-]?blue',
	' 26, 26, 26', 'gr[ae]y10',
	' 28, 28, 28', 'gr[ae]y11',
	' 28,134,238', 'dodgerblue2',
	' 30,144,255', 'dodger[ \-]?blue1?',
	' 31, 31, 31', 'gr[ae]y12',
	' 32,178,170', 'light[ \-]?sea[ \-]?green',
	' 33, 33, 33', 'gr[ae]y13',
	' 34,139, 34', 'forest[ \-]?green',
	' 36, 36, 36', 'gr[ae]y14',
	' 38, 38, 38', 'gr[ae]y15',
	' 39, 64,139', 'royalblue4',
	' 41, 41, 41', 'gr[ae]y16',
	' 43, 43, 43', 'gr[ae]y17',
	' 46, 46, 46', 'gr[ae]y18',
	' 46,139, 87', 'sea[ \-]?green4?',
	' 47, 79, 79', 'dark( slate gr[ae]|-slate-gr[ae]|slategr[ae])y',
	' 48, 48, 48', 'gr[ae]y19',
	' 50,205, 50', 'lime[ \-]?green',
	' 51, 51, 51', 'gr[ae]y20',
	' 54, 54, 54', 'gr[ae]y21',
	' 54,100,139', 'steelblue4',
	' 56, 56, 56', 'gr[ae]y22',
	' 58, 95,205', 'royalblue3',
	' 59, 59, 59', 'gr[ae]y23',
	' 60,179,113', 'medium[ \-]?sea[ \-]?green',
	' 61, 61, 61', 'gr[ae]y24',
	' 64, 64, 64', 'gr[ae]y25',
	' 64,224,208', 'turquoise',
	' 65,105,225', 'royal[ \-]?blue',
	' 66, 66, 66', 'gr[ae]y26',
	' 67,110,238', 'royalblue2',
	' 67,205,128', 'seagreen3',
	' 69, 69, 69', 'gr[ae]y27',
	' 69,139,  0', 'chartreuse4',
	' 69,139,116', 'aquamarine4',
	' 70,130,180', 'steel[ \-]?blue',
	' 71, 60,139', 'slateblue4',
	' 71, 71, 71', 'gr[ae]y28',
	' 72, 61,139', 'dark[ \-]?slate[ \-]?blue',
	' 72,118,255', 'royalblue1',
	' 72,209,204', 'medium[ \-]?turquoise',
	' 74, 74, 74', 'gr[ae]y29',
	' 74,112,139', 'skyblue4',
	' 77, 77, 77', 'gr[ae]y30',
	' 78,238,148', 'seagreen2',
	' 79, 79, 79', 'gr[ae]y31',
	' 79,148,205', 'steelblue3',
	' 82, 82, 82', 'gr[ae]y32',
	' 82,139,139', 'darkslategray4',
	' 83,134,139', 'cadetblue4',
	' 84, 84, 84', 'gr[ae]y33',
	' 84,139, 84', 'palegreen4',
	' 84,255,159', 'seagreen1',
	' 85, 26,139', 'purple4',
	' 85,107, 47', 'dark[ \-]?olive[ \-]?green',
	' 87, 87, 87', 'gr[ae]y34',
	' 89, 89, 89', 'gr[ae]y35',
	' 92, 92, 92', 'gr[ae]y36',
	' 92,172,238', 'steelblue2',
	' 93, 71,139', 'mediumpurple4',
	' 94, 94, 94', 'gr[ae]y37',
	' 95,158,160', 'cadet[ \-]?blue',
	' 96,123,139', 'lightskyblue4',
	' 97, 97, 97', 'gr[ae]y38',
	' 99, 99, 99', 'gr[ae]y39',
	' 99,184,255', 'steelblue1',
	'100,149,237', 'cornflower[ \-]?blue',
	'102,102,102', 'gr[ae]y40',
	'102,139,139', 'paleturquoise4',
	'102,205,  0', 'chartreuse3',
	'102,205,170', 'aquamarine3|medium[ \-]?aquamarine',
	'104, 34,139', 'darkorchid4',
	'104,131,139', 'lightblue4',
	'105, 89,205', 'slateblue3',
	'105,105,105', 'dim( gr[ae]|-gr[ae]|gr[ae])y|gr[ae]y41',
	'105,139, 34', 'olivedrab4',
	'105,139,105', 'darkseagreen4',
	'106, 90,205', 'slate[ \-]?blue',
	'107,107,107', 'gr[ae]y42',
	'107,142, 35', 'olive[ \-]?drab',
	'108,123,139', 'slategray4',
	'108,166,205', 'skyblue3',
	'110,110,110', 'gr[ae]y43',
	'110,123,139', 'lightsteelblue4',
	'110,139, 61', 'darkolivegreen4',
	'112,112,112', 'gr[ae]y44',
	'112,128,144', 'slate( gr[ae]|-gr[ae]|gr[ae])y',
	'115,115,115', 'gr[ae]y45',
	'117,117,117', 'gr[ae]y46',
	'118,238,  0', 'chartreuse2',
	'118,238,198', 'aquamarine2',
	'119,136,153', 'light( slate gr[ae]|-slate-gr[ae]|slategr[ae])y',
	'120,120,120', 'gr[ae]y47',
	'121,205,205', 'darkslategray3',
	'122, 55,139', 'mediumorchid4',
	'122,103,238', 'slateblue2',
	'122,122,122', 'gr[ae]y48',
	'122,139,139', 'lightcyan4',
	'122,197,205', 'cadetblue3',
	'123,104,238', 'medium[ \-]?slate[ \-]?blue',
	'124,205,124', 'palegreen3',
	'124,252,  0', 'lawn[ \-]?green',
	'125, 38,205', 'purple3',
	'125,125,125', 'gr[ae]y49',
	'126,192,238', 'skyblue2',
	'127,127,127', 'gr[ae]y50',
	'127,255,  0', 'chartreuse1?',
	'127,255,212', 'aquamarine1?',
	'130,130,130', 'gr[ae]y51',
	'131,111,255', 'slateblue1',
	'131,139,131', 'honeydew4',
	'131,139,139', 'azure4',
	'132,112,255', 'light[ \-]?slate[ \-]?blue',
	'133,133,133', 'gr[ae]y52',
	'135,135,135', 'gr[ae]y53',
	'135,206,235', 'sky[ \-]?blue',
	'135,206,250', 'light[ \-]?sky[ \-]?blue',
	'135,206,255', 'skyblue1',
	'137,104,205', 'mediumpurple3',
	'138, 43,226', 'blue[ \-]?violet',
	'138,138,138', 'gr[ae]y54',
	'139,  0,  0', 'red4',
	'139,  0,139', 'magenta4',
	'139, 10, 80', 'deeppink4',
	'139, 26, 26', 'firebrick4',
	'139, 28, 98', 'maroon4',
	'139, 34, 82', 'violetred4',
	'139, 35, 35', 'brown4',
	'139, 37,  0', 'orangered4',
	'139, 54, 38', 'tomato4',
	'139, 58, 58', 'indianred4',
	'139, 58, 98', 'hotpink4',
	'139, 62, 47', 'coral4',
	'139, 69,  0', 'darkorange4',
	'139, 69, 19', 'chocolate4|saddle[ \-]?brown',
	'139, 71, 38', 'sienna4',
	'139, 71, 93', 'palevioletred4',
	'139, 71,137', 'orchid4',
	'139, 76, 57', 'salmon4',
	'139, 87, 66', 'lightsalmon4',
	'139, 90,  0', 'orange4',
	'139, 90, 43', 'tan4',
	'139, 95,101', 'lightpink4',
	'139, 99,108', 'pink4',
	'139,101,  8', 'darkgoldenrod4',
	'139,102,139', 'plum4',
	'139,105, 20', 'goldenrod4',
	'139,105,105', 'rosybrown4',
	'139,115, 85', 'burlywood4',
	'139,117,  0', 'gold4',
	'139,119,101', 'peachpuff4',
	'139,121, 94', 'navajowhite4',
	'139,123,139', 'thistle4',
	'139,125,107', 'bisque4',
	'139,125,123', 'mistyrose4',
	'139,126,102', 'wheat4',
	'139,129, 76', 'lightgoldenrod4',
	'139,131,120', 'antiquewhite4',
	'139,131,134', 'lavenderblush4',
	'139,134, 78', 'khaki4',
	'139,134,130', 'seashell4',
	'139,136,120', 'cornsilk4',
	'139,137,112', 'lemonchiffon4',
	'139,137,137', 'snow4',
	'139,139,  0', 'yellow4',
	'139,139,122', 'lightyellow4',
	'139,139,131', 'ivory4',
	'140,140,140', 'gr[ae]y55',
	'141,182,205', 'lightskyblue3',
	'141,238,238', 'darkslategray2',
	'142,229,238', 'cadetblue2',
	'143,143,143', 'gr[ae]y56',
	'143,188,143', 'dark[ \-]?sea[ \-]?green',
	'144,238,144', 'palegreen2',
	'145, 44,238', 'purple2',
	'145,145,145', 'gr[ae]y57',
	'147,112,219', 'medium[ \-]?purple',
	'148,  0,211', 'dark[ \-]?violet',
	'148,148,148', 'gr[ae]y58',
	'150,150,150', 'gr[ae]y59',
	'150,205,205', 'paleturquoise3',
	'151,255,255', 'darkslategray1',
	'152,245,255', 'cadetblue1',
	'152,251,152', 'pale[ \-]?green',
	'153, 50,204', 'dark[ \-]?orchid',
	'153,153,153', 'gr[ae]y60',
	'154, 50,205', 'darkorchid3',
	'154,192,205', 'lightblue3',
	'154,205, 50', 'olivedrab3|yellow[ \-]?green',
	'154,255,154', 'palegreen1',
	'155, 48,255', 'purple1',
	'155,205,155', 'darkseagreen3',
	'156,156,156', 'gr[ae]y61',
	'158,158,158', 'gr[ae]y62',
	'159,121,238', 'mediumpurple2',
	'159,182,205', 'slategray3',
	'160, 32,240', 'purple',
	'160, 82, 45', 'sienna',
	'161,161,161', 'gr[ae]y63',
	'162,181,205', 'lightsteelblue3',
	'162,205, 90', 'darkolivegreen3',
	'163,163,163', 'gr[ae]y64',
	'164,211,238', 'lightskyblue2',
	'165, 42, 42', 'brown',
	'166,166,166', 'gr[ae]y65',
	'168,168,168', 'gr[ae]y66',
	'171,130,255', 'mediumpurple1',
	'171,171,171', 'gr[ae]y67',
	'173,173,173', 'gr[ae]y68',
	'173,216,230', 'light[ \-]?blue',
	'173,255, 47', 'green[ \-]?yellow',
	'174,238,238', 'paleturquoise2',
	'175,238,238', 'pale[ \-]?turquoise',
	'176, 48, 96', 'maroon',
	'176,176,176', 'gr[ae]y69',
	'176,196,222', 'light[ \-]?steel[ \-]?blue',
	'176,224,230', 'powder[ \-]?blue',
	'176,226,255', 'lightskyblue1',
	'178, 34, 34', 'firebrick',
	'178, 58,238', 'darkorchid2',
	'178,223,238', 'lightblue2',
	'179,179,179', 'gr[ae]y70',
	'179,238, 58', 'olivedrab2',
	'180, 82,205', 'mediumorchid3',
	'180,205,205', 'lightcyan3',
	'180,238,180', 'darkseagreen2',
	'181,181,181', 'gr[ae]y71',
	'184,134, 11', 'dark[ \-]?goldenrod',
	'184,184,184', 'gr[ae]y72',
	'185,211,238', 'slategray2',
	'186, 85,211', 'medium[ \-]?orchid',
	'186,186,186', 'gr[ae]y73',
	'187,255,255', 'paleturquoise1',
	'188,143,143', 'rosy[ \-]?brown',
	'188,210,238', 'lightsteelblue2',
	'188,238,104', 'darkolivegreen2',
	'189,183,107', 'dark[ \-]?khaki',
	'189,189,189', 'gr[ae]y74',
	'190,190,190', 'gr[ae]y',
	'191, 62,255', 'darkorchid1',
	'191,191,191', 'gr[ae]y75',
	'191,239,255', 'lightblue1',
	'192,255, 62', 'olivedrab1',
	'193,205,193', 'honeydew3',
	'193,205,205', 'azure3',
	'193,255,193', 'darkseagreen1',
	'194,194,194', 'gr[ae]y76',
	'196,196,196', 'gr[ae]y77',
	'198,226,255', 'slategray1',
	'199, 21,133', 'medium[ \-]?violet[ \-]?red',
	'199,199,199', 'gr[ae]y78',
	'201,201,201', 'gr[ae]y79',
	'202,225,255', 'lightsteelblue1',
	'202,255,112', 'darkolivegreen1',
	'204,204,204', 'gr[ae]y80',
	'205,  0,  0', 'red3',
	'205,  0,205', 'magenta3',
	'205, 16,118', 'deeppink3',
	'205, 38, 38', 'firebrick3',
	'205, 41,144', 'maroon3',
	'205, 50,120', 'violetred3',
	'205, 51, 51', 'brown3',
	'205, 55,  0', 'orangered3',
	'205, 79, 57', 'tomato3',
	'205, 85, 85', 'indianred3',
	'205, 91, 69', 'coral3',
	'205, 92, 92', 'indian[ \-]?red',
	'205, 96,144', 'hotpink3',
	'205,102,  0', 'darkorange3',
	'205,102, 29', 'chocolate3',
	'205,104, 57', 'sienna3',
	'205,104,137', 'palevioletred3',
	'205,105,201', 'orchid3',
	'205,112, 84', 'salmon3',
	'205,129, 98', 'lightsalmon3',
	'205,133,  0', 'orange3',
	'205,133, 63', 'peru|tan3',
	'205,140,149', 'lightpink3',
	'205,145,158', 'pink3',
	'205,149, 12', 'darkgoldenrod3',
	'205,150,205', 'plum3',
	'205,155, 29', 'goldenrod3',
	'205,155,155', 'rosybrown3',
	'205,170,125', 'burlywood3',
	'205,173,  0', 'gold3',
	'205,175,149', 'peachpuff3',
	'205,179,139', 'navajowhite3',
	'205,181,205', 'thistle3',
	'205,183,158', 'bisque3',
	'205,183,181', 'mistyrose3',
	'205,186,150', 'wheat3',
	'205,190,112', 'lightgoldenrod3',
	'205,192,176', 'antiquewhite3',
	'205,193,197', 'lavenderblush3',
	'205,197,191', 'seashell3',
	'205,198,115', 'khaki3',
	'205,200,177', 'cornsilk3',
	'205,201,165', 'lemonchiffon3',
	'205,201,201', 'snow3',
	'205,205,  0', 'yellow3',
	'205,205,180', 'lightyellow3',
	'205,205,193', 'ivory3',
	'207,207,207', 'gr[ae]y81',
	'208, 32,144', 'violet[ \-]?red',
	'209, 95,238', 'mediumorchid2',
	'209,209,209', 'gr[ae]y82',
	'209,238,238', 'lightcyan2',
	'210,105, 30', 'chocolate',
	'210,180,140', 'tan',
	'211,211,211', 'light( gr[ae]|-gr[ae]|gr[ae])y',
	'212,212,212', 'gr[ae]y83',
	'214,214,214', 'gr[ae]y84',
	'216,191,216', 'thistle',
	'217,217,217', 'gr[ae]y85',
	'218,112,214', 'orchid',
	'218,165, 32', 'goldenrod',
	'219,112,147', 'pale[ \-]?violet[ \-]?red',
	'219,219,219', 'gr[ae]y86',
	'220,220,220', 'gainsboro',
	'221,160,221', 'plum',
	'222,184,135', 'burlywood',
	'222,222,222', 'gr[ae]y87',
	'224,102,255', 'mediumorchid1',
	'224,224,224', 'gr[ae]y88',
	'224,238,224', 'honeydew2',
	'224,238,238', 'azure2',
	'224,255,255', 'light[ \-]?cyan1?',
	'227,227,227', 'gr[ae]y89',
	'229,229,229', 'gr[ae]y90',
	'230,230,250', 'lavender',
	'232,232,232', 'gr[ae]y91',
	'233,150,122', 'dark[ \-]?salmon',
	'235,235,235', 'gr[ae]y92',
	'237,237,237', 'gr[ae]y93',
	'238,  0,  0', 'red2',
	'238,  0,238', 'magenta2',
	'238, 18,137', 'deeppink2',
	'238, 44, 44', 'firebrick2',
	'238, 48,167', 'maroon2',
	'238, 58,140', 'violetred2',
	'238, 59, 59', 'brown2',
	'238, 64,  0', 'orangered2',
	'238, 92, 66', 'tomato2',
	'238, 99, 99', 'indianred2',
	'238,106, 80', 'coral2',
	'238,106,167', 'hotpink2',
	'238,118,  0', 'darkorange2',
	'238,118, 33', 'chocolate2',
	'238,121, 66', 'sienna2',
	'238,121,159', 'palevioletred2',
	'238,122,233', 'orchid2',
	'238,130, 98', 'salmon2',
	'238,130,238', 'violet',
	'238,149,114', 'lightsalmon2',
	'238,154,  0', 'orange2',
	'238,154, 73', 'tan2',
	'238,162,173', 'lightpink2',
	'238,169,184', 'pink2',
	'238,173, 14', 'darkgoldenrod2',
	'238,174,238', 'plum2',
	'238,180, 34', 'goldenrod2',
	'238,180,180', 'rosybrown2',
	'238,197,145', 'burlywood2',
	'238,201,  0', 'gold2',
	'238,203,173', 'peachpuff2',
	'238,207,161', 'navajowhite2',
	'238,210,238', 'thistle2',
	'238,213,183', 'bisque2',
	'238,213,210', 'mistyrose2',
	'238,216,174', 'wheat2',
	'238,220,130', 'lightgoldenrod2',
	'238,221,130', 'light[ \-]?goldenrod',
	'238,223,204', 'antiquewhite2',
	'238,224,229', 'lavenderblush2',
	'238,229,222', 'seashell2',
	'238,230,133', 'khaki2',
	'238,232,170', 'pale[ \-]?goldenrod',
	'238,232,205', 'cornsilk2',
	'238,233,191', 'lemonchiffon2',
	'238,233,233', 'snow2',
	'238,238,  0', 'yellow2',
	'238,238,209', 'lightyellow2',
	'238,238,224', 'ivory2',
	'240,128,128', 'light[ \-]?coral',
	'240,230,140', 'khaki',
	'240,240,240', 'gr[ae]y94',
	'240,248,255', 'alice[ \-]?blue',
	'240,255,240', 'honeydew1?',
	'240,255,255', 'azure1?',
	'242,242,242', 'gr[ae]y95',
	'244,164, 96', 'sandy[ \-]?brown',
	'245,222,179', 'wheat',
	'245,245,220', 'beige',
	'245,245,245', 'gr[ae]y96|white[ \-]?smoke',
	'245,255,250', 'mint[ \-]?cream',
	'247,247,247', 'gr[ae]y97',
	'248,248,255', 'ghost[ \-]?white',
	'250,128,114', 'salmon',
	'250,235,215', 'antique[ \-]?white',
	'250,240,230', 'linen',
	'250,250,210', 'light[ \-]?goldenrod[ \-]?yellow',
	'250,250,250', 'gr[ae]y98',
	'252,252,252', 'gr[ae]y99',
	'253,245,230', 'old[ \-]?lace',
	'255,  0,  0', 'red1?',
	'255,  0,255', 'magenta1?',
	'255, 20,147', 'deep[ \-]?pink1?',
	'255, 48, 48', 'firebrick1',
	'255, 52,179', 'maroon1',
	'255, 62,150', 'violetred1',
	'255, 64, 64', 'brown1',
	'255, 69,  0', 'orange[ \-]?red1?',
	'255, 99, 71', 'tomato1?',
	'255,105,180', 'hot[ \-]?pink',
	'255,106,106', 'indianred1',
	'255,110,180', 'hotpink1',
	'255,114, 86', 'coral1',
	'255,127,  0', 'darkorange1',
	'255,127, 36', 'chocolate1',
	'255,127, 80', 'coral',
	'255,130, 71', 'sienna1',
	'255,130,171', 'palevioletred1',
	'255,131,250', 'orchid1',
	'255,140,  0', 'dark[ \-]?orange',
	'255,140,105', 'salmon1',
	'255,160,122', 'light[ \-]?salmon1?',
	'255,165,  0', 'orange1?',
	'255,165, 79', 'tan1',
	'255,174,185', 'lightpink1',
	'255,181,197', 'pink1',
	'255,182,193', 'light[ \-]?pink',
	'255,185, 15', 'darkgoldenrod1',
	'255,187,255', 'plum1',
	'255,192,203', 'pink',
	'255,193, 37', 'goldenrod1',
	'255,193,193', 'rosybrown1',
	'255,211,155', 'burlywood1',
	'255,215,  0', 'gold1?',
	'255,218,185', 'peach[ \-]?puff1?',
	'255,222,173', 'navajo[ \-]?white1?',
	'255,225,255', 'thistle1',
	'255,228,181', 'moccasin',
	'255,228,196', 'bisque1?',
	'255,228,225', 'misty[ \-]?rose1?',
	'255,231,186', 'wheat1',
	'255,235,205', 'blanched[ \-]?almond',
	'255,236,139', 'lightgoldenrod1',
	'255,239,213', 'papaya[ \-]?whip',
	'255,239,219', 'antiquewhite1',
	'255,240,245', 'lavender[ \-]?blush1?',
	'255,245,238', 'seashell1?',
	'255,246,143', 'khaki1',
	'255,248,220', 'cornsilk1?',
	'255,250,205', 'lemon[ \-]?chiffon1?',
	'255,250,240', 'floral[ \-]?white',
	'255,250,250', 'snow1?',
	'255,255,  0', 'yellow1?',
	'255,255,224', 'light[ \-]?yellow1?',
	'255,255,240', 'ivory1?',
	'255,255,255', 'gr[ae]y100|white',
    );
    while (($val, $regex) = each %rgb) {
	return split(',', $val) if m/^$regex$/i;
    }

}
__END__
