exiftool_vendored 12.15.0 → 12.22.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +96 -2
  3. data/bin/MANIFEST +1 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +2 -2
  7. data/bin/config_files/example.config +1 -8
  8. data/bin/exiftool +104 -59
  9. data/bin/fmt_files/gpx.fmt +1 -1
  10. data/bin/fmt_files/gpx_wpt.fmt +1 -1
  11. data/bin/fmt_files/kml.fmt +1 -1
  12. data/bin/fmt_files/kml_track.fmt +1 -1
  13. data/bin/lib/Image/ExifTool.pm +74 -24
  14. data/bin/lib/Image/ExifTool.pod +34 -24
  15. data/bin/lib/Image/ExifTool/Apple.pm +3 -2
  16. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +24 -13
  17. data/bin/lib/Image/ExifTool/Canon.pm +26 -2
  18. data/bin/lib/Image/ExifTool/CanonCustom.pm +19 -1
  19. data/bin/lib/Image/ExifTool/DJI.pm +6 -6
  20. data/bin/lib/Image/ExifTool/DPX.pm +3 -3
  21. data/bin/lib/Image/ExifTool/Exif.pm +35 -16
  22. data/bin/lib/Image/ExifTool/FITS.pm +13 -2
  23. data/bin/lib/Image/ExifTool/FujiFilm.pm +2 -1
  24. data/bin/lib/Image/ExifTool/GPS.pm +24 -13
  25. data/bin/lib/Image/ExifTool/H264.pm +20 -5
  26. data/bin/lib/Image/ExifTool/ICC_Profile.pm +2 -2
  27. data/bin/lib/Image/ExifTool/M2TS.pm +40 -4
  28. data/bin/lib/Image/ExifTool/MIE.pm +2 -2
  29. data/bin/lib/Image/ExifTool/Microsoft.pm +296 -82
  30. data/bin/lib/Image/ExifTool/Nikon.pm +5 -5
  31. data/bin/lib/Image/ExifTool/NikonSettings.pm +16 -16
  32. data/bin/lib/Image/ExifTool/Olympus.pm +2 -2
  33. data/bin/lib/Image/ExifTool/QuickTime.pm +58 -30
  34. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +27 -8
  35. data/bin/lib/Image/ExifTool/README +5 -4
  36. data/bin/lib/Image/ExifTool/RIFF.pm +2 -2
  37. data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -0
  38. data/bin/lib/Image/ExifTool/Sony.pm +63 -29
  39. data/bin/lib/Image/ExifTool/TagInfoXML.pm +1 -0
  40. data/bin/lib/Image/ExifTool/TagLookup.pm +4032 -3981
  41. data/bin/lib/Image/ExifTool/TagNames.pod +261 -104
  42. data/bin/lib/Image/ExifTool/WriteExif.pl +1 -1
  43. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +7 -5
  44. data/bin/lib/Image/ExifTool/WriteXMP.pl +9 -6
  45. data/bin/lib/Image/ExifTool/Writer.pl +49 -14
  46. data/bin/lib/Image/ExifTool/XMP.pm +31 -5
  47. data/bin/perl-Image-ExifTool.spec +1 -1
  48. data/lib/exiftool_vendored/version.rb +1 -1
  49. metadata +48 -6
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
88
88
  sub ProcessExifInfo($$$);
89
89
  sub SwapWords($);
90
90
 
91
- $VERSION = '4.42';
91
+ $VERSION = '4.46';
92
92
 
93
93
  # Note: Removed 'USM' from 'L' lenses since it is redundant - PH
94
94
  # (or is it? Ref 32 shows 5 non-USM L-type lenses)
@@ -589,6 +589,8 @@ $VERSION = '4.42';
589
589
  61182.18 => 'Canon RF 100-500mm F4.5-7.1L IS USM',
590
590
  61182.19 => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF1.4x',
591
591
  61182.20 => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF2x',
592
+ 61182.21 => 'Canon RF 70-200mm F4L IS USM', #42
593
+ 61182.22 => 'Canon RF 50mm F1.8 STM', #42
592
594
  65535 => 'n/a',
