exiftool_vendored 12.16.0 → 12.25.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +137 -1
  3. data/bin/MANIFEST +12 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +44 -43
  7. data/bin/config_files/acdsee.config +193 -6
  8. data/bin/config_files/cuepointlist.config +70 -0
  9. data/bin/config_files/example.config +1 -8
  10. data/bin/exiftool +139 -98
  11. data/bin/fmt_files/gpx.fmt +1 -1
  12. data/bin/fmt_files/gpx_wpt.fmt +1 -1
  13. data/bin/fmt_files/kml.fmt +1 -1
  14. data/bin/fmt_files/kml_track.fmt +1 -1
  15. data/bin/lib/Image/ExifTool.pm +158 -49
  16. data/bin/lib/Image/ExifTool.pod +94 -75
  17. data/bin/lib/Image/ExifTool/Apple.pm +3 -2
  18. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +25 -14
  19. data/bin/lib/Image/ExifTool/Canon.pm +28 -3
  20. data/bin/lib/Image/ExifTool/CanonCustom.pm +19 -1
  21. data/bin/lib/Image/ExifTool/DJI.pm +6 -6
  22. data/bin/lib/Image/ExifTool/DjVu.pm +6 -5
  23. data/bin/lib/Image/ExifTool/Exif.pm +50 -22
  24. data/bin/lib/Image/ExifTool/FITS.pm +13 -2
  25. data/bin/lib/Image/ExifTool/FujiFilm.pm +19 -8
  26. data/bin/lib/Image/ExifTool/GPS.pm +24 -13
  27. data/bin/lib/Image/ExifTool/H264.pm +20 -5
  28. data/bin/lib/Image/ExifTool/ICC_Profile.pm +2 -2
  29. data/bin/lib/Image/ExifTool/JPEG.pm +6 -2
  30. data/bin/lib/Image/ExifTool/JSON.pm +24 -3
  31. data/bin/lib/Image/ExifTool/Jpeg2000.pm +361 -16
  32. data/bin/lib/Image/ExifTool/M2TS.pm +40 -4
  33. data/bin/lib/Image/ExifTool/MIE.pm +2 -2
  34. data/bin/lib/Image/ExifTool/MRC.pm +341 -0
  35. data/bin/lib/Image/ExifTool/MWG.pm +3 -3
  36. data/bin/lib/Image/ExifTool/MXF.pm +1 -1
  37. data/bin/lib/Image/ExifTool/MacOS.pm +1 -1
  38. data/bin/lib/Image/ExifTool/Microsoft.pm +298 -82
  39. data/bin/lib/Image/ExifTool/Nikon.pm +5 -5
  40. data/bin/lib/Image/ExifTool/NikonSettings.pm +25 -16
  41. data/bin/lib/Image/ExifTool/Olympus.pm +2 -2
  42. data/bin/lib/Image/ExifTool/PNG.pm +2 -2
  43. data/bin/lib/Image/ExifTool/Panasonic.pm +14 -1
  44. data/bin/lib/Image/ExifTool/PhaseOne.pm +4 -3
  45. data/bin/lib/Image/ExifTool/QuickTime.pm +148 -68
  46. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +94 -34
  47. data/bin/lib/Image/ExifTool/README +5 -4
  48. data/bin/lib/Image/ExifTool/RIFF.pm +84 -12
  49. data/bin/lib/Image/ExifTool/Samsung.pm +2 -1
  50. data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -0
  51. data/bin/lib/Image/ExifTool/Sony.pm +157 -49
  52. data/bin/lib/Image/ExifTool/TagInfoXML.pm +1 -0
  53. data/bin/lib/Image/ExifTool/TagLookup.pm +4079 -3987
  54. data/bin/lib/Image/ExifTool/TagNames.pod +642 -273
  55. data/bin/lib/Image/ExifTool/WriteExif.pl +1 -1
  56. data/bin/lib/Image/ExifTool/WritePostScript.pl +1 -0
  57. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +44 -17
  58. data/bin/lib/Image/ExifTool/WriteXMP.pl +15 -8
  59. data/bin/lib/Image/ExifTool/Writer.pl +50 -14
  60. data/bin/lib/Image/ExifTool/XMP.pm +50 -11
  61. data/bin/perl-Image-ExifTool.spec +42 -42
  62. data/lib/exiftool_vendored/version.rb +1 -1
  63. metadata +52 -12
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # Description: Example ExifTool print format file to generate a GPX track log
5
5
  #
