<commit_before>From 3783c3ade4f52b643a70ca44ff6c1abdf81fb4f5 Mon Sep 17 00:00:00 2001
From: <NAME> <<EMAIL>>
Date: Fri, 23 Jan 2015 18:04:52 +0100
Subject: [PATCH 1/2] The bitmap preview class now takes maxX and maxY into
 consideration when generating previews This is a fix for
 https://github.com/owncloud/core/issues/13607 and is part of the global
 programme: https://github.com/owncloud/core/issues/13609

---
 lib/private/preview/bitmap.php | 110 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 101 insertions(+), 9 deletions(-)

diff --git a/lib/private/preview/bitmap.php b/lib/private/preview/bitmap.php
index 25f65cf..80c8863 100644
--- a/lib/private/preview/bitmap.php
+++ b/lib/private/preview/bitmap.php
@@ -1,6 +1,7 @@
 <?php
 /**
- * Copyright (c) 2013-2014 <NAME> <EMAIL>
+ * @copyright 2013-2014 <NAME> <EMAIL>
+ * @copyright 2015 <NAME> <<EMAIL>>
  * This file is licensed under the Affero General Public License version 3 or
  * later.
  * See the COPYING-README file.
@@ -8,30 +9,121 @@

 namespace OC\Preview;

+use Imagick;
+
+/**
+ * Creates a PNG preview using ImageMagick via the PECL extension
+ *
+ * @package OC\Preview
+ */
 abstract class Bitmap extends Provider {
+
+	/**
+	 * @type array
+	 */
+	private $maxDims;
+
 	/**
 	 * {@inheritDoc}
 	 */
 	public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) {
+		$this->maxDims = [$maxX, $maxY];
+
 		$tmpPath = $fileview->toTmpFile($path);

-		//create imagick object from bitmap or vector file
+		// Creates \Imagick object from bitmap or vector file
 		try {
-			// Layer 0 contains either the bitmap or
-			// a flat representation of all vector layers
-			$bp = new \Imagick($tmpPath . '[0]');
-
-			$bp->setImageFormat('png');
+			$bp = $this->getResizedPreview($tmpPath);
 		} catch (\Exception $e) {
-			\OC_Log::write('core', $e->getmessage(), \OC_Log::ERROR);
+			\OC_Log::write('core', 'ImageMagick says : ' . $e->getmessage(), \OC_Log::ERROR);
 			return false;
 		}

 		unlink($tmpPath);

 		//new bitmap image object
-		$image = new \OC_Image($bp);
+		$image = new \OC_Image();
+		$image->loadFromData($bp);
 		//check if image object is valid
 		return $image->valid() ? $image : false;
 	}
+
+	/**
+	 * Returns a preview of maxX times maxY dimensions in PNG format
+	 *
+	 * 	* The default resolution is already 72dpi, no need to change it for a bitmap output
+	 * 	* It's possible to have proper colour conversion using profileimage().
+	 * 	ICC profiles are here: http://www.color.org/srgbprofiles.xalter
+	 * 	* It's possible to Gamma-correct an image via gammaImage()
+	 *
+	 * @param string $tmpPath the location of the file to convert
+	 *
+	 * @return \Imagick
+	 */
+	private function getResizedPreview($tmpPath) {
+		$bp = new Imagick();
+
+		// Layer 0 contains either the bitmap or a flat representation of all vector layers
+		$bp->readImage($tmpPath . '[0]');
+
+		$bp = $this->resize($bp);
+
+		$bp->setImageFormat('png');
+
+		return $bp;
+	}
+
+	/**
+	 * Returns a resized \Imagick object
+	 *
+	 * If you want to know more on the various methods available to resize an
+	 * image, check out this link : @link https://stackoverflow.com/questions/8517304/what-the-difference-of-sample-resample-scale-resize-adaptive-resize-thumbnail-im
+	 *
+	 * @param \Imagick $bp
+	 *
+	 * @return \Imagick
+	 */
+	private function resize($bp) {
+		list($maxX, $maxY) = $this->maxDims;
+		list($previewWidth, $previewHeight) = array_values($bp->getImageGeometry());
+
+		// We only need to resize a preview which doesn't fit in the maximum dimensions
+		if ($previewWidth > $maxX || $previewHeight > $maxY) {
+			// TODO: LANCZOS is the default filter, CATROM could bring similar results faster
+			$bp->resizeImage($maxX, $maxY, imagick::FILTER_LANCZOS, 1, true);
+
+			// Fitting preview in max dimensions
+			list($newX, $newY) = $this->calculateNewPosition($previewWidth, $previewHeight);
+			// Transparent background
+			$bp->setImageBackgroundColor('None');
+			$bp->extentImage($maxX, $maxY, -$newX, -$newY);
+		}
+
+		return $bp;
+	}
+
+	/**
+	 * Calculates the new position so that the preview sits in the middle of the area requested by the client
+	 *
+	 * @link https://stackoverflow.com/questions/3050952/resize-an-image-and-fill-gaps-of-proportions-with-a-color
+	 *
+	 * @param int $previewWidth the width of the resized preview
+	 * @param int $previewHeight the height of the resized preview
+	 *
+	 * @return array
+	 */
+	private function calculateNewPosition($previewWidth, $previewHeight) {
+		list($maxX, $maxY) = $this->maxDims;
+		if (($previewWidth / $previewHeight) >= ($maxX / $maxY)) {
+			$newHeight = $previewHeight * ($maxX / $previewWidth);
+			$newX = 0;
+			$newY = round(abs($maxY - $newHeight) / 2);
+		} else {
+			$newWidth = $previewWidth * ($maxY / $previewHeight);
+			$newX = round(abs($maxX - $newWidth) / 2);
+			$newY = 0;
+		}
+
+		return [$newX, $newY];
+	}
 }

