PageRenderTime 224ms CodeModel.GetById 100ms app.highlight 56ms RepoModel.GetById 65ms app.codeStats 0ms

/sys/plugins/id3/getid3/module.audio-video.swf.php

https://bitbucket.org/DESURE/dcms
PHP | 140 lines | 88 code | 27 blank | 25 comment | 12 complexity | 70dae43ff48ba92a36e662de0e964541 MD5 | raw file
  1<?php
  2/////////////////////////////////////////////////////////////////
  3/// getID3() by James Heinrich <info@getid3.org>               //
  4//  available at http://getid3.sourceforge.net                 //
  5//            or http://www.getid3.org                         //
  6//          also https://github.com/JamesHeinrich/getID3       //
  7/////////////////////////////////////////////////////////////////
  8// See readme.txt for more details                             //
  9/////////////////////////////////////////////////////////////////
 10//                                                             //
 11// module.audio-video.swf.php                                  //
 12// module for analyzing Shockwave Flash files                  //
 13// dependencies: NONE                                          //
 14//                                                            ///
 15/////////////////////////////////////////////////////////////////
 16
 17
 18class 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		// http://www.openswf.org/spec/SWFfileformat.html
 29
 30		$this->fseek($info['avdataoffset']);
 31
 32		$SWFfileData = $this->fread($info['avdataend'] - $info['avdataoffset']); // 8 + 2 + 2 + max(9) bytes NOT including Frame_Size RECT data
 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		// http://www-lehre.informatik.uni-osnabrueck.de/~fbstark/diplom/docs/swf/Flash_Uncovered.htm
 76		// Next in the header is the frame rate, which is kind of weird.
 77		// It is supposed to be stored as a 16bit integer, but the first byte
 78		// (or last depending on how you look at it) is completely ignored.
 79		// Example: 0x000C  ->  0x0C  ->  12     So the frame rate is 12 fps.
 80
 81		// Byte at (8 + $FrameSizeDataLength) is always zero and ignored
 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//echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>';
 94
 95
 96		// SWF tags
 97
 98		$CurrentOffset = 12 + $FrameSizeDataLength;
 99		$SWFdataLength = strlen($SWFfileData);
100
101		while ($CurrentOffset < $SWFdataLength) {
102//echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>';
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: // end of movie
120					break 2;
121
122				case 9: // Set background color
123					//$info['swf']['tags'][] = $TagData;
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}