593
595
  );
594
596
 
@@ -945,6 +947,7 @@ $VERSION = '4.42';
945
947
  0x80000437 => 'EOS 90D', #IB
946
948
  0x80000453 => 'EOS R6', #PH
947
949
  0x80000467 => 'PowerShot ZOOM',
950
+ 0x80000468 => 'EOS M50 Mark II / Kiss M2', #IB
948
951
  0x80000520 => 'EOS D2000C', #IB
949
952
  0x80000560 => 'EOS D6000C', #PH (guess)
950
953
  );
@@ -2128,6 +2131,7 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
2128
2131
  16 => 'Pan Focus', #PH
2129
2132
  # 137 - Single?
2130
2133
  256 => 'AF + MF', #PH (NC, EOS M)
2134
+ 257 => 'Live View', #forum12082
2131
2135
  512 => 'Movie Snap Focus', #48
2132
2136
  519 => 'Movie Servo AF', #PH (NC, EOS M)
2133
2137
  },
@@ -4538,6 +4542,16 @@ my %ciMaxFocal = (
4538
4542
  2 => 'Rotate 270 CW',
4539
4543
  },
4540
4544
  },
4545
+ 0x3a => { #IB
4546
+ Name => 'CameraOrientation',
4547
+ Condition => '$$self{Model} =~ /\b(1200D|REBEL T5|Kiss X70)\b/',
4548
+ Notes => '1200D only',
4549
+ PrintConv => {
4550
+ 0 => 'Horizontal (normal)',
4551
+ 1 => 'Rotate 90 CW',
4552
+ 2 => 'Rotate 270 CW',
4553
+ },
4554
+ },
4541
4555
  0x55 => {
4542
4556
  Name => 'FocusDistanceUpper',
4543
4557
  Condition => '$$self{Model} =~ /EOS 60D$/',
@@ -4678,7 +4692,7 @@ my %ciMaxFocal = (
4678
4692
  FIRST_ENTRY => 0,
4679
4693
  PRIORITY => 0,
4680
4694
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
4681
- NOTES => 'CameraInfo tags for the EOS 70D.',
4695
+ NOTES => 'CameraInfo tags for the EOS 80D.',
4682
4696
  0x03 => { %ciFNumber },
4683
4697
  0x04 => { %ciExposureTime },
4684
4698
  0x06 => { %ciISO },
@@ -5254,6 +5268,14 @@ my %ciMaxFocal = (
5254
5268
  0x06 => { %ciISO },
5255
5269
  0x1b => { %ciCameraTemperature }, # (700D + 0)
5256
5270
  0x23 => { %ciFocalLength }, # (700D + 0)
5271
+ 0x96 => { #IB (700D + 0x19)
5272
+ Name => 'CameraOrientation',
5273
+ PrintConv => {
5274
+ 0 => 'Horizontal (normal)',
5275
+ 1 => 'Rotate 90 CW',
5276
+ 2 => 'Rotate 270 CW',
5277
+ },
5278
+ },
5257
5279
  0xa5 => { # (700D + 0x19)
5258
5280
  Name => 'FocusDistanceUpper',
5259
5281
  %focusDistanceByteSwap,
@@ -6735,6 +6757,8 @@ my %ciMaxFocal = (
6735
6757
  275 => 'Canon RF 100-500mm F4.5-7.1L IS USM',
6736
6758
  276 => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF1.4x',
6737
6759
  277 => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF2x',
6760
+ 278 => 'Canon RF 70-200mm F4L IS USM', #42
6761
+ 280 => 'Canon RF 50mm F1.8 STM', #42
6738
6762
  # Note: add new RF lenses to %canonLensTypes with ID 61182
6739
6763
  },
6740
6764
  },
@@ -19,7 +19,7 @@ use Image::ExifTool qw(:DataAccess);
19
19
  use Image::ExifTool::Canon;
20
20
  use Image::ExifTool::Exif;
21
21
 
22
- $VERSION = '1.57';
22
+ $VERSION = '1.58';
23
23
 
24
24
  sub ProcessCanonCustom($$$);
25
25
  sub ProcessCanonCustom2($$$);
@@ -2098,6 +2098,24 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv );
2098
2098
  '$val=~/(\d+)/ ? $1 : 0',
2099
2099
  '$val=~/(\d+)/ ? $1 : 0',
2100
2100
  ],
2101
+ },{ # (1DXmkIII firmware 1.3)
2102
+ Name => 'ContinuousShootingSpeed',
2103
+ Condition => '$count == 5',
2104
+ Count => 5,
2105
+ PrintConv => [
2106
+ '"Hi $val"',
2107
+ '"Cont $val"',
2108
+ '"Lo $val"',
2109
+ '"Soft $val"',
2110
+ '"Soft LS $val"',
2111
+ ],
2112
+ PrintConvInv => [
2113
+ '$val=~/(\d+)/ ? $1 : 0',
2114
+ '$val=~/(\d+)/ ? $1 : 0',
2115
+ '$val=~/(\d+)/ ? $1 : 0',
2116
+ '$val=~/(\d+)/ ? $1 : 0',
2117
+ '$val=~/(\d+)/ ? $1 : 0',
2118
+ ],
2101
2119
  },{ # others
2102
2120
  Name => 'ContinuousShootingSpeed',
2103
2121
  Count => 3,
@@ -15,7 +15,7 @@ use Image::ExifTool::Exif;
15
15
  use Image::ExifTool::XMP;
16
16
  use Image::ExifTool::GPS;
17
17
 
18
- $VERSION = '1.03';
18
+ $VERSION = '1.04';
19
19
 
20
20
  my %convFloat2 = (
21
21
  PrintConv => 'sprintf("%+.2f", $val)',
@@ -90,20 +90,20 @@ my %convFloat2 = (
90
90
  Writable => 'real',
91
91
  Avoid => 1,
92
92
  PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
93
- PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
93
+ PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1, "lat")',
94
94
  },
95
95
  GpsLongtitude => { # (sic)
96
96
  Name => 'GPSLongtitude',
97
97
  Writable => 'real',
98
98
  PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
99
- PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
99
+ PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1, "lon")',
100
100
  },
