exiftool-vendored.pl 12.91.0 → 12.97.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,10 +7,65 @@ RSS feed: https://exiftool.org/rss.xml
7
7
  Note: The most recent production release is Version 12.76. (Other versions are
8
8
  considered development releases, and are not uploaded to MetaCPAN.)
9
9
 
10
+ Sept. 25, 2024 - Version 12.97
11
+
12
+ - Added ability to ignore up to 4095 bytes of garbage at the end of an INDD
13
+ file with the -m option
14
+ - Added a new Canon RFLensType value (thanks Norbert Wasser)
15
+ - Added a new Nikon Z LensID
16
+ - Decode a number of new Nikon Z6_3 tags (thanks Warren Hatch)
17
+ - Decode a few more FujiFilm tags (thanks Greybeard)
18
+ - Enhanced %C format code to allow file-name collisions to be avoided by using
19
+ a colon instead of a decimal in the format modifier
20
+ - Fixed bug which could result in hang when using %C code in an output file
21
+ name
22
+
23
+ Sept. 1, 2024 - Version 12.96
24
+
25
+ - More improvements to handling of trailers on video files (and add ability to
26
+ write videos which have an unknown trailer)
27
+ - Fixed problem geotagging from some newer Google Takeout files
28
+
29
+ Aug. 30, 2024 - Version 12.95
30
+
31
+ - Added a couple of new CanonModelID values
32
+ - Decode ColorData for a couple of new Canon models
33
+ - Fixed problem writing video files which have some known trailer types
34
+
35
+ Aug. 29, 2024 - Version 12.94
36
+
37
+ - Added ability to geotag from new-format Google Takeout JSON files
38
+ - Added a few new Android and Xiaomi QuickTime Keys tags
39
+ - Added ability to read C2PA JUMBF metadata from TTF/OTF files
40
+ - Internal changes to code for creating new directories
41
+ - Changed Windows packages to have the application help text file in the
42
+ exiftool_files folder instead of writing it to a temporary directory
43
+ - Removed new QuickTime Keys tags added in 12.93 because these aren't used in
44
+ top-level metadata (written to the video track by Apple devices)
45
+ - Fixed the group names for synthesized default-language QuickTime tags and
46
+ added a verbose message when generating these tags
47
+ - Fixed warning in Geolocation.t self test
48
+
49
+ Aug. 20, 2024 - Version 12.93
50
+
51
+ - Added a new Nikon LensID
52
+ - Added a couple of new OpenEXR Compression types
53
+ - Added a couple of new QuickTime Keys tags
54
+ - Decode timed metadata from E-ACE B44 dashcam videos
55
+ - Made "Unrecognized" Samsung Meta warnings minor
56
+ - Fixed bug in -listg6 option which resulted in "uninitialized value" warnings
57
+ - Fixed decoding of Func1Button and Func2Button for the Nikon Z6/Z7
58
+ - Fixed bug reading JUMB metadata from JXL images
59
+
60
+ July 24, 2024 - Version 12.92
61
+
62
+ - Removed -w from exiftool shebang due to compatibility issues on some systems
63
+
10
64
  July 24, 2024 - Version 12.91
11
65
 
12
- - Fixed 2 test files that were causing failed tests (ExifTool itself is
13
- unchanged)
66
+ - Added a couple of new OpenEXR Compression values (github#276)
67
+ - Updated 2 test files that were causing failed tests (ExifTool itself is
68
+ unchanged)
14
69
 
15
70
  July 24, 2024 - Version 12.90
16
71
 
@@ -21,7 +76,7 @@ July 24, 2024 - Version 12.90
21
76
  - Drop Nikon ShotInfo record when copying MakerNotes from NEF to JPG if it is
22
77
  larger than 50000 bytes (then MakerNotes would be too large for a single
23
78
  JPEG segment)
24
- - Changed exiftool shebang from "#!/usr/bin/perl" to "#!/usr/bin/env perl"
79
+ - Changed exiftool shebang to use env: "#!/usr/bin/env perl -w"
25
80
  - Revert change of 12.84 to iterate through sub-documents with the -p option
26
81
  only if -ee is used
27
82
 
package/bin/META.json CHANGED
@@ -50,5 +50,5 @@
50
50
  }
51
51
  },
52
52
  "release_status" : "stable",
53
- "version" : "12.91"
53
+ "version" : "12.97"
54
54
  }
package/bin/META.yml CHANGED
@@ -31,4 +31,4 @@ recommends:
31
31
  Time::HiRes: '0'
32
32
  requires:
33
33
  perl: '5.004'
34
- version: '12.91'
34
+ version: '12.97'
package/bin/README CHANGED
@@ -109,8 +109,8 @@ your home directory, then you would type the following commands in a
109
109
  terminal window to extract and run ExifTool:
110
110
 
111
111
  cd ~/Desktop
