exiftool-vendored.exe 12.60.0 → 12.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +254 -254
  2. package/bin/exiftool_files/Changes +110 -0
  3. package/bin/exiftool_files/LICENSE +674 -0
  4. package/bin/exiftool_files/Makefile.PL +7 -1
  5. package/bin/exiftool_files/README +50 -45
  6. package/bin/exiftool_files/config_files/guano.config +161 -0
  7. package/bin/exiftool_files/exiftool.pl +162 -104
  8. package/bin/exiftool_files/lib/Image/ExifTool/7Z.pm +793 -0
  9. package/bin/exiftool_files/lib/Image/ExifTool/Apple.pm +14 -7
  10. package/bin/exiftool_files/lib/Image/ExifTool/BMP.pm +0 -1
  11. package/bin/exiftool_files/lib/Image/ExifTool/BigTIFF.pm +8 -1
  12. package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +4 -4
  13. package/bin/exiftool_files/lib/Image/ExifTool/Canon.pm +4 -1
  14. package/bin/exiftool_files/lib/Image/ExifTool/CanonRaw.pm +4 -4
  15. package/bin/exiftool_files/lib/Image/ExifTool/CanonVRD.pm +4 -1
  16. package/bin/exiftool_files/lib/Image/ExifTool/Exif.pm +31 -14
  17. package/bin/exiftool_files/lib/Image/ExifTool/FlashPix.pm +9 -2
  18. package/bin/exiftool_files/lib/Image/ExifTool/FujiFilm.pm +3 -3
  19. package/bin/exiftool_files/lib/Image/ExifTool/GPS.pm +5 -2
  20. package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +4 -1
  21. package/bin/exiftool_files/lib/Image/ExifTool/Jpeg2000.pm +243 -20
  22. package/bin/exiftool_files/lib/Image/ExifTool/Lang/fr.pm +1467 -202
  23. package/bin/exiftool_files/lib/Image/ExifTool/MPF.pm +2 -1
  24. package/bin/exiftool_files/lib/Image/ExifTool/Matroska.pm +16 -1
  25. package/bin/exiftool_files/lib/Image/ExifTool/MinoltaRaw.pm +2 -2
  26. package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +941 -33
  27. package/bin/exiftool_files/lib/Image/ExifTool/NikonCustom.pm +874 -63
  28. package/bin/exiftool_files/lib/Image/ExifTool/PDF.pm +39 -12
  29. package/bin/exiftool_files/lib/Image/ExifTool/PLIST.pm +8 -1
  30. package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +6 -6
  31. package/bin/exiftool_files/lib/Image/ExifTool/PhaseOne.pm +5 -5
  32. package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +96 -32
  33. package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +68 -37
  34. package/bin/exiftool_files/lib/Image/ExifTool/README +2 -2
  35. package/bin/exiftool_files/lib/Image/ExifTool/RIFF.pm +11 -9
  36. package/bin/exiftool_files/lib/Image/ExifTool/Samsung.pm +227 -227
  37. package/bin/exiftool_files/lib/Image/ExifTool/Shortcuts.pm +2 -1
  38. package/bin/exiftool_files/lib/Image/ExifTool/SigmaRaw.pm +4 -4
  39. package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +237 -32
  40. package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +4762 -4629
  41. package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +737 -20
  42. package/bin/exiftool_files/lib/Image/ExifTool/Validate.pm +17 -1
  43. package/bin/exiftool_files/lib/Image/ExifTool/WPG.pm +296 -0
  44. package/bin/exiftool_files/lib/Image/ExifTool/WriteExif.pl +9 -7
  45. package/bin/exiftool_files/lib/Image/ExifTool/WritePDF.pl +7 -8
  46. package/bin/exiftool_files/lib/Image/ExifTool/WriteQuickTime.pl +21 -9
  47. package/bin/exiftool_files/lib/Image/ExifTool/WriteXMP.pl +2 -2
  48. package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +47 -16
  49. package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +30 -6
  50. package/bin/exiftool_files/lib/Image/ExifTool/XMP2.pl +32 -0
  51. package/bin/exiftool_files/lib/Image/ExifTool/XMPStruct.pl +96 -28
  52. package/bin/exiftool_files/lib/Image/ExifTool/ZIP.pm +159 -41
  53. package/bin/exiftool_files/lib/Image/ExifTool.pm +280 -164
  54. package/bin/exiftool_files/lib/Image/ExifTool.pod +117 -52
  55. package/package.json +3 -2
@@ -29,7 +29,7 @@ use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes
29
29
  %jpegMarker %specialTags %fileTypeLookup $testLen $exeDir
30
30
  %static_vars);
31
31
 
32
- $VERSION = '12.60';
32
+ $VERSION = '12.65';
33
33
  $RELEASE = '';
34
34
  @ISA = qw(Exporter);
