exiftool-vendored.exe 12.31.0 → 12.33.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/exiftool_files/Changes +36 -4
- package/bin/exiftool_files/README +2 -2
- package/bin/exiftool_files/arg_files/xmp2exif.args +2 -1
- package/bin/exiftool_files/exiftool.pl +33 -21
- package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +2 -1
- package/bin/exiftool_files/lib/Image/ExifTool/CBOR.pm +331 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Canon.pm +16 -4
- package/bin/exiftool_files/lib/Image/ExifTool/Exif.pm +97 -3
- package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +13 -2
- package/bin/exiftool_files/lib/Image/ExifTool/JSON.pm +7 -3
- package/bin/exiftool_files/lib/Image/ExifTool/Jpeg2000.pm +47 -14
- package/bin/exiftool_files/lib/Image/ExifTool/MacOS.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +2 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +5 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Panasonic.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Pentax.pm +2 -1
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +8 -1
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +86 -78
- package/bin/exiftool_files/lib/Image/ExifTool/README +5 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +5 -3
- package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +31 -2
- package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +59 -8
- package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +7 -2
- package/bin/exiftool_files/lib/Image/ExifTool/XMP2.pl +1 -0
- package/bin/exiftool_files/lib/Image/ExifTool/XMPStruct.pl +3 -1
- package/bin/exiftool_files/lib/Image/ExifTool.pm +8867 -8864
- package/bin/exiftool_files/lib/Image/ExifTool.pod +3 -3
- package/package.json +2 -2
|
@@ -7,11 +7,43 @@ RSS feed: https://exiftool.org/rss.xml
|
|
|
7
7
|
Note: The most recent production release is Version 12.30. (Other versions are
|
|
8
8
|
considered development releases, and are not uploaded to MetaCPAN.)
|
|
9
9
|
|
|
10
|
+
Oct. 16, 2021 - Version 12.33
|
|
11
|
+
|
|
12
|
+
- Added support for DNG version 1.6.0.0
|
|
13
|
+
- Added two new Sony LensType values (thanks Jos Roost and LibRaw)
|
|
14
|
+
- Added some new elements to the XMP-crs:Look structure (thanks Herb)
|
|
15
|
+
- Added a few new IPTC XMP tags (thanks Michael Steidl)
|
|
16
|
+
- Added a new Canon RF lens (thanks Norbert Wasser)
|
|
17
|
+
- Decode Canon ShutterMode (thanks John Moyer)
|
|
18
|
+
- Extract LensModel from some Olympus MOV videos
|
|
19
|
+
- Generate MediaDataOffset/Size for MOV videos with zero-sized MDAT chunk
|
|
20
|
+
- Improvements to CBOR reader, including hex dump with -v3 option
|
|
21
|
+
- Recognize Final Cut Pro XML files
|
|
22
|
+
- Allow binary data of Protected tags to be extracted with the -X -j and -php
|
|
23
|
+
options with -b by setting the API RequestAll option to 3
|
|
24
|
+
- Changed name of "Canon EF 80-200mm f/4.5-5.6" lens with LensType 38 to add
|
|
25
|
+
"II" to the name (Exiv2 issue 1906)
|
|
26
|
+
- Fixed runtime warning when processing files with a .DIR extension
|
|
27
|
+
|
|
28
|
+
Sept. 30, 2021 - Version 12.32
|
|
29
|
+
|
|
30
|
+
- Added support for CBOR-format metadata in JUMBF (note that JUMBF support is
|
|
31
|
+
still experimental)
|
|
32
|
+
- Added a new Nikon LensID
|
|
33
|
+
- Added a new Pentax LensType
|
|
34
|
+
- Decode timed GPS for two more dashcam formats
|
|
35
|
+
- Support reference direction columns in -geotag CSV input
|
|
36
|
+
- Removed generation of GPSSpeedRef and GPSTrackRef tags in timed metadata for
|
|
37
|
+
most dashcam formats when speed is km/h and track is relative to true north
|
|
38
|
+
- Patched to allow writing of console output to named pipes
|
|
39
|
+
- Fixed formatting of InternalSerialNumber for some Panasonic cameras
|
|
40
|
+
- Fixed bug in arg_files/xmp2exif.args support file
|
|
41
|
+
|
|
10
42
|
Sept. 22, 2021 - Version 12.31
|
|
11
43
|
|
|
12
44
|
- Added a new SonyModelID and a couple of new Sony lenses (thanks Jos Roost)
|
|
13
45
|
- Added a new Canon LensType (thanks Chris Skopec)
|
|
14
|
-
- Added Composite GPSLatitude/Longitude tags for Sony videos
|
|
46
|
+
- Added Composite GPSLatitude/Longitude tags for Sony videos to combine the
|
|
15
47
|
reference hemispheres as with the Composite tags for EXIF GPS
|
|
16
48
|
- Decode DPX AspectRatio
|
|
17
49
|
- Decode more GoPro MP4 tags
|
|
@@ -1470,8 +1502,8 @@ Oct. 9, 2018 - Version 11.13
|
|
|
1470
1502
|
- Added a new Canon LensType (thanks LibRaw)
|
|
1471
1503
|
- Minor improvements to verbose dump of streaming GPS metadata
|
|
1472
1504
|
- Reverted change of version 10.71 which resulted in Windows not recognizing
|
|
1473
|
-
PNG CreationTime as written by ExifTool (added this feature to the
|
|
1474
|
-
StrictDate
|
|
1505
|
+
PNG CreationTime as written by ExifTool (added this feature to the API
|
|
1506
|
+
StrictDate option instead)
|
|
1475
1507
|
- Improved decoding of Nikon CropHiSpeed (thanks LibRaw)
|
|
1476
1508
|
- Improved -fast option to reduce memory usage when reading JPG, PNG,
|
|
1477
1509
|
QuickTime-based and RIFF-based files via a sequential stream
|
|
@@ -1585,7 +1617,7 @@ June 21, 2018 - Version 11.03
|
|
|
1585
1617
|
June 13, 2018 - Version 11.02
|
|
1586
1618
|
|
|
1587
1619
|
- Added support for a different format of Apple iWorks files
|
|
1588
|
-
- Added undocumented FixCorruptedMOV
|
|
1620
|
+
- Added undocumented API FixCorruptedMOV option to allow fixing MOV videos
|
|
1589
1621
|
with multiple 'mdat' atoms which were corrupted by ExifTool
|
|
1590
1622
|
- Decode more QuickTime tags
|
|
1591
1623
|
- Decode more PanasonicRaw tags (thanks Klaus Homeister)
|
|
@@ -107,8 +107,8 @@ your home directory, then you would type the following commands in a
|
|
|
107
107
|
terminal window to extract and run ExifTool:
|
|
108
108
|
|
|
109
109
|
cd ~/Desktop
|
|
110
|
-
gzip -dc Image-ExifTool-12.
|
|
111
|
-
cd Image-ExifTool-12.
|
|
110
|
+
gzip -dc Image-ExifTool-12.33.tar.gz | tar -xf -
|
|
111
|
+
cd Image-ExifTool-12.33
|
|
112
112
|
./exiftool t/images/ExifTool.jpg
|
|
113
113
|
|
|
114
114
|
Note: These commands extract meta information from one of the test images.
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# 2015/01/12 - PH Avoid copying from non-standard namespaces
|
|
14
14
|
# 2016/09/26 - PH Write Composite SubSec tags
|
|
15
15
|
# 2018/05/07 - PH Added support for GPSDestXxxRef tags
|
|
16
|
+
# 2021/09/30 - PH Removed erroneous "-" when copying CreatorTool
|
|
16
17
|
#
|
|
17
18
|
# References: http://www.metadataworkinggroup.org/specs/
|
|
18
19
|
#
|
|
@@ -34,7 +35,7 @@
|
|
|
34
35
|
-Composite:SubSecDateTimeOriginal < XMP-photoshop:DateCreated
|
|
35
36
|
-Composite:SubSecCreateDate < XMP-xmp:CreateDate
|
|
36
37
|
-Composite:SubSecModifyDate < XMP-xmp:ModifyDate
|
|
37
|
-
-EXIF:Software <
|
|
38
|
+
-EXIF:Software < XMP-xmp:CreatorTool
|
|
38
39
|
-EXIF:Copyright < XMP-dc:Rights
|
|
39
40
|
-EXIF:Artist < XMP-dc:Creator
|
|
40
41
|
# XMP flash information is translated by the Composite Flash tag
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
use strict;
|
|
11
11
|
require 5.004;
|
|
12
12
|
|
|
13
|
-
my $version = '12.
|
|
13
|
+
my $version = '12.33';
|
|
14
14
|
|
|
15
15
|
# add our 'lib' directory to the include list BEFORE 'use Image::ExifTool'
|
|
16
16
|
my $exeDir;
|
|
@@ -1619,7 +1619,7 @@ if (@newValues) {
|
|
|
1619
1619
|
next;
|
|
1620
1620
|
}
|
|
1621
1621
|
my %opts = ( Shift => 0 ); # shift values if possible instead of adding/deleting
|
|
1622
|
-
# allow writing of '
|
|
1622
|
+
# allow writing of 'Unsafe' tags unless specified by wildcard
|
|
1623
1623
|
$opts{Protected} = 1 unless $tag =~ /[?*]/;
|
|
1624
1624
|
|
|
1625
1625
|
if ($tag =~ s/<// and defined $newVal) {
|
|
@@ -1954,10 +1954,19 @@ sub GetImageInfo($$)
|
|
|
1954
1954
|
my $pipe = $file;
|
|
1955
1955
|
if ($doUnzip) {
|
|
1956
1956
|
# pipe through gzip or bzip2 if necessary
|
|
1957
|
-
if ($file =~ /\.gz$/i) {
|
|
1958
|
-
$
|
|
1959
|
-
|
|
1960
|
-
|
|
1957
|
+
if ($file =~ /\.(gz|bz2)$/i) {
|
|
1958
|
+
my $type = lc $1;
|
|
1959
|
+
if ($file =~ /[^-_.'A-Za-z0-9\/\\]/) {
|
|
1960
|
+
Warn "Error: Insecure zip file name. Skipped\n";
|
|
1961
|
+
EFile($file);
|
|
1962
|
+
++$countBad;
|
|
1963
|
+
return;
|
|
1964
|
+
}
|
|
1965
|
+
if ($type eq 'gz') {
|
|
1966
|
+
$pipe = qq{gzip -dc "$file" |};
|
|
1967
|
+
} else {
|
|
1968
|
+
$pipe = qq{bzip2 -dc "$file" |};
|
|
1969
|
+
}
|
|
1961
1970
|
}
|
|
1962
1971
|
}
|
|
1963
1972
|
# evaluate -if expression for conditional processing
|
|
@@ -2276,7 +2285,7 @@ TAG: foreach $tag (@foundTags) {
|
|
|
2276
2285
|
# avoid extracting Protected binary tags (eg. data blocks) [insider information]
|
|
2277
2286
|
my $lcTag = lc $tag;
|
|
2278
2287
|
$lcTag =~ s/ .*//;
|
|
2279
|
-
next unless $$et{REQ_TAG_LOOKUP}{$lcTag};
|
|
2288
|
+
next unless $$et{REQ_TAG_LOOKUP}{$lcTag} or ($$et{OPTIONS}{RequestAll} || 0) > 2;
|
|
2280
2289
|
}
|
|
2281
2290
|
$val = ConvertBinary($val); # convert SCALAR references
|
|
2282
2291
|
next unless defined $val;
|
|
@@ -3241,7 +3250,8 @@ sub FormatXML($$$)
|
|
|
3241
3250
|
} elsif (ref $val eq 'HASH') {
|
|
3242
3251
|
$gt = " rdf:parseType='Resource'>";
|
|
3243
3252
|
my $val2 = '';
|
|
3244
|
-
|
|
3253
|
+
my @keys = $$val{_ordered_keys_} ? @{$$val{_ordered_keys_}} : sort keys %$val;
|
|
3254
|
+
foreach (@keys) {
|
|
3245
3255
|
# (some variable-namespace XML structure fields may have a different group)
|
|
3246
3256
|
my $tok = /:/ ? $_ : ($grp . ':' . $_);
|
|
3247
3257
|
$val2 .= "\n$ind <$tok" . FormatXML($$val{$_}, "$ind ", $grp) . "</$tok>";
|
|
@@ -3318,7 +3328,8 @@ sub FormatJSON($$$)
|
|
|
3318
3328
|
} elsif (ref $val eq 'HASH') {
|
|
3319
3329
|
my ($bra, $ket, $sep) = $json == 1 ? ('{','}',':') : ('Array(',')',' =>');
|
|
3320
3330
|
print $fp $bra;
|
|
3321
|
-
|
|
3331
|
+
my @keys = $$val{_ordered_keys_} ? @{$$val{_ordered_keys_}} : sort keys %$val;
|
|
3332
|
+
foreach (@keys) {
|
|
3322
3333
|
print $fp ',' if $comma;
|
|
3323
3334
|
my $key = EscapeJSON($_, 1);
|
|
3324
3335
|
print $fp qq(\n$ind $key$sep );
|
|
@@ -4729,12 +4740,13 @@ OPTIONS
|
|
|
4729
4740
|
names, prefixed by optional family numbers, and separated colons.
|
|
4730
4741
|
If no group name is specified, the tag is created in the preferred
|
|
4731
4742
|
group, and updated in any other location where a same-named tag
|
|
4732
|
-
already exists. The preferred group
|
|
4733
|
-
following list where *TAG* is valid: 1)
|
|
4743
|
+
already exists. The preferred group in JPEG and TIFF-format images
|
|
4744
|
+
is the first group in the following list where *TAG* is valid: 1)
|
|
4745
|
+
EXIF, 2) IPTC, 3) XMP.
|
|
4734
4746
|
|
|
4735
4747
|
The wildcards "*" and "?" may be used in tag names to assign the
|
|
4736
4748
|
same value to multiple tags. When specified with wildcards,
|
|
4737
|
-
"
|
|
4749
|
+
"Unsafe" tags are not written. A tag name of "All" is equivalent to
|
|
4738
4750
|
"*" (except that it doesn't require quoting, while arguments with
|
|
4739
4751
|
wildcards do on systems with shell globbing), and is often used
|
|
4740
4752
|
when deleting all metadata (ie. "-All=") or an entire group (eg.
|
|
@@ -4889,9 +4901,9 @@ OPTIONS
|
|
|
4889
4901
|
Notes:
|
|
4890
4902
|
|
|
4891
4903
|
1) Some tags (generally tags which may affect the appearance of the
|
|
4892
|
-
image) are considered "
|
|
4904
|
+
image) are considered "Unsafe" to write, and are only copied if
|
|
4893
4905
|
specified explicitly (ie. no wildcards). See the tag name
|
|
4894
|
-
documentation for more details about "
|
|
4906
|
+
documentation for more details about "Unsafe" tags.
|
|
4895
4907
|
|
|
4896
4908
|
2) Be aware of the difference between excluding a tag from being
|
|
4897
4909
|
copied (--*TAG*), and deleting a tag (-*TAG*=). Excluding a tag
|
|
@@ -4989,7 +5001,7 @@ OPTIONS
|
|
|
4989
5001
|
exiftool -@ out.args -sep ", " dst.jpg
|
|
4990
5002
|
|
|
4991
5003
|
Note: Be careful when copying information with this technique since
|
|
4992
|
-
it is easy to write tags which are normally considered "
|
|
5004
|
+
it is easy to write tags which are normally considered "Unsafe".
|
|
4993
5005
|
For instance, the FileName and Directory tags are excluded in the
|
|
4994
5006
|
example above to avoid renaming and moving the destination file.
|
|
4995
5007
|
Also note that the second command above will produce warning
|
|
@@ -5009,9 +5021,9 @@ OPTIONS
|
|
|
5009
5021
|
output. By default, list items are separated by a newline when
|
|
5010
5022
|
extracted with the -b option, but this may be changed (see the -sep
|
|
5011
5023
|
option for details). May be combined with -j, -php or -X to extract
|
|
5012
|
-
binary data in JSON, PHP or XML format, but note that "
|
|
5013
|
-
|
|
5014
|
-
|
|
5024
|
+
binary data in JSON, PHP or XML format, but note that "Unsafe" tags
|
|
5025
|
+
are not extracted as binary unless they are specified explicitly or
|
|
5026
|
+
the API RequestAll option is set to 3 or higher.
|
|
5015
5027
|
|
|
5016
5028
|
With a leading double dash (--b or --binary), tags which contain
|
|
5017
5029
|
binary data are suppressed in the output when reading.
|
|
@@ -5215,7 +5227,7 @@ OPTIONS
|
|
|
5215
5227
|
collapsing adjacent identical group names, but this can be avoided
|
|
5216
5228
|
by placing a colon before the first family number (eg. -g:3:1). Use
|
|
5217
5229
|
the -listg option to list group names for a specified family. The
|
|
5218
|
-
SavePath and SaveFormat
|
|
5230
|
+
API SavePath and SaveFormat options are automatically enabled if
|
|
5219
5231
|
the respective family 5 or 6 group names are requested. See the API
|
|
5220
5232
|
GetGroup documentation for more information.
|
|
5221
5233
|
|
|
@@ -5421,7 +5433,7 @@ OPTIONS
|
|
|
5421
5433
|
|
|
5422
5434
|
produces output like this:
|
|
5423
5435
|
|
|
5424
|
-
-- Generated by ExifTool 12.
|
|
5436
|
+
-- Generated by ExifTool 12.33 --
|
|
5425
5437
|
File: a.jpg - 2003:10:31 15:44:19
|
|
5426
5438
|
(f/5.6, 1/60s, ISO 100)
|
|
5427
5439
|
File: b.jpg - 2006:05:23 11:57:38
|
|
@@ -5438,7 +5450,7 @@ OPTIONS
|
|
|
5438
5450
|
If a specified tag does not exist, a minor warning is issued and
|
|
5439
5451
|
the line with the missing tag is not printed. However, the -f
|
|
5440
5452
|
option may be used to set the value of missing tags to '-' (but
|
|
5441
|
-
this may be configured via the MissingTagValue
|
|
5453
|
+
this may be configured via the API MissingTagValue option), or the
|
|
5442
5454
|
-m option may be used to ignore minor warnings and leave the
|
|
5443
5455
|
missing values empty. Alternatively, -q -q may be used to simply
|
|
5444
5456
|
suppress the warning messages.
|
|
@@ -68,6 +68,7 @@ my %tweakOrder = (
|
|
|
68
68
|
IPTC => 'Exif', # put IPTC after EXIF,
|
|
69
69
|
GPS => 'XMP', # etc...
|
|
70
70
|
Composite => 'Extra',
|
|
71
|
+
CBOR => 'JSON',
|
|
71
72
|
GeoTiff => 'GPS',
|
|
72
73
|
CanonVRD=> 'CanonCustom',
|
|
73
74
|
DJI => 'Casio',
|
|
@@ -459,7 +460,7 @@ According to the specification, integer-format QuickTime date/time tags
|
|
|
459
460
|
should be stored as UTC. Unfortunately, digital cameras often store local
|
|
460
461
|
time values instead (presumably because they don't know the time zone). For
|
|
461
462
|
this reason, by default ExifTool does not assume a time zone for these
|
|
462
|
-
values. However, if the L<QuickTimeUTC|../ExifTool.html#QuickTimeUTC>
|
|
463
|
+
values. However, if the API L<QuickTimeUTC|../ExifTool.html#QuickTimeUTC> option is set, then ExifTool will
|
|
463
464
|
assume these values are properly stored as UTC, and will convert them to
|
|
464
465
|
local time when extracting.
|
|
465
466
|
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
#------------------------------------------------------------------------------
|
|
2
|
+
# File: CBOR.pm
|
|
3
|
+
#
|
|
4
|
+
# Description: Read CBOR format metadata
|
|
5
|
+
#
|
|
6
|
+
# Revisions: 2021-09-30 - P. Harvey Created
|
|
7
|
+
#
|
|
8
|
+
# References: 1) https://c2pa.org/public-draft/
|
|
9
|
+
# 2) https://datatracker.ietf.org/doc/html/rfc7049
|
|
10
|
+
#------------------------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
package Image::ExifTool::CBOR;
|
|
13
|
+
use strict;
|
|
14
|
+
use vars qw($VERSION);
|
|
15
|
+
use Image::ExifTool qw(:DataAccess :Utils);
|
|
16
|
+
use Image::ExifTool::JSON;
|
|
17
|
+
|
|
18
|
+
$VERSION = '1.01';
|
|
19
|
+
|
|
20
|
+
sub ProcessCBOR($$$);
|
|
21
|
+
sub ReadCBORValue($$$$);
|
|
22
|
+
|
|
23
|
+
# optional CBOR type code
|
|
24
|
+
my %cborType6 = (
|
|
25
|
+
0 => 'date/time string',
|
|
26
|
+
1 => 'epoch-based date/time',
|
|
27
|
+
2 => 'positive bignum',
|
|
28
|
+
3 => 'negative bignum',
|
|
29
|
+
4 => 'decimal fraction',
|
|
30
|
+
5 => 'bigfloat',
|
|
31
|
+
21 => 'expected base64url encoding',
|
|
32
|
+
22 => 'expected base64 encoding',
|
|
33
|
+
23 => 'expected base16 encoding',
|
|
34
|
+
24 => 'encoded CBOR data',
|
|
35
|
+
32 => 'URI',
|
|
36
|
+
33 => 'base64url',
|
|
37
|
+
34 => 'base64',
|
|
38
|
+
35 => 'regular expression',
|
|
39
|
+
36 => 'MIME message',
|
|
40
|
+
55799 => 'CBOR magic number',
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
my %cborType7 = (
|
|
44
|
+
20 => 'False',
|
|
45
|
+
21 => 'True',
|
|
46
|
+
22 => 'null',
|
|
47
|
+
23 => 'undef',
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
%Image::ExifTool::CBOR::Main = (
|
|
51
|
+
GROUPS => { 0 => 'JUMBF', 1 => 'CBOR', 2 => 'Other' },
|
|
52
|
+
VARS => { NO_ID => 1 },
|
|
53
|
+
PROCESS_PROC => \&ProcessCBOR,
|
|
54
|
+
NOTES => q{
|
|
55
|
+
The tags below are extracted from CBOR (Concise Binary Object
|
|
56
|
+
Representation) metadata. The C2PA specification uses this format for some
|
|
57
|
+
metadata. As well as these tags, ExifTool will read any existing tags.
|
|
58
|
+
},
|
|
59
|
+
'dc:title' => 'Title',
|
|
60
|
+
'dc:format' => 'Format',
|
|
61
|
+
# my sample file has the following 2 tags in CBOR, but they should be JSON
|
|
62
|
+
authorName => { Name => 'AuthorName', Groups => { 2 => 'Author' } },
|
|
63
|
+
authorIdentifier=> { Name => 'AuthorIdentifier', Groups => { 2 => 'Author' } },
|
|
64
|
+
documentID => { },
|
|
65
|
+
instanceID => { },
|
|
66
|
+
thumbnailHash => { List => 1 },
|
|
67
|
+
thumbnailUrl => { Name => 'ThumbnailURL' },
|
|
68
|
+
relationship => { }
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
#------------------------------------------------------------------------------
|
|
72
|
+
# Read CBOR value
|
|
73
|
+
# Inputs: 0) ExifTool ref, 1) data ref, 2) position in data, 3) data end
|
|
74
|
+
# Returns: 0) value, 1) error string, 2) new data position
|
|
75
|
+
sub ReadCBORValue($$$$)
|
|
76
|
+
{
|
|
77
|
+
my ($et, $dataPt, $pos, $end) = @_;
|
|
78
|
+
return(undef, 'Truncated CBOR data', $pos) if $pos >= $end;
|
|
79
|
+
my $verbose = $$et{OPTIONS}{Verbose};
|
|
80
|
+
my $indent = $$et{INDENT};
|
|
81
|
+
my $dumpStart = $pos;
|
|
82
|
+
my $fmt = Get8u($dataPt, $pos++);
|
|
83
|
+
my $dat = $fmt & 0x1f;
|
|
84
|
+
my ($num, $val, $err, $size);
|
|
85
|
+
$fmt >>= 5;
|
|
86
|
+
if ($dat < 24) {
|
|
87
|
+
$num = $dat;
|
|
88
|
+
} elsif ($dat == 31) { # indefinite count (not used in C2PA)
|
|
89
|
+
$num = -1; # (flag for indefinite count)
|
|
90
|
+
$et->VPrint(1, "$$et{INDENT} (indefinite count):\n");
|
|
91
|
+
} else {
|
|
92
|
+
my $format = { 24 => 'int8u', 25 => 'int16u', 26 => 'int32u', 27 => 'int64u' }->{$dat};
|
|
93
|
+
return(undef, "Invalid CBOR integer type $dat", $pos) unless $format;
|
|
94
|
+
$size = Image::ExifTool::FormatSize($format);
|
|
95
|
+
return(undef, 'Truncated CBOR integer value', $pos) if $pos + $size > $end;
|
|
96
|
+
$num = ReadValue($dataPt, $pos, $format, 1, $size);
|
|
97
|
+
$pos += $size;
|
|
98
|
+
}
|
|
99
|
+
my $pre = '';
|
|
100
|
+
if (defined $$et{cbor_pre} and $fmt != 6) {
|
|
101
|
+
$pre = $$et{cbor_pre};
|
|
102
|
+
delete $$et{cbor_pre};
|
|
103
|
+
}
|
|
104
|
+
if ($fmt == 0) { # positive integer
|
|
105
|
+
$val = $num;
|
|
106
|
+
$et->VPrint(1, "$$et{INDENT} ${pre}int+: $val\n");
|
|
107
|
+
} elsif ($fmt == 1) { # negative integer
|
|
108
|
+
$val = -1 * $num;
|
|
109
|
+
$et->VPrint(1, "$$et{INDENT} ${pre}int-: $val\n");
|
|
110
|
+
} elsif ($fmt == 2 or $fmt == 3) { # byte/UTF8 string
|
|
111
|
+
return(undef, 'Truncated CBOR string value', $pos) if $pos + $num > $end;
|
|
112
|
+
if ($num < 0) { # (should not happen in C2PA)
|
|
113
|
+
my $string = '';
|
|
114
|
+
$$et{INDENT} .= ' ';
|
|
115
|
+
for (;;) {
|
|
116
|
+
($val, $err, $pos) = ReadCBORValue($et, $dataPt, $pos, $end);
|
|
117
|
+
return(undef, $err, $pos) if $err;
|
|
118
|
+
last if not defined $val; # hit the break?
|
|
119
|
+
# (note: strictly we should be checking that this was a string we read)
|
|
120
|
+
$string .= $val;
|
|
121
|
+
}
|
|
122
|
+
$$et{INDENT} = $indent;
|
|
123
|
+
return($string, undef, $pos); # return concatenated byte/text string
|
|
124
|
+
} else {
|
|
125
|
+
$val = substr($$dataPt, $pos, $num);
|
|
126
|
+
}
|
|
127
|
+
$pos += $num;
|
|
128
|
+
if ($fmt == 2) { # (byte string)
|
|
129
|
+
$et->VPrint(1, "$$et{INDENT} ${pre}byte: <binary data ".length($val)." bytes>\n");
|
|
130
|
+
my $dat = $val;
|
|
131
|
+
$val = \$dat; # use scalar reference for binary data
|
|
132
|
+
} else { # (text string)
|
|
133
|
+
$val = $et->Decode($val, 'UTF8');
|
|
134
|
+
$et->VPrint(1, "$$et{INDENT} ${pre}text: '${val}'\n");
|
|
135
|
+
}
|
|
136
|
+
} elsif ($fmt == 4 or $fmt == 5) { # list/hash
|
|
137
|
+
if ($fmt == 4) {
|
|
138
|
+
$et->VPrint(1, "$$et{INDENT} ${pre}list: <$num elements>\n");
|
|
139
|
+
} else {
|
|
140
|
+
$et->VPrint(1, "$$et{INDENT} ${pre}hash: <$num pairs>\n");
|
|
141
|
+
$num *= 2;
|
|
142
|
+
}
|
|
143
|
+
$$et{INDENT} .= ' ';
|
|
144
|
+
my $i = 0;
|
|
145
|
+
my @list;
|
|
146
|
+
Image::ExifTool::HexDump($dataPt, $pos - $dumpStart,
|
|
147
|
+
Start => $dumpStart,
|
|
148
|
+
DataPos => $$et{cbor_datapos},
|
|
149
|
+
Prefix => $$et{INDENT},
|
|
150
|
+
) if $verbose > 2;
|
|
151
|
+
while ($num) {
|
|
152
|
+
$$et{cbor_pre} = "$i) ";
|
|
153
|
+
if ($fmt == 4) {
|
|
154
|
+
++$i;
|
|
155
|
+
} elsif ($num & 0x01) {
|
|
156
|
+
$$et{cbor_pre} = ' ' x length($$et{cbor_pre});
|
|
157
|
+
++$i;
|
|
158
|
+
}
|
|
159
|
+
($val, $err, $pos) = ReadCBORValue($et, $dataPt, $pos, $end);
|
|
160
|
+
return(undef, $err, $pos) if $err;
|
|
161
|
+
if (not defined $val) {
|
|
162
|
+
return(undef, 'Unexpected list terminator', $pos) unless $num < 0;
|
|
163
|
+
last;
|
|
164
|
+
}
|
|
165
|
+
push @list, $val;
|
|
166
|
+
--$num;
|
|
167
|
+
}
|
|
168
|
+
$dumpStart = $pos;
|
|
169
|
+
$$et{INDENT} = $indent;
|
|
170
|
+
if ($fmt == 5) {
|
|
171
|
+
my ($i, @keys);
|
|
172
|
+
my %hash = ( _ordered_keys_ => \@keys );
|
|
173
|
+
for ($i=0; $i<@list-1; $i+=2) {
|
|
174
|
+
$hash{$list[$i]} = $list[$i+1];
|
|
175
|
+
push @keys, $list[$i]; # save ordered list of keys
|
|
176
|
+
}
|
|
177
|
+
$val = \%hash;
|
|
178
|
+
} else {
|
|
179
|
+
$val = \@list;
|
|
180
|
+
}
|
|
181
|
+
} elsif ($fmt == 6) { # optional tag
|
|
182
|
+
if ($verbose) {
|
|
183
|
+
my $str = "$num (" . ($cborType6{$num} || 'unknown') . ')';
|
|
184
|
+
my $spc = $$et{cbor_pre} ? (' ' x length $$et{cbor_pre}) : '';
|
|
185
|
+
$et->VPrint(1, "$$et{INDENT} $spc<CBOR optional type $str>\n");
|
|
186
|
+
Image::ExifTool::HexDump($dataPt, $pos - $dumpStart,
|
|
187
|
+
Start => $dumpStart,
|
|
188
|
+
DataPos => $$et{cbor_datapos},
|
|
189
|
+
Prefix => $$et{INDENT} . ' ',
|
|
190
|
+
) if $verbose > 2;
|
|
191
|
+
}
|
|
192
|
+
# read next value (note: in the case of multiple tags,
|
|
193
|
+
# this nesting will apply the tags in the correct order)
|
|
194
|
+
($val, $err, $pos) = ReadCBORValue($et, $dataPt, $pos, $end);
|
|
195
|
+
$dumpStart = $pos;
|
|
196
|
+
# convert some values according to the optional tag number (untested)
|
|
197
|
+
if ($num == 0 and not ref $val) { # date/time string
|
|
198
|
+
require Image::ExifTool::XMP;
|
|
199
|
+
$val = Image::ExifTool::XMP::ConvertXMPDate($val);
|
|
200
|
+
} elsif ($num == 1 and not ref $val) { # epoch-based date/time
|
|
201
|
+
if (Image::ExifTool::IsFloat($val)) {
|
|
202
|
+
my $dec = ($val == int($val)) ? undef : 6;
|
|
203
|
+
$val = Image::ExifTool::ConvertUnixTime($val, 1, $dec);
|
|
204
|
+
}
|
|
205
|
+
} elsif (($num == 2 or $num == 3) and ref($val) eq 'SCALAR') { # pos/neg bignum
|
|
206
|
+
my $big = 0;
|
|
207
|
+
$big = 256 * $big + Get8u($val,$_) foreach 0..(length($$val) - 1);
|
|
208
|
+
$val = $num==2 ? $big : -$big;
|
|
209
|
+
} elsif (($num == 4 or $num == 5) and # decimal fraction or bigfloat
|
|
210
|
+
ref($val) eq 'ARRAY' and @$val == 2 and
|
|
211
|
+
Image::ExifTool::IsInt($$val[0]) and Image::ExifTool::IsInt($$val[1]))
|
|
212
|
+
{
|
|
213
|
+
$val = $$val[1] * ($num == 4 ? 10 : 2) ** $$val[0];
|
|
214
|
+
}
|
|
215
|
+
} elsif ($fmt == 7) {
|
|
216
|
+
if ($dat == 31) {
|
|
217
|
+
undef $val; # "break" = end of indefinite array/hash (not used in C2PA)
|
|
218
|
+
} elsif ($dat < 24) {
|
|
219
|
+
$val = $cborType7{$num};
|
|
220
|
+
$val = "Unknown ($val)" unless defined $val;
|
|
221
|
+
} elsif ($dat == 25) { # half-precision float
|
|
222
|
+
my $exp = ($num >> 10) & 0x1f;
|
|
223
|
+
my $mant = $num & 0x3ff;
|
|
224
|
+
if ($exp == 0) {
|
|
225
|
+
$val = $mant ** -24;
|
|
226
|
+
$val *= -1 if $num & 0x8000;
|
|
227
|
+
} elsif (exp != 31) {
|
|
228
|
+
$val = ($mant + 1024) ** ($exp - 25);
|
|
229
|
+
$val *= -1 if $num & 0x8000;
|
|
230
|
+
} else {
|
|
231
|
+
$val = $mant == 0 ? '<inf>' : '<nan>';
|
|
232
|
+
}
|
|
233
|
+
} elsif ($dat == 26) { # float
|
|
234
|
+
$val = GetFloat($dataPt, $pos - $size);
|
|
235
|
+
} elsif ($dat == 27) { # double
|
|
236
|
+
$val = GetDouble($dataPt, $pos - $size);
|
|
237
|
+
} else {
|
|
238
|
+
return(undef, "Invalid CBOR type 7 variant $num", $pos);
|
|
239
|
+
}
|
|
240
|
+
$et->VPrint(1, "$$et{INDENT} ${pre}typ7: ".(defined $val ? $val : '<break>')."\n");
|
|
241
|
+
} else {
|
|
242
|
+
return(undef, "Unknown CBOR format $fmt", $pos);
|
|
243
|
+
}
|
|
244
|
+
Image::ExifTool::HexDump($dataPt, $pos - $dumpStart,
|
|
245
|
+
Start => $dumpStart,
|
|
246
|
+
DataPos => $$et{cbor_datapos},
|
|
247
|
+
Prefix => $$et{INDENT} . ' ',
|
|
248
|
+
MaxLen => $verbose < 5 ? ($verbose == 3 ? 96 : 2048) : undef,
|
|
249
|
+
) if $verbose > 2;
|
|
250
|
+
return($val, $err, $pos);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
#------------------------------------------------------------------------------
|
|
254
|
+
# Read CBOR box
|
|
255
|
+
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
|
|
256
|
+
# Returns: 1 on success
|
|
257
|
+
sub ProcessCBOR($$$)
|
|
258
|
+
{
|
|
259
|
+
my ($et, $dirInfo, $tagTablePtr) = @_;
|
|
260
|
+
my $dataPt = $$dirInfo{DataPt};
|
|
261
|
+
my $pos = $$dirInfo{DirStart};
|
|
262
|
+
my $end = $pos + $$dirInfo{DirLen};
|
|
263
|
+
my ($val, $err, $tag, $i);
|
|
264
|
+
|
|
265
|
+
$et->VerboseDir('CBOR', undef, $$dirInfo{DirLen});
|
|
266
|
+
|
|
267
|
+
$$et{cbor_datapos} = $$dirInfo{DataPos} + $$dirInfo{Base};
|
|
268
|
+
|
|
269
|
+
while ($pos < $end) {
|
|
270
|
+
($val, $err, $pos) = ReadCBORValue($et, $dataPt, $pos, $end);
|
|
271
|
+
$err and $et->Warn($err), last;
|
|
272
|
+
if (ref $val eq 'HASH') {
|
|
273
|
+
foreach $tag (@{$$val{_ordered_keys_}}) {
|
|
274
|
+
Image::ExifTool::JSON::ProcessTag($et, $tagTablePtr, $tag, $$val{$tag});
|
|
275
|
+
}
|
|
276
|
+
} elsif (ref $val eq 'ARRAY') {
|
|
277
|
+
for ($i=0; $i<@$val; ++$i) {
|
|
278
|
+
Image::ExifTool::JSON::ProcessTag($et, $tagTablePtr, "Item$i", $$val[$i]);
|
|
279
|
+
}
|
|
280
|
+
} elsif ($val eq '0') {
|
|
281
|
+
$et->VPrint(1, "$$et{INDENT} <CBOR end>\n");
|
|
282
|
+
last; # (treat as padding)
|
|
283
|
+
} else {
|
|
284
|
+
$et->VPrint(1, "$$et{INDENT} Unknown value: $val\n");
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return 1;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
1; # end
|
|
291
|
+
|
|
292
|
+
__END__
|
|
293
|
+
|
|
294
|
+
=head1 NAME
|
|
295
|
+
|
|
296
|
+
Image::ExifTool::CBOR - Read CBOR format metadata
|
|
297
|
+
|
|
298
|
+
=head1 SYNOPSIS
|
|
299
|
+
|
|
300
|
+
This module is used by Image::ExifTool
|
|
301
|
+
|
|
302
|
+
=head1 DESCRIPTION
|
|
303
|
+
|
|
304
|
+
This module contains definitions required by Image::ExifTool read Concise
|
|
305
|
+
Binary Object Representation (CBOR) formatted metadata, used by the C2PA
|
|
306
|
+
specification.
|
|
307
|
+
|
|
308
|
+
=head1 AUTHOR
|
|
309
|
+
|
|
310
|
+
Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
|
|
311
|
+
|
|
312
|
+
This library is free software; you can redistribute it and/or modify it
|
|
313
|
+
under the same terms as Perl itself.
|
|
314
|
+
|
|
315
|
+
=head1 REFERENCES
|
|
316
|
+
|
|
317
|
+
=over 4
|
|
318
|
+
|
|
319
|
+
=item L<https://c2pa.org/public-draft/>
|
|
320
|
+
|
|
321
|
+
=item L<https://datatracker.ietf.org/doc/html/rfc7049>
|
|
322
|
+
|
|
323
|
+
=back
|
|
324
|
+
|
|
325
|
+
=head1 SEE ALSO
|
|
326
|
+
|
|
327
|
+
L<Image::ExifTool::TagNames/CBOR Tags>,
|
|
328
|
+
L<Image::ExifTool(3pm)|Image::ExifTool>
|
|
329
|
+
|
|
330
|
+
=cut
|
|
331
|
+
|
|
@@ -88,7 +88,7 @@ sub ProcessCTMD($$$);
|
|
|
88
88
|
sub ProcessExifInfo($$$);
|
|
89
89
|
sub SwapWords($);
|
|
90
90
|
|
|
91
|
-
$VERSION = '4.
|
|
91
|
+
$VERSION = '4.52';
|
|
92
92
|
|
|
93
93
|
# Note: Removed 'USM' from 'L' lenses since it is redundant - PH
|
|
94
94
|
# (or is it? Ref 32 shows 5 non-USM L-type lenses)
|
|
@@ -187,7 +187,7 @@ $VERSION = '4.51';
|
|
|
187
187
|
37.2 => 'Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical [IF] Macro (A20)', #38
|
|
188
188
|
37.3 => 'Tamron SP AF 17-50mm f/2.8 XR Di II VC LD Aspherical [IF]', #34
|
|
189
189
|
37.4 => 'Tamron AF 18-270mm f/3.5-6.3 Di II VC LD Aspherical [IF] Macro', #forum2937
|
|
190
|
-
38 => 'Canon EF 80-200mm f/4.5-5.6', #32
|
|
190
|
+
38 => 'Canon EF 80-200mm f/4.5-5.6 II', #32 (II added ref https://github.com/Exiv2/exiv2/issues/1906)
|
|
191
191
|
39 => 'Canon EF 75-300mm f/4-5.6',
|
|
192
192
|
40 => 'Canon EF 28-80mm f/3.5-5.6',
|
|
193
193
|
41 => 'Canon EF 28-90mm f/4-5.6', #32
|
|
@@ -595,6 +595,7 @@ $VERSION = '4.51';
|
|
|
595
595
|
'61182.21' => 'Canon RF 70-200mm F4L IS USM', #42
|
|
596
596
|
'61182.22' => 'Canon RF 50mm F1.8 STM', #42
|
|
597
597
|
'61182.23' => 'Canon RF 14-35mm F4L IS USM', #IB
|
|
598
|
+
'61182.24' => 'Canon RF 16mm F2.8 STM', #42
|
|
598
599
|
#'61182.xx' => 'Canon RF 100mm F2.8L MACRO IS USM',
|
|
599
600
|
65535 => 'n/a',
|
|
600
601
|
);
|
|
@@ -6731,7 +6732,17 @@ my %ciMaxFocal = (
|
|
|
6731
6732
|
PrintConvInv => '$val =~ s/ ?m$//; IsFloat($val) ? $val : 655.35',
|
|
6732
6733
|
},
|
|
6733
6734
|
# 22 - values: 0, 1
|
|
6734
|
-
|
|
6735
|
+
23 => { #JohnMoyer (forum12925)
|
|
6736
|
+
Name => 'ShutterMode',
|
|
6737
|
+
PrintConv => {
|
|
6738
|
+
0 => 'Mechanical',
|
|
6739
|
+
1 => 'Electronic First Curtain',
|
|
6740
|
+
2 => 'Electronic',
|
|
6741
|
+
# 3 => ?
|
|
6742
|
+
# 21 => ?
|
|
6743
|
+
# 22 => ?
|
|
6744
|
+
},
|
|
6745
|
+
},
|
|
6735
6746
|
25 => { #PH
|
|
6736
6747
|
Name => 'FlashExposureLock',
|
|
6737
6748
|
PrintConv => \%offOn,
|
|
@@ -6764,7 +6775,8 @@ my %ciMaxFocal = (
|
|
|
6764
6775
|
277 => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF2x',
|
|
6765
6776
|
278 => 'Canon RF 70-200mm F4L IS USM', #42
|
|
6766
6777
|
280 => 'Canon RF 50mm F1.8 STM', #42
|
|
6767
|
-
281 => 'Canon RF 14-35mm F4L IS USM', #IB
|
|
6778
|
+
281 => 'Canon RF 14-35mm F4L IS USM', #42/IB
|
|
6779
|
+
288 => 'Canon RF 16mm F2.8 STM', #42
|
|
6768
6780
|
#xxx => 'Canon RF 100mm F2.8L MACRO IS USM',
|
|
6769
6781
|
# Note: add new RF lenses to %canonLensTypes with ID 61182
|
|
6770
6782
|
},
|