exiftool_vendored 12.93.0 → 12.95.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 30869a5b033fa93062cf6f635c5cddb484e8ce9671e8b5b803329edf5d34ee7a
4
- data.tar.gz: 0b886b032d88c6cf22d4052795a6bbc4bd69cc33e40c8a4e308359e5d4ae454f
3
+ metadata.gz: 32e8098c5012682e4371e1eddf6e7e27f93d06967e776de0451b095e12fb34b1
4
+ data.tar.gz: e11e51bed28f32b6bdf52f68c96851bf9be0e98055b0e85418c486a00bef1cd2
5
5
  SHA512:
6
- metadata.gz: 4c563c23c4d432f21bbf8ae3ce284fbb7c325540a92bb6c7dd1a693afbe16d3e091b015779094e2f2db5d70ef1e73bc4bc4fb34d8044cb2ae62fa992dc7a085f
7
- data.tar.gz: 8a6cfea51bf26dff8cec28964277ea72446fc6ec3eb877f0c8082c8362dee69b9cb421253af1f3f8b073d067e5b29acb0364ed580ce346880c6541a945a7a706
6
+ metadata.gz: 409117e3d0b35ffb614af116f9fc7a9440ff2b15a5a46cc635dea749c4a232c22674ccfa0ae11d5bcbd7b2fab734507b8cd379b1b5fd7d3ac31ebc967564831f
7
+ data.tar.gz: bf6761f92ccccd7ad44b2d73875d4ab5d25693b7f3e9c11ec9b63414656906e7e2924eb5b8430144b53dd538e07f9e07916ac1dfd31f4b91b7b54e92f6124d87
data/bin/Changes CHANGED
@@ -7,13 +7,33 @@ 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
+ Aug. 30, 2024 - Version 12.95
11
+
12
+ - Added a couple of new CanonModelID values
13
+ - Decode ColorData for a couple of new Canon models
14
+ - Fixed problem writing video files which have some known trailer types
15
+
16
+ Aug. 29, 2024 - Version 12.94
17
+
18
+ - Added ability to geotag from new-format Google Takeout JSON files
19
+ - Added a few new Android and Xiaomi QuickTime Keys tags
20
+ - Added ability to read C2PA JUMBF metadata from TTF/OTF files
21
+ - Internal changes to code for creating new directories
22
+ - Changed Windows packages to have the application help text file in the
23
+ exiftool_files folder instead of writing it to a temporary directory
24
+ - Removed new QuickTime Keys tags added in 12.93 because these aren't used in
25
+ top-level metadata (written to the video track by Apple devices)
26
+ - Fixed the group names for synthesized default-language QuickTime tags and
27
+ added a verbose message when generating these tags
28
+ - Fixed warning in Geolocation.t self test
29
+
10
30
  Aug. 20, 2024 - Version 12.93
11
31
 
12
32
  - Added a new Nikon LensID
13
33
  - Added a couple of new OpenEXR Compression types
14
34
  - Added a couple of new QuickTime Keys tags
15
- - Decode timed metadata from E-ACE B44 DashCam videos
16
- - Make "Unrecognized" Samsung Meta warnings minor
35
+ - Decode timed metadata from E-ACE B44 dashcam videos
36
+ - Made "Unrecognized" Samsung Meta warnings minor
17
37
  - Fixed bug in -listg6 option which resulted in "uninitialized value" warnings
18
38
  - Fixed decoding of Func1Button and Func2Button for the Nikon Z6/Z7
19
39
  - Fixed bug reading JUMB metadata from JXL images
data/bin/META.json CHANGED
@@ -50,5 +50,5 @@
50
50
  }
51
51
  },
52
52
  "release_status" : "stable",
53
- "version" : "12.93"
53
+ "version" : "12.95"
54
54
  }
data/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.93'
34
+ version: '12.95'
data/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.93.tar.gz | tar -xf -
113
- cd Image-ExifTool-12.93
112
+ gzip -dc Image-ExifTool-12.95.tar.gz | tar -xf -
113
+ cd Image-ExifTool-12.95
114
114
  ./exiftool t/images/ExifTool.jpg
