exiftool_vendored 12.93.0 → 12.96.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/Changes +28 -2
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/exiftool +15 -44
- data/bin/lib/Image/ExifTool/Canon.pm +128 -1
- data/bin/lib/Image/ExifTool/Font.pm +15 -4
- data/bin/lib/Image/ExifTool/Geotag.pm +19 -5
- data/bin/lib/Image/ExifTool/PostScript.pm +3 -12
- data/bin/lib/Image/ExifTool/QuickTime.pm +34 -20
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +14 -14
- data/bin/lib/Image/ExifTool/TagLookup.pm +6920 -6906
- data/bin/lib/Image/ExifTool/TagNames.pod +101 -5
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +48 -16
- data/bin/lib/Image/ExifTool/Writer.pl +4 -53
- data/bin/lib/Image/ExifTool.pm +66 -4
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 470de93eb9d8ccb910e0eb1526fb6b9e1e45cbbeb4a88f63c11ddb4bf33d12b8
|
4
|
+
data.tar.gz: 90cf2dd30483d655432ef216f8af1751878fc02b140167eb2f301d856c96109d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c22dbe664b9eb4ff2327da76ffeea627b45cc47815e3699202d162503c3129c3a31d5b6f2c380dffdedff2a4dccd6a2bd86b68a8ed2e9003b43168788f1df7f8
|
7
|
+
data.tar.gz: 1c86569ae1b1a15088e5ff7a9b13b339ecec57b7df35f97d531e29908fe26d10967ccd71b0a4feba0d6a5e37849cbbfea7526000072fe34692141ce694169717
|
data/bin/Changes
CHANGED
@@ -7,13 +7,39 @@ 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. 1, 2024 - Version 12.96
|
11
|
+
|
12
|
+
- More improvements to handling of trailers on video files (and add ability to
|
13
|
+
write videos which have an unknown trailer)
|
14
|
+
- Fixed problem geotagging from some newer Google Takeout files
|
15
|
+
|
16
|
+
Aug. 30, 2024 - Version 12.95
|
17
|
+
|
18
|
+
- Added a couple of new CanonModelID values
|
19
|
+
- Decode ColorData for a couple of new Canon models
|
20
|
+
- Fixed problem writing video files which have some known trailer types
|
21
|
+
|
22
|
+
Aug. 29, 2024 - Version 12.94
|
23
|
+
|
24
|
+
- Added ability to geotag from new-format Google Takeout JSON files
|
25
|
+
- Added a few new Android and Xiaomi QuickTime Keys tags
|
26
|
+
- Added ability to read C2PA JUMBF metadata from TTF/OTF files
|
27
|
+
- Internal changes to code for creating new directories
|
28
|
+
- Changed Windows packages to have the application help text file in the
|
29
|
+
exiftool_files folder instead of writing it to a temporary directory
|
30
|
+
- Removed new QuickTime Keys tags added in 12.93 because these aren't used in
|
31
|
+
top-level metadata (written to the video track by Apple devices)
|
32
|
+
- Fixed the group names for synthesized default-language QuickTime tags and
|
33
|
+
added a verbose message when generating these tags
|
34
|
+
- Fixed warning in Geolocation.t self test
|
35
|
+
|
10
36
|
Aug. 20, 2024 - Version 12.93
|
11
37
|
|
12
38
|
- Added a new Nikon LensID
|
13
39
|
- Added a couple of new OpenEXR Compression types
|
14
40
|
- Added a couple of new QuickTime Keys tags
|
15
|
-
- Decode timed metadata from E-ACE B44
|
16
|
-
-
|
41
|
+
- Decode timed metadata from E-ACE B44 dashcam videos
|
42
|
+
- Made "Unrecognized" Samsung Meta warnings minor
|
17
43
|
- Fixed bug in -listg6 option which resulted in "uninitialized value" warnings
|
18
44
|
- Fixed decoding of Func1Button and Func2Button for the Nikon Z6/Z7
|
19
45
|
- Fixed bug reading JUMB metadata from JXL images
|
data/bin/META.json
CHANGED
data/bin/META.yml
CHANGED
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.
|
113
|
-
cd Image-ExifTool-12.
|
112
|
+
gzip -dc Image-ExifTool-12.96.tar.gz | tar -xf -
|
113
|
+
cd Image-ExifTool-12.96
|
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.
|
14
|
+
my $version = '12.96';
|
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 (
|
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
|
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
|
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
|
4361
|
-
(
|
4362
|
-
|
4363
|
-
|
4364
|
-
|
4365
|
-
|
4366
|
-
$
|
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
|
4363
|
+
++$countNewDir;
|
4364
|
+
return 1;
|
4394
4365
|
}
|
4395
|
-
return
|
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.
|
5658
|
+
-- Generated by ExifTool 12.96 --
|
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.
|
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.
|
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
|
398
|
+
# look for tags to process
|
394
399
|
my $tag = substr($tbl, $pos, 4);
|
395
|
-
next unless $tag
|
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
|
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.
|
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)"
|
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
|
-
}
|
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.
|
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.
|
51
|
+
$VERSION = '3.02';
|
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 =>
|
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
|
-
|
6610
|
-
|
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) $
|
9494
|
+
$out and print $out "$$et{INDENT}Added ItemList Tag $id = ($ns) $full$msg\n";
|
9494
9495
|
}
|
9495
9496
|
$pos += $len;
|
9496
9497
|
++$index;
|
@@ -9527,7 +9528,7 @@ sub ProcessMOV($$;$)
|
|
9527
9528
|
my $dirID = $$dirInfo{DirID} || '';
|
9528
9529
|
my $charsetQuickTime = $et->Options('CharsetQuickTime');
|
9529
9530
|
my ($buff, $tag, $size, $track, $isUserData, %triplet, $doDefaultLang, $index);
|
9530
|
-
my ($dirEnd, $unkOpt, %saveOptions, $atomCount, $warnStr);
|
9531
|
+
my ($dirEnd, $unkOpt, %saveOptions, $atomCount, $warnStr, $trailer);
|
9531
9532
|
|
9532
9533
|
my $topLevel = not $$et{InQuickTime};
|
9533
9534
|
$$et{InQuickTime} = 1;
|
@@ -9556,6 +9557,17 @@ sub ProcessMOV($$;$)
|
|
9556
9557
|
$tagTablePtr = GetTagTable('Image::ExifTool::QuickTime::Main');
|
9557
9558
|
}
|
9558
9559
|
($size, $tag) = unpack('Na4', $buff);
|
9560
|
+
my $fast = $$et{OPTIONS}{FastScan} || 0;
|
9561
|
+
# check for Insta360 trailer
|
9562
|
+
if ($topLevel and not $fast) {
|
9563
|
+
my $pos = $raf->Tell();
|
9564
|
+
if ($raf->Seek(-40, 2) and $raf->Read($buff, 40) == 40 and
|
9565
|
+
substr($buff, 8) eq '8db42d694ccc418790edff439fe026bf')
|
9566
|
+
{
|
9567
|
+
$trailer = [ 'Insta360', $raf->Tell() - unpack('V',$buff) ];
|
9568
|
+
}
|
9569
|
+
$raf->Seek($pos,0) or return 0;
|
9570
|
+
}
|
9559
9571
|
if ($dataPt) {
|
9560
9572
|
$verbose and $et->VerboseDir($$dirInfo{DirName});
|
9561
9573
|
} else {
|
@@ -9594,7 +9606,6 @@ sub ProcessMOV($$;$)
|
|
9594
9606
|
# have XMP take priority except for HEIC
|
9595
9607
|
$$et{PRIORITY_DIR} = 'XMP' unless $fileType and $fileType eq 'HEIC';
|
9596
9608
|
}
|
9597
|
-
my $fast = $$et{OPTIONS}{FastScan} || 0;
|
9598
9609
|
$$raf{NoBuffer} = 1 if $fast; # disable buffering in FastScan mode
|
9599
9610
|
|
9600
9611
|
my $ee = $$et{OPTIONS}{ExtractEmbedded};
|
@@ -10135,6 +10146,10 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
|
|
10135
10146
|
$dataPos += $size + 8; # point to start of next atom data
|
10136
10147
|
last if $dirEnd and $dataPos >= $dirEnd; # (note: ignores last value if 0 bytes)
|
10137
10148
|
$lastPos = $raf->Tell() + $dirBase;
|
10149
|
+
if ($trailer and $lastPos >= $$trailer[1]) {
|
10150
|
+
$et->Warn(sprintf('%s trailer at offset 0x%x', @$trailer), 1);
|
10151
|
+
last;
|
10152
|
+
}
|
10138
10153
|
$raf->Read($buff, 8) == 8 or last;
|
10139
10154
|
$lastTag = $tag if $$tagTablePtr{$tag} and $tag ne 'free'; # (Insta360 sometimes puts free block before trailer)
|
10140
10155
|
($size, $tag) = unpack('Na4', $buff);
|
@@ -10143,14 +10158,10 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
|
|
10143
10158
|
if ($warnStr) {
|
10144
10159
|
# assume this is an unknown trailer if it comes immediately after
|
10145
10160
|
# mdat or moov and has a tag name we don't recognize
|
10146
|
-
if (($lastTag eq 'mdat' or $lastTag eq 'moov') and
|
10147
|
-
ref $$tagTablePtr{$tag} eq 'HASH' and $$tagTablePtr{$tag}{Unknown}))
|
10161
|
+
if (($lastTag eq 'mdat' or $lastTag eq 'moov') and
|
10162
|
+
(not $$tagTablePtr{$tag} or ref $$tagTablePtr{$tag} eq 'HASH' and $$tagTablePtr{$tag}{Unknown}))
|
10148
10163
|
{
|
10149
|
-
|
10150
|
-
$et->Warn(sprintf('Insta360 trailer at offset 0x%x', $lastPos), 1);
|
10151
|
-
} else {
|
10152
|
-
$et->Warn('Unknown trailer with '.lcfirst($warnStr));
|
10153
|
-
}
|
10164
|
+
$et->Warn('Unknown trailer with '.lcfirst($warnStr));
|
10154
10165
|
} else {
|
10155
10166
|
$et->Warn($warnStr);
|
10156
10167
|
}
|
@@ -10177,7 +10188,10 @@ QTLang: foreach $tag (@{$$et{QTLang}}) {
|
|
10177
10188
|
for ($i=0, $key=$name; $$infoHash{$key}; ++$i, $key="$name ($i)") {
|
10178
10189
|
next QTLang if $et->GetGroup($key, 0) eq 'QuickTime';
|
10179
10190
|
}
|
10180
|
-
$et->FoundTag($tagInfo, $$et{VALUE}{$tag});
|
10191
|
+
$key = $et->FoundTag($tagInfo, $$et{VALUE}{$tag});
|
10192
|
+
# copy extra tag information (groups, etc) to the synthetic tag
|
10193
|
+
$$et{TAG_EXTRA}{$key} = $$et{TAG_EXTRA}{$tag};
|
10194
|
+
$et->VPrint(0, "(synthesized default-language tag for QuickTime:$$tagInfo{Name})");
|
10181
10195
|
}
|
10182
10196
|
delete $$et{QTLang};
|
10183
10197
|
}
|