exiftool_vendored 12.42.0 → 12.52.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +226 -6
  3. data/bin/MANIFEST +14 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +45 -44
  7. data/bin/config_files/acdsee.config +2 -1
  8. data/bin/config_files/frameCount.config +56 -0
  9. data/bin/config_files/tiff_version.config +1 -1
  10. data/bin/exiftool +116 -97
  11. data/bin/fmt_files/gpx.fmt +3 -0
  12. data/bin/fmt_files/gpx_wpt.fmt +3 -0
  13. data/bin/lib/Image/ExifTool/Apple.pm +16 -3
  14. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +23 -12
  15. data/bin/lib/Image/ExifTool/Canon.pm +66 -37
  16. data/bin/lib/Image/ExifTool/CanonRaw.pm +8 -1
  17. data/bin/lib/Image/ExifTool/CanonVRD.pm +7 -8
  18. data/bin/lib/Image/ExifTool/Casio.pm +3 -3
  19. data/bin/lib/Image/ExifTool/DJI.pm +2 -1
  20. data/bin/lib/Image/ExifTool/DarwinCore.pm +13 -1
  21. data/bin/lib/Image/ExifTool/EXE.pm +9 -1
  22. data/bin/lib/Image/ExifTool/Exif.pm +17 -12
  23. data/bin/lib/Image/ExifTool/FLAC.pm +17 -3
  24. data/bin/lib/Image/ExifTool/FLIR.pm +9 -7
  25. data/bin/lib/Image/ExifTool/FlashPix.pm +26 -3
  26. data/bin/lib/Image/ExifTool/FujiFilm.pm +51 -4
  27. data/bin/lib/Image/ExifTool/GPS.pm +31 -5
  28. data/bin/lib/Image/ExifTool/Geotag.pm +36 -8
  29. data/bin/lib/Image/ExifTool/ICC_Profile.pm +3 -2
  30. data/bin/lib/Image/ExifTool/ICO.pm +143 -0
  31. data/bin/lib/Image/ExifTool/ID3.pm +6 -6
  32. data/bin/lib/Image/ExifTool/IPTC.pm +5 -1
  33. data/bin/lib/Image/ExifTool/JPEG.pm +1 -0
  34. data/bin/lib/Image/ExifTool/Jpeg2000.pm +24 -3
  35. data/bin/lib/Image/ExifTool/LNK.pm +5 -2
  36. data/bin/lib/Image/ExifTool/Lang/de.pm +1 -1
  37. data/bin/lib/Image/ExifTool/Lang/fr.pm +6015 -759
  38. data/bin/lib/Image/ExifTool/Lang/sk.pm +1927 -0
  39. data/bin/lib/Image/ExifTool/M2TS.pm +98 -8
  40. data/bin/lib/Image/ExifTool/MIE.pm +9 -3
  41. data/bin/lib/Image/ExifTool/MISB.pm +494 -0
  42. data/bin/lib/Image/ExifTool/MakerNotes.pm +3 -1
  43. data/bin/lib/Image/ExifTool/Matroska.pm +272 -48
  44. data/bin/lib/Image/ExifTool/Motorola.pm +8 -2
  45. data/bin/lib/Image/ExifTool/Nikon.pm +746 -382
  46. data/bin/lib/Image/ExifTool/NikonCustom.pm +139 -106
  47. data/bin/lib/Image/ExifTool/NikonSettings.pm +5 -3
  48. data/bin/lib/Image/ExifTool/Olympus.pm +6 -4
  49. data/bin/lib/Image/ExifTool/PNG.pm +8 -1
  50. data/bin/lib/Image/ExifTool/Panasonic.pm +21 -4
  51. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +25 -5
  52. data/bin/lib/Image/ExifTool/Parrot.pm +96 -2
  53. data/bin/lib/Image/ExifTool/Pentax.pm +7 -2
  54. data/bin/lib/Image/ExifTool/Photoshop.pm +29 -3
  55. data/bin/lib/Image/ExifTool/QuickTime.pm +166 -13
  56. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +161 -22
  57. data/bin/lib/Image/ExifTool/README +15 -4
  58. data/bin/lib/Image/ExifTool/RIFF.pm +106 -9
  59. data/bin/lib/Image/ExifTool/Samsung.pm +2 -2
  60. data/bin/lib/Image/ExifTool/Sigma.pm +27 -1
  61. data/bin/lib/Image/ExifTool/SigmaRaw.pm +37 -13
  62. data/bin/lib/Image/ExifTool/Sony.pm +75 -47
  63. data/bin/lib/Image/ExifTool/TagInfoXML.pm +13 -6
  64. data/bin/lib/Image/ExifTool/TagLookup.pm +4791 -4519
  65. data/bin/lib/Image/ExifTool/TagNames.pod +2056 -1446
  66. data/bin/lib/Image/ExifTool/Text.pm +3 -4
  67. data/bin/lib/Image/ExifTool/Torrent.pm +2 -3
  68. data/bin/lib/Image/ExifTool/Validate.pm +3 -3
  69. data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +7 -0
  70. data/bin/lib/Image/ExifTool/WriteExif.pl +100 -23
  71. data/bin/lib/Image/ExifTool/WriteIPTC.pl +2 -6
  72. data/bin/lib/Image/ExifTool/WritePhotoshop.pl +5 -5
  73. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +12 -7
  74. data/bin/lib/Image/ExifTool/WriteRIFF.pl +359 -0
  75. data/bin/lib/Image/ExifTool/WriteXMP.pl +15 -1
  76. data/bin/lib/Image/ExifTool/Writer.pl +46 -18
  77. data/bin/lib/Image/ExifTool/XMP.pm +78 -59
  78. data/bin/lib/Image/ExifTool/XMP2.pl +19 -4
  79. data/bin/lib/Image/ExifTool/ZIP.pm +19 -7
  80. data/bin/lib/Image/ExifTool.pm +146 -38
  81. data/bin/lib/Image/ExifTool.pod +83 -69
  82. data/bin/perl-Image-ExifTool.spec +43 -43
  83. data/lib/exiftool_vendored/version.rb +1 -1
  84. metadata +10 -4
