exiftool_vendored 12.42.0 → 12.52.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 +226 -6
- data/bin/MANIFEST +14 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +45 -44
- data/bin/config_files/acdsee.config +2 -1
- data/bin/config_files/frameCount.config +56 -0
- data/bin/config_files/tiff_version.config +1 -1
- data/bin/exiftool +116 -97
- data/bin/fmt_files/gpx.fmt +3 -0
- data/bin/fmt_files/gpx_wpt.fmt +3 -0
- data/bin/lib/Image/ExifTool/Apple.pm +16 -3
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +23 -12
- data/bin/lib/Image/ExifTool/Canon.pm +66 -37
- data/bin/lib/Image/ExifTool/CanonRaw.pm +8 -1
- data/bin/lib/Image/ExifTool/CanonVRD.pm +7 -8
- data/bin/lib/Image/ExifTool/Casio.pm +3 -3
- data/bin/lib/Image/ExifTool/DJI.pm +2 -1
- data/bin/lib/Image/ExifTool/DarwinCore.pm +13 -1
- data/bin/lib/Image/ExifTool/EXE.pm +9 -1
- data/bin/lib/Image/ExifTool/Exif.pm +17 -12
- data/bin/lib/Image/ExifTool/FLAC.pm +17 -3
- data/bin/lib/Image/ExifTool/FLIR.pm +9 -7
- data/bin/lib/Image/ExifTool/FlashPix.pm +26 -3
- data/bin/lib/Image/ExifTool/FujiFilm.pm +51 -4
- data/bin/lib/Image/ExifTool/GPS.pm +31 -5
- data/bin/lib/Image/ExifTool/Geotag.pm +36 -8
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +3 -2
- data/bin/lib/Image/ExifTool/ICO.pm +143 -0
- data/bin/lib/Image/ExifTool/ID3.pm +6 -6
- data/bin/lib/Image/ExifTool/IPTC.pm +5 -1
- data/bin/lib/Image/ExifTool/JPEG.pm +1 -0
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +24 -3
- data/bin/lib/Image/ExifTool/LNK.pm +5 -2
- data/bin/lib/Image/ExifTool/Lang/de.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/fr.pm +6015 -759
- data/bin/lib/Image/ExifTool/Lang/sk.pm +1927 -0
- data/bin/lib/Image/ExifTool/M2TS.pm +98 -8
- data/bin/lib/Image/ExifTool/MIE.pm +9 -3
- data/bin/lib/Image/ExifTool/MISB.pm +494 -0
- data/bin/lib/Image/ExifTool/MakerNotes.pm +3 -1
- data/bin/lib/Image/ExifTool/Matroska.pm +272 -48
- data/bin/lib/Image/ExifTool/Motorola.pm +8 -2
- data/bin/lib/Image/ExifTool/Nikon.pm +746 -382
- data/bin/lib/Image/ExifTool/NikonCustom.pm +139 -106
- data/bin/lib/Image/ExifTool/NikonSettings.pm +5 -3
- data/bin/lib/Image/ExifTool/Olympus.pm +6 -4
- data/bin/lib/Image/ExifTool/PNG.pm +8 -1
- data/bin/lib/Image/ExifTool/Panasonic.pm +21 -4
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +25 -5
- data/bin/lib/Image/ExifTool/Parrot.pm +96 -2
- data/bin/lib/Image/ExifTool/Pentax.pm +7 -2
- data/bin/lib/Image/ExifTool/Photoshop.pm +29 -3
- data/bin/lib/Image/ExifTool/QuickTime.pm +166 -13
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +161 -22
- data/bin/lib/Image/ExifTool/README +15 -4
- data/bin/lib/Image/ExifTool/RIFF.pm +106 -9
- data/bin/lib/Image/ExifTool/Samsung.pm +2 -2
- data/bin/lib/Image/ExifTool/Sigma.pm +27 -1
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +37 -13
- data/bin/lib/Image/ExifTool/Sony.pm +75 -47
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +13 -6
- data/bin/lib/Image/ExifTool/TagLookup.pm +4791 -4519
- data/bin/lib/Image/ExifTool/TagNames.pod +2056 -1446
- data/bin/lib/Image/ExifTool/Text.pm +3 -4
- data/bin/lib/Image/ExifTool/Torrent.pm +2 -3
- data/bin/lib/Image/ExifTool/Validate.pm +3 -3
- data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +7 -0
- data/bin/lib/Image/ExifTool/WriteExif.pl +100 -23
- data/bin/lib/Image/ExifTool/WriteIPTC.pl +2 -6
- data/bin/lib/Image/ExifTool/WritePhotoshop.pl +5 -5
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +12 -7
- data/bin/lib/Image/ExifTool/WriteRIFF.pl +359 -0
- data/bin/lib/Image/ExifTool/WriteXMP.pl +15 -1
- data/bin/lib/Image/ExifTool/Writer.pl +46 -18
- data/bin/lib/Image/ExifTool/XMP.pm +78 -59
- data/bin/lib/Image/ExifTool/XMP2.pl +19 -4
- data/bin/lib/Image/ExifTool/ZIP.pm +19 -7
- data/bin/lib/Image/ExifTool.pm +146 -38
- data/bin/lib/Image/ExifTool.pod +83 -69
- data/bin/perl-Image-ExifTool.spec +43 -43
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +10 -4
@@ -27,15 +27,16 @@
|
|
27
27
|
package Image::ExifTool::RIFF;
|
28
28
|
|
29
29
|
use strict;
|
30
|
-
use vars qw($VERSION);
|
30
|
+
use vars qw($VERSION $AUTOLOAD);
|
31
31
|
use Image::ExifTool qw(:DataAccess :Utils);
|
32
32
|
|
33
|
-
$VERSION = '1.
|
33
|
+
$VERSION = '1.61';
|
34
34
|
|
35
35
|
sub ConvertTimecode($);
|
36
36
|
sub ProcessSGLT($$$);
|
37
37
|
sub ProcessSLLT($$$);
|
38
38
|
sub ProcessLucas($$$);
|
39
|
+
sub WriteRIFF($$);
|
39
40
|
|
40
41
|
# recognized RIFF variants
|
41
42
|
my %riffType = (
|
@@ -340,6 +341,9 @@ my %code2charset = (
|
|
340
341
|
Large AVI videos may be a concatenation of two or more RIFF chunks. For
|
341
342
|
these files, information is extracted from subsequent RIFF chunks as
|
342
343
|
sub-documents, but the Duration is calculated for the full video.
|
344
|
+
|
345
|
+
ExifTool currently has the ability to write EXIF, XMP and ICC_Profile
|
346
|
+
metadata to WEBP images, but can't yet write to other RIFF-based formats.
|
343
347
|
},
|
344
348
|
# (not 100% sure that the concatenation technique mentioned above is valid - PH)
|
345
349
|
'fmt ' => {
|
@@ -544,7 +548,7 @@ my %code2charset = (
|
|
544
548
|
},
|
545
549
|
},{ # (WebP) - have also seen with "Exif\0\0" header - PH
|
546
550
|
Name => 'EXIF',
|
547
|
-
Condition => '$$valPt =~ /^Exif\0\0(II\x2a\0|MM\0\x2a)/',
|
551
|
+
Condition => '$$valPt =~ /^Exif\0\0(II\x2a\0|MM\0\x2a)/ and $self->Warn("Improper EXIF header",1)',
|
548
552
|
SubDirectory => {
|
549
553
|
TagTable => 'Image::ExifTool::Exif::Main',
|
550
554
|
ProcessProc => \&Image::ExifTool::ProcessTIFF,
|
@@ -636,6 +640,11 @@ my %code2charset = (
|
|
636
640
|
},
|
637
641
|
# gpsa - seen hex "01 20 00 00", same as QuickTime
|
638
642
|
# gsea - 16 bytes hex "04 08 02 00 20 02 00 00 1f 03 00 00 01 00 00 00"
|
643
|
+
|
644
|
+
acid => { # writen by Acidizer
|
645
|
+
Name => 'Acidizer',
|
646
|
+
SubDirectory => { TagTable => 'Image::ExifTool::RIFF::Acidizer' },
|
647
|
+
},
|
639
648
|
);
|
640
649
|
|
641
650
|
# the maker notes used by some digital cameras
|
@@ -1249,6 +1258,7 @@ my %code2charset = (
|
|
1249
1258
|
Name => 'ImageWidth',
|
1250
1259
|
Format => 'int16u',
|
1251
1260
|
Mask => 0x3fff,
|
1261
|
+
Priority => 0,
|
1252
1262
|
},
|
1253
1263
|
6.1 => {
|
1254
1264
|
Name => 'HorizontalScale',
|
@@ -1259,6 +1269,7 @@ my %code2charset = (
|
|
1259
1269
|
Name => 'ImageHeight',
|
1260
1270
|
Format => 'int16u',
|
1261
1271
|
Mask => 0x3fff,
|
1272
|
+
Priority => 0,
|
1262
1273
|
},
|
1263
1274
|
8.1 => {
|
1264
1275
|
Name => 'VerticalScale',
|
@@ -1275,11 +1286,13 @@ my %code2charset = (
|
|
1275
1286
|
1 => {
|
1276
1287
|
Name => 'ImageWidth',
|
1277
1288
|
Format => 'int16u',
|
1289
|
+
Priority => 0,
|
1278
1290
|
ValueConv => '($val & 0x3fff) + 1',
|
1279
1291
|
},
|
1280
1292
|
2 => {
|
1281
1293
|
Name => 'ImageHeight',
|
1282
1294
|
Format => 'int32u',
|
1295
|
+
Priority => 0,
|
1283
1296
|
ValueConv => '(($val >> 6) & 0x3fff) + 1',
|
1284
1297
|
},
|
1285
1298
|
);
|
@@ -1290,6 +1303,19 @@ my %code2charset = (
|
|
1290
1303
|
GROUPS => { 2 => 'Image' },
|
1291
1304
|
NOTES => 'This chunk is found in extended WebP files.',
|
1292
1305
|
# 0 - bitmask: 2=ICC, 3=alpha, 4=EXIF, 5=XMP, 6=animation
|
1306
|
+
0 => {
|
1307
|
+
Name => 'WebP_Flags',
|
1308
|
+
Description => 'WebP Flags',
|
1309
|
+
Notes => 'flags used in Extended WebP images',
|
1310
|
+
Format => 'int32u',
|
1311
|
+
PrintConv => { BITMASK => {
|
1312
|
+
1 => 'Animation',
|
1313
|
+
2 => 'XMP',
|
1314
|
+
3 => 'EXIF',
|
1315
|
+
4 => 'Alpha',
|
1316
|
+
5 => 'ICC Profile',
|
1317
|
+
}},
|
1318
|
+
},
|
1293
1319
|
4 => {
|
1294
1320
|
Name => 'ImageWidth',
|
1295
1321
|
Format => 'int32u',
|
@@ -1420,6 +1446,54 @@ my %code2charset = (
|
|
1420
1446
|
},
|
1421
1447
|
);
|
1422
1448
|
|
1449
|
+
# Acidizer information (ref https://forums.cockos.com/showthread.php?t=227118)
|
1450
|
+
%Image::ExifTool::RIFF::Acidizer = (
|
1451
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
1452
|
+
GROUPS => { 2 => 'Audio' },
|
1453
|
+
0 => {
|
1454
|
+
Name => 'AcidizerFlags',
|
1455
|
+
Format => 'int32u',
|
1456
|
+
PrintConv => { BITMASK => {
|
1457
|
+
0 => 'One shot',
|
1458
|
+
1 => 'Root note set',
|
1459
|
+
2 => 'Stretch',
|
1460
|
+
3 => 'Disk-based',
|
1461
|
+
4 => 'High octave',
|
1462
|
+
}},
|
1463
|
+
},
|
1464
|
+
4 => {
|
1465
|
+
Name => 'RootNote',
|
1466
|
+
Format => 'int16u',
|
1467
|
+
PrintConv => {
|
1468
|
+
0x30 => 'C', 0x3c => 'High C',
|
1469
|
+
0x31 => 'C#', 0x3d => 'High C#',
|
1470
|
+
0x32 => 'D', 0x3e => 'High D',
|
1471
|
+
0x33 => 'D#', 0x3f => 'High D#',
|
1472
|
+
0x34 => 'E', 0x40 => 'High E',
|
1473
|
+
0x35 => 'F', 0x41 => 'High F',
|
1474
|
+
0x36 => 'F#', 0x42 => 'High F#',
|
1475
|
+
0x37 => 'G', 0x43 => 'High G',
|
1476
|
+
0x38 => 'G#', 0x44 => 'High G#',
|
1477
|
+
0x39 => 'A', 0x45 => 'High A',
|
1478
|
+
0x3a => 'A#', 0x46 => 'High A#',
|
1479
|
+
0x3b => 'B', 0x47 => 'High B',
|
1480
|
+
},
|
1481
|
+
},
|
1482
|
+
12 => {
|
1483
|
+
Name => 'Beats',
|
1484
|
+
Format => 'int32u',
|
1485
|
+
},
|
1486
|
+
16 => {
|
1487
|
+
Name => 'Meter',
|
1488
|
+
Format => 'int16u[2]',
|
1489
|
+
PrintConv => '$val =~ s/(\d+) (\d+)/$2\/$1/; $val', # denominator comes first, so swap them
|
1490
|
+
},
|
1491
|
+
20 => {
|
1492
|
+
Name => 'Tempo',
|
1493
|
+
Format => 'float',
|
1494
|
+
},
|
1495
|
+
);
|
1496
|
+
|
1423
1497
|
# RIFF composite tags
|
1424
1498
|
%Image::ExifTool::RIFF::Composite = (
|
1425
1499
|
Duration => {
|
@@ -1459,6 +1533,14 @@ my %code2charset = (
|
|
1459
1533
|
Image::ExifTool::AddCompositeTags('Image::ExifTool::RIFF');
|
1460
1534
|
|
1461
1535
|
|
1536
|
+
#------------------------------------------------------------------------------
|
1537
|
+
# AutoLoad our writer routines when necessary
|
1538
|
+
#
|
1539
|
+
sub AUTOLOAD
|
1540
|
+
{
|
1541
|
+
return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
|
1542
|
+
}
|
1543
|
+
|
1462
1544
|
#------------------------------------------------------------------------------
|
1463
1545
|
# Convert RIFF date to EXIF format
|
1464
1546
|
my %monthNum = (
|
@@ -1642,7 +1724,7 @@ sub ProcessChunks($$$)
|
|
1642
1724
|
my $start = $$dirInfo{DirStart};
|
1643
1725
|
my $size = $$dirInfo{DirLen};
|
1644
1726
|
my $end = $start + $size;
|
1645
|
-
my $base = $$dirInfo{Base};
|
1727
|
+
my $base = $$dirInfo{Base} || 0;
|
1646
1728
|
my $verbose = $et->Options('Verbose');
|
1647
1729
|
my $unknown = $et->Options('Unknown');
|
1648
1730
|
my $charset = $et->Options('CharsetRIFF');
|
@@ -1896,6 +1978,7 @@ sub ProcessRIFF($$)
|
|
1896
1978
|
my ($buff, $buf2, $type, $mime, $err, $rf64);
|
1897
1979
|
my $verbose = $et->Options('Verbose');
|
1898
1980
|
my $unknown = $et->Options('Unknown');
|
1981
|
+
my $validate = $et->Options('Validate');
|
1899
1982
|
my $ee = $et->Options('ExtractEmbedded');
|
1900
1983
|
|
1901
1984
|
# verify this is a valid RIFF file
|
@@ -1917,6 +2000,8 @@ sub ProcessRIFF($$)
|
|
1917
2000
|
$$et{RIFFStreamType} = ''; # initialize stream type
|
1918
2001
|
$$et{RIFFStreamCodec} = []; # initialize codec array
|
1919
2002
|
SetByteOrder('II');
|
2003
|
+
my $riffEnd = Get32u(\$buff, 4) + 8;
|
2004
|
+
$riffEnd += $riffEnd & 0x01; # (account for padding)
|
1920
2005
|
my $tagTbl = GetTagTable('Image::ExifTool::RIFF::Main');
|
1921
2006
|
my $pos = 12;
|
1922
2007
|
#
|
@@ -1926,10 +2011,13 @@ sub ProcessRIFF($$)
|
|
1926
2011
|
my $num = $raf->Read($buff, 8);
|
1927
2012
|
if ($num < 8) {
|
1928
2013
|
$err = 1 if $num;
|
2014
|
+
$et->Warn('Incorrect RIFF chunk size' . " $pos vs. $riffEnd") if $validate and $pos != $riffEnd;
|
1929
2015
|
last;
|
1930
2016
|
}
|
1931
2017
|
$pos += 8;
|
1932
2018
|
my ($tag, $len) = unpack('a4V', $buff);
|
2019
|
+
# tweak WEBP type if this is an extended WebP
|
2020
|
+
$et->OverrideFileType('Extended WEBP',undef,'webp') if $tag eq 'VP8X' and $type eq 'WEBP';
|
1933
2021
|
# special case: construct new tag name from specific LIST type
|
1934
2022
|
if ($tag eq 'LIST') {
|
1935
2023
|
$raf->Read($buff, 4) == 4 or $err=1, last;
|
@@ -1949,7 +2037,6 @@ sub ProcessRIFF($$)
|
|
1949
2037
|
} else {
|
1950
2038
|
next;
|
1951
2039
|
}
|
1952
|
-
last;
|
1953
2040
|
}
|
1954
2041
|
# stop when we hit the audio data or AVI index or AVI movie data
|
1955
2042
|
# --> no more because Adobe Bridge stores XMP after this!!
|
@@ -1969,6 +2056,7 @@ sub ProcessRIFF($$)
|
|
1969
2056
|
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
1970
2057
|
}
|
1971
2058
|
my $tagInfo = $$tagTbl{$tag};
|
2059
|
+
# (in LIST_movi chunk: ##db = uncompressed DIB, ##dc = compressed DIB, ##wb = audio data)
|
1972
2060
|
if ($tagInfo or (($verbose or $unknown) and $tag !~ /^(data|idx1|LIST_movi|RIFF|\d{2}(db|dc|wb))$/)) {
|
1973
2061
|
$raf->Read($buff, $len2) == $len2 or $err=1, last;
|
1974
2062
|
my $setGroups;
|
@@ -1980,7 +2068,7 @@ sub ProcessRIFF($$)
|
|
1980
2068
|
DataPt => \$buff,
|
1981
2069
|
DataPos => 0, # (relative to Base)
|
1982
2070
|
Start => 0,
|
1983
|
-
Size => $
|
2071
|
+
Size => $len,
|
1984
2072
|
Base => $pos,
|
1985
2073
|
);
|
1986
2074
|
if ($setGroups) {
|
@@ -1989,10 +2077,14 @@ sub ProcessRIFF($$)
|
|
1989
2077
|
}
|
1990
2078
|
delete $$et{DOC_NUM} if $ee;
|
1991
2079
|
} elsif ($tag eq 'RIFF') {
|
2080
|
+
$et->Warn('Incorrect RIFF chunk size') if $validate and $pos - 8 != $riffEnd;
|
2081
|
+
$riffEnd += $len2 + 8;
|
1992
2082
|
# don't read into RIFF chunk (eg. concatenated video file)
|
1993
|
-
$raf->Read($buff, 4) == 4 or $err=1, last;
|
2083
|
+
$raf->Read($buff, 4) == 4 or $err=1, last; # (skip RIFF type word)
|
2084
|
+
$pos += 4;
|
1994
2085
|
# extract information from remaining file as an embedded file
|
1995
|
-
$$et{DOC_NUM} = ++$$et{DOC_COUNT}
|
2086
|
+
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
2087
|
+
next; # (must not increment $pos)
|
1996
2088
|
} elsif ($tag eq 'LIST_movi' and $ee) {
|
1997
2089
|
next; # parse into movi chunk
|
1998
2090
|
} else {
|
@@ -2000,7 +2092,12 @@ sub ProcessRIFF($$)
|
|
2000
2092
|
$et->Warn("Stopped parsing at large $tag chunk (LargeFileSupport not set)");
|
2001
2093
|
last;
|
2002
2094
|
}
|
2003
|
-
|
2095
|
+
if ($validate and $len2) {
|
2096
|
+
# (must actually try to read something after seeking to detect error)
|
2097
|
+
$raf->Seek($len2-1, 1) and $raf->Read($buff, 1) == 1 or $err = 1, last;
|
2098
|
+
} else {
|
2099
|
+
$raf->Seek($len2, 1) or $err=1, last;
|
2100
|
+
}
|
2004
2101
|
}
|
2005
2102
|
$pos += $len2;
|
2006
2103
|
}
|
@@ -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.53';
|
26
26
|
|
27
27
|
sub WriteSTMN($$$);
|
28
28
|
sub ProcessINFO($$$);
|
@@ -991,7 +991,7 @@ my %formatMinMax = (
|
|
991
991
|
'0x0a01' => { #forum7161
|
992
992
|
Name => 'TimeStamp',
|
993
993
|
Groups => { 2 => 'Time' },
|
994
|
-
ValueConv => 'ConvertUnixTime($val / 1e3, 1)',
|
994
|
+
ValueConv => 'ConvertUnixTime($val / 1e3, 1, 3)',
|
995
995
|
PrintConv => '$self->ConvertDateTime($val)',
|
996
996
|
},
|
997
997
|
'0x0a20-name' => 'DualCameraImageName', # ("FlipPhoto_002")
|
@@ -19,7 +19,7 @@ use strict;
|
|
19
19
|
use vars qw($VERSION %sigmaLensTypes);
|
20
20
|
use Image::ExifTool::Exif;
|
21
21
|
|
22
|
-
$VERSION = '1.
|
22
|
+
$VERSION = '1.32';
|
23
23
|
|
24
24
|
# sigma LensType lookup (ref IB)
|
25
25
|
%sigmaLensTypes = (
|
@@ -226,9 +226,35 @@ $VERSION = '1.31';
|
|
226
226
|
0x1008 => 'Sigma 50mm F2.8 Macro', #NJ (DP3 Quattro kit)
|
227
227
|
0x1009 => 'Sigma 14mm F4', #NJ (DP0 Quattro kit)
|
228
228
|
# L-mount lenses?:
|
229
|
+
0x4001 => 'Lumix S 24-105mm F4 Macro OIS (S-R24105)', #IB
|
230
|
+
0x4002 => 'Lumix S 70-200mm F4 OIS (S-R70200)', #IB
|
231
|
+
0x4003 => 'Lumix S 50mm F1.4 (S-X50)', #IB
|
232
|
+
0x4006 => 'Lumix S 24-70mm F2.8 (S-E2470)', #IB
|
233
|
+
0x4007 => 'Lumix S 16-35mm F4 (S-R1635)', #IB
|
234
|
+
0x4008 => 'Lumix S 70-200mm F2.8 OIS (S-E70200)', #IB
|
235
|
+
0x4010 => 'Lumix S 35mm F1.8 (S-S35)', #IB
|
236
|
+
0x4011 => 'LUMIX S 18mm F1.8 (S-S18)', #IB
|
237
|
+
0x400b => 'Lumix S 20-60mm F3.5-5.6 (S-R2060)', #IB
|
238
|
+
0x400c => 'Lumix S 85mm F1.8 (S-S85)', #IB
|
239
|
+
0x400d => 'Lumix S 70-300 F4.5-5.6 Macro OIS (S-R70300)', #IB
|
240
|
+
0x400f => 'Lumix S 24mm F1.8 (S-S24)', #IB
|
229
241
|
0x6001 => 'Sigma 150-600mm F5-6.3 DG OS HSM | S', #PH (NC, fp)
|
230
242
|
0x6003 => 'Sigma 45mm F2.8 DG DN | C', #PH (NC, fp)
|
243
|
+
0x6005 => 'Sigma 14-24mm F2.8 DG DN | A', #IB
|
231
244
|
0x6006 => 'Sigma 50mm F1.4 DG HSM | A', #IB (014)
|
245
|
+
0x6011 => 'Sigma 24-70mm F2.8 DG DN | A', #IB
|
246
|
+
0x6012 => 'Sigma 100-400mm F5-6.3 DG DN OS | C', #IB
|
247
|
+
0x6013 => 'Sigma 100-400mm F5-6.3 DG DN OS | C + TC-1411', #IB
|
248
|
+
0x6015 => 'Sigma 85mm F1.4 DG DN | A', #IB
|
249
|
+
0x6017 => 'Sigma 65mm F2 DG DN | C', #IB
|
250
|
+
0x6018 => 'Sigma 35mm F2 DG DN | C', #IB
|
251
|
+
0x601a => 'Sigma 28-70mm F2.8 DG DN | C', #IB
|
252
|
+
0x601b => 'Sigma 150-600mm F5-6.3 DG DN OS | S', #IB
|
253
|
+
0x6020 => 'Sigma 35mm F1.4 DG DN | A', #IB
|
254
|
+
0x6021 => 'Sigma 90mm F2.8 DG DN | C', #IB
|
255
|
+
0x6023 => 'Sigma 20mm F2 DG DN | C', #IB
|
256
|
+
0x6025 => 'Sigma 20mm F1.4 DG DN | A', #IB
|
257
|
+
0x6026 => 'Sigma 24mm F1.4 DG DN | A', #IB
|
232
258
|
0x8005 => 'Sigma 35mm F1.4 DG HSM | A', #PH (012)
|
233
259
|
0x8009 => 'Sigma 18-35mm F1.8 DC HSM | A', #PH
|
234
260
|
0x8900 => 'Sigma 70-300mm F4-5.6 DG OS', #PH (SD15)
|
@@ -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.29';
|
20
20
|
|
21
21
|
sub ProcessX3FHeader($$$);
|
22
22
|
sub ProcessX3FDirectory($$$);
|
@@ -385,14 +385,14 @@ sub WriteX3F($$)
|
|
385
385
|
my ($et, $dirInfo) = @_;
|
386
386
|
my $raf = $$dirInfo{RAF};
|
387
387
|
my $outfile = $$dirInfo{OutFile};
|
388
|
-
my ($
|
388
|
+
my ($hdr, $buff, $ver, $entries, $dir, $outPos, $index, $didContain, %order, @order);
|
389
389
|
|
390
390
|
$raf->Seek($$dirInfo{DirStart}, 0) or return 'Error seeking to directory start';
|
391
391
|
|
392
392
|
# read the X3F directory header (will be copied directly to output)
|
393
|
-
$raf->Read($
|
394
|
-
$
|
395
|
-
($ver, $entries) = unpack('x4V2', $
|
393
|
+
$raf->Read($hdr, 12) == 12 or return 'Truncated X3F image';
|
394
|
+
$hdr =~ /^SECd/ or return 'Bad section header';
|
395
|
+
($ver, $entries) = unpack('x4V2', $hdr);
|
396
396
|
|
397
397
|
# do sanity check on number of entries in directory
|
398
398
|
return 'Invalid X3F directory count' unless $entries > 2 and $entries < 20;
|
@@ -400,12 +400,16 @@ sub WriteX3F($$)
|
|
400
400
|
unless ($raf->Read($dir, $entries * 12) == $entries * 12) {
|
401
401
|
return 'Truncated X3F directory';
|
402
402
|
}
|
403
|
-
# do a quick scan to determine the offset of the first data subsection
|
403
|
+
# do a quick scan to determine the offset of the first data subsection,
|
404
|
+
# and the order in which the actual data is stored in the file
|
404
405
|
for ($index=0; $index<$entries; ++$index) {
|
405
406
|
my $pos = $index * 12;
|
406
407
|
my ($offset, $len, $tag) = unpack("x${pos}V2a4", $dir);
|
407
408
|
# remember position of first data subsection
|
408
409
|
$outPos = $offset if not defined $outPos or $outPos > $offset;
|
410
|
+
# save the order of the data
|
411
|
+
$order{BAD} = 1 if defined $order{$offset};
|
412
|
+
$order{$offset} = $index;
|
409
413
|
}
|
410
414
|
# copy the file header up to the start of the first data subsection
|
411
415
|
unless ($raf->Seek(0,0) and $raf->Read($buff, $outPos) == $outPos) {
|
@@ -413,8 +417,25 @@ sub WriteX3F($$)
|
|
413
417
|
}
|
414
418
|
Write($outfile, $buff) or return -1;
|
415
419
|
|
416
|
-
#
|
417
|
-
|
420
|
+
# this is a bit tricky/unfortunate: the current version of Sigma Photo Pro
|
421
|
+
# (2022-10-18) is sensitive to the order of the data sections, and these may
|
422
|
+
# differ from the order of their respective entries in the footer. To patch
|
423
|
+
# this, instead of looping through the footer sections in order, we process
|
424
|
+
# them in the order of the offsets they contain, writing their referenced data
|
425
|
+
# sequentially as we go. This preserves both the order of the data sections
|
426
|
+
# and the order of the footer entries. (Note that the upcoming release of
|
427
|
+
# Sigma Photo Pro will fix this issue at their end, but this patch will remain
|
428
|
+
# to maintain backward compatibilty with older SPP versions.)
|
429
|
+
if ($order{BAD}) {
|
430
|
+
# (this could perhaps happen if any of the sections is ever zero-length)
|
431
|
+
$et->Error('Double-referenced data in footer directory!', 1);
|
432
|
+
@order = ( 0 .. $entries-1 );
|
433
|
+
} else {
|
434
|
+
@order = map $order{$_}, sort { $a <=> $b } keys %order;
|
435
|
+
}
|
436
|
+
|
437
|
+
# loop through footer directory, rewriting each section
|
438
|
+
foreach $index (@order) {
|
418
439
|
|
419
440
|
my $pos = $index * 12;
|
420
441
|
my ($offset, $len, $tag) = unpack("x${pos}V2a4", $dir);
|
@@ -450,6 +471,8 @@ sub WriteX3F($$)
|
|
450
471
|
return -1 if $success < 0;
|
451
472
|
# (this shouldn't happen unless someone tries to delete the EXIF...)
|
452
473
|
return 'EXIF segment must come first in X3F JpgFromRaw' unless $newData =~ /^\xff\xd8\xff\xe1/;
|
474
|
+
# trim off any extra null bytes (since section length includes padding -- silly Sigma)
|
475
|
+
$newData =~ s/\0+$//;
|
453
476
|
# write new data if anything changed, otherwise copy old image
|
454
477
|
my $outPt = $$et{CHANGED} ? \$newData : \$buff;
|
455
478
|
Write($outfile, $$outPt) or return -1;
|
@@ -468,20 +491,21 @@ sub WriteX3F($$)
|
|
468
491
|
# copy data for this subsection
|
469
492
|
Image::ExifTool::CopyBlock($raf, $outfile, $len) or return 'Corrupted X3F directory';
|
470
493
|
}
|
471
|
-
# add directory entry and update output file position
|
472
|
-
$outDir .= pack('V2a4', $outPos, $len, $tag);
|
473
|
-
$outPos += $len;
|
474
494
|
# pad data to an even 4-byte boundary
|
495
|
+
# (stored length includes padding! ref Sigma engineer Yuki Miyahara)
|
475
496
|
if ($len & 0x03) {
|
476
497
|
my $pad = 4 - ($len & 0x03);
|
477
498
|
Write($outfile, "\0" x $pad) or return -1;
|
478
|
-
$
|
499
|
+
$len += $pad;
|
479
500
|
}
|
501
|
+
# update footer entry with new offset/size
|
502
|
+
substr($dir, $pos, 8) = pack('V2', $outPos, $len);
|
503
|
+
$outPos += $len;
|
480
504
|
}
|
481
505
|
# warn if we couldn't add metadata to this image (should only be SD9 or SD10)
|
482
506
|
$didContain or $et->Warn("Can't yet write SD9 or SD10 X3F images");
|
483
507
|
# write out the directory and the directory pointer, and we are done
|
484
|
-
Write($outfile, $
|
508
|
+
Write($outfile, $hdr, $dir, pack('V', $outPos)) or return -1;
|
485
509
|
return undef;
|
486
510
|
}
|
487
511
|
|