#!/usr/bin/perl -w

use Image::Magick;
use Image::ExifTool;
use File::Glob ':globally';
use Data::Dumper;
use Carp;
use English qw( -no_match_vars ) ;
use Getopt::Long;
use Time::Local;
use Image::JpegCheck;

use strict;

my $step = 10;
my $size = 1000000;
my $stepnumber = 1000;
my $opts_ref = GetOptions (
				    "copyright=s" => \my $copyright, #setting new copyright
                                    "size=i" => \$size,    # numeric
                                    "rotate=s" => \my $rotation_list,
                                    "step=i" => \$step,                         # numeric, step size (0 .. 100);
                                    "number=i" => \$stepnumber,   # max number of steps
                                  );

if ($#ARGV < 0){
croak "USAGE: $0 files\n";
}
if ($step  < 0 || $step > 100){
croak "Option -step takes a number between 0 and 100. Default is 10";
}

my $rotations_ref;
if ($rotation_list){
    $rotations_ref = get_rotation_list($rotation_list);
}

my @jpeg_files;
foreach my $entry (@ARGV){
my @files = glob $entry;
push @jpeg_files, @files;
}


#fetch EXIF fileinfos
my $fileinfos_ref = get_file_infos(@jpeg_files);

#
adjust_file_size($fileinfos_ref, $rotations_ref);

##########################################################################
# Usage:                        my $exifinfos_ref = get_file_infos();
# Purpose:                     gets a List consisting of EXIF-infos with essential Tags
# Return:                       returns a reference to a list of hashes
# Parameters:                a list with jpeg files (full paht)
# Exceptions:                 none
# Comments:                 none
sub get_file_infos {
my @jpeg_files = @_;
my $exifTool = Image::ExifTool->new();
my @for_img_infos;
    foreach my $img_file (@jpeg_files){
    my @srcfileTagList = ('Directory','FileName', 'DateTimeOriginal',
                                     'Orientation', 'ImageSize','ExifImageWidth', 'ExifImageHeight',
                                    'FileSize','Copyright');
    my $srcfileinfo = $exifTool->ImageInfo($img_file,@srcfileTagList);
    push @for_img_infos, $srcfileinfo;
    }
return \@for_img_infos;
}

##########################################################################
# Usage:                        adjust_file_size($file_info_ref, $rotinfo_ref);
# Purpose:                     gets a List consisting of EXIF-infos with essential Tags
# Return:                       returns a List of hashes
# Parameters:                reference to a list with fileinfos, reference to a simple hash: key filename,
#                                   value:- rotation angle (optional).
# Exceptions:                 none
# Comments:                 none
sub adjust_file_size {
my ($file_info_ref, $rotinfo_ref) = @_;
my $number = $#$file_info_ref; #number of jpeg-files
my $counter= 1;
    IMAGE_PROCESSION:
    foreach my $imgfile (@$file_info_ref){
        my $file = $imgfile->{'Directory'}.'/'.$imgfile->{'FileName'};
        next IMAGE_PROCESSION if (! is_jpeg($file));
        my $model=Image::Magick->new();
        my $x=$model->ReadImage($file);
        warn "$x" if "$x";
        my $filesize = $model->Get('filesize');
        my $shrink_factor = 100;
        my $stepcounter = 1;
        IMAGE_MANIPULATION:
        while ($filesize > $size){
            last IMAGE_MANIPULATION if ($stepcounter > $stepnumber);
            $shrink_factor = $shrink_factor -$step;
            my $adap_model=Image::Magick->new();
            my $y=$adap_model->ReadImage($file);
            warn "$y" if "$y";
            $shrink_factor = $shrink_factor-$step;
            last IMAGE_MANIPULATION if ($shrink_factor < 0);
            $adap_model->AdaptiveResize("$shrink_factor%");
            print "Writing $imgfile->{'Directory'}/tmp.jpg\n";
            $adap_model->Write($imgfile->{'Directory'}.'/tmp.jpg');
            my $tmp_model=Image::Magick->new();
            $x=$tmp_model->ReadImage("$imgfile->{'Directory'}/tmp.jpg");
            warn "$x" if "$x";
            $filesize = $tmp_model->Get('filesize');
            print "Size of tmp_file: $filesize\n";
            $stepcounter++;
        }
      if (-f "$imgfile->{'Directory'}/tmp.jpg"){
         if ($rotinfo_ref && exists $rotinfo_ref->{$imgfile->{'FileName'}}){
            my $rot_model=Image::Magick->new();
            my $z=$rot_model->ReadImage("$imgfile->{'Directory'}/tmp.jpg");
            warn "$z" if "$z";
            my $fname = $imgfile->{'FileName'};
            $rot_model->Rotate( $rotinfo_ref->{$fname} );
            print "Schreibe $imgfile->{'Directory'}/tmp.jpg nach Rotation um $rotinfo_ref->{$fname} Grad\n";
            $rot_model->Write($imgfile->{'Directory'}.'/tmp.jpg');
         }
         if ($copyright){
         print "Writiing Copyright\n";
         write_copyright($imgfile->{'Directory'}.'/tmp.jpg',$copyright);
         }
         print "Finishing by unlinking and renaming.\n";
         unlink $file;
         my $lcfilename = lc $imgfile->{'FileName'};
         my $file = "$imgfile->{'Directory'}/$lcfilename";
         rename  "$imgfile->{'Directory'}/tmp.jpg", $file;
         print "setting mtime of $file to creation- time\n";
         set_file_time($file);
         my $percent = 100*$counter/$number;
         print "Picture Nr. $counter of $number ready.\n";
         print "$percent% ready\n";
        $counter++;
      }
    }
}

