1use std::io::Read;
4
5use ::{BayerDepth,BayerError,BayerResult,CFA,RasterMut};
6use bayer::{BayerRead8,BayerRead16};
7use border_none::*;
8use demosaic::check_depth;
9
10pub fn run(r: &mut Read,
11 depth: BayerDepth, cfa: CFA, dst: &mut RasterMut)
12 -> BayerResult<()> {
13 if dst.w < 2 || dst.h < 2 {
14 return Err(BayerError::WrongResolution);
15 }
16 if !check_depth(depth, dst.depth) {
17 return Err(BayerError::WrongDepth);
18 }
19
20 match depth {
21 BayerDepth::Depth8 => debayer_u8(r, cfa, dst),
22 BayerDepth::Depth16BE => debayer_u16(r, true, cfa, dst),
23 BayerDepth::Depth16LE => debayer_u16(r, false, cfa, dst),
24 }
25}
26
27macro_rules! apply_kernel_row {
28 ($row:ident, $curr:expr, $cfa:expr, $w:expr) => {{
29 for e in $row.iter_mut() {
30 *e = 0;
31 }
32
33 let (mut i, cfa_c) =
34 if $cfa == CFA::BGGR || $cfa == CFA::RGGB {
35 (0, $cfa)
36 } else {
37 apply_kernel_g!($row, $curr, 0);
38 (1, $cfa.next_x())
39 };
40
41 while i + 1 < $w {
42 apply_kernel_c!($row, $curr, cfa_c, i);
43 apply_kernel_g!($row, $curr, i + 1);
44 i = i + 2;
45 }
46
47 if i < $w {
48 apply_kernel_c!($row, $curr, cfa_c, i);
49 }
50 }}
51}
52
53macro_rules! apply_kernel_c {
54 ($row:ident, $curr:expr, $cfa:expr, $i:expr) => {{
55 if $cfa == CFA::BGGR {
56 $row[3 * $i + 2] = $curr[$i];
57 } else {
58 $row[3 * $i + 0] = $curr[$i];
59 }
60 }}
61}
62
63macro_rules! apply_kernel_g {
64 ($row:ident, $curr:expr, $i:expr) => {{
65 $row[3 * $i + 1] = $curr[$i];
66 }}
67}
68
69fn debayer_u8(r: &mut Read, cfa: CFA, dst: &mut RasterMut)
72 -> BayerResult<()> {
73 let (w, h) = (dst.w, dst.h);
74 let mut curr = vec![0u8; w];
75 let mut cfa = cfa;
76
77 let rdr = BorderNone8::new();
78
79 for y in 0..h {
80 let row = dst.borrow_row_u8_mut(y);
81 rdr.read_line(r, &mut curr)?;
82 apply_kernel_row!(row, curr, cfa, w);
83 cfa = cfa.next_y();
84 }
85
86 Ok(())
87}
88
89fn debayer_u16(r: &mut Read, be: bool, cfa: CFA, dst: &mut RasterMut)
90 -> BayerResult<()> {
91 let (w, h) = (dst.w, dst.h);
92 let mut curr = vec![0u16; w];
93 let mut cfa = cfa;
94
95 let rdr: Box<BayerRead16> = if be {
96 Box::new(BorderNone16BE::new())
97 } else {
98 Box::new(BorderNone16LE::new())
99 };
100
101 for y in 0..h {
102 let row = dst.borrow_row_u16_mut(y);
103 rdr.read_line(r, &mut curr)?;
104 apply_kernel_row!(row, curr, cfa, w);
105 cfa = cfa.next_y();
106 }
107
108 Ok(())
109}
110
111#[cfg(test)]
112mod tests {
113 use std::io::Cursor;
114 use ::{CFA,RasterDepth,RasterMut};
115 use super::debayer_u8;
116
117 #[test]
118 fn test_even() {
119 let src = [
121 229, 67, 95,146,
122 232, 51,229,241,
123 169,161, 15, 52,
124 45,175, 98,197 ];
125
126 let expected = [
127 229, 0, 0, 0, 67, 0, 95, 0, 0, 0,146, 0,
128 0,232, 0, 0, 0, 51, 0,229, 0, 0, 0,241,
129 169, 0, 0, 0,161, 0, 15, 0, 0, 0, 52 , 0,
130 0, 45, 0, 0, 0,175, 0, 98, 0, 0, 0,197 ];
131
132 const IMG_W: usize = 4;
133 const IMG_H: usize = 4;
134 let mut buf = [0u8; 3 * IMG_W * IMG_H];
135
136 let res = debayer_u8(&mut Cursor::new(&src[..]), CFA::RGGB,
137 &mut RasterMut::new(IMG_W, IMG_H, RasterDepth::Depth8, &mut buf));
138 assert!(res.is_ok());
139 assert_eq!(&buf[..], &expected[..]);
140 }
141
142 #[test]
143 fn test_odd() {
144 let src = [
146 229, 67, 95,
147 146,232, 51,
148 229,241,169 ];
149
150 let expected = [
151 229, 0, 0, 0, 67, 0, 95, 0, 0,
152 0,146, 0, 0, 0,232, 0, 51, 0,
153 229, 0, 0, 0,241, 0, 169, 0, 0 ];
154
155 const IMG_W: usize = 3;
156 const IMG_H: usize = 3;
157 let mut buf = [0u8; 3 * IMG_W * IMG_H];
158
159 let res = debayer_u8(&mut Cursor::new(&src[..]), CFA::RGGB,
160 &mut RasterMut::new(IMG_W, IMG_H, RasterDepth::Depth8, &mut buf));
161 assert!(res.is_ok());
162 assert_eq!(&buf[..], &expected[..]);
163 }
164}