101
101
  GpsLongitude => { #PH (NC)
102
102
  Name => 'GPSLongitude',
103
103
  Writable => 'real',
104
104
  Avoid => 1,
105
105
  PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
106
- PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
106
+ PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1, "lon")',
107
107
  },
108
108
  FlightXSpeed => { Writable => 'real' },
109
109
  FlightYSpeed => { Writable => 'real' },
@@ -124,13 +124,13 @@ my %convFloat2 = (
124
124
  Name => 'Latitude',
125
125
  Writable => 'real',
126
126
  PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
127
- PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
127
+ PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1, "lat")',
128
128
  },
129
129
  Longitude => {
130
130
  Name => 'Longitude',
131
131
  Writable => 'real',
132
132
  PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
133
- PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
133
+ PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1, "lon")',
134
134
  },
135
135
  );
136
136
 
@@ -15,7 +15,7 @@ use strict;
15
15
  use vars qw($VERSION);
16
16
  use Image::ExifTool qw(:DataAccess :Utils);
17
17
 
18
- $VERSION = '1.04';
18
+ $VERSION = '1.05';
19
19
 
20
20
  # DPX tags
21
21
  %Image::ExifTool::DPX::Main = (
@@ -158,11 +158,11 @@ $VERSION = '1.04';
158
158
  1588=> { Name => 'InputDeviceSerialNumber', Format => 'string[32]' },
159
159
  # 1620=> { Name => 'AspectRatio', Format => 'int32u' },
160
160
  1724 => { Name => 'OriginalFrameRate',Format => 'float' },
161
- 1728 => { Name => 'ShutterAngle', Format => 'float', RawConv => '$val =~ /\d/ ? $val : undef' }, #2
161
+ 1728 => { Name => 'ShutterAngle', Format => 'float', RawConv => '($val =~ /\d/ and $val !~ /nan/i) ? $val : undef' }, #2
162
162
  1732 => { Name => 'FrameID', Format => 'string[32]' },
163
163
  1764 => { Name => 'SlateInformation', Format => 'string[100]' },
164
164
  1920 => { Name => 'TimeCode', Format => 'int32u' }, #2
165
- 1940 => { Name => 'FrameRate', Format => 'float', RawConv => '$val =~ /\d/ ? $val : undef' }, #2
165
+ 1940 => { Name => 'FrameRate', Format => 'float', RawConv => '($val =~ /\d/ and $val !~ /nan/i) ? $val : undef' }, #2
166
166
  1972 => { Name => 'Reserved5', Format => 'string[76]', Unknown => 1 },
167
167
  2048 => { Name => 'UserID', Format => 'string[32]' },
168
168
  );
