exiftool_vendored 11.97.0 → 12.09.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +196 -2
  3. data/bin/MANIFEST +8 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +43 -42
  7. data/bin/exiftool +150 -102
  8. data/bin/lib/Image/ExifTool.pm +162 -111
  9. data/bin/lib/Image/ExifTool.pod +123 -90
  10. data/bin/lib/Image/ExifTool/AIFF.pm +2 -2
  11. data/bin/lib/Image/ExifTool/APE.pm +2 -2
  12. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +21 -10
  13. data/bin/lib/Image/ExifTool/Canon.pm +201 -14
  14. data/bin/lib/Image/ExifTool/CanonCustom.pm +82 -16
  15. data/bin/lib/Image/ExifTool/DPX.pm +56 -2
  16. data/bin/lib/Image/ExifTool/DarwinCore.pm +22 -3
  17. data/bin/lib/Image/ExifTool/EXE.pm +8 -5
  18. data/bin/lib/Image/ExifTool/Exif.pm +15 -6
  19. data/bin/lib/Image/ExifTool/Font.pm +9 -2
  20. data/bin/lib/Image/ExifTool/GIF.pm +6 -1
  21. data/bin/lib/Image/ExifTool/GeoTiff.pm +2 -0
  22. data/bin/lib/Image/ExifTool/Geotag.pm +2 -2
  23. data/bin/lib/Image/ExifTool/GoPro.pm +48 -22
  24. data/bin/lib/Image/ExifTool/H264.pm +1 -1
  25. data/bin/lib/Image/ExifTool/HtmlDump.pm +2 -2
  26. data/bin/lib/Image/ExifTool/ID3.pm +91 -12
  27. data/bin/lib/Image/ExifTool/IPTC.pm +1 -0
  28. data/bin/lib/Image/ExifTool/JSON.pm +27 -4
  29. data/bin/lib/Image/ExifTool/Lang/de.pm +3 -1
  30. data/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
  31. data/bin/lib/Image/ExifTool/M2TS.pm +44 -24
  32. data/bin/lib/Image/ExifTool/MacOS.pm +152 -38
  33. data/bin/lib/Image/ExifTool/Matroska.pm +3 -1
  34. data/bin/lib/Image/ExifTool/Minolta.pm +7 -2
  35. data/bin/lib/Image/ExifTool/MinoltaRaw.pm +11 -10
  36. data/bin/lib/Image/ExifTool/Nikon.pm +163 -18
  37. data/bin/lib/Image/ExifTool/Olympus.pm +39 -17
  38. data/bin/lib/Image/ExifTool/PNG.pm +14 -3
  39. data/bin/lib/Image/ExifTool/PPM.pm +5 -5
  40. data/bin/lib/Image/ExifTool/Panasonic.pm +148 -14
  41. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +34 -0
  42. data/bin/lib/Image/ExifTool/Parrot.pm +2 -1
  43. data/bin/lib/Image/ExifTool/Pentax.pm +3 -1
  44. data/bin/lib/Image/ExifTool/Photoshop.pm +2 -1
  45. data/bin/lib/Image/ExifTool/QuickTime.pm +294 -34
  46. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +419 -60
  47. data/bin/lib/Image/ExifTool/README +26 -22
  48. data/bin/lib/Image/ExifTool/RIFF.pm +15 -3
  49. data/bin/lib/Image/ExifTool/RSRC.pm +17 -11
  50. data/bin/lib/Image/ExifTool/RTF.pm +12 -7
  51. data/bin/lib/Image/ExifTool/Radiance.pm +7 -2
  52. data/bin/lib/Image/ExifTool/Ricoh.pm +19 -1
  53. data/bin/lib/Image/ExifTool/Shift.pl +1 -0
  54. data/bin/lib/Image/ExifTool/SigmaRaw.pm +40 -33
  55. data/bin/lib/Image/ExifTool/Sony.pm +420 -34
  56. data/bin/lib/Image/ExifTool/TagLookup.pm +5799 -5671
  57. data/bin/lib/Image/ExifTool/TagNames.pod +583 -95
  58. data/bin/lib/Image/ExifTool/Validate.pm +4 -4
  59. data/bin/lib/Image/ExifTool/WriteExif.pl +3 -2
  60. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +26 -18
  61. data/bin/lib/Image/ExifTool/Writer.pl +44 -21
  62. data/bin/lib/Image/ExifTool/XMP.pm +99 -17
  63. data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
  64. data/bin/lib/Image/ExifTool/ZISRAW.pm +123 -0
  65. data/bin/perl-Image-ExifTool.spec +42 -41
  66. data/lib/exiftool_vendored/version.rb +1 -1
  67. metadata +8 -7
@@ -512,6 +512,7 @@ my %panasonicWhiteBalance = ( #forum9396
512
512
  # when format is int32u (S models), these values have been observed (ref IB):
513
513
  # 256 - Leica lens
514
514
  # 257 - Lumix lens
515
+ # 258 - ? (seen once)
515
516
  },
