exiftool_vendored 12.55.0 → 12.57.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/Changes +38 -1
- data/bin/MANIFEST +5 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +19 -19
- data/bin/arg_files/xmp2exif.args +4 -1
- data/bin/exiftool +97 -53
- data/bin/fmt_files/kml.fmt +3 -0
- data/bin/fmt_files/kml_track.fmt +3 -0
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +13 -6
- data/bin/lib/Image/ExifTool/Canon.pm +8 -2
- data/bin/lib/Image/ExifTool/Exif.pm +31 -2
- data/bin/lib/Image/ExifTool/FlashPix.pm +73 -8
- data/bin/lib/Image/ExifTool/FujiFilm.pm +2 -1
- data/bin/lib/Image/ExifTool/GPS.pm +7 -2
- data/bin/lib/Image/ExifTool/InfiRay.pm +227 -0
- data/bin/lib/Image/ExifTool/JPEG.pm +40 -6
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +5 -5
- data/bin/lib/Image/ExifTool/MIE.pm +3 -3
- data/bin/lib/Image/ExifTool/Nikon.pm +862 -1264
- data/bin/lib/Image/ExifTool/NikonCustom.pm +2 -2
- data/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
- data/bin/lib/Image/ExifTool/Olympus.pm +3 -1
- data/bin/lib/Image/ExifTool/OpenEXR.pm +32 -15
- data/bin/lib/Image/ExifTool/PNG.pm +80 -2
- data/bin/lib/Image/ExifTool/Photoshop.pm +36 -5
- data/bin/lib/Image/ExifTool/QuickTime.pm +18 -2
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +25 -14
- data/bin/lib/Image/ExifTool/README +11 -2
- data/bin/lib/Image/ExifTool/Real.pm +2 -2
- data/bin/lib/Image/ExifTool/Sigma.pm +2 -1
- data/bin/lib/Image/ExifTool/Sony.pm +5 -1
- data/bin/lib/Image/ExifTool/TagLookup.pm +4667 -4624
- data/bin/lib/Image/ExifTool/TagNames.pod +400 -90
- data/bin/lib/Image/ExifTool/VCard.pm +19 -5
- data/bin/lib/Image/ExifTool/Writer.pl +36 -16
- data/bin/lib/Image/ExifTool.pm +92 -35
- data/bin/lib/Image/ExifTool.pod +54 -53
- data/bin/perl-Image-ExifTool.spec +18 -18
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +3 -2
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
|
|
88
88
|
sub ProcessExifInfo($$$);
|
89
89
|
sub SwapWords($);
|
90
90
|
|
91
|
-
$VERSION = '4.
|
91
|
+
$VERSION = '4.65';
|
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)
|
@@ -621,8 +621,10 @@ $VERSION = '4.64';
|
|
621
621
|
'61182.41' => 'Canon RF 1200mm F8L IS USM + RF1.4x', #42
|
622
622
|
'61182.42' => 'Canon RF 1200mm F8L IS USM + RF2x', #42
|
623
623
|
'61182.43' => 'Canon RF 135mm F1.8 L IS USM', #42
|
624
|
+
'61182.44' => 'Canon RF 24-50mm F4.5-6.3 IS STM', #42
|
625
|
+
'61182.45' => 'Canon RF-S 55-210mm F5-7.1 IS STM', #42
|
624
626
|
# we need the RFLensType values for the following...
|
625
|
-
'61182.
|
627
|
+
'61182.46' => 'Canon RF 5.2mm F2.8L Dual Fisheye 3D VR', #PH (NC)
|
626
628
|
65535 => 'n/a',
|
627
629
|
);
|
628
630
|
|
@@ -983,7 +985,9 @@ $VERSION = '4.64';
|
|
983
985
|
0x80000465 => 'EOS R10', #42
|
984
986
|
0x80000467 => 'PowerShot ZOOM',
|
985
987
|
0x80000468 => 'EOS M50 Mark II / Kiss M2', #IB
|
988
|
+
0x80000480 => 'EOS R50', #42
|
986
989
|
0x80000481 => 'EOS R6 Mark II', #42
|
990
|
+
0x80000487 => 'EOS R8', #42
|
987
991
|
0x80000520 => 'EOS D2000C', #IB
|
988
992
|
0x80000560 => 'EOS D6000C', #PH (guess)
|
989
993
|
);
|
@@ -6840,6 +6844,8 @@ my %ciMaxFocal = (
|
|
6840
6844
|
300 => 'Canon RF 1200mm F8L IS USM + RF2x', #42
|
6841
6845
|
302 => 'Canon RF 15-30mm F4.5-6.3 IS STM', #42
|
6842
6846
|
303 => 'Canon RF 135mm F1.8 L IS USM', #42
|
6847
|
+
304 => 'Canon RF 24-50mm F4.5-6.3 IS STM', #42
|
6848
|
+
305 => 'Canon RF-S 55-210mm F5-7.1 IS STM', #42
|
6843
6849
|
# Note: add new RF lenses to %canonLensTypes with ID 61182
|
6844
6850
|
},
|
6845
6851
|
},
|
@@ -56,7 +56,7 @@ use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat
|
|
56
56
|
use Image::ExifTool qw(:DataAccess :Utils);
|
57
57
|
use Image::ExifTool::MakerNotes;
|
58
58
|
|
59
|
-
$VERSION = '4.
|
59
|
+
$VERSION = '4.43';
|
60
60
|
|
61
61
|
sub ProcessExif($$$);
|
62
62
|
sub WriteExif($$$);
|
@@ -578,6 +578,13 @@ my %opcodeInfo = (
|
|
578
578
|
ValueConv => '$val=join(" ",unpack("N*",pack("V*",split(" ",$val))));\$val',
|
579
579
|
ByteOrder => 'LittleEndian',
|
580
580
|
},
|
581
|
+
{
|
582
|
+
Condition => '$$self{Compression} and $$self{Compression} eq "34892"', # DNG Lossy JPEG
|
583
|
+
Name => 'OtherImageStart',
|
584
|
+
IsOffset => 1,
|
585
|
+
OffsetPair => 0x117, # point to associated byte counts
|
586
|
+
DataTag => 'OtherImage',
|
587
|
+
},
|
581
588
|
{
|
582
589
|
# (APP1 IFD2 is for Leica JPEG preview)
|
583
590
|
Condition => q[
|
@@ -664,6 +671,12 @@ my %opcodeInfo = (
|
|
664
671
|
ValueConv => '$val=join(" ",unpack("N*",pack("V*",split(" ",$val))));\$val',
|
665
672
|
ByteOrder => 'LittleEndian',
|
666
673
|
},
|
674
|
+
{
|
675
|
+
Condition => '$$self{Compression} and $$self{Compression} eq "34892"', # DNG Lossy JPEG
|
676
|
+
Name => 'OtherImageLength',
|
677
|
+
OffsetPair => 0x111, # point to associated offset
|
678
|
+
DataTag => 'OtherImage',
|
679
|
+
},
|
667
680
|
{
|
668
681
|
# (APP1 IFD2 is for Leica JPEG preview)
|
669
682
|
Condition => q[
|
@@ -4706,12 +4719,28 @@ my %subSecConv = (
|
|
4706
4719
|
0 => 'OtherImageStart',
|
4707
4720
|
1 => 'OtherImageLength',
|
4708
4721
|
},
|
4722
|
+
Desire => {
|
4723
|
+
2 => 'OtherImageStart (1)',
|
4724
|
+
3 => 'OtherImageLength (1)',
|
4725
|
+
},
|
4709
4726
|
Notes => q{
|
4710
4727
|
this tag is writable, and may be used to update existing embedded images,
|
4711
4728
|
but not create or delete them
|
4712
4729
|
},
|
4713
|
-
# retrieve
|
4730
|
+
# retrieve all other images
|
4714
4731
|
RawConv => q{
|
4732
|
+
if ($val[2] and $val[3]) {
|
4733
|
+
my $i = 1;
|
4734
|
+
for (;;) {
|
4735
|
+
my %val = ( 0 => $$val{2}, 1 => $$val{3} );
|
4736
|
+
$self->FoundTag($tagInfo, \%val);
|
4737
|
+
++$i;
|
4738
|
+
$$val{2} = "$$val{0} ($i)";
|
4739
|
+
last unless defined $$self{VALUE}{$$val{2}};
|
4740
|
+
$$val{3} = "$$val{1} ($i)";
|
4741
|
+
last unless defined $$self{VALUE}{$$val{3}};
|
4742
|
+
}
|
4743
|
+
}
|
4715
4744
|
@grps = $self->GetGroup($$val{0});
|
4716
4745
|
Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"OtherImage");
|
4717
4746
|
},
|
@@ -21,7 +21,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
21
21
|
use Image::ExifTool::Exif;
|
22
22
|
use Image::ExifTool::ASF; # for GetGUID()
|
23
23
|
|
24
|
-
$VERSION = '1.
|
24
|
+
$VERSION = '1.42';
|
25
25
|
|
26
26
|
sub ProcessFPX($$);
|
27
27
|
sub ProcessFPXR($$$);
|
@@ -318,6 +318,10 @@ my %fpxFileType = (
|
|
318
318
|
unrecognized Windows Compound Binary file as a FlashPix (FPX) file. See
|
319
319
|
L<http://graphcomp.com/info/specs/livepicture/fpx.pdf> for the FlashPix
|
320
320
|
specification.
|
321
|
+
|
322
|
+
Note that Microsoft is not consistent with the time zone used for some
|
323
|
+
date/time tags, and it may be either UTC or local time depending on the
|
324
|
+
software used to create the file.
|
321
325
|
},
|
322
326
|
"\x05SummaryInformation" => {
|
323
327
|
Name => 'SummaryInfo',
|
@@ -483,10 +487,18 @@ my %fpxFileType = (
|
|
483
487
|
},
|
484
488
|
IeImg => {
|
485
489
|
Name => 'EmbeddedImage',
|
486
|
-
Notes =>
|
490
|
+
Notes => q{
|
491
|
+
embedded images in Scene7 vignette VNT files. EmbeddedImageRectangle is
|
492
|
+
generated for applicable images, and may be associated with the
|
493
|
+
corresponding EmbeddedImage via the family 3 group name
|
494
|
+
},
|
487
495
|
Groups => { 2 => 'Preview' },
|
488
496
|
Binary => 1,
|
489
497
|
},
|
498
|
+
IeImg_rect => { # (not a real tag -- extracted from Contents of VNT file)
|
499
|
+
Name => 'EmbeddedImageRectangle',
|
500
|
+
Hidden => 1,
|
501
|
+
},
|
490
502
|
);
|
491
503
|
|
492
504
|
# Summary Information properties
|
@@ -1059,6 +1071,7 @@ my %fpxFileType = (
|
|
1059
1071
|
%Image::ExifTool::FlashPix::Contents = (
|
1060
1072
|
PROCESS_PROC => \&ProcessProperties,
|
1061
1073
|
GROUPS => { 2 => 'Image' },
|
1074
|
+
OriginalFileName => { Name => 'OriginalFileName', Hidden => 1 }, # (not a real tag -- extracted from Contents of VNT file)
|
1062
1075
|
);
|
1063
1076
|
|
1064
1077
|
# CompObj tags
|
@@ -1537,11 +1550,43 @@ sub ProcessContents($$$)
|
|
1537
1550
|
my $isFLA;
|
1538
1551
|
|
1539
1552
|
# all of my FLA samples contain "Contents" data, and no other FPX-like samples have
|
1540
|
-
# this, but check the data for a familiar pattern to be
|
1541
|
-
# Contents of all of my FLA samples start with two bytes
|
1542
|
-
# then 0x01) followed by a number of zero bytes
|
1543
|
-
# somehow to the value of the first byte),
|
1544
|
-
|
1553
|
+
# this (except Scene7 VNT viles), but check the data for a familiar pattern to be
|
1554
|
+
# sure this is FLA: the Contents of all of my FLA samples start with two bytes
|
1555
|
+
# (0x29,0x38,0x3f,0x43 or 0x47, then 0x01) followed by a number of zero bytes
|
1556
|
+
# (from 0x18 to 0x26 of them, related somehow to the value of the first byte),
|
1557
|
+
# followed by the string "DocumentPage"
|
1558
|
+
if ($$dataPt =~ /^..\0+\xff\xff\x01\0\x0d\0CDocumentPage/s) {
|
1559
|
+
$isFLA = 1;
|
1560
|
+
} elsif ($$dataPt =~ /^\0{4}.(.{1,255})\x60\xa1\x3f\x22\0{5}(.{8})/sg) {
|
1561
|
+
# this looks like a VNT file
|
1562
|
+
$et->OverrideFileType('VNT', 'image/x-vignette');
|
1563
|
+
# hack to set proper file description (extension is the same for V-Note files)
|
1564
|
+
$Image::ExifTool::static_vars{OverrideFileDescription}{VNT} = 'Scene7 Vignette',
|
1565
|
+
my $name = $1;
|
1566
|
+
my ($w, $h) = unpack('V2',$2);
|
1567
|
+
$et->FoundTag(ImageWidth => $w);
|
1568
|
+
$et->FoundTag(ImageHeight => $h);
|
1569
|
+
$et->HandleTag($tagTablePtr, OriginalFileName => $name);
|
1570
|
+
if ($$dataPt =~ /\G\x01\0{4}(.{12})/sg) {
|
1571
|
+
# (first 4 bytes seem to be number of objects, next 4 bytes are zero, then ICC size)
|
1572
|
+
my $size = unpack('x8V', $1);
|
1573
|
+
# (not useful?) $et->FoundTag(NumObjects => $num);
|
1574
|
+
if ($size and pos($$dataPt) + $size < length($$dataPt)) {
|
1575
|
+
my $dat = substr($$dataPt, pos($$dataPt), $size);
|
1576
|
+
$et->FoundTag(ICC_Profile => $dat);
|
1577
|
+
pos($$dataPt) += $size;
|
1578
|
+
}
|
1579
|
+
$$et{IeImg_lkup} = { };
|
1580
|
+
# - the byte after TargetRole1 is 0x0d or 0x11 for separate images in my samples,
|
1581
|
+
# and 0x1c or 0x23 for inline masks
|
1582
|
+
while ($$dataPt =~ /\x0bTargetRole1.\x80\0\0\x01.{4}(.{24})/sg) {
|
1583
|
+
my ($index, @coords) = unpack('Vx4V4', $1);
|
1584
|
+
next if $index == 0xffffffff;
|
1585
|
+
$$et{IeImg_lkup}{$index} and $et->WarnOnce('Duplicate image index');
|
1586
|
+
$$et{IeImg_lkup}{$index} = "@coords";
|
1587
|
+
}
|
1588
|
+
}
|
1589
|
+
}
|
1545
1590
|
|
1546
1591
|
# do a brute-force scan of the "Contents" for UTF-16 XMP
|
1547
1592
|
# (this may always be little-endian, but allow for either endianness)
|
@@ -2337,8 +2382,24 @@ sub ProcessFPX($$)
|
|
2337
2382
|
);
|
2338
2383
|
my $subTablePtr = GetTagTable($$subdir{TagTable});
|
2339
2384
|
$et->ProcessDirectory(\%dirInfo, $subTablePtr, $$subdir{ProcessProc});
|
2385
|
+
} elsif (defined $size and $size > length($buff)) {
|
2386
|
+
$et->WarnOnce('Truncated object');
|
2340
2387
|
} else {
|
2341
|
-
$
|
2388
|
+
$buff = substr($buff, 0, $size) if defined $size and $size < length($buff);
|
2389
|
+
if ($tag =~ /^IeImg_0*(\d+)$/) {
|
2390
|
+
# set document number for embedded images and their positions (if available, VNT files)
|
2391
|
+
my $num = $1;
|
2392
|
+
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
2393
|
+
$et->FoundTag($tagInfo, $buff);
|
2394
|
+
if ($$et{IeImg_lkup} and $$et{IeImg_lkup}{$num}) {
|
2395
|
+
# save position of this image
|
2396
|
+
$et->HandleTag($tagTablePtr, IeImg_rect => $$et{IeImg_lkup}{$num});
|
2397
|
+
delete $$et{IeImg_lkup}{$num};
|
2398
|
+
}
|
2399
|
+
delete $$et{DOC_NUM};
|
2400
|
+
} else {
|
2401
|
+
$et->FoundTag($tagInfo, $buff);
|
2402
|
+
}
|
2342
2403
|
}
|
2343
2404
|
# save object index number for all found tags
|
2344
2405
|
my $num2 = $$et{NUM_FOUND};
|
@@ -2395,6 +2456,10 @@ sub ProcessFPX($$)
|
|
2395
2456
|
# process Word document table
|
2396
2457
|
ProcessDocumentTable($et);
|
2397
2458
|
|
2459
|
+
if ($$et{IeImg_lkup} and %{$$et{IeImg_lkup}}) {
|
2460
|
+
$et->Warn('Image positions exist without corresponding images');
|
2461
|
+
}
|
2462
|
+
|
2398
2463
|
return 1;
|
2399
2464
|
}
|
2400
2465
|
|
@@ -31,7 +31,7 @@ use vars qw($VERSION);
|
|
31
31
|
use Image::ExifTool qw(:DataAccess :Utils);
|
32
32
|
use Image::ExifTool::Exif;
|
33
33
|
|
34
|
-
$VERSION = '1.
|
34
|
+
$VERSION = '1.87';
|
35
35
|
|
36
36
|
sub ProcessFujiDir($$$);
|
37
37
|
sub ProcessFaceRec($$$);
|
@@ -808,6 +808,7 @@ my %faceCategories = (
|
|
808
808
|
0x00 => 'Normal',
|
809
809
|
0x10 => 'F-log',
|
810
810
|
0x20 => 'HLG',
|
811
|
+
0x30 => 'F-log2', #forum14384
|
811
812
|
},
|
812
813
|
},
|
813
814
|
0x3804 => { #forum10037
|
@@ -482,13 +482,13 @@ sub PrintTimeStamp($)
|
|
482
482
|
#------------------------------------------------------------------------------
|
483
483
|
# Convert degrees to DMS, or whatever the current settings are
|
484
484
|
# Inputs: 0) ExifTool reference, 1) Value in degrees,
|
485
|
-
# 2) format code (0=no format, 1=CoordFormat, 2=XMP format)
|
485
|
+
# 2) format code (0=no format, 1=CoordFormat, 2=XMP format, 3=signed unformatted)
|
486
486
|
# 3) 'N' or 'E' if sign is significant and N/S/E/W should be added
|
487
487
|
# Returns: DMS string
|
488
488
|
sub ToDMS($$;$$)
|
489
489
|
{
|
490
490
|
my ($et, $val, $doPrintConv, $ref) = @_;
|
491
|
-
my ($fmt, @fmt, $num, $sign, $rtnVal);
|
491
|
+
my ($fmt, @fmt, $num, $sign, $rtnVal, $neg);
|
492
492
|
|
493
493
|
unless (length $val) {
|
494
494
|
# don't convert an empty value
|
@@ -505,6 +505,10 @@ sub ToDMS($$;$$)
|
|
505
505
|
}
|
506
506
|
$ref = " $ref" unless $doPrintConv and $doPrintConv eq '2';
|
507
507
|
} else {
|
508
|
+
if ($doPrintConv and $doPrintConv eq '3') {
|
509
|
+
$neg = 1 if $val < 0;
|
510
|
+
$doPrintConv = 0;
|
511
|
+
}
|
508
512
|
$val = abs($val);
|
509
513
|
$ref = '';
|
510
514
|
}
|
@@ -554,6 +558,7 @@ sub ToDMS($$;$$)
|
|
554
558
|
# trim trailing zeros in XMP
|
555
559
|
$rtnVal =~ s/(\d)0+$ref$/$1$ref/ if $doPrintConv eq '2';
|
556
560
|
} else {
|
561
|
+
$neg and map { $_ *= -1 } @c;
|
557
562
|
$rtnVal = "@c$ref";
|
558
563
|
}
|
559
564
|
return $rtnVal;
|
@@ -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.34';
|
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/',
|
@@ -119,6 +129,10 @@ sub ProcessJPEG_HDR($$$);
|
|
119
129
|
Name => 'FPXR', # (non-standard location written by some HP models)
|
120
130
|
Condition => '$$valPt =~ /^FPXR\0/',
|
121
131
|
SubDirectory => { TagTable => 'Image::ExifTool::FlashPix::Main' },
|
132
|
+
}, {
|
133
|
+
Name => 'InfiRayFactory',
|
134
|
+
Condition => '$$self{HasIJPEG}"',
|
135
|
+
SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::Factory' },
|
122
136
|
}, {
|
123
137
|
Name => 'ThermalParams', # (written by DJI FLIR models)
|
124
138
|
Condition => '$$self{Make} eq "DJI" and $$valPt =~ /^\xaa\x55\x12\x06/',
|
@@ -135,6 +149,10 @@ sub ProcessJPEG_HDR($$$);
|
|
135
149
|
Name => 'SamsungUniqueID',
|
136
150
|
Condition => '$$valPt =~ /ssuniqueid\0/',
|
137
151
|
SubDirectory => { TagTable => 'Image::ExifTool::Samsung::APP5' },
|
152
|
+
}, {
|
153
|
+
Name => 'InfiRayPicture',
|
154
|
+
Condition => '$$self{HasIJPEG}',
|
155
|
+
SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::Picture' },
|
138
156
|
}, {
|
139
157
|
Name => 'ThermalCalibration', # (written by DJI FLIR models)
|
140
158
|
Condition => '$$self{Make} eq "DJI"',
|
@@ -161,13 +179,17 @@ sub ProcessJPEG_HDR($$$);
|
|
161
179
|
Name => 'GoPro',
|
162
180
|
Condition => '$$valPt =~ /^GoPro\0/',
|
163
181
|
SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' },
|
164
|
-
|
182
|
+
}, {
|
183
|
+
Name => 'InfiRayMixMode',
|
184
|
+
Condition => '$$self{HasIJPEG}',
|
185
|
+
SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::MixMode' },
|
165
186
|
}, {
|
166
187
|
Name => 'DJI_DTAT', # (written by ZH20T)
|
167
188
|
Condition => '$$valPt =~ /^DTAT\0\0.\{/s',
|
168
189
|
Groups => { 0 => 'APP6', 1 => 'DJI' },
|
169
190
|
Notes => 'DJI Thermal Analysis Tool record',
|
170
191
|
ValueConv => 'substr($val,7)',
|
192
|
+
# also seen Motorola APP6 "MMIMETA\0", with sub-types: AL3A,ALED,MMI0,MOTD,QC3A
|
171
193
|
}],
|
172
194
|
APP7 => [{
|
173
195
|
Name => 'Pentax',
|
@@ -181,17 +203,29 @@ sub ProcessJPEG_HDR($$$);
|
|
181
203
|
Name => 'Qualcomm',
|
182
204
|
Condition => '$$valPt =~ /^\x1aQualcomm Camera Attributes/',
|
183
205
|
SubDirectory => { TagTable => 'Image::ExifTool::Qualcomm::Main' },
|
206
|
+
}, {
|
207
|
+
Name => 'InfiRayOpMode',
|
208
|
+
Condition => '$$self{HasIJPEG}',
|
209
|
+
SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::OpMode' },
|
184
210
|
}],
|
185
|
-
APP8 => {
|
211
|
+
APP8 => [{
|
186
212
|
Name => 'SPIFF',
|
187
213
|
Condition => '$$valPt =~ /^SPIFF\0/',
|
188
214
|
SubDirectory => { TagTable => 'Image::ExifTool::JPEG::SPIFF' },
|
189
|
-
|
190
|
-
|
215
|
+
}, {
|
216
|
+
Name => 'InfiRayIsothermal',
|
217
|
+
Condition => '$$self{HasIJPEG}',
|
218
|
+
SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::Isothermal' },
|
219
|
+
}],
|
220
|
+
APP9 => [{
|
191
221
|
Name => 'MediaJukebox',
|
192
222
|
Condition => '$$valPt =~ /^Media Jukebox\0/',
|
193
223
|
SubDirectory => { TagTable => 'Image::ExifTool::JPEG::MediaJukebox' },
|
194
|
-
|
224
|
+
}, {
|
225
|
+
Name => 'InfiRaySensor',
|
226
|
+
Condition => '$$self{HasIJPEG}',
|
227
|
+
SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::Sensor' },
|
228
|
+
}],
|
195
229
|
APP10 => {
|
196
230
|
Name => 'Comment',
|
197
231
|
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
|