[ PHPXref.com ] [ Generated: Sun Jul 20 17:58:47 2008 ] [ getID3() 1.7.6 ]
[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/getid3/ -> module.audio-video.quicktime.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.quicktime.php                            //
  11  // module for analyzing Quicktime and MP3-in-MP4 files         //
  12  // dependencies: module.audio.mp3.php                          //
  13  //                                                            ///
  14  /////////////////////////////////////////////////////////////////
  15  
  16  getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true);
  17  
  18  class getid3_quicktime
  19  {
  20  
  21  	function getid3_quicktime(&$fd, &$ThisFileInfo, $ReturnAtomData=true, $ParseAllPossibleAtoms=false) {
  22  
  23          $ThisFileInfo['fileformat'] = 'quicktime';
  24          $ThisFileInfo['quicktime']['hinting'] = false;
  25  
  26          fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
  27  
  28          $offset      = 0;
  29          $atomcounter = 0;
  30  
  31          while ($offset < $ThisFileInfo['avdataend']) {
  32              fseek($fd, $offset, SEEK_SET);
  33              $AtomHeader = fread($fd, 8);
  34  
  35              $atomsize = getid3_lib::BigEndian2Int(substr($AtomHeader, 0, 4));
  36              $atomname =               substr($AtomHeader, 4, 4);
  37              $ThisFileInfo['quicktime'][$atomname]['name']   = $atomname;
  38              $ThisFileInfo['quicktime'][$atomname]['size']   = $atomsize;
  39              $ThisFileInfo['quicktime'][$atomname]['offset'] = $offset;
  40  
  41              if (($offset + $atomsize) > $ThisFileInfo['avdataend']) {
  42                  $ThisFileInfo['error'][] = 'Atom at offset '.$offset.' claims to go beyond end-of-file (length: '.$atomsize.' bytes)';
  43                  return false;
  44              }
  45  
  46              if ($atomsize == 0) {
  47                  // Furthermore, for historical reasons the list of atoms is optionally
  48                  // terminated by a 32-bit integer set to 0. If you are writing a program
  49                  // to read user data atoms, you should allow for the terminating 0.
  50                  break;
  51              }
  52              switch ($atomname) {
  53                  case 'mdat': // Media DATa atom
  54                      // 'mdat' contains the actual data for the audio/video
  55                      if (($atomsize > 8) && (!isset($ThisFileInfo['avdataend_tmp']) || ($ThisFileInfo['quicktime'][$atomname]['size'] > ($ThisFileInfo['avdataend_tmp'] - $ThisFileInfo['avdataoffset'])))) {
  56  
  57                          $ThisFileInfo['avdataoffset'] = $ThisFileInfo['quicktime'][$atomname]['offset'] + 8;
  58                          $OldAVDataEnd                 = $ThisFileInfo['avdataend'];
  59                          $ThisFileInfo['avdataend']    = $ThisFileInfo['quicktime'][$atomname]['offset'] + $ThisFileInfo['quicktime'][$atomname]['size'];
  60  
  61                          if (getid3_mp3::MPEGaudioHeaderValid(getid3_mp3::MPEGaudioHeaderDecode(fread($fd, 4)))) {
  62                              getid3_mp3::getOnlyMPEGaudioInfo($fd, $ThisFileInfo, $ThisFileInfo['avdataoffset'], false);
  63                              if (isset($ThisFileInfo['mpeg']['audio'])) {
  64                                  $ThisFileInfo['audio']['dataformat']   = 'mp3';
  65                                  $ThisFileInfo['audio']['codec']        = (!empty($ThisFileInfo['mpeg']['audio']['encoder']) ? $ThisFileInfo['mpeg']['audio']['encoder'] : (!empty($ThisFileInfo['mpeg']['audio']['codec']) ? $ThisFileInfo['mpeg']['audio']['codec'] : (!empty($ThisFileInfo['mpeg']['audio']['LAME']) ? 'LAME' :'mp3')));
  66                                  $ThisFileInfo['audio']['sample_rate']  = $ThisFileInfo['mpeg']['audio']['sample_rate'];
  67                                  $ThisFileInfo['audio']['channels']     = $ThisFileInfo['mpeg']['audio']['channels'];
  68                                  $ThisFileInfo['audio']['bitrate']      = $ThisFileInfo['mpeg']['audio']['bitrate'];
  69                                  $ThisFileInfo['audio']['bitrate_mode'] = strtolower($ThisFileInfo['mpeg']['audio']['bitrate_mode']);
  70                                  $ThisFileInfo['bitrate']               = $ThisFileInfo['audio']['bitrate'];
  71                              }
  72                          }
  73                          $ThisFileInfo['avdataend'] = $OldAVDataEnd;
  74                          unset($OldAVDataEnd);
  75  
  76                      }
  77                      break;
  78  
  79                  case 'free': // FREE space atom
  80                  case 'skip': // SKIP atom
  81                  case 'wide': // 64-bit expansion placeholder atom
  82                      // 'free', 'skip' and 'wide' are just padding, contains no useful data at all
  83                      break;
  84  
  85                  default:
  86                      $atomHierarchy = array();
  87                      $ThisFileInfo['quicktime'][$atomname] = $this->QuicktimeParseAtom($atomname, $atomsize, fread($fd, $atomsize), $ThisFileInfo, $offset, $atomHierarchy, $ParseAllPossibleAtoms);
  88                      break;
  89              }
  90  
  91              $offset += $atomsize;
  92              $atomcounter++;
  93          }
  94  
  95          if (!empty($ThisFileInfo['avdataend_tmp'])) {
  96              // this value is assigned to a temp value and then erased because
  97              // otherwise any atoms beyond the 'mdat' atom would not get parsed
  98              $ThisFileInfo['avdataend'] = $ThisFileInfo['avdataend_tmp'];
  99              unset($ThisFileInfo['avdataend_tmp']);
 100          }
 101  
 102          if (!isset($ThisFileInfo['bitrate']) && isset($ThisFileInfo['playtime_seconds'])) {
 103              $ThisFileInfo['bitrate'] = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $ThisFileInfo['playtime_seconds'];
 104          }
 105          if (isset($ThisFileInfo['bitrate']) && !isset($ThisFileInfo['audio']['bitrate']) && !isset($ThisFileInfo['quicktime']['video'])) {
 106              $ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['bitrate'];
 107          }
 108  
 109          if (($ThisFileInfo['audio']['dataformat'] == 'mp4') && empty($ThisFileInfo['video']['resolution_x'])) {
 110              $ThisFileInfo['fileformat'] = 'mp4';
 111              $ThisFileInfo['mime_type']  = 'audio/mp4';
 112              unset($ThisFileInfo['video']['dataformat']);
 113          }
 114  
 115          if (!$ReturnAtomData) {
 116              unset($ThisFileInfo['quicktime']['moov']);
 117          }
 118  
 119          if (empty($ThisFileInfo['audio']['dataformat']) && !empty($ThisFileInfo['quicktime']['audio'])) {
 120              $ThisFileInfo['audio']['dataformat'] = 'quicktime';
 121          }
 122          if (empty($ThisFileInfo['video']['dataformat']) && !empty($ThisFileInfo['quicktime']['video'])) {
 123              $ThisFileInfo['video']['dataformat'] = 'quicktime';
 124          }
 125  
 126          return true;
 127      }
 128  
 129  	function QuicktimeParseAtom($atomname, $atomsize, $atomdata, &$ThisFileInfo, $baseoffset, &$atomHierarchy, $ParseAllPossibleAtoms) {
 130          // http://developer.apple.com/techpubs/quicktime/qtdevdocs/APIREF/INDEX/atomalphaindex.htm
 131  
 132          array_push($atomHierarchy, $atomname);
 133          $atomstructure['hierarchy'] = implode(' ', $atomHierarchy);
 134          $atomstructure['name']      = $atomname;
 135          $atomstructure['size']      = $atomsize;
 136          $atomstructure['offset']    = $baseoffset;
 137  
 138          switch ($atomname) {
 139              case 'moov': // MOVie container atom
 140              case 'trak': // TRAcK container atom
 141              case 'clip': // CLIPping container atom
 142              case 'matt': // track MATTe container atom
 143              case 'edts': // EDiTS container atom
 144              case 'tref': // Track REFerence container atom
 145              case 'mdia': // MeDIA container atom
 146              case 'minf': // Media INFormation container atom
 147              case 'dinf': // Data INFormation container atom
 148              case 'udta': // User DaTA container atom
 149              case 'stbl': // Sample TaBLe container atom
 150              case 'cmov': // Compressed MOVie container atom
 151              case 'rmra': // Reference Movie Record Atom
 152              case 'rmda': // Reference Movie Descriptor Atom
 153              case 'gmhd': // Generic Media info HeaDer atom (seen on QTVR)
 154                  $atomstructure['subatoms'] = $this->QuicktimeParseContainerAtom($atomdata, $ThisFileInfo, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
 155                  break;
 156  
 157  
 158              case '妾py':
 159              case '妻ay':
 160              case '妻ir':
 161              case '委d1':
 162              case '委d2':
 163              case '委d3':
 164              case '委d4':
 165              case '委d5':
 166              case '委d6':
 167              case '委d7':
 168              case '委d8':
 169              case '委d9':
 170              case '妹mt':
 171              case '姆nf':
 172              case '妳rd':
 173              case '妳rf':
 174              case '姅eq':
 175              case '孟rc':
 176              case '定rt':
 177              case '姊am':
 178              case '妾mt':
 179              case '定rn':
 180              case '姑st':
 181              case '姓ak':
 182              case '姓od':
 183              case '周RD':
 184              case '孟wr':
 185              case '奄ut':
 186              case '呸RT':
 187              case '孤rk':
 188              case '奄lb':
 189              case '妾om':
 190              case '妮en':
 191              case '妯pe':
 192              case '季rl':
 193              case '委nc':
 194                  $atomstructure['data_length'] = getid3_lib::BigEndian2Int(substr($atomdata,  0, 2));
 195                  $atomstructure['language_id'] = getid3_lib::BigEndian2Int(substr($atomdata,  2, 2));
 196                  $atomstructure['data']        =                           substr($atomdata,  4);
 197  
 198                  $atomstructure['language']    = $this->QuicktimeLanguageLookup($atomstructure['language_id']);
 199                  if (empty($ThisFileInfo['comments']['language']) || (!in_array($atomstructure['language'], $ThisFileInfo['comments']['language']))) {
 200                      $ThisFileInfo['comments']['language'][] = $atomstructure['language'];
 201                  }
 202                  $this->CopyToAppropriateCommentsSection($atomname, $atomstructure['data'], $ThisFileInfo);
 203                  break;
 204  
 205  
 206              case 'play': // auto-PLAY atom
 207                  $atomstructure['autoplay']             = (bool) getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 208  
 209                  $ThisFileInfo['quicktime']['autoplay'] = $atomstructure['autoplay'];
 210                  break;
 211  
 212  
 213              case 'WLOC': // Window LOCation atom
 214                  $atomstructure['location_x']  = getid3_lib::BigEndian2Int(substr($atomdata,  0, 2));
 215                  $atomstructure['location_y']  = getid3_lib::BigEndian2Int(substr($atomdata,  2, 2));
 216                  break;
 217  
 218  
 219              case 'LOOP': // LOOPing atom
 220              case 'SelO': // play SELection Only atom
 221              case 'AllF': // play ALL Frames atom
 222                  $atomstructure['data'] = getid3_lib::BigEndian2Int($atomdata);
 223                  break;
 224  
 225  
 226              case 'name': //
 227              case 'MCPS': // Media Cleaner PRo
 228              case '@PRM': // adobe PReMiere version
 229              case '@PRQ': // adobe PRemiere Quicktime version
 230                  $atomstructure['data'] = $atomdata;
 231                  break;
 232  
 233  
 234              case 'cmvd': // Compressed MooV Data atom
 235                  // Code by ubergeek啽bergeek*tv based on information from
 236                  // http://developer.apple.com/quicktime/icefloe/dispatch012.html
 237                  $atomstructure['unCompressedSize'] = getid3_lib::BigEndian2Int(substr($atomdata, 0, 4));
 238  
 239                  $CompressedFileData = substr($atomdata, 4);
 240                  if ($UncompressedHeader = @gzuncompress($CompressedFileData)) {
 241                      $atomstructure['subatoms'] = $this->QuicktimeParseContainerAtom($UncompressedHeader, $ThisFileInfo, 0, $atomHierarchy, $ParseAllPossibleAtoms);
 242                  } else {
 243                      $ThisFileInfo['warning'][] = 'Error decompressing compressed MOV atom at offset '.$atomstructure['offset'];
 244                  }
 245                  break;
 246  
 247  
 248              case 'dcom': // Data COMpression atom
 249                  $atomstructure['compression_id']   = $atomdata;
 250                  $atomstructure['compression_text'] = $this->QuicktimeDCOMLookup($atomdata);
 251                  break;
 252  
 253  
 254              case 'rdrf': // Reference movie Data ReFerence atom
 255                  $atomstructure['version']                = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 256                  $atomstructure['flags_raw']              = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3));
 257                  $atomstructure['flags']['internal_data'] = (bool) ($atomstructure['flags_raw'] & 0x000001);
 258  
 259                  $atomstructure['reference_type_name']    =                           substr($atomdata,  4, 4);
 260                  $atomstructure['reference_length']       = getid3_lib::BigEndian2Int(substr($atomdata,  8, 4));
 261                  switch ($atomstructure['reference_type_name']) {
 262                      case 'url ':
 263                          $atomstructure['url']            =       $this->NoNullString(substr($atomdata, 12));
 264                          break;
 265  
 266                      case 'alis':
 267                          $atomstructure['file_alias']     =                           substr($atomdata, 12);
 268                          break;
 269  
 270                      case 'rsrc':
 271                          $atomstructure['resource_alias'] =                           substr($atomdata, 12);
 272                          break;
 273  
 274                      default:
 275                          $atomstructure['data']           =                           substr($atomdata, 12);
 276                          break;
 277                  }
 278                  break;
 279  
 280  
 281              case 'rmqu': // Reference Movie QUality atom
 282                  $atomstructure['movie_quality'] = getid3_lib::BigEndian2Int($atomdata);
 283                  break;
 284  
 285  
 286              case 'rmcs': // Reference Movie Cpu Speed atom
 287                  $atomstructure['version']          = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 288                  $atomstructure['flags_raw']        = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 289                  $atomstructure['cpu_speed_rating'] = getid3_lib::BigEndian2Int(substr($atomdata,  4, 2));
 290                  break;
 291  
 292  
 293              case 'rmvc': // Reference Movie Version Check atom
 294                  $atomstructure['version']            = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 295                  $atomstructure['flags_raw']          = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 296                  $atomstructure['gestalt_selector']   =                           substr($atomdata,  4, 4);
 297                  $atomstructure['gestalt_value_mask'] = getid3_lib::BigEndian2Int(substr($atomdata,  8, 4));
 298                  $atomstructure['gestalt_value']      = getid3_lib::BigEndian2Int(substr($atomdata, 12, 4));
 299                  $atomstructure['gestalt_check_type'] = getid3_lib::BigEndian2Int(substr($atomdata, 14, 2));
 300                  break;
 301  
 302  
 303              case 'rmcd': // Reference Movie Component check atom
 304                  $atomstructure['version']                = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 305                  $atomstructure['flags_raw']              = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 306                  $atomstructure['component_type']         =                           substr($atomdata,  4, 4);
 307                  $atomstructure['component_subtype']      =                           substr($atomdata,  8, 4);
 308                  $atomstructure['component_manufacturer'] =                           substr($atomdata, 12, 4);
 309                  $atomstructure['component_flags_raw']    = getid3_lib::BigEndian2Int(substr($atomdata, 16, 4));
 310                  $atomstructure['component_flags_mask']   = getid3_lib::BigEndian2Int(substr($atomdata, 20, 4));
 311                  $atomstructure['component_min_version']  = getid3_lib::BigEndian2Int(substr($atomdata, 24, 4));
 312                  break;
 313  
 314  
 315              case 'rmdr': // Reference Movie Data Rate atom
 316                  $atomstructure['version']       = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 317                  $atomstructure['flags_raw']     = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 318                  $atomstructure['data_rate']     = getid3_lib::BigEndian2Int(substr($atomdata,  4, 4));
 319  
 320                  $atomstructure['data_rate_bps'] = $atomstructure['data_rate'] * 10;
 321                  break;
 322  
 323  
 324              case 'rmla': // Reference Movie Language Atom
 325                  $atomstructure['version']     = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 326                  $atomstructure['flags_raw']   = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 327                  $atomstructure['language_id'] = getid3_lib::BigEndian2Int(substr($atomdata,  4, 2));
 328  
 329                  $atomstructure['language']    = $this->QuicktimeLanguageLookup($atomstructure['language_id']);
 330                  if (empty($ThisFileInfo['comments']['language']) || (!in_array($atomstructure['language'], $ThisFileInfo['comments']['language']))) {
 331                      $ThisFileInfo['comments']['language'][] = $atomstructure['language'];
 332                  }
 333                  break;
 334  
 335  
 336              case 'rmla': // Reference Movie Language Atom
 337                  $atomstructure['version']   = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 338                  $atomstructure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 339                  $atomstructure['track_id']  = getid3_lib::BigEndian2Int(substr($atomdata,  4, 2));
 340                  break;
 341  
 342  
 343              case 'ptv ': // Print To Video - defines a movie's full screen mode
 344                  // http://developer.apple.com/documentation/QuickTime/APIREF/SOURCESIV/at_ptv-_pg.htm
 345                  $atomstructure['display_size_raw']  = getid3_lib::BigEndian2Int(substr($atomdata, 0, 2));
 346                  $atomstructure['reserved_1']        = getid3_lib::BigEndian2Int(substr($atomdata, 2, 2)); // hardcoded: 0x0000
 347                  $atomstructure['reserved_2']        = getid3_lib::BigEndian2Int(substr($atomdata, 4, 2)); // hardcoded: 0x0000
 348                  $atomstructure['slide_show_flag']   = getid3_lib::BigEndian2Int(substr($atomdata, 6, 1));
 349                  $atomstructure['play_on_open_flag'] = getid3_lib::BigEndian2Int(substr($atomdata, 7, 1));
 350  
 351                  $atomstructure['flags']['play_on_open'] = (bool) $atomstructure['play_on_open_flag'];
 352                  $atomstructure['flags']['slide_show']   = (bool) $atomstructure['slide_show_flag'];
 353  
 354                  $ptv_lookup[0] = 'normal';
 355                  $ptv_lookup[1] = 'double';
 356                  $ptv_lookup[2] = 'half';
 357                  $ptv_lookup[3] = 'full';
 358                  $ptv_lookup[4] = 'current';
 359                  if (isset($ptv_lookup[$atomstructure['display_size_raw']])) {
 360                      $atomstructure['display_size'] = $ptv_lookup[$atomstructure['display_size_raw']];
 361                  } else {
 362                      $ThisFileInfo['warning'][] = 'unknown "ptv " display constant ('.$atomstructure['display_size_raw'].')';
 363                  }
 364                  break;
 365  
 366  
 367              case 'stsd': // Sample Table Sample Description atom
 368                  $atomstructure['version']        = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 369                  $atomstructure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 370                  $atomstructure['number_entries'] = getid3_lib::BigEndian2Int(substr($atomdata,  4, 4));
 371                  $stsdEntriesDataOffset = 8;
 372                  for ($i = 0; $i < $atomstructure['number_entries']; $i++) {
 373                      $atomstructure['sample_description_table'][$i]['size']             = getid3_lib::BigEndian2Int(substr($atomdata, $stsdEntriesDataOffset, 4));
 374                      $stsdEntriesDataOffset += 4;
 375                      $atomstructure['sample_description_table'][$i]['data_format']      =                           substr($atomdata, $stsdEntriesDataOffset, 4);
 376                      $stsdEntriesDataOffset += 4;
 377                      $atomstructure['sample_description_table'][$i]['reserved']         = getid3_lib::BigEndian2Int(substr($atomdata, $stsdEntriesDataOffset, 6));
 378                      $stsdEntriesDataOffset += 6;
 379                      $atomstructure['sample_description_table'][$i]['reference_index']  = getid3_lib::BigEndian2Int(substr($atomdata, $stsdEntriesDataOffset, 2));
 380                      $stsdEntriesDataOffset += 2;
 381                      $atomstructure['sample_description_table'][$i]['data']             =                           substr($atomdata, $stsdEntriesDataOffset, ($atomstructure['sample_description_table'][$i]['size'] - 4 - 4 - 6 - 2));
 382                      $stsdEntriesDataOffset += ($atomstructure['sample_description_table'][$i]['size'] - 4 - 4 - 6 - 2);
 383  
 384                      $atomstructure['sample_description_table'][$i]['encoder_version']  = getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'],  0, 2));
 385                      $atomstructure['sample_description_table'][$i]['encoder_revision'] = getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'],  2, 2));
 386                      $atomstructure['sample_description_table'][$i]['encoder_vendor']   =                           substr($atomstructure['sample_description_table'][$i]['data'],  4, 4);
 387  
 388                      switch ($atomstructure['sample_description_table'][$i]['encoder_vendor']) {
 389  
 390                          case "\x00\x00\x00\x00":
 391                              // audio atom
 392                              $atomstructure['sample_description_table'][$i]['audio_channels']       =   getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'],  8,  2));
 393                              $atomstructure['sample_description_table'][$i]['audio_bit_depth']      =   getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'], 10,  2));
 394                              $atomstructure['sample_description_table'][$i]['audio_compression_id'] =   getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'], 12,  2));
 395                              $atomstructure['sample_description_table'][$i]['audio_packet_size']    =   getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'], 14,  2));
 396                              $atomstructure['sample_description_table'][$i]['audio_sample_rate']    = getid3_lib::FixedPoint16_16(substr($atomstructure['sample_description_table'][$i]['data'], 16,  4));
 397  
 398                              switch ($atomstructure['sample_description_table'][$i]['data_format']) {
 399                                  case 'mp4v':
 400                                      $ThisFileInfo['fileformat'] = 'mp4';
 401                                      $ThisFileInfo['error'][] = 'This version ('.GETID3_VERSION.') of getID3() does not fully support MPEG-4 audio/video streams';
 402                                      break;
 403  
 404                                  case 'qtvr':
 405                                      $ThisFileInfo['video']['dataformat'] = 'quicktimevr';
 406                                      break;
 407  
 408                                  case 'mp4a':
 409                                  default:
 410                                      $ThisFileInfo['quicktime']['audio']['codec']       = $this->QuicktimeAudioCodecLookup($atomstructure['sample_description_table'][$i]['data_format']);
 411                                      $ThisFileInfo['quicktime']['audio']['sample_rate'] = $atomstructure['sample_description_table'][$i]['audio_sample_rate'];
 412                                      $ThisFileInfo['quicktime']['audio']['channels']    = $atomstructure['sample_description_table'][$i]['audio_channels'];
 413                                      $ThisFileInfo['quicktime']['audio']['bit_depth']   = $atomstructure['sample_description_table'][$i]['audio_bit_depth'];
 414                                      $ThisFileInfo['audio']['codec']                    = $ThisFileInfo['quicktime']['audio']['codec'];
 415                                      $ThisFileInfo['audio']['sample_rate']              = $ThisFileInfo['quicktime']['audio']['sample_rate'];
 416                                      $ThisFileInfo['audio']['channels']                 = $ThisFileInfo['quicktime']['audio']['channels'];
 417                                      $ThisFileInfo['audio']['bits_per_sample']          = $ThisFileInfo['quicktime']['audio']['bit_depth'];
 418                                      switch ($atomstructure['sample_description_table'][$i]['data_format']) {
 419                                          case 'raw ': // PCM
 420                                          case 'alac': // Apple Lossless Audio Codec
 421                                              $ThisFileInfo['audio']['lossless'] = true;
 422                                              break;
 423                                          default:
 424                                              $ThisFileInfo['audio']['lossless'] = false;
 425                                              break;
 426                                      }
 427                                      break;
 428                              }
 429                              break;
 430  
 431                          default:
 432                              switch ($atomstructure['sample_description_table'][$i]['data_format']) {
 433                                  case 'mp4s':
 434                                      $ThisFileInfo['fileformat'] = 'mp4';
 435                                      break;
 436  
 437                                  default:
 438                                      // video atom
 439                                      $atomstructure['sample_description_table'][$i]['video_temporal_quality']  =   getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'],  8,  4));
 440                                      $atomstructure['sample_description_table'][$i]['video_spatial_quality']   =   getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'], 12,  4));
 441                                      $atomstructure['sample_description_table'][$i]['video_frame_width']       =   getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'], 16,  2));
 442                                      $atomstructure['sample_description_table'][$i]['video_frame_height']      =   getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'], 18,  2));
 443                                      $atomstructure['sample_description_table'][$i]['video_resolution_x']      = getid3_lib::FixedPoint16_16(substr($atomstructure['sample_description_table'][$i]['data'], 20,  4));
 444                                      $atomstructure['sample_description_table'][$i]['video_resolution_y']      = getid3_lib::FixedPoint16_16(substr($atomstructure['sample_description_table'][$i]['data'], 24,  4));
 445                                      $atomstructure['sample_description_table'][$i]['video_data_size']         =   getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'], 28,  4));
 446                                      $atomstructure['sample_description_table'][$i]['video_frame_count']       =   getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'], 32,  2));
 447                                      $atomstructure['sample_description_table'][$i]['video_encoder_name_len']  =   getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'], 34,  1));
 448                                      $atomstructure['sample_description_table'][$i]['video_encoder_name']      =                             substr($atomstructure['sample_description_table'][$i]['data'], 35, $atomstructure['sample_description_table'][$i]['video_encoder_name_len']);
 449                                      $atomstructure['sample_description_table'][$i]['video_pixel_color_depth'] =   getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'], 66,  2));
 450                                      $atomstructure['sample_description_table'][$i]['video_color_table_id']    =   getid3_lib::BigEndian2Int(substr($atomstructure['sample_description_table'][$i]['data'], 68,  2));
 451  
 452                                      $atomstructure['sample_description_table'][$i]['video_pixel_color_type']  = (($atomstructure['sample_description_table'][$i]['video_pixel_color_depth'] > 32) ? 'grayscale' : 'color');
 453                                      $atomstructure['sample_description_table'][$i]['video_pixel_color_name']  = $this->QuicktimeColorNameLookup($atomstructure['sample_description_table'][$i]['video_pixel_color_depth']);
 454  
 455                                      if ($atomstructure['sample_description_table'][$i]['video_pixel_color_name'] != 'invalid') {
 456                                          $ThisFileInfo['quicktime']['video']['codec_fourcc']        = $atomstructure['sample_description_table'][$i]['data_format'];
 457                                          $ThisFileInfo['quicktime']['video']['codec_fourcc_lookup'] = $this->QuicktimeVideoCodecLookup($atomstructure['sample_description_table'][$i]['data_format']);
 458                                          $ThisFileInfo['quicktime']['video']['codec']               = $atomstructure['sample_description_table'][$i]['video_encoder_name'];
 459                                          $ThisFileInfo['quicktime']['video']['color_depth']         = $atomstructure['sample_description_table'][$i]['video_pixel_color_depth'];
 460                                          $ThisFileInfo['quicktime']['video']['color_depth_name']    = $atomstructure['sample_description_table'][$i]['video_pixel_color_name'];
 461  
 462                                          $ThisFileInfo['video']['codec']           = $ThisFileInfo['quicktime']['video']['codec'];
 463                                          $ThisFileInfo['video']['bits_per_sample'] = $ThisFileInfo['quicktime']['video']['color_depth'];
 464                                      }
 465                                      $ThisFileInfo['video']['lossless']           = false;
 466                                      $ThisFileInfo['video']['pixel_aspect_ratio'] = (float) 1;
 467                                      break;
 468                              }
 469                              break;
 470                      }
 471                      switch (strtolower($atomstructure['sample_description_table'][$i]['data_format'])) {
 472                          case 'mp4a':
 473                              $ThisFileInfo['audio']['dataformat']         = 'mp4';
 474                              $ThisFileInfo['quicktime']['audio']['codec'] = 'mp4';
 475                              break;
 476  
 477                          case '3ivx':
 478                          case '3iv1':
 479                          case '3iv2':
 480                              $ThisFileInfo['video']['dataformat'] = '3ivx';
 481                              break;
 482  
 483                          case 'xvid':
 484                              $ThisFileInfo['video']['dataformat'] = 'xvid';
 485                              break;
 486  
 487                          case 'mp4v':
 488                              $ThisFileInfo['video']['dataformat'] = 'mpeg4';
 489                              break;
 490  
 491                          case 'divx':
 492                          case 'div1':
 493                          case 'div2':
 494                          case 'div3':
 495                          case 'div4':
 496                          case 'div5':
 497                          case 'div6':
 498                              $TDIVXileInfo['video']['dataformat'] = 'divx';
 499                              break;
 500  
 501                          default:
 502                              // do nothing
 503                              break;
 504                      }
 505                      unset($atomstructure['sample_description_table'][$i]['data']);
 506                  }
 507                  break;
 508  
 509  
 510              case 'stts': // Sample Table Time-to-Sample atom
 511                  //if ($ParseAllPossibleAtoms) {
 512                      $atomstructure['version']        = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 513                      $atomstructure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 514                      $atomstructure['number_entries'] = getid3_lib::BigEndian2Int(substr($atomdata,  4, 4));
 515                      $sttsEntriesDataOffset = 8;
 516                      $FrameRateCalculatorArray = array();
 517                      for ($i = 0; $i < $atomstructure['number_entries']; $i++) {
 518                          $atomstructure['time_to_sample_table'][$i]['sample_count']    = getid3_lib::BigEndian2Int(substr($atomdata, $sttsEntriesDataOffset, 4));
 519                          $sttsEntriesDataOffset += 4;
 520                          $atomstructure['time_to_sample_table'][$i]['sample_duration'] = getid3_lib::BigEndian2Int(substr($atomdata, $sttsEntriesDataOffset, 4));
 521                          $sttsEntriesDataOffset += 4;
 522  
 523                          if (!empty($ThisFileInfo['quicktime']['time_scale'])) {
 524                              $stts_new_framerate = $ThisFileInfo['quicktime']['time_scale'] / $atomstructure['time_to_sample_table'][$i]['sample_duration'];
 525                              if ($stts_new_framerate <= 60) {
 526                                  // some atoms have durations of "1" giving a very large framerate, which probably is not right
 527                                  $ThisFileInfo['video']['frame_rate'] = max(@$ThisFileInfo['video']['frame_rate'], $stts_new_framerate);
 528                              }
 529                          }
 530                          //@$FrameRateCalculatorArray[($ThisFileInfo['quicktime']['time_scale'] / $atomstructure['time_to_sample_table'][$i]['sample_duration'])] += $atomstructure['time_to_sample_table'][$i]['sample_count'];
 531                      }
 532                      //$sttsFramesTotal  = 0;
 533                      //$sttsSecondsTotal = 0;
 534                      //foreach ($FrameRateCalculatorArray as $frames_per_second => $frame_count) {
 535                      //    if (($frames_per_second > 60) || ($frames_per_second < 1)) {
 536                      //        // not video FPS information, probably audio information
 537                      //        $sttsFramesTotal  = 0;
 538                      //        $sttsSecondsTotal = 0;
 539                      //        break;
 540                      //    }
 541                      //    $sttsFramesTotal  += $frame_count;
 542                      //    $sttsSecondsTotal += $frame_count / $frames_per_second;
 543                      //}
 544                      //if (($sttsFramesTotal > 0) && ($sttsSecondsTotal > 0)) {
 545                      //    if (($sttsFramesTotal / $sttsSecondsTotal) > @$ThisFileInfo['video']['frame_rate']) {
 546                      //        $ThisFileInfo['video']['frame_rate'] = $sttsFramesTotal / $sttsSecondsTotal;
 547                      //    }
 548                      //}
 549                  //}
 550                  break;
 551  
 552  
 553              case 'stss': // Sample Table Sync Sample (key frames) atom
 554                  if ($ParseAllPossibleAtoms) {
 555                      $atomstructure['version']        = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 556                      $atomstructure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 557                      $atomstructure['number_entries'] = getid3_lib::BigEndian2Int(substr($atomdata,  4, 4));
 558                      $stssEntriesDataOffset = 8;
 559                      for ($i = 0; $i < $atomstructure['number_entries']; $i++) {
 560                          $atomstructure['time_to_sample_table'][$i] = getid3_lib::BigEndian2Int(substr($atomdata, $stssEntriesDataOffset, 4));
 561                          $stssEntriesDataOffset += 4;
 562                      }
 563                  }
 564                  break;
 565  
 566  
 567              case 'stsc': // Sample Table Sample-to-Chunk atom
 568                  if ($ParseAllPossibleAtoms) {
 569                      $atomstructure['version']        = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 570                      $atomstructure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 571                      $atomstructure['number_entries'] = getid3_lib::BigEndian2Int(substr($atomdata,  4, 4));
 572                      $stscEntriesDataOffset = 8;
 573                      for ($i = 0; $i < $atomstructure['number_entries']; $i++) {
 574                          $atomstructure['sample_to_chunk_table'][$i]['first_chunk']        = getid3_lib::BigEndian2Int(substr($atomdata, $stscEntriesDataOffset, 4));
 575                          $stscEntriesDataOffset += 4;
 576                          $atomstructure['sample_to_chunk_table'][$i]['samples_per_chunk']  = getid3_lib::BigEndian2Int(substr($atomdata, $stscEntriesDataOffset, 4));
 577                          $stscEntriesDataOffset += 4;
 578                          $atomstructure['sample_to_chunk_table'][$i]['sample_description'] = getid3_lib::BigEndian2Int(substr($atomdata, $stscEntriesDataOffset, 4));
 579                          $stscEntriesDataOffset += 4;
 580                      }
 581                  }
 582                  break;
 583  
 584  
 585              case 'stsz': // Sample Table SiZe atom
 586                  if ($ParseAllPossibleAtoms) {
 587                      $atomstructure['version']        = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 588                      $atomstructure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 589                      $atomstructure['sample_size']    = getid3_lib::BigEndian2Int(substr($atomdata,  4, 4));
 590                      $atomstructure['number_entries'] = getid3_lib::BigEndian2Int(substr($atomdata,  8, 4));
 591                      $stszEntriesDataOffset = 12;
 592                      if ($atomstructure['sample_size'] == 0) {
 593                          for ($i = 0; $i < $atomstructure['number_entries']; $i++) {
 594                              $atomstructure['sample_size_table'][$i] = getid3_lib::BigEndian2Int(substr($atomdata, $stszEntriesDataOffset, 4));
 595                              $stszEntriesDataOffset += 4;
 596                          }
 597                      }
 598                  }
 599                  break;
 600  
 601  
 602              case 'stco': // Sample Table Chunk Offset atom
 603                  if ($ParseAllPossibleAtoms) {
 604                      $atomstructure['version']        = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 605                      $atomstructure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 606                      $atomstructure['number_entries'] = getid3_lib::BigEndian2Int(substr($atomdata,  4, 4));
 607                      $stcoEntriesDataOffset = 8;
 608                      for ($i = 0; $i < $atomstructure['number_entries']; $i++) {
 609                          $atomstructure['chunk_offset_table'][$i] = getid3_lib::BigEndian2Int(substr($atomdata, $stcoEntriesDataOffset, 4));
 610                          $stcoEntriesDataOffset += 4;
 611                      }
 612                  }
 613                  break;
 614  
 615  
 616              case 'dref': // Data REFerence atom
 617                  $atomstructure['version']        = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 618                  $atomstructure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 619                  $atomstructure['number_entries'] = getid3_lib::BigEndian2Int(substr($atomdata,  4, 4));
 620                  $drefDataOffset = 8;
 621                  for ($i = 0; $i < $atomstructure['number_entries']; $i++) {
 622                      $atomstructure['data_references'][$i]['size']                    = getid3_lib::BigEndian2Int(substr($atomdata, $drefDataOffset, 4));
 623                      $drefDataOffset += 4;
 624                      $atomstructure['data_references'][$i]['type']                    =               substr($atomdata, $drefDataOffset, 4);
 625                      $drefDataOffset += 4;
 626                      $atomstructure['data_references'][$i]['version']                 = getid3_lib::BigEndian2Int(substr($atomdata,  $drefDataOffset, 1));
 627                      $drefDataOffset += 1;
 628                      $atomstructure['data_references'][$i]['flags_raw']               = getid3_lib::BigEndian2Int(substr($atomdata,  $drefDataOffset, 3)); // hardcoded: 0x0000
 629                      $drefDataOffset += 3;
 630                      $atomstructure['data_references'][$i]['data']                    =               substr($atomdata, $drefDataOffset, ($atomstructure['data_references'][$i]['size'] - 4 - 4 - 1 - 3));
 631                      $drefDataOffset += ($atomstructure['data_references'][$i]['size'] - 4 - 4 - 1 - 3);
 632  
 633                      $atomstructure['data_references'][$i]['flags']['self_reference'] = (bool) ($atomstructure['data_references'][$i]['flags_raw'] & 0x001);
 634                  }
 635                  break;
 636  
 637  
 638              case 'gmin': // base Media INformation atom
 639                  $atomstructure['version']                = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 640                  $atomstructure['flags_raw']              = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 641                  $atomstructure['graphics_mode']          = getid3_lib::BigEndian2Int(substr($atomdata,  4, 2));
 642                  $atomstructure['opcolor_red']            = getid3_lib::BigEndian2Int(substr($atomdata,  6, 2));
 643                  $atomstructure['opcolor_green']          = getid3_lib::BigEndian2Int(substr($atomdata,  8, 2));
 644                  $atomstructure['opcolor_blue']           = getid3_lib::BigEndian2Int(substr($atomdata, 10, 2));
 645                  $atomstructure['balance']                = getid3_lib::BigEndian2Int(substr($atomdata, 12, 2));
 646                  $atomstructure['reserved']               = getid3_lib::BigEndian2Int(substr($atomdata, 14, 2));
 647                  break;
 648  
 649  
 650              case 'smhd': // Sound Media information HeaDer atom
 651                  $atomstructure['version']                = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 652                  $atomstructure['flags_raw']              = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 653                  $atomstructure['balance']                = getid3_lib::BigEndian2Int(substr($atomdata,  4, 2));
 654                  $atomstructure['reserved']               = getid3_lib::BigEndian2Int(substr($atomdata,  6, 2));
 655                  break;
 656  
 657  
 658              case 'vmhd': // Video Media information HeaDer atom
 659                  $atomstructure['version']                = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 660                  $atomstructure['flags_raw']              = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3));
 661                  $atomstructure['graphics_mode']          = getid3_lib::BigEndian2Int(substr($atomdata,  4, 2));
 662                  $atomstructure['opcolor_red']            = getid3_lib::BigEndian2Int(substr($atomdata,  6, 2));
 663                  $atomstructure['opcolor_green']          = getid3_lib::BigEndian2Int(substr($atomdata,  8, 2));
 664                  $atomstructure['opcolor_blue']           = getid3_lib::BigEndian2Int(substr($atomdata, 10, 2));
 665  
 666                  $atomstructure['flags']['no_lean_ahead'] = (bool) ($atomstructure['flags_raw'] & 0x001);
 667                  break;
 668  
 669  
 670              case 'hdlr': // HanDLeR reference atom
 671                  $atomstructure['version']                = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 672                  $atomstructure['flags_raw']              = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 673                  $atomstructure['component_type']         =                           substr($atomdata,  4, 4);
 674                  $atomstructure['component_subtype']      =                           substr($atomdata,  8, 4);
 675                  $atomstructure['component_manufacturer'] =                           substr($atomdata, 12, 4);
 676                  $atomstructure['component_flags_raw']    = getid3_lib::BigEndian2Int(substr($atomdata, 16, 4));
 677                  $atomstructure['component_flags_mask']   = getid3_lib::BigEndian2Int(substr($atomdata, 20, 4));
 678                  $atomstructure['component_name']         =      $this->Pascal2String(substr($atomdata, 24));
 679  
 680                  if (($atomstructure['component_subtype'] == 'STpn') && ($atomstructure['component_manufacturer'] == 'zzzz')) {
 681                      $ThisFileInfo['video']['dataformat'] = 'quicktimevr';
 682                  }
 683                  break;
 684  
 685  
 686              case 'mdhd': // MeDia HeaDer atom
 687                  $atomstructure['version']               = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 688                  $atomstructure['flags_raw']             = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 689                  $atomstructure['creation_time']         = getid3_lib::BigEndian2Int(substr($atomdata,  4, 4));
 690                  $atomstructure['modify_time']           = getid3_lib::BigEndian2Int(substr($atomdata,  8, 4));
 691                  $atomstructure['time_scale']            = getid3_lib::BigEndian2Int(substr($atomdata, 12, 4));
 692                  $atomstructure['duration']              = getid3_lib::BigEndian2Int(substr($atomdata, 16, 4));
 693                  $atomstructure['language_id']           = getid3_lib::BigEndian2Int(substr($atomdata, 20, 2));
 694                  $atomstructure['quality']               = getid3_lib::BigEndian2Int(substr($atomdata, 22, 2));
 695  
 696                  if ($atomstructure['time_scale'] == 0) {
 697                      $ThisFileInfo['error'][] = 'Corrupt Quicktime file: mdhd.time_scale == zero';
 698                      return false;
 699                  }
 700                  $atomstructure['creation_time_unix']    = getid3_lib::DateMac2Unix($atomstructure['creation_time']);
 701                  $atomstructure['modify_time_unix']      = getid3_lib::DateMac2Unix($atomstructure['modify_time']);
 702                  $atomstructure['playtime_seconds']      = $atomstructure['duration'] / $atomstructure['time_scale'];
 703                  $atomstructure['language']              = $this->QuicktimeLanguageLookup($atomstructure['language_id']);
 704                  if (empty($ThisFileInfo['comments']['language']) || (!in_array($atomstructure['language'], $ThisFileInfo['comments']['language']))) {
 705                      $ThisFileInfo['comments']['language'][] = $atomstructure['language'];
 706                  }
 707                  break;
 708  
 709  
 710              case 'pnot': // Preview atom
 711                  $atomstructure['modification_date']      = getid3_lib::BigEndian2Int(substr($atomdata,  0, 4)); // "standard Macintosh format"
 712                  $atomstructure['version_number']         = getid3_lib::BigEndian2Int(substr($atomdata,  4, 2)); // hardcoded: 0x00
 713                  $atomstructure['atom_type']              =               substr($atomdata,  6, 4);        // usually: 'PICT'
 714                  $atomstructure['atom_index']             = getid3_lib::BigEndian2Int(substr($atomdata, 10, 2)); // usually: 0x01
 715  
 716                  $atomstructure['modification_date_unix'] = getid3_lib::DateMac2Unix($atomstructure['modification_date']);
 717                  break;
 718  
 719  
 720              case 'crgn': // Clipping ReGioN atom
 721                  $atomstructure['region_size']   = getid3_lib::BigEndian2Int(substr($atomdata,  0, 2)); // The Region size, Region boundary box,
 722                  $atomstructure['boundary_box']  = getid3_lib::BigEndian2Int(substr($atomdata,  2, 8)); // and Clipping region data fields
 723                  $atomstructure['clipping_data'] =               substr($atomdata, 10);           // constitute a QuickDraw region.
 724                  break;
 725  
 726  
 727              case 'load': // track LOAD settings atom
 728                  $atomstructure['preload_start_time'] = getid3_lib::BigEndian2Int(substr($atomdata,  0, 4));
 729                  $atomstructure['preload_duration']   = getid3_lib::BigEndian2Int(substr($atomdata,  4, 4));
 730                  $atomstructure['preload_flags_raw']  = getid3_lib::BigEndian2Int(substr($atomdata,  8, 4));
 731                  $atomstructure['default_hints_raw']  = getid3_lib::BigEndian2Int(substr($atomdata, 12, 4));
 732  
 733                  $atomstructure['default_hints']['double_buffer'] = (bool) ($atomstructure['default_hints_raw'] & 0x0020);
 734                  $atomstructure['default_hints']['high_quality']  = (bool) ($atomstructure['default_hints_raw'] & 0x0100);
 735                  break;
 736  
 737  
 738              case 'tmcd': // TiMe CoDe atom
 739              case 'chap': // CHAPter list atom
 740              case 'sync': // SYNChronization atom
 741              case 'scpt': // tranSCriPT atom
 742              case 'ssrc': // non-primary SouRCe atom
 743                  for ($i = 0; $i < (strlen($atomdata) % 4); $i++) {
 744                      $atomstructure['track_id'][$i] = getid3_lib::BigEndian2Int(substr($atomdata, $i * 4, 4));
 745                  }
 746                  break;
 747  
 748  
 749              case 'elst': // Edit LiST atom
 750                  $atomstructure['version']        = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 751                  $atomstructure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 752                  $atomstructure['number_entries'] = getid3_lib::BigEndian2Int(substr($atomdata,  4, 4));
 753                  for ($i = 0; $i < $atomstructure['number_entries']; $i++ ) {
 754                      $atomstructure['edit_list'][$i]['track_duration'] =   getid3_lib::BigEndian2Int(substr($atomdata, 8 + ($i * 12) + 0, 4));
 755                      $atomstructure['edit_list'][$i]['media_time']     =   getid3_lib::BigEndian2Int(substr($atomdata, 8 + ($i * 12) + 4, 4));
 756                      $atomstructure['edit_list'][$i]['media_rate']     = getid3_lib::FixedPoint16_16(substr($atomdata, 8 + ($i * 12) + 8, 4));
 757                  }
 758                  break;
 759  
 760  
 761              case 'kmat': // compressed MATte atom
 762                  $atomstructure['version']        = getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 763                  $atomstructure['flags_raw']      = getid3_lib::BigEndian2Int(substr($atomdata,  1, 3)); // hardcoded: 0x0000
 764                  $atomstructure['matte_data_raw'] =               substr($atomdata,  4);
 765                  break;
 766  
 767  
 768              case 'ctab': // Color TABle atom
 769                  $atomstructure['color_table_seed']   = getid3_lib::BigEndian2Int(substr($atomdata,  0, 4)); // hardcoded: 0x00000000
 770                  $atomstructure['color_table_flags']  = getid3_lib::BigEndian2Int(substr($atomdata,  4, 2)); // hardcoded: 0x8000
 771                  $atomstructure['color_table_size']   = getid3_lib::BigEndian2Int(substr($atomdata,  6, 2)) + 1;
 772                  for ($colortableentry = 0; $colortableentry < $atomstructure['color_table_size']; $colortableentry++) {
 773                      $atomstructure['color_table'][$colortableentry]['alpha'] = getid3_lib::BigEndian2Int(substr($atomdata, 8 + ($colortableentry * 8) + 0, 2));
 774                      $atomstructure['color_table'][$colortableentry]['red']   = getid3_lib::BigEndian2Int(substr($atomdata, 8 + ($colortableentry * 8) + 2, 2));
 775                      $atomstructure['color_table'][$colortableentry]['green'] = getid3_lib::BigEndian2Int(substr($atomdata, 8 + ($colortableentry * 8) + 4, 2));
 776                      $atomstructure['color_table'][$colortableentry]['blue']  = getid3_lib::BigEndian2Int(substr($atomdata, 8 + ($colortableentry * 8) + 6, 2));
 777                  }
 778                  break;
 779  
 780  
 781              case 'mvhd': // MoVie HeaDer atom
 782                  $atomstructure['version']            =   getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 783                  $atomstructure['flags_raw']          =   getid3_lib::BigEndian2Int(substr($atomdata,  1, 3));
 784                  $atomstructure['creation_time']      =   getid3_lib::BigEndian2Int(substr($atomdata,  4, 4));
 785                  $atomstructure['modify_time']        =   getid3_lib::BigEndian2Int(substr($atomdata,  8, 4));
 786                  $atomstructure['time_scale']         =   getid3_lib::BigEndian2Int(substr($atomdata, 12, 4));
 787                  $atomstructure['duration']           =   getid3_lib::BigEndian2Int(substr($atomdata, 16, 4));
 788                  $atomstructure['preferred_rate']     = getid3_lib::FixedPoint16_16(substr($atomdata, 20, 4));
 789                  $atomstructure['preferred_volume']   =   getid3_lib::FixedPoint8_8(substr($atomdata, 24, 2));
 790                  $atomstructure['reserved']           =                             substr($atomdata, 26, 10);
 791                  $atomstructure['matrix_a']           = getid3_lib::FixedPoint16_16(substr($atomdata, 36, 4));
 792                  $atomstructure['matrix_b']           = getid3_lib::FixedPoint16_16(substr($atomdata, 40, 4));
 793                  $atomstructure['matrix_u']           =  getid3_lib::FixedPoint2_30(substr($atomdata, 44, 4));
 794                  $atomstructure['matrix_c']           = getid3_lib::FixedPoint16_16(substr($atomdata, 48, 4));
 795                  $atomstructure['matrix_d']           = getid3_lib::FixedPoint16_16(substr($atomdata, 52, 4));
 796                  $atomstructure['matrix_v']           =  getid3_lib::FixedPoint2_30(substr($atomdata, 56, 4));
 797                  $atomstructure['matrix_x']           = getid3_lib::FixedPoint16_16(substr($atomdata, 60, 4));
 798                  $atomstructure['matrix_y']           = getid3_lib::FixedPoint16_16(substr($atomdata, 64, 4));
 799                  $atomstructure['matrix_w']           =  getid3_lib::FixedPoint2_30(substr($atomdata, 68, 4));
 800                  $atomstructure['preview_time']       =   getid3_lib::BigEndian2Int(substr($atomdata, 72, 4));
 801                  $atomstructure['preview_duration']   =   getid3_lib::BigEndian2Int(substr($atomdata, 76, 4));
 802                  $atomstructure['poster_time']        =   getid3_lib::BigEndian2Int(substr($atomdata, 80, 4));
 803                  $atomstructure['selection_time']     =   getid3_lib::BigEndian2Int(substr($atomdata, 84, 4));
 804                  $atomstructure['selection_duration'] =   getid3_lib::BigEndian2Int(substr($atomdata, 88, 4));
 805                  $atomstructure['current_time']       =   getid3_lib::BigEndian2Int(substr($atomdata, 92, 4));
 806                  $atomstructure['next_track_id']      =   getid3_lib::BigEndian2Int(substr($atomdata, 96, 4));
 807  
 808                  if ($atomstructure['time_scale'] == 0) {
 809                      $ThisFileInfo['error'][] = 'Corrupt Quicktime file: mvhd.time_scale == zero';
 810                      return false;
 811                  }
 812                  $atomstructure['creation_time_unix']        = getid3_lib::DateMac2Unix($atomstructure['creation_time']);
 813                  $atomstructure['modify_time_unix']          = getid3_lib::DateMac2Unix($atomstructure['modify_time']);
 814                  $ThisFileInfo['quicktime']['time_scale']    = $atomstructure['time_scale'];
 815                  $ThisFileInfo['quicktime']['display_scale'] = $atomstructure['matrix_a'];
 816                  $ThisFileInfo['playtime_seconds']           = $atomstructure['duration'] / $atomstructure['time_scale'];
 817                  break;
 818  
 819  
 820              case 'tkhd': // TracK HeaDer atom
 821                  $atomstructure['version']             =   getid3_lib::BigEndian2Int(substr($atomdata,  0, 1));
 822                  $atomstructure['flags_raw']           =   getid3_lib::BigEndian2Int(substr($atomdata,  1, 3));
 823                  $atomstructure['creation_time']       =   getid3_lib::BigEndian2Int(substr($atomdata,  4, 4));
 824                  $atomstructure['modify_time']         =   getid3_lib::BigEndian2Int(substr($atomdata,  8, 4));
 825                  $atomstructure['trackid']             =   getid3_lib::BigEndian2Int(substr($atomdata, 12, 4));
 826                  $atomstructure['reserved1']           =   getid3_lib::BigEndian2Int(substr($atomdata, 16, 4));
 827                  $atomstructure['duration']            =   getid3_lib::BigEndian2Int(substr($atomdata, 20, 4));
 828                  $atomstructure['reserved2']           =   getid3_lib::BigEndian2Int(substr($atomdata, 24, 8));
 829                  $atomstructure['layer']               =   getid3_lib::BigEndian2Int(substr($atomdata, 32, 2));
 830                  $atomstructure['alternate_group']     =   getid3_lib::BigEndian2Int(substr($atomdata, 34, 2));
 831                  $atomstructure['volume']              =   getid3_lib::FixedPoint8_8(substr($atomdata, 36, 2));
 832                  $atomstructure['reserved3']           =   getid3_lib::BigEndian2Int(substr($atomdata, 38, 2));
 833                  $atomstructure['matrix_a']            = getid3_lib::FixedPoint16_16(substr($atomdata, 40, 4));
 834                  $atomstructure['matrix_b']            = getid3_lib::FixedPoint16_16(substr($atomdata, 44, 4));
 835                  $atomstructure['matrix_u']            = getid3_lib::FixedPoint16_16(substr($atomdata, 48, 4));
 836                  $atomstructure['matrix_c']            = getid3_lib::FixedPoint16_16(substr($atomdata, 52, 4));
 837                  $atomstructure['matrix_v']            = getid3_lib::FixedPoint16_16(substr($atomdata, 56, 4));
 838                  $atomstructure['matrix_d']            = getid3_lib::FixedPoint16_16(substr($atomdata, 60, 4));
 839                  $atomstructure['matrix_x']            =  getid3_lib::FixedPoint2_30(substr($atomdata, 64, 4));
 840                  $atomstructure['matrix_y']            =  getid3_lib::FixedPoint2_30(substr($atomdata, 68, 4));
 841                  $atomstructure['matrix_w']            =  getid3_lib::FixedPoint2_30(substr($atomdata, 72, 4));
 842                  $atomstructure['width']               = getid3_lib::FixedPoint16_16(substr($atomdata, 76, 4));
 843                  $atomstructure['height']              = getid3_lib::FixedPoint16_16(substr($atomdata, 80, 4));
 844  
 845                  $atomstructure['flags']['enabled']    = (bool) ($atomstructure['flags_raw'] & 0x0001);
 846                  $atomstructure['flags']['in_movie']   = (bool) ($atomstructure['flags_raw'] & 0x0002);
 847                  $atomstructure['flags']['in_preview'] = (bool) ($atomstructure['flags_raw'] & 0x0004);
 848                  $atomstructure['flags']['in_poster']  = (bool) ($atomstructure['flags_raw'] & 0x0008);
 849                  $atomstructure['creation_time_unix']  = getid3_lib::DateMac2Unix($atomstructure['creation_time']);
 850                  $atomstructure['modify_time_unix']    = getid3_lib::DateMac2Unix($atomstructure['modify_time']);
 851  
 852                  if (!isset($ThisFileInfo['video']['resolution_x']) || !isset($ThisFileInfo['video']['resolution_y'])) {
 853                      $ThisFileInfo['video']['resolution_x'] = $atomstructure['width'];
 854                      $ThisFileInfo['video']['resolution_y'] = $atomstructure['height'];
 855                  }
 856                  if ($atomstructure['flags']['enabled'] == 1) {
 857                      $ThisFileInfo['video']['resolution_x'] = max($ThisFileInfo['video']['resolution_x'], $atomstructure['width']);
 858                      $ThisFileInfo['video']['resolution_y'] = max($ThisFileInfo['video']['resolution_y'], $atomstructure['height']);
 859                  }
 860                  if (!empty($ThisFileInfo['video']['resolution_x']) && !empty($ThisFileInfo['video']['resolution_y'])) {
 861                      $ThisFileInfo['quicktime']['video']['resolution_x'] = $ThisFileInfo['video']['resolution_x'];
 862                      $ThisFileInfo['quicktime']['video']['resolution_y'] = $ThisFileInfo['video']['resolution_y'];
 863                  } else {
 864                      unset($ThisFileInfo['video']['resolution_x']);
 865                      unset($ThisFileInfo['video']['resolution_y']);
 866                      unset($ThisFileInfo['quicktime']['video']);
 867                  }
 868                  break;
 869  
 870  
 871              case 'meta': // METAdata atom
 872                  // http://www.geocities.com/xhelmboyx/quicktime/formats/qti-layout.txt
 873                  $NextTagPosition = strpos($atomdata, '');
 874                  while ($NextTagPosition < strlen($atomdata)) {
 875                      $metaItemSize = getid3_lib::BigEndian2Int(substr($atomdata, $NextTagPosition - 4, 4)) - 4;
 876                      if ($metaItemSize == -4) {
 877                          break;
 878                      }
 879                      $metaItemRaw  = substr($atomdata, $NextTagPosition, $metaItemSize);
 880                      $metaItemKey  = substr($metaItemRaw, 0, 4);
 881                      $metaItemData = substr($metaItemRaw, 20);
 882                      $NextTagPosition += $metaItemSize + 4;
 883  
 884                      $this->CopyToAppropriateCommentsSection($metaItemKey, $metaItemData, $ThisFileInfo);
 885                  }
 886                  break;
 887  
 888              case 'ftyp': // FileTYPe (?) atom (for MP4 it seems)
 889                  $atomstructure['signature'] =                           substr($atomdata,  0, 4);
 890                  $atomstructure['unknown_1'] = getid3_lib::BigEndian2Int(substr($atomdata,  4, 4));
 891                  $atomstructure['fourcc']    =                           substr($atomdata,  8, 4);
 892                  break;
 893  
 894              case 'mdat': // Media DATa atom
 895              case 'free': // FREE space atom
 896              case 'skip': // SKIP atom
 897              case 'wide': // 64-bit expansion placeholder atom
 898                  // 'mdat' data is too big to deal with, contains no useful metadata
 899                  // 'free', 'skip' and 'wide' are just padding, contains no useful data at all
 900  
 901                  // When writing QuickTime files, it is sometimes necessary to update an atom's size.
 902                  // It is impossible to update a 32-bit atom to a 64-bit atom since the 32-bit atom
 903                  // is only 8 bytes in size, and the 64-bit atom requires 16 bytes. Therefore, QuickTime
 904                  // puts an 8-byte placeholder atom before any atoms it may have to update the size of.
 905                  // In this way, if the atom needs to be converted from a 32-bit to a 64-bit atom, the
 906                  // placeholder atom can be overwritten to obtain the necessary 8 extra bytes.
 907                  // The placeholder atom has a type of kWideAtomPlaceholderType ( 'wide' ).
 908                  break;
 909  
 910  
 911              case 'nsav': // NoSAVe atom
 912                  // http://developer.apple.com/technotes/tn/tn2038.html
 913                  $atomstructure['data'] = getid3_lib::BigEndian2Int(substr($atomdata,  0, 4));
 914                  break;
 915  
 916              case 'ctyp': // Controller TYPe atom (seen on QTVR)
 917                  // http://homepages.slingshot.co.nz/~helmboy/quicktime/formats/qtm-layout.txt
 918                  // some controller names are:
 919                  //   0x00 + 'std' for linear movie
 920                  //   'none' for no controls
 921                  $atomstructure['ctyp'] = substr($atomdata, 0, 4);
 922                  switch ($atomstructure['ctyp']) {
 923                      case 'qtvr':
 924                          $ThisFileInfo['video']['dataformat'] = 'quicktimevr';
 925                          break;
 926                  }
 927                  break;
 928  
 929              case 'pano': // PANOrama track (seen on QTVR)
 930                  $atomstructure['pano'] = getid3_lib::BigEndian2Int(substr($atomdata,  0, 4));
 931                  break;
 932  
 933              case 'hint': // HINT track
 934              case 'hinf': //
 935              case 'hinv': //
 936              case 'hnti': //
 937                  $ThisFileInfo['quicktime']['hinting'] = true;
 938                  break;
 939  
 940              case 'imgt': // IMaGe Track reference (kQTVRImageTrackRefType) (seen on QTVR)
 941                  for ($i = 0; $i < ($atomstructure['size'] - 8); $i += 4) {
 942                      $atomstructure['imgt'][] = getid3_lib::BigEndian2Int(substr($atomdata, $i, 4));
 943                  }
 944                  break;
 945  
 946              case 'FXTC': // Something to do with Adobe After Effects (?)
 947              case 'PrmA':
 948              case 'code':
 949              case 'FIEL': // this is NOT "fiel" (Field Ordering) as describe here: http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap3/chapter_4_section_2.html
 950                  // Observed-but-not-handled atom types are just listed here
 951                  // to prevent warnings being generated
 952                  $atomstructure['data'] = $atomdata;
 953                  break;
 954  
 955              default:
 956                  $ThisFileInfo['warning'][] = 'Unknown QuickTime atom type: "'.$atomname.'" at offset '.$baseoffset;
 957                  $atomstructure['data'] = $atomdata;
 958                  break;
 959          }
 960          array_pop($atomHierarchy);
 961          return $atomstructure;
 962      }
 963  
 964  	function QuicktimeParseContainerAtom($atomdata, &$ThisFileInfo, $baseoffset, &$atomHierarchy, $ParseAllPossibleAtoms) {
 965          $atomstructure  = false;
 966          $subatomoffset  = 0;
 967          $subatomcounter = 0;
 968          if ((strlen($atomdata) == 4) && (getid3_lib::BigEndian2Int($atomdata) == 0x00000000)) {
 969              return false;
 970          }
 971          while ($subatomoffset < strlen($atomdata)) {
 972              $subatomsize = getid3_lib::BigEndian2Int(substr($atomdata, $subatomoffset + 0, 4));
 973              $subatomname =               substr($atomdata, $subatomoffset + 4, 4);
 974              $subatomdata =               substr($atomdata, $subatomoffset + 8, $subatomsize - 8);
 975              if ($subatomsize == 0) {
 976                  // Furthermore, for historical reasons the list of atoms is optionally
 977                  // terminated by a 32-bit integer set to 0. If you are writing a program
 978                  // to read user data atoms, you should allow for the terminating 0.
 979                  return $atomstructure;
 980              }
 981  
 982              $atomstructure[$subatomcounter] = $this->QuicktimeParseAtom($subatomname, $subatomsize, $subatomdata, $ThisFileInfo, $baseoffset + $subatomoffset, $atomHierarchy, $ParseAllPossibleAtoms);
 983  
 984              $subatomoffset += $subatomsize;
 985              $subatomcounter++;
 986          }
 987          return $atomstructure;
 988      }
 989  
 990  
 991  	function QuicktimeLanguageLookup($languageid) {
 992          static $QuicktimeLanguageLookup = array();
 993          if (empty($QuicktimeLanguageLookup)) {
 994              $QuicktimeLanguageLookup[0]   = 'English';
 995              $QuicktimeLanguageLookup[1]   = 'French';
 996              $QuicktimeLanguageLookup[2]   = 'German';
 997              $QuicktimeLanguageLookup[3]   = 'Italian';
 998              $QuicktimeLanguageLookup[4]   = 'Dutch';
 999              $QuicktimeLanguageLookup[5]   = 'Swedish';
1000              $QuicktimeLanguageLookup[6]   = 'Spanish';
1001              $QuicktimeLanguageLookup[7]   = 'Danish';
1002              $QuicktimeLanguageLookup[8]   = 'Portuguese';
1003              $QuicktimeLanguageLookup[9]   = 'Norwegian';
1004              $QuicktimeLanguageLookup[10]  = 'Hebrew';
1005              $QuicktimeLanguageLookup[11]  = 'Japanese';
1006              $QuicktimeLanguageLookup[12]  = 'Arabic';
1007              $QuicktimeLanguageLookup[13]  = 'Finnish';
1008              $QuicktimeLanguageLookup[14]  = 'Greek';
1009              $QuicktimeLanguageLookup[15]  = 'Icelandic';
1010              $QuicktimeLanguageLookup[16]  = 'Maltese';
1011              $QuicktimeLanguageLookup[17]  = 'Turkish';
1012              $QuicktimeLanguageLookup[18]  = 'Croatian';
1013              $QuicktimeLanguageLookup[19]  = 'Chinese (Traditional)';
1014              $QuicktimeLanguageLookup[20]  = 'Urdu';
1015              $QuicktimeLanguageLookup[21]  = 'Hindi';
1016              $QuicktimeLanguageLookup[22]  = 'Thai';
1017              $QuicktimeLanguageLookup[23]  = 'Korean';
1018              $QuicktimeLanguageLookup[24]  = 'Lithuanian';
1019              $QuicktimeLanguageLookup[25]  = 'Polish';
1020              $QuicktimeLanguageLookup[26]  = 'Hungarian';
1021              $QuicktimeLanguageLookup[27]  = 'Estonian';
1022              $QuicktimeLanguageLookup[28]  = 'Lettish';
1023              $QuicktimeLanguageLookup[28]  = 'Latvian';
1024              $QuicktimeLanguageLookup[29]  = 'Saamisk';
1025              $QuicktimeLanguageLookup[29]  = 'Lappish';
1026              $QuicktimeLanguageLookup[30]  = 'Faeroese';
1027              $QuicktimeLanguageLookup[31]  = 'Farsi';
1028              $QuicktimeLanguageLookup[31]  = 'Persian';
1029              $QuicktimeLanguageLookup[32]  = 'Russian';
1030              $QuicktimeLanguageLookup[33]  = 'Chinese (Simplified)';
1031              $QuicktimeLanguageLookup[34]  = 'Flemish';
1032              $QuicktimeLanguageLookup[35]  = 'Irish';
1033              $QuicktimeLanguageLookup[36]  = 'Albanian';
1034              $QuicktimeLanguageLookup[37]  = 'Romanian';
1035              $QuicktimeLanguageLookup[38]  = 'Czech';
1036              $QuicktimeLanguageLookup[39]  = 'Slovak';
1037              $QuicktimeLanguageLookup[40]  = 'Slovenian';
1038              $QuicktimeLanguageLookup[41]  = 'Yiddish';
1039              $QuicktimeLanguageLookup[42]  = 'Serbian';
1040              $QuicktimeLanguageLookup[43]  = 'Macedonian';
1041              $QuicktimeLanguageLookup[44]  = 'Bulgarian';
1042              $QuicktimeLanguageLookup[45]  = 'Ukrainian';
1043              $QuicktimeLanguageLookup[46]  = 'Byelorussian';
1044              $QuicktimeLanguageLookup[47]  = 'Uzbek';
1045              $QuicktimeLanguageLookup[48]  = 'Kazakh';
1046              $QuicktimeLanguageLookup[49]  = 'Azerbaijani';
1047              $QuicktimeLanguageLookup[50]  = 'AzerbaijanAr';
1048              $QuicktimeLanguageLookup[51]  = 'Armenian';
1049              $QuicktimeLanguageLookup[52]  = 'Georgian';
1050              $QuicktimeLanguageLookup[53]  = 'Moldavian';
1051              $QuicktimeLanguageLookup[54]  = 'Kirghiz';
1052              $QuicktimeLanguageLookup[55]  = 'Tajiki';
1053              $QuicktimeLanguageLookup[56]  = 'Turkmen';
1054              $QuicktimeLanguageLookup[57]  = 'Mongolian';
1055              $QuicktimeLanguageLookup[58]  = 'MongolianCyr';
1056              $QuicktimeLanguageLookup[59]  = 'Pashto';
1057              $QuicktimeLanguageLookup[60]  = 'Kurdish';
1058              $QuicktimeLanguageLookup[61]  = 'Kashmiri';
1059              $QuicktimeLanguageLookup[62]  = 'Sindhi';
1060              $QuicktimeLanguageLookup[63]  = 'Tibetan';
1061              $QuicktimeLanguageLookup[64]  = 'Nepali';
1062              $QuicktimeLanguageLookup[65]  = 'Sanskrit';
1063              $QuicktimeLanguageLookup[66]  = 'Marathi';
1064              $QuicktimeLanguageLookup[67]  = 'Bengali';
1065              $QuicktimeLanguageLookup[68]  = 'Assamese';
1066              $QuicktimeLanguageLookup[69]  = 'Gujarati';
1067              $QuicktimeLanguageLookup[70]  = 'Punjabi';
1068              $QuicktimeLanguageLookup[71]  = 'Oriya';
1069              $QuicktimeLanguageLookup[72]  = 'Malayalam';
1070              $QuicktimeLanguageLookup[73]  = 'Kannada';
1071              $QuicktimeLanguageLookup[74]  = 'Tamil';
1072              $QuicktimeLanguageLookup[75]  = 'Telugu';
1073              $QuicktimeLanguageLookup[76]  = 'Sinhalese';
1074              $QuicktimeLanguageLookup[77]  = 'Burmese';
1075              $QuicktimeLanguageLookup[78]  = 'Khmer';
1076              $QuicktimeLanguageLookup[79]  = 'Lao';
1077              $QuicktimeLanguageLookup[80]  = 'Vietnamese';
1078              $QuicktimeLanguageLookup[81]  = 'Indonesian';
1079              $QuicktimeLanguageLookup[82]  = 'Tagalog';
1080              $QuicktimeLanguageLookup[83]  = 'MalayRoman';
1081              $QuicktimeLanguageLookup[84]  = 'MalayArabic';
1082              $QuicktimeLanguageLookup[85]  = 'Amharic';
1083              $QuicktimeLanguageLookup[86]  = 'Tigrinya';
1084              $QuicktimeLanguageLookup[87]  = 'Galla';
1085              $QuicktimeLanguageLookup[87]  = 'Oromo';
1086              $QuicktimeLanguageLookup[88]  = 'Somali';
1087              $QuicktimeLanguageLookup[89]  = 'Swahili';
1088              $QuicktimeLanguageLookup[90]  = 'Ruanda';
1089              $QuicktimeLanguageLookup[91]  = 'Rundi';
1090              $QuicktimeLanguageLookup[92]  = 'Chewa';
1091              $QuicktimeLanguageLookup[93]  = 'Malagasy';
1092              $QuicktimeLanguageLookup[94]  = 'Esperanto';
1093              $QuicktimeLanguageLookup[128] = 'Welsh';
1094              $QuicktimeLanguageLookup[129] = 'Basque';
1095              $QuicktimeLanguageLookup[130] = 'Catalan';
1096              $QuicktimeLanguageLookup[131] = 'Latin';
1097              $QuicktimeLanguageLookup[132] = 'Quechua';
1098              $QuicktimeLanguageLookup[133] = 'Guarani';
1099              $QuicktimeLanguageLookup[134] = 'Aymara';
1100              $QuicktimeLanguageLookup[135] = 'Tatar';
1101              $QuicktimeLanguageLookup[136] = 'Uighur';
1102              $QuicktimeLanguageLookup[137] = 'Dzongkha';
1103              $QuicktimeLanguageLookup[138] = 'JavaneseRom';
1104          }
1105          return (isset($QuicktimeLanguageLookup[$languageid]) ? $QuicktimeLanguageLookup[$languageid] : 'invalid');
1106      }
1107  
1108  	function QuicktimeVideoCodecLookup($codecid) {
1109          static $QuicktimeVideoCodecLookup = array();
1110          if (empty($QuicktimeVideoCodecLookup)) {
1111              $QuicktimeVideoCodecLookup['3IVX'] = '3ivx MPEG-4';
1112              $QuicktimeVideoCodecLookup['3IV1'] = '3ivx MPEG-4 v1';
1113              $QuicktimeVideoCodecLookup['3IV2'] = '3ivx MPEG-4 v2';
1114              $QuicktimeVideoCodecLookup['avr '] = 'AVR-JPEG';
1115              $QuicktimeVideoCodecLookup['base'] = 'Base';
1116              $QuicktimeVideoCodecLookup['WRLE'] = 'BMP';
1117              $QuicktimeVideoCodecLookup['cvid'] = 'Cinepak';
1118              $QuicktimeVideoCodecLookup['clou'] = 'Cloud';
1119              $QuicktimeVideoCodecLookup['cmyk'] = 'CMYK';
1120              $QuicktimeVideoCodecLookup['yuv2'] = 'ComponentVideo';
1121              $QuicktimeVideoCodecLookup['yuvu'] = 'ComponentVideoSigned';
1122              $QuicktimeVideoCodecLookup['yuvs'] = 'ComponentVideoUnsigned';
1123              $QuicktimeVideoCodecLookup['dvc '] = 'DVC-NTSC';
1124              $QuicktimeVideoCodecLookup['dvcp'] = 'DVC-PAL';
1125              $QuicktimeVideoCodecLookup['dvpn'] = 'DVCPro-NTSC';
1126              $QuicktimeVideoCodecLookup['dvpp'] = 'DVCPro-PAL';
1127              $QuicktimeVideoCodecLookup['fire'] = 'Fire';
1128              $QuicktimeVideoCodecLookup['flic'] = 'FLC';
1129              $QuicktimeVideoCodecLookup['b48r'] = '48RGB';
1130              $QuicktimeVideoCodecLookup['gif '] = 'GIF';
1131              $QuicktimeVideoCodecLookup['smc '] = 'Graphics';
1132              $QuicktimeVideoCodecLookup['h261'] = 'H261';
1133              $QuicktimeVideoCodecLookup['h263'] = 'H263';
1134              $QuicktimeVideoCodecLookup['IV41'] = 'Indeo4';
1135              $QuicktimeVideoCodecLookup['jpeg'] = 'JPEG';
1136              $QuicktimeVideoCodecLookup['PNTG'] = 'MacPaint';
1137              $QuicktimeVideoCodecLookup['msvc'] = 'Microsoft Video1';
1138              $QuicktimeVideoCodecLookup['mjpa'] = 'Motion JPEG-A';
1139              $QuicktimeVideoCodecLookup['mjpb'] = 'Motion JPEG-B';
1140              $QuicktimeVideoCodecLookup['myuv'] = 'MPEG YUV420';
1141              $QuicktimeVideoCodecLookup['dmb1'] = 'OpenDML JPEG';
1142              $QuicktimeVideoCodecLookup['kpcd'] = 'PhotoCD';
1143              $QuicktimeVideoCodecLookup['8BPS'] = 'Planar RGB';
1144              $QuicktimeVideoCodecLookup['png '] = 'PNG';
1145              $QuicktimeVideoCodecLookup['qdrw'] = 'QuickDraw';
1146              $QuicktimeVideoCodecLookup['qdgx'] = 'QuickDrawGX';
1147              $QuicktimeVideoCodecLookup['raw '] = 'RAW';
1148              $QuicktimeVideoCodecLookup['.SGI'] = 'SGI';
1149              $QuicktimeVideoCodecLookup['b16g'] = '16Gray';
1150              $QuicktimeVideoCodecLookup['b64a'] = '64ARGB';
1151              $QuicktimeVideoCodecLookup['SVQ1'] = 'Sorenson Video 1';
1152              $QuicktimeVideoCodecLookup['SVQ1'] = 'Sorenson Video 3';
1153              $QuicktimeVideoCodecLookup['syv9'] = 'Sorenson YUV9';
1154              $QuicktimeVideoCodecLookup['tga '] = 'Targa';
1155              $QuicktimeVideoCodecLookup['b32a'] = '32AlphaGray';
1156              $QuicktimeVideoCodecLookup['tiff'] = 'TIFF';
1157              $QuicktimeVideoCodecLookup['path'] = 'Vector';
1158              $QuicktimeVideoCodecLookup['rpza'] = 'Video';
1159              $QuicktimeVideoCodecLookup['ripl'] = 'WaterRipple';
1160              $QuicktimeVideoCodecLookup['WRAW'] = 'Windows RAW';
1161              $QuicktimeVideoCodecLookup['y420'] = 'YUV420';
1162          }
1163          return (isset($QuicktimeVideoCodecLookup[$codecid]) ? $QuicktimeVideoCodecLookup[$codecid] : '');
1164      }
1165  
1166  	function QuicktimeAudioCodecLookup($codecid) {
1167          static $QuicktimeAudioCodecLookup = array();
1168          if (empty($QuicktimeAudioCodecLookup)) {
1169              $QuicktimeAudioCodecLookup['.mp3']          = 'Fraunhofer MPEG Layer-III alias';
1170              $QuicktimeAudioCodecLookup['aac ']          = 'ISO/IEC 14496-3 AAC';
1171              $QuicktimeAudioCodecLookup['agsm']          = 'Apple GSM 10:1';
1172              $QuicktimeAudioCodecLookup['alac']          = 'Apple Lossless Audio Codec';
1173              $QuicktimeAudioCodecLookup['alaw']          = 'A-law 2:1';
1174              $QuicktimeAudioCodecLookup['conv']          = 'Sample Format';
1175              $QuicktimeAudioCodecLookup['dvca']          = 'DV';
1176              $QuicktimeAudioCodecLookup['dvi ']          = 'DV 4:1';
1177              $QuicktimeAudioCodecLookup['eqal']          = 'Frequency Equalizer';
1178              $QuicktimeAudioCodecLookup['fl32']          = '32-bit Floating Point';
1179              $QuicktimeAudioCodecLookup['fl64']          = '64-bit Floating Point';
1180              $QuicktimeAudioCodecLookup['ima4']          = 'Interactive Multimedia Association 4:1';
1181              $QuicktimeAudioCodecLookup['in24']          = '24-bit Integer';
1182              $QuicktimeAudioCodecLookup['in32']          = '32-bit Integer';
1183              $QuicktimeAudioCodecLookup['lpc ']          = 'LPC 23:1';
1184              $QuicktimeAudioCodecLookup['MAC3']          = 'Macintosh Audio Compression/Expansion (MACE) 3:1';
1185              $QuicktimeAudioCodecLookup['MAC6']          = 'Macintosh Audio Compression/Expansion (MACE) 6:1';
1186              $QuicktimeAudioCodecLookup['mixb']          = '8-bit Mixer';
1187              $QuicktimeAudioCodecLookup['mixw']          = '16-bit Mixer';
1188              $QuicktimeAudioCodecLookup['mp4a']          = 'ISO/IEC 14496-3 AAC';
1189              $QuicktimeAudioCodecLookup['MS'."\x00\x02"] = 'Microsoft ADPCM';
1190              $QuicktimeAudioCodecLookup['MS'."\x00\x11"] = 'DV IMA';
1191              $QuicktimeAudioCodecLookup['MS'."\x00\x55"] = 'Fraunhofer MPEG Layer III';
1192              $QuicktimeAudioCodecLookup['NONE']          = 'No Encoding';
1193              $QuicktimeAudioCodecLookup['Qclp']          = 'Qualcomm PureVoice';
1194              $QuicktimeAudioCodecLookup['QDM2']          = 'QDesign Music 2';
1195              $QuicktimeAudioCodecLookup['QDMC']          = 'QDesign Music 1';
1196              $QuicktimeAudioCodecLookup['ratb']          = '8-bit Rate';
1197              $QuicktimeAudioCodecLookup['ratw']          = '16-bit Rate';
1198              $QuicktimeAudioCodecLookup['raw ']          = 'raw PCM';
1199              $QuicktimeAudioCodecLookup['sour']          = 'Sound Source';
1200              $QuicktimeAudioCodecLookup['sowt']          = 'signed/two\'s complement (Little Endian)';
1201              $QuicktimeAudioCodecLookup['str1']          = 'Iomega MPEG layer II';
1202              $QuicktimeAudioCodecLookup['str2']          = 'Iomega MPEG *layer II';
1203              $QuicktimeAudioCodecLookup['str3']          = 'Iomega MPEG **layer II';
1204              $QuicktimeAudioCodecLookup['str4']          = 'Iomega MPEG ***layer II';
1205              $QuicktimeAudioCodecLookup['twos']          = 'signed/two\'s complement (Big Endian)';
1206              $QuicktimeAudioCodecLookup['ulaw']          = 'mu-law 2:1';
1207          }
1208          return (isset($QuicktimeAudioCodecLookup[$codecid]) ? $QuicktimeAudioCodecLookup[$codecid] : '');
1209      }
1210  
1211  	function QuicktimeDCOMLookup($compressionid) {
1212          static $QuicktimeDCOMLookup = array();
1213          if (empty($QuicktimeDCOMLookup)) {
1214              $QuicktimeDCOMLookup['zlib'] = 'ZLib Deflate';
1215              $QuicktimeDCOMLookup['adec'] = 'Apple Compression';
1216          }
1217          return (isset($QuicktimeDCOMLookup[$compressionid]) ? $QuicktimeDCOMLookup[$compressionid] : '');
1218      }
1219  
1220  	function QuicktimeColorNameLookup($colordepthid) {
1221          static $QuicktimeColorNameLookup = array();
1222          if (empty($QuicktimeColorNameLookup)) {
1223              $QuicktimeColorNameLookup[1]  = '2-color (monochrome)';
1224              $QuicktimeColorNameLookup[2]  = '4-color';
1225              $QuicktimeColorNameLookup[4]  = '16-color';
1226              $QuicktimeColorNameLookup[8]  = '256-color';
1227              $QuicktimeColorNameLookup[16] = 'thousands (16-bit color)';
1228              $QuicktimeColorNameLookup[24] = 'millions (24-bit color)';
1229              $QuicktimeColorNameLookup[32] = 'millions+ (32-bit color)';
1230              $QuicktimeColorNameLookup[33] = 'black & white';
1231              $QuicktimeColorNameLookup[34] = '4-gray';
1232              $QuicktimeColorNameLookup[36] = '16-gray';
1233              $QuicktimeColorNameLookup[40] = '256-gray';
1234          }
1235          return (isset($QuicktimeColorNameLookup[$colordepthid]) ? $QuicktimeColorNameLookup[$colordepthid] : 'invalid');
1236      }
1237  
1238  	function CopyToAppropriateCommentsSection($keyname, $data, &$ThisFileInfo) {
1239          static $handyatomtranslatorarray = array();
1240          if (empty($handyatomtranslatorarray)) {
1241              $handyatomtranslatorarray['妾py'] = 'copyright';
1242              $handyatomtranslatorarray['妻ay'] = 'creation_date';
1243              $handyatomtranslatorarray['妻ir'] = 'director';
1244              $handyatomtranslatorarray['委d1'] = 'edit1';
1245              $handyatomtranslatorarray['委d2'] = 'edit2';
1246              $handyatomtranslatorarray['委d3'] = 'edit3';
1247              $handyatomtranslatorarray['委d4'] = 'edit4';
1248              $handyatomtranslatorarray['委d5'] = 'edit5';
1249              $handyatomtranslatorarray['委d6'] = 'edit6';
1250              $handyatomtranslatorarray['委d7'] = 'edit7';
1251              $handyatomtranslatorarray['委d8'] = 'edit8';
1252              $handyatomtranslatorarray['委d9'] = 'edit9';
1253              $handyatomtranslatorarray['妹mt'] = 'format';
1254              $handyatomtranslatorarray['姆nf'] = 'information';
1255              $handyatomtranslatorarray['妳rd'] = 'producer';
1256              $handyatomtranslatorarray['妳rf'] = 'performers';
1257              $handyatomtranslatorarray['姅eq'] = 'system_requirements';
1258              $handyatomtranslatorarray['孟rc'] = 'source_credit';
1259              $handyatomtranslatorarray['定rt'] = 'writer';
1260  
1261              // http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt
1262              $handyatomtranslatorarray['姊am'] = 'title';
1263              $handyatomtranslatorarray['妾mt'] = 'comment';
1264              $handyatomtranslatorarray['定rn'] = 'warning';
1265              $handyatomtranslatorarray['姑st'] = 'host_computer';
1266              $handyatomtranslatorarray['姓ak'] = 'make';
1267              $handyatomtranslatorarray['姓od'] = 'model';
1268              $handyatomtranslatorarray['周RD'] = 'product';
1269              $handyatomtranslatorarray['孟wr'] = 'software';
1270              $handyatomtranslatorarray['奄ut'] = 'author';
1271              $handyatomtranslatorarray['呸RT'] = 'artist';
1272              $handyatomtranslatorarray['孤rk'] = 'track';
1273              $handyatomtranslatorarray['奄lb'] = 'album';
1274              $handyatomtranslatorarray['妾om'] = 'comment';
1275              $handyatomtranslatorarray['妮en'] = 'genre';
1276              $handyatomtranslatorarray['妯pe'] = 'composer';
1277              $handyatomtranslatorarray['季rl'] = 'url';
1278              $handyatomtranslatorarray['委nc'] = 'encoder';
1279          }
1280          if (isset($handyatomtranslatorarray[$keyname])) {
1281              $ThisFileInfo['quicktime']['comments'][$handyatomtranslatorarray[$keyname]][] = $data;
1282          }
1283  
1284          return true;
1285      }
1286  
1287  	function NoNullString($nullterminatedstring) {
1288          // remove the single null terminator on null terminated strings
1289          if (substr($nullterminatedstring, strlen($nullterminatedstring) - 1, 1) === "\x00") {
1290              return substr($nullterminatedstring, 0, strlen($nullterminatedstring) - 1);
1291          }
1292          return $nullterminatedstring;
1293      }
1294  
1295  	function Pascal2String($pascalstring) {
1296          // Pascal strings have 1 unsigned byte at the beginning saying how many chars (1-255) are in the string
1297          return substr($pascalstring, 1);
1298      }
1299  
1300  }
1301  
1302  ?>


[ Powered by PHPXref - Served by Debian GNU/Linux ]