@@ -29,7 +29,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
29
29
  %jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
30
30
  %static_vars);
31
31
 
32
- $VERSION = '12.42';
32
+ $VERSION = '12.52';
33
33
  $RELEASE = '';
34
34
  @ISA = qw(Exporter);
35
35
  %EXPORT_TAGS = (
@@ -139,22 +139,22 @@ sub ReadValue($$$;$$$);
139
139
  @loadAllTables = qw(
140
140
  PhotoMechanic Exif GeoTiff CanonRaw KyoceraRaw Lytro MinoltaRaw PanasonicRaw
141
141
  SigmaRaw JPEG GIMP Jpeg2000 GIF BMP BMP::OS2 BMP::Extra BPG BPG::Extensions
142
- PICT PNG MNG FLIF DjVu DPX OpenEXR ZISRAW MRC LIF MRC::FEI12 MIFF PCX PGF
143
- PSP PhotoCD Radiance Other::PFM PDF PostScript Photoshop::Header
142
+ ICO PICT PNG MNG FLIF DjVu DPX OpenEXR ZISRAW MRC LIF MRC::FEI12 MIFF PCX
143
+ PGF PSP PhotoCD Radiance Other::PFM PDF PostScript Photoshop::Header
144
144
  Photoshop::Layers Photoshop::ImageData FujiFilm::RAF FujiFilm::IFD
145
145
  Samsung::Trailer Sony::SRF2 Sony::SR2SubIFD Sony::PMP ITC ID3 ID3::Lyrics3
146
146
  FLAC Ogg Vorbis APE APE::NewHeader APE::OldHeader Audible MPC MPEG::Audio
147
147
  MPEG::Video MPEG::Xing M2TS QuickTime QuickTime::ImageFile QuickTime::Stream
148
- QuickTime::Tags360Fly Matroska MOI MXF DV Flash Flash::FLV Real::Media
149
- Real::Audio Real::Metafile Red RIFF AIFF ASF WTV DICOM FITS MIE JSON HTML
150
- XMP::SVG Palm Palm::MOBI Palm::EXTH Torrent EXE EXE::PEVersion EXE::PEString
151
- EXE::MachO EXE::PEF EXE::ELF EXE::AR EXE::CHM LNK Font VCard Text
152
- VCard::VCalendar RSRC Rawzor ZIP ZIP::GZIP ZIP::RAR RTF OOXML iWork ISO
148
+ QuickTime::Tags360Fly Matroska Matroska::Tags MOI MXF DV Flash Flash::FLV
149
+ Real::Media Real::Audio Real::Metafile Red RIFF AIFF ASF WTV DICOM FITS MIE
150
+ JSON HTML XMP::SVG Palm Palm::MOBI Palm::EXTH Torrent EXE EXE::PEVersion
151
+ EXE::PEString EXE::MachO EXE::PEF EXE::ELF EXE::AR EXE::CHM LNK Font VCard
152
+ Text VCard::VCalendar RSRC Rawzor ZIP ZIP::GZIP ZIP::RAR RTF OOXML iWork ISO
153
153
  FLIR::AFF FLIR::FPF MacOS MacOS::MDItem FlashPix::DocTable
154
154
  );
155
155
 
156
156
  # alphabetical list of current Lang modules
157
- @langs = qw(cs de en en_ca en_gb es fi fr it ja ko nl pl ru sv tr zh_cn zh_tw);
157
+ @langs = qw(cs de en en_ca en_gb es fi fr it ja ko nl pl ru sk sv tr zh_cn zh_tw);
158
158
 
159
159
  $defaultLang = 'en'; # default language
160
160
 
@@ -174,6 +174,7 @@ $defaultLang = 'en'; # default language
174
174
  nl => 'Dutch (Nederlands)',
175
175
  pl => 'Polish (Polski)',
176
176
  ru => 'Russian (Русский)',
177
+ sk => 'Slovak (Slovenčina)',
177
178
  sv => 'Swedish (Svenska)',
178
179
  'tr'=> 'Turkish (Türkçe)',
179
180
  zh_cn => 'Simplified Chinese (简体中文)',
@@ -191,11 +192,12 @@ $defaultLang = 'en'; # default language
191
192
  HTML VRD RTF FITS XCF DSS QTIF FPX PICT ZIP GZIP PLIST RAR BZ2
192
193
  CZI TAR EXE EXR HDR CHM LNK WMF AVC DEX DPX RAW Font RSRC M2TS
193
194
  MacOS PHP PCX DCX DWF DWG DXF WTV Torrent VCard LRI R3D AA PDB
194
- PFM2 MRC LIF JXL MOI ISO ALIAS JSON MP3 DICOM PCD TXT);
195
+ PFM2 MRC LIF JXL MOI ISO ALIAS JSON MP3 DICOM PCD ICO TXT);
195
196
 
