exiftool_vendored 12.17.1 → 12.32.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 +225 -1
- data/bin/MANIFEST +23 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +45 -43
- data/bin/arg_files/xmp2exif.args +2 -1
- data/bin/config_files/acdsee.config +193 -6
- data/bin/config_files/convert_regions.config +25 -14
- data/bin/config_files/cuepointlist.config +70 -0
- data/bin/config_files/example.config +2 -9
- data/bin/exiftool +142 -87
- data/bin/fmt_files/gpx.fmt +2 -2
- data/bin/fmt_files/gpx_wpt.fmt +2 -2
- data/bin/fmt_files/kml.fmt +1 -1
- data/bin/fmt_files/kml_track.fmt +1 -1
- data/bin/lib/Image/ExifTool/Apple.pm +3 -2
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +30 -12
- data/bin/lib/Image/ExifTool/CBOR.pm +277 -0
- data/bin/lib/Image/ExifTool/Canon.pm +49 -18
- data/bin/lib/Image/ExifTool/DJI.pm +6 -6
- data/bin/lib/Image/ExifTool/DPX.pm +13 -2
- data/bin/lib/Image/ExifTool/DjVu.pm +6 -5
- data/bin/lib/Image/ExifTool/Exif.pm +28 -11
- data/bin/lib/Image/ExifTool/FITS.pm +13 -2
- data/bin/lib/Image/ExifTool/FlashPix.pm +35 -10
- data/bin/lib/Image/ExifTool/FujiFilm.pm +19 -8
- data/bin/lib/Image/ExifTool/GPS.pm +22 -11
- data/bin/lib/Image/ExifTool/Geotag.pm +13 -2
- data/bin/lib/Image/ExifTool/GoPro.pm +16 -1
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +2 -2
- data/bin/lib/Image/ExifTool/ID3.pm +15 -3
- data/bin/lib/Image/ExifTool/JPEG.pm +74 -4
- data/bin/lib/Image/ExifTool/JSON.pm +27 -4
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +393 -16
- data/bin/lib/Image/ExifTool/LIF.pm +153 -0
- data/bin/lib/Image/ExifTool/Lang/nl.pm +60 -59
- data/bin/lib/Image/ExifTool/M2TS.pm +137 -5
- data/bin/lib/Image/ExifTool/MIE.pm +4 -3
- data/bin/lib/Image/ExifTool/MRC.pm +341 -0
- data/bin/lib/Image/ExifTool/MWG.pm +3 -3
- data/bin/lib/Image/ExifTool/MXF.pm +1 -1
- data/bin/lib/Image/ExifTool/MacOS.pm +1 -1
- data/bin/lib/Image/ExifTool/Microsoft.pm +298 -82
- data/bin/lib/Image/ExifTool/Nikon.pm +19 -8
- data/bin/lib/Image/ExifTool/NikonSettings.pm +28 -11
- data/bin/lib/Image/ExifTool/Olympus.pm +6 -3
- data/bin/lib/Image/ExifTool/Other.pm +93 -0
- data/bin/lib/Image/ExifTool/PDF.pm +9 -12
- data/bin/lib/Image/ExifTool/PNG.pm +8 -7
- data/bin/lib/Image/ExifTool/Panasonic.pm +28 -3
- data/bin/lib/Image/ExifTool/Pentax.pm +28 -5
- data/bin/lib/Image/ExifTool/PhaseOne.pm +4 -3
- data/bin/lib/Image/ExifTool/Photoshop.pm +6 -0
- data/bin/lib/Image/ExifTool/QuickTime.pm +247 -88
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +283 -141
- data/bin/lib/Image/ExifTool/README +3 -0
- data/bin/lib/Image/ExifTool/RIFF.pm +89 -12
- data/bin/lib/Image/ExifTool/Samsung.pm +48 -10
- data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -0
- data/bin/lib/Image/ExifTool/Sony.pm +237 -78
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +1 -0
- data/bin/lib/Image/ExifTool/TagLookup.pm +4125 -4028
- data/bin/lib/Image/ExifTool/TagNames.pod +644 -286
- data/bin/lib/Image/ExifTool/Torrent.pm +18 -11
- data/bin/lib/Image/ExifTool/WriteExif.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePDF.pl +1 -0
- data/bin/lib/Image/ExifTool/WritePNG.pl +2 -0
- data/bin/lib/Image/ExifTool/WritePostScript.pl +1 -0
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +55 -21
- data/bin/lib/Image/ExifTool/WriteXMP.pl +7 -3
- data/bin/lib/Image/ExifTool/Writer.pl +47 -10
- data/bin/lib/Image/ExifTool/XMP.pm +39 -14
- data/bin/lib/Image/ExifTool/XMP2.pl +2 -1
- data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
- data/bin/lib/Image/ExifTool/ZISRAW.pm +121 -2
- data/bin/lib/Image/ExifTool.pm +223 -72
- data/bin/lib/Image/ExifTool.pod +114 -93
- data/bin/perl-Image-ExifTool.spec +43 -42
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +28 -13
@@ -5,6 +5,7 @@
|
|
5
5
|
#
|
6
6
|
# Revisions: 2010/10/01 - P. Harvey Created
|
7
7
|
# 2011/10/05 - PH Added ProcessXtra()
|
8
|
+
# 2021/02/23 - PH Added abiltity to write Xtra tags
|
8
9
|
#
|
9
10
|
# References: 1) http://research.microsoft.com/en-us/um/redmond/groups/ivm/hdview/hdmetadataspec.htm
|
10
11
|
#------------------------------------------------------------------------------
|
@@ -16,9 +17,11 @@ use vars qw($VERSION);
|
|
16
17
|
use Image::ExifTool qw(:DataAccess :Utils);
|
17
18
|
use Image::ExifTool::XMP;
|
18
19
|
|
19
|
-
$VERSION = '1.
|
20
|
+
$VERSION = '1.23';
|
20
21
|
|
21
22
|
sub ProcessXtra($$$);
|
23
|
+
sub WriteXtra($$$);
|
24
|
+
sub CheckXtra($$$);
|
22
25
|
|
23
26
|
# tags written by Microsoft HDView (ref 1)
|
24
27
|
%Image::ExifTool::Microsoft::Stitch = (
|
@@ -196,11 +199,20 @@ my %sRegions = (
|
|
196
199
|
# and Image::ExifTool::WTV::Metadata
|
197
200
|
%Image::ExifTool::Microsoft::Xtra = (
|
198
201
|
PROCESS_PROC => \&ProcessXtra,
|
202
|
+
WRITE_PROC => \&WriteXtra,
|
203
|
+
CHECK_PROC => \&CheckXtra,
|
204
|
+
WRITE_GROUP => 'Microsoft',
|
205
|
+
AVOID => 1,
|
199
206
|
GROUPS => { 0 => 'QuickTime', 2 => 'Video' },
|
200
207
|
VARS => { NO_ID => 1 },
|
201
208
|
NOTES => q{
|
202
|
-
Tags
|
203
|
-
|
209
|
+
Tags found in the Microsoft "Xtra" atom of QuickTime videos. Tag ID's are
|
210
|
+
not shown because some are unruly GUID's. Currently most of these tags are
|
211
|
+
not writable because the Microsoft documentation is poor and samples were
|
212
|
+
not available, but more tags may be made writable in the future if samples
|
213
|
+
are provided. Note that writable tags in this table are are flagged to
|
214
|
+
"Avoid", which means that other more common tags will be written instead if
|
215
|
+
possible unless the Microsoft group is specified explicitly.
|
204
216
|
},
|
205
217
|
Abstract => { },
|
206
218
|
AcquisitionTime => { Groups => { 2 => 'Time' } },
|
@@ -327,30 +339,34 @@ my %sRegions = (
|
|
327
339
|
UserServiceRating => { },
|
328
340
|
VideoBitrate => { },
|
329
341
|
VideoFormat => { },
|
330
|
-
'WM/AlbumArtist' => 'AlbumArtist',
|
331
|
-
'WM/AlbumCoverURL' => 'AlbumCoverURL',
|
332
|
-
'WM/AlbumTitle' => 'AlbumTitle',
|
342
|
+
'WM/AlbumArtist' => { Name => 'AlbumArtist', Writable => 'Unicode' }, # (NC)
|
343
|
+
'WM/AlbumCoverURL' => { Name => 'AlbumCoverURL', Writable => 'Unicode' }, # (NC)
|
344
|
+
'WM/AlbumTitle' => { Name => 'AlbumTitle', Writable => 'Unicode' }, # (NC)
|
333
345
|
'WM/BeatsPerMinute' => 'BeatsPerMinute',
|
334
|
-
'WM/Category' => 'Category',
|
335
|
-
'WM/Composer' => 'Composer',
|
336
|
-
'WM/Conductor' => 'Conductor',
|
337
|
-
'WM/ContentDistributor' => 'ContentDistributor',
|
346
|
+
'WM/Category' => { Name => 'Category', Writable => 'Unicode', List => 1 },
|
347
|
+
'WM/Composer' => { Name => 'Composer', Writable => 'Unicode' }, # (NC)
|
348
|
+
'WM/Conductor' => { Name => 'Conductor', Writable => 'Unicode', List => 1 },
|
349
|
+
'WM/ContentDistributor' => { Name => 'ContentDistributor', Writable => 'Unicode' },
|
338
350
|
'WM/ContentDistributorType' => 'ContentDistributorType',
|
339
351
|
'WM/ContentGroupDescription'=> 'ContentGroupDescription',
|
340
|
-
'WM/Director' => 'Director',
|
352
|
+
'WM/Director' => { Name => 'Director', Writable => 'Unicode', List => 1 },
|
341
353
|
'WM/EncodingTime' => {
|
342
354
|
Name => 'EncodingTime',
|
343
355
|
Groups => { 2 => 'Time' },
|
356
|
+
Shift => 'Time',
|
357
|
+
Writable => 'date',
|
344
358
|
PrintConv => '$self->ConvertDateTime($val)',
|
359
|
+
PrintConvInv => '$self->InverseDateTime($val)',
|
345
360
|
},
|
346
361
|
'WM/Genre' => 'Genre',
|
347
362
|
'WM/GenreID' => 'GenreID',
|
348
|
-
'WM/InitialKey' => 'InitialKey',
|
363
|
+
'WM/InitialKey' => { Name => 'InitialKey', Writable => 'Unicode' },
|
349
364
|
'WM/Language' => 'Language',
|
350
365
|
'WM/Lyrics' => 'Lyrics',
|
351
366
|
'WM/MCDI' => 'MCDI',
|
352
367
|
'WM/MediaClassPrimaryID' => {
|
353
368
|
Name => 'MediaClassPrimaryID',
|
369
|
+
Writable => 'GUID',
|
354
370
|
PrintConv => { #http://msdn.microsoft.com/en-us/library/windows/desktop/dd757960(v=vs.85).aspx
|
355
371
|
'D1607DBC-E323-4BE2-86A1-48A42A28441E' => 'Music',
|
356
372
|
'DB9830BD-3AB3-4FAB-8A37-1A995F7FF74B' => 'Video',
|
@@ -360,6 +376,7 @@ my %sRegions = (
|
|
360
376
|
},
|
361
377
|
'WM/MediaClassSecondaryID' => {
|
362
378
|
Name => 'MediaClassSecondaryID',
|
379
|
+
Writable => 'GUID',
|
363
380
|
PrintConv => { #http://msdn.microsoft.com/en-us/library/windows/desktop/dd757960(v=vs.85).aspx
|
364
381
|
'E0236BEB-C281-4EDE-A36D-7AF76A3D45B5' => 'Audio Book',
|
365
382
|
'3A172A13-2BD9-4831-835B-114F6A95943F' => 'Spoken Word',
|
@@ -385,22 +402,22 @@ my %sRegions = (
|
|
385
402
|
},
|
386
403
|
'WM/MediaOriginalChannel' => 'MediaOriginalChannel',
|
387
404
|
'WM/MediaStationName' => 'MediaStationName',
|
388
|
-
'WM/Mood' => 'Mood',
|
389
|
-
'WM/OriginalAlbumTitle' => 'OriginalAlbumTitle',
|
390
|
-
'WM/OriginalArtist' => 'OriginalArtist',
|
391
|
-
'WM/OriginalLyricist' => 'OriginalLyricist',
|
392
|
-
'WM/ParentalRating' => 'ParentalRating',
|
405
|
+
'WM/Mood' => { Name => 'Mood', Writable => 'Unicode' },
|
406
|
+
'WM/OriginalAlbumTitle' => { Name => 'OriginalAlbumTitle', Writable => 'Unicode' }, # (NC)
|
407
|
+
'WM/OriginalArtist' => { Name => 'OriginalArtist', Writable => 'Unicode' }, # (NC)
|
408
|
+
'WM/OriginalLyricist' => { Name => 'OriginalLyricist', Writable => 'Unicode' }, # (NC)
|
409
|
+
'WM/ParentalRating' => { Name => 'ParentalRating', Writable => 'Unicode' },
|
393
410
|
'WM/PartOfSet' => 'PartOfSet',
|
394
|
-
'WM/Period' => 'Period',
|
395
|
-
'WM/Producer' => 'Producer',
|
411
|
+
'WM/Period' => { Name => 'Period', Writable => 'Unicode' },
|
412
|
+
'WM/Producer' => { Name => 'Producer', Writable => 'Unicode', List => 1 },
|
396
413
|
'WM/ProtectionType' => 'ProtectionType',
|
397
|
-
'WM/Provider' => 'Provider',
|
414
|
+
'WM/Provider' => { Name => 'Provider', Writable => 'Unicode' }, # (NC)
|
398
415
|
'WM/ProviderRating' => 'ProviderRating',
|
399
416
|
'WM/ProviderStyle' => 'ProviderStyle',
|
400
|
-
'WM/Publisher' => 'Publisher',
|
401
|
-
'WM/SharedUserRating' => 'SharedUserRating',
|
417
|
+
'WM/Publisher' => { Name => 'Publisher', Writable => 'Unicode' }, # (multiple entries separated by semicolon)
|
418
|
+
'WM/SharedUserRating' => { Name => 'SharedUserRating', Writable => 'int64u' },
|
402
419
|
'WM/SubscriptionContentID' => 'SubscriptionContentID',
|
403
|
-
'WM/SubTitle' => 'Subtitle',
|
420
|
+
'WM/SubTitle' => { Name => 'Subtitle', Writable => 'Unicode' },
|
404
421
|
'WM/SubTitleDescription' => 'SubtitleDescription',
|
405
422
|
'WM/TrackNumber' => 'TrackNumber',
|
406
423
|
'WM/UniqueFileIdentifier' => 'UniqueFileIdentifier',
|
@@ -412,8 +429,11 @@ my %sRegions = (
|
|
412
429
|
'WM/WMContentID' => 'WMContentID',
|
413
430
|
'WM/WMShadowFileSourceDRMType' => 'WMShadowFileSourceDRMType',
|
414
431
|
'WM/WMShadowFileSourceFileType' => 'WMShadowFileSourceFileType',
|
415
|
-
'WM/Writer' => 'Writer',
|
416
|
-
'WM/Year' => { Name => 'Year',
|
432
|
+
'WM/Writer' => { Name => 'Writer', Groups => { 2 => 'Author' }, Writable => 'Unicode' }, # (NC)
|
433
|
+
'WM/Year' => { Name => 'Year', Groups => { 2 => 'Time' } },
|
434
|
+
'WM/PromotionURL' => { Name => 'PromotionURL',Writable => 'Unicode' },
|
435
|
+
'WM/AuthorURL' => { Name => 'AuthorURL', Groups => { 2 => 'Author' }, Writable => 'Unicode' },
|
436
|
+
'WM/EncodedBy', => { Name => 'EncodedBy', Writable => 'Unicode' },
|
417
437
|
|
418
438
|
# I can't find documentation for the following tags in videos,
|
419
439
|
# but the tag ID's correspond to Microsoft property GUID+ID's
|
@@ -422,9 +442,12 @@ my %sRegions = (
|
|
422
442
|
# http://multi-rename-script.googlecode.com/svn-history/r4/trunk/plugins/ShellDetails/ShellDetails.ini
|
423
443
|
# I have observed only 1 so far:
|
424
444
|
'{2CBAA8F5-D81F-47CA-B17A-F8D822300131} 100' => {
|
425
|
-
Name => 'DateAcquired',
|
445
|
+
Name => 'DateAcquired', # (seems to be when videos are downloaded from the camera)
|
426
446
|
Groups => { 2 => 'Time' },
|
447
|
+
Shift => 'Time',
|
448
|
+
Writable => 'vt_filetime',
|
427
449
|
PrintConv => '$self->ConvertDateTime($val)',
|
450
|
+
PrintConvInv => '$self->InverseDateTime($val,undef)',
|
428
451
|
},
|
429
452
|
# the following have not yet been observed...
|
430
453
|
'{B725F130-47EF-101A-A5F1-02608C9EEBAC} 10' => 'Name',
|
@@ -764,6 +787,245 @@ my %sRegions = (
|
|
764
787
|
'{64440491-4C8B-11D1-8B70-080036B11A03} 43' => 'TotalBitrate',
|
765
788
|
);
|
766
789
|
|
790
|
+
#------------------------------------------------------------------------------
|
791
|
+
# check new value for Xtra tag
|
792
|
+
# Inputs: 0) ExifTool object ref, 1) tagInfo hash ref, 2) raw value ref
|
793
|
+
# Returns: error string, or undef on success
|
794
|
+
sub CheckXtra($$$)
|
795
|
+
{
|
796
|
+
my ($et, $tagInfo, $valPt) = @_;
|
797
|
+
my $format = $$tagInfo{Writable};
|
798
|
+
return 'Unknown format' unless $format;
|
799
|
+
if ($format =~ /^int/) {
|
800
|
+
return 'Not an integer' unless Image::ExifTool::IsInt($$valPt);
|
801
|
+
} elsif ($format ne 'Unicode') {
|
802
|
+
my @vals = ($$valPt);
|
803
|
+
return 'Invalid format' unless WriteXtraValue($et, $tagInfo, \@vals);
|
804
|
+
}
|
805
|
+
return undef;
|
806
|
+
}
|
807
|
+
|
808
|
+
#------------------------------------------------------------------------------
|
809
|
+
# Decode value(s) in Microsoft Xtra tag
|
810
|
+
# Inputs: 0) ExifTool object ref, 1) value data
|
811
|
+
# Returns: Scalar context: decoded value, List context: 0) decoded value, 1) format string
|
812
|
+
sub ReadXtraValue($$)
|
813
|
+
{
|
814
|
+
my ($et, $data) = @_;
|
815
|
+
my ($format, $i, @vals);
|
816
|
+
|
817
|
+
return undef if length($data) < 10;
|
818
|
+
|
819
|
+
# (version flags according to the reference, but looks more like a count - PH)
|
820
|
+
my $count = Get32u(\$data, 0);
|
821
|
+
# point to start of first value (after 4-byte count, 4-byte length and 2-byte type)
|
822
|
+
my $valPos = 10;
|
823
|
+
for ($i=0; ;) {
|
824
|
+
# (stored value includes size of $valLen and $valType, so subtract 6)
|
825
|
+
my $valLen = Get32u(\$data, $valPos - 6) - 6;
|
826
|
+
last if $valPos + $valLen > length($data);
|
827
|
+
my $valType = Get16u(\$data, $valPos - 2);
|
828
|
+
my $val = substr($data, $valPos, $valLen);
|
829
|
+
# Note: all dumb Microsoft values are little-endian inside a big-endian-format file
|
830
|
+
SetByteOrder('II');
|
831
|
+
if ($valType == 8) {
|
832
|
+
$format = 'Unicode';
|
833
|
+
$val = $et->Decode($val, 'UCS2');
|
834
|
+
} elsif ($valType == 19 and $valLen == 8) {
|
835
|
+
$format = 'int64u';
|
836
|
+
$val = Get64u(\$val, 0);
|
837
|
+
} elsif ($valType == 21 and $valLen == 8) {
|
838
|
+
$format = 'date';
|
839
|
+
$val = Get64u(\$val, 0);
|
840
|
+
# convert time from 100 ns intervals since Jan 1, 1601
|
841
|
+
$val = $val * 1e-7 - 11644473600 if $val;
|
842
|
+
# (the Nikon S100 uses UTC timezone, same as ASF - PH)
|
843
|
+
$val = Image::ExifTool::ConvertUnixTime($val, 1);
|
844
|
+
} elsif ($valType == 72 and $valLen == 16) {
|
845
|
+
$format = 'GUID';
|
846
|
+
$val = uc unpack('H*',pack('NnnNN',unpack('VvvNN',$val)));
|
847
|
+
$val =~ s/(.{8})(.{4})(.{4})(.{4})/$1-$2-$3-$4-/;
|
848
|
+
} elsif ($valType == 65 and $valLen > 4) { #PH (empirical)
|
849
|
+
$format = 'variant';
|
850
|
+
require Image::ExifTool::FlashPix;
|
851
|
+
my $vPos = 0; # (necessary because ReadFPXValue updates this)
|
852
|
+
# read entry as a VT_VARIANT (use FlashPix module for this)
|
853
|
+
$val = Image::ExifTool::FlashPix::ReadFPXValue($et, \$val, $vPos,
|
854
|
+
Image::ExifTool::FlashPix::VT_VARIANT(), $valLen, 1);
|
855
|
+
} else {
|
856
|
+
$format = "Unknown($valType)";
|
857
|
+
}
|
858
|
+
SetByteOrder('MM'); # back to native QuickTime byte ordering
|
859
|
+
push @vals, $val;
|
860
|
+
last if ++$i >= $count;
|
861
|
+
$valPos += $valLen + 6; # step to next value
|
862
|
+
last if $valPos > length($data);
|
863
|
+
}
|
864
|
+
return wantarray ? (\@vals, $format) : \@vals;
|
865
|
+
}
|
866
|
+
|
867
|
+
#------------------------------------------------------------------------------
|
868
|
+
# Write a Microsoft Xtra value
|
869
|
+
# Inputs: 0) ExifTool object ref, 1) tagInfo ref, 2) reference to list of values
|
870
|
+
# Returns: new value binary data (or empty string)
|
871
|
+
sub WriteXtraValue($$$)
|
872
|
+
{
|
873
|
+
my ($et, $tagInfo, $vals) = @_;
|
874
|
+
my $format = $$tagInfo{Writable};
|
875
|
+
my $buff = '';
|
876
|
+
my $count = 0;
|
877
|
+
my $val;
|
878
|
+
foreach $val (@$vals) {
|
879
|
+
SetByteOrder('II');
|
880
|
+
my ($type, $dat);
|
881
|
+
if ($format eq 'Unicode') {
|
882
|
+
$dat = $et->Encode($val,'UCS2','II') . "\0\0"; # (must be null terminated)
|
883
|
+
$type = 8;
|
884
|
+
} elsif ($format eq 'int64u') {
|
885
|
+
if (Image::ExifTool::IsInt($val)) {
|
886
|
+
$dat = Set64u($val);
|
887
|
+
$type = 19;
|
888
|
+
}
|
889
|
+
} elsif ($format eq 'date') {
|
890
|
+
$dat = Image::ExifTool::GetUnixTime($val, 1); # (convert to UTC, NC)
|
891
|
+
if ($dat) {
|
892
|
+
# 100ns intervals since Jan 1, 1601
|
893
|
+
$dat = Set64u(($dat + 11644473600) * 1e7);
|
894
|
+
$type = 21;
|
895
|
+
}
|
896
|
+
} elsif ($format eq 'vt_filetime') { # 'date' value inside a VT_VARIANT
|
897
|
+
$dat = Image::ExifTool::GetUnixTime($val); # (leave as local time, NC)
|
898
|
+
if ($dat) {
|
899
|
+
# 100ns intervals since Jan 1, 1601
|
900
|
+
$dat = Set32u(64) . Set64u(($dat + 11644473600) * 1e7);
|
901
|
+
$type = 65;
|
902
|
+
}
|
903
|
+
} elsif ($format eq 'GUID') {
|
904
|
+
($dat = $val) =~ tr/-//d;
|
905
|
+
if (length($dat) == 32) {
|
906
|
+
$dat = pack('VvvNN',unpack('NnnNN',pack('H*', $dat)));
|
907
|
+
$type = 72;
|
908
|
+
}
|
909
|
+
} else {
|
910
|
+
$et->WarnOnce("Error converting value for Microsoft:$$tagInfo{Name}");
|
911
|
+
}
|
912
|
+
SetByteOrder('MM');
|
913
|
+
if (defined $type) {
|
914
|
+
++$count;
|
915
|
+
$buff .= Set32u(length($dat)+6) . Set16u($type) . $dat;
|
916
|
+
}
|
917
|
+
}
|
918
|
+
return $count ? Set32u($count) . $buff : '';
|
919
|
+
}
|
920
|
+
|
921
|
+
#------------------------------------------------------------------------------
|
922
|
+
# Add new values to list
|
923
|
+
# Inputs: 0) ExifTool ref, 1) new value list ref, 2) nvHash ref
|
924
|
+
# Returns: true if something was added
|
925
|
+
sub AddNewValues($$$)
|
926
|
+
{
|
927
|
+
my ($et, $vals, $nvHash) = @_;
|
928
|
+
my @newVals = $et->GetNewValue($nvHash) or return undef;
|
929
|
+
if ($$et{OPTIONS}{Verbose} > 1) {
|
930
|
+
$et->VPrint(1, " + Microsoft:$$nvHash{TagInfo}{Name} = $_\n") foreach @newVals;
|
931
|
+
}
|
932
|
+
push @$vals, @newVals;
|
933
|
+
return 1;
|
934
|
+
}
|
935
|
+
|
936
|
+
#------------------------------------------------------------------------------
|
937
|
+
# Write tags to a Microsoft Xtra MP4 atom
|
938
|
+
# Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref
|
939
|
+
# Returns: Microsoft Xtra data block (may be empty if no Xtra data) or undef on error
|
940
|
+
sub WriteXtra($$$)
|
941
|
+
{
|
942
|
+
my ($et, $dirInfo, $tagTablePtr) = @_;
|
943
|
+
$et or return 1; # allow dummy access
|
944
|
+
|
945
|
+
my $delGroup = ($$et{DEL_GROUP} and $$et{DEL_GROUP}{Microsoft});
|
946
|
+
my $newTags = $et->GetNewTagInfoHash($tagTablePtr);
|
947
|
+
|
948
|
+
return undef unless $delGroup or %$newTags; # don't rewrite if nothing to do
|
949
|
+
|
950
|
+
my $dataPt = $$dirInfo{DataPt};
|
951
|
+
my $dataLen = length $$dataPt;
|
952
|
+
my $newData = '';
|
953
|
+
my $pos = 0;
|
954
|
+
my ($err, %done, $changed, $tag);
|
955
|
+
|
956
|
+
if ($delGroup) {
|
957
|
+
$changed = 1 if $dataLen;
|
958
|
+
my $empty = '';
|
959
|
+
$dataPt = $empty;
|
960
|
+
$dataLen = 0;
|
961
|
+
}
|
962
|
+
for (;;) {
|
963
|
+
last if $pos + 4 > $dataLen;
|
964
|
+
my $size = Get32u($dataPt, $pos); # (includes $size word)
|
965
|
+
($size < 8 or $pos + $size > $dataLen) and $err=1, last;
|
966
|
+
my $tagLen = Get32u($dataPt, $pos + 4);
|
967
|
+
$tagLen + 18 > $size and $err=1, last;
|
968
|
+
$tag = substr($$dataPt, $pos + 8, $tagLen);
|
969
|
+
my @newVals;
|
970
|
+
while ($$newTags{$tag}) {
|
971
|
+
my $nvHash = $et->GetNewValueHash($$newTags{$tag});
|
972
|
+
$$nvHash{CreateOnly} and delete($$newTags{$tag}), last; # don't edit this tag
|
973
|
+
my $valPos = $pos + 8 + $tagLen;
|
974
|
+
my $valLen = $size - 8 - $tagLen;
|
975
|
+
my $val = ReadXtraValue($et, substr($$dataPt, $valPos, $valLen));
|
976
|
+
foreach $val (@$val) {
|
977
|
+
my $overwrite = $et->IsOverwriting($nvHash, $val);
|
978
|
+
$overwrite or push(@newVals, $val), next;
|
979
|
+
$et->VPrint(1, " - Microsoft:$$newTags{$tag}{Name} = $val\n");
|
980
|
+
next if $done{$tag};
|
981
|
+
$done{$tag} = 1;
|
982
|
+
AddNewValues($et, \@newVals, $nvHash);
|
983
|
+
}
|
984
|
+
# add to the end of the list if this was a List-type tag and we didn't delete anything
|
985
|
+
if (not $done{$tag} and $$newTags{$tag}{List}) {
|
986
|
+
AddNewValues($et, \@newVals, $nvHash) or last;
|
987
|
+
$done{$tag} = 1;
|
988
|
+
}
|
989
|
+
last; # (it was a cheap goto)
|
990
|
+
}
|
991
|
+
if ($done{$tag}) {
|
992
|
+
$changed = 1;
|
993
|
+
# write changed values
|
994
|
+
my $buff = WriteXtraValue($et, $$newTags{$tag}, \@newVals);
|
995
|
+
if (length $buff) {
|
996
|
+
$newData .= Set32u(8+length($tag)+length($buff)) . Set32u(length($tag)) . $tag . $buff;
|
997
|
+
}
|
998
|
+
} else {
|
999
|
+
# nothing changed; just copy over
|
1000
|
+
$newData .= substr($$dataPt, $pos, $size);
|
1001
|
+
}
|
1002
|
+
$pos += $size; # step to next entry
|
1003
|
+
}
|
1004
|
+
if ($err) {
|
1005
|
+
$et->Warn('Microsoft Xtra format error');
|
1006
|
+
return undef;
|
1007
|
+
}
|
1008
|
+
# add any new tags
|
1009
|
+
foreach $tag (sort keys %$newTags) {
|
1010
|
+
next if $done{$tag};
|
1011
|
+
my $nvHash = $et->GetNewValueHash($$newTags{$tag});
|
1012
|
+
next unless $$nvHash{IsCreating} and not $$nvHash{EditOnly};
|
1013
|
+
my @newVals;
|
1014
|
+
AddNewValues($et, \@newVals, $nvHash) or next;
|
1015
|
+
my $buff = WriteXtraValue($et, $$newTags{$tag}, \@newVals);
|
1016
|
+
if (length $buff) {
|
1017
|
+
$newData .= Set32u(8+length($tag)+length($buff)) . Set32u(length($tag)) . $tag . $buff;
|
1018
|
+
$changed = 1;
|
1019
|
+
}
|
1020
|
+
}
|
1021
|
+
if ($changed) {
|
1022
|
+
++$$et{CHANGED};
|
1023
|
+
} else {
|
1024
|
+
undef $newData;
|
1025
|
+
}
|
1026
|
+
return $newData;
|
1027
|
+
}
|
1028
|
+
|
767
1029
|
#------------------------------------------------------------------------------
|
768
1030
|
# Extract information from Xtra MP4 atom
|
769
1031
|
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
|
@@ -783,61 +1045,13 @@ sub ProcessXtra($$$)
|
|
783
1045
|
last if $size < 8 or $pos + $size > $dataLen;
|
784
1046
|
my $tagLen = Get32u($dataPt, $pos + 4);
|
785
1047
|
last if $tagLen + 18 > $size;
|
786
|
-
my $
|
787
|
-
# (version flags according to the reference, but looks more like a count - PH)
|
788
|
-
my $count = Get32u($dataPt, $pos + $tagLen + 8);
|
789
|
-
my ($i, $valPos, $valLen, $valType, $val, $format, @vals);
|
790
|
-
# point to start of first value (after 4-byte length and 2-byte type)
|
791
|
-
$valPos = $pos + $tagLen + 18;
|
792
|
-
for ($i=0; ;) {
|
793
|
-
# (stored value includes size of $valLen and $valType, so subtract 6)
|
794
|
-
$valLen = Get32u($dataPt, $valPos - 6) - 6;
|
795
|
-
my $more = $pos + $size - $valPos - $valLen;
|
796
|
-
last if $more < 0;
|
797
|
-
$valType = Get16u($dataPt, $valPos - 2);
|
798
|
-
$val = substr($$dataPt, $valPos, $valLen);
|
799
|
-
# Note: all dumb Microsoft values are little-endian inside a big-endian-format file
|
800
|
-
SetByteOrder('II');
|
801
|
-
if ($valType == 8) {
|
802
|
-
$format = 'Unicode';
|
803
|
-
$val = $et->Decode($val, 'UCS2');
|
804
|
-
} elsif ($valType == 19 and $valLen == 8) {
|
805
|
-
$format = 'int64u';
|
806
|
-
$val = Get64u(\$val, 0);
|
807
|
-
} elsif ($valType == 21 and $valLen == 8) {
|
808
|
-
$format = 'date';
|
809
|
-
$val = Get64u(\$val, 0);
|
810
|
-
# convert time from 100 ns intervals since Jan 1, 1601
|
811
|
-
$val = $val * 1e-7 - 11644473600 if $val;
|
812
|
-
# (the Nikon S100 uses UTC timezone, same as ASF - PH)
|
813
|
-
$val = Image::ExifTool::ConvertUnixTime($val) . 'Z';
|
814
|
-
} elsif ($valType == 72 and $valLen == 16) {
|
815
|
-
$format = 'GUID';
|
816
|
-
$val = uc unpack('H*',pack('NnnNN',unpack('VvvNN',$val)));
|
817
|
-
$val =~ s/(.{8})(.{4})(.{4})(.{4})/$1-$2-$3-$4-/;
|
818
|
-
} elsif ($valType == 65 && $valLen > 4) { #PH (empirical)
|
819
|
-
$format = 'variant';
|
820
|
-
require Image::ExifTool::FlashPix;
|
821
|
-
my $vPos = $valPos; # (necessary because ReadFPXValue updates this)
|
822
|
-
# read entry as a VT_VARIANT (use FlashPix module for this)
|
823
|
-
$val = Image::ExifTool::FlashPix::ReadFPXValue($et, $dataPt, $vPos,
|
824
|
-
Image::ExifTool::FlashPix::VT_VARIANT(), $valPos+$valLen, 1);
|
825
|
-
} else {
|
826
|
-
$format = "Unknown($valType)";
|
827
|
-
}
|
828
|
-
SetByteOrder('MM'); # back to native QuickTime byte ordering
|
829
|
-
last if ++$i >= $count or $more < 6;
|
830
|
-
push @vals, $val;
|
831
|
-
undef $val;
|
832
|
-
$valPos += $valLen + 6; # step to next value
|
833
|
-
}
|
834
|
-
if (@vals) {
|
835
|
-
push @vals, $val if defined $val;
|
836
|
-
$val = \@vals;
|
837
|
-
$valPos = $pos + $tagLen + 18;
|
838
|
-
$valLen = $size - 18 - $tagLen;
|
839
|
-
}
|
1048
|
+
my $valLen = $size - 8 - $tagLen;
|
840
1049
|
if ($tagLen > 0 and $valLen > 0) {
|
1050
|
+
my $tag = substr($$dataPt, $pos + 8, $tagLen);
|
1051
|
+
my $valPos = $pos + 8 + $tagLen;
|
1052
|
+
my ($val, $format) = ReadXtraValue($et, substr($$dataPt, $valPos, $valLen));
|
1053
|
+
last unless defined $val;
|
1054
|
+
$val = $$val[0] if @$val == 1;
|
841
1055
|
my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
|
842
1056
|
unless ($tagInfo) {
|
843
1057
|
# generate tag information for unrecognized tags
|
@@ -850,6 +1064,7 @@ sub ProcessXtra($$$)
|
|
850
1064
|
$et->VPrint(0, $$et{INDENT}, "[adding Microsoft:$tag]\n");
|
851
1065
|
}
|
852
1066
|
}
|
1067
|
+
my $count = ref $val ? scalar @$val : 1;
|
853
1068
|
$et->HandleTag($tagTablePtr, $tag, $val,
|
854
1069
|
TagInfo => $tagInfo,
|
855
1070
|
DataPt => $dataPt,
|
@@ -857,7 +1072,7 @@ sub ProcessXtra($$$)
|
|
857
1072
|
Start => $valPos,
|
858
1073
|
Size => $valLen,
|
859
1074
|
Format => $format,
|
860
|
-
Extra => " count=$count
|
1075
|
+
Extra => " count=$count",
|
861
1076
|
);
|
862
1077
|
}
|
863
1078
|
$pos += $size; # step to next entry
|
@@ -880,7 +1095,8 @@ This module is used by Image::ExifTool
|
|
880
1095
|
=head1 DESCRIPTION
|
881
1096
|
|
882
1097
|
This module contains definitions required by Image::ExifTool to interpret
|
883
|
-
Microsoft-specific EXIF and XMP tags
|
1098
|
+
Microsoft-specific EXIF and XMP tags, and routines to read/write Microsoft
|
1099
|
+
Xtra tags in videos.
|
884
1100
|
|
885
1101
|
=head1 AUTHOR
|
886
1102
|
|
@@ -62,7 +62,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
62
62
|
use Image::ExifTool::Exif;
|
63
63
|
use Image::ExifTool::GPS;
|
64
64
|
|
65
|
-
$VERSION = '
|
65
|
+
$VERSION = '4.00';
|
66
66
|
|
67
67
|
sub LensIDConv($$$);
|
68
68
|
sub ProcessNikonAVI($$$);
|
@@ -272,6 +272,7 @@ sub GetAFPointGrid($$;$);
|
|
272
272
|
'9F 58 44 44 14 14 A1 06' => 'AF-S DX Nikkor 35mm f/1.8G', #27
|
273
273
|
'A0 54 50 50 0C 0C A2 06' => 'AF-S Nikkor 50mm f/1.4G',
|
274
274
|
'A1 40 18 37 2C 34 A3 06' => 'AF-S DX Nikkor 10-24mm f/3.5-4.5G ED',
|
275
|
+
'A1 40 2D 53 2C 3C CB 86' => 'AF-P DX Nikkor 18-55mm f/3.5-5.6G', #30
|
275
276
|
'A2 48 5C 80 24 24 A4 0E' => 'AF-S Nikkor 70-200mm f/2.8G ED VR II',
|
276
277
|
'A3 3C 29 44 30 30 A5 0E' => 'AF-S Nikkor 16-35mm f/4G ED VR',
|
277
278
|
'A4 54 37 37 0C 0C A6 06' => 'AF-S Nikkor 24mm f/1.4G ED',
|
@@ -495,6 +496,7 @@ sub GetAFPointGrid($$;$);
|
|
495
496
|
'02 46 5C 82 25 25 02 00' => 'Sigma 70-210mm F2.8 APO', #JD
|
496
497
|
'02 40 5C 82 2C 35 02 00' => 'Sigma APO 70-210mm F3.5-4.5',
|
497
498
|
'26 3C 5C 82 30 3C 1C 02' => 'Sigma 70-210mm F4-5.6 UC-II',
|
499
|
+
'02 3B 5C 82 30 3C 02 00' => 'Sigma Zoom-K 70-210mm F4-5.6', #30
|
498
500
|
'26 3C 5C 8E 30 3C 1C 02' => 'Sigma 70-300mm F4-5.6 DG Macro',
|
499
501
|
'56 3C 5C 8E 30 3C 1C 02' => 'Sigma 70-300mm F4-5.6 APO Macro Super II',
|
500
502
|
'E0 3C 5C 8E 30 3C 4B 06' => 'Sigma 70-300mm F4-5.6 APO DG Macro HSM', #22
|
@@ -554,6 +556,7 @@ sub GetAFPointGrid($$;$);
|
|
554
556
|
'F3 54 2B 50 24 24 84 0E' => 'Tamron SP AF 17-50mm f/2.8 XR Di II VC LD Aspherical (IF) (B005)',
|
555
557
|
'00 3F 2D 80 2B 40 00 06' => 'Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) (A14)',
|
556
558
|
'00 3F 2D 80 2C 40 00 06' => 'Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro (A14)',
|
559
|
+
'EC 3E 3C 8E 2C 40 DF 0E' => 'Tamron 28-300mm f/3.5-6.3 Di VC PZD A010', #30
|
557
560
|
'00 40 2D 80 2C 40 00 06' => 'Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro (A14NII)', #NJ
|
558
561
|
'FC 40 2D 80 2C 40 DF 06' => 'Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro (A14NII)', #PH (NC)
|
559
562
|
'E6 40 2D 80 2C 40 DF 0E' => 'Tamron 18-200mm f/3.5-6.3 Di II VC (B018)', #Tanel (removed AF designation, ref 37)
|
@@ -563,7 +566,7 @@ sub GetAFPointGrid($$;$);
|
|
563
566
|
'F0 3F 2D 8A 2C 40 DF 0E' => 'Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD (B008)',
|
564
567
|
'E0 40 2D 98 2C 41 DF 4E' => 'Tamron 18-400mm f/3.5-6.3 Di II VC HLD (B028)', # (removed AF designation, ref 37)
|
565
568
|
'07 40 2F 44 2C 34 03 02' => 'Tamron AF 19-35mm f/3.5-4.5 (A10)',
|
566
|
-
'07 40 30 45 2D 35 03 02' => 'Tamron AF 19-35mm f/3.5-4.5 (A10)',
|
569
|
+
'07 40 30 45 2D 35 03 02.1' => 'Tamron AF 19-35mm f/3.5-4.5 (A10)',
|
567
570
|
'00 49 30 48 22 2B 00 02' => 'Tamron SP AF 20-40mm f/2.7-3.5 (166D)',
|
568
571
|
'0E 4A 31 48 23 2D 0E 02' => 'Tamron SP AF 20-40mm f/2.7-3.5 (166D)',
|
569
572
|
'FE 48 37 5C 24 24 DF 0E' => 'Tamron SP 24-70mm f/2.8 Di VC USD (A007)', #24
|
@@ -595,6 +598,7 @@ sub GetAFPointGrid($$;$);
|
|
595
598
|
'00 48 5C 8E 30 3C 00 06' => 'Tamron AF 70-300mm f/4-5.6 Di LD Macro 1:2 (A17NII)', #JD
|
596
599
|
'F1 47 5C 8E 30 3C DF 0E' => 'Tamron SP 70-300mm f/4-5.6 Di VC USD (A005)',
|
597
600
|
'CF 47 5C 8E 31 3D DF 0E' => 'Tamron SP 70-300mm f/4-5.6 Di VC USD (A030)', #forum9773
|
601
|
+
'CC 44 68 98 34 41 DF 0E' => 'Tamron 100-400mm f/4.5-6.3 Di VC USD', #30
|
598
602
|
'EB 40 76 A6 38 40 DF 0E' => 'Tamron SP AF 150-600mm f/5-6.3 VC USD (A011)',
|
599
603
|
'E3 40 76 A6 38 40 DF 4E' => 'Tamron SP 150-600mm f/5-6.3 Di VC USD G2', #30
|
600
604
|
'20 3C 80 98 3D 3D 1E 02' => 'Tamron AF 200-400mm f/5.6 LD IF (75D)',
|
@@ -612,6 +616,7 @@ sub GetAFPointGrid($$;$);
|
|
612
616
|
'7A 48 1C 29 24 24 7E 06' => 'Tokina AT-X 116 PRO DX II (AF 11-16mm f/2.8)',
|
613
617
|
'80 48 1C 29 24 24 7A 06' => 'Tokina atx-i 11-16mm F2.8 CF', #exiv2 issue 1078
|
614
618
|
'7A 48 1C 30 24 24 7E 06' => 'Tokina AT-X 11-20 F2.8 PRO DX (AF 11-20mm f/2.8)',
|
619
|
+
'8B 48 1C 30 24 24 85 06' => 'Tokina AT-X 11-20 F2.8 PRO DX (AF 11-20mm f/2.8)', #forum12687
|
615
620
|
'00 3C 1F 37 30 30 00 06' => 'Tokina AT-X 124 AF PRO DX (AF 12-24mm f/4)',
|
616
621
|
'7A 3C 1F 37 30 30 7E 06.2' => 'Tokina AT-X 124 AF PRO DX II (AF 12-24mm f/4)',
|
617
622
|
'7A 3C 1F 3C 30 30 7E 06' => 'Tokina AT-X 12-28 PRO DX (AF 12-28mm f/4)',
|
@@ -640,6 +645,7 @@ sub GetAFPointGrid($$;$);
|
|
640
645
|
'24 44 60 98 34 3C 1A 02' => 'Tokina AT-X 840 AF-II (AF 80-400mm f/4.5-5.6)',
|
641
646
|
'00 44 60 98 34 3C 00 02' => 'Tokina AT-X 840 D (AF 80-400mm f/4.5-5.6)',
|
642
647
|
'14 48 68 8E 30 30 0B 00' => 'Tokina AT-X 340 AF (AF 100-300mm f/4)',
|
648
|
+
'8C 48 29 3C 24 24 86 06' => 'Tokina opera 16-28mm F2.8 FF', #30
|
643
649
|
#
|
644
650
|
'06 3F 68 68 2C 2C 06 00' => 'Cosina AF 100mm F3.5 Macro',
|
645
651
|
'07 36 3D 5F 2C 3C 03 00' => 'Cosina AF Zoom 28-80mm F3.5-5.6 MC Macro',
|
@@ -655,6 +661,7 @@ sub GetAFPointGrid($$;$);
|
|
655
661
|
'00 54 48 48 18 18 00 00' => 'Voigtlander Ultron 40mm F2 SLII Aspherical',
|
656
662
|
'00 54 55 55 0C 0C 00 00' => 'Voigtlander Nokton 58mm F1.4 SLII',
|
657
663
|
'00 40 64 64 2C 2C 00 00' => 'Voigtlander APO-Lanthar 90mm F3.5 SLII Close Focus',
|
664
|
+
'07 40 30 45 2D 35 03 02.2' => 'Voigtlander Ultragon 19-35mm F3.5-4.5 VMV', #NJ
|
658
665
|
#
|
659
666
|
'00 40 2D 2D 2C 2C 00 00' => 'Carl Zeiss Distagon T* 3.5/18 ZF.2',
|
660
667
|
'00 48 27 27 24 24 00 00' => 'Carl Zeiss Distagon T* 2.8/15 ZF.2', #MykytaKozlov
|
@@ -716,6 +723,9 @@ sub GetAFPointGrid($$;$);
|
|
716
723
|
'00 40 11 11 2C 2C 00 00' => 'Samyang 8mm f/3.5 Fish-Eye',
|
717
724
|
'00 58 64 64 20 20 00 00' => 'Soligor C/D Macro MC 90mm f/2.5',
|
718
725
|
'4A 58 30 30 14 0C 4D 02' => 'Rokinon 20mm f/1.8 ED AS UMC', #30
|
726
|
+
#
|
727
|
+
'A0 56 44 44 14 14 A2 06' => 'Sony FE 35mm F1.8', #IB (Techart adapter)
|
728
|
+
'A0 37 5C 8E 34 3C A2 06' => 'Sony FE 70-300mm F4.5-5.6 G OSS', #IB (Techart adapter)
|
719
729
|
);
|
720
730
|
|
721
731
|
# text encoding used in LocationInfo (ref PH)
|
@@ -4718,6 +4728,9 @@ my %nikonFocalConversions = (
|
|
4718
4728
|
21 => 'Nikkor Z 50mm f/1.2 S', #IB
|
4719
4729
|
22 => 'Nikkor Z 24-50mm f/4-6.3', #IB
|
4720
4730
|
23 => 'Nikkor Z 14-24mm f/2.8 S', #IB
|
4731
|
+
24 => 'Nikkor Z MC 105mm f/2.8 VR S', #IB
|
4732
|
+
27 => 'Nikkor Z MC 50mm f/2.8', #IB
|
4733
|
+
29 => 'Nikkor Z 28mm f/2.8', #IB
|
4721
4734
|
},
|
4722
4735
|
},
|
4723
4736
|
0x36 => {
|
@@ -8490,8 +8503,8 @@ my %nikonFocalConversions = (
|
|
8490
8503
|
# 0x02 - undef[148]
|
8491
8504
|
# 0x03 - undef[284]
|
8492
8505
|
# 0x04 - undef[148,212]
|
8493
|
-
# 0x05 - undef[84]
|
8494
|
-
# 0x06 - undef[116]
|
8506
|
+
# 0x05 - undef[84] (barrel distortion params at offsets 0x14,0x1c,0x24, ref 28)
|
8507
|
+
# 0x06 - undef[116] (vignette correction params at offsets 0x24,0x34,0x44, ref 28)
|
8495
8508
|
# 0x07 - undef[104]
|
8496
8509
|
# 0x08 - undef[24]
|
8497
8510
|
# 0x09 - undef[36]
|
@@ -9466,7 +9479,7 @@ sub GetAFPointGrid($$;$)
|
|
9466
9479
|
return undef unless $val =~ /^([A-J])(\d+)$/i;
|
9467
9480
|
return (ord(uc($1))-65) * $ncol + $2 - 1;
|
9468
9481
|
} else {
|
9469
|
-
my $row = int(($val + 0.5) / $ncol);
|
9482
|
+
my $row = int(($val + 0.5) / $ncol) & 0xff;
|
9470
9483
|
my $col = $val - $ncol * $row + 1;
|
9471
9484
|
return chr(65+$row) . $col;
|
9472
9485
|
}
|
@@ -9945,12 +9958,10 @@ sub PrescanExif($$$)
|
|
9945
9958
|
$dataLen = length $data;
|
9946
9959
|
$dirStart = 0;
|
9947
9960
|
}
|
9948
|
-
# loop through
|
9949
|
-
my ($lastTag) = sort { $b <=> $a } keys %$tagHash; # (reverse sort)
|
9961
|
+
# loop through Nikon MakerNote IFD entries
|
9950
9962
|
for ($index=0; $index<$numEntries; ++$index) {
|
9951
9963
|
my $entry = $dirStart + 2 + 12 * $index;
|
9952
9964
|
my $tagID = Get16u($dataPt, $entry);
|
9953
|
-
last if $tagID > $lastTag; # (assuming tags are in order)
|
9954
9965
|
next unless exists $$tagHash{$tagID}; # only extract required tags
|
9955
9966
|
my $format = Get16u($dataPt, $entry+2);
|
9956
9967
|
next if $format < 1 or $format > 13;
|