exiftool_vendored 11.99.0 → 12.11.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 +201 -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 +172 -99
- data/bin/lib/Image/ExifTool.pm +170 -117
- data/bin/lib/Image/ExifTool.pod +132 -97
- 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 -13
- 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 +86 -12
- data/bin/lib/Image/ExifTool/IPTC.pm +1 -0
- data/bin/lib/Image/ExifTool/Import.pm +12 -9
- 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 +1 -1
- data/bin/lib/Image/ExifTool/MPF.pm +2 -2
- 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/Nikon.pm +143 -17
- data/bin/lib/Image/ExifTool/Olympus.pm +40 -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 +11 -3
- data/bin/lib/Image/ExifTool/Photoshop.pm +2 -1
- data/bin/lib/Image/ExifTool/QuickTime.pm +240 -37
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +419 -60
- data/bin/lib/Image/ExifTool/README +25 -21
- data/bin/lib/Image/ExifTool/RSRC.pm +17 -11
- 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 +423 -39
- data/bin/lib/Image/ExifTool/Stim.pm +2 -2
- data/bin/lib/Image/ExifTool/TagLookup.pm +5798 -5675
- data/bin/lib/Image/ExifTool/TagNames.pod +575 -100
- data/bin/lib/Image/ExifTool/Validate.pm +4 -4
- data/bin/lib/Image/ExifTool/WriteExif.pl +1 -0
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +30 -21
- data/bin/lib/Image/ExifTool/Writer.pl +49 -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 +9 -8
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 = '11
|
|
31
|
+
$VERSION = '12.11';
|
|
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
|
|
@@ -2486,6 +2505,7 @@ sub ExtractInfo($;@)
|
|
|
2486
2505
|
} else {
|
|
2487
2506
|
$self->Error('Unknown file type');
|
|
2488
2507
|
}
|
|
2508
|
+
$self->BuildCompositeTags() if $fast == 4 and $$options{Composite};
|
|
2489
2509
|
last; # don't read the file
|
|
2490
2510
|
}
|
|
2491
2511
|
if (@fileTypeList) {
|
|
@@ -3095,30 +3115,9 @@ sub GetValue($$;$)
|
|
|
3095
3115
|
}
|
|
3096
3116
|
if (ref $conv eq 'HASH') {
|
|
3097
3117
|
# 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 {
|
|
3118
|
+
if (not defined($value = $$conv{$val})) {
|
|
3109
3119
|
if ($$conv{BITMASK}) {
|
|
3110
3120
|
$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
3121
|
} else {
|
|
3123
3122
|
# use alternate conversion routine if available
|
|
3124
3123
|
if ($$conv{OTHER}) {
|
|
@@ -3131,12 +3130,30 @@ sub GetValue($$;$)
|
|
|
3131
3130
|
if ($$tagInfo{PrintHex} and $val and IsInt($val) and
|
|
3132
3131
|
$convType eq 'PrintConv')
|
|
3133
3132
|
{
|
|
3134
|
-
$
|
|
3133
|
+
$value = sprintf('Unknown (0x%x)',$val);
|
|
3134
|
+
} else {
|
|
3135
|
+
$value = "Unknown ($val)";
|
|
3135
3136
|
}
|
|
3136
|
-
$value = "Unknown ($val)";
|
|
3137
3137
|
}
|
|
3138
3138
|
}
|
|
3139
3139
|
}
|
|
3140
|
+
# override with our localized language PrintConv if available
|
|
3141
|
+
my $tmp;
|
|
3142
|
+
if ($$self{CUR_LANG} and $convType eq 'PrintConv' and
|
|
3143
|
+
# (no need to check for lang-alt tag names -- they won't have a PrintConv)
|
|
3144
|
+
ref($tmp = $$self{CUR_LANG}{$$tagInfo{Name}}) eq 'HASH' and
|
|
3145
|
+
($tmp = $$tmp{PrintConv}))
|
|
3146
|
+
{
|
|
3147
|
+
if ($$conv{BITMASK} and not defined $$conv{$val}) {
|
|
3148
|
+
my @vals = split ', ', $value;
|
|
3149
|
+
foreach (@vals) {
|
|
3150
|
+
$_ = $$tmp{$_} if defined $$tmp{$_};
|
|
3151
|
+
}
|
|
3152
|
+
$value = join ', ', @vals;
|
|
3153
|
+
} elsif (defined($tmp = $$tmp{$value})) {
|
|
3154
|
+
$value = $self->Decode($tmp, 'UTF8');
|
|
3155
|
+
}
|
|
3156
|
+
}
|
|
3140
3157
|
} else {
|
|
3141
3158
|
# call subroutine or do eval to convert value
|
|
3142
3159
|
local $SIG{'__WARN__'} = \&SetWarning;
|
|
@@ -3294,7 +3311,7 @@ sub GetGroup($$;$)
|
|
|
3294
3311
|
{
|
|
3295
3312
|
local $_;
|
|
3296
3313
|
my ($self, $tag, $family) = @_;
|
|
3297
|
-
my ($tagInfo, @groups, @families, $simplify, $byTagInfo, $ex);
|
|
3314
|
+
my ($tagInfo, @groups, @families, $simplify, $byTagInfo, $ex, $noID);
|
|
3298
3315
|
if (ref $tag eq 'HASH') {
|
|
3299
3316
|
$tagInfo = $tag;
|
|
3300
3317
|
$tag = $$tagInfo{Name};
|
|
@@ -3325,6 +3342,7 @@ sub GetGroup($$;$)
|
|
|
3325
3342
|
$simplify = 1 unless $family =~ /^:/;
|
|
3326
3343
|
undef $family;
|
|
3327
3344
|
foreach (0..2) { $groups[$_] = $$groups{$_}; }
|
|
3345
|
+
$noID = 1 if @families == 1 and $families[0] != 7;
|
|
3328
3346
|
} else {
|
|
3329
3347
|
return(($ex && $$ex{"G$family"}) || $$groups{$family}) if $family == 0 or $family == 2;
|
|
3330
3348
|
$groups[1] = $$groups{1};
|
|
@@ -3336,14 +3354,29 @@ sub GetGroup($$;$)
|
|
|
3336
3354
|
$groups[3] = 'Main';
|
|
3337
3355
|
$groups[4] = ($tag =~ /\((\d+)\)$/) ? "Copy$1" : '';
|
|
3338
3356
|
# handle dynamic group names if necessary
|
|
3339
|
-
|
|
3340
|
-
$
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3357
|
+
unless ($byTagInfo) {
|
|
3358
|
+
if ($ex) {
|
|
3359
|
+
$groups[0] = $$ex{G0} if $$ex{G0};
|
|
3360
|
+
$groups[1] = $$ex{G1} =~ /^\+(.*)/ ? "$groups[1]$1" : $$ex{G1} if $$ex{G1};
|
|
3361
|
+
$groups[3] = 'Doc' . $$ex{G3} if $$ex{G3};
|
|
3362
|
+
$groups[5] = $$ex{G5} || $groups[1] if defined $$ex{G5};
|
|
3363
|
+
if (defined $$ex{G6}) {
|
|
3364
|
+
$groups[5] = '' unless defined $groups[5]; # (can't leave a hole in the array)
|
|
3365
|
+
$groups[6] = $$ex{G6};
|
|
3366
|
+
}
|
|
3367
|
+
}
|
|
3368
|
+
# generate tag ID group names unless obviously not needed
|
|
3369
|
+
unless ($noID) {
|
|
3370
|
+
my $id = $$tagInfo{TagID};
|
|
3371
|
+
if (not defined $id) {
|
|
3372
|
+
$id = ''; # (just to be safe)
|
|
3373
|
+
} elsif ($id =~ /^\d+$/) {
|
|
3374
|
+
$id = sprintf('0x%x', $id) if $$self{OPTIONS}{HexTagIDs};
|
|
3375
|
+
} else {
|
|
3376
|
+
$id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge;
|
|
3377
|
+
}
|
|
3378
|
+
$groups[7] = 'ID-' . $id;
|
|
3379
|
+
defined $groups[$_] or $groups[$_] = '' foreach (5,6);
|
|
3347
3380
|
}
|
|
3348
3381
|
}
|
|
3349
3382
|
if ($family) {
|
|
@@ -4191,6 +4224,22 @@ sub ParseArguments($;@)
|
|
|
4191
4224
|
}
|
|
4192
4225
|
}
|
|
4193
4226
|
|
|
4227
|
+
#------------------------------------------------------------------------------
|
|
4228
|
+
# Does group name match the tag ID?
|
|
4229
|
+
# Inputs: 0) tag ID, 1) group name (with "ID-" removed)
|
|
4230
|
+
# Returns: true on success
|
|
4231
|
+
sub IsSameID($$)
|
|
4232
|
+
{
|
|
4233
|
+
my ($id, $grp) = @_;
|
|
4234
|
+
return 1 if $grp eq $id; # decimal ID's or raw ID's
|
|
4235
|
+
if ($id =~ /^\d+$/) { # numerical numerical ID's may be in hex
|
|
4236
|
+
return 1 if $grp =~ s/^0x0*// and $grp eq sprintf('%x', $id);
|
|
4237
|
+
} else { # other ID's may conform to ExifTool group name conventions
|
|
4238
|
+
return 1 if $id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge and $grp eq $id;
|
|
4239
|
+
}
|
|
4240
|
+
return 0;
|
|
4241
|
+
}
|
|
4242
|
+
|
|
4194
4243
|
#------------------------------------------------------------------------------
|
|
4195
4244
|
# Get list of tags in specified group
|
|
4196
4245
|
# Inputs: 0) ExifTool ref, 1) group spec, 2) tag key or reference to list of tag keys
|
|
@@ -4202,40 +4251,41 @@ sub GroupMatches($$$)
|
|
|
4202
4251
|
my ($self, $group, $tagList) = @_;
|
|
4203
4252
|
$tagList = [ $tagList ] unless ref $tagList;
|
|
4204
4253
|
my ($tag, @matches);
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4254
|
+
# check each group name individually (eg. "Author:1IPTC")
|
|
4255
|
+
my @grps = split ':', $group;
|
|
4256
|
+
my (@fmys, $g);
|
|
4257
|
+
for ($g=0; $g<@grps; ++$g) {
|
|
4258
|
+
if ($grps[$g] =~ s/^(\d*)(id-)?//i) {
|
|
4259
|
+
$fmys[$g] = $1 if length $1;
|
|
4260
|
+
if ($2) {
|
|
4261
|
+
$fmys[$g] = 7;
|
|
4262
|
+
next; # (don't convert tag ID's to lower case)
|
|
4263
|
+
}
|
|
4264
|
+
}
|
|
4265
|
+
$grps[$g] = lc $grps[$g];
|
|
4266
|
+
$grps[$g] = '' if $grps[$g] eq 'copy0'; # accept 'Copy0' for primary tag
|
|
4267
|
+
}
|
|
4268
|
+
foreach $tag (@$tagList) {
|
|
4269
|
+
my @groups = $self->GetGroup($tag, -1);
|
|
4209
4270
|
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];
|
|
4271
|
+
my $grp = $grps[$g];
|
|
4272
|
+
next if $grp eq '*' or $grp eq 'all';
|
|
4273
|
+
my $f;
|
|
4274
|
+
if (defined($f = $fmys[$g])) {
|
|
4275
|
+
last unless defined $groups[$f];
|
|
4276
|
+
if ($f == 7) {
|
|
4277
|
+
next if IsSameID($self->GetTagID($tag), $grp);
|
|
4221
4278
|
} else {
|
|
4222
|
-
|
|
4279
|
+
next if $grp eq lc $groups[$f];
|
|
4223
4280
|
}
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
push @matches, $tag;
|
|
4281
|
+
last;
|
|
4282
|
+
} else {
|
|
4283
|
+
last unless grep /^$grp$/i, @groups;
|
|
4228
4284
|
}
|
|
4229
4285
|
}
|
|
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
|
-
}
|
|
4286
|
+
if ($g == @grps) {
|
|
4287
|
+
return $tag unless wantarray;
|
|
4288
|
+
push @matches, $tag;
|
|
4239
4289
|
}
|
|
4240
4290
|
}
|
|
4241
4291
|
return wantarray ? @matches : $matches[0];
|
|
@@ -4694,13 +4744,13 @@ sub AddCompositeTags($;$)
|
|
|
4694
4744
|
my ($module, $prefix, $tagID);
|
|
4695
4745
|
unless (ref $add) {
|
|
4696
4746
|
($prefix = $add) =~ s/.*:://;
|
|
4697
|
-
$prefix .= '::';
|
|
4698
4747
|
$module = $add;
|
|
4699
4748
|
$add .= '::Composite';
|
|
4700
4749
|
no strict 'refs';
|
|
4701
4750
|
$add = \%$add;
|
|
4751
|
+
$prefix .= '-';
|
|
4702
4752
|
} else {
|
|
4703
|
-
$prefix = 'UserDefined
|
|
4753
|
+
$prefix = 'UserDefined-';
|
|
4704
4754
|
}
|
|
4705
4755
|
my $defaultGroups = $$add{GROUPS};
|
|
4706
4756
|
my $compTable = GetTagTable('Image::ExifTool::Composite');
|
|
@@ -5415,36 +5465,38 @@ sub GetDescriptions($$)
|
|
|
5415
5465
|
|
|
5416
5466
|
#------------------------------------------------------------------------------
|
|
5417
5467
|
# Apply filter to value(s) if necessary
|
|
5418
|
-
# Inputs: 0) ExifTool ref, 1) filter expression, 2
|
|
5419
|
-
# Returns:
|
|
5420
|
-
sub Filter(
|
|
5468
|
+
# Inputs: 0) ExifTool ref, 1) filter expression, 2) reference to value to filter
|
|
5469
|
+
# Returns: true unless a filter returned undef; changes value if necessary
|
|
5470
|
+
sub Filter($$$)
|
|
5421
5471
|
{
|
|
5422
5472
|
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
|
-
|
|
5473
|
+
my ($self, $filter, $valPt) = @_;
|
|
5474
|
+
return 1 unless defined $filter and defined $$valPt;
|
|
5475
|
+
my $rtnVal;
|
|
5476
|
+
if (not ref $$valPt) {
|
|
5477
|
+
$_ = $$valPt;
|
|
5478
|
+
#### eval Filter ($_, $self)
|
|
5479
|
+
eval $filter;
|
|
5480
|
+
if (defined $_) {
|
|
5481
|
+
$$valPt = $_;
|
|
5482
|
+
$rtnVal = 1;
|
|
5483
|
+
}
|
|
5484
|
+
} elsif (ref $$valPt eq 'SCALAR') {
|
|
5485
|
+
my $val = $$$valPt; # make a copy to avoid filtering twice
|
|
5486
|
+
$rtnVal = $self->Filter($filter, \$val);
|
|
5487
|
+
$$valPt = \$val;
|
|
5488
|
+
} elsif (ref $$valPt eq 'ARRAY') {
|
|
5489
|
+
my @val = @{$$valPt}; # make a copy to avoid filtering twice
|
|
5490
|
+
$self->Filter($filter, \$_) and $rtnVal = 1 foreach @val;
|
|
5491
|
+
$$valPt = \@val;
|
|
5492
|
+
} elsif (ref $$valPt eq 'HASH') {
|
|
5493
|
+
my %val = %{$$valPt}; # make a copy to avoid filtering twice
|
|
5494
|
+
$self->Filter($filter, \$val{$_}) and $rtnVal = 1 foreach keys %val;
|
|
5495
|
+
$$valPt = \%val;
|
|
5496
|
+
} else {
|
|
5497
|
+
$rtnVal = 1;
|
|
5447
5498
|
}
|
|
5499
|
+
return $rtnVal;
|
|
5448
5500
|
}
|
|
5449
5501
|
|
|
5450
5502
|
#------------------------------------------------------------------------------
|
|
@@ -5681,12 +5733,12 @@ sub ConvertFileSize($)
|
|
|
5681
5733
|
{
|
|
5682
5734
|
my $val = shift;
|
|
5683
5735
|
$val < 2048 and return "$val bytes";
|
|
5684
|
-
$val < 10240 and return sprintf('%.1f
|
|
5685
|
-
$val < 2097152 and return sprintf('%.0f
|
|
5686
|
-
$val < 10485760 and return sprintf('%.1f
|
|
5687
|
-
$val < 2147483648 and return sprintf('%.0f
|
|
5688
|
-
$val < 10737418240 and return sprintf('%.1f
|
|
5689
|
-
return sprintf('%.0f
|
|
5736
|
+
$val < 10240 and return sprintf('%.1f KiB', $val / 1024);
|
|
5737
|
+
$val < 2097152 and return sprintf('%.0f KiB', $val / 1024);
|
|
5738
|
+
$val < 10485760 and return sprintf('%.1f MiB', $val / 1048576);
|
|
5739
|
+
$val < 2147483648 and return sprintf('%.0f MiB', $val / 1048576);
|
|
5740
|
+
$val < 10737418240 and return sprintf('%.1f GiB', $val / 1073741824);
|
|
5741
|
+
return sprintf('%.0f GiB', $val / 1073741824);
|
|
5690
5742
|
}
|
|
5691
5743
|
|
|
5692
5744
|
#------------------------------------------------------------------------------
|
|
@@ -7096,6 +7148,7 @@ sub DoProcessTIFF($$;$)
|
|
|
7096
7148
|
# no longer do this because various files use different values
|
|
7097
7149
|
# (TIFF=0x2a, RW2/RWL=0x55, HDP=0xbc, BTF=0x2b, ORF=0x4f52/0x5352/0x????)
|
|
7098
7150
|
# return 0 unless $identifier == 0x2a;
|
|
7151
|
+
$self->Warn('Invalid magic number in EXIF TIFF header') if $fileType eq 'APP1' and $identifier != 0x2a;
|
|
7099
7152
|
|
|
7100
7153
|
# get offset to IFD0
|
|
7101
7154
|
return 0 if length $$dataPt < 8;
|
|
@@ -7555,7 +7608,7 @@ sub ProcessDirectory($$$;$)
|
|
|
7555
7608
|
|
|
7556
7609
|
#------------------------------------------------------------------------------
|
|
7557
7610
|
# Get Metadata path
|
|
7558
|
-
# Inputs: 0)
|
|
7611
|
+
# Inputs: 0) ExifTool object ref
|
|
7559
7612
|
# Return: Metadata path string
|
|
7560
7613
|
sub MetadataPath($)
|
|
7561
7614
|
{
|
|
@@ -7747,7 +7800,7 @@ sub HandleTag($$$$;%)
|
|
|
7747
7800
|
my ($subdir, $format, $noTagInfo, $rational);
|
|
7748
7801
|
|
|
7749
7802
|
if ($tagInfo) {
|
|
7750
|
-
$subdir = $$tagInfo{SubDirectory}
|
|
7803
|
+
$subdir = $$tagInfo{SubDirectory};
|
|
7751
7804
|
} else {
|
|
7752
7805
|
return undef unless $verbose;
|
|
7753
7806
|
$tagInfo = { Name => "tag $tag" }; # create temporary tagInfo hash
|
|
@@ -8197,7 +8250,7 @@ sub VerboseDir($$;$$)
|
|
|
8197
8250
|
}
|
|
8198
8251
|
my $indent = substr($$self{INDENT}, 0, -2);
|
|
8199
8252
|
my $out = $$self{OPTIONS}{TextOut};
|
|
8200
|
-
my $str = $entries ? " with $entries entries" : '';
|
|
8253
|
+
my $str = ($entries or defined $entries and not $size) ? " with $entries entries" : '';
|
|
8201
8254
|
$str .= ", $size bytes" if $size;
|
|
8202
8255
|
print $out "$indent+ [$name directory$str]\n";
|
|
8203
8256
|
}
|