gdritter repos thermidor / cb6940e
Added some utils + Farbfeld reader Getty Ritter 7 years ago
5 changed file(s) with 113 addition(s) and 7 deletion(s). Collapse all Expand all
1 use glium::texture::{RawImage2d,Texture2dDataSource};
2 use therm_util::reader::ByteReader;
3
4 #[derive(Debug,Clone)]
5 pub struct FFImage {
6 pixels: Vec<Vec<(u16,u16,u16,u16)>>
7 }
8
9 fn parse_pixel<Rd>(r: &mut ByteReader<Rd>) -> Result<(u16,u16,u16,u16), String>
10 where Rd: Iterator<Item=u8>
11 {
12 Ok((try!(r.read_u16be()),
13 try!(r.read_u16be()),
14 try!(r.read_u16be()),
15 try!(r.read_u16be())))
16 }
17
18 impl FFImage {
19 pub fn from_bz2_file(path: &str) -> Result<FFImage, String> {
20 let mut r = match ByteReader::from_compressed_file(path) {
21 Ok(x) => x,
22 Err(_) => return Err("Unable to open file".to_string()),
23 };
24 FFImage::from_reader(&mut r)
25 }
26
27 pub fn from_file(path: &str) -> Result<FFImage, String> {
28 let mut r = match ByteReader::from_file(path) {
29 Ok(x) => x,
30 Err(_) => return Err("Unable to open file".to_string()),
31 };
32 FFImage::from_reader(&mut r)
33 }
34
35
36 pub fn from_reader<Rd>(r: &mut ByteReader<Rd>) -> Result<FFImage, String>
37 where Rd: Iterator<Item=u8>
38 {
39 assert!(try!(r.next()) == 'f' as u8);
40 assert!(try!(r.next()) == 'a' as u8);
41 assert!(try!(r.next()) == 'r' as u8);
42 assert!(try!(r.next()) == 'b' as u8);
43 assert!(try!(r.next()) == 'f' as u8);
44 assert!(try!(r.next()) == 'e' as u8);
45 assert!(try!(r.next()) == 'l' as u8);
46 assert!(try!(r.next()) == 'd' as u8);
47
48 let w = try!(r.read_u32be());
49 let h = try!(r.read_u32be());
50
51 let mut pixels = vec![];
52 for _ in 0..h {
53 let mut row = vec![];
54 for _ in 0..w {
55 row.push(try!(parse_pixel(r)));
56 }
57 pixels.push(row)
58 }
59 pixels.reverse();
60
61 Ok(FFImage { pixels: pixels })
62 }
63
64 pub fn get_raw_data(self) -> Vec<Vec<(u16,u16,u16,u16)>> {
65 self.pixels
66 }
67 }
68
69 impl <'a> Texture2dDataSource<'a> for FFImage {
70 type Data = (u16, u16, u16, u16);
71
72 fn into_raw(self) -> RawImage2d<'a, (u16, u16, u16, u16)> {
73 self.pixels.into_raw()
74 }
75 }
66
77 pub mod model;
88 pub mod graph;
9 pub mod farbfeld;
910
1011 #[cfg(test)]
1112 mod tests {
44 authors = ["Getty Ritter <gdritter@galois.com>"]
55
66 [dependencies]
7 bzip2="*"
1 extern crate bzip2;
2
13 pub mod adnot;
24 pub mod reader;
35
1 use std::{fs,io,iter,slice,vec};
1 use std::{fs,io,iter,mem,slice,vec};
2 use bzip2::bufread::BzDecoder;
23
34 /// A `ByteReader` is just a tiny wrapper over a mutable byte iterator, so we
45 /// can parse things more easily.
67 bytes: Rd,
78 }
89
9 impl<R: io::Read>
10 ByteReader<iter::FilterMap<io::Bytes<R>,
11 &'static Fn(io::Result<u8>) -> Option<u8>>>
10 impl<R: io::Read> ByteReader<iter::FilterMap<io::Bytes<R>, &'static Fn(io::Result<u8>) -> Option<u8>>>
1211 {
1312 /// Create a ByteReader from any type that implement Read
1413 pub fn from_reader(r: R) -> Self {
3534 }
3635 }
3736
38 impl<'a> ByteReader<iter::Map<slice::Iter<'a, u8>, &'static Fn(&u8) -> u8>> {
37 impl<'a> ByteReader<iter::Cloned<slice::Iter<'a, u8>>> {
3938 /// Create a reader from a borrowed slice, with a copy on each access
4039 pub fn from_slice(lst: &'a [u8]) -> Self {
41 const DEREF: &'static Fn(&u8) -> u8 = &|s| *s;
42 ByteReader { bytes: lst.iter().map(DEREF) }
40 ByteReader { bytes: lst.iter().cloned() }
41 }
42 }
43
44 impl<R: io::BufRead> ByteReader<iter::FilterMap<io::Bytes<BzDecoder<R>>, &'static Fn(io::Result<u8>) -> Option<u8>>> {
45 pub fn from_compressed_reader(r: R) -> Self {
46 ByteReader::from_reader(BzDecoder::new(r))
47 }
48 }
49
50 impl ByteReader<iter::FilterMap<io::Bytes<BzDecoder<io::BufReader<fs::File>>>, &'static Fn(io::Result<u8>) -> Option<u8>>> {
51 pub fn from_compressed_file(path: &str) -> io::Result<Self> {
52 let f = try!(fs::File::open(path));
53 Ok(ByteReader::from_compressed_reader(io::BufReader::new(f)))
4354 }
4455 }
4556
7990 pub fn read_ratio(&mut self) -> Result<f32, String> {
8091 let b = try!(self.next());
8192 Ok(b as f32 / 255.0)
93 }
94
95 pub fn read_u32be(&mut self) -> Result<u32, String> {
96 let a = try!(self.next());
97 let b = try!(self.next());
98 let c = try!(self.next());
99 let d = try!(self.next());
100 let rs = [ d, c, b, a ];
101 unsafe { Ok(mem::transmute::<[u8;4],u32>(rs)) }
102 }
103
104 pub fn read_u16be(&mut self) -> Result<u16, String> {
105 let a = try!(self.next());
106 let b = try!(self.next());
107 let rs = [ b, a ];
108 unsafe { Ok(mem::transmute::<[u8;2],u16>(rs)) }
82109 }
83110
84111 /// This reads a 64-bit int with a packed PrefixInteger representation.