Skip to content

Commit d5661ec

Browse files
committed
Avoid panicking bounds check in lut_interp_linear_float
1 parent 82dd8dd commit d5661ec

File tree

2 files changed

+61
-30
lines changed

2 files changed

+61
-30
lines changed

src/chain.rs

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -261,19 +261,35 @@ impl ModularTransform for Clut3x3 {
261261
.unwrap_or_else(unlikely_default)
262262
};
263263

264-
let input_clut_table_r = self.input_clut_table[0].as_ref().unwrap();
265-
let input_clut_table_g = self.input_clut_table[1].as_ref().unwrap();
266-
let input_clut_table_b = self.input_clut_table[2].as_ref().unwrap();
267-
let output_clut_table_r = self.output_clut_table[0].as_ref().unwrap();
268-
let output_clut_table_g = self.output_clut_table[1].as_ref().unwrap();
269-
let output_clut_table_b = self.output_clut_table[2].as_ref().unwrap();
264+
let input_clut_table_r = self.input_clut_table[0].as_ref().unwrap().as_slice();
265+
let input_clut_table_g = self.input_clut_table[1].as_ref().unwrap().as_slice();
266+
let input_clut_table_b = self.input_clut_table[2].as_ref().unwrap().as_slice();
267+
268+
// num_input_table_entries/num_output_table_entries are checked to be in this range
269+
// asserting they're equal optimizes lut_interp_linear_float
270+
assert!(
271+
(2..4096).contains(&input_clut_table_r.len())
272+
&& input_clut_table_r.len() == input_clut_table_g.len()
273+
&& input_clut_table_r.len() == input_clut_table_b.len()
274+
);
275+
276+
let output_clut_table_r = self.output_clut_table[0].as_ref().unwrap().as_slice();
277+
let output_clut_table_g = self.output_clut_table[1].as_ref().unwrap().as_slice();
278+
let output_clut_table_b = self.output_clut_table[2].as_ref().unwrap().as_slice();
279+
280+
assert!(
281+
(2..4096).contains(&output_clut_table_r.len())
282+
&& output_clut_table_r.len() == output_clut_table_g.len()
283+
&& output_clut_table_r.len() == output_clut_table_b.len()
284+
);
285+
270286
for (dest, src) in dest.chunks_exact_mut(3).zip(src.chunks_exact(3)) {
271287
let device_r = src[0];
272288
let device_g = src[1];
273289
let device_b = src[2];
274-
let linear_r = lut_interp_linear_float(device_r, &input_clut_table_r);
275-
let linear_g = lut_interp_linear_float(device_g, &input_clut_table_g);
276-
let linear_b = lut_interp_linear_float(device_b, &input_clut_table_b);
290+
let linear_r = lut_interp_linear_float(device_r, input_clut_table_r);
291+
let linear_g = lut_interp_linear_float(device_g, input_clut_table_g);
292+
let linear_b = lut_interp_linear_float(device_b, input_clut_table_b);
277293
let x = (linear_r * grid_max).floor() as u32;
278294
let y = (linear_g * grid_max).floor() as u32;
279295
let z = (linear_b * grid_max).floor() as u32;
@@ -345,18 +361,33 @@ impl ModularTransform for Clut4x3 {
345361
.unwrap_or_else(unlikely_default)
346362
};
347363

348-
let input_clut_table_0 = self.input_clut_table[0].as_ref().unwrap();
349-
let input_clut_table_1 = self.input_clut_table[1].as_ref().unwrap();
350-
let input_clut_table_2 = self.input_clut_table[2].as_ref().unwrap();
351-
let input_clut_table_3 = self.input_clut_table[3].as_ref().unwrap();
352-
let output_clut_table_r = &self.output_clut_table[0].as_ref().unwrap();
353-
let output_clut_table_g = &self.output_clut_table[1].as_ref().unwrap();
354-
let output_clut_table_b = &self.output_clut_table[2].as_ref().unwrap();
364+
let input_clut_table_0 = self.input_clut_table[0].as_ref().unwrap().as_slice();
365+
let input_clut_table_1 = self.input_clut_table[1].as_ref().unwrap().as_slice();
366+
let input_clut_table_2 = self.input_clut_table[2].as_ref().unwrap().as_slice();
367+
let input_clut_table_3 = self.input_clut_table[3].as_ref().unwrap().as_slice();
368+
369+
assert!(
370+
(2..4096).contains(&input_clut_table_0.len())
371+
&& input_clut_table_0.len() == input_clut_table_1.len()
372+
&& input_clut_table_0.len() == input_clut_table_2.len()
373+
&& input_clut_table_0.len() == input_clut_table_3.len()
374+
);
375+
376+
let output_clut_table_r = self.output_clut_table[0].as_ref().unwrap().as_slice();
377+
let output_clut_table_g = self.output_clut_table[1].as_ref().unwrap().as_slice();
378+
let output_clut_table_b = self.output_clut_table[2].as_ref().unwrap().as_slice();
379+
380+
assert!(
381+
(2..4096).contains(&output_clut_table_r.len())
382+
&& output_clut_table_r.len() == output_clut_table_g.len()
383+
&& output_clut_table_r.len() == output_clut_table_b.len()
384+
);
385+
355386
for (dest, src) in dest.chunks_exact_mut(3).zip(src.chunks_exact(4)) {
356-
let linear_x = lut_interp_linear_float(src[0], &input_clut_table_0);
357-
let linear_y = lut_interp_linear_float(src[1], &input_clut_table_1);
358-
let linear_z = lut_interp_linear_float(src[2], &input_clut_table_2);
359-
let linear_w = lut_interp_linear_float(src[3], &input_clut_table_3);
387+
let linear_x = lut_interp_linear_float(src[0], input_clut_table_0);
388+
let linear_y = lut_interp_linear_float(src[1], input_clut_table_1);
389+
let linear_z = lut_interp_linear_float(src[2], input_clut_table_2);
390+
let linear_w = lut_interp_linear_float(src[3], input_clut_table_3);
360391

361392
let x = (linear_x * grid_max).floor() as u32;
362393
let y = (linear_y * grid_max).floor() as u32;
@@ -578,9 +609,9 @@ impl ModularTransform for GammaTable {
578609
let in_r = src[0];
579610
let in_g = src[1];
580611
let in_b = src[2];
581-
out_r = lut_interp_linear_float(in_r, &input_clut_table_r[..]);
582-
out_g = lut_interp_linear_float(in_g, &input_clut_table_g[..]);
583-
out_b = lut_interp_linear_float(in_b, &input_clut_table_b[..]);
612+
out_r = lut_interp_linear_float(in_r, input_clut_table_r);
613+
out_g = lut_interp_linear_float(in_g, input_clut_table_g);
614+
out_b = lut_interp_linear_float(in_b, input_clut_table_b);
584615

585616
dest[0] = clamp_float(out_r);
586617
dest[1] = clamp_float(out_g);

src/transform_util.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,16 +114,16 @@ fn lut_interp_linear_precache_output(input_value: u32, table: &[u16]) -> u8 {
114114
}
115115
/* value must be a value between 0 and 1 */
116116
//XXX: is the above a good restriction to have?
117+
#[inline]
117118
pub fn lut_interp_linear_float(mut value: f32, table: &[f32]) -> f32 {
118-
value *= (table.len() - 1) as f32;
119+
let max_val = table.len() - 1;
120+
value *= max_val as f32;
119121

120-
let upper: i32 = value.ceil() as i32;
121-
let lower: i32 = value.floor() as i32;
122+
let upper = value.ceil();
123+
let lower = value.floor();
122124
//XXX: can we be more performant here?
123-
value = (table[upper as usize] as f64 * (1.0f64 - (upper as f32 - value) as f64)
124-
+ (table[lower as usize] * (upper as f32 - value)) as f64) as f32;
125-
/* scale the value */
126-
value
125+
(table[max_val.min(upper as usize)] as f64 * (1.0 - (upper - value) as f64)
126+
+ (table[max_val.min(lower as usize)] * (upper - value)) as f64) as f32
127127
}
128128

129129
fn compute_curve_gamma_table_type1(gamma_table: &mut [f32; 256], gamma: u16) {

0 commit comments

Comments
 (0)