exiftool_vendored 12.73.0 → 12.75.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +41 -2
  3. data/bin/META.json +1 -1
  4. data/bin/META.yml +1 -1
  5. data/bin/README +46 -45
  6. data/bin/exiftool +97 -83
  7. data/bin/lib/File/RandomAccess.pm +31 -5
  8. data/bin/lib/File/RandomAccess.pod +4 -4
  9. data/bin/lib/Image/ExifTool/7Z.pm +3 -3
  10. data/bin/lib/Image/ExifTool/AFCP.pm +2 -2
  11. data/bin/lib/Image/ExifTool/BZZ.pm +2 -2
  12. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +7 -7
  13. data/bin/lib/Image/ExifTool/Canon.pm +6 -5
  14. data/bin/lib/Image/ExifTool/CanonVRD.pm +2 -2
  15. data/bin/lib/Image/ExifTool/DICOM.pm +2 -2
  16. data/bin/lib/Image/ExifTool/DNG.pm +4 -4
  17. data/bin/lib/Image/ExifTool/Exif.pm +3 -2
  18. data/bin/lib/Image/ExifTool/FLIR.pm +2 -2
  19. data/bin/lib/Image/ExifTool/Fixup.pm +3 -3
  20. data/bin/lib/Image/ExifTool/FlashPix.pm +3 -3
  21. data/bin/lib/Image/ExifTool/FujiFilm.pm +8 -3
  22. data/bin/lib/Image/ExifTool/Geotag.pm +3 -3
  23. data/bin/lib/Image/ExifTool/HtmlDump.pm +2 -2
  24. data/bin/lib/Image/ExifTool/ID3.pm +2 -2
  25. data/bin/lib/Image/ExifTool/Import.pm +5 -5
  26. data/bin/lib/Image/ExifTool/JSON.pm +2 -2
  27. data/bin/lib/Image/ExifTool/Jpeg2000.pm +51 -12
  28. data/bin/lib/Image/ExifTool/MIE.pm +3 -3
  29. data/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -2
  30. data/bin/lib/Image/ExifTool/Nikon.pm +3 -1
  31. data/bin/lib/Image/ExifTool/NikonCustom.pm +3 -3
  32. data/bin/lib/Image/ExifTool/Ogg.pm +2 -2
  33. data/bin/lib/Image/ExifTool/PDF.pm +54 -4
  34. data/bin/lib/Image/ExifTool/PLIST.pm +3 -3
  35. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +3 -3
  36. data/bin/lib/Image/ExifTool/PhaseOne.pm +2 -2
  37. data/bin/lib/Image/ExifTool/Photoshop.pm +3 -3
  38. data/bin/lib/Image/ExifTool/PostScript.pm +2 -2
  39. data/bin/lib/Image/ExifTool/QuickTime.pm +41 -107
  40. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +8 -6
  41. data/bin/lib/Image/ExifTool/RSRC.pm +2 -2
  42. data/bin/lib/Image/ExifTool/Samsung.pm +4 -4
  43. data/bin/lib/Image/ExifTool/Shift.pl +1 -2
  44. data/bin/lib/Image/ExifTool/SigmaRaw.pm +3 -3
  45. data/bin/lib/Image/ExifTool/Sony.pm +3 -3
  46. data/bin/lib/Image/ExifTool/TagInfoXML.pm +2 -2
  47. data/bin/lib/Image/ExifTool/TagLookup.pm +8 -5
  48. data/bin/lib/Image/ExifTool/TagNames.pod +36 -5
  49. data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
  50. data/bin/lib/Image/ExifTool/WriteExif.pl +26 -23
  51. data/bin/lib/Image/ExifTool/WritePDF.pl +1 -1
  52. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +1 -1
  53. data/bin/lib/Image/ExifTool/WriteXMP.pl +4 -2
  54. data/bin/lib/Image/ExifTool/Writer.pl +68 -44
  55. data/bin/lib/Image/ExifTool/XMP.pm +2 -1
  56. data/bin/lib/Image/ExifTool/XMP2.pl +9 -0
  57. data/bin/lib/Image/ExifTool/ZIP.pm +6 -6
  58. data/bin/lib/Image/ExifTool.pm +42 -26
  59. data/bin/lib/Image/ExifTool.pod +76 -71
  60. data/bin/perl-Image-ExifTool.spec +45 -44
  61. data/lib/exiftool_vendored/version.rb +1 -1
  62. metadata +2 -2
@@ -171,9 +171,9 @@ sub RebuildMakerNotes($$$)
171
171
  my $saveOrder = GetByteOrder();
172
172
  my $loc = Image::ExifTool::MakerNotes::LocateIFD($et,\%subdirInfo);
