Add automatic APNG detection (#2237)

This commit is contained in:
Type-kun
2016-09-08 00:48:39 +05:00
parent 310538dd71
commit 62773852f7
2 changed files with 85 additions and 1 deletions

View File

@@ -0,0 +1,70 @@
class APNGInspector
attr_reader :frames
PNG_MAGIC_NUMBER = ["89504E470D0A1A0A"].pack('H*')
def initialize(file_path)
@file_path = file_path
@corrupted = false
@animated = false
end
#Calls associated block for each PNG chunk
#parameters passed are |chunk_name, chunk_length, file_descriptor|
#returns true if file is read succesfully from start to IEND, false otherwise.
def each_chunk
iend_reached = false
File.open(@file_path, 'rb') do |file|
return false if file.read(8) != PNG_MAGIC_NUMBER
while chunkheader = file.read(8)
return false if chunkheader.to_s.length != 8
chunk_len, chunk_name = chunkheader.unpack("Na4")
current_pos = file.tell
yield chunk_name, chunk_len, file
if chunk_name == "IEND"
iend_reached = true
break
end
file.seek(current_pos+chunk_len+4, IO::SEEK_SET)
end
end
return iend_reached
end
def inspect!
actl_corrupted = false
read_success = each_chunk do |name, len, file|
if name == 'acTL'
if len != 8 then
actl_corrupted = true
else
framedata = file.read(4)
if framedata.to_s.length != 4
actl_corrupted = true
else
framecount = framedata.unpack("N")[0]
if framecount < 1
actl_corrupted = true
else
@animated = true
@frames = framecount
end
end
end
end
end
@corrupted = !read_success || actl_corrupted
return !@corrupted
end
def corrupted?
@corrupted
end
def animated?
!@corrupted && @animated && @frames > 1
end
end

View File

@@ -163,6 +163,16 @@ class Post < ActiveRecord::Base
return false
end
end
def is_animated_png?
if file_ext =~ /png/i
apng = APNGInspector.new(file_path)
apng.inspect!
return apng.animated?
else
return false
end
end
def is_flash?
file_ext =~ /swf/i
@@ -607,7 +617,7 @@ class Post < ActiveRecord::Base
def add_automatic_tags(tags)
return tags if !Danbooru.config.enable_dimension_autotagging
tags -= %w(incredibly_absurdres absurdres highres lowres huge_filesize animated_gif flash webm mp4)
tags -= %w(incredibly_absurdres absurdres highres lowres huge_filesize animated_gif animated_png flash webm mp4)
if has_dimensions?
if image_width >= 10_000 || image_height >= 10_000
@@ -639,6 +649,10 @@ class Post < ActiveRecord::Base
if is_animated_gif?
tags << "animated_gif"
end
if is_animated_png?
tags << "animated_png"
end
if is_flash?
tags << "flash"