exiftool_vendored 13.04.0 → 13.08.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +48 -0
  3. data/bin/MANIFEST +1 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +2 -2
  7. data/bin/exiftool +30 -23
  8. data/bin/lib/Image/ExifTool/AIFF.pm +1 -1
  9. data/bin/lib/Image/ExifTool/APE.pm +1 -1
  10. data/bin/lib/Image/ExifTool/ASF.pm +1 -1
  11. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +4 -3
  12. data/bin/lib/Image/ExifTool/Canon.pm +19 -1
  13. data/bin/lib/Image/ExifTool/DJI.pm +91 -29
  14. data/bin/lib/Image/ExifTool/Exif.pm +2 -2
  15. data/bin/lib/Image/ExifTool/FITS.pm +2 -2
  16. data/bin/lib/Image/ExifTool/FLIF.pm +2 -2
  17. data/bin/lib/Image/ExifTool/FlashPix.pm +11 -11
  18. data/bin/lib/Image/ExifTool/Font.pm +1 -1
  19. data/bin/lib/Image/ExifTool/Geolocation.pm +2 -1
  20. data/bin/lib/Image/ExifTool/GoPro.pm +3 -3
  21. data/bin/lib/Image/ExifTool/HP.pm +1 -1
  22. data/bin/lib/Image/ExifTool/ID3.pm +3 -3
  23. data/bin/lib/Image/ExifTool/IPTC.pm +2 -2
  24. data/bin/lib/Image/ExifTool/InDesign.pm +1 -1
  25. data/bin/lib/Image/ExifTool/JPEG.pm +19 -4
  26. data/bin/lib/Image/ExifTool/Jpeg2000.pm +6 -6
  27. data/bin/lib/Image/ExifTool/M2TS.pm +39 -9
  28. data/bin/lib/Image/ExifTool/MXF.pm +2 -2
  29. data/bin/lib/Image/ExifTool/Matroska.pm +1 -1
  30. data/bin/lib/Image/ExifTool/Microsoft.pm +1 -1
  31. data/bin/lib/Image/ExifTool/PDF.pm +15 -15
  32. data/bin/lib/Image/ExifTool/PLIST.pm +1 -1
  33. data/bin/lib/Image/ExifTool/PNG.pm +4 -4
  34. data/bin/lib/Image/ExifTool/Panasonic.pm +1 -1
  35. data/bin/lib/Image/ExifTool/PhaseOne.pm +3 -3
  36. data/bin/lib/Image/ExifTool/Photoshop.pm +63 -3
  37. data/bin/lib/Image/ExifTool/Protobuf.pm +242 -0
  38. data/bin/lib/Image/ExifTool/QuickTime.pm +23 -14
  39. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +395 -109
  40. data/bin/lib/Image/ExifTool/README +4 -1
  41. data/bin/lib/Image/ExifTool/RIFF.pm +3 -3
  42. data/bin/lib/Image/ExifTool/RTF.pm +1 -1
  43. data/bin/lib/Image/ExifTool/Ricoh.pm +3 -3
  44. data/bin/lib/Image/ExifTool/Sony.pm +4 -3
  45. data/bin/lib/Image/ExifTool/TagInfoXML.pm +4 -3
  46. data/bin/lib/Image/ExifTool/TagLookup.pm +6988 -6967
  47. data/bin/lib/Image/ExifTool/TagNames.pod +85 -5
  48. data/bin/lib/Image/ExifTool/VCard.pm +2 -2
  49. data/bin/lib/Image/ExifTool/Validate.pm +3 -3
  50. data/bin/lib/Image/ExifTool/WriteExif.pl +2 -2
  51. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +4 -4
  52. data/bin/lib/Image/ExifTool/WriteXMP.pl +2 -2
  53. data/bin/lib/Image/ExifTool/Writer.pl +17 -17
  54. data/bin/lib/Image/ExifTool/XMP.pm +20 -10
  55. data/bin/lib/Image/ExifTool/XMP2.pl +38 -0
  56. data/bin/lib/Image/ExifTool/ZIP.pm +1 -1
  57. data/bin/lib/Image/ExifTool.pm +109 -82
  58. data/bin/lib/Image/ExifTool.pod +8 -7
  59. data/bin/perl-Image-ExifTool.spec +1 -1
  60. data/lib/exiftool_vendored/version.rb +1 -1
  61. metadata +3 -2
