From 8978c9c0b314e24b2305060eebf9a03d899715b6 Mon Sep 17 00:00:00 2001 From: Spaceface16518 Date: Thu, 21 Jan 2021 21:09:44 -0600 Subject: [PATCH 1/7] Abstract over quantization function in encode_ac --- src/lib.rs | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 22a8eed..3335d37 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -307,30 +307,15 @@ fn encode_dc(value: [f64; 3]) -> usize { ((rounded_r << 16) + (rounded_g << 8) + rounded_b) as usize } -fn encode_ac(value: [f64; 3], maximum_value: f64) -> usize { - let quant_r = f64::floor(f64::max( - 0f64, - f64::min( - 18f64, - f64::floor(sign_pow(value[0] / maximum_value, 0.5) * 9f64 + 9.5), - ), - )); - let quant_g = f64::floor(f64::max( - 0f64, - f64::min( - 18f64, - f64::floor(sign_pow(value[1] / maximum_value, 0.5) * 9f64 + 9.5), - ), - )); - let quant_b = f64::floor(f64::max( - 0f64, - f64::min( - 18f64, - f64::floor(sign_pow(value[2] / maximum_value, 0.5) * 9f64 + 9.5), - ), - )); - - (quant_r * 19f64 * 19f64 + quant_g * 19f64 + quant_b) as usize +fn encode_ac([r, g, b]: [f64; 3], maximum_value: f64) -> usize { + let quant = |v| { + (sign_pow(v / maximum_value, 0.5) * 9. + 9.5) + .floor() + .min(18.) + .max(0.) + }; + + (quant(r) * 19f64 * 19f64 + quant(g) * 19f64 + quant(b)) as usize } // Base83 From 1df69905b61173536df60237dfa65980d677e637 Mon Sep 17 00:00:00 2001 From: Spaceface16518 Date: Thu, 21 Jan 2021 21:14:01 -0600 Subject: [PATCH 2/7] Abstract over rounding function in encode_dc --- src/lib.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3335d37..8f417d9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -300,11 +300,9 @@ where [r * scale, g * scale, b * scale] } -fn encode_dc(value: [f64; 3]) -> usize { - let rounded_r = linear_to_srgb(value[0]); - let rounded_g = linear_to_srgb(value[1]); - let rounded_b = linear_to_srgb(value[2]); - ((rounded_r << 16) + (rounded_g << 8) + rounded_b) as usize +fn encode_dc([r, g, b]: [f64; 3]) -> usize { + let rounded = |v| linear_to_srgb(v); + ((rounded(r) << 16) + (rounded(g) << 8) + rounded(b)) as usize } fn encode_ac([r, g, b]: [f64; 3], maximum_value: f64) -> usize { From 230cd865633a4fd3a0bf3384bc5b7baf764bebe7 Mon Sep 17 00:00:00 2001 From: Spaceface16518 Date: Thu, 21 Jan 2021 21:21:34 -0600 Subject: [PATCH 3/7] Remove redundant parenthesis --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8f417d9..65c5a14 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -203,9 +203,9 @@ pub fn encode( bytes_per_pixel, 0, |a, b| { - (normalisation + normalisation * f64::cos((PI * x as f64 * a) / width as f64) - * f64::cos((PI * y as f64 * b) / height as f64)) + * f64::cos((PI * y as f64 * b) / height as f64) }, ); From 5c0b127ce3fc2d248a0cfdf587bbd89fe4790b61 Mon Sep 17 00:00:00 2001 From: Spaceface16518 Date: Thu, 21 Jan 2021 21:34:40 -0600 Subject: [PATCH 4/7] Only allocate once when constructing hash --- src/lib.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 65c5a14..51a9c60 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -219,10 +219,10 @@ pub fn encode( } } - let mut hash = String::new(); + let mut hash = String::with_capacity(1 + 1 + 4 + 2 * ac.len()); let size_flag = ((cx - 1) + (cy - 1) * 9) as usize; - hash += &encode_base83_string(size_flag, 1); + hash.extend(encode_base83_string(size_flag, 1)); let maximum_value: f64; @@ -239,16 +239,16 @@ pub fn encode( usize::min(82, f64::floor(actual_maximum_value * 166f64 - 0.5) as usize), ); maximum_value = ((quantised_maximum_value + 1) as f64) / 166f64; - hash += &encode_base83_string(quantised_maximum_value, 1); + hash.extend(encode_base83_string(quantised_maximum_value, 1)); } else { maximum_value = 1f64; - hash += &encode_base83_string(0, 1); + hash.extend(encode_base83_string(0, 1)); } - hash += &encode_base83_string(encode_dc(dc), 4); + hash.extend(encode_base83_string(encode_dc(dc), 4)); for factor in ac { - hash += &encode_base83_string(encode_ac(factor, maximum_value), 2); + hash.extend(encode_base83_string(encode_ac(factor, maximum_value), 2)); } Ok(hash) @@ -335,11 +335,10 @@ fn decode_base83_string(string: &str) -> usize { .fold(0, |value, digit| value * 83 + digit) } -fn encode_base83_string(value: usize, length: u32) -> String { +fn encode_base83_string(value: usize, length: u32) -> impl Iterator { (1..=length) - .map(|i| (value / usize::pow(83, length - i)) % 83) + .map(move |i| (value / usize::pow(83, length - i)) % 83) .map(|digit| ENCODE_CHARACTERS[digit]) - .collect() } #[cfg(test)] From 00558a301af81b1b7fc0fdf76b882c4b1363116e Mon Sep 17 00:00:00 2001 From: Spaceface16518 Date: Thu, 21 Jan 2021 22:02:15 -0600 Subject: [PATCH 5/7] Use associated `pow` function Using associated methods by member access is more idiomatic. --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 51a9c60..e87e8ea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -337,7 +337,7 @@ fn decode_base83_string(string: &str) -> usize { fn encode_base83_string(value: usize, length: u32) -> impl Iterator { (1..=length) - .map(move |i| (value / usize::pow(83, length - i)) % 83) + .map(move |i| (value / 83usize.pow(length - i)) % 83) .map(|digit| ENCODE_CHARACTERS[digit]) } From 5e2586ce952e7bcac8cb813f2f4bb1bcc4253f03 Mon Sep 17 00:00:00 2001 From: Spaceface16518 Date: Fri, 22 Jan 2021 11:55:58 -0600 Subject: [PATCH 6/7] Format code --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index e87e8ea..b15b4ed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -335,7 +335,7 @@ fn decode_base83_string(string: &str) -> usize { .fold(0, |value, digit| value * 83 + digit) } -fn encode_base83_string(value: usize, length: u32) -> impl Iterator { +fn encode_base83_string(value: usize, length: u32) -> impl Iterator { (1..=length) .map(move |i| (value / 83usize.pow(length - i)) % 83) .map(|digit| ENCODE_CHARACTERS[digit]) From 90d464a1e94bc86e76f8842a182846c3877e5c79 Mon Sep 17 00:00:00 2001 From: Spaceface16518 Date: Fri, 22 Jan 2021 11:56:16 -0600 Subject: [PATCH 7/7] Don't clone ac vector when calculating max value --- src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b15b4ed..4c6babc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -228,11 +228,11 @@ pub fn encode( if !ac.is_empty() { // I'm sure there's a better way to write this; following the Swift atm :) + let maxf = |a: &f64, b: &f64| a.partial_cmp(b).unwrap_or(Ordering::Equal); let actual_maximum_value = ac - .clone() - .into_iter() - .map(|[a, b, c]| f64::max(f64::max(f64::abs(a), f64::abs(b)), f64::abs(c))) - .max_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)) + .iter() + .map(|channels| channels.iter().copied().map(f64::abs).max_by(maxf).unwrap()) + .max_by(maxf) .unwrap(); let quantised_maximum_value = usize::max( 0,