112
- gzip -dc Image-ExifTool-12.91.tar.gz | tar -xf -
113
- cd Image-ExifTool-12.91
112
+ gzip -dc Image-ExifTool-12.97.tar.gz | tar -xf -
113
+ cd Image-ExifTool-12.97
114
114
  ./exiftool t/images/ExifTool.jpg
115
115
 
116
116
  Note: These commands extract meta information from one of the test images.
package/bin/exiftool CHANGED
@@ -11,7 +11,7 @@ use strict;
11
11
  use warnings;
12
12
  require 5.004;
13
13
 
14
- my $version = '12.91';
14
+ my $version = '12.97';
15
15
 
16
16
  # add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
17
17
  my $exePath;
@@ -232,10 +232,6 @@ my $stayOpen = 0;
232
232
  my $rtnValApp = 0; # app return value (0=success)
233
233
  my $curTitle = ''; # current window title
234
234
 
235
- # lookup for O/S names which may use a backslash as a directory separator
236
- # (ref File::Spec of PathTools-3.2701)
237
- my %hasBackslash = ( MSWin32 => 1, os2 => 1, dos => 1, NetWare => 1, symbian => 1, cygwin => 1 );
238
-
239
235
  # lookup for O/S names which use CR/LF newlines
240
236
  my $isCRLF = { MSWin32 => 1, os2 => 1, dos => 1 }->{$^O};
241
237
 
@@ -1615,7 +1611,7 @@ if ($argFormat) {
1615
1611
  }
1616
1612
 
1617
1613
  # change to forward slashes if necessary in all filenames (like CleanFilename)
