exiftool_vendored 12.73.0 → 12.75.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.
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) {