+fn elbg_quant(entries: &[YUVCode], codebook: &mut [YUVCode]) -> usize {
+ let cb_len = quantise_median_cut::<YUVCode, YUVCodeSum>(entries, codebook);
+ if cb_len < codebook.len() {
+ cb_len
+ } else {
+ let mut elbg: ELBG<YUVCode, YUVCodeSum> = ELBG::new(codebook);
+ elbg.quantise(entries, codebook)
+ }
+}
+
+fn quant_fast(bins: &mut [Vec<YUVCode>; 4], entries: &[YUVCode], codebook: &mut [YUVCode]) -> usize {
+ for bin in bins.iter_mut() {
+ bin.clear();
+ }
+ for &entry in entries.iter() {
+ let y_avg = avg4(entry.y[0], entry.y[1], entry.y[2], entry.y[3]);
+ let dist = entry.y.iter().fold(0u32, |acc, &x| acc + variance(x, y_avg));
+ let ilog = if dist == 0 { 0 } else { 32 - dist.leading_zeros() };
+ let bin = match ilog {
+ 0..=3 => &mut bins[0],
+ 4..=7 => &mut bins[1],
+ 8..=11 => &mut bins[2],
+ _ => &mut bins[3],
+ };
+ bin.push(entry);
+ }
+ let mut free_cw = codebook.len();
+ let mut entries_left = entries.len();
+ let mut offset = 0;
+ for bin in bins.iter() {
+ if bin.is_empty() {
+ continue;
+ }
+ if free_cw == 0 || entries_left == 0 {
+ break;
+ }
+ let target = (free_cw * bin.len() + entries_left - 1) / entries_left;
+ let cur_len = elbg_quant(bin, &mut codebook[offset..][..target]);
+ offset += cur_len;
+ free_cw -= cur_len;
+ entries_left -= bin.len();
+ }
+ offset
+}
+