1use std::io::Read;
16
17#[cfg(feature = "rayon")]
18use std::slice;
19
20#[cfg(feature = "rayon")]
21use rayon::prelude::*;
22
23use ::{BayerDepth,BayerError,BayerResult,CFA,RasterMut};
24use bayer::{BayerRead8,BayerRead16};
25use border_replicate::*;
26use demosaic::check_depth;
27
28const PADDING: usize = 1;
29
30pub fn run(r: &mut Read,
31 depth: BayerDepth, cfa: CFA, dst: &mut RasterMut)
32 -> BayerResult<()> {
33 if dst.w < 2 || dst.h < 2 {
34 return Err(BayerError::WrongResolution);
35 }
36 if !check_depth(depth, dst.depth) {
37 return Err(BayerError::WrongDepth);
38 }
39
40 match depth {
41 BayerDepth::Depth8 => debayer_u8(r, cfa, dst),
42 BayerDepth::Depth16BE => debayer_u16(r, true, cfa, dst),
43 BayerDepth::Depth16LE => debayer_u16(r, false, cfa, dst),
44 }
45}
46
47macro_rules! apply_kernel_row {
48 ($T:ty; $row:ident, $prev:expr, $curr:expr, $next:expr, $cfa:expr, $w:expr) => {{
49 let (mut i, cfa_c, cfa_g) =
50 if $cfa == CFA::BGGR || $cfa == CFA::RGGB {
51 (0, $cfa, $cfa.next_x())
52 } else {
53 apply_kernel_g!($T; $row, $prev, $curr, $next, $cfa, 0);
54 (1, $cfa.next_x(), $cfa)
55 };
56
57 while i + 1 < $w {
58 apply_kernel_c!($T; $row, $prev, $curr, $next, cfa_c, i);
59 apply_kernel_g!($T; $row, $prev, $curr, $next, cfa_g, i + 1);
60 i = i + 2;
61 }
62
63 if i < $w {
64 apply_kernel_c!($T; $row, $prev, $curr, $next, cfa_c, i);
65 }
66 }}
67}
68
69macro_rules! apply_kernel_c {
70 ($T:ty; $row:ident, $prev:expr, $curr:expr, $next:expr, $cfa:expr, $i:expr) => {{
71 let (c, d) = if $cfa == CFA::BGGR { (2, 0) } else { (0, 2) };
73 let j = $i + PADDING;
74
75 $row[3 * $i + c] = $curr[j];
76 $row[3 * $i + 1]
77 = (( $prev[j] as u32
78 + $curr[j - 1] as u32 + $curr[j + 1] as u32
79 + $next[j] as u32) / 4) as $T;
80 $row[3 * $i + d]
81 = (( $prev[j - 1] as u32 + $prev[j + 1] as u32
82 + $next[j - 1] as u32 + $next[j + 1] as u32) / 4) as $T;
83 }}
84}
85
86macro_rules! apply_kernel_g {
87 ($T:ty; $row:ident, $prev:expr, $curr:expr, $next:expr, $cfa:expr, $i:expr) => {{
88 let (h, v) = if $cfa == CFA::GBRG { (2, 0) } else { (0, 2) };
90 let j = $i + PADDING;
91
92 $row[3 * $i + h]
93 = (($curr[j - 1] as u32 + $curr[j + 1] as u32) / 2) as $T;
94 $row[3 * $i + 1] = $curr[j];
95 $row[3 * $i + v]
96 = (($prev[j] as u32 + $next[j] as u32) / 2) as $T;
97 }}
98}
99
100#[cfg(feature = "rayon")]
105fn debayer_u8(r: &mut Read, cfa: CFA, dst: &mut RasterMut)
106 -> BayerResult<()> {
107 let (w, h) = (dst.w, dst.h);
108 let mut data = vec![0u8; (2 * PADDING + w) * (2 * PADDING + h)];
109
110 {
112 let stride = 2 * PADDING + w;
113 let rdr = BorderReplicate8::new(w, PADDING);
114
115 for mut row in data.chunks_mut(stride).skip(PADDING).take(h) {
116 rdr.read_line(r, &mut row)?;
117 }
118
119 {
120 let (top, src) = data.split_at_mut(stride * PADDING);
121 top[(stride * 0)..(stride * 1)].copy_from_slice(
122 &src[(stride * 1)..(stride * 2)]);
123 }
124
125 {
126 let (src, bottom) = data.split_at_mut(stride * (h + PADDING));
127 let yy = PADDING + h;
128 bottom[(stride * 0)..(stride * 1)].copy_from_slice(
129 &src[(stride * (yy - 2))..(stride * (yy - 1))]);
130 }
131 }
132
133 dst.buf.par_chunks_mut(dst.stride).enumerate()
134 .for_each(|(y, mut row)| {
135 let stride = 2 * PADDING + w;
136 let prev = &data[(stride * (PADDING + y - 1)) .. (stride * (PADDING + y + 0))];
137 let curr = &data[(stride * (PADDING + y + 0)) .. (stride * (PADDING + y + 1))];
138 let next = &data[(stride * (PADDING + y + 1)) .. (stride * (PADDING + y + 2))];
139 let cfa_y = if y % 2 == 0 { cfa } else { cfa.next_y() };
140
141 apply_kernel_row!(u8; row, prev, curr, next, cfa_y, w);
142 });
143
144 Ok(())
145}
146
147#[cfg(feature = "rayon")]
148fn debayer_u16(r: &mut Read, be: bool, cfa: CFA, dst: &mut RasterMut)
149 -> BayerResult<()> {
150 let (w, h) = (dst.w, dst.h);
151 let mut data = vec![0u16; (2 * PADDING + w) * (2 * PADDING + h)];
152
153 {
155 let stride = 2 * PADDING + w;
156 let rdr: Box<BayerRead16> = if be {
157 Box::new(BorderReplicate16BE::new(w, PADDING))
158 } else {
159 Box::new(BorderReplicate16LE::new(w, PADDING))
160 };
161
162 for mut row in data.chunks_mut(stride).skip(PADDING).take(h) {
163 rdr.read_line(r, &mut row)?;
164 }
165
166 {
167 let (top, src) = data.split_at_mut(stride * PADDING);
168 top[(stride * 0)..(stride * 1)].copy_from_slice(
169 &src[(stride * 1)..(stride * 2)]);
170 }
171
172 {
173 let (src, bottom) = data.split_at_mut(stride * (h + PADDING));
174 let yy = PADDING + h;
175 bottom[(stride * 0)..(stride * 1)].copy_from_slice(
176 &src[(stride * (yy - 2))..(stride * (yy - 1))]);
177 }
178 }
179
180 dst.buf.par_chunks_mut(dst.stride).enumerate()
181 .for_each(|(y, mut row)| {
182 let stride = 2 * PADDING + w;
183 let prev = &data[(stride * (PADDING + y - 1)) .. (stride * (PADDING + y + 0))];
184 let curr = &data[(stride * (PADDING + y + 0)) .. (stride * (PADDING + y + 1))];
185 let next = &data[(stride * (PADDING + y + 1)) .. (stride * (PADDING + y + 2))];
186 let cfa_y = if y % 2 == 0 { cfa } else { cfa.next_y() };
187
188 let row16 = unsafe{ slice::from_raw_parts_mut(row.as_mut_ptr() as *mut u16, row.len() / 2) };
189 apply_kernel_row!(u16; row16, prev, curr, next, cfa_y, w);
190 });
191
192 Ok(())
193}
194
195#[cfg(not(feature = "rayon"))]
200fn debayer_u8(r: &mut Read, cfa: CFA, dst: &mut RasterMut)
201 -> BayerResult<()> {
202 let (w, h) = (dst.w, dst.h);
203 let mut prev = vec![0u8; 2 * PADDING + w];
204 let mut curr = vec![0u8; 2 * PADDING + w];
205 let mut next = vec![0u8; 2 * PADDING + w];
206 let mut cfa = cfa;
207
208 let rdr = BorderReplicate8::new(w, PADDING);
209 rdr.read_line(r, &mut curr)?;
210 rdr.read_line(r, &mut next)?;
211
212 { let row = dst.borrow_row_u8_mut(0);
214 apply_kernel_row!(u8; row, next, curr, next, cfa, w);
215 cfa = cfa.next_y();
216 }
217
218 for y in 1..(h - 1) {
219 rotate!(prev <- curr <- next);
220 rdr.read_line(r, &mut next)?;
221
222 let row = dst.borrow_row_u8_mut(y);
223 apply_kernel_row!(u8; row, prev, curr, next, cfa, w);
224 cfa = cfa.next_y();
225 }
226
227 { let row = dst.borrow_row_u8_mut(h - 1);
229 apply_kernel_row!(u8; row, curr, next, curr, cfa, w);
230 }
231
232 Ok(())
233}
234
235#[cfg(not(feature = "rayon"))]
236fn debayer_u16(r: &mut Read, be: bool, cfa: CFA, dst: &mut RasterMut)
237 -> BayerResult<()> {
238 let (w, h) = (dst.w, dst.h);
239 let mut prev = vec![0u16; 2 * PADDING + w];
240 let mut curr = vec![0u16; 2 * PADDING + w];
241 let mut next = vec![0u16; 2 * PADDING + w];
242 let mut cfa = cfa;
243
244 let rdr: Box<BayerRead16> = if be {
245 Box::new(BorderReplicate16BE::new(w, PADDING))
246 } else {
247 Box::new(BorderReplicate16LE::new(w, PADDING))
248 };
249 rdr.read_line(r, &mut curr)?;
250 rdr.read_line(r, &mut next)?;
251
252 { let row = dst.borrow_row_u16_mut(0);
254 apply_kernel_row!(u16; row, next, curr, next, cfa, w);
255 cfa = cfa.next_y();
256 }
257
258 for y in 1..(h - 1) {
259 rotate!(prev <- curr <- next);
260 rdr.read_line(r, &mut next)?;
261
262 let row = dst.borrow_row_u16_mut(y);
263 apply_kernel_row!(u16; row, prev, curr, next, cfa, w);
264 cfa = cfa.next_y();
265 }
266
267 { let row = dst.borrow_row_u16_mut(h - 1);
269 apply_kernel_row!(u16; row, curr, next, curr, cfa, w);
270 }
271
272 Ok(())
273}
274
275#[cfg(test)]
276mod tests {
277 use std::io::Cursor;
278 use ::{CFA,RasterDepth,RasterMut};
279 use super::debayer_u8;
280
281 #[test]
282 fn test_even() {
283 let src = [
285 229, 67, 95,146,
286 232, 51,229,241,
287 169,161, 15, 52,
288 45,175, 98,197 ];
289
290 let expected = [
291 229,149, 51, 162, 67, 51, 95,167,146, 95,146,241,
292 199,232, 51, 127,172, 51, 55,229,146, 55,164,241,
293 169,149,113, 92,161,113, 15,135,166, 15, 52,219,
294 169, 45,175, 92,116,175, 15, 98,186, 15, 75,197 ];
295
296 const IMG_W: usize = 4;
297 const IMG_H: usize = 4;
298 let mut dst = [0u8; 3 * IMG_W * IMG_H];
299
300 let res = debayer_u8(&mut Cursor::new(&src[..]), CFA::RGGB,
301 &mut RasterMut::new(IMG_W, IMG_H, RasterDepth::Depth8, &mut dst[..]));
302 assert!(res.is_ok());
303 assert_eq!(&dst[..], &expected[..]);
304 }
305
306 #[test]
307 fn test_odd() {
308 let src = [
310 229, 67, 95,
311 146,232, 51,
312 229,241,169 ];
313
314 let expected = [
315 229,106,232, 162, 67,232, 95, 59,232,
316 229,146,232, 180,126,232, 132, 51,232,
317 229,193,232, 199,241,232, 169,146,232 ];
318
319 const IMG_W: usize = 3;
320 const IMG_H: usize = 3;
321 let mut buf = [0u8; 3 * IMG_W * IMG_H];
322
323 let res = debayer_u8(&mut Cursor::new(&src[..]), CFA::RGGB,
324 &mut RasterMut::new(IMG_W, IMG_H, RasterDepth::Depth8, &mut buf));
325 assert!(res.is_ok());
326 assert_eq!(&buf[..], &expected[..]);
327 }
328}