/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> |