#!/usr/bin/perl
#
# Starting with a bunch of FITS images, create
# a MPEG movie in order
# 
# MWR 4/14/2006

$debug = 0;

# pattern which will match the FITS file names
#$file_glob = "./QQ_00?.fit";
$file_glob = "./QQ_???.fit";
# give temp files names that start with this
$temp_prefix = "SSS_anim_";

# name of MPEG output file
$mpeg_outfile = "make_anim_mpg.mpg ";

# the typical sky level 
$sky_level = 0;

# the typical sky sigma
$sky_sigma = 20;

# this sets roughly the pixel level
#    of the top of the greyscale -- 
#    everything higher is pure black
$top_pix_val = 2500;

# invert the image, to yield black stars on white background?
$invert_flag = 0;

# frame rate possibilities for the movie: should be
#    of general form n:d where both are integers.  Some examples:
#             24000:1001 - NTSC 3:2 pulldown converted film
#                   24:1 - native film
#                   25:1 - PAL/SECAM
#             30000:1001 - NTSC video
#                   50:1 - PAL field rate
#             60000:1001 - NTSC field rate
$mpeg_framerate = "24:1";

# skip this many images between each image
#    we include in the movie
#    (note bash has limit of 109 args)
#    use skip_number=0 to include all images
$skip_number = 0;

# remove temporary files when done?
$cleanup = 1;



$image_index = 0;
$include_count = 0;
@files = glob($file_glob);
foreach $file (@files) {
  if ($debug > 0) {
    printf "next is file ..$file.. \n";
  }

  if (($image_index % ($skip_number + 1)) == 0) {
    if ($debug > 0) {
      printf " will include file $file ..\n";
    }
  }
  else {
    if ($debug > 0) {
      printf " will skip    file $file ..\n";
    }
    $image_index++;
    next;
  }
    
  # make a copy of the FITS image
  $temp_fits = sprintf "%s.fit", $temp_prefix;
  $cmd = "cp $file $temp_fits ";
  exec_cmd($cmd);
  
  # subtract the sky value
  $cmd = "sub $temp_fits const=$sky_level ";
  exec_cmd($cmd);

  # add a constant to shift most of the noise above zero 
  $cmd = "add $temp_fits const=$sky_sigma ";
  exec_cmd($cmd);
 
  # clip all negative values to zero, and all values
  #    greater than the top_pix_val to the top_pix_val
  $cmd = "clip $temp_fits min=0 vmin=0 ";
  $cmd .= " max=$top_pix_val vmax=$top_pix_val ";
  exec_cmd($cmd);

  if ($invert_flag == 1) {
    # multiply by negative one, to invert image values
    $cmd = "mul $temp_fits const=-1 ";
    exec_cmd($cmd);

    # now add the top_pix_val, so the range of values
    #    runs from zero to top_pix_val
    $cmd = "add $temp_fits const=$top_pix_val ";
    exec_cmd($cmd);
  }

  # rescale the image so that it runs from 0 to 255
  $cmd = "mul $temp_fits const=255 div=$top_pix_val ";
  exec_cmd($cmd);

  # run the conversion programs to turn FITS into PPM images ...
  $temp_pnm = sprintf "%s.pnm", $temp_prefix;
  $temp_ppm[$include_count] = sprintf "%s%04d.ppm", $temp_prefix, $include_count;
  $cmd = "fitstopnm -min 0 -max 255 $temp_fits > $temp_pnm ";
  exec_cmd($cmd);
  $cmd = "convert $temp_pnm $temp_ppm[$include_count] ";
  exec_cmd($cmd);

  $image_index++;
  $include_count++;
}

# all done with making lots of PPM images

#################
# Now, we merge the PPM images into an MPEG movie file
#   we use the "ppmtoy4m" and "mpeg2enc" tools to do the real work.
#   We use xargs in case there are a LOT of PPM files.
$cmd = sprintf "/bin/ls %s*.ppm ", $temp_prefix;
$cmd .= " | xargs -n1 cat ";
$cmd .= " | ppmtoy4m -F $mpeg_framerate ";
$cmd .= " | mpeg2enc -o $mpeg_outfile ";
exec_cmd($cmd);


# clean up temporary files
if ($cleanup == 1) {
  @remove_files = glob("$temp_prefix*");
  foreach $remove_file (@remove_files) {
    unlink($remove_file);
  }
}


exit 0;



##############################################################################
# PROCEDURE: exec_cmd
#
# DESCRIPTION: Execute the given shell command line.  If the $debug flag
#              is set, we print to stdout the command line, and
#              also print out the result string.
#
# RETURNS:
#              the result of the command
#
#
sub exec_cmd {

  my($cmd, $ret);

  $cmd = $_[0];

  if ($debug > 0) {
    printf "cmd is ..$cmd.. \n";
  }
  $ret = `$cmd`;
  if ($debug > 0) {
    printf "ret is ..$ret.. \n";
  }


  return($ret);
}


