aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/composer/composer/autoload_classmap.php2
-rw-r--r--lib/composer/composer/autoload_static.php2
-rw-r--r--lib/private/Image.php (renamed from lib/private/legacy/OC_Image.php)235
-rw-r--r--lib/public/Image.php2
-rw-r--r--tests/lib/Avatar/UserAvatarTest.php11
-rw-r--r--tests/lib/ImageTest.php111
-rw-r--r--tests/lib/Preview/GeneratorTest.php5
7 files changed, 184 insertions, 184 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index c962dc72d70..b8d0dd35f12 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -1636,6 +1636,7 @@ return array(
'OC\\Http\\Client\\Response' => $baseDir . '/lib/private/Http/Client/Response.php',
'OC\\Http\\CookieHelper' => $baseDir . '/lib/private/Http/CookieHelper.php',
'OC\\Http\\WellKnown\\RequestManager' => $baseDir . '/lib/private/Http/WellKnown/RequestManager.php',
+ 'OC\\Image' => $baseDir . '/lib/private/Image.php',
'OC\\InitialStateService' => $baseDir . '/lib/private/InitialStateService.php',
'OC\\Installer' => $baseDir . '/lib/private/Installer.php',
'OC\\IntegrityCheck\\Checker' => $baseDir . '/lib/private/IntegrityCheck/Checker.php',
@@ -2003,7 +2004,6 @@ return array(
'OC_Files' => $baseDir . '/lib/private/legacy/OC_Files.php',
'OC_Helper' => $baseDir . '/lib/private/legacy/OC_Helper.php',
'OC_Hook' => $baseDir . '/lib/private/legacy/OC_Hook.php',
- 'OC_Image' => $baseDir . '/lib/private/legacy/OC_Image.php',
'OC_JSON' => $baseDir . '/lib/private/legacy/OC_JSON.php',
'OC_Response' => $baseDir . '/lib/private/legacy/OC_Response.php',
'OC_Template' => $baseDir . '/lib/private/legacy/OC_Template.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index cedd2d8e8d0..646a41626b7 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -1669,6 +1669,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Http\\Client\\Response' => __DIR__ . '/../../..' . '/lib/private/Http/Client/Response.php',
'OC\\Http\\CookieHelper' => __DIR__ . '/../../..' . '/lib/private/Http/CookieHelper.php',
'OC\\Http\\WellKnown\\RequestManager' => __DIR__ . '/../../..' . '/lib/private/Http/WellKnown/RequestManager.php',
+ 'OC\\Image' => __DIR__ . '/../../..' . '/lib/private/Image.php',
'OC\\InitialStateService' => __DIR__ . '/../../..' . '/lib/private/InitialStateService.php',
'OC\\Installer' => __DIR__ . '/../../..' . '/lib/private/Installer.php',
'OC\\IntegrityCheck\\Checker' => __DIR__ . '/../../..' . '/lib/private/IntegrityCheck/Checker.php',
@@ -2036,7 +2037,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC_Files' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Files.php',
'OC_Helper' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Helper.php',
'OC_Hook' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Hook.php',
- 'OC_Image' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Image.php',
'OC_JSON' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_JSON.php',
'OC_Response' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Response.php',
'OC_Template' => __DIR__ . '/../../..' . '/lib/private/legacy/OC_Template.php',
diff --git a/lib/private/legacy/OC_Image.php b/lib/private/Image.php
index 37cf6b697ac..39624612560 100644
--- a/lib/private/legacy/OC_Image.php
+++ b/lib/private/Image.php
@@ -1,17 +1,27 @@
<?php
declare(strict_types=1);
+
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
*/
+
+namespace OC;
+
+use finfo;
+use GdImage;
+use OCP\IAppConfig;
+use OCP\IConfig;
use OCP\IImage;
+use OCP\Server;
+use Psr\Log\LoggerInterface;
/**
* Class for basic image manipulation
*/
-class OC_Image implements \OCP\IImage {
+class Image implements IImage {
// Default memory limit for images to load (256 MBytes).
protected const DEFAULT_MEMORY_LIMIT = 256;
@@ -21,49 +31,34 @@ class OC_Image implements \OCP\IImage {
// Default quality for webp images
protected const DEFAULT_WEBP_QUALITY = 80;
- /** @var false|\GdImage */
- protected $resource = false; // tmp resource.
- /** @var int */
- protected $imageType = IMAGETYPE_PNG; // Default to png if file type isn't evident.
- /** @var null|string */
- protected $mimeType = 'image/png'; // Default to png
- /** @var null|string */
- protected $filePath = null;
- /** @var ?finfo */
- private $fileInfo = null;
- /** @var \OCP\ILogger */
- private $logger;
- /** @var \OCP\IConfig */
- private $config;
- /** @var ?array */
- private $exif = null;
+ // tmp resource.
+ protected GdImage|false $resource = false;
+ // Default to png if file type isn't evident.
+ protected int $imageType = IMAGETYPE_PNG;
+ // Default to png
+ protected ?string $mimeType = 'image/png';
+ protected ?string $filePath = null;
+ private ?finfo $fileInfo = null;
+ private LoggerInterface $logger;
+ private IAppConfig $appConfig;
+ private IConfig $config;
+ private ?array $exif = null;
/**
- * Constructor.
- *
- * @param mixed $imageRef Deprecated, should be null
- * @psalm-assert null $imageRef
- * @param \OCP\ILogger $logger
- * @param \OCP\IConfig $config
* @throws \InvalidArgumentException in case the $imageRef parameter is not null
*/
- public function __construct($imageRef = null, ?\OCP\ILogger $logger = null, ?\OCP\IConfig $config = null) {
- $this->logger = $logger;
- if ($logger === null) {
- $this->logger = \OC::$server->getLogger();
- }
- $this->config = $config;
- if ($config === null) {
- $this->config = \OC::$server->getConfig();
- }
+ public function __construct(
+ ?LoggerInterface $logger = null,
+ ?IAppConfig $appConfig = null,
+ ?IConfig $config = null,
+ ) {
+ $this->logger = $logger ?? Server::get(LoggerInterface::class);
+ $this->appConfig = $appConfig ?? Server::get(IAppConfig::class);
+ $this->config = $config ?? Server::get(IConfig::class);
if (\OC_Util::fileInfoLoaded()) {
$this->fileInfo = new finfo(FILEINFO_MIME_TYPE);
}
-
- if ($imageRef !== null) {
- throw new \InvalidArgumentException('The first parameter in the constructor is not supported anymore. Please use any of the load* methods of the image object to load an image.');
- }
}
/**
@@ -120,7 +115,7 @@ class OC_Image implements \OCP\IImage {
*/
public function widthTopLeft(): int {
$o = $this->getOrientation();
- $this->logger->debug('OC_Image->widthTopLeft() Orientation: ' . $o, ['app' => 'core']);
+ $this->logger->debug('Image->widthTopLeft() Orientation: ' . $o, ['app' => 'core']);
switch ($o) {
case -1:
case 1:
@@ -144,7 +139,7 @@ class OC_Image implements \OCP\IImage {
*/
public function heightTopLeft(): int {
$o = $this->getOrientation();
- $this->logger->debug('OC_Image->heightTopLeft() Orientation: ' . $o, ['app' => 'core']);
+ $this->logger->debug('Image->heightTopLeft() Orientation: ' . $o, ['app' => 'core']);
switch ($o) {
case -1:
case 1:
@@ -171,7 +166,9 @@ class OC_Image implements \OCP\IImage {
if ($mimeType === null) {
$mimeType = $this->mimeType();
}
- header('Content-Type: ' . $mimeType);
+ if ($mimeType !== null) {
+ header('Content-Type: ' . $mimeType);
+ }
return $this->_output(null, $mimeType);
}
@@ -201,13 +198,10 @@ class OC_Image implements \OCP\IImage {
/**
* Outputs/saves the image.
*
- * @param string $filePath
- * @param string $mimeType
- * @return bool
- * @throws Exception
+ * @throws \Exception
*/
private function _output(?string $filePath = null, ?string $mimeType = null): bool {
- if ($filePath) {
+ if ($filePath !== null && $filePath !== '') {
if (!file_exists(dirname($filePath))) {
mkdir(dirname($filePath), 0777, true);
}
@@ -247,7 +241,7 @@ class OC_Image implements \OCP\IImage {
$imageType = IMAGETYPE_WEBP;
break;
default:
- throw new Exception('\OC_Image::_output(): "' . $mimeType . '" is not supported when forcing a specific output format');
+ throw new \Exception('Image::_output(): "' . $mimeType . '" is not supported when forcing a specific output format');
}
}
@@ -266,7 +260,7 @@ class OC_Image implements \OCP\IImage {
if (function_exists('imagexbm')) {
$retVal = imagexbm($this->resource, $filePath);
} else {
- throw new Exception('\OC_Image::_output(): imagexbm() is not supported.');
+ throw new \Exception('Image::_output(): imagexbm() is not supported.');
}
break;
@@ -350,11 +344,11 @@ class OC_Image implements \OCP\IImage {
break;
default:
$res = imagepng($this->resource);
- $this->logger->info('OC_Image->data. Could not guess mime-type, defaulting to png', ['app' => 'core']);
+ $this->logger->info('Image->data. Could not guess mime-type, defaulting to png', ['app' => 'core']);
break;
}
if (!$res) {
- $this->logger->error('OC_Image->data. Error getting image data.', ['app' => 'core']);
+ $this->logger->error('Image->data. Error getting image data.', ['app' => 'core']);
}
return ob_get_clean();
}
@@ -363,31 +357,22 @@ class OC_Image implements \OCP\IImage {
* @return string - base64 encoded, which is suitable for embedding in a VCard.
*/
public function __toString(): string {
- return base64_encode($this->data());
+ $data = $this->data();
+ if ($data === null) {
+ return '';
+ } else {
+ return base64_encode($data);
+ }
}
- /**
- * @return int
- */
protected function getJpegQuality(): int {
- $quality = $this->config->getAppValue('preview', 'jpeg_quality', (string)self::DEFAULT_JPEG_QUALITY);
- // TODO: remove when getAppValue is type safe
- if ($quality === null) {
- $quality = self::DEFAULT_JPEG_QUALITY;
- }
- return min(100, max(10, (int)$quality));
+ $quality = $this->appConfig->getValueInt('preview', 'jpeg_quality', self::DEFAULT_JPEG_QUALITY);
+ return min(100, max(10, $quality));
}
- /**
- * @return int
- */
protected function getWebpQuality(): int {
- $quality = $this->config->getAppValue('preview', 'webp_quality', (string)self::DEFAULT_WEBP_QUALITY);
- // TODO: remove when getAppValue is type safe
- if ($quality === null) {
- $quality = self::DEFAULT_WEBP_QUALITY;
- }
- return min(100, max(10, (int)$quality));
+ $quality = $this->appConfig->getValueInt('preview', 'webp_quality', self::DEFAULT_WEBP_QUALITY);
+ return min(100, max(10, $quality));
}
private function isValidExifData(array $exif): bool {
@@ -414,41 +399,41 @@ class OC_Image implements \OCP\IImage {
}
if ($this->imageType !== IMAGETYPE_JPEG) {
- $this->logger->debug('OC_Image->fixOrientation() Image is not a JPEG.', ['app' => 'core']);
+ $this->logger->debug('Image->fixOrientation() Image is not a JPEG.', ['app' => 'core']);
return -1;
}
if (!is_callable('exif_read_data')) {
- $this->logger->debug('OC_Image->fixOrientation() Exif module not enabled.', ['app' => 'core']);
+ $this->logger->debug('Image->fixOrientation() Exif module not enabled.', ['app' => 'core']);
return -1;
}
if (!$this->valid()) {
- $this->logger->debug('OC_Image->fixOrientation() No image loaded.', ['app' => 'core']);
+ $this->logger->debug('Image->fixOrientation() No image loaded.', ['app' => 'core']);
return -1;
}
if (is_null($this->filePath) || !is_readable($this->filePath)) {
- $this->logger->debug('OC_Image->fixOrientation() No readable file path set.', ['app' => 'core']);
+ $this->logger->debug('Image->fixOrientation() No readable file path set.', ['app' => 'core']);
return -1;
}
$exif = @exif_read_data($this->filePath, 'IFD0');
- if (!$exif || !$this->isValidExifData($exif)) {
+ if ($exif === false || !$this->isValidExifData($exif)) {
return -1;
}
$this->exif = $exif;
return (int)$exif['Orientation'];
}
- public function readExif($data): void {
+ public function readExif(string $data): void {
if (!is_callable('exif_read_data')) {
- $this->logger->debug('OC_Image->fixOrientation() Exif module not enabled.', ['app' => 'core']);
+ $this->logger->debug('Image->fixOrientation() Exif module not enabled.', ['app' => 'core']);
return;
}
if (!$this->valid()) {
- $this->logger->debug('OC_Image->fixOrientation() No image loaded.', ['app' => 'core']);
+ $this->logger->debug('Image->fixOrientation() No image loaded.', ['app' => 'core']);
return;
}
$exif = @exif_read_data('data://image/jpeg;base64,' . base64_encode($data));
- if (!$exif || !$this->isValidExifData($exif)) {
+ if ($exif === false || !$this->isValidExifData($exif)) {
return;
}
$this->exif = $exif;
@@ -466,7 +451,7 @@ class OC_Image implements \OCP\IImage {
return false;
}
$o = $this->getOrientation();
- $this->logger->debug('OC_Image->fixOrientation() Orientation: ' . $o, ['app' => 'core']);
+ $this->logger->debug('Image->fixOrientation() Orientation: ' . $o, ['app' => 'core']);
$rotate = 0;
$flip = false;
switch ($o) {
@@ -513,15 +498,15 @@ class OC_Image implements \OCP\IImage {
$this->resource = $res;
return true;
} else {
- $this->logger->debug('OC_Image->fixOrientation() Error during alpha-saving', ['app' => 'core']);
+ $this->logger->debug('Image->fixOrientation() Error during alpha-saving', ['app' => 'core']);
return false;
}
} else {
- $this->logger->debug('OC_Image->fixOrientation() Error during alpha-blending', ['app' => 'core']);
+ $this->logger->debug('Image->fixOrientation() Error during alpha-blending', ['app' => 'core']);
return false;
}
} else {
- $this->logger->debug('OC_Image->fixOrientation() Error during orientation fixing', ['app' => 'core']);
+ $this->logger->debug('Image->fixOrientation() Error during orientation fixing', ['app' => 'core']);
return false;
}
}
@@ -632,10 +617,10 @@ class OC_Image implements \OCP\IImage {
imagealphablending($this->resource, true);
imagesavealpha($this->resource, true);
} else {
- $this->logger->debug('OC_Image->loadFromFile, GIF image not valid: ' . $imagePath, ['app' => 'core']);
+ $this->logger->debug('Image->loadFromFile, GIF image not valid: ' . $imagePath, ['app' => 'core']);
}
} else {
- $this->logger->debug('OC_Image->loadFromFile, GIF images not supported: ' . $imagePath, ['app' => 'core']);
+ $this->logger->debug('Image->loadFromFile, GIF images not supported: ' . $imagePath, ['app' => 'core']);
}
break;
case IMAGETYPE_JPEG:
@@ -646,10 +631,10 @@ class OC_Image implements \OCP\IImage {
if (@getimagesize($imagePath) !== false) {
$this->resource = @imagecreatefromjpeg($imagePath);
} else {
- $this->logger->debug('OC_Image->loadFromFile, JPG image not valid: ' . $imagePath, ['app' => 'core']);
+ $this->logger->debug('Image->loadFromFile, JPG image not valid: ' . $imagePath, ['app' => 'core']);
}
} else {
- $this->logger->debug('OC_Image->loadFromFile, JPG images not supported: ' . $imagePath, ['app' => 'core']);
+ $this->logger->debug('Image->loadFromFile, JPG images not supported: ' . $imagePath, ['app' => 'core']);
}
break;
case IMAGETYPE_PNG:
@@ -663,10 +648,10 @@ class OC_Image implements \OCP\IImage {
imagealphablending($this->resource, true);
imagesavealpha($this->resource, true);
} else {
- $this->logger->debug('OC_Image->loadFromFile, PNG image not valid: ' . $imagePath, ['app' => 'core']);
+ $this->logger->debug('Image->loadFromFile, PNG image not valid: ' . $imagePath, ['app' => 'core']);
}
} else {
- $this->logger->debug('OC_Image->loadFromFile, PNG images not supported: ' . $imagePath, ['app' => 'core']);
+ $this->logger->debug('Image->loadFromFile, PNG images not supported: ' . $imagePath, ['app' => 'core']);
}
break;
case IMAGETYPE_XBM:
@@ -676,7 +661,7 @@ class OC_Image implements \OCP\IImage {
}
$this->resource = @imagecreatefromxbm($imagePath);
} else {
- $this->logger->debug('OC_Image->loadFromFile, XBM/XPM images not supported: ' . $imagePath, ['app' => 'core']);
+ $this->logger->debug('Image->loadFromFile, XBM/XPM images not supported: ' . $imagePath, ['app' => 'core']);
}
break;
case IMAGETYPE_WBMP:
@@ -686,7 +671,7 @@ class OC_Image implements \OCP\IImage {
}
$this->resource = @imagecreatefromwbmp($imagePath);
} else {
- $this->logger->debug('OC_Image->loadFromFile, WBMP images not supported: ' . $imagePath, ['app' => 'core']);
+ $this->logger->debug('Image->loadFromFile, WBMP images not supported: ' . $imagePath, ['app' => 'core']);
}
break;
case IMAGETYPE_BMP:
@@ -708,7 +693,7 @@ class OC_Image implements \OCP\IImage {
return false;
}
$data = fread($fp, 90);
- if (!$data) {
+ if ($data === false) {
return false;
}
fclose($fp);
@@ -722,7 +707,7 @@ class OC_Image implements \OCP\IImage {
$header = unpack($headerFormat, $data);
unset($data, $headerFormat);
- if (!$header) {
+ if ($header === false) {
return false;
}
@@ -740,13 +725,13 @@ class OC_Image implements \OCP\IImage {
// Check for animation indicators
if (strpos(strtoupper($header['Chunk']), 'ANIM') !== false || strpos(strtoupper($header['Chunk']), 'ANMF') !== false) {
// Animated so don't let it reach libgd
- $this->logger->debug('OC_Image->loadFromFile, animated WEBP images not supported: ' . $imagePath, ['app' => 'core']);
+ $this->logger->debug('Image->loadFromFile, animated WEBP images not supported: ' . $imagePath, ['app' => 'core']);
} else {
// We're safe so give it to libgd
$this->resource = @imagecreatefromwebp($imagePath);
}
} else {
- $this->logger->debug('OC_Image->loadFromFile, WEBP images not supported: ' . $imagePath, ['app' => 'core']);
+ $this->logger->debug('Image->loadFromFile, WEBP images not supported: ' . $imagePath, ['app' => 'core']);
}
break;
/*
@@ -782,7 +767,7 @@ class OC_Image implements \OCP\IImage {
}
$this->resource = @imagecreatefromstring($data);
$iType = IMAGETYPE_PNG;
- $this->logger->debug('OC_Image->loadFromFile, Default', ['app' => 'core']);
+ $this->logger->debug('Image->loadFromFile, Default', ['app' => 'core']);
break;
}
if ($this->valid()) {
@@ -797,9 +782,8 @@ class OC_Image implements \OCP\IImage {
* Loads an image from a string of data.
*
* @param string $str A string of image data as read from a file.
- * @return bool|\GdImage An image resource or false on error
*/
- public function loadFromData(string $str) {
+ public function loadFromData(string $str): GdImage|false {
if (!$this->checkImageDataSize($str)) {
return false;
}
@@ -813,7 +797,7 @@ class OC_Image implements \OCP\IImage {
}
if (!$this->resource) {
- $this->logger->debug('OC_Image->loadFromFile, could not load', ['app' => 'core']);
+ $this->logger->debug('Image->loadFromFile, could not load', ['app' => 'core']);
return false;
}
return $this->resource;
@@ -836,7 +820,7 @@ class OC_Image implements \OCP\IImage {
$this->mimeType = $this->fileInfo->buffer($data);
}
if (!$this->resource) {
- $this->logger->debug('OC_Image->loadFromBase64, could not load', ['app' => 'core']);
+ $this->logger->debug('Image->loadFromBase64, could not load', ['app' => 'core']);
return false;
}
return $this->resource;
@@ -862,11 +846,7 @@ class OC_Image implements \OCP\IImage {
return $this->valid();
}
- /**
- * @param $maxSize
- * @return bool|\GdImage
- */
- private function resizeNew(int $maxSize) {
+ private function resizeNew(int $maxSize): \GdImage|false {
if (!$this->valid()) {
$this->logger->debug(__METHOD__ . '(): No image loaded', ['app' => 'core']);
return false;
@@ -902,12 +882,7 @@ class OC_Image implements \OCP\IImage {
return $this->valid();
}
- /**
- * @param int $width
- * @param int $height
- * @return bool|\GdImage
- */
- public function preciseResizeNew(int $width, int $height) {
+ public function preciseResizeNew(int $width, int $height): \GdImage|false {
if (!($width > 0) || !($height > 0)) {
$this->logger->info(__METHOD__ . '(): Requested image size not bigger than 0', ['app' => 'core']);
return false;
@@ -926,7 +901,11 @@ class OC_Image implements \OCP\IImage {
// preserve transparency
if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) {
- imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127));
+ $alpha = imagecolorallocatealpha($process, 0, 0, 0, 127);
+ if ($alpha === false) {
+ $alpha = null;
+ }
+ imagecolortransparent($process, $alpha);
imagealphablending($process, false);
imagesavealpha($process, true);
}
@@ -948,7 +927,7 @@ class OC_Image implements \OCP\IImage {
*/
public function centerCrop(int $size = 0): bool {
if (!$this->valid()) {
- $this->logger->debug('OC_Image->centerCrop, No image loaded', ['app' => 'core']);
+ $this->logger->debug('Image->centerCrop, No image loaded', ['app' => 'core']);
return false;
}
$widthOrig = imagesx($this->resource);
@@ -975,20 +954,24 @@ class OC_Image implements \OCP\IImage {
}
$process = imagecreatetruecolor($targetWidth, $targetHeight);
if ($process === false) {
- $this->logger->debug('OC_Image->centerCrop, Error creating true color image', ['app' => 'core']);
+ $this->logger->debug('Image->centerCrop, Error creating true color image', ['app' => 'core']);
return false;
}
// preserve transparency
if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) {
- imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127) ?: null);
+ $alpha = imagecolorallocatealpha($process, 0, 0, 0, 127);
+ if ($alpha === false) {
+ $alpha = null;
+ }
+ imagecolortransparent($process, $alpha);
imagealphablending($process, false);
imagesavealpha($process, true);
}
$result = imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $targetWidth, $targetHeight, $width, $height);
if ($result === false) {
- $this->logger->debug('OC_Image->centerCrop, Error re-sampling process image ' . $width . 'x' . $height, ['app' => 'core']);
+ $this->logger->debug('Image->centerCrop, Error re-sampling process image ' . $width . 'x' . $height, ['app' => 'core']);
return false;
}
imagedestroy($this->resource);
@@ -1038,7 +1021,11 @@ class OC_Image implements \OCP\IImage {
// preserve transparency
if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) {
- imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127) ?: null);
+ $alpha = imagecolorallocatealpha($process, 0, 0, 0, 127);
+ if ($alpha === false) {
+ $alpha = null;
+ }
+ imagecolortransparent($process, $alpha);
imagealphablending($process, false);
imagesavealpha($process, true);
}
@@ -1099,11 +1086,19 @@ class OC_Image implements \OCP\IImage {
}
public function copy(): IImage {
- $image = new OC_Image(null, $this->logger, $this->config);
+ $image = new self($this->logger, $this->appConfig, $this->config);
+ if (!$this->valid()) {
+ /* image is invalid, return an empty one */
+ return $image;
+ }
$image->resource = imagecreatetruecolor($this->width(), $this->height());
+ if (!$image->valid()) {
+ /* image creation failed, cannot copy in it */
+ return $image;
+ }
imagecopy(
- $image->resource(),
- $this->resource(),
+ $image->resource,
+ $this->resource,
0,
0,
0,
@@ -1116,7 +1111,7 @@ class OC_Image implements \OCP\IImage {
}
public function cropCopy(int $x, int $y, int $w, int $h): IImage {
- $image = new OC_Image(null, $this->logger, $this->config);
+ $image = new self($this->logger, $this->appConfig, $this->config);
$image->imageType = $this->imageType;
$image->mimeType = $this->mimeType;
$image->resource = $this->cropNew($x, $y, $w, $h);
@@ -1125,7 +1120,7 @@ class OC_Image implements \OCP\IImage {
}
public function preciseResizeCopy(int $width, int $height): IImage {
- $image = new OC_Image(null, $this->logger, $this->config);
+ $image = new self($this->logger, $this->appConfig, $this->config);
$image->imageType = $this->imageType;
$image->mimeType = $this->mimeType;
$image->resource = $this->preciseResizeNew($width, $height);
@@ -1134,7 +1129,7 @@ class OC_Image implements \OCP\IImage {
}
public function resizeCopy(int $maxSize): IImage {
- $image = new OC_Image(null, $this->logger, $this->config);
+ $image = new self($this->logger, $this->appConfig, $this->config);
$image->imageType = $this->imageType;
$image->mimeType = $this->mimeType;
$image->resource = $this->resizeNew($maxSize);
diff --git a/lib/public/Image.php b/lib/public/Image.php
index e2565cca9a4..a9aab778207 100644
--- a/lib/public/Image.php
+++ b/lib/public/Image.php
@@ -14,5 +14,5 @@ namespace OCP;
* This class provides functions to handle images
* @since 6.0.0
*/
-class Image extends \OC_Image {
+class Image extends \OC\Image {
}
diff --git a/tests/lib/Avatar/UserAvatarTest.php b/tests/lib/Avatar/UserAvatarTest.php
index 2687972b8f6..fde2ccef5c3 100644
--- a/tests/lib/Avatar/UserAvatarTest.php
+++ b/tests/lib/Avatar/UserAvatarTest.php
@@ -14,6 +14,7 @@ use OCP\Files\NotFoundException;
use OCP\Files\SimpleFS\ISimpleFile;
use OCP\IConfig;
use OCP\IL10N;
+use OCP\Image;
use Psr\Log\LoggerInterface;
class UserAvatarTest extends \Test\TestCase {
@@ -92,7 +93,7 @@ class UserAvatarTest extends \Test\TestCase {
['generated', false],
]);
- $expected = new \OC_Image();
+ $expected = new Image();
$expected->loadFromFile(\OC::$SERVERROOT . '/tests/data/testavatar.png');
$file = $this->createMock(ISimpleFile::class);
@@ -109,7 +110,7 @@ class UserAvatarTest extends \Test\TestCase {
['generated', false],
]);
- $expected = new \OC_Image();
+ $expected = new Image();
$expected->loadFromFile(\OC::$SERVERROOT . '/tests/data/testavatar.png');
$file = $this->createMock(ISimpleFile::class);
@@ -128,9 +129,9 @@ class UserAvatarTest extends \Test\TestCase {
['generated', false],
]);
- $expected = new \OC_Image();
+ $expected = new Image();
$expected->loadFromFile(\OC::$SERVERROOT . '/tests/data/testavatar.png');
- $expected2 = new \OC_Image();
+ $expected2 = new Image();
$expected2->loadFromFile(\OC::$SERVERROOT . '/tests/data/testavatar.png');
$expected2->resize(32);
@@ -215,7 +216,7 @@ class UserAvatarTest extends \Test\TestCase {
->with('avatar.png')
->willReturn($newFile);
- $image = new \OC_Image();
+ $image = new Image();
$image->loadFromFile(\OC::$SERVERROOT . '/tests/data/testavatar.png');
$newFile->expects($this->once())
->method('putContent')
diff --git a/tests/lib/ImageTest.php b/tests/lib/ImageTest.php
index 2e93a7fb6fd..80cf22a9442 100644
--- a/tests/lib/ImageTest.php
+++ b/tests/lib/ImageTest.php
@@ -8,6 +8,8 @@
namespace Test;
use OC;
+use OC\Image;
+use OCP\IAppConfig;
use OCP\IConfig;
class ImageTest extends \Test\TestCase {
@@ -19,105 +21,105 @@ class ImageTest extends \Test\TestCase {
}
public function testConstructDestruct() {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
- $this->assertInstanceOf('\OC_Image', $img);
+ $this->assertInstanceOf('\OC\Image', $img);
$this->assertInstanceOf('\OCP\IImage', $img);
unset($img);
$imgcreate = imagecreatefromjpeg(OC::$SERVERROOT.'/tests/data/testimage.jpg');
- $img = new \OC_Image();
+ $img = new Image();
$img->setResource($imgcreate);
- $this->assertInstanceOf('\OC_Image', $img);
+ $this->assertInstanceOf('\OC\Image', $img);
$this->assertInstanceOf('\OCP\IImage', $img);
unset($img);
$base64 = base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif'));
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromBase64($base64);
- $this->assertInstanceOf('\OC_Image', $img);
+ $this->assertInstanceOf('\OC\Image', $img);
$this->assertInstanceOf('\OCP\IImage', $img);
unset($img);
- $img = new \OC_Image();
- $this->assertInstanceOf('\OC_Image', $img);
+ $img = new Image();
+ $this->assertInstanceOf('\OC\Image', $img);
$this->assertInstanceOf('\OCP\IImage', $img);
unset($img);
}
public function testValid() {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
$this->assertTrue($img->valid());
$text = base64_encode('Lorem ipsum dolor sir amet …');
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromBase64($text);
$this->assertFalse($img->valid());
- $img = new \OC_Image();
+ $img = new Image();
$this->assertFalse($img->valid());
}
public function testMimeType() {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
$this->assertEquals('image/png', $img->mimeType());
- $img = new \OC_Image();
+ $img = new Image();
$this->assertEquals('', $img->mimeType());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
$this->assertEquals('image/jpeg', $img->mimeType());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromBase64(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif')));
$this->assertEquals('image/gif', $img->mimeType());
}
public function testWidth() {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
$this->assertEquals(128, $img->width());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
$this->assertEquals(1680, $img->width());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromBase64(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif')));
$this->assertEquals(64, $img->width());
- $img = new \OC_Image();
+ $img = new Image();
$this->assertEquals(-1, $img->width());
}
public function testHeight() {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
$this->assertEquals(128, $img->height());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
$this->assertEquals(1050, $img->height());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromBase64(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif')));
$this->assertEquals(64, $img->height());
- $img = new \OC_Image();
+ $img = new Image();
$this->assertEquals(-1, $img->height());
}
public function testSave() {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
$img->resize(16);
$img->save(OC::$SERVERROOT.'/tests/data/testimage2.png');
$this->assertEquals(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage2.png'), $img->data());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.jpg');
$img->resize(128);
$img->save(OC::$SERVERROOT.'/tests/data/testimage2.jpg');
@@ -125,7 +127,7 @@ class ImageTest extends \Test\TestCase {
}
public function testData() {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
$raw = imagecreatefromstring(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.png'));
// Preserve transparency
@@ -136,16 +138,17 @@ class ImageTest extends \Test\TestCase {
$expected = ob_get_clean();
$this->assertEquals($expected, $img->data());
+ $appConfig = $this->createMock(IAppConfig::class);
+ $appConfig->expects($this->once())
+ ->method('getValueInt')
+ ->with('preview', 'jpeg_quality', 80)
+ ->willReturn(80);
$config = $this->createMock(IConfig::class);
$config->expects($this->once())
- ->method('getAppValue')
- ->with('preview', 'jpeg_quality', '80')
- ->willReturn(null);
- $config->expects($this->once())
->method('getSystemValueInt')
->with('preview_max_memory', 256)
->willReturn(256);
- $img = new \OC_Image(null, null, $config);
+ $img = new Image(null, $appConfig, $config);
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.jpg');
$raw = imagecreatefromstring(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
imageinterlace($raw, true);
@@ -154,7 +157,7 @@ class ImageTest extends \Test\TestCase {
$expected = ob_get_clean();
$this->assertEquals($expected, $img->data());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.gif');
$raw = imagecreatefromstring(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif'));
ob_start();
@@ -164,7 +167,7 @@ class ImageTest extends \Test\TestCase {
}
public function testDataNoResource() {
- $img = new \OC_Image();
+ $img = new Image();
$this->assertNull($img->data());
}
@@ -172,36 +175,36 @@ class ImageTest extends \Test\TestCase {
* @depends testData
*/
public function testToString() {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
$expected = base64_encode($img->data());
$this->assertEquals($expected, (string)$img);
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
$expected = base64_encode($img->data());
$this->assertEquals($expected, (string)$img);
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.gif');
$expected = base64_encode($img->data());
$this->assertEquals($expected, (string)$img);
}
public function testResize() {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
$this->assertTrue($img->resize(32));
$this->assertEquals(32, $img->width());
$this->assertEquals(32, $img->height());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
$this->assertTrue($img->resize(840));
$this->assertEquals(840, $img->width());
$this->assertEquals(525, $img->height());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromBase64(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif')));
$this->assertTrue($img->resize(100));
$this->assertEquals(100, $img->width());
@@ -209,19 +212,19 @@ class ImageTest extends \Test\TestCase {
}
public function testPreciseResize() {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
$this->assertTrue($img->preciseResize(128, 512));
$this->assertEquals(128, $img->width());
$this->assertEquals(512, $img->height());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
$this->assertTrue($img->preciseResize(64, 840));
$this->assertEquals(64, $img->width());
$this->assertEquals(840, $img->height());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromBase64(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif')));
$this->assertTrue($img->preciseResize(1000, 1337));
$this->assertEquals(1000, $img->width());
@@ -229,19 +232,19 @@ class ImageTest extends \Test\TestCase {
}
public function testCenterCrop() {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
$img->centerCrop();
$this->assertEquals(128, $img->width());
$this->assertEquals(128, $img->height());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
$img->centerCrop();
$this->assertEquals(1050, $img->width());
$this->assertEquals(1050, $img->height());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromBase64(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif')));
$img->centerCrop(512);
$this->assertEquals(512, $img->width());
@@ -249,19 +252,19 @@ class ImageTest extends \Test\TestCase {
}
public function testCrop() {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
$this->assertTrue($img->crop(0, 0, 50, 20));
$this->assertEquals(50, $img->width());
$this->assertEquals(20, $img->height());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromData(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.jpg'));
$this->assertTrue($img->crop(500, 700, 550, 300));
$this->assertEquals(550, $img->width());
$this->assertEquals(300, $img->height());
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromBase64(base64_encode(file_get_contents(OC::$SERVERROOT.'/tests/data/testimage.gif')));
$this->assertTrue($img->crop(10, 10, 15, 15));
$this->assertEquals(15, $img->width());
@@ -284,7 +287,7 @@ class ImageTest extends \Test\TestCase {
* @param int[] $expected
*/
public function testFitIn($filename, $asked, $expected) {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT . '/tests/data/' . $filename);
$this->assertTrue($img->fitIn($asked[0], $asked[1]));
$this->assertEquals($expected[0], $img->width());
@@ -307,7 +310,7 @@ class ImageTest extends \Test\TestCase {
* @param string $filename
*/
public function testScaleDownToFitWhenSmallerAlready($filename) {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/' . $filename);
$currentWidth = $img->width();
$currentHeight = $img->height();
@@ -340,7 +343,7 @@ class ImageTest extends \Test\TestCase {
* @param int[] $expected
*/
public function testScaleDownWhenBigger($filename, $asked, $expected) {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/' . $filename);
//$this->assertTrue($img->scaleDownToFit($asked[0], $asked[1]));
$img->scaleDownToFit($asked[0], $asked[1]);
@@ -360,7 +363,7 @@ class ImageTest extends \Test\TestCase {
* @dataProvider convertDataProvider
*/
public function testConvert($mimeType) {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage.png');
$tempFile = tempnam(sys_get_temp_dir(), 'img-test');
@@ -369,14 +372,14 @@ class ImageTest extends \Test\TestCase {
}
public function testMemoryLimitFromFile() {
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromFile(OC::$SERVERROOT.'/tests/data/testimage-badheader.jpg');
$this->assertFalse($img->valid());
}
public function testMemoryLimitFromData() {
$data = file_get_contents(OC::$SERVERROOT.'/tests/data/testimage-badheader.jpg');
- $img = new \OC_Image();
+ $img = new Image();
$img->loadFromData($data);
$this->assertFalse($img->valid());
}
diff --git a/tests/lib/Preview/GeneratorTest.php b/tests/lib/Preview/GeneratorTest.php
index 9116fee7e2f..caac15c3532 100644
--- a/tests/lib/Preview/GeneratorTest.php
+++ b/tests/lib/Preview/GeneratorTest.php
@@ -15,6 +15,7 @@ use OCP\Files\NotFoundException;
use OCP\Files\SimpleFS\ISimpleFile;
use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\IConfig;
+use OCP\IImage;
use OCP\IPreview;
use OCP\Preview\BeforePreviewFetchedEvent;
use OCP\Preview\IProviderV2;
@@ -161,7 +162,7 @@ class GeneratorTest extends \Test\TestCase {
$this->fail('Unexpected provider requested');
});
- $image = $this->createMock(\OC_Image::class);
+ $image = $this->createMock(IImage::class);
$image->method('width')->willReturn(2048);
$image->method('height')->willReturn(2048);
$image->method('valid')->willReturn(true);
@@ -329,7 +330,7 @@ class GeneratorTest extends \Test\TestCase {
}
private function getMockImage($width, $height, $data = null) {
- $image = $this->createMock(\OC_Image::class);
+ $image = $this->createMock(IImage::class);
$image->method('height')->willReturn($width);
$image->method('width')->willReturn($height);
$image->method('valid')->willReturn(true);