/testsuite/weissman.pl
use Time::HiRes qw/gettimeofday tv_interval/;
use File::Find;
use strict;
=pod
So it turns out the Weissman Score is a real formula. Who knew?
r log T_bar
W = alpha * ----- * ---------
r_bar log T
Where r and T are the compression ratio of the target algorithm, and r_bar
and T_bar are the same for a reference compressor (in our case, PNG). Alpha
is a constant scaling factor.
http://spectrum.ieee.org/view-from-the-valley/computing/software/a-madefortv-compression-metric-moves-to-the-real-world
=cut
my ($bs_total, $png_total, $uncompressed_total, $bs_time, $png_time, $t0);
find({
wanted => sub {
next unless -f && /\.png$/;
$t0 = [gettimeofday];
my $bs_size = qx!$ENV{HOME}/go/bin/bitsmash $_ | wc -c!;
$bs_time += tv_interval($t0);
$uncompressed_total += qx!convert $_ rgb:- | wc -c!;
my $png_size = -s;
# So... we're being a bit shifty here by actually decoding a PNG and
# then encoding it again. We really should be working from an
# uncompressed source, but PNGs are handy (and bitsmash is decoding a PNG, too, so it's not unfair).
$t0 = [gettimeofday];
system qq!convert $_ png:- >/dev/null!;
$png_time += tv_interval($t0);
printf("%4.1f%% %-6d %-6d %s\n", ($bs_size / $png_size) * 100, $bs_size, $png_size, $_);
$bs_total += $bs_size;
$png_total += $png_size;
},
no_chdir => 1,
}, @ARGV);
printf("$uncompressed_total uncompressed bytes\n");
printf("$bs_total bitsmash bytes, %.2f seconds\n", $bs_time);
printf("$png_total PNG bytes, %.2f seconds\n", $png_time);
printf("%.1f%% of PNG\n", ($bs_total/$png_total) * 100);
my $r = $uncompressed_total / $bs_total;
my $r_bar = $uncompressed_total / $png_total;
my $alpha = 1.0;
printf("Weissman score: %.2f\n", $alpha * ($r / $r_bar) * (log($png_time) / log($bs_time)));