move writers to their own modules

png-branch
an 2019-03-13 11:32:46 -04:00
parent f4efbfab80
commit 7affb73f95
8 changed files with 121 additions and 106 deletions

View File

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

View File

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

View File

@ -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<T>(opt: &Options, data: &T) -> ResultS<()>
@ -25,7 +25,7 @@ fn make_yaml<T>(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<()>

View File

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

27
source/marathon/ppm.rs Normal file
View File

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

View File

@ -90,12 +90,12 @@ pub fn read_sounds(b: &[u8]) -> ResultS<Vec<SoundTable>>
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");
}

41
source/marathon/tga.rs Normal file
View File

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

45
source/marathon/wav.rs Normal file
View File

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