uploads: add support for uploading .avif files.

Features of AVIF include:

* Lossless and lossy compression.
* High dynamic range (HDR) images
* Wide color gamut images (i.e. 10- and 12-bit color depths)
* Transparency (through alpha planes).
* Animations (with an optional cover image).
* Auxiliary image sequences, where the file contains a single primary
  image and a short secondary video, like Apple's Live Photos.
* Metadata rotation, mirroring, and cropping.

The AVIF format is still relatively new and some of these features aren't well
supported by browsers or other software:

* Animated AVIFs aren't supported by Firefox or by libvips.
* HDR images aren't supported by Firefox.
* Rotated, mirrored, and cropped AVIFs aren't supported by Firefox or Chrome.
* Image grids, where the file contains multiple images that are tiled
  together into one big image, aren't supported by Firefox.
* AVIF as a whole has only been supported for a year or two by Chrome
  and Firefox, and less than a year by Safari.

For these reasons, only basic AVIFs that don't use animation, rotation,
cropping, or image grids can be uploaded.
This commit is contained in:
evazion
2022-10-24 19:10:57 -05:00
parent 420ff2f2f5
commit c96d60a840
26 changed files with 197 additions and 15 deletions

View File

@@ -3,7 +3,7 @@
class MediaAsset < ApplicationRecord
class Error < StandardError; end
FILE_TYPES = %w[jpg png gif mp4 webm swf zip]
FILE_TYPES = %w[jpg png gif avif mp4 webm swf zip]
FILE_KEY_LENGTH = 9
VARIANTS = %i[preview 180x180 360x360 720x720 sample original]
MAX_FILE_SIZE = Danbooru.config.max_file_size.to_i
@@ -273,6 +273,8 @@ class MediaAsset < ApplicationRecord
def validate_media_file!(media_file, uploader)
if !media_file.file_ext.to_s.in?(FILE_TYPES)
raise Error, "File is not an image or video"
elsif !media_file.is_supported?
raise Error, "File type is not supported"
elsif media_file.is_corrupt?
raise Error, "File is corrupt"
elsif media_file.file_size > MAX_FILE_SIZE
@@ -370,7 +372,7 @@ class MediaAsset < ApplicationRecord
concerning :FileTypeMethods do
def is_image?
file_ext.in?(%w[jpg png gif])
file_ext.in?(%w[jpg png gif avif])
end
def is_static_image?

View File

@@ -188,7 +188,7 @@ class Post < ApplicationRecord
end
def is_image?
file_ext =~ /jpg|gif|png/i
file_ext =~ /jpg|gif|png|avif/i
end
def is_flash?