exiftool_vendored 11.97.0 → 12.09.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 +4 -4
- data/bin/Changes +196 -2
- data/bin/MANIFEST +8 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +43 -42
- data/bin/exiftool +150 -102
- data/bin/lib/Image/ExifTool.pm +162 -111
- data/bin/lib/Image/ExifTool.pod +123 -90
- 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 +21 -10
- data/bin/lib/Image/ExifTool/Canon.pm +201 -14
- 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 +22 -3
- data/bin/lib/Image/ExifTool/EXE.pm +8 -5
- 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 +6 -1
- data/bin/lib/Image/ExifTool/GeoTiff.pm +2 -0
- data/bin/lib/Image/ExifTool/Geotag.pm +2 -2
- data/bin/lib/Image/ExifTool/GoPro.pm +48 -22
- 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/IPTC.pm +1 -0
- data/bin/lib/Image/ExifTool/JSON.pm +27 -4
- 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/MacOS.pm +152 -38
- data/bin/lib/Image/ExifTool/Matroska.pm +3 -1
- data/bin/lib/Image/ExifTool/Minolta.pm +7 -2
- data/bin/lib/Image/ExifTool/MinoltaRaw.pm +11 -10
- data/bin/lib/Image/ExifTool/Nikon.pm +163 -18
- data/bin/lib/Image/ExifTool/Olympus.pm +39 -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 +148 -14
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +34 -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 +294 -34
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +419 -60
- data/bin/lib/Image/ExifTool/README +26 -22
- data/bin/lib/Image/ExifTool/RIFF.pm +15 -3
- data/bin/lib/Image/ExifTool/RSRC.pm +17 -11
- data/bin/lib/Image/ExifTool/RTF.pm +12 -7
- data/bin/lib/Image/ExifTool/Radiance.pm +7 -2
- 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 +420 -34
- data/bin/lib/Image/ExifTool/TagLookup.pm +5799 -5671
- data/bin/lib/Image/ExifTool/TagNames.pod +583 -95
- 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 -18
- data/bin/lib/Image/ExifTool/Writer.pl +44 -21
- data/bin/lib/Image/ExifTool/XMP.pm +99 -17
- data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
- data/bin/lib/Image/ExifTool/ZISRAW.pm +123 -0
- data/bin/perl-Image-ExifTool.spec +42 -41
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +8 -7
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.09';
|
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
|
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 MacOS::MDItem
|
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
|
191
|
-
JSON MP3 DICOM PCD TXT);
|
190
|
+
CZI TAR EXE EXR HDR CHM LNK WMF AVC DEX DPX RAW Font RSRC M2TS
|
191
|
+
MacOS PHP PCX DCX DWF DWG WTV Torrent VCard LRI R3D AA PDB MOI
|
192
|
+
ISO 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
|
@@ -207,10 +208,11 @@ my %writeTypes; # lookup for writable file types (hash filled if required)
|
|
207
208
|
# - must update CanCreate() documentation if this list is changed!
|
208
209
|
my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
209
210
|
|
210
|
-
# file type lookup for all recognized file extensions
|
211
|
+
# file type lookup for all recognized file extensions (upper case)
|
211
212
|
# (if extension may be more than one type, the type is a list where
|
212
213
|
# the writable type should come first if it exists)
|
213
214
|
%fileTypeLookup = (
|
215
|
+
'360' => ['MOV', 'GoPro 360 video'],
|
214
216
|
'3FR' => ['TIFF', 'Hasselblad RAW format'],
|
215
217
|
'3G2' => ['MOV', '3rd Gen. Partnership Project 2 audio/video'],
|
216
218
|
'3GP' => ['MOV', '3rd Gen. Partnership Project audio/video'],
|
@@ -253,6 +255,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
253
255
|
CRW => ['CRW', 'Canon RAW format'],
|
254
256
|
CS1 => ['PSD', 'Sinar CaptureShop 1-Shot RAW'],
|
255
257
|
CSV => ['TXT', 'Comma-Separated Values'],
|
258
|
+
CZI => ['CZI', 'Zeiss Integrated Software RAW'],
|
256
259
|
DC3 => 'DICM',
|
257
260
|
DCM => 'DICM',
|
258
261
|
DCP => ['TIFF', 'DNG Camera Profile'],
|
@@ -410,6 +413,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
410
413
|
OFR => ['RIFF', 'OptimFROG audio'],
|
411
414
|
OGG => ['OGG', 'Ogg Vorbis audio file'],
|
412
415
|
OGV => ['OGG', 'Ogg Video file'],
|
416
|
+
ONP => ['JSON', 'ON1 Presets'],
|
413
417
|
OPUS => ['OGG', 'Ogg Opus audio file'],
|
414
418
|
ORF => ['ORF', 'Olympus RAW format'],
|
415
419
|
OTF => ['Font', 'Open Type Font'],
|
@@ -515,6 +519,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
515
519
|
WMV => ['ASF', 'Windows Media Video'],
|
516
520
|
WV => ['RIFF', 'WavePack lossless audio'],
|
517
521
|
X3F => ['X3F', 'Sigma RAW format'],
|
522
|
+
MACOS=> ['MacOS','MacOS ._ sidecar file'],
|
518
523
|
XCF => ['XCF', 'GIMP native image format'],
|
519
524
|
XHTML=> ['HTML', 'Extensible HyperText Markup Language'],
|
520
525
|
XLA => ['FPX', 'Microsoft Excel Add-in'],
|
@@ -527,6 +532,8 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
527
532
|
XLTM => [['ZIP','FPX'], 'Office Open XML Spreadsheet Template Macro-enabled'],
|
528
533
|
XLTX => [['ZIP','FPX'], 'Office Open XML Spreadsheet Template'],
|
529
534
|
XMP => ['XMP', 'Extensible Metadata Platform'],
|
535
|
+
WOFF => ['Font', 'Web Open Font Format'],
|
536
|
+
WOFF2=> ['Font', 'Web Open Font Format2'],
|
530
537
|
WTV => ['WTV', 'Windows recorded TV show'],
|
531
538
|
ZIP => ['ZIP', 'ZIP archive'],
|
532
539
|
);
|
@@ -581,6 +588,7 @@ my %fileDescription = (
|
|
581
588
|
CRM => 'video/x-canon-crm',
|
582
589
|
CRW => 'image/x-canon-crw',
|
583
590
|
CSV => 'text/csv',
|
591
|
+
CZI => 'image/x-zeiss-czi', #PH (NC)
|
584
592
|
DCP => 'application/octet-stream', #PH (NC)
|
585
593
|
DCR => 'image/x-kodak-dcr',
|
586
594
|
DCX => 'image/dcx',
|
@@ -681,6 +689,7 @@ my %fileDescription = (
|
|
681
689
|
ODT => 'application/vnd.oasis.opendocument.text',
|
682
690
|
OGG => 'audio/ogg',
|
683
691
|
OGV => 'video/ogg',
|
692
|
+
ONP => 'application/on1',
|
684
693
|
ORF => 'image/x-olympus-orf',
|
685
694
|
OTF => 'application/x-font-otf',
|
686
695
|
PAGES=> 'application/x-iwork-pages-sffpages',
|
@@ -781,6 +790,7 @@ my %moduleName = (
|
|
781
790
|
CRW => 'CanonRaw',
|
782
791
|
CHM => 'EXE',
|
783
792
|
COS => 'CaptureOne',
|
793
|
+
CZI => 'ZISRAW',
|
784
794
|
DEX => 0,
|
785
795
|
DOCX => 'OOXML',
|
786
796
|
DCX => 0,
|
@@ -851,6 +861,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
851
861
|
BZ2 => 'BZh[1-9]\x31\x41\x59\x26\x53\x59',
|
852
862
|
CHM => 'ITSF.{20}\x10\xfd\x01\x7c\xaa\x7b\xd0\x11\x9e\x0c\0\xa0\xc9\x22\xe6\xec',
|
853
863
|
CRW => '(II|MM).{4}HEAP(CCDR|JPGM)',
|
864
|
+
CZI => 'ZISRAWFILE\0{6}',
|
854
865
|
DCX => '\xb1\x68\xde\x3a',
|
855
866
|
DEX => "dex\n035\0",
|
856
867
|
DICOM=> '(.{128}DICM|\0[\x02\x04\x06\x08]\0[\0-\x20]|[\x02\x04\x06\x08]\0[\0-\x20]\0)',
|
@@ -872,7 +883,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
872
883
|
FLIR => '[AF]FF\0',
|
873
884
|
FLV => 'FLV\x01',
|
874
885
|
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)',
|
886
|
+
'(.{6})?%!(PS-(AdobeFont-|Bitstream )|FontType1-)|Start(Comp|Master)?FontMetrics|wOF[F2])',
|
876
887
|
FPF => 'FPF Public Image Format\0',
|
877
888
|
FPX => '\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1',
|
878
889
|
GIF => 'GIF8[79]a',
|
@@ -935,6 +946,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
935
946
|
WMF => '(\xd7\xcd\xc6\x9a\0\0|\x01\0\x09\0\0\x03)',
|
936
947
|
WTV => '\xb7\xd8\x00\x20\x37\x49\xda\x11\xa6\x4e\x00\x07\xe9\x5e\xad\x8d',
|
937
948
|
X3F => 'FOVb',
|
949
|
+
MacOS=> '\0\x05\x16\x07\0.\0\0Mac OS X ',
|
938
950
|
XCF => 'gimp xcf ',
|
939
951
|
XMP => '\0{0,3}(\xfe\xff|\xff\xfe|\xef\xbb\xbf)?\0{0,3}\s*<',
|
940
952
|
ZIP => 'PK\x03\x04',
|
@@ -1445,6 +1457,11 @@ my %systemTagsNotes = (
|
|
1445
1457
|
return Image::ExifTool::XMP::CheckXMP($self, $tagInfo, \$val);
|
1446
1458
|
},
|
1447
1459
|
},
|
1460
|
+
XML => {
|
1461
|
+
Notes => 'the XML data block, extracted for some file types',
|
1462
|
+
Groups => { 0 => 'XML', 1 => 'XML' },
|
1463
|
+
Binary => 1,
|
1464
|
+
},
|
1448
1465
|
ICC_Profile => {
|
1449
1466
|
Notes => q{
|
1450
1467
|
the full ICC_Profile data block. This tag is generated only if specifically
|
@@ -2236,6 +2253,7 @@ sub ClearOptions($)
|
|
2236
2253
|
GeoSpeedRef => undef, # geotag GPSSpeedRef
|
2237
2254
|
GlobalTimeShift => undef, # apply time shift to all extracted date/time values
|
2238
2255
|
# Group# => undef, # return tags for specified groups in family #
|
2256
|
+
HexTagIDs => 0, # use hex tag ID's in family 7 group names
|
2239
2257
|
HtmlDump => 0, # HTML dump (0-3, higher # = bigger limit)
|
2240
2258
|
HtmlDumpBase => undef, # base address for HTML dump
|
2241
2259
|
IgnoreMinorErrors => undef, # ignore minor errors when reading/writing
|
@@ -2249,6 +2267,7 @@ sub ClearOptions($)
|
|
2249
2267
|
MakerNotes => undef, # extract maker notes as a block
|
2250
2268
|
MDItemTags => undef, # extract MacOS metadata item tags
|
2251
2269
|
MissingTagValue =>undef,# value for missing tags when expanded in expressions
|
2270
|
+
NoMultiExif => undef, # raise error when writing multi-segment EXIF
|
2252
2271
|
NoPDFList => undef, # flag to avoid splitting PDF List-type tag values
|
2253
2272
|
Password => undef, # password for password-protected PDF documents
|
2254
2273
|
PrintConv => 1, # flag to enable print conversion
|
@@ -3095,30 +3114,9 @@ sub GetValue($$;$)
|
|
3095
3114
|
}
|
3096
3115
|
if (ref $conv eq 'HASH') {
|
3097
3116
|
# 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 {
|
3117
|
+
if (not defined($value = $$conv{$val})) {
|
3109
3118
|
if ($$conv{BITMASK}) {
|
3110
3119
|
$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
3120
|
} else {
|
3123
3121
|
# use alternate conversion routine if available
|
3124
3122
|
if ($$conv{OTHER}) {
|
@@ -3131,12 +3129,30 @@ sub GetValue($$;$)
|
|
3131
3129
|
if ($$tagInfo{PrintHex} and $val and IsInt($val) and
|
3132
3130
|
$convType eq 'PrintConv')
|
3133
3131
|
{
|
3134
|
-
$
|
3132
|
+
$value = sprintf('Unknown (0x%x)',$val);
|
3133
|
+
} else {
|
3134
|
+
$value = "Unknown ($val)";
|
3135
3135
|
}
|
3136
|
-
$value = "Unknown ($val)";
|
3137
3136
|
}
|
3138
3137
|
}
|
3139
3138
|
}
|
3139
|
+
# override with our localized language PrintConv if available
|
3140
|
+
my $tmp;
|
3141
|
+
if ($$self{CUR_LANG} and $convType eq 'PrintConv' and
|
3142
|
+
# (no need to check for lang-alt tag names -- they won't have a PrintConv)
|
3143
|
+
ref($tmp = $$self{CUR_LANG}{$$tagInfo{Name}}) eq 'HASH' and
|
3144
|
+
($tmp = $$tmp{PrintConv}))
|
3145
|
+
{
|
3146
|
+
if ($$conv{BITMASK} and not defined $$conv{$val}) {
|
3147
|
+
my @vals = split ', ', $value;
|
3148
|
+
foreach (@vals) {
|
3149
|
+
$_ = $$tmp{$_} if defined $$tmp{$_};
|
3150
|
+
}
|
3151
|
+
$value = join ', ', @vals;
|
3152
|
+
} elsif (defined($tmp = $$tmp{$value})) {
|
3153
|
+
$value = $self->Decode($tmp, 'UTF8');
|
3154
|
+
}
|
3155
|
+
}
|
3140
3156
|
} else {
|
3141
3157
|
# call subroutine or do eval to convert value
|
3142
3158
|
local $SIG{'__WARN__'} = \&SetWarning;
|
@@ -3294,7 +3310,7 @@ sub GetGroup($$;$)
|
|
3294
3310
|
{
|
3295
3311
|
local $_;
|
3296
3312
|
my ($self, $tag, $family) = @_;
|
3297
|
-
my ($tagInfo, @groups, @families, $simplify, $byTagInfo, $ex);
|
3313
|
+
my ($tagInfo, @groups, @families, $simplify, $byTagInfo, $ex, $noID);
|
3298
3314
|
if (ref $tag eq 'HASH') {
|
3299
3315
|
$tagInfo = $tag;
|
3300
3316
|
$tag = $$tagInfo{Name};
|
@@ -3325,6 +3341,7 @@ sub GetGroup($$;$)
|
|
3325
3341
|
$simplify = 1 unless $family =~ /^:/;
|
3326
3342
|
undef $family;
|
3327
3343
|
foreach (0..2) { $groups[$_] = $$groups{$_}; }
|
3344
|
+
$noID = 1 if @families == 1 and $families[0] != 7;
|
3328
3345
|
} else {
|
3329
3346
|
return(($ex && $$ex{"G$family"}) || $$groups{$family}) if $family == 0 or $family == 2;
|
3330
3347
|
$groups[1] = $$groups{1};
|
@@ -3336,14 +3353,29 @@ sub GetGroup($$;$)
|
|
3336
3353
|
$groups[3] = 'Main';
|
3337
3354
|
$groups[4] = ($tag =~ /\((\d+)\)$/) ? "Copy$1" : '';
|
3338
3355
|
# handle dynamic group names if necessary
|
3339
|
-
|
3340
|
-
$
|
3341
|
-
|
3342
|
-
|
3343
|
-
|
3344
|
-
|
3345
|
-
|
3346
|
-
|
3356
|
+
unless ($byTagInfo) {
|
3357
|
+
if ($ex) {
|
3358
|
+
$groups[0] = $$ex{G0} if $$ex{G0};
|
3359
|
+
$groups[1] = $$ex{G1} =~ /^\+(.*)/ ? "$groups[1]$1" : $$ex{G1} if $$ex{G1};
|
3360
|
+
$groups[3] = 'Doc' . $$ex{G3} if $$ex{G3};
|
3361
|
+
$groups[5] = $$ex{G5} || $groups[1] if defined $$ex{G5};
|
3362
|
+
if (defined $$ex{G6}) {
|
3363
|
+
$groups[5] = '' unless defined $groups[5]; # (can't leave a hole in the array)
|
3364
|
+
$groups[6] = $$ex{G6};
|
3365
|
+
}
|
3366
|
+
}
|
3367
|
+
# generate tag ID group names unless obviously not needed
|
3368
|
+
unless ($noID) {
|
3369
|
+
my $id = $$tagInfo{TagID};
|
3370
|
+
if (not defined $id) {
|
3371
|
+
$id = ''; # (just to be safe)
|
3372
|
+
} elsif ($id =~ /^\d+$/) {
|
3373
|
+
$id = sprintf('0x%x', $id) if $$self{OPTIONS}{HexTagIDs};
|
3374
|
+
} else {
|
3375
|
+
$id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge;
|
3376
|
+
}
|
3377
|
+
$groups[7] = 'ID-' . $id;
|
3378
|
+
defined $groups[$_] or $groups[$_] = '' foreach (5,6);
|
3347
3379
|
}
|
3348
3380
|
}
|
3349
3381
|
if ($family) {
|
@@ -4191,6 +4223,22 @@ sub ParseArguments($;@)
|
|
4191
4223
|
}
|
4192
4224
|
}
|
4193
4225
|
|
4226
|
+
#------------------------------------------------------------------------------
|
4227
|
+
# Does group name match the tag ID?
|
4228
|
+
# Inputs: 0) tag ID, 1) group name (with "ID-" removed)
|
4229
|
+
# Returns: true on success
|
4230
|
+
sub IsSameID($$)
|
4231
|
+
{
|
4232
|
+
my ($id, $grp) = @_;
|
4233
|
+
return 1 if $grp eq $id; # decimal ID's or raw ID's
|
4234
|
+
if ($id =~ /^\d+$/) { # numerical numerical ID's may be in hex
|
4235
|
+
return 1 if $grp =~ s/^0x0*// and $grp eq sprintf('%x', $id);
|
4236
|
+
} else { # other ID's may conform to ExifTool group name conventions
|
4237
|
+
return 1 if $id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge and $grp eq $id;
|
4238
|
+
}
|
4239
|
+
return 0;
|
4240
|
+
}
|
4241
|
+
|
4194
4242
|
#------------------------------------------------------------------------------
|
4195
4243
|
# Get list of tags in specified group
|
4196
4244
|
# Inputs: 0) ExifTool ref, 1) group spec, 2) tag key or reference to list of tag keys
|
@@ -4202,40 +4250,41 @@ sub GroupMatches($$$)
|
|
4202
4250
|
my ($self, $group, $tagList) = @_;
|
4203
4251
|
$tagList = [ $tagList ] unless ref $tagList;
|
4204
4252
|
my ($tag, @matches);
|
4205
|
-
|
4206
|
-
|
4207
|
-
|
4208
|
-
|
4253
|
+
# check each group name individually (eg. "Author:1IPTC")
|
4254
|
+
my @grps = split ':', $group;
|
4255
|
+
my (@fmys, $g);
|
4256
|
+
for ($g=0; $g<@grps; ++$g) {
|
4257
|
+
if ($grps[$g] =~ s/^(\d*)(id-)?//i) {
|
4258
|
+
$fmys[$g] = $1 if length $1;
|
4259
|
+
if ($2) {
|
4260
|
+
$fmys[$g] = 7;
|
4261
|
+
next; # (don't convert tag ID's to lower case)
|
4262
|
+
}
|
4263
|
+
}
|
4264
|
+
$grps[$g] = lc $grps[$g];
|
4265
|
+
$grps[$g] = '' if $grps[$g] eq 'copy0'; # accept 'Copy0' for primary tag
|
4266
|
+
}
|
4267
|
+
foreach $tag (@$tagList) {
|
4268
|
+
my @groups = $self->GetGroup($tag, -1);
|
4209
4269
|
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];
|
4270
|
+
my $grp = $grps[$g];
|
4271
|
+
next if $grp eq '*' or $grp eq 'all';
|
4272
|
+
my $f;
|
4273
|
+
if (defined($f = $fmys[$g])) {
|
4274
|
+
last unless defined $groups[$f];
|
4275
|
+
if ($f == 7) {
|
4276
|
+
next if IsSameID($self->GetTagID($tag), $grp);
|
4221
4277
|
} else {
|
4222
|
-
|
4278
|
+
next if $grp eq lc $groups[$f];
|
4223
4279
|
}
|
4224
|
-
|
4225
|
-
|
4226
|
-
|
4227
|
-
push @matches, $tag;
|
4280
|
+
last;
|
4281
|
+
} else {
|
4282
|
+
last unless grep /^$grp$/i, @groups;
|
4228
4283
|
}
|
4229
4284
|
}
|
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
|
-
}
|
4285
|
+
if ($g == @grps) {
|
4286
|
+
return $tag unless wantarray;
|
4287
|
+
push @matches, $tag;
|
4239
4288
|
}
|
4240
4289
|
}
|
4241
4290
|
return wantarray ? @matches : $matches[0];
|
@@ -4694,13 +4743,13 @@ sub AddCompositeTags($;$)
|
|
4694
4743
|
my ($module, $prefix, $tagID);
|
4695
4744
|
unless (ref $add) {
|
4696
4745
|
($prefix = $add) =~ s/.*:://;
|
4697
|
-
$prefix .= '::';
|
4698
4746
|
$module = $add;
|
4699
4747
|
$add .= '::Composite';
|
4700
4748
|
no strict 'refs';
|
4701
4749
|
$add = \%$add;
|
4750
|
+
$prefix .= '-';
|
4702
4751
|
} else {
|
4703
|
-
$prefix = 'UserDefined
|
4752
|
+
$prefix = 'UserDefined-';
|
4704
4753
|
}
|
4705
4754
|
my $defaultGroups = $$add{GROUPS};
|
4706
4755
|
my $compTable = GetTagTable('Image::ExifTool::Composite');
|
@@ -5415,36 +5464,38 @@ sub GetDescriptions($$)
|
|
5415
5464
|
|
5416
5465
|
#------------------------------------------------------------------------------
|
5417
5466
|
# Apply filter to value(s) if necessary
|
5418
|
-
# Inputs: 0) ExifTool ref, 1) filter expression, 2
|
5419
|
-
# Returns:
|
5420
|
-
sub Filter(
|
5467
|
+
# Inputs: 0) ExifTool ref, 1) filter expression, 2) reference to value to filter
|
5468
|
+
# Returns: true unless a filter returned undef; changes value if necessary
|
5469
|
+
sub Filter($$$)
|
5421
5470
|
{
|
5422
5471
|
local $_;
|
5423
|
-
my $self =
|
5424
|
-
|
5425
|
-
|
5426
|
-
|
5427
|
-
|
5428
|
-
|
5429
|
-
|
5430
|
-
|
5431
|
-
|
5432
|
-
|
5433
|
-
|
5434
|
-
|
5435
|
-
|
5436
|
-
|
5437
|
-
|
5438
|
-
|
5439
|
-
|
5440
|
-
|
5441
|
-
|
5442
|
-
|
5443
|
-
|
5444
|
-
|
5445
|
-
|
5446
|
-
|
5472
|
+
my ($self, $filter, $valPt) = @_;
|
5473
|
+
return 1 unless defined $filter and defined $$valPt;
|
5474
|
+
my $rtnVal;
|
5475
|
+
if (not ref $$valPt) {
|
5476
|
+
$_ = $$valPt;
|
5477
|
+
#### eval Filter ($_, $self)
|
5478
|
+
eval $filter;
|
5479
|
+
if (defined $_) {
|
5480
|
+
$$valPt = $_;
|
5481
|
+
$rtnVal = 1;
|
5482
|
+
}
|
5483
|
+
} elsif (ref $$valPt eq 'SCALAR') {
|
5484
|
+
my $val = $$$valPt; # make a copy to avoid filtering twice
|
5485
|
+
$rtnVal = $self->Filter($filter, \$val);
|
5486
|
+
$$valPt = \$val;
|
5487
|
+
} elsif (ref $$valPt eq 'ARRAY') {
|
5488
|
+
my @val = @{$$valPt}; # make a copy to avoid filtering twice
|
5489
|
+
$self->Filter($filter, \$_) and $rtnVal = 1 foreach @val;
|
5490
|
+
$$valPt = \@val;
|
5491
|
+
} elsif (ref $$valPt eq 'HASH') {
|
5492
|
+
my %val = %{$$valPt}; # make a copy to avoid filtering twice
|
5493
|
+
$self->Filter($filter, \$val{$_}) and $rtnVal = 1 foreach keys %val;
|
5494
|
+
$$valPt = \%val;
|
5495
|
+
} else {
|
5496
|
+
$rtnVal = 1;
|
5447
5497
|
}
|
5498
|
+
return $rtnVal;
|
5448
5499
|
}
|
5449
5500
|
|
5450
5501
|
#------------------------------------------------------------------------------
|
@@ -7555,7 +7606,7 @@ sub ProcessDirectory($$$;$)
|
|
7555
7606
|
|
7556
7607
|
#------------------------------------------------------------------------------
|
7557
7608
|
# Get Metadata path
|
7558
|
-
# Inputs: 0)
|
7609
|
+
# Inputs: 0) ExifTool object ref
|
7559
7610
|
# Return: Metadata path string
|
7560
7611
|
sub MetadataPath($)
|
7561
7612
|
{
|
@@ -7747,7 +7798,7 @@ sub HandleTag($$$$;%)
|
|
7747
7798
|
my ($subdir, $format, $noTagInfo, $rational);
|
7748
7799
|
|
7749
7800
|
if ($tagInfo) {
|
7750
|
-
$subdir = $$tagInfo{SubDirectory}
|
7801
|
+
$subdir = $$tagInfo{SubDirectory};
|
7751
7802
|
} else {
|
7752
7803
|
return undef unless $verbose;
|
7753
7804
|
$tagInfo = { Name => "tag $tag" }; # create temporary tagInfo hash
|
@@ -8197,7 +8248,7 @@ sub VerboseDir($$;$$)
|
|
8197
8248
|
}
|
8198
8249
|
my $indent = substr($$self{INDENT}, 0, -2);
|
8199
8250
|
my $out = $$self{OPTIONS}{TextOut};
|
8200
|
-
my $str = $entries ? " with $entries entries" : '';
|
8251
|
+
my $str = ($entries or defined $entries and not $size) ? " with $entries entries" : '';
|
8201
8252
|
$str .= ", $size bytes" if $size;
|
8202
8253
|
print $out "$indent+ [$name directory$str]\n";
|
8203
8254
|
}
|