exiftool_vendored 11.62.0 → 11.63.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of exiftool_vendored might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fc94cfa90b14193e0341f4f89a55df3d76ce0d6e
4
- data.tar.gz: 30ee5059a3860f00728a1b494a1e2c2214dbb53c
3
+ metadata.gz: ea6e0dbd2fcc5d00e9ea0e5fdfa01cf96f64aaf6
4
+ data.tar.gz: 6448e540c1fa5c44c3ff28d6771c14ac3da1b02c
5
5
  SHA512:
6
- metadata.gz: 7038421428a12c1241859e9b4618fb793b27402551223e6a75fa579fe8431176be2a50c55cfabcdffb1a2762f25bd3048966d708b93f8b58992b7778c2b90d56
7
- data.tar.gz: b1a513de8056df7f840c39711a016558da24058a6d3cd5bc7c38839e02e717c10b6c28935d6d868d416f7071ae33f6d6f806ef2adb8794c2e162bceecd4b9298
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
@@ -47,6 +47,6 @@
47
47
  }
48
48
  },
49
49
  "release_status" : "stable",
50
- "version" : "11.62",
50
+ "version" : "11.63",
51
51
  "x_serialization_backend" : "JSON::PP version 4.02"
52
52
  }
data/bin/META.yml CHANGED
@@ -28,5 +28,5 @@ recommends:
28
28
  Time::HiRes: '0'
29
29
  requires:
30
30
  perl: '5.004'
