Display Tiff as Jpeg in browsers without Tiff support (#1488452)

pull/11/head
Aleksander Machniak 12 years ago
parent b9854b8cbe
commit 19cc5b91c9

@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
- Display Tiff as Jpeg in browsers without Tiff support (#1488452)
- Don't display Pdf/Tiff/Flash attachments inline without browser support (#1488452, #1487929)
- Fix html2text conversion of strong|b|a|th|h tags when used in upper case
- Add listcontrols template container in Larry skin (#1488498)

@ -13,7 +13,7 @@
| See the README file for a full license statement. |
| |
| PURPOSE: |
| Image resizer |
| Image resizer and converter |
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
@ -25,6 +25,19 @@ 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)
{
$this->image_file = $filename;
@ -66,7 +79,7 @@ class rcube_image
* @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)
{
@ -95,10 +108,10 @@ class rcube_image
$p['-opts'] = array('-resize' => $size.'>');
if (in_array($type, explode(',', $p['types']))) { // Valid type?
$result = rcube::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;
}
}
@ -148,6 +161,71 @@ class rcube_image
}
}
// @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;
@ -169,4 +247,5 @@ class rcube_image
}
}
}
}

@ -1097,12 +1097,6 @@ function rcmail_message_body($attrib)
}
}
// Skip TIFF images if browser doesn't support this format
// @TODO: we could convert TIFF to JPEG and display it
$tiff_support = !empty($_SESSION['browser_caps']) && !empty($_SESSION['browser_caps']['tif']);
$mime_regex = $tiff_support ? '/^image\//i' : '/^image\/(?!tif)/i';
$ext_regex = '/\.(jpg|jpeg|png|gif|bmp' . ($tiff_support ? '|tif|tiff' : '') .')$/i';
// list images after mail body
if ($CONFIG['inline_images'] && !empty($MESSAGE->attachments)) {
foreach ($MESSAGE->attachments as $attach_prop) {
@ -1112,12 +1106,7 @@ function rcmail_message_body($attrib)
}
// Content-Type: image/*...
if (preg_match($mime_regex, $attach_prop->mimetype) ||
// ...or known file extension: many clients are using application/octet-stream
($attach_prop->filename &&
preg_match('/^application\/octet-stream$/i', $attach_prop->mimetype) &&
preg_match($ext_regex, $attach_prop->filename))
) {
if (rcmail_part_image_type($attach_prop)) {
$out .= html::tag('hr') . html::p(array('align' => "center"),
html::img(array(
'src' => $MESSAGE->get_part_url($attach_prop->mime_id, true),
@ -1135,6 +1124,48 @@ function rcmail_message_body($attrib)
return html::div($attrib, $out);
}
function rcmail_part_image_type($part)
{
$rcmail = rcmail::get_instance();
// Skip TIFF images if browser doesn't support this format...
$tiff_support = !empty($_SESSION['browser_caps']) && !empty($_SESSION['browser_caps']['tif']);
// until we can convert them to JPEG
$tiff_support = $tiff_support || $rcmail->config->get('im_convert_path');
// Content-type regexp
$mime_regex = $tiff_support ? '/^image\//i' : '/^image\/(?!tif)/i';
// Content-Type: image/*...
if (preg_match($mime_regex, $part->mimetype)) {
return $part->mimetype;
}
// Many clients use application/octet-stream, we'll detect mimetype
// by checking filename extension
// Supported image filename extensions to image type map
$types = array(
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
'bmp' => 'image/bmp',
);
if ($tiff_support) {
$types['tif'] = 'image/tiff';
$types['tiff'] = 'image/tiff';
}
if ($part->filename
&& preg_match('/^application\/octet-stream$/i', $part->mimetype)
&& preg_match('/\.([^.])$/i', $part->filename, $m)
&& ($extension = strtolower($m[1]))
&& isset($types[$extension])
) {
return $types[$extension];
}
}
/**
* Convert all relative URLs according to a <base> in HTML

@ -22,7 +22,7 @@
// show loading page
if (!empty($_GET['_preload'])) {
$url = preg_replace('/[&?]+_preload=1/', '', $_SERVER['REQUEST_URI']);
$url = preg_replace('/([&?]+)_preload=/', '\\1_embed=', $_SERVER['REQUEST_URI']);
$message = rcube_label('loadingdata');
header('Content-Type: text/html; charset=' . RCMAIL_CHARSET);
@ -76,6 +76,17 @@ else if (strlen($pid = get_input_value('_part', RCUBE_INPUT_GET))) {
// overwrite modified vars from plugin
$mimetype = $plugin['mimetype'];
// TIFF to JPEG conversion, if needed
$tiff_support = !empty($_SESSION['browser_caps']) && !empty($_SESSION['browser_caps']['tif']);
if (!empty($_REQUEST['_embed']) && !$tiff_support
&& $RCMAIL->config->get('im_convert_path')
&& rcmail_part_image_type($part) == 'image/tiff'
) {
$tiff2jpeg = true;
$mimetype = 'image/jpeg';
}
list($ctype_primary, $ctype_secondary) = explode('/', $mimetype);
if ($plugin['body'])
$part->body = $plugin['body'];
@ -150,8 +161,33 @@ else if (strlen($pid = get_input_value('_part', RCUBE_INPUT_GET))) {
header("Content-Disposition: $disposition; filename=\"$filename\"");
// handle tiff to jpeg conversion
if (!empty($tiff2jpeg)) {
$temp_dir = unslashify($RCMAIL->config->get('temp_dir'));
$file_path = tempnam($temp_dir, 'rcmAttmnt');
// write content to temp file
if ($part->body) {
$saved = file_put_contents($file_path, $part->body);
}
else if ($part->size) {
$fd = fopen($file_path, 'w');
$saved = $RCMAIL->storage->get_message_part($MESSAGE->uid, $part->mime_id, $part, false, $fd);
fclose($fd);
}
// convert image to jpeg and send it to the browser
if ($saved) {
$image = new rcube_image($file_path);
if ($image->convert(rcube_image::TYPE_JPG, $file_path)) {
header("Content-Length: " . filesize($file_path));
readfile($file_path);
}
unlink($file_path);
}
}
// do content filtering to avoid XSS through fake images
if (!empty($_REQUEST['_embed']) && $browser->ie && $browser->ver <= 8) {
else if (!empty($_REQUEST['_embed']) && $browser->ie && $browser->ver <= 8) {
if ($part->body) {
echo preg_match('/<(script|iframe|object)/i', $part->body) ? '' : $part->body;
$sent = true;

@ -61,7 +61,7 @@ if ($uid = get_input_value('_uid', RCUBE_INPUT_GET)) {
$OUTPUT->set_env('mailbox', $mbox_name);
// mimetypes supported by the browser (default settings)
$mimetypes = $RCMAIL->config->get('client_mimetypes', 'text/plain,text/html,text/xml,image/jpeg,image/gif,image/png,image/tiff,application/x-javascript,application/pdf,application/x-shockwave-flash');
$mimetypes = $RCMAIL->config->get('client_mimetypes', 'text/plain,text/html,text/xml,image/jpeg,image/gif,image/png,image/bmp,image/tiff,application/x-javascript,application/pdf,application/x-shockwave-flash');
$mimetypes = is_string($mimetypes) ? explode(',', $mimetypes) : (array)$mimetypes;
// Remove unsupported types, which makes that attachment which cannot be
@ -72,9 +72,11 @@ if ($uid = get_input_value('_uid', RCUBE_INPUT_GET)) {
if (empty($_SESSION['browser_caps']['flash']) && ($key = array_search('application/x-shockwave-flash', $mimetypes)) !== false) {
unset($mimetypes[$key]);
}
// @TODO: we could convert TIFF to JPEG and display it
if (empty($_SESSION['browser_caps']['tif']) && ($key = array_search('image/tiff', $mimetypes)) !== false) {
unset($mimetypes[$key]);
// we can convert tiff to jpeg
if (!$RCMAIL->config->get('im_convert_path')) {
unset($mimetypes[$key]);
}
}
$OUTPUT->set_env('mimetypes', $mimetypes);

Loading…
Cancel
Save