exiftool_vendored 12.70.0 → 12.72.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 +36 -1
- data/bin/MANIFEST +5 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +10 -10
- data/bin/exiftool +21 -14
- data/bin/lib/Image/ExifTool/AAC.pm +175 -0
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +2 -1
- data/bin/lib/Image/ExifTool/Canon.pm +21 -6
- data/bin/lib/Image/ExifTool/Exif.pm +30 -9
- data/bin/lib/Image/ExifTool/FujiFilm.pm +5 -2
- data/bin/lib/Image/ExifTool/GoPro.pm +16 -1
- data/bin/lib/Image/ExifTool/ID3.pm +7 -4
- data/bin/lib/Image/ExifTool/JSON.pm +4 -1
- data/bin/lib/Image/ExifTool/M2TS.pm +21 -16
- data/bin/lib/Image/ExifTool/Nikon.pm +158 -90
- data/bin/lib/Image/ExifTool/Pentax.pm +15 -6
- data/bin/lib/Image/ExifTool/QuickTime.pm +29 -10
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +59 -11
- data/bin/lib/Image/ExifTool/Ricoh.pm +109 -1
- data/bin/lib/Image/ExifTool/Samsung.pm +3 -2
- data/bin/lib/Image/ExifTool/Sony.pm +83 -4
- data/bin/lib/Image/ExifTool/TagLookup.pm +4862 -4828
- data/bin/lib/Image/ExifTool/TagNames.pod +147 -42
- data/bin/lib/Image/ExifTool/WriteExif.pl +19 -4
- data/bin/lib/Image/ExifTool/Writer.pl +81 -14
- data/bin/lib/Image/ExifTool.pm +18 -6
- data/bin/lib/Image/ExifTool.pod +19 -14
- data/bin/perl-Image-ExifTool.spec +9 -9
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +3 -2
@@ -83,7 +83,8 @@ my %processByMetaFormat = (
|
|
83
83
|
|
84
84
|
# data lengths for each INSV/INSP record type
|
85
85
|
my %insvDataLen = (
|
86
|
-
|
86
|
+
0x000 => 0, # directory table (any size)
|
87
|
+
0x200 => 0, # PreviewImage (any size) (a duplicate of PreviewImage in APP2 of INSP files)
|
87
88
|
0x300 => 0, # accelerometer (could be either 20 or 56 bytes)
|
88
89
|
0x400 => 16, # exposure (ref 6)
|
89
90
|
0x600 => 8, # timestamps (ref 6)
|
@@ -91,6 +92,8 @@ my %insvDataLen = (
|
|
91
92
|
# 0x900 => 48, # ? (Insta360 X3)
|
92
93
|
# 0xa00 => 5?, # ? (Insta360 ONE RS)
|
93
94
|
# 0xb00 => 10, # ? (Insta360 X3)
|
95
|
+
# 0xd00 => 10, # ? (Insta360 Ace Pro)
|
96
|
+
# 0x1200 ? # ? (Insta360 Ace Pro)
|
94
97
|
);
|
95
98
|
|
96
99
|
# limit the default amount of data we read for some record types
|
@@ -106,7 +109,7 @@ my %insvLimit = (
|
|
106
109
|
The tags below are extracted from timed metadata in QuickTime and other
|
107
110
|
formats of video files when the ExtractEmbedded option is used. Although
|
108
111
|
most of these tags are combined into the single table below, ExifTool
|
109
|
-
currently reads
|
112
|
+
currently reads 67 different formats of timed GPS metadata from video files.
|
110
113
|
},
|
111
114
|
VARS => { NO_ID => 1 },
|
112
115
|
GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' },
|
@@ -2043,7 +2046,7 @@ ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) {
|
|
2043
2046
|
return 1;
|
2044
2047
|
|
2045
2048
|
} elsif ($$dataPt =~ /^.{28}A.{11}([NS]).{15}([EW])/s) {
|
2046
|
-
|
2049
|
+
|
2047
2050
|
$debug and $et->FoundTag(GPSType => '2G');
|
2048
2051
|
# Vantrue N4 dashcam
|
2049
2052
|
# 0000: 00 00 40 00 66 72 65 65 47 50 53 20 f0 03 00 00 [..@.freeGPS ....]
|
@@ -2778,7 +2781,7 @@ sub ProcessInsta360($;$)
|
|
2778
2781
|
my ($et, $dirInfo) = @_;
|
2779
2782
|
my $raf = $$et{RAF};
|
2780
2783
|
my $offset = $dirInfo ? $$dirInfo{Offset} || 0 : 0;
|
2781
|
-
my $buff;
|
2784
|
+
my ($buff, $dirTable, $dirTablePos);
|
2782
2785
|
|
2783
2786
|
return 0 unless $raf->Seek(-78-$offset, 2) and $raf->Read($buff, 78) == 78 and
|
2784
2787
|
substr($buff,-32) eq "8db42d694ccc418790edff439fe026bf"; # check magic number
|
@@ -2868,7 +2871,19 @@ sub ProcessInsta360($;$)
|
|
2868
2871
|
if ($len % $dlen and $id != 0x700) { # (have seen one 0x700 record which was expected format but not multiple of 53 bytes)
|
2869
2872
|
$et->Warn(sprintf('Unexpected Insta360 record 0x%x length',$id));
|
2870
2873
|
} elsif ($id == 0x200) {
|
2871
|
-
|
2874
|
+
# there are 4 types of record 0x200
|
2875
|
+
# 1. JPEG preview (starts with ff d8 ff e1)
|
2876
|
+
# 2. TIFF preview (starts with 01 00 00 00, then record length)
|
2877
|
+
# 3. Unknown 1 (starts with 00 00 00 01)
|
2878
|
+
# 4. Unknown 2 (starts with 00 00 01 34)
|
2879
|
+
if ($buff =~ /^\xff\xd8\xff/) {
|
2880
|
+
$et->FoundTag(PreviewImage => $buff);
|
2881
|
+
} elsif ($buff =~ /^\x01\0\0\0(.{4})\x01/s and unpack('V',$1) == $dlen) {
|
2882
|
+
my ($w, $h) = unpack('x16V2',$buff);
|
2883
|
+
# build the TIFF image (could the 1 at byte 9 be the SamplesPerPixel?)
|
2884
|
+
my $hdr = Image::ExifTool::MakeTiffHeader($w, $h, 1, 8);
|
2885
|
+
$et->FoundTag(PreviewTIFF => $hdr . substr($buff, 40));
|
2886
|
+
}
|
2872
2887
|
} elsif ($id == 0x300) {
|
2873
2888
|
for ($p=0; $p<$len; $p+=$dlen) {
|
2874
2889
|
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
@@ -2899,7 +2914,7 @@ sub ProcessInsta360($;$)
|
|
2899
2914
|
my $tmp = substr($buff, $p, $dlen);
|
2900
2915
|
my @a = unpack('VVvaa8aa8aa8a8a8', $tmp);
|
2901
2916
|
unless (($a[5] eq 'N' or $a[5] eq 'S') and # (quick validation)
|
2902
|
-
($a[7] eq 'E' or $a[7] eq 'W' or
|
2917
|
+
($a[7] eq 'E' or $a[7] eq 'W' or
|
2903
2918
|
# (odd, but I've seen "O" instead of "W". Perhaps
|
2904
2919
|
# when the language is french? ie. "Ouest"?)
|
2905
2920
|
$a[7] eq 'O'))
|
@@ -2913,13 +2928,15 @@ sub ProcessInsta360($;$)
|
|
2913
2928
|
$a[$_] = GetDouble(\$a[$_], 0) foreach 4,6,8,9,10;
|
2914
2929
|
$a[4] = -abs($a[4]) if $a[5] eq 'S'; # (abs just in case it was already signed)
|
2915
2930
|
$a[6] = -abs($a[6]) if $a[7] ne 'E';
|
2916
|
-
|
2931
|
+
my $ms = '';
|
2932
|
+
$a[2] and ($ms = sprintf('.%.3d', $a[2])) =~ s/0+$//;
|
2933
|
+
$et->HandleTag($tagTbl, GPSDateTime => Image::ExifTool::ConvertUnixTime($a[0]) . $ms . 'Z');
|
2917
2934
|
$et->HandleTag($tagTbl, GPSLatitude => $a[4]);
|
2918
2935
|
$et->HandleTag($tagTbl, GPSLongitude => $a[6]);
|
2919
2936
|
$et->HandleTag($tagTbl, GPSSpeed => $a[8] * $mpsToKph);
|
2920
2937
|
$et->HandleTag($tagTbl, GPSTrack => $a[9]);
|
2921
2938
|
$et->HandleTag($tagTbl, GPSAltitude => $a[10]);
|
2922
|
-
$et->HandleTag($tagTbl, Unknown02 =>
|
2939
|
+
$et->HandleTag($tagTbl, Unknown02 => $a[1]) if $unknown;
|
2923
2940
|
}
|
2924
2941
|
}
|
2925
2942
|
} elsif ($id == 0x101) {
|
@@ -2932,10 +2949,41 @@ sub ProcessInsta360($;$)
|
|
2932
2949
|
$et->HandleTag($tagTablePtr, $t, $val);
|
2933
2950
|
$p += 2 + $n;
|
2934
2951
|
}
|
2952
|
+
} elsif ($id == 0x0) {
|
2953
|
+
last if not $len;
|
2954
|
+
# example directory table for record locations from Insta360AcePro MP4 video:
|
2955
|
+
# vv vv - record ID
|
2956
|
+
# vv vv vv vv - record size
|
2957
|
+
# vv vv vv vv - offset from start of footer
|
2958
|
+
# 00 00 00 00 00 00 00 00 00 00
|
2959
|
+
# 01 01 82 04 00 00 1b 45 62 00
|
2960
|
+
# 02 00 28 46 05 00 ed fe 5c 00
|
2961
|
+
# 03 00 40 aa 24 00 ed fe 34 00
|
2962
|
+
# 04 00 00 c1 01 00 ed fe 30 00
|
2963
|
+
# [...]
|
2964
|
+
unless ($dirTable) {
|
2965
|
+
$dirTable = $buff;
|
2966
|
+
$dirTablePos = 0;
|
2967
|
+
}
|
2935
2968
|
}
|
2936
|
-
|
2937
|
-
|
2938
|
-
|
2969
|
+
# step through directory table instead of sequential scanning if possible
|
2970
|
+
if ($dirTable) {
|
2971
|
+
undef $epos;
|
2972
|
+
for (;;) {
|
2973
|
+
last if $dirTablePos + 10 > length($dirTable);
|
2974
|
+
my ($id, $siz, $off) = unpack("x${dirTablePos}vVV", $dirTable);
|
2975
|
+
$dirTablePos += 10;
|
2976
|
+
if ($id and $siz and $off + $siz < $trailerLen) {
|
2977
|
+
$epos = $off + $siz - $trailerLen;
|
2978
|
+
last;
|
2979
|
+
}
|
2980
|
+
}
|
2981
|
+
last unless defined $epos;
|
2982
|
+
} else {
|
2983
|
+
($epos -= 6) + $trailerLen < 0 and last; # step back to previous record
|
2984
|
+
}
|
2985
|
+
$raf->Seek($epos, 2) or last; # seek to start of next footer
|
2986
|
+
$raf->Read($buff, 6) == 6 or last; # read footer
|
2939
2987
|
}
|
2940
2988
|
$$et{DOC_NUM} = 0;
|
2941
2989
|
SetByteOrder('MM');
|
@@ -9,6 +9,7 @@
|
|
9
9
|
# 2) http://homepage3.nifty.com/kamisaka/makernote/makernote_ricoh.htm
|
10
10
|
# 3) Tim Gray private communication (GR)
|
11
11
|
# 4) https://github.com/atotto/ricoh-theta-tools/
|
12
|
+
# 5) https://github.com/ricohapi/theta-api-specs/blob/main/theta-metadata/README.md
|
12
13
|
# IB) Iliah Borg private communication (LibRaw)
|
13
14
|
#------------------------------------------------------------------------------
|
14
15
|
|
@@ -18,11 +19,13 @@ use strict;
|
|
18
19
|
use vars qw($VERSION);
|
19
20
|
use Image::ExifTool qw(:DataAccess :Utils);
|
20
21
|
use Image::ExifTool::Exif;
|
22
|
+
use Image::ExifTool::GPS;
|
21
23
|
|
22
|
-
$VERSION = '1.
|
24
|
+
$VERSION = '1.37';
|
23
25
|
|
24
26
|
sub ProcessRicohText($$$);
|
25
27
|
sub ProcessRicohRMETA($$$);
|
28
|
+
sub ProcessRicohRDT($$$);
|
26
29
|
|
27
30
|
# lens types for Ricoh GXR
|
28
31
|
my %ricohLensIDs = (
|
@@ -908,6 +911,65 @@ my %ricohLensIDs = (
|
|
908
911
|
},
|
909
912
|
);
|
910
913
|
|
914
|
+
# real-time metadata in RDTA atom (ref 5)
|
915
|
+
%Image::ExifTool::Ricoh::RDTA = (
|
916
|
+
PROCESS_PROC => \&ProcessRicohRDT,
|
917
|
+
GROUPS => { 0 => 'MakerNotes', 2 => 'Location' },
|
918
|
+
0 => { Name => 'Accelerometer', Format => 'float[3]' },
|
919
|
+
16 => { Name => 'TimeStamp', Format => 'int64u', ValueConv => '$val * 1e-9' },
|
920
|
+
);
|
921
|
+
|
922
|
+
# real-time metadata in RDTB atom (ref 5)
|
923
|
+
%Image::ExifTool::Ricoh::RDTB = (
|
924
|
+
PROCESS_PROC => \&ProcessRicohRDT,
|
925
|
+
GROUPS => { 0 => 'MakerNotes', 2 => 'Location' },
|
926
|
+
0 => { Name => 'Gyroscope', Format => 'float[3]', Notes => 'rad/s' },
|
927
|
+
16 => { Name => 'TimeStamp', Format => 'int64u', ValueConv => '$val * 1e-9' },
|
928
|
+
);
|
929
|
+
|
930
|
+
# real-time metadata in RDTC atom (ref 5)
|
931
|
+
%Image::ExifTool::Ricoh::RDTC = (
|
932
|
+
PROCESS_PROC => \&ProcessRicohRDT,
|
933
|
+
GROUPS => { 0 => 'MakerNotes', 2 => 'Location' },
|
934
|
+
0 => { Name => 'MagneticField', Format => 'float[3]' },
|
935
|
+
16 => { Name => 'TimeStamp', Format => 'int64u', ValueConv => '$val * 1e-9' },
|
936
|
+
);
|
937
|
+
|
938
|
+
# real-time metadata in RDTG atom (ref 5)
|
939
|
+
%Image::ExifTool::Ricoh::RDTG = (
|
940
|
+
PROCESS_PROC => \&ProcessRicohRDT,
|
941
|
+
GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
|
942
|
+
0 => { Name => 'TimeStamp', Format => 'int64u', ValueConv => '$val * 1e-9' },
|
943
|
+
100 => { Name => 'FrameNumber', Notes => 'generated internally' },
|
944
|
+
);
|
945
|
+
|
946
|
+
# real-time metadata in RDTL atom (ref 5)
|
947
|
+
%Image::ExifTool::Ricoh::RDTL = (
|
948
|
+
GROUPS => { 0 => 'MakerNotes', 2 => 'Location' },
|
949
|
+
0 => {
|
950
|
+
Name => 'GPSDateTime',
|
951
|
+
Groups => { 2 => 'Time' },
|
952
|
+
Format => 'double',
|
953
|
+
ValueConv => 'ConvertUnixTime($val*1e-9, 1, 9)', # (NC -- what is the epoch?)
|
954
|
+
PrintConv => '$self->ConvertDateTime($val)',
|
955
|
+
},
|
956
|
+
8 => {
|
957
|
+
Name => 'GPSLatitude',
|
958
|
+
Format => 'double',
|
959
|
+
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
|
960
|
+
},
|
961
|
+
16 => {
|
962
|
+
Name => 'GPSLongitude',
|
963
|
+
Format => 'double',
|
964
|
+
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
|
965
|
+
},
|
966
|
+
24 => {
|
967
|
+
Name => 'GPSAltitude',
|
968
|
+
Format => 'double',
|
969
|
+
PrintConv => '($val =~ s/^-// ? "$val m Below" : "$val m Above") . " Sea Level"',
|
970
|
+
},
|
971
|
+
);
|
972
|
+
|
911
973
|
# Ricoh composite tags
|
912
974
|
%Image::ExifTool::Ricoh::Composite = (
|
913
975
|
GROUPS => { 2 => 'Camera' },
|
@@ -932,6 +994,52 @@ my %ricohLensIDs = (
|
|
932
994
|
Image::ExifTool::AddCompositeTags('Image::ExifTool::Ricoh');
|
933
995
|
|
934
996
|
|
997
|
+
#------------------------------------------------------------------------------
|
998
|
+
# Process Ricoh RDT* real-time metadata
|
999
|
+
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
|
1000
|
+
# Returns: 1 on success, otherwise returns 0 and sets a Warning
|
1001
|
+
sub ProcessRicohRDT($$$)
|
1002
|
+
{
|
1003
|
+
my ($et, $dirInfo, $tagTablePtr) = @_;
|
1004
|
+
my $dataPt = $$dirInfo{DataPt};
|
1005
|
+
my $dirLen = $$dirInfo{DirLen};
|
1006
|
+
my $dirName = $$dirInfo{DirName};
|
1007
|
+
my ($i, $rdtg);
|
1008
|
+
return 0 if $dirLen < 16;
|
1009
|
+
my $ee = $et->Options('ExtractEmbedded');
|
1010
|
+
unless ($ee) {
|
1011
|
+
$et->WarnOnce('Use ExtractEmbedded option to read Ricoh real-time metadata',3);
|
1012
|
+
return 1;
|
1013
|
+
}
|
1014
|
+
my $endian = substr($$dataPt, 8, 2);
|
1015
|
+
SetByteOrder($endian eq "\x23\x01" ? 'II' : 'MM');
|
1016
|
+
my $count = Get32u($dataPt, 0);
|
1017
|
+
my $len = Get16u($dataPt, 6);
|
1018
|
+
if ($dirName eq 'RicohRDTG') {
|
1019
|
+
if ($ee < 2) {
|
1020
|
+
$et->WarnOnce('Set ExtractEmbedded option to 2 or higher to extract frame timestamps',3);
|
1021
|
+
return 1;
|
1022
|
+
}
|
1023
|
+
$rdtg = 0;
|
1024
|
+
$et->WarnOnce('Unexpected RDTG record length') if $len > 8;
|
1025
|
+
}
|
1026
|
+
if ($count * $len + 16 > $dirLen) {
|
1027
|
+
$et->Warn("Truncated $dirName data");
|
1028
|
+
$count = int(($dirLen - 16) / $len);
|
1029
|
+
}
|
1030
|
+
$et->VerboseDir($dirName);
|
1031
|
+
$$dirInfo{DirStart} = 16;
|
1032
|
+
$$dirInfo{DirLen} = $len;
|
1033
|
+
for ($i=0; $i<$count; ++$i) {;
|
1034
|
+
$$et{DOC_NUM} = ++$$et{DOC_COUNT};
|
1035
|
+
$et->HandleTag($tagTablePtr, 100, $rdtg++) if defined $rdtg;
|
1036
|
+
$et->ProcessBinaryData($dirInfo, $tagTablePtr);
|
1037
|
+
$$dirInfo{DirStart} += $len;
|
1038
|
+
}
|
1039
|
+
delete $$et{DOC_NUM};
|
1040
|
+
return 1;
|
1041
|
+
}
|
1042
|
+
|
935
1043
|
#------------------------------------------------------------------------------
|
936
1044
|
# Process Ricoh text-based maker notes
|
937
1045
|
# Inputs: 0) ExifTool object reference
|
@@ -22,7 +22,7 @@ use vars qw($VERSION %samsungLensTypes);
|
|
22
22
|
use Image::ExifTool qw(:DataAccess :Utils);
|
23
23
|
use Image::ExifTool::Exif;
|
24
24
|
|
25
|
-
$VERSION = '1.
|
25
|
+
$VERSION = '1.55';
|
26
26
|
|
27
27
|
sub WriteSTMN($$$);
|
28
28
|
sub ProcessINFO($$$);
|
@@ -904,9 +904,10 @@ my %formatMinMax = (
|
|
904
904
|
Name => 'SamsungSvss',
|
905
905
|
SubDirectory => { TagTable => 'Image::ExifTool::Samsung::svss' },
|
906
906
|
},
|
907
|
+
mdln => 'SamsungModel', #PH (Samsung SM-A136U, etc)
|
907
908
|
# swtr - 4 bytes, all zero
|
908
909
|
# scid - 8 bytes, all zero
|
909
|
-
# saut - 4 bytes, all zero
|
910
|
+
# saut - 4 or 6 bytes, all zero
|
910
911
|
);
|
911
912
|
|
912
913
|
# Samsung MP4 svss information (PH - from SM-C101 sample)
|
@@ -34,7 +34,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
|
|
34
34
|
use Image::ExifTool::Exif;
|
35
35
|
use Image::ExifTool::Minolta;
|
36
36
|
|
37
|
-
$VERSION = '3.
|
37
|
+
$VERSION = '3.65';
|
38
38
|
|
39
39
|
sub ProcessSRF($$$);
|
40
40
|
sub ProcessSR2($$$);
|
@@ -1643,9 +1643,11 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 );
|
|
1643
1643
|
# 0x203e - int8u: seen 0, 1, 2, 3, 4 and 255: possibly nr. of detected/tracked faces?
|
1644
1644
|
# 0x203f - int16u
|
1645
1645
|
# 0x2041 - int8u
|
1646
|
-
# 0x2044 - int32u[2]
|
1647
|
-
|
1648
|
-
|
1646
|
+
# 0x2044 - int32u[2] offset and size of some unknown data, relative to TIFF header in JPG and ARW - PH
|
1647
|
+
0x2044 => {
|
1648
|
+
Name => 'HiddenInfo',
|
1649
|
+
SubDirectory => { TagTable => 'Image::ExifTool::Sony::HiddenInfo' },
|
1650
|
+
},
|
1649
1651
|
# 0x2047 - first seen for ILCE-9M3, November 2023
|
1650
1652
|
# 0x2048 - first seen for ILCE-9M3
|
1651
1653
|
# 0x2049 - undef[2]
|
@@ -5958,6 +5960,29 @@ my %faceInfo = (
|
|
5958
5960
|
# 0x001a, 0x001c appear to be 2 int16u values, meaning unknown
|
5959
5961
|
);
|
5960
5962
|
|
5963
|
+
# hidden information (ref PH)
|
5964
|
+
%Image::ExifTool::Sony::HiddenInfo = (
|
5965
|
+
%binaryDataAttrs,
|
5966
|
+
GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
|
5967
|
+
FORMAT => 'int32u',
|
5968
|
+
IS_OFFSET => [ 0 ], # tag 0 is 'IsOffset'
|
5969
|
+
0 => {
|
5970
|
+
Name => 'HiddenDataOffset',
|
5971
|
+
IsOffset => 1,
|
5972
|
+
OffsetPair => 1,
|
5973
|
+
DataTag => 'HiddenData',
|
5974
|
+
WriteGroup => 'MakerNotes',
|
5975
|
+
Protectd => 2,
|
5976
|
+
},
|
5977
|
+
1 => {
|
5978
|
+
Name => 'HiddenDataLength',
|
5979
|
+
OffsetPair => 0,
|
5980
|
+
DataTag => 'HiddenData',
|
5981
|
+
WriteGroup => 'MakerNotes',
|
5982
|
+
Protectd => 2,
|
5983
|
+
},
|
5984
|
+
);
|
5985
|
+
|
5961
5986
|
# shot information (ref PH)
|
5962
5987
|
%Image::ExifTool::Sony::ShotInfo = (
|
5963
5988
|
%binaryDataAttrs,
|
@@ -10735,6 +10760,32 @@ my %isoSetting2010 = (
|
|
10735
10760
|
ValueConv => '$val[1] =~ /^W/i ? -$val[0] : $val[0]',
|
10736
10761
|
PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
|
10737
10762
|
},
|
10763
|
+
HiddenData => {
|
10764
|
+
Require => {
|
10765
|
+
# (Note: This pointer is fragile in JPEG images, and won't be updated
|
10766
|
+
# when the file is written unless the EXIF information is also written, but
|
10767
|
+
# an incorrect offset is fixed by subsequently writing EXIF with ExifTool)
|
10768
|
+
0 => 'Sony:HiddenDataOffset',
|
10769
|
+
1 => 'Sony:HiddenDataLength',
|
10770
|
+
},
|
10771
|
+
Notes => q{
|
10772
|
+
hidden data in some Sony JPG and ARW images, extracted only if specifically
|
10773
|
+
requested
|
10774
|
+
},
|
10775
|
+
RawConv => q{
|
10776
|
+
my $hdOff = $val[0];
|
10777
|
+
my $reqTag = $$self{REQ_TAG_LOOKUP}{hiddendata};
|
10778
|
+
my $hDump = $self->Options('HtmlDump');
|
10779
|
+
return undef unless $reqTag or $self->Options('Validate') or $hDump;
|
10780
|
+
my $dataPt = Image::ExifTool::Sony::ReadHiddenData($self, $hdOff, $val[1]);
|
10781
|
+
if ($dataPt and $hDump) {
|
10782
|
+
my $msg = '(Sony HiddenData)';
|
10783
|
+
$msg .= ' <span class=V>(fixed)</span>' if $hdOff != $val[0];
|
10784
|
+
$self->HDump($hdOff, $val[1], $msg, undef, 0x08);
|
10785
|
+
}
|
10786
|
+
return $reqTag ? $dataPt : undef;
|
10787
|
+
},
|
10788
|
+
},
|
10738
10789
|
);
|
10739
10790
|
|
10740
10791
|
# add our composite tags
|
@@ -10783,6 +10834,34 @@ sub SortLensTypes
|
|
10783
10834
|
$$minoltaTypes{OTHER} = $other;
|
10784
10835
|
}
|
10785
10836
|
|
10837
|
+
#------------------------------------------------------------------------------
|
10838
|
+
# Read HiddenData from JPEG trailer
|
10839
|
+
# Inputs: 0) ExifTool ref, 1) HiddenDataOffset (abs), 2) HiddenDataLength
|
10840
|
+
# Returns: HiddenData reference, or undef on error
|
10841
|
+
# --> updates $hdOff upon return if it was incorrect
|
10842
|
+
sub ReadHiddenData($$$)
|
10843
|
+
{
|
10844
|
+
my ($et, $hdOff, $hdLen) = @_;
|
10845
|
+
my $raf = $$et{RAF};
|
10846
|
+
my ($buff, $pos);
|
10847
|
+
unless ($raf->Seek($hdOff,0) and $raf->Read($buff,$hdLen) == $hdLen and
|
10848
|
+
$buff=~/^\x55\x26\x11\x05\0/)
|
10849
|
+
{
|
10850
|
+
# search the first 4096 bytes of the trailer to find the HiddenData
|
10851
|
+
unless ($$et{TrailerStart} and $raf->Seek($$et{TrailerStart},0) and
|
10852
|
+
$raf->Read($buff,4096) and $buff=~/\x55\x26\x11\x05\0/g and
|
10853
|
+
$pos = $$et{TrailerStart}+pos($buff)-5 and $raf->Seek($pos,0) and
|
10854
|
+
$raf->Read($buff,$hdLen) == $hdLen)
|
10855
|
+
{
|
10856
|
+
$et->Warn('Error reading HiddenData',1);
|
10857
|
+
return undef;
|
10858
|
+
}
|
10859
|
+
$_[1] = $pos; # return fixed offset
|
10860
|
+
$et->Warn('Fixed incorrect HiddenDataOffset',1) if $et->Options('Validate') or $$et{IsWriting};
|
10861
|
+
}
|
10862
|
+
return \$buff;
|
10863
|
+
}
|
10864
|
+
|
10786
10865
|
#------------------------------------------------------------------------------
|
10787
10866
|
# Process "SONY PIC\0" maker notes (DSC-H200/J10/W370/W510, MHS-TS20, ref PH)
|
10788
10867
|
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
|