]> git.nihav.org Git - nihav.git/blob - nihav-indeo/src/codecs/indeo2.rs
c03d2c226c4bf685e81c6d2779d73e15fe2139fd
[nihav.git] / nihav-indeo / src / codecs / indeo2.rs
1 use std::rc::Rc;
2 use std::cell::RefCell;
3 use nihav_core::io::bitreader::*;
4 use nihav_core::io::codebook::*;
5 use nihav_core::formats;
6 use nihav_core::codecs::*;
7
8 static INDEO2_DELTA_TABLE: [[u8; 256]; 4] = [
9 [
10 0x80, 0x80, 0x84, 0x84, 0x7C, 0x7C, 0x7F, 0x85,
11 0x81, 0x7B, 0x85, 0x7F, 0x7B, 0x81, 0x8C, 0x8C,
12 0x74, 0x74, 0x83, 0x8D, 0x7D, 0x73, 0x8D, 0x83,
13 0x73, 0x7D, 0x77, 0x89, 0x89, 0x77, 0x89, 0x77,
14 0x77, 0x89, 0x8C, 0x95, 0x74, 0x6B, 0x95, 0x8C,
15 0x6B, 0x74, 0x7C, 0x90, 0x84, 0x70, 0x90, 0x7C,
16 0x70, 0x84, 0x96, 0x96, 0x6A, 0x6A, 0x82, 0x98,
17 0x7E, 0x68, 0x98, 0x82, 0x68, 0x7E, 0x97, 0xA2,
18 0x69, 0x5E, 0xA2, 0x97, 0x5E, 0x69, 0xA2, 0xA2,
19 0x5E, 0x5E, 0x8B, 0xA3, 0x75, 0x5D, 0xA3, 0x8B,
20 0x5D, 0x75, 0x71, 0x95, 0x8F, 0x6B, 0x95, 0x71,
21 0x6B, 0x8F, 0x78, 0x9D, 0x88, 0x63, 0x9D, 0x78,
22 0x63, 0x88, 0x7F, 0xA7, 0x81, 0x59, 0xA7, 0x7F,
23 0x59, 0x81, 0xA4, 0xB1, 0x5C, 0x4F, 0xB1, 0xA4,
24 0x4F, 0x5C, 0x96, 0xB1, 0x6A, 0x4F, 0xB1, 0x96,
25 0x4F, 0x6A, 0xB2, 0xB2, 0x4E, 0x4E, 0x65, 0x9B,
26 0x9B, 0x65, 0x9B, 0x65, 0x65, 0x9B, 0x89, 0xB4,
27 0x77, 0x4C, 0xB4, 0x89, 0x4C, 0x77, 0x6A, 0xA3,
28 0x96, 0x5D, 0xA3, 0x6A, 0x5D, 0x96, 0x73, 0xAC,
29 0x8D, 0x54, 0xAC, 0x73, 0x54, 0x8D, 0xB4, 0xC3,
30 0x4C, 0x3D, 0xC3, 0xB4, 0x3D, 0x4C, 0xA4, 0xC3,
31 0x5C, 0x3D, 0xC3, 0xA4, 0x3D, 0x5C, 0xC4, 0xC4,
32 0x3C, 0x3C, 0x96, 0xC6, 0x6A, 0x3A, 0xC6, 0x96,
33 0x3A, 0x6A, 0x7C, 0xBA, 0x84, 0x46, 0xBA, 0x7C,
34 0x46, 0x84, 0x5B, 0xAB, 0xA5, 0x55, 0xAB, 0x5B,
35 0x55, 0xA5, 0x63, 0xB4, 0x9D, 0x4C, 0xB4, 0x63,
36 0x4C, 0x9D, 0x86, 0xCA, 0x7A, 0x36, 0xCA, 0x86,
37 0x36, 0x7A, 0xB6, 0xD7, 0x4A, 0x29, 0xD7, 0xB6,
38 0x29, 0x4A, 0xC8, 0xD7, 0x38, 0x29, 0xD7, 0xC8,
39 0x29, 0x38, 0xA4, 0xD8, 0x5C, 0x28, 0xD8, 0xA4,
40 0x28, 0x5C, 0x6C, 0xC1, 0x94, 0x3F, 0xC1, 0x6C,
41 0x3F, 0x94, 0xD9, 0xD9, 0x27, 0x27, 0x80, 0x80,
42 ], [
43 0x80, 0x80, 0x85, 0x85, 0x7B, 0x7B, 0x7E, 0x87,
44 0x82, 0x79, 0x87, 0x7E, 0x79, 0x82, 0x8F, 0x8F,
45 0x71, 0x71, 0x84, 0x8F, 0x7C, 0x71, 0x8F, 0x84,
46 0x71, 0x7C, 0x75, 0x8B, 0x8B, 0x75, 0x8B, 0x75,
47 0x75, 0x8B, 0x8E, 0x9A, 0x72, 0x66, 0x9A, 0x8E,
48 0x66, 0x72, 0x7B, 0x93, 0x85, 0x6D, 0x93, 0x7B,
49 0x6D, 0x85, 0x9B, 0x9B, 0x65, 0x65, 0x82, 0x9D,
50 0x7E, 0x63, 0x9D, 0x82, 0x63, 0x7E, 0x9B, 0xA8,
51 0x65, 0x58, 0xA8, 0x9B, 0x58, 0x65, 0xA9, 0xA9,
52 0x57, 0x57, 0x8D, 0xAA, 0x73, 0x56, 0xAA, 0x8D,
53 0x56, 0x73, 0x6E, 0x99, 0x92, 0x67, 0x99, 0x6E,
54 0x67, 0x92, 0x76, 0xA2, 0x8A, 0x5E, 0xA2, 0x76,
55 0x5E, 0x8A, 0x7F, 0xAF, 0x81, 0x51, 0xAF, 0x7F,
56 0x51, 0x81, 0xAB, 0xBA, 0x55, 0x46, 0xBA, 0xAB,
57 0x46, 0x55, 0x9A, 0xBB, 0x66, 0x45, 0xBB, 0x9A,
58 0x45, 0x66, 0xBB, 0xBB, 0x45, 0x45, 0x60, 0xA0,
59 0xA0, 0x60, 0xA0, 0x60, 0x60, 0xA0, 0x8B, 0xBE,
60 0x75, 0x42, 0xBE, 0x8B, 0x42, 0x75, 0x66, 0xAA,
61 0x9A, 0x56, 0xAA, 0x66, 0x56, 0x9A, 0x70, 0xB5,
62 0x90, 0x4B, 0xB5, 0x70, 0x4B, 0x90, 0xBE, 0xCF,
63 0x42, 0x31, 0xCF, 0xBE, 0x31, 0x42, 0xAB, 0xD0,
64 0x55, 0x30, 0xD0, 0xAB, 0x30, 0x55, 0xD1, 0xD1,
65 0x2F, 0x2F, 0x9A, 0xD3, 0x66, 0x2D, 0xD3, 0x9A,
66 0x2D, 0x66, 0x7B, 0xC5, 0x85, 0x3B, 0xC5, 0x7B,
67 0x3B, 0x85, 0x54, 0xB4, 0xAC, 0x4C, 0xB4, 0x54,
68 0x4C, 0xAC, 0x5E, 0xBE, 0xA2, 0x42, 0xBE, 0x5E,
69 0x42, 0xA2, 0x87, 0xD8, 0x79, 0x28, 0xD8, 0x87,
70 0x28, 0x79, 0xC0, 0xE8, 0x40, 0x18, 0xE8, 0xC0,
71 0x18, 0x40, 0xD5, 0xE8, 0x2B, 0x18, 0xE8, 0xD5,
72 0x18, 0x2B, 0xAB, 0xE9, 0x55, 0x17, 0xE9, 0xAB,
73 0x17, 0x55, 0x68, 0xCD, 0x98, 0x33, 0xCD, 0x68,
74 0x33, 0x98, 0xEA, 0xEA, 0x16, 0x16, 0x80, 0x80,
75 ], [
76 0x80, 0x80, 0x86, 0x86, 0x7A, 0x7A, 0x7E, 0x88,
77 0x82, 0x78, 0x88, 0x7E, 0x78, 0x82, 0x92, 0x92,
78 0x6E, 0x6E, 0x85, 0x92, 0x7B, 0x6E, 0x92, 0x85,
79 0x6E, 0x7B, 0x73, 0x8D, 0x8D, 0x73, 0x8D, 0x73,
80 0x73, 0x8D, 0x91, 0x9E, 0x6F, 0x62, 0x9E, 0x91,
81 0x62, 0x6F, 0x79, 0x97, 0x87, 0x69, 0x97, 0x79,
82 0x69, 0x87, 0xA0, 0xA0, 0x60, 0x60, 0x83, 0xA2,
83 0x7D, 0x5E, 0xA2, 0x83, 0x5E, 0x7D, 0xA0, 0xB0,
84 0x60, 0x50, 0xB0, 0xA0, 0x50, 0x60, 0xB1, 0xB1,
85 0x4F, 0x4F, 0x8F, 0xB2, 0x71, 0x4E, 0xB2, 0x8F,
86 0x4E, 0x71, 0x6B, 0x9E, 0x95, 0x62, 0x9E, 0x6B,
87 0x62, 0x95, 0x74, 0xA9, 0x8C, 0x57, 0xA9, 0x74,
88 0x57, 0x8C, 0x7F, 0xB8, 0x81, 0x48, 0xB8, 0x7F,
89 0x48, 0x81, 0xB4, 0xC5, 0x4C, 0x3B, 0xC5, 0xB4,
90 0x3B, 0x4C, 0x9F, 0xC6, 0x61, 0x3A, 0xC6, 0x9F,
91 0x3A, 0x61, 0xC6, 0xC6, 0x3A, 0x3A, 0x59, 0xA7,
92 0xA7, 0x59, 0xA7, 0x59, 0x59, 0xA7, 0x8D, 0xCA,
93 0x73, 0x36, 0xCA, 0x8D, 0x36, 0x73, 0x61, 0xB2,
94 0x9F, 0x4E, 0xB2, 0x61, 0x4E, 0x9F, 0x6D, 0xBF,
95 0x93, 0x41, 0xBF, 0x6D, 0x41, 0x93, 0xCA, 0xDF,
96 0x36, 0x21, 0xDF, 0xCA, 0x21, 0x36, 0xB3, 0xDF,
97 0x4D, 0x21, 0xDF, 0xB3, 0x21, 0x4D, 0xE1, 0xE1,
98 0x1F, 0x1F, 0x9F, 0xE3, 0x61, 0x1D, 0xE3, 0x9F,
99 0x1D, 0x61, 0x7A, 0xD3, 0x86, 0x2D, 0xD3, 0x7A,
100 0x2D, 0x86, 0x4C, 0xBE, 0xB4, 0x42, 0xBE, 0x4C,
101 0x42, 0xB4, 0x57, 0xCA, 0xA9, 0x36, 0xCA, 0x57,
102 0x36, 0xA9, 0x88, 0xE9, 0x78, 0x17, 0xE9, 0x88,
103 0x17, 0x78, 0xCC, 0xFB, 0x34, 0x05, 0xFB, 0xCC,
104 0x05, 0x34, 0xE6, 0xFB, 0x1A, 0x05, 0xFB, 0xE6,
105 0x05, 0x1A, 0xB4, 0xFD, 0x4C, 0x03, 0xFD, 0xB4,
106 0x03, 0x4C, 0x63, 0xDC, 0x9D, 0x24, 0xDC, 0x63,
107 0x24, 0x9D, 0xFE, 0xFE, 0x02, 0x02, 0x80, 0x80,
108 ], [
109 0x80, 0x80, 0x87, 0x87, 0x79, 0x79, 0x7E, 0x89,
110 0x82, 0x77, 0x89, 0x7E, 0x77, 0x82, 0x95, 0x95,
111 0x6B, 0x6B, 0x86, 0x96, 0x7A, 0x6A, 0x96, 0x86,
112 0x6A, 0x7A, 0x70, 0x90, 0x90, 0x70, 0x90, 0x70,
113 0x70, 0x90, 0x94, 0xA4, 0x6C, 0x5C, 0xA4, 0x94,
114 0x5C, 0x6C, 0x78, 0x9B, 0x88, 0x65, 0x9B, 0x78,
115 0x65, 0x88, 0xA6, 0xA6, 0x5A, 0x5A, 0x83, 0xA9,
116 0x7D, 0x57, 0xA9, 0x83, 0x57, 0x7D, 0xA6, 0xB9,
117 0x5A, 0x47, 0xB9, 0xA6, 0x47, 0x5A, 0xBA, 0xBA,
118 0x46, 0x46, 0x92, 0xBC, 0x6E, 0x44, 0xBC, 0x92,
119 0x44, 0x6E, 0x67, 0xA3, 0x99, 0x5D, 0xA3, 0x67,
120 0x5D, 0x99, 0x72, 0xB0, 0x8E, 0x50, 0xB0, 0x72,
121 0x50, 0x8E, 0x7F, 0xC3, 0x81, 0x3D, 0xC3, 0x7F,
122 0x3D, 0x81, 0xBE, 0xD2, 0x42, 0x2E, 0xD2, 0xBE,
123 0x2E, 0x42, 0xA5, 0xD4, 0x5B, 0x2C, 0xD4, 0xA5,
124 0x2C, 0x5B, 0xD4, 0xD4, 0x2C, 0x2C, 0x52, 0xAE,
125 0xAE, 0x52, 0xAE, 0x52, 0x52, 0xAE, 0x8F, 0xD8,
126 0x71, 0x28, 0xD8, 0x8F, 0x28, 0x71, 0x5B, 0xBB,
127 0xA5, 0x45, 0xBB, 0x5B, 0x45, 0xA5, 0x69, 0xCB,
128 0x97, 0x35, 0xCB, 0x69, 0x35, 0x97, 0xD8, 0xF0,
129 0x28, 0x10, 0xF0, 0xD8, 0x10, 0x28, 0xBD, 0xF1,
130 0x43, 0x0F, 0xF1, 0xBD, 0x0F, 0x43, 0xF3, 0xF3,
131 0x0D, 0x0D, 0xA5, 0xF6, 0x5B, 0x0A, 0xF6, 0xA5,
132 0x0A, 0x5B, 0x78, 0xE2, 0x88, 0x1E, 0xE2, 0x78,
133 0x1E, 0x88, 0x42, 0xC9, 0xBE, 0x37, 0xC9, 0x42,
134 0x37, 0xBE, 0x4F, 0xD8, 0xB1, 0x28, 0xD8, 0x4F,
135 0x28, 0xB1, 0x8A, 0xFD, 0x76, 0x03, 0xFD, 0x8A,
136 0x03, 0x76, 0xDB, 0xFF, 0x25, 0x01, 0xFF, 0xDB,
137 0x01, 0x25, 0xF9, 0xFF, 0x07, 0x01, 0xFF, 0xF9,
138 0x01, 0x07, 0xBE, 0xFF, 0x42, 0x01, 0xFF, 0xBE,
139 0x01, 0x42, 0x5E, 0xED, 0xA2, 0x13, 0xED, 0x5E,
140 0x13, 0xA2, 0xFF, 0xFF, 0x01, 0x01, 0x80, 0x80,
141 ]
142 ];
143
144 static INDEO2_CODE_CODES: &[u16] = &[
145 0x0000, 0x0004, 0x0006, 0x0001, 0x0009, 0x0019, 0x000D, 0x001D,
146 0x0023, 0x0013, 0x0033, 0x000B, 0x002B, 0x001B, 0x0007, 0x0087,
147 0x0027, 0x00A7, 0x0067, 0x00E7, 0x0097, 0x0057, 0x0037, 0x00B7,
148 0x00F7, 0x000F, 0x008F, 0x018F, 0x014F, 0x00CF, 0x002F, 0x012F,
149 0x01AF, 0x006F, 0x00EF, 0x01EF, 0x001F, 0x021F, 0x011F, 0x031F,
150 0x009F, 0x029F, 0x019F, 0x039F, 0x005F, 0x025F, 0x015F, 0x035F,
151 0x00DF, 0x02DF, 0x01DF, 0x03DF, 0x003F, 0x103F, 0x083F, 0x183F,
152 0x043F, 0x143F, 0x0C3F, 0x1C3F, 0x023F, 0x123F, 0x0A3F, 0x1A3F,
153 0x063F, 0x163F, 0x0E3F, 0x1E3F, 0x013F, 0x113F, 0x093F, 0x193F,
154 0x053F, 0x153F, 0x0D3F, 0x1D3F, 0x033F, 0x133F, 0x0B3F, 0x1B3F,
155 0x073F, 0x173F, 0x0F3F, 0x1F3F, 0x00BF, 0x10BF, 0x08BF, 0x18BF,
156 0x04BF, 0x14BF, 0x0CBF, 0x1CBF, 0x02BF, 0x12BF, 0x0ABF, 0x1ABF,
157 0x06BF, 0x16BF, 0x0EBF, 0x1EBF, 0x01BF, 0x11BF, 0x09BF, 0x19BF,
158 0x05BF, 0x15BF, 0x0DBF, 0x1DBF, 0x03BF, 0x13BF, 0x0BBF, 0x1BBF,
159 0x07BF, 0x17BF, 0x0FBF, 0x1FBF, 0x007F, 0x207F, 0x107F, 0x307F,
160 0x087F, 0x287F, 0x187F, 0x387F, 0x047F, 0x247F, 0x147F, 0x0002,
161 0x0011, 0x0005, 0x0015, 0x0003, 0x003B, 0x0047, 0x00C7, 0x0017,
162 0x00D7, 0x0077, 0x010F, 0x004F, 0x01CF, 0x00AF, 0x016F
163 ];
164
165 static INDEO2_CODE_LENGTHS: &[u8] = &[
166 3, 3, 3, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 8, 8,
167 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9,
168 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
169 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
170 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
171 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
172 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
173 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 3,
174 5, 5, 5, 6, 6, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9
175 ];
176
177 struct IR2CodeReader { }
178
179 impl CodebookDescReader<u8> for IR2CodeReader {
180 fn bits(&mut self, idx: usize) -> u8 { INDEO2_CODE_LENGTHS[idx] }
181 fn code(&mut self, idx: usize) -> u32 { INDEO2_CODE_CODES[idx] as u32 }
182 fn sym (&mut self, idx: usize) -> u8 {
183 if idx < 0x7F { (idx + 1) as u8 } else { (idx + 2) as u8 }
184 }
185 fn len(&mut self) -> usize { INDEO2_CODE_LENGTHS.len() }
186 }
187
188 struct Indeo2Decoder {
189 info: Rc<NACodecInfo>,
190 cb: Codebook<u8>,
191 frmmgr: HAMShuffler,
192 }
193
194 impl Indeo2Decoder {
195 fn new() -> Self {
196 let dummy_info = Rc::new(DUMMY_CODEC_INFO);
197 let mut coderead = IR2CodeReader{};
198 let cb = Codebook::new(&mut coderead, CodebookMode::LSB).unwrap();
199 Indeo2Decoder { info: dummy_info, cb: cb, frmmgr: HAMShuffler::new() }
200 }
201
202 fn decode_plane_intra(&self, br: &mut BitReader,
203 buf: &mut NAVideoBuffer<u8>, planeno: usize,
204 tableno: usize) -> DecoderResult<()> {
205 let offs = buf.get_offset(planeno);
206 let (w, h) = buf.get_dimensions(planeno);
207 let stride = buf.get_stride(planeno);
208 let cb = &self.cb;
209
210 let mut data = buf.get_data_mut();
211 let framebuf: &mut [u8] = data.as_mut_slice();
212
213 let table = &INDEO2_DELTA_TABLE[tableno];
214
215 let mut base = offs;
216 let mut x: usize = 0;
217 while x < w {
218 let idx = br.read_cb(cb)? as usize;
219 if idx >= 0x80 {
220 let run = (idx - 0x80) * 2;
221 if x + run > w { return Err(DecoderError::InvalidData); }
222 for i in 0..run {
223 framebuf[base + x + i] = 0x80;
224 }
225 x += run;
226 } else {
227 framebuf[base + x + 0] = table[(idx * 2 + 0) as usize];
228 framebuf[base + x + 1] = table[(idx * 2 + 1) as usize];
229 x += 2;
230 }
231 }
232 base += stride;
233 for _ in 1..h {
234 let mut x: usize = 0;
235 while x < w {
236 let idx = br.read_cb(cb)? as usize;
237 if idx >= 0x80 {
238 let run = (idx - 0x80) * 2;
239 if x + run > w { return Err(DecoderError::InvalidData); }
240 for i in 0..run {
241 framebuf[base + x + i] = framebuf[base + x + i - stride];
242 }
243 x += run;
244 } else {
245 let delta0 = (table[idx * 2 + 0] as i16) - 0x80;
246 let delta1 = (table[idx * 2 + 1] as i16) - 0x80;
247 let mut pix0 = framebuf[base + x + 0 - stride] as i16;
248 let mut pix1 = framebuf[base + x + 1 - stride] as i16;
249 pix0 += delta0;
250 pix1 += delta1;
251 if pix0 < 0 { pix0 = 0; }
252 if pix1 < 0 { pix1 = 0; }
253 if pix0 > 255 { pix0 = 255; }
254 if pix1 > 255 { pix1 = 255; }
255 framebuf[base + x + 0] = pix0 as u8;
256 framebuf[base + x + 1] = pix1 as u8;
257 x += 2;
258 }
259 }
260 base += stride;
261 }
262 Ok(())
263 }
264
265 fn decode_plane_inter(&self, br: &mut BitReader,
266 buf: &mut NAVideoBuffer<u8>, planeno: usize,
267 tableno: usize) -> DecoderResult<()> {
268 let offs = buf.get_offset(planeno);
269 let (w, h) = buf.get_dimensions(planeno);
270 let stride = buf.get_stride(planeno);
271 let cb = &self.cb;
272
273 let mut data = buf.get_data_mut();
274 let framebuf: &mut [u8] = data.as_mut_slice();
275
276 let table = &INDEO2_DELTA_TABLE[tableno];
277
278 let mut base = offs;
279 for _ in 0..h {
280 let mut x: usize = 0;
281 while x < w {
282 let idx = br.read_cb(cb)? as usize;
283 if idx >= 0x80 {
284 let run = (idx - 0x80) * 2;
285 if x + run > w { return Err(DecoderError::InvalidData); }
286 x += run;
287 } else {
288 let delta0 = (table[idx * 2 + 0] as i16) - 0x80;
289 let delta1 = (table[idx * 2 + 1] as i16) - 0x80;
290 let mut pix0 = framebuf[base + x + 0] as i16;
291 let mut pix1 = framebuf[base + x + 1] as i16;
292 pix0 += delta0 * 3 >> 2;
293 pix1 += delta1 * 3 >> 2;
294 if pix0 < 0 { pix0 = 0; }
295 if pix1 < 0 { pix1 = 0; }
296 if pix0 > 255 { pix0 = 255; }
297 if pix1 > 255 { pix1 = 255; }
298 framebuf[base + x + 0] = pix0 as u8;
299 framebuf[base + x + 1] = pix1 as u8;
300 x += 2;
301 }
302 }
303 base += stride;
304 }
305 Ok(())
306 }
307 }
308
309 const IR2_START: usize = 48;
310
311 impl NADecoder for Indeo2Decoder {
312 fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
313 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
314 let w = vinfo.get_width();
315 let h = vinfo.get_height();
316 let f = vinfo.is_flipped();
317 let fmt = formats::YUV410_FORMAT;
318 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, f, fmt));
319 self.info = Rc::new(NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()));
320 self.frmmgr.clear();
321 Ok(())
322 } else {
323 Err(DecoderError::InvalidData)
324 }
325 }
326 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
327 let src = pkt.get_buffer();
328 if src.len() <= IR2_START { return Err(DecoderError::ShortData); }
329 let interframe = src[18];
330 let tabs = src[34];
331 let mut br = BitReader::new(&src[IR2_START..], src.len() - IR2_START, BitReaderMode::LE);
332 let luma_tab = tabs & 3;
333 let chroma_tab = (tabs >> 2) & 3;
334 if interframe != 0 {
335 let vinfo = self.info.get_properties().get_video_info().unwrap();
336 let bufret = alloc_video_buffer(vinfo, 2);
337 if let Err(_) = bufret { return Err(DecoderError::InvalidData); }
338 let mut bufinfo = bufret.unwrap();
339 let mut buf = bufinfo.get_vbuf().unwrap();
340 for plane in 0..3 {
341 let tabidx = (if plane == 0 { luma_tab } else { chroma_tab }) as usize;
342 self.decode_plane_intra(&mut br, &mut buf, plane, tabidx)?;
343 }
344 self.frmmgr.add_frame(buf);
345 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
346 frm.set_keyframe(true);
347 frm.set_frame_type(FrameType::I);
348 Ok(Rc::new(RefCell::new(frm)))
349 } else {
350 let bufret = self.frmmgr.clone_ref();
351 if let None = bufret { return Err(DecoderError::MissingReference); }
352 let mut buf = bufret.unwrap();
353
354 for plane in 0..3 {
355 let tabidx = (if plane == 0 { luma_tab } else { chroma_tab }) as usize;
356 self.decode_plane_inter(&mut br, &mut buf, plane, tabidx)?;
357 }
358 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf));
359 frm.set_keyframe(false);
360 frm.set_frame_type(FrameType::P);
361 Ok(Rc::new(RefCell::new(frm)))
362 }
363 }
364 }
365
366 pub fn get_decoder() -> Box<NADecoder> {
367 Box::new(Indeo2Decoder::new())
368 }
369
370 #[cfg(test)]
371 mod test {
372 use nihav_core::codecs::RegisteredDecoders;
373 use nihav_core::demuxers::RegisteredDemuxers;
374 use nihav_core::test::dec_video::*;
375 use crate::codecs::indeo_register_all_codecs;
376 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
377 #[test]
378 fn test_indeo2() {
379 let mut dmx_reg = RegisteredDemuxers::new();
380 generic_register_all_demuxers(&mut dmx_reg);
381 let mut dec_reg = RegisteredDecoders::new();
382 indeo_register_all_codecs(&mut dec_reg);
383
384 test_file_decoding("avi", "assets/laser05.avi", Some(10), true, false, None, &dmx_reg, &dec_reg);
385 }
386 }