exiftool_vendored 12.34.0 → 12.35.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 +23 -2
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/exiftool +33 -25
- data/bin/lib/Image/ExifTool/Canon.pm +2 -1
- data/bin/lib/Image/ExifTool/FLIR.pm +33 -8
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +3 -3
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +105 -11
- data/bin/lib/Image/ExifTool/Nikon.pm +36 -3
- data/bin/lib/Image/ExifTool/QuickTime.pm +12 -1
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +1 -1
- data/bin/lib/Image/ExifTool/Sony.pm +3 -1
- data/bin/lib/Image/ExifTool/TagLookup.pm +4461 -4459
- data/bin/lib/Image/ExifTool/TagNames.pod +22 -11
- data/bin/lib/Image/ExifTool/Writer.pl +4 -2
- data/bin/lib/Image/ExifTool/XMP2.pl +1 -1
- data/bin/lib/Image/ExifTool.pm +37 -4
- data/bin/perl-Image-ExifTool.spec +1 -1
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52e82f9009ab10204f4fcf27c5e257b9ef7d78a132dd3ff487f6f4057f0277cc
|
4
|
+
data.tar.gz: 43b4bed4388b6518e0350f69d9858dcd74c981851ac681ee0b0fdd1a2fba0052
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea35dbefffadeb4fb7e3b8871acffbc2408ad1e63e7c2995ede7dc6baf7b4f98b1ff377d49677f0e36755ec643a6f12f2a31889106cb703c409128ca0af25a9e
|
7
|
+
data.tar.gz: a6f19417b3eed9bf9f8caaba0f84b100a05a968aded523453b865205cee7c7756da5d17f9a6b99d1bd3e7d1194c3a74247531c832dd88d40d6d468a5dba2861d
|
data/bin/Changes
CHANGED
@@ -7,11 +7,31 @@ RSS feed: https://exiftool.org/rss.xml
|
|
7
7
|
Note: The most recent production release is Version 12.30. (Other versions are
|
8
8
|
considered development releases, and are not uploaded to MetaCPAN.)
|
9
9
|
|
10
|
+
Nov. 11, 2021 - Version 12.35
|
11
|
+
|
12
|
+
- Added ability to write ICC_Profile (and other color specifications) to
|
13
|
+
Jpeg2000 images
|
14
|
+
- Added %o code to -W option format string
|
15
|
+
- Added %f code to -d option for fractional seconds
|
16
|
+
- Added a couple of new Sony LensType values (thanks Jos Roost)
|
17
|
+
- Added a new Nikon LensID
|
18
|
+
- Added a new CanonModelID
|
19
|
+
- Decode more Nikon MakerNotes tags for some new models (thanks Warren Hatch)
|
20
|
+
- Extract ThumbnailImage from some DJI drone videos
|
21
|
+
- Enhanced -ee option to extract metadata from all frames in a SEQ file
|
22
|
+
- Patched to avoid possible "Use of uninitialized value" runtime warning
|
23
|
+
- Fixed a couple if misspelt new ICC_Profile tag names (thanks Herb)
|
24
|
+
- Fixed problem generating the correct file extension when extracting
|
25
|
+
OriginalRawImage from a DNG file using the -W option with the %s format code
|
26
|
+
- Fixed bug introduced in 11.91 where exiftool couldn't find its libraries
|
27
|
+
when running via a link. Also it was looking for the config file in the
|
28
|
+
directory of the link, and this was changed to the target directory
|
29
|
+
|
10
30
|
Oct. 27, 2021 - Version 12.34
|
11
31
|
|
12
32
|
- Added support for ICC.2:2019 (Profile version 5.0.0 - iccMAX) color profiles
|
13
33
|
- Added ability to detect/delete a Windows Zone.Identifier alternate data
|
14
|
-
stream (ADS) via the new ZoneIdentifier tag
|
34
|
+
stream (ADS) via the new ZoneIdentifier tag (thanks Alex Xu)
|
15
35
|
- Added support for the Sony ILCE-7M4 (thanks Jos Roost)
|
16
36
|
- Added a new Sony lens (thanks LibRaw and Jos Roost)
|
17
37
|
- Added a new SonyModelID (thanks LibRaw)
|
@@ -19,7 +39,7 @@ Oct. 27, 2021 - Version 12.34
|
|
19
39
|
- Improved handling of some SVG files
|
20
40
|
- Patched -overwrite_original_in_place option to open the output file in
|
21
41
|
update mode rather than write mode (to allow some write optimizations on
|
22
|
-
certain filesystems)
|
42
|
+
certain filesystems) (thanks Joel Low)
|
23
43
|
- Fixed case of tag ID for new XMP-iptcExt:EventID (thanks Michael Steidl)
|
24
44
|
- Fixed problem extracting ICC_Profile information from some PDF files
|
25
45
|
- API Changes:
|
@@ -635,6 +655,7 @@ Mar. 19, 2020 - Version 11.92
|
|
635
655
|
|
636
656
|
Mar. 5, 2020 - Version 11.91
|
637
657
|
|
658
|
+
- Added undocumented -xpath option for use by alternate Windows version
|
638
659
|
- Decode a couple of new Panasonic tags
|
639
660
|
- Documented -ec option (available since version 11.54)
|
640
661
|
- Reverted -htmlDump fix of 11.90 because it broke more than it fixed, and
|
data/bin/META.json
CHANGED
data/bin/META.yml
CHANGED
data/bin/README
CHANGED
@@ -107,8 +107,8 @@ your home directory, then you would type the following commands in a
|
|
107
107
|
terminal window to extract and run ExifTool:
|
108
108
|
|
109
109
|
cd ~/Desktop
|
110
|
-
gzip -dc Image-ExifTool-12.
|
111
|
-
cd Image-ExifTool-12.
|
110
|
+
gzip -dc Image-ExifTool-12.35.tar.gz | tar -xf -
|
111
|
+
cd Image-ExifTool-12.35
|
112
112
|
./exiftool t/images/ExifTool.jpg
|
113
113
|
|
114
114
|
Note: These commands extract meta information from one of the test images.
|
data/bin/exiftool
CHANGED
@@ -10,24 +10,26 @@
|
|
10
10
|
use strict;
|
11
11
|
require 5.004;
|
12
12
|
|
13
|
-
my $version = '12.
|
13
|
+
my $version = '12.35';
|
14
14
|
|
15
15
|
# add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
|
16
|
-
my $exeDir;
|
17
16
|
BEGIN {
|
18
17
|
# (undocumented -xpath option added in 11.91, must come before other options)
|
19
|
-
$
|
18
|
+
my $exePath = @ARGV && lc($ARGV[0]) eq '-xpath' && shift() ? $^X : $0;
|
20
19
|
# get exe directory
|
21
|
-
$exeDir = ($
|
20
|
+
my $exeDir = ($exePath =~ /(.*)[\\\/]/) ? $1 : '.';
|
21
|
+
my $incDir = ($0 =~ /(.*)[\\\/]/) ? "$1/lib" : './lib';
|
22
22
|
if (-l $0) {
|
23
23
|
my $lnk = eval { readlink $0 };
|
24
24
|
if (defined $lnk) {
|
25
25
|
my $lnkDir = ($lnk =~ /(.*)[\\\/]/) ? $1 : '.';
|
26
26
|
$exeDir = (($lnk =~ m(^/)) ? '' : $exeDir . '/') . $lnkDir;
|
27
|
+
$incDir = "$exeDir/lib";
|
27
28
|
}
|
28
29
|
}
|
30
|
+
$Image::ExifTool::exeDir = $exeDir; # use our exeDir for loading config file
|
29
31
|
# add lib directory at start of include path
|
30
|
-
unshift @INC,
|
32
|
+
unshift @INC, $incDir;
|
31
33
|
# load or disable config file if specified
|
32
34
|
if (@ARGV and lc($ARGV[0]) eq '-config') {
|
33
35
|
shift;
|
@@ -757,7 +759,7 @@ for (;;) {
|
|
757
759
|
}
|
758
760
|
my $fp = ($stayOpen == 1 ? \*STAYOPEN : \*ARGFILE);
|
759
761
|
unless ($mt->Open($fp, $argFile)) {
|
760
|
-
unless ($argFile !~ /^\// and $mt->Open($fp, "$exeDir/$argFile")) {
|
762
|
+
unless ($argFile !~ /^\// and $mt->Open($fp, "$Image::ExifTool::exeDir/$argFile")) {
|
761
763
|
Error "Error opening arg file $argFile\n";
|
762
764
|
$badCmd = 1;
|
763
765
|
next
|
@@ -1235,7 +1237,7 @@ for (;;) {
|
|
1235
1237
|
$textOverwrite += 2 if $t2 =~ /\+/; # append
|
1236
1238
|
if ($t1 ne 'W' and lc($t1) ne 'tagout') {
|
1237
1239
|
undef $tagOut;
|
1238
|
-
} elsif ($textOverwrite >= 2 and $textOut !~ /%[-+]?\d*[.:]?\d*[lu]?[
|
1240
|
+
} elsif ($textOverwrite >= 2 and $textOut !~ /%[-+]?\d*[.:]?\d*[lu]?[tgso]/) {
|
1239
1241
|
$tagOut = 0; # append tags to one file
|
1240
1242
|
} else {
|
1241
1243
|
$tagOut = 1; # separate file for each tag
|
@@ -2365,7 +2367,8 @@ TAG: foreach $tag (@foundTags) {
|
|
2365
2367
|
}
|
2366
2368
|
my @groups = $et->GetGroup($tag);
|
2367
2369
|
$outfile and close($fp), undef($tmpText); # (shouldn't happen)
|
2368
|
-
|
2370
|
+
my $org = $et->GetValue('OriginalRawFileName') || $et->GetValue('OriginalFileName');
|
2371
|
+
($fp, $outfile, $append) = OpenOutputFile($orig, $tagName, \@groups, $ext, $org);
|
2369
2372
|
$fp or ++$countBad, next TAG;
|
2370
2373
|
$tmpText = $outfile unless $append;
|
2371
2374
|
}
|
@@ -3943,7 +3946,7 @@ sub SuggestedExtension($$$)
|
|
3943
3946
|
$ext = 'xml';
|
3944
3947
|
} elsif ($$valPt =~ /^RIFF....WAVE/s) {
|
3945
3948
|
$ext = 'wav';
|
3946
|
-
} elsif ($tag eq '
|
3949
|
+
} elsif ($tag eq 'OriginalRawImage' and defined($ext = $et->GetValue('OriginalRawFileName'))) {
|
3947
3950
|
$ext =~ s/^.*\.//s;
|
3948
3951
|
$ext = $ext ? lc($ext) : 'raw';
|
3949
3952
|
} elsif ($tag eq 'EXIF') {
|
@@ -3995,14 +3998,15 @@ sub LoadPrintFormat($)
|
|
3995
3998
|
# A sort of sprintf for filenames
|
3996
3999
|
# Inputs: 0) format string (%d=dir, %f=file name, %e=ext),
|
3997
4000
|
# 1) source filename or undef to test format string
|
3998
|
-
# 2-4) [%t %g %s only] tag name, ref to array of group names,
|
4001
|
+
# 2-4) [%t %g %s %o only] tag name, ref to array of group names,
|
4002
|
+
# suggested extension, original raw file name
|
3999
4003
|
# Returns: new filename or undef on error (or if no file and fmt contains token)
|
4000
4004
|
sub FilenameSPrintf($;$@)
|
4001
4005
|
{
|
4002
4006
|
my ($fmt, $file, @extra) = @_;
|
4003
4007
|
local $_;
|
4004
4008
|
# return format string straight away if no tokens
|
4005
|
-
return $fmt unless $fmt =~ /%[-+]?\d*[.:]?\d*[lu]?[
|
4009
|
+
return $fmt unless $fmt =~ /%[-+]?\d*[.:]?\d*[lu]?[dDfFeEtgso]/;
|
4006
4010
|
return undef unless defined $file;
|
4007
4011
|
CleanFilename($file); # make sure we are using forward slashes
|
4008
4012
|
# split filename into directory, file, extension
|
@@ -4016,9 +4020,9 @@ sub FilenameSPrintf($;$@)
|
|
4016
4020
|
}
|
4017
4021
|
$part{F} = $part{f} . $part{E};
|
4018
4022
|
($part{D} = $part{d}) =~ s{/+$}{};
|
4019
|
-
@part{qw(t g s)} = @extra;
|
4023
|
+
@part{qw(t g s o)} = @extra;
|
4020
4024
|
my ($filename, $pos) = ('', 0);
|
4021
|
-
while ($fmt =~ /(%([-+]?)(\d*)([.:]?)(\d*)([lu]?)([
|
4025
|
+
while ($fmt =~ /(%([-+]?)(\d*)([.:]?)(\d*)([lu]?)([dDfFeEtgso]))/g) {
|
4022
4026
|
$filename .= substr($fmt, $pos, pos($fmt) - $pos - length($1));
|
4023
4027
|
$pos = pos($fmt);
|
4024
4028
|
my ($sign, $wid, $dot, $skip, $mod, $code) = ($2, $3, $4, $5 || 0, $6, $7);
|
@@ -4181,7 +4185,7 @@ sub OpenOutputFile($;@)
|
|
4181
4185
|
if ($textOut) {
|
4182
4186
|
$outfile = $file;
|
4183
4187
|
CleanFilename($outfile);
|
4184
|
-
if ($textOut =~ /%[-+]?\d*[.:]?\d*[lun]?[
|
4188
|
+
if ($textOut =~ /%[-+]?\d*[.:]?\d*[lun]?[dDfFeEtgsocC]/ or defined $tagOut) {
|
4185
4189
|
# make filename from printf-like $textOut
|
4186
4190
|
$outfile = FilenameSPrintf($textOut, $file, @args);
|
4187
4191
|
return () unless defined $outfile;
|
@@ -5167,9 +5171,11 @@ various components of a date/time value. The specifics of the I<FMT> syntax
|
|
5167
5171
|
are system dependent -- consult the C<strftime> man page on your system for
|
5168
5172
|
details. The default format is equivalent to "%Y:%m:%d %H:%M:%S". This
|
5169
5173
|
option has no effect on date-only or time-only tags and ignores timezone
|
5170
|
-
information if present.
|
5171
|
-
|
5172
|
-
|
5174
|
+
information if present. ExifTool adds a C<%f> format code to represent
|
5175
|
+
fractional seconds, and supports an optional width to specify the number of
|
5176
|
+
digits after the decimal point (eg. C<%3f> would give something like
|
5177
|
+
C<.437>). Only one B<-d> option may be used per command. Requires
|
5178
|
+
POSIX::strptime or Time::Piece for the inversion conversion when writing.
|
5173
5179
|
|
5174
5180
|
=item B<-D> (B<-decimal>)
|
5175
5181
|
|
@@ -5410,7 +5416,7 @@ with this command:
|
|
5410
5416
|
|
5411
5417
|
produces output like this:
|
5412
5418
|
|
5413
|
-
-- Generated by ExifTool 12.
|
5419
|
+
-- Generated by ExifTool 12.35 --
|
5414
5420
|
File: a.jpg - 2003:10:31 15:44:19
|
5415
5421
|
(f/5.6, 1/60s, ISO 100)
|
5416
5422
|
File: b.jpg - 2006:05:23 11:57:38
|
@@ -5665,12 +5671,14 @@ between B<-W> and B<-w>:
|
|
5665
5671
|
|
5666
5672
|
1) With B<-W>, a new output file is created for each extracted tag.
|
5667
5673
|
|
5668
|
-
2) B<-W> supports
|
5669
|
-
|
5670
|
-
|
5671
|
-
|
5672
|
-
The
|
5673
|
-
|
5674
|
+
2) B<-W> supports four additional format codes: %t, %g and %s represent the
|
5675
|
+
tag name, group name, and suggested extension for the output file (based on
|
5676
|
+
the format of the data), and %o represents the value of the
|
5677
|
+
OriginalRawFileName or OriginalFileName tag from the input file (including
|
5678
|
+
extension). The %g code may be followed by a single digit to specify the
|
5679
|
+
group family number (eg. %g1), otherwise family 0 is assumed. The substring
|
5680
|
+
width/position/case specifiers may be used with these format codes in
|
5681
|
+
exactly the same way as with %f and %e.
|
5674
5682
|
|
5675
5683
|
3) The argument for B<-W> is interpreted as a file name if it contains no
|
5676
5684
|
format codes. (For B<-w>, this would be a file extension.) This change
|
@@ -5690,7 +5698,7 @@ example, the following pairs of commands give the same result:
|
|
5690
5698
|
4) Adding the B<-v> option to B<-W> sends a list of the tags and output file
|
5691
5699
|
names to the console instead of giving a verbose dump of the entire file.
|
5692
5700
|
(Unless appending all output to one file for each source file by using
|
5693
|
-
B<-W+> with an output file I<FMT> that does not contain %t, $g or %
|
5701
|
+
B<-W+> with an output file I<FMT> that does not contain %t, $g, %s or %o.)
|
5694
5702
|
|
5695
5703
|
5) Individual list items are stored in separate files when B<-W> is combined
|
5696
5704
|
with B<-b>, but note that for separate files to be created %c or %C must be
|
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
|
|
88
88
|
sub ProcessExifInfo($$$);
|
89
89
|
sub SwapWords($);
|
90
90
|
|
91
|
-
$VERSION = '4.
|
91
|
+
$VERSION = '4.54';
|
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)
|
@@ -954,6 +954,7 @@ $VERSION = '4.53';
|
|
954
954
|
0x80000435 => 'EOS Rebel T8i / 850D / X10i', #JR/PH
|
955
955
|
0x80000436 => 'EOS SL3 / 250D / Kiss X10', #25
|
956
956
|
0x80000437 => 'EOS 90D', #IB
|
957
|
+
0x80000450 => 'EOS R3', #42
|
957
958
|
0x80000453 => 'EOS R6', #PH
|
958
959
|
0x80000467 => 'PowerShot ZOOM',
|
959
960
|
0x80000468 => 'EOS M50 Mark II / Kiss M2', #IB
|
@@ -24,7 +24,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
24
24
|
use Image::ExifTool::Exif;
|
25
25
|
use Image::ExifTool::GPS;
|
26
26
|
|
27
|
-
$VERSION = '1.
|
27
|
+
$VERSION = '1.19';
|
28
28
|
|
29
29
|
sub ProcessFLIR($$;$);
|
30
30
|
sub ProcessFLIRText($$$);
|
@@ -99,7 +99,7 @@ my %float8g = ( Format => 'float', PrintConv => 'sprintf("%.8g",$val)' );
|
|
99
99
|
NOTES => q{
|
100
100
|
Information extracted from FLIR FFF images and the APP1 FLIR segment of JPEG
|
101
101
|
images. These tags may also be extracted from the first frame of an FLIR
|
102
|
-
SEQ file.
|
102
|
+
SEQ file, or all frames if the ExtractEmbedded option is used.
|
103
103
|
},
|
104
104
|
"_header" => {
|
105
105
|
Name => 'FFFHeader',
|
@@ -1457,6 +1457,7 @@ sub ProcessFLIR($$;$)
|
|
1457
1457
|
my $raf = $$dirInfo{RAF} || new File::RandomAccess($$dirInfo{DataPt});
|
1458
1458
|
my $verbose = $et->Options('Verbose');
|
1459
1459
|
my $out = $et->Options('TextOut');
|
1460
|
+
my $base = $raf->Tell();
|
1460
1461
|
my ($i, $hdr, $buff, $rec);
|
1461
1462
|
|
1462
1463
|
# read and verify FFF header
|
@@ -1485,15 +1486,18 @@ sub ProcessFLIR($$;$)
|
|
1485
1486
|
my $ver = Get32u(\$hdr, 0x14);
|
1486
1487
|
last if $ver >= 100 and $ver < 200; # (have seen 100 and 101 - PH)
|
1487
1488
|
ToggleByteOrder();
|
1488
|
-
|
1489
|
+
next unless $i;
|
1490
|
+
return 0 if $$et{DOC_NUM};
|
1491
|
+
$et->Warn("Unsupported FLIR $type version");
|
1492
|
+
return 1;
|
1489
1493
|
}
|
1490
1494
|
|
1491
1495
|
# read the FLIR record directory
|
1492
1496
|
my $pos = Get32u(\$hdr, 0x18);
|
1493
1497
|
my $num = Get32u(\$hdr, 0x1c);
|
1494
|
-
unless ($raf->Seek($pos) and $raf->Read($buff, $num * 0x20) == $num * 0x20) {
|
1498
|
+
unless ($raf->Seek($base+$pos) and $raf->Read($buff, $num * 0x20) == $num * 0x20) {
|
1495
1499
|
$et->Warn('Truncated FLIR FFF directory');
|
1496
|
-
return 1;
|
1500
|
+
return $$et{DOC_NUM} ? 0 : 1;
|
1497
1501
|
}
|
1498
1502
|
|
1499
1503
|
unless ($tagTablePtr) {
|
@@ -1504,6 +1508,7 @@ sub ProcessFLIR($$;$)
|
|
1504
1508
|
# process the header data
|
1505
1509
|
$et->HandleTag($tagTablePtr, '_header', $hdr);
|
1506
1510
|
|
1511
|
+
my $success = 1;
|
1507
1512
|
my $oldIndent = $$et{INDENT};
|
1508
1513
|
$$et{INDENT} .= '| ';
|
1509
1514
|
$et->VerboseDir($type, $num);
|
@@ -1533,12 +1538,22 @@ sub ProcessFLIR($$;$)
|
|
1533
1538
|
$verbose and printf $out "%s%d) FLIR Record 0x%.2x, offset 0x%.4x, length 0x%.4x\n",
|
1534
1539
|
$$et{INDENT}, $i, $recType, $recPos, $recLen;
|
1535
1540
|
|
1536
|
-
|
1537
|
-
|
1541
|
+
# skip RawData records for embedded documents
|
1542
|
+
if ($recType == 1 and $$et{DOC_NUM}) {
|
1543
|
+
$raf->Seek($base+$recPos+$recLen) or $success = 0, last;
|
1544
|
+
next;
|
1545
|
+
}
|
1546
|
+
unless ($raf->Seek($base+$recPos) and $raf->Read($rec, $recLen) == $recLen) {
|
1547
|
+
if ($$et{DOC_NUM}) {
|
1548
|
+
$success = 0; # abort processing more documents
|
1549
|
+
} else {
|
1550
|
+
$et->Warn('Invalid FLIR record');
|
1551
|
+
}
|
1538
1552
|
last;
|
1539
1553
|
}
|
1540
1554
|
if ($$tagTablePtr{$recType}) {
|
1541
1555
|
$et->HandleTag($tagTablePtr, $recType, undef,
|
1556
|
+
Base => $base,
|
1542
1557
|
DataPt => \$rec,
|
1543
1558
|
DataPos => $recPos,
|
1544
1559
|
Start => 0,
|
@@ -1550,7 +1565,17 @@ sub ProcessFLIR($$;$)
|
|
1550
1565
|
}
|
1551
1566
|
delete $$et{SET_GROUP0};
|
1552
1567
|
$$et{INDENT} = $oldIndent;
|
1553
|
-
|
1568
|
+
|
1569
|
+
# extract information from subsequent frames in SEQ file if ExtractEmbedded is used
|
1570
|
+
if ($$dirInfo{RAF} and $et->Options('ExtractEmbedded') and not $$et{DOC_NUM}) {
|
1571
|
+
for (;;) {
|
1572
|
+
$$et{DOC_NUM} = $$et{DOC_COUNT} + 1;
|
1573
|
+
last unless ProcessFLIR($et, $dirInfo, $tagTablePtr);
|
1574
|
+
# (DOC_COUNT will be incremented automatically if we extracted any tags)
|
1575
|
+
}
|
1576
|
+
delete $$et{DOC_NUM};
|
1577
|
+
}
|
1578
|
+
return $success;
|
1554
1579
|
}
|
1555
1580
|
|
1556
1581
|
#------------------------------------------------------------------------------
|
@@ -25,7 +25,7 @@ use strict;
|
|
25
25
|
use vars qw($VERSION);
|
26
26
|
use Image::ExifTool qw(:DataAccess :Utils);
|
27
27
|
|
28
|
-
$VERSION = '1.
|
28
|
+
$VERSION = '1.38';
|
29
29
|
|
30
30
|
sub ProcessICC($$);
|
31
31
|
sub ProcessICC_Profile($$$);
|
@@ -549,7 +549,7 @@ my %manuSig = ( #6
|
|
549
549
|
A2B3 => 'AToB3',
|
550
550
|
A2M0 => 'AToM0',
|
551
551
|
B2A3 => 'BToA3',
|
552
|
-
bcp0 => '
|
552
|
+
bcp0 => 'BRDFColorimetricParam0',
|
553
553
|
bcp1 => 'BRDFColorimetricParam1',
|
554
554
|
bcp2 => 'BRDFColorimetricParam2',
|
555
555
|
bcp3 => 'BRDFColorimetricParam3',
|
@@ -602,7 +602,7 @@ my %manuSig = ( #6
|
|
602
602
|
gdb2 => 'GamutBoundaryDescription2',
|
603
603
|
gdb3 => 'GamutBoundaryDescription3',
|
604
604
|
'mdv '=> 'MultiplexDefaultValues',
|
605
|
-
mcta => '
|
605
|
+
mcta => 'MultiplexTypeArray',
|
606
606
|
minf => 'MeasurementInfo',
|
607
607
|
miin => 'MeasurementInputInfo',
|
608
608
|
M2A0 => 'MToA0',
|
@@ -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.32';
|
20
20
|
|
21
21
|
sub ProcessJpeg2000Box($$$);
|
22
22
|
sub ProcessJUMD($$$);
|
@@ -42,8 +42,9 @@ my %jp2Map = (
|
|
42
42
|
'UUID-IPTC' => 'JP2',
|
43
43
|
'UUID-EXIF' => 'JP2',
|
44
44
|
'UUID-XMP' => 'JP2',
|
45
|
-
|
46
|
-
|
45
|
+
jp2h => 'JP2',
|
46
|
+
colr => 'jp2h',
|
47
|
+
ICC_Profile => 'colr',
|
47
48
|
IFD1 => 'IFD0',
|
48
49
|
EXIF => 'IFD0', # to write EXIF as a block
|
49
50
|
ExifIFD => 'IFD0',
|
@@ -560,11 +561,31 @@ my %j2cMarker = (
|
|
560
561
|
|
561
562
|
%Image::ExifTool::Jpeg2000::ColorSpec = (
|
562
563
|
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
564
|
+
WRITE_PROC => \&Image::ExifTool::WriteBinaryData, # (we don't actually call this)
|
563
565
|
GROUPS => { 2 => 'Image' },
|
564
566
|
FORMAT => 'int8s',
|
567
|
+
WRITABLE => 1,
|
568
|
+
WRITE_GROUP => 'colr',
|
569
|
+
DATAMEMBER => [ 0 ],
|
570
|
+
IS_SUBDIR => [ 3 ],
|
571
|
+
NOTES => q{
|
572
|
+
The table below contains tags in the color specification (colr) box. This
|
573
|
+
box may be rewritten by writing either ICC_Profile, ColorSpace or
|
574
|
+
ColorSpecData. When writing, any existing colr boxes are replaced with the
|
575
|
+
newly created colr box.
|
576
|
+
|
577
|
+
B<NOTE>: Care must be taken when writing this color specification because
|
578
|
+
writing a specification that is incompatible with the image data may make
|
579
|
+
the image undisplayable.
|
580
|
+
},
|
565
581
|
0 => {
|
566
582
|
Name => 'ColorSpecMethod',
|
567
583
|
RawConv => '$$self{ColorSpecMethod} = $val',
|
584
|
+
Protected => 1,
|
585
|
+
Notes => q{
|
586
|
+
default for writing is 2 when writing ICC_Profile, 1 when writing
|
587
|
+
ColorSpace, or 4 when writing ColorSpecData
|
588
|
+
},
|
568
589
|
PrintConv => {
|
569
590
|
1 => 'Enumerated',
|
570
591
|
2 => 'Restricted ICC',
|
@@ -572,9 +593,15 @@ my %j2cMarker = (
|
|
572
593
|
4 => 'Vendor Color',
|
573
594
|
},
|
574
595
|
},
|
575
|
-
1 =>
|
596
|
+
1 => {
|
597
|
+
Name => 'ColorSpecPrecedence',
|
598
|
+
Notes => 'default for writing is 0',
|
599
|
+
Protected => 1,
|
600
|
+
},
|
576
601
|
2 => {
|
577
602
|
Name => 'ColorSpecApproximation',
|
603
|
+
Notes => 'default for writing is 0',
|
604
|
+
Protected => 1,
|
578
605
|
PrintConv => {
|
579
606
|
0 => 'Not Specified',
|
580
607
|
1 => 'Accurate',
|
@@ -599,6 +626,7 @@ my %j2cMarker = (
|
|
599
626
|
Name => 'ColorSpace',
|
600
627
|
Condition => '$$self{ColorSpecMethod} == 1',
|
601
628
|
Format => 'int32u',
|
629
|
+
Protected => 1,
|
602
630
|
PrintConv => { # ref 15444-2 2002-05-15
|
603
631
|
0 => 'Bi-level',
|
604
632
|
1 => 'YCbCr(1)',
|
@@ -628,6 +656,8 @@ my %j2cMarker = (
|
|
628
656
|
{
|
629
657
|
Name => 'ColorSpecData',
|
630
658
|
Format => 'undef[$size-3]',
|
659
|
+
Writable => 'undef',
|
660
|
+
Protected => 1,
|
631
661
|
Binary => 1,
|
632
662
|
},
|
633
663
|
],
|
@@ -817,6 +847,48 @@ sub CreateNewBoxes($$)
|
|
817
847
|
return 1;
|
818
848
|
}
|
819
849
|
|
850
|
+
#------------------------------------------------------------------------------
|
851
|
+
# Create Color Specification Box
|
852
|
+
# Inputs: 0) ExifTool object ref, 1) Output file or scalar ref
|
853
|
+
# Returns: 1 on success
|
854
|
+
sub CreateColorSpec($$)
|
855
|
+
{
|
856
|
+
my ($et, $outfile) = @_;
|
857
|
+
my $meth = $et->GetNewValue('Jpeg2000:ColorSpecMethod');
|
858
|
+
my $prec = $et->GetNewValue('Jpeg2000:ColorSpecPrecedence') || 0;
|
859
|
+
my $approx = $et->GetNewValue('Jpeg2000:ColorSpecApproximation') || 0;
|
860
|
+
my $icc = $et->GetNewValue('ICC_Profile');
|
861
|
+
my $space = $et->GetNewValue('Jpeg2000:ColorSpace');
|
862
|
+
my $cdata = $et->GetNewValue('Jpeg2000:ColorSpecData');
|
863
|
+
unless ($meth) {
|
864
|
+
if ($icc) {
|
865
|
+
$meth = 2;
|
866
|
+
} elsif (defined $space) {
|
867
|
+
$meth = 1;
|
868
|
+
} elsif (defined $cdata) {
|
869
|
+
$meth = 4;
|
870
|
+
} else {
|
871
|
+
$et->Warn('Color space not defined'), return 0;
|
872
|
+
}
|
873
|
+
}
|
874
|
+
if ($meth eq '1') {
|
875
|
+
defined $space or $et->Warn('Must specify ColorSpace'), return 0;
|
876
|
+
$cdata = pack('N', $space);
|
877
|
+
} elsif ($meth eq '2' or $meth eq '3') {
|
878
|
+
defined $icc or $et->Warn('Must specify ICC_Profile'), return 0;
|
879
|
+
$cdata = $icc;
|
880
|
+
} elsif ($meth eq '4') {
|
881
|
+
defined $cdata or $et->Warn('Must specify ColorSpecData'), return 0;
|
882
|
+
} else {
|
883
|
+
$et->Warn('Unknown ColorSpecMethod'), return 0;
|
884
|
+
}
|
885
|
+
my $boxhdr = pack('N', length($cdata) + 11) . 'colr';
|
886
|
+
Write($outfile, $boxhdr, pack('CCC',$meth,$prec,$approx), $cdata) or return 0;
|
887
|
+
++$$et{CHANGED};
|
888
|
+
$et->VPrint(1, " + Jpeg2000:ColorSpec\n");
|
889
|
+
return 1;
|
890
|
+
}
|
891
|
+
|
820
892
|
#------------------------------------------------------------------------------
|
821
893
|
# Process JPEG 2000 box
|
822
894
|
# Inputs: 0) ExifTool object reference, 1) dirInfo reference, 2) Pointer to tag table
|
@@ -834,7 +906,7 @@ sub ProcessJpeg2000Box($$$)
|
|
834
906
|
my $raf = $$dirInfo{RAF};
|
835
907
|
my $outfile = $$dirInfo{OutFile};
|
836
908
|
my $dirEnd = $dirStart + $dirLen;
|
837
|
-
my ($err, $outBuff, $verbose);
|
909
|
+
my ($err, $outBuff, $verbose, $doColour);
|
838
910
|
|
839
911
|
if ($outfile) {
|
840
912
|
unless ($raf) {
|
@@ -842,13 +914,19 @@ sub ProcessJpeg2000Box($$$)
|
|
842
914
|
$outBuff = '';
|
843
915
|
$outfile = \$outBuff;
|
844
916
|
}
|
917
|
+
# determine if we will be writing colr box
|
918
|
+
if ($$dirInfo{DirName} and $$dirInfo{DirName} eq 'JP2Header') {
|
919
|
+
$doColour = 2 if defined $et->GetNewValue('ColorSpecMethod') or $et->GetNewValue('ICC_Profile') or
|
920
|
+
defined $et->GetNewValue('ColorSpecPrecedence') or defined $et->GetNewValue('ColorSpace') or
|
921
|
+
defined $et->GetNewValue('ColorSpecApproximation') or defined $et->GetNewValue('ColorSpecData');
|
922
|
+
}
|
845
923
|
} else {
|
846
924
|
# (must not set verbose flag when writing!)
|
847
925
|
$verbose = $$et{OPTIONS}{Verbose};
|
848
926
|
$et->VerboseDir($$dirInfo{DirName}) if $verbose;
|
849
927
|
}
|
850
928
|
# loop through all contained boxes
|
851
|
-
my ($pos, $boxLen);
|
929
|
+
my ($pos, $boxLen, $lastBox);
|
852
930
|
for ($pos=$dirStart; ; $pos+=$boxLen) {
|
853
931
|
my ($boxID, $buff, $valuePtr);
|
854
932
|
my $hdrLen = 8; # the box header length
|
@@ -857,9 +935,7 @@ sub ProcessJpeg2000Box($$$)
|
|
857
935
|
my $n = $raf->Read($buff,$hdrLen);
|
858
936
|
unless ($n == $hdrLen) {
|
859
937
|
$n and $err = '', last;
|
860
|
-
|
861
|
-
CreateNewBoxes($et, $outfile) or $err = 1;
|
862
|
-
}
|
938
|
+
CreateNewBoxes($et, $outfile) or $err = 1 if $outfile;
|
863
939
|
last;
|
864
940
|
}
|
865
941
|
$dataPt = \$buff;
|
@@ -871,6 +947,17 @@ sub ProcessJpeg2000Box($$$)
|
|
871
947
|
}
|
872
948
|
$boxLen = unpack("x$pos N",$$dataPt); # (length includes header and data)
|
873
949
|
$boxID = substr($$dataPt, $pos+4, 4);
|
950
|
+
# remove old colr boxes if necessary
|
951
|
+
if ($doColour and $boxID eq 'colr') {
|
952
|
+
if ($doColour == 1) { # did we successfully write the new colr box?
|
953
|
+
$et->VPrint(1," - Jpeg2000:ColorSpec\n");
|
954
|
+
++$$et{CHANGED};
|
955
|
+
next;
|
956
|
+
}
|
957
|
+
$et->Warn('Out-of-order colr box encountered');
|
958
|
+
undef $doColour;
|
959
|
+
}
|
960
|
+
$lastBox = $boxID;
|
874
961
|
$pos += $hdrLen; # move to end of box header
|
875
962
|
if ($boxLen == 1) {
|
876
963
|
# box header contains an additional 8-byte integer for length
|
@@ -1009,8 +1096,10 @@ sub ProcessJpeg2000Box($$$)
|
|
1009
1096
|
# remove this directory from our create list
|
1010
1097
|
delete $$et{AddJp2Dirs}{$$tagInfo{Name}};
|
1011
1098
|
my $newdir;
|
1012
|
-
# only edit writable UUID and
|
1013
|
-
if ($uuid or $boxID eq 'Exif' or ($boxID eq 'xml ' and $$et{IsJXL})
|
1099
|
+
# only edit writable UUID, Exif and jp2h boxes
|
1100
|
+
if ($uuid or $boxID eq 'Exif' or ($boxID eq 'xml ' and $$et{IsJXL}) or
|
1101
|
+
($boxID eq 'jp2h' and $$et{EDIT_DIRS}{jp2h}))
|
1102
|
+
{
|
1014
1103
|
$newdir = $et->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc});
|
1015
1104
|
next if defined $newdir and not length $newdir; # next if deleting the box
|
1016
1105
|
} elsif (defined $uuid) {
|
@@ -1022,6 +1111,11 @@ sub ProcessJpeg2000Box($$$)
|
|
1022
1111
|
my $boxhdr = pack('N', length($newdir) + 8 + $prefixLen) . $boxID;
|
1023
1112
|
$boxhdr .= substr($$dataPt, $valuePtr, $prefixLen) if $prefixLen;
|
1024
1113
|
Write($outfile, $boxhdr, $newdir) or $err = 1;
|
1114
|
+
# write new colr box immediately after ihdr
|
1115
|
+
if ($doColour and $boxID eq 'ihdr') {
|
1116
|
+
# (shouldn't be multiple ihdr boxes, but just in case, write only 1)
|
1117
|
+
$doColour = $doColour==2 ? CreateColorSpec($et, $outfile) : 0;
|
1118
|
+
}
|
1025
1119
|
} else {
|
1026
1120
|
# extract as a block if specified
|
1027
1121
|
$subdirInfo{BlockInfo} = $tagInfo if $$tagInfo{BlockExtract};
|