github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/public/libs/tinymce/plugins/jbimages/ci/system/libraries/Image_lib.php (about)

     1  <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
     2  /**
     3   * CodeIgniter
     4   *
     5   * An open source application development framework for PHP 5.1.6 or newer
     6   *
     7   * @package		CodeIgniter
     8   * @author		ExpressionEngine Dev Team
     9   * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
    10   * @license		http://codeigniter.com/user_guide/license.html
    11   * @link		http://codeigniter.com
    12   * @since		Version 1.0
    13   * @filesource
    14   */
    15  
    16  // ------------------------------------------------------------------------
    17  
    18  /**
    19   * Image Manipulation class
    20   *
    21   * @package		CodeIgniter
    22   * @subpackage	Libraries
    23   * @category	Image_lib
    24   * @author		ExpressionEngine Dev Team
    25   * @link		http://codeigniter.com/user_guide/libraries/image_lib.html
    26   */
    27  class CI_Image_lib {
    28  
    29  	var $image_library		= 'gd2';	// Can be:  imagemagick, netpbm, gd, gd2
    30  	var $library_path		= '';
    31  	var $dynamic_output		= FALSE;	// Whether to send to browser or write to disk
    32  	var $source_image		= '';
    33  	var $new_image			= '';
    34  	var $width				= '';
    35  	var $height				= '';
    36  	var $quality			= '90';
    37  	var $create_thumb		= FALSE;
    38  	var $thumb_marker		= '_thumb';
    39  	var $maintain_ratio		= TRUE;		// Whether to maintain aspect ratio when resizing or use hard values
    40  	var $master_dim			= 'auto';	// auto, height, or width.  Determines what to use as the master dimension
    41  	var $rotation_angle		= '';
    42  	var $x_axis				= '';
    43  	var	$y_axis				= '';
    44  
    45  	// Watermark Vars
    46  	var $wm_text			= '';			// Watermark text if graphic is not used
    47  	var $wm_type			= 'text';		// Type of watermarking.  Options:  text/overlay
    48  	var $wm_x_transp		= 4;
    49  	var $wm_y_transp		= 4;
    50  	var $wm_overlay_path	= '';			// Watermark image path
    51  	var $wm_font_path		= '';			// TT font
    52  	var $wm_font_size		= 17;			// Font size (different versions of GD will either use points or pixels)
    53  	var $wm_vrt_alignment	= 'B';			// Vertical alignment:   T M B
    54  	var $wm_hor_alignment	= 'C';			// Horizontal alignment: L R C
    55  	var $wm_padding			= 0;			// Padding around text
    56  	var $wm_hor_offset		= 0;			// Lets you push text to the right
    57  	var $wm_vrt_offset		= 0;			// Lets you push  text down
    58  	var $wm_font_color		= '#ffffff';	// Text color
    59  	var $wm_shadow_color	= '';			// Dropshadow color
    60  	var $wm_shadow_distance	= 2;			// Dropshadow distance
    61  	var $wm_opacity			= 50;			// Image opacity: 1 - 100  Only works with image
    62  
    63  	// Private Vars
    64  	var $source_folder		= '';
    65  	var $dest_folder		= '';
    66  	var $mime_type			= '';
    67  	var $orig_width			= '';
    68  	var $orig_height		= '';
    69  	var $image_type			= '';
    70  	var $size_str			= '';
    71  	var $full_src_path		= '';
    72  	var $full_dst_path		= '';
    73  	var $create_fnc			= 'imagecreatetruecolor';
    74  	var $copy_fnc			= 'imagecopyresampled';
    75  	var $error_msg			= array();
    76  	var $wm_use_drop_shadow	= FALSE;
    77  	var $wm_use_truetype	= FALSE;
    78  
    79  	/**
    80  	 * Constructor
    81  	 *
    82  	 * @param	string
    83  	 * @return	void
    84  	 */
    85  	public function __construct($props = array())
    86  	{
    87  		if (count($props) > 0)
    88  		{
    89  			$this->initialize($props);
    90  		}
    91  
    92  		log_message('debug', "Image Lib Class Initialized");
    93  	}
    94  
    95  	// --------------------------------------------------------------------
    96  
    97  	/**
    98  	 * Initialize image properties
    99  	 *
   100  	 * Resets values in case this class is used in a loop
   101  	 *
   102  	 * @access	public
   103  	 * @return	void
   104  	 */
   105  	function clear()
   106  	{
   107  		$props = array('source_folder', 'dest_folder', 'source_image', 'full_src_path', 'full_dst_path', 'new_image', 'image_type', 'size_str', 'quality', 'orig_width', 'orig_height', 'width', 'height', 'rotation_angle', 'x_axis', 'y_axis', 'create_fnc', 'copy_fnc', 'wm_overlay_path', 'wm_use_truetype', 'dynamic_output', 'wm_font_size', 'wm_text', 'wm_vrt_alignment', 'wm_hor_alignment', 'wm_padding', 'wm_hor_offset', 'wm_vrt_offset', 'wm_font_color', 'wm_use_drop_shadow', 'wm_shadow_color', 'wm_shadow_distance', 'wm_opacity');
   108  
   109  		foreach ($props as $val)
   110  		{
   111  			$this->$val = '';
   112  		}
   113  
   114  		// special consideration for master_dim
   115  		$this->master_dim = 'auto';
   116  	}
   117  
   118  	// --------------------------------------------------------------------
   119  
   120  	/**
   121  	 * initialize image preferences
   122  	 *
   123  	 * @access	public
   124  	 * @param	array
   125  	 * @return	bool
   126  	 */
   127  	function initialize($props = array())
   128  	{
   129  		/*
   130  		 * Convert array elements into class variables
   131  		 */
   132  		if (count($props) > 0)
   133  		{
   134  			foreach ($props as $key => $val)
   135  			{
   136  				$this->$key = $val;
   137  			}
   138  		}
   139  
   140  		/*
   141  		 * Is there a source image?
   142  		 *
   143  		 * If not, there's no reason to continue
   144  		 *
   145  		 */
   146  		if ($this->source_image == '')
   147  		{
   148  			$this->set_error('imglib_source_image_required');
   149  			return FALSE;	
   150  		}
   151  
   152  		/*
   153  		 * Is getimagesize() Available?
   154  		 *
   155  		 * We use it to determine the image properties (width/height).
   156  		 * Note:  We need to figure out how to determine image
   157  		 * properties using ImageMagick and NetPBM
   158  		 *
   159  		 */
   160  		if ( ! function_exists('getimagesize'))
   161  		{
   162  			$this->set_error('imglib_gd_required_for_props');
   163  			return FALSE;
   164  		}
   165  
   166  		$this->image_library = strtolower($this->image_library);
   167  
   168  		/*
   169  		 * Set the full server path
   170  		 *
   171  		 * The source image may or may not contain a path.
   172  		 * Either way, we'll try use realpath to generate the
   173  		 * full server path in order to more reliably read it.
   174  		 *
   175  		 */
   176  		if (function_exists('realpath') AND @realpath($this->source_image) !== FALSE)
   177  		{
   178  			$full_source_path = str_replace("\\", "/", realpath($this->source_image));
   179  		}
   180  		else
   181  		{
   182  			$full_source_path = $this->source_image;
   183  		}
   184  
   185  		$x = explode('/', $full_source_path);
   186  		$this->source_image = end($x);
   187  		$this->source_folder = str_replace($this->source_image, '', $full_source_path);
   188  
   189  		// Set the Image Properties
   190  		if ( ! $this->get_image_properties($this->source_folder.$this->source_image))
   191  		{
   192  			return FALSE;	
   193  		}
   194  
   195  		/*
   196  		 * Assign the "new" image name/path
   197  		 *
   198  		 * If the user has set a "new_image" name it means
   199  		 * we are making a copy of the source image. If not
   200  		 * it means we are altering the original.  We'll
   201  		 * set the destination filename and path accordingly.
   202  		 *
   203  		 */
   204  		if ($this->new_image == '')
   205  		{
   206  			$this->dest_image = $this->source_image;
   207  			$this->dest_folder = $this->source_folder;
   208  		}
   209  		else
   210  		{
   211  			if (strpos($this->new_image, '/') === FALSE AND strpos($this->new_image, '\\') === FALSE)
   212  			{
   213  				$this->dest_folder = $this->source_folder;
   214  				$this->dest_image = $this->new_image;
   215  			}
   216  			else
   217  			{
   218  				if (function_exists('realpath') AND @realpath($this->new_image) !== FALSE)
   219  				{
   220  					$full_dest_path = str_replace("\\", "/", realpath($this->new_image));
   221  				}
   222  				else
   223  				{
   224  					$full_dest_path = $this->new_image;
   225  				}
   226  
   227  				// Is there a file name?
   228  				if ( ! preg_match("#\.(jpg|jpeg|gif|png)$#i", $full_dest_path))
   229  				{
   230  					$this->dest_folder = $full_dest_path.'/';
   231  					$this->dest_image = $this->source_image;
   232  				}
   233  				else
   234  				{
   235  					$x = explode('/', $full_dest_path);
   236  					$this->dest_image = end($x);
   237  					$this->dest_folder = str_replace($this->dest_image, '', $full_dest_path);
   238  				}
   239  			}
   240  		}
   241  
   242  		/*
   243  		 * Compile the finalized filenames/paths
   244  		 *
   245  		 * We'll create two master strings containing the
   246  		 * full server path to the source image and the
   247  		 * full server path to the destination image.
   248  		 * We'll also split the destination image name
   249  		 * so we can insert the thumbnail marker if needed.
   250  		 *
   251  		 */
   252  		if ($this->create_thumb === FALSE OR $this->thumb_marker == '')
   253  		{
   254  			$this->thumb_marker = '';
   255  		}
   256  
   257  		$xp	= $this->explode_name($this->dest_image);
   258  
   259  		$filename = $xp['name'];
   260  		$file_ext = $xp['ext'];
   261  
   262  		$this->full_src_path = $this->source_folder.$this->source_image;
   263  		$this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext;
   264  
   265  		/*
   266  		 * Should we maintain image proportions?
   267  		 *
   268  		 * When creating thumbs or copies, the target width/height
   269  		 * might not be in correct proportion with the source
   270  		 * image's width/height.  We'll recalculate it here.
   271  		 *
   272  		 */
   273  		if ($this->maintain_ratio === TRUE && ($this->width != '' AND $this->height != ''))
   274  		{
   275  			$this->image_reproportion();
   276  		}
   277  
   278  		/*
   279  		 * Was a width and height specified?
   280  		 *
   281  		 * If the destination width/height was
   282  		 * not submitted we will use the values
   283  		 * from the actual file
   284  		 *
   285  		 */
   286  		if ($this->width == '')
   287  			$this->width = $this->orig_width;
   288  
   289  		if ($this->height == '')
   290  			$this->height = $this->orig_height;
   291  
   292  		// Set the quality
   293  		$this->quality = trim(str_replace("%", "", $this->quality));
   294  
   295  		if ($this->quality == '' OR $this->quality == 0 OR ! is_numeric($this->quality))
   296  			$this->quality = 90;
   297  
   298  		// Set the x/y coordinates
   299  		$this->x_axis = ($this->x_axis == '' OR ! is_numeric($this->x_axis)) ? 0 : $this->x_axis;
   300  		$this->y_axis = ($this->y_axis == '' OR ! is_numeric($this->y_axis)) ? 0 : $this->y_axis;
   301  
   302  		// Watermark-related Stuff...
   303  		if ($this->wm_font_color != '')
   304  		{
   305  			if (strlen($this->wm_font_color) == 6)
   306  			{
   307  				$this->wm_font_color = '#'.$this->wm_font_color;
   308  			}
   309  		}
   310  
   311  		if ($this->wm_shadow_color != '')
   312  		{
   313  			if (strlen($this->wm_shadow_color) == 6)
   314  			{
   315  				$this->wm_shadow_color = '#'.$this->wm_shadow_color;
   316  			}
   317  		}
   318  
   319  		if ($this->wm_overlay_path != '')
   320  		{
   321  			$this->wm_overlay_path = str_replace("\\", "/", realpath($this->wm_overlay_path));
   322  		}
   323  
   324  		if ($this->wm_shadow_color != '')
   325  		{
   326  			$this->wm_use_drop_shadow = TRUE;
   327  		}
   328  
   329  		if ($this->wm_font_path != '')
   330  		{
   331  			$this->wm_use_truetype = TRUE;
   332  		}
   333  
   334  		return TRUE;
   335  	}
   336  
   337  	// --------------------------------------------------------------------
   338  
   339  	/**
   340  	 * Image Resize
   341  	 *
   342  	 * This is a wrapper function that chooses the proper
   343  	 * resize function based on the protocol specified
   344  	 *
   345  	 * @access	public
   346  	 * @return	bool
   347  	 */
   348  	function resize()
   349  	{
   350  		$protocol = 'image_process_'.$this->image_library;
   351  
   352  		if (preg_match('/gd2$/i', $protocol))
   353  		{
   354  			$protocol = 'image_process_gd';
   355  		}
   356  
   357  		return $this->$protocol('resize');
   358  	}
   359  
   360  	// --------------------------------------------------------------------
   361  
   362  	/**
   363  	 * Image Crop
   364  	 *
   365  	 * This is a wrapper function that chooses the proper
   366  	 * cropping function based on the protocol specified
   367  	 *
   368  	 * @access	public
   369  	 * @return	bool
   370  	 */
   371  	function crop()
   372  	{
   373  		$protocol = 'image_process_'.$this->image_library;
   374  
   375  		if (preg_match('/gd2$/i', $protocol))
   376  		{
   377  			$protocol = 'image_process_gd';
   378  		}
   379  
   380  		return $this->$protocol('crop');
   381  	}
   382  
   383  	// --------------------------------------------------------------------
   384  
   385  	/**
   386  	 * Image Rotate
   387  	 *
   388  	 * This is a wrapper function that chooses the proper
   389  	 * rotation function based on the protocol specified
   390  	 *
   391  	 * @access	public
   392  	 * @return	bool
   393  	 */
   394  	function rotate()
   395  	{
   396  		// Allowed rotation values
   397  		$degs = array(90, 180, 270, 'vrt', 'hor');
   398  
   399  		if ($this->rotation_angle == '' OR ! in_array($this->rotation_angle, $degs))
   400  		{
   401  			$this->set_error('imglib_rotation_angle_required');
   402  			return FALSE;	
   403  		}
   404  
   405  		// Reassign the width and height
   406  		if ($this->rotation_angle == 90 OR $this->rotation_angle == 270)
   407  		{
   408  			$this->width	= $this->orig_height;
   409  			$this->height	= $this->orig_width;
   410  		}
   411  		else
   412  		{
   413  			$this->width	= $this->orig_width;
   414  			$this->height	= $this->orig_height;
   415  		}
   416  
   417  
   418  		// Choose resizing function
   419  		if ($this->image_library == 'imagemagick' OR $this->image_library == 'netpbm')
   420  		{
   421  			$protocol = 'image_process_'.$this->image_library;
   422  
   423  			return $this->$protocol('rotate');
   424  		}
   425  
   426  		if ($this->rotation_angle == 'hor' OR $this->rotation_angle == 'vrt')
   427  		{
   428  			return $this->image_mirror_gd();
   429  		}
   430  		else
   431  		{
   432  			return $this->image_rotate_gd();
   433  		}
   434  	}
   435  
   436  	// --------------------------------------------------------------------
   437  
   438  	/**
   439  	 * Image Process Using GD/GD2
   440  	 *
   441  	 * This function will resize or crop
   442  	 *
   443  	 * @access	public
   444  	 * @param	string
   445  	 * @return	bool
   446  	 */
   447  	function image_process_gd($action = 'resize')
   448  	{
   449  		$v2_override = FALSE;
   450  
   451  		// If the target width/height match the source, AND if the new file name is not equal to the old file name
   452  		// we'll simply make a copy of the original with the new name... assuming dynamic rendering is off.
   453  		if ($this->dynamic_output === FALSE)
   454  		{
   455  			if ($this->orig_width == $this->width AND $this->orig_height == $this->height)
   456  			{
   457  				if ($this->source_image != $this->new_image)
   458  				{
   459  					if (@copy($this->full_src_path, $this->full_dst_path))
   460  					{
   461  						@chmod($this->full_dst_path, FILE_WRITE_MODE);
   462  					}
   463  				}
   464  
   465  				return TRUE;
   466  			}
   467  		}
   468  
   469  		// Let's set up our values based on the action
   470  		if ($action == 'crop')
   471  		{
   472  			//  Reassign the source width/height if cropping
   473  			$this->orig_width  = $this->width;
   474  			$this->orig_height = $this->height;
   475  
   476  			// GD 2.0 has a cropping bug so we'll test for it
   477  			if ($this->gd_version() !== FALSE)
   478  			{
   479  				$gd_version = str_replace('0', '', $this->gd_version());
   480  				$v2_override = ($gd_version == 2) ? TRUE : FALSE;
   481  			}
   482  		}
   483  		else
   484  		{
   485  			// If resizing the x/y axis must be zero
   486  			$this->x_axis = 0;
   487  			$this->y_axis = 0;
   488  		}
   489  
   490  		//  Create the image handle
   491  		if ( ! ($src_img = $this->image_create_gd()))
   492  		{
   493  			return FALSE;
   494  		}
   495  
   496  		//  Create The Image
   497  		//
   498  		//  old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"
   499  		//  it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment
   500  		//  below should that ever prove inaccurate.
   501  		//
   502  		//  if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor') AND $v2_override == FALSE)
   503  		if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor'))
   504  		{
   505  			$create	= 'imagecreatetruecolor';
   506  			$copy	= 'imagecopyresampled';
   507  		}
   508  		else
   509  		{
   510  			$create	= 'imagecreate';
   511  			$copy	= 'imagecopyresized';
   512  		}
   513  
   514  		$dst_img = $create($this->width, $this->height);
   515  
   516  		if ($this->image_type == 3) // png we can actually preserve transparency
   517  		{
   518  			imagealphablending($dst_img, FALSE);
   519  			imagesavealpha($dst_img, TRUE);
   520  		}
   521  
   522  		$copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);
   523  
   524  		//  Show the image
   525  		if ($this->dynamic_output == TRUE)
   526  		{
   527  			$this->image_display_gd($dst_img);
   528  		}
   529  		else
   530  		{
   531  			// Or save it
   532  			if ( ! $this->image_save_gd($dst_img))
   533  			{
   534  				return FALSE;
   535  			}
   536  		}
   537  
   538  		//  Kill the file handles
   539  		imagedestroy($dst_img);
   540  		imagedestroy($src_img);
   541  
   542  		// Set the file to 777
   543  		@chmod($this->full_dst_path, FILE_WRITE_MODE);
   544  
   545  		return TRUE;
   546  	}
   547  
   548  	// --------------------------------------------------------------------
   549  
   550  	/**
   551  	 * Image Process Using ImageMagick
   552  	 *
   553  	 * This function will resize, crop or rotate
   554  	 *
   555  	 * @access	public
   556  	 * @param	string
   557  	 * @return	bool
   558  	 */
   559  	function image_process_imagemagick($action = 'resize')
   560  	{
   561  		//  Do we have a vaild library path?
   562  		if ($this->library_path == '')
   563  		{
   564  			$this->set_error('imglib_libpath_invalid');
   565  			return FALSE;
   566  		}
   567  
   568  		if ( ! preg_match("/convert$/i", $this->library_path))
   569  		{
   570  			$this->library_path = rtrim($this->library_path, '/').'/';
   571  
   572  			$this->library_path .= 'convert';
   573  		}
   574  
   575  		// Execute the command
   576  		$cmd = $this->library_path." -quality ".$this->quality;
   577  
   578  		if ($action == 'crop')
   579  		{
   580  			$cmd .= " -crop ".$this->width."x".$this->height."+".$this->x_axis."+".$this->y_axis." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";
   581  		}
   582  		elseif ($action == 'rotate')
   583  		{
   584  			switch ($this->rotation_angle)
   585  			{
   586  				case 'hor'	: $angle = '-flop';
   587  					break;
   588  				case 'vrt'	: $angle = '-flip';
   589  					break;
   590  				default		: $angle = '-rotate '.$this->rotation_angle;
   591  					break;
   592  			}
   593  
   594  			$cmd .= " ".$angle." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";
   595  		}
   596  		else  // Resize
   597  		{
   598  			$cmd .= " -resize ".$this->width."x".$this->height." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";
   599  		}
   600  
   601  		$retval = 1;
   602  
   603  		@exec($cmd, $output, $retval);
   604  
   605  		//	Did it work?
   606  		if ($retval > 0)
   607  		{
   608  			$this->set_error('imglib_image_process_failed');
   609  			return FALSE;
   610  		}
   611  
   612  		// Set the file to 777
   613  		@chmod($this->full_dst_path, FILE_WRITE_MODE);
   614  
   615  		return TRUE;
   616  	}
   617  
   618  	// --------------------------------------------------------------------
   619  
   620  	/**
   621  	 * Image Process Using NetPBM
   622  	 *
   623  	 * This function will resize, crop or rotate
   624  	 *
   625  	 * @access	public
   626  	 * @param	string
   627  	 * @return	bool
   628  	 */
   629  	function image_process_netpbm($action = 'resize')
   630  	{
   631  		if ($this->library_path == '')
   632  		{
   633  			$this->set_error('imglib_libpath_invalid');
   634  			return FALSE;
   635  		}
   636  
   637  		//  Build the resizing command
   638  		switch ($this->image_type)
   639  		{
   640  			case 1 :
   641  						$cmd_in		= 'giftopnm';
   642  						$cmd_out	= 'ppmtogif';
   643  				break;
   644  			case 2 :
   645  						$cmd_in		= 'jpegtopnm';
   646  						$cmd_out	= 'ppmtojpeg';
   647  				break;
   648  			case 3 :
   649  						$cmd_in		= 'pngtopnm';
   650  						$cmd_out	= 'ppmtopng';
   651  				break;
   652  		}
   653  
   654  		if ($action == 'crop')
   655  		{
   656  			$cmd_inner = 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height;
   657  		}
   658  		elseif ($action == 'rotate')
   659  		{
   660  			switch ($this->rotation_angle)
   661  			{
   662  				case 90		:	$angle = 'r270';
   663  					break;
   664  				case 180	:	$angle = 'r180';
   665  					break;
   666  				case 270	:	$angle = 'r90';
   667  					break;
   668  				case 'vrt'	:	$angle = 'tb';
   669  					break;
   670  				case 'hor'	:	$angle = 'lr';
   671  					break;
   672  			}
   673  
   674  			$cmd_inner = 'pnmflip -'.$angle.' ';
   675  		}
   676  		else // Resize
   677  		{
   678  			$cmd_inner = 'pnmscale -xysize '.$this->width.' '.$this->height;
   679  		}
   680  
   681  		$cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp';
   682  
   683  		$retval = 1;
   684  
   685  		@exec($cmd, $output, $retval);
   686  
   687  		//  Did it work?
   688  		if ($retval > 0)
   689  		{
   690  			$this->set_error('imglib_image_process_failed');
   691  			return FALSE;
   692  		}
   693  
   694  		// With NetPBM we have to create a temporary image.
   695  		// If you try manipulating the original it fails so
   696  		// we have to rename the temp file.
   697  		copy ($this->dest_folder.'netpbm.tmp', $this->full_dst_path);
   698  		unlink ($this->dest_folder.'netpbm.tmp');
   699  		@chmod($this->full_dst_path, FILE_WRITE_MODE);
   700  
   701  		return TRUE;
   702  	}
   703  
   704  	// --------------------------------------------------------------------
   705  
   706  	/**
   707  	 * Image Rotate Using GD
   708  	 *
   709  	 * @access	public
   710  	 * @return	bool
   711  	 */
   712  	function image_rotate_gd()
   713  	{
   714  		//  Create the image handle
   715  		if ( ! ($src_img = $this->image_create_gd()))
   716  		{
   717  			return FALSE;
   718  		}
   719  
   720  		// Set the background color
   721  		// This won't work with transparent PNG files so we are
   722  		// going to have to figure out how to determine the color
   723  		// of the alpha channel in a future release.
   724  
   725  		$white	= imagecolorallocate($src_img, 255, 255, 255);
   726  
   727  		//  Rotate it!
   728  		$dst_img = imagerotate($src_img, $this->rotation_angle, $white);
   729  
   730  		//  Save the Image
   731  		if ($this->dynamic_output == TRUE)
   732  		{
   733  			$this->image_display_gd($dst_img);
   734  		}
   735  		else
   736  		{
   737  			// Or save it
   738  			if ( ! $this->image_save_gd($dst_img))
   739  			{
   740  				return FALSE;
   741  			}
   742  		}
   743  
   744  		//  Kill the file handles
   745  		imagedestroy($dst_img);
   746  		imagedestroy($src_img);
   747  
   748  		// Set the file to 777
   749  
   750  		@chmod($this->full_dst_path, FILE_WRITE_MODE);
   751  
   752  		return TRUE;
   753  	}
   754  
   755  	// --------------------------------------------------------------------
   756  
   757  	/**
   758  	 * Create Mirror Image using GD
   759  	 *
   760  	 * This function will flip horizontal or vertical
   761  	 *
   762  	 * @access	public
   763  	 * @return	bool
   764  	 */
   765  	function image_mirror_gd()
   766  	{
   767  		if ( ! $src_img = $this->image_create_gd())
   768  		{
   769  			return FALSE;
   770  		}
   771  
   772  		$width  = $this->orig_width;
   773  		$height = $this->orig_height;
   774  
   775  		if ($this->rotation_angle == 'hor')
   776  		{
   777  			for ($i = 0; $i < $height; $i++)
   778  			{
   779  				$left  = 0;
   780  				$right = $width-1;
   781  
   782  				while ($left < $right)
   783  				{
   784  					$cl = imagecolorat($src_img, $left, $i);
   785  					$cr = imagecolorat($src_img, $right, $i);
   786  
   787  					imagesetpixel($src_img, $left, $i, $cr);
   788  					imagesetpixel($src_img, $right, $i, $cl);
   789  
   790  					$left++;
   791  					$right--;
   792  				}
   793  			}
   794  		}
   795  		else
   796  		{
   797  			for ($i = 0; $i < $width; $i++)
   798  			{
   799  				$top = 0;
   800  				$bot = $height-1;
   801  
   802  				while ($top < $bot)
   803  				{
   804  					$ct = imagecolorat($src_img, $i, $top);
   805  					$cb = imagecolorat($src_img, $i, $bot);
   806  
   807  					imagesetpixel($src_img, $i, $top, $cb);
   808  					imagesetpixel($src_img, $i, $bot, $ct);
   809  
   810  					$top++;
   811  					$bot--;
   812  				}
   813  			}
   814  		}
   815  
   816  		//  Show the image
   817  		if ($this->dynamic_output == TRUE)
   818  		{
   819  			$this->image_display_gd($src_img);
   820  		}
   821  		else
   822  		{
   823  			// Or save it
   824  			if ( ! $this->image_save_gd($src_img))
   825  			{
   826  				return FALSE;
   827  			}
   828  		}
   829  
   830  		//  Kill the file handles
   831  		imagedestroy($src_img);
   832  
   833  		// Set the file to 777
   834  		@chmod($this->full_dst_path, FILE_WRITE_MODE);
   835  
   836  		return TRUE;
   837  	}
   838  
   839  	// --------------------------------------------------------------------
   840  
   841  	/**
   842  	 * Image Watermark
   843  	 *
   844  	 * This is a wrapper function that chooses the type
   845  	 * of watermarking based on the specified preference.
   846  	 *
   847  	 * @access	public
   848  	 * @param	string
   849  	 * @return	bool
   850  	 */
   851  	function watermark()
   852  	{
   853  		if ($this->wm_type == 'overlay')
   854  		{
   855  			return $this->overlay_watermark();
   856  		}
   857  		else
   858  		{
   859  			return $this->text_watermark();
   860  		}
   861  	}
   862  
   863  	// --------------------------------------------------------------------
   864  
   865  	/**
   866  	 * Watermark - Graphic Version
   867  	 *
   868  	 * @access	public
   869  	 * @return	bool
   870  	 */
   871  	function overlay_watermark()
   872  	{
   873  		if ( ! function_exists('imagecolortransparent'))
   874  		{
   875  			$this->set_error('imglib_gd_required');
   876  			return FALSE;
   877  		}
   878  
   879  		//  Fetch source image properties
   880  		$this->get_image_properties();
   881  
   882  		//  Fetch watermark image properties
   883  		$props			= $this->get_image_properties($this->wm_overlay_path, TRUE);
   884  		$wm_img_type	= $props['image_type'];
   885  		$wm_width		= $props['width'];
   886  		$wm_height		= $props['height'];
   887  
   888  		//  Create two image resources
   889  		$wm_img  = $this->image_create_gd($this->wm_overlay_path, $wm_img_type);
   890  		$src_img = $this->image_create_gd($this->full_src_path);
   891  
   892  		// Reverse the offset if necessary
   893  		// When the image is positioned at the bottom
   894  		// we don't want the vertical offset to push it
   895  		// further down.  We want the reverse, so we'll
   896  		// invert the offset.  Same with the horizontal
   897  		// offset when the image is at the right
   898  
   899  		$this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));
   900  		$this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));
   901  
   902  		if ($this->wm_vrt_alignment == 'B')
   903  			$this->wm_vrt_offset = $this->wm_vrt_offset * -1;
   904  
   905  		if ($this->wm_hor_alignment == 'R')
   906  			$this->wm_hor_offset = $this->wm_hor_offset * -1;
   907  
   908  		//  Set the base x and y axis values
   909  		$x_axis = $this->wm_hor_offset + $this->wm_padding;
   910  		$y_axis = $this->wm_vrt_offset + $this->wm_padding;
   911  
   912  		//  Set the vertical position
   913  		switch ($this->wm_vrt_alignment)
   914  		{
   915  			case 'T':
   916  				break;
   917  			case 'M':	$y_axis += ($this->orig_height / 2) - ($wm_height / 2);
   918  				break;
   919  			case 'B':	$y_axis += $this->orig_height - $wm_height;
   920  				break;
   921  		}
   922  
   923  		//  Set the horizontal position
   924  		switch ($this->wm_hor_alignment)
   925  		{
   926  			case 'L':
   927  				break;
   928  			case 'C':	$x_axis += ($this->orig_width / 2) - ($wm_width / 2);
   929  				break;
   930  			case 'R':	$x_axis += $this->orig_width - $wm_width;
   931  				break;
   932  		}
   933  
   934  		//  Build the finalized image
   935  		if ($wm_img_type == 3 AND function_exists('imagealphablending'))
   936  		{
   937  			@imagealphablending($src_img, TRUE);
   938  		}
   939  
   940  		// Set RGB values for text and shadow
   941  		$rgba = imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp);
   942  		$alpha = ($rgba & 0x7F000000) >> 24;
   943  
   944  		// make a best guess as to whether we're dealing with an image with alpha transparency or no/binary transparency
   945  		if ($alpha > 0)
   946  		{
   947  			// copy the image directly, the image's alpha transparency being the sole determinant of blending
   948  			imagecopy($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height);
   949  		}
   950  		else
   951  		{
   952  			// set our RGB value from above to be transparent and merge the images with the specified opacity
   953  			imagecolortransparent($wm_img, imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp));
   954  			imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity);
   955  		}
   956  
   957  		//  Output the image
   958  		if ($this->dynamic_output == TRUE)
   959  		{
   960  			$this->image_display_gd($src_img);
   961  		}
   962  		else
   963  		{
   964  			if ( ! $this->image_save_gd($src_img))
   965  			{
   966  				return FALSE;
   967  			}
   968  		}
   969  
   970  		imagedestroy($src_img);
   971  		imagedestroy($wm_img);
   972  
   973  		return TRUE;
   974  	}
   975  
   976  	// --------------------------------------------------------------------
   977  
   978  	/**
   979  	 * Watermark - Text Version
   980  	 *
   981  	 * @access	public
   982  	 * @return	bool
   983  	 */
   984  	function text_watermark()
   985  	{
   986  		if ( ! ($src_img = $this->image_create_gd()))
   987  		{
   988  			return FALSE;
   989  		}
   990  
   991  		if ($this->wm_use_truetype == TRUE AND ! file_exists($this->wm_font_path))
   992  		{
   993  			$this->set_error('imglib_missing_font');
   994  			return FALSE;
   995  		}
   996  
   997  		//  Fetch source image properties
   998  		$this->get_image_properties();
   999  
  1000  		// Set RGB values for text and shadow
  1001  		$this->wm_font_color	= str_replace('#', '', $this->wm_font_color);
  1002  		$this->wm_shadow_color	= str_replace('#', '', $this->wm_shadow_color);
  1003  
  1004  		$R1 = hexdec(substr($this->wm_font_color, 0, 2));
  1005  		$G1 = hexdec(substr($this->wm_font_color, 2, 2));
  1006  		$B1 = hexdec(substr($this->wm_font_color, 4, 2));
  1007  
  1008  		$R2 = hexdec(substr($this->wm_shadow_color, 0, 2));
  1009  		$G2 = hexdec(substr($this->wm_shadow_color, 2, 2));
  1010  		$B2 = hexdec(substr($this->wm_shadow_color, 4, 2));
  1011  
  1012  		$txt_color	= imagecolorclosest($src_img, $R1, $G1, $B1);
  1013  		$drp_color	= imagecolorclosest($src_img, $R2, $G2, $B2);
  1014  
  1015  		// Reverse the vertical offset
  1016  		// When the image is positioned at the bottom
  1017  		// we don't want the vertical offset to push it
  1018  		// further down.  We want the reverse, so we'll
  1019  		// invert the offset.  Note: The horizontal
  1020  		// offset flips itself automatically
  1021  
  1022  		if ($this->wm_vrt_alignment == 'B')
  1023  			$this->wm_vrt_offset = $this->wm_vrt_offset * -1;
  1024  
  1025  		if ($this->wm_hor_alignment == 'R')
  1026  			$this->wm_hor_offset = $this->wm_hor_offset * -1;
  1027  
  1028  		// Set font width and height
  1029  		// These are calculated differently depending on
  1030  		// whether we are using the true type font or not
  1031  		if ($this->wm_use_truetype == TRUE)
  1032  		{
  1033  			if ($this->wm_font_size == '')
  1034  				$this->wm_font_size = '17';
  1035  
  1036  			$fontwidth  = $this->wm_font_size-($this->wm_font_size/4);
  1037  			$fontheight = $this->wm_font_size;
  1038  			$this->wm_vrt_offset += $this->wm_font_size;
  1039  		}
  1040  		else
  1041  		{
  1042  			$fontwidth  = imagefontwidth($this->wm_font_size);
  1043  			$fontheight = imagefontheight($this->wm_font_size);
  1044  		}
  1045  
  1046  		// Set base X and Y axis values
  1047  		$x_axis = $this->wm_hor_offset + $this->wm_padding;
  1048  		$y_axis = $this->wm_vrt_offset + $this->wm_padding;
  1049  
  1050  		// Set verticle alignment
  1051  		if ($this->wm_use_drop_shadow == FALSE)
  1052  			$this->wm_shadow_distance = 0;
  1053  
  1054  		$this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));
  1055  		$this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));
  1056  
  1057  		switch ($this->wm_vrt_alignment)
  1058  		{
  1059  			case	 "T" :
  1060  				break;
  1061  			case "M":	$y_axis += ($this->orig_height/2)+($fontheight/2);
  1062  				break;
  1063  			case "B":	$y_axis += ($this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight/2));
  1064  				break;
  1065  		}
  1066  
  1067  		$x_shad = $x_axis + $this->wm_shadow_distance;
  1068  		$y_shad = $y_axis + $this->wm_shadow_distance;
  1069  
  1070  		// Set horizontal alignment
  1071  		switch ($this->wm_hor_alignment)
  1072  		{
  1073  			case "L":
  1074  				break;
  1075  			case "R":
  1076  						if ($this->wm_use_drop_shadow)
  1077  							$x_shad += ($this->orig_width - $fontwidth*strlen($this->wm_text));
  1078  							$x_axis += ($this->orig_width - $fontwidth*strlen($this->wm_text));
  1079  				break;
  1080  			case "C":
  1081  						if ($this->wm_use_drop_shadow)
  1082  							$x_shad += floor(($this->orig_width - $fontwidth*strlen($this->wm_text))/2);
  1083  							$x_axis += floor(($this->orig_width  -$fontwidth*strlen($this->wm_text))/2);
  1084  				break;
  1085  		}
  1086  
  1087  		//  Add the text to the source image
  1088  		if ($this->wm_use_truetype)
  1089  		{
  1090  			if ($this->wm_use_drop_shadow)
  1091  				imagettftext($src_img, $this->wm_font_size, 0, $x_shad, $y_shad, $drp_color, $this->wm_font_path, $this->wm_text);
  1092  				imagettftext($src_img, $this->wm_font_size, 0, $x_axis, $y_axis, $txt_color, $this->wm_font_path, $this->wm_text);
  1093  		}
  1094  		else
  1095  		{
  1096  			if ($this->wm_use_drop_shadow)
  1097  				imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color);
  1098  				imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color);
  1099  		}
  1100  
  1101  		//  Output the final image
  1102  		if ($this->dynamic_output == TRUE)
  1103  		{
  1104  			$this->image_display_gd($src_img);
  1105  		}
  1106  		else
  1107  		{
  1108  			$this->image_save_gd($src_img);
  1109  		}
  1110  
  1111  		imagedestroy($src_img);
  1112  
  1113  		return TRUE;
  1114  	}
  1115  
  1116  	// --------------------------------------------------------------------
  1117  
  1118  	/**
  1119  	 * Create Image - GD
  1120  	 *
  1121  	 * This simply creates an image resource handle
  1122  	 * based on the type of image being processed
  1123  	 *
  1124  	 * @access	public
  1125  	 * @param	string
  1126  	 * @return	resource
  1127  	 */
  1128  	function image_create_gd($path = '', $image_type = '')
  1129  	{
  1130  		if ($path == '')
  1131  			$path = $this->full_src_path;
  1132  
  1133  		if ($image_type == '')
  1134  			$image_type = $this->image_type;
  1135  
  1136  
  1137  		switch ($image_type)
  1138  		{
  1139  			case	 1 :
  1140  						if ( ! function_exists('imagecreatefromgif'))
  1141  						{
  1142  							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
  1143  							return FALSE;
  1144  						}
  1145  
  1146  						return imagecreatefromgif($path);
  1147  				break;
  1148  			case 2 :
  1149  						if ( ! function_exists('imagecreatefromjpeg'))
  1150  						{
  1151  							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
  1152  							return FALSE;
  1153  						}
  1154  
  1155  						return imagecreatefromjpeg($path);
  1156  				break;
  1157  			case 3 :
  1158  						if ( ! function_exists('imagecreatefrompng'))
  1159  						{
  1160  							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
  1161  							return FALSE;
  1162  						}
  1163  
  1164  						return imagecreatefrompng($path);
  1165  				break;
  1166  
  1167  		}
  1168  
  1169  		$this->set_error(array('imglib_unsupported_imagecreate'));
  1170  		return FALSE;
  1171  	}
  1172  
  1173  	// --------------------------------------------------------------------
  1174  
  1175  	/**
  1176  	 * Write image file to disk - GD
  1177  	 *
  1178  	 * Takes an image resource as input and writes the file
  1179  	 * to the specified destination
  1180  	 *
  1181  	 * @access	public
  1182  	 * @param	resource
  1183  	 * @return	bool
  1184  	 */
  1185  	function image_save_gd($resource)
  1186  	{
  1187  		switch ($this->image_type)
  1188  		{
  1189  			case 1 :
  1190  						if ( ! function_exists('imagegif'))
  1191  						{
  1192  							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
  1193  							return FALSE;
  1194  						}
  1195  
  1196  						if ( ! @imagegif($resource, $this->full_dst_path))
  1197  						{
  1198  							$this->set_error('imglib_save_failed');
  1199  							return FALSE;
  1200  						}
  1201  				break;
  1202  			case 2	:
  1203  						if ( ! function_exists('imagejpeg'))
  1204  						{
  1205  							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
  1206  							return FALSE;
  1207  						}
  1208  
  1209  						if ( ! @imagejpeg($resource, $this->full_dst_path, $this->quality))
  1210  						{
  1211  							$this->set_error('imglib_save_failed');
  1212  							return FALSE;
  1213  						}
  1214  				break;
  1215  			case 3	:
  1216  						if ( ! function_exists('imagepng'))
  1217  						{
  1218  							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
  1219  							return FALSE;
  1220  						}
  1221  
  1222  						if ( ! @imagepng($resource, $this->full_dst_path))
  1223  						{
  1224  							$this->set_error('imglib_save_failed');
  1225  							return FALSE;
  1226  						}
  1227  				break;
  1228  			default		:
  1229  							$this->set_error(array('imglib_unsupported_imagecreate'));
  1230  							return FALSE;
  1231  				break;
  1232  		}
  1233  
  1234  		return TRUE;
  1235  	}
  1236  
  1237  	// --------------------------------------------------------------------
  1238  
  1239  	/**
  1240  	 * Dynamically outputs an image
  1241  	 *
  1242  	 * @access	public
  1243  	 * @param	resource
  1244  	 * @return	void
  1245  	 */
  1246  	function image_display_gd($resource)
  1247  	{
  1248  		header("Content-Disposition: filename={$this->source_image};");
  1249  		header("Content-Type: {$this->mime_type}");
  1250  		header('Content-Transfer-Encoding: binary');
  1251  		header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
  1252  
  1253  		switch ($this->image_type)
  1254  		{
  1255  			case 1		:	imagegif($resource);
  1256  				break;
  1257  			case 2		:	imagejpeg($resource, '', $this->quality);
  1258  				break;
  1259  			case 3		:	imagepng($resource);
  1260  				break;
  1261  			default		:	echo 'Unable to display the image';
  1262  				break;
  1263  		}
  1264  	}
  1265  
  1266  	// --------------------------------------------------------------------
  1267  
  1268  	/**
  1269  	 * Re-proportion Image Width/Height
  1270  	 *
  1271  	 * When creating thumbs, the desired width/height
  1272  	 * can end up warping the image due to an incorrect
  1273  	 * ratio between the full-sized image and the thumb.
  1274  	 *
  1275  	 * This function lets us re-proportion the width/height
  1276  	 * if users choose to maintain the aspect ratio when resizing.
  1277  	 *
  1278  	 * @access	public
  1279  	 * @return	void
  1280  	 */
  1281  	function image_reproportion()
  1282  	{
  1283  		if ( ! is_numeric($this->width) OR ! is_numeric($this->height) OR $this->width == 0 OR $this->height == 0)
  1284  			return;
  1285  
  1286  		if ( ! is_numeric($this->orig_width) OR ! is_numeric($this->orig_height) OR $this->orig_width == 0 OR $this->orig_height == 0)
  1287  			return;
  1288  
  1289  		$new_width	= ceil($this->orig_width*$this->height/$this->orig_height);
  1290  		$new_height	= ceil($this->width*$this->orig_height/$this->orig_width);
  1291  
  1292  		$ratio = (($this->orig_height/$this->orig_width) - ($this->height/$this->width));
  1293  
  1294  		if ($this->master_dim != 'width' AND $this->master_dim != 'height')
  1295  		{
  1296  			$this->master_dim = ($ratio < 0) ? 'width' : 'height';
  1297  		}
  1298  
  1299  		if (($this->width != $new_width) AND ($this->height != $new_height))
  1300  		{
  1301  			if ($this->master_dim == 'height')
  1302  			{
  1303  				$this->width = $new_width;
  1304  			}
  1305  			else
  1306  			{
  1307  				$this->height = $new_height;
  1308  			}
  1309  		}
  1310  	}
  1311  
  1312  	// --------------------------------------------------------------------
  1313  
  1314  	/**
  1315  	 * Get image properties
  1316  	 *
  1317  	 * A helper function that gets info about the file
  1318  	 *
  1319  	 * @access	public
  1320  	 * @param	string
  1321  	 * @return	mixed
  1322  	 */
  1323  	function get_image_properties($path = '', $return = FALSE)
  1324  	{
  1325  		// For now we require GD but we should
  1326  		// find a way to determine this using IM or NetPBM
  1327  
  1328  		if ($path == '')
  1329  			$path = $this->full_src_path;
  1330  
  1331  		if ( ! file_exists($path))
  1332  		{
  1333  			$this->set_error('imglib_invalid_path');
  1334  			return FALSE;
  1335  		}
  1336  
  1337  		$vals = @getimagesize($path);
  1338  
  1339  		$types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
  1340  
  1341  		$mime = (isset($types[$vals['2']])) ? 'image/'.$types[$vals['2']] : 'image/jpg';
  1342  
  1343  		if ($return == TRUE)
  1344  		{
  1345  			$v['width']			= $vals['0'];
  1346  			$v['height']		= $vals['1'];
  1347  			$v['image_type']	= $vals['2'];
  1348  			$v['size_str']		= $vals['3'];
  1349  			$v['mime_type']		= $mime;
  1350  
  1351  			return $v;
  1352  		}
  1353  
  1354  		$this->orig_width	= $vals['0'];
  1355  		$this->orig_height	= $vals['1'];
  1356  		$this->image_type	= $vals['2'];
  1357  		$this->size_str		= $vals['3'];
  1358  		$this->mime_type	= $mime;
  1359  
  1360  		return TRUE;
  1361  	}
  1362  
  1363  	// --------------------------------------------------------------------
  1364  
  1365  	/**
  1366  	 * Size calculator
  1367  	 *
  1368  	 * This function takes a known width x height and
  1369  	 * recalculates it to a new size.  Only one
  1370  	 * new variable needs to be known
  1371  	 *
  1372  	 *	$props = array(
  1373  	 *					'width'			=> $width,
  1374  	 *					'height'		=> $height,
  1375  	 *					'new_width'		=> 40,
  1376  	 *					'new_height'	=> ''
  1377  	 *				  );
  1378  	 *
  1379  	 * @access	public
  1380  	 * @param	array
  1381  	 * @return	array
  1382  	 */
  1383  	function size_calculator($vals)
  1384  	{
  1385  		if ( ! is_array($vals))
  1386  		{
  1387  			return;
  1388  		}
  1389  
  1390  		$allowed = array('new_width', 'new_height', 'width', 'height');
  1391  
  1392  		foreach ($allowed as $item)
  1393  		{
  1394  			if ( ! isset($vals[$item]) OR $vals[$item] == '')
  1395  				$vals[$item] = 0;
  1396  		}
  1397  
  1398  		if ($vals['width'] == 0 OR $vals['height'] == 0)
  1399  		{
  1400  			return $vals;
  1401  		}
  1402  
  1403  		if ($vals['new_width'] == 0)
  1404  		{
  1405  			$vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']);
  1406  		}
  1407  		elseif ($vals['new_height'] == 0)
  1408  		{
  1409  			$vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']);
  1410  		}
  1411  
  1412  		return $vals;
  1413  	}
  1414  
  1415  	// --------------------------------------------------------------------
  1416  
  1417  	/**
  1418  	 * Explode source_image
  1419  	 *
  1420  	 * This is a helper function that extracts the extension
  1421  	 * from the source_image.  This function lets us deal with
  1422  	 * source_images with multiple periods, like:  my.cool.jpg
  1423  	 * It returns an associative array with two elements:
  1424  	 * $array['ext']  = '.jpg';
  1425  	 * $array['name'] = 'my.cool';
  1426  	 *
  1427  	 * @access	public
  1428  	 * @param	array
  1429  	 * @return	array
  1430  	 */
  1431  	function explode_name($source_image)
  1432  	{
  1433  		$ext = strrchr($source_image, '.');
  1434  		$name = ($ext === FALSE) ? $source_image : substr($source_image, 0, -strlen($ext));
  1435  
  1436  		return array('ext' => $ext, 'name' => $name);
  1437  	}
  1438  
  1439  	// --------------------------------------------------------------------
  1440  
  1441  	/**
  1442  	 * Is GD Installed?
  1443  	 *
  1444  	 * @access	public
  1445  	 * @return	bool
  1446  	 */
  1447  	function gd_loaded()
  1448  	{
  1449  		if ( ! extension_loaded('gd'))
  1450  		{
  1451  			if ( ! dl('gd.so'))
  1452  			{
  1453  				return FALSE;
  1454  			}
  1455  		}
  1456  
  1457  		return TRUE;
  1458  	}
  1459  
  1460  	// --------------------------------------------------------------------
  1461  
  1462  	/**
  1463  	 * Get GD version
  1464  	 *
  1465  	 * @access	public
  1466  	 * @return	mixed
  1467  	 */
  1468  	function gd_version()
  1469  	{
  1470  		if (function_exists('gd_info'))
  1471  		{
  1472  			$gd_version = @gd_info();
  1473  			$gd_version = preg_replace("/\D/", "", $gd_version['GD Version']);
  1474  
  1475  			return $gd_version;
  1476  		}
  1477  
  1478  		return FALSE;
  1479  	}
  1480  
  1481  	// --------------------------------------------------------------------
  1482  
  1483  	/**
  1484  	 * Set error message
  1485  	 *
  1486  	 * @access	public
  1487  	 * @param	string
  1488  	 * @return	void
  1489  	 */
  1490  	function set_error($msg)
  1491  	{
  1492  		$CI =& get_instance();
  1493  		$CI->lang->load('imglib');
  1494  
  1495  		if (is_array($msg))
  1496  		{
  1497  			foreach ($msg as $val)
  1498  			{
  1499  
  1500  				$msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);
  1501  				$this->error_msg[] = $msg;
  1502  				log_message('error', $msg);
  1503  			}
  1504  		}
  1505  		else
  1506  		{
  1507  			$msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);
  1508  			$this->error_msg[] = $msg;
  1509  			log_message('error', $msg);
  1510  		}
  1511  	}
  1512  
  1513  	// --------------------------------------------------------------------
  1514  
  1515  	/**
  1516  	 * Show error messages
  1517  	 *
  1518  	 * @access	public
  1519  	 * @param	string
  1520  	 * @return	string
  1521  	 */
  1522  	function display_errors($open = '<p>', $close = '</p>')
  1523  	{
  1524  		$str = '';
  1525  		foreach ($this->error_msg as $val)
  1526  		{
  1527  			$str .= $open.$val.$close;
  1528  		}
  1529  
  1530  		return $str;
  1531  	}
  1532  
  1533  }
  1534  // END Image_lib Class
  1535  
  1536  /* End of file Image_lib.php */
  1537  /* Location: ./system/libraries/Image_lib.php */