@@ -56,7 +56,7 @@ use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat
56
56
  use Image::ExifTool qw(:DataAccess :Utils);
57
57
  use Image::ExifTool::MakerNotes;
58
58
 
59
- $VERSION = '4.31';
59
+ $VERSION = '4.33';
60
60
 
61
61
  sub ProcessExif($$$);
62
62
  sub WriteExif($$$);
@@ -1452,6 +1452,7 @@ my %opcodeInfo = (
1452
1452
  1 => 'Sony Uncompressed 12-bit RAW', #IB
1453
1453
  2 => 'Sony Compressed RAW', # (lossy, ref IB)
1454
1454
  3 => 'Sony Lossless Compressed RAW', #IB
1455
+ 4 => 'Sony Lossless Compressed RAW 2', #JR (ILCE-1)
1455
1456
  },
1456
1457
  },
1457
1458
  # 0x7001 - int16u[1] (in SubIFD of Sony ARW images) - values: 0,1
@@ -1472,6 +1473,7 @@ my %opcodeInfo = (
1472
1473
  PrintConv => {
1473
1474
  256 => 'Off',
1474
1475
  257 => 'Auto',
1476
+ 272 => 'Auto (ILCE-1)', #JR
1475
1477
  511 => 'No correction params available',
1476
1478
  },
1477
1479
  },
@@ -2560,6 +2562,7 @@ my %opcodeInfo = (
2560
2562
  5 => 'Color sequential area',
2561
2563
  7 => 'Trilinear',
2562
2564
  8 => 'Color sequential linear',
2565
+ # 15 - used by DJI XT2
2563
2566
  },
2564
2567
  },