196
197
  # file types that we can write (edit)
197
198
  my @writeTypes = qw(JPEG TIFF GIF CRW MRW ORF RAF RAW PNG MIE PSD XMP PPM EPS
198
- X3F PS PDF ICC VRD DR4 JP2 JXL EXIF AI AIT IND MOV EXV FLIF);
199
+ X3F PS PDF ICC VRD DR4 JP2 JXL EXIF AI AIT IND MOV EXV FLIF
200
+ RIFF);
199
201
  my %writeTypes; # lookup for writable file types (hash filled if required)
200
202
 
201
203
  # file extensions that we can't write for various base types
@@ -205,6 +207,8 @@ my %writeTypes; # lookup for writable file types (hash filled if required)
205
207
  JP2 => [ qw(J2C JPC) ],
206
208
  MOV => [ qw(INSV) ],
207
209
  );
210
+ # file extensions that we can only write for various base types
211
+ my %onlyWriteFile = ( RIFF => [ qw(WEBP) ] );
208
212
 
209
213
  # file types that we can create from scratch
210
214
  # - must update CanCreate() documentation if this list is changed!
@@ -257,6 +261,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
257
261
  CRW => ['CRW', 'Canon RAW format'],
258
262
  CS1 => ['PSD', 'Sinar CaptureShop 1-Shot RAW'],
259
263
  CSV => ['TXT', 'Comma-Separated Values'],
264
+ CUR => ['ICO', 'Windows Cursor'],
260
265
  CZI => ['CZI', 'Zeiss Integrated Software RAW'],
261
266
  DC3 => 'DICM',
262
267
  DCM => 'DICM',
@@ -333,6 +338,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
333
338
  ICAL => 'ICS',
334
339
  ICC => ['ICC', 'International Color Consortium'],
335
340
  ICM => 'ICC',
341
+ ICO => ['ICO', 'Windows Icon'],
336
342
  ICS => ['VCard','iCalendar Schedule'],
337
343
  IDML => ['ZIP', 'Adobe InDesign Markup Language'],
338
344
  IIQ => ['TIFF', 'Phase One Intelligent Image Quality RAW'],
@@ -378,6 +384,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
378
384
  M4B => ['MOV', 'MPEG-4 audio Book'],
379
385
  M4P => ['MOV', 'MPEG-4 Protected'],
380
386
  M4V => ['MOV', 'MPEG-4 Video'],
