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