From bc92ca56ef6c51393d2782b7654eaa162dfc2e10 Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Mon, 30 Jul 2012 07:20:56 -0400
Subject: [PATCH] Fixes after default->classic switch

---
 program/include/rcube_image.php |  134 ++++++++++++++++++++++++++++++++++++--------
 1 files changed, 110 insertions(+), 24 deletions(-)

diff --git a/program/include/rcube_image.php b/program/include/rcube_image.php
index 9fe15fe..80e8bd4 100644
--- a/program/include/rcube_image.php
+++ b/program/include/rcube_image.php
@@ -13,20 +13,30 @@
  | See the README file for a full license statement.                     |
  |                                                                       |
  | PURPOSE:                                                              |
- |   Image resizer                                                       |
+ |   Image resizer and converter                                         |
  |                                                                       |
  +-----------------------------------------------------------------------+
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  | Author: Aleksander Machniak <alec@alec.pl>                            |
  +-----------------------------------------------------------------------+
-
- $Id$
-
 */
 
 class rcube_image
 {
     private $image_file;
+
+    const TYPE_GIF = 1;
+    const TYPE_JPG = 2;
+    const TYPE_PNG = 3;
+    const TYPE_TIF = 4;
+
+    public static $extensions = array(
+        self::TYPE_GIF => 'gif',
+        self::TYPE_JPG => 'jpg',
+        self::TYPE_PNG => 'png',
+        self::TYPE_TIF => 'tif',
+    );
+
 
     function __construct($filename)
     {
@@ -40,8 +50,7 @@
      */
     public function props()
     {
-        $rcmail = rcmail::get_instance();
-
+        // use GD extension
         if (function_exists('getimagesize') && ($imsize = @getimagesize($this->image_file))) {
             $width   = $imsize[0];
             $height  = $imsize[1];
@@ -49,12 +58,9 @@
             $type    = image_type_to_extension($imsize['2'], false);
         }
 
-        if (!$type && ($cmd = $rcmail->config->get('im_identify_path', false))) {
-            $id = rcmail::exec($cmd. ' 2>/dev/null {in}', array('in' => $this->image_file));
-            list(, $type, $size) = explode(' ', strtolower($id));
-            if ($size) {
-                list($width, $height) = explode('x', $size);
-            }
+        // use ImageMagick
+        if (!$type && ($data = $this->identify())) {
+            list($type, $width, $height) = $data;
         }
 
         if ($type) {
@@ -67,22 +73,20 @@
         }
     }
 
-
     /**
      * Resize image to a given size
      *
      * @param int    $size      Max width/height size
      * @param string $filename  Output filename
      *
-     * @return Success of convert as true/false
+     * @return bool True on success, False on failure
      */
     public function resize($size, $filename = null)
     {
-        $result   = false;
-        $rcmail   = rcmail::get_instance();
-        $convert  = $rcmail->config->get('im_convert_path', false);
-        $identify = $rcmail->config->get('im_identify_path', false);
-        $props    = $this->props();
+        $result  = false;
+        $rcube   = rcube::get_instance();
+        $convert = $rcube->config->get('im_convert_path', false);
+        $props   = $this->props();
 
         if (!$filename) {
             $filename = $this->image_file;
@@ -93,10 +97,10 @@
             $p['out']  = $filename;
             $p['in']   = $this->image_file;
             $p['size'] = $size.'x'.$size;
-            $p['type'] = $type = $props['type'];
+            $type      = $props['type'];
 
-            if (!$type) {
-                list(, $p['type']) = explode(' ', strtolower(rcmail::exec($identify . ' 2>/dev/null {in}', $p))); // for things like eps
+            if (!$type && ($data = $this->identify())) {
+                $type = $data[0];
             }
 
             $type = strtr($type, array("jpeg" => "jpg", "tiff" => "tif", "ps" => "eps", "ept" => "eps"));
@@ -104,10 +108,10 @@
             $p['-opts'] = array('-resize' => $size.'>');
 
             if (in_array($type, explode(',', $p['types']))) { // Valid type?
-                $result = rcmail::exec($convert . ' 2>&1 -flatten -auto-orient -colorspace RGB -quality {quality} {-opts} {in} {type}:{out}', $p) === '';
+                $result = rcube::exec($convert . ' 2>&1 -flatten -auto-orient -colorspace RGB -quality {quality} {-opts} {in} {type}:{out}', $p);
             }
 
-            if ($result) {
+            if ($result === '') {
                 return true;
             }
         }
@@ -157,9 +161,91 @@
             }
         }
 
+        // @TODO: print error to the log?
+        return false;
+    }
+
+    /**
+     * Convert image to a given type
+     *
+     * @param int    $type      Destination file type (see class constants)
+     * @param string $filename  Output filename (if empty, original file will be used
+     *                          and filename extension will be modified)
+     *
+     * @return bool True on success, False on failure
+     */
+    public function convert($type, $filename = null)
+    {
+        $rcube   = rcube::get_instance();
+        $convert = $rcube->config->get('im_convert_path', false);
+
+        if (!$filename) {
+            $filename = $this->image_file;
+
+            // modify extension
+            if ($extension = self::$extensions[$type]) {
+                $filename = preg_replace('/\.[^.]+$/', '', $filename) . '.' . $extension;
+            }
+        }
+
+        // use ImageMagick
+        if ($convert) {
+            $p['in']   = $this->image_file;
+            $p['out']  = $filename;
+            $p['type'] = self::$extensions[$type];
+
+            $result = rcube::exec($convert . ' 2>&1 -colorspace RGB -quality 75 {in} {type}:{out}', $p);
+
+            if ($result === '') {
+                return true;
+            }
+        }
+
+        // use GD extension (TIFF isn't supported)
+        $props    = $this->props();
+        $gd_types = array(IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_PNG);
+
+        if ($props['gd_type'] && in_array($props['gd_type'], $gd_types)) {
+            if ($props['gd_type'] == IMAGETYPE_JPEG) {
+                $image = imagecreatefromjpeg($this->image_file);
+            }
+            else if ($props['gd_type'] == IMAGETYPE_GIF) {
+                $image = imagecreatefromgif($this->image_file);
+            }
+            else if ($props['gd_type'] == IMAGETYPE_PNG) {
+                $image = imagecreatefrompng($this->image_file);
+            }
+
+            if ($type == self::TYPE_JPG) {
+                $result = imagejpeg($image, $filename, 75);
+            }
+            else if ($type == self::TYPE_GIF) {
+                $result = imagegif($image, $filename);
+            }
+            else if ($type == self::TYPE_PNG) {
+                $result = imagepng($image, $filename, 6, PNG_ALL_FILTERS);
+            }
+        }
 
         // @TODO: print error to the log?
         return false;
     }
 
+    /**
+     * Identify command handler.
+     */
+    private function identify()
+    {
+        $rcube = rcube::get_instance();
+
+        if ($cmd = $rcube->config->get('im_identify_path')) {
+            $args = array('in' => $this->image_file, 'format' => "%m %[fx:w] %[fx:h]");
+            $id   = rcube::exec($cmd. ' 2>/dev/null -format {format} {in}', $args);
+
+            if ($id) {
+                return explode(' ', strtolower($id));
+            }
+        }
+    }
+
 }

--
Gitblit v1.9.1