115
115
 
116
116
  Note: These commands extract meta information from one of the test images.
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.93';
14
+ my $version = '12.95';
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
  }
@@ -4353,46 +4349,21 @@ sub NextUnusedFilename($;$)
4353
4349
  # Create directory for specified file
4354
4350
  # Inputs: 0) complete file name including path
4355
4351
  # Returns: true if a directory was created
4356
- my $k32CreateDir;
4357
4352
  sub CreateDirectory($)
4358
4353
  {
4359
4354
  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 .= '/';
4355
+ my $err = $mt->CreateDirectory($file);
4356
+ if (defined $err) {
4357
+ $err and Error("$err\n"), return 0;
4358
+ if ($verbose) {
4359
+ my $dir;
4360
+ ($dir = $file) =~ s(/[^/]*$)();
4361
+ print $vout "Created directory $dir\n";
4392
4362
  }
4393
- ++$countNewDir if $created;
4363
+ ++$countNewDir;
4364
+ return 1;
4394
4365
  }
4395
- return $created;
4366
+ return 0;
4396
4367
  }
4397
4368
 
4398
4369
  #------------------------------------------------------------------------------
@@ -5684,7 +5655,7 @@ with this command:
5684
5655
 
5685
5656
  produces output like this:
5686
5657
 
5687
- -- Generated by ExifTool 12.93 --
5658
+ -- Generated by ExifTool 12.95 --
5688
5659
  File: a.jpg - 2003:10:31 15:44:19
5689
5660
  (f/5.6, 1/60s, ISO 100)
5690
5661
  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.80';
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.80';
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' },
@@ -8613,6 +8620,126 @@ my %ciMaxFocal = (
8613
8620
  },
8614
8621
  );
8615
8622
 
