exiftool-vendored.pl 12.45.0 → 12.50.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 (57) hide show
  1. package/bin/Changes +122 -6
  2. package/bin/MANIFEST +12 -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 +89 -75
  10. package/bin/lib/Image/ExifTool/Apple.pm +6 -2
  11. package/bin/lib/Image/ExifTool/BuildTagLookup.pm +17 -9
  12. package/bin/lib/Image/ExifTool/Canon.pm +31 -14
  13. package/bin/lib/Image/ExifTool/CanonRaw.pm +8 -1
  14. package/bin/lib/Image/ExifTool/Exif.pm +13 -8
  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/Geotag.pm +1 -1
  19. package/bin/lib/Image/ExifTool/ICC_Profile.pm +1 -1
  20. package/bin/lib/Image/ExifTool/ICO.pm +143 -0
  21. package/bin/lib/Image/ExifTool/ID3.pm +5 -5
  22. package/bin/lib/Image/ExifTool/IPTC.pm +5 -1
  23. package/bin/lib/Image/ExifTool/M2TS.pm +98 -8
  24. package/bin/lib/Image/ExifTool/MIE.pm +9 -3
  25. package/bin/lib/Image/ExifTool/MISB.pm +494 -0
  26. package/bin/lib/Image/ExifTool/MakerNotes.pm +3 -1
  27. package/bin/lib/Image/ExifTool/Nikon.pm +220 -109
  28. package/bin/lib/Image/ExifTool/NikonSettings.pm +5 -3
  29. package/bin/lib/Image/ExifTool/Olympus.pm +2 -1
  30. package/bin/lib/Image/ExifTool/Panasonic.pm +21 -4
  31. package/bin/lib/Image/ExifTool/PanasonicRaw.pm +12 -5
  32. package/bin/lib/Image/ExifTool/Pentax.pm +7 -2
  33. package/bin/lib/Image/ExifTool/Photoshop.pm +29 -3
  34. package/bin/lib/Image/ExifTool/QuickTime.pm +78 -10
  35. package/bin/lib/Image/ExifTool/QuickTimeStream.pl +76 -5
  36. package/bin/lib/Image/ExifTool/README +5 -1
  37. package/bin/lib/Image/ExifTool/RIFF.pm +106 -9
  38. package/bin/lib/Image/ExifTool/Samsung.pm +2 -2
  39. package/bin/lib/Image/ExifTool/Sigma.pm +27 -1
  40. package/bin/lib/Image/ExifTool/SigmaRaw.pm +37 -13
  41. package/bin/lib/Image/ExifTool/Sony.pm +35 -16
  42. package/bin/lib/Image/ExifTool/TagInfoXML.pm +3 -1
  43. package/bin/lib/Image/ExifTool/TagLookup.pm +4700 -4520
  44. package/bin/lib/Image/ExifTool/TagNames.pod +4796 -4463
  45. package/bin/lib/Image/ExifTool/Text.pm +3 -4
  46. package/bin/lib/Image/ExifTool/Torrent.pm +2 -3
  47. package/bin/lib/Image/ExifTool/WriteCanonRaw.pl +7 -0
  48. package/bin/lib/Image/ExifTool/WriteExif.pl +19 -1
  49. package/bin/lib/Image/ExifTool/WriteRIFF.pl +359 -0
  50. package/bin/lib/Image/ExifTool/Writer.pl +6 -2
  51. package/bin/lib/Image/ExifTool/XMP.pm +72 -57
  52. package/bin/lib/Image/ExifTool/XMP2.pl +9 -1
  53. package/bin/lib/Image/ExifTool.pm +81 -18
  54. package/bin/lib/Image/ExifTool.pod +64 -60
  55. package/bin/perl-Image-ExifTool.spec +43 -43
  56. package/bin/pp_build_exe.args +7 -4
  57. 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.55';
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) {
@@ -2982,8 +2996,9 @@ sub AddFlattenedTags($;$$)
2982
2996
  } else {
2983
2997
  $$flatInfo{Groups}{2} = $tagG2;
2984
2998
  }
2985
- # save reference to top-level structure
2999
+ # save reference to top-level and parent structures
2986
3000
  $$flatInfo{RootTagInfo} = $$tagInfo{RootTagInfo} || $tagInfo;
3001
+ $$flatInfo{ParentTagInfo} = $tagInfo;
2987
3002
  # recursively generate flattened tags for sub-structures
2988
3003
  next unless $$flatInfo{Struct};
