partially format code with rustfmt
parent
dd5bf03252
commit
6d99752e6e
|
@ -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
|
||||
|
|
|
@ -12,23 +12,63 @@ pub trait BinUtil
|
|||
fn c_u16b(&self, i: usize) -> ResultS<u16>;
|
||||
|
||||
fn c_i32b(&self, i: usize) -> ResultS<i32>
|
||||
{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<i16>
|
||||
{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<Ident> {self.c_iden(i).ok()}
|
||||
fn o_u32b(&self, i: usize) -> Option<u32> {self.c_u32b(i).ok()}
|
||||
fn o_u16b(&self, i: usize) -> Option<u16> {self.c_u16b(i).ok()}
|
||||
fn o_i32b(&self, i: usize) -> Option<i32> {self.c_i32b(i).ok()}
|
||||
fn o_i16b(&self, i: usize) -> Option<i16> {self.c_i16b(i).ok()}
|
||||
fn o_iden(&self, i: usize) -> Option<Ident>
|
||||
{
|
||||
self.c_iden(i).ok()
|
||||
}
|
||||
fn o_u32b(&self, i: usize) -> Option<u32>
|
||||
{
|
||||
self.c_u32b(i).ok()
|
||||
}
|
||||
fn o_u16b(&self, i: usize) -> Option<u16>
|
||||
{
|
||||
self.c_u16b(i).ok()
|
||||
}
|
||||
fn o_i32b(&self, i: usize) -> Option<i32>
|
||||
{
|
||||
self.c_i32b(i).ok()
|
||||
}
|
||||
fn o_i16b(&self, i: usize) -> Option<i16>
|
||||
{
|
||||
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<u32>
|
||||
{
|
||||
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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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<T> Fail for ReprError<T> where T: PrimInt {}
|
|||
impl<T> fmt::Display for ReprError<T> 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<T> fmt::Debug for ReprError<T> 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<T> = Result<T, Error>;
|
||||
|
|
|
@ -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<i32> for Fx32 {fn from(n: i32) -> Fx32 {Fx32(n << Fx32::FRACBITS)}}
|
||||
impl From<i32> 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,7 +137,9 @@ 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]
|
||||
|
@ -93,9 +149,9 @@ fn fx32_basic_ops()
|
|||
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]
|
||||
|
@ -111,7 +167,8 @@ 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!("{:7.7}", Fx32::from_bits(0xDEAD_BEEF)),
|
||||
" -8531.7458343");
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
@ -47,8 +52,16 @@ pub fn fuck_string(s: &[u8]) -> Vec<u8>
|
|||
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,49 +72,43 @@ 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()
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
//! 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 {}
|
||||
|
|
41
src/main.rs
41
src/main.rs
|
@ -1,6 +1,7 @@
|
|||
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<()>
|
||||
{
|
||||
|
@ -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"))
|
||||
_ => Err(err_msg("invalid file type specified on commandline")),
|
||||
}?;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,17 +6,21 @@ use crate::durandal::bin::*;
|
|||
pub fn check_apple_single(b: &[u8]) -> Option<usize>
|
||||
{
|
||||
// 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<usize>
|
|||
pub fn check_macbin(b: &[u8]) -> Option<usize>
|
||||
{
|
||||
// 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<usize>
|
|||
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
|
||||
|
|
|
@ -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<Point> for Point
|
||||
|
@ -68,7 +68,7 @@ impl Chunked<Side> for Side
|
|||
{
|
||||
let stype = b.c_u16b(0)?;
|
||||
let flags = b.c_u16b(2)?;
|
||||
let tex_pri = read_side_tex(&b[ 4..10])?;
|
||||
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])?;
|
||||
|
@ -93,11 +93,11 @@ impl Chunker<Minf> for Minf
|
|||
{
|
||||
fn chunk(b: &[u8]) -> ResultS<Minf>
|
||||
{
|
||||
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);
|
||||
|
@ -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
|
||||
|
|
|
@ -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<Image>
|
||||
pub fn read_bitmap_area(mut im: Image,
|
||||
b: &[u8],
|
||||
packed: bool,
|
||||
clip: bool)
|
||||
-> ResultS<Image>
|
||||
{
|
||||
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;
|
||||
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 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)?;
|
||||
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)?;
|
||||
|
||||
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,7 +58,9 @@ 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) ||
|
||||
|
@ -79,15 +88,17 @@ pub fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Re
|
|||
|
||||
p += pp;
|
||||
|
||||
for x in 0..w {im.cr.push(clut[d[x] as usize].clone());}
|
||||
for x in 0..w {
|
||||
im.cr.push(clut[d[x] as usize].clone());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(im)
|
||||
} else {
|
||||
Err(err_msg("invalid configuration"))
|
||||
}
|
||||
},
|
||||
16 =>
|
||||
}
|
||||
16 => {
|
||||
if pitch < 8 || pack_typ == PACK_NONE {
|
||||
// uncompressed R5G5B5
|
||||
for _ in 0..h {
|
||||
|
@ -104,20 +115,25 @@ pub fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Re
|
|||
|
||||
p += pp;
|
||||
|
||||
for x in 0..w {im.cr.push(Color::from_r5g5b5(d.c_u16b(x*2)?));}
|
||||
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 =>
|
||||
}
|
||||
}
|
||||
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]);
|
||||
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});
|
||||
}
|
||||
|
@ -133,7 +149,7 @@ pub fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Re
|
|||
p += pp;
|
||||
|
||||
for x in 0..w {
|
||||
let (r, g, b) = (d[x+w*0], d[x+w*1], d[x+w*2]);
|
||||
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});
|
||||
}
|
||||
}
|
||||
|
@ -141,8 +157,9 @@ pub fn read_bitmap_area(mut im: Image, b: &[u8], packed: bool, clip: bool) -> Re
|
|||
Ok(im)
|
||||
} else {
|
||||
Err(err_msg("invalid configuration"))
|
||||
},
|
||||
_ => Err(err_msg("invalid bit depth"))
|
||||
}
|
||||
}
|
||||
_ => Err(err_msg("invalid bit depth")),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,12 +185,30 @@ pub fn load_pict(b: &[u8]) -> ResultS<Image>
|
|||
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
|
||||
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
|
||||
|
@ -223,7 +258,9 @@ pub fn load_pict(b: &[u8]) -> ResultS<Image>
|
|||
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"))
|
||||
_ => {
|
||||
return Err(err_msg("invalid op in PICT"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,12 +279,15 @@ pub fn get_clut(b: &[u8]) -> ResultS<(Vec<Color>, 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<u8>, 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<u8>, 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<F, N>(cmp: bool, len: usize, out: &mut Vec<u8>, 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<u8>, depth: u16) -> ResultS<Vec<u8>>
|
||||
{
|
||||
let mut o = Vec::with_capacity(match 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"))
|
||||
_ => 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")),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,12 @@ use std::fmt;
|
|||
fn read_group(b: &[u8], text: &[u8]) -> ResultS<Group>
|
||||
{
|
||||
// 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})
|
||||
|
@ -21,13 +21,13 @@ fn read_face(b: &[u8]) -> ResultS<Face>
|
|||
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 encoded = b.c_u16b(2)? & 1 != 0;
|
||||
|
@ -36,13 +36,17 @@ fn read_terminal(b: &[u8]) -> ResultS<(usize, Terminal)>
|
|||
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)?);
|
||||
|
@ -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, "}}")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,12 @@ impl Wad<'_>
|
|||
{
|
||||
pub fn new(b: &[u8]) -> ResultS<Wad>
|
||||
{
|
||||
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;
|
||||
|
@ -21,25 +23,35 @@ impl Wad<'_>
|
|||
// 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,9 +68,9 @@ fn get_chunks(b: &[u8], cnksize: usize) -> ResultS<ChunkMap>
|
|||
let mut p = 0;
|
||||
|
||||
while p < b.len() {
|
||||
let iden = b.c_iden(p )?;
|
||||
let iden = b.c_iden(p)?;
|
||||
// ofs = b.c_u32b(p+ 4)?;
|
||||
let size = b.c_u32b(p+ 8)? as usize;
|
||||
let size = b.c_u32b(p + 8)? as usize;
|
||||
// pofs = b.c_u32b(p+12)?;
|
||||
let beg = p + cnksize;
|
||||
let end = beg + size;
|
||||
|
@ -69,14 +81,14 @@ fn get_chunks(b: &[u8], cnksize: usize) -> ResultS<ChunkMap>
|
|||
Ok(chunks)
|
||||
}
|
||||
|
||||
type Chunk <'a> = &'a[u8];
|
||||
type Chunk<'a> = &'a [u8];
|
||||
type ChunkMap<'a> = BTreeMap<Ident, Chunk<'a>>;
|
||||
type EntryMap<'a> = BTreeMap<u16 , Entry<'a>>;
|
||||
type EntryMap<'a> = BTreeMap<u16, Entry<'a>>;
|
||||
|
||||
pub struct Entry<'a>
|
||||
{
|
||||
pub chunks: ChunkMap<'a>,
|
||||
pub appdata: &'a[u8],
|
||||
pub appdata: &'a [u8],
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -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, "}}")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue