exiftool_vendored 11.99.0 → 12.06.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +119 -2
  3. data/bin/MANIFEST +5 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +32 -32
  7. data/bin/exiftool +55 -50
  8. data/bin/lib/Image/ExifTool.pm +155 -109
  9. data/bin/lib/Image/ExifTool.pod +103 -77
  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 +11 -6
  13. data/bin/lib/Image/ExifTool/Canon.pm +2 -1
  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 +16 -3
  17. data/bin/lib/Image/ExifTool/Exif.pm +15 -6
  18. data/bin/lib/Image/ExifTool/Font.pm +9 -2
  19. data/bin/lib/Image/ExifTool/GIF.pm +5 -0
  20. data/bin/lib/Image/ExifTool/GeoTiff.pm +2 -0
  21. data/bin/lib/Image/ExifTool/GoPro.pm +10 -1
  22. data/bin/lib/Image/ExifTool/H264.pm +1 -1
  23. data/bin/lib/Image/ExifTool/ID3.pm +86 -12
  24. data/bin/lib/Image/ExifTool/Lang/de.pm +3 -1
  25. data/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
  26. data/bin/lib/Image/ExifTool/M2TS.pm +1 -1
  27. data/bin/lib/Image/ExifTool/MacOS.pm +1 -1
  28. data/bin/lib/Image/ExifTool/Minolta.pm +3 -2
  29. data/bin/lib/Image/ExifTool/Nikon.pm +134 -15
  30. data/bin/lib/Image/ExifTool/Olympus.pm +34 -17
  31. data/bin/lib/Image/ExifTool/PNG.pm +14 -3
  32. data/bin/lib/Image/ExifTool/PPM.pm +5 -5
  33. data/bin/lib/Image/ExifTool/Panasonic.pm +147 -13
  34. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +33 -0
  35. data/bin/lib/Image/ExifTool/Parrot.pm +2 -1
  36. data/bin/lib/Image/ExifTool/Pentax.pm +2 -1
  37. data/bin/lib/Image/ExifTool/Photoshop.pm +2 -1
  38. data/bin/lib/Image/ExifTool/QuickTime.pm +204 -27
  39. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +355 -19
  40. data/bin/lib/Image/ExifTool/README +20 -19
  41. data/bin/lib/Image/ExifTool/Ricoh.pm +19 -1
  42. data/bin/lib/Image/ExifTool/Shift.pl +1 -0
  43. data/bin/lib/Image/ExifTool/SigmaRaw.pm +40 -33
  44. data/bin/lib/Image/ExifTool/Sony.pm +376 -11
  45. data/bin/lib/Image/ExifTool/TagLookup.pm +1949 -1872
  46. data/bin/lib/Image/ExifTool/TagNames.pod +329 -53
  47. data/bin/lib/Image/ExifTool/Validate.pm +4 -4
  48. data/bin/lib/Image/ExifTool/WriteExif.pl +1 -0
  49. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +23 -15
  50. data/bin/lib/Image/ExifTool/Writer.pl +44 -21
  51. data/bin/lib/Image/ExifTool/XMP.pm +41 -4
  52. data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
  53. data/bin/lib/Image/ExifTool/ZISRAW.pm +123 -0
  54. data/bin/perl-Image-ExifTool.spec +31 -31
  55. data/lib/exiftool_vendored/version.rb +1 -1
  56. metadata +4 -3
@@ -531,14 +531,45 @@ my %panasonicWhiteBalance = ( #forum9396
531
531
  PrintConv => '"$val mm"',
532
532
  PrintConvInv => '$val=~s/\s*mm$//;$val',
533
533
  },
