#!/usr/bin/perl # # exifmunge: manipulate exif metadata inside a jpeg file # # Gerald Oskoboiny, 16 Feb 2002 # # I wrote this because I kept forgetting to rotate images in my camera # before downloading them, and wanted to change the EXIF orientation # info stored in the file. # # bugs: # - assumes orientation is stored in byte 55 of the file # # source: http://impressive.net/software/photo/source/exifmunge # # $Id: exifmunge,v 1.3 2002/08/08 03:58:03 gerald Exp $ # use strict; my %opt; # global hash to keep track of command line options my $debuggin = 0; # parse command line arguments my @files = &parse_args( \%opt, \@ARGV ); # @@ way inefficient; rewrite foreach my $file (@files) { if ( $opt{set_orientation} ) { &set_orientation($file, $opt{orientation}); } } exit; ########################################################################### sub parse_args { # parse command line arguments # @@ should use Getopt::Long instead of parsing args manually my ($opt_ref,$args_ref) = @_; my $opt = %$opt_ref; # deref my @args = @$args_ref; # deref my @files; &print_usage unless $args[0] =~ /^-/; # first arg must be an option while (my $arg = shift @args) { if (( $arg eq "--orientation" ) || ( $arg eq "-o" )) { $opt{set_orientation} = 1; $opt{orientation} = shift @args; if ( ! length $opt{orientation} ) { print STDERR "ignoring --orientation; no orientation specified!?"; $opt{set_orientation} = 0; } } elsif ( $arg =~ /^-/ ) { # unknown option specified? &print_usage; } else { my $file = $arg; if ( ! -f $file ) { print "skipping $arg because $file is not a file\n" if $debuggin; next; } push( @files, $file ); # add this file to the list } } return @files; } sub print_usage { print STDERR "\nusage: $0 --orientation {n} file1 file2 ...\n\n"; exit -1; } sub set_orientation { my($file,$orientation) = @_; my $oldfile = $file . ".old"; my $buf; # buffer to hold bits of $file rename( $file, $oldfile ); open( NEW, "> $file" ) or die "error creating new file $file: $!"; open( OLD, "< $oldfile" ) or die "error reading from old file $file: $!"; $buf = join('',()); # read whole file into $buf # way inefficient; should use seek/read/write etc instead close( OLD ) or die "error closing old file $oldfile: $!"; my $old_o = substr( $buf, 54, 1 ); print "old orientation was: ", ord($old_o), "\n"; print "setting orientation to: ", $orientation, "\n"; substr( $buf, 54, 1 ) = chr($orientation); print NEW $buf; close( NEW ) or die "error closing new file $file: $!"; return; }