Allow processing still images into animation formats

This commit is contained in:
asonix 2023-09-24 13:20:33 -05:00
parent f3ef2d870b
commit fd965bb1a5
4 changed files with 16 additions and 27 deletions

View file

@ -107,9 +107,6 @@ pub(crate) enum UploadError {
#[error("pict-rs is in read-only mode")] #[error("pict-rs is in read-only mode")]
ReadOnly, ReadOnly,
#[error("Requested file extension cannot be served by source file")]
InvalidProcessExtension,
#[error("Provided process path is invalid")] #[error("Provided process path is invalid")]
ParsePath, ParsePath,
@ -173,7 +170,6 @@ impl UploadError {
} }
Self::Download(_) => ErrorCode::DOWNLOAD_FILE_ERROR, Self::Download(_) => ErrorCode::DOWNLOAD_FILE_ERROR,
Self::ReadOnly => ErrorCode::READ_ONLY, Self::ReadOnly => ErrorCode::READ_ONLY,
Self::InvalidProcessExtension => ErrorCode::INVALID_FILE_EXTENSION,
Self::ParsePath => ErrorCode::INVALID_PROCESS_PATH, Self::ParsePath => ErrorCode::INVALID_PROCESS_PATH,
Self::Semaphore => ErrorCode::PROCESS_SEMAPHORE_CLOSED, Self::Semaphore => ErrorCode::PROCESS_SEMAPHORE_CLOSED,
Self::Canceled => ErrorCode::PANIC, Self::Canceled => ErrorCode::PANIC,
@ -235,7 +231,6 @@ impl ResponseError for Error {
| UploadError::Repo(crate::repo::RepoError::AlreadyClaimed) | UploadError::Repo(crate::repo::RepoError::AlreadyClaimed)
| UploadError::Validation(_) | UploadError::Validation(_)
| UploadError::UnsupportedProcessExtension | UploadError::UnsupportedProcessExtension
| UploadError::InvalidProcessExtension
| UploadError::ReadOnly | UploadError::ReadOnly
| UploadError::FailedExternalValidation, | UploadError::FailedExternalValidation,
) => StatusCode::BAD_REQUEST, ) => StatusCode::BAD_REQUEST,

View file

@ -166,33 +166,31 @@ impl ProcessableFormat {
} }
} }
pub(crate) const fn process_to(self, output: InputProcessableFormat) -> Option<Self> { pub(crate) const fn process_to(self, output: InputProcessableFormat) -> Self {
match (self, output) { match (self, output) {
(Self::Image(_), InputProcessableFormat::Avif) => Some(Self::Image(ImageFormat::Avif)), (Self::Image(_), InputProcessableFormat::Avif) => Self::Image(ImageFormat::Avif),
(Self::Image(_) | Self::Animation(_), InputProcessableFormat::Jpeg) => { (Self::Image(_) | Self::Animation(_), InputProcessableFormat::Jpeg) => {
Some(Self::Image(ImageFormat::Jpeg)) Self::Image(ImageFormat::Jpeg)
} }
(Self::Image(_) | Self::Animation(_), InputProcessableFormat::Jxl) => { (Self::Image(_) | Self::Animation(_), InputProcessableFormat::Jxl) => {
Some(Self::Image(ImageFormat::Jxl)) Self::Image(ImageFormat::Jxl)
} }
(Self::Image(_) | Self::Animation(_), InputProcessableFormat::Png) => { (Self::Image(_) | Self::Animation(_), InputProcessableFormat::Png) => {
Some(Self::Image(ImageFormat::Png)) Self::Image(ImageFormat::Png)
} }
(Self::Image(_), InputProcessableFormat::Webp) => Some(Self::Image(ImageFormat::Webp)), (Self::Image(_), InputProcessableFormat::Webp) => Self::Image(ImageFormat::Webp),
(Self::Animation(_), InputProcessableFormat::Apng) => { (Self::Animation(_) | Self::Image(_), InputProcessableFormat::Apng) => {
Some(Self::Animation(AnimationFormat::Apng)) Self::Animation(AnimationFormat::Apng)
} }
(Self::Animation(_), InputProcessableFormat::Avif) => { (Self::Animation(_), InputProcessableFormat::Avif) => {
Some(Self::Animation(AnimationFormat::Avif)) Self::Animation(AnimationFormat::Avif)
} }
(Self::Animation(_), InputProcessableFormat::Gif) => { (Self::Animation(_) | Self::Image(_), InputProcessableFormat::Gif) => {
Some(Self::Animation(AnimationFormat::Gif)) Self::Animation(AnimationFormat::Gif)
} }
(Self::Animation(_), InputProcessableFormat::Webp) => { (Self::Animation(_), InputProcessableFormat::Webp) => {
Some(Self::Animation(AnimationFormat::Webp)) Self::Animation(AnimationFormat::Webp)
} }
(Self::Image(_), InputProcessableFormat::Apng) => None,
(Self::Image(_), InputProcessableFormat::Gif) => None,
} }
} }

View file

@ -111,9 +111,7 @@ async fn process<S: Store + 'static>(
.processable_format() .processable_format()
.expect("Already verified format is processable"); .expect("Already verified format is processable");
let format = input_format let format = input_format.process_to(output_format);
.process_to(output_format)
.ok_or(UploadError::InvalidProcessExtension)?;
let quality = match format { let quality = match format {
ProcessableFormat::Image(format) => media.image.quality_for(format), ProcessableFormat::Image(format) => media.image.quality_for(format),
@ -178,9 +176,7 @@ where
{ {
let should_thumbnail = let should_thumbnail =
if let Some(input_format) = original_details.internal_format().processable_format() { if let Some(input_format) = original_details.internal_format().processable_format() {
let output_format = input_format let output_format = input_format.process_to(output_format);
.process_to(output_format)
.ok_or(UploadError::InvalidProcessExtension)?;
input_format.should_thumbnail(output_format) input_format.should_thumbnail(output_format)
} else { } else {

View file

@ -118,14 +118,14 @@ where
let quality = quality.map(|q| q.to_string()); let quality = quality.map(|q| q.to_string());
let len = 3 let len = 3
+ if format.coalesce() { 1 } else { 0 } + if input_format.coalesce() { 1 } else { 0 }
+ if quality.is_some() { 1 } else { 0 } + if quality.is_some() { 1 } else { 0 }
+ process_args.len(); + process_args.len();
let mut args: Vec<&str> = Vec::with_capacity(len); let mut args: Vec<&str> = Vec::with_capacity(len);
args.push("convert"); args.push("convert");
args.push(&input_arg); args.push(&input_arg);
if format.coalesce() { if input_format.coalesce() {
args.push("-coalesce"); args.push("-coalesce");
} }
args.extend(process_args.iter().map(|s| s.as_str())); args.extend(process_args.iter().map(|s| s.as_str()));