sub get_rotation_list {
my ($rot_file) = @_;
my %rot_hash;;
open my $RF, '<', $rot_file or carp "Konnte $rot_file nicht öffnen: $OS_ERROR!\n";
while (<$RF>) {
    my $line = $_;
    chomp;
    my @fields = split m{ \t }xms;
    $rot_hash{$fields[0]} = $fields[1] if $fields[0];
    }
close $RF;
return \%rot_hash;
}

sub write_copyright {
my ($srcfile, $copyright) = @_;
my $tag = 'Copyright';
my $newValue = $copyright;
my $exifTool = Image::ExifTool->new();
$exifTool->SetNewValue($tag, $newValue);
$exifTool->WriteInfo($srcfile);
}

sub set_file_time {
my ($fname) = @_;
my ($year, $mon, $mday, $hour, $min, $sec) = split / (?: \s | : ) /xms, get_datetime_info($fname)->{'DateTimeOriginal'};

print "Date of the image file is being set to  $mday.$mon $year at $hour:$min:$sec\n";
my $atime = time;
my $mtime = timegm($sec, $min, $hour, $mday, $mon-1, $year-1900);
utime $atime, $mtime, $fname or carp "Konnte Zeitstempel nicht ändern: $OS_ERROR\n";
print "The Date of $fname is now  $mday.$mon $year um $hour:$min:$sec\n";
}

sub get_datetime_info {
my ($img_file) = @_;
my $datetime;
my $exifTool = Image::ExifTool->new();
my @srcfileTagList = ('DateTimeOriginal');
return $exifTool->ImageInfo($img_file,@srcfileTagList);
}




__END__

=head1 NAME

redimgsize.pl  - Reduce size of multiple jpeg-images, rotate if needed,
                        sets the manipulation date to the DateTimeOriginal according EXIF-Data.


=head1 VERSION

This documentation refers to redimgsize.pl version 0.0.1


=head1 USAGE

    redimgsize.pl [options] file1.jpg file2.jpg, dir/*  ..

=head1 REQUIRED ARGUMENTS

Path to files (wildcards allowed).


=head1 OPTIONS

-c name:     Sets Copyright to the given Argument
--copyright



=head1 DESCRIPTION

A full description of the application and its features.
May include numerous subsections (i.e. =head2, =head3, etc.)


=head1 DIAGNOSTICS

A list of every error and warning message that the application can generate
(even the ones that will "never happen"), with a full explanation of each
problem, one or more likely causes, and any suggested remedies. If the
application generates exit status codes (e.g. under Unix) then list the exit
status associated with each error.


=head1 CONFIGURATION AND ENVIRONMENT

A full explanation of any configuration system(s) used by the application,
including the names and locations of any configuration files, and the
meaning of any environment variables or properties that can be set. These
descriptions must also include details of any configuration language used
(also see  QUOTE \" " INCLUDETEXT "19_Miscellanea" "XREF40334_Configuration_Files_"\! Configuration Files QUOTE \" " QUOTE " in Chapter "  in Chapter  INCLUDETEXT "19_Miscellanea" "XREF55683__"\! 19).


=head1 DEPENDENCIES
=head1 INCOMPATIBILITIES
=head1 BUGS AND LIMITATIONS
=head1 AUTHOR
=head1 LICENCE AND COPYRIGHT

These sections are the same as in  REF XREF45430_Example_71_ \h Example 7-1  08D0C9EA79F9BACE118C8200AA004BA90B0200000008000000160000005800520045004600340035003400330030005F004500780061006D0070006C0065005F00370031005F000000 .

