exiftool_vendored 13.04.0 → 13.08.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.
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;