1#![allow(clippy::erasing_op, clippy::identity_op, reason = "symmetry")]
4
5fn error_diffuse(
7 data: &mut [u8], pos: i32, depth: i32, error: i32, numerator: i32, denominator: i32, ) {
14 let offset = (pos * depth) as usize;
15
16 let mut c = data[offset] as i32 + error * numerator / denominator;
17 if c < 0 {
18 c = 0;
19 }
20 if c >= 1 << 8 {
21 c = (1 << 8) - 1;
22 }
23 data[offset] = c as u8;
24}
25
26pub(super) fn diffuse_fs(
33 data: &mut [u8],
34 width: i32,
35 height: i32,
36 x: i32,
37 y: i32,
38 depth: i32,
39 error: i32,
40) {
41 let pos = y * width + x;
42 if x < width - 1 && y < height - 1 {
43 error_diffuse(data, pos + width * 0 + 1, depth, error, 7, 16);
45 error_diffuse(data, pos + width * 1 - 1, depth, error, 3, 16);
47 error_diffuse(data, pos + width * 1 + 0, depth, error, 5, 16);
49 error_diffuse(data, pos + width * 1 + 1, depth, error, 1, 16);
51 }
52}
53
54pub(super) fn diffuse_atkinson(
62 data: &mut [u8],
63 width: i32,
64 height: i32,
65 x: i32,
66 y: i32,
67 depth: i32,
68 error: i32,
69) {
70 let pos = y * width + x;
71 if y < height - 2 {
72 error_diffuse(data, pos + width * 0 + 1, depth, error, 1, 8);
74 error_diffuse(data, pos + width * 0 + 2, depth, error, 1, 8);
76 error_diffuse(data, pos + width * 1 - 1, depth, error, 1, 8);
78 error_diffuse(data, pos + width * 1 + 0, depth, error, 1, 8);
80 error_diffuse(data, pos + width * 1 + 1, depth, error, 1, 8);
82 error_diffuse(data, pos + width * 2 + 0, depth, error, 1, 8);
84 }
85}
86
87pub(super) fn diffuse_jajuni(
95 data: &mut [u8],
96 width: i32,
97 height: i32,
98 x: i32,
99 y: i32,
100 depth: i32,
101 error: i32,
102) {
103 let pos = y * width + x;
104 if pos < (height - 2) * width - 2 {
105 error_diffuse(data, pos + width * 0 + 1, depth, error, 7, 48);
106 error_diffuse(data, pos + width * 0 + 2, depth, error, 5, 48);
107 error_diffuse(data, pos + width * 1 - 2, depth, error, 3, 48);
108 error_diffuse(data, pos + width * 1 - 1, depth, error, 5, 48);
109 error_diffuse(data, pos + width * 1 + 0, depth, error, 7, 48);
110 error_diffuse(data, pos + width * 1 + 1, depth, error, 5, 48);
111 error_diffuse(data, pos + width * 1 + 2, depth, error, 3, 48);
112 error_diffuse(data, pos + width * 2 - 2, depth, error, 1, 48);
113 error_diffuse(data, pos + width * 2 - 1, depth, error, 3, 48);
114 error_diffuse(data, pos + width * 2 + 0, depth, error, 5, 48);
115 error_diffuse(data, pos + width * 2 + 1, depth, error, 3, 48);
116 error_diffuse(data, pos + width * 2 + 2, depth, error, 1, 48);
117 }
118}
119
120pub(super) fn diffuse_stucki(
128 data: &mut [u8],
129 width: i32,
130 height: i32,
131 x: i32,
132 y: i32,
133 depth: i32,
134 error: i32,
135) {
136 let pos = y * width + x;
137 if pos < (height - 2) * width - 2 {
138 error_diffuse(data, pos + width * 0 + 1, depth, error, 1, 6);
139 error_diffuse(data, pos + width * 0 + 2, depth, error, 1, 12);
140 error_diffuse(data, pos + width * 1 - 2, depth, error, 1, 24);
141 error_diffuse(data, pos + width * 1 - 1, depth, error, 1, 12);
142 error_diffuse(data, pos + width * 1 + 0, depth, error, 1, 6);
143 error_diffuse(data, pos + width * 1 + 1, depth, error, 1, 12);
144 error_diffuse(data, pos + width * 1 + 2, depth, error, 1, 24);
145 error_diffuse(data, pos + width * 2 - 2, depth, error, 1, 48);
146 error_diffuse(data, pos + width * 2 - 1, depth, error, 1, 24);
147 error_diffuse(data, pos + width * 2 + 0, depth, error, 1, 12);
148 error_diffuse(data, pos + width * 2 + 1, depth, error, 1, 24);
149 error_diffuse(data, pos + width * 2 + 2, depth, error, 1, 48);
150 }
151}
152
153pub(super) fn diffuse_burkes(
160 data: &mut [u8],
161 width: i32,
162 height: i32,
163 x: i32,
164 y: i32,
165 depth: i32,
166 error: i32,
167) {
168 let pos = y * width + x;
169 if pos < (height - 1) * width - 2 {
170 error_diffuse(data, pos + width * 0 + 1, depth, error, 1, 4);
171 error_diffuse(data, pos + width * 0 + 2, depth, error, 1, 8);
172 error_diffuse(data, pos + width * 1 - 2, depth, error, 1, 16);
173 error_diffuse(data, pos + width * 1 - 1, depth, error, 1, 8);
174 error_diffuse(data, pos + width * 1 + 0, depth, error, 1, 4);
175 error_diffuse(data, pos + width * 1 + 1, depth, error, 1, 8);
176 error_diffuse(data, pos + width * 1 + 2, depth, error, 1, 16);
177 }
178}