From 7affb73f95a743b94e4b1335a99542d684d962ab Mon Sep 17 00:00:00 2001 From: Marrub Date: Wed, 13 Mar 2019 11:32:46 -0400 Subject: [PATCH] move writers to their own modules --- source/durandal/image.rs | 59 ---------------------------------------- source/durandal/sound.rs | 42 ---------------------------- source/leela/main.rs | 6 ++-- source/marathon/mod.rs | 3 ++ source/marathon/ppm.rs | 27 ++++++++++++++++++ source/marathon/snd.rs | 4 +-- source/marathon/tga.rs | 41 ++++++++++++++++++++++++++++ source/marathon/wav.rs | 45 ++++++++++++++++++++++++++++++ 8 files changed, 121 insertions(+), 106 deletions(-) create mode 100644 source/marathon/ppm.rs create mode 100644 source/marathon/tga.rs create mode 100644 source/marathon/wav.rs diff --git a/source/durandal/image.rs b/source/durandal/image.rs index 46a01bd..01998f5 100644 --- a/source/durandal/image.rs +++ b/source/durandal/image.rs @@ -1,8 +1,5 @@ //! Image and color representations. -use crate::durandal::err::*; -use std::io; - /// Creates a RGB8 color from a R5G5B5 format color. /// /// # Examples @@ -54,62 +51,6 @@ pub fn rgb8_to_rgb16(cr: Color8) -> Color16 Color16::new(cr.r(), cr.g(), cr.b()) } -/// Writes a PPM file from an image. -/// -/// # Errors -/// -/// Errors if `out` cannot be written to. -pub fn write_ppm(out: &mut impl io::Write, im: &impl Image) -> ResultS<()> -{ - write!(out, "P3\n{} {}\n{}\n", im.w(), im.h(), u16::max_value())?; - - for y in 0..im.h() { - for x in 0..im.w() { - let cr = im.index(x, y); - write!(out, "{} {} {} ", cr.r(), cr.g(), cr.b())?; - } - - out.write_all(b"\n")?; - } - - Ok(()) -} - -/// Writes a TGA file from an image. -/// -/// # Errors -/// -/// Errors if `out` cannot be written to. -pub fn write_tga(out: &mut impl io::Write, im: &impl Image) -> ResultS<()> -{ - // id len, color map type, image type - out.write_all(&[0, 0, 2])?; - // color map spec - out.write_all(&[0, 0, 0, 0, 0])?; - // x origin - out.write_all(&[0, 0])?; - // y origin - out.write_all(&[0, 0])?; - // width - out.write_all(&u16::to_le_bytes(im.w() as u16))?; - // height - out.write_all(&u16::to_le_bytes(im.h() as u16))?; - // depth, descriptor - out.write_all(&[32, 0])?; - - for y in (0..im.h()).rev() { - for x in 0..im.w() { - let cr = im.index(x, y); - out.write_all(&[(cr.b() >> 8) as u8, - (cr.g() >> 8) as u8, - (cr.r() >> 8) as u8, - (cr.a() >> 8) as u8])?; - } - } - - Ok(()) -} - /// A generic color matrix image. pub trait Image { diff --git a/source/durandal/sound.rs b/source/durandal/sound.rs index 78054d8..a417aa3 100644 --- a/source/durandal/sound.rs +++ b/source/durandal/sound.rs @@ -1,47 +1,5 @@ //! Sound representation. -use crate::durandal::err::*; -use std::io; - -/// Writes a WAVE file from a sound. -/// -/// # Errors -/// -/// Errors if `out` cannot be written to. -pub fn write_wav(out: &mut impl io::Write, snd: &impl Sound) -> ResultS<()> -{ - let smp_rate = u32::from(snd.rate()); - let smp_size = smp_rate * 2; - let dat_size = snd.len() as u32 * 2; - - out.write_all(b"RIFF")?; - out.write_all(&u32::to_le_bytes(36 + dat_size))?; - out.write_all(b"WAVE")?; - - out.write_all(b"fmt ")?; - out.write_all(&u32::to_le_bytes(16))?; - // PCM - out.write_all(&u16::to_le_bytes(1))?; - // mono - out.write_all(&u16::to_le_bytes(1))?; - out.write_all(&u32::to_le_bytes(smp_rate))?; - out.write_all(&u32::to_le_bytes(smp_size))?; - // block alignment - out.write_all(&u16::to_le_bytes(2))?; - // bits per sample - out.write_all(&u16::to_le_bytes(16))?; - - out.write_all(b"data")?; - out.write_all(&u32::to_le_bytes(dat_size))?; - - for p in 0..snd.len() { - let sample = snd.index(p); - out.write_all(&sample.to_le_bytes())?; - } - - Ok(()) -} - /// Any PCM stream which may be represented as a 16-bit PCM stream. pub trait Sound { diff --git a/source/leela/main.rs b/source/leela/main.rs index 2902ef6..795e1bb 100644 --- a/source/leela/main.rs +++ b/source/leela/main.rs @@ -1,12 +1,12 @@ use maraiah::{durandal::{err::*, file::*, image::*, sound::*}, - marathon::{machdr, shp, snd, wad}}; + marathon::{machdr, shp, snd, tga, wad, wav}}; use std::{fs, io}; fn make_tga(_opt: &Options, fname: &str, im: &impl Image) -> ResultS<()> { let mut out = io::BufWriter::new(fs::File::create(fname)?); - write_tga(&mut out, im) + tga::write_tga(&mut out, im) } fn make_yaml(opt: &Options, data: &T) -> ResultS<()> @@ -25,7 +25,7 @@ fn make_yaml(opt: &Options, data: &T) -> ResultS<()> fn make_wav(fname: &str, snd: &impl Sound) -> ResultS<()> { let mut out = io::BufWriter::new(fs::File::create(fname)?); - write_wav(&mut out, snd) + wav::write_wav(&mut out, snd) } fn process_wad(opt: &Options, b: &[u8]) -> ResultS<()> diff --git a/source/marathon/mod.rs b/source/marathon/mod.rs index f596331..dde7ee7 100644 --- a/source/marathon/mod.rs +++ b/source/marathon/mod.rs @@ -5,10 +5,13 @@ pub mod machdr; pub mod map; pub mod phy; pub mod pict; +pub mod ppm; pub mod shp; pub mod snd; +pub mod tga; pub mod trm; pub mod wad; +pub mod wav; pub mod xfer; // EOF diff --git a/source/marathon/ppm.rs b/source/marathon/ppm.rs new file mode 100644 index 0000000..4789e9d --- /dev/null +++ b/source/marathon/ppm.rs @@ -0,0 +1,27 @@ +//! Portable PixMap format images. + +use crate::durandal::{err::*, image::*}; +use std::io; + +/// Writes a PPM file from an image. +/// +/// # Errors +/// +/// Errors if `out` cannot be written to. +pub fn write_ppm(out: &mut impl io::Write, im: &impl Image) -> ResultS<()> +{ + write!(out, "P3\n{} {}\n{}\n", im.w(), im.h(), u16::max_value())?; + + for y in 0..im.h() { + for x in 0..im.w() { + let cr = im.index(x, y); + write!(out, "{} {} {} ", cr.r(), cr.g(), cr.b())?; + } + + out.write_all(b"\n")?; + } + + Ok(()) +} + +// EOF diff --git a/source/marathon/snd.rs b/source/marathon/snd.rs index e8577ee..967cbab 100644 --- a/source/marathon/snd.rs +++ b/source/marathon/snd.rs @@ -90,12 +90,12 @@ pub fn read_sounds(b: &[u8]) -> ResultS> read_data! { 260, BE in b => version = u32[0]; - magic = Ident[4]; + magic = u8[4..8] slice; src_num = u16[8] usize; snd_num = u16[10] usize; } - if version != 1 || magic.0 != *b"snd2" { + if version != 1 || magic != b"snd2" { bail!("bad sound header"); } diff --git a/source/marathon/tga.rs b/source/marathon/tga.rs new file mode 100644 index 0000000..29ed240 --- /dev/null +++ b/source/marathon/tga.rs @@ -0,0 +1,41 @@ +//! TARGA format images. + +use crate::durandal::{err::*, image::*}; +use std::io; + +/// Writes a TGA file from an image. +/// +/// # Errors +/// +/// Errors if `out` cannot be written to. +pub fn write_tga(out: &mut impl io::Write, im: &impl Image) -> ResultS<()> +{ + // id len, color map type, image type + out.write_all(&[0, 0, 2])?; + // color map spec + out.write_all(&[0, 0, 0, 0, 0])?; + // x origin + out.write_all(&[0, 0])?; + // y origin + out.write_all(&[0, 0])?; + // width + out.write_all(&u16::to_le_bytes(im.w() as u16))?; + // height + out.write_all(&u16::to_le_bytes(im.h() as u16))?; + // depth, descriptor + out.write_all(&[32, 0])?; + + for y in (0..im.h()).rev() { + for x in 0..im.w() { + let cr = im.index(x, y); + out.write_all(&[(cr.b() >> 8) as u8, + (cr.g() >> 8) as u8, + (cr.r() >> 8) as u8, + (cr.a() >> 8) as u8])?; + } + } + + Ok(()) +} + +// EOF diff --git a/source/marathon/wav.rs b/source/marathon/wav.rs new file mode 100644 index 0000000..1265185 --- /dev/null +++ b/source/marathon/wav.rs @@ -0,0 +1,45 @@ +//! RIFF WAVE format sounds. + +use crate::durandal::{err::*, sound::*}; +use std::io; + +/// Writes a WAVE file from a sound. +/// +/// # Errors +/// +/// Errors if `out` cannot be written to. +pub fn write_wav(out: &mut impl io::Write, snd: &impl Sound) -> ResultS<()> +{ + let smp_rate = u32::from(snd.rate()); + let smp_size = smp_rate * 2; + let dat_size = snd.len() as u32 * 2; + + out.write_all(b"RIFF")?; + out.write_all(&u32::to_le_bytes(36 + dat_size))?; + out.write_all(b"WAVE")?; + + out.write_all(b"fmt ")?; + out.write_all(&u32::to_le_bytes(16))?; + // PCM + out.write_all(&u16::to_le_bytes(1))?; + // mono + out.write_all(&u16::to_le_bytes(1))?; + out.write_all(&u32::to_le_bytes(smp_rate))?; + out.write_all(&u32::to_le_bytes(smp_size))?; + // block alignment + out.write_all(&u16::to_le_bytes(2))?; + // bits per sample + out.write_all(&u16::to_le_bytes(16))?; + + out.write_all(b"data")?; + out.write_all(&u32::to_le_bytes(dat_size))?; + + for p in 0..snd.len() { + let sample = snd.index(p); + out.write_all(&sample.to_le_bytes())?; + } + + Ok(()) +} + +// EOF