exiftool_vendored 12.16.0 → 12.25.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 +137 -1
- data/bin/MANIFEST +12 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +44 -43
- data/bin/config_files/acdsee.config +193 -6
- data/bin/config_files/cuepointlist.config +70 -0
- data/bin/config_files/example.config +1 -8
- data/bin/exiftool +139 -98
- data/bin/fmt_files/gpx.fmt +1 -1
- data/bin/fmt_files/gpx_wpt.fmt +1 -1
- data/bin/fmt_files/kml.fmt +1 -1
- data/bin/fmt_files/kml_track.fmt +1 -1
- data/bin/lib/Image/ExifTool.pm +158 -49
- data/bin/lib/Image/ExifTool.pod +94 -75
- data/bin/lib/Image/ExifTool/Apple.pm +3 -2
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +25 -14
- data/bin/lib/Image/ExifTool/Canon.pm +28 -3
- data/bin/lib/Image/ExifTool/CanonCustom.pm +19 -1
- data/bin/lib/Image/ExifTool/DJI.pm +6 -6
- data/bin/lib/Image/ExifTool/DjVu.pm +6 -5
- data/bin/lib/Image/ExifTool/Exif.pm +50 -22
- data/bin/lib/Image/ExifTool/FITS.pm +13 -2
- data/bin/lib/Image/ExifTool/FujiFilm.pm +19 -8
- data/bin/lib/Image/ExifTool/GPS.pm +24 -13
- data/bin/lib/Image/ExifTool/H264.pm +20 -5
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +2 -2
- data/bin/lib/Image/ExifTool/JPEG.pm +6 -2
- data/bin/lib/Image/ExifTool/JSON.pm +24 -3
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +361 -16
- data/bin/lib/Image/ExifTool/M2TS.pm +40 -4
- data/bin/lib/Image/ExifTool/MIE.pm +2 -2
- data/bin/lib/Image/ExifTool/MRC.pm +341 -0
- data/bin/lib/Image/ExifTool/MWG.pm +3 -3
- data/bin/lib/Image/ExifTool/MXF.pm +1 -1
- data/bin/lib/Image/ExifTool/MacOS.pm +1 -1
- data/bin/lib/Image/ExifTool/Microsoft.pm +298 -82
- data/bin/lib/Image/ExifTool/Nikon.pm +5 -5
- data/bin/lib/Image/ExifTool/NikonSettings.pm +25 -16
- data/bin/lib/Image/ExifTool/Olympus.pm +2 -2
- data/bin/lib/Image/ExifTool/PNG.pm +2 -2
- data/bin/lib/Image/ExifTool/Panasonic.pm +14 -1
- data/bin/lib/Image/ExifTool/PhaseOne.pm +4 -3
- data/bin/lib/Image/ExifTool/QuickTime.pm +148 -68
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +94 -34
- data/bin/lib/Image/ExifTool/README +5 -4
- data/bin/lib/Image/ExifTool/RIFF.pm +84 -12
- data/bin/lib/Image/ExifTool/Samsung.pm +2 -1
- data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -0
- data/bin/lib/Image/ExifTool/Sony.pm +157 -49
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +1 -0
- data/bin/lib/Image/ExifTool/TagLookup.pm +4079 -3987
- data/bin/lib/Image/ExifTool/TagNames.pod +642 -273
- data/bin/lib/Image/ExifTool/WriteExif.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePostScript.pl +1 -0
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +44 -17
- data/bin/lib/Image/ExifTool/WriteXMP.pl +15 -8
- data/bin/lib/Image/ExifTool/Writer.pl +50 -14
- data/bin/lib/Image/ExifTool/XMP.pm +50 -11
- data/bin/perl-Image-ExifTool.spec +42 -42
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +52 -12
@@ -62,7 +62,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
62
62
|
use Image::ExifTool::Exif;
|
63
63
|
use Image::ExifTool::GPS;
|
64
64
|
|
65
|
-
$VERSION = '3.
|
65
|
+
$VERSION = '3.95';
|
66
66
|
|
67
67
|
sub LensIDConv($$$);
|
68
68
|
sub ProcessNikonAVI($$$);
|
@@ -563,7 +563,7 @@ sub GetAFPointGrid($$;$);
|
|
563
563
|
'F0 3F 2D 8A 2C 40 DF 0E' => 'Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD (B008)',
|
564
564
|
'E0 40 2D 98 2C 41 DF 4E' => 'Tamron 18-400mm f/3.5-6.3 Di II VC HLD (B028)', # (removed AF designation, ref 37)
|
565
565
|
'07 40 2F 44 2C 34 03 02' => 'Tamron AF 19-35mm f/3.5-4.5 (A10)',
|
566
|
-
'07 40 30 45 2D 35 03 02' => 'Tamron AF 19-35mm f/3.5-4.5 (A10)',
|
566
|
+
'07 40 30 45 2D 35 03 02.1' => 'Tamron AF 19-35mm f/3.5-4.5 (A10)',
|
567
567
|
'00 49 30 48 22 2B 00 02' => 'Tamron SP AF 20-40mm f/2.7-3.5 (166D)',
|
568
568
|
'0E 4A 31 48 23 2D 0E 02' => 'Tamron SP AF 20-40mm f/2.7-3.5 (166D)',
|
569
569
|
'FE 48 37 5C 24 24 DF 0E' => 'Tamron SP 24-70mm f/2.8 Di VC USD (A007)', #24
|
@@ -640,6 +640,7 @@ sub GetAFPointGrid($$;$);
|
|
640
640
|
'24 44 60 98 34 3C 1A 02' => 'Tokina AT-X 840 AF-II (AF 80-400mm f/4.5-5.6)',
|
641
641
|
'00 44 60 98 34 3C 00 02' => 'Tokina AT-X 840 D (AF 80-400mm f/4.5-5.6)',
|
642
642
|
'14 48 68 8E 30 30 0B 00' => 'Tokina AT-X 340 AF (AF 100-300mm f/4)',
|
643
|
+
'8C 48 29 3C 24 24 86 06' => 'Tokina opera 16-28mm F2.8 FF', #30
|
643
644
|
#
|
644
645
|
'06 3F 68 68 2C 2C 06 00' => 'Cosina AF 100mm F3.5 Macro',
|
645
646
|
'07 36 3D 5F 2C 3C 03 00' => 'Cosina AF Zoom 28-80mm F3.5-5.6 MC Macro',
|
@@ -655,6 +656,7 @@ sub GetAFPointGrid($$;$);
|
|
655
656
|
'00 54 48 48 18 18 00 00' => 'Voigtlander Ultron 40mm F2 SLII Aspherical',
|
656
657
|
'00 54 55 55 0C 0C 00 00' => 'Voigtlander Nokton 58mm F1.4 SLII',
|
657
658
|
'00 40 64 64 2C 2C 00 00' => 'Voigtlander APO-Lanthar 90mm F3.5 SLII Close Focus',
|
659
|
+
'07 40 30 45 2D 35 03 02.2' => 'Voigtlander Ultragon 19-35mm F3.5-4.5 VMV', #NJ
|
658
660
|
#
|
659
661
|
'00 40 2D 2D 2C 2C 00 00' => 'Carl Zeiss Distagon T* 3.5/18 ZF.2',
|
660
662
|
'00 48 27 27 24 24 00 00' => 'Carl Zeiss Distagon T* 2.8/15 ZF.2', #MykytaKozlov
|
@@ -9945,12 +9947,10 @@ sub PrescanExif($$$)
|
|
9945
9947
|
$dataLen = length $data;
|
9946
9948
|
$dirStart = 0;
|
9947
9949
|
}
|
9948
|
-
# loop through
|
9949
|
-
my ($lastTag) = sort { $b <=> $a } keys %$tagHash; # (reverse sort)
|
9950
|
+
# loop through Nikon MakerNote IFD entries
|
9950
9951
|
for ($index=0; $index<$numEntries; ++$index) {
|
9951
9952
|
my $entry = $dirStart + 2 + 12 * $index;
|
9952
9953
|
my $tagID = Get16u($dataPt, $entry);
|
9953
|
-
last if $tagID > $lastTag; # (assuming tags are in order)
|
9954
9954
|
next unless exists $$tagHash{$tagID}; # only extract required tags
|
9955
9955
|
my $format = Get16u($dataPt, $entry+2);
|
9956
9956
|
next if $format < 1 or $format > 13;
|
@@ -17,7 +17,7 @@ use strict;
|
|
17
17
|
use vars qw($VERSION);
|
18
18
|
use Image::ExifTool qw(:DataAccess :Utils);
|
19
19
|
|
20
|
-
$VERSION = '1.
|
20
|
+
$VERSION = '1.03';
|
21
21
|
|
22
22
|
sub ProcessNikonSettings($$$);
|
23
23
|
|
@@ -911,14 +911,14 @@ my %infoD6 = (
|
|
911
911
|
},
|
912
912
|
0x05a => [{ # CSf6-b-1 and CSf6-b-2 (D6), CSf5-b-1 and CSf5-b-2 (Z7_2), (continued from above)
|
913
913
|
Name => 'CmdDialsChangeMainSub',
|
914
|
-
Condition => '$$self{CmdDialsChangeMainSubExposure} == 1',
|
914
|
+
Condition => '$$self{CmdDialsChangeMainSubExposure} and $$self{CmdDialsChangeMainSubExposure} == 1',
|
915
915
|
PrintConv => {
|
916
916
|
1 => 'Autofocus On, Exposure On',
|
917
917
|
2 => 'Autofocus Off, Exposure On',
|
918
918
|
},
|
919
919
|
},{
|
920
920
|
Name => 'CmdDialsChangeMainSub',
|
921
|
-
Condition => '$$self{CmdDialsChangeMainSubExposure} == 2',
|
921
|
+
Condition => '$$self{CmdDialsChangeMainSubExposure} and $$self{CmdDialsChangeMainSubExposure} == 2',
|
922
922
|
PrintConv => {
|
923
923
|
1 => 'Autofocus On, Exposure On (Mode A)',
|
924
924
|
2 => 'Autofocus Off, Exposure On (Mode A)',
|
@@ -1014,7 +1014,7 @@ my %infoD6 = (
|
|
1014
1014
|
}],
|
1015
1015
|
0x08b => [{ # CSf6-a-1 and CSf6-a-2 (D6), CSf5-a-1 and CSf5-a-2 (Z7_2), (continued from above)
|
1016
1016
|
Name => 'CmdDialsReverseRotation',
|
1017
|
-
Condition => '$$self{CmdDialsReverseRotExposureComp} == 1',
|
1017
|
+
Condition => '$$self{CmdDialsReverseRotExposureComp} and $$self{CmdDialsReverseRotExposureComp} == 1',
|
1018
1018
|
PrintConv => {
|
1019
1019
|
1 => 'No',
|
1020
1020
|
2 => 'Shutter Speed & Aperture',
|
@@ -1283,7 +1283,7 @@ my %infoD6 = (
|
|
1283
1283
|
PrintConv => {
|
1284
1284
|
1 => 'Enable',
|
1285
1285
|
2 => 'Enable (Standby Timer Active)',
|
1286
|
-
3 => '
|
1286
|
+
3 => 'Disable',
|
1287
1287
|
},
|
1288
1288
|
},
|
1289
1289
|
0x0ab => { # CSf11 (D6)
|
@@ -1313,7 +1313,7 @@ my %infoD6 = (
|
|
1313
1313
|
1 => 'Power Aperture (Open)',
|
1314
1314
|
2 => 'Exposure Compensation',
|
1315
1315
|
3 => 'Subject Tracking',
|
1316
|
-
4 => 'LiveView Info Display On/Off
|
1316
|
+
4 => 'LiveView Info Display On/Off',
|
1317
1317
|
5 => 'Grid Display',
|
1318
1318
|
6 => 'Zoom (Low)',
|
1319
1319
|
7 => 'Zoom (1:1)',
|
@@ -1357,7 +1357,7 @@ my %infoD6 = (
|
|
1357
1357
|
1 => 'Power Aperture (Close)',
|
1358
1358
|
2 => 'Exposure Compensation',
|
1359
1359
|
3 => 'Subject Tracking',
|
1360
|
-
4 => 'LiveView Info Display On/Off
|
1360
|
+
4 => 'LiveView Info Display On/Off',
|
1361
1361
|
5 => 'Grid Display',
|
1362
1362
|
6 => 'Zoom (Low)',
|
1363
1363
|
7 => 'Zoom (1:1)',
|
@@ -1545,10 +1545,10 @@ my %infoD6 = (
|
|
1545
1545
|
12 => 'None',
|
1546
1546
|
},
|
1547
1547
|
},
|
1548
|
-
0x0fb => { Name => 'SecondarySlotFunction',
|
1549
|
-
0x0fb => { Name => 'SecondarySlotFunction',
|
1550
|
-
0x0fc => { Name => 'SilentPhotography',
|
1551
|
-
0x0fd => { Name => '
|
1548
|
+
0x0fb => { Name => 'SecondarySlotFunction', PrintConv => \%tagSecondarySlotFunction }, # tag name selected to maintain compatibility with older cameras # (Z7_2)
|
1549
|
+
0x0fb => { Name => 'SecondarySlotFunction', PrintConv => \%tagSecondarySlotFunction }, # (D6)
|
1550
|
+
0x0fc => { Name => 'SilentPhotography', PrintConv => \%onOff }, # (D6,Z7_2) # tag is associated with Silent LiveView Photography (as distinguisehed from Silent Interval or Silent Focus Shift)
|
1551
|
+
0x0fd => { Name => 'ExtendedShutterSpeeds', PrintConv => \%onOff }, # CSd7 (D6), CSd6 (Z7_2)
|
1552
1552
|
0x109 => { # (D6,Z7_2)
|
1553
1553
|
Name => 'BracketSet',
|
1554
1554
|
RawConv => '$$self{BracketSet} = $val',
|
@@ -1578,7 +1578,7 @@ my %infoD6 = (
|
|
1578
1578
|
},
|
1579
1579
|
},{
|
1580
1580
|
Name => 'BracketProgram',
|
1581
|
-
Condition => '$$self{BracketSet} == 4',
|
1581
|
+
Condition => '$$self{BracketSet} and $$self{BracketSet} == 4',
|
1582
1582
|
Notes => 'White Balance Bracketing',
|
1583
1583
|
RawConv => '$$self{BracketProgram} = $val',
|
1584
1584
|
PrintConv => {
|
@@ -1595,7 +1595,7 @@ my %infoD6 = (
|
|
1595
1595
|
},
|
1596
1596
|
},{
|
1597
1597
|
Name => 'BracketProgram',
|
1598
|
-
Condition => '$$self{BracketSet} == 5',
|
1598
|
+
Condition => '$$self{BracketSet} and $$self{BracketSet} == 5',
|
1599
1599
|
Notes => 'Active-D Bracketing',
|
1600
1600
|
RawConv => '$$self{BracketProgram} = $val',
|
1601
1601
|
Mask => 0x0f,
|
@@ -1802,9 +1802,9 @@ my %infoD6 = (
|
|
1802
1802
|
},
|
1803
1803
|
},
|
1804
1804
|
0x139 => { Name => 'PlaybackFlickUp', RawConv => '$$self{PlaybackFlickUp} = $val', PrintConv => \%flickUpDownD6 }, # CSf12-1-a # (D6)
|
1805
|
-
0x13a => { Name => 'PlaybackFlickUpRating', Condition => '$$self{PlaybackFlickUp} == 1', Notes => 'Meaningful only when PlaybackFlickUp is Rating', PrintConv => \%flickUpDownRatingD6 }, # CSf12-1-b # (D6)
|
1805
|
+
0x13a => { Name => 'PlaybackFlickUpRating', Condition => '$$self{PlaybackFlickUp} and $$self{PlaybackFlickUp} == 1', Notes => 'Meaningful only when PlaybackFlickUp is Rating', PrintConv => \%flickUpDownRatingD6 }, # CSf12-1-b # (D6)
|
1806
1806
|
0x13b => { Name => 'PlaybackFlickDown', RawConv => '$$self{PlaybackFlickDown} = $val', PrintConv => \%flickUpDownD6 }, # CSf12-2-a # (D6)
|
1807
|
-
0x13c => { Name => 'PlaybackFlickDownRating', Condition => '$$self{PlaybackFlickDown} == 1', Notes => 'Meaningful only when PlaybackFlickDown is Rating', PrintConv => \%flickUpDownRatingD6 }, # CSf12-2-b # (D6)
|
1807
|
+
0x13c => { Name => 'PlaybackFlickDownRating', Condition => '$$self{PlaybackFlickDown} and $$self{PlaybackFlickDown} == 1', Notes => 'Meaningful only when PlaybackFlickDown is Rating', PrintConv => \%flickUpDownRatingD6 }, # CSf12-2-b # (D6)
|
1808
1808
|
0x13d => { # CSg2-d (D6)
|
1809
1809
|
Name => 'MovieFunc3Button',
|
1810
1810
|
PrintConv => {
|
@@ -1875,7 +1875,7 @@ my %infoD6 = (
|
|
1875
1875
|
0x164 => { # CSg7-a (Z7_2)
|
1876
1876
|
Name => 'VerticalMovieFuncButton',
|
1877
1877
|
PrintConv => {
|
1878
|
-
1 => 'LiveView Info Display On/Off
|
1878
|
+
1 => 'LiveView Info Display On/Off',
|
1879
1879
|
2 => 'Record Movies',
|
1880
1880
|
3 => 'Exposure Compensation',
|
1881
1881
|
4 => 'ISO',
|
@@ -1919,6 +1919,15 @@ my %infoD6 = (
|
|
1919
1919
|
10 => 'Auto (Animals)',
|
1920
1920
|
},
|
1921
1921
|
},
|
1922
|
+
0x170 => { Name => 'PreferSubSelectorCenter', PrintConv => \%offOn }, # CSf13 (D6 firmware v1.2.0)
|
1923
|
+
0x174 => { # CSa17-d (D6 firmware v1.2.0)
|
1924
|
+
Name => 'FocusPointSelectionSpeed',
|
1925
|
+
PrintConv => {
|
1926
|
+
1 => 'Normal',
|
1927
|
+
2 => 'High',
|
1928
|
+
3 => 'Very High',
|
1929
|
+
},
|
1930
|
+
},
|
1922
1931
|
);
|
1923
1932
|
|
1924
1933
|
#------------------------------------------------------------------------------
|
@@ -40,7 +40,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
40
40
|
use Image::ExifTool::Exif;
|
41
41
|
use Image::ExifTool::APP12;
|
42
42
|
|
43
|
-
$VERSION = '2.
|
43
|
+
$VERSION = '2.71';
|
44
44
|
|
45
45
|
sub PrintLensInfo($$$);
|
46
46
|
|
@@ -3952,7 +3952,7 @@ my %indexInfo = (
|
|
3952
3952
|
1 => 'LensTypeModel',
|
3953
3953
|
},
|
3954
3954
|
Notes => 'based on tags found in some Panasonic RW2 images',
|
3955
|
-
SeparateTable => 'LensType',
|
3955
|
+
SeparateTable => 'Olympus LensType',
|
3956
3956
|
ValueConv => '"$val[0] $val[1]"',
|
3957
3957
|
PrintConv => \%olympusLensTypes,
|
3958
3958
|
},
|
@@ -36,7 +36,7 @@ use strict;
|
|
36
36
|
use vars qw($VERSION $AUTOLOAD %stdCase);
|
37
37
|
use Image::ExifTool qw(:DataAccess :Utils);
|
38
38
|
|
39
|
-
$VERSION = '1.
|
39
|
+
$VERSION = '1.57';
|
40
40
|
|
41
41
|
sub ProcessPNG_tEXt($$$);
|
42
42
|
sub ProcessPNG_iTXt($$$);
|
@@ -975,7 +975,7 @@ sub FoundPNG($$$$;$$$$)
|
|
975
975
|
$$tagInfo{LangCode} = $lang if $lang;
|
976
976
|
# make unknown profiles binary data type
|
977
977
|
$$tagInfo{Binary} = 1 if $tag =~ /^Raw profile type /;
|
978
|
-
$verbose and $et->VPrint(0, "
|
978
|
+
$verbose and $et->VPrint(0, " [adding $tag]\n");
|
979
979
|
AddTagToTable($tagTablePtr, $tag, $tagInfo);
|
980
980
|
}
|
981
981
|
#
|
@@ -2118,6 +2118,7 @@ my %shootingMode = (
|
|
2118
2118
|
Name => 'UserProfile',
|
2119
2119
|
Writable => 'string',
|
2120
2120
|
},
|
2121
|
+
# 0x357 int32u - 0=DNG, 3162=JPG (ref 23)
|
2121
2122
|
0x359 => { #23
|
2122
2123
|
Name => 'ISOSelected',
|
2123
2124
|
Writable => 'int32s',
|
@@ -2134,7 +2135,19 @@ my %shootingMode = (
|
|
2134
2135
|
PrintConv => 'sprintf("%.1f", $val)',
|
2135
2136
|
PrintConvInv => '$val',
|
2136
2137
|
},
|
2137
|
-
|
2138
|
+
0x035b => { #IB
|
2139
|
+
Name => 'CorrelatedColorTemp', # (in Kelvin)
|
2140
|
+
Writable => 'int16u',
|
2141
|
+
},
|
2142
|
+
0x035c => { #IB
|
2143
|
+
Name => 'ColorTint', # (same units as Adobe is using)
|
2144
|
+
Writable => 'int16s',
|
2145
|
+
},
|
2146
|
+
0x035d => { #IB
|
2147
|
+
Name => 'WhitePoint', # (x/y)
|
2148
|
+
Writable => 'rational64u',
|
2149
|
+
Count => 2,
|
2150
|
+
},
|
2138
2151
|
);
|
2139
2152
|
|
2140
2153
|
# Type 2 tags (ref PH)
|
@@ -15,7 +15,7 @@ use vars qw($VERSION);
|
|
15
15
|
use Image::ExifTool qw(:DataAccess :Utils);
|
16
16
|
use Image::ExifTool::Exif;
|
17
17
|
|
18
|
-
$VERSION = '1.
|
18
|
+
$VERSION = '1.07';
|
19
19
|
|
20
20
|
sub WritePhaseOne($$$);
|
21
21
|
sub ProcessPhaseOne($$$);
|
@@ -73,10 +73,11 @@ my @formatName = ( undef, 'string', 'int16s', undef, 'int32s' );
|
|
73
73
|
PrintConv => { #PH
|
74
74
|
1 => 'RAW 1', #? (encrypted)
|
75
75
|
2 => 'RAW 2', #? (encrypted)
|
76
|
-
3 => 'IIQ L',
|
76
|
+
3 => 'IIQ L', # (now "L14", ref IB)
|
77
77
|
# 4?
|
78
78
|
5 => 'IIQ S',
|
79
|
-
6 => 'IIQ Sv2',
|
79
|
+
6 => 'IIQ Sv2', # (now "S14" for "IIQ 14 Smart" and "IIQ 14 Sensor+", ref IB)
|
80
|
+
8 => 'IIQ L16', #IB ("IIQ 16 Extended" and "IIQ 16 Large")
|
80
81
|
},
|
81
82
|
},
|
82
83
|
0x010f => {
|
@@ -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.63';
|
51
51
|
|
52
52
|
sub ProcessMOV($$;$);
|
53
53
|
sub ProcessKeys($$$);
|
@@ -65,6 +65,7 @@ sub Process_gsen($$$);
|
|
65
65
|
sub ProcessRIFFTrailer($$$);
|
66
66
|
sub ProcessTTAD($$$);
|
67
67
|
sub ProcessNMEA($$$);
|
68
|
+
sub ProcessGPSLog($$$);
|
68
69
|
sub SaveMetaKeys($$$);
|
69
70
|
# ++^^^^^^^^^^^^++
|
70
71
|
sub ParseItemLocation($$);
|
@@ -160,8 +161,15 @@ my %ftypLookup = (
|
|
160
161
|
'F4P ' => 'Protected Video for Adobe Flash Player 9+ (.F4P)', # video/mp4
|
161
162
|
'F4V ' => 'Video for Adobe Flash Player 9+ (.F4V)', # video/mp4
|
162
163
|
'isc2' => 'ISMACryp 2.0 Encrypted File', # ?/enc-isoff-generic
|
163
|
-
'iso2' => 'MP4 Base Media v2 [ISO 14496-12:2005]', # video/mp4
|
164
|
-
'
|
164
|
+
'iso2' => 'MP4 Base Media v2 [ISO 14496-12:2005]', # video/mp4 (or audio)
|
165
|
+
'iso3' => 'MP4 Base Media v3', # video/mp4 (or audio)
|
166
|
+
'iso4' => 'MP4 Base Media v4', # video/mp4 (or audio)
|
167
|
+
'iso5' => 'MP4 Base Media v5', # video/mp4 (or audio)
|
168
|
+
'iso6' => 'MP4 Base Media v6', # video/mp4 (or audio)
|
169
|
+
'iso7' => 'MP4 Base Media v7', # video/mp4 (or audio)
|
170
|
+
'iso8' => 'MP4 Base Media v8', # video/mp4 (or audio)
|
171
|
+
'iso9' => 'MP4 Base Media v9', # video/mp4 (or audio)
|
172
|
+
'isom' => 'MP4 Base Media v1 [IS0 14496-12:2003]', # video/mp4 (or audio)
|
165
173
|
'JP2 ' => 'JPEG 2000 Image (.JP2) [ISO 15444-1 ?]', # image/jp2
|
166
174
|
'JP20' => 'Unknown, from GPAC samples (prob non-existent)',
|
167
175
|
'jpm ' => 'JPEG 2000 Compound Image (.JPM) [ISO 15444-6]', # image/jpm
|
@@ -243,7 +251,11 @@ my %timeInfo = (
|
|
243
251
|
},
|
244
252
|
# (all CR3 files store UTC times - PH)
|
245
253
|
ValueConv => 'ConvertUnixTime($val, $self->Options("QuickTimeUTC") || $$self{FileType} eq "CR3")',
|
246
|
-
ValueConvInv =>
|
254
|
+
ValueConvInv => q{
|
255
|
+
$val = GetUnixTime($val, $self->Options("QuickTimeUTC"));
|
256
|
+
return undef unless defined $val;
|
257
|
+
return $val + (66 * 365 + 17) * 24 * 3600;
|
258
|
+
},
|
247
259
|
PrintConv => '$self->ConvertDateTime($val)',
|
248
260
|
PrintConvInv => '$self->InverseDateTime($val)',
|
249
261
|
# (can't put Groups here because they aren't constant!)
|
@@ -258,11 +270,15 @@ my %unknownInfo = (
|
|
258
270
|
Unknown => 1,
|
259
271
|
ValueConv => '$val =~ /^([\x20-\x7e]*)\0*$/ ? $1 : \$val',
|
260
272
|
);
|
273
|
+
|
274
|
+
# multi-language text with 6-byte header
|
275
|
+
my %langText = ( IText => 6 );
|
276
|
+
|
261
277
|
# parsing for most of the 3gp udta language text boxes
|
262
|
-
my %
|
278
|
+
my %langText3gp = (
|
263
279
|
Notes => 'used in 3gp videos',
|
264
|
-
IText => 6,
|
265
280
|
Avoid => 1,
|
281
|
+
IText => 6,
|
266
282
|
);
|
267
283
|
|
268
284
|
# 4-character Vendor ID codes (ref PH)
|
@@ -670,6 +686,15 @@ my %eeBox2 = (
|
|
670
686
|
udat => { #PH (GPS NMEA-format log written by Datakam Player software)
|
671
687
|
Name => 'GPSLog',
|
672
688
|
Binary => 1, # (actually ASCII, but very lengthy)
|
689
|
+
Notes => 'parsed to extract GPS separately when ExtractEmbedded is used',
|
690
|
+
RawConv => q{
|
691
|
+
$val =~ s/\0+$//; # remove trailing nulls
|
692
|
+
if (length $val and $$self{OPTIONS}{ExtractEmbedded}) {
|
693
|
+
my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
694
|
+
Image::ExifTool::QuickTime::ProcessGPSLog($self, { DataPt => \$val }, $tagTbl);
|
695
|
+
}
|
696
|
+
return $val;
|
697
|
+
},
|
673
698
|
},
|
674
699
|
# meta - proprietary XML information written by some Flip cameras - PH
|
675
700
|
# beam - 16 bytes found in an iPhone video
|
@@ -1545,47 +1570,43 @@ my %eeBox2 = (
|
|
1545
1570
|
# the following are 3gp tags, references:
|
1546
1571
|
# http://atomicparsley.sourceforge.net
|
1547
1572
|
# http://www.3gpp.org/ftp/tsg_sa/WG4_CODEC/TSGS4_25/Docs/
|
1548
|
-
# (note that all %
|
1549
|
-
cprt => { Name => 'Copyright', %
|
1550
|
-
auth => { Name => 'Author', %
|
1551
|
-
titl => { Name => 'Title', %
|
1552
|
-
dscp => { Name => 'Description',%
|
1553
|
-
perf => { Name => 'Performer', %
|
1554
|
-
gnre => { Name => 'Genre', %
|
1555
|
-
albm => { Name => 'Album', %
|
1556
|
-
coll => { Name => 'CollectionName', %
|
1573
|
+
# (note that all %langText3gp tags are Avoid => 1)
|
1574
|
+
cprt => { Name => 'Copyright', %langText3gp, Groups => { 2 => 'Author' } },
|
1575
|
+
auth => { Name => 'Author', %langText3gp, Groups => { 2 => 'Author' } },
|
1576
|
+
titl => { Name => 'Title', %langText3gp },
|
1577
|
+
dscp => { Name => 'Description',%langText3gp },
|
1578
|
+
perf => { Name => 'Performer', %langText3gp },
|
1579
|
+
gnre => { Name => 'Genre', %langText3gp },
|
1580
|
+
albm => { Name => 'Album', %langText3gp },
|
1581
|
+
coll => { Name => 'CollectionName', %langText3gp }, #17
|
1557
1582
|
rtng => {
|
1558
1583
|
Name => 'Rating',
|
1584
|
+
Writable => 'undef',
|
1585
|
+
Avoid => 1,
|
1559
1586
|
# (4-byte flags, 4-char entity, 4-char criteria, 2-byte lang, string)
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
my $lang = Image::ExifTool::QuickTime::UnpackLang(Get16u(\$val, 12));
|
1565
|
-
$lang = $lang ? "($lang) " : '';
|
1566
|
-
$val = substr($val, 14);
|
1567
|
-
$val = $self->Decode($val, 'UCS2') if $val =~ /^\xfe\xff/;
|
1568
|
-
return $lang . $str . ' ' . $val;
|
1569
|
-
},
|
1587
|
+
IText => 14, # (14 bytes before string)
|
1588
|
+
Notes => 'string in the form "Entity=XXXX Criteria=XXXX XXXXX", used in 3gp videos',
|
1589
|
+
ValueConv => '$val=~s/^(.{4})(.{4})/Entity=$1 Criteria=$2 /i; $val',
|
1590
|
+
ValueConvInv => '$val=~s/Entity=(.{4}) Criteria=(.{4}) ?/$1$2/i; $val',
|
1570
1591
|
},
|
1571
1592
|
clsf => {
|
1572
1593
|
Name => 'Classification',
|
1594
|
+
Writable => 'undef',
|
1595
|
+
Avoid => 1,
|
1573
1596
|
# (4-byte flags, 4-char entity, 2-byte index, 2-byte lang, string)
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
my $lang = Image::ExifTool::QuickTime::UnpackLang(Get16u(\$val, 10));
|
1579
|
-
$lang = $lang ? "($lang) " : '';
|
1580
|
-
$val = substr($val, 12);
|
1581
|
-
$val = $self->Decode($val, 'UCS2') if $val =~ /^\xfe\xff/;
|
1582
|
-
return $lang . $str . ' ' . $val;
|
1583
|
-
},
|
1597
|
+
IText => 12,
|
1598
|
+
Notes => 'string in the form "Entity=XXXX Index=### XXXXX", used in 3gp videos',
|
1599
|
+
ValueConv => '$val=~s/^(.{4})(.{2})/"Entity=$1 Index=".unpack("n",$2)." "/ie; $val',
|
1600
|
+
ValueConvInv => '$val=~s/Entity=(.{4}) Index=(\d+) ?/$1.pack("n",$2)/ie; $val',
|
1584
1601
|
},
|
1585
1602
|
kywd => {
|
1586
1603
|
Name => 'Keywords',
|
1587
|
-
# (4 byte flags, 2-byte lang, 1-byte count, count x pascal strings)
|
1604
|
+
# (4 byte flags, 2-byte lang, 1-byte count, count x pascal strings, ref 17)
|
1605
|
+
# (but I have also seen a simple string written by iPhone, so don't make writable yet)
|
1606
|
+
Notes => "not writable because Apple doesn't follow the 3gp specification",
|
1588
1607
|
RawConv => q{
|
1608
|
+
my $sep = $self->Options('ListSep');
|
1609
|
+
return join($sep, split /\0+/, $val) unless $val =~ /^\0/; # (iPhone)
|
1589
1610
|
return '<err>' unless length $val >= 7;
|
1590
1611
|
my $lang = Image::ExifTool::QuickTime::UnpackLang(Get16u(\$val, 4));
|
1591
1612
|
$lang = $lang ? "($lang) " : '';
|
@@ -1601,27 +1622,30 @@ my %eeBox2 = (
|
|
1601
1622
|
push @vals, $v;
|
1602
1623
|
$pos += $len;
|
1603
1624
|
}
|
1604
|
-
my $sep = $self->Options('ListSep');
|
1605
1625
|
return $lang . join($sep, @vals);
|
1606
1626
|
},
|
1607
1627
|
},
|
1608
1628
|
loci => {
|
1609
1629
|
Name => 'LocationInformation',
|
1610
1630
|
Groups => { 2 => 'Location' },
|
1631
|
+
Writable => 'undef',
|
1632
|
+
IText => 6,
|
1633
|
+
Avoid => 1,
|
1634
|
+
NoDecode => 1, # (we'll decode the data ourself)
|
1635
|
+
Notes => q{
|
1636
|
+
string in the form "XXXXX Role=XXX Lat=XXX Lon=XXX Alt=XXX Body=XXX
|
1637
|
+
Notes=XXX", used in 3gp videos
|
1638
|
+
},
|
1611
1639
|
# (4-byte flags, 2-byte lang, location string, 1-byte role, 4-byte fixed longitude,
|
1612
1640
|
# 4-byte fixed latitude, 4-byte fixed altitude, body string, notes string)
|
1613
1641
|
RawConv => q{
|
1614
|
-
return '<err>' unless length $val >= 6;
|
1615
|
-
my $lang = Image::ExifTool::QuickTime::UnpackLang(Get16u(\$val, 4));
|
1616
|
-
$lang = $lang ? "($lang) " : '';
|
1617
|
-
$val = substr($val, 6);
|
1618
1642
|
my $str;
|
1619
1643
|
if ($val =~ /^\xfe\xff/) {
|
1620
1644
|
$val =~ s/^(\xfe\xff(.{2})*?)\0\0//s or return '<err>';
|
1621
1645
|
$str = $self->Decode($1, 'UCS2');
|
1622
1646
|
} else {
|
1623
1647
|
$val =~ s/^(.*?)\0//s or return '<err>';
|
1624
|
-
$str = $1;
|
1648
|
+
$str = $self->Decode($1, 'UTF8');
|
1625
1649
|
}
|
1626
1650
|
$str = '(none)' unless length $str;
|
1627
1651
|
return '<err>' if length $val < 13;
|
@@ -1636,27 +1660,52 @@ my %eeBox2 = (
|
|
1636
1660
|
if ($val =~ s/^(\xfe\xff(.{2})*?)\0\0//s) {
|
1637
1661
|
$str .= ' Body=' . $self->Decode($1, 'UCS2');
|
1638
1662
|
} elsif ($val =~ s/^(.*?)\0//s) {
|
1639
|
-
$str .=
|
1663
|
+
$str .= ' Body=' . $self->Decode($1, 'UTF8');
|
1640
1664
|
}
|
1641
1665
|
if ($val =~ s/^(\xfe\xff(.{2})*?)\0\0//s) {
|
1642
1666
|
$str .= ' Notes=' . $self->Decode($1, 'UCS2');
|
1643
1667
|
} elsif ($val =~ s/^(.*?)\0//s) {
|
1644
|
-
$str .=
|
1668
|
+
$str .= ' Notes=' . $self->Decode($1, 'UTF8');
|
1645
1669
|
}
|
1646
|
-
return $
|
1670
|
+
return $str;
|
1671
|
+
},
|
1672
|
+
RawConvInv => q{
|
1673
|
+
my ($role, $lat, $lon, $alt, $body, $note);
|
1674
|
+
$lat = $1 if $val =~ s/ Lat=([-+]?[.\d]+)//i;
|
1675
|
+
$lon = $1 if $val =~ s/ Lon=([-+]?[.\d]+)//i;
|
1676
|
+
$alt = $1 if $val =~ s/ Alt=([-+]?[.\d]+)//i;
|
1677
|
+
$note = $val =~ s/ Notes=(.*)//i ? $1 : '';
|
1678
|
+
$body = $val =~ s/ Body=(.*)//i ? $1 : '';
|
1679
|
+
$role = $val =~ s/ Role=(.*)//i ? $1 : '';
|
1680
|
+
$val = '' if $val eq '(none)';
|
1681
|
+
$role = {shooting=>0,real=>1,fictional=>2}->{lc $role} || 0;
|
1682
|
+
return $self->Encode($val, 'UTF8') . "\0" . Set8u($role) .
|
1683
|
+
SetFixed32s(defined $lon ? $lon : 999) .
|
1684
|
+
SetFixed32s(defined $lat ? $lat : 999) .
|
1685
|
+
SetFixed32s(defined $alt ? $alt : 0) .
|
1686
|
+
$self->Encode($body) . "\0" .
|
1687
|
+
$self->Encode($note) . "\0";
|
1647
1688
|
},
|
1648
1689
|
},
|
1649
1690
|
yrrc => {
|
1650
1691
|
Name => 'Year',
|
1692
|
+
Writable => 'undef',
|
1651
1693
|
Groups => { 2 => 'Time' },
|
1652
|
-
|
1694
|
+
Avoid => 1,
|
1695
|
+
Notes => 'used in 3gp videos',
|
1696
|
+
ValueConv => 'length($val) >= 6 ? unpack("x4n",$val) : "<err>"',
|
1697
|
+
ValueConvInv => 'pack("Nn",0,$val)',
|
1653
1698
|
},
|
1654
1699
|
urat => { #17
|
1655
1700
|
Name => 'UserRating',
|
1656
|
-
|
1701
|
+
Writable => 'undef',
|
1702
|
+
Notes => 'used in 3gp videos',
|
1703
|
+
Avoid => 1,
|
1704
|
+
ValueConv => q{
|
1657
1705
|
return '<err>' unless length $val >= 8;
|
1658
|
-
|
1706
|
+
unpack('x7C', $val);
|
1659
1707
|
},
|
1708
|
+
ValueConvInv => 'pack("N2",0,$val)',
|
1660
1709
|
},
|
1661
1710
|
# tsel - TrackSelection (ref 17)
|
1662
1711
|
# Apple tags (ref 16[dead] -- see ref 25 instead)
|
@@ -1988,7 +2037,11 @@ my %eeBox2 = (
|
|
1988
2037
|
# ---- Microsoft ----
|
1989
2038
|
Xtra => { #PH (microsoft)
|
1990
2039
|
Name => 'MicrosoftXtra',
|
1991
|
-
|
2040
|
+
WriteGroup => 'Microsoft',
|
2041
|
+
SubDirectory => {
|
2042
|
+
DirName => 'Microsoft',
|
2043
|
+
TagTable => 'Image::ExifTool::Microsoft::Xtra',
|
2044
|
+
},
|
1992
2045
|
},
|
1993
2046
|
# ---- Minolta ----
|
1994
2047
|
MMA0 => { #PH (DiMage 7Hi)
|
@@ -2037,7 +2090,7 @@ my %eeBox2 = (
|
|
2037
2090
|
SubDirectory => { TagTable => 'Image::ExifTool::Olympus::thmb' },
|
2038
2091
|
},{ #17 (format is in bytes 3-7)
|
2039
2092
|
Name => 'ThumbnailImage',
|
2040
|
-
Condition => '$$valPt =~ /^.{8}\xff\xd8\xff\xdb/s',
|
2093
|
+
Condition => '$$valPt =~ /^.{8}\xff\xd8\xff[\xdb\xe0]/s',
|
2041
2094
|
Groups => { 2 => 'Preview' },
|
2042
2095
|
RawConv => 'substr($val, 8)',
|
2043
2096
|
Binary => 1,
|
@@ -2994,9 +3047,9 @@ my %eeBox2 = (
|
|
2994
3047
|
3-character ISO 639-2 language code and an optional ISO 3166-1 alpha 2
|
2995
3048
|
country code to the tag name (eg. "ItemList:Title-fra" or
|
2996
3049
|
"ItemList::Title-fra-FR"). When creating a new Meta box to contain the
|
2997
|
-
ItemList directory, by default ExifTool
|
2998
|
-
|
2999
|
-
|
3050
|
+
ItemList directory, by default ExifTool adds an 'mdir' (Metadata) Handler
|
3051
|
+
box because Apple software may ignore ItemList tags otherwise, but the API
|
3052
|
+
L<QuickTimeHandler|../ExifTool.html#QuickTimeHandler> option may be set to 0 to avoid this.
|
3000
3053
|
},
|
3001
3054
|
# in this table, binary 1 and 2-byte "data"-type tags are interpreted as
|
3002
3055
|
# int8u and int16u. Multi-byte binary "data" tags are extracted as binary data.
|
@@ -6157,13 +6210,12 @@ my %eeBox2 = (
|
|
6157
6210
|
PROCESS_PROC => \&ProcessKeys,
|
6158
6211
|
WRITE_PROC => \&WriteKeys,
|
6159
6212
|
CHECK_PROC => \&CheckQTValue,
|
6160
|
-
VARS => { LONG_TAGS =>
|
6213
|
+
VARS => { LONG_TAGS => 7 },
|
6161
6214
|
WRITABLE => 1,
|
6162
6215
|
# (not PREFERRED when writing)
|
6163
6216
|
GROUPS => { 1 => 'Keys' },
|
6164
6217
|
WRITE_GROUP => 'Keys',
|
6165
6218
|
LANG_INFO => \&GetLangInfo,
|
6166
|
-
FORMAT => 'string',
|
6167
6219
|
NOTES => q{
|
6168
6220
|
This directory contains a list of key names which are used to decode tags
|
6169
6221
|
written by the "mdta" handler. Also in this table are a few tags found in
|
@@ -6265,6 +6317,11 @@ my %eeBox2 = (
|
|
6265
6317
|
PrintConv => '$self->ConvertDateTime($val)',
|
6266
6318
|
PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
|
6267
6319
|
},
|
6320
|
+
'location.accuracy.horizontal' => { Name => 'LocationAccuracyHorizontal' },
|
6321
|
+
'live-photo.auto' => { Name => 'LivePhotoAuto', Writable => 'int8u' },
|
6322
|
+
'live-photo.vitality-score' => { Name => 'LivePhotoVitalityScore', Writable => 'float' },
|
6323
|
+
'live-photo.vitality-scoring-version' => { Name => 'LivePhotoVitalityScoringVersion', Writable => 'int64s' },
|
6324
|
+
'apple.photos.variation-identifier' => { Name => 'ApplePhotosVariationIdentifier', Writable => 'int64s' },
|
6268
6325
|
'direction.facing' => { Name => 'CameraDirection', Groups => { 2 => 'Location' } },
|
6269
6326
|
'direction.motion' => { Name => 'CameraMotion', Groups => { 2 => 'Location' } },
|
6270
6327
|
'location.body' => { Name => 'LocationBody', Groups => { 2 => 'Location' } },
|
@@ -6300,11 +6357,15 @@ my %eeBox2 = (
|
|
6300
6357
|
# com.divergentmedia.clipwrap.manufacturer ('Sony')
|
6301
6358
|
# com.divergentmedia.clipwrap.originalDateTime ('2013/2/6 10:30:40+0200')
|
6302
6359
|
#
|
6303
|
-
# seen in timed metadata (mebx), and added dynamically to the table
|
6304
|
-
#
|
6360
|
+
# seen in timed metadata (mebx), and added dynamically to the table via SaveMetaKeys()
|
6361
|
+
# NOTE: these tags are not writable! (timed metadata cannot yet be written)
|
6305
6362
|
#
|
6306
6363
|
# (mdta)com.apple.quicktime.video-orientation (dtyp=66, int16s)
|
6307
|
-
'video-orientation' => {
|
6364
|
+
'video-orientation' => {
|
6365
|
+
Name => 'VideoOrientation',
|
6366
|
+
Writable => 0,
|
6367
|
+
PrintConv => \%Image::ExifTool::Exif::orientation, #PH (NC)
|
6368
|
+
},
|
6308
6369
|
# (mdta)com.apple.quicktime.live-photo-info (dtyp=com.apple.quicktime.com.apple.quicktime.live-photo-info)
|
6309
6370
|
'live-photo-info' => {
|
6310
6371
|
Name => 'LivePhotoInfo',
|
@@ -7589,7 +7650,11 @@ my %eeBox2 = (
|
|
7589
7650
|
8 => {
|
7590
7651
|
Name => 'HandlerType',
|
7591
7652
|
Format => 'undef[4]',
|
7592
|
-
RawConv =>
|
7653
|
+
RawConv => q{
|
7654
|
+
$$self{HandlerType} = $val unless $val eq 'alis' or $val eq 'url ';
|
7655
|
+
$$self{HasHandler}{$val} = 1; # remember all our handlers
|
7656
|
+
return $val;
|
7657
|
+
},
|
7593
7658
|
PrintConvColumns => 2,
|
7594
7659
|
PrintConv => {
|
7595
7660
|
alis => 'Alias Data', #PH
|
@@ -7694,7 +7759,7 @@ my %eeBox2 = (
|
|
7694
7759
|
$val =~ s/\0+$//; # remove trailing nulls
|
7695
7760
|
if (length $val and $$self{OPTIONS}{ExtractEmbedded}) {
|
7696
7761
|
my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
|
7697
|
-
Image::ExifTool::QuickTime::
|
7762
|
+
Image::ExifTool::QuickTime::ProcessGPSLog($self, { DataPt => \$val }, $tagTbl);
|
7698
7763
|
}
|
7699
7764
|
return $val;
|
7700
7765
|
},
|
@@ -8574,7 +8639,7 @@ sub QuickTimeFormat($$)
|
|
8574
8639
|
my ($flags, $len) = @_;
|
8575
8640
|
my $format;
|
8576
8641
|
if ($flags == 0x15 or $flags == 0x16) {
|
8577
|
-
$format = { 1=>'int8', 2=>'int16', 4=>'int32' }->{$len};
|
8642
|
+
$format = { 1=>'int8', 2=>'int16', 4=>'int32', 8=>'int64' }->{$len};
|
8578
8643
|
$format .= $flags == 0x15 ? 's' : 'u' if $format;
|
8579
8644
|
} elsif ($flags == 0x17) {
|
8580
8645
|
$format = 'float';
|
@@ -8927,6 +8992,7 @@ sub ProcessMOV($$;$)
|
|
8927
8992
|
if ($raf->Read($buff, $size-8) == $size-8) {
|
8928
8993
|
$raf->Seek(-($size-8), 1);
|
8929
8994
|
my $type = substr($buff, 0, 4);
|
8995
|
+
$$et{save_ftyp} = $type;
|
8930
8996
|
# see if we know the extension for this file type
|
8931
8997
|
if ($ftypLookup{$type} and $ftypLookup{$type} =~ /\(\.(\w+)/) {
|
8932
8998
|
$fileType = $1;
|
@@ -9350,9 +9416,9 @@ ItemID: foreach $id (keys %$items) {
|
|
9350
9416
|
}
|
9351
9417
|
for (;;) {
|
9352
9418
|
my ($len, $lang);
|
9353
|
-
if ($$tagInfo{IText} and $$tagInfo{IText}
|
9354
|
-
last if $pos +
|
9355
|
-
$pos +=
|
9419
|
+
if ($$tagInfo{IText} and $$tagInfo{IText} >= 6) {
|
9420
|
+
last if $pos + $$tagInfo{IText} > $size;
|
9421
|
+
$pos += $$tagInfo{IText} - 2;
|
9356
9422
|
$lang = unpack("x${pos}n", $val);
|
9357
9423
|
$pos += 2;
|
9358
9424
|
$len = $size - $pos;
|
@@ -9372,7 +9438,7 @@ ItemID: foreach $id (keys %$items) {
|
|
9372
9438
|
# ignore any empty entries (or null padding) after the first
|
9373
9439
|
next if not $len and $pos;
|
9374
9440
|
my $str = substr($val, $pos, $len);
|
9375
|
-
my $langInfo;
|
9441
|
+
my ($langInfo, $enc);
|
9376
9442
|
if (($lang < 0x400 or $lang == 0x7fff) and $str !~ /^\xfe\xff/) {
|
9377
9443
|
# this is a Macintosh language code
|
9378
9444
|
# a language code of 0 is Macintosh english, so treat as default
|
@@ -9389,15 +9455,22 @@ ItemID: foreach $id (keys %$items) {
|
|
9389
9455
|
}
|
9390
9456
|
# the spec says only "Macintosh text encoding", but
|
9391
9457
|
# allow this to be configured by the user
|
9392
|
-
$
|
9458
|
+
$enc = $charsetQuickTime;
|
9393
9459
|
} else {
|
9394
9460
|
# convert language code to ASCII (ignore read-only bit)
|
9395
9461
|
$lang = UnpackLang($lang);
|
9396
9462
|
# may be either UTF-8 or UTF-16BE
|
9397
|
-
|
9463
|
+
$enc = $str=~s/^\xfe\xff// ? 'UTF16' : 'UTF8';
|
9464
|
+
}
|
9465
|
+
unless ($$tagInfo{NoDecode}) {
|
9398
9466
|
$str = $et->Decode($str, $enc);
|
9467
|
+
$str =~ s/\0+$//; # remove any trailing nulls (eg. 3gp tags)
|
9468
|
+
}
|
9469
|
+
if ($$tagInfo{IText} and $$tagInfo{IText} > 6) {
|
9470
|
+
my $n = $$tagInfo{IText} - 6;
|
9471
|
+
# add back extra bytes (eg. 'rtng' box)
|
9472
|
+
$str = substr($val, $pos-$n-2, $n) . $str;
|
9399
9473
|
}
|
9400
|
-
$str =~ s/\0+$//; # remove any trailing nulls (eg. 3gp tags)
|
9401
9474
|
$langInfo = GetLangInfoQT($et, $tagInfo, $lang) if $lang;
|
9402
9475
|
$et->FoundTag($langInfo || $tagInfo, $str);
|
9403
9476
|
$pos += $len;
|
@@ -9447,6 +9520,13 @@ ItemID: foreach $id (keys %$items) {
|
|
9447
9520
|
($size, $tag) = unpack('Na4', $buff);
|
9448
9521
|
++$index if defined $index;
|
9449
9522
|
}
|
9523
|
+
# tweak file type based on track content ("iso*" ftyp only)
|
9524
|
+
if ($$et{VALUE}{FileType} and $$et{VALUE}{FileType} eq 'MP4' and
|
9525
|
+
$$et{save_ftyp} and $$et{HasHandler} and $$et{save_ftyp} =~ /^iso/ and
|
9526
|
+
$$et{HasHandler}{soun} and not $$et{HasHandler}{vide})
|
9527
|
+
{
|
9528
|
+
$et->OverrideFileType('M4A', 'audio/mp4');
|
9529
|
+
}
|
9450
9530
|
# fill in missing defaults for alternate language tags
|
9451
9531
|
# (the first language is taken as the default)
|
9452
9532
|
if ($doDefaultLang and $$et{QTLang}) {
|