35
35
  %EXPORT_TAGS = (
@@ -114,7 +114,7 @@ sub WriteTIFF($$$);
114
114
  sub PackUTF8(@);
115
115
  sub UnpackUTF8($);
116
116
  sub SetPreferredByteOrder($;$);
117
- sub ImageDataMD5($$$;$$);
117
+ sub ImageDataHash($$$;$$);
118
118
  sub CopyBlock($$$);
119
119
  sub CopyFileAttrs($$$);
120
120
  sub TimeNow(;$$);
@@ -126,7 +126,7 @@ sub MakeTiffHeader($$$$;$$);
126
126
  sub SplitFileName($);
127
127
  sub EncodeFileName($$;$);
128
128
  sub Open($*$;$);
129
- sub Exists($$);
129
+ sub Exists($$;$);
130
130
  sub IsDirectory($$);
131
131
  sub Rename($$$);
132
132
  sub Unlink($@);
@@ -142,8 +142,8 @@ sub ReadValue($$$;$$$);
142
142
  @loadAllTables = qw(
143
143
  PhotoMechanic Exif GeoTiff CanonRaw KyoceraRaw Lytro MinoltaRaw PanasonicRaw
144
144
  SigmaRaw JPEG GIMP Jpeg2000 GIF BMP BMP::OS2 BMP::Extra BPG BPG::Extensions
145
- ICO PICT PNG MNG FLIF DjVu DPX OpenEXR ZISRAW MRC LIF MRC::FEI12 MIFF PCX
146
- PGF PSP PhotoCD Radiance Other::PFM PDF PostScript Photoshop::Header
145
+ WPG ICO PICT PNG MNG FLIF DjVu DPX OpenEXR ZISRAW MRC LIF MRC::FEI12 MIFF
146
+ PCX PGF PSP PhotoCD Radiance Other::PFM PDF PostScript Photoshop::Header
147
147
  Photoshop::Layers Photoshop::ImageData FujiFilm::RAF FujiFilm::IFD
148
148
  Samsung::Trailer Sony::SRF2 Sony::SR2SubIFD Sony::PMP ITC ID3 ID3::Lyrics3
149
149
  FLAC Ogg Vorbis APE APE::NewHeader APE::OldHeader Audible MPC MPEG::Audio
@@ -152,8 +152,9 @@ sub ReadValue($$$;$$$);
152
152
  Real::Media Real::Audio Real::Metafile Red RIFF AIFF ASF WTV DICOM FITS MIE
153
153
  JSON HTML XMP::SVG Palm Palm::MOBI Palm::EXTH Torrent EXE EXE::PEVersion
154
154
  EXE::PEString EXE::MachO EXE::PEF EXE::ELF EXE::AR EXE::CHM LNK Font VCard
155
- Text VCard::VCalendar VCard::VNote RSRC Rawzor ZIP ZIP::GZIP ZIP::RAR RTF
156
- OOXML iWork ISO FLIR::AFF FLIR::FPF MacOS MacOS::MDItem FlashPix::DocTable
155
+ Text VCard::VCalendar VCard::VNote RSRC Rawzor ZIP ZIP::GZIP ZIP::RAR
156
+ ZIP::RAR5 RTF OOXML iWork ISO FLIR::AFF FLIR::FPF MacOS MacOS::MDItem
157
+ FlashPix::DocTable
157
158
  );
158
159
 
159
160
  # alphabetical list of current Lang modules
@@ -190,12 +191,12 @@ $defaultLang = 'en'; # default language
190
191
  # 3) PLIST must be in this list for the binary PLIST format, although it may
191
192
  # cause a file to be checked twice for XML
192
193
  @fileTypes = qw(JPEG EXV CRW DR4 TIFF GIF MRW RAF X3F JP2 PNG MIE MIFF PS PDF
193
- PSD XMP BMP BPG PPM RIFF AIFF ASF MOV MPEG Real SWF PSP FLV OGG
194
- FLAC APE MPC MKV MXF DV PMP IND PGF ICC ITC FLIR FLIF FPF LFP
195
- HTML VRD RTF FITS XCF DSS QTIF FPX PICT ZIP GZIP PLIST RAR BZ2
196
- CZI TAR EXE EXR HDR CHM LNK WMF AVC DEX DPX RAW Font RSRC M2TS
197
- MacOS PHP PCX DCX DWF DWG DXF WTV Torrent VCard LRI R3D AA PDB
198
- PFM2 MRC LIF JXL MOI ISO ALIAS JSON MP3 DICOM PCD ICO TXT);
194
+ PSD XMP BMP WPG BPG PPM RIFF AIFF ASF MOV MPEG Real SWF PSP FLV
195
+ OGG FLAC APE MPC MKV MXF DV PMP IND PGF ICC ITC FLIR FLIF FPF
196
+ LFP HTML VRD RTF FITS XCF DSS QTIF FPX PICT ZIP GZIP PLIST RAR
197
+ 7Z BZ2 CZI TAR EXE EXR HDR CHM LNK WMF AVC DEX DPX RAW Font RSRC
198
+ M2TS MacOS PHP PCX DCX DWF DWG DXF WTV Torrent VCard LRI R3D AA
199
+ PDB PFM2 MRC LIF JXL MOI ISO ALIAS JSON MP3 DICOM PCD ICO TXT);
199
200
 
200
201
  # file types that we can write (edit)
201
202
  my @writeTypes = qw(JPEG TIFF GIF CRW MRW ORF RAF RAW PNG MIE PSD XMP PPM EPS
@@ -227,6 +228,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
227
228
  '3GP' => ['MOV', '3rd Gen. Partnership Project audio/video'],
228
229
  '3GP2'=> '3G2',
229
230
  '3GPP'=> '3GP',
231
+ '7Z' => ['7Z', '7z archive'],
230
232
  A => ['EXE', 'Static library'],
231
233
  AA => ['AA', 'Audible Audiobook'],
232
234
  AAE => ['PLIST','Apple edit information'],
@@ -328,6 +330,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
328
330
  FPF => ['FPF', 'FLIR Public image Format'],
329
331
  FPX => ['FPX', 'FlashPix'],
330
332
  GIF => ['GIF', 'Compuserve Graphics Interchange Format'],
333
+ GLV => ['MOV', 'Garmin Low-resolution Video'],
331
334
  GPR => ['TIFF', 'General Purpose RAW'], # https://gopro.github.io/gpr/
332
335
  GZ => 'GZIP',
333
336
  GZIP => ['GZIP', 'GNU ZIP compressed archive'],
@@ -554,6 +557,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
554
557
  XMP => ['XMP', 'Extensible Metadata Platform'],
555
558
  WOFF => ['Font', 'Web Open Font Format'],
556
559
  WOFF2=> ['Font', 'Web Open Font Format2'],
560
+ WPG => ['WPG', 'WordPerfect Graphics'],
557
561
  WTV => ['WTV', 'Windows recorded TV show'],
558
562
  ZIP => ['ZIP', 'ZIP archive'],
559
563
  );