387
+ MACOS=> ['MacOS','MacOS ._ sidecar file'],
381
388
  MAX => ['FPX', '3D Studio MAX'],
382
389
  MEF => ['TIFF', 'Mamiya (RAW) Electronic Format'],
383
390
  MIE => ['MIE', 'Meta Information Encapsulation format'],
@@ -407,7 +414,6 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
407
414
  NEF => ['TIFF', 'Nikon (RAW) Electronic Format'],
408
415
  NEWER => 'COS',
409
416
  NKSC => ['XMP', 'Nikon Sidecar'],
410
-
411
417
  NMBTEMPLATE => ['ZIP','Apple Numbers Template'],
412
418
  NRW => ['TIFF', 'Nikon RAW (2)'],
413
419
  NUMBERS => ['ZIP','Apple Numbers spreadsheet'],
@@ -530,7 +536,6 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
530
536
  WMV => ['ASF', 'Windows Media Video'],
531
537
  WV => ['RIFF', 'WavePack lossless audio'],
532
538
  X3F => ['X3F', 'Sigma RAW format'],
533
- MACOS=> ['MacOS','MacOS ._ sidecar file'],
534
539
  XCF => ['XCF', 'GIMP native image format'],
535
540
  XHTML=> ['HTML', 'Extensible HyperText Markup Language'],
536
541
  XLA => ['FPX', 'Microsoft Excel Add-in'],
@@ -599,6 +604,7 @@ my %fileDescription = (
599
604
  CRM => 'video/x-canon-crm',
600
605
  CRW => 'image/x-canon-crw',
601
606
  CSV => 'text/csv',
607
+ CUR => 'image/x-cursor', #PH (NC)
602
608
  CZI => 'image/x-zeiss-czi', #PH (NC)
603
609
  DCP => 'application/octet-stream', #PH (NC)
604
610
  DCR => 'image/x-kodak-dcr',
@@ -647,6 +653,7 @@ my %fileDescription = (
647
653
  HDR => 'image/vnd.radiance',
648
654
  HTML => 'text/html',
649
655
  ICC => 'application/vnd.iccprofile',
656
+ ICO => 'image/x-icon', #PH (NC)
650
657
  ICS => 'text/calendar',
651
658
  IDML => 'application/vnd.adobe.indesign-idml-package',
652
659
  IIQ => 'image/x-raw',
@@ -913,6 +920,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
913
920
  HDR => '#\?(RADIANCE|RGBE)\x0a',
914
921
  HTML => '(\xef\xbb\xbf)?\s*(?i)<(!DOCTYPE\s+HTML|HTML|\?xml)', # (case insensitive)
915
922
  ICC => '.{12}(scnr|mntr|prtr|link|spac|abst|nmcl|nkpf|cenc|mid |mlnk|mvis)(XYZ |Lab |Luv |YCbr|Yxy |RGB |GRAY|HSV |HLS |CMYK|CMY |[2-9A-F]CLR|nc..|\0{4}){2}',
923
+ ICO => '\0\0[\x01\x02]\0[^0]\0', # (reasonably assume that the file contains less than 256 images)
916
924
  IND => '\x06\x06\xed\xf5\xd8\x1d\x46\xe5\xbd\x31\xef\xe7\xfe\x74\xb7\x1d',
917
925
  # ISO => signature is at byte 32768
918
926
  ITC => '.{4}itch',
@@ -925,6 +933,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
925
933
  LNK => '.{4}\x01\x14\x02\0{5}\xc0\0{6}\x46',
926
934
  LRI => 'LELR \0',
927
935
  M2TS => '(....)?\x47',
936
+ MacOS=> '\0\x05\x16\x07\0.\0\0Mac OS X ',
928
937
  MIE => '~[\x10\x18]\x04.0MIE',
929
938
  MIFF => 'id=ImageMagick',
930
939
  MKV => '\x1a\x45\xdf\xa3',
@@ -972,7 +981,6 @@ $testLen = 1024; # number of bytes to read when testing for magic number
972
981
  WMF => '(\xd7\xcd\xc6\x9a\0\0|\x01\0\x09\0\0\x03)',
973
982
  WTV => '\xb7\xd8\x00\x20\x37\x49\xda\x11\xa6\x4e\x00\x07\xe9\x5e\xad\x8d',
974
983
  X3F => 'FOVb',
975
- MacOS=> '\0\x05\x16\x07\0.\0\0Mac OS X ',
976
984
  XCF => 'gimp xcf ',
977
985
  XMP => '\0{0,3}(\xfe\xff|\xff\xfe|\xef\xbb\xbf)?\0{0,3}\s*<',
978
986
  ZIP => 'PK\x03\x04',
@@ -1800,6 +1808,16 @@ my %systemTagsNotes = (
1800
1808
  Protected => 1,
1801
1809
  },
1802
1810
  PageCount => { Notes => 'the number of pages in a multi-page TIFF document' },
1811
+ SphericalVideoXML => {
1812
+ Groups => { 0 => 'QuickTime', 1 => 'GSpherical', 2 => 'Video' },
1813
+ # (group 1 is 'GSpherical' to trigger creation of this tag when writing,
1814
+ # but when reading the family 1 group is the track number)
1815
+ Flags => [ 'Writable', 'Binary', 'Protected' ],
1816
+ Notes => q{
1817
+ the SphericalVideoXML block from MP4/MOV videos. This tag is generated only
1818
+ if specifically requested
1819
+ },
1820
+ },
1803
1821
  );
1804
1822
 
1805
1823
  # tags defined by UserParam option (added at runtime)
@@ -2022,6 +2040,7 @@ sub new
2022
2040
  $$self{DEL_GROUP} = { }; # lookup for groups to delete when writing
2023
2041
  $$self{SAVE_COUNT} = 0; # count calls to SaveNewValues()
2024
2042
  $$self{FILE_SEQUENCE} = 0; # sequence number for files when reading
2043
+ $$self{INDENT2} = ''; # indentation of verbose messages from SetNewValue
2025
2044
 
2026
2045
  # initialize our new groups for writing
2027
2046
  $self->SetNewGroups(@defaultWriteGroups);
@@ -2209,6 +2228,20 @@ sub Options($$;@)
2209
2228
  } else {
2210
2229
  $$options{$param} = undef; # clear the list
2211
2230
  }
