exiftool-vendored.pl 12.45.0 → 12.49.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 (51) hide show
  1. package/bin/Changes +84 -3
  2. package/bin/MANIFEST +9 -0
  3. package/bin/META.json +1 -1
  4. package/bin/META.yml +1 -1
  5. package/bin/README +45 -44
  6. package/bin/config_files/acdsee.config +2 -1
  7. package/bin/config_files/frameCount.config +56 -0
  8. package/bin/config_files/tiff_version.config +1 -1
  9. package/bin/exiftool +62 -54
  10. package/bin/lib/Image/ExifTool/Apple.pm +6 -2
  11. package/bin/lib/Image/ExifTool/BuildTagLookup.pm +11 -6
  12. package/bin/lib/Image/ExifTool/Canon.pm +20 -8
  13. package/bin/lib/Image/ExifTool/CanonRaw.pm +8 -1
  14. package/bin/lib/Image/ExifTool/Exif.pm +7 -3
  15. package/bin/lib/Image/ExifTool/FLAC.pm +17 -3
  16. package/bin/lib/Image/ExifTool/FlashPix.pm +4 -2
  17. package/bin/lib/Image/ExifTool/FujiFilm.pm +31 -5
  18. package/bin/lib/Image/ExifTool/ICC_Profile.pm +1 -1
  19. package/bin/lib/Image/ExifTool/ICO.pm +141 -0
  20. package/bin/lib/Image/ExifTool/ID3.pm +5 -5
  21. package/bin/lib/Image/ExifTool/M2TS.pm +55 -8
  22. package/bin/lib/Image/ExifTool/MIE.pm +9 -3
  23. package/bin/lib/Image/ExifTool/MISB.pm +494 -0
  24. package/bin/lib/Image/ExifTool/MakerNotes.pm +3 -1
  25. package/bin/lib/Image/ExifTool/Nikon.pm +34 -31
  26. package/bin/lib/Image/ExifTool/NikonSettings.pm +5 -3
  27. package/bin/lib/Image/ExifTool/Panasonic.pm +21 -4
  28. package/bin/lib/Image/ExifTool/PanasonicRaw.pm +12 -5
  29. package/bin/lib/Image/ExifTool/Photoshop.pm +29 -3
  30. package/bin/lib/Image/ExifTool/QuickTime.pm +34 -5
  31. package/bin/lib/Image/ExifTool/QuickTimeStream.pl +42 -4
  32. package/bin/lib/Image/ExifTool/README +1 -1
  33. package/bin/lib/Image/ExifTool/RIFF.pm +106 -9
  34. package/bin/lib/Image/ExifTool/Samsung.pm +2 -2
  35. package/bin/lib/Image/ExifTool/Sigma.pm +27 -1
  36. package/bin/lib/Image/ExifTool/SigmaRaw.pm +37 -13
  37. package/bin/lib/Image/ExifTool/Sony.pm +7 -3
  38. package/bin/lib/Image/ExifTool/TagLookup.pm +176 -6
  39. package/bin/lib/Image/ExifTool/TagNames.pod +4782 -4486
  40. package/bin/lib/Image/ExifTool/Text.pm +3 -4
  41. package/bin/lib/Image/ExifTool/Torrent.pm +2 -3
  42. package/bin/lib/Image/ExifTool/WriteCanonRaw.pl +7 -0
  43. package/bin/lib/Image/ExifTool/WriteExif.pl +19 -1
  44. package/bin/lib/Image/ExifTool/WriteRIFF.pl +359 -0
  45. package/bin/lib/Image/ExifTool/Writer.pl +6 -2
  46. package/bin/lib/Image/ExifTool/XMP.pm +70 -56
  47. package/bin/lib/Image/ExifTool.pm +75 -15
  48. package/bin/lib/Image/ExifTool.pod +55 -52
  49. package/bin/perl-Image-ExifTool.spec +43 -43
  50. package/bin/pp_build_exe.args +7 -4
  51. package/package.json +2 -2
@@ -50,7 +50,7 @@ use Image::ExifTool::Exif;
50
50
  use Image::ExifTool::GPS;
51
51
  require Exporter;
52
52
 
53
- $VERSION = '3.52';
53
+ $VERSION = '3.54';
54
54
  @ISA = qw(Exporter);
55
55
  @EXPORT_OK = qw(EscapeXML UnescapeXML);
56
56
 
@@ -128,6 +128,8 @@ my %xmpNS = (
128
128
  stRef => 'http://ns.adobe.com/xap/1.0/sType/ResourceRef#',
129
129
  stVer => 'http://ns.adobe.com/xap/1.0/sType/Version#',
130
130
  stMfs => 'http://ns.adobe.com/xap/1.0/sType/ManifestItem#',
131
+ stCamera => 'http://ns.adobe.com/photoshop/1.0/camera-profile',
132
+ crlcp => 'http://ns.adobe.com/camera-raw-embedded-lens-profile/1.0/',
131
133
  tiff => 'http://ns.adobe.com/tiff/1.0/',
132
134
  'x' => 'adobe:ns:meta/',
133
135
  xmpG => 'http://ns.adobe.com/xap/1.0/g/',
@@ -1273,6 +1275,41 @@ my %sPantryItem = (
1273
1275
  },
1274
1276
  },
