exiftool_vendored 12.08.0 → 12.13.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.

Potentially problematic release.


This version of exiftool_vendored might be problematic. Click here for more details.

Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +85 -2
  3. data/bin/MANIFEST +2 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +43 -43
  7. data/bin/exiftool +176 -96
  8. data/bin/lib/Image/ExifTool.pm +15 -9
  9. data/bin/lib/Image/ExifTool.pod +62 -52
  10. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +14 -4
  11. data/bin/lib/Image/ExifTool/Canon.pm +181 -15
  12. data/bin/lib/Image/ExifTool/DarwinCore.pm +7 -5
  13. data/bin/lib/Image/ExifTool/GIF.pm +2 -2
  14. data/bin/lib/Image/ExifTool/Geotag.pm +29 -10
  15. data/bin/lib/Image/ExifTool/GoPro.pm +1 -9
  16. data/bin/lib/Image/ExifTool/Import.pm +14 -11
  17. data/bin/lib/Image/ExifTool/JSON.pm +27 -4
  18. data/bin/lib/Image/ExifTool/MPF.pm +2 -2
  19. data/bin/lib/Image/ExifTool/MacOS.pm +3 -1
  20. data/bin/lib/Image/ExifTool/Matroska.pm +3 -1
  21. data/bin/lib/Image/ExifTool/Minolta.pm +2 -1
  22. data/bin/lib/Image/ExifTool/Nikon.pm +7 -4
  23. data/bin/lib/Image/ExifTool/Olympus.pm +3 -1
  24. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +1 -0
  25. data/bin/lib/Image/ExifTool/Pentax.pm +10 -3
  26. data/bin/lib/Image/ExifTool/QuickTime.pm +52 -22
  27. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +50 -37
  28. data/bin/lib/Image/ExifTool/README +5 -2
  29. data/bin/lib/Image/ExifTool/Radiance.pm +7 -2
  30. data/bin/lib/Image/ExifTool/Sony.pm +16 -17
  31. data/bin/lib/Image/ExifTool/Stim.pm +2 -2
  32. data/bin/lib/Image/ExifTool/TagLookup.pm +5756 -5710
  33. data/bin/lib/Image/ExifTool/TagNames.pod +210 -19
  34. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +7 -6
  35. data/bin/lib/Image/ExifTool/Writer.pl +20 -14
  36. data/bin/lib/Image/ExifTool/XMP.pm +62 -17
  37. data/bin/lib/Image/ExifTool/XMP2.pl +5 -0
  38. data/bin/perl-Image-ExifTool.spec +42 -42
  39. data/lib/exiftool_vendored/version.rb +1 -1
  40. metadata +3 -3
@@ -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',
@@ -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.34';
61
+ $VERSION = '3.35';
62
62
 
63
63
  sub CryptShutterCount($$);
64
64
  sub PrintFilter($$$);
@@ -2894,13 +2894,20 @@ my %binaryDataAttrs = (
2894
2894
  Writable => 'string',
2895
2895
  Notes => 'left blank by some cameras',
2896
2896
  },
