Blame view

sources/3rdparty/getid3/module.audio.flac.php 17.6 KB
03e52840d   Kload   Init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  <?php
  /////////////////////////////////////////////////////////////////
  /// getID3() by James Heinrich <info@getid3.org>               //
  //  available at http://getid3.sourceforge.net                 //
  //            or http://www.getid3.org                         //
  /////////////////////////////////////////////////////////////////
  // See readme.txt for more details                             //
  /////////////////////////////////////////////////////////////////
  //                                                             //
  // module.audio.flac.php                                       //
  // module for analyzing FLAC and OggFLAC audio files           //
  // dependencies: module.audio.ogg.php                          //
  //                                                            ///
  /////////////////////////////////////////////////////////////////
  
  
  getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ogg.php', __FILE__, true);
31b7f2792   Kload   Upgrade to ownclo...
18
19
20
  /**
  * @tutorial http://flac.sourceforge.net/format.html
  */
03e52840d   Kload   Init
21
22
  class getid3_flac extends getid3_handler
  {
31b7f2792   Kload   Upgrade to ownclo...
23
  	const syncword = 'fLaC';
03e52840d   Kload   Init
24

31b7f2792   Kload   Upgrade to ownclo...
25
  	public function Analyze() {
03e52840d   Kload   Init
26
  		$info = &$this->getid3->info;
31b7f2792   Kload   Upgrade to ownclo...
27
  		$this->fseek($info['avdataoffset']);
03e52840d   Kload   Init
28
  		$StreamMarker = $this->fread(4);
31b7f2792   Kload   Upgrade to ownclo...
29
30
  		if ($StreamMarker != self::syncword) {
  			return $this->error('Expecting "'.getid3_lib::PrintHexBytes(self::syncword).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($StreamMarker).'"');
03e52840d   Kload   Init
31
32
33
34
35
  		}
  		$info['fileformat']            = 'flac';
  		$info['audio']['dataformat']   = 'flac';
  		$info['audio']['bitrate_mode'] = 'vbr';
  		$info['audio']['lossless']     = true;
31b7f2792   Kload   Upgrade to ownclo...
36
37
  		// parse flac container
  		return $this->parseMETAdata();
03e52840d   Kload   Init
38
  	}
31b7f2792   Kload   Upgrade to ownclo...
39
  	public function parseMETAdata() {
03e52840d   Kload   Init
40
41
  		$info = &$this->getid3->info;
  		do {
31b7f2792   Kload   Upgrade to ownclo...
42
43
44
45
46
47
48
49
50
51
  			$BlockOffset   = $this->ftell();
  			$BlockHeader   = $this->fread(4);
  			$LBFBT         = getid3_lib::BigEndian2Int(substr($BlockHeader, 0, 1));
  			$LastBlockFlag = (bool) ($LBFBT & 0x80);
  			$BlockType     =        ($LBFBT & 0x7F);
  			$BlockLength   = getid3_lib::BigEndian2Int(substr($BlockHeader, 1, 3));
  			$BlockTypeText = self::metaBlockTypeLookup($BlockType);
  
  			if (($BlockOffset + 4 + $BlockLength) > $info['avdataend']) {
  				$this->error('METADATA_BLOCK_HEADER.BLOCK_TYPE ('.$BlockTypeText.') at offset '.$BlockOffset.' extends beyond end of file');
03e52840d   Kload   Init
52
53
  				break;
  			}
31b7f2792   Kload   Upgrade to ownclo...
54
55
  			if ($BlockLength < 1) {
  				$this->error('METADATA_BLOCK_HEADER.BLOCK_LENGTH ('.$BlockLength.') at offset '.$BlockOffset.' is invalid');
03e52840d   Kload   Init
56
57
  				break;
  			}
31b7f2792   Kload   Upgrade to ownclo...
58
59
60
61
62
63
64
65
66
67
68
  
  			$info['flac'][$BlockTypeText]['raw'] = array();
  			$BlockTypeText_raw = &$info['flac'][$BlockTypeText]['raw'];
  
  			$BlockTypeText_raw['offset']          = $BlockOffset;
  			$BlockTypeText_raw['last_meta_block'] = $LastBlockFlag;
  			$BlockTypeText_raw['block_type']      = $BlockType;
  			$BlockTypeText_raw['block_type_text'] = $BlockTypeText;
  			$BlockTypeText_raw['block_length']    = $BlockLength;
  			if ($BlockTypeText_raw['block_type'] != 0x06) { // do not read attachment data automatically
  				$BlockTypeText_raw['block_data']  = $this->fread($BlockLength);
03e52840d   Kload   Init
69
  			}
03e52840d   Kload   Init
70

31b7f2792   Kload   Upgrade to ownclo...
71
  			switch ($BlockTypeText) {
03e52840d   Kload   Init
72
  				case 'STREAMINFO':     // 0x00
31b7f2792   Kload   Upgrade to ownclo...
73
  					if (!$this->parseSTREAMINFO($BlockTypeText_raw['block_data'])) {
03e52840d   Kload   Init
74
75
76
77
78
  						return false;
  					}
  					break;
  
  				case 'PADDING':        // 0x01
31b7f2792   Kload   Upgrade to ownclo...
79
  					unset($info['flac']['PADDING']); // ignore
03e52840d   Kload   Init
80
81
82
  					break;
  
  				case 'APPLICATION':    // 0x02
31b7f2792   Kload   Upgrade to ownclo...
83
  					if (!$this->parseAPPLICATION($BlockTypeText_raw['block_data'])) {
03e52840d   Kload   Init
84
85
86
87
88
  						return false;
  					}
  					break;
  
  				case 'SEEKTABLE':      // 0x03
31b7f2792   Kload   Upgrade to ownclo...
89
  					if (!$this->parseSEEKTABLE($BlockTypeText_raw['block_data'])) {
03e52840d   Kload   Init
90
91
92
93
94
  						return false;
  					}
  					break;
  
  				case 'VORBIS_COMMENT': // 0x04
31b7f2792   Kload   Upgrade to ownclo...
95
96
  					if (!$this->parseVORBIS_COMMENT($BlockTypeText_raw['block_data'])) {
  						return false;
03e52840d   Kload   Init
97
  					}
03e52840d   Kload   Init
98
99
100
  					break;
  
  				case 'CUESHEET':       // 0x05
31b7f2792   Kload   Upgrade to ownclo...
101
  					if (!$this->parseCUESHEET($BlockTypeText_raw['block_data'])) {
03e52840d   Kload   Init
102
103
104
105
106
  						return false;
  					}
  					break;
  
  				case 'PICTURE':        // 0x06
31b7f2792   Kload   Upgrade to ownclo...
107
  					if (!$this->parsePICTURE()) {
03e52840d   Kload   Init
108
109
110
111
112
  						return false;
  					}
  					break;
  
  				default:
31b7f2792   Kload   Upgrade to ownclo...
113
  					$this->warning('Unhandled METADATA_BLOCK_HEADER.BLOCK_TYPE ('.$BlockType.') at offset '.$BlockOffset);
03e52840d   Kload   Init
114
  			}
31b7f2792   Kload   Upgrade to ownclo...
115
116
117
118
  			unset($info['flac'][$BlockTypeText]['raw']);
  			$info['avdataoffset'] = $this->ftell();
  		}
  		while ($LastBlockFlag === false);
03e52840d   Kload   Init
119

31b7f2792   Kload   Upgrade to ownclo...
120
121
122
123
124
125
126
127
128
129
130
131
132
  		// handle tags
  		if (!empty($info['flac']['VORBIS_COMMENT']['comments'])) {
  			$info['flac']['comments'] = $info['flac']['VORBIS_COMMENT']['comments'];
  		}
  		if (!empty($info['flac']['VORBIS_COMMENT']['vendor'])) {
  			$info['audio']['encoder'] = str_replace('reference ', '', $info['flac']['VORBIS_COMMENT']['vendor']);
  		}
  
  		// copy attachments to 'comments' array if nesesary
  		if (isset($info['flac']['PICTURE']) && ($this->getid3->option_save_attachments !== getID3::ATTACHMENTS_NONE)) {
  			foreach ($info['flac']['PICTURE'] as $entry) {
  				if (!empty($entry['data'])) {
  					$info['flac']['comments']['picture'][] = array('image_mime'=>$entry['image_mime'], 'data'=>$entry['data']);
03e52840d   Kload   Init
133
134
135
136
137
  				}
  			}
  		}
  
  		if (isset($info['flac']['STREAMINFO'])) {
31b7f2792   Kload   Upgrade to ownclo...
138
139
140
  			if (!$this->isDependencyFor('matroska')) {
  				$info['flac']['compressed_audio_bytes'] = $info['avdataend'] - $info['avdataoffset'];
  			}
03e52840d   Kload   Init
141
142
  			$info['flac']['uncompressed_audio_bytes'] = $info['flac']['STREAMINFO']['samples_stream'] * $info['flac']['STREAMINFO']['channels'] * ($info['flac']['STREAMINFO']['bits_per_sample'] / 8);
  			if ($info['flac']['uncompressed_audio_bytes'] == 0) {
31b7f2792   Kload   Upgrade to ownclo...
143
144
145
146
  				return $this->error('Corrupt FLAC file: uncompressed_audio_bytes == zero');
  			}
  			if (!empty($info['flac']['compressed_audio_bytes'])) {
  				$info['flac']['compression_ratio'] = $info['flac']['compressed_audio_bytes'] / $info['flac']['uncompressed_audio_bytes'];
03e52840d   Kload   Init
147
  			}
03e52840d   Kload   Init
148
149
150
151
152
153
  		}
  
  		// set md5_data_source - built into flac 0.5+
  		if (isset($info['flac']['STREAMINFO']['audio_signature'])) {
  
  			if ($info['flac']['STREAMINFO']['audio_signature'] === str_repeat("\x00", 16)) {
31b7f2792   Kload   Upgrade to ownclo...
154
155
156
                  $this->warning('FLAC STREAMINFO.audio_signature is null (known issue with libOggFLAC)');
  			}
  			else {
03e52840d   Kload   Init
157
158
159
  				$info['md5_data_source'] = '';
  				$md5 = $info['flac']['STREAMINFO']['audio_signature'];
  				for ($i = 0; $i < strlen($md5); $i++) {
31b7f2792   Kload   Upgrade to ownclo...
160
  					$info['md5_data_source'] .= str_pad(dechex(ord($md5[$i])), 2, '00', STR_PAD_LEFT);
03e52840d   Kload   Init
161
162
163
164
  				}
  				if (!preg_match('/^[0-9a-f]{32}$/', $info['md5_data_source'])) {
  					unset($info['md5_data_source']);
  				}
03e52840d   Kload   Init
165
  			}
03e52840d   Kload   Init
166
  		}
31b7f2792   Kload   Upgrade to ownclo...
167
168
169
170
171
172
173
174
  		if (isset($info['flac']['STREAMINFO']['bits_per_sample'])) {
  			$info['audio']['bits_per_sample'] = $info['flac']['STREAMINFO']['bits_per_sample'];
  			if ($info['audio']['bits_per_sample'] == 8) {
  				// special case
  				// must invert sign bit on all data bytes before MD5'ing to match FLAC's calculated value
  				// MD5sum calculates on unsigned bytes, but FLAC calculated MD5 on 8-bit audio data as signed
  				$this->warning('FLAC calculates MD5 data strangely on 8-bit audio, so the stored md5_data_source value will not match the decoded WAV file');
  			}
03e52840d   Kload   Init
175
176
177
178
  		}
  
  		return true;
  	}
31b7f2792   Kload   Upgrade to ownclo...
179
180
  	private function parseSTREAMINFO($BlockData) {
  		$info = &$this->getid3->info;
03e52840d   Kload   Init
181

31b7f2792   Kload   Upgrade to ownclo...
182
183
  		$info['flac']['STREAMINFO'] = array();
  		$streaminfo = &$info['flac']['STREAMINFO'];
03e52840d   Kload   Init
184

31b7f2792   Kload   Upgrade to ownclo...
185
186
187
188
  		$streaminfo['min_block_size']  = getid3_lib::BigEndian2Int(substr($BlockData, 0, 2));
  		$streaminfo['max_block_size']  = getid3_lib::BigEndian2Int(substr($BlockData, 2, 2));
  		$streaminfo['min_frame_size']  = getid3_lib::BigEndian2Int(substr($BlockData, 4, 3));
  		$streaminfo['max_frame_size']  = getid3_lib::BigEndian2Int(substr($BlockData, 7, 3));
03e52840d   Kload   Init
189

31b7f2792   Kload   Upgrade to ownclo...
190
191
192
193
194
  		$SRCSBSS                       = getid3_lib::BigEndian2Bin(substr($BlockData, 10, 8));
  		$streaminfo['sample_rate']     = getid3_lib::Bin2Dec(substr($SRCSBSS,  0, 20));
  		$streaminfo['channels']        = getid3_lib::Bin2Dec(substr($SRCSBSS, 20,  3)) + 1;
  		$streaminfo['bits_per_sample'] = getid3_lib::Bin2Dec(substr($SRCSBSS, 23,  5)) + 1;
  		$streaminfo['samples_stream']  = getid3_lib::Bin2Dec(substr($SRCSBSS, 28, 36));
03e52840d   Kload   Init
195

31b7f2792   Kload   Upgrade to ownclo...
196
  		$streaminfo['audio_signature'] = substr($BlockData, 18, 16);
03e52840d   Kload   Init
197

31b7f2792   Kload   Upgrade to ownclo...
198
  		if (!empty($streaminfo['sample_rate'])) {
03e52840d   Kload   Init
199

31b7f2792   Kload   Upgrade to ownclo...
200
201
202
203
204
  			$info['audio']['bitrate_mode']    = 'vbr';
  			$info['audio']['sample_rate']     = $streaminfo['sample_rate'];
  			$info['audio']['channels']        = $streaminfo['channels'];
  			$info['audio']['bits_per_sample'] = $streaminfo['bits_per_sample'];
  			$info['playtime_seconds']         = $streaminfo['samples_stream'] / $streaminfo['sample_rate'];
03e52840d   Kload   Init
205
  			if ($info['playtime_seconds'] > 0) {
31b7f2792   Kload   Upgrade to ownclo...
206
207
208
209
210
211
  				if (!$this->isDependencyFor('matroska')) {
  					$info['audio']['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
  				}
  				else {
  					$this->warning('Cannot determine audio bitrate because total stream size is unknown');
  				}
03e52840d   Kload   Init
212
213
214
  			}
  
  		} else {
31b7f2792   Kload   Upgrade to ownclo...
215
  			return $this->error('Corrupt METAdata block: STREAMINFO');
03e52840d   Kload   Init
216
  		}
31b7f2792   Kload   Upgrade to ownclo...
217

03e52840d   Kload   Init
218
219
  		return true;
  	}
31b7f2792   Kload   Upgrade to ownclo...
220
  	private function parseAPPLICATION($BlockData) {
03e52840d   Kload   Init
221
  		$info = &$this->getid3->info;
31b7f2792   Kload   Upgrade to ownclo...
222
223
224
  		$ApplicationID = getid3_lib::BigEndian2Int(substr($BlockData, 0, 4));
  		$info['flac']['APPLICATION'][$ApplicationID]['name'] = self::applicationIDLookup($ApplicationID);
  		$info['flac']['APPLICATION'][$ApplicationID]['data'] = substr($BlockData, 4);
03e52840d   Kload   Init
225

03e52840d   Kload   Init
226
227
  		return true;
  	}
31b7f2792   Kload   Upgrade to ownclo...
228
  	private function parseSEEKTABLE($BlockData) {
03e52840d   Kload   Init
229
230
231
  		$info = &$this->getid3->info;
  
  		$offset = 0;
31b7f2792   Kload   Upgrade to ownclo...
232
  		$BlockLength = strlen($BlockData);
03e52840d   Kload   Init
233
  		$placeholderpattern = str_repeat("\xFF", 8);
31b7f2792   Kload   Upgrade to ownclo...
234
235
  		while ($offset < $BlockLength) {
  			$SampleNumberString = substr($BlockData, $offset, 8);
03e52840d   Kload   Init
236
237
238
239
240
241
242
243
  			$offset += 8;
  			if ($SampleNumberString == $placeholderpattern) {
  
  				// placeholder point
  				getid3_lib::safe_inc($info['flac']['SEEKTABLE']['placeholders'], 1);
  				$offset += 10;
  
  			} else {
31b7f2792   Kload   Upgrade to ownclo...
244
245
  				$SampleNumber                                        = getid3_lib::BigEndian2Int($SampleNumberString);
  				$info['flac']['SEEKTABLE'][$SampleNumber]['offset']  = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 8));
03e52840d   Kload   Init
246
  				$offset += 8;
31b7f2792   Kload   Upgrade to ownclo...
247
  				$info['flac']['SEEKTABLE'][$SampleNumber]['samples'] = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 2));
03e52840d   Kload   Init
248
249
250
251
  				$offset += 2;
  
  			}
  		}
