exiftool-vendored.pl 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/Changes +36 -4
- package/bin/MANIFEST +2 -0
- package/bin/META.json +1 -1
- package/bin/META.yml +1 -1
- package/bin/README +2 -2
- package/bin/arg_files/xmp2exif.args +2 -1
- package/bin/exiftool +18 -16
- package/bin/lib/Image/ExifTool/BuildTagLookup.pm +2 -1
- package/bin/lib/Image/ExifTool/CBOR.pm +331 -0
- package/bin/lib/Image/ExifTool/Canon.pm +16 -4
- package/bin/lib/Image/ExifTool/Exif.pm +97 -3
- package/bin/lib/Image/ExifTool/Geotag.pm +13 -2
- package/bin/lib/Image/ExifTool/JSON.pm +7 -3
- package/bin/lib/Image/ExifTool/Jpeg2000.pm +47 -14
- package/bin/lib/Image/ExifTool/MacOS.pm +2 -2
- package/bin/lib/Image/ExifTool/Nikon.pm +2 -1
- package/bin/lib/Image/ExifTool/Olympus.pm +5 -1
- package/bin/lib/Image/ExifTool/Panasonic.pm +2 -2
- package/bin/lib/Image/ExifTool/Pentax.pm +2 -1
- package/bin/lib/Image/ExifTool/QuickTime.pm +8 -1
- package/bin/lib/Image/ExifTool/QuickTimeStream.pl +86 -78
- package/bin/lib/Image/ExifTool/README +5 -2
- package/bin/lib/Image/ExifTool/Sony.pm +5 -3
- package/bin/lib/Image/ExifTool/TagLookup.pm +31 -2
- package/bin/lib/Image/ExifTool/TagNames.pod +59 -8
- package/bin/lib/Image/ExifTool/XMP.pm +7 -2
- package/bin/lib/Image/ExifTool/XMP2.pl +1 -0
- package/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
- package/bin/lib/Image/ExifTool.pm +16 -13
- package/bin/lib/Image/ExifTool.pod +3 -3
- package/bin/perl-Image-ExifTool.spec +1 -1
- package/bin/pp_build_exe.args +5 -4
- package/package.json +2 -2
package/bin/Changes
CHANGED
|
@@ -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)
|
package/bin/MANIFEST
CHANGED
|
@@ -48,6 +48,7 @@ html/TagNames/Apple.html
|
|
|
48
48
|
html/TagNames/Audible.html
|
|
49
49
|
html/TagNames/BMP.html
|
|
50
50
|
html/TagNames/BPG.html
|
|
51
|
+
html/TagNames/CBOR.html
|
|
51
52
|
html/TagNames/Canon.html
|
|
52
53
|
html/TagNames/CanonCustom.html
|
|
53
54
|
html/TagNames/CanonRaw.html
|
|
@@ -217,6 +218,7 @@ lib/Image/ExifTool/BPG.pm
|
|
|
217
218
|
lib/Image/ExifTool/BZZ.pm
|
|
218
219
|
lib/Image/ExifTool/BigTIFF.pm
|
|
219
220
|
lib/Image/ExifTool/BuildTagLookup.pm
|
|
221
|
+
lib/Image/ExifTool/CBOR.pm
|
|
220
222
|
lib/Image/ExifTool/Canon.pm
|
|
221
223
|
lib/Image/ExifTool/CanonCustom.pm
|
|
222
224
|
lib/Image/ExifTool/CanonRaw.pm
|
package/bin/META.json
CHANGED
package/bin/META.yml
CHANGED
package/bin/README
CHANGED
|
@@ -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
|
package/bin/exiftool
CHANGED
|
@@ -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) {
|
|
@@ -2285,7 +2285,7 @@ TAG: foreach $tag (@foundTags) {
|
|
|
2285
2285
|
# avoid extracting Protected binary tags (eg. data blocks) [insider information]
|
|
2286
2286
|
my $lcTag = lc $tag;
|
|
2287
2287
|
$lcTag =~ s/ .*//;
|
|
2288
|
-
next unless $$et{REQ_TAG_LOOKUP}{$lcTag};
|
|
2288
|
+
next unless $$et{REQ_TAG_LOOKUP}{$lcTag} or ($$et{OPTIONS}{RequestAll} || 0) > 2;
|
|
2289
2289
|
}
|
|
2290
2290
|
$val = ConvertBinary($val); # convert SCALAR references
|
|
2291
2291
|
next unless defined $val;
|
|
@@ -3250,7 +3250,8 @@ sub FormatXML($$$)
|
|
|
3250
3250
|
} elsif (ref $val eq 'HASH') {
|
|
3251
3251
|
$gt = " rdf:parseType='Resource'>";
|
|
3252
3252
|
my $val2 = '';
|
|
3253
|
-
|
|
3253
|
+
my @keys = $$val{_ordered_keys_} ? @{$$val{_ordered_keys_}} : sort keys %$val;
|
|
3254
|
+
foreach (@keys) {
|
|
3254
3255
|
# (some variable-namespace XML structure fields may have a different group)
|
|
3255
3256
|
my $tok = /:/ ? $_ : ($grp . ':' . $_);
|
|
3256
3257
|
$val2 .= "\n$ind <$tok" . FormatXML($$val{$_}, "$ind ", $grp) . "</$tok>";
|
|
@@ -3327,7 +3328,8 @@ sub FormatJSON($$$)
|
|
|
3327
3328
|
} elsif (ref $val eq 'HASH') {
|
|
3328
3329
|
my ($bra, $ket, $sep) = $json == 1 ? ('{','}',':') : ('Array(',')',' =>');
|
|
3329
3330
|
print $fp $bra;
|
|
3330
|
-
|
|
3331
|
+
my @keys = $$val{_ordered_keys_} ? @{$$val{_ordered_keys_}} : sort keys %$val;
|
|
3332
|
+
foreach (@keys) {
|
|
3331
3333
|
print $fp ',' if $comma;
|
|
3332
3334
|
my $key = EscapeJSON($_, 1);
|
|
3333
3335
|
print $fp qq(\n$ind $key$sep );
|
|
@@ -4730,11 +4732,11 @@ I<TAG> may contain one or more leading family 0, 1, 2 or 7 group names,
|
|
|
4730
4732
|
prefixed by optional family numbers, and separated colons. If no group name
|
|
4731
4733
|
is specified, the tag is created in the preferred group, and updated in any
|
|
4732
4734
|
other location where a same-named tag already exists. The preferred group
|
|
4733
|
-
is the first group in the following list
|
|
4734
|
-
IPTC, 3) XMP.
|
|
4735
|
+
in JPEG and TIFF-format images is the first group in the following list
|
|
4736
|
+
where I<TAG> is valid: 1) EXIF, 2) IPTC, 3) XMP.
|
|
4735
4737
|
|
|
4736
4738
|
The wildcards C<*> and C<?> may be used in tag names to assign the same
|
|
4737
|
-
value to multiple tags. When specified with wildcards, "
|
|
4739
|
+
value to multiple tags. When specified with wildcards, "Unsafe" tags are
|
|
4738
4740
|
not written. A tag name of C<All> is equivalent to C<*> (except that it
|
|
4739
4741
|
doesn't require quoting, while arguments with wildcards do on systems with
|
|
4740
4742
|
shell globbing), and is often used when deleting all metadata (ie. C<-All=>)
|
|
@@ -4880,10 +4882,10 @@ See L</COPYING EXAMPLES> for examples using B<-tagsFromFile>.
|
|
|
4880
4882
|
Notes:
|
|
4881
4883
|
|
|
4882
4884
|
1) Some tags (generally tags which may affect the appearance of the image)
|
|
4883
|
-
are considered "
|
|
4885
|
+
are considered "Unsafe" to write, and are only copied if specified
|
|
4884
4886
|
explicitly (ie. no wildcards). See the
|
|
4885
4887
|
L<tag name documentation|Image::ExifTool::TagNames> for more details about
|
|
4886
|
-
"
|
|
4888
|
+
"Unsafe" tags.
|
|
4887
4889
|
|
|
4888
4890
|
2) Be aware of the difference between excluding a tag from being copied
|
|
4889
4891
|
(--I<TAG>), and deleting a tag (-I<TAG>=). Excluding a tag prevents it from
|
|
@@ -4981,7 +4983,7 @@ intermediate file (C<out.args> in this example):
|
|
|
4981
4983
|
exiftool -@ out.args -sep ', ' dst.jpg
|
|
4982
4984
|
|
|
4983
4985
|
Note: Be careful when copying information with this technique since it is
|
|
4984
|
-
easy to write tags which are normally considered "
|
|
4986
|
+
easy to write tags which are normally considered "Unsafe". For instance,
|
|
4985
4987
|
the FileName and Directory tags are excluded in the example above to avoid
|
|
4986
4988
|
renaming and moving the destination file. Also note that the second command
|
|
4987
4989
|
above will produce warning messages for any tags which are not writable.
|
|
@@ -5001,8 +5003,8 @@ are in the default output. By default, list items are separated by a
|
|
|
5001
5003
|
newline when extracted with the B<-b> option, but this may be changed (see
|
|
5002
5004
|
the B<-sep> option for details). May be combined with B<-j>, B<-php> or
|
|
5003
5005
|
B<-X> to extract binary data in JSON, PHP or XML format, but note that
|
|
5004
|
-
"
|
|
5005
|
-
|
|
5006
|
+
"Unsafe" tags are not extracted as binary unless they are specified explicitly or
|
|
5007
|
+
the API RequestAll option is set to 3 or higher.
|
|
5006
5008
|
|
|
5007
5009
|
With a leading double dash (B<--b> or B<--binary>), tags which contain
|
|
5008
5010
|
binary data are suppressed in the output when reading.
|
|
@@ -5203,7 +5205,7 @@ By default the resulting group name is simplified by removing any leading
|
|
|
5203
5205
|
C<Main:> and collapsing adjacent identical group names, but this can be
|
|
5204
5206
|
avoided by placing a colon before the first family number (eg. B<-g:3:1>).
|
|
5205
5207
|
Use the B<-listg> option to list group names for a specified family. The
|
|
5206
|
-
SavePath and SaveFormat
|
|
5208
|
+
API SavePath and SaveFormat options are automatically enabled if the
|
|
5207
5209
|
respective family 5 or 6 group names are requested. See the
|
|
5208
5210
|
L<API GetGroup documentation|Image::ExifTool/GetGroup> for more information.
|
|
5209
5211
|
|
|
@@ -5406,7 +5408,7 @@ with this command:
|
|
|
5406
5408
|
|
|
5407
5409
|
produces output like this:
|
|
5408
5410
|
|
|
5409
|
-
-- Generated by ExifTool 12.
|
|
5411
|
+
-- Generated by ExifTool 12.33 --
|
|
5410
5412
|
File: a.jpg - 2003:10:31 15:44:19
|
|
5411
5413
|
(f/5.6, 1/60s, ISO 100)
|
|
5412
5414
|
File: b.jpg - 2006:05:23 11:57:38
|
|
@@ -5423,7 +5425,7 @@ are effectively processed as separate input files.
|
|
|
5423
5425
|
If a specified tag does not exist, a minor warning is issued and the line
|
|
5424
5426
|
with the missing tag is not printed. However, the B<-f> option may be used
|
|
5425
5427
|
to set the value of missing tags to '-' (but this may be configured via the
|
|
5426
|
-
MissingTagValue
|
|
5428
|
+
API MissingTagValue option), or the B<-m> option may be used to ignore minor
|
|
5427
5429
|
warnings and leave the missing values empty. Alternatively, B<-q -q> may be
|
|
5428
5430
|
used to simply suppress the warning messages.
|
|
5429
5431
|
|
|
@@ -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
|
},
|