exiftool_vendored 10.65.0 → 11.41.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.

Files changed (205) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +818 -19
  3. data/bin/MANIFEST +38 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +48 -44
  7. data/bin/arg_files/exif2xmp.args +4 -1
  8. data/bin/arg_files/gps2xmp.args +4 -1
  9. data/bin/arg_files/iptcCore.args +8 -0
  10. data/bin/arg_files/xmp2exif.args +4 -1
  11. data/bin/arg_files/xmp2gps.args +4 -1
  12. data/bin/config_files/dji.config +131 -0
  13. data/bin/config_files/example.config +6 -2
  14. data/bin/config_files/gps2utm.config +256 -256
  15. data/bin/config_files/nksc.config +146 -0
  16. data/bin/config_files/picasa_faces.config +382 -382
  17. data/bin/exiftool +688 -408
  18. data/bin/fmt_files/gpx.fmt +10 -6
  19. data/bin/fmt_files/gpx_wpt.fmt +10 -6
  20. data/bin/fmt_files/kml.fmt +8 -5
  21. data/bin/lib/File/RandomAccess.pm +48 -8
  22. data/bin/lib/File/RandomAccess.pod +21 -2
  23. data/bin/lib/Image/ExifTool.pm +645 -256
  24. data/bin/lib/Image/ExifTool.pod +219 -164
  25. data/bin/lib/Image/ExifTool/AES.pm +1 -1
  26. data/bin/lib/Image/ExifTool/AFCP.pm +3 -8
  27. data/bin/lib/Image/ExifTool/AIFF.pm +12 -4
  28. data/bin/lib/Image/ExifTool/APE.pm +1 -1
  29. data/bin/lib/Image/ExifTool/APP12.pm +1 -1
  30. data/bin/lib/Image/ExifTool/ASF.pm +19 -6
  31. data/bin/lib/Image/ExifTool/Apple.pm +13 -5
  32. data/bin/lib/Image/ExifTool/Audible.pm +1 -1
  33. data/bin/lib/Image/ExifTool/BMP.pm +1 -1
  34. data/bin/lib/Image/ExifTool/BPG.pm +17 -15
  35. data/bin/lib/Image/ExifTool/BZZ.pm +1 -1
  36. data/bin/lib/Image/ExifTool/BigTIFF.pm +30 -15
  37. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +103 -52
  38. data/bin/lib/Image/ExifTool/Canon.pm +684 -112
  39. data/bin/lib/Image/ExifTool/CanonCustom.pm +119 -9
  40. data/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
  41. data/bin/lib/Image/ExifTool/CanonVRD.pm +13 -26
  42. data/bin/lib/Image/ExifTool/CaptureOne.pm +1 -1
  43. data/bin/lib/Image/ExifTool/Casio.pm +1 -1
  44. data/bin/lib/Image/ExifTool/Charset.pm +1 -1
  45. data/bin/lib/Image/ExifTool/DICOM.pm +12 -5
  46. data/bin/lib/Image/ExifTool/DJI.pm +51 -3
  47. data/bin/lib/Image/ExifTool/DNG.pm +15 -8
  48. data/bin/lib/Image/ExifTool/DPX.pm +1 -1
  49. data/bin/lib/Image/ExifTool/DV.pm +1 -1
  50. data/bin/lib/Image/ExifTool/DarwinCore.pm +63 -23
  51. data/bin/lib/Image/ExifTool/DjVu.pm +4 -2
  52. data/bin/lib/Image/ExifTool/EXE.pm +30 -6
  53. data/bin/lib/Image/ExifTool/Exif.pm +351 -109
  54. data/bin/lib/Image/ExifTool/FITS.pm +148 -0
  55. data/bin/lib/Image/ExifTool/FLAC.pm +2 -2
  56. data/bin/lib/Image/ExifTool/FLIF.pm +1 -1
  57. data/bin/lib/Image/ExifTool/FLIR.pm +109 -13
  58. data/bin/lib/Image/ExifTool/Fixup.pm +1 -1
  59. data/bin/lib/Image/ExifTool/Flash.pm +3 -3
  60. data/bin/lib/Image/ExifTool/FlashPix.pm +433 -9
  61. data/bin/lib/Image/ExifTool/Font.pm +2 -2
  62. data/bin/lib/Image/ExifTool/FotoStation.pm +1 -1
  63. data/bin/lib/Image/ExifTool/FujiFilm.pm +336 -16
  64. data/bin/lib/Image/ExifTool/GE.pm +1 -1
  65. data/bin/lib/Image/ExifTool/GIF.pm +5 -7
  66. data/bin/lib/Image/ExifTool/GIMP.pm +39 -3
  67. data/bin/lib/Image/ExifTool/GPS.pm +48 -22
  68. data/bin/lib/Image/ExifTool/GeoTiff.pm +23 -23
  69. data/bin/lib/Image/ExifTool/Geotag.pm +80 -45
  70. data/bin/lib/Image/ExifTool/GoPro.pm +709 -0
  71. data/bin/lib/Image/ExifTool/H264.pm +40 -18
  72. data/bin/lib/Image/ExifTool/HP.pm +1 -1
  73. data/bin/lib/Image/ExifTool/HTML.pm +19 -12
  74. data/bin/lib/Image/ExifTool/HtmlDump.pm +37 -26
  75. data/bin/lib/Image/ExifTool/ICC_Profile.pm +297 -23
  76. data/bin/lib/Image/ExifTool/ID3.pm +12 -7
  77. data/bin/lib/Image/ExifTool/IPTC.pm +48 -19
  78. data/bin/lib/Image/ExifTool/ISO.pm +1 -1
  79. data/bin/lib/Image/ExifTool/ITC.pm +1 -1
  80. data/bin/lib/Image/ExifTool/Import.pm +13 -9
  81. data/bin/lib/Image/ExifTool/InDesign.pm +3 -5
  82. data/bin/lib/Image/ExifTool/JPEG.pm +22 -11
  83. data/bin/lib/Image/ExifTool/JPEGDigest.pm +1 -1
  84. data/bin/lib/Image/ExifTool/JSON.pm +3 -3
  85. data/bin/lib/Image/ExifTool/JVC.pm +1 -1
  86. data/bin/lib/Image/ExifTool/Jpeg2000.pm +2 -2
  87. data/bin/lib/Image/ExifTool/Kodak.pm +1233 -58
  88. data/bin/lib/Image/ExifTool/KyoceraRaw.pm +1 -1
  89. data/bin/lib/Image/ExifTool/LNK.pm +1 -1
  90. data/bin/lib/Image/ExifTool/Lang/cs.pm +1 -1
  91. data/bin/lib/Image/ExifTool/Lang/de.pm +33 -24
  92. data/bin/lib/Image/ExifTool/Lang/en_ca.pm +64 -2
  93. data/bin/lib/Image/ExifTool/Lang/en_gb.pm +64 -2
  94. data/bin/lib/Image/ExifTool/Lang/es.pm +8 -4
  95. data/bin/lib/Image/ExifTool/Lang/fi.pm +46 -4
  96. data/bin/lib/Image/ExifTool/Lang/fr.pm +5 -3
  97. data/bin/lib/Image/ExifTool/Lang/it.pm +6 -3
  98. data/bin/lib/Image/ExifTool/Lang/ja.pm +15 -3
  99. data/bin/lib/Image/ExifTool/Lang/ko.pm +5 -2
  100. data/bin/lib/Image/ExifTool/Lang/nl.pm +6 -3
  101. data/bin/lib/Image/ExifTool/Lang/pl.pm +2 -2
  102. data/bin/lib/Image/ExifTool/Lang/ru.pm +1 -1
  103. data/bin/lib/Image/ExifTool/Lang/sv.pm +1 -1
  104. data/bin/lib/Image/ExifTool/Lang/tr.pm +4 -2
  105. data/bin/lib/Image/ExifTool/Lang/zh_cn.pm +1 -1
  106. data/bin/lib/Image/ExifTool/Lang/zh_tw.pm +1 -1
  107. data/bin/lib/Image/ExifTool/Leaf.pm +1 -1
  108. data/bin/lib/Image/ExifTool/Lytro.pm +4 -8
  109. data/bin/lib/Image/ExifTool/M2TS.pm +10 -9
  110. data/bin/lib/Image/ExifTool/MIE.pm +12 -8
  111. data/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
  112. data/bin/lib/Image/ExifTool/MIFF.pm +1 -1
  113. data/bin/lib/Image/ExifTool/MNG.pm +1 -1
  114. data/bin/lib/Image/ExifTool/MOI.pm +1 -1
  115. data/bin/lib/Image/ExifTool/MPC.pm +1 -1
  116. data/bin/lib/Image/ExifTool/MPEG.pm +2 -3
  117. data/bin/lib/Image/ExifTool/MPF.pm +6 -6
  118. data/bin/lib/Image/ExifTool/MWG.pm +4 -4
  119. data/bin/lib/Image/ExifTool/MXF.pm +2 -2
  120. data/bin/lib/Image/ExifTool/MacOS.pm +184 -34
  121. data/bin/lib/Image/ExifTool/MakerNotes.pm +101 -18
  122. data/bin/lib/Image/ExifTool/Matroska.pm +1 -1
  123. data/bin/lib/Image/ExifTool/Microsoft.pm +5 -3
  124. data/bin/lib/Image/ExifTool/Minolta.pm +89 -62
  125. data/bin/lib/Image/ExifTool/MinoltaRaw.pm +1 -1
  126. data/bin/lib/Image/ExifTool/Motorola.pm +1 -1
  127. data/bin/lib/Image/ExifTool/Nikon.pm +1511 -380
  128. data/bin/lib/Image/ExifTool/NikonCapture.pm +1 -1
  129. data/bin/lib/Image/ExifTool/NikonCustom.pm +2758 -2935
  130. data/bin/lib/Image/ExifTool/Nintendo.pm +1 -1
  131. data/bin/lib/Image/ExifTool/OOXML.pm +1 -1
  132. data/bin/lib/Image/ExifTool/Ogg.pm +1 -1
  133. data/bin/lib/Image/ExifTool/Olympus.pm +47 -8
  134. data/bin/lib/Image/ExifTool/OpenEXR.pm +1 -1
  135. data/bin/lib/Image/ExifTool/Opus.pm +1 -1
  136. data/bin/lib/Image/ExifTool/PCX.pm +138 -0
  137. data/bin/lib/Image/ExifTool/PDF.pm +58 -42
  138. data/bin/lib/Image/ExifTool/PGF.pm +1 -1
  139. data/bin/lib/Image/ExifTool/PICT.pm +1 -1
  140. data/bin/lib/Image/ExifTool/PLIST.pm +12 -5
  141. data/bin/lib/Image/ExifTool/PLUS.pm +1 -1
  142. data/bin/lib/Image/ExifTool/PNG.pm +108 -10
  143. data/bin/lib/Image/ExifTool/PPM.pm +3 -3
  144. data/bin/lib/Image/ExifTool/PSP.pm +1 -1
  145. data/bin/lib/Image/ExifTool/Palm.pm +1 -1
  146. data/bin/lib/Image/ExifTool/Panasonic.pm +299 -31
  147. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +201 -19
  148. data/bin/lib/Image/ExifTool/Pentax.pm +164 -143
  149. data/bin/lib/Image/ExifTool/PhaseOne.pm +12 -5
  150. data/bin/lib/Image/ExifTool/PhotoCD.pm +9 -10
  151. data/bin/lib/Image/ExifTool/PhotoMechanic.pm +1 -1
  152. data/bin/lib/Image/ExifTool/Photoshop.pm +230 -60
  153. data/bin/lib/Image/ExifTool/PostScript.pm +29 -4
  154. data/bin/lib/Image/ExifTool/PrintIM.pm +1 -1
  155. data/bin/lib/Image/ExifTool/Qualcomm.pm +2 -2
  156. data/bin/lib/Image/ExifTool/QuickTime.pm +1539 -279
  157. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +1857 -0
  158. data/bin/lib/Image/ExifTool/README +84 -46
  159. data/bin/lib/Image/ExifTool/RIFF.pm +116 -23
  160. data/bin/lib/Image/ExifTool/RSRC.pm +1 -1
  161. data/bin/lib/Image/ExifTool/RTF.pm +6 -4
  162. data/bin/lib/Image/ExifTool/Radiance.pm +1 -1
  163. data/bin/lib/Image/ExifTool/Rawzor.pm +3 -2
  164. data/bin/lib/Image/ExifTool/Real.pm +1 -1
  165. data/bin/lib/Image/ExifTool/Reconyx.pm +261 -7
  166. data/bin/lib/Image/ExifTool/Red.pm +325 -0
  167. data/bin/lib/Image/ExifTool/Ricoh.pm +3 -7
  168. data/bin/lib/Image/ExifTool/Samsung.pm +95 -25
  169. data/bin/lib/Image/ExifTool/Sanyo.pm +1 -1
  170. data/bin/lib/Image/ExifTool/Scalado.pm +1 -1
  171. data/bin/lib/Image/ExifTool/Shift.pl +26 -12
  172. data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -2
  173. data/bin/lib/Image/ExifTool/Sigma.pm +36 -30
  174. data/bin/lib/Image/ExifTool/SigmaRaw.pm +3 -8
  175. data/bin/lib/Image/ExifTool/Sony.pm +531 -177
  176. data/bin/lib/Image/ExifTool/SonyIDC.pm +63 -3
  177. data/bin/lib/Image/ExifTool/Stim.pm +2 -2
  178. data/bin/lib/Image/ExifTool/TagInfoXML.pm +23 -23
  179. data/bin/lib/Image/ExifTool/TagLookup.pm +6352 -5062
  180. data/bin/lib/Image/ExifTool/TagNames.pod +3024 -565
  181. data/bin/lib/Image/ExifTool/Theora.pm +1 -1
  182. data/bin/lib/Image/ExifTool/Torrent.pm +2 -2
  183. data/bin/lib/Image/ExifTool/Unknown.pm +1 -1
  184. data/bin/lib/Image/ExifTool/VCard.pm +47 -9
  185. data/bin/lib/Image/ExifTool/Validate.pm +391 -99
  186. data/bin/lib/Image/ExifTool/Vorbis.pm +1 -1
  187. data/bin/lib/Image/ExifTool/WTV.pm +319 -0
  188. data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
  189. data/bin/lib/Image/ExifTool/WriteExif.pl +91 -18
  190. data/bin/lib/Image/ExifTool/WriteIPTC.pl +6 -6
  191. data/bin/lib/Image/ExifTool/WritePDF.pl +13 -12
  192. data/bin/lib/Image/ExifTool/WritePNG.pl +1 -1
  193. data/bin/lib/Image/ExifTool/WritePhotoshop.pl +1 -1
  194. data/bin/lib/Image/ExifTool/WritePostScript.pl +2 -2
  195. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +764 -121
  196. data/bin/lib/Image/ExifTool/WriteXMP.pl +176 -67
  197. data/bin/lib/Image/ExifTool/Writer.pl +490 -246
  198. data/bin/lib/Image/ExifTool/XMP.pm +216 -76
  199. data/bin/lib/Image/ExifTool/XMP2.pl +54 -10
  200. data/bin/lib/Image/ExifTool/XMPStruct.pl +14 -11
  201. data/bin/lib/Image/ExifTool/ZIP.pm +60 -15
  202. data/bin/lib/Image/ExifTool/iWork.pm +12 -5
  203. data/bin/perl-Image-ExifTool.spec +46 -44
  204. data/lib/exiftool_vendored/version.rb +1 -1
  205. metadata +14 -4