@@ -588,6 +592,7 @@ my %fileDescription = (
588
592
  # types may be specified by some modules, eg. QuickTime.pm and RIFF.pm)
589
593
  %mimeType = (
590
594
  '3FR' => 'image/x-hasselblad-3fr',
595
+ '7Z' => 'application/x-7z-compressed',
591
596
  AA => 'audio/audible',
592
597
  AAE => 'application/vnd.apple.photos',
593
598
  AI => 'application/vnd.adobe.illustrator',
@@ -789,6 +794,7 @@ my %fileDescription = (
789
794
  WMA => 'audio/x-ms-wma',
790
795
  WMF => 'application/x-wmf',
791
796
  WMV => 'video/x-ms-wmv',
797
+ WPG => 'image/x-wpg',
792
798
  WTV => 'video/x-ms-wtv',
793
799
  X3F => 'image/x-sigma-x3f',
794
800
  XCF => 'image/x-xcf',
@@ -970,7 +976,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
970
976
  QTIF => '.{4}(idsc|idat|iicc)',
971
977
  R3D => '\0\0..RED(1|2)',
972
978
  RAF => 'FUJIFILM',
973
- RAR => 'Rar!\x1a\x07\0',
979
+ RAR => 'Rar!\x1a\x07\x01?\0',
974
980
  RAW => '(.{25}ARECOYK|II|MM)',
975
981
  Real => '(\.RMF|\.ra\xfd|pnm://|rtsp://|http://)',
976
982
  RIFF => '(RIFF|LA0[234]|OFR |LPAC|wvpk|RF64)', # RIFF plus other variants
@@ -984,6 +990,7 @@ $testLen = 1024; # number of bytes to read when testing for magic number
984
990
  VCard=> '(?i)BEGIN:(VCARD|VCALENDAR|VNOTE)\r\n',
985
991
  VRD => 'CANON OPTIONAL DATA\0',
986
992
  WMF => '(\xd7\xcd\xc6\x9a\0\0|\x01\0\x09\0\0\x03)',
993
+ WPG => '\xff\x57\x50\x43',
987
994
  WTV => '\xb7\xd8\x00\x20\x37\x49\xda\x11\xa6\x4e\x00\x07\xe9\x5e\xad\x8d',
988
995
  X3F => 'FOVb',
989
996
  XCF => 'gimp xcf ',
@@ -1045,6 +1052,93 @@ my %xmpShorthandOpt = ( 0 => 'None', 1 => 'Shorthand', 2 => ['Shorthand','OneDes
1045
1052
  maccroatian => 'MacCroatian', cp10082 => 'MacCroatian',
1046
1053
  );
1047
1054
 
1055
+ # list of available options
1056
+ # +-----------------------------------------------------+
1057
+ # ! DON'T FORGET!! When adding any new option, must !
1058
+ # ! decide how it is handled in SetNewValuesFromFile() !
1059
+ # +-----------------------------------------------------+
1060
+ # (Note: All options must exist in this lookup, even if undefined,
1061
+ # to facilitate case-insensitive options. 'Group#' is handled specially)
1062
+ my @availableOptions = (
1063
+ [ 'Binary', undef, 'flag to extract binary values even if tag not specified' ],
1064
+ [ 'ByteOrder', undef, 'default byte order when creating EXIF information' ],
1065
+ [ 'Charset', 'UTF8', 'character set for converting Unicode characters' ],
1066
+ [ 'CharsetEXIF', undef, 'internal EXIF "ASCII" string encoding' ],
1067
+ [ 'CharsetFileName', undef, 'external encoding for file names' ],
1068
+ [ 'CharsetID3', 'Latin','internal ID3v1 character set' ],
1069
+ [ 'CharsetIPTC', 'Latin','fallback IPTC character set if no CodedCharacterSet' ],
1070
+ [ 'CharsetPhotoshop', 'Latin','internal encoding for Photoshop resource names' ],
1071
+ [ 'CharsetQuickTime', 'MacRoman', 'internal QuickTime string encoding' ],
1072
+ [ 'CharsetRIFF', 0, 'internal RIFF string encoding (0=default to Latin)' ],
1073
+ [ 'Compact', { }, 'write compact XMP' ],
1074
+ [ 'Composite', 1, 'flag to calculate Composite tags' ],
1075
+ [ 'Compress', undef, 'flag to write new values as compressed if possible' ],
1076
+ [ 'CoordFormat', undef, 'GPS lat/long coordinate format' ],
1077
+ [ 'DateFormat', undef, 'format for date/time' ],
1078
+ [ 'Duplicates', 1, 'flag to save duplicate tag values' ],
1079
+ [ 'Escape', undef, 'escape special characters' ],
1080
+ [ 'Exclude', undef, 'tags to exclude' ],
1081
+ [ 'ExtendedXMP', 1, 'strategy for reading extended XMP' ],
1082
+ [ 'ExtractEmbedded', undef, 'flag to extract information from embedded documents' ],
1083
+ [ 'FastScan', undef, 'flag to avoid scanning for trailer' ],
1084
+ [ 'Filter', undef, 'output filter for all tag values' ],
1085
+ [ 'FilterW', undef, 'input filter when writing tag values' ],
1086
+ [ 'FixBase', undef, 'fix maker notes base offsets' ],
1087
+ [ 'GeoMaxIntSecs', 1800, 'geotag maximum interpolation time (secs)' ],
1088
+ [ 'GeoMaxExtSecs', 1800, 'geotag maximum extrapolation time (secs)' ],
1089
+ [ 'GeoMaxHDOP', undef, 'geotag maximum HDOP' ],
1090
+ [ 'GeoMaxPDOP', undef, 'geotag maximum PDOP' ],
1091
+ [ 'GeoMinSats', undef, 'geotag minimum satellites' ],
1092
+ [ 'GeoSpeedRef', undef, 'geotag GPSSpeedRef' ],
1093
+ [ 'GlobalTimeShift', undef, 'apply time shift to all extracted date/time values' ],
1094
+ [ 'Group#', undef, 'return tags for specified groups in family #' ],
1095
+ [ 'HexTagIDs', 0, 'use hex tag ID\'s in family 7 group names' ],
1096
+ [ 'HtmlDump', 0, 'HTML dump (0-3, higher # = bigger limit)' ],
1097
+ [ 'HtmlDumpBase', undef, 'base address for HTML dump' ],
1098
+ [ 'IgnoreMinorErrors',undef, 'ignore minor errors when reading/writing' ],
1099
+ [ 'IgnoreTags', undef, 'list of tags to ignore when extracting' ],
1100
+ [ 'ImageHashType', 'MD5', 'image hash algorithm' ],
1101
+ [ 'Lang', $defaultLang, 'localized language for descriptions etc' ],
1102
+ [ 'LargeFileSupport', undef, 'flag indicating support of 64-bit file offsets' ],
1103
+ [ 'List', undef, '[deprecated, use ListSplit and ListJoin instead]' ],
1104
+ [ 'ListItem', undef, 'used to return a specific item from lists' ],
1105
+ [ 'ListJoin', ', ', 'join lists together with this separator' ],
1106
+ [ 'ListSep', ', ', '[deprecated, use ListSplit and ListJoin instead]' ],
1107
+ [ 'ListSplit', undef, 'regex for splitting list-type tag values when writing' ],
1108
+ [ 'MakerNotes', undef, 'extract maker notes as a block' ],
1109
+ [ 'MDItemTags', undef, 'extract MacOS metadata item tags' ],
1110
+ [ 'MissingTagValue', undef, 'value for missing tags when expanded in expressions' ],
1111
+ [ 'NoMultiExif', undef, 'raise error when writing multi-segment EXIF' ],
1112
+ [ 'NoPDFList', undef, 'flag to avoid splitting PDF List-type tag values' ],
1113
+ [ 'NoWarning', undef, 'regular expression for warnings to suppress' ],
1114
+ [ 'Password', undef, 'password for password-protected PDF documents' ],
1115
+ [ 'PrintConv', 1, 'flag to enable print conversion' ],
1116
+ [ 'QuickTimeHandler', 1, 'flag to add mdir Handler to newly created Meta box' ],
1117
+ [ 'QuickTimePad', undef, 'flag to preserve padding of QuickTime CR3 tags' ],
1118
+ [ 'QuickTimeUTC', undef, 'assume that QuickTime date/time tags are stored as UTC' ],
1119
+ [ 'RequestAll', undef, 'extract all tags that must be specifically requested' ],
1120
+ [ 'RequestTags', undef, 'extra tags to request (on top of those in the tag list)' ],
1121
+ [ 'SaveFormat', undef, 'save family 6 tag TIFF format' ],
1122
+ [ 'SavePath', undef, 'save family 5 location path' ],
1123
+ [ 'ScanForXMP', undef, 'flag to scan for XMP information in all files' ],
1124
+ [ 'Sort', 'Input','order to sort found tags (Input, File, Tag, Descr, Group#)' ],
1125
+ [ 'Sort2', 'File', 'secondary sort order for tags in a group (File, Tag, Descr)' ],
1126
+ [ 'StrictDate', undef, 'flag to return undef for invalid date conversions' ],
1127
+ [ 'Struct', undef, 'return structures as hash references' ],
1128
+ [ 'StructFormat', undef, 'format for structure serialization when reading/writing' ],
1129
+ [ 'SystemTags', undef, 'extract additional File System tags' ],
1130
+ [ 'TextOut', \*STDOUT, 'file for Verbose/HtmlDump output' ],
1131
+ [ 'TimeZone', undef, 'local time zone' ],
1132
+ [ 'Unknown', 0, 'flag to get values of unknown tags (0-2)' ],
1133
+ [ 'UserParam', { }, 'user parameters for additional user-defined tag values' ],
1134
+ [ 'Validate', undef, 'perform additional validation' ],
1135
+ [ 'Verbose', 0, 'print verbose messages (0-5, higher # = more verbose)' ],
1136
+ [ 'WriteMode', 'wcg', 'enable all write modes by default' ],
1137
+ [ 'XAttrTags', undef, 'extract MacOS extended attribute tags' ],
1138
+ [ 'XMPAutoConv', 1, 'automatic conversion of unknown XMP tag values' ],
1139
+ [ 'XMPShorthand', 0, '[deprecated, use Compact=Shorthand instead]' ],
1140
+ );
1141
+
1048
1142
  # default family 0 group priority for writing
1049
1143
  # (NOTE: tags in groups not specified here will not be written unless
1050
1144
  # overridden by the module or specified when writing)
@@ -1823,15 +1917,17 @@ my %systemTagsNotes = (
1823
1917
  if specifically requested
1824
1918
  },
1825
1919
  },
1826
- ImageDataMD5 => {
1920
+ ImageDataHash => {
1827
1921
  Notes => q{
1828
- MD5 of image data. Generated only if specifically requested for JPEG and
1829
- TIFF-based images, PNG, CRW, CR3, MRW, RAF, X3F and AVIF images, MOV/MP4
1830
- videos, and some RIFF-based files. The MD5 includes the main image data,
1831
- plus JpgFromRaw/OtherImage for some formats, but does not include
1832
- ThumbnailImage or PreviewImage. Includes video and audio data for MOV/MP4.
1833
- The L<XMP-et:OriginalImageMD5 tag|XMP.html#ExifTool> provides a place to
1834
- store these values in the file.
1922
+ Hash of image data. Generated only if specifically requested for JPEG, TIFF,
1923
+ PNG, CRW, CR3, MRW, RAF, X3F, IIQ, JP2, JXL, HEIC and AVIF images, MOV/MP4
1924
+ videos, and some RIFF-based files such as AVI, WAV and WEBP. The hash
1925
+ algorithm is set by the API L<ImageHashType|../ExifTool.html#ImageHashType> option, and is 'MD5' by default.
1926
+ The hash includes the main image data, plus JpgFromRaw/OtherImage for some
1927
+ formats, but does not include ThumbnailImage or PreviewImage. Includes
1928
+ video and audio data for MOV/MP4. The L<XMP-et:OriginalImageHash and
1929
+ XMP-et:OriginalImageHashType tags|XMP.html#ExifTool> provide a way to store
1930
+ the this hash value and the hash type in the file.
1835
1931
  },
1836
1932
  },
1837
1933
  );
@@ -2125,8 +2221,10 @@ sub Options($$;@)
2125
2221
 
2126
2222
  while (@_) {
2127
2223
  my $param = shift;
2224
+ my $plus;
2128
2225
  # fix parameter case if necessary
2129
2226
  unless (exists $$options{$param}) {
2227
+ $plus = $param =~ s/\+$//;
2130
2228
  my ($fixed) = grep /^$param$/i, keys %$options;
2131
2229
  if ($fixed) {
2132
2230
  $param = $fixed;
@@ -2291,6 +2389,35 @@ sub Options($$;@)
2291
2389
  $compact{$p} = $val; # preserve most recent setting
2292
2390
  }
2293
2391
  $$options{Compact} = $$options{XMPShorthand} = \%compact;
2392
+ } elsif ($param eq 'NoWarning') {
2393
+ # validate regular expression
2394
+ undef $evalWarning;
2395
+ if (defined $newVal) {
2396
+ local $SIG{'__WARN__'} = \&SetWarning;
2397
+ eval { $param =~ /$newVal/ };
2398
+ $@ and $evalWarning = $@;
2399
+ }
2400
+ if ($evalWarning) {
2401
+ warn 'NoWarning: ' . CleanWarning() . "\n";
2402
+ next;
2403
+ }
2404
+ # add to existing expression if specified
2405
+ if ($plus and defined $oldVal) {
2406
+ $newVal = defined $newVal ? "$oldVal|$newVal" : $oldVal;
2407
+ }
2408
+ $$options{$param} = $newVal;
2409
+ } elsif ($param eq 'ImageHashType') {
2410
+ if (defined $newVal and $newVal =~ /^(MD5|SHA256|SHA512)$/i) {
2411
+ $$options{$param} = uc($newVal);
2412
+ } else {
2413
+ warn("Invalid $param setting '${newVal}'\n"), return $oldVal;
2414
+ }
2415
+ } elsif ($param eq 'StructFormat') {
2416
+ if (defined $newVal) {
2417
+ $newVal =~ /^(JSON|JSONQ)$/i or warn("Invalid $param setting '${newVal}'\n"), return $oldVal;
2418
+ $newVal = uc($newVal);
2419
+ }
2420
+ $$options{$param} = $newVal;
2294
2421
  } else {
2295
2422
  if ($param eq 'Escape') {
2296
2423
  # set ESCAPE_PROC
@@ -2328,89 +2455,11 @@ sub ClearOptions($)
2328
2455
  local $_;
2329
2456
  my $self = shift;
2330
2457
 
2331
- # create options hash with default values
2332
- # +-----------------------------------------------------+
2333
- # ! DON'T FORGET!! When adding any new option, must !
2334
- # ! decide how it is handled in SetNewValuesFromFile() !
2335
- # +-----------------------------------------------------+
2336
- # (Note: All options must exist in this lookup, even if undefined,
2337
- # to facilitate case-insensitive options. 'Group#' is handled specially)
2338
- $$self{OPTIONS} = {
2339
- Binary => undef, # flag to extract binary values even if tag not specified
2340
- ByteOrder => undef, # default byte order when creating EXIF information
2341
- Charset => 'UTF8', # character set for converting Unicode characters
2342
- CharsetEXIF => undef, # internal EXIF "ASCII" string encoding
2343
- CharsetFileName => undef, # external encoding for file names
2344
- CharsetID3 => 'Latin', # internal ID3v1 character set
2345
- CharsetIPTC => 'Latin', # fallback IPTC character set if no CodedCharacterSet
2346
- CharsetPhotoshop => 'Latin', # internal encoding for Photoshop resource names
2347
- CharsetQuickTime => 'MacRoman', # internal QuickTime string encoding
2348
- CharsetRIFF => 0, # internal RIFF string encoding (0=default to Latin)
2349
- Compact => { }, # write compact XMP
2350
- Composite => 1, # flag to calculate Composite tags
2351
- Compress => undef, # flag to write new values as compressed if possible
2352
- CoordFormat => undef, # GPS lat/long coordinate format
2353
- DateFormat => undef, # format for date/time
2354
- Duplicates => 1, # flag to save duplicate tag values
2355
- Escape => undef, # escape special characters
2356
- Exclude => undef, # tags to exclude
2357
- ExtendedXMP => 1, # strategy for reading extended XMP
2358
- ExtractEmbedded =>undef,# flag to extract information from embedded documents
2359
- FastScan => undef, # flag to avoid scanning for trailer
2360
- Filter => undef, # output filter for all tag values
2361
- FilterW => undef, # input filter when writing tag values
2362
- FixBase => undef, # fix maker notes base offsets
2363
- GeoMaxIntSecs => 1800, # geotag maximum interpolation time (secs)
2364
- GeoMaxExtSecs => 1800, # geotag maximum extrapolation time (secs)
2365
- GeoMaxHDOP => undef, # geotag maximum HDOP
2366
- GeoMaxPDOP => undef, # geotag maximum PDOP
2367
- GeoMinSats => undef, # geotag minimum satellites
2368
- GeoSpeedRef => undef, # geotag GPSSpeedRef
2369
- GlobalTimeShift => undef, # apply time shift to all extracted date/time values
2370
- # Group# => undef, # return tags for specified groups in family #
2371
- HexTagIDs => 0, # use hex tag ID's in family 7 group names
2372
- HtmlDump => 0, # HTML dump (0-3, higher # = bigger limit)
2373
- HtmlDumpBase => undef, # base address for HTML dump
2374
- IgnoreMinorErrors => undef, # ignore minor errors when reading/writing
2375
- IgnoreTags => undef, # list of tags to ignore when extracting
2376
- Lang => $defaultLang,# localized language for descriptions etc
2377
- LargeFileSupport => undef, # flag indicating support of 64-bit file offsets
2378
- List => undef, # extract lists of PrintConv values into arrays [no longer documented]
2379
- ListItem => undef, # used to return a specific item from lists
2380
- ListJoin => ', ', # join lists together with this separator
2381
- ListSep => ', ', # list item separator [no longer documented]
2382
- ListSplit => undef, # regex for splitting list-type tag values when writing
2383
- MakerNotes => undef, # extract maker notes as a block
2384
- MDItemTags => undef, # extract MacOS metadata item tags
2385
- MissingTagValue =>undef,# value for missing tags when expanded in expressions
2386
- NoMultiExif => undef, # raise error when writing multi-segment EXIF
2387
- NoPDFList => undef, # flag to avoid splitting PDF List-type tag values
2388
- Password => undef, # password for password-protected PDF documents
2389
- PrintConv => 1, # flag to enable print conversion
2390
- QuickTimeHandler => 1, # flag to add mdir Handler to newly created Meta box
2391
- QuickTimePad=> undef, # flag to preserve padding of QuickTime CR3 tags
2392
- QuickTimeUTC=> undef, # assume that QuickTime date/time tags are stored as UTC
2393
- RequestAll => undef, # extract all tags that must be specifically requested
2394
- RequestTags => undef, # extra tags to request (on top of those in the tag list)
2395
- SaveFormat => undef, # save family 6 tag TIFF format
2396
- SavePath => undef, # save family 5 location path
2397
- ScanForXMP => undef, # flag to scan for XMP information in all files
2398
- Sort => 'Input', # order to sort found tags (Input, File, Tag, Descr, Group#)
2399
- Sort2 => 'File', # secondary sort order for tags in a group (File, Tag, Descr)
2400
- StrictDate => undef, # flag to return undef for invalid date conversions
2401
- Struct => undef, # return structures as hash references
2402
- SystemTags => undef, # extract additional File System tags
2403
- TextOut => \*STDOUT,# file for Verbose/HtmlDump output
2404
- TimeZone => undef, # local time zone
2405
- Unknown => 0, # flag to get values of unknown tags (0-2)
2406
- UserParam => { }, # user parameters for additional user-defined tag values
2407
- Validate => undef, # perform additional validation
2408
- Verbose => 0, # print verbose messages (0-5, higher # = more verbose)
2409
- WriteMode => 'wcg', # enable all write modes by default
2410
- XAttrTags => undef, # extract MacOS extended attribute tags
2411
- XMPAutoConv => 1, # automatic conversion of unknown XMP tag values
2412
- XMPShorthand=> 0, # (unused, but needed for backward compatibility)
2413
- };
2458
+ $$self{OPTIONS} = { }; # clear all options
2459
+
2460
+ # load default options
2461
+ $$self{OPTIONS}{$$_[0]} = $$_[1] foreach @availableOptions;
2462
+
2414
2463
  # keep necessary member variables in sync with options
2415
2464
  delete $$self{CUR_LANG};
2416
2465
  delete $$self{ESCAPE_PROC};
@@ -2494,32 +2543,22 @@ sub ExtractInfo($;@)
2494
2543
  }
2495
2544
  }
2496
2545
 
2497
- # create MD5 object if ImageDataMD5 is requested
2498
- if ($$req{imagedatamd5} and not $$self{ImageDataMD5}) {
2499
- if (require Digest::MD5) {
2500
- $$self{ImageDataMD5} = Digest::MD5->new;
2546
+ # create Hash object if ImageDataHash is requested
2547
+ if ($$req{imagedatahash} and not $$self{ImageDataHash}) {
2548
+ my $imageHashType = $self->Options('ImageHashType');
2549
+ if ($imageHashType =~ /^SHA(256|512)$/i) {
2550
+ if (require Digest::SHA) {
2551
+ $$self{ImageDataHash} = Digest::SHA->new($1);
2552
+ } else {
2553
+ $self->WarnOnce("Install Digest::SHA to calculate image data SHA$1");
2554
+ }
2555
+ } elsif (require Digest::MD5) {
2556
+ $$self{ImageDataHash} = Digest::MD5->new;
2501
2557
  } else {
2502
2558
  $self->WarnOnce('Install Digest::MD5 to calculate image data MD5');
2503
2559
  }
2504
2560
  }
2505
2561
  ++$$self{FILE_SEQUENCE}; # count files read
2506
- # extract information from alternate files if necessary
2507
- my ($g8, $altExifTool);
2508
- foreach $g8 (keys %{$$self{ALT_EXIFTOOL}}) {
2509
- $altExifTool = $$self{ALT_EXIFTOOL}{$g8};
2510
- next if $$altExifTool{DID_EXTRACT}; # avoid extracting twice
2511
- $$altExifTool{OPTIONS} = $$self{OPTIONS};
2512
- $$altExifTool{GLOBAL_TIME_OFFSET} = $$self{GLOBAL_TIME_OFFSET};
2513
- $$altExifTool{REQ_TAG_LOOKUP} = $$self{REQ_TAG_LOOKUP};
2514
- $altExifTool->ExtractInfo($$altExifTool{ALT_FILE});
2515
- # set family 8 group name for all tags
2516
- foreach (keys %{$$altExifTool{VALUE}}) {
2517
- my $ex = $$altExifTool{TAG_EXTRA}{$_};
2518
- $ex or $ex = $$altExifTool{TAG_EXTRA}{$_} = { };
2519
- $$ex{G8} = $g8;
2520
- }
2521
- $$altExifTool{DID_EXTRACT} = 1;
2522
- }
2523
2562
  }
2524
2563
 
2525
2564
  my $filename = $$self{FILENAME}; # image file name ('' if already open)
@@ -2661,7 +2700,7 @@ sub ExtractInfo($;@)
2661
2700
  if ($isDir or (defined $stat[2] and ($stat[2] & 0170000) == 0040000)) {
2662
2701
  $self->FoundTag('FileType', 'DIR');
2663
2702
  $self->FoundTag('FileTypeExtension', '');
2664
- $self->BuildCompositeTags() if $$options{Composite};
2703
+ $self->ExtractAltInfo();
2665
2704
  $raf->Close() if $raf;
2666
2705
  return 1;
2667
2706
  }
@@ -2679,7 +2718,7 @@ sub ExtractInfo($;@)
2679
2718
  } else {
2680
2719
  $self->Error('Unknown file type');
2681
2720
  }
2682
- $self->BuildCompositeTags() if $fast == 4 and $$options{Composite};
2721
+ $self->ExtractAltInfo();
2683
2722
  last; # don't read the file
2684
2723
  }
2685
2724
  if (@fileTypeList) {
@@ -2845,8 +2884,7 @@ sub ExtractInfo($;@)
2845
2884
  }
2846
2885
  unless ($reEntry) {
2847
2886
  $$self{PATH} = [ ]; # reset PATH
2848
- # calculate Composite tags
2849
- $self->BuildCompositeTags() if $$options{Composite};
2887
+ $self->ExtractAltInfo();
2850
2888
  # do our HTML dump if requested
2851
2889
  if ($$self{HTML_DUMP}) {
2852
2890
  $raf->Seek(0, 2); # seek to end of file
@@ -2909,10 +2947,13 @@ sub ExtractInfo($;@)
2909
2947
  # restore necessary members when exiting re-entrant code
2910
2948
  $$self{$_} = $$reEntry{$_} foreach keys %$reEntry;
2911
2949
  SetByteOrder($saveOrder);
2912
- } elsif ($$self{ImageDataMD5}) {
2913
- my $digest = $$self{ImageDataMD5}->hexdigest;
2950
+ } elsif ($$self{ImageDataHash}) {
2951
+ my $digest = $$self{ImageDataHash}->hexdigest;
2914
2952
  # (don't store empty digest)
2915
- $self->FoundTag(ImageDataMD5 => $digest) unless $digest eq 'd41d8cd98f00b204e9800998ecf8427e';
2953
+ $self->FoundTag(ImageDataHash => $digest) unless
2954
+ $digest eq 'd41d8cd98f00b204e9800998ecf8427e' or
2955
+ $digest eq 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' or
2956
+ $digest eq 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e';
2916
2957
  }
2917
2958
 
2918
2959
  # ($type may be undef without an Error when processing sub-documents)
@@ -3648,14 +3689,15 @@ sub SetNewGroups($;@)
3648
3689
 
3649
3690
  #------------------------------------------------------------------------------
3650
3691
  # Build Composite tags from Require'd/Desire'd tags
3651
- # Inputs: 0) ExifTool object reference
3692
+ # Inputs: 0) ExifTool object reference, 1) flag to build only tags that require
3693
+ # tags from alternate files (without this, these tags are ignored)
3652
3694
  # Note: Tag values are calculated in alphabetical order unless a tag Require's
3653
3695
  # or Desire's another Composite tag, in which case the calculation is
3654
3696
  # deferred until after the other tag is calculated.
3655
3697
  sub BuildCompositeTags($)
3656
3698
  {
3657
3699
  local $_;
3658
- my $self = shift;
3700
+ my ($self, $altOnly) = @_;
3659
3701
 
3660
3702
  $$self{BuildingComposite} = 1;
3661
3703
 
@@ -3684,7 +3726,7 @@ COMPOSITE_TAG:
3684
3726
  # loop through sub-documents if necessary
3685
3727
  my $docNum = 0;
3686
3728
  for (;;) {
3687
- my (%tagKey, $found, $index);
3729
+ my (%tagKey, $found, $index, $requireAlt);
3688
3730
  # save Require'd and Desire'd tag values in list
3689
3731
  for ($index=0; ; ++$index) {
3690
3732
  my $reqTag = $$require{$index} || $$desire{$index} || $$inhibit{$index};
@@ -3739,6 +3781,8 @@ COMPOSITE_TAG:
3739
3781
  if ($reqTag =~ /\b(File\d+):/i and $$self{ALT_EXIFTOOL}{$1}) {
3740
3782
  $et = $$self{ALT_EXIFTOOL}{$1};
3741
3783
  $altFile = $1;
3784
+ # set flags indicating we require tags from alternate files
3785
+ $$self{DoAltComposite} = $requireAlt = 1;
3742
3786
  }
3743
3787
  # (CAREFUL! keys may not be sequential if one was deleted)
3744
3788
  for ($key=$name, $i=$$et{DUPL_TAG}{$name} || 0; ; --$i) {
@@ -3770,6 +3814,8 @@ COMPOSITE_TAG:
3770
3814
  }
3771
3815
  $tagKey{$index} = $reqTag;
3772
3816
  }
3817
+ # stop now if this requires alternate tags and we aren't building them
3818
+ last if $requireAlt xor $altOnly;
3773
3819
  if ($docNum) {
3774
3820
  if ($found) {
3775
3821
  $$self{DOC_NUM} = $docNum;
@@ -3850,6 +3896,15 @@ sub GetCompositeTagInfo($)
3850
3896
  return $Image::ExifTool::Composite{$compositeID{$tag}[0]};
3851
3897
  }
3852
3898
 
3899
+ #------------------------------------------------------------------------------
3900
+ # Return List ExifTool API options
3901
+ # Returns: 0) reference to list of available options -- each entry is a list
3902
+ # [0=option name, 1=default value, 2=description]
3903
+ sub AvailableOptions()
3904
+ {
3905
+ return \@availableOptions;
3906
+ }
3907
+
3853
3908
  #------------------------------------------------------------------------------
3854
3909
  # Get tag name (removes copy index)
3855
3910
  # Inputs: 0) Tag key
@@ -4067,6 +4122,49 @@ sub CombineInfo($;@)
4067
4122
  return \%combinedInfo;
4068
4123
  }
4069
4124
 
4125
+ #------------------------------------------------------------------------------
4126
+ # Read metadata from alternate files and build composite tags
4127
+ # Inputs: 0) ExifTool ref
4128
+ # Notes: This is called after reading the main file so the tags are available
4129
+ # for being used in the file name, but before building Composite tags
4130
+ # so tags from the alternate files may be used in the Composite tags
4131
+ sub ExtractAltInfo($)
4132
+ {
4133
+ my $self = shift;
4134
+ # extract information from alternate files if necessary
4135
+ my ($g8, $altExifTool);
4136
+ my $opts = $$self{OPTIONS};
4137
+ if ($$opts{Composite} and (not $$opts{FastScan} or $$opts{FastScan} < 5)) {
4138
+ # build all composite tags except those requiring tags from alternate files
4139
+ $self->BuildCompositeTags();
4140
+ }
4141
+ foreach $g8 (sort keys %{$$self{ALT_EXIFTOOL}}) {
4142
+ $altExifTool = $$self{ALT_EXIFTOOL}{$g8};
4143
+ next if $$altExifTool{DID_EXTRACT}; # avoid extracting twice
4144
+ $$altExifTool{OPTIONS} = $$self{OPTIONS};
4145
+ $$altExifTool{GLOBAL_TIME_OFFSET} = $$self{GLOBAL_TIME_OFFSET};
4146
+ $$altExifTool{REQ_TAG_LOOKUP} = $$self{REQ_TAG_LOOKUP};
4147
+ my $fileName = $$altExifTool{ALT_FILE};
4148
+ # allow tags from the main file to be used in the alternate file names
4149
+ # (eg. -file1 '$originalfilename')
4150
+ if ($fileName =~ /\$/) {
4151
+ my @tags = reverse sort keys %{$$self{VALUE}};
4152
+ $fileName = $self->InsertTagValues(\@tags, $fileName, 'Warn');
4153
+ next unless defined $fileName;
4154
+ }
4155
+ $altExifTool->ExtractInfo($fileName);
4156
+ # set family 8 group name for all tags
4157
+ foreach (keys %{$$altExifTool{VALUE}}) {
4158
+ my $ex = $$altExifTool{TAG_EXTRA}{$_};
4159
+ $ex or $ex = $$altExifTool{TAG_EXTRA}{$_} = { };
4160
+ $$ex{G8} = $g8;
4161
+ }
4162
+ $$altExifTool{DID_EXTRACT} = 1;
4163
+ }
4164
+ # if necessary, build composite tags that rely on tags from alternate files
4165
+ $self->BuildCompositeTags(1) if $$self{DoAltComposite};
4166
+ }
4167
+
4070
4168
  #------------------------------------------------------------------------------
4071
4169
  # Get tag table name
4072
4170
  # Inputs: 0) ExifTool object reference, 1) tag key
@@ -4291,11 +4389,11 @@ sub Open($*$;$)
4291
4389
 
4292
4390
  #------------------------------------------------------------------------------
4293
4391
  # Check to see if a file exists (with Windows Unicode support)
4294
- # Inputs: 0) ExifTool ref, 1) file name
4392
+ # Inputs: 0) ExifTool ref, 1) file name, 2) flag if we are writing this file
4295
4393
  # Returns: true if file exists
4296
- sub Exists($$)
4394
+ sub Exists($$;$)
4297
4395
  {
4298
- my ($self, $file) = @_;
4396
+ my ($self, $file, $writing) = @_;
4299
4397
 
4300
4398
  if ($self->EncodeFileName($file)) {
4301
4399
  local $SIG{'__WARN__'} = \&SetWarning;
@@ -4305,10 +4403,12 @@ sub Exists($$)
4305
4403
  Win32API::File::OPEN_EXISTING(), 0, []) };
4306
4404
  return 0 unless $wh;
4307
4405
  eval { Win32API::File::CloseHandle($wh) };
4308
- } else {
4406
+ } elsif ($writing) {
4309
4407
  # (named pipes already exist, but we pretend that they don't
4310
4408
  # so we will be able to write them, so test with for pipe -p)
4311
4409
  return(-e $file and not -p $file);
4410
+ } else {
4411
+ return(-e $file);
4312
4412
  }
4313
4413
  return 1;
4314
4414
  }
@@ -4811,6 +4911,7 @@ sub SetFoundTags($)
4811
4911
  $groupList = [ $$options{$groupOpt} ];
4812
4912
  }
4813
4913
  foreach (@$groupList) {
4914
+ next unless defined $_;
4814
4915
  # groups have priority in order they were specified
4815
4916
  ++$wantOrder;
4816
4917
  my ($groupName, $want);
@@ -4917,12 +5018,14 @@ sub AUTOLOAD
4917
5018
  sub Warn($$;$)
4918
5019
  {
4919
5020
  my ($self, $str, $ignorable) = @_;
5021
+ my $noWarn = $self->Options('NoWarning');
4920
5022
  if ($ignorable) {
4921
5023
  return 0 if $$self{OPTIONS}{IgnoreMinorErrors};
4922
5024
  return 0 if $ignorable eq '3' and $$self{OPTIONS}{Validate};
5025
+ return 1 if defined $noWarn and eval { $str =~ /$noWarn/ };
4923
5026
  $str = $ignorable eq '2' ? "[Minor] $str" : "[minor] $str";
4924
5027
  }
4925
- $self->FoundTag('Warning', $str);
5028
+ $self->FoundTag('Warning', $str) unless defined $noWarn and eval { $str =~ /$noWarn/ };
4926
5029
  return 1;
4927
5030
  }
4928
5031
 
@@ -5526,6 +5629,7 @@ my %formatSize = (
5526
5629
  ifd => 4,
5527
5630
  ifd64 => 8,
5528
5631
  ue7 => 1,
5632
+ utf8 => 1, # (Exif 3.0)
5529
5633
  );
5530
5634
  my %readValueProc = (
5531
5635
  int8s => \&Get8s,
@@ -5740,7 +5844,8 @@ sub MakeTagName($)
5740
5844
  my $name = shift;
5741
5845
  $name =~ tr/-_a-zA-Z0-9//dc; # remove illegal characters
5742
5846
  $name = ucfirst $name; # capitalize first letter
5743
- $name = "Tag$name" if length($name) < 2; # must at least 2 characters long
5847
+ $name = "Tag$name" if length($name) < 2 or $name =~ /^[-0-9]/;
5848
+ # must at least 2 characters long and not start with - or 0-9-
5744
5849
  return $name;
5745
5850
  }
5746
5851
 
@@ -6431,15 +6536,15 @@ sub ProcessJPEG($$)
6431
6536
  my $req = $$self{REQ_TAG_LOOKUP};
6432
6537
  my $htmlDump = $$self{HTML_DUMP};
6433
6538
  my %dumpParms = ( Out => $out );
6434
- my ($ch, $s, $length, $md5, $md5size);
6435
- my ($success, $wantTrailer, $trailInfo, $foundSOS, %jumbfChunk);
6539
+ my ($ch, $s, $length, $hash, $hashsize);
6540
+ my ($success, $wantTrailer, $trailInfo, $foundSOS, $gotSize, %jumbfChunk);
6436
6541
  my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $flirTotal);
6437
6542
  my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP);
6438
6543
 
6439
- # get pointer to MD5 object if it exists and we are the top-level JPEG
6440
- if ($$self{FILE_TYPE} eq 'JPEG' and not $$self{DOC_NUM}) {
6441
- $md5 = $$self{ImageDataMD5};
6442
- $md5size = 0;
6544
+ # get pointer to hash object if it exists and we are the top-level JPEG or JP2
6545
+ if ($$self{FILE_TYPE} =~ /^(JPEG|JP2)$/ and not $$self{DOC_NUM}) {
6546
+ $hash = $$self{ImageDataHash};
6547
+ $hashsize = 0;
6443
6548
  }
6444
6549
 
6445
6550
  # check to be sure this is a valid JPG (or J2C, or EXV) file
@@ -6488,7 +6593,7 @@ sub ProcessJPEG($$)
6488
6593
  #
6489
6594
  # read ahead to the next segment unless we have reached EOI, SOS or SOD
6490
6595
  #
6491
- unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer and not $md5) or
6596
+ unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer and not $hash) or
6492
6597
  $marker==0x93))
