function ParseRIFFdata(&$RIFFdata, &$ThisFileInfo)
 {
     if ($RIFFdata) {
         $tempfile = tempnam('*', 'getID3');
         $fp_temp = fopen($tempfile, "wb");
         $RIFFdataLength = strlen($RIFFdata);
         $NewLengthString = getid3_lib::LittleEndian2String($RIFFdataLength, 4);
         for ($i = 0; $i < 4; $i++) {
             $RIFFdata[$i + 4] = $NewLengthString[$i];
         }
         fwrite($fp_temp, $RIFFdata);
         fclose($fp_temp);
         $fp_temp = fopen($tempfile, "rb");
         $dummy = array('filesize' => $RIFFdataLength, 'filenamepath' => $ThisFileInfo['filenamepath'], 'tags' => $ThisFileInfo['tags'], 'avdataoffset' => 0, 'avdataend' => $RIFFdataLength, 'warning' => $ThisFileInfo['warning'], 'error' => $ThisFileInfo['error'], 'comments' => $ThisFileInfo['comments'], 'audio' => isset($ThisFileInfo['audio']) ? $ThisFileInfo['audio'] : array(), 'video' => isset($ThisFileInfo['video']) ? $ThisFileInfo['video'] : array());
         $riff = new getid3_riff($fp_temp, $dummy);
         $ThisFileInfo['riff'] = $dummy['riff'];
         $ThisFileInfo['warning'] = $dummy['warning'];
         $ThisFileInfo['error'] = $dummy['error'];
         $ThisFileInfo['tags'] = $dummy['tags'];
         $ThisFileInfo['comments'] = $dummy['comments'];
         fclose($fp_temp);
         unlink($tempfile);
         return true;
     }
     return false;
 }
 public function Analyze()
 {
     $getid3 = $this->getid3;
     $getid3->include_module('audio-video.riff');
     fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET);
     $raw_data = fread($getid3->fp, getid3::FREAD_BUFFER_SIZE);
     $getid3->info['fileformat'] = 'la';
     $getid3->info['audio']['dataformat'] = 'la';
     $getid3->info['audio']['lossless'] = true;
     $getid3->info['la']['version_major'] = (int) $raw_data[2];
     $getid3->info['la']['version_minor'] = (int) $raw_data[3];
     $getid3->info['la']['version'] = (double) $getid3->info['la']['version_major'] + $getid3->info['la']['version_minor'] / 10;
     $getid3->info['la']['uncompressed_size'] = getid3_lib::LittleEndian2Int(substr($raw_data, 4, 4));
     $wave_chunk = substr($raw_data, 8, 4);
     if ($wave_chunk !== 'WAVE') {
         throw new getid3_exception('Expected "WAVE" (' . getid3_lib::PrintHexBytes('WAVE') . ') at offset 8, found "' . $wave_chunk . '" (' . getid3_lib::PrintHexBytes($wave_chunk) . ') instead.');
     }
     $offset = 12;
     $getid3->info['la']['fmt_size'] = 24;
     if ($getid3->info['la']['version'] >= 0.3) {
         $getid3->info['la']['fmt_size'] = getid3_lib::LittleEndian2Int(substr($raw_data, $offset, 4));
         $getid3->info['la']['header_size'] = 49 + $getid3->info['la']['fmt_size'] - 24;
         $offset += 4;
     } else {
         // version 0.2 didn't support additional data blocks
         $getid3->info['la']['header_size'] = 41;
     }
     $fmt_chunk = substr($raw_data, $offset, 4);
     if ($fmt_chunk !== 'fmt ') {
         throw new getid3_exception('Expected "fmt " (' . getid3_lib::PrintHexBytes('fmt ') . ') at offset ' . $offset . ', found "' . $fmt_chunk . '" (' . getid3_lib::PrintHexBytes($fmt_chunk) . ') instead.');
     }
     $offset += 4;
     $fmt_size = getid3_lib::LittleEndian2Int(substr($raw_data, $offset, 4));
     $offset += 4;
     $getid3->info['la']['raw']['format'] = getid3_lib::LittleEndian2Int(substr($raw_data, $offset, 2));
     $offset += 2;
     getid3_lib::ReadSequence('LittleEndian2Int', $getid3->info['la'], $raw_data, $offset, array('channels' => 2, 'sample_rate' => 4, 'bytes_per_second' => 4, 'bytes_per_sample' => 2, 'bits_per_sample' => 2, 'samples' => 4));
     $offset += 18;
     $getid3->info['la']['raw']['flags'] = getid3_lib::LittleEndian2Int($raw_data[$offset++]);
     $getid3->info['la']['flags']['seekable'] = (bool) ($getid3->info['la']['raw']['flags'] & 0x1);
     if ($getid3->info['la']['version'] >= 0.4) {
         $getid3->info['la']['flags']['high_compression'] = (bool) ($getid3->info['la']['raw']['flags'] & 0x2);
     }
     $getid3->info['la']['original_crc'] = getid3_lib::LittleEndian2Int(substr($raw_data, $offset, 4));
     $offset += 4;
     // mikeØbevin*de
     // Basically, the blocksize/seekevery are 61440/19 in La0.4 and 73728/16
     // in earlier versions. A seekpoint is added every blocksize * seekevery
     // samples, so 4 * int(totalSamples / (blockSize * seekEvery)) should
     // give the number of bytes used for the seekpoints. Of course, if seeking
     // is disabled, there are no seekpoints stored.
     if ($getid3->info['la']['version'] >= 0.4) {
         $getid3->info['la']['blocksize'] = 61440;
         $getid3->info['la']['seekevery'] = 19;
     } else {
         $getid3->info['la']['blocksize'] = 73728;
         $getid3->info['la']['seekevery'] = 16;
     }
     $getid3->info['la']['seekpoint_count'] = 0;
     if ($getid3->info['la']['flags']['seekable']) {
         $getid3->info['la']['seekpoint_count'] = floor($getid3->info['la']['samples'] / ($getid3->info['la']['blocksize'] * $getid3->info['la']['seekevery']));
         for ($i = 0; $i < $getid3->info['la']['seekpoint_count']; $i++) {
             $getid3->info['la']['seekpoints'][] = getid3_lib::LittleEndian2Int(substr($raw_data, $offset, 4));
             $offset += 4;
         }
     }
     if ($getid3->info['la']['version'] >= 0.3) {
         // Following the main header information, the program outputs all of the
         // seekpoints. Following these is what I called the 'footer start',
         // i.e. the position immediately after the La audio data is finished.
         $getid3->info['la']['footerstart'] = getid3_lib::LittleEndian2Int(substr($raw_data, $offset, 4));
         $offset += 4;
         if ($getid3->info['la']['footerstart'] > $getid3->info['filesize']) {
             $getid3->warning('FooterStart value points to offset ' . $getid3->info['la']['footerstart'] . ' which is beyond end-of-file (' . $getid3->info['filesize'] . ')');
             $getid3->info['la']['footerstart'] = $getid3->info['filesize'];
         }
     } else {
         // La v0.2 didn't have FooterStart value
         $getid3->info['la']['footerstart'] = $getid3->info['avdataend'];
     }
     if ($getid3->info['la']['footerstart'] < $getid3->info['avdataend']) {
         // Create riff header
         $riff_data = 'WAVE';
         if ($getid3->info['la']['version'] == 0.2) {
             $riff_data .= substr($raw_data, 12, 24);
         } else {
             $riff_data .= substr($raw_data, 16, 24);
         }
         if ($getid3->info['la']['footerstart'] < $getid3->info['avdataend']) {
             fseek($getid3->fp, $getid3->info['la']['footerstart'], SEEK_SET);
             $riff_data .= fread($getid3->fp, $getid3->info['avdataend'] - $getid3->info['la']['footerstart']);
         }
         $riff_data = 'RIFF' . getid3_lib::LittleEndian2String(strlen($riff_data), 4, false) . $riff_data;
         // Clone getid3 - messing with offsets - better safe than sorry
         $clone = clone $getid3;
         // Analyze clone by string
         $riff = new getid3_riff($clone);
         $riff->AnalyzeString($riff_data);
         // Import from clone and destroy
         $getid3->info['riff'] = $clone->info['riff'];
         $getid3->warnings($clone->warnings());
         unset($clone);
     }
     // $getid3->info['avdataoffset'] should be zero to begin with, but just in case it's not, include the addition anyway
     $getid3->info['avdataend'] = $getid3->info['avdataoffset'] + $getid3->info['la']['footerstart'];
     $getid3->info['avdataoffset'] = $getid3->info['avdataoffset'] + $offset;
     $getid3->info['la']['compression_ratio'] = (double) (($getid3->info['avdataend'] - $getid3->info['avdataoffset']) / $getid3->info['la']['uncompressed_size']);
     $getid3->info['playtime_seconds'] = (double) ($getid3->info['la']['samples'] / $getid3->info['la']['sample_rate']) / $getid3->info['la']['channels'];
     $getid3->info['audio']['bitrate'] = ($getid3->info['avdataend'] - $getid3->info['avdataoffset']) * 8 / $getid3->info['playtime_seconds'];
     $getid3->info['audio']['bits_per_sample'] = $getid3->info['la']['bits_per_sample'];
     $getid3->info['audio']['channels'] = $getid3->info['la']['channels'];
     $getid3->info['audio']['sample_rate'] = (int) $getid3->info['la']['sample_rate'];
     $getid3->info['audio']['encoder'] = 'LA v' . $getid3->info['la']['version'];
     return true;
 }
 static function iconv_fallback_utf8_utf16le($string, $bom = false)
 {
     $newcharstring = '';
     if ($bom) {
         $newcharstring .= "ÿþ";
     }
     $offset = 0;
     $stringlength = strlen($string);
     while ($offset < $stringlength) {
         if ((ord($string[$offset]) | 0x7) == 0xf7) {
             // 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
             $charval = (ord($string[$offset + 0]) & 0x7) << 18 & (ord($string[$offset + 1]) & 0x3f) << 12 & (ord($string[$offset + 2]) & 0x3f) << 6 & (ord($string[$offset + 3]) & 0x3f);
             $offset += 4;
         } elseif ((ord($string[$offset]) | 0xf) == 0xef) {
             // 1110bbbb 10bbbbbb 10bbbbbb
             $charval = (ord($string[$offset + 0]) & 0xf) << 12 & (ord($string[$offset + 1]) & 0x3f) << 6 & (ord($string[$offset + 2]) & 0x3f);
             $offset += 3;
         } elseif ((ord($string[$offset]) | 0x1f) == 0xdf) {
             // 110bbbbb 10bbbbbb
             $charval = (ord($string[$offset + 0]) & 0x1f) << 6 & (ord($string[$offset + 1]) & 0x3f);
             $offset += 2;
         } elseif ((ord($string[$offset]) | 0x7f) == 0x7f) {
             // 0bbbbbbb
             $charval = ord($string[$offset]);
             $offset += 1;
         } else {
             // error? maybe throw some warning here?
             $charval = false;
             $offset += 1;
         }
         if ($charval !== false) {
             $newcharstring .= $charval < 65536 ? getid3_lib::LittleEndian2String($charval, 2) : '?' . "";
         }
     }
     return $newcharstring;
 }
 function GenerateAPEtagHeaderFooter(&$items, $isheader = false)
 {
     $tagdatalength = 0;
     foreach ($items as $itemdata) {
         $tagdatalength += strlen($itemdata);
     }
     $APEheader = 'APETAGEX';
     $APEheader .= getid3_lib::LittleEndian2String(2000, 4);
     $APEheader .= getid3_lib::LittleEndian2String(32 + $tagdatalength, 4);
     $APEheader .= getid3_lib::LittleEndian2String(count($items), 4);
     $APEheader .= $this->GenerateAPEtagFlags(true, true, $isheader, 0, false);
     $APEheader .= str_repeat("", 8);
     return $APEheader;
 }
 public function ParseRIFFdata(&$RIFFdata)
 {
     $info =& $this->getid3->info;
     if ($RIFFdata) {
         $tempfile = tempnam(GETID3_TEMP_DIR, 'getID3');
         $fp_temp = fopen($tempfile, 'wb');
         $RIFFdataLength = strlen($RIFFdata);
         $NewLengthString = getid3_lib::LittleEndian2String($RIFFdataLength, 4);
         for ($i = 0; $i < 4; $i++) {
             $RIFFdata[$i + 4] = $NewLengthString[$i];
         }
         fwrite($fp_temp, $RIFFdata);
         fclose($fp_temp);
         $getid3_temp = new getID3();
         $getid3_temp->openfile($tempfile);
         $getid3_temp->info['filesize'] = $RIFFdataLength;
         $getid3_temp->info['filenamepath'] = $info['filenamepath'];
         $getid3_temp->info['tags'] = $info['tags'];
         $getid3_temp->info['warning'] = $info['warning'];
         $getid3_temp->info['error'] = $info['error'];
         $getid3_temp->info['comments'] = $info['comments'];
         $getid3_temp->info['audio'] = isset($info['audio']) ? $info['audio'] : array();
         $getid3_temp->info['video'] = isset($info['video']) ? $info['video'] : array();
         $getid3_riff = new getid3_riff($getid3_temp);
         $getid3_riff->Analyze();
         $info['riff'] = $getid3_temp->info['riff'];
         $info['warning'] = $getid3_temp->info['warning'];
         $info['error'] = $getid3_temp->info['error'];
         $info['tags'] = $getid3_temp->info['tags'];
         $info['comments'] = $getid3_temp->info['comments'];
         unset($getid3_riff, $getid3_temp);
         unlink($tempfile);
     }
     return false;
 }