8623
+ # Color data (MakerNotes tag 0x4001, count=4528, ref PH)
8624
+ %Image::ExifTool::Canon::ColorData12 = (
8625
+ %binaryDataAttrs,
8626
+ NOTES => 'These tags are used by the EOS R1 and R5mkII',
8627
+ FORMAT => 'int16s',
8628
+ FIRST_ENTRY => 0,
8629
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
8630
+ DATAMEMBER => [ 0 ],
8631
+ IS_SUBDIR => [ 0x140 ],
8632
+ 0x00 => {
8633
+ Name => 'ColorDataVersion',
8634
+ DataMember => 'ColorDataVersion',
8635
+ RawConv => '$$self{ColorDataVersion} = $val',
8636
+ PrintConv => {
8637
+ 64 => '64 (R1, R5 Mark II)',
8638
+ },
8639
+ },
8640
+ 0x69 => { Name => 'WB_RGGBLevelsAsShot', Format => 'int16s[4]' }, # (NC)
8641
+ 0x6d => 'ColorTempAsShot', # (NC)
8642
+ 0x6e => { Name => 'WB_RGGBLevelsDaylight', Format => 'int16s[4]' },
8643
+ 0x72 => 'ColorTempDaylight',
8644
+ 0x73 => { Name => 'WB_RGGBLevelsShade', Format => 'int16s[4]' },
8645
+ 0x77 => 'ColorTempShade',
8646
+ 0x78 => { Name => 'WB_RGGBLevelsCloudy', Format => 'int16s[4]' },
8647
+ 0x7c => 'ColorTempCloudy',
8648
+ 0x7d => { Name => 'WB_RGGBLevelsTungsten', Format => 'int16s[4]' },
8649
+ 0x81 => 'ColorTempTungsten',
8650
+ 0x82 => { Name => 'WB_RGGBLevelsFluorescent',Format=> 'int16s[4]' },
8651
+ 0x86 => 'ColorTempFluorescent' ,
8652
+ 0x87 => { Name => 'WB_RGGBLevelsFlash', Format => 'int16s[4]' },
8653
+ 0x8b => 'ColorTempFlash',
8654
+ 0x8c => { Name => 'WB_RGGBLevelsUnknown2', Format => 'int16s[4]', Unknown => 1 },
8655
+ 0x90 => { Name => 'ColorTempUnknown2', Unknown => 1 },
8656
+ 0x91 => { Name => 'WB_RGGBLevelsUnknown3', Format => 'int16s[4]', Unknown => 1 },
8657
+ 0x95 => { Name => 'ColorTempUnknown3', Unknown => 1 },
8658
+ 0x96 => { Name => 'WB_RGGBLevelsUnknown4', Format => 'int16s[4]', Unknown => 1 },
8659
+ 0x9a => { Name => 'ColorTempUnknown4', Unknown => 1 },
8660
+ 0x9b => { Name => 'WB_RGGBLevelsUnknown5', Format => 'int16s[4]', Unknown => 1 },
8661
+ 0x9f => { Name => 'ColorTempUnknown5', Unknown => 1 },
8662
+ 0xa0 => { Name => 'WB_RGGBLevelsUnknown6', Format => 'int16s[4]', Unknown => 1 },
8663
+ 0xa4 => { Name => 'ColorTempUnknown6', Unknown => 1 },
8664
+ 0xa5 => { Name => 'WB_RGGBLevelsUnknown7', Format => 'int16s[4]', Unknown => 1 },
8665
+ 0xa9 => { Name => 'ColorTempUnknown7', Unknown => 1 },
8666
+ 0xaa => { Name => 'WB_RGGBLevelsUnknown8', Format => 'int16s[4]', Unknown => 1 },
8667
+ 0xae => { Name => 'ColorTempUnknown8', Unknown => 1 },
8668
+ 0xaf => { Name => 'WB_RGGBLevelsUnknown9', Format => 'int16s[4]', Unknown => 1 },
8669
+ 0xb3 => { Name => 'ColorTempUnknown9', Unknown => 1 },
8670
+ 0xb4 => { Name => 'WB_RGGBLevelsUnknown10', Format => 'int16s[4]', Unknown => 1 },
8671
+ 0xb8 => { Name => 'ColorTempUnknown10', Unknown => 1 },
8672
+ 0xb9 => { Name => 'WB_RGGBLevelsUnknown11', Format => 'int16s[4]', Unknown => 1 },
8673
+ 0xbd => { Name => 'ColorTempUnknown11', Unknown => 1 },
8674
+ 0xbe => { Name => 'WB_RGGBLevelsUnknown12', Format => 'int16s[4]', Unknown => 1 },
8675
+ 0xc2 => { Name => 'ColorTempUnknown12', Unknown => 1 },
8676
+ 0xc3 => { Name => 'WB_RGGBLevelsUnknown13', Format => 'int16s[4]', Unknown => 1 },
8677
+ 0xc7 => { Name => 'ColorTempUnknown13', Unknown => 1 },
8678
+ 0xc8 => { Name => 'WB_RGGBLevelsUnknown14', Format => 'int16s[4]', Unknown => 1 },
8679
+ 0xcc => { Name => 'ColorTempUnknown14', Unknown => 1 },
8680
+ 0xcd => { Name => 'WB_RGGBLevelsUnknown15', Format => 'int16s[4]', Unknown => 1 },
8681
+ 0xd1 => { Name => 'ColorTempUnknown15', Unknown => 1 },
8682
+ 0xd2 => { Name => 'WB_RGGBLevelsUnknown16', Format => 'int16s[4]', Unknown => 1 },
8683
+ 0xd6 => { Name => 'ColorTempUnknown16', Unknown => 1 },
8684
+ 0xd7 => { Name => 'WB_RGGBLevelsUnknown17', Format => 'int16s[4]', Unknown => 1 },
8685
+ 0xdb => { Name => 'ColorTempUnknown17', Unknown => 1 },
8686
+ 0xdc => { Name => 'WB_RGGBLevelsUnknown18', Format => 'int16s[4]', Unknown => 1 },
8687
+ 0xe0 => { Name => 'ColorTempUnknown18', Unknown => 1 },
8688
+ 0xe1 => { Name => 'WB_RGGBLevelsUnknown19', Format => 'int16s[4]', Unknown => 1 },
8689
+ 0xe5 => { Name => 'ColorTempUnknown19', Unknown => 1 },
8690
+ 0xe6 => { Name => 'WB_RGGBLevelsUnknown20', Format => 'int16s[4]', Unknown => 1 },
8691
+ 0xea => { Name => 'ColorTempUnknown20', Unknown => 1 },
8692
+ 0xeb => { Name => 'WB_RGGBLevelsUnknown21', Format => 'int16s[4]', Unknown => 1 },
8693
+ 0xef => { Name => 'ColorTempUnknown21', Unknown => 1 },
8694
+ 0xf0 => { Name => 'WB_RGGBLevelsUnknown22', Format => 'int16s[4]', Unknown => 1 },
8695
+ 0xf4 => { Name => 'ColorTempUnknown22', Unknown => 1 },
8696
+ 0xf5 => { Name => 'WB_RGGBLevelsUnknown23', Format => 'int16s[4]', Unknown => 1 },
8697
+ 0xf9 => { Name => 'ColorTempUnknown23', Unknown => 1 },
8698
+ 0xfa => { Name => 'WB_RGGBLevelsUnknown24', Format => 'int16s[4]', Unknown => 1 },
8699
+ 0xfe => { Name => 'ColorTempUnknown24', Unknown => 1 },
8700
+ 0xff => { Name => 'WB_RGGBLevelsUnknown25', Format => 'int16s[4]', Unknown => 1 },
8701
+ 0x103 => { Name => 'ColorTempUnknown25', Unknown => 1 },
8702
+ 0x104 => { Name => 'WB_RGGBLevelsUnknown26',Format => 'int16s[4]', Unknown => 1 },
8703
+ 0x108 => { Name => 'ColorTempUnknown26', Unknown => 1 },
8704
+ 0x109 => { Name => 'WB_RGGBLevelsUnknown27',Format => 'int16s[4]', Unknown => 1 },
8705
+ 0x10d => { Name => 'ColorTempUnknown27', Unknown => 1 },
8706
+ 0x10e => { Name => 'WB_RGGBLevelsUnknown28',Format => 'int16s[4]', Unknown => 1 },
8707
+ 0x112 => { Name => 'ColorTempUnknown28', Unknown => 1 },
8708
+ 0x113 => { Name => 'WB_RGGBLevelsUnknown29',Format => 'int16s[4]', Unknown => 1 },
8709
+ 0x117 => { Name => 'ColorTempUnknown29', Unknown => 1 },
8710
+ 0x118 => { Name => 'WB_RGGBLevelsUnknown30',Format => 'int16s[4]', Unknown => 1 },
8711
+ 0x11c => { Name => 'ColorTempUnknown30', Unknown => 1 },
8712
+ 0x11d => { Name => 'WB_RGGBLevelsUnknown31',Format => 'int16s[4]', Unknown => 1 },
8713
+ 0x121 => { Name => 'ColorTempUnknown31', Unknown => 1 },
8714
+ 0x122 => { Name => 'WB_RGGBLevelsUnknown32',Format => 'int16s[4]', Unknown => 1 },
8715
+ 0x126 => { Name => 'ColorTempUnknown32', Unknown => 1 },
8716
+ 0x127 => { Name => 'WB_RGGBLevelsUnknown33',Format => 'int16s[4]', Unknown => 1 },
8717
+ 0x12b => { Name => 'ColorTempUnknown33', Unknown => 1 },
8718
+ 0x140 => {
8719
+ Name => 'ColorCalib',
8720
+ Format => 'undef[120]',
8721
+ Unknown => 1,
8722
+ SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
8723
+ },
8724
+ 0x17f => {
8725
+ Name => 'PerChannelBlackLevel',
8726
+ Format => 'int16u[4]',
8727
+ },
8728
+ 0x294 => {
8729
+ Name => 'NormalWhiteLevel',
8730
+ Format => 'int16u',
8731
+ RawConv => '$val || undef',
8732
+ },
8733
+ 0x295 => {
8734
+ Name => 'SpecularWhiteLevel',
8735
+ Format => 'int16u',
8736
+ },
8737
+ 0x296 => {
8738
+ Name => 'LinearityUpperMargin',
8739
+ Format => 'int16u',
8740
+ },
8741
+ );
8742
+
8616
8743
  # Unknown color data (MakerNotes tag 0x4001)
