exiftool_vendored 12.59.0 → 12.61.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.
- checksums.yaml +4 -4
- data/bin/Changes +46 -6
- data/bin/MANIFEST +1 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/exiftool +83 -46
- data/bin/lib/Image/ExifTool/CanonRaw.pm +5 -1
- data/bin/lib/Image/ExifTool/Exif.pm +53 -14
- data/bin/lib/Image/ExifTool/FujiFilm.pm +6 -3
- data/bin/lib/Image/ExifTool/Geotag.pm +30 -7
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +31 -6
- data/bin/lib/Image/ExifTool/MakerNotes.pm +2 -1
- data/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -9
- data/bin/lib/Image/ExifTool/Nikon.pm +3 -3
- data/bin/lib/Image/ExifTool/PDF.pm +15 -6
- data/bin/lib/Image/ExifTool/PNG.pm +1 -6
- data/bin/lib/Image/ExifTool/QuickTime.pm +10 -0
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +51 -21
- data/bin/lib/Image/ExifTool/RIFF.pm +2 -9
- data/bin/lib/Image/ExifTool/Ricoh.pm +2 -1
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +9 -3
- data/bin/lib/Image/ExifTool/Sony.pm +17 -10
- data/bin/lib/Image/ExifTool/TagLookup.pm +3 -2
- data/bin/lib/Image/ExifTool/TagNames.pod +5 -1
- data/bin/lib/Image/ExifTool/WriteExif.pl +2 -9
- data/bin/lib/Image/ExifTool/WritePDF.pl +7 -8
- data/bin/lib/Image/ExifTool/Writer.pl +40 -6
- data/bin/lib/Image/ExifTool/XMP.pm +13 -4
- data/bin/lib/Image/ExifTool.pm +102 -45
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +2 -2
|
@@ -34,7 +34,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
|
34
34
|
use Image::ExifTool::Exif;
|
|
35
35
|
use Image::ExifTool::Minolta;
|
|
36
36
|
|
|
37
|
-
$VERSION = '3.
|
|
37
|
+
$VERSION = '3.60';
|
|
38
38
|
|
|
39
39
|
sub ProcessSRF($$$);
|
|
40
40
|
sub ProcessSR2($$$);
|
|
@@ -161,6 +161,7 @@ sub PrintInvLensSpec($;$$);
|
|
|
161
161
|
32876 => 'Sony E 11mm F1.8', #JR
|
|
162
162
|
32877 => 'Sony E 15mm F1.4 G', #JR
|
|
163
163
|
32878 => 'Sony FE 20-70mm F4 G', #JR
|
|
164
|
+
32879 => 'Sony FE 50mm F1.4 GM', #JR
|
|
164
165
|
|
|
165
166
|
# (comment this out so LensID will report the LensModel, which is more useful)
|
|
166
167
|
# 32952 => 'Metabones Canon EF Speed Booster Ultra', #JR (corresponds to 184, but 'Advanced' mode, LensMount reported as E-mount)
|
|
@@ -259,7 +260,10 @@ sub PrintInvLensSpec($;$$);
|
|
|
259
260
|
50534 => 'Sigma 20mm F1.4 DG DN | A', #JR (022)
|
|
260
261
|
50535 => 'Sigma 24mm F1.4 DG DN | A', #JR (022)
|
|
261
262
|
50536 => 'Sigma 60-600mm F4.5-6.3 DG DN OS | S', #JR (023)
|
|
263
|
+
50537 => 'Sigma 50mm F2 DG DN | C', #JR (023)
|
|
264
|
+
50538 => 'Sigma 17mm F4 DG DN | C', #JR (023)
|
|
262
265
|
50539 => 'Sigma 50mm F1.4 DG DN | A', #JR (023)
|
|
266
|
+
50544 => 'Sigma 23mm F1.4 DC DN | C', #JR (023)
|
|
263
267
|
|
|
264
268
|
50992 => 'Voigtlander SUPER WIDE-HELIAR 15mm F4.5 III', #JR
|
|
265
269
|
50993 => 'Voigtlander HELIAR-HYPER WIDE 10mm F5.6', #IB
|
|
@@ -1165,7 +1169,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
|
1165
1169
|
},
|
|
1166
1170
|
},{
|
|
1167
1171
|
Name => 'AFAreaModeSetting',
|
|
1168
|
-
Condition => '$$self{Model} =~ /^(NEX-|ILCE-|ILME-|DSC-(RX10M4|RX100M6|RX100M7|RX100M5A|HX99|RX0M2))/',
|
|
1172
|
+
Condition => '$$self{Model} =~ /^(NEX-|ILCE-|ILME-|ZV-E|DSC-(RX10M4|RX100M6|RX100M7|RX100M5A|HX99|RX0M2))/',
|
|
1169
1173
|
Notes => 'NEX, ILCE and some DSC models',
|
|
1170
1174
|
RawConv => '$$self{AFAreaILCE} = $val',
|
|
1171
1175
|
DataMember => 'AFAreaILCE',
|
|
@@ -1201,7 +1205,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
|
1201
1205
|
# observed values in range (0 0) to (640 480), with center (320 240) often seen
|
|
1202
1206
|
# for NEX-5R/6, positions appear to be in an 11x9 grid
|
|
1203
1207
|
Name => 'FlexibleSpotPosition',
|
|
1204
|
-
Condition => '$$self{Model} =~ /^(NEX-|ILCE-|ILME-|DSC-(RX10M4|RX100M6|RX100M7|RX100M5A|HX99|RX0M2))/',
|
|
1208
|
+
Condition => '$$self{Model} =~ /^(NEX-|ILCE-|ILME-|ZV-E|DSC-(RX10M4|RX100M6|RX100M7|RX100M5A|HX99|RX0M2))/',
|
|
1205
1209
|
Writable => 'int16u',
|
|
1206
1210
|
Count => 2,
|
|
1207
1211
|
Notes => q{
|
|
@@ -1669,6 +1673,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
|
1669
1673
|
# 0x28 (e) for ILCE-7RM4/9M2, DSC-RX100M7, ZV-1/E10
|
|
1670
1674
|
# 0x31 (e) for ILCE-1/7M4/7SM3, ILME-FX3
|
|
1671
1675
|
# 0x32 (e) for ILCE-7RM5, ILME-FX30
|
|
1676
|
+
# 0x33 (e) for ZV-E1
|
|
1672
1677
|
# first byte decoded: 40, 204, 202, 27, 58, 62, 48, 215, 28, 106, 89 respectively
|
|
1673
1678
|
{
|
|
1674
1679
|
Name => 'Tag9400a',
|
|
@@ -1683,7 +1688,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
|
1683
1688
|
SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9400b' },
|
|
1684
1689
|
},{
|
|
1685
1690
|
Name => 'Tag9400c',
|
|
1686
|
-
Condition => '$$valPt =~ /^[\x23\x24\x26\x28\x31\x32]/',
|
|
1691
|
+
Condition => '$$valPt =~ /^[\x23\x24\x26\x28\x31\x32\x33]/',
|
|
1687
1692
|
SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9400c' },
|
|
1688
1693
|
},{
|
|
1689
1694
|
Name => 'Sony_0x9400',
|
|
@@ -1896,7 +1901,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
|
1896
1901
|
},
|
|
1897
1902
|
0x940c => [{
|
|
1898
1903
|
Name => 'Tag940c',
|
|
1899
|
-
Condition => '$$self{Model} =~ /^(NEX-|ILCE-|ILME-|Lunar|ZV-E10)\b/',
|
|
1904
|
+
Condition => '$$self{Model} =~ /^(NEX-|ILCE-|ILME-|Lunar|ZV-E10|ZV-E1)\b/',
|
|
1900
1905
|
SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag940c' },
|
|
1901
1906
|
},{
|
|
1902
1907
|
Name => 'Sony_0x940c',
|
|
@@ -1957,6 +1962,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
|
1957
1962
|
'3 3 3 0' => 'ARW 2.3.3', #JR (ILCE-9)
|
|
1958
1963
|
'3 3 5 0' => 'ARW 2.3.5', #JR (DSC-HX99)
|
|
1959
1964
|
'4 0 0 0' => 'ARW 4.0', # (ILCE-7SM3)
|
|
1965
|
+
'4 0 1 0' => 'ARW 4.0.1', #github#195 (ZV-E1)
|
|
1960
1966
|
# what about cRAW images?
|
|
1961
1967
|
},
|
|
1962
1968
|
},
|
|
@@ -2063,6 +2069,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
|
2063
2069
|
389 => 'ZV-1F', #IB
|
|
2064
2070
|
390 => 'ILCE-7RM5', #IB
|
|
2065
2071
|
391 => 'ILME-FX30', #JR
|
|
2072
|
+
393 => 'ZV-E1', #JR
|
|
2066
2073
|
},
|
|
2067
2074
|
},
|
|
2068
2075
|
0xb020 => { #2
|
|
@@ -8237,7 +8244,7 @@ my %isoSetting2010 = (
|
|
|
8237
8244
|
},
|
|
8238
8245
|
0x002a => [{
|
|
8239
8246
|
Name => 'Quality2',
|
|
8240
|
-
Condition => '$$self{Model} !~ /^(ILCE-(1|7M4|7RM5|7SM3)|ILME-FX3)\b/',
|
|
8247
|
+
Condition => '$$self{Model} !~ /^(ILCE-(1|7M4|7RM5|7SM3)|ILME-(FX3|FX30)|ZV-E1)\b/',
|
|
8241
8248
|
PrintConv => {
|
|
8242
8249
|
0 => 'JPEG',
|
|
8243
8250
|
1 => 'RAW',
|
|
@@ -8246,7 +8253,6 @@ my %isoSetting2010 = (
|
|
|
8246
8253
|
},
|
|
8247
8254
|
},{
|
|
8248
8255
|
Name => 'Quality2',
|
|
8249
|
-
Condition => '$$self{Model} =~ /^(ILCE-(1|7M4|7RM5|7SM3)|ILME-FX3)\b/',
|
|
8250
8256
|
PrintConv => {
|
|
8251
8257
|
1 => 'JPEG',
|
|
8252
8258
|
2 => 'RAW',
|
|
@@ -8257,13 +8263,13 @@ my %isoSetting2010 = (
|
|
|
8257
8263
|
}],
|
|
8258
8264
|
0x0047 => {
|
|
8259
8265
|
Name => 'SonyImageHeight',
|
|
8260
|
-
Condition => '$$self{Model} !~ /^(ILCE-(1|7M4|7RM5|7SM3)|ILME-FX3)\b/',
|
|
8266
|
+
Condition => '$$self{Model} !~ /^(ILCE-(1|7M4|7RM5|7SM3)|ILME-(FX3|FX30)|ZV-E1)\b/',
|
|
8261
8267
|
Format => 'int16u',
|
|
8262
8268
|
PrintConv => '$val > 0 ? 8*$val : "n.a."',
|
|
8263
8269
|
},
|
|
8264
8270
|
0x0053 => {
|
|
8265
8271
|
Name => 'ModelReleaseYear',
|
|
8266
|
-
Condition => '$$self{Model} !~ /^(ILCE-(1|7M4|7RM5|7SM3)|ILME-FX3)\b/',
|
|
8272
|
+
Condition => '$$self{Model} !~ /^(ILCE-(1|7M4|7RM5|7SM3)|ILME-(FX3|FX30)|ZV-E1)\b/',
|
|
8267
8273
|
Format => 'int8u',
|
|
8268
8274
|
PrintConv => 'sprintf("20%.2d", $val)',
|
|
8269
8275
|
},
|
|
@@ -8278,9 +8284,10 @@ my %isoSetting2010 = (
|
|
|
8278
8284
|
FIRST_ENTRY => 0,
|
|
8279
8285
|
GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
|
|
8280
8286
|
DATAMEMBER => [ 0 ],
|
|
8281
|
-
IS_SUBDIR => [ 0x044e, 0x0498, 0x049d, 0x04a1, 0x04a2, 0x059d, 0x0634, 0x0636, 0x064c, 0x0653, 0x0678, 0x06b8, 0x06de, 0x06e7 ],
|
|
8287
|
+
IS_SUBDIR => [ 0x03e2, 0x044e, 0x0498, 0x049d, 0x04a1, 0x04a2, 0x059d, 0x0634, 0x0636, 0x064c, 0x0653, 0x0678, 0x06b8, 0x06de, 0x06e7 ],
|
|
8282
8288
|
0x0000 => { Name => 'Ver9401', Hidden => 1, RawConv => '$$self{Ver9401} = $val; $$self{OPTIONS}{Unknown}<2 ? undef : $val' },
|
|
8283
8289
|
|
|
8290
|
+
0x03e2 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 181', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
|
|
8284
8291
|
0x044e => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 178', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
|
|
8285
8292
|
0x0498 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 148', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
|
|
8286
8293
|
0x049d => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 167', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
|
|
@@ -1149,7 +1149,7 @@ my %tagLookup = (
|
|
|
1149
1149
|
'bitspercomponent' => { 133 => 0x87 },
|
|
1150
1150
|
'bitspersample' => { 119 => 0x102, 340 => 0xa, 517 => 'BitsPerSample' },
|
|
1151
1151
|
'blackacquirerows' => { 138 => 0x18ba },
|
|
1152
|
-
'blacklevel' => { 119 => 0xc61a, 206 => 0x20, 233 => 0x3d, 317 => [0x401,0x1012], 379 => 0x21d, 442 => [0x7300,0x7310] },
|
|
1152
|
+
'blacklevel' => { 119 => [0x7310,0xc61a], 206 => 0x20, 233 => 0x3d, 317 => [0x401,0x1012], 379 => 0x21d, 442 => [0x7300,0x7310] },
|
|
1153
1153
|
'blacklevel2' => { 316 => 0x600, 320 => 0x600 },
|
|
1154
1154
|
'blacklevelblue' => { 340 => 0x1e },
|
|
1155
1155
|
'blacklevelbottom' => { 138 => 0x3f0 },
|
|
@@ -6271,6 +6271,7 @@ my %tagLookup = (
|
|
|
6271
6271
|
'sonyminaperture' => { 454 => 0x1, 455 => 0x1 },
|
|
6272
6272
|
'sonymodelid' => { 435 => 0xb001 },
|
|
6273
6273
|
'sonyquality' => { 184 => 0x3c },
|
|
6274
|
+
'sonyrawimagesize' => { 119 => 0x7038 },
|
|
6274
6275
|
'sonytimeminsec' => { 455 => 0x61 },
|
|
6275
6276
|
'sortalbum' => { 387 => 'soal' },
|
|
6276
6277
|
'sortalbumartist' => { 387 => 'soaa' },
|
|
@@ -7052,7 +7053,7 @@ my %tagLookup = (
|
|
|
7052
7053
|
'wb_rgbmulfluorescent' => { 138 => 0x854 },
|
|
7053
7054
|
'wb_rgbmultungsten' => { 138 => 0x853 },
|
|
7054
7055
|
'wb_rggbblacklevels' => { 35 => 0x25 },
|
|
7055
|
-
'wb_rggblevels' => { 190 => 0x4, 201 => 0x0, 205 => 0x13e8, 206 => 0x38, 442 => 0x7313 },
|
|
7056
|
+
'wb_rggblevels' => { 119 => 0x7313, 190 => 0x4, 201 => 0x0, 205 => 0x13e8, 206 => 0x38, 442 => 0x7313 },
|
|
7056
7057
|
'wb_rggblevelsasshot' => { 38 => 0x0, 39 => 0x0, 40 => 0x19, 41 => 0x55, 42 => 0x69, 43 => 0x22, 44 => 0x3f, 47 => 0x3f, 48 => 0x3f, 49 => 0x3f, 50 => 0x47 },
|
|
7057
7058
|
'wb_rggblevelsauto' => { 35 => 0x1, 38 => 0x5, 39 => 0x8, 40 => 0x1e, 41 => 0x5a, 42 => 0x6e, 43 => 0x18, 44 => 0x44, 47 => 0x44, 48 => 0x44, 49 => 0x44, 50 => 0x4c, 205 => 0x1478, 206 => 0x114, 409 => 0xa022, 442 => 0x7312 },
|
|
7058
7059
|
'wb_rggblevelsblack' => { 409 => 0xa028 },
|
|
@@ -12,7 +12,7 @@ meta information extracted from or written to a file.
|
|
|
12
12
|
=head1 TAG TABLES
|
|
13
13
|
|
|
14
14
|
The tables listed below give the names of all tags recognized by ExifTool.
|
|
15
|
-
They contain a total of
|
|
15
|
+
They contain a total of 26393 tags, with 16860 unique tag names.
|
|
16
16
|
|
|
17
17
|
B<Tag ID>, B<Index#> or B<Sequence> is given in the first column of each
|
|
18
18
|
table. A B<Tag ID> is the computer-readable equivalent of a tag name, and
|
|
@@ -498,6 +498,9 @@ for the official EXIF 2.32 specification.
|
|
|
498
498
|
0x7035 ChromaticAberrationCorrParams SubIFD int16s[33]!
|
|
499
499
|
0x7036 DistortionCorrection SubIFD int16s!
|
|
500
500
|
0x7037 DistortionCorrParams SubIFD int16s[17]!
|
|
501
|
+
0x7038 SonyRawImageSize SubIFD int32u[2]!
|
|
502
|
+
0x7310 BlackLevel SubIFD int16u[4]!
|
|
503
|
+
0x7313 WB_RGGBLevels SubIFD int16s[4]!
|
|
501
504
|
0x74c7 SonyCropTopLeft SubIFD int32u[2]!
|
|
502
505
|
0x74c8 SonyCropSize SubIFD int32u[2]!
|
|
503
506
|
0x800d ImageID - no
|
|
@@ -20824,6 +20827,7 @@ WX350/WX500, ILCE-1/7/7C/7R/7S/7M2/7M3/7RM2/7RM3/7RM4/7SM2/7SM3/9/9M2/5000/
|
|
|
20824
20827
|
|
|
20825
20828
|
Index1 Tag Name Writable
|
|
20826
20829
|
------ -------- --------
|
|
20830
|
+
994 ISOInfo Sony ISOInfo
|
|
20827
20831
|
1102 ISOInfo Sony ISOInfo
|
|
20828
20832
|
1176 ISOInfo Sony ISOInfo
|
|
20829
20833
|
1181 ISOInfo Sony ISOInfo
|
|
@@ -430,7 +430,6 @@ sub AddImageDataMD5($$$)
|
|
|
430
430
|
my $verbose = $et->Options('Verbose');
|
|
431
431
|
my $md5 = $$et{ImageDataMD5};
|
|
432
432
|
my $raf = $$dirInfo{RAF};
|
|
433
|
-
my $base = $$dirInfo{Base} || 0;
|
|
434
433
|
|
|
435
434
|
foreach $tagID (sort keys %$offsetInfo) {
|
|
436
435
|
next unless ref $$offsetInfo{$tagID} eq 'ARRAY'; # ignore scalar tag values used for Validate
|
|
@@ -451,14 +450,8 @@ sub AddImageDataMD5($$$)
|
|
|
451
450
|
foreach $offset (@offsets) {
|
|
452
451
|
my $size = shift @sizes;
|
|
453
452
|
next unless $offset =~ /^\d+$/ and $size and $size =~ /^\d+$/ and $size;
|
|
454
|
-
next unless $raf->Seek($offset
|
|
455
|
-
|
|
456
|
-
my $bytes = $size > 65536 ? 65536 : $size;
|
|
457
|
-
$raf->Read($buff, $bytes) or last;
|
|
458
|
-
$md5->add($buff);
|
|
459
|
-
$total += length($buff);
|
|
460
|
-
$size -= $bytes;
|
|
461
|
-
}
|
|
453
|
+
next unless $raf->Seek($offset, 0); # (offset is absolute)
|
|
454
|
+
$total += $et->ImageDataMD5($raf, $size);
|
|
462
455
|
}
|
|
463
456
|
if ($verbose) {
|
|
464
457
|
my $name = "$$dirInfo{DirName}:$$tagInfo{Name}";
|
|
@@ -23,7 +23,7 @@ my $beginComment = '%BeginExifToolUpdate';
|
|
|
23
23
|
my $endComment = '%EndExifToolUpdate ';
|
|
24
24
|
|
|
25
25
|
my $keyExt; # crypt key extension
|
|
26
|
-
my $pdfVer; # version of PDF file we are
|
|
26
|
+
my $pdfVer; # version of PDF file we are writing (highest Version in Root dictionaries)
|
|
27
27
|
|
|
28
28
|
# internal tags used in dictionary objects
|
|
29
29
|
my %myDictTags = (
|
|
@@ -297,15 +297,11 @@ sub WritePDF($$)
|
|
|
297
297
|
$$newTool{PDF_CAPTURE} = \%capture;
|
|
298
298
|
my $info = $newTool->ImageInfo($raf, 'XMP', 'PDF:*', 'Error', 'Warning');
|
|
299
299
|
# not a valid PDF file unless we got a version number
|
|
300
|
-
|
|
301
|
-
my $vers = $newTool->GetInfo('PDF:PDFVersion');
|
|
302
|
-
# take highest version number if multiple versions in an incremental save
|
|
303
|
-
($pdfVer) = sort { $b <=> $a } values %$vers;
|
|
300
|
+
$pdfVer = $$newTool{PDFVersion};
|
|
304
301
|
$pdfVer or $et->Error('Missing PDF:PDFVersion'), return 0;
|
|
305
302
|
# check version number
|
|
306
|
-
if ($pdfVer >
|
|
307
|
-
$et->
|
|
308
|
-
# (so writing by ExifTool is based on trial and error)
|
|
303
|
+
if ($pdfVer > 2.0) {
|
|
304
|
+
$et->Error("Writing PDF $pdfVer is untested", 1) and return 0;
|
|
309
305
|
}
|
|
310
306
|
# fail if we had any serious errors while extracting information
|
|
311
307
|
if ($capture{Error} or $$info{Error}) {
|
|
@@ -412,6 +408,9 @@ sub WritePDF($$)
|
|
|
412
408
|
my $tagID;
|
|
413
409
|
foreach $tagID (sort keys %$newTags) {
|
|
414
410
|
my $tagInfo = $$newTags{$tagID};
|
|
411
|
+
if ($pdfVer >= 2.0 and not $$tagInfo{PDF2}) {
|
|
412
|
+
next if $et->Warn("Writing PDF:$$tagInfo{Name} is deprecated for PDF 2.0 documents",2);
|
|
413
|
+
}
|
|
415
414
|
my $nvHash = $et->GetNewValueHash($tagInfo);
|
|
416
415
|
my (@vals, $deleted);
|
|
417
416
|
my $tag = $$tagInfo{Name};
|
|
@@ -3324,15 +3324,19 @@ sub InsertTagValues($$$;$$$)
|
|
|
3324
3324
|
undef $advFmtSelf;
|
|
3325
3325
|
$didExpr = 1; # set flag indicating an expression was evaluated
|
|
3326
3326
|
}
|
|
3327
|
-
unless (defined $val
|
|
3327
|
+
unless (defined $val) {
|
|
3328
3328
|
$val = $$self{OPTIONS}{MissingTagValue};
|
|
3329
3329
|
unless (defined $val) {
|
|
3330
3330
|
my $g3 = ($docGrp and $var !~ /\b(main|doc\d+):/i) ? $docGrp . ':' : '';
|
|
3331
3331
|
my $msg = $didExpr ? "Advanced formatting expression returned undef for '$g3${var}'" :
|
|
3332
3332
|
"Tag '$g3${var}' not defined";
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
$
|
|
3333
|
+
if (ref $opt) {
|
|
3334
|
+
$self->Warn($msg,2) or $val = '';
|
|
3335
|
+
} elsif ($opt) {
|
|
3336
|
+
no strict 'refs';
|
|
3337
|
+
($opt eq 'Silent' or &$opt($self, $msg, 2)) and return $$self{FMT_EXPR} = undef;
|
|
3338
|
+
$val = '';
|
|
3339
|
+
}
|
|
3336
3340
|
}
|
|
3337
3341
|
}
|
|
3338
3342
|
if (ref $opt eq 'HASH') {
|
|
@@ -5566,7 +5570,7 @@ sub WriteJPEG($$)
|
|
|
5566
5570
|
$s =~ /^JFXX\0\x10/ and $dirName = 'JFXX';
|
|
5567
5571
|
$s =~ /^(II|MM).{4}HEAPJPGM/s and $dirName = 'CIFF';
|
|
5568
5572
|
} elsif ($marker == 0xe1) {
|
|
5569
|
-
if ($s =~ /^(.{0,4})
|
|
5573
|
+
if ($s =~ /^(.{0,4})Exif\0.(.{1,4})/is) {
|
|
5570
5574
|
$dirName = 'IFD0';
|
|
5571
5575
|
my ($junk, $bytes) = ($1, $2);
|
|
5572
5576
|
# support multi-segment EXIF
|
|
@@ -6132,7 +6136,7 @@ sub WriteJPEG($$)
|
|
|
6132
6136
|
}
|
|
6133
6137
|
} elsif ($marker == 0xe1) { # APP1 (EXIF, XMP)
|
|
6134
6138
|
# check for EXIF data
|
|
6135
|
-
if ($$segDataPt =~ /^(.{0,4})
|
|
6139
|
+
if ($$segDataPt =~ /^(.{0,4})Exif\0./is) {
|
|
6136
6140
|
my $hdrLen = length $exifAPP1hdr;
|
|
6137
6141
|
if (length $1) {
|
|
6138
6142
|
$hdrLen += length $1;
|
|
@@ -6867,6 +6871,36 @@ sub SetFileTime($$;$$$$)
|
|
|
6867
6871
|
return 1; # (nothing to do)
|
|
6868
6872
|
}
|
|
6869
6873
|
|
|
6874
|
+
#------------------------------------------------------------------------------
|
|
6875
|
+
# Add data to MD5 checksum
|
|
6876
|
+
# Inputs: 0) ExifTool ref, 1) RAF ref, 2) data size (or undef to read to end of file),
|
|
6877
|
+
# 3) data name (or undef for no warnings or messages), 4) flag for no verbose message
|
|
6878
|
+
# Returns: number of bytes read and MD5'd
|
|
6879
|
+
sub ImageDataMD5($$$;$$)
|
|
6880
|
+
{
|
|
6881
|
+
my ($self, $raf, $size, $type, $noMsg) = @_;
|
|
6882
|
+
my $md5 = $$self{ImageDataMD5} or return;
|
|
6883
|
+
my ($bytesRead, $n) = (0, 65536);
|
|
6884
|
+
my $buff;
|
|
6885
|
+
for (;;) {
|
|
6886
|
+
if (defined $size) {
|
|
6887
|
+
last unless $size;
|
|
6888
|
+
$n = $size > 65536 ? 65536 : $size;
|
|
6889
|
+
$size -= $n;
|
|
6890
|
+
}
|
|
6891
|
+
unless ($raf->Read($buff, $n)) {
|
|
6892
|
+
$self->Warn("Error reading $type data") if $type and defined $size;
|
|
6893
|
+
last;
|
|
6894
|
+
}
|
|
6895
|
+
$md5->add($buff);
|
|
6896
|
+
$bytesRead += length $buff;
|
|
6897
|
+
}
|
|
6898
|
+
if ($$self{OPTIONS}{Verbose} and $bytesRead and $type and not $noMsg) {
|
|
6899
|
+
$self->VPrint(0, "$$self{INDENT}(ImageDataMD5: $bytesRead bytes of $type data)\n");
|
|
6900
|
+
}
|
|
6901
|
+
return $bytesRead;
|
|
6902
|
+
}
|
|
6903
|
+
|
|
6870
6904
|
#------------------------------------------------------------------------------
|
|
6871
6905
|
# Copy data block from RAF to output file in max 64kB chunks
|
|
6872
6906
|
# Inputs: 0) RAF ref, 1) outfile ref, 2) block size
|
|
@@ -248,7 +248,11 @@ my %boolConv = (
|
|
|
248
248
|
|
|
249
249
|
# XMP namespaces which we don't want to contribute to generated EXIF tag names
|
|
250
250
|
# (Note: namespaces with non-standard prefixes aren't currently ignored)
|
|
251
|
-
my %ignoreNamespace = ( 'x'=>1, rdf=>1, xmlns=>1, xml=>1, svg=>1,
|
|
251
|
+
my %ignoreNamespace = ( 'x'=>1, rdf=>1, xmlns=>1, xml=>1, svg=>1, office=>1 );
|
|
252
|
+
|
|
253
|
+
# ExifTool properties that don't generate tag names (et:tagid is historic)
|
|
254
|
+
my %ignoreEtProp = ( 'et:desc'=>1, 'et:prt'=>1, 'et:val'=>1 , 'et:id'=>1, 'et:tagid'=>1,
|
|
255
|
+
'et:toolkit'=>1, 'et:table'=>1, 'et:index'=>1 );
|
|
252
256
|
|
|
253
257
|
# XMP properties to ignore (set dynamically via dirInfo IgnoreProp)
|
|
254
258
|
my %ignoreProp;
|
|
@@ -2850,7 +2854,7 @@ sub GetXMPTagID($;$$)
|
|
|
2850
2854
|
# split name into namespace and property name
|
|
2851
2855
|
# (Note: namespace can be '' for property qualifiers)
|
|
2852
2856
|
my ($ns, $nm) = ($prop =~ /(.*?):(.*)/) ? ($1, $2) : ('', $prop);
|
|
2853
|
-
if ($ignoreNamespace{$ns} or $ignoreProp{$prop}) {
|
|
2857
|
+
if ($ignoreNamespace{$ns} or $ignoreProp{$prop} or $ignoreEtProp{$prop}) {
|
|
2854
2858
|
# special case: don't ignore rdf numbered items
|
|
2855
2859
|
# (not technically allowed in XMP, but used in RDF/XML)
|
|
2856
2860
|
unless ($prop =~ /^rdf:(_\d+)$/) {
|
|
@@ -3420,7 +3424,10 @@ NoLoop:
|
|
|
3420
3424
|
my %grps = ( 0 => $1, 1 => $2 );
|
|
3421
3425
|
# apply a little magic to recover original group names
|
|
3422
3426
|
# from this exiftool-written RDF/XML file
|
|
3423
|
-
if ($grps{1}
|
|
3427
|
+
if ($grps{1} eq 'System') {
|
|
3428
|
+
$grps{1} = 'XML-System';
|
|
3429
|
+
$grps{0} = 'XML';
|
|
3430
|
+
} elsif ($grps{1} =~ /^\d/) {
|
|
3424
3431
|
# URI's with only family 0 are internal tags from the source file,
|
|
3425
3432
|
# so change the group name to avoid confusion with tags from this file
|
|
3426
3433
|
$grps{1} = "XML-$grps{0}";
|
|
@@ -3888,7 +3895,9 @@ sub ParseXMPElement($$$;$$$$)
|
|
|
3888
3895
|
}
|
|
3889
3896
|
}
|
|
3890
3897
|
my $shortVal = $attrs{$shortName};
|
|
3891
|
-
|
|
3898
|
+
# Note: $prop is the containing property in this loop (not the shorthand property)
|
|
3899
|
+
# so $ignoreProp ignores all attributes of the ignored property
|
|
3900
|
+
if ($ignoreNamespace{$ns} or $ignoreProp{$prop} or $ignoreEtProp{$propName}) {
|
|
3892
3901
|
$ignored = $propName;
|
|
3893
3902
|
# handle special attributes (extract as tags only once if not empty)
|
|
3894
3903
|
if (ref $recognizedAttrs{$propName} and $shortVal) {
|
data/bin/lib/Image/ExifTool.pm
CHANGED
|
@@ -29,7 +29,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
|
|
|
29
29
|
%jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
|
|
30
30
|
%static_vars);
|
|
31
31
|
|
|
32
|
-
$VERSION = '12.
|
|
32
|
+
$VERSION = '12.61';
|
|
33
33
|
$RELEASE = '';
|
|
34
34
|
@ISA = qw(Exporter);
|
|
35
35
|
%EXPORT_TAGS = (
|
|
@@ -114,6 +114,7 @@ sub WriteTIFF($$$);
|
|
|
114
114
|
sub PackUTF8(@);
|
|
115
115
|
sub UnpackUTF8($);
|
|
116
116
|
sub SetPreferredByteOrder($;$);
|
|
117
|
+
sub ImageDataMD5($$$;$$);
|
|
117
118
|
sub CopyBlock($$$);
|
|
118
119
|
sub CopyFileAttrs($$$);
|
|
119
120
|
sub TimeNow(;$$);
|
|
@@ -1825,11 +1826,12 @@ my %systemTagsNotes = (
|
|
|
1825
1826
|
ImageDataMD5 => {
|
|
1826
1827
|
Notes => q{
|
|
1827
1828
|
MD5 of image data. Generated only if specifically requested for JPEG and
|
|
1828
|
-
TIFF-based images, CR3, MRW
|
|
1829
|
-
files.
|
|
1830
|
-
some formats, but does not include
|
|
1831
|
-
video and audio data for MOV/MP4.
|
|
1832
|
-
tag|XMP.html#ExifTool> provides a place to
|
|
1829
|
+
TIFF-based images, PNG, CRW, CR3, MRW, RAF, X3F, JP2, JXL and AVIF images,
|
|
1830
|
+
MOV/MP4 videos, and some RIFF-based files. The MD5 includes the main image
|
|
1831
|
+
data, plus JpgFromRaw/OtherImage for some formats, but does not include
|
|
1832
|
+
ThumbnailImage or PreviewImage. Includes video and audio data for MOV/MP4.
|
|
1833
|
+
The L<XMP-et:OriginalImageMD5 tag|XMP.html#ExifTool> provides a place to
|
|
1834
|
+
store these values in the file.
|
|
1833
1835
|
},
|
|
1834
1836
|
},
|
|
1835
1837
|
);
|
|
@@ -2501,23 +2503,6 @@ sub ExtractInfo($;@)
|
|
|
2501
2503
|
}
|
|
2502
2504
|
}
|
|
2503
2505
|
++$$self{FILE_SEQUENCE}; # count files read
|
|
2504
|
-
# extract information from alternate files if necessary
|
|
2505
|
-
my ($g8, $altExifTool);
|
|
2506
|
-
foreach $g8 (keys %{$$self{ALT_EXIFTOOL}}) {
|
|
2507
|
-
$altExifTool = $$self{ALT_EXIFTOOL}{$g8};
|
|
2508
|
-
next if $$altExifTool{DID_EXTRACT}; # avoid extracting twice
|
|
2509
|
-
$$altExifTool{OPTIONS} = $$self{OPTIONS};
|
|
2510
|
-
$$altExifTool{GLOBAL_TIME_OFFSET} = $$self{GLOBAL_TIME_OFFSET};
|
|
2511
|
-
$$altExifTool{REQ_TAG_LOOKUP} = $$self{REQ_TAG_LOOKUP};
|
|
2512
|
-
$altExifTool->ExtractInfo($$altExifTool{ALT_FILE});
|
|
2513
|
-
# set family 8 group name for all tags
|
|
2514
|
-
foreach (keys %{$$altExifTool{VALUE}}) {
|
|
2515
|
-
my $ex = $$altExifTool{TAG_EXTRA}{$_};
|
|
2516
|
-
$ex or $ex = $$altExifTool{TAG_EXTRA}{$_} = { };
|
|
2517
|
-
$$ex{G8} = $g8;
|
|
2518
|
-
}
|
|
2519
|
-
$$altExifTool{DID_EXTRACT} = 1;
|
|
2520
|
-
}
|
|
2521
2506
|
}
|
|
2522
2507
|
|
|
2523
2508
|
my $filename = $$self{FILENAME}; # image file name ('' if already open)
|
|
@@ -2659,6 +2644,7 @@ sub ExtractInfo($;@)
|
|
|
2659
2644
|
if ($isDir or (defined $stat[2] and ($stat[2] & 0170000) == 0040000)) {
|
|
2660
2645
|
$self->FoundTag('FileType', 'DIR');
|
|
2661
2646
|
$self->FoundTag('FileTypeExtension', '');
|
|
2647
|
+
$self->ExtractAltInfo();
|
|
2662
2648
|
$self->BuildCompositeTags() if $$options{Composite};
|
|
2663
2649
|
$raf->Close() if $raf;
|
|
2664
2650
|
return 1;
|
|
@@ -2677,6 +2663,7 @@ sub ExtractInfo($;@)
|
|
|
2677
2663
|
} else {
|
|
2678
2664
|
$self->Error('Unknown file type');
|
|
2679
2665
|
}
|
|
2666
|
+
$self->ExtractAltInfo();
|
|
2680
2667
|
$self->BuildCompositeTags() if $fast == 4 and $$options{Composite};
|
|
2681
2668
|
last; # don't read the file
|
|
2682
2669
|
}
|
|
@@ -2843,6 +2830,7 @@ sub ExtractInfo($;@)
|
|
|
2843
2830
|
}
|
|
2844
2831
|
unless ($reEntry) {
|
|
2845
2832
|
$$self{PATH} = [ ]; # reset PATH
|
|
2833
|
+
$self->ExtractAltInfo();
|
|
2846
2834
|
# calculate Composite tags
|
|
2847
2835
|
$self->BuildCompositeTags() if $$options{Composite};
|
|
2848
2836
|
# do our HTML dump if requested
|
|
@@ -3731,13 +3719,21 @@ COMPOSITE_TAG:
|
|
|
3731
3719
|
next COMPOSITE_TAG;
|
|
3732
3720
|
}
|
|
3733
3721
|
}
|
|
3722
|
+
my ($i, $key, @keys, $altFile);
|
|
3723
|
+
my $et = $self;
|
|
3724
|
+
# get tags from alternate file if a family 8 group was specified
|
|
3725
|
+
if ($reqTag =~ /\b(File\d+):/i and $$self{ALT_EXIFTOOL}{$1}) {
|
|
3726
|
+
$et = $$self{ALT_EXIFTOOL}{$1};
|
|
3727
|
+
$altFile = $1;
|
|
3728
|
+
}
|
|
3734
3729
|
# (CAREFUL! keys may not be sequential if one was deleted)
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
push @keys, $key if defined $$rawValue{$key};
|
|
3730
|
+
for ($key=$name, $i=$$et{DUPL_TAG}{$name} || 0; ; --$i) {
|
|
3731
|
+
push @keys, $key if defined $$et{VALUE}{$key};
|
|
3738
3732
|
last if $i <= 0;
|
|
3739
3733
|
$key = "$name ($i)";
|
|
3740
3734
|
}
|
|
3735
|
+
# make sure the necessary information is available from the alternate file
|
|
3736
|
+
$self->CopyAltInfo($altFile, \@keys) if $altFile;
|
|
3741
3737
|
# find first matching tag
|
|
3742
3738
|
$key = $self->GroupMatches($reqGroup, \@keys);
|
|
3743
3739
|
$reqTag = $key || "$name (0)";
|
|
@@ -4057,6 +4053,42 @@ sub CombineInfo($;@)
|
|
|
4057
4053
|
return \%combinedInfo;
|
|
4058
4054
|
}
|
|
4059
4055
|
|
|
4056
|
+
#------------------------------------------------------------------------------
|
|
4057
|
+
# Read metadata from alternate files
|
|
4058
|
+
# Inputs: 0) ExifTool ref
|
|
4059
|
+
# Notes: This is called after reading the main file so the tags are available
|
|
4060
|
+
# for being used in the file name, but before building Composite tags
|
|
4061
|
+
# so tags from the alternate files may be used in the Composite tags
|
|
4062
|
+
sub ExtractAltInfo($)
|
|
4063
|
+
{
|
|
4064
|
+
my $self = shift;
|
|
4065
|
+
# extract information from alternate files if necessary
|
|
4066
|
+
my ($g8, $altExifTool);
|
|
4067
|
+
foreach $g8 (sort keys %{$$self{ALT_EXIFTOOL}}) {
|
|
4068
|
+
$altExifTool = $$self{ALT_EXIFTOOL}{$g8};
|
|
4069
|
+
next if $$altExifTool{DID_EXTRACT}; # avoid extracting twice
|
|
4070
|
+
$$altExifTool{OPTIONS} = $$self{OPTIONS};
|
|
4071
|
+
$$altExifTool{GLOBAL_TIME_OFFSET} = $$self{GLOBAL_TIME_OFFSET};
|
|
4072
|
+
$$altExifTool{REQ_TAG_LOOKUP} = $$self{REQ_TAG_LOOKUP};
|
|
4073
|
+
my $fileName = $$altExifTool{ALT_FILE};
|
|
4074
|
+
# allow tags from the main file to be used in the alternate file names
|
|
4075
|
+
# (eg. -file1 '$originalfilename')
|
|
4076
|
+
if ($fileName =~ /\$/) {
|
|
4077
|
+
my @tags = reverse sort keys %{$$self{VALUE}};
|
|
4078
|
+
$fileName = $self->InsertTagValues(\@tags, $fileName, 'Warn');
|
|
4079
|
+
next unless defined $fileName;
|
|
4080
|
+
}
|
|
4081
|
+
$altExifTool->ExtractInfo($fileName);
|
|
4082
|
+
# set family 8 group name for all tags
|
|
4083
|
+
foreach (keys %{$$altExifTool{VALUE}}) {
|
|
4084
|
+
my $ex = $$altExifTool{TAG_EXTRA}{$_};
|
|
4085
|
+
$ex or $ex = $$altExifTool{TAG_EXTRA}{$_} = { };
|
|
4086
|
+
$$ex{G8} = $g8;
|
|
4087
|
+
}
|
|
4088
|
+
$$altExifTool{DID_EXTRACT} = 1;
|
|
4089
|
+
}
|
|
4090
|
+
}
|
|
4091
|
+
|
|
4060
4092
|
#------------------------------------------------------------------------------
|
|
4061
4093
|
# Get tag table name
|
|
4062
4094
|
# Inputs: 0) ExifTool object reference, 1) tag key
|
|
@@ -4598,6 +4630,29 @@ sub RemoveTagsFromList($$$$;$)
|
|
|
4598
4630
|
$_[0] = \@filteredTags; # update tag list
|
|
4599
4631
|
}
|
|
4600
4632
|
|
|
4633
|
+
#------------------------------------------------------------------------------
|
|
4634
|
+
# Copy tags from alternate input file
|
|
4635
|
+
# Inputs: 0) ExifTool ref, 1) family 8 group, 2) list ref for tag keys to copy
|
|
4636
|
+
# - updates tag key list to match keys newly added to $self
|
|
4637
|
+
sub CopyAltInfo($$$)
|
|
4638
|
+
{
|
|
4639
|
+
my ($self, $g8, $tags) = @_;
|
|
4640
|
+
my ($tag, $vtag);
|
|
4641
|
+
return unless $g8 =~ /(\d+)/;
|
|
4642
|
+
my $et = $$self{ALT_EXIFTOOL}{$g8} or return;
|
|
4643
|
+
my $altOrder = ($1 + 1) * 100000; # increment file order
|
|
4644
|
+
foreach $tag (@$tags) {
|
|
4645
|
+
($vtag = $tag) =~ s/( |$)/ #[$g8]/;
|
|
4646
|
+
unless (defined $$self{VALUE}{$vtag}) {
|
|
4647
|
+
$$self{VALUE}{$vtag} = $$et{VALUE}{$tag};
|
|
4648
|
+
$$self{TAG_INFO}{$vtag} = $$et{TAG_INFO}{$tag};
|
|
4649
|
+
$$self{TAG_EXTRA}{$vtag} = $$et{TAG_EXTRA}{$tag} || { };
|
|
4650
|
+
$$self{FILE_ORDER}{$vtag} = ($$et{FILE_ORDER}{$tag} || 0) + $altOrder;
|
|
4651
|
+
}
|
|
4652
|
+
$tag = $vtag;
|
|
4653
|
+
}
|
|
4654
|
+
}
|
|
4655
|
+
|
|
4601
4656
|
#------------------------------------------------------------------------------
|
|
4602
4657
|
# Set list of found tags from previously requested tags
|
|
4603
4658
|
# Inputs: 0) ExifTool object reference
|
|
@@ -4624,7 +4679,7 @@ sub SetFoundTags($)
|
|
|
4624
4679
|
my $tagHash = $$self{VALUE};
|
|
4625
4680
|
my $reqTag;
|
|
4626
4681
|
foreach $reqTag (@$reqTags) {
|
|
4627
|
-
my (@matches, $group, $allGrp, $allTag, $byValue, $g8
|
|
4682
|
+
my (@matches, $group, $allGrp, $allTag, $byValue, $g8);
|
|
4628
4683
|
my $et = $self;
|
|
4629
4684
|
if ($reqTag =~ /^(.*):(.+)/) {
|
|
4630
4685
|
($group, $tag) = ($1, $2);
|
|
@@ -4632,7 +4687,6 @@ sub SetFoundTags($)
|
|
|
4632
4687
|
$allGrp = 1;
|
|
4633
4688
|
} elsif ($reqTag =~ /\bfile(\d+):/i) {
|
|
4634
4689
|
$g8 = "File$1";
|
|
4635
|
-
$altOrder = ($1 + 1) * 100000;
|
|
4636
4690
|
$et = $$self{ALT_EXIFTOOL}{$g8} || $self;
|
|
4637
4691
|
$fileOrder = $$et{FILE_ORDER};
|
|
4638
4692
|
$tagHash = $$et{VALUE};
|
|
@@ -4704,16 +4758,7 @@ sub SetFoundTags($)
|
|
|
4704
4758
|
}
|
|
4705
4759
|
# copy over necessary information for tags from alternate files
|
|
4706
4760
|
if ($g8) {
|
|
4707
|
-
|
|
4708
|
-
foreach $tag (@matches) {
|
|
4709
|
-
my $vtag = $tag;
|
|
4710
|
-
$vtag =~ s/( |$)/ #[$g8]/;
|
|
4711
|
-
$$self{VALUE}{$vtag} = $$et{VALUE}{$tag};
|
|
4712
|
-
$$self{TAG_INFO}{$vtag} = $$et{TAG_INFO}{$tag};
|
|
4713
|
-
$$self{TAG_EXTRA}{$vtag} = $$et{TAG_EXTRA}{$tag} || { };
|
|
4714
|
-
$$self{FILE_ORDER}{$vtag} = ($$et{FILE_ORDER}{$tag} || 0) + $altOrder;
|
|
4715
|
-
$tag = $vtag;
|
|
4716
|
-
}
|
|
4761
|
+
$self->CopyAltInfo($g8, \@matches);
|
|
4717
4762
|
# restore variables to original values for main file
|
|
4718
4763
|
$fileOrder = $$self{FILE_ORDER};
|
|
4719
4764
|
$tagHash = $$self{VALUE};
|
|
@@ -6409,12 +6454,12 @@ sub ProcessJPEG($$)
|
|
|
6409
6454
|
my $htmlDump = $$self{HTML_DUMP};
|
|
6410
6455
|
my %dumpParms = ( Out => $out );
|
|
6411
6456
|
my ($ch, $s, $length, $md5, $md5size);
|
|
6412
|
-
my ($success, $wantTrailer, $trailInfo, $foundSOS, %jumbfChunk);
|
|
6457
|
+
my ($success, $wantTrailer, $trailInfo, $foundSOS, $gotSize, %jumbfChunk);
|
|
6413
6458
|
my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $flirTotal);
|
|
6414
6459
|
my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP);
|
|
6415
6460
|
|
|
6416
|
-
# get pointer to MD5 object if it exists and we are the top-level JPEG
|
|
6417
|
-
if ($$self{FILE_TYPE}
|
|
6461
|
+
# get pointer to MD5 object if it exists and we are the top-level JPEG or JP2
|
|
6462
|
+
if ($$self{FILE_TYPE} =~ /^(JPEG|JP2)$/ and not $$self{DOC_NUM}) {
|
|
6418
6463
|
$md5 = $$self{ImageDataMD5};
|
|
6419
6464
|
$md5size = 0;
|
|
6420
6465
|
}
|
|
@@ -6538,7 +6583,8 @@ sub ProcessJPEG($$)
|
|
|
6538
6583
|
$self->HDump($segPos-4, $length+4, "[JPEG $markerName]", undef, 0x08);
|
|
6539
6584
|
$dumpEnd = $segPos + $length;
|
|
6540
6585
|
}
|
|
6541
|
-
next
|
|
6586
|
+
next if $length < 6 or $gotSize;
|
|
6587
|
+
$gotSize = 1; # (ignore subsequent SOF segments in probably corrupted JPEG)
|
|
6542
6588
|
# extract some useful information
|
|
6543
6589
|
my ($p, $h, $w, $n) = unpack('Cn2C', $$segDataPt);
|
|
6544
6590
|
my $sof = GetTagTable('Image::ExifTool::JPEG::SOF');
|
|
@@ -6728,6 +6774,11 @@ sub ProcessJPEG($$)
|
|
|
6728
6774
|
pop @$path;
|
|
6729
6775
|
$verbose and print $out "JPEG SOD\n";
|
|
6730
6776
|
$success = 1;
|
|
6777
|
+
if ($md5 and $$self{FILE_TYPE} eq 'JP2') {
|
|
6778
|
+
my $pos = $raf->Tell();
|
|
6779
|
+
$self->ImageDataMD5($raf, undef, 'SOD');
|
|
6780
|
+
$raf->Seek($pos, 0);
|
|
6781
|
+
}
|
|
6731
6782
|
next if $verbose > 2 or $htmlDump;
|
|
6732
6783
|
last; # all done parsing file
|
|
6733
6784
|
} elsif (defined $markerLenBytes{$marker}) {
|
|
@@ -6802,7 +6853,7 @@ sub ProcessJPEG($$)
|
|
|
6802
6853
|
} elsif ($marker == 0xe1) { # APP1 (EXIF, XMP, QVCI, PARROT)
|
|
6803
6854
|
# (some Kodak cameras don't put a second "\0", and I have seen an
|
|
6804
6855
|
# example where there was a second 4-byte APP1 segment header)
|
|
6805
|
-
if ($$segDataPt =~ /^(.{0,4})Exif\0
|
|
6856
|
+
if ($$segDataPt =~ /^(.{0,4})Exif\0./is) {
|
|
6806
6857
|
undef $dumpType; # (will be dumped here)
|
|
6807
6858
|
# this is EXIF data --
|
|
6808
6859
|
# get the data block (into a common variable)
|
|
@@ -7460,8 +7511,11 @@ sub ProcessJPEG($$)
|
|
|
7460
7511
|
}
|
|
7461
7512
|
} elsif ($marker == 0x51) { # SIZ (J2C)
|
|
7462
7513
|
my ($w, $h) = unpack('x2N2', $$segDataPt);
|
|
7463
|
-
|
|
7464
|
-
|
|
7514
|
+
unless ($gotSize) {
|
|
7515
|
+
$gotSize = 1;
|
|
7516
|
+
$self->FoundTag('ImageWidth', $w);
|
|
7517
|
+
$self->FoundTag('ImageHeight', $h);
|
|
7518
|
+
}
|
|
7465
7519
|
} elsif (($marker & 0xf0) != 0xe0) {
|
|
7466
7520
|
$dumpType = "$markerName segment";
|
|
7467
7521
|
$desc = "[JPEG $markerName]"; # (other known JPEG segments)
|
|
@@ -7801,6 +7855,9 @@ sub DoProcessTIFF($$;$)
|
|
|
7801
7855
|
if ($$self{TIFF_TYPE} eq 'TIFF') {
|
|
7802
7856
|
$self->FoundTag(PageCount => $$self{PageCount}) if $$self{MultiPage};
|
|
7803
7857
|
}
|
|
7858
|
+
if ($$self{ImageDataMD5} and $$self{A100DataOffset} and $raf->Seek($$self{A100DataOffset},0)) {
|
|
7859
|
+
$self->ImageDataMD5($raf, undef, 'A100');
|
|
7860
|
+
}
|
|
7804
7861
|
return 1;
|
|
7805
7862
|
}
|
|
7806
7863
|
#
|