exiftool-vendored.exe 12.56.0 → 12.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/exiftool_files/Changes +80 -5
- package/bin/exiftool_files/README +2 -2
- package/bin/exiftool_files/config_files/example.config +1 -0
- package/bin/exiftool_files/config_files/rotate_regions.config +1 -1
- package/bin/exiftool_files/exiftool.pl +174 -99
- package/bin/exiftool_files/lib/Image/ExifTool/AIFF.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/APE.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +19 -15
- package/bin/exiftool_files/lib/Image/ExifTool/Canon.pm +26 -6
- package/bin/exiftool_files/lib/Image/ExifTool/CanonRaw.pm +5 -1
- package/bin/exiftool_files/lib/Image/ExifTool/DJI.pm +28 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Exif.pm +77 -19
- package/bin/exiftool_files/lib/Image/ExifTool/FlashPix.pm +32 -10
- package/bin/exiftool_files/lib/Image/ExifTool/FujiFilm.pm +7 -3
- package/bin/exiftool_files/lib/Image/ExifTool/GPS.pm +7 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +30 -7
- package/bin/exiftool_files/lib/Image/ExifTool/JPEG.pm +14 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Jpeg2000.pm +5 -5
- package/bin/exiftool_files/lib/Image/ExifTool/LIF.pm +10 -2
- package/bin/exiftool_files/lib/Image/ExifTool/LNK.pm +5 -4
- package/bin/exiftool_files/lib/Image/ExifTool/MIE.pm +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/MPEG.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/MakerNotes.pm +3 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Minolta.pm +6 -7
- package/bin/exiftool_files/lib/Image/ExifTool/MinoltaRaw.pm +2 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +1003 -907
- package/bin/exiftool_files/lib/Image/ExifTool/NikonCustom.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/NikonSettings.pm +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +88 -6
- package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +10 -2
- package/bin/exiftool_files/lib/Image/ExifTool/PanasonicRaw.pm +27 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Pentax.pm +8 -5
- package/bin/exiftool_files/lib/Image/ExifTool/PhaseOne.pm +14 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Photoshop.pm +38 -7
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +44 -13
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +40 -6
- package/bin/exiftool_files/lib/Image/ExifTool/README +19 -2
- package/bin/exiftool_files/lib/Image/ExifTool/RIFF.pm +34 -13
- package/bin/exiftool_files/lib/Image/ExifTool/Rawzor.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Ricoh.pm +2 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Sigma.pm +5 -4
- package/bin/exiftool_files/lib/Image/ExifTool/SigmaRaw.pm +9 -3
- package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +24 -1
- package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +4678 -4628
- package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +305 -113
- package/bin/exiftool_files/lib/Image/ExifTool/Validate.pm +5 -5
- package/bin/exiftool_files/lib/Image/ExifTool/WriteExif.pl +42 -0
- package/bin/exiftool_files/lib/Image/ExifTool/WriteXMP.pl +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +150 -36
- package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +19 -4
- package/bin/exiftool_files/lib/Image/ExifTool/XMP2.pl +2 -1
- package/bin/exiftool_files/lib/Image/ExifTool.pm +195 -42
- package/bin/exiftool_files/lib/Image/ExifTool.pod +44 -9
- package/package.json +2 -2
|
@@ -29,7 +29,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
|
|
|
29
29
|
%jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
|
|
30
30
|
%static_vars);
|
|
31
31
|
|
|
32
|
-
$VERSION = '12.
|
|
32
|
+
$VERSION = '12.60';
|
|
33
33
|
$RELEASE = '';
|
|
34
34
|
@ISA = qw(Exporter);
|
|
35
35
|
%EXPORT_TAGS = (
|
|
@@ -75,6 +75,7 @@ sub GetAllGroups($;$);
|
|
|
75
75
|
sub GetNewGroups($);
|
|
76
76
|
sub GetDeleteGroups();
|
|
77
77
|
sub AddUserDefinedTags($%);
|
|
78
|
+
sub SetAlternateFile($$$);
|
|
78
79
|
# non-public routines below
|
|
79
80
|
sub InsertTagValues($$$;$$$);
|
|
80
81
|
sub IsWritable($);
|
|
@@ -113,6 +114,7 @@ sub WriteTIFF($$$);
|
|
|
113
114
|
sub PackUTF8(@);
|
|
114
115
|
sub UnpackUTF8($);
|
|
115
116
|
sub SetPreferredByteOrder($;$);
|
|
117
|
+
sub ImageDataMD5($$$;$$);
|
|
116
118
|
sub CopyBlock($$$);
|
|
117
119
|
sub CopyFileAttrs($$$);
|
|
118
120
|
sub TimeNow(;$$);
|
|
@@ -1821,6 +1823,17 @@ my %systemTagsNotes = (
|
|
|
1821
1823
|
if specifically requested
|
|
1822
1824
|
},
|
|
1823
1825
|
},
|
|
1826
|
+
ImageDataMD5 => {
|
|
1827
|
+
Notes => q{
|
|
1828
|
+
MD5 of image data. Generated only if specifically requested for JPEG and
|
|
1829
|
+
TIFF-based images, PNG, CRW, CR3, MRW, RAF, X3F and AVIF images, MOV/MP4
|
|
1830
|
+
videos, and some RIFF-based files. The MD5 includes the main image data,
|
|
1831
|
+
plus JpgFromRaw/OtherImage for some formats, but does not include
|
|
1832
|
+
ThumbnailImage or PreviewImage. Includes video and audio data for MOV/MP4.
|
|
1833
|
+
The L<XMP-et:OriginalImageMD5 tag|XMP.html#ExifTool> provides a place to
|
|
1834
|
+
store these values in the file.
|
|
1835
|
+
},
|
|
1836
|
+
},
|
|
1824
1837
|
);
|
|
1825
1838
|
|
|
1826
1839
|
# tags defined by UserParam option (added at runtime)
|
|
@@ -2043,7 +2056,9 @@ sub new
|
|
|
2043
2056
|
$$self{DEL_GROUP} = { }; # lookup for groups to delete when writing
|
|
2044
2057
|
$$self{SAVE_COUNT} = 0; # count calls to SaveNewValues()
|
|
2045
2058
|
$$self{FILE_SEQUENCE} = 0; # sequence number for files when reading
|
|
2059
|
+
$$self{FILES_WRITTEN} = 0; # count of files successfully written
|
|
2046
2060
|
$$self{INDENT2} = ''; # indentation of verbose messages from SetNewValue
|
|
2061
|
+
$$self{ALT_EXIFTOOL} = { }; # alternate exiftool objects
|
|
2047
2062
|
|
|
2048
2063
|
# initialize our new groups for writing
|
|
2049
2064
|
$self->SetNewGroups(@defaultWriteGroups);
|
|
@@ -2478,8 +2493,33 @@ sub ExtractInfo($;@)
|
|
|
2478
2493
|
$self->WarnOnce('Install Time::HiRes to generate ProcessingTime');
|
|
2479
2494
|
}
|
|
2480
2495
|
}
|
|
2481
|
-
|
|
2496
|
+
|
|
2497
|
+
# create MD5 object if ImageDataMD5 is requested
|
|
2498
|
+
if ($$req{imagedatamd5} and not $$self{ImageDataMD5}) {
|
|
2499
|
+
if (require Digest::MD5) {
|
|
2500
|
+
$$self{ImageDataMD5} = Digest::MD5->new;
|
|
2501
|
+
} else {
|
|
2502
|
+
$self->WarnOnce('Install Digest::MD5 to calculate image data MD5');
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2482
2505
|
++$$self{FILE_SEQUENCE}; # count files read
|
|
2506
|
+
# extract information from alternate files if necessary
|
|
2507
|
+
my ($g8, $altExifTool);
|
|
2508
|
+
foreach $g8 (keys %{$$self{ALT_EXIFTOOL}}) {
|
|
2509
|
+
$altExifTool = $$self{ALT_EXIFTOOL}{$g8};
|
|
2510
|
+
next if $$altExifTool{DID_EXTRACT}; # avoid extracting twice
|
|
2511
|
+
$$altExifTool{OPTIONS} = $$self{OPTIONS};
|
|
2512
|
+
$$altExifTool{GLOBAL_TIME_OFFSET} = $$self{GLOBAL_TIME_OFFSET};
|
|
2513
|
+
$$altExifTool{REQ_TAG_LOOKUP} = $$self{REQ_TAG_LOOKUP};
|
|
2514
|
+
$altExifTool->ExtractInfo($$altExifTool{ALT_FILE});
|
|
2515
|
+
# set family 8 group name for all tags
|
|
2516
|
+
foreach (keys %{$$altExifTool{VALUE}}) {
|
|
2517
|
+
my $ex = $$altExifTool{TAG_EXTRA}{$_};
|
|
2518
|
+
$ex or $ex = $$altExifTool{TAG_EXTRA}{$_} = { };
|
|
2519
|
+
$$ex{G8} = $g8;
|
|
2520
|
+
}
|
|
2521
|
+
$$altExifTool{DID_EXTRACT} = 1;
|
|
2522
|
+
}
|
|
2483
2523
|
}
|
|
2484
2524
|
|
|
2485
2525
|
my $filename = $$self{FILENAME}; # image file name ('' if already open)
|
|
@@ -2869,6 +2909,10 @@ sub ExtractInfo($;@)
|
|
|
2869
2909
|
# restore necessary members when exiting re-entrant code
|
|
2870
2910
|
$$self{$_} = $$reEntry{$_} foreach keys %$reEntry;
|
|
2871
2911
|
SetByteOrder($saveOrder);
|
|
2912
|
+
} elsif ($$self{ImageDataMD5}) {
|
|
2913
|
+
my $digest = $$self{ImageDataMD5}->hexdigest;
|
|
2914
|
+
# (don't store empty digest)
|
|
2915
|
+
$self->FoundTag(ImageDataMD5 => $digest) unless $digest eq 'd41d8cd98f00b204e9800998ecf8427e';
|
|
2872
2916
|
}
|
|
2873
2917
|
|
|
2874
2918
|
# ($type may be undef without an Error when processing sub-documents)
|
|
@@ -3500,6 +3544,10 @@ sub GetGroup($$;$)
|
|
|
3500
3544
|
$groups[6] = $$ex{G6};
|
|
3501
3545
|
}
|
|
3502
3546
|
}
|
|
3547
|
+
if ($$ex{G8}) {
|
|
3548
|
+
$groups[7] = '';
|
|
3549
|
+
$groups[8] = $$ex{G8};
|
|
3550
|
+
}
|
|
3503
3551
|
# generate tag ID group names unless obviously not needed
|
|
3504
3552
|
unless ($noID) {
|
|
3505
3553
|
my $id = $$tagInfo{KeysID} || $$tagInfo{TagID};
|
|
@@ -3685,13 +3733,21 @@ COMPOSITE_TAG:
|
|
|
3685
3733
|
next COMPOSITE_TAG;
|
|
3686
3734
|
}
|
|
3687
3735
|
}
|
|
3736
|
+
my ($i, $key, @keys, $altFile);
|
|
3737
|
+
my $et = $self;
|
|
3738
|
+
# get tags from alternate file if a family 8 group was specified
|
|
3739
|
+
if ($reqTag =~ /\b(File\d+):/i and $$self{ALT_EXIFTOOL}{$1}) {
|
|
3740
|
+
$et = $$self{ALT_EXIFTOOL}{$1};
|
|
3741
|
+
$altFile = $1;
|
|
3742
|
+
}
|
|
3688
3743
|
# (CAREFUL! keys may not be sequential if one was deleted)
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
push @keys, $key if defined $$rawValue{$key};
|
|
3744
|
+
for ($key=$name, $i=$$et{DUPL_TAG}{$name} || 0; ; --$i) {
|
|
3745
|
+
push @keys, $key if defined $$et{VALUE}{$key};
|
|
3692
3746
|
last if $i <= 0;
|
|
3693
3747
|
$key = "$name ($i)";
|
|
3694
3748
|
}
|
|
3749
|
+
# make sure the necessary information is available from the alternate file
|
|
3750
|
+
$self->CopyAltInfo($altFile, \@keys) if $altFile;
|
|
3695
3751
|
# find first matching tag
|
|
3696
3752
|
$key = $self->GroupMatches($reqGroup, \@keys);
|
|
3697
3753
|
$reqTag = $key || "$name (0)";
|
|
@@ -4133,7 +4189,11 @@ sub SplitFileName($)
|
|
|
4133
4189
|
} else {
|
|
4134
4190
|
($name = $file) =~ tr/\\/\//;
|
|
4135
4191
|
# remove path
|
|
4136
|
-
|
|
4192
|
+
if ($name =~ s/(.*)\///) {
|
|
4193
|
+
$dir = length($1) ? $1 : '/';
|
|
4194
|
+
} else {
|
|
4195
|
+
$dir = '.';
|
|
4196
|
+
}
|
|
4137
4197
|
}
|
|
4138
4198
|
return ($dir, $name);
|
|
4139
4199
|
}
|
|
@@ -4296,9 +4356,9 @@ sub GetFileTime($$)
|
|
|
4296
4356
|
# on Windows, try to work around incorrect file times when daylight saving time is in effect
|
|
4297
4357
|
if ($^O eq 'MSWin32') {
|
|
4298
4358
|
if (not eval { require Win32::API }) {
|
|
4299
|
-
$self->WarnOnce('Install Win32::API for proper handling of Windows file times');
|
|
4359
|
+
$self->WarnOnce('Install Win32::API for proper handling of Windows file times', 1);
|
|
4300
4360
|
} elsif (not eval { require Win32API::File }) {
|
|
4301
|
-
$self->WarnOnce('Install Win32API::File for proper handling of Windows file times');
|
|
4361
|
+
$self->WarnOnce('Install Win32API::File for proper handling of Windows file times', 1);
|
|
4302
4362
|
} else {
|
|
4303
4363
|
# get Win32 handle, needed for GetFileTime
|
|
4304
4364
|
my $win32Handle = eval { Win32API::File::GetOsFHandle($file) };
|
|
@@ -4548,6 +4608,29 @@ sub RemoveTagsFromList($$$$;$)
|
|
|
4548
4608
|
$_[0] = \@filteredTags; # update tag list
|
|
4549
4609
|
}
|
|
4550
4610
|
|
|
4611
|
+
#------------------------------------------------------------------------------
|
|
4612
|
+
# Copy tags from alternate input file
|
|
4613
|
+
# Inputs: 0) ExifTool ref, 1) family 8 group, 2) list ref for tag keys to copy
|
|
4614
|
+
# - updates tag key list to match keys newly added to $self
|
|
4615
|
+
sub CopyAltInfo($$$)
|
|
4616
|
+
{
|
|
4617
|
+
my ($self, $g8, $tags) = @_;
|
|
4618
|
+
my ($tag, $vtag);
|
|
4619
|
+
return unless $g8 =~ /(\d+)/;
|
|
4620
|
+
my $et = $$self{ALT_EXIFTOOL}{$g8} or return;
|
|
4621
|
+
my $altOrder = ($1 + 1) * 100000; # increment file order
|
|
4622
|
+
foreach $tag (@$tags) {
|
|
4623
|
+
($vtag = $tag) =~ s/( |$)/ #[$g8]/;
|
|
4624
|
+
unless (defined $$self{VALUE}{$vtag}) {
|
|
4625
|
+
$$self{VALUE}{$vtag} = $$et{VALUE}{$tag};
|
|
4626
|
+
$$self{TAG_INFO}{$vtag} = $$et{TAG_INFO}{$tag};
|
|
4627
|
+
$$self{TAG_EXTRA}{$vtag} = $$et{TAG_EXTRA}{$tag} || { };
|
|
4628
|
+
$$self{FILE_ORDER}{$vtag} = ($$et{FILE_ORDER}{$tag} || 0) + $altOrder;
|
|
4629
|
+
}
|
|
4630
|
+
$tag = $vtag;
|
|
4631
|
+
}
|
|
4632
|
+
}
|
|
4633
|
+
|
|
4551
4634
|
#------------------------------------------------------------------------------
|
|
4552
4635
|
# Set list of found tags from previously requested tags
|
|
4553
4636
|
# Inputs: 0) ExifTool object reference
|
|
@@ -4574,11 +4657,17 @@ sub SetFoundTags($)
|
|
|
4574
4657
|
my $tagHash = $$self{VALUE};
|
|
4575
4658
|
my $reqTag;
|
|
4576
4659
|
foreach $reqTag (@$reqTags) {
|
|
4577
|
-
my (@matches, $group, $allGrp, $allTag, $byValue);
|
|
4660
|
+
my (@matches, $group, $allGrp, $allTag, $byValue, $g8);
|
|
4661
|
+
my $et = $self;
|
|
4578
4662
|
if ($reqTag =~ /^(.*):(.+)/) {
|
|
4579
4663
|
($group, $tag) = ($1, $2);
|
|
4580
4664
|
if ($group =~ /^(\*|all)$/i) {
|
|
4581
4665
|
$allGrp = 1;
|
|
4666
|
+
} elsif ($reqTag =~ /\bfile(\d+):/i) {
|
|
4667
|
+
$g8 = "File$1";
|
|
4668
|
+
$et = $$self{ALT_EXIFTOOL}{$g8} || $self;
|
|
4669
|
+
$fileOrder = $$et{FILE_ORDER};
|
|
4670
|
+
$tagHash = $$et{VALUE};
|
|
4582
4671
|
} elsif ($group !~ /^[-\w:]*$/) {
|
|
4583
4672
|
$self->Warn("Invalid group name '${group}'");
|
|
4584
4673
|
$group = 'invalid';
|
|
@@ -4620,7 +4709,7 @@ sub SetFoundTags($)
|
|
|
4620
4709
|
}
|
|
4621
4710
|
if (defined $group and not $allGrp) {
|
|
4622
4711
|
# keep only specified group
|
|
4623
|
-
@matches = $
|
|
4712
|
+
@matches = $et->GroupMatches($group, \@matches);
|
|
4624
4713
|
next unless @matches or not $allTag;
|
|
4625
4714
|
}
|
|
4626
4715
|
if (@matches > 1) {
|
|
@@ -4629,9 +4718,9 @@ sub SetFoundTags($)
|
|
|
4629
4718
|
# return only the highest priority tag unless duplicates wanted
|
|
4630
4719
|
unless ($doDups or $allTag or $allGrp) {
|
|
4631
4720
|
$tag = shift @matches;
|
|
4632
|
-
my $oldPriority = $$
|
|
4721
|
+
my $oldPriority = $$et{PRIORITY}{$tag} || 1;
|
|
4633
4722
|
foreach (@matches) {
|
|
4634
|
-
my $priority = $$
|
|
4723
|
+
my $priority = $$et{PRIORITY}{$_};
|
|
4635
4724
|
$priority = 1 unless defined $priority;
|
|
4636
4725
|
next unless $priority >= $oldPriority;
|
|
4637
4726
|
$tag = $_;
|
|
@@ -4645,6 +4734,13 @@ sub SetFoundTags($)
|
|
|
4645
4734
|
# bogus file order entry to avoid warning if sorting in file order
|
|
4646
4735
|
$$self{FILE_ORDER}{$matches[0]} = 9999;
|
|
4647
4736
|
}
|
|
4737
|
+
# copy over necessary information for tags from alternate files
|
|
4738
|
+
if ($g8) {
|
|
4739
|
+
$self->CopyAltInfo($g8, \@matches);
|
|
4740
|
+
# restore variables to original values for main file
|
|
4741
|
+
$fileOrder = $$self{FILE_ORDER};
|
|
4742
|
+
$tagHash = $$self{VALUE};
|
|
4743
|
+
}
|
|
4648
4744
|
# save indices of tags extracted by value
|
|
4649
4745
|
push @byValue, scalar(@$rtnTags) .. (scalar(@$rtnTags)+scalar(@matches)-1) if $byValue;
|
|
4650
4746
|
# save indices of wildcard tags
|
|
@@ -5867,7 +5963,8 @@ sub ConvertTimeSpan($;$)
|
|
|
5867
5963
|
#------------------------------------------------------------------------------
|
|
5868
5964
|
# Patched timelocal() that fixes ActivePerl timezone bug
|
|
5869
5965
|
# Inputs/Returns: same as timelocal()
|
|
5870
|
-
# Notes: must 'require Time::Local' before calling this routine
|
|
5966
|
+
# Notes: must 'require Time::Local' before calling this routine.
|
|
5967
|
+
# Also note that year should be full year, and not relative to 1900 as with localtime
|
|
5871
5968
|
sub TimeLocal(@)
|
|
5872
5969
|
{
|
|
5873
5970
|
my $tm = Time::Local::timelocal(@_);
|
|
@@ -6326,7 +6423,6 @@ sub ProcessJPEG($$)
|
|
|
6326
6423
|
{
|
|
6327
6424
|
local $_;
|
|
6328
6425
|
my ($self, $dirInfo) = @_;
|
|
6329
|
-
my ($ch, $s, $length);
|
|
6330
6426
|
my $options = $$self{OPTIONS};
|
|
6331
6427
|
my $verbose = $$options{Verbose};
|
|
6332
6428
|
my $out = $$options{TextOut};
|
|
@@ -6335,10 +6431,17 @@ sub ProcessJPEG($$)
|
|
|
6335
6431
|
my $req = $$self{REQ_TAG_LOOKUP};
|
|
6336
6432
|
my $htmlDump = $$self{HTML_DUMP};
|
|
6337
6433
|
my %dumpParms = ( Out => $out );
|
|
6434
|
+
my ($ch, $s, $length, $md5, $md5size);
|
|
6338
6435
|
my ($success, $wantTrailer, $trailInfo, $foundSOS, %jumbfChunk);
|
|
6339
6436
|
my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $flirTotal);
|
|
6340
6437
|
my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP);
|
|
6341
6438
|
|
|
6439
|
+
# get pointer to MD5 object if it exists and we are the top-level JPEG
|
|
6440
|
+
if ($$self{FILE_TYPE} eq 'JPEG' and not $$self{DOC_NUM}) {
|
|
6441
|
+
$md5 = $$self{ImageDataMD5};
|
|
6442
|
+
$md5size = 0;
|
|
6443
|
+
}
|
|
6444
|
+
|
|
6342
6445
|
# check to be sure this is a valid JPG (or J2C, or EXV) file
|
|
6343
6446
|
return 0 unless $raf->Read($s, 2) == 2 and $s =~ /^\xff[\xd8\x4f\x01]/;
|
|
6344
6447
|
if ($s eq "\xff\x01") {
|
|
@@ -6385,7 +6488,9 @@ sub ProcessJPEG($$)
|
|
|
6385
6488
|
#
|
|
6386
6489
|
# read ahead to the next segment unless we have reached EOI, SOS or SOD
|
|
6387
6490
|
#
|
|
6388
|
-
unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer
|
|
6491
|
+
unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer and not $md5) or
|
|
6492
|
+
$marker==0x93))
|
|
6493
|
+
{
|
|
6389
6494
|
# read up to next marker (JPEG markers begin with 0xff)
|
|
6390
6495
|
my $buff;
|
|
6391
6496
|
$raf->ReadLine($buff) or last;
|
|
@@ -6415,6 +6520,19 @@ sub ProcessJPEG($$)
|
|
|
6415
6520
|
$nextSegPos = $raf->Tell();
|
|
6416
6521
|
$len -= 4; # subtract size of length word
|
|
6417
6522
|
last unless $raf->Seek($len, 1);
|
|
6523
|
+
} elsif ($md5 and defined $marker and ($marker == 0x00 or $marker == 0xda or
|
|
6524
|
+
($marker >= 0xd0 and $marker <= 0xd7)))
|
|
6525
|
+
{
|
|
6526
|
+
# calculate MD5 for image data (includes leading ff d9 but not trailing ff da)
|
|
6527
|
+
$md5->add("\xff" . chr($marker));
|
|
6528
|
+
my $n = $skipped - (length($buff) - 1); # number of extra 0xff's
|
|
6529
|
+
if (not $n) {
|
|
6530
|
+
$buff = substr($buff, 0, -1); # remove trailing 0xff
|
|
6531
|
+
} elsif ($n > 1) {
|
|
6532
|
+
$buff .= "\xff" x ($n - 1); # add back extra 0xff's
|
|
6533
|
+
}
|
|
6534
|
+
$md5->add($buff);
|
|
6535
|
+
$md5size += $skipped + 2;
|
|
6418
6536
|
}
|
|
6419
6537
|
# read second segment too if this was the first
|
|
6420
6538
|
next unless defined $marker;
|
|
@@ -6625,7 +6743,7 @@ sub ProcessJPEG($$)
|
|
|
6625
6743
|
next if $trailInfo or $wantTrailer or $verbose > 2 or $htmlDump;
|
|
6626
6744
|
}
|
|
6627
6745
|
# must scan to EOI if Validate or JpegCompressionFactor used
|
|
6628
|
-
next if $$options{Validate} or $calcImageLen or $$req{trailer};
|
|
6746
|
+
next if $$options{Validate} or $calcImageLen or $$req{trailer} or $md5;
|
|
6629
6747
|
# nothing interesting to parse after start of scan (SOS)
|
|
6630
6748
|
$success = 1;
|
|
6631
6749
|
last; # all done parsing file
|
|
@@ -6707,7 +6825,7 @@ sub ProcessJPEG($$)
|
|
|
6707
6825
|
} elsif ($marker == 0xe1) { # APP1 (EXIF, XMP, QVCI, PARROT)
|
|
6708
6826
|
# (some Kodak cameras don't put a second "\0", and I have seen an
|
|
6709
6827
|
# example where there was a second 4-byte APP1 segment header)
|
|
6710
|
-
if ($$segDataPt =~ /^(.{0,4})Exif\0
|
|
6828
|
+
if ($$segDataPt =~ /^(.{0,4})Exif\0./is) {
|
|
6711
6829
|
undef $dumpType; # (will be dumped here)
|
|
6712
6830
|
# this is EXIF data --
|
|
6713
6831
|
# get the data block (into a common variable)
|
|
@@ -7008,7 +7126,7 @@ sub ProcessJPEG($$)
|
|
|
7008
7126
|
$self->FoundTag('PreviewImage', $preview);
|
|
7009
7127
|
undef $preview;
|
|
7010
7128
|
}
|
|
7011
|
-
} elsif ($marker == 0xe4) { # APP4 (InfiRay, "SCALADO", FPXR, PreviewImage)
|
|
7129
|
+
} elsif ($marker == 0xe4) { # APP4 (InfiRay, "SCALADO", FPXR, DJI, PreviewImage)
|
|
7012
7130
|
if ($$segDataPt =~ /^SCALADO\0/ and $length >= 16) {
|
|
7013
7131
|
$dumpType = 'SCALADO';
|
|
7014
7132
|
my ($num, $idx, $len) = unpack('x8n2N', $$segDataPt);
|
|
@@ -7039,6 +7157,16 @@ sub ProcessJPEG($$)
|
|
|
7039
7157
|
DirStart(\%dirInfo, 0, 0);
|
|
7040
7158
|
my $tagTablePtr = GetTagTable('Image::ExifTool::DJI::ThermalParams');
|
|
7041
7159
|
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
|
7160
|
+
} elsif ($$self{Make} eq 'DJI' and $$segDataPt =~ /^(.{32})?.{32}\x2c\x01\x20\0/s) {
|
|
7161
|
+
$dumpType = 'DJI ThermalParams2';
|
|
7162
|
+
DirStart(\%dirInfo, $1 ? 32 : 0, 0);
|
|
7163
|
+
my $tagTablePtr = GetTagTable('Image::ExifTool::DJI::ThermalParams2');
|
|
7164
|
+
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
|
7165
|
+
} elsif ($$self{Make} eq 'DJI' and $$segDataPt =~ /^.{32}\xaa\x55\x38\0/s) {
|
|
7166
|
+
$dumpType = 'DJI ThermalParams3';
|
|
7167
|
+
DirStart(\%dirInfo, 32, 0);
|
|
7168
|
+
my $tagTablePtr = GetTagTable('Image::ExifTool::DJI::ThermalParams3');
|
|
7169
|
+
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
|
7042
7170
|
} elsif ($$self{HasIJPEG} and $length >= 120) {
|
|
7043
7171
|
$dumpType = 'InfiRay Factory';
|
|
7044
7172
|
SetByteOrder('II');
|
|
@@ -7152,6 +7280,13 @@ sub ProcessJPEG($$)
|
|
|
7152
7280
|
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
|
7153
7281
|
delete $$self{SET_GROUP0};
|
|
7154
7282
|
delete $$self{SET_GROUP1};
|
|
7283
|
+
} elsif ($$segDataPt =~ /^DJI-DBG\0/) {
|
|
7284
|
+
$dumpType = 'DJI Info';
|
|
7285
|
+
my $tagTablePtr = GetTagTable('Image::ExifTool::DJI::Info');
|
|
7286
|
+
DirStart(\%dirInfo, 8, 0);
|
|
7287
|
+
$$self{SET_GROUP0} = 'APP7';
|
|
7288
|
+
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
|
7289
|
+
delete $$self{SET_GROUP0};
|
|
7155
7290
|
} elsif ($$segDataPt =~ /^\x1aQualcomm Camera Attributes/) {
|
|
7156
7291
|
# found in HP iPAQ_VoiceMessenger
|
|
7157
7292
|
$dumpType = 'Qualcomm';
|
|
@@ -7412,6 +7547,8 @@ sub ProcessJPEG($$)
|
|
|
7412
7547
|
delete $extendedXMP{$guid};
|
|
7413
7548
|
}
|
|
7414
7549
|
}
|
|
7550
|
+
# print verbose MD5 message if necessary
|
|
7551
|
+
print $out "$$self{INDENT}(ImageDataMD5: $md5size bytes of JPEG image data)\n" if $md5size and $verbose;
|
|
7415
7552
|
# calculate JPEGDigest if requested
|
|
7416
7553
|
if (@dqt) {
|
|
7417
7554
|
require Image::ExifTool::JPEGDigest;
|
|
@@ -7680,7 +7817,7 @@ sub DoProcessTIFF($$;$)
|
|
|
7680
7817
|
}
|
|
7681
7818
|
}
|
|
7682
7819
|
# update FileType if necessary now that we know more about the file
|
|
7683
|
-
if ($$self{DNGVersion} and $$self{
|
|
7820
|
+
if ($$self{DNGVersion} and $$self{FileType} !~ /^(DNG|GPR)$/) {
|
|
7684
7821
|
# override whatever FileType we set since we now know it is DNG
|
|
7685
7822
|
$self->OverrideFileType($$self{TIFF_TYPE} = 'DNG');
|
|
7686
7823
|
}
|
|
@@ -7988,7 +8125,7 @@ sub ProcessDirectory($$$;$)
|
|
|
7988
8125
|
# patch for bug in Windows phone 7.5 O/S that writes incorrect InteropIFD pointer
|
|
7989
8126
|
return 0 unless $dirName eq 'GPS' and $$self{PROCESSED}{$addr} eq 'InteropIFD';
|
|
7990
8127
|
}
|
|
7991
|
-
$$self{PROCESSED}{$addr} = $dirName;
|
|
8128
|
+
$$self{PROCESSED}{$addr} = $dirName unless $$tagTablePtr{VARS} and $$tagTablePtr{VARS}{ALLOW_REPROCESS};
|
|
7992
8129
|
}
|
|
7993
8130
|
my $oldOrder = GetByteOrder();
|
|
7994
8131
|
my @save = @$self{'INDENT','DIR_NAME','Compression','SubfileType'};
|
|
@@ -8566,7 +8703,7 @@ sub DoEscape($$)
|
|
|
8566
8703
|
sub SetFileType($;$$$)
|
|
8567
8704
|
{
|
|
8568
8705
|
my ($self, $fileType, $mimeType, $normExt) = @_;
|
|
8569
|
-
unless ($$self{
|
|
8706
|
+
unless ($$self{FileType} and not $$self{DOC_NUM}) {
|
|
8570
8707
|
my $baseType = $$self{FILE_TYPE};
|
|
8571
8708
|
my $ext = $$self{FILE_EXT};
|
|
8572
8709
|
$fileType or $fileType = $baseType;
|
|
@@ -8585,7 +8722,8 @@ sub SetFileType($;$$$)
|
|
|
8585
8722
|
$normExt = $fileTypeExt{$fileType};
|
|
8586
8723
|
$normExt = $fileType unless defined $normExt;
|
|
8587
8724
|
}
|
|
8588
|
-
$$self{FileType}
|
|
8725
|
+
# ($$self{FileType} is the file type of the main document)
|
|
8726
|
+
$$self{FileType} = $fileType unless $$self{DOC_NUM};
|
|
8589
8727
|
$self->FoundTag('FileType', $fileType);
|
|
8590
8728
|
$self->FoundTag('FileTypeExtension', uc $normExt);
|
|
8591
8729
|
$self->FoundTag('MIMEType', $mimeType || 'application/unknown');
|
|
@@ -8749,13 +8887,16 @@ sub ProcessBinaryData($$$)
|
|
|
8749
8887
|
{
|
|
8750
8888
|
my ($self, $dirInfo, $tagTablePtr) = @_;
|
|
8751
8889
|
my $dataPt = $$dirInfo{DataPt};
|
|
8752
|
-
my $
|
|
8753
|
-
my $
|
|
8890
|
+
my $dataLen = length $$dataPt;
|
|
8891
|
+
my $dirStart = $$dirInfo{DirStart} || 0;
|
|
8892
|
+
my $maxLen = $dataLen - $dirStart;
|
|
8893
|
+
my $size = $$dirInfo{DirLen};
|
|
8754
8894
|
my $base = $$dirInfo{Base} || 0;
|
|
8755
8895
|
my $verbose = $$self{OPTIONS}{Verbose};
|
|
8756
8896
|
my $unknown = $$self{OPTIONS}{Unknown};
|
|
8757
8897
|
my $dataPos = $$dirInfo{DataPos} || 0;
|
|
8758
8898
|
|
|
8899
|
+
$size = $maxLen if not defined $size or $size > $maxLen;
|
|
8759
8900
|
# get default format ('int8u' unless specified)
|
|
8760
8901
|
my $defaultFormat = $$tagTablePtr{FORMAT} || 'int8u';
|
|
8761
8902
|
my $increment = $formatSize{$defaultFormat};
|
|
@@ -8797,6 +8938,7 @@ sub ProcessBinaryData($$$)
|
|
|
8797
8938
|
$tagInfo = $self->GetTagInfo($tagTablePtr, $index);
|
|
8798
8939
|
unless ($tagInfo) {
|
|
8799
8940
|
next unless defined $tagInfo;
|
|
8941
|
+
# $entry = offset of value relative to directory start (or end if negative)
|
|
8800
8942
|
my $entry = int($index) * $increment + $varSize;
|
|
8801
8943
|
if ($entry < 0) {
|
|
8802
8944
|
$entry += $size;
|
|
@@ -8805,7 +8947,7 @@ sub ProcessBinaryData($$$)
|
|
|
8805
8947
|
next if $entry >= $size;
|
|
8806
8948
|
my $more = $size - $entry;
|
|
8807
8949
|
$more = 128 if $more > 128;
|
|
8808
|
-
my $v = substr($$dataPt, $entry+$
|
|
8950
|
+
my $v = substr($$dataPt, $entry+$dirStart, $more);
|
|
8809
8951
|
$tagInfo = $self->GetTagInfo($tagTablePtr, $index, \$v);
|
|
8810
8952
|
next unless $tagInfo;
|
|
8811
8953
|
}
|
|
@@ -8838,7 +8980,7 @@ sub ProcessBinaryData($$$)
|
|
|
8838
8980
|
$count = $more;
|
|
8839
8981
|
} elsif ($format eq 'pstring') {
|
|
8840
8982
|
$format = 'string';
|
|
8841
|
-
$count = Get8u($dataPt, ($entry++)+$
|
|
8983
|
+
$count = Get8u($dataPt, ($entry++)+$dirStart);
|
|
8842
8984
|
--$more;
|
|
8843
8985
|
} elsif (not $formatSize{$format}) {
|
|
8844
8986
|
if ($format =~ /(.*)\[(.*)\]/) {
|
|
@@ -8867,17 +9009,17 @@ sub ProcessBinaryData($$$)
|
|
|
8867
9009
|
} elsif ($format =~ /^var_/) {
|
|
8868
9010
|
# handle variable-length string formats
|
|
8869
9011
|
$format = substr($format, 4);
|
|
8870
|
-
pos($$dataPt) = $entry + $
|
|
9012
|
+
pos($$dataPt) = $entry + $dirStart;
|
|
8871
9013
|
undef $count;
|
|
8872
9014
|
if ($format eq 'ustring') {
|
|
8873
|
-
$count = pos($$dataPt) - ($entry+$
|
|
9015
|
+
$count = pos($$dataPt) - ($entry+$dirStart) if $$dataPt =~ /\G(..)*?\0\0/sg;
|
|
8874
9016
|
$varSize -= 2; # ($count includes base size of 2 bytes)
|
|
8875
9017
|
} elsif ($format eq 'pstring') {
|
|
8876
|
-
$count = Get8u($dataPt, ($entry++)+$
|
|
9018
|
+
$count = Get8u($dataPt, ($entry++)+$dirStart);
|
|
8877
9019
|
--$more;
|
|
8878
9020
|
} elsif ($format eq 'pstr32' or $format eq 'ustr32') {
|
|
8879
9021
|
last if $more < 4;
|
|
8880
|
-
$count = Get32u($dataPt, $entry + $
|
|
9022
|
+
$count = Get32u($dataPt, $entry + $dirStart);
|
|
8881
9023
|
$count *= 2 if $format eq 'ustr32';
|
|
8882
9024
|
$entry += 4;
|
|
8883
9025
|
$more -= 4;
|
|
@@ -8885,22 +9027,22 @@ sub ProcessBinaryData($$$)
|
|
|
8885
9027
|
} elsif ($format eq 'int16u') {
|
|
8886
9028
|
# int16u size of binary data to follow
|
|
8887
9029
|
last if $more < 2;
|
|
8888
|
-
$count = Get16u($dataPt, $entry + $
|
|
9030
|
+
$count = Get16u($dataPt, $entry + $dirStart) + 2;
|
|
8889
9031
|
$varSize -= 2; # ($count includes size word)
|
|
8890
9032
|
$format = 'undef';
|
|
8891
9033
|
} elsif ($format eq 'ue7') {
|
|
8892
9034
|
require Image::ExifTool::BPG;
|
|
8893
|
-
($val, $count) = Image::ExifTool::BPG::Get_ue7($dataPt, $entry + $
|
|
9035
|
+
($val, $count) = Image::ExifTool::BPG::Get_ue7($dataPt, $entry + $dirStart);
|
|
8894
9036
|
last unless defined $val;
|
|
8895
9037
|
--$varSize; # ($count includes base size of 1 byte)
|
|
8896
9038
|
} elsif ($$dataPt =~ /\0/g) {
|
|
8897
|
-
$count = pos($$dataPt) - ($entry+$
|
|
9039
|
+
$count = pos($$dataPt) - ($entry+$dirStart);
|
|
8898
9040
|
--$varSize; # ($count includes base size of 1 byte)
|
|
8899
9041
|
}
|
|
8900
9042
|
$count = $more if not defined $count or $count > $more;
|
|
8901
9043
|
$varSize += $count; # shift subsequent indices
|
|
8902
9044
|
unless (defined $val) {
|
|
8903
|
-
$val = substr($$dataPt, $entry+$
|
|
9045
|
+
$val = substr($$dataPt, $entry+$dirStart, $count);
|
|
8904
9046
|
$val = $self->Decode($val, 'UCS2') if $format eq 'ustring' or $format eq 'ustr32';
|
|
8905
9047
|
$val =~ s/\0.*//s unless $format eq 'undef'; # truncate at null
|
|
8906
9048
|
}
|
|
@@ -8914,7 +9056,7 @@ sub ProcessBinaryData($$$)
|
|
|
8914
9056
|
# hook to allow format, etc to be set dynamically
|
|
8915
9057
|
if (defined $$tagInfo{Hook}) {
|
|
8916
9058
|
my $oldVarSize = $varSize;
|
|
8917
|
-
my $pos = $entry + $
|
|
9059
|
+
my $pos = $entry + $dirStart;
|
|
8918
9060
|
#### eval Hook ($format, $varSize, $size, $dataPt, $pos)
|
|
8919
9061
|
eval $$tagInfo{Hook};
|
|
8920
9062
|
# save variable size data if required for writing (in case changed by Hook)
|
|
@@ -8939,7 +9081,7 @@ sub ProcessBinaryData($$$)
|
|
|
8939
9081
|
next if $$tagInfo{LargeTag} and $$self{EXCL_TAG_LOOKUP}{lc $$tagInfo{Name}};
|
|
8940
9082
|
# read value now if necessary
|
|
8941
9083
|
unless (defined $val and not $$tagInfo{SubDirectory}) {
|
|
8942
|
-
$val = ReadValue($dataPt, $entry+$
|
|
9084
|
+
$val = ReadValue($dataPt, $entry+$dirStart, $format, $count, $more, \$rational);
|
|
8943
9085
|
next unless defined $val;
|
|
8944
9086
|
$mask = $$tagInfo{Mask};
|
|
8945
9087
|
$val = ($val & $mask) >> $$tagInfo{BitShift} if $mask;
|
|
@@ -8956,8 +9098,8 @@ sub ProcessBinaryData($$$)
|
|
|
8956
9098
|
Value => $val,
|
|
8957
9099
|
DataPt => $dataPt,
|
|
8958
9100
|
Size => $len,
|
|
8959
|
-
Start => $entry+$
|
|
8960
|
-
Addr => $entry+$
|
|
9101
|
+
Start => $entry+$dirStart,
|
|
9102
|
+
Addr => $entry+$dirStart+$base+$dataPos,
|
|
8961
9103
|
Format => $format,
|
|
8962
9104
|
Count => $count,
|
|
8963
9105
|
Extra => $mask ? sprintf(', mask 0x%.2x',$mask) : undef,
|
|
@@ -8983,16 +9125,27 @@ sub ProcessBinaryData($$$)
|
|
|
8983
9125
|
my $subdirBase = $base;
|
|
8984
9126
|
if (defined $$subdir{Base}) {
|
|
8985
9127
|
#### eval Base ($start,$base)
|
|
8986
|
-
my $start = $entry + $
|
|
9128
|
+
my $start = $entry + $dirStart + $dataPos;
|
|
8987
9129
|
$subdirBase = eval($$subdir{Base}) + $base;
|
|
8988
9130
|
}
|
|
8989
9131
|
my $start = $$subdir{Start} || 0;
|
|
9132
|
+
if ($start =~ /\$/) {
|
|
9133
|
+
# ignore directories with a zero offset (ie. missing Nikon ShotInfo entries)
|
|
9134
|
+
next unless $val;
|
|
9135
|
+
#### eval Start ($val, $dirStart)
|
|
9136
|
+
$start = eval($start);
|
|
9137
|
+
next if $start < $dirStart or $start > $dataLen;
|
|
9138
|
+
$len = $$subdir{DirLen};
|
|
9139
|
+
$len = $dataLen - $start unless $len and $len <= $dataLen - $start;
|
|
9140
|
+
} else {
|
|
9141
|
+
$start += $dirStart + $entry;
|
|
9142
|
+
}
|
|
8990
9143
|
my %subdirInfo = (
|
|
8991
9144
|
DataPt => $dataPt,
|
|
8992
9145
|
DataPos => $dataPos,
|
|
8993
|
-
DataLen =>
|
|
8994
|
-
DirStart => $
|
|
8995
|
-
DirLen => $len
|
|
9146
|
+
DataLen => $dataLen,
|
|
9147
|
+
DirStart => $start,
|
|
9148
|
+
DirLen => $len,
|
|
8996
9149
|
Base => $subdirBase,
|
|
8997
9150
|
);
|
|
8998
9151
|
delete $$self{NO_UNKNOWN};
|
|
@@ -1727,10 +1727,11 @@ sensitive, and may be prefixed by one or more family 0, 1, 2 or 7 group
|
|
|
1727
1727
|
names with optional leading family numbers, separated by colons (eg.
|
|
1728
1728
|
'exif:iso'). A leading '-' indicates tags to be excluded (eg. '-comment'),
|
|
1729
1729
|
or a trailing '#' causes the ValueConv value to be copied (same as setting
|
|
1730
|
-
the Type option to 'ValueConv' for this tag only).
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1730
|
+
the Type option to 'ValueConv' for this tag only). A leading '+' sets the
|
|
1731
|
+
Replace option to 0 on a per-tag basis (see Options below). Wildcards ('*'
|
|
1732
|
+
and '?') may be used in the tag name. A tag name of '*' is commonly used
|
|
1733
|
+
when a group is specified to copy all tags in the group (eg. 'XMP:*'). A
|
|
1734
|
+
special feature allows tag names of the form 'DSTTAGE<lt>SRCTAG' (or
|
|
1734
1735
|
'SRCTAGE<gt>DSTTAG') to be specified to copy information to a tag with a
|
|
1735
1736
|
different name or a specified group. Both 'SRCTAG' and 'DSTTAG' may contain
|
|
1736
1737
|
wildcards and/or be prefixed by a group name (eg.
|
|
@@ -1769,7 +1770,9 @@ copies all information while preserving the original family 1 groups, while
|
|
|
1769
1770
|
The options are the same was for L</SetNewValue>, and are passed directly
|
|
1770
1771
|
to L</SetNewValue> internally, with a few exceptions:
|
|
1771
1772
|
|
|
1772
|
-
- The Replace option defaults to 1 instead of 0 as with L</SetNewValue
|
|
1773
|
+
- The Replace option defaults to 1 instead of 0 as with L</SetNewValue>,
|
|
1774
|
+
however the tag name argument may be prefixed with '+' to set the Replace
|
|
1775
|
+
option to 0 for this argument only.
|
|
1773
1776
|
|
|
1774
1777
|
- The AddValue or DelValue option is set for individual tags if '+>' or '->'
|
|
1775
1778
|
(or '+E<lt>' or '-E<lt>') are used.
|
|
@@ -1870,6 +1873,31 @@ None.
|
|
|
1870
1873
|
|
|
1871
1874
|
=back
|
|
1872
1875
|
|
|
1876
|
+
=head2 SetAlternateFile
|
|
1877
|
+
|
|
1878
|
+
Specify alternate file from which to read metadata. Tags from the alternate
|
|
1879
|
+
file are available after L</ExtractInfo> is called or during a call to
|
|
1880
|
+
L</SetNewValuesFromFile> by using a family 8 group name (eg. 'File1' in the
|
|
1881
|
+
example below).
|
|
1882
|
+
|
|
1883
|
+
$exifTool->SetAlternateFile(File1 => 'images/test1.jpg');
|
|
1884
|
+
|
|
1885
|
+
=over 4
|
|
1886
|
+
|
|
1887
|
+
=item Inputs:
|
|
1888
|
+
|
|
1889
|
+
0) ExifTool object reference
|
|
1890
|
+
|
|
1891
|
+
1) Family 8 group name, case insensitive (eg. 'File1', 'File2'...)
|
|
1892
|
+
|
|
1893
|
+
2) Name of alternate input file, or undef to reset
|
|
1894
|
+
|
|
1895
|
+
=item Return Values:
|
|
1896
|
+
|
|
1897
|
+
1 on success, or 0 if the group name is invalid.
|
|
1898
|
+
|
|
1899
|
+
=back
|
|
1900
|
+
|
|
1873
1901
|
=head2 SetFileModifyDate
|
|
1874
1902
|
|
|
1875
1903
|
Write the filesystem modification or creation time from the new value of the
|
|
@@ -2088,6 +2116,7 @@ The group family numbers are currently available:
|
|
|
2088
2116
|
5) Metadata Path (eg. JPEG-APP1-IFD0-ExifIFD)
|
|
2089
2117
|
6) EXIF/TIFF Format (eg. int8u, int32u, undef, string)
|
|
2090
2118
|
7) Tag ID (eg. ID-271, ID-rights, ID-a9aut)
|
|
2119
|
+
8) Alternate File Number (eg. File1, File2, File3...)
|
|
2091
2120
|
|
|
2092
2121
|
Families 0 and 1 are based on the file structure, and are similar except
|
|
2093
2122
|
that family 1 is more specific and sub-divides some groups to give more
|
|
@@ -2140,6 +2169,8 @@ non-numerical ID's may or may not have characters other than [-_A-Za-z0-9]
|
|
|
2140
2169
|
converted to hex. Note that unlike other group names, the tag ID's of
|
|
2141
2170
|
family 7 group names are case sensitive (but the leading "ID-" is not).
|
|
2142
2171
|
|
|
2172
|
+
Family 8 specifies the alternate file set from a call to L</SetAlternateFile>.
|
|
2173
|
+
|
|
2143
2174
|
See L</GetAllGroups [static]> for complete lists of group names.
|
|
2144
2175
|
|
|
2145
2176
|
=back
|
|
@@ -2327,9 +2358,9 @@ CBOR, CIFF, CameraIFD, Canon, CanonCustom, CanonDR4, CanonRaw, CanonVRD,
|
|
|
2327
2358
|
Casio, Chapter#, Composite, DICOM, DJI, DNG, DV, DjVu, DjVu-Meta, Ducky,
|
|
2328
2359
|
EPPIM, EXE, EXIF, ExifIFD, ExifTool, FITS, FLAC, FLIR, File, Flash,
|
|
2329
2360
|
FlashPix, Font, FotoStation, FujiFilm, FujiIFD, GE, GIF, GIMP, GPS,
|
|
2330
|
-
GSpherical, GeoTiff, GlobParamIFD, GoPro, GraphConv, H264, HP, HTC,
|
|
2331
|
-
HTML-dc, HTML-ncc, HTML-office, HTML-prod, HTML-vw96, HTTP-equiv,
|
|
2332
|
-
ICC-clrt, ICC-header, ICC-meas, ICC-meta, ICC-view, ICC_Profile,
|
|
2361
|
+
GSpherical, Garmin, GeoTiff, GlobParamIFD, GoPro, GraphConv, H264, HP, HTC,
|
|
2362
|
+
HTML, HTML-dc, HTML-ncc, HTML-office, HTML-prod, HTML-vw96, HTTP-equiv,
|
|
2363
|
+
ICC-chrm, ICC-clrt, ICC-header, ICC-meas, ICC-meta, ICC-view, ICC_Profile,
|
|
2333
2364
|
ICC_Profile#, ID3, ID3v1, ID3v1_Enh, ID3v2_2, ID3v2_3, ID3v2_4, IFD0, IFD1,
|
|
2334
2365
|
IPTC, IPTC#, ISO, ITC, InfiRay, Insta360, InteropIFD, ItemList, JFIF, JFXX,
|
|
2335
2366
|
JPEG, JPEG-HDR, JPS, JSON, JUMBF, JVC, Jpeg2000, KDC_IFD, Keys, Kodak,
|
|
@@ -2349,7 +2380,7 @@ RMETA, RSRC, RTF, Radiance, Rawzor, Real, Real-CONT, Real-MDPR, Real-PROP,
|
|
|
2349
2380
|
Real-RA3, Real-RA4, Real-RA5, Real-RJMD, Reconyx, Red, Ricoh, SPIFF, SR2,
|
|
2350
2381
|
SR2DataIFD, SR2SubIFD, SRF#, SVG, Samsung, Sanyo, Scalado, Sigma, SigmaRaw,
|
|
2351
2382
|
Sony, SonyIDC, Stim, SubIFD, System, Theora, Torrent, Track#, UserData,
|
|
2352
|
-
VCalendar, VCard,
|
|
2383
|
+
VCalendar, VCard, VNote, Version0, Vorbis, WTV, XML, XMP, XMP-DICOM,
|
|
2353
2384
|
XMP-Device, XMP-GAudio, XMP-GCamera, XMP-GCreations, XMP-GDepth, XMP-GFocus,
|
|
2354
2385
|
XMP-GImage, XMP-GPano, XMP-GSpherical, XMP-LImage, XMP-MP, XMP-MP1,
|
|
2355
2386
|
XMP-PixelLive, XMP-aas, XMP-acdsee, XMP-album, XMP-apple-fi, XMP-ast,
|
|
@@ -2392,6 +2423,10 @@ leading "0x" if the HexTagIDs option is set, or decimal otherwise.
|
|
|
2392
2423
|
Characters in non-numerical ID's which are not valid in a group name are
|
|
2393
2424
|
returned as 2 hex digits.)
|
|
2394
2425
|
|
|
2426
|
+
=item Family 8 (Alternate File):
|
|
2427
|
+
|
|
2428
|
+
File#
|
|
2429
|
+
|
|
2395
2430
|
=back
|
|
2396
2431
|
|
|
2397
2432
|
Note: This function may also be called as an ExifTool member function to
|