exiftool_vendored 12.17.1 → 12.32.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +225 -1
  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 +142 -87
  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 +30 -12
  19. data/bin/lib/Image/ExifTool/CBOR.pm +277 -0
  20. data/bin/lib/Image/ExifTool/Canon.pm +49 -18
  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 +28 -11
  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 +27 -4
  35. data/bin/lib/Image/ExifTool/Jpeg2000.pm +393 -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 +1 -1
  44. data/bin/lib/Image/ExifTool/Microsoft.pm +298 -82
  45. data/bin/lib/Image/ExifTool/Nikon.pm +19 -8
  46. data/bin/lib/Image/ExifTool/NikonSettings.pm +28 -11
  47. data/bin/lib/Image/ExifTool/Olympus.pm +6 -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 +247 -88
  56. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +283 -141
  57. data/bin/lib/Image/ExifTool/README +3 -0
  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 +237 -78
  62. data/bin/lib/Image/ExifTool/TagInfoXML.pm +1 -0
  63. data/bin/lib/Image/ExifTool/TagLookup.pm +4125 -4028
  64. data/bin/lib/Image/ExifTool/TagNames.pod +644 -286
  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 +39 -14
  75. data/bin/lib/Image/ExifTool/XMP2.pl +2 -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 +223 -72
  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.17';
32
+ $VERSION = '12.32';
32
33
  $RELEASE = '';
33
34
  @ISA = qw(Exporter);
