devela/media/image/sixel/dither/
dither.rs
1#![allow(clippy::erasing_op, clippy::identity_op, reason = "symmetry")]
18
19crate::impl_cdef! { Self::Auto => Dither }
20
21#[repr(u8)]
29#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
30pub enum Dither {
31 #[default]
33 Auto = 0,
34
35 None = 1,
37
38 Atkinson = 2,
43
44 FS = 3,
49
50 JaJuNi = 4,
55
56 Stucki = 5,
61
62 Burkes = 6,
67
68 ADither = 7,
73
74 XDither = 8,
79}
80
81impl Dither {
82 #[rustfmt::skip]
95 pub fn apply_15bpp(self, pixels: &mut [u8], x: i32, y: i32, width: i32, height: i32) {
96 match self {
97 Dither::None | Dither::Auto => {
98 dither_none(pixels, width); }
99 Dither::Atkinson => {
101 if x < width - 2 && y < height - 2 { dither_atkinson_15bpp(pixels, width); } }
102 Dither::FS => {
103 if x < width - 1 && y < height - 1 { dither_fs_15bpp(pixels, width); } }
104 Dither::JaJuNi => {
105 if x < width - 2 && y < height - 2 { dither_jajuni_15bpp(pixels, width); } }
106 Dither::Stucki => {
107 if x < width - 2 && y < height - 2 { dither_stucki_15bpp(pixels, width); } }
108 Dither::Burkes => {
109 if x < width - 2 && y < height - 1 { dither_burkes_15bpp(pixels, width); } }
110 Dither::ADither => {
112 dither_a_dither_15bpp(pixels, width, x, y); }
113 Dither::XDither => {
114 dither_x_dither_15bpp(pixels, width, x, y); }
115 }
116 }
117}
118
119fn dither_none(_data: &mut [u8], _width: i32) {}
121
122fn dither_fs_15bpp(data: &mut [u8], width: i32) {
129 let error_r = data[0] as i32 & 0x7;
130 let error_g = data[1] as i32 & 0x7;
131 let error_b = data[2] as i32 & 0x7;
132 let width = width as usize;
133 let mut r = data[3 + 0] as i32 + ((error_r * 5) >> 4);
134 let mut g = data[3 + 1] as i32 + ((error_g * 5) >> 4);
135 let mut b = data[3 + 2] as i32 + ((error_b * 5) >> 4);
136 data[3 + 0] = if r > 0xff { 0xff } else { r as u8 };
137 data[3 + 1] = if g > 0xff { 0xff } else { g as u8 };
138 data[3 + 2] = if b > 0xff { 0xff } else { b as u8 };
139 r = data[width * 3 - 3 + 0] as i32 + ((error_r * 3) >> 4);
140 g = data[width * 3 - 3 + 1] as i32 + ((error_g * 3) >> 4);
141 b = data[width * 3 - 3 + 2] as i32 + ((error_b * 3) >> 4);
142 data[width * 3 - 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
143 data[width * 3 - 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
144 data[width * 3 - 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
145 r = data[width * 3 + 0] as i32 + ((error_r * 5) >> 4);
146 g = data[width * 3 + 1] as i32 + ((error_g * 5) >> 4);
147 b = data[width * 3 + 2] as i32 + ((error_b * 5) >> 4);
148 data[width * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
149 data[width * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
150 data[width * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
151}
152
153fn dither_atkinson_15bpp(data: &mut [u8], width: i32) {
160 let mut error_r = data[0] as i32 & 0x7;
161 let mut error_g = data[1] as i32 & 0x7;
162 let mut error_b = data[2] as i32 & 0x7;
163 error_r += 4;
164 error_g += 4;
165 error_b += 4;
166 let width = width as usize;
167
168 let mut r = data[(width * 0 + 1) * 3 + 0] as i32 + (error_r >> 3);
169 let mut g = data[(width * 0 + 1) * 3 + 1] as i32 + (error_g >> 3);
170 let mut b = data[(width * 0 + 1) * 3 + 2] as i32 + (error_b >> 3);
171 data[(width * 0 + 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
172 data[(width * 0 + 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
173 data[(width * 0 + 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
174 r = data[(width * 0 + 2) * 3 + 0] as i32 + (error_r >> 3);
175 g = data[(width * 0 + 2) * 3 + 1] as i32 + (error_g >> 3);
176 b = data[(width * 0 + 2) * 3 + 2] as i32 + (error_b >> 3);
177 data[(width * 0 + 2) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
178 data[(width * 0 + 2) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
179 data[(width * 0 + 2) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
180 r = data[(width * 1 - 1) * 3 + 0] as i32 + (error_r >> 3);
181 g = data[(width * 1 - 1) * 3 + 1] as i32 + (error_g >> 3);
182 b = data[(width * 1 - 1) * 3 + 2] as i32 + (error_b >> 3);
183 data[(width * 1 - 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
184 data[(width * 1 - 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
185 data[(width * 1 - 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
186 r = data[(width * 1 + 0) * 3 + 0] as i32 + (error_r >> 3);
187 g = data[(width * 1 + 0) * 3 + 1] as i32 + (error_g >> 3);
188 b = data[(width * 1 + 0) * 3 + 2] as i32 + (error_b >> 3);
189 data[(width * 1 + 0) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
190 data[(width * 1 + 0) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
191 data[(width * 1 + 0) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
192 r = data[(width * 1 + 1) * 3 + 0] as i32 + (error_r >> 3);
193 g = data[(width * 1 + 1) * 3 + 1] as i32 + (error_g >> 3);
194 b = data[(width * 1 + 1) * 3 + 2] as i32 + (error_b >> 3);
195 data[(width * 1 + 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
196 data[(width * 1 + 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
197 data[(width * 1 + 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
198 r = data[(width * 2 + 0) * 3 + 0] as i32 + (error_r >> 3);
199 g = data[(width * 2 + 0) * 3 + 1] as i32 + (error_g >> 3);
200 b = data[(width * 2 + 0) * 3 + 2] as i32 + (error_b >> 3);
201 data[(width * 2 + 0) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
202 data[(width * 2 + 0) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
203 data[(width * 2 + 0) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
204}
205
206fn dither_jajuni_15bpp(data: &mut [u8], width: i32) {
214 let mut error_r = data[0] as i32 & 0x7;
215 let mut error_g = data[1] as i32 & 0x7;
216 let mut error_b = data[2] as i32 & 0x7;
217 error_r += 4;
218 error_g += 4;
219 error_b += 4;
220 let width = width as usize;
221
222 let mut r = data[(width * 0 + 1) * 3 + 0] as i32 + (error_r * 7 / 48);
223 let mut g = data[(width * 0 + 1) * 3 + 1] as i32 + (error_g * 7 / 48);
224 let mut b = data[(width * 0 + 1) * 3 + 2] as i32 + (error_b * 7 / 48);
225 data[(width * 0 + 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
226 data[(width * 0 + 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
227 data[(width * 0 + 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
228 r = data[(width * 0 + 2) * 3 + 0] as i32 + (error_r * 5 / 48);
229 g = data[(width * 0 + 2) * 3 + 1] as i32 + (error_g * 5 / 48);
230 b = data[(width * 0 + 2) * 3 + 2] as i32 + (error_b * 5 / 48);
231 data[(width * 0 + 2) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
232 data[(width * 0 + 2) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
233 data[(width * 0 + 2) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
234 r = data[(width * 1 - 2) * 3 + 0] as i32 + (error_r * 3 / 48);
235 g = data[(width * 1 - 2) * 3 + 1] as i32 + (error_g * 3 / 48);
236 b = data[(width * 1 - 2) * 3 + 2] as i32 + (error_b * 3 / 48);
237 data[(width * 1 - 2) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
238 data[(width * 1 - 2) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
239 data[(width * 1 - 2) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
240 r = data[(width * 1 - 1) * 3 + 0] as i32 + (error_r * 5 / 48);
241 g = data[(width * 1 - 1) * 3 + 1] as i32 + (error_g * 5 / 48);
242 b = data[(width * 1 - 1) * 3 + 2] as i32 + (error_b * 5 / 48);
243 data[(width * 1 - 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
244 data[(width * 1 - 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
245 data[(width * 1 - 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
246 r = data[(width * 1 + 0) * 3 + 0] as i32 + (error_r * 7 / 48);
247 g = data[(width * 1 + 0) * 3 + 1] as i32 + (error_g * 7 / 48);
248 b = data[(width * 1 + 0) * 3 + 2] as i32 + (error_b * 7 / 48);
249 data[(width * 1 + 0) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
250 data[(width * 1 + 0) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
251 data[(width * 1 + 0) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
252 r = data[(width * 1 + 1) * 3 + 0] as i32 + (error_r * 5 / 48);
253 g = data[(width * 1 + 1) * 3 + 1] as i32 + (error_g * 5 / 48);
254 b = data[(width * 1 + 1) * 3 + 2] as i32 + (error_b * 5 / 48);
255 data[(width * 1 + 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
256 data[(width * 1 + 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
257 data[(width * 1 + 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
258 r = data[(width * 1 + 2) * 3 + 0] as i32 + (error_r * 3 / 48);
259 g = data[(width * 1 + 2) * 3 + 1] as i32 + (error_g * 3 / 48);
260 b = data[(width * 1 + 2) * 3 + 2] as i32 + (error_b * 3 / 48);
261 data[(width * 1 + 2) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
262 data[(width * 1 + 2) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
263 data[(width * 1 + 2) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
264 r = data[(width * 2 - 2) * 3 + 0] as i32 + (error_r * 1 / 48);
265 g = data[(width * 2 - 2) * 3 + 1] as i32 + (error_g * 1 / 48);
266 b = data[(width * 2 - 2) * 3 + 2] as i32 + (error_b * 1 / 48);
267 data[(width * 2 - 2) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
268 data[(width * 2 - 2) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
269 data[(width * 2 - 2) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
270 r = data[(width * 2 - 1) * 3 + 0] as i32 + (error_r * 3 / 48);
271 g = data[(width * 2 - 1) * 3 + 1] as i32 + (error_g * 3 / 48);
272 b = data[(width * 2 - 1) * 3 + 2] as i32 + (error_b * 3 / 48);
273 data[(width * 2 - 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
274 data[(width * 2 - 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
275 data[(width * 2 - 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
276 r = data[(width * 2 + 0) * 3 + 0] as i32 + (error_r * 5 / 48);
277 g = data[(width * 2 + 0) * 3 + 1] as i32 + (error_g * 5 / 48);
278 b = data[(width * 2 + 0) * 3 + 2] as i32 + (error_b * 5 / 48);
279 data[(width * 2 + 0) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
280 data[(width * 2 + 0) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
281 data[(width * 2 + 0) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
282 r = data[(width * 2 + 1) * 3 + 0] as i32 + (error_r * 3 / 48);
283 g = data[(width * 2 + 1) * 3 + 1] as i32 + (error_g * 3 / 48);
284 b = data[(width * 2 + 1) * 3 + 2] as i32 + (error_b * 3 / 48);
285 data[(width * 2 + 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
286 data[(width * 2 + 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
287 data[(width * 2 + 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
288 r = data[(width * 2 + 2) * 3 + 0] as i32 + (error_r * 1 / 48);
289 g = data[(width * 2 + 2) * 3 + 1] as i32 + (error_g * 1 / 48);
290 b = data[(width * 2 + 2) * 3 + 2] as i32 + (error_b * 1 / 48);
291 data[(width * 2 + 2) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
292 data[(width * 2 + 2) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
293 data[(width * 2 + 2) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
294}
295
296fn dither_stucki_15bpp(data: &mut [u8], width: i32) {
304 let mut error_r = data[0] as i32 & 0x7;
305 let mut error_g = data[1] as i32 & 0x7;
306 let mut error_b = data[2] as i32 & 0x7;
307 error_r += 4;
308 error_g += 4;
309 error_b += 4;
310 let width = width as usize;
311
312 let mut r = data[(width * 0 + 1) * 3 + 0] as i32 + (error_r * 8 / 48);
313 let mut g = data[(width * 0 + 1) * 3 + 1] as i32 + (error_g * 8 / 48);
314 let mut b = data[(width * 0 + 1) * 3 + 2] as i32 + (error_b * 8 / 48);
315 data[(width * 0 + 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
316 data[(width * 0 + 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
317 data[(width * 0 + 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
318 r = data[(width * 0 + 2) * 3 + 0] as i32 + (error_r * 4 / 48);
319 g = data[(width * 0 + 2) * 3 + 1] as i32 + (error_g * 4 / 48);
320 b = data[(width * 0 + 2) * 3 + 2] as i32 + (error_b * 4 / 48);
321 data[(width * 0 + 2) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
322 data[(width * 0 + 2) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
323 data[(width * 0 + 2) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
324 r = data[(width * 1 - 2) * 3 + 0] as i32 + (error_r * 2 / 48);
325 g = data[(width * 1 - 2) * 3 + 1] as i32 + (error_g * 2 / 48);
326 b = data[(width * 1 - 2) * 3 + 2] as i32 + (error_b * 2 / 48);
327 data[(width * 1 - 2) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
328 data[(width * 1 - 2) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
329 data[(width * 1 - 2) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
330 r = data[(width * 1 - 1) * 3 + 0] as i32 + (error_r * 4 / 48);
331 g = data[(width * 1 - 1) * 3 + 1] as i32 + (error_g * 4 / 48);
332 b = data[(width * 1 - 1) * 3 + 2] as i32 + (error_b * 4 / 48);
333 data[(width * 1 - 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
334 data[(width * 1 - 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
335 data[(width * 1 - 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
336 r = data[(width * 1 + 0) * 3 + 0] as i32 + (error_r * 8 / 48);
337 g = data[(width * 1 + 0) * 3 + 1] as i32 + (error_g * 8 / 48);
338 b = data[(width * 1 + 0) * 3 + 2] as i32 + (error_b * 8 / 48);
339 data[(width * 1 + 0) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
340 data[(width * 1 + 0) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
341 data[(width * 1 + 0) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
342 r = data[(width * 1 + 1) * 3 + 0] as i32 + (error_r * 4 / 48);
343 g = data[(width * 1 + 1) * 3 + 1] as i32 + (error_g * 4 / 48);
344 b = data[(width * 1 + 1) * 3 + 2] as i32 + (error_b * 4 / 48);
345 data[(width * 1 + 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
346 data[(width * 1 + 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
347 data[(width * 1 + 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
348 r = data[(width * 1 + 2) * 3 + 0] as i32 + (error_r * 2 / 48);
349 g = data[(width * 1 + 2) * 3 + 1] as i32 + (error_g * 2 / 48);
350 b = data[(width * 1 + 2) * 3 + 2] as i32 + (error_b * 2 / 48);
351 data[(width * 1 + 2) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
352 data[(width * 1 + 2) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
353 data[(width * 1 + 2) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
354 r = data[(width * 2 - 2) * 3 + 0] as i32 + (error_r * 1 / 48);
355 g = data[(width * 2 - 2) * 3 + 1] as i32 + (error_g * 1 / 48);
356 b = data[(width * 2 - 2) * 3 + 2] as i32 + (error_b * 1 / 48);
357 data[(width * 2 - 2) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
358 data[(width * 2 - 2) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
359 data[(width * 2 - 2) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
360 r = data[(width * 2 - 1) * 3 + 0] as i32 + (error_r * 2 / 48);
361 g = data[(width * 2 - 1) * 3 + 1] as i32 + (error_g * 2 / 48);
362 b = data[(width * 2 - 1) * 3 + 2] as i32 + (error_b * 2 / 48);
363 data[(width * 2 - 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
364 data[(width * 2 - 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
365 data[(width * 2 - 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
366 r = data[(width * 2 + 0) * 3 + 0] as i32 + (error_r * 4 / 48);
367 g = data[(width * 2 + 0) * 3 + 1] as i32 + (error_g * 4 / 48);
368 b = data[(width * 2 + 0) * 3 + 2] as i32 + (error_b * 4 / 48);
369 data[(width * 2 + 0) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
370 data[(width * 2 + 0) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
371 data[(width * 2 + 0) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
372 r = data[(width * 2 + 1) * 3 + 0] as i32 + (error_r * 2 / 48);
373 g = data[(width * 2 + 1) * 3 + 1] as i32 + (error_g * 2 / 48);
374 b = data[(width * 2 + 1) * 3 + 2] as i32 + (error_b * 2 / 48);
375 data[(width * 2 + 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
376 data[(width * 2 + 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
377 data[(width * 2 + 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
378 r = data[(width * 2 + 2) * 3 + 0] as i32 + (error_r * 1 / 48);
379 g = data[(width * 2 + 2) * 3 + 1] as i32 + (error_g * 1 / 48);
380 b = data[(width * 2 + 2) * 3 + 2] as i32 + (error_b * 1 / 48);
381 data[(width * 2 + 2) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
382 data[(width * 2 + 2) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
383 data[(width * 2 + 2) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
384}
385
386fn dither_burkes_15bpp(data: &mut [u8], width: i32) {
393 let mut error_r = data[0] as i32 & 0x7;
394 let mut error_g = data[1] as i32 & 0x7;
395 let mut error_b = data[2] as i32 & 0x7;
396 error_r += 2;
397 error_g += 2;
398 error_b += 2;
399 let width = width as usize;
400
401 let mut r = data[(width * 0 + 1) * 3 + 0] as i32 + (error_r * 4 / 16);
402 let mut g = data[(width * 0 + 1) * 3 + 1] as i32 + (error_g * 4 / 16);
403 let mut b = data[(width * 0 + 1) * 3 + 2] as i32 + (error_b * 4 / 16);
404 data[(width * 0 + 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
405 data[(width * 0 + 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
406 data[(width * 0 + 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
407 r = data[(width * 0 + 2) * 3 + 0] as i32 + (error_r * 2 / 16);
408 g = data[(width * 0 + 2) * 3 + 1] as i32 + (error_g * 2 / 16);
409 b = data[(width * 0 + 2) * 3 + 2] as i32 + (error_b * 2 / 16);
410 data[(width * 0 + 2) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
411 data[(width * 0 + 2) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
412 data[(width * 0 + 2) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
413 r = data[(width * 1 - 2) * 3 + 0] as i32 + (error_r * 1 / 16);
414 g = data[(width * 1 - 2) * 3 + 1] as i32 + (error_g * 1 / 16);
415 b = data[(width * 1 - 2) * 3 + 2] as i32 + (error_b * 1 / 16);
416 data[(width * 1 - 2) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
417 data[(width * 1 - 2) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
418 data[(width * 1 - 2) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
419 r = data[(width * 1 - 1) * 3 + 0] as i32 + (error_r * 2 / 16);
420 g = data[(width * 1 - 1) * 3 + 1] as i32 + (error_g * 2 / 16);
421 b = data[(width * 1 - 1) * 3 + 2] as i32 + (error_b * 2 / 16);
422 data[(width * 1 - 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
423 data[(width * 1 - 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
424 data[(width * 1 - 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
425 r = data[(width * 1 + 0) * 3 + 0] as i32 + (error_r * 4 / 16);
426 g = data[(width * 1 + 0) * 3 + 1] as i32 + (error_g * 4 / 16);
427 b = data[(width * 1 + 0) * 3 + 2] as i32 + (error_b * 4 / 16);
428 data[(width * 1 + 0) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
429 data[(width * 1 + 0) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
430 data[(width * 1 + 0) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
431 r = data[(width * 1 + 1) * 3 + 0] as i32 + (error_r * 2 / 16);
432 g = data[(width * 1 + 1) * 3 + 1] as i32 + (error_g * 2 / 16);
433 b = data[(width * 1 + 1) * 3 + 2] as i32 + (error_b * 2 / 16);
434 data[(width * 1 + 1) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
435 data[(width * 1 + 1) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
436 data[(width * 1 + 1) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
437 r = data[(width * 1 + 2) * 3 + 0] as i32 + (error_r * 1 / 16);
438 g = data[(width * 1 + 2) * 3 + 1] as i32 + (error_g * 1 / 16);
439 b = data[(width * 1 + 2) * 3 + 2] as i32 + (error_b * 1 / 16);
440 data[(width * 1 + 2) * 3 + 0] = if r > 0xff { 0xff } else { r as u8 };
441 data[(width * 1 + 2) * 3 + 1] = if g > 0xff { 0xff } else { g as u8 };
442 data[(width * 1 + 2) * 3 + 2] = if b > 0xff { 0xff } else { b as u8 };
443}
444
445fn dither_a_dither_15bpp(data: &mut [u8], _width: i32, x: i32, y: i32) {
451 for c in 0..3 {
452 let mask = (((x + c * 17) + y * 236) * 119) & 255;
453 let mask = (mask - 128) / 256;
454 let value = data[c as usize] as i32 + mask;
455 data[c as usize] = value.clamp(0, 255) as u8;
456 }
457}
458
459fn dither_x_dither_15bpp(data: &mut [u8], _width: i32, x: i32, y: i32) {
465 for c in 0..3 {
466 let mask = ((((x + c * 17) ^ y) * 236) * 1234) & 511;
467 let mask = (mask - 128) / 512;
468 let value = data[c as usize] as i32 + mask;
469 data[c as usize] = value.clamp(0, 255) as u8;
470 }
471}