exiftool-vendored.pl 12.39.0 → 12.40.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/Changes CHANGED
@@ -7,6 +7,28 @@ RSS feed: https://exiftool.org/rss.xml
7
7
  Note: The most recent production release is Version 12.30. (Other versions are
8
8
  considered development releases, and are not uploaded to MetaCPAN.)
9
9
 
10
+ Feb. 9, 2022 - Version 12.40
11
+
12
+ - Added a new Nikon LensID (thanks Wolfgang Exler)
13
+ - Added PageCount tag to return the number of pages in a multi-page TIFF
14
+ - Added a few more Sony LensTypes (thanks Jos Roost)
15
+ - Decode some new Canon tags (thanks Mark Reid)
16
+ - Decode another Nikon Z9 tag (thanks Warren Hatch)
17
+ - Decode Nikon NKSC GPSImgDirection (thanks Olaf)
18
+ - Improved handling of empty XMP structures in lists
19
+ - Tolerate leading UTF-8 BOM in -geotag log files
20
+ - Updated photoshop_paths.config to include WorkingPath
21
+ - Patched to allow writing of MP4 videos which have url tracks with a missing
22
+ sample description entry
23
+ - Fixed typo in the name of a new Nikon tag (thanks Herb)
24
+ - Fixed description of GPR (General Purpose RAW) file type
25
+ - Fixed potential deep recursion runtime error when writing nested XMP
26
+ structures
27
+ - Fixed warning which could be generated when writing new
28
+ Composite:GPSCoordinates tag
29
+ - Fixed deep recursion error when reading multi-page TIFF images with more
30
+ than 100 pages
31
+
10
32
  Jan. 13, 2022 - Version 12.39
11
33
 
12
34
  - Added a new Pentax LensType (thanks Christian Shulz)
package/bin/MANIFEST CHANGED
@@ -194,6 +194,7 @@ html/idiosyncracies.html
194
194
  html/index.html
195
195
  html/install.html
196
196
  html/metafiles.html
197
+ html/mistakes.html
197
198
  html/overview.png
198
199
  html/standards.html
199
200
  html/struct.html
package/bin/META.json CHANGED
@@ -47,6 +47,6 @@
47
47
  }
48
48
  },
49
49
  "release_status" : "stable",
50
- "version" : "12.39",
50
+ "version" : "12.40",
51
51
  "x_serialization_backend" : "JSON::PP version 4.02"
52
52
  }
package/bin/META.yml CHANGED
@@ -28,5 +28,5 @@ recommends:
28
28
  Time::HiRes: 0
29
29
  requires:
30
30
  perl: 5.004
31
- version: 12.39
31
+ version: 12.40
32
32
  x_serialization_backend: 'JSON::PP version 4.02'
package/bin/README CHANGED
@@ -107,8 +107,8 @@ your home directory, then you would type the following commands in a
107
107
  terminal window to extract and run ExifTool:
108
108
 
109
109
  cd ~/Desktop
110
- gzip -dc Image-ExifTool-12.39.tar.gz | tar -xf -
111
- cd Image-ExifTool-12.39
110
+ gzip -dc Image-ExifTool-12.40.tar.gz | tar -xf -
111
+ cd Image-ExifTool-12.40
112
112
  ./exiftool t/images/ExifTool.jpg
113
113
 
114
114
  Note: These commands extract meta information from one of the test images.