1275
1277
  EmbeddedXMPDigest => { }, #PH (LR5)
1278
+ CameraProfiles => { #PH (2022-10-11)
1279
+ List => 'Seq',
1280
+ Struct => {
1281
+ NAMESPACE => 'stCamera',
1282
+ STRUCT_NAME => 'Camera',
1283
+ Author => { },
1284
+ Make => { },
1285
+ Model => { },
1286
+ UniqueCameraModel => { },
1287
+ CameraRawProfile => { Writable => 'boolean' },
1288
+ AutoScale => { Writable => 'boolean' },
1289
+ Lens => { },
1290
+ CameraPrettyName => { },
1291
+ LensPrettyName => { },
1292
+ ProfileName => { },
1293
+ SensorFormatFactor => { Writable => 'real' },
1294
+ FocalLength => { Writable => 'real' },
1295
+ FocusDistance => { Writable => 'real' },
1296
+ ApertureValue => { Writable => 'real' },
1297
+ PerspectiveModel => {
1298
+ Namespace => 'crlcp',
1299
+ Struct => {
1300
+ NAMESPACE => 'stCamera',
1301
+ STRUCT_NAME => 'PerspectiveModel',
1302
+ Version => { },
1303
+ ImageXCenter => { Writable => 'real' },
1304
+ ImageYCenter => { Writable => 'real' },
1305
+ ScaleFactor => { Writable => 'real' },
1306
+ RadialDistortParam1 => { Writable => 'real' },
1307
+ RadialDistortParam2 => { Writable => 'real' },
1308
+ RadialDistortParam3 => { Writable => 'real' },
1309
+ },
1310
+ },
1311
+ },
1312
+ },
1276
1313
  );
1277
1314
 
1278
1315
  # Photoshop Camera Raw namespace properties (crs) - (ref 8,PH)
