Skip to main content

bayer/
bayer.rs

1//! Bayer image definitions.
2
3use std::io::Read;
4use byteorder::{BigEndian,LittleEndian,ReadBytesExt};
5
6use ::BayerResult;
7
8/// The 2x2 colour filter array (CFA) pattern.
9///
10/// The sequence of R, G, B describe the colours of the top-left,
11/// top-right, bottom-left, and bottom-right pixels in the 2x2 block,
12/// in that order.
13#[derive(Clone,Copy,Debug,Eq,PartialEq)]
14pub enum CFA {
15    BGGR,
16    GBRG,
17    GRBG,
18    RGGB,
19}
20
21/// The depth and endianness of the raw image.
22///
23/// Note that many cameras only capture 12-bits per pixel, but still
24/// store the data as 16-bits per pixel.  These should be treated as
25/// 16-bits per pixel for the purposes of this library.
26#[derive(Clone,Copy,Debug,Eq,PartialEq)]
27pub enum BayerDepth {
28    Depth8,
29    Depth16BE,
30    Depth16LE,
31}
32
33/// Trait for reading 8-bpp Bayer lines.
34pub trait BayerRead8 {
35    fn read_line(&self, r: &mut Read, dst: &mut [u8]) -> BayerResult<()>;
36}
37
38/// Trait for reading 16-bpp Bayer lines, big-endian or little-endian.
39pub trait BayerRead16 {
40    fn read_line(&self, r: &mut Read, dst: &mut [u16]) -> BayerResult<()>;
41}
42
43/// Read the exact number of bytes required to fill buf.
44/// For u8 source data.
45pub fn read_exact_u8(r: &mut Read, buf: &mut [u8])
46        -> BayerResult<()> {
47    r.read_exact(buf)?;
48    Ok(())
49}
50
51/// Read the exact number of bytes required to fill buf.
52/// For u16 big-endian source data.
53pub fn read_exact_u16be(r: &mut Read, buf: &mut [u16])
54        -> BayerResult<()> {
55    for i in 0..buf.len() {
56        buf[i] = r.read_u16::<BigEndian>()?;
57    }
58    Ok(())
59}
60
61/// Read the exact number of bytes required to fill buf.
62/// For u16 little-endian source data.
63pub fn read_exact_u16le(r: &mut Read, buf: &mut [u16])
64        -> BayerResult<()> {
65    for i in 0..buf.len() {
66        buf[i] = r.read_u16::<LittleEndian>()?;
67    }
68    Ok(())
69}
70
71impl CFA {
72    /// The 2x2 pixel block obtained when moving right 1 column.
73    pub fn next_x(self) -> Self {
74        match self {
75            CFA::BGGR => CFA::GBRG,
76            CFA::GBRG => CFA::BGGR,
77            CFA::GRBG => CFA::RGGB,
78            CFA::RGGB => CFA::GRBG,
79        }
80    }
81
82    /// The 2x2 pixel block obtained when moving down 1 row.
83    pub fn next_y(self) -> Self {
84        match self {
85            CFA::BGGR => CFA::GRBG,
86            CFA::GBRG => CFA::RGGB,
87            CFA::GRBG => CFA::BGGR,
88            CFA::RGGB => CFA::GBRG,
89        }
90    }
91}