exiftool_vendored 12.89.0 → 12.93.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7df2d0fa28308f9ca1e01281f5adb79fb0c7f8a10837bb8bed04119b8176e411
4
- data.tar.gz: c957dcea2b7c27b85bb0dcf947655291551f1d6c9ed60a341c308530e6bf4319
3
+ metadata.gz: 30869a5b033fa93062cf6f635c5cddb484e8ce9671e8b5b803329edf5d34ee7a
4
+ data.tar.gz: 0b886b032d88c6cf22d4052795a6bbc4bd69cc33e40c8a4e308359e5d4ae454f
5
5
  SHA512:
6
- metadata.gz: a5b8e76b963736b502f09c43b1d1d1c3b40533460763e432a5aa0a56151bdda4e5bdaedae95f5a6e7b881437855bee2b9154a88b2c062f7c61a4b0c8f1e4b780
7
- data.tar.gz: a60d7c3d8736f5edd2da67b517880e13a23fd201eefe66774afdeff76a9050055c45e00fe296f21d771d0f193471e807c3608ca79742b14dbe6bd2ce3c20d08f
6
+ metadata.gz: 4c563c23c4d432f21bbf8ae3ce284fbb7c325540a92bb6c7dd1a693afbe16d3e091b015779094e2f2db5d70ef1e73bc4bc4fb34d8044cb2ae62fa992dc7a085f
7
+ data.tar.gz: 8a6cfea51bf26dff8cec28964277ea72446fc6ec3eb877f0c8082c8362dee69b9cb421253af1f3f8b073d067e5b29acb0364ed580ce346880c6541a945a7a706
data/bin/Changes CHANGED
@@ -7,6 +7,40 @@ RSS feed: https://exiftool.org/rss.xml
7
7
  Note: The most recent production release is Version 12.76. (Other versions are
8
8
  considered development releases, and are not uploaded to MetaCPAN.)
9
9
 
10
+ Aug. 20, 2024 - Version 12.93
11
+
12
+ - Added a new Nikon LensID
13
+ - Added a couple of new OpenEXR Compression types
14
+ - Added a couple of new QuickTime Keys tags
15
+ - Decode timed metadata from E-ACE B44 DashCam videos
16
+ - Make "Unrecognized" Samsung Meta warnings minor
17
+ - Fixed bug in -listg6 option which resulted in "uninitialized value" warnings
18
+ - Fixed decoding of Func1Button and Func2Button for the Nikon Z6/Z7
19
+ - Fixed bug reading JUMB metadata from JXL images
20
+
21
+ July 24, 2024 - Version 12.92
22
+
23
+ - Removed -w from exiftool shebang due to compatibility issues on some systems
24
+
25
+ July 24, 2024 - Version 12.91
26
+
27
+ - Added a couple of new OpenEXR Compression values (github#276)
28
+ - Updated 2 test files that were causing failed tests (ExifTool itself is
29
+ unchanged)
30
+
31
+ July 24, 2024 - Version 12.90
32
+
33
+ - Added support for reading Samsung trailer from PNG images
34
+ - Decode two more formats of timed GPS from MP4 videos
35
+ - Decode a few more Samung trailer tags (thanks Neal Krawetz)
36
+ - Decode Canon AntiFlicker tag
37
+ - Drop Nikon ShotInfo record when copying MakerNotes from NEF to JPG if it is
38
+ larger than 50000 bytes (then MakerNotes would be too large for a single
39
+ JPEG segment)
40
+ - Changed exiftool shebang to use env: "#!/usr/bin/env perl -w"
41
+ - Revert change of 12.84 to iterate through sub-documents with the -p option
42
+ only if -ee is used
43
+
10
44
  July 12, 2024 - Version 12.89
11
45
 
12
46
  - Added new Sony lenses and updated decoding of some tags (thanks Jos Roost)
@@ -15,9 +49,7 @@ July 12, 2024 - Version 12.89
15
49
 
16
50
  July 11, 2024 - Version 12.88 - "New Windows/MacOS packages"
17
51
 
18
- -
19
-
20
- NOTE: The install procedure for the Windows executable has changed!
52
+ - NOTE: The install procedure for the Windows executable has changed!
21
53
  - Windows EXE version now uses Oliver Betz's bundle with Strawberry Perl and
22
54
  comes in 32- and 64-bit versions
23
55
  - MacOS distribution now uses a flattened package
@@ -105,6 +137,8 @@ Apr. 23, 2024 - Version 12.84
105
137
  cities
106
138
  - Allow coordinates to be entered without comma separator for the Geolocation
107
139
  feature as long as both coordinates have a decimal point
140
+ - Changed -p option to iterate through sub-documents if they exist even if -ee
141
+ isn't used
108
142
  - Fixed long-standing bug in Windows version that didn't properly handle dates
109
143
  older than 50 years when writing FileModifyDate or FileCreateDate
110
144
  - Fixed API TimeZone option to work in Windows
data/bin/META.json CHANGED
@@ -50,5 +50,5 @@
50
50
  }
51
51
  },
52
52
  "release_status" : "stable",
53
- "version" : "12.89"
53
+ "version" : "12.93"
54
54
  }
data/bin/META.yml CHANGED
@@ -31,4 +31,4 @@ recommends:
31
31
  Time::HiRes: '0'
32
32
  requires:
33
33
  perl: '5.004'
34
- version: '12.89'
34
+ version: '12.93'
data/bin/README CHANGED
@@ -109,8 +109,8 @@ your home directory, then you would type the following commands in a
109
109
  terminal window to extract and run ExifTool:
110
110
 
111
111
  cd ~/Desktop
112
- gzip -dc Image-ExifTool-12.89.tar.gz | tar -xf -
113
- cd Image-ExifTool-12.89
112
+ gzip -dc Image-ExifTool-12.93.tar.gz | tar -xf -
113
+ cd Image-ExifTool-12.93
114
114
  ./exiftool t/images/ExifTool.jpg
115
115
 
116
116
  Note: These commands extract meta information from one of the test images.
@@ -1,4 +1,4 @@
1
- #!/usr/bin/perl -w
1
+ #!/usr/bin/env perl
2
2
  #-------------------------------------------------------------------------------
3
3
  # File: build_geolocation
4
4
  #
data/bin/exiftool CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/perl -w
1
+ #!/usr/bin/env perl
2
2
  #------------------------------------------------------------------------------
3
3
  # File: exiftool
4
4
  #
@@ -11,7 +11,7 @@ use strict;
11
11
  use warnings;
12
12
  require 5.004;
13
13
 
14
- my $version = '12.89';
14
+ my $version = '12.93';
15
15
 
16
16
  # add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
17
17
  my $exePath;
@@ -2310,8 +2310,8 @@ sub GetImageInfo($$)
2310
2310
  # output using print format file (-p) option
2311
2311
  my ($type, $doc, $grp, $lastDoc, $cache);
2312
2312
  $fileTrailer = '';
