From d456460d33859a3f6890062083ace6f64aa17266 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9gis=20Hanol?= <regis@hanol.fr>
Date: Wed, 22 Jul 2015 17:10:42 +0200
Subject: [PATCH] FIX: don't butcher GIFs

Use 'gifsicle' instead of 'convert' to resize & optimize GIFs

FIX: don't even try to fix GIFs orientation
FIX: use 'allow_animated_thumbnails' site setting for user profile backgrounds & user cards
---
 app/models/optimized_image.rb | 23 +++++++++--------------
 app/models/upload.rb          |  6 +++---
 2 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/app/models/optimized_image.rb b/app/models/optimized_image.rb
index 969c20bbe7f..a70c86e63ad 100644
--- a/app/models/optimized_image.rb
+++ b/app/models/optimized_image.rb
@@ -99,6 +99,7 @@ class OptimizedImage < ActiveRecord::Base
   def self.resize_instructions(from, to, dimensions, opts={})
     # NOTE: ORDER is important!
     %W{
+      convert
       #{from}[0]
       -gravity center
       -background transparent
@@ -113,17 +114,18 @@ class OptimizedImage < ActiveRecord::Base
 
   def self.resize_instructions_animated(from, to, dimensions, opts={})
     %W{
+      gifsicle
       #{from}
-      -coalesce
-      -gravity center
-      -thumbnail #{dimensions}^
-      -extent #{dimensions}
-      #{to}
+      --colors=256
+      --resize-fit #{dimensions}
+      --optimize=3
+      --output #{to}
     }
   end
 
   def self.downsize_instructions(from, to, dimensions, opts={})
     %W{
+      convert
       #{from}[0]
       -gravity center
       -background transparent
@@ -133,14 +135,7 @@ class OptimizedImage < ActiveRecord::Base
   end
 
   def self.downsize_instructions_animated(from, to, dimensions, opts={})
-    %W{
-      #{from}
-      -coalesce
-      -gravity center
-      -background transparent
-      -resize #{dimensions}#{!!opts[:force_aspect_ratio] ? "\\!" : "\\>"}
-      #{to}
-    }
+    resize_instructions_animated(from, to, dimensions, opts)
   end
 
   def self.resize(from, to, width, height, opts={})
@@ -164,7 +159,7 @@ class OptimizedImage < ActiveRecord::Base
   end
 
   def self.convert_with(instructions, to)
-    `convert #{instructions.join(" ")} &> /dev/null`
+    `#{instructions.join(" ")} &> /dev/null`
     return false if $?.exitstatus != 0
 
     ImageOptim.new.optimize_image!(to)
diff --git a/app/models/upload.rb b/app/models/upload.rb
index b8e0a1e5f5f..59a647f769e 100644
--- a/app/models/upload.rb
+++ b/app/models/upload.rb
@@ -65,8 +65,8 @@ class Upload < ActiveRecord::Base
           w = svg["width"].to_i
           h = svg["height"].to_i
         else
-          # fix orientation first
-          fix_image_orientation(file.path)
+          # fix orientation first (but not for GIFs)
+          fix_image_orientation(file.path) unless filename =~ /\.GIF$/i
           # retrieve image info
           image_info = FastImage.new(file) rescue nil
           w, h = *(image_info.try(:size) || [0, 0])
@@ -80,7 +80,7 @@ class Upload < ActiveRecord::Base
 
         # crop images depending on their type
         if CROPPED_IMAGE_TYPES.include?(options[:image_type])
-          allow_animation = false
+          allow_animation = SiteSetting.allow_animated_thumbnails
           max_pixel_ratio = Discourse::PIXEL_RATIOS.max
 
           case options[:image_type]