exiftool_vendored 11.53.0 → 11.54.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.

@@ -160,7 +160,7 @@ sub WritePSDirectory($$$$$)
160
160
  <x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool $Image::ExifTool::VERSION'>
161
161
  </x:xmpmeta>
162
162
  EMPTY_XMP
163
- $val .= ((' ' x 100) . "\n") x 24 unless $et->Options('Compact');
163
+ $val .= ((' ' x 100) . "\n") x 24 unless $$et{OPTIONS}{Compact}{NoPadding};
164
164
  $val .= q{<?xpacket end='w'?>};
165
165
  $dataPt = \$val;
166
166
  $len = length $val;
@@ -19,6 +19,9 @@ my %movMap = (
19
19
  XMP => 'UserData', # MOV-Movie-UserData-XMP
20
20
  UserData => 'Movie', # MOV-Movie-UserData
21
21
  Movie => 'MOV',
22
+ GSpherical => 'SphericalVideoXML', # MOV-Movie-Track-SphericalVideoXML
23
+ SphericalVideoXML => 'Track', # (video track specifically, don't create if it doesn't exist)
24
+ Track => 'Movie',
22
25
  );
23
26
  my %mp4Map = (
24
27
  # MP4 ('ftyp' compatible brand 'mp41', 'mp42' or 'f4v ') -> XMP at top level
@@ -29,6 +32,9 @@ my %mp4Map = (
29
32
  UserData => 'Movie', # MOV-Movie-UserData
30
33
  Movie => 'MOV',
31
34
  XMP => 'MOV', # MOV-XMP
35
+ GSpherical => 'SphericalVideoXML', # MOV-Movie-Track-SphericalVideoXML
36
+ SphericalVideoXML => 'Track', # (video track specifically, don't create if it doesn't exist)
37
+ Track => 'Movie',
32
38
  );
33
39
  my %heicMap = (
34
40
  # HEIC ('ftyp' compatible brand 'heic' or 'mif1') -> XMP/EXIF in top level 'meta'
@@ -847,7 +853,12 @@ sub WriteQuickTime($$$)
847
853
  $et->Error("Truncated $tag atom");
848
854
  return $rtnVal;
849
855
  }
850
-
856
+ # save the handler type for this track
857
+ if ($tag eq 'hdlr' and length $buff >= 12) {
858
+ my $hdlr = substr($buff,8,4);
859
+ $$et{HandlerType} = $hdlr if $hdlr =~ /^(vide|soun)$/;
860
+ }
861
+
851
862
  # if this atom stores offsets, save its location so we can fix up offsets later
852
863
  # (are there any other atoms that may store absolute file offsets?)
853
864
  if ($tag =~ /^(stco|co64|iloc|mfra|moof|sidx|saio|gps |CTBO|uuid)$/) {
@@ -937,6 +948,8 @@ sub WriteQuickTime($$$)
937
948
 
938
949
  if ($subdir) { # process atoms in this container from a buffer in memory
939
950
 
951
+ undef $$et{HandlerType} if $tag eq 'trak'; # init handler type for this track
952
+
940
953
  my $subName = $$subdir{DirName} || $$tagInfo{Name};
941
954
  my $start = $$subdir{Start} || 0;
942
955
  my $base = ($$dirInfo{Base} || 0) + $raf->Tell() - $size;
@@ -964,6 +977,7 @@ sub WriteQuickTime($$$)
964
977
  Multi => $$subdir{Multi}, # necessary?
965
978
  OutFile => $outfile,
966
979
  NoRefTest=> 1, # don't check directory references
980
+ WriteGroup => $$tagInfo{WriteGroup},
967
981
  # initialize array to hold details about chunk offset table
968
982
  # (each entry has 3-5 items: 0=atom type, 1=table offset, 2=table size,
969
983
  # 3=optional base offset, 4=optional item ID)
@@ -1301,6 +1315,9 @@ sub WriteQuickTime($$$)
1301
1315
  # (note that $tag may be a binary Keys index here)
1302
1316
  foreach $tag (@addTags) {
1303
1317
  my $tagInfo = $$dirs{$tag} || $$newTags{$tag};
1318
+ next if defined $$tagInfo{CanCreate} and not $$tagInfo{CanCreate};
1319
+ next if defined $$tagInfo{HandlerType} and
1320
+ (not $$et{HandlerType} or $$et{HandlerType} ne $$tagInfo{HandlerType});
1304
1321
  my $subdir = $$tagInfo{SubDirectory};
1305
1322
  unless ($subdir) {
1306
1323
  my $nvHash = $et->GetNewValueHash($tagInfo);
@@ -1386,6 +1403,7 @@ sub WriteQuickTime($$$)
1386
1403
  HasData => $$subdir{HasData},
1387
1404
  OutFile => $outfile,
1388
1405
  ChunkOffset => [ ], # (just to be safe)
1406
+ WriteGroup => $$tagInfo{WriteGroup},
1389
1407
  );
1390
1408
  my $subTable = GetTagTable($$subdir{TagTable});
1391
1409
  my $newData = $et->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc});
@@ -45,7 +45,7 @@ my $rdfClose = "</rdf:RDF>\n";
45
45
  my $xmpClose = "</x:xmpmeta>\n";
46
46
  my $pktCloseW = "<?xpacket end='w'?>"; # writable by default
47
47
  my $pktCloseR = "<?xpacket end='r'?>";
48
- my $noPad;
48
+ my ($sp, $nl);
49
49
 
50
50
  #------------------------------------------------------------------------------
51
51
  # Get XMP opening tag (and set x:xmptk appropriately)
@@ -543,6 +543,36 @@ sub AddStructType($$$$;$)
543
543
  }
544
544
  }
