From ac4306555bf3bce78401918e23b81e863fcd37fb Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 3 Aug 2013 22:14:25 -0400 Subject: [PATCH] Fix for instances with old GraphicsMagick or ImageMagick versions (no -auto-orient). --- inc/config.php | 7 ++++- inc/display.php | 2 +- inc/functions.php | 2 +- inc/image.php | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++----- post.php | 12 ++++++-- 5 files changed, 97 insertions(+), 13 deletions(-) diff --git a/inc/config.php b/inc/config.php index 704889fa..832706e0 100644 --- a/inc/config.php +++ b/inc/config.php @@ -504,7 +504,7 @@ // Command-line options passed to ImageMagick when using `convert` for thumbnailing. Don't touch the // placement of "%s" and "%d". - $config['convert_args'] = '-size %dx%d %s -thumbnail %dx%d -auto-orient +profile "*" %s'; + $config['convert_args'] = '-size %dx%djjj %s -thumbnail %dx%d -auto-orient +profile "*" %s'; // Strip EXIF metadata from JPEG files. $config['strip_exif'] = false; @@ -522,6 +522,11 @@ // this basically does the same thing as $config['redraw_image']. (If $config['redraw_image'] is enabled, // this value doesn't matter as $config['redraw_image'] attempts to correct orientation too.) $config['convert_auto_orient'] = false; + + // Is your version of ImageMagick or GraphicsMagick old? Older versions may not include the -auto-orient + // switch. This is a manual replacement for that switch. This is independent from the above switch; + // -auto-orrient is applied when thumbnailing too. + $config['convert_manual_orient'] = false; // Regular expression to check for an XSS exploit with IE 6 and 7. To disable, set to false. // Details: https://github.com/savetheinternet/Tinyboard/issues/20 diff --git a/inc/display.php b/inc/display.php index dddb6559..97b8c744 100644 --- a/inc/display.php +++ b/inc/display.php @@ -69,7 +69,7 @@ function error($message, $priority = true, $debug_stuff = false) { // Running from CLI die('Error: ' . $message . "\n"); } - + if ($config['debug'] && isset($db_error)) { $debug_stuff = array_combine(array('SQLSTATE', 'Error code', 'Error message'), $db_error); } diff --git a/inc/functions.php b/inc/functions.php index 7c202380..8b2c4c7b 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1947,5 +1947,5 @@ function shell_exec_error($command) { ); } - return ($return === 'TB_SUCCESS') ? false : $return; + return $return === 'TB_SUCCESS' ? false : $return; } diff --git a/inc/image.php b/inc/image.php index 97ef8454..f4c21917 100644 --- a/inc/image.php +++ b/inc/image.php @@ -320,19 +320,23 @@ class ImageConvert extends ImageBase { if ($this->format == 'gif' && ($config['thumb_ext'] == 'gif' || $config['thumb_ext'] == '') && $config['thumb_keep_animation_frames'] > 1) { if ($this->gifsicle) { - if (trim($error = shell_exec("gifsicle --unoptimize -O2 --resize {$this->width}x{$this->height} < " . + if (($error = shell_exec_error("gifsicle --unoptimize -O2 --resize {$this->width}x{$this->height} < " . escapeshellarg($this->src . '') . " \"#0-{$config['thumb_keep_animation_frames']}\" > " . - escapeshellarg($this->temp) . '2>&1 &&echo $?') !== '0') || !file_exists($this->temp)) + escapeshellarg($this->temp))) || !file_exists($this->temp)) error('Failed to resize image!', null, $error); } else { - if ($error = shell_exec_error(($this->gm ? 'gm ' : '') . 'convert ' . - sprintf($config['convert_args'], + if ($config['convert_manual_orient']) + $convert_args = str_replace('-auto-orient', ImageConvert::jpeg_exif_orientation($this->src), $config['convert_args']); + else + $convert_args = &$config['convert_args']; + if (($error = shell_exec_error(($this->gm ? 'gm ' : '') . 'convert ' . + sprintf($convert_args, $this->width, $this->height, escapeshellarg($this->src), $this->width, $this->height, - escapeshellarg($this->temp))) || !file_exists($this->temp)) + escapeshellarg($this->temp)))) || !file_exists($this->temp)) error('Failed to resize image!', null, $error); if ($size = $this->get_size($this->temp)) { $this->width = $size[0]; @@ -340,14 +344,18 @@ class ImageConvert extends ImageBase { } } } else { - if ($error = shell_exec_error(($this->gm ? 'gm ' : '') . 'convert ' . - sprintf($config['convert_args'], + if ($config['convert_manual_orient']) + $convert_args = str_replace('-auto-orient', ImageConvert::jpeg_exif_orientation($this->src), $config['convert_args']); + else + $convert_args = &$config['convert_args']; + if (($error = shell_exec_error(($this->gm ? 'gm ' : '') . 'convert ' . + sprintf($convert_args, $this->width, $this->height, escapeshellarg($this->src . '[0]'), $this->width, $this->height, - escapeshellarg($this->temp))) || !file_exists($this->temp)) + escapeshellarg($this->temp)))) || !file_exists($this->temp)) error('Failed to resize image!', null, $error); if ($size = $this->get_size($this->temp)) { $this->width = $size[0]; @@ -355,6 +363,69 @@ class ImageConvert extends ImageBase { } } } + + // For when -auto-orient doesn't exist (older versions) + static public function jpeg_exif_orientation($src, $exif = false) { + if (!$exif) { + $exif = exif_read_data($src); + if (!isset($exif['Orientation'])) + return false; + } + switch($exif['Orientation']) { + case 1: + // Normal + return false; + case 2: + // 888888 + // 88 + // 8888 + // 88 + // 88 + + return '-flop'; + case 3: + + // 88 + // 88 + // 8888 + // 88 + // 888888 + + return '-flip -flop'; + case 4: + // 88 + // 88 + // 8888 + // 88 + // 888888 + + return '-flip'; + case 5: + // 8888888888 + // 88 88 + // 88 + + return '-rotate 90 -flop'; + case 6: + // 88 + // 88 88 + // 8888888888 + + return '-rotate 90'; + case 7: + // 88 + // 88 88 + // 8888888888 + + return '-rotate "-90" -flop'; + case 8: + // 8888888888 + // 88 88 + // 88 + + return '-rotate "-90"'; + } + } } class ImagePNG extends ImageBase { diff --git a/post.php b/post.php index 3c3d6e62..c355eca6 100644 --- a/post.php +++ b/post.php @@ -455,8 +455,16 @@ if (isset($_POST['delete'])) { $exif = exif_read_data($upload); $gm = in_array($config['thumb_method'], array('gm', 'gm+gifsicle')); if (isset($exif['Orientation']) && $exif['Orientation'] != 1) { - if($error = shell_exec_error(($gm ? 'gm ' : '') . 'convert ' . - escapeshellarg($upload) . ' -auto-orient ' . escapeshellarg($upload))) + if ($config['convert_manual_orient']) { + $error = shell_exec_error(($gm ? 'gm ' : '') . 'convert ' . + escapeshellarg($upload) . ' ' . + ImageConvert::jpeg_exif_orientation(false, $exif) . ' +profile "*" ' . + escapeshellarg($upload)); + } else { + $error = shell_exec_error(($gm ? 'gm ' : '') . 'convert ' . + escapeshellarg($upload) . ' -auto-orient ' . escapeshellarg($upload)); + } + if ($error) error('Could not auto-orient image!', null, $error); $size = @getimagesize($upload); }