diff --git a/src/blob.rs b/src/blob.rs index dcc157ada6..886f295ae2 100644 --- a/src/blob.rs +++ b/src/blob.rs @@ -1330,6 +1330,42 @@ mod tests { Ok(img) } + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_send_big_gif_as_image() -> Result<()> { + let bytes = include_bytes!("../test-data/image/screenshot.gif"); + let (width, height) = (1920u32, 1080u32); + let alice = TestContext::new_alice().await; + let bob = TestContext::new_bob().await; + alice + .set_config( + Config::MediaQuality, + Some(&(MediaQuality::Worse as i32).to_string()), + ) + .await?; + let file = alice.get_blobdir().join("file").with_extension("gif"); + fs::write(&file, &bytes) + .await + .context("failed to write file")?; + let mut msg = Message::new(Viewtype::Image); + msg.set_file(file.to_str().unwrap(), None); + let chat = alice.create_chat(&bob).await; + let sent = alice.send_msg(chat.id, &mut msg).await; + let bob_msg = bob.recv_msg(&sent).await; + // DC must detect the image as GIF and send it w/o reencoding. + assert_eq!(bob_msg.get_viewtype(), Viewtype::Gif); + assert_eq!(bob_msg.get_width() as u32, width); + assert_eq!(bob_msg.get_height() as u32, height); + let file_saved = bob + .get_blobdir() + .join("saved-".to_string() + &bob_msg.get_filename().unwrap()); + bob_msg.save_file(&bob, &file_saved).await?; + let blob = BlobObject::new_from_path(&bob, &file_saved).await?; + let (file_size, _) = blob.metadata()?; + assert_eq!(file_size, bytes.len() as u64); + check_image_size(file_saved, width, height); + Ok(()) + } + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_increation_in_blobdir() -> Result<()> { let t = TestContext::new_alice().await; diff --git a/src/chat.rs b/src/chat.rs index 3af6f94c03..f7ef21be6e 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -2505,27 +2505,6 @@ async fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<()> { .await? .with_context(|| format!("attachment missing for message of type #{}", msg.viewtype))?; - let mut maybe_sticker = msg.viewtype == Viewtype::Sticker; - if msg.viewtype == Viewtype::Image - || maybe_sticker && !msg.param.exists(Param::ForceSticker) - { - blob.recode_to_image_size(context, &mut maybe_sticker) - .await?; - - if !maybe_sticker { - msg.viewtype = Viewtype::Image; - } - } - msg.param.set(Param::File, blob.as_name()); - if let (Some(filename), Some(blob_ext)) = (msg.param.get(Param::Filename), blob.suffix()) { - let stem = match filename.rsplit_once('.') { - Some((stem, _)) => stem, - None => filename, - }; - msg.param - .set(Param::Filename, stem.to_string() + "." + blob_ext); - } - if msg.viewtype == Viewtype::File || msg.viewtype == Viewtype::Image { // Correct the type, take care not to correct already very special // formats as GIF or VOICE. @@ -2533,8 +2512,7 @@ async fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<()> { // Typical conversions: // - from FILE to AUDIO/VIDEO/IMAGE // - from FILE/IMAGE to GIF */ - if let Some((better_type, better_mime)) = - message::guess_msgtype_from_suffix(&blob.to_abs_path()) + if let Some((better_type, _)) = message::guess_msgtype_from_suffix(&blob.to_abs_path()) { if better_type != Viewtype::Webxdc || context @@ -2543,9 +2521,6 @@ async fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<()> { .is_ok() { msg.viewtype = better_type; - if !msg.param.exists(Param::MimeType) { - msg.param.set(Param::MimeType, better_mime); - } } } } else if msg.viewtype == Viewtype::Webxdc { @@ -2554,6 +2529,27 @@ async fn prepare_msg_blob(context: &Context, msg: &mut Message) -> Result<()> { .await?; } + let mut maybe_sticker = msg.viewtype == Viewtype::Sticker; + if msg.viewtype == Viewtype::Image + || maybe_sticker && !msg.param.exists(Param::ForceSticker) + { + blob.recode_to_image_size(context, &mut maybe_sticker) + .await?; + + if !maybe_sticker { + msg.viewtype = Viewtype::Image; + } + } + msg.param.set(Param::File, blob.as_name()); + if let (Some(filename), Some(blob_ext)) = (msg.param.get(Param::Filename), blob.suffix()) { + let stem = match filename.rsplit_once('.') { + Some((stem, _)) => stem, + None => filename, + }; + msg.param + .set(Param::Filename, stem.to_string() + "." + blob_ext); + } + if !msg.param.exists(Param::MimeType) { if let Some((_, mime)) = message::guess_msgtype_from_suffix(&blob.to_abs_path()) { msg.param.set(Param::MimeType, mime); diff --git a/test-data/image/screenshot.gif b/test-data/image/screenshot.gif new file mode 100644 index 0000000000..57221835a0 Binary files /dev/null and b/test-data/image/screenshot.gif differ