- Timestamp:
- Jul 7, 2009, 10:27:37 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/charlies_content/getid3/getid3/module.audio-video.swf.php
r3318 r3544 1 1 <?php 2 // +----------------------------------------------------------------------+ 3 // | PHP version 5 | 4 // +----------------------------------------------------------------------+ 5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen | 6 // +----------------------------------------------------------------------+ 7 // | This source file is subject to version 2 of the GPL license, | 8 // | that is bundled with this package in the file license.txt and is | 9 // | available through the world-wide-web at the following url: | 10 // | http://www.gnu.org/copyleft/gpl.html | 11 // +----------------------------------------------------------------------+ 12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org | 13 // +----------------------------------------------------------------------+ 14 // | Authors: James Heinrich <infoØgetid3*org> | 15 // | Allan Hansen <ahØartemis*dk> | 16 // +----------------------------------------------------------------------+ 17 // | module.audio-video.swf.php | 18 // | module for analyzing Macromedia Shockwave Flash files. | 19 // | dependencies: zlib support in PHP | 20 // +----------------------------------------------------------------------+ 21 // 22 // $Id$ 2 ///////////////////////////////////////////////////////////////// 3 /// getID3() by James Heinrich <info@getid3.org> // 4 // available at http://getid3.sourceforge.net // 5 // or http://www.getid3.org // 6 ///////////////////////////////////////////////////////////////// 7 // See readme.txt for more details // 8 ///////////////////////////////////////////////////////////////// 9 // // 10 // module.audio-video.swf.php // 11 // module for analyzing Shockwave Flash files // 12 // dependencies: NONE // 13 // /// 14 ///////////////////////////////////////////////////////////////// 23 15 24 25 26 class getid3_swf extends getid3_handler 16 17 class getid3_swf 27 18 { 28 19 29 public function Analyze() { 30 31 $getid3 = $this->getid3; 32 33 $getid3->info['fileformat'] = 'swf'; 34 $getid3->info['video']['dataformat'] = 'swf'; 20 function getid3_swf(&$fd, &$ThisFileInfo, $ReturnAllTagData=false) { 21 //$start_time = microtime(true); 22 $ThisFileInfo['fileformat'] = 'swf'; 23 $ThisFileInfo['video']['dataformat'] = 'swf'; 35 24 36 25 // http://www.openswf.org/spec/SWFfileformat.html 37 26 38 fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET);27 fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET); 39 28 40 $swf_file_data = fread($getid3->fp, $getid3->info['avdataend'] - $getid3->info['avdataoffset']); // 8 + 2 + 2 + max(9) bytes NOT including Frame_Size RECT data29 $SWFfileData = fread($fd, $ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']); // 8 + 2 + 2 + max(9) bytes NOT including Frame_Size RECT data 41 30 42 $getid3->info['swf']['header']['signature'] = substr($swf_file_data, 0, 3); 43 switch ($getid3->info['swf']['header']['signature']) { 44 45 case 'FWS': 46 $getid3->info['swf']['header']['compressed'] = false; 47 break; 31 $ThisFileInfo['swf']['header']['signature'] = substr($SWFfileData, 0, 3); 32 switch ($ThisFileInfo['swf']['header']['signature']) { 33 case 'FWS': 34 $ThisFileInfo['swf']['header']['compressed'] = false; 35 break; 48 36 49 50 $getid3->info['swf']['header']['compressed'] = true;51 37 case 'CWS': 38 $ThisFileInfo['swf']['header']['compressed'] = true; 39 break; 52 40 53 default: 54 throw new getid3_exception('Expecting "FWS" or "CWS" at offset '.$getid3->info['avdataoffset'].', found "'.$getid3->info['swf']['header']['signature'].'"'); 55 } 56 $getid3->info['swf']['header']['version'] = getid3_lib::LittleEndian2Int($swf_file_data{3}); 57 $getid3->info['swf']['header']['length'] = getid3_lib::LittleEndian2Int(substr($swf_file_data, 4, 4)); 41 default: 42 $ThisFileInfo['error'][] = 'Expecting "FWS" or "CWS" at offset '.$ThisFileInfo['avdataoffset'].', found "'.$ThisFileInfo['swf']['header']['signature'].'"'; 43 unset($ThisFileInfo['swf']); 44 unset($ThisFileInfo['fileformat']); 45 return false; 46 break; 47 } 48 $ThisFileInfo['swf']['header']['version'] = getid3_lib::LittleEndian2Int(substr($SWFfileData, 3, 1)); 49 $ThisFileInfo['swf']['header']['length'] = getid3_lib::LittleEndian2Int(substr($SWFfileData, 4, 4)); 58 50 59 if (!function_exists('gzuncompress')) { 60 throw new getid3_exception('getid3_swf requires --zlib support in PHP.'); 61 } 51 //echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>'; 62 52 63 if ($getid3->info['swf']['header']['compressed']) {53 if ($ThisFileInfo['swf']['header']['compressed']) { 64 54 65 if ($uncompressed_file_data = @gzuncompress(substr($swf_file_data, 8))) { 66 $swf_file_data = substr($swf_file_data, 0, 8).$uncompressed_file_data; 55 $SWFHead = substr($SWFfileData, 0, 8); 56 $SWFfileData = substr($SWFfileData, 8); 57 if ($decompressed = @gzuncompress($SWFfileData)) { 67 58 68 } else { 69 throw new getid3_exception('Error decompressing compressed SWF data'); 70 } 59 $SWFfileData = $SWFHead.$decompressed; 71 60 72 } 61 } else { 73 62 74 $frame_size_bits_per_value = (ord(substr($swf_file_data, 8, 1)) & 0xF8) >> 3; 75 $frame_size_data_length = ceil((5 + (4 * $frame_size_bits_per_value)) / 8); 76 $frame_size_data_string = str_pad(decbin(ord($swf_file_data[8]) & 0x07), 3, '0', STR_PAD_LEFT); 77 78 for ($i = 1; $i < $frame_size_data_length; $i++) { 79 $frame_size_data_string .= str_pad(decbin(ord(substr($swf_file_data, 8 + $i, 1))), 8, '0', STR_PAD_LEFT); 80 } 81 82 list($x1, $x2, $y1, $y2) = explode("\n", wordwrap($frame_size_data_string, $frame_size_bits_per_value, "\n", 1)); 83 $getid3->info['swf']['header']['frame_width'] = bindec($x2); 84 $getid3->info['swf']['header']['frame_height'] = bindec($y2); 63 $ThisFileInfo['error'][] = 'Error decompressing compressed SWF data ('.strlen($SWFfileData).' bytes compressed, should be '.($ThisFileInfo['swf']['header']['length'] - 8).' bytes uncompressed)'; 64 return false; 85 65 86 // http://www-lehre.informatik.uni-osnabrueck.de/~fbstark/diplom/docs/swf/Flash_Uncovered.htm 87 // Next in the header is the frame rate, which is kind of weird. 88 // It is supposed to be stored as a 16bit integer, but the first byte 89 // (or last depending on how you look at it) is completely ignored. 90 // Example: 0x000C -> 0x0C -> 12 So the frame rate is 12 fps. 66 } 91 67 92 // Byte at (8 + $frame_size_data_length) is always zero and ignored 93 $getid3->info['swf']['header']['frame_rate'] = getid3_lib::LittleEndian2Int($swf_file_data[9 + $frame_size_data_length]); 94 $getid3->info['swf']['header']['frame_count'] = getid3_lib::LittleEndian2Int(substr($swf_file_data, 10 + $frame_size_data_length, 2)); 68 } 69 //echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>'; 95 70 96 $getid3->info['video']['frame_rate'] = $getid3->info['swf']['header']['frame_rate']; 97 $getid3->info['video']['resolution_x'] = intval(round($getid3->info['swf']['header']['frame_width'] / 20)); 98 $getid3->info['video']['resolution_y'] = intval(round($getid3->info['swf']['header']['frame_height'] / 20)); 99 $getid3->info['video']['pixel_aspect_ratio'] = (float)1; 71 $FrameSizeBitsPerValue = (ord(substr($SWFfileData, 8, 1)) & 0xF8) >> 3; 72 $FrameSizeDataLength = ceil((5 + (4 * $FrameSizeBitsPerValue)) / 8); 73 $FrameSizeDataString = str_pad(decbin(ord(substr($SWFfileData, 8, 1)) & 0x07), 3, '0', STR_PAD_LEFT); 74 for ($i = 1; $i < $FrameSizeDataLength; $i++) { 75 $FrameSizeDataString .= str_pad(decbin(ord(substr($SWFfileData, 8 + $i, 1))), 8, '0', STR_PAD_LEFT); 76 } 77 list($X1, $X2, $Y1, $Y2) = explode("\n", wordwrap($FrameSizeDataString, $FrameSizeBitsPerValue, "\n", 1)); 78 $ThisFileInfo['swf']['header']['frame_width'] = getid3_lib::Bin2Dec($X2); 79 $ThisFileInfo['swf']['header']['frame_height'] = getid3_lib::Bin2Dec($Y2); 100 80 101 if (($getid3->info['swf']['header']['frame_count'] > 0) && ($getid3->info['swf']['header']['frame_rate'] > 0)) { 102 $getid3->info['playtime_seconds'] = $getid3->info['swf']['header']['frame_count'] / $getid3->info['swf']['header']['frame_rate']; 103 } 81 // http://www-lehre.informatik.uni-osnabrueck.de/~fbstark/diplom/docs/swf/Flash_Uncovered.htm 82 // Next in the header is the frame rate, which is kind of weird. 83 // It is supposed to be stored as a 16bit integer, but the first byte 84 // (or last depending on how you look at it) is completely ignored. 85 // Example: 0x000C -> 0x0C -> 12 So the frame rate is 12 fps. 86 87 // Byte at (8 + $FrameSizeDataLength) is always zero and ignored 88 $ThisFileInfo['swf']['header']['frame_rate'] = getid3_lib::LittleEndian2Int(substr($SWFfileData, 9 + $FrameSizeDataLength, 1)); 89 $ThisFileInfo['swf']['header']['frame_count'] = getid3_lib::LittleEndian2Int(substr($SWFfileData, 10 + $FrameSizeDataLength, 2)); 90 91 $ThisFileInfo['video']['frame_rate'] = $ThisFileInfo['swf']['header']['frame_rate']; 92 $ThisFileInfo['video']['resolution_x'] = intval(round($ThisFileInfo['swf']['header']['frame_width'] / 20)); 93 $ThisFileInfo['video']['resolution_y'] = intval(round($ThisFileInfo['swf']['header']['frame_height'] / 20)); 94 $ThisFileInfo['video']['pixel_aspect_ratio'] = (float) 1; 95 96 if (($ThisFileInfo['swf']['header']['frame_count'] > 0) && ($ThisFileInfo['swf']['header']['frame_rate'] > 0)) { 97 $ThisFileInfo['playtime_seconds'] = $ThisFileInfo['swf']['header']['frame_count'] / $ThisFileInfo['swf']['header']['frame_rate']; 98 } 99 //echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>'; 104 100 105 101 106 102 // SWF tags 107 103 108 $current_offset = 12 + $frame_size_data_length;109 $swf_data_length = strlen($swf_file_data);104 $CurrentOffset = 12 + $FrameSizeDataLength; 105 $SWFdataLength = strlen($SWFfileData); 110 106 111 while ($current_offset < $swf_data_length) { 107 while ($CurrentOffset < $SWFdataLength) { 108 //echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>'; 112 109 113 $tag_ID_tag_length = getid3_lib::LittleEndian2Int(substr($swf_file_data, $current_offset, 2));114 $tag_ID = ($tag_ID_tag_length & 0xFFFC) >> 6;115 $tag_length = ($tag_ID_tag_length & 0x003F);116 $current_offset += 2;117 if ($tag_length == 0x3F) {118 $tag_length = getid3_lib::LittleEndian2Int(substr($swf_file_data, $current_offset, 4));119 $current_offset += 4;120 110 $TagIDTagLength = getid3_lib::LittleEndian2Int(substr($SWFfileData, $CurrentOffset, 2)); 111 $TagID = ($TagIDTagLength & 0xFFFC) >> 6; 112 $TagLength = ($TagIDTagLength & 0x003F); 113 $CurrentOffset += 2; 114 if ($TagLength == 0x3F) { 115 $TagLength = getid3_lib::LittleEndian2Int(substr($SWFfileData, $CurrentOffset, 4)); 116 $CurrentOffset += 4; 117 } 121 118 122 unset($tag_data); 123 $tag_data['offset'] = $current_offset; 124 $tag_data['size'] = $tag_length; 125 $tag_data['id'] = $tag_ID; 126 $tag_data['data'] = substr($swf_file_data, $current_offset, $tag_length); 127 switch ($tag_ID) { 128 129 case 0: // end of movie 130 break 2; 119 unset($TagData); 120 $TagData['offset'] = $CurrentOffset; 121 $TagData['size'] = $TagLength; 122 $TagData['id'] = $TagID; 123 $TagData['data'] = substr($SWFfileData, $CurrentOffset, $TagLength); 124 switch ($TagID) { 125 case 0: // end of movie 126 break 2; 131 127 132 case 9: // Set background color 133 $getid3->info['swf']['bgcolor'] = strtoupper(str_pad(dechex(getid3_lib::BigEndian2Int($tag_data['data'])), 6, '0', STR_PAD_LEFT)); 134 break; 128 case 9: // Set background color 129 //$ThisFileInfo['swf']['tags'][] = $TagData; 130 $ThisFileInfo['swf']['bgcolor'] = strtoupper(str_pad(dechex(getid3_lib::BigEndian2Int($TagData['data'])), 6, '0', STR_PAD_LEFT)); 131 break; 135 132 136 default: 137 /* 138 if ($ReturnAllTagData) { 139 $getid3->info['swf']['tags'][] = $tag_data; 140 } 141 */ 142 break; 143 } 133 default: 134 if ($ReturnAllTagData) { 135 $ThisFileInfo['swf']['tags'][] = $TagData; 136 } 137 break; 138 } 144 139 145 $current_offset += $tag_length;146 140 $CurrentOffset += $TagLength; 141 } 147 142 148 149 143 return true; 144 } 150 145 151 146 }
Note: See TracChangeset
for help on using the changeset viewer.