source: gs2-extensions/parallel-building/trunk/src/perllib/cpan/Image/ExifTool/FLAC.pm@ 24626

Last change on this file since 24626 was 24626, checked in by jmt12, 13 years ago

An (almost) complete copy of the perllib directory from a (circa SEP2011) head checkout from Greenstone 2 trunk - in order to try and make merging in this extension a little easier later on (as there have been some major changes to buildcol.pl commited in the main trunk but not in the x64 branch)

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