media assets: fix dimensions of corrupt GIFs.
Fix certain corrupt GIFs returning dimensions of 0x0. This happened when the GIF was too corrupt for libvips to read. Fixed by using ExifTool to read the dimensions instead. Also add validations to ensure that it's not possible to have media assets with a width or height of 0.
This commit is contained in:
@@ -120,6 +120,14 @@ class ExifTool
|
||||
metadata.has_key?("PNG:Dream")
|
||||
end
|
||||
|
||||
def width
|
||||
metadata.find { |name, value| name.match?(/\A(File|PNG|GIF|RIFF|Flash|Track\d+):ImageWidth\z/) }&.second
|
||||
end
|
||||
|
||||
def height
|
||||
metadata.find { |name, value| name.match?(/\A(File|PNG|GIF|RIFF|Flash|Track\d+):ImageHeight\z/) }&.second
|
||||
end
|
||||
|
||||
# @see http://www.vurdalakov.net/misc/gif/netscape-looping-application-extension
|
||||
# @see https://wiki.mozilla.org/APNG_Specification#.60acTL.60:_The_Animation_Control_Chunk
|
||||
# @see https://danbooru.donmai.us/posts?tags=-exif:GIF:AnimationIterations=Infinite+animated_gif
|
||||
|
||||
@@ -10,6 +10,8 @@ class MediaFile::Image < MediaFile
|
||||
def dimensions
|
||||
image.size
|
||||
rescue Vips::Error
|
||||
[metadata.width, metadata.height]
|
||||
rescue
|
||||
[0, 0]
|
||||
end
|
||||
|
||||
|
||||
@@ -45,6 +45,9 @@ class MediaAsset < ApplicationRecord
|
||||
validates :md5, uniqueness: { conditions: -> { where(status: [:processing, :active]) } }, if: :md5_changed?
|
||||
validates :file_ext, inclusion: { in: FILE_TYPES, message: "File is not an image or video" }
|
||||
validates :file_key, length: { is: FILE_KEY_LENGTH }, uniqueness: true, if: :file_key_changed?
|
||||
validates :file_size, comparison: { greater_than: 0 }, if: :file_size_changed?
|
||||
validates :image_width, comparison: { greater_than: 0 }, if: :image_width_changed?
|
||||
validates :image_height, comparison: { greater_than: 0 }, if: :image_height_changed?
|
||||
|
||||
before_create :initialize_file_key
|
||||
|
||||
|
||||
@@ -467,6 +467,7 @@ class MediaFileTest < ActiveSupport::TestCase
|
||||
@metadata = @file.metadata
|
||||
|
||||
assert_equal(true, @file.is_corrupt?)
|
||||
assert_equal([475, 600], @file.dimensions)
|
||||
assert_equal("File format error", @metadata["ExifTool:Error"])
|
||||
assert_equal("89a", @metadata["GIF:GIFVersion"])
|
||||
assert_equal(9, @metadata.count)
|
||||
@@ -478,6 +479,7 @@ class MediaFileTest < ActiveSupport::TestCase
|
||||
|
||||
assert_equal(true, @file.is_corrupt?)
|
||||
assert_equal(nil, @file.frame_count)
|
||||
assert_equal([575, 800], @file.dimensions)
|
||||
assert_equal("File format error", @metadata["ExifTool:Error"])
|
||||
assert_equal("89a", @metadata["GIF:GIFVersion"])
|
||||
assert_equal(9, @metadata.count)
|
||||
|
||||
Reference in New Issue
Block a user