DJI.pm (Image-ExifTool-12.57) | : | DJI.pm (Image-ExifTool-12.58) | ||
---|---|---|---|---|
skipping to change at line 19 | skipping to change at line 19 | |||
package Image::ExifTool::DJI; | package Image::ExifTool::DJI; | |||
use strict; | use strict; | |||
use vars qw($VERSION); | use vars qw($VERSION); | |||
use Image::ExifTool qw(:DataAccess :Utils); | use Image::ExifTool qw(:DataAccess :Utils); | |||
use Image::ExifTool::Exif; | use Image::ExifTool::Exif; | |||
use Image::ExifTool::XMP; | use Image::ExifTool::XMP; | |||
use Image::ExifTool::GPS; | use Image::ExifTool::GPS; | |||
$VERSION = '1.06'; | $VERSION = '1.07'; | |||
sub ProcessDJIInfo($$$); | sub ProcessDJIInfo($$$); | |||
my %convFloat2 = ( | my %convFloat2 = ( | |||
PrintConv => 'sprintf("%+.2f", $val)', | PrintConv => 'sprintf("%+.2f", $val)', | |||
PrintConvInv => '$val', | PrintConvInv => '$val', | |||
); | ); | |||
# DJI maker notes (ref PH, mostly educated guesses based on DJI QuickTime::UserD ata tags) | # DJI maker notes (ref PH, mostly educated guesses based on DJI QuickTime::UserD ata tags) | |||
%Image::ExifTool::DJI::Main = ( | %Image::ExifTool::DJI::Main = ( | |||
skipping to change at line 99 | skipping to change at line 99 | |||
0x4a => { Name => 'Reflection', Format => 'int16u', }, | 0x4a => { Name => 'Reflection', Format => 'int16u', }, | |||
0x4c => { Name => 'AmbientTemperature', Format => 'int16u' }, # (aka D1) | 0x4c => { Name => 'AmbientTemperature', Format => 'int16u' }, # (aka D1) | |||
0x50 => { Name => 'D2', Format => 'int32s' }, | 0x50 => { Name => 'D2', Format => 'int32s' }, | |||
0x54 => { Name => 'KJ', Format => 'int16u' }, | 0x54 => { Name => 'KJ', Format => 'int16u' }, | |||
0x56 => { Name => 'DB', Format => 'int16u' }, | 0x56 => { Name => 'DB', Format => 'int16u' }, | |||
0x58 => { Name => 'KK', Format => 'int16u' }, | 0x58 => { Name => 'KK', Format => 'int16u' }, | |||
# 0x500 - 0x55aa1206 - device header magic number | # 0x500 - 0x55aa1206 - device header magic number | |||
# (nothing yet decoded from device header) | # (nothing yet decoded from device header) | |||
); | ); | |||
# thermal parameters in APP4 of DJI M3T, H20N, M2EA and some M30T images (ref PH | ||||
/forum11401) | ||||
%Image::ExifTool::DJI::ThermalParams2 = ( | ||||
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, | ||||
GROUPS => { 0 => 'APP4', 2 => 'Image' }, | ||||
NOTES => 'Thermal parameters extracted from APP4 of DJI M3T RJPEG files.', | ||||
0x00 => { Name => 'AmbientTemperature', Format => 'float', PrintConv => 'sp | ||||
rintf("%.1f C",$val)' }, # (NC) | ||||
0x04 => { Name => 'ObjectDistance', Format => 'float', PrintConv => 'sp | ||||
rintf("%.1f m",$val)' }, | ||||
0x08 => { Name => 'Emissivity', Format => 'float', PrintConv => 'sp | ||||
rintf("%.2f",$val)' }, | ||||
0x0c => { Name => 'RelativeHumidity', Format => 'float', PrintConv => 'sp | ||||
rintf("%g %",$val*100)' }, | ||||
0x10 => { Name => 'ReflectedTemperature',Format => 'float', PrintConv => 'sp | ||||
rintf("%.1f C",$val)' }, | ||||
0x65 => { Name => 'IDString', Format => 'string[16]' }, # (NC) | ||||
); | ||||
# thermal parameters in APP4 of some DJI M30T images (ref PH) | ||||
%Image::ExifTool::DJI::ThermalParams3 = ( | ||||
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, | ||||
GROUPS => { 0 => 'APP4', 2 => 'Image' }, | ||||
NOTES => 'Thermal parameters extracted from APP4 of some DJI RJPEG files.', | ||||
# 0x00 - 0xaa553800 - params3 magic number | ||||
0x04 => { Name => 'RelativeHumidity', Format => 'int16u' }, | ||||
0x06 => { Name => 'ObjectDistance', Format => 'int16u', ValueConv => '$ | ||||
val / 10' }, | ||||
0x08 => { Name => 'Emissivity', Format => 'int16u', ValueConv => '$ | ||||
val / 100' }, | ||||
0x0a => { Name => 'ReflectedTemperature',Format => 'int16u', ValueConv => '$ | ||||
val / 10' }, | ||||
); | ||||
%Image::ExifTool::DJI::XMP = ( | %Image::ExifTool::DJI::XMP = ( | |||
%Image::ExifTool::XMP::xmpTableDefaults, | %Image::ExifTool::XMP::xmpTableDefaults, | |||
GROUPS => { 0 => 'XMP', 1 => 'XMP-drone-dji', 2 => 'Location' }, | GROUPS => { 0 => 'XMP', 1 => 'XMP-drone-dji', 2 => 'Location' }, | |||
NAMESPACE => 'drone-dji', | NAMESPACE => 'drone-dji', | |||
TABLE_DESC => 'XMP DJI', | TABLE_DESC => 'XMP DJI', | |||
VARS => { NO_ID => 1 }, | VARS => { NO_ID => 1 }, | |||
NOTES => 'XMP tags used by DJI for images from drones.', | NOTES => 'XMP tags used by DJI for images from drones.', | |||
AbsoluteAltitude => { Writable => 'real' }, | AbsoluteAltitude => { Writable => 'real' }, | |||
RelativeAltitude => { Writable => 'real' }, | RelativeAltitude => { Writable => 'real' }, | |||
GimbalRollDegree => { Writable => 'real' }, | GimbalRollDegree => { Writable => 'real' }, | |||
skipping to change at line 164 | skipping to change at line 189 | |||
}, | }, | |||
Longitude => { | Longitude => { | |||
Name => 'Longitude', | Name => 'Longitude', | |||
Writable => 'real', | Writable => 'real', | |||
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', | PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', | |||
PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1, "lon")', | PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1, "lon")', | |||
}, | }, | |||
); | ); | |||
#------------------------------------------------------------------------------ | #------------------------------------------------------------------------------ | |||
# Process DJI infor (ref PH) | # Process DJI info (ref PH) | |||
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref | # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref | |||
# Returns: 1 on success | # Returns: 1 on success | |||
sub ProcessDJIInfo($$$) | sub ProcessDJIInfo($$$) | |||
{ | { | |||
my ($et, $dirInfo, $tagTbl) = @_; | my ($et, $dirInfo, $tagTbl) = @_; | |||
my $dataPt = $$dirInfo{DataPt}; | my $dataPt = $$dirInfo{DataPt}; | |||
my $dirStart = $$dirInfo{DirStart} || 0; | my $dirStart = $$dirInfo{DirStart} || 0; | |||
my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart); | my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart); | |||
if ($dirStart) { | if ($dirStart) { | |||
my $buff = substr($$dataPt, $dirStart, $dirLen); | my $buff = substr($$dataPt, $dirStart, $dirLen); | |||
$dataPt = \$buff; | $dataPt = \$buff; | |||
} | } | |||
$et->VerboseDir('DJIInfo', undef, length $$dataPt); | ||||
while ($$dataPt =~ /\G\[(.*?)\](?=(\[|$))/sg) { | while ($$dataPt =~ /\G\[(.*?)\](?=(\[|$))/sg) { | |||
my ($tag, $val) = split /:/, $1, 2; | my ($tag, $val) = split /:/, $1, 2; | |||
next unless defined $tag and defined $val; | next unless defined $tag and defined $val; | |||
if ($val =~ /^([\x20-\x7f]+)\0*$/) { | if ($val =~ /^([\x20-\x7f]+)\0*$/) { | |||
$val = $1; | $val = $1; | |||
} else { | } else { | |||
my $buff = $val; | my $buff = $val; | |||
$val = \$buff; | $val = \$buff; | |||
} | } | |||
if (not $$tagTbl{$tag} and $tag=~ /^[-_a-zA-Z0-9]+$/) { | if (not $$tagTbl{$tag} and $tag=~ /^[-_a-zA-Z0-9]+$/) { | |||
End of changes. 4 change blocks. | ||||
2 lines changed or deleted | 37 lines changed or added |