2989
3004
  length($flatID) > 250 and warn("Possible deep recursion for tag $flatID\n"), last;
@@ -538,7 +538,7 @@ my %sImageRegion = ( # new in 1.5
538
538
  NAMESPACE => 'Iptc4xmpExt',
539
539
  TABLE_DESC => 'XMP IPTC Extension',
540
540
  NOTES => q{
541
- This table contains tags defined by the IPTC Extension schema version 1.6
541
+ This table contains tags defined by the IPTC Extension schema version 1.7
542
542
  and IPTC Video Metadata version 1.3. The actual namespace prefix is
543
543
  "Iptc4xmpExt", but ExifTool shortens this for the family 1 group name. (See
544
544
  L<http://www.iptc.org/standards/photo-metadata/iptc-standard/> and
@@ -683,6 +683,7 @@ my %sImageRegion = ( # new in 1.5
683
683
  ProductName => { Writable => 'lang-alt' },
684
684
  ProductGTIN => { },
685
685
  ProductDescription => { Writable => 'lang-alt' },
686
+ ProductId => { }, # added in version 2022.1
686
687
  },
687
688
  List => 'Bag',
688
689
  },
@@ -1525,6 +1526,7 @@ my %sSubVersion = (
1525
1526
  ImageHistory => { Avoid => 1, Notes => 'different format from EXIF:ImageHistory' },
1526
1527
  LensCorrectionSettings => { },
1527
1528
  ImageUniqueID => { Avoid => 1 },
1529
+ picasawebGPhotoId => { }, #forum14108
1528
1530
  );
1529
1531
 
1530
1532
  # SWF namespace tags (ref PH)
@@ -1854,6 +1856,11 @@ my %sSubVersion = (
1854
1856
  MicroVideoVersion => { Writable => 'integer' },
1855
1857
  MicroVideoOffset => { Writable => 'integer' },
1856
1858
  MicroVideoPresentationTimestampUs => { Writable => 'integer' },
1859
+ shot_log_data => { #forum14108
1860
+ Name => 'ShotLogData',
1861
+ ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
1862
+ ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
1863
+ },
1857
1864
  );
1858
1865
 
1859
1866
  # Google creations namespace (ref PH)
@@ -1863,6 +1870,7 @@ my %sSubVersion = (
1863
1870
  NAMESPACE => 'GCreations',
1864
1871
  NOTES => 'Google creations tags.',
1865
1872
  CameraBurstID => { },
1873
+ Type => { Avoid => 1 },
1866
1874
  );
1867
1875
 
1868
1876
  # Google depth-map Device namespace (ref 13)
@@ -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.50';
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'],
@@ -599,6 +603,7 @@ my %fileDescription = (
599
603
  CRM => 'video/x-canon-crm',
600
604
  CRW => 'image/x-canon-crw',
601
605
  CSV => 'text/csv',
606
+ CUR => 'image/x-cursor', #PH (NC)
602
607
  CZI => 'image/x-zeiss-czi', #PH (NC)
603
608
  DCP => 'application/octet-stream', #PH (NC)
604
609
  DCR => 'image/x-kodak-dcr',
@@ -647,6 +652,7 @@ my %fileDescription = (
647
652
  HDR => 'image/vnd.radiance',
648
653
  HTML => 'text/html',
649
654
  ICC => 'application/vnd.iccprofile',
655
+ ICO => 'image/x-icon', #PH (NC)
650
656
  ICS => 'text/calendar',
651
657
  IDML => 'application/vnd.adobe.indesign-idml-package',
652
658
  IIQ => 'image/x-raw',
@@ -913,6 +919,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
913
919
  HDR => '#\?(RADIANCE|RGBE)\x0a',
914
920
  HTML => '(\xef\xbb\xbf)?\s*(?i)<(!DOCTYPE\s+HTML|HTML|\?xml)', # (case insensitive)
915
921
  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}',
922
+ ICO => '\0\0[\x01\x02]\0[^0]\0', # (reasonably assume that the file contains less than 256 images)
916
923
  IND => '\x06\x06\xed\xf5\xd8\x1d\x46\xe5\xbd\x31\xef\xe7\xfe\x74\xb7\x1d',
917
924
  # ISO => signature is at byte 32768
918
925
  ITC => '.{4}itch',
@@ -925,6 +932,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
925
932
  LNK => '.{4}\x01\x14\x02\0{5}\xc0\0{6}\x46',
926
933
  LRI => 'LELR \0',
927
934
  M2TS => '(....)?\x47',
935
+ MacOS=> '\0\x05\x16\x07\0.\0\0Mac OS X ',
928
936
  MIE => '~[\x10\x18]\x04.0MIE',
929
937
  MIFF => 'id=ImageMagick',
930
938
  MKV => '\x1a\x45\xdf\xa3',
@@ -972,7 +980,6 @@ $testLen = 1024; # number of bytes to read when testing for magic number
972
980
  WMF => '(\xd7\xcd\xc6\x9a\0\0|\x01\0\x09\0\0\x03)',
973
981
  WTV => '\xb7\xd8\x00\x20\x37\x49\xda\x11\xa6\x4e\x00\x07\xe9\x5e\xad\x8d',
974
982
  X3F => 'FOVb',
975
- MacOS=> '\0\x05\x16\x07\0.\0\0Mac OS X ',
976
983
  XCF => 'gimp xcf ',
977
984
  XMP => '\0{0,3}(\xfe\xff|\xff\xfe|\xef\xbb\xbf)?\0{0,3}\s*<',
978
985
  ZIP => 'PK\x03\x04',
@@ -3875,6 +3882,10 @@ sub CanWrite($)
3875
3882
  my $ext = GetFileExtension($file) || uc($file);
3876
3883
  return grep(/^$ext$/, @{$noWriteFile{$type}}) ? 0 : 1 if $ext;
3877
3884
  }
3885
+ if ($onlyWriteFile{$type}) {
3886
+ my $ext = GetFileExtension($file) || uc($file);
3887
+ return grep(/^$ext$/, @{$onlyWriteFile{$type}}) ? 1 : 0 if $ext;
3888
+ }
3878
3889
  unless (%writeTypes) {
3879
3890
  $writeTypes{$_} = 1 foreach @writeTypes;
3880
3891
  }
@@ -4042,6 +4053,57 @@ sub NextTagKey($$)
4042
4053
  return undef;
4043
4054
  }
4044
4055
 
4056
+ #------------------------------------------------------------------------------
4057
+ # Does a string contain valid UTF-8 characters?
4058
+ # Inputs: 0) string reference, 1) true to allow last character to be truncated
4059
+ # Returns: 0=regular ASCII, -1=invalid UTF-8, 1=valid UTF-8 with maximum 16-bit
4060
+ # wide characters, 2=valid UTF-8 requiring 32-bit wide characters
4061
+ # Notes: Changes current string position
4062
+ # (see http://www.fileformat.info/info/unicode/utf8.htm for help understanding this)
4063
+ sub IsUTF8($;$)
4064
+ {
4065
+ my ($strPt, $trunc) = @_;
4066
+ pos($$strPt) = 0; # start at beginning of string
4067
+ return 0 unless $$strPt =~ /([\x80-\xff])/g;
4068
+ my $rtnVal = 1;
4069
+ for (;;) {
4070
+ my $ch = ord($1);
4071
+ # minimum lead byte for 2-byte sequence is 0xc2 (overlong sequences
4072
+ # not allowed), 0xf8-0xfd are restricted by RFC 3629 (no 5 or 6 byte
4073
+ # sequences), and 0xfe and 0xff are not valid in UTF-8 strings
4074
+ return -1 if $ch < 0xc2 or $ch >= 0xf8;
4075
+ # determine number of bytes remaining in sequence
4076
+ my $n;
4077
+ if ($ch < 0xe0) {
4078
+ $n = 1;
4079
+ } elsif ($ch < 0xf0) {
4080
+ $n = 2;
4081
+ } else {
4082
+ $n = 3;
4083
+ # character code is greater than 0xffff if more than 2 extra bytes
4084
+ # were required in the UTF-8 character
4085
+ $rtnVal = 2;
4086
+ }
4087
+ my $pos = pos $$strPt;
4088
+ unless ($$strPt =~ /\G([\x80-\xbf]{$n})/g) {
4089
+ return $rtnVal if $trunc and $pos + $n > length $$strPt;
4090
+ return -1;
4091
+ }
4092
+ # the following is ref https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c
4093
+ if ($n == 2) {
4094
+ return -1 if ($ch == 0xe0 and (ord($1) & 0xe0) == 0x80) or
4095
+ ($ch == 0xed and (ord($1) & 0xe0) == 0xa0) or
4096
+ ($ch == 0xef and ord($1) == 0xbf and
4097
+ (ord(substr $1, 1) & 0xfe) == 0xbe);
4098
+ } else {
4099
+ return -1 if ($ch == 0xf0 and (ord($1) & 0xf0) == 0x80) or
4100
+ ($ch == 0xf4 and ord($1) > 0x8f) or $ch > 0xf4;
4101
+ }
4102
+ last unless $$strPt =~ /([\x80-\xff])/g;
4103
+ }
4104
+ return $rtnVal;
4105
+ }
4106
+
4045
4107
  #------------------------------------------------------------------------------
4046
4108
  # Split file name into directory and name parts
4047
4109
  # Inptus: 0) file name
@@ -4087,10 +4149,7 @@ sub EncodeFileName($$;$)
4087
4149
  }
