- Timestamp:
- 07/02/2020 03:46:17 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/ID3/module.audio-video.quicktime.php
r47902 r48278 16 16 ///////////////////////////////////////////////////////////////// 17 17 18 if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers 19 exit; 20 } 18 21 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true); 19 22 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true); // needed for ISO 639-2 language code lookup … … 56 59 } 57 60 58 $info['quicktime'][$atomname]['name'] = $atomname;59 $info['quicktime'][$atomname]['size'] = $atomsize;60 $info['quicktime'][$atomname]['offset'] = $offset;61 62 61 if (($offset + $atomsize) > $info['avdataend']) { 62 $info['quicktime'][$atomname]['name'] = $atomname; 63 $info['quicktime'][$atomname]['size'] = $atomsize; 64 $info['quicktime'][$atomname]['offset'] = $offset; 63 65 $this->error('Atom at offset '.$offset.' claims to go beyond end-of-file (length: '.$atomsize.' bytes)'); 64 66 return false; 65 67 } 66 67 68 if ($atomsize == 0) { 68 69 // Furthermore, for historical reasons the list of atoms is optionally 69 70 // terminated by a 32-bit integer set to 0. If you are writing a program 70 71 // to read user data atoms, you should allow for the terminating 0. 72 $info['quicktime'][$atomname]['name'] = $atomname; 73 $info['quicktime'][$atomname]['size'] = $atomsize; 74 $info['quicktime'][$atomname]['offset'] = $offset; 71 75 break; 72 76 } 77 73 78 $atomHierarchy = array(); 74 $info['quicktime'][$atomname] = $this->QuicktimeParseAtom($atomname, $atomsize, $this->fread(min($atomsize, $atom_data_read_buffer_size)), $offset, $atomHierarchy, $this->ParseAllPossibleAtoms); 79 $parsedAtomData = $this->QuicktimeParseAtom($atomname, $atomsize, $this->fread(min($atomsize, $atom_data_read_buffer_size)), $offset, $atomHierarchy, $this->ParseAllPossibleAtoms); 80 $parsedAtomData['name'] = $atomname; 81 $parsedAtomData['size'] = $atomsize; 82 $parsedAtomData['offset'] = $offset; 83 if (in_array($atomname, array('uuid'))) { 84 @$info['quicktime'][$atomname][] = $parsedAtomData; 85 } else { 86 $info['quicktime'][$atomname] = $parsedAtomData; 87 } 75 88 76 89 $offset += $atomsize; … … 115 128 $ISO6709parsed = array('latitude'=>false, 'longitude'=>false, 'altitude'=>false); 116 129 if (preg_match('#^([\\+\\-])([0-9]{2}|[0-9]{4}|[0-9]{6})(\\.[0-9]+)?([\\+\\-])([0-9]{3}|[0-9]{5}|[0-9]{7})(\\.[0-9]+)?(([\\+\\-])([0-9]{3}|[0-9]{5}|[0-9]{7})(\\.[0-9]+)?)?/$#', $ISO6709string, $matches)) { 117 @list($dummy, $lat_sign, $lat_deg, $lat_deg_dec, $lon_sign, $lon_deg, $lon_deg_dec, $dummy, $alt_sign, $alt_deg, $alt_deg_dec) = $matches; // phpcs:ignore PHPCompatibility.Lists.AssignmentOrder.Affected 130 // phpcs:ignore PHPCompatibility.Lists.AssignmentOrder.Affected 131 @list($dummy, $lat_sign, $lat_deg, $lat_deg_dec, $lon_sign, $lon_deg, $lon_deg_dec, $dummy, $alt_sign, $alt_deg, $alt_deg_dec) = $matches; 118 132 119 133 if (strlen($lat_deg) == 2) { // [+-]DD.D … … 144 158 if ($ISO6709parsed[$key] !== false) { 145 159 $value = (($lat_sign == '-') ? -1 : 1) * floatval($ISO6709parsed[$key]); 146 if (!i n_array($value, $info['quicktime']['comments']['gps_'.$key])) {147 $info['quicktime']['comments']['gps_'.$key][]= (($lat_sign == '-') ? -1 : 1) * floatval($ISO6709parsed[$key]);160 if (!isset($info['quicktime']['comments']['gps_'.$key]) || !in_array($value, $info['quicktime']['comments']['gps_'.$key])) { 161 @$info['quicktime']['comments']['gps_'.$key][] = (($lat_sign == '-') ? -1 : 1) * floatval($ISO6709parsed[$key]); 148 162 } 149 163 } … … 528 542 $atom_structure['image_mime'] = 'image/gif'; 529 543 } 544 $info['quicktime']['comments']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_structure['data'], 'description'=>'cover'); 530 545 break; 531 546 … … 554 569 $atom_structure['image_mime'] = 'image/gif'; 555 570 } 571 $info['quicktime']['comments']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_structure['data'], 'description'=>'cover'); 556 572 } 557 573 break; … … 756 772 $atom_structure['sample_description_table'][$i]['data'] = substr($atom_data, $stsdEntriesDataOffset, ($atom_structure['sample_description_table'][$i]['size'] - 4 - 4 - 6 - 2)); 757 773 $stsdEntriesDataOffset += ($atom_structure['sample_description_table'][$i]['size'] - 4 - 4 - 6 - 2); 774 775 if (substr($atom_structure['sample_description_table'][$i]['data'], 1, 54) == 'application/octet-stream;type=com.parrot.videometadata') { 776 // special handling for apparently-malformed (TextMetaDataSampleEntry?) data for some version of Parrot drones 777 $atom_structure['sample_description_table'][$i]['parrot_frame_metadata']['mime_type'] = substr($atom_structure['sample_description_table'][$i]['data'], 1, 55); 778 $atom_structure['sample_description_table'][$i]['parrot_frame_metadata']['metadata_version'] = (int) substr($atom_structure['sample_description_table'][$i]['data'], 55, 1); 779 unset($atom_structure['sample_description_table'][$i]['data']); 780 $this->warning('incomplete/incorrect handling of "stsd" with Parrot metadata in this version of getID3() ['.$this->getid3->version().']'); 781 continue; 782 } 758 783 759 784 $atom_structure['sample_description_table'][$i]['encoder_version'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 0, 2)); … … 1134 1159 $atom_structure['component_flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 16, 4)); 1135 1160 $atom_structure['component_flags_mask'] = getid3_lib::BigEndian2Int(substr($atom_data, 20, 4)); 1136 $atom_structure['component_name'] = $this->Pascal2String(substr($atom_data, 24));1161 $atom_structure['component_name'] = $this->MaybePascal2String(substr($atom_data, 24)); 1137 1162 1138 1163 if (($atom_structure['component_subtype'] == 'STpn') && ($atom_structure['component_manufacturer'] == 'zzzz')) { … … 1165 1190 $info['comments']['language'][] = $atom_structure['language']; 1166 1191 } 1192 $info['quicktime']['timestamps_unix']['create'][$atom_structure['hierarchy']] = $atom_structure['creation_time_unix']; 1193 $info['quicktime']['timestamps_unix']['modify'][$atom_structure['hierarchy']] = $atom_structure['modify_time_unix']; 1167 1194 break; 1168 1195 … … 1175 1202 1176 1203 $atom_structure['modification_date_unix'] = getid3_lib::DateMac2Unix($atom_structure['modification_date']); 1204 $info['quicktime']['timestamps_unix']['modify'][$atom_structure['hierarchy']] = $atom_structure['modification_date_unix']; 1177 1205 break; 1178 1206 … … 1272 1300 $atom_structure['creation_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['creation_time']); 1273 1301 $atom_structure['modify_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['modify_time']); 1302 $info['quicktime']['timestamps_unix']['create'][$atom_structure['hierarchy']] = $atom_structure['creation_time_unix']; 1303 $info['quicktime']['timestamps_unix']['modify'][$atom_structure['hierarchy']] = $atom_structure['modify_time_unix']; 1274 1304 $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']); 1275 1305 $info['quicktime']['display_scale'] = $atom_structure['matrix_a']; … … 1310 1340 $atom_structure['creation_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['creation_time']); 1311 1341 $atom_structure['modify_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['modify_time']); 1342 $info['quicktime']['timestamps_unix']['create'][$atom_structure['hierarchy']] = $atom_structure['creation_time_unix']; 1343 $info['quicktime']['timestamps_unix']['modify'][$atom_structure['hierarchy']] = $atom_structure['modify_time_unix']; 1312 1344 1313 1345 // https://www.getid3.org/phpBB3/viewtopic.php?t=1908 … … 1451 1483 1452 1484 $getid3_temp = new getID3(); 1453 $getid3_temp->openfile($this->getid3->filename );1485 $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp); 1454 1486 $getid3_temp->info['avdataoffset'] = $info['avdataoffset']; 1455 1487 $getid3_temp->info['avdataend'] = $info['avdataend']; … … 1640 1672 break; 1641 1673 1642 case 'uuid': // Atom holding 360fly spatial data?? 1643 /* code in this block by Paul Lewis 2019-Oct-31 */ 1644 /* Sensor Timestamps need to be calculated using the recordings base time at ['quicktime']['moov']['subatoms'][0]['creation_time_unix']. */ 1645 $atom_structure['title'] = '360Fly Sensor Data'; 1646 1674 case 'uuid': // user-defined atom often seen containing XML data, also used for potentially many other purposes, only a few specifically handled by getID3 (e.g. 360fly spatial data) 1647 1675 //Get the UUID ID in first 16 bytes 1648 1676 $uuid_bytes_read = unpack('H8time_low/H4time_mid/H4time_hi/H4clock_seq_hi/H12clock_seq_low', substr($atom_data, 0, 16)); 1649 $atom_structure['uuid_field_id'] = print_r(implode('-', $uuid_bytes_read), true); 1650 1651 //Get the UUID HEADER data 1652 $uuid_bytes_read = unpack('Sheader_size/Sheader_version/Stimescale/Shardware_version/x/x/x/x/x/x/x/x/x/x/x/x/x/x/x/x/', substr($atom_data, 16, 32)); 1653 $atom_structure['uuid_header'] = json_encode($uuid_bytes_read, true); 1654 1655 $start_byte = 48; 1656 $atom_SENSOR_data = substr($atom_data, $start_byte); 1657 $atom_structure['sensor_data']['data_type'] = array( 1658 'fusion_count' => 0, // ID 250 1659 'fusion_data' => array(), 1660 'accel_count' => 0, // ID 1 1661 'accel_data' => array(), 1662 'gyro_count' => 0, // ID 2 1663 'gyro_data' => array(), 1664 'magno_count' => 0, // ID 3 1665 'magno_data' => array(), 1666 'gps_count' => 0, // ID 5 1667 'gps_data' => array(), 1668 'rotation_count' => 0, // ID 6 1669 'rotation_data' => array(), 1670 'unknown_count' => 0, // ID ?? 1671 'unknown_data' => array(), 1672 'debug_list' => '', // Used to debug variables stored as comma delimited strings 1673 ); 1674 $debug_structure['debug_items'] = array(); 1675 // Can start loop here to decode all sensor data in 32 Byte chunks: 1676 foreach (str_split($atom_SENSOR_data, 32) as $sensor_key => $sensor_data) { 1677 // This gets me a data_type code to work out what data is in the next 31 bytes. 1678 $sensor_data_type = substr($sensor_data, 0, 1); 1679 $sensor_data_content = substr($sensor_data, 1); 1680 $uuid_bytes_read = unpack('C*', $sensor_data_type); 1681 $sensor_data_array = array(); 1682 switch ($uuid_bytes_read[1]) { 1683 case 250: 1684 $atom_structure['sensor_data']['data_type']['fusion_count']++; 1685 $uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content); 1686 $sensor_data_array['mode'] = $uuid_bytes_read['mode']; 1687 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp']; 1688 $sensor_data_array['yaw'] = $uuid_bytes_read['yaw']; 1689 $sensor_data_array['pitch'] = $uuid_bytes_read['pitch']; 1690 $sensor_data_array['roll'] = $uuid_bytes_read['roll']; 1691 array_push($atom_structure['sensor_data']['data_type']['fusion_data'], $sensor_data_array); 1692 break; 1693 case 1: 1694 $atom_structure['sensor_data']['data_type']['accel_count']++; 1695 $uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content); 1696 $sensor_data_array['mode'] = $uuid_bytes_read['mode']; 1697 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp']; 1698 $sensor_data_array['yaw'] = $uuid_bytes_read['yaw']; 1699 $sensor_data_array['pitch'] = $uuid_bytes_read['pitch']; 1700 $sensor_data_array['roll'] = $uuid_bytes_read['roll']; 1701 array_push($atom_structure['sensor_data']['data_type']['accel_data'], $sensor_data_array); 1702 break; 1703 case 2: 1704 $atom_structure['sensor_data']['data_type']['gyro_count']++; 1705 $uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content); 1706 $sensor_data_array['mode'] = $uuid_bytes_read['mode']; 1707 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp']; 1708 $sensor_data_array['yaw'] = $uuid_bytes_read['yaw']; 1709 $sensor_data_array['pitch'] = $uuid_bytes_read['pitch']; 1710 $sensor_data_array['roll'] = $uuid_bytes_read['roll']; 1711 array_push($atom_structure['sensor_data']['data_type']['gyro_data'], $sensor_data_array); 1712 break; 1713 case 3: 1714 $atom_structure['sensor_data']['data_type']['magno_count']++; 1715 $uuid_bytes_read = unpack('cmode/Jtimestamp/Gmagx/Gmagy/Gmagz/x*', $sensor_data_content); 1716 $sensor_data_array['mode'] = $uuid_bytes_read['mode']; 1717 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp']; 1718 $sensor_data_array['magx'] = $uuid_bytes_read['magx']; 1719 $sensor_data_array['magy'] = $uuid_bytes_read['magy']; 1720 $sensor_data_array['magz'] = $uuid_bytes_read['magz']; 1721 array_push($atom_structure['sensor_data']['data_type']['magno_data'], $sensor_data_array); 1722 break; 1723 case 5: 1724 $atom_structure['sensor_data']['data_type']['gps_count']++; 1725 $uuid_bytes_read = unpack('cmode/Jtimestamp/Glat/Glon/Galt/Gspeed/nbearing/nacc/x*', $sensor_data_content); 1726 $sensor_data_array['mode'] = $uuid_bytes_read['mode']; 1727 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp']; 1728 $sensor_data_array['lat'] = $uuid_bytes_read['lat']; 1729 $sensor_data_array['lon'] = $uuid_bytes_read['lon']; 1730 $sensor_data_array['alt'] = $uuid_bytes_read['alt']; 1731 $sensor_data_array['speed'] = $uuid_bytes_read['speed']; 1732 $sensor_data_array['bearing'] = $uuid_bytes_read['bearing']; 1733 $sensor_data_array['acc'] = $uuid_bytes_read['acc']; 1734 //$sensor_data_array = print_r($uuid_bytes_read, true); 1735 array_push($atom_structure['sensor_data']['data_type']['gps_data'], $sensor_data_array); 1736 //array_push($debug_structure['debug_items'], $uuid_bytes_read['timestamp']); 1737 break; 1738 case 6: 1739 $atom_structure['sensor_data']['data_type']['rotation_count']++; 1740 $uuid_bytes_read = unpack('cmode/Jtimestamp/Grotx/Groty/Grotz/x*', $sensor_data_content); 1741 $sensor_data_array['mode'] = $uuid_bytes_read['mode']; 1742 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp']; 1743 $sensor_data_array['rotx'] = $uuid_bytes_read['rotx']; 1744 $sensor_data_array['roty'] = $uuid_bytes_read['roty']; 1745 $sensor_data_array['rotz'] = $uuid_bytes_read['rotz']; 1746 array_push($atom_structure['sensor_data']['data_type']['rotation_data'], $sensor_data_array); 1747 break; 1748 default: 1749 $atom_structure['sensor_data']['data_type']['unknown_count']++; 1750 break; 1751 } 1752 } 1753 // if (isset($debug_structure['debug_items']) && count($debug_structure['debug_items']) > 0) { 1754 // $atom_structure['sensor_data']['data_type']['debug_list'] = implode(',', $debug_structure['debug_items']); 1755 // } else { 1756 $atom_structure['sensor_data']['data_type']['debug_list'] = 'No debug items in list!'; 1757 // } 1677 $atom_structure['uuid_field_id'] = implode('-', $uuid_bytes_read); 1678 1679 switch ($atom_structure['uuid_field_id']) { // http://fileformats.archiveteam.org/wiki/Boxes/atoms_format#UUID_boxes 1680 1681 case '0537cdab-9d0c-4431-a72a-fa561f2a113e': // Exif - http://fileformats.archiveteam.org/wiki/Exif 1682 case '2c4c0100-8504-40b9-a03e-562148d6dfeb': // Photoshop Image Resources - http://fileformats.archiveteam.org/wiki/Photoshop_Image_Resources 1683 case '33c7a4d2-b81d-4723-a0ba-f1a3e097ad38': // IPTC-IIM - http://fileformats.archiveteam.org/wiki/IPTC-IIM 1684 case '8974dbce-7be7-4c51-84f9-7148f9882554': // PIFF Track Encryption Box - http://fileformats.archiveteam.org/wiki/Protected_Interoperable_File_Format 1685 case '96a9f1f1-dc98-402d-a7ae-d68e34451809': // GeoJP2 World File Box - http://fileformats.archiveteam.org/wiki/GeoJP2 1686 case 'a2394f52-5a9b-4f14-a244-6c427c648df4': // PIFF Sample Encryption Box - http://fileformats.archiveteam.org/wiki/Protected_Interoperable_File_Format 1687 case 'b14bf8bd-083d-4b43-a5ae-8cd7d5a6ce03': // GeoJP2 GeoTIFF Box - http://fileformats.archiveteam.org/wiki/GeoJP2 1688 case 'd08a4f18-10f3-4a82-b6c8-32d8aba183d3': // PIFF Protection System Specific Header Box - http://fileformats.archiveteam.org/wiki/Protected_Interoperable_File_Format 1689 $this->warning('Unhandled (but recognized) "uuid" atom identified by "'.$atom_structure['uuid_field_id'].'" at offset '.$atom_structure['offset'].' ('.strlen($atom_data).' bytes)'); 1690 break; 1691 1692 case 'be7acfcb-97a9-42e8-9c71-999491e3afac': // XMP data (in XML format) 1693 $atom_structure['xml'] = substr($atom_data, 16, strlen($atom_data) - 16 - 8); // 16 bytes for UUID, 8 bytes header(?) 1694 break; 1695 1696 case 'efe1589a-bb77-49ef-8095-27759eb1dc6f': // 360fly data 1697 /* 360fly code in this block by Paul Lewis 2019-Oct-31 */ 1698 /* Sensor Timestamps need to be calculated using the recordings base time at ['quicktime']['moov']['subatoms'][0]['creation_time_unix']. */ 1699 $atom_structure['title'] = '360Fly Sensor Data'; 1700 1701 //Get the UUID HEADER data 1702 $uuid_bytes_read = unpack('vheader_size/vheader_version/vtimescale/vhardware_version/x/x/x/x/x/x/x/x/x/x/x/x/x/x/x/x/', substr($atom_data, 16, 32)); 1703 $atom_structure['uuid_header'] = $uuid_bytes_read; 1704 1705 $start_byte = 48; 1706 $atom_SENSOR_data = substr($atom_data, $start_byte); 1707 $atom_structure['sensor_data']['data_type'] = array( 1708 'fusion_count' => 0, // ID 250 1709 'fusion_data' => array(), 1710 'accel_count' => 0, // ID 1 1711 'accel_data' => array(), 1712 'gyro_count' => 0, // ID 2 1713 'gyro_data' => array(), 1714 'magno_count' => 0, // ID 3 1715 'magno_data' => array(), 1716 'gps_count' => 0, // ID 5 1717 'gps_data' => array(), 1718 'rotation_count' => 0, // ID 6 1719 'rotation_data' => array(), 1720 'unknown_count' => 0, // ID ?? 1721 'unknown_data' => array(), 1722 'debug_list' => '', // Used to debug variables stored as comma delimited strings 1723 ); 1724 $debug_structure['debug_items'] = array(); 1725 // Can start loop here to decode all sensor data in 32 Byte chunks: 1726 foreach (str_split($atom_SENSOR_data, 32) as $sensor_key => $sensor_data) { 1727 // This gets me a data_type code to work out what data is in the next 31 bytes. 1728 $sensor_data_type = substr($sensor_data, 0, 1); 1729 $sensor_data_content = substr($sensor_data, 1); 1730 $uuid_bytes_read = unpack('C*', $sensor_data_type); 1731 $sensor_data_array = array(); 1732 switch ($uuid_bytes_read[1]) { 1733 case 250: 1734 $atom_structure['sensor_data']['data_type']['fusion_count']++; 1735 $uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content); 1736 $sensor_data_array['mode'] = $uuid_bytes_read['mode']; 1737 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp']; 1738 $sensor_data_array['yaw'] = $uuid_bytes_read['yaw']; 1739 $sensor_data_array['pitch'] = $uuid_bytes_read['pitch']; 1740 $sensor_data_array['roll'] = $uuid_bytes_read['roll']; 1741 array_push($atom_structure['sensor_data']['data_type']['fusion_data'], $sensor_data_array); 1742 break; 1743 case 1: 1744 $atom_structure['sensor_data']['data_type']['accel_count']++; 1745 $uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content); 1746 $sensor_data_array['mode'] = $uuid_bytes_read['mode']; 1747 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp']; 1748 $sensor_data_array['yaw'] = $uuid_bytes_read['yaw']; 1749 $sensor_data_array['pitch'] = $uuid_bytes_read['pitch']; 1750 $sensor_data_array['roll'] = $uuid_bytes_read['roll']; 1751 array_push($atom_structure['sensor_data']['data_type']['accel_data'], $sensor_data_array); 1752 break; 1753 case 2: 1754 $atom_structure['sensor_data']['data_type']['gyro_count']++; 1755 $uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content); 1756 $sensor_data_array['mode'] = $uuid_bytes_read['mode']; 1757 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp']; 1758 $sensor_data_array['yaw'] = $uuid_bytes_read['yaw']; 1759 $sensor_data_array['pitch'] = $uuid_bytes_read['pitch']; 1760 $sensor_data_array['roll'] = $uuid_bytes_read['roll']; 1761 array_push($atom_structure['sensor_data']['data_type']['gyro_data'], $sensor_data_array); 1762 break; 1763 case 3: 1764 $atom_structure['sensor_data']['data_type']['magno_count']++; 1765 $uuid_bytes_read = unpack('cmode/Jtimestamp/Gmagx/Gmagy/Gmagz/x*', $sensor_data_content); 1766 $sensor_data_array['mode'] = $uuid_bytes_read['mode']; 1767 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp']; 1768 $sensor_data_array['magx'] = $uuid_bytes_read['magx']; 1769 $sensor_data_array['magy'] = $uuid_bytes_read['magy']; 1770 $sensor_data_array['magz'] = $uuid_bytes_read['magz']; 1771 array_push($atom_structure['sensor_data']['data_type']['magno_data'], $sensor_data_array); 1772 break; 1773 case 5: 1774 $atom_structure['sensor_data']['data_type']['gps_count']++; 1775 $uuid_bytes_read = unpack('cmode/Jtimestamp/Glat/Glon/Galt/Gspeed/nbearing/nacc/x*', $sensor_data_content); 1776 $sensor_data_array['mode'] = $uuid_bytes_read['mode']; 1777 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp']; 1778 $sensor_data_array['lat'] = $uuid_bytes_read['lat']; 1779 $sensor_data_array['lon'] = $uuid_bytes_read['lon']; 1780 $sensor_data_array['alt'] = $uuid_bytes_read['alt']; 1781 $sensor_data_array['speed'] = $uuid_bytes_read['speed']; 1782 $sensor_data_array['bearing'] = $uuid_bytes_read['bearing']; 1783 $sensor_data_array['acc'] = $uuid_bytes_read['acc']; 1784 array_push($atom_structure['sensor_data']['data_type']['gps_data'], $sensor_data_array); 1785 //array_push($debug_structure['debug_items'], $uuid_bytes_read['timestamp']); 1786 break; 1787 case 6: 1788 $atom_structure['sensor_data']['data_type']['rotation_count']++; 1789 $uuid_bytes_read = unpack('cmode/Jtimestamp/Grotx/Groty/Grotz/x*', $sensor_data_content); 1790 $sensor_data_array['mode'] = $uuid_bytes_read['mode']; 1791 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp']; 1792 $sensor_data_array['rotx'] = $uuid_bytes_read['rotx']; 1793 $sensor_data_array['roty'] = $uuid_bytes_read['roty']; 1794 $sensor_data_array['rotz'] = $uuid_bytes_read['rotz']; 1795 array_push($atom_structure['sensor_data']['data_type']['rotation_data'], $sensor_data_array); 1796 break; 1797 default: 1798 $atom_structure['sensor_data']['data_type']['unknown_count']++; 1799 break; 1800 } 1801 } 1802 //if (isset($debug_structure['debug_items']) && count($debug_structure['debug_items']) > 0) { 1803 // $atom_structure['sensor_data']['data_type']['debug_list'] = implode(',', $debug_structure['debug_items']); 1804 //} else { 1805 $atom_structure['sensor_data']['data_type']['debug_list'] = 'No debug items in list!'; 1806 //} 1807 break; 1808 1809 default: 1810 $this->warning('Unhandled "uuid" atom identified by "'.$atom_structure['uuid_field_id'].'" at offset '.$atom_structure['offset'].' ('.strlen($atom_data).' bytes)'); 1811 } 1758 1812 break; 1759 1813 … … 1950 2004 // https://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Kodak.html#frea 1951 2005 if (strlen($atom_data) > 0) { 1952 $info['quicktime']['comments']['picture'][] = array('data'=>$atom_data, 'image_mime'=>'image/jpeg' );2006 $info['quicktime']['comments']['picture'][] = array('data'=>$atom_data, 'image_mime'=>'image/jpeg', 'description'=>'ThumbnailImage'); 1953 2007 } 1954 2008 break; … … 1957 2011 // but the only sample file I've seen has no useful data here 1958 2012 if (strlen($atom_data) > 0) { 1959 $info['quicktime']['comments']['picture'][] = array('data'=>$atom_data, 'image_mime'=>'image/jpeg'); 1960 } 1961 break; 1962 2013 $info['quicktime']['comments']['picture'][] = array('data'=>$atom_data, 'image_mime'=>'image/jpeg', 'description'=>'PreviewImage'); 2014 } 2015 break; 2016 2017 case 'cdsc': // timed metadata reference 2018 // A QuickTime movie can contain none, one, or several timed metadata tracks. Timed metadata tracks can refer to multiple tracks. 2019 // Metadata tracks are linked to the tracks they describe using a track-reference of type 'cdsc'. The metadata track holds the 'cdsc' track reference. 2020 $atom_structure['track_number'] = getid3_lib::BigEndian2Int($atom_data); 2021 break; 1963 2022 1964 2023 default: … … 2000 2059 } 2001 2060 return $atom_structure; 2061 } 2062 if (strlen($subatomdata) < ($subatomsize - 8)) { 2063 // we don't have enough data to decode the subatom. 2064 // this may be because we are refusing to parse large subatoms, or it may be because this atom had its size set too large 2065 // so we passed in the start of a following atom incorrectly? 2066 return $atom_structure; 2002 2067 } 2003 2068 $atom_structure[$subatomcounter++] = $this->QuicktimeParseAtom($subatomname, $subatomsize, $subatomdata, $baseoffset + $subatomoffset, $atomHierarchy, $ParseAllPossibleAtoms); … … 2841 2906 if ($comment_key) { 2842 2907 if ($comment_key == 'picture') { 2843 if (!is_array($data)) { 2844 $image_mime = ''; 2845 if (preg_match('#^\x89\x50\x4E\x47\x0D\x0A\x1A\x0A#', $data)) { 2846 $image_mime = 'image/png'; 2847 } elseif (preg_match('#^\xFF\xD8\xFF#', $data)) { 2848 $image_mime = 'image/jpeg'; 2849 } elseif (preg_match('#^GIF#', $data)) { 2850 $image_mime = 'image/gif'; 2851 } elseif (preg_match('#^BM#', $data)) { 2852 $image_mime = 'image/bmp'; 2853 } 2854 $data = array('data'=>$data, 'image_mime'=>$image_mime); 2855 } 2908 // already copied directly into [comments][picture] elsewhere, do not re-copy here 2909 return true; 2856 2910 } 2857 2911 $gooddata = array($data); … … 2861 2915 } 2862 2916 foreach ($gooddata as $data) { 2863 if ( is_array($data) || (!empty($info['quicktime']['comments'][$comment_key]) && in_array($data, $info['quicktime']['comments'][$comment_key]))) {2917 if (!empty($info['quicktime']['comments'][$comment_key]) && in_array($data, $info['quicktime']['comments'][$comment_key], true)) { 2864 2918 // avoid duplicate copies of identical data 2865 2919 continue; … … 2928 2982 // Pascal strings have 1 unsigned byte at the beginning saying how many chars (1-255) are in the string 2929 2983 return substr($pascalstring, 1); 2984 } 2985 2986 /** 2987 * @param string $pascalstring 2988 * 2989 * @return string 2990 */ 2991 public function MaybePascal2String($pascalstring) { 2992 // Pascal strings have 1 unsigned byte at the beginning saying how many chars (1-255) are in the string 2993 // Check if string actually is in this format or written incorrectly, straight string, or null-terminated string 2994 if (ord(substr($pascalstring, 0, 1)) == (strlen($pascalstring) - 1)) { 2995 return substr($pascalstring, 1); 2996 } elseif (substr($pascalstring, -1, 1) == "\x00") { 2997 // appears to be null-terminated instead of Pascal-style 2998 return substr($pascalstring, 0, -1); 2999 } 3000 return $pascalstring; 2930 3001 } 2931 3002
Note: See TracChangeset
for help on using the changeset viewer.