31b7f2792   Kload   Upgrade to ownclo...
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
  		return true;
  	}
  
  	private function parseVORBIS_COMMENT($BlockData) {
  		$info = &$this->getid3->info;
  
  		$getid3_ogg = new getid3_ogg($this->getid3);
  		if ($this->isDependencyFor('matroska')) {
  			$getid3_ogg->setStringMode($this->data_string);
  		}
  		$getid3_ogg->ParseVorbisComments();
  		if (isset($info['ogg'])) {
  			unset($info['ogg']['comments_raw']);
  			$info['flac']['VORBIS_COMMENT'] = $info['ogg'];
  			unset($info['ogg']);
  		}
  
  		unset($getid3_ogg);
03e52840d   Kload   Init
270
271
272
  
  		return true;
  	}
31b7f2792   Kload   Upgrade to ownclo...
273
  	private function parseCUESHEET($BlockData) {
03e52840d   Kload   Init
274
275
  		$info = &$this->getid3->info;
  		$offset = 0;
31b7f2792   Kload   Upgrade to ownclo...
276
  		$info['flac']['CUESHEET']['media_catalog_number'] =                              trim(substr($BlockData, $offset, 128), "\0");
03e52840d   Kload   Init
277
  		$offset += 128;
31b7f2792   Kload   Upgrade to ownclo...
278
  		$info['flac']['CUESHEET']['lead_in_samples']      =         getid3_lib::BigEndian2Int(substr($BlockData, $offset, 8));
03e52840d   Kload   Init
279
  		$offset += 8;
31b7f2792   Kload   Upgrade to ownclo...
280
  		$info['flac']['CUESHEET']['flags']['is_cd']       = (bool) (getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1)) & 0x80);
