exiftool-vendored.pl 13.26.0 → 13.30.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 (40) hide show
  1. package/README.md +9 -2
  2. package/bin/Changes +64 -1
  3. package/bin/META.json +3 -2
  4. package/bin/META.yml +3 -2
  5. package/bin/README +2 -2
  6. package/bin/arg_files/exif2xmp.args +2 -1
  7. package/bin/arg_files/xmp2exif.args +2 -1
  8. package/bin/config_files/pix4d.config +9 -8
  9. package/bin/exiftool +21 -16
  10. package/bin/lib/Image/ExifTool/BuildTagLookup.pm +1 -1
  11. package/bin/lib/Image/ExifTool/Canon.pm +4 -2
  12. package/bin/lib/Image/ExifTool/Exif.pm +3 -1
  13. package/bin/lib/Image/ExifTool/FujiFilm.pm +2 -1
  14. package/bin/lib/Image/ExifTool/GIMP.pm +1 -1
  15. package/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
  16. package/bin/lib/Image/ExifTool/JPEG.pm +20 -8
  17. package/bin/lib/Image/ExifTool/LigoGPS.pm +16 -2
  18. package/bin/lib/Image/ExifTool/MPF.pm +5 -1
  19. package/bin/lib/Image/ExifTool/MakerNotes.pm +3 -3
  20. package/bin/lib/Image/ExifTool/Olympus.pm +6 -2
  21. package/bin/lib/Image/ExifTool/Panasonic.pm +9 -1
  22. package/bin/lib/Image/ExifTool/Parrot.pm +54 -7
  23. package/bin/lib/Image/ExifTool/Pentax.pm +151 -11
  24. package/bin/lib/Image/ExifTool/Plot.pm +36 -15
  25. package/bin/lib/Image/ExifTool/QuickTime.pm +73 -6
  26. package/bin/lib/Image/ExifTool/QuickTimeStream.pl +80 -14
  27. package/bin/lib/Image/ExifTool/README +12 -2
  28. package/bin/lib/Image/ExifTool/Sigma.pm +12 -4
  29. package/bin/lib/Image/ExifTool/Sony.pm +8 -3
  30. package/bin/lib/Image/ExifTool/TagLookup.pm +3745 -3729
  31. package/bin/lib/Image/ExifTool/TagNames.pod +147 -89
  32. package/bin/lib/Image/ExifTool/WriteExif.pl +2 -0
  33. package/bin/lib/Image/ExifTool/WriteQuickTime.pl +3 -0
  34. package/bin/lib/Image/ExifTool/Writer.pl +18 -7
  35. package/bin/lib/Image/ExifTool/XMP.pm +2 -2
  36. package/bin/lib/Image/ExifTool.pm +12 -7
  37. package/bin/lib/Image/ExifTool.pod +11 -11
  38. package/bin/perl-Image-ExifTool.spec +1 -1
  39. package/bin/windows_exiftool.txt +15 -9
  40. package/package.json +12 -9
@@ -15,7 +15,7 @@ use strict;
15
15
  use vars qw($VERSION);
16
16
  use Image::ExifTool qw(:DataAccess :Utils);
17
17
 
18
- $VERSION = '1.02';
18
+ $VERSION = '1.03';
19
19
 
20
20
  sub Process_mett($$$);
21
21
 
@@ -61,10 +61,18 @@ sub Process_mett($$$);
61
61
  Name => 'ARCoreAccel',
62
62
  SubDirectory => { TagTable => 'Image::ExifTool::Parrot::ARCoreAccel', ByteOrder => 'II' },
63
63
  },
64
+ 'application/arcore-accel-0' => {
65
+ Name => 'ARCoreAccel0',
66
+ SubDirectory => { TagTable => 'Image::ExifTool::Parrot::ARCoreAccel0', ByteOrder => 'II' },
67
+ },
64
68
  'application/arcore-gyro' => {
65
69
  Name => 'ARCoreGyro',
66
70
  SubDirectory => { TagTable => 'Image::ExifTool::Parrot::ARCoreGyro', ByteOrder => 'II' },
67
71
  },
72
+ 'application/arcore-gyro-0' => {
73
+ Name => 'ARCoreGyro0',
74
+ SubDirectory => { TagTable => 'Image::ExifTool::Parrot::ARCoreGyro0', ByteOrder => 'II' },
75
+ },
68
76
  'application/arcore-video-0' => {
69
77
  Name => 'ARCoreVideo',
70
78
  SubDirectory => { TagTable => 'Image::ExifTool::Parrot::ARCoreVideo', ByteOrder => 'II' },
@@ -684,11 +692,24 @@ sub Process_mett($$$);
684
692
  # 33: increments slowly (about once every 56 samples or so)
685
693
  );
686
694
 
