~ubuntu-branches/ubuntu/hardy/gallery2/hardy-security

« back to all changes in this revision

Viewing changes to modules/getid3/lib/getid3/module.tag.lyrics3.inc

  • Committer: Bazaar Package Importer
  • Author(s): Michael C. Schultheiss
  • Date: 2006-04-16 16:42:35 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20060416164235-8uy0u4bfjdxpge2o
Tags: 2.1.1-1
* New upstream release (Closes: #362936)
  + Bugfixes for Postgres7 (Closes: #359000, #362152)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/////////////////////////////////////////////////////////////////
 
3
/// getID3() by James Heinrich <info@getid3.org>               //
 
4
//  available at http://getid3.sourceforge.net                 //
 
5
//            or http://www.getid3.org                         //
 
6
/////////////////////////////////////////////////////////////////
 
7
// See readme.txt for more details                             //
 
8
/////////////////////////////////////////////////////////////////
 
9
///                                                            //
 
10
// module.tag.lyrics3.php                                      //
 
11
// module for analyzing Lyrics3 tags                           //
 
12
// dependencies: module.tag.apetag.php (optional)              //
 
13
//                                                            ///
 
14
/////////////////////////////////////////////////////////////////
 
15
 
 
16
 
 
17
class getid3_lyrics3
 
18
{
 
19
 
 
20
        function getid3_lyrics3(&$fd, &$ThisFileInfo) {
 
21
                // http://www.volweb.cz/str/tags.htm
 
22
 
 
23
                fseek($fd, (0 - 128 - 9 - 6), SEEK_END);          // end - ID3v1 - LYRICSEND - [Lyrics3size]
 
24
                $lyrics3_id3v1 = fread($fd, 128 + 9 + 6);
 
25
                $lyrics3lsz    = substr($lyrics3_id3v1,  0,   6); // Lyrics3size
 
26
                $lyrics3end    = substr($lyrics3_id3v1,  6,   9); // LYRICSEND or LYRICS200
 
27
                $id3v1tag      = substr($lyrics3_id3v1, 15, 128); // ID3v1
 
28
 
 
29
                if ($lyrics3end == 'LYRICSEND') {
 
30
                        // Lyrics3v1, ID3v1, no APE
 
31
 
 
32
                        $lyrics3size    = 5100;
 
33
                        $lyrics3offset  = $ThisFileInfo['filesize'] - 128 - $lyrics3size;
 
34
                        $lyrics3version = 1;
 
35
 
 
36
                } elseif ($lyrics3end == 'LYRICS200') {
 
37
                        // Lyrics3v2, ID3v1, no APE
 
38
 
 
39
                        // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
 
40
                        $lyrics3size    = $lyrics3lsz + 6 + strlen('LYRICS200');
 
41
                        $lyrics3offset  = $ThisFileInfo['filesize'] - 128 - $lyrics3size;
 
42
                        $lyrics3version = 2;
 
43
 
 
44
                } elseif (substr(strrev($lyrics3_id3v1), 0, 9) == strrev('LYRICSEND')) {
 
45
                        // Lyrics3v1, no ID3v1, no APE
 
46
 
 
47
                        $lyrics3size    = 5100;
 
48
                        $lyrics3offset  = $ThisFileInfo['filesize'] - $lyrics3size;
 
49
                        $lyrics3version = 1;
 
50
                        $lyrics3offset  = $ThisFileInfo['filesize'] - $lyrics3size;
 
51
 
 
52
                } elseif (substr(strrev($lyrics3_id3v1), 0, 9) == strrev('LYRICS200')) {
 
53
 
 
54
                        // Lyrics3v2, no ID3v1, no APE
 
55
 
 
56
                        $lyrics3size    = strrev(substr(strrev($lyrics3_id3v1), 9, 6)) + 6 + strlen('LYRICS200'); // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
 
57
                        $lyrics3offset  = $ThisFileInfo['filesize'] - $lyrics3size;
 
58
                        $lyrics3version = 2;
 
59
 
 
60
                } else {
 
61
 
 
62
                        if (isset($ThisFileInfo['ape']['tag_offset_start']) && ($ThisFileInfo['ape']['tag_offset_start'] > 15)) {
 
63
 
 
64
                                fseek($fd, $ThisFileInfo['ape']['tag_offset_start'] - 15, SEEK_SET);
 
65
                                $lyrics3lsz = fread($fd, 6);
 
66
                                $lyrics3end = fread($fd, 9);
 
67
 
 
68
                                if ($lyrics3end == 'LYRICSEND') {
 
69
                                        // Lyrics3v1, APE, maybe ID3v1
 
70
 
 
71
                                        $lyrics3size    = 5100;
 
72
                                        $lyrics3offset  = $ThisFileInfo['ape']['tag_offset_start'] - $lyrics3size;
 
73
                                        $ThisFileInfo['avdataend'] = $lyrics3offset;
 
74
                                        $lyrics3version = 1;
 
75
                                        $ThisFileInfo['warning'][] = 'APE tag located after Lyrics3, will probably break Lyrics3 compatability';
 
76
 
 
77
                                } elseif ($lyrics3end == 'LYRICS200') {
 
78
                                        // Lyrics3v2, APE, maybe ID3v1
 
79
 
 
80
                                        $lyrics3size    = $lyrics3lsz + 6 + strlen('LYRICS200'); // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
 
81
                                        $lyrics3offset  = $ThisFileInfo['ape']['tag_offset_start'] - $lyrics3size;
 
82
                                        $lyrics3version = 2;
 
83
                                        $ThisFileInfo['warning'][] = 'APE tag located after Lyrics3, will probably break Lyrics3 compatability';
 
84
 
 
85
                                }
 
86
 
 
87
                        }
 
88
 
 
89
                }
 
90
 
 
91
                if (isset($lyrics3offset)) {
 
92
                        $ThisFileInfo['avdataend'] = $lyrics3offset;
 
93
                        $this->getLyrics3Data($ThisFileInfo, $fd, $lyrics3offset, $lyrics3version, $lyrics3size);
 
94
 
 
95
                        if (!isset($ThisFileInfo['ape'])) {
 
96
                                $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
 
97
                                if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.apetag.inc', __FILE__, false)) {
 
98
                                        $tag = new getid3_apetag($fd, $ThisFileInfo, $ThisFileInfo['lyrics3']['tag_offset_start']);
 
99
                                }
 
100
                        }
 
101
 
 
102
                }
 
103
 
 
104
                return true;
 
105
        }
 
106
 
 
107
        function getLyrics3Data(&$ThisFileInfo, &$fd, $endoffset, $version, $length) {
 
108
                // http://www.volweb.cz/str/tags.htm
 
109
 
 
110
                fseek($fd, $endoffset, SEEK_SET);
 
111
                if ($length <= 0) {
 
112
                        return false;
 
113
                }
 
114
                $rawdata = fread($fd, $length);
 
115
 
 
116
                if (substr($rawdata, 0, 11) != 'LYRICSBEGIN') {
 
117
                        if (strpos($rawdata, 'LYRICSBEGIN') !== false) {
 
118
 
 
119
                                $ThisFileInfo['warning'][] = '"LYRICSBEGIN" expected at '.$endoffset.' but actually found at '.($endoffset + strpos($rawdata, 'LYRICSBEGIN')).' - this is invalid for Lyrics3 v'.$version;
 
120
                                $ThisFileInfo['avdataend'] = $endoffset + strpos($rawdata, 'LYRICSBEGIN');
 
121
                                $ParsedLyrics3['tag_offset_start'] = $ThisFileInfo['avdataend'];
 
122
                                $rawdata = substr($rawdata, strpos($rawdata, 'LYRICSBEGIN'));
 
123
                                $length = strlen($rawdata);
 
124
 
 
125
                        } else {
 
126
 
 
127
                                $ThisFileInfo['error'][] = '"LYRICSBEGIN" expected at '.$endoffset.' but found "'.substr($rawdata, 0, 11).'" instead';
 
128
                                return false;
 
129
 
 
130
                        }
 
131
 
 
132
                }
 
133
 
 
134
                $ParsedLyrics3['raw']['lyrics3version'] = $version;
 
135
                $ParsedLyrics3['raw']['lyrics3tagsize'] = $length;
 
136
                $ParsedLyrics3['tag_offset_start']      = $endoffset;
 
137
                $ParsedLyrics3['tag_offset_end']        = $endoffset + $length;
 
138
 
 
139
                switch ($version) {
 
140
 
 
141
                        case 1:
 
142
                                if (substr($rawdata, strlen($rawdata) - 9, 9) == 'LYRICSEND') {
 
143
                                        $ParsedLyrics3['raw']['LYR'] = trim(substr($rawdata, 11, strlen($rawdata) - 11 - 9));
 
144
                                        $this->Lyrics3LyricsTimestampParse($ParsedLyrics3);
 
145
                                } else {
 
146
                                        $ThisFileInfo['error'][] = '"LYRICSEND" expected at '.(ftell($fd) - 11 + $length - 9).' but found "'.substr($rawdata, strlen($rawdata) - 9, 9).'" instead';
 
147
                                        return false;
 
148
                                }
 
149
                                break;
 
150
 
 
151
                        case 2:
 
152
                                if (substr($rawdata, strlen($rawdata) - 9, 9) == 'LYRICS200') {
 
153
                                        $ParsedLyrics3['raw']['unparsed'] = substr($rawdata, 11, strlen($rawdata) - 11 - 9 - 6); // LYRICSBEGIN + LYRICS200 + LSZ
 
154
                                        $rawdata = $ParsedLyrics3['raw']['unparsed'];
 
155
                                        while (strlen($rawdata) > 0) {
 
156
                                                $fieldname = substr($rawdata, 0, 3);
 
157
                                                $fieldsize = (int) substr($rawdata, 3, 5);
 
158
                                                $ParsedLyrics3['raw'][$fieldname] = substr($rawdata, 8, $fieldsize);
 
159
                                                $rawdata = substr($rawdata, 3 + 5 + $fieldsize);
 
160
                                        }
 
161
 
 
162
                                        if (isset($ParsedLyrics3['raw']['IND'])) {
 
163
                                                $i = 0;
 
164
                                                $flagnames = array('lyrics', 'timestamps', 'inhibitrandom');
 
165
                                                foreach ($flagnames as $flagname) {
 
166
                                                        if (strlen($ParsedLyrics3['raw']['IND']) > ++$i) {
 
167
                                                                $ParsedLyrics3['flags'][$flagname] = $this->IntString2Bool(substr($ParsedLyrics3['raw']['IND'], $i, 1));
 
168
                                                        }
 
169
                                                }
 
170
                                        }
 
171
 
 
172
                                        $fieldnametranslation = array('ETT'=>'title', 'EAR'=>'artist', 'EAL'=>'album', 'INF'=>'comment', 'AUT'=>'author');
 
173
                                        foreach ($fieldnametranslation as $key => $value) {
 
174
                                                if (isset($ParsedLyrics3['raw'][$key])) {
 
175
                                                        $ParsedLyrics3['comments'][$value][] = trim($ParsedLyrics3['raw'][$key]);
 
176
                                                }
 
177
                                        }
 
178
 
 
179
                                        if (isset($ParsedLyrics3['raw']['IMG'])) {
 
180
                                                $imagestrings = explode("\r\n", $ParsedLyrics3['raw']['IMG']);
 
181
                                                foreach ($imagestrings as $key => $imagestring) {
 
182
                                                        if (strpos($imagestring, '||') !== false) {
 
183
                                                                $imagearray = explode('||', $imagestring);
 
184
                                                                $ParsedLyrics3['images'][$key]['filename']     = $imagearray[0];
 
185
                                                                $ParsedLyrics3['images'][$key]['description']  = $imagearray[1];
 
186
                                                                $ParsedLyrics3['images'][$key]['timestamp']    = $this->Lyrics3Timestamp2Seconds($imagearray[2]);
 
187
                                                        }
 
188
                                                }
 
189
                                        }
 
190
                                        if (isset($ParsedLyrics3['raw']['LYR'])) {
 
191
                                                $this->Lyrics3LyricsTimestampParse($ParsedLyrics3);
 
192
                                        }
 
193
                                } else {
 
194
                                        $ThisFileInfo['error'][] = '"LYRICS200" expected at '.(ftell($fd) - 11 + $length - 9).' but found "'.substr($rawdata, strlen($rawdata) - 9, 9).'" instead';
 
195
                                        return false;
 
196
                                }
 
197
                                break;
 
198
 
 
199
                        default:
 
200
                                $ThisFileInfo['error'][] = 'Cannot process Lyrics3 version '.$version.' (only v1 and v2)';
 
201
                                return false;
 
202
                                break;
 
203
                }
 
204
 
 
205
 
 
206
                if (isset($ThisFileInfo['id3v1']['tag_offset_start']) && ($ThisFileInfo['id3v1']['tag_offset_start'] < $ParsedLyrics3['tag_offset_end'])) {
 
207
                        $ThisFileInfo['warning'][] = 'ID3v1 tag information ignored since it appears to be a false synch in Lyrics3 tag data';
 
208
                        unset($ThisFileInfo['id3v1']);
 
209
                        foreach ($ThisFileInfo['warning'] as $key => $value) {
 
210
                                if ($value == 'Some ID3v1 fields do not use NULL characters for padding') {
 
211
                                        unset($ThisFileInfo['warning'][$key]);
 
212
                                        sort($ThisFileInfo['warning']);
 
213
                                        break;
 
214
                                }
 
215
                        }
 
216
                }
 
217
 
 
218
                $ThisFileInfo['lyrics3'] = $ParsedLyrics3;
 
219
 
 
220
                return true;
 
221
        }
 
222
 
 
223
        function Lyrics3Timestamp2Seconds($rawtimestamp) {
 
224
                if (ereg('^\\[([0-9]{2}):([0-9]{2})\\]$', $rawtimestamp, $regs)) {
 
225
                        return (int) (($regs[1] * 60) + $regs[2]);
 
226
                }
 
227
                return false;
 
228
        }
 
229
 
 
230
        function Lyrics3LyricsTimestampParse(&$Lyrics3data) {
 
231
                $lyricsarray = explode("\r\n", $Lyrics3data['raw']['LYR']);
 
232
                foreach ($lyricsarray as $key => $lyricline) {
 
233
                        $regs = array();
 
234
                        unset($thislinetimestamps);
 
235
                        while (ereg('^(\\[[0-9]{2}:[0-9]{2}\\])', $lyricline, $regs)) {
 
236
                                $thislinetimestamps[] = $this->Lyrics3Timestamp2Seconds($regs[0]);
 
237
                                $lyricline = str_replace($regs[0], '', $lyricline);
 
238
                        }
 
239
                        $notimestamplyricsarray[$key] = $lyricline;
 
240
                        if (isset($thislinetimestamps) && is_array($thislinetimestamps)) {
 
241
                                sort($thislinetimestamps);
 
242
                                foreach ($thislinetimestamps as $timestampkey => $timestamp) {
 
243
                                        if (isset($Lyrics3data['synchedlyrics'][$timestamp])) {
 
244
                                                // timestamps only have a 1-second resolution, it's possible that multiple lines
 
245
                                                // could have the same timestamp, if so, append
 
246
                                                $Lyrics3data['synchedlyrics'][$timestamp] .= "\r\n".$lyricline;
 
247
                                        } else {
 
248
                                                $Lyrics3data['synchedlyrics'][$timestamp] = $lyricline;
 
249
                                        }
 
250
                                }
 
251
                        }
 
252
                }
 
253
                $Lyrics3data['unsynchedlyrics'] = implode("\r\n", $notimestamplyricsarray);
 
254
                if (isset($Lyrics3data['synchedlyrics']) && is_array($Lyrics3data['synchedlyrics'])) {
 
255
                        ksort($Lyrics3data['synchedlyrics']);
 
256
                }
 
257
                return true;
 
258
        }
 
259
 
 
260
        function IntString2Bool($char) {
 
261
                if ($char == '1') {
 
262
                        return true;
 
263
                } elseif ($char == '0') {
 
264
                        return false;
 
265
                }
 
266
                return null;
 
267
        }
 
268
}
 
269
 
 
270
 
 
271
?>