diff --git a/Cargo.toml b/Cargo.toml index 6a887e8..6716f09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,10 +15,9 @@ publish = false members = ["src/leela", "src/tycho"] [dependencies] -bitflags = "1.0" -failure = "0.1" -generic-array = "0.12" -serde = {version = "1.0", features = ["derive"]} +bitflags = "1.0" +failure = "0.1" +serde = {version = "1.0", features = ["derive"]} [profile.dev] opt-level = 1 diff --git a/src/marathon/pict.rs b/src/marathon/pict.rs index a2a6725..bb9eab6 100644 --- a/src/marathon/pict.rs +++ b/src/marathon/pict.rs @@ -1,7 +1,6 @@ //! QuickDraw PICT format loader. use crate::durandal::{bin::*, err::*, image::*}; -use generic_array::*; /// Reads a `PixMap` header. fn read_pm_header<'a>(b: &'a [u8], @@ -77,7 +76,7 @@ fn read_pm_ind(mut im: Image8, b: &[u8], hdr: Header) -> ResultS } else if hdr.rle { // RLE compressed 1, 2, 4 or 8 bit colormap indices for _ in 0..im.h() { - let (d, pp) = read_rle(&b[p..], hdr.pitch, false)?; + let (d, pp) = read_rle::(&b[p..], hdr.pitch)?; let d = if hdr.depth < 8 { expand_data(d, hdr.depth)? } else { @@ -117,12 +116,11 @@ fn read_pm_16(mut im: Image8, b: &[u8], hdr: Header) -> ResultS } else if hdr.rle { // RLE compressed R5G5B5 for _ in 0..im.h() { - let (d, pp) = read_rle(&b[p..], hdr.pitch, true)?; + let (d, pp) = read_rle::(&b[p..], hdr.pitch)?; p += pp; - for x in 0..im.w() { - let cr = u16b(&d[x * 2..]); + for &cr in &d { im.cr.push(r5g5b5_to_rgb8(cr)); } } @@ -167,7 +165,7 @@ fn read_pm_32(mut im: Image8, b: &[u8], hdr: Header) -> ResultS // RLE compressed RGB8 let pitch = hdr.pitch - im.w(); // remove padding byte from pitch for _ in 0..im.h() { - let (d, pp) = read_rle(&b[p..], pitch, false)?; + let (d, pp) = read_rle::(&b[p..], pitch)?; p += pp; @@ -230,11 +228,11 @@ pub fn load_pict(b: &[u8]) -> ResultS // PackBitsRgn return read_pm_area(im, &b[p..], true, true); } - 0x009a => { + 0x009A => { // DirectBitsRect return read_pm_area(im, &b[p..], false, false); } - 0x009b => { + 0x009B => { // DirectBitsRgn return read_pm_area(im, &b[p..], false, true); } @@ -242,57 +240,57 @@ pub fn load_pict(b: &[u8]) -> ResultS // CompressedQuickTime unimplemented!(); } - 0x00ff => { + 0x00FF => { // OpEndPic break; } // help i'm trapped in an awful metafile format from the 80s 0x0000 | // NoOp - 0x001c | // HiliteMode - 0x001e | // DefHilite + 0x001C | // HiliteMode + 0x001E | // DefHilite 0x0038 | // FrameSameRect 0x0039 | // PaintSameRect - 0x003a | // EraseSameRect - 0x003b | // InvertSameRect - 0x003c | // FillSameRect + 0x003A | // EraseSameRect + 0x003B | // InvertSameRect + 0x003C | // FillSameRect 0x8000 | // Reserved 0x8100 => (), // Reserved 0x0003 | // TxFont 0x0004 | // TxFace 0x0005 | // TxMode 0x0008 | // PnMode - 0x000d | // TxSize + 0x000D | // TxSize 0x0011 | // VersionOp 0x0015 | // PnLocHFrac 0x0016 | // ChExtra 0x0023 | // ShortLineFrom - 0x00a0 => p += 2, // ShortComment + 0x00A0 => p += 2, // ShortComment 0x0006 | // SpExtra 0x0007 | // PnSize - 0x000b | // OvSize - 0x000c | // Origin - 0x000e | // FgCol - 0x000f | // BkCol + 0x000B | // OvSize + 0x000C | // Origin + 0x000E | // FgCol + 0x000F | // BkCol 0x0021 => p += 4, // LineFrom - 0x001a | // RGBFgCol - 0x001b | // RGBBkCol - 0x001d | // TxRatio + 0x001A | // RGBFgCol + 0x001B | // RGBBkCol + 0x001D | // TxRatio 0x0022 => p += 6, // ShortLine 0x0002 | // BkPat 0x0009 | // PnPat 0x0010 | // TxRatio 0x0020 | // Line - 0x002e | // GlyphState + 0x002E | // GlyphState 0x0030 | // FrameRect 0x0031 | // PaintRect 0x0032 | // EraseRect 0x0033 | // InvertRect 0x0034 => p += 8, // FillRect - 0x002d => p += 10, // LineJustify + 0x002D => p += 10, // LineJustify 0x0001 => p += (u16b(&b[p.. ]) & !1) as usize, // Clip - 0x00a1 => p += (u16b(&b[p+2..]) & !1) as usize + 2, // LongComment + 0x00A1 => p += (u16b(&b[p+2..]) & !1) as usize + 2, // LongComment 0x100..= - 0x7fff => p += (op >> 8) as usize * 2, // Reserved + 0x7FFF => p += (op >> 8) as usize * 2, // Reserved _ => { bail!("invalid op in PICT"); } @@ -338,7 +336,8 @@ pub fn get_clut(b: &[u8]) -> ResultS<(Vec, usize)> } /// Read run-length encoded data. -pub fn read_rle(b: &[u8], pitch: usize, ln: bool) -> ResultS<(Vec, usize)> +fn read_rle(b: &[u8], pitch: usize) -> ResultS<(Vec, usize)> + where T: ReadRleData { let mut p = 0; let mut o = Vec::with_capacity(pitch); @@ -357,11 +356,7 @@ pub fn read_rle(b: &[u8], pitch: usize, ln: bool) -> ResultS<(Vec, usize)> p += 1; o.reserve(len); - if ln { - read_rle_data(cmp, len, &mut o, || (arr![u8; b[p], b[p+1]], p += 2).0); - } else { - read_rle_data(cmp, len, &mut o, || (arr![u8; b[p] ], p += 1).0); - } + T::read_rle_data(b, &mut p, cmp, len, &mut o); } if o.len() == pitch { @@ -371,23 +366,59 @@ pub fn read_rle(b: &[u8], pitch: usize, ln: bool) -> ResultS<(Vec, usize)> } } -/// Read a sequence of packed RLE data. -fn read_rle_data(cmp: bool, len: usize, out: &mut Vec, mut read: F) - where F: FnMut() -> GenericArray, - N: ArrayLength +trait ReadRleData: Sized { - if cmp { - let d = read(); - for _ in 0..len { - for v in d.iter() { - out.push(*v); + /// Read a sequence of packed RLE data. + fn read_rle_data(b: &[u8], + p: &mut usize, + cmp: bool, + len: usize, + out: &mut Vec); +} + +impl ReadRleData for u16 +{ + fn read_rle_data(b: &[u8], + p: &mut usize, + cmp: bool, + len: usize, + out: &mut Vec) + { + if cmp { + let d = u16b(&b[*p..*p + 2]); + *p += 2; + for _ in 0..len { + out.push(d); + } + } else { + for _ in 0..len { + let d = u16b(&b[*p..*p + 2]); + *p += 2; + out.push(d); } } - } else { - for _ in 0..len { - let d = read(); - for v in d.iter() { - out.push(*v); + } +} + +impl ReadRleData for u8 +{ + fn read_rle_data(b: &[u8], + p: &mut usize, + cmp: bool, + len: usize, + out: &mut Vec) + { + if cmp { + let d = b[*p]; + *p += 1; + for _ in 0..len { + out.push(d); + } + } else { + for _ in 0..len { + let d = b[*p]; + *p += 1; + out.push(d); } } } diff --git a/src/marathon/wad.rs b/src/marathon/wad.rs index e7b5717..8c58bd2 100644 --- a/src/marathon/wad.rs +++ b/src/marathon/wad.rs @@ -115,11 +115,11 @@ pub fn read_wad(b: &[u8]) -> ResultS let siz_ent = if is_old {8 } else {10}; let siz_cnk = if is_old {12} else {16}; - if siz_ent != wentsize { + if siz_ent != siz_went { bail!("invalid entry size"); } - if siz_cnk != wcnksize { + if siz_cnk != siz_wcnk { bail!("invalid chunk size"); }