exiftool-vendored.pl 12.55.0 → 12.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/Changes +97 -4
- package/bin/MANIFEST +9 -0
- package/bin/META.json +1 -1
- package/bin/META.yml +1 -1
- package/bin/README +19 -19
- package/bin/arg_files/xmp2exif.args +4 -1
- package/bin/config_files/example.config +1 -0
- package/bin/config_files/rotate_regions.config +1 -1
- package/bin/exiftool +197 -122
- package/bin/fmt_files/kml.fmt +3 -0
- package/bin/fmt_files/kml_track.fmt +3 -0
- package/bin/lib/Image/ExifTool/AIFF.pm +2 -2
- package/bin/lib/Image/ExifTool/APE.pm +2 -2
- package/bin/lib/Image/ExifTool/BuildTagLookup.pm +25 -19
- package/bin/lib/Image/ExifTool/Canon.pm +33 -7
- package/bin/lib/Image/ExifTool/CanonRaw.pm +5 -1
- package/bin/lib/Image/ExifTool/DJI.pm +28 -2
- package/bin/lib/Image/ExifTool/Exif.pm +107 -20
- package/bin/lib/Image/ExifTool/FlashPix.pm +92 -9
- package/bin/lib/Image/ExifTool/FujiFilm.pm +9 -4
- package/bin/lib/Image/ExifTool/GPS.pm +7 -2
- package/bin/lib/Image/ExifTool/Geotag.pm +30 -7
- package/bin/lib/Image/ExifTool/InfiRay.pm +227 -0
- package/bin/lib/Image/ExifTool/JPEG.pm +53 -7
- package/bin/lib/Image/ExifTool/Jpeg2000.pm +5 -5
- package/bin/lib/Image/ExifTool/LIF.pm +10 -2
- package/bin/lib/Image/ExifTool/LNK.pm +5 -4
- package/bin/lib/Image/ExifTool/MIE.pm +3 -3
- package/bin/lib/Image/ExifTool/MPEG.pm +2 -2
- package/bin/lib/Image/ExifTool/MakerNotes.pm +3 -2
- package/bin/lib/Image/ExifTool/Minolta.pm +6 -7
- package/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -1
- package/bin/lib/Image/ExifTool/Nikon.pm +1199 -1325
- package/bin/lib/Image/ExifTool/NikonCustom.pm +2 -2
- package/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
- package/bin/lib/Image/ExifTool/Olympus.pm +88 -6
- package/bin/lib/Image/ExifTool/OpenEXR.pm +32 -15
- package/bin/lib/Image/ExifTool/PNG.pm +89 -3
- package/bin/lib/Image/ExifTool/PanasonicRaw.pm +27 -1
- package/bin/lib/Image/ExifTool/Pentax.pm +8 -5
- package/bin/lib/Image/ExifTool/PhaseOne.pm +14 -1
- package/bin/lib/Image/ExifTool/Photoshop.pm +38 -7
- package/bin/lib/Image/ExifTool/QuickTime.pm +44 -13
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +63 -20
- package/bin/lib/Image/ExifTool/README +19 -2
- package/bin/lib/Image/ExifTool/RIFF.pm +34 -13
- package/bin/lib/Image/ExifTool/Rawzor.pm +2 -2
- package/bin/lib/Image/ExifTool/Real.pm +2 -2
- package/bin/lib/Image/ExifTool/Ricoh.pm +2 -1
- package/bin/lib/Image/ExifTool/Sigma.pm +5 -4
- package/bin/lib/Image/ExifTool/SigmaRaw.pm +9 -3
- package/bin/lib/Image/ExifTool/Sony.pm +28 -1
- package/bin/lib/Image/ExifTool/TagLookup.pm +4691 -4624
- package/bin/lib/Image/ExifTool/TagNames.pod +511 -117
- package/bin/lib/Image/ExifTool/VCard.pm +19 -5
- package/bin/lib/Image/ExifTool/Validate.pm +5 -5
- package/bin/lib/Image/ExifTool/WriteExif.pl +42 -0
- package/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
- package/bin/lib/Image/ExifTool/Writer.pl +150 -36
- package/bin/lib/Image/ExifTool/XMP.pm +19 -4
- package/bin/lib/Image/ExifTool/XMP2.pl +2 -1
- package/bin/lib/Image/ExifTool.pm +248 -54
- package/bin/lib/Image/ExifTool.pod +94 -58
- package/bin/perl-Image-ExifTool.spec +18 -18
- package/bin/pp_build_exe.args +7 -6
- package/package.json +3 -3
|
@@ -29,7 +29,7 @@ use vars qw($VERSION);
|
|
|
29
29
|
use Image::ExifTool qw(:Public);
|
|
30
30
|
use Image::ExifTool::GPS;
|
|
31
31
|
|
|
32
|
-
$VERSION = '1.
|
|
32
|
+
$VERSION = '1.71';
|
|
33
33
|
|
|
34
34
|
sub JITTER() { return 2 } # maximum time jitter
|
|
35
35
|
|
|
@@ -92,7 +92,7 @@ my %isOrient = ( dir => 1, pitch => 1, roll => 1 ); # test for orientation key
|
|
|
92
92
|
# tags which may exist separately in some formats (eg. CSV)
|
|
93
93
|
my %sepTags = ( dir => 1, pitch => 1, roll => 1, track => 1, speed => 1 );
|
|
94
94
|
|
|
95
|
-
# conversion factors for GPSSpeed
|
|
95
|
+
# conversion factors for GPSSpeed (standard EXIF units only)
|
|
96
96
|
my %speedConv = (
|
|
97
97
|
'K' => 1.852, # km/h per knot
|
|
98
98
|
'M' => 1.150779448, # mph per knot
|
|
@@ -102,7 +102,14 @@ my %speedConv = (
|
|
|
102
102
|
'mph' => 'M',
|
|
103
103
|
);
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
# all recognized speed conversion factors (non-EXIF included)
|
|
106
|
+
my %otherConv = (
|
|
107
|
+
'km/h' => 1.852,
|
|
108
|
+
'mph' => 1.150779448,
|
|
109
|
+
'm/s' => 0.514444,
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
my $secPerDay = 24 * 3600; # a useful constant
|
|
106
113
|
|
|
107
114
|
#------------------------------------------------------------------------------
|
|
108
115
|
# Load GPS track log file
|
|
@@ -140,6 +147,7 @@ sub LoadTrackLog($$;$)
|
|
|
140
147
|
my ($raf, $from, $time, $isDate, $noDate, $noDateChanged, $lastDate, $dateFlarm);
|
|
141
148
|
my ($nmeaStart, $fixSecs, @fixTimes, $lastFix, %nmea, @csvHeadings, $sortFixes);
|
|
142
149
|
my ($canCut, $cutPDOP, $cutHDOP, $cutSats, $e0, $e1, @tmp, $trackFile, $trackTime);
|
|
150
|
+
my $scaleSpeed;
|
|
143
151
|
|
|
144
152
|
unless (eval { require Time::Local }) {
|
|
145
153
|
return 'Geotag feature requires Time::Local installed';
|
|
@@ -246,7 +254,9 @@ sub LoadTrackLog($$;$)
|
|
|
246
254
|
$format = 'CSV';
|
|
247
255
|
# convert recognized headings to our parameter names
|
|
248
256
|
foreach (@csvHeadings) {
|
|
257
|
+
my $head = $_;
|
|
249
258
|
my $param;
|
|
259
|
+
my $xtra = '';
|
|
250
260
|
s/^GPS ?//; # remove leading "GPS" to simplify regex patterns
|
|
251
261
|
if (/^Time ?\(seconds\)$/i) { # DJI
|
|
252
262
|
# DJI CSV log files have a column "Time(seconds)" which is seconds since
|
|
@@ -274,7 +284,16 @@ sub LoadTrackLog($$;$)
|
|
|
274
284
|
/ref$/i and $param .= 'ref';
|
|
275
285
|
} elsif (/^(Pos)?Alt/i) {
|
|
276
286
|
$param = 'alt';
|
|
277
|
-
} elsif (/^
|
|
287
|
+
} elsif (/^Speed/i) {
|
|
288
|
+
$param = 'speed';
|
|
289
|
+
# (recognize units in brackets)
|
|
290
|
+
if (m{\((mph|km/h|m/s)\)}) {
|
|
291
|
+
$scaleSpeed = $otherConv{$1};
|
|
292
|
+
$xtra = " in $1";
|
|
293
|
+
} else {
|
|
294
|
+
$xtra = ' in knots';
|
|
295
|
+
}
|
|
296
|
+
} elsif (/^(Angle)?(Heading|Track|Bearing)/i) {
|
|
278
297
|
$param = 'track';
|
|
279
298
|
} elsif (/^(Angle)?Pitch/i or /^Camera ?Elevation ?Angle/i) {
|
|
280
299
|
$param = 'pitch';
|
|
@@ -284,10 +303,10 @@ sub LoadTrackLog($$;$)
|
|
|
284
303
|
$param = 'dir';
|
|
285
304
|
}
|
|
286
305
|
if ($param) {
|
|
287
|
-
$et->VPrint(2, "CSV column '${
|
|
306
|
+
$et->VPrint(2, "CSV column '${head}' is $param$xtra\n");
|
|
288
307
|
$_ = $param;
|
|
289
308
|
} else {
|
|
290
|
-
$et->VPrint(2, "CSV column '${
|
|
309
|
+
$et->VPrint(2, "CSV column '${head}' ignored\n");
|
|
291
310
|
$_ = ''; # ignore this column
|
|
292
311
|
}
|
|
293
312
|
}
|
|
@@ -479,9 +498,11 @@ DoneFix: $isDate = 1;
|
|
|
479
498
|
my ($param, $date, $secs, %neg);
|
|
480
499
|
foreach $param (@csvHeadings) {
|
|
481
500
|
my $val = shift @vals;
|
|
482
|
-
last unless defined $val;
|
|
501
|
+
last unless defined $val and length($val);
|
|
483
502
|
next unless $param;
|
|
484
503
|
if ($param eq 'datetime') {
|
|
504
|
+
# (fix formats like "24.07.2016 13:47:30")
|
|
505
|
+
$val =~ s/^(\d{2})[^\d](\d{2})[^\d](\d{4}) /$3:$2:$1 /;
|
|
485
506
|
local $SIG{'__WARN__'} = sub { };
|
|
486
507
|
my $dateTime = $et->InverseDateTime($val);
|
|
487
508
|
if ($dateTime) {
|
|
@@ -510,6 +531,7 @@ DoneFix: $isDate = 1;
|
|
|
510
531
|
$date = $trackTime;
|
|
511
532
|
$secs = $val;
|
|
512
533
|
} else {
|
|
534
|
+
$val /= $scaleSpeed if $scaleSpeed and $param eq 'speed';
|
|
513
535
|
$$fix{$param} = $val;
|
|
514
536
|
$$has{$param} = 1 if $sepTags{$param};
|
|
515
537
|
}
|
|
@@ -1204,6 +1226,7 @@ Category: foreach $category (qw{pos track alt orient atemp}) {
|
|
|
1204
1226
|
@r = $et->SetNewValue(GPSTrackRef => (defined $$tFix{track} ? 'T' : undef), %opts);
|
|
1205
1227
|
my ($spd, $ref);
|
|
1206
1228
|
if (defined($spd = $$tFix{speed})) {
|
|
1229
|
+
# convert to specified units if necessary
|
|
1207
1230
|
$ref = $$et{OPTIONS}{GeoSpeedRef};
|
|
1208
1231
|
if ($ref and defined $speedConv{$ref}) {
|
|
1209
1232
|
$ref = $speedConv{$ref} if $speedConv{$speedConv{$ref}};
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
#------------------------------------------------------------------------------
|
|
2
|
+
# File: InfiRay.pm
|
|
3
|
+
#
|
|
4
|
+
# Description: InfiRay IJPEG thermal image metadata
|
|
5
|
+
#
|
|
6
|
+
# Revisions: 2023-02-08 - M. Del Sol Created
|
|
7
|
+
#
|
|
8
|
+
# References: 1) https://github.com/exiftool/exiftool/pull/184
|
|
9
|
+
#
|
|
10
|
+
# Notes: Information in this document has been mostly gathered by
|
|
11
|
+
# disassembling the P2 Pro Android app, version 1.0.8.230111.
|
|
12
|
+
#------------------------------------------------------------------------------
|
|
13
|
+
|
|
14
|
+
package Image::ExifTool::InfiRay;
|
|
15
|
+
|
|
16
|
+
use strict;
|
|
17
|
+
use vars qw($VERSION);
|
|
18
|
+
|
|
19
|
+
$VERSION = '1.00';
|
|
20
|
+
|
|
21
|
+
my %convFloat2 = ( PrintConv => 'sprintf("%.2f", $val)' );
|
|
22
|
+
my %convPercent = ( PrintConv => 'sprintf("%.1f %%", $val * 100)' );
|
|
23
|
+
my %convMeters = ( PrintConv => 'sprintf("%.2f m", $val)' );
|
|
24
|
+
my %convCelsius = ( PrintConv => 'sprintf("%.2f C", $val)' );
|
|
25
|
+
|
|
26
|
+
# InfiRay IJPEG version header, found in JPEGs APP2
|
|
27
|
+
%Image::ExifTool::InfiRay::Version = (
|
|
28
|
+
GROUPS => { 0 => 'APP2', 2 => 'Image' },
|
|
29
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
30
|
+
VARS => { NO_LOOKUP => 1 }, # omit tags from lookup
|
|
31
|
+
NOTES => q{
|
|
32
|
+
This table lists tags found in the InfiRay APP2 IJPEG version header, found
|
|
33
|
+
in JPEGs taken with the P2 Pro camera app.
|
|
34
|
+
},
|
|
35
|
+
0x00 => { Name => 'IJPEGVersion', Format => 'int8u[4]' },
|
|
36
|
+
# 0x04 => { Name => 'IJPEGSignature', Format => 'string[6]' }, # "IJPEG\0"
|
|
37
|
+
0x0c => { Name => 'IJPEGOrgType', Format => 'int8u' },
|
|
38
|
+
0x0d => { Name => 'IJPEGDispType', Format => 'int8u' },
|
|
39
|
+
0x0e => { Name => 'IJPEGRotate', Format => 'int8u' },
|
|
40
|
+
0x0f => { Name => 'IJPEGMirrorFlip', Format => 'int8u' },
|
|
41
|
+
0x10 => { Name => 'ImageColorSwitchable', Format => 'int8u' },
|
|
42
|
+
0x11 => { Name => 'ThermalColorPalette', Format => 'int16u' },
|
|
43
|
+
0x20 => { Name => 'IRDataSize', Format => 'int64u' },
|
|
44
|
+
0x28 => { Name => 'IRDataFormat', Format => 'int16u' },
|
|
45
|
+
0x2a => { Name => 'IRImageWidth', Format => 'int16u' },
|
|
46
|
+
0x2c => { Name => 'IRImageHeight', Format => 'int16u' },
|
|
47
|
+
0x2e => { Name => 'IRImageBpp', Format => 'int8u' },
|
|
48
|
+
0x30 => { Name => 'TempDataSize', Format => 'int64u' },
|
|
49
|
+
0x38 => { Name => 'TempDataFormat', Format => 'int16u' },
|
|
50
|
+
0x3a => { Name => 'TempImageWidth', Format => 'int16u' },
|
|
51
|
+
0x3c => { Name => 'TempImageHeight', Format => 'int16u' },
|
|
52
|
+
0x3e => { Name => 'TempImageBpp', Format => 'int8u' },
|
|
53
|
+
0x40 => { Name => 'VisibleDataSize', Format => 'int64u' },
|
|
54
|
+
0x48 => { Name => 'VisibleDataFormat', Format => 'int16u' },
|
|
55
|
+
0x4a => { Name => 'VisibleImageWidth', Format => 'int16u' },
|
|
56
|
+
0x4c => { Name => 'VisibleImageHeight', Format => 'int16u' },
|
|
57
|
+
0x4e => { Name => 'VisibleImageBpp', Format => 'int8u' },
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
# InfiRay IJPEG factory temperature, found in IJPEG's APP4 section
|
|
61
|
+
%Image::ExifTool::InfiRay::Factory = (
|
|
62
|
+
GROUPS => { 0 => 'APP4', 2 => 'Image' },
|
|
63
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
64
|
+
VARS => { NO_LOOKUP => 1 }, # omit tags from lookup
|
|
65
|
+
NOTES => q{
|
|
66
|
+
This table lists tags found in the InfiRay APP4 IJPEG camera factory
|
|
67
|
+
defaults and calibration data.
|
|
68
|
+
},
|
|
69
|
+
0x00 => { Name => 'IJPEGTempVersion', Format => 'int8u[4]' },
|
|
70
|
+
0x04 => { Name => 'FactDefEmissivity', Format => 'int8s' },
|
|
71
|
+
0x05 => { Name => 'FactDefTau', Format => 'int8s' },
|
|
72
|
+
0x06 => { Name => 'FactDefTa', Format => 'int16s' },
|
|
73
|
+
0x08 => { Name => 'FactDefTu', Format => 'int16s' },
|
|
74
|
+
0x0a => { Name => 'FactDefDist', Format => 'int16s' },
|
|
75
|
+
0x0c => { Name => 'FactDefA0', Format => 'int32s' },
|
|
76
|
+
0x10 => { Name => 'FactDefB0', Format => 'int32s' },
|
|
77
|
+
0x14 => { Name => 'FactDefA1', Format => 'int32s' },
|
|
78
|
+
0x18 => { Name => 'FactDefB1', Format => 'int32s' },
|
|
79
|
+
0x1c => { Name => 'FactDefP0', Format => 'int32s' },
|
|
80
|
+
0x20 => { Name => 'FactDefP1', Format => 'int32s' },
|
|
81
|
+
0x24 => { Name => 'FactDefP2', Format => 'int32s' },
|
|
82
|
+
0x44 => { Name => 'FactRelSensorTemp', Format => 'int16s' },
|
|
83
|
+
0x46 => { Name => 'FactRelShutterTemp', Format => 'int16s' },
|
|
84
|
+
0x48 => { Name => 'FactRelLensTemp', Format => 'int16s' },
|
|
85
|
+
0x64 => { Name => 'FactStatusGain', Format => 'int8s' },
|
|
86
|
+
0x65 => { Name => 'FactStatusEnvOK', Format => 'int8s' },
|
|
87
|
+
0x66 => { Name => 'FactStatusDistOK', Format => 'int8s' },
|
|
88
|
+
0x67 => { Name => 'FactStatusTempMap', Format => 'int8s' },
|
|
89
|
+
# Missing: ndist_table_len, ndist_table, nuc_t_table_len, nuc_t_table
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
# InfiRay IJPEG picture temperature information, found in IJPEG's APP5 section
|
|
93
|
+
%Image::ExifTool::InfiRay::Picture = (
|
|
94
|
+
GROUPS => { 0 => 'APP5', 2 => 'Image' },
|
|
95
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
96
|
+
VARS => { NO_LOOKUP => 1 }, # omit tags from lookup
|
|
97
|
+
NOTES => q{
|
|
98
|
+
This table lists tags found in the InfiRay APP5 IJPEG picture temperature
|
|
99
|
+
information.
|
|
100
|
+
},
|
|
101
|
+
0x00 => { Name => 'EnvironmentTemp', Format => 'float', %convCelsius },
|
|
102
|
+
0x04 => { Name => 'Distance', Format => 'float', %convMeters },
|
|
103
|
+
0x08 => { Name => 'Emissivity', Format => 'float', %convFloat2 },
|
|
104
|
+
0x0c => { Name => 'Humidity', Format => 'float', %convPercent },
|
|
105
|
+
0x10 => { Name => 'ReferenceTemp', Format => 'float', %convCelsius },
|
|
106
|
+
0x20 => { Name => 'TempUnit', Format => 'int8u' },
|
|
107
|
+
0x21 => { Name => 'ShowCenterTemp', Format => 'int8u' },
|
|
108
|
+
0x22 => { Name => 'ShowMaxTemp', Format => 'int8u' },
|
|
109
|
+
0x23 => { Name => 'ShowMinTemp', Format => 'int8u' },
|
|
110
|
+
0x24 => { Name => 'TempMeasureCount', Format => 'int16u' },
|
|
111
|
+
# TODO: process extra measurements list
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
# InfiRay IJPEG visual-infrared mixing mode, found in IJPEG's APP6 section
|
|
115
|
+
%Image::ExifTool::InfiRay::MixMode = (
|
|
116
|
+
GROUPS => { 0 => 'APP6', 2 => 'Image' },
|
|
117
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
118
|
+
VARS => { NO_LOOKUP => 1 }, # omit tags from lookup
|
|
119
|
+
NOTES => q{
|
|
120
|
+
This table lists tags found in the InfiRay APP6 IJPEG visual-infrared mixing
|
|
121
|
+
mode section.
|
|
122
|
+
},
|
|
123
|
+
0x00 => { Name => 'MixMode', Format => 'int8u' },
|
|
124
|
+
0x01 => { Name => 'FusionIntensity', Format => 'float', %convPercent },
|
|
125
|
+
0x05 => { Name => 'OffsetAdjustment', Format => 'float' },
|
|
126
|
+
0x09 => { Name => 'CorrectionAsix', Format => 'float[30]' },
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
# InfiRay IJPEG camera operation mode, found in IJPEG's APP7 section
|
|
130
|
+
#
|
|
131
|
+
# I do not know in what units these times are, or what do they represent.
|
|
132
|
+
%Image::ExifTool::InfiRay::OpMode = (
|
|
133
|
+
GROUPS => { 0 => 'APP7', 2 => 'Image' },
|
|
134
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
135
|
+
VARS => { NO_LOOKUP => 1 }, # omit tags from lookup
|
|
136
|
+
NOTES => q{
|
|
137
|
+
This table lists tags found in the InfiRay APP7 IJPEG camera operation mode
|
|
138
|
+
section.
|
|
139
|
+
},
|
|
140
|
+
0x00 => { Name => 'WorkingMode', Format => 'int8u' },
|
|
141
|
+
0x01 => { Name => 'IntegralTime', Format => 'int32u' },
|
|
142
|
+
0x05 => { Name => 'IntegratTimeHdr', Format => 'int32u' },
|
|
143
|
+
0x09 => { Name => 'GainStable', Format => 'int8u' },
|
|
144
|
+
0x0a => { Name => 'TempControlEnable', Format => 'int8u' },
|
|
145
|
+
0x0b => { Name => 'DeviceTemp', Format => 'float', %convCelsius },
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
# InfiRay IJPEG isothermal information, found in IJPEG's APP8 section
|
|
149
|
+
#
|
|
150
|
+
# I have genuinely no clue what is the meaning of any of this information, or
|
|
151
|
+
# what is it used for.
|
|
152
|
+
%Image::ExifTool::InfiRay::Isothermal = (
|
|
153
|
+
GROUPS => { 0 => 'APP8', 2 => 'Image' },
|
|
154
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
155
|
+
VARS => { NO_LOOKUP => 1 }, # omit tags from lookup
|
|
156
|
+
NOTES => q{
|
|
157
|
+
This table lists tags found in the InfiRay APP8 IJPEG picture isothermal
|
|
158
|
+
information.
|
|
159
|
+
},
|
|
160
|
+
0x00 => { Name => 'IsothermalMax', Format => 'float' },
|
|
161
|
+
0x04 => { Name => 'IsothermalMin', Format => 'float' },
|
|
162
|
+
0x08 => { Name => 'ChromaBarMax', Format => 'float' },
|
|
163
|
+
0x0c => { Name => 'ChromaBarMin', Format => 'float' },
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
# InfiRay IJPEG sensor information, found in IJPEG's APP9 section
|
|
167
|
+
%Image::ExifTool::InfiRay::Sensor = (
|
|
168
|
+
GROUPS => { 0 => 'APP9', 2 => 'Image' },
|
|
169
|
+
PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
|
|
170
|
+
VARS => { NO_LOOKUP => 1 }, # omit tags from lookup
|
|
171
|
+
NOTES => q{
|
|
172
|
+
This table lists tags found in the InfiRay APP9 IJPEG sensor information
|
|
173
|
+
chunk.
|
|
174
|
+
},
|
|
175
|
+
0x000 => { Name => 'IRSensorManufacturer', Format => 'string[12]' },
|
|
176
|
+
0x040 => { Name => 'IRSensorName', Format => 'string[12]' },
|
|
177
|
+
0x080 => { Name => 'IRSensorPartNumber', Format => 'string[32]' },
|
|
178
|
+
0x0c0 => { Name => 'IRSensorSerialNumber', Format => 'string[32]' },
|
|
179
|
+
0x100 => { Name => 'IRSensorFirmware', Format => 'string[12]' },
|
|
180
|
+
0x140 => { Name => 'IRSensorAperture', Format => 'float', %convFloat2 },
|
|
181
|
+
0x144 => { Name => 'IRFocalLength', Format => 'float', %convFloat2 },
|
|
182
|
+
0x180 => { Name => 'VisibleSensorManufacturer', Format => 'string[12]' },
|
|
183
|
+
0x1c0 => { Name => 'VisibleSensorName', Format => 'string[12]' },
|
|
184
|
+
0x200 => { Name => 'VisibleSensorPartNumber', Format => 'string[32]' },
|
|
185
|
+
0x240 => { Name => 'VisibleSensorSerialNumber', Format => 'string[32]' },
|
|
186
|
+
0x280 => { Name => 'VisibleSensorFirmware', Format => 'string[12]' },
|
|
187
|
+
0x2c0 => { Name => 'VisibleSensorAperture', Format => 'float' },
|
|
188
|
+
0x2c4 => { Name => 'VisibleFocalLength', Format => 'float' },
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
__END__
|
|
192
|
+
|
|
193
|
+
=head1 NAME
|
|
194
|
+
|
|
195
|
+
Image::ExifTool::InfiRay - InfiRay IJPEG thermal image metadata
|
|
196
|
+
|
|
197
|
+
=head1 SYNOPSIS
|
|
198
|
+
|
|
199
|
+
This module is loaded automatically by Image::ExifTool when required.
|
|
200
|
+
|
|
201
|
+
=head1 DESCRIPTION
|
|
202
|
+
|
|
203
|
+
This module contains definitions required by Image::ExifTool to interpret
|
|
204
|
+
metadata and thermal-related information of pictures saved by the InfiRay
|
|
205
|
+
IJPEG SDK, used in cameras such as the P2 Pro.
|
|
206
|
+
|
|
207
|
+
=head1 AUTHOR
|
|
208
|
+
|
|
209
|
+
Copyright 2003-2023, Marcos Del Sol Vives (marcos at orca.pet)
|
|
210
|
+
|
|
211
|
+
This library is free software; you can redistribute it and/or modify it
|
|
212
|
+
under the same terms as Perl itself.
|
|
213
|
+
|
|
214
|
+
=head1 REFERENCES
|
|
215
|
+
|
|
216
|
+
=over 4
|
|
217
|
+
|
|
218
|
+
=item L<https://github.com/exiftool/exiftool/pull/184>
|
|
219
|
+
|
|
220
|
+
=back
|
|
221
|
+
|
|
222
|
+
=head1 SEE ALSO
|
|
223
|
+
|
|
224
|
+
L<Image::ExifTool::TagNames/InfiRay Tags>,
|
|
225
|
+
L<Image::ExifTool(3pm)|Image::ExifTool>
|
|
226
|
+
|
|
227
|
+
=cut
|
|
@@ -11,7 +11,7 @@ use strict;
|
|
|
11
11
|
use vars qw($VERSION);
|
|
12
12
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
13
13
|
|
|
14
|
-
$VERSION = '1.
|
|
14
|
+
$VERSION = '1.35';
|
|
15
15
|
|
|
16
16
|
sub ProcessOcad($$$);
|
|
17
17
|
sub ProcessJPEG_HDR($$$);
|
|
@@ -83,6 +83,10 @@ sub ProcessJPEG_HDR($$$);
|
|
|
83
83
|
Name => 'MPF',
|
|
84
84
|
Condition => '$$valPt =~ /^MPF\0/',
|
|
85
85
|
SubDirectory => { TagTable => 'Image::ExifTool::MPF::Main' },
|
|
86
|
+
}, {
|
|
87
|
+
Name => 'InfiRayVersion',
|
|
88
|
+
Condition => '$$valPt =~ /^....IJPEG\0/s',
|
|
89
|
+
SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::Version' },
|
|
86
90
|
}, {
|
|
87
91
|
Name => 'PreviewImage',
|
|
88
92
|
Condition => '$$valPt =~ /^(|QVGA\0|BGTH)\xff\xd8\xff\xdb/',
|
|
@@ -106,6 +110,12 @@ sub ProcessJPEG_HDR($$$);
|
|
|
106
110
|
Notes => 'DJI raw thermal data',
|
|
107
111
|
Groups => { 0 => 'APP3', 1 => 'DJI', 2 => 'Image' },
|
|
108
112
|
Binary => 1,
|
|
113
|
+
}, {
|
|
114
|
+
Name => 'ImagingData', # (written by InfiRay models)
|
|
115
|
+
Condition => '$$self{HasIJPEG}',
|
|
116
|
+
Notes => 'InfiRay IR+thermal+visible data',
|
|
117
|
+
Groups => { 0 => 'APP3', 1 => 'InfiRay', 2 => 'Image' },
|
|
118
|
+
Binary => 1,
|
|
109
119
|
}, {
|
|
110
120
|
Name => 'PreviewImage', # (written by HP R837 and Samsung S1060)
|
|
111
121
|
Condition => '$$valPt =~ /^\xff\xd8\xff\xdb/',
|
|
@@ -120,9 +130,21 @@ sub ProcessJPEG_HDR($$$);
|
|
|
120
130
|
Condition => '$$valPt =~ /^FPXR\0/',
|
|
121
131
|
SubDirectory => { TagTable => 'Image::ExifTool::FlashPix::Main' },
|
|
122
132
|
}, {
|
|
123
|
-
Name => '
|
|
133
|
+
Name => 'InfiRayFactory',
|
|
134
|
+
Condition => '$$self{HasIJPEG}"',
|
|
135
|
+
SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::Factory' },
|
|
136
|
+
}, {
|
|
137
|
+
Name => 'ThermalParams', # (written by some DJI FLIR models)
|
|
124
138
|
Condition => '$$self{Make} eq "DJI" and $$valPt =~ /^\xaa\x55\x12\x06/',
|
|
125
139
|
SubDirectory => { TagTable => 'Image::ExifTool::DJI::ThermalParams' },
|
|
140
|
+
}, {
|
|
141
|
+
Name => 'ThermalParams2', # (written by M3T)
|
|
142
|
+
Condition => '$$self{Make} eq "DJI" and $$valPt =~ /^(.{32})?.{32}\x2c\x01\x20\0/s',
|
|
143
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::ThermalParams2' },
|
|
144
|
+
}, {
|
|
145
|
+
Name => 'ThermalParams3', # (written by M30T)
|
|
146
|
+
Condition => '$$self{Make} eq "DJI" and $$valPt =~ /^.{32}\xaa\x55\x38\0/s',
|
|
147
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::ThermalParams3' },
|
|
126
148
|
}, {
|
|
127
149
|
Name => 'PreviewImage', # (eg. Samsung S1060)
|
|
128
150
|
Notes => 'continued from APP3',
|
|
@@ -135,6 +157,10 @@ sub ProcessJPEG_HDR($$$);
|
|
|
135
157
|
Name => 'SamsungUniqueID',
|
|
136
158
|
Condition => '$$valPt =~ /ssuniqueid\0/',
|
|
137
159
|
SubDirectory => { TagTable => 'Image::ExifTool::Samsung::APP5' },
|
|
160
|
+
}, {
|
|
161
|
+
Name => 'InfiRayPicture',
|
|
162
|
+
Condition => '$$self{HasIJPEG}',
|
|
163
|
+
SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::Picture' },
|
|
138
164
|
}, {
|
|
139
165
|
Name => 'ThermalCalibration', # (written by DJI FLIR models)
|
|
140
166
|
Condition => '$$self{Make} eq "DJI"',
|
|
@@ -161,13 +187,17 @@ sub ProcessJPEG_HDR($$$);
|
|
|
161
187
|
Name => 'GoPro',
|
|
162
188
|
Condition => '$$valPt =~ /^GoPro\0/',
|
|
163
189
|
SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' },
|
|
164
|
-
|
|
190
|
+
}, {
|
|
191
|
+
Name => 'InfiRayMixMode',
|
|
192
|
+
Condition => '$$self{HasIJPEG}',
|
|
193
|
+
SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::MixMode' },
|
|
165
194
|
}, {
|
|
166
195
|
Name => 'DJI_DTAT', # (written by ZH20T)
|
|
167
196
|
Condition => '$$valPt =~ /^DTAT\0\0.\{/s',
|
|
168
197
|
Groups => { 0 => 'APP6', 1 => 'DJI' },
|
|
169
198
|
Notes => 'DJI Thermal Analysis Tool record',
|
|
170
199
|
ValueConv => 'substr($val,7)',
|
|
200
|
+
# also seen Motorola APP6 "MMIMETA\0", with sub-types: AL3A,ALED,MMI0,MOTD,QC3A
|
|
171
201
|
}],
|
|
172
202
|
APP7 => [{
|
|
173
203
|
Name => 'Pentax',
|
|
@@ -181,17 +211,33 @@ sub ProcessJPEG_HDR($$$);
|
|
|
181
211
|
Name => 'Qualcomm',
|
|
182
212
|
Condition => '$$valPt =~ /^\x1aQualcomm Camera Attributes/',
|
|
183
213
|
SubDirectory => { TagTable => 'Image::ExifTool::Qualcomm::Main' },
|
|
214
|
+
}, {
|
|
215
|
+
Name => 'InfiRayOpMode',
|
|
216
|
+
Condition => '$$self{HasIJPEG}',
|
|
217
|
+
SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::OpMode' },
|
|
218
|
+
}, {
|
|
219
|
+
Name => 'DJI-DBG',
|
|
220
|
+
Condition => '$$valPt =~ /^DJI-DBG\0/',
|
|
221
|
+
SubDirectory => { TagTable => 'Image::ExifTool::DJI::Info' },
|
|
184
222
|
}],
|
|
185
|
-
APP8 => {
|
|
223
|
+
APP8 => [{
|
|
186
224
|
Name => 'SPIFF',
|
|
187
225
|
Condition => '$$valPt =~ /^SPIFF\0/',
|
|
188
226
|
SubDirectory => { TagTable => 'Image::ExifTool::JPEG::SPIFF' },
|
|
189
|
-
|
|
190
|
-
|
|
227
|
+
}, {
|
|
228
|
+
Name => 'InfiRayIsothermal',
|
|
229
|
+
Condition => '$$self{HasIJPEG}',
|
|
230
|
+
SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::Isothermal' },
|
|
231
|
+
}],
|
|
232
|
+
APP9 => [{
|
|
191
233
|
Name => 'MediaJukebox',
|
|
192
234
|
Condition => '$$valPt =~ /^Media Jukebox\0/',
|
|
193
235
|
SubDirectory => { TagTable => 'Image::ExifTool::JPEG::MediaJukebox' },
|
|
194
|
-
|
|
236
|
+
}, {
|
|
237
|
+
Name => 'InfiRaySensor',
|
|
238
|
+
Condition => '$$self{HasIJPEG}',
|
|
239
|
+
SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::Sensor' },
|
|
240
|
+
}],
|
|
195
241
|
APP10 => {
|
|
196
242
|
Name => 'Comment',
|
|
197
243
|
Condition => '$$valPt =~ /^UNICODE\0/',
|
|
@@ -59,7 +59,7 @@ my %jp2Map = (
|
|
|
59
59
|
# map of where information is written in a JXL image
|
|
60
60
|
my %jxlMap = (
|
|
61
61
|
IFD0 => 'Exif',
|
|
62
|
-
XMP => '
|
|
62
|
+
XMP => 'xml ',
|
|
63
63
|
'Exif' => 'JP2',
|
|
64
64
|
IFD1 => 'IFD0',
|
|
65
65
|
EXIF => 'IFD0', # to write EXIF as a block
|
|
@@ -827,8 +827,8 @@ sub CreateNewBoxes($$)
|
|
|
827
827
|
# add UUID boxes (and/or JXL Exif/XML boxes)
|
|
828
828
|
foreach $dirName (sort keys %$addDirs) {
|
|
829
829
|
# handle JPEG XL XMP and EXIF
|
|
830
|
-
if ($dirName eq '
|
|
831
|
-
my ($tag, $dir) = $dirName eq '
|
|
830
|
+
if ($dirName eq 'xml ' or $dirName eq 'Exif') {
|
|
831
|
+
my ($tag, $dir) = $dirName eq 'xml ' ? ('xml ', 'XMP') : ('Exif', 'EXIF');
|
|
832
832
|
my $tagInfo = $Image::ExifTool::Jpeg2000::Main{$tag};
|
|
833
833
|
$tagInfo = $$tagInfo[1] if ref $tagInfo eq 'ARRAY'; # (hack for stupid JXL XMP)
|
|
834
834
|
my $subdir = $$tagInfo{SubDirectory};
|
|
@@ -1123,8 +1123,8 @@ sub ProcessJpeg2000Box($$$)
|
|
|
1123
1123
|
my $subTable = GetTagTable($$subdir{TagTable}) || $tagTablePtr;
|
|
1124
1124
|
if ($outfile) {
|
|
1125
1125
|
# remove this directory from our create list
|
|
1126
|
-
delete $$et{AddJp2Dirs}{$$tagInfo{Name}}; # (eg. 'EXIF')
|
|
1127
|
-
delete $$et{AddJp2Dirs}{$boxID}; # (eg. 'Exif')
|
|
1126
|
+
delete $$et{AddJp2Dirs}{$$tagInfo{Name}}; # (eg. 'EXIF' or 'XMP')
|
|
1127
|
+
delete $$et{AddJp2Dirs}{$boxID}; # (eg. 'Exif' or 'xml ')
|
|
1128
1128
|
my $newdir;
|
|
1129
1129
|
# only edit writable UUID, Exif and jp2h boxes
|
|
1130
1130
|
if ($uuid or $boxID eq 'Exif' or ($boxID eq 'xml ' and $$et{IsJXL}) or
|
|
@@ -13,7 +13,7 @@ use vars qw($VERSION);
|
|
|
13
13
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
14
14
|
use Image::ExifTool::XMP;
|
|
15
15
|
|
|
16
|
-
$VERSION = '1.
|
|
16
|
+
$VERSION = '1.01';
|
|
17
17
|
|
|
18
18
|
%Image::ExifTool::LIF::Main = (
|
|
19
19
|
GROUPS => { 0 => 'XML', 1 => 'XML', 2 => 'Image' },
|
|
@@ -30,7 +30,15 @@ $VERSION = '1.00';
|
|
|
30
30
|
my $unixTimeZero = 134774 * 24 * 3600;
|
|
31
31
|
my @vals = split ' ', $val;
|
|
32
32
|
foreach (@vals) {
|
|
33
|
-
|
|
33
|
+
if (/[^0-9a-f]/i) {
|
|
34
|
+
$_ = '0000:00:00 00:00:00';
|
|
35
|
+
} elsif (length $_ > 8) {
|
|
36
|
+
my $lo = hex substr($_, -8);
|
|
37
|
+
my $hi = hex substr($_, 0, -8);
|
|
38
|
+
$_ = 1e-7 * ($hi * 4294967296 + $lo);
|
|
39
|
+
} else {
|
|
40
|
+
$_ = 1e-7 * hex($_);
|
|
41
|
+
}
|
|
34
42
|
# shift from Jan 1, 1601 to Jan 1, 1970
|
|
35
43
|
$_ = Image::ExifTool::ConvertUnixTime($_ - $unixTimeZero);
|
|
36
44
|
}
|
|
@@ -15,7 +15,7 @@ use strict;
|
|
|
15
15
|
use vars qw($VERSION);
|
|
16
16
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
17
17
|
|
|
18
|
-
$VERSION = '1.
|
|
18
|
+
$VERSION = '1.09';
|
|
19
19
|
|
|
20
20
|
sub ProcessItemID($$$);
|
|
21
21
|
sub ProcessLinkInfo($$$);
|
|
@@ -507,7 +507,7 @@ sub ProcessLinkInfo($$$)
|
|
|
507
507
|
if ($lif & 0x01) {
|
|
508
508
|
# read Volume ID
|
|
509
509
|
$off = Get32u($dataPt, 0x0c);
|
|
510
|
-
if ($off + 0x20 <= $dataLen) {
|
|
510
|
+
if ($off and $off + 0x20 <= $dataLen) {
|
|
511
511
|
# my $len = Get32u($dataPt, $off);
|
|
512
512
|
$et->HandleTag($tagTablePtr, 'DriveType', undef, %opts, Start=>$off+4);
|
|
513
513
|
$et->HandleTag($tagTablePtr, 'DriveSerialNumber', undef, %opts, Start=>$off+8);
|
|
@@ -545,6 +545,7 @@ sub ProcessLinkInfo($$$)
|
|
|
545
545
|
$off = Get32u($dataPt, 0x14);
|
|
546
546
|
if ($off and $off + 0x14 <= $dataLen) {
|
|
547
547
|
my $siz = Get32u($dataPt, $off);
|
|
548
|
+
return 0 if $off + $siz > $dataLen;
|
|
548
549
|
$pos = Get32u($dataPt, $off + 0x08);
|
|
549
550
|
if ($pos > 0x14 and $siz >= 0x18) {
|
|
550
551
|
$pos = Get32u($dataPt, $off + 0x14);
|
|
@@ -552,7 +553,7 @@ sub ProcessLinkInfo($$$)
|
|
|
552
553
|
} else {
|
|
553
554
|
undef $unicode;
|
|
554
555
|
}
|
|
555
|
-
$val = GetString($dataPt, $pos, $unicode);
|
|
556
|
+
$val = GetString($dataPt, $off + $pos, $unicode);
|
|
556
557
|
if (defined $val) {
|
|
557
558
|
$size = length $val;
|
|
558
559
|
$val = $et->Decode($val, 'UCS2') if $unicode;
|
|
@@ -567,7 +568,7 @@ sub ProcessLinkInfo($$$)
|
|
|
567
568
|
} else {
|
|
568
569
|
undef $unicode;
|
|
569
570
|
}
|
|
570
|
-
$val = GetString($dataPt, $pos, $unicode);
|
|
571
|
+
$val = GetString($dataPt, $off + $pos, $unicode);
|
|
571
572
|
if (defined $val) {
|
|
572
573
|
$size = length $val;
|
|
573
574
|
$val = $et->Decode($val, 'UCS2') if $unicode;
|
|
@@ -14,7 +14,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
|
14
14
|
use Image::ExifTool::Exif;
|
|
15
15
|
use Image::ExifTool::GPS;
|
|
16
16
|
|
|
17
|
-
$VERSION = '1.
|
|
17
|
+
$VERSION = '1.51';
|
|
18
18
|
|
|
19
19
|
sub ProcessMIE($$);
|
|
20
20
|
sub ProcessMIEGroup($$$);
|
|
@@ -391,7 +391,7 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
|
|
|
391
391
|
-30", "-40.5", "40 30 0.00 S"
|
|
392
392
|
},
|
|
393
393
|
ValueConv => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
|
|
394
|
-
ValueConvInv => 'Image::ExifTool::GPS::ToDMS($self, $val,
|
|
394
|
+
ValueConvInv => 'Image::ExifTool::GPS::ToDMS($self, $val, 3)',
|
|
395
395
|
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
|
|
396
396
|
PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1, "lat")',
|
|
397
397
|
},
|
|
@@ -404,7 +404,7 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
|
|
|
404
404
|
negative, but may be entered as positive numbers with a trailing 'W'
|
|
405
405
|
},
|
|
406
406
|
ValueConv => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
|
|
407
|
-
ValueConvInv => 'Image::ExifTool::GPS::ToDMS($self, $val,
|
|
407
|
+
ValueConvInv => 'Image::ExifTool::GPS::ToDMS($self, $val, 3)',
|
|
408
408
|
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
|
|
409
409
|
PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1, "lon")',
|
|
410
410
|
},
|
|
@@ -18,7 +18,7 @@ use strict;
|
|
|
18
18
|
use vars qw($VERSION);
|
|
19
19
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
20
20
|
|
|
21
|
-
$VERSION = '1.
|
|
21
|
+
$VERSION = '1.17';
|
|
22
22
|
|
|
23
23
|
%Image::ExifTool::MPEG::Audio = (
|
|
24
24
|
GROUPS => { 2 => 'Audio' },
|
|
@@ -599,7 +599,7 @@ sub ProcessMPEGVideo($$)
|
|
|
599
599
|
return 0;
|
|
600
600
|
}
|
|
601
601
|
# set file type if not done already
|
|
602
|
-
$et->SetFileType('MPEG') unless $$et{
|
|
602
|
+
$et->SetFileType('MPEG') unless $$et{FileType};
|
|
603
603
|
|
|
604
604
|
my $tagTablePtr = GetTagTable('Image::ExifTool::MPEG::Video');
|
|
605
605
|
ProcessFrameHeader($et, $tagTablePtr, $w1, $w2);
|
|
@@ -21,7 +21,7 @@ sub ProcessKodakPatch($$$);
|
|
|
21
21
|
sub WriteUnknownOrPreview($$$);
|
|
22
22
|
sub FixLeicaBase($$;$);
|
|
23
23
|
|
|
24
|
-
$VERSION = '2.
|
|
24
|
+
$VERSION = '2.14';
|
|
25
25
|
|
|
26
26
|
my $debug; # set to 1 to enable debugging code
|
|
27
27
|
|
|
@@ -92,11 +92,12 @@ my $debug; # set to 1 to enable debugging code
|
|
|
92
92
|
{
|
|
93
93
|
Name => 'MakerNoteDJIInfo',
|
|
94
94
|
Condition => '$$valPt =~ /^\[ae_dbg_info:/',
|
|
95
|
+
NotIFD => 1,
|
|
95
96
|
SubDirectory => { TagTable => 'Image::ExifTool::DJI::Info' },
|
|
96
97
|
},
|
|
97
98
|
{
|
|
98
99
|
Name => 'MakerNoteDJI',
|
|
99
|
-
Condition => '$$self{Make} eq "DJI" and $$valPt !~
|
|
100
|
+
Condition => '$$self{Make} eq "DJI" and $$valPt !~ /^(...\@AMBA|DJI)/s',
|
|
100
101
|
SubDirectory => {
|
|
101
102
|
TagTable => 'Image::ExifTool::DJI::Main',
|
|
102
103
|
Start => '$valuePtr',
|