exiftool_vendored 11.97.0 → 12.09.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of exiftool_vendored might be problematic. Click here for more details.

Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +196 -2
  3. data/bin/MANIFEST +8 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +43 -42
  7. data/bin/exiftool +150 -102
  8. data/bin/lib/Image/ExifTool.pm +162 -111
  9. data/bin/lib/Image/ExifTool.pod +123 -90
  10. data/bin/lib/Image/ExifTool/AIFF.pm +2 -2
  11. data/bin/lib/Image/ExifTool/APE.pm +2 -2
  12. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +21 -10
  13. data/bin/lib/Image/ExifTool/Canon.pm +201 -14
  14. data/bin/lib/Image/ExifTool/CanonCustom.pm +82 -16
  15. data/bin/lib/Image/ExifTool/DPX.pm +56 -2
  16. data/bin/lib/Image/ExifTool/DarwinCore.pm +22 -3
  17. data/bin/lib/Image/ExifTool/EXE.pm +8 -5
  18. data/bin/lib/Image/ExifTool/Exif.pm +15 -6
  19. data/bin/lib/Image/ExifTool/Font.pm +9 -2
  20. data/bin/lib/Image/ExifTool/GIF.pm +6 -1
  21. data/bin/lib/Image/ExifTool/GeoTiff.pm +2 -0
  22. data/bin/lib/Image/ExifTool/Geotag.pm +2 -2
  23. data/bin/lib/Image/ExifTool/GoPro.pm +48 -22
  24. data/bin/lib/Image/ExifTool/H264.pm +1 -1
  25. data/bin/lib/Image/ExifTool/HtmlDump.pm +2 -2
  26. data/bin/lib/Image/ExifTool/ID3.pm +91 -12
  27. data/bin/lib/Image/ExifTool/IPTC.pm +1 -0
  28. data/bin/lib/Image/ExifTool/JSON.pm +27 -4
  29. data/bin/lib/Image/ExifTool/Lang/de.pm +3 -1
  30. data/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
  31. data/bin/lib/Image/ExifTool/M2TS.pm +44 -24
  32. data/bin/lib/Image/ExifTool/MacOS.pm +152 -38
  33. data/bin/lib/Image/ExifTool/Matroska.pm +3 -1
  34. data/bin/lib/Image/ExifTool/Minolta.pm +7 -2
  35. data/bin/lib/Image/ExifTool/MinoltaRaw.pm +11 -10
  36. data/bin/lib/Image/ExifTool/Nikon.pm +163 -18
  37. data/bin/lib/Image/ExifTool/Olympus.pm +39 -17
  38. data/bin/lib/Image/ExifTool/PNG.pm +14 -3
  39. data/bin/lib/Image/ExifTool/PPM.pm +5 -5
  40. data/bin/lib/Image/ExifTool/Panasonic.pm +148 -14
  41. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +34 -0
  42. data/bin/lib/Image/ExifTool/Parrot.pm +2 -1
  43. data/bin/lib/Image/ExifTool/Pentax.pm +3 -1
  44. data/bin/lib/Image/ExifTool/Photoshop.pm +2 -1
  45. data/bin/lib/Image/ExifTool/QuickTime.pm +294 -34
  46. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +419 -60
  47. data/bin/lib/Image/ExifTool/README +26 -22
  48. data/bin/lib/Image/ExifTool/RIFF.pm +15 -3
  49. data/bin/lib/Image/ExifTool/RSRC.pm +17 -11
  50. data/bin/lib/Image/ExifTool/RTF.pm +12 -7
  51. data/bin/lib/Image/ExifTool/Radiance.pm +7 -2
  52. data/bin/lib/Image/ExifTool/Ricoh.pm +19 -1
  53. data/bin/lib/Image/ExifTool/Shift.pl +1 -0
  54. data/bin/lib/Image/ExifTool/SigmaRaw.pm +40 -33
  55. data/bin/lib/Image/ExifTool/Sony.pm +420 -34
  56. data/bin/lib/Image/ExifTool/TagLookup.pm +5799 -5671
  57. data/bin/lib/Image/ExifTool/TagNames.pod +583 -95
  58. data/bin/lib/Image/ExifTool/Validate.pm +4 -4
  59. data/bin/lib/Image/ExifTool/WriteExif.pl +3 -2
  60. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +26 -18
  61. data/bin/lib/Image/ExifTool/Writer.pl +44 -21
  62. data/bin/lib/Image/ExifTool/XMP.pm +99 -17
  63. data/bin/lib/Image/ExifTool/XMPStruct.pl +3 -1
  64. data/bin/lib/Image/ExifTool/ZISRAW.pm +123 -0
  65. data/bin/perl-Image-ExifTool.spec +42 -41
  66. data/lib/exiftool_vendored/version.rb +1 -1
  67. 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.17';
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.62';
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.03';
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 (fmt B) (Camera INFormation?)
110
- # CMOD (GPMF) - seen: 12,13,17 [13 time-laps video, 17 JPEG] (fmt B)
111
- CYTS => { #PH (Karma)
112
- Name => 'CoyoteStatus',
113
- # UNIT=s,,,,,rad,rad,rad,,
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
- # DVID (GPMF) - DeviceID; seen: 1 (fmt L), HLMT (fmt F)
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', 'HS EIS' (fmt c) [N was for a time-lapse video]
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
- # LINF (GPMF) - seen: LAJ7061916601668, C3341326002180 (fmt c) (Lens INFormation?)
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
- # VERS (APP6) - seen: '7 6 4' (fmt B, Hero8)
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) Exiftool ref, 1) dirInfo ref, 2) tag table ref
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
@@ -13,7 +13,7 @@ use vars qw($VERSION);
13
13
  use Image::ExifTool; # only for FinishTiffDump()
14
14
  use Image::ExifTool::HTML qw(EscapeHTML);
15
15
 
16
- $VERSION = '1.38';
16
+ $VERSION = '1.39';
17
17
 
18
18
  sub DumpTable($$$;$$$$$$);
19
19
  sub Open($$$;@);
@@ -122,7 +122,7 @@ function doClick(e)
122
122
  if (!clicked) {
123
123
  firstOutEvt = lastInEvt = undefined;
124
124
  high(e, 2);
125
- clicked = 1;
125
+ if (hlist) clicked = 1;
126
126
  } else {
127
127
  clicked = 0;
128
128
  if (firstOutEvt) high(firstOutEvt, 0);
@@ -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.53';
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, FLAC, APE, MPC
72
- and RealAudio files. ID3v2 tags which support multiple languages (eg.
73
- Comment and Lyrics) are extracted by specifying the tag name, followed by a
74
- dash ('-'), then a 3-character ISO 639-2 language code (eg. "Comment-spa").
75
- See L<http://www.id3.org/> for the official ID3 specification and
76
- L<http://www.loc.gov/standards/iso639-2/php/code_list.php> for a list of ISO
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 2 if an ID3v1 trailer exists
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
- $$et{DoneID3} = 2; # set to 2 as flag that trailer exists
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
- if ($raf->Seek(-355, 2) and $raf->Read($eBuff, 227) == 227 and $eBuff =~ /^TAG+/) {
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
@@ -497,6 +497,7 @@ my %fileFormat = (
497
497
  103 => {
498
498
  Name => 'OriginalTransmissionReference',
499
499
  Format => 'string[0,32]',
500
+ Notes => 'now used as a job identifier',
500
501
  },
501
502
  105 => {
502
503
  Name => 'Headline',
@@ -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.01';
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
- No JSON tags have been pre-defined, but ExifTool will read any existing
25
- tags from basic JSON-formatted files.
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