exiftool_vendored 11.98.0 → 12.10.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.
- checksums.yaml +4 -4
- data/bin/Changes +198 -2
- data/bin/MANIFEST +8 -0
- data/bin/META.json +1 -1
- data/bin/META.yml +1 -1
- data/bin/README +43 -42
- data/bin/exiftool +102 -75
- data/bin/lib/Image/ExifTool.pm +163 -111
- data/bin/lib/Image/ExifTool.pod +127 -93
- data/bin/lib/Image/ExifTool/AIFF.pm +2 -2
- data/bin/lib/Image/ExifTool/APE.pm +2 -2
- data/bin/lib/Image/ExifTool/BuildTagLookup.pm +21 -10
- data/bin/lib/Image/ExifTool/Canon.pm +202 -14
- data/bin/lib/Image/ExifTool/CanonCustom.pm +82 -16
- data/bin/lib/Image/ExifTool/DPX.pm +56 -2
- data/bin/lib/Image/ExifTool/DarwinCore.pm +22 -3
- data/bin/lib/Image/ExifTool/EXE.pm +8 -5
- data/bin/lib/Image/ExifTool/Exif.pm +15 -6
- data/bin/lib/Image/ExifTool/Font.pm +9 -2
- data/bin/lib/Image/ExifTool/GIF.pm +6 -1
- data/bin/lib/Image/ExifTool/GeoTiff.pm +2 -0
- data/bin/lib/Image/ExifTool/Geotag.pm +2 -2
- data/bin/lib/Image/ExifTool/GoPro.pm +48 -22
- data/bin/lib/Image/ExifTool/H264.pm +1 -1
- data/bin/lib/Image/ExifTool/ID3.pm +91 -12
- data/bin/lib/Image/ExifTool/IPTC.pm +1 -0
- data/bin/lib/Image/ExifTool/JSON.pm +27 -4
- data/bin/lib/Image/ExifTool/Lang/de.pm +3 -1
- data/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
- data/bin/lib/Image/ExifTool/M2TS.pm +19 -19
- data/bin/lib/Image/ExifTool/MacOS.pm +154 -38
- data/bin/lib/Image/ExifTool/Matroska.pm +3 -1
- data/bin/lib/Image/ExifTool/Minolta.pm +7 -2
- data/bin/lib/Image/ExifTool/MinoltaRaw.pm +11 -10
- data/bin/lib/Image/ExifTool/Nikon.pm +164 -20
- data/bin/lib/Image/ExifTool/Olympus.pm +39 -17
- data/bin/lib/Image/ExifTool/PNG.pm +14 -3
- data/bin/lib/Image/ExifTool/PPM.pm +5 -5
- data/bin/lib/Image/ExifTool/Panasonic.pm +148 -14
- data/bin/lib/Image/ExifTool/PanasonicRaw.pm +34 -0
- data/bin/lib/Image/ExifTool/Parrot.pm +2 -1
- data/bin/lib/Image/ExifTool/Pentax.pm +3 -1
- data/bin/lib/Image/ExifTool/Photoshop.pm +2 -1
- data/bin/lib/Image/ExifTool/QuickTime.pm +289 -37
- data/bin/lib/Image/ExifTool/QuickTimeStream.pl +419 -60
- data/bin/lib/Image/ExifTool/README +26 -22
- data/bin/lib/Image/ExifTool/RSRC.pm +17 -11
- data/bin/lib/Image/ExifTool/RTF.pm +12 -7
- data/bin/lib/Image/ExifTool/Radiance.pm +7 -2
- data/bin/lib/Image/ExifTool/Ricoh.pm +19 -1
- data/bin/lib/Image/ExifTool/Shift.pl +1 -0
- data/bin/lib/Image/ExifTool/SigmaRaw.pm +40 -33
- data/bin/lib/Image/ExifTool/Sony.pm +426 -40
- data/bin/lib/Image/ExifTool/TagLookup.pm +5799 -5671
- data/bin/lib/Image/ExifTool/TagNames.pod +584 -97
- data/bin/lib/Image/ExifTool/Validate.pm +4 -4
- data/bin/lib/Image/ExifTool/WriteExif.pl +3 -2
- data/bin/lib/Image/ExifTool/WriteQuickTime.pl +26 -18
- data/bin/lib/Image/ExifTool/Writer.pl +47 -24
- data/bin/lib/Image/ExifTool/XMP.pm +99 -17
- data/bin/lib/Image/ExifTool/XMP2.pl +1 -0
- data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
- data/bin/lib/Image/ExifTool/ZISRAW.pm +123 -0
- data/bin/perl-Image-ExifTool.spec +42 -41
- data/lib/exiftool_vendored/version.rb +1 -1
- metadata +8 -7
|
@@ -20,7 +20,7 @@ use strict;
|
|
|
20
20
|
use vars qw($VERSION);
|
|
21
21
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
22
22
|
|
|
23
|
-
$VERSION = '1.
|
|
23
|
+
$VERSION = '1.18';
|
|
24
24
|
|
|
25
25
|
# road map of directory locations in GIF images
|
|
26
26
|
my %gifMap = (
|
|
@@ -115,6 +115,11 @@ my %gifMap = (
|
|
|
115
115
|
ValueConv => '$val + 1',
|
|
116
116
|
},
|
|
117
117
|
5 => 'BackgroundColor',
|
|
118
|
+
6 => {
|
|
119
|
+
Name => 'PixelAspectRatio',
|
|
120
|
+
RawConv => '$val ? $val : undef',
|
|
121
|
+
ValueConv => '($val + 15) / 64',
|
|
122
|
+
},
|
|
118
123
|
);
|
|
119
124
|
|
|
120
125
|
# GIF Netscape 2.0 animation extension (ref 3)
|
|
@@ -573,6 +573,8 @@ my %epsg_vertcs = (
|
|
|
573
573
|
3053 => 'Hjorsey 1955 Lambert',
|
|
574
574
|
3057 => 'ISN93 Lambert 1993',
|
|
575
575
|
3300 => 'Estonian Coordinate System of 1992',
|
|
576
|
+
3786 => 'Popular Visualisation CRS / Mercator', #PH (NC)
|
|
577
|
+
3857 => 'WGS 84 / Pseudo-Mercator', #PH (NC)
|
|
576
578
|
20137 => 'Adindan UTM zone 37N',
|
|
577
579
|
20138 => 'Adindan UTM zone 38N',
|
|
578
580
|
20248 => 'AGD66 AMG zone 48',
|
|
@@ -27,7 +27,7 @@ use vars qw($VERSION);
|
|
|
27
27
|
use Image::ExifTool qw(:Public);
|
|
28
28
|
use Image::ExifTool::GPS;
|
|
29
29
|
|
|
30
|
-
$VERSION = '1.
|
|
30
|
+
$VERSION = '1.63';
|
|
31
31
|
|
|
32
32
|
sub JITTER() { return 2 } # maximum time jitter
|
|
33
33
|
|
|
@@ -217,7 +217,7 @@ sub LoadTrackLog($$;$)
|
|
|
217
217
|
# (don't set format yet because we want to read HFDTE first)
|
|
218
218
|
$nmeaStart = 'B' ;
|
|
219
219
|
next;
|
|
220
|
-
} elsif (/^HFDTE(\d{2})(\d{2})(\d{2})/) {
|
|
220
|
+
} elsif (/^HFDTE(?:DATE:)?(\d{2})(\d{2})(\d{2})/) {
|
|
221
221
|
my $year = $3 + ($3 >= 70 ? 1900 : 2000);
|
|
222
222
|
$dateFlarm = Time::Local::timegm(0,0,0,$1,$2-1,$year);
|
|
223
223
|
$nmeaStart = 'B' ;
|
|
@@ -16,7 +16,7 @@ use vars qw($VERSION);
|
|
|
16
16
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
17
17
|
use Image::ExifTool::QuickTime;
|
|
18
18
|
|
|
19
|
-
$VERSION = '1.
|
|
19
|
+
$VERSION = '1.06';
|
|
20
20
|
|
|
21
21
|
sub ProcessGoPro($$$);
|
|
22
22
|
sub ProcessString($$$);
|
|
@@ -77,6 +77,9 @@ my %addUnits = (
|
|
|
77
77
|
Notes => 'accelerator readings in m/s2',
|
|
78
78
|
Binary => 1,
|
|
79
79
|
},
|
|
80
|
+
# ANGX (GPMF-GEOC) - seen -0.05 (fmt d, Max)
|
|
81
|
+
# ANGY (GPMF-GEOC) - seen 179.9 (fmt d, Max)
|
|
82
|
+
# ANGZ (GPMF-GEOC) - seen 0.152 (fmt d, Max)
|
|
80
83
|
ALLD => 'AutoLowLightDuration', #1 (gpmd) (untested)
|
|
81
84
|
# APTO (GPMF) - seen: 'RAW', 'DYNM' (fmt c)
|
|
82
85
|
ATTD => { #PH (Karma)
|
|
@@ -105,16 +108,14 @@ my %addUnits = (
|
|
|
105
108
|
},
|
|
106
109
|
# BRID (GPMF) - seen: 0 (fmt B)
|
|
107
110
|
# BROD (GPMF) - seen: 'ASK','' (fmt c)
|
|
111
|
+
# CALH (GPMF-GEOC) - seen 3040 (fmt L, Max)
|
|
112
|
+
# CALW (GPMF-GEOC) - seen 4056 (fmt L, Max)
|
|
108
113
|
CASN => 'CameraSerialNumber', #PH (GPMF - seen: 'C3221324545448', fmt c)
|
|
109
|
-
# CINF (GPMF) - seen: 0x67376be7709bc8876a8baf3940908618, 0xe230988539b30cf5f016627ae8fc5395
|
|
110
|
-
#
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
# TYPE=LLLLLfffBB
|
|
115
|
-
# SCAL=1000 1 1 1 1 1 1 1 1 1
|
|
116
|
-
Binary => 1,
|
|
117
|
-
},
|
|
114
|
+
# CINF (GPMF) - seen: 0x67376be7709bc8876a8baf3940908618, 0xe230988539b30cf5f016627ae8fc5395,
|
|
115
|
+
# 0x8bcbe424acc5b37d7d77001635198b3b (fmt B) (Camera INFormation?)
|
|
116
|
+
# CMOD (GPMF) - seen: 12,13,17 [12 360 video, 13 time-laps video, 17 JPEG] (fmt B)
|
|
117
|
+
# CRTX (GPMF-BACK/FRNT) - double[1]
|
|
118
|
+
# CRTY (GPMF-BACK/FRNT) - double[1]
|
|
118
119
|
CSEN => { #PH (Karma)
|
|
119
120
|
Name => 'CoyoteSense',
|
|
120
121
|
# UNIT=s,rad/s,rad/s,rad/s,g,g,g,,,,
|
|
@@ -122,13 +123,27 @@ my %addUnits = (
|
|
|
122
123
|
# SCAL=1000 1 1 1 1 1 1 1 1 1 1
|
|
123
124
|
Binary => 1,
|
|
124
125
|
},
|
|
126
|
+
CYTS => { #PH (Karma)
|
|
127
|
+
Name => 'CoyoteStatus',
|
|
128
|
+
# UNIT=s,,,,,rad,rad,rad,,
|
|
129
|
+
# TYPE=LLLLLfffBB
|
|
130
|
+
# SCAL=1000 1 1 1 1 1 1 1 1 1
|
|
131
|
+
Binary => 1,
|
|
132
|
+
},
|
|
125
133
|
DEVC => { #PH (gpmd,GPMF, fmt \0)
|
|
126
134
|
Name => 'DeviceContainer',
|
|
127
135
|
SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' },
|
|
128
|
-
|
|
129
|
-
|
|
136
|
+
# (Max) DVID=1,DVNM='Global Settings',VERS,FMWR,LINF,CINF,CASN,MINF,MUID,CMOD,MTYP,OREN,
|
|
137
|
+
# DZOM,DZST,SMTR,PRTN,PTWB,PTSH,PTCL,EXPT,PIMX,PIMN,PTEV,RATE,SROT,ZFOV,VLTE,VLTA,
|
|
138
|
+
# EISE,EISA,AUPT,AUDO,BROD,BRID,PVUL,PRJT,SOFF
|
|
139
|
+
# (Max) DVID='GEOC',DVNM='Geometry Calibrations',SHFX,SHFY,SHFZ,ANGX,ANGY,ANGZ,CALW,CALH
|
|
140
|
+
# (Max) DVID='BACK',DVNM='Back Lens',KLNS,CTRX,CTRY,MFOV,SFTR
|
|
141
|
+
# (Max) DVID='FRNT',DVNM='Front Lens',KLNS,CTRX,CTRY,MFOV,SFTR
|
|
142
|
+
# (Max) DVID='HLMT',DVNM='Highlights'
|
|
143
|
+
},
|
|
144
|
+
# DVID (GPMF) - DeviceID; seen: 1 (fmt L), HLMT (fmt F), GEOC (fmt F), 'BACK' (fmt F, Max)
|
|
130
145
|
DVID => { Name => 'DeviceID', Unknown => 1 }, #2 (gpmd)
|
|
131
|
-
# DVNM (GPMF) seen: 'Video Global Settings' (fmt c), 'Highlights' (fmt c)
|
|
146
|
+
# DVNM (GPMF) seen: 'Video Global Settings' (fmt c), 'Highlights' (fmt c), 'Geometry Calibrations' (Max)
|
|
132
147
|
# DVNM (gpmd) seen: 'Camera' (Hero5), 'Hero6 Black' (Hero6), 'GoPro Karma v1.0' (Karma)
|
|
133
148
|
DVNM => 'DeviceName', #PH (n/c)
|
|
134
149
|
DZOM => { #PH (GPMF - seen: 'Y', fmt c)
|
|
@@ -136,10 +151,10 @@ my %addUnits = (
|
|
|
136
151
|
PrintConv => { N => 'No', Y => 'Yes' },
|
|
137
152
|
},
|
|
138
153
|
# DZST (GPMF) - seen: 0 (fmt L) (something to do with digital zoom maybe?)
|
|
139
|
-
EISA => { #PH (GPMF) - seen: 'Y','N',
|
|
154
|
+
EISA => { #PH (GPMF) - seen: 'Y','N','HS EIS','N/A' (fmt c) [N was for a time-lapse video]
|
|
140
155
|
Name => 'ElectronicImageStabilization',
|
|
141
156
|
},
|
|
142
|
-
# EISE (GPMF) - seen: 'Y' (fmt c)
|
|
157
|
+
# EISE (GPMF) - seen: 'Y','N' (fmt c)
|
|
143
158
|
EMPT => { Name => 'Empty', Unknown => 1 }, #2 (gpmd)
|
|
144
159
|
ESCS => { #PH (Karma)
|
|
145
160
|
Name => 'EscapeStatus',
|
|
@@ -215,7 +230,8 @@ my %addUnits = (
|
|
|
215
230
|
RawConv => '$val', # necessary to use scaled value instead of raw data as subdir data
|
|
216
231
|
SubDirectory => { TagTable => 'Image::ExifTool::GoPro::KBAT' },
|
|
217
232
|
},
|
|
218
|
-
#
|
|
233
|
+
# KLNS (GPMF-BACK/FRNT) - double[5] (fmt d, Max)
|
|
234
|
+
# LINF (GPMF) - seen: LAJ7061916601668,C3341326002180,C33632245450981 (fmt c) (Lens INFormation?)
|
|
219
235
|
LNED => { #PH (Karma)
|
|
220
236
|
Name => 'LocalPositionNED',
|
|
221
237
|
# UNIT=s,m,m,m,m/s,m/s,m/s
|
|
@@ -224,12 +240,13 @@ my %addUnits = (
|
|
|
224
240
|
Binary => 1,
|
|
225
241
|
},
|
|
226
242
|
MAGN => 'Magnetometer', #1 (gpmd) (units of uT)
|
|
243
|
+
# MFOV (GPMF-BACK/FRNT) - seen: 100 (fmt d, Max)
|
|
227
244
|
MINF => { #PH (GPMF - seen: HERO6 Black, fmt c)
|
|
228
245
|
Name => 'Model',
|
|
229
246
|
Groups => { 2 => 'Camera' },
|
|
230
247
|
Description => 'Camera Model Name',
|
|
231
248
|
},
|
|
232
|
-
# MTYP (GPMF) - seen: 0,1,11 [1 for time-lapse video, 11 for JPEG] (fmt B)
|
|
249
|
+
# MTYP (GPMF) - seen: 0,1,5,11 [1 for time-lapse video, 5 for 360 video, 11 for JPEG] (fmt B)
|
|
233
250
|
# MUID (GPMF) - seen: 3882563431 2278071152 967805802 411471936 0 0 0 0 (fmt L)
|
|
234
251
|
OREN => { #PH (GPMF - seen: 'U', fmt c)
|
|
235
252
|
Name => 'AutoRotation',
|
|
@@ -245,7 +262,7 @@ my %addUnits = (
|
|
|
245
262
|
PIMX => 'AutoISOMax', #PH (GPMF - seen: 1600, fmt L)
|
|
246
263
|
# PRAW (APP6) - seen: 0, 'N', 'Y' (fmt c)
|
|
247
264
|
PRES => 'PhotoResolution', #PH (APP6 - seen: '12MP_W')
|
|
248
|
-
# PRJT (APP6) - seen: 'GPRO' (fmt F, Hero8)
|
|
265
|
+
# PRJT (APP6) - seen: 'GPRO','EACO' (fmt F, Hero8, Max)
|
|
249
266
|
PRTN => { #PH (GPMF - seen: 'N', fmt c)
|
|
250
267
|
Name => 'ProTune',
|
|
251
268
|
PrintConv => {
|
|
@@ -257,7 +274,7 @@ my %addUnits = (
|
|
|
257
274
|
PTEV => 'ExposureCompensation', #PH (GPMF - seen: '0.0', fmt c)
|
|
258
275
|
PTSH => 'Sharpness', #PH (GPMF - seen: 'HIGH', fmt c)
|
|
259
276
|
PTWB => 'WhiteBalance', #PH (GPMF - seen: 'AUTO', fmt c)
|
|
260
|
-
# PVUL (APP6) - seen: 'F' (fmt c, Hero8)
|
|
277
|
+
# PVUL (APP6) - seen: 'F' (fmt c, Hero8, Max)
|
|
261
278
|
RATE => 'Rate', #PH (GPMF - seen: '0_5SEC', fmt c; APP6 - seen: '4_1SEC')
|
|
262
279
|
RMRK => { #2 (gpmd)
|
|
263
280
|
Name => 'Comments',
|
|
@@ -274,6 +291,10 @@ my %addUnits = (
|
|
|
274
291
|
# SCAL=1000 0.00999999977648258 0.00999999977648258 100
|
|
275
292
|
%addUnits,
|
|
276
293
|
},
|
|
294
|
+
# SFTR (GPMF-BACK/FRNT) - seen 0.999,1.00004 (fmt d, Max)
|
|
295
|
+
# SHFX (GPMF-GEOC) - seen 22.92 (fmt d, Max)
|
|
296
|
+
# SHFY (GPMF-GEOC) - seen 0.123 (fmt d, Max)
|
|
297
|
+
# SHFZ (GPMF-GEOC) - seen 36.06 (fmt d, Max)
|
|
277
298
|
SHUT => { #2 (gpmd)
|
|
278
299
|
Name => 'ExposureTimes',
|
|
279
300
|
PrintConv => q{
|
|
@@ -295,7 +316,8 @@ my %addUnits = (
|
|
|
295
316
|
ValueConv => '$self->Decode($val, "Latin")',
|
|
296
317
|
},
|
|
297
318
|
# SMTR (GPMF) - seen: 'N' (fmt c)
|
|
298
|
-
# SOFF (APP6) - seen: 0 (fmt L, Hero8)
|
|
319
|
+
# SOFF (APP6) - seen: 0 (fmt L, Hero8, Max)
|
|
320
|
+
# SROT (GPMF) - seen 20.60 (fmt f, Max)
|
|
299
321
|
STMP => { #1 (gpmd)
|
|
300
322
|
Name => 'TimeStamp',
|
|
301
323
|
ValueConv => '$val / 1e6',
|
|
@@ -338,7 +360,10 @@ my %addUnits = (
|
|
|
338
360
|
Unknown => 1,
|
|
339
361
|
ValueConv => '$self->Decode($val, "Latin")',
|
|
340
362
|
},
|
|
341
|
-
|
|
363
|
+
VERS => {
|
|
364
|
+
Name => 'MetadataVersion',
|
|
365
|
+
PrintConv => '$val =~ tr/ /./; $val',
|
|
366
|
+
},
|
|
342
367
|
VFOV => { #PH (GPMF - seen: 'W', fmt c)
|
|
343
368
|
Name => 'FieldOfView',
|
|
344
369
|
PrintConv => {
|
|
@@ -360,7 +385,7 @@ my %addUnits = (
|
|
|
360
385
|
Name => 'WhiteBalanceRGB',
|
|
361
386
|
Binary => 1,
|
|
362
387
|
},
|
|
363
|
-
# ZFOV (APP6) - seen: 148.34 (fmt f, Hero8)
|
|
388
|
+
# ZFOV (APP6,GPMF) - seen: 148.34, 0 (fmt f, Hero8, Max)
|
|
364
389
|
);
|
|
365
390
|
|
|
366
391
|
# GoPro GPS5 tags (ref 2) (Hero5,Hero6)
|
|
@@ -590,6 +615,7 @@ sub ProcessString($$$)
|
|
|
590
615
|
# Process GoPro metadata (gpmd samples, GPMF box, or APP6) (ref PH/1/2)
|
|
591
616
|
# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
|
|
592
617
|
# Returns: 1 on success
|
|
618
|
+
# - with hack to check for encrypted text in gpmd data (Rove Stealth 4K)
|
|
593
619
|
sub ProcessGoPro($$$)
|
|
594
620
|
{
|
|
595
621
|
my ($et, $dirInfo, $tagTablePtr) = @_;
|
|
@@ -890,7 +890,7 @@ sub ParsePictureTiming($$)
|
|
|
890
890
|
|
|
891
891
|
#------------------------------------------------------------------------------
|
|
892
892
|
# Process H.264 Supplementary Enhancement Information (ref 1/PH)
|
|
893
|
-
# Inputs: 0)
|
|
893
|
+
# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
|
|
894
894
|
# Returns: 1 if we processed payload type 5
|
|
895
895
|
# Payload types:
|
|
896
896
|
# 0 - buffer period
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
#------------------------------------------------------------------------------
|
|
2
2
|
# File: ID3.pm
|
|
3
3
|
#
|
|
4
|
-
# Description: Read ID3 meta information
|
|
4
|
+
# Description: Read ID3 and Lyrics3 meta information
|
|
5
5
|
#
|
|
6
6
|
# Revisions: 09/12/2005 - P. Harvey Created
|
|
7
|
+
# 09/08/2020 - PH Added Lyrics3 support
|
|
7
8
|
#
|
|
8
9
|
# References: 1) http://www.id3.org/
|
|
9
10
|
# 2) http://www.mp3-tech.org/
|
|
10
11
|
# 3) http://www.fortunecity.com/underworld/sonic/3/id3tag.html
|
|
12
|
+
# 4) https://id3.org/Lyrics3
|
|
11
13
|
#------------------------------------------------------------------------------
|
|
12
14
|
|
|
13
15
|
package Image::ExifTool::ID3;
|
|
@@ -16,7 +18,7 @@ use strict;
|
|
|
16
18
|
use vars qw($VERSION);
|
|
17
19
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
18
20
|
|
|
19
|
-
$VERSION = '1.
|
|
21
|
+
$VERSION = '1.55';
|
|
20
22
|
|
|
21
23
|
sub ProcessID3v2($$$);
|
|
22
24
|
sub ProcessPrivate($$$);
|
|
@@ -68,13 +70,13 @@ my %dateTimeConv = (
|
|
|
68
70
|
%Image::ExifTool::ID3::Main = (
|
|
69
71
|
VARS => { NO_ID => 1 },
|
|
70
72
|
NOTES => q{
|
|
71
|
-
ExifTool extracts ID3 information from MP3, MPEG, AIFF, OGG,
|
|
72
|
-
and RealAudio files. ID3v2 tags which support multiple
|
|
73
|
-
Comment and Lyrics) are extracted by specifying the tag name,
|
|
74
|
-
dash ('-'), then a 3-character ISO 639-2 language code (eg.
|
|
75
|
-
See L<http://www.id3.org/> for the official ID3
|
|
76
|
-
L<http://www.loc.gov/standards/iso639-2/php/code_list.php>
|
|
77
|
-
639-2 language codes.
|
|
73
|
+
ExifTool extracts ID3 and Lyrics3 information from MP3, MPEG, AIFF, OGG,
|
|
74
|
+
FLAC, APE, MPC and RealAudio files. ID3v2 tags which support multiple
|
|
75
|
+
languages (eg. Comment and Lyrics) are extracted by specifying the tag name,
|
|
76
|
+
followed by a dash ('-'), then a 3-character ISO 639-2 language code (eg.
|
|
77
|
+
"Comment-spa"). See L<http://www.id3.org/> for the official ID3
|
|
78
|
+
specification and L<http://www.loc.gov/standards/iso639-2/php/code_list.php>
|
|
79
|
+
for a list of ISO 639-2 language codes.
|
|
78
80
|
},
|
|
79
81
|
ID3v1 => {
|
|
80
82
|
Name => 'ID3v1',
|
|
@@ -98,6 +100,24 @@ my %dateTimeConv = (
|
|
|
98
100
|
},
|
|
99
101
|
);
|
|
100
102
|
|
|
103
|
+
# Lyrics3 tags (ref 4)
|
|
104
|
+
%Image::ExifTool::ID3::Lyrics3 = (
|
|
105
|
+
GROUPS => { 1 => 'Lyrics3', 2 => 'Audio' },
|
|
106
|
+
NOTES => q{
|
|
107
|
+
ExifTool extracts Lyrics3 version 1.00 and 2.00 tags from any file that
|
|
108
|
+
supports ID3. See L<https://id3.org/Lyrics3> for the specification.
|
|
109
|
+
},
|
|
110
|
+
IND => 'Indications',
|
|
111
|
+
LYR => 'Lyrics',
|
|
112
|
+
INF => 'AdditionalInfo',
|
|
113
|
+
AUT => { Name => 'Author', Groups => { 2 => 'Author' } },
|
|
114
|
+
EAL => 'ExtendedAlbumName',
|
|
115
|
+
EAR => 'ExtendedArtistName',
|
|
116
|
+
ETT => 'ExtendedTrackTitle',
|
|
117
|
+
IMG => 'AssociatedImageFile',
|
|
118
|
+
CRC => 'CRC', #PH
|
|
119
|
+
);
|
|
120
|
+
|
|
101
121
|
# Mapping for ID3v1 Genre numbers
|
|
102
122
|
my %genre = (
|
|
103
123
|
0 => 'Blues',
|
|
@@ -613,6 +633,9 @@ my %id3v2_common = (
|
|
|
613
633
|
Name => 'OlympusDSS',
|
|
614
634
|
SubDirectory => { TagTable => 'Image::ExifTool::Olympus::DSS' },
|
|
615
635
|
},
|
|
636
|
+
GRP1 => 'Grouping',
|
|
637
|
+
MVNM => 'MovementName', # (NC)
|
|
638
|
+
MVIN => 'MovementNumber', # (NC)
|
|
616
639
|
);
|
|
617
640
|
|
|
618
641
|
# Tags for ID3v2.3 (http://www.id3.org/id3v2.3.0)
|
|
@@ -1318,6 +1341,8 @@ sub ProcessID3v2($$$)
|
|
|
1318
1341
|
} elsif ($$tagInfo{Format} or $$tagInfo{SubDirectory}) {
|
|
1319
1342
|
$et->HandleTag($tagTablePtr, $id, undef, DataPt => \$val);
|
|
1320
1343
|
next;
|
|
1344
|
+
} elsif ($id eq 'GRP1' or $id eq 'MVNM' or $id eq 'MVIN') {
|
|
1345
|
+
$val =~ s/(^\0+|\0+$)//g; # (PH guess)
|
|
1321
1346
|
} elsif (not $$tagInfo{Binary}) {
|
|
1322
1347
|
$et->Warn("Don't know how to handle $id frame");
|
|
1323
1348
|
next;
|
|
@@ -1342,7 +1367,7 @@ sub ProcessID3v2($$$)
|
|
|
1342
1367
|
# Inputs: 0) ExifTool object reference, 1) dirInfo reference
|
|
1343
1368
|
# Returns: 1 on success, 0 if this file didn't contain ID3 information
|
|
1344
1369
|
# - also processes audio data if any ID3 information was found
|
|
1345
|
-
# - sets ExifTool DoneID3 to 1 when called, or to
|
|
1370
|
+
# - sets ExifTool DoneID3 to 1 when called, or to trailer size if an ID3v1 trailer exists
|
|
1346
1371
|
sub ProcessID3($$)
|
|
1347
1372
|
{
|
|
1348
1373
|
my ($et, $dirInfo) = @_;
|
|
@@ -1421,8 +1446,9 @@ sub ProcessID3($$)
|
|
|
1421
1446
|
#
|
|
1422
1447
|
# read ID3v1 trailer if it exists
|
|
1423
1448
|
#
|
|
1449
|
+
my $trailSize = 0;
|
|
1424
1450
|
if ($raf->Seek(-128, 2) and $raf->Read($tBuff, 128) == 128 and $tBuff =~ /^TAG/) {
|
|
1425
|
-
|
|
1451
|
+
$trailSize = 128;
|
|
1426
1452
|
%id3Trailer = (
|
|
1427
1453
|
DataPt => \$tBuff,
|
|
1428
1454
|
DataPos => $raf->Tell() - 128,
|
|
@@ -1432,8 +1458,59 @@ sub ProcessID3($$)
|
|
|
1432
1458
|
$id3Len += length($tBuff);
|
|
1433
1459
|
$rtnVal = 1;
|
|
1434
1460
|
# load 'Enhanced TAG' information if available
|
|
1435
|
-
|
|
1461
|
+
my $eSize = 227; # size of ID3 Enhanced TAG info
|
|
1462
|
+
if ($raf->Seek(-$trailSize - $eSize, 2) and $raf->Read($eBuff, $eSize) == $eSize and $eBuff =~ /^TAG+/) {
|
|
1436
1463
|
$id3Trailer{EnhancedTAG} = \$eBuff;
|
|
1464
|
+
$trailSize += $eSize;
|
|
1465
|
+
}
|
|
1466
|
+
$$et{DoneID3} = $trailSize; # save trailer size
|
|
1467
|
+
}
|
|
1468
|
+
#
|
|
1469
|
+
# read Lyrics3 trailer if it exists
|
|
1470
|
+
#
|
|
1471
|
+
if ($raf->Seek(-$trailSize-15, 2) and $raf->Read($buff, 15) == 15 and $buff =~ /^(.{6})LYRICS(END|200)$/) {
|
|
1472
|
+
my $ver = $2; # Lyrics3 version ('END' for version 1)
|
|
1473
|
+
my $len = ($ver eq 'END') ? 5100 : $1 + 15; # max Lyrics3 length
|
|
1474
|
+
my $tbl = GetTagTable('Image::ExifTool::ID3::Lyrics3');
|
|
1475
|
+
$len = $raf->Tell() if $len > $raf->Tell();
|
|
1476
|
+
if ($raf->Seek(-$len, 1) and $raf->Read($buff, $len) == $len and $buff =~ /LYRICSBEGIN/g) {
|
|
1477
|
+
my $pos = pos($buff);
|
|
1478
|
+
$$et{DoneID3} = $trailSize + $len - $pos + 11; # update trailer length
|
|
1479
|
+
my $oldIndent = $$et{INDENT};
|
|
1480
|
+
$$et{INDENT} .= '| ';
|
|
1481
|
+
if ($et->Options('Verbose')) {
|
|
1482
|
+
$et->VPrint(0, "Lyrics3:\n");
|
|
1483
|
+
$et->VerboseDir('Lyrics3', undef, $len);
|
|
1484
|
+
if ($pos > 11) {
|
|
1485
|
+
$buff = substr($buff, $pos - 11);
|
|
1486
|
+
$pos = 11;
|
|
1487
|
+
}
|
|
1488
|
+
$et->VerboseDump(\$buff);
|
|
1489
|
+
}
|
|
1490
|
+
if ($ver eq 'END') {
|
|
1491
|
+
# Lyrics3 v1.00
|
|
1492
|
+
my $val = substr($buff, $pos, $len - $pos - 9);
|
|
1493
|
+
$et->HandleTag($tbl, 'LYR', $et->Decode($val, 'Latin'));
|
|
1494
|
+
} else {
|
|
1495
|
+
# Lyrics3 v2.00
|
|
1496
|
+
for (;;) {
|
|
1497
|
+
# (note: the size field is 5 digits,, not 6 as per the documentation)
|
|
1498
|
+
last unless $buff =~ /\G(.{3})(\d{5})/g;
|
|
1499
|
+
my ($tag, $size) = ($1, $2);
|
|
1500
|
+
$pos += 8;
|
|
1501
|
+
last if $pos + $size > length($buff);
|
|
1502
|
+
unless ($$tbl{$tag}) {
|
|
1503
|
+
AddTagToTable($tbl, $tag, { Name => Image::ExifTool::MakeTagName("Lyrics3_$tag") });
|
|
1504
|
+
}
|
|
1505
|
+
$et->HandleTag($tbl, $tag, $et->Decode(substr($buff, $pos, $size), 'Latin'));
|
|
1506
|
+
$pos += $size;
|
|
1507
|
+
pos($buff) = $pos;
|
|
1508
|
+
}
|
|
1509
|
+
$pos == length($buff) - 15 or $et->Warn('Malformed Lyrics3 v2.00 block');
|
|
1510
|
+
}
|
|
1511
|
+
$$et{INDENT} = $oldIndent;
|
|
1512
|
+
} else {
|
|
1513
|
+
$et->Warn('Error reading Lyrics3 trailer');
|
|
1437
1514
|
}
|
|
1438
1515
|
}
|
|
1439
1516
|
#
|
|
@@ -1578,6 +1655,8 @@ under the same terms as Perl itself.
|
|
|
1578
1655
|
|
|
1579
1656
|
=item L<http://www.fortunecity.com/underworld/sonic/3/id3tag.html>
|
|
1580
1657
|
|
|
1658
|
+
=item L<https://id3.org/Lyrics3>
|
|
1659
|
+
|
|
1581
1660
|
=back
|
|
1582
1661
|
|
|
1583
1662
|
=head1 SEE ALSO
|
|
@@ -14,16 +14,33 @@ use vars qw($VERSION);
|
|
|
14
14
|
use Image::ExifTool qw(:DataAccess :Utils);
|
|
15
15
|
use Image::ExifTool::Import;
|
|
16
16
|
|
|
17
|
-
$VERSION = '1.
|
|
17
|
+
$VERSION = '1.02';
|
|
18
18
|
|
|
19
19
|
sub ProcessTag($$$$%);
|
|
20
20
|
|
|
21
21
|
%Image::ExifTool::JSON::Main = (
|
|
22
22
|
GROUPS => { 0 => 'JSON', 1 => 'JSON', 2 => 'Other' },
|
|
23
|
+
VARS => { NO_ID => 1 },
|
|
23
24
|
NOTES => q{
|
|
24
|
-
|
|
25
|
-
tags from basic
|
|
25
|
+
Other than a few tags in the table below, JSON tags have not been
|
|
26
|
+
pre-defined. However, ExifTool will read any existing tags from basic
|
|
27
|
+
JSON-formatted files.
|
|
26
28
|
},
|
|
29
|
+
# ON1 settings tags
|
|
30
|
+
ON1_SettingsData => {
|
|
31
|
+
RawConv => q{
|
|
32
|
+
require Image::ExifTool::XMP;
|
|
33
|
+
$val = Image::ExifTool::XMP::DecodeBase64($val);
|
|
34
|
+
},
|
|
35
|
+
SubDirectory => { TagTable => 'Image::ExifTool::PLIST::Main' },
|
|
36
|
+
},
|
|
37
|
+
ON1_SettingsMetadataCreated => { Groups => { 2 => 'Time' } },
|
|
38
|
+
ON1_SettingsMetadataModified => { Groups => { 2 => 'Time' } },
|
|
39
|
+
ON1_SettingsMetadataName => { },
|
|
40
|
+
ON1_SettingsMetadataPluginID => { },
|
|
41
|
+
ON1_SettingsMetadataTimestamp => { Groups => { 2 => 'Time' } },
|
|
42
|
+
ON1_SettingsMetadataUsage => { },
|
|
43
|
+
ON1_SettingsMetadataVisibleToUser=>{ },
|
|
27
44
|
);
|
|
28
45
|
|
|
29
46
|
#------------------------------------------------------------------------------
|
|
@@ -33,12 +50,18 @@ sub FoundTag($$$$%)
|
|
|
33
50
|
{
|
|
34
51
|
my ($et, $tagTablePtr, $tag, $val, %flags) = @_;
|
|
35
52
|
|
|
53
|
+
# special case to reformat ON1 tag names
|
|
54
|
+
if ($tag =~ s/^settings\w{8}-\w{4}-\w{4}-\w{4}-\w{12}(Data|Metadata.+)$/ON1_Settings$1/) {
|
|
55
|
+
$et->OverrideFileType('ONP','application/on1') if $$et{FILE_TYPE} eq 'JSON';
|
|
56
|
+
}
|
|
57
|
+
|
|
36
58
|
# avoid conflict with special table entries
|
|
37
59
|
$tag .= '!' if $Image::ExifTool::specialTags{$tag};
|
|
38
60
|
|
|
39
61
|
AddTagToTable($tagTablePtr, $tag, {
|
|
40
62
|
Name => Image::ExifTool::MakeTagName($tag),
|
|
41
63
|
%flags,
|
|
64
|
+
Temporary => 1,
|
|
42
65
|
}) unless $$tagTablePtr{$tag};
|
|
43
66
|
|
|
44
67
|
$et->HandleTag($tagTablePtr, $tag, $val);
|
|
@@ -94,7 +117,7 @@ sub ProcessJSON($$)
|
|
|
94
117
|
|
|
95
118
|
# remove any old tag definitions in case they change flags
|
|
96
119
|
foreach $key (TagTableKeys($tagTablePtr)) {
|
|
97
|
-
delete $$tagTablePtr{$key};
|
|
120
|
+
delete $$tagTablePtr{$key} if $$tagTablePtr{$key}{Temporary};
|
|
98
121
|
}
|
|
99
122
|
|
|
100
123
|
# extract tags from JSON database
|