Coverage Report

Created: 2026-09-28 07:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/pic-scale-safe-0.1.12/src/alpha_check.rs
Line
Count
Source
1
/*
2
 * Copyright (c) Radzivon Bartoshyk, 10/2024. 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 num_traits::AsPrimitive;
30
use std::ops::{AddAssign, BitXor};
31
32
/// Performs scan on the RGBA 8 bit image if it has variable alpha channel
33
///
34
/// # Arguments
35
///
36
/// * `store`: Slice with rgba data
37
/// * `width`: image width
38
///
39
/// returns: bool
40
///
41
0
pub fn has_non_constant_alpha_rgba8(store: &[u8], width: usize) -> bool {
42
0
    has_non_constant_alpha::<u8, u32, 3, 4>(store, width)
43
0
}
44
45
/// Performs scan on the Luma+Alpha 8 bit image if it has variable alpha channel
46
///
47
/// # Arguments
48
///
49
/// * `store`: Slice with luma with alpha data
50
/// * `width`: image width
51
///
52
/// returns: bool
53
///
54
0
pub fn has_non_constant_alpha_la8(store: &[u8], width: usize) -> bool {
55
0
    has_non_constant_alpha::<u8, u32, 1, 2>(store, width)
56
0
}
57
58
/// Performs scan on the RGBA 16 bit image if it has variable alpha channel
59
///
60
/// # Arguments
61
///
62
/// * `store`: Slice with rgba16 data
63
/// * `width`: image width
64
///
65
/// returns: bool
66
///
67
0
pub fn has_non_constant_alpha_rgba16(store: &[u16], width: usize) -> bool {
68
0
    has_non_constant_alpha::<u16, u64, 3, 4>(store, width)
69
0
}
70
71
/// Performs scan on the Luma+Alpha 16 bit image if it has variable alpha channel
72
///
73
/// # Arguments
74
///
75
/// * `store`: Slice with luma with alpha 16-bit data
76
/// * `width`: image width
77
///
78
/// returns: bool
79
///
80
0
pub fn has_non_constant_alpha_la16(store: &[u16], width: usize) -> bool {
81
0
    has_non_constant_alpha::<u16, u64, 1, 2>(store, width)
82
0
}
83
84
/// Performs scan on the RGBA f32 bit image if it has variable alpha channel
85
///
86
/// # Arguments
87
///
88
/// * `store`: Slice with rgba f32 data
89
/// * `width`: image width
90
///
91
/// returns: bool
92
///
93
0
pub fn has_non_constant_alpha_rgba_f32(store: &[f32], width: usize) -> bool {
94
0
    has_non_constant_alpha_f32_impl::<3, 4>(store, width)
95
0
}
96
97
/// Performs scan on the Luma-alpha f32 bit image if it has variable alpha channel
98
///
99
/// # Arguments
100
///
101
/// * `store`: Slice with Luma alpha f32 data
102
/// * `width`: image width
103
///
104
/// returns: bool
105
///
106
0
pub fn has_non_constant_alpha_luma_alpha_f32(store: &[f32], width: usize) -> bool {
107
0
    has_non_constant_alpha_f32_impl::<1, 2>(store, width)
108
0
}
109
110
#[inline]
111
0
fn has_non_constant_alpha<
112
0
    V: Copy + PartialEq + BitXor<V, Output = V> + 'static + AsPrimitive<J> + 'static,
113
0
    J: Copy + AddAssign + Default + 'static + Eq + Ord,
114
0
    const ALPHA_CHANNEL_INDEX: usize,
115
0
    const CHANNELS: usize,
116
0
>(
117
0
    store: &[V],
118
0
    width: usize,
119
0
) -> bool
120
0
where
121
0
    i32: AsPrimitive<V>,
122
0
    u32: AsPrimitive<V> + AsPrimitive<J>,
123
{
124
0
    assert!(ALPHA_CHANNEL_INDEX < CHANNELS);
125
0
    assert!(CHANNELS > 0 && CHANNELS <= 4);
126
0
    if store.is_empty() {
127
0
        return false;
128
0
    }
129
0
    let first = store[0];
130
0
    let mut row_sums: J = 0u32.as_();
131
0
    for row in store.chunks_exact(width * CHANNELS) {
132
0
        for color in row.chunks_exact(CHANNELS) {
133
0
            row_sums += color[ALPHA_CHANNEL_INDEX].bitxor(first).as_();
134
0
        }
135
0
        if row_sums != 0.as_() {
136
0
            return true;
137
0
        }
138
    }
139
140
0
    let zeros = 0.as_();
141
142
0
    row_sums.ne(&zeros)
143
0
}
Unexecuted instantiation: pic_scale_safe::alpha_check::has_non_constant_alpha::<u8, u32, 1, 2>
Unexecuted instantiation: pic_scale_safe::alpha_check::has_non_constant_alpha::<u8, u32, 3, 4>
Unexecuted instantiation: pic_scale_safe::alpha_check::has_non_constant_alpha::<u16, u64, 1, 2>
Unexecuted instantiation: pic_scale_safe::alpha_check::has_non_constant_alpha::<u16, u64, 3, 4>
144
145
#[inline]
146
0
fn has_non_constant_alpha_f32_impl<const ALPHA_CHANNEL_INDEX: usize, const CHANNELS: usize>(
147
0
    store: &[f32],
148
0
    width: usize,
149
0
) -> bool {
150
0
    assert!(ALPHA_CHANNEL_INDEX < CHANNELS);
151
0
    assert!(CHANNELS > 0 && CHANNELS <= 4);
152
0
    if store.is_empty() {
153
0
        return false;
154
0
    }
155
0
    let first = store[0].to_bits();
156
0
    let mut row_sums: u64 = 0u64;
157
0
    for row in store.chunks_exact(width * CHANNELS) {
158
0
        for color in row.chunks_exact(CHANNELS) {
159
0
            row_sums += color[ALPHA_CHANNEL_INDEX].to_bits().bitxor(first) as u64;
160
0
        }
161
0
        if row_sums != 0 {
162
0
            return true;
163
0
        }
164
    }
165
166
0
    let zeros = 0;
167
168
0
    row_sums.ne(&zeros)
169
0
}
Unexecuted instantiation: pic_scale_safe::alpha_check::has_non_constant_alpha_f32_impl::<1, 2>
Unexecuted instantiation: pic_scale_safe::alpha_check::has_non_constant_alpha_f32_impl::<3, 4>