@@ -14,7 +14,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
14
14
  use Image::ExifTool::Exif;
15
15
  use Image::ExifTool::GPS;
16
16
 
17
- $VERSION = '1.46';
17
+ $VERSION = '1.47';
18
18
 
19
19
  sub ProcessMIE($$);
20
20
  sub ProcessMIEGroup($$$);
@@ -152,6 +152,9 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
152
152
  (eg. C<55(mi/h)>). If no units are specified, the default units are
153
153
  written.
154
154
 
155
+ 4) ExifTool writes compressed metadata to MIE files if the Compress (-z)
156
+ option is used and Compress::Zlib is available.
157
+
155
158
  See L<http://owl.phy.queensu.ca/~phil/exiftool/MIE1.1-20070121.pdf> for the
156
159
  official MIE specification.
157
160
  },
@@ -977,7 +980,7 @@ sub WriteMIEGroup($$$)
977
980
  if ($tagLen) {
978
981
  $raf->Read($tag, $tagLen) == $tagLen or last;
979
982
  $oldHdr .= $tag; # add tag to element header
980
- $et->Warn("MIE tag '$tag' out of sequence") if $tag lt $lastTag;
983
+ $et->Warn("MIE tag '${tag}' out of sequence") if $tag lt $lastTag;
981
984
  # separate units from tag name if they exist
982
985
  $units = $1 if $tag =~ s/\((.*)\)$//;
983
986
  } else {
@@ -1035,7 +1038,7 @@ sub WriteMIEGroup($$$)
1035
1038
  if ($newTag eq $tag) {
1036
1039
  # make sure that either both or neither old and new tags are MIE groups
1037
1040
  if ($isMieGroup xor ($format & 0xf3) == 0x10) {
1038
- $et->Warn("Tag '$tag' not expected type");
1041
+ $et->Warn("Tag '${tag}' not expected type");
1039
1042
  next; # don't write our new tag
1040
1043
  }
1041
1044
  # uncompress existing directory into $oldVal since we are editing it
@@ -1122,6 +1125,7 @@ sub WriteMIEGroup($$$)
1122
1125
  eval { require Compress::Zlib })
1123
1126
  {
1124
1127
  $subdirInfo{Compact} = 1;
1128
+ $subdirInfo{ReadOnly} = 1; # because XMP is not writable in place
1125
1129
  }
1126
1130
  }
