[ Index ]

WordPress Cross Reference

title

Body

[close]

/wp-includes/ID3/ -> module.audio-video.riff.php (source)

   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.audio-video.riff.php                                 //
  11  // module for analyzing RIFF files                             //
  12  // multiple formats supported by this module:                  //
  13  //    Wave, AVI, AIFF/AIFC, (MP3,AC3)/RIFF, Wavpack v3, 8SVX   //
  14  // dependencies: module.audio.mp3.php                          //
  15  //               module.audio.ac3.php                          //
  16  //               module.audio.dts.php                          //
  17  //                                                            ///
  18  /////////////////////////////////////////////////////////////////
  19  
  20  /**
  21  * @todo Parse AC-3/DTS audio inside WAVE correctly
  22  * @todo Rewrite RIFF parser totally
  23  */
  24  
  25  getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true);
  26  getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, true);
  27  getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.dts.php', __FILE__, true);
  28  
  29  class getid3_riff extends getid3_handler
  30  {
  31  
  32  	public function Analyze() {
  33          $info = &$this->getid3->info;
  34  
  35          // initialize these values to an empty array, otherwise they default to NULL
  36          // and you can't append array values to a NULL value
  37          $info['riff'] = array('raw'=>array());
  38  
  39          // Shortcuts
  40          $thisfile_riff             = &$info['riff'];
  41          $thisfile_riff_raw         = &$thisfile_riff['raw'];
  42          $thisfile_audio            = &$info['audio'];
  43          $thisfile_video            = &$info['video'];
  44          $thisfile_audio_dataformat = &$thisfile_audio['dataformat'];
  45          $thisfile_riff_audio       = &$thisfile_riff['audio'];
  46          $thisfile_riff_video       = &$thisfile_riff['video'];
  47  
  48          $Original['avdataoffset'] = $info['avdataoffset'];
  49          $Original['avdataend']    = $info['avdataend'];
  50  
  51          $this->fseek($info['avdataoffset']);
  52          $RIFFheader = $this->fread(12);
  53          $offset = $this->ftell();
  54          $RIFFtype    = substr($RIFFheader, 0, 4);
  55          $RIFFsize    = substr($RIFFheader, 4, 4);
  56          $RIFFsubtype = substr($RIFFheader, 8, 4);
  57  
  58          switch ($RIFFtype) {
  59  
  60              case 'FORM':  // AIFF, AIFC
  61                  $info['fileformat']   = 'aiff';
  62                  $thisfile_riff['header_size'] = $this->EitherEndian2Int($RIFFsize);
  63                  $thisfile_riff[$RIFFsubtype]  = $this->ParseRIFF($offset, ($offset + $thisfile_riff['header_size'] - 4));
  64                  break;
  65  
  66              case 'RIFF':  // AVI, WAV, etc
  67              case 'SDSS':  // SDSS is identical to RIFF, just renamed. Used by SmartSound QuickTracks (www.smartsound.com)
  68              case 'RMP3':  // RMP3 is identical to RIFF, just renamed. Used by [unknown program] when creating RIFF-MP3s
  69                  $info['fileformat']   = 'riff';
  70                  $thisfile_riff['header_size'] = $this->EitherEndian2Int($RIFFsize);
  71                  if ($RIFFsubtype == 'RMP3') {
  72                      // RMP3 is identical to WAVE, just renamed. Used by [unknown program] when creating RIFF-MP3s
  73                      $RIFFsubtype = 'WAVE';
  74                  }
  75                  $thisfile_riff[$RIFFsubtype]  = $this->ParseRIFF($offset, ($offset + $thisfile_riff['header_size'] - 4));
  76                  if (($info['avdataend'] - $info['filesize']) == 1) {
  77                      // LiteWave appears to incorrectly *not* pad actual output file
  78                      // to nearest WORD boundary so may appear to be short by one
  79                      // byte, in which case - skip warning
  80                      $info['avdataend'] = $info['filesize'];
  81                  }
  82  
  83                  $nextRIFFoffset = $Original['avdataoffset'] + 8 + $thisfile_riff['header_size']; // 8 = "RIFF" + 32-bit offset
  84                  while ($nextRIFFoffset < min($info['filesize'], $info['avdataend'])) {
  85                      try {
  86                          $this->fseek($nextRIFFoffset);
  87                      } catch (getid3_exception $e) {
  88                          if ($e->getCode() == 10) {
  89                              //$this->warning('RIFF parser: '.$e->getMessage());
  90                              $this->error('AVI extends beyond '.round(PHP_INT_MAX / 1073741824).'GB and PHP filesystem functions cannot read that far, playtime may be wrong');
  91                              $this->warning('[avdataend] value may be incorrect, multiple AVIX chunks may be present');
  92                              break;
  93                          } else {
  94                              throw $e;
  95                          }
  96                      }
  97                      $nextRIFFheader = $this->fread(12);
  98                      if ($nextRIFFoffset == ($info['avdataend'] - 1)) {
  99                          if (substr($nextRIFFheader, 0, 1) == "\x00") {
 100                              // RIFF padded to WORD boundary, we're actually already at the end
 101                              break;
 102                          }
 103                      }
 104                      $nextRIFFheaderID =                         substr($nextRIFFheader, 0, 4);
 105                      $nextRIFFsize     = $this->EitherEndian2Int(substr($nextRIFFheader, 4, 4));
 106                      $nextRIFFtype     =                         substr($nextRIFFheader, 8, 4);
 107                      $chunkdata = array();
 108                      $chunkdata['offset'] = $nextRIFFoffset + 8;
 109                      $chunkdata['size']   = $nextRIFFsize;
 110                      $nextRIFFoffset = $chunkdata['offset'] + $chunkdata['size'];
 111  
 112                      switch ($nextRIFFheaderID) {
 113  
 114                          case 'RIFF':
 115                              $chunkdata['chunks'] = $this->ParseRIFF($chunkdata['offset'] + 4, $nextRIFFoffset);
 116  
 117                              if (!isset($thisfile_riff[$nextRIFFtype])) {
 118                                  $thisfile_riff[$nextRIFFtype] = array();
 119                              }
 120                              $thisfile_riff[$nextRIFFtype][] = $chunkdata;
 121                              break;
 122  
 123                          case 'JUNK':
 124                              // ignore
 125                              $thisfile_riff[$nextRIFFheaderID][] = $chunkdata;
 126                              break;
 127  
 128                          case 'IDVX':
 129                              $info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunkdata['size']));
 130                              break;
 131  
 132                          default:
 133                              if ($info['filesize'] == ($chunkdata['offset'] - 8 + 128)) {
 134                                  $DIVXTAG = $nextRIFFheader.$this->fread(128 - 12);
 135                                  if (substr($DIVXTAG, -7) == 'DIVXTAG') {
 136                                      // DIVXTAG is supposed to be inside an IDVX chunk in a LIST chunk, but some bad encoders just slap it on the end of a file
 137                                      $this->warning('Found wrongly-structured DIVXTAG at offset '.($this->ftell() - 128).', parsing anyway');
 138                                      $info['divxtag']['comments'] = self::ParseDIVXTAG($DIVXTAG);
 139                                      break 2;
 140                                  }
 141                              }
 142                              $this->warning('Expecting "RIFF|JUNK|IDVX" at '.$nextRIFFoffset.', found "'.$nextRIFFheaderID.'" ('.getid3_lib::PrintHexBytes($nextRIFFheaderID).') - skipping rest of file');
 143                              break 2;
 144  
 145                      }
 146  
 147                  }
 148                  if ($RIFFsubtype == 'WAVE') {
 149                      $thisfile_riff_WAVE = &$thisfile_riff['WAVE'];
 150                  }
 151                  break;
 152  
 153              default:
 154                  $this->error('Cannot parse RIFF (this is maybe not a RIFF / WAV / AVI file?) - expecting "FORM|RIFF|SDSS|RMP3" found "'.$RIFFsubtype.'" instead');
 155                  unset($info['fileformat']);
 156                  return false;
 157          }
 158  
 159          $streamindex = 0;
 160          switch ($RIFFsubtype) {
 161              case 'WAVE':
 162                  if (empty($thisfile_audio['bitrate_mode'])) {
 163                      $thisfile_audio['bitrate_mode'] = 'cbr';
 164                  }
 165                  if (empty($thisfile_audio_dataformat)) {
 166                      $thisfile_audio_dataformat = 'wav';
 167                  }
 168  
 169                  if (isset($thisfile_riff_WAVE['data'][0]['offset'])) {
 170                      $info['avdataoffset'] = $thisfile_riff_WAVE['data'][0]['offset'] + 8;
 171                      $info['avdataend']    = $info['avdataoffset'] + $thisfile_riff_WAVE['data'][0]['size'];
 172                  }
 173                  if (isset($thisfile_riff_WAVE['fmt '][0]['data'])) {
 174  
 175                      $thisfile_riff_audio[$streamindex] = self::parseWAVEFORMATex($thisfile_riff_WAVE['fmt '][0]['data']);
 176                      $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
 177                      if (!isset($thisfile_riff_audio[$streamindex]['bitrate']) || ($thisfile_riff_audio[$streamindex]['bitrate'] == 0)) {
 178                          $info['error'][] = 'Corrupt RIFF file: bitrate_audio == zero';
 179                          return false;
 180                      }
 181                      $thisfile_riff_raw['fmt '] = $thisfile_riff_audio[$streamindex]['raw'];
 182                      unset($thisfile_riff_audio[$streamindex]['raw']);
 183                      $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
 184  
 185                      $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
 186                      if (substr($thisfile_audio['codec'], 0, strlen('unknown: 0x')) == 'unknown: 0x') {
 187                          $info['warning'][] = 'Audio codec = '.$thisfile_audio['codec'];
 188                      }
 189                      $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
 190  
 191                      if (empty($info['playtime_seconds'])) { // may already be set (e.g. DTS-WAV)
 192                          $info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']);
 193                      }
 194  
 195                      $thisfile_audio['lossless'] = false;
 196                      if (isset($thisfile_riff_WAVE['data'][0]['offset']) && isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
 197                          switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
 198  
 199                              case 0x0001:  // PCM
 200                                  $thisfile_audio['lossless'] = true;
 201                                  break;
 202  
 203                              case 0x2000:  // AC-3
 204                                  $thisfile_audio_dataformat = 'ac3';
 205                                  break;
 206  
 207                              default:
 208                                  // do nothing
 209                                  break;
 210  
 211                          }
 212                      }
 213                      $thisfile_audio['streams'][$streamindex]['wformattag']   = $thisfile_audio['wformattag'];
 214                      $thisfile_audio['streams'][$streamindex]['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
 215                      $thisfile_audio['streams'][$streamindex]['lossless']     = $thisfile_audio['lossless'];
 216                      $thisfile_audio['streams'][$streamindex]['dataformat']   = $thisfile_audio_dataformat;
 217                  }
 218  
 219                  if (isset($thisfile_riff_WAVE['rgad'][0]['data'])) {
 220  
 221                      // shortcuts
 222                      $rgadData = &$thisfile_riff_WAVE['rgad'][0]['data'];
 223                      $thisfile_riff_raw['rgad']    = array('track'=>array(), 'album'=>array());
 224                      $thisfile_riff_raw_rgad       = &$thisfile_riff_raw['rgad'];
 225                      $thisfile_riff_raw_rgad_track = &$thisfile_riff_raw_rgad['track'];
 226                      $thisfile_riff_raw_rgad_album = &$thisfile_riff_raw_rgad['album'];
 227  
 228                      $thisfile_riff_raw_rgad['fPeakAmplitude']      = getid3_lib::LittleEndian2Float(substr($rgadData, 0, 4));
 229                      $thisfile_riff_raw_rgad['nRadioRgAdjust']      =        $this->EitherEndian2Int(substr($rgadData, 4, 2));
 230                      $thisfile_riff_raw_rgad['nAudiophileRgAdjust'] =        $this->EitherEndian2Int(substr($rgadData, 6, 2));
 231  
 232                      $nRadioRgAdjustBitstring      = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nRadioRgAdjust']), 16, '0', STR_PAD_LEFT);
 233                      $nAudiophileRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nAudiophileRgAdjust']), 16, '0', STR_PAD_LEFT);
 234                      $thisfile_riff_raw_rgad_track['name']       = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 0, 3));
 235                      $thisfile_riff_raw_rgad_track['originator'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 3, 3));
 236                      $thisfile_riff_raw_rgad_track['signbit']    = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 6, 1));
 237                      $thisfile_riff_raw_rgad_track['adjustment'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 7, 9));
 238                      $thisfile_riff_raw_rgad_album['name']       = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 0, 3));
 239                      $thisfile_riff_raw_rgad_album['originator'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 3, 3));
 240                      $thisfile_riff_raw_rgad_album['signbit']    = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 6, 1));
 241                      $thisfile_riff_raw_rgad_album['adjustment'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 7, 9));
 242  
 243                      $thisfile_riff['rgad']['peakamplitude'] = $thisfile_riff_raw_rgad['fPeakAmplitude'];
 244                      if (($thisfile_riff_raw_rgad_track['name'] != 0) && ($thisfile_riff_raw_rgad_track['originator'] != 0)) {
 245                          $thisfile_riff['rgad']['track']['name']            = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_track['name']);
 246                          $thisfile_riff['rgad']['track']['originator']      = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_track['originator']);
 247                          $thisfile_riff['rgad']['track']['adjustment']      = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_track['adjustment'], $thisfile_riff_raw_rgad_track['signbit']);
 248                      }
 249                      if (($thisfile_riff_raw_rgad_album['name'] != 0) && ($thisfile_riff_raw_rgad_album['originator'] != 0)) {
 250                          $thisfile_riff['rgad']['album']['name']       = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_album['name']);
 251                          $thisfile_riff['rgad']['album']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_album['originator']);
 252                          $thisfile_riff['rgad']['album']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_album['adjustment'], $thisfile_riff_raw_rgad_album['signbit']);
 253                      }
 254                  }
 255  
 256                  if (isset($thisfile_riff_WAVE['fact'][0]['data'])) {
 257                      $thisfile_riff_raw['fact']['NumberOfSamples'] = $this->EitherEndian2Int(substr($thisfile_riff_WAVE['fact'][0]['data'], 0, 4));
 258  
 259                      // This should be a good way of calculating exact playtime,
 260                      // but some sample files have had incorrect number of samples,
 261                      // so cannot use this method
 262  
 263                      // if (!empty($thisfile_riff_raw['fmt ']['nSamplesPerSec'])) {
 264                      //     $info['playtime_seconds'] = (float) $thisfile_riff_raw['fact']['NumberOfSamples'] / $thisfile_riff_raw['fmt ']['nSamplesPerSec'];
 265                      // }
 266                  }
 267                  if (!empty($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'])) {
 268                      $thisfile_audio['bitrate'] = getid3_lib::CastAsInt($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'] * 8);
 269                  }
 270  
 271                  if (isset($thisfile_riff_WAVE['bext'][0]['data'])) {
 272                      // shortcut
 273                      $thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE['bext'][0];
 274  
 275                      $thisfile_riff_WAVE_bext_0['title']          =                         trim(substr($thisfile_riff_WAVE_bext_0['data'],   0, 256));
 276                      $thisfile_riff_WAVE_bext_0['author']         =                         trim(substr($thisfile_riff_WAVE_bext_0['data'], 256,  32));
 277                      $thisfile_riff_WAVE_bext_0['reference']      =                         trim(substr($thisfile_riff_WAVE_bext_0['data'], 288,  32));
 278                      $thisfile_riff_WAVE_bext_0['origin_date']    =                              substr($thisfile_riff_WAVE_bext_0['data'], 320,  10);
 279                      $thisfile_riff_WAVE_bext_0['origin_time']    =                              substr($thisfile_riff_WAVE_bext_0['data'], 330,   8);
 280                      $thisfile_riff_WAVE_bext_0['time_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 338,   8));
 281                      $thisfile_riff_WAVE_bext_0['bwf_version']    = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 346,   1));
 282                      $thisfile_riff_WAVE_bext_0['reserved']       =                              substr($thisfile_riff_WAVE_bext_0['data'], 347, 254);
 283                      $thisfile_riff_WAVE_bext_0['coding_history'] =         explode("\r\n", trim(substr($thisfile_riff_WAVE_bext_0['data'], 601)));
 284                      if (preg_match('#^([0-9]{4}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_date'], $matches_bext_date)) {
 285                          if (preg_match('#^([0-9]{2}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_time'], $matches_bext_time)) {
 286                              list($dummy, $bext_timestamp['year'], $bext_timestamp['month'],  $bext_timestamp['day'])    = $matches_bext_date;
 287                              list($dummy, $bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second']) = $matches_bext_time;
 288                              $thisfile_riff_WAVE_bext_0['origin_date_unix'] = gmmktime($bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second'], $bext_timestamp['month'], $bext_timestamp['day'], $bext_timestamp['year']);
 289                          } else {
 290                              $info['warning'][] = 'RIFF.WAVE.BEXT.origin_time is invalid';
 291                          }
 292                      } else {
 293                          $info['warning'][] = 'RIFF.WAVE.BEXT.origin_date is invalid';
 294                      }
 295                      $thisfile_riff['comments']['author'][] = $thisfile_riff_WAVE_bext_0['author'];
 296                      $thisfile_riff['comments']['title'][]  = $thisfile_riff_WAVE_bext_0['title'];
 297                  }
 298  
 299                  if (isset($thisfile_riff_WAVE['MEXT'][0]['data'])) {
 300                      // shortcut
 301                      $thisfile_riff_WAVE_MEXT_0 = &$thisfile_riff_WAVE['MEXT'][0];
 302  
 303                      $thisfile_riff_WAVE_MEXT_0['raw']['sound_information']      = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 0, 2));
 304                      $thisfile_riff_WAVE_MEXT_0['flags']['homogenous']           = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0001);
 305                      if ($thisfile_riff_WAVE_MEXT_0['flags']['homogenous']) {
 306                          $thisfile_riff_WAVE_MEXT_0['flags']['padding']          = ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0002) ? false : true;
 307                          $thisfile_riff_WAVE_MEXT_0['flags']['22_or_44']         =        (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0004);
 308                          $thisfile_riff_WAVE_MEXT_0['flags']['free_format']      =        (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0008);
 309  
 310                          $thisfile_riff_WAVE_MEXT_0['nominal_frame_size']        = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 2, 2));
 311                      }
 312                      $thisfile_riff_WAVE_MEXT_0['anciliary_data_length']         = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 6, 2));
 313                      $thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def']     = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 8, 2));
 314                      $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_left']  = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0001);
 315                      $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_free']  = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0002);
 316                      $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_right'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0004);
 317                  }
 318  
 319                  if (isset($thisfile_riff_WAVE['cart'][0]['data'])) {
 320                      // shortcut
 321                      $thisfile_riff_WAVE_cart_0 = &$thisfile_riff_WAVE['cart'][0];
 322  
 323                      $thisfile_riff_WAVE_cart_0['version']              =                              substr($thisfile_riff_WAVE_cart_0['data'],   0,  4);
 324                      $thisfile_riff_WAVE_cart_0['title']                =                         trim(substr($thisfile_riff_WAVE_cart_0['data'],   4, 64));
 325                      $thisfile_riff_WAVE_cart_0['artist']               =                         trim(substr($thisfile_riff_WAVE_cart_0['data'],  68, 64));
 326                      $thisfile_riff_WAVE_cart_0['cut_id']               =                         trim(substr($thisfile_riff_WAVE_cart_0['data'], 132, 64));
 327                      $thisfile_riff_WAVE_cart_0['client_id']            =                         trim(substr($thisfile_riff_WAVE_cart_0['data'], 196, 64));
 328                      $thisfile_riff_WAVE_cart_0['category']             =                         trim(substr($thisfile_riff_WAVE_cart_0['data'], 260, 64));
 329                      $thisfile_riff_WAVE_cart_0['classification']       =                         trim(substr($thisfile_riff_WAVE_cart_0['data'], 324, 64));
 330                      $thisfile_riff_WAVE_cart_0['out_cue']              =                         trim(substr($thisfile_riff_WAVE_cart_0['data'], 388, 64));
 331                      $thisfile_riff_WAVE_cart_0['start_date']           =                         trim(substr($thisfile_riff_WAVE_cart_0['data'], 452, 10));
 332                      $thisfile_riff_WAVE_cart_0['start_time']           =                         trim(substr($thisfile_riff_WAVE_cart_0['data'], 462,  8));
 333                      $thisfile_riff_WAVE_cart_0['end_date']             =                         trim(substr($thisfile_riff_WAVE_cart_0['data'], 470, 10));
 334                      $thisfile_riff_WAVE_cart_0['end_time']             =                         trim(substr($thisfile_riff_WAVE_cart_0['data'], 480,  8));
 335                      $thisfile_riff_WAVE_cart_0['producer_app_id']      =                         trim(substr($thisfile_riff_WAVE_cart_0['data'], 488, 64));
 336                      $thisfile_riff_WAVE_cart_0['producer_app_version'] =                         trim(substr($thisfile_riff_WAVE_cart_0['data'], 552, 64));
 337                      $thisfile_riff_WAVE_cart_0['user_defined_text']    =                         trim(substr($thisfile_riff_WAVE_cart_0['data'], 616, 64));
 338                      $thisfile_riff_WAVE_cart_0['zero_db_reference']    = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 680,  4), true);
 339                      for ($i = 0; $i < 8; $i++) {
 340                          $thisfile_riff_WAVE_cart_0['post_time'][$i]['usage_fourcc'] =                  substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8), 4);
 341                          $thisfile_riff_WAVE_cart_0['post_time'][$i]['timer_value']  = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8) + 4, 4));
 342                      }
 343                      $thisfile_riff_WAVE_cart_0['url']              =                 trim(substr($thisfile_riff_WAVE_cart_0['data'],  748, 1024));
 344                      $thisfile_riff_WAVE_cart_0['tag_text']         = explode("\r\n", trim(substr($thisfile_riff_WAVE_cart_0['data'], 1772)));
 345  
 346                      $thisfile_riff['comments']['artist'][] = $thisfile_riff_WAVE_cart_0['artist'];
 347                      $thisfile_riff['comments']['title'][]  = $thisfile_riff_WAVE_cart_0['title'];
 348                  }
 349  
 350                  if (isset($thisfile_riff_WAVE['SNDM'][0]['data'])) {
 351                      // SoundMiner metadata
 352  
 353                      // shortcuts
 354                      $thisfile_riff_WAVE_SNDM_0      = &$thisfile_riff_WAVE['SNDM'][0];
 355                      $thisfile_riff_WAVE_SNDM_0_data = &$thisfile_riff_WAVE_SNDM_0['data'];
 356                      $SNDM_startoffset = 0;
 357                      $SNDM_endoffset   = $thisfile_riff_WAVE_SNDM_0['size'];
 358  
 359                      while ($SNDM_startoffset < $SNDM_endoffset) {
 360                          $SNDM_thisTagOffset = 0;
 361                          $SNDM_thisTagSize      = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4));
 362                          $SNDM_thisTagOffset += 4;
 363                          $SNDM_thisTagKey       =                           substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4);
 364                          $SNDM_thisTagOffset += 4;
 365                          $SNDM_thisTagDataSize  = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2));
 366                          $SNDM_thisTagOffset += 2;
 367                          $SNDM_thisTagDataFlags = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2));
 368                          $SNDM_thisTagOffset += 2;
 369                          $SNDM_thisTagDataText =                            substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, $SNDM_thisTagDataSize);
 370                          $SNDM_thisTagOffset += $SNDM_thisTagDataSize;
 371  
 372                          if ($SNDM_thisTagSize != (4 + 4 + 2 + 2 + $SNDM_thisTagDataSize)) {
 373                              $info['warning'][] = 'RIFF.WAVE.SNDM.data contains tag not expected length (expected: '.$SNDM_thisTagSize.', found: '.(4 + 4 + 2 + 2 + $SNDM_thisTagDataSize).') at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
 374                              break;
 375                          } elseif ($SNDM_thisTagSize <= 0) {
 376                              $info['warning'][] = 'RIFF.WAVE.SNDM.data contains zero-size tag at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
 377                              break;
 378                          }
 379                          $SNDM_startoffset += $SNDM_thisTagSize;
 380  
 381                          $thisfile_riff_WAVE_SNDM_0['parsed_raw'][$SNDM_thisTagKey] = $SNDM_thisTagDataText;
 382                          if ($parsedkey = self::waveSNDMtagLookup($SNDM_thisTagKey)) {
 383                              $thisfile_riff_WAVE_SNDM_0['parsed'][$parsedkey] = $SNDM_thisTagDataText;
 384                          } else {
 385                              $info['warning'][] = 'RIFF.WAVE.SNDM contains unknown tag "'.$SNDM_thisTagKey.'" at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
 386                          }
 387                      }
 388  
 389                      $tagmapping = array(
 390                          'tracktitle'=>'title',
 391                          'category'  =>'genre',
 392                          'cdtitle'   =>'album',
 393                          'tracktitle'=>'title',
 394                      );
 395                      foreach ($tagmapping as $fromkey => $tokey) {
 396                          if (isset($thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey])) {
 397                              $thisfile_riff['comments'][$tokey][] = $thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey];
 398                          }
 399                      }
 400                  }
 401  
 402                  if (isset($thisfile_riff_WAVE['iXML'][0]['data'])) {
 403                      // requires functions simplexml_load_string and get_object_vars
 404                      if ($parsedXML = getid3_lib::XML2array($thisfile_riff_WAVE['iXML'][0]['data'])) {
 405                          $thisfile_riff_WAVE['iXML'][0]['parsed'] = $parsedXML;
 406                          if (isset($parsedXML['SPEED']['MASTER_SPEED'])) {
 407                              @list($numerator, $denominator) = explode('/', $parsedXML['SPEED']['MASTER_SPEED']);
 408                              $thisfile_riff_WAVE['iXML'][0]['master_speed'] = $numerator / ($denominator ? $denominator : 1000);
 409                          }
 410                          if (isset($parsedXML['SPEED']['TIMECODE_RATE'])) {
 411                              @list($numerator, $denominator) = explode('/', $parsedXML['SPEED']['TIMECODE_RATE']);
 412                              $thisfile_riff_WAVE['iXML'][0]['timecode_rate'] = $numerator / ($denominator ? $denominator : 1000);
 413                          }
 414                          if (isset($parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO']) && !empty($parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE']) && !empty($thisfile_riff_WAVE['iXML'][0]['timecode_rate'])) {
 415                              $samples_since_midnight = floatval(ltrim($parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_HI'].$parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO'], '0'));
 416                              $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] = $samples_since_midnight / $parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE'];
 417                              $h = floor( $thisfile_riff_WAVE['iXML'][0]['timecode_seconds']       / 3600);
 418                              $m = floor(($thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600))      / 60);
 419                              $s = floor( $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600) - ($m * 60));
 420                              $f =       ($thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600) - ($m * 60) - $s) * $thisfile_riff_WAVE['iXML'][0]['timecode_rate'];
 421                              $thisfile_riff_WAVE['iXML'][0]['timecode_string']       = sprintf('%02d:%02d:%02d:%05.2f', $h, $m, $s,       $f);
 422                              $thisfile_riff_WAVE['iXML'][0]['timecode_string_round'] = sprintf('%02d:%02d:%02d:%02d',   $h, $m, $s, round($f));
 423                          }
 424                          unset($parsedXML);
 425                      }
 426                  }
 427  
 428  
 429  
 430                  if (!isset($thisfile_audio['bitrate']) && isset($thisfile_riff_audio[$streamindex]['bitrate'])) {
 431                      $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
 432                      $info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']);
 433                  }
 434  
 435                  if (!empty($info['wavpack'])) {
 436                      $thisfile_audio_dataformat = 'wavpack';
 437                      $thisfile_audio['bitrate_mode'] = 'vbr';
 438                      $thisfile_audio['encoder']      = 'WavPack v'.$info['wavpack']['version'];
 439  
 440                      // Reset to the way it was - RIFF parsing will have messed this up
 441                      $info['avdataend']        = $Original['avdataend'];
 442                      $thisfile_audio['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
 443  
 444                      $this->fseek($info['avdataoffset'] - 44);
 445                      $RIFFdata = $this->fread(44);
 446                      $OrignalRIFFheaderSize = getid3_lib::LittleEndian2Int(substr($RIFFdata,  4, 4)) +  8;
 447                      $OrignalRIFFdataSize   = getid3_lib::LittleEndian2Int(substr($RIFFdata, 40, 4)) + 44;
 448  
 449                      if ($OrignalRIFFheaderSize > $OrignalRIFFdataSize) {
 450                          $info['avdataend'] -= ($OrignalRIFFheaderSize - $OrignalRIFFdataSize);
 451                          $this->fseek($info['avdataend']);
 452                          $RIFFdata .= $this->fread($OrignalRIFFheaderSize - $OrignalRIFFdataSize);
 453                      }
 454  
 455                      // move the data chunk after all other chunks (if any)
 456                      // so that the RIFF parser doesn't see EOF when trying
 457                      // to skip over the data chunk
 458                      $RIFFdata = substr($RIFFdata, 0, 36).substr($RIFFdata, 44).substr($RIFFdata, 36, 8);
 459                      $getid3_riff = new getid3_riff($this->getid3);
 460                      $getid3_riff->ParseRIFFdata($RIFFdata);
 461                      unset($getid3_riff);
 462                  }
 463  
 464                  if (isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
 465                      switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
 466                          case 0x0001: // PCM
 467                              if (!empty($info['ac3'])) {
 468                                  // Dolby Digital WAV files masquerade as PCM-WAV, but they're not
 469                                  $thisfile_audio['wformattag']  = 0x2000;
 470                                  $thisfile_audio['codec']       = self::wFormatTagLookup($thisfile_audio['wformattag']);
 471                                  $thisfile_audio['lossless']    = false;
 472                                  $thisfile_audio['bitrate']     = $info['ac3']['bitrate'];
 473                                  $thisfile_audio['sample_rate'] = $info['ac3']['sample_rate'];
 474                              }
 475                              if (!empty($info['dts'])) {
 476                                  // Dolby DTS files masquerade as PCM-WAV, but they're not
 477                                  $thisfile_audio['wformattag']  = 0x2001;
 478                                  $thisfile_audio['codec']       = self::wFormatTagLookup($thisfile_audio['wformattag']);
 479                                  $thisfile_audio['lossless']    = false;
 480                                  $thisfile_audio['bitrate']     = $info['dts']['bitrate'];
 481                                  $thisfile_audio['sample_rate'] = $info['dts']['sample_rate'];
 482                              }
 483                              break;
 484                          case 0x08AE: // ClearJump LiteWave
 485                              $thisfile_audio['bitrate_mode'] = 'vbr';
 486                              $thisfile_audio_dataformat   = 'litewave';
 487  
 488                              //typedef struct tagSLwFormat {
 489                              //  WORD    m_wCompFormat;     // low byte defines compression method, high byte is compression flags
 490                              //  DWORD   m_dwScale;         // scale factor for lossy compression
 491                              //  DWORD   m_dwBlockSize;     // number of samples in encoded blocks
 492                              //  WORD    m_wQuality;        // alias for the scale factor
 493                              //  WORD    m_wMarkDistance;   // distance between marks in bytes
 494                              //  WORD    m_wReserved;
 495                              //
 496                              //  //following paramters are ignored if CF_FILESRC is not set
 497                              //  DWORD   m_dwOrgSize;       // original file size in bytes
 498                              //  WORD    m_bFactExists;     // indicates if 'fact' chunk exists in the original file
 499                              //  DWORD   m_dwRiffChunkSize; // riff chunk size in the original file
 500                              //
 501                              //  PCMWAVEFORMAT m_OrgWf;     // original wave format
 502                              // }SLwFormat, *PSLwFormat;
 503  
 504                              // shortcut
 505                              $thisfile_riff['litewave']['raw'] = array();
 506                              $riff_litewave     = &$thisfile_riff['litewave'];
 507                              $riff_litewave_raw = &$riff_litewave['raw'];
 508  
 509                              $flags = array(
 510                                  'compression_method' => 1,
 511                                  'compression_flags'  => 1,
 512                                  'm_dwScale'          => 4,
 513                                  'm_dwBlockSize'      => 4,
 514                                  'm_wQuality'         => 2,
 515                                  'm_wMarkDistance'    => 2,
 516                                  'm_wReserved'        => 2,
 517                                  'm_dwOrgSize'        => 4,
 518                                  'm_bFactExists'      => 2,
 519                                  'm_dwRiffChunkSize'  => 4,
 520                              );
 521                              $litewave_offset = 18;
 522                              foreach ($flags as $flag => $length) {
 523                                  $riff_litewave_raw[$flag] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], $litewave_offset, $length));
 524                                  $litewave_offset += $length;
 525                              }
 526  
 527                              //$riff_litewave['quality_factor'] = intval(round((2000 - $riff_litewave_raw['m_dwScale']) / 20));
 528                              $riff_litewave['quality_factor'] = $riff_litewave_raw['m_wQuality'];
 529  
 530                              $riff_litewave['flags']['raw_source']    = ($riff_litewave_raw['compression_flags'] & 0x01) ? false : true;
 531                              $riff_litewave['flags']['vbr_blocksize'] = ($riff_litewave_raw['compression_flags'] & 0x02) ? false : true;
 532                              $riff_litewave['flags']['seekpoints']    =        (bool) ($riff_litewave_raw['compression_flags'] & 0x04);
 533  
 534                              $thisfile_audio['lossless']        = (($riff_litewave_raw['m_wQuality'] == 100) ? true : false);
 535                              $thisfile_audio['encoder_options'] = '-q'.$riff_litewave['quality_factor'];
 536                              break;
 537  
 538                          default:
 539                              break;
 540                      }
 541                  }
 542                  if ($info['avdataend'] > $info['filesize']) {
 543                      switch (!empty($thisfile_audio_dataformat) ? $thisfile_audio_dataformat : '') {
 544                          case 'wavpack': // WavPack
 545                          case 'lpac':    // LPAC
 546                          case 'ofr':     // OptimFROG
 547                          case 'ofs':     // OptimFROG DualStream
 548                              // lossless compressed audio formats that keep original RIFF headers - skip warning
 549                              break;
 550  
 551                          case 'litewave':
 552                              if (($info['avdataend'] - $info['filesize']) == 1) {
 553                                  // LiteWave appears to incorrectly *not* pad actual output file
 554                                  // to nearest WORD boundary so may appear to be short by one
 555                                  // byte, in which case - skip warning
 556                              } else {
 557                                  // Short by more than one byte, throw warning
 558                                  $info['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
 559                                  $info['avdataend'] = $info['filesize'];
 560                              }
 561                              break;
 562  
 563                          default:
 564                              if ((($info['avdataend'] - $info['filesize']) == 1) && (($thisfile_riff[$RIFFsubtype]['data'][0]['size'] % 2) == 0) && ((($info['filesize'] - $info['avdataoffset']) % 2) == 1)) {
 565                                  // output file appears to be incorrectly *not* padded to nearest WORD boundary
 566                                  // Output less severe warning
 567                                  $info['warning'][] = 'File should probably be padded to nearest WORD boundary, but it is not (expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' therefore short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
 568                                  $info['avdataend'] = $info['filesize'];
 569                              } else {
 570                                  // Short by more than one byte, throw warning
 571                                  $info['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
 572                                  $info['avdataend'] = $info['filesize'];
 573                              }
 574                              break;
 575                      }
 576                  }
 577                  if (!empty($info['mpeg']['audio']['LAME']['audio_bytes'])) {
 578                      if ((($info['avdataend'] - $info['avdataoffset']) - $info['mpeg']['audio']['LAME']['audio_bytes']) == 1) {
 579                          $info['avdataend']--;
 580                          $info['warning'][] = 'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored';
 581                      }
 582                  }
 583                  if (isset($thisfile_audio_dataformat) && ($thisfile_audio_dataformat == 'ac3')) {
 584                      unset($thisfile_audio['bits_per_sample']);
 585                      if (!empty($info['ac3']['bitrate']) && ($info['ac3']['bitrate'] != $thisfile_audio['bitrate'])) {
 586                          $thisfile_audio['bitrate'] = $info['ac3']['bitrate'];
 587                      }
 588                  }
 589                  break;
 590  
 591              case 'AVI ':
 592                  $thisfile_video['bitrate_mode'] = 'vbr'; // maybe not, but probably
 593                  $thisfile_video['dataformat']   = 'avi';
 594                  $info['mime_type']      = 'video/avi';
 595  
 596                  if (isset($thisfile_riff[$RIFFsubtype]['movi']['offset'])) {
 597                      $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['movi']['offset'] + 8;
 598                      if (isset($thisfile_riff['AVIX'])) {
 599                          $info['avdataend'] = $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['offset'] + $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['size'];
 600                      } else {
 601                          $info['avdataend'] = $thisfile_riff['AVI ']['movi']['offset'] + $thisfile_riff['AVI ']['movi']['size'];
 602                      }
 603                      if ($info['avdataend'] > $info['filesize']) {
 604                          $info['warning'][] = 'Probably truncated file - expecting '.($info['avdataend'] - $info['avdataoffset']).' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($info['avdataend'] - $info['filesize']).' bytes)';
 605                          $info['avdataend'] = $info['filesize'];
 606                      }
 607                  }
 608  
 609                  if (isset($thisfile_riff['AVI ']['hdrl']['strl']['indx'])) {
 610                      //$bIndexType = array(
 611                      //    0x00 => 'AVI_INDEX_OF_INDEXES',
 612                      //    0x01 => 'AVI_INDEX_OF_CHUNKS',
 613                      //    0x80 => 'AVI_INDEX_IS_DATA',
 614                      //);
 615                      //$bIndexSubtype = array(
 616                      //    0x01 => array(
 617                      //        0x01 => 'AVI_INDEX_2FIELD',
 618                      //    ),
 619                      //);
 620                      foreach ($thisfile_riff['AVI ']['hdrl']['strl']['indx'] as $streamnumber => $steamdataarray) {
 621                          $ahsisd = &$thisfile_riff['AVI ']['hdrl']['strl']['indx'][$streamnumber]['data'];
 622  
 623                          $thisfile_riff_raw['indx'][$streamnumber]['wLongsPerEntry'] = $this->EitherEndian2Int(substr($ahsisd,  0, 2));
 624                          $thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType']  = $this->EitherEndian2Int(substr($ahsisd,  2, 1));
 625                          $thisfile_riff_raw['indx'][$streamnumber]['bIndexType']     = $this->EitherEndian2Int(substr($ahsisd,  3, 1));
 626                          $thisfile_riff_raw['indx'][$streamnumber]['nEntriesInUse']  = $this->EitherEndian2Int(substr($ahsisd,  4, 4));
 627                          $thisfile_riff_raw['indx'][$streamnumber]['dwChunkId']      =                         substr($ahsisd,  8, 4);
 628                          $thisfile_riff_raw['indx'][$streamnumber]['dwReserved']     = $this->EitherEndian2Int(substr($ahsisd, 12, 4));
 629  
 630                          //$thisfile_riff_raw['indx'][$streamnumber]['bIndexType_name']    =    $bIndexType[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']];
 631                          //$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType_name'] = $bIndexSubtype[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']][$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType']];
 632  
 633                          unset($ahsisd);
 634                      }
 635                  }
 636                  if (isset($thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'])) {
 637                      $avihData = $thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'];
 638  
 639                      // shortcut
 640                      $thisfile_riff_raw['avih'] = array();
 641                      $thisfile_riff_raw_avih = &$thisfile_riff_raw['avih'];
 642  
 643                      $thisfile_riff_raw_avih['dwMicroSecPerFrame']    = $this->EitherEndian2Int(substr($avihData,  0, 4)); // frame display rate (or 0L)
 644                      if ($thisfile_riff_raw_avih['dwMicroSecPerFrame'] == 0) {
 645                          $info['error'][] = 'Corrupt RIFF file: avih.dwMicroSecPerFrame == zero';
 646                          return false;
 647                      }
 648  
 649                      $flags = array(
 650                          'dwMaxBytesPerSec',       // max. transfer rate
 651                          'dwPaddingGranularity',   // pad to multiples of this size; normally 2K.
 652                          'dwFlags',                // the ever-present flags
 653                          'dwTotalFrames',          // # frames in file
 654                          'dwInitialFrames',        //
 655                          'dwStreams',              //
 656                          'dwSuggestedBufferSize',  //
 657                          'dwWidth',                //
 658                          'dwHeight',               //
 659                          'dwScale',                //
 660                          'dwRate',                 //
 661                          'dwStart',                //
 662                          'dwLength',               //
 663                      );
 664                      $avih_offset = 4;
 665                      foreach ($flags as $flag) {
 666                          $thisfile_riff_raw_avih[$flag] = $this->EitherEndian2Int(substr($avihData, $avih_offset, 4));
 667                          $avih_offset += 4;
 668                      }
 669  
 670                      $flags = array(
 671                          'hasindex'     => 0x00000010,
 672                          'mustuseindex' => 0x00000020,
 673                          'interleaved'  => 0x00000100,
 674                          'trustcktype'  => 0x00000800,
 675                          'capturedfile' => 0x00010000,
 676                          'copyrighted'  => 0x00020010,
 677                      );
 678                      foreach ($flags as $flag => $value) {
 679                          $thisfile_riff_raw_avih['flags'][$flag] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & $value);
 680                      }
 681  
 682                      // shortcut
 683                      $thisfile_riff_video[$streamindex] = array();
 684                      $thisfile_riff_video_current = &$thisfile_riff_video[$streamindex];
 685  
 686                      if ($thisfile_riff_raw_avih['dwWidth'] > 0) {
 687                          $thisfile_riff_video_current['frame_width'] = $thisfile_riff_raw_avih['dwWidth'];
 688                          $thisfile_video['resolution_x']             = $thisfile_riff_video_current['frame_width'];
 689                      }
 690                      if ($thisfile_riff_raw_avih['dwHeight'] > 0) {
 691                          $thisfile_riff_video_current['frame_height'] = $thisfile_riff_raw_avih['dwHeight'];
 692                          $thisfile_video['resolution_y']              = $thisfile_riff_video_current['frame_height'];
 693                      }
 694                      if ($thisfile_riff_raw_avih['dwTotalFrames'] > 0) {
 695                          $thisfile_riff_video_current['total_frames'] = $thisfile_riff_raw_avih['dwTotalFrames'];
 696                          $thisfile_video['total_frames']              = $thisfile_riff_video_current['total_frames'];
 697                      }
 698  
 699                      $thisfile_riff_video_current['frame_rate'] = round(1000000 / $thisfile_riff_raw_avih['dwMicroSecPerFrame'], 3);
 700                      $thisfile_video['frame_rate'] = $thisfile_riff_video_current['frame_rate'];
 701                  }
 702                  if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][0]['data'])) {
 703                      if (is_array($thisfile_riff['AVI ']['hdrl']['strl']['strh'])) {
 704                          for ($i = 0; $i < count($thisfile_riff['AVI ']['hdrl']['strl']['strh']); $i++) {
 705                              if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'])) {
 706                                  $strhData = $thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'];
 707                                  $strhfccType = substr($strhData,  0, 4);
 708  
 709                                  if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'])) {
 710                                      $strfData = $thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'];
 711  
 712                                      // shortcut
 713                                      $thisfile_riff_raw_strf_strhfccType_streamindex = &$thisfile_riff_raw['strf'][$strhfccType][$streamindex];
 714  
 715                                      switch ($strhfccType) {
 716                                          case 'auds':
 717                                              $thisfile_audio['bitrate_mode'] = 'cbr';
 718                                              $thisfile_audio_dataformat      = 'wav';
 719                                              if (isset($thisfile_riff_audio) && is_array($thisfile_riff_audio)) {
 720                                                  $streamindex = count($thisfile_riff_audio);
 721                                              }
 722  
 723                                              $thisfile_riff_audio[$streamindex] = self::parseWAVEFORMATex($strfData);
 724                                              $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
 725  
 726                                              // shortcut
 727                                              $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
 728                                              $thisfile_audio_streams_currentstream = &$thisfile_audio['streams'][$streamindex];
 729  
 730                                              if ($thisfile_audio_streams_currentstream['bits_per_sample'] == 0) {
 731                                                  unset($thisfile_audio_streams_currentstream['bits_per_sample']);
 732                                              }
 733                                              $thisfile_audio_streams_currentstream['wformattag'] = $thisfile_audio_streams_currentstream['raw']['wFormatTag'];
 734                                              unset($thisfile_audio_streams_currentstream['raw']);
 735  
 736                                              // shortcut
 737                                              $thisfile_riff_raw['strf'][$strhfccType][$streamindex] = $thisfile_riff_audio[$streamindex]['raw'];
 738  
 739                                              unset($thisfile_riff_audio[$streamindex]['raw']);
 740                                              $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
 741  
 742                                              $thisfile_audio['lossless'] = false;
 743                                              switch ($thisfile_riff_raw_strf_strhfccType_streamindex['wFormatTag']) {
 744                                                  case 0x0001:  // PCM
 745                                                      $thisfile_audio_dataformat  = 'wav';
 746                                                      $thisfile_audio['lossless'] = true;
 747                                                      break;
 748  
 749                                                  case 0x0050: // MPEG Layer 2 or Layer 1
 750                                                      $thisfile_audio_dataformat = 'mp2'; // Assume Layer-2
 751                                                      break;
 752  
 753                                                  case 0x0055: // MPEG Layer 3
 754                                                      $thisfile_audio_dataformat = 'mp3';
 755                                                      break;
 756  
 757                                                  case 0x00FF: // AAC
 758                                                      $thisfile_audio_dataformat = 'aac';
 759                                                      break;
 760  
 761                                                  case 0x0161: // Windows Media v7 / v8 / v9
 762                                                  case 0x0162: // Windows Media Professional v9
 763                                                  case 0x0163: // Windows Media Lossess v9
 764                                                      $thisfile_audio_dataformat = 'wma';
 765                                                      break;
 766  
 767                                                  case 0x2000: // AC-3
 768                                                      $thisfile_audio_dataformat = 'ac3';
 769                                                      break;
 770  
 771                                                  case 0x2001: // DTS
 772                                                      $thisfile_audio_dataformat = 'dts';
 773                                                      break;
 774  
 775                                                  default:
 776                                                      $thisfile_audio_dataformat = 'wav';
 777                                                      break;
 778                                              }
 779                                              $thisfile_audio_streams_currentstream['dataformat']   = $thisfile_audio_dataformat;
 780                                              $thisfile_audio_streams_currentstream['lossless']     = $thisfile_audio['lossless'];
 781                                              $thisfile_audio_streams_currentstream['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
 782                                              break;
 783  
 784  
 785                                          case 'iavs':
 786                                          case 'vids':
 787                                              // shortcut
 788                                              $thisfile_riff_raw['strh'][$i]                  = array();
 789                                              $thisfile_riff_raw_strh_current                 = &$thisfile_riff_raw['strh'][$i];
 790  
 791                                              $thisfile_riff_raw_strh_current['fccType']               =                         substr($strhData,  0, 4);  // same as $strhfccType;
 792                                              $thisfile_riff_raw_strh_current['fccHandler']            =                         substr($strhData,  4, 4);
 793                                              $thisfile_riff_raw_strh_current['dwFlags']               = $this->EitherEndian2Int(substr($strhData,  8, 4)); // Contains AVITF_* flags
 794                                              $thisfile_riff_raw_strh_current['wPriority']             = $this->EitherEndian2Int(substr($strhData, 12, 2));
 795                                              $thisfile_riff_raw_strh_current['wLanguage']             = $this->EitherEndian2Int(substr($strhData, 14, 2));
 796                                              $thisfile_riff_raw_strh_current['dwInitialFrames']       = $this->EitherEndian2Int(substr($strhData, 16, 4));
 797                                              $thisfile_riff_raw_strh_current['dwScale']               = $this->EitherEndian2Int(substr($strhData, 20, 4));
 798                                              $thisfile_riff_raw_strh_current['dwRate']                = $this->EitherEndian2Int(substr($strhData, 24, 4));
 799                                              $thisfile_riff_raw_strh_current['dwStart']               = $this->EitherEndian2Int(substr($strhData, 28, 4));
 800                                              $thisfile_riff_raw_strh_current['dwLength']              = $this->EitherEndian2Int(substr($strhData, 32, 4));
 801                                              $thisfile_riff_raw_strh_current['dwSuggestedBufferSize'] = $this->EitherEndian2Int(substr($strhData, 36, 4));
 802                                              $thisfile_riff_raw_strh_current['dwQuality']             = $this->EitherEndian2Int(substr($strhData, 40, 4));
 803                                              $thisfile_riff_raw_strh_current['dwSampleSize']          = $this->EitherEndian2Int(substr($strhData, 44, 4));
 804                                              $thisfile_riff_raw_strh_current['rcFrame']               = $this->EitherEndian2Int(substr($strhData, 48, 4));
 805  
 806                                              $thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_riff_raw_strh_current['fccHandler']);
 807                                              $thisfile_video['fourcc']             = $thisfile_riff_raw_strh_current['fccHandler'];
 808                                              if (!$thisfile_riff_video_current['codec'] && isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) && self::fourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
 809                                                  $thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']);
 810                                                  $thisfile_video['fourcc']             = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
 811                                              }
 812                                              $thisfile_video['codec']              = $thisfile_riff_video_current['codec'];
 813                                              $thisfile_video['pixel_aspect_ratio'] = (float) 1;
 814                                              switch ($thisfile_riff_raw_strh_current['fccHandler']) {
 815                                                  case 'HFYU': // Huffman Lossless Codec
 816                                                  case 'IRAW': // Intel YUV Uncompressed
 817                                                  case 'YUY2': // Uncompressed YUV 4:2:2
 818                                                      $thisfile_video['lossless'] = true;
 819                                                      break;
 820  
 821                                                  default:
 822                                                      $thisfile_video['lossless'] = false;
 823                                                      break;
 824                                              }
 825  
 826                                              switch ($strhfccType) {
 827                                                  case 'vids':
 828                                                      $thisfile_riff_raw_strf_strhfccType_streamindex = self::ParseBITMAPINFOHEADER(substr($strfData, 0, 40), ($info['fileformat'] == 'riff'));
 829                                                      $thisfile_video['bits_per_sample'] = $thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount'];
 830  
 831                                                      if ($thisfile_riff_video_current['codec'] == 'DV') {
 832                                                          $thisfile_riff_video_current['dv_type'] = 2;
 833                                                      }
 834                                                      break;
 835  
 836                                                  case 'iavs':
 837                                                      $thisfile_riff_video_current['dv_type'] = 1;
 838                                                      break;
 839                                              }
 840                                              break;
 841  
 842                                          default:
 843                                              $info['warning'][] = 'Unhandled fccType for stream ('.$i.'): "'.$strhfccType.'"';
 844                                              break;
 845  
 846                                      }
 847                                  }
 848                              }
 849  
 850                              if (isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
 851  
 852                                  $thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
 853                                  if (self::fourccLookup($thisfile_video['fourcc'])) {
 854                                      $thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_video['fourcc']);
 855                                      $thisfile_video['codec']              = $thisfile_riff_video_current['codec'];
 856                                  }
 857  
 858                                  switch ($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) {
 859                                      case 'HFYU': // Huffman Lossless Codec
 860                                      case 'IRAW': // Intel YUV Uncompressed
 861                                      case 'YUY2': // Uncompressed YUV 4:2:2
 862                                          $thisfile_video['lossless']        = true;
 863                                          //$thisfile_video['bits_per_sample'] = 24;
 864                                          break;
 865  
 866                                      default:
 867                                          $thisfile_video['lossless']        = false;
 868                                          //$thisfile_video['bits_per_sample'] = 24;
 869                                          break;
 870                                  }
 871  
 872                              }
 873                          }
 874                      }
 875                  }
 876                  break;
 877  
 878              case 'CDDA':
 879                  $thisfile_audio['bitrate_mode'] = 'cbr';
 880                  $thisfile_audio_dataformat      = 'cda';
 881                  $thisfile_audio['lossless']     = true;
 882                  unset($info['mime_type']);
 883  
 884                  $info['avdataoffset'] = 44;
 885  
 886                  if (isset($thisfile_riff['CDDA']['fmt '][0]['data'])) {
 887                      // shortcut
 888                      $thisfile_riff_CDDA_fmt_0 = &$thisfile_riff['CDDA']['fmt '][0];
 889  
 890                      $thisfile_riff_CDDA_fmt_0['unknown1']           = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'],  0, 2));
 891                      $thisfile_riff_CDDA_fmt_0['track_num']          = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'],  2, 2));
 892                      $thisfile_riff_CDDA_fmt_0['disc_id']            = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'],  4, 4));
 893                      $thisfile_riff_CDDA_fmt_0['start_offset_frame'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'],  8, 4));
 894                      $thisfile_riff_CDDA_fmt_0['playtime_frames']    = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 12, 4));
 895                      $thisfile_riff_CDDA_fmt_0['unknown6']           = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 16, 4));
 896                      $thisfile_riff_CDDA_fmt_0['unknown7']           = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 20, 4));
 897  
 898                      $thisfile_riff_CDDA_fmt_0['start_offset_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['start_offset_frame'] / 75;
 899                      $thisfile_riff_CDDA_fmt_0['playtime_seconds']     = (float) $thisfile_riff_CDDA_fmt_0['playtime_frames'] / 75;
 900                      $info['comments']['track']                = $thisfile_riff_CDDA_fmt_0['track_num'];
 901                      $info['playtime_seconds']                 = $thisfile_riff_CDDA_fmt_0['playtime_seconds'];
 902  
 903                      // hardcoded data for CD-audio
 904                      $thisfile_audio['sample_rate']     = 44100;
 905                      $thisfile_audio['channels']        = 2;
 906                      $thisfile_audio['bits_per_sample'] = 16;
 907                      $thisfile_audio['bitrate']         = $thisfile_audio['sample_rate'] * $thisfile_audio['channels'] * $thisfile_audio['bits_per_sample'];
 908                      $thisfile_audio['bitrate_mode']    = 'cbr';
 909                  }
 910                  break;
 911  
 912  
 913              case 'AIFF':
 914              case 'AIFC':
 915                  $thisfile_audio['bitrate_mode'] = 'cbr';
 916                  $thisfile_audio_dataformat      = 'aiff';
 917                  $thisfile_audio['lossless']     = true;
 918                  $info['mime_type']      = 'audio/x-aiff';
 919  
 920                  if (isset($thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'])) {
 921                      $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'] + 8;
 922                      $info['avdataend']    = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['SSND'][0]['size'];
 923                      if ($info['avdataend'] > $info['filesize']) {
 924                          if (($info['avdataend'] == ($info['filesize'] + 1)) && (($info['filesize'] % 2) == 1)) {
 925                              // structures rounded to 2-byte boundary, but dumb encoders
 926                              // forget to pad end of file to make this actually work
 927                          } else {
 928                              $info['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['SSND'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found';
 929                          }
 930                          $info['avdataend'] = $info['filesize'];
 931                      }
 932                  }
 933  
 934                  if (isset($thisfile_riff[$RIFFsubtype]['COMM'][0]['data'])) {
 935  
 936                      // shortcut
 937                      $thisfile_riff_RIFFsubtype_COMM_0_data = &$thisfile_riff[$RIFFsubtype]['COMM'][0]['data'];
 938  
 939                      $thisfile_riff_audio['channels']         =         getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data,  0,  2), true);
 940                      $thisfile_riff_audio['total_samples']    =         getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data,  2,  4), false);
 941                      $thisfile_riff_audio['bits_per_sample']  =         getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data,  6,  2), true);
 942                      $thisfile_riff_audio['sample_rate']      = (int) getid3_lib::BigEndian2Float(substr($thisfile_riff_RIFFsubtype_COMM_0_data,  8, 10));
 943  
 944                      if ($thisfile_riff[$RIFFsubtype]['COMM'][0]['size'] > 18) {
 945                          $thisfile_riff_audio['codec_fourcc'] =                                   substr($thisfile_riff_RIFFsubtype_COMM_0_data, 18,  4);
 946                          $CodecNameSize                       =         getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 22,  1), false);
 947                          $thisfile_riff_audio['codec_name']   =                                   substr($thisfile_riff_RIFFsubtype_COMM_0_data, 23,  $CodecNameSize);
 948                          switch ($thisfile_riff_audio['codec_name']) {
 949                              case 'NONE':
 950                                  $thisfile_audio['codec']    = 'Pulse Code Modulation (PCM)';
 951                                  $thisfile_audio['lossless'] = true;
 952                                  break;
 953  
 954                              case '':
 955                                  switch ($thisfile_riff_audio['codec_fourcc']) {
 956                                      // http://developer.apple.com/qa/snd/snd07.html
 957                                      case 'sowt':
 958                                          $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Little-Endian PCM';
 959                                          $thisfile_audio['lossless'] = true;
 960                                          break;
 961  
 962                                      case 'twos':
 963                                          $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Big-Endian PCM';
 964                                          $thisfile_audio['lossless'] = true;
 965                                          break;
 966  
 967                                      default:
 968                                          break;
 969                                  }
 970                                  break;
 971  
 972                              default:
 973                                  $thisfile_audio['codec']    = $thisfile_riff_audio['codec_name'];
 974                                  $thisfile_audio['lossless'] = false;
 975                                  break;
 976                          }
 977                      }
 978  
 979                      $thisfile_audio['channels']        = $thisfile_riff_audio['channels'];
 980                      if ($thisfile_riff_audio['bits_per_sample'] > 0) {
 981                          $thisfile_audio['bits_per_sample'] = $thisfile_riff_audio['bits_per_sample'];
 982                      }
 983                      $thisfile_audio['sample_rate']     = $thisfile_riff_audio['sample_rate'];
 984                      if ($thisfile_audio['sample_rate'] == 0) {
 985                          $info['error'][] = 'Corrupted AIFF file: sample_rate == zero';
 986                          return false;
 987                      }
 988                      $info['playtime_seconds'] = $thisfile_riff_audio['total_samples'] / $thisfile_audio['sample_rate'];
 989                  }
 990  
 991                  if (isset($thisfile_riff[$RIFFsubtype]['COMT'])) {
 992                      $offset = 0;
 993                      $CommentCount                                   = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
 994                      $offset += 2;
 995                      for ($i = 0; $i < $CommentCount; $i++) {
 996                          $info['comments_raw'][$i]['timestamp']      = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 4), false);
 997                          $offset += 4;
 998                          $info['comments_raw'][$i]['marker_id']      = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), true);
 999                          $offset += 2;
