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