diff --git a/src/blob.rs b/src/blob.rs index 27c44f3e31..5e422e947c 100644 --- a/src/blob.rs +++ b/src/blob.rs @@ -419,6 +419,17 @@ impl<'a> BlobObject<'a> { // also `Viewtype::Gif` (maybe renamed to `Animation`) should be used for animated // images. let do_scale = exceeds_max_bytes + // Don't recode huge JPEGs w/o resizing: + // - It may be huge because of high JPEG quality, but we don't know that. + // - We don't want extra CPU work for most photos. + && (fmt == ImageFormat::Jpeg + || encoded_img_exceeds_bytes( + context, + &img, + ofmt.clone(), + max_bytes, + &mut encoded, + )?) || is_avatar && (exceeds_wh || exif.is_some() && { @@ -480,8 +491,7 @@ impl<'a> BlobObject<'a> { } } } - - if do_scale || exif.is_some() { + if !encoded.is_empty() || exif.is_some() { // The file format is JPEG/PNG now, we may have to change the file extension if !matches!(fmt, ImageFormat::Jpeg) && matches!(ofmt, ImageOutputFormat::Jpeg { .. }) diff --git a/src/blob/blob_tests.rs b/src/blob/blob_tests.rs index ed5a2b0017..3933a59e4f 100644 --- a/src/blob/blob_tests.rs +++ b/src/blob/blob_tests.rs @@ -440,6 +440,26 @@ async fn test_recode_image_balanced_png() { .unwrap(); } +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_recode_image_balanced_png_huge() { + let bytes = include_bytes!("../../test-data/image/screenshot-huge.png"); + + SendImageCheckMediaquality { + viewtype: Viewtype::Image, + media_quality_config: "0", + bytes, + extension: "jpg", + original_width: 1618, + original_height: 949, + compressed_width: 1618, + compressed_height: 949, + ..Default::default() + } + .test() + .await + .unwrap(); +} + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_sticker_with_exif() { let bytes = include_bytes!("../../test-data/image/logo-exif.png"); diff --git a/src/tests/pre_messages/additional_text.rs b/src/tests/pre_messages/additional_text.rs index 0af33ec8c6..d27291fd3f 100644 --- a/src/tests/pre_messages/additional_text.rs +++ b/src/tests/pre_messages/additional_text.rs @@ -34,7 +34,8 @@ async fn test_additional_text_on_different_viewtypes() -> Result<()> { let (pre_message, _, _) = send_large_image_message(alice, a_group_id).await?; let msg = bob.recv_msg(&pre_message).await; assert_eq!(msg.text, "test".to_owned()); - assert_eq!(msg.get_text(), "test [Image – 146.12 KiB]".to_owned()); + assert!(msg.get_text().starts_with("test [Image – ")); + assert!(msg.get_text().ends_with(" KiB]")); Ok(()) } diff --git a/src/tests/pre_messages/receiving.rs b/src/tests/pre_messages/receiving.rs index 1926bbd07d..b5fa437a85 100644 --- a/src/tests/pre_messages/receiving.rs +++ b/src/tests/pre_messages/receiving.rs @@ -4,6 +4,7 @@ use pretty_assertions::assert_eq; use crate::EventType; use crate::chat; +use crate::constants; use crate::contact; use crate::download::{DownloadState, PRE_MSG_ATTACHMENT_SIZE_THRESHOLD, PostMsgMetadata}; use crate::message::{Message, MessageState, Viewtype, delete_msgs, markseen_msgs}; @@ -393,9 +394,11 @@ async fn test_receive_pre_message_image() -> Result<()> { // test that metadata is correctly returned by methods assert_eq!(msg.get_post_message_viewtype(), Some(Viewtype::Image)); // recoded image dimensions - assert_eq!(msg.get_filebytes(bob).await?, Some(149632)); - assert_eq!(msg.get_height(), 1280); - assert_eq!(msg.get_width(), 720); + let n_bytes: usize = msg.get_filebytes(bob).await?.unwrap().try_into().unwrap(); + assert!(100_000 < n_bytes); + assert!(n_bytes <= constants::BALANCED_IMAGE_BYTES); + assert_eq!(msg.get_height(), 1920); + assert_eq!(msg.get_width(), 1080); Ok(()) } diff --git a/test-data/image/screenshot-huge.png b/test-data/image/screenshot-huge.png new file mode 100644 index 0000000000..4b83ad994e Binary files /dev/null and b/test-data/image/screenshot-huge.png differ