@@ -1431,7 +1468,14 @@ my %sPantryItem = (
1431
1468
  PostCropVignetteMidpoint => { Writable => 'integer' },
1432
1469
  PostCropVignetteFeather => { Writable => 'integer' },
1433
1470
  PostCropVignetteRoundness => { Writable => 'integer' },
1434
- PostCropVignetteStyle => { Writable => 'integer' },
1471
+ PostCropVignetteStyle => {
1472
+ Writable => 'integer',
1473
+ PrintConv => { #forum14011
1474
+ 1 => 'Highlight Priority',
1475
+ 2 => 'Color Priority',
1476
+ 3 => 'Paint Overlay',
1477
+ },
1478
+ },
1435
1479
  # disable List behaviour of flattened Gradient/PaintBasedCorrections
1436
1480
  # because these are nested in lists and the flattened tags can't
1437
1481
  # do justice to this complex structure
@@ -1528,7 +1572,17 @@ my %sPantryItem = (
1528
1572
  },
1529
1573
  ColorNoiseReductionSmoothness => { Writable => 'integer' },
1530
1574
  PerspectiveAspect => { Writable => 'integer' },
1531
- PerspectiveUpright => { Writable => 'integer' },
1575
+ PerspectiveUpright => {
1576
+ Writable => 'integer',
1577
+ PrintConv => { #forum14012
1578
+ 0 => 'Off', # Disable Upright
1579
+ 1 => 'Auto', # Apply balanced perspective corrections
1580
+ 2 => 'Full', # Apply level, horizontal, and vertical perspective corrections
1581
+ 3 => 'Level', # Apply only level correction
1582
+ 4 => 'Vertical',# Apply level and vertical perspective corrections
1583
+ 5 => 'Guided', # Draw two or more guides to customize perspective corrections
1584
+ },
1585
+ },
1532
1586
  RetouchAreas => {
1533
1587
  FlatName => 'RetouchArea',
1534
1588
  Struct => \%sRetouchArea,
@@ -1552,12 +1606,17 @@ my %sPantryItem = (
1552
1606
  UprightPreview => { Writable => 'boolean' },
1553
1607
  UprightTransformCount => { Writable => 'integer' },
1554
1608
  UprightDependentDigest => { },
1609
+ UprightGuidedDependentDigest => { },
1555
1610
  UprightTransform_0 => { },
1556
1611
  UprightTransform_1 => { },
1557
1612
  UprightTransform_2 => { },
1558
1613
  UprightTransform_3 => { },
1559
1614
  UprightTransform_4 => { },
1560
1615
  UprightTransform_5 => { },
1616
+ UprightFourSegments_0 => { },
1617
+ UprightFourSegments_1 => { },
1618
+ UprightFourSegments_2 => { },
1619
+ UprightFourSegments_3 => { },
1561
1620
  # more stuff seen in lens profile file (unknown source)
1562
1621
  What => { }, # (with value "LensProfileDefaultSettings")
1563
1622
  LensProfileMatchKeyExifMake => { },
@@ -2396,6 +2455,12 @@ my %sPantryItem = (
2396
2455
  LateralChromaticAberrationCorrectionAlreadyApplied => { Writable => 'boolean' },
2397
2456
  LensDistortInfo => { }, # (LR 7.5.1, 4 signed rational values)
2398
2457
  NeutralDensityFactor => { }, # (LR 11.0 - rational value, but denominator seems significant)
2458
+ # the following are ref forum13747
2459
+ EnhanceDetailsAlreadyApplied => { Writable => 'boolean' },
2460
+ EnhanceDetailsVersion => { }, # integer?
2461
+ EnhanceSuperResolutionAlreadyApplied => { Writable => 'boolean' },
2462
+ EnhanceSuperResolutionVersion => { }, # integer?
2463
+ EnhanceSuperResolutionScale => { Writable => 'rational' },
2399
2464
  );
2400
2465
 
2401
2466
  # IPTC Core namespace properties (Iptc4xmpCore) (ref 4)
@@ -2620,7 +2685,7 @@ sub FullEscapeXML($)
2620
2685
  $str =~ s/([&><'"])/&$charName{$1};/sg; # escape necessary XML characters
2621
2686
  $str =~ s/\\/&#92;/sg; # escape backslashes too
2622
2687
  # then use C-escape sequences for invalid characters
2623
- if ($str =~ /[\0-\x1f]/ or IsUTF8(\$str) < 0) {
2688
+ if ($str =~ /[\0-\x1f]/ or Image::ExifTool::IsUTF8(\$str) < 0) {
2624
2689
  $str =~ s/([\0-\x1f\x80-\xff])/sprintf("\\x%.2x",ord $1)/sge;
2625
2690
  }
2626
2691
  return $str;
@@ -2665,57 +2730,6 @@ sub UnescapeChar($$;$)
2665
2730
  return $val;
2666
2731
  }
2667
2732
 
2668
- #------------------------------------------------------------------------------
2669
- # Does a string contain valid UTF-8 characters?
2670
- # Inputs: 0) string reference, 1) true to allow last character to be truncated
2671
- # Returns: 0=regular ASCII, -1=invalid UTF-8, 1=valid UTF-8 with maximum 16-bit
2672
- # wide characters, 2=valid UTF-8 requiring 32-bit wide characters
2673
- # Notes: Changes current string position
2674
- # (see http://www.fileformat.info/info/unicode/utf8.htm for help understanding this)
2675
- sub IsUTF8($;$)
2676
- {
2677
- my ($strPt, $trunc) = @_;
2678
- pos($$strPt) = 0; # start at beginning of string
2679
- return 0 unless $$strPt =~ /([\x80-\xff])/g;
2680
- my $rtnVal = 1;
2681
- for (;;) {
2682
- my $ch = ord($1);
2683
- # minimum lead byte for 2-byte sequence is 0xc2 (overlong sequences
2684
- # not allowed), 0xf8-0xfd are restricted by RFC 3629 (no 5 or 6 byte
2685
- # sequences), and 0xfe and 0xff are not valid in UTF-8 strings
2686
- return -1 if $ch < 0xc2 or $ch >= 0xf8;
2687
- # determine number of bytes remaining in sequence
2688
- my $n;
2689
- if ($ch < 0xe0) {
2690
- $n = 1;
2691
- } elsif ($ch < 0xf0) {
2692
- $n = 2;
2693
- } else {
2694
- $n = 3;
2695
- # character code is greater than 0xffff if more than 2 extra bytes
2696
- # were required in the UTF-8 character
2697
- $rtnVal = 2;
2698
- }
2699
- my $pos = pos $$strPt;
2700
- unless ($$strPt =~ /\G([\x80-\xbf]{$n})/g) {
2701
- return $rtnVal if $trunc and $pos + $n > length $$strPt;
2702
- return -1;
2703
- }
2704
- # the following is ref https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c
2705
- if ($n == 2) {
2706
- return -1 if ($ch == 0xe0 and (ord($1) & 0xe0) == 0x80) or
2707
- ($ch == 0xed and (ord($1) & 0xe0) == 0xa0) or
2708
- ($ch == 0xef and ord($1) == 0xbf and
2709
- (ord(substr $1, 1) & 0xfe) == 0xbe);
2710
- } else {
2711
- return -1 if ($ch == 0xf0 and (ord($1) & 0xf0) == 0x80) or
2712
- ($ch == 0xf4 and ord($1) > 0x8f) or $ch > 0xf4;
2713
- }
2714
- last unless $$strPt =~ /([\x80-\xff])/g;
2715
- }
2716
- return $rtnVal;
2717
- }
2718
-
2719
2733
  #------------------------------------------------------------------------------
2720
2734
  # Fix malformed UTF8 (by replacing bad bytes with specified character)
2721
2735
  # Inputs: 0) string reference, 1) string to replace each bad byte,
@@ -2730,7 +2744,7 @@ sub FixUTF8($;$)
2730
2744
  last unless $$strPt =~ /([\x80-\xff])/g;
2731
2745
  my $ch = ord($1);
2732
2746
  my $pos = pos($$strPt);
2733
- # (see comments in IsUTF8() above)
2747
+ # (see comments in Image::ExifTool::IsUTF8())
2734
2748
  if ($ch >= 0xc2 and $ch < 0xf8) {
2735
2749
  my $n = $ch < 0xe0 ? 1 : ($ch < 0xf0 ? 2 : 3);
2736
2750
  if ($$strPt =~ /\G([\x80-\xbf]{$n})/g) {
@@ -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.45';
32
+ $VERSION = '12.49';
33
33
  $RELEASE = '';
34
34
  @ISA = qw(Exporter);
35
35
  %EXPORT_TAGS = (
@@ -139,8 +139,8 @@ 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
@@ -191,11 +191,12 @@ $defaultLang = 'en'; # default language
191
191
  HTML VRD RTF FITS XCF DSS QTIF FPX PICT ZIP GZIP PLIST RAR BZ2
192
192
  CZI TAR EXE EXR HDR CHM LNK WMF AVC DEX DPX RAW Font RSRC M2TS
193
193
  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);
194
+ PFM2 MRC LIF JXL MOI ISO ALIAS JSON MP3 DICOM PCD ICO TXT);
195
195
 
196
196
  # file types that we can write (edit)
197
197
  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);
198
+ X3F PS PDF ICC VRD DR4 JP2 JXL EXIF AI AIT IND MOV EXV FLIF
199
+ RIFF);
199
200
  my %writeTypes; # lookup for writable file types (hash filled if required)
200
201
 
201
202
  # file extensions that we can't write for various base types
@@ -205,6 +206,8 @@ my %writeTypes; # lookup for writable file types (hash filled if required)
205
206
  JP2 => [ qw(J2C JPC) ],
206
207
  MOV => [ qw(INSV) ],
207
208
  );
209
+ # file extensions that we can only write for various base types
210
+ my %onlyWriteFile = ( RIFF => [ qw(WEBP) ] );
208
211
 
209
212
  # file types that we can create from scratch
210
213
  # - must update CanCreate() documentation if this list is changed!
@@ -257,6 +260,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
257
260
  CRW => ['CRW', 'Canon RAW format'],
258
261
  CS1 => ['PSD', 'Sinar CaptureShop 1-Shot RAW'],
259
262
  CSV => ['TXT', 'Comma-Separated Values'],
263
+ CUR => ['ICO', 'Windows Cursor'],
260
264
  CZI => ['CZI', 'Zeiss Integrated Software RAW'],
261
265
  DC3 => 'DICM',
262
266
  DCM => 'DICM',
@@ -333,6 +337,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
333
337
  ICAL => 'ICS',
334
338
  ICC => ['ICC', 'International Color Consortium'],
335
339
  ICM => 'ICC',
340
+ ICO => ['ICO', 'Windows Icon'],
336
341
  ICS => ['VCard','iCalendar Schedule'],
337
342
  IDML => ['ZIP', 'Adobe InDesign Markup Language'],
338
343
  IIQ => ['TIFF', 'Phase One Intelligent Image Quality RAW'],
@@ -378,6 +383,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
378
383
  M4B => ['MOV', 'MPEG-4 audio Book'],
379
384
  M4P => ['MOV', 'MPEG-4 Protected'],
380
385
  M4V => ['MOV', 'MPEG-4 Video'],
386
+ MACOS=> ['MacOS','MacOS ._ sidecar file'],
381
387
  MAX => ['FPX', '3D Studio MAX'],
382
388
  MEF => ['TIFF', 'Mamiya (RAW) Electronic Format'],
383
389
  MIE => ['MIE', 'Meta Information Encapsulation format'],
@@ -407,7 +413,6 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
407
413
  NEF => ['TIFF', 'Nikon (RAW) Electronic Format'],
408
414
  NEWER => 'COS',
409
415
  NKSC => ['XMP', 'Nikon Sidecar'],
410
-
411
416
  NMBTEMPLATE => ['ZIP','Apple Numbers Template'],
412
417
  NRW => ['TIFF', 'Nikon RAW (2)'],
413
418
  NUMBERS => ['ZIP','Apple Numbers spreadsheet'],
@@ -530,7 +535,6 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
530
535
  WMV => ['ASF', 'Windows Media Video'],
531
536
  WV => ['RIFF', 'WavePack lossless audio'],
532
537
  X3F => ['X3F', 'Sigma RAW format'],
533
- MACOS=> ['MacOS','MacOS ._ sidecar file'],
534
538
  XCF => ['XCF', 'GIMP native image format'],
535
539
  XHTML=> ['HTML', 'Extensible HyperText Markup Language'],
536
540
  XLA => ['FPX', 'Microsoft Excel Add-in'],
@@ -647,6 +651,7 @@ my %fileDescription = (
647
651
  HDR => 'image/vnd.radiance',
648
652
  HTML => 'text/html',
649
653
  ICC => 'application/vnd.iccprofile',
654
+ ICO => 'application/octet-stream', #PH (NC)
650
655
  ICS => 'text/calendar',
651
656
  IDML => 'application/vnd.adobe.indesign-idml-package',
652
657
  IIQ => 'image/x-raw',
@@ -913,6 +918,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
913
918
  HDR => '#\?(RADIANCE|RGBE)\x0a',
914
919
  HTML => '(\xef\xbb\xbf)?\s*(?i)<(!DOCTYPE\s+HTML|HTML|\?xml)', # (case insensitive)
915
920
  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}',
921
+ ICO => '\0\0[\x01\x02]\0[^0]\0', # (reasonably assume that the file contains less than 256 images)
916
922
  IND => '\x06\x06\xed\xf5\xd8\x1d\x46\xe5\xbd\x31\xef\xe7\xfe\x74\xb7\x1d',
917
923
  # ISO => signature is at byte 32768
918
924
  ITC => '.{4}itch',
@@ -925,6 +931,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
925
931
  LNK => '.{4}\x01\x14\x02\0{5}\xc0\0{6}\x46',
926
932
  LRI => 'LELR \0',
927
933
  M2TS => '(....)?\x47',
934
+ MacOS=> '\0\x05\x16\x07\0.\0\0Mac OS X ',
928
935
  MIE => '~[\x10\x18]\x04.0MIE',
929
936
  MIFF => 'id=ImageMagick',
930
937
  MKV => '\x1a\x45\xdf\xa3',
@@ -972,7 +979,6 @@ $testLen = 1024; # number of bytes to read when testing for magic number
972
979
  WMF => '(\xd7\xcd\xc6\x9a\0\0|\x01\0\x09\0\0\x03)',
973
980
  WTV => '\xb7\xd8\x00\x20\x37\x49\xda\x11\xa6\x4e\x00\x07\xe9\x5e\xad\x8d',
974
981
  X3F => 'FOVb',
975
- MacOS=> '\0\x05\x16\x07\0.\0\0Mac OS X ',
976
982
  XCF => 'gimp xcf ',
977
983
  XMP => '\0{0,3}(\xfe\xff|\xff\xfe|\xef\xbb\xbf)?\0{0,3}\s*<',
978
984
  ZIP => 'PK\x03\x04',
@@ -3875,6 +3881,10 @@ sub CanWrite($)
3875
3881
  my $ext = GetFileExtension($file) || uc($file);
3876
3882
  return grep(/^$ext$/, @{$noWriteFile{$type}}) ? 0 : 1 if $ext;
3877
3883
  }
3884
+ if ($onlyWriteFile{$type}) {
3885
+ my $ext = GetFileExtension($file) || uc($file);
3886
+ return grep(/^$ext$/, @{$onlyWriteFile{$type}}) ? 1 : 0 if $ext;
3887
+ }
3878
3888
  unless (%writeTypes) {
3879
3889
  $writeTypes{$_} = 1 foreach @writeTypes;
3880
3890
  }
@@ -4042,6 +4052,57 @@ sub NextTagKey($$)
4042
4052
  return undef;
4043
4053
  }
4044
4054
 
4055
+ #------------------------------------------------------------------------------
4056
+ # Does a string contain valid UTF-8 characters?
4057
+ # Inputs: 0) string reference, 1) true to allow last character to be truncated
4058
+ # Returns: 0=regular ASCII, -1=invalid UTF-8, 1=valid UTF-8 with maximum 16-bit
4059
+ # wide characters, 2=valid UTF-8 requiring 32-bit wide characters
4060
+ # Notes: Changes current string position
4061
+ # (see http://www.fileformat.info/info/unicode/utf8.htm for help understanding this)
4062
+ sub IsUTF8($;$)
4063
+ {
4064
+ my ($strPt, $trunc) = @_;
4065
+ pos($$strPt) = 0; # start at beginning of string
4066
+ return 0 unless $$strPt =~ /([\x80-\xff])/g;
4067
+ my $rtnVal = 1;
4068
+ for (;;) {
4069
+ my $ch = ord($1);
4070
+ # minimum lead byte for 2-byte sequence is 0xc2 (overlong sequences
4071
+ # not allowed), 0xf8-0xfd are restricted by RFC 3629 (no 5 or 6 byte
4072
+ # sequences), and 0xfe and 0xff are not valid in UTF-8 strings
4073
+ return -1 if $ch < 0xc2 or $ch >= 0xf8;
4074
+ # determine number of bytes remaining in sequence
4075
+ my $n;
4076
+ if ($ch < 0xe0) {
4077
+ $n = 1;
4078
+ } elsif ($ch < 0xf0) {
4079
+ $n = 2;
4080
+ } else {
4081
+ $n = 3;
4082
+ # character code is greater than 0xffff if more than 2 extra bytes
4083
+ # were required in the UTF-8 character
4084
+ $rtnVal = 2;
4085
+ }
4086
+ my $pos = pos $$strPt;
4087
+ unless ($$strPt =~ /\G([\x80-\xbf]{$n})/g) {
4088
+ return $rtnVal if $trunc and $pos + $n > length $$strPt;
4089
+ return -1;
4090
+ }
4091
+ # the following is ref https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c
4092
+ if ($n == 2) {
4093
+ return -1 if ($ch == 0xe0 and (ord($1) & 0xe0) == 0x80) or
4094
+ ($ch == 0xed and (ord($1) & 0xe0) == 0xa0) or
4095
+ ($ch == 0xef and ord($1) == 0xbf and
4096
+ (ord(substr $1, 1) & 0xfe) == 0xbe);
4097
+ } else {
4098
+ return -1 if ($ch == 0xf0 and (ord($1) & 0xf0) == 0x80) or
4099
+ ($ch == 0xf4 and ord($1) > 0x8f) or $ch > 0xf4;
4100
+ }
4101
+ last unless $$strPt =~ /([\x80-\xff])/g;
4102
+ }
4103
+ return $rtnVal;
4104
+ }
4105
+
4045
4106
  #------------------------------------------------------------------------------
4046
4107
  # Split file name into directory and name parts
4047
4108
  # Inptus: 0) file name
@@ -4087,10 +4148,7 @@ sub EncodeFileName($$;$)
4087
4148
  }
4088
4149
  }
4089
4150
  } elsif ($^O eq 'MSWin32' and $file =~ /[\x80-\xff]/ and not defined $enc) {
4090
- require Image::ExifTool::XMP;
4091
- if (Image::ExifTool::XMP::IsUTF8(\$file) < 0) {
4092
- $self->WarnOnce('FileName encoding not specified');
4093
- }
4151
+ $self->WarnOnce('FileName encoding not specified') if IsUTF8(\$file) < 0;
4094
4152
  }
4095
4153
  return 0;
4096
4154
  }
@@ -5704,8 +5762,8 @@ sub ConvertDateTime($$)
5704
5762
  $a[4] -= 1; # base month is 1
5705
5763
  # parse our %f fractional seconds first (and round up seconds if necessary)
5706
5764
  # - if there are multiple %f codes, they all get the same number of digits as the first
5707
- if ($fmt =~ /%\.?(\d*)f/) {
5708
- my $dig = $1;
5765
+ if ($fmt =~ /%(-?)\.?(\d*)f/) {
5766
+ my ($neg, $dig) = ($1, $2);
5709
5767
  my $frac = $date =~ /(\.\d+)/ ? $1 : '';
5710
5768
  if (not $frac) {
5711
5769
  $frac = '.' . ('0' x $dig) if $dig;
@@ -5732,7 +5790,8 @@ sub ConvertDateTime($$)
5732
5790
  }
5733
5791
  }
5734
5792
  }
