]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
No need for ImageMagick to detected animated GIF
authorMikael Nordfeldth <mmn@hethane.se>
Sun, 25 Jan 2015 21:45:25 +0000 (22:45 +0100)
committerMikael Nordfeldth <mmn@hethane.se>
Sun, 25 Jan 2015 21:45:25 +0000 (22:45 +0100)
classes/File.php
lib/imagefile.php
plugins/ImageMagick/ImageMagickPlugin.php

index 68da5c6f1ba6583d5f58a94b89f166969000967a..65414977d3114ed5b8fdcd3b045a87ca1d806184 100644 (file)
@@ -384,6 +384,12 @@ class File extends Managed_DataObject
      */
     public function getThumbnail($width=null, $height=null, $crop=false)
     {
+        // Get some more information about this file through our ImageFile class
+        $image = ImageFile::fromFileObject($this);
+        if ($image->animated && !common_config('image', 'resize_animated')) {
+            throw new UseFileAsThumbnailException($this->id);
+        }
+
         if ($width === null) {
             $width = common_config('thumbnail', 'width');
             $height = common_config('thumbnail', 'height');
@@ -398,7 +404,6 @@ class File extends Managed_DataObject
         // Get proper aspect ratio width and height before lookup
         // We have to do it through an ImageFile object because of orientation etc.
         // Only other solution would've been to rotate + rewrite uploaded files.
-        $image = ImageFile::fromFileObject($this);
         list($width, $height, $x, $y, $w, $h) =
                                 $image->scaleToFit($width, $height, $crop);
 
index 967519a95063b483302b747ece0415197054d0ff..6aeab35816e3b3ca399ecd0683fac93e3b1680a4 100644 (file)
@@ -52,7 +52,7 @@ class ImageFile
     var $height;
     var $width;
     var $rotate=0;  // degrees to rotate for properly oriented image (extrapolated from EXIF etc.)
-    var $animated = false;  // Animated image? (has more than 1 frame)
+    var $animated = null;  // Animated image? (has more than 1 frame). null means untested
 
     function __construct($id=null, $filepath=null, $type=null, $width=null, $height=null)
     {
@@ -98,6 +98,8 @@ class ImageFile
                 }
                 // If we ever write this back, Orientation should be set to '1'
             }
+        } elseif ($this->type === IMAGETYPE_GIF) {
+            $this->animated = $this->isAnimatedGif();
         }
 
         Event::handle('FillImageFileMetadata', array($this));
@@ -500,6 +502,41 @@ class ImageFile
                     is_null($cw) ? $width : intval($cw),
                     is_null($ch) ? $height : intval($ch));
     }
+
+    /**
+     * Animated GIF test, courtesy of frank at huddler dot com et al:
+     * http://php.net/manual/en/function.imagecreatefromgif.php#104473
+     * Modified so avoid landing inside of a header (and thus not matching our regexp).
+     */
+    protected function isAnimatedGif()
+    {
+        if (!($fh = @fopen($this->filepath, 'rb'))) {
+            return false;
+        }
+
+        $count = 0;
+        //an animated gif contains multiple "frames", with each frame having a
+        //header made up of:
+        // * a static 4-byte sequence (\x00\x21\xF9\x04)
+        // * 4 variable bytes
+        // * a static 2-byte sequence (\x00\x2C)
+        // In total the header is maximum 10 bytes.
+
+        // We read through the file til we reach the end of the file, or we've found
+        // at least 2 frame headers
+        while(!feof($fh) && $count < 2) {
+            $chunk = fread($fh, 1024 * 100); //read 100kb at a time
+            $count += preg_match_all('#\x00\x21\xF9\x04.{4}\x00\x2C#s', $chunk, $matches);
+            // rewind in case we ended up in the middle of the header, but avoid
+            // infinite loop (i.e. don't rewind if we're already in the end).
+            if (!feof($fh) && ftell($fh) >= 9) {
+                fseek($fh, -9, SEEK_CUR);
+            }
+        }
+
+        fclose($fh);
+        return $count > 1;
+    }
 }
 
 //PHP doesn't (as of 2/24/2010) have an imagecreatefrombmp so conditionally define one
index ff2e6664489efbd329bf762d78522b26fc0b4bea..26335b6df884c1885dc16228ad9de7f6af11dd98 100644 (file)
@@ -65,12 +65,10 @@ class ImageMagickPlugin extends Plugin
      * @param array $info The response from getimagesize()
      */
     public function onFillImageFileMetadata(ImageFile $imagefile) {
-        switch ($imagefile->type) {
-        case IMAGETYPE_GIF:
+        if (is_null($imagefile->animated) && $imagefile->type === IMAGETYPE_GIF) {
             $magick = new Imagick($imagefile->filepath);
             $magick = $magick->coalesceImages();
             $imagefile->animated = $magick->getNumberImages()>1;
-            return true;
         }
 
         return true;