exiftool-vendored.exe 12.34.0 → 12.38.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.
- package/bin/exiftool_files/Changes +61 -2
- package/bin/exiftool_files/README +2 -2
- package/bin/exiftool_files/exiftool.pl +63 -35
- package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +6 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Canon.pm +143 -9
- package/bin/exiftool_files/lib/Image/ExifTool/CanonCustom.pm +12 -2
- package/bin/exiftool_files/lib/Image/ExifTool/DarwinCore.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Exif.pm +13 -1
- package/bin/exiftool_files/lib/Image/ExifTool/FLIR.pm +33 -8
- package/bin/exiftool_files/lib/Image/ExifTool/GIF.pm +5 -1
- package/bin/exiftool_files/lib/Image/ExifTool/GPS.pm +14 -10
- package/bin/exiftool_files/lib/Image/ExifTool/ICC_Profile.pm +3 -3
- package/bin/exiftool_files/lib/Image/ExifTool/Jpeg2000.pm +108 -11
- package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +1203 -96
- package/bin/exiftool_files/lib/Image/ExifTool/NikonCustom.pm +5 -1
- package/bin/exiftool_files/lib/Image/ExifTool/NikonSettings.pm +135 -71
- package/bin/exiftool_files/lib/Image/ExifTool/OpenEXR.pm +4 -2
- package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +1 -0
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +14 -2
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +26 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +3 -1
- package/bin/exiftool_files/lib/Image/ExifTool/TagInfoXML.pm +9 -4
- package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +6363 -5846
- package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +1215 -39
- package/bin/exiftool_files/lib/Image/ExifTool/WriteXMP.pl +10 -11
- package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +10 -5
- package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +110 -24
- package/bin/exiftool_files/lib/Image/ExifTool/XMP2.pl +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool.pm +51 -12
- package/package.json +2 -2
|
@@ -15,7 +15,7 @@ use strict;
|
|
|
15
15
|
use vars qw($VERSION);
|
|
16
16
|
use Image::ExifTool::XMP;
|
|
17
17
|
|
|
18
|
-
$VERSION = '1.
|
|
18
|
+
$VERSION = '1.06';
|
|
19
19
|
|
|
20
20
|
my %dateTimeInfo = (
|
|
21
21
|
# NOTE: Do NOT put "Groups" here because Groups hash must not be common!
|
|
@@ -38,7 +38,7 @@ my %event = (
|
|
|
38
38
|
earliestDate => { %dateTimeInfo, Groups => { 2 => 'Time' } },
|
|
39
39
|
endDayOfYear => { Writable => 'integer', Groups => { 2 => 'Time' } },
|
|
40
40
|
eventDate => { %dateTimeInfo, Groups => { 2 => 'Time' } },
|
|
41
|
-
eventID => { },
|
|
41
|
+
eventID => { Avoid => 1, Notes => 'avoided in favor of XMP-iptcExt:EventID' },
|
|
42
42
|
eventRemarks => { Writable => 'lang-alt' },
|
|
43
43
|
eventTime => {
|
|
44
44
|
Groups => { 2 => 'Time' },
|
|
@@ -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.38';
|
|
60
60
|
|
|
61
61
|
sub ProcessExif($$$);
|
|
62
62
|
sub WriteExif($$$);
|
|
@@ -4816,11 +4816,23 @@ my %subSecConv = (
|
|
|
4816
4816
|
},
|
|
4817
4817
|
GPSPosition => {
|
|
4818
4818
|
Groups => { 2 => 'Location' },
|
|
4819
|
+
Writable => 1,
|
|
4820
|
+
WriteAlso => {
|
|
4821
|
+
GPSLatitude => '$val =~ /(.*?)( ?[NS])?,/ ? $1 : undef',
|
|
4822
|
+
GPSLatitudeRef => '$val =~ /(-?)(.*?) ?([NS]?),/ ? ($3 || ($1 ? "S" : "N")) : undef',
|
|
4823
|
+
GPSLongitude => '$val =~ /, ?(.*?)( ?[EW]?)$/ ? $1 : undef',
|
|
4824
|
+
GPSLongitudeRef => '$val =~ /, ?(-?)(.*?) ?([EW]?)$/ ? ($3 || ($1 ? "W" : "E")) : undef',
|
|
4825
|
+
},
|
|
4819
4826
|
Require => {
|
|
4820
4827
|
0 => 'GPSLatitude',
|
|
4821
4828
|
1 => 'GPSLongitude',
|
|
4822
4829
|
},
|
|
4823
4830
|
Priority => 0,
|
|
4831
|
+
Notes => q{
|
|
4832
|
+
when written, writes GPSLatitude, GPSLatitudeRef, GPSLongitude and
|
|
4833
|
+
GPSLongitudeRef. This tag may be written using the same coordinate
|
|
4834
|
+
format as provided by Google Maps when right-clicking on a location
|
|
4835
|
+
},
|
|
4824
4836
|
ValueConv => '(length($val[0]) or length($val[1])) ? "$val[0] $val[1]" : undef',
|
|
4825
4837
|
PrintConv => '"$prt[0], $prt[1]"',
|
|
4826
4838
|
},
|
|
@@ -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
|
#------------------------------------------------------------------------------
|
|
@@ -20,7 +20,7 @@ use strict;
|
|
|
20
20
|
use vars qw($VERSION);
|
|
21
21
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
22
22
|
|
|
23
|
-
$VERSION = '1.
|
|
23
|
+
$VERSION = '1.19';
|
|
24
24
|
|
|
25
25
|
# road map of directory locations in GIF images
|
|
26
26
|
my %gifMap = (
|
|
@@ -54,6 +54,7 @@ my %gifMap = (
|
|
|
54
54
|
Extensions => { # (for documentation only)
|
|
55
55
|
SubDirectory => { TagTable => 'Image::ExifTool::GIF::Extensions' },
|
|
56
56
|
},
|
|
57
|
+
TransparentColor => { },
|
|
57
58
|
);
|
|
58
59
|
|
|
59
60
|
# GIF89a application extensions:
|
|
@@ -475,6 +476,9 @@ Block:
|
|
|
475
476
|
my $delay = Get16u(\$buff, 1);
|
|
476
477
|
$delayTime += $delay;
|
|
477
478
|
$verbose and printf $out "Graphic Control: delay=%.2f\n", $delay / 100;
|
|
479
|
+
# get transparent colour
|
|
480
|
+
my $bits = Get8u(\$buff, 0);
|
|
481
|
+
$et->HandleTag($tagTablePtr, 'TransparentColor', Get8u(\$buff,3)) if $bits & 0x01;
|
|
478
482
|
$raf->Seek(-$length, 1) or last;
|
|
479
483
|
|
|
480
484
|
} elsif ($a == 0x01 and $length == 12) { # plain text extension
|
|
@@ -137,22 +137,26 @@ my %coordConv = (
|
|
|
137
137
|
my ($v, $et) = @_;
|
|
138
138
|
$v = $et->TimeNow() if lc($v) eq 'now';
|
|
139
139
|
my @tz;
|
|
140
|
-
if ($v =~ s/([-+])(
|
|
140
|
+
if ($v =~ s/([-+])(\d{1,2}):?(\d{2})\s*(DST)?$//i) { # remove timezone
|
|
141
141
|
my $s = $1 eq '-' ? 1 : -1; # opposite sign to convert back to UTC
|
|
142
142
|
my $t = $2;
|
|
143
|
-
@tz = ($s*$
|
|
143
|
+
@tz = ($s*$2, $s*$3);
|
|
144
144
|
}
|
|
145
|
-
|
|
146
|
-
|
|
145
|
+
# (note: we must allow '.' as a time separator, eg. '10.30.00', with is tricky due to decimal seconds)
|
|
146
|
+
# YYYYmmddHHMMSS[.ss] format
|
|
147
|
+
my @a = ($v =~ /^[^\d]*\d{4}[^\d]*\d{1,2}[^\d]*\d{1,2}[^\d]*(\d{1,2})[^\d]*(\d{2})[^\d]*(\d{2}(?:\.\d+)?)[^\d]*$/);
|
|
148
|
+
# HHMMSS[.ss] format
|
|
149
|
+
@a or @a = ($v =~ /^[^\d]*(\d{1,2})[^\d]*(\d{2})[^\d]*(\d{2}(?:\.\d+)?)[^\d]*$/);
|
|
150
|
+
@a or warn('Invalid time (use HH:MM:SS[.ss][+/-HH:MM|Z])'), return undef;
|
|
147
151
|
if (@tz) {
|
|
148
152
|
# adjust to UTC
|
|
149
|
-
$a[
|
|
150
|
-
$a[
|
|
151
|
-
while ($a[
|
|
152
|
-
while ($a[
|
|
153
|
-
$a[
|
|
153
|
+
$a[1] += $tz[1];
|
|
154
|
+
$a[0] += $tz[0];
|
|
155
|
+
while ($a[1] >= 60) { $a[1] -= 60; ++$a[0] }
|
|
156
|
+
while ($a[1] < 0) { $a[1] += 60; --$a[0] }
|
|
157
|
+
$a[0] = ($a[0] + 24) % 24;
|
|
154
158
|
}
|
|
155
|
-
return
|
|
159
|
+
return join(':', @a);
|
|
156
160
|
},
|
|
157
161
|
},
|
|
158
162
|
0x0008 => {
|
|
@@ -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,34 @@ 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
|
+
# (Note: 'colr' is not a real group, but is used as a hack to write the
|
|
569
|
+
# necessary colr box. This hack necessitated another hack in TagInfoXML.pm
|
|
570
|
+
# to avoid reporting this fake group in the XML output)
|
|
571
|
+
WRITE_GROUP => 'colr',
|
|
572
|
+
DATAMEMBER => [ 0 ],
|
|
573
|
+
IS_SUBDIR => [ 3 ],
|
|
574
|
+
NOTES => q{
|
|
575
|
+
The table below contains tags in the color specification (colr) box. This
|
|
576
|
+
box may be rewritten by writing either ICC_Profile, ColorSpace or
|
|
577
|
+
ColorSpecData. When writing, any existing colr boxes are replaced with the
|
|
578
|
+
newly created colr box.
|
|
579
|
+
|
|
580
|
+
B<NOTE>: Care must be taken when writing this color specification because
|
|
581
|
+
writing a specification that is incompatible with the image data may make
|
|
582
|
+
the image undisplayable.
|
|
583
|
+
},
|
|
565
584
|
0 => {
|
|
566
585
|
Name => 'ColorSpecMethod',
|
|
567
586
|
RawConv => '$$self{ColorSpecMethod} = $val',
|
|
587
|
+
Protected => 1,
|
|
588
|
+
Notes => q{
|
|
589
|
+
default for writing is 2 when writing ICC_Profile, 1 when writing
|
|
590
|
+
ColorSpace, or 4 when writing ColorSpecData
|
|
591
|
+
},
|
|
568
592
|
PrintConv => {
|
|
569
593
|
1 => 'Enumerated',
|
|
570
594
|
2 => 'Restricted ICC',
|
|
@@ -572,9 +596,15 @@ my %j2cMarker = (
|
|
|
572
596
|
4 => 'Vendor Color',
|
|
573
597
|
},
|
|
574
598
|
},
|
|
575
|
-
1 =>
|
|
599
|
+
1 => {
|
|
600
|
+
Name => 'ColorSpecPrecedence',
|
|
601
|
+
Notes => 'default for writing is 0',
|
|
602
|
+
Protected => 1,
|
|
603
|
+
},
|
|
576
604
|
2 => {
|
|
577
605
|
Name => 'ColorSpecApproximation',
|
|
606
|
+
Notes => 'default for writing is 0',
|
|
607
|
+
Protected => 1,
|
|
578
608
|
PrintConv => {
|
|
579
609
|
0 => 'Not Specified',
|
|
580
610
|
1 => 'Accurate',
|
|
@@ -599,6 +629,7 @@ my %j2cMarker = (
|
|
|
599
629
|
Name => 'ColorSpace',
|
|
600
630
|
Condition => '$$self{ColorSpecMethod} == 1',
|
|
601
631
|
Format => 'int32u',
|
|
632
|
+
Protected => 1,
|
|
602
633
|
PrintConv => { # ref 15444-2 2002-05-15
|
|
603
634
|
0 => 'Bi-level',
|
|
604
635
|
1 => 'YCbCr(1)',
|
|
@@ -628,6 +659,8 @@ my %j2cMarker = (
|
|
|
628
659
|
{
|
|
629
660
|
Name => 'ColorSpecData',
|
|
630
661
|
Format => 'undef[$size-3]',
|
|
662
|
+
Writable => 'undef',
|
|
663
|
+
Protected => 1,
|
|
631
664
|
Binary => 1,
|
|
632
665
|
},
|
|
633
666
|
],
|
|
@@ -817,6 +850,48 @@ sub CreateNewBoxes($$)
|
|
|
817
850
|
return 1;
|
|
818
851
|
}
|
|
819
852
|
|
|
853
|
+
#------------------------------------------------------------------------------
|
|
854
|
+
# Create Color Specification Box
|
|
855
|
+
# Inputs: 0) ExifTool object ref, 1) Output file or scalar ref
|
|
856
|
+
# Returns: 1 on success
|
|
857
|
+
sub CreateColorSpec($$)
|
|
858
|
+
{
|
|
859
|
+
my ($et, $outfile) = @_;
|
|
860
|
+
my $meth = $et->GetNewValue('Jpeg2000:ColorSpecMethod');
|
|
861
|
+
my $prec = $et->GetNewValue('Jpeg2000:ColorSpecPrecedence') || 0;
|
|
862
|
+
my $approx = $et->GetNewValue('Jpeg2000:ColorSpecApproximation') || 0;
|
|
863
|
+
my $icc = $et->GetNewValue('ICC_Profile');
|
|
864
|
+
my $space = $et->GetNewValue('Jpeg2000:ColorSpace');
|
|
865
|
+
my $cdata = $et->GetNewValue('Jpeg2000:ColorSpecData');
|
|
866
|
+
unless ($meth) {
|
|
867
|
+
if ($icc) {
|
|
868
|
+
$meth = 2;
|
|
869
|
+
} elsif (defined $space) {
|
|
870
|
+
$meth = 1;
|
|
871
|
+
} elsif (defined $cdata) {
|
|
872
|
+
$meth = 4;
|
|
873
|
+
} else {
|
|
874
|
+
$et->Warn('Color space not defined'), return 0;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
if ($meth eq '1') {
|
|
878
|
+
defined $space or $et->Warn('Must specify ColorSpace'), return 0;
|
|
879
|
+
$cdata = pack('N', $space);
|
|
880
|
+
} elsif ($meth eq '2' or $meth eq '3') {
|
|
881
|
+
defined $icc or $et->Warn('Must specify ICC_Profile'), return 0;
|
|
882
|
+
$cdata = $icc;
|
|
883
|
+
} elsif ($meth eq '4') {
|
|
884
|
+
defined $cdata or $et->Warn('Must specify ColorSpecData'), return 0;
|
|
885
|
+
} else {
|
|
886
|
+
$et->Warn('Unknown ColorSpecMethod'), return 0;
|
|
887
|
+
}
|
|
888
|
+
my $boxhdr = pack('N', length($cdata) + 11) . 'colr';
|
|
889
|
+
Write($outfile, $boxhdr, pack('CCC',$meth,$prec,$approx), $cdata) or return 0;
|
|
890
|
+
++$$et{CHANGED};
|
|
891
|
+
$et->VPrint(1, " + Jpeg2000:ColorSpec\n");
|
|
892
|
+
return 1;
|
|
893
|
+
}
|
|
894
|
+
|
|
820
895
|
#------------------------------------------------------------------------------
|
|
821
896
|
# Process JPEG 2000 box
|
|
822
897
|
# Inputs: 0) ExifTool object reference, 1) dirInfo reference, 2) Pointer to tag table
|
|
@@ -834,7 +909,7 @@ sub ProcessJpeg2000Box($$$)
|
|
|
834
909
|
my $raf = $$dirInfo{RAF};
|
|
835
910
|
my $outfile = $$dirInfo{OutFile};
|
|
836
911
|
my $dirEnd = $dirStart + $dirLen;
|
|
837
|
-
my ($err, $outBuff, $verbose);
|
|
912
|
+
my ($err, $outBuff, $verbose, $doColour);
|
|
838
913
|
|
|
839
914
|
if ($outfile) {
|
|
840
915
|
unless ($raf) {
|
|
@@ -842,13 +917,19 @@ sub ProcessJpeg2000Box($$$)
|
|
|
842
917
|
$outBuff = '';
|
|
843
918
|
$outfile = \$outBuff;
|
|
844
919
|
}
|
|
920
|
+
# determine if we will be writing colr box
|
|
921
|
+
if ($$dirInfo{DirName} and $$dirInfo{DirName} eq 'JP2Header') {
|
|
922
|
+
$doColour = 2 if defined $et->GetNewValue('ColorSpecMethod') or $et->GetNewValue('ICC_Profile') or
|
|
923
|
+
defined $et->GetNewValue('ColorSpecPrecedence') or defined $et->GetNewValue('ColorSpace') or
|
|
924
|
+
defined $et->GetNewValue('ColorSpecApproximation') or defined $et->GetNewValue('ColorSpecData');
|
|
925
|
+
}
|
|
845
926
|
} else {
|
|
846
927
|
# (must not set verbose flag when writing!)
|
|
847
928
|
$verbose = $$et{OPTIONS}{Verbose};
|
|
848
929
|
$et->VerboseDir($$dirInfo{DirName}) if $verbose;
|
|
849
930
|
}
|
|
850
931
|
# loop through all contained boxes
|
|
851
|
-
my ($pos, $boxLen);
|
|
932
|
+
my ($pos, $boxLen, $lastBox);
|
|
852
933
|
for ($pos=$dirStart; ; $pos+=$boxLen) {
|
|
853
934
|
my ($boxID, $buff, $valuePtr);
|
|
854
935
|
my $hdrLen = 8; # the box header length
|
|
@@ -857,9 +938,7 @@ sub ProcessJpeg2000Box($$$)
|
|
|
857
938
|
my $n = $raf->Read($buff,$hdrLen);
|
|
858
939
|
unless ($n == $hdrLen) {
|
|
859
940
|
$n and $err = '', last;
|
|
860
|
-
|
|
861
|
-
CreateNewBoxes($et, $outfile) or $err = 1;
|
|
862
|
-
}
|
|
941
|
+
CreateNewBoxes($et, $outfile) or $err = 1 if $outfile;
|
|
863
942
|
last;
|
|
864
943
|
}
|
|
865
944
|
$dataPt = \$buff;
|
|
@@ -871,6 +950,17 @@ sub ProcessJpeg2000Box($$$)
|
|
|
871
950
|
}
|
|
872
951
|
$boxLen = unpack("x$pos N",$$dataPt); # (length includes header and data)
|
|
873
952
|
$boxID = substr($$dataPt, $pos+4, 4);
|
|
953
|
+
# remove old colr boxes if necessary
|
|
954
|
+
if ($doColour and $boxID eq 'colr') {
|
|
955
|
+
if ($doColour == 1) { # did we successfully write the new colr box?
|
|
956
|
+
$et->VPrint(1," - Jpeg2000:ColorSpec\n");
|
|
957
|
+
++$$et{CHANGED};
|
|
958
|
+
next;
|
|
959
|
+
}
|
|
960
|
+
$et->Warn('Out-of-order colr box encountered');
|
|
961
|
+
undef $doColour;
|
|
962
|
+
}
|
|
963
|
+
$lastBox = $boxID;
|
|
874
964
|
$pos += $hdrLen; # move to end of box header
|
|
875
965
|
if ($boxLen == 1) {
|
|
876
966
|
# box header contains an additional 8-byte integer for length
|
|
@@ -1009,8 +1099,10 @@ sub ProcessJpeg2000Box($$$)
|
|
|
1009
1099
|
# remove this directory from our create list
|
|
1010
1100
|
delete $$et{AddJp2Dirs}{$$tagInfo{Name}};
|
|
1011
1101
|
my $newdir;
|
|
1012
|
-
# only edit writable UUID and
|
|
1013
|
-
if ($uuid or $boxID eq 'Exif' or ($boxID eq 'xml ' and $$et{IsJXL})
|
|
1102
|
+
# only edit writable UUID, Exif and jp2h boxes
|
|
1103
|
+
if ($uuid or $boxID eq 'Exif' or ($boxID eq 'xml ' and $$et{IsJXL}) or
|
|
1104
|
+
($boxID eq 'jp2h' and $$et{EDIT_DIRS}{jp2h}))
|
|
1105
|
+
{
|
|
1014
1106
|
$newdir = $et->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc});
|
|
1015
1107
|
next if defined $newdir and not length $newdir; # next if deleting the box
|
|
1016
1108
|
} elsif (defined $uuid) {
|
|
@@ -1022,6 +1114,11 @@ sub ProcessJpeg2000Box($$$)
|
|
|
1022
1114
|
my $boxhdr = pack('N', length($newdir) + 8 + $prefixLen) . $boxID;
|
|
1023
1115
|
$boxhdr .= substr($$dataPt, $valuePtr, $prefixLen) if $prefixLen;
|
|
1024
1116
|
Write($outfile, $boxhdr, $newdir) or $err = 1;
|
|
1117
|
+
# write new colr box immediately after ihdr
|
|
1118
|
+
if ($doColour and $boxID eq 'ihdr') {
|
|
1119
|
+
# (shouldn't be multiple ihdr boxes, but just in case, write only 1)
|
|
1120
|
+
$doColour = $doColour==2 ? CreateColorSpec($et, $outfile) : 0;
|
|
1121
|
+
}
|
|
1025
1122
|
} else {
|
|
1026
1123
|
# extract as a block if specified
|
|
1027
1124
|
$subdirInfo{BlockInfo} = $tagInfo if $$tagInfo{BlockExtract};
|