516
517
  0x1202 => { #IB
517
518
  Name => 'LensTypeModel',
@@ -531,14 +532,45 @@ my %panasonicWhiteBalance = ( #forum9396
531
532
  PrintConv => '"$val mm"',
532
533
  PrintConvInv => '$val=~s/\s*mm$//;$val',
533
534
  },
535
+ # 0x1300 - incident light value? (ref forum11395)
536
+ 0x1301 => { #forum11395
537
+ Name => 'ApertureValue',
538
+ Writable => 'int16s',
539
+ Priority => 0,
540
+ ValueConv => '2 ** ($val / 512)',
541
+ ValueConvInv => '$val>0 ? 512*log($val)/log(2) : 0',
542
+ PrintConv => 'sprintf("%.1f",$val)',
543
+ PrintConvInv => '$val',
544
+ },
545
+ 0x1302 => { #forum11395
546
+ Name => 'ShutterSpeedValue',
547
+ Writable => 'int16s',
548
+ Priority => 0,
549
+ ValueConv => 'abs($val/256)<100 ? 2**(-$val/256) : 0',
550
+ ValueConvInv => '$val>0 ? -256*log($val)/log(2) : -25600',
551
+ PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
552
+ PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
553
+ },
554
+ 0x1303 => { #forum11395
555
+ Name => 'SensitivityValue',
556
+ Writable => 'int16s',
557
+ ValueConv => '$val / 256',
558
+ ValueConvInv => 'int($val * 256)',
559
+ },
534
560
  0x1305 => { #forum9384
535
561
  Name => 'HighISOMode',
536
562
  Writable => 'int16u',
537
563
  RawConv => '$val || undef',
538
564
  PrintConv => { 1 => 'On', 2 => 'Off' },
539
565
  },
566
+ # 0x1306 EV for some models like the GX8 (forum11395)
540
567
  # 0x140b - scaled overall black level? (ref forum9281)
541
568
  # 0x1411 - scaled black level per channel difference (ref forum9281)
569
+ 0x1412 => { #forum11397
570
+ Name => 'FacesDetected',
571
+ Writable => 'int8u',
572
+ PrintConv => { 0 => 'No', 1 => 'Yes' },
573
+ },
542
574
  # 0x2000 - WB tungsten=3, daylight=4 (ref forum9467)
543
575
  # 0x2009 - scaled black level per channel (ref forum9281)
544
576
  # 0x3000-0x310b - red/blue balances * 1024 (ref forum9467)
@@ -600,6 +632,8 @@ my %panasonicWhiteBalance = ( #forum9396
600
632
  Writable => 'int8u',
601
633
  PrintConv => \%Image::ExifTool::Exif::orientation,
602
634
  },
635
+ # 0x3504 = Tag 0x1301+0x1302-0x1303 (Bv = Av+Tv-Sv) (forum11395)
636
+ # 0x3505 - same as 0x1300 (forum11395)
603
637
  0x3600 => { #forum9396
604
638
  Name => 'WhiteBalanceDetected',
605
639
  Writable => 'int8u',
@@ -13,7 +13,7 @@ package Image::ExifTool::Parrot;
13
13
  use strict;
14
14
  use vars qw($VERSION);
15
15
 
16
- $VERSION = '1.00';
16
+ $VERSION = '1.01';
17
17
 
18
18
  sub Process_mett($$$);
19
19
 
@@ -703,6 +703,7 @@ sub Process_mett($$$)
703
703
  $et->HandleTag($tagTbl, $id, undef,
704
704
  DataPt => $dataPt,
705
705
  DataPos => $dataPos,
706
+ Base => $$dirInfo{Base},
706
707
  Start => $pos,
707
708
  Size => $size,
708
709
  );
@@ -58,7 +58,7 @@ use Image::ExifTool::Exif;
58
58
  use Image::ExifTool::GPS;
59
59
  use Image::ExifTool::HP;
60
60
 
61
- $VERSION = '3.31';
61
+ $VERSION = '3.34';
62
62
 
63
63
  sub CryptShutterCount($$);
64
64
  sub PrintFilter($$$);
@@ -338,6 +338,7 @@ sub DecodeAFPoints($$$$;$);
338
338
  '8 63' => 'HD PENTAX-D FA 15-30mm F2.8 ED SDM WR', #PH
339
339
  '8 64' => 'HD PENTAX-D FA* 50mm F1.4 SDM AW', #27
340
340
  '8 65' => 'HD PENTAX-D FA 70-210mm F4 ED SDM WR', #PH
341
+ '8 66' => 'HD PENTAX-D FA 85mm F1.4 ED SDM AW', #James O'Neill
341
342
  '8 196' => 'HD PENTAX-DA* 11-18mm F2.8 ED DC AW', #29
342
343
  '8 197' => 'HD PENTAX-DA 55-300mm F4.5-6.3 ED PLM WR RE', #29
343
344
  '8 198' => 'smc PENTAX-DA L 18-50mm F4-5.6 DC WR RE', #29
@@ -546,6 +547,7 @@ my %pentaxModelID = (
546
547
  0x13222 => 'K-70', #29 (Ricoh)
547
548
  0x1322c => 'KP', #29 (Ricoh)
548
549
  0x13240 => 'K-1 Mark II', # (Ricoh)
550
+ 0x13290 => 'WG-70', # (Ricoh)
549
551
  );
550
552
 
551
553
  # Pentax city codes - (PH, Optio WP)
@@ -28,7 +28,7 @@ use strict;
28
28
  use vars qw($VERSION $AUTOLOAD $iptcDigestInfo);
29
29
  use Image::ExifTool qw(:DataAccess :Utils);
30
30
 
31
- $VERSION = '1.64';
31
+ $VERSION = '1.65';
32
32
 
33
33
  sub ProcessPhotoshop($$$);
34
34
  sub WritePhotoshop($$$);
@@ -982,6 +982,7 @@ sub ProcessPhotoshop($$$)
982
982
  DataPos => $$dirInfo{DataPos},
983
983
  Size => $size,
984
984
  Start => $pos,
985
+ Base => $$dirInfo{Base},
985
986
  Parent => $$dirInfo{DirName},
986
987
  );
987
988
  $size += 1 if $size & 0x01; # size is padded to an even # bytes
@@ -36,6 +36,7 @@
36
36
  # 24) https://github.com/sergiomb2/libmp4v2/wiki/iTunesMetadata
37
37
  # 25) https://cconcolato.github.io/mp4ra/atoms.html
38
38
  # 26) https://github.com/SamsungVR/android_upload_sdk/blob/master/SDKLib/src/main/java/com/samsung/msca/samsungvr/sdk/UserVideo.java
39
+ # 27) https://exiftool.org/forum/index.php?topic=11517.0
39
40
  #------------------------------------------------------------------------------
40
41
 
41
42
  package Image::ExifTool::QuickTime;
@@ -46,7 +47,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
46
47
  use Image::ExifTool::Exif;
47
48
  use Image::ExifTool::GPS;
48
49
 
49
- $VERSION = '2.47';
50
+ $VERSION = '2.54';
50
51
 
51
52
  sub ProcessMOV($$;$);
52
53
  sub ProcessKeys($$$);
@@ -105,7 +106,9 @@ my %mimeLookup = (
105
106
  MQV => 'video/quicktime',
106
107
  HEIC => 'image/heic',
107
108
  HEVC => 'image/heic-sequence',
109
+ HEICS=> 'image/heic-sequence',
108
110
  HEIF => 'image/heif',
111
+ HEIFS=> 'image/heif-sequence',
109
112
  AVIF => 'image/avif', #PH (NC)
110
113
  CRX => 'video/x-canon-crx', # (will get overridden)
111
114
  );
@@ -418,7 +421,8 @@ my %eeBox = (
418
421
  sbtl => { %eeStd },
419
422
  data => { %eeStd },
420
423
  camm => { %eeStd }, # (Insta360)
421
- '' => { 'gps ' => 'moov' }, # (no handler -- in top level 'moov' box)
424
+ ctbx => { %eeStd }, # (GM cars)
425
+ '' => { 'gps ' => 'moov', 'GPS ' => 'main' }, # (no handler -- in top level 'moov' box, and main)
422
426
  );
423
427
 
424
428
  # QuickTime atoms
@@ -555,6 +559,20 @@ my %eeBox = (
555
559
  Start => 16,
556
560
  },
557
561
  },