5735
- $fmt =~ s/(^|[^%])((%%)*)%\.?\d*f/$1$2$frac/g;
5793
+ $neg and $frac =~ s/^\.//;
5794
+ $fmt =~ s/(^|[^%])((%%)*)%-?\.?\d*f/$1$2$frac/g;
5736
5795
  }
5737
5796
  # parse %z and %s ourself (to handle time zones properly)
5738
5797
  if ($fmt =~ /%[sz]/) {
@@ -8061,6 +8120,7 @@ sub AddTagToTable($$;$$)
8061
8120
  unless (defined $$tagTablePtr{$tagID} or $specialTags{$tagID}) {
8062
8121
  $$tagTablePtr{$tagID} = $tagInfo;
8063
8122
  }
8123
+ $$tagInfo{AddedUnknown} = 1 if $$tagInfo{Unknown};
8064
8124
  return $tagInfo;
8065
8125
  }
8066
8126
 
@@ -26,7 +26,7 @@ Image::ExifTool - Read and write meta information
26
26
  # ---- Object-oriented usage ----
27
27
 
28
28
  # Create a new Image::ExifTool object
29
- $exifTool = new Image::ExifTool;
29
+ $exifTool = Image::ExifTool->new;
30
30
 
31
31
  # Extract meta information from an image
