<?php
//
//	file: includes/class_image.php
//	author: ptirhiik
//	begin: 05/03/2006
//	version: 1.6.0 - 10/06/2006
//	license: http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
//
//	based on : attachment_mod copyright (c) 2002 Meik Sievertsen (acydburn)
//

if ( !defined('IN_PHPBB') )
{
	die('Hacking attempt');
	exit;
}

class image_standard
{
	var $handler;
	var $pointer;
	var $buffer;

	function image_standard(&$handler)
	{
		$this->handler = &$handler;
		$this->pointer = 0;
	}

	function image_size($src_file)
	{
		// get the file location
		if ( $this->handler->method != 'ftp' )
		{
			$src_file = phpbb_realpath($src_file);
		}

		// get size from direct hit
		$size = @getimagesize($src_file);
		if ( intval($size[0]) || intval($size[1]) )
		{
			return $size;
		}

		// direct hit failed, get a buffer with the file begin, and try to get the dimension manually, depending on the mimetype
		return $this->process($src_file);
	}

	function process($src_file)
	{
		// read buffer
		$this->buffer = false;
		$this->pointer = 0;
		if ( $fhandler = @fopen($src_file, 'rb') )
		{
			$this->buffer = @fread($fhandler, 1024);
			@fclose($fhandler);
		}
		if ( !$this->buffer )
		{
			return array(0, 0, 0);
		}

		// BMP
		$error = false;
		$this->pointer = 0;
		$sig = read_string(2);
		if ( $sig == 'BM' )
		{
			// length
			$error = (read_longint() <= 6);

			// marker
			$error = $error || (read_longint() != 0);

			// type
			$error = $error || !in_array(read_longint(), array(0x3E, 0x76, 0x436, 0x36));

			// go with size
			if ( !$error )
			{
				$this->pointer += 4;
				$width = read_longint();
				$height = read_longint();
				$error = ($width > 3000) || ($height > 3000);
			}

			// return result
			if ( !$error )
			{
				return array($width, $height, 6);
			}
		}

		// GIF
		$error = false;
		$this->pointer = 0;
		$sig = read_string(3);
		if ( $sig == 'GIF' )
		{
			$this->pointer += 3;
			$width = read_word();
			$height = read_word();

			$info_byte = read_byte();
			$error = (($info_byte & 0x80) != 0x80) && (($info_byte & 0x80) != 0) && (($info_byte & 8) != 0);

			// return result
			if ( !$error )
			{
				return array($width, $height, 1);
			}
		}

		// JPEG
		$error = false;
		$this->pointer = 4;
		$sig = read_word();
		if ( $sig >= 16 )
		{
			if ( read_string(4) == 'JFIF' )
			{
				$error = (intval(read_string(1)) != 0);
				$this->pointer += 2;
				$error = $error || !in_array(read_byte(), array(0, 1, 2));
				if ( !$error )
				{
					$width = read_word();
					$height = read_word();
					$error = ($width <= 0) || ($height <= 0);
				}

				// return result
				if ( !$error )
				{
					return array($width, $height, 2);
				}
			}
		}

		// PCX - IMAGE
		$error = false;
		$this->pointer = 0;
		if ( (read_byte() == 10) && in_array(read_byte(), array(0, 2, 3, 4, 5)) && (read_byte() == 1) )
		{
			$error = !in_array(read_byte(), array(1, 2, 4, 8, 24));
			if ( !$error )
			{
				$xmin = read_word();
				$ymin = read_word();
				$xmax = read_word();
				$ymax = read_word();
				$this->pointer += 52;
				$error = $error || (intval(read_string(1)) != 0);

				// return result
				if ( !$error )
				{
					$width = $xmax - $xmin + 1;
					$height = $ymax - $ymin + 1;
					return array($width, $height, 7);
				}
			}
		}

		return array(0, 0, 0);
	}

	// Read Long Int (4 Bytes)
	function read_longint()
	{
		$data = substr($this->buffer, $this->pointer, 4);
		$this->pointer += 4;
		$value = ord($data[0]) + (ord($data[1])<<8)+(ord($data[2])<<16)+(ord($data[3])<<24);
		if ($value >= 4294967294)
		{
			$value -= 4294967296;
		}
		return $value;
	}

	// Read Word (2 Bytes) - Note: It's an Intel Word
	function read_word()
	{
		$data = substr($this->buffer, $this->pointer, 2);
		$this->pointer += 2;
		$value = ord($data[1]) * 256 + ord($data[0]);
		return $value;
	}

	// Read Byte
	function read_byte()
	{
		$data = substr($this->buffer, $this->pointer, 1);
		$this->pointer++;
		$value = ord($data);
		return $value;
	}

	// read string
	function read_string($len)
	{
		$value = substr($this->buffer, $this->pointer, $len);
		$this->pointer += $len;
		return $value;
	}
}

//
// Flash MX Support
// Routines and Methods are from PhpAdsNew (www.sourceforge.net/projects/phpadsnew)
//
define('swf_tag_compressed', chr(0x43).chr(0x57).chr(0x53));
define('swf_tag_identify', chr(0x46).chr(0x57).chr(0x53));

class image_flash extends image_standard
{
	function process($src_file)
	{
		// read buffer
		$this->buffer = false;
		$this->pointer = 0;
		$do_uncompress = false;
		if ( $fhandler = @fopen($src_file, 'rb') )
		{
			$this->buffer = @fread($fhandler, 1024);
			if ( $do_uncompress = $this->buffer && function_exists('gzuncompress') && (substr($this->buffer, 0, 3) == swf_tag_compressed) && (ord(substr($this->buffer, 3, 1)) >= 6) )
			{
				if ( ($filesize = @filesize($fhandler)) && ($filesize > 1024) )
				{
					$this->buffer .= @fread($fhandler, $filesize - 1024);
				}
			}
			@fclose($fhandler);
			if ( $do_uncompress )
			{
				// Only decompress relevant Informations
				$buffer = 'F';
				$buffer .= substr($this->buffer, 1, 7);
				$buffer .= gzuncompress(substr($this->buffer, 8));
				$this->buffer = $buffer;
				unset($buffer);
			}
		}
		if ( !$this->buffer )
		{
			return array(0, 0, 0);
		}

		// Get size of rect structure
		$bits = swf_bits(64, 5);

		// Get rect
		$width  = intval((swf_bits(69 + $bits, $bits) - swf_bits(69, $bits)) / 20);
		$height = intval((swf_bits(69 + (3 * $bits), $bits) - swf_bits(69 + (2 * $bits), $bits)) / 20);
	}

	// Get flash bits
	function swf_bits($pos, $count)
	{
		$result = 0;
		$count_loop = $pos + $count;
		for ( $loop = $pos; $loop < $count_loop; $loop++ )
		{
			$result = $result + (((ord($this->buffer[ intval($loop / 8) ]) >> (7 - ($loop % 8))) & 0x01) << ($count_loop - 1 - $loop));
		}
		return intval($result);
	}
}

?>