exiftool-vendored.pl 12.76.0 → 12.80.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 +79 -4
- package/bin/MANIFEST +27 -0
- package/bin/META.json +1 -1
- package/bin/META.yml +1 -1
- package/bin/README +3 -3
- package/bin/config_files/acdsee.config +37 -57
- package/bin/config_files/example.config +16 -2
- package/bin/exiftool +84 -29
- package/bin/lib/Image/ExifTool/Canon.pm +12 -9
- package/bin/lib/Image/ExifTool/CanonVRD.pm +7 -1
- package/bin/lib/Image/ExifTool/Exif.pm +52 -4
- package/bin/lib/Image/ExifTool/FujiFilm.pm +3 -0
- package/bin/lib/Image/ExifTool/GPS.pm +5 -3
- package/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
- package/bin/lib/Image/ExifTool/Geolocation.pm +775 -0
- package/bin/lib/Image/ExifTool/Geotag.pm +8 -1
- package/bin/lib/Image/ExifTool/HtmlDump.pm +2 -1
- package/bin/lib/Image/ExifTool/Import.pm +5 -2
- package/bin/lib/Image/ExifTool/JSON.pm +15 -10
- package/bin/lib/Image/ExifTool/MWG.pm +1 -0
- package/bin/lib/Image/ExifTool/MacOS.pm +19 -4
- package/bin/lib/Image/ExifTool/Nikon.pm +2 -2
- package/bin/lib/Image/ExifTool/Ogg.pm +3 -2
- package/bin/lib/Image/ExifTool/Olympus.pm +3 -1
- package/bin/lib/Image/ExifTool/OpenEXR.pm +17 -17
- package/bin/lib/Image/ExifTool/PDF.pm +5 -5
- package/bin/lib/Image/ExifTool/Pentax.pm +1 -1
- package/bin/lib/Image/ExifTool/QuickTime.pm +183 -11
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +253 -237
- package/bin/lib/Image/ExifTool/README +6 -5
- package/bin/lib/Image/ExifTool/TagLookup.pm +2624 -2520
- package/bin/lib/Image/ExifTool/TagNames.pod +184 -4
- package/bin/lib/Image/ExifTool/WriteQuickTime.pl +15 -1
- package/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
- package/bin/lib/Image/ExifTool/Writer.pl +59 -8
- package/bin/lib/Image/ExifTool/XMP.pm +17 -2
- package/bin/lib/Image/ExifTool/XMP2.pl +64 -0
- package/bin/lib/Image/ExifTool.pm +249 -47
- package/bin/lib/Image/ExifTool.pod +57 -25
- package/bin/perl-Image-ExifTool.spec +2 -2
- package/bin/pp_build_exe.args +4 -230
- package/package.json +2 -2
|
@@ -1109,7 +1109,7 @@ sub SetGeoValues($$;$)
|
|
|
1109
1109
|
$iExt = $i1;
|
|
1110
1110
|
}
|
|
1111
1111
|
if (abs($time - $tn) > $geoMaxExtSecs) {
|
|
1112
|
-
$err or $err = 'Time is too far from nearest GPS fix'.' '.abs($time-$tn).' '.$geoMaxExtSecs;
|
|
1112
|
+
$err or $err = 'Time is too far from nearest GPS fix'.' '.abs($time-$tn).' > '.$geoMaxExtSecs;
|
|
1113
1113
|
$et->VPrint(2, ' Nearest fix: ', PrintFixTime($tn), "\n") if $verbose > 2;
|
|
1114
1114
|
$fix = { } if $$geotag{DateTimeOnly};
|
|
1115
1115
|
} else {
|
|
@@ -1218,6 +1218,13 @@ Category: foreach $category (qw{pos track alt orient atemp}) {
|
|
|
1218
1218
|
$coords .= " $alt";
|
|
1219
1219
|
}
|
|
1220
1220
|
@r = $et->SetNewValue(GPSCoordinates => $coords, %opts);
|
|
1221
|
+
# also Geolocate if specified
|
|
1222
|
+
my $nvHash;
|
|
1223
|
+
my $geoloc = $et->GetNewValue('Geolocate', \$nvHash);
|
|
1224
|
+
if ($geoloc and lc($geoloc) eq 'geotag') {
|
|
1225
|
+
$geoloc = ($$nvHash{WantGroup} ? "$$nvHash{WantGroup}:" : '') . 'Geolocate';
|
|
1226
|
+
$et->SetNewValue($geoloc => "$$fix{lat},$$fix{lon}");
|
|
1227
|
+
}
|
|
1221
1228
|
return $err if $qt; # all done if writing to QuickTime only
|
|
1222
1229
|
# (capture error messages by calling SetNewValue in list context)
|
|
1223
1230
|
@r = $et->SetNewValue(GPSLatitude => $$fix{lat}, %opts);
|
|
@@ -13,7 +13,7 @@ use vars qw($VERSION);
|
|
|
13
13
|
use Image::ExifTool; # only for FinishTiffDump()
|
|
14
14
|
use Image::ExifTool::HTML qw(EscapeHTML);
|
|
15
15
|
|
|
16
|
-
$VERSION = '1.
|
|
16
|
+
$VERSION = '1.42';
|
|
17
17
|
|
|
18
18
|
sub DumpTable($$$;$$$$$$);
|
|
19
19
|
sub Open($$$;@);
|
|
@@ -769,6 +769,7 @@ sub FinishTiffDump($$$)
|
|
|
769
769
|
PreviewImageStart => 'PreviewImageLength',
|
|
770
770
|
JpgFromRawStart => 'JpgFromRawLength',
|
|
771
771
|
OtherImageStart => 'OtherImageLength',
|
|
772
|
+
PreviewJXLStart => 'PreviewJXLLength',
|
|
772
773
|
ImageOffset => 'ImageByteCount',
|
|
773
774
|
AlphaOffset => 'AlphaByteCount',
|
|
774
775
|
MPImageStart => 'MPImageLength',
|
|
@@ -12,7 +12,7 @@ require Exporter;
|
|
|
12
12
|
|
|
13
13
|
use vars qw($VERSION @ISA @EXPORT_OK);
|
|
14
14
|
|
|
15
|
-
$VERSION = '1.
|
|
15
|
+
$VERSION = '1.12';
|
|
16
16
|
@ISA = qw(Exporter);
|
|
17
17
|
@EXPORT_OK = qw(ReadCSV ReadJSON);
|
|
18
18
|
|
|
@@ -238,7 +238,7 @@ Tok: for (;;) {
|
|
|
238
238
|
|
|
239
239
|
#------------------------------------------------------------------------------
|
|
240
240
|
# Read JSON file
|
|
241
|
-
# Inputs: 0) JSON file name, file ref or
|
|
241
|
+
# Inputs: 0) JSON file name, file ref, RAF ref or SCALAR ref, 1) database hash ref,
|
|
242
242
|
# 2) flag to delete "-" tags, 3) character set
|
|
243
243
|
# Returns: undef on success, or error string
|
|
244
244
|
sub ReadJSON($$;$$)
|
|
@@ -255,6 +255,9 @@ sub ReadJSON($$;$$)
|
|
|
255
255
|
} elsif (ref $file eq 'GLOB') {
|
|
256
256
|
$raf = File::RandomAccess->new($file);
|
|
257
257
|
$file = 'JSON file';
|
|
258
|
+
} elsif (ref $file eq 'SCALAR') {
|
|
259
|
+
$raf = File::RandomAccess->new($file);
|
|
260
|
+
$file = 'in memory';
|
|
258
261
|
} else {
|
|
259
262
|
open JSONFILE, $file or return "Error opening JSON file '${file}'";
|
|
260
263
|
binmode JSONFILE;
|
|
@@ -14,7 +14,7 @@ use vars qw($VERSION);
|
|
|
14
14
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
15
15
|
use Image::ExifTool::Import;
|
|
16
16
|
|
|
17
|
-
$VERSION = '1.
|
|
17
|
+
$VERSION = '1.08';
|
|
18
18
|
|
|
19
19
|
sub ProcessJSON($$);
|
|
20
20
|
sub ProcessTag($$$$%);
|
|
@@ -60,15 +60,20 @@ sub FoundTag($$$$%)
|
|
|
60
60
|
# avoid conflict with special table entries
|
|
61
61
|
$tag .= '!' if $Image::ExifTool::specialTags{$tag};
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
unless ($$tagTablePtr{$tag}) {
|
|
64
|
+
my $name = $tag;
|
|
65
|
+
$name =~ tr/:/_/; # use underlines in place of colons in tag name
|
|
66
|
+
$name =~ s/^c2pa/C2PA/i; # hack to fix "C2PA" case
|
|
67
|
+
$name = Image::ExifTool::MakeTagName($name);
|
|
68
|
+
my $desc = Image::ExifTool::MakeDescription($name);
|
|
69
|
+
$desc =~ s/^C2 PA/C2PA/; # hack to get "C2PA" correct
|
|
70
|
+
AddTagToTable($tagTablePtr, $tag, {
|
|
71
|
+
Name => $name,
|
|
72
|
+
Description => $desc,
|
|
73
|
+
%flags,
|
|
74
|
+
Temporary => 1,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
72
77
|
$et->HandleTag($tagTablePtr, $tag, $val);
|
|
73
78
|
}
|
|
74
79
|
|
|
@@ -441,6 +441,7 @@ my %sRegionStruct = (
|
|
|
441
441
|
Writable => 'real',
|
|
442
442
|
Notes => 'not part of MWG 2.0 spec',
|
|
443
443
|
},
|
|
444
|
+
# Title - seen in sample XMP of MWG 2.0 specification, but not in spec itself
|
|
444
445
|
seeAlso => { Namespace => 'rdfs', Resource => 1 },
|
|
445
446
|
);
|
|
446
447
|
my %sKeywordStruct;
|
|
@@ -12,7 +12,7 @@ use strict;
|
|
|
12
12
|
use vars qw($VERSION);
|
|
13
13
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
14
14
|
|
|
15
|
-
$VERSION = '1.
|
|
15
|
+
$VERSION = '1.13';
|
|
16
16
|
|
|
17
17
|
sub MDItemLocalTime($);
|
|
18
18
|
sub ProcessATTR($$$);
|
|
@@ -22,6 +22,11 @@ my %mdDateInfo = (
|
|
|
22
22
|
PrintConv => '$self->ConvertDateTime($val)',
|
|
23
23
|
);
|
|
24
24
|
|
|
25
|
+
my %delXAttr = (
|
|
26
|
+
XAttrQuarantine => 'com.apple.quarantine',
|
|
27
|
+
XAttrMDItemWhereFroms => 'com.apple.metadata:kMDItemWhereFroms',
|
|
28
|
+
);
|
|
29
|
+
|
|
25
30
|
# Information decoded from Mac OS sidecar files
|
|
26
31
|
%Image::ExifTool::MacOS::Main = (
|
|
27
32
|
GROUPS => { 0 => 'File', 1 => 'MacOS' },
|
|
@@ -320,7 +325,17 @@ my %mdDateInfo = (
|
|
|
320
325
|
Groups => { 2 => 'Time' },
|
|
321
326
|
},
|
|
322
327
|
'com.apple.metadata:kMDItemFinderComment' => { Name => 'XAttrMDItemFinderComment' },
|
|
323
|
-
'com.apple.metadata:kMDItemWhereFroms'
|
|
328
|
+
'com.apple.metadata:kMDItemWhereFroms' => {
|
|
329
|
+
Name => 'XAttrMDItemWhereFroms',
|
|
330
|
+
Writable => 1,
|
|
331
|
+
WritePseudo => 1,
|
|
332
|
+
WriteCheck => '"May only delete this tag"',
|
|
333
|
+
Protected => 1,
|
|
334
|
+
Notes => q{
|
|
335
|
+
information about where the file came from. May only be deleted when
|
|
336
|
+
writing
|
|
337
|
+
},
|
|
338
|
+
},
|
|
324
339
|
'com.apple.metadata:kMDLabel' => { Name => 'XAttrMDLabel', Binary => 1 },
|
|
325
340
|
'com.apple.ResourceFork' => { Name => 'XAttrResourceFork', Binary => 1 },
|
|
326
341
|
'com.apple.lastuseddate#PS' => {
|
|
@@ -407,9 +422,9 @@ sub SetMacOSTags($$$)
|
|
|
407
422
|
$et->VPrint(1," - $tag = (all)\n") if $overwrite > 0;
|
|
408
423
|
undef $val if $val eq '';
|
|
409
424
|
}
|
|
410
|
-
} elsif ($tag
|
|
425
|
+
} elsif ($delXAttr{$tag}) {
|
|
411
426
|
($f = $file) =~ s/'/'\\''/g;
|
|
412
|
-
$cmd = "/usr/bin/xattr -d
|
|
427
|
+
$cmd = "/usr/bin/xattr -d $delXAttr{$tag} '${f}'";
|
|
413
428
|
$silentErr = 256; # (will get this error if attribute doesn't exist)
|
|
414
429
|
} else {
|
|
415
430
|
($f = $file) =~ s/(["\\])/\\$1/g; # escape necessary characters for script
|
|
@@ -703,8 +703,8 @@ sub GetAFPointGrid($$;$);
|
|
|
703
703
|
#
|
|
704
704
|
'00 54 56 56 30 30 00 00' => 'Coastal Optical Systems 60mm 1:4 UV-VIS-IR Macro Apo',
|
|
705
705
|
#
|
|
706
|
-
'BF 4E 26 26 1E 1E 01 04' => 'Irix 15mm f/2.4 Firefly', #30
|
|
707
|
-
'BF 3C 1B 1B 30 30 01 04' => 'Irix 11mm f/4 Firefly', #30
|
|
706
|
+
'BF 4E 26 26 1E 1E 01 04' => 'Irix 15mm f/2.4 Firefly', #30 (guessing the Blackstone version may be the same ID - PH)
|
|
707
|
+
'BF 3C 1B 1B 30 30 01 04' => 'Irix 11mm f/4 Firefly', #30 (guessing the Blackstone version may be the same ID - PH)
|
|
708
708
|
#
|
|
709
709
|
'4A 40 11 11 2C 0C 4D 02' => 'Samyang 8mm f/3.5 Fish-Eye CS',
|
|
710
710
|
'4A 48 24 24 24 0C 4D 02.1' => 'Samyang 10mm f/2.8 ED AS NCS CS',
|
|
@@ -17,7 +17,7 @@ use strict;
|
|
|
17
17
|
use vars qw($VERSION);
|
|
18
18
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
19
19
|
|
|
20
|
-
$VERSION = '1.
|
|
20
|
+
$VERSION = '1.04';
|
|
21
21
|
|
|
22
22
|
my $MAX_PACKETS = 2; # maximum packets to scan from each stream at start of file
|
|
23
23
|
|
|
@@ -145,6 +145,7 @@ sub ProcessOGG($$)
|
|
|
145
145
|
# calculate total data length
|
|
146
146
|
my $dataLen = Get8u(\$buff, 27);
|
|
147
147
|
if ($nseg) {
|
|
148
|
+
last unless $raf;
|
|
148
149
|
$raf->Read($buff, $nseg-1) == $nseg-1 or last;
|
|
149
150
|
my @segs = unpack('C*', $buff);
|
|
150
151
|
# could check that all these (but the last) are 255...
|
|
@@ -160,7 +161,7 @@ sub ProcessOGG($$)
|
|
|
160
161
|
}
|
|
161
162
|
}
|
|
162
163
|
# read page data
|
|
163
|
-
$raf->Read($buff, $dataLen) == $dataLen
|
|
164
|
+
last unless $raf and $raf->Read($buff, $dataLen) == $dataLen;
|
|
164
165
|
if ($verbose > 1) {
|
|
165
166
|
printf $out "Page %d, stream 0x%x, flag 0x%x (%d bytes)\n",
|
|
166
167
|
$pageNum, $stream, $flag, $dataLen;
|
|
@@ -40,7 +40,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
|
40
40
|
use Image::ExifTool::Exif;
|
|
41
41
|
use Image::ExifTool::APP12;
|
|
42
42
|
|
|
43
|
-
$VERSION = '2.
|
|
43
|
+
$VERSION = '2.83';
|
|
44
44
|
|
|
45
45
|
sub PrintLensInfo($$$);
|
|
46
46
|
|
|
@@ -117,6 +117,7 @@ my %olympusLensTypes = (
|
|
|
117
117
|
'0 36 10' => 'Olympus M.Zuiko Digital ED 8-25mm F4 Pro', #IB
|
|
118
118
|
'0 37 10' => 'Olympus M.Zuiko Digital ED 40-150mm F4.0 Pro', #forum3833
|
|
119
119
|
'0 39 10' => 'Olympus M.Zuiko Digital ED 90mm F3.5 Macro IS Pro', #forum3833
|
|
120
|
+
'0 40 10' => 'Olympus M.Zuiko Digital ED 150-600mm F5.0-6.3', #forum15652
|
|
120
121
|
# Sigma lenses
|
|
121
122
|
'1 01 00' => 'Sigma 18-50mm F3.5-5.6 DC', #8
|
|
122
123
|
'1 01 10' => 'Sigma 30mm F2.8 EX DN', #NJ
|
|
@@ -442,6 +443,7 @@ my %olympusCameraTypes = (
|
|
|
442
443
|
S0093 => 'E-P7', #IB
|
|
443
444
|
S0095 => 'OM-1', #IB
|
|
444
445
|
S0101 => 'OM-5', #IB
|
|
446
|
+
S0121 => 'OM-1MarkII', #forum15652
|
|
445
447
|
SR45 => 'D220',
|
|
446
448
|
SR55 => 'D320L',
|
|
447
449
|
SR83 => 'D340L',
|
|
@@ -16,7 +16,7 @@ use vars qw($VERSION);
|
|
|
16
16
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
17
17
|
use Image::ExifTool::GPS;
|
|
18
18
|
|
|
19
|
-
$VERSION = '1.
|
|
19
|
+
$VERSION = '1.05';
|
|
20
20
|
|
|
21
21
|
# supported EXR value format types (other types are extracted as undef binary data)
|
|
22
22
|
my %formatType = (
|
|
@@ -134,7 +134,7 @@ my %formatType = (
|
|
|
134
134
|
multiView => { },
|
|
135
135
|
owner => { Groups => { 2 => 'Author' } },
|
|
136
136
|
pixelAspectRatio => { },
|
|
137
|
-
preview => { },
|
|
137
|
+
preview => { Groups => { 2 => 'Preview' } },
|
|
138
138
|
renderingTransform => { },
|
|
139
139
|
screenWindowCenter => { },
|
|
140
140
|
screenWindowWidth => { },
|
|
@@ -219,25 +219,25 @@ sub ProcessEXR($$)
|
|
|
219
219
|
AddTagToTable($tagTablePtr, $tag, $tagInfo);
|
|
220
220
|
$et->VPrint(0, $$et{INDENT}, "[adding $tag]\n");
|
|
221
221
|
}
|
|
222
|
-
my ($val, $success);
|
|
222
|
+
my ($val, $success, $buf2);
|
|
223
223
|
my $format = $formatType{$type};
|
|
224
224
|
if ($format or $binary) {
|
|
225
|
-
$raf->Read($
|
|
225
|
+
$raf->Read($buf2, $size) == $size and $success = 1;
|
|
226
226
|
if (not $format) {
|
|
227
|
-
$val = \$
|
|
227
|
+
$val = \$buf2; # treat as undef binary data
|
|
228
228
|
} elsif ($format ne '1') {
|
|
229
229
|
# handle formats which map nicely into ExifTool format codes
|
|
230
230
|
if ($format =~ /^(\w+)\[?(\d*)/) {
|
|
231
231
|
my ($fmt, $cnt) = ($1, $2);
|
|
232
232
|
$cnt = $fmt eq 'string' ? $size : 1 unless $cnt;
|
|
233
|
-
$val = ReadValue(\$
|
|
233
|
+
$val = ReadValue(\$buf2, 0, $fmt, $cnt, $size);
|
|
234
234
|
}
|
|
235
235
|
# handle other format types
|
|
236
236
|
} elsif ($type eq 'tiledesc') {
|
|
237
237
|
if ($size >= 9) {
|
|
238
|
-
my $x = Get32u(\$
|
|
239
|
-
my $y = Get32u(\$
|
|
240
|
-
my $mode = Get8u(\$
|
|
238
|
+
my $x = Get32u(\$buf2, 0);
|
|
239
|
+
my $y = Get32u(\$buf2, 4);
|
|
240
|
+
my $mode = Get8u(\$buf2, 8);
|
|
241
241
|
my $lvl = { 0 => 'One Level', 1 => 'MIMAP Levels', 2 => 'RIPMAP Levels' }->{$mode & 0x0f};
|
|
242
242
|
$lvl or $lvl = 'Unknown Levels (' . ($mode & 0xf) . ')';
|
|
243
243
|
my $rnd = { 0 => 'Round Down', 1 => 'Round Up' }->{$mode >> 4};
|
|
@@ -246,7 +246,7 @@ sub ProcessEXR($$)
|
|
|
246
246
|
}
|
|
247
247
|
} elsif ($type eq 'chlist') {
|
|
248
248
|
$val = [ ];
|
|
249
|
-
while ($
|
|
249
|
+
while ($buf2 =~ /\G([^\0]{1,31})\0(.{16})/sg) {
|
|
250
250
|
my ($str, $dat) = ($1, $2);
|
|
251
251
|
my ($pix,$lin,$x,$y) = unpack('VCx3VV', $dat);
|
|
252
252
|
$pix = { 0 => 'int8u', 1 => 'half', 2 => 'float' }->{$pix} || "unknown($pix)";
|
|
@@ -255,14 +255,14 @@ sub ProcessEXR($$)
|
|
|
255
255
|
} elsif ($type eq 'stringvector') {
|
|
256
256
|
$val = [ ];
|
|
257
257
|
my $pos = 0;
|
|
258
|
-
while ($pos + 4 <= length($
|
|
259
|
-
my $len = Get32u(\$
|
|
260
|
-
last if $pos + 4 + $len > length($
|
|
261
|
-
push @$val, substr($
|
|
258
|
+
while ($pos + 4 <= length($buf2)) {
|
|
259
|
+
my $len = Get32u(\$buf2, $pos);
|
|
260
|
+
last if $pos + 4 + $len > length($buf2);
|
|
261
|
+
push @$val, substr($buf2, $pos + 4, $len);
|
|
262
262
|
$pos += 4 + $len;
|
|
263
263
|
}
|
|
264
264
|
} else {
|
|
265
|
-
$val = \$
|
|
265
|
+
$val = \$buf2; # (shouldn't happen)
|
|
266
266
|
}
|
|
267
267
|
} else {
|
|
268
268
|
# avoid loading binary data
|
|
@@ -282,13 +282,13 @@ sub ProcessEXR($$)
|
|
|
282
282
|
$dim = [$3 - $1 + 1, $4 - $2 + 1];
|
|
283
283
|
}
|
|
284
284
|
if ($verbose) {
|
|
285
|
-
my $dataPt = ref $val ? $val : \$
|
|
285
|
+
my $dataPt = ref $val eq 'SCALAR' ? $val : \$buf2;
|
|
286
286
|
$et->VerboseInfo($tag, $tagInfo,
|
|
287
287
|
Table => $tagTablePtr,
|
|
288
288
|
Value => $val,
|
|
289
289
|
Size => $size,
|
|
290
290
|
Format => $type,
|
|
291
|
-
DataPt =>
|
|
291
|
+
DataPt => $dataPt,
|
|
292
292
|
Addr => $raf->Tell() - $size,
|
|
293
293
|
);
|
|
294
294
|
}
|
|
@@ -114,11 +114,11 @@ my %supportedFilter = (
|
|
|
114
114
|
Notes => q{
|
|
115
115
|
stored as a string but treated as a comma- or semicolon-separated list of
|
|
116
116
|
items when reading if the string contains commas or semicolons, whichever is
|
|
117
|
-
more numerous, otherwise it is treated a space-separated list of items.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
117
|
+
more numerous, otherwise it is treated a space-separated list of items. The
|
|
118
|
+
list behaviour may be defeated by setting the API NoPDFList option. Written
|
|
119
|
+
as a comma-separated string. Note that the corresponding XMP-pdf:Keywords
|
|
120
|
+
tag is not treated as a list, so the NoPDFList option should be used when
|
|
121
|
+
copying between these two.
|
|
122
122
|
},
|
|
123
123
|
},
|
|
124
124
|
Creator => { },
|
|
@@ -177,7 +177,7 @@ sub DecodeAFPoints($$$$;$);
|
|
|
177
177
|
'4 6' => 'smc PENTAX-FA 35-80mm F4-5.6',
|
|
178
178
|
'4 7' => 'Irix 45mm F1.4', #27
|
|
179
179
|
'4 8' => 'Irix 150mm F2.8 Macro', #exiv2 issue 1084
|
|
180
|
-
'4 9' => 'Irix 11mm F4 Firefly', #27
|
|
180
|
+
'4 9' => 'Irix 11mm F4 Firefly', #27 (guessing the Blackstone version may be the same ID - PH)
|
|
181
181
|
'4 10' => 'Irix 15mm F2.4', #27
|
|
182
182
|
'4 12' => 'smc PENTAX-FA 50mm F1.4', #17
|
|
183
183
|
'4 15' => 'smc PENTAX-FA 28-105mm F4-5.6 [IF]',
|
|
@@ -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.
|
|
51
|
+
$VERSION = '2.94';
|
|
52
52
|
|
|
53
53
|
sub ProcessMOV($$;$);
|
|
54
54
|
sub ProcessKeys($$$);
|
|
@@ -58,11 +58,14 @@ sub ProcessEncodingParams($$$);
|
|
|
58
58
|
sub ProcessSampleDesc($$$);
|
|
59
59
|
sub ProcessHybrid($$$);
|
|
60
60
|
sub ProcessRights($$$);
|
|
61
|
+
sub ProcessNextbase($$$);
|
|
61
62
|
# ++vvvvvvvvvvvv++ (in QuickTimeStream.pl)
|
|
62
63
|
sub Process_mebx($$$);
|
|
63
64
|
sub Process_3gf($$$);
|
|
64
65
|
sub Process_gps0($$$);
|
|
65
66
|
sub Process_gsen($$$);
|
|
67
|
+
sub Process_gdat($$$);
|
|
68
|
+
sub Process_nbmt($$$);
|
|
66
69
|
sub ProcessKenwood($$$);
|
|
67
70
|
sub ProcessLIGO_JSON($$$);
|
|
68
71
|
sub ProcessRIFFTrailer($$$);
|
|
@@ -88,6 +91,7 @@ sub UnpackLang($;$);
|
|
|
88
91
|
sub WriteKeys($$$);
|
|
89
92
|
sub WriteQuickTime($$$);
|
|
90
93
|
sub WriteMOV($$);
|
|
94
|
+
sub WriteNextbase($$$);
|
|
91
95
|
sub GetLangInfo($$);
|
|
92
96
|
sub CheckQTValue($$$);
|
|
93
97
|
|
|
@@ -656,6 +660,14 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
656
660
|
Name => 'SensorData', # sensor data for the 360Fly
|
|
657
661
|
Condition => '$$valPt=~/^\xef\xe1\x58\x9a\xbb\x77\x49\xef\x80\x95\x27\x75\x9e\xb1\xdc\x6f/ and $$self{OPTIONS}{ExtractEmbedded}',
|
|
658
662
|
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Tags360Fly' },
|
|
663
|
+
},{
|
|
664
|
+
Name => 'SensorData',
|
|
665
|
+
Condition => '$$valPt=~/^\xef\xe1\x58\x9a\xbb\x77\x49\xef\x80\x95\x27\x75\x9e\xb1\xdc\x6f/',
|
|
666
|
+
Notes => 'raw 360Fly sensor data without ExtractEmbedded option',
|
|
667
|
+
RawConv => q{
|
|
668
|
+
$self->WarnOnce('Use the ExtractEmbedded option to decode timed SensorData',3);
|
|
669
|
+
return \$val;
|
|
670
|
+
},
|
|
659
671
|
},
|
|
660
672
|
{ #https://c2pa.org/specifications/
|
|
661
673
|
Name => 'JUMBF',
|
|
@@ -685,18 +697,9 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
685
697
|
Start => 27,
|
|
686
698
|
},
|
|
687
699
|
},
|
|
688
|
-
{
|
|
689
|
-
Name => 'SensorData',
|
|
690
|
-
Condition => '$$valPt=~/^\xef\xe1\x58\x9a\xbb\x77\x49\xef\x80\x95\x27\x75\x9e\xb1\xdc\x6f/',
|
|
691
|
-
Notes => 'raw 360Fly sensor data without ExtractEmbedded option',
|
|
692
|
-
RawConv => q{
|
|
693
|
-
$self->WarnOnce('Use the ExtractEmbedded option to decode timed SensorData',3);
|
|
694
|
-
return \$val;
|
|
695
|
-
},
|
|
696
|
-
},
|
|
697
700
|
{ #PH (Canon CR3)
|
|
698
701
|
Name => 'PreviewImage',
|
|
699
|
-
Condition => '$$valPt=~/^\xea\xf4\x2b\x5e\x1c\x98\x4b\x88\xb9\xfb\xb7\xdc\x40\x6e\x4d\x16/',
|
|
702
|
+
Condition => '$$valPt=~/^\xea\xf4\x2b\x5e\x1c\x98\x4b\x88\xb9\xfb\xb7\xdc\x40\x6e\x4d\x16.{32}/s',
|
|
700
703
|
Groups => { 2 => 'Preview' },
|
|
701
704
|
PreservePadding => 1,
|
|
702
705
|
# 0x00 - undef[16]: UUID
|
|
@@ -711,6 +714,25 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
711
714
|
# 0x3c - int32u: preview length
|
|
712
715
|
RawConv => '$val = substr($val, 0x30); $self->ValidateImage(\$val, $tag)',
|
|
713
716
|
},
|
|
717
|
+
{ #PH (Garmin MP4)
|
|
718
|
+
Name => 'ThumbnailImage',
|
|
719
|
+
Condition => '$$valPt=~/^\x11\x6e\x40\xdc\xb1\x86\x46\xe4\x84\x7c\xd9\xc0\xc3\x49\x10\x81.{8}\xff\xd8\xff/s',
|
|
720
|
+
Groups => { 2 => 'Preview' },
|
|
721
|
+
Binary => 1,
|
|
722
|
+
# 0x00 - undef[16]: UUID
|
|
723
|
+
# 0x10 - int32u[2]: ThumbnailLength
|
|
724
|
+
# 0x14 - int16u[2]: width/height of image (160/120)
|
|
725
|
+
RawConv => q{
|
|
726
|
+
my $len = Get32u(\$val, 0x10);
|
|
727
|
+
return undef unless length($val) >= $len + 0x18;
|
|
728
|
+
return substr($val, 0x18, $len);
|
|
729
|
+
},
|
|
730
|
+
},
|
|
731
|
+
# also seen 120-byte record in Garmin MP4's, starting like this (model name at byte 9):
|
|
732
|
+
# 0000: 47 52 4d 4e 00 00 00 01 00 44 43 35 37 00 00 00 [GRMN.....DC57...]
|
|
733
|
+
# 0000: 47 52 4d 4e 00 00 00 01 00 44 43 36 36 57 00 00 [GRMN.....DC66W..]
|
|
734
|
+
# and this in Garmin, followed by 8 bytes of 0's:
|
|
735
|
+
# 0000: db 11 98 3d 8f 65 43 8c bb b8 e1 ac 56 fe 6b 04
|
|
714
736
|
{ #8
|
|
715
737
|
Name => 'UUID-Unknown',
|
|
716
738
|
%unknownInfo,
|
|
@@ -835,6 +857,20 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
835
857
|
},
|
|
836
858
|
# gpsa - seen hex "01 20 00 00" (DuDuBell M1, VSYS M6L)
|
|
837
859
|
# gsea - 20 bytes hex "05 00's..." (DuDuBell M1) "05 08 02 01 ..." (VSYS M6L)
|
|
860
|
+
gdat => { # Base64-encoded JSON-format timed GPS (Nextbase software)
|
|
861
|
+
Name => 'GPSData',
|
|
862
|
+
SubDirectory => {
|
|
863
|
+
TagTable => 'Image::ExifTool::QuickTime::Stream',
|
|
864
|
+
ProcessProc => \&Process_gdat,
|
|
865
|
+
},
|
|
866
|
+
},
|
|
867
|
+
nbmt => { # (Nextbase)
|
|
868
|
+
Name => 'NextbaseMeta',
|
|
869
|
+
SubDirectory => {
|
|
870
|
+
TagTable => 'Image::ExifTool::QuickTime::Stream',
|
|
871
|
+
ProcessProc => \&Process_nbmt,
|
|
872
|
+
},
|
|
873
|
+
},
|
|
838
874
|
'GPS ' => { # GPS data written by 70mai dashcam (parsed in QuickTimeStream.pl)
|
|
839
875
|
Name => 'GPSDataList2',
|
|
840
876
|
Unknown => 1,
|
|
@@ -2090,8 +2126,21 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
2090
2126
|
Condition => '$$valPt =~ /^VIRBactioncamera/',
|
|
2091
2127
|
RawConv => 'substr($val, 16)',
|
|
2092
2128
|
RawConvInv => '"VIRBactioncamera$val"',
|
|
2129
|
+
},{
|
|
2130
|
+
Name => 'GarminModel', # (NC)
|
|
2131
|
+
Condition => '$$valPt =~ /^\xf7\x6c\xd7\x6a\x07\x5b\x4a\x1e\xb3\x1c\x0e\x7f\xab\x7e\x09\xd4/',
|
|
2132
|
+
Writable => 0,
|
|
2133
|
+
RawConv => q{
|
|
2134
|
+
return undef unless length($val) > 25;
|
|
2135
|
+
my $len = unpack('x24C', $val);
|
|
2136
|
+
return undef unless length($val) >= 25 + $len;
|
|
2137
|
+
return substr($val, 25, $len);
|
|
2138
|
+
},
|
|
2093
2139
|
},{
|
|
2094
2140
|
# have seen "28 f3 11 e2 b7 91 4f 6f 94 e2 4f 5d ea cb 3c 01" for RicohThetaZ1 accelerometer RADT data (not yet decoded)
|
|
2141
|
+
# also seen in Garmin MP4:
|
|
2142
|
+
# 51 0b 63 46 6c fd 4a 17 87 42 ea c9 ea ae b3 bd - seems to contain a duplicate of the trak atom
|
|
2143
|
+
# b3 e8 21 f4 fe 33 4e 10 8f 92 f5 e1 d4 36 c9 8a - 8 bytes of zeros
|
|
2095
2144
|
Name => 'UUID-Unknown',
|
|
2096
2145
|
Writable => 0,
|
|
2097
2146
|
%unknownInfo,
|
|
@@ -2399,6 +2448,30 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
2399
2448
|
Groups => { 2 => 'Preview' },
|
|
2400
2449
|
Binary => 1,
|
|
2401
2450
|
},
|
|
2451
|
+
# ---- Nextbase ----
|
|
2452
|
+
info => 'FirmwareVersion',
|
|
2453
|
+
'time' => {
|
|
2454
|
+
Name => 'TimeStamp',
|
|
2455
|
+
Format => 'int32u', # (followed by 4 unknown bytes 00 0d 00 00)
|
|
2456
|
+
Writable => 0,
|
|
2457
|
+
Groups => { 2 => 'Time' },
|
|
2458
|
+
ValueConv => '$val =~ s/ .*//; ConvertUnixTime($val)',
|
|
2459
|
+
PrintConv => '$self->ConvertDateTime($val)',
|
|
2460
|
+
},
|
|
2461
|
+
infi => {
|
|
2462
|
+
Name => 'CameraInfo',
|
|
2463
|
+
SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Nextbase' },
|
|
2464
|
+
},
|
|
2465
|
+
finm => {
|
|
2466
|
+
Name => 'OriginalFileName',
|
|
2467
|
+
Writable => 0,
|
|
2468
|
+
},
|
|
2469
|
+
# AMBA ? - (133 bytes)
|
|
2470
|
+
# nbpl ? - "FP-433-KC"
|
|
2471
|
+
nbpl => { Name => 'Unknown_nbpl', Unknown => 1, Hidden => 1 },
|
|
2472
|
+
# maca ? - b8 2d 28 15 f1 48
|
|
2473
|
+
# sern ? - 0d 69 42 74
|
|
2474
|
+
# nbid ? - 0d 69 42 74 65 df 72 65 03 de c0 fb 01 01 00 00
|
|
2402
2475
|
# ---- Unknown ----
|
|
2403
2476
|
# CDET - 128 bytes (unknown origin)
|
|
2404
2477
|
# mtyp - 4 bytes all zero (some drone video)
|
|
@@ -8087,6 +8160,88 @@ my %isImageData = ( av01 => 1, avc1 => 1, hvc1 => 1, lhv1 => 1, hvt1 => 1 );
|
|
|
8087
8160
|
},
|
|
8088
8161
|
);
|
|
8089
8162
|
|
|
8163
|
+
# Nextbase tags (ref PH)
|
|
8164
|
+
%Image::ExifTool::QuickTime::Nextbase = (
|
|
8165
|
+
GROUPS => { 1 => 'Nextbase', 2 => 'Camera' },
|
|
8166
|
+
PROCESS_PROC => \&ProcessNextbase,
|
|
8167
|
+
WRITE_PROC => \&WriteNextbase,
|
|
8168
|
+
VARS => { LONG_TAGS => 3 },
|
|
8169
|
+
NOTES => q{
|
|
8170
|
+
Tags found in 'infi' atom from some Nextbase videos. As well as these tags,
|
|
8171
|
+
other existing tags are also extracted. These tags are not currently
|
|
8172
|
+
writable but they may all be removed by deleting the Nextbase group.
|
|
8173
|
+
},
|
|
8174
|
+
'Wi-Fi SSID' => { },
|
|
8175
|
+
'Wi-Fi Password' => { },
|
|
8176
|
+
'Wi-Fi MAC Address' => { },
|
|
8177
|
+
'Model' => { },
|
|
8178
|
+
'Firmware' => { },
|
|
8179
|
+
'Serial No' => { Name => 'SerialNumber' },
|
|
8180
|
+
'FCC-ID' => { },
|
|
8181
|
+
'Battery Status' => { },
|
|
8182
|
+
'SD Card Manf ID' => { },
|
|
8183
|
+
'SD Card OEM ID' => { },
|
|
8184
|
+
'SD Card Model No' => { },
|
|
8185
|
+
'SD Card Serial No' => { },
|
|
8186
|
+
'SD Card Manf Date' => { },
|
|
8187
|
+
'SD Card Type' => { },
|
|
8188
|
+
'SD Card Used Space' => { },
|
|
8189
|
+
'SD Card Class' => { },
|
|
8190
|
+
'SD Card Size' => { },
|
|
8191
|
+
'SD Card Format' => { },
|
|
8192
|
+
'Wi-Fi SSID' => { },
|
|
8193
|
+
'Wi-Fi Password' => { },
|
|
8194
|
+
'Wi-Fi MAC Address' => { },
|
|
8195
|
+
'Bluetooth Name' => { },
|
|
8196
|
+
'Bluetooth MAC Address' => { },
|
|
8197
|
+
'Resolution' => { },
|
|
8198
|
+
'Exposure' => { },
|
|
8199
|
+
'Video Length' => { },
|
|
8200
|
+
'Audio' => { },
|
|
8201
|
+
'Time Stamp' => { Name => 'VideoTimeStamp' },
|
|
8202
|
+
'Speed Stamp' => { },
|
|
8203
|
+
'GPS Stamp' => { },
|
|
8204
|
+
'Model Stamp' => { },
|
|
8205
|
+
'Dual Files' => { },
|
|
8206
|
+
'Time Lapse' => { },
|
|
8207
|
+
'Number / License Plate' => { },
|
|
8208
|
+
'G Sensor' => { },
|
|
8209
|
+
'Image Stabilisation' => { },
|
|
8210
|
+
'Extreme Weather Mode' => { },
|
|
8211
|
+
'Screen Saver' => { },
|
|
8212
|
+
'Alerts' => { },
|
|
8213
|
+
'Recording History' => { },
|
|
8214
|
+
'Parking Mode' => { },
|
|
8215
|
+
'Language' => { },
|
|
8216
|
+
'Country' => { },
|
|
8217
|
+
'Time Zone / DST' => { Groups => { 2 => 'Time' } },
|
|
8218
|
+
'Time & Date' => { Name => 'TimeAndDate', Groups => { 2 => 'Time' } },
|
|
8219
|
+
'Speed Units' => { },
|
|
8220
|
+
'Device Sounds' => { },
|
|
8221
|
+
'Screen Dimming' => { },
|
|
8222
|
+
'Auto Power Off' => { },
|
|
8223
|
+
'Keep User Settings' => { },
|
|
8224
|
+
'System Info' => { },
|
|
8225
|
+
'Format SD Card' => { },
|
|
8226
|
+
'Default Settings' => { },
|
|
8227
|
+
'Emergency SOS' => { },
|
|
8228
|
+
'Reversing Camera' => { },
|
|
8229
|
+
'what3words' => { Name => 'What3Words' },
|
|
8230
|
+
'MyNextbase - Pairing' => { },
|
|
8231
|
+
'MyNextbase - Paired Device Name' => { },
|
|
8232
|
+
'Alexa' => { },
|
|
8233
|
+
'Alexa - Pairing' => { },
|
|
8234
|
+
'Alexa - Paired Device Name' => { },
|
|
8235
|
+
'Alexa - Privacy Mode' => { },
|
|
8236
|
+
'Alexa - Wake Word Language' => { },
|
|
8237
|
+
'Firmware Version' => { },
|
|
8238
|
+
'RTOS' => { },
|
|
8239
|
+
'Linux' => { },
|
|
8240
|
+
'NBCD' => { },
|
|
8241
|
+
'Alexa' => { },
|
|
8242
|
+
'2nd Cam' => { Name => 'SecondCam' },
|
|
8243
|
+
);
|
|
8244
|
+
|
|
8090
8245
|
# QuickTime composite tags
|
|
8091
8246
|
%Image::ExifTool::QuickTime::Composite = (
|
|
8092
8247
|
GROUPS => { 2 => 'Video' },
|
|
@@ -9149,6 +9304,23 @@ sub ProcessRights($$$)
|
|
|
9149
9304
|
return 1;
|
|
9150
9305
|
}
|
|
9151
9306
|
|
|
9307
|
+
#------------------------------------------------------------------------------
|
|
9308
|
+
# Process Nextbase 'infi' atom (ref PH)
|
|
9309
|
+
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
|
|
9310
|
+
# Returns: 1 on success
|
|
9311
|
+
sub ProcessNextbase($$$)
|
|
9312
|
+
{
|
|
9313
|
+
my ($et, $dirInfo, $tagTbl) = @_;
|
|
9314
|
+
my $dataPt = $$dirInfo{DataPt};
|
|
9315
|
+
$et->VerboseDir('Nextbase', undef, length($$dataPt));
|
|
9316
|
+
while ($$dataPt =~ /(.*?): +(.*)\x0d/g) {
|
|
9317
|
+
my ($id, $val) = ($1, $2);
|
|
9318
|
+
$$tagTbl{$id} or AddTagToTable($tagTbl, $id, { Name => Image::ExifTool::MakeTagName($id) });
|
|
9319
|
+
$et->HandleTag($tagTbl, $id, $val, Size => length($val));
|
|
9320
|
+
}
|
|
9321
|
+
return 1;
|
|
9322
|
+
}
|
|
9323
|
+
|
|
9152
9324
|
#------------------------------------------------------------------------------
|
|
9153
9325
|
# Process iTunes Encoding Params (ref PH)
|
|
9154
9326
|
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
|