1use std::cmp::min;
24use std::io::Read;
25
26#[cfg(feature = "rayon")]
27use std::slice;
28
29#[cfg(feature = "rayon")]
30use rayon::prelude::*;
31
32use ::{BayerDepth,BayerError,BayerResult,CFA,RasterMut};
33use bayer::{BayerRead8,BayerRead16};
34use border_mirror::*;
35use demosaic::check_depth;
36
37const PADDING: usize = 3;
38
39pub fn run(r: &mut Read,
40 depth: BayerDepth, cfa: CFA, dst: &mut RasterMut)
41 -> BayerResult<()> {
42 if dst.w < 4 || dst.h < 4 {
43 return Err(BayerError::WrongResolution);
44 }
45 if !check_depth(depth, dst.depth) {
46 return Err(BayerError::WrongDepth);
47 }
48
49 match depth {
50 BayerDepth::Depth8 => debayer_u8(r, cfa, dst),
51 BayerDepth::Depth16BE => debayer_u16(r, true, cfa, dst),
52 BayerDepth::Depth16LE => debayer_u16(r, false, cfa, dst),
53 }
54}
55
56macro_rules! apply_kernel_row {
57 ($T:ident; $row:ident,
58 $prv3:expr, $prv2:expr, $prv1:expr, $curr:expr,
59 $nxt1:expr, $nxt2:expr, $nxt3:expr,
60 $cfa:expr, $w:expr) => {{
61 let (mut i, cfa_c, cfa_g) =
62 if $cfa == CFA::BGGR || $cfa == CFA::RGGB {
63 (0, $cfa, $cfa.next_x())
64 } else {
65 apply_kernel_g!($T; $row, $w, $prv3, $prv2, $prv1, $curr, $nxt1, $nxt2, $nxt3, $cfa, 0);
66 (1, $cfa.next_x(), $cfa)
67 };
68
69 while i + 1 < $w {
70 apply_kernel_c!($T; $row, $w, $prv3, $prv2, $prv1, $curr, $nxt1, $nxt2, $nxt3, cfa_c, i);
71 apply_kernel_g!($T; $row, $w, $prv3, $prv2, $prv1, $curr, $nxt1, $nxt2, $nxt3, cfa_g, i + 1);
72 i = i + 2;
73 }
74
75 if i < $w {
76 apply_kernel_c!($T; $row, $w, $prv3, $prv2, $prv1, $curr, $nxt1, $nxt2, $nxt3, cfa_c, i);
77 }
78 }}
79}
80
81macro_rules! apply_kernel_c {
82 ($T:ident; $row:ident, $w:expr,
83 $prv3:expr, $prv2:expr, $prv1:expr, $curr:expr,
84 $nxt1:expr, $nxt2:expr, $nxt3:expr,
85 $cfa:expr, $i:expr) => {{
86 let (c, d) = if $cfa == CFA::BGGR { (2, 0) } else { (0, 2) };
88 let j = $i + PADDING;
89
90 let g_pos
91 = ( $prv1[j] as u32
92 + $curr[j - 1] as u32 + $curr[j + 1] as u32
93 + $nxt1[j] as u32) * 81
94 + ( $prv3[j] as u32
95 + $curr[j - 3] as u32 + $curr[j + 3] as u32
96 + $nxt3[j] as u32);
97 let g_neg
98 = ( $prv2[j - 1] as u32 + $prv2[j + 1] as u32
99 + $prv1[j - 2] as u32 + $prv1[j + 2] as u32
100 + $nxt1[j - 2] as u32 + $nxt1[j + 2] as u32
101 + $nxt2[j - 1] as u32 + $nxt2[j + 1] as u32) * 9;
102
103 let d_pos
104 = ( $prv1[j - 1] as u32 + $prv1[j + 1] as u32
105 + $nxt1[j - 1] as u32 + $nxt1[j + 1] as u32) * 81
106 + ( $prv3[j - 3] as u32 + $prv3[j + 3] as u32
107 + $nxt3[j - 3] as u32 + $nxt3[j + 3] as u32);
108 let d_neg
109 = ( $prv3[j - 1] as u32 + $prv3[j + 1] as u32
110 + $prv1[j - 3] as u32 + $prv1[j + 3] as u32
111 + $nxt1[j - 3] as u32 + $nxt1[j + 3] as u32
112 + $nxt3[j - 1] as u32 + $nxt3[j + 1] as u32) * 9;
113
114 $row[3 * $i + c] = $curr[j];
115 $row[3 * $i + 1]
116 = min(g_pos.saturating_sub(g_neg) / 256,
117 $T::max_value() as u32) as $T;
118 $row[3 * $i + d]
119 = min(d_pos.saturating_sub(d_neg) / 256,
120 $T::max_value() as u32) as $T;
121 }}
122}
123
124macro_rules! apply_kernel_g {
125 ($T:ident; $row:ident, $w:expr,
126 $prv3:expr, $prv2:expr, $prv1:expr, $curr:expr,
127 $nxt1:expr, $nxt2:expr, $nxt3:expr,
128 $cfa:expr, $i:expr) => {{
129 let (h, v) = if $cfa == CFA::GBRG { (2, 0) } else { (0, 2) };
131 let j = $i + PADDING;
132
133 let h_pos = ($curr[j - 1] as u32 + $curr[j + 1] as u32) * 9;
134 let h_neg = ($curr[j - 3] as u32 + $curr[j + 3] as u32);
135 let v_pos = ($prv1[j] as u32 + $nxt1[j] as u32) * 9;
136 let v_neg = ($prv3[j] as u32 + $nxt3[j] as u32);
137
138 $row[3 * $i + h]
139 = min(h_pos.saturating_sub(h_neg) / 16,
140 $T::max_value() as u32) as $T;
141 $row[3 * $i + 1] = $curr[j];
142 $row[3 * $i + v]
143 = min(v_pos.saturating_sub(v_neg) / 16,
144 $T::max_value() as u32) as $T;
145 }}
146}
147
148#[cfg(feature = "rayon")]
153#[allow(unused_parens)]
154fn debayer_u8(r: &mut Read, cfa: CFA, dst: &mut RasterMut)
155 -> BayerResult<()> {
156 let (w, h) = (dst.w, dst.h);
157 let mut data = vec![0u8; (2 * PADDING + w) * (2 * PADDING + h)];
158
159 {
161 let stride = 2 * PADDING + w;
162 let rdr = BorderMirror8::new(w, PADDING);
163 for mut row in data.chunks_mut(stride).skip(PADDING).take(h) {
164 rdr.read_line(r, &mut row)?;
165 }
166
167 {
168 let (top, src) = data.split_at_mut(stride * PADDING);
169 top[(stride * 0)..(stride * 1)].copy_from_slice(&src[(stride * 3)..(stride * 4)]);
170 top[(stride * 1)..(stride * 2)].copy_from_slice(&src[(stride * 2)..(stride * 3)]);
171 top[(stride * 2)..(stride * 3)].copy_from_slice(&src[(stride * 1)..(stride * 2)]);
172 }
173
174 {
175 let (src, bottom) = data.split_at_mut(stride * (h + PADDING));
176 let yy = PADDING + h;
177 bottom[(stride * 0)..(stride * 1)].copy_from_slice(&src[(stride * (yy - 2))..(stride * (yy - 1))]);
178 bottom[(stride * 1)..(stride * 2)].copy_from_slice(&src[(stride * (yy - 3))..(stride * (yy - 2))]);
179 bottom[(stride * 2)..(stride * 3)].copy_from_slice(&src[(stride * (yy - 4))..(stride * (yy - 3))]);
180 }
181 }
182
183 dst.buf.par_chunks_mut(dst.stride).enumerate()
184 .for_each(|(y, mut row)| {
185 let stride = 2 * PADDING + w;
186 let prv3 = &data[(stride * (PADDING + y - 3)) .. (stride * (PADDING + y - 2))];
187 let prv2 = &data[(stride * (PADDING + y - 2)) .. (stride * (PADDING + y - 1))];
188 let prv1 = &data[(stride * (PADDING + y - 1)) .. (stride * (PADDING + y + 0))];
189 let curr = &data[(stride * (PADDING + y + 0)) .. (stride * (PADDING + y + 1))];
190 let nxt1 = &data[(stride * (PADDING + y + 1)) .. (stride * (PADDING + y + 2))];
191 let nxt2 = &data[(stride * (PADDING + y + 2)) .. (stride * (PADDING + y + 3))];
192 let nxt3 = &data[(stride * (PADDING + y + 3)) .. (stride * (PADDING + y + 4))];
193 let cfa_y = if y % 2 == 0 { cfa } else { cfa.next_y() };
194
195 apply_kernel_row!(u8; row, prv3, prv2, prv1, curr, nxt1, nxt2, nxt3, cfa_y, w);
196 });
197
198 Ok(())
199}
200
201#[cfg(feature = "rayon")]
202#[allow(unused_parens)]
203fn debayer_u16(r: &mut Read, be: bool, cfa: CFA, dst: &mut RasterMut)
204 -> BayerResult<()> {
205 let (w, h) = (dst.w, dst.h);
206 let mut data = vec![0u16; (2 * PADDING + w) * (2 * PADDING + h)];
207
208 {
210 let stride = 2 * PADDING + w;
211 let rdr: Box<BayerRead16> = if be {
212 Box::new(BorderMirror16BE::new(w, PADDING))
213 } else {
214 Box::new(BorderMirror16LE::new(w, PADDING))
215 };
216
217 for mut row in data.chunks_mut(stride).skip(PADDING).take(h) {
218 rdr.read_line(r, &mut row)?;
219 }
220
221 {
222 let (top, src) = data.split_at_mut(stride * PADDING);
223 top[(stride * 0)..(stride * 1)].copy_from_slice(&src[(stride * 3)..(stride * 4)]);
224 top[(stride * 1)..(stride * 2)].copy_from_slice(&src[(stride * 2)..(stride * 3)]);
225 top[(stride * 2)..(stride * 3)].copy_from_slice(&src[(stride * 1)..(stride * 2)]);
226 }
227
228 {
229 let (src, bottom) = data.split_at_mut(stride * (h + PADDING));
230 let yy = PADDING + h;
231 bottom[(stride * 0)..(stride * 1)].copy_from_slice(&src[(stride * (yy - 2))..(stride * (yy - 1))]);
232 bottom[(stride * 1)..(stride * 2)].copy_from_slice(&src[(stride * (yy - 3))..(stride * (yy - 2))]);
233 bottom[(stride * 2)..(stride * 3)].copy_from_slice(&src[(stride * (yy - 4))..(stride * (yy - 3))]);
234 }
235 }
236
237 dst.buf.par_chunks_mut(dst.stride).enumerate()
238 .for_each(|(y, mut row)| {
239 let stride = 2 * PADDING + w;
240 let prv3 = &data[(stride * (PADDING + y - 3)) .. (stride * (PADDING + y - 2))];
241 let prv2 = &data[(stride * (PADDING + y - 2)) .. (stride * (PADDING + y - 1))];
242 let prv1 = &data[(stride * (PADDING + y - 1)) .. (stride * (PADDING + y + 0))];
243 let curr = &data[(stride * (PADDING + y + 0)) .. (stride * (PADDING + y + 1))];
244 let nxt1 = &data[(stride * (PADDING + y + 1)) .. (stride * (PADDING + y + 2))];
245 let nxt2 = &data[(stride * (PADDING + y + 2)) .. (stride * (PADDING + y + 3))];
246 let nxt3 = &data[(stride * (PADDING + y + 3)) .. (stride * (PADDING + y + 4))];
247 let cfa_y = if y % 2 == 0 { cfa } else { cfa.next_y() };
248
249 let row16 = unsafe{ slice::from_raw_parts_mut(row.as_mut_ptr() as *mut u16, row.len() / 2) };
250 apply_kernel_row!(u16; row16, prv3, prv2, prv1, curr, nxt1, nxt2, nxt3, cfa_y, w);
251 });
252
253 Ok(())
254}
255
256#[cfg(not(feature = "rayon"))]
261#[allow(unused_parens)]
262fn debayer_u8(r: &mut Read, cfa: CFA, dst: &mut RasterMut)
263 -> BayerResult<()> {
264 let (w, h) = (dst.w, dst.h);
265 let mut prv3 = vec![0u8; 2 * PADDING + w];
266 let mut prv2 = vec![0u8; 2 * PADDING + w];
267 let mut prv1 = vec![0u8; 2 * PADDING + w];
268 let mut curr = vec![0u8; 2 * PADDING + w];
269 let mut nxt1 = vec![0u8; 2 * PADDING + w];
270 let mut nxt2 = vec![0u8; 2 * PADDING + w];
271 let mut nxt3 = vec![0u8; 2 * PADDING + w];
272 let mut cfa = cfa;
273
274 let rdr = BorderMirror8::new(w, PADDING);
275 rdr.read_line(r, &mut curr)?;
276 rdr.read_line(r, &mut nxt1)?;
277 rdr.read_line(r, &mut nxt2)?;
278 rdr.read_line(r, &mut nxt3)?;
279
280 prv1.copy_from_slice(&nxt1);
281 prv2.copy_from_slice(&nxt2);
282 prv3.copy_from_slice(&nxt3);
283
284 { let row = dst.borrow_row_u8_mut(0);
286 apply_kernel_row!(u8; row, nxt3, nxt2, nxt1, curr, nxt1, nxt2, nxt3, cfa, w);
287 cfa = cfa.next_y();
288 }
289
290 for y in 1..(h - 3) {
291 rotate!(prv3 <- prv2 <- prv1 <- curr <- nxt1 <- nxt2 <- nxt3);
292 rdr.read_line(r, &mut nxt3)?;
293
294 let row = dst.borrow_row_u8_mut(y);
295 apply_kernel_row!(u8; row, prv3, prv2, prv1, curr, nxt1, nxt2, nxt3, cfa, w);
296 cfa = cfa.next_y();
297 }
298
299 { let row = dst.borrow_row_u8_mut(h - 3);
301 apply_kernel_row!(u8; row, prv2, prv1, curr, nxt1, nxt2, nxt3, nxt2, cfa, w);
302 cfa = cfa.next_y();
303 }
304
305 { let row = dst.borrow_row_u8_mut(h - 2);
307 apply_kernel_row!(u8; row, prv1, curr, nxt1, nxt2, nxt3, nxt2, nxt1, cfa, w);
308 cfa = cfa.next_y();
309 }
310
311 { let row = dst.borrow_row_u8_mut(h - 1);
313 apply_kernel_row!(u8; row, curr, nxt1, nxt2, nxt3, nxt2, nxt1, curr, cfa, w);
314 }
315
316 Ok(())
317}
318
319#[cfg(not(feature = "rayon"))]
320#[allow(unused_parens)]
321fn debayer_u16(r: &mut Read, be: bool, cfa: CFA, dst: &mut RasterMut)
322 -> BayerResult<()> {
323 let (w, h) = (dst.w, dst.h);
324 let mut prv3 = vec![0u16; 2 * PADDING + w];
325 let mut prv2 = vec![0u16; 2 * PADDING + w];
326 let mut prv1 = vec![0u16; 2 * PADDING + w];
327 let mut curr = vec![0u16; 2 * PADDING + w];
328 let mut nxt1 = vec![0u16; 2 * PADDING + w];
329 let mut nxt2 = vec![0u16; 2 * PADDING + w];
330 let mut nxt3 = vec![0u16; 2 * PADDING + w];
331 let mut cfa = cfa;
332
333 let rdr: Box<BayerRead16> = if be {
334 Box::new(BorderMirror16BE::new(w, PADDING))
335 } else {
336 Box::new(BorderMirror16LE::new(w, PADDING))
337 };
338 rdr.read_line(r, &mut curr)?;
339 rdr.read_line(r, &mut nxt1)?;
340 rdr.read_line(r, &mut nxt2)?;
341 rdr.read_line(r, &mut nxt3)?;
342
343 prv1.copy_from_slice(&nxt1);
344 prv2.copy_from_slice(&nxt2);
345 prv3.copy_from_slice(&nxt3);
346
347 { let row = dst.borrow_row_u16_mut(0);
349 apply_kernel_row!(u16; row, nxt3, nxt2, nxt1, curr, nxt1, nxt2, nxt3, cfa, w);
350 cfa = cfa.next_y();
351 }
352
353 for y in 1..(h - 3) {
354 rotate!(prv3 <- prv2 <- prv1 <- curr <- nxt1 <- nxt2 <- nxt3);
355 rdr.read_line(r, &mut nxt3)?;
356
357 let row = dst.borrow_row_u16_mut(y);
358 apply_kernel_row!(u16; row, prv3, prv2, prv1, curr, nxt1, nxt2, nxt3, cfa, w);
359 cfa = cfa.next_y();
360 }
361
362 { let row = dst.borrow_row_u16_mut(h - 3);
364 apply_kernel_row!(u16; row, prv2, prv1, curr, nxt1, nxt2, nxt3, nxt2, cfa, w);
365 cfa = cfa.next_y();
366 }
367
368 { let row = dst.borrow_row_u16_mut(h - 2);
370 apply_kernel_row!(u16; row, prv1, curr, nxt1, nxt2, nxt3, nxt2, nxt1, cfa, w);
371 cfa = cfa.next_y();
372 }
373
374 { let row = dst.borrow_row_u16_mut(h - 1);
376 apply_kernel_row!(u16; row, curr, nxt1, nxt2, nxt3, nxt2, nxt1, curr, cfa, w);
377 }
378
379 Ok(())
380}
381
382#[cfg(test)]
383mod tests {
384 use std::io::Cursor;
385 use ::{CFA,RasterDepth,RasterMut};
386 use super::debayer_u8;
387
388 #[test]
389 fn test_even() {
390 let src = [
392 229, 67, 95,146,232, 51,229,241,
393 169,161, 15, 52, 45,175, 98,197,
394 127,183,253, 97,199,239, 54,166,
395 32, 68, 98, 3, 97,222, 87,123,
396 153,126, 47,211,171,203, 27,185,
397 105,210,165,200,141,135,202, 5,
398 122,187,177,122,220,112, 62, 18,
399 25, 80,132,169,104,233, 75,117 ];
400
401 let expected = [
402 229,122,186, 161, 67,172, 95, 43,108, 155,146, 58, 232, 61,104, 239, 51,169, 229,117,196, 228,241,206,
403 182,169,174, 177,110,161, 177, 15, 98, 201, 70, 52, 219, 45,105, 189,104,175, 154, 98,195, 145,159,197,
404 127,159,116, 185,183,105, 253, 95, 48, 242, 97, 15, 199,121,106, 123,239,203, 54,153,195, 35,166,167,
405 135, 32, 76, 140,103, 68, 151, 98, 21, 176,121, 3, 179, 97,114, 105,159,222, 27, 87,180, 8,115,123,
406 153, 80,146, 98,126,141, 47,157,116, 111,211,100, 171,168,142, 106,203,175, 27,179,110, 9,185, 52,
407 139,105,211, 115,154,210, 99,165,209, 153,167,200, 193,141,175, 124,179,135, 42,202, 57, 23,160, 5,
408 122,118,139, 143,187,145, 177,158,170, 211,122,194, 220,110,200, 143,112,184, 62, 94,114, 42, 18, 60,
409 118, 25, 68, 148,129, 80, 193,132,120, 224,111,169, 226,104,213, 148, 95,233, 66, 75,171, 46, 16,117 ];
410
411 const IMG_W: usize = 8;
412 const IMG_H: usize = 8;
413 let mut buf = [0u8; 3 * IMG_W * IMG_H];
414
415 let res = debayer_u8(&mut Cursor::new(&src[..]), CFA::RGGB,
416 &mut RasterMut::new(IMG_W, IMG_H, RasterDepth::Depth8, &mut buf));
417 assert!(res.is_ok());
418 assert_eq!(&buf[..], &expected[..]);
419 }
420
421 #[test]
422 fn test_odd() {
423 let src = [
425 229, 67, 95,146,232, 51,229,
426 241,169,161, 15, 52, 45,175,
427 98,197,127,183,253, 97,199,
428 239, 54,166, 32, 68, 98, 3,
429 97,222, 87,123,153,126, 47,
430 211,171,203, 27,185,105,210,
431 165,200,141,135,202, 5,122 ];
432
433 let expected = [
434 229,147,204, 161, 67,183, 95,123, 96, 155,146, 12, 232, 52, 14, 238, 51, 38, 229,123, 41,
435 171,241,188, 136,163,169, 111,161, 90, 177,144, 15, 247, 52, 20, 243, 93, 45, 225,175, 48,
436 98,236,114, 102,197,104, 127,185, 61, 195,183, 23, 253, 95, 42, 230, 97, 71, 199, 99, 76,
437 85,239, 56, 88,208, 54, 105,166, 38, 160,129, 32, 201, 68, 63, 159, 53, 98, 116, 3,106,
438 97,231,114, 88,222,105, 87,178, 63, 126,123, 30, 153,125, 63, 97,126,104, 47,124,114,
439 135,211,189, 122,214,171, 114,203, 94, 149,165, 27, 174,185, 57, 124,138,105, 79,210,114,
440 165,203,205, 150,200,185, 141,184,101, 175,135, 26, 202,116, 56, 160, 5,105, 122, 93,115 ];
441
442 const IMG_W: usize = 7;
443 const IMG_H: usize = 7;
444 let mut buf = [0u8; 3 * IMG_W * IMG_H];
445
446 let res = debayer_u8(&mut Cursor::new(&src[..]), CFA::RGGB,
447 &mut RasterMut::new(IMG_W, IMG_H, RasterDepth::Depth8, &mut buf));
448 assert!(res.is_ok());
449 assert_eq!(&buf[..], &expected[..]);
450 }
451
452 #[test]
453 fn test_overflow() {
454 let src = [
455 255,255,255,255,255,255,255,
456 255,255,255,255,255,255,255,
457 255,255,255, 0,255,255,255,
458 255,255, 0, 0, 0,255,255,
459 255,255,255, 0,255,255,255,
460 255,255,255,255,255,255,255,
461 255,255,255,255,255,255,255 ];
462
463 let expected = [
464 255,255,251, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,251,
465 255,255,255, 255,255,255, 255,255,255, 255,190,255, 255,255,255, 255,255,255, 255,255,255,
466 255,255,255, 255,255,255, 255,111,174, 255, 0,111, 255,111,174, 255,255,255, 255,255,255,
467 255,255,255, 255,190,255, 255, 0,111, 255, 0, 0, 255, 0,111, 255,190,255, 255,255,255,
468 255,255,255, 255,255,255, 255,111,174, 255, 0,111, 255,111,174, 255,255,255, 255,255,255,
469 255,255,255, 255,255,255, 255,255,255, 255,190,255, 255,255,255, 255,255,255, 255,255,255,
470 255,255,251, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,251 ];
471
472 const IMG_W: usize = 7;
473 const IMG_H: usize = 7;
474 let mut buf = [0u8; 3 * IMG_W * IMG_H];
475
476 let res = debayer_u8(&mut Cursor::new(&src[..]), CFA::RGGB,
477 &mut RasterMut::new(IMG_W, IMG_H, RasterDepth::Depth8, &mut buf));
478 assert!(res.is_ok());
479 assert_eq!(&buf[..], &expected[..]);
480 }
481}