545
545
 
546
+ #------------------------------------------------------------------------------
547
+ # Hack to use XMP writer for SphericalVideoXML
548
+ # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
549
+ # Returns: SphericalVideoXML data
550
+ sub WriteGSpherical($$$)
551
+ {
552
+ my ($et, $dirInfo, $tagTablePtr) = @_;
553
+ $$dirInfo{Compact} = 1,
554
+ my $dataPt = $$dirInfo{DataPt};
555
+ if ($dataPt and $$dataPt) {
556
+ # make it look like XMP for writing
557
+ my $buff = $$dataPt;
558
+ $buff =~ s/<rdf:SphericalVideo/<?xpacket begin='.*?' id='W5M0MpCehiHzreSzNTczkc9d'?>\n<x:xmpmeta xmlns:x='adobe:ns:meta\/'><rdf:RDF/;
559
+ $buff =~ s/\s*xmlns:GSpherical/>\n<rdf:Description xmlns:GSpherical/s;
560
+ $buff =~ s/<\/rdf:SphericalVideo>/<\/rdf:Description>/;
561
+ $buff .= "</rdf:RDF></x:xmpmeta><?xpacket end='w'?>";
562
+ $$dirInfo{DataPt} = \$buff;
563
+ $$dirInfo{DirLen} = length($buff) - ($$dirInfo{DirStart} || 0);
564
+ }
565
+ my $xmp = Image::ExifTool::XMP::WriteXMP($et, $dirInfo, $tagTablePtr);
566
+ if ($xmp) {
567
+ # change back to rdf:SphericalVideo structure
568
+ $xmp =~ s/^<\?xpacket begin.*?<rdf:RDF/<rdf:SphericalVideo\n/s;
569
+ $xmp =~ s/>\s*<rdf:Description rdf:about=''\s*/\n /;
570
+ $xmp =~ s/\s*<\/rdf:Description>\s*(<\/rdf:RDF>)/\n<\/rdf:SphericalVideo>$1/s;
571
+ $xmp =~ s/\s*<\/rdf:RDF>\s*<\/x:xmpmeta>.*//s;
572
+ }
573
+ return $xmp;
574
+ }
575
+
546
576
  #------------------------------------------------------------------------------
547
577
  # Utility routine to encode data in base64
548
578
  # Inputs: 0) binary data string, 1) flag to avoid inserting newlines
@@ -604,10 +634,9 @@ sub LimitXMPSize($$$$$$)
604
634
  push @$startPt, length($$dataPt); # add end offset to list
605
635
  my $newData = substr($$dataPt, 0, $$startPt[0]);
606
636
  my $guid = '0' x 32;
607
- my ($sp, $nl) = $noPad ? ('', $noPad > 1 ? '' : "\n") : (' ',"\n");
608
637
  # write the required xmpNote:HasExtendedXMP property
609
638
  $newData .= "$nl$sp<$rdfDesc rdf:about='${about}'\n$sp${sp}xmlns:xmpNote='$nsURI{xmpNote}'";