8617
8744
  %Image::ExifTool::Canon::ColorDataUnknown = (
8618
8745
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
@@ -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) {
@@ -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.77';
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"\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;
@@ -16,7 +16,7 @@ use strict;
16
16
  use vars qw($VERSION $AUTOLOAD);
17
17
  use Image::ExifTool qw(:DataAccess :Utils);
18
18
 
19
- $VERSION = '1.45';
19
+ $VERSION = '1.46';
20
20
 
21
21
  sub WritePS($$);
22
22
  sub ProcessPS($$;$);
@@ -156,15 +156,6 @@ sub AUTOLOAD
156
156
  return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
157
157
  }
158
158
 
159
- #------------------------------------------------------------------------------
160
- # Is this a PC system
161
- # Returns: true for PC systems
162
- my %isPC = (MSWin32 => 1, os2 => 1, dos => 1, NetWare => 1, symbian => 1, cygwin => 1);
163
- sub IsPC()
164
- {
165
- return $isPC{$^O};
166
- }
167
-
168
159
  #------------------------------------------------------------------------------
169
160
  # Get image width or height
170
161
  # Inputs: 0) value list ref (ImageData, BoundingBox), 1) true to get height
@@ -284,7 +275,7 @@ sub GetNextLine($$)
284
275
  $$raf{PSEnd} and CheckPSEnd($raf, \$data);
