MCPcopy Create free account
hub / github.com/ImageOptim/libimagequant / vp_create_node

Function vp_create_node

src/nearest.rs:115–178  ·  view source on GitHub ↗
(indexes: &mut [MapIndex], items: &PalF)

Source from the content-addressed store, hash-verified

113
114#[inline(never)]
115fn vp_create_node(indexes: &mut [MapIndex], items: &PalF) -> Node {
116 debug_assert!(!indexes.is_empty());
117 let palette = items.as_slice();
118
119 if indexes.len() <= 1 {
120 let idx = indexes.first().map(|i| i.idx).unwrap_or_default();
121 return Node {
122 vantage_point: palette.get(usize::from(idx)).copied().unwrap_or_default(),
123 idx,
124 inner: NodeInner::Leaf { len: 0, idxs: [0; LEAF_MAX_SIZE], colors: Box::new([f_pixel::default(); LEAF_MAX_SIZE]) },
125 };
126 }
127
128 let most_popular_item = indexes.iter().enumerate().max_by_key(move |(_, idx)| {
129 OrdFloat::new(items.pop_as_slice().get(usize::from(idx.idx))
130 .map(|p| p.popularity()).unwrap_or_default())
131 }).map(|(n, _)| n).unwrap_or_default();
132 indexes.swap(most_popular_item, 0);
133 let (ref_, indexes) = indexes.split_first_mut().unwrap();
134
135 let vantage_point = palette.get(usize::from(ref_.idx)).copied().unwrap_or_default();
136 indexes.sort_by_cached_key(move |i| {
137 OrdFloat::new(palette.get(usize::from(i.idx))
138 .map(|px| vantage_point.diff(px)).unwrap_or_default())
139 });
140
141 let num_indexes = indexes.len();
142
143 let inner = if num_indexes <= LEAF_MAX_SIZE {
144 let mut colors = [f_pixel::default(); LEAF_MAX_SIZE];
145 let mut idxs = [Default::default(); LEAF_MAX_SIZE];
146
147 indexes.iter().zip(colors.iter_mut().zip(idxs.iter_mut())).for_each(|(i, (color, idx))| {
148 if let Some(c) = palette.get(usize::from(i.idx)) {
149 *idx = i.idx;
150 *color = *c;
151 }
152 });
153 NodeInner::Leaf {
154 len: num_indexes as _,
155 idxs,
156 colors: Box::new(colors),
157 }
158 } else {
159 let half_index = num_indexes / 2;
160 let (near, far) = indexes.split_at_mut(half_index);
161 debug_assert!(!near.is_empty());
162 debug_assert!(!far.is_empty());
163 let radius_squared = palette.get(usize::from(far[0].idx))
164 .map(|px| vantage_point.diff(px)).unwrap_or_default();
165 let radius = radius_squared.sqrt();
166 NodeInner::Nodes {
167 radius, radius_squared,
168 near: Box::new(vp_create_node(near, items)),
169 far: Box::new(vp_create_node(far, items)),
170 }
171 };
172

Callers 1

newMethod · 0.85

Calls 8

newFunction · 0.85
pop_as_sliceMethod · 0.80
popularityMethod · 0.80
swapMethod · 0.80
diffMethod · 0.80
iter_mutMethod · 0.80
as_sliceMethod · 0.45
lenMethod · 0.45

Tested by

no test coverage detected