2565
2568
  0xa300 => {
@@ -4728,8 +4731,8 @@ my %subSecConv = (
4728
4731
  },
4729
4732
  LensID => {
4730
4733
  Groups => { 2 => 'Camera' },
4734
+ Require => 'LensType',
4731
4735
  Desire => {
4732
- 0 => 'LensType',
4733
4736
  1 => 'FocalLength',
4734
4737
  2 => 'MaxAperture',
4735
4738
  3 => 'MaxApertureValue',
@@ -4748,25 +4751,16 @@ my %subSecConv = (
4748
4751
  Applies only to LensType values with a lookup table. May be configured
4749
4752
  by adding user-defined lenses
4750
4753
  },
4751
- # this LensID is only valid if the LensType has a PrintConv,
4752
- # or LensType or LensModel are the model name
4754
+ # this LensID is only valid if the LensType has a PrintConv or is a model name
4753
4755
  RawConv => q{
4754
4756
  my $printConv = $$self{TAG_INFO}{LensType}{PrintConv};
4755
- return $val if ref $printConv eq 'HASH' or
4756
- (ref $printConv eq 'ARRAY' and ref $$printConv[0] eq 'HASH') or
4757
- (defined $val[0] and $val[0] =~ /(mm|\d\/F)/) or
4758
- (defined $val[6] and $val[6] =~ /(mm|\d\/F)/);
4757
+ return $val if ref $printConv eq 'HASH' or (ref $printConv eq 'ARRAY' and
4758
+ ref $$printConv[0] eq 'HASH') or $val[0] =~ /(mm|\d\/F)/;
4759
4759
  return undef;
4760
4760
  },
4761
- ValueConv => '$val[0] || $val[6]',
4761
+ ValueConv => '$val',
4762
4762
  PrintConv => q{
4763
4763
  my $pcv;
4764
- # use LensModel ([6]) if LensType ([0]) is not populated
4765
- # (iPhone populates LensModel but not LensType)
4766
- if (not defined $val[0] and defined $val[6]) {
4767
- $val[0] = $val[6];
4768
- $prt[0] = $prt[6];
4769
- }
4770
4764
  # use LensType2 instead of LensType if available and valid (Sony E-mount lenses)
4771
4765
  # (0x8000 or greater; 0 for several older/3rd-party E-mount lenses)
4772
4766
  if (defined $val[9] and ($val[9] & 0x8000 or $val[9] == 0)) {
@@ -4794,6 +4788,30 @@ my %subSecConv = (
4794
4788
  return $lens;
4795
4789
  },
4796
4790
  },
4791
+ 'LensID-2' => {
4792
+ Name => 'LensID',
4793
+ Groups => { 2 => 'Camera' },
4794
+ Desire => {
4795
+ 0 => 'LensModel',
4796
+ 1 => 'Lens',
4797
+ 2 => 'XMP-aux:LensID',
4798
+ 3 => 'Make',
4799
+ },
4800
+ Inhibit => {
4801
+ 4 => 'Composite:LensID',
4802
+ },
4803
+ RawConv => q{
4804
+ return undef if defined $val[2] and defined $val[3];
4805
+ return $val if defined $val[0] and $val[0] =~ /(mm|\d\/F)/;
4806
+ return $val if defined $val[1] and $val[1] =~ /(mm|\d\/F)/;
4807
+ return undef;
4808
+ },
4809
+ ValueConv => q{
4810
+ return $val[0] if defined $val[0] and $val[0] =~ /(mm|\d\/F)/;
4811
+ return $val[1];
4812
+ },
4813
+ PrintConv => '$_=$val; s/(\d)\/F/$1mm F/; s/mmF/mm F/; s/(\d) mm/${1}mm/; s/ - /-/; $_',
4814
+ },
4797
4815
  );
4798
4816
 
4799
4817
  # table for unknown IFD entries
@@ -5780,7 +5798,8 @@ sub ProcessExif($$$)
5780
5798
  $numEntries = Get16u($dataPt, $dirStart);
5781
5799
  } else {
5782
5800
  $et->Warn("Bad $dir directory", $inMakerNotes);
5783
- return 0 unless $inMakerNotes and $dirLen >= 14;
5801
+ return 0 unless $inMakerNotes and $dirLen >= 14 and $dirStart >= 0 and
5802
+ $dirStart + $dirLen <= length($$dataPt);
5784
5803
  $dirSize = $dirLen;
5785
5804
  $numEntries = int(($dirSize - 2) / 12); # read what we can
5786
5805
  Set16u($numEntries, $dataPt, $dirStart);
@@ -14,7 +14,7 @@ use strict;
14
14
  use vars qw($VERSION);
15
15
  use Image::ExifTool qw(:DataAccess :Utils);
16
16
 
17
- $VERSION = '1.00';
17
+ $VERSION = '1.02';
18
18
 
19
19
  # FITS tags (ref 1)
20
20
  %Image::ExifTool::FITS::Main = (
@@ -36,6 +36,10 @@ $VERSION = '1.00';
36
36
  'TIME-OBS'=> { Name => 'ObservationTime', Groups => { 2 => 'Time' } },
37
37
  'DATE-END'=> { Name => 'ObservationDateEnd', Groups => { 2 => 'Time' } },
38
38
  'TIME-END'=> { Name => 'ObservationTimeEnd', Groups => { 2 => 'Time' } },
39
+ COMMENT => { Name => 'Comment', PrintConv => '$val =~ s/^ +//; $val',
40
+ Notes => 'leading spaces are removed if L<PrintConv|../ExifTool.html#PrintConv> is enabled' },
41
+ HISTORY => { Name => 'History', PrintConv => '$val =~ s/^ +//; $val',
42
+ Notes => 'leading spaces are removed if L<PrintConv|../ExifTool.html#PrintConv> is enabled' },
39
43
  );
40
44
 
41
45
  #------------------------------------------------------------------------------
@@ -67,7 +71,14 @@ sub ProcessFITS($$)
67
71
  last if $key eq 'END';
68
72
  # make sure the key is valid
69
73
  $key =~ /^[-_A-Z0-9]*$/ or $et->Warn('Format error in FITS header'), last;
70
- next unless substr($buff,8,2) eq '= '; # ignore comment lines
74
+ if ($key eq 'COMMENT' or $key eq 'HISTORY') {
75
+ my $val = substr($buff, 8); # comments start in column 9
76
+ $val =~ s/ +$//; # remove trailing spaces
77
+ $et->HandleTag($tagTablePtr, $key, $val);
78
+ next;
79
+ }
80
+ # ignore other lines that aren't tags
81
+ next unless substr($buff,8,2) eq '= ';
71
82
  # save tag name (avoiding potential conflict with ExifTool variables)
72
83
  $tag = $Image::ExifTool::specialTags{$key} ? "_$key" : $key;
73
84
  # add to tag table if necessary
@@ -31,7 +31,7 @@ use vars qw($VERSION);
31
31
  use Image::ExifTool qw(:DataAccess :Utils);
32
32
  use Image::ExifTool::Exif;
33
33
 
34
- $VERSION = '1.78';
34
+ $VERSION = '1.79';
35
35
 
36
36
  sub ProcessFujiDir($$$);
37
37
  sub ProcessFaceRec($$$);
@@ -623,6 +623,7 @@ my %faceCategories = (
623
623
  0x700 => 'Eterna', #12
624
624
  0x800 => 'Classic Negative', #forum10536
625
625
  0x900 => 'Bleach Bypass', #forum10890
626
+ 0xa00 => 'Nostalgic Neg', #forum12085
626
627
  },
627
628
  },
628
629
  0x1402 => { #2
@@ -12,13 +12,12 @@ use strict;
12
12
  use vars qw($VERSION);
13
13
  use Image::ExifTool::Exif;
14
14
 
15
- $VERSION = '1.51';
15
+ $VERSION = '1.53';
16
16
 
17
17
  my %coordConv = (
18
18
  ValueConv => 'Image::ExifTool::GPS::ToDegrees($val)',
19
19
  ValueConvInv => 'Image::ExifTool::GPS::ToDMS($self, $val)',
20
20
  PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
21
- PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val)',
22
21
  );
23
22
 
24
23
  %Image::ExifTool::GPS::Main = (
@@ -41,7 +40,7 @@ my %coordConv = (
41
40
  Notes => q{
42
41
  tags 0x0001-0x0006 used for camera location according to MWG 2.0. ExifTool
43
42
  will also accept a number when writing GPSLatitudeRef, positive for north
44
- latitudes or negative for south, or a string ending in N or S
43
+ latitudes or negative for south, or a string containing N, North, S or South
45
44
  },
46
45
  Count => 2,
47
46
  PrintConv => {
@@ -50,8 +49,8 @@ my %coordConv = (
50
49
  OTHER => sub {
51
50
  my ($val, $inv) = @_;
52
51
  return undef unless $inv;
53
- return uc $1 if $val =~ /\b([NS])$/i;
54
- return $1 eq '-' ? 'S' : 'N' if $val =~ /^([-+]?)\d+(\.\d*)?$/;
52
+ return uc $2 if $val =~ /(^|[^A-Z])([NS])(orth|outh)?\b/i;
53
+ return $1 eq '-' ? 'S' : 'N' if $val =~ /([-+]?)\d+/;
55
54
  return undef;
56
55
  },
57
56
  N => 'North',
@@ -63,6 +62,7 @@ my %coordConv = (
63
62
  Writable => 'rational64u',
64
63
  Count => 3,
65
64
  %coordConv,
65
+ PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val,undef,"lat")',
66
66
  },
67
67
  0x0003 => {
68
68
  Name => 'GPSLongitudeRef',
@@ -70,7 +70,7 @@ my %coordConv = (
70
70
  Count => 2,
71
71
  Notes => q{
72
72
  ExifTool will also accept a number when writing this tag, positive for east
73
- longitudes or negative for west, or a string ending in E or W
73
+ longitudes or negative for west, or a string containing E, East, W or West
74
74
  },
75
75
  PrintConv => {
76
76
  # extract E/W if written from Composite:GPSLongitude
@@ -78,8 +78,8 @@ my %coordConv = (
78
78
  OTHER => sub {
79
79
  my ($val, $inv) = @_;
80
80
  return undef unless $inv;
81
- return uc $1 if $val =~ /\b([EW])$/i;
82
- return $1 eq '-' ? 'W' : 'E' if $val =~ /^([-+]?)\d+(\.\d*)?$/;
81
+ return uc $2 if $val =~ /(^|[^A-Z])([EW])(ast|est)?\b/i;
82
+ return $1 eq '-' ? 'W' : 'E' if $val =~ /([-+]?)\d+/;
83
83
  return undef;
84
84
  },
85
85
  E => 'East',
@@ -91,6 +91,7 @@ my %coordConv = (
91
91
  Writable => 'rational64u',
92
92
  Count => 3,
93
93
  %coordConv,
94
+ PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val,undef,"lon")',
94
95
  },
95
96
  0x0005 => {
96
97
  Name => 'GPSAltitudeRef',
@@ -238,6 +239,7 @@ my %coordConv = (
238
239
  Writable => 'rational64u',
239
240
  Count => 3,
240
241
  %coordConv,
242
+ PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val,undef,"lat")',
241
243
  },
242
244
  0x0015 => {
243
245
  Name => 'GPSDestLongitudeRef',
@@ -250,6 +252,7 @@ my %coordConv = (
250
252
  Writable => 'rational64u',
251
253
  Count => 3,
252
254
  %coordConv,
255
+ PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val,undef,"lon")',
253
256
  },
254
257
  0x0017 => {
255
258
  Name => 'GPSDestBearingRef',
@@ -529,18 +532,26 @@ sub ToDMS($$;$$)
529
532
  #------------------------------------------------------------------------------
530
533
  # Convert to decimal degrees
531
534
  # Inputs: 0) a string containing 1-3 decimal numbers and any amount of other garbage
532
- # 1) true if value should be negative if coordinate ends in 'S' or 'W'
533
- # Returns: Coordinate in degrees
534
- sub ToDegrees($;$)
535
+ # 1) true if value should be negative if coordinate ends in 'S' or 'W',
536
+ # 2) 'lat' or 'lon' to extract lat or lon from GPSCoordinates string
537
+ # Returns: Coordinate in degrees, or '' on error
538
+ sub ToDegrees($;$$)
535
539
  {
536
- my ($val, $doSign) = @_;
540
+ my ($val, $doSign, $coord) = @_;
537
541
  return '' if $val =~ /\b(inf|undef)\b/; # ignore invalid values
542
+ # use only lat or lon part of combined GPSCoordinates inputs
543
+ if ($coord and ($coord eq 'lat' or $coord eq 'lon') and
544
+ # (two formatted coordinate values with cardinal directions, separated by a comma)
545
+ $val =~ /^(.*(?:N(?:orth)?|S(?:outh)?)),\s*(.*(?:E(?:ast)?|W(?:est)?))$/i)
546
+ {
547
+ $val = $coord eq 'lat' ? $1 : $2;
548
+ }
538
549
  # extract decimal or floating point values out of any other garbage
539
550
  my ($d, $m, $s) = ($val =~ /((?:[+-]?)(?=\d|\.\d)\d*(?:\.\d*)?(?:[Ee][+-]\d+)?)/g);
540
551
  return '' unless defined $d;
541
552
  my $deg = $d + (($m || 0) + ($s || 0)/60) / 60;
542
553
  # make negative if S or W coordinate
543
- $deg = -$deg if $doSign ? $val =~ /[^A-Z](S|W)$/i : $deg < 0;
554
+ $deg = -$deg if $doSign ? $val =~ /[^A-Z](S(outh)?|W(est)?)\s*$/i : $deg < 0;
544
555
  return $deg;
545
556
  }
546
557