From 2a3dd595702107d30b94258fe4c449c5ba8f3c8e Mon Sep 17 00:00:00 2001 From: Marrub Date: Tue, 11 Dec 2018 02:32:59 -0500 Subject: [PATCH] clean up code --- src/durandal/image.rs | 4 +- src/durandal/machead.rs | 6 +- src/durandal/pict.rs | 181 +++++++++++++++++----------------------- src/durandal/text.rs | 21 ++--- src/main.rs | 59 ++++++------- src/marathon/term.rs | 9 +- src/marathon/wad.rs | 117 +++++++++++++------------- 7 files changed, 172 insertions(+), 225 deletions(-) diff --git a/src/durandal/image.rs b/src/durandal/image.rs index 763271a..994e629 100644 --- a/src/durandal/image.rs +++ b/src/durandal/image.rs @@ -16,8 +16,8 @@ pub struct Color /// Image with width and height. pub struct Image { - w: usize, - h: usize, + w: usize, + h: usize, pub cr: Vec, } diff --git a/src/durandal/machead.rs b/src/durandal/machead.rs index 9a0b0e0..8e78d5a 100644 --- a/src/durandal/machead.rs +++ b/src/durandal/machead.rs @@ -9,8 +9,7 @@ pub fn check_apple_single(b: &[u8]) -> Option let num = b.o_u16b(24)? as usize; - for i in 0..num - { + for i in 0..num { let p = 26 + (12 * i); let fid = b.o_u32b(p )?; let ofs = b.o_u32b(p+4)? as usize; @@ -30,8 +29,7 @@ pub fn check_mac_bin(b: &[u8]) -> Option let mut crc = 0; for i in 0..124 { - for j in 8..16 - { + for j in 8..16 { let d = b[i] as (u16) << j; if (d ^ crc) & 0x8000 != 0 {crc = crc << 1 ^ 0x1021} else {crc <<= 1} diff --git a/src/durandal/pict.rs b/src/durandal/pict.rs index 3e0efe3..c5a798f 100644 --- a/src/durandal/pict.rs +++ b/src/durandal/pict.rs @@ -21,16 +21,15 @@ fn get_clut(b: &[u8]) -> ResultS> map.resize(num, Color{r: 0, g: 0, b: 0, a: 0}); - for i in 0..num - { + for i in 0..num { let p = 8 + i * 8; - let n = (b.c_u16b(p )? & 0xff) as usize; - let r = (b.c_u16b(p+2)? >> 8 ) as u8; - let g = (b.c_u16b(p+4)? >> 8 ) as u8; - let b = (b.c_u16b(p+6)? >> 8 ) as u8; + let n = if !dev {(b.c_u16b(p )? & 0xff) as usize} else {i}; + let r = (b.c_u16b(p+2)? >> 8) as u8; + let g = (b.c_u16b(p+4)? >> 8) as u8; + let b = (b.c_u16b(p+6)? >> 8) as u8; // with device mapping, we ignore the index entirely - map[if dev {i} else {n}] = Color{r, g, b, a: 255}; + map[n] = Color{r, g, b, a: 255}; } Ok(map) @@ -41,13 +40,12 @@ fn read_rle_data(cmp: bool, len: usize, o: &mut Vec, mut rd: F) where F: FnMut() -> GenericArray, N: ArrayLength { - if cmp - { + if cmp { let d = rd(); - for _ in 0..len {for v in d.iter() {o.push(*v)}} + for _ in 0..len {for v in d.iter() {o.push(*v)}} + } else { + for _ in 0..len {let d = rd(); for v in d.iter() {o.push(*v)}} } - else - {for _ in 0..len {let d = rd(); for v in d.iter() {o.push(*v)}}} } /// Read run-length encoded data. @@ -58,8 +56,7 @@ fn read_rle(b: &[u8], pt: usize, ln: bool) -> ResultS<(Vec, usize)> let sz = if pt > 250 {(b.c_u16b(0)? as usize + 2, p += 2).0} else {(b[0] as usize + 1, p += 1).0}; - while p < sz - { + while p < sz { let szf = b[(p, p += 1).0]; let cmp = szf & 0x80 != 0; let len = if cmp {!szf + 2} else {szf + 1} as usize; @@ -84,8 +81,7 @@ fn expand_data(b: Vec, depth: u16) -> ResultS> _ => return Err("invalid bit depth") }); - for ch in b - { + for ch in b { match depth { 4 => for i in 1..=0 {o.push(ch >> i * 4 & 0xfu8)}, // 2 nibbles 2 => for i in 3..=0 {o.push(ch >> i * 2 & 0x3u8)}, // 4 dibits @@ -100,8 +96,6 @@ fn expand_data(b: Vec, depth: u16) -> ResultS> /// Process a CopyBits operation. fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> ResultS { - const SIZE_HEAD: usize = 46; - let mut p = if !packed {4} else {0}; // baseAddr let (w, h) = (im.w(), im.h()); @@ -124,7 +118,7 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result // = b.c_u32b(p+38)?; pmTable // = b.c_u32b(p+42)?; pmReserved - p += SIZE_HEAD; + p += 46; // size of header if pf & 0x8000 == 0 {return Err("PICT1 not supported")} if xe - xb != w || ye - yb != h {return Err("image bounds are incorrect")} @@ -143,22 +137,17 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result match dept { 1 | 2 | 4 | 8 => - // uncompressed 8-bit colormap indices - if pt < 8 && dept == 8 - { + if pt < 8 && dept == 8 { + // uncompressed 8-bit colormap indices for _ in 0..h { for _ in 0..w {im.cr.push(map[b[(p, p += 1).0] as usize].clone())} } Ok(im) - } - - // RLE compressed 1, 2, 4 or 8 bit colormap indices - else if rle - { - for _ in 0..h - { + } else if rle { + // RLE compressed 1, 2, 4 or 8 bit colormap indices + for _ in 0..h { let (d, pp) = read_rle(&b[p..], pt, false)?; let d = if dept < 8 {expand_data(d, dept)?} else {d}; @@ -169,26 +158,19 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result Ok(im) } - - // invalid else {Err("invalid configuration")}, 16 => - // uncompressed R5G5B5 - if pt < 8 || pack == PACK_NONE - { + if pt < 8 || pack == PACK_NONE { + // uncompressed R5G5B5 for _ in 0..h { for _ in 0..w {im.cr.push(Color::from_r5g5b5(b.c_u16b((p, p += 2).0)?))} } Ok(im) - } - - // RLE compressed R5G5B5 - else if rle - { - for _ in 0..h - { + } else if rle { + // RLE compressed R5G5B5 + for _ in 0..h { let (d, pp) = read_rle(&b[p..], pt, true)?; p += pp; @@ -199,16 +181,12 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result Ok(im) } - - // invalid else {Err("invalid configuration")}, 32 => - // uncompressed RGB8 or XRGB8 - if pt < 8 || pack == PACK_NONE || pack == PACK_NOPAD - { + if pt < 8 || pack == PACK_NONE || pack == PACK_NOPAD { + // uncompressed RGB8 or XRGB8 for _ in 0..h { - for _ in 0..w - { + for _ in 0..w { if pack != PACK_NOPAD {p += 1}; let (r, g, b) = (b[p], b[p+1], b[p+2]); p += 3; @@ -217,20 +195,15 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result } Ok(im) - } - - // RLE compressed RGB8 - else if rle - { + } else if rle { + // RLE compressed RGB8 let pt = pt - w; // remove padding byte from pitch - for _ in 0..h - { + for _ in 0..h { let (d, pp) = read_rle(&b[p..], pt, false)?; p += pp; - for x in 0..w - { + for x in 0..w { let (r, g, b) = (d[x+w*0], d[x+w*1], d[x+w*2]); im.cr.push(Color{r, g, b, a: 255}); } @@ -238,8 +211,6 @@ fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Result Ok(im) } - - // invalid else {Err("invalid configuration")}, _ => Err("invalid bit depth") } @@ -252,18 +223,16 @@ fn read_quicktime_c(_im: Image, _b: &[u8]) -> ResultS /// Load a PICT image. pub fn load_pict(b: &[u8]) -> ResultS { - const SIZE_HEAD: usize = 10; + // size = b.c_u16b(0)?; + // top = b.c_u16b(2)?; + // left = b.c_u16b(4)?; + let h = b.c_u16b(6)? as usize; + let w = b.c_u16b(8)? as usize; + let im = Image::new(w, h); - // size = b.c_u16b(0)?; - // top = b.c_u16b(2)?; - // left = b.c_u16b(4)?; - let h = b.c_u16b(6)? as usize; - let w = b.c_u16b(8)? as usize; - let im = Image::new(w, h); - let mut p = SIZE_HEAD; + let mut p = 10; // size of header - while p < b.len() - { + while p < b.len() { let op = b.c_u16b((p, p += 2).0)?; match op { @@ -274,47 +243,47 @@ pub fn load_pict(b: &[u8]) -> ResultS 0x8200 => return read_quicktime_c(im, &b[p..]), // CompressedQuickTime 0x00ff => break, // OpEndPic // help i'm trapped in an awful metafile format from the 80s - 0x0000 => (), // NoOp - 0x001c => (), // HiliteMode - 0x001e => (), // DefHilite - 0x0038 => (), // FrameSameRect - 0x0039 => (), // PaintSameRect - 0x003a => (), // EraseSameRect - 0x003b => (), // InvertSameRect - 0x003c => (), // FillSameRect - 0x8000 => (), // Reserved + 0x0000 | // NoOp + 0x001c | // HiliteMode + 0x001e | // DefHilite + 0x0038 | // FrameSameRect + 0x0039 | // PaintSameRect + 0x003a | // EraseSameRect + 0x003b | // InvertSameRect + 0x003c | // FillSameRect + 0x8000 | // Reserved 0x8100 => (), // Reserved - 0x0003 => p += 2, // TxFont - 0x0004 => p += 2, // TxFace - 0x0005 => p += 2, // TxMode - 0x0008 => p += 2, // PnMode - 0x000d => p += 2, // TxSize - 0x0011 => p += 2, // VersionOp - 0x0015 => p += 2, // PnLocHFrac - 0x0016 => p += 2, // ChExtra - 0x0023 => p += 2, // ShortLineFrom - 0x00a0 => p += 2, // ShortComment + 0x0003 | // TxFont + 0x0004 | // TxFace + 0x0005 | // TxMode + 0x0008 | // PnMode + 0x000d | // TxSize + 0x0011 | // VersionOp + 0x0015 | // PnLocHFrac + 0x0016 | // ChExtra + 0x0023 | // ShortLineFrom + 0x00a0 | // ShortComment 0x02ff => p += 2, // Version - 0x0006 => p += 4, // SpExtra - 0x0007 => p += 4, // PnSize - 0x000b => p += 4, // OvSize - 0x000c => p += 4, // Origin - 0x000e => p += 4, // FgCol - 0x000f => p += 4, // BkCol + 0x0006 | // SpExtra + 0x0007 | // PnSize + 0x000b | // OvSize + 0x000c | // Origin + 0x000e | // FgCol + 0x000f | // BkCol 0x0021 => p += 4, // LineFrom - 0x001a => p += 6, // RGBFgCol - 0x001b => p += 6, // RGBBkCol - 0x001d => p += 6, // TxRatio + 0x001a | // RGBFgCol + 0x001b | // RGBBkCol + 0x001d | // TxRatio 0x0022 => p += 6, // ShortLine - 0x0002 => p += 8, // BkPat - 0x0009 => p += 8, // PnPat - 0x0010 => p += 8, // TxRatio - 0x0020 => p += 8, // Line - 0x002e => p += 8, // GlyphState - 0x0030 => p += 8, // FrameRect - 0x0031 => p += 8, // PaintRect - 0x0032 => p += 8, // EraseRect - 0x0033 => p += 8, // InvertRect + 0x0002 | // BkPat + 0x0009 | // PnPat + 0x0010 | // TxRatio + 0x0020 | // Line + 0x002e | // GlyphState + 0x0030 | // FrameRect + 0x0031 | // PaintRect + 0x0032 | // EraseRect + 0x0033 | // InvertRect 0x0034 => p += 8, // FillRect 0x002d => p += 10, // LineJustify 0x0c00 => p += 24, // HeaderOp diff --git a/src/durandal/text.rs b/src/durandal/text.rs index bf104db..a278891 100644 --- a/src/durandal/text.rs +++ b/src/durandal/text.rs @@ -3,18 +3,16 @@ /// Formats a binary size string for any given number. pub fn to_binsize(n: u64) -> String { - let names = ["kB", "MB", "GB", "TB"]; + const NAMES: [&str; 4] = ["kB", "MB", "GB", "TB"]; // empty size if n == 0 {return String::from("empty")} // terabytes, gigabytes, megabytes, kilobytes - for i in 4..=1 - { - if n >= 1000u64.pow(i) - { + for i in 4..=1 { + if n >= 1000u64.pow(i) { let x = n as f64 / 1000f64.powi(i as i32); - return format!("{:1}{}", x, names[i as usize - 1]) + return format!("{:1}{}", x, NAMES[i as usize - 1]) } } @@ -38,14 +36,11 @@ pub fn fuck_string(s: &[u8]) -> Vec /// Converts input from Mac Roman to a Unicode string. pub fn mac_roman_conv(s: &[u8]) -> String { - let l = s.len(); - let mut v = String::with_capacity(l); + let mut v = String::with_capacity(s.len()); - for i in 0..l - { - if s[i] == 0 {break} - - if s[i] & 0x80 != 0 {v.push(TR[s[i] as usize & 0x7f])} + for i in 0..s.len() { + if s[i] == 0 {break} + else if s[i] & 0x80 != 0 {v.push(TR[s[i] as usize & 0x7f])} else if s[i] == b'\r' {v.push('\n')} else {v.push(s[i] as char)} } diff --git a/src/main.rs b/src/main.rs index 7194bee..48e1ad2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,14 +19,13 @@ use crate::durandal::bin::ResultS; #[derive(Debug)] struct Minf { - env: u16, - phy: u16, - mus: u16, - mfl: u16, - efl: u16, - epf: u32, - bip: bool, - nam: String, + env_code: u16, + physi_id: u16, + music_id: u16, + msn_flag: u16, + env_flag: u16, + ent_flag: u32, + levelnam: String, } impl Minf @@ -38,16 +37,15 @@ impl Minf if b.len() < 88 {return Err("not enough data for Minf")} - let env = b.c_u16b( 0)?; - let phy = b.c_u16b( 2)?; - let mus = b.c_u16b( 4)?; - let mfl = b.c_u16b( 6)?; - let efl = b.c_u16b( 8)?; - let bip = b[10] != 0; - let nam = mac_roman_conv(&b[18..84]); - let epf = b.c_u32b(84)?; + let env_code = b.c_u16b( 0)?; + let physi_id = b.c_u16b( 2)?; + let music_id = b.c_u16b( 4)?; + let msn_flag = b.c_u16b( 6)?; + let env_flag = b.c_u16b( 8)?; + let levelnam = mac_roman_conv(&b[18..84]); + let ent_flag = b.c_u32b(84)?; - Ok(Minf{env, phy, mus, mfl, efl, epf, bip, nam}) + Ok(Minf{env_code, physi_id, music_id, msn_flag, env_flag, ent_flag, levelnam}) } } @@ -59,8 +57,7 @@ fn write_ppm(fname: &str, im: &Image) -> io::Result<()> write!(&mut out, "P3\n{} {}\n255\n", im.w(), im.h())?; for y in 0..im.h() { - for x in 0..im.w() - { + for x in 0..im.w() { let cr = &im[(x, y)]; write!(&mut out, "{} {} {} ", cr.r, cr.g, cr.b)?; } @@ -78,10 +75,8 @@ fn main() -> io::Result<()> println!("{:#?}", wad); - for (id, ent) in wad.ent - { - if let Some(b) = ent.map.get(b"PICT") - { + for (id, ent) in wad.entries { + if let Some(b) = ent.chunks.get(b"PICT") { match load_pict(b) { Ok(im) => { println!("entry {} has PICT {}x{}", id, im.w(), im.h()); @@ -91,19 +86,17 @@ fn main() -> io::Result<()> } } - if let Some(b) = ent.map.get(b"term") - { - match term::Terminal::chunk(b) { - Ok(c) => println!("entry {} has term {:#?}", id, c), - Err(e) => println!("entry {} has term (invalid: {:?})", id, e), + if let Some(b) = ent.chunks.get(b"Minf") { + match Minf::chunk(b) { + Ok (c) => println!("entry {} has Minf {:#?}", id, c), + Err(e) => println!("entry {} has Minf (invalid: {:?})", id, e), } } - if let Some(b) = ent.map.get(b"Minf") - { - match Minf::chunk(b) { - Ok(c) => println!("entry {} has Minf {:#?}", id, c), - Err(e) => println!("entry {} has Minf (invalid: {:?})", id, e), + if let Some(b) = ent.chunks.get(b"term") { + match term::Terminal::chunk(b) { + Ok (c) => println!("entry {} has term {:#?}", id, c), + Err(e) => println!("entry {} has term (invalid: {:?})", id, e), } } } diff --git a/src/marathon/term.rs b/src/marathon/term.rs index 5583e4e..52b06e2 100644 --- a/src/marathon/term.rs +++ b/src/marathon/term.rs @@ -23,8 +23,7 @@ impl Terminal let mut p = SIZE_HEAD; - for _ in 0..gnu - { + for _ in 0..gnu { // flg = b.c_u16b(p )?; let typ = b.c_u16b(p+ 2)?.into(); let per = b.c_i16b(p+ 4)?; @@ -43,8 +42,7 @@ impl Terminal p += SIZE_GROUP; } - for _ in 0..fnu - { + for _ in 0..fnu { let ind = b.c_u16b(p )?; let fce = b.c_u16b(p+2)?; let col = b.c_u16b(p+4)?; @@ -62,8 +60,7 @@ impl Terminal let mut v = Vec::new(); let mut p = 0; - while p < b.len() - { + while p < b.len() { let sta = p; let (len, trm) = Terminal::read(&b[p..])?; diff --git a/src/marathon/wad.rs b/src/marathon/wad.rs index f0b9902..96d6c85 100644 --- a/src/marathon/wad.rs +++ b/src/marathon/wad.rs @@ -13,27 +13,27 @@ type EntryMap<'a> = BTreeMap>; pub struct Entry<'a> { - pub map: ChunkMap<'a>, - pub ext: &'a[u8], + pub chunks: ChunkMap<'a>, + pub appdata: &'a[u8], } #[derive(Debug)] pub struct Wad<'a> { - ver: Ver, - dvr: u16, - ext: usize, - nam: String, - pub ent: EntryMap<'a>, + wadver: Ver, + dataver: u16, + origname: String, + appsize: usize, + pub entries: EntryMap<'a>, } #[derive(Debug)] pub enum Ver { - MI, - M2, - M1Dir, - M1 + Base, + Dir, + Over, + MI } impl<'a> fmt::Debug for Entry<'a> @@ -41,7 +41,7 @@ impl<'a> fmt::Debug for Entry<'a> fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Entry{{ ")?; - for (k, _) in &self.map {write!(f, "{} ", mac_roman_conv(&k[..]))?} + for (ident, _) in &self.chunks {write!(f, "{} ", mac_roman_conv(ident))?} write!(f, "}}") } } @@ -50,79 +50,74 @@ impl<'a> Wad<'a> { pub fn new(b: &[u8]) -> ResultS { - const SIZE_ENTRY_NEW: usize = 10; - const SIZE_ENTRY_OLD: usize = 8; - let b = &b[try_mac_header(b)..]; - if b.len() < 128 {return Err("not enough data for header")} + if b.len() < 128 {return Err("not enough data for Wad header")} - let ver = b.c_u16b( 0)?; - let dvr = b.c_u16b( 2)?; - let nam = &b[4..68]; - // crc = b.c_u32b(68)?; - let dir = b.c_u32b(72)? as usize; - let num = b.c_u16b(76)? as usize; - let ext = b.c_u16b(78)? as usize; - // hdr = b.c_u16b(80)?; - // bsz = b.c_u16b(82)?; - // pck = b.c_u32b(84)?; + let wadver = b.c_u16b( 0)?; + let dataver = b.c_u16b( 2)?; + let origname = mac_roman_conv(&b[4..68]); + // crc = b.c_u32b(68)?; + let dirofs = b.c_u32b(72)? as usize; + let numents = b.c_u16b(76)? as usize; + let appsize = b.c_u16b(78)? as usize; + // chnksize = b.c_u16b(80)?; + // entsize = b.c_u16b(82)?; + // parent = b.c_u32b(84)?; - let ver = match ver { + let wadver = match wadver { 4 => Ver::MI, - 2 => Ver::M2, - 1 => Ver::M1Dir, - 0 => Ver::M1, - _ => return Err("invalid wad version"), + 2 => Ver::Over, + 1 => Ver::Dir, + 0 => Ver::Base, + _ => return Err("invalid Wad version"), }; - let mut map = EntryMap::new(); - let mut p = dir; - let o = match ver {Ver::M1 | Ver::M1Dir => true, _ => false}; - let h = if o {SIZE_ENTRY_OLD} else {SIZE_ENTRY_NEW}; + let is_old = match wadver {Ver::Base => true, _ => false}; + let entsize = if is_old {8} else {10}; - for i in 0..num + let mut entries = EntryMap::new(); + let mut p = dirofs; + + for i in 0..numents { - let ofs = b.c_u32b(p )? as usize; - let len = b.c_u32b(p+4)? as usize; - let ind = if o {i as u16} - else {b.c_u16b(p+8)?}; + let offset = b.c_u32b(p )? as usize; + let size = b.c_u32b(p+4)? as usize; + let index = if !is_old {b.c_u16b(p+8)?} else {i as u16}; - if ofs + len > b.len() {return Err("not enough data for entry")} + if offset + size > b.len() {return Err("not enough data for entry")} - let ent = Entry{map: get_chunks(&b[ofs..ofs+len], o)?, - ext: &b[p+h..p+h+ext]}; + let chunks = get_chunks(&b[offset..offset+size], is_old)?; + let appdata = &b[p+entsize..p+entsize+appsize]; - map.insert(ind, ent); + entries.insert(index, Entry{chunks, appdata}); - p += h + ext; + p += entsize + appsize; } - Ok(Wad{ver, dvr, ext, - nam: mac_roman_conv(nam), - ent: map}) + Ok(Wad{wadver, dataver, appsize, origname, entries}) } } -fn get_chunks(b: &[u8], o: bool) -> ResultS +fn get_chunks(b: &[u8], is_old: bool) -> ResultS { - const SIZE_CHUNK_NEW: usize = 16; - const SIZE_CHUNK_OLD: usize = 12; + let chnksize = if !is_old {16} else {12}; - let mut map = ChunkMap::new(); - let mut p = 0; - let h = if o {SIZE_CHUNK_OLD} else {SIZE_CHUNK_NEW}; + let mut chunks = ChunkMap::new(); + let mut p = 0; while p < b.len() { - let k = b.c_iden(p )?; - // nx = b.c_u32b(p+ 4)?; - let l = b.c_u32b(p+ 8)? as usize; - // o = b.c_u32b(p+12)?; - map.insert(k, &b[p+h ..p+h+l]); - p += l + h; + let ident = b.c_iden(p )?; + // offset = b.c_u32b(p+ 4)?; + let size = b.c_u32b(p+ 8)? as usize; + // patchofs = b.c_u32b(p+12)?; + let beg = p + chnksize; + let end = beg + size; + chunks.insert(ident, &b[beg..end]); + p = end; } - Ok(map) + Ok(chunks) } // EOF