ILIAS  release_4-3 Revision
 All Data Structures Namespaces Files Functions Variables Groups Pages
module.audio-video.swf.php
Go to the documentation of this file.
1 <?php
4 // available at http://getid3.sourceforge.net //
5 // or http://www.getid3.org //
7 // See readme.txt for more details //
9 // //
10 // module.audio-video.swf.php //
11 // module for analyzing Shockwave Flash files //
12 // dependencies: NONE //
13 // ///
15 
16 
18 {
19 
20  function getid3_swf(&$fd, &$ThisFileInfo, $ReturnAllTagData=false) {
21  $ThisFileInfo['fileformat'] = 'swf';
22  $ThisFileInfo['video']['dataformat'] = 'swf';
23 
24  // http://www.openswf.org/spec/SWFfileformat.html
25 
26  fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
27 
28 //echo 'reading '.($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']).' bytes<br>';
29  $SWFfileData = fread($fd, $ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']); // 8 + 2 + 2 + max(9) bytes NOT including Frame_Size RECT data
30 
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;
36 
37  case 'CWS':
38  $ThisFileInfo['swf']['header']['compressed'] = true;
39  break;
40 
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));
50 
51 //echo '1<br>';
52  if ($ThisFileInfo['swf']['header']['compressed']) {
53 
54 //echo '2<br>';
55 // $foo = substr($SWFfileData, 8, 4096);
56 // echo '['.strlen($foo).']<br>';
57 // $fee = gzuncompress($foo);
58 // echo '('.strlen($fee).')<br>';
59 //return false;
60 //echo '<br>time: '.time().'<br>';
61 //return false;
62  if ($UncompressedFileData = gzuncompress(substr($SWFfileData, 8))) {
63 
64 //echo '3<br>';
65  $SWFfileData = substr($SWFfileData, 0, 8).$UncompressedFileData;
66 
67  } else {
68 
69 //echo '4<br>';
70  $ThisFileInfo['error'][] = 'Error decompressing compressed SWF data';
71  return false;
72 
73  }
74 
75  }
76 
77  $FrameSizeBitsPerValue = (ord(substr($SWFfileData, 8, 1)) & 0xF8) >> 3;
78  $FrameSizeDataLength = ceil((5 + (4 * $FrameSizeBitsPerValue)) / 8);
79  $FrameSizeDataString = str_pad(decbin(ord(substr($SWFfileData, 8, 1)) & 0x07), 3, '0', STR_PAD_LEFT);
80  for ($i = 1; $i < $FrameSizeDataLength; $i++) {
81  $FrameSizeDataString .= str_pad(decbin(ord(substr($SWFfileData, 8 + $i, 1))), 8, '0', STR_PAD_LEFT);
82  }
83  list($X1, $X2, $Y1, $Y2) = explode("\n", wordwrap($FrameSizeDataString, $FrameSizeBitsPerValue, "\n", 1));
84  $ThisFileInfo['swf']['header']['frame_width'] = getid3_lib::Bin2Dec($X2);
85  $ThisFileInfo['swf']['header']['frame_height'] = getid3_lib::Bin2Dec($Y2);
86 
87  // http://www-lehre.informatik.uni-osnabrueck.de/~fbstark/diplom/docs/swf/Flash_Uncovered.htm
88  // Next in the header is the frame rate, which is kind of weird.
89  // It is supposed to be stored as a 16bit integer, but the first byte
90  // (or last depending on how you look at it) is completely ignored.
91  // Example: 0x000C -> 0x0C -> 12 So the frame rate is 12 fps.
92 
93  // Byte at (8 + $FrameSizeDataLength) is always zero and ignored
94  $ThisFileInfo['swf']['header']['frame_rate'] = getid3_lib::LittleEndian2Int(substr($SWFfileData, 9 + $FrameSizeDataLength, 1));
95  $ThisFileInfo['swf']['header']['frame_count'] = getid3_lib::LittleEndian2Int(substr($SWFfileData, 10 + $FrameSizeDataLength, 2));
96 
97  $ThisFileInfo['video']['frame_rate'] = $ThisFileInfo['swf']['header']['frame_rate'];
98  $ThisFileInfo['video']['resolution_x'] = intval(round($ThisFileInfo['swf']['header']['frame_width'] / 20));
99  $ThisFileInfo['video']['resolution_y'] = intval(round($ThisFileInfo['swf']['header']['frame_height'] / 20));
100  $ThisFileInfo['video']['pixel_aspect_ratio'] = (float) 1;
101 
102  if (($ThisFileInfo['swf']['header']['frame_count'] > 0) && ($ThisFileInfo['swf']['header']['frame_rate'] > 0)) {
103  $ThisFileInfo['playtime_seconds'] = $ThisFileInfo['swf']['header']['frame_count'] / $ThisFileInfo['swf']['header']['frame_rate'];
104  }
105 
106 
107  // SWF tags
108 
109  $CurrentOffset = 12 + $FrameSizeDataLength;
110  $SWFdataLength = strlen($SWFfileData);
111 
112  while ($CurrentOffset < $SWFdataLength) {
113 
114  $TagIDTagLength = getid3_lib::LittleEndian2Int(substr($SWFfileData, $CurrentOffset, 2));
115  $TagID = ($TagIDTagLength & 0xFFFC) >> 6;
116  $TagLength = ($TagIDTagLength & 0x003F);
117  $CurrentOffset += 2;
118  if ($TagLength == 0x3F) {
119  $TagLength = getid3_lib::LittleEndian2Int(substr($SWFfileData, $CurrentOffset, 4));
120  $CurrentOffset += 4;
121  }
122 
123  unset($TagData);
124  $TagData['offset'] = $CurrentOffset;
125  $TagData['size'] = $TagLength;
126  $TagData['id'] = $TagID;
127  $TagData['data'] = substr($SWFfileData, $CurrentOffset, $TagLength);
128  switch ($TagID) {
129  case 0: // end of movie
130  break 2;
131 
132  case 9: // Set background color
133  //$ThisFileInfo['swf']['tags'][] = $TagData;
134  $ThisFileInfo['swf']['bgcolor'] = strtoupper(str_pad(dechex(getid3_lib::BigEndian2Int($TagData['data'])), 6, '0', STR_PAD_LEFT));
135  break;
136 
137  default:
138  if ($ReturnAllTagData) {
139  $ThisFileInfo['swf']['tags'][] = $TagData;
140  }
141  break;
142  }
143 
144  $CurrentOffset += $TagLength;
145  }
146 
147  return true;
148  }
149 
150 }
151 
152 
153 ?>