move zigzag scan to common place
[nihav.git] / nihav-indeo / src / codecs / ivi.rs
CommitLineData
01c971c5
KS
1use super::ivibr::{IVICodebook,IVI_CB_ZERO,RVMap,IVI_ZERO_RVMAP,IVI_RVMAPS};
2
3pub 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)]
10pub enum IVIFrameType {
11 Intra,
12 Inter,
13 Bidir,
14 Intra1,
15 InterDroppable,
16 InterScal,
17 NULL,
18 NULL2,
19}
20
21impl 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)]
34pub 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
46impl 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 {
f2af8eca
KS
49 ftype,
50 width, height, slice_w, slice_h,
51 transparent,
52 luma_bands, chroma_bands,
53 in_q,
01c971c5
KS
54 }
55 }
56 pub fn new_null(ftype: IVIFrameType) -> Self {
57 PictureHeader {
f2af8eca 58 ftype,
01c971c5
KS
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)]
68pub enum TSize {
69 T8x8,
70 T4x4,
71}
72
73#[derive(Debug,Clone,Copy,PartialEq)]
74pub enum TDir {
75 TwoD,
76 Row,
77 Col,
78}
79
80#[derive(Debug,Clone,Copy,PartialEq)]
81pub enum IVITransformType {
82 Haar (TSize, TDir),
83 Slant(TSize, TDir),
84 DCT (TSize, TDir),
85 None (TSize),
86}
87
88pub type TrFunc = fn (&mut [i32; 64]);
89pub type TrFuncDC = fn (&mut [i32; 64], i32);
90
91impl IVITransformType {
f2af8eca
KS
92 pub fn is_8x8(self) -> bool {
93 match self {
01c971c5
KS
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 }
f2af8eca
KS
100 pub fn is_2d(self) -> bool {
101 match self {
01c971c5
KS
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)]
112pub struct TxParams4x4 {
113 pub quant_intra: &'static [u16; 16],
114 pub quant_inter: &'static [u16; 16],
115 pub scan: &'static [usize; 16],
116}
117
118impl TxParams4x4 {
119 pub fn new(quant_intra: &'static [u16; 16], quant_inter: &'static [u16; 16], scan: &'static [usize; 16]) -> Self {
120 TxParams4x4 {
f2af8eca 121 quant_intra, quant_inter, scan,
01c971c5
KS
122 }
123 }
124}
125
126#[allow(dead_code)]
127#[derive(Clone)]
128pub struct TxParams8x8 {
129 pub quant_intra: &'static [u16; 64],
130 pub quant_inter: &'static [u16; 64],
131 pub scan: &'static [usize; 64],
132}
133
134impl TxParams8x8 {
135 pub fn new(quant_intra: &'static [u16; 64], quant_inter: &'static [u16; 64], scan: &'static [usize; 64]) -> Self {
136 TxParams8x8 {
f2af8eca 137 quant_intra, quant_inter, scan,
01c971c5
KS
138 }
139 }
140}
141
142#[derive(Clone)]
143pub enum TxType {
144 Transform4(TxParams4x4),
145 Transform8(TxParams8x8),
146 None,
147}
148
149pub const CORR_MAP_SIZE: usize = 122;
150
151#[derive(Clone)]
152pub 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
169impl 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;
f2af8eca
KS
175 rvmap.runtab.swap(pos1, pos2);
176 rvmap.valtab.swap(pos1, pos2);
01c971c5
KS
177 }
178 BandHeader {
f2af8eca
KS
179 plane_no, band_no,
180 empty: false, halfpel,
181 inherit_mv,
182 has_qdelta, inherit_qd, quant,
183 mb_size, blk_size,
184 rvmap, blk_cb,
185 tr, ttype,
01c971c5
KS
186 }
187 }
188 pub fn new_empty(plane_no: usize, band_no: usize) -> Self {
189 BandHeader {
f2af8eca 190 plane_no, band_no,
01c971c5
KS
191 empty: true, halfpel: true,
192 inherit_mv: false, has_qdelta: false, inherit_qd: false, quant: 0,
193 mb_size: 0, blk_size: 0,
194 rvmap: IVI_ZERO_RVMAP, blk_cb: IVI_CB_ZERO,
195 tr: IVITransformType::None(TSize::T8x8), ttype: TxType::None,
196 }
197 }
198}
199
200#[derive(Debug,Clone,Copy,PartialEq)]
201pub enum MBType {
202 Intra,
203 Inter,
204 Backward,
205 Bidir,
206}
207
208#[derive(Clone,Copy)]
209pub struct MB {
210 pub mtype: MBType,
211 pub pos_x: usize,
212 pub pos_y: usize,
213 pub mv_x: i32,
214 pub mv_y: i32,
215 pub mv2_x: i32,
216 pub mv2_y: i32,
217 pub qd: i16,
218 pub q: u8,
219 pub cbp: u8,
220}
221
222impl MB {
223 pub fn new(x: usize, y: usize) -> Self {
224 MB {
225 mtype: MBType::Intra,
226 pos_x: x, pos_y: y,
227 mv_x: 0, mv_y: 0,
228 mv2_x: 0, mv2_y: 0,
229 cbp: 0, q: 0, qd: 0,
230 }
231 }
232}
233
234pub struct IVITile {
235 pub pos_x: usize,
236 pub pos_y: usize,
237 pub mb_w: usize,
238 pub mb_h: usize,
239 pub w: usize,
240 pub h: usize,
241 pub mb: Vec<MB>,
242}
243
244impl IVITile {
245 pub fn new(pos_x: usize, pos_y: usize, w: usize, h: usize) -> Self {
246 IVITile {
f2af8eca 247 pos_x, pos_y, w, h,
01c971c5
KS
248 mb_w: 0, mb_h: 0, mb: Vec::new(),
249 }
250 }
251}
252
01c971c5
KS
253pub const IVI_SCAN_8X8_VER: [usize; 64] = [
254 0, 8, 16, 24, 32, 40, 48, 56,
255 1, 9, 17, 25, 33, 41, 49, 57,
256 2, 10, 18, 26, 34, 42, 50, 58,
257 3, 11, 19, 27, 35, 43, 51, 59,
258 4, 12, 20, 28, 36, 44, 52, 60,
259 5, 13, 21, 29, 37, 45, 53, 61,
260 6, 14, 22, 30, 38, 46, 54, 62,
261 7, 15, 23, 31, 39, 47, 55, 63
262];
263pub const IVI_SCAN_8X8_HOR: [usize; 64] = [
264 0, 1, 2, 3, 4, 5, 6, 7,
265 8, 9, 10, 11, 12, 13, 14, 15,
266 16, 17, 18, 19, 20, 21, 22, 23,
267 24, 25, 26, 27, 28, 29, 30, 31,
268 32, 33, 34, 35, 36, 37, 38, 39,
269 40, 41, 42, 43, 44, 45, 46, 47,
270 48, 49, 50, 51, 52, 53, 54, 55,
271 56, 57, 58, 59, 60, 61, 62, 63
272];
273pub const IVI_SCAN_4X4: [usize; 16] = [ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 ];