exiftool-vendored.pl 12.62.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.
- package/bin/Changes +76 -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 +108 -75
- package/bin/lib/Image/ExifTool/7Z.pm +793 -0
- package/bin/lib/Image/ExifTool/Apple.pm +14 -7
- package/bin/lib/Image/ExifTool/BigTIFF.pm +8 -1
- package/bin/lib/Image/ExifTool/Canon.pm +4 -1
- 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 +3 -3
- package/bin/lib/Image/ExifTool/GPS.pm +5 -2
- package/bin/lib/Image/ExifTool/Geotag.pm +4 -1
- 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 +939 -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/PNG.pm +6 -6
- 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 +4757 -4633
- package/bin/lib/Image/ExifTool/TagNames.pod +706 -18
- 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 +35 -12
- package/bin/lib/Image/ExifTool/XMP.pm +14 -2
- package/bin/lib/Image/ExifTool/XMP2.pl +32 -0
- package/bin/lib/Image/ExifTool/XMPStruct.pl +96 -28
- package/bin/lib/Image/ExifTool/ZIP.pm +5 -5
- package/bin/lib/Image/ExifTool.pm +176 -128
- package/bin/lib/Image/ExifTool.pod +109 -53
- package/bin/perl-Image-ExifTool.spec +44 -44
- package/bin/pp_build_exe.args +7 -4
- package/package.json +3 -3
|
@@ -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.
|
|
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
|
|
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,93 @@ 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
|
+
[ '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
|
+
|
|
1052
1142
|
# default family 0 group priority for writing
|
|
1053
1143
|
# (NOTE: tags in groups not specified here will not be written unless
|
|
1054
1144
|
# overridden by the module or specified when writing)
|
|
@@ -1827,15 +1917,17 @@ my %systemTagsNotes = (
|
|
|
1827
1917
|
if specifically requested
|
|
1828
1918
|
},
|
|
1829
1919
|
},
|
|
1830
|
-
|
|
1920
|
+
ImageDataHash => {
|
|
1831
1921
|
Notes => q{
|
|
1832
|
-
|
|
1922
|
+
Hash of image data. Generated only if specifically requested for JPEG, TIFF,
|
|
1833
1923
|
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
|
-
|
|
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.
|
|
1839
1931
|
},
|
|
1840
1932
|
},
|
|
1841
1933
|
);
|
|
@@ -2314,6 +2406,18 @@ sub Options($$;@)
|
|
|
2314
2406
|
$newVal = defined $newVal ? "$oldVal|$newVal" : $oldVal;
|
|
2315
2407
|
}
|
|
2316
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;
|
|
2317
2421
|
} else {
|
|
2318
2422
|
if ($param eq 'Escape') {
|
|
2319
2423
|
# set ESCAPE_PROC
|
|
@@ -2351,90 +2455,11 @@ sub ClearOptions($)
|
|
|
2351
2455
|
local $_;
|
|
2352
2456
|
my $self = shift;
|
|
2353
2457
|
|
|
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
|
-
};
|
|
2458
|
+
$$self{OPTIONS} = { }; # clear all options
|
|
2459
|
+
|
|
2460
|
+
# load default options
|
|
2461
|
+
$$self{OPTIONS}{$$_[0]} = $$_[1] foreach @availableOptions;
|
|
2462
|
+
|
|
2438
2463
|
# keep necessary member variables in sync with options
|
|
2439
2464
|
delete $$self{CUR_LANG};
|
|
2440
2465
|
delete $$self{ESCAPE_PROC};
|
|
@@ -2518,10 +2543,17 @@ sub ExtractInfo($;@)
|
|
|
2518
2543
|
}
|
|
2519
2544
|
}
|
|
2520
2545
|
|
|
2521
|
-
# create
|
|
2522
|
-
if ($$req{
|
|
2523
|
-
|
|
2524
|
-
|
|
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;
|
|
2525
2557
|
} else {
|
|
2526
2558
|
$self->WarnOnce('Install Digest::MD5 to calculate image data MD5');
|
|
2527
2559
|
}
|
|
@@ -2915,10 +2947,13 @@ sub ExtractInfo($;@)
|
|
|
2915
2947
|
# restore necessary members when exiting re-entrant code
|
|
2916
2948
|
$$self{$_} = $$reEntry{$_} foreach keys %$reEntry;
|
|
2917
2949
|
SetByteOrder($saveOrder);
|
|
2918
|
-
} elsif ($$self{
|
|
2919
|
-
my $digest = $$self{
|
|
2950
|
+
} elsif ($$self{ImageDataHash}) {
|
|
2951
|
+
my $digest = $$self{ImageDataHash}->hexdigest;
|
|
2920
2952
|
# (don't store empty digest)
|
|
2921
|
-
$self->FoundTag(
|
|
2953
|
+
$self->FoundTag(ImageDataHash => $digest) unless
|
|
2954
|
+
$digest eq 'd41d8cd98f00b204e9800998ecf8427e' or
|
|
2955
|
+
$digest eq 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' or
|
|
2956
|
+
$digest eq 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e';
|
|
2922
2957
|
}
|
|
2923
2958
|
|
|
2924
2959
|
# ($type may be undef without an Error when processing sub-documents)
|
|
@@ -3861,6 +3896,15 @@ sub GetCompositeTagInfo($)
|
|
|
3861
3896
|
return $Image::ExifTool::Composite{$compositeID{$tag}[0]};
|
|
3862
3897
|
}
|
|
3863
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
|
+
|
|
3864
3908
|
#------------------------------------------------------------------------------
|
|
3865
3909
|
# Get tag name (removes copy index)
|
|
3866
3910
|
# Inputs: 0) Tag key
|
|
@@ -4345,11 +4389,11 @@ sub Open($*$;$)
|
|
|
4345
4389
|
|
|
4346
4390
|
#------------------------------------------------------------------------------
|
|
4347
4391
|
# Check to see if a file exists (with Windows Unicode support)
|
|
4348
|
-
# Inputs: 0) ExifTool ref, 1) file name
|
|
4392
|
+
# Inputs: 0) ExifTool ref, 1) file name, 2) flag if we are writing this file
|
|
4349
4393
|
# Returns: true if file exists
|
|
4350
|
-
sub Exists(
|
|
4394
|
+
sub Exists($$;$)
|
|
4351
4395
|
{
|
|
4352
|
-
my ($self, $file) = @_;
|
|
4396
|
+
my ($self, $file, $writing) = @_;
|
|
4353
4397
|
|
|
4354
4398
|
if ($self->EncodeFileName($file)) {
|
|
4355
4399
|
local $SIG{'__WARN__'} = \&SetWarning;
|
|
@@ -4359,10 +4403,12 @@ sub Exists($$)
|
|
|
4359
4403
|
Win32API::File::OPEN_EXISTING(), 0, []) };
|
|
4360
4404
|
return 0 unless $wh;
|
|
4361
4405
|
eval { Win32API::File::CloseHandle($wh) };
|
|
4362
|
-
}
|
|
4406
|
+
} elsif ($writing) {
|
|
4363
4407
|
# (named pipes already exist, but we pretend that they don't
|
|
4364
4408
|
# so we will be able to write them, so test with for pipe -p)
|
|
4365
4409
|
return(-e $file and not -p $file);
|
|
4410
|
+
} else {
|
|
4411
|
+
return(-e $file);
|
|
4366
4412
|
}
|
|
4367
4413
|
return 1;
|
|
4368
4414
|
}
|
|
@@ -4865,6 +4911,7 @@ sub SetFoundTags($)
|
|
|
4865
4911
|
$groupList = [ $$options{$groupOpt} ];
|
|
4866
4912
|
}
|
|
4867
4913
|
foreach (@$groupList) {
|
|
4914
|
+
next unless defined $_;
|
|
4868
4915
|
# groups have priority in order they were specified
|
|
4869
4916
|
++$wantOrder;
|
|
4870
4917
|
my ($groupName, $want);
|
|
@@ -5582,6 +5629,7 @@ my %formatSize = (
|
|
|
5582
5629
|
ifd => 4,
|
|
5583
5630
|
ifd64 => 8,
|
|
5584
5631
|
ue7 => 1,
|
|
5632
|
+
utf8 => 1, # (Exif 3.0)
|
|
5585
5633
|
);
|
|
5586
5634
|
my %readValueProc = (
|
|
5587
5635
|
int8s => \&Get8s,
|
|
@@ -5796,7 +5844,8 @@ sub MakeTagName($)
|
|
|
5796
5844
|
my $name = shift;
|
|
5797
5845
|
$name =~ tr/-_a-zA-Z0-9//dc; # remove illegal characters
|
|
5798
5846
|
$name = ucfirst $name; # capitalize first letter
|
|
5799
|
-
$name = "Tag$name" if length($name) < 2
|
|
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-
|
|
5800
5849
|
return $name;
|
|
5801
5850
|
}
|
|
5802
5851
|
|
|
@@ -6487,15 +6536,15 @@ sub ProcessJPEG($$)
|
|
|
6487
6536
|
my $req = $$self{REQ_TAG_LOOKUP};
|
|
6488
6537
|
my $htmlDump = $$self{HTML_DUMP};
|
|
6489
6538
|
my %dumpParms = ( Out => $out );
|
|
6490
|
-
my ($ch, $s, $length, $
|
|
6539
|
+
my ($ch, $s, $length, $hash, $hashsize);
|
|
6491
6540
|
my ($success, $wantTrailer, $trailInfo, $foundSOS, $gotSize, %jumbfChunk);
|
|
6492
6541
|
my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $flirTotal);
|
|
6493
6542
|
my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP);
|
|
6494
6543
|
|
|
6495
|
-
# get pointer to
|
|
6544
|
+
# get pointer to hash object if it exists and we are the top-level JPEG or JP2
|
|
6496
6545
|
if ($$self{FILE_TYPE} =~ /^(JPEG|JP2)$/ and not $$self{DOC_NUM}) {
|
|
6497
|
-
$
|
|
6498
|
-
$
|
|
6546
|
+
$hash = $$self{ImageDataHash};
|
|
6547
|
+
$hashsize = 0;
|
|
6499
6548
|
}
|
|
6500
6549
|
|
|
6501
6550
|
# check to be sure this is a valid JPG (or J2C, or EXV) file
|
|
@@ -6544,7 +6593,7 @@ sub ProcessJPEG($$)
|
|
|
6544
6593
|
#
|
|
6545
6594
|
# read ahead to the next segment unless we have reached EOI, SOS or SOD
|
|
6546
6595
|
#
|
|
6547
|
-
unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer and not $
|
|
6596
|
+
unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer and not $hash) or
|
|
6548
6597
|
$marker==0x93))
|
|
6549
6598
|
{
|
|
6550
6599
|
# read up to next marker (JPEG markers begin with 0xff)
|
|
@@ -6576,19 +6625,19 @@ sub ProcessJPEG($$)
|
|
|
6576
6625
|
$nextSegPos = $raf->Tell();
|
|
6577
6626
|
$len -= 4; # subtract size of length word
|
|
6578
6627
|
last unless $raf->Seek($len, 1);
|
|
6579
|
-
} elsif ($
|
|
6628
|
+
} elsif ($hash and defined $marker and ($marker == 0x00 or $marker == 0xda or
|
|
6580
6629
|
($marker >= 0xd0 and $marker <= 0xd7)))
|
|
6581
6630
|
{
|
|
6582
|
-
# calculate
|
|
6583
|
-
$
|
|
6631
|
+
# calculate hash for image data (includes leading ff d9 but not trailing ff da)
|
|
6632
|
+
$hash->add("\xff" . chr($marker));
|
|
6584
6633
|
my $n = $skipped - (length($buff) - 1); # number of extra 0xff's
|
|
6585
6634
|
if (not $n) {
|
|
6586
6635
|
$buff = substr($buff, 0, -1); # remove trailing 0xff
|
|
6587
6636
|
} elsif ($n > 1) {
|
|
6588
6637
|
$buff .= "\xff" x ($n - 1); # add back extra 0xff's
|
|
6589
6638
|
}
|
|
6590
|
-
$
|
|
6591
|
-
$
|
|
6639
|
+
$hash->add($buff);
|
|
6640
|
+
$hashsize += $skipped + 2;
|
|
6592
6641
|
}
|
|
6593
6642
|
# read second segment too if this was the first
|
|
6594
6643
|
next unless defined $marker;
|
|
@@ -6800,7 +6849,7 @@ sub ProcessJPEG($$)
|
|
|
6800
6849
|
next if $trailInfo or $wantTrailer or $verbose > 2 or $htmlDump;
|
|
6801
6850
|
}
|
|
6802
6851
|
# must scan to EOI if Validate or JpegCompressionFactor used
|
|
6803
|
-
next if $$options{Validate} or $calcImageLen or $$req{trailer} or $
|
|
6852
|
+
next if $$options{Validate} or $calcImageLen or $$req{trailer} or $hash;
|
|
6804
6853
|
# nothing interesting to parse after start of scan (SOS)
|
|
6805
6854
|
$success = 1;
|
|
6806
6855
|
last; # all done parsing file
|
|
@@ -6808,9 +6857,9 @@ sub ProcessJPEG($$)
|
|
|
6808
6857
|
pop @$path;
|
|
6809
6858
|
$verbose and print $out "JPEG SOD\n";
|
|
6810
6859
|
$success = 1;
|
|
6811
|
-
if ($
|
|
6860
|
+
if ($hash and $$self{FILE_TYPE} eq 'JP2') {
|
|
6812
6861
|
my $pos = $raf->Tell();
|
|
6813
|
-
$self->
|
|
6862
|
+
$self->ImageDataHash($raf, undef, 'SOD');
|
|
6814
6863
|
$raf->Seek($pos, 0);
|
|
6815
6864
|
}
|
|
6816
6865
|
next if $verbose > 2 or $htmlDump;
|
|
@@ -6829,7 +6878,7 @@ sub ProcessJPEG($$)
|
|
|
6829
6878
|
or ($$options{RequestAll} and $$options{RequestAll} > 2)))
|
|
6830
6879
|
{
|
|
6831
6880
|
my $num = unpack('C',$$segDataPt) & 0x0f; # get table index
|
|
6832
|
-
$dqt[$num] = $$segDataPt if $num < 4; # save for
|
|
6881
|
+
$dqt[$num] = $$segDataPt if $num < 4; # save for hash calculation
|
|
6833
6882
|
}
|
|
6834
6883
|
# handle all other markers
|
|
6835
6884
|
my $dumpType = '';
|
|
@@ -7177,9 +7226,6 @@ sub ProcessJPEG($$)
|
|
|
7177
7226
|
$self->HandleTag($tagTablePtr, 'APP3', $$dataPt);
|
|
7178
7227
|
undef $combinedSegData;
|
|
7179
7228
|
}
|
|
7180
|
-
} elsif ($$self{HasIJPEG}) {
|
|
7181
|
-
$dumpType = 'InfiRay Data',
|
|
7182
|
-
|
|
7183
7229
|
} elsif ($$segDataPt =~ /^\xff\xd8\xff\xdb/) {
|
|
7184
7230
|
$dumpType = 'PreviewImage'; # (Samsung, HP, BenQ)
|
|
7185
7231
|
$preview = $$segDataPt;
|
|
@@ -7612,8 +7658,8 @@ sub ProcessJPEG($$)
|
|
|
7612
7658
|
delete $extendedXMP{$guid};
|
|
7613
7659
|
}
|
|
7614
7660
|
}
|
|
7615
|
-
# print verbose
|
|
7616
|
-
print $out "$$self{INDENT}(
|
|
7661
|
+
# print verbose hash message if necessary
|
|
7662
|
+
print $out "$$self{INDENT}(ImageDataHash: $hashsize bytes of JPEG image data)\n" if $hashsize and $verbose;
|
|
7617
7663
|
# calculate JPEGDigest if requested
|
|
7618
7664
|
if (@dqt) {
|
|
7619
7665
|
require Image::ExifTool::JPEGDigest;
|
|
@@ -7808,6 +7854,8 @@ sub DoProcessTIFF($$;$)
|
|
|
7808
7854
|
return 1;
|
|
7809
7855
|
}
|
|
7810
7856
|
}
|
|
7857
|
+
} elsif ($fileType eq 'ARW') {
|
|
7858
|
+
$$self{LOW_PRIORITY_DIR}{IFD1} = 1; # lower priority of IFD1 tags in ARW files
|
|
7811
7859
|
}
|
|
7812
7860
|
# we have a valid TIFF (or whatever) file
|
|
7813
7861
|
if ($fileType and not $$self{VALUE}{FileType}) {
|
|
@@ -7889,8 +7937,8 @@ sub DoProcessTIFF($$;$)
|
|
|
7889
7937
|
if ($$self{TIFF_TYPE} eq 'TIFF') {
|
|
7890
7938
|
$self->FoundTag(PageCount => $$self{PageCount}) if $$self{MultiPage};
|
|
7891
7939
|
}
|
|
7892
|
-
if ($$self{
|
|
7893
|
-
$self->
|
|
7940
|
+
if ($$self{ImageDataHash} and $$self{A100DataOffset} and $raf->Seek($$self{A100DataOffset},0)) {
|
|
7941
|
+
$self->ImageDataHash($raf, undef, 'A100');
|
|
7894
7942
|
}
|
|
7895
7943
|
return 1;
|
|
7896
7944
|
}
|