exiftool_vendored 11.98.0 → 12.10.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.
- checksums.yaml +4 -4
- data/bin/Changes +198 -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 +102 -75
- data/bin/lib/Image/ExifTool.pm +163 -111
- data/bin/lib/Image/ExifTool.pod +127 -93
- 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 +202 -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/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 +19 -19
- data/bin/lib/Image/ExifTool/MacOS.pm +154 -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 +164 -20
- 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 +289 -37
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +419 -60
- data/bin/lib/Image/ExifTool/README +26 -22
- 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 +426 -40
- data/bin/lib/Image/ExifTool/TagLookup.pm +5799 -5671
- data/bin/lib/Image/ExifTool/TagNames.pod +584 -97
- 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 +47 -24
- data/bin/lib/Image/ExifTool/XMP.pm +99 -17
- data/bin/lib/Image/ExifTool/XMP2.pl +1 -0
- 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.10';
|
|
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
|
#------------------------------------------------------------------------------
|
|
@@ -7096,6 +7147,7 @@ sub DoProcessTIFF($$;$)
|
|
|
7096
7147
|
# no longer do this because various files use different values
|
|
7097
7148
|
# (TIFF=0x2a, RW2/RWL=0x55, HDP=0xbc, BTF=0x2b, ORF=0x4f52/0x5352/0x????)
|
|
7098
7149
|
# return 0 unless $identifier == 0x2a;
|
|
7150
|
+
$self->Warn('Invalid magic number in EXIF TIFF header') if $fileType eq 'APP1' and $identifier != 0x2a;
|
|
7099
7151
|
|
|
7100
7152
|
# get offset to IFD0
|
|
7101
7153
|
return 0 if length $$dataPt < 8;
|
|
@@ -7555,7 +7607,7 @@ sub ProcessDirectory($$$;$)
|
|
|
7555
7607
|
|
|
7556
7608
|
#------------------------------------------------------------------------------
|
|
7557
7609
|
# Get Metadata path
|
|
7558
|
-
# Inputs: 0)
|
|
7610
|
+
# Inputs: 0) ExifTool object ref
|
|
7559
7611
|
# Return: Metadata path string
|
|
7560
7612
|
sub MetadataPath($)
|
|
7561
7613
|
{
|
|
@@ -7747,7 +7799,7 @@ sub HandleTag($$$$;%)
|
|
|
7747
7799
|
my ($subdir, $format, $noTagInfo, $rational);
|
|
7748
7800
|
|
|
7749
7801
|
if ($tagInfo) {
|
|
7750
|
-
$subdir = $$tagInfo{SubDirectory}
|
|
7802
|
+
$subdir = $$tagInfo{SubDirectory};
|
|
7751
7803
|
} else {
|
|
7752
7804
|
return undef unless $verbose;
|
|
7753
7805
|
$tagInfo = { Name => "tag $tag" }; # create temporary tagInfo hash
|
|
@@ -8197,7 +8249,7 @@ sub VerboseDir($$;$$)
|
|
|
8197
8249
|
}
|
|
8198
8250
|
my $indent = substr($$self{INDENT}, 0, -2);
|
|
8199
8251
|
my $out = $$self{OPTIONS}{TextOut};
|
|
8200
|
-
my $str = $entries ? " with $entries entries" : '';
|
|
8252
|
+
my $str = ($entries or defined $entries and not $size) ? " with $entries entries" : '';
|
|
8201
8253
|
$str .= ", $size bytes" if $size;
|
|
8202
8254
|
print $out "$indent+ [$name directory$str]\n";
|
|
8203
8255
|
}
|