exiftool_vendored 12.18.0 → 12.33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +236 -4
  3. data/bin/MANIFEST +23 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +45 -43
  7. data/bin/arg_files/xmp2exif.args +2 -1
  8. data/bin/config_files/acdsee.config +193 -6
  9. data/bin/config_files/convert_regions.config +25 -14
  10. data/bin/config_files/cuepointlist.config +70 -0
  11. data/bin/config_files/example.config +2 -9
  12. data/bin/exiftool +152 -97
  13. data/bin/fmt_files/gpx.fmt +2 -2
  14. data/bin/fmt_files/gpx_wpt.fmt +2 -2
  15. data/bin/fmt_files/kml.fmt +1 -1
  16. data/bin/fmt_files/kml_track.fmt +1 -1
  17. data/bin/lib/Image/ExifTool/Apple.pm +3 -2
  18. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +31 -13
  19. data/bin/lib/Image/ExifTool/CBOR.pm +331 -0
  20. data/bin/lib/Image/ExifTool/Canon.pm +44 -19
  21. data/bin/lib/Image/ExifTool/DJI.pm +6 -6
  22. data/bin/lib/Image/ExifTool/DPX.pm +13 -2
  23. data/bin/lib/Image/ExifTool/DjVu.pm +6 -5
  24. data/bin/lib/Image/ExifTool/Exif.pm +124 -13
  25. data/bin/lib/Image/ExifTool/FITS.pm +13 -2
  26. data/bin/lib/Image/ExifTool/FlashPix.pm +35 -10
  27. data/bin/lib/Image/ExifTool/FujiFilm.pm +19 -8
  28. data/bin/lib/Image/ExifTool/GPS.pm +22 -11
  29. data/bin/lib/Image/ExifTool/Geotag.pm +13 -2
  30. data/bin/lib/Image/ExifTool/GoPro.pm +16 -1
  31. data/bin/lib/Image/ExifTool/ICC_Profile.pm +2 -2
  32. data/bin/lib/Image/ExifTool/ID3.pm +15 -3
  33. data/bin/lib/Image/ExifTool/JPEG.pm +74 -4
  34. data/bin/lib/Image/ExifTool/JSON.pm +30 -5
  35. data/bin/lib/Image/ExifTool/Jpeg2000.pm +395 -16
  36. data/bin/lib/Image/ExifTool/LIF.pm +153 -0
  37. data/bin/lib/Image/ExifTool/Lang/nl.pm +60 -59
  38. data/bin/lib/Image/ExifTool/M2TS.pm +137 -5
  39. data/bin/lib/Image/ExifTool/MIE.pm +4 -3
  40. data/bin/lib/Image/ExifTool/MRC.pm +341 -0
  41. data/bin/lib/Image/ExifTool/MWG.pm +3 -3
  42. data/bin/lib/Image/ExifTool/MXF.pm +1 -1
  43. data/bin/lib/Image/ExifTool/MacOS.pm +3 -3
  44. data/bin/lib/Image/ExifTool/Microsoft.pm +298 -82
  45. data/bin/lib/Image/ExifTool/Nikon.pm +18 -5
  46. data/bin/lib/Image/ExifTool/NikonSettings.pm +19 -2
  47. data/bin/lib/Image/ExifTool/Olympus.pm +10 -3
  48. data/bin/lib/Image/ExifTool/Other.pm +93 -0
  49. data/bin/lib/Image/ExifTool/PDF.pm +9 -12
  50. data/bin/lib/Image/ExifTool/PNG.pm +8 -7
  51. data/bin/lib/Image/ExifTool/Panasonic.pm +28 -3
  52. data/bin/lib/Image/ExifTool/Pentax.pm +28 -5
  53. data/bin/lib/Image/ExifTool/PhaseOne.pm +4 -3
  54. data/bin/lib/Image/ExifTool/Photoshop.pm +6 -0
  55. data/bin/lib/Image/ExifTool/QuickTime.pm +234 -75
  56. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +283 -141
  57. data/bin/lib/Image/ExifTool/README +5 -2
  58. data/bin/lib/Image/ExifTool/RIFF.pm +89 -12
  59. data/bin/lib/Image/ExifTool/Samsung.pm +48 -10
  60. data/bin/lib/Image/ExifTool/Shortcuts.pm +9 -0
  61. data/bin/lib/Image/ExifTool/Sony.pm +230 -69
  62. data/bin/lib/Image/ExifTool/TagInfoXML.pm +1 -0
  63. data/bin/lib/Image/ExifTool/TagLookup.pm +4145 -4029
  64. data/bin/lib/Image/ExifTool/TagNames.pod +671 -287
  65. data/bin/lib/Image/ExifTool/Torrent.pm +18 -11
  66. data/bin/lib/Image/ExifTool/WriteExif.pl +1 -1
  67. data/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
  68. data/bin/lib/Image/ExifTool/WritePDF.pl +1 -0
  69. data/bin/lib/Image/ExifTool/WritePNG.pl +2 -0
  70. data/bin/lib/Image/ExifTool/WritePostScript.pl +1 -0
  71. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +55 -21
  72. data/bin/lib/Image/ExifTool/WriteXMP.pl +7 -3
  73. data/bin/lib/Image/ExifTool/Writer.pl +47 -10
  74. data/bin/lib/Image/ExifTool/XMP.pm +45 -15
  75. data/bin/lib/Image/ExifTool/XMP2.pl +3 -1
  76. data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
  77. data/bin/lib/Image/ExifTool/ZISRAW.pm +121 -2
  78. data/bin/lib/Image/ExifTool.pm +233 -81
  79. data/bin/lib/Image/ExifTool.pod +114 -93
  80. data/bin/perl-Image-ExifTool.spec +43 -42
  81. data/lib/exiftool_vendored/version.rb +1 -1
  82. metadata +28 -13