From bf349e3041f631a68da3cbcacde3116a7f98af19 Mon Sep 17 00:00:00 2001
From: <NAME> <<EMAIL>>
Date: Fri, 23 Jan 2015 18:47:23 +0100
Subject: [PATCH 2/2] Only process a file if we actually have one

---
 lib/private/preview/bitmap.php | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lib/private/preview/bitmap.php b/lib/private/preview/bitmap.php
index 80c8863..c1dacc5 100644
--- a/lib/private/preview/bitmap.php
+++ b/lib/private/preview/bitmap.php
@@ -30,6 +30,9 @@ public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) {
 		$this->maxDims = [$maxX, $maxY];

 		$tmpPath = $fileview->toTmpFile($path);
+		if (!$tmpPath) {
+			return false;
+		}

 		// Creates \Imagick object from bitmap or vector file
 		try {<commit_msg>Don't fill max previews, keep the same aspect ratio<commit_after>--- lib/private/preview/bitmap.php.orig	2015-03-06 15:14:17.770952395 +0000
+++ lib/private/preview/bitmap.php	2015-03-06 15:02:38.803951481 +0000
@@ -1,6 +1,7 @@
 <?php
 /**
- * Copyright (c) 2013-2014 <NAME> <EMAIL>
+ * @copyright 2013-2014 <NAME> <EMAIL>
+ * @copyright 2015 <NAME> <<EMAIL>>
  * This file is licensed under the Affero General Public License version 3 or
  * later.
  * See the COPYING-README file.
@@ -8,31 +9,93 @@
 
 namespace OC\Preview;
 
+use Imagick;
+
+/**
+ * Creates a PNG preview using ImageMagick via the PECL extension
+ *
+ * @package OC\Preview
+ */
 abstract class Bitmap extends Provider {
+
+	/**
+	 * @type array
+	 */
+	private $maxDims;
+
 	/**
 	 * {@inheritDoc}
 	 */
 	public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) {
+		$this->maxDims = [$maxX, $maxY];
+
 		$tmpPath = $fileview->toTmpFile($path);
+		if (!$tmpPath) {
+			return false;
+		}
 
-		//create imagick object from bitmap or vector file
+		// Creates \Imagick object from bitmap or vector file
 		try {
-			// Layer 0 contains either the bitmap or
-			// a flat representation of all vector layers
-			$bp = new \Imagick($tmpPath . '[0]');
-
-			$bp->setImageFormat('png');
+			$bp = $this->getResizedPreview($tmpPath);
 		} catch (\Exception $e) {
-			\OC_Log::write('core', $e->getmessage(), \OC_Log::ERROR);
+			\OC_Log::write('core', 'ImageMagick says : ' . $e->getmessage(), \OC_Log::ERROR);
 			return false;
 		}
 
 		unlink($tmpPath);
 
 		//new bitmap image object
-		$image = new \OC_Image($bp);
+		$image = new \OC_Image();
+		$image->loadFromData($bp);
 		//check if image object is valid
 		return $image->valid() ? $image : false;
 	}
-}
 
+	/**
+	 * Returns a preview of maxX times maxY dimensions in PNG format
+	 *
+	 * 	* The default resolution is already 72dpi, no need to change it for a bitmap output
+	 * 	* It's possible to have proper colour conversion using profileimage().
+	 * 	ICC profiles are here: http://www.color.org/srgbprofiles.xalter
+	 * 	* It's possible to Gamma-correct an image via gammaImage()
+	 *
+	 * @param string $tmpPath the location of the file to convert
+	 *
+	 * @return \Imagick
+	 */
+	private function getResizedPreview($tmpPath) {
+		$bp = new Imagick();
+
+		// Layer 0 contains either the bitmap or a flat representation of all vector layers
+		$bp->readImage($tmpPath . '[0]');
+
+		$bp = $this->resize($bp);
+
+		$bp->setImageFormat('png');
+
+		return $bp;
+	}
+
+	/**
+	 * Returns a resized \Imagick object
+	 *
+	 * If you want to know more on the various methods available to resize an
+	 * image, check out this link : @link https://stackoverflow.com/questions/8517304/what-the-difference-of-sample-resample-scale-resize-adaptive-resize-thumbnail-im
+	 *
+	 * @param \Imagick $bp
+	 *
+	 * @return \Imagick
+	 */
+	private function resize($bp) {
+		list($maxX, $maxY) = $this->maxDims;
+		list($previewWidth, $previewHeight) = array_values($bp->getImageGeometry());
+
+		// We only need to resize a preview which doesn't fit in the maximum dimensions
+		if ($previewWidth > $maxX || $previewHeight > $maxY) {
+			// TODO: LANCZOS is the default filter, CATROM could bring similar results faster
+			$bp->resizeImage($maxX, $maxY, imagick::FILTER_LANCZOS, 1, true);
+		}
+
+		return $bp;
+	}
+}
{'fraction_non_alphanumeric': 0.16498838109992253, 'fraction_numerical': 0.0349673564235919, 'mean_word_length': 3.5948144382308085, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 62, 'https://': 5, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2755936', 'n_tokens_mistral': 3647, 'n_tokens_neox': 3301, 'n_words': 876}