exiftool_vendored 11.62.0 → 11.63.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 +13 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +2 -2
- data/bin/exiftool +12 -12
- data/bin/lib/Image/ExifTool.pm +7 -7
- data/bin/lib/Image/ExifTool/Canon.pm +4 -4
- data/bin/lib/Image/ExifTool/Exif.pm +2 -2
- data/bin/lib/Image/ExifTool/Minolta.pm +23 -23
- data/bin/lib/Image/ExifTool/PNG.pm +86 -94
- data/bin/lib/Image/ExifTool/QuickTime.pm +9 -7
- data/bin/lib/Image/ExifTool/README +4 -0
- data/bin/lib/Image/ExifTool/Sigma.pm +5 -1
- data/bin/lib/Image/ExifTool/TagNames.pod +10 -2
- data/bin/lib/Image/ExifTool/Validate.pm +1 -1
- data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +3 -3
- data/bin/lib/Image/ExifTool/WritePNG.pl +9 -8
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +21 -16
- data/bin/lib/Image/ExifTool/Writer.pl +2 -2
- 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
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ea6e0dbd2fcc5d00e9ea0e5fdfa01cf96f64aaf6
|
|
4
|
+
data.tar.gz: 6448e540c1fa5c44c3ff28d6771c14ac3da1b02c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 73f15e2bb7259f5f1e08ba426f7dca7305d0ae2e71efc50173029a83efdc51ff2cc68ef1942a850ea8eafb56eb81f43f68756a57096fb222a39928ab6a994541
|
|
7
|
+
data.tar.gz: 8aaec703cd4a179de8e9acc3115e3d96c73a25c38a1f60396049db05a11a763fe8033f50da926f4ab08f0e25e44054e82a9e8add022f51e524f381c9c1a1477c
|
data/bin/Changes
CHANGED
|
@@ -7,6 +7,19 @@ RSS feed: http://owl.phy.queensu.ca/~phil/exiftool/rss.xml
|
|
|
7
7
|
Note: The most recent production release is Version 11.50. (Other versions are
|
|
8
8
|
considered development releases, and are not uploaded to CPAN.)
|
|
9
9
|
|
|
10
|
+
Aug. 20, 2019 - Version 11.63 - "PNG Early Text"
|
|
11
|
+
|
|
12
|
+
- Added a few new Sigma lenses (thanks LibRaw)
|
|
13
|
+
- Improved handling of Canon CNTH atom in MOV/MP4 videos
|
|
14
|
+
- Changed PNG writer to place all text chunks before IDAT (not just XMP)
|
|
15
|
+
- Issue minor warning for any text chunk after PNG IDAT (not just XMP)
|
|
16
|
+
- Enhanced ForceWrite feature to allow "PNG" to be specified (to move existing
|
|
17
|
+
text chunks to before IDAT without editing any metadata)
|
|
18
|
+
- Removed Windows "surrogate" warning for files that wouldn't be processed
|
|
19
|
+
anyway
|
|
20
|
+
- Fixed some entries in the Minolta LensType list (thanks Jos Roost)
|
|
21
|
+
- Fixed identification of a Sony lens (thanks Jos Roost)
|
|
22
|
+
|
|
10
23
|
Aug. 15, 2019 - Version 11.62
|
|
11
24
|
|
|
12
25
|
- Added a number of new Canon, Pentax, Sony and Sigma lenses (thanks LibRaw)
|
data/bin/META.json
CHANGED
data/bin/META.yml
CHANGED
data/bin/README
CHANGED
|
@@ -104,8 +104,8 @@ your home directory, then you would type the following commands in a
|
|
|
104
104
|
terminal window to extract and run ExifTool:
|
|
105
105
|
|
|
106
106
|
cd ~/Desktop
|
|
107
|
-
gzip -dc Image-ExifTool-11.
|
|
108
|
-
cd Image-ExifTool-11.
|
|
107
|
+
gzip -dc Image-ExifTool-11.63.tar.gz | tar -xf -
|
|
108
|
+
cd Image-ExifTool-11.63
|
|
109
109
|
./exiftool t/images/ExifTool.jpg
|
|
110
110
|
|
|
111
111
|
Note: These commands extract meta information from one of the test images.
|
data/bin/exiftool
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
use strict;
|
|
11
11
|
require 5.004;
|
|
12
12
|
|
|
13
|
-
my $version = '11.
|
|
13
|
+
my $version = '11.63';
|
|
14
14
|
|
|
15
15
|
# add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
|
|
16
16
|
my $exeDir;
|
|
@@ -3569,16 +3569,6 @@ sub ScanDir($$;$)
|
|
|
3569
3569
|
ScanDir($et, $path, $list);
|
|
3570
3570
|
next;
|
|
3571
3571
|
}
|
|
3572
|
-
# Windows patch to avoid replacing filename containing Unicode surrogate with 8.3 name
|
|
3573
|
-
if ($winSurrogate and $isWriting and
|
|
3574
|
-
(not $overwriteOrig or $overwriteOrig != 2) and
|
|
3575
|
-
not $doSetFileName and $file =~ /~/) # (8.3 name will contain a tilde)
|
|
3576
|
-
{
|
|
3577
|
-
Warn("Not writing $path\n");
|
|
3578
|
-
WarnOnce("Use -overwrite_original_in_place to write files with Unicode surrogate characters\n");
|
|
3579
|
-
++$countBad;
|
|
3580
|
-
next;
|
|
3581
|
-
}
|
|
3582
3572
|
# apply rules from -ext options
|
|
3583
3573
|
my $accepted;
|
|
3584
3574
|
if ($filterFlag) {
|
|
@@ -3600,6 +3590,16 @@ sub ScanDir($$;$)
|
|
|
3600
3590
|
next unless $file =~ /\.(gz|bz2)$/i;
|
|
3601
3591
|
}
|
|
3602
3592
|
}
|
|
3593
|
+
# Windows patch to avoid replacing filename containing Unicode surrogate with 8.3 name
|
|
3594
|
+
if ($winSurrogate and $isWriting and
|
|
3595
|
+
(not $overwriteOrig or $overwriteOrig != 2) and
|
|
3596
|
+
not $doSetFileName and $file =~ /~/) # (8.3 name will contain a tilde)
|
|
3597
|
+
{
|
|
3598
|
+
Warn("Not writing $path\n");
|
|
3599
|
+
WarnOnce("Use -overwrite_original_in_place to write files with Unicode surrogate characters\n");
|
|
3600
|
+
++$countBad;
|
|
3601
|
+
next;
|
|
3602
|
+
}
|
|
3603
3603
|
$utf8FileName{$path} = 1 if $utf8Name;
|
|
3604
3604
|
if ($list) {
|
|
3605
3605
|
push(@$list, $path);
|
|
@@ -5168,7 +5168,7 @@ with this command:
|
|
|
5168
5168
|
|
|
5169
5169
|
produces output like this:
|
|
5170
5170
|
|
|
5171
|
-
-- Generated by ExifTool 11.
|
|
5171
|
+
-- Generated by ExifTool 11.63 --
|
|
5172
5172
|
File: a.jpg - 2003:10:31 15:44:19
|
|
5173
5173
|
(f/5.6, 1/60s, ISO 100)
|
|
5174
5174
|
File: b.jpg - 2006:05:23 11:57:38
|
data/bin/lib/Image/ExifTool.pm
CHANGED
|
@@ -27,7 +27,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
|
|
|
27
27
|
%mimeType $swapBytes $swapWords $currentByteOrder %unpackStd
|
|
28
28
|
%jpegMarker %specialTags %fileTypeLookup);
|
|
29
29
|
|
|
30
|
-
$VERSION = '11.
|
|
30
|
+
$VERSION = '11.63';
|
|
31
31
|
$RELEASE = '';
|
|
32
32
|
@ISA = qw(Exporter);
|
|
33
33
|
%EXPORT_TAGS = (
|
|
@@ -1674,12 +1674,12 @@ my %systemTagsNotes = (
|
|
|
1674
1674
|
Writable => 1,
|
|
1675
1675
|
WriteOnly => 1,
|
|
1676
1676
|
Notes => q{
|
|
1677
|
-
write-only tag used to force EXIF, IPTC
|
|
1678
|
-
rewritten. May be set to "EXIF", "IPTC" or "
|
|
1679
|
-
metadata type to be rewritten, "FixBase" to cause EXIF to be
|
|
1680
|
-
the MakerNotes offset base was fixed, or "All" to rewrite
|
|
1681
|
-
types. Values are case insensitive, and multiple
|
|
1682
|
-
commas, eg. C<-ForceWrite=exif,xmp>
|
|
1677
|
+
write-only tag used to force EXIF, IPTC, XMP or PNG metadata in a file to be
|
|
1678
|
+
rewritten. May be set to "EXIF", "IPTC", "XMP" or "PNG" to force the
|
|
1679
|
+
corresponding metadata type to be rewritten, "FixBase" to cause EXIF to be
|
|
1680
|
+
rewritten only if the MakerNotes offset base was fixed, or "All" to rewrite
|
|
1681
|
+
all of these metadata types. Values are case insensitive, and multiple
|
|
1682
|
+
values may be separated with commas, eg. C<-ForceWrite=exif,xmp>
|
|
1683
1683
|
},
|
|
1684
1684
|
},
|
|
1685
1685
|
EmbeddedVideo => { Groups => { 2 => 'Video' } },
|
|
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
|
|
|
88
88
|
sub ProcessExifInfo($$$);
|
|
89
89
|
sub SwapWords($);
|
|
90
90
|
|
|
91
|
-
$VERSION = '4.
|
|
91
|
+
$VERSION = '4.22';
|
|
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)
|
|
@@ -8656,12 +8656,12 @@ my %filterConv = (
|
|
|
8656
8656
|
|
|
8657
8657
|
%Image::ExifTool::Canon::CNTH = (
|
|
8658
8658
|
GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Video' },
|
|
8659
|
-
VARS => {
|
|
8659
|
+
VARS => { ATOM_COUNT => 1 }, # only one contained atom
|
|
8660
8660
|
WRITABLE => 1,
|
|
8661
8661
|
WRITE_PROC => 'Image::ExifTool::QuickTime::WriteQuickTime',
|
|
8662
8662
|
NOTES => q{
|
|
8663
|
-
Canon-specific QuickTime tags found in the CNTH atom of MOV videos from
|
|
8664
|
-
cameras
|
|
8663
|
+
Canon-specific QuickTime tags found in the CNTH atom of MOV/MP4 videos from
|
|
8664
|
+
some cameras.
|
|
8665
8665
|
},
|
|
8666
8666
|
CNDA => {
|
|
8667
8667
|
Name => 'ThumbnailImage',
|
|
@@ -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.22';
|
|
60
60
|
|
|
61
61
|
sub ProcessExif($$$);
|
|
62
62
|
sub WriteExif($$$);
|
|
@@ -5281,7 +5281,7 @@ sub PrintLensID($$@)
|
|
|
5281
5281
|
# excluding any part between () at the end, and preceded by a space (the space
|
|
5282
5282
|
# ensures that e.g. Zeiss Loxia 21mm having LensSpec "E 21mm F2.8" will not be
|
|
5283
5283
|
# identified as "Sony FE 21mm F2.8 (SEL28F20 + SEL075UWC)")
|
|
5284
|
-
$lensSpecPrt and $lens =~ / \Q$lensSpecPrt\E( \(
|
|
5284
|
+
$lensSpecPrt and $lens =~ / \Q$lensSpecPrt\E( \(| GM$|$)/ and @best = ( $lens ), last;
|
|
5285
5285
|
# exactly-matching Sony lens should have been found above, so only add non-Sony lenses
|
|
5286
5286
|
push @best, $lens unless $lens =~ /^Sony /;
|
|
5287
5287
|
next;
|
|
@@ -49,7 +49,7 @@ use vars qw($VERSION %minoltaLensTypes %minoltaTeleconverters %minoltaColorMode
|
|
|
49
49
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
50
50
|
use Image::ExifTool::Exif;
|
|
51
51
|
|
|
52
|
-
$VERSION = '2.
|
|
52
|
+
$VERSION = '2.82';
|
|
53
53
|
|
|
54
54
|
# Full list of product codes for Sony-compatible Minolta lenses
|
|
55
55
|
# (ref http://www.kb.sony.com/selfservice/documentLink.do?externalId=C1000570)
|
|
@@ -291,7 +291,7 @@ $VERSION = '2.81';
|
|
|
291
291
|
47 => 'Carl Zeiss Sonnar T* 135mm F1.8 ZA (SAL135F18Z)', #JR
|
|
292
292
|
48 => 'Carl Zeiss Vario-Sonnar T* 24-70mm F2.8 ZA SSM (SAL2470Z) or Other Lens', #11/JR
|
|
293
293
|
48.1 => 'Carl Zeiss Vario-Sonnar T* 24-70mm F2.8 ZA SSM II (SAL2470Z2)', #JR
|
|
294
|
-
48.2 => 'Tamron SP 24-70mm F2.8 Di USD', #IB (A007)
|
|
294
|
+
48.2 => 'Tamron SP 24-70mm F2.8 Di USD', #IB (A007) (also with id 204)
|
|
295
295
|
49 => 'Sony DT 55-200mm F4-5.6 (SAL55200)', #JD/JR
|
|
296
296
|
50 => 'Sony DT 18-250mm F3.5-6.3 (SAL18250)', #11/JR
|
|
297
297
|
51 => 'Sony DT 16-105mm F3.5-5.6 (SAL16105)', #11/JR
|
|
@@ -337,25 +337,25 @@ $VERSION = '2.81';
|
|
|
337
337
|
128.7 => 'Sigma 70-200mm F2.8 II EX DG APO MACRO HSM', #24
|
|
338
338
|
128.8 => 'Sigma 10mm F2.8 EX DC HSM Fisheye', #Florian Knorn
|
|
339
339
|
# (yes, '128.10'. My condolences to typed languages that use this database - PH)
|
|
340
|
-
|
|
341
|
-
'128.
|
|
342
|
-
'128.
|
|
343
|
-
'128.
|
|
344
|
-
'128.
|
|
345
|
-
'128.
|
|
346
|
-
'128.
|
|
347
|
-
'128.
|
|
348
|
-
'128.
|
|
349
|
-
'128.
|
|
350
|
-
'128.
|
|
351
|
-
'128.
|
|
352
|
-
'128.
|
|
353
|
-
'128.
|
|
354
|
-
'128.
|
|
355
|
-
'128.
|
|
356
|
-
'128.
|
|
357
|
-
'128.
|
|
358
|
-
'128.
|
|
340
|
+
128.9 => 'Sigma 50mm F1.4 EX DG HSM', #Florian Knorn (Model A014, ref IB)
|
|
341
|
+
'128.10' => 'Sigma 85mm F1.4 EX DG HSM', #27
|
|
342
|
+
'128.11' => 'Sigma 24-70mm F2.8 IF EX DG HSM', #27
|
|
343
|
+
'128.12' => 'Sigma 18-250mm F3.5-6.3 DC OS HSM', #27
|
|
344
|
+
'128.13' => 'Sigma 17-50mm F2.8 EX DC HSM', #Exiv2
|
|
345
|
+
'128.14' => 'Sigma 17-70mm F2.8-4 DC Macro HSM', #JR (OS Model C013, ref IB)
|
|
346
|
+
'128.15' => 'Sigma 150mm F2.8 EX DG OS HSM APO Macro', #Marcus Holland-Moritz
|
|
347
|
+
'128.16' => 'Sigma 150-500mm F5-6.3 APO DG OS HSM', #IB
|
|
348
|
+
'128.17' => 'Tamron AF 28-105mm F4-5.6 [IF]', #IB (Model 179D)
|
|
349
|
+
'128.18' => 'Sigma 35mm F1.4 DG HSM', #JR
|
|
350
|
+
'128.19' => 'Sigma 18-35mm F1.8 DC HSM', #JR (Model A013, ref IB)
|
|
351
|
+
'128.20' => 'Sigma 50-500mm F4.5-6.3 APO DG OS HSM', #JR
|
|
352
|
+
'128.21' => 'Sigma 24-105mm F4 DG HSM | A', #JR (013)
|
|
353
|
+
'128.22' => 'Sigma 30mm F1.4', #IB
|
|
354
|
+
'128.23' => 'Sigma 35mm F1.4 DG HSM | A', #IB/JR (012)
|
|
355
|
+
'128.24' => 'Sigma 105mm F2.8 EX DG OS HSM Macro', #IB
|
|
356
|
+
'128.25' => 'Sigma 180mm F2.8 EX DG OS HSM APO Macro', #IB
|
|
357
|
+
'128.26' => 'Sigma 18-300mm F3.5-6.3 DC Macro HSM | C', #IB/JR (014)
|
|
358
|
+
'128.27' => 'Sigma 18-50mm F2.8-4.5 DC HSM', #IB
|
|
359
359
|
129 => 'Tamron Lens (129)',
|
|
360
360
|
129.1 => 'Tamron 200-400mm F5.6 LD', #12 (LD ref 23)
|
|
361
361
|
129.2 => 'Tamron 70-300mm F4-5.6 LD', #12
|
|
@@ -372,7 +372,7 @@ $VERSION = '2.81';
|
|
|
372
372
|
194 => 'Tamron SP AF 17-50mm F2.8 XR Di II LD Aspherical [IF]', #23 (Model A16)
|
|
373
373
|
202 => 'Tamron SP AF 70-200mm F2.8 Di LD [IF] Macro', #JR (Model A001) (see also 255.7)
|
|
374
374
|
203 => 'Tamron SP 70-200mm F2.8 Di USD', #JR (Model A009)
|
|
375
|
-
204 => 'Tamron SP 24-70mm F2.8 Di USD', #JR (Model A007)
|
|
375
|
+
204 => 'Tamron SP 24-70mm F2.8 Di USD', #JR (Model A007) (also with id 48)
|
|
376
376
|
212 => 'Tamron 28-300mm F3.5-6.3 Di PZD', #JR (Model A010)
|
|
377
377
|
213 => 'Tamron 16-300mm F3.5-6.3 Di II PZD Macro', #JR (Model B016)
|
|
378
378
|
214 => 'Tamron SP 150-600mm F5-6.3 Di USD', #JR (Model A011)
|
|
@@ -505,7 +505,7 @@ $VERSION = '2.81';
|
|
|
505
505
|
26241 => 'Minolta AF 35-80mm F4-5.6 Power Zoom',
|
|
506
506
|
26281 => 'Minolta AF 80-200mm F2.8 HS-APO G', #11 ("HS-APO" added, white, probably same as 1, non-HS is 25891 - ref JR)
|
|
507
507
|
26291 => 'Minolta AF 85mm F1.4 New',
|
|
508
|
-
26311 => 'Minolta
|
|
508
|
+
26311 => 'Minolta AF 100-300mm F4.5-5.6 APO', #11 (does not exist? https://www.dyxum.com/dforum/lens-data-requested_topic23435_page2.html)
|
|
509
509
|
26321 => 'Minolta AF 24-50mm F4 New',
|
|
510
510
|
26381 => 'Minolta AF 50mm F2.8 Macro New',
|
|
511
511
|
26391 => 'Minolta AF 100mm F2.8 Macro',
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
# comes before IDAT. As of version 11.58, ExifTool uses a 2-pass
|
|
27
27
|
# writing algorithm to allow it to be compatible with XMP after
|
|
28
28
|
# IDAT while writing it before IDAT. (PNG and EXIF are still
|
|
29
|
-
# written after IDAT.)
|
|
29
|
+
# written after IDAT.) As of version 11.63, this strategy is
|
|
30
|
+
# applied to all text chunks (tEXt, zTXt and iTXt).
|
|
30
31
|
#------------------------------------------------------------------------------
|
|
31
32
|
|
|
32
33
|
package Image::ExifTool::PNG;
|
|
@@ -35,7 +36,7 @@ use strict;
|
|
|
35
36
|
use vars qw($VERSION $AUTOLOAD %stdCase);
|
|
36
37
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
37
38
|
|
|
38
|
-
$VERSION = '1.
|
|
39
|
+
$VERSION = '1.52';
|
|
39
40
|
|
|
40
41
|
sub ProcessPNG_tEXt($$$);
|
|
41
42
|
sub ProcessPNG_iTXt($$$);
|
|
@@ -86,6 +87,14 @@ my %pngMap = (
|
|
|
86
87
|
# color type of current image
|
|
87
88
|
$Image::ExifTool::PNG::colorType = -1;
|
|
88
89
|
|
|
90
|
+
# data and text chunk types
|
|
91
|
+
my %isDatChunk = ( IDAT => 1, JDAT => 1, JDAA => 1 );
|
|
92
|
+
my %isTxtChunk = ( tEXt => 1, zTXt => 1, iTXt => 1 );
|
|
93
|
+
|
|
94
|
+
# chunks that we shouldn't move other chunks across (ref 3)
|
|
95
|
+
my %noLeapFrog = ( SAVE => 1, SEEK => 1, IHDR => 1, JHDR => 1, IEND => 1, MEND => 1,
|
|
96
|
+
DHDR => 1, BASI => 1, CLON => 1, PAST => 1, SHOW => 1, MAGN => 1 );
|
|
97
|
+
|
|
89
98
|
# PNG chunks
|
|
90
99
|
%Image::ExifTool::PNG::Main = (
|
|
91
100
|
WRITE_PROC => \&Image::ExifTool::DummyWriteProc,
|
|
@@ -101,6 +110,14 @@ $Image::ExifTool::PNG::colorType = -1;
|
|
|
101
110
|
it is specifically deleted with C<-Trailer:All=>. When reading, a minor
|
|
102
111
|
warning is issued if this trailer exists, and ExifTool will attempt to parse
|
|
103
112
|
this data as additional PNG chunks.
|
|
113
|
+
|
|
114
|
+
Also according to the PNG specification, there is no restriction on the
|
|
115
|
+
location of text-type chunks (tEXt, zTXt and iTXt). However, certain
|
|
116
|
+
utilities (including some Apple and Adobe utilities) won't read the XMP iTXt
|
|
117
|
+
chunk (and at least one utility won't read other text chunks) that come
|
|
118
|
+
after the IDAT chunk. For this reason, ExifTool 11.63 and later write all
|
|
119
|
+
text chunks (including XMP) before IDAT, and will move existing text chunks
|
|
120
|
+
up from after IDAT.
|
|
104
121
|
},
|
|
105
122
|
bKGD => {
|
|
106
123
|
Name => 'BackgroundColor',
|
|
@@ -866,9 +883,7 @@ sub FoundPNG($$$$;$$$$)
|
|
|
866
883
|
{
|
|
867
884
|
# write new value for this tag if necessary
|
|
868
885
|
my $newVal;
|
|
869
|
-
if ($$et{DEL_GROUP}{PNG}
|
|
870
|
-
$$et{PNGDoneTag}{ucfirst $tag})
|
|
871
|
-
{
|
|
886
|
+
if ($$et{DEL_GROUP}{PNG}){
|
|
872
887
|
# remove this tag now, but keep in ADD_PNG list to add back later
|
|
873
888
|
$isOverwriting = 1;
|
|
874
889
|
} else {
|
|
@@ -1230,7 +1245,8 @@ sub ProcessPNG($$)
|
|
|
1230
1245
|
my $datChunk = '';
|
|
1231
1246
|
my $datCount = 0;
|
|
1232
1247
|
my $datBytes = 0;
|
|
1233
|
-
my ($
|
|
1248
|
+
my ($n, $sig, $err, $hbuf, $dbuf, $cbuf);
|
|
1249
|
+
my ($wasHdr, $wasEnd, $wasDat, $doTxt, @txtOffset);
|
|
1234
1250
|
|
|
1235
1251
|
# check to be sure this is a valid PNG/MNG/JNG image
|
|
1236
1252
|
return 0 unless $raf->Read($sig,8) == 8 and $pngLookup{$sig};
|
|
@@ -1245,14 +1261,8 @@ sub ProcessPNG($$)
|
|
|
1245
1261
|
$$et{ADD_PNG} = $et->GetNewTagInfoHash(
|
|
1246
1262
|
\%Image::ExifTool::PNG::Main,
|
|
1247
1263
|
\%Image::ExifTool::PNG::TextualData);
|
|
1248
|
-
# NOTE: PNGDoneTag is used to keep track of metadata added before the
|
|
1249
|
-
# PNG IEND chunk is encountered. Currently this is implemented only
|
|
1250
|
-
# for XMP, but may be implemented in the future for other types - PH
|
|
1251
|
-
$$et{PNGDoneTag} = { };
|
|
1252
1264
|
# initialize with same directories, with PNG tags taking priority
|
|
1253
1265
|
$et->InitWriteDirs(\%pngMap,'PNG');
|
|
1254
|
-
$editingXMP = $$et{EDIT_DIRS}{XMP};
|
|
1255
|
-
$deletingXMP = $$et{DEL_GROUP}{XMP};
|
|
1256
1266
|
}
|
|
1257
1267
|
my ($fileType, $hdrChunk, $endChunk) = @{$pngLookup{$sig}};
|
|
1258
1268
|
$et->SetFileType($fileType); # set the FileType tag
|
|
@@ -1265,36 +1275,35 @@ sub ProcessPNG($$)
|
|
|
1265
1275
|
my $verbose = $et->Options('Verbose');
|
|
1266
1276
|
my $validate = $et->Options('Validate');
|
|
1267
1277
|
my $out = $et->Options('TextOut');
|
|
1268
|
-
my ($hbuf, $dbuf, $cbuf, $wasHdr, $wasEnd);
|
|
1269
1278
|
|
|
1270
|
-
# scan ahead
|
|
1271
|
-
if ($outfile
|
|
1279
|
+
# scan ahead to find offsets of all text chunks after IDAT
|
|
1280
|
+
if ($outfile) {
|
|
1272
1281
|
while ($raf->Read($hbuf,8) == 8) {
|
|
1273
1282
|
my ($len, $chunk) = unpack('Na4',$hbuf);
|
|
1274
1283
|
last if $len > 0x7fffffff;
|
|
1275
|
-
if ($
|
|
1276
|
-
$
|
|
1277
|
-
|
|
1284
|
+
if ($wasDat) {
|
|
1285
|
+
last if $noLeapFrog{$chunk}; # (don't move text across these chunks)
|
|
1286
|
+
push @txtOffset, $raf->Tell() - 8 if $isTxtChunk{$chunk};
|
|
1287
|
+
} elsif ($isDatChunk{$chunk}) {
|
|
1288
|
+
$wasDat = $chunk;
|
|
1278
1289
|
}
|
|
1279
|
-
$raf->
|
|
1280
|
-
unless ($dbuf eq "XML:com.adobe.xmp\0") { # is this XMP?
|
|
1281
|
-
$raf->Seek($len - 18 + 4, 1) or last;
|
|
1282
|
-
next;
|
|
1283
|
-
};
|
|
1284
|
-
$raf->Read($dbuf, $len - 18) == $len - 18 or last;
|
|
1285
|
-
my ($compressed, $meth) = unpack('CC', $dbuf);
|
|
1286
|
-
$compressed and $et->Error('XMP is compressed'), last;
|
|
1287
|
-
my ($lang, $trans);
|
|
1288
|
-
($lang, $trans, $xmp) = split /\0/, substr($dbuf, 2), 3;
|
|
1289
|
-
last;
|
|
1290
|
+
$raf->Seek($len + 4, 1) or last; # skip chunk data
|
|
1290
1291
|
}
|
|
1291
1292
|
$raf->Seek(8,0) or $et->Error('Error seeking in file'), return -1;
|
|
1293
|
+
undef $wasDat;
|
|
1292
1294
|
}
|
|
1293
1295
|
|
|
1294
1296
|
# process the PNG/MNG/JNG chunks
|
|
1295
1297
|
undef $noCompressLib;
|
|
1296
1298
|
for (;;) {
|
|
1297
|
-
|
|
1299
|
+
if ($doTxt) {
|
|
1300
|
+
# read text chunks that were found after IDAT so we can write them before
|
|
1301
|
+
$raf->Seek(shift(@txtOffset), 0) or $et->Error('Seek error'), last;
|
|
1302
|
+
# (this is the IDAT offset if @txtOffset is now empty)
|
|
1303
|
+
undef $doTxt unless @txtOffset;
|
|
1304
|
+
}
|
|
1305
|
+
$n = $raf->Read($hbuf,8); # read chunk header
|
|
1306
|
+
|
|
1298
1307
|
if ($wasEnd) {
|
|
1299
1308
|
last unless $n; # stop now if normal end of PNG
|
|
1300
1309
|
$et->WarnOnce("Trailer data after $fileType $endChunk chunk", 1);
|
|
@@ -1310,6 +1319,7 @@ sub ProcessPNG($$)
|
|
|
1310
1319
|
last;
|
|
1311
1320
|
}
|
|
1312
1321
|
if ($verbose) {
|
|
1322
|
+
print $out " Moving $chunk from after IDAT ($len bytes)\n" if $doTxt;
|
|
1313
1323
|
# don't dump image data chunks in verbose mode (only give count instead)
|
|
1314
1324
|
if ($datCount and $chunk ne $datChunk) {
|
|
1315
1325
|
my $s = $datCount > 1 ? 's' : '';
|
|
@@ -1327,41 +1337,32 @@ sub ProcessPNG($$)
|
|
|
1327
1337
|
last;
|
|
1328
1338
|
}
|
|
1329
1339
|
}
|
|
1330
|
-
if ($chunk
|
|
1340
|
+
if ($outfile and ($isDatChunk{$chunk} or $chunk eq $endChunk) and @txtOffset) {
|
|
1341
|
+
# continue processing here after we move the text chunks from after IDAT
|
|
1342
|
+
push @txtOffset, $raf->Tell() - 8;
|
|
1343
|
+
$doTxt = 1; # process text chunks now
|
|
1344
|
+
next;
|
|
1345
|
+
}
|
|
1346
|
+
if ($isDatChunk{$chunk}) {
|
|
1331
1347
|
$datChunk = $chunk;
|
|
1332
1348
|
$datCount++;
|
|
1333
1349
|
$datBytes += $len;
|
|
1350
|
+
$wasDat = $chunk;
|
|
1334
1351
|
} else {
|
|
1335
1352
|
$datChunk = '';
|
|
1336
1353
|
}
|
|
1337
1354
|
if ($outfile) {
|
|
1338
|
-
# add XMP before any data chunk
|
|
1355
|
+
# add text chunks (including XMP) before any data chunk end chunk
|
|
1339
1356
|
if ($datChunk or $chunk eq $endChunk) {
|
|
1340
|
-
if
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
$crc = CalculateCRC($outBuff, $crc);
|
|
1350
|
-
Write($outfile, $hdr, $$outBuff, pack('N',$crc)) or $err = 1;
|
|
1351
|
-
}
|
|
1352
|
-
undef $xmp; # done with this XMP
|
|
1353
|
-
} elsif ($$et{ADD_DIRS}{XMP}) {
|
|
1354
|
-
# add new XMP if necessary
|
|
1355
|
-
AddChunks($et, $outfile, 'XMP') or $err = 1;
|
|
1356
|
-
}
|
|
1357
|
-
}
|
|
1358
|
-
if ($chunk eq $endChunk) {
|
|
1359
|
-
# add other new chunks immediately before the IEND/MEND chunk
|
|
1360
|
-
AddChunks($et, $outfile) or $err = 1;
|
|
1361
|
-
} elsif ($chunk eq 'PLTE' or $chunk eq 'IDAT') {
|
|
1362
|
-
# pHYs must come before IDAT
|
|
1363
|
-
AddChunks($et, $outfile, 'PNG-pHYs') or $err = 1 if $chunk eq 'IDAT';
|
|
1364
|
-
# iCCP chunk must come before PLTE and IDAT
|
|
1357
|
+
# write iCCP chunk now if requested because AddChunks will try
|
|
1358
|
+
# to add it as a text profile chunk if this isn't successful
|
|
1359
|
+
# (ie. if Compress::Zlib wasn't available)
|
|
1360
|
+
Add_iCCP($et, $outfile);
|
|
1361
|
+
AddChunks($et, $outfile) or $err = 1; # all all text chunks
|
|
1362
|
+
# add EXIF before end chunk if not found already
|
|
1363
|
+
AddChunks($et, $outfile, 'IFD0') if $chunk eq $endChunk;
|
|
1364
|
+
} elsif ($chunk eq 'PLTE') {
|
|
1365
|
+
# iCCP chunk must come before PLTE (and IDAT, handled above)
|
|
1365
1366
|
# (ignore errors -- will add later as text profile if this fails)
|
|
1366
1367
|
Add_iCCP($et, $outfile);
|
|
1367
1368
|
}
|
|
@@ -1397,12 +1398,21 @@ sub ProcessPNG($$)
|
|
|
1397
1398
|
next;
|
|
1398
1399
|
}
|
|
1399
1400
|
if ($datChunk) {
|
|
1400
|
-
$foundIDAT = 1 if $chunk eq 'IDAT'; # set flag indicating IDAT was found
|
|
1401
1401
|
# skip over data chunks if possible
|
|
1402
1402
|
unless ($verbose or $validate or $outfile) {
|
|
1403
1403
|
$raf->Seek($len + 4, 1) or $et->Warn('Seek error'), last;
|
|
1404
1404
|
next;
|
|
1405
1405
|
}
|
|
1406
|
+
} elsif ($wasDat and $isTxtChunk{$chunk}) {
|
|
1407
|
+
my $msg;
|
|
1408
|
+
if (not $outfile) {
|
|
1409
|
+
$msg = 'may be ignored by some readers';
|
|
1410
|
+
} elsif (defined $doTxt) { # $doTxt == 0 if we crossed a noLeapFrog chunk
|
|
1411
|
+
$msg = "can't be moved"; # (but could be deleted then added back again)
|
|
1412
|
+
} else {
|
|
1413
|
+
$msg = 'fixed';
|
|
1414
|
+
}
|
|
1415
|
+
$et->WarnOnce("Text chunk(s) found after $$et{FileType} $wasDat ($msg)", 1);
|
|
1406
1416
|
}
|
|
1407
1417
|
# read chunk data and CRC
|
|
1408
1418
|
unless ($raf->Read($dbuf,$len)==$len and $raf->Read($cbuf, 4)==4) {
|
|
@@ -1421,49 +1431,31 @@ sub ProcessPNG($$)
|
|
|
1421
1431
|
Write($outfile, $hbuf, $dbuf, $cbuf) or $err = 1 if $outfile;
|
|
1422
1432
|
next;
|
|
1423
1433
|
}
|
|
1434
|
+
# just skip over any text chunk found after IDAT
|
|
1435
|
+
if ($outfile and $wasDat) {
|
|
1436
|
+
if ($isTxtChunk{$chunk} and not defined $doTxt) {
|
|
1437
|
+
++$$et{CHANGED} if $$et{FORCE_WRITE}{PNG};
|
|
1438
|
+
print $out " Deleting $chunk that was moved ($len bytes)\n" if $verbose;
|
|
1439
|
+
next;
|
|
1440
|
+
}
|
|
1441
|
+
# done moving text if we hit one of these chunks
|
|
1442
|
+
$doTxt = 0 if $noLeapFrog{$chunk};
|
|
1443
|
+
}
|
|
1424
1444
|
if ($verbose) {
|
|
1425
1445
|
print $out "$fileType $chunk ($len bytes):\n";
|
|
1426
1446
|
$et->VerboseDump(\$dbuf, Addr => $raf->Tell() - $len - 4) if $verbose > 2;
|
|
1427
1447
|
}
|
|
1428
1448
|
}
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
if ($outfile and $editingXMP) {
|
|
1432
|
-
# handle this standard XMP iTXt chunk
|
|
1433
|
-
my $editNow;
|
|
1434
|
-
if ($deletingXMP) {
|
|
1435
|
-
# just fall through
|
|
1436
|
-
} elsif ($foundXMP > 1) {
|
|
1437
|
-
$et->Error('Multiple XMP chunks', 1) if $foundXMP == 2;
|
|
1438
|
-
} elsif ($foundIDAT) {
|
|
1439
|
-
$et->WarnOnce('XMP found after PNG IDAT. Fixed.');
|
|
1440
|
-
} elsif ($xmp) {
|
|
1441
|
-
# the XMP is already before IDAT, so edit it now
|
|
1442
|
-
$editNow = 1;
|
|
1443
|
-
undef $xmp; # (don't write again later)
|
|
1444
|
-
}
|
|
1445
|
-
unless ($editNow) {
|
|
1446
|
-
++$$et{CHANGED};
|
|
1447
|
-
print $out " Deleting XMP\n" if $verbose;
|
|
1448
|
-
next;
|
|
1449
|
-
}
|
|
1450
|
-
} else {
|
|
1451
|
-
$et->WarnOnce('XMP found after PNG IDAT') if $foundIDAT;
|
|
1452
|
-
$et->Warn('Multiple XMP chunks') if $foundXMP == 2;
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
# translate case of chunk name if necessary
|
|
1456
|
-
if (not $$tagTablePtr{$chunk}) {
|
|
1449
|
+
# translate case of chunk names that have changed since the first implementation
|
|
1450
|
+
if (not $$tagTablePtr{$chunk} and $stdCase{lc $chunk}) {
|
|
1457
1451
|
my $stdChunk = $stdCase{lc $chunk};
|
|
1458
|
-
if ($stdChunk) {
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
$et->Warn("$chunk chunk should be $stdChunk", 1);
|
|
1464
|
-
}
|
|
1465
|
-
$chunk = $stdCase{lc $chunk};
|
|
1452
|
+
if ($outfile and ($$et{EDIT_DIRS}{IFD0} or $stdChunk !~ /^[ez]xif$/i)) {
|
|
1453
|
+
$et->Warn("Changed $chunk chunk to $stdChunk", 1);
|
|
1454
|
+
++$$et{CHANGED};
|
|
1455
|
+
} else {
|
|
1456
|
+
$et->Warn("$chunk chunk should be $stdChunk", 1);
|
|
1466
1457
|
}
|
|
1458
|
+
$chunk = $stdCase{lc $chunk};
|
|
1467
1459
|
}
|
|
1468
1460
|
# only extract information from chunks in our tables
|
|
1469
1461
|
my ($theBuff, $outBuff);
|
|
@@ -44,7 +44,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
|
44
44
|
use Image::ExifTool::Exif;
|
|
45
45
|
use Image::ExifTool::GPS;
|
|
46
46
|
|
|
47
|
-
$VERSION = '2.
|
|
47
|
+
$VERSION = '2.36';
|
|
48
48
|
|
|
49
49
|
sub ProcessMOV($$;$);
|
|
50
50
|
sub ProcessKeys($$$);
|
|
@@ -8207,7 +8207,7 @@ sub ProcessMOV($$;$)
|
|
|
8207
8207
|
my $dirID = $$dirInfo{DirID} || '';
|
|
8208
8208
|
my $charsetQuickTime = $et->Options('CharsetQuickTime');
|
|
8209
8209
|
my ($buff, $tag, $size, $track, $isUserData, %triplet, $doDefaultLang, $index);
|
|
8210
|
-
my ($dirEnd, $ee, $unkOpt, %saveOptions);
|
|
8210
|
+
my ($dirEnd, $ee, $unkOpt, %saveOptions, $atomCount);
|
|
8211
8211
|
|
|
8212
8212
|
my $topLevel = not $$et{InQuickTime};
|
|
8213
8213
|
$$et{InQuickTime} = 1;
|
|
@@ -8276,9 +8276,13 @@ sub ProcessMOV($$;$)
|
|
|
8276
8276
|
$unkOpt = $$et{OPTIONS}{Unknown};
|
|
8277
8277
|
require 'Image/ExifTool/QuickTimeStream.pl';
|
|
8278
8278
|
}
|
|
8279
|
-
|
|
8279
|
+
if ($$tagTablePtr{VARS}) {
|
|
8280
|
+
$index = $$tagTablePtr{VARS}{START_INDEX};
|
|
8281
|
+
$atomCount = $$tagTablePtr{VARS}{ATOM_COUNT};
|
|
8282
|
+
}
|
|
8280
8283
|
for (;;) {
|
|
8281
8284
|
my ($eeTag, $ignore);
|
|
8285
|
+
last if defined $atomCount and --$atomCount < 0;
|
|
8282
8286
|
if ($size < 8) {
|
|
8283
8287
|
if ($size == 0) {
|
|
8284
8288
|
if ($dataPt) {
|
|
@@ -8711,10 +8715,8 @@ ItemID: foreach $id (keys %$items) {
|
|
|
8711
8715
|
Extra => sprintf(' at offset 0x%.4x', $raf->Tell()),
|
|
8712
8716
|
) if $verbose;
|
|
8713
8717
|
if ($size and (not $raf->Seek($size-1, 1) or $raf->Read($buff, 1) != 1)) {
|
|
8714
|
-
|
|
8715
|
-
|
|
8716
|
-
$et->Warn("Truncated '${t}' data");
|
|
8717
|
-
}
|
|
8718
|
+
my $t = PrintableTagID($tag);
|
|
8719
|
+
$et->Warn("Truncated '${t}' data");
|
|
8718
8720
|
last;
|
|
8719
8721
|
}
|
|
8720
8722
|
}
|
|
@@ -241,6 +241,10 @@ key:
|
|
|
241
241
|
START_INDEX [QuickTime tables only] Initial index for indices shown in
|
|
242
242
|
Verbose output. Indices are not show otherwise.
|
|
243
243
|
|
|
244
|
+
ATOM_COUNT [QuickTime tables only] Maximum number of atoms contained in
|
|
245
|
+
within this atom. Currently used only for Canon CNTH atom,
|
|
246
|
+
which contains garbage after the first contained atom.
|
|
247
|
+
|
|
244
248
|
DATAMEMBER : BinaryData tables only. A reference to a list of sorted tag ID's
|
|
245
249
|
which must be extracted as data members when writing. Must also list "var_"
|
|
246
250
|
format tags and tags with Hook so offsets are properly calculated if the table
|
|
@@ -19,7 +19,7 @@ use strict;
|
|
|
19
19
|
use vars qw($VERSION %sigmaLensTypes);
|
|
20
20
|
use Image::ExifTool::Exif;
|
|
21
21
|
|
|
22
|
-
$VERSION = '1.
|
|
22
|
+
$VERSION = '1.28';
|
|
23
23
|
|
|
24
24
|
# sigma LensType lookup (ref IB)
|
|
25
25
|
%sigmaLensTypes = (
|
|
@@ -132,6 +132,7 @@ $VERSION = '1.27';
|
|
|
132
132
|
0x521 => 'Sigma 18-50mm F3.5-5.6 DC Macro',
|
|
133
133
|
0x527 => 'Sigma 100-300mm F4 EX IF HSM',
|
|
134
134
|
0x529 => 'Sigma 120-300mm F2.8 EX HSM IF APO',
|
|
135
|
+
0x545 => 'Sigma 28-70mm F2.8 EX ASP DF', #IB
|
|
135
136
|
0x547 => 'Sigma 24-60mm F2.8 EX DG',
|
|
136
137
|
0x548 => 'Sigma 24-70mm F2.8 EX DG Macro',
|
|
137
138
|
0x549 => 'Sigma 28-70mm F2.8 EX DG',
|
|
@@ -154,6 +155,7 @@ $VERSION = '1.27';
|
|
|
154
155
|
0x597 => 'Sigma 200-500mm F2.8 APO EX DG',
|
|
155
156
|
0x5A8 => 'Sigma 70-300mm F4-5.6 APO DG Macro (Motorized)',
|
|
156
157
|
0x5A9 => 'Sigma 70-300mm F4-5.6 DG Macro (Motorized)',
|
|
158
|
+
0x605 => 'Sigma 24-70mm F3.5-5.6 ASP HF', #IB
|
|
157
159
|
0x633 => 'Sigma 28-70mm F2.8-4 HS',
|
|
158
160
|
0x634 => 'Sigma 28-70mm F2.8-4 DG',
|
|
159
161
|
0x635 => 'Sigma 24-105mm F4 DG OS HSM | A',
|
|
@@ -190,8 +192,10 @@ $VERSION = '1.27';
|
|
|
190
192
|
0x745 => 'Sigma 150-600mm F5-6.3 DG OS HSM | C',
|
|
191
193
|
0x777 => 'Sigma 18-200mm F3.5-6.3 DC',
|
|
192
194
|
0x77D => 'Sigma 18-200mm F3.5-6.3 DC (Motorized)',
|
|
195
|
+
0x785 => 'Sigma 28-200mm F3.5-5.6 DL ASP IF HZM Macro', #IB
|
|
193
196
|
0x787 => 'Sigma 28-200mm F3.5-5.6 Compact ASP HZ Macro',
|
|
194
197
|
0x789 => 'Sigma 18-125mm F3.5-5.6 DC',
|
|
198
|
+
0x790 => 'Sigma 28-300mm F3.5-6.3 DL ASP IF HZM', #IB
|
|
195
199
|
0x793 => 'Sigma 28-300mm F3.5-6.3 Macro',
|
|
196
200
|
0x794 => 'Sigma 28-200mm F3.5-5.6 DG Compact ASP HZ Macro',
|
|
197
201
|
0x795 => 'Sigma 28-300mm F3.5-6.3 DG Macro',
|
|
@@ -7447,8 +7447,8 @@ information.
|
|
|
7447
7447
|
|
|
7448
7448
|
=head3 Canon CNTH Tags
|
|
7449
7449
|
|
|
7450
|
-
Canon-specific QuickTime tags found in the CNTH atom of MOV videos from
|
|
7451
|
-
cameras
|
|
7450
|
+
Canon-specific QuickTime tags found in the CNTH atom of MOV/MP4 videos from
|
|
7451
|
+
some cameras.
|
|
7452
7452
|
|
|
7453
7453
|
Tag ID Tag Name Writable
|
|
7454
7454
|
------ -------- --------
|
|
@@ -22532,6 +22532,14 @@ it is specifically deleted with C<-Trailer:All=>. When reading, a minor
|
|
|
22532
22532
|
warning is issued if this trailer exists, and ExifTool will attempt to parse
|
|
22533
22533
|
this data as additional PNG chunks.
|
|
22534
22534
|
|
|
22535
|
+
Also according to the PNG specification, there is no restriction on the
|
|
22536
|
+
location of text-type chunks (tEXt, zTXt and iTXt). However, certain
|
|
22537
|
+
utilities (including some Apple and Adobe utilities) won't read the XMP iTXt
|
|
22538
|
+
chunk (and at least one utility won't read other text chunks) that come
|
|
22539
|
+
after the IDAT chunk. For this reason, ExifTool 11.63 and later write all
|
|
22540
|
+
text chunks (including XMP) before IDAT, and will move existing text chunks
|
|
22541
|
+
up from after IDAT.
|
|
22542
|
+
|
|
22535
22543
|
Tag ID Tag Name Writable
|
|
22536
22544
|
------ -------- --------
|
|
22537
22545
|
'IHDR' ImageHeader PNG ImageHeader
|
|
@@ -285,7 +285,7 @@ my %validateInfo = (
|
|
|
285
285
|
enables the API L<Validate|../ExifTool.html#Validate> option, imposing
|
|
286
286
|
additional validation checks when extracting metadata. Returns the number
|
|
287
287
|
of errors, warnings and minor warnings encountered. Note that the Validate
|
|
288
|
-
feature focuses mainly on validation of TIFF
|
|
288
|
+
feature focuses mainly on validation of EXIF/TIFF metadata
|
|
289
289
|
},
|
|
290
290
|
PrintConv => {
|
|
291
291
|
'0 0 0' => 'OK',
|
|
@@ -617,9 +617,9 @@ files and metadata.
|
|
|
617
617
|
=head1 NOTES
|
|
618
618
|
|
|
619
619
|
The CRW format is a pleasure to work with. All pointer offsets are relative
|
|
620
|
-
to the start of the data for each directory. If TIFF
|
|
621
|
-
pointers in this way, it would be MUCH easier to read and write TIFF
|
|
622
|
-
files, and would lead to far fewer problems with corrupted metadata.
|
|
620
|
+
to the start of the data for each directory. If EXIF/TIFF had implemented
|
|
621
|
+
pointers in this way, it would be MUCH easier to read and write TIFF and
|
|
622
|
+
JPEG files, and would lead to far fewer problems with corrupted metadata.
|
|
623
623
|
|
|
624
624
|
=head1 AUTHOR
|
|
625
625
|
|
|
@@ -80,9 +80,9 @@ sub WriteProfile($$$;$)
|
|
|
80
80
|
} else {
|
|
81
81
|
$chunk = $rawType;
|
|
82
82
|
if ($rawType eq $stdCase{zxif}) {
|
|
83
|
-
$prefix = "\0" . pack('N', length $$dataPt);
|
|
83
|
+
$prefix = "\0" . pack('N', length $$dataPt); # (proposed compressed EXIF)
|
|
84
84
|
} else {
|
|
85
|
-
$prefix = '';
|
|
85
|
+
$prefix = ''; # standard EXIF
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
if ($deflate) {
|
|
@@ -116,7 +116,7 @@ sub WriteProfile($$$;$)
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
#------------------------------------------------------------------------------
|
|
119
|
-
# Add iCCP to the PNG image if necessary (must come before PLTE and IDAT)
|
|
119
|
+
# Add iCCP chunk to the PNG image if necessary (must come before PLTE and IDAT)
|
|
120
120
|
# Inputs: 0) ExifTool object ref, 1) output file or scalar ref
|
|
121
121
|
# Returns: true on success
|
|
122
122
|
sub Add_iCCP($$)
|
|
@@ -223,15 +223,16 @@ sub BuildTextChunk($$$$$)
|
|
|
223
223
|
#------------------------------------------------------------------------------
|
|
224
224
|
# Add any outstanding new chunks to the PNG image
|
|
225
225
|
# Inputs: 0) ExifTool object ref, 1) output file or scalar ref
|
|
226
|
-
# 2-N) dirs to add (empty to add all, including PNG tags)
|
|
226
|
+
# 2-N) dirs to add (empty to add all except EXIF 'IFD0', including PNG tags)
|
|
227
227
|
# Returns: true on success
|
|
228
228
|
sub AddChunks($$;@)
|
|
229
229
|
{
|
|
230
230
|
my ($et, $outfile, @add) = @_;
|
|
231
|
-
my ($addTags, $tag, $dir, $err, $tagTablePtr);
|
|
231
|
+
my ($addTags, $tag, $dir, $err, $tagTablePtr, $specified);
|
|
232
232
|
|
|
233
233
|
if (@add) {
|
|
234
234
|
$addTags = { }; # don't add any PNG tags
|
|
235
|
+
$specified = 1;
|
|
235
236
|
} else {
|
|
236
237
|
$addTags = $$et{ADD_PNG}; # add all PNG tags...
|
|
237
238
|
delete $$et{ADD_PNG}; # ...once
|
|
@@ -259,7 +260,6 @@ sub AddChunks($$;@)
|
|
|
259
260
|
my $cbuf = pack('N', CalculateCRC(\$data, undef));
|
|
260
261
|
Write($outfile, $hdr, $data, $cbuf) or $err = 1;
|
|
261
262
|
$et->VerboseValue("+ PNG:$$tagInfo{Name}", $val);
|
|
262
|
-
$$et{PNGDoneTag}{$tag} = 1; # set flag indicating this tag was added
|
|
263
263
|
++$$et{CHANGED};
|
|
264
264
|
}
|
|
265
265
|
}
|
|
@@ -272,6 +272,7 @@ sub AddChunks($$;@)
|
|
|
272
272
|
DirName => $dir,
|
|
273
273
|
);
|
|
274
274
|
if ($dir eq 'IFD0') {
|
|
275
|
+
next unless $specified; # wait until specifically asked to write EXIF 'IFD0'
|
|
275
276
|
my $chunk = $stdCase{exif};
|
|
276
277
|
# (zxIf was not adopted)
|
|
277
278
|
#if ($et->Options('Compress')) {
|
|
@@ -307,7 +308,7 @@ sub AddChunks($$;@)
|
|
|
307
308
|
Write($outfile, $hdr, $buff, $cbuf) or $err = 1;
|
|
308
309
|
}
|
|
309
310
|
} elsif ($dir eq 'IPTC') {
|
|
310
|
-
$et->Warn('Creating non-standard
|
|
311
|
+
$et->Warn('Creating non-standard IPTC in PNG', 1);
|
|
311
312
|
$et->VPrint(0, "Creating IPTC profile:\n");
|
|
312
313
|
# write new IPTC data (stored in a Photoshop directory)
|
|
313
314
|
$dirInfo{DirName} = 'Photoshop';
|
|
@@ -326,7 +327,7 @@ sub AddChunks($$;@)
|
|
|
326
327
|
$et->Warn('Wrote ICC as a raw profile (no Compress::Zlib)');
|
|
327
328
|
}
|
|
328
329
|
} elsif ($dir eq 'PNG-pHYs') {
|
|
329
|
-
$et->VPrint(0, "Creating pHYs chunk:\n");
|
|
330
|
+
$et->VPrint(0, "Creating pHYs chunk (default 2834 pixels per meter):\n");
|
|
330
331
|
$tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::PNG::PhysicalPixel');
|
|
331
332
|
my $blank = "\0\0\x0b\x12\0\0\x0b\x12\x01"; # 2834 pixels per meter (72 dpi)
|
|
332
333
|
$dirInfo{DataPt} = \$blank;
|
|
@@ -697,7 +697,7 @@ sub WriteQuickTime($$$)
|
|
|
697
697
|
my ($et, $dirInfo, $tagTablePtr) = @_;
|
|
698
698
|
$et or return 1; # allow dummy access to autoload this package
|
|
699
699
|
my ($mdat, @mdat, @mdatEdit, $edit, $track, $outBuff, $co, $term, $delCount);
|
|
700
|
-
my (%langTags, $canCreate, $delGrp, %boxPos, %didDir, $writeLast, $err);
|
|
700
|
+
my (%langTags, $canCreate, $delGrp, %boxPos, %didDir, $writeLast, $err, $atomCount);
|
|
701
701
|
my $outfile = $$dirInfo{OutFile} || return 0;
|
|
702
702
|
my $raf = $$dirInfo{RAF}; # (will be null for lower-level atoms)
|
|
703
703
|
my $dataPt = $$dirInfo{DataPt}; # (will be null for top-level atoms)
|
|
@@ -768,7 +768,14 @@ sub WriteQuickTime($$$)
|
|
|
768
768
|
$canCreate = 1;
|
|
769
769
|
$delGrp = $$et{DEL_GROUP}{$dirName};
|
|
770
770
|
}
|
|
771
|
+
$atomCount = $$tagTablePtr{VARS}{ATOM_COUNT} if $$tagTablePtr{VARS};
|
|
772
|
+
|
|
771
773
|
for (;;) { # loop through all atoms at this level
|
|
774
|
+
if (defined $atomCount and --$atomCount < 0 and $dataPt) {
|
|
775
|
+
# stop processing now and just copy the rest of the atom
|
|
776
|
+
Write($outfile, substr($$dataPt, $raf->Tell())) or $rtnVal=$rtnErr, $err=1;
|
|
777
|
+
last;
|
|
778
|
+
}
|
|
772
779
|
my ($hdr, $buff, $keysIndex);
|
|
773
780
|
my $n = $raf->Read($hdr, 8);
|
|
774
781
|
unless ($n == 8) {
|
|
@@ -801,6 +808,7 @@ sub WriteQuickTime($$$)
|
|
|
801
808
|
$size < 0 and $et->Error('Invalid extended atom size'), last;
|
|
802
809
|
} elsif ($size == -8) {
|
|
803
810
|
if ($dataPt) {
|
|
811
|
+
last if $$dirInfo{DirName} eq 'CanonCNTH'; # (this is normal for Canon CNTH atom)
|
|
804
812
|
my $pos = $raf->Tell() - 4;
|
|
805
813
|
$raf->Seek(0,2);
|
|
806
814
|
my $str = $$dirInfo{DirName} . ' with ' . ($raf->Tell() - $pos) . ' bytes';
|
|
@@ -813,15 +821,8 @@ sub WriteQuickTime($$$)
|
|
|
813
821
|
}
|
|
814
822
|
last;
|
|
815
823
|
} elsif ($size < 0) {
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
$buff = substr($$dataPt, $raf->Tell());
|
|
819
|
-
Write($outfile, $hdr, $buff) or $rtnVal=$rtnErr, $err=1;
|
|
820
|
-
last;
|
|
821
|
-
} else {
|
|
822
|
-
$et->Error('Invalid atom size');
|
|
823
|
-
last;
|
|
824
|
-
}
|
|
824
|
+
$et->Error('Invalid atom size');
|
|
825
|
+
last;
|
|
825
826
|
}
|
|
826
827
|
|
|
827
828
|
# keep track of 'mdat' atom locations for writing later
|
|
@@ -1242,11 +1243,11 @@ sub WriteQuickTime($$$)
|
|
|
1242
1243
|
} elsif ($tag eq 'stsd' and length($buff) >= 8) {
|
|
1243
1244
|
my $n = Get32u(\$buff, 4); # get number of sample descriptions in table
|
|
1244
1245
|
my ($pos, $flg) = (8, 0);
|
|
1245
|
-
my $i;
|
|
1246
|
+
my ($i, $msg);
|
|
1246
1247
|
for ($i=0; $i<$n; ++$i) { # loop through sample descriptions
|
|
1247
|
-
|
|
1248
|
+
$pos + 16 <= length($buff) or $msg = 'Truncated sample table', last;
|
|
1248
1249
|
my $siz = Get32u(\$buff, $pos);
|
|
1249
|
-
|
|
1250
|
+
$pos + $siz <= length($buff) or $msg = 'Truncated sample table', last;
|
|
1250
1251
|
my $drefIdx = Get16u(\$buff, $pos + 14);
|
|
1251
1252
|
my $drefTbl = $$et{QtDataRef};
|
|
1252
1253
|
if (not $drefIdx) {
|
|
@@ -1256,12 +1257,16 @@ sub WriteQuickTime($$$)
|
|
|
1256
1257
|
# $flg = 0x01-in this file, 0x02-in some other file
|
|
1257
1258
|
$flg |= ($$dref[1] == 1 and $$dref[0] ne 'rsrc') ? 0x01 : 0x02;
|
|
1258
1259
|
} else {
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
return $rtnVal;
|
|
1260
|
+
$msg = "No data reference for sample description $i";
|
|
1261
|
+
last;
|
|
1262
1262
|
}
|
|
1263
1263
|
$pos += $siz;
|
|
1264
1264
|
}
|
|
1265
|
+
if ($msg) {
|
|
1266
|
+
my $grp = $$et{CUR_WRITE_GROUP} || $parent;
|
|
1267
|
+
$et->Error("$msg for $grp");
|
|
1268
|
+
return $rtnErr;
|
|
1269
|
+
}
|
|
1265
1270
|
$$et{QtDataFlg} = $flg;
|
|
1266
1271
|
}
|
|
1267
1272
|
if ($tagInfo and $$tagInfo{WriteLast}) {
|
|
@@ -3883,11 +3883,11 @@ sub InitWriteDirs($$;$$)
|
|
|
3883
3883
|
$dirName = 'MIE' . ($1 || '');
|
|
3884
3884
|
}
|
|
3885
3885
|
my @dirNames;
|
|
3886
|
-
# allow a group name of '*' to force writing EXIF/IPTC/XMP (ForceWrite tag)
|
|
3886
|
+
# allow a group name of '*' to force writing EXIF/IPTC/XMP/PNG (ForceWrite tag)
|
|
3887
3887
|
if ($dirName eq '*' and $$nvHash{Value}) {
|
|
3888
3888
|
my $val = $$nvHash{Value}[0];
|
|
3889
3889
|
if ($val) {
|
|
3890
|
-
foreach (qw(EXIF IPTC XMP FixBase)) {
|
|
3890
|
+
foreach (qw(EXIF IPTC XMP PNG FixBase)) {
|
|
3891
3891
|
next unless $val =~ /\b($_|All)\b/i;
|
|
3892
3892
|
push @dirNames, $_;
|
|
3893
3893
|
push @dirNames, 'EXIF' if $_ eq 'FixBase';
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: exiftool_vendored
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 11.
|
|
4
|
+
version: 11.63.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matthew McEachen
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2019-08-
|
|
12
|
+
date: 2019-08-20 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: exiftool
|