1000                          $CommentLength                              = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
1001                          $offset += 2;
1002                          $info['comments_raw'][$i]['comment']        =                           substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, $CommentLength);
1003                          $offset += $CommentLength;
1004  
1005                          $info['comments_raw'][$i]['timestamp_unix'] = getid3_lib::DateMac2Unix($info['comments_raw'][$i]['timestamp']);
1006                          $thisfile_riff['comments']['comment'][] = $info['comments_raw'][$i]['comment'];
1007                      }
1008                  }
1009  
1010                  $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment');
1011                  foreach ($CommentsChunkNames as $key => $value) {
1012                      if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) {
1013                          $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data'];
1014                      }
1015                  }
1016  /*
1017                  if (isset($thisfile_riff[$RIFFsubtype]['ID3 '])) {
1018                      getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
1019                      $getid3_temp = new getID3();
1020                      $getid3_temp->openfile($this->getid3->filename);
1021                      $getid3_id3v2 = new getid3_id3v2($getid3_temp);
1022                      $getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['ID3 '][0]['offset'] + 8;
1023                      if ($thisfile_riff[$RIFFsubtype]['ID3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
1024                          $info['id3v2'] = $getid3_temp->info['id3v2'];
1025                      }
1026                      unset($getid3_temp, $getid3_id3v2);
1027                  }
1028  */
1029                  break;
1030  
1031              case '8SVX':
1032                  $thisfile_audio['bitrate_mode']    = 'cbr';
1033                  $thisfile_audio_dataformat         = '8svx';
1034                  $thisfile_audio['bits_per_sample'] = 8;
1035                  $thisfile_audio['channels']        = 1; // overridden below, if need be
1036                  $info['mime_type']                = 'audio/x-aiff';
1037  
1038                  if (isset($thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'])) {
1039                      $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'] + 8;
1040                      $info['avdataend']    = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['BODY'][0]['size'];
1041                      if ($info['avdataend'] > $info['filesize']) {
1042                          $info['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['BODY'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found';
1043                      }
1044                  }
1045  
1046                  if (isset($thisfile_riff[$RIFFsubtype]['VHDR'][0]['offset'])) {
1047                      // shortcut
1048                      $thisfile_riff_RIFFsubtype_VHDR_0 = &$thisfile_riff[$RIFFsubtype]['VHDR'][0];
1049  
1050                      $thisfile_riff_RIFFsubtype_VHDR_0['oneShotHiSamples']  =   getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'],  0, 4));
1051                      $thisfile_riff_RIFFsubtype_VHDR_0['repeatHiSamples']   =   getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'],  4, 4));
1052                      $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerHiCycle'] =   getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'],  8, 4));
1053                      $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec']     =   getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 12, 2));
1054                      $thisfile_riff_RIFFsubtype_VHDR_0['ctOctave']          =   getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 14, 1));
1055                      $thisfile_riff_RIFFsubtype_VHDR_0['sCompression']      =   getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 15, 1));
1056                      $thisfile_riff_RIFFsubtype_VHDR_0['Volume']            = getid3_lib::FixedPoint16_16(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 16, 4));
1057  
1058                      $thisfile_audio['sample_rate'] = $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'];
1059  
1060                      switch ($thisfile_riff_RIFFsubtype_VHDR_0['sCompression']) {
1061                          case 0:
1062                              $thisfile_audio['codec']    = 'Pulse Code Modulation (PCM)';
1063                              $thisfile_audio['lossless'] = true;
1064                              $ActualBitsPerSample        = 8;
1065                              break;
1066  
1067                          case 1:
1068                              $thisfile_audio['codec']    = 'Fibonacci-delta encoding';
1069                              $thisfile_audio['lossless'] = false;
1070                              $ActualBitsPerSample        = 4;
1071                              break;
1072  
1073                          default:
1074                              $info['warning'][] = 'Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.sCompression.'"';
1075                              break;
1076                      }
1077                  }
1078  
1079                  if (isset($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'])) {
1080                      $ChannelsIndex = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'], 0, 4));
1081                      switch ($ChannelsIndex) {
1082                          case 6: // Stereo
1083                              $thisfile_audio['channels'] = 2;
1084                              break;
1085  
1086                          case 2: // Left channel only
1087                          case 4: // Right channel only
1088                              $thisfile_audio['channels'] = 1;
1089                              break;
1090  
1091                          default:
1092                              $info['warning'][] = 'Unexpected value in 8SVX.CHAN chunk - expecting 2 or 4 or 6, found "'.$ChannelsIndex.'"';
1093                              break;
1094                      }
1095  
1096                  }
1097  
1098                  $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment');
1099                  foreach ($CommentsChunkNames as $key => $value) {
1100                      if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) {
1101                          $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data'];
1102                      }
1103                  }
1104  
1105                  $thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $ActualBitsPerSample * $thisfile_audio['channels'];
1106                  if (!empty($thisfile_audio['bitrate'])) {
1107                      $info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset']) / ($thisfile_audio['bitrate'] / 8);
1108                  }
1109                  break;
1110  
1111  
1112              case 'CDXA':
1113                  $info['mime_type'] = 'video/mpeg';
1114                  if (!empty($thisfile_riff['CDXA']['data'][0]['size'])) {
1115                      if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, false)) {
1116                          $getid3_temp = new getID3();
1117                          $getid3_temp->openfile($this->getid3->filename);
1118                          $getid3_mpeg = new getid3_mpeg($getid3_temp);
1119                          $getid3_mpeg->Analyze();
1120                          if (empty($getid3_temp->info['error'])) {
1121                              $info['audio']   = $getid3_temp->info['audio'];
1122                              $info['video']   = $getid3_temp->info['video'];
1123                              $info['mpeg']    = $getid3_temp->info['mpeg'];
1124                              $info['warning'] = $getid3_temp->info['warning'];
1125                          }
1126                          unset($getid3_temp, $getid3_mpeg);
1127                      }
1128                  }
1129                  break;
1130  
1131  
1132              default:
1133                  $info['error'][] = 'Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA), found "'.$RIFFsubtype.'" instead';
1134                  unset($info['fileformat']);
1135                  break;
1136          }
1137  
1138          switch ($RIFFsubtype) {
1139              case 'WAVE':
1140              case 'AIFF':
1141              case 'AIFC':
1142                  $ID3v2_key_good = 'id3 ';
1143                  $ID3v2_keys_bad = array('ID3 ', 'tag ');
1144                  foreach ($ID3v2_keys_bad as $ID3v2_key_bad) {
1145                      if (isset($thisfile_riff[$RIFFsubtype][$ID3v2_key_bad]) && !array_key_exists($ID3v2_key_good, $thisfile_riff[$RIFFsubtype])) {
1146                          $thisfile_riff[$RIFFsubtype][$ID3v2_key_good] = $thisfile_riff[$RIFFsubtype][$ID3v2_key_bad];
1147                          $info['warning'][] = 'mapping "'.$ID3v2_key_bad.'" chunk to "'.$ID3v2_key_good.'"';
1148                      }
1149                  }
1150  
1151                  if (isset($thisfile_riff[$RIFFsubtype]['id3 '])) {
1152                      getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
1153                      $getid3_temp = new getID3();
1154                      $getid3_temp->openfile($this->getid3->filename);
1155                      $getid3_id3v2 = new getid3_id3v2($getid3_temp);
1156                      $getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['id3 '][0]['offset'] + 8;
1157                      if ($thisfile_riff[$RIFFsubtype]['id3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
1158                          $info['id3v2'] = $getid3_temp->info['id3v2'];
1159                      }
1160                      unset($getid3_temp, $getid3_id3v2);
1161                  }
1162                  break;
1163          }
1164  
1165          if (isset($thisfile_riff_WAVE['DISP']) && is_array($thisfile_riff_WAVE['DISP'])) {
1166              $thisfile_riff['comments']['title'][] = trim(substr($thisfile_riff_WAVE['DISP'][count($thisfile_riff_WAVE['DISP']) - 1]['data'], 4));
1167          }
1168          if (isset($thisfile_riff_WAVE['INFO']) && is_array($thisfile_riff_WAVE['INFO'])) {
1169              self::parseComments($thisfile_riff_WAVE['INFO'], $thisfile_riff['comments']);
1170          }
1171          if (isset($thisfile_riff['AVI ']['INFO']) && is_array($thisfile_riff['AVI ']['INFO'])) {
1172              self::parseComments($thisfile_riff['AVI ']['INFO'], $thisfile_riff['comments']);
1173          }
1174  
1175          if (empty($thisfile_audio['encoder']) && !empty($info['mpeg']['audio']['LAME']['short_version'])) {
1176              $thisfile_audio['encoder'] = $info['mpeg']['audio']['LAME']['short_version'];
1177          }
1178  
1179          if (!isset($info['playtime_seconds'])) {
1180              $info['playtime_seconds'] = 0;
1181          }
1182          if (isset($thisfile_riff_raw['strh'][0]['dwLength']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) {
1183              // needed for >2GB AVIs where 'avih' chunk only lists number of frames in that chunk, not entire movie
1184              $info['playtime_seconds'] = $thisfile_riff_raw['strh'][0]['dwLength'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000);
1185          } elseif (isset($thisfile_riff_raw['avih']['dwTotalFrames']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) {
1186              $info['playtime_seconds'] = $thisfile_riff_raw['avih']['dwTotalFrames'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000);
1187          }
1188  
1189          if ($info['playtime_seconds'] > 0) {
1190              if (isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
1191  
1192                  if (!isset($info['bitrate'])) {
1193                      $info['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1194                  }
1195  
1196              } elseif (isset($thisfile_riff_audio) && !isset($thisfile_riff_video)) {
1197  
1198                  if (!isset($thisfile_audio['bitrate'])) {
1199                      $thisfile_audio['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1200                  }
1201  
1202              } elseif (!isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
1203  
1204                  if (!isset($thisfile_video['bitrate'])) {
1205                      $thisfile_video['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1206                  }
1207  
1208              }
1209          }
1210  
1211  
1212          if (isset($thisfile_riff_video) && isset($thisfile_audio['bitrate']) && ($thisfile_audio['bitrate'] > 0) && ($info['playtime_seconds'] > 0)) {
1213  
1214              $info['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1215              $thisfile_audio['bitrate'] = 0;
1216              $thisfile_video['bitrate'] = $info['bitrate'];
1217              foreach ($thisfile_riff_audio as $channelnumber => $audioinfoarray) {
1218                  $thisfile_video['bitrate'] -= $audioinfoarray['bitrate'];
1219                  $thisfile_audio['bitrate'] += $audioinfoarray['bitrate'];
1220              }
1221              if ($thisfile_video['bitrate'] <= 0) {
1222                  unset($thisfile_video['bitrate']);
1223              }
1224              if ($thisfile_audio['bitrate'] <= 0) {
1225                  unset($thisfile_audio['bitrate']);
1226              }
1227          }
1228  
1229          if (isset($info['mpeg']['audio'])) {
1230              $thisfile_audio_dataformat      = 'mp'.$info['mpeg']['audio']['layer'];
1231              $thisfile_audio['sample_rate']  = $info['mpeg']['audio']['sample_rate'];
1232              $thisfile_audio['channels']     = $info['mpeg']['audio']['channels'];
1233              $thisfile_audio['bitrate']      = $info['mpeg']['audio']['bitrate'];
1234              $thisfile_audio['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']);
1235              if (!empty($info['mpeg']['audio']['codec'])) {
1236                  $thisfile_audio['codec'] = $info['mpeg']['audio']['codec'].' '.$thisfile_audio['codec'];
1237              }
1238              if (!empty($thisfile_audio['streams'])) {
1239                  foreach ($thisfile_audio['streams'] as $streamnumber => $streamdata) {
1240                      if ($streamdata['dataformat'] == $thisfile_audio_dataformat) {
1241                          $thisfile_audio['streams'][$streamnumber]['sample_rate']  = $thisfile_audio['sample_rate'];
1242                          $thisfile_audio['streams'][$streamnumber]['channels']     = $thisfile_audio['channels'];
1243                          $thisfile_audio['streams'][$streamnumber]['bitrate']      = $thisfile_audio['bitrate'];
1244                          $thisfile_audio['streams'][$streamnumber]['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
1245                          $thisfile_audio['streams'][$streamnumber]['codec']        = $thisfile_audio['codec'];
1246                      }
1247                  }
1248              }
1249              $getid3_mp3 = new getid3_mp3($this->getid3);
1250              $thisfile_audio['encoder_options'] = $getid3_mp3->GuessEncoderOptions();
1251              unset($getid3_mp3);
1252          }
1253  
1254  
1255          if (!empty($thisfile_riff_raw['fmt ']['wBitsPerSample']) && ($thisfile_riff_raw['fmt ']['wBitsPerSample'] > 0)) {
1256              switch ($thisfile_audio_dataformat) {
1257                  case 'ac3':
1258                      // ignore bits_per_sample
1259                      break;
1260  
1261                  default:
1262                      $thisfile_audio['bits_per_sample'] = $thisfile_riff_raw['fmt ']['wBitsPerSample'];
1263                      break;
1264              }
1265          }
1266  
1267  
1268          if (empty($thisfile_riff_raw)) {
1269              unset($thisfile_riff['raw']);
1270          }
1271          if (empty($thisfile_riff_audio)) {
1272              unset($thisfile_riff['audio']);
1273          }
1274          if (empty($thisfile_riff_video)) {
1275              unset($thisfile_riff['video']);
1276          }
1277  
1278          return true;
1279      }
1280  
1281  	public function ParseRIFF($startoffset, $maxoffset) {
1282          $info = &$this->getid3->info;
1283  
1284          $RIFFchunk = false;
1285          $FoundAllChunksWeNeed = false;
1286  
1287          try {
1288              $this->fseek($startoffset);
1289              $maxoffset = min($maxoffset, $info['avdataend']);
1290              while ($this->ftell() < $maxoffset) {
1291                  $chunknamesize = $this->fread(8);
1292                  //$chunkname =                          substr($chunknamesize, 0, 4);
1293                  $chunkname = str_replace("\x00", '_', substr($chunknamesize, 0, 4));  // note: chunk names of 4 null bytes do appear to be legal (has been observed inside INFO and PRMI chunks, for example), but makes traversing array keys more difficult
1294                  $chunksize =  $this->EitherEndian2Int(substr($chunknamesize, 4, 4));
1295                  //if (strlen(trim($chunkname, "\x00")) < 4) {
1296                  if (strlen($chunkname) < 4) {
1297                      $this->error('Expecting chunk name at offset '.($this->ftell() - 8).' but found nothing. Aborting RIFF parsing.');
1298                      break;
1299                  }
1300                  if (($chunksize == 0) && ($chunkname != 'JUNK')) {
1301                      $this->warning('Chunk ('.$chunkname.') size at offset '.($this->ftell() - 4).' is zero. Aborting RIFF parsing.');
1302                      break;
1303                  }
1304                  if (($chunksize % 2) != 0) {
1305                      // all structures are packed on word boundaries
1306                      $chunksize++;
1307                  }
1308  
1309                  switch ($chunkname) {
1310                      case 'LIST':
1311                          $listname = $this->fread(4);
1312                          if (preg_match('#^(movi|rec )$#i', $listname)) {
1313                              $RIFFchunk[$listname]['offset'] = $this->ftell() - 4;
1314                              $RIFFchunk[$listname]['size']   = $chunksize;
1315  
1316                              if (!$FoundAllChunksWeNeed) {
1317                                  $WhereWeWere      = $this->ftell();
1318                                  $AudioChunkHeader = $this->fread(12);
1319                                  $AudioChunkStreamNum  =                              substr($AudioChunkHeader, 0, 2);
1320                                  $AudioChunkStreamType =                              substr($AudioChunkHeader, 2, 2);
1321                                  $AudioChunkSize       = getid3_lib::LittleEndian2Int(substr($AudioChunkHeader, 4, 4));
1322  
1323                                  if ($AudioChunkStreamType == 'wb') {
1324                                      $FirstFourBytes = substr($AudioChunkHeader, 8, 4);
1325                                      if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) {
1326                                          // MP3
1327                                          if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
1328                                              $getid3_temp = new getID3();
1329                                              $getid3_temp->openfile($this->getid3->filename);
1330                                              $getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
1331                                              $getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
1332                                              $getid3_mp3 = new getid3_mp3($getid3_temp);
1333                                              $getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false);
1334                                              if (isset($getid3_temp->info['mpeg']['audio'])) {
1335                                                  $info['mpeg']['audio']         = $getid3_temp->info['mpeg']['audio'];
1336                                                  $info['audio']                 = $getid3_temp->info['audio'];
1337                                                  $info['audio']['dataformat']   = 'mp'.$info['mpeg']['audio']['layer'];
1338                                                  $info['audio']['sample_rate']  = $info['mpeg']['audio']['sample_rate'];
1339                                                  $info['audio']['channels']     = $info['mpeg']['audio']['channels'];
1340                                                  $info['audio']['bitrate']      = $info['mpeg']['audio']['bitrate'];
1341                                                  $info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']);
1342                                                  //$info['bitrate']               = $info['audio']['bitrate'];
1343                                              }
1344                                              unset($getid3_temp, $getid3_mp3);
1345                                          }
1346  
1347                                      } elseif (strpos($FirstFourBytes, getid3_ac3::syncword) === 0) {
1348  
1349                                          // AC3
1350                                          $getid3_temp = new getID3();
1351                                          $getid3_temp->openfile($this->getid3->filename);
1352                                          $getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
1353                                          $getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
1354                                          $getid3_ac3 = new getid3_ac3($getid3_temp);
1355                                          $getid3_ac3->Analyze();
1356                                          if (empty($getid3_temp->info['error'])) {
1357                                              $info['audio']   = $getid3_temp->info['audio'];
1358                                              $info['ac3']     = $getid3_temp->info['ac3'];
1359                                              if (!empty($getid3_temp->info['warning'])) {
1360                                                  foreach ($getid3_temp->info['warning'] as $key => $value) {
1361                                                      $info['warning'][] = $value;
1362                                                  }
1363                                              }
1364                                          }
1365                                          unset($getid3_temp, $getid3_ac3);
1366                                      }
1367                                  }
1368                                  $FoundAllChunksWeNeed = true;
1369                                  $this->fseek($WhereWeWere);
1370                              }
1371                              $this->fseek($chunksize - 4, SEEK_CUR);
1372  
1373                          } else {
1374  
1375                              if (!isset($RIFFchunk[$listname])) {
1376                                  $RIFFchunk[$listname] = array();
1377                              }
1378                              $LISTchunkParent    = $listname;
1379                              $LISTchunkMaxOffset = $this->ftell() - 4 + $chunksize;
1380                              if ($parsedChunk = $this->ParseRIFF($this->ftell(), $LISTchunkMaxOffset)) {
1381                                  $RIFFchunk[$listname] = array_merge_recursive($RIFFchunk[$listname], $parsedChunk);
1382                              }
1383  
1384                          }
1385                          break;
1386  
1387                      default:
1388                          if (preg_match('#^[0-9]{2}(wb|pc|dc|db)$#', $chunkname)) {
1389                              $this->fseek($chunksize, SEEK_CUR);
1390                              break;
1391                          }
1392                          $thisindex = 0;
1393                          if (isset($RIFFchunk[$chunkname]) && is_array($RIFFchunk[$chunkname])) {
1394                              $thisindex = count($RIFFchunk[$chunkname]);
1395                          }
1396                          $RIFFchunk[$chunkname][$thisindex]['offset'] = $this->ftell() - 8;
1397                          $RIFFchunk[$chunkname][$thisindex]['size']   = $chunksize;
1398                          switch ($chunkname) {
1399                              case 'data':
1400                                  $info['avdataoffset'] = $this->ftell();
1401                                  $info['avdataend']    = $info['avdataoffset'] + $chunksize;
1402  
1403                                  $testData = $this->fread(36);
1404                                  if ($testData === '') {
1405                                      break;
1406                                  }
1407                                  if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($testData, 0, 4))) {
1408  
1409                                      // Probably is MP3 data
1410                                      if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($testData, 0, 4))) {
1411                                          $getid3_temp = new getID3();
1412                                          $getid3_temp->openfile($this->getid3->filename);
1413                                          $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
1414                                          $getid3_temp->info['avdataend']    = $info['avdataend'];
1415                                          $getid3_mp3 = new getid3_mp3($getid3_temp);
1416                                          $getid3_mp3->getOnlyMPEGaudioInfo($info['avdataoffset'], false);
1417                                          if (empty($getid3_temp->info['error'])) {
1418                                              $info['audio'] = $getid3_temp->info['audio'];
1419                                              $info['mpeg']  = $getid3_temp->info['mpeg'];
1420                                          }
1421                                          unset($getid3_temp, $getid3_mp3);
1422                                      }
1423  
1424                                  } elseif (($isRegularAC3 = (substr($testData, 0, 2) == getid3_ac3::syncword)) || substr($testData, 8, 2) == strrev(getid3_ac3::syncword)) {
1425  
1426                                      // This is probably AC-3 data
1427                                      $getid3_temp = new getID3();
1428                                      if ($isRegularAC3) {
1429                                          $getid3_temp->openfile($this->getid3->filename);
1430                                          $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
1431                                          $getid3_temp->info['avdataend']    = $info['avdataend'];
1432                                      }
1433                                      $getid3_ac3 = new getid3_ac3($getid3_temp);
1434                                      if ($isRegularAC3) {
1435                                          $getid3_ac3->Analyze();
1436                                      } else {
1437                                          // Dolby Digital WAV
1438                                          // AC-3 content, but not encoded in same format as normal AC-3 file
1439                                          // For one thing, byte order is swapped
1440                                          $ac3_data = '';
1441                                          for ($i = 0; $i < 28; $i += 2) {
1442                                              $ac3_data .= substr($testData, 8 + $i + 1, 1);
1443                                              $ac3_data .= substr($testData, 8 + $i + 0, 1);
1444                                          }
1445                                          $getid3_ac3->AnalyzeString($ac3_data);
1446                                      }
1447  
1448                                      if (empty($getid3_temp->info['error'])) {
1449                                          $info['audio'] = $getid3_temp->info['audio'];
1450                                          $info['ac3']   = $getid3_temp->info['ac3'];
1451                                          if (!empty($getid3_temp->info['warning'])) {
1452                                              foreach ($getid3_temp->info['warning'] as $newerror) {
1453                                                  $this->warning('getid3_ac3() says: ['.$newerror.']');
1454                                              }
1455                                          }
1456                                      }
1457                                      unset($getid3_temp, $getid3_ac3);
1458  
1459                                  } elseif (preg_match('/^('.implode('|', array_map('preg_quote', getid3_dts::$syncwords)).')/', $testData)) {
1460  
1461                                      // This is probably DTS data
1462                                      $getid3_temp = new getID3();
1463                                      $getid3_temp->openfile($this->getid3->filename);
1464                                      $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
1465                                      $getid3_dts = new getid3_dts($getid3_temp);
1466                                      $getid3_dts->Analyze();
1467                                      if (empty($getid3_temp->info['error'])) {
1468                                          $info['audio']            = $getid3_temp->info['audio'];
1469                                          $info['dts']              = $getid3_temp->info['dts'];
1470                                          $info['playtime_seconds'] = $getid3_temp->info['playtime_seconds']; // may not match RIFF calculations since DTS-WAV often used 14/16 bit-word packing
1471                                          if (!empty($getid3_temp->info['warning'])) {
1472                                              foreach ($getid3_temp->info['warning'] as $newerror) {
1473                                                  $this->warning('getid3_dts() says: ['.$newerror.']');
1474                                              }
1475                                          }
1476                                      }
1477  
1478                                      unset($getid3_temp, $getid3_dts);
1479  
1480                                  } elseif (substr($testData, 0, 4) == 'wvpk') {
1481  
1482                                      // This is WavPack data
1483                                      $info['wavpack']['offset'] = $info['avdataoffset'];
1484                                      $info['wavpack']['size']   = getid3_lib::LittleEndian2Int(substr($testData, 4, 4));
1485                                      $this->parseWavPackHeader(substr($testData, 8, 28));
1486  
1487                                  } else {
1488                                      // This is some other kind of data (quite possibly just PCM)
1489                                      // do nothing special, just skip it
1490                                  }
1491                                  $nextoffset = $info['avdataend'];
1492                                  $this->fseek($nextoffset);
1493                                  break;
1494  
1495                              case 'iXML':
1496                              case 'bext':
1497                              case 'cart':
1498                              case 'fmt ':
1499                              case 'strh':
1500                              case 'strf':
1501                              case 'indx':
1502                              case 'MEXT':
1503                              case 'DISP':
1504                                  // always read data in
1505                              case 'JUNK':
1506                                  // should be: never read data in
1507                                  // but some programs write their version strings in a JUNK chunk (e.g. VirtualDub, AVIdemux, etc)
1508                                  if ($chunksize < 1048576) {
1509                                      if ($chunksize > 0) {
1510                                          $RIFFchunk[$chunkname][$thisindex]['data'] = $this->fread($chunksize);
1511                                          if ($chunkname == 'JUNK') {
1512                                              if (preg_match('#^([\\x20-\\x7F]+)#', $RIFFchunk[$chunkname][$thisindex]['data'], $matches)) {
1513                                                  // only keep text characters [chr(32)-chr(127)]
1514                                                  $info['riff']['comments']['junk'][] = trim($matches[1]);
1515                                              }
1516                                              // but if nothing there, ignore
1517                                              // remove the key in either case
1518                                              unset($RIFFchunk[$chunkname][$thisindex]['data']);
1519                                          }
1520                                      }
1521                                  } else {
1522                                      $this->warning('Chunk "'.$chunkname.'" at offset '.$this->ftell().' is unexpectedly larger than 1MB (claims to be '.number_format($chunksize).' bytes), skipping data');
1523                                      $this->fseek($chunksize, SEEK_CUR);
1524                                  }
1525                                  break;
1526  
1527                              //case 'IDVX':
1528                              //    $info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunksize));
1529                              //    break;
1530  
1531                              default:
1532                                  if (!empty($LISTchunkParent) && (($RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size']) <= $LISTchunkMaxOffset)) {
1533                                      $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1534                                      $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['size']   = $RIFFchunk[$chunkname][$thisindex]['size'];
1535                                      unset($RIFFchunk[$chunkname][$thisindex]['offset']);
1536                                      unset($RIFFchunk[$chunkname][$thisindex]['size']);
1537                                      if (isset($RIFFchunk[$chunkname][$thisindex]) && empty($RIFFchunk[$chunkname][$thisindex])) {
1538                                          unset($RIFFchunk[$chunkname][$thisindex]);
1539                                      }
1540                                      if (isset($RIFFchunk[$chunkname]) && empty($RIFFchunk[$chunkname])) {
1541                                          unset($RIFFchunk[$chunkname]);
1542                                      }
1543                                      $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['data'] = $this->fread($chunksize);
1544                                  } elseif ($chunksize < 2048) {
1545                                      // only read data in if smaller than 2kB
1546                                      $RIFFchunk[$chunkname][$thisindex]['data'] = $this->fread($chunksize);
1547                                  } else {
1548                                      $this->fseek($chunksize, SEEK_CUR);
1549                                  }
1550                                  break;
1551                          }
1552                          break;
1553                  }
1554              }
1555  
1556          } catch (getid3_exception $e) {
1557              if ($e->getCode() == 10) {
1558                  $this->warning('RIFF parser: '.$e->getMessage());
1559              } else {
1560                  throw $e;
1561              }
1562          }
1563  
1564          return $RIFFchunk;
1565      }
1566  
1567  	public function ParseRIFFdata(&$RIFFdata) {
1568          $info = &$this->getid3->info;
1569          if ($RIFFdata) {
1570              $tempfile = tempnam(GETID3_TEMP_DIR, 'getID3');
1571              $fp_temp  = fopen($tempfile, 'wb');
1572              $RIFFdataLength = strlen($RIFFdata);
1573              $NewLengthString = getid3_lib::LittleEndian2String($RIFFdataLength, 4);
1574              for ($i = 0; $i < 4; $i++) {
1575                  $RIFFdata[($i + 4)] = $NewLengthString[$i];
1576              }
1577              fwrite($fp_temp, $RIFFdata);
1578              fclose($fp_temp);
1579  
1580              $getid3_temp = new getID3();
1581              $getid3_temp->openfile($tempfile);
1582              $getid3_temp->info['filesize']     = $RIFFdataLength;
1583              $getid3_temp->info['filenamepath'] = $info['filenamepath'];
1584              $getid3_temp->info['tags']         = $info['tags'];
1585              $getid3_temp->info['warning']      = $info['warning'];
1586              $getid3_temp->info['error']        = $info['error'];
1587              $getid3_temp->info['comments']     = $info['comments'];
1588              $getid3_temp->info['audio']        = (isset($info['audio']) ? $info['audio'] : array());
1589              $getid3_temp->info['video']        = (isset($info['video']) ? $info['video'] : array());
1590              $getid3_riff = new getid3_riff($getid3_temp);
1591              $getid3_riff->Analyze();
1592  
1593              $info['riff']     = $getid3_temp->info['riff'];
1594              $info['warning']  = $getid3_temp->info['warning'];
1595              $info['error']    = $getid3_temp->info['error'];
1596              $info['tags']     = $getid3_temp->info['tags'];
1597              $info['comments'] = $getid3_temp->info['comments'];
1598              unset($getid3_riff, $getid3_temp);
1599              unlink($tempfile);
1600          }
1601          return false;
1602      }
1603  
1604  	public static function parseComments(&$RIFFinfoArray, &$CommentsTargetArray) {
1605          $RIFFinfoKeyLookup = array(
1606              'IARL'=>'archivallocation',
1607              'IART'=>'artist',
1608              'ICDS'=>'costumedesigner',
1609              'ICMS'=>'commissionedby',
1610              'ICMT'=>'comment',
1611              'ICNT'=>'country',
1612              'ICOP'=>'copyright',
1613              'ICRD'=>'creationdate',
1614              'IDIM'=>'dimensions',
1615              'IDIT'=>'digitizationdate',
1616              'IDPI'=>'resolution',
1617              'IDST'=>'distributor',
1618              'IEDT'=>'editor',
1619              'IENG'=>'engineers',
1620              'IFRM'=>'accountofparts',
1621              'IGNR'=>'genre',
1622              'IKEY'=>'keywords',
1623              'ILGT'=>'lightness',
1624              'ILNG'=>'language',
1625              'IMED'=>'orignalmedium',
1626              'IMUS'=>'composer',
1627              'INAM'=>'title',
1628              'IPDS'=>'productiondesigner',
1629              'IPLT'=>'palette',
1630              'IPRD'=>'product',
1631              'IPRO'=>'producer',
1632              'IPRT'=>'part',
1633              'IRTD'=>'rating',
1634              'ISBJ'=>'subject',
1635              'ISFT'=>'software',
1636              'ISGN'=>'secondarygenre',
1637              'ISHP'=>'sharpness',
1638              'ISRC'=>'sourcesupplier',
1639              'ISRF'=>'digitizationsource',
1640              'ISTD'=>'productionstudio',
1641              'ISTR'=>'starring',
1642              'ITCH'=>'encoded_by',
1643              'IWEB'=>'url',
1644              'IWRI'=>'writer',
1645              '____'=>'comment',
1646          );
1647          foreach ($RIFFinfoKeyLookup as $key => $value) {
1648              if (isset($RIFFinfoArray[$key])) {
1649                  foreach ($RIFFinfoArray[$key] as $commentid => $commentdata) {
1650                      if (trim($commentdata['data']) != '') {
1651                          if (isset($CommentsTargetArray[$value])) {
1652                              $CommentsTargetArray[$value][] =     trim($commentdata['data']);
1653                          } else {
1654                              $CommentsTargetArray[$value] = array(trim($commentdata['data']));
1655                          }
1656                      }
1657                  }
1658              }
1659          }
1660          return true;
1661      }
1662  
1663  	public static function parseWAVEFORMATex($WaveFormatExData) {
1664          // shortcut
1665          $WaveFormatEx['raw'] = array();
1666          $WaveFormatEx_raw    = &$WaveFormatEx['raw'];
1667  
1668          $WaveFormatEx_raw['wFormatTag']      = substr($WaveFormatExData,  0, 2);
1669          $WaveFormatEx_raw['nChannels']       = substr($WaveFormatExData,  2, 2);
1670          $WaveFormatEx_raw['nSamplesPerSec']  = substr($WaveFormatExData,  4, 4);
1671          $WaveFormatEx_raw['nAvgBytesPerSec'] = substr($WaveFormatExData,  8, 4);
1672          $WaveFormatEx_raw['nBlockAlign']     = substr($WaveFormatExData, 12, 2);
1673          $WaveFormatEx_raw['wBitsPerSample']  = substr($WaveFormatExData, 14, 2);
1674          if (strlen($WaveFormatExData) > 16) {
1675              $WaveFormatEx_raw['cbSize']      = substr($WaveFormatExData, 16, 2);
1676          }
1677          $WaveFormatEx_raw = array_map('getid3_lib::LittleEndian2Int', $WaveFormatEx_raw);
1678  
1679          $WaveFormatEx['codec']           = self::wFormatTagLookup($WaveFormatEx_raw['wFormatTag']);
1680          $WaveFormatEx['channels']        = $WaveFormatEx_raw['nChannels'];
1681          $WaveFormatEx['sample_rate']     = $WaveFormatEx_raw['nSamplesPerSec'];
1682          $WaveFormatEx['bitrate']         = $WaveFormatEx_raw['nAvgBytesPerSec'] * 8;
1683          $WaveFormatEx['bits_per_sample'] = $WaveFormatEx_raw['wBitsPerSample'];
1684  
1685          return $WaveFormatEx;
1686      }
1687  
1688  	public function parseWavPackHeader($WavPackChunkData) {
1689          // typedef struct {
1690          //     char ckID [4];
1691          //     long ckSize;
1692          //     short version;
1693          //     short bits;                // added for version 2.00
1694          //     short flags, shift;        // added for version 3.00
1695          //     long total_samples, crc, crc2;
1696          //     char extension [4], extra_bc, extras [3];
1697          // } WavpackHeader;
1698  
1699          // shortcut
1700          $info = &$this->getid3->info;
1701          $info['wavpack']  = array();
1702          $thisfile_wavpack = &$info['wavpack'];
1703  
1704          $thisfile_wavpack['version']           = getid3_lib::LittleEndian2Int(substr($WavPackChunkData,  0, 2));
1705          if ($thisfile_wavpack['version'] >= 2) {
1706              $thisfile_wavpack['bits']          = getid3_lib::LittleEndian2Int(substr($WavPackChunkData,  2, 2));
1707          }
1708          if ($thisfile_wavpack['version'] >= 3) {
1709              $thisfile_wavpack['flags_raw']     = getid3_lib::LittleEndian2Int(substr($WavPackChunkData,  4, 2));
1710              $thisfile_wavpack['shift']         = getid3_lib::LittleEndian2Int(substr($WavPackChunkData,  6, 2));
1711              $thisfile_wavpack['total_samples'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData,  8, 4));
1712              $thisfile_wavpack['crc1']          = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 12, 4));
1713              $thisfile_wavpack['crc2']          = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 16, 4));
1714              $thisfile_wavpack['extension']     =                              substr($WavPackChunkData, 20, 4);
1715              $thisfile_wavpack['extra_bc']      = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 24, 1));
1716              for ($i = 0; $i <= 2; $i++) {
1717                  $thisfile_wavpack['extras'][]  = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 25 + $i, 1));
1718              }
1719  
1720              // shortcut
1721              $thisfile_wavpack['flags'] = array();
1722              $thisfile_wavpack_flags = &$thisfile_wavpack['flags'];
1723  
1724              $thisfile_wavpack_flags['mono']                 = (bool) ($thisfile_wavpack['flags_raw'] & 0x000001);
1725              $thisfile_wavpack_flags['fast_mode']            = (bool) ($thisfile_wavpack['flags_raw'] & 0x000002);
1726              $thisfile_wavpack_flags['raw_mode']             = (bool) ($thisfile_wavpack['flags_raw'] & 0x000004);
1727              $thisfile_wavpack_flags['calc_noise']           = (bool) ($thisfile_wavpack['flags_raw'] & 0x000008);
1728              $thisfile_wavpack_flags['high_quality']         = (bool) ($thisfile_wavpack['flags_raw'] & 0x000010);
1729              $thisfile_wavpack_flags['3_byte_samples']       = (bool) ($thisfile_wavpack['flags_raw'] & 0x000020);
1730              $thisfile_wavpack_flags['over_20_bits']         = (bool) ($thisfile_wavpack['flags_raw'] & 0x000040);
1731              $thisfile_wavpack_flags['use_wvc']              = (bool) ($thisfile_wavpack['flags_raw'] & 0x000080);
1732              $thisfile_wavpack_flags['noiseshaping']         = (bool) ($thisfile_wavpack['flags_raw'] & 0x000100);
1733              $thisfile_wavpack_flags['very_fast_mode']       = (bool) ($thisfile_wavpack['flags_raw'] & 0x000200);
1734              $thisfile_wavpack_flags['new_high_quality']     = (bool) ($thisfile_wavpack['flags_raw'] & 0x000400);
1735              $thisfile_wavpack_flags['cancel_extreme']       = (bool) ($thisfile_wavpack['flags_raw'] & 0x000800);
1736              $thisfile_wavpack_flags['cross_decorrelation']  = (bool) ($thisfile_wavpack['flags_raw'] & 0x001000);
1737              $thisfile_wavpack_flags['new_decorrelation']    = (bool) ($thisfile_wavpack['flags_raw'] & 0x002000);
1738              $thisfile_wavpack_flags['joint_stereo']         = (bool) ($thisfile_wavpack['flags_raw'] & 0x004000);
1739              $thisfile_wavpack_flags['extra_decorrelation']  = (bool) ($thisfile_wavpack['flags_raw'] & 0x008000);
1740              $thisfile_wavpack_flags['override_noiseshape']  = (bool) ($thisfile_wavpack['flags_raw'] & 0x010000);
1741              $thisfile_wavpack_flags['override_jointstereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x020000);
1742              $thisfile_wavpack_flags['copy_source_filetime'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x040000);
1743              $thisfile_wavpack_flags['create_exe']           = (bool) ($thisfile_wavpack['flags_raw'] & 0x080000);
1744          }
1745  
1746          return true;
1747      }
1748  
1749  	public static function ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true) {
1750  
1751          $parsed['biSize']          = substr($BITMAPINFOHEADER,  0, 4); // number of bytes required by the BITMAPINFOHEADER structure
1752          $parsed['biWidth']         = substr($BITMAPINFOHEADER,  4, 4); // width of the bitmap in pixels
1753          $parsed['biHeight']        = substr($BITMAPINFOHEADER,  8, 4); // height of the bitmap in pixels. If biHeight is positive, the bitmap is a 'bottom-up' DIB and its origin is the lower left corner. If biHeight is negative, the bitmap is a 'top-down' DIB and its origin is the upper left corner
1754          $parsed['biPlanes']        = substr($BITMAPINFOHEADER, 12, 2); // number of color planes on the target device. In most cases this value must be set to 1
1755          $parsed['biBitCount']      = substr($BITMAPINFOHEADER, 14, 2); // Specifies the number of bits per pixels
1756          $parsed['biSizeImage']     = substr($BITMAPINFOHEADER, 20, 4); // size of the bitmap data section of the image (the actual pixel data, excluding BITMAPINFOHEADER and RGBQUAD structures)
1757          $parsed['biXPelsPerMeter'] = substr($BITMAPINFOHEADER, 24, 4); // horizontal resolution, in pixels per metre, of the target device
1758          $parsed['biYPelsPerMeter'] = substr($BITMAPINFOHEADER, 28, 4); // vertical resolution, in pixels per metre, of the target device
1759          $parsed['biClrUsed']       = substr($BITMAPINFOHEADER, 32, 4); // actual number of color indices in the color table used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression
1760          $parsed['biClrImportant']  = substr($BITMAPINFOHEADER, 36, 4); // number of color indices that are considered important for displaying the bitmap. If this value is zero, all colors are important
1761          $parsed = array_map('getid3_lib::'.($littleEndian ? 'Little' : 'Big').'Endian2Int', $parsed);
1762  
1763          $parsed['fourcc']          = substr($BITMAPINFOHEADER, 16, 4);  // compression identifier
1764  
1765          return $parsed;
1766      }
1767  
1768  	public static function ParseDIVXTAG($DIVXTAG, $raw=false) {
1769          // structure from "IDivX" source, Form1.frm, by "Greg Frazier of Daemonic Software Group", email: gfrazier@icestorm.net, web: http://dsg.cjb.net/
1770          // source available at http://files.divx-digest.com/download/c663efe7ef8ad2e90bf4af4d3ea6188a/on0SWN2r/edit/IDivX.zip
1771          // 'Byte Layout:                   '1111111111111111
1772          // '32 for Movie - 1               '1111111111111111
1773          // '28 for Author - 6              '6666666666666666
1774          // '4  for year - 2                '6666666666662222
1775          // '3  for genre - 3               '7777777777777777
1776          // '48 for Comments - 7            '7777777777777777
1777          // '1  for Rating - 4              '7777777777777777
1778          // '5  for Future Additions - 0    '333400000DIVXTAG
1779          // '128 bytes total
1780  
1781          static $DIVXTAGgenre  = array(
1782               0 => 'Action',
1783               1 => 'Action/Adventure',
1784               2 => 'Adventure',
1785               3 => 'Adult',
1786               4 => 'Anime',
1787               5 => 'Cartoon',
1788               6 => 'Claymation',
1789               7 => 'Comedy',
1790               8 => 'Commercial',
1791               9 => 'Documentary',
1792              10 => 'Drama',
1793              11 => 'Home Video',
1794              12 => 'Horror',
1795              13 => 'Infomercial',
1796              14 => 'Interactive',
1797              15 => 'Mystery',
1798              16 => 'Music Video',
1799              17 => 'Other',
1800              18 => 'Religion',
1801              19 => 'Sci Fi',
1802              20 => 'Thriller',
1803              21 => 'Western',
1804          ),
1805          $DIVXTAGrating = array(
1806               0 => 'Unrated',
1807               1 => 'G',
1808               2 => 'PG',
1809               3 => 'PG-13',
1810               4 => 'R',
1811               5 => 'NC-17',
1812          );
1813  
1814          $parsed['title']     =        trim(substr($DIVXTAG,   0, 32));
1815          $parsed['artist']    =        trim(substr($DIVXTAG,  32, 28));
1816          $parsed['year']      = intval(trim(substr($DIVXTAG,  60,  4)));
1817          $parsed['comment']   =        trim(substr($DIVXTAG,  64, 48));
1818          $parsed['genre_id']  = intval(trim(substr($DIVXTAG, 112,  3)));
1819          $parsed['rating_id'] =         ord(substr($DIVXTAG, 115,  1));
1820          //$parsed['padding'] =             substr($DIVXTAG, 116,  5);  // 5-byte null
1821          //$parsed['magic']   =             substr($DIVXTAG, 121,  7);  // "DIVXTAG"
1822  
1823          $parsed['genre']  = (isset($DIVXTAGgenre[$parsed['genre_id']])   ? $DIVXTAGgenre[$parsed['genre_id']]   : $parsed['genre_id']);
1824          $parsed['rating'] = (isset($DIVXTAGrating[$parsed['rating_id']]) ? $DIVXTAGrating[$parsed['rating_id']] : $parsed['rating_id']);
1825  
1826          if (!$raw) {
1827              unset($parsed['genre_id'], $parsed['rating_id']);
1828              foreach ($parsed as $key => $value) {
1829                  if (!$value === '') {
1830                      unset($parsed['key']);
1831                  }
1832              }
1833          }
1834  
1835          foreach ($parsed as $tag => $value) {
1836              $parsed[$tag] = array($value);
1837          }
1838  
1839          return $parsed;
1840      }
1841  
1842  	public static function waveSNDMtagLookup($tagshortname) {
1843          $begin = __LINE__;
1844  
1845          /** This is not a comment!
1846  
1847              ©kwd    keywords
1848              ©BPM    bpm
1849              ©trt    tracktitle
1850              ©des    description
1851              ©gen    category
1852              ©fin    featuredinstrument
1853              ©LID    longid
1854              ©bex    bwdescription
1855              ©pub    publisher
1856              ©cdt    cdtitle
1857              ©alb    library
1858              ©com    composer
1859  
1860          */
1861  
1862          return getid3_lib::EmbeddedLookup($tagshortname, $begin, __LINE__, __FILE__, 'riff-sndm');
1863      }
1864  
1865  	public static function wFormatTagLookup($wFormatTag) {
1866  
1867          $begin = __LINE__;
1868  
1869          /** This is not a comment!
1870  
1871              0x0000    Microsoft Unknown Wave Format
1872              0x0001    Pulse Code Modulation (PCM)
1873              0x0002    Microsoft ADPCM
1874              0x0003    IEEE Float
1875              0x0004    Compaq Computer VSELP
1876              0x0005    IBM CVSD
1877              0x0006    Microsoft A-Law
1878              0x0007    Microsoft mu-Law
1879              0x0008    Microsoft DTS
1880              0x0010    OKI ADPCM
1881              0x0011    Intel DVI/IMA ADPCM
1882              0x0012    Videologic MediaSpace ADPCM
1883              0x0013    Sierra Semiconductor ADPCM
1884              0x0014    Antex Electronics G.723 ADPCM
1885              0x0015    DSP Solutions DigiSTD
1886              0x0016    DSP Solutions DigiFIX
1887              0x0017    Dialogic OKI ADPCM
1888              0x0018    MediaVision ADPCM
1889              0x0019    Hewlett-Packard CU
1890              0x0020    Yamaha ADPCM
1891              0x0021    Speech Compression Sonarc
1892              0x0022    DSP Group TrueSpeech
1893              0x0023    Echo Speech EchoSC1
1894              0x0024    Audiofile AF36
1895              0x0025    Audio Processing Technology APTX
1896              0x0026    AudioFile AF10
1897              0x0027    Prosody 1612
1898              0x0028    LRC
1899              0x0030    Dolby AC2
1900              0x0031    Microsoft GSM 6.10
1901              0x0032    MSNAudio
1902              0x0033    Antex Electronics ADPCME
1903              0x0034    Control Resources VQLPC
1904              0x0035    DSP Solutions DigiREAL
1905              0x0036    DSP Solutions DigiADPCM
1906              0x0037    Control Resources CR10
1907              0x0038    Natural MicroSystems VBXADPCM
1908              0x0039    Crystal Semiconductor IMA ADPCM
1909              0x003A    EchoSC3
1910              0x003B    Rockwell ADPCM
1911              0x003C    Rockwell Digit LK
1912              0x003D    Xebec
1913              0x0040    Antex Electronics G.721 ADPCM
1914              0x0041    G.728 CELP
1915              0x0042    MSG723
1916              0x0050    MPEG Layer-2 or Layer-1
1917              0x0052    RT24
1918              0x0053    PAC
1919              0x0055    MPEG Layer-3
1920              0x0059    Lucent G.723
1921              0x0060    Cirrus
1922              0x0061    ESPCM
1923              0x0062    Voxware
1924              0x0063    Canopus Atrac
1925              0x0064    G.726 ADPCM
1926              0x0065    G.722 ADPCM
1927              0x0066    DSAT
1928              0x0067    DSAT Display
1929              0x0069    Voxware Byte Aligned
1930              0x0070    Voxware AC8
1931              0x0071    Voxware AC10
1932              0x0072    Voxware AC16
1933              0x0073    Voxware AC20
1934              0x0074    Voxware MetaVoice
1935              0x0075    Voxware MetaSound
1936              0x0076    Voxware RT29HW
1937              0x0077    Voxware VR12
1938              0x0078    Voxware VR18
1939              0x0079    Voxware TQ40
1940              0x0080    Softsound
1941              0x0081    Voxware TQ60
1942              0x0082    MSRT24
1943              0x0083    G.729A
1944              0x0084    MVI MV12
1945              0x0085    DF G.726
1946              0x0086    DF GSM610
1947              0x0088    ISIAudio
1948              0x0089    Onlive
1949              0x0091    SBC24
1950              0x0092    Dolby AC3 SPDIF
1951              0x0093    MediaSonic G.723
1952              0x0094    Aculab PLC    Prosody 8kbps
1953              0x0097    ZyXEL ADPCM
1954              0x0098    Philips LPCBB
1955              0x0099    Packed
1956              0x00FF    AAC
1957              0x0100    Rhetorex ADPCM
1958              0x0101    IBM mu-law
1959              0x0102    IBM A-law
1960              0x0103    IBM AVC Adaptive Differential Pulse Code Modulation (ADPCM)
1961              0x0111    Vivo G.723
1962              0x0112    Vivo Siren
1963              0x0123    Digital G.723
1964              0x0125    Sanyo LD ADPCM
1965              0x0130    Sipro Lab Telecom ACELP NET
1966              0x0131    Sipro Lab Telecom ACELP 4800
1967              0x0132    Sipro Lab Telecom ACELP 8V3
1968              0x0133    Sipro Lab Telecom G.729
1969              0x0134    Sipro Lab Telecom G.729A
1970              0x0135    Sipro Lab Telecom Kelvin
1971              0x0140    Windows Media Video V8
1972              0x0150    Qualcomm PureVoice
1973              0x0151    Qualcomm HalfRate
1974              0x0155    Ring Zero Systems TUB GSM
1975              0x0160    Microsoft Audio 1
1976              0x0161    Windows Media Audio V7 / V8 / V9
1977              0x0162    Windows Media Audio Professional V9
1978              0x0163    Windows Media Audio Lossless V9
1979              0x0200    Creative Labs ADPCM
1980              0x0202    Creative Labs Fastspeech8
1981              0x0203    Creative Labs Fastspeech10
1982              0x0210    UHER Informatic GmbH ADPCM
1983              0x0220    Quarterdeck
1984              0x0230    I-link Worldwide VC
1985              0x0240    Aureal RAW Sport
1986              0x0250    Interactive Products HSX
1987              0x0251    Interactive Products RPELP
1988              0x0260    Consistent Software CS2
1989              0x0270    Sony SCX
1990              0x0300    Fujitsu FM Towns Snd
1991              0x0400    BTV Digital
1992              0x0401    Intel Music Coder
1993              0x0450    QDesign Music
1994              0x0680    VME VMPCM
1995              0x0681    AT&T Labs TPC
1996              0x08AE    ClearJump LiteWave
1997              0x1000    Olivetti GSM
1998              0x1001    Olivetti ADPCM
1999              0x1002    Olivetti CELP
2000              0x1003    Olivetti SBC
2001              0x1004    Olivetti OPR
2002              0x1100    Lernout & Hauspie Codec (0x1100)
2003              0x1101    Lernout & Hauspie CELP Codec (0x1101)
2004              0x1102    Lernout & Hauspie SBC Codec (0x1102)
2005              0x1103    Lernout & Hauspie SBC Codec (0x1103)
2006              0x1104    Lernout & Hauspie SBC Codec (0x1104)
2007              0x1400    Norris
2008              0x1401    AT&T ISIAudio
2009              0x1500    Soundspace Music Compression
2010              0x181C    VoxWare RT24 Speech
2011              0x1FC4    NCT Soft ALF2CD (www.nctsoft.com)
2012              0x2000    Dolby AC3
2013              0x2001    Dolby DTS
2014              0x2002    WAVE_FORMAT_14_4
2015              0x2003    WAVE_FORMAT_28_8
2016              0x2004    WAVE_FORMAT_COOK
2017              0x2005    WAVE_FORMAT_DNET
2018              0x674F    Ogg Vorbis 1
2019              0x6750    Ogg Vorbis 2
2020              0x6751    Ogg Vorbis 3
2021              0x676F    Ogg Vorbis 1+
2022              0x6770    Ogg Vorbis 2+
2023              0x6771    Ogg Vorbis 3+
2024              0x7A21    GSM-AMR (CBR, no SID)
2025              0x7A22    GSM-AMR (VBR, including SID)
2026              0xFFFE    WAVE_FORMAT_EXTENSIBLE
2027              0xFFFF    WAVE_FORMAT_DEVELOPMENT
2028  
2029          */
2030  
2031          return getid3_lib::EmbeddedLookup('0x'.str_pad(strtoupper(dechex($wFormatTag)), 4, '0', STR_PAD_LEFT), $begin, __LINE__, __FILE__, 'riff-wFormatTag');
2032      }
2033  
2034  	public static function fourccLookup($fourcc) {
2035  
2036          $begin = __LINE__;
2037  
2038          /** This is not a comment!
2039  
2040              swot    http://developer.apple.com/qa/snd/snd07.html
2041              ____    No Codec (____)
2042              _BIT    BI_BITFIELDS (Raw RGB)
2043              _JPG    JPEG compressed
2044              _PNG    PNG compressed W3C/ISO/IEC (RFC-2083)
2045              _RAW    Full Frames (Uncompressed)
2046              _RGB    Raw RGB Bitmap
2047              _RL4    RLE 4bpp RGB
2048              _RL8    RLE 8bpp RGB
2049              3IV1    3ivx MPEG-4 v1
2050              3IV2    3ivx MPEG-4 v2
2051              3IVX    3ivx MPEG-4
2052              AASC    Autodesk Animator
2053              ABYR    Kensington ?ABYR?
2054              AEMI    Array Microsystems VideoONE MPEG1-I Capture
2055              AFLC    Autodesk Animator FLC
2056              AFLI    Autodesk Animator FLI
2057              AMPG    Array Microsystems VideoONE MPEG
2058              ANIM    Intel RDX (ANIM)
2059              AP41    AngelPotion Definitive
2060              ASV1    Asus Video v1
2061              ASV2    Asus Video v2
2062              ASVX    Asus Video 2.0 (audio)
2063              AUR2    AuraVision Aura 2 Codec - YUV 4:2:2
2064              AURA    AuraVision Aura 1 Codec - YUV 4:1:1
2065              AVDJ    Independent JPEG Group\'s codec (AVDJ)
2066              AVRN    Independent JPEG Group\'s codec (AVRN)
2067              AYUV    4:4:4 YUV (AYUV)
2068              AZPR    Quicktime Apple Video (AZPR)
2069              BGR     Raw RGB32
2070              BLZ0    Blizzard DivX MPEG-4
2071              BTVC    Conexant Composite Video
2072              BINK    RAD Game Tools Bink Video
2073              BT20    Conexant Prosumer Video
2074              BTCV    Conexant Composite Video Codec
2075              BW10    Data Translation Broadway MPEG Capture
2076              CC12    Intel YUV12
2077              CDVC    Canopus DV
2078              CFCC    Digital Processing Systems DPS Perception
2079              CGDI    Microsoft Office 97 Camcorder Video
2080              CHAM    Winnov Caviara Champagne
2081              CJPG    Creative WebCam JPEG
2082              CLJR    Cirrus Logic YUV 4:1:1
2083              CMYK    Common Data Format in Printing (Colorgraph)
2084              CPLA    Weitek 4:2:0 YUV Planar
2085              CRAM    Microsoft Video 1 (CRAM)
2086              cvid    Radius Cinepak
2087              CVID    Radius Cinepak
2088              CWLT    Microsoft Color WLT DIB
2089              CYUV    Creative Labs YUV
2090              CYUY    ATI YUV
2091              D261    H.261
2092              D263    H.263
2093              DIB     Device Independent Bitmap
2094              DIV1    FFmpeg OpenDivX
2095              DIV2    Microsoft MPEG-4 v1/v2
2096              DIV3    DivX ;-) MPEG-4 v3.x Low-Motion
2097              DIV4    DivX ;-) MPEG-4 v3.x Fast-Motion
2098              DIV5    DivX MPEG-4 v5.x
2099              DIV6    DivX ;-) (MS MPEG-4 v3.x)
2100              DIVX    DivX MPEG-4 v4 (OpenDivX / Project Mayo)
2101              divx    DivX MPEG-4
2102              DMB1    Matrox Rainbow Runner hardware MJPEG
2103              DMB2    Paradigm MJPEG
2104              DSVD    ?DSVD?
2105              DUCK    Duck TrueMotion 1.0
2106              DPS0    DPS/Leitch Reality Motion JPEG
2107              DPSC    DPS/Leitch PAR Motion JPEG
2108              DV25    Matrox DVCPRO codec
2109              DV50    Matrox DVCPRO50 codec
2110              DVC     IEC 61834 and SMPTE 314M (DVC/DV Video)
2111              DVCP    IEC 61834 and SMPTE 314M (DVC/DV Video)
2112              DVHD    IEC Standard DV 1125 lines @ 30fps / 1250 lines @ 25fps
2113              DVMA    Darim Vision DVMPEG (dummy for MPEG compressor) (www.darvision.com)
2114              DVSL    IEC Standard DV compressed in SD (SDL)
2115              DVAN    ?DVAN?
2116              DVE2    InSoft DVE-2 Videoconferencing
2117              dvsd    IEC 61834 and SMPTE 314M DVC/DV Video
2118              DVSD    IEC 61834 and SMPTE 314M DVC/DV Video
2119              DVX1    Lucent DVX1000SP Video Decoder
2120              DVX2    Lucent DVX2000S Video Decoder
2121              DVX3    Lucent DVX3000S Video Decoder
2122              DX50    DivX v5
2123              DXT1    Microsoft DirectX Compressed Texture (DXT1)
2124              DXT2    Microsoft DirectX Compressed Texture (DXT2)
2125              DXT3    Microsoft DirectX Compressed Texture (DXT3)
2126              DXT4    Microsoft DirectX Compressed Texture (DXT4)
2127              DXT5    Microsoft DirectX Compressed Texture (DXT5)
2128              DXTC    Microsoft DirectX Compressed Texture (DXTC)
2129              DXTn    Microsoft DirectX Compressed Texture (DXTn)
2130              EM2V    Etymonix MPEG-2 I-frame (www.etymonix.com)
2131              EKQ0    Elsa ?EKQ0?
2132              ELK0    Elsa ?ELK0?
2133              ESCP    Eidos Escape
2134              ETV1    eTreppid Video ETV1
2135              ETV2    eTreppid Video ETV2
2136              ETVC    eTreppid Video ETVC
2137              FLIC    Autodesk FLI/FLC Animation
2138              FLV1    Sorenson Spark
2139              FLV4    On2 TrueMotion VP6
2140              FRWT    Darim Vision Forward Motion JPEG (www.darvision.com)
2141              FRWU    Darim Vision Forward Uncompressed (www.darvision.com)
2142              FLJP    D-Vision Field Encoded Motion JPEG
2143              FPS1    FRAPS v1
2144              FRWA    SoftLab-Nsk Forward Motion JPEG w/ alpha channel
2145              FRWD    SoftLab-Nsk Forward Motion JPEG
2146              FVF1    Iterated Systems Fractal Video Frame
2147              GLZW    Motion LZW (gabest@freemail.hu)
2148              GPEG    Motion JPEG (gabest@freemail.hu)
2149              GWLT    Microsoft Greyscale WLT DIB
2150              H260    Intel ITU H.260 Videoconferencing
2151              H261    Intel ITU H.261 Videoconferencing
2152              H262    Intel ITU H.262 Videoconferencing
2153              H263    Intel ITU H.263 Videoconferencing
2154              H264    Intel ITU H.264 Videoconferencing
2155              H265    Intel ITU H.265 Videoconferencing
2156              H266    Intel ITU H.266 Videoconferencing
2157              H267    Intel ITU H.267 Videoconferencing
2158              H268    Intel ITU H.268 Videoconferencing
2159              H269    Intel ITU H.269 Videoconferencing
2160              HFYU    Huffman Lossless Codec
2161              HMCR    Rendition Motion Compensation Format (HMCR)
2162              HMRR    Rendition Motion Compensation Format (HMRR)
2163              I263    FFmpeg I263 decoder
2164              IF09    Indeo YVU9 ("YVU9 with additional delta-frame info after the U plane")
2165              IUYV    Interlaced version of UYVY (www.leadtools.com)
2166              IY41    Interlaced version of Y41P (www.leadtools.com)
2167              IYU1    12 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec    IEEE standard
2168              IYU2    24 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec    IEEE standard
2169              IYUV    Planar YUV format (8-bpp Y plane, followed by 8-bpp 2×2 U and V planes)
2170              i263    Intel ITU H.263 Videoconferencing (i263)
2171              I420    Intel Indeo 4
2172              IAN     Intel Indeo 4 (RDX)
2173              ICLB    InSoft CellB Videoconferencing
2174              IGOR    Power DVD
2175              IJPG    Intergraph JPEG
2176              ILVC    Intel Layered Video
2177              ILVR    ITU-T H.263+
2178              IPDV    I-O Data Device Giga AVI DV Codec
2179              IR21    Intel Indeo 2.1
2180              IRAW    Intel YUV Uncompressed
2181              IV30    Intel Indeo 3.0
2182              IV31    Intel Indeo 3.1
2183              IV32    Ligos Indeo 3.2
2184              IV33    Ligos Indeo 3.3
2185              IV34    Ligos Indeo 3.4
2186              IV35    Ligos Indeo 3.5
2187              IV36    Ligos Indeo 3.6
2188              IV37    Ligos Indeo 3.7
2189              IV38    Ligos Indeo 3.8
2190              IV39    Ligos Indeo 3.9
2191              IV40    Ligos Indeo Interactive 4.0
2192              IV41    Ligos Indeo Interactive 4.1
2193              IV42    Ligos Indeo Interactive 4.2
2194              IV43    Ligos Indeo Interactive 4.3
2195              IV44    Ligos Indeo Interactive 4.4
2196              IV45    Ligos Indeo Interactive 4.5
2197              IV46    Ligos Indeo Interactive 4.6
2198              IV47    Ligos Indeo Interactive 4.7
2199              IV48    Ligos Indeo Interactive 4.8
2200              IV49    Ligos Indeo Interactive 4.9
2201              IV50    Ligos Indeo Interactive 5.0
2202              JBYR    Kensington ?JBYR?
2203              JPEG    Still Image JPEG DIB
2204              JPGL    Pegasus Lossless Motion JPEG
2205              KMVC    Team17 Software Karl Morton\'s Video Codec
2206              LSVM    Vianet Lighting Strike Vmail (Streaming) (www.vianet.com)
2207              LEAD    LEAD Video Codec
2208              Ljpg    LEAD MJPEG Codec
2209              MDVD    Alex MicroDVD Video (hacked MS MPEG-4) (www.tiasoft.de)
2210              MJPA    Morgan Motion JPEG (MJPA) (www.morgan-multimedia.com)
2211              MJPB    Morgan Motion JPEG (MJPB) (www.morgan-multimedia.com)
2212              MMES    Matrox MPEG-2 I-frame
2213              MP2v    Microsoft S-Mpeg 4 version 1 (MP2v)
2214              MP42    Microsoft S-Mpeg 4 version 2 (MP42)
2215              MP43    Microsoft S-Mpeg 4 version 3 (MP43)
2216              MP4S    Microsoft S-Mpeg 4 version 3 (MP4S)
2217              MP4V    FFmpeg MPEG-4
2218              MPG1    FFmpeg MPEG 1/2
2219              MPG2    FFmpeg MPEG 1/2
2220              MPG3    FFmpeg DivX ;-) (MS MPEG-4 v3)
2221              MPG4    Microsoft MPEG-4
2222              MPGI    Sigma Designs MPEG
2223              MPNG    PNG images decoder
2224              MSS1    Microsoft Windows Screen Video
2225              MSZH    LCL (Lossless Codec Library) (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm)
2226              M261    Microsoft H.261
2227              M263    Microsoft H.263
2228              M4S2    Microsoft Fully Compliant MPEG-4 v2 simple profile (M4S2)
2229              m4s2    Microsoft Fully Compliant MPEG-4 v2 simple profile (m4s2)
2230              MC12    ATI Motion Compensation Format (MC12)
2231              MCAM    ATI Motion Compensation Format (MCAM)
2232              MJ2C    Morgan Multimedia Motion JPEG2000
2233              mJPG    IBM Motion JPEG w/ Huffman Tables
2234              MJPG    Microsoft Motion JPEG DIB
2235              MP42    Microsoft MPEG-4 (low-motion)
2236              MP43    Microsoft MPEG-4 (fast-motion)
2237              MP4S    Microsoft MPEG-4 (MP4S)
2238              mp4s    Microsoft MPEG-4 (mp4s)
2239              MPEG    Chromatic Research MPEG-1 Video I-Frame
2240              MPG4    Microsoft MPEG-4 Video High Speed Compressor
2241              MPGI    Sigma Designs MPEG
2242              MRCA    FAST Multimedia Martin Regen Codec
2243              MRLE    Microsoft Run Length Encoding
2244              MSVC    Microsoft Video 1
2245              MTX1    Matrox ?MTX1?
2246              MTX2    Matrox ?MTX2?
2247              MTX3    Matrox ?MTX3?
2248              MTX4    Matrox ?MTX4?
2249              MTX5    Matrox ?MTX5?
2250              MTX6    Matrox ?MTX6?
2251              MTX7    Matrox ?MTX7?
2252              MTX8    Matrox ?MTX8?
2253              MTX9    Matrox ?MTX9?
2254              MV12    Motion Pixels Codec (old)
2255              MWV1    Aware Motion Wavelets
2256              nAVI    SMR Codec (hack of Microsoft MPEG-4) (IRC #shadowrealm)
2257              NT00    NewTek LightWave HDTV YUV w/ Alpha (www.newtek.com)
2258              NUV1    NuppelVideo
2259              NTN1    Nogatech Video Compression 1
2260              NVS0    nVidia GeForce Texture (NVS0)
2261              NVS1    nVidia GeForce Texture (NVS1)
2262              NVS2    nVidia GeForce Texture (NVS2)
2263              NVS3    nVidia GeForce Texture (NVS3)
2264              NVS4    nVidia GeForce Texture (NVS4)
2265              NVS5    nVidia GeForce Texture (NVS5)
2266              NVT0    nVidia GeForce Texture (NVT0)
2267              NVT1    nVidia GeForce Texture (NVT1)
2268              NVT2    nVidia GeForce Texture (NVT2)
2269              NVT3    nVidia GeForce Texture (NVT3)
2270              NVT4    nVidia GeForce Texture (NVT4)
2271              NVT5    nVidia GeForce Texture (NVT5)
2272              PIXL    MiroXL, Pinnacle PCTV
2273              PDVC    I-O Data Device Digital Video Capture DV codec
2274              PGVV    Radius Video Vision
2275              PHMO    IBM Photomotion
2276              PIM1    MPEG Realtime (Pinnacle Cards)
2277              PIM2    Pegasus Imaging ?PIM2?
2278              PIMJ    Pegasus Imaging Lossless JPEG
2279              PVEZ    Horizons Technology PowerEZ
2280              PVMM    PacketVideo Corporation MPEG-4
2281              PVW2    Pegasus Imaging Wavelet Compression
2282              Q1.0    Q-Team\'s QPEG 1.0 (www.q-team.de)
2283              Q1.1    Q-Team\'s QPEG 1.1 (www.q-team.de)
2284              QPEG    Q-Team QPEG 1.0
2285              qpeq    Q-Team QPEG 1.1
2286              RGB     Raw BGR32
2287              RGBA    Raw RGB w/ Alpha
2288              RMP4    REALmagic MPEG-4 (unauthorized XVID copy) (www.sigmadesigns.com)
2289              ROQV    Id RoQ File Video Decoder
2290              RPZA    Quicktime Apple Video (RPZA)
2291              RUD0    Rududu video codec (http://rududu.ifrance.com/rududu/)
2292              RV10    RealVideo 1.0 (aka RealVideo 5.0)
2293              RV13    RealVideo 1.0 (RV13)
2294              RV20    RealVideo G2
2295              RV30    RealVideo 8
2296              RV40    RealVideo 9
2297              RGBT    Raw RGB w/ Transparency
2298              RLE     Microsoft Run Length Encoder
2299              RLE4    Run Length Encoded (4bpp, 16-color)
2300              RLE8    Run Length Encoded (8bpp, 256-color)
2301              RT21    Intel Indeo RealTime Video 2.1
2302              rv20    RealVideo G2
2303              rv30    RealVideo 8
2304              RVX     Intel RDX (RVX )
2305              SMC     Apple Graphics (SMC )
2306              SP54    Logitech Sunplus Sp54 Codec for Mustek GSmart Mini 2
2307              SPIG    Radius Spigot
2308              SVQ3    Sorenson Video 3 (Apple Quicktime 5)
2309              s422    Tekram VideoCap C210 YUV 4:2:2
2310              SDCC    Sun Communication Digital Camera Codec
2311              SFMC    CrystalNet Surface Fitting Method
2312              SMSC    Radius SMSC
2313              SMSD    Radius SMSD
2314              smsv    WorldConnect Wavelet Video
2315              SPIG    Radius Spigot
2316              SPLC    Splash Studios ACM Audio Codec (www.splashstudios.net)
2317              SQZ2    Microsoft VXTreme Video Codec V2
2318              STVA    ST Microelectronics CMOS Imager Data (Bayer)
2319              STVB    ST Microelectronics CMOS Imager Data (Nudged Bayer)
2320              STVC    ST Microelectronics CMOS Imager Data (Bunched)
2321              STVX    ST Microelectronics CMOS Imager Data (Extended CODEC Data Format)
2322              STVY    ST Microelectronics CMOS Imager Data (Extended CODEC Data Format with Correction Data)
2323              SV10    Sorenson Video R1
2324              SVQ1    Sorenson Video
2325              T420    Toshiba YUV 4:2:0
2326              TM2A    Duck TrueMotion Archiver 2.0 (www.duck.com)
2327              TVJP    Pinnacle/Truevision Targa 2000 board (TVJP)
2328              TVMJ    Pinnacle/Truevision Targa 2000 board (TVMJ)
2329              TY0N    Tecomac Low-Bit Rate Codec (www.tecomac.com)
2330              TY2C    Trident Decompression Driver
2331              TLMS    TeraLogic Motion Intraframe Codec (TLMS)
2332              TLST    TeraLogic Motion Intraframe Codec (TLST)
2333              TM20    Duck TrueMotion 2.0
2334              TM2X    Duck TrueMotion 2X
2335              TMIC    TeraLogic Motion Intraframe Codec (TMIC)
2336              TMOT    Horizons Technology TrueMotion S
2337              tmot    Horizons TrueMotion Video Compression
2338              TR20    Duck TrueMotion RealTime 2.0
2339              TSCC    TechSmith Screen Capture Codec
2340              TV10    Tecomac Low-Bit Rate Codec
2341              TY2N    Trident ?TY2N?
2342              U263    UB Video H.263/H.263+/H.263++ Decoder
2343              UMP4    UB Video MPEG 4 (www.ubvideo.com)
2344              UYNV    Nvidia UYVY packed 4:2:2
2345              UYVP    Evans & Sutherland YCbCr 4:2:2 extended precision
2346              UCOD    eMajix.com ClearVideo
2347              ULTI    IBM Ultimotion
2348              UYVY    UYVY packed 4:2:2
2349              V261    Lucent VX2000S
2350              VIFP    VFAPI Reader Codec (www.yks.ne.jp/~hori/)
2351              VIV1    FFmpeg H263+ decoder
2352              VIV2    Vivo H.263
2353              VQC2    Vector-quantised codec 2 (research) http://eprints.ecs.soton.ac.uk/archive/00001310/01/VTC97-js.pdf)
2354              VTLP    Alaris VideoGramPiX
2355              VYU9    ATI YUV (VYU9)
2356              VYUY    ATI YUV (VYUY)
2357              V261    Lucent VX2000S
2358              V422    Vitec Multimedia 24-bit YUV 4:2:2 Format
2359              V655    Vitec Multimedia 16-bit YUV 4:2:2 Format
2360              VCR1    ATI Video Codec 1
2361              VCR2    ATI Video Codec 2
2362              VCR3    ATI VCR 3.0
2363              VCR4    ATI VCR 4.0
2364              VCR5    ATI VCR 5.0
2365              VCR6    ATI VCR 6.0
2366              VCR7    ATI VCR 7.0
2367              VCR8    ATI VCR 8.0
2368              VCR9    ATI VCR 9.0
2369              VDCT    Vitec Multimedia Video Maker Pro DIB
2370              VDOM    VDOnet VDOWave
2371              VDOW    VDOnet VDOLive (H.263)
2372              VDTZ    Darim Vison VideoTizer YUV
2373              VGPX    Alaris VideoGramPiX
2374              VIDS    Vitec Multimedia YUV 4:2:2 CCIR 601 for V422
2375              VIVO    Vivo H.263 v2.00
2376              vivo    Vivo H.263
2377              VIXL    Miro/Pinnacle Video XL
2378              VLV1    VideoLogic/PURE Digital Videologic Capture
2379              VP30    On2 VP3.0
2380              VP31    On2 VP3.1
2381              VP6F    On2 TrueMotion VP6
2382              VX1K    Lucent VX1000S Video Codec
2383              VX2K    Lucent VX2000S Video Codec
2384              VXSP    Lucent VX1000SP Video Codec
2385              WBVC    Winbond W9960
2386              WHAM    Microsoft Video 1 (WHAM)
2387              WINX    Winnov Software Compression
2388              WJPG    AverMedia Winbond JPEG
2389              WMV1    Windows Media Video V7
2390              WMV2    Windows Media Video V8
2391              WMV3    Windows Media Video V9
2392              WNV1    Winnov Hardware Compression
2393              XYZP    Extended PAL format XYZ palette (www.riff.org)
2394              x263    Xirlink H.263
2395              XLV0    NetXL Video Decoder
2396              XMPG    Xing MPEG (I-Frame only)
2397              XVID    XviD MPEG-4 (www.xvid.org)
2398              XXAN    ?XXAN?
2399              YU92    Intel YUV (YU92)
2400              YUNV    Nvidia Uncompressed YUV 4:2:2
2401              YUVP    Extended PAL format YUV palette (www.riff.org)
2402              Y211    YUV 2:1:1 Packed
2403              Y411    YUV 4:1:1 Packed
2404              Y41B    Weitek YUV 4:1:1 Planar
2405              Y41P    Brooktree PC1 YUV 4:1:1 Packed
2406              Y41T    Brooktree PC1 YUV 4:1:1 with transparency
2407              Y42B    Weitek YUV 4:2:2 Planar
2408              Y42T    Brooktree UYUV 4:2:2 with transparency
2409              Y422    ADS Technologies Copy of UYVY used in Pyro WebCam firewire camera
2410              Y800    Simple, single Y plane for monochrome images
2411              Y8      Grayscale video
2412              YC12    Intel YUV 12 codec
2413              YUV8    Winnov Caviar YUV8
2414              YUV9    Intel YUV9
2415              YUY2    Uncompressed YUV 4:2:2
2416              YUYV    Canopus YUV
2417              YV12    YVU12 Planar
2418              YVU9    Intel YVU9 Planar (8-bpp Y plane, followed by 8-bpp 4x4 U and V planes)
2419              YVYU    YVYU 4:2:2 Packed
2420              ZLIB    Lossless Codec Library zlib compression (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm)
2421              ZPEG    Metheus Video Zipper
2422  
2423          */
2424  
2425          return getid3_lib::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc');
2426      }
2427  
2428  	private function EitherEndian2Int($byteword, $signed=false) {
2429          if ($this->getid3->info['fileformat'] == 'riff') {
2430              return getid3_lib::LittleEndian2Int($byteword, $signed);
2431          }
2432          return getid3_lib::BigEndian2Int($byteword, false, $signed);
2433      }
2434  
2435  }


Generated: Tue Mar 25 01:41:18 2014 WordPress honlapkészítés: online1.hu