03e52840d   Kload   Init
281
282
283
  		$offset += 1;
  
  		$offset += 258; // reserved
31b7f2792   Kload   Upgrade to ownclo...
284
  		$info['flac']['CUESHEET']['number_tracks']        =         getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1));
03e52840d   Kload   Init
285
286
287
  		$offset += 1;
  
  		for ($track = 0; $track < $info['flac']['CUESHEET']['number_tracks']; $track++) {
31b7f2792   Kload   Upgrade to ownclo...
288
  			$TrackSampleOffset = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 8));
03e52840d   Kload   Init
289
  			$offset += 8;
31b7f2792   Kload   Upgrade to ownclo...
290
  			$TrackNumber       = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1));
03e52840d   Kload   Init
291
292
293
  			$offset += 1;
  
  			$info['flac']['CUESHEET']['tracks'][$TrackNumber]['sample_offset']         = $TrackSampleOffset;
31b7f2792   Kload   Upgrade to ownclo...
294
  			$info['flac']['CUESHEET']['tracks'][$TrackNumber]['isrc']                  =                           substr($BlockData, $offset, 12);
03e52840d   Kload   Init
295
  			$offset += 12;
31b7f2792   Kload   Upgrade to ownclo...
296
  			$TrackFlagsRaw                                                             = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1));
