exiftool-vendored.exe 12.26.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 +119 -4
- package/bin/exiftool_files/README +44 -43
- package/bin/exiftool_files/arg_files/xmp2exif.args +2 -1
- package/bin/exiftool_files/config_files/convert_regions.config +25 -14
- package/bin/exiftool_files/config_files/example.config +1 -1
- package/bin/exiftool_files/exiftool.pl +79 -66
- package/bin/exiftool_files/fmt_files/gpx.fmt +1 -1
- package/bin/exiftool_files/fmt_files/gpx_wpt.fmt +1 -1
- package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +11 -3
- package/bin/exiftool_files/lib/Image/ExifTool/CBOR.pm +331 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Canon.pm +26 -7
- package/bin/exiftool_files/lib/Image/ExifTool/DPX.pm +13 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Exif.pm +98 -4
- package/bin/exiftool_files/lib/Image/ExifTool/FlashPix.pm +35 -10
- package/bin/exiftool_files/lib/Image/ExifTool/FujiFilm.pm +1 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +13 -2
- package/bin/exiftool_files/lib/Image/ExifTool/GoPro.pm +16 -1
- package/bin/exiftool_files/lib/Image/ExifTool/ID3.pm +15 -3
- package/bin/exiftool_files/lib/Image/ExifTool/JSON.pm +7 -3
- package/bin/exiftool_files/lib/Image/ExifTool/Jpeg2000.pm +60 -26
- package/bin/exiftool_files/lib/Image/ExifTool/LIF.pm +153 -0
- package/bin/exiftool_files/lib/Image/ExifTool/Lang/nl.pm +60 -59
- package/bin/exiftool_files/lib/Image/ExifTool/M2TS.pm +103 -7
- package/bin/exiftool_files/lib/Image/ExifTool/MacOS.pm +2 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +14 -3
- package/bin/exiftool_files/lib/Image/ExifTool/NikonSettings.pm +10 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +9 -2
- package/bin/exiftool_files/lib/Image/ExifTool/Other.pm +93 -0
- package/bin/exiftool_files/lib/Image/ExifTool/PDF.pm +9 -12
- package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +7 -6
- package/bin/exiftool_files/lib/Image/ExifTool/Panasonic.pm +14 -3
- package/bin/exiftool_files/lib/Image/ExifTool/Pentax.pm +27 -5
- package/bin/exiftool_files/lib/Image/ExifTool/Photoshop.pm +6 -0
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +105 -24
- package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +203 -121
- package/bin/exiftool_files/lib/Image/ExifTool/README +5 -2
- package/bin/exiftool_files/lib/Image/ExifTool/RIFF.pm +6 -1
- package/bin/exiftool_files/lib/Image/ExifTool/Samsung.pm +47 -10
- package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +85 -34
- package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +65 -5
- package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +153 -32
- package/bin/exiftool_files/lib/Image/ExifTool/Torrent.pm +18 -11
- package/bin/exiftool_files/lib/Image/ExifTool/WritePDF.pl +1 -0
- package/bin/exiftool_files/lib/Image/ExifTool/WritePNG.pl +2 -0
- package/bin/exiftool_files/lib/Image/ExifTool/WriteQuickTime.pl +8 -4
- package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +3 -0
- package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +21 -4
- package/bin/exiftool_files/lib/Image/ExifTool/XMP2.pl +3 -1
- package/bin/exiftool_files/lib/Image/ExifTool/XMPStruct.pl +3 -1
- package/bin/exiftool_files/lib/Image/ExifTool/ZISRAW.pm +121 -2
- package/bin/exiftool_files/lib/Image/ExifTool.pm +8867 -8835
- package/bin/exiftool_files/lib/Image/ExifTool.pod +58 -56
- package/package.json +3 -3
|
@@ -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 );
|
|
@@ -4483,47 +4494,48 @@ DESCRIPTION
|
|
|
4483
4494
|
|
|
4484
4495
|
File Types
|
|
4485
4496
|
------------+-------------+-------------+-------------+------------
|
|
4486
|
-
360 r/w |
|
|
4487
|
-
3FR r |
|
|
4488
|
-
3G2 r/w |
|
|
4489
|
-
3GP r/w |
|
|
4490
|
-
A r |
|
|
4491
|
-
AA r |
|
|
4492
|
-
AAE r |
|
|
4493
|
-
AAX r/w |
|
|
4494
|
-
ACR r |
|
|
4495
|
-
AFM r |
|
|
4496
|
-
AI r/w |
|
|
4497
|
-
AIFF r |
|
|
4498
|
-
APE r |
|
|
4499
|
-
ARQ r/w |
|
|
4500
|
-
ARW r/w |
|
|
4501
|
-
ASF r |
|
|
4502
|
-
AVI r |
|
|
4503
|
-
AVIF r/w |
|
|
4504
|
-
AZW r |
|
|
4505
|
-
BMP r |
|
|
4506
|
-
BPG r |
|
|
4507
|
-
BTF r |
|
|
4508
|
-
CHM r |
|
|
4509
|
-
COS r |
|
|
4510
|
-
CR2 r/w |
|
|
4511
|
-
CR3 r/w |
|
|
4512
|
-
CRM r/w |
|
|
4513
|
-
CRW r/w |
|
|
4514
|
-
CS1 r/w |
|
|
4515
|
-
CSV r |
|
|
4516
|
-
CZI r |
|
|
4517
|
-
DCM r |
|
|
4518
|
-
DCP r/w |
|
|
4519
|
-
DCR r |
|
|
4520
|
-
DFONT r |
|
|
4521
|
-
DIVX r |
|
|
4522
|
-
DJVU r |
|
|
4523
|
-
DLL r |
|
|
4524
|
-
DNG r/w |
|
|
4525
|
-
DOC r |
|
|
4526
|
-
DOCX r |
|
|
4497
|
+
360 r/w | DR4 r/w/c | JNG r/w | ODP r | RIFF r
|
|
4498
|
+
3FR r | DSS r | JP2 r/w | ODS r | RSRC r
|
|
4499
|
+
3G2 r/w | DV r | JPEG r/w | ODT r | RTF r
|
|
4500
|
+
3GP r/w | DVB r/w | JSON r | OFR r | RW2 r/w
|
|
4501
|
+
A r | DVR-MS r | JXL r | OGG r | RWL r/w
|
|
4502
|
+
AA r | DYLIB r | K25 r | OGV r | RWZ r
|
|
4503
|
+
AAE r | EIP r | KDC r | ONP r | RM r
|
|
4504
|
+
AAX r/w | EPS r/w | KEY r | OPUS r | SEQ r
|
|
4505
|
+
ACR r | EPUB r | LA r | ORF r/w | SKETCH r
|
|
4506
|
+
AFM r | ERF r/w | LFP r | ORI r/w | SO r
|
|
4507
|
+
AI r/w | EXE r | LIF r | OTF r | SR2 r/w
|
|
4508
|
+
AIFF r | EXIF r/w/c | LNK r | PAC r | SRF r
|
|
4509
|
+
APE r | EXR r | LRV r/w | PAGES r | SRW r/w
|
|
4510
|
+
ARQ r/w | EXV r/w/c | M2TS r | PBM r/w | SVG r
|
|
4511
|
+
ARW r/w | F4A/V r/w | M4A/V r/w | PCD r | SWF r
|
|
4512
|
+
ASF r | FFF r/w | MACOS r | PCX r | THM r/w
|
|
4513
|
+
AVI r | FITS r | MAX r | PDB r | TIFF r/w
|
|
4514
|
+
AVIF r/w | FLA r | MEF r/w | PDF r/w | TORRENT r
|
|
4515
|
+
AZW r | FLAC r | MIE r/w/ | PEF r/w | TTC r
|
|
4516
|
+
BMP r | FLIF r/w | MIFF r c | PFA r | TTF r
|
|
4517
|
+
BPG r | FLV r | MKA r | PFB r | TXT r
|
|
4518
|
+
BTF r | FPF r | MKS r | PFM r | VCF r
|
|
4519
|
+
CHM r | FPX r | MKV r | PGF r | VRD r/w/c
|
|
4520
|
+
COS r | GIF r/w | MNG r/w | PGM r/w | VSD r
|
|
4521
|
+
CR2 r/w | GPR r/w | MOBI r | PLIST r | WAV r
|
|
4522
|
+
CR3 r/w | GZ r | MODD r | PICT r | WDP r/w
|
|
4523
|
+
CRM r/w | HDP r/w | MOI r | PMP r | WEBP r
|
|
4524
|
+
CRW r/w | HDR r | MOS r/w | PNG r/w | WEBM r
|
|
4525
|
+
CS1 r/w | HEIC r/w | MOV r/w | PPM r/w | WMA r
|
|
4526
|
+
CSV r | HEIF r/w | MP3 r | PPT r | WMV r
|
|
4527
|
+
CZI r | HTML r | MP4 r/w | PPTX r | WTV r
|
|
4528
|
+
DCM r | ICC r/w/c | MPC r | PS r/w | WV r
|
|
4529
|
+
DCP r/w | ICS r | MPG r | PSB r/w | X3F r/w
|
|
4530
|
+
DCR r | IDML r | MPO r/w | PSD r/w | XCF r
|
|
4531
|
+
DFONT r | IIQ r/w | MQV r/w | PSP r | XLS r
|
|
4532
|
+
DIVX r | IND r/w | MRC r | QTIF r/w | XLSX r
|
|
4533
|
+
DJVU r | INSP r/w | MRW r/w | R3D r | XMP r/w/c
|
|
4534
|
+
DLL r | INSV r | MXF r | RA r | ZIP r
|
|
4535
|
+
DNG r/w | INX r | NEF r/w | RAF r/w |
|
|
4536
|
+
DOC r | ISO r | NRW r/w | RAM r |
|
|
4537
|
+
DOCX r | ITC r | NUMBERS r | RAR r |
|
|
4538
|
+
DPX r | J2C r | O r | RAW r/w |
|
|
4527
4539
|
|
|
4528
4540
|
Meta Information
|
|
4529
4541
|
----------------------+----------------------+---------------------
|
|
@@ -4728,12 +4740,13 @@ OPTIONS
|
|
|
4728
4740
|
names, prefixed by optional family numbers, and separated colons.
|
|
4729
4741
|
If no group name is specified, the tag is created in the preferred
|
|
4730
4742
|
group, and updated in any other location where a same-named tag
|
|
4731
|
-
already exists. The preferred group
|
|
4732
|
-
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.
|
|
4733
4746
|
|
|
4734
4747
|
The wildcards "*" and "?" may be used in tag names to assign the
|
|
4735
4748
|
same value to multiple tags. When specified with wildcards,
|
|
4736
|
-
"
|
|
4749
|
+
"Unsafe" tags are not written. A tag name of "All" is equivalent to
|
|
4737
4750
|
"*" (except that it doesn't require quoting, while arguments with
|
|
4738
4751
|
wildcards do on systems with shell globbing), and is often used
|
|
4739
4752
|
when deleting all metadata (ie. "-All=") or an entire group (eg.
|
|
@@ -4888,9 +4901,9 @@ OPTIONS
|
|
|
4888
4901
|
Notes:
|
|
4889
4902
|
|
|
4890
4903
|
1) Some tags (generally tags which may affect the appearance of the
|
|
4891
|
-
image) are considered "
|
|
4904
|
+
image) are considered "Unsafe" to write, and are only copied if
|
|
4892
4905
|
specified explicitly (ie. no wildcards). See the tag name
|
|
4893
|
-
documentation for more details about "
|
|
4906
|
+
documentation for more details about "Unsafe" tags.
|
|
4894
4907
|
|
|
4895
4908
|
2) Be aware of the difference between excluding a tag from being
|
|
4896
4909
|
copied (--*TAG*), and deleting a tag (-*TAG*=). Excluding a tag
|
|
@@ -4988,7 +5001,7 @@ OPTIONS
|
|
|
4988
5001
|
exiftool -@ out.args -sep ", " dst.jpg
|
|
4989
5002
|
|
|
4990
5003
|
Note: Be careful when copying information with this technique since
|
|
4991
|
-
it is easy to write tags which are normally considered "
|
|
5004
|
+
it is easy to write tags which are normally considered "Unsafe".
|
|
4992
5005
|
For instance, the FileName and Directory tags are excluded in the
|
|
4993
5006
|
example above to avoid renaming and moving the destination file.
|
|
4994
5007
|
Also note that the second command above will produce warning
|
|
@@ -5008,9 +5021,9 @@ OPTIONS
|
|
|
5008
5021
|
output. By default, list items are separated by a newline when
|
|
5009
5022
|
extracted with the -b option, but this may be changed (see the -sep
|
|
5010
5023
|
option for details). May be combined with -j, -php or -X to extract
|
|
5011
|
-
binary data in JSON, PHP or XML format, but note that "
|
|
5012
|
-
|
|
5013
|
-
|
|
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.
|
|
5014
5027
|
|
|
5015
5028
|
With a leading double dash (--b or --binary), tags which contain
|
|
5016
5029
|
binary data are suppressed in the output when reading.
|
|
@@ -5214,7 +5227,7 @@ OPTIONS
|
|
|
5214
5227
|
collapsing adjacent identical group names, but this can be avoided
|
|
5215
5228
|
by placing a colon before the first family number (eg. -g:3:1). Use
|
|
5216
5229
|
the -listg option to list group names for a specified family. The
|
|
5217
|
-
SavePath and SaveFormat
|
|
5230
|
+
API SavePath and SaveFormat options are automatically enabled if
|
|
5218
5231
|
the respective family 5 or 6 group names are requested. See the API
|
|
5219
5232
|
GetGroup documentation for more information.
|
|
5220
5233
|
|
|
@@ -5420,7 +5433,7 @@ OPTIONS
|
|
|
5420
5433
|
|
|
5421
5434
|
produces output like this:
|
|
5422
5435
|
|
|
5423
|
-
-- Generated by ExifTool 12.
|
|
5436
|
+
-- Generated by ExifTool 12.33 --
|
|
5424
5437
|
File: a.jpg - 2003:10:31 15:44:19
|
|
5425
5438
|
(f/5.6, 1/60s, ISO 100)
|
|
5426
5439
|
File: b.jpg - 2006:05:23 11:57:38
|
|
@@ -5437,7 +5450,7 @@ OPTIONS
|
|
|
5437
5450
|
If a specified tag does not exist, a minor warning is issued and
|
|
5438
5451
|
the line with the missing tag is not printed. However, the -f
|
|
5439
5452
|
option may be used to set the value of missing tags to '-' (but
|
|
5440
|
-
this may be configured via the MissingTagValue
|
|
5453
|
+
this may be configured via the API MissingTagValue option), or the
|
|
5441
5454
|
-m option may be used to ignore minor warnings and leave the
|
|
5442
5455
|
missing values empty. Alternatively, -q -q may be used to simply
|
|
5443
5456
|
suppress the warning messages.
|
|
@@ -5742,9 +5755,9 @@ OPTIONS
|
|
|
5742
5755
|
|
|
5743
5756
|
Note: This output is NOT the same as XMP because it uses
|
|
5744
5757
|
dynamically-generated property names corresponding to the ExifTool
|
|
5745
|
-
tag names
|
|
5746
|
-
|
|
5747
|
-
file.
|
|
5758
|
+
tag names with ExifTool family 1 group names as namespaces, and not
|
|
5759
|
+
the standard XMP properties and namespaces. To write XMP instead,
|
|
5760
|
+
use the -o option with an XMP extension for the output file.
|
|
5748
5761
|
|
|
5749
5762
|
Processing control
|
|
5750
5763
|
-a, --a (-duplicates, --duplicates)
|
|
@@ -6363,7 +6376,7 @@ OPTIONS
|
|
|
6363
6376
|
-efile[*NUM*][!] *ERRFILE*
|
|
6364
6377
|
Save the names of files giving errors (*NUM* missing or 1), files
|
|
6365
6378
|
that were unchanged (*NUM* is 2), files that fail the -if condition
|
|
6366
|
-
(*NUM* is 4), or any combination thereof
|
|
6379
|
+
(*NUM* is 4), or any combination thereof by summing *NUM* (eg.
|
|
6367
6380
|
-efile3 is the same has having both -efile and -efile2 options with
|
|
6368
6381
|
the same *ERRFILE*). By default, file names are appended to any
|
|
6369
6382
|
existing *ERRFILE*, but *ERRFILE* is overwritten if an exclamation
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# 2019/10/24 - PH Preserve sub-seconds in GPSDateTime value
|
|
14
14
|
#
|
|
15
15
|
# Notes: 1) Input file(s) must contain GPSLatitude and GPSLongitude.
|
|
16
|
-
# 2) The -
|
|
16
|
+
# 2) The -ee3 option is to extract the full track from video files.
|
|
17
17
|
# 3) The -fileOrder option may be used to control the order of the
|
|
18
18
|
# generated track points when processing multiple files.
|
|
19
19
|
#------------------------------------------------------------------------------
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
# 2019/10/24 - PH Preserve sub-seconds in GPSDateTime value
|
|
15
15
|
#
|
|
16
16
|
# Notes: 1) Input file(s) must contain GPSLatitude and GPSLongitude.
|
|
17
|
-
# 2) The -
|
|
17
|
+
# 2) The -ee3 option is to extract the full track from video files.
|
|
18
18
|
# 3) The -fileOrder option may be used to control the order of the
|
|
19
19
|
# generated track points when processing multiple files.
|
|
20
20
|
#------------------------------------------------------------------------------
|
|
@@ -35,7 +35,7 @@ use Image::ExifTool::Sony;
|
|
|
35
35
|
use Image::ExifTool::Validate;
|
|
36
36
|
use Image::ExifTool::MacOS;
|
|
37
37
|
|
|
38
|
-
$VERSION = '3.
|
|
38
|
+
$VERSION = '3.45';
|
|
39
39
|
@ISA = qw(Exporter);
|
|
40
40
|
|
|
41
41
|
sub NumbersFirst($$);
|
|
@@ -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
|
|
|
@@ -2117,7 +2118,7 @@ sub WriteTagNames($$)
|
|
|
2117
2118
|
$short = $$shortName{$tableName};
|
|
2118
2119
|
my @names = split ' ', $short;
|
|
2119
2120
|
my $class = shift @names;
|
|
2120
|
-
if (@names) {
|
|
2121
|
+
if (@names and $class ne 'Other') {
|
|
2121
2122
|
# add heading for tables without a Main
|
|
2122
2123
|
unless ($heading eq $class) {
|
|
2123
2124
|
$heading = $class;
|
|
@@ -2145,6 +2146,13 @@ sub WriteTagNames($$)
|
|
|
2145
2146
|
$short = $$shortName{$tableName};
|
|
2146
2147
|
$short = $tableName unless $short;
|
|
2147
2148
|
$url = "$short.html";
|
|
2149
|
+
# handle various tables in "Other.pm"
|
|
2150
|
+
if ($short =~ /^Other (.*)/) {
|
|
2151
|
+
$short = $1;
|
|
2152
|
+
$url = 'Other.html#' . $1;
|
|
2153
|
+
} else {
|
|
2154
|
+
$url = "$short.html";
|
|
2155
|
+
}
|
|
2148
2156
|
print HTMLFILE "<a href='${url}'>$short</a>";
|
|
2149
2157
|
++$count;
|
|
2150
2158
|
}
|
|
@@ -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
|
+
|