|
| 1 | +// Ogg decoder and encoder written in Rust |
| 2 | +// |
| 3 | +// Copyright (c) 2018 est31 <MTest31@outlook.com> |
| 4 | +// and contributors. All rights reserved. |
| 5 | +// Licensed under MIT license, or Apache 2 license, |
| 6 | +// at your option. Please see the LICENSE file |
| 7 | +// attached to this source distribution for details. |
| 8 | + |
| 9 | +extern crate ogg; |
| 10 | + |
| 11 | +use std::env; |
| 12 | +use ogg::{PacketReader, Packet}; |
| 13 | +use std::fs::File; |
| 14 | + |
| 15 | +fn main() { |
| 16 | + match run() { |
| 17 | + Ok(_) =>(), |
| 18 | + Err(err) => println!("Error: {}", err), |
| 19 | + } |
| 20 | +} |
| 21 | + |
| 22 | +#[allow(dead_code)] |
| 23 | +fn print_u8_slice(arr :&[u8]) { |
| 24 | + if arr.len() <= 4 { |
| 25 | + for a in arr { |
| 26 | + print!("0x{:02x} ", a); |
| 27 | + } |
| 28 | + println!(""); |
| 29 | + return; |
| 30 | + } |
| 31 | + println!("["); |
| 32 | + let mut i :usize = 0; |
| 33 | + while i * 4 < arr.len() - 4 { |
| 34 | + println!("\t0x{:02x}, 0x{:02x}, 0x{:02x}, 0x{:02x},", |
| 35 | + arr[i * 4], arr[i * 4 + 1], arr[i * 4 + 2], arr[i * 4 + 3]); |
| 36 | + i += 1; |
| 37 | + } |
| 38 | + match arr.len() as i64 - i as i64 * 4 { |
| 39 | + 1 => println!("\t0x{:02x}];", arr[i * 4]), |
| 40 | + 2 => println!("\t0x{:02x}, 0x{:02x}];", arr[i * 4], arr[i * 4 + 1]), |
| 41 | + 3 => println!("\t0x{:02x}, 0x{:02x}, 0x{:02x}];", |
| 42 | + arr[i * 4], arr[i * 4 + 1], arr[i * 4 + 2]), |
| 43 | + 4 => println!("\t0x{:02x}, 0x{:02x}, 0x{:02x}, 0x{:02x}];", |
| 44 | + arr[i * 4], arr[i * 4 + 1], arr[i * 4 + 2], arr[i * 4 + 3]), |
| 45 | + de => panic!("impossible value {}", de), |
| 46 | + } |
| 47 | +} |
| 48 | + |
| 49 | +fn dump_pck_info(p :&Packet, ctr :usize) { |
| 50 | + println!("Packet: serial 0x{:08x}, data {:08} large, first {: >5}, last {: >5}, absgp 0x{:016x} nth {}", |
| 51 | + p.stream_serial, p.data.len(), p.first_packet, p.last_packet, |
| 52 | + p.absgp_page, ctr); |
| 53 | + print_u8_slice(&p.data); |
| 54 | +} |
| 55 | + |
| 56 | +fn run() -> Result<(), std::io::Error> { |
| 57 | + let file_path = env::args().nth(1).expect("No arg found. Please specify a file to open."); |
| 58 | + println!("Opening file: {}", file_path); |
| 59 | + let mut f = try!(File::open(file_path)); |
| 60 | + let mut pck_rdr = PacketReader::new(&mut f); |
| 61 | + |
| 62 | + let mut ctr = 0; |
| 63 | + loop { |
| 64 | + let r = pck_rdr.read_packet(); |
| 65 | + match r { |
| 66 | + Ok(Some(p)) => { |
| 67 | + dump_pck_info(&p, ctr); |
| 68 | + // Why do we not check p.last_packet here, and break the loop if false? |
| 69 | + // Well, first, this is only an example. |
| 70 | + // Second, the codecs may end streams in the middle of the file, |
| 71 | + // while still continuing other streams. |
| 72 | + // Therefore, don't do a probably too-early break. |
| 73 | + // Applications which know the codec may know after which |
| 74 | + // ended stream to stop decoding the file and thus not |
| 75 | + // encounter an error. |
| 76 | + }, |
| 77 | + // End of stream |
| 78 | + Ok(None) => break, |
| 79 | + Err(e) => { |
| 80 | + println!("Encountered Error: {:?}", e); |
| 81 | + break; |
| 82 | + } |
| 83 | + } |
| 84 | + ctr+=1; |
| 85 | + } |
| 86 | + Ok(()) |
| 87 | +} |
0 commit comments