03e52840d   Kload   Init
297
298
299
300
301
  			$offset += 1;
  			$info['flac']['CUESHEET']['tracks'][$TrackNumber]['flags']['is_audio']     = (bool) ($TrackFlagsRaw & 0x80);
  			$info['flac']['CUESHEET']['tracks'][$TrackNumber]['flags']['pre_emphasis'] = (bool) ($TrackFlagsRaw & 0x40);
  
  			$offset += 13; // reserved
31b7f2792   Kload   Upgrade to ownclo...
302
  			$info['flac']['CUESHEET']['tracks'][$TrackNumber]['index_points']          = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1));
03e52840d   Kload   Init
303
304
305
  			$offset += 1;
  
  			for ($index = 0; $index < $info['flac']['CUESHEET']['tracks'][$TrackNumber]['index_points']; $index++) {
31b7f2792   Kload   Upgrade to ownclo...
306
  				$IndexSampleOffset = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 8));
03e52840d   Kload   Init
307
  				$offset += 8;
31b7f2792   Kload   Upgrade to ownclo...
308
  				$IndexNumber       = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1));
03e52840d   Kload   Init
309
310
311
312
313
314
315
  				$offset += 1;
  
  				$offset += 3; // reserved
  
  				$info['flac']['CUESHEET']['tracks'][$TrackNumber]['indexes'][$IndexNumber] = $IndexSampleOffset;
  			}
  		}
