129 {
130
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':
140 case 'trak':
141 case 'clip':
142 case 'matt':
143 case 'edts':
144 case 'tref':
145 case 'mdia':
146 case 'minf':
147 case 'dinf':
148 case 'udta':
149 case 'stbl':
150 case 'cmov':
151 case 'rmra':
152 case 'rmda':
153 case 'gmhd':
154 $atomstructure[
'subatoms'] = $this->
QuicktimeParseContainerAtom($atomdata, $ThisFileInfo, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
155 break;
156
157
158 case '©cpy':
159 case '©day':
160 case '©dir':
161 case '©ed1':
162 case '©ed2':
163 case '©ed3':
164 case '©ed4':
165 case '©ed5':
166 case '©ed6':
167 case '©ed7':
168 case '©ed8':
169 case '©ed9':
170 case '©fmt':
171 case '©inf':
172 case '©prd':
173 case '©prf':
174 case '©req':
175 case '©src':
176 case '©wrt':
177 case '©nam':
178 case '©cmt':
179 case '©wrn':
180 case '©hst':
181 case '©mak':
182 case '©mod':
183 case '©PRD':
184 case '©swr':
185 case '©aut':
186 case '©ART':
187 case '©trk':
188 case '©alb':
189 case '©com':
190 case '©gen':
191 case '©ope':
192 case '©url':
193 case '©enc':
196 $atomstructure['data'] = substr($atomdata, 4);
197
199 if (empty($ThisFileInfo['comments']['language']) || (!in_array($atomstructure['language'], $ThisFileInfo['comments']['language']))) {
200 $ThisFileInfo['comments']['language'][] = $atomstructure['language'];
201 }
203 break;
204
205
206 case 'play':
208
209 $ThisFileInfo['quicktime']['autoplay'] = $atomstructure['autoplay'];
210 break;
211
212
213 case 'WLOC':
216 break;
217
218
219 case 'LOOP':
220 case 'SelO':
221 case 'AllF':
223 break;
224
225
226 case 'name':
227 case 'MCPS':
228 case '@PRM':
229 case '@PRQ':
230 $atomstructure['data'] = $atomdata;
231 break;
232
233
234 case 'cmvd':
235
236
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':
249 $atomstructure['compression_id'] = $atomdata;
251 break;
252
253
254 case 'rdrf':
257 $atomstructure['flags']['internal_data'] = (bool) ($atomstructure['flags_raw'] & 0x000001);
258
259 $atomstructure['reference_type_name'] = substr($atomdata, 4, 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':
283 break;
284
285
286 case 'rmcs':
290 break;
291
292
293 case 'rmvc':
296 $atomstructure['gestalt_selector'] = substr($atomdata, 4, 4);
300 break;
301
302
303 case 'rmcd':
306 $atomstructure['component_type'] = substr($atomdata, 4, 4);
307 $atomstructure['component_subtype'] = substr($atomdata, 8, 4);
308 $atomstructure['component_manufacturer'] = substr($atomdata, 12, 4);
312 break;
313
314
315 case 'rmdr':
319
320 $atomstructure['data_rate_bps'] = $atomstructure['data_rate'] * 10;
321 break;
322
323
324 case 'rmla':
328
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':
340 break;
341
342
343 case 'ptv ':
344
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':
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
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 ':
420 case 'alac':
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
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
503 break;
504 }
505 unset($atomstructure['sample_description_table'][$i]['data']);
506 }
507 break;
508
509
510 case 'stts':
511
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']) && (@$atomstructure['time_to_sample_table'][$i]['sample_duration'] > 0)) {
524 $stts_new_framerate = $ThisFileInfo['quicktime']['time_scale'] / $atomstructure['time_to_sample_table'][$i]['sample_duration'];
525 if ($stts_new_framerate <= 60) {
526
527 $ThisFileInfo['video']['frame_rate'] = max(@$ThisFileInfo['video']['frame_rate'], $stts_new_framerate);
528 }
529 }
530
531 }
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550 break;
551
552
553 case 'stss':
554 if ($ParseAllPossibleAtoms) {
558 $stssEntriesDataOffset = 8;
559 for ($i = 0; $i < $atomstructure['number_entries']; $i++) {
561 $stssEntriesDataOffset += 4;
562 }
563 }
564 break;
565
566
567 case 'stsc':
568 if ($ParseAllPossibleAtoms) {
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':
586 if ($ParseAllPossibleAtoms) {
591 $stszEntriesDataOffset = 12;
592 if ($atomstructure['sample_size'] == 0) {
593 for ($i = 0; $i < $atomstructure['number_entries']; $i++) {
595 $stszEntriesDataOffset += 4;
596 }
597 }
598 }
599 break;
600
601
602 case 'stco':
603 if ($ParseAllPossibleAtoms) {
607 $stcoEntriesDataOffset = 8;
608 for ($i = 0; $i < $atomstructure['number_entries']; $i++) {
610 $stcoEntriesDataOffset += 4;
611 }
612 }
613 break;
614
615
616 case 'dref':
620 $drefDataOffset = 8;
621 for ($i = 0; $i < $atomstructure['number_entries']; $i++) {
623 $drefDataOffset += 4;
624 $atomstructure['data_references'][$i]['type'] = substr($atomdata, $drefDataOffset, 4);
625 $drefDataOffset += 4;
627 $drefDataOffset += 1;
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':
647 break;
648
649
650 case 'smhd':
655 break;
656
657
658 case 'vmhd':
665
666 $atomstructure['flags']['no_lean_ahead'] = (bool) ($atomstructure['flags_raw'] & 0x001);
667 break;
668
669
670 case 'hdlr':
673 $atomstructure['component_type'] = substr($atomdata, 4, 4);
674 $atomstructure['component_subtype'] = substr($atomdata, 8, 4);
675 $atomstructure['component_manufacturer'] = substr($atomdata, 12, 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':
695
696 if ($atomstructure['time_scale'] == 0) {
697 $ThisFileInfo['error'][] = 'Corrupt Quicktime file: mdhd.time_scale == zero';
698 return false;
699 }
702 $atomstructure['playtime_seconds'] = $atomstructure['duration'] / $atomstructure['time_scale'];
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':
713 $atomstructure['atom_type'] = substr($atomdata, 6, 4);
715
717 break;
718
719
720 case 'crgn':
723 $atomstructure['clipping_data'] = substr($atomdata, 10);
724 break;
725
726
727 case 'load':
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':
739 case 'chap':
740 case 'sync':
741 case 'scpt':
742 case 'ssrc':
743 for ($i = 0; $i < (strlen($atomdata) % 4); $i++) {
745 }
746 break;
747
748
749 case 'elst':
753 for ($i = 0; $i < $atomstructure['number_entries']; $i++ ) {
757 }
758 break;
759
760
761 case 'kmat':
764 $atomstructure['matte_data_raw'] = substr($atomdata, 4);
765 break;
766
767
768 case 'ctab':
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':
790 $atomstructure['reserved'] = substr($atomdata, 26, 10);
807
808 if ($atomstructure['time_scale'] == 0) {
809 $ThisFileInfo['error'][] = 'Corrupt Quicktime file: mvhd.time_scale == zero';
810 return false;
811 }
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':
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);
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':
872
873 $NextTagPosition = strpos($atomdata, '©');
874 while ($NextTagPosition < strlen($atomdata)) {
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
885 }
886 break;
887
888 case 'ftyp':
889 $atomstructure['signature'] = substr($atomdata, 0, 4);
891 $atomstructure['fourcc'] = substr($atomdata, 8, 4);
892 break;
893
894 case 'mdat':
895 case 'free':
896 case 'skip':
897 case 'wide':
898
899
900
901
902
903
904
905
906
907
908 break;
909
910
911 case 'nsav':
912
914 break;
915
916 case 'ctyp':
917
918
919
920
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':
931 break;
932
933 case 'hint':
934 case 'hinf':
935 case 'hinv':
936 case 'hnti':
937 $ThisFileInfo['quicktime']['hinting'] = true;
938 break;
939
940 case 'imgt':
941 for ($i = 0; $i < ($atomstructure['size'] - 8); $i += 4) {
943 }
944 break;
945
946 case 'FXTC':
947 case 'PrmA':
948 case 'code':
949 case 'FIEL':
950
951
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 }
FixedPoint16_16($rawdata)
QuicktimeVideoCodecLookup($codecid)
NoNullString($nullterminatedstring)
QuicktimeAudioCodecLookup($codecid)
QuicktimeColorNameLookup($colordepthid)
QuicktimeLanguageLookup($languageid)
CopyToAppropriateCommentsSection($keyname, $data, &$ThisFileInfo)
QuicktimeDCOMLookup($compressionid)
Pascal2String($pascalstring)
QuicktimeParseContainerAtom($atomdata, &$ThisFileInfo, $baseoffset, &$atomHierarchy, $ParseAllPossibleAtoms)