source: main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FLAC.pm@ 34921

Last change on this file since 34921 was 34921, checked in by anupama, 3 years ago

Committing the improvements to EmbeddedMetaPlugin's processing of Keywords vs other metadata fields. Keywords were literally stored as arrays of words rather than phrases in PDFs (at least in Diego's sample PDF), whereas other meta fields like Subjects and Creators stored them as arrays of phrases. To get both to work, Kathy updated EXIF to a newer version, to retrieve the actual EXIF values stored in the PDF. And Kathy and Dr Bainbridge came up with a new option that I added called apply_join_before_split_to_metafields that's a regex which can list the metadata fields to apply the join_before_split to and whcih previously always got applied to all metadata fields. Now it's applied to any *Keywords metafields by default, as that's the metafield we have experience of that behaves differently to the others, as it stores by word instead of phrases. Tested on Diego's sample PDF. Diego has double-checked it to works on his sample PDF too, setting the split char to ; and turning on the join_before_split and leaving apply_join_before_split_to_metafields at its default of .*Keywords. File changes are strings.properties for the tooltip, the plugin introducing the option and working with it and Kathy's EXIF updates affecting cpan/File and cpan/Image.

File size: 9.9 KB
Line 
1#------------------------------------------------------------------------------
2# File: FLAC.pm
3#
4# Description: Read Free Lossless Audio Codec information
5#
6# Revisions: 11/13/2006 - P. Harvey Created
7#
8# References: 1) http://flac.sourceforge.net/
9#------------------------------------------------------------------------------
10
11package Image::ExifTool::FLAC;
12
13use strict;
14use vars qw($VERSION);
15use Image::ExifTool qw(:DataAccess :Utils);
16
17$VERSION = '1.08';
18
19sub ProcessBitStream($$$);
20
21# FLAC metadata blocks
22%Image::ExifTool::FLAC::Main = (
23 NOTES => q{
24 Free Lossless Audio Codec (FLAC) meta information. ExifTool also extracts
25 ID3 information from these files.
26 },
27 0 => {
28 Name => 'StreamInfo',
29 SubDirectory => { TagTable => 'Image::ExifTool::FLAC::StreamInfo' },
30 },
31 1 => { Name => 'Padding', Binary => 1, Unknown => 1 },
32 2 => { Name => 'Application', Binary => 1, Unknown => 1 },
33 3 => { Name => 'SeekTable', Binary => 1, Unknown => 1 },
34 4 => {
35 Name => 'VorbisComment',
36 SubDirectory => { TagTable => 'Image::ExifTool::Vorbis::Comments' },
37 },
38 5 => { Name => 'CueSheet', Binary => 1, Unknown => 1 },
39 6 => {
40 Name => 'Picture',
41 SubDirectory => { TagTable => 'Image::ExifTool::FLAC::Picture' },
42 },
43 # 7-126 - Reserved
44 # 127 - Invalid
45);
46
47%Image::ExifTool::FLAC::StreamInfo = (
48 PROCESS_PROC => \&ProcessBitStream,
49 NOTES => 'FLAC is big-endian, so bit 0 is the high-order bit in this table.',
50 GROUPS => { 2 => 'Audio' },
51 'Bit000-015' => 'BlockSizeMin',
52 'Bit016-031' => 'BlockSizeMax',
53 'Bit032-055' => 'FrameSizeMin',
54 'Bit056-079' => 'FrameSizeMax',
55 'Bit080-099' => 'SampleRate',
56 'Bit100-102' => {
57 Name => 'Channels',
58 ValueConv => '$val + 1',
59 },
60 'Bit103-107' => {
61 Name => 'BitsPerSample',
62 ValueConv => '$val + 1',
63 },
64 'Bit108-143' => 'TotalSamples',
65 'Bit144-271' => { #Tim Eliseo
66 Name => 'MD5Signature',
67 Format => 'undef',
68 ValueConv => 'unpack("H*",$val)',
69 },
70);
71
72%Image::ExifTool::FLAC::Picture = (
73 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
74 GROUPS => { 2 => 'Image' },
75 FORMAT => 'int32u',
76 0 => {
77 Name => 'PictureType',
78 PrintConv => { # (Note: Duplicated in ID3, ASF and FLAC modules!)
79 0 => 'Other',
80 1 => '32x32 PNG Icon',
81 2 => 'Other Icon',
82 3 => 'Front Cover',
83 4 => 'Back Cover',
84 5 => 'Leaflet',
85 6 => 'Media',
86 7 => 'Lead Artist',
87 8 => 'Artist',
88 9 => 'Conductor',
89 10 => 'Band',
90 11 => 'Composer',
91 12 => 'Lyricist',
92 13 => 'Recording Studio or Location',
93 14 => 'Recording Session',
94 15 => 'Performance',
95 16 => 'Capture from Movie or Video',
96 17 => 'Bright(ly) Colored Fish',
97 18 => 'Illustration',
98 19 => 'Band Logo',
99 20 => 'Publisher Logo',
100 },
101 },
102 1 => {
103 Name => 'PictureMIMEType',
104 Format => 'var_pstr32',
105 },
106 2 => {
107 Name => 'PictureDescription',
108 Format => 'var_pstr32',
109 ValueConv => '$self->Decode($val, "UTF8")',
110 },
111 3 => 'PictureWidth',
112 4 => 'PictureHeight',
113 5 => 'PictureBitsPerPixel',
114 6 => 'PictureIndexedColors',
115 7 => 'PictureLength',
116 8 => {
117 Name => 'Picture',
118 Groups => { 2 => 'Preview' },
119 Format => 'undef[$val{7}]',
120 Binary => 1,
121 },
122);
123
124# FLAC composite tags
125%Image::ExifTool::FLAC::Composite = (
126 Duration => {
127 Require => {
128 0 => 'FLAC:SampleRate',
129 1 => 'FLAC:TotalSamples',
130 },
131 ValueConv => '($val[0] and $val[1]) ? $val[1] / $val[0] : undef',
132 PrintConv => 'ConvertDuration($val)',
133 },
134);
135
136# add our composite tags
137Image::ExifTool::AddCompositeTags('Image::ExifTool::FLAC');
138
139
140#------------------------------------------------------------------------------
141# Process information in a bit stream
142# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
143# Notes: Byte order is used to determine the ordering of bits in the stream:
144# 'MM' = bit 0 is most significant, 'II' = bit 0 is least significant
145# - can handle arbitrarily wide values (eg. 8-byte or larger integers)
146sub ProcessBitStream($$$)
147{
148 my ($et, $dirInfo, $tagTablePtr) = @_;
149 my $dataPt = $$dirInfo{DataPt};
150 my $dataPos = $$dirInfo{DataPos};
151 my $dirStart = $$dirInfo{DirStart} || 0;
152 my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
153 my $verbose = $et->Options('Verbose');
154 my $byteOrder = GetByteOrder();
155 my $tag;
156
157 if ($verbose) {
158 $et->VPrint(0, " + [BitStream directory, $dirLen bytes, '${byteOrder}' order]\n");
159 }
160 foreach $tag (sort keys %$tagTablePtr) {
161 next unless $tag =~ /^Bit(\d+)-?(\d+)?/;
162 my ($b1, $b2) = ($1, $2 || $1); # start/end bit numbers in stream
163 my ($i1, $i2) = (int($b1 / 8), int($b2 / 8)); # start/end byte numbers
164 my ($f1, $f2) = ($b1 % 8, $b2 % 8); # start/end bit numbers within each byte
165 last if $i2 >= $dirLen;
166 my ($val, $extra);
167 # if Format is unspecified, convert the specified number of bits to an unsigned integer,
168 # otherwise allow HandleTag to convert whole bytes the normal way (via undefined $val)
169 if (ref $$tagTablePtr{$tag} ne 'HASH' or not $$tagTablePtr{$tag}{Format}) {
170 my ($i, $mask);
171 $val = 0;
172 $extra = ', Mask=0x' if $verbose and ($f1 != 0 or $f2 != 7);
173 if ($byteOrder eq 'MM') {
174 # loop from high byte to low byte
175 for ($i=$i1; $i<=$i2; ++$i) {
176 $mask = 0xff;
177 if ($i == $i1 and $f1) {
178 # mask off high bits in first word (0 is high bit)
179 foreach ((8-$f1) .. 7) { $mask ^= (1 << $_) }
180 }
181 if ($i == $i2 and $f2 < 7) {
182 # mask off low bits in last word (7 is low bit)
183 foreach (0 .. (6-$f2)) { $mask ^= (1 << $_) }
184 }
185 $val = $val * 256 + ($mask & Get8u($dataPt, $i + $dirStart));
186 $extra .= sprintf('%.2x', $mask) if $extra;
187 }
188 } else {
189 # (FLAC is big-endian, but support little-endian bit streams
190 # so this routine can be used by other modules)
191 # loop from high byte to low byte
192 for ($i=$i2; $i>=$i1; --$i) {
193 $mask = 0xff;
194 if ($i == $i1 and $f1) {
195 # mask off low bits in first word (0 is low bit)
196 foreach (0 .. ($f1-1)) { $mask ^= (1 << $_) }
197 }
198 if ($i == $i2 and $f2 < 7) {
199 # mask off high bits in last word (7 is high bit)
200 foreach (($f2+1) .. 7) { $mask ^= (1 << $_) }
201 }
202 $val = $val * 256 + ($mask & Get8u($dataPt, $i + $dirStart));
203 $extra .= sprintf('%.2x', $mask) if $extra;
204 }
205 }
206 # shift word down until low bit is in position 0
207 until ($mask & 0x01) {
208 $val /= 2;
209 $mask >>= 1;
210 }
211 }
212 $et->HandleTag($tagTablePtr, $tag, $val,
213 DataPt => $dataPt,
214 DataPos => $dataPos,
215 Start => $dirStart + $i1,
216 Size => $i2 - $i1 + 1,
217 Extra => $extra,
218 );
219 }
220 return 1;
221}
222
223#------------------------------------------------------------------------------
224# Extract information from an Ogg FLAC file
225# Inputs: 0) ExifTool object reference, 1) dirInfo reference
226# Returns: 1 on success, 0 if this wasn't a valid Ogg FLAC file
227sub ProcessFLAC($$)
228{
229 my ($et, $dirInfo) = @_;
230
231 # must first check for leading/trailing ID3 information
232 unless ($$et{DoneID3}) {
233 require Image::ExifTool::ID3;
234 Image::ExifTool::ID3::ProcessID3($et, $dirInfo) and return 1;
235 }
236 my $raf = $$dirInfo{RAF};
237 my $verbose = $et->Options('Verbose');
238 my $out = $et->Options('TextOut');
239 my ($buff, $err);
240
241 # check FLAC signature
242 $raf->Read($buff, 4) == 4 and $buff eq 'fLaC' or return 0;
243 $et->SetFileType();
244 SetByteOrder('MM');
245 my $tagTablePtr = GetTagTable('Image::ExifTool::FLAC::Main');
246 for (;;) {
247 # read next metadata block header
248 $raf->Read($buff, 4) == 4 or last;
249 my $flag = unpack('C', $buff);
250 my $size = unpack('N', $buff) & 0x00ffffff;
251 $raf->Read($buff, $size) == $size or $err = 1, last;
252 my $last = $flag & 0x80; # last-metadata-block flag
253 my $tag = $flag & 0x7f; # tag bits
254 if ($verbose) {
255 print $out "FLAC metadata block, type $tag:\n";
256 $et->VerboseDump(\$buff, DataPos => $raf->Tell() - $size);
257 }
258 $et->HandleTag($tagTablePtr, $tag, undef,
259 DataPt => \$buff,
260 DataPos => $raf->Tell() - $size,
261 );
262 last if $last; # all done if is set
263 }
264 $err and $et->Warn('Format error in FLAC file');
265 return 1;
266}
267
2681; # end
269
270__END__
271
272=head1 NAME
273
274Image::ExifTool::FLAC - Read Free Lossless Audio Codec information
275
276=head1 SYNOPSIS
277
278This module is used by Image::ExifTool
279
280=head1 DESCRIPTION
281
282This module contains definitions required by Image::ExifTool to extract meta
283information from Free Lossless Audio Codec (FLAC) audio files.
284
285=head1 AUTHOR
286
287Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
288
289This library is free software; you can redistribute it and/or modify it
290under the same terms as Perl itself.
291
292=head1 REFERENCES
293
294=over 4
295
296=item L<http://flac.sourceforge.net/>
297
298=back
299
300=head1 SEE ALSO
301
302L<Image::ExifTool::TagNames/FLAC Tags>,
303L<Image::ExifTool::TagNames/Ogg Tags>,
304L<Image::ExifTool(3pm)|Image::ExifTool>
305
306=cut
307
Note: See TracBrowser for help on using the repository browser.