@@ -28,11 +28,12 @@ use strict;
28
28
  use vars qw($VERSION $AUTOLOAD $iptcDigestInfo %printFlags);
29
29
  use Image::ExifTool qw(:DataAccess :Utils);
30
30
 
31
- $VERSION = '1.71';
31
+ $VERSION = '1.72';
32
32
 
33
33
  sub ProcessPhotoshop($$$);
34
34
  sub WritePhotoshop($$$);
35
35
  sub ProcessLayers($$$);
36
+ sub ProcessChannelOptions($$$);
36
37
 
37
38
  # PrintFlags bit definitions (ref forum13785)
38
39
  %printFlags = (
@@ -322,7 +323,13 @@ my %unicodeString = (
322
323
  0x0432 => { Unknown => 1, Name => 'MeasurementScale' }, #7
323
324
  0x0433 => { Unknown => 1, Name => 'TimelineInfo' }, #7
324
325
  0x0434 => { Unknown => 1, Name => 'SheetDisclosure' }, #7
325
- 0x0435 => { Unknown => 1, Name => 'ChannelOptions' }, #7/forum16762
326
+ 0x0435 => {
327
+ Name => 'ChannelOptions', #7/forum16762
328
+ SubDirectory => {
329
+ TagTable => 'Image::ExifTool::Photoshop::ChannelOptions',
330
+ Start => 4,
331
+ },
332
+ },
326
333
  0x0436 => { Unknown => 1, Name => 'OnionSkins' }, #7
327
334
  0x0438 => { Unknown => 1, Name => 'CountInfo' }, #7
328
335
  0x043a => { Unknown => 1, Name => 'PrintInfo2' }, #7
@@ -350,6 +357,40 @@ my %unicodeString = (
350
357
  0x2710 => { Unknown => 1, Name => 'PrintFlagsInfo' },
351
358
  );
352
359
 
360
+ # Photoshop channel options (ref forum16762)
361
+ %Image::ExifTool::Photoshop::ChannelOptions = (
362
+ PROCESS_PROC => \&ProcessChannelOptions,
363
+ VARS => { IS_BINARY => 1 },
364
+ GROUPS => { 2 => 'Image' },
365
+ 0 => {
366
+ Name => 'ChannelColorSpace',
367
+ Format => 'int16u',
368
+ PrintConv => {
369
+ 0 => 'RGB',
370
+ 1 => 'HSB',
371
+ 2 => 'CMYK',
372
+ 7 => 'Lab',
373
+ 8 => 'Grayscale',
374
+ },
375
+ },
376
+ 2 => {
377
+ Name => 'ChannelColorData',
378
+ Format => 'int16u[4]',
379
+ },
380
+ 11 => {
381
+ Name => 'ChannelOpacity',
382
+ PrintConv => '"$val%"',
383
+ },
384
+ 12 => {
385
+ Name => 'ChannelColorIndicates',
386
+ PrintConv => {
387
+ 0 => 'Selected Areas',
388
+ 1 => 'Masked Areas',
389
+ 2 => 'Spot Color',
390
+ },
391
+ },
392
+ );
393
+
353
394
  # Photoshop JPEG quality record (ref 2)
354
395
  %Image::ExifTool::Photoshop::JPEG_Quality = (
355
396
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
@@ -755,6 +796,25 @@ sub ProcessLayersAndMask($$$)
755
796
  return $raf->Seek($end, 0) ? 1 : 0;
756
797
  }
757
798
 
799
+ #------------------------------------------------------------------------------
800
+ # Process Photoshop channel options (ref forum16762)
801
+ # Inputs: 0) ExifTool ref, 1) DirInfo ref, 2) tag table ref
802
+ # Returns: 1 on success
803
+ sub ProcessChannelOptions($$$)
804
+ {
805
+ my ($et, $dirInfo, $tagTablePtr) = @_;
806
+ my $end = $$dirInfo{DirStart} + $$dirInfo{DirLen};
807
+ $$dirInfo{DirLen} = 13;
808
+ my $i;
809
+ for ($i=0; $$dirInfo{DirStart} + 13 <= $end; ++$i) {
810
+ $$et{SET_GROUP1} = "Channel$i";
811
+ $et->ProcessBinaryData($dirInfo, $tagTablePtr);
812
+ $$dirInfo{DirStart} += 13;
813
+ }
814
+ delete $$et{SET_GROUP1};
815
+ return 1;
816
+ }
817
+
758
818
  #------------------------------------------------------------------------------
759
819
  # Process Photoshop layers (beginning with layer count)
760
820
  # Inputs: 0) ExifTool ref, 1) DirInfo ref, 2) tag table ref
@@ -1050,7 +1110,7 @@ sub ProcessPhotoshop($$$)
1050
1110
  if ($$et{VALUE}{IPTCDigest} and $$et{VALUE}{CurrentIPTCDigest} and
1051
1111
  $$et{VALUE}{IPTCDigest} ne $$et{VALUE}{CurrentIPTCDigest})
1052
1112
  {
1053
- $et->WarnOnce('IPTCDigest is not current. XMP may be out of sync');
1113
+ $et->Warn('IPTCDigest is not current. XMP may be out of sync');
1054
1114
  }
1055
1115
  delete $$et{LOW_PRIORITY_DIR}{'*'};
1056
1116
  return $success;
@@ -0,0 +1,242 @@
1
+ #------------------------------------------------------------------------------
2
+ # File: Protobuf.pm
3
+ #
4
+ # Description: Decode protocol buffer data
5
+ #
6
+ # Revisions: 2024-12-04 - P. Harvey Created
7
+ #
8
+ # Notes: Tag definitions for Protobuf tags support additional 'signed'
9
+ # and 'unsigned' formats for varInt (type 0) values
10
+ #
11
+ # References: 1) https://protobuf.dev/programming-guides/encoding/
12
+ #------------------------------------------------------------------------------
13
+
14
+ package Image::ExifTool::Protobuf;
15
+
16
+ use strict;
17
+ use vars qw($VERSION);
18
+ use Image::ExifTool qw(:DataAccess :Utils);
19
+
20
+ $VERSION = '1.00';
21
+
22
+ sub ProcessProtobuf($$$;$);
23
+
24
+ #------------------------------------------------------------------------------
25
+ # Read bytes from dirInfo object
26
+ # Inputs: 0) dirInfo ref, 1) number of bytes
27
+ # Returns: binary data or undef on error
28
+ sub GetBytes($$)
29
+ {
30
+ my ($dirInfo, $n) = @_;
31
+ my $dataPt = $$dirInfo{DataPt};
32
+ my $pos = $$dirInfo{Pos};
33
+ return undef if $pos + $n > length $$dataPt;
34
+ $$dirInfo{Pos} += $n;
35
+ return substr($$dataPt, $pos, $n);
36
+ }
37
+
38
+ #------------------------------------------------------------------------------
39
+ # Read variable-length integer
40
+ # Inputs: 0) dirInfo ref
41
+ # Returns: integer value
42
+ sub VarInt($)
43
+ {
44
+ my $dirInfo = shift;
45
+ my $val = 0;
46
+ my $shift = 0;
47
+ for (;;) {
48
+ my $buff = GetBytes($dirInfo, 1);
49
+ defined $buff or return undef;
50
+ $val += (ord($buff) & 0x7f) << $shift;
51
+ last unless ord($buff) & 0x80;
52
+ $shift += 7;
53
+ }
54
+ return $val;
55
+ }
56
+
57
+ #------------------------------------------------------------------------------
58
+ # Read protobuf record
59
+ # Inputs: 0) dirInfo ref
60
+ # Returns: 0) record payload (plus tag id and format type in list context)
61
+ # Notes: Updates dirInfo Pos to start of next record
62
+ sub ReadRecord($)
63
+ {
64
+ my $dirInfo = shift;
65
+ my $val = VarInt($dirInfo);
66
+ return undef unless defined $val;
67
+ my $id = $val >> 3;
68
+ my $type = $val & 0x07;
69
+ my $buff;
70
+
71
+ if ($type == 0) { # varInt
72
+ $buff = VarInt($dirInfo);
73
+ } elsif ($type == 1) { # 64-bit number
74
+ $buff = GetBytes($dirInfo, 8);
75
+ } elsif ($type == 2) { # string, bytes or protobuf
76
+ my $len = VarInt($dirInfo);
77
+ if ($len) {
78
+ $buff = GetBytes($dirInfo, $len);
79
+ } else {
80
+ $buff = '';
81
+ }
82
+ } elsif ($type == 3) { # (deprecated start group)
83
+ $buff = '';
84
+ } elsif ($type == 4) { # (deprecated end group)
85
+ $buff = '';
86
+ } elsif ($type == 5) { # 32-bit number
87
+ $buff = GetBytes($dirInfo, 4);
88
+ }
89
+ return wantarray ? ($buff, $id, $type) : $buff;
90
+ }
91
+
92
+ #------------------------------------------------------------------------------
93
+ # Check to see if this could be a protobuf object
94
+ # Inputs: 0) data reference
95
+ # Retursn: true if this looks like a protobuf
96
+ sub IsProtobuf($)
97
+ {
98
+ my $pt = shift;
99
+ my $dirInfo = { DataPt => $pt, Pos => 0 };
100
+ for (;;) {
101
+ return 0 unless defined ReadRecord($dirInfo);
102
+ return 1 if $$dirInfo{Pos} == length $$pt;
103
+ }
104
+ }
105
+
106
+ #------------------------------------------------------------------------------
107
+ # Process protobuf data (eg. DJI djmd timed data from Action4 videos) (ref 1)
108
+ # Inputs: 0) ExifTool ref, 1) dirInfo ref with DataPt, DirName and Base,
109
+ # 2) tag table ptr, 3) prefix of parent protobuf ID's
110
+ # Returns: true on success
111
+ sub ProcessProtobuf($$$;$)
112
+ {
113
+ my ($et, $dirInfo, $tagTbl, $prefix) = @_;
114
+ my $dataPt = $$dirInfo{DataPt};
115
+ my $dirName = $$dirInfo{DirName};
116
+ my $unknown = $et->Options('Unknown') || $et->Options('Verbose');
117
+
118
+ $$dirInfo{Pos} = $$dirInfo{DirStart} || 0; # initialize buffer Pos
119
+
120
+ unless ($prefix) {
121
+ $prefix = '';
122
+ $$et{ProtocolName}{$dirName} = '*' unless defined $$et{ProtocolName}{$dirName};
123
+ SetByteOrder('II');
124
+ }
125
+ # loop through protobuf records
126
+ for (;;) {
127
+ my $pos = $$dirInfo{Pos};
128
+ last if $pos >= length $$dataPt;
129
+ my ($buff, $id, $type) = ReadRecord($dirInfo);
130
+ defined $buff or $et->Warn('Protobuf format error'), last;
131
+ if ($type == 2 and $buff =~ /\.proto$/) {
132
+ # save protocol name separately for directory type
133
+ $$et{ProtocolName}{$dirName} = substr($buff, 0, -6);
134
+ $et->HandleTag($tagTbl, Protocol => $buff);
135
+ }
136
+ my $tag = "$$et{ProtocolName}{$dirName}_$prefix$id";
137
+ my $tagInfo = $$tagTbl{$tag};
138
+ if ($tagInfo) {
139
+ next if $type != 2 and $$tagInfo{Unknown} and not $unknown;
140
+ } else {
141
+ next unless $type == 2 or $unknown;
142
+ $tagInfo = AddTagToTable($tagTbl, $tag, { Unknown => 1 });
143
+ }
144
+ # set IsProtobuf flag (only for Unknown tags) if necessary
145
+ if ($type == 2 and $$tagInfo{Unknown}) {
146
+ if ($$tagInfo{IsProtobuf}) {
147
+ $$tagInfo{IsProtobuf} = 0 unless IsProtobuf(\$buff);
148
+ } elsif (not defined $$tagInfo{IsProtobuf} and $buff =~ /[^\x20-\x7e]/ and
149
+ IsProtobuf(\$buff))
150
+ {
151
+ $$tagInfo{IsProtobuf} = 1;
152
+ }
153
+ next unless $$tagInfo{IsProtobuf} or $unknown;
154
+ }
155
+ # format binary payload into a useful value
156
+ my $val;
157
+ if ($$tagInfo{Format}) {
158
+ if ($type == 0) {
159
+ $val = $buff;
160
+ $val = ($val & 1) ? -($val >> 1)-1 : ($val >> 1) if $$tagInfo{Format} eq 'signed';
161
+ } else {
162
+ $val = ReadValue(\$buff, 0, $$tagInfo{Format}, undef, length($buff));
163
+ }
164
+ } elsif ($type == 0) {
165
+ $val = $buff;
166
+ my $signed = ($val & 1) ? -($val >> 1)-1 : ($val >> 1);
167
+ $val .= sprintf(" (0x%x, signed $signed)", $val);
168
+ } elsif ($type == 1) {
169
+ $val = '0x' . unpack('H*', $buff) . ' (double ' . GetDouble(\$buff,0) . ')';
170
+ } elsif ($type == 2) {
171
+ if ($$tagInfo{IsProtobuf}) {
172
+ $et->VPrint(1, "+ Protobuf $tag (" . length($buff) . " bytes)\n");
173
+ my $addr = $$dirInfo{Base} + $$dirInfo{Pos} - length($buff);
174
+ $et->VerboseDump(\$buff, Addr => $addr);
175
+ my %subdir = ( DataPt => \$buff, Base => $addr, DirName => $dirName );
176
+ ProcessProtobuf($et, \%subdir, $tagTbl, "$prefix$id-");
177
+ next;
178
+ } elsif ($buff !~ /[^\x20-\x7e]/) {
179
+ $val = $buff; # assume this is an ASCII string
180
+ } elsif (length($buff) % 4) {
181
+ $val = '0x' . unpack('H*', $buff);
182
+ } else {
183
+ $val = '0x' . join(' ', unpack('(H8)*', $buff)); # (group in 4-byte blocks)
184
+ }
185
+ } elsif ($type == 5) {
186
+ $val = '0x' . unpack('H*', $buff) . ' (int32u ' . Get32u(\$buff, 0);
187
+ $val .= ', int32s ' . Get32s(\$buff, 0) if ord(substr($buff,3,1)) & 0x80;
188
+ $val .= ', float ' . GetFloat(\$buff, 0) . ')';
189
+ } else {
190
+ $val = $buff;
191
+ }
192
+ # get length of data in the record
193
+ my $start = $type == 0 ? $pos + 1 : $$dirInfo{Pos} - length $buff;
194
+ $et->HandleTag($tagTbl, $tag, $val,
195
+ DataPt => $dataPt,
196
+ DataPos=> $$dirInfo{Base},
197
+ Start => $start,
198
+ Size => $$dirInfo{Pos} - $start,
199
+ Extra => ", type=$type",
200
+ Format => $$tagInfo{Format},
201
+ );
202
+ }
203
+ # warn if we didn't finish exactly at the end of the buffer
204
+ $et->Warn('Truncated protobuf data') unless $prefix or $$dirInfo{Pos} == length $$dataPt;
205
+ return 1;
206
+ }
207
+
208
+ __END__
209
+
210
+ =head1 NAME
211
+
212
+ Image::ExifTool::Protobuf - Decode protocol buffer information
213
+
214
+ =head1 SYNOPSIS
215
+
216
+ This module is loaded automatically by Image::ExifTool when required.
217
+
218
+ =head1 DESCRIPTION
219
+
220
+ This module contains definitions required by Image::ExifTool to decode
221
+ information in protocol buffer (protobuf) format.
222
+
223
+ =head1 AUTHOR
224
+
225
+ Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
226
+
227
+ This library is free software; you can redistribute it and/or modify it
228
+ under the same terms as Perl itself.
229
+
230
+ =head1 REFERENCES
231
+
232
+ =over 4
233
+
234
+ =item L<https://protobuf.dev/programming-guides/encoding/>
235
+
236
+ =back
237
+
238
+ =head1 SEE ALSO
239
+
240
+ L<Image::ExifTool(3pm)|Image::ExifTool>
241
+
242
+ =cut
@@ -69,8 +69,9 @@ sub Process_gps0($$$);
69
69
  sub Process_gsen($$$);
70
70
  sub Process_gdat($$$);
71
71
  sub Process_nbmt($$$);
72
+ sub ProcessLigoGPS($$$;$);
73
+ sub ProcessLigoJSON($$$);
72
74
  sub ProcessKenwood($$$);
73
- sub ProcessLIGO_JSON($$$);
74
75
  sub ProcessRIFFTrailer($$$);
75
76
  sub ProcessTTAD($$$);
76
77
  sub ProcessNMEA($$$);
@@ -255,7 +256,7 @@ my %timeInfo = (
255
256
  my $offset = (66 * 365 + 17) * 24 * 3600;
256
257
  return $val - $offset if $val >= $offset or $$self{OPTIONS}{QuickTimeUTC};
257
258
  if ($val and not $$self{IsWriting}) {
258
- $self->WarnOnce('Patched incorrect time zero for QuickTime date/time tag',1);
259
+ $self->Warn('Patched incorrect time zero for QuickTime date/time tag',1);
259
260
  }
260
261
  return $val;
261
262
  },
@@ -584,6 +585,14 @@ my %userDefined = (
584
585
  Condition => '$$valPt =~ /^\0[\0-\x04]..[a-zA-Z ]{4}/s',
585
586
  SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::SkipInfo' },
586
587
  },
588
+ {
589
+ Name => 'LigoGPSInfo',
590
+ Condition => '$$valPt =~ /^LIGOGPSINFO\0/',
591
+ SubDirectory => {
592
+ TagTable => 'Image::ExifTool::QuickTime::Stream',
593
+ ProcessProc => \&ProcessLigoGPS,
594
+ },
595
+ },
587
596
  { Name => 'Skip', Unknown => 1, Binary => 1 },
588
597
  ],
589
598
  wide => { Unknown => 1, Binary => 1 },
@@ -677,7 +686,7 @@ my %userDefined = (
677
686
  Condition => '$$valPt=~/^\xef\xe1\x58\x9a\xbb\x77\x49\xef\x80\x95\x27\x75\x9e\xb1\xdc\x6f/',
678
687
  Notes => 'raw 360Fly sensor data without ExtractEmbedded option',
679
688
  RawConv => q{
680
- $self->WarnOnce('Use the ExtractEmbedded option to decode timed SensorData',3);
689
+ $self->Warn('Use the ExtractEmbedded option to decode timed SensorData',3);
681
690
  return \$val;
682
691
  },
683
692
  },
@@ -762,11 +771,11 @@ my %userDefined = (
762
771
  ProcessProc => \&ProcessKenwood,
763
772
  },
764
773
  },{
765
- Name => 'LIGO_JSON',
774
+ Name => 'LigoJSON',
766
775
  Condition => '$$valPt =~ /^LIGOGPSINFO \{/',
767
776
  SubDirectory => {
768
777
  TagTable => 'Image::ExifTool::QuickTime::Stream',
769
- ProcessProc => \&ProcessLIGO_JSON,
778
+ ProcessProc => \&ProcessLigoJSON,
770
779
  },
771
780
  },{
772
781
  Name => 'FLIRData',
@@ -1303,7 +1312,7 @@ my %userDefined = (
1303
1312
  Condition => '$$valPt=~/^\x9b\x63\x0f\x8d\x63\x74\x40\xec\x82\x04\xbc\x5f\xf5\x09\x17\x28/',
1304
1313
  Notes => 'Garmin GPS sensor data',
1305
1314
  RawConv => q{
1306
- $self->WarnOnce('Use the ExtractEmbedded option to decode timed Garmin GPS',3);
1315
+ $self->Warn('Use the ExtractEmbedded option to decode timed Garmin GPS',3);
1307
1316
  return \$val;
1308
1317
  },
1309
1318
  },
@@ -1407,7 +1416,7 @@ my %userDefined = (
1407
1416
  if ($val >= $offset or $$self{OPTIONS}{QuickTimeUTC}) {
1408
1417
  $val -= $offset;
1409
1418
  } elsif ($val and not $$self{IsWriting}) {
1410
- $self->WarnOnce('Patched incorrect time zero for QuickTime date/time tag',1);
1419
+ $self->Warn('Patched incorrect time zero for QuickTime date/time tag',1);
1411
1420
  }
1412
1421
  return $$self{CreateDate} = $val;
1413
1422
  },
@@ -2557,7 +2566,7 @@ my %userDefined = (
2557
2566
  TTID => { Name => 'TomTomID', ValueConv => 'unpack("x4H*",$val)' },
2558
2567
  TTVI => { Name => 'TomTomVI', Format => 'int32u', Unknown => 1 }, # seen: "0 1 61 508 508"
2559
2568
  # TTVD seen: "normal 720p 60fps 60fps 16/9 wide 1x"
2560
- TTVD => { Name => 'TomTomVD', ValueConv => 'my @a = ($val =~ /[\x20-\x7f]+/g); "@a"', List => 1 },
2569
+ TTVD => { Name => 'TomTomVD', ValueConv => 'my @a = ($val =~ /[\x20-\x7e]+/g); "@a"', List => 1 },
2561
2570
  );
2562
2571
 
2563
2572
  # User-specific media data atoms (ref 11)
@@ -9031,11 +9040,11 @@ sub HandleItemInfo($)
9031
9040
  }