2231
+ } elsif ($param eq 'IgnoreTags') {
2232
+ if (defined $newVal) {
2233
+ # parse list from delimited string if necessary
2234
+ my @ignoreList = (ref $newVal eq 'ARRAY') ? @$newVal : ($newVal =~ /[-\w?*:]+/g);
2235
+ ExpandShortcuts(\@ignoreList);
2236
+ # add to existing tags to ignore
2237
+ $$options{$param} or $$options{$param} = { };
2238
+ foreach (@ignoreList) {
2239
+ /^(.*:)?([-\w?*]+)#?$/ or next;
2240
+ $$options{$param}{lc $2} = 1;
2241
+ }
2242
+ } else {
2243
+ $$options{$param} = undef; # clear the option
2244
+ }
2212
2245
  } elsif ($param eq 'ListJoin') {
2213
2246
  $$options{$param} = $newVal;
2214
2247
  # set the old List and ListSep options for backward compatibility
@@ -2321,6 +2354,7 @@ sub ClearOptions($)
2321
2354
  HtmlDump => 0, # HTML dump (0-3, higher # = bigger limit)
2322
2355
  HtmlDumpBase => undef, # base address for HTML dump
2323
2356
  IgnoreMinorErrors => undef, # ignore minor errors when reading/writing
2357
+ IgnoreTags => undef, # list of tags to ignore when extracting
2324
2358
  Lang => $defaultLang,# localized language for descriptions etc
2325
2359
  LargeFileSupport => undef, # flag indicating support of 64-bit file offsets
2326
2360
  List => undef, # extract lists of PrintConv values into arrays [no longer documented]
@@ -3860,6 +3894,10 @@ sub CanWrite($)
3860
3894
  my $ext = GetFileExtension($file) || uc($file);
3861
3895
  return grep(/^$ext$/, @{$noWriteFile{$type}}) ? 0 : 1 if $ext;
3862
3896
  }
3897
+ if ($onlyWriteFile{$type}) {
3898
+ my $ext = GetFileExtension($file) || uc($file);
3899
+ return grep(/^$ext$/, @{$onlyWriteFile{$type}}) ? 1 : 0 if $ext;
3900
+ }
3863
3901
  unless (%writeTypes) {
3864
3902
  $writeTypes{$_} = 1 foreach @writeTypes;
3865
3903
  }
@@ -3883,7 +3921,7 @@ sub CanCreate($)
3883
3921
  #==============================================================================
3884
3922
  # Functions below this are not part of the public API
3885
3923
 
3886
- # Initialize member variables for reading or writing a new file
3924
+ # Initialize member variables before reading or writing a new file
3887
3925
  # Inputs: 0) ExifTool object reference