562
+ { # (ref https://github.com/JamesHeinrich/getID3/blob/master/getid3/module.audio-video.quicktime.php)
563
+ Name => 'SensorData', # sensor data for the 360Fly
564
+ Condition => '$$valPt=~/^\xef\xe1\x58\x9a\xbb\x77\x49\xef\x80\x95\x27\x75\x9e\xb1\xdc\x6f/ and $$self{OPTIONS}{ExtractEmbedded}',
565
+ SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Tags360Fly' },
566
+ },
567
+ {
568
+ Name => 'SensorData',
569
+ Condition => '$$valPt=~/^\xef\xe1\x58\x9a\xbb\x77\x49\xef\x80\x95\x27\x75\x9e\xb1\xdc\x6f/',
570
+ Notes => 'raw 360Fly sensor data without ExtractEmbedded option',
571
+ RawConv => q{
572
+ $self->WarnOnce('Use the ExtractEmbedded option to decode timed SensorData',3);
573
+ return \$val;
574
+ },
575
+ },
558
576
  { #PH (Canon CR3)
559
577
  Name => 'PreviewImage',
560
578
  Condition => '$$valPt=~/^\xea\xf4\x2b\x5e\x1c\x98\x4b\x88\xb9\xfb\xb7\xdc\x40\x6e\x4d\x16/',
@@ -589,6 +607,11 @@ my %eeBox = (
589
607
  Groups => { 2 => 'Preview' },
590
608
  Binary => 1,
591
609
  },
610
+ 'thm ' => { #PH (70mai A800)
611
+ Name => 'ThumbnailImage',
612
+ Groups => { 2 => 'Preview' },
613
+ Binary => 1,
614
+ },
592
615
  ardt => { #PH
593
616
  Name => 'ARDroneFile',
594
617
  ValueConv => 'length($val) > 4 ? substr($val,4) : $val', # remove length
@@ -667,6 +690,11 @@ my %eeBox = (
667
690
  },
668
691
  # gpsa - seen hex "01 20 00 00" (DuDuBell M1, VSYS M6L)
669
692
  # gsea - 20 bytes hex "05 00's..." (DuDuBell M1) "05 08 02 01 ..." (VSYS M6L)
693
+ 'GPS ' => { # GPS data written by 70mai dashcam (parsed in QuickTimeStream.pl)
694
+ Name => 'GPSDataList2',
695
+ Unknown => 1,
696
+ Binary => 1,
697
+ },
670
698
  );
671
699
 
672
700
  # MPEG-4 'ftyp' atom
@@ -962,7 +990,7 @@ my %eeBox = (
962
990
  %Image::ExifTool::QuickTime::CleanAperture = (
963
991
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
964
992
  GROUPS => { 2 => 'Video' },
965
- FORMAT => 'rational64u',
993
+ FORMAT => 'rational64s',
966
994
  0 => 'CleanApertureWidth',
967
995
  1 => 'CleanApertureHeight',
968
996
  2 => 'CleanApertureOffsetX',
@@ -1307,6 +1335,7 @@ my %eeBox = (
1307
1335
  Format => 'fixed32s[9]',
1308
1336
  Notes => 'writable for the video track via the Composite Rotation tag',
1309
1337
  Writable => 1,
1338
+ Protected => 1,
1310
1339
  Permanent => 1,
1311
1340
  # only set rotation if image size is non-zero
1312
1341
  RawConvInv => \&GetMatrixStructure,
@@ -1371,8 +1400,8 @@ my %eeBox = (
1371
1400
  },
1372
1401
  ValueConvInv => q{
1373
1402
  require Image::ExifTool::XMP;
1374
- $val = Image::ExifTool::XMP::FormatXMPDate($val);
1375
- $val =~ s/([-+]\d{2}):(\d{2})$/$1$2/; # remove time zone colon
1403
+ my $tmp = Image::ExifTool::XMP::FormatXMPDate($val);
1404
+ ($val = $tmp) =~ s/([-+]\d{2}):(\d{2})$/$1$2/ if defined $tmp; # remove time zone colon
1376
1405
  return $val;
1377
1406
  },
1378
1407
  PrintConv => '$self->ConvertDateTime($val)',
@@ -1628,10 +1657,14 @@ my %eeBox = (
1628
1657
  Avoid => 1,
1629
1658
  Format => 'string', # (necessary to remove the trailing NULL)
1630
1659
  },
1631
- date => { # (NC)
1660
+ date => {
1632
1661
  Name => 'DateTimeOriginal',
1633
1662
  Description => 'Date/Time Original',
1634
1663
  Groups => { 2 => 'Time' },
1664
+ Notes => q{
1665
+ Apple Photos has been reported to show a crazy date/time for some MP4 files
1666
+ containing this tag, but perhaps only if it is missing a time zone
1667
+ }, #forum10690/11125
1635
1668
  Shift => 'Time',
1636
1669
  ValueConv => q{
1637
1670
  require Image::ExifTool::XMP;
@@ -1853,6 +1886,25 @@ my %eeBox = (
1853
1886
  ByteOrder => 'LittleEndian',
1854
1887
  },
1855
1888
  },
1889
+ # ---- Garmin ---- (ref PH)
1890
+ uuid => [{
1891
+ Name => 'GarminSoftware', # (NC)
1892
+ Condition => '$$valPt =~ /^VIRBactioncamera/',
1893
+ RawConv => 'substr($val, 16)',
1894
+ RawConvInv => '"VIRBactioncamera$val"',
1895
+ },{
1896
+ # have seen "28 f3 11 e2 b7 91 4f 6f 94 e2 4f 5d ea cb 3c 01" for RicohThetaZ1 accelerometer RADT data (not yet decoded)
1897
+ Name => 'UUID-Unknown',
1898
+ Writable => 0,
1899
+ %unknownInfo,
1900
+ }],
1901
+ pmcc => {
1902
+ Name => 'GarminSettings',
1903
+ ValueConv => 'substr($val, 4)',
1904
+ ValueConvInv => '"\0\0\0\x01$val"',
1905
+ },
1906
+ # hmtp - "\0\0\0\x01" followed by 408 bytes of zero
1907
+ # vrin - "\0\0\0\x01" followed by 8 bytes of zero
1856
1908
  # ---- GoPro ---- (ref PH)
1857
1909
  GoPr => 'GoProType', # (Hero3+)
1858
1910
  FIRM => { Name => 'FirmwareVersion', Avoid => 1 }, # (Hero4)
@@ -1866,7 +1918,7 @@ my %eeBox = (
1866
1918
  # SETT? 12 bytes (Hero4)
1867
1919
  # MUID? 32 bytes (Hero4, starts with serial number hash)
1868
1920
  # HMMT? 404 bytes (Hero4, all zero)
1869
- # BCID? 26 bytes (Hero5, all zero)
1921
+ # BCID? 26 bytes (Hero5, all zero), 36 bytes GoPro Max
1870
1922
  # GUMI? 16 bytes (Hero5)
1871
1923
  "FOV\0" => 'FieldOfView', #forum8938 (Hero2) seen: "Wide"
1872
1924
  GPMF => {
@@ -2036,6 +2088,63 @@ my %eeBox = (
2036
2088
  ProcessProc => \&Image::ExifTool::ProcessTIFF, # (because ProcessMOV is default)
2037
2089
  },
2038
2090
  },
2091
+ '@mak' => { Name => 'Make', Avoid => 1 },
2092
+ '@mod' => { Name => 'Model', Avoid => 1 },
2093
+ '@swr' => { Name => 'SoftwareVersion', Avoid => 1 },
2094
+ '@day' => {
2095
+ Name => 'ContentCreateDate',
2096
+ Notes => q{
2097
+ some stupid Ricoh programmer used the '@' symbol instead of the copyright
2098
+ symbol in these tag ID's for the Ricoh Theta Z1 and maybe other models
2099
+ },
2100
+ Groups => { 2 => 'Time' },
2101
+ Shift => 'Time',
2102
+ Avoid => 1,
2103
+ # handle values in the form "2010-02-12T13:27:14-0800"
2104
+ ValueConv => q{
2105
+ require Image::ExifTool::XMP;
2106
+ $val = Image::ExifTool::XMP::ConvertXMPDate($val);
2107
+ $val =~ s/([-+]\d{2})(\d{2})$/$1:$2/; # add colon to timezone if necessary
2108
+ return $val;
2109
+ },
2110
+ ValueConvInv => q{
2111
+ require Image::ExifTool::XMP;
2112
+ my $tmp = Image::ExifTool::XMP::FormatXMPDate($val);
2113
+ ($val = $tmp) =~ s/([-+]\d{2}):(\d{2})$/$1$2/ if defined $tmp; # remove time zone colon
2114
+ return $val;
2115
+ },
2116
+ PrintConv => '$self->ConvertDateTime($val)',
2117
+ PrintConvInv => '$self->InverseDateTime($val)',
2118
+ },
2119
+ '@xyz' => { #PH (iPhone 3GS)
2120
+ Name => 'GPSCoordinates',
2121
+ Groups => { 2 => 'Location' },
2122
+ Avoid => 1,
2123
+ ValueConv => \&ConvertISO6709,
2124
+ ValueConvInv => \&ConvInvISO6709,
2125
+ PrintConv => \&PrintGPSCoordinates,
2126
+ PrintConvInv => \&PrintInvGPSCoordinates,
2127
+ },
2128
+ # RDT1 - pairs of int32u_BE, starting at byte 8: "458275 471846"
2129
+ # RDT2 - pairs of int32u_BE, starting at byte 8: "472276 468526"
2130
+ # RDT3 - pairs of int32u_BE, starting at byte 8: "876603 482191"
2131
+ # RDT4 - pairs of int32u_BE, starting at byte 8: "1955 484612"
2132
+ # RDT6 - empty
2133
+ # RDT7 - empty
2134
+ # RDT8 - empty
2135
+ # RDT9 - only 16-byte header?
2136
+ # the boxes below all have a similar header (little-endian):
2137
+ # 0 int32u - number of records
2138
+ # 4 ? - "1e 00"
2139
+ # 6 int16u - record length in bytes
2140
+ # 8 ? - "23 01 00 00 00 00 00 00"
2141
+ # 16 - start of records (each record ends in an int64u timestamp in ns)
2142
+ # RDTA - float[4],ts: "-0.31289672 -0.2245330 11.303817 0 775.780"
2143
+ # RDTB - float[4],ts: "-0.04841613 -0.2166595 0.0724792 0 775.780"
2144
+ # RDTC - float[4],ts: "27.60925 -27.10037 -13.27285 0 775.829"
2145
+ # RDTD - int16s[3],ts: "353 -914 16354 0 775.829"
2146
+ # RDTG - ts: "775.825"
2147
+ # RDTI - float[4],ts: "0.00165951 0.005770059 0.06838259 0.1744695 775.862"
2039
2148
  # ---- Samsung ----
2040
2149
  vndr => 'Vendor', #PH (Samsung PL70)
2041
2150
  SDLN => 'PlayMode', #PH (NC, Samsung ST80 "SEQ_PLAY")
@@ -2446,7 +2555,23 @@ my %eeBox = (
2446
2555
  Start => 4,
2447
2556
  },
2448
2557
  },
2449
- # idat
2558
+ idat => {
2559
+ Name => 'MetaImageSize', #PH (NC)
2560
+ Format => 'int16u',
2561
+ # (don't know what the first two numbers are for)
2562
+ PrintConv => '$val =~ s/^(\d+) (\d+) (\d+) (\d+)/${3}x$4/; $val',
2563
+ },
2564
+ uuid => [
2565
+ { #PH (Canon R5/R6 HIF)
2566
+ Name => 'MetaVersion', # (NC)
2567
+ Condition => '$$valPt=~/^\x85\xc0\xb6\x87\x82\x0f\x11\xe0\x81\x11\xf4\xce\x46\x2b\x6a\x48/',
2568
+ RawConv => 'substr($val, 0x14)',
2569
+ },
2570
+ {
2571
+ Name => 'UUID-Unknown',
2572
+ %unknownInfo,
2573
+ },
2574
+ ],
2450
2575
  );
2451
2576
 
2452
2577
  # additional metadata container (ref ISO14496-12:2015)
@@ -2512,6 +2637,7 @@ my %eeBox = (
2512
2637
  Name => 'Rotation',
2513
2638
  Format => 'int8u',
2514
2639
  Writable => 'int8u',
2640
+ Protected => 1,
2515
2641
  ValueConv => '$val * 90',
2516
2642
  ValueConvInv => 'int($val / 90 + 0.5)',
2517
2643
  },
@@ -2543,6 +2669,7 @@ my %eeBox = (
2543
2669
  Name => 'PixelAspectRatio',
2544
2670
  Format => 'int32u',
2545
2671
  Writable => 'int32u',
2672
+ Protected => 1,
2546
2673
  },
2547
2674
  rloc => {
2548
2675
  Name => 'RelativeLocation',
@@ -2551,7 +2678,7 @@ my %eeBox = (
2551
2678
  },
2552
2679
  clap => {
2553
2680
  Name => 'CleanAperture',
2554
- Format => 'rational64u',
2681
+ Format => 'rational64s',
2555
2682
  Notes => '4 numbers: width, height, left and top',
2556
2683
  },
2557
2684
  hvcC => {
@@ -2756,12 +2883,16 @@ my %eeBox = (
2756
2883
  WRITE_PROC => \&WriteQuickTime,
2757
2884
  GROUPS => { 2 => 'Image' },
2758
2885
  # (Note: ExifTool's ItemRefVersion may be used to test the iref version number)
2759
- # dimg - DerivedImage
2760
- # thmb - Thumbnail
2761
- # auxl - AuxiliaryImage
2886
+ NOTES => q{
2887
+ The Item reference entries listed in the table below contain information about
2888
+ the associations between items in the file. This information is used by
2889
+ ExifTool, but these entries are not extracted as tags.
2890
+ },
2891
+ dimg => { Name => 'DerivedImageRef', RawConv => 'undef' },
2892
+ thmb => { Name => 'ThumbnailRef', RawConv => 'undef' },
2893
+ auxl => { Name => 'AuxiliaryImageRef', RawConv => 'undef' },
2762
2894
  cdsc => {
2763
2895
  Name => 'ContentDescribes',
2764
- Notes => 'parsed, but not extracted as a tag',
2765
2896
  RawConv => \&ParseContentDescribes,
2766
2897
  WriteHook => \&ParseContentDescribes,
2767
2898
  },
@@ -2889,10 +3020,25 @@ my %eeBox = (
2889
3020
  "\xa9grp" => 'Grouping',
2890
3021
  "\xa9lyr" => 'Lyrics',
2891
3022
  "\xa9nam" => 'Title',
2892
- # "\xa9st3" ? #10
2893
3023
  "\xa9too" => 'Encoder',
2894
3024
  "\xa9trk" => 'Track',
2895
3025
  "\xa9wrt" => 'Composer',
3026
+ #
3027
+ # the following tags written by AtomicParsley 0.9.6
3028
+ # (ref https://exiftool.org/forum/index.php?topic=11455.0)
3029
+ #
3030
+ "\xa9st3" => 'Subtitle',
3031
+ "\xa9con" => 'Conductor',
3032
+ "\xa9sol" => 'Soloist',
3033
+ "\xa9arg" => 'Arranger',
3034
+ "\xa9ope" => 'OriginalArtist',
3035
+ "\xa9dir" => 'Director',
3036
+ "\xa9ard" => 'ArtDirector',
3037
+ "\xa9sne" => 'SoundEngineer',
3038
+ "\xa9prd" => 'Producer',
3039
+ "\xa9xpd" => 'ExecutiveProducer',
3040
+ sdes => 'StoreDescription',
3041
+ #
2896
3042
  '----' => {
2897
3043
  Name => 'iTunesInfo',
2898
3044
  SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::iTunesInfo' },
@@ -2901,18 +3047,29 @@ my %eeBox = (
2901
3047
  covr => { Name => 'CoverArt', Groups => { 2 => 'Preview' } },
2902
3048
  cpil => { #10
2903
3049
  Name => 'Compilation',
2904
- Format => 'int8u', #23
3050
+ Format => 'int8u', #27 (ref 23 contradicts what AtomicParsley actually writes, which is int8s)
3051
+ Writable => 'int8s',
2905
3052
  PrintConv => { 0 => 'No', 1 => 'Yes' },
2906
3053
  },
2907
3054
  disk => {
2908
3055
  Name => 'DiskNumber',
2909
3056
  Format => 'undef', # (necessary to prevent decoding as string!)
2910
- ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val',
2911
- ValueConvInv => 'my @a = split / of /, $val; @a==2 ? pack("n3",0,@a) : undef',
3057
+ ValueConv => q{
3058
+ return \$val unless length($val) >= 6;
3059
+ my @a = unpack 'x2nn', $val;
3060
+ return $a[1] ? join(' of ', @a) : $a[0];
3061
+ },
3062
+ ValueConvInv => q{
3063
+ my @a = $val =~ /\d+/g;
3064
+ return undef if @a == 0 or @a > 2;
3065
+ push @a, 0 if @a == 1;
3066
+ return pack('n3', 0, @a);
3067
+ },
2912
3068
  },
2913
3069
  pgap => { #10
2914
3070
  Name => 'PlayGap',
2915
3071
  Format => 'int8u', #23
3072
+ Writable => 'int8s', #27
2916
3073
  PrintConv => {
2917
3074
  0 => 'Insert Gap',
2918
3075
  1 => 'No Gap',
@@ -2920,13 +3077,26 @@ my %eeBox = (
2920
3077
  },
2921
3078
  tmpo => {
2922
3079
  Name => 'BeatsPerMinute',
2923
- Format => 'int16u', # marked as boolean but really int16u in my sample
3080
+ # marked as boolean but really int16u in my sample
3081
+ # (but written as int16s by iTunes and AtomicParsley, ref forum11506)
3082
+ Format => 'int16u',
3083
+ Writable => 'int16s',
2924
3084
  },
2925
3085
  trkn => {
2926
3086
  Name => 'TrackNumber',
2927
3087
  Format => 'undef', # (necessary to prevent decoding as string!)
2928
- ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val',
2929
- ValueConvInv => 'my @a = split / of /, $val; @a==2 ? pack("n3",0,@a) : undef',
3088
+ ValueConv => q{
3089
+ return \$val unless length($val) >= 6;
3090
+ my @a = unpack 'x2nn', $val;
3091
+ return $a[1] ? join(' of ', @a) : $a[0];
3092
+ },
3093
+ # (see forum11501 for discussion about the format used)
3094
+ ValueConvInv => q{
3095
+ my @a = $val =~ /\d+/g;
3096
+ return undef if @a == 0 or @a > 2;
3097
+ push @a, 0 if @a == 1;
3098
+ return pack('n4', 0, @a, 0);
3099
+ },
2930
3100
  },
2931
3101
  #
2932
3102
  # Note: it is possible that the tags below are not being decoded properly
@@ -2935,6 +3105,7 @@ my %eeBox = (
2935
3105
  akID => { #10
2936
3106
  Name => 'AppleStoreAccountType',
2937
3107
  Format => 'int8u', #24
3108
+ Writable => 'int8s', #27
2938
3109
  PrintConv => {
2939
3110
  0 => 'iTunes',
2940
3111
  1 => 'AOL',
@@ -2945,12 +3116,14 @@ my %eeBox = (
2945
3116
  atID => { #10 (or TV series)
2946
3117
  Name => 'AlbumTitleID',
2947
3118
  Format => 'int32u',
3119
+ Writable => 'int32s', #27
2948
3120
  },
2949
3121
  auth => { Name => 'Author', Groups => { 2 => 'Author' } },
2950
3122
  catg => 'Category', #7
2951
3123
  cnID => { #10
2952
3124
  Name => 'AppleStoreCatalogID',
2953
3125
  Format => 'int32u',
3126
+ Writable => 'int32s', #27
2954
3127
  },
2955
3128
  cprt => { Name => 'Copyright', Groups => { 2 => 'Author' } },
2956
3129
  dscp => { Name => 'Description', Avoid => 1 },
@@ -2958,22 +3131,28 @@ my %eeBox = (
2958
3131
  gnre => { #10
2959
3132
  Name => 'Genre',
2960
3133
  Avoid => 1,
2961
- # (Note: not written as int16u if numerical, although it should be)
3134
+ # (Note: see https://exiftool.org/forum/index.php?topic=11537.0)
3135
+ Format => 'undef',
3136
+ ValueConv => 'unpack("n",$val)',
3137
+ ValueConvInv => '$val =~ /^\d+$/ ? pack("n",$val) : undef',
2962
3138
  PrintConv => q{
2963
3139
  return $val unless $val =~ /^\d+$/;
2964
3140
  require Image::ExifTool::ID3;
2965
3141
  Image::ExifTool::ID3::PrintGenre($val - 1); # note the "- 1"
2966
3142
  },
2967
3143
  PrintConvInv => q{
3144
+ return $val if $val =~ /^[0-9]+$/;
2968
3145
  require Image::ExifTool::ID3;
2969
3146
  my $id = Image::ExifTool::ID3::GetGenreID($val);
2970
- return defined $id ? $id : $val;
2971
- },
3147
+ return unless defined $id and $id =~ /^\d+$/;
3148
+ return $id + 1;
3149
+ },
2972
3150
  },
2973
3151
  egid => 'EpisodeGlobalUniqueID', #7
2974
3152
  geID => { #10
2975
3153
  Name => 'GenreID',
2976
3154
  Format => 'int32u',
3155
+ Writable => 'int32s', #27
2977
3156
  SeparateTable => 1,
2978
3157
  # the following lookup is based on http://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/genres
2979
3158
  # (see scripts/parse_genre to parse genre JSON file from above)
@@ -5626,6 +5805,7 @@ my %eeBox = (
5626
5805
  hdvd => { #10
5627
5806
  Name => 'HDVideo',
5628
5807
  Format => 'int8u', #24
5808
+ Writable => 'int8s', #27
5629
5809
  PrintConv => { 0 => 'No', 1 => 'Yes' },
5630
5810
  },
5631
5811
  keyw => 'Keyword', #7
@@ -5633,18 +5813,21 @@ my %eeBox = (
5633
5813
  pcst => { #7
5634
5814
  Name => 'Podcast',
5635
5815
  Format => 'int8u', #23
5816
+ Writable => 'int8s', #27
5636
5817
  PrintConv => { 0 => 'No', 1 => 'Yes' },
5637
5818
  },
5638
5819
  perf => 'Performer',
5639
5820
  plID => { #10 (or TV season)
5640
5821
  Name => 'PlayListID',
5641
5822
  Format => 'int8u', # actually int64u, but split it up
5823
+ Writable => 'int32s', #27
5642
5824
  },
5643
5825
  purd => 'PurchaseDate', #7
5644
5826
  purl => 'PodcastURL', #7
5645
5827
  rtng => { #10
5646
5828
  Name => 'Rating',
5647
5829
  Format => 'int8u', #23
5830
+ Writable => 'int8s', #27
5648
5831
  PrintConv => {
5649
5832
  0 => 'none',
5650
5833
  1 => 'Explicit',
@@ -5655,6 +5838,7 @@ my %eeBox = (
5655
5838
  sfID => { #10
5656
5839
  Name => 'AppleStoreCountry',
5657
5840
  Format => 'int32u',
5841
+ Writable => 'int32s', #27
5658
5842
  SeparateTable => 1,
5659
5843
  PrintConv => { #21
5660
5844
  143441 => 'United States', # US
@@ -5823,6 +6007,7 @@ my %eeBox = (
5823
6007
  stik => { #10
5824
6008
  Name => 'MediaType',
5825
6009
  Format => 'int8u', #23
6010
+ Writable => 'int8s', #27
5826
6011
  PrintConvColumns => 2,
5827
6012
  PrintConv => { #(http://weblog.xanga.com/gryphondwb/615474010/iphone-ringtones---what-did-itunes-741-really-do.html)
5828
6013
  0 => 'Movie (old)', #forum9059 (was Movie)
@@ -5844,6 +6029,7 @@ my %eeBox = (
5844
6029
  tves => { #7/10
5845
6030
  Name => 'TVEpisode',
5846
6031
  Format => 'int32u',
6032
+ Writable => 'int32s', #27
5847
6033
  },
5848
6034
  tvnn => 'TVNetworkName', #7
5849
6035
  tvsh => 'TVShow', #10
@@ -5854,7 +6040,8 @@ my %eeBox = (
5854
6040
  yrrc => 'Year', #(ffmpeg source)
5855
6041
  itnu => { #PH (iTunes 10.5)
5856
6042
  Name => 'iTunesU',
5857
- Format => 'int8s',
6043
+ Format => 'int8u', #27
6044
+ Writable => 'int8s', #27
5858
6045
  Description => 'iTunes U',
5859
6046
  PrintConv => { 0 => 'No', 1 => 'Yes' },
5860
6047
  },
@@ -5904,6 +6091,27 @@ my %eeBox = (
5904
6091
  PrintConv => \&PrintGPSCoordinates,
5905
6092
  PrintConvInv => \&PrintInvGPSCoordinates,
5906
6093
  },
6094
+ # the following tags written by iTunes 12.5.1.21
6095
+ # (ref https://www.ventismedia.com/mantis/view.php?id=14963
6096
+ # https://community.mp3tag.de/t/x-mp4-new-tag-problems/19488)
6097
+ "\xa9wrk" => 'Work', #PH
6098
+ "\xa9mvn" => 'MovementName', #PH
6099
+ "\xa9mvi" => { #PH
6100
+ Name => 'MovementNumber',
6101
+ Format => 'int16u', #27
6102
+ Writable => 'int16s', #27
6103
+ },
6104
+ "\xa9mvc" => { #PH
6105
+ Name => 'MovementCount',
6106
+ Format => 'int16u', #27
6107
+ Writable => 'int16s', #27
6108
+ },
6109
+ shwm => { #PH
6110
+ Name => 'ShowMovement',
6111
+ Format => 'int8u', #27
6112
+ Writable => 'int8s', #27
6113
+ PrintConv => { 0 => 'No', 1 => 'Yes' },
6114
+ },
5907
6115
  );
5908
6116
 
5909
6117
  # tag decoded from timed face records
@@ -6123,6 +6331,21 @@ my %eeBox = (
6123
6331
  'detected-face.roll-angle' => { Name => 'DetectedFaceRollAngle', Writable => 0 },
6124
6332
  # (fiel)com.apple.quicktime.detected-face.yaw-angle (dtyp=23, float)
6125
6333
  'detected-face.yaw-angle' => { Name => 'DetectedFaceYawAngle', Writable => 0 },
6334
+ #
6335
+ # seen in Apple ProRes RAW file
6336
+ #
6337
+ # (mdta)com.apple.proapps.manufacturer (eg. "Sony")
6338
+ # (mdta)com.apple.proapps.exif.{Exif}.FNumber (float, eg. 1.0)
6339
+ # (mdta)org.smpte.rdd18.lens.irisfnumber (eg. "F1.0")
6340
+ # (mdta)com.apple.proapps.exif.{Exif}.ShutterSpeedValue (float, eg. 1.006)
6341
+ # (mdta)org.smpte.rdd18.camera.shutterspeed_angle (eg. "179.2deg")
6342
+ # (mdta)org.smpte.rdd18.camera.neutraldensityfilterwheelsetting (eg. "ND1")
6343
+ # (mdta)org.smpte.rdd18.camera.whitebalance (eg. "4300K")
6344
+ # (mdta)com.apple.proapps.exif.{Exif}.ExposureIndex (float, eg. 4000)
6345
+ # (mdta)org.smpte.rdd18.camera.isosensitivity (eg. "4000")
6346
+ # (mdta)com.apple.proapps.image.{TIFF}.Make (eg. "Atmos")
6347
+ # (mdta)com.apple.proapps.image.{TIFF}.Model (eg. "ShogunInferno")
6348
+ # (mdta)com.apple.proapps.image.{TIFF}.Software (eg. "9.0")
6126
6349
  );
6127
6350
 
6128
6351
  # iTunes info ('----') atoms
@@ -6663,7 +6886,7 @@ my %eeBox = (
6663
6886
  #
6664
6887
  # AudioFormat Offset Child atoms
6665
6888
  # ----------- ------ ----------------
6666
- # mp4a 52 * wave, chan, esds, SA3D(Insta360 spherical video params?)
6889
+ # mp4a 52 * wave, chan, esds, SA3D(Insta360 spherical video params?,also GoPro Max)
6667
6890
  # in24 52 wave, chan
6668
6891
  # "ms\0\x11" 52 wave
6669
6892
  # sowt 52 chan
@@ -6700,6 +6923,7 @@ my %eeBox = (
6700
6923
  # alac - 28 bytes
6701
6924
  # adrm - AAX DRM atom? 148 bytes
6702
6925
  # aabd - AAX unknown 17kB (contains 'aavd' strings)
6926
+ # SA3D - written by Garmin VIRB360
6703
6927
  );
6704
6928
 
6705
6929
  # AMR decode config box (ref 3)
@@ -6730,13 +6954,28 @@ my %eeBox = (
6730
6954
  Name => 'SchemeInfo',
6731
6955
  SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::SchemeInfo' },
6732
6956
  },
6957
+ enda => {
6958
+ Name => 'Endianness',
6959
+ Format => 'int16u',
6960
+ PrintConv => {
6961
+ 0 => 'Big-endian (Motorola, MM)',
6962
+ 1 => 'Little-endian (Intel, II)',
6963
+ },
6964
+ },
6733
6965
  # skcr
6734
- # enda
6735
6966
  );
6736
6967
 
6737
6968
  %Image::ExifTool::QuickTime::Wave = (
6738
6969
  PROCESS_PROC => \&ProcessMOV,
6739
6970
  frma => 'PurchaseFileFormat',
6971
+ enda => {
6972
+ Name => 'Endianness',
6973
+ Format => 'int16u',
6974
+ PrintConv => {
6975
+ 0 => 'Big-endian (Motorola, MM)',
6976
+ 1 => 'Little-endian (Intel, II)',
6977
+ },
6978
+ },
6740
6979
  # "ms\0\x11" - 20 bytes
6741
6980
  );
6742
6981
 
@@ -7171,6 +7410,20 @@ my %eeBox = (
7171
7410
  #
7172
7411
  ftab => { Name => 'FontTable', Format => 'undef', ValueConv => 'substr($val, 5)' },
7173
7412
  name => { Name => 'OtherName', Format => 'undef', ValueConv => 'substr($val, 4)' },
7413
+ # mrlh = GM header?
7414
+ # mrlv = GM data
7415
+ # mrld = GM data (448-byte records):
7416
+ # 0 - int32u count
7417
+ # 4 - int32u ? (related to units) 0=none,1=m/km,2=L,3=kph,4=C,7=deg,8=rpm,9=kPa,10=G,11=V,15=Nm,16=%
7418
+ # 8 - int32u ? (0,1,3,4,5)
7419
+ # 12 - string[64] units
7420
+ # 76 - int32u ? (1,3,7,15)
7421
+ # 80 - int32u 0
7422
+ # 84 - undef[4] ?
7423
+ # 88 - int16u[6] ?
7424
+ # 100 - undef[32] ?
7425
+ # 132 - string[64] measurement name
7426
+ # 196 - string[64] measurement name
7174
7427
  );
7175
7428
 
7176
7429
  # MP4 data information box (ref 5)
@@ -7467,6 +7720,7 @@ my %eeBox = (
7467
7720
  1 => 'QuickTime:HandlerType',
7468
7721
  },
7469
7722
  Writable => 1,
7723
+ Protected => 1,
7470
7724
  WriteAlso => {
7471
7725
  MatrixStructure => 'Image::ExifTool::QuickTime::GetRotationMatrix($val)',
7472
7726
  },
@@ -8232,6 +8486,11 @@ sub HandleItemInfo($)
8232
8486
  if ($buff =~ /^(MM\0\x2a|II\x2a\0)/) {
8233
8487
  $et->Warn('Missing Exif header');
8234
8488
  $start = 0;
8489
+ } elsif ($buff =~ /^Exif\0\0/) {
8490
+ # (haven't seen this yet, but it is just a matter of time
8491
+ # until someone screws it up like this)
8492
+ $et->Warn('Missing Exif header size');
8493
+ $start = 6;
8235
8494
  } else {
8236
8495
  my $n = unpack('N', $buff);
8237
8496
  $start = 4 + $n; # skip "Exif\0\0" header if it exists
@@ -8296,7 +8555,7 @@ sub EEWarn($)
8296
8555
  #------------------------------------------------------------------------------
8297
8556
  # Get quicktime format from flags word
8298
8557
  # Inputs: 0) quicktime atom flags, 1) data length
8299
- # Returns: Exiftool format string
8558
+ # Returns: ExifTool format string
8300
8559
  sub QuickTimeFormat($$)
8301
8560
  {
8302
8561
  my ($flags, $len) = @_;
@@ -8523,7 +8782,7 @@ sub ProcessKeys($$$)
8523
8782
  my $ns = substr($$dataPt, $pos + 4, 4);
8524
8783
  my $tag = substr($$dataPt, $pos + 8, $len - 8);
8525
8784
  $tag =~ s/\0.*//s; # truncate at null
8526
- $tag =~ s/^com\.apple\.quicktime\.// if $ns eq 'mdta'; # remove apple quicktime domain
8785
+ $tag =~ s/^com\.(apple\.quicktime\.)?// if $ns eq 'mdta'; # remove apple quicktime domain
8527
8786
  $tag = "Tag_$ns" unless $tag;
8528
8787
  # (I have some samples where the tag is a reversed ItemList or UserData tag ID)
8529
8788
  my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
@@ -8555,9 +8814,10 @@ sub ProcessKeys($$$)
8555
8814
  $$newInfo{Groups} = $groups ? { %$groups } : { };
8556
8815
  $$newInfo{Groups}{$_} or $$newInfo{Groups}{$_} = $$tagTablePtr{GROUPS}{$_} foreach 0..2;
8557
8816
  $$newInfo{Groups}{1} = 'Keys';
8558
- } elsif ($tag =~ /^[-\w. ]+$/) {
8817
+ } elsif ($tag =~ /^[-\w. ]+$/ or $tag =~ /\w{4}/) {
8559
8818
  # create info for tags with reasonable id's
8560
8819
  my $name = ucfirst $tag;
8820
+ $name =~ tr/-0-9a-zA-Z_. //dc;
8561
8821
  $name =~ s/[. ]+(.?)/\U$1/g;
8562
8822
  $name =~ s/_([a-z])/_\U$1/g;
8563
8823
  $name =~ s/([a-z])_([A-Z])/$1$2/g;
@@ -8578,7 +8838,7 @@ sub ProcessKeys($$$)
8578
8838
  if ($newInfo) {
8579
8839
  AddTagToTable($itemList, $id, $newInfo);
8580
8840
  $msg or $msg = '';
8581
- $out and print $out "$$et{INDENT}Added ItemList Tag $id = $tag$msg\n";
8841
+ $out and print $out "$$et{INDENT}Added ItemList Tag $id = ($ns) $tag$msg\n";
8582
8842
  }
8583
8843
  $pos += $len;
8584
8844
  ++$index;
@@ -9033,10 +9293,10 @@ ItemID: foreach $id (keys %$items) {
9033
9293
  }
9034
9294
  }
9035
9295
  if ($ctry or $lang) {
9036
- $lang = GetLangCode($lang, $ctry);
9037
- if ($lang) {
9296
+ my $langCode = GetLangCode($lang, $ctry);
9297
+ if ($langCode) {
9038
9298
  # get tagInfo for other language
9039
- $langInfo = GetLangInfoQT($et, $tagInfo, $lang);
9299
+ $langInfo = GetLangInfoQT($et, $tagInfo, $langCode);
9040
9300
  # save other language tag ID's so we can delete later if necessary
9041
9301
  if ($langInfo) {
9042
9302
  $$tagInfo{OtherLang} or $$tagInfo{OtherLang} = [ ];
@@ -9053,7 +9313,7 @@ ItemID: foreach $id (keys %$items) {
9053
9313
  Size => $len,
9054
9314
  Format => $format,
9055
9315
  Index => $index,
9056
- Extra => sprintf(", Type='${type}', Flags=0x%x%s",$flags,($lang ? ", Lang=$lang" : '')),
9316
+ Extra => sprintf(", Type='${type}', Flags=0x%x, Lang=0x%.4x",$flags,$lang),
9057
9317
  ) if $verbose;
9058
9318
  # use "Keys" in path instead of ItemList if this was defined by a Keys tag
9059
9319
  my $isKey = $$tagInfo{Groups} && $$tagInfo{Groups}{1} && $$tagInfo{Groups}{1} eq 'Keys';