610
- if ($$et{OPTIONS}{XMPShorthand} or $$et{OPTIONS}{Compact} > 4) {
639
+ if ($$et{OPTIONS}{Compact}{Shorthand}) {
611
640
  $newData .= "\n$sp${sp}xmpNote:HasExtendedXMP='${guid}'/>\n";
612
641
  } else {
613
642
  $newData .= ">$nl$sp$sp<xmpNote:HasExtendedXMP>$guid</xmpNote:HasExtendedXMP>$nl$sp</$rdfDesc>\n";
@@ -645,21 +674,14 @@ sub LimitXMPSize($$$$$$)
645
674
  # Close out bottom-level property
646
675
  # Inputs: 0) current property path list ref, 1) longhand properties at each resource
647
676
  # level, 2) shorthand properties at each resource level, 3) resource flag for
648
- # each property path level (set only if XMPShorthand is enabled)
677
+ # each property path level (set only if Shorthand is enabled)
649
678
  sub CloseProperty($$$$)
650
679
  {
651
680
  my ($curPropList, $long, $short, $resFlag) = @_;
652
681
 
653
682
  my $prop = pop @$curPropList;
654
683
  $prop =~ s/ .*//; # remove list index if it exists
655
- my ($pad, $nl);
656
- if ($noPad) {
657
- $pad = '';
658
- $nl = $noPad > 1 ? '' : "\n";
659
- } else {
660
- $pad = ' ' x (scalar(@$curPropList) + 1);
661
- $nl = "\n";
662
- }
684
+ my $pad = $sp x (scalar(@$curPropList) + 1);
663
685
  if ($$resFlag[@$curPropList]) {
664
686
  # close this XMP structure with possible shorthand properties
665
687
  if (length $$short[-1]) {
@@ -703,8 +725,8 @@ sub CloseProperty($$$$)
703
725
 
704
726
  #------------------------------------------------------------------------------
705
727
  # Write XMP information
706
- # Inputs: 0) ExifTool object reference, 1) source dirInfo reference,
707
- # 2) [optional] tag table reference
728
+ # Inputs: 0) ExifTool ref, 1) source dirInfo ref (with optional WriteGroup),
729
+ # 2) [optional] tag table ref
708
730
  # Returns: with tag table: new XMP data (may be empty if no XMP data) or undef on error
709
731
  # without tag table: 1 on success, 0 if not valid XMP file, -1 on write error
710
732
  # Notes: May set dirInfo InPlace flag to rewrite with specified DirLen (=2 to allow larger)
@@ -723,10 +745,9 @@ sub WriteXMP($$;$)
723
745
  # prefer XMP over other metadata formats in some types of files
724
746
  my $preferred = $xmpFile || ($$et{PreferredGroup} and $$et{PreferredGroup} eq 'XMP');
725
747
  my $verbose = $$et{OPTIONS}{Verbose};
726
- my $compact = $$et{OPTIONS}{Compact};
748
+ my %compact = ( %{$$et{OPTIONS}{Compact}} ); # (make a copy so we can change settings)
727
749
  my $dirLen = $$dirInfo{DirLen};
728
750
  $dirLen = length($$dataPt) if not defined $dirLen and $dataPt;
729
- $noPad = $compact > 1 ? ($compact > 3 ? 2 : 1) : undef;
730
751
  #
731
752
  # extract existing XMP information into %capture hash
732
753
  #
@@ -743,6 +764,9 @@ sub WriteXMP($$;$)
743
764
  delete $$et{XMP_IS_XML};
744
765
  delete $$et{XMP_IS_SVG};
745
766
 
767
+ # set current padding characters
768
+ ($sp, $nl) = ($compact{NoIndent} ? '' : ' ', $compact{NoNewline} ? '' : "\n");
769
+
746
770
  # get value for new rdf:about
747
771
  my $tagInfo = $Image::ExifTool::XMP::rdf{about};
748
772
  if (defined $$et{NEW_VALUE}{$tagInfo}) {
@@ -869,9 +893,11 @@ sub WriteXMP($$;$)
869
893
  # (sorted by tag name so alternate languages come last, but with structures
870
894
  # first so flattened tags may be used to override individual structure elements)
871
895
  my @tagInfoList;
896
+ my $writeGroup = $$dirInfo{WriteGroup};
872
897
  foreach $tagInfo (sort ByTagName $et->GetNewTagInfoList()) {
873
898
  next unless $et->GetGroup($tagInfo, 0) eq 'XMP';
874
899
  next if $$tagInfo{Name} eq 'XMP'; # (ignore full XMP block if we didn't write it already)
900
+ next if $writeGroup and $writeGroup ne $$et{NEW_VALUE}{$tagInfo}{WriteGroup};
875
901
  if ($$tagInfo{Struct}) {
876
902
  unshift @tagInfoList, $tagInfo;
877
903
  } else {
@@ -1236,7 +1262,6 @@ sub WriteXMP($$;$)
1236
1262
  # write out the new XMP information (serialize it)
1237
1263
  #
1238
1264
  # start writing the XMP data
1239
- my $useShorthand = $$et{OPTIONS}{XMPShorthand} || ($compact > 4 ? 1 : 0);
1240
1265
  my (@long, @short, @resFlag);
1241
1266
  $long[0] = $long[1] = $short[0] = '';
1242
1267
  if ($$et{XMP_NO_XPACKET}) {
@@ -1279,8 +1304,6 @@ sub WriteXMP($$;$)
1279
1304
  }
1280
1305
  }
1281
1306
 
1282
- my ($sp, $nl) = $noPad ? ('', $noPad > 1 ? '' : "\n") : (' ',"\n");
1283
-
1284
1307
  # write out all properties
1285
1308
  for (;;) {
1286
1309
  my (%nsNew, $newDesc);
@@ -1316,7 +1339,7 @@ sub WriteXMP($$;$)
1316
1339
  my ($path2, $ns2);
1317
1340
  foreach $path2 (@pathList) {
1318
1341
  my @ns2s = ($path2 =~ m{(?:^|/)([^/]+?):}g);
1319
- my $opening = ($compact > 2 or $useShorthand > 1) ? 1 : 0;
1342
+ my $opening = $compact{OneDesc} ? 1 : 0;
1320
1343
  foreach $ns2 (@ns2s) {
1321
1344
  next if $ns2 eq 'rdf';
1322
1345
  $nsNew{$ns2} and ++$opening, next;
@@ -1354,8 +1377,8 @@ sub WriteXMP($$;$)
1354
1377
  }
1355
1378
  $long[-2] .= "\n$sp${sp}xmlns:$_='$nsCur{$_}'" foreach @ns;
1356
1379
  push @curPropList, $prop;
1357
- # set resFlag to 0 to indicate base description when XMPShorthand enabled
1358
- $resFlag[0] = 0 if $useShorthand;
1380
+ # set resFlag to 0 to indicate base description when Shorthand enabled
1381
+ $resFlag[0] = 0 if $compact{Shorthand};
1359
1382
  }
1360
1383
  my ($val, $attrs) = @{$capture{$path}};
1361
1384
  $debug and print "$path = $val\n";
@@ -1367,7 +1390,7 @@ sub WriteXMP($$;$)
1367
1390
  $prop =~ s/ .*//; # remove list index if it exists
1368
1391
  # (we may add parseType and shorthand properties later,
1369
1392
  # so leave off the trailing ">" for now)
1370
- $long[-1] .= ($noPad ? '' : ' ' x scalar(@curPropList)) . "<$prop";
1393
+ $long[-1] .= ($compact{NoIndent} ? '' : ' ' x scalar(@curPropList)) . "<$prop";
1371
1394
  if ($prop ne $rdfDesc and ($propList[$n+1] !~ /^rdf:/ or
1372
1395
  ($propList[$n+1] eq 'rdf:type' and $n+1 == $#propList)))
1373
1396
  {
@@ -1378,7 +1401,7 @@ sub WriteXMP($$;$)
1378
1401
  $dummy = 1;
1379
1402
  last;
1380
1403
  }
1381
- if ($useShorthand) {
1404
+ if ($compact{Shorthand}) {
1382
1405
  $resFlag[$#curPropList] = 1;
1383
1406
  push @long, '';
1384
1407
  push @short, '';
@@ -1394,7 +1417,7 @@ sub WriteXMP($$;$)
1394
1417
  # add element unless it was a dummy structure field
1395
1418
  unless ($dummy or ($val eq '' and $prop2 =~ /:~dummy~$/)) {
1396
1419
  $prop2 =~ s/ .*//; # remove list index if it exists
1397
- my $pad = $noPad ? '' : ' ' x (scalar(@curPropList) + 1);
1420
+ my $pad = $compact{NoIndent} ? '' : ' ' x (scalar(@curPropList) + 1);
1398
1421
  # (can't write as shortcut if it has attributes or CDATA)
1399
1422
  if (defined $resFlag[$#curPropList] and not %$attrs and $val !~ /<!\[CDATA\[/) {
1400
1423
  $short[-1] .= "\n$pad$prop2='${val}'";
@@ -1423,9 +1446,9 @@ sub WriteXMP($$;$)
1423
1446
  $$dirInfo{ExtendedXMP} = $rtn[0];
1424
1447
  $$dirInfo{ExtendedGUID} = $rtn[1];
1425
1448
  # compact if necessary to fit
1426
- $compact = 1 if length($long[-2]) + 101 * $numPadLines > $maxDataLen and not $compact;
1449
+ $compact{NoPadding} = 1 if length($long[-2]) + 101 * $numPadLines > $maxDataLen;
1427
1450
  }
1428
- $compact = 1 if $$dirInfo{Compact} and not $compact;
1451
+ $compact{NoPadding} = 1 if $$dirInfo{Compact};
1429
1452
  #
1430
1453
  # close out the XMP, clean up, and return our data
1431
1454
  #
@@ -1447,7 +1470,7 @@ sub WriteXMP($$;$)
1447
1470
  # pad to specified DirLen
1448
1471
  if ($len > $dirLen) {
1449
1472
  my $str = 'Not enough room to edit XMP in place';
1450
- $str .= '. Try XMPShorthand option' unless $$et{OPTIONS}{XMPShorthand} or $compact > 4;
1473
+ $str .= '. Try Shorthand feature' unless $compact{Shorthand};
1451
1474
  $et->Warn($str);
1452
1475
  return undef;
1453
1476
  }
@@ -1457,7 +1480,7 @@ sub WriteXMP($$;$)
1457
1480
  $len += length($pad) * $num;
1458
1481
  }
1459
1482
  $len < $dirLen and $long[-2] .= (' ' x ($dirLen - $len - 1)) . "\n";
1460
- } elsif (not $compact and not $xmpFile and not $$dirInfo{ReadOnly}) {
1483
+ } elsif (not $compact{NoPadding} and not $xmpFile and not $$dirInfo{ReadOnly}) {
1461
1484
  $long[-2] .= $pad x $numPadLines;
1462
1485
  }
1463
1486
  $long[-2] .= ($$dirInfo{ReadOnly} ? $pktCloseR : $pktCloseW);
@@ -357,6 +357,9 @@ sub SetNewValue($;$$%)
357
357
  $options{Type} = 'ValueConv' if $tag =~ s/#$//;
358
358
  my $convType = $options{Type} || ($$self{OPTIONS}{PrintConv} ? 'PrintConv' : 'ValueConv');
359
359
 
360
+ # filter value if necessary
361
+ Filter($$self{OPTIONS}{FilterW}, \$value) if $convType eq 'PrintConv';
362
+
360
363
  my (@wantGroup, $family2);
361
364
  my $wantGroup = $options{Group};
362
365
  if ($wantGroup) {
@@ -734,6 +737,11 @@ TAG: foreach $tagInfo (@matchingTags) {
734
737
  } else {
735
738
  push @tagInfoList, $tagInfo;
736
739
  }
740
+ # special case to allow override of XMP WriteGroup
741
+ if ($writeGroup eq 'XMP') {
742
+ my $wg = $$tagInfo{WriteGroup} || $$table{WRITE_GROUP};
743
+ $writeGroup = $wg if $wg;
744
+ }
737
745
  $writeGroup{$tagInfo} = $writeGroup;
738
746
  }
739
747
  # sort tag info list in reverse order of priority (higest number last)
@@ -68,6 +68,7 @@ sub AddFlattenedTags($;$$);
68
68
  sub FormatXMPDate($);
69
69
  sub ConvertRational($);
70
70
  sub ConvertRationalList($);
71
+ sub WriteGSpherical($$$);
71
72
 
72
73
  # lookup for translating to ExifTool namespaces (and family 1 group names)
73
74
  %stdXlatNS = (
@@ -1608,11 +1608,13 @@ my %sSubVersion = (
1608
1608
  %Image::ExifTool::XMP::GSpherical = (
1609
1609
  %xmpTableDefaults,
1610
1610
  GROUPS => { 1 => 'XMP-GSpherical', 2 => 'Image' },
1611
+ WRITE_GROUP => 'GSpherical', # write in special location for video files
1611
1612
  NAMESPACE => 'GSpherical',
1612
1613
  AVOID => 1,
1613
1614
  NOTES => q{
1614
1615
  Not actually XMP. These RDF/XML tags are used in Google spherical MP4
1615
- videos. See
1616
+ videos. These tags are written into the video track of MOV/MP4 files, and
1617
+ not at the top level like other XMP tags. See
1616
1618
  L<https://github.com/google/spatial-media/blob/master/docs/spherical-video-rfc.md>
1617
1619
  for the specification.
1618
1620
  },
@@ -1,6 +1,6 @@
1
1
  Summary: perl module for image data extraction
2
2
  Name: perl-Image-ExifTool
3
- Version: 11.53
3
+ Version: 11.54
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.53.0')
4
+ VERSION = Gem::Version.new('11.54.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.53.0
4
+ version: 11.54.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-06-24 00:00:00.000000000 Z
12
+ date: 2019-07-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: exiftool