aac: fix intensity stereo reconstruction for ms_mask_present=0 case
[nihav.git] / nihav-game / src / demuxers / smush.rs
1 use nihav_core::frame::*;
2 use nihav_core::demuxers::*;
3
4 struct SmushDemuxer<'a> {
5 src: &'a mut ByteReader<'a>,
6 old: bool,
7 size: u64,
8
9 nframes: usize,
10 chunks: Vec<u8>,
11
12 keyframe: bool,
13 cur_frame: usize,
14 frme_end: u64,
15 asize: u64,
16 }
17
18 fn parse_iact(br: &mut ByteReader, end: u64, arate: &mut u32, abits: &mut u8, chans: &mut u8, mcmp: bool) -> DemuxerResult<()> {
19 if !mcmp {
20 br.read_skip(14)?;
21 }
22 let tag = br.read_tag()?;
23 if &tag != b"iMUS" {
24 if mcmp {
25 return Err(DemuxerError::InvalidData);
26 }
27 *arate = 22050;
28 *abits = 16;
29 *chans = 2;
30 return Ok(());
31 }
32 br.read_skip(4)?;
33 while br.tell() < end {
34 let tag = br.read_tag()?;
35 let size = u64::from(br.read_u32be()?);
36 match &tag {
37 b"MAP " => {
38 let cend = br.tell() + size;
39 while br.tell() < cend {
40 let tag = br.read_tag()?;
41 let size = u64::from(br.read_u32be()?);
42 match &tag {
43 b"FRMT" => {
44 validate!(size == 20);
45 br.read_u32be()?;
46 br.read_u32be()?;
47 let bits = br.read_u32be()?;
48 validate!(bits > 0 && bits <= 16);
49 *abits = bits as u8;
50 *arate = br.read_u32be()?;
51 let c = br.read_u32be()?;
52 validate!(c == 1 || c == 2);
53 *chans = c as u8;
54 return Ok(());
55 },
56 _ => br.read_skip(size as usize)?,
57 };
58 }
59 },
60 b"DATA" => return Err(DemuxerError::InvalidData),
61 _ => br.read_skip(size as usize)?,
62 };
63 }
64 Err(DemuxerError::InvalidData)
65 }
66
67 impl<'a> SmushDemuxer<'a> {
68 fn new(io: &'a mut ByteReader<'a>) -> Self {
69 SmushDemuxer {
70 src: io,
71
72 old: false,
73 size: 0,
74
75 nframes: 0,
76 chunks: Vec::new(),
77
78 keyframe: false,
79 cur_frame: 0,
80 frme_end: 0,
81 asize: 0,
82 }
83 }
84 fn parse_anim_header(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
85 let src = &mut self.src;
86
87 let tag = src.read_tag()?;
88 validate!(&tag == b"AHDR");
89 let size = u64::from(src.read_u32be()?);
90 validate!(size >= 768 + 6);
91 let end = src.tell() + size;
92 validate!(end < self.size);
93 let version = src.read_u16le()?;
94 validate!(version < 3);
95 self.nframes = src.read_u16le()? as usize;
96 validate!(self.nframes != 0);
97 src.read_skip(2)?; //max FRME size
98 let mut edata = vec![0; 768 + 1];
99 edata[0] = version as u8;
100 src.read_buf(&mut edata[1..][..768])?;
101 src.read_skip(size as usize - 768 - 6)?;
102
103 let start = src.tell();
104 let mut size = 0;
105 while size == 0 {
106 let tag = src.read_tag()?;
107 validate!(&tag == b"FRME");
108 size = u64::from(src.read_u32be()?);
109 }
110
111 let end = src.tell() + size;
112 validate!(end <= self.size + 8); // some NUTs feature slightly incorrect total size
113
114 let mut width = 0;
115 let mut height = 0;
116 let mut aname = "";
117 let mut arate = 0;
118 let mut abits = 0;
119 let mut chans = 0;
120
121 while src.tell() < end {
122 let tag = src.read_tag()?;
123 let size = u64::from(src.read_u32be()?);
124
125 let tend = src.tell() + size;
126 validate!(tend <= end);
127 match &tag {
128 b"FOBJ" => {
129 validate!(size >= 10);
130 let _codec = src.read_u16le()?;
131 let x = src.read_u16le()? as i16;
132 let y = src.read_u16le()? as i16;
133 if x == 0 && y == 0 && width == 0 && height == 0 {
134 width = src.read_u16le()? as usize;
135 height = src.read_u16le()? as usize;
136 } else {
137 let w = src.read_u16le()? as usize;
138 let h = src.read_u16le()? as usize;
139 if x == 0 && y == 0 && w >= width && h >= height {
140 width = w;
141 height = h;
142 }
143 }
144 src.read_skip((size - 10) as usize)?;
145 },
146 b"IACT" => {
147 validate!(size > 8);
148 let end = src.tell() + size;
149 let opcode = src.read_u16le()?;
150 let flags = src.read_u16le()?;
151 if (opcode == 8) && (flags == 0x2E) {
152 if parse_iact(src, end, &mut arate, &mut abits, &mut chans, false).is_ok() {
153 aname = "smush-iact";
154 }
155 validate!(src.tell() <= end);
156 }
157 src.seek(SeekFrom::Start(end))?;
158 },
159 b"PSAD" => {
160 aname = "pcm";
161 arate = 11025;
162 abits = 8;
163 chans = 2;
164 src.read_skip(size as usize)?;
165 },
166 _ => { src.read_skip(size as usize)?; },
167 };
168 if (src.tell() & 1) != 0 {
169 if let Ok(0) = src.peek_byte() {
170 src.read_skip(1)?;
171 }
172 }
173 }
174 // hack
175 width = width.max(320);
176 height = height.max(200);
177 src.seek(SeekFrom::Start(start))?;
178 self.frme_end = start;
179
180 let vhdr = NAVideoInfo::new(width, height, false, PAL8_FORMAT);
181 let vci = NACodecTypeInfo::Video(vhdr);
182 let vinfo = NACodecInfo::new("smushv1", vci, Some(edata));
183 if strmgr.add_stream(NAStream::new(StreamType::Video, 0, vinfo, 1, 15, self.nframes as u64)).is_none() {
184 return Err(DemuxerError::MemoryError);
185 }
186
187 if !aname.is_empty() {
188 validate!(arate > 0);
189 let mut fmt = SND_S16_FORMAT;
190 match aname {
191 "pcm" => { fmt = SND_U8_FORMAT; },
192 "smush-iact" => { fmt.bits = abits; fmt.packed = true; },
193 _ => {},
194 };
195 let ahdr = NAAudioInfo::new(arate, chans, fmt, 0);
196 let ainfo = NACodecInfo::new(aname, NACodecTypeInfo::Audio(ahdr), None);
197 if strmgr.add_stream(NAStream::new(StreamType::Audio, 1, ainfo, 1, arate, 0)).is_none() {
198 return Err(DemuxerError::MemoryError);
199 }
200 }
201
202 Ok(())
203 }
204 fn parse_sanm_header(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
205 let src = &mut self.src;
206
207 let tag = src.read_tag()?;
208 validate!(&tag == b"SHDR");
209 let size = u64::from(src.read_u32be()?);
210 validate!(src.tell() + size <= self.size);
211 validate!(size >= 0x426);
212
213 let maj_ver = src.read_byte()?;
214 let min_ver = src.read_byte()?;
215 if maj_ver != 1 || min_ver != 0 {
216 return Err(DemuxerError::NotImplemented);
217 }
218 self.nframes = src.read_u16le()? as usize;
219 let _xoff = src.read_u16le()? as usize;
220 let _yoff = src.read_u16le()? as usize;
221 let width = src.read_u16le()? as usize;
222 let height = src.read_u16le()? as usize;
223 let _imgtype = src.read_u16le()?;
224 let frame_delay = src.read_u32le()?;
225 let _max_frame_size = src.read_u32le()?;
226 src.read_skip(1024)?; // palette
227 src.read_skip((size as usize) - 0x416)?;
228
229 let tag = src.read_tag()?;
230 validate!(&tag == b"FLHD");
231 let size = u64::from(src.read_u32be()?);
232 let end = src.tell() + size;
233
234 let mut arate = 0;
235 let mut chans = 0;
236 let mut alen = 0;
237 while src.tell() < end {
238 let tag = src.read_tag()?;
239 if src.tell() == end { break; }
240 let size = src.read_u32be()?;
241 match &tag {
242 b"Wave" => {
243 validate!(size >= 8);
244 arate = src.read_u32le()?;
245 let cc = src.read_u32le()?;
246 validate!(cc == 1 || cc == 2);
247 chans = cc as u8;
248 if size >= 12 {
249 alen = u64::from(src.read_u32le()? / cc / 2);
250 src.read_skip((size as usize) - 12)?;
251 }
252 },
253 _ => src.read_skip(size as usize)?,
254 };
255 }
256 validate!(src.tell() == end);
257
258 let vhdr = NAVideoInfo::new(width, height, false, RGB565_FORMAT);
259 let vci = NACodecTypeInfo::Video(vhdr);
260 let vinfo = NACodecInfo::new("smushv2", vci, None);
261 if strmgr.add_stream(NAStream::new(StreamType::Video, 0, vinfo, frame_delay, 1000000, self.nframes as u64)).is_none() {
262 return Err(DemuxerError::MemoryError);
263 }
264 if arate != 0 {
265 let ahdr = NAAudioInfo::new(arate, chans, SND_S16P_FORMAT, 0);
266 let ainfo = NACodecInfo::new("smush-vima", NACodecTypeInfo::Audio(ahdr), None);
267 if strmgr.add_stream(NAStream::new(StreamType::Audio, 1, ainfo, 1, arate, alen)).is_none() {
268 return Err(DemuxerError::MemoryError);
269 }
270 }
271
272 Ok(())
273 }
274
275 fn queue_chunk(&mut self, tag: [u8; 4], size: usize) -> DemuxerResult<()> {
276 self.chunks.extend_from_slice(&tag);
277 let start = self.chunks.len();
278 let nlen = start + size + 4;
279 self.chunks.resize(nlen, 0);
280 write_u32be(&mut self.chunks[start..], size as u32).unwrap();
281 self.src.read_buf(&mut self.chunks[start + 4..])?;
282 Ok(())
283 }
284 fn get_frame_anim(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
285 loop {
286 if self.src.tell() >= self.frme_end {
287 if !self.chunks.is_empty() {
288 let mut buf = Vec::new();
289 std::mem::swap(&mut self.chunks, &mut buf);
290 let stream = strmgr.get_stream(0).unwrap();
291 let ts = stream.make_ts(Some(self.cur_frame as u64 - 1), None, None);
292 return Ok(NAPacket::new(stream, ts, false, buf));
293 }
294 if self.cur_frame == self.nframes {
295 return Err(DemuxerError::EOF);
296 }
297 let tag = self.src.read_tag()?;
298 validate!(&tag == b"FRME");
299 let size = u64::from(self.src.read_u32be()?);
300 self.frme_end = self.src.tell() + size;
301
302 self.chunks.clear();
303 self.cur_frame += 1;
304 if size == 0 {
305 continue;
306 }
307 }
308 let tag = self.src.read_tag()?;
309 let size = u64::from(self.src.read_u32be()?);
310 let tend = self.src.tell() + size;
311 validate!(tend <= self.frme_end);
312 match &tag {
313 b"STOR" | b"FTCH" | b"NPAL" | b"XPAL" | b"FOBJ" => {
314 self.queue_chunk(tag, size as usize)?;
315 },
316 b"IACT" => {
317 validate!(size >= 4);
318 let opcode = self.src.read_u16le()?;
319 let flags = self.src.read_u16le()?;
320 if (opcode == 8) && (flags == 0x2E) {
321 if let Some(stream) = strmgr.get_stream(1) {
322 let ts = stream.make_ts(None, None, None);
323
324 let mut buf = vec![0; size as usize];
325 write_u16le(&mut buf[0..2], opcode).unwrap();
326 write_u16le(&mut buf[2..4], flags).unwrap();
327 self.src.read_buf(&mut buf[4..])?;
328
329 if (self.src.tell() & 1) == 1 {
330 if let Ok(0) = self.src.peek_byte() {
331 self.src.read_skip(1)?;
332 }
333 }
334 return Ok(NAPacket::new(stream, ts, true, buf));
335 }
336 }
337 self.src.read_skip((size as usize) - 4)?;
338 },
339 b"PSAD" => {
340 if size > 0x30 {
341 self.src.read_skip(0x30)?;
342 if let Some(stream) = strmgr.get_stream(1) {
343 let audio_size = size - 0x30;
344 let ts = stream.make_ts(Some(self.asize), None, None);
345 let pkt = self.src.read_packet(stream, ts, true, audio_size as usize)?;
346 self.asize += audio_size;
347 if (self.src.tell() & 1) == 1 {
348 if let Ok(0) = self.src.peek_byte() {
349 self.src.read_skip(1)?;
350 }
351 }
352 return Ok(pkt);
353 } else {
354 self.src.read_skip((size - 0x30) as usize)?;
355 }
356 } else {
357 self.src.read_skip(size as usize)?;
358 }
359 },
360 _ => {
361 self.src.read_skip(size as usize)?;
362 },
363 };
364 if (self.src.tell() & 1) == 1 {
365 if let Ok(0) = self.src.peek_byte() {
366 self.src.read_skip(1)?;
367 }
368 }
369 }
370 }
371 fn get_frame_sanm(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
372 loop {
373 if self.src.tell() >= self.frme_end {
374 if !self.chunks.is_empty() {
375 let mut buf = Vec::new();
376 std::mem::swap(&mut self.chunks, &mut buf);
377 let stream = strmgr.get_stream(0).unwrap();
378 let ts = stream.make_ts(Some(self.cur_frame as u64 - 1), None, None);
379 return Ok(NAPacket::new(stream, ts, self.keyframe, buf));
380 }
381 if self.cur_frame == self.nframes {
382 return Err(DemuxerError::EOF);
383 }
384 let tag = self.src.read_tag()?;
385 let size = u64::from(self.src.read_u32be()?);
386 self.frme_end = self.src.tell() + size;
387 match &tag {
388 b"FLHD" => { self.keyframe = true; },
389 b"FRME" => { self.keyframe = false; },
390 _ => {
391 self.src.read_skip(size as usize)?;
392 continue;
393 },
394 };
395
396 self.chunks.clear();
397 self.cur_frame += 1;
398 if size == 0 {
399 continue;
400 }
401 }
402 let tag = self.src.read_tag()?;
403 if self.src.tell() >= self.frme_end { // happens after some Wave tags
404 continue;
405 }
406 let size = u64::from(self.src.read_u32be()?);
407 let tend = self.src.tell() + size;
408 validate!(tend <= self.frme_end);
409 match &tag {
410 b"Bl16" => {
411 self.queue_chunk(tag, size as usize)?;
412 },
413 b"Wave" => {
414 if let Some(stream) = strmgr.get_stream(1) {
415 let mut buf = [0; 12];
416 let mut nsamples = 0;
417 if size >= 12 {
418 self.src.peek_buf(&mut buf)?;
419 nsamples = read_u32be(&buf[0..])?;
420 if nsamples == 0xFFFFFFFF {
421 nsamples = read_u32be(&buf[8..])?;
422 }
423 }
424
425 let mut ts = stream.make_ts(None, None, None);
426 if nsamples != 0 {
427 ts.pts = Some(self.asize);
428 self.asize += u64::from(nsamples);
429 }
430 let pkt = self.src.read_packet(stream, ts, true, size as usize)?;
431 return Ok(pkt);
432 } else {
433 self.src.read_skip(size as usize)?;
434 }
435 },
436 _ => {
437 //println!("unknown tag {}{}{}{} size {:X} @ {:X}", tag[0] as char, tag[1] as char, tag[2] as char, tag[3] as char, size, self.src.tell() - 8);
438 self.src.read_skip(size as usize)?;
439 },
440 };
441 }
442 }
443 }
444
445 impl<'a> DemuxCore<'a> for SmushDemuxer<'a> {
446 fn open(&mut self, strmgr: &mut StreamManager, _seek_index: &mut SeekIndex) -> DemuxerResult<()> {
447 let magic = self.src.read_tag()?;
448 match &magic {
449 b"ANIM" => {
450 self.old = true;
451 },
452 b"SANM" => {
453 self.old = false;
454 },
455 _ => return Err(DemuxerError::InvalidData),
456 };
457 self.size = u64::from(self.src.read_u32be()?);
458 if self.old {
459 self.parse_anim_header(strmgr)?;
460 } else {
461 self.parse_sanm_header(strmgr)?;
462 }
463
464 self.cur_frame = 0;
465 Ok(())
466 }
467
468 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
469 if self.cur_frame > self.nframes { return Err(DemuxerError::EOF); }
470 if self.old {
471 self.get_frame_anim(strmgr)
472 } else {
473 self.get_frame_sanm(strmgr)
474 }
475 }
476
477 fn seek(&mut self, _time: NATimePoint, _seek_index: &SeekIndex) -> DemuxerResult<()> {
478 Err(DemuxerError::NotPossible)
479 }
480 fn get_duration(&self) -> u64 { 0 }
481 }
482
483 impl<'a> NAOptionHandler for SmushDemuxer<'a> {
484 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
485 fn set_options(&mut self, _options: &[NAOption]) { }
486 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
487 }
488
489 pub struct SmushDemuxerCreator { }
490
491 impl DemuxerCreator for SmushDemuxerCreator {
492 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
493 Box::new(SmushDemuxer::new(br))
494 }
495 fn get_name(&self) -> &'static str { "smush" }
496 }
497
498
499 struct MCMPDemuxer<'a> {
500 src: &'a mut ByteReader<'a>,
501 cur_frame: usize,
502
503 offsets: Vec<u64>,
504 sizes: Vec<u32>,
505 samples: Vec<u32>,
506 pts: Vec<u64>,
507 }
508
509 impl<'a> MCMPDemuxer<'a> {
510 fn new(io: &'a mut ByteReader<'a>) -> Self {
511 MCMPDemuxer {
512 src: io,
513 cur_frame: 0,
514
515 offsets: Vec::new(),
516 sizes: Vec::new(),
517 samples: Vec::new(),
518 pts: Vec::new(),
519 }
520 }
521 }
522
523 impl<'a> DemuxCore<'a> for MCMPDemuxer<'a> {
524 fn open(&mut self, strmgr: &mut StreamManager, seek_index: &mut SeekIndex) -> DemuxerResult<()> {
525 let magic = self.src.read_tag()?;
526 validate!(&magic == b"MCMP");
527 let nframes = self.src.read_u16be()? as usize;
528 validate!(nframes > 1);
529 let cmp = self.src.read_byte()?;
530 let size1 = self.src.read_u32be()?;
531 let hdr_size = self.src.read_u32be()?;
532 validate!(cmp == 0 && size1 == hdr_size);
533
534 let size = nframes - 1;
535 self.offsets = Vec::with_capacity(size);
536 self.sizes = Vec::with_capacity(size);
537 self.samples = Vec::with_capacity(size);
538 self.pts = Vec::with_capacity(size);
539
540 let mut start = 0;
541 let mut pts = 0;
542 for _ in 1..nframes {
543 let compr = self.src.read_byte()?;
544 if compr != 1 {
545 return Err(DemuxerError::NotImplemented);
546 }
547 let samples = self.src.read_u32be()? / 2;
548 let size = self.src.read_u32be()?;
549 self.offsets.push(start);
550 self.sizes.push(size);
551 self.samples.push(samples);
552 self.pts.push(pts);
553
554 start += u64::from(size);
555 pts += u64::from(samples);
556 }
557
558 let codecs_desc_size = self.src.read_u16be()? as usize;
559 // todo check it's NULL+VIMA
560 self.src.read_skip(codecs_desc_size)?;
561 let data_start = self.src.tell() + u64::from(hdr_size);
562 let mut arate = 0;
563 let mut abits = 0;
564 let mut chans = 0;
565 if let Ok([b'R', b'I', b'F', b'F']) = self.src.peek_tag() {
566 validate!(hdr_size >= 44);
567 self.src.read_skip(22)?;
568 let c = self.src.read_u16le()?;
569 validate!(c == 1 || c == 2);
570 chans = c as u8;
571 arate = self.src.read_u32le()?;
572 validate!(arate > 0);
573 } else {
574 parse_iact(self.src, data_start, &mut arate, &mut abits, &mut chans, true)?;
575 }
576 if chans == 2 {
577 for (samp, pts) in self.samples.iter_mut().zip(self.pts.iter_mut()) {
578 validate!((*samp & 1) == 0);
579 *samp >>= 1;
580 *pts >>= 1;
581 }
582 pts >>= 1;
583 }
584
585 let ahdr = NAAudioInfo::new(arate, chans, SND_S16_FORMAT, 0);
586 let ainfo = NACodecInfo::new("smush-vima", NACodecTypeInfo::Audio(ahdr), None);
587 if strmgr.add_stream(NAStream::new(StreamType::Audio, 0, ainfo, 1, arate, pts)).is_none() {
588 return Err(DemuxerError::MemoryError);
589 }
590
591 seek_index.mode = SeekIndexMode::Present;
592 seek_index.add_stream(0);
593 let index = seek_index.get_stream_index(0).unwrap();
594 for (i, (off, &pts)) in self.offsets.iter_mut().zip(self.pts.iter()).enumerate() {
595 *off += data_start;
596 index.add_entry(SeekEntry { time: pts * 1000 / u64::from(arate), pts, pos: i as u64 });
597 }
598 index.filled = true;
599
600 self.cur_frame = 0;
601 Ok(())
602 }
603
604 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
605 let idx = self.cur_frame;
606 if idx >= self.offsets.len() { return Err(DemuxerError::EOF); }
607 self.src.seek(SeekFrom::Start(self.offsets[idx]))?;
608 let mut buf = vec![0; self.sizes[idx] as usize + 4];
609 write_u32be(&mut buf, self.samples[idx])?;
610 self.src.read_buf(&mut buf[4..])?;
611
612 let stream = strmgr.get_stream(0).unwrap();
613 let ts = stream.make_ts(Some(self.pts[idx]), None, None);
614
615 self.cur_frame += 1;
616
617 Ok(NAPacket::new(stream, ts, true, buf))
618 }
619
620 fn seek(&mut self, time: NATimePoint, seek_index: &SeekIndex) -> DemuxerResult<()> {
621 if let Some(ret) = seek_index.find_pos(time) {
622 self.cur_frame = ret.pos as usize;
623 Ok(())
624 } else {
625 Err(DemuxerError::SeekError)
626 }
627 }
628 fn get_duration(&self) -> u64 { 0 }
629 }
630
631 impl<'a> NAOptionHandler for MCMPDemuxer<'a> {
632 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
633 fn set_options(&mut self, _options: &[NAOption]) { }
634 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
635 }
636
637 pub struct MCMPDemuxerCreator { }
638
639 impl DemuxerCreator for MCMPDemuxerCreator {
640 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
641 Box::new(MCMPDemuxer::new(br))
642 }
643 fn get_name(&self) -> &'static str { "smush-mcmp" }
644 }
645
646
647 #[cfg(test)]
648 mod test {
649 use super::*;
650 use std::fs::File;
651
652 #[test]
653 fn test_smush_demux_anim_v1() {
654 // sample from Rebel Assault game
655 let mut file = File::open("assets/Game/smush/c1block.anm").unwrap();
656 let mut fr = FileReader::new_read(&mut file);
657 let mut br = ByteReader::new(&mut fr);
658 let mut dmx = SmushDemuxer::new(&mut br);
659 let mut sm = StreamManager::new();
660 let mut si = SeekIndex::new();
661 dmx.open(&mut sm, &mut si).unwrap();
662 loop {
663 let pktres = dmx.get_frame(&mut sm);
664 if let Err(e) = pktres {
665 if (e as i32) == (DemuxerError::EOF as i32) { break; }
666 panic!("error");
667 }
668 let pkt = pktres.unwrap();
669 println!("Got {}", pkt);
670 }
671 }
672 #[test]
673 fn test_smush_demux_anim_v2() {
674 // sample from The Dig
675 let mut file = File::open("assets/Game/smush/PIGOUT.SAN").unwrap();
676 let mut fr = FileReader::new_read(&mut file);
677 let mut br = ByteReader::new(&mut fr);
678 let mut dmx = SmushDemuxer::new(&mut br);
679 let mut sm = StreamManager::new();
680 let mut si = SeekIndex::new();
681 dmx.open(&mut sm, &mut si).unwrap();
682 loop {
683 let pktres = dmx.get_frame(&mut sm);
684 if let Err(e) = pktres {
685 if (e as i32) == (DemuxerError::EOF as i32) { break; }
686 panic!("error");
687 }
688 let pkt = pktres.unwrap();
689 println!("Got {}", pkt);
690 }
691 }
692 #[test]
693 fn test_smush_demux_sanm() {
694 // sample from Grim Fandango
695 let mut file = File::open("assets/Game/smush/lol.snm").unwrap();
696 let mut fr = FileReader::new_read(&mut file);
697 let mut br = ByteReader::new(&mut fr);
698 let mut dmx = SmushDemuxer::new(&mut br);
699 let mut sm = StreamManager::new();
700 let mut si = SeekIndex::new();
701 dmx.open(&mut sm, &mut si).unwrap();
702 loop {
703 let pktres = dmx.get_frame(&mut sm);
704 if let Err(e) = pktres {
705 if (e as i32) == (DemuxerError::EOF as i32) { break; }
706 panic!("error");
707 }
708 let pkt = pktres.unwrap();
709 println!("Got {}", pkt);
710 }
711 }
712 #[test]
713 fn test_mcmp_demux_imus() {
714 // sample from Grim Fandango
715 let mut file = File::open("assets/Game/smush/1104 - Lupe.IMC").unwrap();
716 let mut fr = FileReader::new_read(&mut file);
717 let mut br = ByteReader::new(&mut fr);
718 let mut dmx = MCMPDemuxer::new(&mut br);
719 let mut sm = StreamManager::new();
720 let mut si = SeekIndex::new();
721 dmx.open(&mut sm, &mut si).unwrap();
722 loop {
723 let pktres = dmx.get_frame(&mut sm);
724 if let Err(e) = pktres {
725 if (e as i32) == (DemuxerError::EOF as i32) { break; }
726 panic!("error");
727 }
728 let pkt = pktres.unwrap();
729 println!("Got {}", pkt);
730 }
731 }
732 #[test]
733 fn test_mcmp_demux_wav() {
734 // sample from Grim Fandango
735 let mut file = File::open("assets/Game/smush/breadpor.WAV").unwrap();
736 let mut fr = FileReader::new_read(&mut file);
737 let mut br = ByteReader::new(&mut fr);
738 let mut dmx = MCMPDemuxer::new(&mut br);
739 let mut sm = StreamManager::new();
740 let mut si = SeekIndex::new();
741 dmx.open(&mut sm, &mut si).unwrap();
742 loop {
743 let pktres = dmx.get_frame(&mut sm);
744 if let Err(e) = pktres {
745 if (e as i32) == (DemuxerError::EOF as i32) { break; }
746 panic!("error");
747 }
748 let pkt = pktres.unwrap();
749 println!("Got {}", pkt);
750 }
751 }
752 }