2897
- 0x022a => { #PH (K-5)
2897
+ 0x022a => [{ #PH (RICOH models (GR III))
2898
+ Name => 'FilterInfo',
2899
+ Condition => '$$self{Make} =~ /^RICOH/',
2900
+ SubDirectory => {
2901
+ TagTable => 'Image::ExifTool::Pentax::FilterInfo',
2902
+ ByteOrder => 'LittleEndian',
2903
+ },
2904
+ },{ #PH (K-5)
2898
2905
  Name => 'FilterInfo',
2899
2906
  SubDirectory => {
2900
2907
  TagTable => 'Image::ExifTool::Pentax::FilterInfo',
2901
2908
  ByteOrder => 'BigEndian',
2902
2909
  },
2903
- },
2910
+ }],
2904
2911
  0x022b => { #PH (K-5)
2905
2912
  Name => 'LevelInfo',
2906
2913
  SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LevelInfo' },
@@ -47,7 +47,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
47
47
  use Image::ExifTool::Exif;
48
48
  use Image::ExifTool::GPS;
49
49
 
50
- $VERSION = '2.53';
50
+ $VERSION = '2.56';
51
51
 
52
52
  sub ProcessMOV($$;$);
53
53
  sub ProcessKeys($$$);
@@ -214,11 +214,16 @@ my %ftypLookup = (
214
214
  'crx ' => 'Canon Raw (.CRX)', #PH (CR3 or CRM; use Canon CompressorVersion to decide)
215
215
  );
216
216
 
217
- # information for time/date-based tags (time zero is Jan 1, 1904)
217
+ # information for int32u date/time tags (time zero is Jan 1, 1904)
218
218
  my %timeInfo = (
219
219
  Notes => 'converted from UTC to local time if the QuickTimeUTC option is set',
220
+ Shift => 'Time',
221
+ Writable => 1,
222
+ Permanent => 1,
223
+ DelValue => 0,
220
224
  # It is not uncommon for brain-dead software to use the wrong time zero,
221
225
  # so assume a time zero of Jan 1, 1970 if the date is before this
226
+ # Note: This value will be in UTC if generated by a system that is aware of the time zone
222
227
  RawConv => q{
223
228
  my $offset = (66 * 365 + 17) * 24 * 3600;
224
229
  return $val - $offset if $val >= $offset or $$self{OPTIONS}{QuickTimeUTC};
@@ -227,12 +232,17 @@ my %timeInfo = (
227
232
  }
228
233
  return $val;
229
234
  },
230
- Shift => 'Time',
231
- Writable => 1,
232
- Permanent => 1,
233
- DelValue => 0,
234
- # Note: This value will be in UTC if generated by a system that is aware of the time zone
235
- ValueConv => 'ConvertUnixTime($val, $self->Options("QuickTimeUTC"))',
235
+ RawConvInv => q{
236
+ if ($$self{FileType} eq 'CR3' and not $self->Options('QuickTimeUTC')) {
237
+ # convert to UTC
238
+ my $offset = (66 * 365 + 17) * 24 * 3600;
239
+ $val = ConvertUnixTime($val - $offset);
240
+ $val = GetUnixTime($val, 1) + $offset;
241
+ }
242
+ return $val;
243
+ },
244
+ # (all CR3 files store UTC times - PH)
245
+ ValueConv => 'ConvertUnixTime($val, $self->Options("QuickTimeUTC") || $$self{FileType} eq "CR3")',
236
246
  ValueConvInv => 'GetUnixTime($val, $self->Options("QuickTimeUTC")) + (66 * 365 + 17) * 24 * 3600',
237
247
  PrintConv => '$self->ConvertDateTime($val)',
238
248
  PrintConvInv => '$self->InverseDateTime($val)',
@@ -672,7 +682,7 @@ my %eeBox = (
672
682
  ValueConv => '$val=~tr/-/:/; $val',
673
683
  ValueConvInv => '$val=~s/(\d+):(\d+):/$1-$2-/; $val',
674
684
  PrintConv => '$self->ConvertDateTime($val)',
675
- PrintConvInv => '$self->InverseDateTime($val)',
685
+ PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
676
686
  },
677
687
  gps0 => { #PH (DuDuBell M1, VSYS M6L)
678
688
  Name => 'GPSTrack',
@@ -1405,7 +1415,7 @@ my %eeBox = (
1405
1415
  return $val;
1406
1416
  },
1407
1417
  PrintConv => '$self->ConvertDateTime($val)',
1408
- PrintConvInv => '$self->InverseDateTime($val)',
1418
+ PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
1409
1419
  },
1410
1420
  "\xa9ART" => 'Artist', #PH (iTunes 8.0.2)
1411
1421
  "\xa9alb" => 'Album', #PH (iTunes 8.0.2)
@@ -1679,7 +1689,7 @@ my %eeBox = (
1679
1689
  return $val;
1680
1690
  },
1681
1691
  PrintConv => '$self->ConvertDateTime($val)',
1682
- PrintConvInv => '$self->InverseDateTime($val)',
1692
+ PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
1683
1693
  },
1684
1694
  manu => { # (SX280)
1685
1695
  Name => 'Make',
@@ -2114,7 +2124,7 @@ my %eeBox = (
2114
2124
  return $val;
2115
2125
  },
2116
2126
  PrintConv => '$self->ConvertDateTime($val)',
2117
- PrintConvInv => '$self->InverseDateTime($val)',
2127
+ PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
2118
2128
  },
2119
2129
  '@xyz' => { #PH (iPhone 3GS)
2120
2130
  Name => 'GPSCoordinates',
@@ -2555,7 +2565,23 @@ my %eeBox = (
2555
2565
  Start => 4,
2556
2566
  },
2557
2567
  },
2558
- # idat
2568
+ idat => {
2569
+ Name => 'MetaImageSize', #PH (NC)
2570
+ Format => 'int16u',
2571
+ # (don't know what the first two numbers are for)
2572
+ PrintConv => '$val =~ s/^(\d+) (\d+) (\d+) (\d+)/${3}x$4/; $val',
2573
+ },
2574
+ uuid => [
2575
+ { #PH (Canon R5/R6 HIF)
2576
+ Name => 'MetaVersion', # (NC)
2577
+ Condition => '$$valPt=~/^\x85\xc0\xb6\x87\x82\x0f\x11\xe0\x81\x11\xf4\xce\x46\x2b\x6a\x48/',
2578
+ RawConv => 'substr($val, 0x14)',
2579
+ },
2580
+ {
2581
+ Name => 'UUID-Unknown',
2582
+ %unknownInfo,
2583
+ },
2584
+ ],
2559
2585
  );
2560
2586
 
2561
2587
  # additional metadata container (ref ISO14496-12:2015)
@@ -2867,12 +2893,16 @@ my %eeBox = (
2867
2893
  WRITE_PROC => \&WriteQuickTime,
2868
2894
  GROUPS => { 2 => 'Image' },
2869
2895
  # (Note: ExifTool's ItemRefVersion may be used to test the iref version number)
2870
- # dimg - DerivedImage
2871
- # thmb - Thumbnail
2872
- # auxl - AuxiliaryImage
2896
+ NOTES => q{
2897
+ The Item reference entries listed in the table below contain information about
2898
+ the associations between items in the file. This information is used by
2899
+ ExifTool, but these entries are not extracted as tags.
2900
+ },
2901
+ dimg => { Name => 'DerivedImageRef', RawConv => 'undef' },
2902
+ thmb => { Name => 'ThumbnailRef', RawConv => 'undef' },
2903
+ auxl => { Name => 'AuxiliaryImageRef', RawConv => 'undef' },
2873
2904
  cdsc => {
2874
2905
  Name => 'ContentDescribes',
2875
- Notes => 'parsed, but not extracted as a tag',
2876
2906
  RawConv => \&ParseContentDescribes,
2877
2907
  WriteHook => \&ParseContentDescribes,
2878
2908
  },
@@ -2992,7 +3022,7 @@ my %eeBox = (
2992
3022
  return $val;
2993
3023
  },
2994
3024
  PrintConv => '$self->ConvertDateTime($val)',
2995
- PrintConvInv => '$self->InverseDateTime($val)',
3025
+ PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
2996
3026
  },
2997
3027
  "\xa9des" => 'Description', #4
2998
3028
  "\xa9enc" => 'EncodedBy', #10
@@ -6170,7 +6200,7 @@ my %eeBox = (
6170
6200
  return $val;
6171
6201
  },
6172
6202
  PrintConv => '$self->ConvertDateTime($val)',