3888
3926
  sub Init($)
3889
3927
  {
@@ -4027,6 +4065,57 @@ sub NextTagKey($$)
4027
4065
  return undef;
4028
4066
  }
4029
4067
 
4068
+ #------------------------------------------------------------------------------
4069
+ # Does a string contain valid UTF-8 characters?
4070
+ # Inputs: 0) string reference, 1) true to allow last character to be truncated
4071
+ # Returns: 0=regular ASCII, -1=invalid UTF-8, 1=valid UTF-8 with maximum 16-bit
4072
+ # wide characters, 2=valid UTF-8 requiring 32-bit wide characters
4073
+ # Notes: Changes current string position
4074
+ # (see http://www.fileformat.info/info/unicode/utf8.htm for help understanding this)
4075
+ sub IsUTF8($;$)
4076
+ {
4077
+ my ($strPt, $trunc) = @_;
4078
+ pos($$strPt) = 0; # start at beginning of string
4079
+ return 0 unless $$strPt =~ /([\x80-\xff])/g;
4080
+ my $rtnVal = 1;
4081
+ for (;;) {
4082
+ my $ch = ord($1);
4083
+ # minimum lead byte for 2-byte sequence is 0xc2 (overlong sequences
4084
+ # not allowed), 0xf8-0xfd are restricted by RFC 3629 (no 5 or 6 byte
4085
+ # sequences), and 0xfe and 0xff are not valid in UTF-8 strings
4086
+ return -1 if $ch < 0xc2 or $ch >= 0xf8;
4087
+ # determine number of bytes remaining in sequence
4088
+ my $n;
4089
+ if ($ch < 0xe0) {
4090
+ $n = 1;
4091
+ } elsif ($ch < 0xf0) {
4092
+ $n = 2;
4093
+ } else {
4094
+ $n = 3;
4095
+ # character code is greater than 0xffff if more than 2 extra bytes
4096
+ # were required in the UTF-8 character
4097
+ $rtnVal = 2;
4098
+ }
4099
+ my $pos = pos $$strPt;
4100
+ unless ($$strPt =~ /\G([\x80-\xbf]{$n})/g) {
4101
+ return $rtnVal if $trunc and $pos + $n > length $$strPt;
4102
+ return -1;
4103
+ }
4104
+ # the following is ref https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c
4105
+ if ($n == 2) {
4106
+ return -1 if ($ch == 0xe0 and (ord($1) & 0xe0) == 0x80) or
4107
+ ($ch == 0xed and (ord($1) & 0xe0) == 0xa0) or
4108
+ ($ch == 0xef and ord($1) == 0xbf and
4109
+ (ord(substr $1, 1) & 0xfe) == 0xbe);
4110
+ } else {
4111
+ return -1 if ($ch == 0xf0 and (ord($1) & 0xf0) == 0x80) or
4112
+ ($ch == 0xf4 and ord($1) > 0x8f) or $ch > 0xf4;
4113
+ }
4114
+ last unless $$strPt =~ /([\x80-\xff])/g;
4115
+ }
4116
+ return $rtnVal;
4117
+ }
4118
+
4030
4119
  #------------------------------------------------------------------------------
4031
4120
  # Split file name into directory and name parts
4032
4121
  # Inptus: 0) file name
@@ -4072,10 +4161,7 @@ sub EncodeFileName($$;$)
4072
4161
  }
4073
4162
  }
4074
4163
  } elsif ($^O eq 'MSWin32' and $file =~ /[\x80-\xff]/ and not defined $enc) {
4075
- require Image::ExifTool::XMP;
4076
- if (Image::ExifTool::XMP::IsUTF8(\$file) < 0) {
4077
- $self->WarnOnce('FileName encoding not specified');
4078
- }
4164
+ $self->WarnOnce('FileName encoding not specified') if IsUTF8(\$file) < 0;
4079
4165
  }
4080
4166
  return 0;
4081
4167
  }
@@ -4100,10 +4186,15 @@ sub Open($*$;$)
4100
4186
  # handle Windows Unicode file name
4101
4187
  local $SIG{'__WARN__'} = \&SetWarning;
4102
4188
  my ($access, $create);
