From 067e8906be7bc8af2e4f5b7e642338b851e14780 Mon Sep 17 00:00:00 2001 From: Jared Roberts Date: Mon, 19 Sep 2016 03:00:54 -0700 Subject: [PATCH] factor out ega loader --- src/bin/tileview.rs | 46 ++++++++-------------------------- src/ega.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 3 +++ 3 files changed, 75 insertions(+), 35 deletions(-) create mode 100644 src/ega.rs diff --git a/src/bin/tileview.rs b/src/bin/tileview.rs index 66d9f38..8c21a10 100644 --- a/src/bin/tileview.rs +++ b/src/bin/tileview.rs @@ -1,30 +1,14 @@ +extern crate vrtue; +use vrtue::ega; +use vrtue::ega::{Compression, Tiling}; + extern crate image; -extern crate itertools; use std::env; use std::io::Read; use std::path::Path; -static EGA_PALETTE: [[u8; 4]; 16] = [[0x00, 0x00, 0x00, 0x00], - [0x00, 0x00, 0xAA, 0x00], - [0x00, 0xAA, 0x00, 0x00], - [0x00, 0xAA, 0xAA, 0x00], - [0xAA, 0x00, 0x00, 0x00], - [0xAA, 0x00, 0xAA, 0x00], - [0xAA, 0x55, 0x00, 0x00], - [0xAA, 0xAA, 0xAA, 0x00], - [0x55, 0x55, 0x55, 0x00], - [0x55, 0x55, 0xFF, 0x00], - [0x55, 0xFF, 0x55, 0x00], - [0x55, 0xFF, 0xFF, 0x00], - [0xFF, 0x55, 0x55, 0x00], - [0xFF, 0x55, 0xFF, 0x00], - [0xFF, 0xFF, 0x55, 0x00], - [0xFF, 0xFF, 0xFF, 0x00]]; - - - -pub fn main() { +fn main() { let args: Vec = env::args().collect(); let filename; if args.len() > 1 { @@ -33,24 +17,16 @@ pub fn main() { filename = "data/SHAPES.EGA"; } - let mut file = std::fs::File::open(Path::new(filename)).unwrap(); - let mut tile_buf = [0u8; 128]; + let mut file = std::fs::File::open(Path::new(filename)) + .expect(&format!("failed opening EGA file: {}", filename)); + let mut ega_vec = Vec::::new(); - let mut i = 0; - while file.read_exact(&mut tile_buf).is_ok() { - let tilepixels = tile_buf.iter() - .flat_map(|tile_byte| { - EGA_PALETTE[(tile_byte >> 4u8 & 0xF) as usize] - .into_iter() - .chain(EGA_PALETTE[(tile_byte & 0xF) as usize] - .into_iter()) - }) - .map(|x| *x) - .collect::>(); + file.read_to_end(&mut ega_vec).expect("Read EGA file"); + let ega_page = ega::decode(&ega_vec, Compression::UNCOMPRESSED, Tiling::TILED(16)); + for (i, tilepixels) in ega_page.iter().enumerate() { let out_name = format!("out/{}.png", i); let out_file = std::fs::File::create(Path::new(&out_name)).expect("open out file"); let enc = image::png::PNGEncoder::new(out_file); enc.encode(&tilepixels, 16, 16, image::ColorType::RGBA(8)).expect("write png"); - i += 1; } } diff --git a/src/ega.rs b/src/ega.rs new file mode 100644 index 0000000..54c9710 --- /dev/null +++ b/src/ega.rs @@ -0,0 +1,61 @@ +static EGA_PALETTE: [[u8; 4]; 16] = [[0x00, 0x00, 0x00, 0x00], + [0x00, 0x00, 0xAA, 0x00], + [0x00, 0xAA, 0x00, 0x00], + [0x00, 0xAA, 0xAA, 0x00], + [0xAA, 0x00, 0x00, 0x00], + [0xAA, 0x00, 0xAA, 0x00], + [0xAA, 0x55, 0x00, 0x00], + [0xAA, 0xAA, 0xAA, 0x00], + [0x55, 0x55, 0x55, 0x00], + [0x55, 0x55, 0xFF, 0x00], + [0x55, 0xFF, 0x55, 0x00], + [0x55, 0xFF, 0xFF, 0x00], + [0xFF, 0x55, 0x55, 0x00], + [0xFF, 0x55, 0xFF, 0x00], + [0xFF, 0xFF, 0x55, 0x00], + [0xFF, 0xFF, 0xFF, 0x00]]; + +pub enum Compression { + UNCOMPRESSED, + RLE, + LZW +} + +pub enum Tiling { + UNTILED, + TILED(u16) +} + +pub struct EgaPage { + pub data: Vec, + pub tilesize: u16, +} + +impl EgaPage { + pub fn iter<'a>(&'a self) -> impl Iterator { + self.data.chunks(self.tilesize as usize) + } +} + +pub fn decode<'a>(buf: &[u8], compression: Compression, tiling: Tiling) + -> EgaPage { + let out: Vec; + + out = match compression { + Compression::UNCOMPRESSED => buf.iter() + .flat_map(|tile_byte| { + EGA_PALETTE[(tile_byte >> 4u8 & 0xF) as usize] + .into_iter() + .chain(EGA_PALETTE[(tile_byte & 0xF) as usize] + .into_iter()) + }) + .map(|x| *x) + .collect(), + _ => unimplemented!() + }; + let tilesize = match tiling { + Tiling::TILED(tiledim) => 4 * tiledim * tiledim, + Tiling::UNTILED => out.len() as u16 + }; + EgaPage { data: out, tilesize: tilesize} +} diff --git a/src/lib.rs b/src/lib.rs index a4dd473..56c2b19 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,6 @@ +#![feature(conservative_impl_trait)] + #[macro_use] extern crate log; +pub mod ega; pub mod vr;