]> git.nihav.org Git - nihav.git/blame - nihav-llaudio/src/codecs/ape.rs
fix clippy warnings
[nihav.git] / nihav-llaudio / src / codecs / ape.rs
CommitLineData
87927c57
KS
1use nihav_core::codecs::*;
2use nihav_core::io::byteio::*;
3use nihav_core::io::bitreader::*;
4
5use super::apepred::*;
6use super::apereader::*;
7
8struct APEDecoder {
9 ainfo: NAAudioInfo,
10 chmap: NAChannelMap,
11 version: u16,
12 decode_mono: fn(&mut Coder, &mut [i32]) -> DecoderResult<()>,
13 decode_stereo: fn(&mut Coder, &mut [i32], &mut [i32]) -> DecoderResult<()>,
14 is_stereo: bool,
15 left: Vec<i32>,
16 right: Vec<i32>,
17 fmode: FilterMode,
18 data: Vec<u8>,
19 blocksperframe: usize,
20}
21
22impl APEDecoder {
23 fn new() -> Self {
24 Self {
25 ainfo: NAAudioInfo::new(0, 1, SND_S16P_FORMAT, 0),
26 chmap: NAChannelMap::new(),
27 version: 0,
28 decode_mono: decode_mono_dummy,
29 decode_stereo: decode_stereo_dummy,
30 is_stereo: false,
31 left: Vec::new(),
32 right: Vec::new(),
33 fmode: FilterMode::None,
34 data: Vec::new(),
35 blocksperframe: 0,
36 }
37 }
38}
39
40impl NADecoder for APEDecoder {
41 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
42 if let NACodecTypeInfo::Audio(_ainfo) = info.get_properties() {
43 if let Some(buf) = info.get_extradata() {
44 let mut mr = MemoryReader::new_read(&buf);
45 let mut br = ByteReader::new(&mut mr);
46 let version = br.read_u16le()?;
47 let compression = br.read_u16le()?;
48 let _flags = br.read_u16le()?;
49 let channels = br.read_byte()?;
50 let bits = br.read_byte()?;
51 let srate = br.read_u32le()?;
52 let blocksperframe = br.read_u32le()? as usize;
53
54 validate!(channels > 0);
55 validate!(bits > 0 && bits <= 32);
56 validate!((compression % 1000) == 0 && compression > 0 && compression <= 5000);
57 validate!(compression < 5000 || version >= 3930);
58 if bits != 16 {
59 return Err(DecoderError::NotImplemented);
60 }
61 if version > 3990 {
62 return Err(DecoderError::NotImplemented);
63 }
64
65 self.version = version;
66 self.blocksperframe = blocksperframe;
67 self.is_stereo = channels == 2;
68 self.left.resize(blocksperframe, 0);
69 if self.is_stereo {
70 self.right.resize(blocksperframe, 0);
71 }
72
73 self.decode_mono = if version >= 3990 {
74 decode_mono_3990
75 } else if version >= 3910 {
76 decode_mono_3910
77 } else if version >= 3900 {
78 decode_mono_3900
79 } else if version >= 3890 {
80 decode_mono_3890
81 } else if version >= 3860 {
82 decode_mono_3860
83 } else {
84 decode_mono_0000
85 };
86 self.decode_stereo = if version >= 3990 {
87 decode_stereo_3990
88 } else if version >= 3930 {
89 decode_stereo_3930
90 } else if version >= 3910 {
91 decode_stereo_3910
92 } else if version >= 3900 {
93 decode_stereo_3900
94 } else if version >= 3890 {
95 decode_stereo_3890
96 } else if version >= 3860 {
97 decode_stereo_3860
98 } else {
99 decode_stereo_0000
100 };
101 self.fmode = FilterMode::new(version, compression);
102
103 self.chmap = if channels == 1 {
104 NAChannelMap::from_str("C").unwrap()
105 } else if channels == 2 {
106 NAChannelMap::from_str("L,R").unwrap()
107 } else {
108 return Err(DecoderError::NotImplemented);
109 };
110 self.ainfo = NAAudioInfo::new(srate, channels as u8, SND_S16P_FORMAT, 4602);
111 Ok(())
112 } else {
113 Err(DecoderError::InvalidData)
114 }
115 } else {
116 Err(DecoderError::InvalidData)
117 }
118 }
119 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
120 let info = pkt.get_stream().get_info();
121 if let NACodecTypeInfo::Audio(_) = info.get_properties() {
122 let pktbuf = pkt.get_buffer();
123 validate!(pktbuf.len() > 9);
124
125 let nblocks = read_u32le(&pktbuf[0..])? as usize;
126 validate!(nblocks > 0);
127 let bits = u32::from(pktbuf[4]);
128 validate!(bits < 32);
37952415 129 self.data.clear();
87927c57
KS
130 self.data.reserve((pktbuf.len() & !3) + 2);
131 for word in pktbuf[8..].chunks_exact(4) {
132 self.data.push(word[3]);
133 self.data.push(word[2]);
134 self.data.push(word[1]);
135 self.data.push(word[0]);
136 }
137 if self.version < 3950 {
138 self.data.push(0);
139 self.data.push(0);
140 }
141
142 let (mut coder, ref_crc, fflags) = if self.version < 3900 {
143 let mut br = BitReader::new(&self.data, BitReaderMode::BE);
144 br.skip(bits)?;
145 let mut crc = br.read(32)?;
146 let fflags = if self.version >= 3830 && (crc & 0x80000000) != 0 {
147 crc ^= 0x80000000;
148 br.read(32)?
149 } else {
150 0
151 };
152 (Coder::Rice(RiceCoder::new(br)), crc, fflags)
153 } else {
154 let mut boff = (bits / 8) as usize;
155 let mut crc = read_u32be(&self.data[boff..])?;
156 boff += 4;
157 let fflags = if (crc & 0x80000000) != 0 {
158 crc ^= 0x80000000;
159 let flg = read_u32be(&self.data[boff..])?;
160 boff += 4;
161 flg
162 } else {
163 0
164 };
165 // it ignores first byte anyway
166 (Coder::Range(RangeCoder::new(&self.data[boff + 1..])), crc, fflags)
167 };
168 self.left.resize(nblocks, 0);
169 if self.is_stereo {
170 self.right.resize(nblocks, 0);
171 }
7e0b626d 172 if (!self.is_stereo && (fflags & 1) == 0) || (self.is_stereo && (fflags & 3) != 3) {
87927c57
KS
173 if !self.is_stereo || (fflags & 4) != 0 {
174 (self.decode_mono)(&mut coder, &mut self.left)?;
175 self.fmode.filter_mono(&mut self.left);
176
177 if (fflags & 4) != 0 {
178 self.right.copy_from_slice(&self.left);
179 }
180 } else {
181 (self.decode_stereo)(&mut coder, &mut self.left, &mut self.right)?;
182 self.fmode.filter_stereo(&mut self.left, &mut self.right);
183 }
06fc12ca
KS
184 } else {
185 for l in self.left.iter_mut() { *l = 0; }
186 if self.is_stereo {
187 for r in self.right.iter_mut() { *r = 0; }
188 }
87927c57
KS
189 }
190
191 if self.version >= 0x3990 || nblocks == self.blocksperframe {
192 let mut crc = 0xFFFFFFFF;
193 if !self.is_stereo {
194 for el in self.left.iter() {
195 let byte1 = *el as u8;
196 let byte0 = (*el >> 8) as u8;
197 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte1) as usize];
198 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte0) as usize];
199 }
200 } else {
201 for (l, r) in self.left.iter().zip(self.right.iter()) {
202 let byte1 = *l as u8;
203 let byte0 = (*l >> 8) as u8;
204 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte1) as usize];
205 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte0) as usize];
206 let byte1 = *r as u8;
207 let byte0 = (*r >> 8) as u8;
208 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte1) as usize];
209 crc = (crc >> 8) ^ CRC32_TAB[((crc as u8) ^ byte0) as usize];
210 }
211 }
212 crc = !crc;
213 if self.version >= 3830 {
214 crc >>= 1;
215 }
216 if crc != ref_crc {
217 return Err(DecoderError::ChecksumError);
218 }
219 }
220
221 let abuf = alloc_audio_buffer(self.ainfo, nblocks, self.chmap.clone())?;
222 let mut adata = abuf.get_abuf_i16().unwrap();
223 let off1 = adata.get_offset(1);
224 let dst = adata.get_data_mut().unwrap();
225 let (left, right) = dst.split_at_mut(off1);
226 for (dst, src) in left.iter_mut().zip(self.left.iter()) {
227 *dst = *src as i16;
228 }
229 if self.is_stereo {
230 for (dst, src) in right.iter_mut().zip(self.right.iter()) {
231 *dst = *src as i16;
232 }
233 }
234
235 let mut frm = NAFrame::new_from_pkt(pkt, info, abuf);
236 frm.set_duration(Some(nblocks as u64));
237 Ok(frm.into_ref())
238 } else {
239 Err(DecoderError::InvalidData)
240 }
241 }
242 fn flush(&mut self) {
243 }
244}
245
246impl NAOptionHandler for APEDecoder {
247 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
248 fn set_options(&mut self, _options: &[NAOption]) { }
249 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
250}
251
252pub fn get_decoder() -> Box<dyn NADecoder + Send> {
253 Box::new(APEDecoder::new())
254}
255
256#[cfg(test)]
257mod test {
258 use nihav_core::codecs::RegisteredDecoders;
259 use nihav_core::demuxers::RegisteredDemuxers;
260 use nihav_codec_support::test::dec_video::*;
261 use crate::llaudio_register_all_decoders;
262 use crate::llaudio_register_all_demuxers;
263 #[test]
264 fn test_ape_3990() {
265 let mut dmx_reg = RegisteredDemuxers::new();
266 llaudio_register_all_demuxers(&mut dmx_reg);
267 let mut dec_reg = RegisteredDecoders::new();
268 llaudio_register_all_decoders(&mut dec_reg);
269
270 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight.ape", Some(3), &dmx_reg, &dec_reg,
271 ExpectedTestResult::MD5([0x569e002b, 0xd93772a9, 0x1cfd81cd, 0xad81319a]));
272 }
273 #[test]
274 fn test_ape_3940() {
275 let mut dmx_reg = RegisteredDemuxers::new();
276 llaudio_register_all_demuxers(&mut dmx_reg);
277 let mut dec_reg = RegisteredDecoders::new();
278 llaudio_register_all_decoders(&mut dec_reg);
279
280 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac394b1-c4000.ape", Some(1), &dmx_reg, &dec_reg,
281 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
282 }
283 #[test]
284 fn test_ape_3920() {
285 let mut dmx_reg = RegisteredDemuxers::new();
286 llaudio_register_all_demuxers(&mut dmx_reg);
287 let mut dec_reg = RegisteredDecoders::new();
288 llaudio_register_all_decoders(&mut dec_reg);
289
290 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac392b2-c4000.ape", Some(1), &dmx_reg, &dec_reg,
291 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
292 }
293 #[test]
294 fn test_ape_3910() {
295 let mut dmx_reg = RegisteredDemuxers::new();
296 llaudio_register_all_demuxers(&mut dmx_reg);
297 let mut dec_reg = RegisteredDecoders::new();
298 llaudio_register_all_decoders(&mut dec_reg);
299
300 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac391b1-c4000.ape", Some(1), &dmx_reg, &dec_reg,
301 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
302 }
303 #[test]
304 fn test_ape_3890() {
305 let mut dmx_reg = RegisteredDemuxers::new();
306 llaudio_register_all_demuxers(&mut dmx_reg);
307 let mut dec_reg = RegisteredDecoders::new();
308 llaudio_register_all_decoders(&mut dec_reg);
309
310 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac389b1-c4000.ape", Some(1), &dmx_reg, &dec_reg,
311 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
312 }
313 #[test]
314 fn test_ape_3880() {
315 let mut dmx_reg = RegisteredDemuxers::new();
316 llaudio_register_all_demuxers(&mut dmx_reg);
317 let mut dec_reg = RegisteredDecoders::new();
318 llaudio_register_all_decoders(&mut dec_reg);
319
320 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac388-c4000.ape", Some(1), &dmx_reg, &dec_reg,
321 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
322 }
323 #[test]
324 fn test_ape_3800() {
325 let mut dmx_reg = RegisteredDemuxers::new();
326 llaudio_register_all_demuxers(&mut dmx_reg);
327 let mut dec_reg = RegisteredDecoders::new();
328 llaudio_register_all_decoders(&mut dec_reg);
329
330 test_decoding("ape", "ape", "assets/LLaudio/ape/luckynight-mac380-c4000.ape", Some(1), &dmx_reg, &dec_reg,
331 ExpectedTestResult::MD5([0xeb55ece6, 0xe5f22759, 0xd0696dd6, 0x84ae9a6c]));
332 }
333}
334
335const CRC32_TAB: [u32; 256] = [
336 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
337 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
338 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
339 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
340 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
341 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
342 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
343 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
344 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
345 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
346 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
347 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
348 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
349 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
350 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
351 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
352 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
353 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
354 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
355 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
356 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
357 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
358 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
359 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
360 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
361 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
362 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
363 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
364 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
365 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
366 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
367 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
368];