03e52840d   Kload   Init
316
317
  		return true;
  	}
31b7f2792   Kload   Upgrade to ownclo...
318
319
320
321
322
  	/**
  	* Parse METADATA_BLOCK_PICTURE flac structure and extract attachment
  	* External usage: audio.ogg
  	*/
  	public function parsePICTURE() {
03e52840d   Kload   Init
323
  		$info = &$this->getid3->info;
03e52840d   Kload   Init
324

31b7f2792   Kload   Upgrade to ownclo...
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
  		$picture['typeid']         = getid3_lib::BigEndian2Int($this->fread(4));
  		$picture['type']           = self::pictureTypeLookup($picture['typeid']);
  		$picture['image_mime']     = $this->fread(getid3_lib::BigEndian2Int($this->fread(4)));
  		$descr_length              = getid3_lib::BigEndian2Int($this->fread(4));
  		if ($descr_length) {
  			$picture['description'] = $this->fread($descr_length);
  		}
  		$picture['width']          = getid3_lib::BigEndian2Int($this->fread(4));
  		$picture['height']         = getid3_lib::BigEndian2Int($this->fread(4));
  		$picture['color_depth']    = getid3_lib::BigEndian2Int($this->fread(4));
  		$picture['colors_indexed'] = getid3_lib::BigEndian2Int($this->fread(4));
  		$data_length               = getid3_lib::BigEndian2Int($this->fread(4));
  
  		if ($picture['image_mime'] == '-->') {
  			$picture['data'] = $this->fread($data_length);
  		} else {
  			$picture['data'] = $this->saveAttachment(
  				str_replace('/', '_', $picture['type']).'_'.$this->ftell(),
  				$this->ftell(),
  				$data_length,
  				$picture['image_mime']);
  		}
03e52840d   Kload   Init
347

31b7f2792   Kload   Upgrade to ownclo...
348
  		$info['flac']['PICTURE'][] = $picture;
03e52840d   Kload   Init
349

31b7f2792   Kload   Upgrade to ownclo...
350
351
  		return true;
  	}
