exiftool_vendored 12.82.0 → 12.83.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +20 -0
  3. data/bin/MANIFEST +2 -18
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +3 -2
  7. data/bin/build_geolocation +867 -0
  8. data/bin/exiftool +26 -4
  9. data/bin/fmt_files/gpx.fmt +2 -1
  10. data/bin/fmt_files/gpx_wpt.fmt +2 -1
  11. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +5 -2
  12. data/bin/lib/Image/ExifTool/CanonVRD.pm +6 -5
  13. data/bin/lib/Image/ExifTool/DJI.pm +29 -0
  14. data/bin/lib/Image/ExifTool/Exif.pm +19 -2
  15. data/bin/lib/Image/ExifTool/GM.pm +17 -8
  16. data/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
  17. data/bin/lib/Image/ExifTool/Geolocation.pm +48 -35
  18. data/bin/lib/Image/ExifTool/Nikon.pm +7 -6
  19. data/bin/lib/Image/ExifTool/QuickTime.pm +4 -1
  20. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +5 -0
  21. data/bin/lib/Image/ExifTool/Sony.pm +15 -6
  22. data/bin/lib/Image/ExifTool/TagLookup.pm +11 -5
  23. data/bin/lib/Image/ExifTool/TagNames.pod +17 -4
  24. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +2 -1
  25. data/bin/lib/Image/ExifTool/Writer.pl +163 -131
  26. data/bin/lib/Image/ExifTool/XMP2.pl +3 -0
  27. data/bin/lib/Image/ExifTool.pm +12 -5
  28. data/bin/lib/Image/ExifTool.pod +13 -7
  29. data/bin/perl-Image-ExifTool.spec +1 -1
  30. data/lib/exiftool_vendored/version.rb +1 -1
  31. metadata +3 -20
  32. data/bin/lib/Image/ExifTool/GeoLang/cs.pm +0 -978
  33. data/bin/lib/Image/ExifTool/GeoLang/de.pm +0 -1975
  34. data/bin/lib/Image/ExifTool/GeoLang/en_ca.pm +0 -44
  35. data/bin/lib/Image/ExifTool/GeoLang/en_gb.pm +0 -124
  36. data/bin/lib/Image/ExifTool/GeoLang/es.pm +0 -2921
  37. data/bin/lib/Image/ExifTool/GeoLang/fi.pm +0 -1116
  38. data/bin/lib/Image/ExifTool/GeoLang/fr.pm +0 -3171
  39. data/bin/lib/Image/ExifTool/GeoLang/it.pm +0 -2750
  40. data/bin/lib/Image/ExifTool/GeoLang/ja.pm +0 -10256
  41. data/bin/lib/Image/ExifTool/GeoLang/ko.pm +0 -4499
  42. data/bin/lib/Image/ExifTool/GeoLang/nl.pm +0 -1270
  43. data/bin/lib/Image/ExifTool/GeoLang/pl.pm +0 -3019
  44. data/bin/lib/Image/ExifTool/GeoLang/ru.pm +0 -18220
  45. data/bin/lib/Image/ExifTool/GeoLang/sk.pm +0 -441
  46. data/bin/lib/Image/ExifTool/GeoLang/sv.pm +0 -714
  47. data/bin/lib/Image/ExifTool/GeoLang/tr.pm +0 -452
  48. data/bin/lib/Image/ExifTool/GeoLang/zh_cn.pm +0 -2225
  49. data/bin/lib/Image/ExifTool/GeoLang/zh_tw.pm +0 -72
data/bin/exiftool CHANGED
@@ -11,7 +11,7 @@ use strict;
11
11
  use warnings;
12
12
  require 5.004;
13
13
 
14
- my $version = '12.82';
14
+ my $version = '12.83';
15
15
 
16
16
  # add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
17
17
  my $exePath;