32
32
  $exifTool->ExtractInfo($file, \%options);
@@ -65,48 +65,48 @@ supported by ExifTool (r = read, w = write, c = create):
65
65
 
66
66
  File Types
67
67
  ------------+-------------+-------------+-------------+------------
68
- 360 r/w | DR4 r/w/c | JNG r/w | O r | RAW r/w
69
- 3FR r | DSS r | JP2 r/w | ODP r | RIFF r
70
- 3G2 r/w | DV r | JPEG r/w | ODS r | RSRC r
71
- 3GP r/w | DVB r/w | JSON r | ODT r | RTF r
72
- A r | DVR-MS r | JXL r | OFR r | RW2 r/w
73
- AA r | DYLIB r | K25 r | OGG r | RWL r/w
74
- AAE r | EIP r | KDC r | OGV r | RWZ r
75
- AAX r/w | EPS r/w | KEY r | ONP r | RM r
76
- ACR r | EPUB r | LA r | OPUS r | SEQ r
77
- AFM r | ERF r/w | LFP r | ORF r/w | SKETCH r
78
- AI r/w | EXE r | LIF r | ORI r/w | SO r
79
- AIFF r | EXIF r/w/c | LNK r | OTF r | SR2 r/w
80
- APE r | EXR r | LRV r/w | PAC r | SRF r
81
- ARQ r/w | EXV r/w/c | M2TS r | PAGES r | SRW r/w
82
- ARW r/w | F4A/V r/w | M4A/V r/w | PBM r/w | SVG r
83
- ASF r | FFF r/w | MACOS r | PCD r | SWF r
84
- AVI r | FITS r | MAX r | PCX r | THM r/w
85
- AVIF r/w | FLA r | MEF r/w | PDB r | TIFF r/w
86
- AZW r | FLAC r | MIE r/w/ | PDF r/w | TORRENT r
87
- BMP r | FLIF r/w | MIFF r c | PEF r/w | TTC r
88
- BPG r | FLV r | MKA r | PFA r | TTF r
89
- BTF r | FPF r | MKS r | PFB r | TXT r
90
- CHM r | FPX r | MKV r | PFM r | VCF r
91
- COS r | GIF r/w | MNG r/w | PGF r | VRD r/w/c
92
- CR2 r/w | GPR r/w | MOBI r | PGM r/w | VSD r
93
- CR3 r/w | GZ r | MODD r | PLIST r | WAV r
94
- CRM r/w | HDP r/w | MOI r | PICT r | WDP r/w
95
- CRW r/w | HDR r | MOS r/w | PMP r | WEBP r
96
- CS1 r/w | HEIC r/w | MOV r/w | PNG r/w | WEBM r
97
- CSV r | HEIF r/w | MP3 r | PPM r/w | WMA r
98
- CZI r | HTML r | MP4 r/w | PPT r | WMV r
99
- DCM r | ICC r/w/c | MPC r | PPTX r | WTV r
100
- DCP r/w | ICS r | MPG r | PS r/w | WV r
101
- DCR r | IDML r | MPO r/w | PSB r/w | X3F r/w
102
- DFONT r | IIQ r/w | MQV r/w | PSD r/w | XCF r
103
- DIVX r | IND r/w | MRC r | PSP r | XLS r
104
- DJVU r | INSP r/w | MRW r/w | QTIF r/w | XLSX r
105
- DLL r | INSV r | MXF r | R3D r | XMP r/w/c
106
- DNG r/w | INX r | NEF r/w | RA r | ZIP r
107
- DOC r | ISO r | NKSC r/w | RAF r/w |
108
- DOCX r | ITC r | NRW r/w | RAM r |
109
- DPX r | J2C r | NUMBERS r | RAR r |
68
+ 360 r/w | DPX r | ITC r | NRW r/w | RAM r
69
+ 3FR r | DR4 r/w/c | J2C r | NUMBERS r | RAR r
70
+ 3G2 r/w | DSS r | JNG r/w | O r | RAW r/w
71
+ 3GP r/w | DV r | JP2 r/w | ODP r | RIFF r
72
+ A r | DVB r/w | JPEG r/w | ODS r | RSRC r
73
+ AA r | DVR-MS r | JSON r | ODT r | RTF r
74
+ AAE r | DYLIB r | JXL r | OFR r | RW2 r/w
75
+ AAX r/w | EIP r | K25 r | OGG r | RWL r/w
76
+ ACR r | EPS r/w | KDC r | OGV r | RWZ r
77
+ AFM r | EPUB r | KEY r | ONP r | RM r
78
+ AI r/w | ERF r/w | LA r | OPUS r | SEQ r
79
+ AIFF r | EXE r | LFP r | ORF r/w | SKETCH r
80
+ APE r | EXIF r/w/c | LIF r | ORI r/w | SO r
81
+ ARQ r/w | EXR r | LNK r | OTF r | SR2 r/w
82
+ ARW r/w | EXV r/w/c | LRV r/w | PAC r | SRF r
83
+ ASF r | F4A/V r/w | M2TS r | PAGES r | SRW r/w
84
+ AVI r | FFF r/w | M4A/V r/w | PBM r/w | SVG r
85
+ AVIF r/w | FITS r | MACOS r | PCD r | SWF r
86
+ AZW r | FLA r | MAX r | PCX r | THM r/w
87
+ BMP r | FLAC r | MEF r/w | PDB r | TIFF r/w
88
+ BPG r | FLIF r/w | MIE r/w/c | PDF r/w | TORRENT r
89
+ BTF r | FLV r | MIFF r | PEF r/w | TTC r
90
+ CHM r | FPF r | MKA r | PFA r | TTF r
91
+ COS r | FPX r | MKS r | PFB r | TXT r
92
+ CR2 r/w | GIF r/w | MKV r | PFM r | VCF r
93
+ CR3 r/w | GPR r/w | MNG r/w | PGF r | VRD r/w/c
94
+ CRM r/w | GZ r | MOBI r | PGM r/w | VSD r
95
+ CRW r/w | HDP r/w | MODD r | PLIST r | WAV r
96
+ CS1 r/w | HDR r | MOI r | PICT r | WDP r/w
97
+ CSV r | HEIC r/w | MOS r/w | PMP r | WEBP r/w
98
+ CUR r | HEIF r/w | MOV r/w | PNG r/w | WEBM r
99
+ CZI r | HTML r | MP3 r | PPM r/w | WMA r
100
+ DCM r | ICC r/w/c | MP4 r/w | PPT r | WMV r
101
+ DCP r/w | ICO r | MPC r | PPTX r | WTV r
102
+ DCR r | ICS r | MPG r | PS r/w | WV r
103
+ DFONT r | IDML r | MPO r/w | PSB r/w | X3F r/w
104
+ DIVX r | IIQ r/w | MQV r/w | PSD r/w | XCF r
105
+ DJVU r | IND r/w | MRC r | PSP r | XLS r
106
+ DLL r | INSP r/w | MRW r/w | QTIF r/w | XLSX r
107
+ DNG r/w | INSV r | MXF r | R3D r | XMP r/w/c
108
+ DOC r | INX r | NEF r/w | RA r | ZIP r
109
+ DOCX r | ISO r | NKSC r/w | RAF r/w |
110
110
 
