exiftool_vendored 12.92.0 → 12.95.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/Changes +35 -3
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/exiftool +15 -44
- data/bin/lib/Image/ExifTool/Canon.pm +135 -3
- data/bin/lib/Image/ExifTool/Font.pm +15 -4
- data/bin/lib/Image/ExifTool/Geotag.pm +19 -5
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +2 -2
- data/bin/lib/Image/ExifTool/Nikon.pm +2 -1
- data/bin/lib/Image/ExifTool/NikonSettings.pm +56 -1
- data/bin/lib/Image/ExifTool/OpenEXR.pm +3 -1
- data/bin/lib/Image/ExifTool/PostScript.pm +3 -12
- data/bin/lib/Image/ExifTool/QuickTime.pm +23 -9
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +117 -37
- data/bin/lib/Image/ExifTool/Samsung.pm +5 -3
- data/bin/lib/Image/ExifTool/TagLookup.pm +6920 -6904
- data/bin/lib/Image/ExifTool/TagNames.pod +104 -5
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +47 -14
- data/bin/lib/Image/ExifTool/Writer.pl +8 -54
- data/bin/lib/Image/ExifTool.pm +66 -4
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +2 -2
@@ -16,7 +16,7 @@ use strict;
|
|
16
16
|
use vars qw($VERSION $AUTOLOAD);
|
17
17
|
use Image::ExifTool qw(:DataAccess :Utils);
|
18
18
|
|
19
|
-
$VERSION = '1.
|
19
|
+
$VERSION = '1.46';
|
20
20
|
|
21
21
|
sub WritePS($$);
|
22
22
|
sub ProcessPS($$;$);
|
@@ -156,15 +156,6 @@ sub AUTOLOAD
|
|
156
156
|
return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
|
157
157
|
}
|
158
158
|
|
159
|
-
#------------------------------------------------------------------------------
|
160
|
-
# Is this a PC system
|
161
|
-
# Returns: true for PC systems
|
162
|
-
my %isPC = (MSWin32 => 1, os2 => 1, dos => 1, NetWare => 1, symbian => 1, cygwin => 1);
|
163
|
-
sub IsPC()
|
164
|
-
{
|
165
|
-
return $isPC{$^O};
|
166
|
-
}
|
167
|
-
|
168
159
|
#------------------------------------------------------------------------------
|
169
160
|
# Get image width or height
|
170
161
|
# Inputs: 0) value list ref (ImageData, BoundingBox), 1) true to get height
|
@@ -284,7 +275,7 @@ sub GetNextLine($$)
|
|
284
275
|
$$raf{PSEnd} and CheckPSEnd($raf, \$data);
|
285
276
|
# split line if it contains other newline sequences
|
286
277
|
if ($data =~ /$altnl/) {
|
287
|
-
if (length($data) > 500000 and IsPC()) {
|
278
|
+
if (length($data) > 500000 and Image::ExifTool::IsPC()) {
|
288
279
|
# patch for Windows memory problem
|
289
280
|
unless ($changedNL) {
|
290
281
|
$changedNL = $/;
|
@@ -537,7 +528,7 @@ sub ProcessPS($$;$)
|
|
537
528
|
$raf->ReadLine($data) or last;
|
538
529
|
# check for alternate newlines as efficiently as possible
|
539
530
|
if ($data =~ /$altnl/) {
|
540
|
-
if (length($data) > 500000 and IsPC()) {
|
531
|
+
if (length($data) > 500000 and Image::ExifTool::IsPC()) {
|
541
532
|
# Windows can't split very long lines due to poor memory handling,
|
542
533
|
# so re-read the file with the other newline character instead
|
543
534
|
# (slower but uses less memory)
|
@@ -48,7 +48,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
48
48
|
use Image::ExifTool::Exif;
|
49
49
|
use Image::ExifTool::GPS;
|
50
50
|
|
51
|
-
$VERSION = '
|
51
|
+
$VERSION = '3.01';
|
52
52
|
|
53
53
|
sub ProcessMOV($$;$);
|
54
54
|
sub ProcessKeys($$$);
|
@@ -6552,7 +6552,7 @@ my %userDefined = (
|
|
6552
6552
|
PROCESS_PROC => \&ProcessKeys,
|
6553
6553
|
WRITE_PROC => \&WriteKeys,
|
6554
6554
|
CHECK_PROC => \&CheckQTValue,
|
6555
|
-
VARS => { LONG_TAGS =>
|
6555
|
+
VARS => { LONG_TAGS => 8 },
|
6556
6556
|
WRITABLE => 1,
|
6557
6557
|
# (not PREFERRED when writing)
|
6558
6558
|
GROUPS => { 1 => 'Keys' },
|
@@ -6606,6 +6606,8 @@ my %userDefined = (
|
|
6606
6606
|
PrintConv => '$val * 1e6 . " microseconds"',
|
6607
6607
|
PrintConvInv => '$val =~ s/ .*//; $val * 1e-6',
|
6608
6608
|
},
|
6609
|
+
# 'camera.focal_length.35mm_equivalent' - not top level (written to Keys in video track)
|
6610
|
+
# 'camera.lens_model' - not top level (written to Keys in video track)
|
6609
6611
|
'location.ISO6709' => {
|
6610
6612
|
Name => 'GPSCoordinates',
|
6611
6613
|
Groups => { 2 => 'Location' },
|
@@ -6668,7 +6670,12 @@ my %userDefined = (
|
|
6668
6670
|
#
|
6669
6671
|
'com.apple.photos.captureMode' => 'CaptureMode',
|
6670
6672
|
'com.android.version' => 'AndroidVersion',
|
6671
|
-
'com.android.capture.fps' => 'AndroidCaptureFPS',
|
6673
|
+
'com.android.capture.fps' => { Name => 'AndroidCaptureFPS', Writable => 'float' },
|
6674
|
+
'com.android.manufacturer' => 'AndroidMake',
|
6675
|
+
'com.android.model' => 'AndroidModel',
|
6676
|
+
'com.xiaomi.preview_video_cover' => { Name => 'XiaomiPreviewVideoCover', Writable => 'int32s' },
|
6677
|
+
'xiaomi.exifInfo.videoinfo' => 'XiaomiExifInfo',
|
6678
|
+
'com.xiaomi.hdr10' => { Name => 'XiaomiHDR10', Writable => 'int32s' },
|
6672
6679
|
#
|
6673
6680
|
# also seen
|
6674
6681
|
#
|
@@ -9484,7 +9491,7 @@ sub ProcessKeys($$$)
|
|
9484
9491
|
$$newInfo{KeysID} = $tag; # save original ID for use in family 7 group name
|
9485
9492
|
AddTagToTable($itemList, $id, $newInfo);
|
9486
9493
|
$msg or $msg = '';
|
9487
|
-
$out and print $out "$$et{INDENT}Added ItemList Tag $id = ($ns) $
|
9494
|
+
$out and print $out "$$et{INDENT}Added ItemList Tag $id = ($ns) $full$msg\n";
|
9488
9495
|
}
|
9489
9496
|
$pos += $len;
|
9490
9497
|
++$index;
|
@@ -10136,11 +10143,15 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
|
|
10136
10143
|
}
|
10137
10144
|
if ($warnStr) {
|
10138
10145
|
# assume this is an unknown trailer if it comes immediately after
|
10139
|
-
# mdat or moov and has a tag name we don't recognize
|
10140
|
-
|
10141
|
-
|
10146
|
+
# mdat or moov or free and has a tag name we don't recognize
|
10147
|
+
# (Insta360 can write trailer after a 'free' atom)
|
10148
|
+
if (($lastTag eq 'mdat' or $lastTag eq 'moov' or $lastTag eq 'free') and
|
10149
|
+
(not $$tagTablePtr{$tag} or ref $$tagTablePtr{$tag} eq 'HASH' and $$tagTablePtr{$tag}{Unknown}))
|
10142
10150
|
{
|
10143
|
-
if ($
|
10151
|
+
if ($raf->Seek(-40, 2) and $raf->Read($buff, 40) == 40 and
|
10152
|
+
substr($buff, 8) eq '8db42d694ccc418790edff439fe026bf' and
|
10153
|
+
$lastPos == $raf->Tell() - unpack('V',$buff))
|
10154
|
+
{
|
10144
10155
|
$et->Warn(sprintf('Insta360 trailer at offset 0x%x', $lastPos), 1);
|
10145
10156
|
} else {
|
10146
10157
|
$et->Warn('Unknown trailer with '.lcfirst($warnStr));
|
@@ -10171,7 +10182,10 @@ QTLang: foreach $tag (@{$$et{QTLang}}) {
|
|
10171
10182
|
for ($i=0, $key=$name; $$infoHash{$key}; ++$i, $key="$name ($i)") {
|
10172
10183
|
next QTLang if $et->GetGroup($key, 0) eq 'QuickTime';
|
10173
10184
|
}
|
10174
|
-
$et->FoundTag($tagInfo, $$et{VALUE}{$tag});
|
10185
|
+
$key = $et->FoundTag($tagInfo, $$et{VALUE}{$tag});
|
10186
|
+
# copy extra tag information (groups, etc) to the synthetic tag
|
10187
|
+
$$et{TAG_EXTRA}{$key} = $$et{TAG_EXTRA}{$tag};
|
10188
|
+
$et->VPrint(0, "(synthesized default-language tag for QuickTime:$$tagInfo{Name})");
|
10175
10189
|
}
|
10176
10190
|
delete $$et{QTLang};
|
10177
10191
|
}
|
@@ -109,7 +109,7 @@ my %insvLimit = (
|
|
109
109
|
The tags below are extracted from timed metadata in QuickTime and other
|
110
110
|
formats of video files when the ExtractEmbedded option is used. Although
|
111
111
|
most of these tags are combined into the single table below, ExifTool
|
112
|
-
currently reads
|
112
|
+
currently reads 77 different formats of timed GPS metadata from video files.
|
113
113
|
},
|
114
114
|
VARS => { NO_ID => 1 },
|
115
115
|
GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
|
@@ -757,6 +757,15 @@ my %insvLimit = (
|
|
757
757
|
10 => { Name => 'FusionYPR', Format => 'float[3]' },
|
758
758
|
);
|
759
759
|
|
760
|
+
#------------------------------------------------------------------------------
|
761
|
+
# Convert unsigned 32-bit integer to signed
|
762
|
+
# Inputs: <none> (uses value in $_)
|
763
|
+
# Returns: signed integer
|
764
|
+
sub SignedInt32()
|
765
|
+
{
|
766
|
+
return $_ < 0x80000000 ? $_ : $_ - 4294967296;
|
767
|
+
}
|
768
|
+
|
760
769
|
#------------------------------------------------------------------------------
|
761
770
|
# Save information from keys in OtherSampleDesc directory for processing timed metadata
|
762
771
|
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
|
@@ -1474,6 +1483,31 @@ sub ConvertLatLon($$)
|
|
1474
1483
|
$_[1] = $deg + ($_[1] - $deg * 100) / 60;
|
1475
1484
|
}
|
1476
1485
|
|
1486
|
+
#------------------------------------------------------------------------------
|
1487
|
+
# Decrypt Lucky data
|
1488
|
+
# Inputs: 0) string to decrypt, 1) encryption key
|
1489
|
+
# Returns: decrypted string
|
1490
|
+
my @luckyKeys = ('luckychip gps', 'customer ## gps');
|
1491
|
+
sub DecryptLucky($$) {
|
1492
|
+
my ($str, $key) = @_;
|
1493
|
+
my @str = unpack('C*', $str);
|
1494
|
+
my @key = unpack('C*', $key);
|
1495
|
+
my @enc = (0..255);
|
1496
|
+
my ($i, $j, $k) = (0, 0, 0);
|
1497
|
+
do {
|
1498
|
+
$j = ($j + $enc[$i] + $key[$i % length($key)]) & 0xff;
|
1499
|
+
@enc[$i,$j] = @enc[$j,$i];
|
1500
|
+
} while (++$i < 256);
|
1501
|
+
($i, $j, $k) = (0, 0, 0);
|
1502
|
+
do {
|
1503
|
+
$j = ($j + 1) & 0xff;
|
1504
|
+
$k = ($k + $enc[$j]) & 0xff;
|
1505
|
+
@enc[$j,$k] = @enc[$k,$j];
|
1506
|
+
$str[$i] ^= $enc[($enc[$j] + $enc[$k]) & 0xff];
|
1507
|
+
} while (++$i < @str);
|
1508
|
+
return pack('C*', @str);
|
1509
|
+
}
|
1510
|
+
|
1477
1511
|
#------------------------------------------------------------------------------
|
1478
1512
|
# Process "freeGPS " data blocks
|
1479
1513
|
# Inputs: 0) ExifTool ref, 1) dirInfo ref {DataPt,SampleTime,SampleDuration}, 2) tagTable ref
|
@@ -1589,40 +1623,87 @@ sub ProcessFreeGPS($$$)
|
|
1589
1623
|
}
|
1590
1624
|
if (defined $lat) {
|
1591
1625
|
# extract accelerometer readings if GPS was valid
|
1592
|
-
|
1593
|
-
|
1594
|
-
map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
|
1626
|
+
# and change to signed integer and divide by 256
|
1627
|
+
@acc = map { SignedInt32 / 256 } unpack('x68V3', $$dataPt);
|
1595
1628
|
}
|
1596
1629
|
|
1597
|
-
} elsif ($$dataPt =~ /^.{37}\0\0\0A([NS])([EW])/s) {
|
1630
|
+
} elsif ($$dataPt =~ /^.{37}\0\0\0A([NS])([EW])\0/s) {
|
1598
1631
|
|
1599
|
-
$debug and $et->FoundTag(GPSType => 3);
|
1600
|
-
# decode freeGPS from ViofoA119v3 dashcam (similar to Novatek GPS format)
|
1601
|
-
# 0000: 00 00 40 00 66 72 65 65 47 50 53 20 f0 03 00 00 [..@.freeGPS ....]
|
1602
|
-
# 0010: 05 00 00 00 2f 00 00 00 03 00 00 00 13 00 00 00 [..../...........]
|
1603
|
-
# 0020: 09 00 00 00 1b 00 00 00 41 4e 57 00 25 d1 99 45 [........ANW.%..E]
|
1604
|
-
# 0030: f1 47 40 46 66 66 d2 41 85 eb 83 41 00 00 00 00 [.G@Fff.A...A....]
|
1605
1632
|
($latRef, $lonRef) = ($1, $2);
|
1606
1633
|
($hr,$min,$sec,$yr,$mon,$day) = unpack('x16V6', $$dataPt);
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1613
|
-
$
|
1614
|
-
|
1615
|
-
|
1616
|
-
}
|
1617
|
-
$
|
1618
|
-
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1634
|
+
# test for base64-encoded and encrypted lucky gps strings
|
1635
|
+
my ($notEnc, $notStr, $lt, $ln);
|
1636
|
+
if (length($$dataPt) < 0x78) {
|
1637
|
+
$notEnc = $notStr = 1;
|
1638
|
+
} else {
|
1639
|
+
$lt = substr($$dataPt, 0x2c, 20), # latitude
|
1640
|
+
$ln = substr($$dataPt, 0x40, 20), # longitude
|
1641
|
+
/^[A-Za-z0-9+\/]{8,20}={0,2}\0*$/ or $notEnc = 1, last foreach ($lt, $ln);
|
1642
|
+
/^\d{1,5}\.\d+\0*$/ or $notStr = 1, last foreach ($lt, $ln);
|
1643
|
+
}
|
1644
|
+
if ($notEnc and $notStr) {
|
1645
|
+
|
1646
|
+
$debug and $et->FoundTag(GPSType => '3a');
|
1647
|
+
# decode freeGPS from ViofoA119v3 dashcam (similar to Novatek GPS format)
|
1648
|
+
# 0000: 00 00 40 00 66 72 65 65 47 50 53 20 f0 03 00 00 [..@.freeGPS ....]
|
1649
|
+
# 0010: 05 00 00 00 2f 00 00 00 03 00 00 00 13 00 00 00 [..../...........]
|
1650
|
+
# 0020: 09 00 00 00 1b 00 00 00 41 4e 57 00 25 d1 99 45 [........ANW.%..E]
|
1651
|
+
# 0030: f1 47 40 46 66 66 d2 41 85 eb 83 41 00 00 00 00 [.G@Fff.A...A....]
|
1652
|
+
if ($yr >= 2000) {
|
1653
|
+
# Kenwood dashcam sometimes stores absolute year and local time
|
1654
|
+
# (but sometimes year since 2000 and UTC time in same video!)
|
1655
|
+
require Time::Local;
|
1656
|
+
my $time = Image::ExifTool::TimeLocal($sec,$min,$hr,$day,$mon-1,$yr);
|
1657
|
+
($sec,$min,$hr,$day,$mon,$yr) = gmtime($time);
|
1658
|
+
$yr += 1900;
|
1659
|
+
++$mon;
|
1660
|
+
$et->WarnOnce('Converting GPSDateTime to UTC based on local time zone',1);
|
1661
|
+
}
|
1662
|
+
$lat = GetFloat($dataPt, 0x2c);
|
1663
|
+
$lon = GetFloat($dataPt, 0x30);
|
1664
|
+
$spd = GetFloat($dataPt, 0x34) * $knotsToKph;
|
1665
|
+
$trk = GetFloat($dataPt, 0x38);
|
1666
|
+
# (may be all zeros or int16u counting from 1 to 6 if not valid)
|
1667
|
+
my $tmp = substr($$dataPt, 60, 12);
|
1668
|
+
if ($tmp ne "\0\0\0\0\0\0\0\0\0\0\0\0" and $tmp ne "\x01\0\x02\0\x03\0\x04\0\x05\0\x06\0") {
|
1669
|
+
@acc = map { SignedInt32 / 256 } unpack('V3', $tmp);
|
1670
|
+
}
|
1671
|
+
|
1672
|
+
} else {
|
1673
|
+
|
1674
|
+
$debug and $et->FoundTag(GPSType => '3b');
|
1675
|
+
# decode freeGPS from E-ACE B44 dashcam
|
1676
|
+
# 0000: 00 00 40 00 66 72 65 65 47 50 53 20 f0 03 00 00 [..@.freeGPS ....]
|
1677
|
+
# 0010: 08 00 00 00 22 00 00 00 01 00 00 00 18 00 00 00 [...."...........]
|
1678
|
+
# 0020: 08 00 00 00 10 00 00 00 41 4e 45 00 67 4e 69 69 [........ANE.gNii]
|
1679
|
+
# 0030: 5a 38 4a 54 74 48 63 61 36 74 77 3d 00 00 00 00 [Z8JTtHca6tw=....]
|
1680
|
+
# 0040: 68 74 75 69 5a 4d 4a 53 73 58 55 58 37 4e 6f 3d [htuiZMJSsXUX7No=]
|
1681
|
+
# 0050: 00 00 00 00 64 3b ac 41 e1 3a 1d 43 2b 01 00 00 [....d;.A.:.C+...]
|
1682
|
+
# 0060: fd ff ff ff 43 00 00 00 32 4a 37 31 50 70 55 48 [....C...2J71PpUH]
|
1683
|
+
# 0070: 37 69 68 66 00 00 00 00 00 00 00 00 00 00 00 00 [7ihf............]
|
1684
|
+
# (16-byte string at 0x68 is base64 encoded and encrypted 'luckychip' string)
|
1685
|
+
$spd = GetFloat($dataPt, 0x54) * $knotsToKph;
|
1686
|
+
$trk = GetFloat($dataPt, 0x58);
|
1687
|
+
@acc = map SignedInt32, unpack('x92V3', $$dataPt);
|
1688
|
+
# (accelerometer scaling is roughly 1G=250-300, but it varies depending on the axis,
|
1689
|
+
# so leave the values as raw. The axes are positive acceleration up,left,forward)
|
1690
|
+
if ($notEnc) { # (not encrypted)
|
1691
|
+
($lat = $lt) =~ s/\0+$//;
|
1692
|
+
($lon = $ln) =~ s/\0+$//;
|
1693
|
+
} else {
|
1694
|
+
# decode base64 strings
|
1695
|
+
require Image::ExifTool::XMP;
|
1696
|
+
$_ = ${Image::ExifTool::XMP::DecodeBase64($_)} foreach ($lt, $ln);
|
1697
|
+
# try various keys to decrypt lat/lon
|
1698
|
+
my ($i, $ch, $key) = (0, 'a', $luckyKeys[0]);
|
1699
|
+
for (; $i<20; ++$i) {
|
1700
|
+
$i and ($key = $luckyKeys[1]) =~ s/#/$ch/g, ++$ch;
|
1701
|
+
($lat = DecryptLucky($lt, $key)) =~ /^\d{1,4}\.\d+$/ or undef($lat), next;
|
1702
|
+
($lon = DecryptLucky($ln, $key)) =~ /^\d{1,5}\.\d+$/ or undef($lon), next;
|
1703
|
+
last;
|
1704
|
+
}
|
1705
|
+
$lon or $et->WarnOnce('Unknown encryption for latitude/longitude');
|
1706
|
+
}
|
1626
1707
|
}
|
1627
1708
|
|
1628
1709
|
} elsif ($$dataPt =~ /^.{21}\0\0\0A([NS])([EW])/s) {
|
@@ -1683,7 +1764,7 @@ sub ProcessFreeGPS($$$)
|
|
1683
1764
|
$trk -= 360 if $trk >= 360;
|
1684
1765
|
undef @acc;
|
1685
1766
|
} else {
|
1686
|
-
|
1767
|
+
@acc = map { SignedInt32 / 1000 } @acc; # (NC)
|
1687
1768
|
}
|
1688
1769
|
|
1689
1770
|
} elsif ($$dataPt =~ /^.{60}4W`b]S</s and length($$dataPt) >= 140) {
|
@@ -1787,7 +1868,7 @@ sub ProcessFreeGPS($$$)
|
|
1787
1868
|
return 0;
|
1788
1869
|
}
|
1789
1870
|
# (not sure about acc scaling)
|
1790
|
-
|
1871
|
+
@acc = map { SignedInt32 / 1000 } @acc;
|
1791
1872
|
$lon = GetFloat($dataPt, 0x5c);
|
1792
1873
|
$lat = GetFloat($dataPt, 0x60);
|
1793
1874
|
$spd = GetFloat($dataPt, 0x64) * $knotsToKph;
|
@@ -1932,7 +2013,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
1932
2013
|
# 0x7c - int32s[3] accelerometer * 1000
|
1933
2014
|
($latRef, $lonRef) = ($1, $2);
|
1934
2015
|
($hr,$min,$sec,$yr,$mon,$day,@acc) = unpack('x48V3x52V6', $$dataPt);
|
1935
|
-
|
2016
|
+
@acc = map { SignedInt32 / 1000 } @acc;
|
1936
2017
|
$lat = GetDouble($dataPt, 0x40);
|
1937
2018
|
$lon = GetDouble($dataPt, 0x50);
|
1938
2019
|
$spd = GetDouble($dataPt, 0x60) * $knotsToKph;
|
@@ -1948,8 +2029,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
1948
2029
|
$lon = abs(GetFloat(\$dat, 8)); # (abs just to be safe)
|
1949
2030
|
$spd = GetFloat(\$dat, 12) * $knotsToKph;
|
1950
2031
|
$trk = GetFloat(\$dat, 16);
|
1951
|
-
@acc = unpack('x20V3', $dat);
|
1952
|
-
map { $_ = $_ - 4294967296 if $_ >= 0x80000000 } @acc;
|
2032
|
+
@acc = map SignedInt32, unpack('x20V3', $dat);
|
1953
2033
|
ConvertLatLon($lat, $lon);
|
1954
2034
|
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
1955
2035
|
$et->HandleTag($tagTbl, GPSLatitude => $lat * (substr($dat,1,1) eq 'S' ? -1 : 1));
|
@@ -1983,7 +2063,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
1983
2063
|
$lon = abs(GetDouble($dataPt, 48)); # (abs just to be safe)
|
1984
2064
|
$spd = GetDouble($dataPt, 64) * $knotsToKph;
|
1985
2065
|
$trk = GetDouble($dataPt, 72);
|
1986
|
-
|
2066
|
+
@acc = map { SignedInt32 / 1000 } @acc; # (NC)
|
1987
2067
|
# (not necessary to read RMC sentence because we already have it all)
|
1988
2068
|
|
1989
2069
|
} elsif ($$dataPt =~ /^.{72}A[NS][EW]\0/s) {
|
@@ -2117,7 +2197,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
2117
2197
|
$day < 1 or $day > 31 or
|
2118
2198
|
$hr > 59 or $min > 59 or $sec > 600;
|
2119
2199
|
# change lat/lon to signed integer and divide by 1e7
|
2120
|
-
|
2200
|
+
($lat, $lon) = map { SignedInt32 / 1e7 } $lat, $lon;
|
2121
2201
|
$trk -= 0x10000 if $trk >= 0x8000; # make it signed
|
2122
2202
|
$trk /= 100;
|
2123
2203
|
$trk += 360 if $trk < 0;
|
@@ -22,7 +22,7 @@ use vars qw($VERSION %samsungLensTypes);
|
|
22
22
|
use Image::ExifTool qw(:DataAccess :Utils);
|
23
23
|
use Image::ExifTool::Exif;
|
24
24
|
|
25
|
-
$VERSION = '1.
|
25
|
+
$VERSION = '1.58';
|
26
26
|
|
27
27
|
sub WriteSTMN($$$);
|
28
28
|
sub ProcessINFO($$$);
|
@@ -957,7 +957,7 @@ my %formatMinMax = (
|
|
957
957
|
Samsung models such as the Galaxy S4 and Tab S, and from the 'sefd' atom in
|
958
958
|
HEIC images from models such as the S10+.
|
959
959
|
},
|
960
|
-
'0x0001-name' => 'EmbeddedImageName', # ("DualShot_1","DualShot_2")
|
960
|
+
'0x0001-name' => 'EmbeddedImageName', # ("DualShot_1","DualShot_2","SingleShot")
|
961
961
|
'0x0001' => [
|
962
962
|
{
|
963
963
|
Name => 'EmbeddedImage',
|
@@ -970,6 +970,7 @@ my %formatMinMax = (
|
|
970
970
|
Groups => { 2 => 'Preview' },
|
971
971
|
Binary => 1,
|
972
972
|
},
|
973
|
+
# (have also seen the string "BOKEH" here (SM-A226B)
|
973
974
|
],
|
974
975
|
'0x0100-name' => 'EmbeddedAudioFileName', # ("SoundShot_000")
|
975
976
|
'0x0100' => { Name => 'EmbeddedAudioFile', Groups => { 2 => 'Audio' }, Binary => 1 },
|
@@ -1265,6 +1266,7 @@ my %formatMinMax = (
|
|
1265
1266
|
'0x0b40' => { # (SM-N975X front camera)
|
1266
1267
|
Name => 'SingleShotMeta',
|
1267
1268
|
SubDirectory => { TagTable => 'Image::ExifTool::Samsung::SingleShotMeta' },
|
1269
|
+
# (have also see the string "BOKEH_INFO" here (SM-A226B)
|
1268
1270
|
},
|
1269
1271
|
# 0x0b41-name - seen 'SingeShot_DepthMap_1' (Yes, "Singe") (SM-N975X front camera)
|
1270
1272
|
'0x0b41' => { Name => 'SingleShotDepthMap', Binary => 1 },
|
@@ -1493,7 +1495,7 @@ sub ProcessSamsungMeta($$$)
|
|
1493
1495
|
my $pos = $$dirInfo{DirStart};
|
1494
1496
|
my $end = $$dirInfo{DirLen} + $pos;
|
1495
1497
|
unless ($pos + 8 <= $end and substr($$dataPt, $pos, 4) eq 'DOFS') {
|
1496
|
-
$et->Warn("Unrecognized $dirName data");
|
1498
|
+
$et->Warn("Unrecognized $dirName data", 1);
|
1497
1499
|
return 0;
|
1498
1500
|
}
|
1499
1501
|
my $ver = Get32u($dataPt, $pos + 4);
|