- Timestamp:
- 11/17/2025 10:20:32 PM (3 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/ID3/module.audio-video.quicktime.php
r60800 r61253 40 40 41 41 /** 42 * real ugly, but so is the QuickTime structure that stores keys and values in different multi-nested locations that are hard to relate to each other 43 * https://github.com/JamesHeinrich/getID3/issues/214 44 * 45 * @var int 46 */ 47 private $metaDATAkey = 1; 48 49 /** 42 50 * @return bool 43 51 */ … … 45 53 $info = &$this->getid3->info; 46 54 55 $this->metaDATAkey = 1; 47 56 $info['fileformat'] = 'quicktime'; 48 57 $info['quicktime']['hinting'] = false; … … 148 157 149 158 if (strlen($lat_deg) == 2) { // [+-]DD.D 150 $ISO6709parsed['latitude'] = (($lat_sign == '-') ? -1 : 1) * floatval(ltrim($lat_deg, '0').$lat_deg_dec);159 $ISO6709parsed['latitude'] = (($lat_sign == '-') ? -1 : 1) * (float) (ltrim($lat_deg, '0').$lat_deg_dec); 151 160 } elseif (strlen($lat_deg) == 4) { // [+-]DDMM.M 152 $ISO6709parsed['latitude'] = (($lat_sign == '-') ? -1 : 1) * floatval(ltrim(substr($lat_deg, 0, 2), '0')) + floatval(ltrim(substr($lat_deg, 2, 2), '0').$lat_deg_dec/ 60);161 $ISO6709parsed['latitude'] = (($lat_sign == '-') ? -1 : 1) * (int) ltrim(substr($lat_deg, 0, 2), '0') + ((float) (ltrim(substr($lat_deg, 2, 2), '0').$lat_deg_dec) / 60); 153 162 } elseif (strlen($lat_deg) == 6) { // [+-]DDMMSS.S 154 $ISO6709parsed['latitude'] = (($lat_sign == '-') ? -1 : 1) * floatval(ltrim(substr($lat_deg, 0, 2), '0')) + floatval((int) ltrim(substr($lat_deg, 2, 2), '0') / 60) + floatval(ltrim(substr($lat_deg, 4, 2), '0').$lat_deg_dec/ 3600);163 $ISO6709parsed['latitude'] = (($lat_sign == '-') ? -1 : 1) * (int) ltrim(substr($lat_deg, 0, 2), '0') + ((int) ltrim(substr($lat_deg, 2, 2), '0') / 60) + ((float) (ltrim(substr($lat_deg, 4, 2), '0').$lat_deg_dec) / 3600); 155 164 } 156 165 157 166 if (strlen($lon_deg) == 3) { // [+-]DDD.D 158 $ISO6709parsed['longitude'] = (($lon_sign == '-') ? -1 : 1) * floatval(ltrim($lon_deg, '0').$lon_deg_dec);167 $ISO6709parsed['longitude'] = (($lon_sign == '-') ? -1 : 1) * (float) (ltrim($lon_deg, '0').$lon_deg_dec); 159 168 } elseif (strlen($lon_deg) == 5) { // [+-]DDDMM.M 160 $ISO6709parsed['longitude'] = (($lon_sign == '-') ? -1 : 1) * floatval(ltrim(substr($lon_deg, 0, 2), '0')) + floatval(ltrim(substr($lon_deg, 2, 2), '0').$lon_deg_dec/ 60);169 $ISO6709parsed['longitude'] = (($lon_sign == '-') ? -1 : 1) * (int) ltrim(substr($lon_deg, 0, 2), '0') + ((float) (ltrim(substr($lon_deg, 2, 2), '0').$lon_deg_dec) / 60); 161 170 } elseif (strlen($lon_deg) == 7) { // [+-]DDDMMSS.S 162 $ISO6709parsed['longitude'] = (($lon_sign == '-') ? -1 : 1) * floatval(ltrim(substr($lon_deg, 0, 2), '0')) + floatval((int) ltrim(substr($lon_deg, 2, 2), '0') / 60) + floatval(ltrim(substr($lon_deg, 4, 2), '0').$lon_deg_dec/ 3600);171 $ISO6709parsed['longitude'] = (($lon_sign == '-') ? -1 : 1) * (int) ltrim(substr($lon_deg, 0, 2), '0') + ((int) ltrim(substr($lon_deg, 2, 2), '0') / 60) + ((float) (ltrim(substr($lon_deg, 4, 2), '0').$lon_deg_dec) / 3600); 163 172 } 164 173 165 174 if (strlen($alt_deg) == 3) { // [+-]DDD.D 166 $ISO6709parsed['altitude'] = (($alt_sign == '-') ? -1 : 1) * floatval(ltrim($alt_deg, '0').$alt_deg_dec);175 $ISO6709parsed['altitude'] = (($alt_sign == '-') ? -1 : 1) * (float) (ltrim($alt_deg, '0').$alt_deg_dec); 167 176 } elseif (strlen($alt_deg) == 5) { // [+-]DDDMM.M 168 $ISO6709parsed['altitude'] = (($alt_sign == '-') ? -1 : 1) * floatval(ltrim(substr($alt_deg, 0, 2), '0')) + floatval(ltrim(substr($alt_deg, 2, 2), '0').$alt_deg_dec/ 60);177 $ISO6709parsed['altitude'] = (($alt_sign == '-') ? -1 : 1) * (int) ltrim(substr($alt_deg, 0, 2), '0') + ((float) (ltrim(substr($alt_deg, 2, 2), '0').$alt_deg_dec) / 60); 169 178 } elseif (strlen($alt_deg) == 7) { // [+-]DDDMMSS.S 170 $ISO6709parsed['altitude'] = (($alt_sign == '-') ? -1 : 1) * floatval(ltrim(substr($alt_deg, 0, 2), '0')) + floatval((int) ltrim(substr($alt_deg, 2, 2), '0') / 60) + floatval(ltrim(substr($alt_deg, 4, 2), '0').$alt_deg_dec/ 3600);179 $ISO6709parsed['altitude'] = (($alt_sign == '-') ? -1 : 1) * (int) ltrim(substr($alt_deg, 0, 2), '0') + ((int) ltrim(substr($alt_deg, 2, 2), '0') / 60) + ((float) (ltrim(substr($alt_deg, 4, 2), '0').$alt_deg_dec) / 3600); 171 180 } 172 181 … … 214 223 } else { 215 224 $info['mime_type'] = 'video/mp4'; 225 } 226 } 227 if (!empty($info['quicktime']['ftyp']['signature']) && in_array($info['quicktime']['ftyp']['signature'], array('heic','heix','hevc','hevx','heim','heis','hevm','hevs'))) { 228 if ($info['mime_type'] == 'video/quicktime') { // default value, as we 229 // https://en.wikipedia.org/wiki/High_Efficiency_Image_File_Format 230 $this->error('HEIF files not currently supported'); 231 switch ($info['quicktime']['ftyp']['signature']) { 232 // https://github.com/strukturag/libheif/issues/83 (comment by Dirk Farin 2018-09-14) 233 case 'heic': // the usual HEIF images 234 case 'heix': // 10bit images, or anything that uses h265 with range extension 235 case 'hevc': // brands for image sequences 236 case 'hevx': // brands for image sequences 237 case 'heim': // multiview 238 case 'heis': // scalable 239 case 'hevm': // multiview sequence 240 case 'hevs': // scalable sequence 241 $info['fileformat'] = 'heif'; 242 $info['mime_type'] = 'image/heif'; 243 break; 244 } 216 245 } 217 246 } … … 794 823 795 824 $stsdEntriesDataOffset = 8; 796 for ($i = 0; $i < $atom_structure['number_entries']; $i++) {825 for ($i = 0; $i < (int) $atom_structure['number_entries']; $i++) { 797 826 $atom_structure['sample_description_table'][$i]['size'] = getid3_lib::BigEndian2Int(substr($atom_data, $stsdEntriesDataOffset, 4)); 798 827 $stsdEntriesDataOffset += 4; … … 830 859 // video tracks 831 860 // http://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/QTFFChap3/qtff3.html 832 $atom_structure['sample_description_table'][$i]['temporal_quality'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 8, 4)); 833 $atom_structure['sample_description_table'][$i]['spatial_quality'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 12, 4)); 834 $atom_structure['sample_description_table'][$i]['width'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 16, 2)); 835 $atom_structure['sample_description_table'][$i]['height'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 18, 2)); 836 $atom_structure['sample_description_table'][$i]['resolution_x'] = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 24, 4)); 837 $atom_structure['sample_description_table'][$i]['resolution_y'] = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], 28, 4)); 838 $atom_structure['sample_description_table'][$i]['data_size'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 32, 4)); 839 $atom_structure['sample_description_table'][$i]['frame_count'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 36, 2)); 840 $atom_structure['sample_description_table'][$i]['compressor_name'] = substr($atom_structure['sample_description_table'][$i]['data'], 38, 4); 841 $atom_structure['sample_description_table'][$i]['pixel_depth'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 42, 2)); 842 $atom_structure['sample_description_table'][$i]['color_table_id'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 44, 2)); 861 // https://developer.apple.com/documentation/quicktime-file-format 862 $STSDvOffset = 8; 863 $atom_structure['sample_description_table'][$i]['temporal_quality'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], $STSDvOffset, 4)); $STSDvOffset += 4; 864 $atom_structure['sample_description_table'][$i]['spatial_quality'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], $STSDvOffset, 4)); $STSDvOffset += 4; 865 $atom_structure['sample_description_table'][$i]['width'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], $STSDvOffset, 2)); $STSDvOffset += 2; 866 $atom_structure['sample_description_table'][$i]['height'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], $STSDvOffset, 2)); $STSDvOffset += 2; 867 $atom_structure['sample_description_table'][$i]['resolution_x'] = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], $STSDvOffset, 4)); $STSDvOffset += 4; 868 $atom_structure['sample_description_table'][$i]['resolution_y'] = getid3_lib::FixedPoint16_16(substr($atom_structure['sample_description_table'][$i]['data'], $STSDvOffset, 4)); $STSDvOffset += 4; 869 $atom_structure['sample_description_table'][$i]['data_size'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], $STSDvOffset, 4)); $STSDvOffset += 4; 870 $atom_structure['sample_description_table'][$i]['frame_count'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], $STSDvOffset, 2)); $STSDvOffset += 2; 871 $atom_structure['sample_description_table'][$i]['compressor_name'] = substr($atom_structure['sample_description_table'][$i]['data'], $STSDvOffset, 32) ; $STSDvOffset += 32; 872 $atom_structure['sample_description_table'][$i]['compressor_name'] = $this->MaybePascal2String(rtrim($atom_structure['sample_description_table'][$i]['compressor_name'], "\x00")); // https://github.com/JamesHeinrich/getID3/issues/452 873 $atom_structure['sample_description_table'][$i]['pixel_depth'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], $STSDvOffset, 2)); $STSDvOffset += 2; 874 $atom_structure['sample_description_table'][$i]['color_table_id'] = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], $STSDvOffset, 2)); $STSDvOffset += 2; 843 875 844 876 switch ($atom_structure['sample_description_table'][$i]['data_format']) { … … 1642 1674 $info['quicktime']['comments']['gps_latitude'][] = floatval($latitude); 1643 1675 $info['quicktime']['comments']['gps_longitude'][] = floatval($longitude); 1644 if (!empty($altitude)) { 1676 if (!empty($altitude)) { // @phpstan-ignore-line 1645 1677 $info['quicktime']['comments']['gps_altitude'][] = floatval($altitude); 1646 1678 } … … 1722 1754 1723 1755 case 'data': // metaDATA atom 1724 static $metaDATAkey = 1; // real ugly, but so is the QuickTime structure that stores keys and values in different multinested locations that are hard to relate to each other1725 1756 // seems to be 2 bytes language code (ASCII), 2 bytes unknown (set to 0x10B5 in sample I have), remainder is useful data 1726 1757 $atom_structure['language'] = substr($atom_data, 4 + 0, 2); 1727 1758 $atom_structure['unknown'] = getid3_lib::BigEndian2Int(substr($atom_data, 4 + 2, 2)); 1728 1759 $atom_structure['data'] = substr($atom_data, 4 + 4); 1729 $atom_structure['key_name'] = (isset($info['quicktime']['temp_meta_key_names'][$metaDATAkey]) ? $info['quicktime']['temp_meta_key_names'][$metaDATAkey] : ''); 1730 $metaDATAkey++; 1760 $atom_structure['key_name'] = (isset($info['quicktime']['temp_meta_key_names'][$this->metaDATAkey]) ? $info['quicktime']['temp_meta_key_names'][$this->metaDATAkey] : ''); 1761 $this->metaDATAkey++; 1762 1763 switch ($atom_structure['key_name']) { 1764 case 'com.android.capture.fps': 1765 $atom_structure['data'] = getid3_lib::BigEndian2Float($atom_structure['data']); 1766 break; 1767 } 1731 1768 1732 1769 if ($atom_structure['key_name'] && $atom_structure['data']) { 1733 @$info['quicktime']['comments'][str_replace('com.a pple.quicktime.', '', $atom_structure['key_name'])][] = $atom_structure['data'];1770 @$info['quicktime']['comments'][str_replace('com.android.', '', str_replace('com.apple.quicktime.', '', $atom_structure['key_name']))][] = $atom_structure['data']; 1734 1771 } 1735 1772 break; … … 1972 2009 preg_match('#^([0-9]{1,3})([0-9]{2}\\.[0-9]+)$#', $GPS_this_GPRMC['raw'][$latlon], $matches); 1973 2010 list($dummy, $deg, $min) = $matches; 1974 $GPS_this_GPRMC[$latlon] = $deg + ($min / 60);2011 $GPS_this_GPRMC[$latlon] = (int) $deg + ((float) $min / 60); 1975 2012 } 1976 2013 $GPS_this_GPRMC['latitude'] *= (($GPS_this_GPRMC['raw']['latitude_direction'] == 'S') ? -1 : 1); … … 1979 2016 $GPS_this_GPRMC['heading'] = $GPS_this_GPRMC['raw']['angle']; 1980 2017 $GPS_this_GPRMC['speed_knot'] = $GPS_this_GPRMC['raw']['knots']; 1981 $GPS_this_GPRMC['speed_kmh'] = $GPS_this_GPRMC['raw']['knots'] * 1.852;2018 $GPS_this_GPRMC['speed_kmh'] = (float) $GPS_this_GPRMC['raw']['knots'] * 1.852; 1982 2019 if ($GPS_this_GPRMC['raw']['variation']) { 1983 $GPS_this_GPRMC['variation'] = $GPS_this_GPRMC['raw']['variation'];2020 $GPS_this_GPRMC['variation'] = (float) $GPS_this_GPRMC['raw']['variation']; 1984 2021 $GPS_this_GPRMC['variation'] *= (($GPS_this_GPRMC['raw']['variation_direction'] == 'W') ? -1 : 1); 1985 2022 } … … 2115 2152 $esds_offset += 1; 2116 2153 if ($atom_structure['ES_DescrTag'] != 0x03) { 2117 $this->warning('expecting esds.ES_DescrTag = 0x03, found 0x'. getid3_lib::PrintHexBytes($atom_structure['ES_DescrTag']).'), at offset '.$atom_structure['offset']);2154 $this->warning('expecting esds.ES_DescrTag = 0x03, found 0x'.sprintf('%02X', $atom_structure['ES_DescrTag']).', at offset '.$atom_structure['offset']); 2118 2155 break; 2119 2156 } … … 2144 2181 $esds_offset += 1; 2145 2182 if ($atom_structure['ES_DecoderConfigDescrTag'] != 0x04) { 2146 $this->warning('expecting esds.ES_DecoderConfigDescrTag = 0x04, found 0x'. getid3_lib::PrintHexBytes($atom_structure['ES_DecoderConfigDescrTag']).'), at offset '.$atom_structure['offset']);2183 $this->warning('expecting esds.ES_DecoderConfigDescrTag = 0x04, found 0x'.sprintf('%02X', $atom_structure['ES_DecoderConfigDescrTag']).', at offset '.$atom_structure['offset']); 2147 2184 break; 2148 2185 } … … 2175 2212 $esds_offset += 1; 2176 2213 if ($atom_structure['ES_DecSpecificInfoTag'] != 0x05) { 2177 $this->warning('expecting esds.ES_DecSpecificInfoTag = 0x05, found 0x'. getid3_lib::PrintHexBytes($atom_structure['ES_DecSpecificInfoTag']).'), at offset '.$atom_structure['offset']);2214 $this->warning('expecting esds.ES_DecSpecificInfoTag = 0x05, found 0x'.sprintf('%02X', $atom_structure['ES_DecSpecificInfoTag']).', at offset '.$atom_structure['offset']); 2178 2215 break; 2179 2216 } … … 2186 2223 $esds_offset += 1; 2187 2224 if ($atom_structure['ES_SLConfigDescrTag'] != 0x06) { 2188 $this->warning('expecting esds.ES_SLConfigDescrTag = 0x05, found 0x'. getid3_lib::PrintHexBytes($atom_structure['ES_SLConfigDescrTag']).'), at offset '.$atom_structure['offset']);2225 $this->warning('expecting esds.ES_SLConfigDescrTag = 0x05, found 0x'.sprintf('%02X', $atom_structure['ES_SLConfigDescrTag']).', at offset '.$atom_structure['offset']); 2189 2226 break; 2190 2227 }
Note: See TracChangeset
for help on using the changeset viewer.