exiftool_vendored 12.42.0 → 12.52.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/Changes +226 -6
- data/bin/MANIFEST +14 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +45 -44
- data/bin/config_files/acdsee.config +2 -1
- data/bin/config_files/frameCount.config +56 -0
- data/bin/config_files/tiff_version.config +1 -1
- data/bin/exiftool +116 -97
- data/bin/fmt_files/gpx.fmt +3 -0
- data/bin/fmt_files/gpx_wpt.fmt +3 -0
- data/bin/lib/Image/ExifTool/Apple.pm +16 -3
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +23 -12
- data/bin/lib/Image/ExifTool/Canon.pm +66 -37
- data/bin/lib/Image/ExifTool/CanonRaw.pm +8 -1
- data/bin/lib/Image/ExifTool/CanonVRD.pm +7 -8
- data/bin/lib/Image/ExifTool/Casio.pm +3 -3
- data/bin/lib/Image/ExifTool/DJI.pm +2 -1
- data/bin/lib/Image/ExifTool/DarwinCore.pm +13 -1
- data/bin/lib/Image/ExifTool/EXE.pm +9 -1
- data/bin/lib/Image/ExifTool/Exif.pm +17 -12
- data/bin/lib/Image/ExifTool/FLAC.pm +17 -3
- data/bin/lib/Image/ExifTool/FLIR.pm +9 -7
- data/bin/lib/Image/ExifTool/FlashPix.pm +26 -3
- data/bin/lib/Image/ExifTool/FujiFilm.pm +51 -4
- data/bin/lib/Image/ExifTool/GPS.pm +31 -5
- data/bin/lib/Image/ExifTool/Geotag.pm +36 -8
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +3 -2
- data/bin/lib/Image/ExifTool/ICO.pm +143 -0
- data/bin/lib/Image/ExifTool/ID3.pm +6 -6
- data/bin/lib/Image/ExifTool/IPTC.pm +5 -1
- data/bin/lib/Image/ExifTool/JPEG.pm +1 -0
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +24 -3
- data/bin/lib/Image/ExifTool/LNK.pm +5 -2
- data/bin/lib/Image/ExifTool/Lang/de.pm +1 -1
- data/bin/lib/Image/ExifTool/Lang/fr.pm +6015 -759
- data/bin/lib/Image/ExifTool/Lang/sk.pm +1927 -0
- data/bin/lib/Image/ExifTool/M2TS.pm +98 -8
- data/bin/lib/Image/ExifTool/MIE.pm +9 -3
- data/bin/lib/Image/ExifTool/MISB.pm +494 -0
- data/bin/lib/Image/ExifTool/MakerNotes.pm +3 -1
- data/bin/lib/Image/ExifTool/Matroska.pm +272 -48
- data/bin/lib/Image/ExifTool/Motorola.pm +8 -2
- data/bin/lib/Image/ExifTool/Nikon.pm +746 -382
- data/bin/lib/Image/ExifTool/NikonCustom.pm +139 -106
- data/bin/lib/Image/ExifTool/NikonSettings.pm +5 -3
- data/bin/lib/Image/ExifTool/Olympus.pm +6 -4
- data/bin/lib/Image/ExifTool/PNG.pm +8 -1
- data/bin/lib/Image/ExifTool/Panasonic.pm +21 -4
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +25 -5
- data/bin/lib/Image/ExifTool/Parrot.pm +96 -2
- data/bin/lib/Image/ExifTool/Pentax.pm +7 -2
- data/bin/lib/Image/ExifTool/Photoshop.pm +29 -3
- data/bin/lib/Image/ExifTool/QuickTime.pm +166 -13
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +161 -22
- data/bin/lib/Image/ExifTool/README +15 -4
- data/bin/lib/Image/ExifTool/RIFF.pm +106 -9
- data/bin/lib/Image/ExifTool/Samsung.pm +2 -2
- data/bin/lib/Image/ExifTool/Sigma.pm +27 -1
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +37 -13
- data/bin/lib/Image/ExifTool/Sony.pm +75 -47
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +13 -6
- data/bin/lib/Image/ExifTool/TagLookup.pm +4791 -4519
- data/bin/lib/Image/ExifTool/TagNames.pod +2056 -1446
- data/bin/lib/Image/ExifTool/Text.pm +3 -4
- data/bin/lib/Image/ExifTool/Torrent.pm +2 -3
- data/bin/lib/Image/ExifTool/Validate.pm +3 -3
- data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +7 -0
- data/bin/lib/Image/ExifTool/WriteExif.pl +100 -23
- data/bin/lib/Image/ExifTool/WriteIPTC.pl +2 -6
- data/bin/lib/Image/ExifTool/WritePhotoshop.pl +5 -5
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +12 -7
- data/bin/lib/Image/ExifTool/WriteRIFF.pl +359 -0
- data/bin/lib/Image/ExifTool/WriteXMP.pl +15 -1
- data/bin/lib/Image/ExifTool/Writer.pl +46 -18
- data/bin/lib/Image/ExifTool/XMP.pm +78 -59
- data/bin/lib/Image/ExifTool/XMP2.pl +19 -4
- data/bin/lib/Image/ExifTool/ZIP.pm +19 -7
- data/bin/lib/Image/ExifTool.pm +146 -38
- data/bin/lib/Image/ExifTool.pod +83 -69
- data/bin/perl-Image-ExifTool.spec +43 -43
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +10 -4
data/bin/lib/Image/ExifTool.pm
CHANGED
@@ -29,7 +29,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
|
|
29
29
|
%jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
|
30
30
|
%static_vars);
|
31
31
|
|
32
|
-
$VERSION = '12.
|
32
|
+
$VERSION = '12.52';
|
33
33
|
$RELEASE = '';
|
34
34
|
@ISA = qw(Exporter);
|
35
35
|
%EXPORT_TAGS = (
|
@@ -139,22 +139,22 @@ sub ReadValue($$$;$$$);
|
|
139
139
|
@loadAllTables = qw(
|
140
140
|
PhotoMechanic Exif GeoTiff CanonRaw KyoceraRaw Lytro MinoltaRaw PanasonicRaw
|
141
141
|
SigmaRaw JPEG GIMP Jpeg2000 GIF BMP BMP::OS2 BMP::Extra BPG BPG::Extensions
|
142
|
-
PICT PNG MNG FLIF DjVu DPX OpenEXR ZISRAW MRC LIF MRC::FEI12 MIFF PCX
|
143
|
-
PSP PhotoCD Radiance Other::PFM PDF PostScript Photoshop::Header
|
142
|
+
ICO PICT PNG MNG FLIF DjVu DPX OpenEXR ZISRAW MRC LIF MRC::FEI12 MIFF PCX
|
143
|
+
PGF PSP PhotoCD Radiance Other::PFM PDF PostScript Photoshop::Header
|
144
144
|
Photoshop::Layers Photoshop::ImageData FujiFilm::RAF FujiFilm::IFD
|
145
145
|
Samsung::Trailer Sony::SRF2 Sony::SR2SubIFD Sony::PMP ITC ID3 ID3::Lyrics3
|
146
146
|
FLAC Ogg Vorbis APE APE::NewHeader APE::OldHeader Audible MPC MPEG::Audio
|
147
147
|
MPEG::Video MPEG::Xing M2TS QuickTime QuickTime::ImageFile QuickTime::Stream
|
148
|
-
QuickTime::Tags360Fly Matroska MOI MXF DV Flash Flash::FLV
|
149
|
-
Real::Audio Real::Metafile Red RIFF AIFF ASF WTV DICOM FITS MIE
|
150
|
-
XMP::SVG Palm Palm::MOBI Palm::EXTH Torrent EXE EXE::PEVersion
|
151
|
-
EXE::MachO EXE::PEF EXE::ELF EXE::AR EXE::CHM LNK Font VCard
|
152
|
-
VCard::VCalendar RSRC Rawzor ZIP ZIP::GZIP ZIP::RAR RTF OOXML iWork ISO
|
148
|
+
QuickTime::Tags360Fly Matroska Matroska::Tags MOI MXF DV Flash Flash::FLV
|
149
|
+
Real::Media Real::Audio Real::Metafile Red RIFF AIFF ASF WTV DICOM FITS MIE
|
150
|
+
JSON HTML XMP::SVG Palm Palm::MOBI Palm::EXTH Torrent EXE EXE::PEVersion
|
151
|
+
EXE::PEString EXE::MachO EXE::PEF EXE::ELF EXE::AR EXE::CHM LNK Font VCard
|
152
|
+
Text VCard::VCalendar RSRC Rawzor ZIP ZIP::GZIP ZIP::RAR RTF OOXML iWork ISO
|
153
153
|
FLIR::AFF FLIR::FPF MacOS MacOS::MDItem FlashPix::DocTable
|
154
154
|
);
|
155
155
|
|
156
156
|
# alphabetical list of current Lang modules
|
157
|
-
@langs = qw(cs de en en_ca en_gb es fi fr it ja ko nl pl ru sv tr zh_cn zh_tw);
|
157
|
+
@langs = qw(cs de en en_ca en_gb es fi fr it ja ko nl pl ru sk sv tr zh_cn zh_tw);
|
158
158
|
|
159
159
|
$defaultLang = 'en'; # default language
|
160
160
|
|
@@ -174,6 +174,7 @@ $defaultLang = 'en'; # default language
|
|
174
174
|
nl => 'Dutch (Nederlands)',
|
175
175
|
pl => 'Polish (Polski)',
|
176
176
|
ru => 'Russian (Русский)',
|
177
|
+
sk => 'Slovak (Slovenčina)',
|
177
178
|
sv => 'Swedish (Svenska)',
|
178
179
|
'tr'=> 'Turkish (Türkçe)',
|
179
180
|
zh_cn => 'Simplified Chinese (简体中文)',
|
@@ -191,11 +192,12 @@ $defaultLang = 'en'; # default language
|
|
191
192
|
HTML VRD RTF FITS XCF DSS QTIF FPX PICT ZIP GZIP PLIST RAR BZ2
|
192
193
|
CZI TAR EXE EXR HDR CHM LNK WMF AVC DEX DPX RAW Font RSRC M2TS
|
193
194
|
MacOS PHP PCX DCX DWF DWG DXF WTV Torrent VCard LRI R3D AA PDB
|
194
|
-
PFM2 MRC LIF JXL MOI ISO ALIAS JSON MP3 DICOM PCD TXT);
|
195
|
+
PFM2 MRC LIF JXL MOI ISO ALIAS JSON MP3 DICOM PCD ICO TXT);
|
195
196
|
|
196
197
|
# file types that we can write (edit)
|
197
198
|
my @writeTypes = qw(JPEG TIFF GIF CRW MRW ORF RAF RAW PNG MIE PSD XMP PPM EPS
|
198
|
-
X3F PS PDF ICC VRD DR4 JP2 JXL EXIF AI AIT IND MOV EXV FLIF
|
199
|
+
X3F PS PDF ICC VRD DR4 JP2 JXL EXIF AI AIT IND MOV EXV FLIF
|
200
|
+
RIFF);
|
199
201
|
my %writeTypes; # lookup for writable file types (hash filled if required)
|
200
202
|
|
201
203
|
# file extensions that we can't write for various base types
|
@@ -205,6 +207,8 @@ my %writeTypes; # lookup for writable file types (hash filled if required)
|
|
205
207
|
JP2 => [ qw(J2C JPC) ],
|
206
208
|
MOV => [ qw(INSV) ],
|
207
209
|
);
|
210
|
+
# file extensions that we can only write for various base types
|
211
|
+
my %onlyWriteFile = ( RIFF => [ qw(WEBP) ] );
|
208
212
|
|
209
213
|
# file types that we can create from scratch
|
210
214
|
# - must update CanCreate() documentation if this list is changed!
|
@@ -257,6 +261,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
257
261
|
CRW => ['CRW', 'Canon RAW format'],
|
258
262
|
CS1 => ['PSD', 'Sinar CaptureShop 1-Shot RAW'],
|
259
263
|
CSV => ['TXT', 'Comma-Separated Values'],
|
264
|
+
CUR => ['ICO', 'Windows Cursor'],
|
260
265
|
CZI => ['CZI', 'Zeiss Integrated Software RAW'],
|
261
266
|
DC3 => 'DICM',
|
262
267
|
DCM => 'DICM',
|
@@ -333,6 +338,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
333
338
|
ICAL => 'ICS',
|
334
339
|
ICC => ['ICC', 'International Color Consortium'],
|
335
340
|
ICM => 'ICC',
|
341
|
+
ICO => ['ICO', 'Windows Icon'],
|
336
342
|
ICS => ['VCard','iCalendar Schedule'],
|
337
343
|
IDML => ['ZIP', 'Adobe InDesign Markup Language'],
|
338
344
|
IIQ => ['TIFF', 'Phase One Intelligent Image Quality RAW'],
|
@@ -378,6 +384,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
378
384
|
M4B => ['MOV', 'MPEG-4 audio Book'],
|
379
385
|
M4P => ['MOV', 'MPEG-4 Protected'],
|
380
386
|
M4V => ['MOV', 'MPEG-4 Video'],
|
387
|
+
MACOS=> ['MacOS','MacOS ._ sidecar file'],
|
381
388
|
MAX => ['FPX', '3D Studio MAX'],
|
382
389
|
MEF => ['TIFF', 'Mamiya (RAW) Electronic Format'],
|
383
390
|
MIE => ['MIE', 'Meta Information Encapsulation format'],
|
@@ -407,7 +414,6 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
407
414
|
NEF => ['TIFF', 'Nikon (RAW) Electronic Format'],
|
408
415
|
NEWER => 'COS',
|
409
416
|
NKSC => ['XMP', 'Nikon Sidecar'],
|
410
|
-
|
411
417
|
NMBTEMPLATE => ['ZIP','Apple Numbers Template'],
|
412
418
|
NRW => ['TIFF', 'Nikon RAW (2)'],
|
413
419
|
NUMBERS => ['ZIP','Apple Numbers spreadsheet'],
|
@@ -530,7 +536,6 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
530
536
|
WMV => ['ASF', 'Windows Media Video'],
|
531
537
|
WV => ['RIFF', 'WavePack lossless audio'],
|
532
538
|
X3F => ['X3F', 'Sigma RAW format'],
|
533
|
-
MACOS=> ['MacOS','MacOS ._ sidecar file'],
|
534
539
|
XCF => ['XCF', 'GIMP native image format'],
|
535
540
|
XHTML=> ['HTML', 'Extensible HyperText Markup Language'],
|
536
541
|
XLA => ['FPX', 'Microsoft Excel Add-in'],
|
@@ -599,6 +604,7 @@ my %fileDescription = (
|
|
599
604
|
CRM => 'video/x-canon-crm',
|
600
605
|
CRW => 'image/x-canon-crw',
|
601
606
|
CSV => 'text/csv',
|
607
|
+
CUR => 'image/x-cursor', #PH (NC)
|
602
608
|
CZI => 'image/x-zeiss-czi', #PH (NC)
|
603
609
|
DCP => 'application/octet-stream', #PH (NC)
|
604
610
|
DCR => 'image/x-kodak-dcr',
|
@@ -647,6 +653,7 @@ my %fileDescription = (
|
|
647
653
|
HDR => 'image/vnd.radiance',
|
648
654
|
HTML => 'text/html',
|
649
655
|
ICC => 'application/vnd.iccprofile',
|
656
|
+
ICO => 'image/x-icon', #PH (NC)
|
650
657
|
ICS => 'text/calendar',
|
651
658
|
IDML => 'application/vnd.adobe.indesign-idml-package',
|
652
659
|
IIQ => 'image/x-raw',
|
@@ -913,6 +920,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
913
920
|
HDR => '#\?(RADIANCE|RGBE)\x0a',
|
914
921
|
HTML => '(\xef\xbb\xbf)?\s*(?i)<(!DOCTYPE\s+HTML|HTML|\?xml)', # (case insensitive)
|
915
922
|
ICC => '.{12}(scnr|mntr|prtr|link|spac|abst|nmcl|nkpf|cenc|mid |mlnk|mvis)(XYZ |Lab |Luv |YCbr|Yxy |RGB |GRAY|HSV |HLS |CMYK|CMY |[2-9A-F]CLR|nc..|\0{4}){2}',
|
923
|
+
ICO => '\0\0[\x01\x02]\0[^0]\0', # (reasonably assume that the file contains less than 256 images)
|
916
924
|
IND => '\x06\x06\xed\xf5\xd8\x1d\x46\xe5\xbd\x31\xef\xe7\xfe\x74\xb7\x1d',
|
917
925
|
# ISO => signature is at byte 32768
|
918
926
|
ITC => '.{4}itch',
|
@@ -925,6 +933,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
925
933
|
LNK => '.{4}\x01\x14\x02\0{5}\xc0\0{6}\x46',
|
926
934
|
LRI => 'LELR \0',
|
927
935
|
M2TS => '(....)?\x47',
|
936
|
+
MacOS=> '\0\x05\x16\x07\0.\0\0Mac OS X ',
|
928
937
|
MIE => '~[\x10\x18]\x04.0MIE',
|
929
938
|
MIFF => 'id=ImageMagick',
|
930
939
|
MKV => '\x1a\x45\xdf\xa3',
|
@@ -972,7 +981,6 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
972
981
|
WMF => '(\xd7\xcd\xc6\x9a\0\0|\x01\0\x09\0\0\x03)',
|
973
982
|
WTV => '\xb7\xd8\x00\x20\x37\x49\xda\x11\xa6\x4e\x00\x07\xe9\x5e\xad\x8d',
|
974
983
|
X3F => 'FOVb',
|
975
|
-
MacOS=> '\0\x05\x16\x07\0.\0\0Mac OS X ',
|
976
984
|
XCF => 'gimp xcf ',
|
977
985
|
XMP => '\0{0,3}(\xfe\xff|\xff\xfe|\xef\xbb\xbf)?\0{0,3}\s*<',
|
978
986
|
ZIP => 'PK\x03\x04',
|
@@ -1800,6 +1808,16 @@ my %systemTagsNotes = (
|
|
1800
1808
|
Protected => 1,
|
1801
1809
|
},
|
1802
1810
|
PageCount => { Notes => 'the number of pages in a multi-page TIFF document' },
|
1811
|
+
SphericalVideoXML => {
|
1812
|
+
Groups => { 0 => 'QuickTime', 1 => 'GSpherical', 2 => 'Video' },
|
1813
|
+
# (group 1 is 'GSpherical' to trigger creation of this tag when writing,
|
1814
|
+
# but when reading the family 1 group is the track number)
|
1815
|
+
Flags => [ 'Writable', 'Binary', 'Protected' ],
|
1816
|
+
Notes => q{
|
1817
|
+
the SphericalVideoXML block from MP4/MOV videos. This tag is generated only
|
1818
|
+
if specifically requested
|
1819
|
+
},
|
1820
|
+
},
|
1803
1821
|
);
|
1804
1822
|
|
1805
1823
|
# tags defined by UserParam option (added at runtime)
|
@@ -2022,6 +2040,7 @@ sub new
|
|
2022
2040
|
$$self{DEL_GROUP} = { }; # lookup for groups to delete when writing
|
2023
2041
|
$$self{SAVE_COUNT} = 0; # count calls to SaveNewValues()
|
2024
2042
|
$$self{FILE_SEQUENCE} = 0; # sequence number for files when reading
|
2043
|
+
$$self{INDENT2} = ''; # indentation of verbose messages from SetNewValue
|
2025
2044
|
|
2026
2045
|
# initialize our new groups for writing
|
2027
2046
|
$self->SetNewGroups(@defaultWriteGroups);
|
@@ -2209,6 +2228,20 @@ sub Options($$;@)
|
|
2209
2228
|
} else {
|
2210
2229
|
$$options{$param} = undef; # clear the list
|
2211
2230
|
}
|
2231
|
+
} elsif ($param eq 'IgnoreTags') {
|
2232
|
+
if (defined $newVal) {
|
2233
|
+
# parse list from delimited string if necessary
|
2234
|
+
my @ignoreList = (ref $newVal eq 'ARRAY') ? @$newVal : ($newVal =~ /[-\w?*:]+/g);
|
2235
|
+
ExpandShortcuts(\@ignoreList);
|
2236
|
+
# add to existing tags to ignore
|
2237
|
+
$$options{$param} or $$options{$param} = { };
|
2238
|
+
foreach (@ignoreList) {
|
2239
|
+
/^(.*:)?([-\w?*]+)#?$/ or next;
|
2240
|
+
$$options{$param}{lc $2} = 1;
|
2241
|
+
}
|
2242
|
+
} else {
|
2243
|
+
$$options{$param} = undef; # clear the option
|
2244
|
+
}
|
2212
2245
|
} elsif ($param eq 'ListJoin') {
|
2213
2246
|
$$options{$param} = $newVal;
|
2214
2247
|
# set the old List and ListSep options for backward compatibility
|
@@ -2321,6 +2354,7 @@ sub ClearOptions($)
|
|
2321
2354
|
HtmlDump => 0, # HTML dump (0-3, higher # = bigger limit)
|
2322
2355
|
HtmlDumpBase => undef, # base address for HTML dump
|
2323
2356
|
IgnoreMinorErrors => undef, # ignore minor errors when reading/writing
|
2357
|
+
IgnoreTags => undef, # list of tags to ignore when extracting
|
2324
2358
|
Lang => $defaultLang,# localized language for descriptions etc
|
2325
2359
|
LargeFileSupport => undef, # flag indicating support of 64-bit file offsets
|
2326
2360
|
List => undef, # extract lists of PrintConv values into arrays [no longer documented]
|
@@ -3860,6 +3894,10 @@ sub CanWrite($)
|
|
3860
3894
|
my $ext = GetFileExtension($file) || uc($file);
|
3861
3895
|
return grep(/^$ext$/, @{$noWriteFile{$type}}) ? 0 : 1 if $ext;
|
3862
3896
|
}
|
3897
|
+
if ($onlyWriteFile{$type}) {
|
3898
|
+
my $ext = GetFileExtension($file) || uc($file);
|
3899
|
+
return grep(/^$ext$/, @{$onlyWriteFile{$type}}) ? 1 : 0 if $ext;
|
3900
|
+
}
|
3863
3901
|
unless (%writeTypes) {
|
3864
3902
|
$writeTypes{$_} = 1 foreach @writeTypes;
|
3865
3903
|
}
|
@@ -3883,7 +3921,7 @@ sub CanCreate($)
|
|
3883
3921
|
#==============================================================================
|
3884
3922
|
# Functions below this are not part of the public API
|
3885
3923
|
|
3886
|
-
# Initialize member variables
|
3924
|
+
# Initialize member variables before reading or writing a new file
|
3887
3925
|
# Inputs: 0) ExifTool object reference
|
3888
3926
|
sub Init($)
|
3889
3927
|
{
|
@@ -4027,6 +4065,57 @@ sub NextTagKey($$)
|
|
4027
4065
|
return undef;
|
4028
4066
|
}
|
4029
4067
|
|
4068
|
+
#------------------------------------------------------------------------------
|
4069
|
+
# Does a string contain valid UTF-8 characters?
|
4070
|
+
# Inputs: 0) string reference, 1) true to allow last character to be truncated
|
4071
|
+
# Returns: 0=regular ASCII, -1=invalid UTF-8, 1=valid UTF-8 with maximum 16-bit
|
4072
|
+
# wide characters, 2=valid UTF-8 requiring 32-bit wide characters
|
4073
|
+
# Notes: Changes current string position
|
4074
|
+
# (see http://www.fileformat.info/info/unicode/utf8.htm for help understanding this)
|
4075
|
+
sub IsUTF8($;$)
|
4076
|
+
{
|
4077
|
+
my ($strPt, $trunc) = @_;
|
4078
|
+
pos($$strPt) = 0; # start at beginning of string
|
4079
|
+
return 0 unless $$strPt =~ /([\x80-\xff])/g;
|
4080
|
+
my $rtnVal = 1;
|
4081
|
+
for (;;) {
|
4082
|
+
my $ch = ord($1);
|
4083
|
+
# minimum lead byte for 2-byte sequence is 0xc2 (overlong sequences
|
4084
|
+
# not allowed), 0xf8-0xfd are restricted by RFC 3629 (no 5 or 6 byte
|
4085
|
+
# sequences), and 0xfe and 0xff are not valid in UTF-8 strings
|
4086
|
+
return -1 if $ch < 0xc2 or $ch >= 0xf8;
|
4087
|
+
# determine number of bytes remaining in sequence
|
4088
|
+
my $n;
|
4089
|
+
if ($ch < 0xe0) {
|
4090
|
+
$n = 1;
|
4091
|
+
} elsif ($ch < 0xf0) {
|
4092
|
+
$n = 2;
|
4093
|
+
} else {
|
4094
|
+
$n = 3;
|
4095
|
+
# character code is greater than 0xffff if more than 2 extra bytes
|
4096
|
+
# were required in the UTF-8 character
|
4097
|
+
$rtnVal = 2;
|
4098
|
+
}
|
4099
|
+
my $pos = pos $$strPt;
|
4100
|
+
unless ($$strPt =~ /\G([\x80-\xbf]{$n})/g) {
|
4101
|
+
return $rtnVal if $trunc and $pos + $n > length $$strPt;
|
4102
|
+
return -1;
|
4103
|
+
}
|
4104
|
+
# the following is ref https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c
|
4105
|
+
if ($n == 2) {
|
4106
|
+
return -1 if ($ch == 0xe0 and (ord($1) & 0xe0) == 0x80) or
|
4107
|
+
($ch == 0xed and (ord($1) & 0xe0) == 0xa0) or
|
4108
|
+
($ch == 0xef and ord($1) == 0xbf and
|
4109
|
+
(ord(substr $1, 1) & 0xfe) == 0xbe);
|
4110
|
+
} else {
|
4111
|
+
return -1 if ($ch == 0xf0 and (ord($1) & 0xf0) == 0x80) or
|
4112
|
+
($ch == 0xf4 and ord($1) > 0x8f) or $ch > 0xf4;
|
4113
|
+
}
|
4114
|
+
last unless $$strPt =~ /([\x80-\xff])/g;
|
4115
|
+
}
|
4116
|
+
return $rtnVal;
|
4117
|
+
}
|
4118
|
+
|
4030
4119
|
#------------------------------------------------------------------------------
|
4031
4120
|
# Split file name into directory and name parts
|
4032
4121
|
# Inptus: 0) file name
|
@@ -4072,10 +4161,7 @@ sub EncodeFileName($$;$)
|
|
4072
4161
|
}
|
4073
4162
|
}
|
4074
4163
|
} elsif ($^O eq 'MSWin32' and $file =~ /[\x80-\xff]/ and not defined $enc) {
|
4075
|
-
|
4076
|
-
if (Image::ExifTool::XMP::IsUTF8(\$file) < 0) {
|
4077
|
-
$self->WarnOnce('FileName encoding not specified');
|
4078
|
-
}
|
4164
|
+
$self->WarnOnce('FileName encoding not specified') if IsUTF8(\$file) < 0;
|
4079
4165
|
}
|
4080
4166
|
return 0;
|
4081
4167
|
}
|
@@ -4100,10 +4186,15 @@ sub Open($*$;$)
|
|
4100
4186
|
# handle Windows Unicode file name
|
4101
4187
|
local $SIG{'__WARN__'} = \&SetWarning;
|
4102
4188
|
my ($access, $create);
|
4103
|
-
if ($mode eq '>') {
|
4189
|
+
if ($mode eq '>' or $mode eq '>>') {
|
4104
4190
|
eval {
|
4105
4191
|
$access = Win32API::File::GENERIC_WRITE();
|
4106
|
-
$
|
4192
|
+
if ($mode eq '>>') {
|
4193
|
+
$access |= Win32API::File::FILE_APPEND_DATA();
|
4194
|
+
$create = Win32API::File::OPEN_ALWAYS();
|
4195
|
+
} else {
|
4196
|
+
$create = Win32API::File::CREATE_ALWAYS();
|
4197
|
+
}
|
4107
4198
|
}
|
4108
4199
|
} else {
|
4109
4200
|
eval {
|
@@ -4359,11 +4450,15 @@ sub ParseArguments($;@)
|
|
4359
4450
|
sub IsSameID($$)
|
4360
4451
|
{
|
4361
4452
|
my ($id, $grp) = @_;
|
4362
|
-
|
4363
|
-
|
4364
|
-
|
4365
|
-
|
4366
|
-
|
4453
|
+
for (;;) {
|
4454
|
+
return 1 if $grp eq $id; # decimal ID's or raw ID's
|
4455
|
+
if ($id =~ /^\d+$/) { # numerical numerical ID's may be in hex
|
4456
|
+
return 1 if $grp =~ s/^0x0*// and $grp eq sprintf('%x', $id);
|
4457
|
+
} else { # other ID's may conform to ExifTool group name conventions
|
4458
|
+
my $tmp = $id;
|
4459
|
+
return 1 if $tmp =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge and $grp eq $tmp;
|
4460
|
+
}
|
4461
|
+
last unless $id =~ s/-.*//; # remove language code if it exists
|
4367
4462
|
}
|
4368
4463
|
return 0;
|
4369
4464
|
}
|
@@ -5689,8 +5784,8 @@ sub ConvertDateTime($$)
|
|
5689
5784
|
$a[4] -= 1; # base month is 1
|
5690
5785
|
# parse our %f fractional seconds first (and round up seconds if necessary)
|
5691
5786
|
# - if there are multiple %f codes, they all get the same number of digits as the first
|
5692
|
-
if ($fmt =~
|
5693
|
-
my $dig = $1;
|
5787
|
+
if ($fmt =~ /%(-?)\.?(\d*)f/) {
|
5788
|
+
my ($neg, $dig) = ($1, $2);
|
5694
5789
|
my $frac = $date =~ /(\.\d+)/ ? $1 : '';
|
5695
5790
|
if (not $frac) {
|
5696
5791
|
$frac = '.' . ('0' x $dig) if $dig;
|
@@ -5717,7 +5812,8 @@ sub ConvertDateTime($$)
|
|
5717
5812
|
}
|
5718
5813
|
}
|
5719
5814
|
}
|
5720
|
-
$
|
5815
|
+
$neg and $frac =~ s/^\.//;
|
5816
|
+
$fmt =~ s/(^|[^%])((%%)*)%-?\.?\d*f/$1$2$frac/g;
|
5721
5817
|
}
|
5722
5818
|
# parse %z and %s ourself (to handle time zones properly)
|
5723
5819
|
if ($fmt =~ /%[sz]/) {
|
@@ -5863,7 +5959,7 @@ sub GetUnixTime($;$)
|
|
5863
5959
|
{
|
5864
5960
|
my ($timeStr, $isLocal) = @_;
|
5865
5961
|
return 0 if $timeStr eq '0000:00:00 00:00:00';
|
5866
|
-
my @tm = ($timeStr =~ /^(\d+)
|
5962
|
+
my @tm = ($timeStr =~ /^(\d+)[-:](\d+)[-:](\d+)\s+(\d+):(\d+):(\d+)(.*)/);
|
5867
5963
|
return undef unless @tm == 7;
|
5868
5964
|
unless (eval { require Time::Local }) {
|
5869
5965
|
warn "Time::Local is not installed\n";
|
@@ -7955,11 +8051,11 @@ sub GetTagInfo($$$;$$$)
|
|
7955
8051
|
next;
|
7956
8052
|
}
|
7957
8053
|
}
|
7958
|
-
|
7959
|
-
|
7960
|
-
|
8054
|
+
# don't return Unknown tags unless that option is set (also see forum13716)
|
8055
|
+
if ($$tagInfo{Unknown} and not $$self{OPTIONS}{Unknown} and not
|
8056
|
+
($$self{OPTIONS}{Verbose} or $$self{HTML_DUMP} or
|
8057
|
+
($$self{OPTIONS}{Validate} and not $$tagInfo{AddedUnknown})))
|
7961
8058
|
{
|
7962
|
-
# don't return Unknown tags unless that option is set
|
7963
8059
|
return undef;
|
7964
8060
|
}
|
7965
8061
|
# return the tag information we found
|
@@ -7984,6 +8080,7 @@ sub GetTagInfo($$$;$$$)
|
|
7984
8080
|
Unknown => 1,
|
7985
8081
|
Writable => 0, # can't write unknown tags
|
7986
8082
|
PrintConv => $printConv,
|
8083
|
+
AddedUnknown => 1,
|
7987
8084
|
};
|
7988
8085
|
# add tag information to table
|
7989
8086
|
AddTagToTable($tagTablePtr, $tagID, $tagInfo);
|
@@ -8045,6 +8142,7 @@ sub AddTagToTable($$;$$)
|
|
8045
8142
|
unless (defined $$tagTablePtr{$tagID} or $specialTags{$tagID}) {
|
8046
8143
|
$$tagTablePtr{$tagID} = $tagInfo;
|
8047
8144
|
}
|
8145
|
+
$$tagInfo{AddedUnknown} = 1 if $$tagInfo{Unknown};
|
8048
8146
|
return $tagInfo;
|
8049
8147
|
}
|
8050
8148
|
|
@@ -8187,15 +8285,17 @@ sub FoundTag($$$;@)
|
|
8187
8285
|
{
|
8188
8286
|
local $_;
|
8189
8287
|
my ($self, $tagInfo, $value, @grps) = @_;
|
8190
|
-
my ($tag, $noListDel);
|
8288
|
+
my ($tag, $noListDel, $tbl);
|
8191
8289
|
my $options = $$self{OPTIONS};
|
8192
8290
|
|
8193
8291
|
if (ref $tagInfo eq 'HASH') {
|
8194
8292
|
$tag = $$tagInfo{Name} or warn("No tag name\n"), return undef;
|
8293
|
+
$tbl = $$tagInfo{Table};
|
8195
8294
|
} else {
|
8196
8295
|
$tag = $tagInfo;
|
8197
8296
|
# look for tag in Extra
|
8198
|
-
$
|
8297
|
+
$tbl = GetTagTable('Image::ExifTool::Extra');
|
8298
|
+
$tagInfo = $self->GetTagInfo($tbl, $tag);
|
8199
8299
|
# make temporary hash if tag doesn't exist in Extra
|
8200
8300
|
# (not advised to do this since the tag won't show in list)
|
8201
8301
|
$tagInfo or $tagInfo = { Name => $tag, Groups => \%allGroupsExifTool };
|
@@ -8204,7 +8304,7 @@ sub FoundTag($$$;@)
|
|
8204
8304
|
# get tag priority
|
8205
8305
|
my $priority = $$tagInfo{Priority};
|
8206
8306
|
unless (defined $priority) {
|
8207
|
-
$priority = $$
|
8307
|
+
$priority = $$tbl{PRIORITY};
|
8208
8308
|
$priority = 0 if not defined $priority and $$tagInfo{Avoid};
|
8209
8309
|
}
|
8210
8310
|
$grps[0] or $grps[0] = $$self{SET_GROUP0};
|
@@ -8233,6 +8333,14 @@ sub FoundTag($$$;@)
|
|
8233
8333
|
$self->Warn("RawConv $tag: " . CleanWarning()) if $evalWarning;
|
8234
8334
|
return undef unless defined $value;
|
8235
8335
|
}
|
8336
|
+
# ignore specified tags (AFTER doing RawConv if necessary!)
|
8337
|
+
if ($$options{IgnoreTags}) {
|
8338
|
+
if ($$options{IgnoreTags}{all}) {
|
8339
|
+
return undef unless $$self{REQ_TAG_LOOKUP}{lc $tag};
|
8340
|
+
} else {
|
8341
|
+
return undef if $$options{IgnoreTags}{lc $tag};
|
8342
|
+
}
|
8343
|
+
}
|
8236
8344
|
# handle duplicate tag names
|
8237
8345
|
if (defined $$valueHash{$tag}) {
|
8238
8346
|
# add to list if there is an active list for this tag
|
@@ -8444,7 +8552,7 @@ sub SetFileType($;$$$)
|
|
8444
8552
|
|
8445
8553
|
#------------------------------------------------------------------------------
|
8446
8554
|
# Override the FileType and MIMEType tags
|
8447
|
-
# Inputs: 0) ExifTool object ref, 1) file type, 2) MIME type, 3) normal extension
|
8555
|
+
# Inputs: 0) ExifTool object ref, 1) file type, 2) MIME type, 3) normal extension (lower case)
|
8448
8556
|
# Notes: does nothing if FileType was not previously defined (ie. when writing)
|
8449
8557
|
sub OverrideFileType($$;$$)
|
8450
8558
|
{
|