Image-Animated-JPEG
view release on metacpan or search on metacpan
bin/makeajpeg view on Meta::CPAN
#!/usr/bin/perl
# adds an APP0 AJPG ("Animated JPEG") segment to a JPEG
use strict;
use warnings;
use lib 'lib';
# use Data::Dumper;
# use Data::HexDump;
use Encode;
use File::Basename;
use Getopt::Long;
use Image::Animated::JPEG;
use Image::MetaData::JPEG;
use Pod::Usage;
Getopt::Long::Configure('no_ignore_case');
GetOptions(
'output-file|o:s' => \my $output_file,
'delay|d:s' => \my $delay,
'repeat|r:s' => \my $repeat,
'keep-mtime' => \my $keep_mtime,
'metadata-filename' => \my $metadata_filename,
'split' => \my $split,
'debug|d' => \my $debug,
'force|f' => \my $force,
'help|h' => \my $help,
) or pod2usage(2);
pod2usage(1) unless !$help;
## split mode
if($split){
require Cwd;
require Path::Tiny;
Path::Tiny->import;
die " Can't process more than one file in split mode!\n" if @ARGV > 1;
die " Could not find file $ARGV!\n" unless -f $ARGV[0];
print " Splitting file $ARGV[0]\n" if $debug;
open(my $io_file, '<', $ARGV[0]) or die $!;
binmode($io_file);
print " Building file index... \n" if $debug;
my $index = Image::Animated::JPEG::index($io_file); # , { debug => $debug }
my $basename = path($ARGV[0])->basename(qr/\.\w{2,5}$/);
# my $path = path($ARGV[0])->parent; # relative to input-file
my $path = Cwd::cwd(); # relative to where we're called / cwd()
my @stat = stat($ARGV[0]) if $keep_mtime;
my $cnt;
for my $frame (@$index){
$cnt++;
my $framename = $basename . '_frame' . sprintf("%04d", $cnt) . '.jpg';
my $framepath = path($path,$framename)->canonpath;
die " Frame output won't overwrite existing file $framepath unless --force is set!\n" if -f $framepath && !$force;
# let's assume these frames aren't too big and we can use a temp scalar
seek($io_file, $frame->{offset},0);
my $buffer;
sysread($io_file,$buffer,$frame->{length});
print " -Extracting frame #". $cnt ." data: offset:$frame->{offset}, length:$frame->{length}, buffer: ". length($buffer) ."\n" if $debug;
# from playajpeg
# my $ref = Image::Animated::JPEG::process(\$buffer);
# my $per_frame;
# if($ref && $ref->{AJPEG}){
# $per_frame = Image::Animated::JPEG::decode_ajpeg_data( substr($buffer,$ref->{AJPEG}->{data_offset},$ref->{AJPEG}->{data_length}), { debug => 1});
# my $per_frame = Image::Animated::JPEG::decode_ajpeg_data( $buffer, { debug => 1 } );
# use Data::Dumper;
# print Dumper $per_frame;
print " Writing frame #". $cnt ." to $framepath \n" if $debug;
open(my $fh, ">", $framepath) or die " Can't open $framepath: $!";
binmode($fh);
# syswrite($fh,$buffer);
print $fh $buffer;
close($fh);
if($keep_mtime){
print " Adjusting mtime of frame output file \n" if $debug;
utime(0, $stat[9], $framepath);
}
}
exit;
}
## default assemble mode
pod2usage({ -message => "\n Please supply an output-file and a number of JPEG images (frames)\n on command-line.\n Example makeajpeg -o out.jpg frame1.jpg frame2.jpg\n", exitval => 2 }) unless $ARGV[0] && $output_file;
die " Output-file $output_file exists! (Use --force to overwrite)\n" if -f $output_file && !$force;
for(@ARGV){ die " Could not find file $_!\n" unless -f $_; }
( run in 1.030 second using v1.01-cache-2.11-cpan-71847e10f99 )