Skip to content

Commit

Permalink
Merge pull request #79 from woss/v13.21
Browse files Browse the repository at this point in the history
Update exiftool to version 13.21
  • Loading branch information
woss authored Feb 24, 2025
2 parents 4417299 + e0aa14c commit 475b7fe
Show file tree
Hide file tree
Showing 20 changed files with 6,926 additions and 5,755 deletions.
202 changes: 138 additions & 64 deletions exiftool/exiftool

Large diffs are not rendered by default.

18 changes: 16 additions & 2 deletions 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 = '13.19';
$VERSION = '13.21';
$RELEASE = '';
@ISA = qw(Exporter);
%EXPORT_TAGS = (
Expand Down Expand Up @@ -1152,6 +1152,7 @@ my @availableOptions = (
[ 'NoPDFList', undef, 'flag to avoid splitting PDF List-type tag values' ],
[ 'NoWarning', undef, 'regular expression for warnings to suppress' ],
[ 'Password', undef, 'password for password-protected PDF documents' ],
[ 'Plot', undef, 'SVG plot settings' ],
[ 'PrintCSV', undef, 'flag to print CSV directly (selected metadata types only)' ],
[ 'PrintConv', 1, 'flag to enable print conversion' ],
[ 'QuickTimeHandler', 1, 'flag to add mdir Handler to newly created Meta box' ],
Expand Down Expand Up @@ -2587,6 +2588,10 @@ sub Options($$;@)
} else {
warn("Can't set $param to undef\n");
}
} elsif ($param eq 'Plot') {
# add to existing plot settings
$newVal = "$oldVal,$newVal" if defined $oldVal and defined $newVal;
$$options{$param} = $newVal;
} elsif (lc $param eq 'geodir') {
$Image::ExifTool::Geolocation::geoDir = $newVal;
} else {
Expand Down Expand Up @@ -9151,10 +9156,11 @@ sub AddTagToTable($$;$$)
# Handle simple extraction of new tag information
# Inputs: 0) ExifTool object ref, 1) tag table reference, 2) tagID, 3) value,
# 4-N) parameters hash: Index, DataPt, DataPos, Base, Start, Size, Parent,
# TagInfo, ProcessProc, RAF, Format, Count
# TagInfo, ProcessProc, RAF, Format, Count, MakeTagInfo
# Returns: tag key or undef if tag not found
# Notes: if value is not defined, it is extracted from DataPt using TagInfo
# Format and Count if provided
# - set MakeTagInfo to add tag info for unknown tags with name made from tag ID
sub HandleTag($$$$;%)
{
my ($self, $tagTablePtr, $tag, $val, %parms) = @_;
Expand All @@ -9166,6 +9172,14 @@ sub HandleTag($$$$;%)

if ($tagInfo) {
$subdir = $$tagInfo{SubDirectory};
} elsif ($parms{MakeTagInfo}) {
$self->VPrint(0, $$self{INDENT}, "[adding $tag]\n") if $verbose;
my $name = $tag;
$name =~ s/([^A-Za-z])([a-z])/$1\u$2/g; # capitalize words
$name =~ tr/-_a-zA-Z0-9//dc; # remove illegal characters
$name = "Tag$name" if length($name) < 2 or $name =~ /^[-0-9]/;
$tagInfo = { Name => ucfirst($name) };
AddTagToTable($tagTablePtr, $tag, $tagInfo);
} else {
return undef unless $verbose;
$tagInfo = { Name => "tag $tag" }; # create temporary tagInfo hash
Expand Down
27 changes: 27 additions & 0 deletions exiftool/lib/Image/ExifTool.pod
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,33 @@ Password for reading/writing password-protected PDF documents. Ignored if a
password is not required. Character encoding of the password is determined
by the value of the Charset option at processing time. Default is undef.

=item Plot

Settings to override defaults for SVG plot feature. Value is a comma
delimited string of settings, or undef to revert to default settings.
Settings are accumulated if this option is set multiple times. Commas in
the settings must be escaped as "&#44;". Valid settings and their default
values are:

"Type=Line" - plot type (Line, Scatter or Histogram)
"Style=Line" - data style (Line, Marker and/or Fill)
"NBins=20" - number of bins for histogram plot
"Size=800 600" - width,height of output image
"Margin=60 15 15 30" - left,top,right,bottom margins around plot area
"Legend=0 0" - x,y offset to shift plot legend
"TxtPad=10 10" - padding between text and x,y scale
"LineSpacing=20" - spacing between text lines
Title, XLabel, YLabel - plot title and x/y axis labels (no default)
XMin, XMax - x axis minimum/maximum (autoscaling if not set)
YMin, YMax - y axis minimum/maximum
Split - flag to split strings of numbers into lists
(> 1 to split into lists of N items)
"Grid=darkgray" - grid color
"Text=black" - color of text and plot border
"Bkg=" - background color (default is transparent)
"Cols=red green blue black orange gray purple cyan brown pink"
- colors for plot data

=item PrintConv

Flag to enable automatic print conversion. Also enables inverse
Expand Down
108 changes: 85 additions & 23 deletions exiftool/lib/Image/ExifTool/DJI.pm
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ use Image::ExifTool::Protobuf;
$VERSION = '1.13';

sub ProcessDJIInfo($$$);
sub ProcessSettings($$$);

%knownProtocol = (
'dvtm_ac203.proto' => 1, # Osmo Action 4
'dvtm_ac204.proto' => 1, # Osmo Action 5
'dvtm_AVATA2.proto' => 1, # Avanta 2
'dvtm_AVATA2.proto' => 1, # Avata 2
'dvtm_wm265e.proto' => 1, # Mavic 3
'dvtm_pm320.proto' => 1, # Matrice 30
'dvtm_Mini4_Pro.proto' => 1, # Matrice 30
Expand Down Expand Up @@ -197,6 +198,27 @@ my %convFloat2 = (
},
);

%Image::ExifTool::DJI::Glamour = (
GROUPS => { 0 => 'QuickTime', 1 => 'DJI', 2 => 'Image' },
PROCESS_PROC => \&Image::ExifTool::DJI::ProcessSettings,
NOTES => 'Glamour settings used by some DJI models.',
beauty_enable => 'BeautyEnable',
smoother => 'Smoother',
whitening => 'Whitening',
face_slimming => 'FaceSlimming',
eye_enlarge => 'EyeEnlarge',
nose_slimming => 'NoseSlimming',
mouth_beautify => 'MouthModify',
teeth_whitening => 'TeethWhitening',
leg_longer => 'LegLonger',
head_shrinking => 'HeadShrinking',
lipstick => 'Lipstick',
blush => 'Blush',
dark_circle => 'DarkCircle',
acne_spot_removal=>'AcneSpotRemoval',
eyebrows => 'Eyebrows',
);

# metadata in protobuf format (djmd and dbgi meta types, ref PH)
%Image::ExifTool::DJI::Protobuf = (
GROUPS => { 0 => 'Protobuf', 1 => 'DJI', 2 => 'Camera' },
Expand All @@ -210,7 +232,7 @@ my %convFloat2 = (
file name combined with the hierarchical protobuf field numbers.
ExifTool currently extracts timed GPS plus a few other tags from DJI devices
which use the following protocols: dvtm_AVATA2.proto (Avanta 2),
which use the following protocols: dvtm_AVATA2.proto (Avata 2),
dvtm_ac203.proto (Osmo Action 4), dvtm_ac204.proto (Osmo Action 5),
dvtm_wm265e.proto (Mavic 3), dvtm_pm320.proto (Matrice 30) and
dvtm_pm320.proto (Mini 4 Pro).
Expand All @@ -229,13 +251,21 @@ my %convFloat2 = (
#
# Osmo Action 4
#
'dvtm_ac203_1-1-5' => 'SerialNumber', # (NC)
'dvtm_ac203_1-1-5' => { Name => 'SerialNumber', Notes => 'Osmo Action 4' }, # (NC)
# dvtm_ac203_1-1-6 - some version number
'dvtm_ac203_1-1-10' => 'Model',
'dvtm_ac203_2-3' => {
Name => 'FrameInfo',
SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
},
'dvtm_ac203_3-2-2-1' => { Name => 'ISO', Format => 'float' },
'dvtm_ac203_3-2-4-1' => { # (NC)
Name => 'ShutterSpeed',
Format => 'rational',
PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
},
'dvtm_ac203_3-2-6-1' => { Name => 'ColorTemperature', Format => 'unsigned' }, # (NC)
# dvtm_ac203_3-2-9-1 - looks like Z accerometer measurement, but 2 and 3 don't look like other components
# dvtm_ac203_3-4-1-4 - model code?
'dvtm_ac203_3-4-2-1' => {
Name => 'GPSInfo',
Expand All @@ -258,19 +288,24 @@ my %convFloat2 = (
#
# Osmo Action 5
#
'dvtm_ac204_1-1-5' => 'SerialNumber', # (NC)
'dvtm_ac204_1-1-5' => { Name => 'SerialNumber', Notes => 'Osmo Action 5' }, # (NC)
# dvtm_ac204_1-1-6 - some version number
'dvtm_ac204_1-1-10' => 'Model',
'dvtm_ac204_2-3' => {
Name => 'FrameInfo',
SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
},
'dvtm_ac204_3-2-4-1' => { # (NC)
Name => 'ShutterSpeed',
Format => 'rational',
PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
},
'dvtm_ac204_3-2-6-1' => { Name => 'ColorTemperature', Format => 'unsigned' }, # (NC)
# dvtm_ac204_3-4-1-4 - model code?
'dvtm_ac204_3-4-2-1' => {
Name => 'GPSInfo',
SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
},
# dvtm_ac204_3-2-4-1 - shutter speed? (rational)
'dvtm_ac204_3-4-2-2' => {
Name => 'GPSAltitude',
Groups => { 2 => 'Location' },
Expand All @@ -286,11 +321,11 @@ my %convFloat2 = (
PrintConv => '$self->ConvertDateTime($val)',
},
#
# Avanta 2
# Avata 2
#
# dvtm_AVATA2_1-1-2 - some version number
# dvtm_AVATA2_1-1-3 - some version number
'dvtm_AVATA2_1-1-5' => 'SerialNumber', # (NC)
'dvtm_AVATA2_1-1-5' => { Name => 'SerialNumber', Notes => 'Avata 2' }, # (NC)
'dvtm_AVATA2_1-1-10' => 'Model',
# dvtm_AVATA2_2-2-1-4 - model code?
'dvtm_AVATA2_2-2-3-1' => 'SerialNumber2', # (NC)
Expand All @@ -308,17 +343,33 @@ my %convFloat2 = (
},
# dvtm_AVATA2_3-2-1-4 - model code?
# dvtm_AVATA2_3-2-1-5 - frame rate?
# dvtm_AVATA2_3-2-4-1 - shutter speed? (rational)
'dvtm_AVATA2_3-2-2-1' => { Name => 'ISO', Format => 'float' }, # (NC)
'dvtm_AVATA2_3-2-4-1' => {
Name => 'ShutterSpeed',
Format => 'rational',
PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
},
'dvtm_AVATA2_3-2-6-1' => { Name => 'ColorTemperature', Format => 'unsigned' }, # (NC)
'dvtm_AVATA2_3-2-10-1' => { # (NC)
Name => 'FNumber',
Format => 'rational',
PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
},
# dvtm_AVATA2_3-4-1-4 - model code?
# dvtm_AVATA2_3-4-3-1,2,3 - YPR? (int64s)
'dvtm_AVATA2_3-4-3' => { # (NC)
Name => 'DroneInfo',
SubDirectory => { TagTable => 'Image::ExifTool::DJI::DroneInfo' },
},
'dvtm_AVATA2_3-4-4-1' => {
Name => 'GPSInfo',
SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
},
'dvtm_AVATA2_3-4-4-2' => { Name => 'AbsoluteAltitude', Format => 'int64s', ValueConv => '$val / 1000' }, # (NC)
'dvtm_AVATA2_3-4-5-1' => { Name => 'RelativeAltitude', Format => 'float', ValueConv => '$val / 1000' }, # (NC)
#
# Mavic 3
#
'dvtm_wm265e_1-1-5' => 'SerialNumber', # (confirmed)
'dvtm_wm265e_1-1-5' => { Name => 'SerialNumber', Notes => 'Mavic 3' }, # (confirmed)
'dvtm_wm265e_1-1-10' => 'Model',
'dvtm_wm265e_2-2' => {
Name => 'FrameInfo',
Expand Down Expand Up @@ -350,7 +401,7 @@ my %convFloat2 = (
#
# Matrice 30
#
'dvtm_pm320_1-1-5' => 'SerialNumber',
'dvtm_pm320_1-1-5' => { Name => 'SerialNumber', Notes => 'Matrice 30' },
'dvtm_pm320_1-1-10' => 'Model',
'dvtm_pm320_2-2' => {
Name => 'FrameInfo',
Expand Down Expand Up @@ -380,7 +431,7 @@ my %convFloat2 = (
#
# Mini 4 Pro
#
'dvtm_Mini4_Pro_1-1-5' => 'SerialNumber',
'dvtm_Mini4_Pro_1-1-5' => { Name => 'SerialNumber', Notes => 'Mini 4 Pro' },
'dvtm_Mini4_Pro_1-1-10' => 'Model',
'dvtm_Mini4_Pro_2-3' => {
Name => 'FrameInfo',
Expand Down Expand Up @@ -418,7 +469,7 @@ my %convFloat2 = (
%Image::ExifTool::DJI::DroneInfo = (
GROUPS => { 0 => 'Protobuf', 1 => 'DJI', 2 => 'Camera' },
PROCESS_PROC => \&Image::ExifTool::Protobuf::ProcessProtobuf,
VARS => { HEX_ID => 0 },
VARS => { HEX_ID => 0, ID_LABEL => 'Field #' },
1 => { Name => 'DroneRoll', Format => 'int64s', ValueConv => '$val / 10' },
2 => { Name => 'DronePitch', Format => 'int64s', ValueConv => '$val / 10' },
3 => { Name => 'DroneYaw', Format => 'int64s', ValueConv => '$val / 10' },
Expand All @@ -427,16 +478,16 @@ my %convFloat2 = (
%Image::ExifTool::DJI::GimbalInfo = (
GROUPS => { 0 => 'Protobuf', 1 => 'DJI', 2 => 'Camera' },
PROCESS_PROC => \&Image::ExifTool::Protobuf::ProcessProtobuf,
VARS => { HEX_ID => 0 },
VARS => { HEX_ID => 0, ID_LABEL => 'Field #' },
1 => { Name => 'GimbalPitch',Format => 'int64s', ValueConv => '$val / 10' },
2 => { Name => 'GimbalRoll', Format => 'int64s', ValueConv => '$val / 10' },
2 => { Name => 'GimbalRoll', Format => 'int64s', ValueConv => '$val / 10' }, # usually 0, so missing
3 => { Name => 'GimbalYaw', Format => 'int64s', ValueConv => '$val / 10' },
);

%Image::ExifTool::DJI::FrameInfo = (
GROUPS => { 0 => 'Protobuf', 1 => 'DJI', 2 => 'Video' },
PROCESS_PROC => \&Image::ExifTool::Protobuf::ProcessProtobuf,
VARS => { HEX_ID => 0 },
VARS => { HEX_ID => 0, ID_LABEL => 'Field #' },
1 => { Name => 'FrameWidth', Format => 'unsigned' },
2 => { Name => 'FrameHeight', Format => 'unsigned' },
3 => { Name => 'FrameRate', Format => 'float' },
Expand All @@ -445,7 +496,7 @@ my %convFloat2 = (
%Image::ExifTool::DJI::GPSInfo = (
GROUPS => { 0 => 'Protobuf', 1 => 'DJI', 2 => 'Location' },
PROCESS_PROC => \&Image::ExifTool::Protobuf::ProcessProtobuf,
VARS => { HEX_ID => 0 },
VARS => { HEX_ID => 0, ID_LABEL => 'Field #' },
1 => {
Name => 'CoordinateUnits',
Format => 'unsigned',
Expand All @@ -469,6 +520,22 @@ my %convFloat2 = (
},
);

#------------------------------------------------------------------------------
# Process DJI beauty settings (ref PH)
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
# Returns: 1 on success
sub ProcessSettings($$$)
{
my ($et, $dirInfo, $tagTbl) = @_;
$et->VerboseDir($$dirInfo{DirName}, undef, length(${$$dirInfo{DataPt}}));
foreach (split /;/, ${$$dirInfo{DataPt}}) {
my ($tag, $val) = split /=/;
next unless defined $tag and defined $val;
$et->HandleTag($tagTbl, $tag, $val, MakeTagInfo => 1);
}
return 1;
}

#------------------------------------------------------------------------------
# Process DJI info (ref PH)
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
Expand All @@ -493,12 +560,7 @@ sub ProcessDJIInfo($$$)
my $buff = $val;
$val = \$buff;
}
if (not $$tagTbl{$tag} and $tag=~ /^[-_a-zA-Z0-9]+$/) {
my $name = $tag;
$name =~ s/_([a-z])/_\U$1/g;
AddTagToTable($tagTbl, $tag, { Name => Image::ExifTool::MakeTagName($name) });
}
$et->HandleTag($tagTbl, $tag, $val);
$et->HandleTag($tagTbl, $tag, $val, MakeTagInfo => 1);
}
return 1;
}
Expand Down
11 changes: 2 additions & 9 deletions exiftool/lib/Image/ExifTool/EXE.pm
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use strict;
use vars qw($VERSION);
use Image::ExifTool qw(:DataAccess :Utils);

$VERSION = '1.22';
$VERSION = '1.23';

sub ProcessPEResources($$);
sub ProcessPEVersion($$);
Expand Down Expand Up @@ -1005,20 +1005,13 @@ sub ProcessPEVersion($$)
next;
}
my $tag = $string;
# create entry in tag table if it doesn't already exist
unless ($$tagTablePtr{$tag}) {
my $name = $tag;
$name =~ tr/-_a-zA-Z0-9//dc; # remove illegal characters
next unless length $name;
AddTagToTable($tagTablePtr, $tag, { Name => $name });
}
# get tag value (converted to current Charset)
if ($valLen) {
($string, $pt) = ReadUnicodeStr($dataPt, $pt, $entryEnd, $et);
} else {
$string = '';
}
$et->HandleTag($tagTablePtr, $tag, $string);
$et->HandleTag($tagTablePtr, $tag, $string, MakeTagInfo => 1);
# step to next entry (padded to an even word)
$pt = ($entryEnd + 3) & 0xfffffffc;
}
Expand Down
Loading

0 comments on commit 475b7fe

Please sign in to comment.