Fixed metadata key stuff, rustfmt.toml for a better work enviroment
This commit is contained in:
parent
f52079b527
commit
b7f4a363b8
2
rustfmt.toml
Normal file
2
rustfmt.toml
Normal file
|
@ -0,0 +1,2 @@
|
|||
trailing_semicolon = false
|
||||
max_width = 200
|
107
src/main.rs
107
src/main.rs
|
@ -1,8 +1,8 @@
|
|||
use std::{env, io, process};
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader, BufWriter, Lines};
|
||||
use arrayvec::{ArrayString, ArrayVec};
|
||||
use png::{BitDepth, ColorType, EncodingError};
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader, BufWriter, Lines};
|
||||
use std::{env, io, process};
|
||||
use thiserror::Error;
|
||||
|
||||
mod nummap;
|
||||
|
@ -81,12 +81,21 @@ fn lines_read_noempty<T: BufRead>(lines: &mut Lines<T>) -> Result<Option<String>
|
|||
|
||||
#[inline]
|
||||
fn assert_trailing_leading(s: &str) -> Result<()> {
|
||||
if s.is_empty() || s.as_bytes()[0] == 32 || s.as_bytes()[s.len()-1] == 32 {
|
||||
return Err(IllegalWhitespaceError(s.to_string()));
|
||||
if s.is_empty() || s.as_bytes()[0] == 32 || s.as_bytes()[s.len() - 1] == 32 {
|
||||
return Err(IllegalWhitespaceError(s.to_string()))
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_cif_number(num: &str, bytes_per_pixel: u32) -> Result<ArrayVec<&str, 4_usize>> {
|
||||
let split = num.split(';').collect::<ArrayVec<_, 4>>();
|
||||
if split.len() != bytes_per_pixel as usize {
|
||||
return Err(InvalidPixelError(num.to_string()))
|
||||
} else {
|
||||
Ok(split)
|
||||
}
|
||||
}
|
||||
|
||||
fn unfuck_cif_number(number: &str) -> Result<u32> {
|
||||
assert_trailing_leading(number)?;
|
||||
let mut buf = ArrayString::<2048>::new();
|
||||
|
@ -94,14 +103,14 @@ fn unfuck_cif_number(number: &str) -> Result<u32> {
|
|||
let splitlen = split.len();
|
||||
for (i, word) in split.iter().enumerate() {
|
||||
if !word.starts_with("ty") {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
let thousands = match *word {
|
||||
"tysiąc" => {
|
||||
if i == 0 {
|
||||
&1_u16
|
||||
} else {
|
||||
return Err(GrammarError(number.to_string()));
|
||||
return Err(GrammarError(number.to_string()))
|
||||
}
|
||||
}
|
||||
"tysięcy" | "tysiące" => {
|
||||
|
@ -109,10 +118,10 @@ fn unfuck_cif_number(number: &str) -> Result<u32> {
|
|||
join_to_arraystring(&split[..i], &mut buf)?;
|
||||
nummap::U16_NUMMAP.get(&buf).ok_or_else(|| GrammarError(number.to_string()))?
|
||||
} else {
|
||||
return Err(GrammarError(number.to_string()));
|
||||
return Err(GrammarError(number.to_string()))
|
||||
}
|
||||
}
|
||||
_ => return Err(GrammarError(number.to_string()))
|
||||
_ => return Err(GrammarError(number.to_string())),
|
||||
};
|
||||
let remainder = if i + 1 < splitlen {
|
||||
buf.clear();
|
||||
|
@ -121,7 +130,7 @@ fn unfuck_cif_number(number: &str) -> Result<u32> {
|
|||
} else {
|
||||
&0_u16
|
||||
};
|
||||
return Ok(u32::from(*thousands) * 1000 + u32::from(*remainder));
|
||||
return Ok(u32::from(*thousands) * 1000 + u32::from(*remainder))
|
||||
}
|
||||
Ok(u32::from(*nummap::U16_NUMMAP.get(number).ok_or_else(|| GrammarError(number.to_string()))?))
|
||||
}
|
||||
|
@ -130,8 +139,10 @@ fn unfuck_cif_number_fast(number: &str) -> Result<u8> {
|
|||
assert_trailing_leading(number)?;
|
||||
let mut buf = ArrayString::<2048>::new();
|
||||
let split = number.split_ascii_whitespace().take(8).collect::<ArrayVec<_, 64>>();
|
||||
|
||||
join_to_arraystring(&split, &mut buf)?;
|
||||
let number = *(nummap::U8_NUMMAP.get(&buf).ok_or_else(|| InvalidPixelError(number.to_string()))?);
|
||||
|
||||
Ok(number)
|
||||
}
|
||||
|
||||
|
@ -155,25 +166,41 @@ fn decoder(inputfile: &str, outputfile: &str) -> Result<()> {
|
|||
|
||||
// "ROZMIAR szerokość: osiem, wysokość: osiem, bitów_na_piksel: trzydzieści dwa"
|
||||
let size_string = lines_read_noempty(&mut lines)?.ok_or(InvalidHeaderError)?;
|
||||
let size_split = size_string.strip_prefix("ROZMIAR")
|
||||
let size_split = size_string
|
||||
.strip_prefix("ROZMIAR")
|
||||
.ok_or_else(|| InvalidSizeError(size_string.to_string()))?
|
||||
.split(',').take(3).collect::<ArrayVec<_, 3>>();
|
||||
.split(',')
|
||||
.take(3)
|
||||
.collect::<ArrayVec<_, 3>>();
|
||||
if size_split.len() != 3 {
|
||||
return Err(InvalidSizeError(size_string.to_string()))
|
||||
}
|
||||
|
||||
let width = unfuck_cif_number(size_split[0].trim_start().strip_prefix("szerokość:")
|
||||
.ok_or_else(|| InvalidSizeError(size_string.to_string()))?.trim_start())?;
|
||||
let height = unfuck_cif_number(size_split[1].trim_start().strip_prefix("wysokość:")
|
||||
.ok_or_else(|| InvalidSizeError(size_string.to_string()))?.trim_start())?;
|
||||
let width = unfuck_cif_number(
|
||||
size_split[0]
|
||||
.trim_start()
|
||||
.strip_prefix("szerokość:")
|
||||
.ok_or_else(|| InvalidSizeError(size_string.to_string()))?
|
||||
.trim_start(),
|
||||
)?;
|
||||
let height = unfuck_cif_number(
|
||||
size_split[1]
|
||||
.trim_start()
|
||||
.strip_prefix("wysokość:")
|
||||
.ok_or_else(|| InvalidSizeError(size_string.to_string()))?
|
||||
.trim_start(),
|
||||
)?;
|
||||
|
||||
let format = match unfuck_cif_number_fast(
|
||||
size_split[2].trim_start().strip_prefix("bitów_na_piksel:")
|
||||
.ok_or_else(|| InvalidSizeError(size_string.to_string()))?.trim_start()
|
||||
size_split[2]
|
||||
.trim_start()
|
||||
.strip_prefix("bitów_na_piksel:")
|
||||
.ok_or_else(|| InvalidSizeError(size_string.to_string()))?
|
||||
.trim_start(),
|
||||
)? {
|
||||
24 => ColorType::Rgb,
|
||||
32 => ColorType::Rgba,
|
||||
_ => return Err(InvalidSizeError(size_string.to_string()))
|
||||
_ => return Err(InvalidSizeError(size_string.to_string())),
|
||||
};
|
||||
|
||||
if width == 0 || height == 0 {
|
||||
|
@ -184,27 +211,49 @@ fn decoder(inputfile: &str, outputfile: &str) -> Result<()> {
|
|||
outpng.set_color(format);
|
||||
outpng.set_depth(BitDepth::Eight);
|
||||
|
||||
let bytes_per_pixel = if format == ColorType::Rgb { 3 } else { 4 };
|
||||
|
||||
let mut md_head = false;
|
||||
let mut md_txt = ArrayString::<2048>::new();
|
||||
let mut md_key = ArrayString::<2048>::new();
|
||||
|
||||
let first = loop {
|
||||
if let Some(line) = lines_read_noempty(&mut lines)? {
|
||||
// TODO: THIS IS A BAD IDEA TO PARSE METADATA, CHANGE THIS ASAP
|
||||
// So this is still some cringe code
|
||||
// But currently it works
|
||||
if line.starts_with("METADANE ") {
|
||||
let mut buf = ArrayString::<2048>::new();
|
||||
let split = line.split_ascii_whitespace().collect::<ArrayVec<_, 256>>();
|
||||
join_to_arraystring(&split, &mut buf)?;
|
||||
let md_split = buf.splitn(3, ' ').collect::<ArrayVec<_, 3>>();
|
||||
if md_split.len() != 3 {
|
||||
return Err(InvalidMetadataError(line.to_string()))
|
||||
if md_head {
|
||||
let split = line.split_ascii_whitespace().collect::<ArrayVec<_, 256>>();
|
||||
if split.len() > 2 {
|
||||
return Err(InvalidMetadataError("Metadata values must not contain line feeds.".to_string()))
|
||||
}
|
||||
md_txt.push_str(&line[8..]);
|
||||
continue
|
||||
} else {
|
||||
md_head = true;
|
||||
let mut buf = ArrayString::<2048>::new();
|
||||
let split = line.split_ascii_whitespace().collect::<ArrayVec<_, 256>>();
|
||||
join_to_arraystring(&split, &mut buf)?;
|
||||
let md_split = buf.splitn(3, ' ').collect::<ArrayVec<_, 3>>();
|
||||
if md_split.len() != 3 {
|
||||
return Err(InvalidMetadataError(line.to_string()))
|
||||
}
|
||||
md_key.push_str(md_split[1]);
|
||||
md_txt.push_str(md_split[2]);
|
||||
continue
|
||||
}
|
||||
outpng.add_itxt_chunk(md_split[1].to_string(), md_split[2].to_string())?;
|
||||
} else if is_cif_number(&line, bytes_per_pixel).is_err() {
|
||||
md_txt.push_str(&line);
|
||||
continue
|
||||
} else {
|
||||
outpng.add_itxt_chunk(md_key.to_string(), md_txt.to_string())?;
|
||||
break line
|
||||
}
|
||||
break line
|
||||
}
|
||||
return Err(NoDataError)
|
||||
};
|
||||
|
||||
let mut outpng = outpng.write_header()?;
|
||||
let bytes_per_pixel = if format == ColorType::Rgb {3} else {4};
|
||||
|
||||
let mut pixmap = Vec::with_capacity((bytes_per_pixel * width * height) as usize);
|
||||
|
||||
|
|
Loading…
Reference in a new issue