695
+ # ARCore Accel data (ref PH)
696
+ %Image::ExifTool::Parrot::ARCoreAccel0 = (
697
+ PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
698
+ GROUPS => { 2 => 'Location' },
699
+ NOTES => 'ARCore accelerometer data.',
700
+ FIRST_ENTRY => 0,
701
+ 9 => { # (NC)
702
+ Name => 'Accelerometer',
703
+ Format => 'undef[14]',
704
+ RawConv => 'GetFloat(\$val,0) . " " . GetFloat(\$val,5) . " " . GetFloat(\$val,10)',
705
+ },
706
+ );
707
+
687
708
  # ARCore Gyro data (ref PH)
688
709
  %Image::ExifTool::Parrot::ARCoreGyro = (
689
710
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
690
711
  GROUPS => { 2 => 'Location' },
691
- NOTES => 'ARCore accelerometer data.',
712
+ NOTES => 'ARCore gyro data.',
692
713
  FIRST_ENTRY => 0,
693
714
  # 00-04: always 10 34 16 3 29
694
715
  4 => {
@@ -704,6 +725,19 @@ sub Process_mett($$$);
704
725
  },
705
726
  );
706
727
 
728
+ # ARCore Gyro data (ref PH)
729
+ %Image::ExifTool::Parrot::ARCoreGyro0 = (
730
+ PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
731
+ GROUPS => { 2 => 'Location' },
732
+ NOTES => 'ARCore gyro data.',
733
+ FIRST_ENTRY => 0,
734
+ 9 => { # (NC)
735
+ Name => 'Gyroscope',
736
+ Format => 'undef[14]',
737
+ RawConv => 'GetFloat(\$val,0) . " " . GetFloat(\$val,5) . " " . GetFloat(\$val,10)',
738
+ },
739
+ );
740
+
707
741
  %Image::ExifTool::Parrot::ARCoreVideo = (
708
742
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
709
743
  FIRST_ENTRY => 0,
@@ -766,11 +800,24 @@ sub Process_mett($$$)
766
800
  $et->VerboseDir('Parrot mett', undef, $dirEnd);
767
801
 
768
802
  if ($$tagTbl{$metaType}) {
769
- $et->HandleTag($tagTbl, $metaType, undef,
770
- DataPt => $dataPt,
771
- DataPos => $dataPos,
772
- Base => $$dirInfo{Base},
773
- );
803
+ # loop through ARCore records
804
+ while ($pos < $dirEnd - 2) {
805
+ last unless substr($$dataPt,$pos,1) eq "\x0a";
806
+ my $len = ord(substr($$dataPt, $pos+1, 1));
807
+ if ($pos + $len + 2 > $dirEnd) {
808
+ $et->Warn("Unexpected length for $metaType record", 1);
809
+ last;
810
+ }
811
+ $len or $len = $dirEnd - $pos - 2; # use entire record if length is 0
812
+ $et->HandleTag($tagTbl, $metaType, undef,
813
+ DataPt => $dataPt,
814
+ DataPos => $dataPos,
815
+ DirStart => $pos,
816
+ DirLen => $len,
817
+ Base => $$dirInfo{Base},
818
+ );
819
+ $pos += $len + 2;
820
+ }
774
821
  return 1;
775
822
  }
776
823
  while ($pos + 4 < $dirEnd) {
@@ -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.48';
61
+ $VERSION = '3.51';
62
62
 
63
63
  sub CryptShutterCount($$);
64
64
  sub PrintFilter($$$);
@@ -737,6 +737,18 @@ my %filterSettings = (
737
737
  52 => ['Toning2', '%+d'], #31 Extract Color (-3-+3)
738
738
  );
739
739
 
740
+ # order of selectable K-3iii AF points. The array looks like this:
741
+ # B1 C1 E1 G1 I1 K1 L1
742
+ # A3 B3 C3 E3 G3 I3 K3 L3 M3
743
+ # A5 B5 C5 E5 G5 I5 K5 L5 M5
744
+ # A7 B7 C7 E7 G7 I7 K7 L7 M7
745
+ # B9 C9 E9 G9 I9 K9 L9
746
+ my @k3iiiAF = qw(
747
+ C1 E1 G1 I1 K1 C3 E3 G3 I3 K3 C5 E5 G5
748
+ I5 K5 C7 E7 G7 I7 K7 C9 E9 G9 I9 K9 A5 M5 B3
749
+ L3 B5 L5 B7 L7 B1 L1 B9 L9 A3 M3 A7 M7
750
+ );
751
+
740
752
  # decoding for Pentax Firmware ID tags - PH
741
753
  my %pentaxFirmwareID = (
742
754
  # the first 2 numbers are the firmware version, I'm not sure what the second 2 mean
@@ -1251,7 +1263,7 @@ my %binaryDataAttrs = (
1251
1263
  }],
1252
1264
  },{
1253
1265
  Name => 'AFPointSelected',
1254
- Condition => '$$self{Model} =~ /K-3\b/',
1266
+ Condition => '$$self{Model} =~ /(K-3|KP)\b/',
1255
1267
  Writable => 'int16u',
1256
1268
  Notes => 'K-3',
1257
1269
  PrintConvColumns => 2,
@@ -1944,6 +1956,7 @@ my %binaryDataAttrs = (
1944
1956
  '18 3' => 'Auto Program (MTF)', #PH (NC)
1945
1957
  '18 22' => 'Auto Program (Shallow DOF)', #PH (NC)
1946
1958
  '20 22' => 'Blur Control', #PH (Q)
1959
+ '26 0' => 'Shutter and Aperture Priority (TAv)', #PH (K-3III)
1947
1960
  '249 0' => 'Movie (TAv)', #31
1948
1961
  '250 0' => 'Movie (TAv, Auto Aperture)', #31
1949
1962
  '251 0' => 'Movie (Manual)', #31
@@ -3025,6 +3038,10 @@ my %binaryDataAttrs = (
3025
3038
  # 0x0236 - undef[52] (Q)
3026
3039
  # 0x0237 - undef[11] possibly related to smart effect setting? (Q)
3027
3040
  # 0x0238 - undef[9] (Q)
3041
+ 0x0238 => { #KarstenGieselmann
3042
+ Name => 'CAFPointInfo',
3043
+ SubDirectory => { TagTable => 'Image::ExifTool::Pentax::CAFPointInfo' },
3044
+ },
3028
3045
  0x0239 => { #PH
3029
3046
  Name => 'LensInfoQ',
3030
3047
  SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensInfoQ' },
@@ -4918,6 +4935,7 @@ my %binaryDataAttrs = (
4918
4935
  # CalFlag, ContrastFlag, PrecalFlag, SelectSensor
4919
4936
  0x00 => { #PH
4920
4937
  Name => 'AFPointsUnknown1',
4938
+ Condition => '$$self{Model} !~ /K-3 Mark III/', # (and maybe others?)
4921
4939
  Unknown => 1,
4922
4940
  Format => 'int16u',
4923
4941
  ValueConv => '$self->Options("Unknown") ? $val : $val & 0x7ff',
@@ -4945,6 +4963,7 @@ my %binaryDataAttrs = (
4945
4963
  },
4946
4964
  0x02 => { #PH
4947
4965
  Name => 'AFPointsUnknown2',
4966
+ Condition => '$$self{Model} !~ /K-3 Mark III/', # (and maybe others?)
4948
4967
  Unknown => 1,
4949
4968
  Format => 'int16u',
4950
4969
  ValueConv => '$self->Options("Unknown") ? $val : $val & 0x7ff',
@@ -4986,10 +5005,10 @@ my %binaryDataAttrs = (
4986
5005
  # 0x0a - values: 00,05,0d,15,86,8e,a6,ae
4987
5006
  0x0b => { #JD
4988
5007
  Name => 'AFPointsInFocus',
4989
- Condition => '$$self{Model} !~ /K-[13]\b/',
5008
+ Condition => '$$self{Model} !~ /(K-(1|3|70)|KP)\b/',
4990
5009
  Notes => q{
4991
- models other than the K-1 and K-3. May report two points in focus even
4992
- though a single AFPoint has been selected, in which case the selected
5010
+ models other than the K-1, K-3, K-70 and KP. May report two points in focus
5011
+ even though a single AFPoint has been selected, in which case the selected
4993
5012
  AFPoint is the first reported
4994
5013
  },
4995
5014
  PrintConvColumns => 2,
@@ -5017,6 +5036,41 @@ my %binaryDataAttrs = (
5017
5036
  20 => 'Mid-right',
5018
5037
  },
5019
5038
  },
5039
+ 0x14 => {
5040
+ Name => 'AFPointValues',
5041
+ Condition => '$$self{Model} eq "PENTAX K-3 Mark III"', # any other models?
5042
+ Format => 'int16uRev[69]',
5043
+ Unknown => 1,
5044
+ Notes => 'some unknown values related to each AFPoint',
5045
+ # order is the same as AFPoints below, but there is an additional value for
5046
+ # each AF point starting at offset 28 in the array (yes, the range overlaps
5047
+ # with the 1st values)
5048
+ # (values are int16s stored in reversed byte order)
5049
+ ValueConv => 'my @a=split " ",$val;$_>32767 and $_-=65536 foreach @a;join " ",@a',
5050
+ PrintConv => \&AFPointValues,
5051
+ },
5052
+ 0x12a => { # byte has a value of 2 if corresponding AF point is selected
5053
+ Name => 'AFPointsSelected',
5054
+ Condition => '$$self{Model} eq "PENTAX K-3 Mark III"', # any other models?
5055
+ Notes => q{
5056
+ K-3III only. 41 selectable AF points from a total of 101 available in a 13x9
5057
+ grid. Columns are labelled A-M and rows are 1-9. The center point is G5
5058
+ },
5059
+ Format => 'int8u[41]',
5060
+ PrintConv => 'Image::ExifTool::Pentax::AFPointsK3iii($val,$self,2)',
5061
+ },
5062
+ #
5063
+ # (maybe not coincidentally, there are 60 unknown bytes
5064
+ # here, and there are also 60 non-selectable AF points)
5065
+ #
5066
+ 0x18f => { # byte has a value of 1 if corresponding AF point is ... in focus maybe?
5067
+ # usually the same points as AFPoints above, but not always
5068
+ Name => 'AFPointsUnknown',
5069
+ Condition => '$$self{Model} eq "PENTAX K-3 Mark III"', # any other models?
5070
+ Unknown => 1,
5071
+ Format => 'int8u[41]',
5072
+ PrintConv => \&AFPointsK3iii,
5073
+ },
5020
5074
  0x1fa => {
5021
5075
  Name => 'LiveView',
5022
5076
  Notes => 'decoded only for the K-3 III',
@@ -5031,6 +5085,37 @@ my %binaryDataAttrs = (
5031
5085
  },
5032
5086
  );
5033
5087
 
5088
+ # AF information for K-01 and later (ref Karsten Gieselmann private communication)
5089
+ %Image::ExifTool::Pentax::CAFPointInfo = (
5090
+ %binaryDataAttrs,
5091
+ FIRST_ENTRY => 0,
5092
+ DATAMEMBER => [ 1 ],
5093
+ GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
5094
+ NOTES => 'Contrast-detect AF-point information for the K-01 and later models.',
5095
+ 1 => {
5096
+ Name => 'NumCAFPoints',
5097
+ RawConv => '$$self{NumCAFPoints} = ($val & 0x0f) * ($val >> 4); $val',
5098
+ ValueConv => '($val >> 4) * ($val & 0x0f)',
5099
+ },
5100
+ 1.1 => {
5101
+ Name => 'CAFGridSize',
5102
+ ValueConv => '($val >> 4) . " " . ($val & 0x0f)', # (width x height)
5103
+ PrintConv => '$val =~ tr/ /x/; $val',
5104
+ },
5105
+ 2 => {
5106
+ Name => 'CAFPointsInFocus',
5107
+ Format => 'int8u[int(($val{1}+3)/4)]',
5108
+ Writable => 0,
5109
+ PrintConv => 'Image::ExifTool::Pentax::DecodeAFPoints($val,$$self{NumCAFPoints},2,0x02)',
5110
+ },
5111
+ 2.1 => {
5112
+ Name => 'CAFPointsSelected',
5113
+ Format => 'int8u[int(($val{1}+3)/4)]',
5114
+ Writable => 0,
5115
+ PrintConv => 'Image::ExifTool::Pentax::DecodeAFPoints($val,$$self{NumCAFPoints},2,0x03)',
5116
+ },
5117
+ );
5118
+
5034
5119
  # Kelvin white balance information (ref 28, topic 4834)
5035
5120
  %Image::ExifTool::Pentax::KelvinWB = (
5036
5121
  %binaryDataAttrs,
@@ -5697,29 +5782,34 @@ my %binaryDataAttrs = (
5697
5782
  %Image::ExifTool::Pentax::AFPointInfo = (
5698
5783
  %binaryDataAttrs,
5699
5784
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
5785
+ DATAMEMBER => [ 2 ],
5700
5786
  NOTES => 'AF point information written by the K-1.',
5701
5787
  # 0 - int16u: 1 (version?)
5702
5788
  2 => {
5703
5789
  Name => 'NumAFPoints',
5704
5790
  Format => 'int16u',
5791
+ RawConv => '$$self{NumAFPoints} = $val',
5705
5792
  },
5706
5793
  4 => {
5707
5794
  Name => 'AFPointsInFocus',
5708
5795
  Condition => '$$self{Model} =~ /K-1\b/',
5709
- Format => 'int8u[9]',
5710
- PrintConv => 'Image::ExifTool::Pentax::DecodeAFPoints($val,33,2,0x02)',
5796
+ Format => 'int8u[int(($val{2}+3)/4)]',
5797
+ Writable => 0,
5798
+ PrintConv => 'Image::ExifTool::Pentax::DecodeAFPoints($val,$$self{NumAFPoints},2,0x02)',
5711
5799
  },
5712
5800
  4.1 => {
5713
5801
  Name => 'AFPointsSelected',
5714
5802
  Condition => '$$self{Model} =~ /K-1\b/',
5715
- Format => 'int8u[9]',
5716
- PrintConv => 'Image::ExifTool::Pentax::DecodeAFPoints($val,33,2,0x03)',
5803
+ Format => 'int8u[int(($val{2}+3)/4)]',
5804
+ Writable => 0,
5805
+ PrintConv => 'Image::ExifTool::Pentax::DecodeAFPoints($val,$$self{NumAFPoints},2,0x03)',
5717
5806
  },
5718
5807
  4.2 => {
5719
5808
  Name => 'AFPointsSpecial',
5720
5809
  Condition => '$$self{Model} =~ /K-1\b/',
5721
- Format => 'int8u[9]',
5722
- PrintConv => 'Image::ExifTool::Pentax::DecodeAFPoints($val,33,2,0x03,0x03)',
5810
+ Format => 'int8u[int(($val{2}+3)/4)]',
5811
+ Writable => 0,
5812
+ PrintConv => 'Image::ExifTool::Pentax::DecodeAFPoints($val,$$self{NumAFPoints},2,0x03,0x03)',
5723
5813
  },
5724
5814
  );
5725
5815
 
@@ -5740,6 +5830,7 @@ my %binaryDataAttrs = (
5740
5830
  # more quickly than CameraTemperature when shooting video.)
5741
5831
  0x0c => {
5742
5832
  Name => 'SensorTemperature', #forum6677 (was CameraTemperature2)
5833
+ Condition => '$$self{Model} !~ /K-3 Mark III/', # (and maybe others?)
5743
5834
  Format => 'int16s',
5744
5835
  ValueConv => '$val / 10',
5745
5836
  ValueConvInv => '$val * 10',
@@ -5748,6 +5839,7 @@ my %binaryDataAttrs = (
5748
5839
  },
5749
5840
  0x0e => {
5750
5841
  Name => 'SensorTemperature2', #forum6677 (was CameraTemperature3)
5842
+ Condition => '$$self{Model} !~ /K-3 Mark III/', # (and maybe others?)
5751
5843
  Format => 'int16s',
5752
5844
  ValueConv => '$val / 10',
5753
5845
  ValueConvInv => '$val * 10',
@@ -5769,6 +5861,15 @@ my %binaryDataAttrs = (
5769
5861
  PrintConvInv => '$val=~s/ ?c$//i; $val',
5770
5862
  },
5771
5863
  # 0x18,0x1a,0x1c,0x1e = int16u[4] BlackPoint - PH
5864
+ 0x2a => {
5865
+ Name => 'SensorTemperature',
5866
+ Condition => '$$self{Model} =~ /K-3 Mark III/',
5867
+ Format => 'int16s',
5868
+ ValueConv => '$val / 10',
5869
+ ValueConvInv => '$val * 10',
5870
+ PrintConv => 'sprintf("%.1f C", $val)',
5871
+ PrintConvInv => '$val=~s/ ?c$//i; $val',
5872
+ },
5772
5873
  );
5773
5874
 
5774
5875
  # currently unknown info
@@ -6357,6 +6458,45 @@ sub DecodeAFPoints($$$$;$)
6357
6458
  return join(',', @bitList);
6358
6459
  }
6359
6460
 
6461
+ #------------------------------------------------------------------------------
6462
+ # Print AF Point names for K-3III (ref PH)
6463
+ # Inputs: 0) value, 1) ExifTool ref, 2) optional value to match
6464
+ sub AFPointsK3iii($$;$)
6465
+ {
6466
+ my @a = split ' ', $_[0];
6467
+ my $match = $_[2];
6468
+ my @pts;
6469
+ if ($match) {
6470
+ $a[$_] == $match and push @pts, $k3iiiAF[$_] || "Unknown($_)" foreach 0..$#a;
6471
+ } else {
6472
+ $a[$_] and push @pts, $k3iiiAF[$_] || "Unknown($_)" foreach 0..$#a;
6473
+ }
6474
+ return @pts ? join ',', sort @pts : '(none)';
6475
+ }
6476
+
6477
+ #------------------------------------------------------------------------------
6478
+ # Print AF point values for K-3III (ref PH)
6479
+ # Inputs: 0) value, 1) ExifTool ref
6480
+ # Notes: this is experimental and not well understood
6481
+ sub AFPointValues($$)
6482
+ {
6483
+ my @a = split ' ', shift;
6484
+ my @vals;
6485
+ # (I really don't understand why Pentax seemed to use 28 instead of 41 for
6486
+ # the first index of the 2nd value, because as it stands there is
6487
+ # overlap between the ranges of the 1st and 2nd values, and there is
6488
+ # no way to tell which is which for cases were multiple points have values)
6489
+ foreach (0 .. $#a) {
6490
+ next unless $a[$_];
6491
+ my $pt = $k3iiiAF[$_] ? $k3iiiAF[$_] . '=' : $k3iiiAF[$_-28] . '=/';
6492
+ push @vals, "$pt$a[$_]";
6493
+ next unless $a[$_ + 28];
6494
+ $vals[-1] .= '/' . $a[$_ + 28];
6495
+ $a[$_ + 28] = undef;
6496
+ }
6497
+ return @vals ? join ',', sort @vals : '(none)';
6498
+ }
6499
+
6360
6500
  #------------------------------------------------------------------------------
6361
6501
  # Convert Pentax hex-based EV (modulo 8) to real number
6362
6502
  # Inputs: 0) value to convert
@@ -11,7 +11,7 @@ package Image::ExifTool::Plot;
11
11
  use strict;
12
12
  use vars qw($VERSION);
13
13
 
14
- $VERSION = '1.02';
14
+ $VERSION = '1.03';
15
15
 
16
16
  # default plot settings (lower-case settings may be overridden by the user)
17
17
  my %defaults = (
@@ -262,23 +262,35 @@ sub Draw($$)
262
262
  {
263
263
  my ($self, $fp) = @_;
264
264
  my ($min, $max, $xmin, $xmax, $name, $style) = @$self{qw(Min Max XMin XMax Name style)};
265
+ my ($plotNum, $multiMulti);
265
266
 
266
267
  if (not defined $min or not defined $xmin) {
267
268
  $$self{Error} = 'Nothing to plot';
268
269
  return;
269
270
  }
270
- my ($i, $n, %col, %class, $dx, $dy, $dx2, $xAxis, $x, $y, $px, $py, @og);
271
- my ($noLegend, $xname, $xdat, $xdiff, $diff, %markID, $plotNum);
272
271
  my $scat = $$self{type} =~ /^s/ ? 1 : 0;
273
272
  my $hist = $$self{type} =~ /^h/ ? [ ] : 0;
274
- my $multi = int($$self{multi} || 0);
273
+ my $multi = $$self{multi} || 0;
274
+ my @multi = $multi =~ /\d+/g;
275
+ my @names = @$name;
276
+ shift @names if $scat;
277
+ $multi = shift @multi;
275
278
  $multi = 0 unless $multi > 0;
276
279
  $style or $style = $hist ? 'line+fill' : 'line';
277
280
  unless ($style =~ /\b[mpl]/ or ($hist and $style =~ /\bf/)) {
278
281
  $$self{Error} = 'Invalid plot Style setting';
279
282
  return;
280
283
  }
281
- my $numPlots = $multi ? scalar(@$name) - $scat : 1;
284
+ my $numPlots = 0;
285
+ if ($multi) {
286
+ my $n;
287
+ for ($n=0; $n<scalar(@$name)-$scat; ++$numPlots) {
288
+ $n += ($multi[$numPlots] || 1);
289
+ $multiMulti = 1 if $multi[$numPlots] and $multi[$numPlots] > 1;
290
+ }
291
+ } else {
292
+ $numPlots = 1;
293
+ }
282
294
  my @size = @{$$self{size}};
283
295
  my $sy = $size[1];
284
296
  if ($multi) {
@@ -293,6 +305,8 @@ sub Draw($$)
293
305
  <title>$tmp</title>};
294
306
  # loop through all plots
295
307
  for ($plotNum=0; $plotNum<$numPlots; ++$plotNum) {
308
+ my ($i, $n, %col, %class, $dx, $dy, $dx2, $xAxis, $x, $y, $px, $py, @og);
309
+ my ($noLegend, $xname, $xdat, $xdiff, $diff, %markID);
296
310
  if ($numPlots > 1) {
297
311
  print $fp "\n<g transform='translate(", ($plotNum % $multi) * $size[0],
298
312
  ',', int($plotNum/$multi) * $size[1], ")'>";
@@ -304,14 +318,19 @@ sub Draw($$)
304
318
  }
305
319
  $name = $$self{Name} = [ ];
306
320
  push @{$$self{Name}}, $$self{SaveName}[0] if $scat;
307
- push @{$$self{Name}}, $$self{SaveName}[$scat + $plotNum];
308
- my $dat = $$self{Data}{$$self{Name}[$scat]};
321
+ foreach (0 .. (($multi[$plotNum] || 1) - 1)) {
322
+ push @{$$self{Name}}, shift(@names);
323
+ }
324
+ warn "@{$$self{Name}}\n";
309
325
  undef $min; undef $max;
310
- foreach (@$dat) {
311
- defined or next;
312
- defined $min or $min = $max = $_, next;
313
- $min > $_ and $min = $_;
314
- $max < $_ and $max = $_;
326
+ foreach ($scat .. (@{$$self{Name}} - 1)) {
327
+ my $dat = $$self{Data}{$$self{Name}[$_]};
328
+ foreach (@$dat) {
329
+ defined or next;
330
+ defined $min or $min = $max = $_, next;
331
+ $min > $_ and $min = $_;
332
+ $max < $_ and $max = $_;
333
+ }
315
334
  }
316
335
  }
317
336
  my ($data, $title, $xlabel, $ylabel, $cols, $marks, $tpad, $wid) =
@@ -321,12 +340,12 @@ sub Draw($$)
321
340
 
322
341
  # set reasonable default titles and labels
323
342
  $xname = shift @name if $scat;
324
- $title = "$name[0] vs $xname" if $scat and defined $title and not $title and @name == 1;
343
+ $title = "$name[0] vs $xname" if $scat and defined $title and not $title and @name == 1 and not $multi;
325
344
  if ($scat || $hist and defined $xlabel and not $xlabel) {
326
345
  $xlabel = $$name[0];
327
346
  $noLegend = 1 if $hist;
328
347
  }
329
- if (defined $ylabel and not $ylabel and @name == 1) {
348
+ if (defined $ylabel and not $ylabel and @name == 1 and not $multiMulti) {
330
349
  $ylabel = $hist ? 'Count' : $name[0];
331
350
  $noLegend = 1 unless $hist;
332
351
  }
@@ -645,7 +664,9 @@ Change plot settings.
645
664
  Title, XLabel, YLabel - plot title and x/y axis labels (no default)
646
665
  XMin, XMax - x axis minimum/maximum (autoscaling if not set)
647
666
  YMin, YMax - y axis minimum/maximum
648
- Multi - flag to draw multiple plots, one for each dataset
667
+ Multi - number of columns when drawing multiple plots,
668
+ followed optional number of datasets for each
669
+ plot (1 by default) using any separator
649
670
  Split - flag to split strings of numbers into lists
650
671
  (> 1 to split into lists of N items)
651
672
  "Grid=darkgray" - grid color
@@ -49,7 +49,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
49
49
  use Image::ExifTool::Exif;
50
50
  use Image::ExifTool::GPS;
51
51
 
52
- $VERSION = '3.15';
52
+ $VERSION = '3.17';
53
53
 
54
54
  sub ProcessMOV($$;$);
55
55
  sub ProcessKeys($$$);
@@ -815,6 +815,13 @@ my %userDefined = (
815
815
  TagTable => 'Image::ExifTool::QuickTime::Stream',
816
816
  ProcessProc => 'Image::ExifTool::LigoGPS::ProcessLigoJSON',
817
817
  },
818
+ },{
819
+ Name => 'GKUData',
820
+ Condition => '$$valPt =~ /^.{8}__V35AX_QVDATA__/',
821
+ SubDirectory => {
822
+ TagTable => 'Image::ExifTool::QuickTime::Stream',
823
+ ProcessProc => 'Image::ExifTool::LigoGPS::ProcessGKU',
824
+ },
818
825
  },{
819
826
  Name => 'FLIRData',
820
827
  SubDirectory => { TagTable => 'Image::ExifTool::FLIR::UserData' },
@@ -945,7 +952,7 @@ my %userDefined = (
945
952
  Notes => 'MP4-format video saved in Samsung motion-photo HEIC images.',
946
953
  Binary => 1,
947
954
  # note that this may be written and/or deleted, but can't currently be added back again
948
- Writable => 1,
955
+ Writable => 'undef',
949
956
  },
950
957
  # '35AX'? - seen "AT" (Yada RoadCam Pro 4K dashcam)
951
958
  cust => 'CustomInfo', # 70mai A810
@@ -953,6 +960,15 @@ my %userDefined = (
953
960
  Name => 'SEAL',
954
961
  SubDirectory => { TagTable => 'Image::ExifTool::XMP::SEAL' },
955
962
  },
963
+ inst => {
964
+ Name => 'Insta360Info',
965
+ DontRead => 1, # don't read into memory when extracting
966
+ WriteLast => 1, # must go at end of file
967
+ SubDirectory => {
968
+ TagTable => 'Image::ExifTool::QuickTime::Stream',
969
+ ProcessProc => \&ProcessInsta360,
970
+ },
971
+ },
956
972
  );
957
973
 
958
974
  # stuff seen in 'skip' atom (70mai Pro Plus+ MP4 videos)
@@ -2362,6 +2378,25 @@ my %userDefined = (
2362
2378
  # @etc - 4 bytes all zero (Samsung WB30F)
2363
2379
  # saut - 4 bytes all zero (Samsung SM-N900T)
2364
2380
  # smrd - string "TRUEBLUE" (Samsung SM-C101, etc)
2381
+ # ---- Sigma ----
2382
+ SIGM => {
2383
+ Name => 'PreviewImage',
2384
+ # 32-byte header followed by preview image. Length at offset 6 in header
2385
+ Condition => 'length($$valPt) > 0x20 and length($$valPt) == unpack("x6V",$$valPt) + 0x20',
2386
+ Groups => { 2 => 'Preview' },
2387
+ SetBase => 1, # so $$self{BASE} will be set for correct offsets in verbose/html dumps
2388
+ RawConv => q{
2389
+ $val = substr($val, 0x20);
2390
+ my $pt = $self->ValidateImage(\$val, $tag);
2391
+ if ($pt) {
2392
+ $$self{BASE} += 0x20;
2393
+ $$self{DOC_NUM} = ++$$self{DOC_COUNT};
2394
+ $self->ExtractInfo($pt, { ReEntry => 1 });
2395
+ $$self{DOC_NUM} = 0;
2396
+ }
2397
+ return $pt;
2398
+ },
2399
+ },
2365
2400
  # ---- TomTom Bandit Action Cam ----
2366
2401
  TTMD => {
2367
2402
  Name => 'TomTomMetaData',
@@ -2387,6 +2422,19 @@ my %userDefined = (
2387
2422
  Groups => { 2 => 'Preview' },
2388
2423
  Binary => 1,
2389
2424
  },
2425
+ # ---- Insta360 ----
2426
+ nail => {
2427
+ Name => 'ThumbnailTIFF',
2428
+ Notes => 'image found in some Insta360 videos, converted to TIFF format',
2429
+ Groups => { 2 => 'Preview' },
2430
+ RawConv => q{
2431
+ return undef if length $val < 8;
2432
+ my ($w, $h) = unpack('NN', $val);
2433
+ return undef if length $val < $w * $h + 8;
2434
+ return MakeTiffHeader($w, $h, 1, 8) . substr($val, 8, $w * $h);
2435
+ },
2436
+ Binary => 1,
2437
+ },
2390
2438
  # ---- Nextbase ----
2391
2439
  info => 'FirmwareVersion',
2392
2440
  'time' => {
@@ -9351,7 +9399,7 @@ sub HandleItemInfo($)
9351
9399
  $et->ProcessDirectory(\%dirInfo, $subTable, $proc);
9352
9400
  delete $$et{DOC_NUM};
9353
9401
  }
9354
- $raf->Seek($curPos, 0) or $et->Warn('Seek error'), last; # seek back to original position
9402
+ $raf->Seek($curPos, 0) or $et->Warn('Seek error'); # seek back to original position
9355
9403
  pop @{$$et{PATH}};
9356
9404
  }
9357
9405
  # process the item properties now that we should know their associations and document numbers
@@ -9743,6 +9791,7 @@ sub IdentifyTrailers($)
9743
9791
  } else {
9744
9792
  last;
9745
9793
  }
9794
+ # 0) trailer type, 1) trailer start, 2) trailer length, 3) pointer to next trailer
9746
9795
  $trailer = [ $type , $raf->Tell() - $len, $len, $nextTrail ];
9747
9796
  $nextTrail = $trailer;
9748
9797
  $offset += $len;
@@ -10017,7 +10066,7 @@ sub ProcessMOV($$;$)
10017
10066
  }
10018
10067
  }
10019
10068
  }
10020
- if (defined $tagInfo and not $ignore) {
10069
+ if (defined $tagInfo and not $ignore and not ($tagInfo and $$tagInfo{DontRead})) {
10021
10070
  # set document number for this item property if necessary
10022
10071
  if ($$et{IsItemProperty}) {
10023
10072
  my $items = $$et{ItemInfo};
@@ -10070,7 +10119,7 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
10070
10119
  # use value to get tag info if necessary
10071
10120
  $tagInfo or $tagInfo = $et->GetTagInfo($tagTablePtr, $tag, \$val);
10072
10121
  my $hasData = ($$dirInfo{HasData} and $val =~ /^....data\0/s);
10073
- if ($verbose and not $hasData) {
10122
+ if ($verbose and defined $val and not $hasData) {
10074
10123
  my $tval;
10075
10124
  if ($tagInfo and $$tagInfo{Format}) {
10076
10125
  $tval = ReadValue(\$val, 0, $$tagInfo{Format}, $$tagInfo{Count}, length($val));
@@ -10389,7 +10438,25 @@ ItemID: foreach $id (reverse sort { $a <=> $b } keys %$items) {
10389
10438
  Size => $size,
10390
10439
  Extra => sprintf(' at offset 0x%.4x', $raf->Tell()),
10391
10440
  ) if $verbose;
10392
- if ($size and (not $raf->Seek($size-1, 1) or $raf->Read($buff, 1) != 1)) {
10441
+ my $seekTo = $raf->Tell() + $size;
10442
+ if ($tagInfo and $$tagInfo{DontRead} and $$tagInfo{SubDirectory}) {
10443
+ # ignore first trailer if it is the payload of this box
10444
+ $trailer = $$trailer[3] if $trailer and $$trailer[1] == $raf->Tell();
10445
+ my $subdir = $$tagInfo{SubDirectory};
10446
+ my %dirInfo = (
10447
+ RAF => $raf,
10448
+ DirName => $$tagInfo{Name},
10449
+ DirID => $tag,
10450
+ DirEnd => $seekTo,
10451
+ );
10452
+ my $subTable = GetTagTable($$subdir{TagTable});
10453
+ my $proc = $$subdir{ProcessProc};
10454
+ # make ProcessMOV() the default processing procedure for subdirectories
10455
+ $proc = \&ProcessMOV unless $proc or $$subTable{PROCESS_PROC};
10456
+ $et->ProcessDirectory(\%dirInfo, $subTable, $proc);
10457
+ $raf->Seek($seekTo);
10458
+ }
10459
+ unless ($raf->Seek($seekTo-1) and $raf->Read($buff, 1) == 1) {
10393
10460
  my $t = PrintableTagID($tag,2);
10394
10461
  $warnStr = sprintf("Truncated '${t}' data at offset 0x%x", $lastPos);
10395
10462
  last;