Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Experimental support for WebP and AVIF as a preview
Signed-off-by: JanisPlayer <[email protected]>
  • Loading branch information
JanisPlayer authored Sep 10, 2023
commit 276d4737db190755d67fdcaf73e3be7f871a3334
61 changes: 61 additions & 0 deletions lib/private/legacy/OC_Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class OC_Image implements \OCP\IImage {

// Default quality for jpeg images
protected const DEFAULT_JPEG_QUALITY = 80;
protected const DEFAULT_WEBP_QUALITY = 80;
protected const DEFAULT_AVIF_QUALITY = 80;

/** @var false|resource|\GdImage */
protected $resource = false; // tmp resource.
Expand Down Expand Up @@ -273,6 +275,12 @@ private function _output(?string $filePath = null, ?string $mimeType = null): bo
case 'image/jpeg':
$imageType = IMAGETYPE_JPEG;
break;
case 'image/webp':
$imageType = IMAGETYPE_WEBP;
break;
case 'image/avif':
$imageType = IMAGETYPE_AVIF;
break;
case 'image/png':
$imageType = IMAGETYPE_PNG;
break;
Expand All @@ -297,6 +305,16 @@ private function _output(?string $filePath = null, ?string $mimeType = null): bo
imageinterlace($this->resource, (PHP_VERSION_ID >= 80000 ? true : 1));
$retVal = imagejpeg($this->resource, $filePath, $this->getJpegQuality());
break;
case "image/webp":
/** @psalm-suppress InvalidScalarArgument */
imageinterlace($this->resource, (PHP_VERSION_ID >= 80100 ? true : 1));
$retVal = imagewebp($this->resource, $filePath, $this->getWebpQuality());
break;
case "image/avif":
/** @psalm-suppress InvalidScalarArgument */
imageinterlace($this->resource, (PHP_VERSION_ID >= 80100 ? true : 1));
$retVal = imageavif($this->resource, $filePath, $this->getAvifQuality(), 10);

Check failure

Code scanning / Psalm

UndefinedFunction

Function imageavif does not exist
break;
case IMAGETYPE_PNG:
$retVal = imagepng($this->resource, $filePath);
break;
Expand Down Expand Up @@ -360,9 +378,24 @@ public function dataMimeType(): ?string {
return null;
}

if ($this->mimeType !== 'image/gif') {
$preview_format = $this->config->getSystemValueString('preview_format', 'jpeg');

switch ($preview_format) { // Change the format to the correct one
case 'webp':
return 'image/webp';
break;
case 'avif':
return 'image/avif';
break;
default:
}
}

switch ($this->mimeType) {
case 'image/png':
case 'image/jpeg':
case 'image/webp':

Check failure

Code scanning / Psalm

TypeDoesNotContainType

Type never for $this->mimeType is never =string(image/webp)
case 'image/avif':
return 'image/jpeg';
case 'image/gif':
Expand Down Expand Up @@ -390,6 +423,16 @@ public function data(): ?string {
$quality = $this->getJpegQuality();
$res = imagejpeg($this->resource, null, $quality);
break;
case "image/webp":
/** @psalm-suppress InvalidScalarArgument */
imageinterlace($this->resource, (PHP_VERSION_ID >= 80100 ? true : 1));
$res = imagewebp($this->resource, null, $this->getWebpQuality());
break;
case "image/avif":
/** @psalm-suppress InvalidScalarArgument */
imageinterlace($this->resource, (PHP_VERSION_ID >= 80100 ? true : 1));
$res = imageavif($this->resource, null, $this->getAvifQuality(), 10);

Check failure

Code scanning / Psalm

UndefinedFunction

Function imageavif does not exist
break;
case "image/gif":
$res = imagegif($this->resource);
break;
Expand Down Expand Up @@ -423,6 +466,24 @@ protected function getJpegQuality(): int {
return min(100, max(10, (int) $quality));
}

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));
}

protected function getAvifQuality(): int {
$quality = $this->config->getAppValue('preview', 'avif_quality', (string) self::DEFAULT_AVIF_QUALITY);
// TODO: remove when getAppValue is type safe
if ($quality === null) {
$quality = self::DEFAULT_AVIF_QUALITY;
}
return min(100, max(10, (int) $quality));
}

/**
* (I'm open for suggestions on better method name ;)
* Get the orientation based on EXIF data.
Expand Down