1: <?php
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18: class getid3_swf extends getid3_handler
19: {
20: public $ReturnAllTagData = false;
21:
22: public function Analyze() {
23: $info = &$this->getid3->info;
24:
25: $info['fileformat'] = 'swf';
26: $info['video']['dataformat'] = 'swf';
27:
28:
29:
30: $this->fseek($info['avdataoffset']);
31:
32: $SWFfileData = $this->fread($info['avdataend'] - $info['avdataoffset']);
33:
34: $info['swf']['header']['signature'] = substr($SWFfileData, 0, 3);
35: switch ($info['swf']['header']['signature']) {
36: case 'FWS':
37: $info['swf']['header']['compressed'] = false;
38: break;
39:
40: case 'CWS':
41: $info['swf']['header']['compressed'] = true;
42: break;
43:
44: default:
45: $info['error'][] = 'Expecting "FWS" or "CWS" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($info['swf']['header']['signature']).'"';
46: unset($info['swf']);
47: unset($info['fileformat']);
48: return false;
49: break;
50: }
51: $info['swf']['header']['version'] = getid3_lib::LittleEndian2Int(substr($SWFfileData, 3, 1));
52: $info['swf']['header']['length'] = getid3_lib::LittleEndian2Int(substr($SWFfileData, 4, 4));
53:
54: if ($info['swf']['header']['compressed']) {
55: $SWFHead = substr($SWFfileData, 0, 8);
56: $SWFfileData = substr($SWFfileData, 8);
57: if ($decompressed = @gzuncompress($SWFfileData)) {
58: $SWFfileData = $SWFHead.$decompressed;
59: } else {
60: $info['error'][] = 'Error decompressing compressed SWF data ('.strlen($SWFfileData).' bytes compressed, should be '.($info['swf']['header']['length'] - 8).' bytes uncompressed)';
61: return false;
62: }
63: }
64:
65: $FrameSizeBitsPerValue = (ord(substr($SWFfileData, 8, 1)) & 0xF8) >> 3;
66: $FrameSizeDataLength = ceil((5 + (4 * $FrameSizeBitsPerValue)) / 8);
67: $FrameSizeDataString = str_pad(decbin(ord(substr($SWFfileData, 8, 1)) & 0x07), 3, '0', STR_PAD_LEFT);
68: for ($i = 1; $i < $FrameSizeDataLength; $i++) {
69: $FrameSizeDataString .= str_pad(decbin(ord(substr($SWFfileData, 8 + $i, 1))), 8, '0', STR_PAD_LEFT);
70: }
71: list($X1, $X2, $Y1, $Y2) = explode("\n", wordwrap($FrameSizeDataString, $FrameSizeBitsPerValue, "\n", 1));
72: $info['swf']['header']['frame_width'] = getid3_lib::Bin2Dec($X2);
73: $info['swf']['header']['frame_height'] = getid3_lib::Bin2Dec($Y2);
74:
75:
76:
77:
78:
79:
80:
81:
82: $info['swf']['header']['frame_rate'] = getid3_lib::LittleEndian2Int(substr($SWFfileData, 9 + $FrameSizeDataLength, 1));
83: $info['swf']['header']['frame_count'] = getid3_lib::LittleEndian2Int(substr($SWFfileData, 10 + $FrameSizeDataLength, 2));
84:
85: $info['video']['frame_rate'] = $info['swf']['header']['frame_rate'];
86: $info['video']['resolution_x'] = intval(round($info['swf']['header']['frame_width'] / 20));
87: $info['video']['resolution_y'] = intval(round($info['swf']['header']['frame_height'] / 20));
88: $info['video']['pixel_aspect_ratio'] = (float) 1;
89:
90: if (($info['swf']['header']['frame_count'] > 0) && ($info['swf']['header']['frame_rate'] > 0)) {
91: $info['playtime_seconds'] = $info['swf']['header']['frame_count'] / $info['swf']['header']['frame_rate'];
92: }
93:
94:
95:
96:
97:
98: $CurrentOffset = 12 + $FrameSizeDataLength;
99: $SWFdataLength = strlen($SWFfileData);
100:
101: while ($CurrentOffset < $SWFdataLength) {
102:
103:
104: $TagIDTagLength = getid3_lib::LittleEndian2Int(substr($SWFfileData, $CurrentOffset, 2));
105: $TagID = ($TagIDTagLength & 0xFFFC) >> 6;
106: $TagLength = ($TagIDTagLength & 0x003F);
107: $CurrentOffset += 2;
108: if ($TagLength == 0x3F) {
109: $TagLength = getid3_lib::LittleEndian2Int(substr($SWFfileData, $CurrentOffset, 4));
110: $CurrentOffset += 4;
111: }
112:
113: unset($TagData);
114: $TagData['offset'] = $CurrentOffset;
115: $TagData['size'] = $TagLength;
116: $TagData['id'] = $TagID;
117: $TagData['data'] = substr($SWFfileData, $CurrentOffset, $TagLength);
118: switch ($TagID) {
119: case 0:
120: break 2;
121:
122: case 9:
123:
124: $info['swf']['bgcolor'] = strtoupper(str_pad(dechex(getid3_lib::BigEndian2Int($TagData['data'])), 6, '0', STR_PAD_LEFT));
125: break;
126:
127: default:
128: if ($this->ReturnAllTagData) {
129: $info['swf']['tags'][] = $TagData;
130: }
131: break;
132: }
133:
134: $CurrentOffset += $TagLength;
135: }
136:
137: return true;
138: }
139:
140: }
141: