exiftool_vendored 12.86.0 → 12.92.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +81 -1
  3. data/bin/MANIFEST +1 -0
  4. data/bin/META.json +2 -2
  5. data/bin/META.yml +17 -17
  6. data/bin/README +3 -2
  7. data/bin/build_geolocation +7 -4
  8. data/bin/config_files/onone.config +28 -0
  9. data/bin/exiftool +23 -15
  10. data/bin/lib/Image/ExifTool/AIFF.pm +8 -4
  11. data/bin/lib/Image/ExifTool/ASF.pm +4 -1
  12. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +12 -7
  13. data/bin/lib/Image/ExifTool/Canon.pm +75 -10
  14. data/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
  15. data/bin/lib/Image/ExifTool/CanonVRD.pm +1 -1
  16. data/bin/lib/Image/ExifTool/FujiFilm.pm +46 -4
  17. data/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
  18. data/bin/lib/Image/ExifTool/Geolocation.pm +6 -0
  19. data/bin/lib/Image/ExifTool/InDesign.pm +8 -4
  20. data/bin/lib/Image/ExifTool/Jpeg2000.pm +0 -1
  21. data/bin/lib/Image/ExifTool/Lang/de.pm +2 -2
  22. data/bin/lib/Image/ExifTool/Matroska.pm +66 -10
  23. data/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -2
  24. data/bin/lib/Image/ExifTool/Nikon.pm +36 -2
  25. data/bin/lib/Image/ExifTool/PNG.pm +10 -2
  26. data/bin/lib/Image/ExifTool/Panasonic.pm +1 -0
  27. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +1 -0
  28. data/bin/lib/Image/ExifTool/Pentax.pm +80 -14
  29. data/bin/lib/Image/ExifTool/QuickTime.pm +51 -9
  30. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +111 -8
  31. data/bin/lib/Image/ExifTool/RIFF.pm +20 -10
  32. data/bin/lib/Image/ExifTool/Samsung.pm +28 -19
  33. data/bin/lib/Image/ExifTool/Sony.pm +21 -11
  34. data/bin/lib/Image/ExifTool/TagLookup.pm +6804 -6784
  35. data/bin/lib/Image/ExifTool/TagNames.pod +92 -21
  36. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +84 -15
  37. data/bin/lib/Image/ExifTool/Writer.pl +7 -4
  38. data/bin/lib/Image/ExifTool/XMP.pm +8 -8
  39. data/bin/lib/Image/ExifTool/XMP2.pl +51 -30
  40. data/bin/lib/Image/ExifTool/ZIP.pm +8 -4
  41. data/bin/lib/Image/ExifTool.pm +22 -16
  42. data/bin/lib/Image/ExifTool.pod +15 -6
  43. data/bin/perl-Image-ExifTool.spec +1 -1
  44. data/lib/exiftool_vendored/version.rb +1 -1
  45. metadata +3 -2
@@ -562,7 +562,7 @@ sub BuildMakerNotes($$$$$$);
562
562
  3 => {
563
563
  Name => 'Rotation',
564
564
  Format => 'int32s',
565
- Writable => 'int32s',
565
+ Writable => 1,
566
566
  },
567
567
  4 => 'ComponentBitDepth', #3
568
568
  5 => 'ColorBitDepth', #3
@@ -1306,7 +1306,7 @@ my $blankFooter = "CANON OPTIONAL DATA\0" . ("\0" x 42) . "\xff\xd9";
1306
1306
  # 2 - value: 6