31
- version: '11.62'
31
+ version: '11.63'
32
32
  x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
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.62.tar.gz | tar -xf -
108
- cd Image-ExifTool-11.62
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.62';
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.62 --
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
@@ -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.62';
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 and/or XMP in a file to be
1678
- rewritten. May be set to "EXIF", "IPTC" or "XMP" to force the corresponding
1679
- metadata type to be rewritten, "FixBase" to cause EXIF to be rewritten only if
1680
- the MakerNotes offset base was fixed, or "All" to rewrite all of these metadata
1681
- types. Values are case insensitive, and multiple values may be separated with
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.21';
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 => { IGNORE_BAD_ATOMS => 1 },
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 some
8664
- cameras such as the PowerShot S95.
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.21';
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( \(|$)/ and @best = ( $lens ), last;
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.81';
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
- '128.10' => 'Sigma 50mm F1.4 EX DG HSM', #Florian Knorn (Model A014, ref IB)
341
- '128.11' => 'Sigma 85mm F1.4 EX DG HSM', #27
342
- '128.12' => 'Sigma 24-70mm F2.8 IF EX DG HSM', #27
343
- '128.13' => 'Sigma 18-250mm F3.5-6.3 DC OS HSM', #27
344
- '128.14' => 'Sigma 17-50mm F2.8 EX DC HSM', #Exiv2
345
- '128.15' => 'Sigma 17-70mm F2.8-4 DC Macro HSM', #JR (OS Model C013, ref IB)
346
- '128.16' => 'Sigma 150mm F2.8 EX DG OS HSM APO Macro', #Marcus Holland-Moritz
347
- '128.17' => 'Sigma 150-500mm F5-6.3 APO DG OS HSM', #IB
348
- '128.18' => 'Tamron AF 28-105mm F4-5.6 [IF]', #IB (Model 179D)
349
- '128.19' => 'Sigma 35mm F1.4 DG HSM', #JR
350
- '128.20' => 'Sigma 18-35mm F1.8 DC HSM', #JR (Model A013, ref IB)
351
- '128.21' => 'Sigma 50-500mm F4.5-6.3 APO DG OS HSM', #JR
352
- '128.22' => 'Sigma 24-105mm F4 DG HSM | A', #JR (013)
353
- '128.23' => 'Sigma 30mm F1.4', #IB
354
- '128.24' => 'Sigma 35mm F1.4 DG HSM | A', #IB/JR (012)
355
- '128.25' => 'Sigma 105mm F2.8 EX DG OS HSM Macro', #IB
356
- '128.26' => 'Sigma 180mm F2.8 EX DG OS HSM APO Macro', #IB
357
- '128.27' => 'Sigma 18-300mm F3.5-6.3 DC Macro HSM | C', #IB/JR (014)
358
- '128.28' => 'Sigma 18-50mm F2.8-4.5 DC HSM', #IB
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/Sony AF 100-300mm F4.5-5.6 APO', #11 (does not exist? https://www.dyxum.com/dforum/lens-data-requested_topic23435_page2.html)
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.51';
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} or $$et{PNGDoneTag}{$tag} or
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 ($sig, $err, $xmp, $foundXMP, $foundIDAT, $editingXMP, $deletingXMP);
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 for XMP if we are editing it
1271
- if ($outfile and $editingXMP and not $deletingXMP) {
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 ($chunk ne 'iTXt' or $len < 22) {
1276
- $raf->Seek($len + 4, 1) or last;
1277
- next;
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->Read($dbuf, 18) == 18 or last;
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
- my $n = $raf->Read($hbuf,8);
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 =~ /^(IDAT|JDAT|JDAA)$/) {
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, or before IEND/MEND if no data
1355
+ # add text chunks (including XMP) before any data chunk end chunk
1339
1356
  if ($datChunk or $chunk eq $endChunk) {
1340
- if ($xmp) {
1341
- # rewrite existing XMP
1342
- my $tbl = GetTagTable('Image::ExifTool::PNG::TextualData');
1343
- my $buf;
1344
- FoundPNG($et, $tbl, 'XML:com.adobe.xmp', $xmp, 0, \$buf, 'UTF8', '');
1345
- my $outBuff = defined $buf ? \$buf : \$xmp;
1346
- if (length $$outBuff) {
1347
- my $hdr = pack('Na4', length($$outBuff), 'iTXt');
1348
- my $crc = CalculateCRC(\$hdr, undef, 4);
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
- if ($chunk eq 'iTXt' and $dbuf =~ /^XML:com.adobe.xmp\0/) {
1430
- $foundXMP = ($foundXMP || 0) + 1;
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
- if ($outfile and ($$et{EDIT_DIRS}{IFD0} or $stdChunk !~ /^[ez]xif$/i)) {
1460
- $et->Warn("Changed $chunk chunk to $stdChunk", 1);
1461
- ++$$et{CHANGED};
1462
- } else {
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.35';
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
- $index = $$tagTablePtr{VARS}{START_INDEX} if $$tagTablePtr{VARS};
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
- unless ($$tagTablePtr{VARS} and $$tagTablePtr{VARS}{IGNORE_BAD_ATOMS}) {
8715
- my $t = PrintableTagID($tag);
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.27';
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 some
7451
- cameras such as the PowerShot S95.
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/EXIF metadata
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/EXIF had implemented
621
- pointers in this way, it would be MUCH easier to read and write TIFF/JPEG
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 EXIF in PNG', 1);
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
- if ($$tagTablePtr{VARS}{IGNORE_BAD_ATOMS} and $dataPt) {
817
- # ignore bad atom and just copy the rest of this directory
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
- last if $pos + 16 > length($buff);
1248
+ $pos + 16 <= length($buff) or $msg = 'Truncated sample table', last;
1248
1249
  my $siz = Get32u(\$buff, $pos);
1249
- last if $pos + $siz > length($buff);
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
- my $grp = $$et{CUR_WRITE_GROUP} || $parent;
1260
- $et->Error("No data reference for $grp sample description $i");
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';
@@ -1,6 +1,6 @@
1
1
  Summary: perl module for image data extraction
2
2
  Name: perl-Image-ExifTool
3
- Version: 11.62
3
+ Version: 11.63
4
4
  Release: 1
5
5
  License: Artistic/GPL
6
6
  Group: Development/Libraries/Perl
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ExiftoolVendored
4
- VERSION = Gem::Version.new('11.62.0')
4
+ VERSION = Gem::Version.new('11.63.0')
5
5
  end
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.62.0
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-15 00:00:00.000000000 Z
12
+ date: 2019-08-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: exiftool