Skip to content

Commit f94328e

Browse files
committed
SPLINE TIME
1 parent 3b3ffb9 commit f94328e

File tree

6 files changed

+63
-41
lines changed

6 files changed

+63
-41
lines changed

‎Cargo.lock‎

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎blitz/Cargo.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ palette = "0.5.0"
1414
rayon = "1.3.0"
1515
num-traits = "0.2.11"
1616
ordered-float = "1.0.2"
17+
splines = "3.4.1"

‎blitz/src/render.rs‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,8 @@ pub fn render_raw_with_settings(img: &ParsedRafFile, settings: &RenderSettings)
4545
blue: pixel.blue * scale_factors[2],
4646
};
4747

48-
let apply_curve_floats = |pixel: f32| {
49-
let coefs = settings.tone_curve.len();
50-
let mut chosen = (pixel * coefs as f32) as usize;
51-
if chosen >= coefs {
52-
chosen = coefs - 1;
53-
}
54-
settings.tone_curve[chosen] * pixel
55-
};
48+
let apply_curve_floats =
49+
|pixel: f32| settings.tone_curve.spline.clamped_sample(pixel).unwrap() * pixel;
5650

5751
let clamp = |pixel: &Pixel<_>| Pixel {
5852
red: float_clamp(pixel.red),

‎blitz/src/render_settings.rs‎

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,63 @@
11
use itertools::Itertools;
2-
use std::iter::once;
2+
use splines;
3+
use splines::{Interpolation, Key, Spline};
4+
use std::iter::{once, repeat};
35

6+
#[derive(Debug, Clone)]
47
pub struct ToneCurve {
5-
x_vals: Vec<f32>,
6-
tangents: Vec<f32>,
8+
pub spline: Spline<f32, f32>,
79
}
810

911
impl ToneCurve {
10-
pub fn new(points: &Vec<f32>) -> Self {
12+
pub fn new(points: &[f32]) -> Self {
1113
// SPLINE TIME
1214
// https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Catmull%E2%80%93Rom_spline
15+
// TODO: figure out what's going on with the edges, they're unhappy here.
16+
// Start and end at 1 because this is multiplicative.
1317
let x_inc = 1.0 / points.len() as f32;
18+
let start = Key::new(0., 1., Interpolation::Cosine);
19+
let end = Key::new(1., 1., Interpolation::default());
20+
1421
// for 4 points, this should be 12.5, 37.5, 62.5, 87.5, i.e. split into 4 even bands
15-
let x_vals = (0..points.len()).map(|x| (x as f32 + 0.5) * x_inc);
16-
let xs = once(0.0).chain(x_vals).chain(once(1.0)).collect_vec();
17-
let ys = once(0.0)
18-
.chain(points.iter().copied())
19-
.chain(once(1.0))
20-
.collect_vec();
21-
assert_eq!(xs.len(), ys.len());
22-
23-
let tangents = (1..(xs.len() - 1))
24-
.map(|k| {
25-
// as per wikipedia:
26-
// m_k =
27-
(ys[k + 1] - ys[k - 1]) / (xs[k + 1] - xs[k - 1])
28-
})
29-
.collect_vec();
30-
ToneCurve {
31-
x_vals: xs,
32-
tangents,
33-
}
22+
let xs = (0..points.len()).map(|x| (x as f32 + 0.5) * x_inc);
23+
24+
let iter = once(start)
25+
.chain(
26+
xs.zip_eq(points.iter().copied())
27+
.map(|(x, y)| Key::new(x, y, Interpolation::CatmullRom)),
28+
)
29+
.chain(repeat(end).take(2));
30+
let spline = Spline::from_iter(iter);
31+
32+
ToneCurve { spline }
3433
}
3534

36-
pub fn apply(val: f32) -> f32 {}
35+
pub fn apply(&self, val: f32) -> f32 {
36+
self.spline.sample(val).unwrap_or(f32::NAN)
37+
}
38+
}
39+
40+
impl Default for ToneCurve {
41+
fn default() -> Self {
42+
let spl = Spline::from_vec(vec![
43+
// Flat curve
44+
Key::new(0.0, 1.0, Interpolation::Linear),
45+
Key::new(1.0, 1.0, Interpolation::Linear),
46+
]);
47+
ToneCurve { spline: spl }
48+
}
3749
}
3850

3951
#[derive(Debug, Clone)]
4052
pub struct RenderSettings {
41-
pub tone_curve: Vec<f32>,
53+
pub tone_curve: ToneCurve,
4254
pub exposure_basis: f32,
4355
}
4456

4557
impl Default for RenderSettings {
4658
fn default() -> Self {
4759
RenderSettings {
48-
tone_curve: vec![1.5],
60+
tone_curve: ToneCurve::default(),
4961
exposure_basis: 1.0,
5062
}
5163
}

‎blitzexport/src/lib.rs‎

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use blitz::render::{render_raw, render_raw_with_settings};
22
use blitz::render_settings;
3+
use blitz::render_settings::ToneCurve;
34
use libc::c_char;
45
use libraw::raf::{ParsedRafFile, RafFile};
56
use std::ffi::CStr;
@@ -78,13 +79,20 @@ const TONE_CURVE_CONST: f32 = 2.0;
7879

7980
impl RenderSettings {
8081
fn to_blitz_settings(&self) -> render_settings::RenderSettings {
82+
let coefs: Vec<_> = self
83+
.tone_curve
84+
.iter()
85+
.copied()
86+
.map(|x| TONE_CURVE_CONST.powf(x))
87+
.collect();
88+
let tc = ToneCurve::new(&coefs);
89+
println!("Tonecurve: {:?}", tc);
90+
for i in 0..100 {
91+
println!("{},{}", i, tc.apply(i as f32 / 100.));
92+
}
93+
8194
render_settings::RenderSettings {
82-
tone_curve: self
83-
.tone_curve
84-
.iter()
85-
.copied()
86-
.map(|x| TONE_CURVE_CONST.powf(x))
87-
.collect(),
95+
tone_curve: tc,
8896
exposure_basis: TONE_CURVE_CONST.powf(self.exposure_basis),
8997
}
9098
}

‎gui/Blitz/Blitz/ContentView.swift‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ struct RenderControlsView: View {
132132
}
133133
HStack {
134134
Text("Baseline Exposure: \(self.exposure)")
135-
SlideyBoi(value: $exposure, min:-1, max:1)
135+
SlideyBoi(value: $exposure, min:-5, max:5)
136136
}
137137
HStack {
138138
Text("Tone Curve")

0 commit comments

Comments
 (0)