Coverage Report

Created: 2025-11-09 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/moxcms-0.7.9/src/gamut.rs
Line
Count
Source
1
/*
2
 * // Copyright (c) Radzivon Bartoshyk 3/2025. All rights reserved.
3
 * //
4
 * // Redistribution and use in source and binary forms, with or without modification,
5
 * // are permitted provided that the following conditions are met:
6
 * //
7
 * // 1.  Redistributions of source code must retain the above copyright notice, this
8
 * // list of conditions and the following disclaimer.
9
 * //
10
 * // 2.  Redistributions in binary form must reproduce the above copyright notice,
11
 * // this list of conditions and the following disclaimer in the documentation
12
 * // and/or other materials provided with the distribution.
13
 * //
14
 * // 3.  Neither the name of the copyright holder nor the names of its
15
 * // contributors may be used to endorse or promote products derived from
16
 * // this software without specific prior written permission.
17
 * //
18
 * // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
 * // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
 * // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
 * // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
 * // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
 * // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
 * // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
 * // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 */
29
use crate::Rgb;
30
31
#[inline]
32
0
fn filmlike_clip_rgb_tone(r: &mut f32, g: &mut f32, b: &mut f32, l: f32) {
33
0
    let new_r = r.min(l);
34
0
    let new_b = b.min(l);
35
0
    let new_g = new_b + ((new_r - new_b) * (*g - *b) / (*r - *b));
36
0
    *r = new_r;
37
0
    *g = new_g;
38
0
    *b = new_b;
39
0
}
40
41
/// Soft clipping out-of-bounds values in S-curve
42
///
43
/// Works only on highlights, negative values are skipped
44
#[inline]
45
0
pub fn filmlike_clip(rgb: Rgb<f32>) -> Rgb<f32> {
46
    const L: f32 = 1.;
47
0
    let mut rgb = rgb;
48
0
    if rgb.r >= rgb.g {
49
0
        if rgb.g > rgb.b {
50
0
            filmlike_clip_rgb_tone(&mut rgb.r, &mut rgb.g, &mut rgb.b, L);
51
0
        } else if rgb.b > rgb.r {
52
0
            filmlike_clip_rgb_tone(&mut rgb.b, &mut rgb.r, &mut rgb.g, L);
53
0
        } else if rgb.b > rgb.g {
54
0
            filmlike_clip_rgb_tone(&mut rgb.r, &mut rgb.b, &mut rgb.g, L);
55
0
        } else {
56
0
            Rgb::new(rgb.r.min(L), rgb.g.min(L), rgb.g);
57
0
        }
58
0
    } else if rgb.r >= rgb.b {
59
0
        filmlike_clip_rgb_tone(&mut rgb.g, &mut rgb.r, &mut rgb.b, L);
60
0
    } else if rgb.b > rgb.g {
61
0
        filmlike_clip_rgb_tone(&mut rgb.b, &mut rgb.g, &mut rgb.r, L);
62
0
    } else {
63
0
        filmlike_clip_rgb_tone(&mut rgb.g, &mut rgb.b, &mut rgb.r, L);
64
0
    }
65
0
    rgb
66
0
}