Skip to content

Commit ca16a5c

Browse files
committed
Use selective strategy only at the end
1 parent 4b3dd4d commit ca16a5c

File tree

1 file changed

+11
-23
lines changed

1 file changed

+11
-23
lines changed

src/mediancut.rs

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,9 @@ impl<'hist> MBox<'hist> {
3535
Self::new_inner(hist, weight_sum, weighed_average_color(hist))
3636
}
3737

38-
fn from_split(hist: &'hist mut [HistItem], adjusted_weight_sum: f64, other_boxes: &[MBox<'_>]) -> Self {
38+
fn from_split(hist: &'hist mut [HistItem], adjusted_weight_sum: f64) -> Self {
3939
debug_assert!(!hist.is_empty());
40-
let mut avg_color = weighed_average_color(hist);
41-
// It's possible that an average color will end up being bad for every entry,
42-
// so prefer picking actual colors so that at least one histogram entry will be satisfied.
43-
if (hist.len() < 500 && hist.len() > 2) || Self::is_useless_color(avg_color, hist, other_boxes) {
44-
avg_color = hist.iter().min_by_key(|a| OrdFloat::new(avg_color.diff(&a.color))).map(|a| a.color).unwrap_or_default();
45-
}
40+
let avg_color = weighed_average_color(hist);
4641
Self::new_inner(hist, adjusted_weight_sum, avg_color)
4742
}
4843

@@ -58,17 +53,6 @@ impl<'hist> MBox<'hist> {
5853
}
5954
}
6055

61-
/// It's possible that the average color is useless
62-
fn is_useless_color(new_avg_color: f_pixel, colors: &[HistItem], other_boxes: &[MBox<'_>]) -> bool {
63-
colors.iter().all(move |c| {
64-
let own_box_diff = new_avg_color.diff(&c.color);
65-
let other_box_is_better = other_boxes.iter()
66-
.any(move |other| other.avg_color.diff(&c.color) < own_box_diff);
67-
68-
other_box_is_better
69-
})
70-
}
71-
7256
fn box_stats(hist: &[HistItem], avg_color: f_pixel) -> (ARGBF, f32) {
7357
let mut variance = ARGBF::default();
7458
let mut max_error = 0.;
@@ -132,7 +116,7 @@ impl<'hist> MBox<'hist> {
132116
}
133117

134118
#[inline]
135-
pub fn split(mut self, other_boxes: &[MBox<'_>]) -> [Self; 2] {
119+
pub fn split(mut self) -> [Self; 2] {
136120
self.prepare_sort();
137121
let half_weight = self.prepare_color_weight_total() / 2.;
138122
// yeah, there's some off-by-one error in there
@@ -142,8 +126,8 @@ impl<'hist> MBox<'hist> {
142126
let left_sum = left.iter().map(|a| f64::from(a.adjusted_weight)).sum();
143127
let right_sum = self.adjusted_weight_sum - left_sum;
144128

145-
[MBox::from_split(left, left_sum, other_boxes),
146-
MBox::from_split(right, right_sum, other_boxes)]
129+
[MBox::from_split(left, left_sum),
130+
MBox::from_split(right, right_sum)]
147131
}
148132
}
149133

@@ -269,7 +253,11 @@ impl<'hist> MedianCutter<'hist> {
269253

270254
// store total color popularity (perceptual_weight is approximation of it)
271255
let pop = mbox.colors.iter().map(|a| f64::from(a.perceptual_weight)).sum::<f64>();
272-
palette.push(mbox.avg_color, PalPop::new(pop as f32));
256+
let mut representative_color = mbox.avg_color;
257+
if mbox.colors.len() > 2 {
258+
representative_color = mbox.colors.iter().min_by_key(|a| OrdFloat::new(representative_color.diff(&a.color))).map(|a| a.color).unwrap_or_default();
259+
}
260+
palette.push(representative_color, PalPop::new(pop as f32));
273261
}
274262
palette
275263
}
@@ -286,7 +274,7 @@ impl<'hist> MedianCutter<'hist> {
286274
break
287275
};
288276

289-
self.boxes.extend(bi.split(&self.boxes));
277+
self.boxes.extend(bi.split());
290278

291279
if self.total_box_error_below_target(target_mse) {
292280
break;

0 commit comments

Comments
 (0)