9032
9041
  $warn = "Can't currently decode protected $type metadata" if $$item{ProtectionIndex};
9033
9042
  $warn = "Can't currently extract $type with construction method $$item{ConstructionMethod}" if $$item{ConstructionMethod};
9034
- $et->WarnOnce($warn) if $warn and $name;
9043
+ $et->Warn($warn) if $warn and $name;
9035
9044
  $warn = 'Not this file' if $$item{DataReferenceIndex}; # (can only extract from "this file")
9036
9045
  unless (($$item{Extents} and @{$$item{Extents}}) or $warn) {
9037
9046
  $warn = "No Extents for $type item";
9038
- $et->WarnOnce($warn) if $name;
9047
+ $et->Warn($warn) if $name;
9039
9048
  }
9040
9049
  if ($warn) {
9041
9050
  $et->VPrint(0, "$$et{INDENT} [not extracted] ($warn)\n") if $verbose > 2;
@@ -9099,7 +9108,7 @@ sub HandleItemInfo($)
9099
9108
  $et->VerboseDump(\$buff);
9100
9109
  } else {
9101
9110
  $warn = "Error inflating $name metadata";
9102
- $et->WarnOnce($warn);
9111
+ $et->Warn($warn);
9103
9112
  $et->VPrint(0, "$$et{INDENT} [not extracted] ($warn)\n") if $verbose > 2;
9104
9113
  next;
9105
9114
  }
