prettier demuxers module
[nihav.git] / src / codecs / indeo2.rs
CommitLineData
77d06de2
KS
1use io::bitreader::*;
2use io::codebook::*;
3use formats;
4use super::*;
5
6static 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
142static 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
163static 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
175struct IR2CodeReader { }
176
177impl 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
186pub struct Indeo2Decoder {
187 info: Rc<NACodecInfo>,
188 cb: Codebook<u8>,
189 lastfrm: Option<Rc<NAFrame>>,
190}
191
192impl Indeo2Decoder {
193 pub 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, lastfrm: None }
198 }
199
200 fn decode_plane_intra(&self, br: &mut BitReader,
201 frm: &mut NAFrame, planeno: usize,
202 tableno: usize) -> DecoderResult<()> {
203 let offs = frm.get_offset(planeno);
204 let (w, h) = frm.get_dimensions(planeno);
205 let stride = frm.get_stride(planeno);
206 let cb = &self.cb;
207
208 let mut buffer = frm.get_buffer_mut().unwrap();
209 let mut data = buffer.get_data_mut().unwrap();
210 let mut 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 = (table[idx * 2 + 0] as i16) - 0x80;
245 let delta1 = (table[idx * 2 + 1] as i16) - 0x80;
246 let mut pix0 = framebuf[base + x + 0 - stride] as i16;
247 let mut pix1 = framebuf[base + x + 1 - stride] as i16;
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 frm: &mut NAFrame, planeno: usize,
266 tableno: usize) -> DecoderResult<()> {
267 let offs = frm.get_offset(planeno);
268 let (w, h) = frm.get_dimensions(planeno);
269 let stride = frm.get_stride(planeno);
270 let cb = &self.cb;
271
272 let mut buffer = frm.get_buffer_mut().unwrap();
273 let mut data = buffer.get_data_mut().unwrap();
274 let mut 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
309const IR2_START: usize = 48;
310
311impl NADecoder for Indeo2Decoder {
312 #[allow(unused_variables)]
313 fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
314 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
315 let w = vinfo.get_width();
316 let h = vinfo.get_height();
317 let f = vinfo.is_flipped();
318 let fmt = formats::YUV410_FORMAT;
319 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, f, fmt));
320 self.info = Rc::new(NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()));
321 Ok(())
322 } else {
323 Err(DecoderError::InvalidData)
324 }
325 }
326 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<Rc<NAFrame>> {
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 mut frm = NAFrame::new_from_pkt(pkt, self.info.clone());
336 for plane in 0..3 {
337 let tabidx = (if plane == 0 { luma_tab } else { chroma_tab }) as usize;
338 self.decode_plane_intra(&mut br, &mut frm, plane, tabidx)?;
339 }
340 let rcf = Rc::new(frm);
341 self.lastfrm = Some(rcf.clone());
342 Ok(rcf)
343 } else {
344 let lf = self.lastfrm.clone();
345 if let None = lf { return Err(DecoderError::MissingReference); }
346 let lastfr = lf.unwrap();
347 let mut frm = NAFrame::from_copy(lastfr.as_ref());
348 frm.fill_timestamps(pkt);
349 for plane in 0..3 {
350 let tabidx = (if plane == 0 { luma_tab } else { chroma_tab }) as usize;
351 self.decode_plane_inter(&mut br, &mut frm, plane, tabidx)?;
352 }
353 let rcf = Rc::new(frm);
354 self.lastfrm = Some(rcf.clone());
355 Ok(rcf)
356 }
357 }
358}
359
360#[cfg(test)]
361mod test {
362 use super::*;
eb71d98f 363 use demuxers::*;
77d06de2
KS
364 use io::byteio::*;
365 use std::fs::File;
366 use std::io::prelude::*;
367
368 #[test]
369 fn test_indeo2() {
eb71d98f 370 let avi_dmx = find_demuxer("avi").unwrap();
77d06de2
KS
371 let mut file = File::open("assets/laser05.avi").unwrap();
372 let mut fr = FileReader::new_read(&mut file);
373 let mut br = ByteReader::new(&mut fr);
eb71d98f 374 let mut dmx = avi_dmx.new_demuxer(&mut br);
77d06de2
KS
375 dmx.open().unwrap();
376 let mut dec = Indeo2Decoder::new();
377
378 let mut str: u32 = 42;
379 for i in 0..dmx.get_num_streams() {
380 let s = dmx.get_stream(i).unwrap();
381 let info = s.get_info();
382 if info.is_video() && info.get_name() == "indeo2" {
383 str = s.get_id();
384 dec.init(s.get_info()).unwrap();
385 break;
386 }
387 }
388
389 loop {
390 let pktres = dmx.get_frame();
391 if let Err(e) = pktres {
392 if (e as i32) == (DemuxerError::EOF as i32) { break; }
393 panic!("error");
394 }
395 let pkt = pktres.unwrap();
396 if pkt.get_stream().get_id() == str {
397 let frm = dec.decode(&pkt).unwrap();
398 write_pgmyuv(pkt.get_pts().unwrap(), &frm);
399 }
400 }
401 }
402
403 fn write_pgmyuv(num: u64, frm: &NAFrame) {
404 let name = format!("assets/out{:04}.pgm", num);
405 let mut ofile = File::create(name).unwrap();
406 let (w, h) = frm.get_dimensions(0);
407 let (w2, h2) = frm.get_dimensions(1);
408 let tot_h = h + h2;
409 let hdr = format!("P5\n{} {}\n255\n", w, tot_h);
410 ofile.write_all(hdr.as_bytes()).unwrap();
411 let buf = frm.get_buffer();
412 let dta = buf.get_data();
413 let ls = frm.get_stride(0);
414 let mut idx = 0;
415 let mut idx2 = ls;
416 let mut pad: Vec<u8> = Vec::with_capacity((w - w2 * 2) / 2);
417 pad.resize((w - w2 * 2) / 2, 0xFF);
418 for _ in 0..h {
419 let line = &dta[idx..idx2];
420 ofile.write_all(line).unwrap();
421 idx += ls;
422 idx2 += ls;
423 }
424 let mut base1 = frm.get_offset(1);
425 let stride1 = frm.get_stride(1);
426 let mut base2 = frm.get_offset(2);
427 let stride2 = frm.get_stride(2);
428 for _ in 0..h2 {
429 let bend1 = base1 + w2;
430 let line = &dta[base1..bend1];
431 ofile.write_all(line).unwrap();
432 ofile.write_all(pad.as_slice()).unwrap();
433
434 let bend2 = base2 + w2;
435 let line = &dta[base2..bend2];
436 ofile.write_all(line).unwrap();
437 ofile.write_all(pad.as_slice()).unwrap();
438
439 base1 += stride1;
440 base2 += stride2;
441 }
442 }
443}