173
173
  if (defined $loc) {
174
- my $makerFixup = $subdirInfo{Fixup} = new Image::ExifTool::Fixup;
174
+ my $makerFixup = $subdirInfo{Fixup} = Image::ExifTool::Fixup->new;
175
175
  # create new exiftool object to rewrite the directory without changing it
176
- my $newTool = new Image::ExifTool;
176
+ my $newTool = Image::ExifTool->new;
177
177
  $newTool->Options(
178
178
  IgnoreMinorErrors => $$et{OPTIONS}{IgnoreMinorErrors},
179
179
  FixBase => $$et{OPTIONS}{FixBase},
@@ -565,7 +565,7 @@ sub WriteExif($$$)
565
565
  my $firstBase = $base;
566
566
  my $raf = $$dirInfo{RAF};
567
567
  my $dirName = $$dirInfo{DirName} || 'unknown';
568
- my $fixup = $$dirInfo{Fixup} || new Image::ExifTool::Fixup;
568
+ my $fixup = $$dirInfo{Fixup} || Image::ExifTool::Fixup->new;
569
569
  my $imageDataFlag = $$dirInfo{ImageData} || '';
570
570
  my $verbose = $et->Options('Verbose');
571
571
  my $out = $et->Options('TextOut');
@@ -745,7 +745,7 @@ sub WriteExif($$$)
745
745
  my $valBuff = ''; # buffer for value data
746
746
  my @valFixups; # list of fixups for offsets in valBuff
747
747
  # fixup for offsets in dirBuff
748
- my $dirFixup = new Image::ExifTool::Fixup;
748
+ my $dirFixup = Image::ExifTool::Fixup->new;
749
749
  my $entryBasedFixup;
750
750
  my $lastTagID = -1;
751
751
  my ($oldInfo, $oldFormat, $oldFormName, $oldCount, $oldSize, $oldValue, $oldImageData);
@@ -896,7 +896,7 @@ Entry: for (;;) {
896
896
  TagInfo => $oldInfo || $tmpInfo,
897
897
  Offset => $base + $valuePtr + $dataPos,
898
898
  Size => $oldSize,
899
- Fixup => new Image::ExifTool::Fixup,
899
+ Fixup => Image::ExifTool::Fixup->new,
900
900
  },
901
901
  $invalidPreview = 2;
902
902
  # remove SubDirectory to prevent processing (for now)
@@ -1348,7 +1348,7 @@ NoOverwrite: next if $isNew > 0;
1348
1348
  # create empty source directory
1349
1349
  my %sourceDir = (
1350
1350
  Parent => $dirName,
1351
- Fixup => new Image::ExifTool::Fixup,
1351
+ Fixup => Image::ExifTool::Fixup->new,
1352
1352
  );
1353
1353
  $sourceDir{DirName} = $$newInfo{Groups}{1} if $$newInfo{SubIFD};
1354
1354
  $newValue = $et->WriteDirectory(\%sourceDir, $subTable);
@@ -1509,7 +1509,7 @@ NoOverwrite: next if $isNew > 0;
1509
1509
  }
1510
1510
  if (defined $loc) {
1511
1511
  # we need fixup data for this subdirectory
1512
- $subdirInfo{Fixup} = new Image::ExifTool::Fixup;
1512
+ $subdirInfo{Fixup} = Image::ExifTool::Fixup->new;
1513
1513
  # rewrite maker notes
1514
1514
  my $changed = $$et{CHANGED};
1515
1515
  $subdir = $et->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
@@ -1673,7 +1673,7 @@ NoOverwrite: next if $isNew > 0;
1673
1673
  Name => $$newInfo{Name},
1674
1674
  TagInfo => $newInfo,
1675
1675
  Parent => $dirName,
1676
- Fixup => new Image::ExifTool::Fixup,
1676
+ Fixup => Image::ExifTool::Fixup->new,
1677
1677
  RAF => $raf,
1678
1678
  Subdir => $subdir,
1679
1679
  # set ImageData only for 1st level SubIFD's
@@ -1782,7 +1782,7 @@ NoOverwrite: next if $isNew > 0;
1782
1782
  #### eval Base ($start,$base)
1783
1783
  $subdirBase += eval $$subdir{Base};
1784
1784
  }
1785
- my $subFixup = new Image::ExifTool::Fixup;
1785
+ my $subFixup = Image::ExifTool::Fixup->new;
1786
1786
  my %subdirInfo = (
1787
1787
  Base => $subdirBase,
1788
1788
  DataPt => $valueDataPt,
@@ -1995,7 +1995,7 @@ NoOverwrite: next if $isNew > 0;
1995
1995
  # hold onto the PreviewImage until we can determine if it fits
1996
1996
  $$et{PREVIEW_INFO} or $$et{PREVIEW_INFO} = {
1997
1997
  Data => $$newValuePt,
1998
- Fixup => new Image::ExifTool::Fixup,
1998
+ Fixup => Image::ExifTool::Fixup->new,
1999
1999
  };
2000
2000
  $$et{PREVIEW_INFO}{ChangeBase} = 1 if $$newInfo{ChangeBase};
2001
2001
  if ($$newInfo{IsOffset} and $$newInfo{IsOffset} eq '2') {
@@ -2017,7 +2017,7 @@ NoOverwrite: next if $isNew > 0;
2017
2017
  $valBuff .= $$newValuePt; # add value data to buffer
2018
2018
  # must save a fixup pointer for every pointer in the directory
2019
2019
  if ($entryBased) {
2020
- $entryBasedFixup or $entryBasedFixup = new Image::ExifTool::Fixup;
2020
+ $entryBasedFixup or $entryBasedFixup = Image::ExifTool::Fixup->new;
2021
2021
  $entryBasedFixup->AddFixup(length($dirBuff) + 8, $dataTag);
2022
2022
  } else {
2023
2023
  $dirFixup->AddFixup(length($dirBuff) + 8, $dataTag);
@@ -2277,14 +2277,17 @@ NoOverwrite: next if $isNew > 0;
2277
2277
  $$offsetInfo{0x117} and $$offsetInfo{0x145} and
2278
2278
  $$offsetInfo{0x111}[2]==1) # (must be a single strip or the tile offsets could get out of sync)
2279
2279
  {
2280
- # some Sony ARW images contain double-referenced raw data stored as both strips
2281
- # and tiles. Copy the data using only the strip tags, but store the TileOffets
2282
- # information for updating later (see PanasonicRaw:PatchRawDataOffset for a
2283
- # description of offsetInfo elements)
2284
- $$offsetInfo{0x111}[5] = $$offsetInfo{0x144}; # hack to save TileOffsets
2285
- # delete tile information from offsetInfo because we will copy as strips
2286
- delete $$offsetInfo{0x144};
2287
- delete $$offsetInfo{0x145};
2280
+ # check the start offsets to see if they are the same
2281
+ if ($$offsetInfo{0x111}[3] == $$offsetInfo{0x144}[3]) {
2282
+ # some Sony ARW images contain double-referenced raw data stored as both strips
2283
+ # and tiles. Copy the data using only the strip tags, but store the TileOffets
2284
+ # information for updating later (see PanasonicRaw:PatchRawDataOffset for a
2285
+ # description of offsetInfo elements)
2286
+ $$offsetInfo{0x111}[5] = $$offsetInfo{0x144}; # hack to save TileOffsets
2287
+ # delete tile information from offsetInfo because we will copy as strips
2288
+ delete $$offsetInfo{0x144};
2289
+ delete $$offsetInfo{0x145};
2290
+ }
2288
2291
  } else {
2289
2292
  $et->Error("TIFF $dirName contains both strip and tile data");
2290
2293
  }
@@ -2451,7 +2454,7 @@ NoOverwrite: next if $isNew > 0;
2451
2454
  $newOffset += $blockSize; # data comes after other deferred data
2452
2455
  # create fixup for SubIFD ImageData
2453
2456
  if ($imageDataFlag eq 'SubIFD' and not $subIfdDataFixup) {
2454
- $subIfdDataFixup = new Image::ExifTool::Fixup;
2457
+ $subIfdDataFixup = Image::ExifTool::Fixup->new;
2455
2458
  $imageData[-1][4] = $subIfdDataFixup;
2456
2459
  }
2457
2460
  $size += $pad; # account for pad byte if necessary
@@ -2522,7 +2525,7 @@ NoOverwrite: next if $isNew > 0;
2522
2525
  # hold onto the PreviewImage until we can determine if it fits
2523
2526
  $$et{PREVIEW_INFO} or $$et{PREVIEW_INFO} = {
2524
2527
  Data => $buff,
2525
- Fixup => new Image::ExifTool::Fixup,
2528
+ Fixup => Image::ExifTool::Fixup->new,
2526
2529
  };
2527
2530
  if ($$tagInfo{IsOffset} and $$tagInfo{IsOffset} eq '2') {
2528
2531
  $$et{PREVIEW_INFO}{NoBaseShift} = 1;
@@ -2603,7 +2606,7 @@ NoOverwrite: next if $isNew > 0;
2603
2606
  $fixup->AddFixup($entry + 8);
2604
2607
  # create special fixup for SubIFD data
2605
2608
  if ($imageDataFlag eq 'SubIFD') {
2606
- my $subIfdDataFixup = new Image::ExifTool::Fixup;
2609
+ my $subIfdDataFixup = Image::ExifTool::Fixup->new;
2607
2610
  $subIfdDataFixup->AddFixup($entry + 8);
2608
2611
  # save fixup in imageData list
2609
2612
  $$blockInfo[4] = $subIfdDataFixup;
@@ -2668,7 +2671,7 @@ NoOverwrite: next if $isNew > 0;
2668
2671
  } else {
2669
2672
  # Doesn't fit, or we still don't know, so save fixup information
2670
2673
  # and put the preview at the end of the file
2671
- $$previewInfo{Fixup} or $$previewInfo{Fixup} = new Image::ExifTool::Fixup;
2674
+ $$previewInfo{Fixup} or $$previewInfo{Fixup} = Image::ExifTool::Fixup->new;
2672
2675
  $$previewInfo{Fixup}->AddFixup($fixup);
2673
2676
  }
2674
2677
  } elsif (defined $newData and $deleteAll) {
@@ -290,7 +290,7 @@ sub WritePDF($$)
290
290
  $raf->Seek($pos, 0);
291
291
 
292
292
  # create a new ExifTool object and use it to read PDF and XMP information
293
- my $newTool = new Image::ExifTool;
293
+ my $newTool = Image::ExifTool->new;
294
294
  $newTool->Options(List => 1);
295
295
  $newTool->Options(Password => $et->Options('Password'));
296
296
  $newTool->Options(NoPDFList => $et->Options('NoPDFList'));
@@ -785,7 +785,7 @@ sub WriteQuickTime($$$)
785
785
  my ($rtnVal, $rtnErr) = $dataPt ? (undef, undef) : (1, 0);
786
786
 
787
787
  if ($dataPt) {
788
- $raf = new File::RandomAccess($dataPt);
788
+ $raf = File::RandomAccess->new($dataPt);
789
789
  } else {
790
790
  return 0 unless $raf;
791
791
  }
@@ -1083,6 +1083,8 @@ sub WriteXMP($$;$)
1083
1083
  # delete all structure (or pseudo-structure) elements
1084
1084
  require 'Image/ExifTool/XMPStruct.pl';
1085
1085
  ($deleted, $added, $existed) = DeleteStruct($et, \%capture, \$path, $nvHash, \$changed);
1086
+ # don't add if it didn't exist and not IsCreating and Avoid
1087
+ undef $added if not $existed and not $$nvHash{IsCreating} and $$tagInfo{Avoid};
1086
1088
  next unless $deleted or $added or $et->IsOverwriting($nvHash);
1087
1089
  next if $existed and $$nvHash{CreateOnly};
1088
1090
  } elsif ($cap) {
@@ -1262,8 +1264,8 @@ sub WriteXMP($$;$)
1262
1264
  # check to see if we want to create this tag
1263
1265
  # (create non-avoided tags in XMP data files by default)
1264
1266
  my $isCreating = ($$nvHash{IsCreating} or (($isStruct or
1265
- ($preferred and not $$tagInfo{Avoid} and
1266
- not defined $$nvHash{Shift})) and not $$nvHash{EditOnly}));
1267
+ ($preferred and not defined $$nvHash{Shift})) and
1268
+ not $$tagInfo{Avoid} and not $$nvHash{EditOnly}));
1267
1269
 
1268
1270
  # don't add new values unless...
1269
1271
  # ...tag existed before and was deleted, or we added it to a list
@@ -26,6 +26,7 @@ sub RemoveNewValuesForGroup($$);
26
26
  sub GetWriteGroup1($$);
27
27
  sub Sanitize($$);
28
28
  sub ConvInv($$$$$;$$);
29
+ sub PushValue($$$;$);
29
30
 
30
31
  my $loadedAllTables; # flag indicating we loaded all tables
31
32
  my $advFmtSelf; # ExifTool object during evaluation of advanced formatting expr
@@ -1260,7 +1261,7 @@ sub SetNewValuesFromFile($$;@)
1260
1261
  }