@@ -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.18';
32
+ $VERSION = '12.33';
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 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
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 MOI
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',
@@ -794,10 +808,12 @@ my %moduleName = (
794
808
  DEX => 0,
795
809
  DOCX => 'OOXML',
796
810
  DCX => 0,
811
+ DIR => 0,
797
812
  DR4 => 'CanonVRD',
798
813
  DSS => 'Olympus',
799
814
  DWF => 0,
800
815
  DWG => 0,
816
+ DXF => 0,
801
817
  EPS => 'PostScript',
802
818
  EXIF => '',
803
819
  EXR => 'OpenEXR',
@@ -811,6 +827,7 @@ my %moduleName = (
811
827
  HDR => 'Radiance',
812
828
  JP2 => 'Jpeg2000',
813
829
  JPEG => '',
830
+ JXL => 'Jpeg2000',
814
831
  LFP => 'Lytro',
815
832
  LRI => 0,
816
833
  MOV => 'QuickTime',
@@ -821,6 +838,7 @@ my %moduleName = (
821
838
  ORF => 'Olympus',
822
839
  PDB => 'Palm',
823
840
  PCD => 'PhotoCD',
841
+ PFM2 => 'Other',
824
842
  PHP => 0,
825
843
  PMP => 'Sony',
826
844
  PS => 'PostScript',
@@ -872,6 +890,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
872
890
  DV => '\x1f\x07\0[\x3f\xbf]', # (not tested if extension recognized)
873
891
  DWF => '\(DWF V\d',
874
892
  DWG => 'AC10\d{2}\0',
893
+ DXF => '\s*0\s+\0?\s*SECTION\s+2\s+HEADER',
875
894
  EPS => '(%!PS|%!Ad|\xc5\xd0\xd3\xc6)',
876
895
  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
896
  EXIF => '(II\x2a\0|MM\0\x2a)',
@@ -897,7 +916,9 @@ $testLen = 1024; # number of bytes to read when testing for magic number
897
916
  JP2 => '(\0\0\0\x0cjP( |\x1a\x1a)\x0d\x0a\x87\x0a|\xff\x4f\xff\x51\0)',
898
917
  JPEG => '\xff\xd8\xff',
899
918
  JSON => '(\xef\xbb\xbf)?\s*(\[\s*)?\{\s*"[^"]*"\s*:',
919
+ JXL => '\xff\x0a|\0\0\0\x0cJXL \x0d\x0a......ftypjxl ',
900
920
  LFP => '\x89LFP\x0d\x0a\x1a\x0a',
921
+ LIF => '\x70\0{3}.{4}\x2a.{4}<\0',
901
922
  LNK => '.{4}\x01\x14\x02\0{5}\xc0\0{6}\x46',
902
923
  LRI => 'LELR \0',
903
924
  M2TS => '(....)?\x47',
@@ -909,14 +930,16 @@ $testLen = 1024; # number of bytes to read when testing for magic number
909
930
  MPC => '(MP\+|ID3)',
910
931
  MOI => 'V6',
911
932
  MPEG => '\0\0\x01[\xb0-\xbf]',
933
+ 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
934
  MRW => '\0MR[MI]',
913
935
  MXF => '\x06\x0e\x2b\x34\x02\x05\x01\x01\x0d\x01\x02', # (not tested if extension recognized)
914
936
  OGG => '(OggS|ID3)',
915
937
  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
938
  # PCD => signature is at byte 2048
918
939
  PCX => '\x0a[\0-\x05]\x01[\x01\x02\x04\x08].{64}[\0-\x02]',
940
+ 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
941
  PDF => '\s*%PDF-\d+\.\d+',
942
+ PFM => 'P[Ff]\x0a\d+ \d+\x0a[-+0-9.]+\x0a',
920
943
  PGF => 'PGF',
921
944
  PHP => '<\?php\s',
922
945
  PICT => '(.{10}|.{522})(\x11\x01|\x00\x11)',
@@ -1129,11 +1152,18 @@ my %systemTagsNotes = (
1129
1152
  RawConv => '$self->ConvertFileName($val)',
1130
1153
  ValueConvInv => '$self->InverseFileName($val)',
1131
1154
  },
1155
+ BaseName => {
1156
+ Groups => { 1 => 'System', 2 => 'Other' },
1157
+ Notes => q{
1158
+ file name without extension. Not generated unless specifically requested or
1159
+ the API L<RequestAll|../ExifTool.html#RequestAll> option is set
1160
+ },
1161
+ },
1132
1162
  FilePath => {
1133
1163
  Groups => { 1 => 'System', 2 => 'Other' },
1134
1164
  Notes => q{
1135
1165
  absolute path of source file. Not generated unless specifically requested or
1136
- the L<RequestAll|../ExifTool.html#RequestAll> API option is set. Does not support Windows Unicode file
1166
+ the API L<RequestAll|../ExifTool.html#RequestAll> option is set. Does not support Windows Unicode file
1137
1167
  names
1138
1168
  },
1139
1169
  },
@@ -1156,7 +1186,7 @@ my %systemTagsNotes = (
1156
1186
  sequence number for each source file when extracting or copying information,
1157
1187
  including files that fail the -if condition of the command-line application,
1158
1188
  beginning at 0 for the first file. Not generated unless specifically
1159
- requested or the L<RequestAll|../ExifTool.html#RequestAll> API option is set
1189
+ requested or the API L<RequestAll|../ExifTool.html#RequestAll> option is set
1160
1190
  },
1161
1191
  },
1162
1192
  FileSize => {
@@ -1229,7 +1259,7 @@ my %systemTagsNotes = (
1229
1259
  the filesystem creation date/time. Windows/Mac only. In Windows, the file
1230
1260
  creation date/time is preserved by default when writing if Win32API::File
1231
1261
  and Win32::API are available. On Mac, this tag is extracted only if it or
1232
- the MacOS group is specifically requested or the L<RequestAll|../ExifTool.html#RequestAll> API option is
1262
+ the MacOS group is specifically requested or the API L<RequestAll|../ExifTool.html#RequestAll> option is
1233
1263
  set to 2 or higher. Requires "setfile" for writing on Mac, which may be
1234
1264
  installed by typing C<xcode-select --install> in the Terminal
1235
1265
  },
@@ -1270,10 +1300,19 @@ my %systemTagsNotes = (
1270
1300
  WritePseudo => 1,
1271
1301
  DelCheck => q{"Can't delete"},
1272
1302
  Protected => 1, # all writable pseudo-tags must be protected!
1273
- ValueConv => 'sprintf("%.3o", $val & 0777)',
1274
- ValueConvInv => 'oct($val)',
1303
+ ValueConv => 'sprintf("%.3o", $val)',
1304
+ ValueConvInv => 'oct($val & 07777)',
1275
1305
  PrintConv => sub {
1276
- my ($mask, $str, $val) = (0400, '', oct(shift));
1306
+ my ($mask, $val) = (0400, oct(shift));
1307
+ my %types = (
1308
+ 0010000 => 'p',
1309
+ 0020000 => 'c',
1310
+ 0040000 => 'd',
1311
+ 0060000 => 'b',
1312
+ 0120000 => 'l',
1313
+ 0140000 => 's',
1314
+ );
1315
+ my $str = $types{$val & 0170000} || '-';
1277
1316
  while ($mask) {
1278
1317
  foreach (qw(r w x)) {
1279
1318
  $str .= $val & $mask ? $_ : '-';
@@ -1284,6 +1323,7 @@ my %systemTagsNotes = (
1284
1323
  },
1285
1324
  PrintConvInv => sub {
1286
1325
  my ($bit, $val, $str) = (8, 0, shift);
1326
+ $str = substr($str, 1) if length($str) == 10;
1287
1327
  return undef if length($str) != 9;
1288
1328
  while ($bit >= 0) {
1289
1329
  foreach (qw(r w x)) {
@@ -1610,7 +1650,7 @@ my %systemTagsNotes = (
1610
1650
  sub-sampling values to generate the value of this tag. The result is
1611
1651
  compared to known values in an attempt to deduce the originating software
1612
1652
  based only on the JPEG image data. For performance reasons, this tag is
1613
- generated only if specifically requested or the L<RequestAll|../ExifTool.html#RequestAll> API option is set
1653
+ generated only if specifically requested or the API L<RequestAll|../ExifTool.html#RequestAll> option is set
1614
1654
  to 3 or higher
1615
1655
  },
1616
1656
  },
@@ -1618,14 +1658,14 @@ my %systemTagsNotes = (
1618
1658
  Notes => q{
1619
1659
  an estimate of the IJG JPEG quality setting for the image, calculated from
1620
1660
  the quantization tables. For performance reasons, this tag is generated
1621
- only if specifically requested or the L<RequestAll|../ExifTool.html#RequestAll> API option is set to 3 or
1661
+ only if specifically requested or the API L<RequestAll|../ExifTool.html#RequestAll> option is set to 3 or
1622
1662
  higher
1623
1663
  },
1624
1664
  },
1625
1665
  JPEGImageLength => {
1626
1666
  Notes => q{
1627
1667
  byte length of JPEG image without metadata. For performance reasons, this
1628
- tag is generated only if specifically requested or the L<RequestAll|../ExifTool.html#RequestAll> API option
1668
+ tag is generated only if specifically requested or the API L<RequestAll|../ExifTool.html#RequestAll> option
1629
1669
  is set to 3 or higher
1630
1670
  },
1631
1671
  },
@@ -1635,7 +1675,7 @@ my %systemTagsNotes = (
1635
1675
  Notes => q{
1636
1676
  the current date/time. Useful when setting the tag values, eg.
1637
1677
  C<"-modifydate<now">. Not generated unless specifically requested or the
1638
- L<RequestAll|../ExifTool.html#RequestAll> API option is set
1678
+ API L<RequestAll|../ExifTool.html#RequestAll> option is set
1639
1679
  },
1640
1680
  PrintConv => '$self->ConvertDateTime($val)',
1641
1681
  },
@@ -1646,7 +1686,7 @@ my %systemTagsNotes = (
1646
1686
  YYYYmmdd-HHMM-SSNN-PPPP-RRRRRRRRRRRR, where Y=year, m=month, d=day, H=hour,
1647
1687
  M=minute, S=second, N=file sequence number in hex, P=process ID in hex, and
1648
1688
  R=random hex number; without dashes with the -n option. Not generated
1649
- unless specifically requested or the L<RequestAll|../ExifTool.html#RequestAll> API option is set
1689
+ unless specifically requested or the API L<RequestAll|../ExifTool.html#RequestAll> option is set
1650
1690
  },
1651
1691
  PrintConv => '$val =~ s/(.{8})(.{4})(.{4})(.{4})/$1-$2-$3-$4-/; $val',
1652
1692
  },
@@ -1737,7 +1777,10 @@ my %systemTagsNotes = (
1737
1777
  EmbeddedVideo => { Groups => { 0 => 'Trailer', 2 => 'Video' } },
1738
1778
  Trailer => {
1739
1779
  Groups => { 0 => 'Trailer' },
1740
- Notes => 'the full JPEG trailer data block. Extracted only if specifically requested',
1780
+ Notes => q{
1781
+ the full JPEG trailer data block. Extracted only if specifically requested
1782
+ or the API RequestAll option is set to 3 or higher
1783
+ },
1741
1784
  Writable => 1,
1742
1785
  Protected => 1,
1743
1786
  },
@@ -1898,6 +1941,8 @@ my %systemTagsNotes = (
1898
1941
  return \$img;
1899
1942
  },
1900
1943
  },
1944
+ # Apple may add "AMPF" to the end of the JFIF record,
1945
+ # possibly indicating the existence of MPF images (ref forum12677)
1901
1946
  );
1902
1947
 
1903
1948
  # Composite tags (accumulation of all Composite tag tables)
@@ -2050,12 +2095,15 @@ sub Options($$;@)
2050
2095
  $$options{$param} = $newVal;
2051
2096
  delete $$self{CUR_LANG};
2052
2097
  # make sure the language is available
2053
- } elsif (eval "require Image::ExifTool::Lang::$newVal") {
2054
- my $xlat = "Image::ExifTool::Lang::${newVal}::Translate";
2055
- no strict 'refs';
2056
- if (%$xlat) {
2057
- $$self{CUR_LANG} = \%$xlat;
2058
- $$options{$param} = $newVal;
2098
+ } else {
2099
+ my %langs = map { $_ => 1 } @langs;
2100
+ if ($langs{$newVal} and eval "require Image::ExifTool::Lang::$newVal") {
2101
+ my $xlat = "Image::ExifTool::Lang::${newVal}::Translate";
2102
+ no strict 'refs';
2103
+ if (%$xlat) {
2104
+ $$self{CUR_LANG} = \%$xlat;
2105
+ $$options{$param} = $newVal;
2106
+ }
2059
2107
  }
2060
2108
  } # else don't change Lang
2061
2109
  } elsif ($param eq 'Exclude' and defined $newVal) {
@@ -2271,7 +2319,7 @@ sub ClearOptions($)
2271
2319
  NoPDFList => undef, # flag to avoid splitting PDF List-type tag values
2272
2320
  Password => undef, # password for password-protected PDF documents
2273
2321
  PrintConv => 1, # flag to enable print conversion
2274
- QuickTimeHandler => undef, # flag to add mdir Handler to newly created Meta box
2322
+ QuickTimeHandler => 1, # flag to add mdir Handler to newly created Meta box
2275
2323
  QuickTimeUTC=> undef, # assume that QuickTime date/time tags are stored as UTC
2276
2324
  RequestAll => undef, # extract all tags that must be specifically requested
2277
2325
  RequestTags => undef, # extra tags to request (on top of those in the tag list)
@@ -2321,7 +2369,7 @@ sub ExtractInfo($;@)
2321
2369
  my $fast = $$options{FastScan} || 0;
2322
2370
  my $req = $$self{REQ_TAG_LOOKUP};
2323
2371
  my $reqAll = $$options{RequestAll} || 0;
2324
- my (%saveOptions, $reEntry, $rsize, $type, @startTime, $saveOrder);
2372
+ my (%saveOptions, $reEntry, $rsize, $type, @startTime, $saveOrder, $isDir);
2325
2373
 
2326
2374
  # check for internal ReEntry option to allow recursive calls to ExtractInfo
2327
2375
  if (ref $_[1] eq 'HASH' and $_[1]{ReEntry} and
@@ -2394,6 +2442,11 @@ sub ExtractInfo($;@)
2394
2442
  $realname =~ /\|$/ and $realname =~ s/^.*?"(.*?)".*/$1/s;
2395
2443
  my ($dir, $name) = SplitFileName($realname);
2396
2444
  $self->FoundTag('FileName', $name);
2445
+ if ($$req{basename} or
2446
+ ($reqAll and not $$self{EXCL_TAG_LOOKUP}{basename}))
2447
+ {
2448
+ $self->FoundTag('BaseName', $name =~ /(.*)\./ ? $1 : $name);
2449
+ }
2397
2450
  $self->FoundTag('Directory', $dir) if defined $dir and length $dir;
2398
2451
  if ($$req{filepath} or
2399
2452
  ($reqAll and not $$self{EXCL_TAG_LOOKUP}{filepath}))
@@ -2417,6 +2470,8 @@ sub ExtractInfo($;@)
2417
2470
  # in Windows cmd shell pipe even though it really failed
2418
2471
  $$raf{TESTED} = -1 if $filename eq '-' or $filename =~ /\|$/;
2419
2472
  $$self{RAF} = $raf;
2473
+ } elsif ($self->IsDirectory($filename)) {
2474
+ $isDir = 1;
2420
2475
  } else {
2421
2476
  $self->Error('Error opening file');
2422
2477
  }
@@ -2425,28 +2480,34 @@ sub ExtractInfo($;@)
2425
2480
  }
2426
2481
  }
2427
2482
 
2428
- while ($raf) {
2429
- my (@stat, $fileSize);
2483
+ while ($raf or $isDir) {
2484
+ my (@stat, $plainFile);
2430
2485
  if ($reEntry) {
2431
2486
  # we already set these tags
2487
+ } elsif (not $raf) {
2488
+ @stat = stat $filename;
2432
2489
  } elsif (not $$raf{FILE_PT}) {
2433
2490
  # get file size from image in memory
2434
2491
  $self->FoundTag('FileSize', length ${$$raf{BUFF_PT}});
2435
2492
  } elsif (-f $$raf{FILE_PT}) {
2436
2493
  # get file tags if this is a plain file
2437
- $fileSize = -s _;
2438
2494
  @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];
2495
+ $plainFile = 1;
2496
+ # hack to patch Windows daylight savings time bug
2497
+ @stat[8,9,10] = $self->GetFileTime($$raf{FILE_PT}) if $^O eq 'MSWin32';
2447
2498
  } else {
2499
+ # (note that Windows directories will still show the
2500
+ # daylight savings time bug -- should fix this sometime)
2448
2501
  @stat = stat $$raf{FILE_PT};
2449
2502
  }
2503
+ my $fileSize = $stat[7];
2504
+ $self->FoundTag('FileSize', $stat[7]) if defined $stat[7];
2505
+ $self->FoundTag('ResourceForkSize', $rsize) if $rsize;
2506
+ $self->FoundTag('FileModifyDate', $stat[9]) if defined $stat[9];
2507
+ $self->FoundTag('FileAccessDate', $stat[8]) if defined $stat[8];
2508
+ my $cTag = $^O eq 'MSWin32' ? 'FileCreateDate' : 'FileInodeChangeDate';
2509
+ $self->FoundTag($cTag, $stat[10]) if defined $stat[10];
2510
+ $self->FoundTag('FilePermissions', $stat[2]) if defined $stat[2];
2450
2511
  # extract more system info if SystemTags option is set
2451
2512
  if (@stat) {
2452
2513
  my $sys = $$options{SystemTags} || ($reqAll and not defined $$options{SystemTags});
@@ -2486,11 +2547,18 @@ sub ExtractInfo($;@)
2486
2547
  if ($crDate or $mdItem or $xattr) {
2487
2548
  require Image::ExifTool::MacOS;
2488
2549
  Image::ExifTool::MacOS::GetFileCreateDate($self, $filename) if $crDate;
2489
- Image::ExifTool::MacOS::ExtractMDItemTags($self, $filename) if $mdItem;
2550
+ Image::ExifTool::MacOS::ExtractMDItemTags($self, $filename) if $mdItem and $plainFile;
2490
2551
  Image::ExifTool::MacOS::ExtractXAttrTags($self, $filename) if $xattr;
2491
2552
  }
2492
2553
  }
2493
-
2554
+ # do whatever else we can with directories, then return
2555
+ if ($isDir or (defined $stat[2] and ($stat[2] & 0170000) == 0040000)) {
2556
+ $self->FoundTag('FileType', 'DIR');
2557
+ $self->FoundTag('FileTypeExtension', '');
2558
+ $self->BuildCompositeTags() if $$options{Composite};
2559
+ $raf->Close() if $raf;
2560
+ return 1;
2561
+ }
2494
2562
  # get list of file types to check
2495
2563
  my ($tiffType, %noMagic, $recognizedExt);
2496
2564
  my $ext = $$self{FILE_EXT} = GetFileExtension($realname);
@@ -3250,8 +3318,9 @@ sub GetTagID($$)
3250
3318
  my ($self, $tag) = @_;
3251
3319
  my $tagInfo = $$self{TAG_INFO}{$tag};
3252
3320
  return '' unless $tagInfo and defined $$tagInfo{TagID};
3253
- return ($$tagInfo{TagID}, $$tagInfo{LangCode}) if wantarray;
3254
- return $$tagInfo{TagID};
3321
+ my $id = $$tagInfo{KeysID} || $$tagInfo{TagID};
3322
+ return ($id, $$tagInfo{LangCode}) if wantarray;
3323
+ return $id;
3255
3324
  }
3256
3325
 
3257
3326
  #------------------------------------------------------------------------------
@@ -3367,7 +3436,7 @@ sub GetGroup($$;$)
3367
3436
  }
3368
3437
  # generate tag ID group names unless obviously not needed
3369
3438
  unless ($noID) {
3370
- my $id = $$tagInfo{TagID};
3439
+ my $id = $$tagInfo{KeysID} || $$tagInfo{TagID};
3371
3440
  if (not defined $id) {
3372
3441
  $id = ''; # (just to be safe)
3373
3442
  } elsif ($id =~ /^\d+$/) {
@@ -3722,7 +3791,15 @@ sub GetFileType(;$$)
3722
3791
  # return description if specified
3723
3792
  # (allow input $file to be a FileType for this purpose)
3724
3793
  if ($desc) {
3725
- $desc = $fileType ? $$fileType[1] : $fileDescription{$file};
3794
+ if ($fileType) {
3795
+ if ($static_vars{OverrideFileDescription} and $static_vars{OverrideFileDescription}{$fileExt}) {
3796
+ $desc = $static_vars{OverrideFileDescription}{$fileExt};
3797
+ } else {
3798
+ $desc = $$fileType[1];
3799
+ }
3800
+ } else {
3801
+ $desc = $fileDescription{$file};
3802
+ }
3726
3803
  $desc .= ", $subType" if $subType;
3727
3804
  return $desc;
3728
3805
  } elsif ($fileType and (not defined $desc or $desc ne '0')) {
@@ -3787,6 +3864,7 @@ sub Init($)
3787
3864
  foreach (keys %$self) {
3788
3865
  /[a-z]/ and delete $$self{$_};
3789
3866
  }
3867
+ undef %static_vars; # clear all static variables
3790
3868
  delete $$self{FOUND_TAGS}; # list of found tags
3791
3869
  delete $$self{EXIF_DATA}; # the EXIF data block
3792
3870
  delete $$self{EXIF_POS}; # EXIF position in file
@@ -4044,7 +4122,9 @@ sub Exists($$)
4044
4122
  return 0 unless $wh;
4045
4123
  eval { Win32API::File::CloseHandle($wh) };
4046
4124
  } else {
4047
- return -e $file;
4125
+ # (named pipes already exist, but we pretend that they don't
4126
+ # so we will be able to write them, so test with for pipe -p)
4127
+ return(-e $file and not -p $file);
4048
4128
  }
4049
4129
  return 1;
4050
4130
  }
@@ -4079,7 +4159,14 @@ sub GetFileTime($$)
4079
4159
  # open file by name if necessary
4080
4160
  unless (ref $file) {
4081
4161
  local *FH;
4082
- $self->Open(\*FH, $file) or $self->Warn("GetFileTime error for '${file}'"), return ();
4162
+ unless ($self->Open(\*FH, $file)) {
4163
+ if ($self->IsDirectory($file)) {
4164
+ my @rtn = (stat $file)[8, 9, 10];
4165
+ return @rtn if defined $rtn[0];
4166
+ }
4167
+ $self->Warn("GetFileTime error for '${file}'");
4168
+ return ();
4169
+ }
4083
4170
  $file = *FH; # (not \*FH, so *FH will be kept open until $file goes out of scope)
4084
4171
  }
4085
4172
  # on Windows, try to work around incorrect file times when daylight saving time is in effect
@@ -5710,7 +5797,11 @@ sub GetUnixTime($;$)
5710
5797
  my ($timeStr, $isLocal) = @_;
5711
5798
  return 0 if $timeStr eq '0000:00:00 00:00:00';
5712
5799
  my @tm = ($timeStr =~ /^(\d+):(\d+):(\d+)\s+(\d+):(\d+):(\d+)(.*)/);
5713
- return undef unless @tm == 7 and eval { require Time::Local };
5800
+ return undef unless @tm == 7;
5801
+ unless (eval { require Time::Local }) {
5802
+ warn "Time::Local is not installed\n";
5803
+ return undef;
5804
+ }
5714
5805
  my ($tzStr, $tzSec) = (pop(@tm), 0);
5715
5806
  # use specified timezone offset (if given) instead of local system time
5716
5807
  # if we are converting a local time value
@@ -5908,7 +5999,7 @@ sub ProcessTrailers($$)
5908
5999
  for (;;) { # loop through all trailers
5909
6000
  my ($proc, $outBuff);
5910
6001
  if ($dirName eq 'Insta360') {
5911
- require "Image/ExifTool/QuickTimeStream.pl";
6002
+ require 'Image/ExifTool/QuickTimeStream.pl';
5912
6003
  $proc = 'Image::ExifTool::QuickTime::ProcessInsta360';
5913
6004
  } else {
5914
6005
  require "Image/ExifTool/$dirName.pm";
@@ -6070,9 +6161,10 @@ sub ProcessJPEG($$)
6070
6161
  my $out = $$options{TextOut};
6071
6162
  my $fast = $$options{FastScan} || 0;
6072
6163
  my $raf = $$dirInfo{RAF};
6164
+ my $req = $$self{REQ_TAG_LOOKUP};
6073
6165
  my $htmlDump = $$self{HTML_DUMP};
6074
6166
  my %dumpParms = ( Out => $out );
6075
- my ($success, $wantTrailer, $trailInfo, $foundSOS);
6167
+ my ($success, $wantTrailer, $trailInfo, $foundSOS, %jumbfChunk);
6076
6168
  my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $flirTotal);
6077
6169
  my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP);
6078
6170
 
@@ -6083,7 +6175,7 @@ sub ProcessJPEG($$)
6083
6175
  $$self{FILE_TYPE} = 'EXV';
6084
6176
  }
6085
6177
  my $appBytes = 0;
6086
- my $calcImageLen = $$self{REQ_TAG_LOOKUP}{jpegimagelength};
6178
+ my $calcImageLen = $$req{jpegimagelength};
6087
6179
  if ($$options{RequestAll} and $$options{RequestAll} > 2) {
6088
6180
  $calcImageLen = 1;
6089
6181
  }
@@ -6116,6 +6208,7 @@ sub ProcessJPEG($$)
6116
6208
  my $marker = $nextMarker;
6117
6209
  my $segDataPt = $nextSegDataPt;
6118
6210
  my $segPos = $nextSegPos;
6211
+ my $skipped;
6119
6212
  undef $nextMarker;
6120
6213
  undef $nextSegDataPt;
6121
6214
  #
@@ -6125,11 +6218,13 @@ sub ProcessJPEG($$)
6125
6218
  # read up to next marker (JPEG markers begin with 0xff)
6126
6219
  my $buff;
6127
6220
  $raf->ReadLine($buff) or last;
6221
+ $skipped = length($buff) - 1;
6128
6222
  # JPEG markers can be padded with unlimited 0xff's
6129
6223
  for (;;) {
6130
6224
  $raf->Read($ch, 1) or last Marker;
6131
6225
  $nextMarker = ord($ch);
6132
6226
  last unless $nextMarker == 0xff;
6227
+ ++$skipped;
6133
6228
  }
6134
6229
  # read segment data if it exists
6135
6230
  if (not defined $markerLenBytes{$nextMarker}) {
@@ -6156,6 +6251,14 @@ sub ProcessJPEG($$)
6156
6251
  # set some useful variables for the current segment
6157
6252
  my $markerName = JpegMarkerName($marker);
6158
6253
  $$path[$pn] = $markerName;
6254
+ # issue warning if we skipped some garbage
6255
+ if ($skipped and not $foundSOS) {
6256
+ $self->Warn("Skipped unknown $skipped bytes after JPEG $markerName segment", 1);
6257
+ if ($htmlDump) {
6258
+ $self->HDump($nextSegPos-4-$skipped, $skipped, "[unknown $skipped bytes]", undef, 0x08);
6259
+ $dumpEnd = $nextSegPos - 4;
6260
+ }
6261
+ }
6159
6262
  #
6160
6263
  # parse the current segment
6161
6264
  #
@@ -6217,7 +6320,7 @@ sub ProcessJPEG($$)
6217
6320
  } else {
6218
6321
  $self->Warn('Missing JPEG SOS');
6219
6322
  }
6220
- if ($$self{REQ_TAG_LOOKUP}{trailer}) {
6323
+ if ($$req{trailer}) {
6221
6324
  # read entire trailer into memory
6222
6325
  if ($raf->Seek(0,2)) {
6223
6326
  my $len = $raf->Tell() - $pos;
@@ -6351,7 +6454,7 @@ sub ProcessJPEG($$)
6351
6454
  next if $trailInfo or $wantTrailer or $verbose > 2 or $htmlDump;
6352
6455
  }
6353
6456
  # must scan to EOI if Validate or JpegCompressionFactor used
6354
- next if $$options{Validate} or $calcImageLen or $$self{REQ_TAG_LOOKUP}{trailer};
6457
+ next if $$options{Validate} or $calcImageLen or $$req{trailer};
6355
6458
  # nothing interesting to parse after start of scan (SOS)
6356
6459
  $success = 1;
6357
6460
  last; # all done parsing file
@@ -6367,11 +6470,11 @@ sub ProcessJPEG($$)
6367
6470
  next;
6368
6471
  } elsif ($marker == 0xdb and length($$segDataPt) and # DQT
6369
6472
  # save the DQT data only if JPEGDigest has been requested
6370
- # (Note: since we aren't checking the RequestAll API option here, the application
6473
+ # (Note: since we aren't checking the API RequestAll option here, the application
6371
6474
  # must use the RequestTags option to generate these tags if they have not been
6372
6475
  # specifically requested. The reason is that there is too much overhead involved
6373
6476
  # 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}
6477
+ ($$req{jpegdigest} or $$req{jpegqualityestimate}
6375
6478
  or ($$options{RequestAll} and $$options{RequestAll} > 2)))
6376
6479
  {
6377
6480
  my $num = unpack('C',$$segDataPt) & 0x0f; # get table index
@@ -6489,7 +6592,7 @@ sub ProcessJPEG($$)
6489
6592
  }
6490
6593
  if ($start and $plen and IsInt($start) and IsInt($plen) and
6491
6594
  $start + $plen > $$self{EXIF_POS} + length($$self{EXIF_DATA}) and
6492
- ($$self{REQ_TAG_LOOKUP}{previewimage} or
6595
+ ($$req{previewimage} or
6493
6596
  # (extracted normally, so check Binary option)
6494
6597
  ($$options{Binary} and not $$self{EXCL_TAG_LOOKUP}{previewimage})))
6495
6598
  {
@@ -6695,6 +6798,12 @@ sub ProcessJPEG($$)
6695
6798
  # extract the Stim information (it is in standard TIFF format)
6696
6799
  my $tagTablePtr = GetTagTable('Image::ExifTool::Stim::Main');
6697
6800
  $self->ProcessTIFF(\%dirInfo, $tagTablePtr);
6801
+ } elsif ($$segDataPt =~ /^_JPSJPS_/) {
6802
+ $dumpType = 'JPS';
6803
+ $self->OverrideFileType('JPS') if $$self{FILE_TYPE} eq 'JPEG';
6804
+ SetByteOrder('MM');
6805
+ my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::JPS');
6806
+ $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
6698
6807
  } elsif ($$self{Make} eq 'DJI') {
6699
6808
  $dumpType = 'DJI ThermalData';
6700
6809
  # add this data to the combined data if it exists
@@ -6884,7 +6993,7 @@ sub ProcessJPEG($$)
6884
6993
  # (with number of elements N = ImageHeight / 16 - 1, ref PH/NealKrawetz)
6885
6994
  $xtra = 'segment (N=' . unpack('x6N', $$segDataPt) . ')';
6886
6995
  }
6887
- } elsif ($marker == 0xeb) { # APP11 (JPEG-HDR)
6996
+ } elsif ($marker == 0xeb) { # APP11 (JPEG-HDR, JUMBF)
6888
6997
  if ($$segDataPt =~ /^HDR_RI /) {
6889
6998
  $dumpType = 'JPEG-HDR';
6890
6999
  my $dataPt = $segDataPt;
@@ -6904,6 +7013,47 @@ sub ProcessJPEG($$)
6904
7013
  $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
6905
7014
  undef $combinedSegData;
6906
7015
  }
7016
+ } elsif ($$segDataPt =~ /^(JP..)/s and length($$segDataPt) >= 16) {
7017
+ # JUMBF extension marker
7018
+ my $hdr = $1;
7019
+ $dumpType = 'JUMBF';
7020
+ SetByteOrder('MM');
7021
+ my $seq = Get32u($segDataPt, 4) - 1; # (start from 0)
7022
+ my $len = Get32u($segDataPt, 8);
7023
+ my $type = substr($$segDataPt, 12, 4);
7024
+ my $hdrLen;
7025
+ if ($len == 1 and length($$segDataPt) >= 24) {
7026
+ $len = Get64u($$segDataPt, 16);
7027
+ $hdrLen = 16;
7028
+ } else {
7029
+ $hdrLen = 8;
7030
+ }
7031
+ $jumbfChunk{$type} or $jumbfChunk{$type} = [ ];
7032
+ if ($len < $hdrLen) {
7033
+ $self->Warn('Invalid JUMBF segment');
7034
+ } elsif ($seq < 0) {
7035
+ $self->Warn('Invalid JUMBF sequence number');
7036
+ } elsif (defined $jumbfChunk{$type}[$seq]) {
7037
+ $self->Warn('Duplicate JUMBF sequence number');
7038
+ } else {
7039
+ # add to list of JUMBF chunks
7040
+ $jumbfChunk{$type}[$seq] = substr($$segDataPt, 8 + $hdrLen);
7041
+ # check to see if we have a complete JUMBF box
7042
+ my $size = $hdrLen;
7043
+ foreach (@{$jumbfChunk{$type}}) {
7044
+ defined $_ or $size = 0, last;
7045
+ $size += length $_;
7046
+ }
7047
+ if ($size == $len) {
7048
+ my $buff = join '', substr($$segDataPt,8,$hdrLen), @{$jumbfChunk{$type}};
7049
+ $dirInfo{DataPt} = \$buff;
7050
+ $dirInfo{DataPos} = $segPos + 8; # (shows correct offsets for single-segment JUMBF)
7051
+ $dirInfo{DataLen} = $dirInfo{DirLen} = $size;
7052
+ my $tagTablePtr = GetTagTable('Image::ExifTool::Jpeg2000::Main');
7053
+ $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
7054
+ delete $jumbfChunk{$type};
7055
+ }
7056
+ }
6907
7057
  }
6908
7058
  } elsif ($marker == 0xec) { # APP12 (Ducky, Picture Info)
6909
7059
  if ($$segDataPt =~ /^Ducky/) {
@@ -6955,7 +7105,7 @@ sub ProcessJPEG($$)
6955
7105
  } elsif ($marker == 0xee) { # APP14 (Adobe)
6956
7106
  if ($$segDataPt =~ /^Adobe/) {
6957
7107
  # extract as a block if requested, or if copying tags from file
6958
- if ($$self{REQ_TAG_LOOKUP}{adobe} or
7108
+ if ($$req{adobe} or
6959
7109
  # (not extracted normally, so check TAGS_FROM_FILE)
6960
7110
  ($$self{TAGS_FROM_FILE} and not $$self{EXCL_TAG_LOOKUP}{adobe}))
6961
7111
  {
@@ -7058,6 +7208,7 @@ sub ProcessJPEG($$)
7058
7208
  Image::ExifTool::JPEGDigest::Calculate($self, \@dqt, $subSampling);
7059
7209
  }
7060
7210
  # issue necessary warnings
7211
+ $self->Warn('Invalid JUMBF size or missing JUMBF chunk') if %jumbfChunk;
7061
7212
  $self->Warn('Incomplete ICC_Profile record', 1) if defined $iccChunkCount;
7062
7213
  $self->Warn('Incomplete FLIR record', 1) if defined $flirCount;
7063
7214
  $self->Warn('Error reading PreviewImage', 1) if $$self{PreviewError};
@@ -7726,7 +7877,8 @@ sub GetTagInfo($$$;$$$)
7726
7877
  }
7727
7878
  }
7728
7879
  if ($$tagInfo{Unknown} and not $$self{OPTIONS}{Unknown} and
7729
- not $$self{OPTIONS}{Verbose} and not $$self{HTML_DUMP})
7880
+ not $$self{OPTIONS}{Verbose} and not $$self{OPTIONS}{Validate} and
7881
+ not $$self{HTML_DUMP})
7730
7882
  {
7731
7883
  # don't return Unknown tags unless that option is set
7732
7884
  return undef;