Fix the handling of unhandled image types and of animations (#13904)
authorMichael Vogel <icarus@dabo.de>
Sat, 17 Feb 2024 14:46:48 +0000 (15:46 +0100)
committerGitHub <noreply@github.com>
Sat, 17 Feb 2024 14:46:48 +0000 (15:46 +0100)
* Fix the handling of unhandled image types and of animations

* Avoid warnings

src/Module/Photo.php
src/Module/Proxy.php
src/Object/Image.php
src/Util/Images.php

index 3a064c4..1bac70c 100644 (file)
@@ -207,13 +207,13 @@ class Photo extends BaseApi
                        $mimetype = $img->getType();
                }
 
-               // if customsize is set and image is not a gif, resize it
-               if ($photo['type'] !== image_type_to_mime_type(IMAGETYPE_GIF) && $customsize > 0 && $customsize <= Proxy::PIXEL_THUMB && $square_resize) {
+               // if customsize is set and image resizing is supported for this image, resize it
+               if (Images::canResize($photo['type']) && $customsize > 0 && $customsize <= Proxy::PIXEL_THUMB && $square_resize) {
                        $img = new Image($imgdata, $photo['type'], $photo['filename']);
                        $img->scaleToSquare($customsize);
                        $imgdata  = $img->asString();
                        $mimetype = $img->getType();
-               } elseif ($photo['type'] !== image_type_to_mime_type(IMAGETYPE_GIF) && $customsize > 0) {
+               } elseif (Images::canResize($photo['type']) && $customsize > 0) {
                        $img = new Image($imgdata, $photo['type'], $photo['filename']);
                        $img->scaleDown($customsize);
                        $imgdata  = $img->asString();
index 12f58f3..8a72e40 100644 (file)
@@ -106,8 +106,8 @@ class Proxy extends BaseModule
                        // stop.
                }
 
-               // reduce quality - if it isn't a GIF
-               if ($image->getImageType() != IMAGETYPE_GIF) {
+               // reduce quality - if it is supported for this image type
+               if (Images::canResize($image->getType())) {
                        $image->scaleDown($request['size']);
                }
 
index d938643..d024904 100644 (file)
@@ -66,7 +66,7 @@ class Image
 
                if (Images::isSupportedMimeType($type)) {
                        $this->imageType = Images::getImageTypeByMimeType($type);
-               } elseif (($type == '') || substr($type, 0, 6) != 'image/' || substr($type, 0, 12) != ' application/') {
+               } elseif (($type == '') || substr($type, 0, 6) == 'image/' || substr($type, 0, 12) == ' application/') {
                        $this->imageType = IMAGETYPE_WEBP;
                        DI::logger()->debug('Unhandled image mime type, use WebP instead', ['type' => $type, 'filename' => $filename, 'size' => strlen($data)]);
                } else {
@@ -100,7 +100,7 @@ class Image
                }
 
                if ($this->imageType == IMAGETYPE_GIF) {
-                       $count = preg_match_all("#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s", $data);
+                       $count = @preg_match_all("#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s", $data);
                        return ($count > 0);
                }
 
@@ -115,7 +115,7 @@ class Image
         */
        private function isAnimatedWebP(string $data) {
                $header_format = 'A4Riff/I1Filesize/A4Webp/A4Vp/A74Chunk';
-               $header = unpack($header_format, $data);
+               $header = @unpack($header_format, $data);
 
                if (!isset($header['Riff']) || strtoupper($header['Riff']) !== 'RIFF') {
                        return false;
index 33bae87..f5a7e5a 100644 (file)
@@ -183,6 +183,21 @@ class Images
                return $types;
        }
 
+       /**
+        * Checks if the provided mime type can be handled for resizing.
+        * Only with Imagick installed, animated GIF and WebP keep their animation after resize.
+        *
+        * @param string $mimetype
+        * @return boolean
+        */
+       public static function canResize(string $mimetype): bool
+       {
+               if (in_array(self::getImageTypeByMimeType($mimetype), [IMAGETYPE_GIF, IMAGETYPE_WEBP])) {
+                       return class_exists('Imagick');
+               }
+               return true;
+       }
+
        /**
         * Fetch image mimetype from the image data or guessing from the file name
         *