exiftool-vendored.pl 12.55.0 → 12.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/Changes +97 -4
- package/bin/MANIFEST +9 -0
- package/bin/META.json +1 -1
- package/bin/META.yml +1 -1
- package/bin/README +19 -19
- package/bin/arg_files/xmp2exif.args +4 -1
- package/bin/config_files/example.config +1 -0
- package/bin/config_files/rotate_regions.config +1 -1
- package/bin/exiftool +197 -122
- package/bin/fmt_files/kml.fmt +3 -0
- package/bin/fmt_files/kml_track.fmt +3 -0
- package/bin/lib/Image/ExifTool/AIFF.pm +2 -2
- package/bin/lib/Image/ExifTool/APE.pm +2 -2
- package/bin/lib/Image/ExifTool/BuildTagLookup.pm +25 -19
- package/bin/lib/Image/ExifTool/Canon.pm +33 -7
- package/bin/lib/Image/ExifTool/CanonRaw.pm +5 -1
- package/bin/lib/Image/ExifTool/DJI.pm +28 -2
- package/bin/lib/Image/ExifTool/Exif.pm +107 -20
- package/bin/lib/Image/ExifTool/FlashPix.pm +92 -9
- package/bin/lib/Image/ExifTool/FujiFilm.pm +9 -4
- package/bin/lib/Image/ExifTool/GPS.pm +7 -2
- package/bin/lib/Image/ExifTool/Geotag.pm +30 -7
- package/bin/lib/Image/ExifTool/InfiRay.pm +227 -0
- package/bin/lib/Image/ExifTool/JPEG.pm +53 -7
- package/bin/lib/Image/ExifTool/Jpeg2000.pm +5 -5
- package/bin/lib/Image/ExifTool/LIF.pm +10 -2
- package/bin/lib/Image/ExifTool/LNK.pm +5 -4
- package/bin/lib/Image/ExifTool/MIE.pm +3 -3
- package/bin/lib/Image/ExifTool/MPEG.pm +2 -2
- package/bin/lib/Image/ExifTool/MakerNotes.pm +3 -2
- package/bin/lib/Image/ExifTool/Minolta.pm +6 -7
- package/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -1
- package/bin/lib/Image/ExifTool/Nikon.pm +1199 -1325
- package/bin/lib/Image/ExifTool/NikonCustom.pm +2 -2
- package/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
- package/bin/lib/Image/ExifTool/Olympus.pm +88 -6
- package/bin/lib/Image/ExifTool/OpenEXR.pm +32 -15
- package/bin/lib/Image/ExifTool/PNG.pm +89 -3
- package/bin/lib/Image/ExifTool/PanasonicRaw.pm +27 -1
- package/bin/lib/Image/ExifTool/Pentax.pm +8 -5
- package/bin/lib/Image/ExifTool/PhaseOne.pm +14 -1
- package/bin/lib/Image/ExifTool/Photoshop.pm +38 -7
- package/bin/lib/Image/ExifTool/QuickTime.pm +44 -13
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +63 -20
- package/bin/lib/Image/ExifTool/README +19 -2
- package/bin/lib/Image/ExifTool/RIFF.pm +34 -13
- package/bin/lib/Image/ExifTool/Rawzor.pm +2 -2
- package/bin/lib/Image/ExifTool/Real.pm +2 -2
- package/bin/lib/Image/ExifTool/Ricoh.pm +2 -1
- package/bin/lib/Image/ExifTool/Sigma.pm +5 -4
- package/bin/lib/Image/ExifTool/SigmaRaw.pm +9 -3
- package/bin/lib/Image/ExifTool/Sony.pm +28 -1
- package/bin/lib/Image/ExifTool/TagLookup.pm +4691 -4624
- package/bin/lib/Image/ExifTool/TagNames.pod +511 -117
- package/bin/lib/Image/ExifTool/VCard.pm +19 -5
- package/bin/lib/Image/ExifTool/Validate.pm +5 -5
- package/bin/lib/Image/ExifTool/WriteExif.pl +42 -0
- package/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
- package/bin/lib/Image/ExifTool/Writer.pl +150 -36
- package/bin/lib/Image/ExifTool/XMP.pm +19 -4
- package/bin/lib/Image/ExifTool/XMP2.pl +2 -1
- package/bin/lib/Image/ExifTool.pm +248 -54
- package/bin/lib/Image/ExifTool.pod +94 -58
- package/bin/perl-Image-ExifTool.spec +18 -18
- package/bin/pp_build_exe.args +7 -6
- package/package.json +3 -3
|
@@ -56,7 +56,7 @@ use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat
|
|
|
56
56
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
57
57
|
use Image::ExifTool::MakerNotes;
|
|
58
58
|
|
|
59
|
-
$VERSION = '4.
|
|
59
|
+
$VERSION = '4.44';
|
|
60
60
|
|
|
61
61
|
sub ProcessExif($$$);
|
|
62
62
|
sub WriteExif($$$);
|
|
@@ -65,6 +65,7 @@ sub RebuildMakerNotes($$$);
|
|
|
65
65
|
sub EncodeExifText($$);
|
|
66
66
|
sub ValidateIFD($;$);
|
|
67
67
|
sub ValidateImageData($$$;$);
|
|
68
|
+
sub AddImageDataMD5($$$);
|
|
68
69
|
sub ProcessTiffIFD($$$);
|
|
69
70
|
sub PrintParameter($$$);
|
|
70
71
|
sub GetOffList($$$$$);
|
|
@@ -573,11 +574,20 @@ my %opcodeInfo = (
|
|
|
573
574
|
],
|
|
574
575
|
Name => 'StripOffsets',
|
|
575
576
|
IsOffset => 1,
|
|
577
|
+
IsImageData => 1,
|
|
576
578
|
OffsetPair => 0x117, # point to associated byte counts
|
|
577
579
|
# A200 stores this information in the wrong byte order!!
|
|
578
580
|
ValueConv => '$val=join(" ",unpack("N*",pack("V*",split(" ",$val))));\$val',
|
|
579
581
|
ByteOrder => 'LittleEndian',
|
|
580
582
|
},
|
|
583
|
+
{
|
|
584
|
+
Condition => '$$self{Compression} and $$self{Compression} eq "34892"', # DNG Lossy JPEG
|
|
585
|
+
Name => 'OtherImageStart',
|
|
586
|
+
IsOffset => 1,
|
|
587
|
+
IsImageData => 1,
|
|
588
|
+
OffsetPair => 0x117, # point to associated byte counts
|
|
589
|
+
DataTag => 'OtherImage',
|
|
590
|
+
},
|
|
581
591
|
{
|
|
582
592
|
# (APP1 IFD2 is for Leica JPEG preview)
|
|
583
593
|
Condition => q[
|
|
@@ -587,6 +597,7 @@ my %opcodeInfo = (
|
|
|
587
597
|
],
|
|
588
598
|
Name => 'StripOffsets',
|
|
589
599
|
IsOffset => 1,
|
|
600
|
+
IsImageData => 1,
|
|
590
601
|
OffsetPair => 0x117, # point to associated byte counts
|
|
591
602
|
ValueConv => 'length($val) > 32 ? \$val : $val',
|
|
592
603
|
},
|
|
@@ -623,6 +634,7 @@ my %opcodeInfo = (
|
|
|
623
634
|
# JpgFromRawStart in various IFD's of DNG images except SubIFD2
|
|
624
635
|
Name => 'JpgFromRawStart',
|
|
625
636
|
IsOffset => 1,
|
|
637
|
+
IsImageData => 1,
|
|
626
638
|
OffsetPair => 0x117,
|
|
627
639
|
DataTag => 'JpgFromRaw',
|
|
628
640
|
Writable => 'int32u',
|
|
@@ -664,6 +676,12 @@ my %opcodeInfo = (
|
|
|
664
676
|
ValueConv => '$val=join(" ",unpack("N*",pack("V*",split(" ",$val))));\$val',
|
|
665
677
|
ByteOrder => 'LittleEndian',
|
|
666
678
|
},
|
|
679
|
+
{
|
|
680
|
+
Condition => '$$self{Compression} and $$self{Compression} eq "34892"', # DNG Lossy JPEG
|
|
681
|
+
Name => 'OtherImageLength',
|
|
682
|
+
OffsetPair => 0x111, # point to associated offset
|
|
683
|
+
DataTag => 'OtherImage',
|
|
684
|
+
},
|
|
667
685
|
{
|
|
668
686
|
# (APP1 IFD2 is for Leica JPEG preview)
|
|
669
687
|
Condition => q[
|
|
@@ -920,6 +938,7 @@ my %opcodeInfo = (
|
|
|
920
938
|
0x144 => {
|
|
921
939
|
Name => 'TileOffsets',
|
|
922
940
|
IsOffset => 1,
|
|
941
|
+
IsImageData => 1,
|
|
923
942
|
OffsetPair => 0x145,
|
|
924
943
|
ValueConv => 'length($val) > 32 ? \$val : $val',
|
|
925
944
|
},
|
|
@@ -1174,6 +1193,7 @@ my %opcodeInfo = (
|
|
|
1174
1193
|
Name => 'JpgFromRawStart',
|
|
1175
1194
|
Condition => '$$self{DIR_NAME} eq "SubIFD"',
|
|
1176
1195
|
IsOffset => 1,
|
|
1196
|
+
IsImageData => 1,
|
|
1177
1197
|
OffsetPair => 0x202,
|
|
1178
1198
|
DataTag => 'JpgFromRaw',
|
|
1179
1199
|
Writable => 'int32u',
|
|
@@ -1186,6 +1206,7 @@ my %opcodeInfo = (
|
|
|
1186
1206
|
Name => 'JpgFromRawStart',
|
|
1187
1207
|
Condition => '$$self{DIR_NAME} eq "IFD2"',
|
|
1188
1208
|
IsOffset => 1,
|
|
1209
|
+
IsImageData => 1,
|
|
1189
1210
|
OffsetPair => 0x202,
|
|
1190
1211
|
DataTag => 'JpgFromRaw',
|
|
1191
1212
|
Writable => 'int32u',
|
|
@@ -1197,6 +1218,7 @@ my %opcodeInfo = (
|
|
|
1197
1218
|
{
|
|
1198
1219
|
Name => 'OtherImageStart',
|
|
1199
1220
|
Condition => '$$self{DIR_NAME} eq "SubIFD1"',
|
|
1221
|
+
IsImageData => 1,
|
|
1200
1222
|
IsOffset => 1,
|
|
1201
1223
|
OffsetPair => 0x202,
|
|
1202
1224
|
DataTag => 'OtherImage',
|
|
@@ -1209,6 +1231,7 @@ my %opcodeInfo = (
|
|
|
1209
1231
|
Name => 'OtherImageStart',
|
|
1210
1232
|
Condition => '$$self{DIR_NAME} eq "SubIFD2"',
|
|
1211
1233
|
IsOffset => 1,
|
|
1234
|
+
IsImageData => 1,
|
|
1212
1235
|
OffsetPair => 0x202,
|
|
1213
1236
|
DataTag => 'OtherImage',
|
|
1214
1237
|
Writable => 'int32u',
|
|
@@ -1219,6 +1242,7 @@ my %opcodeInfo = (
|
|
|
1219
1242
|
{
|
|
1220
1243
|
Name => 'OtherImageStart',
|
|
1221
1244
|
IsOffset => 1,
|
|
1245
|
+
IsImageData => 1,
|
|
1222
1246
|
OffsetPair => 0x202,
|
|
1223
1247
|
},
|
|
1224
1248
|
],
|
|
@@ -1487,9 +1511,10 @@ my %opcodeInfo = (
|
|
|
1487
1511
|
0x7031 => {
|
|
1488
1512
|
Name => 'VignettingCorrection',
|
|
1489
1513
|
Notes => 'found in Sony ARW images',
|
|
1490
|
-
Protected => 1,
|
|
1491
1514
|
Writable => 'int16s',
|
|
1492
1515
|
WriteGroup => 'SubIFD',
|
|
1516
|
+
Permanent => 1,
|
|
1517
|
+
Protected => 1,
|
|
1493
1518
|
PrintConv => {
|
|
1494
1519
|
256 => 'Off',
|
|
1495
1520
|
257 => 'Auto',
|
|
@@ -1500,17 +1525,19 @@ my %opcodeInfo = (
|
|
|
1500
1525
|
0x7032 => {
|
|
1501
1526
|
Name => 'VignettingCorrParams', #forum7640
|
|
1502
1527
|
Notes => 'found in Sony ARW images',
|
|
1503
|
-
Protected => 1,
|
|
1504
1528
|
Writable => 'int16s',
|
|
1505
1529
|
WriteGroup => 'SubIFD',
|
|
1506
1530
|
Count => 17,
|
|
1531
|
+
Permanent => 1,
|
|
1532
|
+
Protected => 1,
|
|
1507
1533
|
},
|
|
1508
1534
|
0x7034 => {
|
|
1509
1535
|
Name => 'ChromaticAberrationCorrection',
|
|
1510
1536
|
Notes => 'found in Sony ARW images',
|
|
1511
|
-
Protected => 1,
|
|
1512
1537
|
Writable => 'int16s',
|
|
1513
1538
|
WriteGroup => 'SubIFD',
|
|
1539
|
+
Permanent => 1,
|
|
1540
|
+
Protected => 1,
|
|
1514
1541
|
PrintConv => {
|
|
1515
1542
|
0 => 'Off',
|
|
1516
1543
|
1 => 'Auto',
|
|
@@ -1520,17 +1547,19 @@ my %opcodeInfo = (
|
|
|
1520
1547
|
0x7035 => {
|
|
1521
1548
|
Name => 'ChromaticAberrationCorrParams', #forum6509
|
|
1522
1549
|
Notes => 'found in Sony ARW images',
|
|
1523
|
-
Protected => 1,
|
|
1524
1550
|
Writable => 'int16s',
|
|
1525
1551
|
WriteGroup => 'SubIFD',
|
|
1526
1552
|
Count => 33,
|
|
1553
|
+
Permanent => 1,
|
|
1554
|
+
Protected => 1,
|
|
1527
1555
|
},
|
|
1528
1556
|
0x7036 => {
|
|
1529
1557
|
Name => 'DistortionCorrection',
|
|
1530
1558
|
Notes => 'found in Sony ARW images',
|
|
1531
|
-
Protected => 1,
|
|
1532
1559
|
Writable => 'int16s',
|
|
1533
1560
|
WriteGroup => 'SubIFD',
|
|
1561
|
+
Permanent => 1,
|
|
1562
|
+
Protected => 1,
|
|
1534
1563
|
PrintConv => {
|
|
1535
1564
|
0 => 'Off',
|
|
1536
1565
|
1 => 'Auto',
|
|
@@ -1541,10 +1570,38 @@ my %opcodeInfo = (
|
|
|
1541
1570
|
0x7037 => {
|
|
1542
1571
|
Name => 'DistortionCorrParams', #forum6509
|
|
1543
1572
|
Notes => 'found in Sony ARW images',
|
|
1544
|
-
Protected => 1,
|
|
1545
1573
|
Writable => 'int16s',
|
|
1546
1574
|
WriteGroup => 'SubIFD',
|
|
1547
1575
|
Count => 17,
|
|
1576
|
+
Permanent => 1,
|
|
1577
|
+
Protected => 1,
|
|
1578
|
+
},
|
|
1579
|
+
0x7038 => { #github#195 (Sony ARW)
|
|
1580
|
+
Name => 'SonyRawImageSize',
|
|
1581
|
+
Notes => 'size of actual image in Sony ARW files',
|
|
1582
|
+
Writable => 'int32u',
|
|
1583
|
+
WriteGroup => 'SubIFD',
|
|
1584
|
+
Count => 2,
|
|
1585
|
+
Permanent => 1,
|
|
1586
|
+
Protected => 1,
|
|
1587
|
+
},
|
|
1588
|
+
0x7310 => { #github#195 (Sony ARW)
|
|
1589
|
+
Name => 'BlackLevel',
|
|
1590
|
+
Notes => 'found in Sony ARW images',
|
|
1591
|
+
Writable => 'int16u',
|
|
1592
|
+
WriteGroup => 'SubIFD',
|
|
1593
|
+
Count => 4,
|
|
1594
|
+
Permanent => 1,
|
|
1595
|
+
Protected => 1,
|
|
1596
|
+
},
|
|
1597
|
+
0x7313 => { #github#195 (Sony ARW)
|
|
1598
|
+
Name => 'WB_RGGBLevels',
|
|
1599
|
+
Notes => 'found in Sony ARW images',
|
|
1600
|
+
Writable => 'int16s',
|
|
1601
|
+
WriteGroup => 'SubIFD',
|
|
1602
|
+
Count => 4,
|
|
1603
|
+
Permanent => 1,
|
|
1604
|
+
Protected => 1,
|
|
1548
1605
|
},
|
|
1549
1606
|
0x74c7 => { #IB (in ARW images from some Sony cameras)
|
|
1550
1607
|
Name => 'SonyCropTopLeft',
|
|
@@ -2955,6 +3012,7 @@ my %opcodeInfo = (
|
|
|
2955
3012
|
0xbcc0 => { #13
|
|
2956
3013
|
Name => 'ImageOffset',
|
|
2957
3014
|
IsOffset => 1,
|
|
3015
|
+
IsImageData => 1,
|
|
2958
3016
|
OffsetPair => 0xbcc1, # point to associated byte count
|
|
2959
3017
|
},
|
|
2960
3018
|
0xbcc1 => { #13
|
|
@@ -2964,6 +3022,7 @@ my %opcodeInfo = (
|
|
|
2964
3022
|
0xbcc2 => { #13
|
|
2965
3023
|
Name => 'AlphaOffset',
|
|
2966
3024
|
IsOffset => 1,
|
|
3025
|
+
IsImageData => 1,
|
|
2967
3026
|
OffsetPair => 0xbcc3, # point to associated byte count
|
|
2968
3027
|
},
|
|
2969
3028
|
0xbcc3 => { #13
|
|
@@ -4706,12 +4765,28 @@ my %subSecConv = (
|
|
|
4706
4765
|
0 => 'OtherImageStart',
|
|
4707
4766
|
1 => 'OtherImageLength',
|
|
4708
4767
|
},
|
|
4768
|
+
Desire => {
|
|
4769
|
+
2 => 'OtherImageStart (1)',
|
|
4770
|
+
3 => 'OtherImageLength (1)',
|
|
4771
|
+
},
|
|
4709
4772
|
Notes => q{
|
|
4710
4773
|
this tag is writable, and may be used to update existing embedded images,
|
|
4711
4774
|
but not create or delete them
|
|
4712
4775
|
},
|
|
4713
|
-
# retrieve
|
|
4776
|
+
# retrieve all other images
|
|
4714
4777
|
RawConv => q{
|
|
4778
|
+
if ($val[2] and $val[3]) {
|
|
4779
|
+
my $i = 1;
|
|
4780
|
+
for (;;) {
|
|
4781
|
+
my %val = ( 0 => $$val{2}, 1 => $$val{3} );
|
|
4782
|
+
$self->FoundTag($tagInfo, \%val);
|
|
4783
|
+
++$i;
|
|
4784
|
+
$$val{2} = "$$val{0} ($i)";
|
|
4785
|
+
last unless defined $$self{VALUE}{$$val{2}};
|
|
4786
|
+
$$val{3} = "$$val{1} ($i)";
|
|
4787
|
+
last unless defined $$self{VALUE}{$$val{3}};
|
|
4788
|
+
}
|
|
4789
|
+
}
|
|
4715
4790
|
@grps = $self->GetGroup($$val{0});
|
|
4716
4791
|
Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"OtherImage");
|
|
4717
4792
|
},
|
|
@@ -5851,15 +5926,17 @@ sub ProcessExif($$$)
|
|
|
5851
5926
|
my $base = $$dirInfo{Base} || 0;
|
|
5852
5927
|
my $firstBase = $base;
|
|
5853
5928
|
my $raf = $$dirInfo{RAF};
|
|
5854
|
-
my $verbose =
|
|
5855
|
-
my $validate = $et->Options('Validate');
|
|
5856
|
-
my $saveFormat = $et->Options('SaveFormat');
|
|
5929
|
+
my ($verbose,$validate,$saveFormat) = @{$$et{OPTIONS}}{qw(Verbose Validate SaveFormat)};
|
|
5857
5930
|
my $htmlDump = $$et{HTML_DUMP};
|
|
5858
5931
|
my $success = 1;
|
|
5859
|
-
my ($tagKey, $dirSize, $makerAddr, $strEnc, %offsetInfo, $offName, $nextOffName);
|
|
5932
|
+
my ($tagKey, $dirSize, $makerAddr, $strEnc, %offsetInfo, $offName, $nextOffName, $doMD5);
|
|
5860
5933
|
my $inMakerNotes = $$tagTablePtr{GROUPS}{0} eq 'MakerNotes';
|
|
5861
5934
|
my $isExif = ($tagTablePtr eq \%Image::ExifTool::Exif::Main);
|
|
5862
5935
|
|
|
5936
|
+
# set flag to calculate image data MD5 if requested
|
|
5937
|
+
$doMD5 = 1 if $$et{ImageDataMD5} and (($$et{FILE_TYPE} eq 'TIFF' and not $base and not $inMakerNotes) or
|
|
5938
|
+
($$et{FILE_TYPE} eq 'RAF' and $dirName eq 'FujiIFD'));
|
|
5939
|
+
|
|
5863
5940
|
# set encoding to assume for strings
|
|
5864
5941
|
$strEnc = $et->Options('CharsetEXIF') if $$tagTablePtr{GROUPS}{0} eq 'EXIF';
|
|
5865
5942
|
|
|
@@ -5868,7 +5945,12 @@ sub ProcessExif($$$)
|
|
|
5868
5945
|
$isExif and $$et{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/)
|
|
5869
5946
|
{
|
|
5870
5947
|
my $path = $et->MetadataPath();
|
|
5871
|
-
|
|
5948
|
+
if ($path =~ /^(JPEG-APP1-IFD0|TIFF-IFD0|PSD-EXIFInfo-IFD0)$/) {
|
|
5949
|
+
unless ($$et{DOC_NUM}) {
|
|
5950
|
+
$et->Warn("Duplicate EXIF at $path") if $$et{HasExif};
|
|
5951
|
+
$$et{HasExif} = 1;
|
|
5952
|
+
}
|
|
5953
|
+
} else {
|
|
5872
5954
|
if ($Image::ExifTool::MWG::strict) {
|
|
5873
5955
|
$et->Warn("Ignored non-standard EXIF at $path");
|
|
5874
5956
|
return 0;
|
|
@@ -6332,10 +6414,10 @@ sub ProcessExif($$$)
|
|
|
6332
6414
|
$tval .= " ($rational)" if defined $rational;
|
|
6333
6415
|
if ($htmlDump) {
|
|
6334
6416
|
my ($tagName, $colName);
|
|
6335
|
-
if ($
|
|
6336
|
-
$tagName = 'MakerNotes';
|
|
6337
|
-
} elsif ($tagInfo) {
|
|
6417
|
+
if ($tagInfo) {
|
|
6338
6418
|
$tagName = $$tagInfo{Name};
|
|
6419
|
+
} elsif ($tagID == 0x927c and $dirName eq 'ExifIFD') {
|
|
6420
|
+
$tagName = 'MakerNotes';
|
|
6339
6421
|
} else {
|
|
6340
6422
|
$tagName = sprintf("Tag 0x%.4x",$tagID);
|
|
6341
6423
|
}
|
|
@@ -6410,6 +6492,9 @@ sub ProcessExif($$$)
|
|
|
6410
6492
|
}
|
|
6411
6493
|
# add value data block (underlining maker notes data)
|
|
6412
6494
|
$et->HDump($exifDumpPos,$size,"$tagName value",'SAME', $flag, $sid);
|
|
6495
|
+
if ($subdir and $$tagInfo{MakerNotes} and $$tagInfo{NotIFD}) {
|
|
6496
|
+
$et->HDump($exifDumpPos,$size,"$tagName value",undef,undef,$$dirInfo{OffsetName});
|
|
6497
|
+
}
|
|
6413
6498
|
}
|
|
6414
6499
|
} else {
|
|
6415
6500
|
if ($tagID <= $lastID and not $inMakerNotes) {
|
|
@@ -6696,7 +6781,7 @@ sub ProcessExif($$$)
|
|
|
6696
6781
|
}
|
|
6697
6782
|
$val = join(' ', @vals);
|
|
6698
6783
|
}
|
|
6699
|
-
if ($validate) {
|
|
6784
|
+
if ($validate or $doMD5) {
|
|
6700
6785
|
if ($$tagInfo{OffsetPair}) {
|
|
6701
6786
|
$offsetInfo{$tagID} = [ $tagInfo, $val ];
|
|
6702
6787
|
} elsif ($saveForValidate{$tagID} and $isExif) {
|
|
@@ -6714,9 +6799,11 @@ sub ProcessExif($$$)
|
|
|
6714
6799
|
}
|
|
6715
6800
|
}
|
|
6716
6801
|
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6802
|
+
if (%offsetInfo) {
|
|
6803
|
+
# calculate image data MD5 if requested
|
|
6804
|
+
AddImageDataMD5($et, $dirInfo, \%offsetInfo) if $doMD5;
|
|
6805
|
+
# validate image data offsets for this IFD (note: modifies %offsetInfo)
|
|
6806
|
+
Image::ExifTool::Validate::ValidateOffsetInfo($et, \%offsetInfo, $dirName, $inMakerNotes) if $validate;
|
|
6720
6807
|
}
|
|
6721
6808
|
|
|
6722
6809
|
# scan for subsequent IFD's if specified
|
|
@@ -21,7 +21,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
|
21
21
|
use Image::ExifTool::Exif;
|
|
22
22
|
use Image::ExifTool::ASF; # for GetGUID()
|
|
23
23
|
|
|
24
|
-
$VERSION = '1.
|
|
24
|
+
$VERSION = '1.44';
|
|
25
25
|
|
|
26
26
|
sub ProcessFPX($$);
|
|
27
27
|
sub ProcessFPXR($$$);
|
|
@@ -318,6 +318,10 @@ my %fpxFileType = (
|
|
|
318
318
|
unrecognized Windows Compound Binary file as a FlashPix (FPX) file. See
|
|
319
319
|
L<http://graphcomp.com/info/specs/livepicture/fpx.pdf> for the FlashPix
|
|
320
320
|
specification.
|
|
321
|
+
|
|
322
|
+
Note that Microsoft is not consistent with the time zone used for some
|
|
323
|
+
date/time tags, and it may be either UTC or local time depending on the
|
|
324
|
+
software used to create the file.
|
|
321
325
|
},
|
|
322
326
|
"\x05SummaryInformation" => {
|
|
323
327
|
Name => 'SummaryInfo',
|
|
@@ -483,10 +487,29 @@ my %fpxFileType = (
|
|
|
483
487
|
},
|
|
484
488
|
IeImg => {
|
|
485
489
|
Name => 'EmbeddedImage',
|
|
486
|
-
Notes =>
|
|
490
|
+
Notes => q{
|
|
491
|
+
embedded images in Scene7 vignette VNT files. The EmbeddedImage Class and
|
|
492
|
+
Rectangle are also extracted for applicable images, and may be associated
|
|
493
|
+
with the corresponding EmbeddedImage via the family 3 group name
|
|
494
|
+
},
|
|
487
495
|
Groups => { 2 => 'Preview' },
|
|
488
496
|
Binary => 1,
|
|
489
497
|
},
|
|
498
|
+
IeImg_class => {
|
|
499
|
+
Name => 'EmbeddedImageClass',
|
|
500
|
+
Notes => q{
|
|
501
|
+
not a real tag. This information is extracted if available for the
|
|
502
|
+
corresponding EmbeddedImage from the Contents of a VNT file
|
|
503
|
+
},
|
|
504
|
+
# eg. "Cache", "Mask"
|
|
505
|
+
},
|
|
506
|
+
IeImg_rect => { #
|
|
507
|
+
Name => 'EmbeddedImageRectangle',
|
|
508
|
+
Notes => q{
|
|
509
|
+
not a real tag. This information is extracted if available for the
|
|
510
|
+
corresponding EmbeddedImage from the Contents of a VNT file
|
|
511
|
+
},
|
|
512
|
+
},
|
|
490
513
|
);
|
|
491
514
|
|
|
492
515
|
# Summary Information properties
|
|
@@ -1059,6 +1082,7 @@ my %fpxFileType = (
|
|
|
1059
1082
|
%Image::ExifTool::FlashPix::Contents = (
|
|
1060
1083
|
PROCESS_PROC => \&ProcessProperties,
|
|
1061
1084
|
GROUPS => { 2 => 'Image' },
|
|
1085
|
+
OriginalFileName => { Name => 'OriginalFileName', Hidden => 1 }, # (not a real tag -- extracted from Contents of VNT file)
|
|
1062
1086
|
);
|
|
1063
1087
|
|
|
1064
1088
|
# CompObj tags
|
|
@@ -1537,11 +1561,46 @@ sub ProcessContents($$$)
|
|
|
1537
1561
|
my $isFLA;
|
|
1538
1562
|
|
|
1539
1563
|
# all of my FLA samples contain "Contents" data, and no other FPX-like samples have
|
|
1540
|
-
# this, but check the data for a familiar pattern to be
|
|
1541
|
-
# Contents of all of my FLA samples start with two bytes
|
|
1542
|
-
# then 0x01) followed by a number of zero bytes
|
|
1543
|
-
# somehow to the value of the first byte),
|
|
1544
|
-
|
|
1564
|
+
# this (except Scene7 VNT viles), but check the data for a familiar pattern to be
|
|
1565
|
+
# sure this is FLA: the Contents of all of my FLA samples start with two bytes
|
|
1566
|
+
# (0x29,0x38,0x3f,0x43 or 0x47, then 0x01) followed by a number of zero bytes
|
|
1567
|
+
# (from 0x18 to 0x26 of them, related somehow to the value of the first byte),
|
|
1568
|
+
# followed by the string "DocumentPage"
|
|
1569
|
+
if ($$dataPt =~ /^..\0+\xff\xff\x01\0\x0d\0CDocumentPage/s) {
|
|
1570
|
+
$isFLA = 1;
|
|
1571
|
+
} elsif ($$dataPt =~ /^\0{4}.(.{1,255})\x60\xa1\x3f\x22\0{5}(.{8})/sg) {
|
|
1572
|
+
# this looks like a VNT file
|
|
1573
|
+
$et->OverrideFileType('VNT', 'image/x-vignette');
|
|
1574
|
+
# hack to set proper file description (extension is the same for V-Note files)
|
|
1575
|
+
$Image::ExifTool::static_vars{OverrideFileDescription}{VNT} = 'Scene7 Vignette',
|
|
1576
|
+
my $name = $1;
|
|
1577
|
+
my ($w, $h) = unpack('V2',$2);
|
|
1578
|
+
$et->FoundTag(ImageWidth => $w);
|
|
1579
|
+
$et->FoundTag(ImageHeight => $h);
|
|
1580
|
+
$et->HandleTag($tagTablePtr, OriginalFileName => $name);
|
|
1581
|
+
if ($$dataPt =~ /\G\x01\0{4}(.{12})/sg) {
|
|
1582
|
+
# (first 4 bytes seem to be number of objects, next 4 bytes are zero, then ICC size)
|
|
1583
|
+
my $size = unpack('x8V', $1);
|
|
1584
|
+
# (not useful?) $et->FoundTag(NumObjects => $num);
|
|
1585
|
+
if ($size and pos($$dataPt) + $size < length($$dataPt)) {
|
|
1586
|
+
my $dat = substr($$dataPt, pos($$dataPt), $size);
|
|
1587
|
+
$et->FoundTag(ICC_Profile => $dat);
|
|
1588
|
+
pos($$dataPt) += $size;
|
|
1589
|
+
}
|
|
1590
|
+
$$et{IeImg_lkup} = { };
|
|
1591
|
+
$$et{IeImg_class} = { };
|
|
1592
|
+
# - the byte before \x80 is 0x0d, 0x11 or 0x1f for separate images in my samples,
|
|
1593
|
+
# and 0x1c or 0x23 for inline masks
|
|
1594
|
+
# - the byte after \xff\xff is 0x3b in my samples for $1 containing 'VnMask' or 'VnCache'
|
|
1595
|
+
while ($$dataPt =~ /\x0bTargetRole1(?:.\x80|\xff\xff.\0.\0Vn(\w+))\0\0\x01.{4}(.{24})/sg) {
|
|
1596
|
+
my ($index, @coords) = unpack('Vx4V4', $2);
|
|
1597
|
+
next if $index == 0xffffffff;
|
|
1598
|
+
$$et{IeImg_lkup}{$index} and $et->WarnOnce('Duplicate image index');
|
|
1599
|
+
$$et{IeImg_lkup}{$index} = "@coords";
|
|
1600
|
+
$$et{IeImg_class}{$index} = $1 if $1;
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1545
1604
|
|
|
1546
1605
|
# do a brute-force scan of the "Contents" for UTF-16 XMP
|
|
1547
1606
|
# (this may always be little-endian, but allow for either endianness)
|
|
@@ -2337,8 +2396,28 @@ sub ProcessFPX($$)
|
|
|
2337
2396
|
);
|
|
2338
2397
|
my $subTablePtr = GetTagTable($$subdir{TagTable});
|
|
2339
2398
|
$et->ProcessDirectory(\%dirInfo, $subTablePtr, $$subdir{ProcessProc});
|
|
2399
|
+
} elsif (defined $size and $size > length($buff)) {
|
|
2400
|
+
$et->WarnOnce('Truncated object');
|
|
2340
2401
|
} else {
|
|
2341
|
-
$
|
|
2402
|
+
$buff = substr($buff, 0, $size) if defined $size and $size < length($buff);
|
|
2403
|
+
if ($tag =~ /^IeImg_0*(\d+)$/) {
|
|
2404
|
+
# set document number for embedded images and their positions (if available, VNT files)
|
|
2405
|
+
my $num = $1;
|
|
2406
|
+
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
|
2407
|
+
$et->FoundTag($tagInfo, $buff);
|
|
2408
|
+
if ($$et{IeImg_lkup} and $$et{IeImg_lkup}{$num}) {
|
|
2409
|
+
# save position of this image
|
|
2410
|
+
$et->HandleTag($tagTablePtr, IeImg_rect => $$et{IeImg_lkup}{$num});
|
|
2411
|
+
delete $$et{IeImg_lkup}{$num};
|
|
2412
|
+
if ($$et{IeImg_class} and $$et{IeImg_class}{$num}) {
|
|
2413
|
+
$et->HandleTag($tagTablePtr, IeImg_class => $$et{IeImg_class}{$num});
|
|
2414
|
+
delete $$et{IeImg_class}{$num};
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
delete $$et{DOC_NUM};
|
|
2418
|
+
} else {
|
|
2419
|
+
$et->FoundTag($tagInfo, $buff);
|
|
2420
|
+
}
|
|
2342
2421
|
}
|
|
2343
2422
|
# save object index number for all found tags
|
|
2344
2423
|
my $num2 = $$et{NUM_FOUND};
|
|
@@ -2380,7 +2459,7 @@ sub ProcessFPX($$)
|
|
|
2380
2459
|
}
|
|
2381
2460
|
$$et{INDENT} = $oldIndent if $verbose;
|
|
2382
2461
|
# try to better identify the file type
|
|
2383
|
-
if ($$et{
|
|
2462
|
+
if ($$et{FileType} eq 'FPX') {
|
|
2384
2463
|
my $val = $$et{CompObjUserType} || $$et{Software};
|
|
2385
2464
|
if ($val) {
|
|
2386
2465
|
my %type = ( '^3ds Max' => 'MAX', Word => 'DOC', PowerPoint => 'PPT', Excel => 'XLS' );
|
|
@@ -2395,6 +2474,10 @@ sub ProcessFPX($$)
|
|
|
2395
2474
|
# process Word document table
|
|
2396
2475
|
ProcessDocumentTable($et);
|
|
2397
2476
|
|
|
2477
|
+
if ($$et{IeImg_lkup} and %{$$et{IeImg_lkup}}) {
|
|
2478
|
+
$et->Warn('Image positions exist without corresponding images');
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2398
2481
|
return 1;
|
|
2399
2482
|
}
|
|
2400
2483
|
|
|
@@ -31,7 +31,7 @@ use vars qw($VERSION);
|
|
|
31
31
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
32
32
|
use Image::ExifTool::Exif;
|
|
33
33
|
|
|
34
|
-
$VERSION = '1.
|
|
34
|
+
$VERSION = '1.87';
|
|
35
35
|
|
|
36
36
|
sub ProcessFujiDir($$$);
|
|
37
37
|
sub ProcessFaceRec($$$);
|
|
@@ -808,6 +808,7 @@ my %faceCategories = (
|
|
|
808
808
|
0x00 => 'Normal',
|
|
809
809
|
0x10 => 'F-log',
|
|
810
810
|
0x20 => 'HLG',
|
|
811
|
+
0x30 => 'F-log2', #forum14384
|
|
811
812
|
},
|
|
812
813
|
},
|
|
813
814
|
0x3804 => { #forum10037
|
|
@@ -1371,6 +1372,7 @@ my %faceCategories = (
|
|
|
1371
1372
|
0xf007 => {
|
|
1372
1373
|
Name => 'StripOffsets',
|
|
1373
1374
|
IsOffset => 1,
|
|
1375
|
+
IsImageData => 1,
|
|
1374
1376
|
OffsetPair => 0xf008, # point to associated byte counts
|
|
1375
1377
|
},
|
|
1376
1378
|
0xf008 => {
|
|
@@ -1669,11 +1671,11 @@ sub ProcessRAF($$)
|
|
|
1669
1671
|
my ($rafNum, $ifdNum) = ('','');
|
|
1670
1672
|
foreach $offset (0x5c, 0x64, 0x78, 0x80) {
|
|
1671
1673
|
last if $offset >= $jpos;
|
|
1672
|
-
unless ($raf->Seek($offset, 0) and $raf->Read($buff,
|
|
1674
|
+
unless ($raf->Seek($offset, 0) and $raf->Read($buff, 8)) {
|
|
1673
1675
|
$warn = 1;
|
|
1674
1676
|
last;
|
|
1675
1677
|
}
|
|
1676
|
-
my $start = unpack('
|
|
1678
|
+
my ($start, $len) = unpack('N2',$buff);
|
|
1677
1679
|
next unless $start;
|
|
1678
1680
|
if ($offset == 0x64 or $offset == 0x80) {
|
|
1679
1681
|
# parse FujiIFD directory
|
|
@@ -1684,7 +1686,10 @@ sub ProcessRAF($$)
|
|
|
1684
1686
|
$$et{SET_GROUP1} = "FujiIFD$ifdNum";
|
|
1685
1687
|
my $tagTablePtr = GetTagTable('Image::ExifTool::FujiFilm::IFD');
|
|
1686
1688
|
# this is TIFF-format data only for some models, so no warning if it fails
|
|
1687
|
-
$et->ProcessTIFF(\%dirInfo, $tagTablePtr, \&Image::ExifTool::ProcessTIFF)
|
|
1689
|
+
unless ($et->ProcessTIFF(\%dirInfo, $tagTablePtr, \&Image::ExifTool::ProcessTIFF)) {
|
|
1690
|
+
# do MD5 of image data if necessary
|
|
1691
|
+
$et->ImageDataMD5($raf, $len, 'raw') if $$et{ImageDataMD5} and $raf->Seek($start,0);
|
|
1692
|
+
}
|
|
1688
1693
|
delete $$et{SET_GROUP1};
|
|
1689
1694
|
$ifdNum = ($ifdNum || 1) + 1;
|
|
1690
1695
|
} else {
|
|
@@ -482,13 +482,13 @@ sub PrintTimeStamp($)
|
|
|
482
482
|
#------------------------------------------------------------------------------
|
|
483
483
|
# Convert degrees to DMS, or whatever the current settings are
|
|
484
484
|
# Inputs: 0) ExifTool reference, 1) Value in degrees,
|
|
485
|
-
# 2) format code (0=no format, 1=CoordFormat, 2=XMP format)
|
|
485
|
+
# 2) format code (0=no format, 1=CoordFormat, 2=XMP format, 3=signed unformatted)
|
|
486
486
|
# 3) 'N' or 'E' if sign is significant and N/S/E/W should be added
|
|
487
487
|
# Returns: DMS string
|
|
488
488
|
sub ToDMS($$;$$)
|
|
489
489
|
{
|
|
490
490
|
my ($et, $val, $doPrintConv, $ref) = @_;
|
|
491
|
-
my ($fmt, @fmt, $num, $sign, $rtnVal);
|
|
491
|
+
my ($fmt, @fmt, $num, $sign, $rtnVal, $neg);
|
|
492
492
|
|
|
493
493
|
unless (length $val) {
|
|
494
494
|
# don't convert an empty value
|
|
@@ -505,6 +505,10 @@ sub ToDMS($$;$$)
|
|
|
505
505
|
}
|
|
506
506
|
$ref = " $ref" unless $doPrintConv and $doPrintConv eq '2';
|
|
507
507
|
} else {
|
|
508
|
+
if ($doPrintConv and $doPrintConv eq '3') {
|
|
509
|
+
$neg = 1 if $val < 0;
|
|
510
|
+
$doPrintConv = 0;
|
|
511
|
+
}
|
|
508
512
|
$val = abs($val);
|
|
509
513
|
$ref = '';
|
|
510
514
|
}
|
|
@@ -554,6 +558,7 @@ sub ToDMS($$;$$)
|
|
|
554
558
|
# trim trailing zeros in XMP
|
|
555
559
|
$rtnVal =~ s/(\d)0+$ref$/$1$ref/ if $doPrintConv eq '2';
|
|
556
560
|
} else {
|
|
561
|
+
$neg and map { $_ *= -1 } @c;
|
|
557
562
|
$rtnVal = "@c$ref";
|
|
558
563
|
}
|
|
559
564
|
return $rtnVal;
|