4088
4150
  }
4089
4151
  } 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
- }
4152
+ $self->WarnOnce('FileName encoding not specified') if IsUTF8(\$file) < 0;
4094
4153
  }
4095
4154
  return 0;
4096
4155
  }
@@ -5704,8 +5763,8 @@ sub ConvertDateTime($$)
5704
5763
  $a[4] -= 1; # base month is 1
5705
5764
  # parse our %f fractional seconds first (and round up seconds if necessary)
5706
5765
  # - 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;
5766
+ if ($fmt =~ /%(-?)\.?(\d*)f/) {
5767
+ my ($neg, $dig) = ($1, $2);
5709
5768
  my $frac = $date =~ /(\.\d+)/ ? $1 : '';
5710
5769
  if (not $frac) {
5711
5770
  $frac = '.' . ('0' x $dig) if $dig;
@@ -5732,7 +5791,8 @@ sub ConvertDateTime($$)
5732
5791
  }
5733
5792
  }
5734
5793
  }
5735
- $fmt =~ s/(^|[^%])((%%)*)%\.?\d*f/$1$2$frac/g;
5794
+ $neg and $frac =~ s/^\.//;
5795
+ $fmt =~ s/(^|[^%])((%%)*)%-?\.?\d*f/$1$2$frac/g;
5736
5796
  }
