]> git.nihav.org Git - nihav.git/blobdiff - src/formats.rs
improve bit reading functionality
[nihav.git] / src / formats.rs
index 3f7ae7fb2fd610c3b7b432e82cbe2b800805bd34..bc23d1ebaf35235cd133d66cc36c63accfc09133 100644 (file)
@@ -1,7 +1,7 @@
 use std::string::*;
 use std::fmt;
 
-#[derive(Debug,Copy,Clone)]
+#[derive(Debug,Copy,Clone,PartialEq)]
 pub struct NASoniton {
     bits:       u8,
     be:         bool,
@@ -11,27 +11,23 @@ pub struct NASoniton {
     signed:     bool,
 }
 
-bitflags! {
-    pub flags SonitonFlags: u8 {
-        const SONITON_FLAG_BE       = 0x01,
-        const SONITON_FLAG_PACKED   = 0x02,
-        const SONITON_FLAG_PLANAR   = 0x04,
-        const SONITON_FLAG_FLOAT    = 0x08,
-        const SONITON_FLAG_SIGNED   = 0x10,
-    }
-}
+pub const SONITON_FLAG_BE     :u32 = 0x01;
+pub const SONITON_FLAG_PACKED :u32 = 0x02;
+pub const SONITON_FLAG_PLANAR :u32 = 0x04;
+pub const SONITON_FLAG_FLOAT  :u32 = 0x08;
+pub const SONITON_FLAG_SIGNED :u32 = 0x10;
 
 pub const SND_U8_FORMAT: NASoniton = NASoniton { bits: 8, be: false, packed: false, planar: false, float: false, signed: false };
 pub const SND_S16_FORMAT: NASoniton = NASoniton { bits: 16, be: false, packed: false, planar: false, float: false, signed: true };
-pub const SND_F32_FORMAT: NASoniton = NASoniton { bits: 32, be: false, packed: false, planar: false, float: true, signed: true };
+pub const SND_F32P_FORMAT: NASoniton = NASoniton { bits: 32, be: false, packed: false, planar: true, float: true, signed: true };
 
 impl NASoniton {
-    pub fn new(bits: u8, flags: SonitonFlags) -> Self {
-        let is_be = (flags.bits & SONITON_FLAG_BE.bits) != 0;
-        let is_pk = (flags.bits & SONITON_FLAG_PACKED.bits) != 0;
-        let is_pl = (flags.bits & SONITON_FLAG_PLANAR.bits) != 0;
-        let is_fl = (flags.bits & SONITON_FLAG_FLOAT.bits) != 0;
-        let is_sg = (flags.bits & SONITON_FLAG_SIGNED.bits) != 0;
+    pub fn new(bits: u8, flags: u32) -> Self {
+        let is_be = (flags & SONITON_FLAG_BE) != 0;
+        let is_pk = (flags & SONITON_FLAG_PACKED) != 0;
+        let is_pl = (flags & SONITON_FLAG_PLANAR) != 0;
+        let is_fl = (flags & SONITON_FLAG_FLOAT) != 0;
+        let is_sg = (flags & SONITON_FLAG_SIGNED) != 0;
         NASoniton { bits: bits, be: is_be, packed: is_pk, planar: is_pl, float: is_fl, signed: is_sg }
     }
 
@@ -41,6 +37,14 @@ impl NASoniton {
     pub fn is_planar(&self) -> bool { self.planar }
     pub fn is_float(&self)  -> bool { self.float }
     pub fn is_signed(&self) -> bool { self.signed }
+
+    pub fn get_audio_size(&self, length: u64) -> usize {
+        if self.packed {
+            ((length * (self.bits as u64) + 7) >> 3) as usize
+        } else {
+            (length * (((self.bits + 7) >> 3) as u64)) as usize
+        }
+    }
 }
 
 impl fmt::Display for NASoniton {
@@ -51,7 +55,7 @@ impl fmt::Display for NASoniton {
     }
 }
 
-#[derive(Debug,Clone,Copy)]
+#[derive(Debug,Clone,Copy,PartialEq)]
 pub enum NAChannelType {
     C, L, R, Cs, Ls, Rs, Lss, Rss, LFE, Lc, Rc, Lh, Rh, Ch, LFE2, Lw, Rw, Ov, Lhs, Rhs, Chs, Ll, Rl, Cl, Lt, Rt, Lo, Ro
 }
@@ -124,6 +128,7 @@ impl fmt::Display for NAChannelType {
     }
 }
 
+#[derive(Clone)]
 pub struct NAChannelMap {
     ids: Vec<NAChannelType>,
 }
@@ -133,6 +138,11 @@ impl NAChannelMap {
     pub fn add_channel(&mut self, ch: NAChannelType) {
         self.ids.push(ch);
     }
+    pub fn add_channels(&mut self, chs: &[NAChannelType]) {
+        for i in 0..chs.len() {
+            self.ids.push(chs[i]);
+        }
+    }
     pub fn num_channels(&self) -> usize {
         self.ids.len()
     }
@@ -147,7 +157,7 @@ impl NAChannelMap {
     }
 }
 
-#[derive(Debug,Clone,Copy)]
+#[derive(Debug,Clone,Copy,PartialEq)]
 pub enum RGBSubmodel {
     RGB,
     SRGB,
@@ -163,7 +173,7 @@ impl fmt::Display for RGBSubmodel {
     }
 }
 
-#[derive(Debug,Clone,Copy)]
+#[derive(Debug,Clone,Copy,PartialEq)]
 pub enum YUVSubmodel {
     YCbCr,
     YIQ,
@@ -181,7 +191,7 @@ impl fmt::Display for YUVSubmodel {
     }
 }
 
-#[derive(Debug, Clone,Copy)]
+#[derive(Debug, Clone,Copy,PartialEq)]
 pub enum ColorModel {
     RGB(RGBSubmodel),
     YUV(YUVSubmodel),
@@ -214,7 +224,7 @@ impl fmt::Display for ColorModel {
     }
 }
 
-#[derive(Clone,Copy)]
+#[derive(Clone,Copy,PartialEq)]
 pub struct NAPixelChromaton {
     h_ss:           u8,
     v_ss:           u8,
@@ -225,16 +235,12 @@ pub struct NAPixelChromaton {
     next_elem:      u8,
 }
 
-bitflags! {
-    pub flags FormatonFlags: u8 {
-        const FORMATON_FLAG_BE       = 0x01,
-        const FORMATON_FLAG_ALPHA    = 0x02,
-        const FORMATON_FLAG_PALETTE  = 0x04,
-    }
-}
+pub const FORMATON_FLAG_BE      :u32 = 0x01;
+pub const FORMATON_FLAG_ALPHA   :u32 = 0x02;
+pub const FORMATON_FLAG_PALETTE :u32 = 0x04;
 
 
-#[derive(Clone,Copy)]
+#[derive(Clone,Copy,PartialEq)]
 pub struct NAPixelFormaton {
     model:      ColorModel,
     components: u8,
@@ -268,6 +274,22 @@ pub const YUV420_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::
                                             None, None],
                                         elem_size: 0, be: false, alpha: false, palette: false };
 
+pub const YUV410_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::YUV(YUVSubmodel::YUVJ), components: 3,
+                                        comp_info: [
+                                            chromaton!(0, 0, false, 8, 0, 0, 1),
+                                            chromaton!(yuv8; 2, 2, 1),
+                                            chromaton!(yuv8; 2, 2, 2),
+                                            None, None],
+                                        elem_size: 0, be: false, alpha: false, palette: false };
+pub const YUVA410_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::YUV(YUVSubmodel::YUVJ), components: 4,
+                                        comp_info: [
+                                            chromaton!(0, 0, false, 8, 0, 0, 1),
+                                            chromaton!(yuv8; 2, 2, 1),
+                                            chromaton!(yuv8; 2, 2, 2),
+                                            chromaton!(0, 0, false, 8, 0, 3, 1),
+                                            None],
+                                        elem_size: 0, be: false, alpha: true, palette: false };
+
 pub const PAL8_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::RGB(RGBSubmodel::RGB), components: 3,
                                         comp_info: [
                                             chromaton!(pal8; 0),
@@ -284,6 +306,14 @@ pub const RGB565_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::
                                             None, None],
                                         elem_size: 2, be: false, alpha: false, palette: false };
 
