diff --git a/rustfmt.toml b/rustfmt.toml index d20889d..a932feb 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -2,6 +2,7 @@ binop_separator = "Back" brace_style = "AlwaysNextLine" condense_wildcard_suffixes = true enum_discrim_align_threshold = 40 +fn_single_line = true format_doc_comments = true format_macro_matchers = true format_strings = true diff --git a/src/durandal/bin.rs b/src/durandal/bin.rs index a4e0eec..5cf926d 100644 --- a/src/durandal/bin.rs +++ b/src/durandal/bin.rs @@ -12,23 +12,63 @@ pub trait BinUtil fn c_u16b(&self, i: usize) -> ResultS; fn c_i32b(&self, i: usize) -> ResultS - {match self.c_u32b(i) {Ok(n) => Ok(n as i32), Err(e) => Err(e)}} + { + match self.c_u32b(i) { + Ok(n) => Ok(n as i32), + Err(e) => Err(e), + } + } fn c_i16b(&self, i: usize) -> ResultS - {match self.c_u16b(i) {Ok(n) => Ok(n as i16), Err(e) => Err(e)}} + { + match self.c_u16b(i) { + Ok(n) => Ok(n as i16), + Err(e) => Err(e), + } + } // Optional - fn o_iden(&self, i: usize) -> Option {self.c_iden(i).ok()} - fn o_u32b(&self, i: usize) -> Option {self.c_u32b(i).ok()} - fn o_u16b(&self, i: usize) -> Option {self.c_u16b(i).ok()} - fn o_i32b(&self, i: usize) -> Option {self.c_i32b(i).ok()} - fn o_i16b(&self, i: usize) -> Option {self.c_i16b(i).ok()} + fn o_iden(&self, i: usize) -> Option + { + self.c_iden(i).ok() + } + fn o_u32b(&self, i: usize) -> Option + { + self.c_u32b(i).ok() + } + fn o_u16b(&self, i: usize) -> Option + { + self.c_u16b(i).ok() + } + fn o_i32b(&self, i: usize) -> Option + { + self.c_i32b(i).ok() + } + fn o_i16b(&self, i: usize) -> Option + { + self.c_i16b(i).ok() + } // Unchecked - fn b_iden(&self, i: usize) -> Ident {self.c_iden(i).unwrap()} - fn b_u32b(&self, i: usize) -> u32 {self.c_u32b(i).unwrap()} - fn b_u16b(&self, i: usize) -> u16 {self.c_u16b(i).unwrap()} - fn b_i32b(&self, i: usize) -> i32 {self.c_i32b(i).unwrap()} - fn b_i16b(&self, i: usize) -> i16 {self.c_i16b(i).unwrap()} + fn b_iden(&self, i: usize) -> Ident + { + self.c_iden(i).unwrap() + } + fn b_u32b(&self, i: usize) -> u32 + { + self.c_u32b(i).unwrap() + } + fn b_u16b(&self, i: usize) -> u16 + { + self.c_u16b(i).unwrap() + } + fn b_i32b(&self, i: usize) -> i32 + { + self.c_i32b(i).unwrap() + } + fn b_i16b(&self, i: usize) -> i16 + { + self.c_i16b(i).unwrap() + } } impl BinUtil for [u8] @@ -45,7 +85,10 @@ impl BinUtil for [u8] fn c_u32b(&self, i: usize) -> ResultS { if i + 3 < self.len() { - Ok(u32::from_be_bytes([self[i], self[i + 1], self[i + 2], self[i + 3]])) + Ok(u32::from_be_bytes([self[i], + self[i + 1], + self[i + 2], + self[i + 3]])) } else { Err(err_msg("not enough data")) } @@ -61,9 +104,21 @@ impl BinUtil for [u8] } } -pub fn d_u32b(n: u32) -> [u8; 4] {n.to_be_bytes()} -pub fn d_u16b(n: u16) -> [u8; 2] {n.to_be_bytes()} -pub fn d_i32b(n: i32) -> [u8; 4] {d_u32b(n as u32)} -pub fn d_i16b(n: i16) -> [u8; 2] {d_u16b(n as u16)} +pub fn d_u32b(n: u32) -> [u8; 4] +{ + n.to_be_bytes() +} +pub fn d_u16b(n: u16) -> [u8; 2] +{ + n.to_be_bytes() +} +pub fn d_i32b(n: i32) -> [u8; 4] +{ + d_u32b(n as u32) +} +pub fn d_i16b(n: i16) -> [u8; 2] +{ + d_u16b(n as u16) +} // EOF diff --git a/src/durandal/crc.rs b/src/durandal/crc.rs index 692e86b..2aebe7d 100644 --- a/src/durandal/crc.rs +++ b/src/durandal/crc.rs @@ -2,21 +2,27 @@ fn crc_accum(a: u32) -> u32 { - if a & 1 == 1 {0xedb88320 ^ a >> 1} - else {a >> 1} + if a & 1 == 1 { + 0xedb88320 ^ a >> 1 + } else { + a >> 1 + } } fn crc_init() -> [u32; 256] { let mut t = [0; 256]; - for n in 0..256 {t[n] = (0..8).fold(n as u32, |a, _| crc_accum(a));} + for n in 0..256 { + t[n] = (0..8).fold(n as u32, |a, _| crc_accum(a)); + } t } pub fn crc32(b: &[u8], s: u32) -> u32 { let t = crc_init(); - !b.iter().fold(s, |a, &o| {a >> 8 ^ t[(a & 0xff ^ o as u32) as usize]}) + !b.iter() + .fold(s, |a, &o| a >> 8 ^ t[(a & 0xff ^ o as u32) as usize]) } #[test] diff --git a/src/durandal/err.rs b/src/durandal/err.rs index 1889c30..a443505 100644 --- a/src/durandal/err.rs +++ b/src/durandal/err.rs @@ -1,6 +1,6 @@ //! Error handling. -pub use failure::{Error, Fail, err_msg}; +pub use failure::{err_msg, Error, Fail}; use crate::durandal::traits::PrimInt; use std::fmt; @@ -13,13 +13,17 @@ impl Fail for ReprError where T: PrimInt {} impl fmt::Display for ReprError where T: PrimInt { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result - {write!(f, "representation error (got {})", self.0)} + { + write!(f, "representation error (got {})", self.0) + } } impl fmt::Debug for ReprError where T: PrimInt { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result - {fmt::Display::fmt(self, f)} + { + fmt::Display::fmt(self, f) + } } pub type ResultS = Result; diff --git a/src/durandal/fx32.rs b/src/durandal/fx32.rs index a1a71fd..dee3560 100644 --- a/src/durandal/fx32.rs +++ b/src/durandal/fx32.rs @@ -1,4 +1,5 @@ -use std::{fmt, fmt::Write, ops}; +use std::{fmt::{self, Write}, + ops}; pub struct Fx32(i32); @@ -8,55 +9,108 @@ impl Fx32 const FRACMASK: u32 = 0xFFFF; const ONE: i32 = 1 << Fx32::FRACBITS; - pub fn to_bits(&self) -> u32 {self.0 as u32} - pub fn set_bits(&mut self, bits: u32) {self.0 = bits as i32} - pub fn from_bits(bits: u32) -> Fx32 {Fx32( bits as i32)} + pub fn to_bits(&self) -> u32 + { + self.0 as u32 + } - pub fn integ(&self) -> i16 {(self.0 >> Fx32::FRACBITS) as i16} - pub fn fract(&self) -> u16 {(self.0 as u32 & Fx32::FRACMASK) as u16} + pub fn set_bits(&mut self, bits: u32) + { + self.0 = bits as i32 + } - pub fn mul_i(&self, n: i32) -> Fx32 {Fx32(self.0 * n)} - pub fn div_i(&self, n: i32) -> Fx32 {Fx32(self.0 / n)} + pub fn from_bits(bits: u32) -> Fx32 + { + Fx32(bits as i32) + } + + pub fn integ(&self) -> i16 + { + (self.0 >> Fx32::FRACBITS) as i16 + } + + pub fn fract(&self) -> u16 + { + (self.0 as u32 & Fx32::FRACMASK) as u16 + } + + pub fn mul_i(&self, n: i32) -> Fx32 + { + Fx32(self.0 * n) + } + + pub fn div_i(&self, n: i32) -> Fx32 + { + Fx32(self.0 / n) + } } -impl From for Fx32 {fn from(n: i32) -> Fx32 {Fx32(n << Fx32::FRACBITS)}} +impl From for Fx32 +{ + fn from(n: i32) -> Fx32 + { + Fx32(n << Fx32::FRACBITS) + } +} impl ops::Add for Fx32 { type Output = Fx32; - fn add(self, o: Fx32) -> Fx32 {Fx32(self.0 + o.0)} + + fn add(self, o: Fx32) -> Fx32 + { + Fx32(self.0 + o.0) + } } impl ops::Sub for Fx32 { type Output = Fx32; - fn sub(self, o: Fx32) -> Fx32 {Fx32(self.0 - o.0)} + + fn sub(self, o: Fx32) -> Fx32 + { + Fx32(self.0 - o.0) + } } impl ops::Mul for Fx32 { type Output = Fx32; + fn mul(self, o: Fx32) -> Fx32 - {Fx32((self.0 as i64 * o.0 as i64 / Fx32::ONE as i64) as i32)} + { + Fx32((self.0 as i64 * o.0 as i64 / Fx32::ONE as i64) as i32) + } } impl ops::Div for Fx32 { type Output = Fx32; + fn div(self, o: Fx32) -> Fx32 - {Fx32((self.0 as i64 * Fx32::ONE as i64 / o.0 as i64) as i32)} + { + Fx32((self.0 as i64 * Fx32::ONE as i64 / o.0 as i64) as i32) + } } impl ops::Neg for Fx32 { type Output = Fx32; - fn neg(self) -> Fx32 {Fx32(-self.0)} + + fn neg(self) -> Fx32 + { + Fx32(-self.0) + } } impl ops::Not for Fx32 { type Output = Fx32; - fn not(self) -> Fx32 {Fx32(!self.0)} + + fn not(self) -> Fx32 + { + Fx32(!self.0) + } } impl fmt::Display for Fx32 @@ -83,19 +137,21 @@ impl fmt::Display for Fx32 impl fmt::Debug for Fx32 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result - {fmt::Display::fmt(self, f)} + { + fmt::Display::fmt(self, f) + } } #[test] fn fx32_basic_ops() { let seven_div_2 = 3 << Fx32::FRACBITS | Fx32::FRACMASK / 2 + 1; - assert_eq!((Fx32::from(1) + 1.into()).to_bits(), 2 << Fx32::FRACBITS); - assert_eq!((Fx32::from(2) - 1.into()).to_bits(), 1 << Fx32::FRACBITS); + assert_eq!((Fx32::from(1) + 1.into()).to_bits(), 2 << Fx32::FRACBITS); + assert_eq!((Fx32::from(2) - 1.into()).to_bits(), 1 << Fx32::FRACBITS); assert_eq!((Fx32::from(6) * 2.into()).to_bits(), 12 << Fx32::FRACBITS); - assert_eq!((Fx32::from(6).mul_i(2) ).to_bits(), 12 << Fx32::FRACBITS); + assert_eq!((Fx32::from(6).mul_i(2)).to_bits(), 12 << Fx32::FRACBITS); assert_eq!((Fx32::from(7) / 2.into()).to_bits(), seven_div_2); - assert_eq!((Fx32::from(7).div_i(2) ).to_bits(), seven_div_2); + assert_eq!((Fx32::from(7).div_i(2)).to_bits(), seven_div_2); } #[test] @@ -109,9 +165,10 @@ fn fx32_overflow() #[test] fn fx32_printing() { - assert_eq!(format!("{}", Fx32::from(6)), "6.0"); - assert_eq!(format!("{}", Fx32::from(7).div_i(2)), "3.5"); - assert_eq!(format!("{:7.7}", Fx32::from_bits(0xDEAD_BEEF)), " -8531.7458343"); + assert_eq!(format!("{}", Fx32::from(6)), "6.0"); + assert_eq!(format!("{}", Fx32::from(7).div_i(2)), "3.5"); + assert_eq!(format!("{:7.7}", Fx32::from_bits(0xDEAD_BEEF)), + " -8531.7458343"); } // EOF diff --git a/src/durandal/image.rs b/src/durandal/image.rs index 15c2996..e0fcf92 100644 --- a/src/durandal/image.rs +++ b/src/durandal/image.rs @@ -15,8 +15,8 @@ pub struct Color /// Image with width and height. pub struct Image { - w: usize, - h: usize, + w: usize, + h: usize, pub cr: Vec, } @@ -26,8 +26,8 @@ impl Color pub fn from_r5g5b5(rgb: u16) -> Color { let r = rgb >> 10 & 0x1f; - let g = rgb >> 5 & 0x1f; - let b = rgb & 0x1f; + let g = rgb >> 5 & 0x1f; + let b = rgb & 0x1f; Color{r: (r << 3 | r >> 2) as u8, g: (g << 3 | g >> 2) as u8, b: (b << 3 | b >> 2) as u8, @@ -39,10 +39,19 @@ impl Image { /// Creates a new Image structure. pub fn new(w: usize, h: usize) -> Image - {Image{w, h, cr: Vec::with_capacity(w * h)}} + { + Image{w, h, cr: Vec::with_capacity(w * h)} + } - pub fn w(&self) -> usize {self.w} - pub fn h(&self) -> usize {self.h} + pub fn w(&self) -> usize + { + self.w + } + + pub fn h(&self) -> usize + { + self.h + } } impl Index<(usize, usize)> for Image @@ -50,13 +59,17 @@ impl Index<(usize, usize)> for Image type Output = Color; fn index(&self, (x, y): (usize, usize)) -> &Color - {&self.cr[x + y * self.w]} + { + &self.cr[x + y * self.w] + } } impl IndexMut<(usize, usize)> for Image { fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Color - {&mut self.cr[x + y * self.w]} + { + &mut self.cr[x + y * self.w] + } } // EOF diff --git a/src/durandal/text.rs b/src/durandal/text.rs index e953963..d76f1aa 100644 --- a/src/durandal/text.rs +++ b/src/durandal/text.rs @@ -11,8 +11,11 @@ pub fn dump_mem(b: &[u8]) p = 0; } - if c.is_ascii_graphic() {eprint!(" {} ", c as char);} - else {eprint!("{:02X} ", c);} + if c.is_ascii_graphic() { + eprint!(" {} ", c as char); + } else { + eprint!("{:02X} ", c); + } p += 3; } @@ -26,7 +29,9 @@ pub fn to_binsize(n: u64) -> String const NAMES: [&str; 4] = ["kB", "MB", "GB", "TB"]; // empty size - if n == 0 {return String::from("empty");} + if n == 0 { + return String::from("empty"); + } // terabytes, gigabytes, megabytes, kilobytes for i in (1..=4).rev() { @@ -44,11 +49,19 @@ pub fn to_binsize(n: u64) -> String pub fn fuck_string(s: &[u8]) -> Vec { let mut v = s.to_vec(); - let l = s.len(); + let l = s.len(); let mut p = 0; - for _ in 0..l / 4 {p += 2; v[p] ^= 0xfe; v[p + 1] ^= 0xed; p += 2;} - for _ in 0..l % 4 {v[p] ^= 0xfe; p += 1;} + for _ in 0..l / 4 { + p += 2; + v[p] ^= 0xfe; + v[p + 1] ^= 0xed; + p += 2; + } + for _ in 0..l % 4 { + v[p] ^= 0xfe; + p += 1; + } v } @@ -59,64 +72,58 @@ pub fn mac_roman_conv(s: &[u8]) -> String let mut v = String::with_capacity(s.len()); 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);} + 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); + } } v } -const TR: [char; 128] = [ - '\u{00c4}', '\u{00c5}', '\u{00c7}', '\u{00c9}', - '\u{00d1}', '\u{00d6}', '\u{00dc}', '\u{00e1}', - '\u{00e0}', '\u{00e2}', '\u{00e4}', '\u{00e3}', - '\u{00e5}', '\u{00e7}', '\u{00e9}', '\u{00e8}', - '\u{00ea}', '\u{00eb}', '\u{00ed}', '\u{00ec}', - '\u{00ee}', '\u{00ef}', '\u{00f1}', '\u{00f3}', - '\u{00f2}', '\u{00f4}', '\u{00f6}', '\u{00f5}', - '\u{00fa}', '\u{00f9}', '\u{00fb}', '\u{00fc}', - '\u{2020}', '\u{00b0}', '\u{00a2}', '\u{00a3}', - '\u{00a7}', '\u{2022}', '\u{00b6}', '\u{00df}', - '\u{00ae}', '\u{00a9}', '\u{2122}', '\u{00b4}', - '\u{00a8}', '\u{2260}', '\u{00c6}', '\u{00d8}', - '\u{221e}', '\u{00b1}', '\u{2264}', '\u{2265}', - '\u{00a5}', '\u{00b5}', '\u{2202}', '\u{2211}', - '\u{220f}', '\u{03c0}', '\u{222b}', '\u{00aa}', - '\u{00ba}', '\u{03a9}', '\u{00e6}', '\u{00f8}', - '\u{00bf}', '\u{00a1}', '\u{00ac}', '\u{221a}', - '\u{0192}', '\u{2248}', '\u{2206}', '\u{00ab}', - '\u{00bb}', '\u{2026}', '\u{00a0}', '\u{00c0}', - '\u{00c3}', '\u{00d5}', '\u{0152}', '\u{0153}', - '\u{2013}', '\u{2014}', '\u{201c}', '\u{201d}', - '\u{2018}', '\u{2019}', '\u{00f7}', '\u{25ca}', - '\u{00ff}', '\u{0178}', '\u{2044}', '\u{20ac}', - '\u{2039}', '\u{203a}', '\u{fb01}', '\u{fb02}', - '\u{2021}', '\u{00b7}', '\u{201a}', '\u{201e}', - '\u{2030}', '\u{00c2}', '\u{00ca}', '\u{00c1}', - '\u{00cb}', '\u{00c8}', '\u{00cd}', '\u{00ce}', - '\u{00cf}', '\u{00cc}', '\u{00d3}', '\u{00d4}', - '\u{f8ff}', '\u{00d2}', '\u{00da}', '\u{00db}', - '\u{00d9}', '\u{0131}', '\u{02c6}', '\u{02dc}', - '\u{00af}', '\u{02d8}', '\u{02d9}', '\u{02da}', - '\u{00b8}', '\u{02dd}', '\u{02db}', '\u{02c7}' -]; +const TR: [char; 128] = + ['\u{00c4}', '\u{00c5}', '\u{00c7}', '\u{00c9}', '\u{00d1}', '\u{00d6}', + '\u{00dc}', '\u{00e1}', '\u{00e0}', '\u{00e2}', '\u{00e4}', '\u{00e3}', + '\u{00e5}', '\u{00e7}', '\u{00e9}', '\u{00e8}', '\u{00ea}', '\u{00eb}', + '\u{00ed}', '\u{00ec}', '\u{00ee}', '\u{00ef}', '\u{00f1}', '\u{00f3}', + '\u{00f2}', '\u{00f4}', '\u{00f6}', '\u{00f5}', '\u{00fa}', '\u{00f9}', + '\u{00fb}', '\u{00fc}', '\u{2020}', '\u{00b0}', '\u{00a2}', '\u{00a3}', + '\u{00a7}', '\u{2022}', '\u{00b6}', '\u{00df}', '\u{00ae}', '\u{00a9}', + '\u{2122}', '\u{00b4}', '\u{00a8}', '\u{2260}', '\u{00c6}', '\u{00d8}', + '\u{221e}', '\u{00b1}', '\u{2264}', '\u{2265}', '\u{00a5}', '\u{00b5}', + '\u{2202}', '\u{2211}', '\u{220f}', '\u{03c0}', '\u{222b}', '\u{00aa}', + '\u{00ba}', '\u{03a9}', '\u{00e6}', '\u{00f8}', '\u{00bf}', '\u{00a1}', + '\u{00ac}', '\u{221a}', '\u{0192}', '\u{2248}', '\u{2206}', '\u{00ab}', + '\u{00bb}', '\u{2026}', '\u{00a0}', '\u{00c0}', '\u{00c3}', '\u{00d5}', + '\u{0152}', '\u{0153}', '\u{2013}', '\u{2014}', '\u{201c}', '\u{201d}', + '\u{2018}', '\u{2019}', '\u{00f7}', '\u{25ca}', '\u{00ff}', '\u{0178}', + '\u{2044}', '\u{20ac}', '\u{2039}', '\u{203a}', '\u{fb01}', '\u{fb02}', + '\u{2021}', '\u{00b7}', '\u{201a}', '\u{201e}', '\u{2030}', '\u{00c2}', + '\u{00ca}', '\u{00c1}', '\u{00cb}', '\u{00c8}', '\u{00cd}', '\u{00ce}', + '\u{00cf}', '\u{00cc}', '\u{00d3}', '\u{00d4}', '\u{f8ff}', '\u{00d2}', + '\u{00da}', '\u{00db}', '\u{00d9}', '\u{0131}', '\u{02c6}', '\u{02dc}', + '\u{00af}', '\u{02d8}', '\u{02d9}', '\u{02da}', '\u{00b8}', '\u{02dd}', + '\u{02db}', '\u{02c7}']; #[test] fn to_binsize_integrals() { - assert_eq!(to_binsize(0), "empty"); - assert_eq!(to_binsize(1), "1 byte"); - assert_eq!(to_binsize(2), "2 bytes"); - assert_eq!(to_binsize(999), "999 bytes"); - assert_eq!(to_binsize(1000), "1kB"); - assert_eq!(to_binsize(1000 * 7), "7kB"); - assert_eq!(to_binsize(1000 * 1000), "1MB"); - assert_eq!(to_binsize(1000 * 1000 * 7), "7MB"); - assert_eq!(to_binsize(1000 * 1000 * 1000), "1GB"); - assert_eq!(to_binsize(1000 * 1000 * 1000 * 7), "7GB"); - assert_eq!(to_binsize(1000 * 1000 * 1000 * 1000), "1TB"); + assert_eq!(to_binsize(0), "empty"); + assert_eq!(to_binsize(1), "1 byte"); + assert_eq!(to_binsize(2), "2 bytes"); + assert_eq!(to_binsize(999), "999 bytes"); + assert_eq!(to_binsize(1000), "1kB"); + assert_eq!(to_binsize(1000 * 7), "7kB"); + assert_eq!(to_binsize(1000 * 1000), "1MB"); + assert_eq!(to_binsize(1000 * 1000 * 7), "7MB"); + assert_eq!(to_binsize(1000 * 1000 * 1000), "1GB"); + assert_eq!(to_binsize(1000 * 1000 * 1000 * 7), "7GB"); + assert_eq!(to_binsize(1000 * 1000 * 1000 * 1000), "1TB"); assert_eq!(to_binsize(1000 * 1000 * 1000 * 1000 * 7), "7TB"); } diff --git a/src/durandal/traits.rs b/src/durandal/traits.rs index 5d6b84b..a1041c7 100644 --- a/src/durandal/traits.rs +++ b/src/durandal/traits.rs @@ -1,16 +1,19 @@ //! Traits for basic types, because Rust doesn't provide them. /// Any primitive integer type. -pub trait PrimInt: 'static + Send + Sync + std::fmt::Display + PartialEq {} +pub trait PrimInt: + 'static + Send + Sync + std::fmt::Display + PartialEq +{ +} -impl PrimInt for u8 {} -impl PrimInt for i8 {} -impl PrimInt for u16 {} -impl PrimInt for i16 {} -impl PrimInt for u32 {} -impl PrimInt for i32 {} -impl PrimInt for u64 {} -impl PrimInt for i64 {} +impl PrimInt for u8 {} +impl PrimInt for i8 {} +impl PrimInt for u16 {} +impl PrimInt for i16 {} +impl PrimInt for u32 {} +impl PrimInt for i32 {} +impl PrimInt for u64 {} +impl PrimInt for i64 {} impl PrimInt for u128 {} impl PrimInt for i128 {} diff --git a/src/main.rs b/src/main.rs index b1c0d9a..a2d9287 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,11 @@ -use maraiah::durandal::{bin::*, chunk::*, err::*, image::Image, text::*}; -use maraiah::marathon::{machdr, map, pict, term, wad}; -use std::{io, io::Write, fs, env}; +use maraiah::{durandal::{bin::*, chunk::*, err::*, image::Image, text::*}, + marathon::{machdr, map, pict, term, wad}}; +use std::{env, fs, + io::{self, Write}}; fn write_ppm(fname: &str, im: &Image) -> io::Result<()> { - let out = fs::File::create(fname)?; + let out = fs::File::create(fname)?; let mut out = io::BufWriter::new(out); write!(&mut out, "P3\n{} {}\n255\n", im.w(), im.h())?; @@ -22,41 +23,41 @@ fn write_ppm(fname: &str, im: &Image) -> io::Result<()> fn read_chunk(cid: &Ident, cnk: &[u8], eid: u16) -> ResultS<()> { match cid { - b"PICT" => { - let im = pict::load_pict(cnk)?; - println!("entry {} has PICT {}x{}", eid, im.w(), im.h()); - write_ppm(&format!("out/{}.ppm", eid), &im)?; - } - b"Minf" => { - let minf = map::Minf::chunk(cnk)?; - println!("entry {} has {:#?}", eid, minf); - } - b"EPNT" => { - let epnt = map::Endpoint::chunk(cnk)?; - println!("entry {} has EPNT {:#?}", eid, epnt); - } - b"PNTS" => { - let epnt = map::Point::chunk(cnk)?; - println!("entry {} has PNTS {:#?}", eid, epnt); - } - b"LINS" => { - let line = map::Line::chunk(cnk)?; - println!("entry {} has LINS {:#?}", eid, line); - } - b"SIDS" => { - let line = map::Side::chunk(cnk)?; - println!("entry {} has SIDS {:#?}", eid, line); - } - b"term" => { - let term = term::Terminal::chunk(cnk)?; - println!("entry {} has term {:#?}", eid, term); - } - cid => { - let fname = format!("out/{:04}{}.bin", eid, mac_roman_conv(cid)); - let out = fs::File::create(&fname)?; - let mut out = io::BufWriter::new(out); - out.write(cnk)?; - } + b"PICT" => { + let im = pict::load_pict(cnk)?; + println!("entry {} has PICT {}x{}", eid, im.w(), im.h()); + write_ppm(&format!("out/{}.ppm", eid), &im)?; + } + b"Minf" => { + let minf = map::Minf::chunk(cnk)?; + println!("entry {} has {:#?}", eid, minf); + } + b"EPNT" => { + let epnt = map::Endpoint::chunk(cnk)?; + println!("entry {} has EPNT {:#?}", eid, epnt); + } + b"PNTS" => { + let epnt = map::Point::chunk(cnk)?; + println!("entry {} has PNTS {:#?}", eid, epnt); + } + b"LINS" => { + let line = map::Line::chunk(cnk)?; + println!("entry {} has LINS {:#?}", eid, line); + } + b"SIDS" => { + let line = map::Side::chunk(cnk)?; + println!("entry {} has SIDS {:#?}", eid, line); + } + b"term" => { + let term = term::Terminal::chunk(cnk)?; + println!("entry {} has term {:#?}", eid, term); + } + cid => { + let fname = format!("out/{:04}{}.bin", eid, mac_roman_conv(cid)); + let out = fs::File::create(&fname)?; + let mut out = io::BufWriter::new(out); + out.write(cnk)?; + } } Ok(()) @@ -79,11 +80,11 @@ fn process_wad(b: &[u8]) -> ResultS<()> fn collection(b: &[u8]) -> ResultS<()> { - let version = b.c_u16b(0 )?; - let dt_type = b.c_u16b(2 )?; - let flags = b.c_u16b(4 )?; - let colors = b.c_u16b(6 )?; - let clu_num = b.c_u16b(8 )?; + let version = b.c_u16b(0)?; + let dt_type = b.c_u16b(2)?; + let flags = b.c_u16b(4)?; + let colors = b.c_u16b(6)?; + let clu_num = b.c_u16b(8)?; let clu_ofs = b.c_u32b(10)?; let seq_num = b.c_u16b(14)?; let seq_ofs = b.c_u32b(16)?; @@ -109,7 +110,9 @@ fn collection(b: &[u8]) -> ResultS<()> dbg!(size); eprintln!("[end of collection]"); - if version != 3 {return Err(err_msg("invalid collection version number"));} + if version != 3 { + return Err(err_msg("invalid collection version number")); + } Ok(()) } @@ -118,12 +121,12 @@ fn process_shp(b: &[u8]) -> ResultS<()> { for i in 0..32 { let p = 32 * i; - let status = b.c_u16b(p+0 )?; - let flags = b.c_u16b(p+2 )?; - let offset_lo = b.c_u32b(p+4 )? as usize; - let length_lo = b.c_u32b(p+8 )? as usize; - let offset_hi = b.c_u32b(p+12)? as usize; - let length_hi = b.c_u32b(p+16)? as usize; + let status = b.c_u16b(p + 0)?; + let flags = b.c_u16b(p + 2)?; + let offset_lo = b.c_u32b(p + 4)? as usize; + let length_lo = b.c_u32b(p + 8)? as usize; + let offset_hi = b.c_u32b(p + 12)? as usize; + let length_hi = b.c_u32b(p + 16)? as usize; dbg!(i); dbg!(status); dbg!(flags); @@ -133,11 +136,11 @@ fn process_shp(b: &[u8]) -> ResultS<()> dbg!(length_hi); if offset_lo != u32::max_value() as usize { eprintln!("collection {} has lo-res frames", i); - collection(&b[offset_lo .. offset_lo + length_lo])?; + collection(&b[offset_lo..offset_lo + length_lo])?; } if offset_hi != u32::max_value() as usize { eprintln!("collection {} has hi-res frames", i); - collection(&b[offset_hi .. offset_hi + length_hi])?; + collection(&b[offset_hi..offset_hi + length_hi])?; } } @@ -156,13 +159,13 @@ fn main() -> ResultS<()> }; let fp = fs::File::open(fna)?; - let mm = unsafe{Mmap::map(&fp)?}; + let mm = unsafe {Mmap::map(&fp)?}; let b = &mm[machdr::try_mac_header(&mm)..]; match typ { - "wad:" => process_wad(b), - "shp:" => process_shp(b), - _ => Err(err_msg("invalid file type specified on commandline")) + "wad:" => process_wad(b), + "shp:" => process_shp(b), + _ => Err(err_msg("invalid file type specified on commandline")), }?; } diff --git a/src/marathon/machdr.rs b/src/marathon/machdr.rs index dc321df..2a8dc1d 100644 --- a/src/marathon/machdr.rs +++ b/src/marathon/machdr.rs @@ -6,17 +6,21 @@ use crate::durandal::bin::*; pub fn check_apple_single(b: &[u8]) -> Option { // check magic numbers - if b[0..8] != [0, 5, 22, 0, 0, 2, 0, 0] {return None;} + if b[0..8] != [0, 5, 22, 0, 0, 2, 0, 0] { + return None; + } // get the resource fork (entity 1) let num = b.o_u16b(24)? as usize; for i in 0..num { let p = 26 + 12 * i; - let ent = b.o_u32b(p )?; - let ofs = b.o_u32b(p+4)? as usize; - let len = b.o_u32b(p+8)? as usize; + let ent = b.o_u32b(p)?; + let ofs = b.o_u32b(p + 4)? as usize; + let len = b.o_u32b(p + 8)? as usize; - if ent == 1 {return if ofs + len > b.len() {None} else {Some(ofs)};} + if ent == 1 { + return if ofs + len > b.len() {None} else {Some(ofs)}; + } } // no resource fork @@ -27,7 +31,9 @@ pub fn check_apple_single(b: &[u8]) -> Option pub fn check_macbin(b: &[u8]) -> Option { // check legacy version, length, zero fill, and macbin2 version - if b[0] != 0 || b[1] > 63 || b[74] != 0 || b[123] > 129 {return None;} + if b[0] != 0 || b[1] > 63 || b[74] != 0 || b[123] > 129 { + return None; + } let mut crc = 0; @@ -35,21 +41,31 @@ pub fn check_macbin(b: &[u8]) -> Option for i in 0..124 { for j in 8..16 { let d = b[i] as (u16) << j; - if (d ^ crc) & 0x8000 != 0 {crc = crc << 1 ^ 0x1021;} - else {crc <<= 1;} + if (d ^ crc) & 0x8000 != 0 { + crc = crc << 1 ^ 0x1021; + } else { + crc <<= 1; + } } } // if ok, resource fork follows - if crc == b.o_u16b(124)? {Some(128)} else {None} + if crc == b.o_u16b(124)? { + Some(128) + } else { + None + } } /// Reads a MacBin or AppleSingle header if there is one and returns the /// offset from the start of the header to the resource fork (if one is found.) pub fn try_mac_header(b: &[u8]) -> usize { - if let Some(ofs) = check_macbin(b) {ofs} - else {check_apple_single(b).unwrap_or(0)} + if let Some(ofs) = check_macbin(b) { + ofs + } else { + check_apple_single(b).unwrap_or(0) + } } // EOF diff --git a/src/marathon/map.rs b/src/marathon/map.rs index 5947cd8..7dd8f54 100644 --- a/src/marathon/map.rs +++ b/src/marathon/map.rs @@ -1,5 +1,5 @@ -use bitflags::bitflags; use crate::durandal::{bin::*, chunk::*, err::*, fx32::*, text::mac_roman_conv}; +use bitflags::bitflags; use std::fmt; impl Chunked for Point @@ -20,12 +20,12 @@ impl Chunked for Endpoint fn read(b: &[u8]) -> ResultS { - let flags = b.c_u16b(0)?; - let adj_hi = b.c_i16b(2)?; - let adj_lo = b.c_i16b(4)?; - let pos = Point::read(&b[6..10])?; + let flags = b.c_u16b(0)?; + let adj_hi = b.c_i16b(2)?; + let adj_lo = b.c_i16b(4)?; + let pos = Point::read(&b[6..10])?; let support = b.c_u16b(14)?; - let flags = EndpointFlags::from_bits_truncate(flags); + let flags = EndpointFlags::from_bits_truncate(flags); Ok(Endpoint{flags, adj_hi, adj_lo, pos, support}) } } @@ -38,7 +38,7 @@ impl Chunked for Line { let epnt_f = b.c_u16b(0)?; let epnt_b = b.c_u16b(2)?; - let flags = b.c_u16b(4)?; + let flags = b.c_u16b(4)?; let length = b.c_i16b(6)?; let adj_hi = b.c_i16b(8)?; let adj_lo = b.c_i16b(10)?; @@ -46,7 +46,7 @@ impl Chunked for Line let side_b = b.c_u16b(14)?; let poly_f = b.c_u16b(16)?; let poly_b = b.c_u16b(18)?; - let flags = LineFlags::from_bits_truncate(flags); + let flags = LineFlags::from_bits_truncate(flags); Ok(Line{flags, length, adj_hi, adj_lo, epnt_f, epnt_b, side_f, side_b, poly_f, poly_b}) } @@ -54,7 +54,7 @@ impl Chunked for Line fn read_side_tex(b: &[u8]) -> ResultS { - let offs = Point::read(&b[0..4])?; + let offs = Point::read(&b[0..4])?; let tex_id = b.c_u16b(4)?; let tex_id = if tex_id == 65535 {None} else {Some(tex_id)}; Ok(SideTex{offs, tex_id}) @@ -66,11 +66,11 @@ impl Chunked for Side fn read(b: &[u8]) -> ResultS { - let stype = b.c_u16b(0)?; - let flags = b.c_u16b(2)?; - let tex_pri = read_side_tex(&b[ 4..10])?; - let tex_sec = read_side_tex(&b[10..16])?; - let tex_tra = read_side_tex(&b[16..22])?; + let stype = b.c_u16b(0)?; + let flags = b.c_u16b(2)?; + let tex_pri = read_side_tex(&b[4..10])?; + let tex_sec = read_side_tex(&b[10..16])?; + let tex_tra = read_side_tex(&b[16..22])?; let ex_tleft = Point::read(&b[22..26])?; let ex_trigh = Point::read(&b[26..30])?; let ex_bleft = Point::read(&b[30..34])?; @@ -80,9 +80,9 @@ impl Chunked for Side let xfer_pri = b.c_u16b(42)?; let xfer_sec = b.c_u16b(44)?; let xfer_tra = b.c_u16b(46)?; - let shade = b.c_u32b(48)?; - let flags = SideFlags::from_bits_truncate(flags); - let shade = Fx32::from_bits(shade); + let shade = b.c_u32b(48)?; + let flags = SideFlags::from_bits_truncate(flags); + let shade = Fx32::from_bits(shade); Ok(Side{stype, flags, tex_pri, tex_sec, tex_tra, ex_tleft, ex_trigh, ex_bleft, ex_brigh, paneltyp, paneldat, xfer_pri, xfer_sec, xfer_tra, shade}) @@ -93,11 +93,11 @@ impl Chunker for Minf { fn chunk(b: &[u8]) -> ResultS { - 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 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)?; let msn_flag = MsnFlags::from_bits_truncate(msn_flag); @@ -119,17 +119,17 @@ pub struct Point #[derive(Debug)] pub struct Endpoint { - flags: EndpointFlags, - adj_hi: Unit, - adj_lo: Unit, - pos: Point, + flags: EndpointFlags, + adj_hi: Unit, + adj_lo: Unit, + pos: Point, support: u16, } #[derive(Debug)] pub struct Line { - flags: LineFlags, + flags: LineFlags, length: Unit, adj_hi: Unit, adj_lo: Unit, @@ -144,18 +144,18 @@ pub struct Line #[derive(Debug)] pub struct SideTex { - offs: Point, + offs: Point, tex_id: Option, } #[derive(Debug)] pub struct Side { - stype: u16, - flags: SideFlags, - tex_pri: SideTex, - tex_sec: SideTex, - tex_tra: SideTex, + stype: u16, + flags: SideFlags, + tex_pri: SideTex, + tex_sec: SideTex, + tex_tra: SideTex, ex_tleft: Point, ex_trigh: Point, ex_bleft: Point, @@ -165,7 +165,7 @@ pub struct Side xfer_pri: u16, xfer_sec: u16, xfer_tra: u16, - shade: Fx32, + shade: Fx32, } #[derive(Debug)] @@ -262,7 +262,9 @@ bitflags! { impl fmt::Debug for Point { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result - {write!(f, "({}, {})", self.x, self.y)} + { + write!(f, "({}, {})", self.x, self.y) + } } // EOF diff --git a/src/marathon/pict.rs b/src/marathon/pict.rs index d2e6bc8..de91239 100644 --- a/src/marathon/pict.rs +++ b/src/marathon/pict.rs @@ -4,39 +4,46 @@ use crate::durandal::{bin::*, err::*, image::*}; use generic_array::*; const PACK_DEFAULT: u16 = 0; -const PACK_NONE : u16 = 1; -const PACK_NOPAD : u16 = 2; -const PACK_RLE16 : u16 = 3; -const PACK_RLE32 : u16 = 4; +const PACK_NONE: u16 = 1; +const PACK_NOPAD: u16 = 2; +const PACK_RLE16: u16 = 3; +const PACK_RLE32: u16 = 4; /// Process a CopyBits operation. -pub fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> ResultS +pub fn read_bitmap_area(mut im: Image, + b: &[u8], + packed: bool, + clip: bool) + -> ResultS { let mut p = if !packed {4} else {0}; let (w, h) = (im.w(), im.h()); - let pitch_fl = b.c_u16b(p )?; - let top = b.c_u16b(p+ 2)? as usize; - let left = b.c_u16b(p+ 4)? as usize; - let bottom = b.c_u16b(p+ 6)? as usize; - let right = b.c_u16b(p+ 8)? as usize; - // version = b.c_u16b(p+10)?; - let pack_typ = b.c_u16b(p+12)?; + let pitch_fl = b.c_u16b(p)?; + let top = b.c_u16b(p + 2)? as usize; + let left = b.c_u16b(p + 4)? as usize; + let bottom = b.c_u16b(p + 6)? as usize; + let right = b.c_u16b(p + 8)? as usize; + // version = b.c_u16b(p+10)?; + let pack_typ = b.c_u16b(p + 12)?; // pack_siz = b.c_u32b(p+14)?; // horz_dpi = b.c_u32b(p+18)?; // vert_dpi = b.c_u32b(p+22)?; - // format = b.c_u16b(p+26)?; - let depth = b.c_u16b(p+28)?; - // comp_n = b.c_u16b(p+30)?; - // comp_d = b.c_u16b(p+32)?; + // format = b.c_u16b(p+26)?; + let depth = b.c_u16b(p + 28)?; + // comp_n = b.c_u16b(p+30)?; + // comp_d = b.c_u16b(p+32)?; // planeofs = b.c_u32b(p+34)?; - // clut_id = b.c_u32b(p+38)?; + // clut_id = b.c_u32b(p+38)?; - if pitch_fl & 0x8000 == 0 - {return Err(err_msg("PICT1 not supported"));} - if right - left != w || bottom - top != h - {return Err(err_msg("image bounds are incorrect"));} + if pitch_fl & 0x8000 == 0 { + return Err(err_msg("PICT1 not supported")); + } + + if right - left != w || bottom - top != h { + return Err(err_msg("image bounds are incorrect")); + } p += 46; // size of header @@ -51,98 +58,108 @@ pub fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Re p += 18; // srcRect, dstRect, mode - if clip {p += b.c_u16b(p)? as usize;} // maskRgn + if clip { + p += b.c_u16b(p)? as usize; // maskRgn + } - let rle = pack_typ == PACK_DEFAULT || - (pack_typ == PACK_RLE16 && depth == 16) || - (pack_typ == PACK_RLE32 && depth == 32); + let rle = pack_typ == PACK_DEFAULT || + (pack_typ == PACK_RLE16 && depth == 16) || + (pack_typ == PACK_RLE32 && depth == 32); let pitch = (pitch_fl & 0x3fff) as usize; match depth { - 1 | 2 | 4 | 8 => { - let clut = clut.ok_or_else(|| err_msg("no clut in indexed mode"))?; - if pitch < 8 && depth == 8 { - // uncompressed 8-bit colormap indices - for _ in 0..h { - for _ in 0..w { - im.cr.push(clut[b[(p, p += 1).0] as usize].clone()); + 1 | 2 | 4 | 8 => { + let clut = clut.ok_or_else(|| err_msg("no clut in indexed mode"))?; + if pitch < 8 && depth == 8 { + // uncompressed 8-bit colormap indices + for _ in 0..h { + for _ in 0..w { + im.cr.push(clut[b[(p, p += 1).0] as usize].clone()); + } } + + Ok(im) + } else if rle { + // RLE compressed 1, 2, 4 or 8 bit colormap indices + for _ in 0..h { + let (d, pp) = read_rle(&b[p..], pitch, false)?; + let d = if depth < 8 {expand_data(d, depth)?} else {d}; + + p += pp; + + for x in 0..w { + im.cr.push(clut[d[x] as usize].clone()); + } + } + + Ok(im) + } else { + Err(err_msg("invalid configuration")) } - - Ok(im) - } else if rle { - // RLE compressed 1, 2, 4 or 8 bit colormap indices - for _ in 0..h { - let (d, pp) = read_rle(&b[p..], pitch, false)?; - let d = if depth < 8 {expand_data(d, depth)?} else {d}; - - p += pp; - - for x in 0..w {im.cr.push(clut[d[x] as usize].clone());} - } - - Ok(im) - } else { - Err(err_msg("invalid configuration")) } - }, - 16 => - if pitch < 8 || pack_typ == 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)?)); + 16 => { + if pitch < 8 || pack_typ == 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) - } else if rle { - // RLE compressed R5G5B5 - for _ in 0..h { - let (d, pp) = read_rle(&b[p..], pitch, true)?; + Ok(im) + } else if rle { + // RLE compressed R5G5B5 + for _ in 0..h { + let (d, pp) = read_rle(&b[p..], pitch, true)?; - p += pp; + p += pp; - for x in 0..w {im.cr.push(Color::from_r5g5b5(d.c_u16b(x*2)?));} - } - - Ok(im) - } else { - Err(err_msg("invalid configuration")) - }, - 32 => - if pitch < 8 || pack_typ == PACK_NONE || pack_typ == PACK_NOPAD { - // uncompressed RGB8 or XRGB8 - for _ in 0..h { - for _ in 0..w { - if pack_typ != PACK_NOPAD {p += 1;} - let (r, g, b) = (b[p], b[p+1], b[p+2]); - p += 3; - im.cr.push(Color{r, g, b, a: 255}); + for x in 0..w { + im.cr.push(Color::from_r5g5b5(d.c_u16b(x * 2)?)); + } } + + Ok(im) + } else { + Err(err_msg("invalid configuration")) } - - Ok(im) - } else if rle { - // RLE compressed RGB8 - let pitch = pitch - w; // remove padding byte from pitch - for _ in 0..h { - let (d, pp) = read_rle(&b[p..], pitch, false)?; - - p += pp; - - 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}); + } + 32 => { + if pitch < 8 || pack_typ == PACK_NONE || pack_typ == PACK_NOPAD { + // uncompressed RGB8 or XRGB8 + for _ in 0..h { + for _ in 0..w { + if pack_typ != PACK_NOPAD { + p += 1; + } + let (r, g, b) = (b[p], b[p + 1], b[p + 2]); + p += 3; + im.cr.push(Color{r, g, b, a: 255}); + } } - } - Ok(im) - } else { - Err(err_msg("invalid configuration")) - }, - _ => Err(err_msg("invalid bit depth")) + Ok(im) + } else if rle { + // RLE compressed RGB8 + let pitch = pitch - w; // remove padding byte from pitch + for _ in 0..h { + let (d, pp) = read_rle(&b[p..], pitch, false)?; + + p += pp; + + 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}); + } + } + + Ok(im) + } else { + Err(err_msg("invalid configuration")) + } + } + _ => Err(err_msg("invalid bit depth")), } } @@ -156,11 +173,11 @@ pub fn read_quicktime_c(_im: Image, _b: &[u8]) -> ResultS pub fn load_pict(b: &[u8]) -> ResultS { // size = b.c_u16b(0)?; - // top = b.c_u16b(2)?; + // 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 h = b.c_u16b(6)? as usize; + let w = b.c_u16b(8)? as usize; + let im = Image::new(w, h); let mut p = 10; // size of header @@ -168,62 +185,82 @@ pub fn load_pict(b: &[u8]) -> ResultS let op = b.c_u16b((p, p += 2).0)?; match op { - 0x0098 => return read_bitmap_area(im, &b[p..], true, false), // PackBitsRect - 0x0099 => return read_bitmap_area(im, &b[p..], true, true ), // PackBitsRgn - 0x009a => return read_bitmap_area(im, &b[p..], false, false), // DirectBitsRect - 0x009b => return read_bitmap_area(im, &b[p..], false, true ), // DirectBitsRgn - 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 - 0x8100 => (), // Reserved - 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 | // SpExtra - 0x0007 | // PnSize - 0x000b | // OvSize - 0x000c | // Origin - 0x000e | // FgCol - 0x000f | // BkCol - 0x0021 => p += 4, // LineFrom - 0x001a | // RGBFgCol - 0x001b | // RGBBkCol - 0x001d | // TxRatio - 0x0022 => p += 6, // ShortLine - 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 - 0x0001 => p += (b.c_u16b(p )? & !1) as usize, // Clip - 0x00a1 => p += (b.c_u16b(p+2)? & !1) as usize + 2, // LongComment - 0x100..= - 0x7fff => p += (op >> 8) as usize * 2, // Reserved - _ => return Err(err_msg("invalid op in PICT")) + 0x0098 => { + // PackBitsRect + return read_bitmap_area(im, &b[p..], true, false); + } + 0x0099 => { + // PackBitsRgn + return read_bitmap_area(im, &b[p..], true, true); + } + 0x009a => { + // DirectBitsRect + return read_bitmap_area(im, &b[p..], false, false); + } + 0x009b => { + // DirectBitsRgn + return read_bitmap_area(im, &b[p..], false, true); + } + 0x8200 => { + // CompressedQuickTime + return read_quicktime_c(im, &b[p..]); + } + 0x00ff => { + // OpEndPic + break; + } + // 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 + 0x8100 => (), // Reserved + 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 | // SpExtra + 0x0007 | // PnSize + 0x000b | // OvSize + 0x000c | // Origin + 0x000e | // FgCol + 0x000f | // BkCol + 0x0021 => p += 4, // LineFrom + 0x001a | // RGBFgCol + 0x001b | // RGBBkCol + 0x001d | // TxRatio + 0x0022 => p += 6, // ShortLine + 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 + 0x0001 => p += (b.c_u16b(p )? & !1) as usize, // Clip + 0x00a1 => p += (b.c_u16b(p+2)? & !1) as usize + 2, // LongComment + 0x100..= + 0x7fff => p += (op >> 8) as usize * 2, // Reserved + _ => { + return Err(err_msg("invalid op in PICT")); + } } } @@ -242,12 +279,15 @@ pub fn get_clut(b: &[u8]) -> ResultS<(Vec, usize)> for i in 0..num { // with device mapping, we ignore the index entirely - let n = if !dev {b[p+1] as usize} else {i}; - let r = b[p+2]; - let g = b[p+4]; - let b = b[p+6]; + let n = if !dev {b[p + 1] as usize} else {i}; + let r = b[p + 2]; + let g = b[p + 4]; + let b = b[p + 6]; + + if n >= clut.len() { + return Err(err_msg("bad clut index")); + } - if n >= clut.len() {return Err(err_msg("bad clut index"));} clut[n] = Color{r, g, b, a: 255}; p += 8; @@ -261,8 +301,12 @@ pub fn read_rle(b: &[u8], pitch: usize, ln: bool) -> ResultS<(Vec, usize)> { let mut p = 0; let mut o = Vec::with_capacity(pitch); - let sz = if pitch > 250 {(b.c_u16b(0)? as usize + 2, p += 2).0} - else {(b[0] as usize + 1, p += 1).0}; + + let sz = if pitch > 250 { + (b.c_u16b(0)? as usize + 2, p += 2).0 + } else { + (b[0] as usize + 1, p += 1).0 + }; while p < sz { let szf = b[(p, p += 1).0]; @@ -278,8 +322,11 @@ pub fn read_rle(b: &[u8], pitch: usize, ln: bool) -> ResultS<(Vec, usize)> } } - if o.len() == pitch {Ok((o, p))} - else {Err(err_msg("incorrect size for compressed scanline"))} + if o.len() == pitch { + Ok((o, p)) + } else { + Err(err_msg("incorrect size for compressed scanline")) + } } /// Read a sequence of packed RLE data. @@ -289,28 +336,38 @@ fn read_rle_data(cmp: bool, len: usize, out: &mut Vec, mut read: F) { if cmp { let d = read(); - for _ in 0..len {for v in d.iter() {out.push(*v);}} + for _ in 0..len { + for v in d.iter() { + out.push(*v); + } + } } else { - for _ in 0..len {let d = read(); for v in d.iter() {out.push(*v);}} + for _ in 0..len { + let d = read(); + for v in d.iter() { + out.push(*v); + } + } } } /// Expand packed pixel data based on bit depth. pub fn expand_data(b: Vec, depth: u16) -> ResultS> { - let mut o = Vec::with_capacity(match depth { - 4 => b.len() * 2, - 2 => b.len() * 4, - 1 => b.len() * 8, - _ => return Err(err_msg("invalid bit depth")) - }); + let mut o = + Vec::with_capacity(match depth { + 4 => b.len() * 2, + 2 => b.len() * 4, + 1 => b.len() * 8, + _ => return Err(err_msg("invalid bit depth")), + }); 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 - 1 => for i in 7..=0 {o.push(ch >> i * 1 & 0x1u8);}, // 8 bits - _ => return Err(err_msg("invalid bit 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 + 1 => {for i in 7..=0 {o.push(ch >> i * 1 & 0x1u8);}} // 8 bits + _ => return Err(err_msg("invalid bit depth")), } } diff --git a/src/marathon/term.rs b/src/marathon/term.rs index aade008..6d24271 100644 --- a/src/marathon/term.rs +++ b/src/marathon/term.rs @@ -4,12 +4,12 @@ use std::fmt; fn read_group(b: &[u8], text: &[u8]) -> ResultS { // flags = b.c_u16b( 0)?; - let ttype = b.c_u16b( 2)?; - let pdata = b.c_i16b( 4)?; - let start = b.c_u16b( 6)? as usize; - let size = b.c_u16b( 8)? as usize; + let ttype = b.c_u16b(2)?; + let pdata = b.c_i16b(4)?; + let start = b.c_u16b(6)? as usize; + let size = b.c_u16b(8)? as usize; let lines = b.c_u16b(10)?; - let text = mac_roman_conv(&text[start..start+size]); + let text = mac_roman_conv(&text[start..start + size]); let ttype = GroupType::from_repr(ttype)?; Ok(Group{ttype, pdata, lines, text}) @@ -18,31 +18,35 @@ fn read_group(b: &[u8], text: &[u8]) -> ResultS fn read_face(b: &[u8]) -> ResultS { let start = b.c_u16b(0)? as usize; - let face = b.c_u16b(2)?; + let face = b.c_u16b(2)?; let color = b.c_u16b(4)?; - Ok(Face{start, face, color}) + Ok(Face { start, face, color }) } fn read_terminal(b: &[u8]) -> ResultS<(usize, Terminal)> { const SIZE_GROUP: usize = 12; - const SIZE_FACE : usize = 6; + const SIZE_FACE: usize = 6; - let end = b.c_u16b(0)? as usize; + let end = b.c_u16b(0)? as usize; let encoded = b.c_u16b(2)? & 1 != 0; - let lines = b.c_u16b(4)?; + let lines = b.c_u16b(4)?; let group_n = b.c_u16b(6)? as usize; - let face_n = b.c_u16b(8)? as usize; + let face_n = b.c_u16b(8)? as usize; let mut groups = Vec::with_capacity(group_n); - let mut faces = Vec::with_capacity( face_n); + let mut faces = Vec::with_capacity(face_n); let mut p = 10; // size of header let text_st = p + SIZE_GROUP * group_n + SIZE_FACE * face_n; let text = &b[text_st..end]; - let text = if encoded {fuck_string(text)} else {text.to_vec()}; + let text = if encoded { + fuck_string(text) + } else { + text.to_vec() + }; for _ in 0..group_n { groups.push(read_group(&b[p..], &text)?); @@ -77,16 +81,16 @@ impl Chunker> for Terminal #[derive(Debug)] pub struct Terminal { - lines: u16, + lines: u16, groups: Vec, - faces: Vec, + faces: Vec, } #[derive(Debug)] pub struct Face { start: usize, - face: u16, + face: u16, color: u16, } @@ -95,7 +99,7 @@ pub struct Group ttype: GroupType, pdata: i16, lines: u16, - text: String, + text: String, } c_enum! { @@ -127,7 +131,9 @@ impl fmt::Debug for Group fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Group{{{:?} {} {}", self.ttype, self.pdata, self.lines)?; - if self.text.len() != 0 {write!(f, ";\n{}", self.text)?;} + if self.text.len() != 0 { + write!(f, ";\n{}", self.text)?; + } write!(f, "}}") } } diff --git a/src/marathon/wad.rs b/src/marathon/wad.rs index 24f5ebe..af60e4d 100644 --- a/src/marathon/wad.rs +++ b/src/marathon/wad.rs @@ -7,39 +7,51 @@ impl Wad<'_> { pub fn new(b: &[u8]) -> ResultS { - if b.len() < 128 {return Err(err_msg("not enough data for Wad header"));} + if b.len() < 128 { + return Err(err_msg("not enough data for Wad header")); + } - let wadver = b.c_u16b( 0)?; - let dataver = b.c_u16b( 2)?; + 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; + // 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; let wcnksize = b.c_u16b(80)? as usize; let wentsize = b.c_u16b(82)? as usize; - // parent = b.c_u32b(84)?; - let wadver = Ver::from_repr(wadver)?; + // parent = b.c_u32b(84)?; + let wadver = Ver::from_repr(wadver)?; - let is_old = match wadver {Ver::Base => true, _ => false}; + let is_old = match wadver { + Ver::Base => true, + _ => false, + }; let entsize = if !is_old {10} else {8 }; let cnksize = if !is_old {16} else {12}; - if entsize != wentsize {return Err(err_msg("invalid entry size"));} - if cnksize != wcnksize {return Err(err_msg("invalid chunk size"));} + if entsize != wentsize { + return Err(err_msg("invalid entry size")); + } + + if cnksize != wcnksize { + return Err(err_msg("invalid chunk size")); + } let mut entries = EntryMap::new(); let mut p = dirofs; for i in 0..numents { - 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}; + 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 offset + size > b.len() {return Err(err_msg("not enough data for entry"));} + if offset + size > b.len() { + return Err(err_msg("not enough data for entry")); + } - let chunks = get_chunks(&b[offset..offset+size], cnksize)?; - let appdata = &b[p..p+appsize]; + let chunks = get_chunks(&b[offset..offset + size], cnksize)?; + let appdata = &b[p..p + appsize]; entries.insert(index, Entry{chunks, appdata}); @@ -56,12 +68,12 @@ fn get_chunks(b: &[u8], cnksize: usize) -> ResultS let mut p = 0; while p < b.len() { - let iden = b.c_iden(p )?; - // ofs = b.c_u32b(p+ 4)?; - let size = b.c_u32b(p+ 8)? as usize; + let iden = b.c_iden(p)?; + // ofs = b.c_u32b(p+ 4)?; + let size = b.c_u32b(p + 8)? as usize; // pofs = b.c_u32b(p+12)?; - let beg = p + cnksize; - let end = beg + size; + let beg = p + cnksize; + let end = beg + size; chunks.insert(iden, &b[beg..end]); p = end; } @@ -69,24 +81,24 @@ fn get_chunks(b: &[u8], cnksize: usize) -> ResultS Ok(chunks) } -type Chunk <'a> = &'a[u8]; +type Chunk<'a> = &'a [u8]; type ChunkMap<'a> = BTreeMap>; -type EntryMap<'a> = BTreeMap>; +type EntryMap<'a> = BTreeMap>; pub struct Entry<'a> { - pub chunks: ChunkMap<'a>, - pub appdata: &'a[u8], + pub chunks: ChunkMap<'a>, + pub appdata: &'a [u8], } #[derive(Debug)] pub struct Wad<'a> { - wadver: Ver, - dataver: u16, - origname: String, - appsize: usize, - pub entries: EntryMap<'a>, + wadver: Ver, + dataver: u16, + origname: String, + appsize: usize, + pub entries: EntryMap<'a>, } c_enum! { @@ -105,8 +117,12 @@ impl fmt::Debug for Entry<'_> fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Entry{{ ")?; - for (iden, _) in &self.chunks {write!(f, "{} ", mac_roman_conv(iden))?;} - if self.appdata.len() != 0 {write!(f, "\nappdata: {:?} ", self.appdata)?;} + for (iden, _) in &self.chunks { + write!(f, "{} ", mac_roman_conv(iden))?; + } + if self.appdata.len() != 0 { + write!(f, "\nappdata: {:?} ", self.appdata)?; + } write!(f, "}}") } } diff --git a/tests/clut.rs b/tests/clut.rs index 0c8fdbb..ca93542 100644 --- a/tests/clut.rs +++ b/tests/clut.rs @@ -1,5 +1,4 @@ -use maraiah::durandal::image::Color; -use maraiah::marathon::pict::get_clut; +use maraiah::{durandal::image::Color, marathon::pict::get_clut}; #[test] fn get_clut_must_process_this() diff --git a/tests/machdr.rs b/tests/machdr.rs index bd8ed5e..1e4eec0 100644 --- a/tests/machdr.rs +++ b/tests/machdr.rs @@ -5,7 +5,7 @@ use maraiah::marathon::machdr::*; #[test] fn macbin_must_process_this() { - assert_eq!( check_macbin(INPUT_MACBIN), Some(128)); + assert_eq!(check_macbin(INPUT_MACBIN), Some(128)); assert_eq!(try_mac_header(INPUT_MACBIN), 128); }