exiftool-vendored.pl 12.62.0 → 12.67.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.
- package/bin/Changes +96 -1
- package/bin/MANIFEST +4 -0
- package/bin/META.json +5 -3
- package/bin/META.yml +5 -3
- package/bin/Makefile.PL +7 -1
- package/bin/README +50 -46
- package/bin/config_files/guano.config +161 -0
- package/bin/exiftool +116 -79
- package/bin/lib/Image/ExifTool/7Z.pm +793 -0
- package/bin/lib/Image/ExifTool/Apple.pm +19 -8
- package/bin/lib/Image/ExifTool/BigTIFF.pm +8 -1
- package/bin/lib/Image/ExifTool/Canon.pm +33 -12
- package/bin/lib/Image/ExifTool/CanonRaw.pm +4 -4
- package/bin/lib/Image/ExifTool/CanonVRD.pm +4 -1
- package/bin/lib/Image/ExifTool/Exif.pm +31 -14
- package/bin/lib/Image/ExifTool/FlashPix.pm +8 -2
- package/bin/lib/Image/ExifTool/FujiFilm.pm +6 -3
- package/bin/lib/Image/ExifTool/GPS.pm +5 -2
- package/bin/lib/Image/ExifTool/Geotag.pm +5 -2
- package/bin/lib/Image/ExifTool/Jpeg2000.pm +226 -28
- package/bin/lib/Image/ExifTool/Lang/fr.pm +1467 -202
- package/bin/lib/Image/ExifTool/MPF.pm +2 -1
- package/bin/lib/Image/ExifTool/Matroska.pm +16 -1
- package/bin/lib/Image/ExifTool/MinoltaRaw.pm +2 -2
- package/bin/lib/Image/ExifTool/Nikon.pm +948 -31
- package/bin/lib/Image/ExifTool/NikonCustom.pm +874 -63
- package/bin/lib/Image/ExifTool/PDF.pm +23 -5
- package/bin/lib/Image/ExifTool/PLIST.pm +8 -1
- package/bin/lib/Image/ExifTool/PLUS.pm +19 -4
- package/bin/lib/Image/ExifTool/PNG.pm +6 -6
- package/bin/lib/Image/ExifTool/Pentax.pm +3 -1
- package/bin/lib/Image/ExifTool/PhaseOne.pm +5 -5
- package/bin/lib/Image/ExifTool/QuickTime.pm +91 -30
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +20 -19
- package/bin/lib/Image/ExifTool/README +2 -2
- package/bin/lib/Image/ExifTool/RIFF.pm +11 -9
- package/bin/lib/Image/ExifTool/Samsung.pm +227 -227
- package/bin/lib/Image/ExifTool/Shortcuts.pm +2 -1
- package/bin/lib/Image/ExifTool/SigmaRaw.pm +4 -4
- package/bin/lib/Image/ExifTool/Sony.pm +229 -30
- package/bin/lib/Image/ExifTool/TagLookup.pm +4758 -4633
- package/bin/lib/Image/ExifTool/TagNames.pod +715 -23
- package/bin/lib/Image/ExifTool/Validate.pm +17 -1
- package/bin/lib/Image/ExifTool/WriteExif.pl +9 -7
- package/bin/lib/Image/ExifTool/WriteQuickTime.pl +21 -9
- package/bin/lib/Image/ExifTool/WriteXMP.pl +2 -2
- package/bin/lib/Image/ExifTool/Writer.pl +36 -12
- package/bin/lib/Image/ExifTool/XMP.pm +14 -2
- package/bin/lib/Image/ExifTool/XMP2.pl +33 -1
- package/bin/lib/Image/ExifTool/XMPStruct.pl +96 -28
- package/bin/lib/Image/ExifTool/ZIP.pm +5 -5
- package/bin/lib/Image/ExifTool.pm +184 -132
- package/bin/lib/Image/ExifTool.pod +124 -58
- package/bin/perl-Image-ExifTool.spec +44 -44
- package/bin/pp_build_exe.args +7 -4
- package/package.json +3 -3
|
@@ -20,7 +20,7 @@ use strict;
|
|
|
20
20
|
use vars qw($VERSION $warnString);
|
|
21
21
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
22
22
|
|
|
23
|
-
$VERSION = '1.
|
|
23
|
+
$VERSION = '1.30';
|
|
24
24
|
|
|
25
25
|
sub WarnProc($) { $warnString = $_[0]; }
|
|
26
26
|
|
|
@@ -259,8 +259,8 @@ my %iWorkType = (
|
|
|
259
259
|
%Image::ExifTool::ZIP::RAR5 = (
|
|
260
260
|
GROUPS => { 2 => 'Other' },
|
|
261
261
|
VARS => { NO_ID => 1 },
|
|
262
|
-
NOTES => 'These tags are extracted from RAR v5 archive files.',
|
|
263
|
-
|
|
262
|
+
NOTES => 'These tags are extracted from RAR v5 and 7z archive files.',
|
|
263
|
+
FileVersion => { },
|
|
264
264
|
CompressedSize => { },
|
|
265
265
|
ModifyDate => {
|
|
266
266
|
Groups => { 2 => 'Time' },
|
|
@@ -310,7 +310,7 @@ sub ProcessRAR($$)
|
|
|
310
310
|
$et->SetFileType();
|
|
311
311
|
SetByteOrder('II');
|
|
312
312
|
my $tagTablePtr = GetTagTable('Image::ExifTool::ZIP::RAR5');
|
|
313
|
-
$et->HandleTag($tagTablePtr, '
|
|
313
|
+
$et->HandleTag($tagTablePtr, 'FileVersion', 'RAR v4');
|
|
314
314
|
$tagTablePtr = GetTagTable('Image::ExifTool::ZIP::RAR');
|
|
315
315
|
|
|
316
316
|
for (;;) {
|
|
@@ -356,7 +356,7 @@ sub ProcessRAR($$)
|
|
|
356
356
|
return 0 unless $raf->Read($buff, 1) and $buff eq "\0";
|
|
357
357
|
$et->SetFileType();
|
|
358
358
|
my $tagTablePtr = GetTagTable('Image::ExifTool::ZIP::RAR5');
|
|
359
|
-
$et->HandleTag($tagTablePtr, '
|
|
359
|
+
$et->HandleTag($tagTablePtr, 'FileVersion', 'RAR v5');
|
|
360
360
|
$$et{INDENT} .= '| ';
|
|
361
361
|
|
|
362
362
|
# loop through header blocks
|
|
@@ -29,15 +29,15 @@ 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.
|
|
32
|
+
$VERSION = '12.67';
|
|
33
33
|
$RELEASE = '';
|
|
34
34
|
@ISA = qw(Exporter);
|
|
35
35
|
%EXPORT_TAGS = (
|
|
36
36
|
# all public non-object-oriented functions:
|
|
37
37
|
Public => [qw(
|
|
38
|
-
ImageInfo GetTagName GetShortcuts GetAllTags
|
|
39
|
-
GetAllGroups GetDeleteGroups GetFileType CanWrite
|
|
40
|
-
AddUserDefinedTags
|
|
38
|
+
ImageInfo AvailableOptions GetTagName GetShortcuts GetAllTags
|
|
39
|
+
GetWritableTags GetAllGroups GetDeleteGroups GetFileType CanWrite
|
|
40
|
+
CanCreate AddUserDefinedTags
|
|
41
41
|
)],
|
|
42
42
|
# exports not part of the public API, but used by ExifTool modules:
|
|
43
43
|
DataAccess => [qw(
|
|
@@ -114,7 +114,7 @@ sub WriteTIFF($$$);
|
|
|
114
114
|
sub PackUTF8(@);
|
|
115
115
|
sub UnpackUTF8($);
|
|
116
116
|
sub SetPreferredByteOrder($;$);
|
|
117
|
-
sub
|
|
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($@);
|
|
@@ -194,7 +194,7 @@ $defaultLang = 'en'; # default language
|
|
|
194
194
|
PSD XMP BMP WPG BPG PPM RIFF AIFF ASF MOV MPEG Real SWF PSP FLV
|
|
195
195
|
OGG FLAC APE MPC MKV MXF DV PMP IND PGF ICC ITC FLIR FLIF FPF
|
|
196
196
|
LFP HTML VRD RTF FITS XCF DSS QTIF FPX PICT ZIP GZIP PLIST RAR
|
|
197
|
-
BZ2 CZI TAR
|
|
197
|
+
7Z BZ2 CZI TAR EXE EXR HDR CHM LNK WMF AVC DEX DPX RAW Font RSRC
|
|
198
198
|
M2TS MacOS PHP PCX DCX DWF DWG DXF WTV Torrent VCard LRI R3D AA
|
|
199
199
|
PDB PFM2 MRC LIF JXL MOI ISO ALIAS JSON MP3 DICOM PCD ICO TXT);
|
|
200
200
|
|
|
@@ -228,6 +228,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
|
228
228
|
'3GP' => ['MOV', '3rd Gen. Partnership Project audio/video'],
|
|
229
229
|
'3GP2'=> '3G2',
|
|
230
230
|
'3GPP'=> '3GP',
|
|
231
|
+
'7Z' => ['7Z', '7z archive'],
|
|
231
232
|
A => ['EXE', 'Static library'],
|
|
232
233
|
AA => ['AA', 'Audible Audiobook'],
|
|
233
234
|
AAE => ['PLIST','Apple edit information'],
|
|
@@ -329,6 +330,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
|
|
|
329
330
|
FPF => ['FPF', 'FLIR Public image Format'],
|
|
330
331
|
FPX => ['FPX', 'FlashPix'],
|
|
331
332
|
GIF => ['GIF', 'Compuserve Graphics Interchange Format'],
|
|
333
|
+
GLV => ['MOV', 'Garmin Low-resolution Video'],
|
|
332
334
|
GPR => ['TIFF', 'General Purpose RAW'], # https://gopro.github.io/gpr/
|
|
333
335
|
GZ => 'GZIP',
|
|
334
336
|
GZIP => ['GZIP', 'GNU ZIP compressed archive'],
|
|
@@ -590,6 +592,7 @@ my %fileDescription = (
|
|
|
590
592
|
# types may be specified by some modules, eg. QuickTime.pm and RIFF.pm)
|
|
591
593
|
%mimeType = (
|
|
592
594
|
'3FR' => 'image/x-hasselblad-3fr',
|
|
595
|
+
'7Z' => 'application/x-7z-compressed',
|
|
593
596
|
AA => 'audio/audible',
|
|
594
597
|
AAE => 'application/vnd.apple.photos',
|
|
595
598
|
AI => 'application/vnd.adobe.illustrator',
|
|
@@ -1049,6 +1052,94 @@ my %xmpShorthandOpt = ( 0 => 'None', 1 => 'Shorthand', 2 => ['Shorthand','OneDes
|
|
|
1049
1052
|
maccroatian => 'MacCroatian', cp10082 => 'MacCroatian',
|
|
1050
1053
|
);
|
|
1051
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
|
+
[ 'WindowsWideFile', undef, 'force the use of Windows wide-character file routines' ], # (see forum15208)
|
|
1137
|
+
[ 'WriteMode', 'wcg', 'enable all write modes by default' ],
|
|
1138
|
+
[ 'XAttrTags', undef, 'extract MacOS extended attribute tags' ],
|
|
1139
|
+
[ 'XMPAutoConv', 1, 'automatic conversion of unknown XMP tag values' ],
|
|
1140
|
+
[ 'XMPShorthand', 0, '[deprecated, use Compact=Shorthand instead]' ],
|
|
1141
|
+
);
|
|
1142
|
+
|
|
1052
1143
|
# default family 0 group priority for writing
|
|
1053
1144
|
# (NOTE: tags in groups not specified here will not be written unless
|
|
1054
1145
|
# overridden by the module or specified when writing)
|
|
@@ -1827,15 +1918,17 @@ my %systemTagsNotes = (
|
|
|
1827
1918
|
if specifically requested
|
|
1828
1919
|
},
|
|
1829
1920
|
},
|
|
1830
|
-
|
|
1921
|
+
ImageDataHash => {
|
|
1831
1922
|
Notes => q{
|
|
1832
|
-
|
|
1923
|
+
Hash of image data. Generated only if specifically requested for JPEG, TIFF,
|
|
1833
1924
|
PNG, CRW, CR3, MRW, RAF, X3F, IIQ, JP2, JXL, HEIC and AVIF images, MOV/MP4
|
|
1834
|
-
videos, and some RIFF-based files such as AVI, WAV and WEBP. The
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1925
|
+
videos, and some RIFF-based files such as AVI, WAV and WEBP. The hash
|
|
1926
|
+
algorithm is set by the API L<ImageHashType|../ExifTool.html#ImageHashType> option, and is 'MD5' by default.
|
|
1927
|
+
The hash includes the main image data, plus JpgFromRaw/OtherImage for some
|
|
1928
|
+
formats, but does not include ThumbnailImage or PreviewImage. Includes
|
|
1929
|
+
video and audio data for MOV/MP4. The L<XMP-et:OriginalImageHash and
|
|
1930
|
+
XMP-et:OriginalImageHashType tags|XMP.html#ExifTool> provide a way to store
|
|
1931
|
+
the this hash value and the hash type in the file.
|
|
1839
1932
|
},
|
|
1840
1933
|
},
|
|
1841
1934
|
);
|
|
@@ -2314,6 +2407,18 @@ sub Options($$;@)
|
|
|
2314
2407
|
$newVal = defined $newVal ? "$oldVal|$newVal" : $oldVal;
|
|
2315
2408
|
}
|
|
2316
2409
|
$$options{$param} = $newVal;
|
|
2410
|
+
} elsif ($param eq 'ImageHashType') {
|
|
2411
|
+
if (defined $newVal and $newVal =~ /^(MD5|SHA256|SHA512)$/i) {
|
|
2412
|
+
$$options{$param} = uc($newVal);
|
|
2413
|
+
} else {
|
|
2414
|
+
warn("Invalid $param setting '${newVal}'\n"), return $oldVal;
|
|
2415
|
+
}
|
|
2416
|
+
} elsif ($param eq 'StructFormat') {
|
|
2417
|
+
if (defined $newVal) {
|
|
2418
|
+
$newVal =~ /^(JSON|JSONQ)$/i or warn("Invalid $param setting '${newVal}'\n"), return $oldVal;
|
|
2419
|
+
$newVal = uc($newVal);
|
|
2420
|
+
}
|
|
2421
|
+
$$options{$param} = $newVal;
|
|
2317
2422
|
} else {
|
|
2318
2423
|
if ($param eq 'Escape') {
|
|
2319
2424
|
# set ESCAPE_PROC
|
|
@@ -2351,90 +2456,11 @@ sub ClearOptions($)
|
|
|
2351
2456
|
local $_;
|
|
2352
2457
|
my $self = shift;
|
|
2353
2458
|
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
#
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
# (Note: All options must exist in this lookup, even if undefined,
|
|
2360
|
-
# to facilitate case-insensitive options. 'Group#' is handled specially)
|
|
2361
|
-
$$self{OPTIONS} = {
|
|
2362
|
-
Binary => undef, # flag to extract binary values even if tag not specified
|
|
2363
|
-
ByteOrder => undef, # default byte order when creating EXIF information
|
|
2364
|
-
Charset => 'UTF8', # character set for converting Unicode characters
|
|
2365
|
-
CharsetEXIF => undef, # internal EXIF "ASCII" string encoding
|
|
2366
|
-
CharsetFileName => undef, # external encoding for file names
|
|
2367
|
-
CharsetID3 => 'Latin', # internal ID3v1 character set
|
|
2368
|
-
CharsetIPTC => 'Latin', # fallback IPTC character set if no CodedCharacterSet
|
|
2369
|
-
CharsetPhotoshop => 'Latin', # internal encoding for Photoshop resource names
|
|
2370
|
-
CharsetQuickTime => 'MacRoman', # internal QuickTime string encoding
|
|
2371
|
-
CharsetRIFF => 0, # internal RIFF string encoding (0=default to Latin)
|
|
2372
|
-
Compact => { }, # write compact XMP
|
|
2373
|
-
Composite => 1, # flag to calculate Composite tags
|
|
2374
|
-
Compress => undef, # flag to write new values as compressed if possible
|
|
2375
|
-
CoordFormat => undef, # GPS lat/long coordinate format
|
|
2376
|
-
DateFormat => undef, # format for date/time
|
|
2377
|
-
Duplicates => 1, # flag to save duplicate tag values
|
|
2378
|
-
Escape => undef, # escape special characters
|
|
2379
|
-
Exclude => undef, # tags to exclude
|
|
2380
|
-
ExtendedXMP => 1, # strategy for reading extended XMP
|
|
2381
|
-
ExtractEmbedded =>undef,# flag to extract information from embedded documents
|
|
2382
|
-
FastScan => undef, # flag to avoid scanning for trailer
|
|
2383
|
-
Filter => undef, # output filter for all tag values
|
|
2384
|
-
FilterW => undef, # input filter when writing tag values
|
|
2385
|
-
FixBase => undef, # fix maker notes base offsets
|
|
2386
|
-
GeoMaxIntSecs => 1800, # geotag maximum interpolation time (secs)
|
|
2387
|
-
GeoMaxExtSecs => 1800, # geotag maximum extrapolation time (secs)
|
|
2388
|
-
GeoMaxHDOP => undef, # geotag maximum HDOP
|
|
2389
|
-
GeoMaxPDOP => undef, # geotag maximum PDOP
|
|
2390
|
-
GeoMinSats => undef, # geotag minimum satellites
|
|
2391
|
-
GeoSpeedRef => undef, # geotag GPSSpeedRef
|
|
2392
|
-
GlobalTimeShift => undef, # apply time shift to all extracted date/time values
|
|
2393
|
-
# Group# => undef, # return tags for specified groups in family #
|
|
2394
|
-
HexTagIDs => 0, # use hex tag ID's in family 7 group names
|
|
2395
|
-
HtmlDump => 0, # HTML dump (0-3, higher # = bigger limit)
|
|
2396
|
-
HtmlDumpBase => undef, # base address for HTML dump
|
|
2397
|
-
IgnoreMinorErrors => undef, # ignore minor errors when reading/writing
|
|
2398
|
-
IgnoreTags => undef, # list of tags to ignore when extracting
|
|
2399
|
-
Lang => $defaultLang,# localized language for descriptions etc
|
|
2400
|
-
LargeFileSupport => undef, # flag indicating support of 64-bit file offsets
|
|
2401
|
-
List => undef, # extract lists of PrintConv values into arrays [no longer documented]
|
|
2402
|
-
ListItem => undef, # used to return a specific item from lists
|
|
2403
|
-
ListJoin => ', ', # join lists together with this separator
|
|
2404
|
-
ListSep => ', ', # list item separator [no longer documented]
|
|
2405
|
-
ListSplit => undef, # regex for splitting list-type tag values when writing
|
|
2406
|
-
MakerNotes => undef, # extract maker notes as a block
|
|
2407
|
-
MDItemTags => undef, # extract MacOS metadata item tags
|
|
2408
|
-
MissingTagValue =>undef,# value for missing tags when expanded in expressions
|
|
2409
|
-
NoMultiExif => undef, # raise error when writing multi-segment EXIF
|
|
2410
|
-
NoPDFList => undef, # flag to avoid splitting PDF List-type tag values
|
|
2411
|
-
NoWarning => undef, # regular expression for warnings to suppress
|
|
2412
|
-
Password => undef, # password for password-protected PDF documents
|
|
2413
|
-
PrintConv => 1, # flag to enable print conversion
|
|
2414
|
-
QuickTimeHandler => 1, # flag to add mdir Handler to newly created Meta box
|
|
2415
|
-
QuickTimePad=> undef, # flag to preserve padding of QuickTime CR3 tags
|
|
2416
|
-
QuickTimeUTC=> undef, # assume that QuickTime date/time tags are stored as UTC
|
|
2417
|
-
RequestAll => undef, # extract all tags that must be specifically requested
|
|
2418
|
-
RequestTags => undef, # extra tags to request (on top of those in the tag list)
|
|
2419
|
-
SaveFormat => undef, # save family 6 tag TIFF format
|
|
2420
|
-
SavePath => undef, # save family 5 location path
|
|
2421
|
-
ScanForXMP => undef, # flag to scan for XMP information in all files
|
|
2422
|
-
Sort => 'Input', # order to sort found tags (Input, File, Tag, Descr, Group#)
|
|
2423
|
-
Sort2 => 'File', # secondary sort order for tags in a group (File, Tag, Descr)
|
|
2424
|
-
StrictDate => undef, # flag to return undef for invalid date conversions
|
|
2425
|
-
Struct => undef, # return structures as hash references
|
|
2426
|
-
SystemTags => undef, # extract additional File System tags
|
|
2427
|
-
TextOut => \*STDOUT,# file for Verbose/HtmlDump output
|
|
2428
|
-
TimeZone => undef, # local time zone
|
|
2429
|
-
Unknown => 0, # flag to get values of unknown tags (0-2)
|
|
2430
|
-
UserParam => { }, # user parameters for additional user-defined tag values
|
|
2431
|
-
Validate => undef, # perform additional validation
|
|
2432
|
-
Verbose => 0, # print verbose messages (0-5, higher # = more verbose)
|
|
2433
|
-
WriteMode => 'wcg', # enable all write modes by default
|
|
2434
|
-
XAttrTags => undef, # extract MacOS extended attribute tags
|
|
2435
|
-
XMPAutoConv => 1, # automatic conversion of unknown XMP tag values
|
|
2436
|
-
XMPShorthand=> 0, # (unused, but needed for backward compatibility)
|
|
2437
|
-
};
|
|
2459
|
+
$$self{OPTIONS} = { }; # clear all options
|
|
2460
|
+
|
|
2461
|
+
# load default options
|
|
2462
|
+
$$self{OPTIONS}{$$_[0]} = $$_[1] foreach @availableOptions;
|
|
2463
|
+
|
|
2438
2464
|
# keep necessary member variables in sync with options
|
|
2439
2465
|
delete $$self{CUR_LANG};
|
|
2440
2466
|
delete $$self{ESCAPE_PROC};
|
|
@@ -2518,10 +2544,17 @@ sub ExtractInfo($;@)
|
|
|
2518
2544
|
}
|
|
2519
2545
|
}
|
|
2520
2546
|
|
|
2521
|
-
# create
|
|
2522
|
-
if ($$req{
|
|
2523
|
-
|
|
2524
|
-
|
|
2547
|
+
# create Hash object if ImageDataHash is requested
|
|
2548
|
+
if ($$req{imagedatahash} and not $$self{ImageDataHash}) {
|
|
2549
|
+
my $imageHashType = $self->Options('ImageHashType');
|
|
2550
|
+
if ($imageHashType =~ /^SHA(256|512)$/i) {
|
|
2551
|
+
if (require Digest::SHA) {
|
|
2552
|
+
$$self{ImageDataHash} = Digest::SHA->new($1);
|
|
2553
|
+
} else {
|
|
2554
|
+
$self->WarnOnce("Install Digest::SHA to calculate image data SHA$1");
|
|
2555
|
+
}
|
|
2556
|
+
} elsif (require Digest::MD5) {
|
|
2557
|
+
$$self{ImageDataHash} = Digest::MD5->new;
|
|
2525
2558
|
} else {
|
|
2526
2559
|
$self->WarnOnce('Install Digest::MD5 to calculate image data MD5');
|
|
2527
2560
|
}
|
|
@@ -2915,10 +2948,13 @@ sub ExtractInfo($;@)
|
|
|
2915
2948
|
# restore necessary members when exiting re-entrant code
|
|
2916
2949
|
$$self{$_} = $$reEntry{$_} foreach keys %$reEntry;
|
|
2917
2950
|
SetByteOrder($saveOrder);
|
|
2918
|
-
} elsif ($$self{
|
|
2919
|
-
my $digest = $$self{
|
|
2951
|
+
} elsif ($$self{ImageDataHash}) {
|
|
2952
|
+
my $digest = $$self{ImageDataHash}->hexdigest;
|
|
2920
2953
|
# (don't store empty digest)
|
|
2921
|
-
$self->FoundTag(
|
|
2954
|
+
$self->FoundTag(ImageDataHash => $digest) unless
|
|
2955
|
+
$digest eq 'd41d8cd98f00b204e9800998ecf8427e' or
|
|
2956
|
+
$digest eq 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' or
|
|
2957
|
+
$digest eq 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e';
|
|
2922
2958
|
}
|
|
2923
2959
|
|
|
2924
2960
|
# ($type may be undef without an Error when processing sub-documents)
|
|
@@ -3861,6 +3897,15 @@ sub GetCompositeTagInfo($)
|
|
|
3861
3897
|
return $Image::ExifTool::Composite{$compositeID{$tag}[0]};
|
|
3862
3898
|
}
|
|
3863
3899
|
|
|
3900
|
+
#------------------------------------------------------------------------------
|
|
3901
|
+
# Return List ExifTool API options
|
|
3902
|
+
# Returns: 0) reference to list of available options -- each entry is a list
|
|
3903
|
+
# [0=option name, 1=default value, 2=description]
|
|
3904
|
+
sub AvailableOptions()
|
|
3905
|
+
{
|
|
3906
|
+
return \@availableOptions;
|
|
3907
|
+
}
|
|
3908
|
+
|
|
3864
3909
|
#------------------------------------------------------------------------------
|
|
3865
3910
|
# Get tag name (removes copy index)
|
|
3866
3911
|
# Inputs: 0) Tag key
|
|
@@ -4261,6 +4306,7 @@ sub EncodeFileName($$;$)
|
|
|
4261
4306
|
{
|
|
4262
4307
|
my ($self, $file, $force) = @_;
|
|
4263
4308
|
my $enc = $$self{OPTIONS}{CharsetFileName};
|
|
4309
|
+
$force = 1 if $$self{OPTIONS}{WindowsWideFile};
|
|
4264
4310
|
if ($enc) {
|
|
4265
4311
|
if ($file =~ /[\x80-\xff]/ or $force) {
|
|
4266
4312
|
# encode for use in Windows Unicode functions if necessary
|
|
@@ -4345,11 +4391,11 @@ sub Open($*$;$)
|
|
|
4345
4391
|
|
|
4346
4392
|
#------------------------------------------------------------------------------
|
|
4347
4393
|
# Check to see if a file exists (with Windows Unicode support)
|
|
4348
|
-
# Inputs: 0) ExifTool ref, 1) file name
|
|
4394
|
+
# Inputs: 0) ExifTool ref, 1) file name, 2) flag if we are writing this file
|
|
4349
4395
|
# Returns: true if file exists
|
|
4350
|
-
sub Exists(
|
|
4396
|
+
sub Exists($$;$)
|
|
4351
4397
|
{
|
|
4352
|
-
my ($self, $file) = @_;
|
|
4398
|
+
my ($self, $file, $writing) = @_;
|
|
4353
4399
|
|
|
4354
4400
|
if ($self->EncodeFileName($file)) {
|
|
4355
4401
|
local $SIG{'__WARN__'} = \&SetWarning;
|
|
@@ -4359,10 +4405,12 @@ sub Exists($$)
|
|
|
4359
4405
|
Win32API::File::OPEN_EXISTING(), 0, []) };
|
|
4360
4406
|
return 0 unless $wh;
|
|
4361
4407
|
eval { Win32API::File::CloseHandle($wh) };
|
|
4362
|
-
}
|
|
4408
|
+
} elsif ($writing) {
|
|
4363
4409
|
# (named pipes already exist, but we pretend that they don't
|
|
4364
4410
|
# so we will be able to write them, so test with for pipe -p)
|
|
4365
4411
|
return(-e $file and not -p $file);
|
|
4412
|
+
} else {
|
|
4413
|
+
return(-e $file);
|
|
4366
4414
|
}
|
|
4367
4415
|
return 1;
|
|
4368
4416
|
}
|
|
@@ -4694,13 +4742,16 @@ sub CopyAltInfo($$$)
|
|
|
4694
4742
|
# Notes: index lists are returned in increasing order
|
|
4695
4743
|
sub SetFoundTags($)
|
|
4696
4744
|
{
|
|
4745
|
+
local $_;
|
|
4697
4746
|
my $self = shift;
|
|
4698
4747
|
my $options = $$self{OPTIONS};
|
|
4699
4748
|
my $reqTags = $$self{REQUESTED_TAGS} || [ ];
|
|
4700
4749
|
my $duplicates = $$options{Duplicates};
|
|
4701
4750
|
my $exclude = $$options{Exclude};
|
|
4702
4751
|
my $fileOrder = $$self{FILE_ORDER};
|
|
4703
|
-
my @groupOptions
|
|
4752
|
+
my @groupOptions;
|
|
4753
|
+
# ignore empty group options
|
|
4754
|
+
$$options{$_} and push @groupOptions, $_ foreach sort grep /^Group/, keys %$options;
|
|
4704
4755
|
my $doDups = $duplicates || $exclude || @groupOptions;
|
|
4705
4756
|
my ($tag, $rtnTags, @byValue, @wildTags);
|
|
4706
4757
|
|
|
@@ -5582,6 +5633,7 @@ my %formatSize = (
|
|
|
5582
5633
|
ifd => 4,
|
|
5583
5634
|
ifd64 => 8,
|
|
5584
5635
|
ue7 => 1,
|
|
5636
|
+
utf8 => 1, # (Exif 3.0)
|
|
5585
5637
|
);
|
|
5586
5638
|
my %readValueProc = (
|
|
5587
5639
|
int8s => \&Get8s,
|
|
@@ -5796,7 +5848,8 @@ sub MakeTagName($)
|
|
|
5796
5848
|
my $name = shift;
|
|
5797
5849
|
$name =~ tr/-_a-zA-Z0-9//dc; # remove illegal characters
|
|
5798
5850
|
$name = ucfirst $name; # capitalize first letter
|
|
5799
|
-
$name = "Tag$name" if length($name) < 2
|
|
5851
|
+
$name = "Tag$name" if length($name) < 2 or $name =~ /^[-0-9]/;
|
|
5852
|
+
# must at least 2 characters long and not start with - or 0-9-
|
|
5800
5853
|
return $name;
|
|
5801
5854
|
}
|
|
5802
5855
|
|
|
@@ -6487,15 +6540,15 @@ sub ProcessJPEG($$)
|
|
|
6487
6540
|
my $req = $$self{REQ_TAG_LOOKUP};
|
|
6488
6541
|
my $htmlDump = $$self{HTML_DUMP};
|
|
6489
6542
|
my %dumpParms = ( Out => $out );
|
|
6490
|
-
my ($ch, $s, $length, $
|
|
6543
|
+
my ($ch, $s, $length, $hash, $hashsize);
|
|
6491
6544
|
my ($success, $wantTrailer, $trailInfo, $foundSOS, $gotSize, %jumbfChunk);
|
|
6492
6545
|
my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $flirTotal);
|
|
6493
6546
|
my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP);
|
|
6494
6547
|
|
|
6495
|
-
# get pointer to
|
|
6548
|
+
# get pointer to hash object if it exists and we are the top-level JPEG or JP2
|
|
6496
6549
|
if ($$self{FILE_TYPE} =~ /^(JPEG|JP2)$/ and not $$self{DOC_NUM}) {
|
|
6497
|
-
$
|
|
6498
|
-
$
|
|
6550
|
+
$hash = $$self{ImageDataHash};
|
|
6551
|
+
$hashsize = 0;
|
|
6499
6552
|
}
|
|
6500
6553
|
|
|
6501
6554
|
# check to be sure this is a valid JPG (or J2C, or EXV) file
|
|
@@ -6544,7 +6597,7 @@ sub ProcessJPEG($$)
|
|
|
6544
6597
|
#
|
|
6545
6598
|
# read ahead to the next segment unless we have reached EOI, SOS or SOD
|
|
6546
6599
|
#
|
|
6547
|
-
unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer and not $
|
|
6600
|
+
unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer and not $hash) or
|
|
6548
6601
|
$marker==0x93))
|
|
6549
6602
|
{
|
|
6550
6603
|
# read up to next marker (JPEG markers begin with 0xff)
|
|
@@ -6576,19 +6629,19 @@ sub ProcessJPEG($$)
|
|
|
6576
6629
|
$nextSegPos = $raf->Tell();
|
|
6577
6630
|
$len -= 4; # subtract size of length word
|
|
6578
6631
|
last unless $raf->Seek($len, 1);
|
|
6579
|
-
} elsif ($
|
|
6632
|
+
} elsif ($hash and defined $marker and ($marker == 0x00 or $marker == 0xda or
|
|
6580
6633
|
($marker >= 0xd0 and $marker <= 0xd7)))
|
|
6581
6634
|
{
|
|
6582
|
-
# calculate
|
|
6583
|
-
$
|
|
6635
|
+
# calculate hash for image data (includes leading ff d9 but not trailing ff da)
|
|
6636
|
+
$hash->add("\xff" . chr($marker));
|
|
6584
6637
|
my $n = $skipped - (length($buff) - 1); # number of extra 0xff's
|
|
6585
6638
|
if (not $n) {
|
|
6586
6639
|
$buff = substr($buff, 0, -1); # remove trailing 0xff
|
|
6587
6640
|
} elsif ($n > 1) {
|
|
6588
6641
|
$buff .= "\xff" x ($n - 1); # add back extra 0xff's
|
|
6589
6642
|
}
|
|
6590
|
-
$
|
|
6591
|
-
$
|
|
6643
|
+
$hash->add($buff);
|
|
6644
|
+
$hashsize += $skipped + 2;
|
|
6592
6645
|
}
|
|
6593
6646
|
# read second segment too if this was the first
|
|
6594
6647
|
next unless defined $marker;
|
|
@@ -6800,7 +6853,7 @@ sub ProcessJPEG($$)
|
|
|
6800
6853
|
next if $trailInfo or $wantTrailer or $verbose > 2 or $htmlDump;
|
|
6801
6854
|
}
|
|
6802
6855
|
# must scan to EOI if Validate or JpegCompressionFactor used
|
|
6803
|
-
next if $$options{Validate} or $calcImageLen or $$req{trailer} or $
|
|
6856
|
+
next if $$options{Validate} or $calcImageLen or $$req{trailer} or $hash;
|
|
6804
6857
|
# nothing interesting to parse after start of scan (SOS)
|
|
6805
6858
|
$success = 1;
|
|
6806
6859
|
last; # all done parsing file
|
|
@@ -6808,9 +6861,9 @@ sub ProcessJPEG($$)
|
|
|
6808
6861
|
pop @$path;
|
|
6809
6862
|
$verbose and print $out "JPEG SOD\n";
|
|
6810
6863
|
$success = 1;
|
|
6811
|
-
if ($
|
|
6864
|
+
if ($hash and $$self{FILE_TYPE} eq 'JP2') {
|
|
6812
6865
|
my $pos = $raf->Tell();
|
|
6813
|
-
$self->
|
|
6866
|
+
$self->ImageDataHash($raf, undef, 'SOD');
|
|
6814
6867
|
$raf->Seek($pos, 0);
|
|
6815
6868
|
}
|
|
6816
6869
|
next if $verbose > 2 or $htmlDump;
|
|
@@ -6829,7 +6882,7 @@ sub ProcessJPEG($$)
|
|
|
6829
6882
|
or ($$options{RequestAll} and $$options{RequestAll} > 2)))
|
|
6830
6883
|
{
|
|
6831
6884
|
my $num = unpack('C',$$segDataPt) & 0x0f; # get table index
|
|
6832
|
-
$dqt[$num] = $$segDataPt if $num < 4; # save for
|
|
6885
|
+
$dqt[$num] = $$segDataPt if $num < 4; # save for hash calculation
|
|
6833
6886
|
}
|
|
6834
6887
|
# handle all other markers
|
|
6835
6888
|
my $dumpType = '';
|
|
@@ -7177,9 +7230,6 @@ sub ProcessJPEG($$)
|
|
|
7177
7230
|
$self->HandleTag($tagTablePtr, 'APP3', $$dataPt);
|
|
7178
7231
|
undef $combinedSegData;
|
|
7179
7232
|
}
|
|
7180
|
-
} elsif ($$self{HasIJPEG}) {
|
|
7181
|
-
$dumpType = 'InfiRay Data',
|
|
7182
|
-
|
|
7183
7233
|
} elsif ($$segDataPt =~ /^\xff\xd8\xff\xdb/) {
|
|
7184
7234
|
$dumpType = 'PreviewImage'; # (Samsung, HP, BenQ)
|
|
7185
7235
|
$preview = $$segDataPt;
|
|
@@ -7612,8 +7662,8 @@ sub ProcessJPEG($$)
|
|
|
7612
7662
|
delete $extendedXMP{$guid};
|
|
7613
7663
|
}
|
|
7614
7664
|
}
|
|
7615
|
-
# print verbose
|
|
7616
|
-
print $out "$$self{INDENT}(
|
|
7665
|
+
# print verbose hash message if necessary
|
|
7666
|
+
print $out "$$self{INDENT}(ImageDataHash: $hashsize bytes of JPEG image data)\n" if $hashsize and $verbose;
|
|
7617
7667
|
# calculate JPEGDigest if requested
|
|
7618
7668
|
if (@dqt) {
|
|
7619
7669
|
require Image::ExifTool::JPEGDigest;
|
|
@@ -7808,6 +7858,8 @@ sub DoProcessTIFF($$;$)
|
|
|
7808
7858
|
return 1;
|
|
7809
7859
|
}
|
|
7810
7860
|
}
|
|
7861
|
+
} elsif ($fileType eq 'ARW') {
|
|
7862
|
+
$$self{LOW_PRIORITY_DIR}{IFD1} = 1; # lower priority of IFD1 tags in ARW files
|
|
7811
7863
|
}
|
|
7812
7864
|
# we have a valid TIFF (or whatever) file
|
|
7813
7865
|
if ($fileType and not $$self{VALUE}{FileType}) {
|
|
@@ -7889,8 +7941,8 @@ sub DoProcessTIFF($$;$)
|
|
|
7889
7941
|
if ($$self{TIFF_TYPE} eq 'TIFF') {
|
|
7890
7942
|
$self->FoundTag(PageCount => $$self{PageCount}) if $$self{MultiPage};
|
|
7891
7943
|
}
|
|
7892
|
-
if ($$self{
|
|
7893
|
-
$self->
|
|
7944
|
+
if ($$self{ImageDataHash} and $$self{A100DataOffset} and $raf->Seek($$self{A100DataOffset},0)) {
|
|
7945
|
+
$self->ImageDataHash($raf, undef, 'A100');
|
|
7894
7946
|
}
|
|
7895
7947
|
return 1;
|
|
7896
7948
|
}
|