@@ -1166,7 +1166,7 @@ for (;;) {
1166
1166
  if (/^p(-?)$/ or /^printformat(-?)$/i) {
1167
1167
  my $fmt = shift;
1168
1168
  if ($pass) {
1169
- LoadPrintFormat($fmt, $1);
1169
+ LoadPrintFormat($fmt, $1 || $binaryOutput);
1170
1170
  # load MWG module now if necessary
1171
1171
  if (not $useMWG and grep /^mwg:/i, @requestTags) {
1172
1172
  $useMWG = 1;
@@ -2244,6 +2244,14 @@ sub GetImageInfo($$)
2244
2244
  if (%printFmt) {
2245
2245
  $et->Options(Duplicates => 1);
2246
2246
  $et->Options(RequestTags => \@requestTags);
2247
+ if ($printFmt{SetTags}) {
2248
+ # initialize options so we can set any tags we want
2249
+ $$et{TAGS_FROM_FILE} = 1;
2250
+ $et->Options(MakerNotes => 1);
2251
+ $et->Options(Struct => 2);
2252
+ $et->Options(List => 1);
2253
+ $et->Options(CoordFormat => '%d %d %.8f') unless $et->Options('CoordFormat');
2254
+ }
2247
2255
  } else {
2248
2256
  @foundTags = @tags;
2249
2257
  }
@@ -4121,6 +4129,7 @@ sub AddPrintFormat($)
4121
4129
  push @{$printFmt{$type}}, $expr;
4122
4130
  # add to list of requested tags
4123
4131
  push @requestTags, $expr =~ /\$\{?((?:[-\w]+:)*[-\w?*]+)/g;
4132
+ $printFmt{SetTags} = 1 if $expr =~ /\bSetTags\b/;
4124
4133
  }
4125
4134
 
4126
4135
  #------------------------------------------------------------------------------
@@ -5642,7 +5651,7 @@ it from subsequent text (and must be used if subsequent text begins with an
5642
5651
  alphanumeric character, hyphen, underline, colon or number sign). Use C<$$>
5643
5652
  to represent a C<$> symbol, and C<$/> for a newline. When the string
5644
5653
  argument is used (ie. I<STR>), a newline is added to the end of the string
5645
- unless B<-p-> is specified.
5654
+ unless B<-p-> is specified or the B<-b> option is used.
5646
5655
 
5647
5656
  Multiple B<-p> options may be used. Lines beginning with C<#[HEAD]> and
5648
5657
  C<#[TAIL]> are output before the first processed file and after the last
@@ -5668,7 +5677,7 @@ with this command:
5668
5677
 
5669
5678
  produces output like this:
5670
5679
 
5671
- -- Generated by ExifTool 12.82 --
5680
+ -- Generated by ExifTool 12.83 --
5672
5681
  File: a.jpg - 2003:10:31 15:44:19
5673
5682
  (f/5.6, 1/60s, ISO 100)
5674
5683
  File: b.jpg - 2006:05:23 11:57:38
@@ -6902,6 +6911,19 @@ sources. An equivalent to the above commands using this feature would be:
6902
6911
 
6903
6912
  exiftool -tagsfromfile @ -keywords -api nodups a.jpg
6904
6913
 
6914
+ C<SetTags>
6915
+
6916
+ Used to set tags in extracted images. With no arguments, copies all tags
6917
+ from the source file to the embedded image:
6918
+
6919
+ exiftool -p '${previewimage;SetTags}' -b a.arw > preview.jpg
6920
+
6921
+ Arguments may be added to copy or set specific tags. Arguments take exactly
6922
+ the same form as those on the command line when copying or writing tags,
6923
+ but without the leading dash. For example:
6924
+
6925
+ exiftool -p '${previewimage;SetTags("comment=test","title<filename"}' ...
6926
+
6905
6927
  =head1 WINDOWS UNICODE FILE NAMES
6906
6928
 
6907
6929
  In Windows, command-line arguments are specified using the current code page
@@ -11,6 +11,7 @@
11
11
  # 2018/01/04 - PH Added IF to be sure position exists
12
12
  # 2018/01/06 - PH Use DateFmt function instead of -d option
13
13
  # 2019/10/24 - PH Preserve sub-seconds in GPSDateTime value
14
+ # 2024/04/11 - PH Use %f feature in GPSDateTime formatting
14
15
  #
15
16
  # Notes: 1) Input file(s) must contain GPSLatitude and GPSLongitude.
16
17
  # 2) The -ee3 option is to extract the full track from video files.
@@ -32,7 +33,7 @@
32
33
  #[IF] $gpslatitude $gpslongitude
33
34
  #[BODY]<trkpt lat="$gpslatitude#" lon="$gpslongitude#">
34
35
  #[BODY] <ele>$gpsaltitude#</ele>
35
- #[BODY] <time>${gpsdatetime#;my ($ss)=/\.\d+/g;DateFmt("%Y-%m-%dT%H:%M:%SZ");s/Z/${ss}Z/ if $ss}</time>
36
+ #[BODY] <time>${gpsdatetime#;DateFmt("%Y-%m-%dT%H:%M:%S%fZ")}</time>
36
37
  #[BODY]</trkpt>
37
38
  #[TAIL]</trkseg>
38
39
  #[TAIL]</trk>
@@ -12,6 +12,7 @@
12
12
  # 2018/01/04 - PH Added IF to be sure position exists
13
13
  # 2018/01/06 - PH Use DateFmt function instead of -d option
14
14
  # 2019/10/24 - PH Preserve sub-seconds in GPSDateTime value
15
+ # 2024/04/11 - PH Use %f feature in GPSDateTime formatting
15
16
  #
16
17
  # Notes: 1) Input file(s) must contain GPSLatitude and GPSLongitude.
17
18
  # 2) The -ee3 option is to extract the full track from video files.
@@ -30,7 +31,7 @@
30
31
  #[IF] $gpslatitude $gpslongitude
31
32
  #[BODY]<wpt lat="$gpslatitude#" lon="$gpslongitude#">
32
33
  #[BODY] <ele>$gpsaltitude#</ele>
33
- #[BODY] <time>${gpsdatetime#;my ($ss)=/\.\d+/g;DateFmt("%Y-%m-%dT%H:%M:%SZ");s/Z/${ss}Z/ if $ss}</time>
34
+ #[BODY] <time>${gpsdatetime#;DateFmt("%Y-%m-%dT%H:%M:%S%fZ")}</time>
34
35
  #[BODY] <name>$filename</name>
35
36
  #[BODY] <link href="$directory/$filename"/>
36
37
  #[BODY] <sym>Scenic Area</sym>
@@ -35,7 +35,7 @@ use Image::ExifTool::Sony;
35
35
  use Image::ExifTool::Validate;
36
36
  use Image::ExifTool::MacOS;
37
37
 
38
- $VERSION = '3.55';
38
+ $VERSION = '3.56';
39
39
  @ISA = qw(Exporter);
40
40
 
41
41
  sub NumbersFirst($$);
@@ -672,7 +672,10 @@ Camero.
672
672
 
673
673
  Use the API L<PrintCSV|../ExifTool.html#PrintCSV> option to output all timed
674
674
  PDR data in CSV format at greatly increased speed and with much lower memory
675
- usage.
675
+ usage. This option prints the numerical values for each channel in CSV
676
+ format, suitable for import into RaceRender. In this output, the gear
677
+ numbers for Neutral and Reverse are changed to -1 and -100 respectively for
678
+ compatibility with RaceRender.
676
679
  },
677
680
  PodTrailer => q{
678
681
  ~head1 NOTES
@@ -23,7 +23,7 @@ use vars qw($VERSION);
23
23
  use Image::ExifTool qw(:DataAccess :Utils);
24
24
  use Image::ExifTool::Canon;
25
25
 
26
- $VERSION = '1.39';
26
+ $VERSION = '1.40';
27
27
 
28
28
  sub ProcessCanonVRD($$;$);
29
29
  sub WriteCanonVRD($$;$);
@@ -1427,15 +1427,16 @@ my $blankFooter = "CANON OPTIONAL DATA\0" . ("\0" x 42) . "\xff\xd9";
1427
1427
  4 => 'CropY',
1428
1428
  5 => 'CropWidth',
1429
1429
  6 => 'CropHeight',
1430
+ 7 => 'CropRotation',
1430
1431
  8 => {
1431
- Name => 'CropRotation',
1432
+ Name => 'CropAngle',
1432
1433
  Format => 'double',
1433
1434
  PrintConv => 'sprintf("%.7g",$val)',
1434
1435
  PrintConvInv => '$val',
1435
1436
  },
1436
- 0x0a => 'CropOriginalWidth',
1437
- 0x0b => 'CropOriginalHeight',
1438
- # 0x0c double - value: 100
1437
+ 10 => 'CropOriginalWidth',
1438
+ 11 => 'CropOriginalHeight',
1439
+ # 12 double - value: 100
1439
1440
  );
1440
1441
 
1441
1442
  # DR4 Stamp Tool tags (ref PH)
@@ -19,6 +19,7 @@ use Image::ExifTool::GPS;
19
19
  $VERSION = '1.09';
20
20
 
21
21
  sub ProcessDJIInfo($$$);
22
+ sub Process_djmd($$$);
22
23
 
23
24
  my %convFloat2 = (
24
25
  PrintConv => 'sprintf("%+.2f", $val)',
@@ -186,6 +187,34 @@ my %convFloat2 = (
186
187
  },
187
188
  );
188
189
 
190
+ # TODO - eventually add ability to decode this?
191
+ %Image::ExifTool::DJI::djmd = (
192
+ PROCESS_PROC => \&Process_djmd,
193
+ );
194
+
195
+ #------------------------------------------------------------------------------
196
+ # Process DJI djmd timed data from Action4 videos (ref PH)
197
+ # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
198
+ # Returns: 1 on success
199
+ # TODO: work in progress
200
+ sub Process_djmd($$$)
201
+ {
202
+ my ($et, $dirInfo, $tagTbl) = @_;
203
+ my $dataPt = $$dirInfo{DataPt};
204
+ my ($pos, $bit, $val) = (6, 0, 0);
205
+ for (;;) {
206
+ my $v = Get8u($dataPt, $pos);
207
+ $val += ($v & 0x7f) << $bit;
208
+ last unless $v & 0x80;
209
+ ++$pos;
210
+ $bit += 7;
211
+ }
212
+ $pos += 49;
213
+ my @a = unpack("x${pos}fxfxfxfx3fxfxf", $$dataPt);
214
+ print "$val @a\n";
215
+ return 1;
216
+ }
217
+
189
218
  #------------------------------------------------------------------------------
190
219
  # Process DJI info (ref PH)
191
220
  # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
@@ -57,7 +57,7 @@ use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat
57
57
  use Image::ExifTool qw(:DataAccess :Utils);
58
58
  use Image::ExifTool::MakerNotes;
59
59
 
60
- $VERSION = '4.51';
60
+ $VERSION = '4.52';
61
61
 
62
62
  sub ProcessExif($$$);
63
63
  sub WriteExif($$$);
@@ -4342,7 +4342,7 @@ my %opcodeInfo = (
4342
4342
  Count => -1,
4343
4343
  Protected => 1,
4344
4344
  },
4345
- 0xcd3b => { # DNG 1.6
4345
+ 0xcd3f => { # DNG 1.6
4346
4346
  Name => 'RGBTables',
4347
4347
  Writable => 'undef',
4348
4348
  WriteGroup => 'IFD0',
@@ -4404,6 +4404,23 @@ my %opcodeInfo = (
4404
4404
  WriteGroup => 'IFD0',
4405
4405
  Protected => 1,
4406
4406
  },
4407
+ 0xcd49 => { # DNG 1.7.1
4408
+ Name => 'JXLDistance',
4409
+ Writable => 'float',
4410
+ WriteGroup => 'IFD0',
4411
+ },
4412
+ 0xcd4a => { # DNG 1.7.1
4413
+ Name => 'JXLEffort',
4414
+ Notes => 'values range from 1=low to 9=high',
4415
+ Writable => 'int32u',
4416
+ WriteGroup => 'IFD0',
4417
+ },
4418
+ 0xcd4b => { # DNG 1.7.1
4419
+ Name => 'JXLDecodeSpeed',
4420
+ Notes => 'values range from 1=slow to 4=fast',
4421
+ Writable => 'int32u',
4422
+ WriteGroup => 'IFD0',
4423
+ },
4407
4424
  0xea1c => { #13
4408
4425
  Name => 'Padding',
4409
4426
  Binary => 1,
@@ -15,7 +15,7 @@ use vars qw($VERSION);
15
15
  use Image::ExifTool qw(:DataAccess :Utils);
16
16
  use Image::ExifTool::GPS;
17
17
 
18
- $VERSION = '1.00';
18
+ $VERSION = '1.01';
19
19
 
20
20
  sub Process_marl($$$);
21
21
  sub Process_mrld($$$);
@@ -30,6 +30,8 @@ my %convertUnits = (
30
30
  ltr => 'L',
31
31
  );
32
32
 
33
+ my $pi = 3.141592653589793;
34
+
33
35
  # offsets and scaling factors to convert to reasonable units
34
36
  my %changeOffset = (
35
37
  C => -273.15, # K to C
@@ -37,8 +39,8 @@ my %changeOffset = (
37
39
  my %changeScale = (
38
40
  G => 1 / 9.80665, # m/s2 to G
39
41
  kph => 3.6, # m/s to km/h
40
- deg => 180 / 3.1415926536, # radians to degrees
41
- 'deg/sec' => 180 / 3.1415926536, # rad/s to deg/s
42
+ deg => 180 / $pi, # radians to degrees
43
+ 'deg/sec' => 180 / $pi, # rad/s to deg/s
42
44
  '%' => 100, # decimal to %
43
45
  kPa => 1/1000, # Pa to kPa
44
46
  rpm => 10, # ? (arbitrary factor of 10)
@@ -181,7 +183,7 @@ my %channelStruct = (
181
183
  Name => 'GPSTrack',
182
184
  Description => 'GPS Track',
183
185
  Groups => { 2 => 'Location' },
184
- PrintConv => 'sprintf("%.2f",$val)',
186
+ PrintConv => '$val > 360 ? "n/a" : sprintf("%.2f",$val)', # (seen 655.35)
185
187
  },
186
188
  ABSActive => { },
187
189
  AccelPos => { },
@@ -209,7 +211,14 @@ my %channelStruct = (
209
211
  EngineTorqureReq => { },
210
212
  FuelCapacity => { },
211
213
  FuelLevel => { },
212
- Gear => { ValueConv => { 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 13=>'N', 14=>'R' } },
214
+ Gear => {
215
+ Notes => q{
216
+ in the PrintCSV output, the value for Neutral is set to -1, and Reverse to
217
+ -100 for compatibility with RaceRender
218
+ },
219
+ CSVConv => { 13 => -1, 14 => -100 },
220
+ PrintConv => { 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 13=>'N', 14=>'R' }
221
+ },
213
222
  GPSFix => { },
214
223
  InfotainOpMode => { },
215
224
  IntakeAirTemperature => { },
@@ -261,7 +270,7 @@ my %channelStruct = (
261
270
  sub PrintCSV($;$)
262
271
  {
263
272
  my ($et, $ts) = @_;
264
- my $csv = $$et{GMCsv} or return;
273
+ my $csv = $$et{GMCsv} or return; # get the list of channels with measurements
265
274
  @$csv or return;
266
275
  my $vals = $$et{GMVals};
267
276
  my $gmDict = $$et{GMDictionary};
@@ -271,7 +280,7 @@ sub PrintCSV($;$)
271
280
  foreach (@$csv) {
272
281
  my $gmChan = $$gmDict[$_];
273
282
  $items[$_] = $$vals[$_] * $$gmChan{Mult} + $$gmChan{Off};
274
- # apply lookup conversion if applicable (ie. Gear)
283
+ # apply CSV conversion if applicable (ie. Gear)
275
284
  next unless $$gmChan{Conv} and defined $$gmChan{Conv}{$items[$_]};
276
285
  $items[$_] = $$gmChan{Conv}{$items[$_]};
277
286
  }
@@ -397,7 +406,7 @@ sub Process_mrld($$$)
397
406
  my $init = int(($a[6] + $a[7]) / 2); # initial value for difference readings
398
407
  # save information about this channel necessary for processing the marl data
399
408
  $$gmDict[$chan] = { Name => $name, Mult => $mult, Off => $off, Init => $init };
400
- $$gmDict[$chan]{Conv} = $$tagInfo{ValueConv} if ref $$tagInfo{ValueConv} eq 'HASH';
409
+ $$gmDict[$chan]{Conv} = $$tagInfo{CSVConv};
401
410
  $csv and $$csv[$chan] = $a[12] . ($a[3] ? " ($a[3])" : '');
402
411
  }
403
412
  # channel 0 must not be defined because we use it for the TimeStamp
Binary file
@@ -9,14 +9,15 @@
9
9
  #
10
10
  # References: https://download.geonames.org/export/
11
11
  #
12
- # Notes: Set $Image::ExifTool::Geolocation::geoDir to override
13
- # default directory for the database file Geolocation.dat
14
- # and language directory GeoLang.
12
+ # Notes: Set $Image::ExifTool::Geolocation::geoDir to override the
13
+ # default directory containing the database file Geolocation.dat
14
+ # and the GeoLang directory with the alternate language files.
15
+ # If set, this directory is
15
16
  #
16
- # Set $Image::ExifTool::Geolocation::altDir to use a database
17
- # of alternate city names. The file is called AltNames.dat
18
- # with entries in the same order as Geolocation.dat. Each
19
- # entry is a newline-separated list of alternate names
17
+ # AltNames.dat may be loaded from a different directory by
18
+ # specifying $Image::ExifTool::Geolocation::altDir. This
19
+ # database and has entries in the same order as Geolocation.dat,
20
+ # and each entry is a newline-separated list of alternate names
20
21
  # terminated by a null byte.
21
22
  #
22
23
  # Databases are based on data from geonames.org with a
@@ -52,9 +53,12 @@
52
53
  # "\0\0\0\0\x04"
53
54
  # Time zone entries:
54
55
  # 1. Time zone name, terminated by newline
56
+ # "\0\0\0\0\x05" (feature codes added in v1.03)
57
+ # Feature codes:
58
+ # 1. Feature code, terminated by newline
55
59
  # "\0\0\0\0\0"
56
60
  #
57
- # Feature Codes: (see http://www.geonames.org/export/codes.html#P for descriptions)
61
+ # Feature Codes (v1.02): (see http://www.geonames.org/export/codes.html#P for descriptions)
58
62
  #
59
63
  # 0. Other 3. PPLA2 6. PPLA5 9. PPLF 12. PPLR 15. PPLX
60
64
  # 1. PPL 4. PPLA3 7. PPLC 10. PPLG 13. PPLS
@@ -66,7 +70,7 @@ package Image::ExifTool::Geolocation;
66
70
  use strict;
67
71
  use vars qw($VERSION $geoDir $altDir $dbInfo);
68
72
 
69
- $VERSION = '1.04'; # (this is the module version number, not the database version)
73
+ $VERSION = '1.06'; # (this is the module version number, not the database version)
70
74
 
71
75
  my $debug; # set to output processing time for testing
72
76
 
@@ -78,17 +82,15 @@ sub Geolocate($;$$$$$);
78
82
 
79
83
  my (@cityList, @countryList, @regionList, @subregionList, @timezoneList);
80
84
  my (%countryNum, %regionNum, %subregionNum, %timezoneNum); # reverse lookups
81
- my (@sortOrder, @altNames, %langLookup, $nCity);
85
+ my (@sortOrder, @altNames, %langLookup, $nCity, %featureCodes);
82
86
  my ($lastArgs, %lastFound, @lastByPop, @lastByLat); # cached city matches
83
87
  my $dbVer = '1.03';
84
88
  my $sortedBy = 'Latitude';
85
89
  my $pi = 3.1415926536;
86
90
  my $earthRadius = 6371; # earth radius in km
87
-
91
+ # hard-coded feature codes for v1.02 database
88
92
  my @featureCodes = qw(Other PPL PPLA PPLA2 PPLA3 PPLA4 PPLA5 PPLC
89
93
  PPLCH PPLF PPLG PPLL PPLR PPLS STLMT PPLX);
90
- my $i = 0;
91
- my %featureCodes = map { lc($_) => $i++ } @featureCodes;
92
94
 
93
95
  # get path name for database file from lib/Image/ExifTool/Geolocation.dat by default,
94
96
  # or according to $Image::ExifTool::Geolocation::directory if specified
@@ -107,12 +109,10 @@ unless (defined $geoDir and not $geoDir) {
107
109
  }
108
110
  }
109
111
 
110
- # set directory for language files
111
- my $geoLang;
112
- if ($geoDir and -d "$geoDir/GeoLang") {
113
- $geoLang = "$geoDir/GeoLang";
114
- } elsif ($geoDir or not defined $geoDir) {
115
- $geoLang = "$defaultDir/GeoLang";
112
+ # set directory for language files and alternate names
113
+ $geoDir = $defaultDir unless defined $geoDir;
114
+ if (not defined $altDir and $geoDir and -e "$geoDir/AltNames.dat") {
115
+ $altDir = $geoDir;
116
116
  }
117
117
 
118
118
  # add user-defined entries to the database
@@ -144,7 +144,7 @@ sub ReadDatabase($)
144
144
  return 0;
145
145
  }
146
146
  my $comment = <DATFILE>;
147
- defined $comment and $comment =~ /(\d+)/ or close(DATFILE), return 0;
147
+ defined $comment and $comment =~ / (\d+) / or close(DATFILE), return 0;
148
148
  $dbInfo = "$datfile v$dbVer: $nCity cities with population > $1";
149
149
  my $isUserDefined = @Image::ExifTool::UserDefined::Geolocation;
150
150
 
@@ -193,7 +193,20 @@ sub ReadDatabase($)
193
193
  push @timezoneList, $line;
194
194
  $timezoneNum{lc $line} = $#timezoneList if $isUserDefined;
195
195
  }
196
+ # read feature codes if available
197
+ if ($line eq "\0\0\0\0\x05\n") {
198
+ undef @featureCodes;
199
+ for (;;) {
200
+ $line = <DATFILE>;
201
+ last if length($line) == 6 and $line =~ /\0\0\0\0/;
202
+ chomp $line;
203
+ push @featureCodes, $line;
204
+ }
205
+ }
196
206
  close DATFILE;
207
+ # initialize featureCodes lookup
208
+ $i = 0;
209
+ %featureCodes = map { lc($_) => $i++ } @featureCodes;
197
210
  return 1;
198
211
  }
199
212
 
@@ -369,14 +382,14 @@ sub GetEntry($;$$)
369
382
  my $pop = (($code>>16 & 0x0f) . '.' . ($code>>12 & 0x0f) . 'e+' . ($code>>20 & 0x0f)) + 0;
370
383
  $lt = sprintf('%.4f', (($lt<<4)|($f >> 4)) * 180 / 0x100000 - 90);
371
384
  $ln = sprintf('%.4f', (($ln<<4)|($f & 0x0f))* 360 / 0x100000 - 180);
372
- $fc = $featureCodes[$fc & 0x0f];
385
+ $fc = $featureCodes[$fc & 0x1f];
373
386
  my $cc = substr($ctry, 0, 2);
374
387
  my $country = substr($ctry, 2);
375
388
  if ($lang) {
376
389
  my $xlat = $langLookup{$lang};
377
390
  # load language lookups if not done already
378
391
  if (not defined $xlat) {
379
- if (eval "require '$geoLang/$lang.pm'") {
392
+ if (eval "require '$geoDir/GeoLang/$lang.pm'") {
380
393
  my $trans = "Image::ExifTool::GeoLang::${lang}::Translate";
381
394
  no strict 'refs';
382
395
  $xlat = \%$trans if %$trans;
@@ -691,10 +704,10 @@ True on success.
691
704
  =head2 ReadAltNames
692
705
 
693
706
  Load the alternate names database. Before calling this method the $altDir
694
- package variable must be set to a directory containing the AltNames.dat
695
- database that matches the current Geolocation.dat. This method is called
696
- automatically by L</Geolocate> if $altDir is set and the GeolocAltNames
697
- option is used and an input city name is provided.
707
+ package variable may be set, otherwise AltNames.dat is loaded from the same
708
+ directory as Geolocation.dat. This method is called automatically by
709
+ L</Geolocate> if the GeolocAltNames option is used and an input city name is
710
+ provided.
698
711
 
699
712
  Image::ExifTool::Geolocation::ReadAltNames();
700
713
 
@@ -706,8 +719,8 @@ option is used and an input city name is provided.
706
719
 
707
720
  =item Return Value:
708
721
 
709
- True on success. Resets the value of $altDir to prevent further attempts at
710
- re-loading the same database.
722
+ True on success. May be called repeatedly, but AltNames.dat is loaded only
723
+ on the first call.
711
724
 
712
725
  =back
713
726
 
@@ -833,8 +846,7 @@ Comma-separated string of alternate names for this city.
833
846
 
834
847
  =item Notes:
835
848
 
836
- Must set the $altDir package variable and call L</ReadAltNames> before
837
- calling this routine.
849
+ L</ReadAltNames> must be called before calling this routine.
838
850
 
839
851
  =back
840
852
 
@@ -896,11 +908,12 @@ contain the Geolocation.dat file, and optionally a GeoLang directory for the
896
908
  language translations. The $geoDir variable may be set to an empty string
897
909
  to disable loading of a database.
898
910
 
899
- A database of alternate city names may be loaded by setting the package
900
- $altDir variable. This directory should contain the AltNames.dat database
901
- that matches the version of Geolocation.dat being used. When searching for
902
- a city by name, the alternate-names database is checked to provide
903
- additional possibilities for matches.
911
+ When searching for a city by name, AltNames.dat is checked to provide
912
+ additional possibilities for matches if the GeolocAltNames option is set.
913
+ The package $altDir variable may be set to specify a different directory for
914
+ AltNames.dat, otherwise the Geolocation.dat directory is assumed. The
915
+ entries in AltNames.dat must match those in the currently loaded version of
916
+ Geolocation.dat.
904
917
 
905
918
  =head1 ADDING USER-DEFINED DATABASE ENTRIES
906
919
 
@@ -65,7 +65,7 @@ use Image::ExifTool::Exif;
65
65
  use Image::ExifTool::GPS;
66
66
  use Image::ExifTool::XMP;
67
67
 
68
- $VERSION = '4.32';
68
+ $VERSION = '4.33';
69
69
 
70
70
  sub LensIDConv($$$);
71
71
  sub ProcessNikonAVI($$$);
@@ -5506,13 +5506,14 @@ my %nikonFocalConversions = (
5506
5506
  37 => 'Nikkor Z 600mm f/4 TC VR S', #28
5507
5507
  38 => 'Nikkor Z 85mm f/1.2 S', #28
5508
5508
  39 => 'Nikkor Z 17-28mm f/2.8', #IB
5509
- 40 => 'NIKKOR Z 26mm f/2.8', #28
5510
- 41 => 'NIKKOR Z DX 12-28mm f/3.5-5.6 PZ VR', #28
5509
+ 40 => 'Nikkor Z 26mm f/2.8', #28
5510
+ 41 => 'Nikkor Z DX 12-28mm f/3.5-5.6 PZ VR', #28
5511
5511
  42 => 'Nikkor Z 180-600mm f/5.6-6.3 VR', #30
5512
- 43 => 'NIKKOR Z DX 24mm f/1.7', #28
5513
- 44 => 'NIKKOR Z 70-180mm f/2.8', #28
5514
- 45 => 'NIKKOR Z 600mm f/6.3 VR S', #28
5512
+ 43 => 'Nikkor Z DX 24mm f/1.7', #28
5513
+ 44 => 'Nikkor Z 70-180mm f/2.8', #28
5514
+ 45 => 'Nikkor Z 600mm f/6.3 VR S', #28
5515
5515
  46 => 'Nikkor Z 135mm f/1.8 S Plena', #28
5516
+ 48 => 'Nikkor Z 28-400mm f/4-8 VR', #30
5516
5517
  32768 => 'Nikkor Z 400mm f/2.8 TC VR S TC-1.4x', #28
5517
5518
  32769 => 'Nikkor Z 600mm f/4 TC VR S TC-1.4x', #28
5518
5519
  },
@@ -48,7 +48,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
48
48
  use Image::ExifTool::Exif;
49
49
  use Image::ExifTool::GPS;
50
50
 
51
- $VERSION = '2.95';
51
+ $VERSION = '2.96';
52
52
 
53
53
  sub ProcessMOV($$;$);
54
54
  sub ProcessKeys($$$);
@@ -6494,6 +6494,9 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
6494
6494
  },
6495
6495
  ownr => 'Owner', #PH (obscure) (ref ChrisAdan private communication)
6496
6496
  'xid ' => 'ISRC', #PH
6497
+ # found in DJI Osmo Action4 video
6498
+ tnal => { Name => 'ThumbnailImage', Groups => { 2 => 'Preview' } },
6499
+ snal => { Name => 'PreviewImage', Groups => { 2 => 'Preview' } },
6497
6500
  );
6498
6501
 
6499
6502
  # tag decoded from timed face records
@@ -338,6 +338,9 @@ my %insvLimit = (
338
338
  Groups => { 2 => 'Preview' },
339
339
  RawConv => '$self->ValidateImage(\$val,$tag)',
340
340
  },
341
+ # djmd - DJI AC003 Osmo Action 4 cam
342
+ #TODO djmd => { SubDirectory => { TagTable => 'Image::ExifTool::DJI::djmd', ByteOrder => 'Little-Endian' } },
343
+ # dbgi - DJI AC003 Osmo Action 4 cam -- lots more unknown stuff
341
344
  Unknown00 => { Unknown => 1 },
342
345
  Unknown01 => { Unknown => 1 },
343
346
  Unknown02 => { Unknown => 1 },
@@ -2428,7 +2431,9 @@ sub Process_nbmt($$$)
2428
2431
  $$et{DOC_NUM} = $$et{DOC_COUNT} + 1;
2429
2432
  delete $$et{UnknownTextCount};
2430
2433
  delete $$et{NoMoreTextDecoding};
2434
+ $$et{SET_GROUP1} = 'Nextbase';
2431
2435
  Process_text($et, $dataPt, $tagTbl, 1);
2436
+ delete $$et{SET_GROUP1};
2432
2437
  delete $$et{UnknownTextCount};
2433
2438
  delete $$et{NoMoreTextDecoding};
2434
2439
  delete $$et{DOC_NUM};