6173
- PrintConvInv => '$self->InverseDateTime($val)',
6203
+ PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
6174
6204
  },
6175
6205
  description => { },
6176
6206
  director => { },
@@ -6230,7 +6260,7 @@ my %eeBox = (
6230
6260
  return $val;
6231
6261
  },
6232
6262
  PrintConv => '$self->ConvertDateTime($val)',
6233
- PrintConvInv => '$self->InverseDateTime($val)',
6263
+ PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
6234
6264
  },
6235
6265
  'direction.facing' => { Name => 'CameraDirection', Groups => { 2 => 'Location' } },
6236
6266
  'direction.motion' => { Name => 'CameraMotion', Groups => { 2 => 'Location' } },
@@ -8618,10 +8648,10 @@ sub ProcessSampleDesc($$$)
8618
8648
  my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $pos);
8619
8649
  return 0 if $pos + 8 > $dirLen;
8620
8650
 
8621
- my $num = Get32u($dataPt, 4); # get number of sample descriptions in table
8651
+ my $num = Get32u($dataPt, 4); # get number of sample entries in table
8622
8652
  $pos += 8;
8623
8653
  my $i;
8624
- for ($i=0; $i<$num; ++$i) { # loop through sample descriptions
8654
+ for ($i=0; $i<$num; ++$i) { # loop through sample entries
8625
8655
  last if $pos + 8 > $dirLen;
8626
8656
  my $size = Get32u($dataPt, $pos);
8627
8657
  last if $pos + $size > $dirLen;
@@ -165,10 +165,17 @@ my %insvLimit = (
165
165
  ProcessProc => \&Process_mebx,
166
166
  },
167
167
  },
168
- gpmd => {
169
- Name => 'gpmd',
168
+ gpmd => [{
169
+ Name => 'gpmd_GoPro',
170
+ Condition => '$$valPt !~ /^\0\0\xf2\xe1\xf0\xeeTT/',
170
171
  SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' },
171
- },
172
+ },{
173
+ Name => 'gpmd_Rove', # Rove Stealth 4K encrypted text
174
+ SubDirectory => {
175
+ TagTable => 'Image::ExifTool::QuickTime::Stream',
176
+ ProcessProc => \&Process_text,
177
+ },
178
+ }],
172
179
  fdsc => {
173
180
  Name => 'fdsc',
174
181
  Condition => '$$valPt =~ /^GPRO/',
@@ -837,15 +844,21 @@ sub HandleTextTags($$$)
837
844
 
838
845
  #------------------------------------------------------------------------------
839
846
  # Process subtitle 'text'
840
- # Inputs: 0) ExifTool ref, 1) tag table ref, 2) data ref
847
+ # Inputs: 0) ExifTool ref, 1) data ref or dirInfo ref, 2) tag table ref
841
848
  sub Process_text($$$)
842
849
  {
843
- my ($et, $tagTbl, $buffPt) = @_;
850
+ my ($et, $dataPt, $tagTbl) = @_;
844
851
  my %tags;
845
852
 
846
853
  return if $$et{NoMoreTextDecoding};
847
854
 
848
- while ($$buffPt =~ /\$(\w+)([^\$]*)/g) {
855
+ if (ref $dataPt eq 'HASH') {
856
+ my $dirName = $$dataPt{DirName};
857
+ $dataPt = $$dataPt{DataPt};
858
+ $et->VerboseDir($dirName, undef, length($$dataPt));
859
+ }
860
+
861
+ while ($$dataPt =~ /\$(\w+)([^\$]*)/g) {
849
862
  my ($tag, $dat) = ($1, $2);
850
863
  if ($tag =~ /^[A-Z]{2}RMC$/ and $dat =~ /^,(\d{2})(\d{2})(\d+(?:\.\d*)),A?,(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/) {
851
864
  my $time = "$1:$2:$3";
@@ -936,31 +949,31 @@ sub Process_text($$$)
936
949
  # 0110: 31 30 38 30 30 30 58 00 58 00 58 00 58 00 58 00 [108000X.X.X.X.X.]
937
950
  # 0120: 58 00 58 00 58 00 58 00 00 00 00 00 00 00 00 00 [X.X.X.X.........]
938
951
  # 0130: 00 00 00 00 00 00 00 [.......]
939
- if ($$buffPt =~ /^\0\0(..\xaa\xaa|\xf2\xe1\xf0\xee)/s and length $$buffPt >= 282) {
940
- my $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 8, 14)));
952
+ if ($$dataPt =~ /^\0\0(..\xaa\xaa|\xf2\xe1\xf0\xee)/s and length $$dataPt >= 282) {
953
+ my $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 8, 14)));
941
954
  if ($val =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/) {
942
955
  $tags{GPSDateTime} = "$1:$2:$3 $4:$5:$6";
943
- $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 38, 9)));
956
+ $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 38, 9)));
944
957
  if ($val =~ /^([NS])(\d{2})(\d+$)$/) {
945
958
  $tags{GPSLatitude} = ($2 + $3 / 600000) * ($1 eq 'S' ? -1 : 1);
946
959
  }
