source: gs2-extensions/parallel-building/trunk/src/perllib/cpan/Image/ExifTool/AIFF.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: 7.5 KB
Line 
1#------------------------------------------------------------------------------
2# File: AIFF.pm
3#
4# Description: Read AIFF meta information
5#
6# Revisions: 01/06/2006 - P. Harvey Created
7# 09/22/2008 - PH Added DjVu support
8#
9# References: 1) http://developer.apple.com/documentation/QuickTime/INMAC/SOUND/imsoundmgr.30.htm#pgfId=3190
10# 2) http://astronomy.swin.edu.au/~pbourke/dataformats/aiff/
11# 3) http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/
12#------------------------------------------------------------------------------
13
14package Image::ExifTool::AIFF;
15
16use strict;
17use vars qw($VERSION);
18use Image::ExifTool qw(:DataAccess :Utils);
19use Image::ExifTool::ID3;
20
21$VERSION = '1.03';
22
23# information for time/date-based tags (time zero is Jan 1, 1904)
24my %timeInfo = (
25 Groups => { 2 => 'Time' },
26 ValueConv => 'ConvertUnixTime($val - ((66 * 365 + 17) * 24 * 3600))',
27 PrintConv => '$self->ConvertDateTime($val)',
28);
29
30# AIFF info
31%Image::ExifTool::AIFF::Main = (
32 GROUPS => { 2 => 'Audio' },
33 NOTES => 'Only the tags decoded by ExifTool are listed in this table.',
34# FORM => 'Format',
35 FVER => {
36 Name => 'FormatVersion',
37 SubDirectory => { TagTable => 'Image::ExifTool::AIFF::FormatVers' },
38 },
39 COMM => {
40 Name => 'Common',
41 SubDirectory => { TagTable => 'Image::ExifTool::AIFF::Common' },
42 },
43 COMT => {
44 Name => 'Comment',
45 SubDirectory => { TagTable => 'Image::ExifTool::AIFF::Comment' },
46 },
47 NAME => 'Name',
48 AUTH => { Name => 'Author', Groups => { 2 => 'Author' } },
49 '(c) ' => { Name => 'Copyright', Groups => { 2 => 'Author' } },
50 ANNO => 'Annotation',
51 'ID3 ' => {
52 Name => 'ID3',
53 SubDirectory => {
54 TagTable => 'Image::ExifTool::ID3::Main',
55 ProcessProc => \&Image::ExifTool::ID3::ProcessID3,
56 },
57 },
58# SSND => 'SoundData',
59# MARK => 'Marker',
60# INST => 'Instrument',
61# MIDI => 'MidiData',
62# AESD => 'AudioRecording',
63# APPL => 'ApplicationSpecific',
64);
65
66%Image::ExifTool::AIFF::Common = (
67 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
68 GROUPS => { 2 => 'Audio' },
69 FORMAT => 'int16u',
70 0 => 'NumChannels',
71 1 => { Name => 'NumSampleFrames', Format => 'int32u' },
72 3 => 'SampleSize',
73 4 => { Name => 'SampleRate', Format => 'extended' }, #3
74 9 => {
75 Name => 'CompressionType',
76 Format => 'string[4]',
77 PrintConv => {
78 NONE => 'None',
79 ACE2 => 'ACE 2-to-1',
80 ACE8 => 'ACE 8-to-3',
81 MAC3 => 'MAC 3-to-1',
82 MAC6 => 'MAC 6-to-1',
83 sowt => 'Little-endian, no compression',
84 },
85 },
86);
87
88%Image::ExifTool::AIFF::FormatVers = (
89 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
90 FORMAT => 'int32u',
91 0 => { Name => 'FormatVersionTime', %timeInfo },
92);
93
94%Image::ExifTool::AIFF::Comment = (
95 PROCESS_PROC => \&Image::ExifTool::AIFF::ProcessComment,
96 GROUPS => { 2 => 'Audio' },
97 0 => { Name => 'CommentTime', %timeInfo },
98 1 => 'MarkerID',
99 2 => 'Comment',
100);
101
102#------------------------------------------------------------------------------
103# Process AIFF Comment chunk
104# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) tag table ref
105# Returns: 1 on success
106sub ProcessComment($$$)
107{
108 my ($exifTool, $dirInfo, $tagTablePtr) = @_;
109 my $dataPt = $$dirInfo{DataPt};
110 my $dirLen = $$dirInfo{DirLen};
111 my $verbose = $exifTool->Options('Verbose');
112 return 0 unless $dirLen > 2;
113 my $numComments = unpack('n',$$dataPt);
114 my $pos = 2;
115 my $i;
116 $verbose and $exifTool->VerboseDir('Comment', $numComments);
117 for ($i=0; $i<$numComments; ++$i) {
118 last if $pos + 8 > $dirLen;
119 my ($time, $markerID, $size) = unpack("x${pos}Nnn", $$dataPt);
120 $exifTool->HandleTag($tagTablePtr, 0, $time);
121 $exifTool->HandleTag($tagTablePtr, 1, $markerID) if $markerID;
122 $pos += 8;
123 last if $pos + $size > $dirLen;
124 my $val = substr($$dataPt, $pos, $size);
125 $exifTool->HandleTag($tagTablePtr, 2, $val);
126 ++$size if $size & 0x01; # account for padding byte if necessary
127 $pos += $size;
128 }
129}
130
131#------------------------------------------------------------------------------
132# Extract information from a AIFF file
133# Inputs: 0) ExifTool object reference, 1) DirInfo reference
134# Returns: 1 on success, 0 if this wasn't a valid AIFF file
135sub ProcessAIFF($$)
136{
137 my ($exifTool, $dirInfo) = @_;
138 my $raf = $$dirInfo{RAF};
139 my ($buff, $err, $tagTablePtr, $page, $type);
140
141 # verify this is a valid AIFF file
142 return 0 unless $raf->Read($buff, 12) == 12;
143 my $pos = 12;
144 # check for DjVu image
145 if ($buff =~ /^AT&TFORM/) {
146 # http://www.djvu.org/
147 # http://djvu.sourceforge.net/specs/djvu3changes.txt
148 my $buf2;
149 return 0 unless $raf->Read($buf2, 4) == 4 and $buf2 =~ /^(DJVU|DJVM)/;
150 $pos += 4;
151 $buff = substr($buff, 4) . $buf2;
152 $tagTablePtr = GetTagTable('Image::ExifTool::DjVu::Main');
153 $exifTool->SetFileType('DJVU');
154 # modifiy FileType to indicate a multi-page document
155 $exifTool->{VALUE}->{FileType} .= " (multi-page)" if $buf2 eq 'DJVM';
156 $type = 'DjVu';
157 } else {
158 return 0 unless $buff =~ /^FORM....(AIF(F|C))/s;
159 $exifTool->SetFileType($1);
160 $tagTablePtr = GetTagTable('Image::ExifTool::AIFF::Main');
161 $type = 'AIFF';
162 }
163 SetByteOrder('MM');
164#
165# Read through the IFF chunks
166#
167 for (;;) {
168 $raf->Read($buff, 8) == 8 or last;
169 $pos += 8;
170 my ($tag, $len) = unpack('a4N', $buff);
171 my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
172 $exifTool->VPrint(0, "AIFF '$tag' chunk ($len bytes of data):\n");
173 # AIFF chunks are padded to an even number of bytes
174 my $len2 = $len + ($len & 0x01);
175 if ($tagInfo) {
176 if ($$tagInfo{TypeOnly}) {
177 $len = $len2 = 4;
178 $page = ($page || 0) + 1;
179 $exifTool->VPrint(0, $exifTool->{INDENT} . "Page $page:\n");
180 }
181 $raf->Read($buff, $len2) >= $len or $err=1, last;
182 unless ($$tagInfo{SubDirectory} or $$tagInfo{Binary}) {
183 $buff =~ s/\0+$//; # remove trailing nulls
184 }
185 $exifTool->HandleTag($tagTablePtr, $tag, $buff,
186 DataPt => \$buff,
187 DataPos => $pos,
188 Start => 0,
189 Size => $len,
190 );
191 } else {
192 $raf->Seek($len2, 1) or $err=1, last;
193 }
194 $pos += $len2;
195 }
196 $err and $exifTool->Warn("Error reading $type file (corrupted?)");
197 return 1;
198}
199
2001; # end
201
202__END__
203
204=head1 NAME
205
206Image::ExifTool::AIFF - Read AIFF meta information
207
208=head1 SYNOPSIS
209
210This module is used by Image::ExifTool
211
212=head1 DESCRIPTION
213
214This module contains routines required by Image::ExifTool to extract
215information from AIFF (Audio Interchange File Format) audio files.
216
217=head1 AUTHOR
218
219Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
220
221This library is free software; you can redistribute it and/or modify it
222under the same terms as Perl itself.
223
224=head1 REFERENCES
225
226=over 4
227
228=item L<http://developer.apple.com/documentation/QuickTime/INMAC/SOUND/imsoundmgr.30.htm#pgfId=3190>
229
230=item L<http://astronomy.swin.edu.au/~pbourke/dataformats/aiff/>
231
232=item L<http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/>
233
234=back
235
236=head1 SEE ALSO
237
238L<Image::ExifTool::TagNames/AIFF Tags>,
239L<Image::ExifTool(3pm)|Image::ExifTool>
240
241=cut
Note: See TracBrowser for help on using the repository browser.