source: gsdl/trunk/perllib/cpan/Image/ExifTool/AIFF.pm@ 16842

Last change on this file since 16842 was 16842, checked in by davidb, 16 years ago

ExifTool added to cpan area to support metadata extraction from files such as JPEG. Primarily targetted as Image files (hence the Image folder name decided upon by the ExifTool author) it also can handle video such as flash and audio such as Wav

File size: 6.6 KB
Line 
1#------------------------------------------------------------------------------
2# File: AIFF.pm
3#
4# Description: Read AIFF meta information
5#
6# Revisions: 01/06/2006 - P. Harvey Created
7#
8# References: 1) http://developer.apple.com/documentation/QuickTime/INMAC/SOUND/imsoundmgr.30.htm#pgfId=3190
9# 2) http://astronomy.swin.edu.au/~pbourke/dataformats/aiff/
10# 3) http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/
11#------------------------------------------------------------------------------
12
13package Image::ExifTool::AIFF;
14
15use strict;
16use vars qw($VERSION);
17use Image::ExifTool qw(:DataAccess :Utils);
18use Image::ExifTool::ID3;
19
20$VERSION = '1.01';
21
22# information for time/date-based tags (time zero is Jan 1, 1904)
23my %timeInfo = (
24 Groups => { 2 => 'Time' },
25 ValueConv => 'ConvertUnixTime($val - ((66 * 365 + 17) * 24 * 3600))',
26 PrintConv => '$self->ConvertDateTime($val)',
27);
28
29# AIFF info
30%Image::ExifTool::AIFF::Main = (
31 PROCESS_PROC => \&Image::ExifTool::AIFF::ProcessSubChunks,
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 $verbose = $exifTool->Options('Verbose');
140 my ($buff, $err);
141
142 # verify this is a valid AIFF file
143 return 0 unless $raf->Read($buff, 12) == 12;
144 return 0 unless $buff =~ /^FORM....(AIF(F|C))/s;
145 $exifTool->SetFileType($1);
146 SetByteOrder('MM');
147 my $tagTablePtr = GetTagTable('Image::ExifTool::AIFF::Main');
148 my $pos = 12;
149#
150# Read chunks in AIFF image
151#
152 for (;;) {
153 $raf->Read($buff, 8) == 8 or last;
154 $pos += 8;
155 my ($tag, $len) = unpack('a4N', $buff);
156 my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
157 $exifTool->VPrint(0, "AIFF '$tag' chunk ($len bytes of data):\n");
158 # AIFF chunks are padded to an even number of bytes
159 my $len2 = $len + ($len & 0x01);
160 if ($tagInfo) {
161 $raf->Read($buff, $len2) == $len2 or $err=1, last;
162 $exifTool->HandleTag($tagTablePtr, $tag, $buff,
163 DataPt => \$buff,
164 DataPos => $pos,
165 Start => 0,
166 Size => $len,
167 );
168 } else {
169 $raf->Seek($len2, 1) or $err=1, last;
170 }
171 $pos += $len2;
172 }
173 $err and $exifTool->Warn('Error reading AIFF file (corrupted?)');
174 return 1;
175}
176
1771; # end
178
179__END__
180
181=head1 NAME
182
183Image::ExifTool::AIFF - Read AIFF meta information
184
185=head1 SYNOPSIS
186
187This module is used by Image::ExifTool
188
189=head1 DESCRIPTION
190
191This module contains routines required by Image::ExifTool to extract
192information from AIFF (Audio Interchange File Format) audio files.
193
194=head1 AUTHOR
195
196Copyright 2003-2007, Phil Harvey (phil at owl.phy.queensu.ca)
197
198This library is free software; you can redistribute it and/or modify it
199under the same terms as Perl itself.
200
201=head1 REFERENCES
202
203=over 4
204
205=item L<http://developer.apple.com/documentation/QuickTime/INMAC/SOUND/imsoundmgr.30.htm#pgfId=3190>
206
207=item L<http://astronomy.swin.edu.au/~pbourke/dataformats/aiff/>
208
209=item L<http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/>
210
211=back
212
213=head1 SEE ALSO
214
215L<Image::ExifTool::TagNames/AIFF Tags>,
216L<Image::ExifTool(3pm)|Image::ExifTool>
217
218=cut
219
Note: See TracBrowser for help on using the repository browser.