1618
- if ($hasBackslash{$^O}) {
1614
+ if (Image::ExifTool::IsPC()) {
1619
1615
  tr/\\/\// foreach @files;
1620
1616
  }
1621
1617
 
@@ -3774,7 +3770,7 @@ sub DoSetFromFile($$$)
3774
3770
  # Returns: nothing, but changes filename if necessary
3775
3771
  sub CleanFilename($)
3776
3772
  {
3777
- $_[0] =~ tr/\\/\// if $hasBackslash{$^O};
3773
+ $_[0] =~ tr/\\/\// if Image::ExifTool::IsPC();
3778
3774
  }
3779
3775
 
3780
3776
  #------------------------------------------------------------------------------
@@ -4097,7 +4093,7 @@ sub AbsPath($)
4097
4093
  $path = eval { Cwd::abs_path($file) };
4098
4094
  # make the delimiters and case consistent
4099
4095
  # (abs_path is very inconsistent about what it returns in Windows)
4100
- if (defined $path and $hasBackslash{$^O}) {
4096
+ if (defined $path and Image::ExifTool::IsPC()) {
4101
4097
  $path =~ tr/\\/\//;
4102
4098
  $path = lc $path;
4103
4099
  }
@@ -4305,17 +4301,20 @@ sub Num2Alpha($)
4305
4301
  sub NextUnusedFilename($;$)
4306
4302
  {
4307
4303
  my ($fmt, $okfile) = @_;
4308
- return $fmt unless $fmt =~ /%[-+]?\d*\.?\d*[lun]?[cC]/;
4304
+ return $fmt unless $fmt =~ /%[-+]?\d*[.:]?\d*[lun]?[cC]/;
4309
4305
  my %sep = ( '-' => '-', '+' => '_' );
4310
4306
  my ($copy, $alpha) = (0, 'a');
4307
+ my $lastFile;
4311
4308
  for (;;) {
4312
4309
  my ($filename, $pos) = ('', 0);
4313
- while ($fmt =~ /(%([-+]?)(\d*)(\.?)(\d*)([lun]?)([cC]))/g) {
4310
+ while ($fmt =~ /(%([-+]?)(\d*)([.:]?)(\d*)([lun]?)([cC]))/g) {
4314
4311
  $filename .= substr($fmt, $pos, pos($fmt) - $pos - length($1));
4315
4312
  $pos = pos($fmt);
4316
4313
  my ($sign, $wid, $dec, $wid2, $mod, $tok) = ($2, $3 || 0, $4, $5 || 0, $6, $7);
4317
4314
  my $seq;
4318
4315
  if ($tok eq 'C') {
4316
+ # increment sequence number for %C on collision if ':' is used
4317
+ $sign eq '-' ? ++$seqFileDir : ++$seqFileNum if $copy and $dec eq ':';
4319
4318
  $seq = $wid + ($sign eq '-' ? $seqFileDir : $seqFileNum) - 1;
4320
4319
  $wid = $wid2;
4321
4320
  } else {
@@ -4344,6 +4343,8 @@ sub NextUnusedFilename($;$)
4344
4343
  my ($fn, $ok) = (AbsPath($filename), AbsPath($okfile));
4345
4344
  return $okfile if defined $fn and defined $ok and $fn eq $ok;
4346
4345
  }
4346
+ return $filename if defined $lastFile and $lastFile eq $filename;
4347
+ $lastFile = $filename;
4347
4348
  ++$copy;
4348
4349
  ++$alpha;
4349
4350
  }
@@ -4353,46 +4354,21 @@ sub NextUnusedFilename($;$)
4353
4354
  # Create directory for specified file
4354
4355
  # Inputs: 0) complete file name including path
4355
4356
  # Returns: true if a directory was created
4356
- my $k32CreateDir;
4357
4357
  sub CreateDirectory($)
4358
4358
  {
4359
4359
  my $file = shift;
4360
- my ($dir, $created);
4361
- ($dir = $file) =~ s/[^\/]*$//; # remove filename from path specification
4362
- if ($dir and not $mt->IsDirectory($dir)) {
4363
- my @parts = split /\//, $dir;
4364
- $dir = '';
4365
- foreach (@parts) {
4366
- $dir .= $_;
4367
- if (length $dir and not $mt->IsDirectory($dir) and
4368
- # don't try to create a network drive root directory
4369
- not ($hasBackslash{$^O} and $dir =~ m{^//[^/]*$}))
4370
- {
4371
- my $success;
4372
- # create directory since it doesn't exist
4373
- my $d2 = $dir; # (must make a copy in case EncodeFileName recodes it)
4374
- if ($mt->EncodeFileName($d2)) {
4375
- # handle Windows Unicode directory names
4376
- unless (eval { require Win32::API }) {
4377
- Error('Install Win32::API to create directories with Unicode names');
4378
- return 0;
4379
- }
4380
- unless ($k32CreateDir) {
4381
- $k32CreateDir = Win32::API->new('KERNEL32', 'CreateDirectoryW', 'PP', 'I');
4382
- }
4383
- $success = $k32CreateDir->Call($d2, 0) if $k32CreateDir;
4384
- } else {
4385
- $success = mkdir($d2, 0777);
4386
- }
4387
- $success or Error("Error creating directory $dir\n"), return 0;
4388
- $verbose and print $vout "Created directory $dir\n";
4389
- $created = 1;
4390
- }
4391
- $dir .= '/';
4360
+ my $err = $mt->CreateDirectory($file);
4361
+ if (defined $err) {
4362
+ $err and Error("$err\n"), return 0;
4363
+ if ($verbose) {
4364
+ my $dir;
4365
+ ($dir = $file) =~ s(/[^/]*$)();
4366
+ print $vout "Created directory $dir\n";
4392
4367
  }
4393
- ++$countNewDir if $created;
4368
+ ++$countNewDir;
4369
+ return 1;
4394
4370
  }
4395
- return $created;
4371
+ return 0;
4396
4372
  }
4397
4373
 
4398
4374
  #------------------------------------------------------------------------------
@@ -4668,6 +4644,10 @@ sub PrintErrors($$$)
4668
4644
  return $$info{Error};
4669
4645
  }
4670
4646
 
4647
+ #=====================================================================================
4648
+ # NOTE: Be sure to update windows_exiftool.txt with any changes to this documentation!
4649
+ #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
4650
+
4671
4651
  __END__
4672
4652
 
4673
4653
  =head1 NAME
@@ -5199,16 +5179,14 @@ B<-struct> option for details.
5199
5179
  E<quot>'-I<DSTTAG>E<lt>I<SRCTAG>'E<quot>) is not the same as interpolating
5200
5180
  its value inside a string (ie. E<quot>'-I<DSTTAG>E<lt>$I<SRCTAG>'E<quot>)
5201
5181
  for source tags which are list-type tags,
5202
- L<shortcut tags|Image::ExifTool::Shortcuts>, tag names containing wildcards,
5203
- or UserParam variables. When copying directly, the values of each matching
5204
- source tag are copied individually to the destination tag (as if they were
5205
- separate assignments). However, when interpolated inside a string, list
5206
- items and the values of shortcut tags are concatenated (with a separator set
5207
- by the B<-sep> option), and wildcards are not allowed. Also, UserParam
5208
- variables are available only when interpolated in a string. Another
5209
- difference is that a minor warning is generated if a tag doesn't exist when
5210
- interpolating its value in a string (with C<$>), but isn't when copying the
5211
- tag directly.
5182
+ L<shortcut tags|Image::ExifTool::Shortcuts>, or tag names containing
5183
+ wildcards. When copying directly, the values of each matching source tag
5184
+ are copied individually to the destination tag (as if they were separate
5185
+ assignments). However, when interpolated inside a string, list items and
5186
+ the values of shortcut tags are concatenated (with a separator set by the
5187
+ B<-sep> option), and wildcards are not allowed.Another difference is that a
5188
+ minor warning is generated if a tag doesn't exist when interpolating its
5189
+ value in a string (with C<$>), but isn't when copying the tag directly.
5212
5190
 
5213
5191
  Finally, the behaviour is different when a destination tag or group of
5214
5192
  C<All> is used. When copying directly, a destination group and/or tag name
@@ -5684,7 +5662,7 @@ with this command:
5684
5662
 
5685
5663
  produces output like this:
5686
5664
 
5687
- -- Generated by ExifTool 12.91 --
5665
+ -- Generated by ExifTool 12.97 --
5688
5666
  File: a.jpg - 2003:10:31 15:44:19
5689
5667
  (f/5.6, 1/60s, ISO 100)
5690
5668
  File: b.jpg - 2006:05:23 11:57:38
@@ -5926,7 +5904,13 @@ A leading '-' causes the number to be reset at the start of each new
5926
5904
  directory (in the original directory structure if the files are being
5927
5905
  moved), and '+' has no effect. The number before the decimal place gives
5928
5906
  the starting index, the number after the decimal place gives the field
5929
- width. The following examples show the output filenames when used with the
5907
+ width. To preserve synchronization with the processed file number, by
5908
+ default the copy number is not incremented to avoid file name collisions, so
5909
+ any existing same-named file will cause an error. However using a colon
5910
+ instead of a decimal point causes the number to be incremented to avoid
5911
+ collisions with existing files.
5912
+
5913
+ The following examples show the output filenames when used with the
5930
5914
  command C<exiftool rose.jpg star.jpg jet.jpg ...>:
5931
5915
 
5932
5916
  -w %C%f.txt # 0rose.txt, 1star.txt, 2jet.txt
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
88
88
  sub ProcessExifInfo($$$);
89
89
  sub SwapWords($);
90
90
 
91
- $VERSION = '4.79';
91
+ $VERSION = '4.81';
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)
@@ -995,6 +995,8 @@ $VERSION = '4.79';
995
995
  0x80000481 => 'EOS R6 Mark II', #42
996
996
  0x80000487 => 'EOS R8', #42
997
997
  0x80000491 => 'PowerShot V10', #25
998
+ 0x80000495 => 'EOS R1', #PH
999
+ 0x80000496 => 'R5 Mark II', #forum16406
998
1000
  0x80000498 => 'EOS R100', #25
999
1001
  0x80000520 => 'EOS D2000C', #IB
1000
1002
  0x80000560 => 'EOS D6000C', #PH (guess)
@@ -1978,6 +1980,11 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
1978
1980
  Name => 'ColorData11',
1979
1981
  SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData11' },
1980
1982
  },
1983
+ { # (int16u[4528]) - R1/R5mkII ref forum16406
1984
+ Condition => '$count == 4528',
1985
+ Name => 'ColorData12',
1986
+ SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData12' },
1987
+ },
1981
1988
  {
1982
1989
  Name => 'ColorDataUnknown',
1983
1990
  SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorDataUnknown' },
@@ -6992,6 +6999,7 @@ my %ciMaxFocal = (
6992
6999
  314 => 'Canon RF 24-105mm F2.8 L IS USM Z', #42
6993
7000
  315 => 'Canon RF-S 10-18mm F4.5-6.3 IS STM', #42
6994
7001
  316 => 'Canon RF 35mm F1.4 L VCM', #42
7002
+ 318 => 'Canon RF 28-70mm F2.8 IS STM', #42
6995
7003
  # Note: add new RF lenses to %canonLensTypes with ID 61182
6996
7004
  },
6997
7005
  },
@@ -8613,6 +8621,126 @@ my %ciMaxFocal = (
8613
8621
  },
8614
8622
  );
8615
8623
 
8624
+ # Color data (MakerNotes tag 0x4001, count=4528, ref PH)
8625
+ %Image::ExifTool::Canon::ColorData12 = (
8626
+ %binaryDataAttrs,
8627
+ NOTES => 'These tags are used by the EOS R1 and R5mkII',
8628
+ FORMAT => 'int16s',
8629
+ FIRST_ENTRY => 0,
8630
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8631
+ DATAMEMBER => [ 0 ],
8632
+ IS_SUBDIR => [ 0x140 ],
8633
+ 0x00 => {
8634
+ Name => 'ColorDataVersion',
8635
+ DataMember => 'ColorDataVersion',
8636
+ RawConv => '$$self{ColorDataVersion} = $val',
8637
+ PrintConv => {
8638
+ 64 => '64 (R1, R5 Mark II)',
8639
+ },
8640
+ },
8641
+ 0x69 => { Name => 'WB_RGGBLevelsAsShot', Format => 'int16s[4]' }, # (NC)
8642
+ 0x6d => 'ColorTempAsShot', # (NC)
8643
+ 0x6e => { Name => 'WB_RGGBLevelsDaylight', Format => 'int16s[4]' },
8644
+ 0x72 => 'ColorTempDaylight',
8645
+ 0x73 => { Name => 'WB_RGGBLevelsShade', Format => 'int16s[4]' },
8646
+ 0x77 => 'ColorTempShade',
8647
+ 0x78 => { Name => 'WB_RGGBLevelsCloudy', Format => 'int16s[4]' },
8648
+ 0x7c => 'ColorTempCloudy',
8649
+ 0x7d => { Name => 'WB_RGGBLevelsTungsten', Format => 'int16s[4]' },
8650
+ 0x81 => 'ColorTempTungsten',
8651
+ 0x82 => { Name => 'WB_RGGBLevelsFluorescent',Format=> 'int16s[4]' },
8652
+ 0x86 => 'ColorTempFluorescent' ,
8653
+ 0x87 => { Name => 'WB_RGGBLevelsFlash', Format => 'int16s[4]' },
8654
+ 0x8b => 'ColorTempFlash',
8655
+ 0x8c => { Name => 'WB_RGGBLevelsUnknown2', Format => 'int16s[4]', Unknown => 1 },
8656
+ 0x90 => { Name => 'ColorTempUnknown2', Unknown => 1 },
8657
+ 0x91 => { Name => 'WB_RGGBLevelsUnknown3', Format => 'int16s[4]', Unknown => 1 },
8658
+ 0x95 => { Name => 'ColorTempUnknown3', Unknown => 1 },
8659
+ 0x96 => { Name => 'WB_RGGBLevelsUnknown4', Format => 'int16s[4]', Unknown => 1 },
8660
+ 0x9a => { Name => 'ColorTempUnknown4', Unknown => 1 },
8661
+ 0x9b => { Name => 'WB_RGGBLevelsUnknown5', Format => 'int16s[4]', Unknown => 1 },
8662
+ 0x9f => { Name => 'ColorTempUnknown5', Unknown => 1 },
8663
+ 0xa0 => { Name => 'WB_RGGBLevelsUnknown6', Format => 'int16s[4]', Unknown => 1 },
8664
+ 0xa4 => { Name => 'ColorTempUnknown6', Unknown => 1 },
8665
+ 0xa5 => { Name => 'WB_RGGBLevelsUnknown7', Format => 'int16s[4]', Unknown => 1 },
8666
+ 0xa9 => { Name => 'ColorTempUnknown7', Unknown => 1 },
8667
+ 0xaa => { Name => 'WB_RGGBLevelsUnknown8', Format => 'int16s[4]', Unknown => 1 },
8668
+ 0xae => { Name => 'ColorTempUnknown8', Unknown => 1 },
8669
+ 0xaf => { Name => 'WB_RGGBLevelsUnknown9', Format => 'int16s[4]', Unknown => 1 },
8670
+ 0xb3 => { Name => 'ColorTempUnknown9', Unknown => 1 },
8671
+ 0xb4 => { Name => 'WB_RGGBLevelsUnknown10', Format => 'int16s[4]', Unknown => 1 },
8672
+ 0xb8 => { Name => 'ColorTempUnknown10', Unknown => 1 },
8673
+ 0xb9 => { Name => 'WB_RGGBLevelsUnknown11', Format => 'int16s[4]', Unknown => 1 },
8674
+ 0xbd => { Name => 'ColorTempUnknown11', Unknown => 1 },
8675
+ 0xbe => { Name => 'WB_RGGBLevelsUnknown12', Format => 'int16s[4]', Unknown => 1 },
8676
+ 0xc2 => { Name => 'ColorTempUnknown12', Unknown => 1 },
8677
+ 0xc3 => { Name => 'WB_RGGBLevelsUnknown13', Format => 'int16s[4]', Unknown => 1 },
8678
+ 0xc7 => { Name => 'ColorTempUnknown13', Unknown => 1 },
8679
+ 0xc8 => { Name => 'WB_RGGBLevelsUnknown14', Format => 'int16s[4]', Unknown => 1 },
8680
+ 0xcc => { Name => 'ColorTempUnknown14', Unknown => 1 },
8681
+ 0xcd => { Name => 'WB_RGGBLevelsUnknown15', Format => 'int16s[4]', Unknown => 1 },
8682
+ 0xd1 => { Name => 'ColorTempUnknown15', Unknown => 1 },
8683
+ 0xd2 => { Name => 'WB_RGGBLevelsUnknown16', Format => 'int16s[4]', Unknown => 1 },
8684
+ 0xd6 => { Name => 'ColorTempUnknown16', Unknown => 1 },
8685
+ 0xd7 => { Name => 'WB_RGGBLevelsUnknown17', Format => 'int16s[4]', Unknown => 1 },
8686
+ 0xdb => { Name => 'ColorTempUnknown17', Unknown => 1 },
8687
+ 0xdc => { Name => 'WB_RGGBLevelsUnknown18', Format => 'int16s[4]', Unknown => 1 },
8688
+ 0xe0 => { Name => 'ColorTempUnknown18', Unknown => 1 },
8689
+ 0xe1 => { Name => 'WB_RGGBLevelsUnknown19', Format => 'int16s[4]', Unknown => 1 },
8690
+ 0xe5 => { Name => 'ColorTempUnknown19', Unknown => 1 },
8691
+ 0xe6 => { Name => 'WB_RGGBLevelsUnknown20', Format => 'int16s[4]', Unknown => 1 },
8692
+ 0xea => { Name => 'ColorTempUnknown20', Unknown => 1 },
8693
+ 0xeb => { Name => 'WB_RGGBLevelsUnknown21', Format => 'int16s[4]', Unknown => 1 },
8694
+ 0xef => { Name => 'ColorTempUnknown21', Unknown => 1 },
8695
+ 0xf0 => { Name => 'WB_RGGBLevelsUnknown22', Format => 'int16s[4]', Unknown => 1 },
8696
+ 0xf4 => { Name => 'ColorTempUnknown22', Unknown => 1 },
8697
+ 0xf5 => { Name => 'WB_RGGBLevelsUnknown23', Format => 'int16s[4]', Unknown => 1 },
8698
+ 0xf9 => { Name => 'ColorTempUnknown23', Unknown => 1 },
8699
+ 0xfa => { Name => 'WB_RGGBLevelsUnknown24', Format => 'int16s[4]', Unknown => 1 },
8700
+ 0xfe => { Name => 'ColorTempUnknown24', Unknown => 1 },
8701
+ 0xff => { Name => 'WB_RGGBLevelsUnknown25', Format => 'int16s[4]', Unknown => 1 },
8702
+ 0x103 => { Name => 'ColorTempUnknown25', Unknown => 1 },
8703
+ 0x104 => { Name => 'WB_RGGBLevelsUnknown26',Format => 'int16s[4]', Unknown => 1 },
8704
+ 0x108 => { Name => 'ColorTempUnknown26', Unknown => 1 },
8705
+ 0x109 => { Name => 'WB_RGGBLevelsUnknown27',Format => 'int16s[4]', Unknown => 1 },
8706
+ 0x10d => { Name => 'ColorTempUnknown27', Unknown => 1 },
8707
+ 0x10e => { Name => 'WB_RGGBLevelsUnknown28',Format => 'int16s[4]', Unknown => 1 },
8708
+ 0x112 => { Name => 'ColorTempUnknown28', Unknown => 1 },
8709
+ 0x113 => { Name => 'WB_RGGBLevelsUnknown29',Format => 'int16s[4]', Unknown => 1 },
8710
+ 0x117 => { Name => 'ColorTempUnknown29', Unknown => 1 },
8711
+ 0x118 => { Name => 'WB_RGGBLevelsUnknown30',Format => 'int16s[4]', Unknown => 1 },
8712
+ 0x11c => { Name => 'ColorTempUnknown30', Unknown => 1 },
8713
+ 0x11d => { Name => 'WB_RGGBLevelsUnknown31',Format => 'int16s[4]', Unknown => 1 },
8714
+ 0x121 => { Name => 'ColorTempUnknown31', Unknown => 1 },
8715
+ 0x122 => { Name => 'WB_RGGBLevelsUnknown32',Format => 'int16s[4]', Unknown => 1 },
8716
+ 0x126 => { Name => 'ColorTempUnknown32', Unknown => 1 },
8717
+ 0x127 => { Name => 'WB_RGGBLevelsUnknown33',Format => 'int16s[4]', Unknown => 1 },
8718
+ 0x12b => { Name => 'ColorTempUnknown33', Unknown => 1 },
8719
+ 0x140 => {
8720
+ Name => 'ColorCalib',
8721
+ Format => 'undef[120]',
8722
+ Unknown => 1,
8723
+ SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
8724
+ },
8725
+ 0x17f => {
8726
+ Name => 'PerChannelBlackLevel',
8727
+ Format => 'int16u[4]',
8728
+ },
8729
+ 0x294 => {
8730
+ Name => 'NormalWhiteLevel',
8731
+ Format => 'int16u',
8732
+ RawConv => '$val || undef',
8733
+ },
8734
+ 0x295 => {
8735
+ Name => 'SpecularWhiteLevel',
8736
+ Format => 'int16u',
8737
+ },
8738
+ 0x296 => {
8739
+ Name => 'LinearityUpperMargin',
8740
+ Format => 'int16u',
8741
+ },
8742
+ );
8743
+
8616
8744
  # Unknown color data (MakerNotes tag 0x4001)
8617
8745
  %Image::ExifTool::Canon::ColorDataUnknown = (
8618
8746
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
@@ -9199,14 +9327,19 @@ my %filterConv = (
9199
9327
  PrintConvInv => '$val=~s/\s*mm//;$val',
9200
9328
  },
9201
9329
  8 => {
9202
- Name => 'MinFocalLength',
9330
+ Name => 'MinFocalLength2',
9331
+ Notes => q{
9332
+ these seem to be min/max focal length without teleconverter, as opposed to
9333
+ MinFocalLength and MaxFocalLength which include the effect of a
9334
+ teleconverter
9335
+ }, #forum16309
9203
9336
  ValueConv => '$val / 10',
9204
9337
  ValueConvInv => 'int($val * 10 + 0.5)',
9205
9338
  PrintConv => '"$val mm"',
9206
9339
  PrintConvInv => '$val=~s/\s*mm//;$val',
9207
9340
  },
9208
9341
  9 => {
9209
- Name => 'MaxFocalLength',
9342
+ Name => 'MaxFocalLength2',
9210
9343
  ValueConv => '$val / 10',
9211
9344
  ValueConvInv => 'int($val * 10 + 0.5)',
9212
9345
  PrintConv => '"$val mm"',
@@ -19,7 +19,7 @@ use strict;
19
19
  use vars qw($VERSION %ttLang);
20
20
  use Image::ExifTool qw(:DataAccess :Utils);
21
21
 
22
- $VERSION = '1.10';
22
+ $VERSION = '1.11';
23
23
 
24
24
  sub ProcessOTF($$);
25
25
 
@@ -189,6 +189,9 @@ my %ttCharset = (
189
189
  name => {
190
190
  SubDirectory => { TagTable => 'Image::ExifTool::Font::Name' },
191
191
  },
192
+ C2PA => {
193
+ SubDirectory => { TagTable => 'Image::ExifTool::Jpeg2000::Main', Start => 20 },
194
+ },
192
195
  PFM => {
193
196
  Name => 'PFMHeader',
194
197
  SubDirectory => { TagTable => 'Image::ExifTool::Font::PFM' },
@@ -389,10 +392,12 @@ sub ProcessOTF($$)
389
392
  $$et{INDENT} .= '| ';
390
393
  $et->VerboseDir('TrueType', $numTables) if $verbose;
391
394
 
395
+ my %processTag = ( name => 1, C2PA => 1 ); # tags to process (skip all others)
396
+
392
397
  for ($pos=0; $pos<$len; $pos+=16) {
393
- # look for 'name' table
398
+ # look for tags to process
394
399
  my $tag = substr($tbl, $pos, 4);
395
- next unless $tag eq 'name' or $verbose;
400
+ next unless $processTag{$tag} or $verbose;
396
401
  my $offset = Get32u(\$tbl, $pos + 8);
397
402
  my $size = Get32u(\$tbl, $pos + 12);
398
403
  unless ($raf->Seek($offset+$base, 0) and $raf->Read($buff, $size) == $size) {
@@ -405,9 +410,15 @@ sub ProcessOTF($$)
405
410
  $$et{INDENT}, $pos/16, $tag, $offset, $size);
406
411
  $et->VPrint(0, $str);
407
412
  $et->VerboseDump(\$buff, Addr => $offset) if $verbose > 2;
408
- next unless $tag eq 'name';
413
+ next unless $processTag{$tag};
409
414
  }
410
415
  next unless $size >= 8;
416
+ unless ($tag eq 'name') {
417
+ my $tagTablePtr = GetTagTable('Image::ExifTool::Font::Main');
418
+ $et->HandleTag($tagTablePtr, $tag, undef, DataPt => \$buff, Size => length($buff));
419
+ next;
420
+ }
421
+ # process the 'name' tag
411
422
  my $entries = Get16u(\$buff, 2);
412
423
  my $recEnd = 6 + $entries * 12;
413
424
  if ($recEnd > $size) {
@@ -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.95';
34
+ $VERSION = '1.96';
35
35
 
36
36
  sub ProcessFujiDir($$$);
37
37
  sub ProcessFaceRec($$$);
@@ -1252,6 +1252,28 @@ my %faceCategories = (
1252
1252
  ValueConv => 'my @v=reverse split(" ",$val);"@v"', # reverse to show width first
1253
1253
  PrintConv => '$val=~tr/ /:/; $val',
1254
1254
  },
1255
+ 0x117 => {
1256
+ Name => 'RawZoomActive',
1257
+ Format => 'int32u',
1258
+ Count => 1,
1259
+ PrintConv => { 0 => 'No', 1 => 'Yes' },
1260
+ },
1261
+ 0x118 => {
1262
+ Name => 'RawZoomTopLeft',
1263
+ Format => 'int16u',
1264
+ Count => 2,
1265
+ Notes => 'relative to RawCroppedImageSize',
1266
+ ValueConv => 'my @v=reverse split(" ",$val);"@v"', # reverse to show width first
1267
+ PrintConv => '$val=~tr/ /x/; $val',
1268
+ },
1269
+ 0x119 => {
1270
+ Name => 'RawZoomSize',
1271
+ Format => 'int16u',
1272
+ Count => 2,
1273
+ Notes => 'relative to RawCroppedImageSize',
1274
+ ValueConv => 'my @v=reverse split(" ",$val);"@v"', # reverse to show width first
1275
+ PrintConv => '$val=~tr/ /x/; $val',
1276
+ },
1255
1277
  0x121 => [
1256
1278
  {
1257
1279
  Name => 'RawImageSize',
@@ -16,6 +16,7 @@
16
16
  # 2020/12/01 - PH Added ability to read DJI CSV log files
17
17
  # 2022/06/21 - PH Added ability to read Google Takeout JSON files
18
18
  # 2024/04/23 - PH Added ability to read more OpenTracks GPS tags
19
+ # 2024/08/28 - PH Added support for new Google Takeout JSON format
19
20
  #
20
21
  # References: 1) http://www.topografix.com/GPX/1/1/
21
22
  # 2) http://www.gpsinformation.org/dale/nmea.htm#GSA
@@ -30,7 +31,7 @@ use vars qw($VERSION);
30
31
  use Image::ExifTool qw(:Public);
31
32
  use Image::ExifTool::GPS;
32
33
 
33
- $VERSION = '1.76';
34
+ $VERSION = '1.78';
34
35
 
35
36
  sub JITTER() { return 2 } # maximum time jitter
36
37
 
@@ -151,7 +152,7 @@ sub LoadTrackLog($$;$)
151
152
  my ($raf, $from, $time, $isDate, $noDate, $noDateChanged, $lastDate, $dateFlarm);
152
153
  my ($nmeaStart, $fixSecs, @fixTimes, $lastFix, %nmea, @csvHeadings, $sortFixes);
153
154
  my ($canCut, $cutPDOP, $cutHDOP, $cutSats, $e0, $e1, @tmp, $trackFile, $trackTime);
154
- my $scaleSpeed;
155
+ my ($scaleSpeed, $startTime);
155
156
 
156
157
  unless (eval { require Time::Local }) {
157
158
  return 'Geotag feature requires Time::Local installed';
@@ -318,10 +319,13 @@ sub LoadTrackLog($$;$)
318
319
  }
319
320
  }
320
321
  next;
321
- } elsif (/"(timelineObjects|placeVisit|activitySegment|latitudeE7)":/) {
322
+ } elsif (/"(timelineObjects|placeVisit|activitySegment|latitudeE7)"\s*:/) {
322
323
  # Google Takeout JSON format
323
324
  $format = 'JSON';
324
325
  $sortFixes = 1; # (fixes are not all in order for this format)
326
+ } elsif (/"(durationMinutesOffsetFromStartTime|startTime)"\s*:/) {
327
+ $format = 'JSON'; # new Google Takeout JSON format (fixes seem to be in order)
328
+ $raf->Seek(0,0); # rewind to start of file
325
329
  } else {
326
330
  # search only first 50 lines of file for a valid fix
327
331
  last if ++$skipped > 50;
@@ -558,14 +562,24 @@ DoneFix: $isDate = 1;
558
562
  next;
559
563
  } elsif ($format eq 'JSON') {
560
564
  # Google Takeout JSON format
561
- if (/"(latitudeE7|longitudeE7|latE7|lngE7|timestamp)":\s*"?(.*?)"?,?\s*[\x0d\x0a]/) {
565
+ if (/"(latitudeE7|longitudeE7|latE7|lngE7|timestamp|startTime|point|durationMinutesOffsetFromStartTime)"\s*:\s*"?(.*?)"?,?\s*[\x0d\x0a]/) {
562
566
  if ($1 eq 'timestamp') {
563
567
  $time = GetTime($2);
564
568
  goto DoneFix if $time and $$fix{lat} and $$fix{lon};
569
+ } elsif ($1 eq 'startTime') { # (new format)
570
+ $startTime = GetTime($2);
565
571
  } elsif ($1 eq 'latitudeE7' or $1 eq 'latE7') {
566
572
  $$fix{lat} = $2 * 1e-7;
567
- } else {
573
+ } elsif ($1 eq 'longitudeE7' or $1 eq 'lngE7') {
568
574
  $$fix{lon} = $2 * 1e-7;
575
+ } elsif ($1 eq 'point') { # (new format)
576
+ my $point = $2;
577
+ my @coords = $point =~ /[-+]?\d+\.\d+/g;
578
+ @$fix{'lat','lon'} = @coords[0,1] if @coords == 2;
579
+ } elsif ($1 eq 'durationMinutesOffsetFromStartTime' and defined $startTime) { # (new format)
580
+ $time = $startTime + $2 * 60;
581
+ # note: this assumes that "point" comes first, which it does in my sample
582
+ goto DoneFix if $time and $$fix{lat} and $$fix{lon};
569
583
  }
570
584
  }
571
585
  next;