exiftool_vendored 12.16.0 → 12.25.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 +137 -1
- data/bin/MANIFEST +12 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +44 -43
- data/bin/config_files/acdsee.config +193 -6
- data/bin/config_files/cuepointlist.config +70 -0
- data/bin/config_files/example.config +1 -8
- data/bin/exiftool +139 -98
- data/bin/fmt_files/gpx.fmt +1 -1
- data/bin/fmt_files/gpx_wpt.fmt +1 -1
- data/bin/fmt_files/kml.fmt +1 -1
- data/bin/fmt_files/kml_track.fmt +1 -1
- data/bin/lib/Image/ExifTool.pm +158 -49
- data/bin/lib/Image/ExifTool.pod +94 -75
- data/bin/lib/Image/ExifTool/Apple.pm +3 -2
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +25 -14
- data/bin/lib/Image/ExifTool/Canon.pm +28 -3
- data/bin/lib/Image/ExifTool/CanonCustom.pm +19 -1
- data/bin/lib/Image/ExifTool/DJI.pm +6 -6
- data/bin/lib/Image/ExifTool/DjVu.pm +6 -5
- data/bin/lib/Image/ExifTool/Exif.pm +50 -22
- data/bin/lib/Image/ExifTool/FITS.pm +13 -2
- data/bin/lib/Image/ExifTool/FujiFilm.pm +19 -8
- data/bin/lib/Image/ExifTool/GPS.pm +24 -13
- data/bin/lib/Image/ExifTool/H264.pm +20 -5
- data/bin/lib/Image/ExifTool/ICC_Profile.pm +2 -2
- data/bin/lib/Image/ExifTool/JPEG.pm +6 -2
- data/bin/lib/Image/ExifTool/JSON.pm +24 -3
- data/bin/lib/Image/ExifTool/Jpeg2000.pm +361 -16
- data/bin/lib/Image/ExifTool/M2TS.pm +40 -4
- data/bin/lib/Image/ExifTool/MIE.pm +2 -2
- 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 +5 -5
- data/bin/lib/Image/ExifTool/NikonSettings.pm +25 -16
- data/bin/lib/Image/ExifTool/Olympus.pm +2 -2
- data/bin/lib/Image/ExifTool/PNG.pm +2 -2
- data/bin/lib/Image/ExifTool/Panasonic.pm +14 -1
- data/bin/lib/Image/ExifTool/PhaseOne.pm +4 -3
- data/bin/lib/Image/ExifTool/QuickTime.pm +148 -68
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +94 -34
- data/bin/lib/Image/ExifTool/README +5 -4
- data/bin/lib/Image/ExifTool/RIFF.pm +84 -12
- data/bin/lib/Image/ExifTool/Samsung.pm +2 -1
- data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -0
- data/bin/lib/Image/ExifTool/Sony.pm +157 -49
- data/bin/lib/Image/ExifTool/TagInfoXML.pm +1 -0
- data/bin/lib/Image/ExifTool/TagLookup.pm +4079 -3987
- data/bin/lib/Image/ExifTool/TagNames.pod +642 -273
- data/bin/lib/Image/ExifTool/WriteExif.pl +1 -1
- data/bin/lib/Image/ExifTool/WritePostScript.pl +1 -0
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +44 -17
- data/bin/lib/Image/ExifTool/WriteXMP.pl +15 -8
- data/bin/lib/Image/ExifTool/Writer.pl +50 -14
- data/bin/lib/Image/ExifTool/XMP.pm +50 -11
- data/bin/perl-Image-ExifTool.spec +42 -42
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +52 -12
data/bin/fmt_files/gpx.fmt
CHANGED
data/bin/fmt_files/gpx_wpt.fmt
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# Description: Example ExifTool print format file to generate GPX waypoints
|
|
5
5
|
# with pictures
|
|
6
6
|
#
|
|
7
|
-
# Usage: exiftool -p gpx_wpt.fmt -
|
|
7
|
+
# Usage: exiftool -p gpx_wpt.fmt -ee3 FILE [...] > out.gpx
|
|
8
8
|
#
|
|
9
9
|
# Requires: ExifTool version 10.49 or later
|
|
10
10
|
#
|
data/bin/fmt_files/kml.fmt
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
# 2020/01/11 - F. Kotov Limited image preview size to 500px
|
|
16
16
|
#
|
|
17
17
|
# Notes: 1) Input files must contain GPSLatitude and GPSLongitude.
|
|
18
|
-
# 2) Add the -
|
|
18
|
+
# 2) Add the -ee3 option to extract the full track from video files.
|
|
19
19
|
# 3) For Google Earth to be able to find the images, the input
|
|
20
20
|
# images must be specified using relative paths, and "out.kml"
|
|
21
21
|
# must stay in the same directory as where the command was run.
|
data/bin/fmt_files/kml_track.fmt
CHANGED
data/bin/lib/Image/ExifTool.pm
CHANGED
|
@@ -28,7 +28,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
|
|
|
28
28
|
%mimeType $swapBytes $swapWords $currentByteOrder %unpackStd
|
|
29
29
|
%jpegMarker %specialTags %fileTypeLookup $testLen $exePath);
|
|
30
30
|
|
|
31
|
-
$VERSION = '12.
|
|
31
|
+
$VERSION = '12.25';
|
|
32
32
|
$RELEASE = '';
|
|
33
33
|
@ISA = qw(Exporter);
|
|
34
34
|
%EXPORT_TAGS = (
|
|
@@ -42,7 +42,7 @@ $RELEASE = '';
|
|
|
42
42
|
DataAccess => [qw(
|
|
43
43
|
ReadValue GetByteOrder SetByteOrder ToggleByteOrder Get8u Get8s Get16u
|
|
44
44
|
Get16s Get32u Get32s Get64u GetFloat GetDouble GetFixed32s Write
|
|
45
|
-
WriteValue Tell Set8u Set8s Set16u Set32u Set64u
|
|
45
|
+
WriteValue Tell Set8u Set8s Set16u Set32u Set64u Set64s
|
|
46
46
|
)],
|
|
47
47
|
Utils => [qw(GetTagTable TagTableKeys GetTagInfoList AddTagToTable HexDump)],
|
|
48
48
|
Vars => [qw(%allTables @tableOrder @fileTypes)],
|
|
@@ -70,7 +70,7 @@ sub SetFileName($$;$$$);
|
|
|
70
70
|
sub SetSystemTags($$);
|
|
71
71
|
sub GetAllTags(;$);
|
|
72
72
|
sub GetWritableTags(;$);
|
|
73
|
-
sub GetAllGroups(
|
|
73
|
+
sub GetAllGroups($;$);
|
|
74
74
|
sub GetNewGroups($);
|
|
75
75
|
sub GetDeleteGroups();
|
|
76
76
|
sub AddUserDefinedTags($%);
|
|
@@ -89,6 +89,7 @@ sub Get64u($$);
|
|
|
89
89
|
sub GetFixed64s($$);
|
|
90
90
|
sub GetExtended($$);
|
|
91
91
|
sub Set64u(@);
|
|
92
|
+
sub Set64s(@);
|
|
92
93
|
sub DecodeBits($$;$);
|
|
93
94
|
sub EncodeBits($$;$$);
|
|
94
95
|
sub Filter($$$);
|
|
@@ -137,18 +138,18 @@ sub ReadValue($$$;$$$);
|
|
|
137
138
|
@loadAllTables = qw(
|
|
138
139
|
PhotoMechanic Exif GeoTiff CanonRaw KyoceraRaw Lytro MinoltaRaw PanasonicRaw
|
|
139
140
|
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 PSP
|
|
141
|
-
PDF PostScript Photoshop::Header Photoshop::Layers
|
|
142
|
-
FujiFilm::RAF FujiFilm::IFD Samsung::Trailer Sony::SRF2
|
|
143
|
-
Sony::PMP ITC ID3 ID3::Lyrics3 FLAC Ogg Vorbis APE
|
|
144
|
-
APE::OldHeader Audible MPC MPEG::Audio MPEG::Video MPEG::Xing
|
|
145
|
-
QuickTime::ImageFile QuickTime::Stream QuickTime::Tags360Fly
|
|
146
|
-
MXF DV Flash Flash::FLV Real::Media Real::Audio Real::Metafile
|
|
147
|
-
ASF WTV DICOM FITS MIE JSON HTML XMP::SVG Palm Palm::MOBI
|
|
148
|
-
EXE EXE::PEVersion EXE::PEString EXE::MachO EXE::PEF
|
|
149
|
-
EXE::CHM LNK Font VCard Text VCard::VCalendar RSRC Rawzor
|
|
150
|
-
ZIP::RAR RTF OOXML iWork ISO FLIR::AFF FLIR::FPF MacOS
|
|
151
|
-
FlashPix::DocTable
|
|
141
|
+
PICT PNG MNG FLIF DjVu DPX OpenEXR ZISRAW MRC MRC::FEI12 MIFF PCX PGF PSP
|
|
142
|
+
PhotoCD Radiance PDF PostScript Photoshop::Header Photoshop::Layers
|
|
143
|
+
Photoshop::ImageData FujiFilm::RAF FujiFilm::IFD Samsung::Trailer Sony::SRF2
|
|
144
|
+
Sony::SR2SubIFD Sony::PMP ITC ID3 ID3::Lyrics3 FLAC Ogg Vorbis APE
|
|
145
|
+
APE::NewHeader APE::OldHeader Audible MPC MPEG::Audio MPEG::Video MPEG::Xing
|
|
146
|
+
M2TS QuickTime QuickTime::ImageFile QuickTime::Stream QuickTime::Tags360Fly
|
|
147
|
+
Matroska MOI MXF DV Flash Flash::FLV Real::Media Real::Audio Real::Metafile
|
|
148
|
+
Red RIFF AIFF ASF WTV DICOM FITS MIE JSON HTML XMP::SVG Palm Palm::MOBI
|
|
149
|
+
Palm::EXTH Torrent EXE EXE::PEVersion EXE::PEString EXE::MachO EXE::PEF
|
|
150
|
+
EXE::ELF EXE::AR EXE::CHM LNK Font VCard Text VCard::VCalendar RSRC Rawzor
|
|
151
|
+
ZIP ZIP::GZIP ZIP::RAR RTF OOXML iWork ISO FLIR::AFF FLIR::FPF MacOS
|
|
152
|
+
MacOS::MDItem FlashPix::DocTable
|
|
152
153
|
);
|
|
153
154
|
|
|
154
155
|
# alphabetical list of current Lang modules
|
|
@@ -188,12 +189,12 @@ $defaultLang = 'en'; # default language
|
|
|
188
189
|
FLAC APE MPC MKV MXF DV PMP IND PGF ICC ITC FLIR FLIF FPF LFP
|
|
189
190
|
HTML VRD RTF FITS XCF DSS QTIF FPX PICT ZIP GZIP PLIST RAR BZ2
|
|
190
191
|
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);
|
|
192
|
+
MacOS PHP PCX DCX DWF DWG DXF WTV Torrent VCard LRI R3D AA PDB
|
|
193
|
+
MRC JXL MOI ISO ALIAS JSON MP3 DICOM PCD TXT);
|
|
193
194
|
|
|
194
195
|
# file types that we can write (edit)
|
|
195
196
|
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);
|
|
197
|
+
X3F PS PDF ICC VRD DR4 JP2 JXL EXIF AI AIT IND MOV EXV FLIF);
|
|
197
198
|
my %writeTypes; # lookup for writable file types (hash filled if required)
|
|
198
199
|
|
|
199
200
|
# file extensions that we can't write for various base types
|
|
@@ -266,6 +267,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
|
266
267
|
DIB => ['BMP', 'Device Independent Bitmap'],
|
|
267
268
|
DIC => 'DICM',
|
|
268
269
|
DICM => ['DICOM','Digital Imaging and Communications in Medicine'],
|
|
270
|
+
DIR => ['DIR', 'Directory'],
|
|
269
271
|
DIVX => ['ASF', 'DivX media format'],
|
|
270
272
|
DJV => 'DJVU',
|
|
271
273
|
DJVU => ['AIFF', 'DjVu image'],
|
|
@@ -290,6 +292,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
|
290
292
|
DWF => ['DWF', 'Autodesk drawing (Design Web Format)'],
|
|
291
293
|
DWG => ['DWG', 'AutoCAD Drawing'],
|
|
292
294
|
DYLIB=> ['EXE', 'Mach-O Dynamic Link Library'],
|
|
295
|
+
DXF => ['DXF', 'AutoCAD Drawing Exchange Format'],
|
|
293
296
|
EIP => ['ZIP', 'Capture One Enhanced Image Package'],
|
|
294
297
|
EPS => ['EPS', 'Encapsulated PostScript Format'],
|
|
295
298
|
EPS2 => 'EPS',
|
|
@@ -353,6 +356,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
|
353
356
|
JPM => ['JP2', 'JPEG 2000 compound image'],
|
|
354
357
|
JPX => ['JP2', 'JPEG 2000 with extensions'],
|
|
355
358
|
JSON => ['JSON', 'JavaScript Object Notation'],
|
|
359
|
+
JXL => ['JXL', 'JPEG XL'],
|
|
356
360
|
JXR => ['TIFF', 'JPEG XR'],
|
|
357
361
|
K25 => ['TIFF', 'Kodak DC25 RAW'],
|
|
358
362
|
KDC => ['TIFF', 'Kodak Digital Camera RAW'],
|
|
@@ -392,6 +396,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
|
392
396
|
MPG => 'MPEG',
|
|
393
397
|
MPO => ['JPEG', 'Extended Multi-Picture format'],
|
|
394
398
|
MQV => ['MOV', 'Sony Mobile Quicktime Video'],
|
|
399
|
+
MRC => ['MRC', 'Medical Research Council image'],
|
|
395
400
|
MRW => ['MRW', 'Minolta RAW format'],
|
|
396
401
|
MTS => 'M2TS',
|
|
397
402
|
MXF => ['MXF', 'Material Exchange Format'],
|
|
@@ -416,6 +421,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
|
416
421
|
ONP => ['JSON', 'ON1 Presets'],
|
|
417
422
|
OPUS => ['OGG', 'Ogg Opus audio file'],
|
|
418
423
|
ORF => ['ORF', 'Olympus RAW format'],
|
|
424
|
+
ORI => 'ORF',
|
|
419
425
|
OTF => ['Font', 'Open Type Font'],
|
|
420
426
|
PAC => ['RIFF', 'Lossless Predictive Audio Compression'],
|
|
421
427
|
PAGES => ['ZIP', 'Apple Pages document'],
|
|
@@ -612,6 +618,7 @@ my %fileDescription = (
|
|
|
612
618
|
'DVR-MS' => 'video/x-ms-dvr',
|
|
613
619
|
DWF => 'model/vnd.dwf',
|
|
614
620
|
DWG => 'image/vnd.dwg',
|
|
621
|
+
DXF => 'application/dxf',
|
|
615
622
|
EIP => 'application/x-captureone', #(NC)
|
|
616
623
|
EPS => 'application/postscript',
|
|
617
624
|
ERF => 'image/x-epson-erf',
|
|
@@ -649,6 +656,7 @@ my %fileDescription = (
|
|
|
649
656
|
JPM => 'image/jpm',
|
|
650
657
|
JPX => 'image/jpx',
|
|
651
658
|
JSON => 'application/json',
|
|
659
|
+
JXL => 'image/jxl', #PH (NC)
|
|
652
660
|
JXR => 'image/jxr',
|
|
653
661
|
K25 => 'image/x-kodak-k25',
|
|
654
662
|
KDC => 'image/x-kodak-kdc',
|
|
@@ -674,6 +682,7 @@ my %fileDescription = (
|
|
|
674
682
|
MP4 => 'video/mp4',
|
|
675
683
|
MPC => 'audio/x-musepack',
|
|
676
684
|
MPEG => 'video/mpeg',
|
|
685
|
+
MRC => 'image/x-mrc',
|
|
677
686
|
MRW => 'image/x-minolta-mrw',
|
|
678
687
|
MXF => 'application/mxf',
|
|
679
688
|
NEF => 'image/x-nikon-nef',
|
|
@@ -798,6 +807,7 @@ my %moduleName = (
|
|
|
798
807
|
DSS => 'Olympus',
|
|
799
808
|
DWF => 0,
|
|
800
809
|
DWG => 0,
|
|
810
|
+
DXF => 0,
|
|
801
811
|
EPS => 'PostScript',
|
|
802
812
|
EXIF => '',
|
|
803
813
|
EXR => 'OpenEXR',
|
|
@@ -811,6 +821,7 @@ my %moduleName = (
|
|
|
811
821
|
HDR => 'Radiance',
|
|
812
822
|
JP2 => 'Jpeg2000',
|
|
813
823
|
JPEG => '',
|
|
824
|
+
JXL => 'Jpeg2000',
|
|
814
825
|
LFP => 'Lytro',
|
|
815
826
|
LRI => 0,
|
|
816
827
|
MOV => 'QuickTime',
|
|
@@ -872,6 +883,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
|
872
883
|
DV => '\x1f\x07\0[\x3f\xbf]', # (not tested if extension recognized)
|
|
873
884
|
DWF => '\(DWF V\d',
|
|
874
885
|
DWG => 'AC10\d{2}\0',
|
|
886
|
+
DXF => '\s*0\s+\0?\s*SECTION\s+2\s+HEADER',
|
|
875
887
|
EPS => '(%!PS|%!Ad|\xc5\xd0\xd3\xc6)',
|
|
876
888
|
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
889
|
EXIF => '(II\x2a\0|MM\0\x2a)',
|
|
@@ -897,6 +909,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
|
897
909
|
JP2 => '(\0\0\0\x0cjP( |\x1a\x1a)\x0d\x0a\x87\x0a|\xff\x4f\xff\x51\0)',
|
|
898
910
|
JPEG => '\xff\xd8\xff',
|
|
899
911
|
JSON => '(\xef\xbb\xbf)?\s*(\[\s*)?\{\s*"[^"]*"\s*:',
|
|
912
|
+
JXL => '\xff\x0a|\0\0\0\x0cJXL \x0d\x0a......ftypjxl ',
|
|
900
913
|
LFP => '\x89LFP\x0d\x0a\x1a\x0a',
|
|
901
914
|
LNK => '.{4}\x01\x14\x02\0{5}\xc0\0{6}\x46',
|
|
902
915
|
LRI => 'LELR \0',
|
|
@@ -909,6 +922,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
|
|
|
909
922
|
MPC => '(MP\+|ID3)',
|
|
910
923
|
MOI => 'V6',
|
|
911
924
|
MPEG => '\0\0\x01[\xb0-\xbf]',
|
|
925
|
+
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
926
|
MRW => '\0MR[MI]',
|
|
913
927
|
MXF => '\x06\x0e\x2b\x34\x02\x05\x01\x01\x0d\x01\x02', # (not tested if extension recognized)
|
|
914
928
|
OGG => '(OggS|ID3)',
|
|
@@ -1129,6 +1143,13 @@ my %systemTagsNotes = (
|
|
|
1129
1143
|
RawConv => '$self->ConvertFileName($val)',
|
|
1130
1144
|
ValueConvInv => '$self->InverseFileName($val)',
|
|
1131
1145
|
},
|
|
1146
|
+
BaseName => {
|
|
1147
|
+
Groups => { 1 => 'System', 2 => 'Other' },
|
|
1148
|
+
Notes => q{
|
|
1149
|
+
file name without extension. Not generated unless specifically requested or
|
|
1150
|
+
the L<RequestAll|../ExifTool.html#RequestAll> API option is set
|
|
1151
|
+
},
|
|
1152
|
+
},
|
|
1132
1153
|
FilePath => {
|
|
1133
1154
|
Groups => { 1 => 'System', 2 => 'Other' },
|
|
1134
1155
|
Notes => q{
|
|
@@ -1270,10 +1291,19 @@ my %systemTagsNotes = (
|
|
|
1270
1291
|
WritePseudo => 1,
|
|
1271
1292
|
DelCheck => q{"Can't delete"},
|
|
1272
1293
|
Protected => 1, # all writable pseudo-tags must be protected!
|
|
1273
|
-
ValueConv => 'sprintf("%.3o", $val
|
|
1274
|
-
ValueConvInv => 'oct($val)',
|
|
1294
|
+
ValueConv => 'sprintf("%.3o", $val)',
|
|
1295
|
+
ValueConvInv => 'oct($val & 07777)',
|
|
1275
1296
|
PrintConv => sub {
|
|
1276
|
-
my ($mask, $
|
|
1297
|
+
my ($mask, $val) = (0400, oct(shift));
|
|
1298
|
+
my %types = (
|
|
1299
|
+
0010000 => 'p',
|
|
1300
|
+
0020000 => 'c',
|
|
1301
|
+
0040000 => 'd',
|
|
1302
|
+
0060000 => 'b',
|
|
1303
|
+
0120000 => 'l',
|
|
1304
|
+
0140000 => 's',
|
|
1305
|
+
);
|
|
1306
|
+
my $str = $types{$val & 0170000} || '-';
|
|
1277
1307
|
while ($mask) {
|
|
1278
1308
|
foreach (qw(r w x)) {
|
|
1279
1309
|
$str .= $val & $mask ? $_ : '-';
|
|
@@ -1284,6 +1314,7 @@ my %systemTagsNotes = (
|
|
|
1284
1314
|
},
|
|
1285
1315
|
PrintConvInv => sub {
|
|
1286
1316
|
my ($bit, $val, $str) = (8, 0, shift);
|
|
1317
|
+
$str = substr($str, 1) if length($str) == 10;
|
|
1287
1318
|
return undef if length($str) != 9;
|
|
1288
1319
|
while ($bit >= 0) {
|
|
1289
1320
|
foreach (qw(r w x)) {
|
|
@@ -1737,7 +1768,10 @@ my %systemTagsNotes = (
|
|
|
1737
1768
|
EmbeddedVideo => { Groups => { 0 => 'Trailer', 2 => 'Video' } },
|
|
1738
1769
|
Trailer => {
|
|
1739
1770
|
Groups => { 0 => 'Trailer' },
|
|
1740
|
-
Notes =>
|
|
1771
|
+
Notes => q{
|
|
1772
|
+
the full JPEG trailer data block. Extracted only if specifically requested
|
|
1773
|
+
or the RequestAll API option is set to 3 or higher
|
|
1774
|
+
},
|
|
1741
1775
|
Writable => 1,
|
|
1742
1776
|
Protected => 1,
|
|
1743
1777
|
},
|
|
@@ -2271,7 +2305,7 @@ sub ClearOptions($)
|
|
|
2271
2305
|
NoPDFList => undef, # flag to avoid splitting PDF List-type tag values
|
|
2272
2306
|
Password => undef, # password for password-protected PDF documents
|
|
2273
2307
|
PrintConv => 1, # flag to enable print conversion
|
|
2274
|
-
QuickTimeHandler =>
|
|
2308
|
+
QuickTimeHandler => 1, # flag to add mdir Handler to newly created Meta box
|
|
2275
2309
|
QuickTimeUTC=> undef, # assume that QuickTime date/time tags are stored as UTC
|
|
2276
2310
|
RequestAll => undef, # extract all tags that must be specifically requested
|
|
2277
2311
|
RequestTags => undef, # extra tags to request (on top of those in the tag list)
|
|
@@ -2321,7 +2355,7 @@ sub ExtractInfo($;@)
|
|
|
2321
2355
|
my $fast = $$options{FastScan} || 0;
|
|
2322
2356
|
my $req = $$self{REQ_TAG_LOOKUP};
|
|
2323
2357
|
my $reqAll = $$options{RequestAll} || 0;
|
|
2324
|
-
my (%saveOptions, $reEntry, $rsize, $type, @startTime, $saveOrder);
|
|
2358
|
+
my (%saveOptions, $reEntry, $rsize, $type, @startTime, $saveOrder, $isDir);
|
|
2325
2359
|
|
|
2326
2360
|
# check for internal ReEntry option to allow recursive calls to ExtractInfo
|
|
2327
2361
|
if (ref $_[1] eq 'HASH' and $_[1]{ReEntry} and
|
|
@@ -2394,6 +2428,11 @@ sub ExtractInfo($;@)
|
|
|
2394
2428
|
$realname =~ /\|$/ and $realname =~ s/^.*?"(.*?)".*/$1/s;
|
|
2395
2429
|
my ($dir, $name) = SplitFileName($realname);
|
|
2396
2430
|
$self->FoundTag('FileName', $name);
|
|
2431
|
+
if ($$req{basename} or
|
|
2432
|
+
($reqAll and not $$self{EXCL_TAG_LOOKUP}{basename}))
|
|
2433
|
+
{
|
|
2434
|
+
$self->FoundTag('BaseName', $name =~ /(.*)\./ ? $1 : $name);
|
|
2435
|
+
}
|
|
2397
2436
|
$self->FoundTag('Directory', $dir) if defined $dir and length $dir;
|
|
2398
2437
|
if ($$req{filepath} or
|
|
2399
2438
|
($reqAll and not $$self{EXCL_TAG_LOOKUP}{filepath}))
|
|
@@ -2417,6 +2456,8 @@ sub ExtractInfo($;@)
|
|
|
2417
2456
|
# in Windows cmd shell pipe even though it really failed
|
|
2418
2457
|
$$raf{TESTED} = -1 if $filename eq '-' or $filename =~ /\|$/;
|
|
2419
2458
|
$$self{RAF} = $raf;
|
|
2459
|
+
} elsif ($self->IsDirectory($filename)) {
|
|
2460
|
+
$isDir = 1;
|
|
2420
2461
|
} else {
|
|
2421
2462
|
$self->Error('Error opening file');
|
|
2422
2463
|
}
|
|
@@ -2425,28 +2466,34 @@ sub ExtractInfo($;@)
|
|
|
2425
2466
|
}
|
|
2426
2467
|
}
|
|
2427
2468
|
|
|
2428
|
-
while ($raf) {
|
|
2429
|
-
my (@stat, $
|
|
2469
|
+
while ($raf or $isDir) {
|
|
2470
|
+
my (@stat, $plainFile);
|
|
2430
2471
|
if ($reEntry) {
|
|
2431
2472
|
# we already set these tags
|
|
2473
|
+
} elsif (not $raf) {
|
|
2474
|
+
@stat = stat $filename;
|
|
2432
2475
|
} elsif (not $$raf{FILE_PT}) {
|
|
2433
2476
|
# get file size from image in memory
|
|
2434
2477
|
$self->FoundTag('FileSize', length ${$$raf{BUFF_PT}});
|
|
2435
2478
|
} elsif (-f $$raf{FILE_PT}) {
|
|
2436
2479
|
# get file tags if this is a plain file
|
|
2437
|
-
$fileSize = -s _;
|
|
2438
2480
|
@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];
|
|
2481
|
+
$plainFile = 1;
|
|
2482
|
+
# hack to patch Windows daylight savings time bug
|
|
2483
|
+
@stat[8,9,10] = $self->GetFileTime($$raf{FILE_PT}) if $^O eq 'MSWin32';
|
|
2447
2484
|
} else {
|
|
2485
|
+
# (note that Windows directories will still show the
|
|
2486
|
+
# daylight savings time bug -- should fix this sometime)
|
|
2448
2487
|
@stat = stat $$raf{FILE_PT};
|
|
2449
2488
|
}
|
|
2489
|
+
my $fileSize = $stat[7];
|
|
2490
|
+
$self->FoundTag('FileSize', $stat[7]) if defined $stat[7];
|
|
2491
|
+
$self->FoundTag('ResourceForkSize', $rsize) if $rsize;
|
|
2492
|
+
$self->FoundTag('FileModifyDate', $stat[9]) if defined $stat[9];
|
|
2493
|
+
$self->FoundTag('FileAccessDate', $stat[8]) if defined $stat[8];
|
|
2494
|
+
my $cTag = $^O eq 'MSWin32' ? 'FileCreateDate' : 'FileInodeChangeDate';
|
|
2495
|
+
$self->FoundTag($cTag, $stat[10]) if defined $stat[10];
|
|
2496
|
+
$self->FoundTag('FilePermissions', $stat[2]) if defined $stat[2];
|
|
2450
2497
|
# extract more system info if SystemTags option is set
|
|
2451
2498
|
if (@stat) {
|
|
2452
2499
|
my $sys = $$options{SystemTags} || ($reqAll and not defined $$options{SystemTags});
|
|
@@ -2486,11 +2533,18 @@ sub ExtractInfo($;@)
|
|
|
2486
2533
|
if ($crDate or $mdItem or $xattr) {
|
|
2487
2534
|
require Image::ExifTool::MacOS;
|
|
2488
2535
|
Image::ExifTool::MacOS::GetFileCreateDate($self, $filename) if $crDate;
|
|
2489
|
-
Image::ExifTool::MacOS::ExtractMDItemTags($self, $filename) if $mdItem;
|
|
2536
|
+
Image::ExifTool::MacOS::ExtractMDItemTags($self, $filename) if $mdItem and $plainFile;
|
|
2490
2537
|
Image::ExifTool::MacOS::ExtractXAttrTags($self, $filename) if $xattr;
|
|
2491
2538
|
}
|
|
2492
2539
|
}
|
|
2493
|
-
|
|
2540
|
+
# do whatever else we can with directories, then return
|
|
2541
|
+
if ($isDir or (defined $stat[2] and ($stat[2] & 0170000) == 0040000)) {
|
|
2542
|
+
$self->FoundTag('FileType', 'DIR');
|
|
2543
|
+
$self->FoundTag('FileTypeExtension', '');
|
|
2544
|
+
$self->BuildCompositeTags() if $$options{Composite};
|
|
2545
|
+
$raf->Close() if $raf;
|
|
2546
|
+
return 1;
|
|
2547
|
+
}
|
|
2494
2548
|
# get list of file types to check
|
|
2495
2549
|
my ($tiffType, %noMagic, $recognizedExt);
|
|
2496
2550
|
my $ext = $$self{FILE_EXT} = GetFileExtension($realname);
|
|
@@ -4079,7 +4133,14 @@ sub GetFileTime($$)
|
|
|
4079
4133
|
# open file by name if necessary
|
|
4080
4134
|
unless (ref $file) {
|
|
4081
4135
|
local *FH;
|
|
4082
|
-
$self->Open(\*FH, $file)
|
|
4136
|
+
unless ($self->Open(\*FH, $file)) {
|
|
4137
|
+
if ($self->IsDirectory($file)) {
|
|
4138
|
+
my @rtn = (stat $file)[8, 9, 10];
|
|
4139
|
+
return @rtn if defined $rtn[0];
|
|
4140
|
+
}
|
|
4141
|
+
$self->Warn("GetFileTime error for '${file}'");
|
|
4142
|
+
return ();
|
|
4143
|
+
}
|
|
4083
4144
|
$file = *FH; # (not \*FH, so *FH will be kept open until $file goes out of scope)
|
|
4084
4145
|
}
|
|
4085
4146
|
# on Windows, try to work around incorrect file times when daylight saving time is in effect
|
|
@@ -5710,7 +5771,11 @@ sub GetUnixTime($;$)
|
|
|
5710
5771
|
my ($timeStr, $isLocal) = @_;
|
|
5711
5772
|
return 0 if $timeStr eq '0000:00:00 00:00:00';
|
|
5712
5773
|
my @tm = ($timeStr =~ /^(\d+):(\d+):(\d+)\s+(\d+):(\d+):(\d+)(.*)/);
|
|
5713
|
-
return undef unless @tm == 7
|
|
5774
|
+
return undef unless @tm == 7;
|
|
5775
|
+
unless (eval { require Time::Local }) {
|
|
5776
|
+
warn "Time::Local is not installed\n";
|
|
5777
|
+
return undef;
|
|
5778
|
+
}
|
|
5714
5779
|
my ($tzStr, $tzSec) = (pop(@tm), 0);
|
|
5715
5780
|
# use specified timezone offset (if given) instead of local system time
|
|
5716
5781
|
# if we are converting a local time value
|
|
@@ -5908,7 +5973,7 @@ sub ProcessTrailers($$)
|
|
|
5908
5973
|
for (;;) { # loop through all trailers
|
|
5909
5974
|
my ($proc, $outBuff);
|
|
5910
5975
|
if ($dirName eq 'Insta360') {
|
|
5911
|
-
require
|
|
5976
|
+
require 'Image/ExifTool/QuickTimeStream.pl';
|
|
5912
5977
|
$proc = 'Image::ExifTool::QuickTime::ProcessInsta360';
|
|
5913
5978
|
} else {
|
|
5914
5979
|
require "Image/ExifTool/$dirName.pm";
|
|
@@ -6070,9 +6135,10 @@ sub ProcessJPEG($$)
|
|
|
6070
6135
|
my $out = $$options{TextOut};
|
|
6071
6136
|
my $fast = $$options{FastScan} || 0;
|
|
6072
6137
|
my $raf = $$dirInfo{RAF};
|
|
6138
|
+
my $req = $$self{REQ_TAG_LOOKUP};
|
|
6073
6139
|
my $htmlDump = $$self{HTML_DUMP};
|
|
6074
6140
|
my %dumpParms = ( Out => $out );
|
|
6075
|
-
my ($success, $wantTrailer, $trailInfo, $foundSOS);
|
|
6141
|
+
my ($success, $wantTrailer, $trailInfo, $foundSOS, %jumbfChunk);
|
|
6076
6142
|
my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $flirTotal);
|
|
6077
6143
|
my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP);
|
|
6078
6144
|
|
|
@@ -6083,7 +6149,7 @@ sub ProcessJPEG($$)
|
|
|
6083
6149
|
$$self{FILE_TYPE} = 'EXV';
|
|
6084
6150
|
}
|
|
6085
6151
|
my $appBytes = 0;
|
|
6086
|
-
my $calcImageLen = $$
|
|
6152
|
+
my $calcImageLen = $$req{jpegimagelength};
|
|
6087
6153
|
if ($$options{RequestAll} and $$options{RequestAll} > 2) {
|
|
6088
6154
|
$calcImageLen = 1;
|
|
6089
6155
|
}
|
|
@@ -6217,7 +6283,7 @@ sub ProcessJPEG($$)
|
|
|
6217
6283
|
} else {
|
|
6218
6284
|
$self->Warn('Missing JPEG SOS');
|
|
6219
6285
|
}
|
|
6220
|
-
if ($$
|
|
6286
|
+
if ($$req{trailer}) {
|
|
6221
6287
|
# read entire trailer into memory
|
|
6222
6288
|
if ($raf->Seek(0,2)) {
|
|
6223
6289
|
my $len = $raf->Tell() - $pos;
|
|
@@ -6351,7 +6417,7 @@ sub ProcessJPEG($$)
|
|
|
6351
6417
|
next if $trailInfo or $wantTrailer or $verbose > 2 or $htmlDump;
|
|
6352
6418
|
}
|
|
6353
6419
|
# must scan to EOI if Validate or JpegCompressionFactor used
|
|
6354
|
-
next if $$options{Validate} or $calcImageLen or $$
|
|
6420
|
+
next if $$options{Validate} or $calcImageLen or $$req{trailer};
|
|
6355
6421
|
# nothing interesting to parse after start of scan (SOS)
|
|
6356
6422
|
$success = 1;
|
|
6357
6423
|
last; # all done parsing file
|
|
@@ -6371,7 +6437,7 @@ sub ProcessJPEG($$)
|
|
|
6371
6437
|
# must use the RequestTags option to generate these tags if they have not been
|
|
6372
6438
|
# specifically requested. The reason is that there is too much overhead involved
|
|
6373
6439
|
# in the calculation of this tag to make this worth the CPU time.)
|
|
6374
|
-
($$
|
|
6440
|
+
($$req{jpegdigest} or $$req{jpegqualityestimate}
|
|
6375
6441
|
or ($$options{RequestAll} and $$options{RequestAll} > 2)))
|
|
6376
6442
|
{
|
|
6377
6443
|
my $num = unpack('C',$$segDataPt) & 0x0f; # get table index
|
|
@@ -6489,7 +6555,7 @@ sub ProcessJPEG($$)
|
|
|
6489
6555
|
}
|
|
6490
6556
|
if ($start and $plen and IsInt($start) and IsInt($plen) and
|
|
6491
6557
|
$start + $plen > $$self{EXIF_POS} + length($$self{EXIF_DATA}) and
|
|
6492
|
-
($$
|
|
6558
|
+
($$req{previewimage} or
|
|
6493
6559
|
# (extracted normally, so check Binary option)
|
|
6494
6560
|
($$options{Binary} and not $$self{EXCL_TAG_LOOKUP}{previewimage})))
|
|
6495
6561
|
{
|
|
@@ -6884,7 +6950,7 @@ sub ProcessJPEG($$)
|
|
|
6884
6950
|
# (with number of elements N = ImageHeight / 16 - 1, ref PH/NealKrawetz)
|
|
6885
6951
|
$xtra = 'segment (N=' . unpack('x6N', $$segDataPt) . ')';
|
|
6886
6952
|
}
|
|
6887
|
-
} elsif ($marker == 0xeb) { # APP11 (JPEG-HDR)
|
|
6953
|
+
} elsif ($marker == 0xeb) { # APP11 (JPEG-HDR, JUMBF)
|
|
6888
6954
|
if ($$segDataPt =~ /^HDR_RI /) {
|
|
6889
6955
|
$dumpType = 'JPEG-HDR';
|
|
6890
6956
|
my $dataPt = $segDataPt;
|
|
@@ -6904,6 +6970,47 @@ sub ProcessJPEG($$)
|
|
|
6904
6970
|
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
|
6905
6971
|
undef $combinedSegData;
|
|
6906
6972
|
}
|
|
6973
|
+
} elsif ($$segDataPt =~ /^(JP..)/s and length($$segDataPt) >= 16) {
|
|
6974
|
+
# JUMBF extension marker
|
|
6975
|
+
my $hdr = $1;
|
|
6976
|
+
$dumpType = 'JUMBF';
|
|
6977
|
+
SetByteOrder('MM');
|
|
6978
|
+
my $seq = Get32u($segDataPt, 4) - 1; # (start from 0)
|
|
6979
|
+
my $len = Get32u($segDataPt, 8);
|
|
6980
|
+
my $type = substr($$segDataPt, 12, 4);
|
|
6981
|
+
my $hdrLen;
|
|
6982
|
+
if ($len == 1 and length($$segDataPt) >= 24) {
|
|
6983
|
+
$len = Get64u($$segDataPt, 16);
|
|
6984
|
+
$hdrLen = 16;
|
|
6985
|
+
} else {
|
|
6986
|
+
$hdrLen = 8;
|
|
6987
|
+
}
|
|
6988
|
+
$jumbfChunk{$type} or $jumbfChunk{$type} = [ ];
|
|
6989
|
+
if ($len < $hdrLen) {
|
|
6990
|
+
$self->Warn('Invalid JUMBF segment');
|
|
6991
|
+
} elsif ($seq < 0) {
|
|
6992
|
+
$self->Warn('Invalid JUMBF sequence number');
|
|
6993
|
+
} elsif (defined $jumbfChunk{$type}[$seq]) {
|
|
6994
|
+
$self->Warn('Duplicate JUMBF sequence number');
|
|
6995
|
+
} else {
|
|
6996
|
+
# add to list of JUMBF chunks
|
|
6997
|
+
$jumbfChunk{$type}[$seq] = substr($$segDataPt, 8 + $hdrLen);
|
|
6998
|
+
# check to see if we have a complete JUMBF box
|
|
6999
|
+
my $size = $hdrLen;
|
|
7000
|
+
foreach (@{$jumbfChunk{$type}}) {
|
|
7001
|
+
defined $_ or $size = 0, last;
|
|
7002
|
+
$size += length $_;
|
|
7003
|
+
}
|
|
7004
|
+
if ($size == $len) {
|
|
7005
|
+
my $buff = join '', substr($$segDataPt,8,$hdrLen), @{$jumbfChunk{$type}};
|
|
7006
|
+
$dirInfo{DataPt} = \$buff;
|
|
7007
|
+
$dirInfo{DataPos} = $segPos + 8; # (shows correct offsets for single-segment JUMBF)
|
|
7008
|
+
$dirInfo{DataLen} = $dirInfo{DirLen} = $size;
|
|
7009
|
+
my $tagTablePtr = GetTagTable('Image::ExifTool::Jpeg2000::Main');
|
|
7010
|
+
$self->ProcessDirectory(\%dirInfo, $tagTablePtr);
|
|
7011
|
+
delete $jumbfChunk{$type};
|
|
7012
|
+
}
|
|
7013
|
+
}
|
|
6907
7014
|
}
|
|
6908
7015
|
} elsif ($marker == 0xec) { # APP12 (Ducky, Picture Info)
|
|
6909
7016
|
if ($$segDataPt =~ /^Ducky/) {
|
|
@@ -6955,7 +7062,7 @@ sub ProcessJPEG($$)
|
|
|
6955
7062
|
} elsif ($marker == 0xee) { # APP14 (Adobe)
|
|
6956
7063
|
if ($$segDataPt =~ /^Adobe/) {
|
|
6957
7064
|
# extract as a block if requested, or if copying tags from file
|
|
6958
|
-
if ($$
|
|
7065
|
+
if ($$req{adobe} or
|
|
6959
7066
|
# (not extracted normally, so check TAGS_FROM_FILE)
|
|
6960
7067
|
($$self{TAGS_FROM_FILE} and not $$self{EXCL_TAG_LOOKUP}{adobe}))
|
|
6961
7068
|
{
|
|
@@ -7058,6 +7165,7 @@ sub ProcessJPEG($$)
|
|
|
7058
7165
|
Image::ExifTool::JPEGDigest::Calculate($self, \@dqt, $subSampling);
|
|
7059
7166
|
}
|
|
7060
7167
|
# issue necessary warnings
|
|
7168
|
+
$self->Warn('Invalid JUMBF size or missing JUMBF chunk') if %jumbfChunk;
|
|
7061
7169
|
$self->Warn('Incomplete ICC_Profile record', 1) if defined $iccChunkCount;
|
|
7062
7170
|
$self->Warn('Incomplete FLIR record', 1) if defined $flirCount;
|
|
7063
7171
|
$self->Warn('Error reading PreviewImage', 1) if $$self{PreviewError};
|
|
@@ -7726,7 +7834,8 @@ sub GetTagInfo($$$;$$$)
|
|
|
7726
7834
|
}
|
|
7727
7835
|
}
|
|
7728
7836
|
if ($$tagInfo{Unknown} and not $$self{OPTIONS}{Unknown} and
|
|
7729
|
-
not $$self{OPTIONS}{Verbose} and not $$self{
|
|
7837
|
+
not $$self{OPTIONS}{Verbose} and not $$self{OPTIONS}{Validate} and
|
|
7838
|
+
not $$self{HTML_DUMP})
|
|
7730
7839
|
{
|
|
7731
7840
|
# don't return Unknown tags unless that option is set
|
|
7732
7841
|
return undef;
|