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