947
- $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 47, 10)));
960
+ $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 47, 10)));
948
961
  if ($val =~ /^([EW])(\d{3})(\d+$)$/) {
949
962
  $tags{GPSLongitude} = ($2 + $3 / 600000) * ($1 eq 'W' ? -1 : 1);
950
963
  }
951
- $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 0x39, 5)));
964
+ $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 0x39, 5)));
952
965
  $tags{GPSAltitude} = $val + 0 if $val =~ /^[-+]\d+$/;
953
- $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 0x3e, 3)));
966
+ $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 0x3e, 3)));
954
967
  if ($val =~ /^\d+$/) {
955
968
  $tags{GPSSpeed} = $val + 0;
956
969
  $tags{GPSSpeedRef} = 'K';
957
970
  }
958
- if ($$buffPt =~ /^\0\0..\xaa\xaa/s) { # (BlueSkySea)
959
- $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 0xad, 12)));
971
+ if ($$dataPt =~ /^\0\0..\xaa\xaa/s) { # (BlueSkySea)
972
+ $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 0xad, 12)));
960
973
  # the first X,Y,Z accelerometer readings from the AccelerometerData
961
974
  if ($val =~ /^([-+]\d{3})([-+]\d{3})([-+]\d{3})$/) {
962
975
  $tags{Accelerometer} = "$1 $2 $3";
963
- $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 0xba, 96)));
976
+ $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 0xba, 96)));
964
977
  my $order = GetByteOrder();
965
978
  SetByteOrder('II');
966
979
  $val = ReadValue(\$val, 0, 'float');
@@ -969,7 +982,7 @@ sub Process_text($$$)
969
982
  }
970
983
  } else { # (Ambarella)
971
984
  my @acc;
972
- $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 0x41, 195)));
985
+ $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 0x41, 195)));
973
986
  push @acc, $1, $2, $3 while $val =~ /\G([-+]\d{3})([-+]\d{3})([-+]\d{3})/g;
974
987
  $tags{Accelerometer} = "@acc" if @acc;
975
988
  }
@@ -980,36 +993,36 @@ sub Process_text($$$)
980
993
  # check for DJI telemetry data, eg:
981
994
  # "F/3.5, SS 1000, ISO 100, EV 0, GPS (8.6499, 53.1665, 18), D 24.26m,
982
995
  # H 6.00m, H.S 2.10m/s, V.S 0.00m/s \n"