03e52840d   Kload   Init
352

31b7f2792   Kload   Upgrade to ownclo...
353
354
355
356
357
358
359
360
361
362
363
364
  	public static function metaBlockTypeLookup($blocktype) {
  		static $lookup = array(
  			0 => 'STREAMINFO',
  			1 => 'PADDING',
  			2 => 'APPLICATION',
  			3 => 'SEEKTABLE',
  			4 => 'VORBIS_COMMENT',
  			5 => 'CUESHEET',
  			6 => 'PICTURE',
  		);
  		return (isset($lookup[$blocktype]) ? $lookup[$blocktype] : 'reserved');
  	}
03e52840d   Kload   Init
365

31b7f2792   Kload   Upgrade to ownclo...
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
  	public static function applicationIDLookup($applicationid) {
  		// http://flac.sourceforge.net/id.html
  		static $lookup = array(
  			0x41544348 => 'FlacFile',                                                                           // "ATCH"
  			0x42534F4C => 'beSolo',                                                                             // "BSOL"
  			0x42554753 => 'Bugs Player',                                                                        // "BUGS"
  			0x43756573 => 'GoldWave cue points (specification)',                                                // "Cues"
  			0x46696361 => 'CUE Splitter',                                                                       // "Fica"
  			0x46746F6C => 'flac-tools',                                                                         // "Ftol"
  			0x4D4F5442 => 'MOTB MetaCzar',                                                                      // "MOTB"
  			0x4D505345 => 'MP3 Stream Editor',                                                                  // "MPSE"
  			0x4D754D4C => 'MusicML: Music Metadata Language',                                                   // "MuML"
  			0x52494646 => 'Sound Devices RIFF chunk storage',                                                   // "RIFF"
  			0x5346464C => 'Sound Font FLAC',                                                                    // "SFFL"
  			0x534F4E59 => 'Sony Creative Software',                                                             // "SONY"
  			0x5351455A => 'flacsqueeze',                                                                        // "SQEZ"
  			0x54745776 => 'TwistedWave',                                                                        // "TtWv"
  			0x55495453 => 'UITS Embedding tools',                                                               // "UITS"
  			0x61696666 => 'FLAC AIFF chunk storage',                                                            // "aiff"
  			0x696D6167 => 'flac-image application for storing arbitrary files in APPLICATION metadata blocks',  // "imag"
  			0x7065656D => 'Parseable Embedded Extensible Metadata (specification)',                             // "peem"
  			0x71667374 => 'QFLAC Studio',                                                                       // "qfst"
  			0x72696666 => 'FLAC RIFF chunk storage',                                                            // "riff"
  			0x74756E65 => 'TagTuner',                                                                           // "tune"
  			0x78626174 => 'XBAT',                                                                               // "xbat"
  			0x786D6364 => 'xmcd',                                                                               // "xmcd"
  		);
  		return (isset($lookup[$applicationid]) ? $lookup[$applicationid] : 'reserved');
  	}