5737
5797
  # parse %z and %s ourself (to handle time zones properly)
5738
5798
  if ($fmt =~ /%[sz]/) {
@@ -8061,6 +8121,7 @@ sub AddTagToTable($$;$$)
8061
8121
  unless (defined $$tagTablePtr{$tagID} or $specialTags{$tagID}) {
8062
8122
  $$tagTablePtr{$tagID} = $tagInfo;
8063
8123
  }
8124
+ $$tagInfo{AddedUnknown} = 1 if $$tagInfo{Unknown};
8064
8125
  return $tagInfo;
8065
8126
  }
8066
8127
 
@@ -8203,15 +8264,17 @@ sub FoundTag($$$;@)
8203
8264
  {
8204
8265
  local $_;
8205
8266
  my ($self, $tagInfo, $value, @grps) = @_;
8206
- my ($tag, $noListDel);
8267
+ my ($tag, $noListDel, $tbl);
8207
8268
  my $options = $$self{OPTIONS};
8208
8269
 
8209
8270
  if (ref $tagInfo eq 'HASH') {
8210
8271
  $tag = $$tagInfo{Name} or warn("No tag name\n"), return undef;
8272
+ $tbl = $$tagInfo{Table};
8211
8273
  } else {
8212
8274
  $tag = $tagInfo;
8213
8275
  # look for tag in Extra
8214
- $tagInfo = $self->GetTagInfo(GetTagTable('Image::ExifTool::Extra'), $tag);
8276
+ $tbl = GetTagTable('Image::ExifTool::Extra');
8277
+ $tagInfo = $self->GetTagInfo($tbl, $tag);
8215
8278
  # make temporary hash if tag doesn't exist in Extra
8216
8279
  # (not advised to do this since the tag won't show in list)
8217
8280
  $tagInfo or $tagInfo = { Name => $tag, Groups => \%allGroupsExifTool };
@@ -8220,7 +8283,7 @@ sub FoundTag($$$;@)
8220
8283
  # get tag priority
8221
8284
  my $priority = $$tagInfo{Priority};
8222
8285
  unless (defined $priority) {
8223
- $priority = $$tagInfo{Table}{PRIORITY};
8286
+ $priority = $$tbl{PRIORITY};
8224
8287
  $priority = 0 if not defined $priority and $$tagInfo{Avoid};
8225
8288
  }
8226
8289
  $grps[0] or $grps[0] = $$self{SET_GROUP0};