983
- if ($$buffPt =~ /GPS \(([-+]?\d*\.\d+),\s*([-+]?\d*\.\d+)/) {
996
+ if ($$dataPt =~ /GPS \(([-+]?\d*\.\d+),\s*([-+]?\d*\.\d+)/) {
984
997
  $$et{CreateDateAtEnd} = 1; # set flag indicating the file creation date is at the end
985
998
  $tags{GPSLatitude} = $2;
986
999
  $tags{GPSLongitude} = $1;
987
- $tags{GPSAltitude} = $1 if $$buffPt =~ /,\s*H\s+([-+]?\d+\.?\d*)m/;
988
- if ($$buffPt =~ /,\s*H.S\s+([-+]?\d+\.?\d*)/) {
1000
+ $tags{GPSAltitude} = $1 if $$dataPt =~ /,\s*H\s+([-+]?\d+\.?\d*)m/;
1001
+ if ($$dataPt =~ /,\s*H.S\s+([-+]?\d+\.?\d*)/) {
989
1002
  $tags{GPSSpeed} = $1 * $mpsToKph;
990
1003
  $tags{GPSSpeedRef} = 'K';
991
1004
  }
992
- $tags{Distance} = $1 * $mpsToKph if $$buffPt =~ /,\s*D\s+(\d+\.?\d*)m/;
993
- $tags{VerticalSpeed} = $1 if $$buffPt =~ /,\s*V.S\s+([-+]?\d+\.?\d*)/;
994
- $tags{FNumber} = $1 if $$buffPt =~ /\bF\/(\d+\.?\d*)/;
995
- $tags{ExposureTime} = 1 / $1 if $$buffPt =~ /\bSS\s+(\d+\.?\d*)/;
996
- $tags{ExposureCompensation} = ($1 / ($2 || 1)) if $$buffPt =~ /\bEV\s+([-+]?\d+\.?\d*)(\/\d+)?/;
997
- $tags{ISO} = $1 if $$buffPt =~ /\bISO\s+(\d+\.?\d*)/;
1005
+ $tags{Distance} = $1 * $mpsToKph if $$dataPt =~ /,\s*D\s+(\d+\.?\d*)m/;
1006
+ $tags{VerticalSpeed} = $1 if $$dataPt =~ /,\s*V.S\s+([-+]?\d+\.?\d*)/;
1007
+ $tags{FNumber} = $1 if $$dataPt =~ /\bF\/(\d+\.?\d*)/;
1008
+ $tags{ExposureTime} = 1 / $1 if $$dataPt =~ /\bSS\s+(\d+\.?\d*)/;
1009
+ $tags{ExposureCompensation} = ($1 / ($2 || 1)) if $$dataPt =~ /\bEV\s+([-+]?\d+\.?\d*)(\/\d+)?/;
1010
+ $tags{ISO} = $1 if $$dataPt =~ /\bISO\s+(\d+\.?\d*)/;
998
1011
  HandleTextTags($et, $tagTbl, \%tags);
999
1012
  return;
1000
1013
  }
1001
1014
 
1002
1015
  # check for Mini 0806 dashcam GPS, eg:
1003
1016
  # "A,270519,201555.000,3356.8925,N,08420.2071,W,000.0,331.0M,+01.84,-09.80,-00.61;\n"
1004
- if ($$buffPt =~ /^A,(\d{2})(\d{2})(\d{2}),(\d{2})(\d{2})(\d{2}(\.\d+)?)/) {
1017
+ if ($$dataPt =~ /^A,(\d{2})(\d{2})(\d{2}),(\d{2})(\d{2})(\d{2}(\.\d+)?)/) {
1005
1018
  $tags{GPSDateTime} = "20$3:$2:$1 $4:$5:$6Z";
1006
- if ($$buffPt =~ /^A,.*?,.*?,(\d{2})(\d+\.\d+),([NS])/) {
1019
+ if ($$dataPt =~ /^A,.*?,.*?,(\d{2})(\d+\.\d+),([NS])/) {
1007
1020
  $tags{GPSLatitude} = ($1 + $2/60) * ($3 eq 'S' ? -1 : 1);
1008
1021
  }
1009
- if ($$buffPt =~ /^A,.*?,.*?,.*?,.*?,(\d{3})(\d+\.\d+),([EW])/) {
1022
+ if ($$dataPt =~ /^A,.*?,.*?,.*?,.*?,(\d{3})(\d+\.\d+),([EW])/) {
1010
1023
  $tags{GPSLongitude} = ($1 + $2/60) * ($3 eq 'W' ? -1 : 1);
1011
1024
  }
1012
- my @a = split ',', $$buffPt;
1025
+ my @a = split ',', $$dataPt;
1013
1026
  $tags{GPSAltitude} = $a[8] if $a[8] and $a[8] =~ s/M$//;
1014
1027
  $tags{GPSSpeed} = $a[7] if $a[7] and $a[7] =~ /^\d+\.\d+$/; # (NC)
1015
1028
  $tags{Accelerometer} = "$a[9] $a[10] $a[11]" if $a[11] and $a[11] =~ s/;\s*$//;
@@ -1022,10 +1035,10 @@ sub Process_text($$$)
1022
1035
  # decoded:
1023
1036
  # "X0000.2340Y-000.0720Z0000.9900G0001.0400$GPRMC,082138,A,5330.6683,N,00641.9749,W,012.5,87.86,050213,002.1,A"
1024
1037
  # (note: "002.1" is magnetic variation and is not decoded; it should have ",E" or ",W" afterward for direction)
1025
- if ($$buffPt =~ /\*[0-9A-F]{2}~$/) {
1038
+ if ($$dataPt =~ /\*[0-9A-F]{2}~$/) {
1026
1039
  # (ref https://reverseengineering.stackexchange.com/questions/11582/how-to-reverse-engineer-dash-cam-metadata)
1027
1040
  my @decode = unpack 'C*', '-I8XQWRVNZOYPUTA0B1C2SJ9K.L,M$D3E4F5G6H7';
1028
- my @chars = unpack 'C*', substr($$buffPt, 0, -4);
1041
+ my @chars = unpack 'C*', substr($$dataPt, 0, -4);
1029
1042
  foreach (@chars) {
1030
1043
  my $n = $_ - 43;
1031
1044
  $_ = $decode[$n] if $n >= 0 and defined $decode[$n];
@@ -1034,14 +1047,14 @@ sub Process_text($$$)
1034
1047
  if ($buff =~ /X(.*?)Y(.*?)Z(.*?)G(.*?)\$/) {
1035
1048
  # yup. the decoding worked out
1036
1049
  $tags{Accelerometer} = "$1 $2 $3 $4";
1037
- $$buffPt = $buff; # (process GPRMC below)
1050
+ $$dataPt = $buff; # (process GPRMC below)
1038
1051
  }
1039
1052
  }
1040
1053
 
1041
1054
  # check for Thinkware format (and other NMEA RMC), eg:
1042
1055
  # "gsensori,4,512,-67,-12,100;GNRMC,161313.00,A,4529.87489,N,07337.01215,W,6.225,35.34,310819,,,A*52..;
1043
1056
  # CAR,0,0,0,0.0,0,0,0,0,0,0,0,0"
1044
- if ($$buffPt =~ /[A-Z]{2}RMC,(\d{2})(\d{2})(\d+(\.\d*)?),A?,(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/ and
1057
+ if ($$dataPt =~ /[A-Z]{2}RMC,(\d{2})(\d{2})(\d+(\.\d*)?),A?,(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/ and
1045
1058
  # do some basic sanity checks on the date
1046
1059
  $13 <= 31 and $14 <= 12 and $15 <= 99)
1047
1060
  {
@@ -1058,8 +1071,8 @@ sub Process_text($$$)
1058
1071
  $tags{GPSTrackRef} = 'T';
1059
1072
  }
1060
1073
  }
1061
- $tags{GSensor} = $1 if $$buffPt =~ /\bgsensori,(.*?)(;|$)/;
1062
- $tags{Car} = $1 if $$buffPt =~ /\bCAR,(.*?)(;|$)/;
1074
+ $tags{GSensor} = $1 if $$dataPt =~ /\bgsensori,(.*?)(;|$)/;
1075
+ $tags{Car} = $1 if $$dataPt =~ /\bCAR,(.*?)(;|$)/;
1063
1076
 
1064
1077
  if (%tags) {
1065
1078
  HandleTextTags($et, $tagTbl, \%tags);
@@ -1233,7 +1246,7 @@ sub ProcessSamples($)
1233
1246
  $et->HandleTag($tagTbl, Text => $buff); # just store any other text
1234
1247
  }
1235
1248
  }
1236
- Process_text($et, $tagTbl, \$buff);
1249
+ Process_text($et, \$buff, $tagTbl);
1237
1250
 
1238
1251
  } elsif ($processByMetaFormat{$type}) {
1239
1252
 
@@ -1254,7 +1267,7 @@ sub ProcessSamples($)
1254
1267
  # "X0000.0000Y0000.0000Z0000.0000G0000.0000$GPRMC,000125,V,,,,,000.0,,280908,002.1,N*71~, 794021 \x0a"
1255
1268
  FoundSomething($et, $tagTbl, $time[$i], $dur[$i]);
1256
1269
  $et->HandleTag($tagTbl, Accelerometer => "$1 $2 $3 $4") if $buff =~ /X(.*?)Y(.*?)Z(.*?)G(.*?)\$/;
1257
- Process_text($et, $tagTbl, \$buff);
1270
+ Process_text($et, \$buff, $tagTbl);
1258
1271
  }
1259
1272
  } elsif ($verbose) {
1260
1273
  $et->VPrint(0, "Unknown $type format ($metaFormat)");
@@ -387,8 +387,11 @@ numerical, and generated automatically otherwise.
387
387
  'Flattened' - [reserved] used internally to mark Struct tags
388
388
  which have been processed to generate flattened equivalents.
389
389
 
390
- 'GotGroups' - [reserved] flag used internally to indicate that
391
- the Groups hash has been initialized for this tag.
390
+ 'NotFlat' - [XMP tags only] Flag indicates that this tag ID
391
+ does not represent a flattened tag. Used to avoid a conflict
392
+ if the tag ID would be the same as a generated ID for a
393
+ flattened tag. The result is that the flattened tag will not
394
+ be accessible.
392
395
 
393
396
  'Hidden' - set to hide tag from the TagName documentation.
394
397
  Also suppresses verbose output of a BinaryData tag.
@@ -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.01';
18
+ $VERSION = '1.02';
19
19
 
20
20
  # Radiance tags
21
21
  %Image::ExifTool::Radiance::Main = (
@@ -42,6 +42,7 @@ $VERSION = '1.01';
42
42
  },
43
43
  },
44
44
  _command => 'Command',
45
+ _comment => 'Comment',
45
46
  software => 'Software',
46
47
  view => 'View',
47
48
  'format' => 'Format', # <-- this is the one that caused the conflict when uppercase
@@ -74,8 +75,12 @@ sub ProcessHDR($$)
74
75
  while ($raf->ReadLine($buff)) {
75
76
  chomp $buff;
76
77
  last unless length($buff) > 0 and length($buff) < 4096;
78
+ if ($buff =~ s/^#\s*//) {
79
+ $et->HandleTag($tagTablePtr, '_comment', $buff) if length $buff;
80
+ next;
81
+ }
77
82
  unless ($buff =~ /^(.*)?\s*=\s*(.*)/) {
78
- $et->HandleTag($tagTablePtr, '_command', $buff);
83
+ $et->HandleTag($tagTablePtr, '_command', $buff) if length $buff;
79
84
  next;
80
85
  }
81
86
  # use lower-case tag names to avoid conflicts with reserved tag table entries