1127
1131
  $subdirInfo{Parent} = $dirName;
@@ -1269,7 +1273,7 @@ sub WriteMIEGroup($$$)
1269
1273
  }
1270
1274
  $newFormat = $mieCode{$writable};
1271
1275
  unless (defined $newFormat) {
1272
- $msg = "Bad format '$writable' for $$newInfo{Name}";
1276
+ $msg = "Bad format '${writable}' for $$newInfo{Name}";
1273
1277
  next MieElement;
1274
1278
  }
1275
1279
  }
@@ -1478,7 +1482,7 @@ sub ProcessMIEGroup($$$)
1478
1482
  my ($tag, $units);
1479
1483
  if ($tagLen) {
1480
1484
  $raf->Read($tag, $tagLen) == $tagLen or last;
1481
- $et->Warn("MIE tag '$tag' out of sequence") if $tag lt $lastTag;
1485
+ $et->Warn("MIE tag '${tag}' out of sequence") if $tag lt $lastTag;
1482
1486
  $lastTag = $tag;
1483
1487
  # separate units from tag name if they exist
1484
1488
  $units = $1 if $tag =~ s/\((.*)\)$//;
@@ -1538,7 +1542,7 @@ sub ProcessMIEGroup($$$)
1538
1542
  $raf->Read($value, $valLen) == $valLen or last;
1539
1543
  if ($format & 0x04) {
1540
1544
  if ($verbose) {
1541
- print $out "$$et{INDENT}\[Tag '$tag' $valLen bytes compressed]\n";
1545
+ print $out "$$et{INDENT}\[Tag '${tag}' $valLen bytes compressed]\n";
1542
1546
  }
1543
1547
  next unless HasZlib($et, 'decode');
1544
1548
  my $stat;
@@ -1603,7 +1607,7 @@ sub ProcessMIEGroup($$$)
1603
1607
  }
1604
1608
  $et->VerboseInfo($lastTag, $tagInfo,
1605
1609
  DataPt => \$value,
1606
- DataPos => $raf->Tell() - $valLen,
1610
+ DataPos => $wasCompressed ? undef : $raf->Tell() - $valLen,
1607
1611
  Size => $valLen,
1608
1612
  Format => $formatStr,
1609
1613
  Value => $val,
@@ -2541,7 +2545,7 @@ tag name. For example:
2541
2545
 
2542
2546
  =head1 AUTHOR
2543
2547
 
2544
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
2548
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
2545
2549
 
2546
2550
  This library is free software; you can redistribute it and/or modify it
2547
2551
  under the same terms as Perl itself. The MIE format itself is also
@@ -356,7 +356,7 @@ A few examples of combined units strings:
356
356
 
357
357
  =head1 AUTHOR
358
358
 
359
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
359
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
360
360
 
361
361
  This library is free software; you can redistribute it and/or modify it
362
362
  under the same terms as Perl itself.
@@ -255,7 +255,7 @@ This module contains routines required by Image::ExifTool to read MIFF
255
255
 
256
256
  =head1 AUTHOR
257
257
 
258
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
258
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
259
259
 
260
260
  This library is free software; you can redistribute it and/or modify it
261
261
  under the same terms as Perl itself.
@@ -661,7 +661,7 @@ This module contains definitions required by Image::ExifTool to read MNG
661
661
 
662
662
  =head1 AUTHOR
663
663
 
664
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
664
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
665
665
 
666
666
  This library is free software; you can redistribute it and/or modify it
667
667
  under the same terms as Perl itself.
@@ -136,7 +136,7 @@ information from MOI files.
136
136
 
137
137
  =head1 AUTHOR
138
138
 
139
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
139
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
140
140
 
141
141
  This library is free software; you can redistribute it and/or modify it
142
142
  under the same terms as Perl itself.
@@ -134,7 +134,7 @@ information from Musepack (MPC) audio files.
134
134
 
135
135
  =head1 AUTHOR
136
136
 
137
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
137
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
138
138
 
139
139
  This library is free software; you can redistribute it and/or modify it
140
140
  under the same terms as Perl itself.
@@ -18,7 +18,7 @@ use strict;
18
18
  use vars qw($VERSION);
19
19
  use Image::ExifTool qw(:DataAccess :Utils);
20
20
 
21
- $VERSION = '1.15';
21
+ $VERSION = '1.16';
22
22
 
23
23
  %Image::ExifTool::MPEG::Audio = (
24
24
  GROUPS => { 2 => 'Audio' },
@@ -369,7 +369,6 @@ $VERSION = '1.15';
369
369
  24 => {
370
370
  Name => 'LameStereoMode',
371
371
  Mask => 0x1c,
372
- ValueConv => '$val >> 2',
373
372
  PrintConv => {
374
373
  0 => 'Mono',
375
374
  1 => 'Stereo',
@@ -705,7 +704,7 @@ based on unofficial sources which may be incomplete, inaccurate or outdated.
705
704
 
706
705
  =head1 AUTHOR
707
706
 
708
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
707
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
709
708
 
710
709
  This library is free software; you can redistribute it and/or modify it
711
710
  under the same terms as Perl itself.
@@ -15,11 +15,11 @@ use vars qw($VERSION);
15
15
  use Image::ExifTool qw(:DataAccess :Utils);
16
16
  use Image::ExifTool::Exif;
17
17
 
18
- $VERSION = '1.13';
18
+ $VERSION = '1.14';
19
19
 
20
20
  sub ProcessMPImageList($$$);
21
21
 
22
- # Tags found in MPF APP2 segment in JPEG images
22
+ # Tags found in APP2 MPF segment in JPEG images
23
23
  %Image::ExifTool::MPF::Main = (
24
24
  GROUPS => { 0 => 'MPF', 1 => 'MPF0', 2 => 'Image'},
25
25
  NOTES => q{
@@ -105,9 +105,9 @@ sub ProcessMPImageList($$$);
105
105
  Format => 'int32u',
106
106
  Mask => 0xf8000000,
107
107
  PrintConv => { BITMASK => {
108
- 29 => 'Representative image',
109
- 30 => 'Dependent child image',
110
- 31 => 'Dependent parent image',
108
+ 2 => 'Representative image',
109
+ 3 => 'Dependent child image',
110
+ 4 => 'Dependent parent image',
111
111
  }},
112
112
  },
113
113
  0.2 => {
@@ -266,7 +266,7 @@ Format (MPF) information from JPEG images.
266
266
 
267
267
  =head1 AUTHOR
268
268
 
269
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
269
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
270
270
 
271
271
  This library is free software; you can redistribute it and/or modify it
272
272
  under the same terms as Perl itself.
@@ -16,7 +16,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
16
16
  use Image::ExifTool::Exif;
17
17
  use Image::ExifTool::XMP;
18
18
 
19
- $VERSION = '1.21';
19
+ $VERSION = '1.22';
20
20
 
21
21
  sub RecoverTruncatedIPTC($$$);
22
22
  sub ListToString($);
@@ -131,7 +131,7 @@ my $mwgLoaded; # flag set if we alreaded Load()ed the MWG tags
131
131
  # must check for validity in RawConv to avoid hiding a same-named tag,
132
132
  # but IPTC dates use a ValueConv so we need to derive the value there
133
133
  RawConv => q{
134
- (defined $val[0] or defined $val[1] or defined $val[3] or
134
+ (defined $val[0] or defined $val[1] or $val[2] or
135
135
  (defined $val[4] and (not defined $val[5] or not defined $val[6]
136
136
  or $val[5] eq $val[6]))) ? $val : undef
137
137
  },
@@ -171,7 +171,7 @@ my $mwgLoaded; # flag set if we alreaded Load()ed the MWG tags
171
171
  6 => 'IPTCDigest',
172
172
  },
173
173
  RawConv => q{
174
- (defined $val[0] or defined $val[1] or defined $val[3] or
174
+ (defined $val[0] or defined $val[1] or $val[2] or
175
175
  (defined $val[4] and (not defined $val[5] or not defined $val[6]
176
176
  or $val[5] eq $val[6]))) ? $val : undef
177
177
  },
@@ -744,7 +744,7 @@ must be loaded explicitly as described above.
744
744
 
745
745
  =head1 AUTHOR
746
746
 
747
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
747
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
748
748
 
749
749
  This library is free software; you can redistribute it and/or modify it
750
750
  under the same terms as Perl itself.
@@ -2591,7 +2591,7 @@ sub ProcessPrimer($$$)
2591
2591
  next unless $verbose;
2592
2592
  my $indx = $i . ')';
2593
2593
  $indx .= ' ' if length($indx) < 3;
2594
- $et->VPrint(0, sprintf(" | $indx 0x%.4x => '$global'\n", $local));
2594
+ $et->VPrint(0, sprintf(" | $indx 0x%.4x => '${global}'\n", $local));
2595
2595
  }
2596
2596
  return 1;
2597
2597
  }
@@ -2987,7 +2987,7 @@ information from MXF (Material Exchange Format) files.
2987
2987
 
2988
2988
  =head1 AUTHOR
2989
2989
 
2990
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
2990
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
2991
2991
 
2992
2992
  This library is free software; you can redistribute it and/or modify it
2993
2993
  under the same terms as Perl itself.
@@ -11,7 +11,7 @@ use strict;
11
11
  use vars qw($VERSION);
12
12
  use Image::ExifTool qw(:DataAccess :Utils);
13
13
 
14
- $VERSION = '1.01';
14
+ $VERSION = '1.09';
15
15
 
16
16
  sub MDItemLocalTime($);
17
17
 
@@ -20,7 +20,7 @@ my %mdDateInfo = (
20
20
  PrintConv => '$self->ConvertDateTime($val)',
21
21
  );
22
22
 
23
- # "mdls" tags
23
+ # "mdls" tags (ref PH)
24
24
  %Image::ExifTool::MacOS::MDItem = (
25
25
  WRITE_PROC => \&Image::ExifTool::DummyWriteProc,
26
26
  VARS => { NO_ID => 1 },
@@ -29,7 +29,9 @@ my %mdDateInfo = (
29
29
  MDItem tags are extracted using the "mdls" utility. They are extracted if
30
30
  any "MDItem*" tag or the MacOS group is specifically requested, or by
31
31
  setting the L<MDItemTags API option|../ExifTool.html#MDItemTags> to 1 or the L<RequestAll API option|../ExifTool.html#RequestAll> to 2 or
32
- higher.
32
+ higher. Note that these tags do not necessarily reflect the current
33
+ metadata of a file -- it may take some time for the MacOS mdworker daemon to
34
+ index the file after a metadata change.
33
35
  },
34
36
  MDItemFinderComment => {
35
37
  Writable => 1,
@@ -40,8 +42,17 @@ my %mdDateInfo = (
40
42
  Writable => 1,
41
43
  WritePseudo => 1,
42
44
  Protected => 1, # (all writable pseudo tags must be protected)
43
- Notes => 'label number: 0-7',
44
45
  WriteCheck => '$val =~ /^[0-7]$/ ? undef : "Not an integer in the range 0-7"',
46
+ PrintConv => {
47
+ 0 => '0 (none)',
48
+ 1 => '1 (Gray)',
49
+ 2 => '2 (Green)',
50
+ 3 => '3 (Purple)',
51
+ 4 => '4 (Blue)',
52
+ 5 => '5 (Yellow)',
53
+ 6 => '6 (Red)',
54
+ 7 => '7 (Orange)',
55
+ },
45
56
  },
46
57
  MDItemFSCreationDate => {
47
58
  Writable => 1,
@@ -49,19 +60,14 @@ my %mdDateInfo = (
49
60
  DelCheck => q{"Can't delete"},
50
61
  Protected => 1, # (all writable pseudo tags must be protected)
51
62
  Shift => 'Time', # (but not supported yet)
52
- Notes => 'file creation date. Requires "setfile" for writing',
63
+ Notes => q{
64
+ file creation date. Requires "setfile" for writing. Note that when
65
+ reading, it may take a few seconds after writing a file before this value
66
+ reflects the change. However, L<FileCreateDate|Extra.html> is updated immediately
67
+ },
53
68
  Groups => { 2 => 'Time' },
54
69
  ValueConv => \&MDItemLocalTime,
55
- ValueConvInv => sub {
56
- my $val = shift;
57
- # convert to local time if value has a time zone
58
- if ($val =~ /[-+Z]/) {
59
- my $time = Image::ExifTool::GetUnixTime($val, 1);
60
- $val = Image::ExifTool::ConvertUnixTime($time, 1) if $time;
61
- }
62
- $val =~ s{(\d{4}):(\d{2}):(\d{2})}{$2/$3/$1}; # reformat for setfile
63
- return $val;
64
- },
70
+ ValueConvInv => '$val',
65
71
  PrintConv => '$self->ConvertDateTime($val)',
66
72
  PrintConvInv => '$self->InverseDateTime($val)',
67
73
  },
@@ -69,21 +75,30 @@ my %mdDateInfo = (
69
75
  MDItemAcquisitionModel => { Groups => { 2 => 'Camera' } },
70
76
  MDItemAltitude => { Groups => { 2 => 'Location' } },
71
77
  MDItemAperture => { Groups => { 2 => 'Camera' } },
78
+ MDItemAudioBitRate => { Groups => { 2 => 'Audio' } },
79
+ MDItemAudioChannelCount => { Groups => { 2 => 'Audio' } },
72
80
  MDItemAuthors => { Groups => { 2 => 'Author' } },
73
81
  MDItemBitsPerSample => { Groups => { 2 => 'Image' } },
82
+ MDItemCity => { Groups => { 2 => 'Location' } },
83
+ MDItemCodecs => { },
74
84
  MDItemColorSpace => { Groups => { 2 => 'Image' } },
75
85
  MDItemComment => { },
76
86
  MDItemContentCreationDate => { Groups => { 2 => 'Time' }, %mdDateInfo },
87
+ MDItemContentCreationDateRanking => { Groups => { 2 => 'Time' }, %mdDateInfo },
77
88
  MDItemContentModificationDate => { Groups => { 2 => 'Time' }, %mdDateInfo },
78
89
  MDItemContentType => { },
79
90
  MDItemContentTypeTree => { },
91
+ MDItemContributors => { },
92
+ MDItemCopyright => { Groups => { 2 => 'Author' } },
93
+ MDItemCountry => { Groups => { 2 => 'Location' } },
80
94
  MDItemCreator => { Groups => { 2 => 'Document' } },
81
95
  MDItemDateAdded => { Groups => { 2 => 'Time' }, %mdDateInfo },
82
96
  MDItemDescription => { },
83
97
  MDItemDisplayName => { },
84
98
  MDItemDownloadedDate => { Groups => { 2 => 'Time' }, %mdDateInfo },
99
+ MDItemDurationSeconds => { PrintConv => 'ConvertDuration($val)' },
85
100
  MDItemEncodingApplications => { },
86
- MDItemEXIFGPSVersion => { Groups => { 2 => 'Location' } },
101
+ MDItemEXIFGPSVersion => { Groups => { 2 => 'Location' }, Description => 'MD Item EXIF GPS Version' },
87
102
  MDItemEXIFVersion => { },
88
103
  MDItemExposureMode => { Groups => { 2 => 'Camera' } },
89
104
  MDItemExposureProgram => { Groups => { 2 => 'Camera' } },
@@ -109,13 +124,17 @@ my %mdDateInfo = (
109
124
  MDItemGPSTrack => { Groups => { 2 => 'Location' } },
110
125
  MDItemHasAlphaChannel => { Groups => { 2 => 'Image' } },
111
126
  MDItemImageDirection => { Groups => { 2 => 'Location' } },
127
+ MDItemInterestingDateRanking => { Groups => { 2 => 'Time' }, %mdDateInfo },
112
128
  MDItemISOSpeed => { Groups => { 2 => 'Camera' } },
113
129
  MDItemKeywords => { },
114
130
  MDItemKind => { },
115
131
  MDItemLastUsedDate => { Groups => { 2 => 'Time' }, %mdDateInfo },
132
+ MDItemLastUsedDate_Ranking => { },
116
133
  MDItemLatitude => { Groups => { 2 => 'Location' } },
134
+ MDItemLensModel => { },
117
135
  MDItemLogicalSize => { },
118
136
  MDItemLongitude => { Groups => { 2 => 'Location' } },
137
+ MDItemMediaTypes => { },
119
138
  MDItemNumberOfPages => { },
120
139
  MDItemOrientation => { Groups => { 2 => 'Image' } },
121
140
  MDItemOriginApplicationIdentifier => { },
@@ -135,13 +154,62 @@ my %mdDateInfo = (
135
154
  MDItemResolutionWidthDPI => { Groups => { 2 => 'Image' } },
136
155
  MDItemSecurityMethod => { },
137
156
  MDItemSpeed => { Groups => { 2 => 'Location' } },
157
+ MDItemStateOrProvince => { Groups => { 2 => 'Location' } },
158
+ MDItemStreamable => { },
138
159
  MDItemTimestamp => { Groups => { 2 => 'Time' } }, # (time only)
139
160
  MDItemTitle => { },
161
+ MDItemTotalBitRate => { },
140
162
  MDItemUseCount => { },
141
163
  MDItemUsedDates => { Groups => { 2 => 'Time' }, %mdDateInfo },
164
+ MDItemUserDownloadedDate => { Groups => { 2 => 'Time' }, %mdDateInfo },
165
+ MDItemUserDownloadedUserHandle=> { },
166
+ MDItemUserSharedReceivedDate => { },
167
+ MDItemUserSharedReceivedRecipient => { },
168
+ MDItemUserSharedReceivedRecipientHandle => { },
169
+ MDItemUserSharedReceivedSender=> { },
170
+ MDItemUserSharedReceivedSenderHandle => { },
171
+ MDItemUserSharedReceivedTransport => { },
172
+ MDItemUserTags => {
173
+ List => 1,
174
+ Writable => 1,
175
+ WritePseudo => 1,
176
+ Protected => 1, # (all writable pseudo tags must be protected)
177
+ Notes => q{
178
+ requires "tag" utility for writing -- install with "brew install tag". Note
179
+ that user tags may not contain a comma, and that duplicate user tags will
180
+ not be written
181
+ },
182
+ },
142
183
  MDItemVersion => { },
184
+ MDItemVideoBitRate => { Groups => { 2 => 'Video' } },
143
185
  MDItemWhereFroms => { },
144
186
  MDItemWhiteBalance => { Groups => { 2 => 'Image' } },
187
+ # tags used by Apple Mail on .emlx files
188
+ com_apple_mail_dateReceived => { Name => 'AppleMailDateReceived', Groups => { 2 => 'Time' }, %mdDateInfo },
189
+ com_apple_mail_dateSent => { Name => 'AppleMailDateSent', Groups => { 2 => 'Time' }, %mdDateInfo },
190
+ com_apple_mail_flagged => { Name => 'AppleMailFlagged' },
191
+ com_apple_mail_messageID => { Name => 'AppleMailMessageID' },
192
+ com_apple_mail_priority => { Name => 'AppleMailPriority' },
193
+ com_apple_mail_read => { Name => 'AppleMailRead' },
194
+ com_apple_mail_repliedTo => { Name => 'AppleMailRepliedTo' },
195
+ com_apple_mail_isRemoteAttachment => { Name => 'AppleMailIsRemoteAttachment' },
196
+ MDItemAccountHandles => { },
197
+ MDItemAccountIdentifier => { },
198
+ MDItemAuthorEmailAddresses => { },
199
+ MDItemBundleIdentifier => { },
200
+ MDItemContentCreationDate_Ranking=>{Groups=> { 2 => 'Time' }, %mdDateInfo },
201
+ MDItemDateAdded_Ranking => { Groups => { 2 => 'Time' }, %mdDateInfo },
202
+ MDItemEmailConversationID => { },
203
+ MDItemIdentifier => { },
204
+ MDItemInterestingDate_Ranking => { Groups => { 2 => 'Time' }, %mdDateInfo },
205
+ MDItemIsApplicationManaged => { },
206
+ MDItemIsExistingThread => { },
207
+ MDItemIsLikelyJunk => { },
208
+ MDItemMailboxes => { },
209
+ MDItemMailDateReceived_Ranking=> { Groups => { 2 => 'Time' }, %mdDateInfo },
210
+ MDItemPrimaryRecipientEmailAddresses => { },
211
+ MDItemRecipients => { },
212
+ MDItemSubject => { },
145
213
  );
146
214
 
147
215
  # "xattr" tags
@@ -160,7 +228,7 @@ my %mdDateInfo = (
160
228
  # ref https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-9A581/Finder.h
161
229
  ValueConv => q{
162
230
  my @a = unpack('a4a4n3x10nx2N', $$val);
163
- tr/\0//d, $_="'$_'" foreach @a[0,1];
231
+ tr/\0//d, $_="'${_}'" foreach @a[0,1];
164
232
  return "@a";
165
233
  },
166
234
  PrintConv => q{
@@ -200,15 +268,27 @@ my %mdDateInfo = (
200
268
  quarantine information for files downloaded from the internet. May only be
201
269
  deleted when writing
202
270
  },
271
+ # ($a[1] is the time when the quarantine tag was set)
203
272
  PrintConv => q{
204
273
  my @a = split /;/, $val;
205
274
  $a[0] = 'Flags=' . $a[0];
206
- $a[1] = 'downloaded at ' . ConvertUnixTime(hex $a[1]);
275
+ $a[1] = 'set at ' . ConvertUnixTime(hex $a[1]);
207
276
  $a[2] = 'by ' . $a[2];
208
277
  return join ' ', @a;
209
278
  },
210
279
  PrintConvInv => '$val',
211
280
  },
281
+ 'com.apple.metadata:com_apple_mail_dateReceived' => {
282
+ Name => 'XAttrAppleMailDateReceived',
283
+ Groups => { 2 => 'Time' },
284
+ },
285
+ 'com.apple.metadata:com_apple_mail_dateSent' => {
286
+ Name => 'XAttrAppleMailDateSent',
287
+ Groups => { 2 => 'Time' },
288
+ },
289
+ 'com.apple.metadata:com_apple_mail_isRemoteAttachment' => {
290
+ Name => 'XAttrAppleMailIsRemoteAttachment',
291
+ },
212
292
  'com.apple.metadata:kMDItemDownloadedDate' => {
213
293
  Name => 'XAttrMDItemDownloadedDate',
214
294
  Groups => { 2 => 'Time' },
@@ -217,6 +297,13 @@ my %mdDateInfo = (
217
297
  'com.apple.metadata:kMDItemWhereFroms' => { Name => 'XAttrMDItemWhereFroms' },
218
298
  'com.apple.metadata:kMDLabel' => { Name => 'XAttrMDLabel', Binary => 1 },
219
299
  'com.apple.ResourceFork' => { Name => 'XAttrResourceFork', Binary => 1 },
300
+ 'com.apple.lastuseddate#PS' => {
301
+ Name => 'XAttrLastUsedDate',
302
+ Groups => { 2 => 'Time' },
303
+ # (first 4 bytes are date/time. Not sure what remaining 12 bytes are for)
304
+ RawConv => 'ConvertUnixTime(unpack("V",$$val))',
305
+ PrintConv => '$self->ConvertDateTime($val)',
306
+ },
220
307
  );
221
308
 
222
309
  #------------------------------------------------------------------------------
@@ -248,24 +335,58 @@ sub SetMacOSTags($$$)
248
335
  my $tag;
249
336
 
250
337
  foreach $tag (@$setTags) {
251
- my ($nvHash, $f, $v, $attr, $cmd, $silentErr);
338
+ my ($nvHash, $f, $v, $attr, $cmd, $err, $silentErr);
252
339
  my $val = $et->GetNewValue($tag, \$nvHash);
253
340
  next unless $nvHash;
254
- my $overwrite = $et->IsOverwriting($nvHash) or next;
255
- if ($overwrite < 0) {
256
- my $operation = $$nvHash{Shift} ? 'Shifting' : 'Conditional replacement';
257
- $et->Warn("$operation of $tag not yet supported");
258
- next;
341
+ my $overwrite = $et->IsOverwriting($nvHash);
342
+ unless ($$nvHash{TagInfo}{List}) {
343
+ next unless $overwrite;
344
+ if ($overwrite < 0) {
345
+ my $operation = $$nvHash{Shift} ? 'Shifting' : 'Conditional replacement';
346
+ $et->Warn("$operation of $tag not yet supported");
347
+ next;
348
+ }
259
349
  }
260
- if ($tag eq 'MDItemFSCreationDate') {
350
+ if ($tag eq 'MDItemFSCreationDate' or $tag eq 'FileCreateDate') {
351
+ ($f = $file) =~ s/'/'\\''/g;
352
+ # convert to local time if value has a time zone
353
+ if ($val =~ /[-+Z]/) {
354
+ my $time = Image::ExifTool::GetUnixTime($val, 1);
355
+ $val = Image::ExifTool::ConvertUnixTime($time, 1) if $time;
356
+ }
357
+ $val =~ s{(\d{4}):(\d{2}):(\d{2})}{$2/$3/$1}; # reformat for setfile
358
+ $cmd = "setfile -d '${val}' '${f}'";
359
+ } elsif ($tag eq 'MDItemUserTags') {
360
+ # (tested with "tag" version 0.9.0)
261
361
  ($f = $file) =~ s/'/'\\''/g;
262
- $cmd = "setfile -d '$val' '$f'";
362
+ my @vals = $et->GetNewValue($nvHash);
363
+ if ($overwrite < 0 and @{$$nvHash{DelValue}}) {
364
+ # delete specified tags
365
+ my @dels = @{$$nvHash{DelValue}};
366
+ s/'/'\\''/g foreach @dels;
367
+ my $del = join ',', @dels;
368
+ $err = system "tag -r '${del}' '${f}'>/dev/null 2>&1";
369
+ unless ($err) {
370
+ $et->VerboseValue("- $tag", $del);
371
+ $result = 1;
372
+ undef $err if @vals; # more to do if there are tags to add
373
+ }
374
+ }
375
+ unless (defined $err) {
376
+ # add new tags, or overwrite or delete existing tags
377
+ s/'/'\\''/g foreach @vals;
378
+ my $opt = $overwrite > 0 ? '-s' : '-a';
379
+ $val = @vals ? join(',', @vals) : '';
380
+ $cmd = "tag $opt '${val}' '${f}'";
381
+ $et->VPrint(1," - $tag = (all)\n") if $overwrite > 0;
382
+ undef $val if $val eq '';
383
+ }
263
384
  } elsif ($tag eq 'XAttrQuarantine') {
264
385
  ($f = $file) =~ s/'/'\\''/g;
265
- $cmd = "xattr -d com.apple.quarantine '$f'";
386
+ $cmd = "xattr -d com.apple.quarantine '${f}'";
266
387
  $silentErr = 256; # (will get this error if attribute doesn't exist)
267
388
  } else {
268
- ($f = $file) =~ s/(["\\])/\\$1/g; # escape necessary characters
389
+ ($f = $file) =~ s/(["\\])/\\$1/g; # escape necessary characters for script
269
390
  $f =~ s/'/'"'"'/g;
270
391
  if ($tag eq 'MDItemFinderComment') {
271
392
  # (write finder comment using osascript instead of xattr
@@ -282,9 +403,11 @@ sub SetMacOSTags($$$)
282
403
  $cmd = qq(osascript -e 'set fp to POSIX file "$f" as alias' -e \\
283
404
  'tell application "Finder" to set $attr of file fp to "$v"');
284
405
  }
285
- my $err = system $cmd . '>/dev/null 2>&1'; # (pipe all output to /dev/null)
406
+ if (defined $cmd) {
407
+ $err = system $cmd . '>/dev/null 2>&1'; # (pipe all output to /dev/null)
408
+ }
286
409
  if (not $err) {
287
- $et->VerboseValue("+ $tag", $val);
410
+ $et->VerboseValue("+ $tag", $val) if defined $val;
288
411
  $result = 1;
289
412
  } elsif (not $silentErr or $err != $silentErr) {
290
413
  $cmd =~ s/ .*//s;
@@ -302,7 +425,7 @@ sub ExtractMDItemTags($$)
302
425
  {
303
426
  local $_;
304
427
  my ($et, $file) = @_;
305
- my ($fn, $tag, $val);
428
+ my ($fn, $tag, $val, $tmp);
306
429
 
307
430
  ($fn = $file) =~ s/([`"\$\\])/\\$1/g; # escape necessary characters
308
431
  $et->VPrint(0, '(running mdls)');
@@ -332,6 +455,7 @@ sub ExtractMDItemTags($$)
332
455
  s/,$//; # remove trailing comma
333
456
  $_ = '' if $_ eq '(null)';
334
457
  s/^"// and s/"$//; # remove quotes if they exist
458
+ s/\\"/"/g; # un-escape quotes
335
459
  $_ = $et->Decode($_, 'UTF8');
336
460
  push @$val, $_;
337
461
  next;
@@ -345,7 +469,10 @@ sub ExtractMDItemTags($$)
345
469
  ValueConv => \&MDItemLocalTime,
346
470
  PrintConv => '$self->ConvertDateTime($val)',
347
471
  ) if /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/;
348
- $tagInfo{Name} = Image::ExifTool::MakeTagName($tag);
472
+ # change tags like "com_apple_mail_xxx" to "AppleMailXxx"
473
+ ($tmp = $tag) =~ s/^com_//; # remove leading "com_"
474
+ $tmp =~ s/_([a-z])/\u$1/g; # use CamelCase
475
+ $tagInfo{Name} = Image::ExifTool::MakeTagName($tmp);
349
476
  $tagInfo{List} = 1 if ref $val eq 'ARRAY';
350
477
  $tagInfo{Groups}{2} = 'Audio' if $tag =~ /Audio/;
351
478
  $tagInfo{Groups}{2} = 'Author' if $tag =~ /(Copyright|Author)/;
@@ -396,9 +523,11 @@ sub ExtractXAttrTags($$)
396
523
  # generate tag name from attribute name
397
524
  if ($tag =~ /^com\.apple\.(.*)$/) {
398
525
  ($name = $1) =~ s/^metadata:_?k//;
526
+ $name =~ s/^metadata:(com_)?//;
399
527
  } else {
400
- ($name = $tag) =~ s/[.:]([a-z])/\U$1/g;
528
+ $name = $tag;
401
529
  }
530
+ $name =~ s/[.:_]([a-z])/\U$1/g;
402
531
  $name = 'XAttr' . ucfirst $name;
403
532
  my %tagInfo = ( Name => $name );
404
533
  $tagInfo{Groups} = { 2 => 'Time' } if $tag=~/Date$/;
@@ -434,6 +563,27 @@ sub ExtractXAttrTags($$)
434
563
  $$et{INDENT} =~ s/\| $//;
435
564
  }
436
565
 
566
+ #------------------------------------------------------------------------------
567
+ # Extract MacOS file creation date/time
568
+ # Inputs: 0) ExifTool object ref, 1) file name
569
+ sub GetFileCreateDate($$)
570
+ {
571
+ local $_;
572
+ my ($et, $file) = @_;
573
+ my ($fn, $tag, $val, $tmp);
574
+
575
+ ($fn = $file) =~ s/([`"\$\\])/\\$1/g; # escape necessary characters
576
+ $et->VPrint(0, '(running stat)');
577
+ my $time = `stat -f '%SB' -t '%Y:%m:%d %H:%M:%S%z' "$fn" 2> /dev/null`;
578
+ if ($? or not $time or $time !~ s/([-+]\d{2})(\d{2})\s*$/$1:$2/) {
579
+ $et->Warn('Error running "stat" to extract FileCreateDate');
580
+ return;
581
+ }
582
+ $$et{SET_GROUP1} = 'MacOS';
583
+ $et->FoundTag(FileCreateDate => $time);
584
+ delete $$et{SET_GROUP1};
585
+ }
586
+
437
587
  1; # end
438
588
 
439
589
  __END__
@@ -455,7 +605,7 @@ for writing.
455
605
 
456
606
  =head1 AUTHOR
457
607
 
458
- Copyright 2003-2017, Phil Harvey (phil at owl.phy.queensu.ca)
608
+ Copyright 2003-2019, Phil Harvey (phil at owl.phy.queensu.ca)
459
609
 
460
610
  This library is free software; you can redistribute it and/or modify it
461
611
  under the same terms as Perl itself.