1261
1262
  # expand shortcuts
1262
1263
  @setTags and ExpandShortcuts(\@setTags);
1263
- my $srcExifTool = new Image::ExifTool;
1264
+ my $srcExifTool = Image::ExifTool->new;
1264
1265
  # set flag to indicate we are being called from inside SetNewValuesFromFile()
1265
1266
  $$srcExifTool{TAGS_FROM_FILE} = 1;
1266
1267
  # synchronize and increment the file sequence number
@@ -1582,7 +1583,7 @@ SET: foreach $set (@setList) {
1582
1583
  my $opts = $$set[3];
1583
1584
  # handle expressions
1584
1585
  if ($$opts{EXPR}) {
1585
- my $val = $srcExifTool->InsertTagValues(\@tags, $$set[1], 'Error');
1586
+ my $val = $srcExifTool->InsertTagValues($$set[1], \@tags, 'Error');
1586
1587
  my $err = $$srcExifTool{VALUE}{Error};
1587
1588
  if ($err) {
1588
1589
  # pass on any error as a warning unless it is suppressed
@@ -2432,7 +2433,7 @@ sub WriteInfo($$;$$)
2432
2433
  #
2433
2434
  until ($$self{VALUE}{Error}) {
2434
2435
  # create random access file object (disable seek test in case of straight copy)
2435
- $raf or $raf = new File::RandomAccess($inRef, 1);
2436
+ $raf or $raf = File::RandomAccess->new($inRef, 1);
2436
2437
  $raf->BinMode();
2437
2438
  if ($numNew == $numPseudo) {
2438
2439
  $rtnVal = 1;
@@ -2703,7 +2704,7 @@ sub GetAllTags(;$)
2703
2704
  my (%allTags, @groups);
2704
2705
  @groups = split ':', $group if $group;
2705
2706
 
2706
- my $et = new Image::ExifTool;
2707
+ my $et = Image::ExifTool->new;
2707
2708
  LoadAllTables(); # first load all our tables
2708
2709
  my @tableNames = keys %allTables;
2709
2710
 
@@ -2748,7 +2749,7 @@ sub GetWritableTags(;$)
2748
2749
  my (%writableTags, @groups);
2749
2750
  @groups = split ':', $group if $group;
2750
2751
 
2751
- my $et = new Image::ExifTool;
2752
+ my $et = Image::ExifTool->new;
2752
2753
  LoadAllTables();
2753
2754
  my @tableNames = keys %allTables;
2754
2755
 
@@ -3124,11 +3125,37 @@ Conv: for (;;) {
3124
3125
  return($val, $err);
3125
3126
  }
3126
3127
 
3128
+ #------------------------------------------------------------------------------
3129
+ # Dereference value and push onto list
3130
+ # Inputs: 0) ExifTool ref, 1) value, 2) list ref, 3) flag to push MissingTagValue for undef value
3131
+ sub PushValue($$$;$)
3132
+ {
3133
+ local $_;
3134
+ my ($self, $val, $list, $missing) = @_;
3135
+ if (ref $val eq 'ARRAY' and ref $$val[0] ne 'HASH') {
3136
+ $self->PushValue($_, $list, $missing) foreach @$val;
3137
+ } elsif (ref $val eq 'SCALAR') {
3138
+ if ($$self{OPTIONS}{Binary} or $$val =~ /^Binary data/) {
3139
+ push @$list, $$val;
3140
+ } else {
3141
+ push @$list, 'Binary data ' . length($$val) . ' bytes';
3142
+ }
3143
+ } elsif (ref $val eq 'HASH' or ref $val eq 'ARRAY') {
3144
+ require 'Image/ExifTool/XMPStruct.pl';
3145
+ push @$list, Image::ExifTool::XMP::SerializeStruct($self, $val);
3146
+ } elsif (not defined $val) {
3147
+ my $mval = $$self{OPTIONS}{MissingTagValue};
3148
+ push @$list, $mval if $missing and defined $mval;
3149
+ } else {
3150
+ push @$list, $val;
3151
+ }
3152
+ }
3153
+
3127
3154
  #------------------------------------------------------------------------------
3128
3155
  # Convert tag names to values or variables in a string
3129
3156
  # (eg. '${EXIF:ISO}x $$' --> '100x $' without hash ref, or "$info{'EXIF:ISO'}x $" with)
3130
- # Inputs: 0) ExifTool object ref, 1) reference to list of found tags
3131
- # 2) string with embedded tag names, 3) Options:
3157
+ # Inputs: 0) ExifTool object ref, 1) string with embedded tag names,
3158
+ # 2) reference to list of found tags or undef to use FOUND_TAGS, 3) Options:
3132
3159
  # undef - set missing tags to ''
3133
3160
  # 'Error' - issue minor error on missing tag (and return undef)
3134
3161
  # 'Warn' - issue minor warning on missing tag (and return undef)
@@ -3145,20 +3172,22 @@ Conv: for (;;) {
3145
3172
  # - advanced feature allows Perl expressions inside braces (eg. '${model;tr/ //d}')
3146
3173
  # - an error/warning in an advanced expression ("${TAG;EXPR}") generates an error
3147
3174
  # if option set to 'Error', or a warning otherwise
3148
- sub InsertTagValues($$$;$$$)
3175
+ sub InsertTagValues($$;$$$$)
3149
3176
  {
3150
3177
  local $_;
3151
- my ($self, $foundTags, $line, $opt, $docGrp, $cache) = @_;
3178
+ my ($self, $line, $foundTags, $opt, $docGrp, $cache) = @_;
3152
3179
  my $rtnStr = '';
3153
3180
  my ($docNum, $tag);
3181
+
3154
3182
  if ($docGrp) {
3155
3183
  $docNum = $docGrp =~ /(\d+)$/ ? $1 : 0;
3156
3184
  } else {
3157
3185
  undef $cache; # no cache if no document groups
3158
3186
  }
3187
+ $foundTags or $foundTags = $$self{FOUND_TAGS} || [];
3159
3188
  while ($line =~ s/(.*?)\$(\{\s*)?([-\w]*\w|\$|\/)//s) {
3160
3189
  my ($pre, $bra, $var) = ($1, $2, $3);
3161
- my (@tags, $val, $tg, @val, $type, $expr, $didExpr, $level, $asList);
3190
+ my (@tags, $tg, $val, @val, $type, $expr, $didExpr, $level, $asList);
3162
3191
  # "$$" represents a "$" symbol, and "$/" is a newline
3163
3192
  if ($var eq '$' or $var eq '/') {
3164
3193
  $line =~ s/^\s*\}// if $bra;
@@ -3261,15 +3290,24 @@ sub InsertTagValues($$$;$$$)
3261
3290
  } elsif (defined $$et{OPTIONS}{UserParam}{$lcTag}) {
3262
3291
  $val = $$et{OPTIONS}{UserParam}{$lcTag};
3263
3292
  } elsif ($tag =~ /(.*):(.+)/) {
3264
- my $group;
3293
+ my ($group, @matches);
3265
3294
  ($group, $tag) = ($1, $2);
3266
- if (lc $tag eq 'all') {
3267
- # see if any tag from the specified group exists
3268
- my $match = $et->GroupMatches($group, $fileTags);
3269
- $val = $match ? 1 : 0;
3295
+ # join values of all matching tags if "All" group is used
3296
+ # (and remove "All" from group prefix)
3297
+ if ($group =~ s/(^|:)(all|\*)(:|$)/$1 and $3/ei) {
3298
+ if (lc $tag eq 'all') {
3299
+ @matches = $group ? $et->GroupMatches($group, $fileTags) : @$fileTags;
3300
+ } else {
3301
+ @matches = grep /^$tag(\s|$)/i, @$fileTags;
3302
+ @matches = $et->GroupMatches($group, \@matches) if $group;
3303
+ }
3304
+ $self->PushValue(scalar $et->GetValue($_, $type), \@val) foreach @matches;
3305
+ } elsif (lc $tag eq 'all') {
3306
+ # return "1" if any tag from the specified group exists
3307
+ $val = $et->GroupMatches($group, $fileTags) ? 1 : 0;
3270
3308
  } else {
3271
3309
  # find the specified tag
3272
- my @matches = grep /^$tag(\s|$)/i, @$fileTags;
3310
+ @matches = grep /^$tag(\s|$)/i, @$fileTags;
3273
3311
  @matches = $et->GroupMatches($group, \@matches);
3274
3312
  foreach $tg (@matches) {
3275
3313
  if (defined $val and $tg =~ / \((\d+)\)$/) {
@@ -3298,31 +3336,15 @@ sub InsertTagValues($$$;$$$)
3298
3336
  }
3299
3337
  }
3300
3338
  $self->Options(ListJoin => $oldListJoin) if $asList;
3301
- if (ref $val eq 'ARRAY') {
3302
- push @val, @$val;
3303
- undef $val;
3304
- last unless @tags;
3305
- } elsif (ref $val eq 'SCALAR') {
3306
- if ($$self{OPTIONS}{Binary} or $$val =~ /^Binary data/) {
3307
- $val = $$val;
3308
- } else {
3309
- $val = 'Binary data ' . length($$val) . ' bytes';
3310
- }
3311
- } elsif (ref $val eq 'HASH') {
3312
- require 'Image/ExifTool/XMPStruct.pl';
3313
- $val = Image::ExifTool::XMP::SerializeStruct($self, $val);
3314
- } elsif (not defined $val) {
3315
- $val = $$self{OPTIONS}{MissingTagValue} if $asList;
3316
- }
3317
- last unless @tags;
3318
- push @val, $val if defined $val;
3339
+ $self->PushValue($val, \@val, $asList);
3319
3340
  undef $val;
3341
+ last unless @tags;
3320
3342
  }
3321
3343
  if (@val) {
3322
- push @val, $val if defined $val;
3344
+ $self->PushValue($val, \@val) if defined $val;
3323
3345
  $val = join $$self{OPTIONS}{ListSep}, @val;
3324
- } else {
3325
- push @val, $val if defined $val; # (so the eval has access to @val if required)
3346
+ } elsif (defined $val) {
3347
+ $self->PushValue($val, \@val); # (so the eval has access to @val if required)
3326
3348
  }
3327
3349
  # evaluate advanced formatting expression if given (eg. "${TAG;EXPR}")
3328
3350
  if (defined $expr and defined $val) {
@@ -3331,7 +3353,7 @@ sub InsertTagValues($$$;$$$)
3331
3353
  $advFmtSelf = $self;
3332
3354
  if ($asList) {
3333
3355
  foreach (@val) {
3334
- #### eval advanced formatting expression ($_, $self, @val, $advFmtSelf)
3356
+ #### eval advanced formatting expression ($_, $self, @val, $tag, $advFmtSelf)
3335
3357
  eval $expr;
3336
3358
  $@ and $evalWarning = $@;
3337
3359
  }
@@ -3340,7 +3362,7 @@ sub InsertTagValues($$$;$$$)
3340
3362
  $val = @val ? join $$self{OPTIONS}{ListSep}, @val : undef;
3341
3363
  } else {
3342
3364
  $_ = $val;
3343
- #### eval advanced formatting expression ($_, $self, @val, $advFmtSelf)
3365
+ #### eval advanced formatting expression ($_, $self, @val, $tag, $advFmtSelf)
3344
3366
  eval $expr;
3345
3367
  $@ and $evalWarning = $@;
3346
3368
  $val = ref $_ eq 'ARRAY' ? join($$self{OPTIONS}{ListSep}, @$_): $_;
@@ -3395,6 +3417,7 @@ sub InsertTagValues($$$;$$$)
3395
3417
  #------------------------------------------------------------------------------
3396
3418
  # Reformat date/time value in $_ based on specified format string
3397
3419
  # Inputs: 0) date/time format string
3420
+ # Returns: Reformatted date/time string
3398
3421
  sub DateFmt($)
3399
3422
  {
3400
3423
  my $et = bless { OPTIONS => { DateFormat => shift, StrictDate => 1 } };
@@ -3406,6 +3429,7 @@ sub DateFmt($)
3406
3429
  $_ = $et->ConvertDateTime($_);
3407
3430
  defined $_ or warn "Error converting date/time\n";
3408
3431
  $$advFmtSelf{GLOBAL_TIME_OFFSET} = $$et{GLOBAL_TIME_OFFSET} if $shift;
3432
+ return $_;
3409
3433
  }
3410
3434
 
3411
3435
  #------------------------------------------------------------------------------
@@ -3515,7 +3539,7 @@ sub CreateDirectory($$)
3515
3539
  }
3516
3540
  unless ($k32CreateDir) {
3517
3541
  return -1 if defined $k32CreateDir;
3518
- $k32CreateDir = new Win32::API('KERNEL32', 'CreateDirectoryW', 'PP', 'I');
3542
+ $k32CreateDir = Win32::API->new('KERNEL32', 'CreateDirectoryW', 'PP', 'I');
3519
3543
  unless ($k32CreateDir) {
3520
3544
  $self->Warn('Error calling Win32::API::CreateDirectoryW');
3521
3545
  $k32CreateDir = 0;
@@ -6233,7 +6257,7 @@ sub WriteJPEG($$)
6233
6257
  last unless $$editDirs{CIFF};
6234
6258
  my $newData = '';
6235
6259
  my %dirInfo = (
6236
- RAF => new File::RandomAccess($segDataPt),
6260
+ RAF => File::RandomAccess->new($segDataPt),
6237
6261
  OutFile => \$newData,
6238
6262
  );
6239
6263
  require Image::ExifTool::CanonRaw;
@@ -6952,7 +6976,7 @@ sub SetFileTime($$;$$$$)
6952
6976
  }
6953
6977
  unless ($k32SetFileTime) {
6954
6978
  return 0 if defined $k32SetFileTime;
6955
- $k32SetFileTime = new Win32::API('KERNEL32', 'SetFileTime', 'NPPP', 'I');
6979
+ $k32SetFileTime = Win32::API->new('KERNEL32', 'SetFileTime', 'NPPP', 'I');
6956
6980
  unless ($k32SetFileTime) {
6957
6981
  $self->Warn('Error calling Win32::API::SetFileTime');
6958
6982
  $k32SetFileTime = 0;
@@ -7196,7 +7220,7 @@ sub WriteBinaryData($$$)
7196
7220
  $$self{HiddenData} = {
7197
7221
  Offset => $offset,
7198
7222
  Size => $size,
7199
- Fixup => new Image::ExifTool::Fixup,
7223
+ Fixup => Image::ExifTool::Fixup->new,
7200
7224
  Base => $$dirInfo{Base},
7201
7225
  };
7202
7226
  next;
@@ -7205,7 +7229,7 @@ sub WriteBinaryData($$$)
7205
7229
  next unless $$tagInfo{DataTag} eq 'PreviewImage' and $$self{FILE_TYPE} eq 'JPEG';
7206
7230
  my $previewInfo = $$self{PREVIEW_INFO};
7207
7231
  $previewInfo or $previewInfo = $$self{PREVIEW_INFO} = {
7208
- Fixup => new Image::ExifTool::Fixup,
7232
+ Fixup => Image::ExifTool::Fixup->new,
7209
7233
  };
7210
7234
  # set flag indicating we are using short pointers
7211
7235
  $$previewInfo{IsShort} = 1 unless $format eq 'int32u';
@@ -50,7 +50,7 @@ use Image::ExifTool::Exif;
50
50
  use Image::ExifTool::GPS;
51
51
  require Exporter;
52
52
 
53
- $VERSION = '3.62';
53
+ $VERSION = '3.63';
54
54
  @ISA = qw(Exporter);
55
55
  @EXPORT_OK = qw(EscapeXML UnescapeXML);
56
56
 
@@ -3644,6 +3644,7 @@ NoLoop:
3644
3644
  IgnoreProp => $$subdir{IgnoreProp}, # (allow XML to ignore specified properties)
3645
3645
  IsExtended => 1, # (hack to avoid Duplicate warning for embedded XMP)
3646
3646
  NoStruct => 1, # (don't try to build structures since this isn't true XMP)
3647
+ NoBlockSave => 1,# (don't save as a block because we already did this)
3647
3648
  );
3648
3649
  my $oldOrder = GetByteOrder();
3649
3650
  SetByteOrder($$subdir{ByteOrder}) if $$subdir{ByteOrder};
@@ -2191,6 +2191,15 @@ my %sSubVersion = (
2191
2191
  GROUPS => { 0 => 'SVG', 2 => 'Unknown' },
2192
2192
  LANG_INFO => \&GetLangInfo,
2193
2193
  NAMESPACE => undef, # variable namespace
2194
+ 'c2pa:manifest' => {
2195
+ Name => 'JUMBF',
2196
+ Groups => { 0 => 'JUMBF' },
2197
+ RawConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
2198
+ SubDirectory => {
2199
+ TagTable => 'Image::ExifTool::Jpeg2000::Main',
2200
+ ByteOrder => 'BigEndian',
2201
+ },
2202
+ },
2194
2203
  );
2195
2204
 
2196
2205
  #------------------------------------------------------------------------------
@@ -20,7 +20,7 @@ use strict;
20
20
  use vars qw($VERSION $warnString);
21
21
  use Image::ExifTool qw(:DataAccess :Utils);
22
22
 
23
- $VERSION = '1.30';
23
+ $VERSION = '1.31';
24
24
 
25
25
  sub WarnProc($) { $warnString = $_[0]; }
26
26
 
@@ -367,7 +367,7 @@ sub ProcessRAR($$)
367
367
  # read the header and create new RAF object for reading it
368
368
  my $header;
369
369
  $raf->Read($header, $headSize) == $headSize or last;
370
- my $rafHdr = new File::RandomAccess(\$header);
370
+ my $rafHdr = File::RandomAccess->new(\$header);
371
371
  my $headType = ReadULEB($rafHdr); # get header type
372
372
 
373
373
  if ($headType == 4) { # encryption block
@@ -550,14 +550,14 @@ sub ProcessZIP($$)
550
550
  } elsif (eval { require IO::String }) {
551
551
  # read the whole file into memory (what else can I do?)
552
552
  $raf->Slurp();
553
- $fh = new IO::String ${$raf->{BUFF_PT}};
553
+ $fh = IO::String->new(${$raf->{BUFF_PT}});
554
554
  } else {
555
555
  my $type = $raf->{FILE_PT} ? 'pipe or socket' : 'scalar reference';
556
556
  $et->Warn("Install IO::String to decode compressed ZIP information from a $type");
557
557
  last;
558
558
  }
559
559
  $et->VPrint(1, " --- using Archive::Zip ---\n");
560
- $zip = new Archive::Zip;
560
+ $zip = Archive::Zip->new;
561
561
  # catch all warnings! (Archive::Zip is bad for this)
562
562
  local $SIG{'__WARN__'} = \&WarnProc;
563
563
  my $status = $zip->readFromFileHandle($fh);
@@ -568,8 +568,8 @@ sub ProcessZIP($$)
568
568
  # a failed test with Perl 5.6.2 GNU/Linux 2.6.32-5-686 i686-linux-64int-ld
569
569
  $raf->Seek(0,0);
570
570
  $raf->Slurp();
571
- $fh = new IO::String ${$raf->{BUFF_PT}};
572
- $zip = new Archive::Zip;
571
+ $fh = IO::String->new(${$raf->{BUFF_PT}});
572
+ $zip = Archive::Zip->new;
573
573
  $status = $zip->readFromFileHandle($fh);
574
574
  }
575
575
  if ($status) {