add PPM reader
parent
54d253c89b
commit
bf8fa42e26
|
@ -1,5 +1,5 @@
|
|||
use maraiah::{durandal::{err::*, file::*, image::*, sound::*},
|
||||
marathon::{machdr, shp, snd, tga, wad, wav}};
|
||||
marathon::{machdr, ppm, shp, snd, tga, wad, wav}};
|
||||
use std::{fs, io};
|
||||
|
||||
fn make_tga(_opt: &Options, fname: &str, im: &impl Image) -> ResultS<()>
|
||||
|
@ -9,6 +9,13 @@ fn make_tga(_opt: &Options, fname: &str, im: &impl Image) -> ResultS<()>
|
|||
tga::write_tga(&mut out, im)
|
||||
}
|
||||
|
||||
fn make_ppm(_opt: &Options, fname: &str, im: &impl Image) -> ResultS<()>
|
||||
{
|
||||
let mut out = io::BufWriter::new(fs::File::create(fname)?);
|
||||
|
||||
ppm::write_ppm(&mut out, im)
|
||||
}
|
||||
|
||||
fn make_yaml<T>(opt: &Options, data: &T) -> ResultS<()>
|
||||
where T: serde::Serialize + std::fmt::Debug
|
||||
{
|
||||
|
@ -111,6 +118,17 @@ fn process_snd(opt: &Options, b: &[u8]) -> ResultS<()>
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn process_ppm(opt: &Options, b: &[u8]) -> ResultS<()>
|
||||
{
|
||||
let im = ppm::read_ppm(b)?;
|
||||
|
||||
let fname = format!("{}/out.tga", opt.out_dir);
|
||||
make_tga(opt, &fname, &im)?;
|
||||
|
||||
let fname = format!("{}/out.ppm", opt.out_dir);
|
||||
make_ppm(opt, &fname, &im)
|
||||
}
|
||||
|
||||
fn main() -> ResultS<()>
|
||||
{
|
||||
use argparse::*;
|
||||
|
@ -210,6 +228,7 @@ fn main() -> ResultS<()>
|
|||
"wad:" => process_wad(&opt, b),
|
||||
"shp:" => process_shp(&opt, b),
|
||||
"snd:" => process_snd(&opt, b),
|
||||
"ppm:" => process_ppm(&opt, b),
|
||||
_ => Err(err_msg("invalid file type specified on commandline")),
|
||||
}?;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Portable PixMap format images.
|
||||
|
||||
use crate::durandal::{err::*, image::*};
|
||||
use crate::durandal::{err::*, fixed::FixedLong, image::*};
|
||||
use std::io;
|
||||
|
||||
/// Writes a PPM file from an image.
|
||||
|
@ -24,4 +24,46 @@ pub fn write_ppm(out: &mut impl io::Write, im: &impl Image) -> ResultS<()>
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Reads a PPM file into an image.
|
||||
pub fn read_ppm(inp: &[u8]) -> ResultS<Image16>
|
||||
{
|
||||
let mut it = inp.split(|&n| n == b'\n' || n == b'\r' || n == b' ');
|
||||
|
||||
if ok!(it.next(), "no magic number")? != b"P3" {
|
||||
bail!("not P3 format");
|
||||
}
|
||||
|
||||
let mut get_num = move || -> ResultS<u16> {
|
||||
let st = loop {
|
||||
match ok!(it.next(), "no more strings")? {
|
||||
b"" => {}
|
||||
st => break st
|
||||
}
|
||||
};
|
||||
let st = unsafe {std::str::from_utf8_unchecked(&st)};
|
||||
let nu = u16::from_str_radix(st, 10)?;
|
||||
Ok(nu)
|
||||
};
|
||||
|
||||
let width = get_num()?;
|
||||
let height = get_num()?;
|
||||
let depth = i64::from(get_num()?);
|
||||
|
||||
let mut im = Image16::new(usize::from(width), usize::from(height));
|
||||
|
||||
for _ in 0..height * width {
|
||||
let r = FixedLong::from_int(get_num()?.into());
|
||||
let g = FixedLong::from_int(get_num()?.into());
|
||||
let b = FixedLong::from_int(get_num()?.into());
|
||||
|
||||
let r = (r / depth * 65535).integ() as u16;
|
||||
let g = (g / depth * 65535).integ() as u16;
|
||||
let b = (b / depth * 65535).integ() as u16;
|
||||
|
||||
im.cr.push(Color16::new(r, g, b));
|
||||
}
|
||||
|
||||
Ok(im)
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
Loading…
Reference in New Issue