move zigzag scan to common place
[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,
50 width, height, slice_w, slice_h,
51 transparent,
52 luma_bands, chroma_bands,
53 in_q,
54 }
55 }
56 pub fn new_null(ftype: IVIFrameType) -> Self {
57 PictureHeader {
58 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_inter, 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_inter, 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 rvmap.runtab.swap(pos1, pos2);
176 rvmap.valtab.swap(pos1, pos2);
177 }
178 BandHeader {
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,
186 }
187 }
188 pub fn new_empty(plane_no: usize, band_no: usize) -> Self {
189 BandHeader {
190 plane_no, band_no,
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)]
201 pub enum MBType {
202 Intra,
203 Inter,
204 Backward,
205 Bidir,
206 }
207
208 #[derive(Clone,Copy)]
209 pub 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
222 impl 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
234 pub 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
244 impl IVITile {
245 pub fn new(pos_x: usize, pos_y: usize, w: usize, h: usize) -> Self {
246 IVITile {
247 pos_x, pos_y, w, h,
248 mb_w: 0, mb_h: 0, mb: Vec::new(),
249 }
250 }
251 }
252
253 pub 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 ];
263 pub 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 ];
273 pub const IVI_SCAN_4X4: [usize; 16] = [ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 ];