285
276
  # split line if it contains other newline sequences
286
277
  if ($data =~ /$altnl/) {
287
- if (length($data) > 500000 and IsPC()) {
278
+ if (length($data) > 500000 and Image::ExifTool::IsPC()) {
288
279
  # patch for Windows memory problem
289
280
  unless ($changedNL) {
290
281
  $changedNL = $/;
@@ -537,7 +528,7 @@ sub ProcessPS($$;$)
537
528
  $raf->ReadLine($data) or last;
538
529
  # check for alternate newlines as efficiently as possible
539
530
  if ($data =~ /$altnl/) {
540
- if (length($data) > 500000 and IsPC()) {
531
+ if (length($data) > 500000 and Image::ExifTool::IsPC()) {
541
532
  # Windows can't split very long lines due to poor memory handling,
542
533
  # so re-read the file with the other newline character instead
543
534
  # (slower but uses less memory)
@@ -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 = '3.00';
51
+ $VERSION = '3.01';
52
52
 
53
53
  sub ProcessMOV($$;$);
54
54
  sub ProcessKeys($$$);
@@ -6552,7 +6552,7 @@ my %userDefined = (
6552
6552
  PROCESS_PROC => \&ProcessKeys,
6553
6553
  WRITE_PROC => \&WriteKeys,
6554
6554
  CHECK_PROC => \&CheckQTValue,
6555
- VARS => { LONG_TAGS => 7 },
6555
+ VARS => { LONG_TAGS => 8 },
6556
6556
  WRITABLE => 1,
6557
6557
  # (not PREFERRED when writing)
6558
6558
  GROUPS => { 1 => 'Keys' },
@@ -6606,12 +6606,8 @@ my %userDefined = (
6606
6606
  PrintConv => '$val * 1e6 . " microseconds"',
6607
6607
  PrintConvInv => '$val =~ s/ .*//; $val * 1e-6',
6608
6608
  },
6609
- 'camera.focal_length.35mm_equivalent' => {
6610
- Name => 'FocalLengthIn35mmFormat',
6611
- PrintConv => '"$val mm"',
6612
- PrintConvInv => '$val=~s/\s*mm$//;$val',
6613
- },
6614
- 'camera.lens_model' => { Name => 'LensModel' },
6609
+ # 'camera.focal_length.35mm_equivalent' - not top level (written to Keys in video track)
6610
+ # 'camera.lens_model' - not top level (written to Keys in video track)
6615
6611
  'location.ISO6709' => {
6616
6612
  Name => 'GPSCoordinates',
6617
6613
  Groups => { 2 => 'Location' },
@@ -6674,7 +6670,12 @@ my %userDefined = (
6674
6670
  #
6675
6671
  'com.apple.photos.captureMode' => 'CaptureMode',
6676
6672
  'com.android.version' => 'AndroidVersion',
6677
- 'com.android.capture.fps' => 'AndroidCaptureFPS',
6673
+ 'com.android.capture.fps' => { Name => 'AndroidCaptureFPS', Writable => 'float' },
6674
+ 'com.android.manufacturer' => 'AndroidMake',
6675
+ 'com.android.model' => 'AndroidModel',
6676
+ 'com.xiaomi.preview_video_cover' => { Name => 'XiaomiPreviewVideoCover', Writable => 'int32s' },
6677
+ 'xiaomi.exifInfo.videoinfo' => 'XiaomiExifInfo',
6678
+ 'com.xiaomi.hdr10' => { Name => 'XiaomiHDR10', Writable => 'int32s' },
6678
6679
  #
6679
6680
  # also seen
6680
6681
  #
@@ -9490,7 +9491,7 @@ sub ProcessKeys($$$)
9490
9491
  $$newInfo{KeysID} = $tag; # save original ID for use in family 7 group name
9491
9492
  AddTagToTable($itemList, $id, $newInfo);
9492
9493
  $msg or $msg = '';
9493
- $out and print $out "$$et{INDENT}Added ItemList Tag $id = ($ns) $tag$msg\n";
9494
+ $out and print $out "$$et{INDENT}Added ItemList Tag $id = ($ns) $full$msg\n";
9494
9495
  }
9495
9496
  $pos += $len;
9496
9497
  ++$index;
@@ -10142,11 +10143,15 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
10142
10143
  }
10143
10144
  if ($warnStr) {
10144
10145
  # assume this is an unknown trailer if it comes immediately after
10145
- # mdat or moov and has a tag name we don't recognize
10146
- if (($lastTag eq 'mdat' or $lastTag eq 'moov') and (not $$tagTablePtr{$tag} or
10147
- ref $$tagTablePtr{$tag} eq 'HASH' and $$tagTablePtr{$tag}{Unknown}))
10146
+ # mdat or moov or free and has a tag name we don't recognize
10147
+ # (Insta360 can write trailer after a 'free' atom)
10148
+ if (($lastTag eq 'mdat' or $lastTag eq 'moov' or $lastTag eq 'free') and
10149
+ (not $$tagTablePtr{$tag} or ref $$tagTablePtr{$tag} eq 'HASH' and $$tagTablePtr{$tag}{Unknown}))
10148
10150
  {
10149
- if ($size == 0x1000000 - 8 and $tag =~ /^(\x94\xc0\x7e\0|\0\x02\0\0)/) {
10151
+ if ($raf->Seek(-40, 2) and $raf->Read($buff, 40) == 40 and
10152
+ substr($buff, 8) eq '8db42d694ccc418790edff439fe026bf' and
10153
+ $lastPos == $raf->Tell() - unpack('V',$buff))
10154
+ {
10150
10155
  $et->Warn(sprintf('Insta360 trailer at offset 0x%x', $lastPos), 1);
10151
10156
  } else {
10152
10157
  $et->Warn('Unknown trailer with '.lcfirst($warnStr));
@@ -10177,7 +10182,10 @@ QTLang: foreach $tag (@{$$et{QTLang}}) {
10177
10182
  for ($i=0, $key=$name; $$infoHash{$key}; ++$i, $key="$name ($i)") {
10178
10183
  next QTLang if $et->GetGroup($key, 0) eq 'QuickTime';
10179
10184
  }
10180
- $et->FoundTag($tagInfo, $$et{VALUE}{$tag});
10185
+ $key = $et->FoundTag($tagInfo, $$et{VALUE}{$tag});
10186
+ # copy extra tag information (groups, etc) to the synthetic tag
10187
+ $$et{TAG_EXTRA}{$key} = $$et{TAG_EXTRA}{$tag};
10188
+ $et->VPrint(0, "(synthesized default-language tag for QuickTime:$$tagInfo{Name})");
10181
10189
  }
10182
10190
  delete $$et{QTLang};
10183
10191
  }