exiftool_vendored 12.17.1 → 12.32.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 +225 -1
- data/bin/MANIFEST +23 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +45 -43
- data/bin/arg_files/xmp2exif.args +2 -1
- data/bin/config_files/acdsee.config +193 -6
- data/bin/config_files/convert_regions.config +25 -14
- data/bin/config_files/cuepointlist.config +70 -0
- data/bin/config_files/example.config +2 -9
- data/bin/exiftool +142 -87
- data/bin/fmt_files/gpx.fmt +2 -2
- data/bin/fmt_files/gpx_wpt.fmt +2 -2
- data/bin/fmt_files/kml.fmt +1 -1
- data/bin/fmt_files/kml_track.fmt +1 -1
- data/bin/lib/Image/ExifTool/Apple.pm +3 -2
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +30 -12
- data/bin/lib/Image/ExifTool/CBOR.pm +277 -0
- data/bin/lib/Image/ExifTool/Canon.pm +49 -18
- data/bin/lib/Image/ExifTool/DJI.pm +6 -6
- data/bin/lib/Image/ExifTool/DPX.pm +13 -2
- data/bin/lib/Image/ExifTool/DjVu.pm +6 -5
- data/bin/lib/Image/ExifTool/Exif.pm +28 -11
- data/bin/lib/Image/ExifTool/FITS.pm +13 -2
- data/bin/lib/Image/ExifTool/FlashPix.pm +35 -10
- data/bin/lib/Image/ExifTool/FujiFilm.pm +19 -8
- data/bin/lib/Image/ExifTool/GPS.pm +22 -11
- data/bin/lib/Image/ExifTool/Geotag.pm +13 -2
- data/bin/lib/Image/ExifTool/GoPro.pm +16 -1
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +2 -2
- data/bin/lib/Image/ExifTool/ID3.pm +15 -3
- data/bin/lib/Image/ExifTool/JPEG.pm +74 -4
- data/bin/lib/Image/ExifTool/JSON.pm +27 -4
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +393 -16
- data/bin/lib/Image/ExifTool/LIF.pm +153 -0
- data/bin/lib/Image/ExifTool/Lang/nl.pm +60 -59
- data/bin/lib/Image/ExifTool/M2TS.pm +137 -5
- data/bin/lib/Image/ExifTool/MIE.pm +4 -3
- data/bin/lib/Image/ExifTool/MRC.pm +341 -0
- data/bin/lib/Image/ExifTool/MWG.pm +3 -3
- data/bin/lib/Image/ExifTool/MXF.pm +1 -1
- data/bin/lib/Image/ExifTool/MacOS.pm +1 -1
- data/bin/lib/Image/ExifTool/Microsoft.pm +298 -82
- data/bin/lib/Image/ExifTool/Nikon.pm +19 -8
- data/bin/lib/Image/ExifTool/NikonSettings.pm +28 -11
- data/bin/lib/Image/ExifTool/Olympus.pm +6 -3
- data/bin/lib/Image/ExifTool/Other.pm +93 -0
- data/bin/lib/Image/ExifTool/PDF.pm +9 -12
- data/bin/lib/Image/ExifTool/PNG.pm +8 -7
- data/bin/lib/Image/ExifTool/Panasonic.pm +28 -3
- data/bin/lib/Image/ExifTool/Pentax.pm +28 -5
- data/bin/lib/Image/ExifTool/PhaseOne.pm +4 -3
- data/bin/lib/Image/ExifTool/Photoshop.pm +6 -0
- data/bin/lib/Image/ExifTool/QuickTime.pm +247 -88
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +283 -141
- data/bin/lib/Image/ExifTool/README +3 -0
- data/bin/lib/Image/ExifTool/RIFF.pm +89 -12
- data/bin/lib/Image/ExifTool/Samsung.pm +48 -10
- data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -0
- data/bin/lib/Image/ExifTool/Sony.pm +237 -78
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +1 -0
- data/bin/lib/Image/ExifTool/TagLookup.pm +4125 -4028
- data/bin/lib/Image/ExifTool/TagNames.pod +644 -286
- data/bin/lib/Image/ExifTool/Torrent.pm +18 -11
- data/bin/lib/Image/ExifTool/WriteExif.pl +1 -1
- data/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePDF.pl +1 -0
- data/bin/lib/Image/ExifTool/WritePNG.pl +2 -0
- data/bin/lib/Image/ExifTool/WritePostScript.pl +1 -0
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +55 -21
- data/bin/lib/Image/ExifTool/WriteXMP.pl +7 -3
- data/bin/lib/Image/ExifTool/Writer.pl +47 -10
- data/bin/lib/Image/ExifTool/XMP.pm +39 -14
- data/bin/lib/Image/ExifTool/XMP2.pl +2 -1
- data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
- data/bin/lib/Image/ExifTool/ZISRAW.pm +121 -2
- data/bin/lib/Image/ExifTool.pm +223 -72
- data/bin/lib/Image/ExifTool.pod +114 -93
- data/bin/perl-Image-ExifTool.spec +43 -42
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +28 -13
data/bin/lib/Image/ExifTool.pm
CHANGED
|
@@ -26,9 +26,10 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
|
|
|
26
26
|
$psAPP13hdr $psAPP13old @loadAllTables %UserDefined $evalWarning
|
|
27
27
|
%noWriteFile %magicNumber @langs $defaultLang %langName %charsetName
|
|
28
28
|
%mimeType $swapBytes $swapWords $currentByteOrder %unpackStd
|
|
29
|
-
%jpegMarker %specialTags %fileTypeLookup $testLen $exePath
|
|
29
|
+
%jpegMarker %specialTags %fileTypeLookup $testLen $exePath
|
|
30
|
+
%static_vars);
|
|
30
31
|
|
|
31
|
-
$VERSION = '12.
|
|
32
|
+
$VERSION = '12.32';
|
|
32
33
|
$RELEASE = '';
|
|
33
34
|
@ISA = qw(Exporter);
|
|
34
35
|
%EXPORT_TAGS = (
|
|
@@ -42,7 +43,7 @@ $RELEASE = '';
|
|
|
42
43
|
DataAccess => [qw(
|
|
43
44
|
ReadValue GetByteOrder SetByteOrder ToggleByteOrder Get8u Get8s Get16u
|
|
44
45
|
Get16s Get32u Get32s Get64u GetFloat GetDouble GetFixed32s Write
|
|
45
|
-
WriteValue Tell Set8u Set8s Set16u Set32u Set64u
|
|
46
|
+
WriteValue Tell Set8u Set8s Set16u Set32u Set64u Set64s
|
|
46
47
|
)],
|
|
47
48
|
Utils => [qw(GetTagTable TagTableKeys GetTagInfoList AddTagToTable HexDump)],
|
|
48
49
|
Vars => [qw(%allTables @tableOrder @fileTypes)],
|
|
@@ -70,7 +71,7 @@ sub SetFileName($$;$$$);
|
|
|
70
71
|
sub SetSystemTags($$);
|
|
71
72
|
sub GetAllTags(;$);
|
|
72
73
|
sub GetWritableTags(;$);
|
|
73
|
-
sub GetAllGroups(
|
|
74
|
+
sub GetAllGroups($;$);
|
|
74
75
|
sub GetNewGroups($);
|
|
75
76
|
sub GetDeleteGroups();
|
|
76
77
|
sub AddUserDefinedTags($%);
|
|
@@ -89,6 +90,7 @@ sub Get64u($$);
|
|
|
89
90
|
sub GetFixed64s($$);
|
|
90
91
|
sub GetExtended($$);
|
|
91
92
|
sub Set64u(@);
|
|
93
|
+
sub Set64s(@);
|
|
92
94
|
sub DecodeBits($$;$);
|
|
93
95
|
sub EncodeBits($$;$$);
|
|
94
96
|
sub Filter($$$);
|
|
@@ -137,18 +139,18 @@ sub ReadValue($$$;$$$);
|
|
|
137
139
|
@loadAllTables = qw(
|
|
138
140
|
PhotoMechanic Exif GeoTiff CanonRaw KyoceraRaw Lytro MinoltaRaw PanasonicRaw
|
|
139
141
|
SigmaRaw JPEG GIMP Jpeg2000 GIF BMP BMP::OS2 BMP::Extra BPG BPG::Extensions
|
|
140
|
-
PICT PNG MNG FLIF DjVu DPX OpenEXR ZISRAW MIFF PCX PGF
|
|
141
|
-
PDF PostScript Photoshop::Header
|
|
142
|
-
FujiFilm::RAF FujiFilm::IFD
|
|
143
|
-
Sony::PMP ITC ID3 ID3::Lyrics3
|
|
144
|
-
APE::OldHeader Audible MPC MPEG::Audio
|
|
145
|
-
QuickTime::ImageFile QuickTime::Stream
|
|
146
|
-
MXF DV Flash Flash::FLV Real::Media
|
|
147
|
-
ASF WTV DICOM FITS MIE JSON HTML
|
|
148
|
-
|
|
149
|
-
EXE::CHM LNK Font VCard Text
|
|
150
|
-
ZIP::RAR RTF OOXML iWork ISO
|
|
151
|
-
FlashPix::DocTable
|
|
142
|
+
PICT PNG MNG FLIF DjVu DPX OpenEXR ZISRAW MRC LIF MRC::FEI12 MIFF PCX PGF
|
|
143
|
+
PSP PhotoCD Radiance Other::PFM PDF PostScript Photoshop::Header
|
|
144
|
+
Photoshop::Layers Photoshop::ImageData FujiFilm::RAF FujiFilm::IFD
|
|
145
|
+
Samsung::Trailer Sony::SRF2 Sony::SR2SubIFD Sony::PMP ITC ID3 ID3::Lyrics3
|
|
146
|
+
FLAC Ogg Vorbis APE APE::NewHeader APE::OldHeader Audible MPC MPEG::Audio
|
|
147
|
+
MPEG::Video MPEG::Xing M2TS QuickTime QuickTime::ImageFile QuickTime::Stream
|
|
148
|
+
QuickTime::Tags360Fly Matroska MOI MXF DV Flash Flash::FLV Real::Media
|
|
149
|
+
Real::Audio Real::Metafile Red RIFF AIFF ASF WTV DICOM FITS MIE JSON HTML
|
|
150
|
+
XMP::SVG Palm Palm::MOBI Palm::EXTH Torrent EXE EXE::PEVersion EXE::PEString
|
|
151
|
+
EXE::MachO EXE::PEF EXE::ELF EXE::AR EXE::CHM LNK Font VCard Text
|
|
152
|
+
VCard::VCalendar RSRC Rawzor ZIP ZIP::GZIP ZIP::RAR RTF OOXML iWork ISO
|
|
153
|
+
FLIR::AFF FLIR::FPF MacOS MacOS::MDItem FlashPix::DocTable
|
|
152
154
|
);
|
|
153
155
|
|
|
154
156
|
# alphabetical list of current Lang modules
|
|
@@ -188,12 +190,12 @@ $defaultLang = 'en'; # default language
|
|
|
188
190
|
FLAC APE MPC MKV MXF DV PMP IND PGF ICC ITC FLIR FLIF FPF LFP
|
|
189
191
|
HTML VRD RTF FITS XCF DSS QTIF FPX PICT ZIP GZIP PLIST RAR BZ2
|
|
190
192
|
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
|
|
192
|
-
ISO ALIAS JSON MP3 DICOM PCD TXT);
|
|
193
|
+
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);
|
|
193
195
|
|
|
194
196
|
# file types that we can write (edit)
|
|
195
197
|
my @writeTypes = qw(JPEG TIFF GIF CRW MRW ORF RAF RAW PNG MIE PSD XMP PPM EPS
|
|
196
|
-
X3F PS PDF ICC VRD DR4 JP2 EXIF AI AIT IND MOV EXV FLIF);
|
|
198
|
+
X3F PS PDF ICC VRD DR4 JP2 JXL EXIF AI AIT IND MOV EXV FLIF);
|
|
197
199
|
my %writeTypes; # lookup for writable file types (hash filled if required)
|
|
198
200
|
|
|
199
201
|
# file extensions that we can't write for various base types
|
|
@@ -266,6 +268,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
|
266
268
|
DIB => ['BMP', 'Device Independent Bitmap'],
|
|
267
269
|
DIC => 'DICM',
|
|
268
270
|
DICM => ['DICOM','Digital Imaging and Communications in Medicine'],
|
|
271
|
+
DIR => ['DIR', 'Directory'],
|
|
269
272
|
DIVX => ['ASF', 'DivX media format'],
|
|
270
273
|
DJV => 'DJVU',
|
|
271
274
|
DJVU => ['AIFF', 'DjVu image'],
|
|
@@ -290,6 +293,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
|
290
293
|
DWF => ['DWF', 'Autodesk drawing (Design Web Format)'],
|
|
291
294
|
DWG => ['DWG', 'AutoCAD Drawing'],
|
|
292
295
|
DYLIB=> ['EXE', 'Mach-O Dynamic Link Library'],
|
|
296
|
+
DXF => ['DXF', 'AutoCAD Drawing Exchange Format'],
|
|
293
297
|
EIP => ['ZIP', 'Capture One Enhanced Image Package'],
|
|
294
298
|
EPS => ['EPS', 'Encapsulated PostScript Format'],
|
|
295
299
|
EPS2 => 'EPS',
|
|
@@ -351,8 +355,10 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
|
351
355
|
JPF => 'JP2',
|
|
352
356
|
JPG => 'JPEG',
|
|
353
357
|
JPM => ['JP2', 'JPEG 2000 compound image'],
|
|
358
|
+
JPS => ['JPEG', 'JPEG Stereo image'],
|
|
354
359
|
JPX => ['JP2', 'JPEG 2000 with extensions'],
|
|
355
360
|
JSON => ['JSON', 'JavaScript Object Notation'],
|
|
361
|
+
JXL => ['JXL', 'JPEG XL'],
|
|
356
362
|
JXR => ['TIFF', 'JPEG XR'],
|
|
357
363
|
K25 => ['TIFF', 'Kodak DC25 RAW'],
|
|
358
364
|
KDC => ['TIFF', 'Kodak Digital Camera RAW'],
|
|
@@ -361,6 +367,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
|
361
367
|
LA => ['RIFF', 'Lossless Audio'],
|
|
362
368
|
LFP => ['LFP', 'Lytro Light Field Picture'],
|
|
363
369
|
LFR => 'LFP', # (Light Field RAW)
|
|
370
|
+
LIF => ['LIF', 'Leica Image File'],
|
|
364
371
|
LNK => ['LNK', 'Windows shortcut'],
|
|
365
372
|
LRI => ['LRI', 'Light RAW'],
|
|
366
373
|
LRV => ['MOV', 'Low-Resolution Video'],
|
|
@@ -392,6 +399,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
|
392
399
|
MPG => 'MPEG',
|
|
393
400
|
MPO => ['JPEG', 'Extended Multi-Picture format'],
|
|
394
401
|
MQV => ['MOV', 'Sony Mobile Quicktime Video'],
|
|
402
|
+
MRC => ['MRC', 'Medical Research Council image'],
|
|
395
403
|
MRW => ['MRW', 'Minolta RAW format'],
|
|
396
404
|
MTS => 'M2TS',
|
|
397
405
|
MXF => ['MXF', 'Material Exchange Format'],
|
|
@@ -416,6 +424,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
|
416
424
|
ONP => ['JSON', 'ON1 Presets'],
|
|
417
425
|
OPUS => ['OGG', 'Ogg Opus audio file'],
|
|
418
426
|
ORF => ['ORF', 'Olympus RAW format'],
|
|
427
|
+
ORI => 'ORF',
|
|
419
428
|
OTF => ['Font', 'Open Type Font'],
|
|
420
429
|
PAC => ['RIFF', 'Lossless Predictive Audio Compression'],
|
|
421
430
|
PAGES => ['ZIP', 'Apple Pages document'],
|
|
@@ -428,7 +437,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
|
428
437
|
PEF => ['TIFF', 'Pentax (RAW) Electronic Format'],
|
|
429
438
|
PFA => ['Font', 'PostScript Font ASCII'],
|
|
430
439
|
PFB => ['Font', 'PostScript Font Binary'],
|
|
431
|
-
PFM => ['Font', 'Printer Font Metrics'],
|
|
440
|
+
PFM => [['Font','PFM2'], 'Printer Font Metrics'], # (description is overridden for Portable FloatMap images)
|
|
432
441
|
PGF => ['PGF', 'Progressive Graphics File'],
|
|
433
442
|
PGM => ['PPM', 'Portable Gray Map'],
|
|
434
443
|
PHP => ['PHP', 'PHP Hypertext Preprocessor'],
|
|
@@ -599,7 +608,7 @@ my %fileDescription = (
|
|
|
599
608
|
DJVU => 'image/vnd.djvu',
|
|
600
609
|
DNG => 'image/x-adobe-dng',
|
|
601
610
|
DOC => 'application/msword',
|
|
602
|
-
DOCM => 'application/vnd.ms-word.document.macroEnabled',
|
|
611
|
+
DOCM => 'application/vnd.ms-word.document.macroEnabled.12',
|
|
603
612
|
DOCX => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
604
613
|
DOT => 'application/msword',
|
|
605
614
|
DOTM => 'application/vnd.ms-word.template.macroEnabledTemplate',
|
|
@@ -612,6 +621,7 @@ my %fileDescription = (
|
|
|
612
621
|
'DVR-MS' => 'video/x-ms-dvr',
|
|
613
622
|
DWF => 'model/vnd.dwf',
|
|
614
623
|
DWG => 'image/vnd.dwg',
|
|
624
|
+
DXF => 'application/dxf',
|
|
615
625
|
EIP => 'application/x-captureone', #(NC)
|
|
616
626
|
EPS => 'application/postscript',
|
|
617
627
|
ERF => 'image/x-epson-erf',
|
|
@@ -647,13 +657,16 @@ my %fileDescription = (
|
|
|
647
657
|
JP2 => 'image/jp2',
|
|
648
658
|
JPEG => 'image/jpeg',
|
|
649
659
|
JPM => 'image/jpm',
|
|
660
|
+
JPS => 'image/x-jps',
|
|
650
661
|
JPX => 'image/jpx',
|
|
651
662
|
JSON => 'application/json',
|
|
663
|
+
JXL => 'image/jxl', #PH (NC)
|
|
652
664
|
JXR => 'image/jxr',
|
|
653
665
|
K25 => 'image/x-kodak-k25',
|
|
654
666
|
KDC => 'image/x-kodak-kdc',
|
|
655
667
|
KEY => 'application/x-iwork-keynote-sffkey',
|
|
656
668
|
LFP => 'image/x-lytro-lfp', #PH (NC)
|
|
669
|
+
LIF => 'image/x-lif',
|
|
657
670
|
LNK => 'application/octet-stream',
|
|
658
671
|
LRI => 'image/x-light-lri',
|
|
659
672
|
M2T => 'video/mpeg',
|
|
@@ -674,6 +687,7 @@ my %fileDescription = (
|
|
|
674
687
|
MP4 => 'video/mp4',
|
|
675
688
|
MPC => 'audio/x-musepack',
|
|
676
689
|
MPEG => 'video/mpeg',
|
|
690
|
+
MRC => 'image/x-mrc',
|
|
677
691
|
MRW => 'image/x-minolta-mrw',
|
|
678
692
|
MXF => 'application/mxf',
|
|
679
693
|
NEF => 'image/x-nikon-nef',
|
|
@@ -708,16 +722,16 @@ my %fileDescription = (
|
|
|
708
722
|
PMP => 'image/x-sony-pmp', #PH (NC)
|
|
709
723
|
PNG => 'image/png',
|
|
710
724
|
POT => 'application/vnd.ms-powerpoint',
|
|
711
|
-
POTM => 'application/vnd.ms-powerpoint.template.macroEnabled',
|
|
725
|
+
POTM => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
|
|
712
726
|
POTX => 'application/vnd.openxmlformats-officedocument.presentationml.template',
|
|
713
|
-
PPAM => 'application/vnd.ms-powerpoint.addin.macroEnabled',
|
|
727
|
+
PPAM => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
|
|
714
728
|
PPAX => 'application/vnd.openxmlformats-officedocument.presentationml.addin', # (NC, PH invented)
|
|
715
729
|
PPM => 'image/x-portable-pixmap',
|
|
716
730
|
PPS => 'application/vnd.ms-powerpoint',
|
|
717
|
-
PPSM => 'application/vnd.ms-powerpoint.slideshow.macroEnabled',
|
|
731
|
+
PPSM => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
|
|
718
732
|
PPSX => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
|
|
719
733
|
PPT => 'application/vnd.ms-powerpoint',
|
|
720
|
-
PPTM => 'application/vnd.ms-powerpoint.presentation.macroEnabled',
|
|
734
|
+
PPTM => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
|
|
721
735
|
PPTX => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
722
736
|
PS => 'application/postscript',
|
|
723
737
|
PSD => 'application/vnd.adobe.photoshop',
|
|
@@ -764,13 +778,13 @@ my %fileDescription = (
|
|
|
764
778
|
X3F => 'image/x-sigma-x3f',
|
|
765
779
|
XCF => 'image/x-xcf',
|
|
766
780
|
XLA => 'application/vnd.ms-excel',
|
|
767
|
-
XLAM => 'application/vnd.ms-excel.addin.macroEnabled',
|
|
781
|
+
XLAM => 'application/vnd.ms-excel.addin.macroEnabled.12',
|
|
768
782
|
XLS => 'application/vnd.ms-excel',
|
|
769
|
-
XLSB => 'application/vnd.ms-excel.sheet.binary.macroEnabled',
|
|
770
|
-
XLSM => 'application/vnd.ms-excel.sheet.macroEnabled',
|
|
783
|
+
XLSB => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
|
|
784
|
+
XLSM => 'application/vnd.ms-excel.sheet.macroEnabled.12',
|
|
771
785
|
XLSX => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
772
786
|
XLT => 'application/vnd.ms-excel',
|
|
773
|
-
XLTM => 'application/vnd.ms-excel.template.macroEnabled',
|
|
787
|
+
XLTM => 'application/vnd.ms-excel.template.macroEnabled.12',
|
|
774
788
|
XLTX => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
|
|
775
789
|
XML => 'application/xml',
|
|
776
790
|
XMP => 'application/rdf+xml',
|
|
@@ -798,6 +812,7 @@ my %moduleName = (
|
|
|
798
812
|
DSS => 'Olympus',
|
|
799
813
|
DWF => 0,
|
|
800
814
|
DWG => 0,
|
|
815
|
+
DXF => 0,
|
|
801
816
|
EPS => 'PostScript',
|
|
802
817
|
EXIF => '',
|
|
803
818
|
EXR => 'OpenEXR',
|
|
@@ -811,6 +826,7 @@ my %moduleName = (
|
|
|
811
826
|
HDR => 'Radiance',
|
|
812
827
|
JP2 => 'Jpeg2000',
|
|
813
828
|
JPEG => '',
|
|
829
|
+
JXL => 'Jpeg2000',
|
|
814
830
|
LFP => 'Lytro',
|
|
815
831
|
LRI => 0,
|
|
816
832
|
MOV => 'QuickTime',
|
|
@@ -821,6 +837,7 @@ my %moduleName = (
|
|
|
821
837
|
ORF => 'Olympus',
|
|
822
838
|
PDB => 'Palm',
|
|
823
839
|
PCD => 'PhotoCD',
|
|
840
|
+
PFM2 => 'Other',
|
|
824
841
|
PHP => 0,
|
|
825
842
|
PMP => 'Sony',
|
|
826
843
|
PS => 'PostScript',
|
|
@@ -872,6 +889,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
|
872
889
|
DV => '\x1f\x07\0[\x3f\xbf]', # (not tested if extension recognized)
|
|
873
890
|
DWF => '\(DWF V\d',
|
|
874
891
|
DWG => 'AC10\d{2}\0',
|
|
892
|
+
DXF => '\s*0\s+\0?\s*SECTION\s+2\s+HEADER',
|
|
875
893
|
EPS => '(%!PS|%!Ad|\xc5\xd0\xd3\xc6)',
|
|
876
894
|
EXE => '(MZ|\xca\xfe\xba\xbe|\xfe\xed\xfa[\xce\xcf]|[\xce\xcf]\xfa\xed\xfe|Joy!peff|\x7fELF|#!\s*/\S*bin/|!<arch>\x0a)',
|
|
877
895
|
EXIF => '(II\x2a\0|MM\0\x2a)',
|
|
@@ -897,7 +915,9 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
|
897
915
|
JP2 => '(\0\0\0\x0cjP( |\x1a\x1a)\x0d\x0a\x87\x0a|\xff\x4f\xff\x51\0)',
|
|
898
916
|
JPEG => '\xff\xd8\xff',
|
|
899
917
|
JSON => '(\xef\xbb\xbf)?\s*(\[\s*)?\{\s*"[^"]*"\s*:',
|
|
918
|
+
JXL => '\xff\x0a|\0\0\0\x0cJXL \x0d\x0a......ftypjxl ',
|
|
900
919
|
LFP => '\x89LFP\x0d\x0a\x1a\x0a',
|
|
920
|
+
LIF => '\x70\0{3}.{4}\x2a.{4}<\0',
|
|
901
921
|
LNK => '.{4}\x01\x14\x02\0{5}\xc0\0{6}\x46',
|
|
902
922
|
LRI => 'LELR \0',
|
|
903
923
|
M2TS => '(....)?\x47',
|
|
@@ -909,14 +929,16 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
|
909
929
|
MPC => '(MP\+|ID3)',
|
|
910
930
|
MOI => 'V6',
|
|
911
931
|
MPEG => '\0\0\x01[\xb0-\xbf]',
|
|
932
|
+
MRC => '.{64}[\x01\x02\x03]\0\0\0[\x01\x02\x03]\0\0\0[\x01\x02\x03]\0\0\0.{132}MAP[\0 ](\x44\x44|\x44\x41|\x11\x11)\0\0',
|
|
912
933
|
MRW => '\0MR[MI]',
|
|
913
934
|
MXF => '\x06\x0e\x2b\x34\x02\x05\x01\x01\x0d\x01\x02', # (not tested if extension recognized)
|
|
914
935
|
OGG => '(OggS|ID3)',
|
|
915
936
|
ORF => '(II|MM)',
|
|
916
|
-
PDB => '.{60}(\.pdfADBE|TEXtREAd|BVokBDIC|DB99DBOS|PNRdPPrs|DataPPrs|vIMGView|PmDBPmDB|InfoINDB|ToGoToGo|SDocSilX|JbDbJBas|JfDbJFil|DATALSdb|Mdb1Mdb1|BOOKMOBI|DataPlkr|DataSprd|SM01SMem|TEXtTlDc|InfoTlIf|DataTlMl|DataTlPt|dataTDBP|TdatTide|ToRaTRPW|zTXTGPlm|BDOCWrdS)',
|
|
917
937
|
# PCD => signature is at byte 2048
|
|
918
938
|
PCX => '\x0a[\0-\x05]\x01[\x01\x02\x04\x08].{64}[\0-\x02]',
|
|
939
|
+
PDB => '.{60}(\.pdfADBE|TEXtREAd|BVokBDIC|DB99DBOS|PNRdPPrs|DataPPrs|vIMGView|PmDBPmDB|InfoINDB|ToGoToGo|SDocSilX|JbDbJBas|JfDbJFil|DATALSdb|Mdb1Mdb1|BOOKMOBI|DataPlkr|DataSprd|SM01SMem|TEXtTlDc|InfoTlIf|DataTlMl|DataTlPt|dataTDBP|TdatTide|ToRaTRPW|zTXTGPlm|BDOCWrdS)',
|
|
919
940
|
PDF => '\s*%PDF-\d+\.\d+',
|
|
941
|
+
PFM => 'P[Ff]\x0a\d+ \d+\x0a[-+0-9.]+\x0a',
|
|
920
942
|
PGF => 'PGF',
|
|
921
943
|
PHP => '<\?php\s',
|
|
922
944
|
PICT => '(.{10}|.{522})(\x11\x01|\x00\x11)',
|
|
@@ -1129,6 +1151,13 @@ my %systemTagsNotes = (
|
|
|
1129
1151
|
RawConv => '$self->ConvertFileName($val)',
|
|
1130
1152
|
ValueConvInv => '$self->InverseFileName($val)',
|
|
1131
1153
|
},
|
|
1154
|
+
BaseName => {
|
|
1155
|
+
Groups => { 1 => 'System', 2 => 'Other' },
|
|
1156
|
+
Notes => q{
|
|
1157
|
+
file name without extension. Not generated unless specifically requested or
|
|
1158
|
+
the L<RequestAll|../ExifTool.html#RequestAll> API option is set
|
|
1159
|
+
},
|
|
1160
|
+
},
|
|
1132
1161
|
FilePath => {
|
|
1133
1162
|
Groups => { 1 => 'System', 2 => 'Other' },
|
|
1134
1163
|
Notes => q{
|
|
@@ -1270,10 +1299,19 @@ my %systemTagsNotes = (
|
|
|
1270
1299
|
WritePseudo => 1,
|
|
1271
1300
|
DelCheck => q{"Can't delete"},
|
|
1272
1301
|
Protected => 1, # all writable pseudo-tags must be protected!
|
|
1273
|
-
ValueConv => 'sprintf("%.3o", $val
|
|
1274
|
-
ValueConvInv => 'oct($val)',
|
|
1302
|
+
ValueConv => 'sprintf("%.3o", $val)',
|
|
1303
|
+
ValueConvInv => 'oct($val & 07777)',
|
|
1275
1304
|
PrintConv => sub {
|
|
1276
|
-
my ($mask, $
|
|
1305
|
+
my ($mask, $val) = (0400, oct(shift));
|
|
1306
|
+
my %types = (
|
|
1307
|
+
0010000 => 'p',
|
|
1308
|
+
0020000 => 'c',
|
|
1309
|
+
0040000 => 'd',
|
|
1310
|
+
0060000 => 'b',
|
|
1311
|
+
0120000 => 'l',
|
|
1312
|
+
0140000 => 's',
|
|
1313
|
+
);
|
|
1314
|
+
my $str = $types{$val & 0170000} || '-';
|
|
1277
1315
|
while ($mask) {
|
|
1278
1316
|
foreach (qw(r w x)) {
|
|
1279
1317
|
$str .= $val & $mask ? $_ : '-';
|
|
@@ -1284,6 +1322,7 @@ my %systemTagsNotes = (
|
|
|
1284
1322
|
},
|
|
1285
1323
|
PrintConvInv => sub {
|
|
1286
1324
|
my ($bit, $val, $str) = (8, 0, shift);
|
|
1325
|
+
$str = substr($str, 1) if length($str) == 10;
|
|
1287
1326
|
return undef if length($str) != 9;
|
|
1288
1327
|
while ($bit >= 0) {
|
|
1289
1328
|
foreach (qw(r w x)) {
|
|
@@ -1737,7 +1776,10 @@ my %systemTagsNotes = (
|
|
|
1737
1776
|
EmbeddedVideo => { Groups => { 0 => 'Trailer', 2 => 'Video' } },
|
|
1738
1777
|
Trailer => {
|
|
1739
1778
|
Groups => { 0 => 'Trailer' },
|
|
1740
|
-
Notes =>
|
|
1779
|
+
Notes => q{
|
|
1780
|
+
the full JPEG trailer data block. Extracted only if specifically requested
|
|
1781
|
+
or the RequestAll API option is set to 3 or higher
|
|
1782
|
+
},
|
|
1741
1783
|
Writable => 1,
|
|
1742
1784
|
Protected => 1,
|
|
1743
1785
|
},
|
|
@@ -1898,6 +1940,8 @@ my %systemTagsNotes = (
|
|
|
1898
1940
|
return \$img;
|
|
1899
1941
|
},
|
|
1900
1942
|
},
|
|
1943
|
+
# Apple may add "AMPF" to the end of the JFIF record,
|
|
1944
|
+
# possibly indicating the existence of MPF images (ref forum12677)
|
|
1901
1945
|
);
|
|
1902
1946
|
|
|
1903
1947
|
# Composite tags (accumulation of all Composite tag tables)
|
|
@@ -2050,12 +2094,15 @@ sub Options($$;@)
|
|
|
2050
2094
|
$$options{$param} = $newVal;
|
|
2051
2095
|
delete $$self{CUR_LANG};
|
|
2052
2096
|
# make sure the language is available
|
|
2053
|
-
}
|
|
2054
|
-
my
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2097
|
+
} else {
|
|
2098
|
+
my %langs = map { $_ => 1 } @langs;
|
|
2099
|
+
if ($langs{$newVal} and eval "require Image::ExifTool::Lang::$newVal") {
|
|
2100
|
+
my $xlat = "Image::ExifTool::Lang::${newVal}::Translate";
|
|
2101
|
+
no strict 'refs';
|
|
2102
|
+
if (%$xlat) {
|
|
2103
|
+
$$self{CUR_LANG} = \%$xlat;
|
|
2104
|
+
$$options{$param} = $newVal;
|
|
2105
|
+
}
|
|
2059
2106
|
}
|
|
2060
2107
|
} # else don't change Lang
|
|
2061
2108
|
} elsif ($param eq 'Exclude' and defined $newVal) {
|
|
@@ -2271,7 +2318,7 @@ sub ClearOptions($)
|
|
|
2271
2318
|
NoPDFList => undef, # flag to avoid splitting PDF List-type tag values
|
|
2272
2319
|
Password => undef, # password for password-protected PDF documents
|
|
2273
2320
|
PrintConv => 1, # flag to enable print conversion
|
|
2274
|
-
QuickTimeHandler =>
|
|
2321
|
+
QuickTimeHandler => 1, # flag to add mdir Handler to newly created Meta box
|
|
2275
2322
|
QuickTimeUTC=> undef, # assume that QuickTime date/time tags are stored as UTC
|
|
2276
2323
|
RequestAll => undef, # extract all tags that must be specifically requested
|
|
2277
2324
|
RequestTags => undef, # extra tags to request (on top of those in the tag list)
|
|
@@ -2321,7 +2368,7 @@ sub ExtractInfo($;@)
|
|
|
2321
2368
|
my $fast = $$options{FastScan} || 0;
|
|
2322
2369
|
my $req = $$self{REQ_TAG_LOOKUP};
|
|
2323
2370
|
my $reqAll = $$options{RequestAll} || 0;
|
|
2324
|
-
my (%saveOptions, $reEntry, $rsize, $type, @startTime, $saveOrder);
|
|
2371
|
+
my (%saveOptions, $reEntry, $rsize, $type, @startTime, $saveOrder, $isDir);
|
|
2325
2372
|
|
|
2326
2373
|
# check for internal ReEntry option to allow recursive calls to ExtractInfo
|
|
2327
2374
|
if (ref $_[1] eq 'HASH' and $_[1]{ReEntry} and
|
|
@@ -2394,6 +2441,11 @@ sub ExtractInfo($;@)
|
|
|
2394
2441
|
$realname =~ /\|$/ and $realname =~ s/^.*?"(.*?)".*/$1/s;
|
|
2395
2442
|
my ($dir, $name) = SplitFileName($realname);
|
|
2396
2443
|
$self->FoundTag('FileName', $name);
|
|
2444
|
+
if ($$req{basename} or
|
|
2445
|
+
($reqAll and not $$self{EXCL_TAG_LOOKUP}{basename}))
|
|
2446
|
+
{
|
|
2447
|
+
$self->FoundTag('BaseName', $name =~ /(.*)\./ ? $1 : $name);
|
|
2448
|
+
}
|
|
2397
2449
|
$self->FoundTag('Directory', $dir) if defined $dir and length $dir;
|
|
2398
2450
|
if ($$req{filepath} or
|
|
2399
2451
|
($reqAll and not $$self{EXCL_TAG_LOOKUP}{filepath}))
|
|
@@ -2417,6 +2469,8 @@ sub ExtractInfo($;@)
|
|
|
2417
2469
|
# in Windows cmd shell pipe even though it really failed
|
|
2418
2470
|
$$raf{TESTED} = -1 if $filename eq '-' or $filename =~ /\|$/;
|
|
2419
2471
|
$$self{RAF} = $raf;
|
|
2472
|
+
} elsif ($self->IsDirectory($filename)) {
|
|
2473
|
+
$isDir = 1;
|
|
2420
2474
|
} else {
|
|
2421
2475
|
$self->Error('Error opening file');
|
|
2422
2476
|
}
|
|
@@ -2425,28 +2479,34 @@ sub ExtractInfo($;@)
|
|
|
2425
2479
|
}
|
|
2426
2480
|
}
|
|
2427
2481
|
|
|
2428
|
-
while ($raf) {
|
|
2429
|
-
my (@stat, $
|
|
2482
|
+
while ($raf or $isDir) {
|
|
2483
|
+
my (@stat, $plainFile);
|
|
2430
2484
|
if ($reEntry) {
|
|
2431
2485
|
# we already set these tags
|
|
2486
|
+
} elsif (not $raf) {
|
|
2487
|
+
@stat = stat $filename;
|
|
2432
2488
|
} elsif (not $$raf{FILE_PT}) {
|
|
2433
2489
|
# get file size from image in memory
|
|
2434
2490
|
$self->FoundTag('FileSize', length ${$$raf{BUFF_PT}});
|
|
2435
2491
|
} elsif (-f $$raf{FILE_PT}) {
|
|
2436
2492
|
# get file tags if this is a plain file
|
|
2437
|
-
$fileSize = -s _;
|
|
2438
2493
|
@stat = stat _;
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
$self->
|
|
2442
|
-
$self->FoundTag('FileModifyDate', $mTime) if defined $mTime;
|
|
2443
|
-
$self->FoundTag('FileAccessDate', $aTime) if defined $aTime;
|
|
2444
|
-
my $cTag = $^O eq 'MSWin32' ? 'FileCreateDate' : 'FileInodeChangeDate';
|
|
2445
|
-
$self->FoundTag($cTag, $cTime) if defined $cTime;
|
|
2446
|
-
$self->FoundTag('FilePermissions', $stat[2]) if defined $stat[2];
|
|
2494
|
+
$plainFile = 1;
|
|
2495
|
+
# hack to patch Windows daylight savings time bug
|
|
2496
|
+
@stat[8,9,10] = $self->GetFileTime($$raf{FILE_PT}) if $^O eq 'MSWin32';
|
|
2447
2497
|
} else {
|
|
2498
|
+
# (note that Windows directories will still show the
|
|
2499
|
+
# daylight savings time bug -- should fix this sometime)
|
|
2448
2500
|
@stat = stat $$raf{FILE_PT};
|
|
2449
2501
|
}
|
|
2502
|
+
my $fileSize = $stat[7];
|
|
2503
|
+
$self->FoundTag('FileSize', $stat[7]) if defined $stat[7];
|
|
2504
|
+
$self->FoundTag('ResourceForkSize', $rsize) if $rsize;
|
|
2505
|
+
$self->FoundTag('FileModifyDate', $stat[9]) if defined $stat[9];
|
|
2506
|
+
$self->FoundTag('FileAccessDate', $stat[8]) if defined $stat[8];
|
|
2507
|
+
my $cTag = $^O eq 'MSWin32' ? 'FileCreateDate' : 'FileInodeChangeDate';
|
|
2508
|
+
$self->FoundTag($cTag, $stat[10]) if defined $stat[10];
|
|
2509
|
+
$self->FoundTag('FilePermissions', $stat[2]) if defined $stat[2];
|
|
2450
2510
|
# extract more system info if SystemTags option is set
|
|
2451
2511
|
if (@stat) {
|
|
2452
2512
|
my $sys = $$options{SystemTags} || ($reqAll and not defined $$options{SystemTags});
|
|
@@ -2486,11 +2546,18 @@ sub ExtractInfo($;@)
|
|
|
2486
2546
|
if ($crDate or $mdItem or $xattr) {
|
|
2487
2547
|
require Image::ExifTool::MacOS;
|
|
2488
2548
|
Image::ExifTool::MacOS::GetFileCreateDate($self, $filename) if $crDate;
|
|
2489
|
-
Image::ExifTool::MacOS::ExtractMDItemTags($self, $filename) if $mdItem;
|
|
2549
|
+
Image::ExifTool::MacOS::ExtractMDItemTags($self, $filename) if $mdItem and $plainFile;
|
|
2490
2550
|
Image::ExifTool::MacOS::ExtractXAttrTags($self, $filename) if $xattr;
|
|
2491
2551
|
}
|
|
2492
2552
|
}
|
|
2493
|
-
|
|
2553
|
+
# do whatever else we can with directories, then return
|
|
2554
|
+
if ($isDir or (defined $stat[2] and ($stat[2] & 0170000) == 0040000)) {
|
|
2555
|
+
$self->FoundTag('FileType', 'DIR');
|
|
2556
|
+
$self->FoundTag('FileTypeExtension', '');
|
|
2557
|
+
$self->BuildCompositeTags() if $$options{Composite};
|
|
2558
|
+
$raf->Close() if $raf;
|
|
2559
|
+
return 1;
|
|
2560
|
+
}
|
|
2494
2561
|
# get list of file types to check
|
|
2495
2562
|
my ($tiffType, %noMagic, $recognizedExt);
|
|
2496
2563
|
my $ext = $$self{FILE_EXT} = GetFileExtension($realname);
|
|
@@ -3250,8 +3317,9 @@ sub GetTagID($$)
|
|
|
3250
3317
|
my ($self, $tag) = @_;
|
|
3251
3318
|
my $tagInfo = $$self{TAG_INFO}{$tag};
|
|
3252
3319
|
return '' unless $tagInfo and defined $$tagInfo{TagID};
|
|
3253
|
-
|
|
3254
|
-
return $$tagInfo{
|
|
3320
|
+
my $id = $$tagInfo{KeysID} || $$tagInfo{TagID};
|
|
3321
|
+
return ($id, $$tagInfo{LangCode}) if wantarray;
|
|
3322
|
+
return $id;
|
|
3255
3323
|
}
|
|
3256
3324
|
|
|
3257
3325
|
#------------------------------------------------------------------------------
|
|
@@ -3367,7 +3435,7 @@ sub GetGroup($$;$)
|
|
|
3367
3435
|
}
|
|
3368
3436
|
# generate tag ID group names unless obviously not needed
|
|
3369
3437
|
unless ($noID) {
|
|
3370
|
-
my $id = $$tagInfo{TagID};
|
|
3438
|
+
my $id = $$tagInfo{KeysID} || $$tagInfo{TagID};
|
|
3371
3439
|
if (not defined $id) {
|
|
3372
3440
|
$id = ''; # (just to be safe)
|
|
3373
3441
|
} elsif ($id =~ /^\d+$/) {
|
|
@@ -3722,7 +3790,15 @@ sub GetFileType(;$$)
|
|
|
3722
3790
|
# return description if specified
|
|
3723
3791
|
# (allow input $file to be a FileType for this purpose)
|
|
3724
3792
|
if ($desc) {
|
|
3725
|
-
|
|
3793
|
+
if ($fileType) {
|
|
3794
|
+
if ($static_vars{OverrideFileDescription} and $static_vars{OverrideFileDescription}{$fileExt}) {
|
|
3795
|
+
$desc = $static_vars{OverrideFileDescription}{$fileExt};
|
|
3796
|
+
} else {
|
|
3797
|
+
$desc = $$fileType[1];
|
|
3798
|
+
}
|
|
3799
|
+
} else {
|
|
3800
|
+
$desc = $fileDescription{$file};
|
|
3801
|
+
}
|
|
3726
3802
|
$desc .= ", $subType" if $subType;
|
|
3727
3803
|
return $desc;
|
|
3728
3804
|
} elsif ($fileType and (not defined $desc or $desc ne '0')) {
|
|
@@ -3787,6 +3863,7 @@ sub Init($)
|
|
|
3787
3863
|
foreach (keys %$self) {
|
|
3788
3864
|
/[a-z]/ and delete $$self{$_};
|
|
3789
3865
|
}
|
|
3866
|
+
undef %static_vars; # clear all static variables
|
|
3790
3867
|
delete $$self{FOUND_TAGS}; # list of found tags
|
|
3791
3868
|
delete $$self{EXIF_DATA}; # the EXIF data block
|
|
3792
3869
|
delete $$self{EXIF_POS}; # EXIF position in file
|
|
@@ -4044,7 +4121,9 @@ sub Exists($$)
|
|
|
4044
4121
|
return 0 unless $wh;
|
|
4045
4122
|
eval { Win32API::File::CloseHandle($wh) };
|
|
4046
4123
|
} else {
|
|
4047
|
-
|
|
4124
|
+
# (named pipes already exist, but we pretend that they don't
|
|
4125
|
+
# so we will be able to write them, so test with for pipe -p)
|
|
4126
|
+
return(-e $file and not -p $file);
|
|
4048
4127
|
}
|
|
4049
4128
|
return 1;
|
|
4050
4129
|
}
|
|
@@ -4079,7 +4158,14 @@ sub GetFileTime($$)
|
|
|
4079
4158
|
# open file by name if necessary
|
|
4080
4159
|
unless (ref $file) {
|
|
4081
4160
|
local *FH;
|
|
4082
|
-
$self->Open(\*FH, $file)
|
|
4161
|
+
unless ($self->Open(\*FH, $file)) {
|
|
4162
|
+
if ($self->IsDirectory($file)) {
|
|
4163
|
+
my @rtn = (stat $file)[8, 9, 10];
|
|
4164
|
+
return @rtn if defined $rtn[0];
|
|
4165
|
+
}
|
|
4166
|
+
$self->Warn("GetFileTime error for '${file}'");
|
|
4167
|
+
return ();
|
|
4168
|
+
}
|
|
4083
4169
|
$file = *FH; # (not \*FH, so *FH will be kept open until $file goes out of scope)
|
|
4084
4170
|
}
|
|
4085
4171
|
# on Windows, try to work around incorrect file times when daylight saving time is in effect
|
|
@@ -5710,7 +5796,11 @@ sub GetUnixTime($;$)
|
|
|
5710
5796
|
my ($timeStr, $isLocal) = @_;
|
|
5711
5797
|
return 0 if $timeStr eq '0000:00:00 00:00:00';
|
|
5712
5798
|
my @tm = ($timeStr =~ /^(\d+):(\d+):(\d+)\s+(\d+):(\d+):(\d+)(.*)/);
|
|
5713
|
-
return undef unless @tm == 7
|
|
5799
|
+
return undef unless @tm == 7;
|
|
5800
|
+
unless (eval { require Time::Local }) {
|
|
5801
|
+
warn "Time::Local is not installed\n";
|
|
5802
|
+
return undef;
|
|
5803
|
+
}
|
|
5714
5804
|
my ($tzStr, $tzSec) = (pop(@tm), 0);
|
|
5715
5805
|
# use specified timezone offset (if given) instead of local system time
|
|
5716
5806
|
# if we are converting a local time value
|
|
@@ -5908,7 +5998,7 @@ sub ProcessTrailers($$)
|
|
|
5908
5998
|
for (;;) { # loop through all trailers
|
|
5909
5999
|
my ($proc, $outBuff);
|
|
5910
6000
|
if ($dirName eq 'Insta360') {
|
|
5911
|
-
require
|
|
6001
|
+
require 'Image/ExifTool/QuickTimeStream.pl';
|
|
5912
6002
|
$proc = 'Image::ExifTool::QuickTime::ProcessInsta360';
|
|
5913
6003
|
} else {
|
|
5914
6004
|
require "Image/ExifTool/$dirName.pm";
|
|
@@ -6070,9 +6160,10 @@ sub ProcessJPEG($$)
|
|
|
6070
6160
|
my $out = $$options{TextOut};
|
|
6071
6161
|
my $fast = $$options{FastScan} || 0;
|
|
6072
6162
|
my $raf = $$dirInfo{RAF};
|
|
6163
|
+
my $req = $$self{REQ_TAG_LOOKUP};
|
|
6073
6164
|
my $htmlDump = $$self{HTML_DUMP};
|
|
6074
6165
|
my %dumpParms = ( Out => $out );
|
|
6075
|
-
my ($success, $wantTrailer, $trailInfo, $foundSOS);
|
|
6166
|
+
my ($success, $wantTrailer, $trailInfo, $foundSOS, %jumbfChunk);
|
|
6076
6167
|
my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $flirTotal);
|
|
6077
6168
|
my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP);
|
|
6078
6169
|
|
|
@@ -6083,7 +6174,7 @@ sub ProcessJPEG($$)
|
|
|
6083
6174
|
$$self{FILE_TYPE} = 'EXV';
|
|
6084
6175
|
}
|
|
6085
6176
|
my $appBytes = 0;
|
|
6086
|
-
my $calcImageLen = $$
|
|
6177
|
+
my $calcImageLen = $$req{jpegimagelength};
|
|
6087
6178
|
if ($$options{RequestAll} and $$options{RequestAll} > 2) {
|
|
6088
6179
|
$calcImageLen = 1;
|
|
6089
6180
|
}
|
|
@@ -6116,6 +6207,7 @@ sub ProcessJPEG($$)
|
|
|
6116
6207
|
my $marker = $nextMarker;
|
|
6117
6208
|
my $segDataPt = $nextSegDataPt;
|
|
6118
6209
|
my $segPos = $nextSegPos;
|
|
6210
|
+
my $skipped;
|
|
6119
6211
|
undef $nextMarker;
|
|
6120
6212
|
undef $nextSegDataPt;
|
|
6121
6213
|
#
|
|
@@ -6125,11 +6217,13 @@ sub ProcessJPEG($$)
|
|
|
6125
6217
|
# read up to next marker (JPEG markers begin with 0xff)
|
|
6126
6218
|
my $buff;
|
|
6127
6219
|
$raf->ReadLine($buff) or last;
|
|
6220
|
+
$skipped = length($buff) - 1;
|
|
6128
6221
|
# JPEG markers can be padded with unlimited 0xff's
|
|
6129
6222
|
for (;;) {
|
|
6130
6223
|
$raf->Read($ch, 1) or last Marker;
|
|
6131
6224
|
$nextMarker = ord($ch);
|
|
6132
6225
|
last unless $nextMarker == 0xff;
|
|
6226
|
+
++$skipped;
|
|
6133
6227
|
}
|
|
6134
6228
|
# read segment data if it exists
|
|
6135
6229
|
if (not defined $markerLenBytes{$nextMarker}) {
|
|
@@ -6156,6 +6250,14 @@ sub ProcessJPEG($$)
|
|
|
6156
6250
|
# set some useful variables for the current segment
|
|
6157
6251
|
my $markerName = JpegMarkerName($marker);
|
|
6158
6252
|
$$path[$pn] = $markerName;
|
|
6253
|
+
# issue warning if we skipped some garbage
|
|
6254
|
+
if ($skipped and not $foundSOS) {
|
|
6255
|
+
$self->Warn("Skipped unknown $skipped bytes after JPEG $markerName segment", 1);
|
|
6256
|
+
if ($htmlDump) {
|
|
6257
|
+
$self->HDump($nextSegPos-4-$skipped, $skipped, "[unknown $skipped bytes]", undef, 0x08);
|
|
6258
|
+
$dumpEnd = $nextSegPos - 4;
|
|
6259
|
+
}
|
|
6260
|
+
}
|
|
6159
6261
|
#
|
|
6160
6262
|
# parse the current segment
|
|
6161
6263
|
#
|
|
@@ -6217,7 +6319,7 @@ sub ProcessJPEG($$)
|
|
|
6217
6319
|
} else {
|
|
6218
6320
|
$self->Warn('Missing JPEG SOS');
|
|
6219
6321
|
}
|
|
6220
|
-
if ($$
|
|
6322
|
+
if ($$req{trailer}) {
|
|
6221
6323
|
# read entire trailer into memory
|
|
6222
6324
|
if ($raf->Seek(0,2)) {
|
|
6223
6325
|
my $len = $raf->Tell() - $pos;
|
|
@@ -6351,7 +6453,7 @@ sub ProcessJPEG($$)
|
|
|
6351
6453
|
next if $trailInfo or $wantTrailer or $verbose > 2 or $htmlDump;
|
|
6352
6454
|
}
|
|
6353
6455
|
# must scan to EOI if Validate or JpegCompressionFactor used
|
|
6354
|
-
next if $$options{Validate} or $calcImageLen or $$
|
|
6456
|
+
next if $$options{Validate} or $calcImageLen or $$req{trailer};
|
|
6355
6457
|
# nothing interesting to parse after start of scan (SOS)
|
|
6356
6458
|
$success = 1;
|
|
6357
6459
|
last; # all done parsing file
|
|
@@ -6371,7 +6473,7 @@ sub ProcessJPEG($$)
|
|
|
6371
6473
|
# must use the RequestTags option to generate these tags if they have not been
|
|
6372
6474
|
# specifically requested. The reason is that there is too much overhead involved
|
|
6373
6475
|
# in the calculation of this tag to make this worth the CPU time.)
|
|
6374
|
-
($$
|
|
6476
|
+
($$req{jpegdigest} or $$req{jpegqualityestimate}
|
|
6375
6477
|
or ($$options{RequestAll} and $$options{RequestAll} > 2)))
|
|
6376
6478
|
{
|
|
6377
6479
|
my $num = unpack('C',$$segDataPt) & 0x0f; # get table index
|
|
@@ -6489,7 +6591,7 @@ sub ProcessJPEG($$)
|
|
|
6489
6591
|
}
|
|
6490
6592
|
if ($start and $plen and IsInt($start) and IsInt($plen) and
|
|
6491
6593
|
$start + $plen > $$self{EXIF_POS} + length($$self{EXIF_DATA}) and
|
|
6492
|
-
($$
|
|
6594
|
+
($$req{previewimage} or
|
|
6493
6595
|
# (extracted normally, so check Binary option)
|
|
6494
6596
|
($$options{Binary} and not $$self{EXCL_TAG_LOOKUP}{previewimage})))
|
|
6495
6597
|
{
|
|
@@ -6695,6 +6797,12 @@ sub ProcessJPEG($$)
|
|
|
6695
6797
|
# extract the Stim information (it is in standard TIFF format)
|
|
6696
6798
|
my $tagTablePtr = GetTagTable('Image::ExifTool::Stim::Main');
|
|
6697
6799
|
$self->ProcessTIFF(\%dirInfo, $tagTablePtr);
|
|
6800
|
+
} elsif ($$segDataPt =~ /^_JPSJPS_/) {
|
|
6801
|
+
$dumpType = 'JPS';
|
|
6802
|
+
$self->OverrideFileType('JPS') if $$self{FILE_TYPE} eq 'JPEG';
|
|
6803
|
+
SetByteOrder('MM');
|
|
6804
|
+
my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::JPS');
|
|
6805
|
+
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
|
6698
6806
|
} elsif ($$self{Make} eq 'DJI') {
|
|
6699
6807
|
$dumpType = 'DJI ThermalData';
|
|
6700
6808
|
# add this data to the combined data if it exists
|
|
@@ -6884,7 +6992,7 @@ sub ProcessJPEG($$)
|
|
|
6884
6992
|
# (with number of elements N = ImageHeight / 16 - 1, ref PH/NealKrawetz)
|
|
6885
6993
|
$xtra = 'segment (N=' . unpack('x6N', $$segDataPt) . ')';
|
|
6886
6994
|
}
|
|
6887
|
-
} elsif ($marker == 0xeb) { # APP11 (JPEG-HDR)
|
|
6995
|
+
} elsif ($marker == 0xeb) { # APP11 (JPEG-HDR, JUMBF)
|
|
6888
6996
|
if ($$segDataPt =~ /^HDR_RI /) {
|
|
6889
6997
|
$dumpType = 'JPEG-HDR';
|
|
6890
6998
|
my $dataPt = $segDataPt;
|
|
@@ -6904,6 +7012,47 @@ sub ProcessJPEG($$)
|
|
|
6904
7012
|
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
|
6905
7013
|
undef $combinedSegData;
|
|
6906
7014
|
}
|
|
7015
|
+
} elsif ($$segDataPt =~ /^(JP..)/s and length($$segDataPt) >= 16) {
|
|
7016
|
+
# JUMBF extension marker
|
|
7017
|
+
my $hdr = $1;
|
|
7018
|
+
$dumpType = 'JUMBF';
|
|
7019
|
+
SetByteOrder('MM');
|
|
7020
|
+
my $seq = Get32u($segDataPt, 4) - 1; # (start from 0)
|
|
7021
|
+
my $len = Get32u($segDataPt, 8);
|
|
7022
|
+
my $type = substr($$segDataPt, 12, 4);
|
|
7023
|
+
my $hdrLen;
|
|
7024
|
+
if ($len == 1 and length($$segDataPt) >= 24) {
|
|
7025
|
+
$len = Get64u($$segDataPt, 16);
|
|
7026
|
+
$hdrLen = 16;
|
|
7027
|
+
} else {
|
|
7028
|
+
$hdrLen = 8;
|
|
7029
|
+
}
|
|
7030
|
+
$jumbfChunk{$type} or $jumbfChunk{$type} = [ ];
|
|
7031
|
+
if ($len < $hdrLen) {
|
|
7032
|
+
$self->Warn('Invalid JUMBF segment');
|
|
7033
|
+
} elsif ($seq < 0) {
|
|
7034
|
+
$self->Warn('Invalid JUMBF sequence number');
|
|
7035
|
+
} elsif (defined $jumbfChunk{$type}[$seq]) {
|
|
7036
|
+
$self->Warn('Duplicate JUMBF sequence number');
|
|
7037
|
+
} else {
|
|
7038
|
+
# add to list of JUMBF chunks
|
|
7039
|
+
$jumbfChunk{$type}[$seq] = substr($$segDataPt, 8 + $hdrLen);
|
|
7040
|
+
# check to see if we have a complete JUMBF box
|
|
7041
|
+
my $size = $hdrLen;
|
|
7042
|
+
foreach (@{$jumbfChunk{$type}}) {
|
|
7043
|
+
defined $_ or $size = 0, last;
|
|
7044
|
+
$size += length $_;
|
|
7045
|
+
}
|
|
7046
|
+
if ($size == $len) {
|
|
7047
|
+
my $buff = join '', substr($$segDataPt,8,$hdrLen), @{$jumbfChunk{$type}};
|
|
7048
|
+
$dirInfo{DataPt} = \$buff;
|
|
7049
|
+
$dirInfo{DataPos} = $segPos + 8; # (shows correct offsets for single-segment JUMBF)
|
|
7050
|
+
$dirInfo{DataLen} = $dirInfo{DirLen} = $size;
|
|
7051
|
+
my $tagTablePtr = GetTagTable('Image::ExifTool::Jpeg2000::Main');
|
|
7052
|
+
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
|
7053
|
+
delete $jumbfChunk{$type};
|
|
7054
|
+
}
|
|
7055
|
+
}
|
|
6907
7056
|
}
|
|
6908
7057
|
} elsif ($marker == 0xec) { # APP12 (Ducky, Picture Info)
|
|
6909
7058
|
if ($$segDataPt =~ /^Ducky/) {
|
|
@@ -6955,7 +7104,7 @@ sub ProcessJPEG($$)
|
|
|
6955
7104
|
} elsif ($marker == 0xee) { # APP14 (Adobe)
|
|
6956
7105
|
if ($$segDataPt =~ /^Adobe/) {
|
|
6957
7106
|
# extract as a block if requested, or if copying tags from file
|
|
6958
|
-
if ($$
|
|
7107
|
+
if ($$req{adobe} or
|
|
6959
7108
|
# (not extracted normally, so check TAGS_FROM_FILE)
|
|
6960
7109
|
($$self{TAGS_FROM_FILE} and not $$self{EXCL_TAG_LOOKUP}{adobe}))
|
|
6961
7110
|
{
|
|
@@ -7058,6 +7207,7 @@ sub ProcessJPEG($$)
|
|
|
7058
7207
|
Image::ExifTool::JPEGDigest::Calculate($self, \@dqt, $subSampling);
|
|
7059
7208
|
}
|
|
7060
7209
|
# issue necessary warnings
|
|
7210
|
+
$self->Warn('Invalid JUMBF size or missing JUMBF chunk') if %jumbfChunk;
|
|
7061
7211
|
$self->Warn('Incomplete ICC_Profile record', 1) if defined $iccChunkCount;
|
|
7062
7212
|
$self->Warn('Incomplete FLIR record', 1) if defined $flirCount;
|
|
7063
7213
|
$self->Warn('Error reading PreviewImage', 1) if $$self{PreviewError};
|
|
@@ -7726,7 +7876,8 @@ sub GetTagInfo($$$;$$$)
|
|
|
7726
7876
|
}
|
|
7727
7877
|
}
|
|
7728
7878
|
if ($$tagInfo{Unknown} and not $$self{OPTIONS}{Unknown} and
|
|
7729
|
-
not $$self{OPTIONS}{Verbose} and not $$self{
|
|
7879
|
+
not $$self{OPTIONS}{Verbose} and not $$self{OPTIONS}{Validate} and
|
|
7880
|
+
not $$self{HTML_DUMP})
|
|
7730
7881
|
{
|
|
7731
7882
|
# don't return Unknown tags unless that option is set
|
|
7732
7883
|
return undef;
|