add PPM reader

png-branch
an 2019-03-13 12:56:39 -04:00
parent 54d253c89b
commit bf8fa42e26
2 changed files with 63 additions and 2 deletions

View File

@ -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")),
}?;
}

View File

@ -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