mirror of
https://github.com/stoatchat/stoatchat.git
synced 2026-07-14 05:26:59 +00:00
@@ -4,7 +4,7 @@ use aes_gcm::{
|
||||
aead::{AeadCore, AeadMutInPlace, OsRng},
|
||||
Aes256Gcm, Key, KeyInit, Nonce,
|
||||
};
|
||||
use image::DynamicImage;
|
||||
use image::{DynamicImage, ImageBuffer};
|
||||
use revolt_config::{config, report_internal_error, FilesS3};
|
||||
use revolt_result::{create_error, Result};
|
||||
|
||||
@@ -152,38 +152,67 @@ pub fn video_size(f: &NamedTempFile) -> Option<(i64, i64)> {
|
||||
}
|
||||
|
||||
/// Decode image from reader
|
||||
pub fn decode_image<R: Read + BufRead + Seek>(
|
||||
reader: &mut R,
|
||||
is_jxl: bool,
|
||||
) -> Result<DynamicImage> {
|
||||
if is_jxl {
|
||||
Err(create_error!(LabelMe))
|
||||
} else {
|
||||
pub fn decode_image<R: Read + BufRead + Seek>(reader: &mut R, mime: &str) -> Result<DynamicImage> {
|
||||
match mime {
|
||||
// Read image using jxl-oxide crate
|
||||
"image/jxl" => {
|
||||
let jxl_image = report_internal_error!(jxl_oxide::JxlImage::builder().read(reader))?;
|
||||
if let Ok(frame) = jxl_image.render_frame(0) {
|
||||
match frame.color_channels().len() {
|
||||
3 => Ok(DynamicImage::ImageRgb8(
|
||||
DynamicImage::ImageRgb32F(
|
||||
ImageBuffer::from_vec(
|
||||
jxl_image.width(),
|
||||
jxl_image.height(),
|
||||
frame.image().buf().to_vec(),
|
||||
)
|
||||
.ok_or_else(|| create_error!(LabelMe))?,
|
||||
)
|
||||
.to_rgb8(),
|
||||
)),
|
||||
4 => Ok(DynamicImage::ImageRgba8(
|
||||
DynamicImage::ImageRgba32F(
|
||||
ImageBuffer::from_vec(
|
||||
jxl_image.width(),
|
||||
jxl_image.height(),
|
||||
frame.image().buf().to_vec(),
|
||||
)
|
||||
.ok_or_else(|| create_error!(LabelMe))?,
|
||||
)
|
||||
.to_rgba8(),
|
||||
)),
|
||||
_ => Err(create_error!(LabelMe)),
|
||||
}
|
||||
} else {
|
||||
Err(create_error!(LabelMe))
|
||||
}
|
||||
}
|
||||
// Read image using resvg
|
||||
"image/svg+xml" => Err(create_error!(LabelMe)),
|
||||
// Check if we can read using image-rs crate
|
||||
report_internal_error!(report_internal_error!(
|
||||
_ => report_internal_error!(report_internal_error!(
|
||||
image::ImageReader::new(reader).with_guessed_format()
|
||||
)?
|
||||
.decode())
|
||||
.decode()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Check whether given reader has a valid image
|
||||
pub fn is_valid_image<R: Read + BufRead + Seek>(reader: &mut R, is_jxl: bool) -> bool {
|
||||
if is_jxl {
|
||||
pub fn is_valid_image<R: Read + BufRead + Seek>(reader: &mut R, mime: &str) -> bool {
|
||||
match mime {
|
||||
// Check if we can read using jxl-oxide crate
|
||||
jxl_oxide::JxlImage::builder()
|
||||
"image/jxl" => jxl_oxide::JxlImage::builder()
|
||||
.read(reader)
|
||||
.inspect_err(|err| tracing::error!("Failed to read JXL! {err:?}"))
|
||||
.is_ok()
|
||||
} else {
|
||||
!matches!(
|
||||
// Check if we can read using image-rs crate
|
||||
.is_ok(),
|
||||
// Check if we can read using image-rs crate
|
||||
_ => !matches!(
|
||||
image::ImageReader::new(reader)
|
||||
.with_guessed_format()
|
||||
.inspect_err(|err| tracing::error!("Failed to read image! {err:?}"))
|
||||
.map(|f| f.decode()),
|
||||
Err(_) | Ok(Err(_))
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ use axum::{
|
||||
Json, Router,
|
||||
};
|
||||
use axum_typed_multipart::{FieldData, TryFromMultipart, TypedMultipart};
|
||||
use image::ImageReader;
|
||||
use lazy_static::lazy_static;
|
||||
use revolt_config::{config, report_internal_error};
|
||||
use revolt_database::{iso8601_timestamp::Timestamp, Database, FileHash, Metadata, User};
|
||||
@@ -355,7 +354,11 @@ async fn fetch_preview(
|
||||
let data = retrieve_file_by_hash(&hash).await?;
|
||||
|
||||
// Read image and create thumbnail
|
||||
let data = create_thumbnail(decode_image(&mut Cursor::new(data), false)?, tag).await;
|
||||
let data = create_thumbnail(
|
||||
decode_image(&mut Cursor::new(data), &file.content_type)?,
|
||||
tag,
|
||||
)
|
||||
.await;
|
||||
|
||||
Ok((
|
||||
[
|
||||
|
||||
@@ -71,7 +71,7 @@ impl Request {
|
||||
let reader = &mut Cursor::new(&bytes);
|
||||
|
||||
if matches!(mime.subtype(), mime::GIF) {
|
||||
if is_valid_image(reader, false) {
|
||||
if is_valid_image(reader, "image/gif") {
|
||||
Ok(("image/gif".to_owned(), bytes.to_vec()))
|
||||
} else {
|
||||
Err(create_error!(LabelMe))
|
||||
@@ -79,8 +79,11 @@ impl Request {
|
||||
} else {
|
||||
Ok((
|
||||
"image/webp".to_owned(),
|
||||
create_thumbnail(decode_image(reader, false)?, "attachments")
|
||||
.await,
|
||||
create_thumbnail(
|
||||
decode_image(reader, mime.as_ref())?,
|
||||
"attachments",
|
||||
)
|
||||
.await,
|
||||
))
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user