diff --git a/imageflow_core/tests/visuals.rs b/imageflow_core/tests/visuals.rs index 73eba79c..c0bd7336 100644 --- a/imageflow_core/tests/visuals.rs +++ b/imageflow_core/tests/visuals.rs @@ -1068,6 +1068,25 @@ fn test_crop_with_preshrink() { } +#[test] +fn test_zoom_with_preshrink() { + + //Certain dimensions of images would trigger preshrinking and also break zoom calculation + let steps = vec![ + Node::CommandString{ + kind: CommandStringKind::ImageResizer4, + value: "zoom=0.25".to_owned(), + decode: Some(0), + encode: None, + watermarks: None + } + ]; + let (w, _h) = get_result_dimensions(&steps, vec![ IoTestEnum::Url("https://imageflow-resources.s3.us-west-2.amazonaws.com/test_inputs/5760_x_4320.jpg".to_owned())], false); + assert_eq!(w, 1440); + +} + + #[test] fn webp_lossless_alpha_decode_and_scale() { let matched = compare(Some(IoTestEnum::Url("https://imageflow-resources.s3-us-west-2.amazonaws.com/test_inputs/1_webp_ll.webp".to_owned())), 500, diff --git a/imageflow_riapi/src/ir4/layout.rs b/imageflow_riapi/src/ir4/layout.rs index 668382bf..4f9a365d 100644 --- a/imageflow_riapi/src/ir4/layout.rs +++ b/imageflow_riapi/src/ir4/layout.rs @@ -9,7 +9,9 @@ use imageflow_types::{ConstraintMode, ConstraintGravity, WatermarkConstraintBox, pub struct Ir4Layout{ i: Instructions, + /// The actual, not-pre-shrunk image width. May differ from the bitmap size during IDCT scaling reference_width: i32, + /// The actual, not-pre-shrunk image height. May differ from the bitmap size during IDCT scaling reference_height: i32, /// source width w: i32, @@ -40,6 +42,11 @@ impl Ir4Layout{ } + fn get_preshrink_ratio(&self) ->f64{ + return f64::from(self.w) / f64::from(self.reference_width) + } + + fn get_precrop(&self) -> (i32,i32){ if((self.i.srotate.unwrap_or(0) / 90 + 4) % 2) == 0 { @@ -82,12 +89,16 @@ impl Ir4Layout{ Ok((if w < 1 { None } else { Some(w) }, if h < 1 { None } else { Some(h)})) } - fn get_ideal_target_size(&self, source: AspectRatio) -> sizing::Result{ + fn get_ideal_target_size(&self, source: AspectRatio, preshrink_ratio: f64) -> sizing::Result{ + // When no w/h is specified, we should apply zoom relative to the original image dimensions. + let unshrunk_w = (f64::from(source.w) / preshrink_ratio) as i32; + let unshrunk_h = (f64::from(source.h) / preshrink_ratio) as i32; + let (w,h) = match self.get_wh_from_all(source)? { (Some(w), Some(h)) => (w,h), - (None, None) => (source.w, source.h), + (None, None) => (unshrunk_w, unshrunk_h), (Some(w), None) => (w, source.height_for(w, None)?), (None, Some(h)) => (source.width_for(h, None)?,h) }; @@ -291,7 +302,7 @@ impl Ir4Layout{ let initial_size = AspectRatio::create(source_w, source_h)?; - let target = ir_layout.get_ideal_target_size(initial_size)?; + let target = ir_layout.get_ideal_target_size(initial_size, ir_layout.get_preshrink_ratio())?; let constraints = ir_layout.build_constraints(); @@ -353,7 +364,7 @@ impl Ir4Layout{ let initial_size = sizing::AspectRatio::create(initial_crop[2] - initial_crop[0], initial_crop[3] - initial_crop[1])?; - let target = self.get_ideal_target_size(initial_size)?; + let target = self.get_ideal_target_size(initial_size, self.get_preshrink_ratio())?; let constraints = self.build_constraints(); diff --git a/imageflow_riapi/src/ir4/mod.rs b/imageflow_riapi/src/ir4/mod.rs index fcee8724..7859446d 100644 --- a/imageflow_riapi/src/ir4/mod.rs +++ b/imageflow_riapi/src/ir4/mod.rs @@ -140,7 +140,9 @@ impl Ir4SourceFrameInfo{ pub struct Ir4Expand{ pub i: Ir4Command, pub source: Ir4SourceFrameInfo, + /// The actual, not-pre-shrunk image width. May differ from the bitmap size during IDCT scaling pub reference_width: i32, + /// The actual, not-pre-shrunk image height. May differ from the bitmap size during IDCT scaling pub reference_height: i32, pub encode_id: Option, pub watermarks: Option>