4103
- if ($mode eq '>') {
4189
+ if ($mode eq '>' or $mode eq '>>') {
4104
4190
  eval {
4105
4191
  $access = Win32API::File::GENERIC_WRITE();
4106
- $create = Win32API::File::CREATE_ALWAYS();
4192
+ if ($mode eq '>>') {
4193
+ $access |= Win32API::File::FILE_APPEND_DATA();
4194
+ $create = Win32API::File::OPEN_ALWAYS();
4195
+ } else {
4196
+ $create = Win32API::File::CREATE_ALWAYS();
4197
+ }
4107
4198
  }
4108
4199
  } else {
4109
4200
  eval {
@@ -4359,11 +4450,15 @@ sub ParseArguments($;@)
4359
4450
  sub IsSameID($$)
4360
4451
  {
4361
4452
  my ($id, $grp) = @_;
4362
- return 1 if $grp eq $id; # decimal ID's or raw ID's
4363
- if ($id =~ /^\d+$/) { # numerical numerical ID's may be in hex
4364
- return 1 if $grp =~ s/^0x0*// and $grp eq sprintf('%x', $id);
4365
- } else { # other ID's may conform to ExifTool group name conventions
4366
- return 1 if $id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge and $grp eq $id;
4453
+ for (;;) {
4454
+ return 1 if $grp eq $id; # decimal ID's or raw ID's
4455
+ if ($id =~ /^\d+$/) { # numerical numerical ID's may be in hex
4456
+ return 1 if $grp =~ s/^0x0*// and $grp eq sprintf('%x', $id);
4457
+ } else { # other ID's may conform to ExifTool group name conventions
4458
+ my $tmp = $id;
4459
+ return 1 if $tmp =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge and $grp eq $tmp;
4460
+ }
4461
+ last unless $id =~ s/-.*//; # remove language code if it exists
4367
4462
  }
4368
4463
  return 0;
4369
4464
  }
@@ -5689,8 +5784,8 @@ sub ConvertDateTime($$)
5689
5784
  $a[4] -= 1; # base month is 1
5690
5785
  # parse our %f fractional seconds first (and round up seconds if necessary)
5691
5786
  # - if there are multiple %f codes, they all get the same number of digits as the first
5692
- if ($fmt =~ /%\.?(\d*)f/) {
5693
- my $dig = $1;
5787
+ if ($fmt =~ /%(-?)\.?(\d*)f/) {
5788
+ my ($neg, $dig) = ($1, $2);
5694
5789
  my $frac = $date =~ /(\.\d+)/ ? $1 : '';
5695
5790
  if (not $frac) {
5696
5791
  $frac = '.' . ('0' x $dig) if $dig;
@@ -5717,7 +5812,8 @@ sub ConvertDateTime($$)
5717
5812
  }
5718
5813
  }
5719
5814
  }
5720
- $fmt =~ s/(^|[^%])((%%)*)%\.?\d*f/$1$2$frac/g;
5815
+ $neg and $frac =~ s/^\.//;
5816
+ $fmt =~ s/(^|[^%])((%%)*)%-?\.?\d*f/$1$2$frac/g;
5721
5817
  }
5722
5818
  # parse %z and %s ourself (to handle time zones properly)
5723
5819
  if ($fmt =~ /%[sz]/) {
@@ -5863,7 +5959,7 @@ sub GetUnixTime($;$)
5863
5959
  {
5864
5960
  my ($timeStr, $isLocal) = @_;
5865
5961
  return 0 if $timeStr eq '0000:00:00 00:00:00';
5866
- my @tm = ($timeStr =~ /^(\d+):(\d+):(\d+)\s+(\d+):(\d+):(\d+)(.*)/);
5962
+ my @tm = ($timeStr =~ /^(\d+)[-:](\d+)[-:](\d+)\s+(\d+):(\d+):(\d+)(.*)/);
5867
5963
  return undef unless @tm == 7;
5868
5964
  unless (eval { require Time::Local }) {
5869
5965
  warn "Time::Local is not installed\n";
@@ -7955,11 +8051,11 @@ sub GetTagInfo($$$;$$$)
7955
8051
  next;
7956
8052
  }
7957
8053
  }
7958
- if ($$tagInfo{Unknown} and not $$self{OPTIONS}{Unknown} and
7959
- not $$self{OPTIONS}{Verbose} and not $$self{OPTIONS}{Validate} and
7960
- not $$self{HTML_DUMP})
8054
+ # don't return Unknown tags unless that option is set (also see forum13716)
8055
+ if ($$tagInfo{Unknown} and not $$self{OPTIONS}{Unknown} and not
8056
+ ($$self{OPTIONS}{Verbose} or $$self{HTML_DUMP} or
8057
+ ($$self{OPTIONS}{Validate} and not $$tagInfo{AddedUnknown})))
7961
8058
  {
7962
- # don't return Unknown tags unless that option is set
7963
8059
  return undef;
7964
8060
  }
7965
8061
  # return the tag information we found
@@ -7984,6 +8080,7 @@ sub GetTagInfo($$$;$$$)
7984
8080
  Unknown => 1,
7985
8081
  Writable => 0, # can't write unknown tags
7986
8082
  PrintConv => $printConv,
8083
+ AddedUnknown => 1,
7987
8084
  };
7988
8085
  # add tag information to table
7989
8086
  AddTagToTable($tagTablePtr, $tagID, $tagInfo);
@@ -8045,6 +8142,7 @@ sub AddTagToTable($$;$$)
8045
8142
  unless (defined $$tagTablePtr{$tagID} or $specialTags{$tagID}) {
8046
8143
  $$tagTablePtr{$tagID} = $tagInfo;
8047
8144
  }
8145
+ $$tagInfo{AddedUnknown} = 1 if $$tagInfo{Unknown};
8048
8146
  return $tagInfo;
8049
8147
  }
8050
8148
 
@@ -8187,15 +8285,17 @@ sub FoundTag($$$;@)
8187
8285
  {
8188
8286
  local $_;
8189
8287
  my ($self, $tagInfo, $value, @grps) = @_;
8190
- my ($tag, $noListDel);
8288
+ my ($tag, $noListDel, $tbl);
8191
8289
  my $options = $$self{OPTIONS};
8192
8290
 
8193
8291
  if (ref $tagInfo eq 'HASH') {
8194
8292
  $tag = $$tagInfo{Name} or warn("No tag name\n"), return undef;
8293
+ $tbl = $$tagInfo{Table};
8195
8294
  } else {
8196
8295
  $tag = $tagInfo;
8197
8296
  # look for tag in Extra
8198
- $tagInfo = $self->GetTagInfo(GetTagTable('Image::ExifTool::Extra'), $tag);
8297
+ $tbl = GetTagTable('Image::ExifTool::Extra');
8298
+ $tagInfo = $self->GetTagInfo($tbl, $tag);
8199
8299
  # make temporary hash if tag doesn't exist in Extra
8200
8300
  # (not advised to do this since the tag won't show in list)
8201
8301
  $tagInfo or $tagInfo = { Name => $tag, Groups => \%allGroupsExifTool };
@@ -8204,7 +8304,7 @@ sub FoundTag($$$;@)
8204
8304
  # get tag priority
8205
8305
  my $priority = $$tagInfo{Priority};
8206
8306
  unless (defined $priority) {
8207
- $priority = $$tagInfo{Table}{PRIORITY};
8307
+ $priority = $$tbl{PRIORITY};
8208
8308
  $priority = 0 if not defined $priority and $$tagInfo{Avoid};
8209
8309
  }
8210
8310
  $grps[0] or $grps[0] = $$self{SET_GROUP0};
@@ -8233,6 +8333,14 @@ sub FoundTag($$$;@)
8233
8333
  $self->Warn("RawConv $tag: " . CleanWarning()) if $evalWarning;
8234
8334
  return undef unless defined $value;
8235
8335
  }
8336
+ # ignore specified tags (AFTER doing RawConv if necessary!)
8337
+ if ($$options{IgnoreTags}) {
8338
+ if ($$options{IgnoreTags}{all}) {
8339
+ return undef unless $$self{REQ_TAG_LOOKUP}{lc $tag};
8340
+ } else {
8341
+ return undef if $$options{IgnoreTags}{lc $tag};
8342
+ }
8343
+ }
8236
8344
  # handle duplicate tag names
8237
8345
  if (defined $$valueHash{$tag}) {
8238
8346
  # add to list if there is an active list for this tag
@@ -8444,7 +8552,7 @@ sub SetFileType($;$$$)
8444
8552
 
8445
8553
  #------------------------------------------------------------------------------
8446
8554
  # Override the FileType and MIMEType tags
8447
- # Inputs: 0) ExifTool object ref, 1) file type, 2) MIME type, 3) normal extension
8555
+ # Inputs: 0) ExifTool object ref, 1) file type, 2) MIME type, 3) normal extension (lower case)
8448
8556
  # Notes: does nothing if FileType was not previously defined (ie. when writing)
8449
8557
  sub OverrideFileType($$;$$)
8450
8558
  {