6493
6598
  {
6494
6599
  # read up to next marker (JPEG markers begin with 0xff)
@@ -6520,19 +6625,19 @@ sub ProcessJPEG($$)
6520
6625
  $nextSegPos = $raf->Tell();
6521
6626
  $len -= 4; # subtract size of length word
6522
6627
  last unless $raf->Seek($len, 1);
6523
- } elsif ($md5 and defined $marker and ($marker == 0x00 or $marker == 0xda or
6628
+ } elsif ($hash and defined $marker and ($marker == 0x00 or $marker == 0xda or
6524
6629
  ($marker >= 0xd0 and $marker <= 0xd7)))
6525
6630
  {
6526
- # calculate MD5 for image data (includes leading ff d9 but not trailing ff da)
6527
- $md5->add("\xff" . chr($marker));
6631
+ # calculate hash for image data (includes leading ff d9 but not trailing ff da)
6632
+ $hash->add("\xff" . chr($marker));
6528
6633
  my $n = $skipped - (length($buff) - 1); # number of extra 0xff's
6529
6634
  if (not $n) {
6530
6635
  $buff = substr($buff, 0, -1); # remove trailing 0xff
6531
6636
  } elsif ($n > 1) {
6532
6637
  $buff .= "\xff" x ($n - 1); # add back extra 0xff's
6533
6638
  }
6534
- $md5->add($buff);
6535
- $md5size += $skipped + 2;
6639
+ $hash->add($buff);
6640
+ $hashsize += $skipped + 2;
6536
6641
  }
6537
6642
  # read second segment too if this was the first
6538
6643
  next unless defined $marker;
@@ -6561,7 +6666,8 @@ sub ProcessJPEG($$)
6561
6666
  $self->HDump($segPos-4, $length+4, "[JPEG $markerName]", undef, 0x08);
6562
6667
  $dumpEnd = $segPos + $length;
6563
6668
  }
