This commit is contained in:
Albert Yi
2018-10-17 15:37:26 -07:00
parent 6148cb39a2
commit 12b88f7f97
4 changed files with 70 additions and 12 deletions

View File

@@ -1,4 +1,6 @@
module DanbooruImageResizer
extend self
# Taken from ArgyllCMS 2.0.0 (see also: https://ninedegreesbelow.com/photography/srgb-profile-comparison.html)
SRGB_PROFILE = "#{Rails.root}/config/sRGB.icm"
# http://jcupitt.github.io/libvips/API/current/libvips-resample.html#vips-thumbnail
@@ -9,7 +11,7 @@ module DanbooruImageResizer
# XXX libvips-8.4 on Debian doesn't support the `Vips::Image.thumbnail` method.
# On 8.4 we have to shell out to vipsthumbnail instead. Remove when Debian supports 8.5.
def self.resize(file, width, height, quality = 90)
def resize(file, width, height, quality = 90)
if Vips.at_least_libvips?(8, 5)
resize_ruby(file, width, height, quality)
else
@@ -17,13 +19,13 @@ module DanbooruImageResizer
end
end
def self.crop(file, width, height, quality = 90)
def crop(file, width, height, quality = 90)
crop_shell(file, width, height, quality)
end
# https://github.com/jcupitt/libvips/wiki/HOWTO----Image-shrinking
# http://jcupitt.github.io/libvips/API/current/Using-vipsthumbnail.md.html
def self.resize_ruby(file, width, height, resize_quality)
def resize_ruby(file, width, height, resize_quality)
output_file = Tempfile.new
resized_image = Vips::Image.thumbnail(file.path, width, height: height, **THUMBNAIL_OPTIONS)
resized_image.jpegsave(output_file.path, Q: resize_quality, **JPEG_OPTIONS)
@@ -31,7 +33,7 @@ module DanbooruImageResizer
output_file
end
def self.crop_ruby(file, width, height, resize_quality)
def crop_ruby(file, width, height, resize_quality)
return nil unless Danbooru.config.enable_image_cropping
output_file = Tempfile.new
@@ -41,7 +43,7 @@ module DanbooruImageResizer
output_file
end
def self.resize_shell(file, width, height, quality)
def resize_shell(file, width, height, quality)
output_file = Tempfile.new(["resize", ".jpg"])
# --size=WxH will upscale if the image is smaller than the target size.
@@ -63,7 +65,7 @@ module DanbooruImageResizer
output_file
end
def self.crop_shell(file, width, height, quality)
def crop_shell(file, width, height, quality)
return nil unless Danbooru.config.enable_image_cropping
output_file = Tempfile.new(["crop", ".jpg"])
@@ -85,4 +87,20 @@ module DanbooruImageResizer
output_file
end
def validate_shell(file)
temp = Tempfile.new("validate")
output, status = Open3.capture2e("vips stats #{file.path} #{temp.path}.v")
# png | jpeg | gif
if output =~ /Read Error|Premature end of JPEG file|Failed to read from given file/m
return false
end
return true
ensure
temp.close
temp.unlink
end
end

View File

@@ -1,6 +1,7 @@
class UploadService
module Utils
extend self
class CorruptFileError < RuntimeError; end
def file_header_to_file_ext(file)
case File.read(file.path, 16)
@@ -23,9 +24,9 @@ class UploadService
end
end
def delete_file(md5, file_ext, upload_id = nil)
def delete_file(md5, file_ext, upload_id = nil)
if Post.where(md5: md5).exists?
if upload_id
if upload_id.present? && Upload.where(id: upload_id).exists?
CurrentUser.as_system do
Upload.find(upload_id).update(status: "completed")
end
@@ -34,7 +35,7 @@ class UploadService
return
end
if upload_id && Upload.where(id: upload_id).exists?
if upload_id.present? && Upload.where(id: upload_id).exists?
CurrentUser.as_system do
Upload.find(upload_id).update(status: "preprocessed + deleted")
end
@@ -206,8 +207,24 @@ class UploadService
end
def download_for_upload(upload)
download = Downloads::File.new(upload.source, upload.referer_url)
file, strategy = download.download!
attempts = 0
begin
download = Downloads::File.new(upload.source, upload.referer_url)
file, strategy = download.download!
if !DanbooruImageResizer.validate_shell(file)
raise CorruptFileError.new("File is corrupted")
end
rescue
if attempts == 3
raise
end
attempts += 1
retry
end
if download.data[:ugoira_frame_data]
upload.context = {