1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
use crate::opbasics::*;
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub struct OpGamma {
}
impl<'a> OpGamma {
pub fn new(_img: &RawImage) -> OpGamma {
OpGamma{}
}
}
impl<'a> ImageOp<'a> for OpGamma {
fn name(&self) -> &str {"gamma"}
fn run(&self, pipeline: &PipelineGlobals, buf: Arc<OpBuffer>) -> Arc<OpBuffer> {
if pipeline.settings.linear {
buf
} else {
let g: f32 = 0.45;
let f: f32 = 0.099;
let min: f32 = 0.018;
let mul: f32 = 4.5;
let maxvals = 1 << 16;
let mut glookup: Vec<f32> = vec![0.0; maxvals+1];
for i in 0..(maxvals+1) {
let v = (i as f32) / (maxvals as f32);
glookup[i] = if v <= min {
mul * v
} else {
((1.0+f) * v.powf(g)) - f
}
}
Arc::new(buf.mutate_lines_copying(&(|line: &mut [f32], _| {
for pix in line.chunks_exact_mut(1) {
pix[0] = glookup[(pix[0].max(0.0)*(maxvals as f32)).min(maxvals as f32) as usize];
}
})))
}
}
}