6564
- next unless $length >= 6;
6669
+ next if $length < 6 or $gotSize;
6670
+ $gotSize = 1; # (ignore subsequent SOF segments in probably corrupted JPEG)
6565
6671
  # extract some useful information
6566
6672
  my ($p, $h, $w, $n) = unpack('Cn2C', $$segDataPt);
6567
6673
  my $sof = GetTagTable('Image::ExifTool::JPEG::SOF');
@@ -6743,7 +6849,7 @@ sub ProcessJPEG($$)
6743
6849
  next if $trailInfo or $wantTrailer or $verbose > 2 or $htmlDump;
6744
6850
  }
6745
6851
  # must scan to EOI if Validate or JpegCompressionFactor used
6746
- next if $$options{Validate} or $calcImageLen or $$req{trailer} or $md5;
6852
+ next if $$options{Validate} or $calcImageLen or $$req{trailer} or $hash;
6747
6853
  # nothing interesting to parse after start of scan (SOS)
6748
6854
  $success = 1;
6749
6855
  last; # all done parsing file
@@ -6751,6 +6857,11 @@ sub ProcessJPEG($$)
6751
6857
  pop @$path;
6752
6858
  $verbose and print $out "JPEG SOD\n";
6753
6859
  $success = 1;
6860
+ if ($hash and $$self{FILE_TYPE} eq 'JP2') {
6861
+ my $pos = $raf->Tell();
6862
+ $self->ImageDataHash($raf, undef, 'SOD');
6863
+ $raf->Seek($pos, 0);
6864
+ }
6754
6865
  next if $verbose > 2 or $htmlDump;
