200 {
201
202
203
204 $info = &$this->getid3->info;
205
206 $atom_parent = end($atomHierarchy);
207 array_push($atomHierarchy, $atomname);
208 $atom_structure['hierarchy'] = implode(' ', $atomHierarchy);
209 $atom_structure['name'] = $atomname;
210 $atom_structure['size'] = $atomsize;
211 $atom_structure['offset'] = $baseoffset;
212 switch ($atomname) {
213 case 'moov':
214 case 'trak':
215 case 'clip':
216 case 'matt':
217 case 'edts':
218 case 'tref':
219 case 'mdia':
220 case 'minf':
221 case 'dinf':
222 case 'udta':
223 case 'cmov':
224 case 'rmra':
225 case 'rmda':
226 case 'gmhd':
228 break;
229
230 case 'ilst':
232
233 $allnumericnames = true;
234 foreach ($atom_structure['subatoms'] as $subatomarray) {
235 if (!is_integer($subatomarray['name']) || (count($subatomarray['subatoms']) != 1)) {
236 $allnumericnames = false;
237 break;
238 }
239 }
240 if ($allnumericnames) {
241 $newData = array();
242 foreach ($atom_structure['subatoms'] as $subatomarray) {
243 foreach ($subatomarray['subatoms'] as $newData_subatomarray) {
244 unset($newData_subatomarray['hierarchy'], $newData_subatomarray['name']);
245 $newData[$subatomarray['name']] = $newData_subatomarray;
246 break;
247 }
248 }
249 $atom_structure['data'] = $newData;
250 unset($atom_structure['subatoms']);
251 }
252 }
253 break;
254
255 case "\x00\x00\x00\x01":
256 case "\x00\x00\x00\x02":
257 case "\x00\x00\x00\x03":
258 case "\x00\x00\x00\x04":
259 case "\x00\x00\x00\x05":
261 $atom_structure['name'] = $atomname;
263 break;
264
265 case 'stbl':
267 $isVideo = false;
268 $framerate = 0;
269 $framecount = 0;
270 foreach ($atom_structure[
'subatoms'] as
$key => $value_array) {
271 if (isset($value_array['sample_description_table'])) {
272 foreach ($value_array['sample_description_table'] as $key2 => $value_array2) {
273 if (isset($value_array2['data_format'])) {
274 switch ($value_array2['data_format']) {
275 case 'avc1':
276 case 'mp4v':
277
278 $isVideo = true;
279 break;
280 case 'mp4a':
281
282 break;
283 }
284 }
285 }
286 } elseif (isset($value_array['time_to_sample_table'])) {
287 foreach ($value_array['time_to_sample_table'] as $key2 => $value_array2) {
288 if (isset($value_array2['sample_count']) && isset($value_array2['sample_duration']) && ($value_array2['sample_duration'] > 0)) {
289 $framerate = round(
$info[
'quicktime'][
'time_scale'] / $value_array2[
'sample_duration'], 3);
290 $framecount = $value_array2['sample_count'];
291 }
292 }
293 }
294 }
295 if ($isVideo && $framerate) {
296 $info[
'quicktime'][
'video'][
'frame_rate'] = $framerate;
297 $info[
'video'][
'frame_rate'] =
$info[
'quicktime'][
'video'][
'frame_rate'];
298 }
299 if ($isVideo && $framecount) {
300 $info[
'quicktime'][
'video'][
'frame_count'] = $framecount;
301 }
302 break;
303
304
305 case "\xA9".'alb':
306 case "\xA9".'ART':
307 case "\xA9".'art':
308 case "\xA9".'aut':
309 case "\xA9".'cmt':
310 case "\xA9".'com':
311 case "\xA9".'cpy':
312 case "\xA9".'day':
313 case "\xA9".'dir':
314 case "\xA9".'ed1':
315 case "\xA9".'ed2':
316 case "\xA9".'ed3':
317 case "\xA9".'ed4':
318 case "\xA9".'ed5':
319 case "\xA9".'ed6':
320 case "\xA9".'ed7':
321 case "\xA9".'ed8':
322 case "\xA9".'ed9':
323 case "\xA9".'enc':
324 case "\xA9".'fmt':
325 case "\xA9".'gen':
326 case "\xA9".'grp':
327 case "\xA9".'hst':
328 case "\xA9".'inf':
329 case "\xA9".'lyr':
330 case "\xA9".'mak':
331 case "\xA9".'mod':
332 case "\xA9".'nam':
333 case "\xA9".'ope':
334 case "\xA9".'PRD':
335 case "\xA9".'prf':
336 case "\xA9".'req':
337 case "\xA9".'src':
338 case "\xA9".'swr':
339 case "\xA9".'too':
340 case "\xA9".'trk':
341 case "\xA9".'url':
342 case "\xA9".'wrn':
343 case "\xA9".'wrt':
344 case '----':
345 case 'aART':
346 case 'akID':
347 case 'apID':
348 case 'atID':
349 case 'catg':
350 case 'cmID':
351 case 'cnID':
352 case 'covr':
353 case 'cpil':
354 case 'cprt':
355 case 'desc':
356 case 'disk':
357 case 'egid':
358 case 'geID':
359 case 'gnre':
360 case 'hdvd':
361 case 'keyw':
362 case 'ldes':
363 case 'pcst':
364 case 'pgap':
365 case 'plID':
366 case 'purd':
367 case 'purl':
368 case 'rati':
369 case 'rndu':
370 case 'rpdu':
371 case 'rtng':
372 case 'sfID':
373 case 'soaa':
374 case 'soal':
375 case 'soar':
376 case 'soco':
377 case 'sonm':
378 case 'sosn':
379 case 'stik':
380 case 'tmpo':
381 case 'trkn':
382 case 'tven':
383 case 'tves':
384 case 'tvnn':
385 case 'tvsh':
386 case 'tvsn':
387 if ($atom_parent == 'udta') {
388
391 $atom_structure['data'] = substr($atom_data, 4);
392
394 if (empty(
$info[
'comments'][
'language']) || (!in_array($atom_structure[
'language'],
$info[
'comments'][
'language']))) {
395 $info[
'comments'][
'language'][] = $atom_structure[
'language'];
396 }
397 } else {
398
399 $atomoffset = 0;
400 if (substr($atom_data, 2, 2) == "\x10\xB5") {
401
402
403 while ($atomoffset < strlen($atom_data)) {
405 $boxsmalltype = substr($atom_data, $atomoffset + 2, 2);
406 $boxsmalldata = substr($atom_data, $atomoffset + 4, $boxsmallsize);
407 if ($boxsmallsize <= 1) {
408 $this->
warning(
'Invalid QuickTime atom smallbox size "'.$boxsmallsize.
'" in atom "'.preg_replace(
'#[^a-zA-Z0-9 _\\-]#',
'?', $atomname).
'" at offset: '.($atom_structure[
'offset'] + $atomoffset));
409 $atom_structure['data'] = null;
410 $atomoffset = strlen($atom_data);
411 break;
412 }
413 switch ($boxsmalltype) {
414 case "\x10\xB5":
415 $atom_structure['data'] = $boxsmalldata;
416 break;
417 default:
418 $this->
warning(
'Unknown QuickTime smallbox type: "'.preg_replace(
'#[^a-zA-Z0-9 _\\-]#',
'?', $boxsmalltype).
'" ('.trim(
getid3_lib::PrintHexBytes($boxsmalltype)).
') at offset '.$baseoffset);
419 $atom_structure['data'] = $atom_data;
420 break;
421 }
422 $atomoffset += (4 + $boxsmallsize);
423 }
424 } else {
425 while ($atomoffset < strlen($atom_data)) {
427 $boxtype = substr($atom_data, $atomoffset + 4, 4);
428 $boxdata = substr($atom_data, $atomoffset + 8, $boxsize - 8);
429 if ($boxsize <= 1) {
430 $this->
warning(
'Invalid QuickTime atom box size "'.$boxsize.
'" in atom "'.preg_replace(
'#[^a-zA-Z0-9 _\\-]#',
'?', $atomname).
'" at offset: '.($atom_structure[
'offset'] + $atomoffset));
431 $atom_structure['data'] = null;
432 $atomoffset = strlen($atom_data);
433 break;
434 }
435 $atomoffset += $boxsize;
436
437 switch ($boxtype) {
438 case 'mean':
439 case 'name':
440 $atom_structure[$boxtype] = substr($boxdata, 4);
441 break;
442
443 case 'data':
446 switch ($atom_structure['flags_raw']) {
447 case 0:
448 case 21:
449 switch ($atomname) {
450 case 'cpil':
451 case 'hdvd':
452 case 'pcst':
453 case 'pgap':
454
456 break;
457
458 case 'tmpo':
459
461 break;
462
463 case 'disk':
464 case 'trkn':
465
468 $atom_structure['data'] = empty($num) ? '' : $num;
469 $atom_structure['data'] .= empty($num_total) ? '' : '/'.$num_total;
470 break;
471
472 case 'gnre':
473
476 break;
477
478 case 'rtng':
479
482 break;
483
484 case 'stik':
485
488 break;
489
490 case 'sfID':
491
494 break;
495
496 case 'egid':
497 case 'purl':
498 $atom_structure['data'] = substr($boxdata, 8);
499 break;
500
501 case 'plID':
502
504 break;
505
506 case 'covr':
507 $atom_structure['data'] = substr($boxdata, 8);
508
509 if (preg_match('#^\\xFF\\xD8\\xFF#', $atom_structure['data'])) {
510 $atom_structure['image_mime'] = 'image/jpeg';
511 } elseif (preg_match('#^\\x89\\x50\\x4E\\x47\\x0D\\x0A\\x1A\\x0A#', $atom_structure['data'])) {
512 $atom_structure['image_mime'] = 'image/png';
513 } elseif (preg_match('#^GIF#', $atom_structure['data'])) {
514 $atom_structure['image_mime'] = 'image/gif';
515 }
516 break;
517
518 case 'atID':
519 case 'cnID':
520 case 'geID':
521 case 'tves':
522 case 'tvsn':
523 default:
524
526 }
527 break;
528
529 case 1:
530 case 13:
531 default:
532 $atom_structure['data'] = substr($boxdata, 8);
533 if ($atomname == 'covr') {
534
535 if (preg_match('#^\\xFF\\xD8\\xFF#', $atom_structure['data'])) {
536 $atom_structure['image_mime'] = 'image/jpeg';
537 } elseif (preg_match('#^\\x89\\x50\\x4E\\x47\\x0D\\x0A\\x1A\\x0A#', $atom_structure['data'])) {
538 $atom_structure['image_mime'] = 'image/png';
539 } elseif (preg_match('#^GIF#', $atom_structure['data'])) {
540 $atom_structure['image_mime'] = 'image/gif';
541 }
542 }
543 break;
544
545 }
546 break;
547
548 default:
549 $this->
warning(
'Unknown QuickTime box type: "'.preg_replace(
'#[^a-zA-Z0-9 _\\-]#',
'?', $boxtype).
'" ('.trim(
getid3_lib::PrintHexBytes($boxtype)).
') at offset '.$baseoffset);
550 $atom_structure['data'] = $atom_data;
551
552 }
553 }
554 }
555 }
557 break;
558
559
560 case 'play':
562
563 $info[
'quicktime'][
'autoplay'] = $atom_structure[
'autoplay'];
564 break;
565
566
567 case 'WLOC':
570 break;
571
572
573 case 'LOOP':
574 case 'SelO':
575 case 'AllF':
577 break;
578
579
580 case 'name':
581 case 'MCPS':
582 case '@PRM':
583 case '@PRQ':
584 $atom_structure['data'] = $atom_data;
585 break;
586
587
588 case 'cmvd':
589
590
592
593 $CompressedFileData = substr($atom_data, 4);
594 if ($UncompressedHeader = @gzuncompress($CompressedFileData)) {
596 } else {
597 $this->
warning(
'Error decompressing compressed MOV atom at offset '.$atom_structure[
'offset']);
598 }
599 break;
600
601
602 case 'dcom':
603 $atom_structure['compression_id'] = $atom_data;
605 break;
606
607
608 case 'rdrf':
611 $atom_structure['flags']['internal_data'] = (bool) ($atom_structure['flags_raw'] & 0x000001);
612
613 $atom_structure['reference_type_name'] = substr($atom_data, 4, 4);
615 switch ($atom_structure['reference_type_name']) {
616 case 'url ':
617 $atom_structure[
'url'] = $this->
NoNullString(substr($atom_data, 12));
618 break;
619
620 case 'alis':
621 $atom_structure['file_alias'] = substr($atom_data, 12);
622 break;
623
624 case 'rsrc':
625 $atom_structure['resource_alias'] = substr($atom_data, 12);
626 break;
627
628 default:
629 $atom_structure['data'] = substr($atom_data, 12);
630 break;
631 }
632 break;
633
634
635 case 'rmqu':
637 break;
638
639
640 case 'rmcs':
644 break;
645
646
647 case 'rmvc':
650 $atom_structure['gestalt_selector'] = substr($atom_data, 4, 4);
654 break;
655
656
657 case 'rmcd':
660 $atom_structure['component_type'] = substr($atom_data, 4, 4);
661 $atom_structure['component_subtype'] = substr($atom_data, 8, 4);
662 $atom_structure['component_manufacturer'] = substr($atom_data, 12, 4);
666 break;
667
668
669 case 'rmdr':
673
674 $atom_structure['data_rate_bps'] = $atom_structure['data_rate'] * 10;
675 break;
676
677
678 case 'rmla':
682
684 if (empty(
$info[
'comments'][
'language']) || (!in_array($atom_structure[
'language'],
$info[
'comments'][
'language']))) {
685 $info[
'comments'][
'language'][] = $atom_structure[
'language'];
686 }
687 break;
688
689
690 case 'rmla':
694 break;
695
696
697 case 'ptv ':
698
704
705 $atom_structure['flags']['play_on_open'] = (bool) $atom_structure['play_on_open_flag'];
706 $atom_structure['flags']['slide_show'] = (bool) $atom_structure['slide_show_flag'];
707
708 $ptv_lookup[0] = 'normal';
709 $ptv_lookup[1] = 'double';
710 $ptv_lookup[2] = 'half';
711 $ptv_lookup[3] = 'full';
712 $ptv_lookup[4] = 'current';
713 if (isset($ptv_lookup[$atom_structure['display_size_raw']])) {
714 $atom_structure['display_size'] = $ptv_lookup[$atom_structure['display_size_raw']];
715 } else {
716 $this->
warning(
'unknown "ptv " display constant ('.$atom_structure[
'display_size_raw'].
')');
717 }
718 break;
719
720
721 case 'stsd':
725 $stsdEntriesDataOffset = 8;
726 for (
$i = 0;
$i < $atom_structure[
'number_entries'];
$i++) {
727 $atom_structure[
'sample_description_table'][
$i][
'size'] =
getid3_lib::BigEndian2Int(substr($atom_data, $stsdEntriesDataOffset, 4));
728 $stsdEntriesDataOffset += 4;
729 $atom_structure[
'sample_description_table'][
$i][
'data_format'] = substr($atom_data, $stsdEntriesDataOffset, 4);
730 $stsdEntriesDataOffset += 4;
731 $atom_structure[
'sample_description_table'][
$i][
'reserved'] =
getid3_lib::BigEndian2Int(substr($atom_data, $stsdEntriesDataOffset, 6));
732 $stsdEntriesDataOffset += 6;
733 $atom_structure[
'sample_description_table'][
$i][
'reference_index'] =
getid3_lib::BigEndian2Int(substr($atom_data, $stsdEntriesDataOffset, 2));
734 $stsdEntriesDataOffset += 2;
735 $atom_structure[
'sample_description_table'][
$i][
'data'] = substr($atom_data, $stsdEntriesDataOffset, ($atom_structure[
'sample_description_table'][
$i][
'size'] - 4 - 4 - 6 - 2));
736 $stsdEntriesDataOffset += ($atom_structure[
'sample_description_table'][
$i][
'size'] - 4 - 4 - 6 - 2);
737
738 $atom_structure[
'sample_description_table'][
$i][
'encoder_version'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 0, 2));
739 $atom_structure[
'sample_description_table'][
$i][
'encoder_revision'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 2, 2));
740 $atom_structure[
'sample_description_table'][
$i][
'encoder_vendor'] = substr($atom_structure[
'sample_description_table'][
$i][
'data'], 4, 4);
741
742 switch ($atom_structure[
'sample_description_table'][
$i][
'encoder_vendor']) {
743
744 case "\x00\x00\x00\x00":
745
746 $atom_structure[
'sample_description_table'][
$i][
'audio_channels'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 8, 2));
747 $atom_structure[
'sample_description_table'][
$i][
'audio_bit_depth'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 10, 2));
748 $atom_structure[
'sample_description_table'][
$i][
'audio_compression_id'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 12, 2));
749 $atom_structure[
'sample_description_table'][
$i][
'audio_packet_size'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 14, 2));
750 $atom_structure[
'sample_description_table'][
$i][
'audio_sample_rate'] =
getid3_lib::FixedPoint16_16(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 16, 4));
751
752
753
754 $atom_structure[
'sample_description_table'][
$i][
'temporal_quality'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 8, 4));
755 $atom_structure[
'sample_description_table'][
$i][
'spatial_quality'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 12, 4));
756 $atom_structure[
'sample_description_table'][
$i][
'width'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 16, 2));
757 $atom_structure[
'sample_description_table'][
$i][
'height'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 18, 2));
758 $atom_structure[
'sample_description_table'][
$i][
'resolution_x'] =
getid3_lib::FixedPoint16_16(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 24, 4));
759 $atom_structure[
'sample_description_table'][
$i][
'resolution_y'] =
getid3_lib::FixedPoint16_16(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 28, 4));
760 $atom_structure[
'sample_description_table'][
$i][
'data_size'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 32, 4));
761 $atom_structure[
'sample_description_table'][
$i][
'frame_count'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 36, 2));
762 $atom_structure[
'sample_description_table'][
$i][
'compressor_name'] = substr($atom_structure[
'sample_description_table'][
$i][
'data'], 38, 4);
763 $atom_structure[
'sample_description_table'][
$i][
'pixel_depth'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 42, 2));
764 $atom_structure[
'sample_description_table'][
$i][
'color_table_id'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 44, 2));
765
766 switch ($atom_structure[
'sample_description_table'][
$i][
'data_format']) {
767 case '2vuY':
768 case 'avc1':
769 case 'cvid':
770 case 'dvc ':
771 case 'dvcp':
772 case 'gif ':
773 case 'h263':
774 case 'jpeg':
775 case 'kpcd':
776 case 'mjpa':
777 case 'mjpb':
778 case 'mp4v':
779 case 'png ':
780 case 'raw ':
781 case 'rle ':
782 case 'rpza':
783 case 'smc ':
784 case 'SVQ1':
785 case 'SVQ3':
786 case 'tiff':
787 case 'v210':
788 case 'v216':
789 case 'v308':
790 case 'v408':
791 case 'v410':
792 case 'yuv2':
793 $info[
'fileformat'] =
'mp4';
794 $info[
'video'][
'fourcc'] = $atom_structure[
'sample_description_table'][
$i][
'data_format'];
795
796
797if (!empty($atom_structure[
'sample_description_table'][
$i][
'width']) && !empty($atom_structure[
'sample_description_table'][
$i][
'height'])) {
798
799 $info[
'video'][
'resolution_x'] = $atom_structure[
'sample_description_table'][
$i][
'width'];
800 $info[
'video'][
'resolution_y'] = $atom_structure[
'sample_description_table'][
$i][
'height'];
801 $info[
'quicktime'][
'video'][
'resolution_x'] =
$info[
'video'][
'resolution_x'];
802 $info[
'quicktime'][
'video'][
'resolution_y'] =
$info[
'video'][
'resolution_y'];
803}
804 break;
805
806 case 'qtvr':
807 $info[
'video'][
'dataformat'] =
'quicktimevr';
808 break;
809
810 case 'mp4a':
811 default:
813 $info[
'quicktime'][
'audio'][
'sample_rate'] = $atom_structure[
'sample_description_table'][
$i][
'audio_sample_rate'];
814 $info[
'quicktime'][
'audio'][
'channels'] = $atom_structure[
'sample_description_table'][
$i][
'audio_channels'];
815 $info[
'quicktime'][
'audio'][
'bit_depth'] = $atom_structure[
'sample_description_table'][
$i][
'audio_bit_depth'];
816 $info[
'audio'][
'codec'] =
$info[
'quicktime'][
'audio'][
'codec'];
817 $info[
'audio'][
'sample_rate'] =
$info[
'quicktime'][
'audio'][
'sample_rate'];
818 $info[
'audio'][
'channels'] =
$info[
'quicktime'][
'audio'][
'channels'];
819 $info[
'audio'][
'bits_per_sample'] =
$info[
'quicktime'][
'audio'][
'bit_depth'];
820 switch ($atom_structure[
'sample_description_table'][
$i][
'data_format']) {
821 case 'raw ':
822 case 'alac':
823 $info[
'audio'][
'lossless'] =
true;
824 break;
825 default:
826 $info[
'audio'][
'lossless'] =
false;
827 break;
828 }
829 break;
830 }
831 break;
832
833 default:
834 switch ($atom_structure[
'sample_description_table'][
$i][
'data_format']) {
835 case 'mp4s':
836 $info[
'fileformat'] =
'mp4';
837 break;
838
839 default:
840
841 $atom_structure[
'sample_description_table'][
$i][
'video_temporal_quality'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 8, 4));
842 $atom_structure[
'sample_description_table'][
$i][
'video_spatial_quality'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 12, 4));
843 $atom_structure[
'sample_description_table'][
$i][
'video_frame_width'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 16, 2));
844 $atom_structure[
'sample_description_table'][
$i][
'video_frame_height'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 18, 2));
845 $atom_structure[
'sample_description_table'][
$i][
'video_resolution_x'] =
getid3_lib::FixedPoint16_16(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 20, 4));
846 $atom_structure[
'sample_description_table'][
$i][
'video_resolution_y'] =
getid3_lib::FixedPoint16_16(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 24, 4));
847 $atom_structure[
'sample_description_table'][
$i][
'video_data_size'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 28, 4));
848 $atom_structure[
'sample_description_table'][
$i][
'video_frame_count'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 32, 2));
849 $atom_structure[
'sample_description_table'][
$i][
'video_encoder_name_len'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 34, 1));
850 $atom_structure[
'sample_description_table'][
$i][
'video_encoder_name'] = substr($atom_structure[
'sample_description_table'][
$i][
'data'], 35, $atom_structure[
'sample_description_table'][
$i][
'video_encoder_name_len']);
851 $atom_structure[
'sample_description_table'][
$i][
'video_pixel_color_depth'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 66, 2));
852 $atom_structure[
'sample_description_table'][
$i][
'video_color_table_id'] =
getid3_lib::BigEndian2Int(substr($atom_structure[
'sample_description_table'][
$i][
'data'], 68, 2));
853
854 $atom_structure[
'sample_description_table'][
$i][
'video_pixel_color_type'] = (($atom_structure[
'sample_description_table'][
$i][
'video_pixel_color_depth'] > 32) ?
'grayscale' :
'color');
855 $atom_structure[
'sample_description_table'][
$i][
'video_pixel_color_name'] = $this->
QuicktimeColorNameLookup($atom_structure[
'sample_description_table'][
$i][
'video_pixel_color_depth']);
856
857 if ($atom_structure[
'sample_description_table'][
$i][
'video_pixel_color_name'] !=
'invalid') {
858 $info[
'quicktime'][
'video'][
'codec_fourcc'] = $atom_structure[
'sample_description_table'][
$i][
'data_format'];
860 $info[
'quicktime'][
'video'][
'codec'] = (($atom_structure[
'sample_description_table'][
$i][
'video_encoder_name_len'] > 0) ? $atom_structure[
'sample_description_table'][
$i][
'video_encoder_name'] : $atom_structure[
'sample_description_table'][
$i][
'data_format']);
861 $info[
'quicktime'][
'video'][
'color_depth'] = $atom_structure[
'sample_description_table'][
$i][
'video_pixel_color_depth'];
862 $info[
'quicktime'][
'video'][
'color_depth_name'] = $atom_structure[
'sample_description_table'][
$i][
'video_pixel_color_name'];
863
864 $info[
'video'][
'codec'] =
$info[
'quicktime'][
'video'][
'codec'];
865 $info[
'video'][
'bits_per_sample'] =
$info[
'quicktime'][
'video'][
'color_depth'];
866 }
867 $info[
'video'][
'lossless'] =
false;
868 $info[
'video'][
'pixel_aspect_ratio'] = (float) 1;
869 break;
870 }
871 break;
872 }
873 switch (strtolower($atom_structure[
'sample_description_table'][
$i][
'data_format'])) {
874 case 'mp4a':
875 $info[
'audio'][
'dataformat'] =
'mp4';
876 $info[
'quicktime'][
'audio'][
'codec'] =
'mp4';
877 break;
878
879 case '3ivx':
880 case '3iv1':
881 case '3iv2':
882 $info[
'video'][
'dataformat'] =
'3ivx';
883 break;
884
885 case 'xvid':
886 $info[
'video'][
'dataformat'] =
'xvid';
887 break;
888
889 case 'mp4v':
890 $info[
'video'][
'dataformat'] =
'mpeg4';
891 break;
892
893 case 'divx':
894 case 'div1':
895 case 'div2':
896 case 'div3':
897 case 'div4':
898 case 'div5':
899 case 'div6':
900 $info[
'video'][
'dataformat'] =
'divx';
901 break;
902
903 default:
904
905 break;
906 }
907 unset($atom_structure[
'sample_description_table'][
$i][
'data']);
908 }
909 break;
910
911
912 case 'stts':
916 $sttsEntriesDataOffset = 8;
917
918 $frames_count = 0;
919
920 $max_stts_entries_to_scan = (
$info[
'php_memory_limit'] ? min(floor($this->getid3->memory_limit / 10000), $atom_structure[
'number_entries']) : $atom_structure[
'number_entries']);
921 if ($max_stts_entries_to_scan < $atom_structure['number_entries']) {
922 $this->
warning(
'QuickTime atom "stts" has '.$atom_structure[
'number_entries'].
' but only scanning the first '.$max_stts_entries_to_scan.
' entries due to limited PHP memory available ('.floor($atom_structure[
'number_entries'] / 1048576).
'MB).');
923 }
924 for (
$i = 0;
$i < $max_stts_entries_to_scan;
$i++) {
925 $atom_structure[
'time_to_sample_table'][
$i][
'sample_count'] =
getid3_lib::BigEndian2Int(substr($atom_data, $sttsEntriesDataOffset, 4));
926 $sttsEntriesDataOffset += 4;
927 $atom_structure[
'time_to_sample_table'][
$i][
'sample_duration'] =
getid3_lib::BigEndian2Int(substr($atom_data, $sttsEntriesDataOffset, 4));
928 $sttsEntriesDataOffset += 4;
929
930 $frames_count += $atom_structure[
'time_to_sample_table'][
$i][
'sample_count'];
931
932
933
934
935
936
937
938
939
940
941
942 }
943 $info[
'quicktime'][
'stts_framecount'][] = $frames_count;
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961 break;
962
963
964 case 'stss':
969 $stssEntriesDataOffset = 8;
970 for (
$i = 0;
$i < $atom_structure[
'number_entries'];
$i++) {
972 $stssEntriesDataOffset += 4;
973 }
974 }
975 break;
976
977
978 case 'stsc':
983 $stscEntriesDataOffset = 8;
984 for (
$i = 0;
$i < $atom_structure[
'number_entries'];
$i++) {
985 $atom_structure[
'sample_to_chunk_table'][
$i][
'first_chunk'] =
getid3_lib::BigEndian2Int(substr($atom_data, $stscEntriesDataOffset, 4));
986 $stscEntriesDataOffset += 4;
987 $atom_structure[
'sample_to_chunk_table'][
$i][
'samples_per_chunk'] =
getid3_lib::BigEndian2Int(substr($atom_data, $stscEntriesDataOffset, 4));
988 $stscEntriesDataOffset += 4;
989 $atom_structure[
'sample_to_chunk_table'][
$i][
'sample_description'] =
getid3_lib::BigEndian2Int(substr($atom_data, $stscEntriesDataOffset, 4));
990 $stscEntriesDataOffset += 4;
991 }
992 }
993 break;
994
995
996 case 'stsz':
1002 $stszEntriesDataOffset = 12;
1003 if ($atom_structure['sample_size'] == 0) {
1004 for (
$i = 0;
$i < $atom_structure[
'number_entries'];
$i++) {
1006 $stszEntriesDataOffset += 4;
1007 }
1008 }
1009 }
1010 break;
1011
1012
1013 case 'stco':
1018 $stcoEntriesDataOffset = 8;
1019 for (
$i = 0;
$i < $atom_structure[
'number_entries'];
$i++) {
1021 $stcoEntriesDataOffset += 4;
1022 }
1023 }
1024 break;
1025
1026
1027 case 'co64':
1032 $stcoEntriesDataOffset = 8;
1033 for (
$i = 0;
$i < $atom_structure[
'number_entries'];
$i++) {
1035 $stcoEntriesDataOffset += 8;
1036 }
1037 }
1038 break;
1039
1040
1041 case 'dref':
1045 $drefDataOffset = 8;
1046 for (
$i = 0;
$i < $atom_structure[
'number_entries'];
$i++) {
1048 $drefDataOffset += 4;
1049 $atom_structure[
'data_references'][
$i][
'type'] = substr($atom_data, $drefDataOffset, 4);
1050 $drefDataOffset += 4;
1052 $drefDataOffset += 1;
1054 $drefDataOffset += 3;
1055 $atom_structure[
'data_references'][
$i][
'data'] = substr($atom_data, $drefDataOffset, ($atom_structure[
'data_references'][
$i][
'size'] - 4 - 4 - 1 - 3));
1056 $drefDataOffset += ($atom_structure[
'data_references'][
$i][
'size'] - 4 - 4 - 1 - 3);
1057
1058 $atom_structure[
'data_references'][
$i][
'flags'][
'self_reference'] = (bool) ($atom_structure[
'data_references'][
$i][
'flags_raw'] & 0x001);
1059 }
1060 break;
1061
1062
1063 case 'gmin':
1072 break;
1073
1074
1075 case 'smhd':
1080 break;
1081
1082
1083 case 'vmhd':
1090
1091 $atom_structure['flags']['no_lean_ahead'] = (bool) ($atom_structure['flags_raw'] & 0x001);
1092 break;
1093
1094
1095 case 'hdlr':
1098 $atom_structure['component_type'] = substr($atom_data, 4, 4);
1099 $atom_structure['component_subtype'] = substr($atom_data, 8, 4);
1100 $atom_structure['component_manufacturer'] = substr($atom_data, 12, 4);
1103 $atom_structure[
'component_name'] = $this->
Pascal2String(substr($atom_data, 24));
1104
1105 if (($atom_structure['component_subtype'] == 'STpn') && ($atom_structure['component_manufacturer'] == 'zzzz')) {
1106 $info[
'video'][
'dataformat'] =
'quicktimevr';
1107 }
1108 break;
1109
1110
1111 case 'mdhd':
1120
1121 if ($atom_structure['time_scale'] == 0) {
1122 $this->
error(
'Corrupt Quicktime file: mdhd.time_scale == zero');
1123 return false;
1124 }
1125 $info[
'quicktime'][
'time_scale'] = ((isset(
$info[
'quicktime'][
'time_scale']) && (
$info[
'quicktime'][
'time_scale'] < 1000)) ? max(
$info[
'quicktime'][
'time_scale'], $atom_structure[
'time_scale']) : $atom_structure[
'time_scale']);
1126
1129 $atom_structure['playtime_seconds'] = $atom_structure['duration'] / $atom_structure['time_scale'];
1131 if (empty(
$info[
'comments'][
'language']) || (!in_array($atom_structure[
'language'],
$info[
'comments'][
'language']))) {
1132 $info[
'comments'][
'language'][] = $atom_structure[
'language'];
1133 }
1134 break;
1135
1136
1137 case 'pnot':
1140 $atom_structure['atom_type'] = substr($atom_data, 6, 4);
1142
1144 break;
1145
1146
1147 case 'crgn':
1150 $atom_structure['clipping_data'] = substr($atom_data, 10);
1151 break;
1152
1153
1154 case 'load':
1159
1160 $atom_structure['default_hints']['double_buffer'] = (bool) ($atom_structure['default_hints_raw'] & 0x0020);
1161 $atom_structure['default_hints']['high_quality'] = (bool) ($atom_structure['default_hints_raw'] & 0x0100);
1162 break;
1163
1164
1165 case 'tmcd':
1166 case 'chap':
1167 case 'sync':
1168 case 'scpt':
1169 case 'ssrc':
1170 for (
$i = 0;
$i < strlen($atom_data);
$i += 4) {
1172 }
1173 break;
1174
1175
1176 case 'elst':
1180 for (
$i = 0;
$i < $atom_structure[
'number_entries'];
$i++ ) {
1184 }
1185 break;
1186
1187
1188 case 'kmat':
1191 $atom_structure['matte_data_raw'] = substr($atom_data, 4);
1192 break;
1193
1194
1195 case 'ctab':
1199 for ($colortableentry = 0; $colortableentry < $atom_structure['color_table_size']; $colortableentry++) {
1200 $atom_structure[
'color_table'][$colortableentry][
'alpha'] =
getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($colortableentry * 8) + 0, 2));
1201 $atom_structure[
'color_table'][$colortableentry][
'red'] =
getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($colortableentry * 8) + 2, 2));
1202 $atom_structure[
'color_table'][$colortableentry][
'green'] =
getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($colortableentry * 8) + 4, 2));
1203 $atom_structure[
'color_table'][$colortableentry][
'blue'] =
getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($colortableentry * 8) + 6, 2));
1204 }
1205 break;
1206
1207
1208 case 'mvhd':
1217 $atom_structure['reserved'] = substr($atom_data, 26, 10);
1234
1235 if ($atom_structure['time_scale'] == 0) {
1236 $this->
error(
'Corrupt Quicktime file: mvhd.time_scale == zero');
1237 return false;
1238 }
1241 $info[
'quicktime'][
'time_scale'] = ((isset(
$info[
'quicktime'][
'time_scale']) && (
$info[
'quicktime'][
'time_scale'] < 1000)) ? max(
$info[
'quicktime'][
'time_scale'], $atom_structure[
'time_scale']) : $atom_structure[
'time_scale']);
1242 $info[
'quicktime'][
'display_scale'] = $atom_structure[
'matrix_a'];
1243 $info[
'playtime_seconds'] = $atom_structure[
'duration'] / $atom_structure[
'time_scale'];
1244 break;
1245
1246
1247 case 'tkhd':
1260
1261
1273 $atom_structure['flags']['enabled'] = (bool) ($atom_structure['flags_raw'] & 0x0001);
1274 $atom_structure['flags']['in_movie'] = (bool) ($atom_structure['flags_raw'] & 0x0002);
1275 $atom_structure['flags']['in_preview'] = (bool) ($atom_structure['flags_raw'] & 0x0004);
1276 $atom_structure['flags']['in_poster'] = (bool) ($atom_structure['flags_raw'] & 0x0008);
1279
1280 if ($atom_structure['flags']['enabled'] == 1) {
1281 if (!isset(
$info[
'video'][
'resolution_x']) || !isset(
$info[
'video'][
'resolution_y'])) {
1282 $info[
'video'][
'resolution_x'] = $atom_structure[
'width'];
1283 $info[
'video'][
'resolution_y'] = $atom_structure[
'height'];
1284 }
1285 $info[
'video'][
'resolution_x'] = max(
$info[
'video'][
'resolution_x'], $atom_structure[
'width']);
1286 $info[
'video'][
'resolution_y'] = max(
$info[
'video'][
'resolution_y'], $atom_structure[
'height']);
1287 $info[
'quicktime'][
'video'][
'resolution_x'] =
$info[
'video'][
'resolution_x'];
1288 $info[
'quicktime'][
'video'][
'resolution_y'] =
$info[
'video'][
'resolution_y'];
1289 } else {
1290
1291
1292
1293
1294 }
1295 break;
1296
1297
1298 case 'iods':
1299
1300
1301 $offset = 0;
1303 $offset += 1;
1305 $offset += 3;
1307 $offset += 1;
1309
1311 $offset += 2;
1313 $offset += 1;
1315 $offset += 1;
1317 $offset += 1;
1319 $offset += 1;
1321 $offset += 1;
1322
1323 $atom_structure['num_iods_tracks'] = ($atom_structure['length'] - 7) / 6;
1324 for (
$i = 0;
$i < $atom_structure[
'num_iods_tracks'];
$i++) {
1326 $offset += 1;
1328
1330 $offset += 4;
1331 }
1332
1335 break;
1336
1337 case 'ftyp':
1338 $atom_structure['signature'] = substr($atom_data, 0, 4);
1340 $atom_structure['fourcc'] = substr($atom_data, 8, 4);
1341 break;
1342
1343 case 'mdat':
1344
1345
1346
1347
1348
1349 $mdat_offset = 0;
1350 while (true) {
1351 if (substr($atom_data, $mdat_offset, 8) == "\x00\x00\x00\x08".'wide') {
1352 $mdat_offset += 8;
1353 } elseif (substr($atom_data, $mdat_offset, 8) == "\x00\x00\x00\x00".'mdat') {
1354 $mdat_offset += 8;
1355 } else {
1356 break;
1357 }
1358 }
1359
1360
1361 while (($mdat_offset < (strlen($atom_data) - 8))
1363 && ($chapter_string_length < 1000)
1364 && ($chapter_string_length <= (strlen($atom_data) - $mdat_offset - 2))
1365 && preg_match('#^([\x00-\xFF]{2})([\x20-\xFF]+)$#', substr($atom_data, $mdat_offset, $chapter_string_length + 2), $chapter_matches)) {
1366 list($dummy, $chapter_string_length_hex, $chapter_string) = $chapter_matches;
1367 $mdat_offset += (2 + $chapter_string_length);
1368 @
$info[
'quicktime'][
'comments'][
'chapters'][] = $chapter_string;
1369
1370
1371 if (substr($atom_data, $mdat_offset, 12) == "\x00\x00\x00\x0C\x65\x6E\x63\x64\x00\x00\x01\x00") {
1372 $mdat_offset += 12;
1373 }
1374 }
1375
1376
1377 if (($atomsize > 8) && (!isset(
$info[
'avdataend_tmp']) || (
$info[
'quicktime'][$atomname][
'size'] > (
$info[
'avdataend_tmp'] -
$info[
'avdataoffset'])))) {
1378
1379 $info[
'avdataoffset'] = $atom_structure[
'offset'] + 8;
1380 $OldAVDataEnd =
$info[
'avdataend'];
1381 $info[
'avdataend'] = $atom_structure[
'offset'] + $atom_structure[
'size'];
1382
1383 $getid3_temp =
new getID3();
1384 $getid3_temp->openfile($this->getid3->filename);
1385 $getid3_temp->info[
'avdataoffset'] =
$info[
'avdataoffset'];
1386 $getid3_temp->info[
'avdataend'] =
$info[
'avdataend'];
1388 if ($getid3_mp3->MPEGaudioHeaderValid($getid3_mp3->MPEGaudioHeaderDecode($this->fread(4)))) {
1389 $getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false);
1390 if (!empty($getid3_temp->info['warning'])) {
1391 foreach ($getid3_temp->info['warning'] as $value) {
1393 }
1394 }
1395 if (!empty($getid3_temp->info['mpeg'])) {
1396 $info[
'mpeg'] = $getid3_temp->info[
'mpeg'];
1397 if (isset(
$info[
'mpeg'][
'audio'])) {
1398 $info[
'audio'][
'dataformat'] =
'mp3';
1399 $info[
'audio'][
'codec'] = (!empty(
$info[
'mpeg'][
'audio'][
'encoder']) ?
$info[
'mpeg'][
'audio'][
'encoder'] : (!empty(
$info[
'mpeg'][
'audio'][
'codec']) ?
$info[
'mpeg'][
'audio'][
'codec'] : (!empty(
$info[
'mpeg'][
'audio'][
'LAME']) ?
'LAME' :
'mp3')));
1400 $info[
'audio'][
'sample_rate'] =
$info[
'mpeg'][
'audio'][
'sample_rate'];
1401 $info[
'audio'][
'channels'] =
$info[
'mpeg'][
'audio'][
'channels'];
1402 $info[
'audio'][
'bitrate'] =
$info[
'mpeg'][
'audio'][
'bitrate'];
1403 $info[
'audio'][
'bitrate_mode'] = strtolower(
$info[
'mpeg'][
'audio'][
'bitrate_mode']);
1404 $info[
'bitrate'] =
$info[
'audio'][
'bitrate'];
1405 }
1406 }
1407 }
1408 unset($getid3_mp3, $getid3_temp);
1409 $info[
'avdataend'] = $OldAVDataEnd;
1410 unset($OldAVDataEnd);
1411
1412 }
1413
1414 unset($mdat_offset, $chapter_string_length, $chapter_matches);
1415 break;
1416
1417 case 'free':
1418 case 'skip':
1419 case 'wide':
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429 break;
1430
1431
1432 case 'nsav':
1433
1435 break;
1436
1437 case 'ctyp':
1438
1439
1440
1441
1442 $atom_structure['ctyp'] = substr($atom_data, 0, 4);
1443 $info[
'quicktime'][
'controller'] = $atom_structure[
'ctyp'];
1444 switch ($atom_structure['ctyp']) {
1445 case 'qtvr':
1446 $info[
'video'][
'dataformat'] =
'quicktimevr';
1447 break;
1448 }
1449 break;
1450
1451 case 'pano':
1453 break;
1454
1455 case 'hint':
1456 case 'hinf':
1457 case 'hinv':
1458 case 'hnti':
1459 $info[
'quicktime'][
'hinting'] =
true;
1460 break;
1461
1462 case 'imgt':
1463 for (
$i = 0;
$i < ($atom_structure[
'size'] - 8);
$i += 4) {
1465 }
1466 break;
1467
1468
1469
1470 case 'FXTC':
1471 case 'PrmA':
1472 case 'code':
1473 case 'FIEL':
1474 case 'tapt':
1475
1476
1477
1478 case 'ctts':
1479 case 'cslg':
1480 case 'sdtp':
1481 case 'stps':
1482
1483 break;
1484
1485 case "\xA9".'xyz':
1486 $atom_structure['data'] = $atom_data;
1487 if (preg_match('#([\\+\\-][0-9\\.]+)([\\+\\-][0-9\\.]+)([\\+\\-][0-9\\.]+)?/$#i', $atom_data, $matches)) {
1488 @list($all, $latitude, $longitude, $altitude) = $matches;
1489 $info[
'quicktime'][
'comments'][
'gps_latitude'][] = floatval($latitude);
1490 $info[
'quicktime'][
'comments'][
'gps_longitude'][] = floatval($longitude);
1491 if (!empty($altitude)) {
1492 $info[
'quicktime'][
'comments'][
'gps_altitude'][] = floatval($altitude);
1493 }
1494 } else {
1495 $this->
warning(
'QuickTime atom "©xyz" data does not match expected data pattern at offset '.$baseoffset.
'. Please report as getID3() bug.');
1496 }
1497 break;
1498
1499 case 'NCDT':
1500
1501
1503 break;
1504 case 'NCTH':
1505 case 'NCVW':
1506
1507 if (preg_match('/^\xFF\xD8\xFF/', $atom_data)) {
1508 $atom_structure['data'] = $atom_data;
1509 $atom_structure['image_mime'] = 'image/jpeg';
1510 $atom_structure['description'] = (($atomname == 'NCTH') ? 'Nikon Camera Thumbnail Image' : (($atomname == 'NCVW') ? 'Nikon Camera Preview Image' : 'Nikon preview image'));
1511 $info[
'quicktime'][
'comments'][
'picture'][] = array(
'image_mime'=>$atom_structure[
'image_mime'],
'data'=>$atom_data,
'description'=>$atom_structure[
'description']);
1512 }
1513 break;
1514 case 'NCTG':
1516 break;
1517 case 'NCHD':
1518 case 'NCDB':
1519 case 'CNCV':
1520 $atom_structure['data'] = $atom_data;
1521 break;
1522
1523 case "\x00\x00\x00\x00":
1524
1525
1526
1527
1531
1532 break;
1533
1534 case 'meta':
1535
1536
1540 break;
1541
1542 case 'data':
1543 static $metaDATAkey = 1;
1544
1545 $atom_structure['language'] = substr($atom_data, 4 + 0, 2);
1547 $atom_structure['data'] = substr($atom_data, 4 + 4);
1548 $atom_structure[
'key_name'] = @
$info[
'quicktime'][
'temp_meta_key_names'][$metaDATAkey++];
1549
1550 if ($atom_structure['key_name'] && $atom_structure['data']) {
1551 @
$info[
'quicktime'][
'comments'][str_replace(
'com.apple.quicktime.',
'', $atom_structure[
'key_name'])][] = $atom_structure[
'data'];
1552 }
1553 break;
1554
1555 case 'keys':
1556
1557
1558
1562 $keys_atom_offset = 8;
1563 for (
$i = 1;
$i <= $atom_structure[
'entry_count'];
$i++) {
1565 $atom_structure[
'keys'][
$i][
'key_namespace'] = substr($atom_data, $keys_atom_offset + 4, 4);
1566 $atom_structure[
'keys'][
$i][
'key_value'] = substr($atom_data, $keys_atom_offset + 8, $atom_structure[
'keys'][
$i][
'key_size'] - 8);
1567 $keys_atom_offset += $atom_structure[
'keys'][
$i][
'key_size'];
1568
1569 $info[
'quicktime'][
'temp_meta_key_names'][
$i] = $atom_structure[
'keys'][
$i][
'key_value'];
1570 }
1571 break;
1572
1573 default:
1574 $this->
warning(
'Unknown QuickTime atom type: "'.preg_replace(
'#[^a-zA-Z0-9 _\\-]#',
'?', $atomname).
'" ('.trim(
getid3_lib::PrintHexBytes($atomname)).
') at offset '.$baseoffset);
1575 $atom_structure['data'] = $atom_data;
1576 break;
1577 }
1578 array_pop($atomHierarchy);
1579 return $atom_structure;
1580 }
static LookupGenreName($genreid, $allowSCMPXextended=true)
static FixedPoint8_8($rawdata)
static PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8')
static FixedPoint2_30($rawdata)
static FixedPoint16_16($rawdata)
static DateMac2Unix($macdate)
QuicktimeParseNikonNCTG($atom_data)
QuicktimeVideoCodecLookup($codecid)
QuicktimeIODSvideoProfileName($video_profile_id)
QuicktimeContentRatingLookup($rtng)
NoNullString($nullterminatedstring)
CopyToAppropriateCommentsSection($keyname, $data, $boxname='')
quicktime_read_mp4_descr_length($data, &$offset)
QuicktimeAudioCodecLookup($codecid)
QuicktimeColorNameLookup($colordepthid)
QuicktimeSTIKLookup($stik)
QuicktimeIODSaudioProfileName($audio_profile_id)
QuicktimeParseContainerAtom($atom_data, $baseoffset, &$atomHierarchy, $ParseAllPossibleAtoms)
QuicktimeLanguageLookup($languageid)
QuicktimeDCOMLookup($compressionid)
Pascal2String($pascalstring)
QuicktimeStoreFrontCodeLookup($sfid)