#!/usr/bin/perl

# create PNG image from Tpod pcap file

# typical usage (note PNG is created on STDOUT) :
# ./tpodlog2png.pl tpod.cap 10 > tpod.png
# typical commands:

# Andrew Daviel Feb 2016

$width = 5000 ; # width of image to create

use Net::Pcap qw( :functions );
my $err = '';

$file = shift or die "Need pcap file\n" ;
$pcap = pcap_open_offline($file, \$err) or die "Can't read '$file': $err\n";

$scale = shift or $scale = 1 ;

use GD; # use Thomas Boutell's gd graphics library 

$im = new GD::Image($width,300);

# create a greyscape palette to map sonar return intensity to brightness (darker = more intense)
$white = $im->colorAllocate(255,255,255) ;
for ($i=0;$i<256;$i++) {
  $grey[255-$i] = $im->colorAllocate($i,$i,$i) ;
}


$filter_str = 'udp and port 5000 and src 192.168.1.1' ;
$s = pcap_compile($pcap, \$filter, $filter_str, 1, 0) ;

pcap_setfilter($pcap, $filter) ;

pcap_loop($pcap, -1, \&process_packet, "user data");

binmode STDOUT;
print $im->png;

sub process_packet {
  my ($user_data, $header, $packet) = @_;
  $time = $header->{'tv_sec'} + $header->{'tv_usec'} / 1000000 ;
  my @pkt = split('',$packet) ;

  for ($i=0;$i<42;$i++) { shift(@pkt) ; } # packet header
  for ($i=0;$i<@pkt;$i++) { $B[$i] = unpack("C",$pkt[$i]) ; }

  $len = $B[5]*256+$B[4] ; # record length (340 for depth data)
  $range = $B[18] ; # display range

  unless ($len == 340) { return ; }
  unless ($time0) { $time0 = $time ; }
  for ($y=40;$y<338;$y++) {
    $d = $B[$y] ;
    $x = int(($time - $time0) * $scale + 0.5) ;
    if ($x > $width ) { last ; }
    $im->setPixel($x,$y-40,$grey[$d]) ;
  }
}


