exiftool_vendored 12.98.0 → 13.02.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 +73 -1
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/arg_files/exif2xmp.args +4 -0
- data/bin/arg_files/xmp2exif.args +4 -0
- data/bin/config_files/example.config +2 -1
- data/bin/exiftool +297 -66
- data/bin/lib/Image/ExifTool/APP12.pm +3 -2
- data/bin/lib/Image/ExifTool/CBOR.pm +4 -1
- data/bin/lib/Image/ExifTool/Canon.pm +36 -26
- data/bin/lib/Image/ExifTool/Exif.pm +8 -9
- data/bin/lib/Image/ExifTool/FlashPix.pm +5 -9
- data/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
- data/bin/lib/Image/ExifTool/Geotag.pm +6 -5
- data/bin/lib/Image/ExifTool/GoPro.pm +2 -2
- data/bin/lib/Image/ExifTool/Import.pm +7 -3
- data/bin/lib/Image/ExifTool/JSON.pm +3 -4
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +2 -2
- data/bin/lib/Image/ExifTool/LNK.pm +1 -1
- data/bin/lib/Image/ExifTool/Lytro.pm +2 -2
- data/bin/lib/Image/ExifTool/M2TS.pm +2 -2
- data/bin/lib/Image/ExifTool/MIE.pm +9 -3
- data/bin/lib/Image/ExifTool/MacOS.pm +2 -1
- data/bin/lib/Image/ExifTool/Nikon.pm +5 -2
- data/bin/lib/Image/ExifTool/PDF.pm +7 -3
- data/bin/lib/Image/ExifTool/PhaseOne.pm +2 -1
- data/bin/lib/Image/ExifTool/QuickTime.pm +11 -1
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +88 -9
- data/bin/lib/Image/ExifTool/TagLookup.pm +14 -9
- data/bin/lib/Image/ExifTool/TagNames.pod +37 -20
- data/bin/lib/Image/ExifTool/Text.pm +3 -2
- data/bin/lib/Image/ExifTool/Validate.pm +2 -2
- data/bin/lib/Image/ExifTool/WriteXMP.pl +16 -4
- data/bin/lib/Image/ExifTool/Writer.pl +42 -61
- data/bin/lib/Image/ExifTool/XMP.pm +13 -3
- data/bin/lib/Image/ExifTool/XMPStruct.pl +16 -9
- data/bin/lib/Image/ExifTool.pm +190 -77
- data/bin/lib/Image/ExifTool.pod +73 -36
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +2 -2
@@ -14,7 +14,7 @@ use strict;
|
|
14
14
|
use vars qw($VERSION);
|
15
15
|
use Image::ExifTool qw(:DataAccess :Utils);
|
16
16
|
|
17
|
-
$VERSION = '1.
|
17
|
+
$VERSION = '1.14';
|
18
18
|
|
19
19
|
sub ProcessAPP12($$$);
|
20
20
|
sub ProcessDucky($$$);
|
@@ -72,7 +72,7 @@ sub WriteDucky($$$);
|
|
72
72
|
StrobeTime => { },
|
73
73
|
Resolution => { },
|
74
74
|
Protect => { },
|
75
|
-
|
75
|
+
ContTake => { },
|
76
76
|
ImageSize => { PrintConv => '$val=~tr/-/x/;$val' },
|
77
77
|
ColorMode => { },
|
78
78
|
Zoom => { },
|
@@ -278,6 +278,7 @@ sub ProcessAPP12($$$)
|
|
278
278
|
$tagInfo = { Name => ucfirst $tag };
|
279
279
|
# put in Camera group if information in "Camera" section
|
280
280
|
$$tagInfo{Groups} = { 2 => 'Camera' } if $section =~ /camera/i;
|
281
|
+
$et->VPrint(0, $$et{INDENT}, "[adding APP12:$$tagInfo{Name}]\n");
|
281
282
|
AddTagToTable($tagTablePtr, $tag, $tagInfo);
|
282
283
|
}
|
283
284
|
$et->FoundTag($tagInfo, $val);
|
@@ -16,7 +16,7 @@ use vars qw($VERSION);
|
|
16
16
|
use Image::ExifTool qw(:DataAccess :Utils);
|
17
17
|
use Image::ExifTool::JSON;
|
18
18
|
|
19
|
-
$VERSION = '1.
|
19
|
+
$VERSION = '1.03';
|
20
20
|
|
21
21
|
sub ProcessCBOR($$$);
|
22
22
|
sub ReadCBORValue($$$$);
|
@@ -160,6 +160,7 @@ sub ReadCBORValue($$$$)
|
|
160
160
|
Start => $dumpStart,
|
161
161
|
DataPos => $$et{cbor_datapos},
|
162
162
|
Prefix => $$et{INDENT},
|
163
|
+
Out => $et->Options('TextOut'),
|
163
164
|
) if $verbose > 2;
|
164
165
|
while ($num) {
|
165
166
|
$$et{cbor_pre} = "$i) ";
|
@@ -200,6 +201,7 @@ sub ReadCBORValue($$$$)
|
|
200
201
|
Start => $dumpStart,
|
201
202
|
DataPos => $$et{cbor_datapos},
|
202
203
|
Prefix => $$et{INDENT} . ' ',
|
204
|
+
Out => $et->Options('TextOut'),
|
203
205
|
) if $verbose > 2;
|
204
206
|
}
|
205
207
|
# read next value (note: in the case of multiple tags,
|
@@ -259,6 +261,7 @@ sub ReadCBORValue($$$$)
|
|
259
261
|
DataPos => $$et{cbor_datapos},
|
260
262
|
Prefix => $$et{INDENT} . ' ',
|
261
263
|
MaxLen => $verbose < 5 ? ($verbose == 3 ? 96 : 2048) : undef,
|
264
|
+
Out => $et->Options('TextOut'),
|
262
265
|
) if $verbose > 2;
|
263
266
|
return($val, $err, $pos);
|
264
267
|
}
|
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
|
|
88
88
|
sub ProcessExifInfo($$$);
|
89
89
|
sub SwapWords($);
|
90
90
|
|
91
|
-
$VERSION = '4.
|
91
|
+
$VERSION = '4.84';
|
92
92
|
|
93
93
|
# Note: Removed 'USM' from 'L' lenses since it is redundant - PH
|
94
94
|
# (or is it? Ref 32 shows 5 non-USM L-type lenses)
|
@@ -6999,6 +6999,7 @@ my %ciMaxFocal = (
|
|
6999
6999
|
314 => 'Canon RF 24-105mm F2.8 L IS USM Z', #42
|
7000
7000
|
315 => 'Canon RF-S 10-18mm F4.5-6.3 IS STM', #42
|
7001
7001
|
316 => 'Canon RF 35mm F1.4 L VCM', #42
|
7002
|
+
317 => 'Canon RF-S 3.9mm F3.5 STM DUAL FISHEYE', #42
|
7002
7003
|
318 => 'Canon RF 28-70mm F2.8 IS STM', #42
|
7003
7004
|
# Note: add new RF lenses to %canonLensTypes with ID 61182
|
7004
7005
|
},
|
@@ -9829,35 +9830,39 @@ sub LensWithTC($$)
|
|
9829
9830
|
|
9830
9831
|
#------------------------------------------------------------------------------
|
9831
9832
|
# Attempt to calculate sensor size for Canon cameras
|
9832
|
-
# Inputs: 0
|
9833
|
+
# Inputs: 0) ExifTool ref
|
9833
9834
|
# Returns: Sensor diagonal size in mm, or undef
|
9834
9835
|
# Notes: This algorithm is fairly reliable, but has been found to give incorrect
|
9835
9836
|
# values for some firmware versions of the EOS 20D, A310, SD40 and IXUS 65
|
9836
9837
|
# (ref http://wyw.dcweb.cn/download.asp?path=&file=jhead-2.96-ccdwidth_hack.zip)
|
9837
|
-
sub CalcSensorDiag(
|
9838
|
+
sub CalcSensorDiag($)
|
9838
9839
|
{
|
9839
|
-
my
|
9840
|
-
#
|
9841
|
-
|
9842
|
-
|
9843
|
-
|
9844
|
-
|
9845
|
-
|
9846
|
-
|
9847
|
-
|
9848
|
-
|
9849
|
-
|
9850
|
-
|
9851
|
-
|
9852
|
-
|
9853
|
-
|
9854
|
-
|
9855
|
-
|
9856
|
-
|
9857
|
-
|
9858
|
-
|
9859
|
-
|
9860
|
-
|
9840
|
+
my $et = shift;
|
9841
|
+
# calculation is based on the rational value of FocalPlaneX/YResolution
|
9842
|
+
# (most Canon cameras store the sensor size in the denominator)
|
9843
|
+
return undef unless $$et{TAG_EXTRA}{FocalPlaneXResolution} and
|
9844
|
+
$$et{TAG_EXTRA}{FocalPlaneYResolution};
|
9845
|
+
my $xres = $$et{TAG_EXTRA}{FocalPlaneXResolution}{Rational};
|
9846
|
+
my $yres = $$et{TAG_EXTRA}{FocalPlaneYResolution}{Rational};
|
9847
|
+
return undef unless $xres and $yres;
|
9848
|
+
# assumptions: 1) numerators are image width/height * 1000
|
9849
|
+
# 2) denominators are sensor width/height in inches * 1000
|
9850
|
+
my @xres = split /[ \/]/, $xres;
|
9851
|
+
my @yres = split /[ \/]/, $yres;
|
9852
|
+
# verify assumptions as best we can:
|
9853
|
+
# numerators are always divisible by 1000
|
9854
|
+
if ($xres[0] % 1000 == 0 and $yres[0] % 1000 == 0 and
|
9855
|
+
# at least 640x480 pixels (DC models - PH)
|
9856
|
+
$xres[0] >= 640000 and $yres[0] >= 480000 and
|
9857
|
+
# ... but not too big!
|
9858
|
+
$xres[0] < 10000000 and $yres[0] < 10000000 and
|
9859
|
+
# minimum sensor size is 0.061 inches (DC models - PH)
|
9860
|
+
$xres[1] >= 61 and $xres[1] < 1500 and
|
9861
|
+
$yres[1] >= 61 and $yres[1] < 1000 and
|
9862
|
+
# sensor isn't square (may happen if rationals have been reduced)
|
9863
|
+
$xres[1] != $yres[1])
|
9864
|
+
{
|
9865
|
+
return sqrt($xres[1]*$xres[1] + $yres[1]*$yres[1]) * 0.0254;
|
9861
9866
|
}
|
9862
9867
|
return undef;
|
9863
9868
|
}
|
@@ -10250,7 +10255,11 @@ sub ProcessSerialData($$$)
|
|
10250
10255
|
$et->ProcessDirectory(\%dirInfo, $subTablePtr);
|
10251
10256
|
} elsif (not $$tagInfo{Unknown} or $unknown) {
|
10252
10257
|
# don't extract zero-length information
|
10253
|
-
$et->FoundTag($tagInfo, $val) if $count;
|
10258
|
+
my $key = $et->FoundTag($tagInfo, $val) if $count;
|
10259
|
+
if ($key) {
|
10260
|
+
$$et{TAG_EXTRA}{$key}{G6} = $format if $$et{OPTIONS}{SaveFormat};
|
10261
|
+
$$et{TAG_EXTRA}{$key}{BinVal} = substr($$dataPt, $pos+$offset, $len) if $$et{OPTIONS}{SaveBin};
|
10262
|
+
}
|
10254
10263
|
}
|
10255
10264
|
$pos += $len;
|
10256
10265
|
}
|
@@ -10447,6 +10456,7 @@ sub ProcessCTMD($$$)
|
|
10447
10456
|
Start => $pos + 6,
|
10448
10457
|
Addr => $$dirInfo{Base} + $pos + 6,
|
10449
10458
|
Prefix => $$et{INDENT},
|
10459
|
+
Out => $et->Options('TextOut'),
|
10450
10460
|
) if $verbose > 2;
|
10451
10461
|
if ($$tagTablePtr{$type}) {
|
10452
10462
|
$et->HandleTag($tagTablePtr, $type, undef,
|
@@ -57,7 +57,7 @@ use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat
|
|
57
57
|
use Image::ExifTool qw(:DataAccess :Utils);
|
58
58
|
use Image::ExifTool::MakerNotes;
|
59
59
|
|
60
|
-
$VERSION = '4.
|
60
|
+
$VERSION = '4.53';
|
61
61
|
|
62
62
|
sub ProcessExif($$$);
|
63
63
|
sub WriteExif($$$);
|
@@ -2931,7 +2931,7 @@ my %opcodeInfo = (
|
|
2931
2931
|
0xa433 => { Name => 'LensMake', Writable => 'string' }, #24
|
2932
2932
|
0xa434 => { Name => 'LensModel', Writable => 'string' }, #24
|
2933
2933
|
0xa435 => { Name => 'LensSerialNumber', Writable => 'string' }, #24
|
2934
|
-
0xa436 => { Name => '
|
2934
|
+
0xa436 => { Name => 'ImageTitle', Writable => 'string' }, #33
|
2935
2935
|
0xa437 => { Name => 'Photographer', Writable => 'string' }, #33
|
2936
2936
|
0xa438 => { Name => 'ImageEditor', Writable => 'string' }, #33
|
2937
2937
|
0xa439 => { Name => 'CameraFirmware', Writable => 'string' }, #33
|
@@ -5346,10 +5346,7 @@ sub CalcScaleFactor35efl
|
|
5346
5346
|
# calculate Canon sensor size using a dedicated algorithm
|
5347
5347
|
if ($$et{Make} eq 'Canon') {
|
5348
5348
|
require Image::ExifTool::Canon;
|
5349
|
-
my $canonDiag = Image::ExifTool::Canon::CalcSensorDiag(
|
5350
|
-
$$et{RATIONAL}{FocalPlaneXResolution},
|
5351
|
-
$$et{RATIONAL}{FocalPlaneYResolution},
|
5352
|
-
);
|
5349
|
+
my $canonDiag = Image::ExifTool::Canon::CalcSensorDiag($et);
|
5353
5350
|
$diag = $canonDiag if $canonDiag;
|
5354
5351
|
}
|
5355
5352
|
unless ($diag and Image::ExifTool::IsFloat($diag)) {
|
@@ -6171,7 +6168,7 @@ sub ProcessExif($$$)
|
|
6171
6168
|
my $base = $$dirInfo{Base} || 0;
|
6172
6169
|
my $firstBase = $base;
|
6173
6170
|
my $raf = $$dirInfo{RAF};
|
6174
|
-
my ($verbose,$validate,$saveFormat) = @{$$et{OPTIONS}}{qw(Verbose Validate SaveFormat)};
|
6171
|
+
my ($verbose,$validate,$saveFormat,$saveBin) = @{$$et{OPTIONS}}{qw(Verbose Validate SaveFormat SaveBin)};
|
6175
6172
|
my $htmlDump = $$et{HTML_DUMP};
|
6176
6173
|
my $success = 1;
|
6177
6174
|
my ($tagKey, $dirSize, $makerAddr, $strEnc, %offsetInfo, $offName, $nextOffName, $doHash);
|
@@ -6361,7 +6358,7 @@ sub ProcessExif($$$)
|
|
6361
6358
|
my $valueDataLen = $dataLen;
|
6362
6359
|
my $valuePtr = $entry + 8; # pointer to value within $$dataPt
|
6363
6360
|
my $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID);
|
6364
|
-
my ($origFormStr, $bad, $rational, $subOffName);
|
6361
|
+
my ($origFormStr, $bad, $rational, $binVal, $subOffName);
|
6365
6362
|
# save the EXIF format codes if requested
|
6366
6363
|
$$et{SaveFormat}{$saveFormat = $formatStr} = 1 if $saveFormat;
|
6367
6364
|
# hack to patch incorrect count in Kodak SubIFD3 tags
|
@@ -6658,6 +6655,7 @@ sub ProcessExif($$$)
|
|
6658
6655
|
} else {
|
6659
6656
|
# convert according to specified format
|
6660
6657
|
$val = ReadValue($valueDataPt,$valuePtr,$formatStr,$count,$readSize,\$rational);
|
6658
|
+
$binVal = substr($$valueDataPt,$valuePtr,$readSize) if $saveBin;
|
6661
6659
|
# re-code if necessary
|
6662
6660
|
if (defined $val) {
|
6663
6661
|
if ($formatStr eq 'utf8') {
|
@@ -7055,7 +7053,8 @@ sub ProcessExif($$$)
|
|
7055
7053
|
# set the group 1 name for tags in specified tables
|
7056
7054
|
$et->SetGroup($tagKey, $dirName) if $$tagTablePtr{SET_GROUP1};
|
7057
7055
|
# save original components of rational numbers (used when copying)
|
7058
|
-
$$et{
|
7056
|
+
$$et{TAG_EXTRA}{$tagKey}{Rational} = $rational if defined $rational;
|
7057
|
+
$$et{TAG_EXTRA}{$tagKey}{BinVal} = $binVal if defined $binVal;
|
7059
7058
|
$$et{TAG_EXTRA}{$tagKey}{G6} = $saveFormat if $saveFormat;
|
7060
7059
|
if ($$et{MAKER_NOTE_FIXUP}) {
|
7061
7060
|
$$et{TAG_EXTRA}{$tagKey}{Fixup} = $$et{MAKER_NOTE_FIXUP};
|
@@ -22,7 +22,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
22
22
|
use Image::ExifTool::Exif;
|
23
23
|
use Image::ExifTool::ASF; # for GetGUID()
|
24
24
|
|
25
|
-
$VERSION = '1.
|
25
|
+
$VERSION = '1.49';
|
26
26
|
|
27
27
|
sub ProcessFPX($$);
|
28
28
|
sub ProcessFPXR($$$);
|
@@ -1717,16 +1717,14 @@ sub ProcessDocumentTable($)
|
|
1717
1717
|
my $offsets = $$value{$key};
|
1718
1718
|
last unless defined $offsets;
|
1719
1719
|
my $doc;
|
1720
|
-
$doc = $$extra{$key}{G3}
|
1721
|
-
$doc = '' unless $doc;
|
1720
|
+
$doc = $$extra{$key}{G3} || '';
|
1722
1721
|
# get DocFlags for this sub-document
|
1723
1722
|
my ($docFlags, $docTable);
|
1724
1723
|
for ($j=0; ; ++$j) {
|
1725
1724
|
my $key = 'DocFlags' . ($j ? " ($j)" : '');
|
1726
1725
|
last unless defined $$value{$key};
|
1727
1726
|
my $tmp;
|
1728
|
-
$tmp = $$extra{$key}{G3}
|
1729
|
-
$tmp = '' unless $tmp;
|
1727
|
+
$tmp = $$extra{$key}{G3} || '';
|
1730
1728
|
if ($tmp eq $doc) {
|
1731
1729
|
$docFlags = $$value{$key};
|
1732
1730
|
last;
|
@@ -1739,8 +1737,7 @@ sub ProcessDocumentTable($)
|
|
1739
1737
|
my $key = $tag . ($j ? " ($j)" : '');
|
1740
1738
|
last unless defined $$value{$key};
|
1741
1739
|
my $tmp;
|
1742
|
-
$tmp = $$extra{$key}{G3}
|
1743
|
-
$tmp = '' unless $tmp;
|
1740
|
+
$tmp = $$extra{$key}{G3} || '';
|
1744
1741
|
if ($tmp eq $doc) {
|
1745
1742
|
$docTable = \$$value{$key};
|
1746
1743
|
last;
|
@@ -2505,8 +2502,7 @@ sub ProcessFPX($$)
|
|
2505
2502
|
for ($copy=1; ;++$copy) {
|
2506
2503
|
my $key = "$tag ($copy)";
|
2507
2504
|
last unless defined $$et{VALUE}{$key};
|
2508
|
-
|
2509
|
-
next if $extra and $$extra{G3}; # not Main if family 3 group is set
|
2505
|
+
next if $$et{TAG_EXTRA}{$key}{G3}; # not Main if family 3 group is set
|
2510
2506
|
foreach $member ('PRIORITY','VALUE','FILE_ORDER','TAG_INFO','TAG_EXTRA') {
|
2511
2507
|
my $pHash = $$et{$member};
|
2512
2508
|
my $t = $$pHash{$tag};
|
Binary file
|
@@ -31,7 +31,7 @@ use vars qw($VERSION);
|
|
31
31
|
use Image::ExifTool qw(:Public);
|
32
32
|
use Image::ExifTool::GPS;
|
33
33
|
|
34
|
-
$VERSION = '1.
|
34
|
+
$VERSION = '1.80';
|
35
35
|
|
36
36
|
sub JITTER() { return 2 } # maximum time jitter
|
37
37
|
|
@@ -562,8 +562,8 @@ DoneFix: $isDate = 1;
|
|
562
562
|
next;
|
563
563
|
} elsif ($format eq 'JSON') {
|
564
564
|
# Google Takeout JSON format
|
565
|
-
if (/"(latitudeE7|longitudeE7|latE7|lngE7|timestamp|startTime|point|durationMinutesOffsetFromStartTime)"\s*:\s*"?(.*?)"?,?\s*[\x0d\x0a]/) {
|
566
|
-
if ($1 eq 'timestamp') {
|
565
|
+
if (/"(latitudeE7|longitudeE7|latE7|lngE7|timestamp|startTime|point|durationMinutesOffsetFromStartTime|time)"\s*:\s*"?(.*?)"?,?\s*[\x0d\x0a]/) {
|
566
|
+
if ($1 eq 'timestamp' or $1 eq 'time') {
|
567
567
|
$time = GetTime($2);
|
568
568
|
goto DoneFix if $time and $$fix{lat} and $$fix{lon};
|
569
569
|
} elsif ($1 eq 'startTime') { # (new format)
|
@@ -1127,8 +1127,9 @@ sub SetGeoValues($$;$)
|
|
1127
1127
|
$iExt = $i1;
|
1128
1128
|
}
|
1129
1129
|
if (abs($time - $tn) > $geoMaxExtSecs) {
|
1130
|
-
$err or $err = 'Time is too far from nearest GPS fix'
|
1131
|
-
$et->VPrint(2, ' Nearest fix: ', PrintFixTime($tn),
|
1130
|
+
$err or $err = 'Time is too far from nearest GPS fix';
|
1131
|
+
$et->VPrint(2, ' Nearest fix: ', PrintFixTime($tn), ' (',
|
1132
|
+
int(abs $time-$tn), " sec away)\n") if $verbose > 2;
|
1132
1133
|
$fix = { } if $$geotag{DateTimeOnly};
|
1133
1134
|
} else {
|
1134
1135
|
$fix = $$points{$tn};
|
@@ -16,7 +16,7 @@ use vars qw($VERSION);
|
|
16
16
|
use Image::ExifTool qw(:DataAccess :Utils);
|
17
17
|
use Image::ExifTool::QuickTime;
|
18
18
|
|
19
|
-
$VERSION = '1.
|
19
|
+
$VERSION = '1.09';
|
20
20
|
|
21
21
|
sub ProcessGoPro($$$);
|
22
22
|
sub ProcessString($$$);
|
@@ -604,7 +604,7 @@ sub ScaleValues($$)
|
|
604
604
|
sub AddUnits($$$)
|
605
605
|
{
|
606
606
|
my ($et, $val, $tag) = @_;
|
607
|
-
if ($et and $$et{TAG_EXTRA}{$tag}
|
607
|
+
if ($et and $$et{TAG_EXTRA}{$tag}{Units}) {
|
608
608
|
my $u = $$et{TAG_EXTRA}{$tag}{Units};
|
609
609
|
$u = [ $u ] unless ref $u eq 'ARRAY';
|
610
610
|
my @a = split ' ', $val;
|
@@ -12,7 +12,7 @@ require Exporter;
|
|
12
12
|
|
13
13
|
use vars qw($VERSION @ISA @EXPORT_OK);
|
14
14
|
|
15
|
-
$VERSION = '1.
|
15
|
+
$VERSION = '1.13';
|
16
16
|
@ISA = qw(Exporter);
|
17
17
|
@EXPORT_OK = qw(ReadCSV ReadJSON);
|
18
18
|
|
@@ -87,6 +87,7 @@ sub ReadCSV($$;$$)
|
|
87
87
|
$fileInfo{$tags[$i]} =
|
88
88
|
(defined $missingValue and $vals[$i] eq $missingValue) ? undef : $vals[$i];
|
89
89
|
}
|
90
|
+
$fileInfo{_ordered_keys_} = \@tags;
|
90
91
|
# figure out the file name to use
|
91
92
|
if ($fileInfo{SourceFile}) {
|
92
93
|
$$database{$fileInfo{SourceFile}} = \%fileInfo;
|
@@ -173,7 +174,7 @@ Tok: for (;;) {
|
|
173
174
|
}
|
174
175
|
# see what type of object this is
|
175
176
|
if ($tok eq '{') { # object (hash)
|
176
|
-
$rtnVal = { } unless defined $rtnVal;
|
177
|
+
$rtnVal = { _ordered_keys_ => [ ] } unless defined $rtnVal;
|
177
178
|
for (;;) {
|
178
179
|
# read "KEY":"VALUE" pairs
|
179
180
|
unless (defined $key) {
|
@@ -189,6 +190,7 @@ Tok: for (;;) {
|
|
189
190
|
$pos = pos $$buffPt;
|
190
191
|
return undef unless defined $val;
|
191
192
|
$$rtnVal{$key} = $val;
|
193
|
+
push @{$$rtnVal{_ordered_keys_}}, $key;
|
192
194
|
undef $key;
|
193
195
|
}
|
194
196
|
# scan to delimiting ',' or bounding '}'
|
@@ -345,7 +347,9 @@ option for a list of valid character sets.
|
|
345
347
|
These functions return an error string, or undef on success and populate the
|
346
348
|
database hash with entries from the CSV or JSON file. Entries are keyed
|
347
349
|
based on the SourceFile column of the CSV or JSON information, and are
|
348
|
-
stored as hash lookups of tag name/value for each SourceFile.
|
350
|
+
stored as hash lookups of tag name/value for each SourceFile. The order
|
351
|
+
of the keys (CSV column order or order in a JSON object) is stored as an
|
352
|
+
ARRAY reference in a special "_ordered_keys_" element of this hash.
|
349
353
|
|
350
354
|
=back
|
351
355
|
|
@@ -14,7 +14,7 @@ use vars qw($VERSION);
|
|
14
14
|
use Image::ExifTool qw(:DataAccess :Utils);
|
15
15
|
use Image::ExifTool::Import;
|
16
16
|
|
17
|
-
$VERSION = '1.
|
17
|
+
$VERSION = '1.09';
|
18
18
|
|
19
19
|
sub ProcessJSON($$);
|
20
20
|
sub ProcessTag($$$$%);
|
@@ -92,8 +92,7 @@ sub ProcessTag($$$$%)
|
|
92
92
|
return unless $et->Options('Struct') > 1;
|
93
93
|
}
|
94
94
|
# support hashes with ordered keys
|
95
|
-
|
96
|
-
foreach (@keys) {
|
95
|
+
foreach (Image::ExifTool::OrderedKeys($val)) {
|
97
96
|
my $tg = $tag . ((/^\d/ and $tag =~ /\d$/) ? '_' : '') . ucfirst;
|
98
97
|
$tg =~ s/([^a-zA-Z])([a-z])/$1\U$2/g;
|
99
98
|
ProcessTag($et, $tagTablePtr, $tg, $$val{$_}, %flags, Flat => 1);
|
@@ -155,7 +154,7 @@ sub ProcessJSON($$)
|
|
155
154
|
|
156
155
|
# extract tags from JSON database
|
157
156
|
foreach $key (sort keys %database) {
|
158
|
-
foreach $tag (
|
157
|
+
foreach $tag (Image::ExifTool::OrderedKeys($database{$key})) {
|
159
158
|
my $val = $database{$key}{$tag};
|
160
159
|
# (ignore SourceFile if generated automatically by ReadJSON)
|
161
160
|
next if $tag eq 'SourceFile' and defined $val and $val eq '*';
|
@@ -16,7 +16,7 @@ use strict;
|
|
16
16
|
use vars qw($VERSION);
|
17
17
|
use Image::ExifTool qw(:DataAccess :Utils);
|
18
18
|
|
19
|
-
$VERSION = '1.
|
19
|
+
$VERSION = '1.42';
|
20
20
|
|
21
21
|
sub ProcessJpeg2000Box($$$);
|
22
22
|
sub ProcessJUMD($$$);
|
@@ -1338,7 +1338,7 @@ sub ProcessJpeg2000Box($$$)
|
|
1338
1338
|
if (defined $val) {
|
1339
1339
|
my $key = $et->FoundTag($tagInfo, $val);
|
1340
1340
|
# save Rational value
|
1341
|
-
$$et{
|
1341
|
+
$$et{TAG_EXTRA}{$key}{Rational} = $rational if defined $rational and defined $key;
|
1342
1342
|
}
|
1343
1343
|
} elsif ($outfile) {
|
1344
1344
|
my $boxhdr = pack('N', $boxLen + 8) . $boxID;
|
@@ -650,7 +650,7 @@ sub ProcessLNK($$)
|
|
650
650
|
my $mask = 0x04 << $i;
|
651
651
|
next unless $flags & $mask;
|
652
652
|
$raf->Read($buff, 2) or return 1;
|
653
|
-
$len = unpack('v', $buff);
|
653
|
+
$len = unpack('v', $buff) or next;
|
654
654
|
$len *= 2 if $flags & 0x80; # characters are 2 bytes if Unicode flag is set
|
655
655
|
$raf->Read($buff, $len) or return 1;
|
656
656
|
my $val;
|
@@ -15,7 +15,7 @@ use vars qw($VERSION);
|
|
15
15
|
use Image::ExifTool qw(:DataAccess :Utils);
|
16
16
|
use Image::ExifTool::Import;
|
17
17
|
|
18
|
-
$VERSION = '1.
|
18
|
+
$VERSION = '1.04';
|
19
19
|
|
20
20
|
sub ExtractTags($$$);
|
21
21
|
|
@@ -106,7 +106,7 @@ sub ExtractTags($$$)
|
|
106
106
|
my ($et, $meta, $parent) = @_;
|
107
107
|
ref $meta eq 'HASH' or $et->Warn('Invalid LFP metadata'), return;
|
108
108
|
my ($key, $val, $name, $tagTablePtr);
|
109
|
-
foreach $key (
|
109
|
+
foreach $key (Image::ExifTool::OrderedKeys($meta)) {
|
110
110
|
my $tag = $parent . ucfirst($key);
|
111
111
|
foreach $val (ref $$meta{$key} eq 'ARRAY' ? @{$$meta{$key}} : $$meta{$key}) {
|
112
112
|
ref $val eq 'HASH' and ExtractTags($et, $val, $tag), next;
|
@@ -32,7 +32,7 @@ use strict;
|
|
32
32
|
use vars qw($VERSION);
|
33
33
|
use Image::ExifTool qw(:DataAccess :Utils);
|
34
34
|
|
35
|
-
$VERSION = '1.
|
35
|
+
$VERSION = '1.26';
|
36
36
|
|
37
37
|
# program map table "stream_type" lookup (ref 6/1/9)
|
38
38
|
my %streamType = (
|
@@ -82,7 +82,7 @@ my %streamType = (
|
|
82
82
|
0x86 => 'DTS-HD Audio',
|
83
83
|
0x87 => 'E-AC-3 Audio',
|
84
84
|
0x8a => 'DTS Audio',
|
85
|
-
0x90 => '
|
85
|
+
0x90 => 'Presentation Graphic Stream (subtitle)', #https://en.wikipedia.org/wiki/Program-specific_information
|
86
86
|
0x91 => 'A52b/AC-3 Audio',
|
87
87
|
0x92 => 'DVD_SPU vls Subtitle',
|
88
88
|
0x94 => 'SDDS Audio',
|
@@ -14,7 +14,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
14
14
|
use Image::ExifTool::Exif;
|
15
15
|
use Image::ExifTool::GPS;
|
16
16
|
|
17
|
-
$VERSION = '1.
|
17
|
+
$VERSION = '1.55';
|
18
18
|
|
19
19
|
sub ProcessMIE($$);
|
20
20
|
sub ProcessMIEGroup($$$);
|
@@ -1596,9 +1596,10 @@ sub ProcessMIEGroup($$$)
|
|
1596
1596
|
} else {
|
1597
1597
|
# process MIE data format types
|
1598
1598
|
if ($tagInfo) {
|
1599
|
-
my $rational;
|
1599
|
+
my ($rational, $binVal);
|
1600
1600
|
# extract tag value
|
1601
1601
|
my $val = ReadMIEValue(\$value, 0, $formatStr, undef, $valLen, \$rational);
|
1602
|
+
$binVal = substr($value, 0, $valLen) if $$et{OPTIONS}{SaveBin};
|
1602
1603
|
unless (defined $val) {
|
1603
1604
|
$et->Warn("Error reading $tag value");
|
1604
1605
|
$val = '<err>';
|
@@ -1661,7 +1662,12 @@ sub ProcessMIEGroup($$$)
|
|
1661
1662
|
$val .= "($units)" if defined $units;
|
1662
1663
|
}
|
1663
1664
|
my $key = $et->FoundTag($tagInfo, $val);
|
1664
|
-
|
1665
|
+
if (defined $key) {
|
1666
|
+
my $ex = $$et{TAG_EXTRA}{$key};
|
1667
|
+
$$ex{Rational} = $rational if defined $rational;
|
1668
|
+
$$ex{BinVal} = $binVal if defined $binVal;
|
1669
|
+
$$ex{G6} = $formatStr if $$et{OPTIONS}{SaveFormat};
|
1670
|
+
}
|
1665
1671
|
}
|
1666
1672
|
} else {
|
1667
1673
|
# skip over unknown information or free bytes
|
@@ -12,7 +12,7 @@ use strict;
|
|
12
12
|
use vars qw($VERSION);
|
13
13
|
use Image::ExifTool qw(:DataAccess :Utils);
|
14
14
|
|
15
|
-
$VERSION = '1.
|
15
|
+
$VERSION = '1.14';
|
16
16
|
|
17
17
|
sub MDItemLocalTime($);
|
18
18
|
sub ProcessATTR($$$);
|
@@ -394,6 +394,7 @@ sub SetMacOSTags($$$)
|
|
394
394
|
if ($val =~ /[-+Z]/) {
|
395
395
|
my $time = Image::ExifTool::GetUnixTime($val, 1);
|
396
396
|
$val = Image::ExifTool::ConvertUnixTime($time, 1) if $time;
|
397
|
+
$val =~ s/[-+].*//; # remove time zone
|
397
398
|
}
|
398
399
|
$val =~ s{(\d{4}):(\d{2}):(\d{2})}{$2/$3/$1}; # reformat for setfile
|
399
400
|
$cmd = "/usr/bin/setfile -d '${val}' '${f}'";
|
@@ -65,7 +65,7 @@ use Image::ExifTool::Exif;
|
|
65
65
|
use Image::ExifTool::GPS;
|
66
66
|
use Image::ExifTool::XMP;
|
67
67
|
|
68
|
-
$VERSION = '4.
|
68
|
+
$VERSION = '4.39';
|
69
69
|
|
70
70
|
sub LensIDConv($$$);
|
71
71
|
sub ProcessNikonAVI($$$);
|
@@ -13609,7 +13609,10 @@ sub ProcessNikonMOV($$$)
|
|
13609
13609
|
Size => $size,
|
13610
13610
|
Base => $$dirInfo{Base},
|
13611
13611
|
);
|
13612
|
-
|
13612
|
+
if ($key) {
|
13613
|
+
$$et{TAG_EXTRA}{$key}{Rational} = $rational if $rational;
|
13614
|
+
$$et{TAG_EXTRA}{$key}{BinVal} = substr($$dataPt, $pos, $size) if $$et{OPTIONS}{SaveBin};
|
13615
|
+
}
|
13613
13616
|
} elsif (exists $needTags{$tag}) {
|
13614
13617
|
$needTags{$tag} = ReadValue($dataPt, $pos, $fmtStr, $count, $size);
|
13615
13618
|
$$et{NikonSerialKey} = SerialKey($et, $needTags{0x110a431});
|
@@ -21,7 +21,7 @@ use vars qw($VERSION $AUTOLOAD $lastFetched);
|
|
21
21
|
use Image::ExifTool qw(:DataAccess :Utils);
|
22
22
|
require Exporter;
|
23
23
|
|
24
|
-
$VERSION = '1.
|
24
|
+
$VERSION = '1.59';
|
25
25
|
|
26
26
|
sub FetchObject($$$$);
|
27
27
|
sub ExtractObject($$;$$);
|
@@ -1595,9 +1595,13 @@ sub DecryptInit($$$)
|
|
1595
1595
|
$password = $et->Options('Password');
|
1596
1596
|
return 'Document is password protected (use Password option)' unless defined $password;
|
1597
1597
|
# make sure there is no UTF-8 flag on the password
|
1598
|
-
if ($] >= 5.006 and (
|
1598
|
+
if ($] >= 5.006 and ($$et{OPTIONS}{EncodeHangs} or
|
1599
|
+
eval { require Encode; Encode::is_utf8($password) } or $@))
|
1600
|
+
{
|
1601
|
+
local $SIG{'__WARN__'} = sub { };
|
1599
1602
|
# repack by hand if Encode isn't available
|
1600
|
-
$password = $@ ? pack('C*',unpack($] < 5.010000 ?
|
1603
|
+
$password = ($$et{OPTIONS}{EncodeHangs} or $@) ? pack('C*', unpack($] < 5.010000 ?
|
1604
|
+
'U0C*' : 'C0C*', $password)) : Encode::encode('utf8', $password);
|
1601
1605
|
}
|
1602
1606
|
} else {
|
1603
1607
|
return 'Incorrect password';
|
@@ -15,7 +15,7 @@ use vars qw($VERSION);
|
|
15
15
|
use Image::ExifTool qw(:DataAccess :Utils);
|
16
16
|
use Image::ExifTool::Exif;
|
17
17
|
|
18
|
-
$VERSION = '1.
|
18
|
+
$VERSION = '1.11';
|
19
19
|
|
20
20
|
sub WritePhaseOne($$$);
|
21
21
|
sub ProcessPhaseOne($$$);
|
@@ -71,6 +71,7 @@ my @formatName = ( undef, 'string', 'int16s', undef, 'int32s' );
|
|
71
71
|
# >2 = compressed
|
72
72
|
# 5 = non-linear
|
73
73
|
PrintConv => { #PH
|
74
|
+
0 => 'Uncompressed', #https://github.com/darktable-org/darktable/issues/7308
|
74
75
|
1 => 'RAW 1', #? (encrypted)
|
75
76
|
2 => 'RAW 2', #? (encrypted)
|
76
77
|
3 => 'IIQ L', # (now "L14", ref IB)
|
@@ -48,7 +48,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
48
48
|
use Image::ExifTool::Exif;
|
49
49
|
use Image::ExifTool::GPS;
|
50
50
|
|
51
|
-
$VERSION = '3.
|
51
|
+
$VERSION = '3.04';
|
52
52
|
|
53
53
|
sub ProcessMOV($$;$);
|
54
54
|
sub ProcessKeys($$$);
|
@@ -901,6 +901,7 @@ my %userDefined = (
|
|
901
901
|
Writable => 1,
|
902
902
|
},
|
903
903
|
# '35AX'? - seen "AT" (Yada RoadCam Pro 4K dashcam)
|
904
|
+
cust => 'CustomInfo', # 70mai A810
|
904
905
|
);
|
905
906
|
|
906
907
|
# stuff seen in 'skip' atom (70mai Pro Plus+ MP4 videos)
|
@@ -3351,6 +3352,7 @@ my %userDefined = (
|
|
3351
3352
|
PrintConv => '"Track $val"',
|
3352
3353
|
},
|
3353
3354
|
# cdep (Structural Dependency QT tag?)
|
3355
|
+
# fall - ? int32u, seen: 2
|
3354
3356
|
);
|
3355
3357
|
|
3356
3358
|
# track aperture mode dimensions atoms
|
@@ -6744,6 +6746,13 @@ my %userDefined = (
|
|
6744
6746
|
Avoid => 1,
|
6745
6747
|
%iso8601Date,
|
6746
6748
|
},
|
6749
|
+
# (mdta)com.apple.quicktime.scene-illuminance
|
6750
|
+
'scene-illuminance' => {
|
6751
|
+
Name => 'SceneIlluminance',
|
6752
|
+
Notes => 'milli-lux',
|
6753
|
+
ValueConv => 'unpack("N", $val)',
|
6754
|
+
Writable => 0, # (don't make this writable because it is found in timed metadata)
|
6755
|
+
},
|
6747
6756
|
#
|
6748
6757
|
# seen in Apple ProRes RAW file
|
6749
6758
|
#
|
@@ -7393,6 +7402,7 @@ my %userDefined = (
|
|
7393
7402
|
# alac - 28 bytes
|
7394
7403
|
# adrm - AAX DRM atom? 148 bytes
|
7395
7404
|
# aabd - AAX unknown 17kB (contains 'aavd' strings)
|
7405
|
+
# dapa - ? 203 bytes
|
7396
7406
|
);
|
7397
7407
|
|
7398
7408
|
# AMR decode config box (ref 3)
|