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