pict-rs/src/validate/magick.rs

107 lines
2.5 KiB
Rust
Raw Normal View History

use std::ffi::OsStr;
use actix_web::web::Bytes;
use crate::{
formats::{AnimationFormat, ImageFormat},
magick::{MagickError, MAGICK_TEMPORARY_PATH},
process::{Process, ProcessRead},
2023-12-23 02:54:02 +00:00
tmp_file::TmpDir,
};
pub(super) async fn convert_image(
tmp_dir: &TmpDir,
input: ImageFormat,
output: ImageFormat,
quality: Option<u8>,
2023-08-05 17:41:06 +00:00
timeout: u64,
bytes: Bytes,
) -> Result<ProcessRead, MagickError> {
convert(
tmp_dir,
input.magick_format(),
output.magick_format(),
false,
quality,
2023-08-05 17:41:06 +00:00
timeout,
bytes,
)
.await
}
pub(super) async fn convert_animation(
tmp_dir: &TmpDir,
input: AnimationFormat,
output: AnimationFormat,
quality: Option<u8>,
2023-08-05 17:41:06 +00:00
timeout: u64,
bytes: Bytes,
) -> Result<ProcessRead, MagickError> {
convert(
tmp_dir,
input.magick_format(),
output.magick_format(),
true,
quality,
2023-08-05 17:41:06 +00:00
timeout,
bytes,
)
.await
}
2023-07-13 22:42:21 +00:00
async fn convert(
tmp_dir: &TmpDir,
input: &'static str,
output: &'static str,
coalesce: bool,
quality: Option<u8>,
2023-08-05 17:41:06 +00:00
timeout: u64,
bytes: Bytes,
) -> Result<ProcessRead, MagickError> {
let temporary_path = tmp_dir
.tmp_folder()
.await
.map_err(MagickError::CreateTemporaryDirectory)?;
let input_file = tmp_dir.tmp_file(None);
crate::store::file_store::safe_create_parent(&input_file)
.await
.map_err(MagickError::CreateDir)?;
let mut tmp_one = crate::file::File::create(&input_file)
.await
.map_err(MagickError::CreateFile)?;
tmp_one
.write_from_bytes(bytes)
.await
.map_err(MagickError::Write)?;
tmp_one.close().await.map_err(MagickError::CloseFile)?;
let input_arg = [input.as_ref(), input_file.as_os_str()].join(":".as_ref());
let output_arg = format!("{output}:-");
let quality = quality.map(|q| q.to_string());
let mut args: Vec<&OsStr> = vec!["convert".as_ref()];
if coalesce {
args.push("-coalesce".as_ref());
}
args.extend(["-strip".as_ref(), "-auto-orient".as_ref(), &input_arg] as [&OsStr; 3]);
if let Some(quality) = &quality {
args.extend(["-quality".as_ref(), quality.as_ref()] as [&OsStr; 2]);
}
args.push(output_arg.as_ref());
let envs = [(MAGICK_TEMPORARY_PATH, temporary_path.as_os_str())];
let reader = Process::run("magick", &args, &envs, timeout)?.read();
2023-07-13 22:42:21 +00:00
let clean_reader = reader.add_extras(input_file).add_extras(temporary_path);
2023-07-13 22:42:21 +00:00
Ok(clean_reader)
2023-07-13 22:42:21 +00:00
}