Beispiel #6
0
 protected function generate_header_footer(&$items, $is_header = false)
 {
     $comments_length = 0;
     foreach ($items as $item_data) {
         $comments_length += strlen($item_data);
     }
     $header = 'APETAGEX';
     $header .= getid3_lib::LittleEndian2String(2000, 4);
     $header .= getid3_lib::LittleEndian2String(32 + $comments_length, 4);
     $header .= getid3_lib::LittleEndian2String(count($items), 4);
     $header .= $this->generate_flags(true, true, $is_header, 0, false);
     $header .= str_repeat("", 8);
     return $header;
 }
Beispiel #7
0
 function getid3_la(&$fd, &$ThisFileInfo)
 {
     $offset = 0;
     fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
     $rawdata = fread($fd, GETID3_FREAD_BUFFER_SIZE);
     switch (substr($rawdata, $offset, 4)) {
         case 'LA02':
         case 'LA03':
         case 'LA04':
             $ThisFileInfo['fileformat'] = 'la';
             $ThisFileInfo['audio']['dataformat'] = 'la';
             $ThisFileInfo['audio']['lossless'] = true;
             $ThisFileInfo['la']['version_major'] = (int) substr($rawdata, $offset + 2, 1);
             $ThisFileInfo['la']['version_minor'] = (int) substr($rawdata, $offset + 3, 1);
             $ThisFileInfo['la']['version'] = (double) $ThisFileInfo['la']['version_major'] + $ThisFileInfo['la']['version_minor'] / 10;
             $offset += 4;
             $ThisFileInfo['la']['uncompressed_size'] = getid3_lib::LittleEndian2Int(substr($rawdata, $offset, 4));
             $offset += 4;
             if ($ThisFileInfo['la']['uncompressed_size'] == 0) {
                 $ThisFileInfo['error'][] = 'Corrupt LA file: uncompressed_size == zero';
                 return false;
             }
             $WAVEchunk = substr($rawdata, $offset, 4);
             if ($WAVEchunk !== 'WAVE') {
                 $ThisFileInfo['error'][] = 'Expected "WAVE" (' . getid3_lib::PrintHexBytes('WAVE') . ') at offset ' . $offset . ', found "' . $WAVEchunk . '" (' . getid3_lib::PrintHexBytes($WAVEchunk) . ') instead.';
                 return false;
             }
             $offset += 4;
             $ThisFileInfo['la']['fmt_size'] = 24;
             if ($ThisFileInfo['la']['version'] >= 0.3) {
                 $ThisFileInfo['la']['fmt_size'] = getid3_lib::LittleEndian2Int(substr($rawdata, $offset, 4));
                 $ThisFileInfo['la']['header_size'] = 49 + $ThisFileInfo['la']['fmt_size'] - 24;
                 $offset += 4;
             } else {
                 // version 0.2 didn't support additional data blocks
                 $ThisFileInfo['la']['header_size'] = 41;
             }
             $fmt_chunk = substr($rawdata, $offset, 4);
             if ($fmt_chunk !== 'fmt ') {
                 $ThisFileInfo['error'][] = 'Expected "fmt " (' . getid3_lib::PrintHexBytes('fmt ') . ') at offset ' . $offset . ', found "' . $fmt_chunk . '" (' . getid3_lib::PrintHexBytes($fmt_chunk) . ') instead.';
                 return false;
             }
             $offset += 4;
             $fmt_size = getid3_lib::LittleEndian2Int(substr($rawdata, $offset, 4));
             $offset += 4;
             $ThisFileInfo['la']['raw']['format'] = getid3_lib::LittleEndian2Int(substr($rawdata, $offset, 2));
             $offset += 2;
             $ThisFileInfo['la']['channels'] = getid3_lib::LittleEndian2Int(substr($rawdata, $offset, 2));
             $offset += 2;
             if ($ThisFileInfo['la']['channels'] == 0) {
                 $ThisFileInfo['error'][] = 'Corrupt LA file: channels == zero';
                 return false;
             }
             $ThisFileInfo['la']['sample_rate'] = getid3_lib::LittleEndian2Int(substr($rawdata, $offset, 4));
             $offset += 4;
             if ($ThisFileInfo['la']['sample_rate'] == 0) {
                 $ThisFileInfo['error'][] = 'Corrupt LA file: sample_rate == zero';
                 return false;
             }
             $ThisFileInfo['la']['bytes_per_second'] = getid3_lib::LittleEndian2Int(substr($rawdata, $offset, 4));
             $offset += 4;
             $ThisFileInfo['la']['bytes_per_sample'] = getid3_lib::LittleEndian2Int(substr($rawdata, $offset, 2));
             $offset += 2;
             $ThisFileInfo['la']['bits_per_sample'] = getid3_lib::LittleEndian2Int(substr($rawdata, $offset, 2));
             $offset += 2;
             $ThisFileInfo['la']['samples'] = getid3_lib::LittleEndian2Int(substr($rawdata, $offset, 4));
             $offset += 4;
             $ThisFileInfo['la']['raw']['flags'] = getid3_lib::LittleEndian2Int(substr($rawdata, $offset, 1));
             $offset += 1;
             $ThisFileInfo['la']['flags']['seekable'] = (bool) ($ThisFileInfo['la']['raw']['flags'] & 0x1);
             if ($ThisFileInfo['la']['version'] >= 0.4) {
                 $ThisFileInfo['la']['flags']['high_compression'] = (bool) ($ThisFileInfo['la']['raw']['flags'] & 0x2);
             }
             $ThisFileInfo['la']['original_crc'] = getid3_lib::LittleEndian2Int(substr($rawdata, $offset, 4));
             $offset += 4;
             // mikeØbevin*de
             // Basically, the blocksize/seekevery are 61440/19 in La0.4 and 73728/16
             // in earlier versions. A seekpoint is added every blocksize * seekevery
             // samples, so 4 * int(totalSamples / (blockSize * seekEvery)) should
             // give the number of bytes used for the seekpoints. Of course, if seeking
             // is disabled, there are no seekpoints stored.
             if ($ThisFileInfo['la']['version'] >= 0.4) {
                 $ThisFileInfo['la']['blocksize'] = 61440;
                 $ThisFileInfo['la']['seekevery'] = 19;
             } else {
                 $ThisFileInfo['la']['blocksize'] = 73728;
                 $ThisFileInfo['la']['seekevery'] = 16;
             }
             $ThisFileInfo['la']['seekpoint_count'] = 0;
             if ($ThisFileInfo['la']['flags']['seekable']) {
                 $ThisFileInfo['la']['seekpoint_count'] = floor($ThisFileInfo['la']['samples'] / ($ThisFileInfo['la']['blocksize'] * $ThisFileInfo['la']['seekevery']));
                 for ($i = 0; $i < $ThisFileInfo['la']['seekpoint_count']; $i++) {
                     $ThisFileInfo['la']['seekpoints'][] = getid3_lib::LittleEndian2Int(substr($rawdata, $offset, 4));
                     $offset += 4;
                 }
             }
             if ($ThisFileInfo['la']['version'] >= 0.3) {
                 // Following the main header information, the program outputs all of the
                 // seekpoints. Following these is what I called the 'footer start',
                 // i.e. the position immediately after the La audio data is finished.
                 $ThisFileInfo['la']['footerstart'] = getid3_lib::LittleEndian2Int(substr($rawdata, $offset, 4));
                 $offset += 4;
                 if ($ThisFileInfo['la']['footerstart'] > $ThisFileInfo['filesize']) {
                     $ThisFileInfo['warning'][] = 'FooterStart value points to offset ' . $ThisFileInfo['la']['footerstart'] . ' which is beyond end-of-file (' . $ThisFileInfo['filesize'] . ')';
                     $ThisFileInfo['la']['footerstart'] = $ThisFileInfo['filesize'];
                 }
             } else {
                 // La v0.2 didn't have FooterStart value
                 $ThisFileInfo['la']['footerstart'] = $ThisFileInfo['avdataend'];
             }
             if ($ThisFileInfo['la']['footerstart'] < $ThisFileInfo['avdataend']) {
                 if ($RIFFtempfilename = tempnam('*', 'id3')) {
                     if ($RIFF_fp = fopen($RIFFtempfilename, 'w+b')) {
                         $RIFFdata = 'WAVE';
                         if ($ThisFileInfo['la']['version'] == 0.2) {
                             $RIFFdata .= substr($rawdata, 12, 24);
                         } else {
                             $RIFFdata .= substr($rawdata, 16, 24);
                         }
                         if ($ThisFileInfo['la']['footerstart'] < $ThisFileInfo['avdataend']) {
                             fseek($fd, $ThisFileInfo['la']['footerstart'], SEEK_SET);
                             $RIFFdata .= fread($fd, $ThisFileInfo['avdataend'] - $ThisFileInfo['la']['footerstart']);
                         }
                         $RIFFdata = 'RIFF' . getid3_lib::LittleEndian2String(strlen($RIFFdata), 4, false) . $RIFFdata;
                         fwrite($RIFF_fp, $RIFFdata, strlen($RIFFdata));
                         $dummy = $ThisFileInfo;
                         $dummy['filesize'] = strlen($RIFFdata);
                         $dummy['avdataoffset'] = 0;
                         $dummy['avdataend'] = $dummy['filesize'];
                         $riff = new getid3_riff($RIFF_fp, $dummy);
                         if (empty($dummy['error'])) {
                             $ThisFileInfo['riff'] = $dummy['riff'];
                         } else {
                             $ThisFileInfo['warning'][] = 'Error parsing RIFF portion of La file: ' . implode($dummy['error']);
                         }
                         unset($riff);
                         unset($dummy);
                         fclose($RIFF_fp);
                     }
                     unlink($RIFFtempfilename);
                 }
             }
             // $ThisFileInfo['avdataoffset'] should be zero to begin with, but just in case it's not, include the addition anyway
             $ThisFileInfo['avdataend'] = $ThisFileInfo['avdataoffset'] + $ThisFileInfo['la']['footerstart'];
             $ThisFileInfo['avdataoffset'] = $ThisFileInfo['avdataoffset'] + $offset;
             //$ThisFileInfo['la']['codec']                = RIFFwFormatTagLookup($ThisFileInfo['la']['raw']['format']);
             $ThisFileInfo['la']['compression_ratio'] = (double) (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) / $ThisFileInfo['la']['uncompressed_size']);
             $ThisFileInfo['playtime_seconds'] = (double) ($ThisFileInfo['la']['samples'] / $ThisFileInfo['la']['sample_rate']) / $ThisFileInfo['la']['channels'];
             if ($ThisFileInfo['playtime_seconds'] == 0) {
                 $ThisFileInfo['error'][] = 'Corrupt LA file: playtime_seconds == zero';
                 return false;
             }
             $ThisFileInfo['audio']['bitrate'] = ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8 / $ThisFileInfo['playtime_seconds'];
             //$ThisFileInfo['audio']['codec']              = $ThisFileInfo['la']['codec'];
             $ThisFileInfo['audio']['bits_per_sample'] = $ThisFileInfo['la']['bits_per_sample'];
             break;
         default:
             if (substr($rawdata, $offset, 2) == 'LA') {
                 $ThisFileInfo['error'][] = 'This version of getID3() (v' . GETID3_VERSION . ') doesn\'t support LA version ' . substr($rawdata, $offset + 2, 1) . '.' . substr($rawdata, $offset + 3, 1) . ' which this appears to be - check http://getid3.sourceforge.net for updates.';
             } else {
                 $ThisFileInfo['error'][] = 'Not a LA (Lossless-Audio) file';
             }
             return false;
             break;
     }
     $ThisFileInfo['audio']['channels'] = $ThisFileInfo['la']['channels'];
     $ThisFileInfo['audio']['sample_rate'] = (int) $ThisFileInfo['la']['sample_rate'];
     $ThisFileInfo['audio']['encoder'] = 'LA v' . $ThisFileInfo['la']['version'];
     return true;
 }
	function iconv_fallback_utf8_utf16le($string, $bom=false) {
		$newcharstring = '';
		if ($bom) {
			$newcharstring .= "\xFF\xFE";
		}
		$offset = 0;
		$stringlength = strlen($string);
		while ($offset < $stringlength) {
			if ((ord($string{$offset}) | 0x07) == 0xF7) {
				// 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x07) << 18) &
				           ((ord($string{($offset + 1)}) & 0x3F) << 12) &
				           ((ord($string{($offset + 2)}) & 0x3F) <<  6) &
				            (ord($string{($offset + 3)}) & 0x3F);
				$offset += 4;
			} elseif ((ord($string{$offset}) | 0x0F) == 0xEF) {
				// 1110bbbb 10bbbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) &
				           ((ord($string{($offset + 1)}) & 0x3F) <<  6) &
				            (ord($string{($offset + 2)}) & 0x3F);
				$offset += 3;
			} elseif ((ord($string{$offset}) | 0x1F) == 0xDF) {
				// 110bbbbb 10bbbbbb
				$charval = ((ord($string{($offset + 0)}) & 0x1F) <<  6) &
				            (ord($string{($offset + 1)}) & 0x3F);
				$offset += 2;
			} elseif ((ord($string{$offset}) | 0x7F) == 0x7F) {
				// 0bbbbbbb
				$charval = ord($string{$offset});
				$offset += 1;
			} else {
				// error? maybe throw some warning here?
				$charval = false;
				$offset += 1;
			}
			if ($charval !== false) {
				$newcharstring .= (($charval < 65536) ? getid3_lib::LittleEndian2String($charval, 2) : '?'."\x00");
			}
		}
		return $newcharstring;
	}
 public function AnalyzeString(&$string)
 {
     // Rewrite header_size in header
     $new_header_size = getid3_lib::LittleEndian2String(strlen($string), 4);
     for ($i = 0; $i < 4; $i++) {
         $string[$i + 4] = $new_header_size[$i];
     }
     return parent::AnalyzeString($string);
 }
 function ParseRIFFdata(&$RIFFdata, &$ThisFileInfo)
 {
     if ($RIFFdata) {
         if ($fp_temp = tmpfile()) {
             $RIFFdataLength = strlen($RIFFdata);
             $NewLengthString = getid3_lib::LittleEndian2String($RIFFdataLength, 4);
             for ($i = 0; $i < 4; $i++) {
                 $RIFFdata[$i + 4] = $NewLengthString[$i];
             }
             fwrite($fp_temp, $RIFFdata);
             $dummy = array('filesize' => $RIFFdataLength, 'filenamepath' => $ThisFileInfo['filenamepath'], 'tags' => $ThisFileInfo['tags'], 'avdataoffset' => 0, 'avdataend' => $RIFFdataLength, 'warning' => $ThisFileInfo['warning'], 'error' => $ThisFileInfo['error'], 'comments' => $ThisFileInfo['comments'], 'audio' => isset($ThisFileInfo['audio']) ? $ThisFileInfo['audio'] : array(), 'video' => isset($ThisFileInfo['video']) ? $ThisFileInfo['video'] : array());
             $riff = new getid3_riff($fp_temp, $dummy);
             $ThisFileInfo['riff'] = $dummy['riff'];
             $ThisFileInfo['warning'] = $dummy['warning'];
             $ThisFileInfo['error'] = $dummy['error'];
             $ThisFileInfo['tags'] = $dummy['tags'];
             $ThisFileInfo['comments'] = $dummy['comments'];
             fclose($fp_temp);
             return true;
         } else {
             $ThisFileInfo['error'][] = 'Error calling tmpfile() to parse OptimFROG RIFF header';
         }
     }
     return false;
 }