exiftool_vendored 12.25.0 → 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 +114 -4
- data/bin/MANIFEST +11 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +44 -43
- data/bin/arg_files/xmp2exif.args +2 -1
- data/bin/config_files/convert_regions.config +25 -14
- data/bin/config_files/example.config +1 -1
- data/bin/exiftool +72 -56
- data/bin/fmt_files/gpx.fmt +1 -1
- data/bin/fmt_files/gpx_wpt.fmt +1 -1
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +10 -2
- data/bin/lib/Image/ExifTool/CBOR.pm +277 -0
- data/bin/lib/Image/ExifTool/Canon.pm +25 -18
- data/bin/lib/Image/ExifTool/DPX.pm +13 -2
- data/bin/lib/Image/ExifTool/Exif.pm +11 -6
- data/bin/lib/Image/ExifTool/FlashPix.pm +35 -10
- data/bin/lib/Image/ExifTool/FujiFilm.pm +1 -0
- data/bin/lib/Image/ExifTool/Geotag.pm +13 -2
- data/bin/lib/Image/ExifTool/GoPro.pm +16 -1
- data/bin/lib/Image/ExifTool/ID3.pm +15 -3
- data/bin/lib/Image/ExifTool/JPEG.pm +68 -2
- data/bin/lib/Image/ExifTool/JSON.pm +4 -2
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +58 -26
- 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 +103 -7
- data/bin/lib/Image/ExifTool/MIE.pm +2 -1
- data/bin/lib/Image/ExifTool/MRC.pm +1 -1
- data/bin/lib/Image/ExifTool/Nikon.pm +15 -4
- data/bin/lib/Image/ExifTool/NikonSettings.pm +10 -2
- data/bin/lib/Image/ExifTool/Olympus.pm +5 -2
- 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 +7 -6
- data/bin/lib/Image/ExifTool/Panasonic.pm +14 -2
- data/bin/lib/Image/ExifTool/Pentax.pm +28 -5
- data/bin/lib/Image/ExifTool/Photoshop.pm +6 -0
- data/bin/lib/Image/ExifTool/QuickTime.pm +103 -24
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +203 -121
- data/bin/lib/Image/ExifTool/README +3 -0
- data/bin/lib/Image/ExifTool/RIFF.pm +7 -2
- data/bin/lib/Image/ExifTool/Samsung.pm +47 -10
- data/bin/lib/Image/ExifTool/Sony.pm +84 -33
- data/bin/lib/Image/ExifTool/TagLookup.pm +50 -3
- data/bin/lib/Image/ExifTool/TagNames.pod +135 -29
- data/bin/lib/Image/ExifTool/Torrent.pm +18 -11
- 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/WriteQuickTime.pl +11 -4
- data/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
- data/bin/lib/Image/ExifTool/Writer.pl +3 -0
- data/bin/lib/Image/ExifTool/XMP.pm +17 -5
- 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 +79 -37
- data/bin/lib/Image/ExifTool.pod +62 -60
- data/bin/perl-Image-ExifTool.spec +43 -42
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +6 -3
@@ -56,7 +56,7 @@ use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat
|
|
56
56
|
use Image::ExifTool qw(:DataAccess :Utils);
|
57
57
|
use Image::ExifTool::MakerNotes;
|
58
58
|
|
59
|
-
$VERSION = '4.
|
59
|
+
$VERSION = '4.36';
|
60
60
|
|
61
61
|
sub ProcessExif($$$);
|
62
62
|
sub WriteExif($$$);
|
@@ -2581,7 +2581,7 @@ my %opcodeInfo = (
|
|
2581
2581
|
0xa301 => {
|
2582
2582
|
Name => 'SceneType',
|
2583
2583
|
Writable => 'undef',
|
2584
|
-
ValueConvInv => 'chr($val)',
|
2584
|
+
ValueConvInv => 'chr($val & 0xff)',
|
2585
2585
|
PrintConv => {
|
2586
2586
|
1 => 'Directly photographed',
|
2587
2587
|
},
|
@@ -5918,7 +5918,7 @@ sub ProcessExif($$$)
|
|
5918
5918
|
my $size = $count * $formatSize[$format];
|
5919
5919
|
my $readSize = $size;
|
5920
5920
|
if ($size > 4) {
|
5921
|
-
if ($size > 0x7fffffff) {
|
5921
|
+
if ($size > 0x7fffffff and (not $tagInfo or not $$tagInfo{ReadFromRAF})) {
|
5922
5922
|
$et->Warn(sprintf("Invalid size (%u) for %s %s",$size,$dir,TagName($tagID,$tagInfo)), $inMakerNotes);
|
5923
5923
|
++$warnCount;
|
5924
5924
|
next;
|
@@ -6171,18 +6171,23 @@ sub ProcessExif($$$)
|
|
6171
6171
|
unless ($bad) {
|
6172
6172
|
# limit maximum length of data to reformat
|
6173
6173
|
# (avoids long delays when processing some corrupted files)
|
6174
|
+
my $warned;
|
6174
6175
|
if ($count > 100000 and $formatStr !~ /^(undef|string|binary)$/) {
|
6175
6176
|
my $tagName = $tagInfo ? $$tagInfo{Name} : sprintf('tag 0x%.4x', $tagID);
|
6176
6177
|
# (count of 196608 is typical for ColorMap)
|
6177
6178
|
if ($tagName ne 'TransferFunction' or $count != 196608) {
|
6178
6179
|
my $minor = $count > 2000000 ? 0 : 2;
|
6179
|
-
|
6180
|
+
if ($et->Warn("Ignoring $dirName $tagName with excessive count", $minor)) {
|
6181
|
+
next unless $$et{OPTIONS}{HtmlDump};
|
6182
|
+
$warned = 1;
|
6183
|
+
}
|
6180
6184
|
}
|
6181
6185
|
}
|
6182
6186
|
if ($count > 500 and $formatStr !~ /^(undef|string|binary)$/ and
|
6183
|
-
(not $tagInfo or $$tagInfo{LongBinary}) and not $$et{OPTIONS}{IgnoreMinorErrors})
|
6187
|
+
(not $tagInfo or $$tagInfo{LongBinary} or $warned) and not $$et{OPTIONS}{IgnoreMinorErrors})
|
6184
6188
|
{
|
6185
|
-
$et->WarnOnce('Not decoding some large array(s). Ignore minor errors to decode', 2);
|
6189
|
+
$et->WarnOnce('Not decoding some large array(s). Ignore minor errors to decode', 2) unless $warned;
|
6190
|
+
next if $$et{TAGS_FROM_FILE}; # don't generate bogus value when copying tags
|
6186
6191
|
$val = "(large array of $count $formatStr values)";
|
6187
6192
|
} else {
|
6188
6193
|
# convert according to specified format
|
@@ -21,7 +21,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
21
21
|
use Image::ExifTool::Exif;
|
22
22
|
use Image::ExifTool::ASF; # for GetGUID()
|
23
23
|
|
24
|
-
$VERSION = '1.
|
24
|
+
$VERSION = '1.39';
|
25
25
|
|
26
26
|
sub ProcessFPX($$);
|
27
27
|
sub ProcessFPXR($$$);
|
@@ -1369,29 +1369,48 @@ sub ReadFPXValue($$$$$;$$)
|
|
1369
1369
|
my $flags = $type & 0xf000;
|
1370
1370
|
if ($flags) {
|
1371
1371
|
if ($flags == VT_VECTOR) {
|
1372
|
-
$noPad = 1; # values
|
1372
|
+
$noPad = 1; # values sometimes aren't padded inside vectors!!
|
1373
1373
|
my $size = $oleFormatSize{VT_VECTOR};
|
1374
|
-
|
1374
|
+
if ($valPos + $size > $dirEnd) {
|
1375
|
+
$et->WarnOnce('Incorrect FPX VT_VECTOR size');
|
1376
|
+
last;
|
1377
|
+
}
|
1375
1378
|
$count = Get32u($dataPt, $valPos);
|
1376
1379
|
push @vals, '' if $count == 0; # allow zero-element vector
|
1377
1380
|
$valPos += 4;
|
1378
1381
|
} else {
|
1379
1382
|
# can't yet handle this property flag
|
1383
|
+
$et->WarnOnce('Unknown FPX property');
|
1380
1384
|
last;
|
1381
1385
|
}
|
1382
1386
|
}
|
1383
1387
|
unless ($format =~ /^VT_/) {
|
1384
1388
|
my $size = Image::ExifTool::FormatSize($format) * $count;
|
1385
|
-
|
1389
|
+
if ($valPos + $size > $dirEnd) {
|
1390
|
+
$et->WarnOnce("Incorrect FPX $format size");
|
1391
|
+
last;
|
1392
|
+
}
|
1386
1393
|
@vals = ReadValue($dataPt, $valPos, $format, $count, $size);
|
1387
1394
|
# update position to end of value plus padding
|
1388
1395
|
$valPos += ($count * $size + 3) & 0xfffffffc;
|
1389
1396
|
last;
|
1390
1397
|
}
|
1391
1398
|
my $size = $oleFormatSize{$format};
|
1392
|
-
my ($item, $val);
|
1399
|
+
my ($item, $val, $len);
|
1393
1400
|
for ($item=0; $item<$count; ++$item) {
|
1394
|
-
|
1401
|
+
if ($valPos + $size > $dirEnd) {
|
1402
|
+
$et->WarnOnce("Truncated FPX $format value");
|
1403
|
+
last;
|
1404
|
+
}
|
1405
|
+
# sometimes VT_VECTOR items are padded to even 4-byte boundaries, and sometimes they aren't
|
1406
|
+
if ($noPad and defined $len and $len & 0x03) {
|
1407
|
+
my $pad = 4 - ($len & 0x03);
|
1408
|
+
if ($valPos + $pad + $size <= $dirEnd) {
|
1409
|
+
# skip padding if all zeros
|
1410
|
+
$valPos += $pad if substr($$dataPt, $valPos, $pad) eq "\0" x $pad;
|
1411
|
+
}
|
1412
|
+
}
|
1413
|
+
undef $len;
|
1395
1414
|
if ($format eq 'VT_VARIANT') {
|
1396
1415
|
my $subType = Get32u($dataPt, $valPos);
|
1397
1416
|
$valPos += $size;
|
@@ -1429,9 +1448,12 @@ sub ReadFPXValue($$$$$;$$)
|
|
1429
1448
|
$val = ($val - 25569) * 24 * 3600 if $val != 0;
|
1430
1449
|
$val = Image::ExifTool::ConvertUnixTime($val);
|
1431
1450
|
} elsif ($format =~ /STR$/) {
|
1432
|
-
|
1451
|
+
$len = Get32u($dataPt, $valPos);
|
1433
1452
|
$len *= 2 if $format eq 'VT_LPWSTR'; # convert to byte count
|
1434
|
-
|
1453
|
+
if ($valPos + $len + 4 > $dirEnd) {
|
1454
|
+
$et->WarnOnce("Truncated $format value");
|
1455
|
+
last;
|
1456
|
+
}
|
1435
1457
|
$val = substr($$dataPt, $valPos + 4, $len);
|
1436
1458
|
if ($format eq 'VT_LPWSTR') {
|
1437
1459
|
# convert wide string from Unicode
|
@@ -1450,8 +1472,11 @@ sub ReadFPXValue($$$$$;$$)
|
|
1450
1472
|
# on even 32-bit boundaries, but this isn't always the case)
|
1451
1473
|
$valPos += $noPad ? $len : ($len + 3) & 0xfffffffc;
|
1452
1474
|
} elsif ($format eq 'VT_BLOB' or $format eq 'VT_CF') {
|
1453
|
-
my $len = Get32u($dataPt, $valPos);
|
1454
|
-
|
1475
|
+
my $len = Get32u($dataPt, $valPos); # (use local $len because we always expect padding)
|
1476
|
+
if ($valPos + $len + 4 > $dirEnd) {
|
1477
|
+
$et->WarnOnce("Truncated $format value");
|
1478
|
+
last;
|
1479
|
+
}
|
1455
1480
|
$val = substr($$dataPt, $valPos + 4, $len);
|
1456
1481
|
# update position for data length plus padding
|
1457
1482
|
# (does this padding disappear in arrays too?)
|
@@ -28,7 +28,7 @@ use vars qw($VERSION);
|
|
28
28
|
use Image::ExifTool qw(:Public);
|
29
29
|
use Image::ExifTool::GPS;
|
30
30
|
|
31
|
-
$VERSION = '1.
|
31
|
+
$VERSION = '1.65';
|
32
32
|
|
33
33
|
sub JITTER() { return 2 } # maximum time jitter
|
34
34
|
|
@@ -262,8 +262,10 @@ sub LoadTrackLog($$;$)
|
|
262
262
|
$param = 'time';
|
263
263
|
} elsif (/^(Pos)?Lat/i) {
|
264
264
|
$param = 'lat';
|
265
|
+
/ref$/i and $param .= 'ref';
|
265
266
|
} elsif (/^(Pos)?Lon/i) {
|
266
267
|
$param = 'lon';
|
268
|
+
/ref$/i and $param .= 'ref';
|
267
269
|
} elsif (/^(Pos)?Alt/i) {
|
268
270
|
$param = 'alt';
|
269
271
|
} elsif (/^(Angle)?(Heading|Track)/i) {
|
@@ -453,7 +455,7 @@ DoneFix: $isDate = 1;
|
|
453
455
|
# (ExifTool enhancements allow for standard tag names or descriptions as the column headings,
|
454
456
|
# add support for time zones and flexible coordinates, and allow new DateTime and Shift columns)
|
455
457
|
#
|
456
|
-
my ($param, $date, $secs);
|
458
|
+
my ($param, $date, $secs, %neg);
|
457
459
|
foreach $param (@csvHeadings) {
|
458
460
|
my $val = shift @vals;
|
459
461
|
last unless defined $val;
|
@@ -479,6 +481,10 @@ DoneFix: $isDate = 1;
|
|
479
481
|
}
|
480
482
|
} elsif ($param eq 'lat' or $param eq 'lon') {
|
481
483
|
$$fix{$param} = Image::ExifTool::GPS::ToDegrees($val, 1);
|
484
|
+
} elsif ($param eq 'latref') {
|
485
|
+
$neg{lat} = 1 if $val =~ /^S/i;
|
486
|
+
} elsif ($param eq 'lonref') {
|
487
|
+
$neg{lon} = 1 if $val =~ /^W/i;
|
482
488
|
} elsif ($param eq 'runtime') {
|
483
489
|
$date = $trackTime;
|
484
490
|
$secs = $val;
|
@@ -486,6 +492,11 @@ DoneFix: $isDate = 1;
|
|
486
492
|
$$fix{$param} = $val;
|
487
493
|
}
|
488
494
|
}
|
495
|
+
# make coordinate negative according to reference direction if necessary
|
496
|
+
foreach $param (keys %neg) {
|
497
|
+
next unless defined $$fix{$param};
|
498
|
+
$$fix{$param} = -abs($$fix{$param});
|
499
|
+
}
|
489
500
|
if ($date and defined $secs and defined $$fix{lat} and defined $$fix{lon}) {
|
490
501
|
$time = $date + $secs;
|
491
502
|
$$has{alt} = 1 if defined $$fix{alt};
|
@@ -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.07';
|
20
20
|
|
21
21
|
sub ProcessGoPro($$$);
|
22
22
|
sub ProcessString($$$);
|
@@ -386,6 +386,21 @@ my %addUnits = (
|
|
386
386
|
Binary => 1,
|
387
387
|
},
|
388
388
|
# ZFOV (APP6,GPMF) - seen: 148.34, 0 (fmt f, Hero8, Max)
|
389
|
+
# the following ref forum12825
|
390
|
+
MUID => {
|
391
|
+
Name => 'MediaUniqueID',
|
392
|
+
PrintConv => q{
|
393
|
+
my @a = split ' ', $val;
|
394
|
+
$_ = sprintf('%.8x',$_) foreach @a;
|
395
|
+
return join('', @a);
|
396
|
+
},
|
397
|
+
},
|
398
|
+
EXPT => 'MaximumShutterAngle',
|
399
|
+
MTRX => 'AccelerometerMatrix',
|
400
|
+
ORIN => 'InputOrientation',
|
401
|
+
ORIO => 'OutputOrientation',
|
402
|
+
UNIF => 'InputUniformity',
|
403
|
+
SROT => 'SensorReadoutTime',
|
389
404
|
);
|
390
405
|
|
391
406
|
# GoPro GPS5 tags (ref 2) (Hero5,Hero6)
|
@@ -18,11 +18,12 @@ use strict;
|
|
18
18
|
use vars qw($VERSION);
|
19
19
|
use Image::ExifTool qw(:DataAccess :Utils);
|
20
20
|
|
21
|
-
$VERSION = '1.
|
21
|
+
$VERSION = '1.57';
|
22
22
|
|
23
23
|
sub ProcessID3v2($$$);
|
24
24
|
sub ProcessPrivate($$$);
|
25
25
|
sub ProcessSynText($$$);
|
26
|
+
sub ProcessID3Dir($$$);
|
26
27
|
sub ConvertID3v1Text($$);
|
27
28
|
sub ConvertTimeStamp($);
|
28
29
|
|
@@ -69,9 +70,10 @@ my %dateTimeConv = (
|
|
69
70
|
# This table is just for documentation purposes
|
70
71
|
%Image::ExifTool::ID3::Main = (
|
71
72
|
VARS => { NO_ID => 1 },
|
73
|
+
PROCESS_PROC => \&ProcessID3Dir, # (used to process 'id3 ' chunk in WAV files)
|
72
74
|
NOTES => q{
|
73
|
-
ExifTool extracts ID3 and Lyrics3 information from MP3, MPEG,
|
74
|
-
FLAC, APE, MPC and RealAudio files. ID3v2 tags which support multiple
|
75
|
+
ExifTool extracts ID3 and Lyrics3 information from MP3, MPEG, WAV, AIFF,
|
76
|
+
OGG, FLAC, APE, MPC and RealAudio files. ID3v2 tags which support multiple
|
75
77
|
languages (eg. Comment and Lyrics) are extracted by specifying the tag name,
|
76
78
|
followed by a dash ('-'), then a 3-character ISO 639-2 language code (eg.
|
77
79
|
"Comment-spa"). See L<http://www.id3.org/> for the official ID3
|
@@ -1570,6 +1572,16 @@ sub ProcessID3($$)
|
|
1570
1572
|
return $rtnVal;
|
1571
1573
|
}
|
1572
1574
|
|
1575
|
+
#------------------------------------------------------------------------------
|
1576
|
+
# Process ID3 directory
|
1577
|
+
# Inputs: 0) ExifTool object reference, 1) dirInfo reference, 2) dummy tag table ref
|
1578
|
+
sub ProcessID3Dir($$$)
|
1579
|
+
{
|
1580
|
+
my ($et, $dirInfo, $tagTablePtr) = @_;
|
1581
|
+
$et->VerboseDir('ID3', undef, length ${$$dirInfo{DataPt}});
|
1582
|
+
return ProcessID3($et, $dirInfo);
|
1583
|
+
}
|
1584
|
+
|
1573
1585
|
#------------------------------------------------------------------------------
|
1574
1586
|
# Extract ID3 information from an MP3 audio file
|
1575
1587
|
# Inputs: 0) ExifTool object reference, 1) dirInfo reference
|
@@ -11,7 +11,7 @@ use strict;
|
|
11
11
|
use vars qw($VERSION);
|
12
12
|
use Image::ExifTool qw(:DataAccess :Utils);
|
13
13
|
|
14
|
-
$VERSION = '1.
|
14
|
+
$VERSION = '1.32';
|
15
15
|
|
16
16
|
sub ProcessOcad($$$);
|
17
17
|
sub ProcessJPEG_HDR($$$);
|
@@ -96,6 +96,10 @@ sub ProcessJPEG_HDR($$$);
|
|
96
96
|
Name => 'Stim',
|
97
97
|
Condition => '$$valPt =~ /^Stim\0/',
|
98
98
|
SubDirectory => { TagTable => 'Image::ExifTool::Stim::Main' },
|
99
|
+
}, {
|
100
|
+
Name => 'JPS',
|
101
|
+
Condition => '$$valPt =~ /^_JPSJPS_/',
|
102
|
+
SubDirectory => { TagTable => 'Image::ExifTool::JPEG::JPS' },
|
99
103
|
}, {
|
100
104
|
Name => 'ThermalData', # (written by DJI FLIR models)
|
101
105
|
Condition => '$$self{Make} eq "DJI"',
|
@@ -287,6 +291,68 @@ sub ProcessJPEG_HDR($$$);
|
|
287
291
|
}],
|
288
292
|
);
|
289
293
|
|
294
|
+
# JPS APP3 segment (ref http://paulbourke.net/stereographics/stereoimage/)
|
295
|
+
%Image::ExifTool::JPEG::JPS = (
|
296
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
297
|
+
GROUPS => { 0 => 'APP3', 1 => 'JPS', 2 => 'Image' },
|
298
|
+
NOTES => 'Tags found in JPEG Stereo (JPS) images.',
|
299
|
+
0x0a => {
|
300
|
+
Name => 'JPSSeparation',
|
301
|
+
Format => 'int32u', # (just so we can look ahead to MediaType);
|
302
|
+
Notes => 'stereo only',
|
303
|
+
RawConv => q{
|
304
|
+
$$self{MediaType} = $val & 0xff;
|
305
|
+
return undef unless $$self{MediaType} == 1;
|
306
|
+
return(($val >> 24) & 0xff);
|
307
|
+
},
|
308
|
+
},
|
309
|
+
0x08 => {
|
310
|
+
Name => 'HdrLength',
|
311
|
+
Format => 'int16u',
|
312
|
+
Hidden => 1,
|
313
|
+
RawConv => '$$self{HdrLength} = $val; undef',
|
314
|
+
},
|
315
|
+
0x0b => {
|
316
|
+
Name => 'JPSFlags',
|
317
|
+
PrintConv => { BITMASK => {
|
318
|
+
0 => 'Half height',
|
319
|
+
1 => 'Half width',
|
320
|
+
2 => 'Left field first',
|
321
|
+
}},
|
322
|
+
},
|
323
|
+
0x0c => [{
|
324
|
+
Name => 'JPSLayout',
|
325
|
+
Condition => '$$self{MediaType} == 0',
|
326
|
+
Notes => 'mono',
|
327
|
+
PrintConv => {
|
328
|
+
0 => 'Both Eyes',
|
329
|
+
1 => 'Left Eye',
|
330
|
+
2 => 'Right Eye',
|
331
|
+
},
|
332
|
+
},{
|
333
|
+
Name => 'JPSLayout',
|
334
|
+
Condition => '$$self{MediaType} == 1',
|
335
|
+
Notes => 'stereo',
|
336
|
+
PrintConv => {
|
337
|
+
1 => 'Interleaved',
|
338
|
+
2 => 'Side By Side',
|
339
|
+
3 => 'Over Under',
|
340
|
+
4 => 'Anaglyph',
|
341
|
+
},
|
342
|
+
}],
|
343
|
+
0x0d => {
|
344
|
+
Name => 'JPSType',
|
345
|
+
Hook => '$varSize += $$self{HdrLength} - 4', # comment starts after header block
|
346
|
+
PrintConv => { 0 => 'Mono', 1 => 'Stereo' },
|
347
|
+
},
|
348
|
+
# 0x0e - in16u comment length (ignored -- assume the remainder is all comment)
|
349
|
+
# (this is offset if we had a 4-byte JPS header block)
|
350
|
+
0x10 => {
|
351
|
+
Name => 'JPSComment',
|
352
|
+
Format => 'string',
|
353
|
+
},
|
354
|
+
);
|
355
|
+
|
290
356
|
# EPPIM APP6 (Toshiba PrintIM) segment (ref PH, from PDR-M700 samples)
|
291
357
|
%Image::ExifTool::JPEG::EPPIM = (
|
292
358
|
GROUPS => { 0 => 'APP6', 1 => 'EPPIM', 2 => 'Image' },
|
@@ -545,7 +611,7 @@ sub ProcessJPEG_HDR($$$);
|
|
545
611
|
},
|
546
612
|
2 => {
|
547
613
|
Name => 'ImageFormat',
|
548
|
-
ValueConv => 'chr($val)',
|
614
|
+
ValueConv => 'chr($val & 0xff)',
|
549
615
|
PrintConv => { B => 'IMode B' },
|
550
616
|
},
|
551
617
|
3 => {
|
@@ -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.04';
|
18
18
|
|
19
19
|
sub ProcessJSON($$);
|
20
20
|
sub ProcessTag($$$$%);
|
@@ -83,7 +83,9 @@ sub ProcessTag($$$$%)
|
|
83
83
|
FoundTag($et, $tagTablePtr, $tag, $val, %flags, Struct => 1);
|
84
84
|
return unless $et->Options('Struct') > 1;
|
85
85
|
}
|
86
|
-
|
86
|
+
# support hashes with ordered keys
|
87
|
+
my @keys = $$val{_ordered_keys_} ? @{$$val{_ordered_keys_}} : sort keys %$val;
|
88
|
+
foreach (@keys) {
|
87
89
|
ProcessTag($et, $tagTablePtr, $tag . ucfirst, $$val{$_}, %flags, Flat => 1);
|
88
90
|
}
|
89
91
|
} elsif (ref $val eq 'ARRAY') {
|
@@ -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.31';
|
20
20
|
|
21
21
|
sub ProcessJpeg2000Box($$$);
|
22
22
|
sub ProcessJUMD($$$);
|
@@ -116,9 +116,6 @@ my %j2cMarker = (
|
|
116
116
|
0x76 => 'NLT', # non-linearity point transformation
|
117
117
|
);
|
118
118
|
|
119
|
-
my %jumbfTypes = (
|
120
|
-
);
|
121
|
-
|
122
119
|
# JPEG 2000 "box" (ie. atom) names
|
123
120
|
# Note: only tags with a defined "Format" are extracted
|
124
121
|
%Image::ExifTool::Jpeg2000::Main = (
|
@@ -127,10 +124,13 @@ my %jumbfTypes = (
|
|
127
124
|
WRITE_PROC => \&ProcessJpeg2000Box,
|
128
125
|
PREFERRED => 1, # always add these tags when writing
|
129
126
|
NOTES => q{
|
130
|
-
The tags below are
|
131
|
-
|
132
|
-
tags in Jpeg2000 images.
|
127
|
+
The tags below are found in JPEG 2000 images and the JUMBF metadata in JPEG
|
128
|
+
images, but not all of these are extracted. Note that ExifTool currently
|
129
|
+
writes only EXIF, IPTC and XMP tags in Jpeg2000 images.
|
133
130
|
},
|
131
|
+
#
|
132
|
+
# NOTE: ONLY TAGS WITH "Format" DEFINED ARE EXTRACTED!
|
133
|
+
#
|
134
134
|
'jP ' => 'JP2Signature', # (ref 1)
|
135
135
|
"jP\x1a\x1a" => 'JP2Signature', # (ref 2)
|
136
136
|
prfl => 'Profile',
|
@@ -344,6 +344,14 @@ my %jumbfTypes = (
|
|
344
344
|
Format => 'undef',
|
345
345
|
ValueConv => 'substr($val,16)',
|
346
346
|
},
|
347
|
+
{
|
348
|
+
Name => 'UUID-C2PAClaimSignature', # (seen in JUMB data of JPEG images)
|
349
|
+
Condition => '$$valPt=~/^c2cs\x00\x11\x00\x10\x80\x00\x00\xaa\x00\x38\x9b\x71/',
|
350
|
+
SubDirectory => {
|
351
|
+
TagTable => 'Image::ExifTool::CBOR::Main',
|
352
|
+
Start => '$valuePtr + 16',
|
353
|
+
},
|
354
|
+
},
|
347
355
|
{
|
348
356
|
Name => 'UUID-Unknown',
|
349
357
|
},
|
@@ -386,6 +394,27 @@ my %jumbfTypes = (
|
|
386
394
|
},
|
387
395
|
SubDirectory => { TagTable => 'Image::ExifTool::JSON::Main' },
|
388
396
|
},
|
397
|
+
cbor => {
|
398
|
+
Name => 'CBORData',
|
399
|
+
Flags => [ 'Binary', 'Protected' ],
|
400
|
+
SubDirectory => { TagTable => 'Image::ExifTool::CBOR::Main' },
|
401
|
+
},
|
402
|
+
bfdb => { # used in JUMBF (see # (used when tag is renamed according to JUMDLabel)
|
403
|
+
Name => 'BinaryDataType',
|
404
|
+
Notes => 'JUMBF, MIME type and optional file name',
|
405
|
+
Format => 'undef',
|
406
|
+
# (ignore "toggles" byte and just extract MIME type and file name)
|
407
|
+
ValueConv => '$_=substr($val,1); s/\0+$//; s/\0/, /; $_',
|
408
|
+
JUMBF_Suffix => 'Type', # (used when tag is renamed according to JUMDLabel)
|
409
|
+
},
|
410
|
+
bidb => { # used in JUMBF
|
411
|
+
Name => 'BinaryData',
|
412
|
+
Notes => 'JUMBF',
|
413
|
+
Groups => { 2 => 'Preview' },
|
414
|
+
Format => 'undef',
|
415
|
+
Binary => 1,
|
416
|
+
JUMBF_Suffix => 'Data', # (used when tag is renamed according to JUMDLabel)
|
417
|
+
},
|
389
418
|
#
|
390
419
|
# stuff seen in JPEG XL images:
|
391
420
|
#
|
@@ -607,23 +636,24 @@ my %jumbfTypes = (
|
|
607
636
|
PROCESS_PROC => \&ProcessJUMD,
|
608
637
|
GROUPS => { 0 => 'JUMBF', 1 => 'JUMBF', 2 => 'Image' },
|
609
638
|
NOTES => 'Information extracted from the JUMBF description box.',
|
610
|
-
'
|
639
|
+
'type' => {
|
611
640
|
Name => 'JUMDType',
|
612
641
|
ValueConv => 'unpack "H*", $val',
|
613
642
|
PrintConv => q{
|
614
643
|
my @a = $val =~ /^(\w{8})(\w{4})(\w{4})(\w{16})$/;
|
615
644
|
return $val unless @a;
|
616
645
|
my $ascii = pack 'H*', $a[0];
|
617
|
-
$a[0] = $ascii if $ascii =~ /^[a-zA-Z0-9]{4}$/;
|
646
|
+
$a[0] = "($ascii)" if $ascii =~ /^[a-zA-Z0-9]{4}$/;
|
618
647
|
return join '-', @a;
|
619
648
|
},
|
620
649
|
# seen:
|
621
650
|
# cacb/cast/caas/cacl/casg/json-00110010800000aa00389b71
|
622
651
|
# 6579d6fbdba2446bb2ac1b82feeb89d1 - JPEG image
|
623
652
|
},
|
624
|
-
'
|
625
|
-
'
|
626
|
-
Name => '
|
653
|
+
'label' => { Name => 'JUMDLabel' },
|
654
|
+
'toggles' => {
|
655
|
+
Name => 'JUMDToggles',
|
656
|
+
Unknown => 1,
|
627
657
|
PrintConv => { BITMASK => {
|
628
658
|
0 => 'Requestable',
|
629
659
|
1 => 'Label',
|
@@ -631,8 +661,8 @@ my %jumbfTypes = (
|
|
631
661
|
3 => 'Signature',
|
632
662
|
}},
|
633
663
|
},
|
634
|
-
'
|
635
|
-
'
|
664
|
+
'id' => { Name => 'JUMDID', Description => 'JUMD ID' },
|
665
|
+
'sig' => { Name => 'JUMDSignature', PrintConv => 'unpack "H*", $val' },
|
636
666
|
);
|
637
667
|
|
638
668
|
#------------------------------------------------------------------------------
|
@@ -675,20 +705,21 @@ sub ProcessJUMD($$$)
|
|
675
705
|
delete $$et{JUMBFLabel};
|
676
706
|
$$dirInfo{DirLen} < 17 and $et->Warn('Truncated JUMD directory'), return 0;
|
677
707
|
my $type = substr($$dataPt, $pos, 4);
|
678
|
-
$et->HandleTag($tagTablePtr, '
|
708
|
+
$et->HandleTag($tagTablePtr, 'type', substr($$dataPt, $pos, 16));
|
679
709
|
$pos += 16;
|
680
710
|
my $flags = Get8u($dataPt, $pos++);
|
681
|
-
$et->HandleTag($tagTablePtr, '
|
711
|
+
$et->HandleTag($tagTablePtr, 'toggles', $flags);
|
682
712
|
if ($flags & 0x02) { # label exists?
|
683
713
|
pos($$dataPt) = $pos;
|
684
714
|
$$dataPt =~ /\0/g or $et->Warn('Missing JUMD label terminator'), return 0;
|
685
715
|
my $len = pos($$dataPt) - $pos;
|
686
716
|
my $name = substr($$dataPt, $pos, $len);
|
687
|
-
$et->HandleTag($tagTablePtr, '
|
717
|
+
$et->HandleTag($tagTablePtr, 'label', $name);
|
688
718
|
$pos += $len;
|
689
719
|
if ($len) {
|
690
720
|
$name =~ s/[^-_a-zA-Z0-9]([a-z])/\U$1/g; # capitalize characters after illegal characters
|
691
721
|
$name =~ tr/-_a-zA-Z0-9//dc; # remove other illegal characters
|
722
|
+
$name =~ s/__/_/; # collapse double underlines
|
692
723
|
$name = ucfirst $name; # capitalize first letter
|
693
724
|
$name = "Tag$name" if length($name) < 2; # must at least 2 characters long
|
694
725
|
$$et{JUMBFLabel} = $name;
|
@@ -696,12 +727,12 @@ sub ProcessJUMD($$$)
|
|
696
727
|
}
|
697
728
|
if ($flags & 0x04) { # ID exists?
|
698
729
|
$pos + 4 > $end and $et->Warn('Missing JUMD ID'), return 0;
|
699
|
-
$et->HandleTag($tagTablePtr, '
|
730
|
+
$et->HandleTag($tagTablePtr, 'id', Get32u($dataPt, $pos));
|
700
731
|
$pos += 4;
|
701
732
|
}
|
702
733
|
if ($flags & 0x08) { # signature exists?
|
703
734
|
$pos + 32 > $end and $et->Warn('Missing JUMD signature'), return 0;
|
704
|
-
$et->HandleTag($tagTablePtr, '
|
735
|
+
$et->HandleTag($tagTablePtr, 'sig', substr($$dataPt, $pos, 32));
|
705
736
|
$pos += 32;
|
706
737
|
}
|
707
738
|
$pos == $end or $et->Warn('Extra data in JUMD box'." $pos $end", 1);
|
@@ -931,6 +962,14 @@ sub ProcessJpeg2000Box($$$)
|
|
931
962
|
}
|
932
963
|
}
|
933
964
|
}
|
965
|
+
# create new tag for JUMBF data values with name corresponding to JUMBFLabel
|
966
|
+
if ($tagInfo and $$et{JUMBFLabel} and (not $$tagInfo{SubDirectory} or $$tagInfo{BlockExtract})) {
|
967
|
+
$tagInfo = { %$tagInfo, Name => $$et{JUMBFLabel} . ($$tagInfo{JUMBF_Suffix} || '') };
|
968
|
+
delete $$tagInfo{Description};
|
969
|
+
AddTagToTable($tagTablePtr, '_JUMBF_' . $$et{JUMBFLabel}, $tagInfo);
|
970
|
+
delete $$tagInfo{Protected}; # (must do this so -j -b returns JUMBF binary data)
|
971
|
+
$$tagInfo{TagID} = $boxID;
|
972
|
+
}
|
934
973
|
if ($verbose) {
|
935
974
|
$et->VerboseInfo($boxID, $tagInfo,
|
936
975
|
Table => $tagTablePtr,
|
@@ -941,13 +980,6 @@ sub ProcessJpeg2000Box($$$)
|
|
941
980
|
);
|
942
981
|
next unless $tagInfo;
|
943
982
|
}
|
944
|
-
# create new tag for JUMBF data values with name corresponding to JUMBFLabel
|
945
|
-
if ($$et{JUMBFLabel} and (not $$tagInfo{SubDirectory} or $$tagInfo{BlockExtract})) {
|
946
|
-
$tagInfo = { %$tagInfo, Name => $$et{JUMBFLabel} };
|
947
|
-
AddTagToTable($tagTablePtr, '_JUMBF_' . $$et{JUMBFLabel}, $tagInfo);
|
948
|
-
delete $$tagInfo{Protected}; # (must do this so -j -b returns JUMBF binary data)
|
949
|
-
$$tagInfo{TagID} = $boxID;
|
950
|
-
}
|
951
983
|
if ($$tagInfo{SubDirectory}) {
|
952
984
|
my $subdir = $$tagInfo{SubDirectory};
|
953
985
|
my $subdirStart = $valuePtr;
|