03e52840d   Kload   Init
395

31b7f2792   Kload   Upgrade to ownclo...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
  	public static function pictureTypeLookup($type_id) {
  		static $lookup = array (
  			 0 => 'Other',
  			 1 => '32x32 pixels \'file icon\' (PNG only)',
  			 2 => 'Other file icon',
  			 3 => 'Cover (front)',
  			 4 => 'Cover (back)',
  			 5 => 'Leaflet page',
  			 6 => 'Media (e.g. label side of CD)',
  			 7 => 'Lead artist/lead performer/soloist',
  			 8 => 'Artist/performer',
  			 9 => 'Conductor',
  			10 => 'Band/Orchestra',
  			11 => 'Composer',
  			12 => 'Lyricist/text writer',
  			13 => 'Recording Location',
  			14 => 'During recording',
  			15 => 'During performance',
  			16 => 'Movie/video screen capture',
  			17 => 'A bright coloured fish',
  			18 => 'Illustration',
  			19 => 'Band/artist logotype',
  			20 => 'Publisher/Studio logotype',
  		);
  		return (isset($lookup[$type_id]) ? $lookup[$type_id] : 'reserved');
03e52840d   Kload   Init
421
  	}
03e52840d   Kload   Init
422

31b7f2792   Kload   Upgrade to ownclo...
423
  }