#!/usr/bin/perl

use strict;

sub ps {
 my ($s) = @_;
 print "$s\n";
 system "$s";
}

sub rotate {
 my ($th, $w, $h, $x, $y) = @_;
 my ($s, $c) = (sin($th), cos($th));
 my ($xn, $yn) = ($c * $x + $s * $y, -$s * $x + $c * $y);
 if ($th > 0) { $yn += $w * $s }
 else         { $xn += $h * $s }
 [$xn, $yn]
}

my ($fn,$outdir,$sn) = @ARGV;

die "Usage: $0 pgmfile outputdir startnum" unless defined $sn;

open IN, $fn or die $!;

my @hd;

while (<IN>) {
 chomp;
 push @hd, split;
 last if (@hd >= 4);
}

my ($t,$w,$h,$max) = @hd;
die "Need raw PGM" unless $t eq "P5";
die "Expected maxval = 255" unless $max == 255;

undef $/;

my $b = <IN>;
my @b = unpack("C*", $b);
my $c = 0;
my @coord;

OUTER: # we actually do want $x to be the outer loop,
       # so that the two registration points are got
       # in the correct order, regardless of whether
       # the rotation of the image is slightly positive
       # or slightly negative.
for my $x (0..($w-1)) {
for my $y (0..($h-1)) {
my $v = $b[$x + $y * $w];
if (not ($v == 0 or $v == 255)) {
 $c++; 
 push @coord, [$x, $y];
 last OUTER if ($c == 2);
}
}
}

my $a = atan2($coord[1][1] - $coord[0][1], $coord[1][0] - $coord[0][0]);
my $adeg = $a * 180 / 3.14159265;

ps("pnmrotate -noantialias $adeg $fn > /tmp/rot$$.pgm");
my @nc; #newcoord
for (0,1) { $nc[$_] = rotate($a, $w, $h, @{$coord[$_]}) }
#print "$coord[0][0] $coord[0][1] $coord[1][0] $coord[1][1]\n";
#print "$nc[0][0] $nc[0][1] $nc[1][0] $nc[1][1]\n";
### now $nc[0][1] == $nc[1][1]
my $dw = $nc[1][0] - $nc[0][0];
my $dh = $dw * 6.5 / 9;
my $cw = $dw / 8;
my $ch = $dh / 4;

for my $cy (0..3) {
 for my $cx (0..7) {
my $left = int(0.1 * $cw + $nc[0][0] + $cw * $cx);
my $top = int(0.2 * $ch + $nc[0][1] + $ch * $cy);
my $width = int($cw * 0.8);
my $height = int($ch * 0.77);
my $n = $cx + $cy * 8;
my $hn = sprintf ("%04x", $sn + $n);
ps("pnmcut -left $left -top $top -width $width -height $height /tmp/rot$$.pgm > /tmp/img$$-$n.pgm");
ps("pnmtopng /tmp/img$$-$n.pgm > $outdir/uni$hn.png");  
 }
}