6755
6866
  last; # all done parsing file
6756
6867
  } elsif (defined $markerLenBytes{$marker}) {
@@ -6767,7 +6878,7 @@ sub ProcessJPEG($$)
6767
6878
  or ($$options{RequestAll} and $$options{RequestAll} > 2)))
6768
6879
  {
6769
6880
  my $num = unpack('C',$$segDataPt) & 0x0f; # get table index
6770
- $dqt[$num] = $$segDataPt if $num < 4; # save for MD5 calculation
6881
+ $dqt[$num] = $$segDataPt if $num < 4; # save for hash calculation
6771
6882
  }
6772
6883
  # handle all other markers
6773
6884
  my $dumpType = '';
@@ -7115,9 +7226,6 @@ sub ProcessJPEG($$)
7115
7226
  $self->HandleTag($tagTablePtr, 'APP3', $$dataPt);
7116
7227
  undef $combinedSegData;
7117
7228
  }
7118
- } elsif ($$self{HasIJPEG}) {
7119
- $dumpType = 'InfiRay Data',
7120
-
7121
7229
  } elsif ($$segDataPt =~ /^\xff\xd8\xff\xdb/) {
7122
7230
  $dumpType = 'PreviewImage'; # (Samsung, HP, BenQ)
7123
7231
  $preview = $$segDataPt;
@@ -7483,8 +7591,11 @@ sub ProcessJPEG($$)
7483
7591
  }
