clippy saves the world

png-branch
an 2019-02-14 00:19:36 -05:00
parent a2c6e7eeff
commit aadf35e9cb
12 changed files with 224 additions and 182 deletions

1
clippy.toml Normal file
View File

@ -0,0 +1 @@
single-char-binding-names-threshold = 10

View File

@ -7,13 +7,13 @@ macro_rules! c_enum
{
(
$(#[$outer:meta])*
pub enum $E:ident: $T:ty
$V:vis enum $E:ident: $T:ty
{
$($value:expr => $Enum:ident,)+
}
) => {
$(#[$outer])*
pub enum $E
$V enum $E
{
$($Enum,)+
}

View File

@ -3,7 +3,7 @@
fn crc_accum(a: u32, _: u32) -> u32
{
if a & 1 == 1 {
0xedb88320 ^ a >> 1
0xEDB8_8320 ^ a >> 1
} else {
a >> 1
}
@ -12,8 +12,8 @@ fn crc_accum(a: u32, _: u32) -> u32
fn crc_init() -> [u32; 256]
{
let mut t = [0; 256];
for n in 0..256 {
t[n] = (0..8).fold(n as u32, crc_accum);
for (n, v) in t.iter_mut().enumerate() {
*v = (0..8).fold(n as u32, crc_accum);
}
t
}
@ -22,7 +22,7 @@ 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])
.fold(s, |a, &o| a >> 8 ^ t[(a & 0xFF ^ u32::from(o)) as usize])
}
#[test]

View File

@ -81,7 +81,7 @@ impl ops::Mul for Fx32
fn mul(self, o: Fx32) -> Fx32
{
Fx32((self.0 as i64 * o.0 as i64 / Fx32::ONE as i64) as i32)
Fx32((i64::from(self.0) * i64::from(o.0) / i64::from(Fx32::ONE)) as i32)
}
}
@ -91,7 +91,7 @@ impl ops::Div for Fx32
fn div(self, o: Fx32) -> Fx32
{
Fx32((self.0 as i64 * Fx32::ONE as i64 / o.0 as i64) as i32)
Fx32((i64::from(self.0) * i64::from(Fx32::ONE) / i64::from(o.0)) as i32)
}
}

View File

@ -26,7 +26,7 @@ pub fn r5g5b5_to_rgb16(rgb: u16) -> Color16
/// Creates a RGB16 color from a RGB8 format color.
pub fn rgb8_to_rgb16(r: u8, g: u8, b: u8) -> Color16
{
Color16::new(r as (u16) << 8, g as (u16) << 8, b as (u16) << 8)
Color16::new(u16::from(r) << 8, u16::from(g) << 8, u16::from(b) << 8)
}
/// Writes a PPM file from an image.
@ -40,7 +40,7 @@ pub fn write_ppm(out: &mut impl io::Write, im: &impl Image) -> ResultS<()>
write!(out, "{} {} {} ", cr.r(), cr.g(), cr.b())?;
}
out.write(b"\n")?;
out.write_all(b"\n")?;
}
Ok(())
@ -49,21 +49,21 @@ pub fn write_ppm(out: &mut impl io::Write, im: &impl Image) -> ResultS<()>
/// Writes a TGA file from an image.
pub fn write_tga(out: &mut impl io::Write, im: &impl Image) -> ResultS<()>
{
out.write(&[0, 0, 2])?; // id len, color map type, image type
out.write(&[0, 0, 0, 0, 0])?; // color map spec
out.write(&[0, 0])?; // x origin
out.write(&[0, 0])?; // y origin
out.write(&(im.w() as u16).to_le_bytes())?; // width
out.write(&(im.h() as u16).to_le_bytes())?; // height
out.write(&[32, 0])?; // depth, descriptor
out.write_all(&[0, 0, 2])?; // id len, color map type, image type
out.write_all(&[0, 0, 0, 0, 0])?; // color map spec
out.write_all(&[0, 0])?; // x origin
out.write_all(&[0, 0])?; // y origin
out.write_all(&(im.w() as u16).to_le_bytes())?; // width
out.write_all(&(im.h() as u16).to_le_bytes())?; // height
out.write_all(&[32, 0])?; // depth, descriptor
for y in (0..im.h()).rev() {
for x in 0..im.w() {
let cr = im.index(x, y);
out.write(&[(cr.b() >> 8) as u8,
(cr.g() >> 8) as u8,
(cr.r() >> 8) as u8,
(cr.a() >> 8) as u8])?;
out.write_all(&[(cr.b() >> 8) as u8,
(cr.g() >> 8) as u8,
(cr.r() >> 8) as u8,
(cr.a() >> 8) as u8])?;
}
}

View File

@ -71,7 +71,7 @@ pub fn fuck_string(s: &[u8]) -> Vec<u8>
pub fn pascal_str(b: &[u8]) -> Option<&[u8]>
{
let s = *b.get(0)? as usize;
b.get(1..1 + s)
b.get(1..=s)
}
/// Converts input from Mac Roman to a Unicode string.
@ -79,16 +79,14 @@ 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);
}
for &c in s.iter() {
let c = match c {
0 => break,
b'\r' => '\n',
c if c & 0x80 != 0 => TR[c as usize & 0x7F],
c => c as char,
};
v.push(c);
}
v

