exiftool_vendored 11.94.0 → 12.06.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of exiftool_vendored might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/bin/Changes +163 -3
- data/bin/MANIFEST +5 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +32 -32
- data/bin/exiftool +152 -52
- data/bin/lib/Image/ExifTool.pm +166 -115
- data/bin/lib/Image/ExifTool.pod +108 -81
- data/bin/lib/Image/ExifTool/AIFF.pm +2 -2
- data/bin/lib/Image/ExifTool/APE.pm +2 -2
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +13 -7
- data/bin/lib/Image/ExifTool/Canon.pm +6 -3
- data/bin/lib/Image/ExifTool/CanonCustom.pm +82 -16
- data/bin/lib/Image/ExifTool/DPX.pm +56 -2
- data/bin/lib/Image/ExifTool/DarwinCore.pm +16 -3
- data/bin/lib/Image/ExifTool/Exif.pm +15 -6
- data/bin/lib/Image/ExifTool/Font.pm +9 -2
- data/bin/lib/Image/ExifTool/GIF.pm +5 -0
- data/bin/lib/Image/ExifTool/GeoTiff.pm +2 -0
- data/bin/lib/Image/ExifTool/Geotag.pm +69 -21
- data/bin/lib/Image/ExifTool/GoPro.pm +10 -1
- data/bin/lib/Image/ExifTool/H264.pm +1 -1
- data/bin/lib/Image/ExifTool/HtmlDump.pm +2 -2
- data/bin/lib/Image/ExifTool/ID3.pm +91 -12
- data/bin/lib/Image/ExifTool/Lang/de.pm +3 -1
- data/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
- data/bin/lib/Image/ExifTool/M2TS.pm +44 -24
- data/bin/lib/Image/ExifTool/MWG.pm +9 -1
- data/bin/lib/Image/ExifTool/MacOS.pm +1 -1
- data/bin/lib/Image/ExifTool/Minolta.pm +3 -2
- data/bin/lib/Image/ExifTool/MinoltaRaw.pm +11 -10
- data/bin/lib/Image/ExifTool/Nikon.pm +156 -18
- data/bin/lib/Image/ExifTool/Olympus.pm +34 -17
- data/bin/lib/Image/ExifTool/PNG.pm +14 -3
- data/bin/lib/Image/ExifTool/PPM.pm +5 -5
- data/bin/lib/Image/ExifTool/Panasonic.pm +147 -13
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +33 -0
- data/bin/lib/Image/ExifTool/Parrot.pm +2 -1
- data/bin/lib/Image/ExifTool/Pentax.pm +3 -1
- data/bin/lib/Image/ExifTool/Photoshop.pm +2 -1
- data/bin/lib/Image/ExifTool/QuickTime.pm +277 -33
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +460 -67
- data/bin/lib/Image/ExifTool/README +21 -20
- data/bin/lib/Image/ExifTool/RIFF.pm +123 -3
- data/bin/lib/Image/ExifTool/RTF.pm +12 -7
- data/bin/lib/Image/ExifTool/Ricoh.pm +19 -1
- data/bin/lib/Image/ExifTool/Shift.pl +1 -0
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +40 -33
- data/bin/lib/Image/ExifTool/Sony.pm +379 -12
- data/bin/lib/Image/ExifTool/TagLookup.pm +1959 -1874
- data/bin/lib/Image/ExifTool/TagNames.pod +346 -55
- data/bin/lib/Image/ExifTool/Validate.pm +4 -4
- data/bin/lib/Image/ExifTool/WriteExif.pl +3 -2
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +26 -15
- data/bin/lib/Image/ExifTool/Writer.pl +52 -23
- data/bin/lib/Image/ExifTool/XMP.pm +41 -4
- data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
- data/bin/lib/Image/ExifTool/ZISRAW.pm +123 -0
- data/bin/perl-Image-ExifTool.spec +31 -31
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +4 -4
@@ -763,25 +763,26 @@ numerical, and generated automatically otherwise.
|
|
763
763
|
conditionally deleted.
|
764
764
|
|
765
765
|
Writable : Indicates this tag can be written (or not written if Writable
|
766
|
-
is set to zero), and for EXIF
|
767
|
-
writing. Writable may be set to 1 for MakerNotes
|
768
|
-
because the existing format is always used,
|
769
|
-
a format is desirable because it is used in
|
770
|
-
value. Set to 2 for tag to show "yes" in the
|
771
|
-
of the tag name documentation even when there
|
772
|
-
defined (eg. if it is written via an Extra
|
773
|
-
tables, the Writable flag may be
|
774
|
-
flag, in which case Format is used
|
775
|
-
value and Writable specifies the
|
776
|
-
EXIF IFD. For SubDirectories in
|
777
|
-
is only defined if the
|
778
|
-
|
779
|
-
is set to 0). If
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
for all
|
766
|
+
is set to zero), and for EXIF and QuickTime tables gives
|
767
|
+
format for writing. Writable may be set to 1 for MakerNotes
|
768
|
+
information because the existing format is always used,
|
769
|
+
however providing a format is desirable because it is used in
|
770
|
+
validating the value. Set to 2 for tag to show "yes" in the
|
771
|
+
Writable column of the tag name documentation even when there
|
772
|
+
is no WRITE_PROC defined (eg. if it is written via an Extra
|
773
|
+
tag). For EXIF and QuickTime tables, the Writable flag may be
|
774
|
+
different than the Format flag, in which case Format is used
|
775
|
+
for converting the binary value and Writable specifies the
|
776
|
+
format code written to the EXIF IFD. For SubDirectories in
|
777
|
+
EXIF information, this flag is only defined if the
|
778
|
+
SubDirectory is writable as a block, or if the SubDirectory
|
779
|
+
can not be edited (in which case Writable is set to 0). If
|
780
|
+
non-zero, the SubDirectory is also extracted as a block, so
|
781
|
+
the Binary and Protected flags should usually set as well.
|
782
|
+
There is currently no way to specify a write format for a
|
783
|
+
SubDirectory that is not writable as a block (the default is
|
784
|
+
'int32u' for IFD-type SubDirectories, and 'undef' for all
|
785
|
+
others).
|
785
786
|
|
786
787
|
WriteAlso : Used for writable tag to specify other tags to write when this
|
787
788
|
tag is written. The value is a hash reference. The hash keys
|
@@ -1083,7 +1084,7 @@ The contained structure field information hashes are similar to tag information
|
|
1083
1084
|
hashes, except that only the following elements are used:
|
1084
1085
|
|
1085
1086
|
Raw/Value/PrintConv (and their inverses), TagID (optional), Groups, List,
|
1086
|
-
Writable, Struct, Namespace, LangCode, PropertyPath, Notes.
|
1087
|
+
Writable, Struct, Namespace, FlatName, LangCode, PropertyPath, Notes.
|
1087
1088
|
|
1088
1089
|
But note that for PropertyPath, only the element of the path corresponding to
|
1089
1090
|
the specific field is stored (including any necessary list properties). The
|
@@ -29,11 +29,12 @@ use strict;
|
|
29
29
|
use vars qw($VERSION);
|
30
30
|
use Image::ExifTool qw(:DataAccess :Utils);
|
31
31
|
|
32
|
-
$VERSION = '1.
|
32
|
+
$VERSION = '1.56';
|
33
33
|
|
34
34
|
sub ConvertTimecode($);
|
35
35
|
sub ProcessSGLT($$$);
|
36
36
|
sub ProcessSLLT($$$);
|
37
|
+
sub ProcessLucas($$$);
|
37
38
|
|
38
39
|
# recognized RIFF variants
|
39
40
|
my %riffType = (
|
@@ -433,6 +434,14 @@ my %code2charset = (
|
|
433
434
|
Condition => '$$valPt =~ /^PENTDigital Camera/',
|
434
435
|
SubDirectory => { TagTable => 'Image::ExifTool::Pentax::Junk2' },
|
435
436
|
},
|
437
|
+
{
|
438
|
+
Name => 'LucasJunk', # (Lucas LK-7900 Ace)
|
439
|
+
Condition => '$$valPt =~ /^0G(DA|PS)/',
|
440
|
+
SubDirectory => {
|
441
|
+
TagTable => 'Image::ExifTool::QuickTime::Stream',
|
442
|
+
ProcessProc => \&ProcessLucas,
|
443
|
+
},
|
444
|
+
},
|
436
445
|
{
|
437
446
|
Name => 'TextJunk',
|
438
447
|
# try to interpret unknown junk as an ASCII string
|
@@ -476,14 +485,26 @@ my %code2charset = (
|
|
476
485
|
#
|
477
486
|
# WebP-specific tags
|
478
487
|
#
|
479
|
-
EXIF => { # (WebP)
|
488
|
+
EXIF => [{ # (WebP)
|
480
489
|
Name => 'EXIF',
|
490
|
+
Condition => '$$valPt =~ /^(II\x2a\0|MM\0\x2a)/',
|
481
491
|
Notes => 'WebP files',
|
482
492
|
SubDirectory => {
|
483
493
|
TagTable => 'Image::ExifTool::Exif::Main',
|
484
494
|
ProcessProc => \&Image::ExifTool::ProcessTIFF,
|
485
495
|
},
|
486
|
-
},
|
496
|
+
},{ # (WebP) - have also seen with "Exif\0\0" header - PH
|
497
|
+
Name => 'EXIF',
|
498
|
+
Condition => '$$valPt =~ /^Exif\0\0(II\x2a\0|MM\0\x2a)/',
|
499
|
+
SubDirectory => {
|
500
|
+
TagTable => 'Image::ExifTool::Exif::Main',
|
501
|
+
ProcessProc => \&Image::ExifTool::ProcessTIFF,
|
502
|
+
Start => 6,
|
503
|
+
},
|
504
|
+
},{
|
505
|
+
Name => 'UnknownEXIF',
|
506
|
+
Binary => 1,
|
507
|
+
}],
|
487
508
|
'XMP ' => { #14 (WebP)
|
488
509
|
Name => 'XMP',
|
489
510
|
Notes => 'WebP files',
|
@@ -1621,6 +1642,105 @@ sub ProcessSLLT($$$)
|
|
1621
1642
|
return 1;
|
1622
1643
|
}
|
1623
1644
|
|
1645
|
+
#------------------------------------------------------------------------------
|
1646
|
+
# Process Lucas streaming GPS information (Lucas LK-7900 Ace) (ref PH)
|
1647
|
+
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
|
1648
|
+
# Returns: 1 on success
|
1649
|
+
sub ProcessLucas($$$)
|
1650
|
+
{
|
1651
|
+
my ($et, $dirInfo, $tagTbl) = @_;
|
1652
|
+
my $dataPt = $$dirInfo{DataPt};
|
1653
|
+
my $dataLen = length $$dataPt;
|
1654
|
+
|
1655
|
+
unless ($et->Options('ExtractEmbedded')) {
|
1656
|
+
$et->Warn('Use ExtractEmbedded option to extract timed GPS', 3);
|
1657
|
+
return 1;
|
1658
|
+
}
|
1659
|
+
my %recLen = ( # record lengths (not including 4-byte ID)
|
1660
|
+
'0GDA' => 24,
|
1661
|
+
'0GPS' => 48,
|
1662
|
+
);
|
1663
|
+
my ($date,$time,$lat,$lon,$alt,$spd,$sat,$dop,$ew,$ns);
|
1664
|
+
$$et{SET_GROUP0} = $$et{SET_GROUP1} = 'RIFF';
|
1665
|
+
while ($$dataPt =~ /(0GDA|0GPS)/g) {
|
1666
|
+
my ($rec, $pos) = ($1, pos $$dataPt);
|
1667
|
+
$pos + $recLen{$rec} > $dataLen and $et->Warn("Truncated $1 record"), last;
|
1668
|
+
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
1669
|
+
# records start with int64u sample date/time in ms since 1970
|
1670
|
+
$et->HandleTag($tagTbl, SampleDateTime => Get64u($dataPt, $pos) / 1000);
|
1671
|
+
if ($rec eq '0GPS') {
|
1672
|
+
my $len = Get32u($dataPt, $pos+8);
|
1673
|
+
my $endPos = $pos + $recLen{$rec} + $len;
|
1674
|
+
$endPos > $dataLen and $et->Warn('Truncated 0GPS record'), last;
|
1675
|
+
my $buff = substr($$dataPt, $pos+$recLen{$rec}, $len);
|
1676
|
+
while ($buff =~ /\$(GC|GA),(\d+),/g) {
|
1677
|
+
my $p = pos $buff;
|
1678
|
+
$time = $2;
|
1679
|
+
if ($1 eq 'GC') {
|
1680
|
+
# time date dist ? sat dop alt A
|
1681
|
+
# $GC,052350,180914,0000955,1,08,1.1,0017,,A*45\x0d\x0a\0
|
1682
|
+
if ($buff =~ /\G(\d+),\d*,\d*,(\d+),([-\d.]+),(\d+),\d*,A/g) {
|
1683
|
+
($date,$sat,$dop,$alt) = ($1,$2,$3,$4);
|
1684
|
+
}
|
1685
|
+
} else {
|
1686
|
+
# time A lat lon spd N W
|
1687
|
+
# $GA,052351,A,0949.6626,07635.4439,049,N,E,*4C\x0d\x0a\0
|
1688
|
+
if ($buff =~ /\GA,([\d.]+),([\d.]+),(\d+),([NS]),([EW])/g) {
|
1689
|
+
($lat,$lon,$spd,$ns,$ew) = ($1,$2,$3,$4,$5,$6);
|
1690
|
+
# lat/long are in DDDMM.MMMM format
|
1691
|
+
my $deg = int($lat / 100);
|
1692
|
+
$lat = $deg + ($lat - $deg * 100) / 60;
|
1693
|
+
$deg = int($lon / 100);
|
1694
|
+
$lon = $deg + ($lon - $deg * 100) / 60;
|
1695
|
+
$lat *= -1 if $ns eq 'S';
|
1696
|
+
$lon *= -1 if $ew eq 'W';
|
1697
|
+
}
|
1698
|
+
}
|
1699
|
+
# look ahead to next NMEA-like sentence, and store the fix
|
1700
|
+
# now only if the next sentence is not at the same time
|
1701
|
+
if ($buff !~ /\$(GC|GA),$time,/g) {
|
1702
|
+
pos($$dataPt) = $endPos;
|
1703
|
+
if ($$dataPt !~ /\$(GC|GA),(\d+)/ or $1 ne $time) {
|
1704
|
+
$time =~ s/(\d{2})(\d{2})(\d{2})/$1:$2:$3Z/;
|
1705
|
+
if ($date) {
|
1706
|
+
$date =~ s/(\d{2})(\d{2})(\d{2})/20$3:$2:$1/;
|
1707
|
+
$et->HandleTag($tagTbl, GPSDateTime => "$date $time");
|
1708
|
+
} else {
|
1709
|
+
$et->HandleTag($tagTbl, GPSTimeStamp => $time);
|
1710
|
+
}
|
1711
|
+
if (defined $lat) {
|
1712
|
+
$et->HandleTag($tagTbl, GPSLatitude => $lat);
|
1713
|
+
$et->HandleTag($tagTbl, GPSLongitude => $lon);
|
1714
|
+
$et->HandleTag($tagTbl, GPSSpeed => $spd);
|
1715
|
+
}
|
1716
|
+
if (defined $alt) {
|
1717
|
+
$et->HandleTag($tagTbl, GPSAltitude => $alt);
|
1718
|
+
$et->HandleTag($tagTbl, GPSSatellites => $sat);
|
1719
|
+
$et->HandleTag($tagTbl, GPSDOP => $dop);
|
1720
|
+
}
|
1721
|
+
undef $lat;
|
1722
|
+
undef $alt;
|
1723
|
+
}
|
1724
|
+
}
|
1725
|
+
pos($buff) = $p;
|
1726
|
+
}
|
1727
|
+
$pos += $len;
|
1728
|
+
} else { # this is an accelerometer (0GDA) record
|
1729
|
+
# record has 4 more int32s values (the last is always 57 or 58 --
|
1730
|
+
# maybe related to sample time in ms? -- not extracted)
|
1731
|
+
my @acc = unpack('x'.($pos+8).'V3', $$dataPt);
|
1732
|
+
# change to signed integer and divide by 256
|
1733
|
+
map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
|
1734
|
+
$et->HandleTag($tagTbl, Accelerometer => "@acc");
|
1735
|
+
}
|
1736
|
+
pos($$dataPt) = $pos + $recLen{$rec};
|
1737
|
+
}
|
1738
|
+
delete $$et{SET_GROUP0};
|
1739
|
+
delete $$et{SET_GROUP1};
|
1740
|
+
$$et{DOC_NUM} = 0;
|
1741
|
+
return 1;
|
1742
|
+
}
|
1743
|
+
|
1624
1744
|
#------------------------------------------------------------------------------
|
1625
1745
|
# Extract information from a RIFF file
|
1626
1746
|
# Inputs: 0) ExifTool object reference, 1) DirInfo reference
|
@@ -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.04';
|
19
19
|
|
20
20
|
sub ProcessUserProps($$$);
|
21
21
|
|
@@ -181,12 +181,17 @@ sub UnescapeRTF($$$)
|
|
181
181
|
if ($1 eq 'uc') { # \ucN
|
182
182
|
$skip = $2;
|
183
183
|
} elsif ($1 eq 'u') { # \uN
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
184
|
+
if ($2 < 0) {
|
185
|
+
$et->WarnOnce('Invalid Unicode character(s) in text');
|
186
|
+
$rtnVal .= '?';
|
187
|
+
} else {
|
188
|
+
require Image::ExifTool::Charset;
|
189
|
+
$rtnVal .= Image::ExifTool::Charset::Recompose($et, [$2]);
|
190
|
+
if ($skip) {
|
191
|
+
# must skip the specified number of characters
|
192
|
+
# (not simple because RTF control words count as a single character)
|
193
|
+
last unless $val =~ /\G([^\\]|\\([a-zA-Z]+)(-?\d+)? ?|\\'.{2}|\\.){$skip}/g;
|
194
|
+
}
|
190
195
|
}
|
191
196
|
} elsif ($rtfEntity{$1}) {
|
192
197
|
require Image::ExifTool::Charset;
|
@@ -19,7 +19,7 @@ use vars qw($VERSION);
|
|
19
19
|
use Image::ExifTool qw(:DataAccess :Utils);
|
20
20
|
use Image::ExifTool::Exif;
|
21
21
|
|
22
|
-
$VERSION = '1.
|
22
|
+
$VERSION = '1.35';
|
23
23
|
|
24
24
|
sub ProcessRicohText($$$);
|
25
25
|
sub ProcessRicohRMETA($$$);
|
@@ -875,6 +875,7 @@ my %ricohLensIDs = (
|
|
875
875
|
Name => 'SoundFile',
|
876
876
|
Notes => 'audio data recorded in JPEG images by the G700SE',
|
877
877
|
},
|
878
|
+
_barcode => { Name => 'Barcodes', List => 1 },
|
878
879
|
);
|
879
880
|
|
880
881
|
# information stored in Ricoh AVI images (ref PH)
|
@@ -1004,6 +1005,23 @@ sub ProcessRicohRMETA($$$)
|
|
1004
1005
|
# (but it looks like the int16u at $dirStart+6 is the next block number
|
1005
1006
|
# if the data is continued, or 0 for the last block)
|
1006
1007
|
$dirLen < 14 and $et->Warn('Short Ricoh RMETA block', 1), return 0;
|
1008
|
+
if ($$dataPt =~ /^.{20}BARCODE/s) {
|
1009
|
+
my $val = substr($$dataPt, 20);
|
1010
|
+
$val =~ s/\0.*//s;
|
1011
|
+
$val =~ s/^BARCODE\w+,\d{2},//;
|
1012
|
+
my @codes;
|
1013
|
+
for (;;) {
|
1014
|
+
$val =~ s/(\d+),// and length $val >= $1 or last;
|
1015
|
+
push @codes, substr($val, 0, $1);
|
1016
|
+
last unless length $val > $1;
|
1017
|
+
$val = substr($val, $1+1);
|
1018
|
+
}
|
1019
|
+
$et->HandleTag($tagTablePtr, '_barcode', \@codes) if @codes;
|
1020
|
+
return 1;
|
1021
|
+
} elsif ($$dataPt =~ /^.{18}ASCII/s) {
|
1022
|
+
# (ignore barcode tag names for now)
|
1023
|
+
return 1;
|
1024
|
+
}
|
1007
1025
|
my $audioLen = Get16u($dataPt, $dirStart+12);
|
1008
1026
|
$audioLen + 14 > $dirLen and $et->Warn('Truncated Ricoh RMETA audio data', 1), return 0;
|
1009
1027
|
my $buff = substr($$dataPt, $dirStart + 14, $audioLen);
|
@@ -300,6 +300,7 @@ sub ShiftTime($;$$$)
|
|
300
300
|
#
|
301
301
|
SplitTime($val, \@time) or return "Invalid time string ($val)";
|
302
302
|
if (defined $time[0]) {
|
303
|
+
return "Can't shift from year 0000" if $time[0] eq '0000';
|
303
304
|
$mode = defined $time[3] ? 'DateTime' : 'Date';
|
304
305
|
} elsif (defined $time[3]) {
|
305
306
|
$mode = 'Time';
|
@@ -16,7 +16,7 @@ use vars qw($VERSION);
|
|
16
16
|
use Image::ExifTool qw(:DataAccess :Utils);
|
17
17
|
use Image::ExifTool::Sigma;
|
18
18
|
|
19
|
-
$VERSION = '1.
|
19
|
+
$VERSION = '1.27';
|
20
20
|
|
21
21
|
sub ProcessX3FHeader($$$);
|
22
22
|
sub ProcessX3FDirectory($$$);
|
@@ -427,36 +427,43 @@ sub WriteX3F($$)
|
|
427
427
|
$len -= 28;
|
428
428
|
|
429
429
|
# only rewrite full-sized JpgFromRaw (version 2.0, type 2, format 18)
|
430
|
-
if ($buff =~ /^SECi\0\0\x02\0\x02\0\0\0\x12\0\0\0/
|
431
|
-
$$et{ImageWidth} == unpack('x16V', $buff))
|
432
|
-
{
|
430
|
+
if ($buff =~ /^SECi\0\0\x02\0\x02\0\0\0\x12\0\0\0/) {
|
433
431
|
$raf->Read($buff, $len) == $len or return 'Error reading JpgFromRaw';
|
434
|
-
#
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
432
|
+
if ($buff =~ /^\xff\xd8\xff\xe1/) { # does this preview contain EXIF?
|
433
|
+
# use same write directories as JPEG
|
434
|
+
$et->InitWriteDirs('JPEG');
|
435
|
+
# make sure we don't add APP0 JFIF because it would mess up our preview identification
|
436
|
+
delete $$et{ADD_DIRS}{APP0};
|
437
|
+
delete $$et{ADD_DIRS}{JFIF};
|
438
|
+
# rewrite the embedded JPEG in memory
|
439
|
+
my $newData;
|
440
|
+
my %jpegInfo = (
|
441
|
+
Parent => 'X3F',
|
442
|
+
RAF => new File::RandomAccess(\$buff),
|
443
|
+
OutFile => \$newData,
|
444
|
+
);
|
445
|
+
$$et{FILE_TYPE} = 'JPEG';
|
446
|
+
my $success = $et->WriteJPEG(\%jpegInfo);
|
447
|
+
$$et{FILE_TYPE} = 'X3F';
|
448
|
+
SetByteOrder('II');
|
449
|
+
return 'Error writing X3F JpgFromRaw' unless $success and $newData;
|
450
|
+
return -1 if $success < 0;
|
451
|
+
# (this shouldn't happen unless someone tries to delete the EXIF...)
|
452
|
+
return 'EXIF segment must come first in X3F JpgFromRaw' unless $newData =~ /^\xff\xd8\xff\xe1/;
|
453
|
+
# write new data if anything changed, otherwise copy old image
|
454
|
+
my $outPt = $$et{CHANGED} ? \$newData : \$buff;
|
455
|
+
Write($outfile, $$outPt) or return -1;
|
456
|
+
# set $len to the total subsection data length
|
457
|
+
$len = length($$outPt);
|
458
|
+
$didContain = 1;
|
459
|
+
} else {
|
460
|
+
Write($outfile, $buff) or return -1;
|
461
|
+
}
|
455
462
|
} else {
|
456
463
|
# copy original image data
|
457
464
|
Image::ExifTool::CopyBlock($raf, $outfile, $len) or return 'Corrupted X3F image';
|
458
|
-
$len += 28;
|
459
465
|
}
|
466
|
+
$len += 28; # add back header length
|
460
467
|
} else {
|
461
468
|
# copy data for this subsection
|
462
469
|
Image::ExifTool::CopyBlock($raf, $outfile, $len) or return 'Corrupted X3F directory';
|
@@ -516,16 +523,18 @@ sub ProcessX3FDirectory($$$)
|
|
516
523
|
$raf->Read($buff, 28) == 28 or return 'Error reading PreviewImage header';
|
517
524
|
# ignore all image data but JPEG compressed (version 2.0, type 2, format 18)
|
518
525
|
next unless $buff =~ /^SECi\0\0\x02\0\x02\0\0\0\x12\0\0\0/;
|
519
|
-
|
520
|
-
|
526
|
+
$offset += 28;
|
527
|
+
$len -= 28;
|
528
|
+
$raf->Read($buff, $len) == $len or return "Error reading PreviewImage data";
|
529
|
+
# check fore EXIF segment, and extract this image as the JpgFromRaw
|
530
|
+
if ($buff =~ /^\xff\xd8\xff\xe1/) {
|
521
531
|
$$et{IsJpgFromRaw} = 1;
|
522
532
|
$tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
|
523
533
|
delete $$et{IsJpgFromRaw};
|
524
534
|
}
|
525
|
-
|
526
|
-
$len
|
535
|
+
} else {
|
536
|
+
$raf->Read($buff, $len) == $len or return "Error reading $$tagInfo{Name} data";
|
527
537
|
}
|
528
|
-
$raf->Read($buff, $len) == $len or return "Error reading $$tagInfo{Name} data";
|
529
538
|
my $subdir = $$tagInfo{SubDirectory};
|
530
539
|
if ($subdir) {
|
531
540
|
my %dirInfo = ( DataPt => \$buff );
|
@@ -591,8 +600,6 @@ sub ProcessX3F($$)
|
|
591
600
|
$buff .= $buf2;
|
592
601
|
}
|
593
602
|
my ($widPos, $hdrType) = $ver < 4 ? (28, 'Header') : (40, 'Header4');
|
594
|
-
# extract ImageWidth for later
|
595
|
-
$$et{ImageWidth} = Get32u(\$buff, $widPos);
|
596
603
|
# process header information
|
597
604
|
my $tagTablePtr = GetTagTable('Image::ExifTool::SigmaRaw::Main');
|
598
605
|
unless ($outfile) {
|
@@ -34,7 +34,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
34
34
|
use Image::ExifTool::Exif;
|
35
35
|
use Image::ExifTool::Minolta;
|
36
36
|
|
37
|
-
$VERSION = '3.
|
37
|
+
$VERSION = '3.28';
|
38
38
|
|
39
39
|
sub ProcessSRF($$$);
|
40
40
|
sub ProcessSR2($$$);
|
@@ -143,6 +143,7 @@ sub PrintInvLensSpec($;$$);
|
|
143
143
|
32854 => 'Sony E 70-350mm F4.5-6.3 G OSS', #IB/JR
|
144
144
|
32858 => 'Sony FE 35mm F1.8', #JR/IB
|
145
145
|
32859 => 'Sony FE 20mm F1.8 G', #IB/JR
|
146
|
+
32860 => 'Sony FE 12-24mm F2.8 GM', #JR/IB
|
146
147
|
|
147
148
|
# (comment this out so LensID will report the LensModel, which is more useful)
|
148
149
|
# 32952 => 'Metabones Canon EF Speed Booster Ultra', #JR (corresponds to 184, but 'Advanced' mode, LensMount reported as E-mount)
|
@@ -180,6 +181,7 @@ sub PrintInvLensSpec($;$$);
|
|
180
181
|
49460 => 'Tamron 24mm F2.8 Di III OSD M1:2', #JR (Model F051)
|
181
182
|
49461 => 'Tamron 20mm F2.8 Di III OSD M1:2', #JR (Model F050)
|
182
183
|
49462 => 'Tamron 70-180mm F2.8 Di III VXD', #JR (Model A056)
|
184
|
+
49463 => 'Tamron 28-200mm F2.8-5.6 Di III RXD', #JR (Model A071)
|
183
185
|
|
184
186
|
49712 => 'Tokina FiRIN 20mm F2 FE AF', # (firmware Ver.01)
|
185
187
|
49713 => 'Tokina FiRIN 100mm F2.8 FE MACRO', # (firmware Ver.01)
|
@@ -209,6 +211,8 @@ sub PrintInvLensSpec($;$$);
|
|
209
211
|
50515 => 'Sigma 35mm F1.2 DG DN | A', #IB/JR (019)
|
210
212
|
50516 => 'Sigma 14-24mm F2.8 DG DN | A', #IB/JR (019)
|
211
213
|
50517 => 'Sigma 24-70mm F2.8 DG DN | A', #JR (019)
|
214
|
+
50518 => 'Sigma 100-400mm F5-6.3 DG DN OS | C', #JR (020)
|
215
|
+
50521 => 'Sigma 85mm F1.4 DG DN | A', #JR (020)
|
212
216
|
|
213
217
|
50992 => 'Voigtlander SUPER WIDE-HELIAR 15mm F4.5 III', #JR
|
214
218
|
50993 => 'Voigtlander HELIAR-HYPER WIDE 10mm F5.6', #IB
|
@@ -221,18 +225,21 @@ sub PrintInvLensSpec($;$$);
|
|
221
225
|
51000 => 'Voigtlander NOKTON 50mm F1.2 Aspherical', #JR
|
222
226
|
51001 => 'Voigtlander NOKTON 21mm F1.4 Aspherical', #JR
|
223
227
|
51002 => 'Voigtlander APO-LANTHAR 50mm F2 Aspherical', #JR
|
228
|
+
51003 => 'Voigtlander NOKTON 35mm F1.2 Aspherical SE', #JR
|
224
229
|
|
225
230
|
# lenses listed in the Sigma MC-11 list, but not yet seen:
|
226
231
|
# 504xx => 'Sigma 18-200mm F3.5-6.3 DC MACRO OS HSM | C + MC-11', # (014)
|
227
232
|
# 504xx => 'Sigma 30mm F1.4 DC HSM | A + MC-11', # (013)
|
228
233
|
|
234
|
+
# Note: For Samyang lenses, the "FE" designation isn't written to
|
235
|
+
# EXIF:LensModel, so it isn't included in these strings either - JR/PH
|
229
236
|
51504 => 'Samyang AF 50mm F1.4', #IB
|
230
237
|
51505 => 'Samyang AF 14mm F2.8 or Samyang AF 35mm F2.8', #forum3833
|
231
238
|
51505.1 => 'Samyang AF 35mm F2.8', #PH (also 32794)
|
232
239
|
51507 => 'Samyang AF 35mm F1.4', #IB
|
233
240
|
51508 => 'Samyang AF 45mm F1.8',
|
234
241
|
51510 => 'Samyang AF 18mm F2.8', #JR
|
235
|
-
|
242
|
+
51512 => 'Samyang AF 75mm F1.8', #IB/JR
|
236
243
|
);
|
237
244
|
|
238
245
|
# ExposureProgram values (ref PH, mainly decoded from A200)
|
@@ -993,7 +1000,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
993
1000
|
SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010h' },
|
994
1001
|
},{
|
995
1002
|
Name => 'Tag2010i', # ?
|
996
|
-
Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9|9M2)|DSC-(RX10M4|RX100M6|RX100M5A|RX100M7|HX99|RX0M2))\b/',
|
1003
|
+
Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9|9M2)|DSC-(RX10M4|RX100M6|RX100M5A|RX100M7|HX99|RX0M2)|ZV-1)\b/',
|
997
1004
|
SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010i' },
|
998
1005
|
},{
|
999
1006
|
Name => 'Tag_0x2010',
|
@@ -1378,6 +1385,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
1378
1385
|
'1 0' => 'Off',
|
1379
1386
|
'1 1' => 'Standard',
|
1380
1387
|
'1 2' => 'High',
|
1388
|
+
'65535 65535' => 'n/a', # ILCE-7SM3
|
1381
1389
|
},
|
1382
1390
|
},
|
1383
1391
|
0x2029 => { # uncompressed 14-bit RAW file type setting introduced 2015
|
@@ -1386,6 +1394,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
1386
1394
|
PrintConv => {
|
1387
1395
|
0 => 'Compressed RAW',
|
1388
1396
|
1 => 'Uncompressed RAW',
|
1397
|
+
65535 => 'n/a', # seen for ILCE-7SM3 JPEG-only
|
1389
1398
|
},
|
1390
1399
|
},
|
1391
1400
|
# 0x202a - first seen for ILCE-6300: 66 bytes
|
@@ -1484,6 +1493,13 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
1484
1493
|
PrintConv => 'sprintf("%.8d",$val)',
|
1485
1494
|
PrintConvInv => '$val',
|
1486
1495
|
},
|
1496
|
+
# 0x2032 - first seen for ILCE-7SM3, July 2020
|
1497
|
+
# 0x2033 - first seen for ILCE-7SM3, July 2020
|
1498
|
+
# 0x2034 - first seen for ILCE-7SM3, July 2020
|
1499
|
+
# 0x2035 - first seen for ILCE-7SM3, July 2020
|
1500
|
+
# 0x2036 - first seen for ILCE-7SM3, July 2020
|
1501
|
+
# 0x2037 - first seen for ILCE-7SM3, July 2020
|
1502
|
+
# 0x2039 - first seen for ILCE-7SM3, July 2020
|
1487
1503
|
0x3000 => {
|
1488
1504
|
Name => 'ShotInfo',
|
1489
1505
|
SubDirectory => { TagTable => 'Image::ExifTool::Sony::ShotInfo' },
|
@@ -1512,7 +1528,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
1512
1528
|
# from mid-2015: ILCE-7RM2/7SM2/6300 and newer models use different offsets
|
1513
1529
|
{
|
1514
1530
|
Name => 'Tag9050a',
|
1515
|
-
Condition => '$$self{Model} !~ /^(DSC-|Stellar|ILCE-(6100|6300|6400|6500|6600|7M3|7RM2|7RM3|7RM4|7SM2|9|9M2)|ILCA-99M2)/',
|
1531
|
+
Condition => '$$self{Model} !~ /^(DSC-|Stellar|ILCE-(6100|6300|6400|6500|6600|7M3|7RM2|7RM3|7RM4|7SM2|7SM3|9|9M2)|ILCA-99M2|ZV-)/',
|
1516
1532
|
SubDirectory => {
|
1517
1533
|
TagTable => 'Image::ExifTool::Sony::Tag9050a',
|
1518
1534
|
ByteOrder => 'LittleEndian',
|
@@ -1524,6 +1540,13 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
1524
1540
|
TagTable => 'Image::ExifTool::Sony::Tag9050b',
|
1525
1541
|
ByteOrder => 'LittleEndian',
|
1526
1542
|
},
|
1543
|
+
},{
|
1544
|
+
Name => 'Tag9050c',
|
1545
|
+
Condition => '$$self{Model} =~ /^(ILCE-7SM3)/',
|
1546
|
+
SubDirectory => {
|
1547
|
+
TagTable => 'Image::ExifTool::Sony::Tag9050c',
|
1548
|
+
ByteOrder => 'LittleEndian',
|
1549
|
+
},
|
1527
1550
|
},{
|
1528
1551
|
Name => 'Sony_0x9050',
|
1529
1552
|
%unknownCipherData,
|
@@ -1538,7 +1561,8 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
1538
1561
|
# 0x23 (e) for DSC-RX10/HX60V/HX350/HX400V/WX220/WX350, ILCE-7/7R/5000/6000, ILCA-68/77M2
|
1539
1562
|
# 0x24 (e) for ILCA-99M2,ILCE-5100/6300/6500/7M2/7RM2/7S/7SM2/QX1, DSC-HX80/HX90V/QX30/RX0/RX100M3/RX100M4/RX100M5/RX10M2/RX10M3/RX1RM2/WX500
|
1540
1563
|
# 0x26 (e) for ILCE-6100/6400/6600/7M3/7RM3/9, DSC-RX0M2/RX10M4/RX100M5A/RX100M6/HX99
|
1541
|
-
# 0x28 (e) for ILCE-7RM4/9M2, DSC-RX100M7
|
1564
|
+
# 0x28 (e) for ILCE-7RM4/9M2, DSC-RX100M7, ZV-1
|
1565
|
+
# 0x31 (e) for ILCE-7SM3
|
1542
1566
|
# first byte decoded: 40, 204, 202, 27, 58, 62, 48, 215, 28 respectively
|
1543
1567
|
{
|
1544
1568
|
Name => 'Tag9400a',
|
@@ -1677,7 +1701,8 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
1677
1701
|
# 13 0 9 2 2 DSC-QX10/QX100/RX100M2
|
1678
1702
|
# 15 0 35 2 2 ILCA-68/77M2, ILCE-5000/5100/6000/7/7R/7S/7M2/QX1, DSC-HX60V/HX350/HX400V/QX30/RX10/RX100M3/WX220/WX350
|
1679
1703
|
# 16 0 85 2 2 DSC-HX80/HX90V/WX500
|
1680
|
-
# 17 0 232 1 2 DSC-RX0/RX0M2/RX1RM2/RX10M2/RX10M3/RX10M4/RX100M4/RX100M5/RX100M5A/RX100M6/RX100M7/HX99, ILCE-6100/6300/6400/6500/6600/7M3/7RM2/7RM3/7RM4/7SM2/9/9M2, ILCA-99M2
|
1704
|
+
# 17 0 232 1 2 DSC-RX0/RX0M2/RX1RM2/RX10M2/RX10M3/RX10M4/RX100M4/RX100M5/RX100M5A/RX100M6/RX100M7/HX99, ILCE-6100/6300/6400/6500/6600/7M3/7RM2/7RM3/7RM4/7SM2/9/9M2, ILCA-99M2, ZV-1
|
1705
|
+
# 18 0 20 0 164 ILCE-7SM3
|
1681
1706
|
# other values for Panorama images and several other models
|
1682
1707
|
0x9404 => [{
|
1683
1708
|
Name => 'Tag9404a',
|
@@ -1711,7 +1736,8 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
1711
1736
|
# 142 var (0x25 = 37 var enc.) DSC-HX80/HX90V/RX1RM2/RX10M2/RX10M3/RX100M4/WX500, ILCE-6300/7RM2/7SM2
|
1712
1737
|
# 144 var (0xe1 = 225 var enc.) DSC-RX100M5
|
1713
1738
|
# 145 var (0x76 = 118 var enc.) ILCA-99M2, ILCE-6500, DSC-RX0
|
1714
|
-
# 163 var (0x8b = 139 var enc.) ILCE-6100/6400/6600/7M3/7RM3/7RM4/9/9M2, DSC-RX0M2/RX10M4/RX100M5A/RX100M6/RX100M7/HX99
|
1739
|
+
# 163 var (0x8b = 139 var enc.) ILCE-6100/6400/6600/7M3/7RM3/7RM4/9/9M2, DSC-RX0M2/RX10M4/RX100M5A/RX100M6/RX100M7/HX99, ZV-1
|
1740
|
+
# July 2020: ILCE-7SM3 doesn't write this tag anymore, but writes 0x9416
|
1715
1741
|
0x9405 => [{
|
1716
1742
|
Name => 'Tag9405a',
|
1717
1743
|
# first byte must be 0x1b or 0x40 or 0x7d
|
@@ -1798,6 +1824,10 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
1798
1824
|
%unknownCipherData,
|
1799
1825
|
# 0x02 - int32u?: 1,3,5,7,9 (A77)
|
1800
1826
|
},
|
1827
|
+
0x9416 => { # replaces 0x9405 for the Sony ILCE-7SM3, from July 2020
|
1828
|
+
Name => 'Sony_0x9416',
|
1829
|
+
SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9416' },
|
1830
|
+
},
|
1801
1831
|
0xb000 => { #8
|
1802
1832
|
Name => 'FileFormat',
|
1803
1833
|
Writable => 'int8u',
|
@@ -1820,6 +1850,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
1820
1850
|
'3 3 2 0' => 'ARW 2.3.2', #JR (DSC-RX1RM2,ILCE-7SM2 - support for uncompressed 14-bit RAW)
|
1821
1851
|
'3 3 3 0' => 'ARW 2.3.3', #JR (ILCE-9)
|
1822
1852
|
'3 3 5 0' => 'ARW 2.3.5', #JR (DSC-HX99)
|
1853
|
+
'4 0 0 0' => 'ARW 4.0', # (ILCE-7SM3)
|
1823
1854
|
# what about cRAW images?
|
1824
1855
|
},
|
1825
1856
|
},
|
@@ -1913,6 +1944,8 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
1913
1944
|
376 => 'ILCE-9M2', #JR
|
1914
1945
|
378 => 'ILCE-6600', #IB/JR
|
1915
1946
|
379 => 'ILCE-6100', #IB/JR
|
1947
|
+
380 => 'ZV-1', #JR
|
1948
|
+
383 => 'ILCE-7SM3',
|
1916
1949
|
},
|
1917
1950
|
},
|
1918
1951
|
0xb020 => { #2
|
@@ -6049,8 +6082,11 @@ my %isoSetting2010 = (
|
|
6049
6082
|
33 => 16000,
|
6050
6083
|
34 => 20000,
|
6051
6084
|
35 => 25600,
|
6085
|
+
36 => 32000,
|
6086
|
+
37 => 40000,
|
6052
6087
|
38 => 51200,
|
6053
6088
|
39 => 64000,
|
6089
|
+
40 => 80000,
|
6054
6090
|
41 => 102400,
|
6055
6091
|
42 => 128000,
|
6056
6092
|
43 => 160000,
|
@@ -7725,6 +7761,107 @@ my %isoSetting2010 = (
|
|
7725
7761
|
},
|
7726
7762
|
);
|
7727
7763
|
|
7764
|
+
%Image::ExifTool::Sony::Tag9050c = ( #JR
|
7765
|
+
PROCESS_PROC => \&ProcessEnciphered,
|
7766
|
+
WRITE_PROC => \&WriteEnciphered,
|
7767
|
+
CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
|
7768
|
+
FORMAT => 'int8u',
|
7769
|
+
NOTES => q{
|
7770
|
+
Valid from July 2020 for ILCE-7SM3.
|
7771
|
+
},
|
7772
|
+
WRITABLE => 1,
|
7773
|
+
FIRST_ENTRY => 0,
|
7774
|
+
GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
|
7775
|
+
DATAMEMBER => [ 0x0039 ],
|
7776
|
+
0x0026 => {
|
7777
|
+
Name => 'Shutter',
|
7778
|
+
Format => 'int16u[3]',
|
7779
|
+
PrintConv => {
|
7780
|
+
'0 0 0' => 'Silent / Electronic (0 0 0)',
|
7781
|
+
OTHER => sub {
|
7782
|
+
my ($val, $inv) = @_;
|
7783
|
+
return $inv ? ($val=~/\((.*?)\)/ ? $1 : undef) : "Mechanical ($val)";
|
7784
|
+
},
|
7785
|
+
},
|
7786
|
+
},
|
7787
|
+
0x0039 => {
|
7788
|
+
Name => 'FlashStatus',
|
7789
|
+
RawConv => '$$self{FlashFired} = $val',
|
7790
|
+
PrintConv => {
|
7791
|
+
0 => 'No Flash present',
|
7792
|
+
2 => 'Flash Inhibited', # seen for ILCE-7/7R continuous, panorama, HDR mode
|
7793
|
+
64 => 'Built-in Flash present',
|
7794
|
+
65 => 'Built-in Flash Fired',
|
7795
|
+
66 => 'Built-in Flash Inhibited', # seen for panorama, HDR, burst mode
|
7796
|
+
128 => 'External Flash present', # seen for NEX-5N/5T
|
7797
|
+
129 => 'External Flash Fired', # seen for SLT-A99V, ILCE-7R, NEX-5N/5R
|
7798
|
+
},
|
7799
|
+
},
|
7800
|
+
0x003a => {
|
7801
|
+
Name => 'ShutterCount',
|
7802
|
+
# or "ShutterCount"? : number of shutter actuations, does not increase during Silent Shooting,
|
7803
|
+
# at least for ILCE-7RM2
|
7804
|
+
Format => 'int32u',
|
7805
|
+
Notes => 'total number of image exposures made by the camera',
|
7806
|
+
RawConv => '$val & 0x00ffffff',
|
7807
|
+
PrintConv => 'sprintf("%6d",$val)',
|
7808
|
+
},
|
7809
|
+
0x0046 => { # appr. same value as Exif ExposureTime, but longer in HDR-modes
|
7810
|
+
Name => 'SonyExposureTime',
|
7811
|
+
Format => 'int16u',
|
7812
|
+
ValueConv => '$val ? 2 ** (16 - $val/256) : 0',
|
7813
|
+
ValueConvInv => '$val ? int((16 - log($val) / log(2)) * 256 + 0.5) : 0',
|
7814
|
+
PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
|
7815
|
+
PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
|
7816
|
+
},
|
7817
|
+
0x0048 => {
|
7818
|
+
Name => 'SonyFNumber',
|
7819
|
+
Format => 'int16u',
|
7820
|
+
ValueConv => '2 ** (($val/256 - 16) / 2)',
|
7821
|
+
ValueConvInv => '(log($val)*2/log(2)+16)*256',
|
7822
|
+
PrintConv => 'sprintf("%.1f",$val)',
|
7823
|
+
PrintConvInv => '$val',
|
7824
|
+
},
|
7825
|
+
0x004b => {
|
7826
|
+
Name => 'ReleaseMode2',
|
7827
|
+
%releaseMode2,
|
7828
|
+
},
|
7829
|
+
0x0050 => {
|
7830
|
+
Name => 'ShutterCount2',
|
7831
|
+
Condition => '(($$self{FlashFired} & 0x01) != 1) and ($$self{Model} =~ /^(ILCE-7SM3)/)',
|
7832
|
+
Format => 'int32u',
|
7833
|
+
RawConv => '$val & 0x00ffffff',
|
7834
|
+
},
|
7835
|
+
0x0066 => { # appr. same value as Exif ExposureTime, but not valid in HDR-modes
|
7836
|
+
Name => 'SonyExposureTime',
|
7837
|
+
Condition => '$$self{Model} =~ /^(ILCE-7SM3)/',
|
7838
|
+
Format => 'int16u',
|
7839
|
+
ValueConv => '$val ? 2 ** (16 - $val/256) : 0',
|
7840
|
+
ValueConvInv => '$val ? int((16 - log($val) / log(2)) * 256 + 0.5) : 0',
|
7841
|
+
PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
|
7842
|
+
PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
|
7843
|
+
},
|
7844
|
+
0x0068 => { # appr. same value as Exif ExposureTime, but not valid in HDR-modes
|
7845
|
+
Name => 'SonyFNumber',
|
7846
|
+
Condition => '$$self{Model} =~ /^(ILCE-7SM3)/',
|
7847
|
+
Format => 'int16u',
|
7848
|
+
ValueConv => '2 ** (($val/256 - 16) / 2)',
|
7849
|
+
ValueConvInv => '(log($val)*2/log(2)+16)*256',
|
7850
|
+
PrintConv => 'sprintf("%.1f",$val)',
|
7851
|
+
PrintConvInv => '$val',
|
7852
|
+
},
|
7853
|
+
0x006b => {
|
7854
|
+
Name => 'ReleaseMode2',
|
7855
|
+
Condition => '$$self{Model} =~ /^(ILCE-7SM3)/',
|
7856
|
+
%releaseMode2,
|
7857
|
+
},
|
7858
|
+
0x0088 => {
|
7859
|
+
Name => 'InternalSerialNumber', #(NC)
|
7860
|
+
Format => 'int8u[6]',
|
7861
|
+
PrintConv => 'unpack "H*", pack "C*", split " ", $val',
|
7862
|
+
},
|
7863
|
+
);
|
7864
|
+
|
7728
7865
|
%Image::ExifTool::Sony::Tag9400a = ( #JR
|
7729
7866
|
PROCESS_PROC => \&ProcessEnciphered,
|
7730
7867
|
WRITE_PROC => \&WriteEnciphered,
|
@@ -7901,7 +8038,7 @@ my %isoSetting2010 = (
|
|
7901
8038
|
GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
|
7902
8039
|
0x0009 => { %releaseMode2 },
|
7903
8040
|
0x000a => [{
|
7904
|
-
Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9|9M2)|DSC-(RX10M4|RX100M6|RX100M7|RX100M5A|HX99|RX0M2))\b/',
|
8041
|
+
Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9|9M2)|DSC-(RX10M4|RX100M6|RX100M7|RX100M5A|HX99|RX0M2)|ZV-1)\b/',
|
7905
8042
|
Name => 'ShotNumberSincePowerUp',
|
7906
8043
|
Format => 'int8u',
|
7907
8044
|
},{
|
@@ -7981,11 +8118,12 @@ my %isoSetting2010 = (
|
|
7981
8118
|
FIRST_ENTRY => 0,
|
7982
8119
|
GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
|
7983
8120
|
DATAMEMBER => [ 0 ],
|
7984
|
-
IS_SUBDIR => [ 0x0498, 0x04a2, 0x059d, 0x0634, 0x0636, 0x064c, 0x0653, 0x0678, 0x06b8, 0x06de, 0x06e7 ],
|
8121
|
+
IS_SUBDIR => [ 0x0498, 0x04a1, 0x04a2, 0x059d, 0x0634, 0x0636, 0x064c, 0x0653, 0x0678, 0x06b8, 0x06de, 0x06e7 ],
|
7985
8122
|
0x0000 => { Name => 'Ver9401', Hidden => 1, RawConv => '$$self{Ver9401} = $val; $$self{OPTIONS}{Unknown}<2 ? undef : $val' },
|
7986
8123
|
|
7987
8124
|
0x0498 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 148', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
|
7988
|
-
|
8125
|
+
0x04a1 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 160', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
|
8126
|
+
0x04a2 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(152|154|155)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
|
7989
8127
|
0x059d => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(144|146)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
|
7990
8128
|
0x0634 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 68', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
|
7991
8129
|
0x0636 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(73|74)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
|
@@ -8056,6 +8194,7 @@ my %isoSetting2010 = (
|
|
8056
8194
|
14 => 'Tracking',
|
8057
8195
|
15 => 'Face Tracking',
|
8058
8196
|
20 => 'Animal Eye Tracking',
|
8197
|
+
# 21 => '???', # (ILCE-7SM3)
|
8059
8198
|
255 => 'Manual',
|
8060
8199
|
},
|
8061
8200
|
},
|
@@ -8327,7 +8466,7 @@ my %isoSetting2010 = (
|
|
8327
8466
|
# also often deviating results for Sony FE 90mm F2.8 Macro G OSS ...
|
8328
8467
|
Name => 'SonyFNumber',
|
8329
8468
|
Format => 'int16u',
|
8330
|
-
Condition => '$$self{Model} !~ /^DSC
|
8469
|
+
Condition => '$$self{Model} !~ /^(DSC-|ZV-)/',
|
8331
8470
|
ValueConv => '2 ** (($val/256 - 16) / 2)',
|
8332
8471
|
ValueConvInv => '(log($val)*2/log(2)+16)*256',
|
8333
8472
|
PrintConv => 'sprintf("%.1f",$val)',
|
@@ -8443,7 +8582,7 @@ my %isoSetting2010 = (
|
|
8443
8582
|
},
|
8444
8583
|
0x0342 => {
|
8445
8584
|
Name => 'LensZoomPosition',
|
8446
|
-
Condition => '$$self{Model} !~ /^(ILCA-|ILCE-(7RM2|7M3|7RM3|7RM4|7SM2|6100|6300|6400|6500|6600|9|9M2)|DSC-(HX80|HX90V|HX99|RX0|RX10M2|RX10M3|RX10M4|RX100M4|RX100M5|RX100M5A|RX100M6|RX100M7|WX500))/',
|
8585
|
+
Condition => '$$self{Model} !~ /^(ILCA-|ILCE-(7RM2|7M3|7RM3|7RM4|7SM2|6100|6300|6400|6500|6600|9|9M2)|DSC-(HX80|HX90V|HX99|RX0|RX10M2|RX10M3|RX10M4|RX100M4|RX100M5|RX100M5A|RX100M6|RX100M7|WX500)|ZV-)/',
|
8447
8586
|
Format => 'int16u',
|
8448
8587
|
PrintConv => 'sprintf("%.0f%%",$val/10.24)',
|
8449
8588
|
PrintConvInv => '$val=~s/ ?%$//; $val * 10.24',
|
@@ -9243,6 +9382,145 @@ my %isoSetting2010 = (
|
|
9243
9382
|
0xbc => { Name => 'AFStatus_94_E6_Center_F2-8', %Image::ExifTool::Minolta::afStatusInfo },
|
9244
9383
|
);
|
9245
9384
|
|
9385
|
+
# tag 0x9416 decoding (ref JR)
|
9386
|
+
%Image::ExifTool::Sony::Tag9416 = (
|
9387
|
+
PROCESS_PROC => \&ProcessEnciphered,
|
9388
|
+
WRITE_PROC => \&WriteEnciphered,
|
9389
|
+
CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
|
9390
|
+
FORMAT => 'int8u',
|
9391
|
+
FIRST_ENTRY => 0,
|
9392
|
+
GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
|
9393
|
+
0x0000 => { Name => 'Tag9416_0000', PrintConv => 'sprintf("%3d",$val)', RawConv => '$$self{TagVersion} = $val' },
|
9394
|
+
0x0004 => {
|
9395
|
+
Name => 'SonyISO',
|
9396
|
+
Format => 'int16u',
|
9397
|
+
ValueConv => '100 * 2**(16 - $val/256)',
|
9398
|
+
ValueConvInv => '256 * (16 - log($val/100)/log(2))',
|
9399
|
+
PrintConv => 'sprintf("%.0f",$val)',
|
9400
|
+
PrintConvInv => '$val',
|
9401
|
+
},
|
9402
|
+
0x0006 => { %gain2010 },
|
9403
|
+
0x000a => { # appr. same value as Exif ExposureTime, but shorter in HDR-modes
|
9404
|
+
Name => 'SonyExposureTime2',
|
9405
|
+
Format => 'int16u',
|
9406
|
+
ValueConv => '$val ? 2 ** (16 - $val/256) : 0',
|
9407
|
+
ValueConvInv => '$val ? int((16 - log($val) / log(2)) * 256 + 0.5) : 0',
|
9408
|
+
PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
|
9409
|
+
PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
|
9410
|
+
},
|
9411
|
+
0x000c => {
|
9412
|
+
Name => 'ExposureTime',
|
9413
|
+
Format => 'rational32u',
|
9414
|
+
PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"', # (Bulb NC)
|
9415
|
+
PrintConvInv => 'lc($val) eq "bulb" ? 0 : $val',
|
9416
|
+
},
|
9417
|
+
0x0010 => { # but sometimes deviating results
|
9418
|
+
Name => 'SonyFNumber2',
|
9419
|
+
Format => 'int16u',
|
9420
|
+
ValueConv => '2 ** (($val/256 - 16) / 2)',
|
9421
|
+
ValueConvInv => '(log($val)*2/log(2)+16)*256',
|
9422
|
+
PrintConv => 'sprintf("%.1f",$val)',
|
9423
|
+
PrintConvInv => '$val',
|
9424
|
+
},
|
9425
|
+
0x0012 => {
|
9426
|
+
Name => 'SonyMaxApertureValue', # (at current focal length)
|
9427
|
+
Format => 'int16u',
|
9428
|
+
ValueConv => '2 ** (($val/256 - 16) / 2)',
|
9429
|
+
ValueConvInv => '(log($val)*2/log(2)+16)*256',
|
9430
|
+
PrintConv => 'sprintf("%.1f",$val)',
|
9431
|
+
PrintConvInv => '$val',
|
9432
|
+
},
|
9433
|
+
0x001d => { %sequenceImageNumber },
|
9434
|
+
0x0035 => {
|
9435
|
+
Name => 'ExposureProgram',
|
9436
|
+
Priority => 0,
|
9437
|
+
SeparateTable => 'ExposureProgram3',
|
9438
|
+
PrintConv => \%sonyExposureProgram3,
|
9439
|
+
},
|
9440
|
+
0x0048 => {
|
9441
|
+
Name => 'LensMount',
|
9442
|
+
Condition => '$$self{Model} !~ /^(DSC-)/',
|
9443
|
+
PrintConv => {
|
9444
|
+
0 => 'Unknown',
|
9445
|
+
1 => 'A-mount',
|
9446
|
+
2 => 'E-mount',
|
9447
|
+
3 => 'A-mount (3)',
|
9448
|
+
},
|
9449
|
+
},
|
9450
|
+
0x0049 => {
|
9451
|
+
Name => 'LensFormat',
|
9452
|
+
Condition => '$$self{Model} !~ /^(DSC-)/',
|
9453
|
+
PrintConv => {
|
9454
|
+
0 => 'Unknown',
|
9455
|
+
1 => 'APS-C',
|
9456
|
+
2 => 'Full-frame',
|
9457
|
+
},
|
9458
|
+
},
|
9459
|
+
0x004a => {
|
9460
|
+
Name => 'LensMount',
|
9461
|
+
DataMember => 'LensMount',
|
9462
|
+
RawConv => '$$self{LensMount} = $val; $$self{Model} =~ /^(DSC-)/ ? undef : $val',
|
9463
|
+
PrintConv => {
|
9464
|
+
0 => 'Unknown',
|
9465
|
+
1 => 'A-mount',
|
9466
|
+
2 => 'E-mount',
|
9467
|
+
},
|
9468
|
+
},
|
9469
|
+
0x004b => {
|
9470
|
+
Name => 'LensType2',
|
9471
|
+
Condition => '$$self{LensMount} == 2',
|
9472
|
+
Format => 'int16u',
|
9473
|
+
SeparateTable => 'LensType2',
|
9474
|
+
PrintConv => \%sonyLensTypes2,
|
9475
|
+
},
|
9476
|
+
0x004d => {
|
9477
|
+
Name => 'LensType',
|
9478
|
+
Condition => '$$self{LensMount} == 1',
|
9479
|
+
Priority => 0, #PH (just to be safe)
|
9480
|
+
Format => 'int16u', #PH
|
9481
|
+
SeparateTable => 1,
|
9482
|
+
ValueConvInv => '($val & 0xff00) == 0x8000 ? 0 : int($val)',
|
9483
|
+
PrintConv => \%sonyLensTypes,
|
9484
|
+
},
|
9485
|
+
0x004f => {
|
9486
|
+
Name => 'DistortionCorrParams',
|
9487
|
+
Format => 'int16s[16]',
|
9488
|
+
},
|
9489
|
+
0x0071 => {
|
9490
|
+
Name => 'FocalLength',
|
9491
|
+
Format => 'int16u',
|
9492
|
+
ValueConv => '$val / 10',
|
9493
|
+
ValueConvInv => '$val * 10',
|
9494
|
+
PrintConv => 'sprintf("%.1f mm",$val)',
|
9495
|
+
PrintConvInv => '$val =~ s/ ?mm//; $val',
|
9496
|
+
},
|
9497
|
+
0x0073 => {
|
9498
|
+
Name => 'MinFocalLength',
|
9499
|
+
Format => 'int16u',
|
9500
|
+
ValueConv => '$val / 10',
|
9501
|
+
ValueConvInv => '$val * 10',
|
9502
|
+
PrintConv => 'sprintf("%.1f mm",$val)',
|
9503
|
+
PrintConvInv => '$val =~ s/ ?mm//; $val',
|
9504
|
+
},
|
9505
|
+
0x0075 => { # may give 0 for fixed focal length lenses
|
9506
|
+
Name => 'MaxFocalLength',
|
9507
|
+
Format => 'int16u',
|
9508
|
+
RawConv => '$val || undef',
|
9509
|
+
ValueConv => '$val / 10',
|
9510
|
+
ValueConvInv => '$val * 10',
|
9511
|
+
PrintConv => 'sprintf("%.1f mm",$val)',
|
9512
|
+
PrintConvInv => '$val =~ s/ ?mm//; $val',
|
9513
|
+
},
|
9514
|
+
0x088f => {
|
9515
|
+
Name => 'VignettingCorrParams',
|
9516
|
+
Format => 'int16s[16]',
|
9517
|
+
},
|
9518
|
+
0x0914 => {
|
9519
|
+
Name => 'ChromaticAberrationCorrParams',
|
9520
|
+
Format => 'int16s[32]',
|
9521
|
+
},
|
9522
|
+
);
|
9523
|
+
|
9246
9524
|
%Image::ExifTool::Sony::FaceInfo1 = (
|
9247
9525
|
%binaryDataAttrs,
|
9248
9526
|
GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
|
@@ -9740,12 +10018,88 @@ my %isoSetting2010 = (
|
|
9740
10018
|
# 0x8100 - 16 bytes starting with 0x060e2b340401
|
9741
10019
|
0x8100 => { Name => 'Sony_rtmd_0x8100', Format => 'int8u', %hidUnk },
|
9742
10020
|
0x8101 => { Name => 'Sony_rtmd_0x8101', Format => 'int8u', %hidUnk }, # seen: 0,1
|
10021
|
+
0x8106 => { Name => 'Sony_rtmd_0x8106', Format => 'int32u', %hidUnk }, # seen: "25 1"
|
9743
10022
|
0x8109 => { Name => 'Sony_rtmd_0x8109', Format => 'int32u', %hidUnk }, # seen: "1 50"
|
9744
10023
|
0x810a => { Name => 'Sony_rtmd_0x810a', Format => 'int16u', %hidUnk }, # seen: 0
|
9745
10024
|
0x810b => { Name => 'Sony_rtmd_0x810b', Format => 'int16u', %hidUnk }, # seen: 100
|
9746
10025
|
0x810c => { Name => 'Sony_rtmd_0x810c', Format => 'int16u', %hidUnk }, # seen: 100
|
9747
10026
|
0x810d => { Name => 'Sony_rtmd_0x810d', Format => 'int8u', %hidUnk }, # seen: 1
|
10027
|
+
0x8115 => { Name => 'Sony_rtmd_0x8115', Format => 'int16u', %hidUnk }, # seen: 100
|
9748
10028
|
# 0x8300 - container for other tags in this format
|
10029
|
+
0x8500 => {
|
10030
|
+
Name => 'GPSVersionID',
|
10031
|
+
Groups => { 2 => 'Location' },
|
10032
|
+
Format => 'int8u',
|
10033
|
+
PrintConv => '$val =~ tr/ /./; $val',
|
10034
|
+
},
|
10035
|
+
0x8501 => {
|
10036
|
+
Name => 'GPSLatitudeRef',
|
10037
|
+
Groups => { 2 => 'Location' },
|
10038
|
+
Format => 'string',
|
10039
|
+
PrintConv => {
|
10040
|
+
N => 'North',
|
10041
|
+
S => 'South',
|
10042
|
+
},
|
10043
|
+
},
|
10044
|
+
0x8502 => {
|
10045
|
+
Name => 'GPSLatitude',
|
10046
|
+
Groups => { 2 => 'Location' },
|
10047
|
+
Format => 'rational64u',
|
10048
|
+
ValueConv => 'require Image::ExifTool::GPS;Image::ExifTool::GPS::ToDegrees($val)',
|
10049
|
+
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
|
10050
|
+
},
|
10051
|
+
0x8503 => {
|
10052
|
+
Name => 'GPSLongitudeRef',
|
10053
|
+
Groups => { 2 => 'Location' },
|
10054
|
+
Format => 'string',
|
10055
|
+
PrintConv => {
|
10056
|
+
E => 'East',
|
10057
|
+
W => 'West',
|
10058
|
+
},
|
10059
|
+
},
|
10060
|
+
0x8504 => {
|
10061
|
+
Name => 'GPSLongitude',
|
10062
|
+
Groups => { 2 => 'Location' },
|
10063
|
+
Format => 'rational64u',
|
10064
|
+
ValueConv => 'require Image::ExifTool::GPS;Image::ExifTool::GPS::ToDegrees($val)',
|
10065
|
+
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
|
10066
|
+
},
|
10067
|
+
0x8507 => {
|
10068
|
+
Name => 'GPSTimeStamp',
|
10069
|
+
Groups => { 2 => 'Time' },
|
10070
|
+
Format => 'rational64u',
|
10071
|
+
ValueConv => 'require Image::ExifTool::GPS;Image::ExifTool::GPS::ConvertTimeStamp($val)',
|
10072
|
+
PrintConv => 'Image::ExifTool::GPS::PrintTimeStamp($val)',
|
10073
|
+
},
|
10074
|
+
0x8509 => {
|
10075
|
+
Name => 'GPSStatus',
|
10076
|
+
Groups => { 2 => 'Location' },
|
10077
|
+
Format => 'string',
|
10078
|
+
PrintConv => {
|
10079
|
+
A => 'Measurement Active',
|
10080
|
+
V => 'Measurement Void',
|
10081
|
+
},
|
10082
|
+
},
|
10083
|
+
0x850a => {
|
10084
|
+
Name => 'GPSMeasureMode',
|
10085
|
+
Groups => { 2 => 'Location' },
|
10086
|
+
Format => 'string',
|
10087
|
+
PrintConv => {
|
10088
|
+
2 => '2-Dimensional Measurement',
|
10089
|
+
3 => '3-Dimensional Measurement',
|
10090
|
+
},
|
10091
|
+
},
|
10092
|
+
0x8512 => {
|
10093
|
+
Name => 'GPSMapDatum',
|
10094
|
+
Groups => { 2 => 'Location' },
|
10095
|
+
Format => 'string',
|
10096
|
+
},
|
10097
|
+
0x851d => {
|
10098
|
+
Name => 'GPSDateStamp',
|
10099
|
+
Groups => { 2 => 'Time' },
|
10100
|
+
Format => 'string',
|
10101
|
+
ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
|
10102
|
+
},
|
9749
10103
|
0xe000 => { Name => 'Sony_rtmd_0xe000', Format => 'int8u', %hidUnk }, # (16 bytes)
|
9750
10104
|
0xe300 => { Name => 'Sony_rtmd_0xe300', Format => 'int8u', %hidUnk }, # seen: 0,1
|
9751
10105
|
0xe301 => { Name => 'Sony_rtmd_0xe301', Format => 'int32u', %hidUnk }, # seen: 100
|
@@ -9758,6 +10112,8 @@ my %isoSetting2010 = (
|
|
9758
10112
|
ValueConv => 'my @a=unpack("x1H4H2H2H2H2H2",$val); "$a[0]:$a[1]:$a[2] $a[3]:$a[4]:$a[5]"',
|
9759
10113
|
PrintConv => '$self->ConvertDateTime($val)',
|
9760
10114
|
},
|
10115
|
+
# f010 - 2048 bytes
|
10116
|
+
# f020 - 543 bytes
|
9761
10117
|
);
|
9762
10118
|
|
9763
10119
|
# Composite Sony tags
|
@@ -9792,6 +10148,17 @@ my %isoSetting2010 = (
|
|
9792
10148
|
},
|
9793
10149
|
PrintConv => '$val eq "inf" ? $val : sprintf("%.2f m",$val)',
|
9794
10150
|
},
|
10151
|
+
GPSDateTime => {
|
10152
|
+
Description => 'GPS Date/Time',
|
10153
|
+
Groups => { 2 => 'Time' },
|
10154
|
+
SubDoc => 1, # generate for all sub-documents
|
10155
|
+
Require => {
|
10156
|
+
0 => 'Sony:GPSDateStamp',
|
10157
|
+
1 => 'Sony:GPSTimeStamp',
|
10158
|
+
},
|
10159
|
+
ValueConv => '"$val[0] $val[1]Z"',
|
10160
|
+
PrintConv => '$self->ConvertDateTime($val)',
|
10161
|
+
},
|
9795
10162
|
);
|
9796
10163
|
|
9797
10164
|
# add our composite tags
|