summaryrefslogtreecommitdiff
path: root/lib/Image
diff options
context:
space:
mode:
authorexiftool <exiftool@users.sourceforge.net>2020-07-27 16:31:19 -0400
committerexiftool <exiftool@users.sourceforge.net>2020-07-27 16:31:19 -0400
commit6ef7fc5a2e65639a1d3883708d44cde6b9c18b15 (patch)
treeef8e699653006fc2d71ab5ae8efadedaa956607f /lib/Image
parent3d8a19238300c21f48ee8bc82b79b101fb3a67b8 (diff)
Update to 12.02
Diffstat (limited to 'lib/Image')
-rw-r--r--lib/Image/ExifTool.pm13
-rw-r--r--lib/Image/ExifTool/CanonCustom.pm98
-rw-r--r--lib/Image/ExifTool/GoPro.pm2
-rw-r--r--lib/Image/ExifTool/Panasonic.pm15
-rw-r--r--lib/Image/ExifTool/PanasonicRaw.pm33
-rw-r--r--lib/Image/ExifTool/Parrot.pm3
-rw-r--r--lib/Image/ExifTool/Pentax.pm3
-rw-r--r--lib/Image/ExifTool/QuickTime.pm153
-rw-r--r--lib/Image/ExifTool/QuickTimeStream.pl153
-rw-r--r--lib/Image/ExifTool/Ricoh.pm20
-rw-r--r--lib/Image/ExifTool/Sony.pm94
-rw-r--r--lib/Image/ExifTool/TagLookup.pm37
-rw-r--r--lib/Image/ExifTool/TagNames.pod67
-rw-r--r--lib/Image/ExifTool/Writer.pl26
-rw-r--r--lib/Image/ExifTool/XMP.pm4
15 files changed, 643 insertions, 78 deletions
diff --git a/lib/Image/ExifTool.pm b/lib/Image/ExifTool.pm
index f0679430..808f1c94 100644
--- a/lib/Image/ExifTool.pm
+++ b/lib/Image/ExifTool.pm
@@ -28,7 +28,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
%mimeType $swapBytes $swapWords $currentByteOrder %unpackStd
%jpegMarker %specialTags %fileTypeLookup $testLen $exePath);
-$VERSION = '12.01';
+$VERSION = '12.02';
$RELEASE = '';
@ISA = qw(Exporter);
%EXPORT_TAGS = (
@@ -3349,6 +3349,17 @@ sub GetGroup($$;$)
$groups[6] = $$ex{G6};
}
}
+ if ($$self{OPTIONS}{SaveIDGroup}) {
+ my $id = $$tagInfo{TagID};
+ $id = '' unless defined $id;
+ if ($$self{OPTIONS}{SaveIDGroup} eq '2' and $id =~ /^\d+$/) {
+ $groups[7] = 'ID_' . sprintf('0x%x', $id);
+ } else {
+ $id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge;
+ $groups[7] = 'ID_' . $id;
+ }
+ defined $groups[$_] or $groups[$_] = '' foreach (5,6);
+ }
if ($family) {
return $groups[$family] || '' if $family > 0;
# add additional matching group names to list
diff --git a/lib/Image/ExifTool/CanonCustom.pm b/lib/Image/ExifTool/CanonCustom.pm
index 2cb7405b..fdddea8a 100644
--- a/lib/Image/ExifTool/CanonCustom.pm
+++ b/lib/Image/ExifTool/CanonCustom.pm
@@ -19,7 +19,7 @@ use Image::ExifTool qw(:DataAccess);
use Image::ExifTool::Canon;
use Image::ExifTool::Exif;
-$VERSION = '1.56';
+$VERSION = '1.57';
sub ProcessCanonCustom($$$);
sub ProcessCanonCustom2($$$);
@@ -1326,9 +1326,15 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv );
2 => 'Enable (ISO speed)',
},
},
- 0x0109 => {
+ 0x0109 => [{ # (1DXmkIII)
Name => 'UsableShootingModes',
- Count => 2, # (Count is 1 for 1DXmkIII -- need to decode this)
+ Condition => '$count == 1',
+ Count => 1,
+ PrintConv => 'sprintf("Flags 0x%x",$val)',
+ PrintConvInv => '$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
+ },{
+ Name => 'UsableShootingModes',
+ Count => 2,
PrintConv => [
\%disableEnable,
'sprintf("Flags 0x%x",$val)', # (M, Tv, Av, P, Bulb)
@@ -1337,10 +1343,16 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv );
undef,
'$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
],
- },
- 0x010a => {
+ }],
+ 0x010a => [{ # (1DXmkIII)
Name => 'UsableMeteringModes',
- Count => 2, # (Count is 1 for 1DXmkIII -- need to decode this)
+ Condition => '$count == 1',
+ Count => 1,
+ PrintConv => 'sprintf("Flags 0x%x",$val)',
+ PrintConvInv => '$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
+ },{
+ Name => 'UsableMeteringModes',
+ Count => 2,
PrintConv => [
\%disableEnable,
'sprintf("Flags 0x%x",$val)', # (evaluative,partial,spot,center-weighted average)
@@ -1349,7 +1361,7 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv );
undef,
'$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
],
- },
+ }],
0x010b => {
Name => 'ExposureModeInManual',
PrintConv => {
@@ -2066,7 +2078,27 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv );
2 => 'Enable: Down with Set',
},
},
- 0x0610 => {
+ 0x0610 => [{ # (1DXmkIII)
+ Name => 'ContinuousShootingSpeed',
+ Condition => '$count == 6',
+ Count => 6,
+ PrintConv => [
+ \%disableEnable,
+ '"Hi $val"',
+ '"Cont $val"',
+ '"Lo $val"',
+ '"Soft $val"',
+ '"Soft LS $val"',
+ ],
+ PrintConvInv => [
+ undef,
+ '$val=~/(\d+)/ ? $1 : 0',
+ '$val=~/(\d+)/ ? $1 : 0',
+ '$val=~/(\d+)/ ? $1 : 0',
+ '$val=~/(\d+)/ ? $1 : 0',
+ '$val=~/(\d+)/ ? $1 : 0',
+ ],
+ },{ # others
Name => 'ContinuousShootingSpeed',
Count => 3,
PrintConv => [
@@ -2079,7 +2111,7 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv );
'$val=~/(\d+)/ ? $1 : 0',
'$val=~/(\d+)/ ? $1 : 0',
],
- },
+ }],
0x0611 => {
Name => 'ContinuousShotLimit',
Count => 2,
@@ -2092,9 +2124,15 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv );
'$val=~/(\d+)/ ? $1 : 0',
],
},
- 0x0612 => { # (1DX)
+ 0x0612 => [{ # (1DXmkIII)
+ Name => 'RestrictDriveModes',
+ Condition => '$count == 1',
+ Count => 1,
+ PrintConv => 'sprintf("Flags 0x%x",$val)',
+ PrintConvInv => '$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
+ },{ # (1DX)
Name => 'RestrictDriveModes',
- Count => 2, # (Count is 1 for 1DXmkIII -- need to decode this)
+ Count => 2,
PrintConv => [
\%disableEnable,
'sprintf("Flags 0x%x",$val)', # (Single,Cont Hi,Cont Lo,Timer 10,Timer 2,Silent,Super Hi)
@@ -2103,7 +2141,7 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv );
undef,
'$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
],
- },
+ }],
#### 4a) Operation
0x0701 => [
{
@@ -2458,7 +2496,21 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv );
},
},
],
- 0x080c => {
+ 0x080c => [{ # (1DXmkIII)
+ Name => 'TimerLength',
+ Condition => '$count == 3',
+ Count => 3,
+ PrintConv => [
+ '"6 s: $val"',
+ '"16 s: $val"',
+ '"After release: $val"',
+ ],
+ PrintConvInv => [
+ '$val=~/(\d+)$/ ? $1 : 0',
+ '$val=~/(\d+)$/ ? $1 : 0',
+ '$val=~/(\d+)$/ ? $1 : 0',
+ ],
+ },{
Name => 'TimerLength',
Count => 4,
PrintConv => [
@@ -2473,7 +2525,7 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv );
'$val=~/(\d+)$/ ? $1 : 0',
'$val=~/(\d+)$/ ? $1 : 0',
],
- },
+ }],
0x080d => {
Name => 'ShortReleaseTimeLag',
PrintConv => \%disableEnable,
@@ -2520,6 +2572,8 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv );
PrintConv => {
0 => 'Cancel selected',
1 => 'Erase selected',
+ 2 => 'Erase RAW selected', # (1DXmkIII)
+ 3 => 'Erase non-RAW selected', # (1DXmkIII)
},
},
0x0814 => { # (5DS)
@@ -2595,7 +2649,7 @@ sub ProcessCanonCustom2($$$)
my $recPos = $pos;
my $recEnd = $pos + $recLen - 8;
if ($recEnd > $end) {
- $et->Warn('Corrupted CanonCustom2 group');
+ $et->Warn("Corrupted CanonCustom2 group $recNum");
return 0;
}
if ($verbose and not $write) {
@@ -2605,8 +2659,17 @@ sub ProcessCanonCustom2($$$)
for ($i=0; $recPos + 8 < $recEnd; ++$i, $recPos+=4*$num) {
$tag = Get32u($dataPt, $recPos);
$num = Get32u($dataPt, $recPos + 4);
+ my $nextRec = $recPos + 8 + $num * 4;
+ last if $nextRec > $recEnd;
+ # patch for EOS-1DXmkIII firmware 1.0.0 bug:
+ if ($tag == 0x70c and $num == 0x66 and $nextRec + 8 < $recEnd) {
+ my $tmp = Get32u($dataPt, $nextRec + 4);
+ if ($tmp == 0x70f) {
+ $et->Warn('Fixed incorrect CanonCustom tag 0x70c size', 1);
+ ++$num; # (count should be one greater)
+ }
+ }
$recPos += 8;
- last if $recPos + $num * 4 > $recEnd;
my $val = ReadValue($dataPt, $recPos, 'int32s', $num, $num * 4);
if ($write) {
# write new value
@@ -2638,6 +2701,9 @@ sub ProcessCanonCustom2($$$)
}
}
}
+ if ($i != $recCount) {
+ $et->Warn('Missing '.($recCount-$i)." entries in CanonCustom2 group $recNum directory", 1);
+ }
$pos = $recEnd;
}
if ($pos != $end) {
diff --git a/lib/Image/ExifTool/GoPro.pm b/lib/Image/ExifTool/GoPro.pm
index a873f3c4..d24a5bc6 100644
--- a/lib/Image/ExifTool/GoPro.pm
+++ b/lib/Image/ExifTool/GoPro.pm
@@ -603,7 +603,7 @@ sub ProcessGoPro($$$)
my ($size, $type, $unit, $scal, $setGroup0);
# the Rove Stealth 4K writes encrypted text here, so check for this first
- # (really should check for this before loading GoPro module, but I was lazy)
+ # (really should check for this before loading GoPro module, but I was lazy) PHIL
if ($$dataPt =~ /^\0\0\xf2\xe1\xf0\xeeTT/) {
$et->VerboseDir('gpmd encrypted text', undef, length($$dataPt));
my $strmTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
diff --git a/lib/Image/ExifTool/Panasonic.pm b/lib/Image/ExifTool/Panasonic.pm
index 275dd784..e8671dee 100644
--- a/lib/Image/ExifTool/Panasonic.pm
+++ b/lib/Image/ExifTool/Panasonic.pm
@@ -736,8 +736,19 @@ my %shootingMode = (
PrintConvInv => '$val =~ /(\d+)/ ? $1 : $val',
},
# 0x37 - values: 0,1,2 (LZ6, 0 for movie preview); 257 (FX10K); 0,256 (TZ5, 0 for movie preview)
- # 0x38 - values: 0,1,2 (LZ6, same as 0x37); 1,2 (FX10K); 0,256 (TZ5, 0 for movie preview)
- # - changes with noise reduction for DC-S1
+ 0x38 => { #forum11388
+ Name => 'BatteryLevel',
+ Writable => 'int16u',
+ PrintConv => {
+ 1 => 'Full',
+ 2 => 'Medium',
+ 3 => 'Low',
+ 4 => 'Near Empty',
+ 7 => 'Near Full',
+ 8 => 'Medimu Low',
+ 256 => 'n/a',
+ },
+ },
0x39 => { #7 (L1/L10)
Name => 'Contrast',
Format => 'int16s',
diff --git a/lib/Image/ExifTool/PanasonicRaw.pm b/lib/Image/ExifTool/PanasonicRaw.pm
index e259c201..ea0931a0 100644
--- a/lib/Image/ExifTool/PanasonicRaw.pm
+++ b/lib/Image/ExifTool/PanasonicRaw.pm
@@ -531,14 +531,45 @@ my %panasonicWhiteBalance = ( #forum9396
PrintConv => '"$val mm"',
PrintConvInv => '$val=~s/\s*mm$//;$val',
},
+ # 0x1300 - incident light value? (ref forum11395)
+ 0x1301 => { #forum11395
+ Name => 'ApertureValue',
+ Writable => 'int16s',
+ Priority => 0,
+ ValueConv => '2 ** ($val / 512)',
+ ValueConvInv => '$val>0 ? 512*log($val)/log(2) : 0',
+ PrintConv => 'sprintf("%.1f",$val)',
+ PrintConvInv => '$val',
+ },
+ 0x1302 => { #forum11395
+ Name => 'ShutterSpeedValue',
+ Writable => 'int16s',
+ Priority => 0,
+ ValueConv => 'abs($val/256)<100 ? 2**(-$val/256) : 0',
+ ValueConvInv => '$val>0 ? -256*log($val)/log(2) : -25600',
+ PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+ PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+ },
+ 0x1303 => { #forum11395
+ Name => 'SensitivityValue',
+ Writable => 'int16s',
+ ValueConv => '$val / 256',
+ ValueConvInv => 'int($val * 256)',
+ },
0x1305 => { #forum9384
Name => 'HighISOMode',
Writable => 'int16u',
RawConv => '$val || undef',
PrintConv => { 1 => 'On', 2 => 'Off' },
},
+ # 0x1306 EV for some models like the GX8 (forum11395)
# 0x140b - scaled overall black level? (ref forum9281)
# 0x1411 - scaled black level per channel difference (ref forum9281)
+ 0x1412 => { #forum11397
+ Name => 'FacesDetected',
+ Writable => 'int8u',
+ PrintConv => { 0 => 'No', 1 => 'Yes' },
+ },
# 0x2000 - WB tungsten=3, daylight=4 (ref forum9467)
# 0x2009 - scaled black level per channel (ref forum9281)
# 0x3000-0x310b - red/blue balances * 1024 (ref forum9467)
@@ -600,6 +631,8 @@ my %panasonicWhiteBalance = ( #forum9396
Writable => 'int8u',
PrintConv => \%Image::ExifTool::Exif::orientation,
},
+ # 0x3504 = Tag 0x1301+0x1302-0x1303 (Bv = Av+Tv-Sv) (forum11395)
+ # 0x3505 - same as 0x1300 (forum11395)
0x3600 => { #forum9396
Name => 'WhiteBalanceDetected',
Writable => 'int8u',
diff --git a/lib/Image/ExifTool/Parrot.pm b/lib/Image/ExifTool/Parrot.pm
index a67db62c..d42cbc2a 100644
--- a/lib/Image/ExifTool/Parrot.pm
+++ b/lib/Image/ExifTool/Parrot.pm
@@ -13,7 +13,7 @@ package Image::ExifTool::Parrot;
use strict;
use vars qw($VERSION);
-$VERSION = '1.00';
+$VERSION = '1.01';
sub Process_mett($$$);
@@ -703,6 +703,7 @@ sub Process_mett($$$)
$et->HandleTag($tagTbl, $id, undef,
DataPt => $dataPt,
DataPos => $dataPos,
+ Base => $$dirInfo{Base},
Start => $pos,
Size => $size,
);
diff --git a/lib/Image/ExifTool/Pentax.pm b/lib/Image/ExifTool/Pentax.pm
index 2265e882..5fdd6b77 100644
--- a/lib/Image/ExifTool/Pentax.pm
+++ b/lib/Image/ExifTool/Pentax.pm
@@ -58,7 +58,7 @@ use Image::ExifTool::Exif;
use Image::ExifTool::GPS;
use Image::ExifTool::HP;
-$VERSION = '3.32';
+$VERSION = '3.33';
sub CryptShutterCount($$);
sub PrintFilter($$$);
@@ -338,6 +338,7 @@ sub DecodeAFPoints($$$$;$);
'8 63' => 'HD PENTAX-D FA 15-30mm F2.8 ED SDM WR', #PH
'8 64' => 'HD PENTAX-D FA* 50mm F1.4 SDM AW', #27
'8 65' => 'HD PENTAX-D FA 70-210mm F4 ED SDM WR', #PH
+ '8 66' => 'HD PEBTAX-D FA 85mm F1.4 ED SDM AW', #James O'Neill
'8 196' => 'HD PENTAX-DA* 11-18mm F2.8 ED DC AW', #29
'8 197' => 'HD PENTAX-DA 55-300mm F4.5-6.3 ED PLM WR RE', #29
'8 198' => 'smc PENTAX-DA L 18-50mm F4-5.6 DC WR RE', #29
diff --git a/lib/Image/ExifTool/QuickTime.pm b/lib/Image/ExifTool/QuickTime.pm
index 4c2e16af..65758d74 100644
--- a/lib/Image/ExifTool/QuickTime.pm
+++ b/lib/Image/ExifTool/QuickTime.pm
@@ -46,7 +46,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
use Image::ExifTool::Exif;
use Image::ExifTool::GPS;
-$VERSION = '2.50';
+$VERSION = '2.51';
sub ProcessMOV($$;$);
sub ProcessKeys($$$);
@@ -420,7 +420,8 @@ my %eeBox = (
sbtl => { %eeStd },
data => { %eeStd },
camm => { %eeStd }, # (Insta360)
- '' => { 'gps ' => 'moov' }, # (no handler -- in top level 'moov' box)
+ ctbx => { %eeStd }, # (GM cars)
+ '' => { 'gps ' => 'moov', 'GPS ' => 'main' }, # (no handler -- in top level 'moov' box, and main)
);
# QuickTime atoms
@@ -683,6 +684,11 @@ my %eeBox = (
},
# gpsa - seen hex "01 20 00 00" (DuDuBell M1, VSYS M6L)
# gsea - 20 bytes hex "05 00's..." (DuDuBell M1) "05 08 02 01 ..." (VSYS M6L)
+ 'GPS ' => { # GPS data written by 70mai dashcam (parsed in QuickTimeStream.pl)
+ Name => 'GPSDataList2',
+ Unknown => 1,
+ Binary => 1,
+ },
);
# MPEG-4 'ftyp' atom
@@ -978,7 +984,7 @@ my %eeBox = (
%Image::ExifTool::QuickTime::CleanAperture = (
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
GROUPS => { 2 => 'Video' },
- FORMAT => 'rational64u',
+ FORMAT => 'rational64s',
0 => 'CleanApertureWidth',
1 => 'CleanApertureHeight',
2 => 'CleanApertureOffsetX',
@@ -1387,8 +1393,8 @@ my %eeBox = (
},
ValueConvInv => q{
require Image::ExifTool::XMP;
- $val = Image::ExifTool::XMP::FormatXMPDate($val);
- $val =~ s/([-+]\d{2}):(\d{2})$/$1$2/; # remove time zone colon
+ my $tmp = Image::ExifTool::XMP::FormatXMPDate($val);
+ ($val = $tmp) =~ s/([-+]\d{2}):(\d{2})$/$1$2/ if defined $tmp; # remove time zone colon
return $val;
},
PrintConv => '$self->ConvertDateTime($val)',
@@ -1873,6 +1879,25 @@ my %eeBox = (
ByteOrder => 'LittleEndian',
},
},
+ # ---- Garmin ---- (ref PH)
+ uuid => [{
+ Name => 'GarminSoftware', # (NC)
+ Condition => '$$valPt =~ /^VIRBactioncamera/',
+ RawConv => 'substr($val, 16)',
+ RawConvInv => '"VIRBactioncamera$val"',
+ },{
+ # 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)
+ Name => 'UUID-Unknown',
+ Writable => 0,
+ %unknownInfo,
+ }],
+ pmcc => {
+ Name => 'GarminSettings',
+ ValueConv => 'substr($val, 4)',
+ ValueConvInv => '"\0\0\0\x01$val"',
+ },
+ # hmtp - "\0\0\0\x01" followed by 408 bytes of zero
+ # vrin - "\0\0\0\x01" followed by 8 bytes of zero
# ---- GoPro ---- (ref PH)
GoPr => 'GoProType', # (Hero3+)
FIRM => { Name => 'FirmwareVersion', Avoid => 1 }, # (Hero4)
@@ -2056,6 +2081,63 @@ my %eeBox = (
ProcessProc => \&Image::ExifTool::ProcessTIFF, # (because ProcessMOV is default)
},
},
+ '@mak' => { Name => 'Make', Avoid => 1 },
+ '@mod' => { Name => 'Model', Avoid => 1 },
+ '@swr' => { Name => 'SoftwareVersion', Avoid => 1 },
+ '@day' => {
+ Name => 'ContentCreateDate',
+ Notes => q{
+ some stupid Ricoh programmer used the '@' symbol instead of the copyright
+ symbol in these tag ID's for the Ricoh Theta Z1 and maybe other models
+ },
+ Groups => { 2 => 'Time' },
+ Shift => 'Time',
+ Avoid => 1,
+ # handle values in the form "2010-02-12T13:27:14-0800"
+ ValueConv => q{
+ require Image::ExifTool::XMP;
+ $val = Image::ExifTool::XMP::ConvertXMPDate($val);
+ $val =~ s/([-+]\d{2})(\d{2})$/$1:$2/; # add colon to timezone if necessary
+ return $val;
+ },
+ ValueConvInv => q{
+ require Image::ExifTool::XMP;
+ my $tmp = Image::ExifTool::XMP::FormatXMPDate($val);
+ ($val = $tmp) =~ s/([-+]\d{2}):(\d{2})$/$1$2/ if defined $tmp; # remove time zone colon
+ return $val;
+ },
+ PrintConv => '$self->ConvertDateTime($val)',
+ PrintConvInv => '$self->InverseDateTime($val)',
+ },
+ '@xyz' => { #PH (iPhone 3GS)
+ Name => 'GPSCoordinates',
+ Groups => { 2 => 'Location' },
+ Avoid => 1,
+ ValueConv => \&ConvertISO6709,
+ ValueConvInv => \&ConvInvISO6709,
+ PrintConv => \&PrintGPSCoordinates,
+ PrintConvInv => \&PrintInvGPSCoordinates,
+ },
+ # RDT1 - pairs of int32u_BE, starting at byte 8: "458275 471846"
+ # RDT2 - pairs of int32u_BE, starting at byte 8: "472276 468526"
+ # RDT3 - pairs of int32u_BE, starting at byte 8: "876603 482191"
+ # RDT4 - pairs of int32u_BE, starting at byte 8: "1955 484612"
+ # RDT6 - empty
+ # RDT7 - empty
+ # RDT8 - empty
+ # RDT9 - only 16-byte header?
+ # the boxes below all have a similar header (little-endian):
+ # 0 int32u - number of records
+ # 4 ? - "1e 00"
+ # 6 int16u - record length in bytes
+ # 8 ? - "23 01 00 00 00 00 00 00"
+ # 16 - start of records (each record ends in an int64u timestamp in ns)
+ # RDTA - float[4],ts: "-0.31289672 -0.2245330 11.303817 0 775.780"
+ # RDTB - float[4],ts: "-0.04841613 -0.2166595 0.0724792 0 775.780"
+ # RDTC - float[4],ts: "27.60925 -27.10037 -13.27285 0 775.829"
+ # RDTD - int16s[3],ts: "353 -914 16354 0 775.829"
+ # RDTG - ts: "775.825"
+ # RDTI - float[4],ts: "0.00165951 0.005770059 0.06838259 0.1744695 775.862"
# ---- Samsung ----
vndr => 'Vendor', #PH (Samsung PL70)
SDLN => 'PlayMode', #PH (NC, Samsung ST80 "SEQ_PLAY")
@@ -2571,7 +2653,7 @@ my %eeBox = (
},
clap => {
Name => 'CleanAperture',
- Format => 'rational64u',
+ Format => 'rational64s',
Notes => '4 numbers: width, height, left and top',
},
hvcC => {
@@ -2909,7 +2991,6 @@ my %eeBox = (
"\xa9grp" => 'Grouping',
"\xa9lyr" => 'Lyrics',
"\xa9nam" => 'Title',
- # "\xa9st3" ? #10
"\xa9too" => 'Encoder',
"\xa9trk" => 'Track',
"\xa9wrt" => 'Composer',
@@ -2927,8 +3008,17 @@ my %eeBox = (
disk => {
Name => 'DiskNumber',
Format => 'undef', # (necessary to prevent decoding as string!)
- ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val',
- ValueConvInv => 'my @a = split / of /, $val; @a==2 ? pack("n3",0,@a) : undef',
+ ValueConv => q{
+ return \$val unless length($val) >= 6;
+ my @a = unpack 'x2nn', $val;
+ return $a[1] ? join(' of ', @a) : $a[0];
+ },
+ ValueConvInv => q{
+ my @a = $val =~ /\d+/g;
+ return undef if @a == 0 or @a > 2;
+ push @a, 0 if @a == 1;
+ return pack('n3', 0, @a);
+ },
},
pgap => { #10
Name => 'PlayGap',
@@ -2945,8 +3035,17 @@ my %eeBox = (
trkn => {
Name => 'TrackNumber',
Format => 'undef', # (necessary to prevent decoding as string!)
- ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val',
- ValueConvInv => 'my @a = split / of /, $val; @a==2 ? pack("n3",0,@a) : undef',
+ ValueConv => q{
+ return \$val unless length($val) >= 6;
+ my @a = unpack 'x2nn', $val;
+ return $a[1] ? join(' of ', @a) : $a[0];
+ },
+ ValueConvInv => q{
+ my @a = $val =~ /\d+/g;
+ return undef if @a == 0 or @a > 2;
+ push @a, 0 if @a == 1;
+ return pack('n3', 0, @a);
+ },
},
#
# Note: it is possible that the tags below are not being decoded properly
@@ -6162,6 +6261,21 @@ my %eeBox = (
# (fiel)com.apple.quicktime.detected-face.yaw-angle (dtyp=23, float)
'detected-face.yaw-angle' => { Name => 'DetectedFaceYawAngle', Writable => 0 },
#
+# the following tags written by AtomicParsley 0.9.6
+# (ref https://exiftool.org/forum/index.php?topic=11455.0)
+#
+ "\xa9st3" => 'Subtitle',
+ "\xa9con" => 'Conductor',
+ "\xa9sol" => 'Soloist',
+ "\xa9arg" => 'Arranger',
+ "\xa9ope" => 'OriginalArtist',
+ "\xa9dir" => 'Director',
+ "\xa9ard" => 'ArtDirector',
+ "\xa9sne" => 'SoundEngineer',
+ "\xa9prd" => 'Producer',
+ "\xa9xpd" => 'ExecutiveProducer',
+ sdes => 'StoreDescription',
+#
# seen in Apple ProRes RAW file
#
# (mdta)com.apple.proapps.manufacturer (eg. "Sony")
@@ -6753,6 +6867,7 @@ my %eeBox = (
# alac - 28 bytes
# adrm - AAX DRM atom? 148 bytes
# aabd - AAX unknown 17kB (contains 'aavd' strings)
+ # SA3D - written by Garmin VIRB360
);
# AMR decode config box (ref 3)
@@ -7239,6 +7354,20 @@ my %eeBox = (
#
ftab => { Name => 'FontTable', Format => 'undef', ValueConv => 'substr($val, 5)' },
name => { Name => 'OtherName', Format => 'undef', ValueConv => 'substr($val, 4)' },
+ # mrlh = GM header?
+ # mrlv = GM data
+ # mrld = GM data (448-byte records):
+ # 0 - int32u count
+ # 4 - int32u ? (related to units) 0=none,1=m/km,2=L,3=kph,4=C,7=deg,8=rpm,9=kPa,10=G,11=V,15=Nm,16=%
+ # 8 - int32u ? (0,1,3,4,5)
+ # 12 - string[64] units
+ # 76 - int32u ? (1,3,7,15)
+ # 80 - int32u 0
+ # 84 - undef[4] ?
+ # 88 - int16u[6] ?
+ # 100 - undef[32] ?
+ # 132 - string[64] measurement name
+ # 196 - string[64] measurement name
);
# MP4 data information box (ref 5)
@@ -8596,7 +8725,7 @@ sub ProcessKeys($$$)
my $ns = substr($$dataPt, $pos + 4, 4);
my $tag = substr($$dataPt, $pos + 8, $len - 8);
$tag =~ s/\0.*//s; # truncate at null
- $tag =~ s/^com\.apple\.quicktime\.// if $ns eq 'mdta'; # remove apple quicktime domain
+ $tag =~ s/^com\.(apple\.quicktime\.)?// if $ns eq 'mdta'; # remove apple quicktime domain
$tag = "Tag_$ns" unless $tag;
# (I have some samples where the tag is a reversed ItemList or UserData tag ID)
my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
diff --git a/lib/Image/ExifTool/QuickTimeStream.pl b/lib/Image/ExifTool/QuickTimeStream.pl
index b6c14b44..3c6398af 100644
--- a/lib/Image/ExifTool/QuickTimeStream.pl
+++ b/lib/Image/ExifTool/QuickTimeStream.pl
@@ -19,6 +19,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
use Image::ExifTool::QuickTime;
sub Process_tx3g($$$);
+sub Process_marl($$$);
sub Process_mebx($$$);
sub ProcessFreeGPS($$$);
sub ProcessFreeGPS2($$$);
@@ -71,6 +72,7 @@ my %processByMetaFormat = (
meta => 1, # ('CTMD' in CR3 images, 'priv' unknown in DJI video)
data => 1, # ('RVMI')
sbtl => 1, # (subtitle; 'tx3g' in Yuneec drone videos)
+ ctbx => 1, # ('marl' in GM videos)
);
# data lengths for each INSV record type
@@ -92,7 +94,7 @@ my %insvLimit = (
NOTES => q{
Timed metadata extracted from QuickTime media data and some AVI videos when
the ExtractEmbedded option is used. Although most of these tags are
- combined into the single table below, ExifTool currently reads 37 different
+ combined into the single table below, ExifTool currently reads 46 different
formats of timed GPS metadata from video files.
},
VARS => { NO_ID => 1 },
@@ -174,6 +176,10 @@ my %insvLimit = (
Name => 'rtmd',
SubDirectory => { TagTable => 'Image::ExifTool::Sony::rtmd' },
},
+ marl => {
+ Name => 'marl',
+ SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::marl' },
+ },
CTMD => { # (Canon Timed MetaData)
Name => 'CTMD',
SubDirectory => { TagTable => 'Image::ExifTool::Canon::CTMD' },
@@ -673,6 +679,13 @@ my %insvLimit = (
10 => { Name => 'FusionYPR', Format => 'float[3]' },
);
+# tags found in 'marl' ctbx timed metadata (ref PH)
+%Image::ExifTool::QuickTime::marl = (
+ PROCESS_PROC => \&Process_marl,
+ GROUPS => { 2 => 'Other' },
+ NOTES => 'Tags extracted from the marl ctbx timed metadata of GM cars.',
+);
+
#------------------------------------------------------------------------------
# Save information from keys in OtherSampleDesc directory for processing timed metadata
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
@@ -773,7 +786,7 @@ sub FoundSomething($$;$$)
#------------------------------------------------------------------------------
# Approximate GPSDateTime value from sample time and CreateDate
-# Inputs: 0) ExifTool ref, 1) tag table ptr, 2) sample time (ms)
+# Inputs: 0) ExifTool ref, 1) tag table ptr, 2) sample time (s)
# 3) true if CreateDate is at end of video
# Notes: Uses ExifTool CreateDateAtEnd as flag to subtract video duration
sub SetGPSDateTime($$$)
@@ -821,7 +834,7 @@ sub HandleTextTags($$$)
#------------------------------------------------------------------------------
# Process subtitle 'text'
-# Inputs: 0) ExifTool ref, 1) tag table ref, 2) data ref, 3) optional sample time
+# Inputs: 0) ExifTool ref, 1) tag table ref, 2) data ref
sub Process_text($$$)
{
my ($et, $tagTbl, $buffPt) = @_;
@@ -1226,8 +1239,8 @@ sub ProcessSamples($)
$$et{ee} = $ee; # need ee information for 'keys'
$et->HandleTag($tagTbl, $metaFormat, undef,
DataPt => \$buff,
- DataPos => $$start[$i],
- Base => $$start[$i],
+ DataPos => 0,
+ Base => $$start[$i], # (Base must be set for CR3 files)
TagInfo => $tagInfo,
);
delete $$et{ee};
@@ -1239,7 +1252,7 @@ sub ProcessSamples($)
Process_text($et, $tagTbl, \$buff);
}
} elsif ($verbose) {
- $et->VPrint(0, "Unknown meta format ($metaFormat)");
+ $et->VPrint(0, "Unknown $type format ($metaFormat)");
}
} elsif ($type eq 'gps ') { # (ie. GPSDataList tag)
@@ -1261,8 +1274,8 @@ sub ProcessSamples($)
FoundSomething($et, $tagTbl, $time[$i], $dur[$i]);
$et->HandleTag($tagTbl, $type, undef,
DataPt => \$buff,
- DataPos => $$start[$i],
- Base => $$start[$i],
+ DataPos => 0,
+ Base => $$start[$i], # (Base must be set for CR3 files)
TagInfo => $tagInfo,
);
}
@@ -1402,12 +1415,12 @@ sub ProcessFreeGPS($$$)
# decode freeGPS from Akaso dashcam
# 0000: 00 00 80 00 66 72 65 65 47 50 53 20 60 00 00 00 [....freeGPS `...]
- # 0000: 78 2e 78 78 00 00 00 00 00 00 00 00 00 00 00 00 [x.xx............]
- # 0000: 30 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 [00000...........]
- # 0000: 12 00 00 00 2f 00 00 00 19 00 00 00 41 00 00 00 [..../.......A...]
- # 0000: 13 b3 ca 44 4e 00 00 00 29 92 fb 45 45 00 00 00 [...DN...)..EE...]
- # 0000: d9 ee b4 41 ec d1 d3 42 e4 07 00 00 01 00 00 00 [...A...B........]
- # 0000: 0c 00 00 00 01 00 00 00 05 00 00 00 00 00 00 00 [................]
+ # 0010: 78 2e 78 78 00 00 00 00 00 00 00 00 00 00 00 00 [x.xx............]
+ # 0020: 30 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 [00000...........]
+ # 0030: 12 00 00 00 2f 00 00 00 19 00 00 00 41 00 00 00 [..../.......A...]
+ # 0040: 13 b3 ca 44 4e 00 00 00 29 92 fb 45 45 00 00 00 [...DN...)..EE...]
+ # 0050: d9 ee b4 41 ec d1 d3 42 e4 07 00 00 01 00 00 00 [...A...B........]
+ # 0060: 0c 00 00 00 01 00 00 00 05 00 00 00 00 00 00 00 [................]
($latRef, $lonRef) = ($1, $2);
($hr, $min, $sec, $yr, $mon, $day) = unpack('x48V3x28V3', $$dataPt);
SetByteOrder('II');
@@ -1418,6 +1431,56 @@ sub ProcessFreeGPS($$$)
$trk -= 360 if $trk >= 360;
SetByteOrder('MM');
+ } elsif ($$dataPt =~ /^.{16}YndAkasoCar/s) {
+
+ # Akaso V1 dascham
+ # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 78 00 00 00 [....freeGPS x...]
+ # 0010: 59 6e 64 41 6b 61 73 6f 43 61 72 00 00 00 00 00 [YndAkasoCar.....]
+ # 0020: 30 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 [00000...........]
+ # 0030: 0e 00 00 00 27 00 00 00 2c 00 00 00 e3 07 00 00 [....'...,.......]
+ # 0040: 05 00 00 00 1d 00 00 00 41 4e 45 00 00 00 00 00 [........ANE.....]
+ # 0050: f1 4e 3e 3d 90 df ca 40 e3 50 bf 0b 0b 31 a0 40 [.N>=...@.P...1.@]
+ # 0060: 4b dc c8 41 9a 79 a7 43 34 58 43 31 4f 37 31 35 [K..A.y.C4XC1O715]
+ # 0070: 35 31 32 36 36 35 37 35 59 4e 44 53 0d e7 cc f9 [51266575YNDS....]
+ # 0080: 00 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 [................]
+ ($hr,$min,$sec,$yr,$mon,$day,$stat,$latRef,$lonRef) =
+ unpack('x48V6a1a1a1x1', $$dataPt);
+ # ignore invalid fixes
+ return 0 unless $stat eq 'A' and ($latRef eq 'N' or $latRef eq 'S') and
+ ($lonRef eq 'E' or $lonRef eq 'W');
+
+ $et->WarnOnce("Can't yet decrypt Akaso V1 timed GPS", 1);
+ # (see https://exiftool.org/forum/index.php?topic=11320.0)
+ return 1;
+
+ SetByteOrder('II');
+ $lat = GetDouble($dataPt, 0x50); # latitude is here, but encrypted somehow
+ $lon = GetDouble($dataPt, 0x58); # longitude is here, but encrypted somehow
+ SetByteOrder('MM');
+ #my $serialNum = substr($$dataPt, 0x68, 20);
+
+ } elsif ($$dataPt =~ /^.{12}\xac\0\0\0.{44}(.{72})/s) {
+
+ # EACHPAI dash cam
+ # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 ac 00 00 00 [....freeGPS ....]
+ # 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
+ # 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
+ # 0030: 00 00 00 00 00 00 00 00 00 00 00 00 34 57 60 62 [............4W`b]
+ # 0040: 5d 53 3c 41 47 45 45 42 42 3e 40 40 40 3c 51 3c []S<AGEEBB>@@@<Q<]
+ # 0050: 44 42 44 40 3e 48 46 43 45 3c 5e 3c 40 48 43 41 [DBD@>HFCE<^<@HCA]
+ # 0060: 42 3e 46 42 47 48 3c 67 3c 40 3e 40 42 3c 43 3e [B>FBGH<g<@>@B<C>]
+ # 0070: 43 41 3c 40 42 40 46 42 40 3c 3c 3c 51 3a 47 46 [CA<@B@FB@<<<Q:GF]
+ # 0080: 00 2a 36 35 00 00 00 00 00 00 00 00 00 00 00 00 [.*65............]
+
+ $et->WarnOnce("Can't yet decrypt EACHPAI timed GPS", 1);
+ # (see https://exiftool.org/forum/index.php?topic=5095.msg61266#msg61266)
+ return 1;
+
+ my $time = pack 'C*', map { $_ ^= 0 } unpack 'C*', $1;
+ # bytes 7-12 are the timestamp in ASCII HHMMSS after xor-ing with 0x70
+ substr($time,7,6) = pack 'C*', map { $_ ^= 0x70 } unpack 'C*', substr($time,7,6);
+ # (other values are currently unknown)
+
} else {
# decode binary GPS format (Viofo A119S, ref 2)
@@ -1432,6 +1495,21 @@ sub ProcessFreeGPS($$$)
return 0 unless $stat eq 'A' and ($latRef eq 'N' or $latRef eq 'S') and
($lonRef eq 'E' or $lonRef eq 'W');
($lat,$lon,$spd,$trk) = unpack 'f*', pack 'L*', $lat, $lon, $spd, $trk;
+ # lat/lon also stored as doubles by Transcend Driver Pro 230 (ref PH)
+ SetByteOrder('II');
+ my ($lat2, $lon2, $alt2) = (
+ GetDouble($dataPt, 0x70),
+ GetDouble($dataPt, 0x80),
+ # GetDouble($dataPt, 0x98), # (don't know what this is)
+ GetDouble($dataPt,0xa0),
+ # GetDouble($dataPt,0xa8)) # (don't know what this is)
+ );
+ if (abs($lat2-$lat) < 0.001 and abs($lon2-$lon) < 0.001) {
+ $lat = $lat2;
+ $lon = $lon2;
+ $alt = $alt2;
+ }
+ SetByteOrder('MM');
$yr += 2000 if $yr < 2000;
$spd *= $knotsToKph; # convert speed to km/h
# ($trk is not confirmed; may be GPSImageDirection, ref PH)
@@ -1824,6 +1902,33 @@ sub ParseTag($$$)
}
$$et{HandlerType} = $tag; # fake handler type
ProcessSamples($et); # we have all we need to process sample data now
+ } elsif ($tag eq 'GPS ') {
+ my $pos = 0;
+ my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
+ SetByteOrder('II');
+ while ($pos + 36 < $dataLen) {
+ my $dat = substr($$dataPt, $pos, 36);
+ last if $dat eq "\x0" x 36;
+ my @a = unpack 'VVVVCVCV', $dat;
+ $$et{DOC_NUM} = ++$$et{DOC_COUNT};
+ # 0=1, 1=1, 2=secs, 3=?
+ SetGPSDateTime($et, $tagTbl, $a[2]);
+ my $lat = $a[5] / 1e3;
+ my $lon = $a[7] / 1e3;
+ my $deg = int($lat / 100);
+ $lat = $deg + ($lat - $deg * 100) / 60;
+ $deg = int($lon / 100);
+ $lon = $deg + ($lon - $deg * 100) / 60;
+ $lat = -$lat if $a[4] eq 'S';
+ $lon = -$lon if $a[6] eq 'W';
+ $et->HandleTag($tagTbl, GPSLatitude => $lat);
+ $et->HandleTag($tagTbl, GPSLongitude => $lon);
+ $et->HandleTag($tagTbl, GPSSpeed => $a[3] / 1e3);
+ $et->HandleTag($tagTbl, GPSSpeedRef => 'K');
+ $pos += 36;
+ }
+ SetByteOrder('MM');
+ delete $$et{DOC_NUM};
}
}
@@ -1842,6 +1947,26 @@ sub Process_tx3g($$$)
}
#------------------------------------------------------------------------------
+# Process GM 'marl' ctbx metadata (ref PH)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub Process_marl($$$)
+{
+ my ($et, $dirInfo, $tagTablePtr) = @_;
+ my $dataPt = $$dirInfo{DataPt};
+ return 0 if length $$dataPt < 2;
+
+ # 8-byte records:
+ # byte 0 seems to be tag ID (0=timestamp in sec * 1e7)
+ # bytes 1-3 seem to be 24-bit signed integer (unknown meaning)
+ # bytes 4-7 are an int32u value, usually a multiple of 10000
+
+ $et->WarnOnce("Can't yet decode timed GM data", 1);
+ # (see https://exiftool.org/forum/index.php?topic=11335.msg61393#msg61393)
+ return 1;
+}
+
+#------------------------------------------------------------------------------
# Process QuickTime 'mebx' timed metadata
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
# Returns: 1 on success
diff --git a/lib/Image/ExifTool/Ricoh.pm b/lib/Image/ExifTool/Ricoh.pm
index 6c22ab01..42b51362 100644
--- a/lib/Image/ExifTool/Ricoh.pm
+++ b/lib/Image/ExifTool/Ricoh.pm
@@ -19,7 +19,7 @@ use vars qw($VERSION);
use Image::ExifTool qw(:DataAccess :Utils);
use Image::ExifTool::Exif;
-$VERSION = '1.34';
+$VERSION = '1.35';
sub ProcessRicohText($$$);
sub ProcessRicohRMETA($$$);
@@ -875,6 +875,7 @@ my %ricohLensIDs = (
Name => 'SoundFile',
Notes => 'audio data recorded in JPEG images by the G700SE',
},
+ _barcode => { Name => 'Barcodes', List => 1 },
);
# information stored in Ricoh AVI images (ref PH)
@@ -1004,6 +1005,23 @@ sub ProcessRicohRMETA($$$)
# (but it looks like the int16u at $dirStart+6 is the next block number
# if the data is continued, or 0 for the last block)
$dirLen < 14 and $et->Warn('Short Ricoh RMETA block', 1), return 0;
+ if ($$dataPt =~ /^.{20}BARCODE/s) {
+ my $val = substr($$dataPt, 20);
+ $val =~ s/\0.*//s;
+ $val =~ s/^BARCODE\w+,\d{2},//;
+ my @codes;
+ for (;;) {
+ $val =~ s/(\d+),// and length $val >= $1 or last;
+ push @codes, substr($val, 0, $1);
+ last unless length $val > $1;
+ $val = substr($val, $1+1);
+ }
+ $et->HandleTag($tagTablePtr, '_barcode', \@codes) if @codes;
+ return 1;
+ } elsif ($$dataPt =~ /^.{18}ASCII/s) {
+ # (ignore barcode tag names for now)
+ return 1;
+ }
my $audioLen = Get16u($dataPt, $dirStart+12);
$audioLen + 14 > $dirLen and $et->Warn('Truncated Ricoh RMETA audio data', 1), return 0;
my $buff = substr($$dataPt, $dirStart + 14, $audioLen);
diff --git a/lib/Image/ExifTool/Sony.pm b/lib/Image/ExifTool/Sony.pm
index 4a634bd3..dcb831ad 100644
--- a/lib/Image/ExifTool/Sony.pm
+++ b/lib/Image/ExifTool/Sony.pm
@@ -34,7 +34,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
use Image::ExifTool::Exif;
use Image::ExifTool::Minolta;
-$VERSION = '3.26';
+$VERSION = '3.27';
sub ProcessSRF($$$);
sub ProcessSR2($$$);
@@ -143,6 +143,7 @@ sub PrintInvLensSpec($;$$);
32854 => 'Sony E 70-350mm F4.5-6.3 G OSS', #IB/JR
32858 => 'Sony FE 35mm F1.8', #JR/IB
32859 => 'Sony FE 20mm F1.8 G', #IB/JR
+ 32860 => 'Sony FE 12-24mm F2.8 GM', #JR/IB
# (comment this out so LensID will report the LensModel, which is more useful)
# 32952 => 'Metabones Canon EF Speed Booster Ultra', #JR (corresponds to 184, but 'Advanced' mode, LensMount reported as E-mount)
@@ -210,7 +211,7 @@ sub PrintInvLensSpec($;$$);
50515 => 'Sigma 35mm F1.2 DG DN | A', #IB/JR (019)
50516 => 'Sigma 14-24mm F2.8 DG DN | A', #IB/JR (019)
50517 => 'Sigma 24-70mm F2.8 DG DN | A', #JR (019)
- 50518 => 'Sigma 100-400mm F5-6.3 DG DN OS', #JR
+ 50518 => 'Sigma 100-400mm F5-6.3 DG DN OS | C', #JR (020)
50992 => 'Voigtlander SUPER WIDE-HELIAR 15mm F4.5 III', #JR
50993 => 'Voigtlander HELIAR-HYPER WIDE 10mm F5.6', #IB
@@ -9746,12 +9747,88 @@ my %isoSetting2010 = (
# 0x8100 - 16 bytes starting with 0x060e2b340401
0x8100 => { Name => 'Sony_rtmd_0x8100', Format => 'int8u', %hidUnk },
0x8101 => { Name => 'Sony_rtmd_0x8101', Format => 'int8u', %hidUnk }, # seen: 0,1
+ 0x8106 => { Name => 'Sony_rtmd_0x8106', Format => 'int32u', %hidUnk }, # seen: "25 1"
0x8109 => { Name => 'Sony_rtmd_0x8109', Format => 'int32u', %hidUnk }, # seen: "1 50"
0x810a => { Name => 'Sony_rtmd_0x810a', Format => 'int16u', %hidUnk }, # seen: 0
0x810b => { Name => 'Sony_rtmd_0x810b', Format => 'int16u', %hidUnk }, # seen: 100
0x810c => { Name => 'Sony_rtmd_0x810c', Format => 'int16u', %hidUnk }, # seen: 100
0x810d => { Name => 'Sony_rtmd_0x810d', Format => 'int8u', %hidUnk }, # seen: 1
+ 0x8115 => { Name => 'Sony_rtmd_0x8115', Format => 'int16u', %hidUnk }, # seen: 100
# 0x8300 - container for other tags in this format
+ 0x8500 => {
+ Name => 'GPSVersionID',
+ Groups => { 2 => 'Location' },
+ Format => 'int8u',
+ PrintConv => '$val =~ tr/ /./; $val',
+ },
+ 0x8501 => {
+ Name => 'GPSLatitudeRef',
+ Groups => { 2 => 'Location' },
+ Format => 'string',
+ PrintConv => {
+ N => 'North',
+ S => 'South',
+ },
+ },
+ 0x8502 => {
+ Name => 'GPSLatitude',
+ Groups => { 2 => 'Location' },
+ Format => 'rational64u',
+ ValueConv => 'require Image::ExifTool::GPS;Image::ExifTool::GPS::ToDegrees($val)',
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
+ },
+ 0x8503 => {
+ Name => 'GPSLongitudeRef',
+ Groups => { 2 => 'Location' },
+ Format => 'string',
+ PrintConv => {
+ E => 'East',
+ W => 'West',
+ },
+ },
+ 0x8504 => {
+ Name => 'GPSLongitude',
+ Groups => { 2 => 'Location' },
+ Format => 'rational64u',
+ ValueConv => 'require Image::ExifTool::GPS;Image::ExifTool::GPS::ToDegrees($val)',
+ PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
+ },
+ 0x8507 => {
+ Name => 'GPSTimeStamp',
+ Groups => { 2 => 'Time' },
+ Format => 'rational64u',
+ ValueConv => 'require Image::ExifTool::GPS;Image::ExifTool::GPS::ConvertTimeStamp($val)',
+ PrintConv => 'Image::ExifTool::GPS::PrintTimeStamp($val)',
+ },
+ 0x8509 => {
+ Name => 'GPSStatus',
+ Groups => { 2 => 'Location' },
+ Format => 'string',
+ PrintConv => {
+ A => 'Measurement Active',
+ V => 'Measurement Void',
+ },
+ },
+ 0x850a => {
+ Name => 'GPSMeasureMode',
+ Groups => { 2 => 'Location' },
+ Format => 'string',
+ PrintConv => {
+ 2 => '2-Dimensional Measurement',
+ 3 => '3-Dimensional Measurement',
+ },
+ },
+ 0x8512 => {
+ Name => 'GPSMapDatum',
+ Groups => { 2 => 'Location' },
+ Format => 'string',
+ },
+ 0x851d => {
+ Name => 'GPSDateStamp',
+ Groups => { 2 => 'Time' },
+ Format => 'string',
+ ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
+ },
0xe000 => { Name => 'Sony_rtmd_0xe000', Format => 'int8u', %hidUnk }, # (16 bytes)
0xe300 => { Name => 'Sony_rtmd_0xe300', Format => 'int8u', %hidUnk }, # seen: 0,1
0xe301 => { Name => 'Sony_rtmd_0xe301', Format => 'int32u', %hidUnk }, # seen: 100
@@ -9764,6 +9841,8 @@ my %isoSetting2010 = (
ValueConv => 'my @a=unpack("x1H4H2H2H2H2H2",$val); "$a[0]:$a[1]:$a[2] $a[3]:$a[4]:$a[5]"',
PrintConv => '$self->ConvertDateTime($val)',
},
+ # f010 - 2048 bytes
+ # f020 - 543 bytes
);
# Composite Sony tags
@@ -9798,6 +9877,17 @@ my %isoSetting2010 = (
},
PrintConv => '$val eq "inf" ? $val : sprintf("%.2f m",$val)',
},
+ GPSDateTime => {
+ Description => 'GPS Date/Time',
+ Groups => { 2 => 'Time' },
+ SubDoc => 1, # generate for all sub-documents
+ Require => {
+ 0 => 'Sony:GPSDateStamp',
+ 1 => 'Sony:GPSTimeStamp',
+ },
+ ValueConv => '"$val[0] $val[1]Z"',
+ PrintConv => '$self->ConvertDateTime($val)',
+ },
);
# add our composite tags
diff --git a/lib/Image/ExifTool/TagLookup.pm b/lib/Image/ExifTool/TagLookup.pm
index a96ea3ea..eff43338 100644
--- a/lib/Image/ExifTool/TagLookup.pm
+++ b/lib/Image/ExifTool/TagLookup.pm
@@ -928,8 +928,9 @@ my %tagLookup = (
'aquahsl' => { 100 => 0x20914 },
'armidentifier' => { 129 => 0x78 },
'armversion' => { 129 => 0x7a },
- 'arranger' => { 366 => "\xa9arg" },
+ 'arranger' => { 360 => "\xa9arg", 366 => "\xa9arg" },
'arrangerkeywords' => { 366 => "\xa9ark" },
+ 'artdirector' => { 360 => "\xa9ard" },
'artfilter' => { 283 => 0x529 },
'artfiltereffect' => { 283 => 0x52f },
'artist' => { 116 => 0x13b, 296 => 'Artist', 341 => 0x22e, 358 => "\xa9ART", 360 => 'artist', 366 => "\xa9ART", 484 => 'Artist', 488 => 'artist' },
@@ -1057,7 +1058,7 @@ my %tagLookup = (
'baselinesharpness' => { 116 => 0xc62c },
'baseurl' => { 486 => 'BaseURL' },
'bass' => { 360 => 'player.movie.audio.bass' },
- 'batterylevel' => { 393 => 0x51, 397 => 0xc, 398 => 0x4, 399 => 0x4, 436 => 0x7 },
+ 'batterylevel' => { 306 => 0x38, 393 => 0x51, 397 => 0xc, 398 => 0x4, 399 => 0x4, 436 => 0x7 },
'batterylevelgrip1' => { 436 => 0x6 },
'batterylevelgrip2' => { 436 => 0x8 },
'batteryorder' => { 266 => '12.5', 275 => '13.2', 276 => '2.1', 279 => '3.1' },
@@ -1657,6 +1658,7 @@ my %tagLookup = (
'condadoneurange' => { 134 => 0xf3d },
'condadotunoffsets' => { 134 => 0xf43 },
'condadotunthresh' => { 134 => 0xf40 },
+ 'conductor' => { 360 => "\xa9con" },
'confidence' => { 447 => 'Confidence' },
'confidencelevel' => { 458 => 'ConfidenceLevel' },
'confidencemime' => { 447 => 'ConfidenceMime' },
@@ -1674,7 +1676,7 @@ my %tagLookup = (
'containerformat' => { 474 => 'ContainerFormat' },
'containerformatidentifier' => { 474 => [\'ContainerFormat','ContainerFormatIdentifier'] },
'containerformatname' => { 474 => [\'ContainerFormat','ContainerFormatName'] },
- 'contentcreatedate' => { 358 => "\xa9day", 366 => "\xa9day" },
+ 'contentcreatedate' => { 358 => "\xa9day", 366 => ['@day',"\xa9day"] },
'contentdistributorid' => { 366 => 'cdis' },
'contentid' => { 366 => 'ccid' },
'contentidentifier' => { 1 => 0x11 },
@@ -2107,7 +2109,7 @@ my %tagLookup = (
'digitalzoom' => { 34 => 0xc, 109 => 0xa, 124 => 0x1044, 136 => 0x68, 147 => 0x22, 148 => 0x1e, 152 => 'DigitalZoom', 176 => 0xc, 219 => 0x86, 249 => 0xa, 288 => 0x204, 341 => 0x1e, 348 => 0xa, 382 => 0x204, 426 => 0x12, 427 => 0x12 },
'digitalzoomon' => { 382 => 0x21b },
'digitalzoomratio' => { 116 => 0xa404, 416 => 0x200, 418 => 0x21c, 468 => 'DigitalZoomRatio' },
- 'director' => { 360 => 'director', 366 => "\xa9dir", 488 => 'director' },
+ 'director' => { 360 => ['director',"\xa9dir"], 366 => "\xa9dir", 488 => 'director' },
'directorphotography' => { 488 => 'directorPhotography' },
'directory' => { 117 => 'Directory' },
'directoryindex' => { 7 => 0x137, 9 => 0x2dc, 11 => 0x17e, 13 => 0x238, 14 => 0x13f, 15 => 0x133, 16 => 0x1df, 17 => 0x1a7, 18 => 0x1f0, 19 => 0xcc, 20 => 0x1c7, 21 => 0x298, 22 => 0x1e7, 23 => 0x1e5, 24 => [0x27c,0x280], 25 => 0x2b6, 26 => 0x2bf, 28 => 0x1f7, 29 => 0x4ba },
@@ -2318,6 +2320,7 @@ my %tagLookup = (
'exclusivecoverage' => { 452 => 'ExclusiveCoverage' },
'exclusivityenddate' => { 481 => 'exclusivityEndDate' },
'excursiontolerance' => { 130 => 0x82 },
+ 'executiveproducer' => { 360 => "\xa9xpd" },
'exif' => { 117 => 'EXIF' },
'exifbyteorder' => { 117 => 'ExifByteOrder' },
'exifcamerainfo' => { 128 => 0xe8 },
@@ -2787,6 +2790,8 @@ my %tagLookup = (
'gammaunsharpmaskstrength' => { 102 => 0x5 },
'gammaunsharpmaskthreshold' => { 102 => 0x7 },
'gammawhitepoint' => { 102 => 0xd },
+ 'garminsettings' => { 366 => 'pmcc' },
+ 'garminsoftware' => { 366 => 'uuid' },
'gdalmetadata' => { 116 => 0xa480 },
'gdalnodata' => { 116 => 0xa481 },
'geimagesize' => { 124 => 0x1304 },
@@ -2830,7 +2835,7 @@ my %tagLookup = (
'gpsaltitude' => { 127 => 0x6, 156 => 'Altitude', 468 => 'GPSAltitude' },
'gpsaltituderef' => { 127 => 0x5, 468 => 'GPSAltitudeRef' },
'gpsareainformation' => { 127 => 0x1c, 468 => 'GPSAreaInformation' },
- 'gpscoordinates' => { 358 => "\xa9xyz", 360 => 'location.ISO6709', 366 => "\xa9xyz" },
+ 'gpscoordinates' => { 358 => "\xa9xyz", 360 => 'location.ISO6709', 366 => ['@xyz',"\xa9xyz"] },
'gpsdatestamp' => { 127 => 0x1d },
'gpsdatetime' => { 156 => 'DateTime', 468 => 'GPSTimeStamp' },
'gpsdestbearing' => { 127 => 0x18, 156 => 'Bearing', 468 => 'GPSDestBearing' },
@@ -3658,7 +3663,7 @@ my %tagLookup = (
'maindialexposurecomp' => { 277 => '0.6' },
'mainingredient' => { 480 => 'mainIngredient' },
'majorversion' => { 453 => 'MajorVersion' },
- 'make' => { 95 => 0x0, 112 => 0x1, 116 => 0x10f, 152 => 'Make', 296 => 'Make', 311 => 0x10f, 360 => 'make', 366 => "\xa9mak", 477 => 'make', 484 => 'Make' },
+ 'make' => { 95 => 0x0, 112 => 0x1, 116 => 0x10f, 152 => 'Make', 296 => 'Make', 311 => 0x10f, 360 => 'make', 366 => ['@mak',"\xa9mak"], 477 => 'make', 484 => 'Make' },
'makernote' => { 468 => 'MakerNote' },
'makernoteapple' => { 114 => 'MakN', 116 => 0x927c },
'makernotecanon' => { 114 => 'MakN', 116 => 0x927c },
@@ -3964,7 +3969,7 @@ my %tagLookup = (
'mobilenetworkcode' => { 461 => 'mnc' },
'moddate' => { 296 => 'modify-date', 475 => 'ModDate' },
'modedialposition' => { 399 => 0x14 },
- 'model' => { 95 => 0x6, 116 => 0x110, 152 => 'Model', 296 => 'Model', 311 => 0x110, 341 => 0x23f, 360 => 'model', 366 => ['CNMN','cmnm',"\xa9mdl","\xa9mod"], 383 => 0x84, 447 => 'Model', 477 => 'model', 484 => 'Model' },
+ 'model' => { 95 => 0x6, 116 => 0x110, 152 => 'Model', 296 => 'Model', 311 => 0x110, 341 => 0x23f, 360 => 'model', 366 => ['@mod','CNMN','cmnm',"\xa9mdl","\xa9mod"], 383 => 0x84, 447 => 'Model', 477 => 'model', 484 => 'Model' },
'modelage' => { 474 => 'ModelAge' },
'modelid' => { 282 => 0x0 },
'modelingflash' => { 266 => '21.4', 267 => '31.1', 269 => '31.1', 270 => '31.1', 275 => '26.4', 276 => '30.2', 277 => '7.4', 278 => '30.1', 279 => '31.1', 280 => '31.1', 281 => '31.3' },
@@ -4219,6 +4224,7 @@ my %tagLookup = (
'orientation2' => { 411 => [0x28,0x2e] },
'orientationlinkedaf' => { 2 => 0xe },
'orientationlinkedafpoint' => { 81 => 0x516 },
+ 'originalartist' => { 360 => "\xa9ope" },
'originalbestqualitysize' => { 116 => 0xc792 },
'originalcreatedatetime' => { 452 => 'OriginalCreateDateTime' },
'originaldecisiondata' => { 111 => 'Canon::OriginalDecisionData' },
@@ -4690,7 +4696,7 @@ my %tagLookup = (
'processborderrowstop' => { 134 => 0xc63 },
'processingsoftware' => { 116 => 0xb },
'processversion' => { 462 => 'ProcessVersion', 464 => 'ProcessVersion' },
- 'producer' => { 292 => 'Producer', 360 => 'producer', 366 => "\xa9prd", 475 => 'Producer' },
+ 'producer' => { 292 => 'Producer', 360 => ['producer',"\xa9prd"], 366 => "\xa9prd", 475 => 'Producer' },
'producerkeywords' => { 366 => "\xa9pdk" },
'productcode' => { 478 => 'productCode' },
'productid' => { 129 => 0x32, 358 => 'prID', 477 => 'productID' },
@@ -4764,7 +4770,7 @@ my %tagLookup = (
'rangefinder' => { 271 => '4.1', 272 => '5.1', 273 => '5.1' },
'rasterizedcaption' => { 128 => 0x7d },
'rating' => { 116 => 0x4746, 124 => 0x1431, 352 => 0xdf, 358 => 'rtng', 406 => 0x2002, 457 => 'rating', 466 => 'rating', 474 => 'Rating', 478 => 'rating', 486 => 'Rating' },
- 'ratingpercent' => { 116 => 0x4749, 174 => 'Rating', 358 => 'rate' },
+ 'ratingpercent' => { 116 => 0x4749, 174 => 'Rating', 358 => 'rate', 486 => 'RatingPercent' },
'ratingregion' => { 474 => [\'Rating','RatingRatingRegion'] },
'ratingregioncity' => { 474 => [\'Rating','RatingRatingRegionCity'] },
'ratingregioncountrycode' => { 474 => [\'Rating','RatingRatingRegionCountryCode'] },
@@ -5354,7 +5360,8 @@ my %tagLookup = (
'snapshotwidthpixels' => { 474 => [\'SnapshotLink','SnapshotLinkWidthPixels'] },
'softskineffect' => { 406 => 0x200f },
'software' => { 116 => 0x131, 153 => 'Software', 296 => 'Software', 350 => 0x203, 360 => 'software', 383 => 0x18, 447 => 'Software', 484 => 'Software' },
- 'softwareversion' => { 366 => "\xa9swr", 382 => 0x207 },
+ 'softwareversion' => { 366 => ['@swr',"\xa9swr"], 382 => 0x207 },
+ 'soloist' => { 360 => "\xa9sol" },
'songwriter' => { 366 => "\xa9swf" },
'songwriterkeywords' => { 366 => "\xa9swk" },
'sonycropsize' => { 116 => 0x74c8 },
@@ -5382,6 +5389,7 @@ my %tagLookup = (
'sortcomposer' => { 358 => 'soco' },
'sortname' => { 358 => 'sonm', 462 => 'SortName', 464 => 'SortName' },
'sortshow' => { 358 => 'sosn' },
+ 'soundengineer' => { 360 => "\xa9sne" },
'source' => { 128 => 0x73, 296 => 'Source', 465 => 'source', 466 => 'source', 476 => 'Source' },
'sourcecount' => { 451 => 'SourceCount' },
'sourcecredits' => { 366 => "\xa9src" },
@@ -5467,6 +5475,7 @@ my %tagLookup = (
'stopsabovebaseiso' => { 414 => 0x113e, 415 => 0x113e, 416 => 0x111a, 417 => 0x1196, 418 => 0x1172, 419 => 0x102a, 420 => 0x222, 421 => 0x222, 422 => 0x217, 435 => 0xa },
'storagemethod' => { 183 => 0x12 },
'storebyorientation' => { 267 => '46.3', 269 => '47.3', 270 => '47.3', 279 => '47.3', 280 => '47.3' },
+ 'storedescription' => { 360 => 'sdes' },
'storylineidentifier' => { 474 => 'StorylineIdentifier' },
'straightenangle' => { 259 => 0x2fc08431 },
'streamready' => { 474 => 'StreamReady' },
@@ -5512,7 +5521,7 @@ my %tagLookup = (
'subselectorassignment' => { 267 => '48.1' },
'subselectorcenter' => { 269 => '72.1', 270 => '72.1', 280 => '72.1' },
'subselectorplusdials' => { 267 => '49.2', 269 => '73.1', 270 => '73.1', 280 => '73.1' },
- 'subtitle' => { 366 => "\xa9snm", 478 => 'subtitle' },
+ 'subtitle' => { 360 => "\xa9st3", 366 => "\xa9snm", 478 => 'subtitle' },
'subtitlekeywords' => { 366 => "\xa9snk" },
'subversionfilename' => { 472 => [\'SubVersions','SubVersionsFileName'] },
'subversionreference' => { 472 => [\'SubVersions','SubVersionsVersRef'] },
@@ -6627,6 +6636,7 @@ my %tagExists = (
'bannerimagetype' => 1,
'bannerimageurl' => 1,
'barcode' => 1,
+ 'barcodes' => 1,
'barometerinfo' => 1,
'barometerinfoversion' => 1,
'baselinelength' => 1,
@@ -7188,7 +7198,6 @@ my %tagExists = (
'concreteflag' => 1,
'condition' => 1,
'conditionalfec' => 1,
- 'conductor' => 1,
'conductors' => 1,
'confirmedobjectsize' => 1,
'connectionspaceilluminant' => 1,
@@ -8114,6 +8123,7 @@ my %tagExists = (
'gps360fly' => 1,
'gpsaltituderaw' => 1,
'gpsdatalist' => 1,
+ 'gpsdatalist2' => 1,
'gpsdatetimeraw' => 1,
'gpsdestaltitude' => 1,
'gpsframingaltitude' => 1,
@@ -8795,6 +8805,7 @@ my %tagExists = (
'marker' => 1,
'markerid' => 1,
'markinfo' => 1,
+ 'marl' => 1,
'matrixworldtocamera' => 1,
'matrixworldtoscreen' => 1,
'mattcolor' => 1,
@@ -9342,7 +9353,6 @@ my %tagExists = (
'orientationinfo' => 1,
'originalalbum' => 1,
'originalalbumtitle' => 1,
- 'originalartist' => 1,
'originaldocumentsize' => 1,
'originalfilesize' => 1,
'originalfiletype' => 1,
@@ -10127,6 +10137,7 @@ my %tagExists = (
'senderaddress' => 1,
'sendername' => 1,
'sensitivity' => 1,
+ 'sensitivityvalue' => 1,
'sensorbottomborder' => 1,
'sensordata' => 1,
'sensordefects' => 1,
diff --git a/lib/Image/ExifTool/TagNames.pod b/lib/Image/ExifTool/TagNames.pod
index 1bb89393..bae11e43 100644
--- a/lib/Image/ExifTool/TagNames.pod
+++ b/lib/Image/ExifTool/TagNames.pod
@@ -12,7 +12,7 @@ meta information extracted from or written to a file.
=head1 TAG TABLES
The tables listed below give the names of all tags recognized by ExifTool.
-They contain a total of 23465 tags, with 15349 unique tag names.
+They contain a total of 23508 tags, with 15359 unique tag names.
B<Tag ID>, B<Index#> or B<Sequence> is given in the first column of each
table. A B<Tag ID> is the computer-readable equivalent of a tag name, and
@@ -4329,6 +4329,7 @@ These tags belong to the ExifTool XMP-xmp family 1 group.
PageImagePageNumber integer_+
PageImageWidth integer_+
Rating real
+ RatingPercent real/
Thumbnails Thumbnail Struct+
ThumbnailFormat string_+
ThumbnailHeight integer_+
@@ -8239,8 +8240,10 @@ well as newer tags and values added by later models.
AEBShotCount int32s[2]
0x0107 SpotMeterLinkToAFPoint int32s
0x0108 SafetyShift int32s
- 0x0109 UsableShootingModes int32s[2]
- 0x010a UsableMeteringModes int32s[2]
+ 0x0109 UsableShootingModes int32s
+ UsableShootingModes int32s[2]
+ 0x010a UsableMeteringModes int32s
+ UsableMeteringModes int32s[2]
0x010b ExposureModeInManual int32s
0x010c ShutterSpeedRange int32s[3]
ShutterSpeedRange int32s[4]
@@ -8298,9 +8301,11 @@ well as newer tags and values added by later models.
0x051d VFDisplayIllumination int32s
0x051e InitialAFPointAIServoAF int32s
0x060f MirrorLockup int32s
- 0x0610 ContinuousShootingSpeed int32s[3]
+ 0x0610 ContinuousShootingSpeed int32s[6]
+ ContinuousShootingSpeed int32s[3]
0x0611 ContinuousShotLimit int32s[2]
- 0x0612 RestrictDriveModes int32s[2]
+ 0x0612 RestrictDriveModes int32s
+ RestrictDriveModes int32s[2]
0x0701 Shutter-AELock int32s
AFAndMeteringButtons int32s
ShutterButtonAFOnButton int32s
@@ -8325,7 +8330,8 @@ well as newer tags and values added by later models.
0x0714 RFLensMFFocusRingSensitivity int32s
0x0715 CustomizeDials int32s
0x080b FocusingScreen int32s
- 0x080c TimerLength int32s[4]
+ 0x080c TimerLength int32s[3]
+ TimerLength int32s[4]
0x080d ShortReleaseTimeLag int32s
0x080e AddAspectRatioInfo int32s
0x080f AddOriginalDecisionData int32s
@@ -14965,6 +14971,7 @@ These tags are used in Panasonic/Leica cameras.
0x0034 OpticalZoomMode int16u
0x0035 ConversionLens int16u
0x0036 TravelDay int16u
+ 0x0038 BatteryLevel int16u
0x0039 Contrast int16u
0x003a WorldTimeLocation int16u
0x003b TextStamp int16u
@@ -16749,6 +16756,7 @@ defined below, ExifTool will extract any information found here.
'Location' Location no
'Sign type' SignType no
'_audio' SoundFile no
+ '_barcode' Barcodes no+
=head3 Ricoh AVI Tags
@@ -18597,6 +18605,16 @@ some models when the ExtractEmbedded option is used.
Tag ID Tag Name Writable
------ -------- --------
+ 0x8500 GPSVersionID no
+ 0x8501 GPSLatitudeRef no
+ 0x8502 GPSLatitude no
+ 0x8503 GPSLongitudeRef no
+ 0x8504 GPSLongitude no
+ 0x8507 GPSTimeStamp no
+ 0x8509 GPSStatus no
+ 0x850a GPSMeasureMode no
+ 0x8512 GPSMapDatum no
+ 0x851d GPSDateStamp no
0xe304 DateTime no
=head2 SonyIDC Tags
@@ -19168,7 +19186,11 @@ Lens distortion correction information.
0x1201 LensTypeMake no
0x1202 LensTypeModel no
0x1203 FocalLengthIn35mmFormat no
+ 0x1301 ApertureValue no
+ 0x1302 ShutterSpeedValue no
+ 0x1303 SensitivityValue no
0x1305 HighISOMode no
+ 0x1412 FacesDetected no
0x3200 WB_CFA0_LevelDaylight no
0x3201 WB_CFA1_LevelDaylight no
0x3202 WB_CFA2_LevelDaylight no
@@ -25074,6 +25096,7 @@ for the official specification.
Tag ID Tag Name Writable
------ -------- --------
+ 'GPS ' GPSDataList2? no
'IDIT' DateTimeOriginal string
'PICT' PreviewPICT no
'_htc' HTCInfo QuickTime HTCInfo
@@ -25138,7 +25161,7 @@ Tags found in Pittasoft Blackvue dashcam "free" data.
Timed metadata extracted from QuickTime media data and some AVI videos when
the ExtractEmbedded option is used. Although most of these tags are
-combined into the single table below, ExifTool currently reads 37 different
+combined into the single table below, ExifTool currently reads 46 different
formats of timed GPS metadata from video files.
Tag Name Writable
@@ -25194,6 +25217,7 @@ formats of timed GPS metadata from video files.
camm7 QuickTime camm7
fdsc GoPro fdsc
gpmd GoPro GPMF
+ marl QuickTime marl
mebx QuickTime Keys
mett Parrot mett
rtmd Sony rtmd
@@ -25301,6 +25325,14 @@ specification.
------ -------- --------
4 MagneticField no
+=head3 QuickTime marl Tags
+
+Tags extracted from the marl ctbx timed metadata of GM cars.
+
+ Tag ID Tag Name Writable
+ ------ -------- --------
+ [no tags known]
+
=head3 QuickTime Keys Tags
This directory contains a list of key names which are used to decode tags
@@ -25371,12 +25403,23 @@ changed via the config file.
'producer' Producer string
'publisher' Publisher string
'rating.user' UserRating string
+ 'sdes' StoreDescription string
'software' Software string
'still-image-time' StillImageTime no
'title' Title string
'version' Version string
'video-orientation' VideoOrientation no
'year' Year string
+ "\xa9ard" ArtDirector string
+ "\xa9arg" Arranger string
+ "\xa9con" Conductor string
+ "\xa9dir" Director string
+ "\xa9ope" OriginalArtist string
+ "\xa9prd" Producer string
+ "\xa9sne" SoundEngineer string
+ "\xa9sol" Soloist string
+ "\xa9st3" Subtitle string
+ "\xa9xpd" ExecutiveProducer string
=head3 QuickTime FaceInfo Tags
@@ -26155,7 +26198,12 @@ the config file.
Tag ID Tag Name Writable
------ -------- --------
+ '@day' ContentCreateDate string/
+ '@mak' Make string/
+ '@mod' Model string/
'@sec' SamsungSec Samsung sec
+ '@swr' SoftwareVersion string/
+ '@xyz' GPSCoordinates string/
'AllF' PlayAllFrames int8u
'CAME' SerialNumberHash string
'CNCV' CompressorVersion string
@@ -26247,6 +26295,7 @@ the config file.
'modl' Model no
'name' Name string
'perf' Performer string/
+ 'pmcc' GarminSettings string
'pose' pose Kodak pose
'ptch' Pitch rational64s/
'ptv ' PrintToVideo QuickTime Video
@@ -26267,6 +26316,8 @@ the config file.
UnknownThumbnail string
'titl' Title string/
'urat' UserRating no
+ 'uuid' GarminSoftware string
+ UUID-Unknown? no
'vndr' Vendor string
'vrot' AccelerometerData no
'yrrc' Year no
@@ -34478,6 +34529,8 @@ values, may created via the ExifTool configuration file.
GPSDateTime Parrot:GPSLatitude no
Main:CreateDate
SampleTime
+ GPSDateTime Sony:GPSDateStamp no
+ Sony:GPSTimeStamp
GPSDestLatitude GPS:GPSDestLatitude no
GPS:GPSDestLatitudeRef
GPSDestLatitudeRef XMP-exif:GPSDestLatitude no
diff --git a/lib/Image/ExifTool/Writer.pl b/lib/Image/ExifTool/Writer.pl
index 15c17e33..907076c4 100644
--- a/lib/Image/ExifTool/Writer.pl
+++ b/lib/Image/ExifTool/Writer.pl
@@ -366,14 +366,18 @@ sub SetNewValue($;$$%)
if ($wantGroup) {
foreach (split /:/, $wantGroup) {
next unless length($_) and /^(\d+)?(.*)/; # separate family number and group name
- my ($f, $g) = ($1, lc $2);
+ my ($f, $g) = ($1, $2);
+ my $lcg = lc $g;
# save group/family unless '*' or 'all'
- push @wantGroup, [ $f, $g ] unless $g eq '*' or $g eq 'all';
- if (defined $f) {
- $f > 2 and return 0; # only allow family 0, 1 or 2
- $family2 = 1 if $f == 2; # set flag indicating family 2 was used
+ push @wantGroup, [ $f, $lcg ] unless $lcg eq '*' or $lcg eq 'all';
+ if ($g =~ /^ID_(.*)/i) { # family 7 is this is a tag ID
+ return 0 if defined $f and $f ne 7;
+ $wantGroup[-1] = [ 7, "ID_$1" ]; # case is significant for tag ID's
+ } elsif (defined $f) {
+ $f > 2 and return 0; # only allow family 0, 1 or 2
+ $family2 = 1 if $f == 2; # set flag indicating family 2 was used
} else {
- $family2 = 1 if $family2groups{$g};
+ $family2 = 1 if $family2groups{$lcg};
}
}
undef $wantGroup unless @wantGroup;
@@ -622,6 +626,16 @@ TAG: foreach $tagInfo (@matchingTags) {
next;
}
next if $lcWant eq lc $grp[2];
+ } elsif ($fam == 7) {
+ my $idGrp;
+ if ($$self{OPTIONS}{HexIDGroup} and $$tagInfo{TagID} =~ /^\d+$/) {
+ $idGrp = 'ID_' . sprintf('0x%x', $$tagInfo{TagID});
+ } else {
+ $idGrp = 'ID_' . $$tagInfo{TagID};
+ }
+ next if $lcWant eq $idGrp; # also allow raw tag ID
+ $idGrp =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge;
+ next if $lcWant eq $idGrp; # plain ASCII tag ID group name
} elsif ($fam != 1 and not $$tagInfo{AllowGroup}) {
next if $lcWant eq lc $grp[$fam];
if ($wgAll and not $fam and $allFam0{$lcWant}) {
diff --git a/lib/Image/ExifTool/XMP.pm b/lib/Image/ExifTool/XMP.pm
index 05fb9902..127b1590 100644
--- a/lib/Image/ExifTool/XMP.pm
+++ b/lib/Image/ExifTool/XMP.pm
@@ -49,7 +49,7 @@ use Image::ExifTool::Exif;
use Image::ExifTool::GPS;
require Exporter;
-$VERSION = '3.33';
+$VERSION = '3.34';
@ISA = qw(Exporter);
@EXPORT_OK = qw(EscapeXML UnescapeXML);
@@ -889,6 +889,7 @@ my %sRetouchArea = (
ModifyDate => { Groups => { 2 => 'Time' }, %dateTimeInfo, Priority => 0 },
Nickname => { },
Rating => { Writable => 'real', Notes => 'a value from 0 to 5, or -1 for "rejected"' },
+ RatingPercent=>{ Writable => 'real', Avoid => 1, Notes => 'non-standard' },
Thumbnails => {
FlatName => 'Thumbnail',
Struct => \%sThumbnail,
@@ -3217,6 +3218,7 @@ NoLoop:
#} elsif (grep / /, @$props) {
# $$tagInfo{List} = 1;
}
+ #PHIL why flat tag added here???? (try a.xmp)
AddTagToTable($tagTablePtr, $tagID, $tagInfo);
$added = 1;
last;