exiftool_vendored 12.17.1 → 12.32.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 +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;
|