111
111
  Meta Information
112
112
  ----------------------+----------------------+---------------------
@@ -175,7 +175,7 @@ The ExifTool methods are not thread safe.
175
175
 
176
176
  Creates a new ExifTool object.
177
177
 
178
- $exifTool = new Image::ExifTool;
178
+ $exifTool = Image::ExifTool->new;
179
179
 
180
180
  One ExifTool object may be used to process many files, so creating multiple
181
181
  ExifTool objects usually is not necessary.
@@ -338,7 +338,7 @@ The code below gives an example of how to handle these return values, as
338
338
  well as illustrating the use of other ExifTool functions:
339
339
 
340
340
  use Image::ExifTool;
341
- my $exifTool = new Image::ExifTool;
341
+ my $exifTool = Image::ExifTool->new;
342
342
  $exifTool->Options(Unknown => 1);
343
343
  my $info = $exifTool->ImageInfo('a.jpg');
344
344
  my $group = '';
@@ -615,11 +615,14 @@ undef.
615
615
 
616
616
  =item Exclude
617
617
 
618
- Exclude specified tags from tags extracted from an image. The option value
619
- is either a tag name or reference to a list of tag names to exclude. The
620
- case of tag names is not significant. This option is ignored for
621
- specifically requested tags. Tags may also be excluded by preceding their
622
- name with a '-' in the arguments to L</ImageInfo>.
618
+ Exclude specified tags when extracting information. Note that this option
619
+ is applied after all of the tags have already been loaded into memory (so
620
+ different tags may be excluded in subsequent calls to L</GetInfo>). See the
621
+ IgnoreTags option to save memory by not loading the tags in the first place.
622
+ The option value is either a tag name or reference to a list of tag names to
623
+ exclude. The case of tag names is not significant. This option is ignored
624
+ for specifically requested tags. Tags may also be excluded by preceding
625
+ their name with a '-' in the arguments to L</ImageInfo>.
623
626
 
