Skip to content

Commit 13efe75

Browse files
committed
feat: Don't scale down huge non-JPEGs, recode them first (#7977)
If after recoding to JPEG an image isn't huge anymore, don't scale it down, this preserves quality of most screenshots. For JPEGs however we don't try to recode them w/o scaling down: - They are already JPEG-encoded, maybe with higher quality, but anyway. - We don't want extra CPU work for most photos.
1 parent 01b2aa0 commit 13efe75

4 files changed

Lines changed: 34 additions & 3 deletions

File tree

src/blob.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,17 @@ impl<'a> BlobObject<'a> {
419419
// also `Viewtype::Gif` (maybe renamed to `Animation`) should be used for animated
420420
// images.
421421
let do_scale = exceeds_max_bytes
422+
// Don't recode huge JPEGs w/o resizing:
423+
// - It may be huge because of high JPEG quality, but we don't know that.
424+
// - We don't want extra CPU work for most photos.
425+
&& (fmt == ImageFormat::Jpeg
426+
|| encoded_img_exceeds_bytes(
427+
context,
428+
&img,
429+
ofmt.clone(),
430+
max_bytes,
431+
&mut encoded,
432+
)?)
422433
|| is_avatar
423434
&& (exceeds_wh
424435
|| exif.is_some() && {
@@ -480,8 +491,7 @@ impl<'a> BlobObject<'a> {
480491
}
481492
}
482493
}
483-
484-
if do_scale || exif.is_some() {
494+
if !encoded.is_empty() || exif.is_some() {
485495
// The file format is JPEG/PNG now, we may have to change the file extension
486496
if !matches!(fmt, ImageFormat::Jpeg)
487497
&& matches!(ofmt, ImageOutputFormat::Jpeg { .. })

src/blob/blob_tests.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,26 @@ async fn test_recode_image_balanced_png() {
440440
.unwrap();
441441
}
442442

443+
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
444+
async fn test_recode_image_balanced_png_huge() {
445+
let bytes = include_bytes!("../../test-data/image/screenshot-huge.png");
446+
447+
SendImageCheckMediaquality {
448+
viewtype: Viewtype::Image,
449+
media_quality_config: "0",
450+
bytes,
451+
extension: "jpg",
452+
original_width: 1618,
453+
original_height: 949,
454+
compressed_width: 1618,
455+
compressed_height: 949,
456+
..Default::default()
457+
}
458+
.test()
459+
.await
460+
.unwrap();
461+
}
462+
443463
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
444464
async fn test_sticker_with_exif() {
445465
let bytes = include_bytes!("../../test-data/image/logo-exif.png");

src/tests/pre_messages/additional_text.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ async fn test_additional_text_on_different_viewtypes() -> Result<()> {
3434
let (pre_message, _, _) = send_large_image_message(alice, a_group_id).await?;
3535
let msg = bob.recv_msg(&pre_message).await;
3636
assert_eq!(msg.text, "test".to_owned());
37-
assert_eq!(msg.get_text(), "test [Image – 146.12 KiB]".to_owned());
37+
assert!(msg.get_text().starts_with("test [Image – "));
38+
assert!(msg.get_text().ends_with(" KiB]"));
3839

3940
Ok(())
4041
}
792 KB
Loading

0 commit comments

Comments
 (0)