@@ -9188,7 +9197,7 @@ sub HandleItemInfo($)
9188
9197
  sub EEWarn($)
9189
9198
  {
9190
9199
  my $et = shift;
9191
- $et->WarnOnce('The ExtractEmbedded option may find more tags in the media data',3);
9200
+ $et->Warn('The ExtractEmbedded option may find more tags in the media data',3);
9192
9201
  }
9193
9202
 
9194
9203
  #------------------------------------------------------------------------------
@@ -9675,7 +9684,7 @@ sub ProcessMOV($$;$)
9675
9684
  $warnStr = 'End of processing at large atom (LargeFileSupport not enabled)';
9676
9685
  last;
9677
9686
  } elsif ($et->Options('LargeFileSupport') eq '2') {
9678
- $et->WarnOnce('Processing large atom (LargeFileSupport is 2)');
9687
+ $et->Warn('Processing large atom (LargeFileSupport is 2)');
9679
9688
  }
9680
9689
  }
9681
9690
  $size = $hi * 4294967296 + $lo - 16;
@@ -9690,7 +9699,7 @@ sub ProcessMOV($$;$)
9690
9699
  if ($$et{ValidatePath}{$path} and not $dupTagOK{$tag} and not $dupDirOK{$dirID}) {
9691
9700
  my $i = Get32u(\$tag,0);
9692
9701
  my $str = $i < 255 ? "index $i" : "tag '" . PrintableTagID($tag,2) . "'";
9693
- $et->WarnOnce("Duplicate $str at " . join('-', @{$$et{PATH}}));
9702
+ $et->Warn("Duplicate $str at " . join('-', @{$$et{PATH}}));
9694
9703
  $$et{ValidatePath} = { } if $path eq 'MOV-moov'; # avoid warnings for all contained dups
9695
9704
  }
9696
9705
  $$et{ValidatePath}{$path} = 1;