534
+ # 0x1300 - incident light value? (ref forum11395)
535
+ 0x1301 => { #forum11395
536
+ Name => 'ApertureValue',
537
+ Writable => 'int16s',
538
+ Priority => 0,
539
+ ValueConv => '2 ** ($val / 512)',
540
+ ValueConvInv => '$val>0 ? 512*log($val)/log(2) : 0',
541
+ PrintConv => 'sprintf("%.1f",$val)',
542
+ PrintConvInv => '$val',
543
+ },
544
+ 0x1302 => { #forum11395
545
+ Name => 'ShutterSpeedValue',
546
+ Writable => 'int16s',
547
+ Priority => 0,
548
+ ValueConv => 'abs($val/256)<100 ? 2**(-$val/256) : 0',
549
+ ValueConvInv => '$val>0 ? -256*log($val)/log(2) : -25600',
550
+ PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
551
+ PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
552
+ },
553
+ 0x1303 => { #forum11395
554
+ Name => 'SensitivityValue',
555
+ Writable => 'int16s',
556
+ ValueConv => '$val / 256',
557
+ ValueConvInv => 'int($val * 256)',
558
+ },
534
559
  0x1305 => { #forum9384
535
560
  Name => 'HighISOMode',
536
561
  Writable => 'int16u',
537
562
  RawConv => '$val || undef',
538
563
  PrintConv => { 1 => 'On', 2 => 'Off' },
539
564
  },
565
+ # 0x1306 EV for some models like the GX8 (forum11395)
540
566
  # 0x140b - scaled overall black level? (ref forum9281)
541
567
  # 0x1411 - scaled black level per channel difference (ref forum9281)
568
+ 0x1412 => { #forum11397
569
+ Name => 'FacesDetected',
570
+ Writable => 'int8u',
571
+ PrintConv => { 0 => 'No', 1 => 'Yes' },
572
+ },
542
573
  # 0x2000 - WB tungsten=3, daylight=4 (ref forum9467)
543
574
  # 0x2009 - scaled black level per channel (ref forum9281)
544
575
  # 0x3000-0x310b - red/blue balances * 1024 (ref forum9467)
@@ -600,6 +631,8 @@ my %panasonicWhiteBalance = ( #forum9396
600
631
  Writable => 'int8u',
601
632
  PrintConv => \%Image::ExifTool::Exif::orientation,
602
633
  },
634
+ # 0x3504 = Tag 0x1301+0x1302-0x1303 (Bv = Av+Tv-Sv) (forum11395)
635
+ # 0x3505 - same as 0x1300 (forum11395)
603
636
  0x3600 => { #forum9396
604
637
  Name => 'WhiteBalanceDetected',
605
638
  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.32';
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
@@ -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.49';
50
+ $VERSION = '2.52';
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/',
@@ -667,6 +685,11 @@ my %eeBox = (
667
685
  },
668
686
  # gpsa - seen hex "01 20 00 00" (DuDuBell M1, VSYS M6L)
669
687
  # gsea - 20 bytes hex "05 00's..." (DuDuBell M1) "05 08 02 01 ..." (VSYS M6L)
688
+ 'GPS ' => { # GPS data written by 70mai dashcam (parsed in QuickTimeStream.pl)
689
+ Name => 'GPSDataList2',
690
+ Unknown => 1,
691
+ Binary => 1,
692
+ },
670
693
  );
671
694
 
672
695
  # MPEG-4 'ftyp' atom
