exiftool_vendored 11.94.0 → 12.06.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of exiftool_vendored might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/bin/Changes +163 -3
- data/bin/MANIFEST +5 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +32 -32
- data/bin/exiftool +152 -52
- data/bin/lib/Image/ExifTool.pm +166 -115
- data/bin/lib/Image/ExifTool.pod +108 -81
- data/bin/lib/Image/ExifTool/AIFF.pm +2 -2
- data/bin/lib/Image/ExifTool/APE.pm +2 -2
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +13 -7
- data/bin/lib/Image/ExifTool/Canon.pm +6 -3
- data/bin/lib/Image/ExifTool/CanonCustom.pm +82 -16
- data/bin/lib/Image/ExifTool/DPX.pm +56 -2
- data/bin/lib/Image/ExifTool/DarwinCore.pm +16 -3
- data/bin/lib/Image/ExifTool/Exif.pm +15 -6
- data/bin/lib/Image/ExifTool/Font.pm +9 -2
- data/bin/lib/Image/ExifTool/GIF.pm +5 -0
- data/bin/lib/Image/ExifTool/GeoTiff.pm +2 -0
- data/bin/lib/Image/ExifTool/Geotag.pm +69 -21
- data/bin/lib/Image/ExifTool/GoPro.pm +10 -1
- data/bin/lib/Image/ExifTool/H264.pm +1 -1
- data/bin/lib/Image/ExifTool/HtmlDump.pm +2 -2
- data/bin/lib/Image/ExifTool/ID3.pm +91 -12
- data/bin/lib/Image/ExifTool/Lang/de.pm +3 -1
- data/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
- data/bin/lib/Image/ExifTool/M2TS.pm +44 -24
- data/bin/lib/Image/ExifTool/MWG.pm +9 -1
- data/bin/lib/Image/ExifTool/MacOS.pm +1 -1
- data/bin/lib/Image/ExifTool/Minolta.pm +3 -2
- data/bin/lib/Image/ExifTool/MinoltaRaw.pm +11 -10
- data/bin/lib/Image/ExifTool/Nikon.pm +156 -18
- data/bin/lib/Image/ExifTool/Olympus.pm +34 -17
- data/bin/lib/Image/ExifTool/PNG.pm +14 -3
- data/bin/lib/Image/ExifTool/PPM.pm +5 -5
- data/bin/lib/Image/ExifTool/Panasonic.pm +147 -13
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +33 -0
- data/bin/lib/Image/ExifTool/Parrot.pm +2 -1
- data/bin/lib/Image/ExifTool/Pentax.pm +3 -1
- data/bin/lib/Image/ExifTool/Photoshop.pm +2 -1
- data/bin/lib/Image/ExifTool/QuickTime.pm +277 -33
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +460 -67
- data/bin/lib/Image/ExifTool/README +21 -20
- data/bin/lib/Image/ExifTool/RIFF.pm +123 -3
- data/bin/lib/Image/ExifTool/RTF.pm +12 -7
- data/bin/lib/Image/ExifTool/Ricoh.pm +19 -1
- data/bin/lib/Image/ExifTool/Shift.pl +1 -0
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +40 -33
- data/bin/lib/Image/ExifTool/Sony.pm +379 -12
- data/bin/lib/Image/ExifTool/TagLookup.pm +1959 -1874
- data/bin/lib/Image/ExifTool/TagNames.pod +346 -55
- data/bin/lib/Image/ExifTool/Validate.pm +4 -4
- data/bin/lib/Image/ExifTool/WriteExif.pl +3 -2
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +26 -15
- data/bin/lib/Image/ExifTool/Writer.pl +52 -23
- data/bin/lib/Image/ExifTool/XMP.pm +41 -4
- data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
- data/bin/lib/Image/ExifTool/ZISRAW.pm +123 -0
- data/bin/perl-Image-ExifTool.spec +31 -31
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +4 -4
data/bin/lib/Image/ExifTool.pm
CHANGED
@@ -28,7 +28,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
|
|
28
28
|
%mimeType $swapBytes $swapWords $currentByteOrder %unpackStd
|
29
29
|
%jpegMarker %specialTags %fileTypeLookup $testLen $exePath);
|
30
30
|
|
31
|
-
$VERSION = '
|
31
|
+
$VERSION = '12.06';
|
32
32
|
$RELEASE = '';
|
33
33
|
@ISA = qw(Exporter);
|
34
34
|
%EXPORT_TAGS = (
|
@@ -91,7 +91,7 @@ sub GetExtended($$);
|
|
91
91
|
sub Set64u(@);
|
92
92
|
sub DecodeBits($$;$);
|
93
93
|
sub EncodeBits($$;$$);
|
94
|
-
sub Filter(
|
94
|
+
sub Filter($$$);
|
95
95
|
sub HexDump($;$%);
|
96
96
|
sub DumpTrailer($$);
|
97
97
|
sub DumpUnknownTrailer($$);
|
@@ -137,17 +137,18 @@ sub ReadValue($$$;$$$);
|
|
137
137
|
@loadAllTables = qw(
|
138
138
|
PhotoMechanic Exif GeoTiff CanonRaw KyoceraRaw Lytro MinoltaRaw PanasonicRaw
|
139
139
|
SigmaRaw JPEG GIMP Jpeg2000 GIF BMP BMP::OS2 BMP::Extra BPG BPG::Extensions
|
140
|
-
PICT PNG MNG FLIF DjVu DPX OpenEXR MIFF PCX PGF PSP PhotoCD Radiance
|
141
|
-
PostScript Photoshop::Header Photoshop::Layers Photoshop::ImageData
|
140
|
+
PICT PNG MNG FLIF DjVu DPX OpenEXR ZISRAW MIFF PCX PGF PSP PhotoCD Radiance
|
141
|
+
PDF PostScript Photoshop::Header Photoshop::Layers Photoshop::ImageData
|
142
142
|
FujiFilm::RAF FujiFilm::IFD Samsung::Trailer Sony::SRF2 Sony::SR2SubIFD
|
143
|
-
Sony::PMP ITC ID3 FLAC Ogg Vorbis APE APE::NewHeader
|
144
|
-
MPC MPEG::Audio MPEG::Video MPEG::Xing M2TS QuickTime
|
145
|
-
QuickTime::Stream Matroska MOI
|
146
|
-
Real::Audio Real::Metafile Red RIFF AIFF
|
147
|
-
XMP::SVG Palm Palm::MOBI Palm::EXTH Torrent
|
148
|
-
EXE::MachO EXE::PEF EXE::ELF EXE::AR
|
149
|
-
VCard::VCalendar RSRC Rawzor ZIP ZIP::GZIP
|
150
|
-
FLIR::AFF FLIR::FPF MacOS::MDItem MacOS::XAttr
|
143
|
+
Sony::PMP ITC ID3 ID3::Lyrics3 FLAC Ogg Vorbis APE APE::NewHeader
|
144
|
+
APE::OldHeader Audible MPC MPEG::Audio MPEG::Video MPEG::Xing M2TS QuickTime
|
145
|
+
QuickTime::ImageFile QuickTime::Stream QuickTime::Tags360Fly Matroska MOI
|
146
|
+
MXF DV Flash Flash::FLV Real::Media Real::Audio Real::Metafile Red RIFF AIFF
|
147
|
+
ASF WTV DICOM FITS MIE JSON HTML XMP::SVG Palm Palm::MOBI Palm::EXTH Torrent
|
148
|
+
EXE EXE::PEVersion EXE::PEString EXE::MachO EXE::PEF EXE::ELF EXE::AR
|
149
|
+
EXE::CHM LNK Font VCard Text VCard::VCalendar RSRC Rawzor ZIP ZIP::GZIP
|
150
|
+
ZIP::RAR RTF OOXML iWork ISO FLIR::AFF FLIR::FPF MacOS::MDItem MacOS::XAttr
|
151
|
+
FlashPix::DocTable
|
151
152
|
);
|
152
153
|
|
153
154
|
# alphabetical list of current Lang modules
|
@@ -186,9 +187,9 @@ $defaultLang = 'en'; # default language
|
|
186
187
|
PSD XMP BMP BPG PPM RIFF AIFF ASF MOV MPEG Real SWF PSP FLV OGG
|
187
188
|
FLAC APE MPC MKV MXF DV PMP IND PGF ICC ITC FLIR FLIF FPF LFP
|
188
189
|
HTML VRD RTF FITS XCF DSS QTIF FPX PICT ZIP GZIP PLIST RAR BZ2
|
189
|
-
TAR EXE EXR HDR CHM LNK WMF AVC DEX DPX RAW Font RSRC M2TS
|
190
|
-
PCX DCX DWF DWG WTV Torrent VCard LRI R3D AA PDB MOI ISO
|
191
|
-
JSON MP3 DICOM PCD TXT);
|
190
|
+
CZI TAR EXE EXR HDR CHM LNK WMF AVC DEX DPX RAW Font RSRC M2TS
|
191
|
+
PHP PCX DCX DWF DWG WTV Torrent VCard LRI R3D AA PDB MOI ISO
|
192
|
+
ALIAS JSON MP3 DICOM PCD TXT);
|
192
193
|
|
193
194
|
# file types that we can write (edit)
|
194
195
|
my @writeTypes = qw(JPEG TIFF GIF CRW MRW ORF RAF RAW PNG MIE PSD XMP PPM EPS
|
@@ -253,6 +254,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
253
254
|
CRW => ['CRW', 'Canon RAW format'],
|
254
255
|
CS1 => ['PSD', 'Sinar CaptureShop 1-Shot RAW'],
|
255
256
|
CSV => ['TXT', 'Comma-Separated Values'],
|
257
|
+
CZI => ['CZI', 'Zeiss Integrated Software RAW'],
|
256
258
|
DC3 => 'DICM',
|
257
259
|
DCM => 'DICM',
|
258
260
|
DCP => ['TIFF', 'DNG Camera Profile'],
|
@@ -527,6 +529,8 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
527
529
|
XLTM => [['ZIP','FPX'], 'Office Open XML Spreadsheet Template Macro-enabled'],
|
528
530
|
XLTX => [['ZIP','FPX'], 'Office Open XML Spreadsheet Template'],
|
529
531
|
XMP => ['XMP', 'Extensible Metadata Platform'],
|
532
|
+
WOFF => ['Font', 'Web Open Font Format'],
|
533
|
+
WOFF2=> ['Font', 'Web Open Font Format2'],
|
530
534
|
WTV => ['WTV', 'Windows recorded TV show'],
|
531
535
|
ZIP => ['ZIP', 'ZIP archive'],
|
532
536
|
);
|
@@ -581,6 +585,7 @@ my %fileDescription = (
|
|
581
585
|
CRM => 'video/x-canon-crm',
|
582
586
|
CRW => 'image/x-canon-crw',
|
583
587
|
CSV => 'text/csv',
|
588
|
+
CZI => 'image/x-zeiss-czi', #PH (NC)
|
584
589
|
DCP => 'application/octet-stream', #PH (NC)
|
585
590
|
DCR => 'image/x-kodak-dcr',
|
586
591
|
DCX => 'image/dcx',
|
@@ -781,6 +786,7 @@ my %moduleName = (
|
|
781
786
|
CRW => 'CanonRaw',
|
782
787
|
CHM => 'EXE',
|
783
788
|
COS => 'CaptureOne',
|
789
|
+
CZI => 'ZISRAW',
|
784
790
|
DEX => 0,
|
785
791
|
DOCX => 'OOXML',
|
786
792
|
DCX => 0,
|
@@ -851,6 +857,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
851
857
|
BZ2 => 'BZh[1-9]\x31\x41\x59\x26\x53\x59',
|
852
858
|
CHM => 'ITSF.{20}\x10\xfd\x01\x7c\xaa\x7b\xd0\x11\x9e\x0c\0\xa0\xc9\x22\xe6\xec',
|
853
859
|
CRW => '(II|MM).{4}HEAP(CCDR|JPGM)',
|
860
|
+
CZI => 'ZISRAWFILE\0{6}',
|
854
861
|
DCX => '\xb1\x68\xde\x3a',
|
855
862
|
DEX => "dex\n035\0",
|
856
863
|
DICOM=> '(.{128}DICM|\0[\x02\x04\x06\x08]\0[\0-\x20]|[\x02\x04\x06\x08]\0[\0-\x20]\0)',
|
@@ -872,7 +879,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
872
879
|
FLIR => '[AF]FF\0',
|
873
880
|
FLV => 'FLV\x01',
|
874
881
|
Font => '((\0\x01\0\0|OTTO|true|typ1)[\0\x01]|ttcf\0[\x01\x02]\0\0|\0[\x01\x02]|' .
|
875
|
-
'(.{6})?%!(PS-(AdobeFont-|Bitstream )|FontType1-)|Start(Comp|Master)?FontMetrics)',
|
882
|
+
'(.{6})?%!(PS-(AdobeFont-|Bitstream )|FontType1-)|Start(Comp|Master)?FontMetrics|wOF[F2])',
|
876
883
|
FPF => 'FPF Public Image Format\0',
|
877
884
|
FPX => '\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1',
|
878
885
|
GIF => 'GIF8[79]a',
|
@@ -1445,6 +1452,11 @@ my %systemTagsNotes = (
|
|
1445
1452
|
return Image::ExifTool::XMP::CheckXMP($self, $tagInfo, \$val);
|
1446
1453
|
},
|
1447
1454
|
},
|
1455
|
+
XML => {
|
1456
|
+
Notes => 'the XML data block, extracted for some file types',
|
1457
|
+
Groups => { 0 => 'XML', 1 => 'XML' },
|
1458
|
+
Binary => 1,
|
1459
|
+
},
|
1448
1460
|
ICC_Profile => {
|
1449
1461
|
Notes => q{
|
1450
1462
|
the full ICC_Profile data block. This tag is generated only if specifically
|
@@ -2236,6 +2248,7 @@ sub ClearOptions($)
|
|
2236
2248
|
GeoSpeedRef => undef, # geotag GPSSpeedRef
|
2237
2249
|
GlobalTimeShift => undef, # apply time shift to all extracted date/time values
|
2238
2250
|
# Group# => undef, # return tags for specified groups in family #
|
2251
|
+
HexTagIDs => 0, # use hex tag ID's in family 7 group names
|
2239
2252
|
HtmlDump => 0, # HTML dump (0-3, higher # = bigger limit)
|
2240
2253
|
HtmlDumpBase => undef, # base address for HTML dump
|
2241
2254
|
IgnoreMinorErrors => undef, # ignore minor errors when reading/writing
|
@@ -2249,6 +2262,7 @@ sub ClearOptions($)
|
|
2249
2262
|
MakerNotes => undef, # extract maker notes as a block
|
2250
2263
|
MDItemTags => undef, # extract MacOS metadata item tags
|
2251
2264
|
MissingTagValue =>undef,# value for missing tags when expanded in expressions
|
2265
|
+
NoMultiExif => undef, # raise error when writing multi-segment EXIF
|
2252
2266
|
NoPDFList => undef, # flag to avoid splitting PDF List-type tag values
|
2253
2267
|
Password => undef, # password for password-protected PDF documents
|
2254
2268
|
PrintConv => 1, # flag to enable print conversion
|
@@ -3095,30 +3109,9 @@ sub GetValue($$;$)
|
|
3095
3109
|
}
|
3096
3110
|
if (ref $conv eq 'HASH') {
|
3097
3111
|
# look up converted value in hash
|
3098
|
-
|
3099
|
-
if (defined($value = $$conv{$val})) {
|
3100
|
-
# override with our localized language PrintConv if available
|
3101
|
-
if ($$self{CUR_LANG} and $convType eq 'PrintConv' and
|
3102
|
-
# (no need to check for lang-alt tag names -- they won't have a PrintConv)
|
3103
|
-
ref($lc = $$self{CUR_LANG}{$$tagInfo{Name}}) eq 'HASH' and
|
3104
|
-
($lc = $$lc{PrintConv}) and ($lc = $$lc{$value}))
|
3105
|
-
{
|
3106
|
-
$value = $self->Decode($lc, 'UTF8');
|
3107
|
-
}
|
3108
|
-
} else {
|
3112
|
+
if (not defined($value = $$conv{$val})) {
|
3109
3113
|
if ($$conv{BITMASK}) {
|
3110
3114
|
$value = DecodeBits($val, $$conv{BITMASK}, $$tagInfo{BitsPerWord});
|
3111
|
-
# override with localized language strings
|
3112
|
-
if (defined $value and $$self{CUR_LANG} and $convType eq 'PrintConv' and
|
3113
|
-
ref($lc = $$self{CUR_LANG}{$$tagInfo{Name}}) eq 'HASH' and
|
3114
|
-
($lc = $$lc{PrintConv}))
|
3115
|
-
{
|
3116
|
-
my @vals = split ', ', $value;
|
3117
|
-
foreach (@vals) {
|
3118
|
-
$_ = $$lc{$_} if defined $$lc{$_};
|
3119
|
-
}
|
3120
|
-
$value = join ', ', @vals;
|
3121
|
-
}
|
3122
3115
|
} else {
|
3123
3116
|
# use alternate conversion routine if available
|
3124
3117
|
if ($$conv{OTHER}) {
|
@@ -3131,12 +3124,30 @@ sub GetValue($$;$)
|
|
3131
3124
|
if ($$tagInfo{PrintHex} and $val and IsInt($val) and
|
3132
3125
|
$convType eq 'PrintConv')
|
3133
3126
|
{
|
3134
|
-
$
|
3127
|
+
$value = sprintf('Unknown (0x%x)',$val);
|
3128
|
+
} else {
|
3129
|
+
$value = "Unknown ($val)";
|
3135
3130
|
}
|
3136
|
-
$value = "Unknown ($val)";
|
3137
3131
|
}
|
3138
3132
|
}
|
3139
3133
|
}
|
3134
|
+
# override with our localized language PrintConv if available
|
3135
|
+
my $tmp;
|
3136
|
+
if ($$self{CUR_LANG} and $convType eq 'PrintConv' and
|
3137
|
+
# (no need to check for lang-alt tag names -- they won't have a PrintConv)
|
3138
|
+
ref($tmp = $$self{CUR_LANG}{$$tagInfo{Name}}) eq 'HASH' and
|
3139
|
+
($tmp = $$tmp{PrintConv}))
|
3140
|
+
{
|
3141
|
+
if ($$conv{BITMASK} and not defined $$conv{$val}) {
|
3142
|
+
my @vals = split ', ', $value;
|
3143
|
+
foreach (@vals) {
|
3144
|
+
$_ = $$tmp{$_} if defined $$tmp{$_};
|
3145
|
+
}
|
3146
|
+
$value = join ', ', @vals;
|
3147
|
+
} elsif (defined($tmp = $$tmp{$value})) {
|
3148
|
+
$value = $self->Decode($tmp, 'UTF8');
|
3149
|
+
}
|
3150
|
+
}
|
3140
3151
|
} else {
|
3141
3152
|
# call subroutine or do eval to convert value
|
3142
3153
|
local $SIG{'__WARN__'} = \&SetWarning;
|
@@ -3198,7 +3209,7 @@ sub GetValue($$;$)
|
|
3198
3209
|
# $valueConv is undefined if there was no print conversion done
|
3199
3210
|
$valueConv = $value;
|
3200
3211
|
}
|
3201
|
-
Filter($$self{OPTIONS}{Filter}, \$value);
|
3212
|
+
$self->Filter($$self{OPTIONS}{Filter}, \$value);
|
3202
3213
|
# return Both values as a list (ValueConv, PrintConv)
|
3203
3214
|
return ($valueConv, $value);
|
3204
3215
|
}
|
@@ -3206,7 +3217,7 @@ sub GetValue($$;$)
|
|
3206
3217
|
DoEscape($value, $$self{ESCAPE_PROC}) if $$self{ESCAPE_PROC};
|
3207
3218
|
|
3208
3219
|
# filter if necessary
|
3209
|
-
Filter($$self{OPTIONS}{Filter}, \$value) if $$self{OPTIONS}{Filter} and $type eq 'PrintConv';
|
3220
|
+
$self->Filter($$self{OPTIONS}{Filter}, \$value) if $$self{OPTIONS}{Filter} and $type eq 'PrintConv';
|
3210
3221
|
|
3211
3222
|
if (ref $value eq 'ARRAY') {
|
3212
3223
|
if (defined $$self{OPTIONS}{ListItem}) {
|
@@ -3294,7 +3305,7 @@ sub GetGroup($$;$)
|
|
3294
3305
|
{
|
3295
3306
|
local $_;
|
3296
3307
|
my ($self, $tag, $family) = @_;
|
3297
|
-
my ($tagInfo, @groups, @families, $simplify, $byTagInfo, $ex);
|
3308
|
+
my ($tagInfo, @groups, @families, $simplify, $byTagInfo, $ex, $noID);
|
3298
3309
|
if (ref $tag eq 'HASH') {
|
3299
3310
|
$tagInfo = $tag;
|
3300
3311
|
$tag = $$tagInfo{Name};
|
@@ -3325,6 +3336,7 @@ sub GetGroup($$;$)
|
|
3325
3336
|
$simplify = 1 unless $family =~ /^:/;
|
3326
3337
|
undef $family;
|
3327
3338
|
foreach (0..2) { $groups[$_] = $$groups{$_}; }
|
3339
|
+
$noID = 1 if @families == 1 and $families[0] != 7;
|
3328
3340
|
} else {
|
3329
3341
|
return(($ex && $$ex{"G$family"}) || $$groups{$family}) if $family == 0 or $family == 2;
|
3330
3342
|
$groups[1] = $$groups{1};
|
@@ -3336,14 +3348,29 @@ sub GetGroup($$;$)
|
|
3336
3348
|
$groups[3] = 'Main';
|
3337
3349
|
$groups[4] = ($tag =~ /\((\d+)\)$/) ? "Copy$1" : '';
|
3338
3350
|
# handle dynamic group names if necessary
|
3339
|
-
|
3340
|
-
$
|
3341
|
-
|
3342
|
-
|
3343
|
-
|
3344
|
-
|
3345
|
-
|
3346
|
-
|
3351
|
+
unless ($byTagInfo) {
|
3352
|
+
if ($ex) {
|
3353
|
+
$groups[0] = $$ex{G0} if $$ex{G0};
|
3354
|
+
$groups[1] = $$ex{G1} =~ /^\+(.*)/ ? "$groups[1]$1" : $$ex{G1} if $$ex{G1};
|
3355
|
+
$groups[3] = 'Doc' . $$ex{G3} if $$ex{G3};
|
3356
|
+
$groups[5] = $$ex{G5} || $groups[1] if defined $$ex{G5};
|
3357
|
+
if (defined $$ex{G6}) {
|
3358
|
+
$groups[5] = '' unless defined $groups[5]; # (can't leave a hole in the array)
|
3359
|
+
$groups[6] = $$ex{G6};
|
3360
|
+
}
|
3361
|
+
}
|
3362
|
+
# generate tag ID group names unless obviously not needed
|
3363
|
+
unless ($noID) {
|
3364
|
+
my $id = $$tagInfo{TagID};
|
3365
|
+
if (not defined $id) {
|
3366
|
+
$id = ''; # (just to be safe)
|
3367
|
+
} elsif ($id =~ /^\d+$/) {
|
3368
|
+
$id = sprintf('0x%x', $id) if $$self{OPTIONS}{HexTagIDs};
|
3369
|
+
} else {
|
3370
|
+
$id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge;
|
3371
|
+
}
|
3372
|
+
$groups[7] = 'ID-' . $id;
|
3373
|
+
defined $groups[$_] or $groups[$_] = '' foreach (5,6);
|
3347
3374
|
}
|
3348
3375
|
}
|
3349
3376
|
if ($family) {
|
@@ -4191,6 +4218,22 @@ sub ParseArguments($;@)
|
|
4191
4218
|
}
|
4192
4219
|
}
|
4193
4220
|
|
4221
|
+
#------------------------------------------------------------------------------
|
4222
|
+
# Does group name match the tag ID?
|
4223
|
+
# Inputs: 0) tag ID, 1) group name (with "ID-" removed)
|
4224
|
+
# Returns: true on success
|
4225
|
+
sub IsSameID($$)
|
4226
|
+
{
|
4227
|
+
my ($id, $grp) = @_;
|
4228
|
+
return 1 if $grp eq $id; # decimal ID's or raw ID's
|
4229
|
+
if ($id =~ /^\d+$/) { # numerical numerical ID's may be in hex
|
4230
|
+
return 1 if $grp =~ s/^0x0*// and $grp eq sprintf('%x', $id);
|
4231
|
+
} else { # other ID's may conform to ExifTool group name conventions
|
4232
|
+
return 1 if $id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge and $grp eq $id;
|
4233
|
+
}
|
4234
|
+
return 0;
|
4235
|
+
}
|
4236
|
+
|
4194
4237
|
#------------------------------------------------------------------------------
|
4195
4238
|
# Get list of tags in specified group
|
4196
4239
|
# Inputs: 0) ExifTool ref, 1) group spec, 2) tag key or reference to list of tag keys
|
@@ -4202,40 +4245,41 @@ sub GroupMatches($$$)
|
|
4202
4245
|
my ($self, $group, $tagList) = @_;
|
4203
4246
|
$tagList = [ $tagList ] unless ref $tagList;
|
4204
4247
|
my ($tag, @matches);
|
4205
|
-
|
4206
|
-
|
4207
|
-
|
4208
|
-
|
4248
|
+
# check each group name individually (eg. "Author:1IPTC")
|
4249
|
+
my @grps = split ':', $group;
|
4250
|
+
my (@fmys, $g);
|
4251
|
+
for ($g=0; $g<@grps; ++$g) {
|
4252
|
+
if ($grps[$g] =~ s/^(\d*)(id-)?//i) {
|
4253
|
+
$fmys[$g] = $1 if length $1;
|
4254
|
+
if ($2) {
|
4255
|
+
$fmys[$g] = 7;
|
4256
|
+
next; # (don't convert tag ID's to lower case)
|
4257
|
+
}
|
4258
|
+
}
|
4259
|
+
$grps[$g] = lc $grps[$g];
|
4260
|
+
$grps[$g] = '' if $grps[$g] eq 'copy0'; # accept 'Copy0' for primary tag
|
4261
|
+
}
|
4262
|
+
foreach $tag (@$tagList) {
|
4263
|
+
my @groups = $self->GetGroup($tag, -1);
|
4209
4264
|
for ($g=0; $g<@grps; ++$g) {
|
4210
|
-
$
|
4211
|
-
$
|
4212
|
-
|
4213
|
-
|
4214
|
-
|
4215
|
-
|
4216
|
-
|
4217
|
-
next if $grp eq '*' or $grp eq 'all';
|
4218
|
-
if (defined $fmys[$g]) {
|
4219
|
-
my $f = $fmys[$g];
|
4220
|
-
last unless defined $groups[$f] and $grp eq lc $groups[$f];
|
4265
|
+
my $grp = $grps[$g];
|
4266
|
+
next if $grp eq '*' or $grp eq 'all';
|
4267
|
+
my $f;
|
4268
|
+
if (defined($f = $fmys[$g])) {
|
4269
|
+
last unless defined $groups[$f];
|
4270
|
+
if ($f == 7) {
|
4271
|
+
next if IsSameID($self->GetTagID($tag), $grp);
|
4221
4272
|
} else {
|
4222
|
-
|
4273
|
+
next if $grp eq lc $groups[$f];
|
4223
4274
|
}
|
4224
|
-
|
4225
|
-
|
4226
|
-
|
4227
|
-
push @matches, $tag;
|
4275
|
+
last;
|
4276
|
+
} else {
|
4277
|
+
last unless grep /^$grp$/i, @groups;
|
4228
4278
|
}
|
4229
4279
|
}
|
4230
|
-
|
4231
|
-
|
4232
|
-
|
4233
|
-
foreach $tag (@$tagList) {
|
4234
|
-
my @groups = $self->GetGroup($tag, $family);
|
4235
|
-
if (grep(/^$group$/i, @groups)) {
|
4236
|
-
return $tag unless wantarray;
|
4237
|
-
push @matches, $tag;
|
4238
|
-
}
|
4280
|
+
if ($g == @grps) {
|
4281
|
+
return $tag unless wantarray;
|
4282
|
+
push @matches, $tag;
|
4239
4283
|
}
|
4240
4284
|
}
|
4241
4285
|
return wantarray ? @matches : $matches[0];
|
@@ -4694,13 +4738,13 @@ sub AddCompositeTags($;$)
|
|
4694
4738
|
my ($module, $prefix, $tagID);
|
4695
4739
|
unless (ref $add) {
|
4696
4740
|
($prefix = $add) =~ s/.*:://;
|
4697
|
-
$prefix .= '::';
|
4698
4741
|
$module = $add;
|
4699
4742
|
$add .= '::Composite';
|
4700
4743
|
no strict 'refs';
|
4701
4744
|
$add = \%$add;
|
4745
|
+
$prefix .= '-';
|
4702
4746
|
} else {
|
4703
|
-
$prefix = 'UserDefined
|
4747
|
+
$prefix = 'UserDefined-';
|
4704
4748
|
}
|
4705
4749
|
my $defaultGroups = $$add{GROUPS};
|
4706
4750
|
my $compTable = GetTagTable('Image::ExifTool::Composite');
|
@@ -5415,35 +5459,38 @@ sub GetDescriptions($$)
|
|
5415
5459
|
|
5416
5460
|
#------------------------------------------------------------------------------
|
5417
5461
|
# Apply filter to value(s) if necessary
|
5418
|
-
# Inputs: 0) filter expression,
|
5419
|
-
# Returns:
|
5420
|
-
sub Filter(
|
5462
|
+
# Inputs: 0) ExifTool ref, 1) filter expression, 2) reference to value to filter
|
5463
|
+
# Returns: true unless a filter returned undef; changes value if necessary
|
5464
|
+
sub Filter($$$)
|
5421
5465
|
{
|
5422
5466
|
local $_;
|
5423
|
-
my $filter =
|
5424
|
-
return unless defined $filter;
|
5425
|
-
|
5426
|
-
|
5427
|
-
|
5428
|
-
|
5429
|
-
|
5430
|
-
|
5431
|
-
|
5432
|
-
|
5433
|
-
}
|
5434
|
-
|
5435
|
-
|
5436
|
-
|
5437
|
-
|
5438
|
-
|
5439
|
-
|
5440
|
-
|
5441
|
-
|
5442
|
-
|
5443
|
-
|
5444
|
-
|
5445
|
-
|
5467
|
+
my ($self, $filter, $valPt) = @_;
|
5468
|
+
return 1 unless defined $filter and defined $$valPt;
|
5469
|
+
my $rtnVal;
|
5470
|
+
if (not ref $$valPt) {
|
5471
|
+
$_ = $$valPt;
|
5472
|
+
#### eval Filter ($_, $self)
|
5473
|
+
eval $filter;
|
5474
|
+
if (defined $_) {
|
5475
|
+
$$valPt = $_;
|
5476
|
+
$rtnVal = 1;
|
5477
|
+
}
|
5478
|
+
} elsif (ref $$valPt eq 'SCALAR') {
|
5479
|
+
my $val = $$$valPt; # make a copy to avoid filtering twice
|
5480
|
+
$rtnVal = $self->Filter($filter, \$val);
|
5481
|
+
$$valPt = \$val;
|
5482
|
+
} elsif (ref $$valPt eq 'ARRAY') {
|
5483
|
+
my @val = @{$$valPt}; # make a copy to avoid filtering twice
|
5484
|
+
$self->Filter($filter, \$_) and $rtnVal = 1 foreach @val;
|
5485
|
+
$$valPt = \@val;
|
5486
|
+
} elsif (ref $$valPt eq 'HASH') {
|
5487
|
+
my %val = %{$$valPt}; # make a copy to avoid filtering twice
|
5488
|
+
$self->Filter($filter, \$val{$_}) and $rtnVal = 1 foreach keys %val;
|
5489
|
+
$$valPt = \%val;
|
5490
|
+
} else {
|
5491
|
+
$rtnVal = 1;
|
5446
5492
|
}
|
5493
|
+
return $rtnVal;
|
5447
5494
|
}
|
5448
5495
|
|
5449
5496
|
#------------------------------------------------------------------------------
|
@@ -5644,7 +5691,7 @@ sub ConvertUnixTime($;$$)
|
|
5644
5691
|
|
5645
5692
|
#------------------------------------------------------------------------------
|
5646
5693
|
# Get Unix time from EXIF-formatted date/time string with optional timezone
|
5647
|
-
# Inputs: 0) EXIF date/time string, 1) non-zero if time is local
|
5694
|
+
# Inputs: 0) EXIF date/time string, 1) non-zero if time is local, or 2 to assume UTC
|
5648
5695
|
# Returns: Unix time (seconds since 0:00 GMT Jan 1, 1970) or undefined on error
|
5649
5696
|
sub GetUnixTime($;$)
|
5650
5697
|
{
|
@@ -5655,10 +5702,14 @@ sub GetUnixTime($;$)
|
|
5655
5702
|
my ($tzStr, $tzSec) = (pop(@tm), 0);
|
5656
5703
|
# use specified timezone offset (if given) instead of local system time
|
5657
5704
|
# if we are converting a local time value
|
5658
|
-
if ($isLocal
|
5659
|
-
|
5660
|
-
|
5661
|
-
|
5705
|
+
if ($isLocal) {
|
5706
|
+
if ($tzStr =~ /(?:Z|([-+])(\d+):(\d+))/i) {
|
5707
|
+
# use specified timezone if one exists
|
5708
|
+
$tzSec = ($2 * 60 + $3) * ($1 eq '-' ? -60 : 60) if $1;
|
5709
|
+
undef $isLocal; # convert using GMT corrected for specified timezone
|
5710
|
+
} elsif ($isLocal eq '2') {
|
5711
|
+
undef $isLocal;
|
5712
|
+
}
|
5662
5713
|
}
|
5663
5714
|
$tm[1] -= 1; # convert month
|
5664
5715
|
@tm = reverse @tm; # change to order required by timelocal()
|
@@ -7550,7 +7601,7 @@ sub ProcessDirectory($$$;$)
|
|
7550
7601
|
|
7551
7602
|
#------------------------------------------------------------------------------
|
7552
7603
|
# Get Metadata path
|
7553
|
-
# Inputs: 0)
|
7604
|
+
# Inputs: 0) ExifTool object ref
|
7554
7605
|
# Return: Metadata path string
|
7555
7606
|
sub MetadataPath($)
|
7556
7607
|
{
|
@@ -8192,7 +8243,7 @@ sub VerboseDir($$;$$)
|
|
8192
8243
|
}
|
8193
8244
|
my $indent = substr($$self{INDENT}, 0, -2);
|
8194
8245
|
my $out = $$self{OPTIONS}{TextOut};
|
8195
|
-
my $str = $entries ? " with $entries entries" : '';
|
8246
|
+
my $str = ($entries or defined $entries and not $size) ? " with $entries entries" : '';
|
8196
8247
|
$str .= ", $size bytes" if $size;
|
8197
8248
|
print $out "$indent+ [$name directory$str]\n";
|
8198
8249
|
}
|