View File

@ -10,12 +10,12 @@ fn make_tga(fname: &str, im: &impl Image) -> ResultS<()>
write_tga(&mut out, im)
}
fn make_chunk(opt: &Options, cid: &Ident, cnk: &[u8], eid: u16) -> ResultS<()>
fn make_chunk(opt: &Options, cid: Ident, cnk: &[u8], eid: u16) -> ResultS<()>
{
let cid = mac_roman_conv(cid);
let cid = mac_roman_conv(&cid);
let fname = format!("{}/{:04}{}.bin", opt.out_dir, eid, cid);
let mut out = io::BufWriter::new(fs::File::create(&fname)?);
out.write(cnk)?;
out.write_all(cnk)?;
Ok(())
}
@ -26,51 +26,51 @@ fn make_yaml(data: &impl serde::Serialize) -> ResultS<()>
Ok(())
}
fn dump_chunk(opt: &Options, cid: &Ident, cnk: &[u8], eid: u16) -> ResultS<()>
fn dump_chunk(opt: &Options, cid: Ident, cnk: &[u8], eid: u16) -> ResultS<()>
{
if opt.wad_all {
make_chunk(opt, cid, cnk, eid)?;
return Ok(());
}
match cid {
match &cid {
b"PICT" => {
if opt.wad_chunks.contains(cid) {
if opt.wad_chunks.contains(&cid) {
let im = pict::load_pict(cnk)?;
make_tga(&format!("{}/pict_{}.tga", opt.out_dir, eid), &im)?;
}
}
b"Minf" => {
if opt.wad_chunks.contains(cid) {
if opt.wad_chunks.contains(&cid) {
make_yaml(&map::Minf::chunk(cnk)?)?;
}
}
b"EPNT" => {
if opt.wad_chunks.contains(cid) {
if opt.wad_chunks.contains(&cid) {
make_yaml(&map::Endpoint::chunk(cnk)?)?;
}
}
b"PNTS" => {
if opt.wad_chunks.contains(cid) {
if opt.wad_chunks.contains(&cid) {
make_yaml(&map::Point::chunk(cnk)?)?;
}
}
b"LINS" => {
if opt.wad_chunks.contains(cid) {
if opt.wad_chunks.contains(&cid) {
make_yaml(&map::Line::chunk(cnk)?)?;
}
}
b"SIDS" => {
if opt.wad_chunks.contains(cid) {
if opt.wad_chunks.contains(&cid) {
make_yaml(&map::Side::chunk(cnk)?)?;
}
}
b"term" => {
if opt.wad_chunks.contains(cid) {
if opt.wad_chunks.contains(&cid) {
make_yaml(&term::Terminal::chunk(cnk)?)?;
}
}
cid => {
&cid => {
if opt.wad_unknown {
make_chunk(opt, cid, cnk, eid)?;
}
@ -90,7 +90,7 @@ fn process_wad(opt: &Options, b: &[u8]) -> ResultS<()>
for (eid, ent) in wad.entries {
for (cid, cnk) in ent.chunks {
dump_chunk(opt, &cid, cnk, eid)?;
dump_chunk(opt, cid, cnk, eid)?;
}
}

View File

@ -38,9 +38,9 @@ pub fn check_macbin(b: &[u8]) -> Option<usize>
let mut crc = 0;
// check header crc
for i in 0..124 {
for &byte in b.iter().take(124) {
for j in 8..16 {
let d = b[i] as (u16) << j;
let d = u16::from(byte) << j;
if (d ^ crc) & 0x8000 != 0 {
crc = crc << 1 ^ 0x1021;
} else {

View File

@ -3,43 +3,34 @@
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;
/// Process a CopyBits operation.
pub fn read_bitmap_area(mut im: Image8,
b: &[u8],
packed: bool,
clip: bool)
-> ResultS<Image8>
/// Reads a PixMap header.
fn read_pm_header<'a>(b: &'a [u8],
pack: bool,
clip: bool,
im: &Image8)
-> ResultS<(&'a [u8], Header)>
{
let mut p = if !packed {4} else {0};
let pt_fl = c_u16b(b, 0)?;
let top = c_u16b(b, 2)? as usize;
let left = c_u16b(b, 4)? as usize;
let bottom = c_u16b(b, 6)? as usize;
let right = c_u16b(b, 8)? as usize;
let pack_t = c_u16b(b, 12)?;
let depth = c_u16b(b, 28)?;
let pack_t = PackType::from_repr(pack_t)?;
let (w, h) = (im.w(), im.h());
let pitch_fl = c_u16b(b, p)?;
let top = c_u16b(b, p + 2)? as usize;
let left = c_u16b(b, p + 4)? as usize;
let bottom = c_u16b(b, p + 6)? as usize;
let right = c_u16b(b, p + 8)? as usize;
let pack_typ = c_u16b(b, p + 12)?;
let depth = c_u16b(b, p + 28)?;
if pitch_fl & 0x8000 == 0 {
if pt_fl & 0x8000 == 0 {
bail!("PICT1 not supported");
}
if right - left != w || bottom - top != h {
if right - left != im.w() || bottom - top != im.h() {
bail!("image bounds are incorrect");
}
p += 46; // size of header
let mut p = 46;
// get CLUT if packed
let clut = if packed {
let clut = if pack {
let (clut, sz) = get_clut(c_data(b, p..)?)?;
p += sz;
Some(clut)
@ -53,115 +44,148 @@ pub fn read_bitmap_area(mut im: Image8,
p += c_u16b(b, 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_t == PackType::Default ||
pack_t == PackType::Rle16 && depth == 16 ||
pack_t == PackType::Rle32 && depth == 32;
let pitch = (pitch_fl & 0x3fff) as usize;
let pitch = (pt_fl & 0x3FFF) as usize;
match depth {
1 | 2 | 4 | 8 => {
let clut = ok!(clut, "no CLUT in indexed mode")?;
if pitch < 8 && depth == 8 {
// uncompressed 8-bit colormap indices
for _ in 0..h {
for _ in 0..w {
let idx = c_byte(b, (p, p += 1).0)? as usize;
im.cr.push(ok!(clut.get(idx), "invalid index")?.clone());
}
}
Ok((&b[p..], Header{pitch, pack_t, depth, clut, rle}))
}
Ok(im)
} else if rle {
// RLE compressed 1, 2, 4 or 8 bit colormap indices
for _ in 0..h {
let (d, pp) = read_rle(c_data(b, p..)?, pitch, false)?;
let d = if depth < 8 {expand_data(d, depth)?} else {d};
/// Reads an indexed PixMap.
fn read_pm_ind(mut im: Image8, b: &[u8], hdr: Header) -> ResultS<Image8>
{
let clut = ok!(hdr.clut, "no CLUT in indexed mode")?;
let mut p = 0;
p += pp;
for x in 0..w {
let idx = c_byte(&d, x)? as usize;
im.cr.push(ok!(clut.get(idx), "invalid index")?.clone());
}
}
Ok(im)
} else {
Err(err_msg("invalid configuration"))
if hdr.pitch < 8 && hdr.depth == 8 {
// uncompressed 8-bit colormap indices
for _ in 0..im.h() {
for _ in 0..im.w() {
let idx = c_byte(b, p)? as usize;
im.cr.push(ok!(clut.get(idx), "invalid index")?.clone());
p += 1;
}
}
16 => {
if pitch < 8 || pack_typ == PACK_NONE {
// uncompressed R5G5B5
for _ in 0..h {
for _ in 0..w {
im.cr.push(r5g5b5_to_rgb8(c_u16b(b, (p, p += 2).0)?));
}
}
Ok(im)
} else if rle {
// RLE compressed R5G5B5
for _ in 0..h {
let (d, pp) = read_rle(c_data(b, p..)?, pitch, true)?;
Ok(im)
} else if hdr.rle {
// RLE compressed 1, 2, 4 or 8 bit colormap indices
for _ in 0..im.h() {
let (d, pp) = read_rle(c_data(b, p..)?, hdr.pitch, false)?;
let d = if hdr.depth < 8 {expand_data(d, hdr.depth)?} else {d};
p += pp;
p += pp;
for x in 0..w {
im.cr.push(r5g5b5_to_rgb8(c_u16b(&d, x * 2)?));
}
}
Ok(im)
} else {
Err(err_msg("invalid configuration"))
for x in 0..im.w() {
let idx = c_byte(&d, x)? as usize;
im.cr.push(ok!(clut.get(idx), "invalid index")?.clone());
}
}
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 = c_byte(b, p)?;
let g = c_byte(b, p + 1)?;
let b = c_byte(b, p + 2)?;
p += 3;
im.cr.push(Color8::new(r, g, b));
}
}
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(c_data(b, p..)?, pitch, false)?;
Ok(im)
} else {
bail!("invalid configuration")
}
}
p += pp;
/// Reads a R5G5B5 PixMap.
fn read_pm_16(mut im: Image8, b: &[u8], hdr: Header) -> ResultS<Image8>
{
let mut p = 0;
for x in 0..w {
let r = c_byte(&d, x + w)?;
let g = c_byte(&d, x + w * 1)?;
let b = c_byte(&d, x + w * 2)?;
im.cr.push(Color8::new(r, g, b));
}
}
Ok(im)
} else {
Err(err_msg("invalid configuration"))
if hdr.pitch < 8 || hdr.pack_t == PackType::None {
// uncompressed R5G5B5
for _ in 0..im.h() {
for _ in 0..im.w() {
im.cr.push(r5g5b5_to_rgb8(c_u16b(b, p)?));
p += 2;
}
}
_ => Err(err_msg("invalid bit depth")),
Ok(im)
} else if hdr.rle {
// RLE compressed R5G5B5
for _ in 0..im.h() {
let (d, pp) = read_rle(c_data(b, p..)?, hdr.pitch, true)?;
p += pp;
for x in 0..im.w() {
im.cr.push(r5g5b5_to_rgb8(c_u16b(&d, x * 2)?));
}
}
Ok(im)
} else {
bail!("invalid configuration")
}
}
/// Reads a RGB8 PixMap.
fn read_pm_32(mut im: Image8, b: &[u8], hdr: Header) -> ResultS<Image8>
{
let mut p = 0;
if hdr.pitch < 8 || hdr.pack_t == PackType::None || hdr.pack_t == PackType::NoPad {
// uncompressed RGB8 or XRGB8
for _ in 0..im.h() {
for _ in 0..im.w() {
if hdr.pack_t != PackType::NoPad {
p += 1;
}
let r = c_byte(b, p)?;
let g = c_byte(b, p + 1)?;
let b = c_byte(b, p + 2)?;
p += 3;
im.cr.push(Color8::new(r, g, b));
}
}
Ok(im)
} else if hdr.rle {
// RLE compressed RGB8
let pitch = hdr.pitch - im.w(); // remove padding byte from pitch
for _ in 0..im.h() {
let (d, pp) = read_rle(c_data(b, p..)?, pitch, false)?;
p += pp;
for x in 0..im.w() {
let r = c_byte(&d, x + im.w())?;
let g = c_byte(&d, x + im.w() * 2)?;
let b = c_byte(&d, x + im.w() * 3)?;
im.cr.push(Color8::new(r, g, b));
}
}
Ok(im)
} else {
bail!("invalid configuration")
}
}
/// Process a CopyBits operation.
fn read_pm_area(im: Image8,
b: &[u8],
pack: bool,
clip: bool)
-> ResultS<Image8>
{
let p = if pack {0} else {4};
let (b, hdr) = read_pm_header(&b[p..], pack, clip, &im)?;
match hdr.depth {
1 | 2 | 4 | 8 => read_pm_ind(im, b, hdr),
16 => read_pm_16(im, b, hdr),
32 => read_pm_32(im, b, hdr),
_ => bail!("invalid bit depth"),
}
}
/// Process a CompressedQuickTime operation.
pub fn read_quicktime_c(_im: Image8, _b: &[u8]) -> ResultS<Image8>
fn read_quicktime_c(_im: Image8, _b: &[u8]) -> ResultS<Image8>
{
unimplemented!()
}
@ -176,24 +200,25 @@ pub fn load_pict(b: &[u8]) -> ResultS<Image8>
let mut p = 10; // size of header
while p < b.len() {
let op = c_u16b(b, (p, p += 2).0)?;
let op = c_u16b(b, p)?;
p += 2;
match op {
0x0098 => {
// PackBitsRect
return read_bitmap_area(im, c_data(b, p..)?, true, false);
return read_pm_area(im, c_data(b, p..)?, true, false);
}
0x0099 => {
// PackBitsRgn
return read_bitmap_area(im, c_data(b, p..)?, true, true);
return read_pm_area(im, c_data(b, p..)?, true, true);
}
0x009a => {
// DirectBitsRect
return read_bitmap_area(im, c_data(b, p..)?, false, false);
return read_pm_area(im, c_data(b, p..)?, false, false);
}
0x009b => {
// DirectBitsRgn
return read_bitmap_area(im, c_data(b, p..)?, false, true);
return read_pm_area(im, c_data(b, p..)?, false, true);
}
0x8200 => {
// CompressedQuickTime
@ -223,8 +248,7 @@ pub fn load_pict(b: &[u8]) -> ResultS<Image8>
0x0015 | // PnLocHFrac
0x0016 | // ChExtra
0x0023 | // ShortLineFrom
0x00a0 | // ShortComment
0x02ff => p += 2, // Version
0x00a0 => p += 2, // ShortComment
0x0006 | // SpExtra
0x0007 | // PnSize
0x000b | // OvSize
@ -247,7 +271,6 @@ pub fn load_pict(b: &[u8]) -> ResultS<Image8>
0x0033 | // InvertRect
0x0034 => p += 8, // FillRect
0x002d => p += 10, // LineJustify
0x0c00 => p += 24, // HeaderOp
0x0001 => p += (c_u16b(b, p )? & !1) as usize, // Clip
0x00a1 => p += (c_u16b(b, p+2)? & !1) as usize + 2, // LongComment
0x100..=
@ -302,10 +325,11 @@ pub fn read_rle(b: &[u8], pitch: usize, ln: bool) -> ResultS<(Vec<u8>, usize)>
};
while p < sz {
let szf = c_byte(b, (p, p += 1).0)?;
let szf = c_byte(b, p)?;
let cmp = szf & 0x80 != 0;
let len = if cmp {!szf + 2} else {szf + 1} as usize;
p += 1;
o.reserve(len);
if ln {
@ -356,9 +380,9 @@ pub fn expand_data(b: Vec<u8>, depth: u16) -> ResultS<Vec<u8>>
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
4 => {for i in (0..=1).rev() {o.push(ch >> (i * 4) & 0xFu8);}}
2 => {for i in (0..=3).rev() {o.push(ch >> (i * 2) & 0x3u8);}}
1 => {for i in (0..=7).rev() {o.push(ch >> i & 0x1u8);}}
_ => bail!("invalid bit depth"),
}
}
@ -366,4 +390,25 @@ pub fn expand_data(b: Vec<u8>, depth: u16) -> ResultS<Vec<u8>>
Ok(o)
}
struct Header
{
pitch: usize,
pack_t: PackType,
depth: u16,
clut: Option<Vec<Color8>>,
rle: bool,
}
c_enum! {
#[derive(PartialEq)]
enum PackType: u16
{
0 => Default,
1 => None,
2 => NoPad,
3 => Rle16,
4 => Rle32,
}
}
// EOF

View File

@ -29,9 +29,7 @@ fn tab_coll(b: &[u8],
let mut tabs = vec![vec![ColorShp::Translucent; clr_num]; tab_num];
let mut p = 0;
for i in 0..tab_num {
let clut = &mut tabs[i];
for clut in tabs.iter_mut().take(tab_num) {
for _ in 0..clr_num {
let (i, cr) = color(c_data(b, p..)?)?;

View File

@ -133,7 +133,7 @@ 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 {
if !self.text.is_empty() {
write!(f, ";\n{}", self.text)?;
}
write!(f, "}}")

View File

@ -119,10 +119,10 @@ impl fmt::Debug for Entry<'_>
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
write!(f, "Entry{{ ")?;
for (iden, _) in &self.chunks {
for iden in self.chunks.keys() {
write!(f, "{} ", mac_roman_conv(iden))?;
}
if self.appdata.len() != 0 {
if !self.appdata.is_empty() {
write!(f, "\nappdata: {:?} ", self.appdata)?;
}
write!(f, "}}")