exiftool_vendored 13.02.0 → 13.04.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.
@@ -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 $advFmtSelf);
31
31
 
32
- $VERSION = '13.02';
32
+ $VERSION = '13.04';
33
33
  $RELEASE = '';
34
34
  @ISA = qw(Exporter);
35
35
  %EXPORT_TAGS = (
@@ -2583,7 +2583,7 @@ sub Options($$;@)
2583
2583
  warn("Can't set $param to undef\n");
2584
2584
  }
2585
2585
  } elsif (lc $param eq 'geodir') {
2586
- $Image::ExifTool::Geolocation::geoDir = $newVal; # (undocumented)
2586
+ $Image::ExifTool::Geolocation::geoDir = $newVal;
2587
2587
  } else {
2588
2588
  if ($param eq 'Escape') {
2589
2589
  # set ESCAPE_PROC
@@ -4404,6 +4404,7 @@ sub DoneExtract($)
4404
4404
  local $SIG{'__WARN__'} = \&SetWarning;
4405
4405
  undef $evalWarning;
4406
4406
  $$opts{GeolocMulti} = $$opts{Duplicates};
4407
+ $self->VPrint(0, "Geolocation arguments: '${arg}'\n");
4407
4408
  my ($cities, $dist) = Image::ExifTool::Geolocation::Geolocate($arg, $opts);
4408
4409
  delete $$opts{GeolocMulti};
4409
4410
  if ($cities and (@$cities < 2 or $dist or not $self->Warn('Multiple Geolocation cities are possible',2))) {
@@ -4660,74 +4661,56 @@ sub EncodeFileName($$;$)
4660
4661
  # References:
4661
4662
  # - https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats
4662
4663
  # - https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
4664
+ # GetFullPathName supported by Windows XP and later. It handles:
4665
+ # full path names EG: c:\foto\sub\abc.jpg
4666
+ # relative EG: .\abc.jpg, ..\abc.jpg
4667
+ # full UNC paths EG: \\server\share\abc.jpg
4668
+ # relative UNC paths EG: .\abc.jpg, ..\abc.jpg
4669
+ # Dos device paths EG: \\.\c:\fotoabc.jpg
4670
+ # relative path on other drives EG: z:abc.jpg (working dir on z: z:\foto called from c:\foto)
4671
+ # Wide chars EG: Chars that need UTF8.
4672
+ my $k32GetFullPathName;
4663
4673
  sub WindowsLongPath($$)
4664
4674
  {
4665
4675
  my ($self, $path) = @_;
4666
4676
  my $debug = $$self{OPTIONS}{Debug};
4667
4677
  my $out = $$self{OPTIONS}{TextOut};
4668
- my @fullParts;
4669
- my $prefixLen = 0;
4670
4678
 
4671
4679
  $debug and print $out "WindowsLongPath input : $path\n";
4672
- $path =~ tr(/)(\\); # convert slashes to backslashes
4673
- my @pathParts = split /\\/, $path;
4674
4680
 
4675
- if ($path =~ /^\\\\\?\\/ or # already a device path in the format we want
4676
- $path =~ s/^\\\\\.\\/\\\\?\\/) # convert //./ to //?/
4677
- {
4678
- # path is already long-path compatible
4679
- $prefixLen = 3; # path already contains prefix of 3 parts ('', '' and '?')
4680
- } elsif ($path =~ /[*?]/) {
4681
- return $path; # do nothing because we don't support wildcards
4682
- } elsif ($path =~ /^\\\\/) {
4683
- # UNC path starts with two slashes change to "\\?\UNC\"
4684
- splice @pathParts, 2, 0, '?', 'UNC';
4685
- $prefixLen = (@pathParts > 6 ? 6 : @pathParts); # ('', '', '?', 'UNC', <server>, <share>)
4686
- } elsif ($path =~ /^[a-z]:\\/i) {
4687
- # path is already absolute but we need to add the device path prefix
4688
- unshift @pathParts, '', '', '?';
4689
- $prefixLen = 4;
4690
- } elsif ({ eval { require Cwd } }) {
4691
- my $drive;
4692
- $drive = $1 if $pathParts[0] =~ s/^([a-z]:)//;
4693
- my $cwd = Cwd::getdcwd($drive); # ($drive is undef for current working drive)
4694
- $debug and print $out "WindowsLongPath getcwd: $cwd\n";
4695
- @fullParts = split /[\\\/]/, $cwd;
4696
- # UNC path starts with "\\", so first 2 elements are empty
4697
- # --> shift and put UNC in first element.
4698
- if (@fullParts > 1 and $fullParts[0] eq '' and $fullParts[1] eq '') {
4699
- shift @fullParts;
4700
- $fullParts[0] = 'UNC';
4701
- unshift @fullParts, '', '', '?';
4702
- $prefixLen = (@fullParts > 6 ? 6 : @fullParts);
4703
- } else {
4704
- $prefixLen = 1; # drive designator only
4681
+ for (;;) { # (cheap goto)
4682
+ $path =~ tr(/)(\\); # convert slashes to backslashes
4683
+ last if $path =~ /^\\\\\?\\/; # already a device path in the format we want
4684
+
4685
+ unless ($k32GetFullPathName) { # need to import (once) GetFullPathNameW
4686
+ last if defined $k32GetFullPathName;
4687
+ unless (eval { require Win32::API }) {
4688
+ $self->WarnOnce('Install Win32::API to use WindowsLongPath option');
4689
+ last;
4690
+ }
4691
+ $k32GetFullPathName = Win32::API->new('KERNEL32', 'GetFullPathNameW', 'PNPP', 'I');
4692
+ unless ($k32GetFullPathName) {
4693
+ $k32GetFullPathName = 0;
4694
+ $self->Warn('Error loading Win32::API GetFullPathNameW');
4695
+ last;
4696
+ }
4705
4697
  }
4706
- # if absolute path on current drive starts with "\"
4707
- # just keep prefix and drop the rest of the cwd
4708
- $#fullParts = $prefixLen - 1 if $pathParts[0] eq '';
4709
- } else {
4710
- $prefixLen = @pathParts; # (nothing more we can do)
4711
- }
4712
- # remove "." and ".." from path (not handled for device paths)
4713
- my $part;
4714
- foreach $part (@pathParts) {
4715
- if ($part eq '.') {
4716
- next;
4717
- } elsif ($part eq '') {
4718
- # only allow double slashes at start of path name (max 2)
4719
- push @fullParts, $part if not @fullParts or (@fullParts == 1 and $fullParts[0] eq '');
4720
- } elsif ($part eq '..') {
4721
- # step up one directory, but not into the prefix
4722
- pop @fullParts if @fullParts > $prefixLen;
4698
+ my $enc = $$self{OPTIONS}{CharsetFileName};
4699
+ my $encPath = $self->Encode($path, 'UTF16', 'II', $enc); # need to encode to UTF16
4700
+ my $lenReq = $k32GetFullPathName->Call($encPath,0,0,0) + 1; # first pass gets length required, +1 for safety (null?)
4701
+ my $fullPath = "\0" x $lenReq x 2; # create buffer to hold full path
4702
+ $k32GetFullPathName->Call($encPath, $lenReq, $fullPath, 0); # fullPath is UTF16 now
4703
+ $path = $self->Decode($fullPath, 'UTF16', 'II', $enc);
4704
+
4705
+ last if length($path) <= 247;
4706
+
4707
+ if ($path =~ /^\\\\/) {
4708
+ $path = '\\\\?\\UNC' . substr($path, 1);
4723
4709
  } else {
4724
- push @fullParts, $part;
4710
+ $path = '\\\\?\\' . $path;
4725
4711
  }
4712
+ last;
4726
4713
  }
4727
- $path = join '\\', @fullParts;
4728
- # add device path prefix ("\\?\") if path length near the limit (the most
4729
- # conservative limit I can find is 247, which is the limit on the directory name)
4730
- $path = '\\\\?\\' . $path unless $prefixLen > 1 or length($path) <= 247;
4731
4714
  $debug and print $out "WindowsLongPath return: $path\n";
4732
4715
  return $path;
4733
4716
  }
@@ -4861,16 +4844,16 @@ sub CreateDirectory($$)
4861
4844
  my $d2 = $dir; # (must make a copy in case EncodeFileName recodes it)
4862
4845
  if ($self->EncodeFileName($d2)) {
4863
4846
  # handle Windows Unicode directory names
4864
- unless (eval { require Win32::API }) {
4865
- $err = 'Install Win32::API to create directories with Unicode names';
4866
- last;
4867
- }
4868
4847
  unless (defined $k32CreateDir) {
4848
+ unless (eval { require Win32::API }) {
4849
+ $err = 'Install Win32::API to create directories with Unicode names';
4850
+ last;
4851
+ }
4869
4852
  $k32CreateDir = Win32::API->new('KERNEL32', 'CreateDirectoryW', 'PP', 'I');
4870
4853
  unless ($k32CreateDir) {
4871
4854
  $k32CreateDir = 0;
4872
4855
  # give this error once, then just "Error creating" for subsequent attempts
4873
- return 'Error accessing Win32::API::CreateDirectoryW';
4856
+ return 'Error loading Win32::API CreateDirectoryW';
4874
4857
  }
4875
4858
  }
4876
4859
  $success = $k32CreateDir->Call($d2, 0) if $k32CreateDir;
@@ -4928,13 +4911,13 @@ sub GetFileTime($$)
4928
4911
  return () if defined $k32GetFileTime;
4929
4912
  $k32GetFileTime = Win32::API->new('KERNEL32', 'GetFileTime', 'NPPP', 'I');
4930
4913
  unless ($k32GetFileTime) {
4931
- $self->Warn('Error calling Win32::API::GetFileTime');
4914
+ $self->Warn('Error loading Win32::API GetFileTime');
4932
4915
  $k32GetFileTime = 0;
4933
4916
  return ();
4934
4917
  }
4935
4918
  }
4936
4919
  unless ($k32GetFileTime->Call($win32Handle, $ctime, $atime, $mtime)) {
4937
- $self->Warn("Win32::API::GetFileTime returned " . Win32::GetLastError());
4920
+ $self->Warn("Win32::API GetFileTime returned " . Win32::GetLastError());
4938
4921
  return ();
4939
4922
  }
4940
4923
  # convert FILETIME structs to Unix seconds
@@ -5085,7 +5068,7 @@ sub IsSameID($$)
5085
5068
 
5086
5069
  #------------------------------------------------------------------------------
5087
5070
  # Get list of tags in specified group
5088
- # Inputs: 0) ExifTool ref, 1) group spec, 2) tag key or reference to list of tag keys
5071
+ # Inputs: 0) ExifTool ref, 1) group spec (case insensitive), 2) tag key or reference to list of tag keys
5089
5072
  # Returns: list of matching tags in list context, or first match in scalar context
5090
5073
  # Notes: Group spec may contain multiple groups separated by colons, each
5091
5074
  # possibly with a leading family number
@@ -6450,9 +6433,45 @@ sub ConvertDateTime($$)
6450
6433
  my $fmt = $$self{OPTIONS}{DateFormat};
6451
6434
  my $shift = $$self{OPTIONS}{GlobalTimeShift};
6452
6435
  if ($shift) {
6453
- my $dir = ($shift =~ s/^([-+])// and $1 eq '-') ? -1 : 1;
6454
6436
  my $offset = $$self{GLOBAL_TIME_OFFSET};
6455
- $offset or $offset = $$self{GLOBAL_TIME_OFFSET} = { };
6437
+ my ($g, $t, $dir, @matches);
6438
+ if ($shift =~ s/^((\d?[A-Z][-\w]*\w:)*)([A-Z][-\w]*\w)([-+])//i) {
6439
+ ($g, $t, $dir) = ($1, $3, ($4 eq '-' ? -1 : 1));
6440
+ } else {
6441
+ $dir = ($shift =~ s/^([-+])// and $1 eq '-') ? -1 : 1;
6442
+ }
6443
+ unless ($offset) {
6444
+ $offset = $$self{GLOBAL_TIME_OFFSET} = { };
6445
+ # (see forum16692 for a discussion about why this code was added)
6446
+ if ($t) {
6447
+ # determine initial shift from specified tag
6448
+ @matches = sort grep(/^$t( \(|$)/i, keys %{$$self{VALUE}});
6449
+ if ($g and @matches) {
6450
+ $g =~ s/:$//;
6451
+ @matches = $self->GroupMatches($g, \@matches);
6452
+ }
6453
+ }
6454
+ if (not @matches and $$self{TAGS_FROM_FILE} and $$self{OPTIONS}{RequestTags}) {
6455
+ # determine initial shift from first requested date/time tag
6456
+ my @reqDate = grep /date/i, @{$$self{OPTIONS}{RequestTags}};
6457
+ while (@reqDate) {
6458
+ $t = shift @reqDate;
6459
+ @matches = sort grep(/^$t( \(|$)/i, keys %{$$self{VALUE}});
6460
+ my $ti = $$self{TAG_INFO};
6461
+ for (; @matches; shift @matches) {
6462
+ # select the first tag that calls this routine in its PrintConv
6463
+ next unless $$ti{$matches[0]}{PrintConv};
6464
+ next unless $$ti{$matches[0]}{PrintConv} =~ /ConvertDateTime/;
6465
+ undef @reqDate;
6466
+ last;
6467
+ }
6468
+ }
6469
+ }
6470
+ if (@matches) {
6471
+ my $val = $self->GetValue($matches[0], 'ValueConv');
6472
+ ShiftTime($val, $shift, $dir, $offset) if defined $val;
6473
+ }
6474
+ }
6456
6475
  ShiftTime($date, $shift, $dir, $offset);
6457
6476
  }
6458
6477
  # only convert date if a format was specified and the date is recognizable
@@ -7952,6 +7971,10 @@ sub ProcessJPEG($$;$)
7952
7971
  SetByteOrder('II');
7953
7972
  my $tagTablePtr = GetTagTable('Image::ExifTool::InfiRay::Isothermal');
7954
7973
  $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
7974
+ } elsif ($$segDataPt =~ /^SEAL\0/) {
7975
+ $dumpType = 'SEAL';
7976
+ DirStart(\%dirInfo, 5);
7977
+ $self->ProcessDirectory(\%dirInfo, GetTagTable("Image::ExifTool::XMP::SEAL"));
7955
7978
  }
7956
7979
  } elsif ($marker == 0xe9) { # APP9 (InfiRay, Media Jukebox)
7957
7980
  if ($$segDataPt =~ /^Media Jukebox\0/ and $length > 22) {
@@ -7967,6 +7990,10 @@ sub ProcessJPEG($$;$)
7967
7990
  SetByteOrder('II');
7968
7991
  my $tagTablePtr = GetTagTable('Image::ExifTool::InfiRay::Sensor');
7969
7992
  $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
7993
+ } elsif ($$segDataPt =~ /^SEAL\0/) {
7994
+ $dumpType = 'SEAL';
7995
+ DirStart(\%dirInfo, 5);
7996
+ $self->ProcessDirectory(\%dirInfo, GetTagTable("Image::ExifTool::XMP::SEAL"));
7970
7997
  }
7971
7998
  } elsif ($marker == 0xea) { # APP10 (PhotoStudio Unicode comments)
7972
7999
  if ($$segDataPt =~ /^UNICODE\0/) {
@@ -8889,6 +8916,7 @@ sub GetTagInfo($$$;$$$)
8889
8916
  my ($valPt, $format, $count);
8890
8917
 
8891
8918
  my @infoArray = GetTagInfoList($tagTablePtr, $tagID);
8919
+ my $options = $$self{OPTIONS};
8892
8920
  # evaluate condition
8893
8921
  my $tagInfo;
8894
8922
  foreach $tagInfo (@infoArray) {
@@ -8907,9 +8935,9 @@ sub GetTagInfo($$$;$$$)
8907
8935
  }
8908
8936
  }
8909
8937
  # don't return Unknown tags unless that option is set (also see forum13716)
8910
- if ($$tagInfo{Unknown} and not $$self{OPTIONS}{Unknown} and not
8911
- ($$self{OPTIONS}{Verbose} or $$self{HTML_DUMP} or
8912
- ($$self{OPTIONS}{Validate} and not $$tagInfo{AddedUnknown})))
8938
+ if ($$tagInfo{Unknown} and not $$options{Unknown} and not
8939
+ ($$options{Verbose} or $$self{HTML_DUMP} or
8940
+ ($$options{Validate} and not $$tagInfo{AddedUnknown})))
8913
8941
  {
8914
8942
  return undef;
8915
8943
  }
@@ -8917,7 +8945,7 @@ sub GetTagInfo($$$;$$$)
8917
8945
  return $tagInfo;
8918
8946
  }
8919
8947
  # generate information for unknown tags (numerical only) if required
8920
- if (not $tagInfo and ($$self{OPTIONS}{Unknown} or $$self{OPTIONS}{Verbose}) and
8948
+ if (not $tagInfo and ($$options{Unknown} or $$options{Verbose} or $$self{HTML_DUMP}) and
8921
8949
  $tagID =~ /^\d+$/ and not $$self{NO_UNKNOWN})
8922
8950
  {
8923
8951
  my $printConv;
@@ -9102,6 +9130,7 @@ sub HandleTag($$$$;%)
9102
9130
  Base => $parms{Base},
9103
9131
  Multi => $$subdir{Multi},
9104
9132
  TagInfo => $tagInfo,
9133
+ IgnoreProp => $$subdir{IgnoreProp},
9105
9134
  RAF => $parms{RAF},
9106
9135
  );
9107
9136
  my $oldOrder = GetByteOrder();
@@ -809,8 +809,21 @@ Reference units for writing GPSSpeed when geotagging:
809
809
 
810
810
  Time shift to apply to all extracted date/time PrintConv values. Does not
811
811
  affect ValueConv values. Value is a date/time shift string (see
812
- L<Image::ExifTool::Shift(3pm)|Image::ExifTool::Shift.pl>), with a leading
813
- '-' for negative shifts. Default is undef.
812
+ L<Image::ExifTool::Shift(3pm)|Image::ExifTool::Shift.pl>) with a leading
813
+ '-' for negative shifts, or a tag name with option group prefix followed
814
+ by '+' or '-' then the shift string. Default is undef.
815
+
816
+ Note: When specifying a number of months and/or years to shift, the tag for
817
+ the starting date should be specified so the number of days can be
818
+ determined unambiguously. For example:
819
+
820
+ 'createdate-1:0:0 0:0:0' - shift back by the length of the
821
+ year before the CreateDate value
822
+ 'xmp:createdate+0:2:0 0' - shift forward by the length of
823
+ the 2 months after XMP:CreateDate
824
+
825
+ If the starting tag is not specified, or the specified tag isn't available,
826
+ then the shift is calculated based on the first shifted tag.
814
827
 
815
828
  =item Group#
816
829
 
@@ -2563,7 +2576,7 @@ Pentax, PhaseOne, PhotoCD, PhotoMechanic, Photoshop, PictureInfo,
2563
2576
  PostScript, PreviewIFD, PrintIM, ProfileIFD, Qualcomm, QuickTime, RAF, RAF2,
2564
2577
  RIFF, RMETA, RSRC, RTF, Radiance, Rawzor, Real, Real-CONT, Real-MDPR,
2565
2578
  Real-PROP, Real-RA3, Real-RA4, Real-RA5, Real-RJMD, Reconyx, Red, Ricoh,
2566
- SPIFF, SR2, SR2DataIFD, SR2SubIFD, SRF#, SVG, Samsung, Sanyo, Scalado,
2579
+ SEAL, SPIFF, SR2, SR2DataIFD, SR2SubIFD, SRF#, SVG, Samsung, Sanyo, Scalado,
2567
2580
  Sigma, SigmaRaw, Sony, SonyIDC, Stim, SubIFD, System, Theora, Torrent,
2568
2581
  Track#, UserData, VCalendar, VCard, VNote, Version0, Vorbis, WTV, XML, XMP,
2569
2582
  XMP-DICOM, XMP-Device, XMP-GAudio, XMP-GCamera, XMP-GContainer,
@@ -1,6 +1,6 @@
1
1
  Summary: perl module for image data extraction
2
2
  Name: perl-Image-ExifTool
3
- Version: 13.02
3
+ Version: 13.04
4
4
  Release: 1
5
5
  License: Artistic/GPL
6
6
  Group: Development/Libraries/Perl
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ExiftoolVendored
4
- VERSION = Gem::Version.new('13.02.0')
4
+ VERSION = Gem::Version.new('13.04.0')
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exiftool_vendored
3
3
  version: !ruby/object:Gem::Version
4
- version: 13.02.0
4
+ version: 13.04.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew McEachen
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-11-11 00:00:00.000000000 Z
12
+ date: 2024-11-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: exiftool