6
- # Usage: exiftool -p gpx.fmt -ee FILE [...] > out.gpx
6
+ # Usage: exiftool -p gpx.fmt -ee3 FILE [...] > out.gpx
7
7
  #
8
8
  # Requires: ExifTool version 10.49 or later
9
9
  #
@@ -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 -ee FILE [...] > out.gpx
7
+ # Usage: exiftool -p gpx_wpt.fmt -ee3 FILE [...] > out.gpx
8
8
  #
9
9
  # Requires: ExifTool version 10.49 or later
10
10
  #
@@ -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 -ee option to extract the full track from video files.
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.
@@ -11,7 +11,7 @@
11
11
  #
12
12
  # From video files:
13
13
  #
14
- # exiftool -p kml.fmt -ee FILEorDIR [...] > out.kml
14
+ # exiftool -p kml.fmt -ee3 FILEorDIR [...] > out.kml
15
15
  #
16
16
  # Requires: ExifTool version 10.41 or later
17
17
  #
@@ -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.16';
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 PhotoCD Radiance
141
- PDF PostScript Photoshop::Header Photoshop::Layers Photoshop::ImageData
142
- FujiFilm::RAF FujiFilm::IFD Samsung::Trailer Sony::SRF2 Sony::SR2SubIFD
143
- Sony::PMP ITC ID3 ID3::Lyrics3 FLAC Ogg Vorbis APE APE::NewHeader
144
- APE::OldHeader Audible MPC MPEG::Audio MPEG::Video MPEG::Xing M2TS QuickTime
145
- QuickTime::ImageFile QuickTime::Stream QuickTime::Tags360Fly Matroska MOI
146
- MXF DV Flash Flash::FLV Real::Media Real::Audio Real::Metafile Red RIFF AIFF
147
- ASF WTV DICOM FITS MIE JSON HTML XMP::SVG Palm Palm::MOBI Palm::EXTH Torrent
148
- EXE EXE::PEVersion EXE::PEString EXE::MachO EXE::PEF EXE::ELF EXE::AR
149
- EXE::CHM LNK Font VCard Text VCard::VCalendar RSRC Rawzor ZIP ZIP::GZIP
150
- ZIP::RAR RTF OOXML iWork ISO FLIR::AFF FLIR::FPF MacOS MacOS::MDItem
151
- FlashPix::DocTable
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 MOI
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 & 0777)',
1274
- ValueConvInv => 'oct($val)',
1294
+ ValueConv => 'sprintf("%.3o", $val)',
1295
+ ValueConvInv => 'oct($val & 07777)',
1275
1296
  PrintConv => sub {
1276
- my ($mask, $str, $val) = (0400, '', oct(shift));
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 => 'the full JPEG trailer data block. Extracted only if specifically requested',
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 => undef, # flag to add mdir Handler to newly created Meta box
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, $fileSize);
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
- my ($aTime, $mTime, $cTime) = $self->GetFileTime($$raf{FILE_PT});
2440
- $self->FoundTag('FileSize', $fileSize) if defined $fileSize;
2441
- $self->FoundTag('ResourceForkSize', $rsize) if $rsize;
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) or $self->Warn("GetFileTime error for '${file}'"), return ();
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 and eval { require Time::Local };
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 "Image/ExifTool/QuickTimeStream.pl";
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 = $$self{REQ_TAG_LOOKUP}{jpegimagelength};
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 ($$self{REQ_TAG_LOOKUP}{trailer}) {
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 $$self{REQ_TAG_LOOKUP}{trailer};
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
- ($$self{REQ_TAG_LOOKUP}{jpegdigest} or $$self{REQ_TAG_LOOKUP}{jpegqualityestimate}
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
- ($$self{REQ_TAG_LOOKUP}{previewimage} or
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 ($$self{REQ_TAG_LOOKUP}{adobe} or
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{HTML_DUMP})
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;