7484
7592
  } elsif ($marker == 0x51) { # SIZ (J2C)
7485
7593
  my ($w, $h) = unpack('x2N2', $$segDataPt);
7486
- $self->FoundTag('ImageWidth', $w);
7487
- $self->FoundTag('ImageHeight', $h);
7594
+ unless ($gotSize) {
7595
+ $gotSize = 1;
7596
+ $self->FoundTag('ImageWidth', $w);
7597
+ $self->FoundTag('ImageHeight', $h);
7598
+ }
7488
7599
  } elsif (($marker & 0xf0) != 0xe0) {
7489
7600
  $dumpType = "$markerName segment";
7490
7601
  $desc = "[JPEG $markerName]"; # (other known JPEG segments)
@@ -7547,8 +7658,8 @@ sub ProcessJPEG($$)
7547
7658
  delete $extendedXMP{$guid};
7548
7659
  }
7549
7660
  }
7550
- # print verbose MD5 message if necessary
7551
- print $out "$$self{INDENT}(ImageDataMD5: $md5size bytes of JPEG image data)\n" if $md5size and $verbose;
7661
+ # print verbose hash message if necessary
7662
+ print $out "$$self{INDENT}(ImageDataHash: $hashsize bytes of JPEG image data)\n" if $hashsize and $verbose;
7552
7663
  # calculate JPEGDigest if requested
7553
7664
  if (@dqt) {
7554
7665
  require Image::ExifTool::JPEGDigest;
@@ -7743,6 +7854,8 @@ sub DoProcessTIFF($$;$)
7743
7854
  return 1;
7744
7855
  }
7745
7856
  }
7857
+ } elsif ($fileType eq 'ARW') {
7858
+ $$self{LOW_PRIORITY_DIR}{IFD1} = 1; # lower priority of IFD1 tags in ARW files
7746
7859
  }
7747
7860
  # we have a valid TIFF (or whatever) file
7748
7861
  if ($fileType and not $$self{VALUE}{FileType}) {
@@ -7824,6 +7937,9 @@ sub DoProcessTIFF($$;$)
7824
7937
  if ($$self{TIFF_TYPE} eq 'TIFF') {
7825
7938
  $self->FoundTag(PageCount => $$self{PageCount}) if $$self{MultiPage};
7826
7939
  }
7940
+ if ($$self{ImageDataHash} and $$self{A100DataOffset} and $raf->Seek($$self{A100DataOffset},0)) {
7941
+ $self->ImageDataHash($raf, undef, 'A100');
7942
+ }
7827
7943
  return 1;
7828
7944
  }
7829
7945
  #