2313
- # repeat for each sub-document if necessary
2314
- if ($$et{DOC_COUNT}) {
2313
+ # repeat for each embedded document if necessary (only if -ee used)
2314
+ if ($et->Options('ExtractEmbedded')) {
2315
2315
  # (cache tag keys if there are sub-documents)
2316
2316
  $lastDoc = $$et{DOC_COUNT} and $cache = { };
2317
2317
  } else {
@@ -5684,7 +5684,7 @@ with this command:
5684
5684
 
5685
5685
  produces output like this:
5686
5686
 
5687
- -- Generated by ExifTool 12.89 --
5687
+ -- Generated by ExifTool 12.93 --
5688
5688
  File: a.jpg - 2003:10:31 15:44:19
5689
5689
  (f/5.6, 1/60s, ISO 100)
5690
5690
  File: b.jpg - 2006:05:23 11:57:38
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
88
88
  sub ProcessExifInfo($$$);
89
89
  sub SwapWords($);
90
90
 
91
- $VERSION = '4.78';
91
+ $VERSION = '4.80';
92
92
 
93
93
  # Note: Removed 'USM' from 'L' lenses since it is redundant - PH
94
94
  # (or is it? Ref 32 shows 5 non-USM L-type lenses)
@@ -6403,6 +6403,8 @@ my %ciMaxFocal = (
6403
6403
  12 => 'Flexizone Multi (9 point)', #PH (750D, 9 points)
6404
6404
  13 => 'Flexizone Single', #PH (EOS M default, live view) (R7 calls this '1-point AF', ref github268)
6405
6405
  14 => 'Large Zone AF', #PH/forum6237 (7DmkII)
6406
+ 16 => 'Large Zone AF (vertical)', #forum16223
6407
+ 17 => 'Large Zone AF (horizontal)', #forum16223
6406
6408
  19 => 'Flexible Zone AF 1', #github268 (R7)
6407
6409
  20 => 'Flexible Zone AF 2', #github268 (R7)
6408
6410
  21 => 'Flexible Zone AF 3', #github268 (R7)
@@ -6921,6 +6923,10 @@ my %ciMaxFocal = (
6921
6923
  Name => 'FlashExposureLock',
6922
6924
  PrintConv => \%offOn,
6923
6925
  },
6926
+ 32 => { #forum16257
6927
+ Name => 'AntiFlicker',
6928
+ PrintConv => \%offOn,
6929
+ },
6924
6930
  0x3d => { #IB
6925
6931
  Name => 'RFLensType',
6926
6932
  Format => 'int16u',
@@ -9123,19 +9129,19 @@ my %filterConv = (
9123
9129
  2 => 'Disable',
9124
9130
  },
9125
9131
  },
9126
- 18 => { #52
9132
+ 18 => { #52/forum16223
9127
9133
  Name => 'AFStatusViewfinder',
9128
- Condition => '$$self{Model} =~ /1D X/',
9129
- Notes => '1D X only',
9134
+ Condition => '$$self{Model} =~ /EOS-1D X|EOS R/',
9135
+ Notes => '1D X and R models',
9130
9136
  PrintConv => {
9131
9137
  0 => 'Show in Field of View',
9132
9138
  1 => 'Show Outside View',
9133
9139
  },
9134
9140
  },
9135
- 19 => { #52
9141
+ 19 => { #52/forum16223
9136
9142
  Name => 'InitialAFPointInServo',
9137
- Condition => '$$self{Model} =~ /1D X/',
9138
- Notes => '1D X only',
9143
+ Condition => '$$self{Model} =~ /EOS-1D X|EOS R/',
9144
+ Notes => '1D X and R models',
9139
9145
  PrintConv => {
9140
9146
  0 => 'Initial AF Point Selected',
9141
9147
  1 => 'Manual AF Point',
@@ -9193,14 +9199,19 @@ my %filterConv = (
9193
9199
  PrintConvInv => '$val=~s/\s*mm//;$val',
9194
9200
  },
9195
9201
  8 => {
9196
- Name => 'MinFocalLength',
9202
+ Name => 'MinFocalLength2',
9203
+ Notes => q{
9204
+ these seem to be min/max focal length without teleconverter, as opposed to
9205
+ MinFocalLength and MaxFocalLength which include the effect of a
9206
+ teleconverter
9207
+ }, #forum16309
9197
9208
  ValueConv => '$val / 10',
9198
9209
  ValueConvInv => 'int($val * 10 + 0.5)',
9199
9210
  PrintConv => '"$val mm"',
9200
9211
  PrintConvInv => '$val=~s/\s*mm//;$val',
9201
9212
  },
9202
9213
  9 => {
9203
- Name => 'MaxFocalLength',
9214
+ Name => 'MaxFocalLength2',
9204
9215
  ValueConv => '$val / 10',
9205
9216
  ValueConvInv => 'int($val * 10 + 0.5)',
9206
9217
  PrintConv => '"$val mm"',
@@ -16,7 +16,7 @@ use strict;
16
16
  use vars qw($VERSION);
17
17
  use Image::ExifTool qw(:DataAccess :Utils);
18
18
 
19
- $VERSION = '1.39';
19
+ $VERSION = '1.40';
20
20
 
21
21
  sub ProcessJpeg2000Box($$$);
22
22
  sub ProcessJUMD($$$);
@@ -1442,7 +1442,7 @@ sub ProcessBrotli($$$)
1442
1442
  }
1443
1443
  } elsif ($type eq 'jumb') {
1444
1444
  return undef if $isWriting; # (can't yet write JUMBF)
1445
- Image::ExifTool::ProcessJUMB($et, \%dirInfo, $tagTablePtr); # (untested)
1445
+ Image::ExifTool::Jpeg2000::ProcessJUMB($et, \%dirInfo, $tagTablePtr); # (untested)
1446
1446
  }
1447
1447
  if ($isWriting) {
1448
1448
  return undef unless defined $dat;
@@ -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.35';
68
+ $VERSION = '4.37';
69
69
 
70
70
  sub LensIDConv($$$);
71
71
  sub ProcessNikonAVI($$$);
@@ -367,6 +367,7 @@ sub GetAFPointGrid($$;$);
367
367
  '02 46 37 37 25 25 02 00' => 'Sigma 24mm F2.8 Super Wide II Macro',
368
368
  '7E 54 37 37 0C 0C 4B 06' => 'Sigma 24mm F1.4 DG HSM | A', #30
369
369
  '26 58 3C 3C 14 14 1C 02' => 'Sigma 28mm F1.8 EX DG Aspherical Macro',
370
+ 'BC 54 3C 3C 0C 0C 4B 46' => 'Sigma 28mm F1.4 DG HSM | A', #30
370
371
  '48 54 3E 3E 0C 0C 4B 06' => 'Sigma 30mm F1.4 EX DC HSM',
371
372
  'F8 54 3E 3E 0C 0C 4B 06' => 'Sigma 30mm F1.4 EX DC HSM', #JD
372
373
  '91 54 44 44 0C 0C 4B 06' => 'Sigma 35mm F1.4 DG HSM', #30
@@ -2495,6 +2496,7 @@ my %base64coord = (
2495
2496
  { # D7100=0227
2496
2497
  Condition => '$$valPt =~ /^0[28]/',
2497
2498
  Name => 'ShotInfo02xx',
2499
+ Drop => 50000, # drop if too large (>64k for Z6iii)
2498
2500
  SubDirectory => {
2499
2501
  TagTable => 'Image::ExifTool::Nikon::ShotInfo',
2500
2502
  ProcessProc => \&ProcessNikonEncrypted,
@@ -5635,6 +5637,38 @@ my %nikonFocalConversions = (
5635
5637
  Notes => 'P6000',
5636
5638
  PrintConv => \%offOn,
5637
5639
  },
5640
+ # for Nikon Z6iii JPG and RAW images (version 0809),
5641
+ # the offset table starts at 0x24 and is as follows
5642
+ # JPG Offset Size NEF Offset Size
5643
+ # 0) 0x0000 0 0) 0x009c 21604
5644
+ # 1) 0x0000 0 1) 0x5500 6008
5645
+ # 2) 0x009c 2528 2) 0x6c78 2528
5646
+ # 3) 0x0a7c 200 3) 0x7658 200
5647
+ # 4) 0x0b44 2488 4) 0x7720 2488
5648
+ # 5) 0x14fc 1468 5) 0x80d8 1468
5649
+ # 6) 0x1ab8 1032 6) 0x8694 1032
5650
+ # 7) 0x1ec0 256 7) 0x8a9c 256
5651
+ # 8) 0x1fc0 800 8) 0x8b9c 800
5652
+ # 9) 0x22e0 144 9) 0x8ebc 144
5653
+ # 10) 0x2370 64 10) 0x8f4c 64
5654
+ # 11) 0x0000 0 11) 0x0000 0
5655
+ # 12) 0x23b0 5009 12) 0x8f8c 5009
5656
+ # 13) 0x3741 1536 13) 0xa31d 1536
5657
+ # 14) 0x3d41 11928 14) 0xa91d 11928
5658
+ # 15) 0x6bd9 5937 15) 0xd7b5 5937
5659
+ # 16) 0x830a 500 16) 0xeee6 500
5660
+ # 17) 0x84fe 160 17) 0xf0da 160
5661
+ # 18) 0x859e 464 18) 0xf17a 464
5662
+ # 19) 0x876e 8 19) 0xf34a 8
5663
+ # 20) 0x8776 64 20) 0xf352 64
5664
+ # 21) 0x87b6 6 21) 0xf392 6
5665
+ # 22) 0x87bc 48 22) 0xf398 48
5666
+ # 23) 0x87ec 20 23) 0xf3c8 20
5667
+ # 24) 0x8800 108 24) 0xf3dc 108
5668
+ # 25) 0x886c 8 25) 0xf448 8
5669
+ # 26) 0x8874 2420 26) 0xf450 2420
5670
+ # 27) 0x0000 0 27) 0x0000 0
5671
+ # 28) 0x0000 0 28) 0x0000 0
5638
5672
  0x66 => {
5639
5673
  Name => 'VR_0x66',
5640
5674
  Condition => '$$self{ShotInfoVersion} eq "0204"',
@@ -17,12 +17,57 @@ use strict;
17
17
  use vars qw($VERSION);
18
18
  use Image::ExifTool qw(:DataAccess :Utils);
19
19
 
20
- $VERSION = '1.07';
20
+ $VERSION = '1.08';
21
21
 
22
22
  sub ProcessNikonSettings($$$);
23
23
 
24
24
  my %enableDisable = ( 1 => 'Enable', 2 => 'Disable' );
25
25
 
26
+ my %funcButtonZ6 = ( #forum16316
27
+ 1 => 'AF-On or Subject Tracking', # (bug in 3.xx firmware?)
28
+ 2 => 'AF Lock Only',
29
+ 3 => 'AE Lock (hold)',
30
+ 4 => 'AE Lock (reset on release)',
31
+ 5 => 'AE Lock Only',
32
+ 6 => 'AE/AF Lock',
33
+ 7 => 'FV Lock',
34
+ 8 => 'Flash Disable/Enable',
35
+ 9 => 'Preview',
36
+ 10 => 'Matrix Metering',
37
+ 11 => 'Center-weighted Metering',
38
+ 12 => 'Spot Metering',
39
+ 13 => 'Highlight-weighted Metering',
40
+ 14 => 'Bracketing Burst',
41
+ 15 => 'Synchronized Release (Master)',
42
+ 16 => 'Synchronized Release (Remote)', # no settings map to 17 or 18
43
+ 19 => '+NEF(RAW)',
44
+ 20 => 'Framing Grid Display',
45
+ # 21 - missing
46
+ 22 => 'Zoom On/Off',
47
+ # 23 - missing
48
+ 24 => 'My Menu',
49
+ 25 => 'My Menu Top Item',
50
+ 26 => 'Playback',
51
+ 27 => 'Protect',
52
+ 28 => 'Image Area',
53
+ 29 => 'Image Quality',
54
+ 30 => 'White Balance',
55
+ 31 => 'Picture Control',
56
+ 32 => 'Active D-Lighting',
57
+ 33 => 'Metering',
58
+ 34 => 'Flash Mode',
59
+ 35 => 'Focus Mode',
60
+ 36 => 'Auto Bracketing',
61
+ 37 => 'Multiple Exposure',
62
+ 38 => 'HDR',
63
+ 39 => 'Exposure Delay Mode',
64
+ 40 => 'Shutter/Aperture Lock',
65
+ 41 => 'Focus Peaking',
66
+ 42 => 'Rating',
67
+ 43 => 'Non-CPU Lens',
68
+ 44 => 'None',
69
+ );
70
+
26
71
  my %funcButtonZ7m2 = (
27
72
  1 => 'AF-On',
28
73
  2 => 'AF Lock Only',
@@ -1117,6 +1162,11 @@ my %infoZSeries = (
1117
1162
  Name => 'Func1Button',
1118
1163
  PrintConv => \%previewButtonD6,
1119
1164
  %infoD6,
1165
+ },{ # CSf2-a (Z6)
1166
+ Name => 'Func1Button',
1167
+ Condition => '$$self{Model} =~ /^NIKON Z [67]\b/',
1168
+ Notes => 'Z6 and Z7',
1169
+ PrintConv => \%funcButtonZ6,
1120
1170
  },{ # CSf2-a (Z7_2)
1121
1171
  Name => 'Func1Button',
1122
1172
  PrintConv => \%funcButtonZ7m2,
@@ -1126,6 +1176,11 @@ my %infoZSeries = (
1126
1176
  Name => 'Func2Button',
1127
1177
  PrintConv => \%previewButtonD6,
1128
1178
  %infoD6,
1179
+ },{ # CSf2-b (Z6)
1180
+ Name => 'Func2Button',
1181
+ Condition => '$$self{Model} =~ /^NIKON Z [67]\b/',
1182
+ Notes => 'Z6 and Z7',
1183
+ PrintConv => \%funcButtonZ6,
1129
1184
  },{ # CSf2-b (Z7_2)
1130
1185
  Name => 'Func2Button',
1131
1186
  PrintConv => \%funcButtonZ7m2,
@@ -16,7 +16,7 @@ use vars qw($VERSION);
16
16
  use Image::ExifTool qw(:DataAccess :Utils);
17
17
  use Image::ExifTool::GPS;
18
18
 
19
- $VERSION = '1.06';
19
+ $VERSION = '1.07';
20
20
 
21
21
  # supported EXR value format types (other types are extracted as undef binary data)
22
22
  my %formatType = (
@@ -91,6 +91,8 @@ my %formatType = (
91
91
  5 => 'PXR24',
92
92
  6 => 'B44',
93
93
  7 => 'B44A',
94
+ 8 => 'DWAA', #github276
95
+ 9 => 'DWAB', #github276
94
96
  },
95
97
  },
96
98
  dataWindow => { },
@@ -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
  }
@@ -48,7 +48,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
48
48
  use Image::ExifTool::Exif;
49
49
  use Image::ExifTool::GPS;
50
50
 
51
- $VERSION = '2.98';
51
+ $VERSION = '3.00';
52
52
 
53
53
  sub ProcessMOV($$;$);
54
54
  sub ProcessKeys($$$);
@@ -6606,6 +6606,12 @@ my %userDefined = (
6606
6606
  PrintConv => '$val * 1e6 . " microseconds"',
6607
6607
  PrintConvInv => '$val =~ s/ .*//; $val * 1e-6',
6608
6608
  },
6609
+ 'camera.focal_length.35mm_equivalent' => {
6610
+ Name => 'FocalLengthIn35mmFormat',
6611
+ PrintConv => '"$val mm"',
6612
+ PrintConvInv => '$val=~s/\s*mm$//;$val',
6613
+ },
6614
+ 'camera.lens_model' => { Name => 'LensModel' },
6609
6615
  'location.ISO6709' => {
6610
6616
  Name => 'GPSCoordinates',
6611
6617
  Groups => { 2 => 'Location' },
@@ -9737,7 +9743,7 @@ sub ProcessMOV($$;$)
9737
9743
  if ($size > 0x2000000) { # start to get worried above 32 MiB
9738
9744
  # check for RIFF trailer (written by Auto-Vox dashcam)
9739
9745
  if ($buff =~ /^(gpsa|gps0|gsen|gsea)...\0/s) { # (yet seen only gpsa as first record)
9740
- $et->VPrint(0, "Found RIFF trailer");
9746
+ $et->VPrint(0, sprintf("Found RIFF trailer at offset 0x%x",$lastPos));
9741
9747
  if ($et->Options('ExtractEmbedded')) {
9742
9748
  $raf->Seek(-8, 1) or last; # seek back to start of trailer
9743
9749
  my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
@@ -9746,6 +9752,11 @@ sub ProcessMOV($$;$)
9746
9752
  EEWarn($et);
9747
9753
  }
9748
9754
  last;
9755
+ } elsif ($buff eq 'CCCCCCCC') {
9756
+ $et->VPrint(0, sprintf("Found Kenwood trailer at offset 0x%x",$lastPos));
9757
+ my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
9758
+ ProcessKenwoodTrailer($et, { RAF => $raf }, $tbl);
9759
+ last;
9749
9760
  }
9750
9761
  $ignore = 1;
9751
9762
  if ($tagInfo and not $$tagInfo{Unknown} and not $eeTag) {
@@ -109,7 +109,7 @@ my %insvLimit = (
109
109
  The tags below are extracted from timed metadata in QuickTime and other
110
110
  formats of video files when the ExtractEmbedded option is used. Although
111
111
  most of these tags are combined into the single table below, ExifTool
112
- currently reads 74 different formats of timed GPS metadata from video files.
112
+ currently reads 77 different formats of timed GPS metadata from video files.
113
113
  },
114
114
  VARS => { NO_ID => 1 },
115
115
  GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
@@ -757,6 +757,15 @@ my %insvLimit = (
757
757
  10 => { Name => 'FusionYPR', Format => 'float[3]' },
758
758
  );
759
759
 
760
+ #------------------------------------------------------------------------------
761
+ # Convert unsigned 4-byte integer to signed
762
+ # Inputs: <none> (uses value in $_)
763
+ # Returns: signed integet
764
+ sub MakeSigned()
765
+ {
766
+ return $_ < 0x80000000 ? $_ : $_ - 4294967296;
767
+ }
768
+
760
769
  #------------------------------------------------------------------------------
761
770
  # Save information from keys in OtherSampleDesc directory for processing timed metadata
762
771
  # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
@@ -1420,9 +1429,10 @@ Sample: for ($i=0; ; ) {
1420
1429
  } elsif ($type eq 'gps ') { # (ie. GPSDataList tag)
1421
1430
 
1422
1431
  if ($buff =~ /^....freeGPS /s) {
1423
- # process by brute scan instead if ExtractEmbedded >= 3
1424
- # (some videos don't reference all freeGPS info from 'gps ' table, eg. INNOV)
1425
- last if $eeOpt >= 3;
1432
+ # parse freeGPS data unless done already in brute-force scan
1433
+ # (some videos don't reference all freeGPS info from 'gps ' table, eg. INNOV,
1434
+ # and some videos don't put 'gps ' data in mdat, eg XGODY 12" 4K Dashcam)
1435
+ last if $$et{FoundGPSByScan};
1426
1436
  # decode "freeGPS " data (Novatek and others)
1427
1437
  ProcessFreeGPS($et, {
1428
1438
  DataPt => \$buff,
@@ -1473,6 +1483,31 @@ sub ConvertLatLon($$)
1473
1483
  $_[1] = $deg + ($_[1] - $deg * 100) / 60;
1474
1484
  }
1475
1485
 
1486
+ #------------------------------------------------------------------------------
1487
+ # Decrypt Lucky data
1488
+ # Inputs: 0) string to decrypt, 1) encryption key
1489
+ # Returns: decrypted string
1490
+ my @luckyKeys = ('luckychip gps', 'customer ## gps');
1491
+ sub DecryptLucky($$) {
1492
+ my ($str, $key) = @_;
1493
+ my @str = unpack('C*', $str);
1494
+ my @key = unpack('C*', $key);
1495
+ my @enc = (0..255);
1496
+ my ($i, $j, $k) = (0, 0, 0);
1497
+ do {
1498
+ $j = ($j + $enc[$i] + $key[$i % length($key)]) & 0xff;
1499
+ @enc[$i,$j] = @enc[$j,$i];
1500
+ } while (++$i < 256);
1501
+ ($i, $j, $k) = (0, 0, 0);
1502
+ do {
1503
+ $j = ($j + 1) & 0xff;
1504
+ $k = ($k + $enc[$j]) & 0xff;
1505
+ @enc[$j,$k] = @enc[$k,$j];
1506
+ $str[$i] ^= $enc[($enc[$j] + $enc[$k]) & 0xff];
1507
+ } while (++$i < @str);
1508
+ return pack('C*', @str);
1509
+ }
1510
+
1476
1511
  #------------------------------------------------------------------------------
1477
1512
  # Process "freeGPS " data blocks
1478
1513
  # Inputs: 0) ExifTool ref, 1) dirInfo ref {DataPt,SampleTime,SampleDuration}, 2) tagTable ref
@@ -1588,40 +1623,87 @@ sub ProcessFreeGPS($$$)
1588
1623
  }
1589
1624
  if (defined $lat) {
1590
1625
  # extract accelerometer readings if GPS was valid
1591
- @acc = unpack('x68V3', $$dataPt);
1592
- # change to signed integer and divide by 256
1593
- map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
1626
+ # and change to signed integer and divide by 256
1627
+ @acc = map { MakeSigned / 256 } unpack('x68V3', $$dataPt);
1594
1628
  }
1595
1629
 
1596
- } elsif ($$dataPt =~ /^.{37}\0\0\0A([NS])([EW])/s) {
1630
+ } elsif ($$dataPt =~ /^.{37}\0\0\0A([NS])([EW])\0/s) {
1597
1631
 
1598
- $debug and $et->FoundTag(GPSType => 3);
1599
- # decode freeGPS from ViofoA119v3 dashcam (similar to Novatek GPS format)
1600
- # 0000: 00 00 40 00 66 72 65 65 47 50 53 20 f0 03 00 00 [..@.freeGPS ....]
1601
- # 0010: 05 00 00 00 2f 00 00 00 03 00 00 00 13 00 00 00 [..../...........]
1602
- # 0020: 09 00 00 00 1b 00 00 00 41 4e 57 00 25 d1 99 45 [........ANW.%..E]
1603
- # 0030: f1 47 40 46 66 66 d2 41 85 eb 83 41 00 00 00 00 [.G@Fff.A...A....]
1604
1632
  ($latRef, $lonRef) = ($1, $2);
1605
1633
  ($hr,$min,$sec,$yr,$mon,$day) = unpack('x16V6', $$dataPt);
1606
- if ($yr >= 2000) {
1607
- # Kenwood dashcam sometimes stores absolute year and local time
1608
- # (but sometimes year since 2000 and UTC time in same video!)
1609
- require Time::Local;
1610
- my $time = Image::ExifTool::TimeLocal($sec,$min,$hr,$day,$mon-1,$yr);
1611
- ($sec,$min,$hr,$day,$mon,$yr) = gmtime($time);
1612
- $yr += 1900;
1613
- ++$mon;
1614
- $et->WarnOnce('Converting GPSDateTime to UTC based on local time zone',1);
1615
- }
1616
- $lat = GetFloat($dataPt, 0x2c);
1617
- $lon = GetFloat($dataPt, 0x30);
1618
- $spd = GetFloat($dataPt, 0x34) * $knotsToKph; # (convert knots to km/h)
1619
- $trk = GetFloat($dataPt, 0x38);
1620
- # (may be all zeros or int16u counting from 1 to 6 if not valid)
1621
- my $tmp = substr($$dataPt, 60, 12);
1622
- if ($tmp ne "\0\0\0\0\0\0\0\0\0\0\0\0" and $tmp ne "\x01\0\x02\0\x03\0\x04\0\x05\0\x06\0") {
1623
- @acc = unpack('V3', $tmp);
1624
- map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
1634
+ # test for base64-encoded and encrypted lucky gps strings
1635
+ my ($notEnc, $notStr, $lt, $ln);
1636
+ if (length($$dataPt) < 0x78) {
1637
+ $notEnc = $notStr = 1;
1638
+ } else {
1639
+ $lt = substr($$dataPt, 0x2c, 20), # latitude
1640
+ $ln = substr($$dataPt, 0x40, 20), # longitude
1641
+ /^[A-Za-z0-9+\/]{8,20}={0,2}\0*$/ or $notEnc = 1, last foreach ($lt, $ln);
1642
+ /^\d{1,5}\.\d+\0*$/ or $notStr = 1, last foreach ($lt, $ln);
1643
+ }
1644
+ if ($notEnc and $notStr) {
1645
+
1646
+ $debug and $et->FoundTag(GPSType => '3a');
1647
+ # decode freeGPS from ViofoA119v3 dashcam (similar to Novatek GPS format)
1648
+ # 0000: 00 00 40 00 66 72 65 65 47 50 53 20 f0 03 00 00 [..@.freeGPS ....]
1649
+ # 0010: 05 00 00 00 2f 00 00 00 03 00 00 00 13 00 00 00 [..../...........]
1650
+ # 0020: 09 00 00 00 1b 00 00 00 41 4e 57 00 25 d1 99 45 [........ANW.%..E]
1651
+ # 0030: f1 47 40 46 66 66 d2 41 85 eb 83 41 00 00 00 00 [.G@Fff.A...A....]
1652
+ if ($yr >= 2000) {
1653
+ # Kenwood dashcam sometimes stores absolute year and local time
1654
+ # (but sometimes year since 2000 and UTC time in same video!)
1655
+ require Time::Local;
1656
+ my $time = Image::ExifTool::TimeLocal($sec,$min,$hr,$day,$mon-1,$yr);
1657
+ ($sec,$min,$hr,$day,$mon,$yr) = gmtime($time);
1658
+ $yr += 1900;
1659
+ ++$mon;
1660
+ $et->WarnOnce('Converting GPSDateTime to UTC based on local time zone',1);
1661
+ }
1662
+ $lat = GetFloat($dataPt, 0x2c);
1663
+ $lon = GetFloat($dataPt, 0x30);
1664
+ $spd = GetFloat($dataPt, 0x34) * $knotsToKph;
1665
+ $trk = GetFloat($dataPt, 0x38);
1666
+ # (may be all zeros or int16u counting from 1 to 6 if not valid)
1667
+ my $tmp = substr($$dataPt, 60, 12);
1668
+ if ($tmp ne "\0\0\0\0\0\0\0\0\0\0\0\0" and $tmp ne "\x01\0\x02\0\x03\0\x04\0\x05\0\x06\0") {
1669
+ @acc = map { MakeSigned / 256 } unpack('V3', $tmp);
1670
+ }
1671
+
1672
+ } else {
1673
+
1674
+ $debug and $et->FoundTag(GPSType => '3b');
1675
+ # decode freeGPS from E-ACE B44 dashcam
1676
+ # 0000: 00 00 40 00 66 72 65 65 47 50 53 20 f0 03 00 00 [..@.freeGPS ....]
1677
+ # 0010: 08 00 00 00 22 00 00 00 01 00 00 00 18 00 00 00 [...."...........]
1678
+ # 0020: 08 00 00 00 10 00 00 00 41 4e 45 00 67 4e 69 69 [........ANE.gNii]
1679
+ # 0030: 5a 38 4a 54 74 48 63 61 36 74 77 3d 00 00 00 00 [Z8JTtHca6tw=....]
1680
+ # 0040: 68 74 75 69 5a 4d 4a 53 73 58 55 58 37 4e 6f 3d [htuiZMJSsXUX7No=]
1681
+ # 0050: 00 00 00 00 64 3b ac 41 e1 3a 1d 43 2b 01 00 00 [....d;.A.:.C+...]
1682
+ # 0060: fd ff ff ff 43 00 00 00 32 4a 37 31 50 70 55 48 [....C...2J71PpUH]
1683
+ # 0070: 37 69 68 66 00 00 00 00 00 00 00 00 00 00 00 00 [7ihf............]
1684
+ # (16-byte string at 0x68 is base64 encoded and encrypted 'luckychip' string)
1685
+ $spd = GetFloat($dataPt, 0x54) * $knotsToKph;
1686
+ $trk = GetFloat($dataPt, 0x58);
1687
+ @acc = map MakeSigned, unpack('x92V3', $$dataPt);
1688
+ # (accelerometer scaling is roughly 300=1G, but this doesn't seem to be exact for each
1689
+ # axis, so leave the values as raw. The axes are positive acceleration up,left,forward)
1690
+ if ($notEnc) { # (not encrypted)
1691
+ ($lat = $lt) =~ s/\0+$//;
1692
+ ($lon = $ln) =~ s/\0+$//;
1693
+ } else {
1694
+ # decode base64 strings
1695
+ require Image::ExifTool::XMP;
1696
+ $_ = ${Image::ExifTool::XMP::DecodeBase64($_)} foreach ($lt, $ln);
1697
+ # try various keys to decrypt lat/lon
1698
+ my ($i, $ch, $key) = (0, 'a', $luckyKeys[0]);
1699
+ for (; $i<20; ++$i) {
1700
+ $i and ($key = $luckyKeys[1]) =~ s/#/$ch/g, ++$ch;
1701
+ ($lat = DecryptLucky($lt, $key)) =~ /^\d{1,4}\.\d+$/ or undef($lat), next;
1702
+ ($lon = DecryptLucky($ln, $key)) =~ /^\d{1,5}\.\d+$/ or undef($lon), next;
1703
+ last;
1704
+ }
1705
+ $lon or $et->WarnOnce('Unknown encryption for latitude/longitude');
1706
+ }
1625
1707
  }
1626
1708
 
1627
1709
  } elsif ($$dataPt =~ /^.{21}\0\0\0A([NS])([EW])/s) {
@@ -1682,7 +1764,7 @@ sub ProcessFreeGPS($$$)
1682
1764
  $trk -= 360 if $trk >= 360;
1683
1765
  undef @acc;
1684
1766
  } else {
1685
- map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 1000 } @acc; # (NC)
1767
+ @acc = map { MakeSigned / 1000 } @acc; # (NC)
1686
1768
  }
1687
1769
 
1688
1770
  } elsif ($$dataPt =~ /^.{60}4W`b]S</s and length($$dataPt) >= 140) {
@@ -1786,7 +1868,7 @@ sub ProcessFreeGPS($$$)
1786
1868
  return 0;
1787
1869
  }
1788
1870
  # (not sure about acc scaling)
1789
- map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 1000 } @acc;
1871
+ @acc = map { MakeSigned / 1000 } @acc;
1790
1872
  $lon = GetFloat($dataPt, 0x5c);
1791
1873
  $lat = GetFloat($dataPt, 0x60);
1792
1874
  $spd = GetFloat($dataPt, 0x64) * $knotsToKph;
@@ -1931,7 +2013,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1931
2013
  # 0x7c - int32s[3] accelerometer * 1000
1932
2014
  ($latRef, $lonRef) = ($1, $2);
1933
2015
  ($hr,$min,$sec,$yr,$mon,$day,@acc) = unpack('x48V3x52V6', $$dataPt);
1934
- map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 1000 } @acc;
2016
+ @acc = map { MakeSigned / 1000 } @acc;
1935
2017
  $lat = GetDouble($dataPt, 0x40);
1936
2018
  $lon = GetDouble($dataPt, 0x50);
1937
2019
  $spd = GetDouble($dataPt, 0x60) * $knotsToKph;
@@ -1947,8 +2029,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1947
2029
  $lon = abs(GetFloat(\$dat, 8)); # (abs just to be safe)
1948
2030
  $spd = GetFloat(\$dat, 12) * $knotsToKph;
1949
2031
  $trk = GetFloat(\$dat, 16);
1950
- @acc = unpack('x20V3', $dat);
1951
- map { $_ = $_ - 4294967296 if $_ >= 0x80000000 } @acc;
2032
+ @acc = map MakeSigned, unpack('x20V3', $dat);
1952
2033
  ConvertLatLon($lat, $lon);
1953
2034
  $$et{DOC_NUM} = ++$$et{DOC_COUNT};
1954
2035
  $et->HandleTag($tagTbl, GPSLatitude => $lat * (substr($dat,1,1) eq 'S' ? -1 : 1));
@@ -1982,7 +2063,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
1982
2063
  $lon = abs(GetDouble($dataPt, 48)); # (abs just to be safe)
1983
2064
  $spd = GetDouble($dataPt, 64) * $knotsToKph;
1984
2065
  $trk = GetDouble($dataPt, 72);
1985
- map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 1000 } @acc; # (NC)
2066
+ @acc = map { MakeSigned / 1000 } @acc; # (NC)
1986
2067
  # (not necessary to read RMC sentence because we already have it all)
1987
2068
 
1988
2069
  } elsif ($$dataPt =~ /^.{72}A[NS][EW]\0/s) {
@@ -2049,9 +2130,41 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
2049
2130
  }
2050
2131
  }
2051
2132
 
2052
- } else {
2133
+ } elsif ($$dataPt =~ m<^.{23}(\d{4})/(\d{2})/(\d{2}) (\d{2}):(\d{2}):(\d{2}) [N|S]>s) {
2053
2134
 
2054
2135
  $debug and $et->FoundTag(GPSType => 16);
2136
+ # XGODY 12" 4K Dashcam
2137
+ # 0000: 00 00 00 a8 66 72 65 65 47 50 53 20 98 00 00 00 [....freeGPS ....]
2138
+ # 0010: 6e 6f 72 6d 61 6c 3a 32 30 32 34 2f 30 35 2f 32 [normal:2024/05/2]
2139
+ # 0020: 32 20 30 32 3a 35 34 3a 32 39 20 4e 3a 34 32 2e [2 02:54:29 N:42.]
2140
+ # 0030: 33 38 32 34 37 30 20 57 3a 38 33 2e 33 38 39 35 [382470 W:83.3895]
2141
+ # 0040: 37 30 20 35 33 2e 36 20 6b 6d 2f 68 20 78 3a 2d [70 53.6 km/h x:-]
2142
+ # 0050: 30 2e 30 32 20 79 3a 30 2e 39 39 20 7a 3a 30 2e [0.02 y:0.99 z:0.]
2143
+ # 0060: 31 30 20 41 3a 32 36 39 2e 32 20 48 3a 32 34 35 [10 A:269.2 H:245]
2144
+ # 0070: 2e 35 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [.5..............]
2145
+ ($yr,$mon,$day,$hr,$min,$sec) = ($1,$2,$3,$4,$5,$6);
2146
+ $$dataPt =~ s/\0+$//; # remove trailing nulls
2147
+ my @a = split ' ', substr($$dataPt,43);
2148
+ $ddd = 1;
2149
+ foreach (@a) {
2150
+ unless (/^([A-Z]):([-+]?\d+(\.\d+)?)$/i) {
2151
+ # (the "km/h" after spd is display units? because the value is stored in knots)
2152
+ defined $lon and not defined $spd and /^\d+\.\d+$/ and $spd = $_ * $knotsToKph;
2153
+ next;
2154
+ }
2155
+ ($1 eq 'N' or $1 eq 'S') and $lat = $2, $latRef = $1, next;
2156
+ ($1 eq 'E' or $1 eq 'W') and $lon = $2, $lonRef = $1, next;
2157
+ ($1 eq 'x' or $1 eq 'y' or $1 eq 'z') and push(@acc,$2), next;
2158
+ $1 eq 'A' and $trk = $2, next; # (verified, but why 'A'?)
2159
+ # seen 'H' - one might expect altitude ('H'eight), but it doesn't fit
2160
+ # the sample data, so save all other information as an "Unknown_X" tag
2161
+ $$tagTbl{$1} or AddTagToTable($tagTbl, $1, { Name => "Unknown_$1", Unknown => 1 });
2162
+ push(@xtra, $1 => $2), next;
2163
+ }
2164
+
2165
+ } else {
2166
+
2167
+ $debug and $et->FoundTag(GPSType => 17);
2055
2168
  # (look for binary GPS as stored by Nextbase 512G, ref PH)
2056
2169
  # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 78 01 00 00 [....freeGPS x...]
2057
2170
  # 0010: 78 2e 78 78 00 00 00 00 00 00 00 00 00 00 00 00 [x.xx............]
@@ -2084,7 +2197,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
2084
2197
  $day < 1 or $day > 31 or
2085
2198
  $hr > 59 or $min > 59 or $sec > 600;
2086
2199
  # change lat/lon to signed integer and divide by 1e7
2087
- map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 1e7 } $lat, $lon;
2200
+ ($lat, $lon) = map { MakeSigned / 1e7 } $lat, $lon;
2088
2201
  $trk -= 0x10000 if $trk >= 0x8000; # make it signed
2089
2202
  $trk /= 100;
2090
2203
  $trk += 360 if $trk < 0;
@@ -2115,7 +2228,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
2115
2228
  my $time = sprintf('%.2d:%.2d:%sZ',$hr,$min,$sec);
2116
2229
  $et->HandleTag($tagTbl, GPSTimeStamp => $time);
2117
2230
  }
2118
- if (defined $lat) {
2231
+ if (defined $lat and defined $lon) {
2119
2232
  # lat/long are in DDDMM.MMMM format unless $ddd is set
2120
2233
  ConvertLatLon($lat, $lon) unless $ddd;
2121
2234
  $et->HandleTag($tagTbl, GPSLatitude => $lat * ($latRef eq 'S' ? -1 : 1));
@@ -2680,6 +2793,53 @@ sub ProcessRIFFTrailer($$$)
2680
2793
  return 1;
2681
2794
  }
2682
2795
 
2796
+ #------------------------------------------------------------------------------
2797
+ # Process Kenwood Dashcam trailer (forum16229)
2798
+ # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
2799
+ # Returns: 1 on success
2800
+ # Sample data (chained 512-byte records starting like this):
2801
+ # 0000: 43 43 43 43 43 43 43 43 43 43 43 43 43 43 47 50 [CCCCCCCCCCCCCCGP]
2802
+ # 0010: 53 44 41 54 41 2d 2d 32 30 32 34 30 37 31 31 31 [SDATA--202407111]
2803
+ # 0020: 32 30 34 31 32 4e 35 30 2e 36 31 32 33 38 36 30 [20412N50.6123860]
2804
+ # 0030: 36 37 37 45 38 2e 37 30 32 37 31 38 30 39 38 39 [677E8.7027180989]
2805
+ # 0040: 35 33 33 2e 30 30 30 30 30 30 30 30 30 30 30 30 [533.000000000000]
2806
+ # 0050: 2e 30 30 30 30 30 30 30 30 30 30 30 30 30 2e 30 [.0000000000000.0]
2807
+ # 0060: 31 39 39 39 39 39 39 39 35 35 33 2d 30 2e 30 39 [19999999553-0.09]
2808
+ # 0070: 30 30 30 30 30 30 33 35 37 2d 30 2e 31 34 30 30 [000000357-0.1400]
2809
+ # 0080: 30 30 30 30 30 35 39 47 50 53 44 41 54 41 2d 2d [0000059GPSDATA--]
2810
+ sub ProcessKenwoodTrailer($$$)
2811
+ {
2812
+ my ($et, $dirInfo, $tagTbl) = @_;
2813
+ my $raf = $$dirInfo{RAF};
2814
+ my $buff;
2815
+ # current file position is 8 bytes into the 14 C's, so test the next 6:
2816
+ $raf->Read($buff, 14) and $buff eq 'CCCCCCCCCCCCCC' or return 0;
2817
+ $et->VerboseDir('Kenwood trailer', undef, undef);
2818
+ unless ($$et{OPTIONS}{ExtractEmbedded}) {
2819
+ $et->WarnOnce('Use the ExtractEmbedded option to extract timed GPSData from Kenwood trailer',3);
2820
+ return 1;
2821
+ }
2822
+ while ($raf->Read($buff, 121) and $buff =~ /^GPSDATA--(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/) {
2823
+ FoundSomething($et, $tagTbl);
2824
+ $et->HandleTag($tagTbl, GPSDateTime => "$1:$2:$3 $4:$5:$6");
2825
+ my $i = 9 + 14;
2826
+ my ($val, @acc, $tag);
2827
+ foreach $tag (qw(GPSLatitude GPSLongitude GPSSpeed unk acc acc acc)) {
2828
+ $val = substr($buff, $i, 14); $i += 14;
2829
+ next if $tag eq 'unk';
2830
+ my $hemi;
2831
+ $hemi = $1 if $val =~ s/^([NSEW])//;
2832
+ $val =~ /^[-+]?\d+\.\d+$/ or next;
2833
+ $tag eq 'acc' and push(@acc,$val), next;
2834
+ $val = -$val if $hemi and ($hemi eq 'S' or $hemi eq 'W');
2835
+ $et->HandleTag($tagTbl, $tag => $val);
2836
+ }
2837
+ $et->HandleTag($tagTbl, Accelerometer => "@acc") if @acc == 3;
2838
+ }
2839
+ delete $$et{DOC_NUM};
2840
+ return 1;
2841
+ }
2842
+
2683
2843
  #------------------------------------------------------------------------------
2684
2844
  # Process 'gps ' atom containing NMEA from Pittasoft Blackvue dashcam (ref PH)
2685
2845
  # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
@@ -3353,6 +3513,7 @@ sub ScanMediaData($)
3353
3513
  }
3354
3514
  my $dirInfo = { DataPt => \$buff, DataPos => $pos + $dataPos, DirLen => $len };
3355
3515
  ProcessFreeGPS($et, $dirInfo, $tagTbl);
3516
+ $$et{FoundGPSByScan} = 1;
3356
3517
  }
3357
3518
  $pos += $len;
3358
3519
  $buf2 = substr($buff, $len);
@@ -22,13 +22,13 @@ use vars qw($VERSION %samsungLensTypes);
22
22
  use Image::ExifTool qw(:DataAccess :Utils);
23
23
  use Image::ExifTool::Exif;
24
24
 
25
- $VERSION = '1.56';
25
+ $VERSION = '1.58';
26
26
 
27
27
  sub WriteSTMN($$$);
28
28
  sub ProcessINFO($$$);
29
29
  sub ProcessSamsungMeta($$$);
30
30
  sub ProcessSamsungIFD($$$);
31
- sub ProcessSamsung($$$);
31
+ sub ProcessSamsung($$;$);
32
32
 
33
33
  # Samsung LensType lookup
34
34
  %samsungLensTypes = (
@@ -943,25 +943,25 @@ my %formatMinMax = (
943
943
  );
944
944
 
945
945
  # information extracted from Samsung trailer (ie. Samsung SM-T805 "Sound & Shot" JPEG) (ref PH)
946
+ # NOTE: These tags may use $$self{SamsungTagName} in a Condition statement
947
+ # if necessary to differentiate tags with the same ID but different names
946
948
  %Image::ExifTool::Samsung::Trailer = (
947
949
  GROUPS => { 0 => 'MakerNotes', 2 => 'Other' },
948
950
  VARS => { NO_ID => 1, HEX_ID => 0 },
949
951
  PROCESS_PROC => \&ProcessSamsung,
952
+ TAG_PREFIX => 'SamsungTrailer',
950
953
  PRIORITY => 0, # (first one takes priority so DepthMapWidth/Height match first DepthMapData)
951
954
  NOTES => q{
952
- Tags extracted from the trailer of JPEG images written when using certain
953
- features (such as "Sound & Shot" or "Shot & More") from Samsung models such
954
- as the Galaxy S4 and Tab S, and from the 'sefd' atom in HEIC images from the
955
- Samsung S10+.
956
- },
957
- '0x0001-name' => {
958
- Name => 'EmbeddedImageName', # ("DualShot_1","DualShot_2")
959
- RawConv => '$$self{EmbeddedImageName} = $val',
955
+ Tags extracted from the SEFT trailer of JPEG and PNG images written when
956
+ using certain features (such as "Sound & Shot" or "Shot & More") from
957
+ Samsung models such as the Galaxy S4 and Tab S, and from the 'sefd' atom in
958
+ HEIC images from models such as the S10+.
960
959
  },
960
+ '0x0001-name' => 'EmbeddedImageName', # ("DualShot_1","DualShot_2","SingleShot")
961
961
  '0x0001' => [
962
962
  {
963
963
  Name => 'EmbeddedImage',
964
- Condition => '$$self{EmbeddedImageName} eq "DualShot_1"',
964
+ Condition => '$$self{SamsungTagName} ne "DualShot_2"',
965
965
  Groups => { 2 => 'Preview' },
966
966
  Binary => 1,
967
967
  },
@@ -970,6 +970,7 @@ my %formatMinMax = (
970
970
  Groups => { 2 => 'Preview' },
971
971
  Binary => 1,
972
972
  },
973
+ # (have also seen the string "BOKEH" here (SM-A226B)
973
974
  ],
974
975
  '0x0100-name' => 'EmbeddedAudioFileName', # ("SoundShot_000")
975
976
  '0x0100' => { Name => 'EmbeddedAudioFile', Groups => { 2 => 'Audio' }, Binary => 1 },
@@ -1265,6 +1266,7 @@ my %formatMinMax = (
1265
1266
  '0x0b40' => { # (SM-N975X front camera)
1266
1267
  Name => 'SingleShotMeta',
1267
1268
  SubDirectory => { TagTable => 'Image::ExifTool::Samsung::SingleShotMeta' },
1269
+ # (have also see the string "BOKEH_INFO" here (SM-A226B)
1268
1270
  },
1269
1271
  # 0x0b41-name - seen 'SingeShot_DepthMap_1' (Yes, "Singe") (SM-N975X front camera)
1270
1272
  '0x0b41' => { Name => 'SingleShotDepthMap', Binary => 1 },
@@ -1277,8 +1279,10 @@ my %formatMinMax = (
1277
1279
  # 0x0bd0-name - seen 'Dual_Relighting_Bokeh_Info' #forum16086
1278
1280
  # 0x0be0-name - seen 'Livefocus_JDM_Info' #forum16086
1279
1281
  # 0x0bf0-name - seen 'Remaster_Info' #forum16086
1282
+ '0x0bf0' => 'RemasterInfo', #forum16086/16242
1280
1283
  # 0x0c21-name - seen 'Portrait_Effect_Info' #forum16086
1281
1284
  # 0x0c51-name - seen 'Samsung_Capture_Info' #forum16086
1285
+ '0x0c51' => 'SamsungCaptureInfo', #forum16086/16242
1282
1286
  # 0x0c61-name - seen 'Camera_Capture_Mode_Info' #forum16086
1283
1287
  # 0x0c71-name - seen 'Pro_White_Balance_Info' #forum16086
1284
1288
  # 0x0c81-name - seen 'Watermark_Info' #forum16086
@@ -1289,7 +1293,11 @@ my %formatMinMax = (
1289
1293
  # 0x0d11-name - seen 'Video_Snapshot_Info' #forum16086
1290
1294
  # 0x0d21-name - seen 'Camera_Scene_Info' #forum16086
1291
1295
  # 0x0d31-name - seen 'Food_Blur_Effect_Info' #forum16086
1292
- # 0x0d91-name - seen 'PEg_Info' #forum16086
1296
+ '0x0d91' => { #forum16086/16242
1297
+ Name => 'PEg_Info',
1298
+ Description => 'PEg Info',
1299
+ SubDirectory => { TagTable => 'Image::ExifTool::JSON::Main' },
1300
+ },
1293
1301
  # 0x0da1-name - seen 'Captured_App_Info' #forum16086
1294
1302
  # 0xa050-name - seen 'Jpeg360_2D_Info' (Samsung Gear 360)
1295
1303
  # 0xa050 - seen 'Jpeg3602D' (Samsung Gear 360)
@@ -1487,7 +1495,7 @@ sub ProcessSamsungMeta($$$)
1487
1495
  my $pos = $$dirInfo{DirStart};
1488
1496
  my $end = $$dirInfo{DirLen} + $pos;
1489
1497
  unless ($pos + 8 <= $end and substr($$dataPt, $pos, 4) eq 'DOFS') {
1490
- $et->Warn("Unrecognized $dirName data");
1498
+ $et->Warn("Unrecognized $dirName data", 1);
1491
1499
  return 0;
1492
1500
  }
1493
1501
  my $ver = Get32u($dataPt, $pos + 4);
@@ -1563,7 +1571,7 @@ sub ProcessSamsungIFD($$$)
1563
1571
  # Returns: 1 on success, 0 not valid Samsung trailer, or -1 error writing
1564
1572
  # - updates DataPos to point to start of Samsung trailer
1565
1573
  # - updates DirLen to existing trailer length
1566
- sub ProcessSamsung($$$)
1574
+ sub ProcessSamsung($$;$)
1567
1575
  {
1568
1576
  my ($et, $dirInfo) = @_;
1569
1577
  my $raf = $$dirInfo{RAF};
@@ -1653,8 +1661,13 @@ SamBlock:
1653
1661
  $audioSize = $size - 8 - $len;
1654
1662
  next;
1655
1663
  }
1656
- # add unknown tags if necessary
1664
+ last unless $raf->Seek($dirPos-$noff, 0) and $raf->Read($buf2, $size) == $size;
1665
+ # (could validate the first 4 bytes of the block because they
1666
+ # are the same as the first 4 bytes of the directory entry)
1667
+ $len = Get32u(\$buf2, 4);
1668
+ last if $len + 8 > $size;
1657
1669
  my $tag = sprintf("0x%.4x", $type);
1670
+ # add unknown tags if necessary
1658
1671
  unless ($$tagTablePtr{$tag}) {
1659
1672
  next unless $unknown or $verbose;
1660
1673
  my %tagInfo = (
@@ -1673,11 +1686,8 @@ SamBlock:
1673
1686
  );
1674
1687
  AddTagToTable($tagTablePtr, "$tag-name", \%tagInfo2);
1675
1688
  }
1676
- last unless $raf->Seek($dirPos-$noff, 0) and $raf->Read($buf2, $size) == $size;
1677
- # (could validate the first 4 bytes of the block because they
1678
- # are the same as the first 4 bytes of the directory entry)
1679
- $len = Get32u(\$buf2, 4);
1680
- last if $len + 8 > $size;
1689
+ # set SamsungTagName ExifTool member for use in tag Condition
1690
+ $$et{SamsungTagName} = substr($buf2, 8, $len);
1681
1691
  # extract tag name and value
1682
1692
  $et->HandleTag($tagTablePtr, "$tag-name", undef,
1683
1693
  DataPt => \$buf2,
@@ -1691,6 +1701,7 @@ SamBlock:
1691
1701
  Start => 8 + $len,
1692
1702
  Size => $size - (8 + $len),
1693
1703
  );
1704
+ delete $$et{SamsungTagName};
1694
1705
  }
1695
1706
  if ($outfile) {
1696
1707
  last unless $raf->Seek($dataPos, 0) and $raf->Read($buff, $dirLen) == $dirLen;
@@ -997,6 +997,7 @@ my %tagLookup = (
997
997
  'angleinfoyaw' => { 510 => 'AngleInfoYaw' },
998
998
  'anti-blur' => { 451 => 0xb04b },
999
999
  'antialiasstrength' => { 123 => 0xc632 },
1000
+ 'antiflicker' => { 59 => 0x20 },
1000
1001
  'aperturelock' => { 306 => '38.2', 308 => '38.2', 309 => '38.2', 318 => '38.2', 319 => '38.2', 321 => 0xb8, 322 => 0xb8, 323 => 0xb8 },
1001
1002
  'aperturemode' => { 410 => 'apmd' },
1002
1003
  'aperturerange' => { 88 => 0x10d },
@@ -3132,7 +3133,7 @@ my %tagLookup = (
3132
3133
  'focallength' => { 7 => 0x1d, 8 => 0xa, 9 => 0x23, 10 => 0x9, 11 => 0x1d, 12 => 0x9, 13 => 0x1e, 14 => 0x1d, 15 => 0x1d, 16 => 0x1e, 17 => 0x1e, 18 => 0x1e, 19 => 0x28, 20 => 0x1e, 21 => 0x23, 22 => 0x1e, 23 => 0x1e, 24 => 0x23, 25 => 0x23, 26 => 0x23, 27 => 0x23, 28 => 0x1e, 29 => 0x23, 61 => 0x1, 64 => 0x7, 117 => 0x1d, 123 => 0x920a, 151 => 0x1d, 167 => 'FocalLength', 185 => 0x12, 233 => 0xa, 234 => 0xb, 238 => [0xc,0x3c], 343 => 0x1, 385 => 0x1d, 394 => 0x403, 417 => 0x1500, 436 => 0xe, 464 => 0x1278, 465 => 0x1134, 466 => 0x32c, 467 => 0x32c, 468 => 0x30a, 520 => 'FocalLength' },
3133
3134
  'focallength2' => { 456 => [0x23,0x25,0x29] },
3134
3135
  'focallength35mm' => { 339 => 'FocalLength35mm' },
3135
- 'focallengthin35mmformat' => { 123 => 0xa405, 424 => 0xa01a, 520 => 'FocalLengthIn35mmFilm' },
3136
+ 'focallengthin35mmformat' => { 123 => 0xa405, 404 => 'camera.focal_length.35mm_equivalent', 424 => 0xa01a, 520 => 'FocalLengthIn35mmFilm' },
3136
3137
  'focallengthtelezoom' => { 436 => 0x10 },
3137
3138
  'focalplaneafpointarea' => { 469 => 0x2 },
3138
3139
  'focalplaneafpointlocation1' => { 469 => 0x6 },
@@ -4115,7 +4116,7 @@ my %tagLookup = (
4115
4116
  'lensmanualdistortionamount' => { 514 => 'LensManualDistortionAmount', 516 => 'LensManualDistortionAmount' },
4116
4117
  'lensmanufacturer' => { 182 => 'LensManufacturer' },
4117
4118
  'lensmaxaperturerange' => { 427 => 0x2b },
4118
- 'lensmodel' => { 7 => 0x937, 14 => 0x92b, 15 => 0x933, 67 => 0x95, 123 => 0xa434, 167 => 'Model', 182 => 'LensModel', 235 => 0x18a, 236 => 0x18b, 237 => 0x2ac, 326 => 0x203, 381 => 0xc, 394 => 0x412, 521 => 'LensModel' },
4119
+ 'lensmodel' => { 7 => 0x937, 14 => 0x92b, 15 => 0x933, 67 => 0x95, 123 => 0xa434, 167 => 'Model', 182 => 'LensModel', 235 => 0x18a, 236 => 0x18b, 237 => 0x2ac, 326 => 0x203, 381 => 0xc, 394 => 0x412, 404 => 'camera.lens_model', 521 => 'LensModel' },
4119
4120
  'lensmodulationoptimizer' => { 131 => 0x1045 },
4120
4121
  'lensmount' => { 439 => 0x99, 464 => 0x1892, 466 => 0x18be, 467 => 0x18ee, 468 => 0x17f2, 470 => 0x105, 471 => 0x105, 482 => 0x604, 483 => 0x5e },
4121
4122
  'lensmount2' => { 487 => 0x8 },
@@ -4726,7 +4727,8 @@ my %tagLookup = (
4726
4727
  'maxavailwidth' => { 528 => 'MaxAvailWidth' },
4727
4728
  'maxcontinuousrelease' => { 305 => 0xb, 306 => 0xc, 308 => '12.1', 309 => '12.1', 314 => 0xc, 315 => 0xb, 318 => '12.1', 319 => '12.1', 321 => 0x3d, 322 => 0x3d, 323 => 0x3d },
4728
4729
  'maxfaces' => { 329 => 0x1202 },
4729
- 'maxfocallength' => { 7 => 0xe6, 8 => 0x10, 9 => 0x1ab, 10 => 0x13, 11 => 0x115, 12 => 0x13, 13 => 0x153, 14 => 0xda, 16 => 0xfa, 17 => 0xee, 18 => 0x103, 19 => 0x95, 20 => 0xea, 21 => 0x157, 22 => 0xee, 23 => 0xec, 24 => 0x12b, 25 => 0x165, 26 => 0x16a, 27 => 0x188, 28 => 0x116, 29 => 0x18d, 36 => 0x17, 64 => 0x9, 131 => 0x1405, 167 => 'MaxFocalLength', 232 => 0x9, 233 => 0xe, 234 => 0xf, 238 => 0x10, 326 => 0x208, 464 => 0x127c, 465 => 0x1138, 466 => 0x330, 467 => 0x330, 468 => 0x30e },
4730
+ 'maxfocallength' => { 7 => 0xe6, 8 => 0x10, 9 => 0x1ab, 10 => 0x13, 11 => 0x115, 12 => 0x13, 13 => 0x153, 14 => 0xda, 16 => 0xfa, 17 => 0xee, 18 => 0x103, 19 => 0x95, 20 => 0xea, 21 => 0x157, 22 => 0xee, 23 => 0xec, 24 => 0x12b, 25 => 0x165, 26 => 0x16a, 27 => 0x188, 28 => 0x116, 29 => 0x18d, 36 => 0x17, 131 => 0x1405, 167 => 'MaxFocalLength', 232 => 0x9, 233 => 0xe, 234 => 0xf, 238 => 0x10, 326 => 0x208, 464 => 0x127c, 465 => 0x1138, 466 => 0x330, 467 => 0x330, 468 => 0x30e },
4731
+ 'maxfocallength2' => { 64 => 0x9 },
4730
4732
  'maximumdensityrange' => { 137 => 0x8c },
4731
4733
  'maxpagesize' => { 548 => 'MaxPageSize' },
4732
4734
  'maxpagesizeh' => { 548 => [\'MaxPageSize','MaxPageSizeH'] },
@@ -4829,7 +4831,8 @@ my %tagLookup = (
4829
4831
  'mime' => { 499 => 'Mime' },
4830
4832
  'minaperture' => { 36 => 0x1b, 142 => 0x3f8, 167 => 'MinAperture', 375 => '0.2' },
4831
4833
  'minaperturevalue' => { 394 => 0x415 },
4832
- 'minfocallength' => { 7 => 0xe4, 8 => 0xe, 9 => 0x1a9, 10 => 0x11, 11 => 0x113, 12 => 0x11, 13 => 0x151, 14 => 0xd8, 16 => 0xf8, 17 => 0xec, 18 => 0x101, 19 => 0x93, 20 => 0xe8, 21 => 0x155, 22 => 0xec, 23 => 0xea, 24 => 0x129, 25 => 0x163, 26 => 0x168, 27 => 0x186, 28 => 0x114, 29 => 0x18b, 36 => 0x18, 64 => 0x8, 131 => 0x1404, 167 => 'MinFocalLength', 232 => 0x8, 233 => 0xd, 234 => 0xe, 238 => 0xf, 326 => 0x207, 464 => 0x127a, 465 => 0x1136, 466 => 0x32e, 467 => 0x32e, 468 => 0x30c },
4834
+ 'minfocallength' => { 7 => 0xe4, 8 => 0xe, 9 => 0x1a9, 10 => 0x11, 11 => 0x113, 12 => 0x11, 13 => 0x151, 14 => 0xd8, 16 => 0xf8, 17 => 0xec, 18 => 0x101, 19 => 0x93, 20 => 0xe8, 21 => 0x155, 22 => 0xec, 23 => 0xea, 24 => 0x129, 25 => 0x163, 26 => 0x168, 27 => 0x186, 28 => 0x114, 29 => 0x18b, 36 => 0x18, 131 => 0x1404, 167 => 'MinFocalLength', 232 => 0x8, 233 => 0xd, 234 => 0xe, 238 => 0xf, 326 => 0x207, 464 => 0x127a, 465 => 0x1136, 466 => 0x32e, 467 => 0x32e, 468 => 0x30c },
4835
+ 'minfocallength2' => { 64 => 0x8 },
4833
4836
  'minfocusdistance' => { 375 => 0x3 },
4834
4837
  'minimumiso' => { 349 => 0xe8 },
4835
4838
  'minintegrationrows' => { 142 => 0x1874 },
@@ -11290,6 +11293,7 @@ my %tagExists = (
11290
11293
  'peakspectralsensitivity' => 1,
11291
11294
  'peakvalue' => 1,
11292
11295
  'pefversion' => 1,
11296
+ 'peg_info' => 1,
11293
11297
  'pentax' => 1,
11294
11298
  'pentaxdata' => 1,
11295
11299
  'pentaxdata2' => 1,
@@ -11750,6 +11754,7 @@ my %tagExists = (
11750
11754
  'releasedateyearmonth' => 1,
11751
11755
  'releasedateyearmonthday' => 1,
11752
11756
  'releasinginstructions' => 1,
11757
+ 'remasterinfo' => 1,
11753
11758
  'rembrandtconsumertonescale' => 1,
11754
11759
  'rembrandtportraittonescale' => 1,
11755
11760
  'rembrandttonescale' => 1,
@@ -11915,6 +11920,7 @@ my %tagExists = (
11915
11920
  'sampletochunk' => 1,
11916
11921
  'sampletogroup' => 1,
11917
11922
  'samsung' => 1,
11923
+ 'samsungcaptureinfo' => 1,
11918
11924
  'samsungifd' => 1,
11919
11925
  'samsunginfo' => 1,
11920
11926
  'samsungmodel' => 1,
@@ -12,7 +12,7 @@ meta information extracted from or written to a file.
12
12
  =head1 TAG TABLES
13
13
 
14
14
  The tables listed below give the names of all tags recognized by ExifTool.
15
- They contain a total of 27892 tags, with 17459 unique tag names.
15
+ They contain a total of 27899 tags, with 17464 unique tag names.
16
16
 
17
17
  B<Tag ID>, B<Index#> or B<Sequence> is given in the first column of each
18
18
  table. A B<Tag ID> is the computer-readable equivalent of a tag name, and
@@ -10476,6 +10476,7 @@ WB tags for the Canon G9.
10476
10476
  21 FocusDistanceLower int16u
10477
10477
  23 ShutterMode int16s
10478
10478
  25 FlashExposureLock int16s
10479
+ 32 AntiFlicker int16s
10479
10480
  61 RFLensType int16u
10480
10481
 
10481
10482
  =head3 Canon SerialInfo Tags
@@ -11600,8 +11601,8 @@ Information about creative filter settings.
11600
11601
  4 RollAngle int32s
11601
11602
  5 PitchAngle int32s
11602
11603
  7 FocalLength int32s
11603
- 8 MinFocalLength int32s
11604
- 9 MaxFocalLength int32s
11604
+ 8 MinFocalLength2 int32s
11605
+ 9 MaxFocalLength2 int32s
11605
11606
 
11606
11607
  =head3 Canon CTMD Tags
11607
11608
 
@@ -20869,10 +20870,10 @@ Camera orientation information written by the Gear 360 (SM-C200).
20869
20870
 
20870
20871
  =head3 Samsung Trailer Tags
20871
20872
 
20872
- Tags extracted from the trailer of JPEG images written when using certain
20873
- features (such as "Sound & Shot" or "Shot & More") from Samsung models such
20874
- as the Galaxy S4 and Tab S, and from the 'sefd' atom in HEIC images from the
20875
- Samsung S10+.
20873
+ Tags extracted from the SEFT trailer of JPEG and PNG images written when
20874
+ using certain features (such as "Sound & Shot" or "Shot & More") from
20875
+ Samsung models such as the Galaxy S4 and Tab S, and from the 'sefd' atom in
20876
+ HEIC images from models such as the S10+.
20876
20877
 
20877
20878
  Tag Name Writable
20878
20879
  -------- --------
@@ -20890,6 +20891,9 @@ Samsung S10+.
20890
20891
  EmbeddedVideoFile no
20891
20892
  EmbeddedVideoType no
20892
20893
  MCCData no
20894
+ PEg_Info JSON
20895
+ RemasterInfo no
20896
+ SamsungCaptureInfo no
20893
20897
  SingleShotDepthMap no
20894
20898
  SingleShotMeta Samsung SingleShotMeta
20895
20899
  SurroundShotVideo no
@@ -29614,7 +29618,7 @@ for the official QuickTime specification.
29614
29618
  The tags below are extracted from timed metadata in QuickTime and other
29615
29619
  formats of video files when the ExtractEmbedded option is used. Although
29616
29620
  most of these tags are combined into the single table below, ExifTool
29617
- currently reads 74 different formats of timed GPS metadata from video files.
29621
+ currently reads 77 different formats of timed GPS metadata from video files.
29618
29622
 
29619
29623
  Tag Name Writable
29620
29624
  -------- --------
@@ -29814,9 +29818,12 @@ changed via the config file.
29814
29818
  'artist' Artist yes
29815
29819
  'artwork' Artwork yes
29816
29820
  'author' Author yes
29821
+ 'camera.focal_length.35mm_equivalent'
29822
+ FocalLengthIn35mmFormat yes
29817
29823
  'camera.framereadouttimeinmicroseconds'
29818
29824
  FrameReadoutTime yes
29819
29825
  'camera.identifier' CameraIdentifier yes
29826
+ 'camera.lens_model' LensModel yes
29820
29827
  'collection.user' UserCollection yes
29821
29828
  'com.android.capture.fps' AndroidCaptureFPS yes
29822
29829
  'com.android.version' AndroidVersion yes
@@ -536,7 +536,7 @@ sub WriteItemInfo($$$)
536
536
  my $comp = $et->Options('Compress');
537
537
  if (defined $comp and ($comp xor $$item{ContentEncoding})) {
538
538
  #TODO: add ability to edit infe entry in iinf to change encoding according to Compress option if set
539
- $et->Warn("Can't currently change compression when rewriting $name in HEIC");
539
+ $et->Warn("Can't currently change compression when rewriting $name in HEIC",1);
540
540
  }
541
541
  my $wasDeflated;
542
542
  if ($$item{ContentEncoding}) {
@@ -2835,7 +2835,10 @@ sub GetAllGroups($;$)
2835
2835
  $family == 3 and return('Doc#', 'Main');
2836
2836
  $family == 4 and return('Copy#');
2837
2837
  $family == 5 and return('[too many possibilities to list]');
2838
- $family == 6 and return(@Image::ExifTool::Exif::formatName[1..$#Image::ExifTool::Exif::formatName]);
2838
+ if ($family == 6) {
2839
+ my $fn = \%Image::ExifTool::Exif::formatNumber;
2840
+ return(sort { $$fn{$a} <=> $$fn{$b} } keys %$fn);
2841
+ }
2839
2842
  $family == 8 and return('File#');
2840
2843
 
2841
2844
  LoadAllTables(); # first load all our tables
@@ -29,7 +29,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
29
29
  %jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
30
30
  %static_vars $advFmtSelf);
31
31
 
32
- $VERSION = '12.89';
32
+ $VERSION = '12.93';
33
33
  $RELEASE = '';
34
34
  @ISA = qw(Exporter);
35
35
  %EXPORT_TAGS = (
@@ -1,6 +1,6 @@
1
1
  Summary: perl module for image data extraction
2
2
  Name: perl-Image-ExifTool
3
- Version: 12.89
3
+ Version: 12.93
4
4
  Release: 1
5
5
  License: Artistic/GPL
6
6
  Group: Development/Libraries/Perl
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ExiftoolVendored
4
- VERSION = Gem::Version.new('12.89.0')
4
+ VERSION = Gem::Version.new('12.93.0')
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exiftool_vendored
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.89.0
4
+ version: 12.93.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew McEachen
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-07-18 00:00:00.000000000 Z
12
+ date: 2024-08-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: exiftool