1use VFrame;
8use std::collections::VecDeque;
9use std::mem::transmute;
10
11#[derive(Copy, Clone, PartialEq)] #[repr(u8)]
13pub enum ColorChannels {
14 Grayscale = 1u8,
16 Rgb = 3u8,
18 Rgba = 4u8,
20 Bgr = 8u8,
22 Bgra = 9u8,
24 YCbCr = 13u8,
26}
27
28impl Default for ColorChannels {
29 fn default() -> ColorChannels { Rgba }
30}
31
32pub use ColorChannels::*;
33
34impl ColorChannels {
35 pub fn from(self, from: ColorChannels, p: [u8; 4]) -> [u8; 4] {
37 if self == from {
38 p
39 } else {
40 self.rgba_to(from.to_rgba(p))
41 }
42 }
43
44 pub fn pack(p: [u8; 4]) -> u32 {
46 let r = (p[0] as u32).rotate_right(0);
47 let g = (p[1] as u32).rotate_right(8);
48 let b = (p[2] as u32).rotate_right(16);
49 let a = (p[3] as u32).rotate_right(24);
50
51 r | g | b | a
52 }
53
54 pub fn unpack(p: u32) -> [u8; 4] {
56 unsafe {
57 transmute(p)
58 }
59 }
60
61 fn rgba_to(self, p: [u8; 4]) -> [u8; 4] {
63 let [r, g, b, a] = p;
64 match self {
65 Grayscale => {
66 let gray = (r as u16 + g as u16 + b as u16) / 3;
67 [gray as u8, 255, 255, 255]
68 },
69 Rgb => [r, g, b, 255],
70 Rgba => [r, g, b, a],
71 Bgr => [b, g, r, 255],
72 Bgra => [b, g, r, a],
73 YCbCr => {
75 let [r, g, b] = [r as f64, g as f64, b as f64];
76 let y = (0.299 * r) + (0.587 * g) + (0.114 * b);
77 let cb = 128.0 - (0.168736 * r) - (0.331264 * g)
78 + (0.5 * b);
79 let cr = 128.0 + (0.5 * r) - (0.418688 * g)
80 - (0.081312 * b);
81 [y as u8, cb as u8, cr as u8, 255]
82 }
83 }
84 }
85
86 fn to_rgba(self, p: [u8; 4]) -> [u8; 4] {
88 let [r, g, b, a] = p;
89 match self {
90 Grayscale => [r, r, r, r],
91 Rgb => [r, g, b, 255],
92 Rgba => [r, g, b, a],
93 Bgr => [b, g, r, 255],
94 Bgra => [b, g, r, a],
95 YCbCr => {
97 let [y, cb, cr] = [r as f64, g as f64, b as f64];
98 let r = y + 1.402 * (cr - 128.0);
99 let g = y - 0.344136 * (cb - 128.0) - 0.714136 *
100 (cr - 128.0);
101 let b = y + 1.772 * (cb - 128.0);
102 [r as u8, g as u8, b as u8, 255]
103 }
104 }
105 }
106
107 pub fn n_channels(self) -> usize {
109 (self as u8 % 5) as usize
110 }
111}
112
113pub struct Video {
115 format: ColorChannels,
116 wh: (u16, u16),
117 n_frames: u32, frames: VecDeque<VFrame>,
119}
120
121impl Video {
122 pub fn new(format: ColorChannels, wh: (u16, u16), n_frames: u32) -> Self
124 {
125 Video {
126 wh, n_frames, format, frames: VecDeque::new(),
127 }
128 }
129
130 pub fn wh(&self) -> (u16, u16) {
132 self.wh
133 }
134
135 pub fn format(&self) -> ColorChannels {
137 self.format
138 }
139
140 pub fn add(&mut self, data: VFrame) {
142 self.frames.push_back(data);
143 }
144
145 pub fn len(&self) -> u32 {
147 self.frames.len() as u32
148 }
149
150 pub fn pop(&mut self) -> Option<VFrame> {
152 Some(self.frames.pop_front()?)
153 }
154
155 pub fn n_channels(&self) -> usize {
157 self.format.n_channels()
158 }
159
160 pub fn frames(&self) -> u32 {
162 self.n_frames
163 }
164}