34
35
  %EXPORT_TAGS = (
@@ -42,7 +43,7 @@ $RELEASE = '';
42
43
  DataAccess => [qw(
43
44
  ReadValue GetByteOrder SetByteOrder ToggleByteOrder Get8u Get8s Get16u
44
45
  Get16s Get32u Get32s Get64u GetFloat GetDouble GetFixed32s Write
45
- WriteValue Tell Set8u Set8s Set16u Set32u Set64u
46
+ WriteValue Tell Set8u Set8s Set16u Set32u Set64u Set64s
46
47
  )],
47
48
  Utils => [qw(GetTagTable TagTableKeys GetTagInfoList AddTagToTable HexDump)],
48
49
  Vars => [qw(%allTables @tableOrder @fileTypes)],
@@ -70,7 +71,7 @@ sub SetFileName($$;$$$);
70
71
  sub SetSystemTags($$);
71
72
  sub GetAllTags(;$);
72
73
  sub GetWritableTags(;$);
73
- sub GetAllGroups($);
74
+ sub GetAllGroups($;$);
74
75
  sub GetNewGroups($);
75
76
  sub GetDeleteGroups();
76
77
  sub AddUserDefinedTags($%);
@@ -89,6 +90,7 @@ sub Get64u($$);
89
90
  sub GetFixed64s($$);
90
91
  sub GetExtended($$);
91
92
  sub Set64u(@);
93
+ sub Set64s(@);
92
94
  sub DecodeBits($$;$);
93
95
  sub EncodeBits($$;$$);
94
96
  sub Filter($$$);
@@ -137,18 +139,18 @@ sub ReadValue($$$;$$$);
137
139
  @loadAllTables = qw(
138
140
  PhotoMechanic Exif GeoTiff CanonRaw KyoceraRaw Lytro MinoltaRaw PanasonicRaw
139
141
  SigmaRaw JPEG GIMP Jpeg2000 GIF BMP BMP::OS2 BMP::Extra BPG BPG::Extensions
140
- PICT PNG MNG FLIF DjVu DPX OpenEXR ZISRAW MIFF PCX PGF 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',
@@ -798,6 +812,7 @@ my %moduleName = (
798
812
  DSS => 'Olympus',
799
813
  DWF => 0,
800
814
  DWG => 0,
815
+ DXF => 0,
801
816
  EPS => 'PostScript',
802
817
  EXIF => '',
803
818
  EXR => 'OpenEXR',
@@ -811,6 +826,7 @@ my %moduleName = (
811
826
  HDR => 'Radiance',
812
827
  JP2 => 'Jpeg2000',
813
828
  JPEG => '',
829
+ JXL => 'Jpeg2000',
814
830
  LFP => 'Lytro',
815
831
  LRI => 0,
816
832
  MOV => 'QuickTime',
@@ -821,6 +837,7 @@ my %moduleName = (
821
837
  ORF => 'Olympus',
822
838
  PDB => 'Palm',
823
839
  PCD => 'PhotoCD',
840
+ PFM2 => 'Other',
824
841
  PHP => 0,
825
842
  PMP => 'Sony',
826
843
  PS => 'PostScript',
@@ -872,6 +889,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
872
889
  DV => '\x1f\x07\0[\x3f\xbf]', # (not tested if extension recognized)
873
890
  DWF => '\(DWF V\d',
874
891
  DWG => 'AC10\d{2}\0',
892
+ DXF => '\s*0\s+\0?\s*SECTION\s+2\s+HEADER',
875
893
  EPS => '(%!PS|%!Ad|\xc5\xd0\xd3\xc6)',
876
894
  EXE => '(MZ|\xca\xfe\xba\xbe|\xfe\xed\xfa[\xce\xcf]|[\xce\xcf]\xfa\xed\xfe|Joy!peff|\x7fELF|#!\s*/\S*bin/|!<arch>\x0a)',
877
895
  EXIF => '(II\x2a\0|MM\0\x2a)',
@@ -897,7 +915,9 @@ $testLen = 1024; # number of bytes to read when testing for magic number
897
915
  JP2 => '(\0\0\0\x0cjP( |\x1a\x1a)\x0d\x0a\x87\x0a|\xff\x4f\xff\x51\0)',
898
916
  JPEG => '\xff\xd8\xff',
899
917
  JSON => '(\xef\xbb\xbf)?\s*(\[\s*)?\{\s*"[^"]*"\s*:',
918
+ JXL => '\xff\x0a|\0\0\0\x0cJXL \x0d\x0a......ftypjxl ',
900
919
  LFP => '\x89LFP\x0d\x0a\x1a\x0a',
920
+ LIF => '\x70\0{3}.{4}\x2a.{4}<\0',
901
921
  LNK => '.{4}\x01\x14\x02\0{5}\xc0\0{6}\x46',
902
922
  LRI => 'LELR \0',
903
923
  M2TS => '(....)?\x47',
@@ -909,14 +929,16 @@ $testLen = 1024; # number of bytes to read when testing for magic number
909
929
  MPC => '(MP\+|ID3)',
910
930
  MOI => 'V6',
911
931
  MPEG => '\0\0\x01[\xb0-\xbf]',
932
+ MRC => '.{64}[\x01\x02\x03]\0\0\0[\x01\x02\x03]\0\0\0[\x01\x02\x03]\0\0\0.{132}MAP[\0 ](\x44\x44|\x44\x41|\x11\x11)\0\0',
912
933
  MRW => '\0MR[MI]',
913
934
  MXF => '\x06\x0e\x2b\x34\x02\x05\x01\x01\x0d\x01\x02', # (not tested if extension recognized)
914
935
  OGG => '(OggS|ID3)',
915
936
  ORF => '(II|MM)',
916
- PDB => '.{60}(\.pdfADBE|TEXtREAd|BVokBDIC|DB99DBOS|PNRdPPrs|DataPPrs|vIMGView|PmDBPmDB|InfoINDB|ToGoToGo|SDocSilX|JbDbJBas|JfDbJFil|DATALSdb|Mdb1Mdb1|BOOKMOBI|DataPlkr|DataSprd|SM01SMem|TEXtTlDc|InfoTlIf|DataTlMl|DataTlPt|dataTDBP|TdatTide|ToRaTRPW|zTXTGPlm|BDOCWrdS)',
917
937
  # PCD => signature is at byte 2048
918
938
  PCX => '\x0a[\0-\x05]\x01[\x01\x02\x04\x08].{64}[\0-\x02]',
939
+ PDB => '.{60}(\.pdfADBE|TEXtREAd|BVokBDIC|DB99DBOS|PNRdPPrs|DataPPrs|vIMGView|PmDBPmDB|InfoINDB|ToGoToGo|SDocSilX|JbDbJBas|JfDbJFil|DATALSdb|Mdb1Mdb1|BOOKMOBI|DataPlkr|DataSprd|SM01SMem|TEXtTlDc|InfoTlIf|DataTlMl|DataTlPt|dataTDBP|TdatTide|ToRaTRPW|zTXTGPlm|BDOCWrdS)',
919
940
  PDF => '\s*%PDF-\d+\.\d+',
941
+ PFM => 'P[Ff]\x0a\d+ \d+\x0a[-+0-9.]+\x0a',
920
942
  PGF => 'PGF',
921
943
  PHP => '<\?php\s',
922
944
  PICT => '(.{10}|.{522})(\x11\x01|\x00\x11)',
@@ -1129,6 +1151,13 @@ my %systemTagsNotes = (
1129
1151
  RawConv => '$self->ConvertFileName($val)',
1130
1152
  ValueConvInv => '$self->InverseFileName($val)',
1131
1153
  },
1154
+ BaseName => {
1155
+ Groups => { 1 => 'System', 2 => 'Other' },
1156
+ Notes => q{
1157
+ file name without extension. Not generated unless specifically requested or
1158
+ the L<RequestAll|../ExifTool.html#RequestAll> API option is set
1159
+ },
1160
+ },
1132
1161
  FilePath => {
1133
1162
  Groups => { 1 => 'System', 2 => 'Other' },
1134
1163
  Notes => q{
@@ -1270,10 +1299,19 @@ my %systemTagsNotes = (
1270
1299
  WritePseudo => 1,
1271
1300
  DelCheck => q{"Can't delete"},
1272
1301
  Protected => 1, # all writable pseudo-tags must be protected!
1273
- ValueConv => 'sprintf("%.3o", $val & 0777)',
1274
- ValueConvInv => 'oct($val)',
1302
+ ValueConv => 'sprintf("%.3o", $val)',
1303
+ ValueConvInv => 'oct($val & 07777)',
1275
1304
  PrintConv => sub {
1276
- my ($mask, $str, $val) = (0400, '', oct(shift));
1305
+ my ($mask, $val) = (0400, oct(shift));
1306
+ my %types = (
1307
+ 0010000 => 'p',
1308
+ 0020000 => 'c',
1309
+ 0040000 => 'd',
1310
+ 0060000 => 'b',
1311
+ 0120000 => 'l',
1312
+ 0140000 => 's',
1313
+ );
1314
+ my $str = $types{$val & 0170000} || '-';
1277
1315
  while ($mask) {
1278
1316
  foreach (qw(r w x)) {
1279
1317
  $str .= $val & $mask ? $_ : '-';
@@ -1284,6 +1322,7 @@ my %systemTagsNotes = (
1284
1322
  },
1285
1323
  PrintConvInv => sub {
1286
1324
  my ($bit, $val, $str) = (8, 0, shift);
1325
+ $str = substr($str, 1) if length($str) == 10;
1287
1326
  return undef if length($str) != 9;
1288
1327
  while ($bit >= 0) {
1289
1328
  foreach (qw(r w x)) {
@@ -1737,7 +1776,10 @@ my %systemTagsNotes = (
1737
1776
  EmbeddedVideo => { Groups => { 0 => 'Trailer', 2 => 'Video' } },
1738
1777
  Trailer => {
1739
1778
  Groups => { 0 => 'Trailer' },
1740
- Notes => 'the full JPEG trailer data block. Extracted only if specifically requested',
1779
+ Notes => q{
1780
+ the full JPEG trailer data block. Extracted only if specifically requested
1781
+ or the RequestAll API option is set to 3 or higher
1782
+ },
1741
1783
  Writable => 1,
1742
1784
  Protected => 1,
1743
1785
  },
@@ -1898,6 +1940,8 @@ my %systemTagsNotes = (
1898
1940
  return \$img;
1899
1941
  },
1900
1942
  },
1943
+ # Apple may add "AMPF" to the end of the JFIF record,
1944
+ # possibly indicating the existence of MPF images (ref forum12677)
1901
1945
  );
1902
1946
 
1903
1947
  # Composite tags (accumulation of all Composite tag tables)
@@ -2050,12 +2094,15 @@ sub Options($$;@)
2050
2094
  $$options{$param} = $newVal;
2051
2095
  delete $$self{CUR_LANG};
2052
2096
  # make sure the language is available
2053
- } 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;
2097
+ } else {
2098
+ my %langs = map { $_ => 1 } @langs;
2099
+ if ($langs{$newVal} and eval "require Image::ExifTool::Lang::$newVal") {
2100
+ my $xlat = "Image::ExifTool::Lang::${newVal}::Translate";
2101
+ no strict 'refs';
2102
+ if (%$xlat) {
2103
+ $$self{CUR_LANG} = \%$xlat;
2104
+ $$options{$param} = $newVal;
2105
+ }
2059
2106
  }
2060
2107
  } # else don't change Lang
2061
2108
  } elsif ($param eq 'Exclude' and defined $newVal) {
@@ -2271,7 +2318,7 @@ sub ClearOptions($)
2271
2318
  NoPDFList => undef, # flag to avoid splitting PDF List-type tag values
2272
2319
  Password => undef, # password for password-protected PDF documents
2273
2320
  PrintConv => 1, # flag to enable print conversion
2274
- QuickTimeHandler => undef, # flag to add mdir Handler to newly created Meta box
2321
+ QuickTimeHandler => 1, # flag to add mdir Handler to newly created Meta box
2275
2322
  QuickTimeUTC=> undef, # assume that QuickTime date/time tags are stored as UTC
2276
2323
  RequestAll => undef, # extract all tags that must be specifically requested
2277
2324
  RequestTags => undef, # extra tags to request (on top of those in the tag list)
@@ -2321,7 +2368,7 @@ sub ExtractInfo($;@)
2321
2368
  my $fast = $$options{FastScan} || 0;
2322
2369
  my $req = $$self{REQ_TAG_LOOKUP};
2323
2370
  my $reqAll = $$options{RequestAll} || 0;
2324
- my (%saveOptions, $reEntry, $rsize, $type, @startTime, $saveOrder);
2371
+ my (%saveOptions, $reEntry, $rsize, $type, @startTime, $saveOrder, $isDir);
2325
2372
 
2326
2373
  # check for internal ReEntry option to allow recursive calls to ExtractInfo
2327
2374
  if (ref $_[1] eq 'HASH' and $_[1]{ReEntry} and
@@ -2394,6 +2441,11 @@ sub ExtractInfo($;@)
2394
2441
  $realname =~ /\|$/ and $realname =~ s/^.*?"(.*?)".*/$1/s;
2395
2442
  my ($dir, $name) = SplitFileName($realname);
2396
2443
  $self->FoundTag('FileName', $name);
2444
+ if ($$req{basename} or
2445
+ ($reqAll and not $$self{EXCL_TAG_LOOKUP}{basename}))
2446
+ {
2447
+ $self->FoundTag('BaseName', $name =~ /(.*)\./ ? $1 : $name);
2448
+ }
2397
2449
  $self->FoundTag('Directory', $dir) if defined $dir and length $dir;
2398
2450
  if ($$req{filepath} or
2399
2451
  ($reqAll and not $$self{EXCL_TAG_LOOKUP}{filepath}))
@@ -2417,6 +2469,8 @@ sub ExtractInfo($;@)
2417
2469
  # in Windows cmd shell pipe even though it really failed
2418
2470
  $$raf{TESTED} = -1 if $filename eq '-' or $filename =~ /\|$/;
2419
2471
  $$self{RAF} = $raf;
2472
+ } elsif ($self->IsDirectory($filename)) {
2473
+ $isDir = 1;
2420
2474
  } else {
2421
2475
  $self->Error('Error opening file');
2422
2476
  }
@@ -2425,28 +2479,34 @@ sub ExtractInfo($;@)
2425
2479
  }
2426
2480
  }
2427
2481
 
2428
- while ($raf) {
2429
- my (@stat, $fileSize);
2482
+ while ($raf or $isDir) {
2483
+ my (@stat, $plainFile);
2430
2484
  if ($reEntry) {
2431
2485
  # we already set these tags
2486
+ } elsif (not $raf) {
2487
+ @stat = stat $filename;
2432
2488
  } elsif (not $$raf{FILE_PT}) {
2433
2489
  # get file size from image in memory
2434
2490
  $self->FoundTag('FileSize', length ${$$raf{BUFF_PT}});
2435
2491
  } elsif (-f $$raf{FILE_PT}) {
2436
2492
  # get file tags if this is a plain file
2437
- $fileSize = -s _;
2438
2493
  @stat = stat _;
2439
- 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];
2494
+ $plainFile = 1;
2495
+ # hack to patch Windows daylight savings time bug
2496
+ @stat[8,9,10] = $self->GetFileTime($$raf{FILE_PT}) if $^O eq 'MSWin32';
2447
2497
  } else {
2498
+ # (note that Windows directories will still show the
2499
+ # daylight savings time bug -- should fix this sometime)
2448
2500
  @stat = stat $$raf{FILE_PT};
2449
2501
  }
2502
+ my $fileSize = $stat[7];
2503
+ $self->FoundTag('FileSize', $stat[7]) if defined $stat[7];
2504
+ $self->FoundTag('ResourceForkSize', $rsize) if $rsize;
2505
+ $self->FoundTag('FileModifyDate', $stat[9]) if defined $stat[9];
2506
+ $self->FoundTag('FileAccessDate', $stat[8]) if defined $stat[8];
2507
+ my $cTag = $^O eq 'MSWin32' ? 'FileCreateDate' : 'FileInodeChangeDate';
2508
+ $self->FoundTag($cTag, $stat[10]) if defined $stat[10];
2509
+ $self->FoundTag('FilePermissions', $stat[2]) if defined $stat[2];
2450
2510
  # extract more system info if SystemTags option is set
2451
2511
  if (@stat) {
2452
2512
  my $sys = $$options{SystemTags} || ($reqAll and not defined $$options{SystemTags});
@@ -2486,11 +2546,18 @@ sub ExtractInfo($;@)
2486
2546
  if ($crDate or $mdItem or $xattr) {
2487
2547
  require Image::ExifTool::MacOS;
2488
2548
  Image::ExifTool::MacOS::GetFileCreateDate($self, $filename) if $crDate;
2489
- Image::ExifTool::MacOS::ExtractMDItemTags($self, $filename) if $mdItem;
2549
+ Image::ExifTool::MacOS::ExtractMDItemTags($self, $filename) if $mdItem and $plainFile;
2490
2550
  Image::ExifTool::MacOS::ExtractXAttrTags($self, $filename) if $xattr;
2491
2551
  }
2492
2552
  }
2493
-
2553
+ # do whatever else we can with directories, then return
2554
+ if ($isDir or (defined $stat[2] and ($stat[2] & 0170000) == 0040000)) {
2555
+ $self->FoundTag('FileType', 'DIR');
2556
+ $self->FoundTag('FileTypeExtension', '');
2557
+ $self->BuildCompositeTags() if $$options{Composite};
2558
+ $raf->Close() if $raf;
2559
+ return 1;
2560
+ }
2494
2561
  # get list of file types to check
2495
2562
  my ($tiffType, %noMagic, $recognizedExt);
2496
2563
  my $ext = $$self{FILE_EXT} = GetFileExtension($realname);
@@ -3250,8 +3317,9 @@ sub GetTagID($$)
3250
3317
  my ($self, $tag) = @_;
3251
3318
  my $tagInfo = $$self{TAG_INFO}{$tag};
3252
3319
  return '' unless $tagInfo and defined $$tagInfo{TagID};
3253
- return ($$tagInfo{TagID}, $$tagInfo{LangCode}) if wantarray;
3254
- return $$tagInfo{TagID};
3320
+ my $id = $$tagInfo{KeysID} || $$tagInfo{TagID};
3321
+ return ($id, $$tagInfo{LangCode}) if wantarray;
3322
+ return $id;
3255
3323
  }
3256
3324
 
3257
3325
  #------------------------------------------------------------------------------
@@ -3367,7 +3435,7 @@ sub GetGroup($$;$)
3367
3435
  }
3368
3436
  # generate tag ID group names unless obviously not needed
3369
3437
  unless ($noID) {
3370
- my $id = $$tagInfo{TagID};
3438
+ my $id = $$tagInfo{KeysID} || $$tagInfo{TagID};
3371
3439
  if (not defined $id) {
3372
3440
  $id = ''; # (just to be safe)
3373
3441
  } elsif ($id =~ /^\d+$/) {
@@ -3722,7 +3790,15 @@ sub GetFileType(;$$)
3722
3790
  # return description if specified
3723
3791
  # (allow input $file to be a FileType for this purpose)
3724
3792
  if ($desc) {
3725
- $desc = $fileType ? $$fileType[1] : $fileDescription{$file};
3793
+ if ($fileType) {
3794
+ if ($static_vars{OverrideFileDescription} and $static_vars{OverrideFileDescription}{$fileExt}) {
3795
+ $desc = $static_vars{OverrideFileDescription}{$fileExt};
3796
+ } else {
3797
+ $desc = $$fileType[1];
3798
+ }
3799
+ } else {
3800
+ $desc = $fileDescription{$file};
3801
+ }
3726
3802
  $desc .= ", $subType" if $subType;
3727
3803
  return $desc;
3728
3804
  } elsif ($fileType and (not defined $desc or $desc ne '0')) {
@@ -3787,6 +3863,7 @@ sub Init($)
3787
3863
  foreach (keys %$self) {
3788
3864
  /[a-z]/ and delete $$self{$_};
3789
3865
  }
3866
+ undef %static_vars; # clear all static variables
3790
3867
  delete $$self{FOUND_TAGS}; # list of found tags
3791
3868
  delete $$self{EXIF_DATA}; # the EXIF data block
3792
3869
  delete $$self{EXIF_POS}; # EXIF position in file
@@ -4044,7 +4121,9 @@ sub Exists($$)
4044
4121
  return 0 unless $wh;
4045
4122
  eval { Win32API::File::CloseHandle($wh) };
4046
4123
  } else {
4047
- return -e $file;
4124
+ # (named pipes already exist, but we pretend that they don't
4125
+ # so we will be able to write them, so test with for pipe -p)
4126
+ return(-e $file and not -p $file);
4048
4127
  }
4049
4128
  return 1;
4050
4129
  }
@@ -4079,7 +4158,14 @@ sub GetFileTime($$)
4079
4158
  # open file by name if necessary
4080
4159
  unless (ref $file) {
4081
4160
  local *FH;
4082
- $self->Open(\*FH, $file) or $self->Warn("GetFileTime error for '${file}'"), return ();
4161
+ unless ($self->Open(\*FH, $file)) {
4162
+ if ($self->IsDirectory($file)) {
4163
+ my @rtn = (stat $file)[8, 9, 10];
4164
+ return @rtn if defined $rtn[0];
4165
+ }
4166
+ $self->Warn("GetFileTime error for '${file}'");
4167
+ return ();
4168
+ }
4083
4169
  $file = *FH; # (not \*FH, so *FH will be kept open until $file goes out of scope)
4084
4170
  }
4085
4171
  # on Windows, try to work around incorrect file times when daylight saving time is in effect
@@ -5710,7 +5796,11 @@ sub GetUnixTime($;$)
5710
5796
  my ($timeStr, $isLocal) = @_;
5711
5797
  return 0 if $timeStr eq '0000:00:00 00:00:00';
5712
5798
  my @tm = ($timeStr =~ /^(\d+):(\d+):(\d+)\s+(\d+):(\d+):(\d+)(.*)/);
5713
- return undef unless @tm == 7 and eval { require Time::Local };
5799
+ return undef unless @tm == 7;
5800
+ unless (eval { require Time::Local }) {
5801
+ warn "Time::Local is not installed\n";
5802
+ return undef;
5803
+ }
5714
5804
  my ($tzStr, $tzSec) = (pop(@tm), 0);
5715
5805
  # use specified timezone offset (if given) instead of local system time
5716
5806
  # if we are converting a local time value
@@ -5908,7 +5998,7 @@ sub ProcessTrailers($$)
5908
5998
  for (;;) { # loop through all trailers
5909
5999
  my ($proc, $outBuff);
5910
6000
  if ($dirName eq 'Insta360') {
5911
- require "Image/ExifTool/QuickTimeStream.pl";
6001
+ require 'Image/ExifTool/QuickTimeStream.pl';
5912
6002
  $proc = 'Image::ExifTool::QuickTime::ProcessInsta360';
5913
6003
  } else {
5914
6004
  require "Image/ExifTool/$dirName.pm";
@@ -6070,9 +6160,10 @@ sub ProcessJPEG($$)
6070
6160
  my $out = $$options{TextOut};
6071
6161
  my $fast = $$options{FastScan} || 0;
6072
6162
  my $raf = $$dirInfo{RAF};
6163
+ my $req = $$self{REQ_TAG_LOOKUP};
6073
6164
  my $htmlDump = $$self{HTML_DUMP};
6074
6165
  my %dumpParms = ( Out => $out );
6075
- my ($success, $wantTrailer, $trailInfo, $foundSOS);
6166
+ my ($success, $wantTrailer, $trailInfo, $foundSOS, %jumbfChunk);
6076
6167
  my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $flirTotal);
6077
6168
  my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP);
6078
6169
 
@@ -6083,7 +6174,7 @@ sub ProcessJPEG($$)
6083
6174
  $$self{FILE_TYPE} = 'EXV';
6084
6175
  }
6085
6176
  my $appBytes = 0;
6086
- my $calcImageLen = $$self{REQ_TAG_LOOKUP}{jpegimagelength};
6177
+ my $calcImageLen = $$req{jpegimagelength};
6087
6178
  if ($$options{RequestAll} and $$options{RequestAll} > 2) {
6088
6179
  $calcImageLen = 1;
6089
6180
  }
@@ -6116,6 +6207,7 @@ sub ProcessJPEG($$)
6116
6207
  my $marker = $nextMarker;
6117
6208
  my $segDataPt = $nextSegDataPt;
6118
6209
  my $segPos = $nextSegPos;
6210
+ my $skipped;
6119
6211
  undef $nextMarker;
6120
6212
  undef $nextSegDataPt;
6121
6213
  #
@@ -6125,11 +6217,13 @@ sub ProcessJPEG($$)
6125
6217
  # read up to next marker (JPEG markers begin with 0xff)
6126
6218
  my $buff;
6127
6219
  $raf->ReadLine($buff) or last;
6220
+ $skipped = length($buff) - 1;
6128
6221
  # JPEG markers can be padded with unlimited 0xff's
6129
6222
  for (;;) {
6130
6223
  $raf->Read($ch, 1) or last Marker;
6131
6224
  $nextMarker = ord($ch);
6132
6225
  last unless $nextMarker == 0xff;
6226
+ ++$skipped;
6133
6227
  }
6134
6228
  # read segment data if it exists
6135
6229
  if (not defined $markerLenBytes{$nextMarker}) {
@@ -6156,6 +6250,14 @@ sub ProcessJPEG($$)
6156
6250
  # set some useful variables for the current segment
6157
6251
  my $markerName = JpegMarkerName($marker);
6158
6252
  $$path[$pn] = $markerName;
6253
+ # issue warning if we skipped some garbage
6254
+ if ($skipped and not $foundSOS) {
6255
+ $self->Warn("Skipped unknown $skipped bytes after JPEG $markerName segment", 1);
6256
+ if ($htmlDump) {
6257
+ $self->HDump($nextSegPos-4-$skipped, $skipped, "[unknown $skipped bytes]", undef, 0x08);
6258
+ $dumpEnd = $nextSegPos - 4;
6259
+ }
6260
+ }
6159
6261
  #
6160
6262
  # parse the current segment
6161
6263
  #
@@ -6217,7 +6319,7 @@ sub ProcessJPEG($$)
6217
6319
  } else {
6218
6320
  $self->Warn('Missing JPEG SOS');
6219
6321
  }
6220
- if ($$self{REQ_TAG_LOOKUP}{trailer}) {
6322
+ if ($$req{trailer}) {
6221
6323
  # read entire trailer into memory
6222
6324
  if ($raf->Seek(0,2)) {
6223
6325
  my $len = $raf->Tell() - $pos;
@@ -6351,7 +6453,7 @@ sub ProcessJPEG($$)
6351
6453
  next if $trailInfo or $wantTrailer or $verbose > 2 or $htmlDump;
6352
6454
  }
6353
6455
  # must scan to EOI if Validate or JpegCompressionFactor used
6354
- next if $$options{Validate} or $calcImageLen or $$self{REQ_TAG_LOOKUP}{trailer};
6456
+ next if $$options{Validate} or $calcImageLen or $$req{trailer};
6355
6457
  # nothing interesting to parse after start of scan (SOS)
6356
6458
  $success = 1;
6357
6459
  last; # all done parsing file
@@ -6371,7 +6473,7 @@ sub ProcessJPEG($$)
6371
6473
  # must use the RequestTags option to generate these tags if they have not been
6372
6474
  # specifically requested. The reason is that there is too much overhead involved
6373
6475
  # in the calculation of this tag to make this worth the CPU time.)
6374
- ($$self{REQ_TAG_LOOKUP}{jpegdigest} or $$self{REQ_TAG_LOOKUP}{jpegqualityestimate}
6476
+ ($$req{jpegdigest} or $$req{jpegqualityestimate}
6375
6477
  or ($$options{RequestAll} and $$options{RequestAll} > 2)))
6376
6478
  {
6377
6479
  my $num = unpack('C',$$segDataPt) & 0x0f; # get table index
@@ -6489,7 +6591,7 @@ sub ProcessJPEG($$)
6489
6591
  }
6490
6592
  if ($start and $plen and IsInt($start) and IsInt($plen) and
6491
6593
  $start + $plen > $$self{EXIF_POS} + length($$self{EXIF_DATA}) and
6492
- ($$self{REQ_TAG_LOOKUP}{previewimage} or
6594
+ ($$req{previewimage} or
6493
6595
  # (extracted normally, so check Binary option)
6494
6596
  ($$options{Binary} and not $$self{EXCL_TAG_LOOKUP}{previewimage})))
6495
6597
  {
@@ -6695,6 +6797,12 @@ sub ProcessJPEG($$)
6695
6797
  # extract the Stim information (it is in standard TIFF format)
6696
6798
  my $tagTablePtr = GetTagTable('Image::ExifTool::Stim::Main');
6697
6799
  $self->ProcessTIFF(\%dirInfo, $tagTablePtr);
6800
+ } elsif ($$segDataPt =~ /^_JPSJPS_/) {
6801
+ $dumpType = 'JPS';
6802
+ $self->OverrideFileType('JPS') if $$self{FILE_TYPE} eq 'JPEG';
6803
+ SetByteOrder('MM');
6804
+ my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::JPS');
6805
+ $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
6698
6806
  } elsif ($$self{Make} eq 'DJI') {
6699
6807
  $dumpType = 'DJI ThermalData';
6700
6808
  # add this data to the combined data if it exists
@@ -6884,7 +6992,7 @@ sub ProcessJPEG($$)
6884
6992
  # (with number of elements N = ImageHeight / 16 - 1, ref PH/NealKrawetz)
6885
6993
  $xtra = 'segment (N=' . unpack('x6N', $$segDataPt) . ')';
6886
6994
  }
6887
- } elsif ($marker == 0xeb) { # APP11 (JPEG-HDR)
6995
+ } elsif ($marker == 0xeb) { # APP11 (JPEG-HDR, JUMBF)
6888
6996
  if ($$segDataPt =~ /^HDR_RI /) {
6889
6997
  $dumpType = 'JPEG-HDR';
6890
6998
  my $dataPt = $segDataPt;
@@ -6904,6 +7012,47 @@ sub ProcessJPEG($$)
6904
7012
  $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
6905
7013
  undef $combinedSegData;
6906
7014
  }
7015
+ } elsif ($$segDataPt =~ /^(JP..)/s and length($$segDataPt) >= 16) {
7016
+ # JUMBF extension marker
7017
+ my $hdr = $1;
7018
+ $dumpType = 'JUMBF';
7019
+ SetByteOrder('MM');
7020
+ my $seq = Get32u($segDataPt, 4) - 1; # (start from 0)
7021
+ my $len = Get32u($segDataPt, 8);
7022
+ my $type = substr($$segDataPt, 12, 4);
7023
+ my $hdrLen;
7024
+ if ($len == 1 and length($$segDataPt) >= 24) {
7025
+ $len = Get64u($$segDataPt, 16);
7026
+ $hdrLen = 16;
7027
+ } else {
7028
+ $hdrLen = 8;
7029
+ }
7030
+ $jumbfChunk{$type} or $jumbfChunk{$type} = [ ];
7031
+ if ($len < $hdrLen) {
7032
+ $self->Warn('Invalid JUMBF segment');
7033
+ } elsif ($seq < 0) {
7034
+ $self->Warn('Invalid JUMBF sequence number');
7035
+ } elsif (defined $jumbfChunk{$type}[$seq]) {
7036
+ $self->Warn('Duplicate JUMBF sequence number');
7037
+ } else {
7038
+ # add to list of JUMBF chunks
7039
+ $jumbfChunk{$type}[$seq] = substr($$segDataPt, 8 + $hdrLen);
7040
+ # check to see if we have a complete JUMBF box
7041
+ my $size = $hdrLen;
7042
+ foreach (@{$jumbfChunk{$type}}) {
7043
+ defined $_ or $size = 0, last;
7044
+ $size += length $_;
7045
+ }
7046
+ if ($size == $len) {
7047
+ my $buff = join '', substr($$segDataPt,8,$hdrLen), @{$jumbfChunk{$type}};
7048
+ $dirInfo{DataPt} = \$buff;
7049
+ $dirInfo{DataPos} = $segPos + 8; # (shows correct offsets for single-segment JUMBF)
7050
+ $dirInfo{DataLen} = $dirInfo{DirLen} = $size;
7051
+ my $tagTablePtr = GetTagTable('Image::ExifTool::Jpeg2000::Main');
7052
+ $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
7053
+ delete $jumbfChunk{$type};
7054
+ }
7055
+ }
6907
7056
  }
6908
7057
  } elsif ($marker == 0xec) { # APP12 (Ducky, Picture Info)
6909
7058
  if ($$segDataPt =~ /^Ducky/) {
@@ -6955,7 +7104,7 @@ sub ProcessJPEG($$)
6955
7104
  } elsif ($marker == 0xee) { # APP14 (Adobe)
6956
7105
  if ($$segDataPt =~ /^Adobe/) {
6957
7106
  # extract as a block if requested, or if copying tags from file
6958
- if ($$self{REQ_TAG_LOOKUP}{adobe} or
7107
+ if ($$req{adobe} or
6959
7108
  # (not extracted normally, so check TAGS_FROM_FILE)
6960
7109
  ($$self{TAGS_FROM_FILE} and not $$self{EXCL_TAG_LOOKUP}{adobe}))
6961
7110
  {
@@ -7058,6 +7207,7 @@ sub ProcessJPEG($$)
7058
7207
  Image::ExifTool::JPEGDigest::Calculate($self, \@dqt, $subSampling);
7059
7208
  }
7060
7209
  # issue necessary warnings
7210
+ $self->Warn('Invalid JUMBF size or missing JUMBF chunk') if %jumbfChunk;
7061
7211
  $self->Warn('Incomplete ICC_Profile record', 1) if defined $iccChunkCount;
7062
7212
  $self->Warn('Incomplete FLIR record', 1) if defined $flirCount;
7063
7213
  $self->Warn('Error reading PreviewImage', 1) if $$self{PreviewError};
@@ -7726,7 +7876,8 @@ sub GetTagInfo($$$;$$$)
7726
7876
  }
7727
7877
  }
7728
7878
  if ($$tagInfo{Unknown} and not $$self{OPTIONS}{Unknown} and
7729
- not $$self{OPTIONS}{Verbose} and not $$self{HTML_DUMP})
7879
+ not $$self{OPTIONS}{Verbose} and not $$self{OPTIONS}{Validate} and
7880
+ not $$self{HTML_DUMP})
7730
7881
  {
7731
7882
  # don't return Unknown tags unless that option is set
7732
7883
  return undef;