Rust black magic, but this is considerably faster

This commit is contained in:
famfo 2022-01-25 20:22:56 +01:00
parent 7cf550a3a9
commit b191d16ac5

View file

@ -148,11 +148,9 @@ fn unfuck_color_type(color_type: &str) -> Result<ColorType> {
}
#[allow(clippy::too_many_lines)] // bruh
fn decoder(inputfile: &str, outputfile: &str) -> Result<()> {
fn decoder(inputfile: &str) -> Result<(u32, u32, ColorType, ArrayVec<String, 124_usize>, ArrayVec<String, 124_usize>, Vec<u8>)> {
let infile = File::open(inputfile)?;
let outfile = File::create(outputfile)?;
let mut lines = BufReader::new(infile).lines();
let rawriter = BufWriter::new(outfile);
// "CIF: <flags>"
if !lines.next().transpose()?.ok_or(InvalidHeaderError)?.starts_with("CIF:") {
@ -204,14 +202,12 @@ fn decoder(inputfile: &str, outputfile: &str) -> Result<()> {
return Err(NoDataError)
}
let mut outpng = png::Encoder::new(rawriter, width, height);
outpng.set_color(format);
outpng.set_depth(BitDepth::Eight);
let bytes_per_pixel = if format == ColorType::Rgb { 3 } else { 4 };
let mut md_keylock = false;
let mut md_key = ArrayString::<2048>::new();
let mut md_key_vec = ArrayVec::<String, 124>::new();
let mut md_val = ArrayVec::<String, 124>::new();
let first = loop {
if let Some(line) = lines_read_noempty(&mut lines)? {
@ -221,7 +217,8 @@ fn decoder(inputfile: &str, outputfile: &str) -> Result<()> {
if split.len() != 2 {
continue
}
outpng.add_itxt_chunk(md_key.to_string(), split[1].trim_start().to_string())?;
md_key_vec.push(md_key.to_string());
md_val.push(split[1].trim_start().to_string());
md_keylock = false;
md_key.clear();
continue
@ -233,12 +230,13 @@ fn decoder(inputfile: &str, outputfile: &str) -> Result<()> {
1 => {
md_key.try_push_str(&sline)?;
md_keylock = true;
},
}
_ => {
md_key.try_push_str(&sline)?;
outpng.add_itxt_chunk(split[0].trim_start().to_string(), split[1].trim_start().to_string())?;
md_key_vec.push(split[0].trim_start().to_string());
md_val.push(split[1].trim_start().to_string());
md_key.clear();
},
}
}
continue
}
@ -247,8 +245,6 @@ fn decoder(inputfile: &str, outputfile: &str) -> Result<()> {
return Err(NoDataError)
};
let mut outpng = outpng.write_header()?;
let mut pixmap = Vec::with_capacity((bytes_per_pixel * width * height) as usize);
if !first.is_empty() {
@ -271,8 +267,26 @@ fn decoder(inputfile: &str, outputfile: &str) -> Result<()> {
}
}
outpng.write_image_data(&pixmap)?;
Ok((width, height, format, md_key_vec, md_val, pixmap))
}
fn write_png(outfile: &str, width: u32, height: u32, format: ColorType, md_key: ArrayVec<String, 124>, md_val: ArrayVec<String, 124>, pixmap: Vec<u8>) -> Result<()> {
let outfile = File::create(outfile)?;
let rawriter = BufWriter::new(outfile);
let mut outpng = png::Encoder::new(rawriter, width, height);
for i in 0..md_key.len() {
if md_key[i].is_empty() {
break
}
outpng.add_itxt_chunk(md_key[i].clone(), md_val[i].clone())?;
}
outpng.set_color(format);
outpng.set_depth(BitDepth::Eight);
let mut outpng = outpng.write_header()?;
outpng.write_image_data(&pixmap)?;
Ok(())
}
@ -282,8 +296,13 @@ fn main() {
eprintln!("Invalid usage:\nUsage: zardzewialy-dekoder-cif <input cif file> <output bmp file>");
process::exit(1);
}
if let Err(e) = decoder(&argv[0], &argv[1]) {
eprintln!("Error: {}", e);
let data = decoder(&argv[0]);
if let Err(e) = data {
eprintln!("Error while parsing cif: {}", e);
process::exit(1);
}
let data = data.unwrap();
if let Err(e) = write_png(&argv[1], data.0, data.1, data.2, data.3, data.4, data.5) {
eprintln!("Error while writing image: {}", e);
}
}