From 367cc9e1ac6cdfd7f5c8c09eb6b3010a4b6e932e Mon Sep 17 00:00:00 2001
From: Stephen <webmaster@scd31.com>
Date: Sun, 23 Apr 2023 21:16:02 -0300
Subject: [PATCH] better image resizing logic

---
 src/img.rs | 36 +++++++++++++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/src/img.rs b/src/img.rs
index 16efd83..bada3c3 100644
--- a/src/img.rs
+++ b/src/img.rs
@@ -1,5 +1,5 @@
 use image::{imageops::FilterType, io::Reader as ImageReader, ImageOutputFormat};
-use std::{fs, io::Cursor, path::PathBuf, sync::mpsc::Receiver};
+use std::{cmp::max, fs, io::Cursor, path::PathBuf, sync::mpsc::Receiver};
 
 const IMG_DIM: u32 = 1024;
 const IMG_MAX_SIZE: u32 = 2048;
@@ -20,8 +20,13 @@ impl ImgInfo {
 
         // want a imagine that's 512 on one side
         // resize so that the larger dimension is 512
-        // TODO make this better. needs to be smaller than IMG_DIM but still % 16 on both sides
-        let img = img.resize(IMG_DIM, IMG_DIM, FilterType::Triangle);
+        let (mut w, mut h) = resize_dimensions(img.width(), img.height(), IMG_DIM, IMG_DIM, false);
+
+        // make both dimensions divisible by 16 (SSDV requirement)
+        w -= w % 16;
+        h -= h % 16;
+
+        let img = img.resize_exact(w, h, FilterType::Triangle);
 
         let mut bytes = vec![];
 
@@ -210,3 +215,28 @@ impl ImgManager {
         Ok(())
     }
 }
+
+// shamelessly stolen from the image crate
+fn resize_dimensions(width: u32, height: u32, nwidth: u32, nheight: u32, fill: bool) -> (u32, u32) {
+    let wratio = nwidth as f64 / width as f64;
+    let hratio = nheight as f64 / height as f64;
+
+    let ratio = if fill {
+        f64::max(wratio, hratio)
+    } else {
+        f64::min(wratio, hratio)
+    };
+
+    let nw = max((width as f64 * ratio).round() as u64, 1);
+    let nh = max((height as f64 * ratio).round() as u64, 1);
+
+    if nw > u64::from(u32::MAX) {
+        let ratio = u32::MAX as f64 / width as f64;
+        (u32::MAX, max((height as f64 * ratio).round() as u32, 1))
+    } else if nh > u64::from(u32::MAX) {
+        let ratio = u32::MAX as f64 / height as f64;
+        (max((width as f64 * ratio).round() as u32, 1), u32::MAX)
+    } else {
+        (nw as u32, nh as u32)
+    }
+}
-- 
GitLab