+pub const RGB24_FORMAT: NAPixelFormaton = NAPixelFormaton { model: ColorModel::RGB(RGBSubmodel::RGB), components: 3,
+                                        comp_info: [
+                                            chromaton!(packrgb; 8, 0, 2, 3),
+                                            chromaton!(packrgb; 8, 0, 1, 3),
+                                            chromaton!(packrgb; 8, 0, 0, 3),
+                                            None, None],
+                                        elem_size: 3, be: false, alpha: false, palette: false };
+
 impl NAPixelChromaton {
     pub fn get_subsampling(&self) -> (u8, u8) { (self.h_ss, self.v_ss) }
     pub fn is_packed(&self) -> bool { self.packed }
@@ -291,6 +321,25 @@ impl NAPixelChromaton {
     pub fn get_shift(&self) -> u8   { self.shift }
     pub fn get_offset(&self) -> u8  { self.comp_offs }
     pub fn get_step(&self)  -> u8   { self.next_elem }
+
+    pub fn get_width(&self, width: usize) -> usize {
+        (width  + ((1 << self.h_ss) - 1)) >> self.h_ss
+    }
+    pub fn get_height(&self, height: usize) -> usize {
+        (height + ((1 << self.v_ss) - 1)) >> self.v_ss
+    }
+    pub fn get_linesize(&self, width: usize) -> usize {
+        let d = self.depth as usize;
+        if self.packed {
+            (self.get_width(width) * d + d - 1) >> 3
+        } else {
+            self.get_width(width)
+        }
+    }
+    pub fn get_data_size(&self, width: usize, height: usize) -> usize {
+        let nh = (height + ((1 << self.v_ss) - 1)) >> self.v_ss;
+        self.get_linesize(width) * nh
+    }
 }
 
 impl fmt::Display for NAPixelChromaton {
@@ -312,12 +361,12 @@ impl NAPixelFormaton {
                comp3: Option<NAPixelChromaton>,
                comp4: Option<NAPixelChromaton>,
                comp5: Option<NAPixelChromaton>,
-               flags: FormatonFlags, elem_size: u8) -> Self {
+               flags: u32, elem_size: u8) -> Self {
         let mut chromatons: [Option<NAPixelChromaton>; 5] = [None; 5];
         let mut ncomp = 0;
-        let be      = (flags.bits & FORMATON_FLAG_BE.bits)      != 0;
-        let alpha   = (flags.bits & FORMATON_FLAG_ALPHA.bits)   != 0;
-        let palette = (flags.bits & FORMATON_FLAG_PALETTE.bits) != 0;
+        let be      = (flags & FORMATON_FLAG_BE)      != 0;
+        let alpha   = (flags & FORMATON_FLAG_ALPHA)   != 0;
+        let palette = (flags & FORMATON_FLAG_PALETTE) != 0;
         if let Some(c) = comp1 { chromatons[0] = Some(c); ncomp += 1; }
         if let Some(c) = comp2 { chromatons[1] = Some(c); ncomp += 1; }
         if let Some(c) = comp3 { chromatons[2] = Some(c); ncomp += 1; }
@@ -331,7 +380,7 @@ impl NAPixelFormaton {
     }
 
     pub fn get_model(&self) -> ColorModel { self.model }
-    pub fn get_num_comp(&self) -> u8 { self.components }
+    pub fn get_num_comp(&self) -> usize { self.components as usize }
     pub fn get_chromaton(&self, idx: usize) -> Option<NAPixelChromaton> {
         if idx < self.comp_info.len() { return self.comp_info[idx]; }
         None
@@ -365,7 +414,7 @@ mod test {
     fn test_fmt() {
         println!("{}", SND_S16_FORMAT);
         println!("{}", SND_U8_FORMAT);
-        println!("{}", SND_F32_FORMAT);
+        println!("{}", SND_F32P_FORMAT);
         println!("formaton yuv- {}", YUV420_FORMAT);
         println!("formaton pal- {}", PAL8_FORMAT);
         println!("formaton rgb565- {}", RGB565_FORMAT);