split NihAV into subcrates
[nihav.git] / nihav-indeo / src / codecs / ivi.rs
1 use super::ivibr::{IVICodebook,IVI_CB_ZERO,RVMap,IVI_ZERO_RVMAP,IVI_RVMAPS};
2
3 pub fn clip8(a: i16) -> u8 {
4 if a < 0 { 0 }
5 else if a > 255 { 255 }
6 else { a as u8 }
7 }
8
9 #[derive(Debug,Clone,Copy,PartialEq)]
10 pub enum IVIFrameType {
11 Intra,
12 Inter,
13 Bidir,
14 Intra1,
15 InterDroppable,
16 InterScal,
17 NULL,
18 NULL2,
19 }
20
21 impl IVIFrameType {
22 pub fn is_intra(self) -> bool {
23 (self == IVIFrameType::Intra) || (self == IVIFrameType::Intra1)
24 }
25 pub fn is_null(self) -> bool {
26 (self == IVIFrameType::NULL) || (self == IVIFrameType::NULL2)
27 }
28 pub fn is_bidir(self) -> bool {
29 self == IVIFrameType::Bidir
30 }
31 }
32
33 #[derive(Clone,Copy)]
34 pub struct PictureHeader {
35 pub ftype: IVIFrameType,
36 pub width: usize,
37 pub height: usize,
38 pub slice_w: usize,
39 pub slice_h: usize,
40 pub transparent: bool,
41 pub luma_bands: usize,
42 pub chroma_bands: usize,
43 pub in_q: bool,
44 }
45
46 impl PictureHeader {
47 pub fn new(ftype: IVIFrameType, width: usize, height: usize, slice_w: usize, slice_h: usize, transparent: bool, luma_bands: usize, chroma_bands: usize, in_q: bool) -> Self {
48 PictureHeader {
49 ftype: ftype,
50 width: width, height: height, slice_w: slice_w, slice_h: slice_h,
51 transparent: transparent,
52 luma_bands: luma_bands, chroma_bands: chroma_bands,
53 in_q: in_q,
54 }
55 }
56 pub fn new_null(ftype: IVIFrameType) -> Self {
57 PictureHeader {
58 ftype: ftype,
59 width: 0, height: 0, slice_w: 0, slice_h: 0,
60 transparent: false,
61 luma_bands: 0, chroma_bands: 0,
62 in_q: false,
63 }
64 }
65 }
66
67 #[derive(Debug,Clone,Copy,PartialEq)]
68 pub enum TSize {
69 T8x8,
70 T4x4,
71 }
72
73 #[derive(Debug,Clone,Copy,PartialEq)]
74 pub enum TDir {
75 TwoD,
76 Row,
77 Col,
78 }
79
80 #[derive(Debug,Clone,Copy,PartialEq)]
81 pub enum IVITransformType {
82 Haar (TSize, TDir),
83 Slant(TSize, TDir),
84 DCT (TSize, TDir),
85 None (TSize),
86 }
87
88 pub type TrFunc = fn (&mut [i32; 64]);
89 pub type TrFuncDC = fn (&mut [i32; 64], i32);
90
91 impl IVITransformType {
92 pub fn is_8x8(&self) -> bool {
93 match *self {
94 IVITransformType::Haar (ref sz, _) => { *sz == TSize::T8x8 },
95 IVITransformType::Slant(ref sz, _) => { *sz == TSize::T8x8 },
96 IVITransformType::DCT (ref sz, _) => { *sz == TSize::T8x8 },
97 IVITransformType::None (ref sz) => { *sz == TSize::T8x8 },
98 }
99 }
100 pub fn is_2d(&self) -> bool {
101 match *self {
102 IVITransformType::Haar (_, ref dir) => { *dir == TDir::TwoD },
103 IVITransformType::Slant(_, ref dir) => { *dir == TDir::TwoD },
104 IVITransformType::DCT (_, ref dir) => { *dir == TDir::TwoD },
105 _ => { false },
106 }
107 }
108 }
109
110 #[allow(dead_code)]
111 #[derive(Clone)]
112 pub struct TxParams4x4 {
113 pub quant_intra: &'static [u16; 16],
114 pub quant_inter: &'static [u16; 16],
115 pub scan: &'static [usize; 16],
116 }
117
118 impl TxParams4x4 {
119 pub fn new(quant_intra: &'static [u16; 16], quant_inter: &'static [u16; 16], scan: &'static [usize; 16]) -> Self {
120 TxParams4x4 {
121 quant_intra: quant_intra, quant_inter: quant_inter, scan: scan,
122 }
123 }
124 }
125
126 #[allow(dead_code)]
127 #[derive(Clone)]
128 pub struct TxParams8x8 {
129 pub quant_intra: &'static [u16; 64],
130 pub quant_inter: &'static [u16; 64],
131 pub scan: &'static [usize; 64],
132 }
133
134 impl TxParams8x8 {
135 pub fn new(quant_intra: &'static [u16; 64], quant_inter: &'static [u16; 64], scan: &'static [usize; 64]) -> Self {
136 TxParams8x8 {
137 quant_intra: quant_intra, quant_inter: quant_inter, scan: scan,
138 }
139 }
140 }
141
142 #[derive(Clone)]
143 pub enum TxType {
144 Transform4(TxParams4x4),
145 Transform8(TxParams8x8),
146 None,
147 }
148
149 pub const CORR_MAP_SIZE: usize = 122;
150
151 #[derive(Clone)]
152 pub struct BandHeader {
153 pub plane_no: usize,
154 pub band_no: usize,
155 pub empty: bool,
156 pub mb_size: usize,
157 pub blk_size: usize,
158 pub halfpel: bool,
159 pub inherit_mv: bool,
160 pub has_qdelta: bool,
161 pub inherit_qd: bool,
162 pub quant: u32,
163 pub blk_cb: IVICodebook,
164 pub rvmap: RVMap,
165 pub tr: IVITransformType,
166 pub ttype: TxType,
167 }
168
169 impl BandHeader {
170 pub fn new(plane_no: usize, band_no: usize, mb_size: usize, blk_size: usize, halfpel: bool, inherit_mv: bool, has_qdelta: bool, inherit_qd: bool, quant: u32, rvmap_idx: usize, num_corr: usize, corr_map: [u8; CORR_MAP_SIZE], blk_cb: IVICodebook, tr: IVITransformType, ttype: TxType) -> Self {
171 let mut rvmap = IVI_RVMAPS[rvmap_idx].clone();
172 for i in 0..num_corr {
173 let pos1 = corr_map[i * 2 + 0] as usize;
174 let pos2 = corr_map[i * 2 + 1] as usize;
175 let t = rvmap.runtab[pos1];
176 rvmap.runtab[pos1] = rvmap.runtab[pos2];
177 rvmap.runtab[pos2] = t;
178 let t = rvmap.valtab[pos1];
179 rvmap.valtab[pos1] = rvmap.valtab[pos2];
180 rvmap.valtab[pos2] = t;
181 }
182 BandHeader {
183 plane_no: plane_no, band_no: band_no,
184 empty: false, halfpel: halfpel,
185 inherit_mv: inherit_mv,
186 has_qdelta: has_qdelta, inherit_qd: inherit_qd, quant: quant,
187 mb_size: mb_size, blk_size: blk_size,
188 rvmap: rvmap, blk_cb: blk_cb,
189 tr: tr, ttype: ttype,
190 }
191 }
192 pub fn new_empty(plane_no: usize, band_no: usize) -> Self {
193 BandHeader {
194 plane_no: plane_no, band_no: band_no,
195 empty: true, halfpel: true,
196 inherit_mv: false, has_qdelta: false, inherit_qd: false, quant: 0,
197 mb_size: 0, blk_size: 0,
198 rvmap: IVI_ZERO_RVMAP, blk_cb: IVI_CB_ZERO,
199 tr: IVITransformType::None(TSize::T8x8), ttype: TxType::None,
200 }
201 }
202 }
203
204 #[derive(Debug,Clone,Copy,PartialEq)]
205 pub enum MBType {
206 Intra,
207 Inter,
208 Backward,
209 Bidir,
210 }
211
212 #[derive(Clone,Copy)]
213 pub struct MB {
214 pub mtype: MBType,
215 pub pos_x: usize,
216 pub pos_y: usize,
217 pub mv_x: i32,
218 pub mv_y: i32,
219 pub mv2_x: i32,
220 pub mv2_y: i32,
221 pub qd: i16,
222 pub q: u8,
223 pub cbp: u8,
224 }
225
226 impl MB {
227 pub fn new(x: usize, y: usize) -> Self {
228 MB {
229 mtype: MBType::Intra,
230 pos_x: x, pos_y: y,
231 mv_x: 0, mv_y: 0,
232 mv2_x: 0, mv2_y: 0,
233 cbp: 0, q: 0, qd: 0,
234 }
235 }
236 }
237
238 pub struct IVITile {
239 pub pos_x: usize,
240 pub pos_y: usize,
241 pub mb_w: usize,
242 pub mb_h: usize,
243 pub w: usize,
244 pub h: usize,
245 pub mb: Vec<MB>,
246 }
247
248 impl IVITile {
249 pub fn new(pos_x: usize, pos_y: usize, w: usize, h: usize) -> Self {
250 IVITile {
251 pos_x: pos_x, pos_y: pos_y, w: w, h: h,
252 mb_w: 0, mb_h: 0, mb: Vec::new(),
253 }
254 }
255 }
256
257 pub const IVI_ZIGZAG: [usize; 64] = [
258 0, 1, 8, 16, 9, 2, 3, 10,
259 17, 24, 32, 25, 18, 11, 4, 5,
260 12, 19, 26, 33, 40, 48, 41, 34,
261 27, 20, 13, 6, 7, 14, 21, 28,
262 35, 42, 49, 56, 57, 50, 43, 36,
263 29, 22, 15, 23, 30, 37, 44, 51,
264 58, 59, 52, 45, 38, 31, 39, 46,
265 53, 60, 61, 54, 47, 55, 62, 63
266 ];
267 pub const IVI_SCAN_8X8_VER: [usize; 64] = [
268 0, 8, 16, 24, 32, 40, 48, 56,
269 1, 9, 17, 25, 33, 41, 49, 57,
270 2, 10, 18, 26, 34, 42, 50, 58,
271 3, 11, 19, 27, 35, 43, 51, 59,
272 4, 12, 20, 28, 36, 44, 52, 60,
273 5, 13, 21, 29, 37, 45, 53, 61,
274 6, 14, 22, 30, 38, 46, 54, 62,
275 7, 15, 23, 31, 39, 47, 55, 63
276 ];
277 pub const IVI_SCAN_8X8_HOR: [usize; 64] = [
278 0, 1, 2, 3, 4, 5, 6, 7,
279 8, 9, 10, 11, 12, 13, 14, 15,
280 16, 17, 18, 19, 20, 21, 22, 23,
281 24, 25, 26, 27, 28, 29, 30, 31,
282 32, 33, 34, 35, 36, 37, 38, 39,
283 40, 41, 42, 43, 44, 45, 46, 47,
284 48, 49, 50, 51, 52, 53, 54, 55,
285 56, 57, 58, 59, 60, 61, 62, 63
286 ];
287 pub const IVI_SCAN_4X4: [usize; 16] = [ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 ];