Skip to content

Commit

Permalink
Merge pull request #13 from woss/v12.92
Browse files Browse the repository at this point in the history
v12.92
  • Loading branch information
woss authored Jul 26, 2024
2 parents 167ba80 + 05fce7d commit f592e36
Show file tree
Hide file tree
Showing 13 changed files with 224 additions and 50 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/update.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Update Version
on: workflow_dispatch
jobs:
test-typescript:
runs-on: ubuntu-latest

steps:
- name: Checkout
id: checkout
uses: actions/checkout@v4

- name: Clone exiftool/master
run: ./script/update-exiftool

- name: Exiftool version
run: ./exiftool/exiftool -ver
10 changes: 5 additions & 5 deletions exiftool/exiftool
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/perl -w
#!/usr/bin/env perl
#------------------------------------------------------------------------------
# File: exiftool
#
Expand All @@ -11,7 +11,7 @@ use strict;
use warnings;
require 5.004;

my $version = '12.89';
my $version = '12.92';

# add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
my $exePath;
Expand Down Expand Up @@ -2310,8 +2310,8 @@ sub GetImageInfo($$)
# output using print format file (-p) option
my ($type, $doc, $grp, $lastDoc, $cache);
$fileTrailer = '';
# repeat for each sub-document if necessary
if ($$et{DOC_COUNT}) {
# repeat for each embedded document if necessary (only if -ee used)
if ($et->Options('ExtractEmbedded')) {
# (cache tag keys if there are sub-documents)
$lastDoc = $$et{DOC_COUNT} and $cache = { };
} else {
Expand Down Expand Up @@ -5684,7 +5684,7 @@ with this command:
produces output like this:
-- Generated by ExifTool 12.89 --
-- Generated by ExifTool 12.92 --
File: a.jpg - 2003:10:31 15:44:19
(f/5.6, 1/60s, ISO 100)
File: b.jpg - 2006:05:23 11:57:38
Expand Down
2 changes: 1 addition & 1 deletion exiftool/lib/Image/ExifTool.pm
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
%jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
%static_vars $advFmtSelf);

$VERSION = '12.89';
$VERSION = '12.92';
$RELEASE = '';
@ISA = qw(Exporter);
%EXPORT_TAGS = (
Expand Down
20 changes: 13 additions & 7 deletions exiftool/lib/Image/ExifTool/Canon.pm
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
sub ProcessExifInfo($$$);
sub SwapWords($);

$VERSION = '4.78';
$VERSION = '4.79';

# Note: Removed 'USM' from 'L' lenses since it is redundant - PH
# (or is it? Ref 32 shows 5 non-USM L-type lenses)
Expand Down Expand Up @@ -6403,6 +6403,8 @@ my %ciMaxFocal = (
12 => 'Flexizone Multi (9 point)', #PH (750D, 9 points)
13 => 'Flexizone Single', #PH (EOS M default, live view) (R7 calls this '1-point AF', ref github268)
14 => 'Large Zone AF', #PH/forum6237 (7DmkII)
16 => 'Large Zone AF (vertical)', #forum16223
17 => 'Large Zone AF (horizontal)', #forum16223
19 => 'Flexible Zone AF 1', #github268 (R7)
20 => 'Flexible Zone AF 2', #github268 (R7)
21 => 'Flexible Zone AF 3', #github268 (R7)
Expand Down Expand Up @@ -6921,6 +6923,10 @@ my %ciMaxFocal = (
Name => 'FlashExposureLock',
PrintConv => \%offOn,
},
32 => { #forum16257
Name => 'AntiFlicker',
PrintConv => \%offOn,
},
0x3d => { #IB
Name => 'RFLensType',
Format => 'int16u',
Expand Down Expand Up @@ -9123,19 +9129,19 @@ my %filterConv = (
2 => 'Disable',
},
},
18 => { #52
18 => { #52/forum16223
Name => 'AFStatusViewfinder',
Condition => '$$self{Model} =~ /1D X/',
Notes => '1D X only',
Condition => '$$self{Model} =~ /EOS-1D X|EOS R/',
Notes => '1D X and R models',
PrintConv => {
0 => 'Show in Field of View',
1 => 'Show Outside View',
},
},
19 => { #52
19 => { #52/forum16223
Name => 'InitialAFPointInServo',
Condition => '$$self{Model} =~ /1D X/',
Notes => '1D X only',
Condition => '$$self{Model} =~ /EOS-1D X|EOS R/',
Notes => '1D X and R models',
PrintConv => {
0 => 'Initial AF Point Selected',
1 => 'Manual AF Point',
Expand Down
35 changes: 34 additions & 1 deletion exiftool/lib/Image/ExifTool/Nikon.pm
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ use Image::ExifTool::Exif;
use Image::ExifTool::GPS;
use Image::ExifTool::XMP;

$VERSION = '4.35';
$VERSION = '4.36';

sub LensIDConv($$$);
sub ProcessNikonAVI($$$);
Expand Down Expand Up @@ -2495,6 +2495,7 @@ my %base64coord = (
{ # D7100=0227
Condition => '$$valPt =~ /^0[28]/',
Name => 'ShotInfo02xx',
Drop => 50000, # drop if too large (>64k for Z6iii)
SubDirectory => {
TagTable => 'Image::ExifTool::Nikon::ShotInfo',
ProcessProc => \&ProcessNikonEncrypted,
Expand Down Expand Up @@ -5635,6 +5636,38 @@ my %nikonFocalConversions = (
Notes => 'P6000',
PrintConv => \%offOn,
},
# for Nikon Z6iii JPG and RAW images (version 0809),
# the offset table starts at 0x24 and is as follows
# JPG Offset Size NEF Offset Size
# 0) 0x0000 0 0) 0x009c 21604
# 1) 0x0000 0 1) 0x5500 6008
# 2) 0x009c 2528 2) 0x6c78 2528
# 3) 0x0a7c 200 3) 0x7658 200
# 4) 0x0b44 2488 4) 0x7720 2488
# 5) 0x14fc 1468 5) 0x80d8 1468
# 6) 0x1ab8 1032 6) 0x8694 1032
# 7) 0x1ec0 256 7) 0x8a9c 256
# 8) 0x1fc0 800 8) 0x8b9c 800
# 9) 0x22e0 144 9) 0x8ebc 144
# 10) 0x2370 64 10) 0x8f4c 64
# 11) 0x0000 0 11) 0x0000 0
# 12) 0x23b0 5009 12) 0x8f8c 5009
# 13) 0x3741 1536 13) 0xa31d 1536
# 14) 0x3d41 11928 14) 0xa91d 11928
# 15) 0x6bd9 5937 15) 0xd7b5 5937
# 16) 0x830a 500 16) 0xeee6 500
# 17) 0x84fe 160 17) 0xf0da 160
# 18) 0x859e 464 18) 0xf17a 464
# 19) 0x876e 8 19) 0xf34a 8
# 20) 0x8776 64 20) 0xf352 64
# 21) 0x87b6 6 21) 0xf392 6
# 22) 0x87bc 48 22) 0xf398 48
# 23) 0x87ec 20 23) 0xf3c8 20
# 24) 0x8800 108 24) 0xf3dc 108
# 25) 0x886c 8 25) 0xf448 8
# 26) 0x8874 2420 26) 0xf450 2420
# 27) 0x0000 0 27) 0x0000 0
# 28) 0x0000 0 28) 0x0000 0
0x66 => {
Name => 'VR_0x66',
Condition => '$$self{ShotInfoVersion} eq "0204"',
Expand Down
12 changes: 10 additions & 2 deletions exiftool/lib/Image/ExifTool/PNG.pm
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use strict;
use vars qw($VERSION $AUTOLOAD %stdCase);
use Image::ExifTool qw(:DataAccess :Utils);

$VERSION = '1.67';
$VERSION = '1.68';

sub ProcessPNG_tEXt($$$);
sub ProcessPNG_iTXt($$$);
Expand Down Expand Up @@ -1400,7 +1400,7 @@ sub ProcessPNG($$)
my $fastScan = $et->Options('FastScan');
my $hash = $$et{ImageDataHash};
my ($n, $sig, $err, $hbuf, $dbuf, $cbuf);
my ($wasHdr, $wasEnd, $wasDat, $doTxt, @txtOffset);
my ($wasHdr, $wasEnd, $wasDat, $doTxt, @txtOffset, $wasTrailer);

# check to be sure this is a valid PNG/MNG/JNG image
return 0 unless $raf->Read($sig,8) == 8 and $pngLookup{$sig};
Expand Down Expand Up @@ -1461,6 +1461,7 @@ sub ProcessPNG($$)
if ($wasEnd) {
last unless $n; # stop now if normal end of PNG
$et->WarnOnce("Trailer data after $fileType $endChunk chunk", 1);
$wasTrailer = 1;
last if $n < 8;
$$et{SET_GROUP1} = 'Trailer';
} elsif ($n != 8) {
Expand Down Expand Up @@ -1654,6 +1655,13 @@ sub ProcessPNG($$)
}
}
delete $$et{SET_GROUP1};
# read Samsung trailer if it exists
if ($wasTrailer and not $outfile and $raf->Seek(-8, 2) and
$raf->Read($dbuf,8) and $dbuf =~ /\0\0(QDIOBS|SEFT)$/) # (have only seen SEFT type)
{
require Image::ExifTool::Samsung;
Image::ExifTool::Samsung::ProcessSamsung($et, { DirName => 'Samsung', RAF => $raf });
}
return -1 if $outfile and ($err or not $wasEnd);
return 1; # this was a valid PNG/MNG/JNG image
}
Expand Down
9 changes: 7 additions & 2 deletions exiftool/lib/Image/ExifTool/QuickTime.pm
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
use Image::ExifTool::Exif;
use Image::ExifTool::GPS;

$VERSION = '2.98';
$VERSION = '2.99';

sub ProcessMOV($$;$);
sub ProcessKeys($$$);
Expand Down Expand Up @@ -9737,7 +9737,7 @@ sub ProcessMOV($$;$)
if ($size > 0x2000000) { # start to get worried above 32 MiB
# check for RIFF trailer (written by Auto-Vox dashcam)
if ($buff =~ /^(gpsa|gps0|gsen|gsea)...\0/s) { # (yet seen only gpsa as first record)
$et->VPrint(0, "Found RIFF trailer");
$et->VPrint(0, sprintf("Found RIFF trailer at offset 0x%x",$lastPos));
if ($et->Options('ExtractEmbedded')) {
$raf->Seek(-8, 1) or last; # seek back to start of trailer
my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
Expand All @@ -9746,6 +9746,11 @@ sub ProcessMOV($$;$)
EEWarn($et);
}
last;
} elsif ($buff eq 'CCCCCCCC') {
$et->VPrint(0, sprintf("Found Kenwood trailer at offset 0x%x",$lastPos));
my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
ProcessKenwoodTrailer($et, { RAF => $raf }, $tbl);
last;
}
$ignore = 1;
if ($tagInfo and not $$tagInfo{Unknown} and not $eeTag) {
Expand Down
93 changes: 87 additions & 6 deletions exiftool/lib/Image/ExifTool/QuickTimeStream.pl
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ package Image::ExifTool::QuickTime;
The tags below are extracted from timed metadata in QuickTime and other
formats of video files when the ExtractEmbedded option is used. Although
most of these tags are combined into the single table below, ExifTool
currently reads 74 different formats of timed GPS metadata from video files.
currently reads 76 different formats of timed GPS metadata from video files.
},
VARS => { NO_ID => 1 },
GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
Expand Down Expand Up @@ -1420,9 +1420,10 @@ ($)
} elsif ($type eq 'gps ') { # (ie. GPSDataList tag)

if ($buff =~ /^....freeGPS /s) {
# process by brute scan instead if ExtractEmbedded >= 3
# (some videos don't reference all freeGPS info from 'gps ' table, eg. INNOV)
last if $eeOpt >= 3;
# parse freeGPS data unless done already in brute-force scan
# (some videos don't reference all freeGPS info from 'gps ' table, eg. INNOV,
# and some videos don't put 'gps ' data in mdat, eg XGODY 12" 4K Dashcam)
last if $$et{FoundGPSByScan};
# decode "freeGPS " data (Novatek and others)
ProcessFreeGPS($et, {
DataPt => \$buff,
Expand Down Expand Up @@ -2049,9 +2050,41 @@ ($$$)
}
}

} else {
} elsif ($$dataPt =~ m<^.{23}(\d{4})/(\d{2})/(\d{2}) (\d{2}):(\d{2}):(\d{2}) [N|S]>s) {

$debug and $et->FoundTag(GPSType => 16);
# XGODY 12" 4K Dashcam
# 0000: 00 00 00 a8 66 72 65 65 47 50 53 20 98 00 00 00 [....freeGPS ....]
# 0010: 6e 6f 72 6d 61 6c 3a 32 30 32 34 2f 30 35 2f 32 [normal:2024/05/2]
# 0020: 32 20 30 32 3a 35 34 3a 32 39 20 4e 3a 34 32 2e [2 02:54:29 N:42.]
# 0030: 33 38 32 34 37 30 20 57 3a 38 33 2e 33 38 39 35 [382470 W:83.3895]
# 0040: 37 30 20 35 33 2e 36 20 6b 6d 2f 68 20 78 3a 2d [70 53.6 km/h x:-]
# 0050: 30 2e 30 32 20 79 3a 30 2e 39 39 20 7a 3a 30 2e [0.02 y:0.99 z:0.]
# 0060: 31 30 20 41 3a 32 36 39 2e 32 20 48 3a 32 34 35 [10 A:269.2 H:245]
# 0070: 2e 35 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [.5..............]
($yr,$mon,$day,$hr,$min,$sec) = ($1,$2,$3,$4,$5,$6);
$$dataPt =~ s/\0+$//; # remove trailing nulls
my @a = split ' ', substr($$dataPt,43);
$ddd = 1;
foreach (@a) {
unless (/^([A-Z]):([-+]?\d+(\.\d+)?)$/i) {
# (the "km/h" after spd is display units? because the value is stored in knots)
defined $lon and not defined $spd and /^\d+\.\d+$/ and $spd = $_ * $knotsToKph;
next;
}
($1 eq 'N' or $1 eq 'S') and $lat = $2, $latRef = $1, next;
($1 eq 'E' or $1 eq 'W') and $lon = $2, $lonRef = $1, next;
($1 eq 'x' or $1 eq 'y' or $1 eq 'z') and push(@acc,$2), next;
$1 eq 'A' and $trk = $2, next; # (verified, but why 'A'?)
# seen 'H' - one might expect altitude ('H'eight), but it doesn't fit
# the sample data, so save all other information as an "Unknown_X" tag
$$tagTbl{$1} or AddTagToTable($tagTbl, $1, { Name => "Unknown_$1", Unknown => 1 });
push(@xtra, $1 => $2), next;
}

} else {

$debug and $et->FoundTag(GPSType => 17);
# (look for binary GPS as stored by Nextbase 512G, ref PH)
# 0000: 00 00 80 00 66 72 65 65 47 50 53 20 78 01 00 00 [....freeGPS x...]
# 0010: 78 2e 78 78 00 00 00 00 00 00 00 00 00 00 00 00 [x.xx............]
Expand Down Expand Up @@ -2115,7 +2148,7 @@ ($$$)
my $time = sprintf('%.2d:%.2d:%sZ',$hr,$min,$sec);
$et->HandleTag($tagTbl, GPSTimeStamp => $time);
}
if (defined $lat) {
if (defined $lat and defined $lon) {
# lat/long are in DDDMM.MMMM format unless $ddd is set
ConvertLatLon($lat, $lon) unless $ddd;
$et->HandleTag($tagTbl, GPSLatitude => $lat * ($latRef eq 'S' ? -1 : 1));
Expand Down Expand Up @@ -2680,6 +2713,53 @@ ($$$)
return 1;
}

#------------------------------------------------------------------------------
# Process Kenwood Dashcam trailer (forum16229)
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
# Returns: 1 on success
# Sample data (chained 512-byte records starting like this):
# 0000: 43 43 43 43 43 43 43 43 43 43 43 43 43 43 47 50 [CCCCCCCCCCCCCCGP]
# 0010: 53 44 41 54 41 2d 2d 32 30 32 34 30 37 31 31 31 [SDATA--202407111]
# 0020: 32 30 34 31 32 4e 35 30 2e 36 31 32 33 38 36 30 [20412N50.6123860]
# 0030: 36 37 37 45 38 2e 37 30 32 37 31 38 30 39 38 39 [677E8.7027180989]
# 0040: 35 33 33 2e 30 30 30 30 30 30 30 30 30 30 30 30 [533.000000000000]
# 0050: 2e 30 30 30 30 30 30 30 30 30 30 30 30 30 2e 30 [.0000000000000.0]
# 0060: 31 39 39 39 39 39 39 39 35 35 33 2d 30 2e 30 39 [19999999553-0.09]
# 0070: 30 30 30 30 30 30 33 35 37 2d 30 2e 31 34 30 30 [000000357-0.1400]
# 0080: 30 30 30 30 30 35 39 47 50 53 44 41 54 41 2d 2d [0000059GPSDATA--]
sub ProcessKenwoodTrailer($$$)
{
my ($et, $dirInfo, $tagTbl) = @_;
my $raf = $$dirInfo{RAF};
my $buff;
# current file position is 8 bytes into the 14 C's, so test the next 6:
$raf->Read($buff, 14) and $buff eq 'CCCCCCCCCCCCCC' or return 0;
$et->VerboseDir('Kenwood trailer', undef, undef);
unless ($$et{OPTIONS}{ExtractEmbedded}) {
$et->WarnOnce('Use the ExtractEmbedded option to extract timed GPSData from Kenwood trailer',3);
return 1;
}
while ($raf->Read($buff, 121) and $buff =~ /^GPSDATA--(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/) {
FoundSomething($et, $tagTbl);
$et->HandleTag($tagTbl, GPSDateTime => "$1:$2:$3 $4:$5:$6");
my $i = 9 + 14;
my ($val, @acc, $tag);
foreach $tag (qw(GPSLatitude GPSLongitude GPSSpeed unk acc acc acc)) {
$val = substr($buff, $i, 14); $i += 14;
next if $tag eq 'unk';
my $hemi;
$hemi = $1 if $val =~ s/^([NSEW])//;
$val =~ /^[-+]?\d+\.\d+$/ or next;
$tag eq 'acc' and push(@acc,$val), next;
$val = -$val if $hemi and ($hemi eq 'S' or $hemi eq 'W');
$et->HandleTag($tagTbl, $tag => $val);
}
$et->HandleTag($tagTbl, Accelerometer => "@acc") if @acc == 3;
}
delete $$et{DOC_NUM};
return 1;
}

#------------------------------------------------------------------------------
# Process 'gps ' atom containing NMEA from Pittasoft Blackvue dashcam (ref PH)
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
Expand Down Expand Up @@ -3353,6 +3433,7 @@ ($)
}
my $dirInfo = { DataPt => \$buff, DataPos => $pos + $dataPos, DirLen => $len };
ProcessFreeGPS($et, $dirInfo, $tagTbl);
$$et{FoundGPSByScan} = 1;
}
$pos += $len;
$buf2 = substr($buff, $len);
Expand Down
Loading

0 comments on commit f592e36

Please sign in to comment.