exiftool_vendored 11.94.0 → 12.06.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
|
}
|