@@ -962,7 +985,7 @@ my %eeBox = (
962
985
  %Image::ExifTool::QuickTime::CleanAperture = (
963
986
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
964
987
  GROUPS => { 2 => 'Video' },
965
- FORMAT => 'rational64u',
988
+ FORMAT => 'rational64s',
966
989
  0 => 'CleanApertureWidth',
967
990
  1 => 'CleanApertureHeight',
968
991
  2 => 'CleanApertureOffsetX',
@@ -1307,6 +1330,7 @@ my %eeBox = (
1307
1330
  Format => 'fixed32s[9]',
1308
1331
  Notes => 'writable for the video track via the Composite Rotation tag',
1309
1332
  Writable => 1,
1333
+ Protected => 1,
1310
1334
  Permanent => 1,
1311
1335
  # only set rotation if image size is non-zero
1312
1336
  RawConvInv => \&GetMatrixStructure,
@@ -1371,8 +1395,8 @@ my %eeBox = (
1371
1395
  },
1372
1396
  ValueConvInv => q{
1373
1397
  require Image::ExifTool::XMP;
1374
- $val = Image::ExifTool::XMP::FormatXMPDate($val);
1375
- $val =~ s/([-+]\d{2}):(\d{2})$/$1$2/; # remove time zone colon
1398
+ my $tmp = Image::ExifTool::XMP::FormatXMPDate($val);
1399
+ ($val = $tmp) =~ s/([-+]\d{2}):(\d{2})$/$1$2/ if defined $tmp; # remove time zone colon
1376
1400
  return $val;
1377
1401
  },
1378
1402
  PrintConv => '$self->ConvertDateTime($val)',
@@ -1634,7 +1658,7 @@ my %eeBox = (
1634
1658
  Groups => { 2 => 'Time' },
1635
1659
  Notes => q{
1636
1660
  Apple Photos has been reported to show a crazy date/time for some MP4 files
1637
- containing this tag
1661
+ containing this tag, but perhaps only if it is missing a time zone
1638
1662
  }, #forum10690/11125
1639
1663
  Shift => 'Time',
1640
1664
  ValueConv => q{
@@ -1857,6 +1881,25 @@ my %eeBox = (
1857
1881
  ByteOrder => 'LittleEndian',
1858
1882
  },
1859
1883
  },
1884
+ # ---- Garmin ---- (ref PH)
1885
+ uuid => [{
1886
+ Name => 'GarminSoftware', # (NC)
1887
+ Condition => '$$valPt =~ /^VIRBactioncamera/',
1888
+ RawConv => 'substr($val, 16)',
1889
+ RawConvInv => '"VIRBactioncamera$val"',
1890
+ },{
1891
+ # 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)
1892
+ Name => 'UUID-Unknown',
1893
+ Writable => 0,
1894
+ %unknownInfo,
1895
+ }],
1896
+ pmcc => {
1897
+ Name => 'GarminSettings',
1898
+ ValueConv => 'substr($val, 4)',
1899
+ ValueConvInv => '"\0\0\0\x01$val"',
1900
+ },
1901
+ # hmtp - "\0\0\0\x01" followed by 408 bytes of zero
1902
+ # vrin - "\0\0\0\x01" followed by 8 bytes of zero
1860
1903
  # ---- GoPro ---- (ref PH)
1861
1904
  GoPr => 'GoProType', # (Hero3+)
1862
1905
  FIRM => { Name => 'FirmwareVersion', Avoid => 1 }, # (Hero4)
@@ -2040,6 +2083,63 @@ my %eeBox = (
2040
2083
  ProcessProc => \&Image::ExifTool::ProcessTIFF, # (because ProcessMOV is default)
2041
2084
  },
2042
2085
  },
2086
+ '@mak' => { Name => 'Make', Avoid => 1 },
2087
+ '@mod' => { Name => 'Model', Avoid => 1 },
2088
+ '@swr' => { Name => 'SoftwareVersion', Avoid => 1 },
2089
+ '@day' => {
2090
+ Name => 'ContentCreateDate',
2091
+ Notes => q{
2092
+ some stupid Ricoh programmer used the '@' symbol instead of the copyright
2093
+ symbol in these tag ID's for the Ricoh Theta Z1 and maybe other models
2094
+ },
2095
+ Groups => { 2 => 'Time' },
2096
+ Shift => 'Time',
2097
+ Avoid => 1,
2098
+ # handle values in the form "2010-02-12T13:27:14-0800"
2099
+ ValueConv => q{
2100
+ require Image::ExifTool::XMP;
2101
+ $val = Image::ExifTool::XMP::ConvertXMPDate($val);
2102
+ $val =~ s/([-+]\d{2})(\d{2})$/$1:$2/; # add colon to timezone if necessary
2103
+ return $val;
2104
+ },
2105
+ ValueConvInv => q{
2106
+ require Image::ExifTool::XMP;
2107
+ my $tmp = Image::ExifTool::XMP::FormatXMPDate($val);
2108
+ ($val = $tmp) =~ s/([-+]\d{2}):(\d{2})$/$1$2/ if defined $tmp; # remove time zone colon
2109
+ return $val;
2110
+ },
2111
+ PrintConv => '$self->ConvertDateTime($val)',
2112
+ PrintConvInv => '$self->InverseDateTime($val)',
2113
+ },
2114
+ '@xyz' => { #PH (iPhone 3GS)
2115
+ Name => 'GPSCoordinates',
2116
+ Groups => { 2 => 'Location' },
2117
+ Avoid => 1,
2118
+ ValueConv => \&ConvertISO6709,
2119
+ ValueConvInv => \&ConvInvISO6709,
2120
+ PrintConv => \&PrintGPSCoordinates,
2121
+ PrintConvInv => \&PrintInvGPSCoordinates,
2122
+ },
2123
+ # RDT1 - pairs of int32u_BE, starting at byte 8: "458275 471846"
2124
+ # RDT2 - pairs of int32u_BE, starting at byte 8: "472276 468526"
2125
+ # RDT3 - pairs of int32u_BE, starting at byte 8: "876603 482191"
2126
+ # RDT4 - pairs of int32u_BE, starting at byte 8: "1955 484612"
2127
+ # RDT6 - empty
2128
+ # RDT7 - empty
2129
+ # RDT8 - empty
2130
+ # RDT9 - only 16-byte header?
2131
+ # the boxes below all have a similar header (little-endian):
2132
+ # 0 int32u - number of records
2133
+ # 4 ? - "1e 00"
2134
+ # 6 int16u - record length in bytes
2135
+ # 8 ? - "23 01 00 00 00 00 00 00"
2136
+ # 16 - start of records (each record ends in an int64u timestamp in ns)
2137
+ # RDTA - float[4],ts: "-0.31289672 -0.2245330 11.303817 0 775.780"
2138
+ # RDTB - float[4],ts: "-0.04841613 -0.2166595 0.0724792 0 775.780"
2139
+ # RDTC - float[4],ts: "27.60925 -27.10037 -13.27285 0 775.829"
2140
+ # RDTD - int16s[3],ts: "353 -914 16354 0 775.829"
2141
+ # RDTG - ts: "775.825"
2142
+ # RDTI - float[4],ts: "0.00165951 0.005770059 0.06838259 0.1744695 775.862"
2043
2143
  # ---- Samsung ----
2044
2144
  vndr => 'Vendor', #PH (Samsung PL70)
2045
2145
  SDLN => 'PlayMode', #PH (NC, Samsung ST80 "SEQ_PLAY")
@@ -2516,6 +2616,7 @@ my %eeBox = (
2516
2616
  Name => 'Rotation',
2517
2617
  Format => 'int8u',
2518
2618
  Writable => 'int8u',
2619
+ Protected => 1,
2519
2620
  ValueConv => '$val * 90',
2520
2621
  ValueConvInv => 'int($val / 90 + 0.5)',
2521
2622
  },
@@ -2547,6 +2648,7 @@ my %eeBox = (
2547
2648
  Name => 'PixelAspectRatio',
2548
2649
  Format => 'int32u',
2549
2650
  Writable => 'int32u',
2651
+ Protected => 1,
2550
2652
  },
2551
2653
  rloc => {
2552
2654
  Name => 'RelativeLocation',
@@ -2555,7 +2657,7 @@ my %eeBox = (
2555
2657
  },
2556
2658
  clap => {
2557
2659
  Name => 'CleanAperture',
2558
- Format => 'rational64u',
2660
+ Format => 'rational64s',
2559
2661
  Notes => '4 numbers: width, height, left and top',
2560
2662
  },
2561
2663
  hvcC => {
@@ -2893,10 +2995,25 @@ my %eeBox = (
2893
2995
  "\xa9grp" => 'Grouping',
2894
2996
  "\xa9lyr" => 'Lyrics',
2895
2997
  "\xa9nam" => 'Title',
2896
- # "\xa9st3" ? #10
2897
2998
  "\xa9too" => 'Encoder',
2898
2999
  "\xa9trk" => 'Track',
2899
3000
  "\xa9wrt" => 'Composer',
3001
+ #
3002
+ # the following tags written by AtomicParsley 0.9.6
3003
+ # (ref https://exiftool.org/forum/index.php?topic=11455.0)
3004
+ #
3005
+ "\xa9st3" => 'Subtitle',
3006
+ "\xa9con" => 'Conductor',
3007
+ "\xa9sol" => 'Soloist',
3008
+ "\xa9arg" => 'Arranger',
3009
+ "\xa9ope" => 'OriginalArtist',
3010
+ "\xa9dir" => 'Director',
3011
+ "\xa9ard" => 'ArtDirector',
3012
+ "\xa9sne" => 'SoundEngineer',
3013
+ "\xa9prd" => 'Producer',
3014
+ "\xa9xpd" => 'ExecutiveProducer',
3015
+ sdes => 'StoreDescription',
3016
+ #
2900
3017
  '----' => {
2901
3018
  Name => 'iTunesInfo',
2902
3019
  SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::iTunesInfo' },
@@ -2905,18 +3022,29 @@ my %eeBox = (
2905
3022
  covr => { Name => 'CoverArt', Groups => { 2 => 'Preview' } },
2906
3023
  cpil => { #10
2907
3024
  Name => 'Compilation',
2908
- Format => 'int8u', #23
3025
+ Format => 'int8u', #27 (ref 23 contradicts what AtomicParsley actually writes, which is int8s)
3026
+ Writable => 'int8s',
2909
3027
  PrintConv => { 0 => 'No', 1 => 'Yes' },
2910
3028
  },
2911
3029
  disk => {
2912
3030
  Name => 'DiskNumber',
2913
3031
  Format => 'undef', # (necessary to prevent decoding as string!)
2914
- ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val',
2915
- ValueConvInv => 'my @a = split / of /, $val; @a==2 ? pack("n3",0,@a) : undef',
3032
+ ValueConv => q{
3033
+ return \$val unless length($val) >= 6;
3034
+ my @a = unpack 'x2nn', $val;
3035
+ return $a[1] ? join(' of ', @a) : $a[0];
3036
+ },
3037
+ ValueConvInv => q{
3038
+ my @a = $val =~ /\d+/g;
3039
+ return undef if @a == 0 or @a > 2;
3040
+ push @a, 0 if @a == 1;
3041
+ return pack('n3', 0, @a);
3042
+ },
2916
3043
  },
2917
3044
  pgap => { #10
2918
3045
  Name => 'PlayGap',
2919
3046
  Format => 'int8u', #23
3047
+ Writable => 'int8s', #27
2920
3048
  PrintConv => {
2921
3049
  0 => 'Insert Gap',
2922
3050
  1 => 'No Gap',
@@ -2924,13 +3052,26 @@ my %eeBox = (
2924
3052
  },
2925
3053
  tmpo => {
2926
3054
  Name => 'BeatsPerMinute',
2927
- Format => 'int16u', # marked as boolean but really int16u in my sample
3055
+ # marked as boolean but really int16u in my sample
3056
+ # (but written as int16s by iTunes and AtomicParsley, ref forum11506)
3057
+ Format => 'int16u',
3058
+ Writable => 'int16s',
2928
3059
  },
2929
3060
  trkn => {
2930
3061
  Name => 'TrackNumber',
2931
3062
  Format => 'undef', # (necessary to prevent decoding as string!)
2932
- ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val',
2933
- ValueConvInv => 'my @a = split / of /, $val; @a==2 ? pack("n3",0,@a) : undef',
3063
+ ValueConv => q{
3064
+ return \$val unless length($val) >= 6;
3065
+ my @a = unpack 'x2nn', $val;
3066
+ return $a[1] ? join(' of ', @a) : $a[0];
3067
+ },
3068
+ # (see forum11501 for discussion about the format used)
3069
+ ValueConvInv => q{
3070
+ my @a = $val =~ /\d+/g;
3071
+ return undef if @a == 0 or @a > 2;
3072
+ push @a, 0 if @a == 1;
3073
+ return pack('n4', 0, @a, 0);
3074
+ },
2934
3075
  },
2935
3076
  #
2936
3077
  # Note: it is possible that the tags below are not being decoded properly
@@ -2939,6 +3080,7 @@ my %eeBox = (
2939
3080
  akID => { #10
2940
3081
  Name => 'AppleStoreAccountType',
2941
3082
  Format => 'int8u', #24
3083
+ Writable => 'int8s', #27
2942
3084
  PrintConv => {
2943
3085
  0 => 'iTunes',
2944
3086
  1 => 'AOL',
@@ -2949,12 +3091,14 @@ my %eeBox = (
2949
3091
  atID => { #10 (or TV series)
2950
3092
  Name => 'AlbumTitleID',
2951
3093
  Format => 'int32u',
3094
+ Writable => 'int32s', #27
2952
3095
  },
2953
3096
  auth => { Name => 'Author', Groups => { 2 => 'Author' } },
2954
3097
  catg => 'Category', #7
2955
3098
  cnID => { #10
2956
3099
  Name => 'AppleStoreCatalogID',
2957
3100
  Format => 'int32u',
3101
+ Writable => 'int32s', #27
2958
3102
  },
2959
3103
  cprt => { Name => 'Copyright', Groups => { 2 => 'Author' } },
2960
3104
  dscp => { Name => 'Description', Avoid => 1 },
@@ -2962,22 +3106,28 @@ my %eeBox = (
2962
3106
  gnre => { #10
2963
3107
  Name => 'Genre',
2964
3108
  Avoid => 1,
2965
- # (Note: not written as int16u if numerical, although it should be)
3109
+ # (Note: see https://exiftool.org/forum/index.php?topic=11537.0)
3110
+ Format => 'undef',
3111
+ ValueConv => 'unpack("n",$val)',
3112
+ ValueConvInv => '$val =~ /^\d+$/ ? pack("n",$val) : undef',
2966
3113
  PrintConv => q{
2967
3114
  return $val unless $val =~ /^\d+$/;
2968
3115
  require Image::ExifTool::ID3;
2969
3116
  Image::ExifTool::ID3::PrintGenre($val - 1); # note the "- 1"
2970
3117
  },
2971
3118
  PrintConvInv => q{
3119
+ return $val if $val =~ /^[0-9]+$/;
2972
3120
  require Image::ExifTool::ID3;
2973
3121
  my $id = Image::ExifTool::ID3::GetGenreID($val);
2974
- return defined $id ? $id : $val;
2975
- },
3122
+ return unless defined $id and $id =~ /^\d+$/;
3123
+ return $id + 1;
3124
+ },
2976
3125
  },
2977
3126
  egid => 'EpisodeGlobalUniqueID', #7
2978
3127
  geID => { #10
2979
3128
  Name => 'GenreID',
2980
3129
  Format => 'int32u',
3130
+ Writable => 'int32s', #27
2981
3131
  SeparateTable => 1,
2982
3132
  # the following lookup is based on http://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/genres
2983
3133
  # (see scripts/parse_genre to parse genre JSON file from above)
@@ -5630,6 +5780,7 @@ my %eeBox = (
5630
5780
  hdvd => { #10
5631
5781
  Name => 'HDVideo',
5632
5782
  Format => 'int8u', #24
5783
+ Writable => 'int8s', #27
5633
5784
  PrintConv => { 0 => 'No', 1 => 'Yes' },
5634
5785
  },
5635
5786
  keyw => 'Keyword', #7
@@ -5637,18 +5788,21 @@ my %eeBox = (
5637
5788
  pcst => { #7
5638
5789
  Name => 'Podcast',
5639
5790
  Format => 'int8u', #23
5791
+ Writable => 'int8s', #27
5640
5792
  PrintConv => { 0 => 'No', 1 => 'Yes' },
5641
5793
  },
5642
5794
  perf => 'Performer',
5643
5795
  plID => { #10 (or TV season)
5644
5796
  Name => 'PlayListID',
5645
5797
  Format => 'int8u', # actually int64u, but split it up
5798
+ Writable => 'int32s', #27
5646
5799
  },
5647
5800
  purd => 'PurchaseDate', #7
5648
5801
  purl => 'PodcastURL', #7
5649
5802
  rtng => { #10
5650
5803
  Name => 'Rating',
5651
5804
  Format => 'int8u', #23
5805
+ Writable => 'int8s', #27
5652
5806
  PrintConv => {
5653
5807
  0 => 'none',
5654
5808
  1 => 'Explicit',
@@ -5659,6 +5813,7 @@ my %eeBox = (
5659
5813
  sfID => { #10
5660
5814
  Name => 'AppleStoreCountry',
5661
5815
  Format => 'int32u',
5816
+ Writable => 'int32s', #27
5662
5817
  SeparateTable => 1,
5663
5818
  PrintConv => { #21
5664
5819
  143441 => 'United States', # US
@@ -5827,6 +5982,7 @@ my %eeBox = (
5827
5982
  stik => { #10
5828
5983
  Name => 'MediaType',
5829
5984
  Format => 'int8u', #23
5985
+ Writable => 'int8s', #27
5830
5986
  PrintConvColumns => 2,
5831
5987
  PrintConv => { #(http://weblog.xanga.com/gryphondwb/615474010/iphone-ringtones---what-did-itunes-741-really-do.html)
5832
5988
  0 => 'Movie (old)', #forum9059 (was Movie)
@@ -5848,6 +6004,7 @@ my %eeBox = (
5848
6004
  tves => { #7/10
5849
6005
  Name => 'TVEpisode',
5850
6006
  Format => 'int32u',
6007
+ Writable => 'int32s', #27
5851
6008
  },
5852
6009
  tvnn => 'TVNetworkName', #7
5853
6010
  tvsh => 'TVShow', #10
@@ -5858,7 +6015,8 @@ my %eeBox = (
5858
6015
  yrrc => 'Year', #(ffmpeg source)
5859
6016
  itnu => { #PH (iTunes 10.5)
5860
6017
  Name => 'iTunesU',
5861
- Format => 'int8s',
6018
+ Format => 'int8u', #27
6019
+ Writable => 'int8s', #27
5862
6020
  Description => 'iTunes U',
5863
6021
  PrintConv => { 0 => 'No', 1 => 'Yes' },
5864
6022
  },
@@ -5915,15 +6073,18 @@ my %eeBox = (
5915
6073
  "\xa9mvn" => 'MovementName', #PH
5916
6074
  "\xa9mvi" => { #PH
5917
6075
  Name => 'MovementNumber',
5918
- Format => 'int16s',
6076
+ Format => 'int16u', #27
6077
+ Writable => 'int16s', #27
5919
6078
  },
5920
6079
  "\xa9mvc" => { #PH
5921
6080
  Name => 'MovementCount',
5922
- Format => 'int16s',
6081
+ Format => 'int16u', #27
6082
+ Writable => 'int16s', #27
5923
6083
  },
5924
6084
  shwm => { #PH
5925
6085
  Name => 'ShowMovement',
5926
- Format => 'int8s',
6086
+ Format => 'int8u', #27
6087
+ Writable => 'int8s', #27
5927
6088
  PrintConv => { 0 => 'No', 1 => 'Yes' },
5928
6089
  },
5929
6090
  );
@@ -6737,6 +6898,7 @@ my %eeBox = (
6737
6898
  # alac - 28 bytes
6738
6899
  # adrm - AAX DRM atom? 148 bytes
6739
6900
  # aabd - AAX unknown 17kB (contains 'aavd' strings)
6901
+ # SA3D - written by Garmin VIRB360
6740
6902
  );
6741
6903
 
6742
6904
  # AMR decode config box (ref 3)
@@ -7223,6 +7385,20 @@ my %eeBox = (
7223
7385
  #
7224
7386
  ftab => { Name => 'FontTable', Format => 'undef', ValueConv => 'substr($val, 5)' },
7225
7387
  name => { Name => 'OtherName', Format => 'undef', ValueConv => 'substr($val, 4)' },
7388
+ # mrlh = GM header?
7389
+ # mrlv = GM data
7390
+ # mrld = GM data (448-byte records):
7391
+ # 0 - int32u count
7392
+ # 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=%
7393
+ # 8 - int32u ? (0,1,3,4,5)
7394
+ # 12 - string[64] units
7395
+ # 76 - int32u ? (1,3,7,15)
7396
+ # 80 - int32u 0
7397
+ # 84 - undef[4] ?
7398
+ # 88 - int16u[6] ?
7399
+ # 100 - undef[32] ?
7400
+ # 132 - string[64] measurement name
7401
+ # 196 - string[64] measurement name
7226
7402
  );
7227
7403
 
7228
7404
  # MP4 data information box (ref 5)
@@ -7519,6 +7695,7 @@ my %eeBox = (
7519
7695
  1 => 'QuickTime:HandlerType',
7520
7696
  },
7521
7697
  Writable => 1,
7698
+ Protected => 1,
7522
7699
  WriteAlso => {
7523
7700
  MatrixStructure => 'Image::ExifTool::QuickTime::GetRotationMatrix($val)',
7524
7701
  },
@@ -8353,7 +8530,7 @@ sub EEWarn($)
8353
8530
  #------------------------------------------------------------------------------
8354
8531
  # Get quicktime format from flags word
8355
8532
  # Inputs: 0) quicktime atom flags, 1) data length
8356
- # Returns: Exiftool format string
8533
+ # Returns: ExifTool format string
8357
8534
  sub QuickTimeFormat($$)
8358
8535
  {
8359
8536
  my ($flags, $len) = @_;
@@ -8580,7 +8757,7 @@ sub ProcessKeys($$$)
8580
8757
  my $ns = substr($$dataPt, $pos + 4, 4);
8581
8758
  my $tag = substr($$dataPt, $pos + 8, $len - 8);
8582
8759
  $tag =~ s/\0.*//s; # truncate at null
8583
- $tag =~ s/^com\.apple\.quicktime\.// if $ns eq 'mdta'; # remove apple quicktime domain
8760
+ $tag =~ s/^com\.(apple\.quicktime\.)?// if $ns eq 'mdta'; # remove apple quicktime domain
8584
8761
  $tag = "Tag_$ns" unless $tag;
8585
8762
  # (I have some samples where the tag is a reversed ItemList or UserData tag ID)
8586
8763
  my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
@@ -9091,10 +9268,10 @@ ItemID: foreach $id (keys %$items) {
9091
9268
  }
9092
9269
  }
9093
9270
  if ($ctry or $lang) {
9094
- $lang = GetLangCode($lang, $ctry);
9095
- if ($lang) {
9271
+ my $langCode = GetLangCode($lang, $ctry);
9272
+ if ($langCode) {
9096
9273
  # get tagInfo for other language
9097
- $langInfo = GetLangInfoQT($et, $tagInfo, $lang);
9274
+ $langInfo = GetLangInfoQT($et, $tagInfo, $langCode);
9098
9275
  # save other language tag ID's so we can delete later if necessary
9099
9276
  if ($langInfo) {
9100
9277
  $$tagInfo{OtherLang} or $$tagInfo{OtherLang} = [ ];
@@ -9111,7 +9288,7 @@ ItemID: foreach $id (keys %$items) {
9111
9288
  Size => $len,
9112
9289
  Format => $format,
9113
9290
  Index => $index,
9114
- Extra => sprintf(", Type='${type}', Flags=0x%x%s",$flags,($lang ? ", Lang=$lang" : '')),
9291
+ Extra => sprintf(", Type='${type}', Flags=0x%x, Lang=0x%.4x",$flags,$lang),
9115
9292
  ) if $verbose;
9116
9293
  # use "Keys" in path instead of ItemList if this was defined by a Keys tag
9117
9294
  my $isKey = $$tagInfo{Groups} && $$tagInfo{Groups}{1} && $$tagInfo{Groups}{1} eq 'Keys';