@@ -97,8 +97,8 @@ my %sACDSeeRegionStruct = (
97
97
  # new XMP namespaces for ACDSee regions
98
98
  'Image::ExifTool::XMP::Main' => {
99
99
  'acdsee-rs' => { # <-- must be the same as the NAMESPACE prefix
100
- SubDirectory => {
101
- TagTable => 'Image::ExifTool::UserDefined::ACDSeeRegions'
100
+ SubDirectory => {
101
+ TagTable => 'Image::ExifTool::UserDefined::ACDSeeRegions'
102
102
  },
103
103
  },
104
104
  },
@@ -147,7 +147,7 @@ my %sACDSeeRegionStruct = (
147
147
  },
148
148
  ValueConv => q{
149
149
  my ($rgn, @newRgns);
150
- my $rgns = ref $val[0] eq 'ARRAY' ? $val[0] : [ $val[0] ];
150
+ my $rgns = ref $val[0] eq 'ARRAY' ? $val[0] : [ $val[0] ];
151
151
  foreach $rgn (@$rgns) {
152
152
  my %newRgn = ( Type => 'Face' );
153
153
  if ($$rgn{RegionBoundary} and $$rgn{RegionBoundary}{RbShape} eq 'rectangle') {
@@ -220,13 +220,13 @@ my %sACDSeeRegionStruct = (
220
220
  # the "Struct" entry defines the structure fields
221
221
  Struct => {
222
222
  # optional structure name (used for warning messages only)
223
- STRUCT_NAME => 'ACDSee RegionInfo',
223
+ STRUCT_NAME => 'ACDSee RegionInfo',
224
224
  RegionList => {
225
225
  FlatName => 'Region',
226
226
  Struct => \%sACDSeeRegionStruct,
227
227
  List => 'Bag',
228
228
  },
229
- AppliedToDimensions => {
229
+ AppliedToDimensions => {
230
230
  FlatName => 'RegionAppliedToDimensions',Struct => \%sACDSeeDimensions },
231
231
  },
232
232
  },
@@ -239,7 +239,7 @@ my %sACDSeeRegionStruct = (
239
239
  RegionInfoACDSeeAppliedToDimensionsW => 'ACDSeeRegionAppliedToDimensionsW',
240
240
  RegionInfoACDSeeRegionListDLYAreaH => 'ACDSeeRegionDLYAreaH',
241
241
  RegionInfoACDSeeRegionListDLYAreaW => 'ACDSeeRegionDLYAreaW',
242
- RegionInfoACDSeeRegionListDLYAreaX => 'ACDSeeRegionDLYAreaX',
242
+ RegionInfoACDSeeRegionListDLYAreaX => 'ACDSeeRegionDLYAreaX',
243
243
  RegionInfoACDSeeRegionListDLYAreaY => 'ACDSeeRegionDLYAreaY',
244
244
  RegionInfoACDSeeRegionListALGAreaH => 'ACDSeeRegionALGAreaH',
245
245
  RegionInfoACDSeeRegionListALGAreaW => 'ACDSeeRegionALGAreaW',
@@ -34,15 +34,15 @@
34
34
  # Usage:
35
35
  #
36
36
  # 1) Extract Photoshop path names:
37
- #
37
+ #
38
38
  # exiftool -config photoshop_paths.config -allpaths FILE
39
39
  #
40
40
  # 2) Extract Photoshop path names and anchor points:
41
- #
41
+ #
42
42
  # exiftool -config photoshop_paths.config -userparam anchor -allpaths FILE
43
43
  #
44
44
  # 3) Extract Photoshop path anchor points only:
45
- #
45
+ #
46
46
  # exiftool -config photoshop_paths.config -userparam anchoronly -allpaths FILE
47
47
  #
48
48
  # 4) Copy all Photoshop paths from one file (SRC) to another (DST):
@@ -68,6 +68,7 @@
68
68
  # subpath respectively
69
69
  # 2017/06/03 - PH Added TotalPathPoints
70
70
  # 2017/07/17 - PH Added UniquePathPoints
71
+ # 2022/02/03 - PH Added WorkingPath and WorkingPathPix
71
72
  #
72
73
  # References: https://exiftool.org/forum/index.php/topic,1621.0.html
73
74
  # https://exiftool.org/forum/index.php/topic,3910.0.html
@@ -77,10 +78,11 @@
77
78
  # Print Photoshop path name and/or anchor points
78
79
  # Inputs: 0) reference to Photoshop path data, 1) ExifTool object reference
79
80
  # 2-3) optional image width/height to convert anchor points to pixels
81
+ # 4) optional path name
80
82
  # Returns: String with name and/or Bezier knot anchor points
81
- sub PrintPath($$;$$)
83
+ sub PrintPath($$;$$$)
82
84
  {
83
- my ($val, $et, $w, $h) = @_;
85
+ my ($val, $et, $w, $h, $nm) = @_;
84
86
  my ($pos, $name, @rtn);
85
87
  my $len = length($$val) - 26;
86
88
 
@@ -88,8 +90,9 @@ sub PrintPath($$;$$)
88
90
  if ($$val =~ m{.*/#(.{0,255})#/$}s) {
89
91
  $name = $1;
90
92
  $len -= length($1) + 4;
93
+ $name = $nm if defined $nm and not length $name;
91
94
  } else {
92
- $name = '<none>';
95
+ $name = defined $nm ? $nm : '<none>';
93
96
  }
94
97
  my $anchorOnly = $et->Options(UserParam => 'AnchorOnly');
95
98
  push @rtn, $name unless $anchorOnly;
@@ -118,7 +121,7 @@ sub PrintPath($$;$$)
118
121
  }
119
122
 
120
123
  %Image::ExifTool::Shortcuts::UserDefined = (
121
- # create "AllPaths" shortcut for all Photoshop path tags
124
+ # create "AllPaths" shortcut for all Photoshop path tags (except WorkingPath)
122
125
  AllPaths => [
123
126
  map { sprintf "Path%x", $_ } (0x7d0 .. 0xbb5),
124
127
  ],
@@ -133,6 +136,14 @@ sub PrintPath($$;$$)
133
136
  Name => 'OriginPathInfo',
134
137
  Flags => [ qw(Writable Protected Binary SetResourceName) ],
135
138
  },
139
+ 0x401 => {
140
+ Name => 'WorkingPath',
141
+ Flags => [ qw(Writable Protected Binary ConvertBinary SetResourceName) ],
142
+ PrintConv => sub {
143
+ my ($val, $et) = @_;
144
+ PrintPath($val, $et, undef, undef, 'Work Path');
145
+ },
146
+ },
136
147
  # generate tags for each of the 998 possible Photoshop paths
137
148
  map { $_ => {
138
149
  Name => sprintf('Path%x', $_),
@@ -143,6 +154,7 @@ sub PrintPath($$;$$)
143
154
  },
144
155
  'Image::ExifTool::Composite' => {
145
156
  PathCount => {
157
+ # (PathCount statistics do not include WorkingPath)
146
158
  Desire => {
147
159
  map { $_-0x7d0 => sprintf('Path%x', $_) } (0x7d0 .. 0xbb5),
148
160
  },
@@ -180,6 +192,17 @@ sub PrintPath($$;$$)
180
192
  Require => 'PathCount',
181
193
  ValueConv => '$$self{TotalPathPoints}',
182
194
  },
195
+ WorkingPathPix => {
196
+ Require => {
197
+ 0 => 'ImageWidth',
198
+ 1 => 'ImageHeight',
199
+ 2 => 'WorkingPath',
200
+ },
201
+ ValueConv => sub {
202
+ my ($val, $et) = @_;
203
+ PrintPath($$val[2], $et, $$val[0], $$val[1], 'Work Path');
204
+ },
205
+ },
183
206
  map { sprintf('PathPix%x', $_) => {
184
207
  Require => {
185
208
  0 => 'ImageWidth',
@@ -63,7 +63,7 @@
63
63
  # 2015/05/12 - PH Minor code tweaks
64
64
  # 2015/10/26 - BKW Round off area sizes to 7 decimal places
65
65
  # 2016/01/18 - BKW Improved rounding algorithm
66
- # 2016/05/14 - BKW Increased rounding to 9 decimal places (Max Picasa accepts),
66
+ # 2016/05/14 - BKW Increased rounding to 9 decimal places (Max Picasa accepts),
67
67
  # moved rounding operation to subroutine
68
68
  #
69
69
  # References: https://exiftool.org/forum/index.php/topic,6354.0.html
@@ -16,13 +16,13 @@
16
16
 
17
17
  %Image::ExifTool::UserDefined = (
18
18
  'Image::ExifTool::XMP::Main' => {
19
- Camera => {
19
+ Camera => {
20
20
  SubDirectory => {
21
21
  TagTable => 'Image::ExifTool::UserDefined::Camera',
22
22
  },
23
23
  },
24
24
  },
25
- );
25
+ );
26
26
 
27
27
  %Image::ExifTool::UserDefined::Camera = (
28
28
  GROUPS => { 0 => 'XMP', 1 => 'XMP-Camera', 2 => 'Camera' },
@@ -68,9 +68,9 @@ sub has_defined {
68
68
  35 => 'EXIF:TransferRange', # TransferRange (342/0x0156)
69
69
  36 => 'EXIF:YCbCrCoefficients', # YCbCrCoefficients (529/0x0211)
70
70
  37 => 'EXIF:YCbCrPositioning', # YCbCrPositioning (531/0x0213)
71
- 38 => 'EXIF:YCbCrSubSampling', # YCbCrSubSampling (530/0x0212)
71
+ 38 => 'EXIF:YCbCrSubSampling', # YCbCrSubSampling (530/0x0212)
72
72
  # Other tags to check
73
- 39 => 'EXIF:PhotometricInterpretation', # PhotometricInterpretation (262/0x0106)
73
+ 39 => 'EXIF:PhotometricInterpretation', # PhotometricInterpretation (262/0x0106)
74
74
  40 => 'EXIF:Compression', # Compression (259/0x0103)
75
75
  },
76
76
  ValueConv => q{
package/bin/exiftool CHANGED
@@ -10,7 +10,7 @@
10
10
  use strict;
11
11
  require 5.004;
12
12
 
13
- my $version = '12.39';
13
+ my $version = '12.40';
14
14
 
15
15
  # add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
16
16
  BEGIN {
@@ -5436,7 +5436,7 @@ with this command:
5436
5436
 
5437
5437
  produces output like this:
5438
5438
 
5439
- -- Generated by ExifTool 12.39 --
5439
+ -- Generated by ExifTool 12.40 --
5440
5440
  File: a.jpg - 2003:10:31 15:44:19
5441
5441
  (f/5.6, 1/60s, ISO 100)
5442
5442
  File: b.jpg - 2006:05:23 11:57:38
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
88
88
  sub ProcessExifInfo($$$);
89
89
  sub SwapWords($);
90
90
 
91
- $VERSION = '4.55';
91
+ $VERSION = '4.56';
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)
@@ -970,8 +970,8 @@ my %canonQuality = (
970
970
  4 => 'RAW',
971
971
  5 => 'Superfine',
972
972
  7 => 'CRAW', #42
973
- 130 => 'Normal Movie', #22
974
- 131 => 'Movie (2)', #PH (7DmkII 1920x1080)
973
+ 130 => 'Light (RAW)', #github#119
974
+ 131 => 'Standard (RAW)', #github#119
975
975
  );
976
976
  my %canonImageSize = (
977
977
  -1 => 'n/a',
@@ -2053,6 +2053,13 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
2053
2053
  TagTable => 'Image::ExifTool::Canon::HDRInfo',
2054
2054
  }
2055
2055
  },
2056
+ 0x4026 => { #github#119
2057
+ Name => 'LogInfo',
2058
+ SubDirectory => {
2059
+ Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
2060
+ TagTable => 'Image::ExifTool::Canon::LogInfo',
2061
+ }
2062
+ },
2056
2063
  0x4028 => { #PH
2057
2064
  Name => 'AFConfig', # (AFTabInfo)
2058
2065
  SubDirectory => {
@@ -8701,6 +8708,65 @@ my %filterConv = (
8701
8708
  # 3 - maybe related to AutoImageAlign?
8702
8709
  );
8703
8710
 
8711
+ # More color information (MakerNotes tag 0x4026) (ref github issue #119)
8712
+ %Image::ExifTool::Canon::LogInfo = (
8713
+ %binaryDataAttrs,
8714
+ FORMAT => 'int32s',
8715
+ FIRST_ENTRY => 1,
8716
+ PRIORITY => 0,
8717
+ 4 => {
8718
+ Name => 'CompressionFormat',
8719
+ PrintConv => {
8720
+ 0 => 'Editing (ALL-I)',
8721
+ 1 => 'Standard (IPB)',
8722
+ 2 => 'Light (IPB)',
8723
+ 3 => 'Motion JPEG',
8724
+ 4 => 'RAW', # either Standard or Light, depending on Quality
8725
+ },
8726
+ },
8727
+ 6 => { # 0 to 7
8728
+ Name => 'Sharpness',
8729
+ RawConv => '$val == 0x7fffffff ? undef : $val',
8730
+ },
8731
+ 7 => { # -4 to 4
8732
+ Name => 'Saturation',
8733
+ RawConv => '$val == 0x7fffffff ? undef : $val',
8734
+ %Image::ExifTool::Exif::printParameter,
8735
+ },
8736
+ 8 => { # -4 to 4
8737
+ Name => 'ColorTone',
8738
+ RawConv => '$val == 0x7fffffff ? undef : $val',
8739
+ %Image::ExifTool::Exif::printParameter,
8740
+ },
8741
+ 9 => {
8742
+ Name => 'ColorSpace2',
8743
+ RawConv => '$val == 0x7fffffff ? undef : $val',
8744
+ PrintConv => {
8745
+ 0 => 'BT.709',
8746
+ 1 => 'BT.2020',
8747
+ 2 => 'CinemaGamut',
8748
+ },
8749
+ },
8750
+ 10 => {
8751
+ Name => 'ColorMatrix',
8752
+ RawConv => '$val == 0x7fffffff ? undef : $val',
8753
+ PrintConv => {
8754
+ 0 => 'EOS Original',
8755
+ 1 => 'Neutral',
8756
+ },
8757
+ },
8758
+ 11 => {
8759
+ Name => 'CanonLogVersion', # (increases dynamic range of sensor data)
8760
+ RawConv => '$val == 0x7fffffff ? undef : $val',
8761
+ PrintConv => {
8762
+ 0 => 'OFF',
8763
+ 1 => 'CLogV1',
8764
+ 2 => 'CLogV2', # (NC)
8765
+ 3 => 'CLogV3',
8766
+ },
8767
+ },
8768
+ );
8769
+
8704
8770
  # AF configuration info (MakerNotes tag 0x4028) (ref PH)
8705
8771
  %Image::ExifTool::Canon::AFConfig = (
8706
8772
  %binaryDataAttrs,
@@ -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.38';
59
+ $VERSION = '4.39';
60
60
 
61
61
  sub ProcessExif($$$);
62
62
  sub WriteExif($$$);
@@ -415,7 +415,14 @@ my %opcodeInfo = (
415
415
  WriteGroup => 'IFD0',
416
416
  # set priority directory if this is the full resolution image
417
417
  DataMember => 'SubfileType',
418
- RawConv => '$self->SetPriorityDir() if $val eq "0"; $$self{SubfileType} = $val',
418
+ RawConv => q{
419
+ if ($val == ($val & 0x02)) {
420
+ $self->SetPriorityDir() if $val == 0;
421
+ $$self{PageCount} = ($$self{PageCount} || 0) + 1;
422
+ $$self{MultiPage} = 1 if $val == 2 or $$self{PageCount} > 1;
423
+ }
424
+ $$self{SubfileType} = $val;
425
+ },
419
426
  PrintConv => \%subfileType,
420
427
  },
421
428
  0xff => {
@@ -425,7 +432,14 @@ my %opcodeInfo = (
425
432
  Writable => 'int16u',
426
433
  WriteGroup => 'IFD0',
427
434
  # set priority directory if this is the full resolution image
428
- RawConv => '$self->SetPriorityDir() if $val eq "1"; $val',
435
+ RawConv => q{
436
+ if ($val == 1 or $val == 3) {
437
+ $self->SetPriorityDir() if $val == 1;
438
+ $$self{PageCount} = ($$self{PageCount} || 0) + 1;
439
+ $$self{MultiPage} = 1 if $val == 3 or $$self{PageCount} > 1;
440
+ }
441
+ $val;
442
+ },
429
443
  PrintConv => {
430
444
  1 => 'Full-resolution image',
431
445
  2 => 'Reduced-resolution image',
@@ -2144,7 +2158,7 @@ my %opcodeInfo = (
2144
2158
  Notes => 'displayed in seconds, but stored as an APEX value',
2145
2159
  Format => 'rational64s', # Leica M8 patch (incorrectly written as rational64u)
2146
2160
  Writable => 'rational64s',
2147
- ValueConv => 'abs($val)<100 ? 2**(-$val) : 0',
2161
+ ValueConv => 'IsFloat($val) && abs($val)<100 ? 2**(-$val) : 0',
2148
2162
  ValueConvInv => '$val>0 ? -log($val)/log(2) : -100',
2149
2163
  PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
2150
2164
  PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
@@ -4827,6 +4841,7 @@ my %subSecConv = (
4827
4841
  PrintConvInv => q{
4828
4842
  return undef unless $val =~ /(.*? ?[NS]?), ?(.*? ?[EW]?)$/;
4829
4843
  my ($lat, $lon) = ($1, $2);
4844
+ require Image::ExifTool::GPS;
4830
4845
  $lat = Image::ExifTool::GPS::ToDegrees($lat, 1, "lat");
4831
4846
  $lon = Image::ExifTool::GPS::ToDegrees($lon, 1, "lon");
4832
4847
  return "$lat, $lon";
@@ -5248,6 +5263,7 @@ sub RedBlueBalance($@)
5248
5263
  sub PrintExposureTime($)
5249
5264
  {
5250
5265
  my $secs = shift;
5266
+ return $secs unless Image::ExifTool::IsFloat($secs);
5251
5267
  if ($secs < 0.25001 and $secs > 0) {
5252
5268
  return sprintf("1/%d",int(0.5 + 1/$secs));
5253
5269
  }
@@ -5853,7 +5869,7 @@ sub ProcessExif($$$)
5853
5869
  unless ($path =~ /^(JPEG-APP1-IFD0|TIFF-IFD0|PSD-EXIFInfo-IFD0)$/) {
5854
5870
  if ($Image::ExifTool::MWG::strict) {
5855
5871
  $et->Warn("Ignored non-standard EXIF at $path");
5856
- return 1;
5872
+ return 0;
5857
5873
  } else {
5858
5874
  $et->Warn("Non-standard EXIF at $path", 1);
5859
5875
  }
@@ -5896,10 +5912,6 @@ sub ProcessExif($$$)
5896
5912
  # also read next IFD pointer if available
5897
5913
  if ($raf->Read($buf2, $len+4) >= $len) {
5898
5914
  $buff .= $buf2;
5899
- # make copy of dirInfo since we're going to modify it
5900
- my %newDirInfo = %$dirInfo;
5901
- $dirInfo = \%newDirInfo;
5902
- # update directory parameters for the newly loaded IFD
5903
5915
  $dataPt = $$dirInfo{DataPt} = \$buff;
5904
5916
  $dataPos = $$dirInfo{DataPos} = $offset;
5905
5917
  $dataLen = $$dirInfo{DataLen} = length $buff;
@@ -6706,28 +6718,40 @@ sub ProcessExif($$$)
6706
6718
 
6707
6719
  # scan for subsequent IFD's if specified
6708
6720
  if ($$dirInfo{Multi} and $bytesFromEnd >= 4) {
6709
- my $offset = Get32u($dataPt, $dirEnd);
6710
- if ($offset) {
6711
- my $subdirStart = $offset - $dataPos;
6712
- # use same directory information for trailing directory,
6713
- # but change the start location (ProcessDirectory will
6714
- # test to make sure we don't reprocess the same dir twice)
6715
- my %newDirInfo = %$dirInfo;
6716
- $newDirInfo{DirStart} = $subdirStart;
6721
+ # use same directory information for trailing directory,
6722
+ # but change the start location (ProcessDirectory will
6723
+ # test to make sure we don't reprocess the same dir twice)
6724
+ my %newDirInfo = %$dirInfo;
6725
+ $newDirInfo{Multi} = 0; # prevent recursion
6726
+ $newDirInfo{OffsetName} = $nextOffName;
6727
+ $$et{INDENT} =~ s/..$//; # keep indent the same
6728
+ for (;;) {
6729
+ my $offset = Get32u($dataPt, $dirEnd) or last;
6730
+ $newDirInfo{DirStart} = $offset - $dataPos;
6717
6731
  # increment IFD number
6718
6732
  my $ifdNum = $newDirInfo{DirName} =~ s/(\d+)$// ? $1 : 0;
6719
6733
  $newDirInfo{DirName} .= $ifdNum + 1;
6720
- $newDirInfo{OffsetName} = $nextOffName;
6721
6734
  # must validate SubIFD1 because the nextIFD pointer is invalid for some RAW formats
6722
6735
  if ($newDirInfo{DirName} ne 'SubIFD1' or ValidateIFD(\%newDirInfo)) {
6723
- $$et{INDENT} =~ s/..$//; # keep indent the same
6724
6736
  my $cur = pop @{$$et{PATH}};
6725
6737
  $et->ProcessDirectory(\%newDirInfo, $tagTablePtr) or $success = 0;
6726
6738
  push @{$$et{PATH}}, $cur;
6739
+ if ($success and $newDirInfo{BytesFromEnd} >= 4) {
6740
+ $dataPt = $newDirInfo{DataPt};
6741
+ $dataPos = $newDirInfo{DataPos};
6742
+ $dirEnd = $newDirInfo{DirEnd};
6743
+ next;
6744
+ }
6727
6745
  } elsif ($verbose or $$et{TIFF_TYPE} eq 'TIFF') {
6728
6746
  $et->Warn('Ignored bad IFD linked from SubIFD');
6729
6747
  }
6748
+ last;
6730
6749
  }
6750
+ } elsif (defined $$dirInfo{Multi}) {
6751
+ # return necessary parameters for parsing next IFD
6752
+ $$dirInfo{DirEnd} = $dirEnd;
6753
+ $$dirInfo{OffsetName} = $nextOffName;
6754
+ $$dirInfo{BytesFromEnd} = $bytesFromEnd;
6731
6755
  }
6732
6756
  return $success;
6733
6757
  }
@@ -28,7 +28,7 @@ use vars qw($VERSION);
28
28
  use Image::ExifTool qw(:Public);
29
29
  use Image::ExifTool::GPS;
30
30
 
31
- $VERSION = '1.65';
31
+ $VERSION = '1.66';
32
32
 
33
33
  sub JITTER() { return 2 } # maximum time jitter
34
34
 
@@ -210,13 +210,14 @@ sub LoadTrackLog($$;$)
210
210
  $raf->ReadLine($_) or last;
211
211
  # determine file format
212
212
  if (not $format) {
213
+ s/^\xef\xbb\xbf//; # remove leading BOM if it exists
213
214
  if (/^<(\?xml|gpx)[\s>]/) { # look for XML or GPX header
214
215
  $format = 'XML';
215
216
  # check for NMEA sentence
216
217
  # (must ONLY start with ones that have timestamps! eg. not GSA or PTNTHPR!)
217
218
  } elsif (/^.*\$([A-Z]{2}(RMC|GGA|GLL|ZDA)|PMGNTRK),/) {
218
219
  $format = 'NMEA';
219
- $nmeaStart = $2 || $1; # save type of first sentence
220
+ $nmeaStart = $2 || $1; # save type of first sentence
220
221
  } elsif (/^A(FLA|XSY|FIL)/) {
221
222
  # (don't set format yet because we want to read HFDTE first)
222
223
  $nmeaStart = 'B' ;
@@ -63,7 +63,7 @@ use Image::ExifTool::Exif;
63
63
  use Image::ExifTool::GPS;
64
64
  use Image::ExifTool::XMP;
65
65
 
66
- $VERSION = '4.04';
66
+ $VERSION = '4.05';
67
67
 
68
68
  sub LensIDConv($$$);
69
69
  sub ProcessNikonAVI($$$);
@@ -495,6 +495,7 @@ sub GetAFPointGrid($$;$);
495
495
  '7A 48 5C 80 24 24 4B 06' => 'Sigma 70-200mm F2.8 EX APO DG Macro HSM II',
496
496
  'EE 48 5C 80 24 24 4B 06' => 'Sigma 70-200mm F2.8 EX APO DG Macro HSM II', #JD
497
497
  '9C 48 5C 80 24 24 4B 0E' => 'Sigma 70-200mm F2.8 EX DG OS HSM', #Rolando Ruzic
498
+ 'BB 48 5C 80 24 24 4B 4E' => 'Sigma 70-200mm F2.8 DG OS HSM | S', #forum13207
498
499
  '02 46 5C 82 25 25 02 00' => 'Sigma 70-210mm F2.8 APO', #JD
499
500
  '02 40 5C 82 2C 35 02 00' => 'Sigma APO 70-210mm F3.5-4.5',
500
501
  '26 3C 5C 82 30 3C 1C 02' => 'Sigma 70-210mm F4-5.6 UC-II',
@@ -1220,6 +1221,16 @@ my %binaryDataAttrs = (
1220
1221
  my %base64bin = ( ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)' );
1221
1222
  my %base64int32u = ( ValueConv => 'my $val=Image::ExifTool::XMP::DecodeBase64($val); unpack("V",$$val)' );
1222
1223
  my %base64bytes = ( ValueConv => 'my $val=Image::ExifTool::XMP::DecodeBase64($val); join(".",unpack("C*",$$val))' );
1224
+ my %base64double = (
1225
+ ValueConv => q{
1226
+ my $val=Image::ExifTool::XMP::DecodeBase64($val);
1227
+ my $saveOrder = GetByteOrder();
1228
+ SetByteOrder('II');
1229
+ $val = GetDouble($val,0);
1230
+ SetByteOrder($saveOrder);
1231
+ return $val;
1232
+ },
1233
+ );
1223
1234
  my %base64coord = (
1224
1235
  ValueConv => q{
1225
1236
  my $val=Image::ExifTool::XMP::DecodeBase64($val);
@@ -4180,7 +4191,7 @@ my %base64coord = (
4180
4191
  Format => 'int16u',
4181
4192
  },
4182
4193
  0x43 => {
4183
- Name => 'FocusPositionHoriontal',
4194
+ Name => 'FocusPositionHorizontal',
4184
4195
  PrintConv => sub { my ($val) = @_; PrintAFPointsLeftRight($val, 29 ); }, #493 focus points for Z9 fall in a 30x18 grid (some coordinates are not accessible)
4185
4196
  },
4186
4197
  0x45 => {
@@ -8565,7 +8576,17 @@ my %nikonFocalConversions = (
8565
8576
  444 => { Name => 'FlashRemoteControl', PrintConv => \%flashRemoteControlZ7, Unknown => 1},
8566
8577
  456 => { Name => 'FlashWirelessOption', PrintConv => \%flashWirelessOptionZ7, Unknown => 1},
8567
8578
  #526 FocusMode
8568
- #528 AFAreaMode
8579
+ 528 => {
8580
+ Name => 'AFAreaMode',
8581
+ PrintConv => {
8582
+ 1 => 'Single',
8583
+ 2 => 'Dynamic',
8584
+ 3 => 'Wide (S)',
8585
+ 4 => 'Wide (L)',
8586
+ 5 => '3D',
8587
+ 6 => 'Auto',
8588
+ },
8589
+ },
8569
8590
  530 => { Name => 'VRMode', PrintConv => \%vRModeZ9},
8570
8591
  534 => {
8571
8592
  Name => 'BracketSet',
@@ -11055,17 +11076,22 @@ my %nikonFocalConversions = (
11055
11076
  },
11056
11077
  GPSAltitude => {
11057
11078
  Groups => { 2 => 'Location' },
11058
- ValueConv => q{
11059
- my $val=Image::ExifTool::XMP::DecodeBase64($val);
11060
- my $saveOrder = GetByteOrder();
11061
- SetByteOrder('II');
11062
- $val = GetDouble($val,0);
11063
- SetByteOrder($saveOrder);
11064
- return $val;
11065
- },
11079
+ %base64double,
11066
11080
  PrintConv => '"$val m"',
11067
11081
  },
11068
- GPSMapDatum => { },
11082
+ GPSMapDatum => { Groups => { 2 => 'Location' } },
11083
+ GPSImgDirection => {
11084
+ Groups => { 2 => 'Location' },
11085
+ %base64double,
11086
+ PrintConv => 'sprintf("%.2f", $val)',
11087
+ },
11088
+ GPSImgDirectionRef => {
11089
+ Groups => { 2 => 'Location' },
11090
+ PrintConv => {
11091
+ M => 'Magnetic North',
11092
+ T => 'True North',
11093
+ },
11094
+ },
11069
11095
  );
11070
11096
  %Image::ExifTool::Nikon::sdc = (
11071
11097
  GROUPS => { 0 => 'XMP', 1 => 'XMP-sdc', 2 => 'Image' },