#!/usr/bin/perl # # stupid thing to try and compress the output of # gif2html (http://www.illuminated.co.uk/gif2html/) # by making more use of stylesheets for colouring # it seemed like a good idea at the time. # # howie@thingy.com http://wotsit.thingy.com/haj/ # 23rd January 2001 # Update Jan 26th: # Tweaked to name the classes a little more compactly # for the first 3224 colours - saves an additional 3226 bytes on # my test image (91825 original -> 78309 first version -> 75043 now) # use Text::Wrap qw(wrap $columns $huge); $columns = 132; $source = shift; # First pass through, we'll collect up the colour stats. # This might take a lot of memory! # I'm going to assume that the input will have one bgcolor per line, # because that's how it is right now, and I'm lazy. # lines contain: bgcolor="#ffffff" open(INPUT,$source) || die("Failed to open input file: $!"); while() { if (m/bgcolor="#(\w\w\w\w\w\w)"/) { $colourcounts{$1}++; $lines++; } } close(INPUT); # find the most popular colours @mostcolours = sort {$colourcounts{$b} <=> $colourcounts{$a}} keys %colourcounts; print "$lines lines checked.\n"; $totalsavings = 0; $compressed=0; $i=0; $style_head=""; foreach $colour (@mostcolours) { $frequency = $colourcounts{$colour}; $classname = get_class_name($i); $stylesheet_replacement = sprintf("TD.%s{background:#%s;} ",$classname,$colour); $body_replacement = 'class="'.$classname.'"'; $current_cost = length('bgcolor="#ffffff"') * $frequency; $new_cost = length($stylesheet_replacement) + length($body_replacement); $saving = $current_cost - $new_cost; if($saving > 0) { $totalsavings+=$saving; $replace{$colour}=$body_replacement; $style_head .= $stylesheet_replacement; $compressed++; } print "$i: $frequency: $colour: $saving\n"; $i++; } print "saved $totalsavings with stylesheet, in total!\n"; print "$i colours in use, $compressed colours were packed\n"; $output = ""; # now we implement our decisions open(INPUT,$source) || die("Failed to open input file: $!"); while() { chomp;chomp; if(m/-->/) { $output .= "\n".wrap("","",$style_head); } if (m/bgcolor="#(\w\w\w\w\w\w)"/) { $colour=$1; if($replace{$colour} ne "") { s/bgcolor="#$colour"/$replace{$colour}/; } } $output .= $_; } close(INPUT); open(OUTPUT,">".$source.".new") || die("Failed to create output file: $!"); print OUTPUT wrap("","",$output); close(OUTPUT); sub get_class_name { my $count = shift; my ($first,$second); my $firstpos = "abcdefghijklmnopqrstuvwxyzABCEDEFGHIJKLMNOPQRSTUVWXYZ"; my $subseqpos = "0123456789abcdefghijklmnopqrstuvwxyzABCEDEFGHIJKLMNOPQRSTUVWXYZ"; my $nfpos = length($firstpos); my $nspos = length($subseqpos); my $max2digit = $nfpos * $nspos; my $classname=""; if($count < $nfpos) { $classname = substr($firstpos,$i,1); } else { if($count <$max2digit) { $first = int($count/$nspos); $second = $count - ($first*$nspos); $classname = substr($firstpos,$first,1).substr($subseqpos,$second,1); } else { # fall back to previous scheme - if you get this far, the image is either very complex or HUGE - you won't miss it $classname = sprintf("s%x",$count); } } return $classname; }