1307
1307
  3 => {
1308
1308
  Name => 'DR4CameraModel',
1309
- Writable => 'int32u',
1309
+ Format => 'int32u',
1310
1310
  PrintHex => 1,
1311
1311
  SeparateTable => 'Canon CanonModelID',
1312
1312
  PrintConv => \%Image::ExifTool::Canon::canonModelID,
@@ -31,7 +31,7 @@ use vars qw($VERSION);
31
31
  use Image::ExifTool qw(:DataAccess :Utils);
32
32
  use Image::ExifTool::Exif;
33
33
 
34
- $VERSION = '1.94';
34
+ $VERSION = '1.95';
35
35
 
36
36
  sub ProcessFujiDir($$$);
37
37
  sub ProcessFaceRec($$$);
@@ -1169,6 +1169,46 @@ my %faceCategories = (
1169
1169
  Face8Birthday => { },
1170
1170
  );
1171
1171
 
1172
+ # tags extracted from RAF header
1173
+ %Image::ExifTool::FujiFilm::RAFHeader = (
1174
+ PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
1175
+ GROUPS => { 0 => 'RAF', 1 => 'RAF', 2 => 'Image' },
1176
+ NOTES => 'Tags extracted from the header of RAF images.',
1177
+ # 0x00 - eg. "FUJIFILMCCD-RAW 0201FA392001FinePix S3Pro"
1178
+ 0x3c => { #PH
1179
+ Name => 'RAFVersion',
1180
+ Format => 'undef[4]',
1181
+ },
1182
+ # (all int32u values)
1183
+ # 0x40 - 1 for M-RAW, 0 otherwise?
1184
+ # 0x44 - high word of M-RAW offset? (only seen zero)
1185
+ # 0x48 - M-RAW header offset
1186
+ # 0x4c - M-RAW header length
1187
+ # 0x50 - ? (only seen zero)
1188
+ # 0x54 - JPEG offset
1189
+ # 0x58 - JPEG length
1190
+ # 0x5c - RAF directory offset
1191
+ # 0x60 - RAF directory length
1192
+ # 0x64 - FujiIFD dir offset
1193
+ # 0x68 - FujiIFD dir length
1194
+ # 0x6c - RAFCompression or JPEG start
1195
+ 0x6c => { #10
1196
+ Name => 'RAFCompression',
1197
+ Condition => '$$valPt =~ /^\0\0\0/', # (JPEG header is in this location for some RAF versions)
1198
+ Format => 'int32u',
1199
+ PrintConv => { 0 => 'Uncompressed', 2 => 'Lossless', 3 => 'Lossy' },
1200
+ },
1201
+ # 0x70 - ? same as 0x68?
1202
+ # 0x74 - ? usually 0, but have seen 0x1700
1203
+ # 0x78 - RAF1 dir offset
1204
+ # 0x7c - RAF1 dir length
1205
+ # 0x80 - FujiIFD1 dir offset
1206
+ # 0x84 - FujiIFD1 dir length
1207
+ # 0x88-0x8c - always zero?
1208
+ # 0x90 - ? same as 0x74?
1209
+ # 0x94 - JPEG or M-RAW start
1210
+ );
1211
+
1172
1212
  # tags in RAF images (ref 5)
1173
1213
  %Image::ExifTool::FujiFilm::RAF = (
1174
1214
  PROCESS_PROC => \&ProcessFujiDir,
@@ -1797,7 +1837,7 @@ sub ProcessRAF($$)
1797
1837
  my ($buff, $jpeg, $warn, $offset);
1798
1838
 
1799
1839
  my $raf = $$dirInfo{RAF};
1800
- $raf->Read($buff,0x5c) == 0x5c or return 0;
1840
+ $raf->Read($buff,0x70) == 0x70 or return 0;
1801
1841
  $buff =~ /^FUJIFILM/ or return 0;
1802
1842
  # get position and size of M-RAW header and jpeg preview
1803
1843
  my ($mpos, $mlen) = unpack('x72NN', $buff);
@@ -1807,9 +1847,11 @@ sub ProcessRAF($$)
1807
1847
  $raf->Seek($jpos, 0) or return 0;
1808
1848
  $raf->Read($jpeg, $jlen) == $jlen or return 0;
1809
1849
  }
1850
+ SetByteOrder('MM');
1810
1851
  $et->SetFileType();
1811
- $et->FoundTag('RAFVersion', substr($buff, 0x3c, 4));
1812
-
1852
+ my $tbl = GetTagTable('Image::ExifTool::FujiFilm::RAFHeader');
1853
+ $et->ProcessDirectory({ DataPt => \$buff, DirName => 'RAFHeader' }, $tbl);
1854
+
1813
1855
  # extract information from embedded JPEG
1814
1856
  my %dirInfo = (
1815
1857
  Parent => 'RAF',
Binary file
@@ -509,6 +509,12 @@ sub Geolocate($;$)
509
509
  $city = '' unless defined $city;
510
510
  } elsif (/^[-+]?\d+(\.\d+)?$/) { # coordinate format
511
511
  push @coords, $_ if @coords < 2;
512
+ } elsif (/^([-+]?\d+(?:\.\d+)?) *(([NS])[A-Z]*)? +([-+]?\d+(?:\.\d+)?) *(([EW])[A-Z]*)?/i) { # "lat lon" format
513
+ next if @coords;
514
+ my ($lat, $lon) = ($1, $4);
515
+ $lat = -abs($lat) if $3 and uc($3) eq 'S';
516
+ $lon = -abs($lon) if $6 and uc($6) eq 'W';
517
+ push @coords, $lat, $lon;
512
518
  } elsif (lc $_ eq 'both') {
513
519
  $both = 1;
514
520
  } elsif ($_ =~ /^num=(\d+)$/i) {
@@ -14,7 +14,7 @@ use strict;
14
14
  use vars qw($VERSION);
15
15
  use Image::ExifTool qw(:DataAccess :Utils);
16
16
 
17
- $VERSION = '1.06';
17
+ $VERSION = '1.07';
18
18
 
19
19
  # map for writing metadata to InDesign files (currently only write XMP)
20
20
  my %indMap = (
@@ -73,9 +73,13 @@ sub ProcessIND($$)
73
73
  my $pages = Get32u($curPage, 280);
74
74
  $pages < 2 and $err = 'Invalid page count', goto DONE;
75
75
  my $pos = $pages * 4096;
76
- if ($pos > 0x7fffffff and not $et->Options('LargeFileSupport')) {
77
- $err = 'InDesign files larger than 2 GB not supported (LargeFileSupport not set)';
78
- goto DONE;
76
+ if ($pos > 0x7fffffff) {
77
+ if (not $et->Options('LargeFileSupport')) {
78
+ $err = 'InDesign files larger than 2 GB not supported (LargeFileSupport not set)';
79
+ goto DONE;
80
+ } elsif ($et->Options('LargeFileSupport') eq '2') {
81
+ $et->WarnOnce('Processing large file (LargeFileSupport is 2)');
82
+ }
79
83
  }
80
84
  if ($outfile) {
81
85
  # make XMP the preferred group for writing
@@ -727,7 +727,6 @@ my %j2cMarker = (
727
727
  {
728
728
  Name => 'ColorSpecData',
729
729
  Format => 'undef[$size-3]',
730
- Writable => 'undef',
731
730
  Protected => 1,
732
731
  Binary => 1,
733
732
  },
@@ -11,7 +11,7 @@ package Image::ExifTool::Lang::de;
11
11
  use strict;
12
12
  use vars qw($VERSION);
13
13
 
14
- $VERSION = '1.36';
14
+ $VERSION = '1.37';
15
15
 
16
16
  %Image::ExifTool::Lang::de::Translate = (
17
17
  'AEAperture' => 'AE-Blende',
@@ -5118,7 +5118,7 @@ $VERSION = '1.36';
5118
5118
  'LensMake' => 'Objektivhersteller',
5119
5119
  'LensManufacturer' => 'Objektivhersteller',
5120
5120
  'LensMaxApertureRange' => 'Objektiv Blendenbereich',
5121
- 'LensModel' => 'Objektiv-Typ',
5121
+ 'LensModel' => 'Objektivmodell',
5122
5122
  'LensProfileDigest' => 'Kennwert des Objektivprofils',
5123
5123
  'LensProperties' => 'Objektivfunktionen?',
5124
5124
  'LensSerialNumber' => 'Objektiv-Seriennummer',
@@ -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.15';
18
+ $VERSION = '1.16';
19
19
 
20
20
  sub HandleStruct($$;$$$$);
21
21
 
@@ -44,7 +44,8 @@ my %uidInfo = (
44
44
  NOTES => q{
45
45
  The following tags are extracted from Matroska multimedia container files.
46
46
  This container format is used by file types such as MKA, MKV, MKS and WEBM.
47
- For speed, by default ExifTool extracts tags only up to the first Cluster.
47
+ For speed, by default ExifTool extracts tags only up to the first Cluster
48
+ unless a Seek element specifies the position of a Tags element after this.
48
49
  However, the L<Verbose|../ExifTool.html#Verbose> (-v) and L<Unknown|../ExifTool.html#Unknown> = 2 (-U) options force processing of
49
50
  Cluster data, and the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> (-ee) option skips over Clusters to
50
51
  read subsequent tags. See
@@ -112,8 +113,25 @@ my %uidInfo = (
112
113
  Name => 'Seek',
113
114
  SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
114
115
  },
115
- 0x13ab => { Name => 'SeekID', Binary => 1, Unknown => 1 },
116
- 0x13ac => { Name => 'SeekPosition', Format => 'unsigned', Unknown => 1 },
116
+ 0x13ab => {
117
+ Name => 'SeekID',
118
+ Unknown => 1,
119
+ SeekInfo => 'ID', # save seek ID's
120
+ # (note: converted from VInt internally)
121
+ PrintConv => q{
122
+ my $tagInfo = $Image::ExifTool::Matroska::Main{$val};
123
+ $val = sprintf('0x%x', $val);
124
+ $val .= " ($$tagInfo{Name})" if ref $tagInfo eq 'HASH' and $$tagInfo{Name};
125
+ return $val;
126
+ },
127
+ },
128
+ 0x13ac => {
129
+ Name => 'SeekPosition',
130
+ Format => 'unsigned',
131
+ Unknown => 1,
132
+ SeekInfo => 'Position', # save seek positions
133
+ RawConv => '$val + $$self{SeekHeadOffset}',
134
+ },
117
135
  #
118
136
  # Segment Info
119
137
  #
@@ -350,8 +368,9 @@ my %uidInfo = (
350
368
  Name => 'VideoScanType',
351
369
  Format => 'unsigned',
352
370
  PrintConv => {
353
- 0 => 'Progressive',
371
+ 0 => 'Undetermined',
354
372
  1 => 'Interlaced',
373
+ 2 => 'Progressive',
355
374
  },
356
375
  },
357
376
  0x13b8 => {
@@ -893,6 +912,7 @@ sub HandleStruct($$;$$$$)
893
912
  # Inputs: 0) data buffer, 1) position in data
894
913
  # Returns: integer value and updates position, -1 for unknown/reserved value,
895
914
  # or undef if no data left
915
+ # Notes: Increments position pointer
896
916
  sub GetVInt($$)
897
917
  {
898
918
  return undef if $_[1] >= length $_[0];
@@ -929,7 +949,7 @@ sub ProcessMKV($$)
929
949
  {
930
950
  my ($et, $dirInfo) = @_;
931
951
  my $raf = $$dirInfo{RAF};
932
- my ($buff, $buf2, @dirEnd, $trackIndent, %trackTypes, $struct);
952
+ my ($buff, $buf2, @dirEnd, $trackIndent, %trackTypes, $struct, %seekInfo, %seek);
933
953
 
934
954
  $raf->Read($buff, 4) == 4 or return 0;
935
955
  return 0 unless $buff =~ /^\x1a\x45\xdf\xa3/;
@@ -952,6 +972,7 @@ sub ProcessMKV($$)
952
972
  my $processAll = ($verbose or $et->Options('Unknown') > 1) ? 2 : 0;
953
973
  ++$processAll if $et->Options('ExtractEmbedded');
954
974
  $$et{TrackTypes} = \%trackTypes; # store Track types reference
975
+ $$et{SeekHeadOffset} = 0;
955
976
  my $oldIndent = $$et{INDENT};
956
977
  my $chapterNum = 0;
957
978
  my $dirName = 'MKV';
@@ -960,6 +981,16 @@ sub ProcessMKV($$)
960
981
  for (;;) {
961
982
  while (@dirEnd) {
962
983
  if ($pos + $dataPos >= $dirEnd[-1][0]) {
984
+ if ($dirEnd[-1][1] eq 'Seek') {
985
+ # save seek info
986
+ if (defined $seekInfo{ID} and defined $seekInfo{Position}) {
987
+ my $seekTag = $$tagTablePtr{$seekInfo{ID}};
988
+ if (ref $seekTag eq 'HASH' and $$seekTag{Name}) {
989
+ $seek{$$seekTag{Name}} = $seekInfo{Position} + $$et{SeekHeadOffset};
990
+ }
991
+ }
992
+ undef %seekInfo;
993
+ }
963
994
  pop @dirEnd;
964
995
  if ($struct) {
965
996
  if (@dirEnd and $dirEnd[-1][2]) {
@@ -993,9 +1024,10 @@ sub ProcessMKV($$)
993
1024
  }
994
1025
  my $tag = GetVInt($buff, $pos);
995
1026
  last unless defined $tag and $tag >= 0;
1027
+ $$et{SeekHeadOffset} = $pos if $tag == 0x14d9b74; # save offset of seek head
996
1028
  my $size = GetVInt($buff, $pos);
997
1029
  last unless defined $size;
998
- my $unknownSize;
1030
+ my ($unknownSize, $seekInfoOnly);
999
1031
  $size < 0 and $unknownSize = 1, $size = 1e20;
1000
1032
  if (@dirEnd and $pos + $dataPos + $size > $dirEnd[-1][0]) {
1001
1033
  $et->Warn("Invalid or corrupted $dirEnd[-1][1] master element");
@@ -1010,14 +1042,28 @@ sub ProcessMKV($$)
1010
1042
  next;
1011
1043
  }
1012
1044
  my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
1013
- # just fall through into the contained EBML elements
1045
+ if (not $tagInfo and ref $$tagTablePtr{$tag} eq 'HASH' and $$tagTablePtr{$tag}{SeekInfo}) {
1046
+ $tagInfo = $$tagTablePtr{$tag};
1047
+ $seekInfoOnly = 1;
1048
+ }
1014
1049
  if ($tagInfo) {
1015
1050
  if ($$tagInfo{SubDirectory}) {
1016
1051
  # stop processing at first cluster unless we are using -v -U or -ee
1052
+ # or there are Tags after this
1017
1053
  if ($$tagInfo{Name} eq 'Cluster' and $processAll < 2) {
1018
- last unless $processAll;
1054
+ # jump to Tags if possible
1055
+ unless ($processAll) {
1056
+ if ($seek{Tags} and $seek{Tags} > $pos + $dataPos and $raf->Seek($seek{Tags},0)) {
1057
+ $buff = '';
1058
+ $dataPos = $seek{Tags};
1059
+ $pos = $dataLen = 0;
1060
+ next;
1061
+ }
1062
+ last;
1063
+ }
1019
1064
  undef $tagInfo; # just skip the Cluster when -ee is used
1020
1065
  } else {
1066
+ # just fall through into the contained EBML elements
1021
1067
  $$et{INDENT} .= '| ';
1022
1068
  $et->VerboseDir($$tagTablePtr{$tag}{Name}, undef, $size);
1023
1069
  $dirName = $$tagInfo{Name};
@@ -1040,7 +1086,12 @@ sub ProcessMKV($$)
1040
1086
  # just skip unknown and large data blocks
1041
1087
  if (not $tagInfo or $more > 10000000) {
1042
1088
  # don't try to skip very large blocks unless LargeFileSupport is enabled
1043
- last if $more >= 0x80000000 and not $et->Options('LargeFileSupport');
1089
+ if ($more >= 0x80000000) {
1090
+ last unless $et->Options('LargeFileSupport');
1091
+ if ($et->Options('LargeFileSupport') eq '2') {
1092
+ $et->WarnOnce('Processing large block (LargeFileSupport is 2)');
1093
+ }
1094
+ }
1044
1095
  $raf->Seek($more, 1) or last;
1045
1096
  $buff = '';
1046
1097
  $dataPos += $dataLen + $more;
@@ -1118,6 +1169,11 @@ sub ProcessMKV($$)
1118
1169
  if ($$tagInfo{NoSave} or $struct) {
1119
1170
  $et->VerboseInfo($tag, $tagInfo, Value => $val, %parms) if $verbose;
1120
1171
  $$struct{$$tagInfo{Name}} = $val if $struct;
1172
+ } elsif ($$tagInfo{SeekInfo}) {
1173
+ my $p = $pos;
1174
+ $val = GetVInt($buff, $p) unless defined $val;
1175
+ $seekInfo{$$tagInfo{SeekInfo}} = $val;
1176
+ $et->HandleTag($tagTablePtr, $tag, $val, %parms) unless $seekInfoOnly;
1121
1177
  } else {
1122
1178
  $et->HandleTag($tagTablePtr, $tag, $val, %parms);
1123
1179
  }
@@ -203,13 +203,13 @@ sub WriteMRW($$;$);
203
203
  Name => 'ColorMode',
204
204
  Condition => '$$self{Make} !~ /^SONY/',
205
205
  Priority => 0,
206
- Writable => 'int32u',
206
+ Writable => 1,
207
207
  PrintConv => \%Image::ExifTool::Minolta::minoltaColorMode,
208
208
  },
209
209
  { #3
210
210
  Name => 'ColorMode',
211
211
  Condition => '$$self{Model} eq "DSLR-A100"',
212
- Writable => 'int32u',
212
+ Writable => 1,
213
213
  Notes => 'Sony A100',
214
214
  Priority => 0,
215
215
  PrintHex => 1,
@@ -65,7 +65,7 @@ use Image::ExifTool::Exif;
65
65
  use Image::ExifTool::GPS;
66
66
  use Image::ExifTool::XMP;
67
67
 
68
- $VERSION = '4.34';
68
+ $VERSION = '4.36';
69
69
 
70
70
  sub LensIDConv($$$);
71
71
  sub ProcessNikonAVI($$$);
@@ -720,6 +720,7 @@ sub GetAFPointGrid($$;$);
720
720
  '9A 4C 50 50 14 14 9C 06' => 'Yongnuo YN50mm F1.8N',
721
721
  '9F 48 48 48 24 24 A1 06' => 'Yongnuo YN40mm F2.8N', #30
722
722
  '9F 54 68 68 18 18 A2 06' => 'Yongnuo YN100mm F2N', #30
723
+ '9F 4C 44 44 18 18 A1 06' => 'Yongnuo YN35mm F2', #30
723
724
  #
724
725
  '02 40 44 5C 2C 34 02 00' => 'Exakta AF 35-70mm 1:3.5-4.5 MC',
725
726
  #
@@ -2494,6 +2495,7 @@ my %base64coord = (
2494
2495
  { # D7100=0227
2495
2496
  Condition => '$$valPt =~ /^0[28]/',
2496
2497
  Name => 'ShotInfo02xx',
2498
+ Drop => 50000, # drop if too large (>64k for Z6iii)
2497
2499
  SubDirectory => {
2498
2500
  TagTable => 'Image::ExifTool::Nikon::ShotInfo',
2499
2501
  ProcessProc => \&ProcessNikonEncrypted,
@@ -5634,6 +5636,38 @@ my %nikonFocalConversions = (
5634
5636
  Notes => 'P6000',
5635
5637
  PrintConv => \%offOn,
5636
5638
  },
5639
+ # for Nikon Z6iii JPG and RAW images (version 0809),
5640
+ # the offset table starts at 0x24 and is as follows
5641
+ # JPG Offset Size NEF Offset Size
5642
+ # 0) 0x0000 0 0) 0x009c 21604
5643
+ # 1) 0x0000 0 1) 0x5500 6008
5644
+ # 2) 0x009c 2528 2) 0x6c78 2528
5645
+ # 3) 0x0a7c 200 3) 0x7658 200
5646
+ # 4) 0x0b44 2488 4) 0x7720 2488
5647
+ # 5) 0x14fc 1468 5) 0x80d8 1468
5648
+ # 6) 0x1ab8 1032 6) 0x8694 1032
5649
+ # 7) 0x1ec0 256 7) 0x8a9c 256
5650
+ # 8) 0x1fc0 800 8) 0x8b9c 800
5651
+ # 9) 0x22e0 144 9) 0x8ebc 144
5652
+ # 10) 0x2370 64 10) 0x8f4c 64
5653
+ # 11) 0x0000 0 11) 0x0000 0
5654
+ # 12) 0x23b0 5009 12) 0x8f8c 5009
5655
+ # 13) 0x3741 1536 13) 0xa31d 1536
5656
+ # 14) 0x3d41 11928 14) 0xa91d 11928
5657
+ # 15) 0x6bd9 5937 15) 0xd7b5 5937
5658
+ # 16) 0x830a 500 16) 0xeee6 500
5659
+ # 17) 0x84fe 160 17) 0xf0da 160
5660
+ # 18) 0x859e 464 18) 0xf17a 464
5661
+ # 19) 0x876e 8 19) 0xf34a 8
5662
+ # 20) 0x8776 64 20) 0xf352 64
5663
+ # 21) 0x87b6 6 21) 0xf392 6
5664
+ # 22) 0x87bc 48 22) 0xf398 48
5665
+ # 23) 0x87ec 20 23) 0xf3c8 20
5666
+ # 24) 0x8800 108 24) 0xf3dc 108
5667
+ # 25) 0x886c 8 25) 0xf448 8
5668
+ # 26) 0x8874 2420 26) 0xf450 2420
5669
+ # 27) 0x0000 0 27) 0x0000 0
5670
+ # 28) 0x0000 0 28) 0x0000 0
5637
5671
  0x66 => {
5638
5672
  Name => 'VR_0x66',
5639
5673
  Condition => '$$self{ShotInfoVersion} eq "0204"',
@@ -11710,7 +11744,7 @@ my %nikonFocalConversions = (
11710
11744
  },
11711
11745
  10 => {
11712
11746
  Name => 'NEFCompression',
11713
- Writable => 'int16u',
11747
+ Format => 'int16u',
11714
11748
  SeparateTable => 'NEFCompression',
11715
11749
  PrintConv => \%nefCompression,
11716
11750
  },
@@ -36,7 +36,7 @@ use strict;
36
36
  use vars qw($VERSION $AUTOLOAD %stdCase);
37
37
  use Image::ExifTool qw(:DataAccess :Utils);
38
38
 
39
- $VERSION = '1.67';
39
+ $VERSION = '1.68';
40
40
 
41
41
  sub ProcessPNG_tEXt($$$);
42
42
  sub ProcessPNG_iTXt($$$);
@@ -1400,7 +1400,7 @@ sub ProcessPNG($$)
1400
1400
  my $fastScan = $et->Options('FastScan');
1401
1401
  my $hash = $$et{ImageDataHash};
1402
1402
  my ($n, $sig, $err, $hbuf, $dbuf, $cbuf);
1403
- my ($wasHdr, $wasEnd, $wasDat, $doTxt, @txtOffset);
1403
+ my ($wasHdr, $wasEnd, $wasDat, $doTxt, @txtOffset, $wasTrailer);
1404
1404
 
1405
1405
  # check to be sure this is a valid PNG/MNG/JNG image
1406
1406
  return 0 unless $raf->Read($sig,8) == 8 and $pngLookup{$sig};
@@ -1461,6 +1461,7 @@ sub ProcessPNG($$)
1461
1461
  if ($wasEnd) {
1462
1462
  last unless $n; # stop now if normal end of PNG
1463
1463
  $et->WarnOnce("Trailer data after $fileType $endChunk chunk", 1);
1464
+ $wasTrailer = 1;
1464
1465
  last if $n < 8;
1465
1466
  $$et{SET_GROUP1} = 'Trailer';
1466
1467
  } elsif ($n != 8) {
@@ -1654,6 +1655,13 @@ sub ProcessPNG($$)
1654
1655
  }
1655
1656
  }
1656
1657
  delete $$et{SET_GROUP1};
1658
+ # read Samsung trailer if it exists
1659
+ if ($wasTrailer and not $outfile and $raf->Seek(-8, 2) and
1660
+ $raf->Read($dbuf,8) and $dbuf =~ /\0\0(QDIOBS|SEFT)$/) # (have only seen SEFT type)
1661
+ {
1662
+ require Image::ExifTool::Samsung;
1663
+ Image::ExifTool::Samsung::ProcessSamsung($et, { DirName => 'Samsung', RAF => $raf });
1664
+ }
1657
1665
  return -1 if $outfile and ($err or not $wasEnd);
1658
1666
  return 1; # this was a valid PNG/MNG/JNG image
1659
1667
  }
@@ -366,6 +366,7 @@ my %shootingMode = (
366
366
  '32 1' => '3-area (left)?', # (DMC-L1 guess)
367
367
  '32 2' => '3-area (center)?', # (DMC-L1 guess)
368
368
  '32 3' => '3-area (right)?', # (DMC-L1 guess)
369
+ # '32 16' ? (DC-GH6)
369
370
  '64 0' => 'Face Detect',
370
371
  '64 1' => 'Face Detect (animal detect on)', #forum11194
371
372
  '64 2' => 'Face Detect (animal detect off)', #forum11194
@@ -218,6 +218,7 @@ my %panasonicWhiteBalance = ( #forum9396
218
218
  0x30 => { Name => 'CropLeft', Writable => 'int16u' },
219
219
  0x31 => { Name => 'CropBottom', Writable => 'int16u' },
220
220
  0x32 => { Name => 'CropRight', Writable => 'int16u' },
221
+ 0x37 => { Name => 'ISO', Writable => 'int32u' },
221
222
  # 0x44 - may contain another pointer to the raw data starting at byte 2 in this data (DC-GH6)
222
223
  0x10f => {
223
224
  Name => 'Make',
@@ -4697,7 +4697,7 @@ my %binaryDataAttrs = (
4697
4697
  3 => 'Grip Battery',
4698
4698
  4 => 'External Power Supply', #PH
4699
4699
  },
4700
- },{ #PH
4700
+ },{ #PH (forum15976)
4701
4701
  Name => 'PowerSource',
4702
4702
  Mask => 0x0f,
4703
4703
  Notes => 'K-3III',
@@ -4709,8 +4709,18 @@ my %binaryDataAttrs = (
4709
4709
  2 => 'Grip Battery',
4710
4710
  4 => 'External Power Supply',
4711
4711
  },
4712
- },{
4713
4712
  }],
4713
+ 0.2 => {
4714
+ Name => 'PowerAvailable',
4715
+ Condition => '$$self{Model} =~ /K-3 Mark III/',
4716
+ Notes => 'K-3III',
4717
+ Mask => 0xf0,
4718
+ PrintConv => { BITMASK => {
4719
+ 0 => 'Body Battery',
4720
+ 1 => 'Grip Battery',
4721
+ 3 => 'External Power Supply',
4722
+ }},
4723
+ },
4714
4724
  1.1 => [
4715
4725
  {
4716
4726
  Name => 'BodyBatteryState',
@@ -4735,11 +4745,6 @@ my %binaryDataAttrs = (
4735
4745
  4 => 'Close to Full',
4736
4746
  5 => 'Full',
4737
4747
  },
4738
- },{
4739
- Name => 'BodyBatteryState',
4740
- Notes => 'decoding unknown for some models',
4741
- Unknown => 1, # (doesn't appear to be valid for the K-3 III)
4742
- Mask => 0xf0,
4743
4748
  },
4744
4749
  ],
4745
4750
  1.2 => [
@@ -4754,11 +4759,6 @@ my %binaryDataAttrs = (
4754
4759
  3 => 'Running Low',
4755
4760
  4 => 'Full',
4756
4761
  },
4757
- },{
4758
- Name => 'GripBatteryState',
4759
- Notes => 'decoding unknown for other models',
4760
- Unknown => 1, # (doesn't appear to be valid for the K-5)
4761
- Mask => 0x0f,
4762
4762
  },
4763
4763
  ],
4764
4764
  # internal and grip battery voltage Analogue to Digital measurements,
@@ -4794,7 +4794,19 @@ my %binaryDataAttrs = (
4794
4794
  # BodyBatteryVoltage4 6.10 V 7.55 V 7.45 V
4795
4795
  # "Meas" open-circuit voltages with DVM: AB=0V, AC=+8.33V, BC=+8.22V
4796
4796
  # (terminal "C" is closest to edge of battery)
4797
- },
4797
+ },{
4798
+ Name => 'BodyBatteryState',
4799
+ Condition => '$$self{Model} =~ /K-3 Mark III/',
4800
+ Notes => 'K-3III',
4801
+ PrintConv => {
4802
+ 0 => 'Empty or Missing',
4803
+ 1 => 'Almost Empty',
4804
+ 2 => 'Running Low',
4805
+ 3 => 'Half Full',
4806
+ 4 => 'Close to Full',
4807
+ 5 => 'Full',
4808
+ },
4809
+ }
4798
4810
  ],
4799
4811
  3 => [
4800
4812
  {
@@ -4810,7 +4822,11 @@ my %binaryDataAttrs = (
4810
4822
  Name => 'BodyBatteryADLoad',
4811
4823
  Description => 'Body Battery A/D Load',
4812
4824
  Condition => '$$self{Model} =~ /(\*ist|K100D|K200D)\b/',
4813
- },
4825
+ },{
4826
+ Name => 'BodyBatteryPercent',
4827
+ Condition => '$$self{Model} =~ /K-3 Mark III/',
4828
+ Notes => 'K-3III',
4829
+ }
4814
4830
  ],
4815
4831
  4 => [
4816
4832
  {
@@ -4827,6 +4843,15 @@ my %binaryDataAttrs = (
4827
4843
  PrintConv => 'sprintf("%.2f V", $val)',
4828
4844
  PrintConvInv => '$val =~ s/\s*V$//',
4829
4845
  },
4846
+ {
4847
+ Name => 'BodyBatteryVoltage',
4848
+ Condition => '$$self{Model} =~ /K-3 Mark III/',
4849
+ Format => 'int32u',
4850
+ ValueConv => '$val * 4e-8 + 0.27219',
4851
+ ValueConvInv => '($val - 0.27219) / 4e-8',
4852
+ PrintConv => 'sprintf("%.2f V", $val)',
4853
+ PrintConvInv => '$val =~ s/\s*V$//',
4854
+ },
4830
4855
  ],
4831
4856
  5 => {
4832
4857
  Name => 'GripBatteryADLoad',
@@ -4853,6 +4878,34 @@ my %binaryDataAttrs = (
4853
4878
  PrintConv => 'sprintf("%.2f V", $val)',
4854
4879
  PrintConvInv => '$val =~ s/\s*V$//',
4855
4880
  },
4881
+ 16 => {
4882
+ Name => 'GripBatteryState',
4883
+ Condition => '$$self{Model} =~ /K-3 Mark III/',
4884
+ Notes => 'K-3III',
4885
+ PrintConv => {
4886
+ 0 => 'Empty or Missing',
4887
+ 1 => 'Almost Empty',
4888
+ 2 => 'Running Low',
4889
+ 3 => 'Half Full',
4890
+ 4 => 'Close to Full',
4891
+ 5 => 'Full',
4892
+ },
4893
+ },
4894
+ 17 => {
4895
+ Name => 'GripBatteryPercent',
4896
+ Condition => '$$self{Model} =~ /K-3 Mark III/',
4897
+ Notes => 'K-3III',
4898
+ },
4899
+ 18 => {
4900
+ Name => 'GripBatteryVoltage',
4901
+ Condition => '$$self{Model} =~ /K-3 Mark III/',
4902
+ Notes => 'K-3III',
4903
+ Format => 'int32u',
4904
+ ValueConv => '$val * 4e-8 + 0.27219',
4905
+ ValueConvInv => '($val - 0.27219) / 4e-8',
4906
+ PrintConv => 'sprintf("%.2f V", $val)',
4907
+ PrintConvInv => '$val =~ s/\s*V$//',
4908
+ },
4856
4909
  );
4857
4910
 
4858
4911
  # auto focus information
@@ -5521,14 +5574,27 @@ my %binaryDataAttrs = (
5521
5574
  GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
5522
5575
  FORMAT => 'int8s',
5523
5576
  NOTES => 'Tags decoded from the electronic level information for the K-3 III.',
5577
+ 1 => {
5578
+ Name => 'CameraOrientation',
5579
+ PrintConv => {
5580
+ 0 => 'Horizontal (normal)',
5581
+ 1 => 'Rotate 270 CW',
5582
+ 2 => 'Rotate 180',
5583
+ 3 => 'Rotate 90 CW',
5584
+ 4 => 'Upwards', # (to the sky)
5585
+ 5 => 'Downwards', # (to the ground)
5586
+ },
5587
+ },
5524
5588
  3 => {
5525
5589
  Name => 'RollAngle',
5590
+ Notes => 'converted to degrees of clockwise camera rotation',
5526
5591
  Format => 'int16s',
5527
5592
  ValueConv => '-$val / 2',
5528
5593
  ValueConvInv => '-$val * 2',
5529
5594
  },
5530
5595
  5 => {
5531
5596
  Name => 'PitchAngle',
5597
+ Notes => 'converted to degrees of upward camera tilt',
5532
5598
  Format => 'int16s',
5533
5599
  ValueConv => '-$val / 2',
5534
5600
  ValueConvInv => '-$val * 2',