exiftool_vendored 12.08.0 → 12.13.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.
Potentially problematic release.
This version of exiftool_vendored might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/bin/Changes +85 -2
- data/bin/MANIFEST +2 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +43 -43
- data/bin/exiftool +176 -96
- data/bin/lib/Image/ExifTool.pm +15 -9
- data/bin/lib/Image/ExifTool.pod +62 -52
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +14 -4
- data/bin/lib/Image/ExifTool/Canon.pm +181 -15
- data/bin/lib/Image/ExifTool/DarwinCore.pm +7 -5
- data/bin/lib/Image/ExifTool/GIF.pm +2 -2
- data/bin/lib/Image/ExifTool/Geotag.pm +29 -10
- data/bin/lib/Image/ExifTool/GoPro.pm +1 -9
- data/bin/lib/Image/ExifTool/Import.pm +14 -11
- data/bin/lib/Image/ExifTool/JSON.pm +27 -4
- data/bin/lib/Image/ExifTool/MPF.pm +2 -2
- data/bin/lib/Image/ExifTool/MacOS.pm +3 -1
- data/bin/lib/Image/ExifTool/Matroska.pm +3 -1
- data/bin/lib/Image/ExifTool/Minolta.pm +2 -1
- data/bin/lib/Image/ExifTool/Nikon.pm +7 -4
- data/bin/lib/Image/ExifTool/Olympus.pm +3 -1
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +1 -0
- data/bin/lib/Image/ExifTool/Pentax.pm +10 -3
- data/bin/lib/Image/ExifTool/QuickTime.pm +52 -22
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +50 -37
- data/bin/lib/Image/ExifTool/README +5 -2
- data/bin/lib/Image/ExifTool/Radiance.pm +7 -2
- data/bin/lib/Image/ExifTool/Sony.pm +16 -17
- data/bin/lib/Image/ExifTool/Stim.pm +2 -2
- data/bin/lib/Image/ExifTool/TagLookup.pm +5756 -5710
- data/bin/lib/Image/ExifTool/TagNames.pod +210 -19
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +7 -6
- data/bin/lib/Image/ExifTool/Writer.pl +20 -14
- data/bin/lib/Image/ExifTool/XMP.pm +62 -17
- data/bin/lib/Image/ExifTool/XMP2.pl +5 -0
- data/bin/perl-Image-ExifTool.spec +42 -42
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +3 -3
@@ -58,7 +58,7 @@ use Image::ExifTool::Exif;
|
|
58
58
|
use Image::ExifTool::GPS;
|
59
59
|
use Image::ExifTool::HP;
|
60
60
|
|
61
|
-
$VERSION = '3.
|
61
|
+
$VERSION = '3.35';
|
62
62
|
|
63
63
|
sub CryptShutterCount($$);
|
64
64
|
sub PrintFilter($$$);
|
@@ -2894,13 +2894,20 @@ my %binaryDataAttrs = (
|
|
2894
2894
|
Writable => 'string',
|
2895
2895
|
Notes => 'left blank by some cameras',
|
2896
2896
|
},
|
2897
|
-
0x022a => { #PH (
|
2897
|
+
0x022a => [{ #PH (RICOH models (GR III))
|
2898
|
+
Name => 'FilterInfo',
|
2899
|
+
Condition => '$$self{Make} =~ /^RICOH/',
|
2900
|
+
SubDirectory => {
|
2901
|
+
TagTable => 'Image::ExifTool::Pentax::FilterInfo',
|
2902
|
+
ByteOrder => 'LittleEndian',
|
2903
|
+
},
|
2904
|
+
},{ #PH (K-5)
|
2898
2905
|
Name => 'FilterInfo',
|
2899
2906
|
SubDirectory => {
|
2900
2907
|
TagTable => 'Image::ExifTool::Pentax::FilterInfo',
|
2901
2908
|
ByteOrder => 'BigEndian',
|
2902
2909
|
},
|
2903
|
-
},
|
2910
|
+
}],
|
2904
2911
|
0x022b => { #PH (K-5)
|
2905
2912
|
Name => 'LevelInfo',
|
2906
2913
|
SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LevelInfo' },
|
@@ -47,7 +47,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
47
47
|
use Image::ExifTool::Exif;
|
48
48
|
use Image::ExifTool::GPS;
|
49
49
|
|
50
|
-
$VERSION = '2.
|
50
|
+
$VERSION = '2.56';
|
51
51
|
|
52
52
|
sub ProcessMOV($$;$);
|
53
53
|
sub ProcessKeys($$$);
|
@@ -214,11 +214,16 @@ my %ftypLookup = (
|
|
214
214
|
'crx ' => 'Canon Raw (.CRX)', #PH (CR3 or CRM; use Canon CompressorVersion to decide)
|
215
215
|
);
|
216
216
|
|
217
|
-
# information for time
|
217
|
+
# information for int32u date/time tags (time zero is Jan 1, 1904)
|
218
218
|
my %timeInfo = (
|
219
219
|
Notes => 'converted from UTC to local time if the QuickTimeUTC option is set',
|
220
|
+
Shift => 'Time',
|
221
|
+
Writable => 1,
|
222
|
+
Permanent => 1,
|
223
|
+
DelValue => 0,
|
220
224
|
# It is not uncommon for brain-dead software to use the wrong time zero,
|
221
225
|
# so assume a time zero of Jan 1, 1970 if the date is before this
|
226
|
+
# Note: This value will be in UTC if generated by a system that is aware of the time zone
|
222
227
|
RawConv => q{
|
223
228
|
my $offset = (66 * 365 + 17) * 24 * 3600;
|
224
229
|
return $val - $offset if $val >= $offset or $$self{OPTIONS}{QuickTimeUTC};
|
@@ -227,12 +232,17 @@ my %timeInfo = (
|
|
227
232
|
}
|
228
233
|
return $val;
|
229
234
|
},
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
235
|
+
RawConvInv => q{
|
236
|
+
if ($$self{FileType} eq 'CR3' and not $self->Options('QuickTimeUTC')) {
|
237
|
+
# convert to UTC
|
238
|
+
my $offset = (66 * 365 + 17) * 24 * 3600;
|
239
|
+
$val = ConvertUnixTime($val - $offset);
|
240
|
+
$val = GetUnixTime($val, 1) + $offset;
|
241
|
+
}
|
242
|
+
return $val;
|
243
|
+
},
|
244
|
+
# (all CR3 files store UTC times - PH)
|
245
|
+
ValueConv => 'ConvertUnixTime($val, $self->Options("QuickTimeUTC") || $$self{FileType} eq "CR3")',
|
236
246
|
ValueConvInv => 'GetUnixTime($val, $self->Options("QuickTimeUTC")) + (66 * 365 + 17) * 24 * 3600',
|
237
247
|
PrintConv => '$self->ConvertDateTime($val)',
|
238
248
|
PrintConvInv => '$self->InverseDateTime($val)',
|
@@ -672,7 +682,7 @@ my %eeBox = (
|
|
672
682
|
ValueConv => '$val=~tr/-/:/; $val',
|
673
683
|
ValueConvInv => '$val=~s/(\d+):(\d+):/$1-$2-/; $val',
|
674
684
|
PrintConv => '$self->ConvertDateTime($val)',
|
675
|
-
PrintConvInv => '$self->InverseDateTime($val)',
|
685
|
+
PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
|
676
686
|
},
|
677
687
|
gps0 => { #PH (DuDuBell M1, VSYS M6L)
|
678
688
|
Name => 'GPSTrack',
|
@@ -1405,7 +1415,7 @@ my %eeBox = (
|
|
1405
1415
|
return $val;
|
1406
1416
|
},
|
1407
1417
|
PrintConv => '$self->ConvertDateTime($val)',
|
1408
|
-
PrintConvInv => '$self->InverseDateTime($val)',
|
1418
|
+
PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
|
1409
1419
|
},
|
1410
1420
|
"\xa9ART" => 'Artist', #PH (iTunes 8.0.2)
|
1411
1421
|
"\xa9alb" => 'Album', #PH (iTunes 8.0.2)
|
@@ -1679,7 +1689,7 @@ my %eeBox = (
|
|
1679
1689
|
return $val;
|
1680
1690
|
},
|
1681
1691
|
PrintConv => '$self->ConvertDateTime($val)',
|
1682
|
-
PrintConvInv => '$self->InverseDateTime($val)',
|
1692
|
+
PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
|
1683
1693
|
},
|
1684
1694
|
manu => { # (SX280)
|
1685
1695
|
Name => 'Make',
|
@@ -2114,7 +2124,7 @@ my %eeBox = (
|
|
2114
2124
|
return $val;
|
2115
2125
|
},
|
2116
2126
|
PrintConv => '$self->ConvertDateTime($val)',
|
2117
|
-
PrintConvInv => '$self->InverseDateTime($val)',
|
2127
|
+
PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
|
2118
2128
|
},
|
2119
2129
|
'@xyz' => { #PH (iPhone 3GS)
|
2120
2130
|
Name => 'GPSCoordinates',
|
@@ -2555,7 +2565,23 @@ my %eeBox = (
|
|
2555
2565
|
Start => 4,
|
2556
2566
|
},
|
2557
2567
|
},
|
2558
|
-
|
2568
|
+
idat => {
|
2569
|
+
Name => 'MetaImageSize', #PH (NC)
|
2570
|
+
Format => 'int16u',
|
2571
|
+
# (don't know what the first two numbers are for)
|
2572
|
+
PrintConv => '$val =~ s/^(\d+) (\d+) (\d+) (\d+)/${3}x$4/; $val',
|
2573
|
+
},
|
2574
|
+
uuid => [
|
2575
|
+
{ #PH (Canon R5/R6 HIF)
|
2576
|
+
Name => 'MetaVersion', # (NC)
|
2577
|
+
Condition => '$$valPt=~/^\x85\xc0\xb6\x87\x82\x0f\x11\xe0\x81\x11\xf4\xce\x46\x2b\x6a\x48/',
|
2578
|
+
RawConv => 'substr($val, 0x14)',
|
2579
|
+
},
|
2580
|
+
{
|
2581
|
+
Name => 'UUID-Unknown',
|
2582
|
+
%unknownInfo,
|
2583
|
+
},
|
2584
|
+
],
|
2559
2585
|
);
|
2560
2586
|
|
2561
2587
|
# additional metadata container (ref ISO14496-12:2015)
|
@@ -2867,12 +2893,16 @@ my %eeBox = (
|
|
2867
2893
|
WRITE_PROC => \&WriteQuickTime,
|
2868
2894
|
GROUPS => { 2 => 'Image' },
|
2869
2895
|
# (Note: ExifTool's ItemRefVersion may be used to test the iref version number)
|
2870
|
-
|
2871
|
-
|
2872
|
-
|
2896
|
+
NOTES => q{
|
2897
|
+
The Item reference entries listed in the table below contain information about
|
2898
|
+
the associations between items in the file. This information is used by
|
2899
|
+
ExifTool, but these entries are not extracted as tags.
|
2900
|
+
},
|
2901
|
+
dimg => { Name => 'DerivedImageRef', RawConv => 'undef' },
|
2902
|
+
thmb => { Name => 'ThumbnailRef', RawConv => 'undef' },
|
2903
|
+
auxl => { Name => 'AuxiliaryImageRef', RawConv => 'undef' },
|
2873
2904
|
cdsc => {
|
2874
2905
|
Name => 'ContentDescribes',
|
2875
|
-
Notes => 'parsed, but not extracted as a tag',
|
2876
2906
|
RawConv => \&ParseContentDescribes,
|
2877
2907
|
WriteHook => \&ParseContentDescribes,
|
2878
2908
|
},
|
@@ -2992,7 +3022,7 @@ my %eeBox = (
|
|
2992
3022
|
return $val;
|
2993
3023
|
},
|
2994
3024
|
PrintConv => '$self->ConvertDateTime($val)',
|
2995
|
-
PrintConvInv => '$self->InverseDateTime($val)',
|
3025
|
+
PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
|
2996
3026
|
},
|
2997
3027
|
"\xa9des" => 'Description', #4
|
2998
3028
|
"\xa9enc" => 'EncodedBy', #10
|
@@ -6170,7 +6200,7 @@ my %eeBox = (
|
|
6170
6200
|
return $val;
|
6171
6201
|
},
|
6172
6202
|
PrintConv => '$self->ConvertDateTime($val)',
|
6173
|
-
PrintConvInv => '$self->InverseDateTime($val)',
|
6203
|
+
PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
|
6174
6204
|
},
|
6175
6205
|
description => { },
|
6176
6206
|
director => { },
|
@@ -6230,7 +6260,7 @@ my %eeBox = (
|
|
6230
6260
|
return $val;
|
6231
6261
|
},
|
6232
6262
|
PrintConv => '$self->ConvertDateTime($val)',
|
6233
|
-
PrintConvInv => '$self->InverseDateTime($val)',
|
6263
|
+
PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
|
6234
6264
|
},
|
6235
6265
|
'direction.facing' => { Name => 'CameraDirection', Groups => { 2 => 'Location' } },
|
6236
6266
|
'direction.motion' => { Name => 'CameraMotion', Groups => { 2 => 'Location' } },
|
@@ -8618,10 +8648,10 @@ sub ProcessSampleDesc($$$)
|
|
8618
8648
|
my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $pos);
|
8619
8649
|
return 0 if $pos + 8 > $dirLen;
|
8620
8650
|
|
8621
|
-
my $num = Get32u($dataPt, 4); # get number of sample
|
8651
|
+
my $num = Get32u($dataPt, 4); # get number of sample entries in table
|
8622
8652
|
$pos += 8;
|
8623
8653
|
my $i;
|
8624
|
-
for ($i=0; $i<$num; ++$i) { # loop through sample
|
8654
|
+
for ($i=0; $i<$num; ++$i) { # loop through sample entries
|
8625
8655
|
last if $pos + 8 > $dirLen;
|
8626
8656
|
my $size = Get32u($dataPt, $pos);
|
8627
8657
|
last if $pos + $size > $dirLen;
|
@@ -165,10 +165,17 @@ my %insvLimit = (
|
|
165
165
|
ProcessProc => \&Process_mebx,
|
166
166
|
},
|
167
167
|
},
|
168
|
-
gpmd => {
|
169
|
-
Name => '
|
168
|
+
gpmd => [{
|
169
|
+
Name => 'gpmd_GoPro',
|
170
|
+
Condition => '$$valPt !~ /^\0\0\xf2\xe1\xf0\xeeTT/',
|
170
171
|
SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' },
|
171
|
-
},
|
172
|
+
},{
|
173
|
+
Name => 'gpmd_Rove', # Rove Stealth 4K encrypted text
|
174
|
+
SubDirectory => {
|
175
|
+
TagTable => 'Image::ExifTool::QuickTime::Stream',
|
176
|
+
ProcessProc => \&Process_text,
|
177
|
+
},
|
178
|
+
}],
|
172
179
|
fdsc => {
|
173
180
|
Name => 'fdsc',
|
174
181
|
Condition => '$$valPt =~ /^GPRO/',
|
@@ -837,15 +844,21 @@ sub HandleTextTags($$$)
|
|
837
844
|
|
838
845
|
#------------------------------------------------------------------------------
|
839
846
|
# Process subtitle 'text'
|
840
|
-
# Inputs: 0) ExifTool ref, 1)
|
847
|
+
# Inputs: 0) ExifTool ref, 1) data ref or dirInfo ref, 2) tag table ref
|
841
848
|
sub Process_text($$$)
|
842
849
|
{
|
843
|
-
my ($et, $
|
850
|
+
my ($et, $dataPt, $tagTbl) = @_;
|
844
851
|
my %tags;
|
845
852
|
|
846
853
|
return if $$et{NoMoreTextDecoding};
|
847
854
|
|
848
|
-
|
855
|
+
if (ref $dataPt eq 'HASH') {
|
856
|
+
my $dirName = $$dataPt{DirName};
|
857
|
+
$dataPt = $$dataPt{DataPt};
|
858
|
+
$et->VerboseDir($dirName, undef, length($$dataPt));
|
859
|
+
}
|
860
|
+
|
861
|
+
while ($$dataPt =~ /\$(\w+)([^\$]*)/g) {
|
849
862
|
my ($tag, $dat) = ($1, $2);
|
850
863
|
if ($tag =~ /^[A-Z]{2}RMC$/ and $dat =~ /^,(\d{2})(\d{2})(\d+(?:\.\d*)),A?,(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/) {
|
851
864
|
my $time = "$1:$2:$3";
|
@@ -936,31 +949,31 @@ sub Process_text($$$)
|
|
936
949
|
# 0110: 31 30 38 30 30 30 58 00 58 00 58 00 58 00 58 00 [108000X.X.X.X.X.]
|
937
950
|
# 0120: 58 00 58 00 58 00 58 00 00 00 00 00 00 00 00 00 [X.X.X.X.........]
|
938
951
|
# 0130: 00 00 00 00 00 00 00 [.......]
|
939
|
-
if ($$
|
940
|
-
my $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$
|
952
|
+
if ($$dataPt =~ /^\0\0(..\xaa\xaa|\xf2\xe1\xf0\xee)/s and length $$dataPt >= 282) {
|
953
|
+
my $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 8, 14)));
|
941
954
|
if ($val =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/) {
|
942
955
|
$tags{GPSDateTime} = "$1:$2:$3 $4:$5:$6";
|
943
|
-
$val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$
|
956
|
+
$val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 38, 9)));
|
944
957
|
if ($val =~ /^([NS])(\d{2})(\d+$)$/) {
|
945
958
|
$tags{GPSLatitude} = ($2 + $3 / 600000) * ($1 eq 'S' ? -1 : 1);
|
946
959
|
}
|
947
|
-
$val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$
|
960
|
+
$val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 47, 10)));
|
948
961
|
if ($val =~ /^([EW])(\d{3})(\d+$)$/) {
|
949
962
|
$tags{GPSLongitude} = ($2 + $3 / 600000) * ($1 eq 'W' ? -1 : 1);
|
950
963
|
}
|
951
|
-
$val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$
|
964
|
+
$val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 0x39, 5)));
|
952
965
|
$tags{GPSAltitude} = $val + 0 if $val =~ /^[-+]\d+$/;
|
953
|
-
$val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$
|
966
|
+
$val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 0x3e, 3)));
|
954
967
|
if ($val =~ /^\d+$/) {
|
955
968
|
$tags{GPSSpeed} = $val + 0;
|
956
969
|
$tags{GPSSpeedRef} = 'K';
|
957
970
|
}
|
958
|
-
if ($$
|
959
|
-
$val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$
|
971
|
+
if ($$dataPt =~ /^\0\0..\xaa\xaa/s) { # (BlueSkySea)
|
972
|
+
$val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 0xad, 12)));
|
960
973
|
# the first X,Y,Z accelerometer readings from the AccelerometerData
|
961
974
|
if ($val =~ /^([-+]\d{3})([-+]\d{3})([-+]\d{3})$/) {
|
962
975
|
$tags{Accelerometer} = "$1 $2 $3";
|
963
|
-
$val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$
|
976
|
+
$val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 0xba, 96)));
|
964
977
|
my $order = GetByteOrder();
|
965
978
|
SetByteOrder('II');
|
966
979
|
$val = ReadValue(\$val, 0, 'float');
|
@@ -969,7 +982,7 @@ sub Process_text($$$)
|
|
969
982
|
}
|
970
983
|
} else { # (Ambarella)
|
971
984
|
my @acc;
|
972
|
-
$val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$
|
985
|
+
$val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 0x41, 195)));
|
973
986
|
push @acc, $1, $2, $3 while $val =~ /\G([-+]\d{3})([-+]\d{3})([-+]\d{3})/g;
|
974
987
|
$tags{Accelerometer} = "@acc" if @acc;
|
975
988
|
}
|
@@ -980,36 +993,36 @@ sub Process_text($$$)
|
|
980
993
|
# check for DJI telemetry data, eg:
|
981
994
|
# "F/3.5, SS 1000, ISO 100, EV 0, GPS (8.6499, 53.1665, 18), D 24.26m,
|
982
995
|
# H 6.00m, H.S 2.10m/s, V.S 0.00m/s \n"
|
983
|
-
if ($$
|
996
|
+
if ($$dataPt =~ /GPS \(([-+]?\d*\.\d+),\s*([-+]?\d*\.\d+)/) {
|
984
997
|
$$et{CreateDateAtEnd} = 1; # set flag indicating the file creation date is at the end
|
985
998
|
$tags{GPSLatitude} = $2;
|
986
999
|
$tags{GPSLongitude} = $1;
|
987
|
-
$tags{GPSAltitude} = $1 if $$
|
988
|
-
if ($$
|
1000
|
+
$tags{GPSAltitude} = $1 if $$dataPt =~ /,\s*H\s+([-+]?\d+\.?\d*)m/;
|
1001
|
+
if ($$dataPt =~ /,\s*H.S\s+([-+]?\d+\.?\d*)/) {
|
989
1002
|
$tags{GPSSpeed} = $1 * $mpsToKph;
|
990
1003
|
$tags{GPSSpeedRef} = 'K';
|
991
1004
|
}
|
992
|
-
$tags{Distance} = $1 * $mpsToKph if $$
|
993
|
-
$tags{VerticalSpeed} = $1 if $$
|
994
|
-
$tags{FNumber} = $1 if $$
|
995
|
-
$tags{ExposureTime} = 1 / $1 if $$
|
996
|
-
$tags{ExposureCompensation} = ($1 / ($2 || 1)) if $$
|
997
|
-
$tags{ISO} = $1 if $$
|
1005
|
+
$tags{Distance} = $1 * $mpsToKph if $$dataPt =~ /,\s*D\s+(\d+\.?\d*)m/;
|
1006
|
+
$tags{VerticalSpeed} = $1 if $$dataPt =~ /,\s*V.S\s+([-+]?\d+\.?\d*)/;
|
1007
|
+
$tags{FNumber} = $1 if $$dataPt =~ /\bF\/(\d+\.?\d*)/;
|
1008
|
+
$tags{ExposureTime} = 1 / $1 if $$dataPt =~ /\bSS\s+(\d+\.?\d*)/;
|
1009
|
+
$tags{ExposureCompensation} = ($1 / ($2 || 1)) if $$dataPt =~ /\bEV\s+([-+]?\d+\.?\d*)(\/\d+)?/;
|
1010
|
+
$tags{ISO} = $1 if $$dataPt =~ /\bISO\s+(\d+\.?\d*)/;
|
998
1011
|
HandleTextTags($et, $tagTbl, \%tags);
|
999
1012
|
return;
|
1000
1013
|
}
|
1001
1014
|
|
1002
1015
|
# check for Mini 0806 dashcam GPS, eg:
|
1003
1016
|
# "A,270519,201555.000,3356.8925,N,08420.2071,W,000.0,331.0M,+01.84,-09.80,-00.61;\n"
|
1004
|
-
if ($$
|
1017
|
+
if ($$dataPt =~ /^A,(\d{2})(\d{2})(\d{2}),(\d{2})(\d{2})(\d{2}(\.\d+)?)/) {
|
1005
1018
|
$tags{GPSDateTime} = "20$3:$2:$1 $4:$5:$6Z";
|
1006
|
-
if ($$
|
1019
|
+
if ($$dataPt =~ /^A,.*?,.*?,(\d{2})(\d+\.\d+),([NS])/) {
|
1007
1020
|
$tags{GPSLatitude} = ($1 + $2/60) * ($3 eq 'S' ? -1 : 1);
|
1008
1021
|
}
|
1009
|
-
if ($$
|
1022
|
+
if ($$dataPt =~ /^A,.*?,.*?,.*?,.*?,(\d{3})(\d+\.\d+),([EW])/) {
|
1010
1023
|
$tags{GPSLongitude} = ($1 + $2/60) * ($3 eq 'W' ? -1 : 1);
|
1011
1024
|
}
|
1012
|
-
my @a = split ',', $$
|
1025
|
+
my @a = split ',', $$dataPt;
|
1013
1026
|
$tags{GPSAltitude} = $a[8] if $a[8] and $a[8] =~ s/M$//;
|
1014
1027
|
$tags{GPSSpeed} = $a[7] if $a[7] and $a[7] =~ /^\d+\.\d+$/; # (NC)
|
1015
1028
|
$tags{Accelerometer} = "$a[9] $a[10] $a[11]" if $a[11] and $a[11] =~ s/;\s*$//;
|
@@ -1022,10 +1035,10 @@ sub Process_text($$$)
|
|
1022
1035
|
# decoded:
|
1023
1036
|
# "X0000.2340Y-000.0720Z0000.9900G0001.0400$GPRMC,082138,A,5330.6683,N,00641.9749,W,012.5,87.86,050213,002.1,A"
|
1024
1037
|
# (note: "002.1" is magnetic variation and is not decoded; it should have ",E" or ",W" afterward for direction)
|
1025
|
-
if ($$
|
1038
|
+
if ($$dataPt =~ /\*[0-9A-F]{2}~$/) {
|
1026
1039
|
# (ref https://reverseengineering.stackexchange.com/questions/11582/how-to-reverse-engineer-dash-cam-metadata)
|
1027
1040
|
my @decode = unpack 'C*', '-I8XQWRVNZOYPUTA0B1C2SJ9K.L,M$D3E4F5G6H7';
|
1028
|
-
my @chars = unpack 'C*', substr($$
|
1041
|
+
my @chars = unpack 'C*', substr($$dataPt, 0, -4);
|
1029
1042
|
foreach (@chars) {
|
1030
1043
|
my $n = $_ - 43;
|
1031
1044
|
$_ = $decode[$n] if $n >= 0 and defined $decode[$n];
|
@@ -1034,14 +1047,14 @@ sub Process_text($$$)
|
|
1034
1047
|
if ($buff =~ /X(.*?)Y(.*?)Z(.*?)G(.*?)\$/) {
|
1035
1048
|
# yup. the decoding worked out
|
1036
1049
|
$tags{Accelerometer} = "$1 $2 $3 $4";
|
1037
|
-
$$
|
1050
|
+
$$dataPt = $buff; # (process GPRMC below)
|
1038
1051
|
}
|
1039
1052
|
}
|
1040
1053
|
|
1041
1054
|
# check for Thinkware format (and other NMEA RMC), eg:
|
1042
1055
|
# "gsensori,4,512,-67,-12,100;GNRMC,161313.00,A,4529.87489,N,07337.01215,W,6.225,35.34,310819,,,A*52..;
|
1043
1056
|
# CAR,0,0,0,0.0,0,0,0,0,0,0,0,0"
|
1044
|
-
if ($$
|
1057
|
+
if ($$dataPt =~ /[A-Z]{2}RMC,(\d{2})(\d{2})(\d+(\.\d*)?),A?,(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/ and
|
1045
1058
|
# do some basic sanity checks on the date
|
1046
1059
|
$13 <= 31 and $14 <= 12 and $15 <= 99)
|
1047
1060
|
{
|
@@ -1058,8 +1071,8 @@ sub Process_text($$$)
|
|
1058
1071
|
$tags{GPSTrackRef} = 'T';
|
1059
1072
|
}
|
1060
1073
|
}
|
1061
|
-
$tags{GSensor} = $1 if $$
|
1062
|
-
$tags{Car} = $1 if $$
|
1074
|
+
$tags{GSensor} = $1 if $$dataPt =~ /\bgsensori,(.*?)(;|$)/;
|
1075
|
+
$tags{Car} = $1 if $$dataPt =~ /\bCAR,(.*?)(;|$)/;
|
1063
1076
|
|
1064
1077
|
if (%tags) {
|
1065
1078
|
HandleTextTags($et, $tagTbl, \%tags);
|
@@ -1233,7 +1246,7 @@ sub ProcessSamples($)
|
|
1233
1246
|
$et->HandleTag($tagTbl, Text => $buff); # just store any other text
|
1234
1247
|
}
|
1235
1248
|
}
|
1236
|
-
Process_text($et, $tagTbl
|
1249
|
+
Process_text($et, \$buff, $tagTbl);
|
1237
1250
|
|
1238
1251
|
} elsif ($processByMetaFormat{$type}) {
|
1239
1252
|
|
@@ -1254,7 +1267,7 @@ sub ProcessSamples($)
|
|
1254
1267
|
# "X0000.0000Y0000.0000Z0000.0000G0000.0000$GPRMC,000125,V,,,,,000.0,,280908,002.1,N*71~, 794021 \x0a"
|
1255
1268
|
FoundSomething($et, $tagTbl, $time[$i], $dur[$i]);
|
1256
1269
|
$et->HandleTag($tagTbl, Accelerometer => "$1 $2 $3 $4") if $buff =~ /X(.*?)Y(.*?)Z(.*?)G(.*?)\$/;
|
1257
|
-
Process_text($et, $tagTbl
|
1270
|
+
Process_text($et, \$buff, $tagTbl);
|
1258
1271
|
}
|
1259
1272
|
} elsif ($verbose) {
|
1260
1273
|
$et->VPrint(0, "Unknown $type format ($metaFormat)");
|
@@ -387,8 +387,11 @@ numerical, and generated automatically otherwise.
|
|
387
387
|
'Flattened' - [reserved] used internally to mark Struct tags
|
388
388
|
which have been processed to generate flattened equivalents.
|
389
389
|
|
390
|
-
'
|
391
|
-
|
390
|
+
'NotFlat' - [XMP tags only] Flag indicates that this tag ID
|
391
|
+
does not represent a flattened tag. Used to avoid a conflict
|
392
|
+
if the tag ID would be the same as a generated ID for a
|
393
|
+
flattened tag. The result is that the flattened tag will not
|
394
|
+
be accessible.
|
392
395
|
|
393
396
|
'Hidden' - set to hide tag from the TagName documentation.
|
394
397
|
Also suppresses verbose output of a BinaryData tag.
|
@@ -15,7 +15,7 @@ use strict;
|
|
15
15
|
use vars qw($VERSION);
|
16
16
|
use Image::ExifTool qw(:DataAccess :Utils);
|
17
17
|
|
18
|
-
$VERSION = '1.
|
18
|
+
$VERSION = '1.02';
|
19
19
|
|
20
20
|
# Radiance tags
|
21
21
|
%Image::ExifTool::Radiance::Main = (
|
@@ -42,6 +42,7 @@ $VERSION = '1.01';
|
|
42
42
|
},
|
43
43
|
},
|
44
44
|
_command => 'Command',
|
45
|
+
_comment => 'Comment',
|
45
46
|
software => 'Software',
|
46
47
|
view => 'View',
|
47
48
|
'format' => 'Format', # <-- this is the one that caused the conflict when uppercase
|
@@ -74,8 +75,12 @@ sub ProcessHDR($$)
|
|
74
75
|
while ($raf->ReadLine($buff)) {
|
75
76
|
chomp $buff;
|
76
77
|
last unless length($buff) > 0 and length($buff) < 4096;
|
78
|
+
if ($buff =~ s/^#\s*//) {
|
79
|
+
$et->HandleTag($tagTablePtr, '_comment', $buff) if length $buff;
|
80
|
+
next;
|
81
|
+
}
|
77
82
|
unless ($buff =~ /^(.*)?\s*=\s*(.*)/) {
|
78
|
-
$et->HandleTag($tagTablePtr, '_command', $buff);
|
83
|
+
$et->HandleTag($tagTablePtr, '_command', $buff) if length $buff;
|
79
84
|
next;
|
80
85
|
}
|
81
86
|
# use lower-case tag names to avoid conflicts with reserved tag table entries
|