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 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