624
627
  =item ExtendedXMP
625
628
 
@@ -2310,7 +2313,7 @@ APP5, APP6, APP8, ASF, Audible, CanonVRD, Composite, DICOM, DNG, DV, DjVu,
2310
2313
  Ducky, EXE, EXIF, ExifTool, FITS, FLAC, FLIR, File, Flash, FlashPix, Font,
2311
2314
  FotoStation, GIF, GIMP, GeoTiff, GoPro, H264, HTML, ICC_Profile, ID3, IPTC,
2312
2315
  ISO, ITC, JFIF, JPEG, JSON, JUMBF, Jpeg2000, LNK, Leaf, Lytro, M2TS, MIE,
2313
- MIFF, MNG, MOI, MPC, MPEG, MPF, MXF, MakerNotes, Matroska, Meta, Ogg,
2316
+ MIFF, MISB, MNG, MOI, MPC, MPEG, MPF, MXF, MakerNotes, Matroska, Meta, Ogg,
2314
2317
  OpenEXR, Opus, PDF, PICT, PLIST, PNG, PSP, Palm, Parrot, PanasonicRaw,
2315
2318
  PhotoCD, PhotoMechanic, Photoshop, PostScript, PrintIM, QuickTime, RAF,
2316
2319
  RIFF, RSRC, RTF, Radiance, Rawzor, Real, Red, SVG, SigmaRaw, Stim, Theora,
@@ -2333,7 +2336,7 @@ KyoceraRaw, LNK, Leaf, LeafSubIFD, Leica, Lyrics3, Lytro, M2TS, MAC,
2333
2336
  MIE-Audio, MIE-Camera, MIE-Canon, MIE-Doc, MIE-Extender, MIE-Flash, MIE-GPS,
2334
2337
  MIE-Geo, MIE-Image, MIE-Lens, MIE-Main, MIE-MakerNotes, MIE-Meta,
2335
2338
  MIE-Orient, MIE-Preview, MIE-Thumbnail, MIE-UTM, MIE-Unknown, MIE-Video,
2336
- MIFF, MNG, MOBI, MOI, MPC, MPEG, MPF0, MPImage, MS-DOC, MXF, MacOS,
2339
+ MIFF, MISB, MNG, MOBI, MOI, MPC, MPEG, MPF0, MPImage, MS-DOC, MXF, MacOS,
2337
2340
  MakerNotes, MakerUnknown, Matroska, MediaJukebox, Meta, MetaIFD, Microsoft,
2338
2341
  Minolta, MinoltaRaw, Motorola, NITF, Nikon, NikonCapture, NikonCustom,
2339
2342
  NikonScan, NikonSettings, NineEdits, Nintendo, Ocad, Ogg, Olympus, OpenEXR,