exiftool_vendored 12.83.0 → 12.86.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 +51 -1
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +46 -46
- data/bin/build_geolocation +99 -21
- data/bin/config_files/example.config +7 -2
- data/bin/exiftool +52 -50
- data/bin/lib/Image/ExifTool/Apple.pm +52 -7
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +3 -2
- data/bin/lib/Image/ExifTool/Canon.pm +38 -4
- data/bin/lib/Image/ExifTool/CanonVRD.pm +17 -2
- data/bin/lib/Image/ExifTool/DPX.pm +3 -3
- data/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
- data/bin/lib/Image/ExifTool/Geolocation.pm +132 -79
- data/bin/lib/Image/ExifTool/Geotag.pm +18 -10
- data/bin/lib/Image/ExifTool/ID3.pm +36 -8
- data/bin/lib/Image/ExifTool/Nikon.pm +19 -1
- data/bin/lib/Image/ExifTool/Olympus.pm +27 -17
- data/bin/lib/Image/ExifTool/Pentax.pm +64 -13
- data/bin/lib/Image/ExifTool/QuickTime.pm +28 -9
- data/bin/lib/Image/ExifTool/Samsung.pm +29 -1
- data/bin/lib/Image/ExifTool/TagLookup.pm +3550 -3539
- data/bin/lib/Image/ExifTool/TagNames.pod +51 -22
- data/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +2 -1
- data/bin/lib/Image/ExifTool/Writer.pl +5 -5
- data/bin/lib/Image/ExifTool/XMP.pm +2 -0
- data/bin/lib/Image/ExifTool.pm +91 -49
- data/bin/lib/Image/ExifTool.pod +61 -51
- data/bin/perl-Image-ExifTool.spec +45 -45
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +3 -3
data/bin/lib/Image/ExifTool.pm
CHANGED
@@ -27,9 +27,9 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
|
|
27
27
|
%noWriteFile %magicNumber @langs $defaultLang %langName %charsetName
|
28
28
|
%mimeType $swapBytes $swapWords $currentByteOrder %unpackStd
|
29
29
|
%jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
|
30
|
-
%static_vars);
|
30
|
+
%static_vars $advFmtSelf);
|
31
31
|
|
32
|
-
$VERSION = '12.
|
32
|
+
$VERSION = '12.86';
|
33
33
|
$RELEASE = '';
|
34
34
|
@ISA = qw(Exporter);
|
35
35
|
%EXPORT_TAGS = (
|
@@ -198,7 +198,7 @@ $defaultLang = 'en'; # default language
|
|
198
198
|
RAR 7Z BZ2 CZI TAR EXE EXR HDR CHM LNK WMF AVC DEX DPX RAW Font
|
199
199
|
JUMBF RSRC M2TS MacOS PHP PCX DCX DWF DWG DXF WTV Torrent VCard
|
200
200
|
LRI R3D AA PDB PFM2 MRC LIF JXL MOI ISO ALIAS JSON MP3 DICOM PCD
|
201
|
-
ICO TXT AAC);
|
201
|
+
NKA ICO TXT AAC);
|
202
202
|
|
203
203
|
# file types that we can write (edit)
|
204
204
|
my @writeTypes = qw(JPEG TIFF GIF CRW MRW ORF RAF RAW PNG MIE PSD XMP PPM EPS
|
@@ -210,7 +210,7 @@ my %writeTypes; # lookup for writable file types (hash filled if required)
|
|
210
210
|
# (See here for 3FR reason: https://exiftool.org/forum/index.php?msg=17570)
|
211
211
|
%noWriteFile = (
|
212
212
|
TIFF => [ qw(3FR DCR K25 KDC SRF) ],
|
213
|
-
XMP => [ qw(SVG INX) ],
|
213
|
+
XMP => [ qw(SVG INX NXD) ],
|
214
214
|
JP2 => [ qw(J2C JPC) ],
|
215
215
|
MOV => [ qw(INSV) ],
|
216
216
|
);
|
@@ -426,10 +426,12 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
426
426
|
# NDPI => ['TIFF', 'Hamamatsu NanoZoomer Digital Pathology Image'],
|
427
427
|
NEF => ['TIFF', 'Nikon (RAW) Electronic Format'],
|
428
428
|
NEWER => 'COS',
|
429
|
+
NKA => ['NKA', 'Nikon NX Studio Settings'],
|
429
430
|
NKSC => ['XMP', 'Nikon Sidecar'],
|
430
431
|
NMBTEMPLATE => ['ZIP','Apple Numbers Template'],
|
431
432
|
NRW => ['TIFF', 'Nikon RAW (2)'],
|
432
433
|
NUMBERS => ['ZIP','Apple Numbers spreadsheet'],
|
434
|
+
NXD => ['XMP', 'Nikon NX-D Settings'],
|
433
435
|
O => ['EXE', 'Relocatable Object'],
|
434
436
|
ODB => ['ZIP', 'Open Document Database'],
|
435
437
|
ODC => ['ZIP', 'Open Document Chart'],
|
@@ -869,6 +871,7 @@ my %moduleName = (
|
|
869
871
|
MKV => 'Matroska',
|
870
872
|
MP3 => 'ID3',
|
871
873
|
MRW => 'MinoltaRaw',
|
874
|
+
NKA => 'Nikon',
|
872
875
|
OGG => 'Ogg',
|
873
876
|
ORF => 'Olympus',
|
874
877
|
PDB => 'Palm',
|
@@ -972,6 +975,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
972
975
|
MRC => '.{64}[\x01\x02\x03]\0\0\0[\x01\x02\x03]\0\0\0[\x01\x02\x03]\0\0\0.{132}MAP[\0 ](\x44\x44|\x44\x41|\x11\x11)\0\0',
|
973
976
|
MRW => '\0MR[MI]',
|
974
977
|
MXF => '\x06\x0e\x2b\x34\x02\x05\x01\x01\x0d\x01\x02', # (not tested if extension recognized)
|
978
|
+
NKA => 'NIKONADJ',
|
975
979
|
OGG => '(OggS|ID3)',
|
976
980
|
ORF => '(II|MM)',
|
977
981
|
# PCD => signature is at byte 2048
|
@@ -1176,7 +1180,7 @@ my @defaultWriteGroups = qw(
|
|
1176
1180
|
|
1177
1181
|
# group hash for ExifTool-generated tags
|
1178
1182
|
my %allGroupsExifTool = ( 0 => 'ExifTool', 1 => 'ExifTool', 2 => 'ExifTool' );
|
1179
|
-
my %geoInfo = ( Groups => { 0 => 'ExifTool', 1 => 'ExifTool', 2 => 'Location' }
|
1183
|
+
my %geoInfo = ( Groups => { 0 => 'ExifTool', 1 => 'ExifTool', 2 => 'Location' } );
|
1180
1184
|
|
1181
1185
|
# special tag names (not used for tag info)
|
1182
1186
|
%specialTags = map { $_ => 1 } qw(
|
@@ -1269,6 +1273,7 @@ my %systemTagsNotes = (
|
|
1269
1273
|
},
|
1270
1274
|
Writable => 1,
|
1271
1275
|
WritePseudo => 1,
|
1276
|
+
Priority => 2,
|
1272
1277
|
DelCheck => q{"Can't delete"},
|
1273
1278
|
Protected => 1,
|
1274
1279
|
RawConv => '$self->ConvertFileName($val)',
|
@@ -1281,6 +1286,7 @@ my %systemTagsNotes = (
|
|
1281
1286
|
WritePseudo => 1,
|
1282
1287
|
DelCheck => q{"Can't delete"},
|
1283
1288
|
Protected => 1,
|
1289
|
+
Priority => 2,
|
1284
1290
|
Notes => q{
|
1285
1291
|
may be written with a full path name to set FileName and Directory in one
|
1286
1292
|
operation. This is such a powerful feature that a TestName tag is provided
|
@@ -1293,6 +1299,7 @@ my %systemTagsNotes = (
|
|
1293
1299
|
},
|
1294
1300
|
BaseName => {
|
1295
1301
|
Groups => { 1 => 'System', 2 => 'Other' },
|
1302
|
+
Priority => 2,
|
1296
1303
|
Notes => q{
|
1297
1304
|
file name without extension. Not generated unless specifically requested or
|
1298
1305
|
the API L<RequestAll|../ExifTool.html#RequestAll> option is set
|
@@ -1362,6 +1369,7 @@ my %systemTagsNotes = (
|
|
1362
1369
|
},
|
1363
1370
|
FileType => {
|
1364
1371
|
Groups => { 2 => 'Other' },
|
1372
|
+
Priority => 2,
|
1365
1373
|
Notes => q{
|
1366
1374
|
a short description of the file type. For many file types this is the just
|
1367
1375
|
the uppercase file extension
|
@@ -1995,14 +2003,14 @@ my %systemTagsNotes = (
|
|
1995
2003
|
return $val if $val =~ /\bgeotag\b/i;
|
1996
2004
|
$val .= ',both';
|
1997
2005
|
my $opts = $$self{OPTIONS};
|
1998
|
-
my ($
|
1999
|
-
return '' unless $
|
2000
|
-
if (
|
2006
|
+
my ($cities, $dist) = Image::ExifTool::Geolocation::Geolocate($self->Encode($val,'UTF8'), $opts);
|
2007
|
+
return '' unless $cities;
|
2008
|
+
if (@$cities > 1 and $self->Warn('Multiple matching cities found',2)) {
|
2001
2009
|
warn "$$self{VALUE}{Warning}\n";
|
2002
2010
|
return '';
|
2003
2011
|
}
|
2004
|
-
my @geo = Image::ExifTool::Geolocation::GetEntry(
|
2005
|
-
my @tags = $self->GetGeolocateTags($wantGroup, $
|
2012
|
+
my @geo = Image::ExifTool::Geolocation::GetEntry($$cities[0], $$opts{Lang});
|
2013
|
+
my @tags = $self->GetGeolocateTags($wantGroup, $dist ? 0 : 1);
|
2006
2014
|
my %geoNum = ( City => 0, Province => 1, State => 1, Code => 3, Country => 4,
|
2007
2015
|
Coordinates => 89, Latitude => 8, Longitude => 9 );
|
2008
2016
|
my ($tag, $value);
|
@@ -2049,8 +2057,9 @@ my %systemTagsNotes = (
|
|
2049
2057
|
GeolocationSubregion=> { %geoInfo, Notes => 'geolocation county or subregion', ValueConv => '$self->Decode($val,"UTF8")' },
|
2050
2058
|
GeolocationCountry => { %geoInfo, Notes => 'geolocation country name', ValueConv => '$self->Decode($val,"UTF8")' },
|
2051
2059
|
GeolocationCountryCode=>{%geoInfo, Notes => 'geolocation country code' },
|
2052
|
-
GeolocationTimeZone => { %geoInfo, Notes => 'geolocation time zone
|
2053
|
-
GeolocationFeatureCode=>{%geoInfo, Notes => 'feature code, see L<http://www.geonames.org/export/codes.html#P>' },
|
2060
|
+
GeolocationTimeZone => { %geoInfo, Notes => 'geolocation time zone ID' },
|
2061
|
+
GeolocationFeatureCode=>{%geoInfo, Notes => 'geolocation feature code, see L<http://www.geonames.org/export/codes.html#P>' },
|
2062
|
+
GeolocationFeatureType=>{%geoInfo, Notes => 'geolocation feature type' },
|
2054
2063
|
GeolocationPopulation=>{ %geoInfo, Notes => 'city population rounded to 2 significant digits' },
|
2055
2064
|
GeolocationDistance => { %geoInfo, Notes => 'distance in km from current GPS to city', PrintConv => '"$val km"' },
|
2056
2065
|
GeolocationPosition => { %geoInfo, Notes => 'approximate GPS coordinates of city',
|
@@ -2556,6 +2565,8 @@ sub Options($$;@)
|
|
2556
2565
|
} else {
|
2557
2566
|
warn("Can't set $param to undef\n");
|
2558
2567
|
}
|
2568
|
+
} elsif (lc $param eq 'geodir') {
|
2569
|
+
$Image::ExifTool::Geolocation::geoDir = $newVal; # (undocumented)
|
2559
2570
|
} else {
|
2560
2571
|
if ($param eq 'Escape') {
|
2561
2572
|
# set ESCAPE_PROC
|
@@ -2574,7 +2585,15 @@ sub Options($$;@)
|
|
2574
2585
|
delete $$self{GLOBAL_TIME_OFFSET}; # reset our calculated offset
|
2575
2586
|
} elsif ($param eq 'TimeZone' and defined $newVal and length $newVal) {
|
2576
2587
|
$ENV{TZ} = $newVal;
|
2577
|
-
|
2588
|
+
if ($^O eq 'MSWin32') {
|
2589
|
+
if (eval { require Time::Piece }) {
|
2590
|
+
eval { Time::Piece::_tzset() };
|
2591
|
+
} else {
|
2592
|
+
warn("Install Time::Piece to set time zone in Windows\n");
|
2593
|
+
}
|
2594
|
+
} else {
|
2595
|
+
eval { require POSIX; POSIX::tzset() };
|
2596
|
+
}
|
2578
2597
|
} elsif ($param eq 'Validate') {
|
2579
2598
|
# load Validate module if Validate option enabled
|
2580
2599
|
$newVal and require Image::ExifTool::Validate;
|
@@ -4362,13 +4381,14 @@ sub DoneExtract($)
|
|
4362
4381
|
local $SIG{'__WARN__'} = \&SetWarning;
|
4363
4382
|
undef $evalWarning;
|
4364
4383
|
$$opts{GeolocMulti} = $$opts{Duplicates};
|
4365
|
-
my ($
|
4384
|
+
my ($cities, $dist) = Image::ExifTool::Geolocation::Geolocate($arg, $opts);
|
4366
4385
|
delete $$opts{GeolocMulti};
|
4367
|
-
|
4368
|
-
|
4369
|
-
my $
|
4370
|
-
foreach $
|
4371
|
-
|
4386
|
+
if ($cities and (@$cities < 2 or $dist or not $self->Warn('Multiple Geolocation cities are possible',2))) {
|
4387
|
+
$self->FoundTag(GeolocationWarning => 'Search matched '.scalar(@$cities).' cities') if @$cities > 1;
|
4388
|
+
my $city;
|
4389
|
+
foreach $city (@$cities) {
|
4390
|
+
$$self{DOC_NUM} = ++$$self{DOC_COUNT} unless $city eq $$cities[0];
|
4391
|
+
my @geo = Image::ExifTool::Geolocation::GetEntry($city, $$opts{Lang});
|
4372
4392
|
$self->FoundTag(GeolocationCity => $geo[0]);
|
4373
4393
|
$self->FoundTag(GeolocationRegion => $geo[1]) if $geo[1];
|
4374
4394
|
$self->FoundTag(GeolocationSubregion => $geo[2]) if $geo[2];
|
@@ -4376,13 +4396,17 @@ sub DoneExtract($)
|
|
4376
4396
|
$self->FoundTag(GeolocationCountry => $geo[4]) if $geo[4];
|
4377
4397
|
$self->FoundTag(GeolocationTimeZone => $geo[5]) if $geo[5];
|
4378
4398
|
$self->FoundTag(GeolocationFeatureCode => $geo[6]);
|
4399
|
+
$self->FoundTag(GeolocationFeatureType => $geo[10]) if $geo[10];
|
4379
4400
|
$self->FoundTag(GeolocationPopulation => $geo[7]);
|
4380
4401
|
$self->FoundTag(GeolocationPosition => "$geo[8] $geo[9]");
|
4381
|
-
|
4382
|
-
|
4383
|
-
|
4384
|
-
|
4402
|
+
if ($dist) {
|
4403
|
+
$self->FoundTag(GeolocationDistance => $$dist[0][0]);
|
4404
|
+
$self->FoundTag(GeolocationBearing => $$dist[0][1]);
|
4405
|
+
shift @$dist;
|
4406
|
+
}
|
4407
|
+
last unless $$opts{Duplicates};
|
4385
4408
|
}
|
4409
|
+
delete $$self{DOC_NUM};
|
4386
4410
|
} elsif ($evalWarning) {
|
4387
4411
|
$self->Warn(CleanWarning());
|
4388
4412
|
}
|
@@ -6363,6 +6387,7 @@ sub TimeLocal(@)
|
|
6363
6387
|
if ($^O eq 'MSWin32') {
|
6364
6388
|
# patch for ActivePerl timezone bug
|
6365
6389
|
my @t2 = localtime($tm);
|
6390
|
+
$t2[5] += 1900;
|
6366
6391
|
my $t2 = Time::Local::timelocal(@t2);
|
6367
6392
|
# adjust timelocal() return value to be consistent with localtime()
|
6368
6393
|
$tm += $tm - $t2;
|
@@ -6834,11 +6859,12 @@ sub DirStart($$;$)
|
|
6834
6859
|
#------------------------------------------------------------------------------
|
6835
6860
|
# Extract metadata from a jpg image
|
6836
6861
|
# Inputs: 0) ExifTool object reference, 1) dirInfo ref with RAF set
|
6862
|
+
# 2) tag table ref to process JPEG-like metadata
|
6837
6863
|
# Returns: 1 on success, 0 if this wasn't a valid JPEG file
|
6838
|
-
sub ProcessJPEG(
|
6864
|
+
sub ProcessJPEG($$;$)
|
6839
6865
|
{
|
6840
6866
|
local $_;
|
6841
|
-
my ($self, $dirInfo) = @_;
|
6867
|
+
my ($self, $dirInfo, $optionalTagTable) = @_;
|
6842
6868
|
my $options = $$self{OPTIONS};
|
6843
6869
|
my $verbose = $$options{Verbose};
|
6844
6870
|
my $out = $$options{TextOut};
|
@@ -6846,20 +6872,29 @@ sub ProcessJPEG($$)
|
|
6846
6872
|
my $raf = $$dirInfo{RAF};
|
6847
6873
|
my $req = $$self{REQ_TAG_LOOKUP};
|
6848
6874
|
my $htmlDump = $$self{HTML_DUMP};
|
6849
|
-
my %dumpParms = ( Out => $out );
|
6850
|
-
my ($ch, $s, $length, $hash, $hashsize);
|
6875
|
+
my %dumpParms = ( Out => $out, Prefix => $$self{INDENT} );
|
6876
|
+
my ($ch, $s, $length, $hash, $hashsize, $indent);
|
6851
6877
|
my ($success, $wantTrailer, $trailInfo, $foundSOS, $gotSize, %jumbfChunk);
|
6852
6878
|
my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $flirTotal);
|
6853
6879
|
my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP);
|
6854
6880
|
|
6881
|
+
($indent = $$self{INDENT}) =~ s/ $//;
|
6882
|
+
unless ($raf) {
|
6883
|
+
$raf = File::RandomAccess->new($$dirInfo{DataPt});
|
6884
|
+
$self->VerboseDir('JPEG', undef, length(${$$dirInfo{DataPt}}));
|
6885
|
+
}
|
6855
6886
|
# get pointer to hash object if it exists and we are the top-level JPEG or JP2
|
6856
6887
|
if ($$self{FILE_TYPE} =~ /^(JPEG|JP2)$/ and not $$self{DOC_NUM}) {
|
6857
6888
|
$hash = $$self{ImageDataHash};
|
6858
6889
|
$hashsize = 0;
|
6859
6890
|
}
|
6860
|
-
|
6861
6891
|
# check to be sure this is a valid JPG (or J2C, or EXV) file
|
6862
|
-
|
6892
|
+
if ($raf->Read($s, 2) == 2 and $s =~ /^\xff[\xd8\x4f\x01]/) {
|
6893
|
+
undef $optionalTagTable;
|
6894
|
+
} else {
|
6895
|
+
return 0 unless $optionalTagTable and $s =~ /^\xff[\xe0-\xef]/;
|
6896
|
+
$raf->Seek(-2, 1) or $self->Error('Seek error'), return 1;
|
6897
|
+
}
|
6863
6898
|
if ($s eq "\xff\x01") {
|
6864
6899
|
return 0 unless $raf->Read($s, 5) == 5 and $s eq 'Exiv2';
|
6865
6900
|
$$self{FILE_TYPE} = 'EXV';
|
@@ -6877,7 +6912,7 @@ sub ProcessJPEG($$)
|
|
6877
6912
|
$$raf{NoBuffer} = 1 if $self->Options('FastScan'); # disable buffering in FastScan mode
|
6878
6913
|
|
6879
6914
|
$dumpParms{MaxLen} = 128 if $verbose < 4;
|
6880
|
-
if ($htmlDump) {
|
6915
|
+
if ($htmlDump and not $optionalTagTable) {
|
6881
6916
|
$dumpEnd = $raf->Tell();
|
6882
6917
|
my ($n, $t, $m) = $s eq 'Exiv2' ? (7,'EXV','TEM') : (2,'JPEG','SOI');
|
6883
6918
|
my $pos = $dumpEnd - $n;
|
@@ -6896,6 +6931,7 @@ sub ProcessJPEG($$)
|
|
6896
6931
|
Marker: for (;;) {
|
6897
6932
|
# set marker and data pointer for current segment
|
6898
6933
|
my $marker = $nextMarker;
|
6934
|
+
last if $marker and $marker < 0;
|
6899
6935
|
my $segDataPt = $nextSegDataPt;
|
6900
6936
|
my $segPos = $nextSegPos;
|
6901
6937
|
my $skipped;
|
@@ -6904,12 +6940,17 @@ sub ProcessJPEG($$)
|
|
6904
6940
|
#
|
6905
6941
|
# read ahead to the next segment unless we have reached EOI, SOS or SOD
|
6906
6942
|
#
|
6907
|
-
|
6943
|
+
until ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer and not $hash) or
|
6908
6944
|
$marker==0x93))
|
6909
6945
|
{
|
6910
6946
|
# read up to next marker (JPEG markers begin with 0xff)
|
6911
6947
|
my $buff;
|
6912
|
-
$raf->ReadLine($buff)
|
6948
|
+
unless ($raf->ReadLine($buff)) {
|
6949
|
+
last Marker unless $optionalTagTable;
|
6950
|
+
$nextMarker = -1;
|
6951
|
+
$success = 1;
|
6952
|
+
last;
|
6953
|
+
}
|
6913
6954
|
$skipped = length($buff) - 1;
|
6914
6955
|
# JPEG markers can be padded with unlimited 0xff's
|
6915
6956
|
for (;;) {
|
@@ -6921,21 +6962,21 @@ sub ProcessJPEG($$)
|
|
6921
6962
|
# read segment data if it exists
|
6922
6963
|
if (not defined $markerLenBytes{$nextMarker}) {
|
6923
6964
|
# read record length word
|
6924
|
-
last unless $raf->Read($s, 2) == 2;
|
6965
|
+
last Marker unless $raf->Read($s, 2) == 2;
|
6925
6966
|
my $len = unpack('n',$s); # get data length
|
6926
|
-
last unless defined($len) and $len >= 2;
|
6967
|
+
last Marker unless defined($len) and $len >= 2;
|
6927
6968
|
$nextSegPos = $raf->Tell();
|
6928
6969
|
$len -= 2; # subtract size of length word
|
6929
|
-
last unless $raf->Read($buff, $len) == $len;
|
6970
|
+
last Marker unless $raf->Read($buff, $len) == $len;
|
6930
6971
|
$nextSegDataPt = \$buff; # set pointer to our next data
|
6931
6972
|
} elsif ($markerLenBytes{$nextMarker} == 4) {
|
6932
6973
|
# handle J2C extensions with 4-byte length word
|
6933
|
-
last unless $raf->Read($s, 4) == 4;
|
6974
|
+
last Marker unless $raf->Read($s, 4) == 4;
|
6934
6975
|
my $len = unpack('N',$s); # get data length
|
6935
|
-
last unless defined($len) and $len >= 4;
|
6976
|
+
last Marker unless defined($len) and $len >= 4;
|
6936
6977
|
$nextSegPos = $raf->Tell();
|
6937
6978
|
$len -= 4; # subtract size of length word
|
6938
|
-
last unless $raf->Seek($len, 1);
|
6979
|
+
last Marker unless $raf->Seek($len, 1);
|
6939
6980
|
} elsif ($hash and defined $marker and ($marker == 0x00 or $marker == 0xda or
|
6940
6981
|
($marker >= 0xd0 and $marker <= 0xd7)))
|
6941
6982
|
{
|
@@ -6951,7 +6992,8 @@ sub ProcessJPEG($$)
|
|
6951
6992
|
$hashsize += $skipped + 2;
|
6952
6993
|
}
|
6953
6994
|
# read second segment too if this was the first
|
6954
|
-
next unless defined $marker;
|
6995
|
+
next Marker unless defined $marker;
|
6996
|
+
last;
|
6955
6997
|
}
|
6956
6998
|
# set some useful variables for the current segment
|
6957
6999
|
my $markerName = JpegMarkerName($marker);
|
@@ -6971,7 +7013,7 @@ sub ProcessJPEG($$)
|
|
6971
7013
|
if (($marker & 0xf0) == 0xc0 and ($marker == 0xc0 or $marker & 0x03)) {
|
6972
7014
|
$length = length $$segDataPt;
|
6973
7015
|
if ($verbose) {
|
6974
|
-
print $out "JPEG $markerName ($length bytes):\n";
|
7016
|
+
print $out "${indent}JPEG $markerName ($length bytes):\n";
|
6975
7017
|
HexDump($segDataPt, undef, %dumpParms, Addr=>$segPos) if $verbose>2;
|
6976
7018
|
} elsif ($htmlDump) {
|
6977
7019
|
$self->HDump($segPos-4, $length+4, "[JPEG $markerName]", undef, 0x08);
|
@@ -7014,7 +7056,7 @@ sub ProcessJPEG($$)
|
|
7014
7056
|
next;
|
7015
7057
|
} elsif ($marker == 0xd9) { # EOI
|
7016
7058
|
pop @$path;
|
7017
|
-
$verbose and print $out "JPEG EOI\n";
|
7059
|
+
$verbose and print $out "${indent}JPEG EOI\n";
|
7018
7060
|
my $pos = $raf->Tell();
|
7019
7061
|
$$self{TrailerStart} = $pos unless $$self{DOC_NUM};
|
7020
7062
|
if ($htmlDump and $dumpEnd) {
|
@@ -7075,7 +7117,7 @@ sub ProcessJPEG($$)
|
|
7075
7117
|
# adjust PreviewImageStart to this location
|
7076
7118
|
my $actual = $pos + pos($buff) - 4;
|
7077
7119
|
if ($start and $start ne $actual and $verbose > 1) {
|
7078
|
-
print $out "(Fixed PreviewImage location: $start -> $actual)\n";
|
7120
|
+
print $out "${indent}(Fixed PreviewImage location: $start -> $actual)\n";
|
7079
7121
|
}
|
7080
7122
|
# update preview image offsets
|
7081
7123
|
if ($start) {
|
@@ -7129,7 +7171,7 @@ sub ProcessJPEG($$)
|
|
7129
7171
|
pop @$path;
|
7130
7172
|
$foundSOS = 1;
|
7131
7173
|
# all done with meta information unless we have a trailer
|
7132
|
-
$verbose and print $out "JPEG SOS\n";
|
7174
|
+
$verbose and print $out "${indent}JPEG SOS\n";
|
7133
7175
|
unless ($fast) {
|
7134
7176
|
$trailInfo = IdentifyTrailer($raf);
|
7135
7177
|
# process trailer now unless we are doing verbose dump
|
@@ -7169,7 +7211,7 @@ sub ProcessJPEG($$)
|
|
7169
7211
|
last; # all done parsing file
|
7170
7212
|
} elsif ($marker == 0x93) {
|
7171
7213
|
pop @$path;
|
7172
|
-
$verbose and print $out "JPEG SOD\n";
|
7214
|
+
$verbose and print $out "${indent}JPEG SOD\n";
|
7173
7215
|
$success = 1;
|
7174
7216
|
if ($hash and $$self{FILE_TYPE} eq 'JP2') {
|
7175
7217
|
my $pos = $raf->Tell();
|
@@ -7180,7 +7222,7 @@ sub ProcessJPEG($$)
|
|
7180
7222
|
last; # all done parsing file
|
7181
7223
|
} elsif (defined $markerLenBytes{$marker}) {
|
7182
7224
|
# handle other stand-alone markers and segments we skipped over
|
7183
|
-
$verbose and $marker and print $out "JPEG $markerName\n";
|
7225
|
+
$verbose and $marker and print $out "${indent}JPEG $markerName\n";
|
7184
7226
|
next;
|
7185
7227
|
} elsif ($marker == 0xdb and length($$segDataPt) and # DQT
|
7186
7228
|
# save the DQT data only if JPEGDigest has been requested
|
@@ -7200,7 +7242,7 @@ sub ProcessJPEG($$)
|
|
7200
7242
|
$length = length $$segDataPt;
|
7201
7243
|
$appBytes += $length + 4 if ($marker & 0xf0) == 0xe0; # total size of APP segments
|
7202
7244
|
if ($verbose) {
|
7203
|
-
print $out "JPEG $markerName ($length bytes):\n";
|
7245
|
+
print $out "${indent}JPEG $markerName ($length bytes):\n";
|
7204
7246
|
if ($verbose > 2) {
|
7205
7247
|
my %extraParms = ( Addr => $segPos );
|
7206
7248
|
$extraParms{MaxLen} = 128 if $verbose == 4;
|
@@ -7358,7 +7400,7 @@ sub ProcessJPEG($$)
|
|
7358
7400
|
# some software erroneously writes zeros for the chunk counts)
|
7359
7401
|
my $chunkNum = Get8u($segDataPt, 6);
|
7360
7402
|
my $chunksTot = Get8u($segDataPt, 7) + 1; # (note the "+ 1"!)
|
7361
|
-
$verbose and printf $out "
|
7403
|
+
$verbose and printf $out "${indent}FLIR chunk %d of %d\n",
|
7362
7404
|
$chunkNum + 1, $chunksTot;
|
7363
7405
|
if (defined $flirTotal) {
|
7364
7406
|
# abort parsing FLIR if the total chunk count is inconsistent
|
@@ -7423,7 +7465,7 @@ sub ProcessJPEG($$)
|
|
7423
7465
|
# some software erroneously writes zeros for the chunk counts)
|
7424
7466
|
my $chunkNum = Get8u($segDataPt, 12);
|
7425
7467
|
my $chunksTot = Get8u($segDataPt, 13);
|
7426
|
-
$verbose and print $out "
|
7468
|
+
$verbose and print $out "${indent}ICC_Profile chunk $chunkNum of $chunksTot\n";
|
7427
7469
|
if (defined $iccChunksTotal) {
|
7428
7470
|
# abort parsing ICC_Profile if the total chunk count is inconsistent
|
7429
7471
|
undef $iccChunkCount if $chunksTot != $iccChunksTotal;
|
@@ -7976,7 +8018,7 @@ sub ProcessJPEG($$)
|
|
7976
8018
|
}
|
7977
8019
|
}
|
7978
8020
|
# print verbose hash message if necessary
|
7979
|
-
print $out "
|
8021
|
+
print $out "${indent}(ImageDataHash: $hashsize bytes of JPEG image data)\n" if $hashsize and $verbose;
|
7980
8022
|
# calculate JPEGDigest if requested
|
7981
8023
|
if (@dqt) {
|
7982
8024
|
require Image::ExifTool::JPEGDigest;
|
data/bin/lib/Image/ExifTool.pod
CHANGED
@@ -65,50 +65,50 @@ supported by ExifTool (r = read, w = write, c = create):
|
|
65
65
|
|
66
66
|
File Types
|
67
67
|
------------+-------------+-------------+-------------+------------
|
68
|
-
360 r/w | DOCX r | ITC r |
|
69
|
-
3FR r | DPX r | J2C r |
|
70
|
-
3G2 r/w | DR4 r/w/c | JNG r/w |
|
71
|
-
3GP r/w | DSS r | JP2 r/w |
|
72
|
-
7Z r | DV r | JPEG r/w |
|
73
|
-
A r | DVB r/w | JSON r |
|
74
|
-
AA r | DVR-MS r | JXL r/w |
|
75
|
-
AAC r | DYLIB r | K25 r |
|
76
|
-
AAE r | EIP r | KDC r |
|
77
|
-
AAX r/w | EPS r/w | KEY r |
|
78
|
-
ACR r | EPUB r | LA r |
|
79
|
-
AFM r | ERF r/w | LFP r |
|
80
|
-
AI r/w | EXE r | LIF r |
|
81
|
-
AIFF r | EXIF r/w/c | LNK r |
|
82
|
-
APE r | EXR r | LRV r/w |
|
83
|
-
ARQ r/w | EXV r/w/c | M2TS r |
|
84
|
-
ARW r/w | F4A/V r/w | M4A/V r/w |
|
85
|
-
ASF r | FFF r/w | MACOS r |
|
86
|
-
AVI r | FITS r | MAX r |
|
87
|
-
AVIF r/w | FLA r | MEF r/w |
|
88
|
-
AZW r | FLAC r | MIE r/w/c |
|
89
|
-
BMP r | FLIF r/w | MIFF r |
|
90
|
-
BPG r | FLV r | MKA r |
|
91
|
-
BTF r | FPF r | MKS r |
|
92
|
-
C2PA r | FPX r | MKV r |
|
93
|
-
CHM r | GIF r/w | MNG r/w |
|
94
|
-
COS r | GLV r/w | MOBI r |
|
95
|
-
CR2 r/w | GPR r/w | MODD r |
|
96
|
-
CR3 r/w | GZ r | MOI r |
|
97
|
-
CRM r/w | HDP r/w | MOS r/w |
|
98
|
-
CRW r/w | HDR r | MOV r/w |
|
99
|
-
CS1 r/w | HEIC r/w | MP3 r |
|
100
|
-
CSV r | HEIF r/w | MP4 r/w |
|
101
|
-
CUR r | HTML r | MPC r |
|
102
|
-
CZI r | ICC r/w/c | MPG r |
|
103
|
-
DCM r | ICO r | MPO r/w |
|
104
|
-
DCP r/w | ICS r | MQV r/w |
|
105
|
-
DCR r | IDML r | MRC r |
|
106
|
-
DFONT r | IIQ r/w | MRW r/w |
|
107
|
-
DIVX r | IND r/w | MXF r |
|
108
|
-
DJVU r | INSP r/w | NEF r/w |
|
109
|
-
DLL r | INSV r |
|
110
|
-
DNG r/w | INX r |
|
111
|
-
DOC r | ISO r |
|
68
|
+
360 r/w | DOCX r | ITC r | NUMBERS r | RAW r/w
|
69
|
+
3FR r | DPX r | J2C r | NXD r | RIFF r
|
70
|
+
3G2 r/w | DR4 r/w/c | JNG r/w | O r | RSRC r
|
71
|
+
3GP r/w | DSS r | JP2 r/w | ODP r | RTF r
|
72
|
+
7Z r | DV r | JPEG r/w | ODS r | RW2 r/w
|
73
|
+
A r | DVB r/w | JSON r | ODT r | RWL r/w
|
74
|
+
AA r | DVR-MS r | JXL r/w | OFR r | RWZ r
|
75
|
+
AAC r | DYLIB r | K25 r | OGG r | RM r
|
76
|
+
AAE r | EIP r | KDC r | OGV r | SEQ r
|
77
|
+
AAX r/w | EPS r/w | KEY r | ONP r | SKETCH r
|
78
|
+
ACR r | EPUB r | LA r | OPUS r | SO r
|
79
|
+
AFM r | ERF r/w | LFP r | ORF r/w | SR2 r/w
|
80
|
+
AI r/w | EXE r | LIF r | ORI r/w | SRF r
|
81
|
+
AIFF r | EXIF r/w/c | LNK r | OTF r | SRW r/w
|
82
|
+
APE r | EXR r | LRV r/w | PAC r | SVG r
|
83
|
+
ARQ r/w | EXV r/w/c | M2TS r | PAGES r | SWF r
|
84
|
+
ARW r/w | F4A/V r/w | M4A/V r/w | PBM r/w | THM r/w
|
85
|
+
ASF r | FFF r/w | MACOS r | PCD r | TIFF r/w
|
86
|
+
AVI r | FITS r | MAX r | PCX r | TORRENT r
|
87
|
+
AVIF r/w | FLA r | MEF r/w | PDB r | TTC r
|
88
|
+
AZW r | FLAC r | MIE r/w/c | PDF r/w | TTF r
|
89
|
+
BMP r | FLIF r/w | MIFF r | PEF r/w | TXT r
|
90
|
+
BPG r | FLV r | MKA r | PFA r | VCF r
|
91
|
+
BTF r | FPF r | MKS r | PFB r | VNT r
|
92
|
+
C2PA r | FPX r | MKV r | PFM r | VRD r/w/c
|
93
|
+
CHM r | GIF r/w | MNG r/w | PGF r | VSD r
|
94
|
+
COS r | GLV r/w | MOBI r | PGM r/w | WAV r
|
95
|
+
CR2 r/w | GPR r/w | MODD r | PLIST r | WDP r/w
|
96
|
+
CR3 r/w | GZ r | MOI r | PICT r | WEBP r/w
|
97
|
+
CRM r/w | HDP r/w | MOS r/w | PMP r | WEBM r
|
98
|
+
CRW r/w | HDR r | MOV r/w | PNG r/w | WMA r
|
99
|
+
CS1 r/w | HEIC r/w | MP3 r | PPM r/w | WMV r
|
100
|
+
CSV r | HEIF r/w | MP4 r/w | PPT r | WPG r
|
101
|
+
CUR r | HTML r | MPC r | PPTX r | WTV r
|
102
|
+
CZI r | ICC r/w/c | MPG r | PS r/w | WV r
|
103
|
+
DCM r | ICO r | MPO r/w | PSB r/w | X3F r/w
|
104
|
+
DCP r/w | ICS r | MQV r/w | PSD r/w | XCF r
|
105
|
+
DCR r | IDML r | MRC r | PSP r | XISF r
|
106
|
+
DFONT r | IIQ r/w | MRW r/w | QTIF r/w | XLS r
|
107
|
+
DIVX r | IND r/w | MXF r | R3D r | XLSX r
|
108
|
+
DJVU r | INSP r/w | NEF r/w | RA r | XMP r/w/c
|
109
|
+
DLL r | INSV r | NKA r | RAF r/w | ZIP r
|
110
|
+
DNG r/w | INX r | NKSC r/w | RAM r |
|
111
|
+
DOC r | ISO r | NRW r/w | RAR r |
|
112
112
|
|
113
113
|
Meta Information
|
114
114
|
----------------------+----------------------+---------------------
|
@@ -715,6 +715,13 @@ value to be added to the maker notes base offset. It may also be set to the
|
|
715
715
|
empty string ('') for ExifTool will take its best guess at the correct base,
|
716
716
|
or undef (the default) for no base adjustment.
|
717
717
|
|
718
|
+
=item GeoDir
|
719
|
+
|
720
|
+
[Not a real option] Provided as a convenience to allow
|
721
|
+
$Image::ExifTool::geoDir to be set at runtime. This variable specifies the
|
722
|
+
directory for the Geolocation databases, and is used only once when these
|
723
|
+
databases are loaded.
|
724
|
+
|
718
725
|
=item Geolocation
|
719
726
|
|
720
727
|
Flag to generate geolocation tags based on the GPSLatitude/GPSLongitude or
|
@@ -738,9 +745,10 @@ use of the alternate names. Default is 1.
|
|
738
745
|
|
739
746
|
Comma-separated list of feature codes to include in city search, or exclude
|
740
747
|
if the list begins with a dash (-). Valid feature codes are PPL, PPLA,
|
741
|
-
PPLA2, PPLA3, PPLA4, PPLA5, PPLC, PPLCH, PPLF, PPLG, PPLL,
|
742
|
-
and Other
|
743
|
-
|
748
|
+
PPLA2, PPLA3, PPLA4, PPLA5, PPLC, PPLCH, PPLF, PPLG, PPLH, PPLL, PPLQ, PPLR,
|
749
|
+
PPLS, PPLW, PPLX, STLMT and Other, plus possible user-include codes if an
|
750
|
+
alternate database is used. See L<http://www.geonames.org/export/codes.html#P>
|
751
|
+
for a description of these codes. Default is undef.
|
744
752
|
|
745
753
|
=item GeolocMaxDist
|
746
754
|
|
@@ -1105,10 +1113,12 @@ Output file reference for Verbose and HtmlDump options. Default is
|
|
1105
1113
|
|
1106
1114
|
=item TimeZone
|
1107
1115
|
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1116
|
+
Set the time zone for local date/time values. The value is a time zone
|
1117
|
+
offset like "+05:00" (but note that the offset is to UTC, not from UTC, so
|
1118
|
+
it is positive for western time zones), or a time zone name like "EST5EDT".
|
1119
|
+
For Unix-based systems, the value may also be a time zone ID like
|
1120
|
+
"America/New_York". Requires Time::Piece on Windows, or POSIX::tzset on
|
1121
|
+
other systems. Default is undef.
|
1112
1122
|
|
1113
1123
|
=item Unknown
|
1114
1124
|
|